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.5KB

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.Collections;
  18. import java.util.LinkedHashMap;
  19. import java.util.Map;
  20. import java.util.Objects;
  21. import com.vaadin.server.AbstractClientConnector;
  22. import com.vaadin.server.AbstractExtension;
  23. import com.vaadin.shared.Registration;
  24. import com.vaadin.shared.ui.dnd.DragSourceRpc;
  25. import com.vaadin.shared.ui.dnd.DragSourceState;
  26. import com.vaadin.shared.ui.dnd.EffectAllowed;
  27. import com.vaadin.ui.AbstractComponent;
  28. /**
  29. * Extension to add drag source functionality to a component for using HTML5
  30. * drag and drop.
  31. */
  32. public class DragSourceExtension extends AbstractExtension {
  33. /**
  34. * Constructor for {@link DragSourceExtension}
  35. */
  36. public DragSourceExtension() {
  37. registerRpc(new DragSourceRpc() {
  38. @Override
  39. public void dragStart() {
  40. DragStartEvent event = new DragStartEvent(
  41. (AbstractComponent) getParent(), getState(false).types,
  42. getState(false).data, getState(false).effectAllowed);
  43. fireEvent(event);
  44. }
  45. @Override
  46. public void dragEnd() {
  47. DragEndEvent event = new DragEndEvent(
  48. (AbstractComponent) getParent(), getState(false).types,
  49. getState(false).data, getState(false).effectAllowed);
  50. fireEvent(event);
  51. }
  52. });
  53. }
  54. /**
  55. * Makes {@code target} component a drag source.
  56. *
  57. * @param target
  58. * Component to be extended.
  59. */
  60. public void extend(AbstractComponent target) {
  61. super.extend(target);
  62. }
  63. /**
  64. * Sets the allowed effects for the current drag source element. Used for
  65. * setting client side {@code DataTransfer.effectAllowed} parameter for the
  66. * drag event.
  67. * <p>
  68. * By default the value is {@link EffectAllowed#UNINITIALIZED} which is
  69. * equivalent to {@link EffectAllowed#ALL}.
  70. *
  71. * @param effect
  72. * Effects to allow for this draggable element. Cannot be {@code
  73. * null}.
  74. */
  75. public void setEffectAllowed(EffectAllowed effect) {
  76. if (effect == null) {
  77. throw new IllegalArgumentException("Allowed effect cannot be null");
  78. }
  79. if (!Objects.equals(getState(false).effectAllowed, effect)) {
  80. getState().effectAllowed = effect;
  81. }
  82. }
  83. /**
  84. * Returns the allowed effects for the current drag source element. Used to
  85. * set client side {@code DataTransfer.effectAllowed} parameter for the drag
  86. * event.
  87. *
  88. * @return Effects that are allowed for this draggable element.
  89. */
  90. public EffectAllowed getEffectAllowed() {
  91. return getState(false).effectAllowed;
  92. }
  93. /**
  94. * Sets the data for this drag source element. Used to set data for client
  95. * side drag element using {@code DataTransfer.setData()}. To be used as a
  96. * map, key-value pairs are stored. Order of entries are preserved.
  97. * <p>
  98. * Note that by HTML specification, the browser will change data type
  99. * "{@code text}" to "{@code text/plain}" and "{@code url}" to "{@code
  100. * text/uri-list}" during client side drag event.
  101. *
  102. * @param format
  103. * Data type to store, e.g. {@code text/plain} or {@code
  104. * text/uri-list}. Cannot be {@code null}.
  105. * @param data
  106. * Data to store for the data type. Cannot be {@code null}.
  107. */
  108. public void setTransferData(String format, String data) {
  109. if (format == null) {
  110. throw new IllegalArgumentException("Data type cannot be null");
  111. }
  112. if (data == null) {
  113. throw new IllegalArgumentException("Data cannot be null");
  114. }
  115. if (!getState(false).types.contains(format)) {
  116. getState().types.add(format);
  117. }
  118. getState().data.put(format, data);
  119. }
  120. /**
  121. * Returns the data stored for {@code format} type in this drag source
  122. * element.
  123. *
  124. * @param format
  125. * Data type of the requested data, e.g. {@code text/plain} or
  126. * {@code text/uri-list}.
  127. * @return Data that is stored for {@code format} data type.
  128. */
  129. public String getTransferData(String format) {
  130. return getState(false).data.get(format);
  131. }
  132. /**
  133. * Returns the map of data stored in this drag source element. The returned
  134. * map preserves the order of storage and is unmodifiable.
  135. *
  136. * @return Unmodifiable copy of the map of data in the order the data was
  137. * stored.
  138. */
  139. public Map<String, String> getTransferData() {
  140. Map<String, String> data = getState(false).data;
  141. // Create a map of data that preserves the order of types
  142. LinkedHashMap<String, String> orderedData = new LinkedHashMap<>(
  143. data.size());
  144. getState(false).types
  145. .forEach(type -> orderedData.put(type, data.get(type)));
  146. return Collections.unmodifiableMap(orderedData);
  147. }
  148. /**
  149. * Clears data with the given type for this drag source element when
  150. * present.
  151. *
  152. * @param format
  153. * Type of data to be cleared. Cannot be {@code null}.
  154. */
  155. public void clearTransferData(String format) {
  156. if (format == null) {
  157. throw new IllegalArgumentException("Data type cannot be null");
  158. }
  159. getState().types.remove(format);
  160. getState().data.remove(format);
  161. }
  162. /**
  163. * Clears all data for this drag source element.
  164. */
  165. public void clearTransferData() {
  166. getState().types.clear();
  167. getState().data.clear();
  168. }
  169. /**
  170. * Attaches dragstart listener for the current drag source. {@link
  171. * DragStartListener#dragStart(DragStartEvent)} is called when dragstart
  172. * event happens on the client side.
  173. *
  174. * @param listener
  175. * Listener to handle dragstart event.
  176. * @return Handle to be used to remove this listener.
  177. */
  178. public Registration addDragStartListener(DragStartListener listener) {
  179. return addListener(DragSourceState.EVENT_DRAGSTART,
  180. DragStartEvent.class, listener,
  181. DragStartListener.DRAGSTART_METHOD);
  182. }
  183. /**
  184. * Attaches dragend listener for the current drag source. {@link
  185. * DragEndListener#dragEnd(DragEndEvent)} is called when dragend
  186. * event happens on the client side.
  187. *
  188. * @param listener
  189. * Listener to handle dragend event.
  190. * @return Handle to be used to remove this listener.
  191. */
  192. public Registration addDragEndListener(DragEndListener listener) {
  193. return addListener(DragSourceState.EVENT_DRAGEND, DragEndEvent.class,
  194. listener, DragEndListener.DRAGEND_METHOD);
  195. }
  196. @Override
  197. protected DragSourceState getState() {
  198. return (DragSourceState) super.getState();
  199. }
  200. @Override
  201. protected DragSourceState getState(boolean markAsDirty) {
  202. return (DragSourceState) super.getState(markAsDirty);
  203. }
  204. }