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.

VDragEvent.java 6.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. /*
  2. @ITMillApache2LicenseForJavaFiles@
  3. */
  4. package com.vaadin.terminal.gwt.client.ui.dd;
  5. import java.util.HashMap;
  6. import java.util.Map;
  7. import com.google.gwt.dom.client.Document;
  8. import com.google.gwt.dom.client.NativeEvent;
  9. import com.google.gwt.dom.client.Style.Unit;
  10. import com.google.gwt.dom.client.TableElement;
  11. import com.google.gwt.dom.client.TableSectionElement;
  12. import com.google.gwt.event.dom.client.MouseOverEvent;
  13. import com.google.gwt.user.client.Element;
  14. import com.vaadin.terminal.gwt.client.BrowserInfo;
  15. /**
  16. * DragEvent used by Vaadin client side engine. Supports components, items,
  17. * properties and custom payload (HTML5 style).
  18. *
  19. *
  20. */
  21. public class VDragEvent {
  22. private static final int DEFAULT_OFFSET = 10;
  23. private static int eventId = 0;
  24. private VTransferable transferable;
  25. private NativeEvent currentGwtEvent;
  26. private NativeEvent startEvent;
  27. private int id;
  28. private HashMap<String, Object> dropDetails = new HashMap<String, Object>();
  29. private Element elementOver;
  30. VDragEvent(VTransferable t, NativeEvent startEvent) {
  31. transferable = t;
  32. this.startEvent = startEvent;
  33. id = eventId++;
  34. }
  35. public VTransferable getTransferable() {
  36. return transferable;
  37. }
  38. /**
  39. * Returns the the latest {@link NativeEvent} that relates to this drag and
  40. * drop operation. For example on {@link VDropHandler#dragEnter(VDragEvent)}
  41. * this is commonly a {@link MouseOverEvent}.
  42. *
  43. * @return
  44. */
  45. public NativeEvent getCurrentGwtEvent() {
  46. return currentGwtEvent;
  47. }
  48. public void setCurrentGwtEvent(NativeEvent event) {
  49. currentGwtEvent = event;
  50. }
  51. int getEventId() {
  52. return id;
  53. }
  54. /**
  55. * Detecting the element on which the the event is happening may be
  56. * problematic during drag and drop operation. This is especially the case
  57. * if a drag image (often called also drag proxy) is kept under the mouse
  58. * cursor (see {@link #createDragImage(Element, boolean)}. Drag and drop
  59. * event handlers (like the one provided by {@link VDragAndDropManager} )
  60. * should set elmentOver field to reflect the the actual element on which
  61. * the pointer currently is (drag image excluded). {@link VDropHandler}s can
  62. * then more easily react properly on drag events by reading the element via
  63. * this method.
  64. *
  65. * @return the element in {@link VDropHandler} on which mouse cursor is on
  66. */
  67. public Element getElementOver() {
  68. if (elementOver != null) {
  69. return elementOver;
  70. } else if (currentGwtEvent != null) {
  71. return currentGwtEvent.getEventTarget().cast();
  72. }
  73. return null;
  74. }
  75. public void setElementOver(Element targetElement) {
  76. elementOver = targetElement;
  77. }
  78. /**
  79. * Sets the drag image used for current drag and drop operation. Drag image
  80. * is displayed next to mouse cursor during drag and drop.
  81. * <p>
  82. * The element to be used as drag image will automatically get CSS style
  83. * name "v-drag-element".
  84. *
  85. * TODO decide if this method should be here or in {@link VTransferable} (in
  86. * HTML5 it is in DataTransfer) or {@link VDragAndDropManager}
  87. *
  88. * TODO should be possible to override behavior. Like to proxy the element
  89. * to HTML5 DataTransfer
  90. *
  91. * @param node
  92. */
  93. public void setDragImage(Element node) {
  94. setDragImage(node, DEFAULT_OFFSET, DEFAULT_OFFSET);
  95. }
  96. /**
  97. * TODO consider using similar smaller (than map) api as in Transferable
  98. *
  99. * TODO clean up when drop handler changes
  100. *
  101. * @return
  102. */
  103. public Map<String, Object> getDropDetails() {
  104. return dropDetails;
  105. }
  106. /**
  107. * Sets the drag image used for current drag and drop operation. Drag image
  108. * is displayed next to mouse cursor during drag and drop.
  109. * <p>
  110. * The element to be used as drag image will automatically get CSS style
  111. * name "v-drag-element".
  112. *
  113. * @param element
  114. * the dom element to be positioned next to mouse cursor
  115. * @param offsetX
  116. * the horizontal offset of drag image from mouse cursor
  117. * @param offsetY
  118. * the vertical offset of drag image from mouse cursor
  119. */
  120. public void setDragImage(Element element, int offsetX, int offsetY) {
  121. element.getStyle().setMarginLeft(offsetX, Unit.PX);
  122. element.getStyle().setMarginTop(offsetY, Unit.PX);
  123. VDragAndDropManager.get().setDragElement(element);
  124. }
  125. /**
  126. * @return the current Element used as a drag image (aka drag proxy) or null
  127. * if drag image is not currently set for this drag operation.
  128. */
  129. public Element getDragImage() {
  130. return (Element) VDragAndDropManager.get().getDragElement();
  131. }
  132. /**
  133. * Automatically tries to create a proxy image from given element.
  134. *
  135. * @param element
  136. * @param alignImageToEvent
  137. * if true, proxy image is aligned to start event, else next to
  138. * mouse cursor
  139. */
  140. public void createDragImage(Element element, boolean alignImageToEvent) {
  141. Element cloneNode = (Element) element.cloneNode(true);
  142. if (BrowserInfo.get().isIE()) {
  143. if (cloneNode.getTagName().toLowerCase().equals("tr")) {
  144. TableElement table = Document.get().createTableElement();
  145. TableSectionElement tbody = Document.get().createTBodyElement();
  146. table.appendChild(tbody);
  147. tbody.appendChild(cloneNode);
  148. cloneNode = table.cast();
  149. }
  150. }
  151. if (alignImageToEvent) {
  152. int absoluteTop = element.getAbsoluteTop();
  153. int absoluteLeft = element.getAbsoluteLeft();
  154. int clientX = startEvent.getClientX();
  155. int clientY = startEvent.getClientY();
  156. int offsetX = absoluteLeft - clientX;
  157. int offsetY = absoluteTop - clientY;
  158. setDragImage(cloneNode, offsetX, offsetY);
  159. } else {
  160. setDragImage(cloneNode);
  161. }
  162. }
  163. }