You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

DragSourceExtension.java 7.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  1. /*
  2. * Copyright 2000-2016 Vaadin Ltd.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License"); you may not
  5. * use this file except in compliance with the License. You may obtain a copy of
  6. * the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  12. * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
  13. * License for the specific language governing permissions and limitations under
  14. * the License.
  15. */
  16. package com.vaadin.event.dnd;
  17. import java.util.Objects;
  18. import com.vaadin.server.AbstractExtension;
  19. import com.vaadin.shared.Registration;
  20. import com.vaadin.shared.ui.dnd.DragSourceRpc;
  21. import com.vaadin.shared.ui.dnd.DragSourceState;
  22. import com.vaadin.shared.ui.dnd.EffectAllowed;
  23. import com.vaadin.ui.AbstractComponent;
  24. /**
  25. * Extension to make a component drag source for HTML5 drag and drop
  26. * functionality.
  27. *
  28. * @param <T>
  29. * Type of the component to be extended.
  30. * @author Vaadin Ltd
  31. * @since 8.1
  32. */
  33. public class DragSourceExtension<T extends AbstractComponent> extends
  34. AbstractExtension {
  35. private Registration dragStartListenerHandle;
  36. private Registration dragEndListenerHandle;
  37. /**
  38. * Stores the server side drag data that is available for the drop target if
  39. * it is in the same UI.
  40. */
  41. private Object dragData;
  42. /**
  43. * Extends {@code target} component and makes it a drag source.
  44. *
  45. * @param target
  46. * Component to be extended.
  47. */
  48. public DragSourceExtension(T target) {
  49. registerRpc(new DragSourceRpc() {
  50. @Override
  51. public void dragStart() {
  52. DragStartEvent<T> event = new DragStartEvent<>(target,
  53. getState(false).dataTransferText,
  54. getState(false).effectAllowed);
  55. fireEvent(event);
  56. }
  57. @Override
  58. public void dragEnd() {
  59. DragEndEvent<T> event = new DragEndEvent<>(target,
  60. getState(false).dataTransferText,
  61. getState(false).effectAllowed);
  62. fireEvent(event);
  63. }
  64. });
  65. super.extend(target);
  66. // Set current extension as active drag source in the UI
  67. dragStartListenerHandle = addDragStartListener(
  68. event -> getUI().setActiveDragSource(this));
  69. // Remove current extension as active drag source from the UI
  70. dragEndListenerHandle = addDragEndListener(
  71. event -> getUI().setActiveDragSource(null));
  72. }
  73. @Override
  74. public void remove() {
  75. super.remove();
  76. // Remove listeners attached on construction
  77. dragStartListenerHandle.remove();
  78. dragEndListenerHandle.remove();
  79. }
  80. /**
  81. * Sets the allowed effects for the current drag source element. Used for
  82. * setting client side {@code DataTransfer.effectAllowed} parameter for the
  83. * drag event.
  84. * <p>
  85. * By default the value is {@link EffectAllowed#UNINITIALIZED} which is
  86. * equivalent to {@link EffectAllowed#ALL}.
  87. *
  88. * @param effect
  89. * Effects to allow for this draggable element. Cannot be {@code
  90. * null}.
  91. */
  92. public void setEffectAllowed(EffectAllowed effect) {
  93. if (effect == null) {
  94. throw new IllegalArgumentException("Allowed effect cannot be null");
  95. }
  96. if (!Objects.equals(getState(false).effectAllowed, effect)) {
  97. getState().effectAllowed = effect;
  98. }
  99. }
  100. /**
  101. * Returns the allowed effects for the current drag source element. Used to
  102. * set client side {@code DataTransfer.effectAllowed} parameter for the drag
  103. * event.
  104. *
  105. * @return Effects that are allowed for this draggable element.
  106. */
  107. public EffectAllowed getEffectAllowed() {
  108. return getState(false).effectAllowed;
  109. }
  110. /**
  111. * Sets data for this drag source element. The data is set for the client
  112. * side draggable element using the {@code DataTransfer.setData("text",
  113. * data)} method.
  114. *
  115. * @param data
  116. * Data to be set for the client side draggable element.
  117. */
  118. public void setDataTransferText(String data) {
  119. getState().dataTransferText = data;
  120. }
  121. /**
  122. * Returns the data stored with type {@code "text"} in this drag source
  123. * element.
  124. *
  125. * @return Data of type {@code "text"} stored in this drag source element.
  126. */
  127. public String getDataTransferText() {
  128. return getState(false).dataTransferText;
  129. }
  130. /**
  131. * Clears data of type {@code "text"} in this drag source element.
  132. */
  133. public void clearDataTransferText() {
  134. getState().dataTransferText = null;
  135. }
  136. /**
  137. * Set server side drag data. This data is available in the drop event and
  138. * can be used to transfer data between drag source and drop target if they
  139. * are in the same UI.
  140. *
  141. * @param data
  142. * Data to transfer to drop event.
  143. */
  144. public void setDragData(Object data) {
  145. dragData = data;
  146. }
  147. /**
  148. * Get server side drag data. This data is available in the drop event and
  149. * can be used to transfer data between drag source and drop target if they
  150. * are in the same UI.
  151. *
  152. * @return Server side drag data if set, otherwise {@literal null}.
  153. */
  154. public Object getDragData() {
  155. return dragData;
  156. }
  157. /**
  158. * Attaches dragstart listener for the current drag source. {@link
  159. * DragStartListener#dragStart(DragStartEvent)} is called when dragstart
  160. * event happens on the client side.
  161. *
  162. * @param listener
  163. * Listener to handle dragstart event.
  164. * @return Handle to be used to remove this listener.
  165. */
  166. public Registration addDragStartListener(DragStartListener<T> listener) {
  167. return addListener(DragSourceState.EVENT_DRAGSTART,
  168. DragStartEvent.class, listener,
  169. DragStartListener.DRAGSTART_METHOD);
  170. }
  171. /**
  172. * Attaches dragend listener for the current drag source. {@link
  173. * DragEndListener#dragEnd(DragEndEvent)} is called when dragend
  174. * event happens on the client side.
  175. *
  176. * @param listener
  177. * Listener to handle dragend event.
  178. * @return Handle to be used to remove this listener.
  179. */
  180. public Registration addDragEndListener(DragEndListener<T> listener) {
  181. return addListener(DragSourceState.EVENT_DRAGEND, DragEndEvent.class,
  182. listener, DragEndListener.DRAGEND_METHOD);
  183. }
  184. @Override
  185. protected DragSourceState getState() {
  186. return (DragSourceState) super.getState();
  187. }
  188. @Override
  189. protected DragSourceState getState(boolean markAsDirty) {
  190. return (DragSourceState) super.getState(markAsDirty);
  191. }
  192. /**
  193. * Returns the component this extension is attached to.
  194. *
  195. * @return Extended component.
  196. */
  197. @Override
  198. @SuppressWarnings("unchecked")
  199. public T getParent() {
  200. return (T) super.getParent();
  201. }
  202. }