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

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

Bug fixing and cleanups.

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