Revision: 6711 Author: [email protected] Date: Thu Nov 5 11:50:57 2009 Log: Merging /trunk c6709.
http://code.google.com/p/google-web-toolkit/source/detail?r=6711 Modified: /releases/2.0/samples/showcase/src/com/google/gwt/sample/showcase/client/content/popups/CwDialogBox.java /releases/2.0/user/javadoc/com/google/gwt/examples/DialogBoxExample.java /releases/2.0/user/src/com/google/gwt/user/client/ui/PopupPanel.java /releases/2.0/user/src/com/google/gwt/user/theme/chrome/public/gwt/chrome/chrome.css /releases/2.0/user/src/com/google/gwt/user/theme/chrome/public/gwt/chrome/chrome_rtl.css /releases/2.0/user/src/com/google/gwt/user/theme/dark/public/gwt/dark/dark.css /releases/2.0/user/src/com/google/gwt/user/theme/dark/public/gwt/dark/dark_rtl.css /releases/2.0/user/src/com/google/gwt/user/theme/standard/public/gwt/standard/standard.css /releases/2.0/user/src/com/google/gwt/user/theme/standard/public/gwt/standard/standard_rtl.css /releases/2.0/user/test/com/google/gwt/user/client/ui/PopupTest.java ======================================= --- /releases/2.0/samples/showcase/src/com/google/gwt/sample/showcase/client/content/popups/CwDialogBox.java Mon Nov 2 08:09:39 2009 +++ /releases/2.0/samples/showcase/src/com/google/gwt/sample/showcase/client/content/popups/CwDialogBox.java Thu Nov 5 11:50:57 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 ======================================= --- /releases/2.0/user/javadoc/com/google/gwt/examples/DialogBoxExample.java Thu Nov 20 14:17:44 2008 +++ /releases/2.0/user/javadoc/com/google/gwt/examples/DialogBoxExample.java Thu Nov 5 11:50:57 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"); ======================================= --- /releases/2.0/user/src/com/google/gwt/user/client/ui/PopupPanel.java Wed Nov 4 07:16:01 2009 +++ /releases/2.0/user/src/com/google/gwt/user/client/ui/PopupPanel.java Thu Nov 5 11:50:57 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? ======================================= --- /releases/2.0/user/src/com/google/gwt/user/theme/chrome/public/gwt/chrome/chrome.css Fri Jan 16 14:46:42 2009 +++ /releases/2.0/user/src/com/google/gwt/user/theme/chrome/public/gwt/chrome/chrome.css Thu Nov 5 11:50:57 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, ======================================= --- /releases/2.0/user/src/com/google/gwt/user/theme/chrome/public/gwt/chrome/chrome_rtl.css Fri Jan 16 14:46:42 2009 +++ /releases/2.0/user/src/com/google/gwt/user/theme/chrome/public/gwt/chrome/chrome_rtl.css Thu Nov 5 11:50:57 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, ======================================= --- /releases/2.0/user/src/com/google/gwt/user/theme/dark/public/gwt/dark/dark.css Fri Jan 16 14:46:42 2009 +++ /releases/2.0/user/src/com/google/gwt/user/theme/dark/public/gwt/dark/dark.css Thu Nov 5 11:50:57 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, ======================================= --- /releases/2.0/user/src/com/google/gwt/user/theme/dark/public/gwt/dark/dark_rtl.css Fri Jan 16 14:46:42 2009 +++ /releases/2.0/user/src/com/google/gwt/user/theme/dark/public/gwt/dark/dark_rtl.css Thu Nov 5 11:50:57 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, ======================================= --- /releases/2.0/user/src/com/google/gwt/user/theme/standard/public/gwt/standard/standard.css Fri Jan 16 14:46:42 2009 +++ /releases/2.0/user/src/com/google/gwt/user/theme/standard/public/gwt/standard/standard.css Thu Nov 5 11:50:57 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, ======================================= --- /releases/2.0/user/src/com/google/gwt/user/theme/standard/public/gwt/standard/standard_rtl.css Fri Jan 16 14:46:42 2009 +++ /releases/2.0/user/src/com/google/gwt/user/theme/standard/public/gwt/standard/standard_rtl.css Thu Nov 5 11:50:57 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, ======================================= --- /releases/2.0/user/test/com/google/gwt/user/client/ui/PopupTest.java Wed Oct 28 19:23:32 2009 +++ /releases/2.0/user/test/com/google/gwt/user/client/ui/PopupTest.java Thu Nov 5 11:50:57 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 -~----------~----~----~----~------~----~------~--~---
