diff options
author | Pekka Hyvönen <pekka@vaadin.com> | 2017-05-15 16:46:03 +0300 |
---|---|---|
committer | Pekka Hyvönen <pekka@vaadin.com> | 2017-05-15 16:46:03 +0300 |
commit | a49ad975f631e3fd40a0bd573ae271c172c617fb (patch) | |
tree | 7c8894f63494a4535519a4dfff57923c236bddd6 | |
parent | 91e0eb1ce19aec5f634261534674960b7b7af399 (diff) | |
download | vaadin-framework-mobile_drag_image_offset.tar.gz vaadin-framework-mobile_drag_image_offset.zip |
WIP: Customize drag image offset for mobile devicesmobile_drag_image_offset
Doesn't work properly, as the callback is executed multiple times and the drag image gets stuck at some point.
3 files changed, 159 insertions, 4 deletions
diff --git a/client/src/main/java/com/vaadin/client/extensions/DragImageTranslateOverrideCallback.java b/client/src/main/java/com/vaadin/client/extensions/DragImageTranslateOverrideCallback.java new file mode 100644 index 0000000000..968e56bf28 --- /dev/null +++ b/client/src/main/java/com/vaadin/client/extensions/DragImageTranslateOverrideCallback.java @@ -0,0 +1,49 @@ +/* + * Copyright 2000-2016 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.client.extensions; + +import elemental.events.TouchEvent; +import elemental.html.HtmlElement; +import elemental.html.Point; +import jsinterop.annotations.JsFunction; + +/** + * Listener used to be able to override drag image location when mobile drag and + * drop support has been enabled using a polyfill + * (https://github.com/timruffles/ios-html5-drag-drop-shim/tree/rewrite). + * + * @author Vaadin Ltd + * @since 8.1 + */ +@FunctionalInterface +@JsFunction +public interface DragImageTranslateOverrideCallback { + /** + * Hook for custom logic that can manipulate the drag image translate + * offset. + * + * @param event + * corresponding touchmove event + * @param hoverCoordinates + * the processed touch event viewport coordinates + * @param hoveredElement + * the element under the calculated touch coordinates + * @param callback + * callback for updating the drag image offset + */ + void execute(TouchEvent event, Point hoverCoordinates, + HtmlElement hoveredElement, TranslateDragImageCallback callback); +} diff --git a/client/src/main/java/com/vaadin/client/extensions/TranslateDragImageCallback.java b/client/src/main/java/com/vaadin/client/extensions/TranslateDragImageCallback.java new file mode 100644 index 0000000000..af39198faf --- /dev/null +++ b/client/src/main/java/com/vaadin/client/extensions/TranslateDragImageCallback.java @@ -0,0 +1,40 @@ +/* + * Copyright 2000-2016 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.client.extensions; + +import jsinterop.annotations.JsFunction; + +/** + * The callback for updating the drag image offset coordinates from + * {@link DragImageTranslateOverrideCallback}. + * + * @author Vaadin Ltd + * @since 8.1 + */ +@FunctionalInterface +@JsFunction +public interface TranslateDragImageCallback { + + /** + * Updates the drag image offset with the given values. + * + * @param offsetX + * the x offset + * @param offsetY + * the y offset + */ + void execute(Number offsetX, Number offsetY); +} 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..a214667af0 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 @@ -69,8 +69,10 @@ import com.vaadin.client.ValueMap; import com.vaadin.client.annotations.OnStateChange; import com.vaadin.client.communication.StateChangeEvent; import com.vaadin.client.communication.StateChangeEvent.StateChangeHandler; +import com.vaadin.client.extensions.DragImageTranslateOverrideCallback; import com.vaadin.client.extensions.DragSourceExtensionConnector; import com.vaadin.client.extensions.DropTargetExtensionConnector; +import com.vaadin.client.extensions.TranslateDragImageCallback; import com.vaadin.client.ui.AbstractConnector; import com.vaadin.client.ui.AbstractSingleComponentContainerConnector; import com.vaadin.client.ui.ClickEventHandler; @@ -107,6 +109,9 @@ import com.vaadin.shared.util.SharedUtil; import com.vaadin.ui.UI; import elemental.client.Browser; +import elemental.events.TouchEvent; +import elemental.html.HtmlElement; +import elemental.html.Point; @Connect(value = UI.class, loadStyle = LoadStyle.EAGER) public class UIConnector extends AbstractSingleComponentContainerConnector @@ -118,6 +123,8 @@ public class UIConnector extends AbstractSingleComponentContainerConnector private HandlerRegistration windowOrderRegistration; + private Element draggedElement; + /* * Used to workaround IE bug related to popstate events and certain fragment * only changes @@ -170,7 +177,9 @@ public class UIConnector extends AbstractSingleComponentContainerConnector @Override public void initializeMobileHtml5DndPolyfill() { - initializeMobileDndPolyfill(); + // this method is called from the server side only once + DragImageTranslateOverrideCallback callback = UIConnector.this::applyMobileDragImageOffset; + initializeMobileDndPolyfill(callback); } }); registerRpc(ScrollClientRpc.class, new ScrollClientRpc() { @@ -1231,9 +1240,66 @@ public class UIConnector extends AbstractSingleComponentContainerConnector } } - // TODO add configuration to use custom drag start decider - private static native void initializeMobileDndPolyfill() + private void applyMobileDragImageOffset(TouchEvent event, + Point hoverCoordinates, HtmlElement hoveredElement, + TranslateDragImageCallback callback) { + Element target = (Element) event.getTarget(); + + while (target != null && !target.getPropertyBoolean("draggable")) { + target = target.getParentElement(); + } + if (target == null) { + getLogger().info( + "Could not detect draggable element for fixing drag image offset"); + return; + } + + // using style instead of computed style since that would produce matrix + // values "matrix(1, 0, 0, 1, 0, 190)" that are a bit hard to read from + String transform = target.getStyle().getProperty("transform"); + if (transform == null || transform.isEmpty()) { + transform = target.getStyle().getProperty("webkitTransform"); + } + + if (transform == null || transform.isEmpty() + || !transform.startsWith("translate")) { + return; + } + // transform should be either "translate(Npx, Npx)" or "translate3d(Npx, + // Npx, 0px)", and we are interested only in X and Y coordinate + // transforms. Cannot effect any else using the callback. + + final int indexOfFirstPx = transform.indexOf("px"); + final int indexOfSecondPx = transform.indexOf("px", indexOfFirstPx + 1); + if (indexOfFirstPx == -1 || indexOfSecondPx == -1) { + getLogger() + .info("Could not parse transform css property X and Y coordinates from string: " + + transform); + return; + } + String transformX = transform + .substring(transform.indexOf("(") + 1, indexOfFirstPx).trim(); + String transformY = transform.substring(indexOfFirstPx + 3, // px, Npx + indexOfSecondPx).trim(); + + getLogger().warning( + "PARSED X:<" + transformX + ">, Y: <" + transformY + ">"); + + int offsetX = Math.negateExact(Integer.parseInt(transformX)); + int offsetY = Math.negateExact(Integer.parseInt(transformY)); + + getLogger().warning( + "Applying drag image offset X:" + offsetX + ", Y:" + offsetY); + callback.execute(offsetX, offsetY); + + } + + private static native void initializeMobileDndPolyfill( + DragImageTranslateOverrideCallback callback) /*-{ - $wnd.DragDropPolyfill.Initialize(); + var conf = new Object(); + conf['dragImageTranslateOverride'] = callback; + + $wnd.DragDropPolyfill.Initialize(conf); }-*/; } |