All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.google.gwt.cell.client.CompositeCell Maven / Gradle / Ivy

There is a newer version: 2.10.0
Show newest version
/*
 * 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.EventTarget;
import com.google.gwt.dom.client.NativeEvent;
import com.google.gwt.safehtml.shared.SafeHtmlBuilder;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * 

* A {@link Cell} that is composed of other {@link Cell}s. *

* *

* When this cell is rendered, it will render each component {@link Cell} inside * a span. If the component {@link Cell} uses block level elements (such as a * Div), the component cells will stack vertically. *

* * @param the type that this Cell represents */ public class CompositeCell extends AbstractCell { /** * The events consumed by this cell. */ private Set consumedEvents; /** * Indicates whether or not this cell depends on selection. */ private boolean dependsOnSelection; /** * Indicates whether or not this cell handles selection. */ private boolean handlesSelection; /** * The cells that compose this {@link Cell}. * *

* NOTE: Do not add add/insert/remove hasCells methods to the API. This cell * assumes that the index of the cellParent corresponds to the index in the * hasCells array. *

*/ private final List> hasCells; /** * Construct a new {@link CompositeCell}. * * @param hasCells the cells that makeup the composite */ public CompositeCell(List> hasCells) { // Create a new, readonly copy so cells cannot be added or removed. this.hasCells = Collections.unmodifiableList(new ArrayList>(hasCells)); // Get the consumed events and depends on selection. Set theConsumedEvents = null; for (HasCell hasCell : hasCells) { Cell cell = hasCell.getCell(); Set events = cell.getConsumedEvents(); if (events != null) { if (theConsumedEvents == null) { theConsumedEvents = new HashSet(); } theConsumedEvents.addAll(events); } if (cell.dependsOnSelection()) { dependsOnSelection = true; } if (cell.handlesSelection()) { handlesSelection = true; } } if (theConsumedEvents != null) { this.consumedEvents = Collections.unmodifiableSet(theConsumedEvents); } } @Override public boolean dependsOnSelection() { return dependsOnSelection; } @Override public Set getConsumedEvents() { return consumedEvents; } @Override public boolean handlesSelection() { return handlesSelection; } @Override public boolean isEditing(Context context, Element parent, C value) { Element curChild = getContainerElement(parent).getFirstChildElement(); for (HasCell hasCell : hasCells) { if (isEditingImpl(context, curChild, value, hasCell)) { return true; } curChild = curChild.getNextSiblingElement(); } return false; } @Override public void onBrowserEvent(Context context, Element parent, C value, NativeEvent event, ValueUpdater valueUpdater) { int index = 0; EventTarget eventTarget = event.getEventTarget(); if (Element.is(eventTarget)) { Element target = eventTarget.cast(); Element container = getContainerElement(parent); Element wrapper = container.getFirstChildElement(); while (wrapper != null) { if (wrapper.isOrHasChild(target)) { onBrowserEventImpl(context, wrapper, value, event, valueUpdater, hasCells.get(index)); } index++; wrapper = wrapper.getNextSiblingElement(); } } } @Override public void render(Context context, C value, SafeHtmlBuilder sb) { for (HasCell hasCell : hasCells) { render(context, value, sb, hasCell); } } @Override public boolean resetFocus(Context context, Element parent, C value) { Element curChild = getContainerElement(parent).getFirstChildElement(); for (HasCell hasCell : hasCells) { // The first child that takes focus wins. Only one child should ever be in // edit mode, so this is safe. if (resetFocusImpl(context, curChild, value, hasCell)) { return true; } curChild = curChild.getNextSiblingElement(); } return false; } @Override public void setValue(Context context, Element parent, C object) { Element curChild = getContainerElement(parent).getFirstChildElement(); for (HasCell hasCell : hasCells) { setValueImpl(context, curChild, object, hasCell); curChild = curChild.getNextSiblingElement(); } } /** * Returns the readonly list of {@link HasCell}'s that make up this composite. */ public List> getHasCells() { return hasCells; } /** * Get the element that acts as the container for all children. If children * are added directly to the parent, the parent is the container. If children * are added in a table row, the row is the parent. * * @param parent the parent element of the cell * @return the container element */ protected Element getContainerElement(Element parent) { return parent; } /** * Render the composite cell as HTML into a {@link SafeHtmlBuilder}, suitable * for passing to {@link Element#setInnerHTML} on a container element. * *

* Note: If your cell contains natively focusable elements, such as buttons or * input elements, be sure to set the tabIndex to -1 so that they do not steal * focus away from the containing widget. *

* * @param context the {@link com.google.gwt.cell.client.Cell.Context Context} of the cell * @param value the cell value to be rendered * @param sb the {@link SafeHtmlBuilder} to be written to * @param hasCell a {@link HasCell} instance containing the cells to be * rendered within this cell */ protected void render(Context context, C value, SafeHtmlBuilder sb, HasCell hasCell) { Cell cell = hasCell.getCell(); sb.appendHtmlConstant(""); cell.render(context, hasCell.getValue(value), sb); sb.appendHtmlConstant(""); } private boolean isEditingImpl(Context context, Element cellParent, C object, HasCell hasCell) { return hasCell.getCell().isEditing(context, cellParent, hasCell.getValue(object)); } private void onBrowserEventImpl(final Context context, Element parent, final C object, NativeEvent event, final ValueUpdater valueUpdater, final HasCell hasCell) { Cell cell = hasCell.getCell(); String eventType = event.getType(); Set cellConsumedEvents = cell.getConsumedEvents(); if (cellConsumedEvents == null || !cellConsumedEvents.contains(eventType)) { // If this sub-cell doesn't consume this event. return; } ValueUpdater tempUpdater = null; final FieldUpdater fieldUpdater = hasCell.getFieldUpdater(); if (fieldUpdater != null) { tempUpdater = new ValueUpdater() { @Override public void update(X value) { fieldUpdater.update(context.getIndex(), object, value); if (valueUpdater != null) { valueUpdater.update(object); } } }; } cell.onBrowserEvent(context, parent, hasCell.getValue(object), event, tempUpdater); } private boolean resetFocusImpl(Context context, Element cellParent, C value, HasCell hasCell) { X cellValue = hasCell.getValue(value); return hasCell.getCell().resetFocus(context, cellParent, cellValue); } private void setValueImpl(Context context, Element cellParent, C object, HasCell hasCell) { hasCell.getCell().setValue(context, cellParent, hasCell.getValue(object)); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy