From 813a99cfeff9d9cd70d77bd5d9ae75f5fa7b2ff5 Mon Sep 17 00:00:00 2001 From: Adam Wagner Date: Wed, 22 Feb 2017 15:36:58 +0200 Subject: Make DragSource extension/component available in DropEvent (#8636) * Make DragSource extension/component available in DropEvent (resolves #8439) * Update drag and drop test to use new API * Change type of drag source and update javadoc * Use existing data map instead of DataTransfer --- .../extensions/DragSourceExtensionConnector.java | 9 ++++ .../extensions/DropTargetExtensionConnector.java | 3 +- .../java/com/vaadin/event/dnd/DragEndEvent.java | 3 +- .../java/com/vaadin/event/dnd/DragEndListener.java | 4 +- .../java/com/vaadin/event/dnd/DragStartEvent.java | 3 +- .../com/vaadin/event/dnd/DragStartListener.java | 4 +- .../main/java/com/vaadin/event/dnd/DropEvent.java | 46 +++++++++++++++++--- .../java/com/vaadin/event/dnd/DropListener.java | 4 +- .../com/vaadin/event/dnd/DropTargetExtension.java | 13 +++++- .../com/vaadin/shared/ui/dnd/DropTargetRpc.java | 4 +- .../vaadin/tests/dnd/DragAndDropCardShuffle.java | 49 ++++++---------------- 11 files changed, 87 insertions(+), 55 deletions(-) diff --git a/client/src/main/java/com/vaadin/client/extensions/DragSourceExtensionConnector.java b/client/src/main/java/com/vaadin/client/extensions/DragSourceExtensionConnector.java index 532b9877fc..b823167572 100644 --- a/client/src/main/java/com/vaadin/client/extensions/DragSourceExtensionConnector.java +++ b/client/src/main/java/com/vaadin/client/extensions/DragSourceExtensionConnector.java @@ -42,6 +42,11 @@ public class DragSourceExtensionConnector extends AbstractExtensionConnector { private static final String CLASS_DRAGGABLE = "v-draggable"; + /** + * Data type for storing drag source extension connector's ID + */ + static final String DATA_TYPE_DRAG_SOURCE_ID = "drag-source-id"; + // Create event listeners private final EventListener dragStartListener = this::onDragStart; private final EventListener dragEndListener = this::onDragEnd; @@ -104,6 +109,10 @@ public class DragSourceExtensionConnector extends AbstractExtensionConnector { nativeEvent.getDataTransfer().setData(format, data.get(format)); } + // Store the extension's connector ID in DataTransfer.data + nativeEvent.getDataTransfer() + .setData(DATA_TYPE_DRAG_SOURCE_ID, getConnectorId()); + // Initiate firing server side dragstart event when there is a // DragStartListener attached on the server side if (hasEventListener(DragSourceState.EVENT_DRAGSTART)) { diff --git a/client/src/main/java/com/vaadin/client/extensions/DropTargetExtensionConnector.java b/client/src/main/java/com/vaadin/client/extensions/DropTargetExtensionConnector.java index 3a9cbbfe84..37d62ad7c0 100644 --- a/client/src/main/java/com/vaadin/client/extensions/DropTargetExtensionConnector.java +++ b/client/src/main/java/com/vaadin/client/extensions/DropTargetExtensionConnector.java @@ -193,7 +193,8 @@ public class DropTargetExtensionConnector extends AbstractExtensionConnector { } getRpcProxy(DropTargetRpc.class) - .drop(types, data, getState().dropEffect); + .drop(types, data, getState().dropEffect, data.get( + DragSourceExtensionConnector.DATA_TYPE_DRAG_SOURCE_ID)); } removeTargetIndicator(getDropTargetElement()); diff --git a/server/src/main/java/com/vaadin/event/dnd/DragEndEvent.java b/server/src/main/java/com/vaadin/event/dnd/DragEndEvent.java index 47abea4eae..9de3611457 100644 --- a/server/src/main/java/com/vaadin/event/dnd/DragEndEvent.java +++ b/server/src/main/java/com/vaadin/event/dnd/DragEndEvent.java @@ -20,6 +20,7 @@ import java.util.List; import java.util.Map; import com.vaadin.shared.ui.dnd.EffectAllowed; +import com.vaadin.ui.AbstractComponent; import com.vaadin.ui.Component; /** @@ -29,7 +30,7 @@ import com.vaadin.ui.Component; * Type of the component that was dragged. * @see DragSourceExtension#addDragEndListener(DragEndListener) */ -public class DragEndEvent extends Component.Event { +public class DragEndEvent extends Component.Event { private final Map data; private final EffectAllowed effectAllowed; diff --git a/server/src/main/java/com/vaadin/event/dnd/DragEndListener.java b/server/src/main/java/com/vaadin/event/dnd/DragEndListener.java index 7b35bcab1d..51e113e4fd 100644 --- a/server/src/main/java/com/vaadin/event/dnd/DragEndListener.java +++ b/server/src/main/java/com/vaadin/event/dnd/DragEndListener.java @@ -18,7 +18,7 @@ package com.vaadin.event.dnd; import java.lang.reflect.Method; import com.vaadin.event.ConnectorEventListener; -import com.vaadin.ui.Component; +import com.vaadin.ui.AbstractComponent; /** * Interface to be implemented when creating a dragend listener on a drag @@ -29,7 +29,7 @@ import com.vaadin.ui.Component; * @see DragSourceExtension#addDragEndListener(DragEndListener) */ @FunctionalInterface -public interface DragEndListener extends +public interface DragEndListener extends ConnectorEventListener { static final Method DRAGEND_METHOD = DragEndListener.class .getDeclaredMethods()[0]; diff --git a/server/src/main/java/com/vaadin/event/dnd/DragStartEvent.java b/server/src/main/java/com/vaadin/event/dnd/DragStartEvent.java index de6a1a79f4..8e9f82551c 100644 --- a/server/src/main/java/com/vaadin/event/dnd/DragStartEvent.java +++ b/server/src/main/java/com/vaadin/event/dnd/DragStartEvent.java @@ -20,6 +20,7 @@ import java.util.List; import java.util.Map; import com.vaadin.shared.ui.dnd.EffectAllowed; +import com.vaadin.ui.AbstractComponent; import com.vaadin.ui.Component; /** @@ -30,7 +31,7 @@ import com.vaadin.ui.Component; * Type of the component that is dragged. * @see DragSourceExtension#addDragStartListener(DragStartListener) */ -public class DragStartEvent extends Component.Event { +public class DragStartEvent extends Component.Event { private final Map data; private final EffectAllowed effectAllowed; diff --git a/server/src/main/java/com/vaadin/event/dnd/DragStartListener.java b/server/src/main/java/com/vaadin/event/dnd/DragStartListener.java index a9536144d9..d56254c58d 100644 --- a/server/src/main/java/com/vaadin/event/dnd/DragStartListener.java +++ b/server/src/main/java/com/vaadin/event/dnd/DragStartListener.java @@ -18,7 +18,7 @@ package com.vaadin.event.dnd; import java.lang.reflect.Method; import com.vaadin.event.ConnectorEventListener; -import com.vaadin.ui.Component; +import com.vaadin.ui.AbstractComponent; /** * Interface to be implemented when creating a dragstart listener on a drag @@ -29,7 +29,7 @@ import com.vaadin.ui.Component; * @see DragSourceExtension#addDragStartListener(DragStartListener) */ @FunctionalInterface -public interface DragStartListener extends +public interface DragStartListener extends ConnectorEventListener { static final Method DRAGSTART_METHOD = DragStartListener.class .getDeclaredMethods()[0]; diff --git a/server/src/main/java/com/vaadin/event/dnd/DropEvent.java b/server/src/main/java/com/vaadin/event/dnd/DropEvent.java index 5257a06367..9a16efc097 100644 --- a/server/src/main/java/com/vaadin/event/dnd/DropEvent.java +++ b/server/src/main/java/com/vaadin/event/dnd/DropEvent.java @@ -18,8 +18,10 @@ package com.vaadin.event.dnd; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; +import java.util.Optional; import com.vaadin.shared.ui.dnd.DropEffect; +import com.vaadin.ui.AbstractComponent; import com.vaadin.ui.Component; /** @@ -29,15 +31,17 @@ import com.vaadin.ui.Component; * Type of the drop target component. * @see DropTargetExtension#addDropListener(DropListener) */ -public class DropEvent extends Component.Event { +public class DropEvent extends Component.Event { private final Map data; private final DropEffect dropEffect; + private final DragSourceExtension dragSourceExtension; + private final AbstractComponent dragSource; /** * Creates a server side drop event. * - * @param source - * Component that is dragged. + * @param target + * Component that received the drop. * @param types * List of data types from {@code DataTransfer.types} object. * @param data @@ -45,16 +49,24 @@ public class DropEvent extends Component.Event { * DataTransfer} object. * @param dropEffect * Drop effect from {@code DataTransfer.dropEffect} object. + * @param dragSourceExtension + * Drag source extension of the component that initiated the drop + * event. */ - public DropEvent(T source, List types, Map data, - DropEffect dropEffect) { - super(source); + public DropEvent(T target, List types, Map data, + DropEffect dropEffect, + DragSourceExtension dragSourceExtension) { + super(target); // Create a linked map that preserves the order of types this.data = new LinkedHashMap<>(); types.forEach(type -> this.data.put(type, data.get(type))); this.dropEffect = dropEffect; + + this.dragSourceExtension = dragSourceExtension; + this.dragSource = Optional.ofNullable(dragSourceExtension) + .map(DragSourceExtension::getParent).orElse(null); } /** @@ -78,6 +90,28 @@ public class DropEvent extends Component.Event { return dropEffect; } + /** + * Returns the drag source component if the drag originated from a + * component in the same UI as the drop target component, or an empty + * optional. + * + * @return Drag source component or an empty optional. + */ + public Optional getDragSourceComponent() { + return Optional.ofNullable(dragSource); + } + + /** + * Returns the extension of the drag source component if the drag + * originated from a component in the same UI as the drop target component, + * or an empty optional. + * + * @return Drag source extension or an empty optional + */ + public Optional> getDragSourceExtension() { + return Optional.ofNullable(dragSourceExtension); + } + /** * Returns the drop target component where the drop event occurred. * diff --git a/server/src/main/java/com/vaadin/event/dnd/DropListener.java b/server/src/main/java/com/vaadin/event/dnd/DropListener.java index 41c1bfc6ff..98e8147fc3 100644 --- a/server/src/main/java/com/vaadin/event/dnd/DropListener.java +++ b/server/src/main/java/com/vaadin/event/dnd/DropListener.java @@ -18,7 +18,7 @@ package com.vaadin.event.dnd; import java.lang.reflect.Method; import com.vaadin.event.ConnectorEventListener; -import com.vaadin.ui.Component; +import com.vaadin.ui.AbstractComponent; /** * Interface to be implemented when creating a drop listener on a drop target @@ -29,7 +29,7 @@ import com.vaadin.ui.Component; * @see DropTargetExtension#addDropListener(DropListener) */ @FunctionalInterface -public interface DropListener extends +public interface DropListener extends ConnectorEventListener { static final Method DROP_METHOD = DropListener.class .getDeclaredMethods()[0]; diff --git a/server/src/main/java/com/vaadin/event/dnd/DropTargetExtension.java b/server/src/main/java/com/vaadin/event/dnd/DropTargetExtension.java index e6f1fe1214..887361e883 100644 --- a/server/src/main/java/com/vaadin/event/dnd/DropTargetExtension.java +++ b/server/src/main/java/com/vaadin/event/dnd/DropTargetExtension.java @@ -18,6 +18,7 @@ package com.vaadin.event.dnd; import java.util.Objects; import com.vaadin.server.AbstractExtension; +import com.vaadin.server.ClientConnector; import com.vaadin.shared.Registration; import com.vaadin.shared.ui.dnd.DropEffect; import com.vaadin.shared.ui.dnd.DropTargetRpc; @@ -41,9 +42,17 @@ public class DropTargetExtension extends * Component to be extended. */ public DropTargetExtension(T target) { - registerRpc((DropTargetRpc) (types, data, dropEffect) -> { + registerRpc((DropTargetRpc) (types, data, dropEffect, dataSourceId) -> { + DragSourceExtension dragSource = null; + + ClientConnector connector = getUI().getConnectorTracker() + .getConnector(dataSourceId); + if (connector != null && connector instanceof DragSourceExtension) { + dragSource = (DragSourceExtension) connector; + } + DropEvent event = new DropEvent<>(target, types, data, - dropEffect); + dropEffect, dragSource); fireEvent(event); }); diff --git a/shared/src/main/java/com/vaadin/shared/ui/dnd/DropTargetRpc.java b/shared/src/main/java/com/vaadin/shared/ui/dnd/DropTargetRpc.java index dd21278277..9f335f010d 100644 --- a/shared/src/main/java/com/vaadin/shared/ui/dnd/DropTargetRpc.java +++ b/shared/src/main/java/com/vaadin/shared/ui/dnd/DropTargetRpc.java @@ -36,7 +36,9 @@ public interface DropTargetRpc extends ServerRpc { * Contains data from {@code DataTransfer} object. * @param dropEffect * Drop effect set for the drop target where drop happened. + * @param dragSourceId + * Drag source component connector's ID. */ public void drop(List types, Map data, - DropEffect dropEffect); + DropEffect dropEffect, String dragSourceId); } diff --git a/uitest/src/main/java/com/vaadin/tests/dnd/DragAndDropCardShuffle.java b/uitest/src/main/java/com/vaadin/tests/dnd/DragAndDropCardShuffle.java index 8f5df032cc..745297cde8 100644 --- a/uitest/src/main/java/com/vaadin/tests/dnd/DragAndDropCardShuffle.java +++ b/uitest/src/main/java/com/vaadin/tests/dnd/DragAndDropCardShuffle.java @@ -15,23 +15,17 @@ */ package com.vaadin.tests.dnd; -import java.util.Optional; - import com.vaadin.event.dnd.DragSourceExtension; import com.vaadin.event.dnd.DropTargetExtension; -import com.vaadin.server.Extension; import com.vaadin.server.Page; import com.vaadin.server.VaadinRequest; +import com.vaadin.shared.ui.dnd.DropEffect; import com.vaadin.tests.components.AbstractTestUIWithLog; -import com.vaadin.ui.Component; import com.vaadin.ui.HorizontalLayout; import com.vaadin.ui.Label; public class DragAndDropCardShuffle extends AbstractTestUIWithLog { - // Data type for storing card position - private static final String DATA_INDEX = "index"; - // Create cards private final Label ace = new Label("A"); private final Label jack = new Label("J"); @@ -74,10 +68,6 @@ public class DragAndDropCardShuffle extends AbstractTestUIWithLog { DragSourceExtension