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

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

Add timer in alarm set dialog to update alarm time display. Send events on number picker accept (work around probable bug). Fixed cancel not cancelling if you're using a fixed-time alarm.

File size: 7.9 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 show();
130 if (!mHaveShownWindow) {
131 Rect alarmRect = mSetAlarmButton.getFrame();
132 Rect contentRect = getContentRect();
133 mStatusBox.setPosition(contentRect.left + 8, alarmRect.top + 2);
134 mStatusBox.setSize(alarmRect.left - 8, 11);
135 mStatusBox.show();
136 addChild(mStatusBox);
137 mHaveShownWindow = true;
138 setAutoSize(false); // don't resize to contain it next time
139 }
140 }
141
142 protected boolean isIn() {
143 return (mInButton.getValue() == 1);
144 }
145
146 protected int editingInterval() {
147 int itemIndex = mPeriodUnitsPopup.getValue();
148 MenuItem itemAtIndex = mPeriodUnitsPopup.getItem(itemIndex);
149 Event event = itemAtIndex.getEvent();
150 return mPeriodField.getValue() * event.data;
151 }
152
153 protected Date editingDate() {
154 Date date;
155 if (isIn()) {
156 date = new Date();
157 date.addSeconds(editingInterval());
158 } else {
159 date = mDateEditor.getDate();
160 date.setTime(mTimeEditor.getDate().getTime());
161 date.setSeconds(0);
162 }
163 return date;
164 }
165
166 protected boolean isValid() {
167 // doesn't redraw properly otherwise
168 invalidate(mStatusBox.getBounds());
169 if (mMessageField.length() == 0) {
170 mStatusBox.setText("Specify a message.");
171 return false;
172 }
173 Date now = new Date();
174 mDateEditor.min(now);
175 mDatePicker.min(now);
176 Date editingDate = editingDate();
177 if (isIn()) {
178 mValidateAlarm.resetWake(60 - now.getSeconds());
179 } else {
180 int secondsUntilDate =
181 editingDate.getDangerTimeGMT() - now.getDangerTimeGMT();
182 if (secondsUntilDate <= 0) {
183 mStatusBox.setText("Specify a future date.");
184 return false;
185 }
186 mValidateAlarm.resetWake(secondsUntilDate);
187 }
188 mStatusBox.setText(Alarm.dateTimeString(editingDate, true));
189 return true;
190 }
191
192 // XXX make a timer-only version of this which doesn't try to extract
193 // XXX the editing date (it can cause odd behavior by forcing the
194 // XXX NumberEditor to spit out a value)
195 protected void validate() {
196 boolean isValid = isValid();
197 mSetAlarmButton.setEnabled(isValid);
198 if (!isValid)
199 mValidateAlarm.deactivate();
200 }
201
202 protected void stopEditing() {
203 mEditingAlarm = null;
204 mValidateAlarm.deactivate();
205 }
206
207 public boolean receiveEvent(Event e) {
208 switch (e.type) {
209 case EVENT_SET_ALARM:
210 if (!isValid())
211 return true;
212 mEditingAlarm.setMessage(mMessageField.toString());
213 if (isIn()) {
214 mEditingAlarm.setPeriod(editingInterval(),
215 mRepeatCheckBox.getValue() == 1);
216 } else {
217 mEditingAlarm.setDate(editingDate());
218 }
219 mEditingAlarm.setAlert(mAlertPicker.getRingTone());
220 // schedule before adding so the tooltip is correct
221 mEditingAlarm.schedule();
222 if (mAlarmIsNew) Alarms.addAlarm(mEditingAlarm);
223 stopEditing();
224 return true;
225 case EVENT_CANCEL_ALARM:
226 if (!mAlarmIsNew) mEditingAlarm.resume();
227 stopEditing();
228 return true;
229 case EVENT_DISCARD_ALARM:
230 // XXX prompt for confirmation
231 stopEditing();
232 return true;
233 case Event.EVENT_TIME_CHANGED:
234 // XXX this isn't being delivered on the simulator, why?
235 DEBUG.p("time changed");
236 validate();
237 return true;
238 case Event.EVENT_ALARM:
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.