Adds an option to SplitLayoutPanel to hide a widget when its splitter is double clicked. We set the width to 0 instead of hiding the widget because hiding a widget can cause issues with flash components. Also adds a method DockLayoutPanel#setWidgetHidden() which allows users to hide a widget in a DockLayoutPanel. The existance of a "hidden" field in LayoutData suggests that we intended to support this functionality but never got around to it. http://gwt-code-reviews.appspot.com/1398801/ Author: antoine.dessaigne Reviewer: jlabanca Issue: 5264 git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@10896 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/user/src/com/google/gwt/user/client/ui/DockLayoutPanel.java b/user/src/com/google/gwt/user/client/ui/DockLayoutPanel.java index 29ef48e..654927d 100644 --- a/user/src/com/google/gwt/user/client/ui/DockLayoutPanel.java +++ b/user/src/com/google/gwt/user/client/ui/DockLayoutPanel.java
@@ -396,6 +396,24 @@ return removed; } + + /** + * Sets whether or not the given widget should be hidden. + * + * @param widget the widget to hide or display + * @param hidden true to hide the widget, false to display it + */ + public void setWidgetHidden(Widget widget, boolean hidden) { + assertIsChild(widget); + + LayoutData data = (LayoutData) widget.getLayoutData(); + if (data.hidden == hidden) { + return; + } + + data.hidden = hidden; + animate(0); + } /** * Updates the size of the widget passed in as long as it is not the center @@ -532,6 +550,11 @@ LayoutData data = (LayoutData) child.getLayoutData(); Layer layer = data.layer; + if (data.hidden) { + layer.setVisible(false); + continue; + } + switch (getResolvedDirection(data.direction)) { case NORTH: layer.setLeftRight(left, unit, right, unit); @@ -562,6 +585,9 @@ layer.setTopBottom(top, unit, bottom, unit); break; } + + // First set the size, then ensure it's visible + layer.setVisible(true); } filledWidth = left + right;
diff --git a/user/src/com/google/gwt/user/client/ui/SplitLayoutPanel.java b/user/src/com/google/gwt/user/client/ui/SplitLayoutPanel.java index 0a2422f..aaca39f 100644 --- a/user/src/com/google/gwt/user/client/ui/SplitLayoutPanel.java +++ b/user/src/com/google/gwt/user/client/ui/SplitLayoutPanel.java
@@ -15,6 +15,7 @@ */ package com.google.gwt.user.client.ui; +import com.google.gwt.core.client.Duration; import com.google.gwt.core.client.Scheduler; import com.google.gwt.core.client.Scheduler.ScheduledCommand; import com.google.gwt.dom.client.Document; @@ -101,6 +102,9 @@ private int minSize; private double centerSize, syncedCenterSize; + + private boolean toggleDisplayAllowed = false; + private double lastClick = 0; public Splitter(Widget target, boolean reverse) { this.target = target; @@ -138,6 +142,29 @@ mouseDown = false; glassElem.removeFromParent(); + + // Handle double-clicks. + // Fake them since the double-click event aren't fired. + if (this.toggleDisplayAllowed) { + double now = Duration.currentTimeMillis(); + if (now - this.lastClick < DOUBLE_CLICK_TIMEOUT) { + now = 0; + LayoutData layout = (LayoutData) target.getLayoutData(); + if (layout.size == 0) { + // Restore the old size. + setAssociatedWidgetSize(layout.oldSize); + } else { + /* + * Collapse to size 0. We change the size instead of hiding the + * widget because hiding the widget can cause issues if the + * widget contains a flash component. + */ + layout.oldSize = layout.size; + setAssociatedWidgetSize(0); + } + } + this.lastClick = now; + } Event.releaseCapture(getElement()); event.preventDefault(); @@ -152,6 +179,7 @@ } else { size = getEventPosition(event) - getTargetPosition() - offset; } + ((LayoutData) target.getLayoutData()).hidden = false; setAssociatedWidgetSize(size); event.preventDefault(); } @@ -167,6 +195,10 @@ // minSize value. setAssociatedWidgetSize((int) layout.size); } + + public void setToggleDisplayAllowed(boolean allowed) { + this.toggleDisplayAllowed = allowed; + } protected abstract int getAbsolutePosition(); @@ -215,6 +247,7 @@ // mouse events before layout/paint occurs, we'll only update once. if (layoutCommand == null) { layoutCommand = new Command() { + @Override public void execute() { layoutCommand = null; forceLayout(); @@ -259,6 +292,7 @@ } private static final int DEFAULT_SPLITTER_SIZE = 8; + private static final int DOUBLE_CLICK_TIMEOUT = 500; /** * The element that masks the screen so we can catch mouse events over @@ -358,6 +392,22 @@ splitter.setMinSize(minSize); } } + + /** + * Sets whether or not double-clicking on the splitter should toggle the + * display of the widget. + * + * @param child the child whose display toggling will be allowed or not. + * @param allowed whether or not display toggling is allowed for this widget + */ + public void setWidgetToggleDisplayAllowed(Widget child, boolean allowed) { + assertIsChild(child); + Splitter splitter = getAssociatedSplitter(child); + // The splitter is null for the center element. + if (splitter != null) { + splitter.setToggleDisplayAllowed(allowed); + } + } private Splitter getAssociatedSplitter(Widget child) { // If a widget has a next sibling, it must be a splitter, because the only