| /* |
| * 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.KeyDownEvent; |
| import com.google.gwt.event.dom.client.KeyCodes; |
| import com.google.gwt.user.client.DOM; |
| import com.google.gwt.user.client.Event; |
| import com.google.gwt.user.client.impl.ElementMapperImpl; |
| import com.google.gwt.user.client.ui.Grid; |
| import com.google.gwt.user.client.ui.UIObject; |
| |
| import java.util.ArrayList; |
| import java.util.Iterator; |
| |
| /** |
| * Highlighting, selectable cell grid. Used to help construct the default |
| * calendar view. |
| * |
| * @param <V> type of value in grid. |
| */ |
| @SuppressWarnings("unchecked") |
| abstract class CellGridImpl<V> extends Grid { |
| |
| /** |
| * Cell type. |
| */ |
| public abstract class Cell extends UIObject { |
| private boolean enabled = true; |
| private V value; |
| private int index; |
| |
| /** |
| * Create a cell grid. |
| * |
| * @param elem the wrapped element |
| * @param value the value |
| */ |
| public Cell(Element elem, V value) { |
| this.value = value; |
| Cell current = this; |
| index = cellList.size(); |
| cellList.add(current); |
| |
| setElement(elem); |
| elementToCell.put(current); |
| } |
| |
| public V getValue() { |
| return value; |
| } |
| |
| public boolean isEnabled() { |
| return enabled; |
| } |
| |
| public boolean isHighlighted() { |
| return this == highlightedCell; |
| } |
| |
| public boolean isSelected() { |
| return selectedCell == this; |
| } |
| |
| public final void setEnabled(boolean enabled) { |
| this.enabled = enabled; |
| onEnabled(enabled); |
| } |
| |
| public void verticalNavigation(int keyCode) { |
| switch (keyCode) { |
| case KeyCodes.KEY_UP: |
| setHighlighted(previousItem()); |
| break; |
| case KeyCodes.KEY_DOWN: |
| setHighlighted(nextItem()); |
| break; |
| case KeyCodes.KEY_ESCAPE: |
| // Figure out new event for this. |
| break; |
| case KeyCodes.KEY_ENTER: |
| setSelected(this); |
| break; |
| } |
| } |
| |
| protected Cell nextItem() { |
| if (index == getLastIndex()) { |
| return cellList.get(0); |
| } else { |
| return cellList.get(index + 1); |
| } |
| } |
| |
| /** |
| * @param enabled |
| */ |
| protected void onEnabled(boolean enabled) { |
| updateStyle(); |
| } |
| |
| /** |
| * @param highlighted |
| */ |
| protected void onHighlighted(boolean highlighted) { |
| updateStyle(); |
| } |
| |
| /** |
| * @param selected |
| */ |
| protected void onSelected(boolean selected) { |
| updateStyle(); |
| } |
| |
| protected Cell previousItem() { |
| if (index != 0) { |
| return cellList.get(index - 1); |
| } else { |
| return cellList.get(getLastIndex()); |
| } |
| } |
| |
| protected abstract void updateStyle(); |
| |
| private int getLastIndex() { |
| return cellList.size() - 1; |
| } |
| } |
| |
| private Cell highlightedCell; |
| |
| private Cell selectedCell; |
| private ElementMapperImpl<Cell> elementToCell = new ElementMapperImpl<Cell>(); |
| private ArrayList<Cell> cellList = new ArrayList<Cell>(); |
| |
| protected CellGridImpl() { |
| setCellPadding(0); |
| setCellSpacing(0); |
| setBorderWidth(0); |
| sinkEvents(Event.ONCLICK | Event.ONMOUSEOVER | Event.ONMOUSEOUT); |
| } |
| |
| public Cell getCell(Element element) { |
| // This cast is always valid because both Element types are JSOs and have |
| // no new fields are added in the subclass. |
| return elementToCell.get((com.google.gwt.user.client.Element) element); |
| } |
| |
| public Cell getCell(Event e) { |
| // Find out which cell was actually clicked. |
| Element td = getEventTargetCell(e); |
| return td != null |
| ? elementToCell.get((com.google.gwt.user.client.Element) td) : null; |
| } |
| |
| public Cell getCell(int i) { |
| return cellList.get(i); |
| } |
| |
| public Iterator getCells() { |
| return cellList.iterator(); |
| } |
| |
| public Cell getHighlightedCell() { |
| return highlightedCell; |
| } |
| |
| public int getNumCells() { |
| return cellList.size(); |
| } |
| |
| public Cell getSelectedCell() { |
| return selectedCell; |
| } |
| |
| public V getSelectedValue() { |
| return getValue(selectedCell); |
| } |
| |
| public V getValue(Cell cell) { |
| return (cell == null ? null : cell.getValue()); |
| } |
| |
| @Override |
| public void onBrowserEvent(Event event) { |
| switch (DOM.eventGetType(event)) { |
| case Event.ONCLICK: { |
| Cell cell = getCell(event); |
| if (isActive(cell)) { |
| setSelected(cell); |
| } |
| break; |
| } |
| case Event.ONMOUSEOUT: { |
| Element e = DOM.eventGetFromElement(event); |
| if (e != null) { |
| Cell cell = elementToCell.get((com.google.gwt.user.client.Element) e); |
| if (cell == highlightedCell) { |
| setHighlighted(null); |
| } |
| } |
| break; |
| } |
| case Event.ONMOUSEOVER: { |
| Element e = DOM.eventGetToElement(event); |
| if (e != null) { |
| Cell cell = elementToCell.get((com.google.gwt.user.client.Element) e); |
| if (isActive(cell)) { |
| setHighlighted(cell); |
| } |
| } |
| break; |
| } |
| } |
| } |
| |
| @Override |
| public void onUnload() { |
| setHighlighted(null); |
| } |
| |
| public final void setHighlighted(Cell nextHighlighted) { |
| if (nextHighlighted == highlightedCell) { |
| return; |
| } |
| Cell oldHighlighted = highlightedCell; |
| highlightedCell = nextHighlighted; |
| if (oldHighlighted != null) { |
| oldHighlighted.onHighlighted(false); |
| } |
| if (highlightedCell != null) { |
| highlightedCell.onHighlighted(true); |
| } |
| } |
| |
| public final void setSelected(Cell cell) { |
| Cell last = getSelectedCell(); |
| selectedCell = cell; |
| |
| if (last != null) { |
| last.onSelected(false); |
| } |
| if (selectedCell != null) { |
| selectedCell.onSelected(true); |
| } |
| onSelected(last, selectedCell); |
| } |
| |
| protected void onKeyDown(Cell lastHighlighted, KeyDownEvent event) { |
| if (event.isAnyModifierKeyDown()) { |
| return; |
| } |
| int keyCode = event.getNativeKeyCode(); |
| if (lastHighlighted == null) { |
| if (keyCode == KeyCodes.KEY_DOWN && cellList.size() > 0) { |
| setHighlighted(cellList.get(0)); |
| } |
| } else { |
| lastHighlighted.verticalNavigation(keyCode); |
| } |
| } |
| |
| protected abstract void onSelected(Cell lastSelected, Cell cell); |
| |
| private boolean isActive(Cell cell) { |
| return cell != null && cell.isEnabled(); |
| } |
| } |