Revision: 6080
Author: [email protected]
Date: Thu Sep  3 12:28:14 2009
Log: - Changed Requires/ProvidesLayout => Requires/ProvidesResize; some  
small doc
additions.
- Added RequiresLayout; moved doc into it.
- Added LayoutPanelExample.
- Added DockLayoutPanel.
- A bit of cleanup here and there.

Review: http://gwt-code-reviews.appspot.com/63801
http://code.google.com/p/google-web-toolkit/source/detail?r=6080

Added:
  /trunk/user/javadoc/com/google/gwt/examples/DockLayoutPanelExample.java
  /trunk/user/javadoc/com/google/gwt/examples/LayoutExample.java
  /trunk/user/src/com/google/gwt/user/client/ui/DockLayoutPanel.java
  /trunk/user/src/com/google/gwt/user/client/ui/ProvidesResize.java
  /trunk/user/src/com/google/gwt/user/client/ui/RequiresResize.java
Deleted:
  /trunk/user/src/com/google/gwt/layout/client/UserAgent.java
  /trunk/user/src/com/google/gwt/user/client/ui/ProvidesLayout.java
Modified:
  /trunk/user/javadoc/com/google/gwt/examples/LayoutPanelExample.java
  /trunk/user/src/com/google/gwt/layout/client/Layout.java
  /trunk/user/src/com/google/gwt/layout/client/LayoutImpl.java
  /trunk/user/src/com/google/gwt/layout/client/LayoutImplIE6.java
  /trunk/user/src/com/google/gwt/user/client/ui/LayoutComposite.java
  /trunk/user/src/com/google/gwt/user/client/ui/LayoutPanel.java
  /trunk/user/src/com/google/gwt/user/client/ui/RequiresLayout.java
  /trunk/user/src/com/google/gwt/user/client/ui/RootLayoutPanel.java

=======================================
--- /dev/null
+++ /trunk/user/javadoc/com/google/gwt/examples/DockLayoutPanelExample.java     
 
Thu Sep  3 12:28:14 2009
@@ -0,0 +1,51 @@
+/*
+ * 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
+ * License for the specific language governing permissions and limitations  
under
+ * the License.
+ */
+package com.google.gwt.examples;
+
+import com.google.gwt.core.client.EntryPoint;
+import com.google.gwt.dom.client.Style.Unit;
+import com.google.gwt.user.client.ui.DockLayoutPanel;
+import com.google.gwt.user.client.ui.HTML;
+import com.google.gwt.user.client.ui.RootLayoutPanel;
+import com.google.gwt.user.client.ui.DockLayoutPanel.Direction;
+
+public class DockLayoutPanelExample implements EntryPoint {
+
+  public void onModuleLoad() {
+    // Attach five widgets to a DockLayoutPanel, one in each direction. Lay
+    // them out in 'em' units.
+    DockLayoutPanel p = new DockLayoutPanel(Unit.EM);
+    p.add(new HTML("north"), Direction.NORTH, 2);
+    p.add(new HTML("south"), Direction.SOUTH, 2);
+    p.add(new HTML("east"), Direction.EAST, 2);
+    p.add(new HTML("west"), Direction.WEST, 2);
+    p.add(new HTML("center"), Direction.CENTER, 2);
+
+    // Note the explicit call to layout(). This is required for the layout  
to
+    // take effect.
+    p.layout();
+
+    // Attach the LayoutPanel to the RootLayoutPanel. The latter will  
listen for
+    // resize events on the window to ensure that its children are  
informed of
+    // possible size changes.
+    RootLayoutPanel rp = RootLayoutPanel.get();
+    rp.add(p);
+
+    // The RootLayoutPanel also requires that its layout() method be  
explicitly
+    // called for the initial layout to take effect.
+    rp.layout();
+  }
+}
=======================================
--- /dev/null
+++ /trunk/user/javadoc/com/google/gwt/examples/LayoutExample.java      Thu Sep 
  
