/* * Copyright 2008 Google Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of * the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. */ package com.google.gwt.user.datepicker.client; import com.google.gwt.dom.client.Element; import com.google.gwt.event.dom.client.ChangeEvent; import com.google.gwt.event.dom.client.ChangeHandler; import com.google.gwt.event.dom.client.ClickEvent; import com.google.gwt.event.dom.client.ClickHandler; import com.google.gwt.safehtml.shared.annotations.IsSafeHtml; import com.google.gwt.user.client.ui.FlexTable; import com.google.gwt.user.client.ui.ListBox; import com.google.gwt.user.client.ui.PushButton; import com.google.gwt.user.client.ui.Widget; import java.util.Date; /** * A simple {@link MonthSelector} used for the default date picker. It allows to select months and * years but the name is not changed for backward compatibility. Also not extensible as we wish to * evolve it freely over time. */ public final class DefaultMonthSelector extends MonthSelector { private PushButton monthBackwards; private PushButton monthForwards; private FlexTable grid; private PushButton yearBackwards; private PushButton yearForwards; private ListBox monthSelect; private ListBox yearSelect; private int monthColumn; /** * Returns the button for moving to the previous month. */ public Element getBackwardButtonElement() { return monthBackwards.getElement(); } /** * Returns the button for moving to the next month. */ public Element getForwardButtonElement() { return monthForwards.getElement(); } /** * Returns the button for moving to the previous year. */ public Element getYearBackwardButtonElement() { return yearBackwards.getElement(); } /** * Returns the button for moving to the next year. */ public Element getYearForwardButtonElement() { return yearForwards.getElement(); } /** * Returns the ListBox for selecting the month */ public ListBox getMonthSelectListBox() { return monthSelect; } /** * Returns the ListBox for selecting the year */ public ListBox getYearSelectListBox() { return yearSelect; } @Override protected void refresh() { if (isDatePickerConfigChanged()) { // if the config has changed since the last refresh, rebuild the grid setupGrid(); } setDate(getModel().getCurrentMonth()); } @Override protected void setup() { // previous, next buttons monthBackwards = createNavigationButton("‹", -1, css().previousButton()); monthForwards = createNavigationButton("›", 1, css().nextButton()); yearBackwards = createNavigationButton("«", -12, css().previousYearButton()); yearForwards = createNavigationButton("»", 12, css().nextYearButton()); // month and year selector monthSelect = createMonthSelect(); yearSelect = createYearSelect(); // Set up grid. grid = new FlexTable(); grid.setStyleName(css().monthSelector()); setupGrid(); initWidget(grid); } private PushButton createNavigationButton( @IsSafeHtml String label, final int noOfMonths, String styleName) { PushButton button = new PushButton(); button.addClickHandler(new ClickHandler() { public void onClick(ClickEvent event) { addMonths(noOfMonths); } }); button.getUpFace().setHTML(label); button.setStyleName(styleName); return button; } private ListBox createMonthSelect() { final ListBox monthListBox = new ListBox(); for (int i = 0; i < CalendarModel.MONTHS_IN_YEAR; i++) { monthListBox.addItem(getModel().formatMonth(i)); } monthListBox.addChangeHandler(new ChangeHandler() { @Override public void onChange(ChangeEvent event) { int previousMonth = getModel().getCurrentMonth().getMonth(); int newMonth = monthListBox.getSelectedIndex(); int delta = newMonth - previousMonth; addMonths(delta); } }); return monthListBox; } private ListBox createYearSelect() { final ListBox yearListBox = new ListBox(); yearListBox.addChangeHandler(new ChangeHandler() { @Override public void onChange(ChangeEvent event) { int deltaYears = yearListBox.getSelectedIndex() - getNoOfYearsToDisplayBefore(); addMonths(deltaYears * CalendarModel.MONTHS_IN_YEAR); } }); return yearListBox; } private boolean isDatePickerConfigChanged() { boolean isMonthCurrentlySelectable = monthSelect.getParent() != null; boolean isYearNavigationCurrentlyEnabled = yearBackwards.getParent() != null; return getDatePicker().isYearAndMonthDropdownVisible() != isMonthCurrentlySelectable || getDatePicker().isYearArrowsVisible() != isYearNavigationCurrentlyEnabled; } private void setDate(Date date) { if (getDatePicker().isYearAndMonthDropdownVisible()) { // setup months dropdown int month = date.getMonth(); monthSelect.setSelectedIndex(month); // setup years dropdown yearSelect.clear(); int year = date.getYear(); int startYear = year - getNoOfYearsToDisplayBefore(); int endYear = year + getNoOfYearsToDisplayAfter(); Date newDate = new Date(); for (int i = startYear; i <= endYear; i++) { newDate.setYear(i); yearSelect.addItem(getModel().getYearFormatter().format(newDate)); } yearSelect.setSelectedIndex(year - startYear); } else { grid.setText(0, monthColumn, getModel().formatCurrentMonthAndYear()); } } private int getNoOfYearsToDisplayBefore() { return (getDatePicker().getVisibleYearCount() - 1) / 2; } private int getNoOfYearsToDisplayAfter() { return getDatePicker().getVisibleYearCount() / 2; } private void setupGrid() { grid.removeAllRows(); grid.insertRow(0); // Back arrows if (getDatePicker().isYearArrowsVisible()) { addCell(yearBackwards, "1"); } addCell(monthBackwards, "1"); // Month/Year column if (getDatePicker().isYearAndMonthDropdownVisible()) { // Drop-down if (getModel().isMonthBeforeYear()) { addCell(monthSelect, "50%", css().month()); addCell(yearSelect, "50%", css().year()); } else { addCell(yearSelect, "50%", css().year()); addCell(monthSelect, "50%", css().month()); } } else { // Text-only monthColumn = addCell(null, "100%", css().month()); } // Forward arrows addCell(monthForwards, "1"); if (getDatePicker().isYearArrowsVisible()) { addCell(yearForwards, "1"); } } private int addCell(Widget widget, String width) { return addCell(widget, width, null); } private int addCell(Widget widget, String width, String className) { int cell = grid.getCellCount(0); grid.setWidget(0, cell, widget); grid.getCellFormatter().setWidth(0, cell, width); if (className != null) { grid.getCellFormatter().setStyleName(0, cell, className); } return cell; } }