Add setting to control whether tree items are scrolled into view when selected.
Adapted from patch http://gwt-code-reviews.appspot.com/1819803/
Credit for the original patch goes to Marko Krajnc (marko.krajnc@cursor.si)
Fixes issue 2467.
Review by: mdempsky@google.com
git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@11465 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/user/src/com/google/gwt/user/client/ui/Tree.java b/user/src/com/google/gwt/user/client/ui/Tree.java
index a83796c..5d062a5 100644
--- a/user/src/com/google/gwt/user/client/ui/Tree.java
+++ b/user/src/com/google/gwt/user/client/ui/Tree.java
@@ -243,6 +243,8 @@
private TreeItem root;
+ private boolean scrollOnSelectEnabled = true;
+
private boolean useLeafImages;
/**
@@ -635,6 +637,13 @@
return isAnimationEnabled;
}
+ /**
+ * Determines whether selecting a tree item will scroll it into view.
+ */
+ public boolean isScrollOnSelectEnabled() {
+ return scrollOnSelectEnabled;
+ }
+
@Override
public Iterator<Widget> iterator() {
final Widget[] widgets = new Widget[childWidgets.size()];
@@ -853,6 +862,14 @@
}
/**
+ * Enable or disable scrolling a tree item into view when it is selected. Scrolling into view is
+ * enabled by default.
+ */
+ public void setScrollOnSelectEnabled(boolean enable) {
+ scrollOnSelectEnabled = enable;
+ }
+
+ /**
* Selects a specified item.
*
* @param item the item to be selected, or <code>null</code> to deselect all
@@ -1221,35 +1238,39 @@
Focusable focusableWidget = curSelection.getFocusable();
if (focusableWidget != null) {
focusableWidget.setFocus(true);
- DOM.scrollIntoView(((Widget) focusableWidget).getElement());
- } else {
- // Get the location and size of the given item's content element relative
- // to the tree.
- Element selectedElem = curSelection.getContentElem();
- int containerLeft = getAbsoluteLeft();
- int containerTop = getAbsoluteTop();
-
- int left = DOM.getAbsoluteLeft(selectedElem) - containerLeft;
- int top = DOM.getAbsoluteTop(selectedElem) - containerTop;
- int width = DOM.getElementPropertyInt(selectedElem, "offsetWidth");
- int height = DOM.getElementPropertyInt(selectedElem, "offsetHeight");
-
- // If the item is not visible, quite here
- if (width == 0 || height == 0) {
- DOM.setIntStyleAttribute(focusable, "left", 0);
- DOM.setIntStyleAttribute(focusable, "top", 0);
- return;
+ if (scrollOnSelectEnabled) {
+ DOM.scrollIntoView(((Widget) focusableWidget).getElement());
}
+ } else {
+ if (scrollOnSelectEnabled) {
+ // Get the location and size of the given item's content element relative
+ // to the tree.
+ Element selectedElem = curSelection.getContentElem();
+ int containerLeft = getAbsoluteLeft();
+ int containerTop = getAbsoluteTop();
+
+ int left = DOM.getAbsoluteLeft(selectedElem) - containerLeft;
+ int top = DOM.getAbsoluteTop(selectedElem) - containerTop;
+ int width = DOM.getElementPropertyInt(selectedElem, "offsetWidth");
+ int height = DOM.getElementPropertyInt(selectedElem, "offsetHeight");
- // Set the focusable element's position and size to exactly underlap the
- // item's content element.
- DOM.setStyleAttribute(focusable, "left", left + "px");
- DOM.setStyleAttribute(focusable, "top", top + "px");
- DOM.setStyleAttribute(focusable, "width", width + "px");
- DOM.setStyleAttribute(focusable, "height", height + "px");
-
- // Scroll it into view.
- DOM.scrollIntoView(focusable);
+ // If the item is not visible, quite here
+ if (width == 0 || height == 0) {
+ DOM.setIntStyleAttribute(focusable, "left", 0);
+ DOM.setIntStyleAttribute(focusable, "top", 0);
+ return;
+ }
+
+ // Set the focusable element's position and size to exactly underlap the
+ // item's content element.
+ DOM.setStyleAttribute(focusable, "left", left + "px");
+ DOM.setStyleAttribute(focusable, "top", top + "px");
+ DOM.setStyleAttribute(focusable, "width", width + "px");
+ DOM.setStyleAttribute(focusable, "height", height + "px");
+
+ // Scroll it into view.
+ DOM.scrollIntoView(focusable);
+ }
// Update ARIA attributes to reflect the information from the
// newly-selected item.
diff --git a/user/test/com/google/gwt/user/client/ui/TreeTest.java b/user/test/com/google/gwt/user/client/ui/TreeTest.java
index 212b901..dfcda3a 100644
--- a/user/test/com/google/gwt/user/client/ui/TreeTest.java
+++ b/user/test/com/google/gwt/user/client/ui/TreeTest.java
@@ -15,6 +15,8 @@
*/
package com.google.gwt.user.client.ui;
+import com.google.gwt.junit.DoNotRunWith;
+import com.google.gwt.junit.Platform;
import com.google.gwt.junit.client.GWTTestCase;
import com.google.gwt.safehtml.shared.SafeHtmlUtils;
import com.google.gwt.user.client.DOM;
@@ -344,6 +346,55 @@
// Expected.
}
}
+
+ @DoNotRunWith(Platform.HtmlUnitLayout)
+ public void testScrollOnSelectEnabledFalse() {
+ // With scrolling disabled.
+ Tree tree = createTree();
+ tree.setScrollOnSelectEnabled(false);
+ assertScrollingOnSelection(tree, false);
+ }
+
+ @DoNotRunWith(Platform.HtmlUnitLayout)
+ public void testScrollOnSelectEnabledTrue() {
+ // With scrolling enabled (default)
+ Tree tree = createTree();
+ assertTrue(tree.isScrollOnSelectEnabled());
+ assertScrollingOnSelection(tree, true);
+ }
+
+ private void assertScrollingOnSelection(Tree tree, boolean shouldScroll) {
+ tree.addItem(new Label("hello1"));
+ tree.addItem(new Label("hello2"));
+ TreeItem levelZeroTreeItem = tree.addItem(new Label("level0"));
+ TreeItem selectedItem = levelZeroTreeItem.addItem(new Label("level1"));
+ selectedItem.addItem(SafeHtmlUtils.fromString("level2"));
+
+ // For the tree to be opened. Otherwise, all sizes will be zero and no scrolling would occur,
+ // regardless of the mode.
+ levelZeroTreeItem.setState(true);
+ selectedItem.setState(true);
+
+ ScrollPanel panel = new ScrollPanel();
+ RootPanel.get().add(panel);
+ panel.setWidget(tree);
+
+ // Set a size that is smaller than the content to allow scrolling
+ panel.setPixelSize(40, 90);
+
+ assertEquals(0, panel.getVerticalScrollPosition());
+ assertEquals(0, panel.getHorizontalScrollPosition());
+
+ tree.setSelectedItem(selectedItem);
+
+ if (shouldScroll) {
+ assertTrue("Expected vertical scroll", panel.getVerticalScrollPosition() != 0);
+ assertTrue("Expected horizontal scroll", panel.getHorizontalScrollPosition() != 0);
+ } else {
+ assertEquals("Expected no vertical scroll", 0, panel.getVerticalScrollPosition());
+ assertEquals("Expected no horizontal scroll", 0, panel.getHorizontalScrollPosition());
+ }
+ }
public void testSwap() {
Tree t = createTree();