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.

GridDropTargetExtensionConnector.java 6.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  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.client.connectors.grid;
  17. import java.util.Objects;
  18. import java.util.Optional;
  19. import com.google.gwt.dom.client.Element;
  20. import com.google.gwt.dom.client.NativeEvent;
  21. import com.google.gwt.dom.client.TableRowElement;
  22. import com.google.gwt.user.client.Window;
  23. import com.vaadin.client.ServerConnector;
  24. import com.vaadin.client.WidgetUtil;
  25. import com.vaadin.client.extensions.DropTargetExtensionConnector;
  26. import com.vaadin.client.widget.escalator.RowContainer;
  27. import com.vaadin.client.widgets.Escalator;
  28. import com.vaadin.shared.ui.Connect;
  29. import com.vaadin.shared.ui.grid.DropLocation;
  30. import com.vaadin.shared.ui.grid.DropMode;
  31. import com.vaadin.shared.ui.grid.GridDropTargetExtensionRpc;
  32. import com.vaadin.shared.ui.grid.GridDropTargetExtensionState;
  33. import com.vaadin.shared.ui.grid.GridState;
  34. import com.vaadin.ui.GridDropTargetExtension;
  35. import elemental.events.Event;
  36. import elemental.json.JsonObject;
  37. /**
  38. * Makes Grid an HTML5 drop target. This is the client side counterpart of
  39. * {@link GridDropTargetExtension}.
  40. *
  41. * @author Vaadin Ltd
  42. * @since
  43. */
  44. @Connect(GridDropTargetExtension.class)
  45. public class GridDropTargetExtensionConnector extends
  46. DropTargetExtensionConnector {
  47. // Drag over class name suffixes
  48. private final static String CLASS_SUFFIX_BEFORE = "-before";
  49. private final static String CLASS_SUFFIX_AFTER = "-after";
  50. // Drag over class names
  51. private final static String CLASS_DRAG_OVER_BEFORE =
  52. CLASS_DRAG_OVER + CLASS_SUFFIX_BEFORE;
  53. private final static String CLASS_DRAG_OVER_AFTER =
  54. CLASS_DRAG_OVER + CLASS_SUFFIX_AFTER;
  55. /**
  56. * Current drag over class name
  57. */
  58. private String dragOverClassName;
  59. private GridConnector gridConnector;
  60. @Override
  61. protected void extend(ServerConnector target) {
  62. gridConnector = (GridConnector) target;
  63. super.extend(target);
  64. }
  65. @Override
  66. protected void sendDropEventToServer(String dataTransferText,
  67. Event dropEvent) {
  68. String rowKey = null;
  69. DropLocation dropLocation = null;
  70. Optional<TableRowElement> targetRow = getTargetRow(
  71. (Element) dropEvent.getTarget());
  72. if (targetRow.isPresent()) {
  73. rowKey = getRowData(targetRow.get())
  74. .getString(GridState.JSONKEY_ROWKEY);
  75. dropLocation = getDropLocation(targetRow.get(),
  76. (NativeEvent) dropEvent);
  77. }
  78. getRpcProxy(GridDropTargetExtensionRpc.class)
  79. .drop(dataTransferText, rowKey, dropLocation);
  80. }
  81. private JsonObject getRowData(TableRowElement row) {
  82. int rowIndex = ((Escalator.AbstractRowContainer) getGridBody())
  83. .getLogicalRowIndex(row);
  84. return gridConnector.getDataSource().getRow(rowIndex);
  85. }
  86. /**
  87. * Returns the location of the event within the row.
  88. */
  89. private DropLocation getDropLocation(Element target, NativeEvent event) {
  90. if (getState().dropMode == DropMode.BETWEEN) {
  91. if (getRelativeY(target, event) < (target.getOffsetHeight() / 2)) {
  92. return DropLocation.ABOVE;
  93. } else {
  94. return DropLocation.BELOW;
  95. }
  96. }
  97. return DropLocation.ON_TOP;
  98. }
  99. private int getRelativeY(Element element, NativeEvent event) {
  100. int relativeTop = element.getAbsoluteTop() - Window.getScrollTop();
  101. return WidgetUtil.getTouchOrMouseClientY(event) - relativeTop;
  102. }
  103. @Override
  104. protected void setTargetIndicator(Event event) {
  105. getTargetRow(((Element) event.getTarget())).ifPresent(target -> {
  106. // Get required class name
  107. String className = getTargetClassName(target, (NativeEvent) event);
  108. // Add or replace class name if changed
  109. if (!target.hasClassName(className)) {
  110. if (dragOverClassName != null) {
  111. target.removeClassName(dragOverClassName);
  112. }
  113. target.addClassName(className);
  114. dragOverClassName = className;
  115. }
  116. });
  117. }
  118. private String getTargetClassName(Element target, NativeEvent event) {
  119. String classSuffix;
  120. switch (getDropLocation(target, event)) {
  121. case ABOVE:
  122. classSuffix = CLASS_SUFFIX_BEFORE;
  123. break;
  124. case BELOW:
  125. classSuffix = CLASS_SUFFIX_AFTER;
  126. break;
  127. case ON_TOP:
  128. default:
  129. classSuffix = "";
  130. break;
  131. }
  132. return CLASS_DRAG_OVER + classSuffix;
  133. }
  134. @Override
  135. protected void removeTargetIndicator(Event event) {
  136. // Remove all possible drag over class names
  137. getTargetRow((Element) event.getTarget()).ifPresent(e -> {
  138. e.removeClassName(CLASS_DRAG_OVER);
  139. e.removeClassName(CLASS_DRAG_OVER_BEFORE);
  140. e.removeClassName(CLASS_DRAG_OVER_AFTER);
  141. });
  142. }
  143. private Optional<TableRowElement> getTargetRow(Element source) {
  144. while (!Objects.equals(source, getGridBody().getElement())) {
  145. if (TableRowElement.is(source)) {
  146. return Optional.of(source.cast());
  147. }
  148. source = source.getParentElement();
  149. }
  150. return Optional.empty();
  151. }
  152. @Override
  153. protected Element getDropTargetElement() {
  154. return getGridBody().getElement();
  155. }
  156. private Escalator getEscalator() {
  157. return gridConnector.getWidget().getEscalator();
  158. }
  159. private RowContainer.BodyRowContainer getGridBody() {
  160. return getEscalator().getBody();
  161. }
  162. @Override
  163. public GridDropTargetExtensionState getState() {
  164. return (GridDropTargetExtensionState) super.getState();
  165. }
  166. }