Pastie now auto-senses if line-wrap is a bad or good idea. Feedback?
## mark a section (Learn more)
package org.emerick.rtm.ui.lists; import java.util.Vector; import net.rim.device.api.system.Bitmap; import net.rim.device.api.system.KeypadListener; import net.rim.device.api.ui.ContextMenu; import net.rim.device.api.ui.DrawStyle; import net.rim.device.api.ui.Field; import net.rim.device.api.ui.Font; import net.rim.device.api.ui.Graphics; import net.rim.device.api.ui.Keypad; import net.rim.device.api.ui.Manager; import net.rim.device.api.ui.MenuItem; import net.rim.device.api.ui.UiApplication; import net.rim.device.api.ui.component.BitmapField; import net.rim.device.api.ui.component.LabelField; import net.rim.device.api.ui.component.ListField; import net.rim.device.api.ui.component.ListFieldCallback; import net.rim.device.api.ui.component.NullField; import org.emerick.rtm.RTM; import org.emerick.rtm.beans.Task; import org.emerick.rtm.ui.field.FontColorField; import org.emerick.rtm.ui.screens.DetailTaskScreen; public class TaskListField extends ListField implements ListFieldCallback { private Vector tasks; private Vector rows; private Bitmap p1; private Bitmap p2; private Bitmap p3; public TaskListField(Vector tasks) { super(0, ListField.MULTI_SELECT); setRowHeight(40); setEmptyString("Hooray, no tasks here!", DrawStyle.HCENTER); setCallback(this); setSearchable(false); p1 = Bitmap.getBitmapResource("p1.png"); p2 = Bitmap.getBitmapResource("p2.png"); p3 = Bitmap.getBitmapResource("p3.png"); this.tasks = tasks; rows = new Vector(); for (int x = 0; x < tasks.size(); ++x) { TableRowManager row = new TableRowManager(); // SET THE PRIORITY BITMAP FIELD Task task = (Task)tasks.elementAt(x); switch (task.getPriority()) { case 1: // if high priority, display p1 bitmap row.add(new BitmapField(p1)); break; case 2: // if priority is 2, set p2 bitmap row.add(new BitmapField(p2)); break; case 3: // if priority is 3, set p3 bitmap row.add(new BitmapField(p3)); break; default: // no priority set row.add(new NullField()); break; } // SET THE TASK NAME LABELFIELD // if overdue, bold/underline LabelField taskname = new LabelField(task.getName(), DrawStyle.ELLIPSIS); // if due today, bold if (task.overdue()) { taskname.setFont(Font.getDefault().derive(Font.BOLD | Font.UNDERLINED)); } else if (task.dueToday()) { taskname.setFont(Font.getDefault().derive(Font.BOLD)); } row.add(taskname); // SET THE LIST NAME row.add(new FontColorField(RTM.getListName(task.getListID()), DrawStyle.ELLIPSIS, 0x00878787)); // SET THE DUE DATE/TIME row.add(new FontColorField(task.getFormattedDue(), DrawStyle.ELLIPSIS | LabelField.USE_ALL_WIDTH | DrawStyle.RIGHT, 0x00878787)); rows.addElement(row); } setSize(rows.size()); } private class TableRowManager extends Manager { public TableRowManager() { super(0); } // Causes the fields within this row manager to be layed out then // painted. public void drawRow(Graphics g, int x, int y, int width, int height) { // Arrange the cell fields within this row manager. layout(width, height); // Place this row manager within its enclosing list. setPosition(x, y); // Apply a translating/clipping transformation to the graphics // context so that this row paints in the right area. g.pushRegion(getExtent()); // Paint this manager's controlled fields. subpaint(g); g.setColor(0x00CACACA); g.drawLine(0, 0, getPreferredWidth(), 0); g.drawLine(10, 0, 10, getPreferredHeight()); // Restore the graphics context. g.popContext(); } // Arrages this manager's controlled fields from left to right within // the enclosing table's columns. protected void sublayout(int width, int height) { // set the size and position of each field. int fontHeight = Font.getDefault().getHeight(); int preferredWidth = getPreferredWidth(); // start with the Bitmap Field of the priority icon Field field = getField(0); layoutChild(field, 10, 40); setPositionChild(field, 0, 0); // set the task name label field field = getField(1); layoutChild(field, preferredWidth - 16, fontHeight + 1); setPositionChild(field, 16, 3); // set the list name label field field = getField(2); layoutChild(field, 150, fontHeight + 1); setPositionChild(field, 16, fontHeight + 6); // set the due time name label field field = getField(3); layoutChild(field, 150, fontHeight + 1); setPositionChild(field, preferredWidth - 152, fontHeight + 6); setExtent(preferredWidth, getPreferredHeight()); } // The preferred width of a row is defined by the list renderer. public int getPreferredWidth() { return Graphics.getScreenWidth(); } // The preferred height of a row is the "row height" as defined in the // enclosing list. public int getPreferredHeight() { return getRowHeight(); } } // ListFieldCallback Implementation public void drawListRow(ListField listField, Graphics g, int index, int y, int width) { TaskListField list = (TaskListField) listField; TableRowManager rowManager = (TableRowManager) list.rows.elementAt(index); rowManager.drawRow(g, 0, y, width, list.getRowHeight()); } public Object get(ListField list, int index) { return tasks.elementAt(index); } public int indexOfList(ListField list, String prefix, int start) { for(int x = start; x < tasks.size(); ++x) { Task task = (Task)tasks.elementAt(x); if(task.getName().startsWith(prefix)) { return x; } } return -1; } public int getPreferredWidth(ListField list) { return Graphics.getScreenWidth(); } public ContextMenu getContextMenu() { ContextMenu menu = super.getContextMenu(); menu.addItem(new CompleteTaskMenuItem()); menu.addItem(new EditTaskMenuItem()); menu.addItem(new DeleteTaskMenuItem()); menu.addItem(new PostponeTaskMenuItem()); return menu; } protected boolean navigationClick(int status, int time) { if ((status & KeypadListener.STATUS_TRACKWHEEL) == KeypadListener.STATUS_TRACKWHEEL) return false; selectItem(); return true; } protected boolean keyDown(int keycode, int time) { if (Keypad.key(keycode) == Keypad.KEY_ENTER) { selectItem(); } else if (Keypad.key(keycode) == Keypad.KEY_DELETE) { deleteSelected(); } else if (Keypad.map(keycode) == 'c') { completeSelected(); } else if (Keypad.map(keycode) == 'p') { postponeSelected(); } else if(Keypad.map(keycode) == 't') { setSelectedIndex(0); setFocus(); } else if(Keypad.map(keycode) == 'b') { setSelectedIndex(tasks.size() - 1); setFocus(); } else { return false; } return true; } public void delete(int index) { super.delete(index); tasks.removeElementAt(index); } public void selectItem() { int index = getSelectedIndex(); UiApplication.getUiApplication().pushScreen(new DetailTaskScreen((Task)tasks.elementAt(index))); } public void completeSelected() { int[] items = getSelection(); for (int x = items.length; x > 0; x--) { RTM.completeTask((Task)tasks.elementAt(items[x - 1])); delete(items[x - 1]); } } public void deleteSelected() { int[] items = getSelection(); for (int x = items.length; x > 0; x--) { RTM.deleteTask((Task)tasks.elementAt(items[x - 1])); delete(items[x - 1]); } } public void postponeSelected() { int[] items = getSelection(); for (int x = items.length; x > 0; x--) { RTM.postponeTask((Task)tasks.elementAt(items[x - 1])); ((Task)tasks.elementAt(items[x - 1])).postpone(); } } private final class CompleteTaskMenuItem extends MenuItem { public CompleteTaskMenuItem() { super("Complete", 100000, 1); } public void run() { completeSelected(); } } private final class EditTaskMenuItem extends MenuItem { public EditTaskMenuItem() { super("Edit", 100001, 2); } public void run() { selectItem(); } } private final class DeleteTaskMenuItem extends MenuItem { public DeleteTaskMenuItem() { super("Delete", 100002, 3); } public void run() { deleteSelected(); } } private final class PostponeTaskMenuItem extends MenuItem { public PostponeTaskMenuItem() { super("Postpone", 100004, 4); } public void run() { postponeSelected(); } } }
This paste will be private.
From the Design Piracy series on my blog: