diff options
author | leandrogracia@chromium.org <leandrogracia@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-07-03 12:31:16 +0000 |
---|---|---|
committer | leandrogracia@chromium.org <leandrogracia@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-07-03 12:31:16 +0000 |
commit | eb7be252bd1c0861a15d4776dc4ae0ffc49c10c5 (patch) | |
tree | 5dfe1fd773d3cd2b6cdcd6bee5dce66a095aa157 /content | |
parent | 3bcafa841e3c3405fee6bfb11012b240309c1752 (diff) | |
download | chromium_src-eb7be252bd1c0861a15d4776dc4ae0ffc49c10c5.zip chromium_src-eb7be252bd1c0861a15d4776dc4ae0ffc49c10c5.tar.gz chromium_src-eb7be252bd1c0861a15d4776dc4ae0ffc49c10c5.tar.bz2 |
[Android] Add UI pickers.
CL 10626017 introduced a new interface for app resources, enabling to upstream these.
BUG=none
TEST=none
Review URL: https://chromiumcodereview.appspot.com/10664016
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@145291 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'content')
4 files changed, 876 insertions, 0 deletions
diff --git a/content/public/android/java/src/org/chromium/content/app/AppResource.java b/content/public/android/java/src/org/chromium/content/app/AppResource.java index 4178702..3bd7f60 100644 --- a/content/public/android/java/src/org/chromium/content/app/AppResource.java +++ b/content/public/android/java/src/org/chromium/content/app/AppResource.java @@ -21,6 +21,42 @@ public class AppResource { /** Drawable resource for the link preview popup overlay. */ public static int DRAWABLE_LINK_PREVIEW_POPUP_OVERLAY; + /** Id of the date picker view. */ + public static int ID_DATE_PICKER; + + /** Id of the month picker view. */ + public static int ID_MONTH_PICKER; + + /** Id of the time picker view. */ + public static int ID_TIME_PICKER; + + /** Id of the year picker view. */ + public static int ID_YEAR_PICKER; + + /** Id of the view containing the month and year pickers. */ + public static int ID_MONTH_YEAR_PICKERS_CONTAINER; + + /** Layout of the date/time picker dialog. */ + public static int LAYOUT_DATE_TIME_PICKER_DIALOG; + + /** Layout of the month picker. */ + public static int LAYOUT_MONTH_PICKER; + + /** Layout of the month picker dialog. */ + public static int LAYOUT_MONTH_PICKER_DIALOG; + + /** String for the Clear button in the date picker dialog. */ + public static int STRING_DATE_PICKER_DIALOG_CLEAR; + + /** String for the Set button in the date picker dialog. */ + public static int STRING_DATE_PICKER_DIALOG_SET; + + /** String for the title of the date/time picker dialog. */ + public static int STRING_DATE_TIME_PICKER_DIALOG_TITLE; + + /** String for the title of the month picker dialog. */ + public static int STRING_MONTH_PICKER_DIALOG_TITLE; + /** * Iterates through all the resources ids and verifies they have values other than zero. * @return true if all the resources have been registered. diff --git a/content/public/android/java/src/org/chromium/content/browser/DateTimePickerDialog.java b/content/public/android/java/src/org/chromium/content/browser/DateTimePickerDialog.java new file mode 100644 index 0000000..409b88c --- /dev/null +++ b/content/public/android/java/src/org/chromium/content/browser/DateTimePickerDialog.java @@ -0,0 +1,208 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.content.browser; + +import android.app.AlertDialog; +import android.content.Context; +import android.content.DialogInterface; +import android.content.DialogInterface.OnClickListener; +import android.os.Build; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.widget.DatePicker; +import android.widget.TimePicker; +import android.widget.DatePicker.OnDateChangedListener; +import android.widget.TimePicker.OnTimeChangedListener; + +import org.chromium.content.app.AppResource; + +class DateTimePickerDialog extends AlertDialog implements OnClickListener, + OnDateChangedListener, OnTimeChangedListener { + + private static final String YEAR = "year"; + private static final String MONTH = "month"; + private static final String DAY = "day"; + private static final String HOUR = "hour"; + private static final String MINUTE = "minute"; + private static final String IS_24_HOUR = "is24hour"; + + private final DatePicker mDatePicker; + private final TimePicker mTimePicker; + private final OnDateTimeSetListener mCallBack; + + /** + * The callback used to indicate the user is done filling in the date. + */ + public interface OnDateTimeSetListener { + + /** + * @param dateView The DatePicker view associated with this listener. + * @param timeView The TimePicker view associated with this listener. + * @param year The year that was set. + * @param monthOfYear The month that was set (0-11) for compatibility + * with {@link java.util.Calendar}. + * @param dayOfMonth The day of the month that was set. + * @param hourOfDay The hour that was set. + * @param minute The minute that was set. + */ + void onDateTimeSet(DatePicker dateView, TimePicker timeView, int year, int monthOfYear, + int dayOfMonth, int hourOfDay, int minute); + } + + /** + * @param context The context the dialog is to run in. + * @param callBack How the parent is notified that the date is set. + * @param year The initial year of the dialog. + * @param monthOfYear The initial month of the dialog. + * @param dayOfMonth The initial day of the dialog. + */ + public DateTimePickerDialog(Context context, + OnDateTimeSetListener callBack, + int year, + int monthOfYear, + int dayOfMonth, + int hourOfDay, int minute, boolean is24HourView) { + this(context, 0, callBack, year, monthOfYear, dayOfMonth, + hourOfDay, minute, is24HourView); + } + + /** + * @param context The context the dialog is to run in. + * @param theme the theme to apply to this dialog + * @param callBack How the parent is notified that the date is set. + * @param year The initial year of the dialog. + * @param monthOfYear The initial month of the dialog. + * @param dayOfMonth The initial day of the dialog. + */ + public DateTimePickerDialog(Context context, + int theme, + OnDateTimeSetListener callBack, + int year, + int monthOfYear, + int dayOfMonth, + int hourOfDay, int minute, boolean is24HourView) { + super(context, theme); + + mCallBack = callBack; + + assert AppResource.STRING_DATE_PICKER_DIALOG_SET != 0; + assert AppResource.STRING_DATE_TIME_PICKER_DIALOG_TITLE != 0; + assert AppResource.LAYOUT_DATE_TIME_PICKER_DIALOG != 0; + assert AppResource.ID_DATE_PICKER != 0; + assert AppResource.ID_TIME_PICKER != 0; + + setButton(BUTTON_POSITIVE, context.getText( + AppResource.STRING_DATE_PICKER_DIALOG_SET), this); + setButton(BUTTON_NEGATIVE, context.getText(android.R.string.cancel), + (OnClickListener) null); + setIcon(0); + setTitle(context.getText(AppResource.STRING_DATE_TIME_PICKER_DIALOG_TITLE)); + + LayoutInflater inflater = + (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); + View view = inflater.inflate(AppResource.LAYOUT_DATE_TIME_PICKER_DIALOG, null); + setView(view); + mDatePicker = (DatePicker) view.findViewById(AppResource.ID_DATE_PICKER); + mDatePicker.init(year, monthOfYear, dayOfMonth, this); + + mTimePicker = (TimePicker) view.findViewById(AppResource.ID_TIME_PICKER); + mTimePicker.setIs24HourView(is24HourView); + mTimePicker.setCurrentHour(hourOfDay); + mTimePicker.setCurrentMinute(minute); + mTimePicker.setOnTimeChangedListener(this); + } + + @Override + public void onClick(DialogInterface dialog, int which) { + tryNotifyDateTimeSet(); + } + + private void tryNotifyDateTimeSet() { + if (mCallBack != null) { + mDatePicker.clearFocus(); + mCallBack.onDateTimeSet(mDatePicker, mTimePicker, mDatePicker.getYear(), + mDatePicker.getMonth(), mDatePicker.getDayOfMonth(), + mTimePicker.getCurrentHour(), mTimePicker.getCurrentMinute()); + } + } + + @Override + protected void onStop() { + if (Build.VERSION.SDK_INT >= 16) { + tryNotifyDateTimeSet(); + } + super.onStop(); + } + + @Override + public void onDateChanged(DatePicker view, int year, + int month, int day) { + mDatePicker.init(year, month, day, null); + } + + @Override + public void onTimeChanged(TimePicker view, int hourOfDay, int minute) { + /* do nothing */ + } + + /** + * Gets the {@link DatePicker} contained in this dialog. + * + * @return The DatePicker view. + */ + public DatePicker getDatePicker() { + return mDatePicker; + } + + /** + * Gets the {@link TimePicker} contained in this dialog. + * + * @return The TimePicker view. + */ + public TimePicker getTimePicker() { + return mTimePicker; + } + + /** + * Sets the current date. + * + * @param year The date year. + * @param monthOfYear The date month. + * @param dayOfMonth The date day of month. + */ + public void updateDateTime(int year, int monthOfYear, int dayOfMonth, + int hourOfDay, int minutOfHour) { + mDatePicker.updateDate(year, monthOfYear, dayOfMonth); + mTimePicker.setCurrentHour(hourOfDay); + mTimePicker.setCurrentMinute(minutOfHour); + } + + @Override + public Bundle onSaveInstanceState() { + Bundle state = super.onSaveInstanceState(); + state.putInt(YEAR, mDatePicker.getYear()); + state.putInt(MONTH, mDatePicker.getMonth()); + state.putInt(DAY, mDatePicker.getDayOfMonth()); + state.putInt(HOUR, mTimePicker.getCurrentHour()); + state.putInt(MINUTE, mTimePicker.getCurrentMinute()); + state.putBoolean(IS_24_HOUR, mTimePicker.is24HourView()); + return state; + } + + @Override + public void onRestoreInstanceState(Bundle savedInstanceState) { + super.onRestoreInstanceState(savedInstanceState); + int year = savedInstanceState.getInt(YEAR); + int month = savedInstanceState.getInt(MONTH); + int day = savedInstanceState.getInt(DAY); + mDatePicker.init(year, month, day, this); + int hour = savedInstanceState.getInt(HOUR); + int minute = savedInstanceState.getInt(MINUTE); + mTimePicker.setIs24HourView(savedInstanceState.getBoolean(IS_24_HOUR)); + mTimePicker.setCurrentHour(hour); + mTimePicker.setCurrentMinute(minute); + } +} diff --git a/content/public/android/java/src/org/chromium/content/browser/MonthPicker.java b/content/public/android/java/src/org/chromium/content/browser/MonthPicker.java new file mode 100644 index 0000000..f70a771 --- /dev/null +++ b/content/public/android/java/src/org/chromium/content/browser/MonthPicker.java @@ -0,0 +1,481 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.content.browser; + +import android.content.Context; +import android.content.res.Configuration; +import android.os.Parcel; +import android.os.Parcelable; +import android.text.format.DateUtils; +import android.util.AttributeSet; +import android.util.SparseArray; +import android.view.LayoutInflater; +import android.view.accessibility.AccessibilityEvent; +import android.widget.DatePicker; +import android.widget.FrameLayout; +import android.widget.LinearLayout; +import android.widget.NumberPicker; +import android.widget.NumberPicker.OnValueChangeListener; + +import java.util.Arrays; +import java.util.Calendar; +import java.util.Locale; +import java.util.TimeZone; + +import org.chromium.content.app.AppResource; + +// This class is heavily based on android.widget.DatePicker. +public class MonthPicker extends FrameLayout { + + private static final int DEFAULT_START_YEAR = 1900; + + private static final int DEFAULT_END_YEAR = 2100; + + private static final boolean DEFAULT_ENABLED_STATE = true; + + private final LinearLayout mSpinners; + + private final NumberPicker mMonthSpinner; + + private final NumberPicker mYearSpinner; + + private Locale mCurrentLocale; + + private OnMonthChangedListener mMonthChangedListener; + + private String[] mShortMonths; + + private int mNumberOfMonths; + + private Calendar mTempDate; + + private Calendar mMinDate; + + private Calendar mMaxDate; + + private Calendar mCurrentDate; + + private boolean mIsEnabled = DEFAULT_ENABLED_STATE; + + /** + * The callback used to indicate the user changes\d the date. + */ + public interface OnMonthChangedListener { + + /** + * Called upon a date change. + * + * @param view The view associated with this listener. + * @param year The year that was set. + * @param monthOfYear The month that was set (0-11) for compatibility + * with {@link java.util.Calendar}. + */ + void onMonthChanged(MonthPicker view, int year, int monthOfYear); + } + + public MonthPicker(Context context) { + this(context, null); + } + + public MonthPicker(Context context, AttributeSet attrs) { + this(context, attrs, android.R.attr.datePickerStyle); + } + + public MonthPicker(Context context, AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + + // initialization based on locale + setCurrentLocale(Locale.getDefault()); + + int startYear = DEFAULT_START_YEAR; + int endYear = DEFAULT_END_YEAR; + + LayoutInflater inflater = (LayoutInflater) context + .getSystemService(Context.LAYOUT_INFLATER_SERVICE); + assert AppResource.LAYOUT_MONTH_PICKER != 0; + inflater.inflate(AppResource.LAYOUT_MONTH_PICKER, this, true); + + OnValueChangeListener onChangeListener = new OnValueChangeListener() { + public void onValueChange(NumberPicker picker, int oldVal, int newVal) { + mTempDate.setTimeInMillis(mCurrentDate.getTimeInMillis()); + // take care of wrapping of days and months to update greater fields + if (picker == mMonthSpinner) { + if (oldVal == 11 && newVal == 0) { + mTempDate.add(Calendar.MONTH, 1); + } else if (oldVal == 0 && newVal == 11) { + mTempDate.add(Calendar.MONTH, -1); + } else { + mTempDate.add(Calendar.MONTH, newVal - oldVal); + } + } else if (picker == mYearSpinner) { + mTempDate.set(Calendar.YEAR, newVal); + } else { + throw new IllegalArgumentException(); + } + // now set the date to the adjusted one + setDate(mTempDate.get(Calendar.YEAR), mTempDate.get(Calendar.MONTH)); + updateSpinners(); + notifyDateChanged(); + } + }; + + assert AppResource.ID_MONTH_YEAR_PICKERS_CONTAINER != 0; + mSpinners = (LinearLayout) findViewById(AppResource.ID_MONTH_YEAR_PICKERS_CONTAINER); + + // month + assert AppResource.ID_MONTH_PICKER != 0; + mMonthSpinner = (NumberPicker) findViewById(AppResource.ID_MONTH_PICKER); + mMonthSpinner.setMinValue(0); + mMonthSpinner.setMaxValue(mNumberOfMonths - 1); + mMonthSpinner.setDisplayedValues(mShortMonths); + mMonthSpinner.setOnLongPressUpdateInterval(200); + mMonthSpinner.setOnValueChangedListener(onChangeListener); + + // year + assert AppResource.ID_YEAR_PICKER != 0; + mYearSpinner = (NumberPicker) findViewById(AppResource.ID_YEAR_PICKER); + mYearSpinner.setOnLongPressUpdateInterval(100); + mYearSpinner.setOnValueChangedListener(onChangeListener); + + mTempDate.clear(); + mTempDate.set(startYear, 0, 1); + + setMinDate(mTempDate.getTimeInMillis()); + + mTempDate.clear(); + mTempDate.set(endYear, 11, 31); + setMaxDate(mTempDate.getTimeInMillis()); + + // initialize to current date + mCurrentDate.setTimeInMillis(System.currentTimeMillis()); + init(mCurrentDate.get(Calendar.YEAR), mCurrentDate.get(Calendar.MONTH), null); + } + + /** + * Gets the minimal date supported by this {@link DatePicker} in + * milliseconds since January 1, 1970 00:00:00 in + * {@link TimeZone#getDefault()} time zone. + * <p> + * Note: The default minimal date is 01/01/1900. + * <p> + * + * @return The minimal supported date. + */ + public long getMinDate() { + return mMinDate.getTimeInMillis(); + } + + /** + * Sets the minimal date supported by this {@link NumberPicker} in + * milliseconds since January 1, 1970 00:00:00 in + * {@link TimeZone#getDefault()} time zone. + * + * @param minDate The minimal supported date. + */ + public void setMinDate(long minDate) { + mTempDate.setTimeInMillis(minDate); + if (mTempDate.get(Calendar.YEAR) == mMinDate.get(Calendar.YEAR) + && mTempDate.get(Calendar.DAY_OF_YEAR) != mMinDate.get(Calendar.DAY_OF_YEAR)) { + return; + } + mMinDate.setTimeInMillis(minDate); + if (mCurrentDate.before(mMinDate)) { + mCurrentDate.setTimeInMillis(mMinDate.getTimeInMillis()); + } + updateSpinners(); + } + + /** + * Gets the maximal date supported by this {@link DatePicker} in + * milliseconds since January 1, 1970 00:00:00 in + * {@link TimeZone#getDefault()} time zone. + * <p> + * Note: The default maximal date is 12/31/2100. + * <p> + * + * @return The maximal supported date. + */ + public long getMaxDate() { + return mMaxDate.getTimeInMillis(); + } + + /** + * Sets the maximal date supported by this {@link DatePicker} in + * milliseconds since January 1, 1970 00:00:00 in + * {@link TimeZone#getDefault()} time zone. + * + * @param maxDate The maximal supported date. + */ + public void setMaxDate(long maxDate) { + mTempDate.setTimeInMillis(maxDate); + if (mTempDate.get(Calendar.YEAR) == mMaxDate.get(Calendar.YEAR) + && mTempDate.get(Calendar.DAY_OF_YEAR) != mMaxDate.get(Calendar.DAY_OF_YEAR)) { + return; + } + mMaxDate.setTimeInMillis(maxDate); + if (mCurrentDate.after(mMaxDate)) { + mCurrentDate.setTimeInMillis(mMaxDate.getTimeInMillis()); + } + updateSpinners(); + } + + @Override + public void setEnabled(boolean enabled) { + if (mIsEnabled == enabled) { + return; + } + super.setEnabled(enabled); + mMonthSpinner.setEnabled(enabled); + mYearSpinner.setEnabled(enabled); + mIsEnabled = enabled; + } + + @Override + public boolean isEnabled() { + return mIsEnabled; + } + + @Override + public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) { + onPopulateAccessibilityEvent(event); + return true; + } + + @Override + public void onPopulateAccessibilityEvent(AccessibilityEvent event) { + super.onPopulateAccessibilityEvent(event); + + final int flags = DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_SHOW_YEAR; + String selectedDateUtterance = DateUtils.formatDateTime(getContext(), + mCurrentDate.getTimeInMillis(), flags); + event.getText().add(selectedDateUtterance); + } + + @Override + protected void onConfigurationChanged(Configuration newConfig) { + super.onConfigurationChanged(newConfig); + setCurrentLocale(newConfig.locale); + } + + /** + * Sets the current locale. + * + * @param locale The current locale. + */ + private void setCurrentLocale(Locale locale) { + if (locale.equals(mCurrentLocale)) { + return; + } + + mCurrentLocale = locale; + + mTempDate = getCalendarForLocale(mTempDate, locale); + mMinDate = getCalendarForLocale(mMinDate, locale); + mMaxDate = getCalendarForLocale(mMaxDate, locale); + mCurrentDate = getCalendarForLocale(mCurrentDate, locale); + + mNumberOfMonths = mTempDate.getActualMaximum(Calendar.MONTH) + 1; + mShortMonths = new String[mNumberOfMonths]; + for (int i = 0; i < mNumberOfMonths; i++) { + mShortMonths[i] = DateUtils.getMonthString(Calendar.JANUARY + i, + DateUtils.LENGTH_MEDIUM); + } + } + + /** + * Gets a calendar for locale bootstrapped with the value of a given calendar. + * + * @param oldCalendar The old calendar. + * @param locale The locale. + */ + private Calendar getCalendarForLocale(Calendar oldCalendar, Locale locale) { + if (oldCalendar == null) { + return Calendar.getInstance(locale); + } else { + final long currentTimeMillis = oldCalendar.getTimeInMillis(); + Calendar newCalendar = Calendar.getInstance(locale); + newCalendar.setTimeInMillis(currentTimeMillis); + return newCalendar; + } + } + + /** + * Updates the current date. + * + * @param year The year. + * @param month The month which is <strong>starting from zero</strong>. + */ + public void updateMonth(int year, int month) { + if (!isNewDate(year, month)) { + return; + } + setDate(year, month); + updateSpinners(); + notifyDateChanged(); + } + + // Override so we are in complete control of save / restore for this widget. + @Override + protected void dispatchRestoreInstanceState(SparseArray<Parcelable> container) { + dispatchThawSelfOnly(container); + } + + @Override + protected Parcelable onSaveInstanceState() { + Parcelable superState = super.onSaveInstanceState(); + return new SavedState(superState, getYear(), getMonth()); + } + + @Override + protected void onRestoreInstanceState(Parcelable state) { + SavedState ss = (SavedState) state; + super.onRestoreInstanceState(ss.getSuperState()); + setDate(ss.mYear, ss.mMonth); + updateSpinners(); + } + + /** + * Initialize the state. If the provided values designate an inconsistent + * date the values are normalized before updating the spinners. + * + * @param year The initial year. + * @param monthOfYear The initial month <strong>starting from zero</strong>. + * @param onMonthChangedListener How user is notified date is changed by + * user, can be null. + */ + public void init(int year, int monthOfYear, OnMonthChangedListener onMonthChangedListener) { + setDate(year, monthOfYear); + updateSpinners(); + mMonthChangedListener = onMonthChangedListener; + } + + private boolean isNewDate(int year, int month) { + return (mCurrentDate.get(Calendar.YEAR) != year + || mCurrentDate.get(Calendar.MONTH) != month); + } + + private void setDate(int year, int month) { + mCurrentDate.set(year, month, 1); + if (mCurrentDate.before(mMinDate)) { + mCurrentDate.setTimeInMillis(mMinDate.getTimeInMillis()); + } else if (mCurrentDate.after(mMaxDate)) { + mCurrentDate.setTimeInMillis(mMaxDate.getTimeInMillis()); + } + } + + private void updateSpinners() { + // set the spinner ranges respecting the min and max dates + if (mCurrentDate.equals(mMinDate)) { + mMonthSpinner.setDisplayedValues(null); + mMonthSpinner.setMinValue(mCurrentDate.get(Calendar.MONTH)); + mMonthSpinner.setMaxValue(mCurrentDate.getActualMaximum(Calendar.MONTH)); + mMonthSpinner.setWrapSelectorWheel(false); + } else if (mCurrentDate.equals(mMaxDate)) { + mMonthSpinner.setDisplayedValues(null); + mMonthSpinner.setMinValue(mCurrentDate.getActualMinimum(Calendar.MONTH)); + mMonthSpinner.setMaxValue(mCurrentDate.get(Calendar.MONTH)); + mMonthSpinner.setWrapSelectorWheel(false); + } else { + mMonthSpinner.setDisplayedValues(null); + mMonthSpinner.setMinValue(0); + mMonthSpinner.setMaxValue(11); + mMonthSpinner.setWrapSelectorWheel(true); + } + + // make sure the month names are a zero based array + // with the months in the month spinner + String[] displayedValues = Arrays.copyOfRange(mShortMonths, + mMonthSpinner.getMinValue(), mMonthSpinner.getMaxValue() + 1); + mMonthSpinner.setDisplayedValues(displayedValues); + + // year spinner range does not change based on the current date + mYearSpinner.setMinValue(mMinDate.get(Calendar.YEAR)); + mYearSpinner.setMaxValue(mMaxDate.get(Calendar.YEAR)); + mYearSpinner.setWrapSelectorWheel(false); + + // set the spinner values + mYearSpinner.setValue(mCurrentDate.get(Calendar.YEAR)); + mMonthSpinner.setValue(mCurrentDate.get(Calendar.MONTH)); + } + + /** + * @return The selected year. + */ + public int getYear() { + return mCurrentDate.get(Calendar.YEAR); + } + + /** + * @return The selected month. + */ + public int getMonth() { + return mCurrentDate.get(Calendar.MONTH); + } + + /** + * @return The selected day of month. + */ + public int getDayOfMonth() { + return mCurrentDate.get(Calendar.DAY_OF_MONTH); + } + + /** + * Notifies the listener, if such, for a change in the selected date. + */ + private void notifyDateChanged() { + sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_SELECTED); + if (mMonthChangedListener != null) { + mMonthChangedListener.onMonthChanged(this, getYear(), getMonth()); + } + } + + /** + * Class for managing state storing/restoring. + */ + private static class SavedState extends BaseSavedState { + + private final int mYear; + + private final int mMonth; + + /** + * Constructor called from {@link DatePicker#onSaveInstanceState()} + */ + private SavedState(Parcelable superState, int year, int month) { + super(superState); + mYear = year; + mMonth = month; + } + + /** + * Constructor called from {@link #CREATOR} + */ + private SavedState(Parcel in) { + super(in); + mYear = in.readInt(); + mMonth = in.readInt(); + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + super.writeToParcel(dest, flags); + dest.writeInt(mYear); + dest.writeInt(mMonth); + } + + @SuppressWarnings("all") + // suppress unused and hiding + public static final Parcelable.Creator<SavedState> CREATOR = new Creator<SavedState>() { + + public SavedState createFromParcel(Parcel in) { + return new SavedState(in); + } + + public SavedState[] newArray(int size) { + return new SavedState[size]; + } + }; + } +} diff --git a/content/public/android/java/src/org/chromium/content/browser/MonthPickerDialog.java b/content/public/android/java/src/org/chromium/content/browser/MonthPickerDialog.java new file mode 100644 index 0000000..23fe793 --- /dev/null +++ b/content/public/android/java/src/org/chromium/content/browser/MonthPickerDialog.java @@ -0,0 +1,151 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.content.browser; + +import android.app.AlertDialog; +import android.content.Context; +import android.content.DialogInterface; +import android.content.DialogInterface.OnClickListener; +import android.os.Build; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; + +import org.chromium.content.app.AppResource; +import org.chromium.content.browser.MonthPicker.OnMonthChangedListener; + +public class MonthPickerDialog extends AlertDialog implements OnClickListener, + OnMonthChangedListener { + + private static final String YEAR = "year"; + private static final String MONTH = "month"; + + private final MonthPicker mMonthPicker; + private final OnMonthSetListener mCallBack; + + /** + * The callback used to indicate the user is done filling in the date. + */ + public interface OnMonthSetListener { + + /** + * @param view The view associated with this listener. + * @param year The year that was set. + * @param monthOfYear The month that was set (0-11) for compatibility + * with {@link java.util.Calendar}. + */ + void onMonthSet(MonthPicker view, int year, int monthOfYear); + } + + /** + * @param context The context the dialog is to run in. + * @param callBack How the parent is notified that the date is set. + * @param year The initial year of the dialog. + * @param monthOfYear The initial month of the dialog. + */ + public MonthPickerDialog(Context context, + OnMonthSetListener callBack, + int year, + int monthOfYear) { + this(context, 0, callBack, year, monthOfYear); + } + + /** + * @param context The context the dialog is to run in. + * @param theme the theme to apply to this dialog + * @param callBack How the parent is notified that the date is set. + * @param year The initial year of the dialog. + * @param monthOfYear The initial month of the dialog. + */ + public MonthPickerDialog(Context context, + int theme, + OnMonthSetListener callBack, + int year, + int monthOfYear) { + super(context, theme); + + mCallBack = callBack; + + assert AppResource.STRING_DATE_PICKER_DIALOG_SET != 0; + assert AppResource.STRING_MONTH_PICKER_DIALOG_TITLE != 0; + assert AppResource.LAYOUT_MONTH_PICKER_DIALOG != 0; + assert AppResource.ID_DATE_PICKER != 0; + + setButton(BUTTON_POSITIVE, context.getText( + AppResource.STRING_DATE_PICKER_DIALOG_SET), this); + setButton(BUTTON_NEGATIVE, context.getText(android.R.string.cancel), + (OnClickListener) null); + setIcon(0); + setTitle(AppResource.STRING_MONTH_PICKER_DIALOG_TITLE); + + LayoutInflater inflater = + (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); + View view = inflater.inflate(AppResource.LAYOUT_MONTH_PICKER_DIALOG, null); + setView(view); + mMonthPicker = (MonthPicker) view.findViewById(AppResource.ID_DATE_PICKER); + mMonthPicker.init(year, monthOfYear, this); + } + + @Override + public void onClick(DialogInterface dialog, int which) { + tryNotifyMonthSet(); + } + + private void tryNotifyMonthSet() { + if (mCallBack != null) { + mMonthPicker.clearFocus(); + mCallBack.onMonthSet(mMonthPicker, mMonthPicker.getYear(), + mMonthPicker.getMonth()); + } + } + + @Override + protected void onStop() { + if (Build.VERSION.SDK_INT >= 16) { + tryNotifyMonthSet(); + } + super.onStop(); + } + + @Override + public void onMonthChanged(MonthPicker view, int year, int month) { + mMonthPicker.init(year, month, null); + } + + /** + * Gets the {@link MonthPicker} contained in this dialog. + * + * @return The calendar view. + */ + public MonthPicker getMonthPicker() { + return mMonthPicker; + } + + /** + * Sets the current date. + * + * @param year The date year. + * @param monthOfYear The date month. + */ + public void updateDate(int year, int monthOfYear) { + mMonthPicker.updateMonth(year, monthOfYear); + } + + @Override + public Bundle onSaveInstanceState() { + Bundle state = super.onSaveInstanceState(); + state.putInt(YEAR, mMonthPicker.getYear()); + state.putInt(MONTH, mMonthPicker.getMonth()); + return state; + } + + @Override + public void onRestoreInstanceState(Bundle savedInstanceState) { + super.onRestoreInstanceState(savedInstanceState); + int year = savedInstanceState.getInt(YEAR); + int month = savedInstanceState.getInt(MONTH); + mMonthPicker.init(year, month, this); + } +} |