3 12:28:14 2009
@@ -0,0 +1,63 @@
+/*
+ * 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
+ * License for the specific language governing permissions and limitations  
under
+ * the License.
+ */
+package com.google.gwt.examples;
+
+import static com.google.gwt.dom.client.Style.Unit.EM;
+import static com.google.gwt.dom.client.Style.Unit.PCT;
+import static com.google.gwt.dom.client.Style.Unit.PX;
+
+import com.google.gwt.core.client.EntryPoint;
+import com.google.gwt.dom.client.Document;
+import com.google.gwt.dom.client.Element;
+import com.google.gwt.layout.client.Layout;
+import com.google.gwt.layout.client.Layout.Layer;
+
+public class LayoutExample implements EntryPoint {
+
+  public void onModuleLoad() {
+    // The following is a very simple example, which constructs a layout  
around
+    // a parent element, and attaches two child elements that split their
+    // parent's space vertically. It then goes on to animate from the first
+    // state to a horizontal stacking that uses EM units rather than
+    // percentages.
+    Document doc = Document.get();
+    Element parent = doc.createDivElement();
+    doc.getBody().appendChild(parent);
+
+    Layout layout = new Layout(parent);
+    layout.onAttach();
+
+    Element topChild = doc.createDivElement(), bottomChild = doc
+        .createDivElement();
+    Layer topLayer = layout.attachChild(topChild);
+    Layer bottomLayer = layout.attachChild(bottomChild);
+
+    // Stack the two children vertically, meeting at 50%.
+    topLayer.setLeftRight(0, PX, 0, PX);
+    bottomLayer.setLeftRight(0, PX, 0, PX);
+    topLayer.setTopHeight(0, PCT, 50, PCT);
+    bottomLayer.setBottomHeight(0, PCT, 50, PCT);
+    layout.layout();
+
+    // Update the two children to stack horizontally, meeting at 10em.
+    // Also have them animate for 500ms.
+    topLayer.setTopBottom(0, PX, 0, PX);
+    bottomLayer.setTopBottom(0, PX, 0, PX);
+    topLayer.setLeftWidth(0, EM, 10, EM);
+    bottomLayer.setLeftRight(10, EM, 0, EM);
+    layout.layout(500);
+  }
+}
=======================================
--- /dev/null
+++ /trunk/user/src/com/google/gwt/user/client/ui/DockLayoutPanel.java  Thu  
Sep  3 12:28:14 2009
@@ -0,0 +1,296 @@
+/*
+ * 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
+ * License for the specific language governing permissions and limitations  
under
+ * the License.
+ */
+package com.google.gwt.user.client.ui;
+
+import com.google.gwt.dom.client.Document;
+import com.google.gwt.dom.client.Element;
+import com.google.gwt.dom.client.Style.Unit;
+import com.google.gwt.layout.client.Layout;
+import com.google.gwt.layout.client.Layout.Layer;
+
+/**
+ * A panel that lays its child widgets out "docked" at its outer edges, and
+ * allows its last widget to take up the remaining space in its center.
+ *
+ * <p>
+ * Whenever children are added to, or removed from, this panel, you must  
call
+ * one of {...@link #layout()}, {...@link #layout(int)}, or
+ * {...@link #layout(int,  
com.google.gwt.layout.client.Layout.AnimationCallback)}
+ * to update the panel's layout.
+ * </p>
+ *
+ * <p>
+ * This widget will <em>only</em> work in standards mode, which requires
+ * that the HTML page in which it is run have an explicit &lt;!DOCTYPE&gt;
+ * declaration.
+ * </p>
+ *
+ * <p>
+ * NOTE: This class is still very new, and its interface may change without
+ * warning. Use at your own risk.
+ * </p>
+ *
+ * <p>
+ * <h3>Example</h3>
+ * {...@example com.google.gwt.examples.DockLayoutPanelExample}
+ * </p>
+ *
+ * TODO(jgw): RTL support.
+ */
+public class DockLayoutPanel extends ComplexPanel implements  
RequiresLayout,
+    RequiresResize, ProvidesResize {
+
+  /**
+   * Used in {...@link DockLayoutPanel#add(Widget, Direction, double)} to  
specify
+   * the direction in which a child widget will be added.
+   */
+  public enum Direction {
+    NORTH, EAST, SOUTH, WEST, CENTER, LINE_START, LINE_END
+  }
+
+  protected static class LayoutData {
+    public Direction direction;
+    public double oldSize, size;
+    public double originalSize;
+    public boolean hidden;
+    public Layer layer;
+
+    public LayoutData(Direction direction, double size, Layer layer) {
+      this.direction = direction;
+      this.size = size;
+      this.layer = layer;
+    }
+  }
+
+  private final Unit unit;
+  private Widget center;
+  private final Layout layout;
+
+  /**
+   * Creates an empty dock panel.
+   *
+   * @param unit the unit to be used for layout
+   */
+  public DockLayoutPanel(Unit unit) {
+    this.unit = unit;
+
+    setElement(Document.get().createDivElement());
+    layout = new Layout(getElement());
+  }
+
+  /**
+   * Adds a widget to the specified edge of the dock. If the widget is  
already a
+   * child of this panel, this method behaves as though {...@link  
#remove(Widget)}
+   * had already been called.
+   *
+   * @param widget the widget to be added
+   * @param direction the widget's direction in the dock
+   *
+   * @throws IllegalArgumentException when adding to the {...@link #CENTER}  
and
+   *           there is already a different widget there
+   */
+  public void add(Widget widget, Direction direction, double size) {
+    insert(widget, direction, size, null);
+  }
+
+  /**
+   * Adds a widget to the specified edge of the dock. If the widget is  
already a
+   * child of this panel, this method behaves as though {...@link  
#remove(Widget)}
+   * had already been called.
+   *
+   * @param widget the widget to be added
+   * @param direction the widget's direction in the dock
+   * @param before the widget before which to insert the new child, or
+   *          <code>null</code> to append
+   *
+   * @throws IllegalArgumentException when adding to the {...@link #CENTER}  
and
+   *           there is already a different widget there
+   */
+  public void insert(Widget widget, Direction direction, double size,
+      Widget before) {
+    assertIsChild(before);
+
+    // Validation.
+    if (before == null) {
+      assert center == null : "No widget may be added after the CENTER  
widget";
+    } else {
+      assert direction != Direction.CENTER : "A CENTER widget must always  
be added last";
+    }
+
+    // Detach new child.
+    widget.removeFromParent();
+
+    // Logical attach.
+    getChildren().add(widget);
+    if (direction == Direction.CENTER) {
+      center = widget;
+    }
+
+    // Physical attach.
+    Layer layer = layout.attachChild(widget.getElement(),
+        (before != null) ? before.getElement() : null, widget);
+    LayoutData data = new LayoutData(direction, size, layer);
+    widget.setLayoutData(data);
+
+    // Adopt.
+    adopt(widget);
+  }
+
+  /**
+   * Gets the layout direction of the given child widget.
+   *
+   * @param w the widget to be queried
+   * @return the widget's layout direction, or <code>null</code> if it is  
not a
+   *         child of this panel
+   */
+  public Direction getWidgetDirection(Widget w) {
+    if (w.getParent() != this) {
+      return null;
+    }
+    return ((LayoutData) w.getLayoutData()).direction;
+  }
+
+  public void onResize() {
+    for (Widget child : getChildren()) {
+      if (child instanceof RequiresResize) {
+        ((RequiresResize) child).onResize();
+      }
+    }
+  }
+
+  @Override
+  public boolean remove(Widget w) {
+    boolean removed = super.remove(w);
+    if (removed) {
+      // Clear the center widget.
+      if (w == center) {
+        center = null;
+      }
+
+      LayoutData data = (LayoutData) w.getLayoutData();
+      layout.removeChild(data.layer);
+    }
+
+    return removed;
+  }
+
+  protected Widget getCenter() {
+    return center;
+  }
+
+  protected Unit getUnit() {
+    return unit;
+  }
+
+  @Override
+  protected void onLoad() {
+    layout.onAttach();
+  }
+
+  @Override
+  protected void onUnload() {
+    layout.onDetach();
+  }
+
+  public void layout() {
+    layout(0);
+  }
+
+  public void layout(int duration) {
+    layout(0, null);
+  }
+
+  public void layout(int duration, final Layout.AnimationCallback  
callback) {
+    int left = 0, top = 0, right = 0, bottom = 0;
+
+    for (Widget child : getChildren()) {
+      LayoutData data = (LayoutData) child.getLayoutData();
+      Layer layer = data.layer;
+
+      switch (data.direction) {
+        case NORTH:
+          layer.setLeftRight(left, unit, right, unit);
+          layer.setTopHeight(top, unit, data.size, unit);
+          top += data.size;
+          break;
+
+        case SOUTH:
+          layer.setLeftRight(left, unit, right, unit);
+          layer.setBottomHeight(bottom, unit, data.size, unit);
+          bottom += data.size;
+          break;
+
+        case WEST:
+          layer.setTopBottom(top, unit, bottom, unit);
+          layer.setLeftWidth(left, unit, data.size, unit);
+          left += data.size;
+          break;
+
+        case EAST:
+          layer.setTopBottom(top, unit, bottom, unit);
+          layer.setRightWidth(right, unit, data.size, unit);
+          right += data.size;
+          break;
+
+        case CENTER:
+          layer.setLeftRight(left, unit, right, unit);
+          layer.setTopBottom(top, unit, bottom, unit);
+          break;
+      }
+    }
+
+    layout.layout(duration, new Layout.AnimationCallback() {
+      public void onAnimationComplete() {
+        for (Widget child : getChildren()) {
+          LayoutData data = (LayoutData) child.getLayoutData();
+          if (data.size != data.oldSize) {
+            data.oldSize = data.size;
+            if (child instanceof RequiresResize) {
+              ((RequiresResize) child).onResize();
+            }
+          }
+
+          if (callback != null) {
+            callback.onAnimationComplete();
+          }
+        }
+      }
+
+      public void onLayout(Layer layer, double progress) {
+        Widget child = (Widget) layer.getUserObject();
+        if (child instanceof RequiresResize) {
+          ((RequiresResize) child).onResize();
+        }
+
+        if (callback != null) {
+          callback.onLayout(layer, progress);
+        }
+      }
+    });
+  }
+
+  /**
+   * TODO(jgw): Is this really the best way to do this?
+   */
+  public Element getContainerElementFor(Widget widget) {
+    assertIsChild(widget);
+    return  
((LayoutData)widget.getLayoutData()).layer.getContainerElement();
+  }
+
+  private void assertIsChild(Widget widget) {
+    assert (widget == null) || (widget.getParent() == this) : "TODO";
+  }
+}
=======================================
--- /dev/null
+++ /trunk/user/src/com/google/gwt/user/client/ui/ProvidesResize.java   Thu  
Sep  3 12:28:14 2009
@@ -0,0 +1,40 @@
+/*
+ * 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
+ * License for the specific language governing permissions and limitations  
under
+ * the License.
+ */
+package com.google.gwt.user.client.ui;
+
+/**
+ * This tag interface specifies that the implementing widget will call
+ * {...@link RequiresResize#onResize()} on its children whenever their size  
may
+ * have changed.
+ *
+ * <p>
+ * With limited exceptions (such as {...@link RootLayoutPanel}), widgets that
+ * implement this interface will also implement {...@link RequiresResize}. A  
typical
+ * widget will implement {...@link RequiresResize#onResize()} like this:
+ *
+ * <code>
+ * public void onResize() {
+ *   for (Widget child : getChildren()) {
+ *     if (child instanceof RequiresResize) {
+ *       ((RequiresResize) child).onResize();
+ *     }
+ *   }
+ * }
+ * </code>
+ * </p>
+ */
+public interface ProvidesResize {
+}
=======================================
--- /dev/null
+++ /trunk/user/src/com/google/gwt/user/client/ui/RequiresResize.java   Thu  
Sep  3 12:28:14 2009
@@ -0,0 +1,35 @@
+/*
+ * 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
+ * License for the specific language governing permissions and limitations  
under
+ * the License.
+ */
+package com.google.gwt.user.client.ui;
+
+/**
+ * This interface designates that its implementor needs to be informed  
whenever
+ * its size is modified.
+ *
+ * <p>
+ * Widgets that implement this interface should only be added to those that
+ * implement {...@link ProvidesResize}. Failure to do so will usually result  
in
+ * {...@link #onResize()} not being called.
+ * </p>
+ */
+public interface RequiresResize {
+
+  /**
+   * This method must be called whenever the implementor's size has been
+   * modified.
+   */
+  void onResize();
+}
=======================================
--- /trunk/user/src/com/google/gwt/layout/client/UserAgent.java Tue Aug  4  
14:08:06 2009
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * 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
- * License for the specific language governing permissions and limitations  
under
- * the License.
- */
-package com.google.gwt.layout.client;
-
-/**
- * User-Agent utility methods used by {...@link LayoutImplIE6}.
- *
- * TODO: Generalize this, move it into a common place, and make it  
available for
- * use by other classes.
- */
-class UserAgent {
-
-  // Stolen and modified from UserAgent.gwt.xml.
-  public static native boolean isIE6() /*-{
-     function makeVersion(result) {
-       return (parseInt(result[1]) * 1000) + parseInt(result[2]);
-     }
-
-     var ua = navigator.userAgent.toLowerCase();
-     if (ua.indexOf("msie") != -1) {
-       var result = /msie ([0-9]+)\.([0-9]+)/.exec(ua);
-       if (result && result.length == 3) {
-         var v = makeVersion(result);
-         if (v < 7000) {
-           return true;
-         }
-       }
-     }
-
-     return false;
-   }-*/;
-}
=======================================
--- /trunk/user/src/com/google/gwt/user/client/ui/ProvidesLayout.java   Tue  
Aug  4 14:08:06 2009
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * 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
- * License for the specific language governing permissions and limitations  
under
- * the License.
- */
-package com.google.gwt.user.client.ui;
-
-/**
- * This tag interface specifies that the implementing widget will call
- * {...@link RequiresLayout#onLayout()} on its children whenever their size  
may
- * have changed.
- *
- * <p>
- * With limited exceptions (such as {...@link RootLayoutPanel}), widgets that
- * implement this interface will also implement {...@link RequiresLayout}. A  
typical
- * widget will implement {...@link RequiresLayout#onLayout()} like this:
- *
- * <code>
- * public void onLayout() {
- *   for (Widget child : getChildren()) {
- *     if (child instanceof RequiresLayout) {
- *       ((RequiresLayout) child).onLayout();
- *     }
- *   }
- * }
- * </code>
- * </p>
- */
-public interface ProvidesLayout {
-}
=======================================
--- /trunk/user/src/com/google/gwt/layout/client/Layout.java    Wed Aug  5  
07:51:26 2009
+++ /trunk/user/src/com/google/gwt/layout/client/Layout.java    Thu Sep  3  
12:28:14 2009
@@ -317,6 +317,23 @@
    public Layer attachChild(Element child) {
      return attachChild(child, null);
    }
