diff options
author | Adam Wagner <wbadam@users.noreply.github.com> | 2017-05-16 10:21:31 +0300 |
---|---|---|
committer | Pekka Hyvönen <pekka@vaadin.com> | 2017-05-16 10:21:31 +0300 |
commit | eb743d965278d263a4c496bb4e39c067fe2b1a8c (patch) | |
tree | f820843370c55216a4ec9612f3e20569b3d1e40f /server | |
parent | 04e7259fb497e47bcd6d664e87c243db5badd934 (diff) | |
download | vaadin-framework-eb743d965278d263a4c496bb4e39c067fe2b1a8c.tar.gz vaadin-framework-eb743d965278d263a4c496bb4e39c067fe2b1a8c.zip |
Add API to store any type of data in the dataTransfer object (#9319)
Diffstat (limited to 'server')
6 files changed, 189 insertions, 45 deletions
diff --git a/server/src/main/java/com/vaadin/ui/components/grid/GridDropEvent.java b/server/src/main/java/com/vaadin/ui/components/grid/GridDropEvent.java index 40df9f254f..08d0dad956 100644 --- a/server/src/main/java/com/vaadin/ui/components/grid/GridDropEvent.java +++ b/server/src/main/java/com/vaadin/ui/components/grid/GridDropEvent.java @@ -15,6 +15,8 @@ */ package com.vaadin.ui.components.grid; +import java.util.Map; + import com.vaadin.shared.ui.dnd.DropEffect; import com.vaadin.shared.ui.grid.DropLocation; import com.vaadin.ui.AbstractComponent; @@ -40,25 +42,25 @@ public class GridDropEvent<T> extends DropEvent<Grid<T>> { * Creates a Grid row drop event. * * @param target - * Grid that received the drop. - * @param dataTransferText - * Data of type {@code "text"} from the {@code DataTransfer} - * object. + * Grid that received the drop. + * @param data + * Map containing all types and corresponding data from the {@code + * DataTransfer} object. * @param dropEffect - * the desired drop effect + * the desired drop effect * @param dragSourceExtension - * Drag source extension of the component that initiated the drop - * event. + * Drag source extension of the component that initiated the drop + * event. * @param dropTargetRow - * Target row that received the drop. + * Target row that received the drop. * @param dropLocation - * Location of the drop within the target row. + * Location of the drop within the target row. */ - public GridDropEvent(Grid<T> target, String dataTransferText, + public GridDropEvent(Grid<T> target, Map<String, String> data, DropEffect dropEffect, DragSourceExtension<? extends AbstractComponent> dragSourceExtension, T dropTargetRow, DropLocation dropLocation) { - super(target, dataTransferText, dropEffect, dragSourceExtension); + super(target, data, dropEffect, dragSourceExtension); this.dropTargetRow = dropTargetRow; this.dropLocation = dropLocation; diff --git a/server/src/main/java/com/vaadin/ui/components/grid/GridDropTarget.java b/server/src/main/java/com/vaadin/ui/components/grid/GridDropTarget.java index 435f40da6e..07c81c9981 100644 --- a/server/src/main/java/com/vaadin/ui/components/grid/GridDropTarget.java +++ b/server/src/main/java/com/vaadin/ui/components/grid/GridDropTarget.java @@ -15,6 +15,9 @@ */ 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; @@ -130,14 +133,18 @@ public class GridDropTarget<T> extends DropTargetExtension<Grid<T>> { @Override protected void registerDropTargetRpc() { - registerRpc((GridDropTargetRpc) (dataTransferText, dropEffect, rowKey, + registerRpc((GridDropTargetRpc) (types, data, dropEffect, rowKey, dropLocation) -> { + // 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); GridDropEvent<T> event = new GridDropEvent<>(getParent(), - dataTransferText, + dataPreserveOrder, DropEffect.valueOf(dropEffect.toUpperCase()), getUI().getActiveDragSource(), dropTargetRow, dropLocation); diff --git a/server/src/main/java/com/vaadin/ui/dnd/DragSourceExtension.java b/server/src/main/java/com/vaadin/ui/dnd/DragSourceExtension.java index 24192fa592..42c29f738a 100644 --- a/server/src/main/java/com/vaadin/ui/dnd/DragSourceExtension.java +++ b/server/src/main/java/com/vaadin/ui/dnd/DragSourceExtension.java @@ -15,6 +15,9 @@ */ package com.vaadin.ui.dnd; +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.Map; import java.util.Objects; import com.vaadin.server.AbstractExtension; @@ -163,6 +166,14 @@ public class DragSourceExtension<T extends AbstractComponent> * Returns the allowed effects for the current drag source element. Used to * set client side {@code DataTransfer.effectAllowed} parameter for the drag * event. + * <p> + * You can use different types of data to support dragging to different + * targets. Accepted types depend on the drop target and those can be + * platform specific. See https://developer.mozilla.org/en-US/docs/Web/API/HTML_Drag_and_Drop_API/Recommended_drag_types + * for examples on different types. + * <p> + * <em>NOTE: IE11 only supports type ' text', which can be set using {@link + * #setDataTransferText(String data)}</em> * * @return Effects that are allowed for this draggable element. */ @@ -171,15 +182,81 @@ public class DragSourceExtension<T extends AbstractComponent> } /** - * Sets data for this drag source element. The data is set for the client - * side draggable element using the {@code DataTransfer.setData("text", - * data)} method. + * Sets data for this drag source element with the given type. The data is + * set for the client side draggable element using {@code + * DataTransfer.setData(type, data)} method. + * <p> + * Note that {@code "text"} is the only cross browser supported data type. + * Use {@link #setDataTransferText(String)} method instead if your + * application supports IE11. * + * @param type + * Type of the data to be set for the client side draggable element, + * e.g. {@code text/plain}. Cannot be {@code null}. * @param data - * Data to be set for the client side draggable element. + * Data to be set for the client side draggable element. Cannot be + * {@code null}. + */ + public void setDataTransferData(String type, String data) { + if (type == null) { + throw new IllegalArgumentException("Data type cannot be null"); + } + + if (data == null) { + throw new IllegalArgumentException("Data cannot be null"); + } + + if (!getState(false).types.contains(type)) { + getState().types.add(type); + } + getState().data.put(type, data); + } + + /** + * Returns the data stored with type {@code type} in this drag source + * element. + * + * @param type + * Type of the requested data, e.g. {@code text/plain}. + * @return Data of type {@code type} stored in this drag source element. + */ + public String getDataTransferData(String type) { + return getState(false).data.get(type); + } + + /** + * Returns the map of data stored in this drag source element. The returned + * map preserves the order of storage and is unmodifiable. + * + * @return Unmodifiable copy of the map of data in the order the data was + * stored. + */ + public Map<String, String> getDataTransferData() { + Map<String, String> data = getState(false).data; + + // Create a map of data that preserves the order of types + LinkedHashMap<String, String> orderedData = new LinkedHashMap<>( + data.size()); + getState(false).types + .forEach(type -> orderedData.put(type, data.get(type))); + + return Collections.unmodifiableMap(orderedData); + } + + /** + * Sets data of type {@code "text"} for this drag source element. The data + * is set for the client side draggable element using the {@code + * DataTransfer.setData("text", data)} method. + * <p> + * Note that {@code "text"} is the only cross browser supported data type. + * Use this method if your application supports IE11. + * + * @param data + * Data to be set for the client side draggable element. + * @see #setDataTransferData(String, String) */ public void setDataTransferText(String data) { - getState().dataTransferText = data; + setDataTransferData(DragSourceState.DATA_TYPE_TEXT, data); } /** @@ -189,7 +266,31 @@ public class DragSourceExtension<T extends AbstractComponent> * @return Data of type {@code "text"} stored in this drag source element. */ public String getDataTransferText() { - return getState(false).dataTransferText; + return getDataTransferData(DragSourceState.DATA_TYPE_TEXT); + } + + /** + * Clears data with the given type for this drag source element when + * present. + * + * @param type + * Type of data to be cleared. Cannot be {@code null}. + */ + public void clearDataTransferData(String type) { + if (type == null) { + throw new IllegalArgumentException("Data type cannot be null"); + } + + getState().types.remove(type); + getState().data.remove(type); + } + + /** + * Clears all data for this drag source element. + */ + public void clearDataTransferData() { + getState().types.clear(); + getState().data.clear(); } /** diff --git a/server/src/main/java/com/vaadin/ui/dnd/DropTargetExtension.java b/server/src/main/java/com/vaadin/ui/dnd/DropTargetExtension.java index 24a0372f50..fddb636f70 100644 --- a/server/src/main/java/com/vaadin/ui/dnd/DropTargetExtension.java +++ b/server/src/main/java/com/vaadin/ui/dnd/DropTargetExtension.java @@ -15,6 +15,9 @@ */ package com.vaadin.ui.dnd; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; import java.util.Objects; import com.vaadin.server.AbstractExtension; @@ -62,12 +65,11 @@ public class DropTargetExtension<T extends AbstractComponent> * Override this method if you need to have a custom RPC interface for * transmitting the drop event with more data. If just need to do additional * things before firing the drop event, then you should override - * {@link #onDrop(String, DropEffect)} instead. + * {@link #onDrop(List, Map, DropEffect)} instead. */ protected void registerDropTargetRpc() { - registerRpc((DropTargetRpc) (dataTransferText, dropEffect) -> { - onDrop(dataTransferText, - DropEffect.valueOf(dropEffect.toUpperCase())); + registerRpc((DropTargetRpc) (types, data, dropEffect) -> { + onDrop(types, data, DropEffect.valueOf(dropEffect.toUpperCase())); }); } @@ -75,13 +77,22 @@ public class DropTargetExtension<T extends AbstractComponent> * Invoked when a <code>drop</code> has been received from client side. * Fires the {@link DropEvent}. * - * @param dataTransferText - * the data transfer of type 'text' for the drop + * @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 drop effect + * the drop effect */ - protected void onDrop(String dataTransferText, DropEffect dropEffect) { - DropEvent<T> event = new DropEvent<>(getParent(), dataTransferText, + protected void onDrop(List<String> types, Map<String, String> data, + DropEffect dropEffect) { + + // 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))); + + DropEvent<T> event = new DropEvent<>(getParent(), dataPreserveOrder, dropEffect, getUI().getActiveDragSource()); fireEvent(event); diff --git a/server/src/main/java/com/vaadin/ui/dnd/event/DragEndEvent.java b/server/src/main/java/com/vaadin/ui/dnd/event/DragEndEvent.java index 592a81497f..de0ba64a5e 100644 --- a/server/src/main/java/com/vaadin/ui/dnd/event/DragEndEvent.java +++ b/server/src/main/java/com/vaadin/ui/dnd/event/DragEndEvent.java @@ -64,7 +64,6 @@ public class DragEndEvent<T extends AbstractComponent> extends Component.Event { * dragend event. * @see DragSourceExtension#setEffectAllowed(EffectAllowed) * @see DropTargetExtension#setDropEffect(DropEffect) - * @see DropTargetExtension#setDragOverCriteria(String) * @see DropTargetExtension#setDropCriteria(String) */ public DropEffect getDropEffect() { diff --git a/server/src/main/java/com/vaadin/ui/dnd/event/DropEvent.java b/server/src/main/java/com/vaadin/ui/dnd/event/DropEvent.java index 45dabd0a62..db0e4aa7a9 100644 --- a/server/src/main/java/com/vaadin/ui/dnd/event/DropEvent.java +++ b/server/src/main/java/com/vaadin/ui/dnd/event/DropEvent.java @@ -15,8 +15,10 @@ */ package com.vaadin.ui.dnd.event; +import java.util.Map; import java.util.Optional; +import com.vaadin.shared.ui.dnd.DragSourceState; import com.vaadin.shared.ui.dnd.DropEffect; import com.vaadin.ui.AbstractComponent; import com.vaadin.ui.Component; @@ -33,7 +35,7 @@ import com.vaadin.ui.dnd.DropTargetExtension; * @since 8.1 */ public class DropEvent<T extends AbstractComponent> extends Component.Event { - private final String dataTransferText; + private final Map<String, String> data; private final DragSourceExtension<? extends AbstractComponent> dragSourceExtension; private final AbstractComponent dragSource; private final DropEffect dropEffect; @@ -42,37 +44,59 @@ public class DropEvent<T extends AbstractComponent> extends Component.Event { * Creates a server side drop event. * * @param target - * Component that received the drop. - * @param dataTransferText - * Data of type {@code "text"} from the {@code DataTransfer} - * object. + * Component that received the drop. + * @param data + * Map containing all types and corresponding data from the {@code + * DataTransfer} object. * @param dropEffect - * the desired drop effect + * the desired drop effect * @param dragSourceExtension - * Drag source extension of the component that initiated the drop - * event. + * Drag source extension of the component that initiated the drop + * event. */ - public DropEvent(T target, String dataTransferText, DropEffect dropEffect, + public DropEvent(T target, Map<String, String> data, DropEffect dropEffect, DragSourceExtension<? extends AbstractComponent> dragSourceExtension) { super(target); - this.dataTransferText = dataTransferText; + this.data = data; this.dropEffect = dropEffect; - this.dragSourceExtension = dragSourceExtension; this.dragSource = Optional.ofNullable(dragSourceExtension) .map(DragSourceExtension::getParent).orElse(null); } /** - * Get data of type {@code "text"} from the client side {@code DataTransfer} - * object. + * Get data from the {@code DataTransfer} object. + * + * @param type + * Data format, e.g. {@code text/plain} or {@code text/uri-list}. + * @return Optional data for the given format if exists in the {@code + * DataTransfer}, otherwise {@code Optional.empty()}. + */ + public Optional<String> getDataTransferData(String type) { + return Optional.ofNullable(data.get(type)); + } + + /** + * Get data of type {@code "text"} from the {@code DataTransfer} object. * - * @return Data of type {@code "text"} if exists in the client side {@code - * DataTransfer} object, otherwise {@literal null}. + * @return Data of type {@code "text"} if exists in the {@code DataTransfer} + * object, otherwise {@literal null}. */ public String getDataTransferText() { - return dataTransferText; + return data.get(DragSourceState.DATA_TYPE_TEXT); + } + + /** + * Get all of the transfer data from the {@code DataTransfer} object. The + * data can be iterated to find the most relevant data as it preserves the + * order in which the data was set to the drag source element. + * + * @return Map of type/data pairs, containing all the data from the {@code + * DataTransfer} object. + */ + public Map<String, String> getDataTransferData() { + return data; } /** |