* Add DragSource Extension (#8169) * Add DropTarget Extension (#8170) * Add DragStart Event to DragSource Extension (#8171) * Make DataTransfer.dropEffect configurable (#8174) * Make DragSource.dataTransfer data configurable (#8172) * Add server-side Event for drop (#8177) * Added license headers * Extract handler methods, move DropEvent and DropListener to new file, move enums to top * Replaced LinkedHashMap with Map and added List to preserve order of data * Add API for adding a JS acceptance criteria for dragover and drop (#8178, #8179) * Make DragSource Extension extendable (#8175) * Make DropTarget Extension extendable (#8176) * Added javadoc to protected methods * Moved EffectAllowed to shared so that it could be used in shared state directly * Moved DropEffect to separate file, some review fixes and javadoc * Added list to DropTargetRpc to preserve order of data * Remove event listeners on unregister * Changed method names set/getData() to more descriptive set/getTransferData() * Add server side dragStart event (#8171) * Add style to prevent text selection to allow drag * Remove target indicator style on drop * Add client side dragend event listener for drag source * Add server side dragend listener. Attach client side listener only when server side listener added. * Add drag source information to server side dragstart and dragend events. * Fixed some issues addressed in review * Trigger server side dragstart only when there is a listener attached * Criteria script can be set as null to clear * Use Js Interop instead of JSNI for handling event listeners * Use elemental package instead of Js Interop for handling event listeners * Add missing javadoc for public methods * Add default value "uninitialized" to effectAllowed parameter * Simple test UI for HTML5 DnD functionality (#8395) * Add javadoc and other minor changestags/8.1.0.alpha1
/* | |||||
* 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.extensions; | |||||
import java.util.List; | |||||
import java.util.Map; | |||||
import com.google.gwt.dom.client.DataTransfer; | |||||
import com.google.gwt.dom.client.Element; | |||||
import com.google.gwt.dom.client.NativeEvent; | |||||
import com.vaadin.client.ComponentConnector; | |||||
import com.vaadin.client.ServerConnector; | |||||
import com.vaadin.event.dnd.DragSourceExtension; | |||||
import com.vaadin.shared.ui.Connect; | |||||
import com.vaadin.shared.ui.dnd.DragSourceRpc; | |||||
import com.vaadin.shared.ui.dnd.DragSourceState; | |||||
import elemental.events.Event; | |||||
import elemental.events.EventListener; | |||||
import elemental.events.EventTarget; | |||||
/** | |||||
* Extension to add drag source functionality to a widget for using HTML5 drag | |||||
* and drop. Client side counterpart of {@link DragSourceExtension}. | |||||
*/ | |||||
@Connect(DragSourceExtension.class) | |||||
public class DragSourceExtensionConnector extends AbstractExtensionConnector { | |||||
private static final String CLASS_DRAGGABLE = "v-draggable"; | |||||
// Create event listeners | |||||
private final EventListener dragStartListener = this::onDragStart; | |||||
private final EventListener dragEndListener = this::onDragEnd; | |||||
@Override | |||||
protected void extend(ServerConnector target) { | |||||
Element dragSourceElement = getDraggableElement(); | |||||
dragSourceElement.setDraggable(Element.DRAGGABLE_TRUE); | |||||
dragSourceElement.addClassName(CLASS_DRAGGABLE); | |||||
EventTarget dragSource = dragSourceElement.cast(); | |||||
// dragstart | |||||
dragSource.addEventListener(Event.DRAGSTART, dragStartListener); | |||||
// dragend | |||||
dragSource.addEventListener(Event.DRAGEND, dragEndListener); | |||||
} | |||||
@Override | |||||
public void onUnregister() { | |||||
super.onUnregister(); | |||||
EventTarget dragSource = (EventTarget) getDraggableElement(); | |||||
// Remove listeners | |||||
dragSource.removeEventListener(Event.DRAGSTART, dragStartListener); | |||||
dragSource.removeEventListener(Event.DRAGEND, dragEndListener); | |||||
} | |||||
/** | |||||
* Event handler for the {@code dragstart} event. Called when {@code | |||||
* dragstart} event occurs. | |||||
* | |||||
* @param event | |||||
* browser event to be handled | |||||
*/ | |||||
protected void onDragStart(Event event) { | |||||
// Convert elemental event to have access to dataTransfer | |||||
NativeEvent nativeEvent = (NativeEvent) event; | |||||
// Set effectAllowed parameter | |||||
if (getState().effectAllowed != null) { | |||||
setEffectAllowed(nativeEvent.getDataTransfer(), | |||||
getState().effectAllowed.getValue()); | |||||
} | |||||
// Set data parameter | |||||
List<String> types = getState().types; | |||||
Map<String, String> data = getState().data; | |||||
for (String format : types) { | |||||
nativeEvent.getDataTransfer().setData(format, data.get(format)); | |||||
} | |||||
// Initiate firing server side dragstart event when there is a | |||||
// DragStartListener attached on the server side | |||||
if (hasEventListener(DragSourceState.EVENT_DRAGSTART)) { | |||||
getRpcProxy(DragSourceRpc.class).dragStart(); | |||||
} | |||||
} | |||||
/** | |||||
* Event handler for the {@code dragend} event. Called when {@code dragend} | |||||
* event occurs. | |||||
* | |||||
* @param event | |||||
*/ | |||||
protected void onDragEnd(Event event) { | |||||
// Initiate server start dragend event when there is a DragEndListener | |||||
// attached on the server side | |||||
if (hasEventListener(DragSourceState.EVENT_DRAGEND)) { | |||||
getRpcProxy(DragSourceRpc.class).dragEnd(); | |||||
} | |||||
} | |||||
/** | |||||
* Finds the draggable element within the widget. By default, returns the | |||||
* topmost element. | |||||
* | |||||
* @return the draggable element in the parent widget. | |||||
*/ | |||||
protected Element getDraggableElement() { | |||||
return ((ComponentConnector) getParent()).getWidget().getElement(); | |||||
} | |||||
private native void setEffectAllowed(DataTransfer dataTransfer, | |||||
String effectAllowed)/*-{ | |||||
dataTransfer.effectAllowed = effectAllowed; | |||||
}-*/; | |||||
@Override | |||||
public DragSourceState getState() { | |||||
return (DragSourceState) super.getState(); | |||||
} | |||||
} |
/* | |||||
* 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.extensions; | |||||
import java.util.ArrayList; | |||||
import java.util.HashMap; | |||||
import java.util.List; | |||||
import java.util.Map; | |||||
import com.google.gwt.core.client.JsArrayString; | |||||
import com.google.gwt.dom.client.BrowserEvents; | |||||
import com.google.gwt.dom.client.DataTransfer; | |||||
import com.google.gwt.dom.client.Element; | |||||
import com.google.gwt.dom.client.NativeEvent; | |||||
import com.vaadin.client.ComponentConnector; | |||||
import com.vaadin.client.ServerConnector; | |||||
import com.vaadin.event.dnd.DropTargetExtension; | |||||
import com.vaadin.shared.ui.Connect; | |||||
import com.vaadin.shared.ui.dnd.DropTargetRpc; | |||||
import com.vaadin.shared.ui.dnd.DropTargetState; | |||||
import elemental.events.Event; | |||||
import elemental.events.EventListener; | |||||
import elemental.events.EventTarget; | |||||
/** | |||||
* Extension to add drop target functionality to a widget for using HTML5 drag | |||||
* and drop. Client side counterpart of {@link DropTargetExtension}. | |||||
*/ | |||||
@Connect(DropTargetExtension.class) | |||||
public class DropTargetExtensionConnector extends AbstractExtensionConnector { | |||||
private static final String CLASS_DRAG_OVER = "v-drag-over"; | |||||
// Create event listeners | |||||
private final EventListener dragEnterListener = this::onDragEnter; | |||||
private final EventListener dragOverListener = this::onDragOver; | |||||
private final EventListener dragLeaveListener = this::onDragLeave; | |||||
private final EventListener dropListener = this::onDrop; | |||||
@Override | |||||
protected void extend(ServerConnector target) { | |||||
EventTarget dropTarget = getDropTargetElement().cast(); | |||||
// dragenter event | |||||
dropTarget.addEventListener(BrowserEvents.DRAGENTER, dragEnterListener); | |||||
// dragover event | |||||
dropTarget.addEventListener(BrowserEvents.DRAGOVER, dragOverListener); | |||||
// dragleave event | |||||
dropTarget.addEventListener(BrowserEvents.DRAGLEAVE, dragLeaveListener); | |||||
// drop event | |||||
dropTarget.addEventListener(BrowserEvents.DROP, dropListener); | |||||
} | |||||
@Override | |||||
public void onUnregister() { | |||||
super.onUnregister(); | |||||
EventTarget dropTarget = getDropTargetElement().cast(); | |||||
// Remove listeners | |||||
dropTarget.removeEventListener(BrowserEvents.DRAGENTER, | |||||
dragEnterListener); | |||||
dropTarget.removeEventListener(BrowserEvents.DRAGOVER, | |||||
dragOverListener); | |||||
dropTarget.removeEventListener(BrowserEvents.DRAGLEAVE, | |||||
dragLeaveListener); | |||||
dropTarget.removeEventListener(BrowserEvents.DROP, dropListener); | |||||
} | |||||
/** | |||||
* Finds the drop target element within the widget. By default, returns the | |||||
* topmost element. | |||||
* | |||||
* @return the drop target element in the parent widget. | |||||
*/ | |||||
protected Element getDropTargetElement() { | |||||
return ((ComponentConnector) getParent()).getWidget().getElement(); | |||||
} | |||||
/** | |||||
* Event handler for the {@code dragenter} event. | |||||
* | |||||
* @param event | |||||
* browser event to be handled | |||||
*/ | |||||
protected void onDragEnter(Event event) { | |||||
addTargetIndicator(getDropTargetElement()); | |||||
} | |||||
/** | |||||
* Event handler for the {@code dragover} event. | |||||
* | |||||
* @param event | |||||
* browser event to be handled | |||||
*/ | |||||
protected void onDragOver(Event event) { | |||||
NativeEvent nativeEvent = (NativeEvent) event; | |||||
if (isDragOverAllowed(nativeEvent)) { | |||||
// Set dropEffect parameter | |||||
if (getState().dropEffect != null) { | |||||
nativeEvent.getDataTransfer().setDropEffect( | |||||
DataTransfer.DropEffect | |||||
.valueOf(getState().dropEffect.name())); | |||||
} | |||||
// Prevent default to allow drop | |||||
nativeEvent.preventDefault(); | |||||
nativeEvent.stopPropagation(); | |||||
} else { | |||||
// Remove drop effect | |||||
nativeEvent.getDataTransfer() | |||||
.setDropEffect(DataTransfer.DropEffect.NONE); | |||||
// Remove drop target indicator | |||||
removeTargetIndicator(getDropTargetElement()); | |||||
} | |||||
} | |||||
/** | |||||
* Determines if dragover event is allowed on this drop target according to | |||||
* the dragover criteria. | |||||
* | |||||
* @param event | |||||
* Native dragover event. | |||||
* @return {@code true} if dragover is allowed, {@code false} otherwise. | |||||
* @see DropTargetExtension#setDragOverCriteria(String) | |||||
*/ | |||||
protected boolean isDragOverAllowed(NativeEvent event) { | |||||
if (getState().dragOverCriteria != null) { | |||||
return executeScript(event, getState().dragOverCriteria); | |||||
} | |||||
// Allow when criteria not set | |||||
return true; | |||||
} | |||||
/** | |||||
* Event handler for the {@code dragleave} event. | |||||
* | |||||
* @param event | |||||
* browser event to be handled | |||||
*/ | |||||
protected void onDragLeave(Event event) { | |||||
removeTargetIndicator(getDropTargetElement()); | |||||
} | |||||
/** | |||||
* Event handler for the {@code drop} event. | |||||
* | |||||
* @param event | |||||
* browser event to be handled | |||||
*/ | |||||
protected void onDrop(Event event) { | |||||
NativeEvent nativeEvent = (NativeEvent) event; | |||||
if (dropAllowed(nativeEvent)) { | |||||
nativeEvent.preventDefault(); | |||||
nativeEvent.stopPropagation(); | |||||
// Initiate firing server side drop event | |||||
JsArrayString typesJsArray = getTypes( | |||||
nativeEvent.getDataTransfer()); | |||||
List<String> types = new ArrayList<>(); | |||||
Map<String, String> data = new HashMap<>(); | |||||
for (int i = 0; i < typesJsArray.length(); i++) { | |||||
types.add(typesJsArray.get(i)); | |||||
data.put(typesJsArray.get(i), nativeEvent.getDataTransfer() | |||||
.getData(typesJsArray.get(i))); | |||||
} | |||||
getRpcProxy(DropTargetRpc.class) | |||||
.drop(types, data, getState().dropEffect); | |||||
} | |||||
removeTargetIndicator(getDropTargetElement()); | |||||
} | |||||
private boolean dropAllowed(NativeEvent event) { | |||||
if (getState().dropCriteria != null) { | |||||
return executeScript(event, getState().dropCriteria); | |||||
} | |||||
// Allow when criteria not set | |||||
return true; | |||||
} | |||||
private void addTargetIndicator(Element element) { | |||||
element.addClassName(CLASS_DRAG_OVER); | |||||
} | |||||
private void removeTargetIndicator(Element element) { | |||||
element.removeClassName(CLASS_DRAG_OVER); | |||||
} | |||||
private native boolean executeScript(NativeEvent event, String script)/*-{ | |||||
return new Function('event', script)(event); | |||||
}-*/; | |||||
private native JsArrayString getTypes(DataTransfer dataTransfer)/*-{ | |||||
return dataTransfer.types; | |||||
}-*/; | |||||
@Override | |||||
public DropTargetState getState() { | |||||
return (DropTargetState) super.getState(); | |||||
} | |||||
} |
/* | |||||
* 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.event.dnd; | |||||
import java.util.LinkedHashMap; | |||||
import java.util.List; | |||||
import java.util.Map; | |||||
import com.vaadin.shared.ui.dnd.EffectAllowed; | |||||
import com.vaadin.ui.Component; | |||||
/** | |||||
* Server side dragend event. Fired when an HTML5 dragend happens. | |||||
* | |||||
* @see DragSourceExtension#addDragEndListener(DragEndListener) | |||||
*/ | |||||
public class DragEndEvent extends Component.Event { | |||||
private final Map<String, String> data; | |||||
private final EffectAllowed effectAllowed; | |||||
/** | |||||
* Creates a new server side dragend event. | |||||
* | |||||
* @param source | |||||
* Draggable component. | |||||
* @param types | |||||
* List of data types from {@code DataTransfer.types}. | |||||
* @param data | |||||
* Map of all data from {@code DataTransfer}. | |||||
* @param effectAllowed | |||||
* Parameter from {@code DataTransfer.effectAllowed}. | |||||
*/ | |||||
public DragEndEvent(Component source, List<String> types, | |||||
Map<String, String> data, EffectAllowed effectAllowed) { | |||||
super(source); | |||||
// 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.effectAllowed = effectAllowed; | |||||
} | |||||
/** | |||||
* Get data from the client side {@code DataTransfer} object. | |||||
* | |||||
* @param format | |||||
* Data format, e.g. {@code text/plain} or {@code text/uri-list}. | |||||
* @return Data for the given format if exists in the client side {@code | |||||
* DataTransfer}, otherwise {@code null}. | |||||
*/ | |||||
public String getTransferData(String format) { | |||||
return data != null ? data.get(format) : null; | |||||
} | |||||
/** | |||||
* Returns the {@code effectAllowed} parameter of this event. | |||||
* | |||||
* @return This event's {@code effectAllowed} parameter. | |||||
*/ | |||||
public EffectAllowed getEffectAllowed() { | |||||
return effectAllowed; | |||||
} | |||||
} |
/* | |||||
* 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.event.dnd; | |||||
import java.lang.reflect.Method; | |||||
import com.vaadin.event.ConnectorEventListener; | |||||
/** | |||||
* Interface to be implemented when creating a dragend listener on a drag | |||||
* source for HTML5 drag and drop. | |||||
* | |||||
* @see DragSourceExtension#addDragEndListener(DragEndListener) | |||||
*/ | |||||
@FunctionalInterface | |||||
public interface DragEndListener extends ConnectorEventListener { | |||||
static final Method DRAGEND_METHOD = DragEndListener.class | |||||
.getDeclaredMethods()[0]; | |||||
/** | |||||
* Called when a server side dragend event is fired. | |||||
* | |||||
* @param event | |||||
* The dragend event that is fired. | |||||
*/ | |||||
void dragEnd(DragEndEvent event); | |||||
} |
/* | |||||
* 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.event.dnd; | |||||
import java.util.Collections; | |||||
import java.util.LinkedHashMap; | |||||
import java.util.Map; | |||||
import java.util.Objects; | |||||
import com.vaadin.server.AbstractClientConnector; | |||||
import com.vaadin.server.AbstractExtension; | |||||
import com.vaadin.shared.Registration; | |||||
import com.vaadin.shared.ui.dnd.DragSourceRpc; | |||||
import com.vaadin.shared.ui.dnd.DragSourceState; | |||||
import com.vaadin.shared.ui.dnd.EffectAllowed; | |||||
import com.vaadin.ui.AbstractComponent; | |||||
/** | |||||
* Extension to add drag source functionality to a component for using HTML5 | |||||
* drag and drop. | |||||
*/ | |||||
public class DragSourceExtension extends AbstractExtension { | |||||
/** | |||||
* Constructor for {@link DragSourceExtension} | |||||
*/ | |||||
public DragSourceExtension() { | |||||
registerRpc(new DragSourceRpc() { | |||||
@Override | |||||
public void dragStart() { | |||||
DragStartEvent event = new DragStartEvent( | |||||
(AbstractComponent) getParent(), getState(false).types, | |||||
getState(false).data, getState(false).effectAllowed); | |||||
fireEvent(event); | |||||
} | |||||
@Override | |||||
public void dragEnd() { | |||||
DragEndEvent event = new DragEndEvent( | |||||
(AbstractComponent) getParent(), getState(false).types, | |||||
getState(false).data, getState(false).effectAllowed); | |||||
fireEvent(event); | |||||
} | |||||
}); | |||||
} | |||||
/** | |||||
* Makes {@code target} component a drag source. | |||||
* | |||||
* @param target | |||||
* Component to be extended. | |||||
*/ | |||||
public void extend(AbstractComponent target) { | |||||
super.extend(target); | |||||
} | |||||
/** | |||||
* Sets the allowed effects for the current drag source element. Used for | |||||
* setting client side {@code DataTransfer.effectAllowed} parameter for the | |||||
* drag event. | |||||
* <p> | |||||
* By default the value is {@link EffectAllowed#UNINITIALIZED} which is | |||||
* equivalent to {@link EffectAllowed#ALL}. | |||||
* | |||||
* @param effect | |||||
* Effects to allow for this draggable element. Cannot be {@code | |||||
* null}. | |||||
*/ | |||||
public void setEffectAllowed(EffectAllowed effect) { | |||||
if (effect == null) { | |||||
throw new IllegalArgumentException("Allowed effect cannot be null"); | |||||
} | |||||
if (!Objects.equals(getState(false).effectAllowed, effect)) { | |||||
getState().effectAllowed = effect; | |||||
} | |||||
} | |||||
/** | |||||
* Returns the allowed effects for the current drag source element. Used to | |||||
* set client side {@code DataTransfer.effectAllowed} parameter for the drag | |||||
* event. | |||||
* | |||||
* @return Effects that are allowed for this draggable element. | |||||
*/ | |||||
public EffectAllowed getEffectAllowed() { | |||||
return getState(false).effectAllowed; | |||||
} | |||||
/** | |||||
* Sets the data for this drag source element. Used to set data for client | |||||
* side drag element using {@code DataTransfer.setData()}. To be used as a | |||||
* map, key-value pairs are stored. Order of entries are preserved. | |||||
* <p> | |||||
* Note that by HTML specification, the browser will change data type | |||||
* "{@code text}" to "{@code text/plain}" and "{@code url}" to "{@code | |||||
* text/uri-list}" during client side drag event. | |||||
* | |||||
* @param format | |||||
* Data type to store, e.g. {@code text/plain} or {@code | |||||
* text/uri-list}. Cannot be {@code null}. | |||||
* @param data | |||||
* Data to store for the data type. Cannot be {@code null}. | |||||
*/ | |||||
public void setTransferData(String format, String data) { | |||||
if (format == null) { | |||||
throw new IllegalArgumentException("Data type cannot be null"); | |||||
} | |||||
if (data == null) { | |||||
throw new IllegalArgumentException("Data cannot be null"); | |||||
} | |||||
if (!getState(false).types.contains(format)) { | |||||
getState().types.add(format); | |||||
} | |||||
getState().data.put(format, data); | |||||
} | |||||
/** | |||||
* Returns the data stored for {@code format} type in this drag source | |||||
* element. | |||||
* | |||||
* @param format | |||||
* Data type of the requested data, e.g. {@code text/plain} or | |||||
* {@code text/uri-list}. | |||||
* @return Data that is stored for {@code format} data type. | |||||
*/ | |||||
public String getTransferData(String format) { | |||||
return getState(false).data.get(format); | |||||
} | |||||
/** | |||||
* 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> getTransferData() { | |||||
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); | |||||
} | |||||
/** | |||||
* Clears data with the given type for this drag source element when | |||||
* present. | |||||
* | |||||
* @param format | |||||
* Type of data to be cleared. Cannot be {@code null}. | |||||
*/ | |||||
public void clearTransferData(String format) { | |||||
if (format == null) { | |||||
throw new IllegalArgumentException("Data type cannot be null"); | |||||
} | |||||
getState().types.remove(format); | |||||
getState().data.remove(format); | |||||
} | |||||
/** | |||||
* Clears all data for this drag source element. | |||||
*/ | |||||
public void clearTransferData() { | |||||
getState().types.clear(); | |||||
getState().data.clear(); | |||||
} | |||||
/** | |||||
* Attaches dragstart listener for the current drag source. {@link | |||||
* DragStartListener#dragStart(DragStartEvent)} is called when dragstart | |||||
* event happens on the client side. | |||||
* | |||||
* @param listener | |||||
* Listener to handle dragstart event. | |||||
* @return Handle to be used to remove this listener. | |||||
*/ | |||||
public Registration addDragStartListener(DragStartListener listener) { | |||||
return addListener(DragSourceState.EVENT_DRAGSTART, | |||||
DragStartEvent.class, listener, | |||||
DragStartListener.DRAGSTART_METHOD); | |||||
} | |||||
/** | |||||
* Attaches dragend listener for the current drag source. {@link | |||||
* DragEndListener#dragEnd(DragEndEvent)} is called when dragend | |||||
* event happens on the client side. | |||||
* | |||||
* @param listener | |||||
* Listener to handle dragend event. | |||||
* @return Handle to be used to remove this listener. | |||||
*/ | |||||
public Registration addDragEndListener(DragEndListener listener) { | |||||
return addListener(DragSourceState.EVENT_DRAGEND, DragEndEvent.class, | |||||
listener, DragEndListener.DRAGEND_METHOD); | |||||
} | |||||
@Override | |||||
protected DragSourceState getState() { | |||||
return (DragSourceState) super.getState(); | |||||
} | |||||
@Override | |||||
protected DragSourceState getState(boolean markAsDirty) { | |||||
return (DragSourceState) super.getState(markAsDirty); | |||||
} | |||||
} |
/* | |||||
* 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.event.dnd; | |||||
import java.util.LinkedHashMap; | |||||
import java.util.List; | |||||
import java.util.Map; | |||||
import com.vaadin.shared.ui.dnd.EffectAllowed; | |||||
import com.vaadin.ui.Component; | |||||
/** | |||||
* Server side dragstart event. Fired when an HTML5 dragstart happens. | |||||
* | |||||
* @see DragSourceExtension#addDragStartListener(DragStartListener) | |||||
*/ | |||||
public class DragStartEvent extends Component.Event { | |||||
private final Map<String, String> data; | |||||
private final EffectAllowed effectAllowed; | |||||
/** | |||||
* Creates a new server side dragend event. | |||||
* | |||||
* @param source | |||||
* Draggable component. | |||||
* @param types | |||||
* List of data types from {@code DataTransfer.types}. | |||||
* @param data | |||||
* Map of all data from {@code DataTransfer}. | |||||
* @param effectAllowed | |||||
* Parameter from {@code DataTransfer.effectAllowed}. | |||||
*/ | |||||
public DragStartEvent(Component source, List<String> types, | |||||
Map<String, String> data, EffectAllowed effectAllowed) { | |||||
super(source); | |||||
// 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.effectAllowed = effectAllowed; | |||||
} | |||||
/** | |||||
* Get data from the client side {@code DataTransfer} object. | |||||
* | |||||
* @param format | |||||
* Data format, e.g. {@code text/plain} or {@code text/uri-list}. | |||||
* @return Data for the given format if exists in the client side {@code | |||||
* DataTransfer}, otherwise {@code null}. | |||||
*/ | |||||
public String getTransferData(String format) { | |||||
return data != null ? data.get(format) : null; | |||||
} | |||||
/** | |||||
* Returns the {@code effectAllowed} parameter of this event. | |||||
* | |||||
* @return This event's {@code effectAllowed} parameter. | |||||
*/ | |||||
public EffectAllowed getEffectAllowed() { | |||||
return effectAllowed; | |||||
} | |||||
} |
/* | |||||
* 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.event.dnd; | |||||
import java.lang.reflect.Method; | |||||
import com.vaadin.event.ConnectorEventListener; | |||||
/** | |||||
* Interface to be implemented when creating a dragstart listener on a drag | |||||
* source for HTML5 drag and drop. | |||||
* | |||||
* @see DragSourceExtension#addDragStartListener(DragStartListener) | |||||
*/ | |||||
@FunctionalInterface | |||||
public interface DragStartListener extends ConnectorEventListener { | |||||
static final Method DRAGSTART_METHOD = DragStartListener.class | |||||
.getDeclaredMethods()[0]; | |||||
/** | |||||
* Called when a server side dragstart event is fired. | |||||
* | |||||
* @param event | |||||
* The dragstart event that is fired. | |||||
*/ | |||||
void dragStart(DragStartEvent event); | |||||
} |
/* | |||||
* 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.event.dnd; | |||||
import java.util.LinkedHashMap; | |||||
import java.util.List; | |||||
import java.util.Map; | |||||
import com.vaadin.shared.ui.dnd.DropEffect; | |||||
import com.vaadin.ui.Component; | |||||
/** | |||||
* Server side drop event. Fired when an HTML5 drop happens. | |||||
* | |||||
* @see DropTargetExtension#addDropListener(DropListener) | |||||
*/ | |||||
public class DropEvent extends Component.Event { | |||||
private final Map<String, String> data; | |||||
private final DropEffect dropEffect; | |||||
/** | |||||
* Creates a new server side drop event. | |||||
* | |||||
* @param source | |||||
* Drop target component. | |||||
* @param types | |||||
* List of data types from {@code DataTransfer.types}. | |||||
* @param data | |||||
* Map of all data from {@code DataTransfer}. | |||||
* @param dropEffect | |||||
* Parameter from {@code DataTransfer.dropEffect}. | |||||
*/ | |||||
public DropEvent(Component source, List<String> types, | |||||
Map<String, String> data, DropEffect dropEffect) { | |||||
super(source); | |||||
// 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; | |||||
} | |||||
/** | |||||
* Get data from the client side {@code DataTransfer} object. | |||||
* | |||||
* @param format | |||||
* Data format, e.g. {@code text/plain} or {@code text/uri-list}. | |||||
* @return Data for the given format if exists in the client side {@code | |||||
* DataTransfer}, otherwise {@code null}. | |||||
*/ | |||||
public String getTransferData(String format) { | |||||
return data != null ? data.get(format) : null; | |||||
} | |||||
/** | |||||
* Get drop effect set for the current drop target. | |||||
* | |||||
* @return {@code dropEffect} parameter set for the current drop target. | |||||
*/ | |||||
public DropEffect getDropEffect() { | |||||
return dropEffect; | |||||
} | |||||
} |
/* | |||||
* 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.event.dnd; | |||||
import java.lang.reflect.Method; | |||||
import com.vaadin.event.ConnectorEventListener; | |||||
/** | |||||
* Interface to be implemented when creating a drop listener on a drop target | |||||
* for HTML5 drag and drop. See {@link DropTargetExtension#addDropListener(DropListener)}. | |||||
*/ | |||||
@FunctionalInterface | |||||
public interface DropListener extends ConnectorEventListener { | |||||
static final Method DROP_METHOD = DropListener.class | |||||
.getDeclaredMethods()[0]; | |||||
/** | |||||
* Called when a server side drop event is fired. | |||||
* | |||||
* @param event | |||||
* The drop event that is fired. | |||||
*/ | |||||
void drop(DropEvent event); | |||||
} |
/* | |||||
* 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.event.dnd; | |||||
import java.util.Objects; | |||||
import com.vaadin.server.AbstractClientConnector; | |||||
import com.vaadin.server.AbstractExtension; | |||||
import com.vaadin.shared.Registration; | |||||
import com.vaadin.shared.ui.dnd.DropEffect; | |||||
import com.vaadin.shared.ui.dnd.DropTargetRpc; | |||||
import com.vaadin.shared.ui.dnd.DropTargetState; | |||||
import com.vaadin.ui.AbstractComponent; | |||||
/** | |||||
* Extension to add drop target functionality to a widget for using HTML5 drag | |||||
* and drop. | |||||
*/ | |||||
public class DropTargetExtension extends AbstractExtension { | |||||
/** | |||||
* Constructor for {@link DropTargetExtension}. | |||||
*/ | |||||
public DropTargetExtension() { | |||||
registerRpc((DropTargetRpc) (types, data, dropEffect) -> { | |||||
DropEvent event = new DropEvent((AbstractComponent) getParent(), | |||||
types, data, dropEffect); | |||||
fireEvent(event); | |||||
}); | |||||
} | |||||
/** | |||||
* Makes {@code target} component a drop target. | |||||
* | |||||
* @param target | |||||
* Component to be extended. | |||||
*/ | |||||
public void extend(AbstractComponent target) { | |||||
super.extend(target); | |||||
} | |||||
/** | |||||
* Sets the drop effect for the current drop target. Used for the client | |||||
* side {@code DataTransfer.dropEffect} parameter. | |||||
* <p> | |||||
* Default value is browser dependent and can depend on e.g. modifier keys. | |||||
* | |||||
* @param dropEffect | |||||
* The drop effect to be set. Cannot be {@code null}. | |||||
*/ | |||||
public void setDropEffect(DropEffect dropEffect) { | |||||
if (dropEffect == null) { | |||||
throw new IllegalArgumentException("Drop effect cannot be null."); | |||||
} | |||||
if (!Objects.equals(getState(false).dropEffect, dropEffect)) { | |||||
getState().dropEffect = dropEffect; | |||||
} | |||||
} | |||||
/** | |||||
* Returns the drop effect for the current drop target. | |||||
* | |||||
* @return The drop effect of this drop target. | |||||
*/ | |||||
public DropEffect getDropEffect() { | |||||
return getState(false).dropEffect; | |||||
} | |||||
/** | |||||
* Sets criteria to allow dragover event on the current drop target. The | |||||
* script executes when dragover event happens and stops the event in case | |||||
* the script returns {@code false}. | |||||
* | |||||
* @param criteriaScript | |||||
* JavaScript to be executed when dragover event happens or {@code | |||||
* null} to clear. | |||||
*/ | |||||
public void setDragOverCriteria(String criteriaScript) { | |||||
if (!Objects.equals(getState(false).dragOverCriteria, criteriaScript)) { | |||||
getState().dragOverCriteria = criteriaScript; | |||||
} | |||||
} | |||||
/** | |||||
* Sets criteria to allow drop event on the current drop target. The script | |||||
* executes when drop event happens and stops the event in case the script | |||||
* returns {@code false}. | |||||
* | |||||
* @param criteriaScript | |||||
* JavaScript to be executed when drop event happens or {@code null} | |||||
* to clear. | |||||
*/ | |||||
public void setDropCriteria(String criteriaScript) { | |||||
if (!Objects.equals(getState(false).dropCriteria, criteriaScript)) { | |||||
getState().dropCriteria = criteriaScript; | |||||
} | |||||
} | |||||
/** | |||||
* Returns the criteria for allowing drop event on the current drop target. | |||||
* | |||||
* @return JavaScript that executes when drop event happens. | |||||
*/ | |||||
public String getDropCriteria() { | |||||
return getState(false).dropCriteria; | |||||
} | |||||
/** | |||||
* Attaches drop listener for the current drop target. {@link | |||||
* DropListener#drop(DropEvent)} 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 addDropListener(DropListener listener) { | |||||
return addListener(DropEvent.class, listener, DropListener.DROP_METHOD); | |||||
} | |||||
@Override | |||||
protected DropTargetState getState() { | |||||
return (DropTargetState) super.getState(); | |||||
} | |||||
@Override | |||||
protected DropTargetState getState(boolean markAsDirty) { | |||||
return (DropTargetState) super.getState(markAsDirty); | |||||
} | |||||
} |
/* | |||||
* 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.dnd; | |||||
import com.vaadin.shared.communication.ServerRpc; | |||||
/** | |||||
* RPC for firing server side event when client side dragstart event happens on | |||||
* drag source. | |||||
*/ | |||||
public interface DragSourceRpc extends ServerRpc { | |||||
/** | |||||
* Called when dragsource event happens on client side. | |||||
*/ | |||||
public void dragStart(); | |||||
/** | |||||
* Called when dragend event happens on client side. | |||||
*/ | |||||
public void dragEnd(); | |||||
} |
/* | |||||
* 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.dnd; | |||||
import java.util.ArrayList; | |||||
import java.util.HashMap; | |||||
import java.util.List; | |||||
import java.util.Map; | |||||
import com.vaadin.shared.communication.SharedState; | |||||
/** | |||||
* State class containing parameters for DragSourceExtension. | |||||
*/ | |||||
public class DragSourceState extends SharedState { | |||||
/** | |||||
* Event identifier for dragend event. | |||||
*/ | |||||
public static final String EVENT_DRAGEND = "dragend"; | |||||
/** | |||||
* Event identifier for dragstart event. | |||||
*/ | |||||
public static final String EVENT_DRAGSTART = "dragstart"; | |||||
/** | |||||
* {@code DataTransfer.effectAllowed} parameter for the drag event. | |||||
*/ | |||||
public EffectAllowed effectAllowed = EffectAllowed.UNINITIALIZED; | |||||
/** | |||||
* {@code DataTransfer.types} parameter. Used to keep track of data formats | |||||
* set for the drag event. | |||||
*/ | |||||
public List<String> types = new ArrayList<>(); | |||||
/** | |||||
* Used to store data in the {@code DataTransfer} object for the drag event. | |||||
*/ | |||||
public Map<String, String> data = new HashMap<>(); | |||||
} |
/* | |||||
* 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.dnd; | |||||
/** | |||||
* Used to specify the drop effect to use on dragenter or dragover events. | |||||
*/ | |||||
public enum DropEffect { | |||||
/** | |||||
* A copy of the source item is made at the new location. | |||||
*/ | |||||
COPY, | |||||
/** | |||||
* An item is moved to a new location. | |||||
*/ | |||||
MOVE, | |||||
/** | |||||
* A link is established to the source at the new location. | |||||
*/ | |||||
LINK, | |||||
/** | |||||
* The item may not be dropped. | |||||
*/ | |||||
NONE | |||||
} |
/* | |||||
* 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.dnd; | |||||
import java.util.List; | |||||
import java.util.Map; | |||||
import com.vaadin.shared.communication.ServerRpc; | |||||
/** | |||||
* RPC for firing server side drop event when client side drop event happens on | |||||
* drop target. | |||||
*/ | |||||
public interface DropTargetRpc extends ServerRpc { | |||||
/** | |||||
* Called when drop event happens on client side. | |||||
* | |||||
* @param types | |||||
* Data types that are present in {@code data} map in the same order | |||||
* as found in {@code DataTransfer.types}. | |||||
* @param data | |||||
* Contains data from {@code DataTransfer} object. | |||||
* @param dropEffect | |||||
* Drop effect set for the drop target where drop happened. | |||||
*/ | |||||
public void drop(List<String> types, Map<String, String> data, | |||||
DropEffect dropEffect); | |||||
} |
/* | |||||
* 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.dnd; | |||||
import com.vaadin.shared.communication.SharedState; | |||||
/** | |||||
* State class containing parameters for DropTargetExtension. | |||||
*/ | |||||
public class DropTargetState extends SharedState { | |||||
/** | |||||
* {@code DataTransfer.dropEffect} parameter for the drag event | |||||
*/ | |||||
public DropEffect dropEffect; | |||||
/** | |||||
* Criteria script to allow dragOver event on the element | |||||
*/ | |||||
public String dragOverCriteria; | |||||
/** | |||||
* Criteria script to allow drop event on the element | |||||
*/ | |||||
public String dropCriteria; | |||||
} |
/* | |||||
* 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.dnd; | |||||
/** | |||||
* Used to specify the effect that is allowed for a drag operation. | |||||
*/ | |||||
public enum EffectAllowed { | |||||
/** | |||||
* The item may not be dropped. | |||||
*/ | |||||
NONE("none"), | |||||
/** | |||||
* A copy of the source item may be made at the new location. | |||||
*/ | |||||
COPY("copy"), | |||||
/** | |||||
* An item may be moved to a new location. | |||||
*/ | |||||
MOVE("move"), | |||||
/** | |||||
* A link may be established to the source at the new location. | |||||
*/ | |||||
LINK("link"), | |||||
/** | |||||
* A copy or move operation is permitted. | |||||
*/ | |||||
COPY_MOVE("copyMove"), | |||||
/** | |||||
* A copy or link operation is permitted. | |||||
*/ | |||||
COPY_LINK("copyLink"), | |||||
/** | |||||
* A link or move operation is permitted. | |||||
*/ | |||||
LINK_MOVE("linkMove"), | |||||
/** | |||||
* All operations are permitted. | |||||
*/ | |||||
ALL("all"), | |||||
/** | |||||
* Default state, equivalent to ALL | |||||
*/ | |||||
UNINITIALIZED("uninitialized"); | |||||
private final String value; | |||||
EffectAllowed(String value) { | |||||
this.value = value; | |||||
} | |||||
/** | |||||
* Get the string value that is accepted by the client side drag event. | |||||
* | |||||
* @return String value accepted by the client side drag event. | |||||
*/ | |||||
public String getValue() { | |||||
return value; | |||||
} | |||||
} |
@include valo-drag-element; | @include valo-drag-element; | ||||
@include valo-draggable; | |||||
@include valo-tooltip; | @include valo-tooltip; | ||||
@include valo-contextmenu; | @include valo-contextmenu; |
} | } | ||||
} | } | ||||
@mixin valo-draggable { | |||||
.v-draggable { | |||||
user-select: none !important; | |||||
} | |||||
} | |||||
/** | /** | ||||
* Outputs the styles for generic dragging ghost elements. | * Outputs the styles for generic dragging ghost elements. | ||||
* | * |
/* | |||||
* 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.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.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"); | |||||
private final Label queen = new Label("Q"); | |||||
private final Label king = new Label("K"); | |||||
// Create desk | |||||
private final HorizontalLayout desk = new HorizontalLayout(); | |||||
@Override | |||||
protected void setup(VaadinRequest request) { | |||||
// Create UI and add extensions | |||||
desk.addComponents(ace, jack, queen, king); | |||||
ace.setStyleName("card"); | |||||
addDragSourceExtension(ace); | |||||
addDropTargetExtension(ace); | |||||
jack.setStyleName("card"); | |||||
addDragSourceExtension(jack); | |||||
addDropTargetExtension(jack); | |||||
queen.setStyleName("card"); | |||||
addDragSourceExtension(queen); | |||||
addDropTargetExtension(queen); | |||||
king.setStyleName("card"); | |||||
addDragSourceExtension(king); | |||||
addDropTargetExtension(king); | |||||
addComponent(desk); | |||||
// Add styling | |||||
setStyle(); | |||||
} | |||||
private void addDragSourceExtension(Label source) { | |||||
// Create and attach extension | |||||
DragSourceExtension dragSource = new DragSourceExtension(); | |||||
dragSource.extend(source); | |||||
// Set component position as transfer data | |||||
dragSource.setTransferData(DATA_INDEX, | |||||
String.valueOf(desk.getComponentIndex(source))); | |||||
// Add listeners | |||||
dragSource.addDragStartListener(event -> { | |||||
event.getComponent().addStyleName("dragged"); | |||||
log(((Label) event.getComponent()).getValue() + " dragstart"); | |||||
}); | |||||
dragSource.addDragEndListener(event -> { | |||||
event.getComponent().removeStyleName("dragged"); | |||||
log(((Label) event.getComponent()).getValue() + " dragend"); | |||||
}); | |||||
} | |||||
private void addDropTargetExtension(Label target) { | |||||
// Create and attach extension | |||||
DropTargetExtension dropTarget = new DropTargetExtension(); | |||||
dropTarget.extend(target); | |||||
// Add listener | |||||
dropTarget.addDropListener(event -> { | |||||
// Retrieve the source's position | |||||
int sourceIndex = Integer | |||||
.valueOf(event.getTransferData(DATA_INDEX)); | |||||
// Find source component | |||||
Component source = desk.getComponent(sourceIndex); | |||||
// Swap source and target components | |||||
desk.replaceComponent(target, source); | |||||
// Get DragSource extension for target component and set position data | |||||
Optional<Extension> targetExt = target.getExtensions().stream() | |||||
.filter(e -> e instanceof DragSourceExtension).findFirst(); | |||||
targetExt.ifPresent(extension -> { | |||||
((DragSourceExtension) extension).setTransferData(DATA_INDEX, | |||||
String.valueOf(desk.getComponentIndex(target))); | |||||
}); | |||||
// Get DragSource extension for source component and set position data | |||||
Optional<Extension> sourceExt = source.getExtensions().stream() | |||||
.filter(e -> e instanceof DragSourceExtension).findFirst(); | |||||
sourceExt.ifPresent(extension -> { | |||||
((DragSourceExtension) extension).setTransferData(DATA_INDEX, | |||||
String.valueOf(desk.getComponentIndex(source))); | |||||
}); | |||||
log(((Label) source).getValue() + " dropped onto " + ((Label) event | |||||
.getComponent()).getValue()); | |||||
}); | |||||
} | |||||
private void setStyle() { | |||||
Page.Styles styles = Page.getCurrent().getStyles(); | |||||
styles.add(".card {" | |||||
+ "width: 150px;" | |||||
+ "height: 200px;" | |||||
+ "border: 1px solid black;" | |||||
+ "border-radius: 7px;" | |||||
+ "padding-left: 10px;" | |||||
+ "color: red;" | |||||
+ "font-weight: bolder;" | |||||
+ "font-size: 25px;" | |||||
+ "background-color: gainsboro;" | |||||
+ "}"); | |||||
styles.add(".v-drag-over {border-style: dashed;}"); | |||||
styles.add(".dragged {opacity: .4;}"); | |||||
} | |||||
@Override | |||||
protected String getTestDescription() { | |||||
return "Shuffle cards with pure HTML5 drag and drop"; | |||||
} | |||||
} |