Revision: 6709
Author: [email protected]
Date: Thu Nov 5 11:48:25 2009
Log: Adds PopupPanel.setGlassEnabled(), along with related tests and sample
changes.
Review: http://gwt-code-reviews.appspot.com/93809
http://code.google.com/p/google-web-toolkit/source/detail?r=6709
Modified:
/trunk/samples/showcase/src/com/google/gwt/sample/showcase/client/content/popups/CwDialogBox.java
/trunk/user/javadoc/com/google/gwt/examples/DialogBoxExample.java
/trunk/user/src/com/google/gwt/user/client/ui/PopupPanel.java
/trunk/user/src/com/google/gwt/user/theme/chrome/public/gwt/chrome/chrome.css
/trunk/user/src/com/google/gwt/user/theme/chrome/public/gwt/chrome/chrome_rtl.css
/trunk/user/src/com/google/gwt/user/theme/dark/public/gwt/dark/dark.css
/trunk/user/src/com/google/gwt/user/theme/dark/public/gwt/dark/dark_rtl.css
/trunk/user/src/com/google/gwt/user/theme/standard/public/gwt/standard/standard.css
/trunk/user/src/com/google/gwt/user/theme/standard/public/gwt/standard/standard_rtl.css
/trunk/user/test/com/google/gwt/user/client/ui/PopupTest.java
=======================================
---
/trunk/samples/showcase/src/com/google/gwt/sample/showcase/client/content/popups/CwDialogBox.java
Mon Nov 2 07:51:58 2009
+++
/trunk/samples/showcase/src/com/google/gwt/sample/showcase/client/content/popups/CwDialogBox.java
Thu Nov 5 11:48:25 2009
@@ -102,6 +102,7 @@
public Widget onInitialize() {
// Create the dialog box
final DialogBox dialogBox = createDialogBox();
+ dialogBox.setGlassEnabled(true);
dialogBox.setAnimationEnabled(true);
// Create a button to show the dialog Box
=======================================
--- /trunk/user/javadoc/com/google/gwt/examples/DialogBoxExample.java Thu
Nov 20 14:17:44 2008
+++ /trunk/user/javadoc/com/google/gwt/examples/DialogBoxExample.java Thu
Nov 5 11:48:25 2009
@@ -30,6 +30,12 @@
// Set the dialog box's caption.
setText("My First Dialog");
+ // Enable animation.
+ setAnimationEnabled(true);
+
+ // Enable glass background.
+ setGlassEnabled(true);
+
// DialogBox is a SimplePanel, so you have to set its widget
property to
// whatever you want its contents to be.
Button ok = new Button("OK");
=======================================
--- /trunk/user/src/com/google/gwt/user/client/ui/PopupPanel.java Wed Oct
28 12:55:56 2009
+++ /trunk/user/src/com/google/gwt/user/client/ui/PopupPanel.java Thu Nov
5 11:48:25 2009
@@ -21,9 +21,15 @@
import com.google.gwt.dom.client.Element;
import com.google.gwt.dom.client.EventTarget;
import com.google.gwt.dom.client.NativeEvent;
+import com.google.gwt.dom.client.Style;
+import com.google.gwt.dom.client.Style.Display;
+import com.google.gwt.dom.client.Style.Position;
+import com.google.gwt.dom.client.Style.Unit;
import com.google.gwt.event.logical.shared.CloseEvent;
import com.google.gwt.event.logical.shared.CloseHandler;
import com.google.gwt.event.logical.shared.HasCloseHandlers;
+import com.google.gwt.event.logical.shared.ResizeEvent;
+import com.google.gwt.event.logical.shared.ResizeHandler;
import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.i18n.client.LocaleInfo;
import com.google.gwt.user.client.Command;
@@ -67,6 +73,8 @@
* <dd>the outside of the popup</dd>
* <dt>.gwt-PopupPanel .popupContent</dt>
* <dd>the wrapper around the content</dd>
+ * <dt>.gwt-PopupGlass</dt>
+ * <dd>the glass background behind the popup</dd>
* </dl>
*/
@SuppressWarnings("deprecation")
@@ -97,8 +105,8 @@
*
* <ul>
* <li>CENTER - Expand from the center of the popup</li>
- * <li>ONE_WAY_CORNER - Expand from the top left corner, do not animate
- * hiding </li>
+ * <li>ONE_WAY_CORNER - Expand from the top left corner, do not animate
hiding
+ * </li>
* </ul>
*/
static enum AnimationType {
@@ -122,7 +130,12 @@
/**
* A boolean indicating whether we are showing or hiding the popup.
*/
- private boolean showing = false;
+ private boolean showing;
+
+ /**
+ * A boolean indicating whether the glass element is currently
attached.
+ */
+ private boolean glassShowing;
/**
* Create a new {...@link ResizeAnimation}.
@@ -157,6 +170,8 @@
// the animation. If we move this to onStart, the animation will
look
// choppy or not run at all.
if (showing) {
+ maybeShowGlass();
+
// Set the position attribute, and then attach to the DOM.
Otherwise,
// the PopupPanel will appear to 'jump' from its static/relative
// position to its absolute position (issue #1231).
@@ -184,6 +199,7 @@
@Override
protected void onComplete() {
if (!showing) {
+ maybeShowGlass();
RootPanel.get().remove(curPanel);
impl.onHide(curPanel.getElement());
}
@@ -243,8 +259,27 @@
return "rect(" + top + "px, " + right + "px, " + bottom + "px, " +
left
+ "px)";
}
+
+ /**
+ * Show or hide the glass.
+ */
+ private void maybeShowGlass() {
+ if (showing) {
+ if (curPanel.isGlassEnabled) {
+ Document.get().getBody().appendChild(curPanel.glass);
+ glassShowing = true;
+
+ Window.addResizeHandler(curPanel.glassResizer);
+ curPanel.glassResizer.onResize(null);
+ }
+ } else if (glassShowing) {
+ Document.get().getBody().removeChild(curPanel.glass);
+ glassShowing = false;
+ }
+ }
private void onInstantaneousRun() {
+ maybeShowGlass();
if (showing) {
// Set the position attribute, and then attach to the DOM.
Otherwise,
// the PopupPanel will appear to 'jump' from its static/relative
@@ -275,6 +310,35 @@
private static final PopupImpl impl = GWT.create(PopupImpl.class);
+ /**
+ * Window resize handler used to keep the glass the proper size.
+ */
+ private ResizeHandler glassResizer = new ResizeHandler() {
+ public void onResize(ResizeEvent event) {
+ Style style = glass.getStyle();
+
+ int winWidth = Window.getClientWidth();
+ int winHeight = Window.getClientHeight();
+
+ // Hide the glass while checking the document size. Otherwise it
would
+ // interfere with the measurement.
+ style.setDisplay(Display.NONE);
+ style.setWidth(0, Unit.PX);
+ style.setHeight(0, Unit.PX);
+
+ int width = Document.get().getScrollWidth();
+ int height = Document.get().getScrollHeight();
+
+ // Set the glass size to the larger of the window's client size or
the
+ // document's scroll size.
+ style.setWidth(Math.max(width, winWidth), Unit.PX);
+ style.setHeight(Math.max(height, winHeight), Unit.PX);
+
+ // The size is set. Show the glass again.
+ style.setDisplay(Display.BLOCK);
+ }
+ };
+
/**
* If true, animate the opening of this popup from the center. If false,
* animate it open from top to bottom, and do not animate closing. Use
false
@@ -291,6 +355,16 @@
private String desiredWidth;
+ /**
+ * The glass element.
+ */
+ private Element glass;
+
+ /**
+ * A boolean indicating that a glass element should be used.
+ */
+ private boolean isGlassEnabled;
+
private boolean isAnimationEnabled = false;
// the left style attribute in pixels
@@ -479,14 +553,24 @@
}
/**
- * Returns <code>true</code> if the popup should be automatically hidden
- * when the user clicks outside of it.
+ * Returns <code>true</code> if the popup should be automatically hidden
when
+ * the user clicks outside of it.
*
* @return true if autoHide is enabled, false if disabled
*/
public boolean isAutoHideEnabled() {
return autoHide;
}
+
+ /**
+ * Returns <code>true</code> if a glass element will be displayed under
+ * the {...@link PopupPanel}.
+ *
+ * @return true if enabled
+ */
+ public boolean isGlassEnabled() {
+ return isGlassEnabled;
+ }
/**
* Returns <code>true</code> if keyboard or mouse events that do not
target
@@ -599,8 +683,8 @@
}
/**
- * @deprecated Use the {...@link HandlerRegistration#removeHandler}
- * method on the object returned by {...@link #addCloseHandler} instead
+ * @deprecated Use the {...@link HandlerRegistration#removeHandler} method
on the
+ * object returned by {...@link #addCloseHandler} instead
*/
@Deprecated
public void removePopupListener(PopupListener listener) {
@@ -620,6 +704,25 @@
public void setAutoHideEnabled(boolean autoHide) {
this.autoHide = autoHide;
}
+
+ /**
+ * When enabled, the background will be blocked with a semi-transparent
pane
+ * the next time it is shown. If the PopupPanel is already visible, the
+ * glass will not be displayed until it is hidden and shown again.
+ *
+ * @param enabled true to enable, false to disable
+ */
+ public void setGlassEnabled(boolean enabled) {
+ this.isGlassEnabled = enabled;
+ if (enabled && glass == null) {
+ glass = Document.get().createDivElement();
+ glass.setClassName("gwt-PopupGlass");
+
+ glass.getStyle().setPosition(Position.ABSOLUTE);
+ glass.getStyle().setLeft(0, Unit.PX);
+ glass.getStyle().setTop(0, Unit.PX);
+ }
+ }
/**
* Sets the height of the panel's child widget. If the panel's child
widget
@@ -730,8 +833,8 @@
* <code>visibility</code> style attribute. You need to call {...@link
#show()}
* to actually attached/detach the {...@link PopupPanel} to the page.
*
- * @param visible <code>true</code> to show the object,
<code>false</code>
- * to hide it
+ * @param visible <code>true</code> to show the object,
<code>false</code> to
+ * hide it
* @see #show()
* @see #hide()
*/
@@ -813,6 +916,16 @@
protected com.google.gwt.user.client.Element getContainerElement() {
return impl.getContainerElement(getPopupImplElement());
}
+
+ /**
+ * Get the glass element used by this {...@link PopupPanel}. The element is
not
+ * created until it is enabled via {...@link #setGlassEnabled(boolean)}.
+ *
+ * @return the glass element, or null if not created
+ */
+ protected Element getGlassElement() {
+ return glass;
+ }
@Override
protected com.google.gwt.user.client.Element getStyleElement() {
@@ -889,11 +1002,11 @@
* @param elt The Element on which <code>blur()</code> will be invoked
*/
private native void blur(Element elt) /*-{
- // Issue 2390: blurring the body causes IE to disappear to the
background
- if (elt.blur && elt != $doc.body) {
- elt.blur();
- }
- }-*/;
+ // Issue 2390: blurring the body causes IE to disappear to the
background
+ if (elt.blur && elt != $doc.body) {
+ elt.blur();
+ }
+ }-*/;
/**
* Does the event target one of the partner elements?
=======================================
---
/trunk/user/src/com/google/gwt/user/theme/chrome/public/gwt/chrome/chrome.css
Fri Jan 16 14:46:42 2009
+++
/trunk/user/src/com/google/gwt/user/theme/chrome/public/gwt/chrome/chrome.css
Thu Nov 5 11:48:25 2009
@@ -478,6 +478,12 @@
height: 8px;
overflow: hidden;
}
+
+.gwt-PopupGlass {
+ background-color: #000;
+ opacity: 0.3;
+ filter: alpha(opacity=30);
+}
.gwt-PushButton-up,
.gwt-PushButton-up-hovering,
=======================================
---
/trunk/user/src/com/google/gwt/user/theme/chrome/public/gwt/chrome/chrome_rtl.css
Fri Jan 16 14:46:42 2009
+++
/trunk/user/src/com/google/gwt/user/theme/chrome/public/gwt/chrome/chrome_rtl.css
Thu Nov 5 11:48:25 2009
@@ -478,6 +478,12 @@
height: 8px;
overflow: hidden;
}
+
+.gwt-PopupGlass {
+ background-color: #000;
+ opacity: 0.3;
+ filter: alpha(opacity=30);
+}
.gwt-PushButton-up,
.gwt-PushButton-up-hovering,
=======================================
--- /trunk/user/src/com/google/gwt/user/theme/dark/public/gwt/dark/dark.css
Fri Jan 16 14:46:42 2009
+++ /trunk/user/src/com/google/gwt/user/theme/dark/public/gwt/dark/dark.css
Thu Nov 5 11:48:25 2009
@@ -462,6 +462,12 @@
height: 8px;
overflow: hidden;
}
+
+.gwt-PopupGlass {
+ background-color: #0cf;
+ opacity: 0.3;
+ filter: alpha(opacity=30);
+}
.gwt-PushButton-up,
.gwt-PushButton-up-hovering,
=======================================
---
/trunk/user/src/com/google/gwt/user/theme/dark/public/gwt/dark/dark_rtl.css
Fri Jan 16 14:46:42 2009
+++
/trunk/user/src/com/google/gwt/user/theme/dark/public/gwt/dark/dark_rtl.css
Thu Nov 5 11:48:25 2009
@@ -462,6 +462,12 @@
height: 8px;
overflow: hidden;
}
+
+.gwt-PopupGlass {
+ background-color: #0cf;
+ opacity: 0.3;
+ filter: alpha(opacity=30);
+}
.gwt-PushButton-up,
.gwt-PushButton-up-hovering,
=======================================
---
/trunk/user/src/com/google/gwt/user/theme/standard/public/gwt/standard/standard.css
Fri Jan 16 14:46:42 2009
+++
/trunk/user/src/com/google/gwt/user/theme/standard/public/gwt/standard/standard.css
Thu Nov 5 11:48:25 2009
@@ -478,6 +478,12 @@
height: 8px;
overflow: hidden;
}
+
+.gwt-PopupGlass {
+ background-color: #000;
+ opacity: 0.3;
+ filter: alpha(opacity=30);
+}
.gwt-PushButton-up,
.gwt-PushButton-up-hovering,
=======================================
---
/trunk/user/src/com/google/gwt/user/theme/standard/public/gwt/standard/standard_rtl.css
Fri Jan 16 14:46:42 2009
+++
/trunk/user/src/com/google/gwt/user/theme/standard/public/gwt/standard/standard_rtl.css
Thu Nov 5 11:48:25 2009
@@ -478,6 +478,12 @@
height: 8px;
overflow: hidden;
}
+
+.gwt-PopupGlass {
+ background-color: #000;
+ opacity: 0.3;
+ filter: alpha(opacity=30);
+}
.gwt-PushButton-up,
.gwt-PushButton-up-hovering,
=======================================
--- /trunk/user/test/com/google/gwt/user/client/ui/PopupTest.java Mon Oct
26 18:35:41 2009
+++ /trunk/user/test/com/google/gwt/user/client/ui/PopupTest.java Thu Nov
5 11:48:25 2009
@@ -17,10 +17,12 @@
import com.google.gwt.dom.client.DivElement;
import com.google.gwt.dom.client.Document;
+import com.google.gwt.dom.client.Element;
+import com.google.gwt.event.logical.shared.CloseEvent;
+import com.google.gwt.event.logical.shared.CloseHandler;
import com.google.gwt.junit.DoNotRunWith;
import com.google.gwt.junit.Platform;
import com.google.gwt.junit.client.GWTTestCase;
-import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.Timer;
import com.google.gwt.user.client.Window;
@@ -50,7 +52,7 @@
}
@Override
- public Element getContainerElement() {
+ public com.google.gwt.user.client.Element getContainerElement() {
return super.getContainerElement();
}
@@ -171,6 +173,81 @@
testDependantPopupPanel(primaryPopup);
}
+
+ public void testGlassPanelDisabled() {
+ // Verify that the glass is disabled by default
+ PopupPanel popup = createPopupPanel();
+ assertFalse(popup.isGlassEnabled());
+ assertNull(popup.getGlassElement());
+
+ // Verify the glass panel is never created
+ popup.show();
+ assertNull(popup.getGlassElement());
+ popup.hide();
+ }
+
+ public void testGlassDisabledWhileShowing() {
+ // Show the popup and glass panel
+ PopupPanel popup = createPopupPanel();
+ popup.setGlassEnabled(true);
+ Element glass = popup.getGlassElement();
+ popup.show();
+
+ // Disable the glass panel and hide the popup
+ popup.setGlassEnabled(false);
+ assertTrue(isAttached(glass));
+ popup.hide();
+ assertFalse(isAttached(glass));
+
+ // Show the popup and verify that glass is no longer used
+ popup.show();
+ assertFalse(isAttached(glass));
+ popup.hide();
+ }
+
+ public void testGlassEnabled() {
+ // Verify that the glass is disabled by default
+ PopupPanel popup = createPopupPanel();
+ assertFalse(popup.isGlassEnabled());
+ assertNull(popup.getGlassElement());
+
+ // Enable the glass panel and verify it is created
+ popup.setGlassEnabled(true);
+ Element glass = popup.getGlassElement();
+ assertNotNull(glass);
+ assertFalse(isAttached(glass));
+
+ // Show the popup and verify the glass panel is added
+ popup.show();
+ assertTrue(isAttached(glass));
+
+ // Hide the popup and verify the glass panel is removed
+ popup.hide();
+ assertFalse(isAttached(glass));
+ }
+
+ public void testGlassEnabledWhileShowing() {
+ // Verify that the glass is disabled by default
+ PopupPanel popup = createPopupPanel();
+ assertFalse(popup.isGlassEnabled());
+ assertNull(popup.getGlassElement());
+
+ // Show the popup and enable the glass panel
+ popup.show();
+ popup.setGlassEnabled(true);
+ Element glass = popup.getGlassElement();
+ assertNotNull(glass);
+ assertFalse(isAttached(glass));
+
+ // Hide the popup and verify the glass panel is removed
+ popup.hide();
+ assertFalse(isAttached(glass));
+
+ // Show the popup and verify the glas is now used
+ popup.show();
+ assertTrue(isAttached(glass));
+ popup.hide();
+ }
/**
* Test that the onLoad method is only called once when showing the
popup.
@@ -256,8 +333,8 @@
// Ensure that hiding the popup fires the appropriate events.
delayTestFinish(1000);
- popup.addPopupListener(new PopupListener() {
- public void onPopupClosed(PopupPanel sender, boolean autoClosed) {
+ popup.addCloseHandler(new CloseHandler<PopupPanel>() {
+ public void onClose(CloseEvent<PopupPanel> event) {
finishTest();
}
});
@@ -342,4 +419,8 @@
}
}.schedule(2000);
}
-}
+
+ private boolean isAttached(Element elem) {
+ return Document.get().getBody().isOrHasChild(elem);
+ }
+}
--~--~---------~--~----~------------~-------~--~----~
http://groups.google.com/group/Google-Web-Toolkit-Contributors
-~----------~----~----~----~------~----~------~--~---