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
-~----------~----~----~----~------~----~------~--~---

Reply via email to