1/*
2 * Copyright (C) 2007 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.app;
18
19import android.content.Context;
20import android.content.DialogInterface;
21import android.content.DialogInterface.OnClickListener;
22import android.os.Bundle;
23import android.util.TypedValue;
24import android.view.LayoutInflater;
25import android.view.View;
26import android.widget.Button;
27import android.widget.TimePicker;
28import android.widget.TimePicker.OnTimeChangedListener;
29import android.widget.TimePicker.ValidationCallback;
30
31import com.android.internal.R;
32
33/**
34 * A dialog that prompts the user for the time of day using a
35 * {@link TimePicker}.
36 *
37 * <p>
38 * See the <a href="{@docRoot}guide/topics/ui/controls/pickers.html">Pickers</a>
39 * guide.
40 */
41public class TimePickerDialog extends AlertDialog implements OnClickListener,
42        OnTimeChangedListener {
43    private static final String HOUR = "hour";
44    private static final String MINUTE = "minute";
45    private static final String IS_24_HOUR = "is24hour";
46
47    private final TimePicker mTimePicker;
48    private final OnTimeSetListener mTimeSetListener;
49
50    private final int mInitialHourOfDay;
51    private final int mInitialMinute;
52    private final boolean mIs24HourView;
53
54    /**
55     * The callback interface used to indicate the user is done filling in
56     * the time (e.g. they clicked on the 'OK' button).
57     */
58    public interface OnTimeSetListener {
59        /**
60         * Called when the user is done setting a new time and the dialog has
61         * closed.
62         *
63         * @param view the view associated with this listener
64         * @param hourOfDay the hour that was set
65         * @param minute the minute that was set
66         */
67        public void onTimeSet(TimePicker view, int hourOfDay, int minute);
68    }
69
70    /**
71     * Creates a new time picker dialog.
72     *
73     * @param context the parent context
74     * @param listener the listener to call when the time is set
75     * @param hourOfDay the initial hour
76     * @param minute the initial minute
77     * @param is24HourView whether this is a 24 hour view or AM/PM
78     */
79    public TimePickerDialog(Context context, OnTimeSetListener listener, int hourOfDay, int minute,
80            boolean is24HourView) {
81        this(context, 0, listener, hourOfDay, minute, is24HourView);
82    }
83
84    static int resolveDialogTheme(Context context, int resId) {
85        if (resId == 0) {
86            final TypedValue outValue = new TypedValue();
87            context.getTheme().resolveAttribute(R.attr.timePickerDialogTheme, outValue, true);
88            return outValue.resourceId;
89        } else {
90            return resId;
91        }
92    }
93
94    /**
95     * Creates a new time picker dialog with the specified theme.
96     *
97     * @param context the parent context
98     * @param themeResId the resource ID of the theme to apply to this dialog
99     * @param listener the listener to call when the time is set
100     * @param hourOfDay the initial hour
101     * @param minute the initial minute
102     * @param is24HourView Whether this is a 24 hour view, or AM/PM.
103     */
104    public TimePickerDialog(Context context, int themeResId, OnTimeSetListener listener,
105            int hourOfDay, int minute, boolean is24HourView) {
106        super(context, resolveDialogTheme(context, themeResId));
107
108        mTimeSetListener = listener;
109        mInitialHourOfDay = hourOfDay;
110        mInitialMinute = minute;
111        mIs24HourView = is24HourView;
112
113        final Context themeContext = getContext();
114
115
116        final TypedValue outValue = new TypedValue();
117        context.getTheme().resolveAttribute(R.attr.timePickerDialogTheme, outValue, true);
118        final int layoutResId = outValue.resourceId;
119
120        final LayoutInflater inflater = LayoutInflater.from(themeContext);
121        final View view = inflater.inflate(R.layout.time_picker_dialog, null);
122        setView(view);
123        setButton(BUTTON_POSITIVE, themeContext.getString(R.string.ok), this);
124        setButton(BUTTON_NEGATIVE, themeContext.getString(R.string.cancel), this);
125        setButtonPanelLayoutHint(LAYOUT_HINT_SIDE);
126
127        mTimePicker = (TimePicker) view.findViewById(R.id.timePicker);
128        mTimePicker.setIs24HourView(mIs24HourView);
129        mTimePicker.setCurrentHour(mInitialHourOfDay);
130        mTimePicker.setCurrentMinute(mInitialMinute);
131        mTimePicker.setOnTimeChangedListener(this);
132        mTimePicker.setValidationCallback(mValidationCallback);
133    }
134
135    @Override
136    public void onTimeChanged(TimePicker view, int hourOfDay, int minute) {
137        /* do nothing */
138    }
139
140    @Override
141    public void onClick(DialogInterface dialog, int which) {
142        switch (which) {
143            case BUTTON_POSITIVE:
144                if (mTimeSetListener != null) {
145                    mTimeSetListener.onTimeSet(mTimePicker, mTimePicker.getCurrentHour(),
146                            mTimePicker.getCurrentMinute());
147                }
148                break;
149            case BUTTON_NEGATIVE:
150                cancel();
151                break;
152        }
153    }
154
155    /**
156     * Sets the current time.
157     *
158     * @param hourOfDay The current hour within the day.
159     * @param minuteOfHour The current minute within the hour.
160     */
161    public void updateTime(int hourOfDay, int minuteOfHour) {
162        mTimePicker.setCurrentHour(hourOfDay);
163        mTimePicker.setCurrentMinute(minuteOfHour);
164    }
165
166    @Override
167    public Bundle onSaveInstanceState() {
168        final Bundle state = super.onSaveInstanceState();
169        state.putInt(HOUR, mTimePicker.getCurrentHour());
170        state.putInt(MINUTE, mTimePicker.getCurrentMinute());
171        state.putBoolean(IS_24_HOUR, mTimePicker.is24HourView());
172        return state;
173    }
174
175    @Override
176    public void onRestoreInstanceState(Bundle savedInstanceState) {
177        super.onRestoreInstanceState(savedInstanceState);
178        final int hour = savedInstanceState.getInt(HOUR);
179        final int minute = savedInstanceState.getInt(MINUTE);
180        mTimePicker.setIs24HourView(savedInstanceState.getBoolean(IS_24_HOUR));
181        mTimePicker.setCurrentHour(hour);
182        mTimePicker.setCurrentMinute(minute);
183    }
184
185    private final ValidationCallback mValidationCallback = new ValidationCallback() {
186        @Override
187        public void onValidationChanged(boolean valid) {
188            final Button positive = getButton(BUTTON_POSITIVE);
189            if (positive != null) {
190                positive.setEnabled(valid);
191            }
192        }
193    };
194}
195