From: Teemu Suo-Anttila Date: Tue, 9 Dec 2014 13:57:48 +0000 (+0200) Subject: Introduce GridClickEvents and handlers (#13334) X-Git-Tag: 7.4.0.beta1~9^2~52 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=a8fa4735466c4c4e52efd2baff3f77c106143eed;p=vaadin-framework.git Introduce GridClickEvents and handlers (#13334) This patch also adds body cell click selecting to single selection model to test this feature. Change-Id: I06819799c97457dc0e7bd38dd5855eb33ba91943 --- diff --git a/client/src/com/vaadin/client/ui/grid/Grid.java b/client/src/com/vaadin/client/ui/grid/Grid.java index 353c6ff97c..26f946447c 100644 --- a/client/src/com/vaadin/client/ui/grid/Grid.java +++ b/client/src/com/vaadin/client/ui/grid/Grid.java @@ -38,6 +38,7 @@ import com.google.gwt.dom.client.TableRowElement; import com.google.gwt.dom.client.Touch; import com.google.gwt.event.dom.client.KeyCodes; import com.google.gwt.event.dom.client.KeyEvent; +import com.google.gwt.event.dom.client.MouseEvent; import com.google.gwt.event.logical.shared.ValueChangeEvent; import com.google.gwt.event.logical.shared.ValueChangeHandler; import com.google.gwt.event.shared.HandlerRegistration; @@ -55,15 +56,20 @@ 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.events.AbstractGridKeyEventHandler; +import com.vaadin.client.ui.grid.events.AbstractGridMouseEventHandler; +import com.vaadin.client.ui.grid.events.BodyClickHandler; import com.vaadin.client.ui.grid.events.BodyKeyDownHandler; import com.vaadin.client.ui.grid.events.BodyKeyPressHandler; import com.vaadin.client.ui.grid.events.BodyKeyUpHandler; +import com.vaadin.client.ui.grid.events.FooterClickHandler; import com.vaadin.client.ui.grid.events.FooterKeyDownHandler; import com.vaadin.client.ui.grid.events.FooterKeyPressHandler; import com.vaadin.client.ui.grid.events.FooterKeyUpHandler; +import com.vaadin.client.ui.grid.events.GridClickEvent; import com.vaadin.client.ui.grid.events.GridKeyDownEvent; import com.vaadin.client.ui.grid.events.GridKeyPressEvent; import com.vaadin.client.ui.grid.events.GridKeyUpEvent; +import com.vaadin.client.ui.grid.events.HeaderClickHandler; import com.vaadin.client.ui.grid.events.HeaderKeyDownHandler; import com.vaadin.client.ui.grid.events.HeaderKeyPressHandler; import com.vaadin.client.ui.grid.events.HeaderKeyUpHandler; @@ -919,7 +925,7 @@ public class Grid extends ResizeComposite implements extends KeyEvent { /** - * Enum describing different section of Grid. + * Enum describing different sections of Grid. */ public enum GridSection { HEADER, BODY, FOOTER @@ -973,7 +979,91 @@ public class Grid extends ResizeComposite implements } } - protected abstract void doDispatch(HANDLER handler, GridSection seciton); + protected abstract void doDispatch(HANDLER handler, GridSection section); + + @Override + public Type getAssociatedType() { + return associatedType; + } + } + + public static abstract class AbstractGridMouseEvent + extends MouseEvent { + + /** + * Enum describing different sections of Grid. + */ + public enum GridSection { + HEADER, BODY, FOOTER + } + + private Grid grid; + protected Cell targetCell; + private final Type associatedType = new Type( + getBrowserEventType(), this); + + public AbstractGridMouseEvent(Grid grid) { + this.grid = grid; + } + + protected abstract String getBrowserEventType(); + + /** + * Gets the Grid instance for this event. + * + * @return grid + */ + public Grid getGrid() { + return grid; + } + + /** + * Gets the target cell for this event. + * + * @return target cell + */ + public Cell getTargetCell() { + return targetCell; + } + + @Override + protected void dispatch(HANDLER handler) { + EventTarget target = getNativeEvent().getEventTarget(); + if (!Element.is(target)) { + // Target is not an element + return; + } + + Element targetElement = Element.as(target); + if (grid.isElementInChildWidget(targetElement)) { + // Target is some widget inside of Grid + return; + } + + final RowContainer container = grid.escalator + .findRowContainer(targetElement); + if (container == null) { + // No container for given element + return; + } + + targetCell = container.getCell(targetElement); + if (targetCell == null) { + // Is not a cell in given container. + return; + } + + GridSection section = GridSection.FOOTER; + if (container == grid.escalator.getHeader()) { + section = GridSection.HEADER; + } else if (container == grid.escalator.getBody()) { + section = GridSection.BODY; + } + + doDispatch(handler, section); + } + + protected abstract void doDispatch(HANDLER handler, GridSection section); @Override public Type getAssociatedType() { @@ -986,6 +1076,7 @@ public class Grid extends ResizeComposite implements private GridKeyDownEvent keyDown = new GridKeyDownEvent(this); private GridKeyUpEvent keyUp = new GridKeyUpEvent(this); private GridKeyPressEvent keyPress = new GridKeyPressEvent(this); + private GridClickEvent clickEvent = new GridClickEvent(this); private class CellFocusHandler { @@ -3415,7 +3506,7 @@ public class Grid extends ResizeComposite implements return; } - // Fire GridKeyEvents and pass the event to escalator. + // Fire GridKeyEvents and GridClickEvents. Pass the event to escalator. super.onBrowserEvent(event); if (!isElementInChildWidget(e)) { @@ -4212,6 +4303,42 @@ public class Grid extends ResizeComposite implements return addHandler(handler, keyPress.getAssociatedType()); } + /** + * Register a BodyClickHandler to this Grid. The event for this handler is + * fired when a Click event occurs in the Body of this Grid. + * + * @param handler + * the click handler to register + * @return the registration for the event + */ + public HandlerRegistration addBodyClickHandler(BodyClickHandler handler) { + return addHandler(handler, clickEvent.getAssociatedType()); + } + + /** + * Register a HeaderClickHandler to this Grid. The event for this handler is + * fired when a Click event occurs in the Header of this Grid. + * + * @param handler + * the click handler to register + * @return the registration for the event + */ + public HandlerRegistration addHeaderClickHandler(HeaderClickHandler handler) { + return addHandler(handler, clickEvent.getAssociatedType()); + } + + /** + * Register a FooterClickHandler to this Grid. The event for this handler is + * fired when a Click event occurs in the Footer of this Grid. + * + * @param handler + * the click handler to register + * @return the registration for the event + */ + public HandlerRegistration addFooterClickHandler(FooterClickHandler handler) { + return addHandler(handler, clickEvent.getAssociatedType()); + } + /** * Apply sorting to data source. */ diff --git a/client/src/com/vaadin/client/ui/grid/events/AbstractGridMouseEventHandler.java b/client/src/com/vaadin/client/ui/grid/events/AbstractGridMouseEventHandler.java new file mode 100644 index 0000000000..24a8952f07 --- /dev/null +++ b/client/src/com/vaadin/client/ui/grid/events/AbstractGridMouseEventHandler.java @@ -0,0 +1,34 @@ +/* + * 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.events; + +import com.google.gwt.event.shared.EventHandler; +import com.vaadin.client.ui.grid.Grid.AbstractGridMouseEvent; + +/** + * Base interface of all handlers for {@link AbstractGridMouseEvent}s. + * + * @since + * @author Vaadin Ltd + */ +public abstract interface AbstractGridMouseEventHandler extends EventHandler { + + public abstract interface GridClickHandler extends + AbstractGridMouseEventHandler { + public void onClick(GridClickEvent event); + } + +} \ No newline at end of file diff --git a/client/src/com/vaadin/client/ui/grid/events/BodyClickHandler.java b/client/src/com/vaadin/client/ui/grid/events/BodyClickHandler.java new file mode 100644 index 0000000000..7110097b85 --- /dev/null +++ b/client/src/com/vaadin/client/ui/grid/events/BodyClickHandler.java @@ -0,0 +1,28 @@ +/* + * 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.events; + +import com.vaadin.client.ui.grid.events.AbstractGridMouseEventHandler.GridClickHandler; + +/** + * Handler for {@link GridClickEvent}s that happen in the body of the Grid. + * + * @since + * @author Vaadin Ltd + */ +public interface BodyClickHandler extends GridClickHandler { + +} diff --git a/client/src/com/vaadin/client/ui/grid/events/FooterClickHandler.java b/client/src/com/vaadin/client/ui/grid/events/FooterClickHandler.java new file mode 100644 index 0000000000..d9e91ded22 --- /dev/null +++ b/client/src/com/vaadin/client/ui/grid/events/FooterClickHandler.java @@ -0,0 +1,28 @@ +/* + * 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.events; + +import com.vaadin.client.ui.grid.events.AbstractGridMouseEventHandler.GridClickHandler; + +/** + * Handler for {@link GridClickEvent}s that happen in the footer of the Grid. + * + * @since + * @author Vaadin Ltd + */ +public interface FooterClickHandler extends GridClickHandler { + +} diff --git a/client/src/com/vaadin/client/ui/grid/events/GridClickEvent.java b/client/src/com/vaadin/client/ui/grid/events/GridClickEvent.java new file mode 100644 index 0000000000..1d85f0b41a --- /dev/null +++ b/client/src/com/vaadin/client/ui/grid/events/GridClickEvent.java @@ -0,0 +1,48 @@ +/* + * 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.events; + +import com.google.gwt.dom.client.BrowserEvents; +import com.vaadin.client.ui.grid.Grid; +import com.vaadin.client.ui.grid.Grid.AbstractGridMouseEvent; +import com.vaadin.client.ui.grid.events.AbstractGridMouseEventHandler.GridClickHandler; + +/** + * Represents native mouse click event in Grid. + * + * @since + * @author Vaadin Ltd + */ +public class GridClickEvent extends AbstractGridMouseEvent { + + public GridClickEvent(Grid grid) { + super(grid); + } + + @Override + protected String getBrowserEventType() { + return BrowserEvents.CLICK; + } + + @Override + protected void doDispatch(GridClickHandler handler, GridSection section) { + if ((section == GridSection.BODY && handler instanceof BodyClickHandler) + || (section == GridSection.HEADER && handler instanceof HeaderClickHandler) + || (section == GridSection.FOOTER && handler instanceof FooterClickHandler)) { + handler.onClick(this); + } + } +} diff --git a/client/src/com/vaadin/client/ui/grid/events/HeaderClickHandler.java b/client/src/com/vaadin/client/ui/grid/events/HeaderClickHandler.java new file mode 100644 index 0000000000..3c8896a8af --- /dev/null +++ b/client/src/com/vaadin/client/ui/grid/events/HeaderClickHandler.java @@ -0,0 +1,28 @@ +/* + * 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.events; + +import com.vaadin.client.ui.grid.events.AbstractGridMouseEventHandler.GridClickHandler; + +/** + * Handler for {@link GridClickEvent}s that happen in the header of the Grid. + * + * @since + * @author Vaadin Ltd + */ +public interface HeaderClickHandler extends GridClickHandler { + +} diff --git a/client/src/com/vaadin/client/ui/grid/selection/ClickSelectHandler.java b/client/src/com/vaadin/client/ui/grid/selection/ClickSelectHandler.java new file mode 100644 index 0000000000..48562329cc --- /dev/null +++ b/client/src/com/vaadin/client/ui/grid/selection/ClickSelectHandler.java @@ -0,0 +1,63 @@ +/* + * 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.selection; + +import com.google.gwt.event.shared.HandlerRegistration; +import com.vaadin.client.ui.grid.Grid; +import com.vaadin.client.ui.grid.events.BodyClickHandler; +import com.vaadin.client.ui.grid.events.GridClickEvent; + +/** + * Generic class to perform selections when clicking on cells in body of Grid. + * + * @since + * @author Vaadin Ltd + */ +public class ClickSelectHandler { + + private Grid grid; + private HandlerRegistration clickHandler; + + private class RowClickHandler implements BodyClickHandler { + + @Override + public void onClick(GridClickEvent event) { + T row = grid.getDataSource().getRow(event.getTargetCell().getRow()); + if (!grid.isSelected(row)) { + grid.select(row); + } + } + } + + /** + * Constructor for ClickSelectHandler. This constructor will add all + * necessary handlers for selecting rows by clicking cells. + * + * @param grid + * grid to attach to + */ + public ClickSelectHandler(Grid grid) { + this.grid = grid; + clickHandler = grid.addBodyClickHandler(new RowClickHandler()); + } + + /** + * Clean up function for removing all now obsolete handlers. + */ + public void removeHandler() { + clickHandler.removeHandler(); + } +} diff --git a/client/src/com/vaadin/client/ui/grid/selection/SelectionModelSingle.java b/client/src/com/vaadin/client/ui/grid/selection/SelectionModelSingle.java index 2c8b6cd391..8778b65179 100644 --- a/client/src/com/vaadin/client/ui/grid/selection/SelectionModelSingle.java +++ b/client/src/com/vaadin/client/ui/grid/selection/SelectionModelSingle.java @@ -33,9 +33,13 @@ public class SelectionModelSingle extends AbstractRowHandleSelectionModel private Grid grid; private RowHandle selectedRow; + /** Event handling for selection with space key */ private SpaceSelectHandler spaceSelectHandler; + /** Event handling for selection by clicking cells */ + private ClickSelectHandler clickSelectHandler; + @Override public boolean isSelected(T row) { return selectedRow != null @@ -61,9 +65,12 @@ public class SelectionModelSingle extends AbstractRowHandleSelectionModel this.grid = grid; if (this.grid != null) { spaceSelectHandler = new SpaceSelectHandler(grid); + clickSelectHandler = new ClickSelectHandler(grid); } else { spaceSelectHandler.removeHandler(); + clickSelectHandler.removeHandler(); spaceSelectHandler = null; + clickSelectHandler = null; } } diff --git a/uitest/src/com/vaadin/tests/components/grid/basicfeatures/server/GridSelectionTest.java b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/server/GridSelectionTest.java index a242ad1dd1..3933099835 100644 --- a/uitest/src/com/vaadin/tests/components/grid/basicfeatures/server/GridSelectionTest.java +++ b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/server/GridSelectionTest.java @@ -114,13 +114,13 @@ public class GridSelectionTest extends GridBasicFeaturesTest { grid.getCell(5, 0).click(); assertTrue("Fifth row was not selected.", getRow(5).isSelected()); assertFalse("First row was still selected.", getRow(0).isSelected()); - grid.getCell(0, 0).click(); + grid.getCell(0, 6).click(); toggleFirstRowSelection(); assertFalse("First row was still selected.", getRow(0).isSelected()); assertFalse("Fifth row was still selected.", getRow(5).isSelected()); grid.scrollToRow(600); - grid.getCell(595, 0).click(); + grid.getCell(595, 3).click(); assertTrue("Row 595 was not selected.", getRow(595).isSelected()); toggleFirstRowSelection(); assertFalse("Row 595 was still selected.", getRow(595).isSelected()); @@ -159,21 +159,25 @@ public class GridSelectionTest extends GridBasicFeaturesTest { GridElement grid = getGridElement(); grid.getCell(3, 1).click(); + + assertTrue("Grid row 3 was not selected with clicking.", grid.getRow(3) + .isSelected()); + new Actions(getDriver()).sendKeys(Keys.SPACE).perform(); - assertTrue("Grid row 3 was not selected with space key.", grid + assertTrue("Grid row 3 was not deselected with space key.", !grid .getRow(3).isSelected()); new Actions(getDriver()).sendKeys(Keys.SPACE).perform(); - assertTrue("Grid row 3 was not deselected with space key.", !grid + assertTrue("Grid row 3 was not selected with space key.", grid .getRow(3).isSelected()); grid.scrollToRow(500); new Actions(getDriver()).sendKeys(Keys.SPACE).perform(); - assertTrue("Grid row 3 was not selected with space key.", grid + assertTrue("Grid row 3 was not deselected with space key.", !grid .getRow(3).isSelected()); }