diff options
author | Pekka Hyvönen <pekka@vaadin.com> | 2017-05-17 14:20:26 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-05-17 14:20:26 +0300 |
commit | 19ad2a565fd32fb97023a6df30cb120decec376e (patch) | |
tree | 160b2de8a7cfabd0ebc64ed1a82f6c49839752d6 /client | |
parent | 394299cd4cd5cddb08578aa758f927d3b40e3403 (diff) | |
download | vaadin-framework-19ad2a565fd32fb97023a6df30cb120decec376e.tar.gz vaadin-framework-19ad2a565fd32fb97023a6df30cb120decec376e.zip |
Fix drag image offset for Grid rows for mobile (#9336)
Asks the polyfill to always center the drag image based on the touch coordinates.
Also temporarely removes the transform offset for the row.
Diffstat (limited to 'client')
3 files changed, 66 insertions, 31 deletions
diff --git a/client/src/main/java/com/vaadin/client/connectors/grid/GridDragSourceConnector.java b/client/src/main/java/com/vaadin/client/connectors/grid/GridDragSourceConnector.java index 5e83fef651..7f8fb429a2 100644 --- a/client/src/main/java/com/vaadin/client/connectors/grid/GridDragSourceConnector.java +++ b/client/src/main/java/com/vaadin/client/connectors/grid/GridDragSourceConnector.java @@ -26,7 +26,8 @@ import java.util.stream.Collectors; import com.google.gwt.animation.client.AnimationScheduler; import com.google.gwt.dom.client.Element; import com.google.gwt.dom.client.NativeEvent; -import com.google.gwt.dom.client.Style; +import com.google.gwt.dom.client.Style.Float; +import com.google.gwt.dom.client.Style.Unit; import com.google.gwt.dom.client.TableRowElement; import com.google.gwt.user.client.DOM; import com.google.gwt.user.client.Window; @@ -39,7 +40,6 @@ import com.vaadin.client.widget.escalator.RowContainer; import com.vaadin.client.widget.grid.selection.SelectionModel; import com.vaadin.client.widgets.Escalator; import com.vaadin.client.widgets.Grid; -import com.vaadin.server.SerializableFunction; import com.vaadin.shared.Range; import com.vaadin.shared.ui.Connect; import com.vaadin.shared.ui.dnd.DragSourceState; @@ -150,8 +150,8 @@ public class GridDragSourceConnector extends DragSourceExtensionConnector { protected void setDragImage(NativeEvent dragStartEvent) { // do not call super since need to handle specifically // 1. use resource if set (never needs safari hack) - // 2. add number badge if necessary (with safari hack if needed) - // 3. just use normal (with safari hack if needed) + // 2. add row count badge if necessary + // 3. apply hacks for safari/mobile drag image if needed // Add badge showing the number of dragged columns String imageUrl = getResourceUrl(DragSourceState.RESOURCE_DRAG_IMAGE); @@ -171,13 +171,18 @@ public class GridDragSourceConnector extends DragSourceExtensionConnector { + STYLE_SUFFIX_DRAG_BADGE); badge.setInnerHTML(draggedItemKeys.size() + ""); - badge.getStyle().setMarginLeft( - getRelativeX(draggedRowElement, dragStartEvent) + 10, - Style.Unit.PX); - badge.getStyle().setMarginTop( - getRelativeY(draggedRowElement, dragStartEvent) - - draggedRowElement.getOffsetHeight() + 10, - Style.Unit.PX); + if (BrowserInfo.get().isTouchDevice()) { + // the drag image is centered on the touch coordinates + // -> show the badge on the right edge of the row + badge.getStyle().setFloat(Float.RIGHT); + badge.getStyle().setMarginRight(20, Unit.PX); + } else { + badge.getStyle().setMarginLeft( + getRelativeX(draggedRowElement, dragStartEvent) + + 10, + Unit.PX); + } + badge.getStyle().setMarginTop(-20, Unit.PX); draggedRowElement.appendChild(badge); @@ -187,15 +192,11 @@ public class GridDragSourceConnector extends DragSourceExtensionConnector { badge.removeFromParent(); }, (Element) dragStartEvent.getEventTarget().cast()); } - fixDragImageForSafari(draggedRowElement); + fixDragImageForDesktopSafari(draggedRowElement); + fixDragImageTransformForMobile(draggedRowElement); } } - private int getRelativeY(Element element, NativeEvent event) { - int relativeTop = element.getAbsoluteTop() - Window.getScrollTop(); - return WidgetUtil.getTouchOrMouseClientY(event) - relativeTop; - } - private int getRelativeX(Element element, NativeEvent event) { int relativeLeft = element.getAbsoluteLeft() - Window.getScrollLeft(); return WidgetUtil.getTouchOrMouseClientX(event) - relativeLeft; @@ -204,8 +205,8 @@ public class GridDragSourceConnector extends DragSourceExtensionConnector { @Override protected Map<String, String> createDataTransferData( NativeEvent dragStartEvent) { - Map<String, String> dataMap = super - .createDataTransferData(dragStartEvent); + Map<String, String> dataMap = super.createDataTransferData( + dragStartEvent); // Add data provided by the generator functions getDraggedRows(dragStartEvent).forEach(row -> { @@ -331,9 +332,9 @@ public class GridDragSourceConnector extends DragSourceExtensionConnector { * Gets drag data provided by the generator functions. * * @param row - * The row data. + * The row data. * @return The generated drag data type mapped to the corresponding drag - * data. If there are no generator functions, returns an empty map. + * data. If there are no generator functions, returns an empty map. */ private Map<String, String> getRowDragData(JsonObject row) { // Collect a map of data types and data that is provided by the diff --git a/client/src/main/java/com/vaadin/client/extensions/DragSourceExtensionConnector.java b/client/src/main/java/com/vaadin/client/extensions/DragSourceExtensionConnector.java index 7d79fb74dc..61ff4dea8a 100644 --- a/client/src/main/java/com/vaadin/client/extensions/DragSourceExtensionConnector.java +++ b/client/src/main/java/com/vaadin/client/extensions/DragSourceExtensionConnector.java @@ -211,20 +211,22 @@ public class DragSourceExtensionConnector extends AbstractExtensionConnector { } /** - * Fixes missing drag image for Safari by making the dragged element + * Fixes missing drag image for desktop Safari by making the dragged element * position to relative if needed. Safari won't show drag image unless the * dragged element position is relative or absolute / fixed, but not with * display block for the latter. * <p> - * This method is a NOOP for non-safari browser. + * This method is a NOOP for non-safari browser, or mobile safari which is + * using the DnD Polyfill. * <p> * This fix is not needed if a custom drag image is used on Safari. * * @param draggedElement * the element that forms the drag image */ - protected void fixDragImageForSafari(Element draggedElement) { - if (!BrowserInfo.get().isSafari()) { + protected void fixDragImageForDesktopSafari(Element draggedElement) { + if (!BrowserInfo.get().isSafari() + || BrowserInfo.get().isTouchDevice()) { return; } final Style style = draggedElement.getStyle(); @@ -253,12 +255,40 @@ public class DragSourceExtensionConnector extends AbstractExtensionConnector { } /** + * Fix drag image offset for touch devices when the dragged image has been + * offset with css transform: translate/translate3d. + * <p> + * This necessary for e.g grid rows. + * <p> + * This method is NOOP for non-touch browsers. + * + * @param draggedElement + * the element that forms the drag image + */ + protected void fixDragImageTransformForMobile(Element draggedElement) { + if (!BrowserInfo.get().isTouchDevice()) { + return; + } + + Style style = draggedElement.getStyle(); + String transition = style.getProperty("transform"); + if (transition == null || transition.isEmpty() + || !transition.startsWith("translate")) { + return; + } + style.clearProperty("transform"); + AnimationScheduler.get().requestAnimationFrame(timestamp -> { + draggedElement.getStyle().setProperty("transform", transition); + }, draggedElement); + } + + /** * Creates the data map to be set as the {@code DataTransfer} object's data. * * @param dragStartEvent - * The drag start event + * The drag start event * @return The map from type to data, or {@code null} for not setting any - * data. Returning {@code null} will cancel the drag start. + * data. Returning {@code null} will cancel the drag start. */ protected Map<String, String> createDataTransferData( NativeEvent dragStartEvent) { @@ -299,8 +329,10 @@ public class DragSourceExtensionConnector extends AbstractExtensionConnector { dragStartEvent.getDataTransfer() .setDragImage(dragImage.getElement(), 0, 0); } else { - fixDragImageForSafari( - (Element) dragStartEvent.getCurrentEventTarget().cast()); + Element draggedElement = (Element) dragStartEvent + .getCurrentEventTarget().cast(); + fixDragImageForDesktopSafari(draggedElement); + fixDragImageTransformForMobile(draggedElement); } } diff --git a/client/src/main/java/com/vaadin/client/ui/ui/UIConnector.java b/client/src/main/java/com/vaadin/client/ui/ui/UIConnector.java index 49a7e181b2..5618cabb19 100644 --- a/client/src/main/java/com/vaadin/client/ui/ui/UIConnector.java +++ b/client/src/main/java/com/vaadin/client/ui/ui/UIConnector.java @@ -1231,9 +1231,11 @@ public class UIConnector extends AbstractSingleComponentContainerConnector } } - // TODO add configuration to use custom drag start decider private static native void initializeMobileDndPolyfill() /*-{ - $wnd.DragDropPolyfill.Initialize(); + var conf = new Object(); + // this is needed or the drag image will offset to weird place in for grid rows + conf['dragImageCenterOnTouch'] = true; + $wnd.DragDropPolyfill.Initialize(conf); }-*/; } |