Revision: 6387
Author: [email protected]
Date: Thu Oct 15 18:41:37 2009
Log: DisclosurePanel now does  ImageResource and is nice in UiBinder.

Deprecates many of its convience constructors--necessary for
UiBinder sanity, and just plain good API hygiene.

Reviewed by: jgw
http://code.google.com/p/google-web-toolkit/source/detail?r=6387

Added:
  /trunk/user/src/com/google/gwt/uibinder/sample/client/down.png
  /trunk/user/src/com/google/gwt/uibinder/sample/client/right.png
Modified:
  /trunk/user/src/com/google/gwt/uibinder/parsers/DisclosurePanelParser.java
  /trunk/user/src/com/google/gwt/uibinder/sample/client/WidgetBasedUi.ui.xml
  /trunk/user/src/com/google/gwt/user/client/ui/DisclosurePanel.java
  /trunk/user/src/com/google/gwt/user/client/ui/DisclosurePanelImages.java
  /trunk/user/src/com/google/gwt/user/client/ui/DisclosurePanelImagesRTL.java

=======================================
--- /dev/null   
+++ /trunk/user/src/com/google/gwt/uibinder/sample/client/down.png      Thu Oct 
 
15 18:41:37 2009
Binary file, no diff available.
=======================================
--- /dev/null   
+++ /trunk/user/src/com/google/gwt/uibinder/sample/client/right.png     Thu Oct 
 
15 18:41:37 2009
Binary file, no diff available.
=======================================
---  
/trunk/user/src/com/google/gwt/uibinder/parsers/DisclosurePanelParser.java      
 
Tue Sep  1 15:14:29 2009
+++  
/trunk/user/src/com/google/gwt/uibinder/parsers/DisclosurePanelParser.java      
 
