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;
*/
public class VUI extends SimplePanel implements ResizeHandler,
Window.ClosingHandler, ShortcutActionHandlerOwner, Focusable,
- HasResizeHandlers {
+ HasResizeHandlers, HasScrollHandlers {
private static int MONITOR_PARENT_TIMER_INTERVAL = 1000;
/** stored height of parent for embedded application auto-resize */
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;
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);
- }
}
}
return addHandler(resizeHandler, ResizeEvent.getType());
}
+ @Override
+ public HandlerRegistration addScrollHandler(ScrollHandler scrollHandler) {
+ return addHandler(scrollHandler, ScrollEvent.getType());
+ }
+
}
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;
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;
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) {
}
}
});
+ 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
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());
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;
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) {
// 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;
+ }
};
/**
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
--- /dev/null
+/*
+ * 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);
+}
@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
--- /dev/null
+<?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>
--- /dev/null
+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;
+ }
+
+}