Revision: 7531
Author: [email protected]
Date: Fri Feb  5 08:10:59 2010
Log: Merging tr...@7479 into this branch.

http://code.google.com/p/google-web-toolkit/source/detail?r=7531

Added:
/releases/2.0/user/src/com/google/gwt/user/theme/chrome/public/gwt/chrome/images/splitPanelThumb.png /releases/2.0/user/src/com/google/gwt/user/theme/dark/public/gwt/dark/images/splitPanelThumb.png /releases/2.0/user/src/com/google/gwt/user/theme/standard/public/gwt/standard/images/splitPanelThumb.png
Modified:
 /releases/2.0/branch-info.txt
 /releases/2.0/samples/mail/src/com/google/gwt/sample/mail/client/global.css
/releases/2.0/user/src/com/google/gwt/uibinder/elementparsers/StackLayoutPanelParser.java
 /releases/2.0/user/src/com/google/gwt/user/client/ui/SplitLayoutPanel.java
 /releases/2.0/user/src/com/google/gwt/user/client/ui/StackLayoutPanel.java
 /releases/2.0/user/src/com/google/gwt/user/client/ui/TabLayoutPanel.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/uibinder/elementparsers/StackLayoutPanelParserTest.java /releases/2.0/user/test/com/google/gwt/user/client/ui/StackLayoutPanelTest.java

