| /* |
| * Copyright 2010 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.cell.client; |
| |
| import com.google.gwt.dom.client.Element; |
| import com.google.gwt.dom.client.NativeEvent; |
| |
| import java.util.HashSet; |
| import java.util.Set; |
| |
| /** |
| * An {@link AbstractCell} used to render input elements that can receive focus. |
| * |
| * @param <C> the type that this Cell represents |
| * @param <V> the data type of the view data state |
| */ |
| public abstract class AbstractInputCell<C, V> extends |
| AbstractEditableCell<C, V> { |
| |
| /** |
| * Get the events consumed by the input cell. |
| * |
| * @param userEvents the events consumed by the subclass |
| * @return the events |
| */ |
| private static Set<String> getConsumedEventsImpl(Set<String> userEvents) { |
| Set<String> events = new HashSet<String>(); |
| events.add("focus"); |
| events.add("blur"); |
| events.add("keydown"); |
| if (userEvents != null && userEvents.size() > 0) { |
| events.addAll(userEvents); |
| } |
| return events; |
| } |
| |
| /** |
| * Get the events consumed by the input cell. |
| * |
| * @param userEvents the events consumed by the subclass |
| * @return the events |
| */ |
| private static Set<String> getConsumedEventsImpl(String... consumedEvents) { |
| Set<String> userEvents = new HashSet<String>(); |
| if (consumedEvents != null) { |
| for (String event : consumedEvents) { |
| userEvents.add(event); |
| } |
| } |
| return getConsumedEventsImpl(userEvents); |
| } |
| |
| /** |
| * The currently focused value key. Only one key can be focused at any time. |
| */ |
| private Object focusedKey; |
| |
| /** |
| * Construct a new {@link AbstractInputCell} with the specified consumed |
| * events. |
| * |
| * @param consumedEvents the events that this cell consumes |
| */ |
| public AbstractInputCell(String... consumedEvents) { |
| super(getConsumedEventsImpl(consumedEvents)); |
| } |
| |
| /** |
| * Construct a new {@link AbstractInputCell} with the specified consumed |
| * events. |
| * |
| * @param consumedEvents the events that this cell consumes |
| */ |
| public AbstractInputCell(Set<String> consumedEvents) { |
| super(getConsumedEventsImpl(consumedEvents)); |
| } |
| |
| @Override |
| public boolean isEditing(Element parent, C value, Object key) { |
| return focusedKey != null && focusedKey.equals(key); |
| } |
| |
| @Override |
| public void onBrowserEvent(Element parent, C value, Object key, |
| NativeEvent event, ValueUpdater<C> valueUpdater) { |
| super.onBrowserEvent(parent, value, key, event, valueUpdater); |
| |
| // Ignore events that don't target the input. |
| Element target = event.getEventTarget().cast(); |
| if (!getInputElement(parent).isOrHasChild(target)) { |
| return; |
| } |
| |
| String eventType = event.getType(); |
| if ("focus".equals(eventType)) { |
| focusedKey = key; |
| } else if ("blur".equals(eventType)) { |
| focusedKey = null; |
| } |
| } |
| |
| @Override |
| public boolean resetFocus(Element parent, C value, Object key) { |
| if (isEditing(parent, value, key)) { |
| getInputElement(parent).focus(); |
| return true; |
| } |
| return false; |
| } |
| |
| /** |
| * Call this method when editing is complete. |
| * |
| * @param parent the parent Element |
| * @param value the value associated with the cell |
| * @param key the unique key associated with the row object |
| * @param valueUpdater the value update to fire |
| */ |
| protected void finishEditing(Element parent, C value, Object key, |
| ValueUpdater<C> valueUpdater) { |
| focusedKey = null; |
| getInputElement(parent).blur(); |
| } |
| |
| /** |
| * Get the input element. |
| * |
| * @param parent the cell parent element |
| * @return the input element |
| */ |
| protected Element getInputElement(Element parent) { |
| return parent.getFirstChildElement(); |
| } |
| |
| @Override |
| protected void onEnterKeyDown(Element parent, C value, Object key, |
| NativeEvent event, ValueUpdater<C> valueUpdater) { |
| Element input = getInputElement(parent); |
| Element target = event.getEventTarget().cast(); |
| if (getInputElement(parent).isOrHasChild(target)) { |
| finishEditing(parent, value, key, valueUpdater); |
| } else { |
| focusedKey = key; |
| input.focus(); |
| } |
| } |
| } |