summaryrefslogtreecommitdiffstats
path: root/client/src
diff options
context:
space:
mode:
authorJohannes Dahlström <johannesd@vaadin.com>2014-12-11 13:55:33 +0200
committerVaadin Code Review <review@vaadin.com>2014-12-11 12:44:29 +0000
commitaa4b5bb44cb76147ec22229c27bb307f036216a8 (patch)
tree66b606fad73472352542b7b4a696d0a9f4ce5cf4 /client/src
parent66e07930b9749046e65434eb7d5dc8125a1f761c (diff)
downloadvaadin-framework-aa4b5bb44cb76147ec22229c27bb307f036216a8.tar.gz
vaadin-framework-aa4b5bb44cb76147ec22229c27bb307f036216a8.zip
Move client-side EditorRow inside Grid (#13334)
This is the first step in the planned API flattening. Change-Id: I0127108b70131f328895dd8d7376c30b9a613464
Diffstat (limited to 'client/src')
-rw-r--r--client/src/com/vaadin/client/ui/grid/EditorRow.java421
-rw-r--r--client/src/com/vaadin/client/ui/grid/Grid.java394
2 files changed, 392 insertions, 423 deletions
diff --git a/client/src/com/vaadin/client/ui/grid/EditorRow.java b/client/src/com/vaadin/client/ui/grid/EditorRow.java
deleted file mode 100644
index cc56a4c4a9..0000000000
--- a/client/src/com/vaadin/client/ui/grid/EditorRow.java
+++ /dev/null
@@ -1,421 +0,0 @@
-/*
- * Copyright 2000-2014 Vaadin Ltd.
- *
- * 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.vaadin.client.ui.grid;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import com.google.gwt.dom.client.DivElement;
-import com.google.gwt.dom.client.Element;
-import com.google.gwt.dom.client.Style;
-import com.google.gwt.dom.client.Style.Unit;
-import com.google.gwt.dom.client.TableCellElement;
-import com.google.gwt.dom.client.TableRowElement;
-import com.google.gwt.event.dom.client.ClickEvent;
-import com.google.gwt.event.dom.client.ClickHandler;
-import com.google.gwt.event.dom.client.KeyCodes;
-import com.google.gwt.event.shared.HandlerRegistration;
-import com.google.gwt.user.client.DOM;
-import com.google.gwt.user.client.ui.Button;
-import com.google.gwt.user.client.ui.Widget;
-import com.vaadin.client.ui.grid.EditorRowHandler.EditorRowRequest;
-import com.vaadin.client.ui.grid.EditorRowHandler.EditorRowRequest.RequestCallback;
-import com.vaadin.client.ui.grid.Escalator.AbstractRowContainer;
-import com.vaadin.client.ui.grid.Grid.SelectionColumn;
-import com.vaadin.client.ui.grid.ScrollbarBundle.Direction;
-import com.vaadin.client.ui.grid.events.ScrollEvent;
-import com.vaadin.client.ui.grid.events.ScrollHandler;
-import com.vaadin.shared.ui.grid.ScrollDestination;
-
-/**
- * An editor UI for Grid rows. A single Grid row at a time can be opened for
- * editing.
- *
- * @since
- * @author Vaadin Ltd
- */
-public class EditorRow<T> {
-
- public static final int KEYCODE_SHOW = KeyCodes.KEY_ENTER;
- public static final int KEYCODE_HIDE = KeyCodes.KEY_ESCAPE;
-
- public enum State {
- INACTIVE, ACTIVATING, ACTIVE, COMMITTING
- }
-
- private Grid<T> grid;
-
- private EditorRowHandler<T> handler;
-
- private DivElement editorOverlay = DivElement.as(DOM.createDiv());
-
- private Map<GridColumn<?, T>, Widget> columnToWidget = new HashMap<GridColumn<?, T>, Widget>();
-
- private boolean enabled = false;
- private State state = State.INACTIVE;
- private int rowIndex = -1;
- private String styleName = null;
-
- private HandlerRegistration scrollHandler;
-
- public int getRow() {
- return rowIndex;
- }
-
- /**
- * Opens the editor over the row with the given index.
- *
- * @param rowIndex
- * the index of the row to be edited
- *
- * @throws IllegalStateException
- * if this editor row is not enabled
- * @throws IllegalStateException
- * if this editor row is already in edit mode
- */
- public void editRow(int rowIndex) {
- if (!enabled) {
- throw new IllegalStateException(
- "Cannot edit row: EditorRow is not enabled");
- }
- if (state != State.INACTIVE) {
- throw new IllegalStateException(
- "Cannot edit row: EditorRow already in edit mode");
- }
-
- this.rowIndex = rowIndex;
-
- state = State.ACTIVATING;
-
- if (grid.getEscalator().getVisibleRowRange().contains(rowIndex)) {
- show();
- } else {
- grid.scrollToRow(rowIndex, ScrollDestination.MIDDLE);
- }
- }
-
- /**
- * Cancels the currently active edit and hides the editor. Any changes that
- * are not {@link #commit() committed} are lost.
- *
- * @throws IllegalStateException
- * if this editor row is not enabled
- * @throws IllegalStateException
- * if this editor row is not in edit mode
- */
- public void cancel() {
- if (!enabled) {
- throw new IllegalStateException(
- "Cannot cancel edit: EditorRow is not enabled");
- }
- if (state == State.INACTIVE) {
- throw new IllegalStateException(
- "Cannot cancel edit: EditorRow is not in edit mode");
- }
- hideOverlay();
- grid.getEscalator().setScrollLocked(Direction.VERTICAL, false);
- handler.cancel(new EditorRowRequest<T>(grid, rowIndex, null));
- state = State.INACTIVE;
- }
-
- /**
- * Commits any unsaved changes to the data source.
- *
- * @throws IllegalStateException
- * if this editor row is not enabled
- * @throws IllegalStateException
- * if this editor row is not in edit mode
- */
- public void commit() {
- if (!enabled) {
- throw new IllegalStateException(
- "Cannot commit: EditorRow is not enabled");
- }
- if (state != State.ACTIVE) {
- throw new IllegalStateException(
- "Cannot commit: EditorRow is not in edit mode");
- }
-
- state = State.COMMITTING;
-
- handler.commit(new EditorRowRequest<T>(grid, rowIndex,
- new RequestCallback<T>() {
- @Override
- public void onResponse(EditorRowRequest<T> request) {
- if (state == State.COMMITTING) {
- state = State.ACTIVE;
- }
- }
- }));
- }
-
- /**
- * Reloads row values from the data source, discarding any unsaved changes.
- *
- * @throws IllegalStateException
- * if this editor row is not enabled
- * @throws IllegalStateException
- * if this editor row is not in edit mode
- */
- public void discard() {
- if (!enabled) {
- throw new IllegalStateException(
- "Cannot discard: EditorRow is not enabled");
- }
- if (state != State.ACTIVE) {
- throw new IllegalStateException(
- "Cannot discard: EditorRow is not in edit mode");
- }
- handler.discard(new EditorRowRequest<T>(grid, rowIndex, null));
- }
-
- /**
- * Returns the handler responsible for binding data and editor widgets to
- * this editor row.
- *
- * @return the editor row handler or null if not set
- */
- public EditorRowHandler<T> getHandler() {
- return handler;
- }
-
- /**
- * Sets the handler responsible for binding data and editor widgets to this
- * editor row.
- *
- * @param rowHandler
- * the new editor row handler
- *
- * @throws IllegalStateException
- * if this editor row is currently in edit mode
- */
- public void setHandler(EditorRowHandler<T> rowHandler) {
- if (state != State.INACTIVE) {
- throw new IllegalStateException(
- "Cannot set EditorRowHandler: EditorRow is currently in edit mode");
- }
- this.handler = rowHandler;
- }
-
- public boolean isEnabled() {
- return enabled;
- }
-
- /**
- * Sets the enabled state of this editor row.
- *
- * @param enabled
- * true if enabled, false otherwise
- *
- * @throws IllegalStateException
- * if in edit mode and trying to disable
- * @throws IllegalStateException
- * if the editor row handler is not set
- */
- public void setEnabled(boolean enabled) {
- if (enabled == false && state != State.INACTIVE) {
- throw new IllegalStateException(
- "Cannot disable: EditorRow is in edit mode");
- } else if (enabled == true && getHandler() == null) {
- throw new IllegalStateException(
- "Cannot enable: EditorRowHandler not set");
- }
- this.enabled = enabled;
- }
-
- protected void show() {
- if (state == State.ACTIVATING) {
- handler.bind(new EditorRowRequest<T>(grid, rowIndex,
- new RequestCallback<T>() {
- @Override
- public void onResponse(EditorRowRequest<T> request) {
- if (state == State.ACTIVATING) {
- state = State.ACTIVE;
- showOverlay(grid.getEscalator().getBody()
- .getRowElement(request.getRowIndex()));
- }
- }
- }));
- grid.getEscalator().setScrollLocked(Direction.VERTICAL, true);
- }
- }
-
- protected void setGrid(final Grid<T> grid) {
- assert grid != null : "Grid cannot be null";
- assert this.grid == null : "Can only attach EditorRow to Grid once";
-
- this.grid = grid;
-
- grid.addDataAvailableHandler(new DataAvailableHandler() {
- @Override
- public void onDataAvailable(DataAvailableEvent event) {
- if (event.getAvailableRows().contains(rowIndex)) {
- show();
- }
- }
- });
- }
-
- protected State getState() {
- return state;
- }
-
- protected void setState(State state) {
- this.state = state;
- }
-
- /**
- * Returns the editor widget associated with the given column. If the editor
- * row is not active, returns null.
- *
- * @param column
- * the column
- * @return the widget if the editor row is open, null otherwise
- */
- protected Widget getWidget(GridColumn<?, T> column) {
- return columnToWidget.get(column);
- }
-
- /**
- * Opens the editor overlay over the given table row.
- *
- * @param tr
- * the row to be edited
- */
- protected void showOverlay(TableRowElement tr) {
-
- DivElement tableWrapper = DivElement.as(tr.getParentElement()
- .getParentElement().getParentElement());
-
- AbstractRowContainer body = (AbstractRowContainer) grid.getEscalator()
- .getBody();
-
- int rowTop = body.getRowTop(tr);
- int bodyTop = body.getElement().getAbsoluteTop();
- int wrapperTop = tableWrapper.getAbsoluteTop();
-
- setBounds(editorOverlay, tr.getOffsetLeft(), rowTop + bodyTop
- - wrapperTop, tr.getOffsetWidth(), tr.getOffsetHeight());
-
- updateHorizontalScrollPosition();
-
- scrollHandler = grid.addScrollHandler(new ScrollHandler() {
- @Override
- public void onScroll(ScrollEvent event) {
- updateHorizontalScrollPosition();
- }
- });
-
- tableWrapper.appendChild(editorOverlay);
-
- for (int i = 0; i < tr.getCells().getLength(); i++) {
- Element cell = createCell(tr.getCells().getItem(i));
-
- editorOverlay.appendChild(cell);
-
- GridColumn<?, T> column = grid.getColumn(i);
- if (column instanceof SelectionColumn) {
- continue;
- }
-
- Widget editor = getHandler().getWidget(column);
- if (editor != null) {
- columnToWidget.put(column, editor);
- attachWidget(editor, cell);
- }
- }
-
- Button save = new Button();
- save.setText("Save");
- save.setStyleName("v-editor-row-save");
- save.addClickHandler(new ClickHandler() {
- @Override
- public void onClick(ClickEvent event) {
- // TODO should have a mechanism for handling failed commits
- commit();
- cancel();
- }
- });
- setBounds(save.getElement(), 0, tr.getOffsetHeight() + 5, 50, 25);
- attachWidget(save, editorOverlay);
-
- Button cancel = new Button();
- cancel.setText("Cancel");
- cancel.setStyleName("v-editor-row-cancel");
- cancel.addClickHandler(new ClickHandler() {
- @Override
- public void onClick(ClickEvent event) {
- cancel();
- }
- });
- setBounds(cancel.getElement(), 55, tr.getOffsetHeight() + 5, 50, 25);
- attachWidget(cancel, editorOverlay);
- }
-
- protected void hideOverlay() {
- for (Widget w : columnToWidget.values()) {
- GridUtil.setParent(w, null);
- }
- columnToWidget.clear();
-
- editorOverlay.removeAllChildren();
- editorOverlay.removeFromParent();
-
- scrollHandler.removeHandler();
- }
-
- protected void setStylePrimaryName(String primaryName) {
- if (styleName != null) {
- editorOverlay.removeClassName(styleName);
- }
- styleName = primaryName + "-editor-row";
- editorOverlay.addClassName(styleName);
- }
-
- /**
- * Creates an editor row cell corresponding to the given table cell. The
- * returned element is empty and has the same dimensions and position as the
- * table cell.
- *
- * @param td
- * the table cell used as a reference
- * @return an editor row cell corresponding to the given cell
- */
- protected Element createCell(TableCellElement td) {
- DivElement cell = DivElement.as(DOM.createDiv());
- setBounds(cell, td.getOffsetLeft(), td.getOffsetTop(),
- td.getOffsetWidth(), td.getOffsetHeight());
- return cell;
- }
-
- private void attachWidget(Widget w, Element parent) {
- parent.appendChild(w.getElement());
- GridUtil.setParent(w, grid);
- }
-
- private static void setBounds(Element e, int left, int top, int width,
- int height) {
- Style style = e.getStyle();
- style.setLeft(left, Unit.PX);
- style.setTop(top, Unit.PX);
- style.setWidth(width, Unit.PX);
- style.setHeight(height, Unit.PX);
- }
-
- private void updateHorizontalScrollPosition() {
- editorOverlay.getStyle().setLeft(-grid.getScrollLeft(), Unit.PX);
- }
-}
diff --git a/client/src/com/vaadin/client/ui/grid/Grid.java b/client/src/com/vaadin/client/ui/grid/Grid.java
index 92e412b211..bf68c7ace7 100644
--- a/client/src/com/vaadin/client/ui/grid/Grid.java
+++ b/client/src/com/vaadin/client/ui/grid/Grid.java
@@ -31,11 +31,16 @@ import com.google.gwt.core.client.Scheduler;
import com.google.gwt.core.client.Scheduler.ScheduledCommand;
import com.google.gwt.core.shared.GWT;
import com.google.gwt.dom.client.BrowserEvents;
+import com.google.gwt.dom.client.DivElement;
import com.google.gwt.dom.client.Element;
import com.google.gwt.dom.client.EventTarget;
+import com.google.gwt.dom.client.Style;
+import com.google.gwt.dom.client.Style.Unit;
import com.google.gwt.dom.client.TableCellElement;
import com.google.gwt.dom.client.TableRowElement;
import com.google.gwt.dom.client.Touch;
+import com.google.gwt.event.dom.client.ClickEvent;
+import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.KeyCodes;
import com.google.gwt.event.dom.client.KeyEvent;
import com.google.gwt.event.dom.client.MouseEvent;
@@ -46,6 +51,7 @@ import com.google.gwt.touch.client.Point;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Event;
import com.google.gwt.user.client.Timer;
+import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.CheckBox;
import com.google.gwt.user.client.ui.ResizeComposite;
import com.google.gwt.user.client.ui.Widget;
@@ -54,7 +60,10 @@ import com.vaadin.client.Util;
import com.vaadin.client.data.DataChangeHandler;
import com.vaadin.client.data.DataSource;
import com.vaadin.client.ui.SubPartAware;
-import com.vaadin.client.ui.grid.EditorRow.State;
+import com.vaadin.client.ui.grid.EditorRowHandler.EditorRowRequest;
+import com.vaadin.client.ui.grid.EditorRowHandler.EditorRowRequest.RequestCallback;
+import com.vaadin.client.ui.grid.Escalator.AbstractRowContainer;
+import com.vaadin.client.ui.grid.ScrollbarBundle.Direction;
import com.vaadin.client.ui.grid.events.AbstractGridKeyEventHandler;
import com.vaadin.client.ui.grid.events.AbstractGridMouseEventHandler;
import com.vaadin.client.ui.grid.events.BodyClickHandler;
@@ -931,6 +940,387 @@ public class Grid<T> extends ResizeComposite implements
}
}
+ /**
+ * An editor UI for Grid rows. A single Grid row at a time can be opened for
+ * editing.
+ */
+ public static class EditorRow<T> {
+
+ public static final int KEYCODE_SHOW = KeyCodes.KEY_ENTER;
+ public static final int KEYCODE_HIDE = KeyCodes.KEY_ESCAPE;
+
+ public enum State {
+ INACTIVE, ACTIVATING, ACTIVE, COMMITTING
+ }
+
+ private Grid<T> grid;
+
+ private EditorRowHandler<T> handler;
+
+ private DivElement editorOverlay = DivElement.as(DOM.createDiv());
+
+ private Map<GridColumn<?, T>, Widget> columnToWidget = new HashMap<GridColumn<?, T>, Widget>();
+
+ private boolean enabled = false;
+ private State state = State.INACTIVE;
+ private int rowIndex = -1;
+ private String styleName = null;
+
+ private HandlerRegistration scrollHandler;
+
+ public int getRow() {
+ return rowIndex;
+ }
+
+ /**
+ * Opens the editor over the row with the given index.
+ *
+ * @param rowIndex
+ * the index of the row to be edited
+ *
+ * @throws IllegalStateException
+ * if this editor row is not enabled
+ * @throws IllegalStateException
+ * if this editor row is already in edit mode
+ */
+ public void editRow(int rowIndex) {
+ if (!enabled) {
+ throw new IllegalStateException(
+ "Cannot edit row: EditorRow is not enabled");
+ }
+ if (state != State.INACTIVE) {
+ throw new IllegalStateException(
+ "Cannot edit row: EditorRow already in edit mode");
+ }
+
+ this.rowIndex = rowIndex;
+
+ state = State.ACTIVATING;
+
+ if (grid.getEscalator().getVisibleRowRange().contains(rowIndex)) {
+ show();
+ } else {
+ grid.scrollToRow(rowIndex, ScrollDestination.MIDDLE);
+ }
+ }
+
+ /**
+ * Cancels the currently active edit and hides the editor. Any changes
+ * that are not {@link #commit() committed} are lost.
+ *
+ * @throws IllegalStateException
+ * if this editor row is not enabled
+ * @throws IllegalStateException
+ * if this editor row is not in edit mode
+ */
+ public void cancel() {
+ if (!enabled) {
+ throw new IllegalStateException(
+ "Cannot cancel edit: EditorRow is not enabled");
+ }
+ if (state == State.INACTIVE) {
+ throw new IllegalStateException(
+ "Cannot cancel edit: EditorRow is not in edit mode");
+ }
+ hideOverlay();
+ grid.getEscalator().setScrollLocked(Direction.VERTICAL, false);
+ handler.cancel(new EditorRowRequest<T>(grid, rowIndex, null));
+ state = State.INACTIVE;
+ }
+
+ /**
+ * Commits any unsaved changes to the data source.
+ *
+ * @throws IllegalStateException
+ * if this editor row is not enabled
+ * @throws IllegalStateException
+ * if this editor row is not in edit mode
+ */
+ public void commit() {
+ if (!enabled) {
+ throw new IllegalStateException(
+ "Cannot commit: EditorRow is not enabled");
+ }
+ if (state != State.ACTIVE) {
+ throw new IllegalStateException(
+ "Cannot commit: EditorRow is not in edit mode");
+ }
+
+ state = State.COMMITTING;
+
+ handler.commit(new EditorRowRequest<T>(grid, rowIndex,
+ new RequestCallback<T>() {
+ @Override
+ public void onResponse(EditorRowRequest<T> request) {
+ if (state == State.COMMITTING) {
+ state = State.ACTIVE;
+ }
+ }
+ }));
+ }
+
+ /**
+ * Reloads row values from the data source, discarding any unsaved
+ * changes.
+ *
+ * @throws IllegalStateException
+ * if this editor row is not enabled
+ * @throws IllegalStateException
+ * if this editor row is not in edit mode
+ */
+ public void discard() {
+ if (!enabled) {
+ throw new IllegalStateException(
+ "Cannot discard: EditorRow is not enabled");
+ }
+ if (state != State.ACTIVE) {
+ throw new IllegalStateException(
+ "Cannot discard: EditorRow is not in edit mode");
+ }
+ handler.discard(new EditorRowRequest<T>(grid, rowIndex, null));
+ }
+
+ /**
+ * Returns the handler responsible for binding data and editor widgets
+ * to this editor row.
+ *
+ * @return the editor row handler or null if not set
+ */
+ public EditorRowHandler<T> getHandler() {
+ return handler;
+ }
+
+ /**
+ * Sets the handler responsible for binding data and editor widgets to
+ * this editor row.
+ *
+ * @param rowHandler
+ * the new editor row handler
+ *
+ * @throws IllegalStateException
+ * if this editor row is currently in edit mode
+ */
+ public void setHandler(EditorRowHandler<T> rowHandler) {
+ if (state != State.INACTIVE) {
+ throw new IllegalStateException(
+ "Cannot set EditorRowHandler: EditorRow is currently in edit mode");
+ }
+ this.handler = rowHandler;
+ }
+
+ public boolean isEnabled() {
+ return enabled;
+ }
+
+ /**
+ * Sets the enabled state of this editor row.
+ *
+ * @param enabled
+ * true if enabled, false otherwise
+ *
+ * @throws IllegalStateException
+ * if in edit mode and trying to disable
+ * @throws IllegalStateException
+ * if the editor row handler is not set
+ */
+ public void setEnabled(boolean enabled) {
+ if (enabled == false && state != State.INACTIVE) {
+ throw new IllegalStateException(
+ "Cannot disable: EditorRow is in edit mode");
+ } else if (enabled == true && getHandler() == null) {
+ throw new IllegalStateException(
+ "Cannot enable: EditorRowHandler not set");
+ }
+ this.enabled = enabled;
+ }
+
+ protected void show() {
+ if (state == State.ACTIVATING) {
+ handler.bind(new EditorRowRequest<T>(grid, rowIndex,
+ new RequestCallback<T>() {
+ @Override
+ public void onResponse(EditorRowRequest<T> request) {
+ if (state == State.ACTIVATING) {
+ state = State.ACTIVE;
+ showOverlay(grid
+ .getEscalator()
+ .getBody()
+ .getRowElement(
+ request.getRowIndex()));
+ }
+ }
+ }));
+ grid.getEscalator().setScrollLocked(Direction.VERTICAL, true);
+ }
+ }
+
+ protected void setGrid(final Grid<T> grid) {
+ assert grid != null : "Grid cannot be null";
+ assert this.grid == null : "Can only attach EditorRow to Grid once";
+
+ this.grid = grid;
+
+ grid.addDataAvailableHandler(new DataAvailableHandler() {
+ @Override
+ public void onDataAvailable(DataAvailableEvent event) {
+ if (event.getAvailableRows().contains(rowIndex)) {
+ show();
+ }
+ }
+ });
+ }
+
+ protected State getState() {
+ return state;
+ }
+
+ protected void setState(State state) {
+ this.state = state;
+ }
+
+ /**
+ * Returns the editor widget associated with the given column. If the
+ * editor row is not active, returns null.
+ *
+ * @param column
+ * the column
+ * @return the widget if the editor row is open, null otherwise
+ */
+ protected Widget getWidget(GridColumn<?, T> column) {
+ return columnToWidget.get(column);
+ }
+
+ /**
+ * Opens the editor overlay over the given table row.
+ *
+ * @param tr
+ * the row to be edited
+ */
+ protected void showOverlay(TableRowElement tr) {
+
+ DivElement tableWrapper = DivElement.as(tr.getParentElement()
+ .getParentElement().getParentElement());
+
+ AbstractRowContainer body = (AbstractRowContainer) grid
+ .getEscalator().getBody();
+
+ int rowTop = body.getRowTop(tr);
+ int bodyTop = body.getElement().getAbsoluteTop();
+ int wrapperTop = tableWrapper.getAbsoluteTop();
+
+ setBounds(editorOverlay, tr.getOffsetLeft(), rowTop + bodyTop
+ - wrapperTop, tr.getOffsetWidth(), tr.getOffsetHeight());
+
+ updateHorizontalScrollPosition();
+
+ scrollHandler = grid.addScrollHandler(new ScrollHandler() {
+ @Override
+ public void onScroll(ScrollEvent event) {
+ updateHorizontalScrollPosition();
+ }
+ });
+
+ tableWrapper.appendChild(editorOverlay);
+
+ for (int i = 0; i < tr.getCells().getLength(); i++) {
+ Element cell = createCell(tr.getCells().getItem(i));
+
+ editorOverlay.appendChild(cell);
+
+ GridColumn<?, T> column = grid.getColumn(i);
+ if (column == grid.selectionColumn) {
+ continue;
+ }
+
+ Widget editor = getHandler().getWidget(column);
+ if (editor != null) {
+ columnToWidget.put(column, editor);
+ attachWidget(editor, cell);
+ }
+ }
+
+ Button save = new Button();
+ save.setText("Save");
+ save.setStyleName("v-editor-row-save");
+ save.addClickHandler(new ClickHandler() {
+ @Override
+ public void onClick(ClickEvent event) {
+ // TODO should have a mechanism for handling failed commits
+ commit();
+ cancel();
+ }
+ });
+ setBounds(save.getElement(), 0, tr.getOffsetHeight() + 5, 50, 25);
+ attachWidget(save, editorOverlay);
+
+ Button cancel = new Button();
+ cancel.setText("Cancel");
+ cancel.setStyleName("v-editor-row-cancel");
+ cancel.addClickHandler(new ClickHandler() {
+ @Override
+ public void onClick(ClickEvent event) {
+ cancel();
+ }
+ });
+ setBounds(cancel.getElement(), 55, tr.getOffsetHeight() + 5, 50, 25);
+ attachWidget(cancel, editorOverlay);
+ }
+
+ protected void hideOverlay() {
+ for (Widget w : columnToWidget.values()) {
+ GridUtil.setParent(w, null);
+ }
+ columnToWidget.clear();
+
+ editorOverlay.removeAllChildren();
+ editorOverlay.removeFromParent();
+
+ scrollHandler.removeHandler();
+ }
+
+ protected void setStylePrimaryName(String primaryName) {
+ if (styleName != null) {
+ editorOverlay.removeClassName(styleName);
+ }
+ styleName = primaryName + "-editor-row";
+ editorOverlay.addClassName(styleName);
+ }
+
+ /**
+ * Creates an editor row cell corresponding to the given table cell. The
+ * returned element is empty and has the same dimensions and position as
+ * the table cell.
+ *
+ * @param td
+ * the table cell used as a reference
+ * @return an editor row cell corresponding to the given cell
+ */
+ protected Element createCell(TableCellElement td) {
+ DivElement cell = DivElement.as(DOM.createDiv());
+ setBounds(cell, td.getOffsetLeft(), td.getOffsetTop(),
+ td.getOffsetWidth(), td.getOffsetHeight());
+ return cell;
+ }
+
+ private void attachWidget(Widget w, Element parent) {
+ parent.appendChild(w.getElement());
+ GridUtil.setParent(w, grid);
+ }
+
+ private static void setBounds(Element e, int left, int top, int width,
+ int height) {
+ Style style = e.getStyle();
+ style.setLeft(left, Unit.PX);
+ style.setTop(top, Unit.PX);
+ style.setWidth(width, Unit.PX);
+ style.setHeight(height, Unit.PX);
+ }
+
+ private void updateHorizontalScrollPosition() {
+ editorOverlay.getStyle().setLeft(-grid.getScrollLeft(), Unit.PX);
+ }
+ }
+
public static abstract class AbstractGridKeyEvent<HANDLER extends AbstractGridKeyEventHandler>
extends KeyEvent<HANDLER> {
@@ -3667,7 +4057,7 @@ public class Grid<T> extends ResizeComposite implements
private boolean handleEditorRowEvent(Event event, RowContainer container,
Cell cell) {
- if (editorRow.getState() != State.INACTIVE) {
+ if (editorRow.getState() != EditorRow.State.INACTIVE) {
if (event.getTypeInt() == Event.ONKEYDOWN
&& event.getKeyCode() == EditorRow.KEYCODE_HIDE) {
editorRow.cancel();