summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--client/src/com/vaadin/client/ui/VUI.java39
-rw-r--r--client/src/com/vaadin/client/ui/ui/UIConnector.java46
-rw-r--r--server/src/com/vaadin/ui/UI.java55
-rw-r--r--shared/src/com/vaadin/shared/ui/ui/ScrollClientRpc.java26
-rw-r--r--shared/src/com/vaadin/shared/ui/ui/UIServerRpc.java3
-rw-r--r--uitest/src/com/vaadin/tests/components/uitest/UIScrollTest.html57
-rw-r--r--uitest/src/com/vaadin/tests/components/uitest/UIScrollTest.java44
7 files changed, 226 insertions, 44 deletions
diff --git a/client/src/com/vaadin/client/ui/VUI.java b/client/src/com/vaadin/client/ui/VUI.java
index 688c60bca1..cbfbda813e 100644
--- a/client/src/com/vaadin/client/ui/VUI.java
+++ b/client/src/com/vaadin/client/ui/VUI.java
@@ -20,6 +20,9 @@ import java.util.ArrayList;
import com.google.gwt.core.client.Scheduler.ScheduledCommand;
import com.google.gwt.dom.client.Element;
+import com.google.gwt.event.dom.client.HasScrollHandlers;
+import com.google.gwt.event.dom.client.ScrollEvent;
+import com.google.gwt.event.dom.client.ScrollHandler;
import com.google.gwt.event.logical.shared.HasResizeHandlers;
import com.google.gwt.event.logical.shared.ResizeEvent;
import com.google.gwt.event.logical.shared.ResizeHandler;
@@ -49,7 +52,7 @@ import com.vaadin.shared.ui.ui.UIConstants;
*/
public class VUI extends SimplePanel implements ResizeHandler,
Window.ClosingHandler, ShortcutActionHandlerOwner, Focusable,
- HasResizeHandlers {
+ HasResizeHandlers, HasScrollHandlers {
private static int MONITOR_PARENT_TIMER_INTERVAL = 1000;
@@ -95,18 +98,9 @@ public class VUI extends SimplePanel implements ResizeHandler,
private int parentHeight;
/** For internal use only. May be removed or replaced in the future. */
- public int scrollTop;
-
- /** For internal use only. May be removed or replaced in the future. */
- public int scrollLeft;
-
- /** For internal use only. May be removed or replaced in the future. */
public boolean rendering;
/** For internal use only. May be removed or replaced in the future. */
- public boolean scrollable;
-
- /** For internal use only. May be removed or replaced in the future. */
public boolean immediate;
/** For internal use only. May be removed or replaced in the future. */
@@ -350,26 +344,6 @@ public class VUI extends SimplePanel implements ResizeHandler,
if (type == Event.ONKEYDOWN && actionHandler != null) {
actionHandler.handleKeyboardEvent(event);
return;
- } else if (scrollable && type == Event.ONSCROLL) {
- updateScrollPosition();
- }
- }
-
- /**
- * Updates scroll position from DOM and saves variables to server.
- */
- private void updateScrollPosition() {
- int oldTop = scrollTop;
- int oldLeft = scrollLeft;
- scrollTop = DOM.getElementPropertyInt(getElement(), "scrollTop");
- scrollLeft = DOM.getElementPropertyInt(getElement(), "scrollLeft");
- if (connection != null && !rendering) {
- if (oldTop != scrollTop) {
- connection.updateVariable(id, "scrollTop", scrollTop, false);
- }
- if (oldLeft != scrollLeft) {
- connection.updateVariable(id, "scrollLeft", scrollLeft, false);
- }
}
}
@@ -478,4 +452,9 @@ public class VUI extends SimplePanel implements ResizeHandler,
return addHandler(resizeHandler, ResizeEvent.getType());
}
+ @Override
+ public HandlerRegistration addScrollHandler(ScrollHandler scrollHandler) {
+ return addHandler(scrollHandler, ScrollEvent.getType());
+ }
+
}
diff --git a/client/src/com/vaadin/client/ui/ui/UIConnector.java b/client/src/com/vaadin/client/ui/ui/UIConnector.java
index 1d2c830ea6..a297a89b8e 100644
--- a/client/src/com/vaadin/client/ui/ui/UIConnector.java
+++ b/client/src/com/vaadin/client/ui/ui/UIConnector.java
@@ -23,10 +23,13 @@ import com.google.gwt.core.client.Scheduler;
import com.google.gwt.dom.client.NativeEvent;
import com.google.gwt.dom.client.Style;
import com.google.gwt.dom.client.Style.Position;
+import com.google.gwt.event.dom.client.ScrollEvent;
+import com.google.gwt.event.dom.client.ScrollHandler;
import com.google.gwt.event.logical.shared.ResizeEvent;
import com.google.gwt.event.logical.shared.ResizeHandler;
import com.google.gwt.user.client.Command;
import com.google.gwt.user.client.DOM;
+import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.Event;
import com.google.gwt.user.client.History;
import com.google.gwt.user.client.Window;
@@ -56,6 +59,7 @@ import com.vaadin.shared.ui.ComponentStateUtil;
import com.vaadin.shared.ui.Connect;
import com.vaadin.shared.ui.Connect.LoadStyle;
import com.vaadin.shared.ui.ui.PageClientRpc;
+import com.vaadin.shared.ui.ui.ScrollClientRpc;
import com.vaadin.shared.ui.ui.UIConstants;
import com.vaadin.shared.ui.ui.UIServerRpc;
import com.vaadin.shared.ui.ui.UIState;
@@ -85,6 +89,17 @@ public class UIConnector extends AbstractSingleComponentContainerConnector
com.google.gwt.user.client.Window.setTitle(title);
}
});
+ registerRpc(ScrollClientRpc.class, new ScrollClientRpc() {
+ @Override
+ public void setScrollTop(int scrollTop) {
+ getWidget().getElement().setScrollTop(scrollTop);
+ }
+
+ @Override
+ public void setScrollLeft(int scrollLeft) {
+ getWidget().getElement().setScrollLeft(scrollLeft);
+ }
+ });
getWidget().addResizeHandler(new ResizeHandler() {
@Override
public void onResize(ResizeEvent event) {
@@ -96,6 +111,24 @@ public class UIConnector extends AbstractSingleComponentContainerConnector
}
}
});
+ getWidget().addScrollHandler(new ScrollHandler() {
+ private int lastSentScrollTop = Integer.MAX_VALUE;
+ private int lastSentScrollLeft = Integer.MAX_VALUE;
+
+ @Override
+ public void onScroll(ScrollEvent event) {
+ Element element = getWidget().getElement();
+ int newScrollTop = element.getScrollTop();
+ int newScrollLeft = element.getScrollLeft();
+ if (newScrollTop != lastSentScrollTop
+ || newScrollLeft != lastSentScrollLeft) {
+ lastSentScrollTop = newScrollTop;
+ lastSentScrollLeft = newScrollLeft;
+ getRpcProxy(UIServerRpc.class).scroll(newScrollTop,
+ newScrollLeft);
+ }
+ }
+ });
}
@Override
@@ -244,19 +277,6 @@ public class UIConnector extends AbstractSingleComponentContainerConnector
Window.addResizeHandler(getWidget());
}
- // finally set scroll position from UIDL
- if (uidl.hasVariable("scrollTop")) {
- getWidget().scrollable = true;
- getWidget().scrollTop = uidl.getIntVariable("scrollTop");
- DOM.setElementPropertyInt(getWidget().getElement(), "scrollTop",
- getWidget().scrollTop);
- getWidget().scrollLeft = uidl.getIntVariable("scrollLeft");
- DOM.setElementPropertyInt(getWidget().getElement(), "scrollLeft",
- getWidget().scrollLeft);
- } else {
- getWidget().scrollable = false;
- }
-
if (uidl.hasAttribute("scrollTo")) {
final ComponentConnector connector = (ComponentConnector) uidl
.getPaintableAttribute("scrollTo", getConnection());
diff --git a/server/src/com/vaadin/ui/UI.java b/server/src/com/vaadin/ui/UI.java
index 55f756010e..b45aedb8e1 100644
--- a/server/src/com/vaadin/ui/UI.java
+++ b/server/src/com/vaadin/ui/UI.java
@@ -39,6 +39,7 @@ import com.vaadin.server.VaadinServlet;
import com.vaadin.server.VaadinSession;
import com.vaadin.shared.EventId;
import com.vaadin.shared.MouseEventDetails;
+import com.vaadin.shared.ui.ui.ScrollClientRpc;
import com.vaadin.shared.ui.ui.UIConstants;
import com.vaadin.shared.ui.ui.UIServerRpc;
import com.vaadin.shared.ui.ui.UIState;
@@ -114,6 +115,16 @@ public abstract class UI extends AbstractSingleComponentContainer implements
private Page page = new Page(this);
+ /**
+ * Scroll Y position.
+ */
+ private int scrollTop = 0;
+
+ /**
+ * Scroll X position
+ */
+ private int scrollLeft = 0;
+
private UIServerRpc rpc = new UIServerRpc() {
@Override
public void click(MouseEventDetails mouseDetails) {
@@ -126,6 +137,12 @@ public abstract class UI extends AbstractSingleComponentContainer implements
// TODO We're not doing anything with the view dimensions
getPage().updateBrowserWindowSize(windowWidth, windowHeight);
}
+
+ @Override
+ public void scroll(int scrollTop, int scrollLeft) {
+ UI.this.scrollTop = scrollTop;
+ UI.this.scrollLeft = scrollLeft;
+ }
};
/**
@@ -560,8 +577,44 @@ public abstract class UI extends AbstractSingleComponentContainer implements
return CurrentInstance.get(UI.class);
}
+ /**
+ * Set top offset to which the UI should scroll to.
+ *
+ * @param scrollTop
+ */
public void setScrollTop(int scrollTop) {
- throw new RuntimeException("Not yet implemented");
+ if (scrollTop < 0) {
+ throw new IllegalArgumentException(
+ "Scroll offset must be at least 0");
+ }
+ if (this.scrollTop != scrollTop) {
+ this.scrollTop = scrollTop;
+ getRpcProxy(ScrollClientRpc.class).setScrollTop(scrollTop);
+ }
+ }
+
+ public int getScrollTop() {
+ return scrollTop;
+ }
+
+ /**
+ * Set left offset to which the UI should scroll to.
+ *
+ * @param scrollLeft
+ */
+ public void setScrollLeft(int scrollLeft) {
+ if (scrollLeft < 0) {
+ throw new IllegalArgumentException(
+ "Scroll offset must be at least 0");
+ }
+ if (this.scrollLeft != scrollLeft) {
+ this.scrollLeft = scrollLeft;
+ getRpcProxy(ScrollClientRpc.class).setScrollLeft(scrollLeft);
+ }
+ }
+
+ public int getScrollLeft() {
+ return scrollLeft;
}
@Override
diff --git a/shared/src/com/vaadin/shared/ui/ui/ScrollClientRpc.java b/shared/src/com/vaadin/shared/ui/ui/ScrollClientRpc.java
new file mode 100644
index 0000000000..26ec7f2de2
--- /dev/null
+++ b/shared/src/com/vaadin/shared/ui/ui/ScrollClientRpc.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2011 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.shared.ui.ui;
+
+import com.vaadin.shared.communication.ClientRpc;
+
+public interface ScrollClientRpc extends ClientRpc {
+
+ public void setScrollTop(int scrollTop);
+
+ public void setScrollLeft(int scrollLeft);
+}
diff --git a/shared/src/com/vaadin/shared/ui/ui/UIServerRpc.java b/shared/src/com/vaadin/shared/ui/ui/UIServerRpc.java
index 11a400bbe0..a89b70c8cd 100644
--- a/shared/src/com/vaadin/shared/ui/ui/UIServerRpc.java
+++ b/shared/src/com/vaadin/shared/ui/ui/UIServerRpc.java
@@ -23,4 +23,7 @@ public interface UIServerRpc extends ClickRpc, ServerRpc {
@Delayed(lastOnly = true)
public void resize(int viewWidth, int viewHeight, int windowWidth,
int windowHeight);
+
+ @Delayed(lastOnly = true)
+ public void scroll(int scrollTop, int scrollLeft);
} \ No newline at end of file
diff --git a/uitest/src/com/vaadin/tests/components/uitest/UIScrollTest.html b/uitest/src/com/vaadin/tests/components/uitest/UIScrollTest.html
new file mode 100644
index 0000000000..b5326e4660
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/components/uitest/UIScrollTest.html
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head profile="http://selenium-ide.openqa.org/profiles/test-case">
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+<link rel="selenium.base" href="" />
+<title>UIScrollTest</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">UIScrollTest</td></tr>
+</thead><tbody>
+<tr>
+ <td>open</td>
+ <td>/run/com.vaadin.tests.components.uitest.UIScrollTest?restartApplication</td>
+ <td></td>
+</tr>
+<tr>
+ <td>click</td>
+ <td>vaadin=runcomvaadintestscomponentsuitestUIScrollTest::/VVerticalLayout[0]/VOrderedLayout$Slot[1]/VVerticalLayout[0]/VOrderedLayout$Slot[0]/VButton[0]/domChild[0]/domChild[0]</td>
+ <td></td>
+</tr>
+<tr>
+ <td>screenCapture</td>
+ <td></td>
+ <td>Halfway_down_button</td>
+</tr>
+<tr>
+ <td>scroll</td>
+ <td>vaadin=runcomvaadintestscomponentsuitestUIScrollTest::</td>
+ <td>1020</td>
+</tr>
+<tr>
+ <td>pause</td>
+ <td>300</td>
+ <td></td>
+</tr>
+<tr>
+ <td>click</td>
+ <td>vaadin=runcomvaadintestscomponentsuitestUIScrollTest::/VVerticalLayout[0]/VOrderedLayout$Slot[1]/VVerticalLayout[0]/VOrderedLayout$Slot[1]/VButton[0]/domChild[0]/domChild[0]</td>
+ <td></td>
+</tr>
+<tr>
+ <td>assertText</td>
+ <td>//div[@id='runcomvaadintestscomponentsuitestUIScrollTest-1797389287-overlays']/div</td>
+ <td>Scrolled to 1020 px</td>
+</tr>
+<tr>
+ <td>closeNotification</td>
+ <td>//div[@id='runcomvaadintestscomponentsuitestUIScrollTest-1797389287-overlays']/div</td>
+ <td>0,0</td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/uitest/src/com/vaadin/tests/components/uitest/UIScrollTest.java b/uitest/src/com/vaadin/tests/components/uitest/UIScrollTest.java
new file mode 100644
index 0000000000..66b6ef90b1
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/components/uitest/UIScrollTest.java
@@ -0,0 +1,44 @@
+package com.vaadin.tests.components.uitest;
+
+import com.vaadin.tests.components.TestBase;
+import com.vaadin.ui.Button;
+import com.vaadin.ui.Button.ClickEvent;
+import com.vaadin.ui.Notification;
+import com.vaadin.ui.UI;
+
+public class UIScrollTest extends TestBase {
+
+ @Override
+ protected void setup() {
+ // Set layout to high enough to get scroll.
+ getLayout().setHeight("2250px");
+ addComponent(new Button("scoll to 1000px", new Button.ClickListener() {
+
+ @Override
+ public void buttonClick(ClickEvent event) {
+ UI.getCurrent().setScrollTop(1000);
+ }
+ }));
+ addComponent(new Button(
+ "This button is halfway down. Click to report scroll position.",
+ new Button.ClickListener() {
+ @Override
+ public void buttonClick(ClickEvent event) {
+ Notification.show("Scrolled to "
+ + event.getButton().getUI().getScrollTop()
+ + " px");
+ }
+ }));
+ }
+
+ @Override
+ protected String getDescription() {
+ return "Windows can be programmatically scrolled";
+ }
+
+ @Override
+ protected Integer getTicketNumber() {
+ return 9952;
+ }
+
+}