source: trunk/hiptop/pester/net/sabi/pester/AlarmListView.java@ 241

Last change on this file since 241 was 241, checked in by Nicholas Riley, 18 years ago

Alarm scheduling UI more or less done.

File size: 7.2 KB
Line 
1package net.sabi.pester;
2
3import danger.app.Application;
4import danger.app.Event;
5import danger.internal.Date;
6import danger.ui.ActiveListView;
7import danger.ui.Button;
8import danger.ui.CheckBox;
9import danger.ui.DateTimeEditor;
10import danger.ui.DatePicker;
11import danger.ui.DialogWindow;
12import danger.ui.Menu;
13import danger.ui.MenuItem;
14import danger.ui.NumberEditor;
15import danger.ui.PopupMenu;
16import danger.ui.RadioButton;
17import danger.ui.Rect;
18import danger.ui.TypeAheadTextField;
19import danger.util.ActiveList;
20import danger.util.StdActiveList;
21import danger.util.DEBUG;
22
23public class AlarmListView extends ActiveListView
24 implements Resources, Commands {
25 private static Pester sPester;
26 private static AlarmListWindow sAlarmListWindow;
27 // XXX some of these shouldn't conceptually be static, but who cares
28 private static StdActiveList sAlarmList;
29 private static Alarms sAlarms;
30
31 private static DialogWindow sEditWindow;
32 private TypeAheadTextField sMessageField;
33 private RadioButton sInButton, sAtButton;
34 private NumberEditor sPeriodField;
35 private Menu sPeriodUnitsMenu;
36 private PopupMenu sPeriodUnitsPopup;
37 private CheckBox sRepeatCheckBox;
38 private DateTimeEditor sTimeEditor, sDateEditor;
39 private DatePicker sDatePicker;
40 private Button sDiscardAlarmButton, sSetAlarmButton;
41
42 private static Alarm sFocusedAlarm, sEditingAlarm;
43
44 private static final int EVENT_CANCEL_ALARM = -1; // XXX move this?
45
46 public void onDecoded() {
47 sPester = (Pester)Application.getCurrentApp();
48 sAlarmListWindow = (AlarmListWindow)getWindow();
49 sAlarmList = new StdActiveList();
50 setList(sAlarmList);
51
52 sEditWindow = sPester.getDialog(ID_ALARM_SET_DIALOG, this);
53 sEditWindow.setCancelButtonEvent(new Event(this, EVENT_CANCEL_ALARM));
54 sMessageField = (TypeAheadTextField)sEditWindow.getDescendantWithID(ID_MESSAGE_FIELD);
55 sEditWindow.disableBottomRightButtonOnEmptyField(sMessageField);
56 sInButton = (RadioButton)sEditWindow.getDescendantWithID(ID_IN_BUTTON);
57 sAtButton = (RadioButton)sEditWindow.getDescendantWithID(ID_AT_BUTTON);
58 sPeriodField = (NumberEditor)sEditWindow.getDescendantWithID(ID_PERIOD_FIELD);
59 sPeriodUnitsMenu = (Menu)sEditWindow.getDescendantWithID(ID_PERIOD_UNITS_MENU);
60 sPeriodUnitsPopup = (PopupMenu)sEditWindow.getDescendantWithID(ID_PERIOD_UNITS_POPUP);
61 sRepeatCheckBox = (CheckBox)sEditWindow.getDescendantWithID(ID_PERIOD_REPEAT_CHECKBOX);
62 sTimeEditor = (DateTimeEditor)sEditWindow.getDescendantWithID(ID_TIME_EDITOR);
63 sDateEditor = (DateTimeEditor)sEditWindow.getDescendantWithID(ID_DATE_EDITOR);
64 sDatePicker = (DatePicker)sEditWindow.getDescendantWithID(ID_DATE_PICKER);
65 sSetAlarmButton = (Button)sEditWindow.getDescendantWithID(ID_SET_ALARM_BUTTON);
66 sDiscardAlarmButton = (Button)sEditWindow.getDescendantWithID(ID_DISCARD_ALARM_BUTTON);
67 sInButton.setValue(1);
68 sDateEditor.limitToDangerEpoch();
69
70 super.onDecoded();
71 }
72
73 public boolean eventWidgetUp(int widget, Event e) {
74 switch (widget) {
75 case Event.DEVICE_BUTTON_BACK:
76 case Event.DEVICE_BUTTON_CANCEL:
77 sPester.returnToLauncher();
78 return true;
79 }
80 return super.eventWidgetUp(widget, e);
81 }
82
83 protected void editDateOrPeriod(Alarm alarm) {
84 boolean usesPeriod = alarm.getUsesPeriod();
85 if (usesPeriod) {
86 int period = alarm.getPeriod();
87 for (int i = sPeriodUnitsPopup.itemCount() - 1 ; i >= 0 ; --i) {
88 MenuItem item = sPeriodUnitsPopup.getItem(i);
89 int unitsPerSec = item.getEvent().data;
90 if (period % unitsPerSec == 0) {
91 sPeriodUnitsPopup.setValueWithItemID(sPeriodUnitsMenu.getIDOfItem(item));
92 sPeriodField.setValue(period / unitsPerSec);
93 break;
94 }
95 }
96 sRepeatCheckBox.setValue(alarm.getRepeating() ? 1 : 0);
97 }
98
99 Date date = alarm.getDate();
100 sTimeEditor.setDate(date);
101 sDateEditor.setDate(date);
102 sDatePicker.setDate(date);
103
104 sInButton.setValue(usesPeriod ? 1 : 0);
105 sAtButton.setValue(usesPeriod ? 0 : 1);
106 }
107
108 protected void editAlarm(Alarm alarm, boolean asNew) {
109 sEditingAlarm = alarm;
110 alarm.beginEditing();
111 sMessageField.setText(alarm.getMessage());
112 if (asNew) {
113 sDiscardAlarmButton.hide();
114 } else {
115 sDiscardAlarmButton.show();
116 editDateOrPeriod(alarm);
117 }
118 constrainDate();
119 sEditWindow.show();
120 }
121
122 protected Date editingDate() {
123 Date date = sDateEditor.getDate();
124 date.setTime(sTimeEditor.getDate().getTime());
125 return date;
126 }
127
128 protected void constrainDate() {
129 // XXX schedule every minute (second?) if in AT mode
130 Date now = new Date();
131 sDateEditor.min(now);
132 sDatePicker.min(now);
133 sSetAlarmButton.setEnabled(editingDate().compareTo(now) > 0);
134 }
135
136 public boolean receiveEvent(Event e) {
137 switch (e.type) {
138 case EVENT_NEW_ALARM:
139 editAlarm(new Alarm(), true);
140 return true;
141 case EVENT_SET_ALARM:
142 sEditingAlarm.setMessage(sMessageField.toString());
143 if (sInButton.getValue() == 1) {
144 int itemID = sPeriodUnitsPopup.getValueAsItemID();
145 MenuItem itemWithID = sPeriodUnitsMenu.getItemWithID(itemID);
146 Event event = itemWithID.getEvent();
147 sEditingAlarm.setPeriod(sPeriodField.getValue() * event.data,
148 sRepeatCheckBox.getValue() == 1);
149 } else {
150 sEditingAlarm.setDate(editingDate());
151 }
152 if (sEditingAlarm != sFocusedAlarm) { // new alarm
153 sAlarmList.addItem(sEditingAlarm);
154 setFocusedItem(sEditingAlarm);
155 sFocusedAlarm = sEditingAlarm; // XXX do we need this?
156 } else {
157 sEditingAlarm.update();
158 }
159 case EVENT_CANCEL_ALARM:
160 if (sEditingAlarm == sFocusedAlarm) { // existing alarm
161 // XXX (re)schedule alarm
162 sEditingAlarm.endEditing();
163 }
164 sEditingAlarm = null;
165 return true;
166 case EVENT_DISCARD_ALARM:
167 // XXX confirmation
168 sAlarmList.removeItem(sFocusedAlarm);
169 return true;
170 case EVENT_IN:
171 sAtButton.setValue(0);
172 return true;
173 case EVENT_AT:
174 sInButton.setValue(0);
175 constrainDate();
176 return true;
177 case EVENT_TIME_EDITOR:
178 Date date = editingDate();
179 // XXX factor this out (it's used twice)
180 // XXX do this on exit from the field, not on change
181 if (date.compareTo(new Date()) <= 0) {
182 date.addDays(1);
183 sDatePicker.setDate(date);
184 sDateEditor.setDate(date);
185 }
186 constrainDate();
187 return true;
188 case EVENT_DATE_EDITOR:
189 sDatePicker.setDate(sDateEditor.getDate());
190 constrainDate();
191 return true;
192 case EVENT_DATE_PICKER:
193 sDateEditor.setDate((Date)e.argument);
194 constrainDate();
195 return true;
196 }
197 return super.receiveEvent(e);
198 }
199
200 protected void itemActivated(Object item) {
201 // XXX deschedule alarm
202 editAlarm(sFocusedAlarm, false);
203 }
204 protected void itemFocused(Object item) {
205 sFocusedAlarm = (Alarm)item;
206 }
207
208 public int alarmsSet() {
209 return getListSize();
210 }
211 public void onItemAdded(ActiveList list, Object item, int index) {
212 sAlarmListWindow.updateAlarmCount();
213 super.onItemAdded(list, item, index);
214 }
215 public void onItemRemoved(ActiveList list, Object item, int index) {
216 sAlarmListWindow.updateAlarmCount();
217 super.onItemRemoved(list, item, index);
218 }
219
220 protected CharSequence getToolTipForItem(Object item) {
221 if (item == null) // this is dumb, why do we get asked for a tooltip?
222 return null;
223 // XXX only set a tooltip if the message is truncated
224 return ((Alarm)item).getMessage();
225 }
226}
Note: See TracBrowser for help on using the repository browser.