Replaced PopupPanel#setAutoHidePartner() with PopupPanel#addAutoHidePartner() so multiple partners can be specified.
Patch by: jlabanca
Review by: ecc
Issue: 3254
git-svn-id: https://google-web-toolkit.googlecode.com/svn/releases/1.6@4394 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/reference/code-museum/src/com/google/gwt/museum/client/defaultmuseum/VisualsForPopupEvents.java b/reference/code-museum/src/com/google/gwt/museum/client/defaultmuseum/VisualsForPopupEvents.java
index ffa898a..81fa475 100644
--- a/reference/code-museum/src/com/google/gwt/museum/client/defaultmuseum/VisualsForPopupEvents.java
+++ b/reference/code-museum/src/com/google/gwt/museum/client/defaultmuseum/VisualsForPopupEvents.java
@@ -24,12 +24,14 @@
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.HTML;
+import com.google.gwt.user.client.ui.HorizontalPanel;
+import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.PopupPanel;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;
/**
- * A simple tree used to quickly exercise tree behavior.
+ * Visual tests for {@link PopupPanel}.
*/
public class VisualsForPopupEvents extends AbstractIssue {
static int xPos = 0;
@@ -37,10 +39,26 @@
@Override
public Widget createIssue() {
VerticalPanel panel = new VerticalPanel();
+ panel.setSpacing(3);
+ {
+ PopupPanel popup = createButton(true, false, panel);
+ Label partner0 = new Label("AutoHide Partner 0");
+ Label partner1 = new Label("AutoHide Partner 1");
+ popup.addAutoHidePartner(partner0.getElement());
+ popup.addAutoHidePartner(partner1.getElement());
+
+ HorizontalPanel hPanel = new HorizontalPanel();
+ hPanel.setBorderWidth(1);
+ hPanel.setSpacing(3);
+ hPanel.add(partner0);
+ hPanel.add(partner1);
+ panel.add(new Label(
+ "Clicking on partners should not autoHide this popup:"));
+ panel.add(hPanel);
+ }
createButton(true, true, panel);
- createButton(true, false, panel);
- createButton(false, true, panel);
createButton(false, false, panel);
+ createButton(false, true, panel);
return panel;
}
@@ -59,7 +77,8 @@
return false;
}
- private void createButton(boolean autoHide, boolean modal, VerticalPanel panel) {
+ private PopupPanel createButton(boolean autoHide, boolean modal,
+ VerticalPanel panel) {
final String text = " popup " + (modal ? " modal " : " non-modal ")
+ (autoHide ? "auto hide" : " persistent");
panel.add(new HTML("<h2>" + text + "</h2>"));
@@ -85,5 +104,7 @@
+ event.isAutoClosed());
}
});
+
+ return p;
}
}
\ No newline at end of file
diff --git a/user/src/com/google/gwt/user/client/ui/PopupPanel.java b/user/src/com/google/gwt/user/client/ui/PopupPanel.java
index 105b3be..6ed6891 100644
--- a/user/src/com/google/gwt/user/client/ui/PopupPanel.java
+++ b/user/src/com/google/gwt/user/client/ui/PopupPanel.java
@@ -34,6 +34,9 @@
import com.google.gwt.user.client.Event.NativePreviewHandler;
import com.google.gwt.user.client.ui.impl.PopupImpl;
+import java.util.ArrayList;
+import java.util.List;
+
/**
* A panel that can "pop up" over other widgets. It overlays the browser's
* client area (and any previously-created popups).
@@ -280,7 +283,7 @@
private boolean isAnimationEnabled = false;
- private Element autoHidePartner;
+ private List<Element> autoHidePartners;
/**
* The {@link ResizeAnimation} used to open and close the {@link PopupPanel}s.
@@ -334,6 +337,20 @@
this.modal = modal;
}
+ /**
+ * Mouse events that occur within an autoHide partner will not hide a panel
+ * set to autoHide.
+ *
+ * @param partner the auto hide partner to add
+ */
+ public void addAutoHidePartner(Element partner) {
+ assert partner != null : "partner cannot be null";
+ if (autoHidePartners == null) {
+ autoHidePartners = new ArrayList<Element>();
+ }
+ autoHidePartners.add(partner);
+ }
+
public HandlerRegistration addCloseHandler(CloseHandler<PopupPanel> handler) {
return addHandler(handler, CloseEvent.getType());
}
@@ -536,6 +553,18 @@
return true;
}
+ /**
+ * Remove an autoHide partner.
+ *
+ * @param partner the auto hide partner to remove
+ */
+ public void removeAutoHidePartner(Element partner) {
+ assert partner != null : "partner cannot be null";
+ if (autoHidePartners != null) {
+ autoHidePartners.remove(partner);
+ }
+ }
+
@Deprecated
public void removePopupListener(PopupListener listener) {
ListenerWrapper.Popup.remove(this, listener);
@@ -556,16 +585,6 @@
}
/**
- * If the auto hide partner is non null, its mouse events will not hide a
- * panel set to autohide.
- *
- * @param element new auto hide partner
- */
- public void setAutoHidePartner(Element element) {
- this.autoHidePartner = element;
- }
-
- /**
* Sets the height of the panel's child widget. If the panel's child widget
* has not been set, the height passed in will be cached and used to set the
* height immediately after the child widget is set.
@@ -834,14 +853,23 @@
}-*/;
/**
- * Does the event target the partner element?
+ * Does the event target one of the partner elements?
*
* @param event the native event
- * @return true if the event targets the partner
+ * @return true if the event targets a partner
*/
private boolean eventTargetsPartner(Event event) {
- return autoHidePartner != null
- && autoHidePartner.isOrHasChild(event.getTarget());
+ if (autoHidePartners == null) {
+ return false;
+ }
+
+ Element target = event.getTarget();
+ for (Element elem : autoHidePartners) {
+ if (elem.isOrHasChild(target)) {
+ return true;
+ }
+ }
+ return false;
}
/**
@@ -855,7 +883,7 @@
}
/**
- * Get the element that {@link PopupImpl} uses. PopupImpl creates an element
+ * Get the element that {@link PopupImpl} uses. PopupImpl creates an element
* that goes inside of the outer element, so all methods in PopupImpl are
* relative to the first child of the outer element, not the outer element
* itself.
@@ -867,7 +895,8 @@
}
/**
- * Positions the popup, called after the offset width and height of the popup are known.
+ * Positions the popup, called after the offset width and height of the popup
+ * are known.
*
* @param relativeObject the ui object to position relative to
* @param offsetWidth the drop down's offset width
diff --git a/user/src/com/google/gwt/user/datepicker/client/DateBox.java b/user/src/com/google/gwt/user/datepicker/client/DateBox.java
index d9fc83d..4e5a6a4 100644
--- a/user/src/com/google/gwt/user/datepicker/client/DateBox.java
+++ b/user/src/com/google/gwt/user/datepicker/client/DateBox.java
@@ -267,7 +267,7 @@
this.format = format;
popup.setAutoHideEnabled(true);
- popup.setAutoHidePartner(box.getElement());
+ popup.addAutoHidePartner(box.getElement());
popup.setWidget(picker);
popup.setStyleName("dateBoxPopup");
diff --git a/user/test/com/google/gwt/user/client/ui/PopupTest.java b/user/test/com/google/gwt/user/client/ui/PopupTest.java
index 8aa91e3..4285ea6 100644
--- a/user/test/com/google/gwt/user/client/ui/PopupTest.java
+++ b/user/test/com/google/gwt/user/client/ui/PopupTest.java
@@ -15,6 +15,8 @@
*/
package com.google.gwt.user.client.ui;
+import com.google.gwt.dom.client.DivElement;
+import com.google.gwt.dom.client.Document;
import com.google.gwt.junit.client.GWTTestCase;
import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.Timer;
@@ -82,6 +84,18 @@
assertFalse(popup.isPreviewingAllNativeEvents());
}
+ public void testAutoHidePartner() {
+ final PopupPanel popup = new PopupPanel();
+
+ // Add a partner
+ DivElement partner0 = Document.get().createDivElement();
+ popup.addAutoHidePartner(partner0);
+ popup.addAutoHidePartner(Document.get().createDivElement());
+
+ // Remove a partner
+ popup.removeAutoHidePartner(partner0);
+ }
+
/**
* Issue 2463: If a {@link PopupPanel} contains a dependent {@link PopupPanel}
* that is hidden or shown in the onDetach or onAttach method, we could run