// -*- mode: java; c-basic-offset: 2; -*- // Copyright 2009-2011 Google, All Rights reserved // Copyright 2011-2014 MIT, All rights reserved // Released under the Apache License, Version 2.0 // http://www.apache.org/licenses/LICENSE-2.0 package com.google.appinventor.components.runtime; import com.google.appinventor.components.annotations.DesignerComponent; import com.google.appinventor.components.annotations.PropertyCategory; import com.google.appinventor.components.annotations.SimpleEvent; import com.google.appinventor.components.annotations.SimpleFunction; import com.google.appinventor.components.annotations.SimpleObject; import com.google.appinventor.components.annotations.SimpleProperty; import com.google.appinventor.components.common.ComponentCategory; import com.google.appinventor.components.common.YaVersion; import com.google.appinventor.components.runtime.util.Dates; import com.google.appinventor.components.runtime.util.ErrorMessages; import android.app.Dialog; import android.app.TimePickerDialog; import android.text.format.DateFormat; import android.os.Handler; import java.util.Calendar; /** * A button allowing a user to launch the TimePickerDialog. This component is * is based off the ButtonBase class instead of the base Picker class because * unlike the other pickers, the TimePicker does not need to launch a new * activity and get a result. The TimePicker is launched as a dialog. * * @author vedharaju@gmail.com */ @DesignerComponent(version = YaVersion.TIMEPICKER_COMPONENT_VERSION, category = ComponentCategory.USERINTERFACE, description = "<p>A button that, when clicked on, launches a popup" + " dialog to allow the user to select a time.</p>") @SimpleObject public class TimePicker extends ButtonBase { private int hour = 0; private int minute = 0; private TimePickerDialog time; private boolean customTime = false; private Form form; private Calendar instant; private Handler androidUIHandler; /** * Create a new TimePicker component. * * @param container the parent container. */ public TimePicker(ComponentContainer container) { super(container); form = container.$form(); final Calendar c = Calendar.getInstance(); hour = c.get(Calendar.HOUR_OF_DAY); minute = c.get(Calendar.MINUTE); time = new TimePickerDialog(this.container.$context(), timePickerListener, hour, minute, DateFormat.is24HourFormat(this.container.$context())); instant = Dates.TimeInstant(hour, minute); androidUIHandler = new Handler(); } /** * Returns the hour of the time that was last picked using the timepicker. * The time returned is always in the 24hour format. * * @return hour in 24-hour format */ @SimpleProperty( description = "The hour of the last time set using the time picker." + " The hour is in a 24 hour format. If the last time set was 11:53 pm" + ", this property will return 23.", category = PropertyCategory.APPEARANCE) public int Hour() { return hour; } /** * Returns the hour of the time that was last picked using the timepicker. * The time returned is always in the 24hour format. * * @return hour in 24-hour format */ @SimpleProperty( description = "The minute of the last time set using the time picker", category = PropertyCategory.APPEARANCE) public int Minute() { return minute; } /** * Returns the instant in time that was last picked using the DatePicker. * @return instant of the date */ @SimpleProperty( description = "The instant of the last time set using the time picker", category = PropertyCategory.APPEARANCE) public Calendar Instant() { return instant; } @SimpleFunction(description="Set the time to be shown in the Time Picker popup. Current time is shown by default.") public void SetTimeToDisplay(int hour, int minute) { if ((hour < 0) || (hour > 23)) { form.dispatchErrorOccurredEvent(this, "SetTimeToDisplay", ErrorMessages.ERROR_ILLEGAL_HOUR); } else if ((minute < 0) || (minute > 59)) { form.dispatchErrorOccurredEvent(this, "SetTimeToDisplay", ErrorMessages.ERROR_ILLEGAL_MINUTE); } else { time.updateTime(hour, minute); instant = Dates.TimeInstant(hour, minute); customTime = true; } } @SimpleFunction(description="Set the time from the instant to be shown in the Time Picker popup. " + "Current time is shown by default.") public void SetTimeToDisplayFromInstant(Calendar instant) { int hour = Dates.Hour(instant); int minute = Dates.Minute(instant); time.updateTime(hour, minute); instant = Dates.TimeInstant(hour, minute); customTime = true; } @SimpleFunction(description="Launches the TimePicker popup.") public void LaunchPicker(){ click(); } @Override public void click() { if (!customTime) { Calendar c = Calendar.getInstance(); int h = c.get(Calendar.HOUR_OF_DAY); int m = c.get(Calendar.MINUTE); time.updateTime(h, m); instant = Dates.TimeInstant(hour, minute); } else { customTime = false; } time.show(); } private TimePickerDialog.OnTimeSetListener timePickerListener = new TimePickerDialog.OnTimeSetListener() { public void onTimeSet(android.widget.TimePicker view, int selectedHour, int selectedMinute) { if (view.isShown()) { hour = selectedHour; minute = selectedMinute; instant = Dates.TimeInstant(hour, minute); // We post an event to the Android handler to do the App Inventor // event dispatch. This way it gets called outside of the context // of the timepicker's event. This permits the App Inventor dispatch // handler to re-launch this timepicker androidUIHandler.post(new Runnable() { public void run() { AfterTimeSet(); } }); } } }; /** * Indicates the user has set the time. */ @SimpleEvent(description="This event is run when a user has set the time in the popup dialog.") public void AfterTimeSet() { EventDispatcher.dispatchEvent(this, "AfterTimeSet"); } }