source: trunk/hiptop/pester/net/sabi/pester/AlarmSetDialog.java@ 254

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

Register for time changed events so we actually get them in the alarm set dialog.

File size: 8.1 KB
Line 
1package net.sabi.pester;
2
3import danger.app.Application;
4import danger.app.Event;
5import danger.audio.ToneClass;
6import danger.audio.ToneRights;
7import danger.internal.Date;
8import danger.ui.Button;
9import danger.ui.CheckBox;
10import danger.ui.Color;
11import danger.ui.DateTimeEditor;
12import danger.ui.DatePicker;
13import danger.ui.DialogWindow;
14import danger.ui.Font;
15import danger.ui.Layout;
16import danger.ui.MenuItem;
17import danger.ui.NumberEditor;
18import danger.ui.Pen;
19import danger.ui.PopupMenu;
20import danger.ui.RadioButton;
21import danger.ui.Rect;
22import danger.ui.RingTonePicker;
23import danger.ui.StaticTextBox;
24import danger.ui.TypeAheadTextField;
25import danger.util.DEBUG;
26
27public class AlarmSetDialog extends DialogWindow
28 implements Resources, Commands {
29
30 private TypeAheadTextField mMessageField;
31 private RadioButton mInButton, mAtButton;
32 private NumberEditor mPeriodField;
33 private PopupMenu mPeriodUnitsPopup;
34 // XXX don't allow <5 second repeating alarms
35 private CheckBox mRepeatCheckBox;
36 private DateTimeEditor mTimeEditor, mDateEditor;
37 private DatePicker mDatePicker;
38 private RingTonePicker mAlertPicker;
39 private Button mDiscardAlarmButton, mSetAlarmButton;
40 private StaticTextBox mStatusBox;
41
42 private Alarm mEditingAlarm;
43 private boolean mAlarmIsNew;
44 private boolean mHaveShownWindow = false;
45
46 private danger.app.Alarm mValidateAlarm;
47
48 public static AlarmSetDialog getDialog() {
49 AlarmSetDialog dialog = (AlarmSetDialog)
50 Application.getCurrentApp().getDialog(ID_ALARM_SET_DIALOG, null);
51 return dialog;
52 }
53
54 public void onDecoded() {
55 setCancelButtonEvent(new Event(this, EVENT_CANCEL_ALARM));
56 mMessageField =
57 (TypeAheadTextField)getDescendantWithID(ID_MESSAGE_FIELD);
58 disableBottomRightButtonOnEmptyField(mMessageField);
59 mInButton = (RadioButton)getDescendantWithID(ID_IN_BUTTON);
60 mAtButton = (RadioButton)getDescendantWithID(ID_AT_BUTTON);
61 mPeriodField = (NumberEditor)getDescendantWithID(ID_PERIOD_FIELD);
62 mPeriodUnitsPopup =
63 (PopupMenu)getDescendantWithID(ID_PERIOD_UNITS_POPUP);
64 mRepeatCheckBox =
65 (CheckBox)getDescendantWithID(ID_PERIOD_REPEAT_CHECKBOX);
66 mTimeEditor = (DateTimeEditor)getDescendantWithID(ID_TIME_EDITOR);
67 mDateEditor = (DateTimeEditor)getDescendantWithID(ID_DATE_EDITOR);
68 mDatePicker = (DatePicker)getDescendantWithID(ID_DATE_PICKER);
69 mAlertPicker = (RingTonePicker)getDescendantWithID(ID_ALERT_PICKER);
70 mSetAlarmButton = (Button)getDescendantWithID(ID_SET_ALARM_BUTTON);
71 mDiscardAlarmButton =
72 (Button)getDescendantWithID(ID_DISCARD_ALARM_BUTTON);
73 mInButton.setValue(1);
74 mDateEditor.limitToDangerEpoch();
75 mAlertPicker.setGroupFilter(ToneClass.FOREGROUND | ToneClass.CUSTOM);
76 mAlertPicker.setRights(ToneRights.FULL);
77 // this doesn't work properly yet
78 // mAlertPicker.setCanRecord(true);
79
80 mStatusBox = new StaticTextBox();
81 mStatusBox.setTransparent(true);
82 mStatusBox.setHasBorder(false);
83 mStatusBox.setFont(Font.findSystemFont());
84 mStatusBox.setAutoResize(false);
85
86 mValidateAlarm = new danger.app.Alarm(1, this);
87
88 super.onDecoded();
89 }
90
91 protected void editDateOrPeriod(Alarm alarm) {
92 boolean usesPeriod = alarm.getUsesPeriod();
93 if (usesPeriod) {
94 int period = alarm.getPeriod();
95 for (int i = mPeriodUnitsPopup.itemCount() - 1 ; i >= 0 ; --i) {
96 int unitsPerSec = mPeriodUnitsPopup.getItem(i).getEvent().data;
97 if (period % unitsPerSec == 0) {
98 mPeriodUnitsPopup.setValue(i);
99 mPeriodField.setValue(period / unitsPerSec);
100 break;
101 }
102 }
103 mRepeatCheckBox.setValue(alarm.getRepeating() ? 1 : 0);
104 }
105
106 Date date = new Date(alarm.getDate());
107 mTimeEditor.setDate(date);
108 mDateEditor.setDate(date);
109 mDatePicker.setDate(date);
110
111 mInButton.setValue(usesPeriod ? 1 : 0);
112 mAtButton.setValue(usesPeriod ? 0 : 1);
113 }
114
115 public void editAlarm(Alarm alarm, boolean asNew) {
116 mEditingAlarm = alarm;
117 mAlarmIsNew = asNew;
118 alarm.beginEditing();
119 if (asNew) {
120 mDiscardAlarmButton.hide();
121 // XXX default to now?
122 } else {
123 mMessageField.setText(alarm.getMessage());
124 mDiscardAlarmButton.show();
125 editDateOrPeriod(alarm);
126 mAlertPicker.setRingTone(mEditingAlarm.getAlert());
127 }
128 validate();
129 Application.registerForEvent(this, Event.EVENT_TIME_CHANGED));
130 show();
131 if (!mHaveShownWindow) {
132 Rect alarmRect = mSetAlarmButton.getFrame();
133 Rect contentRect = getContentRect();
134 mStatusBox.setPosition(contentRect.left + 8, alarmRect.top + 2);
135 mStatusBox.setSize(alarmRect.left - 8, 11);
136 mStatusBox.show();
137 addChild(mStatusBox);
138 mHaveShownWindow = true;
139 setAutoSize(false); // don't resize to contain it next time
140 }
141 }
142
143 protected boolean isIn() {
144 return (mInButton.getValue() == 1);
145 }
146
147 protected int editingInterval() {
148 int itemIndex = mPeriodUnitsPopup.getValue();
149 MenuItem itemAtIndex = mPeriodUnitsPopup.getItem(itemIndex);
150 Event event = itemAtIndex.getEvent();
151 return mPeriodField.getValue() * event.data;
152 }
153
154 protected Date editingDate() {
155 Date date;
156 if (isIn()) {
157 date = new Date();
158 date.addSeconds(editingInterval());
159 } else {
160 // XXX is it necessary to do this, or do the two share the
161 // XXX same physical Date object?
162 date = mDateEditor.getDate();
163 date.setTime(mTimeEditor.getDate().getTime());
164 date.setSeconds(0);
165 }
166 return date;
167 }
168
169 protected boolean isValid() {
170 // doesn't redraw properly otherwise
171 invalidate(mStatusBox.getBounds());
172 if (mMessageField.length() == 0) {
173 mStatusBox.setText("Specify a message.");
174 return false;
175 }
176 Date now = new Date();
177 mDateEditor.min(now);
178 mDatePicker.min(now);
179 Date editingDate = editingDate();
180 if (isIn()) {
181 mValidateAlarm.resetWake(60 - now.getSeconds());
182 } else {
183 int secondsUntilDate =
184 editingDate.getDangerTimeGMT() - now.getDangerTimeGMT();
185 if (secondsUntilDate <= 0) {
186 mStatusBox.setText("Specify a future date.");
187 return false;
188 }
189 mValidateAlarm.resetWake(secondsUntilDate);
190 }
191 mStatusBox.setText(Alarm.dateTimeString(editingDate, true));
192 return true;
193 }
194
195 // XXX make a timer-only version of this which doesn't try to extract
196 // XXX the editing date (it can cause odd behavior by forcing the
197 // XXX NumberEditor to spit out a value)
198 protected void validate() {
199 boolean isValid = isValid();
200 mSetAlarmButton.setEnabled(isValid);
201 if (!isValid)
202 mValidateAlarm.deactivate();
203 }
204
205 protected void stopEditing() {
206 mEditingAlarm = null;
207 mValidateAlarm.deactivate();
208 Application.unregisterForEvent(this, Event.EVENT_TIME_CHANGED);
209 }
210
211 public boolean receiveEvent(Event e) {
212 switch (e.type) {
213 case EVENT_SET_ALARM:
214 if (!isValid())
215 return true;
216 mEditingAlarm.setMessage(mMessageField.toString());
217 if (isIn()) {
218 mEditingAlarm.setPeriod(editingInterval(),
219 mRepeatCheckBox.getValue() == 1);
220 } else {
221 mEditingAlarm.setDate(editingDate());
222 }
223 mEditingAlarm.setAlert(mAlertPicker.getRingTone());
224 // schedule before adding so the tooltip is correct
225 mEditingAlarm.schedule();
226 if (mAlarmIsNew) Alarms.addAlarm(mEditingAlarm);
227 stopEditing();
228 return true;
229 case EVENT_CANCEL_ALARM:
230 if (!mAlarmIsNew) mEditingAlarm.resume();
231 stopEditing();
232 return true;
233 case EVENT_DISCARD_ALARM:
234 // XXX prompt for confirmation
235 stopEditing();
236 return true;
237 case Event.EVENT_TIME_CHANGED: // time on device changed
238 case Event.EVENT_ALARM: // computed time invalid
239 case EVENT_VALIDATE: // something changed
240 validate();
241 return true;
242 case EVENT_IN:
243 mAtButton.setValue(0);
244 validate();
245 return true;
246 case EVENT_AT:
247 mInButton.setValue(0);
248 validate();
249 return true;
250 case EVENT_TIME_EDITOR:
251 validate();
252 return true;
253 case EVENT_DATE_EDITOR_TOOK_FOCUS:
254 Date date = editingDate();
255 if (date.compareTo(new Date()) <= 0) {
256 date.addDays(1);
257 mDatePicker.setDate(date);
258 mDateEditor.setDate(date);
259 }
260 validate();
261 return true;
262 case EVENT_DATE_EDITOR:
263 mDatePicker.setDate(mDateEditor.getDate());
264 validate();
265 return true;
266 case EVENT_DATE_PICKER:
267 mDateEditor.setDate((Date)e.argument);
268 validate();
269 return true;
270 }
271 return super.receiveEvent(e);
272 }
273}
Note: See TracBrowser for help on using the repository browser.