From fefedeab68461ebc04fd45f91a35835fc9026a56 Mon Sep 17 00:00:00 2001 From: Thomas Date: Tue, 5 Nov 2013 15:21:06 +0200 Subject: [PATCH] Send window position data back to server after drag (#12885) Change-Id: I9ca766b0e06390c7ab90f9cbd4996b83032789db --- client/src/com/vaadin/client/ui/VWindow.java | 16 ++++ .../client/ui/window/WindowConnector.java | 13 ++- .../client/ui/window/WindowMoveEvent.java | 82 +++++++++++++++++++ .../client/ui/window/WindowMoveHandler.java | 35 ++++++++ server/src/com/vaadin/ui/Window.java | 10 +++ .../shared/ui/window/WindowServerRpc.java | 2 + .../components/window/WindowMoveListener.java | 67 +++++++++++++++ .../window/WindowMoveListenerTest.java | 50 +++++++++++ 8 files changed, 274 insertions(+), 1 deletion(-) create mode 100644 client/src/com/vaadin/client/ui/window/WindowMoveEvent.java create mode 100644 client/src/com/vaadin/client/ui/window/WindowMoveHandler.java create mode 100644 uitest/src/com/vaadin/tests/components/window/WindowMoveListener.java create mode 100644 uitest/src/com/vaadin/tests/components/window/WindowMoveListenerTest.java diff --git a/client/src/com/vaadin/client/ui/VWindow.java b/client/src/com/vaadin/client/ui/VWindow.java index 9f19a3e0ab..62937b6a67 100644 --- a/client/src/com/vaadin/client/ui/VWindow.java +++ b/client/src/com/vaadin/client/ui/VWindow.java @@ -33,6 +33,7 @@ import com.google.gwt.event.dom.client.KeyDownEvent; import com.google.gwt.event.dom.client.KeyDownHandler; import com.google.gwt.event.dom.client.ScrollEvent; import com.google.gwt.event.dom.client.ScrollHandler; +import com.google.gwt.event.shared.HandlerRegistration; import com.google.gwt.user.client.Command; import com.google.gwt.user.client.DOM; import com.google.gwt.user.client.Element; @@ -47,6 +48,8 @@ import com.vaadin.client.LayoutManager; import com.vaadin.client.Util; import com.vaadin.client.debug.internal.VDebugWindow; import com.vaadin.client.ui.ShortcutActionHandler.ShortcutActionHandlerOwner; +import com.vaadin.client.ui.window.WindowMoveEvent; +import com.vaadin.client.ui.window.WindowMoveHandler; import com.vaadin.shared.EventId; import com.vaadin.shared.ui.window.WindowMode; @@ -921,6 +924,9 @@ public class VWindow extends VOverlay implements ShortcutActionHandlerOwner, dragging = false; hideDraggingCurtain(); DOM.releaseCapture(getElement()); + + // fire move event + fireEvent(new WindowMoveEvent(uidlPositionX, uidlPositionY)); } @Override @@ -1036,4 +1042,14 @@ public class VWindow extends VOverlay implements ShortcutActionHandlerOwner, - contentPanel.getElement().getOffsetWidth(); } + /** + * Adds a Handler for when user moves the window. + * + * @since 7.1.9 + * @return {@link HandlerRegistration} used to remove the handler + */ + public HandlerRegistration addMoveHandler(WindowMoveHandler handler) { + return addHandler(handler, WindowMoveEvent.getType()); + } + } diff --git a/client/src/com/vaadin/client/ui/window/WindowConnector.java b/client/src/com/vaadin/client/ui/window/WindowConnector.java index ff2e93a3b2..54ea384f5a 100644 --- a/client/src/com/vaadin/client/ui/window/WindowConnector.java +++ b/client/src/com/vaadin/client/ui/window/WindowConnector.java @@ -34,6 +34,7 @@ import com.vaadin.client.LayoutManager; import com.vaadin.client.Paintable; import com.vaadin.client.UIDL; import com.vaadin.client.Util; +import com.vaadin.client.communication.RpcProxy; import com.vaadin.client.communication.StateChangeEvent; import com.vaadin.client.ui.AbstractSingleComponentContainerConnector; import com.vaadin.client.ui.ClickEventHandler; @@ -52,7 +53,8 @@ import com.vaadin.shared.ui.window.WindowState; @Connect(value = com.vaadin.ui.Window.class) public class WindowConnector extends AbstractSingleComponentContainerConnector implements Paintable, BeforeShortcutActionListener, - SimpleManagedLayout, PostLayoutListener, MayScrollChildren { + SimpleManagedLayout, PostLayoutListener, MayScrollChildren, + WindowMoveHandler { private ClickEventHandler clickEventHandler = new ClickEventHandler(this) { @Override @@ -112,6 +114,8 @@ public class WindowConnector extends AbstractSingleComponentContainerConnector DoubleClickEvent.getType()); window.setOwner(getConnection().getUIConnector().getWidget()); + + window.addMoveHandler(this); } @Override @@ -400,4 +404,11 @@ public class WindowConnector extends AbstractSingleComponentContainerConnector */ return true; } + + @Override + public void onWindowMove(WindowMoveEvent event) { + RpcProxy.create(WindowServerRpc.class, this).windowMoved( + event.getNewX(), event.getNewY()); + + } } diff --git a/client/src/com/vaadin/client/ui/window/WindowMoveEvent.java b/client/src/com/vaadin/client/ui/window/WindowMoveEvent.java new file mode 100644 index 0000000000..439a90e3a1 --- /dev/null +++ b/client/src/com/vaadin/client/ui/window/WindowMoveEvent.java @@ -0,0 +1,82 @@ +/* + * Copyright 2000-2013 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.ui.window; + +import com.google.gwt.event.shared.GwtEvent; + +/** + * Event for window position updates + * + * @since 7.1.9 + * @author Vaadin Ltd + */ +public class WindowMoveEvent extends GwtEvent { + + private static final Type TYPE = new Type(); + + private final int newX; + private final int newY; + + /** + * Creates a new event with the given parameters + * + * @param x + * The new x-position for the VWindow + * @param y + * The new y-position for the VWindow + */ + public WindowMoveEvent(int x, int y) { + newX = x; + newY = y; + } + + /** + * Gets the new x position of the window + * + * @return the new X position of the VWindow + */ + public int getNewX() { + return newX; + } + + /** + * Gets the new y position of the window + * + * @return the new Y position of the VWindow + */ + public int getNewY() { + return newY; + } + + /** + * Gets the type of the event + * + * @return the type of the event + */ + public static Type getType() { + return TYPE; + } + + @Override + public Type getAssociatedType() { + return TYPE; + } + + @Override + protected void dispatch(WindowMoveHandler handler) { + handler.onWindowMove(this); + } +} diff --git a/client/src/com/vaadin/client/ui/window/WindowMoveHandler.java b/client/src/com/vaadin/client/ui/window/WindowMoveHandler.java new file mode 100644 index 0000000000..e30e1853fe --- /dev/null +++ b/client/src/com/vaadin/client/ui/window/WindowMoveHandler.java @@ -0,0 +1,35 @@ +/* + * Copyright 2000-2013 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.ui.window; + +import com.google.gwt.event.shared.EventHandler; + +/** + * Handler for {@link WindowMoveEvent}s + * + * @since 7.1.9 + * @author Vaadin Ltd + */ +public interface WindowMoveHandler extends EventHandler { + + /** + * Called when the VWindow was moved by the user. + * + * @param event + * Contains new coordinates for the VWindow + */ + public void onWindowMove(WindowMoveEvent event); +} diff --git a/server/src/com/vaadin/ui/Window.java b/server/src/com/vaadin/ui/Window.java index 5820161c1c..c173b401b9 100644 --- a/server/src/com/vaadin/ui/Window.java +++ b/server/src/com/vaadin/ui/Window.java @@ -77,6 +77,16 @@ public class Window extends Panel implements FocusNotifier, BlurNotifier, public void windowModeChanged(WindowMode newState) { setWindowMode(newState); } + + @Override + public void windowMoved(int x, int y) { + if (x != getState(false).positionX) { + setPositionX(x); + } + if (y != getState(false).positionY) { + setPositionY(y); + } + } }; /** diff --git a/shared/src/com/vaadin/shared/ui/window/WindowServerRpc.java b/shared/src/com/vaadin/shared/ui/window/WindowServerRpc.java index b43765274e..1307b1e765 100644 --- a/shared/src/com/vaadin/shared/ui/window/WindowServerRpc.java +++ b/shared/src/com/vaadin/shared/ui/window/WindowServerRpc.java @@ -22,4 +22,6 @@ public interface WindowServerRpc extends ClickRpc, ServerRpc { public void windowModeChanged(WindowMode newState); + public void windowMoved(int x, int y); + } \ No newline at end of file diff --git a/uitest/src/com/vaadin/tests/components/window/WindowMoveListener.java b/uitest/src/com/vaadin/tests/components/window/WindowMoveListener.java new file mode 100644 index 0000000000..e0bc0d9471 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/window/WindowMoveListener.java @@ -0,0 +1,67 @@ +package com.vaadin.tests.components.window; + +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUI; +import com.vaadin.ui.Button; +import com.vaadin.ui.Button.ClickEvent; +import com.vaadin.ui.Button.ClickListener; +import com.vaadin.ui.Window; + +@SuppressWarnings("serial") +public class WindowMoveListener extends AbstractTestUI { + + /* + * (non-Javadoc) + * + * @see com.vaadin.tests.components.AbstractTestUI#setup(com.vaadin.server. + * VaadinRequest) + */ + @Override + protected void setup(VaadinRequest request) { + + Window w = new Window("Caption"); + w.setId("testwindow"); + w.setHeight("100px"); + w.setWidth("100px"); + w.setPositionX(100); + w.setPositionY(100); + addWindow(w); + + Button b = new Button(); + b.setId("testbutton"); + addComponent(b); + b.addClickListener(new ClickListener() { + + @Override + public void buttonClick(ClickEvent event) { + for (Window window : getWindows()) { + window.setPositionX(100); + window.setPositionY(100); + } + } + }); + + } + + /* + * (non-Javadoc) + * + * @see com.vaadin.tests.components.AbstractTestUI#getTestDescription() + */ + @Override + protected String getTestDescription() { + return "Tests that windows send their updated position " + + "to server-side after being moved by user"; + } + + /* + * (non-Javadoc) + * + * @see com.vaadin.tests.components.AbstractTestUI#getTicketNumber() + */ + @Override + protected Integer getTicketNumber() { + return 12885; + } + +} \ No newline at end of file diff --git a/uitest/src/com/vaadin/tests/components/window/WindowMoveListenerTest.java b/uitest/src/com/vaadin/tests/components/window/WindowMoveListenerTest.java new file mode 100644 index 0000000000..3ea3b719c0 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/window/WindowMoveListenerTest.java @@ -0,0 +1,50 @@ +package com.vaadin.tests.components.window; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotEquals; + +import org.junit.Test; +import org.openqa.selenium.By; +import org.openqa.selenium.Point; +import org.openqa.selenium.WebElement; +import org.openqa.selenium.interactions.Action; +import org.openqa.selenium.interactions.Actions; + +import com.vaadin.tests.tb3.MultiBrowserTest; + +public class WindowMoveListenerTest extends MultiBrowserTest { + + @Test + public void testWindowRepositioning() throws Exception { + openTestURL(); + + WebElement window = getDriver().findElement(By.id("testwindow")); + WebElement button = getDriver().findElement(By.id("testbutton")); + + // I'd loved to use the header, but that doesn't work. Footer works + // fine, though :) + WebElement windowHeader = getDriver().findElement( + By.className("v-window-footer")); + + Point winPos = window.getLocation(); + + // move window + Action a = new Actions(driver).clickAndHold(windowHeader) + .moveByOffset(100, 100).release().build(); + a.perform(); + + assertNotEquals("Window was not dragged correctly.", winPos.x, + window.getLocation().x); + assertNotEquals("Window was not dragged correctly.", winPos.y, + window.getLocation().y); + + // re-set window + button.click(); + + assertEquals("Window was not re-positioned correctly.", winPos.x, + window.getLocation().x); + assertEquals("Window was not re-positioned correctly.", winPos.y, + window.getLocation().y); + + } +} \ No newline at end of file -- 2.39.5