aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAdam Wagner <wbadam@users.noreply.github.com>2017-06-28 10:29:57 +0200
committerHenri Sara <henri.sara@gmail.com>2017-06-28 11:29:57 +0300
commit6ed5f2a0df068dba713d8e24dc9f78e2a0829a73 (patch)
tree0cc6c37ba43e5d1371b9283b18042289f2e14db0
parente4e2328a3a78d652cd09ef8293f233d31d899415 (diff)
downloadvaadin-framework-6ed5f2a0df068dba713d8e24dc9f78e2a0829a73.tar.gz
vaadin-framework-6ed5f2a0df068dba713d8e24dc9f78e2a0829a73.zip
Create drag source and drop target extensions for tree grid (#9463)
Resolves #9372
-rw-r--r--client/src/main/java/com/vaadin/client/connectors/grid/GridDropTargetConnector.java25
-rw-r--r--client/src/main/java/com/vaadin/client/connectors/grid/TreeGridDragSourceConnector.java37
-rw-r--r--client/src/main/java/com/vaadin/client/connectors/grid/TreeGridDropTargetConnector.java86
-rw-r--r--client/src/main/java/com/vaadin/client/widget/treegrid/TreeGrid.java70
-rw-r--r--documentation/advanced/advanced-dragndrop.asciidoc5
-rw-r--r--server/src/main/java/com/vaadin/ui/components/grid/TreeGridDragSource.java54
-rw-r--r--server/src/main/java/com/vaadin/ui/components/grid/TreeGridDropEvent.java99
-rw-r--r--server/src/main/java/com/vaadin/ui/components/grid/TreeGridDropListener.java44
-rw-r--r--server/src/main/java/com/vaadin/ui/components/grid/TreeGridDropTarget.java104
-rw-r--r--shared/src/main/java/com/vaadin/shared/ui/treegrid/TreeGridDragSourceState.java28
-rw-r--r--shared/src/main/java/com/vaadin/shared/ui/treegrid/TreeGridDropTargetRpc.java59
-rw-r--r--shared/src/main/java/com/vaadin/shared/ui/treegrid/TreeGridDropTargetState.java28
-rw-r--r--uitest/src/main/java/com/vaadin/tests/components/treegrid/TreeGridDragAndDrop.java48
13 files changed, 682 insertions, 5 deletions
diff --git a/client/src/main/java/com/vaadin/client/connectors/grid/GridDropTargetConnector.java b/client/src/main/java/com/vaadin/client/connectors/grid/GridDropTargetConnector.java
index 5b409e3174..9954134821 100644
--- a/client/src/main/java/com/vaadin/client/connectors/grid/GridDropTargetConnector.java
+++ b/client/src/main/java/com/vaadin/client/connectors/grid/GridDropTargetConnector.java
@@ -124,7 +124,14 @@ public class GridDropTargetConnector extends DropTargetExtensionConnector {
rowKey, dropLocation, mouseEventDetails);
}
- private JsonObject getRowData(TableRowElement row) {
+ /**
+ * Get the row data as json object for the given row.
+ *
+ * @param row
+ * table row element
+ * @return row data as json object for the given row
+ */
+ protected JsonObject getRowData(TableRowElement row) {
int rowIndex = ((Escalator.AbstractRowContainer) getGridBody())
.getLogicalRowIndex(row);
return gridConnector.getDataSource().getRow(rowIndex);
@@ -132,8 +139,13 @@ public class GridDropTargetConnector extends DropTargetExtensionConnector {
/**
* Returns the location of the event within the row.
+ *
+ * @param target
+ * drop target element
+ * @param event
+ * drop event
*/
- private DropLocation getDropLocation(Element target, NativeEvent event) {
+ protected DropLocation getDropLocation(Element target, NativeEvent event) {
if (TableRowElement.is(target)) {
if (getState().dropMode == DropMode.BETWEEN) {
if (getRelativeY(target,
@@ -241,7 +253,14 @@ public class GridDropTargetConnector extends DropTargetExtensionConnector {
element.removeClassName(styleDragEmpty);
}
- private Element getTargetElement(Element source) {
+ /**
+ * Gets the target element for a dragover or drop event.
+ *
+ * @param source
+ * the event target of the event
+ * @return the element that should be handled as the target of the event
+ */
+ protected Element getTargetElement(Element source) {
final Element tableWrapper = getDropTargetElement();
final BodyRowContainer gridBody = getGridBody();
final int rowCount = gridBody.getRowCount();
diff --git a/client/src/main/java/com/vaadin/client/connectors/grid/TreeGridDragSourceConnector.java b/client/src/main/java/com/vaadin/client/connectors/grid/TreeGridDragSourceConnector.java
new file mode 100644
index 0000000000..c2450bb9db
--- /dev/null
+++ b/client/src/main/java/com/vaadin/client/connectors/grid/TreeGridDragSourceConnector.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2000-2016 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.connectors.grid;
+
+import com.vaadin.shared.ui.Connect;
+import com.vaadin.shared.ui.treegrid.TreeGridDragSourceState;
+import com.vaadin.ui.components.grid.TreeGridDragSource;
+
+/**
+ * Adds HTML5 drag and drop functionality to a TreeGrid's rows. This is the
+ * client side counterpart of {@link TreeGridDragSource}.
+ *
+ * @author Vaadin Ltd
+ * @since 8.1
+ */
+@Connect(TreeGridDragSource.class)
+public class TreeGridDragSourceConnector extends GridDragSourceConnector {
+
+ @Override
+ public TreeGridDragSourceState getState() {
+ return (TreeGridDragSourceState) super.getState();
+ }
+
+}
diff --git a/client/src/main/java/com/vaadin/client/connectors/grid/TreeGridDropTargetConnector.java b/client/src/main/java/com/vaadin/client/connectors/grid/TreeGridDropTargetConnector.java
new file mode 100644
index 0000000000..fd13426514
--- /dev/null
+++ b/client/src/main/java/com/vaadin/client/connectors/grid/TreeGridDropTargetConnector.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright 2000-2016 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.connectors.grid;
+
+import java.util.List;
+import java.util.Map;
+
+import com.google.gwt.dom.client.Element;
+import com.google.gwt.dom.client.NativeEvent;
+import com.google.gwt.dom.client.TableRowElement;
+import com.vaadin.client.MouseEventDetailsBuilder;
+import com.vaadin.shared.MouseEventDetails;
+import com.vaadin.shared.data.HierarchicalDataCommunicatorConstants;
+import com.vaadin.shared.ui.Connect;
+import com.vaadin.shared.ui.grid.DropLocation;
+import com.vaadin.shared.ui.grid.GridState;
+import com.vaadin.shared.ui.treegrid.TreeGridDropTargetRpc;
+import com.vaadin.shared.ui.treegrid.TreeGridDropTargetState;
+import com.vaadin.ui.components.grid.TreeGridDropTarget;
+
+import elemental.json.JsonObject;
+
+/**
+ * Makes TreeGrid an HTML5 drop target. This is the client side counterpart of
+ * {@link TreeGridDropTarget}.
+ *
+ * @author Vaadin Ltd
+ * @since 8.1
+ */
+@Connect(TreeGridDropTarget.class)
+public class TreeGridDropTargetConnector extends GridDropTargetConnector {
+
+ @Override
+ protected void sendDropEventToServer(List<String> types,
+ Map<String, String> data, String dropEffect,
+ NativeEvent dropEvent) {
+ String rowKey = null;
+ DropLocation dropLocation = null;
+ Integer rowDepth = null;
+ Boolean rowCollapsed = null;
+
+ Element targetElement = getTargetElement(
+ (Element) dropEvent.getEventTarget().cast());
+ // the target element is either the tablewrapper or one of the body rows
+ if (TableRowElement.is(targetElement)) {
+ JsonObject rowData = getRowData(targetElement.cast());
+ rowKey = rowData.getString(GridState.JSONKEY_ROWKEY);
+ dropLocation = getDropLocation(targetElement, dropEvent);
+
+ // Collect hierarchy information
+ JsonObject hierarchyDescription = rowData.getObject(
+ HierarchicalDataCommunicatorConstants.ROW_HIERARCHY_DESCRIPTION);
+ rowDepth = (int) hierarchyDescription
+ .getNumber(HierarchicalDataCommunicatorConstants.ROW_DEPTH);
+ rowCollapsed = hierarchyDescription.getBoolean(
+ HierarchicalDataCommunicatorConstants.ROW_COLLAPSED);
+ } else {
+ dropLocation = DropLocation.EMPTY;
+ }
+
+ MouseEventDetails mouseEventDetails = MouseEventDetailsBuilder
+ .buildMouseEventDetails(dropEvent, targetElement);
+
+ getRpcProxy(TreeGridDropTargetRpc.class).drop(types, data, dropEffect,
+ rowKey, rowDepth, rowCollapsed, dropLocation,
+ mouseEventDetails);
+ }
+
+ @Override
+ public TreeGridDropTargetState getState() {
+ return (TreeGridDropTargetState) super.getState();
+ }
+}
diff --git a/client/src/main/java/com/vaadin/client/widget/treegrid/TreeGrid.java b/client/src/main/java/com/vaadin/client/widget/treegrid/TreeGrid.java
index fb66bebb7d..328d594fe1 100644
--- a/client/src/main/java/com/vaadin/client/widget/treegrid/TreeGrid.java
+++ b/client/src/main/java/com/vaadin/client/widget/treegrid/TreeGrid.java
@@ -16,10 +16,14 @@
package com.vaadin.client.widget.treegrid;
import com.google.gwt.dom.client.Element;
+import com.google.gwt.dom.client.TableRowElement;
import com.google.gwt.event.shared.HandlerRegistration;
+import com.vaadin.client.widget.escalator.EscalatorUpdater;
+import com.vaadin.client.widget.escalator.Row;
import com.vaadin.client.widget.grid.events.BodyClickHandler;
import com.vaadin.client.widget.treegrid.events.TreeGridClickEvent;
import com.vaadin.client.widgets.Grid;
+import com.vaadin.shared.data.HierarchicalDataCommunicatorConstants;
import elemental.json.JsonObject;
@@ -27,14 +31,63 @@ import elemental.json.JsonObject;
* An extension of the Grid widget, which supports displaying of hierarchical
* data.
*
- * @see Grid
- *
* @author Vaadin Ltd
+ * @see Grid
* @since 8.1
*/
public class TreeGrid extends Grid<JsonObject> {
/**
+ * Style name prefix for the row's depth in the hierarchy
+ */
+ private String depthStyleNamePrefix;
+
+ /**
+ * Body updater that adds additional style to each row containing depth
+ * information inside the hierarchy.
+ */
+ protected class BodyUpdater extends Grid.BodyUpdater {
+ @Override
+ public void update(Row row, Iterable cellsToUpdate) {
+ super.update(row, cellsToUpdate);
+
+ int rowIndex = row.getRow();
+ TableRowElement rowElement = row.getElement();
+
+ JsonObject rowData = getDataSource().getRow(rowIndex);
+ if (rowData != null) {
+ int depth = (int) rowData.getObject(
+ HierarchicalDataCommunicatorConstants.ROW_HIERARCHY_DESCRIPTION)
+ .getNumber(
+ HierarchicalDataCommunicatorConstants.ROW_DEPTH);
+
+ // Add or replace style name containing depth information
+ String styleToBeReplaced = getFullClassName(
+ depthStyleNamePrefix, rowElement.getClassName());
+ if (styleToBeReplaced == null) {
+ rowElement.addClassName(depthStyleNamePrefix + depth);
+ } else {
+ rowElement.replaceClassName(styleToBeReplaced,
+ depthStyleNamePrefix + depth);
+ }
+ }
+ }
+
+ private String getFullClassName(String prefix, String classNameList) {
+ int start = classNameList.indexOf(prefix);
+ int end = start + prefix.length();
+ if (start > -1) {
+ while (end < classNameList.length()
+ && classNameList.charAt(end) != ' ') {
+ end++;
+ }
+ return classNameList.substring(start, end);
+ }
+ return null;
+ }
+ }
+
+ /**
* Method for accessing the private {@link Grid#focusCell(int, int)} method
* from this package
*/
@@ -50,8 +103,21 @@ public class TreeGrid extends Grid<JsonObject> {
return this.@com.vaadin.client.widgets.Grid::isElementInChildWidget(*)(e);
}-*/;
+
@Override
public HandlerRegistration addBodyClickHandler(BodyClickHandler handler) {
return addHandler(handler, TreeGridClickEvent.TYPE);
}
+
+ @Override
+ protected EscalatorUpdater createBodyUpdater() {
+ return new BodyUpdater();
+ }
+
+ @Override
+ public void setStylePrimaryName(String style) {
+ super.setStylePrimaryName(style);
+
+ depthStyleNamePrefix = getStylePrimaryName() + "-row-depth-";
+ }
}
diff --git a/documentation/advanced/advanced-dragndrop.asciidoc b/documentation/advanced/advanced-dragndrop.asciidoc
index 8aa18b72ac..47f63a74d9 100644
--- a/documentation/advanced/advanced-dragndrop.asciidoc
+++ b/documentation/advanced/advanced-dragndrop.asciidoc
@@ -361,6 +361,11 @@ When dragging on top of a row, `v-grid-row-drag-center` indicates ON_TOP, `v-gri
(((range="endofrange", startref="term.advanced.dragndrop")))
+=== Drag and Drop Rows in TreeGrid
+
+To make the rows of a TreeGrid component draggable or to make them a drop target, apply [classname]#TreeGridDragSource# or [classname]#TreeGridDropTarget# extensions to the component, respectively.
+In addition to the drag and drop features for Grid above, [classname]#TreeGridDropEvent# provides information about the status of the node (expanded or collapsed) and its depth in the hierarchy.
+
== Drag and Drop Files
Files can be uploaded to the server by dropping them onto a file drop target. To make a component a file drop target, apply the [classname]#FileDropTarget# extension to it by creating a new instance and passing the component as first constructor parameter to it.
diff --git a/server/src/main/java/com/vaadin/ui/components/grid/TreeGridDragSource.java b/server/src/main/java/com/vaadin/ui/components/grid/TreeGridDragSource.java
new file mode 100644
index 0000000000..68d0c68b13
--- /dev/null
+++ b/server/src/main/java/com/vaadin/ui/components/grid/TreeGridDragSource.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2000-2016 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.ui.components.grid;
+
+import com.vaadin.shared.ui.treegrid.TreeGridDragSourceState;
+import com.vaadin.ui.TreeGrid;
+
+/**
+ * Makes a TreeGrid's rows draggable for HTML5 drag and drop functionality.
+ * <p>
+ * When dragging a selected row, all the visible selected rows are dragged. Note
+ * that ONLY visible rows are taken into account and the subtree belonging to a
+ * selected row is not dragged either.
+ *
+ * @param <T>
+ * The TreeGrid bean type.
+ * @author Vaadin Ltd.
+ * @since 8.1
+ */
+public class TreeGridDragSource<T> extends GridDragSource<T> {
+
+ /**
+ * Extends a TreeGrid and makes it's rows draggable.
+ *
+ * @param target
+ * TreeGrid to be extended.
+ */
+ public TreeGridDragSource(TreeGrid<T> target) {
+ super(target);
+ }
+
+ @Override
+ protected TreeGridDragSourceState getState() {
+ return (TreeGridDragSourceState) super.getState();
+ }
+
+ @Override
+ protected TreeGridDragSourceState getState(boolean markAsDirty) {
+ return (TreeGridDragSourceState) super.getState(markAsDirty);
+ }
+}
diff --git a/server/src/main/java/com/vaadin/ui/components/grid/TreeGridDropEvent.java b/server/src/main/java/com/vaadin/ui/components/grid/TreeGridDropEvent.java
new file mode 100644
index 0000000000..015f6169d5
--- /dev/null
+++ b/server/src/main/java/com/vaadin/ui/components/grid/TreeGridDropEvent.java
@@ -0,0 +1,99 @@
+/*
+ * Copyright 2000-2016 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.ui.components.grid;
+
+import java.util.Map;
+import java.util.Optional;
+
+import com.vaadin.shared.MouseEventDetails;
+import com.vaadin.shared.ui.dnd.DropEffect;
+import com.vaadin.shared.ui.grid.DropLocation;
+import com.vaadin.ui.AbstractComponent;
+import com.vaadin.ui.TreeGrid;
+import com.vaadin.ui.dnd.DragSourceExtension;
+
+/**
+ * Drop event on an HTML5 drop target {@link TreeGrid} row.
+ *
+ * @param <T>
+ * The TreeGrid bean type.
+ * @author Vaadin Ltd.
+ * @see TreeGridDropTarget#addTreeGridDropListener(TreeGridDropListener)
+ * @since 8.1
+ */
+public class TreeGridDropEvent<T> extends GridDropEvent<T> {
+
+ private Integer depth;
+ private Boolean collapsed;
+
+ /**
+ * Creates a TreeGrid row drop event.
+ *
+ * @param target
+ * TreeGrid that received the drop.
+ * @param data
+ * Map containing all types and corresponding data from the {@code
+ * DataTransfer} object.
+ * @param dropEffect
+ * the desired drop effect
+ * @param dragSourceExtension
+ * Drag source extension of the component that initiated the drop
+ * event.
+ * @param dropTargetRow
+ * Target row that received the drop, or {@code null} if dropped on
+ * empty grid
+ * @param dropLocation
+ * Location of the drop within the target row.
+ * @param mouseEventDetails
+ * Mouse event details object containing information about the drop
+ * event
+ * @param depth
+ * depth of the row in the hierarchy
+ * @param collapsed
+ * whether the target row is collapsed
+ */
+ public TreeGridDropEvent(TreeGrid<T> target, Map<String, String> data,
+ DropEffect dropEffect,
+ DragSourceExtension<? extends AbstractComponent> dragSourceExtension,
+ T dropTargetRow, DropLocation dropLocation,
+ MouseEventDetails mouseEventDetails, Integer depth,
+ Boolean collapsed) {
+ super(target, data, dropEffect, dragSourceExtension, dropTargetRow,
+ dropLocation, mouseEventDetails);
+
+ this.depth = depth;
+ this.collapsed = collapsed;
+ }
+
+ /**
+ * Gets the depth of the drop target row in the hierarchy.
+ *
+ * @return the depth of the drop target row in the hierarchy
+ */
+ public Optional<Integer> getDropTargetRowDepth() {
+ return Optional.ofNullable(depth);
+ }
+
+ /**
+ * Tells whether the drop target row is collapsed.
+ *
+ * @return {@code true} if the drop target row is collapsed, {@code false}
+ * otherwise
+ */
+ public Optional<Boolean> isDropTargetRowCollapsed() {
+ return Optional.ofNullable(collapsed);
+ }
+}
diff --git a/server/src/main/java/com/vaadin/ui/components/grid/TreeGridDropListener.java b/server/src/main/java/com/vaadin/ui/components/grid/TreeGridDropListener.java
new file mode 100644
index 0000000000..d413a7b42b
--- /dev/null
+++ b/server/src/main/java/com/vaadin/ui/components/grid/TreeGridDropListener.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2000-2016 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.ui.components.grid;
+
+import java.lang.reflect.Method;
+
+import com.vaadin.event.ConnectorEventListener;
+
+/**
+ * Drop listener for HTML5 drop on a TreeGrid row.
+ *
+ * @param <T>
+ * The Grid bean type.
+ * @author Vaadin Ltd.
+ * @see TreeGridDropTarget#addTreeGridDropListener(TreeGridDropListener)
+ * @since 8.1
+ */
+@FunctionalInterface
+public interface TreeGridDropListener<T> extends ConnectorEventListener {
+
+ static final Method DROP_METHOD = TreeGridDropListener.class
+ .getDeclaredMethods()[0];
+
+ /**
+ * Called when drop event is fired on a Grid row.
+ *
+ * @param event
+ * Server side drop event.
+ */
+ void drop(TreeGridDropEvent<T> event);
+}
diff --git a/server/src/main/java/com/vaadin/ui/components/grid/TreeGridDropTarget.java b/server/src/main/java/com/vaadin/ui/components/grid/TreeGridDropTarget.java
new file mode 100644
index 0000000000..1d440b5fec
--- /dev/null
+++ b/server/src/main/java/com/vaadin/ui/components/grid/TreeGridDropTarget.java
@@ -0,0 +1,104 @@
+/*
+ * Copyright 2000-2016 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.ui.components.grid;
+
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+import com.vaadin.shared.Registration;
+import com.vaadin.shared.ui.dnd.DropEffect;
+import com.vaadin.shared.ui.grid.DropMode;
+import com.vaadin.shared.ui.treegrid.TreeGridDropTargetRpc;
+import com.vaadin.shared.ui.treegrid.TreeGridDropTargetState;
+import com.vaadin.ui.TreeGrid;
+
+/**
+ * Makes the rows of a TreeGrid HTML5 drop targets. This is the server side
+ * counterpart of GridDropTargetExtensionConnector.
+ *
+ * @param <T>
+ * Type of the TreeGrid bean.
+ * @author Vaadin Ltd
+ * @since 8.1
+ */
+public class TreeGridDropTarget<T> extends GridDropTarget<T> {
+
+ /**
+ * Extends a TreeGrid and makes it's rows drop targets for HTML5 drag and
+ * drop.
+ *
+ * @param target
+ * TreeGrid to be extended.
+ * @param dropMode
+ * Drop mode that describes the allowed drop locations within the
+ * TreeGrid's row.
+ */
+ public TreeGridDropTarget(TreeGrid<T> target, DropMode dropMode) {
+ super(target, dropMode);
+ }
+
+ /**
+ * Attaches drop listener for the current drop target. {@link
+ * TreeGridDropListener#drop(TreeGridDropEvent)} is called when drop event
+ * happens on the client side.
+ *
+ * @param listener
+ * Listener to handle drop event.
+ * @return Handle to be used to remove this listener.
+ */
+ public Registration addTreeGridDropListener(
+ TreeGridDropListener<T> listener) {
+ return addListener(TreeGridDropEvent.class, listener,
+ TreeGridDropListener.DROP_METHOD);
+ }
+
+ @Override
+ protected void registerDropTargetRpc() {
+ registerRpc((TreeGridDropTargetRpc) (types, data, dropEffect, rowKey,
+ depth, collapsed, dropLocation, mouseEventDetails) -> {
+
+ // Create a linked map that preserves the order of types
+ Map<String, String> dataPreserveOrder = new LinkedHashMap<>();
+ types.forEach(type -> dataPreserveOrder.put(type, data.get(type)));
+
+ T dropTargetRow = getParent().getDataCommunicator().getKeyMapper()
+ .get(rowKey);
+
+ TreeGridDropEvent<T> event = new TreeGridDropEvent<>(getParent(),
+ dataPreserveOrder,
+ DropEffect.valueOf(dropEffect.toUpperCase()),
+ getUI().getActiveDragSource(), dropTargetRow, dropLocation,
+ mouseEventDetails, depth, collapsed);
+
+ fireEvent(event);
+ });
+ }
+
+ @Override
+ public TreeGrid<T> getParent() {
+ return (TreeGrid<T>) super.getParent();
+ }
+
+ @Override
+ protected TreeGridDropTargetState getState() {
+ return (TreeGridDropTargetState) super.getState();
+ }
+
+ @Override
+ protected TreeGridDropTargetState getState(boolean markAsDirty) {
+ return (TreeGridDropTargetState) super.getState(markAsDirty);
+ }
+}
diff --git a/shared/src/main/java/com/vaadin/shared/ui/treegrid/TreeGridDragSourceState.java b/shared/src/main/java/com/vaadin/shared/ui/treegrid/TreeGridDragSourceState.java
new file mode 100644
index 0000000000..f3ea4cf900
--- /dev/null
+++ b/shared/src/main/java/com/vaadin/shared/ui/treegrid/TreeGridDragSourceState.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2000-2016 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.shared.ui.treegrid;
+
+import com.vaadin.shared.ui.grid.GridDragSourceState;
+
+/**
+ * State class containing parameters for TreeGridDragSource.
+ *
+ * @author Vaadin Ltd
+ * @since 8.1
+ */
+public class TreeGridDragSourceState extends GridDragSourceState {
+
+}
diff --git a/shared/src/main/java/com/vaadin/shared/ui/treegrid/TreeGridDropTargetRpc.java b/shared/src/main/java/com/vaadin/shared/ui/treegrid/TreeGridDropTargetRpc.java
new file mode 100644
index 0000000000..0ce81c80dd
--- /dev/null
+++ b/shared/src/main/java/com/vaadin/shared/ui/treegrid/TreeGridDropTargetRpc.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2000-2016 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.shared.ui.treegrid;
+
+import java.util.List;
+import java.util.Map;
+
+import com.vaadin.shared.MouseEventDetails;
+import com.vaadin.shared.communication.ServerRpc;
+import com.vaadin.shared.ui.grid.DropLocation;
+
+/**
+ * RPC for firing server side drop event when client side drop event happens on
+ * drop target TreeGrid.
+ *
+ * @author Vaadin Ltd.
+ * @since 8.1
+ */
+public interface TreeGridDropTargetRpc extends ServerRpc {
+
+ /**
+ * Called when drop event happens on client side.
+ *
+ * @param types
+ * list of data types from {@code DataTransfer.types} object
+ * @param data
+ * map containing all types and corresponding data from the {@code
+ * DataTransfer} object
+ * @param dropEffect
+ * the desired drop effect
+ * @param rowKey
+ * key of the row on which the drop event occurred
+ * @param depth
+ * depth of the row in the hierarchy
+ * @param collapsed
+ * whether the target row is collapsed
+ * @param dropLocation
+ * location of the drop within the row
+ * @param mouseEventDetails
+ * Mouse event details object containing information about the drop
+ * event
+ */
+ public void drop(List<String> types, Map<String, String> data,
+ String dropEffect, String rowKey, Integer depth, Boolean collapsed,
+ DropLocation dropLocation, MouseEventDetails mouseEventDetails);
+}
diff --git a/shared/src/main/java/com/vaadin/shared/ui/treegrid/TreeGridDropTargetState.java b/shared/src/main/java/com/vaadin/shared/ui/treegrid/TreeGridDropTargetState.java
new file mode 100644
index 0000000000..29fea79c98
--- /dev/null
+++ b/shared/src/main/java/com/vaadin/shared/ui/treegrid/TreeGridDropTargetState.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2000-2016 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.shared.ui.treegrid;
+
+import com.vaadin.shared.ui.grid.GridDropTargetState;
+
+/**
+ * State class containing parameters for TreeGridDropTarget.
+ *
+ * @author Vaadin Ltd
+ * @since 8.1
+ */
+public class TreeGridDropTargetState extends GridDropTargetState {
+
+}
diff --git a/uitest/src/main/java/com/vaadin/tests/components/treegrid/TreeGridDragAndDrop.java b/uitest/src/main/java/com/vaadin/tests/components/treegrid/TreeGridDragAndDrop.java
new file mode 100644
index 0000000000..2ed2c4f1f4
--- /dev/null
+++ b/uitest/src/main/java/com/vaadin/tests/components/treegrid/TreeGridDragAndDrop.java
@@ -0,0 +1,48 @@
+package com.vaadin.tests.components.treegrid;
+
+import com.vaadin.annotations.Theme;
+import com.vaadin.annotations.Widgetset;
+import com.vaadin.server.VaadinRequest;
+import com.vaadin.shared.ui.grid.DropMode;
+import com.vaadin.tests.components.AbstractTestUIWithLog;
+import com.vaadin.tests.data.bean.HierarchicalTestBean;
+import com.vaadin.ui.TreeGrid;
+import com.vaadin.ui.components.grid.TreeGridDragSource;
+import com.vaadin.ui.components.grid.TreeGridDropTarget;
+
+@Theme("valo")
+@Widgetset("com.vaadin.DefaultWidgetSet")
+public class TreeGridDragAndDrop extends AbstractTestUIWithLog {
+ @Override
+ protected void setup(VaadinRequest request) {
+ getUI().setMobileHtml5DndEnabled(true);
+
+ TreeGrid<HierarchicalTestBean> grid;
+ grid = new TreeGrid<>();
+ grid.setSizeFull();
+ grid.addColumn(HierarchicalTestBean::toString).setCaption("String")
+ .setId("string");
+ grid.addColumn(HierarchicalTestBean::getDepth).setCaption("Depth")
+ .setId("depth").setDescriptionGenerator(
+ t -> "Hierarchy depth: " + t.getDepth());
+ grid.addColumn(HierarchicalTestBean::getIndex)
+ .setCaption("Index on this depth").setId("index");
+ grid.setHierarchyColumn("string");
+ grid.setDataProvider(new LazyHierarchicalDataProvider(3, 2));
+
+ grid.setId("testComponent");
+
+ TreeGridDragSource<HierarchicalTestBean> dragSource = new TreeGridDragSource<>(
+ grid);
+ TreeGridDropTarget<HierarchicalTestBean> dropTarget = new TreeGridDropTarget<>(
+ grid, DropMode.ON_TOP_OR_BETWEEN);
+
+ dropTarget.addTreeGridDropListener(event -> {
+ log("depth=" + event.getDropTargetRowDepth().orElse(null)
+ + ", collapsed=" + event.isDropTargetRowCollapsed()
+ .orElse(null));
+ });
+
+ addComponent(grid);
+ }
+}