]> source.dussan.org Git - vaadin-framework.git/commitdiff
Introduce GridClickEvents and handlers (#13334)
authorTeemu Suo-Anttila <teemusa@vaadin.com>
Tue, 9 Dec 2014 13:57:48 +0000 (15:57 +0200)
committerTeemu Suo-Anttila <teemusa@vaadin.com>
Wed, 10 Dec 2014 09:23:54 +0000 (11:23 +0200)
This patch also adds body cell click selecting to single selection model
to test this feature.

Change-Id: I06819799c97457dc0e7bd38dd5855eb33ba91943

client/src/com/vaadin/client/ui/grid/Grid.java
client/src/com/vaadin/client/ui/grid/events/AbstractGridMouseEventHandler.java [new file with mode: 0644]
client/src/com/vaadin/client/ui/grid/events/BodyClickHandler.java [new file with mode: 0644]
client/src/com/vaadin/client/ui/grid/events/FooterClickHandler.java [new file with mode: 0644]
client/src/com/vaadin/client/ui/grid/events/GridClickEvent.java [new file with mode: 0644]
client/src/com/vaadin/client/ui/grid/events/HeaderClickHandler.java [new file with mode: 0644]
client/src/com/vaadin/client/ui/grid/selection/ClickSelectHandler.java [new file with mode: 0644]
client/src/com/vaadin/client/ui/grid/selection/SelectionModelSingle.java
uitest/src/com/vaadin/tests/components/grid/basicfeatures/server/GridSelectionTest.java

index 353c6ff97ce88f23e07810c6a2d28378b4215e54..26f946447c883a148cbdd1bf47b4c2f09ca3afbb 100644 (file)
@@ -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<T> extends ResizeComposite implements
             extends KeyEvent<HANDLER> {
 
         /**
-         * 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<T> extends ResizeComposite implements
             }
         }
 
-        protected abstract void doDispatch(HANDLER handler, GridSection seciton);
+        protected abstract void doDispatch(HANDLER handler, GridSection section);
+
+        @Override
+        public Type<HANDLER> getAssociatedType() {
+            return associatedType;
+        }
+    }
+
+    public static abstract class AbstractGridMouseEvent<HANDLER extends AbstractGridMouseEventHandler>
+            extends MouseEvent<HANDLER> {
+
+        /**
+         * Enum describing different sections of Grid.
+         */
+        public enum GridSection {
+            HEADER, BODY, FOOTER
+        }
+
+        private Grid<?> grid;
+        protected Cell targetCell;
+        private final Type<HANDLER> associatedType = new Type<HANDLER>(
+                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<HANDLER> getAssociatedType() {
@@ -986,6 +1076,7 @@ public class Grid<T> 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<T> 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<T> 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 (file)
index 0000000..24a8952
--- /dev/null
@@ -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 (file)
index 0000000..7110097
--- /dev/null
@@ -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 (file)
index 0000000..d9e91de
--- /dev/null
@@ -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 (file)
index 0000000..1d85f0b
--- /dev/null
@@ -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<GridClickHandler> {
+
+    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 (file)
index 0000000..3c8896a
--- /dev/null
@@ -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 (file)
index 0000000..4856232
--- /dev/null
@@ -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<T> {
+
+    private Grid<T> 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<T> grid) {
+        this.grid = grid;
+        clickHandler = grid.addBodyClickHandler(new RowClickHandler());
+    }
+
+    /**
+     * Clean up function for removing all now obsolete handlers.
+     */
+    public void removeHandler() {
+        clickHandler.removeHandler();
+    }
+}
index 2c8b6cd391fa17ae3a59f0129310868e98b527e6..8778b65179f88948db20e5da60406957a9e7cd16 100644 (file)
@@ -33,9 +33,13 @@ public class SelectionModelSingle<T> extends AbstractRowHandleSelectionModel<T>
 
     private Grid<T> grid;
     private RowHandle<T> selectedRow;
+
     /** Event handling for selection with space key */
     private SpaceSelectHandler<T> spaceSelectHandler;
 
+    /** Event handling for selection by clicking cells */
+    private ClickSelectHandler<T> clickSelectHandler;
+
     @Override
     public boolean isSelected(T row) {
         return selectedRow != null
@@ -61,9 +65,12 @@ public class SelectionModelSingle<T> extends AbstractRowHandleSelectionModel<T>
         this.grid = grid;
         if (this.grid != null) {
             spaceSelectHandler = new SpaceSelectHandler<T>(grid);
+            clickSelectHandler = new ClickSelectHandler<T>(grid);
         } else {
             spaceSelectHandler.removeHandler();
+            clickSelectHandler.removeHandler();
             spaceSelectHandler = null;
+            clickSelectHandler = null;
         }
     }
 
index a242ad1dd10d865b46f806f52e47c10edd93eed7..3933099835781528284fe44c804c40a71d54cfb3 100644 (file)
@@ -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());
     }