package net.sabi.pester; import danger.app.Application; import danger.app.Event; import danger.audio.ToneClass; import danger.audio.ToneRights; import danger.internal.Date; import danger.ui.Button; import danger.ui.CheckBox; import danger.ui.Color; import danger.ui.DateTimeEditor; import danger.ui.DatePicker; import danger.ui.DialogWindow; import danger.ui.Font; import danger.ui.Layout; import danger.ui.MenuItem; import danger.ui.NumberEditor; import danger.ui.Pen; import danger.ui.PopupMenu; import danger.ui.RadioButton; import danger.ui.Rect; import danger.ui.RingTonePicker; import danger.ui.StaticTextBox; import danger.ui.TypeAheadTextField; import danger.util.DEBUG; public class AlarmSetDialog extends DialogWindow implements Resources, Commands { private TypeAheadTextField mMessageField; private RadioButton mInButton, mAtButton; private NumberEditor mPeriodField; private PopupMenu mPeriodUnitsPopup; // XXX don't allow <5 second repeating alarms private CheckBox mRepeatCheckBox; private DateTimeEditor mTimeEditor, mDateEditor; private DatePicker mDatePicker; private RingTonePicker mAlertPicker; private Button mDiscardAlarmButton, mSetAlarmButton; private StaticTextBox mStatusBox; private Alarm mEditingAlarm; private boolean mAlarmIsNew; private boolean haveShownWindow = false; public static AlarmSetDialog getDialog() { AlarmSetDialog dialog = (AlarmSetDialog) Application.getCurrentApp().getDialog(ID_ALARM_SET_DIALOG, null); return dialog; } public void onDecoded() { setCancelButtonEvent(new Event(this, EVENT_CANCEL_ALARM)); mMessageField = (TypeAheadTextField)getDescendantWithID(ID_MESSAGE_FIELD); disableBottomRightButtonOnEmptyField(mMessageField); mInButton = (RadioButton)getDescendantWithID(ID_IN_BUTTON); mAtButton = (RadioButton)getDescendantWithID(ID_AT_BUTTON); mPeriodField = (NumberEditor)getDescendantWithID(ID_PERIOD_FIELD); mPeriodUnitsPopup = (PopupMenu)getDescendantWithID(ID_PERIOD_UNITS_POPUP); mRepeatCheckBox = (CheckBox)getDescendantWithID(ID_PERIOD_REPEAT_CHECKBOX); mTimeEditor = (DateTimeEditor)getDescendantWithID(ID_TIME_EDITOR); mDateEditor = (DateTimeEditor)getDescendantWithID(ID_DATE_EDITOR); mDatePicker = (DatePicker)getDescendantWithID(ID_DATE_PICKER); mAlertPicker = (RingTonePicker)getDescendantWithID(ID_ALERT_PICKER); mSetAlarmButton = (Button)getDescendantWithID(ID_SET_ALARM_BUTTON); mDiscardAlarmButton = (Button)getDescendantWithID(ID_DISCARD_ALARM_BUTTON); mInButton.setValue(1); mDateEditor.limitToDangerEpoch(); mAlertPicker.setGroupFilter(ToneClass.FOREGROUND | ToneClass.CUSTOM); mAlertPicker.setRights(ToneRights.FULL); // this doesn't work properly yet // mAlertPicker.setCanRecord(true); mStatusBox = new StaticTextBox(); mStatusBox.setTransparent(true); mStatusBox.setHasBorder(false); mStatusBox.setFont(Font.findSystemFont()); mStatusBox.setAutoResize(false); super.onDecoded(); } protected void editDateOrPeriod(Alarm alarm) { boolean usesPeriod = alarm.getUsesPeriod(); if (usesPeriod) { int period = alarm.getPeriod(); for (int i = mPeriodUnitsPopup.itemCount() - 1 ; i >= 0 ; --i) { int unitsPerSec = mPeriodUnitsPopup.getItem(i).getEvent().data; if (period % unitsPerSec == 0) { mPeriodUnitsPopup.setValue(i); mPeriodField.setValue(period / unitsPerSec); break; } } mRepeatCheckBox.setValue(alarm.getRepeating() ? 1 : 0); } Date date = alarm.getDate(); mTimeEditor.setDate(date); mDateEditor.setDate(date); mDatePicker.setDate(date); mInButton.setValue(usesPeriod ? 1 : 0); mAtButton.setValue(usesPeriod ? 0 : 1); } public void editAlarm(Alarm alarm, boolean asNew) { mEditingAlarm = alarm; mAlarmIsNew = asNew; alarm.beginEditing(); if (asNew) { mDiscardAlarmButton.hide(); // XXX default to now? } else { mMessageField.setText(alarm.getMessage()); mDiscardAlarmButton.show(); editDateOrPeriod(alarm); mAlertPicker.setRingTone(mEditingAlarm.getAlert()); } validate(); show(); if (!haveShownWindow) { Rect alarmRect = mSetAlarmButton.getFrame(); Rect contentRect = getContentRect(); mStatusBox.setPosition(contentRect.left + 8, alarmRect.top + 2); mStatusBox.setSize(alarmRect.left - 8, 11); mStatusBox.show(); addChild(mStatusBox); haveShownWindow = true; setAutoSize(false); // don't resize to contain it next time } } protected boolean isIn() { return (mInButton.getValue() == 1); } protected int editingInterval() { int itemIndex = mPeriodUnitsPopup.getValue(); MenuItem itemAtIndex = mPeriodUnitsPopup.getItem(itemIndex); Event event = itemAtIndex.getEvent(); return mPeriodField.getValue() * event.data; } protected Date editingDate() { Date date; if (isIn()) { date = new Date(); date.addSeconds(editingInterval()); } else { date = mDateEditor.getDate(); date.setTime(mTimeEditor.getDate().getTime()); date.setSeconds(0); } return date; } protected boolean isValid() { // doesn't redraw properly otherwise invalidate(mStatusBox.getBounds()); if (mMessageField.length() == 0) { mStatusBox.setText("Specify a message."); return false; } Date now = new Date(); mDateEditor.min(now); mDatePicker.min(now); if (!isIn() && editingDate().compareTo(now) <= 0) { mStatusBox.setText("Specify a future date."); return false; } mStatusBox.setText(Alarm.dateTimeString(editingDate(), true)); // XXX invalidate @ alarm date if isIn() // XXX invalidate in 1 sec if isAt() return true; } protected void validate() { mSetAlarmButton.setEnabled(isValid()); } public boolean receiveEvent(Event e) { switch (e.type) { case EVENT_SET_ALARM: if (!isValid()) return true; mEditingAlarm.setMessage(mMessageField.toString()); if (isIn()) { mEditingAlarm.setPeriod(editingInterval(), mRepeatCheckBox.getValue() == 1); } else { mEditingAlarm.setDate(editingDate()); } mEditingAlarm.setAlert(mAlertPicker.getRingTone()); // schedule before adding so the tooltip is correct mEditingAlarm.schedule(); if (mAlarmIsNew) Alarms.addAlarm(mEditingAlarm); mEditingAlarm = null; return true; case EVENT_CANCEL_ALARM: if (!mAlarmIsNew) mEditingAlarm.resume(); mEditingAlarm = null; return true; case EVENT_DISCARD_ALARM: // XXX confirmation Alarms.removeAlarm(mEditingAlarm); mEditingAlarm = null; return true; case EVENT_VALIDATE: // something changed validate(); return true; case EVENT_IN: mAtButton.setValue(0); validate(); return true; case EVENT_AT: mInButton.setValue(0); validate(); return true; case EVENT_TIME_EDITOR: validate(); return true; case EVENT_DATE_EDITOR_TOOK_FOCUS: Date date = editingDate(); if (date.compareTo(new Date()) <= 0) { date.addDays(1); mDatePicker.setDate(date); mDateEditor.setDate(date); } validate(); return true; case EVENT_DATE_EDITOR: mDatePicker.setDate(mDateEditor.getDate()); validate(); return true; case EVENT_DATE_PICKER: mDateEditor.setDate((Date)e.argument); validate(); return true; } return super.receiveEvent(e); } }