Thu Oct 15 18:41:37 2009
@@ -1,12 +1,12 @@
  /*
- * Copyright 2007 Google Inc.
- *
+ * Copyright 2009 Google Inc.
+ *
   * Licensed under the Apache License, Version 2.0 (the "License"); you may  
not
   * use this file except in compliance with the License. You may obtain a  
copy of
   * the License at
- *
+ *
   * http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,  
WITHOUT
   * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
@@ -19,100 +19,134 @@
  import com.google.gwt.core.ext.typeinfo.JClassType;
  import com.google.gwt.uibinder.rebind.UiBinderWriter;
  import com.google.gwt.uibinder.rebind.XMLElement;
-import com.google.gwt.user.client.ui.DisclosurePanel;

  /**
   * Parses {...@link com.google.gwt.user.client.ui.DisclosurePanel} widgets.
   */
  public class DisclosurePanelParser implements ElementParser {

-  private static final String ATTRIBUTE_HEADER_WIDGET  
= "DisclosurePanel-header";
-
-  private static final String ATTRIBUTE_HEADER_BUNDLE = "imageBundle";
-
-  private static final String ATTRIBUTE_INITIALLY_OPEN = "initiallyOpen";
-
-  private static final String ATTRIBUTE_ENABLE_ANIMATION  
= "enableAnimation";
-
-  /**
-   * @return the type oracle's DisclosurePanel class
-   */
-  private static JClassType getDisclosurePanelClass(UiBinderWriter w) {
-    return w.getOracle().findType(DisclosurePanel.class.getName());
-  }
-
-  public void parse(XMLElement elem, String fieldName, JClassType type,
-      UiBinderWriter writer) throws UnableToCompleteException {
-
-    String text = null;
-    // They must specify a label
-    if (elem.hasAttribute("text")) {
-      text = elem.consumeAttribute("text");
-      text = '"' + UiBinderWriter.escapeTextForJavaStringLiteral(text)  
+ '"';
+  private static class Children {
+    XMLElement body;
+    XMLElement header;
+    XMLElement customHeader;
+  }
+
+  private static final String CUSTOM = "customHeader";
+  private static final String HEADER = "header";
+  private static final String OPEN_IMAGE = "openImage";
+
+  private static final String CLOSED_IMAGE = "closedImage";
+
+  public void parse(final XMLElement panelElem, String panelField,
+      JClassType type, final UiBinderWriter writer)
+      throws UnableToCompleteException {
+    Children children = findChildren(panelElem, writer);
+
+    if (null != children.body) {
+      if (!writer.isWidgetElement(children.body)) {
+        writer.die("In %s, %s must be a widget", panelElem, children.body);
+      }
+
+      String bodyField = writer.parseElementToField(children.body);
+      writer.addInitStatement("%s.add(%s);", panelField, bodyField);
      }

-    // They may specify an image bundle
-    String imageBundle = null;
-    if (elem.hasAttribute(ATTRIBUTE_HEADER_BUNDLE)) {
-      imageBundle = elem.consumeAttribute(ATTRIBUTE_HEADER_BUNDLE);
-    }
-
-    // They may specify an initial closed state
-    String initiallyOpen = "false";
-    if (elem.hasAttribute(ATTRIBUTE_INITIALLY_OPEN)) {
-      initiallyOpen = elem.consumeAttribute(ATTRIBUTE_INITIALLY_OPEN);
+    if (null != children.customHeader) {
+      XMLElement headerElement =  
children.customHeader.consumeSingleChildElement();
+
+      if (!writer.isWidgetElement(headerElement)) {
+        writer.die("In %s of %s, %s is not a widget",  
children.customHeader,
+            panelElem, headerElement);
+      }
+
+      String headerField = writer.parseElementToField(headerElement);
+      writer.addInitStatement("%s.setHeader(%s);", panelField,  
headerField);
      }

-    // They may enable animation
-    String enableAnimation = "true";
-    if (elem.hasAttribute(ATTRIBUTE_ENABLE_ANIMATION)) {
-      enableAnimation = elem.consumeAttribute(ATTRIBUTE_ENABLE_ANIMATION);
-    }
-
-    String childFieldName = null;
-    String headerFieldName = null;
-
-    for (XMLElement child : elem.consumeChildElements()) {
-      // Disclosure panel header optionally comes from the  
DisclosurePanel-header attribute of the
-      // child
-      boolean childIsHeader = false;
-      String headerAttributeName = elem.getPrefix() + ":" +  
ATTRIBUTE_HEADER_WIDGET;
-      if (child.hasAttribute(headerAttributeName)) {
-        if (headerFieldName != null) {
-          writer.die("In %s, DisclosurePanel cannot contain more than one  
header widget.", elem);
-        }
-        child.consumeAttribute(headerAttributeName);
-        headerFieldName = writer.parseElementToField(child);
-        childIsHeader = true;
-      }
-      if (!childIsHeader) {
-        if (childFieldName != null) {
-          writer.die("In %s, DisclosurePanel cannot contain more than one  
content widget.", elem);
-        }
-        childFieldName = writer.parseElementToField(child);
-      }
-    }
-
-    // To use the image bundle, you must provide a text header.
-    if (imageBundle != null) {
-      writer.setFieldInitializerAsConstructor(fieldName,
-          getDisclosurePanelClass(writer), imageBundle, (text != null ?  
text : "\"\""),
-          initiallyOpen);
-    } else {
-      JClassType panelClass = getDisclosurePanelClass(writer);
-      if (text != null) {
-        writer.setFieldInitializerAsConstructor(fieldName, panelClass,  
text);
-      } else {
-        writer.setFieldInitializerAsConstructor(fieldName, panelClass);
-      }
-    }
-    if (childFieldName != null) {
-      writer.addStatement("%1$s.setContent(%2$s);", fieldName,  
childFieldName);
-    }
-    if (headerFieldName != null) {
-      writer.addStatement("%1$s.setHeader(%2$s);", fieldName,  
headerFieldName);
-    }
-    writer.addStatement("%1$s.setAnimationEnabled(%2$s);", fieldName,  
enableAnimation);
-    writer.addStatement("%1$s.setOpen(%2$s);", fieldName, initiallyOpen);
+    if (null != children.header) {
+      String openImage = getAttribute(OPEN_IMAGE, children.header, writer);
+      String closedImage = getAttribute(CLOSED_IMAGE, children.header,  
writer);
+      String headerText =  
children.header.consumeInnerTextEscapedAsHtmlStringLiteral(new  
TextInterpreter(
+          writer));
+
+      if ((openImage == null || closedImage == null)
+          && !(openImage == closedImage)) {
+        writer.die("In %s of %s, both %s and %s must be specified, or  
neither",
+            children.header, panelElem, OPEN_IMAGE, CLOSED_IMAGE);
+      }
+
+      String panelTypeName = type.getQualifiedSourceName();
+      if (openImage != null) {
+        writer.setFieldInitializer(panelField, String.format(
+            "new %s(%s, %s, \"%s\")", panelTypeName, openImage,  
closedImage,
+            headerText));
+      } else {
+        writer.setFieldInitializer(panelField,  
String.format("new %s(\"%s\")",
+            panelTypeName, headerText));
+      }
+    }
+  }
+
+  private Children findChildren(final XMLElement elem,
+      final UiBinderWriter writer) throws UnableToCompleteException {
+    final Children children = new Children();
+
+    elem.consumeChildElements(new XMLElement.Interpreter<Boolean>() {
+      public Boolean interpretElement(XMLElement child)
+          throws UnableToCompleteException {
+
+        if (hasAttribute(child, HEADER)) {
+          assertFirstHeader();
+          children.header = child;
+          return true;
+        }
+
+        if (hasAttribute(child, CUSTOM)) {
+          assertFirstHeader();
+          children.customHeader = child;
+          return true;
+        }
+
+        // Must be the body, then
+        if (null != children.body) {
+          writer.die("In %s, may have only one body element", elem);
+        }
+
+        children.body = child;
+        return true;
+      }
+
+      void assertFirstHeader() throws UnableToCompleteException {
+        if ((null != children.header) && (null != children.customHeader)) {
+          writer.die("In %1$s, may have only one %2$s:header "
+              + "or %2$s:customHeader", elem, elem.getPrefix());
+        }
+      }
+
+      private boolean hasAttribute(XMLElement child, final String  
attribute) {
+        return rightNamespace(child) &&  
child.getLocalName().equals(attribute);
+      }
+
+      private boolean rightNamespace(XMLElement child) {
+        return child.getNamespaceUri().equals(elem.getNamespaceUri());
+      }
+    });
+
+    return children;
+  }
+
+  /**
+   * @return a field reference or a null string if the attribute is unset
+   * @throws UnableToCompleteException on bad value
+   */
+  private String getAttribute(String attribute, XMLElement headerElem,
+      UiBinderWriter writer) throws UnableToCompleteException {
+    // TODO(rjrjr) parser should come from XMLElement
+
+    String value = headerElem.consumeAttribute(attribute, null);
+    if (value != null) {
+      value = new StrictAttributeParser().parse(value, writer);
+    }
+    return value;
    }
  }
=======================================
---  
/trunk/user/src/com/google/gwt/uibinder/sample/client/WidgetBasedUi.ui.xml      
 
Tue Oct 13 13:41:12 2009
+++  
/trunk/user/src/com/google/gwt/uibinder/sample/client/WidgetBasedUi.ui.xml      
 
Thu Oct 15 18:41:37 2009
@@ -126,6 +126,8 @@
  </ui:style>
  <ui:image field='prettyImage' />
  <ui:image field='prettyTilingImage' src='prettyImage.png' flipRtl='true'  
repeatStyle='Both'/>
+<ui:image field='right'/>
+<ui:image field='down'/>

  <gwt:DockPanel ui:field="root" width="100%">
    <gwt:Dock direction='NORTH'>
@@ -257,6 +259,7 @@
          <gwt:Tree ui:field='myTree' width="100px" />

        <p>...TextBoxes...</p>
+
        <gwt:TextBox maxLength="21">21 chars only, please</gwt:TextBox>

        <p>...or perhaps a handful of RadioButtons:</p>
@@ -270,7 +273,9 @@
          text="Charlie (this one is a subclass of RadioButton)">
          <ui:attribute name="text" description="radio button name"/>
        </demo:PointlessRadioButtonSubclass>
+
        <p> ... a StackPanel ... </p>
+
        <gwt:StackPanel stylePrimaryName="myStyle" width="280px"  
ui:field='myStackPanel'>
          <gwt:Label text="Stack One Text"  gwt:StackPanel-text="Stack One"
              ui:field='myStackPanelItem'>
@@ -287,47 +292,94 @@
          </gwt:HTMLPanel>
          <gwt:Label text="Stack Three Text"  gwt:StackPanel-text="Stack  
Three" />
        </gwt:StackPanel>
+
        <p> ... a DisclosurePanel with a text header ... </p>
-      <gwt:DisclosurePanel text="I just have a text header"  
ui:field='myDisclosurePanel'>
-        <!--ui:attribute name="text" description="Label for Disclosure  
One"/ -->
-        <gwt:Label text="Disclosure Text" ui:field='myDisclosurePanelItem'>
-          <ui:attribute name="text" description="Content for Disclosure  
One Text"/>
-        </gwt:Label>
+
+      <gwt:DisclosurePanel ui:field='myDisclosurePanel'  
animationEnabled='true'>
+        <gwt:header>
+          <ui:msg description="Label for Disclosure One">I just have a  
text header</ui:msg>
+        </gwt:header>
+
+
+          <gwt:Label ui:field='myDisclosurePanelItem'>
+            <ui:msg  description="Content for Disclosure One  
Text">Disclosure Text</ui:msg>
+          </gwt:Label>
+
        </gwt:DisclosurePanel>
+
        <p> ... a DisclosurePanel with a widget header ... </p>
-      <gwt:DisclosurePanel>
-        <gwt:Label text="Disclosure Header - closed"  
gwt:DisclosurePanel-header="true">
-          <ui:attribute name="text" description="Content for Disclosure  
Two Text"/>
-        </gwt:Label>
-        <gwt:Label text="Disclosure Two - closed">
-          <ui:attribute name="text" description="Content for Disclosure  
Two"/>
-        </gwt:Label>
+
+      <gwt:DisclosurePanel animationEnabled='true'>
+        <gwt:customHeader>
+          <gwt:Label>
+            <ui:msg description="Content for Disclosure Two  
Text">Disclosure Header - closed</ui:msg>
+          </gwt:Label>
+        </gwt:customHeader>
+
+
+          <gwt:Label>
+            <ui:msg description="Content for Disclosure Two">Disclosure  
Two - closed</ui:msg>
+          </gwt:Label>
+
        </gwt:DisclosurePanel>
+
        <p> ... an open DisclosurePanel with a widget header ... </p>
-      <gwt:DisclosurePanel initiallyOpen="true">
-        <gwt:Label text="Disclosure Header - open"  
gwt:DisclosurePanel-header="true">
-          <ui:attribute name="text" description="Content for Disclosure  
Two Text"/>
-        </gwt:Label>
-        <gwt:Label text="Disclosure Two - open">
-          <ui:attribute name="text" description="Content for Disclosure  
Two"/>
-        </gwt:Label>
+
+      <gwt:DisclosurePanel open='true' animationEnabled='true'>
+        <gwt:customHeader>
+          <gwt:Label>
+            <ui:msg description="Content for Disclosure Two  
Text">Disclosure Header - open</ui:msg>
+          </gwt:Label>
+        </gwt:customHeader>
+
+
+          <gwt:Label>
+            <ui:msg description="Content for Disclosure Two">Disclosure  
Two - open</ui:msg>
+          </gwt:Label>
+
        </gwt:DisclosurePanel>
+
        <p> ... a DisclosurePanel with no header ... </p>
-      <gwt:DisclosurePanel initiallyOpen="true">
-        <gwt:Label text="Disclosure Three">
-          <ui:attribute name="text" description="Content for Disclosure  
Three"/>
-        </gwt:Label>
+
+      <gwt:DisclosurePanel open="true" animationEnabled='true'>
+
+          <gwt:Label>
+            <ui:msg description="Content for Disclosure Three">Disclosure  
Three</ui:msg>
+          </gwt:Label>
+
        </gwt:DisclosurePanel>
+
        <p> ... an open DisclosurePanel with a text label and no  
animation</p>
-      <gwt:DisclosurePanel text="Disclosure Three - open"  
initiallyOpen="true"
-          enableAnimation="false">
-        <gwt:Label text="Disclosure Three">
-          <ui:attribute name="text" description="Content for Disclosure  
Three"/>
-        </gwt:Label>
+
+      <gwt:DisclosurePanel open="true" >
+        <gwt:header><ui:msg>Disclosure Three - open</ui:msg></gwt:header>
+
+
+          <gwt:Label>
+            <ui:msg description="Content for Disclosure Three">Disclosure  
Three</ui:msg>
+          </gwt:Label>
+
        </gwt:DisclosurePanel>
+
        <p> ... a DisclosurePanel with no content ... </p>
-      <gwt:DisclosurePanel text="I just have a text header" />
-
+
+      <gwt:DisclosurePanel>
+        <gwt:header><ui:msg>"I just have a text  
header"</ui:msg></gwt:header>
+      </gwt:DisclosurePanel>
+
+      <p> ... a DisclosurePanel with custom images ... </p>
+
+      <gwt:DisclosurePanel open='false' animationEnabled='true'>
+        <gwt:header openImage='{down}' closedImage='{right}'>
+          <ui:msg description="Content for Disclosure Two Text">Custom  
images header</ui:msg>
+        </gwt:header>
+
+          <gwt:Label>
+            <ui:msg description="Content for Disclosure Two">Custom images  
body</ui:msg>
+          </gwt:Label>
+
+      </gwt:DisclosurePanel>
+
        <h2>Stylish</h2>
        <p>
         Templates work with ClientBundle. For example,
=======================================
--- /trunk/user/src/com/google/gwt/user/client/ui/DisclosurePanel.java  Fri  
Mar 20 11:33:42 2009
+++ /trunk/user/src/com/google/gwt/user/client/ui/DisclosurePanel.java  Thu  
Oct 15 18:41:37 2009
@@ -24,7 +24,8 @@
  import com.google.gwt.event.logical.shared.OpenEvent;
  import com.google.gwt.event.logical.shared.OpenHandler;
  import com.google.gwt.event.shared.HandlerRegistration;
-import com.google.gwt.i18n.client.LocaleInfo;
+import com.google.gwt.resources.client.ClientBundle;
+import com.google.gwt.resources.client.ImageResource;
  import com.google.gwt.user.client.DOM;
  import com.google.gwt.user.client.Element;
  import com.google.gwt.user.client.Event;
@@ -35,11 +36,10 @@
   * A widget that consists of a header and a content panel that discloses  
the
   * content when a user clicks on the header.
   *
- * <h3>CSS Style Rules</h3>
- * <ul class="css">
- * <li>.gwt-DisclosurePanel { the panel's primary style }</li>
- * <li>.gwt-DisclosurePanel-open { dependent style set when panel is open  
}</li>
- * <li>.gwt-DisclosurePanel-closed { dependent style set when panel is  
closed }</li>
+ * <h3>CSS Style Rules</h3> <ul class="css"> <li>.gwt-DisclosurePanel { the
+ * panel's primary style }</li> <li>.gwt-DisclosurePanel-open { dependent  
style
+ * set when panel is open }</li> <li>.gwt-DisclosurePanel-closed {  
dependent
+ * style set when panel is closed }</li>
   *
   * <p>
   * <img class='gallery' src='DisclosurePanel.png'/>
@@ -47,17 +47,51 @@
   *
   * <p>
   * The header and content sections can be easily selected using css with a  
child
- * selector:<br/> .gwt-DisclosurePanel-open .header { ... }
+ * selector:<br/>
+ * .gwt-DisclosurePanel-open .header { ... }
   * </p>
   */
  @SuppressWarnings("deprecation")
  public final class DisclosurePanel extends Composite implements
      FiresDisclosureEvents, HasWidgets, HasAnimation,
      HasOpenHandlers<DisclosurePanel>, HasCloseHandlers<DisclosurePanel> {
+  interface DefaultImages extends ClientBundle {
+    ImageResource disclosurePanelClosed();
+
+    ImageResource disclosurePanelOpen();
+  }
+
+  private static final DefaultImages DEFAULT_IMAGES =  
GWT.create(DefaultImages.class);
+
    /**
-   * The duration of the animation.
+   * Used to wrap widgets in the header to provide click support.  
Effectively
+   * wraps the widget in an <code>anchor</code> to get automatic keyboard
+   * access.
     */
-  private static final int ANIMATION_DURATION = 350;
+  private final class ClickableHeader extends SimplePanel {
+
+    private ClickableHeader() {
+      // Anchor is used to allow keyboard access.
+      super(DOM.createAnchor());
+      Element elem = getElement();
+      DOM.setElementProperty(elem, "href", "javascript:void(0);");
+      // Avoids layout problems from having blocks in inlines.
+      DOM.setStyleAttribute(elem, "display", "block");
+      sinkEvents(Event.ONCLICK);
+      setStyleName(STYLENAME_HEADER);
+    }
+
+    @Override
+    public void onBrowserEvent(Event event) {
+      // no need to call super.
+      switch (DOM.eventGetType(event)) {
+        case Event.ONCLICK:
+          // Prevent link default action.
+          DOM.eventPreventDefault(event);
+          setOpen(!isOpen);
+      }
+    }
+  }

    /**
     * An {...@link Animation} used to open the content.
@@ -91,7 +125,7 @@
        } else {
          panel.contentWrapper.setVisible(panel.isOpen);
          if (panel.isOpen) {
-          // Special treatment on the visible case to ensure LazyPanel  
works
+          // Special treatment on the visible case to ensure LazyPanel  
works
            panel.getContent().setVisible(true);
          }
        }
@@ -112,9 +146,9 @@
        super.onStart();
        if (opening) {
          curPanel.contentWrapper.setVisible(true);
-        // Special treatment on the visible case to ensure LazyPanel works
+        // Special treatment on the visible case to ensure LazyPanel works
          curPanel.getContent().setVisible(true);
-     }
+      }
      }

      @Override
@@ -132,36 +166,6 @@
            "auto");
      }
    }
-
-  /**
-   * Used to wrap widgets in the header to provide click support.  
Effectively
-   * wraps the widget in an <code>anchor</code> to get automatic keyboard
-   * access.
-   */
-  private final class ClickableHeader extends SimplePanel {
-
-    private ClickableHeader() {
-      // Anchor is used to allow keyboard access.
-      super(DOM.createAnchor());
-      Element elem = getElement();
-      DOM.setElementProperty(elem, "href", "javascript:void(0);");
-      // Avoids layout problems from having blocks in inlines.
-      DOM.setStyleAttribute(elem, "display", "block");
-      sinkEvents(Event.ONCLICK);
-      setStyleName(STYLENAME_HEADER);
-    }
-
-    @Override
-    public void onBrowserEvent(Event event) {
-      // no need to call super.
-      switch (DOM.eventGetType(event)) {
-        case Event.ONCLICK:
-          // Prevent link default action.
-          DOM.eventPreventDefault(event);
-          setOpen(!isOpen);
-      }
-    }
-  }

    /**
     * The default header widget used within a {...@link DisclosurePanel}.
@@ -176,13 +180,27 @@
      private final Element labelTD;

      private final Image iconImage;
-    private final DisclosurePanelImages images;
-
-    private DefaultHeader(DisclosurePanelImages images, String text) {
-      this.images = images;
-
-      iconImage = isOpen ? images.disclosurePanelOpen().createImage()
-          : images.disclosurePanelClosed().createImage();
+    private final Imager imager;
+
+    private DefaultHeader(final DisclosurePanelImages images, String text)  
{
+      this(new Imager() {
+        public Image makeImage() {
+          return images.disclosurePanelClosed().createImage();
+        }
+
+        public void updateImage(boolean open, Image image) {
+          if (open) {
+            images.disclosurePanelOpen().applyTo(image);
+          } else {
+            images.disclosurePanelClosed().applyTo(image);
+          }
+        }
+      }, text);
+    }
+
+    private DefaultHeader(Imager imager, String text) {
+      this.imager = imager;
+      iconImage = imager.makeImage();

        // I do not need any Widgets here, just a DOM structure.
        Element root = DOM.createTable();
@@ -211,6 +229,23 @@
        addCloseHandler(this);
        setStyle();
      }
+
+    private DefaultHeader(final ImageResource openImage,
+        final ImageResource closedImage, String text) {
+      this(new Imager() {
+        public Image makeImage() {
+          return new Image(closedImage);
+        }
+
+        public void updateImage(boolean open, Image image) {
+          if (open) {
+            image.setResource(openImage);
+          } else {
+            image.setResource(closedImage);
+          }
+        }
+      }, text);
+    }

      public final String getText() {
        return DOM.getInnerText(labelTD);
@@ -229,14 +264,21 @@
      }

      private void setStyle() {
-      if (isOpen) {
-        images.disclosurePanelOpen().applyTo(iconImage);
-      } else {
-        images.disclosurePanelClosed().applyTo(iconImage);
-      }
+      imager.updateImage(isOpen, iconImage);
      }
    }

+  private interface Imager {
+    Image makeImage();
+
+    void updateImage(boolean open, Image image);
+  }
+
+  /**
+   * The duration of the animation.
+   */
+  private static final int ANIMATION_DURATION = 350;
+
    // Stylename constants.
    private static final String STYLENAME_DEFAULT = "gwt-DisclosurePanel";

@@ -253,13 +295,6 @@
     */
    private static ContentAnimation contentAnimation;

-  private static DisclosurePanelImages createDefaultImages() {
-    if (LocaleInfo.getCurrentLocale().isRTL()) {
-      return GWT.create(DisclosurePanelImagesRTL.class);
-    }
-    return GWT.create(DisclosurePanelImages.class);
-  }
-
    /**
     * top level widget. The first child will be a reference to {...@link  
#header}.
     * The second child will be a reference to {...@link #contentWrapper}.
@@ -284,7 +319,13 @@
     * Creates an empty DisclosurePanel that is initially closed.
     */
    public DisclosurePanel() {
-    init(false);
+    initWidget(mainPanel);
+    mainPanel.add(header);
+    mainPanel.add(contentWrapper);
+    DOM.setStyleAttribute(contentWrapper.getElement(), "padding", "0px");
+     
DOM.setStyleAttribute(contentWrapper.getElement(), "overflow", "hidden");
+    setStyleName(STYLENAME_DEFAULT);
+    setContentDisplay(false);
    }

    /**
@@ -295,12 +336,33 @@
     * @param images a bundle that provides disclosure panel specific images
     * @param headerText the text to be displayed in the header
     * @param isOpen the initial open/close state of the content panel
+   *
+   * @deprecated use
+   *             {...@link #DisclosurePanel(ImageResource, ImageResource,  
String)
+   *             and {...@link #setOpen(boolean)}
     */
+  @Deprecated
    public DisclosurePanel(DisclosurePanelImages images, String headerText,
        boolean isOpen) {
-    init(isOpen);
+    this();
+    setOpen(isOpen);
      setHeader(new DefaultHeader(images, headerText));
    }
+
+  /**
+   * Creates a DisclosurePanel with the specified header text, an initial
+   * open/close state and a bundle of images to be used in the default  
header
+   * widget.
+   *
+   * @param images a bundle that provides disclosure panel specific images
+   * @param headerText the text to be displayed in the header
+   * @param isOpen the initial open/close state of the content panel
+   */
+  public DisclosurePanel(ImageResource openImage, ImageResource  
closedImage,
+      String headerText) {
+    this();
+    setHeader(new DefaultHeader(openImage, closedImage, headerText));
+  }

    /**
     * Creates a DisclosurePanel that will be initially closed using the  
specified
@@ -309,7 +371,8 @@
     * @param headerText the text to be displayed in the header
     */
    public DisclosurePanel(String headerText) {
-    this(createDefaultImages(), headerText, false);
+    this(DEFAULT_IMAGES.disclosurePanelOpen(),
+        DEFAULT_IMAGES.disclosurePanelClosed(), headerText);
    }

    /**
@@ -318,9 +381,14 @@
     *
     * @param headerText the text to be displayed in the header
     * @param isOpen the initial open/close state of the content panel
+   * @deprecated use {...@link #DisclosurePanel(String)} and
+   *             {...@link #setOpen(boolean)}
     */
+  @Deprecated
    public DisclosurePanel(String headerText, boolean isOpen) {
-    this(createDefaultImages(), headerText, isOpen);
+    this(DEFAULT_IMAGES.disclosurePanelOpen(),
+        DEFAULT_IMAGES.disclosurePanelClosed(), headerText);
+    this.setOpen(isOpen);
    }

    /**
@@ -328,9 +396,11 @@
     * the header.
     *
     * @param header the widget to be used as a header
+   * @deprecated use {...@link #DisclosurePanel()} and {...@link  
#setHeader(Widget)}
     */
    public DisclosurePanel(Widget header) {
-    this(header, false);
+    this();
+    setHeader(header);
    }

    /**
@@ -339,10 +409,14 @@
     *
     * @param header the widget to be used as a header
     * @param isOpen the initial open/close state of the content panel
+   * @deprecated use {...@link #DisclosurePanel()}, {...@link 
#setOpen(boolean)}  
and
+   *             {...@link #setHeader(Widget)} instead
     */
+  @Deprecated
    public DisclosurePanel(Widget header, boolean isOpen) {
-    init(isOpen);
+    this();
      setHeader(header);
+    setOpen(isOpen);
    }

    public void add(Widget w) {
@@ -365,7 +439,7 @@
     *
     * @param handler the handler to be added (should not be null)
     * @deprecated Use {...@link DisclosurePanel#addOpenHandler(OpenHandler)}  
and
-   * {...@link DisclosurePanel#addCloseHandler(CloseHandler)} instead
+   *             {...@link DisclosurePanel#addCloseHandler(CloseHandler)}  
instead
     */
    @Deprecated
    public void addEventHandler(final DisclosureHandler handler) {
@@ -403,7 +477,7 @@
     * the header widget does provide such access.
     *
     * @return a reference to the header widget if it implements {...@link  
HasText},
-   * <code>null</code> otherwise
+   *         <code>null</code> otherwise
     */
    public HasText getHeaderTextAccessor() {
      Widget widget = header.getWidget();
@@ -440,8 +514,8 @@
     * Removes an event handler from the panel.
     *
     * @param handler the handler to be removed
-   * @deprecated Use the {...@link HandlerRegistration#removeHandler} method  
on
-   * the object returned by an add*Handler method instead
+   * @deprecated Use the {...@link HandlerRegistration#removeHandler} method  
on the
+   *             object returned by an add*Handler method instead
     */
    @Deprecated
    public void removeEventHandler(DisclosureHandler handler) {
@@ -488,7 +562,7 @@
     * Changes the visible state of this <code>DisclosurePanel</code>.
     *
     * @param isOpen <code>true</code> to open the panel, <code>false</code>  
to
-   * close
+   *          close
     */
    public void setOpen(boolean isOpen) {
      if (this.isOpen != isOpen) {
@@ -519,17 +593,6 @@
        CloseEvent.fire(this, this);
      }
    }
-
-  private void init(boolean isOpen) {
-    initWidget(mainPanel);
-    mainPanel.add(header);
-    mainPanel.add(contentWrapper);
-    DOM.setStyleAttribute(contentWrapper.getElement(), "padding", "0px");
-     
DOM.setStyleAttribute(contentWrapper.getElement(), "overflow", "hidden");
-    this.isOpen = isOpen;
-    setStyleName(STYLENAME_DEFAULT);
-    setContentDisplay(false);
-  }

    private void setContentDisplay(boolean animate) {
      if (isOpen) {
=======================================
---  
/trunk/user/src/com/google/gwt/user/client/ui/DisclosurePanelImages.java        
 
Tue Mar 17 08:17:42 2009
+++  
/trunk/user/src/com/google/gwt/user/client/ui/DisclosurePanelImages.java        
 
Thu Oct 15 18:41:37 2009
@@ -18,6 +18,7 @@
  /**
   * An {...@link ImageBundle} that provides images for {...@link 
DisclosurePanel}.
   */
+...@deprecated
  public interface DisclosurePanelImages extends ImageBundle {

    /**
=======================================
---  
/trunk/user/src/com/google/gwt/user/client/ui/DisclosurePanelImagesRTL.java     
 
Tue Mar 17 08:17:42 2009
+++  
/trunk/user/src/com/google/gwt/user/client/ui/DisclosurePanelImagesRTL.java     
 
Thu Oct 15 18:41:37 2009
@@ -20,6 +20,7 @@
   * only need to override the disclosurePanelClosed() method, as the image  
that we provide
   * for disclosurePanelOpen() is direction-agnostic.
   */
+...@deprecated
  public interface DisclosurePanelImagesRTL extends DisclosurePanelImages {
    /**
     * An image indicating a closed disclosure panel for a RTL context.

--~--~---------~--~----~------------~-------~--~----~
http://groups.google.com/group/Google-Web-Toolkit-Contributors
-~----------~----~----~----~------~----~------~--~---

Reply via email to