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

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

Save most recent alarm settings to SettingsDB.

File size: 8.2 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 editAlarm(Alarms.getDefaultAlarm());
89
90 super.onDecoded();
91 }
92
93 protected void editAlarm(Alarm alarm) {
94 mMessageField.setText(alarm.getMessage());
95
96 boolean usesPeriod = alarm.getUsesPeriod();
97 if (usesPeriod) {
98 int period = alarm.getPeriod();
99 for (int i = mPeriodUnitsPopup.itemCount() - 1 ; i >= 0 ; --i) {
100 int unitsPerSec = mPeriodUnitsPopup.getItem(i).getEvent().data;
101 if (period % unitsPerSec == 0) {
102 mPeriodUnitsPopup.setValue(i);
103 mPeriodField.setValue(period / unitsPerSec);
104 break;
105 }
106 }
107 mRepeatCheckBox.setValue(alarm.getRepeating() ? 1 : 0);
108 }
109
110 Date date = new Date(alarm.getDate());
111 mTimeEditor.setDate(date);
112 mDateEditor.setDate(date);
113 mDatePicker.setDate(date);
114
115 mInButton.setValue(usesPeriod ? 1 : 0);
116 mAtButton.setValue(usesPeriod ? 0 : 1);
117
118 mAlertPicker.setRingTone(alarm.getAlert());
119 }
120
121 public void editAlarm(Alarm alarm, boolean asNew) {
122 mEditingAlarm = alarm;
123 mAlarmIsNew = asNew;
124 alarm.beginEditing();
125 if (asNew) {
126 mDiscardAlarmButton.hide();
127 // XXX default to now?
128 } else {
129 editAlarm(alarm);
130 mDiscardAlarmButton.show();
131 }
132 validate();
133 Application.registerForEvent(this, Event.EVENT_TIME_CHANGED);
134 show();
135 if (!mHaveShownWindow) {
136 Rect alarmRect = mSetAlarmButton.getFrame();
137 Rect contentRect = getContentRect();
138 mStatusBox.setPosition(contentRect.left + 8, alarmRect.top + 2);
139 mStatusBox.setSize(alarmRect.left - 8, 11);
140 mStatusBox.show();
141 addChild(mStatusBox);
142 mHaveShownWindow = true;
143 setAutoSize(false); // don't resize to contain it next time
144 }
145 }
146
147 protected boolean isIn() {
148 return (mInButton.getValue() == 1);
149 }
150
151 protected int editingInterval() {
152 int itemIndex = mPeriodUnitsPopup.getValue();
153 MenuItem itemAtIndex = mPeriodUnitsPopup.getItem(itemIndex);
154 Event event = itemAtIndex.getEvent();
155 return mPeriodField.getValue() * event.data;
156 }
157
158 protected Date editingDate() {
159 Date date;
160 if (isIn()) {
161 date = new Date();
162 date.addSeconds(editingInterval());
163 } else {
164 // XXX is it necessary to do this, or do the two share the
165 // XXX same physical Date object?
166 date = mDateEditor.getDate();
167 date.setTime(mTimeEditor.getDate().getTime());
168 date.setSeconds(0);
169 }
170 return date;
171 }
172
173 protected boolean isValid() {
174 // doesn't redraw properly otherwise
175 invalidate(mStatusBox.getBounds());
176 if (mMessageField.length() == 0) {
177 mStatusBox.setText("Specify a message.");
178 return false;
179 }
180 Date now = new Date();
181 mDateEditor.min(now);
182 mDatePicker.min(now);
183 Date editingDate = editingDate();
184 if (isIn()) {
185 mValidateAlarm.resetWake(60 - now.getSeconds());
186 } else {
187 int secondsUntilDate =
188 editingDate.getDangerTimeGMT() - now.getDangerTimeGMT();
189 if (secondsUntilDate <= 0) {
190 mStatusBox.setText("Specify a future date.");
191 return false;
192 }
193 mValidateAlarm.resetWake(secondsUntilDate);
194 }
195 mStatusBox.setText(Alarm.dateTimeString(editingDate, true));
196 return true;
197 }
198
199 // XXX make a timer-only version of this which doesn't try to extract
200 // XXX the editing date (it can cause odd behavior by forcing the
201 // XXX NumberEditor to spit out a value)
202 protected void validate() {
203 boolean isValid = isValid();
204 mSetAlarmButton.setEnabled(isValid);
205 if (!isValid)
206 mValidateAlarm.deactivate();
207 }
208
209 protected void stopEditing() {
210 mEditingAlarm = null;
211 mValidateAlarm.deactivate();
212 Application.unregisterForEvent(this, Event.EVENT_TIME_CHANGED);
213 }
214
215 public boolean receiveEvent(Event e) {
216 switch (e.type) {
217 case EVENT_SET_ALARM:
218 if (!isValid())
219 return true;
220 mEditingAlarm.setMessage(mMessageField.toString());
221 if (isIn()) {
222 mEditingAlarm.setPeriod(editingInterval(),
223 mRepeatCheckBox.getValue() == 1);
224 } else {
225 mEditingAlarm.setDate(editingDate());
226 }
227 mEditingAlarm.setAlert(mAlertPicker.getRingTone());
228 // schedule before adding so the tooltip is correct
229 mEditingAlarm.schedule();
230 if (mAlarmIsNew) Alarms.addAlarm(mEditingAlarm);
231 Alarms.setDefaultAlarm(mEditingAlarm);
232 stopEditing();
233 return true;
234 case EVENT_CANCEL_ALARM:
235 if (!mAlarmIsNew) mEditingAlarm.resume();
236 stopEditing();
237 return true;
238 case EVENT_DISCARD_ALARM:
239 Alarms.removeAlarm(mEditingAlarm);
240 stopEditing();
241 return true;
242 case Event.EVENT_TIME_CHANGED: // time on device changed
243 case Event.EVENT_ALARM: // computed time invalid
244 case EVENT_VALIDATE: // something changed
245 validate();
246 return true;
247 case EVENT_IN:
248 mAtButton.setValue(0);
249 validate();
250 return true;
251 case EVENT_AT:
252 mInButton.setValue(0);
253 validate();
254 return true;
255 case EVENT_TIME_EDITOR:
256 validate();
257 return true;
258 case EVENT_DATE_EDITOR_TOOK_FOCUS:
259 Date date = editingDate();
260 if (date.compareTo(new Date()) <= 0) {
261 date.addDays(1);
262 mDatePicker.setDate(date);
263 mDateEditor.setDate(date);
264 }
265 validate();
266 return true;
267 case EVENT_DATE_EDITOR:
268 mDatePicker.setDate(mDateEditor.getDate());
269 validate();
270 return true;
271 case EVENT_DATE_PICKER:
272 mDateEditor.setDate((Date)e.argument);
273 validate();
274 return true;
275 }
276 return super.receiveEvent(e);
277 }
278}
Note: See TracBrowser for help on using the repository browser.