+
+  /**
+   * Attaches a child element to this layout.
+   *
+   * <p>
+   * This method will attach the child to the layout, removing it from its
+   * current parent element. Use the {...@link Layer} it returns to  
manipulate the
+   * child.
+   * </p>
+   *
+   * @param child the child to be attached
+   * @param before the child element before which to insert
+   * @return the {...@link Layer} associated with the element
+   */
+  public Layer attachChild(Element child, Element before) {
+    return attachChild(child, before, null);
+  }

    /**
     * Attaches a child element to this layout.
@@ -332,7 +349,25 @@
     * @return the {...@link Layer} associated with the element
     */
    public Layer attachChild(Element child, Object userObject) {
-    Element container = impl.attachChild(parentElem, child);
+    return attachChild(child, null, userObject);
+  }
+
+  /**
+   * Attaches a child element to this layout.
+   *
+   * <p>
+   * This method will attach the child to the layout, removing it from its
+   * current parent element. Use the {...@link Layer} it returns to  
manipulate the
+   * child.
+   * </p>
+   *
+   * @param child the child to be attached
+   * @param before the child element before which to insert
+   * @param userObject an arbitrary object to be associated with this layer
+   * @return the {...@link Layer} associated with the element
+   */
+  public Layer attachChild(Element child, Element before, Object  
userObject) {
+    Element container = impl.attachChild(parentElem, child, before);
      Layer layer = new Layer(container, child, userObject);
      layers.add(layer);
      return layer;
=======================================
--- /trunk/user/src/com/google/gwt/layout/client/LayoutImpl.java        Wed Aug 
 5  
07:51:26 2009
+++ /trunk/user/src/com/google/gwt/layout/client/LayoutImpl.java        Thu Sep 
 3  
12:28:14 2009
@@ -24,6 +24,7 @@
  import com.google.gwt.dom.client.Document;
  import com.google.gwt.dom.client.Element;
  import com.google.gwt.dom.client.Style;
+import com.google.gwt.dom.client.Style.Overflow;
  import com.google.gwt.dom.client.Style.Position;
  import com.google.gwt.dom.client.Style.Unit;
  import com.google.gwt.layout.client.Layout.Layer;
@@ -60,20 +61,21 @@

    protected DivElement relativeRuler;

-  public Element attachChild(Element parent, Element child) {
+  public Element attachChild(Element parent, Element child, Element  
before) {
      DivElement container = Document.get().createDivElement();
      container.appendChild(child);

-    container.getStyle().setProperty("position", "absolute");
-    container.getStyle().setProperty("overflow", "hidden");
+    container.getStyle().setPosition(Position.ABSOLUTE);
+    container.getStyle().setOverflow(Overflow.HIDDEN);

      fillParent(child);

-    Style style = child.getStyle();
-    style.setWidth(100, Unit.PCT);
-    style.setHeight(100, Unit.PCT);
-
-    parent.appendChild(container);
+    Element beforeContainer = null;
+    if (before != null) {
+      beforeContainer = before.getParentElement();
+      assert beforeContainer.getParentElement() == parent : "Element to  
insert before must be a sibling";
+    }
+    parent.insertBefore(container, beforeContainer);
      return container;
    }

@@ -118,7 +120,7 @@
    }

    public void initParent(Element parent) {
-    parent.getStyle().setProperty("position", "relative");
+    parent.getStyle().setPosition(Position.RELATIVE);
      parent.appendChild(relativeRuler = createRuler(EM, EX));
    }

=======================================
--- /trunk/user/src/com/google/gwt/layout/client/LayoutImplIE6.java     Wed  
Aug  5 07:51:26 2009
+++ /trunk/user/src/com/google/gwt/layout/client/LayoutImplIE6.java     Thu  
Sep  3 12:28:14 2009
@@ -38,6 +38,30 @@
   */
  class LayoutImplIE6 extends LayoutImpl {

+  private static boolean isIE6 = isIE6();
+
+  // Stolen and modified from UserAgent.gwt.xml.
+  // TODO(jgw): Get rid of this method, and switch to using soft  
permutations
+  // once they land in trunk.
+  private static native boolean isIE6() /*-{
+     function makeVersion(result) {
+       return (parseInt(result[1]) * 1000) + parseInt(result[2]);
+     }
+
+     var ua = navigator.userAgent.toLowerCase();
+     if (ua.indexOf("msie") != -1) {
+       var result = /msie ([0-9]+)\.([0-9]+)/.exec(ua);
+       if (result && result.length == 3) {
+         var v = makeVersion(result);
+         if (v < 7000) {
+           return true;
+         }
+       }
+     }
+
+     return false;
+   }-*/;
+
    private static Element createStyleRuler(Element parent) {
      DivElement styleRuler = Document.get().createDivElement();
      DivElement styleInner = Document.get().createDivElement();
@@ -111,13 +135,14 @@
      elem[name] = value;
    }-*/;

-  public Element attachChild(Element parent, Element child) {
-    if (!UserAgent.isIE6()) {
-      return super.attachChild(parent, child);
+  @Override
+  public Element attachChild(Element parent, Element child, Element  
before) {
+    if (!isIE6) {
+      return super.attachChild(parent, child, before);
      }

      DivElement container = Document.get().createDivElement();
-    container.appendChild(child);
+    container.insertBefore(child, before);

      container.getStyle().setPosition(Position.ABSOLUTE);
      container.getStyle().setOverflow(Overflow.HIDDEN);
@@ -127,13 +152,18 @@
      // the child element, so that measureDecoration(child) will work.
      setPropertyElement(child, "__styleRuler", createStyleRuler(container));

-    parent.appendChild(container);
+    Element beforeContainer = null;
+    if (before != null) {
+      beforeContainer = before.getParentElement();
+      assert beforeContainer.getParentElement() == parent : "Element to  
insert before must be a sibling";
+    }
+    parent.insertBefore(container, beforeContainer);
      return container;
    }

    @Override
    public void fillParent(Element elem) {
-    if (!UserAgent.isIE6()) {
+    if (!isIE6) {
        super.fillParent(elem);
        return;
      }
@@ -143,7 +173,7 @@

    @Override
    public void finalizeLayout(Element parent) {
-    if (!UserAgent.isIE6()) {
+    if (!isIE6) {
        super.finalizeLayout(parent);
        return;
      }
@@ -156,13 +186,13 @@
    public void initParent(Element parent) {
      super.initParent(parent);

-    if (UserAgent.isIE6()) {
+    if (isIE6) {
        setPropertyElement(parent, "__styleRuler", createStyleRuler(parent));
      }
    }

    public void layout(Layer layer) {
-    if (!UserAgent.isIE6()) {
+    if (!isIE6) {
        super.layout(layer);
        return;
      }
@@ -173,7 +203,7 @@

    @Override
    public void onAttach(Element parent) {
-    if (UserAgent.isIE6()) {
+    if (isIE6) {
        // No need to re-connect layer refs. This will be taken care of
        // automatically in layout().
        initResizeHandler(parent);
@@ -183,7 +213,7 @@

    @Override
    public void onDetach(Element parent) {
-    if (UserAgent.isIE6()) {
+    if (isIE6) {
        removeLayerRefs(parent);
        removeResizeHandler(parent);
        removeUnitChangeHandler(relativeRuler);
=======================================
--- /trunk/user/src/com/google/gwt/user/client/ui/LayoutComposite.java  Tue  
Aug  4 14:08:06 2009
+++ /trunk/user/src/com/google/gwt/user/client/ui/LayoutComposite.java  Thu  
Sep  3 12:28:14 2009
@@ -16,20 +16,20 @@
  package com.google.gwt.user.client.ui;

  /**
- * A {...@link Composite} implementation that implements {...@link  
RequiresLayout} and
+ * A {...@link Composite} implementation that implements {...@link  
RequiresResize} and
   * automatically delegates that interface's methods to its wrapped widget,  
which
- * must itself implement {...@link RequiresLayout}.
+ * must itself implement {...@link RequiresResize}.
   */
-public abstract class LayoutComposite extends Composite implements  
RequiresLayout {
+public abstract class LayoutComposite extends Composite implements  
RequiresResize {

    @Override
    protected void initWidget(Widget widget) {
-    assert widget instanceof RequiresLayout :
+    assert widget instanceof RequiresResize :
        "LayoutComposite requires that its wrapped widget implement  
HasLayout";
      super.initWidget(widget);
    }

-  public void onLayout() {
-    ((RequiresLayout) getWidget()).onLayout();
+  public void onResize() {
+    ((RequiresResize) getWidget()).onResize();
    }
  }
=======================================
--- /trunk/user/src/com/google/gwt/user/client/ui/LayoutPanel.java      Wed Aug 
  
5 07:51:26 2009
+++ /trunk/user/src/com/google/gwt/user/client/ui/LayoutPanel.java      Thu Sep 
  
3 12:28:14 2009
@@ -24,8 +24,15 @@
   * using the {...@link Layout} class.
   *
   * <p>
- * NOTE: This widget will <em>only</em> work in standards mode, which  
requires
- * that the HTML page in which it is run have an explicit &lt;!DOCTYPE&gt;
+ * Whenever children are added to, or removed from, this panel, you must  
call
+ * one of {...@link #layout()}, {...@link #layout(int)}, or
+ * {...@link #layout(int,  
com.google.gwt.layout.client.Layout.AnimationCallback)}
+ * to update the panel's layout.
+ * </p>
+ *
+ * <p>
+ * This widget will <em>only</em> work in standards mode, which requires  
that
+ * the HTML page in which it is run have an explicit &lt;!DOCTYPE&gt;
   * declaration.
   * </p>
   *
@@ -40,7 +47,7 @@
   * </p>
   */
  public class LayoutPanel extends ComplexPanel implements RequiresLayout,
-    ProvidesLayout {
+    RequiresResize, ProvidesResize {

    private final Layout layout;

@@ -84,7 +91,7 @@
     *
     * <p>
     * After you have made changes to any of the child widgets' constraints,  
you
-   * must call one of the {...@link HasAnimatedLayout} methods for those  
changes to
+   * must call one of the {...@link RequiresLayout} methods for those changes  
to
     * be reflected visually.
     * </p>
     *
@@ -96,52 +103,14 @@
      return (Layout.Layer) child.getLayoutData();
    }

-  /**
-   * This method, or one of its overloads, must be called whenever any of  
the
-   * {...@link Layout.Layer layers} associated with its children is modified.
-   *
-   * @see #layout(int)
-   * @see #layout(int,  
com.google.gwt.layout.client.Layout.AnimationCallback)
-   */
    public void layout() {
      layout.layout();
    }

-  /**
-   * This method, or one of its overloads, must be called whenever any of  
the
-   * {...@link Layout.Layer layers} associated with its children is modified.
-   *
-   * <p>
-   * This overload will cause the layout to be updated by animating over a
-   * specified period of time.
-   * </p>
-   *
-   * @param duration the animation duration, in milliseconds
-   *
-   * @see #layout()
-   * @see #layout(int,  
com.google.gwt.layout.client.Layout.AnimationCallback)
-   */
    public void layout(int duration) {
      layout.layout(duration);
    }

-  /**
-   * This method, or one of its overloads, must be called whenever any of  
the
-   * {...@link Layout.Layer layers} associated with its children is modified.
-   *
-   * <p>
-   * This overload will cause the layout to be updated by animating over a
-   * specified period of time. In addition, it provides a callback that  
will be
-   * informed of updates to the layers. This can be used to create more  
complex
-   * animation effects.
-   * </p>
-   *
-   * @param duration the animation duration, in milliseconds
-   * @param callback the animation callback
-   *
-   * @see #layout()
-   * @see #layout(int,  
com.google.gwt.layout.client.Layout.AnimationCallback)
-   */
    public void layout(int duration, final Layout.AnimationCallback  
callback) {
      layout.layout(duration, new Layout.AnimationCallback() {
        public void onAnimationComplete() {
@@ -155,8 +124,8 @@
          // Inform the child associated with this layer that its size may  
have
          // changed.
          Widget child = (Widget) layer.getUserObject();
-        if (child instanceof RequiresLayout) {
-          ((RequiresLayout) child).onLayout();
+        if (child instanceof RequiresResize) {
+          ((RequiresResize) child).onResize();
          }

          // Chain to the passed callback.
@@ -167,10 +136,10 @@
      });
    }

-  public void onLayout() {
+  public void onResize() {
      for (Widget child : getChildren()) {
-      if (child instanceof RequiresLayout) {
-        ((RequiresLayout) child).onLayout();
+      if (child instanceof RequiresResize) {
+        ((RequiresResize) child).onResize();
        }
      }
    }
=======================================
--- /trunk/user/src/com/google/gwt/user/client/ui/RequiresLayout.java   Tue  
Aug  4 14:08:06 2009
+++ /trunk/user/src/com/google/gwt/user/client/ui/RequiresLayout.java   Thu  
Sep  3 12:28:14 2009
@@ -15,20 +15,54 @@
   */
  package com.google.gwt.user.client.ui;

+import com.google.gwt.layout.client.Layout;
+
  /**
- * This interface designates that its implementor needs to be informed  
whenever
- * its size is modified.
+ * Designates that a widget requires a method to be explicitly called  
after its
+ * children are modified.
   *
   * <p>
- * Widgets that implement this interface should only be added to those that
- * implement {...@link ProvidesLayout}. Failure to do so will usually result  
in
- * {...@link #onLayout()} not being called.
+ * Widgets that implement this interface perform some layout work that  
will not
+ * be fully realized until {...@link #layout()} or one of its overloads is  
called.
+ * This is required after adding or removing child widgets, and after any  
other
+ * operations that the implementor designates as requiring layout. Note  
that
+ * only <em>one</em> call to {...@link #layout()} is required after any  
number of
+ * modifications.
   * </p>
   */
  public interface RequiresLayout {

    /**
-   * Update the layout immediately.
+   * Layout children immediately.
+   *
+   * @see #layout(int)
+   * @see #layout(int,  
com.google.gwt.layout.client.Layout.AnimationCallback)
     */
-  void onLayout();
-}
+  void layout();
+
+  /**
+   * Layout children, animating over the specified period of time.
+   *
+   * @param duration the animation duration, in milliseconds
+   *
+   * @see #layout()
+   * @see #layout(int,  
com.google.gwt.layout.client.Layout.AnimationCallback)
+   */
+  void layout(int duration);
+
+  /**
+   * Layout children, animating over the specified period of time.
+   *
+   * <p>
+   * This method provides a callback that will be informed of animation  
updates.
+   * This can be used to create more complex animation effects.
+   * </p>
+   *
+   * @param duration the animation duration, in milliseconds
+   * @param callback the animation callback
+   *
+   * @see #layout()
+   * @see #layout(int,  
com.google.gwt.layout.client.Layout.AnimationCallback)
+   */
+  void layout(int duration, final Layout.AnimationCallback callback);
+}
=======================================
--- /trunk/user/src/com/google/gwt/user/client/ui/RootLayoutPanel.java  Wed  
Aug  5 07:51:26 2009
+++ /trunk/user/src/com/google/gwt/user/client/ui/RootLayoutPanel.java  Thu  
Sep  3 12:28:14 2009
@@ -24,7 +24,7 @@
   * to the document body (i.e. {...@link RootPanel#get()}).
   *
   * <p>
- * This panel automatically calls {...@link RequiresLayout#layout()} on  
itself when
+ * This panel automatically calls {...@link RequiresResize#layout()} on  
itself when
   * initially created, and whenever the window is resized.
   * </p>
   *
@@ -44,7 +44,7 @@
   * {...@example com.google.gwt.examples.LayoutPanelExample}
   * </p>
   */
-public class RootLayoutPanel extends LayoutPanel implements ProvidesLayout  
{
+public class RootLayoutPanel extends LayoutPanel {

    private static RootLayoutPanel singleton;

@@ -70,11 +70,11 @@
    private RootLayoutPanel() {
      Window.addResizeHandler(new ResizeHandler() {
        public void onResize(ResizeEvent event) {
-        onLayout();
+        RootLayoutPanel.this.onResize();
        }
      });

-    // TODO: We need notification of font-size changes as well.
+    // TODO(jgw): We need notification of font-size changes as well.
      // I believe there's a hidden iframe trick that we can use to get
      // a font-size-change event (really an em-definition-change event).
    }

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

Reply via email to