=======================================
--- /dev/null
+++ /releases/2.0/user/src/com/google/gwt/user/theme/chrome/public/gwt/chrome/images/splitPanelThumb.png Fri Feb 5 08:10:59 2010
@@ -0,0 +1,8 @@
+‰PNG
+ + +IHDR ÄRWÓ gAMA ÖØÔOX2 tEXtSoftware Adobe ImageReadyqÉe< ÆIDATxÚbüÿÿ?C`` 8++k;##£Ìß¿ ®Y³¦‘ ¤yxxÎ~ýúõ' Óo . ø %K–ر u4 ÿþý'//ïk NNÎ ÏŸ?׎ ÷faff– êümhhÈ ¤¤ÄÀÆÆÆpâÄ‰ß >| P šÄt’ $!..Î d3þþý›MXXx'#ÈA
+
+
+û ��...@üûÓ§o¬bbb óóó Á’ ÐÑÑaÏÅÅ¥ tÃáÌÌÌk 1€   u¸B
+...@ú·f    IEND®B`‚
=======================================
--- /dev/null
+++ /releases/2.0/user/src/com/google/gwt/user/theme/dark/public/gwt/dark/images/splitPanelThumb.png Fri Feb 5 08:10:59 2010
@@ -0,0 +1,8 @@
+‰PNG
+ + +IHDR ÄRWÓ gAMA ÖØÔOX2 tEXtSoftware Adobe ImageReadyqÉe< ÆIDATxÚbüÿÿ?C`` 8++k;##£Ìß¿ ®Y³¦‘ ¤yxxÎ~ýúõ' Óo . ø %K–ر u4 ÿþý'//ïk NNÎ ÏŸ?׎ ÷faff– êümhhÈ ¤¤ÄÀÆÆÆpâÄ‰ß >| P šÄt’ $!..Î d3þþý›MXXx'#ÈA
+
+
+û ��...@üûÓ§o¬bbb óóó Á’ ÐÑÑaÏÅÅ¥ tÃáÌÌÌk 1€   u¸B
+...@ú·f    IEND®B`‚
=======================================
--- /dev/null
+++ /releases/2.0/user/src/com/google/gwt/user/theme/standard/public/gwt/standard/images/splitPanelThumb.png Fri Feb 5 08:10:59 2010
@@ -0,0 +1,8 @@
+‰PNG
+ + +IHDR ÄRWÓ gAMA ÖØÔOX2 tEXtSoftware Adobe ImageReadyqÉe< ÆIDATxÚbüÿÿ?C`` 8++k;##£Ìß¿ ®Y³¦‘ ¤yxxÎ~ýúõ' Óo . ø %K–ر u4 ÿþý'//ïk NNÎ ÏŸ?׎ ÷faff– êümhhÈ ¤¤ÄÀÆÆÆpâÄ‰ß >| P šÄt’ $!..Î d3þþý›MXXx'#ÈA
+
+
+û ��...@üûÓ§o¬bbb óóó Á’ ÐÑÑaÏÅÅ¥ tÃáÌÌÌk 1€   u¸B
+...@ú·f    IEND®B`‚
=======================================
--- /releases/2.0/branch-info.txt       Wed Feb  3 07:25:42 2010
+++ /releases/2.0/branch-info.txt       Fri Feb  5 08:10:59 2010
@@ -1474,3 +1474,8 @@
 tr...@7358 was merged into this branch
Fix issue 4425: Invalid String.charAt(int) results when using escape string syntax svn merge --ignore-ancestry -c 7358 https://google-web-toolkit.googlecode.com/svn/trunk .
+
+tr...@7479 was merged into this branch
+  Fixes for issues 4335, 4429, 4453.
+ svn merge -c7479 --ignore-ancestry https://google-web-toolkit.googlecode.com/svn/trunk
+
=======================================
--- /releases/2.0/samples/mail/src/com/google/gwt/sample/mail/client/global.css Tue Dec 1 21:26:37 2009 +++ /releases/2.0/samples/mail/src/com/google/gwt/sample/mail/client/global.css Fri Feb 5 08:10:59 2010
@@ -55,6 +55,10 @@
 }

 /* Splitters */
+.gwt-SplitLayoutPanel-HDragger, .gwt-SplitLayoutPanel-VDragger {
+  background-color: white;
+}
+
 .gwt-SplitLayoutPanel-HDragger {
   cursor: col-resize;
 }
=======================================
--- /releases/2.0/user/src/com/google/gwt/uibinder/elementparsers/StackLayoutPanelParser.java Wed Nov 11 22:32:37 2009 +++ /releases/2.0/user/src/com/google/gwt/uibinder/elementparsers/StackLayoutPanelParser.java Fri Feb 5 08:10:59 2010
@@ -76,9 +76,7 @@
             writer, fieldName);
String size = children.header.consumeRequiredDoubleAttribute("size");
         String html = children.header.consumeInnerHtml(htmlInt);
-        writer.addStatement("%s.add(%s, "
-            + "new com.google.gwt.user.client.ui.HTML(\"%s\"), "
-            + "%s);", fieldName,
+        writer.addStatement("%s.add(%s, \"%s\", true, %s);", fieldName,
             childFieldName, html, size);
       } else if (children.customHeader != null) {
         XMLElement headerElement =
=======================================
--- /releases/2.0/user/src/com/google/gwt/user/client/ui/SplitLayoutPanel.java Tue Jan 26 08:23:54 2010 +++ /releases/2.0/user/src/com/google/gwt/user/client/ui/SplitLayoutPanel.java Fri Feb 5 08:10:59 2010
@@ -98,7 +98,6 @@
       setElement(Document.get().createDivElement());
       sinkEvents(Event.ONMOUSEDOWN | Event.ONMOUSEUP | Event.ONMOUSEMOVE
           | Event.ONDBLCLICK);
-      getElement().getStyle().setBackgroundColor("white");
     }

     @Override
=======================================
--- /releases/2.0/user/src/com/google/gwt/user/client/ui/StackLayoutPanel.java Tue Jan 26 08:23:54 2010 +++ /releases/2.0/user/src/com/google/gwt/user/client/ui/StackLayoutPanel.java Fri Feb 5 08:10:59 2010
@@ -16,7 +16,16 @@
 package com.google.gwt.user.client.ui;

 import com.google.gwt.dom.client.Style.Unit;
-import com.google.gwt.user.client.Event;
+import com.google.gwt.event.dom.client.ClickEvent;
+import com.google.gwt.event.dom.client.ClickHandler;
+import com.google.gwt.event.dom.client.HasClickHandlers;
+import com.google.gwt.event.logical.shared.BeforeSelectionEvent;
+import com.google.gwt.event.logical.shared.BeforeSelectionHandler;
+import com.google.gwt.event.logical.shared.HasBeforeSelectionHandlers;
+import com.google.gwt.event.logical.shared.HasSelectionHandlers;
+import com.google.gwt.event.logical.shared.SelectionEvent;
+import com.google.gwt.event.logical.shared.SelectionHandler;
+import com.google.gwt.event.shared.HandlerRegistration;

 import java.util.ArrayList;
 import java.util.Iterator;
@@ -32,6 +41,15 @@
  * declaration.
  * </p>
  *
+ * <h3>CSS Style Rules</h3>
+ * <dl>
+ * <dt>.gwt-StackLayoutPanel <dd> the panel itself
+ * <dt>.gwt-StackLayoutPanel .gwt-StackLayoutPanelHeader <dd> applied to each
+ * header widget
+ * <dt>.gwt-StackLayoutPanel .gwt-StackLayoutPanelContent <dd> applied to each
+ * child widget
+ * </dl>
+ *
  * <p>
  * <h3>Example</h3>
  * {...@example com.google.gwt.examples.StackLayoutPanelExample}
@@ -69,44 +87,42 @@
  * &lt;/g:StackLayoutPanel>
  * </pre>
  */
-public class StackLayoutPanel extends Composite implements HasWidgets,
-    RequiresResize, ProvidesResize {
-
-  private class ClickWrapper extends Composite {
-    private Widget target;
-
-    public ClickWrapper(Widget target, Widget wrappee) {
-      this.target = target;
-      initWidget(wrappee);
-      sinkEvents(Event.ONCLICK);
+public class StackLayoutPanel extends ResizeComposite implements HasWidgets,
+    RequiresResize, ProvidesResize, IndexedPanel,
+    HasBeforeSelectionHandlers<Integer>, HasSelectionHandlers<Integer> {
+
+  private class Header extends Composite implements HasClickHandlers {
+    public Header(Widget child) {
+      initWidget(child);
     }

-    @Override
-    public void onBrowserEvent(Event event) {
-      if (event.getTypeInt() == Event.ONCLICK) {
-        showWidget(target);
-      }
+    public HandlerRegistration addClickHandler(ClickHandler handler) {
+      return this.addDomHandler(handler, ClickEvent.getType());
     }
   }

   private static class LayoutData {
     public double headerSize;
-    public Widget header;
+    public Header header;
     public Widget widget;

-    public LayoutData(Widget widget, Widget header, double headerSize) {
+    public LayoutData(Widget widget, Header header, double headerSize) {
       this.widget = widget;
       this.header = header;
       this.headerSize = headerSize;
     }
   }
+
+  private static final String WIDGET_STYLE = "gwt-StackLayoutPanel";
+ private static final String CONTENT_STYLE = "gwt-StackLayoutPanelContent";
+  private static final String HEADER_STYLE = "gwt-StackLayoutPanelHeader";

   private static final int ANIMATION_TIME = 250;

   private LayoutPanel layoutPanel;
   private Unit unit;
   private ArrayList<LayoutData> layoutData = new ArrayList<LayoutData>();
-  private Widget visibleWidget;
+  private int selectedIndex = -1;

   /**
    * Creates an empty stack panel.
@@ -116,11 +132,37 @@
   public StackLayoutPanel(Unit unit) {
     this.unit = unit;
     initWidget(layoutPanel = new LayoutPanel());
+    setStyleName(WIDGET_STYLE);
   }

   public void add(Widget w) {
assert false : "Single-argument add() is not supported for this widget";
   }
+
+  /**
+ * Adds a child widget to this stack, along with a widget representing the
+   * stack header.
+   *
+   * @param widget the child widget to be added
+   * @param text the text to be shown on its header
+   * @param asHtml <code>true</code> to treat the specified text as HTML
+   * @param headerSize the size of the header widget
+   */
+ public void add(final Widget widget, String header, boolean asHtml, double headerSize) {
+    insert(widget, header, asHtml, headerSize, getWidgetCount());
+  }
+
+  /**
+ * Adds a child widget to this stack, along with a widget representing the
+   * stack header.
+   *
+   * @param widget the child widget to be added
+   * @param text the text to be shown on its header
+   * @param headerSize the size of the header widget
+   */
+  public void add(final Widget widget, String header, double headerSize) {
+    insert(widget, header, headerSize, getWidgetCount());
+  }

   /**
* Adds a child widget to this stack, along with a widget representing the
@@ -131,27 +173,54 @@
    * @param headerSize the size of the header widget
    */
   public void add(final Widget widget, Widget header, double headerSize) {
-    ClickWrapper wrapper = new ClickWrapper(widget, header);
-    layoutPanel.add(wrapper);
-    layoutPanel.add(widget);
-
-    layoutPanel.setWidgetLeftRight(wrapper, 0, Unit.PX, 0, Unit.PX);
-    layoutPanel.setWidgetLeftRight(widget, 0, Unit.PX, 0, Unit.PX);
-
-    LayoutData data = new LayoutData(widget, wrapper, headerSize);
-    layoutData.add(data);
-
-    if (visibleWidget == null) {
- // If there's no visible widget, display the first one. The layout will
-      // be updated onLoad().
-      visibleWidget = widget;
-    }
+    insert(widget, header, headerSize, getWidgetCount());
+  }
+
+  public HandlerRegistration addBeforeSelectionHandler(
+      BeforeSelectionHandler<Integer> handler) {
+    return addHandler(handler, BeforeSelectionEvent.getType());
+  }
+
+  public HandlerRegistration addSelectionHandler(
+      SelectionHandler<Integer> handler) {
+    return addHandler(handler, SelectionEvent.getType());
   }

   public void clear() {
     layoutPanel.clear();
     layoutData.clear();
-    visibleWidget = null;
+    selectedIndex = -1;
+  }
+
+  /**
+   * Gets the widget in the stack header at the given index.
+   *
+   * @param index the index of the stack header to be retrieved
+   * @return the header widget
+   */
+  public Widget getHeaderWidget(int index) {
+    checkIndex(index);
+    return layoutData.get(index).header.getWidget();
+  }
+
+  /**
+ * Gets the widget in the stack header associated with the given child widget.
+   *
+   * @param child the child whose stack header is to be retrieved
+   * @return the header widget
+   */
+  public Widget getHeaderWidget(Widget child) {
+    checkChild(child);
+    return getHeaderWidget(getWidgetIndex(child));
+  }
+
+  /**
+   * Gets the currently-selected index.
+   *
+   * @return the selected index, or <code>-1</code> if none is selected
+   */
+  public int getVisibleIndex() {
+    return selectedIndex;
   }

   /**
@@ -160,7 +229,74 @@
    * @return the selected widget, or <code>null</code> if none exist
    */
   public Widget getVisibleWidget() {
-    return visibleWidget;
+    if (selectedIndex == -1) {
+      return null;
+    }
+    return getWidget(selectedIndex);
+  }
+
+  public Widget getWidget(int index) {
+    return layoutPanel.getWidget(index * 2 + 1);
+  }
+
+  public int getWidgetCount() {
+    return layoutPanel.getWidgetCount() / 2;
+  }
+
+  public int getWidgetIndex(Widget child) {
+    int index = layoutPanel.getWidgetIndex(child);
+    if (index == -1) {
+      return index;
+    }
+    return (index - 1) / 2;
+  }
+
+  /**
+ * Inserts a widget into the panel. If the Widget is already attached, it will
+   * be moved to the requested index.
+   *
+   * @param child the widget to be added
+   * @param text the text to be shown on its header
+   * @param asHtml <code>true</code> to treat the specified text as HTML
+   * @param headerSize the size of the header widget
+   * @param beforeIndex the index before which it will be inserted
+   */
+  public void insert(Widget child, String text, boolean asHtml,
+      double headerSize, int beforeIndex) {
+    HTML contents = new HTML();
+    if (asHtml) {
+      contents.setHTML(text);
+    } else {
+      contents.setText(text);
+    }
+    insert(child, contents, headerSize, beforeIndex);
+  }
+
+  /**
+ * Inserts a widget into the panel. If the Widget is already attached, it will
+   * be moved to the requested index.
+   *
+   * @param child the widget to be added
+   * @param text the text to be shown on its header
+   * @param headerSize the size of the header widget
+   * @param beforeIndex the index before which it will be inserted
+   */
+ public void insert(Widget child, String text, double headerSize, int beforeIndex) {
+    insert(child, text, false, headerSize, beforeIndex);
+  }
+
+  /**
+ * Inserts a widget into the panel. If the Widget is already attached, it will
+   * be moved to the requested index.
+   *
+   * @param child the widget to be added
+   * @param header the widget to be placed in the associated header
+   * @param headerSize the size of the header widget
+   * @param beforeIndex the index before which it will be inserted
+   */
+  public void insert(Widget child, Widget header, double headerSize,
+      int beforeIndex) {
+    insert(child, new Header(header), headerSize, beforeIndex);
   }

   public Iterator<Widget> iterator() {
@@ -193,6 +329,10 @@
   public void onResize() {
     layoutPanel.onResize();
   }
+
+  public boolean remove(int index) {
+    return remove(getWidget(index));
+  }

   public boolean remove(Widget child) {
     if (child.getParent() != layoutPanel) {
@@ -204,11 +344,15 @@
       LayoutData data = layoutData.get(i);
       if (data.widget == child) {
         layoutPanel.remove(data.header);
-        layoutPanel.remove(child);
+        layoutPanel.remove(data.widget);
+
+        data.header.removeStyleName(HEADER_STYLE);
+        data.widget.removeStyleName(CONTENT_STYLE);
+
         layoutData.remove(i);

-        if (visibleWidget == child) {
-          visibleWidget = null;
+        if (selectedIndex == i) {
+          selectedIndex = -1;
           if (layoutData.size() > 0) {
             showWidget(layoutData.get(0).widget);
           }
@@ -221,12 +365,57 @@
   }

   /**
-   * Shows the specified widget.
+   * Sets a stack header's HTML contents.
+   *
+   * Use care when setting an object's HTML; it is an easy way to expose
+   * script-based security problems. Consider using
+   * {...@link #setHeaderText(int, String)} whenever possible.
+   *
+   * @param index the index of the header whose HTML is to be set
+   * @param html the header's new HTML contents
+   */
+  public void setHeaderHTML(int index, String html) {
+    checkIndex(index);
+    LayoutData data = layoutData.get(index);
+
+    Widget headerWidget = data.header.getWidget();
+ assert headerWidget instanceof HasHTML : "Header widget does not implement HasHTML";
+    ((HasHTML) headerWidget).setHTML(html);
+  }
+
+  /**
+   * Sets a stack header's text contents.
+   *
+   * @param index the index of the header whose text is to be set
+   * @param text the object's new text
+   */
+  public void setHeaderText(int index, String text) {
+    checkIndex(index);
+    LayoutData data = layoutData.get(index);
+
+    Widget headerWidget = data.header.getWidget();
+ assert headerWidget instanceof HasText : "Header widget does not implement HasText";
+    ((HasText) headerWidget).setText(text);
+  }
+
+  /**
+   * Shows the widget at the specified index.
    *
    * @param widget the child widget to be shown.
    */
-  public void showWidget(Widget widget) {
-    showWidget(widget, ANIMATION_TIME);
+  public void showWidget(int index) {
+    checkIndex(index);
+    showWidget(index, ANIMATION_TIME);
+  }
+
+  /**
+   * Shows the specified widget.
+   *
+   * @param child the child widget to be shown.
+   */
+  public void showWidget(Widget child) {
+    checkChild(child);
+    showWidget(getWidgetIndex(child), ANIMATION_TIME);
   }

   @Override
@@ -242,7 +431,7 @@
     }

     double top = 0, bottom = 0;
-    int i = 0, visibleIndex = -1;
+    int i = 0;
     for (; i < layoutData.size(); ++i) {
       LayoutData data = layoutData.get(i);
layoutPanel.setWidgetTopHeight(data.header, top, unit, data.headerSize,
@@ -252,13 +441,10 @@

       layoutPanel.setWidgetTopHeight(data.widget, top, unit, 0, unit);

-      if (data.widget == visibleWidget) {
-        visibleIndex = i;
+      if (i == selectedIndex) {
         break;
       }
     }
-
-    assert visibleIndex != -1;

     for (int j = layoutData.size() - 1; j > i; --j) {
       LayoutData data = layoutData.get(j);
@@ -268,14 +454,86 @@
       bottom += data.headerSize;
     }

-    LayoutData data = layoutData.get(visibleIndex);
+    LayoutData data = layoutData.get(selectedIndex);
     layoutPanel.setWidgetTopBottom(data.widget, top, unit, bottom, unit);

     layoutPanel.animate(duration);
   }

-  private void showWidget(Widget widget, final int duration) {
-    visibleWidget = widget;
-    animate(duration);
+  private void checkChild(Widget child) {
+    assert layoutPanel.getChildren().contains(child);
+  }
+
+  private void checkIndex(int index) {
+ assert (index >= 0) && (index < getWidgetCount()) : "Index out of bounds";
+  }
+
+  private void insert(final Widget child, Header header, double headerSize,
+      int beforeIndex) {
+ assert (beforeIndex >= 0) && (beforeIndex <= getWidgetCount()) : "beforeIndex out of bounds";
+
+    // Check to see if the StackPanel already contains the Widget. If so,
+    // remove it and see if we need to shift the position to the left.
+    int idx = getWidgetIndex(child);
+    if (idx != -1) {
+      remove(child);
+      if (idx < beforeIndex) {
+        beforeIndex--;
+      }
+    }
+
+    beforeIndex *= 2;
+    layoutPanel.insert(child, beforeIndex);
+    layoutPanel.insert(header, beforeIndex);
+
+    layoutPanel.setWidgetLeftRight(header, 0, Unit.PX, 0, Unit.PX);
+    layoutPanel.setWidgetLeftRight(child, 0, Unit.PX, 0, Unit.PX);
+
+    LayoutData data = new LayoutData(child, header, headerSize);
+    layoutData.add(data);
+
+    header.addStyleName(HEADER_STYLE);
+    child.addStyleName(CONTENT_STYLE);
+
+    header.addClickHandler(new ClickHandler() {
+      public void onClick(ClickEvent event) {
+        showWidget(child);
+      }
+    });
+
+    if (selectedIndex == -1) {
+ // If there's no visible widget, display the first one. The layout will
+      // be updated onLoad().
+      showWidget(0);
+    }
+
+ // If the widget is already attached, we must call animate() to update the
+    // layout (if it's not yet attached, then onLoad() will do this).
+    if (isAttached()) {
+      animate(ANIMATION_TIME);
+    }
+  }
+
+  private void showWidget(int index, final int duration) {
+    checkIndex(index);
+    if (index == selectedIndex) {
+      return;
+    }
+
+    // Fire the before selection event, giving the recipients a chance to
+    // cancel the selection.
+ BeforeSelectionEvent<Integer> event = BeforeSelectionEvent.fire(this, index);
+    if ((event != null) && event.isCanceled()) {
+      return;
+    }
+
+    selectedIndex = index;
+
+    if (isAttached()) {
+      animate(duration);
+    }
+
+    // Fire the selection event.
+    SelectionEvent.fire(this, index);
   }
 }
=======================================
--- /releases/2.0/user/src/com/google/gwt/user/client/ui/TabLayoutPanel.java Tue Jan 26 08:23:54 2010 +++ /releases/2.0/user/src/com/google/gwt/user/client/ui/TabLayoutPanel.java Fri Feb 5 08:10:59 2010
@@ -52,6 +52,8 @@
  * <dt>.gwt-TabLayoutPanel .gwt-TabLayoutPanelTab <dd> an individual tab
* <dt>.gwt-TabLayoutPanel .gwt-TabLayoutPanelTabInner <dd> an element nested in
  * each tab (useful for styling)
+ * <dt>.gwt-TabLayoutPanel .gwt-TabLayoutPanelContent<dd> applied to all child
+ * content widgets
  * </dl>
  *
  * <p>
@@ -92,6 +94,10 @@
     ProvidesResize, IndexedPanel, HasBeforeSelectionHandlers<Integer>,
     HasSelectionHandlers<Integer> {

+  private static final String CONTENT_STYLE = "gwt-TabLayoutPanelContent";
+  private static final String TAB_STYLE = "gwt-TabLayoutPanelTab";
+ private static final String TAB_INNER_STYLE = "gwt-TabLayoutPanelTabInner";
+
   private static final int BIG_ENOUGH_TO_NOT_WRAP = 16384;

   private static class Tab extends SimplePanel {
@@ -102,8 +108,8 @@
       getElement().appendChild(inner = Document.get().createDivElement());

       setWidget(child);
-      setStyleName("gwt-TabLayoutPanelTab");
-      inner.setClassName("gwt-TabLayoutPanelTabInner");
+      setStyleName(TAB_STYLE);
+      inner.setClassName(TAB_INNER_STYLE);

       // TODO: float:left may not be enough. If there are tabs of differing
// heights, the shorter ones will top-align, rather than bottom-align,
@@ -115,10 +121,6 @@
     public HandlerRegistration addClickHandler(ClickHandler handler) {
       return addDomHandler(handler, ClickEvent.getType());
     }
-
-    public Widget asWidget() {
-      return this;
-    }

     public void setSelected(boolean selected) {
       if (selected) {
@@ -331,8 +333,10 @@
       return false;
     }

+    Widget child = children.get(index);
     tabBar.remove(index);
-    panel.remove(children.get(index));
+    panel.remove(child);
+    child.removeStyleName(CONTENT_STYLE);

     children.remove(index);
     tabs.remove(index);
@@ -458,7 +462,7 @@
     children.insert(child, beforeIndex);
     tabs.add(beforeIndex, tab);

-    tabBar.insert(tab.asWidget(), beforeIndex);
+    tabBar.insert(tab, beforeIndex);
     tab.addClickHandler(new ClickHandler() {
       public void onClick(ClickEvent event) {
         selectTab(child);
@@ -478,6 +482,7 @@
     panel.setWidgetTopBottom(child, barHeight, barUnit, 0, Unit.PX);
     panel.getWidgetContainerElement(child).getStyle().setDisplay(
         Display.NONE);
+    child.addStyleName(CONTENT_STYLE);
     child.setVisible(false);
   }
 }
=======================================
--- /releases/2.0/user/src/com/google/gwt/user/theme/chrome/public/gwt/chrome/chrome.css Tue Dec 1 21:26:37 2009 +++ /releases/2.0/user/src/com/google/gwt/user/theme/chrome/public/gwt/chrome/chrome.css Fri Feb 5 08:10:59 2010
@@ -1079,3 +1079,61 @@
   cursor: pointer;
   padding: 0px 4px;
 }
+
+.gwt-StackLayoutPanel {
+  border-bottom: 1px solid #bbbbbb;
+}
+.gwt-StackLayoutPanel .gwt-StackLayoutPanelHeader {
+  cursor: pointer;
+  cursor: hand;
+  border: 1px solid #bbbbbb;
+  border-bottom: 0px;
+  background: #d3def6 url(images/hborder.png) repeat-x 0px -989px;
+
+  font-weight: bold;
+  font-size: 1.3em;
+  padding: 3px;
+  text-align: center;
+}
+.gwt-StackLayoutPanel .gwt-StackLayoutPanelContent {
+  border: 1px solid #bbbbbb;
+  border-bottom: 0px;
+  background: white;
+  padding: 2px 2px 10px 5px;
+}
+
+.gwt-TabLayoutPanel {
+}
+.gwt-TabLayoutPanel .gwt-TabLayoutPanelTabs {
+}
+.gwt-TabLayoutPanel .gwt-TabLayoutPanelContent {
+  border-color: #bcbcbc;
+  border-style: solid;
+  border-width: 3px 2px 2px;
+  overflow: hidden;
+  padding: 6px;
+}
+.gwt-TabLayoutPanel .gwt-TabLayoutPanelTab {
+  margin-left: 6px;
+  padding: 3px 6px 3px 6px;
+  cursor: pointer;
+  cursor: hand;
+  color: black;
+  font-weight: bold;
+  text-align: center;
+  background: #e3e3e3;
+}
+.gwt-TabLayoutPanel .gwt-TabLayoutPanelTab-selected {
+  cursor: default;
+  background: #bcbcbc;
+}
+
+.gwt-SplitLayoutPanel-HDragger {
+ background: white url(images/splitPanelThumb.png) center center no-repeat;
+  cursor: col-resize;
+}
+
+.gwt-SplitLayoutPanel-VDragger {
+ background: white url(images/splitPanelThumb.png) center center no-repeat;
+  cursor: row-resize;
+}
=======================================
--- /releases/2.0/user/src/com/google/gwt/user/theme/chrome/public/gwt/chrome/chrome_rtl.css Tue Dec 1 21:26:37 2009 +++ /releases/2.0/user/src/com/google/gwt/user/theme/chrome/public/gwt/chrome/chrome_rtl.css Fri Feb 5 08:10:59 2010
@@ -1080,3 +1080,61 @@
   cursor: pointer;
   padding: 0px 4px;
 }
+
+.gwt-StackLayoutPanel {
+  border-bottom: 1px solid #bbbbbb;
+}
+.gwt-StackLayoutPanel .gwt-StackLayoutPanelHeader {
+  cursor: pointer;
+  cursor: hand;
+  border: 1px solid #bbbbbb;
+  border-bottom: 0px;
+  background: #d3def6 url(images/hborder.png) repeat-x 0px -989px;
+
+  font-weight: bold;
+  font-size: 1.3em;
+  padding: 3px;
+  text-align: center;
+}
+.gwt-StackLayoutPanel .gwt-StackLayoutPanelContent {
+  border: 1px solid #bbbbbb;
+  border-bottom: 0px;
+  background: white;
+  padding: 2px 5px 10px 2px;
+}
+
+.gwt-TabLayoutPanel {
+}
+.gwt-TabLayoutPanel .gwt-TabLayoutPanelTabs {
+}
+.gwt-TabLayoutPanel .gwt-TabLayoutPanelContent {
+  border-color: #bcbcbc;
+  border-style: solid;
+  border-width: 3px 2px 2px;
+  overflow: hidden;
+  padding: 6px;
+}
+.gwt-TabLayoutPanel .gwt-TabLayoutPanelTab {
+  margin-left: 6px;
+  padding: 3px 6px 3px 6px;
+  cursor: pointer;
+  cursor: hand;
+  color: black;
+  font-weight: bold;
+  text-align: center;
+  background: #e3e3e3;
+}
+.gwt-TabLayoutPanel .gwt-TabLayoutPanelTab-selected {
+  cursor: default;
+  background: #bcbcbc;
+}
+
+.gwt-SplitLayoutPanel-HDragger {
+ background: white url(images/splitPanelThumb.png) center center no-repeat;
+  cursor: col-resize;
+}
+
+.gwt-SplitLayoutPanel-VDragger {
+ background: white url(images/splitPanelThumb.png) center center no-repeat;
+  cursor: row-resize;
+}
=======================================
--- /releases/2.0/user/src/com/google/gwt/user/theme/dark/public/gwt/dark/dark.css Tue Dec 1 21:26:37 2009 +++ /releases/2.0/user/src/com/google/gwt/user/theme/dark/public/gwt/dark/dark.css Fri Feb 5 08:10:59 2010
@@ -1031,3 +1031,60 @@
   padding: 0px 4px;
   color: #dddddd;
 }
+
+.gwt-StackLayoutPanel {
+  border-bottom: 1px solid #00CCFF;
+}
+.gwt-StackLayoutPanel .gwt-StackLayoutPanelHeader {
+  cursor: pointer;
+  cursor: hand;
+  font-weight: bold;
+  font-size: 1.3em;
+  padding: 4px;
+  border: 1px solid #00CCFF;
+  border-bottom: 0px;
+  background: #222;
+}
+.gwt-StackLayoutPanel .gwt-StackLayoutPanelContent {
+  border: 1px solid #00CCFF;
+  border-bottom: 0px;
+  background: #666;
+  padding: 2px 2px 10px 5px;
+}
+
+.gwt-TabLayoutPanel {
+}
+.gwt-TabLayoutPanel .gwt-TabLayoutPanelTabs {
+}
+.gwt-TabLayoutPanel .gwt-TabLayoutPanelContent {
+  border-color: #00CCFF;
+  border-style: solid;
+  border-width: 3px 2px 2px;
+  overflow: hidden;
+  padding: 6px;
+}
+.gwt-TabLayoutPanel .gwt-TabLayoutPanelTab {
+  margin-left: 6px;
+  padding: 4px 6px;
+  cursor: pointer;
+  cursor: hand;
+  color: #bec7cc;
+  font-weight: bold;
+  text-align: center;
+  background: #222222;
+}
+.gwt-TabLayoutPanel .gwt-TabLayoutPanelTab-selected {
+  cursor: default;
+  color: black;
+  background: #00CCFF;
+}
+
+.gwt-SplitLayoutPanel-HDragger {
+ background: #00CCFF url(images/splitPanelThumb.png) center center no-repeat;
+  cursor: col-resize;
+}
+
+.gwt-SplitLayoutPanel-VDragger {
+ background: #00CCFF url(images/splitPanelThumb.png) center center no-repeat;
+  cursor: row-resize;
+}
=======================================
--- /releases/2.0/user/src/com/google/gwt/user/theme/dark/public/gwt/dark/dark_rtl.css Tue Dec 1 21:26:37 2009 +++ /releases/2.0/user/src/com/google/gwt/user/theme/dark/public/gwt/dark/dark_rtl.css Fri Feb 5 08:10:59 2010
@@ -1032,3 +1032,60 @@
   padding: 0px 4px;
   color: #dddddd;
 }
+
+.gwt-StackLayoutPanel {
+  border-bottom: 1px solid #00CCFF;
+}
+.gwt-StackLayoutPanel .gwt-StackLayoutPanelHeader {
+  cursor: pointer;
+  cursor: hand;
+  font-weight: bold;
+  font-size: 1.3em;
+  padding: 4px;
+  border: 1px solid #00CCFF;
+  border-bottom: 0px;
+  background: #222;
+}
+.gwt-StackLayoutPanel .gwt-StackLayoutPanelContent {
+  border: 1px solid #00CCFF;
+  border-bottom: 0px;
+  background: #666;
+  padding: 2px 5px 10px 2px;
+}
+
+.gwt-TabLayoutPanel {
+}
+.gwt-TabLayoutPanel .gwt-TabLayoutPanelTabs {
+}
+.gwt-TabLayoutPanel .gwt-TabLayoutPanelContent {
+  border-color: #00CCFF;
+  border-style: solid;
+  border-width: 3px 2px 2px;
+  overflow: hidden;
+  padding: 6px;
+}
+.gwt-TabLayoutPanel .gwt-TabLayoutPanelTab {
+  margin-left: 6px;
+  padding: 4px 6px;
+  cursor: pointer;
+  cursor: hand;
+  color: #bec7cc;
+  font-weight: bold;
+  text-align: center;
+  background: #222222;
+}
+.gwt-TabLayoutPanel .gwt-TabLayoutPanelTab-selected {
+  cursor: default;
+  color: black;
+  background: #00CCFF;
+}
+
+.gwt-SplitLayoutPanel-HDragger {
+ background: #00CCFF url(images/splitPanelThumb.png) center center no-repeat;
+  cursor: col-resize;
+}
+
+.gwt-SplitLayoutPanel-VDragger {
+ background: #00CCFF url(images/splitPanelThumb.png) center center no-repeat;
+  cursor: row-resize;
+}
=======================================
--- /releases/2.0/user/src/com/google/gwt/user/theme/standard/public/gwt/standard/standard.css Tue Dec 1 21:26:37 2009 +++ /releases/2.0/user/src/com/google/gwt/user/theme/standard/public/gwt/standard/standard.css Fri Feb 5 08:10:59 2010
@@ -1080,3 +1080,59 @@
   cursor: pointer;
   padding: 0px 4px;
 }
+
+.gwt-StackLayoutPanel {
+  border-bottom: 1px solid #bbbbbb;
+}
+.gwt-StackLayoutPanel .gwt-StackLayoutPanelHeader {
+  cursor: pointer;
+  cursor: hand;
+  font-weight: bold;
+  font-size: 1.3em;
+  padding: 3px;
+  border: 1px solid #bbbbbb;
+  border-bottom: 0px;
+  background: #d3def6 url(images/hborder.png) repeat-x 0px -989px;
+}
+.gwt-StackLayoutPanel .gwt-StackLayoutPanelContent {
+  border: 1px solid #bbbbbb;
+  border-bottom: 0px;
+  background: white;
+  padding: 2px 2px 10px 5px;
+}
+
+.gwt-TabLayoutPanel {
+}
+.gwt-TabLayoutPanel .gwt-TabLayoutPanelTabs {
+}
+.gwt-TabLayoutPanel .gwt-TabLayoutPanelContent {
+  border-color: #92c1f0;
+  border-style: solid;
+  border-width: 3px 2px 2px;
+  overflow: hidden;
+  padding: 6px;
+}
+.gwt-TabLayoutPanel .gwt-TabLayoutPanelTab {
+  margin-left: 6px;
+  padding: 3px 6px 3px 6px;
+  cursor: pointer;
+  cursor: hand;
+  color: black;
+  font-weight: bold;
+  text-align: center;
+  background: #d0e4f6;
+}
+.gwt-TabLayoutPanel .gwt-TabLayoutPanelTab-selected {
+  cursor: default;
+  background: #92c1f0;
+}
+
+.gwt-SplitLayoutPanel-HDragger {
+ background: #d0e4f6 url(images/splitPanelThumb.png) center center no-repeat;
+  cursor: col-resize;
+}
+
+.gwt-SplitLayoutPanel-VDragger {
+ background: #d0e4f6 url(images/splitPanelThumb.png) center center no-repeat;
+  cursor: row-resize;
+}
=======================================
--- /releases/2.0/user/src/com/google/gwt/user/theme/standard/public/gwt/standard/standard_rtl.css Tue Dec 1 21:26:37 2009 +++ /releases/2.0/user/src/com/google/gwt/user/theme/standard/public/gwt/standard/standard_rtl.css Fri Feb 5 08:10:59 2010
@@ -1081,3 +1081,59 @@
   cursor: pointer;
   padding: 0px 4px;
 }
+
+.gwt-StackLayoutPanel {
+  border-bottom: 1px solid #bbbbbb;
+}
+.gwt-StackLayoutPanel .gwt-StackLayoutPanelHeader {
+  cursor: pointer;
+  cursor: hand;
+  font-weight: bold;
+  font-size: 1.3em;
+  padding: 3px;
+  border: 1px solid #bbbbbb;
+  border-bottom: 0px;
+  background: #d3def6 url(images/hborder.png) repeat-x 0px -989px;
+}
+.gwt-StackLayoutPanel .gwt-StackLayoutPanelContent {
+  border: 1px solid #bbbbbb;
+  border-bottom: 0px;
+  background: white;
+  padding: 2px 5px 10px 2px;
+}
+
+.gwt-TabLayoutPanel {
+}
+.gwt-TabLayoutPanel .gwt-TabLayoutPanelTabs {
+}
+.gwt-TabLayoutPanel .gwt-TabLayoutPanelContent {
+  border-color: #92c1f0;
+  border-style: solid;
+  border-width: 3px 2px 2px;
+  overflow: hidden;
+  padding: 6px;
+}
+.gwt-TabLayoutPanel .gwt-TabLayoutPanelTab {
+  margin-left: 6px;
+  padding: 3px 6px 3px 6px;
+  cursor: pointer;
+  cursor: hand;
+  color: black;
+  font-weight: bold;
+  text-align: center;
+  background: #d0e4f6;
+}
+.gwt-TabLayoutPanel .gwt-TabLayoutPanelTab-selected {
+  cursor: default;
+  background: #92c1f0;
+}
+
+.gwt-SplitLayoutPanel-HDragger {
+ background: #d0e4f6 url(images/splitPanelThumb.png) center center no-repeat;
+  cursor: col-resize;
+}
+
+.gwt-SplitLayoutPanel-VDragger {
+ background: #d0e4f6 url(images/splitPanelThumb.png) center center no-repeat;
+  cursor: row-resize;
+}
=======================================
--- /releases/2.0/user/test/com/google/gwt/uibinder/elementparsers/StackLayoutPanelParserTest.java Tue Nov 10 14:44:37 2009 +++ /releases/2.0/user/test/com/google/gwt/uibinder/elementparsers/StackLayoutPanelParserTest.java Fri Feb 5 08:10:59 2010
@@ -72,8 +72,7 @@
     b.append("</g:StackLayoutPanel>");

     String[] expected = {
-        "fieldName.add(<g:Label id='able'>, "
- + "new com.google.gwt.user.client.ui.HTML(\"Re<b>mark</b>able\"), 3);", + "fieldName.add(<g:Label id='able'>, \"Re<b>mark</b>able\", true, 3);", "fieldName.add(<g:Label id='baker'>, " + "<g:Label id='custom'>, 3);",};

     FieldWriter w = tester.parse(b.toString());
=======================================
--- /releases/2.0/user/test/com/google/gwt/user/client/ui/StackLayoutPanelTest.java Tue Jan 26 08:23:54 2010 +++ /releases/2.0/user/test/com/google/gwt/user/client/ui/StackLayoutPanelTest.java Fri Feb 5 08:10:59 2010
@@ -16,6 +16,12 @@
 package com.google.gwt.user.client.ui;

 import com.google.gwt.dom.client.Style.Unit;
+import com.google.gwt.event.logical.shared.BeforeSelectionEvent;
+import com.google.gwt.event.logical.shared.BeforeSelectionHandler;
+import com.google.gwt.event.logical.shared.SelectionEvent;
+import com.google.gwt.event.logical.shared.SelectionHandler;
+
+import java.util.Iterator;

 /**
  * Tests for {...@link StackLayoutPanel}.
@@ -27,6 +33,19 @@
       ((StackLayoutPanel) container).add(child, new Label("Header"), 1);
     }
   }
+
+ private class TestSelectionHandler implements BeforeSelectionHandler<Integer>, SelectionHandler<Integer> {
+    private boolean onBeforeFired;
+
+    public void onBeforeSelection(BeforeSelectionEvent<Integer> event) {
+      onBeforeFired = true;
+    }
+
+    public void onSelection(SelectionEvent<Integer> event) {
+      assertTrue(onBeforeFired);
+      finishTest();
+    }
+  }

   public void testAttachDetachOrder() {
HasWidgetsTester.testAll(new StackLayoutPanel(Unit.EM), new Adder(), true);
@@ -37,6 +56,122 @@
     StackLayoutPanel p = new StackLayoutPanel(Unit.EM);
     RootPanel.get().add(p);
   }
+
+  public void testInsertMultipleTimes() {
+    StackLayoutPanel p = new StackLayoutPanel(Unit.EM);
+
+    TextBox tb = new TextBox();
+    p.add(tb, "Title", 1);
+    p.add(tb, "Title", 1);
+    p.add(tb, "Title3", 1);
+
+    assertEquals(1, p.getWidgetCount());
+    assertEquals(0, p.getWidgetIndex(tb));
+    Iterator<Widget> i = p.iterator();
+    assertTrue(i.hasNext());
+    assertTrue(tb.equals(i.next()));
+    assertFalse(i.hasNext());
+
+    Label l = new Label();
+    p.add(l, "Title", 1);
+    p.add(l, "Title", 1);
+    p.add(l, "Title3", 1);
+    assertEquals(2, p.getWidgetCount());
+    assertEquals(0, p.getWidgetIndex(tb));
+    assertEquals(1, p.getWidgetIndex(l));
+
+    p.insert(l, "Title", 1, 0);
+    assertEquals(2, p.getWidgetCount());
+    assertEquals(0, p.getWidgetIndex(l));
+    assertEquals(1, p.getWidgetIndex(tb));
+
+    p.insert(l, "Title", 1, 1);
+    assertEquals(2, p.getWidgetCount());
+    assertEquals(0, p.getWidgetIndex(l));
+    assertEquals(1, p.getWidgetIndex(tb));
+
+    p.insert(l, "Title", 1, 2);
+    assertEquals(2, p.getWidgetCount());
+    assertEquals(0, p.getWidgetIndex(tb));
+    assertEquals(1, p.getWidgetIndex(l));
+  }
+
+  public void testInsertWithHTML() {
+    StackLayoutPanel p = new StackLayoutPanel(Unit.EM);
+    Label l = new Label();
+    p.add(l, "three", 1);
+    p.insert(new HTML("<b>hello</b>"), "two", true, 1, 0);
+    p.insert(new HTML("goodbye"), "one", false, 1, 0);
+    assertEquals(3, p.getWidgetCount());
+  }
+
+  /**
+ * Tests to ensure that arbitrary widgets can be added/inserted effectively.
+   */
+  public void testInsertWithWidgets() {
+    StackLayoutPanel p = new StackLayoutPanel(Unit.EM);
+
+    TextBox wa = new TextBox();
+    CheckBox wb = new CheckBox();
+    VerticalPanel wc = new VerticalPanel();
+    wc.add(new Label("First"));
+    wc.add(new Label("Second"));
+
+    p.add(new Label("Content C"), wc, 1);
+    p.insert(new Label("Content B"), wb, 1, 0);
+    p.insert(new Label("Content A"), wa, 1, 0);
+
+    // Call these to ensure we don't throw an exception.
+    assertNotNull(p.getHeaderWidget(0));
+    assertNotNull(p.getHeaderWidget(1));
+    assertNotNull(p.getHeaderWidget(2));
+    assertEquals(3, p.getWidgetCount());
+  }
+
+  public void testIterator() {
+    StackLayoutPanel p = new StackLayoutPanel(Unit.EM);
+    HTML foo = new HTML("foo");
+    HTML bar = new HTML("bar");
+    HTML baz = new HTML("baz");
+    p.add(foo, "foo", 1);
+    p.add(bar, "bar", 1);
+    p.add(baz, "baz", 1);
+
+    // Iterate over the entire set and make sure it stops correctly.
+    Iterator<Widget> it = p.iterator();
+    assertTrue(it.hasNext());
+    assertTrue(it.next() == foo);
+    assertTrue(it.hasNext());
+    assertTrue(it.next() == bar);
+    assertTrue(it.hasNext());
+    assertTrue(it.next() == baz);
+    assertFalse(it.hasNext());
+
+    // Test removing using the iterator.
+    it = p.iterator();
+    it.next();
+    it.remove();
+    assertTrue(it.next() == bar);
+    assertTrue(p.getWidgetCount() == 2);
+    assertTrue(p.getWidget(0) == bar);
+    assertTrue(p.getWidget(1) == baz);
+  }
+
+  public void testSelectionEvents() {
+    StackLayoutPanel p = new StackLayoutPanel(Unit.EM);
+    RootPanel.get().add(p);
+
+    p.add(new Button("foo"), "foo", 1);
+    p.add(new Button("bar"), "bar", 1);
+
+    // Make sure selecting a stack fires both events in the right order.
+    TestSelectionHandler handler = new TestSelectionHandler();
+    p.addBeforeSelectionHandler(handler);
+    p.addSelectionHandler(handler);
+
+    delayTestFinish(2000);
+    p.showWidget(1);
+  }

   public void testVisibleWidget() {
     StackLayoutPanel p = new StackLayoutPanel(Unit.EM);

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

Reply via email to