Adds the ability to position child elements within their layers.
Review: http://gwt-code-reviews.appspot.com/78809

git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@6349 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/user/src/com/google/gwt/layout/client/Layout.java b/user/src/com/google/gwt/layout/client/Layout.java
index a4efe5e..8d678de 100644
--- a/user/src/com/google/gwt/layout/client/Layout.java
+++ b/user/src/com/google/gwt/layout/client/Layout.java
@@ -78,6 +78,27 @@
 public class Layout {
 
   /**
+   * Used to specify the alignment of child elements within a layer.
+   */
+  public enum Alignment {
+
+    /**
+     * Positions an element at the beginning of a given axis.
+     */
+    BEGIN,
+
+    /**
+     * Positions an element at the beginning of a given axis.
+     */
+    END,
+
+    /**
+     * Stretches an element to fill the layer on a given axis.
+     */
+    STRETCH;
+  }
+
+  /**
    * Callback interface used by {@link Layout#layout(int, AnimationCallback)}
    * to provide updates on animation progress.
    */
@@ -123,7 +144,6 @@
    */
   public class Layer {
     final Element container, child;
-
     Object userObject;
 
     boolean setLeft, setRight, setTop, setBottom, setWidth, setHeight;
@@ -138,6 +158,8 @@
     double targetLeft, targetTop, targetRight, targetBottom, targetWidth,
         targetHeight;
 
+    Alignment hPos = Alignment.STRETCH, vPos = Alignment.STRETCH;
+
     Layer(Element container, Element child, Object userObject) {
       this.container = container;
       this.child = child;
@@ -187,6 +209,24 @@
     }
 
     /**
+     * Sets the child element's horizontal position within the layer.
+     * 
+     * @param position
+     */
+    public void setChildHorizontalPosition(Alignment position) {
+      this.hPos = position;
+    }
+
+    /**
+     * Sets the child element's vertical position within the layer.
+     * 
+     * @param position
+     */
+    public void setChildVerticalPosition(Alignment position) {
+      this.vPos = position;
+    }
+
+    /**
      * Sets the layer's left and right values.
      * 
      * @param left
diff --git a/user/src/com/google/gwt/layout/client/LayoutImpl.java b/user/src/com/google/gwt/layout/client/LayoutImpl.java
index 3dcfda4..2d43e2d 100644
--- a/user/src/com/google/gwt/layout/client/LayoutImpl.java
+++ b/user/src/com/google/gwt/layout/client/LayoutImpl.java
@@ -143,6 +143,35 @@
         ? (layer.width + layer.widthUnit.getType()) : "");
     style.setProperty("height", layer.setHeight
         ? (layer.height + layer.heightUnit.getType()) : "");
+
+    style = layer.child.getStyle();
+    switch (layer.hPos) {
+      case BEGIN:
+        style.clearLeft();
+        break;
+      case END:
+        style.clearLeft();
+        style.setRight(0, Unit.PX);
+        break;
+      case STRETCH:
+        style.setLeft(0, Unit.PX);
+        style.setRight(0, Unit.PX);
+        break;
+    }
+
+    switch (layer.vPos) {
+      case BEGIN:
+        style.clearTop();
+        break;
+      case END:
+        style.clearTop();
+        style.setBottom(0, Unit.PX);
+        break;
+      case STRETCH:
+        style.setTop(0, Unit.PX);
+        style.setBottom(0, Unit.PX);
+        break;
+    }
   }
 
   public void onAttach(Element parent) {
diff --git a/user/src/com/google/gwt/layout/client/LayoutImplIE6.java b/user/src/com/google/gwt/layout/client/LayoutImplIE6.java
index 4a9be19..c99b324 100644
--- a/user/src/com/google/gwt/layout/client/LayoutImplIE6.java
+++ b/user/src/com/google/gwt/layout/client/LayoutImplIE6.java
@@ -323,6 +323,11 @@
       var _rightUnit = layer.@com.google.gwt.layout.client.Layout.Layer::rightUnit;
       var _bottomUnit = layer.@com.google.gwt.layout.client.Layout.Layer::bottomUnit;
 
+      var _hPos = layer.@com.google.gwt.layout.client.Layout.Layer::hPos
+                  .@com.google.gwt.layout.client.Layout.Alignment::ordinal()();
+      var _vPos = layer.@com.google.gwt.layout.client.Layout.Layer::vPos
+                  .@com.google.gwt.layout.client.Layout.Alignment::ordinal()();
+
       // Apply the requested position & size values to the element's style.
       var style = container.style;
       style.left = _setLeft ? (_left + _leftUnit.@com.google.gwt.dom.client.Style.Unit::getType()()) : "";
@@ -366,16 +371,43 @@
         }
       }
 
-      // Resize the child to take up all of its container's width and height.
+      // Resize and position the child based on the layer's [hv]Pos.
       var child = container.firstChild;
       @com.google.gwt.layout.client.LayoutImplIE6::measureDecoration(Lcom/google/gwt/dom/client/Element;)(child);
       var childDecoWidth = child.__decoWidth;
       var childDecoHeight = child.__decoHeight;
+
       if (container.offsetWidth > childDecoWidth) {
-        child.style.width = (container.offsetWidth - childDecoWidth) + 'px';
+        switch (_hPos) {
+          case 0: // BEGIN
+            child.style.left = '0px';
+            child.style.width = '';
+            break;
+          case 1: // END
+            child.style.width = '';
+            child.style.left = (container.offsetWidth - childDecoWidth - child.offsetWidth) + 'px';
+            break;
+          case 2: // STRETCH
+            child.style.left = '0px';
+            child.style.width = (container.offsetWidth - childDecoWidth) + 'px';
+            break;
+        }
       }
       if (container.offsetHeight > childDecoHeight) {
-        child.style.height = (container.offsetHeight - childDecoHeight) + 'px';
+        switch (_vPos) {
+          case 0: // BEGIN
+            child.style.top = '0px';
+            child.style.height = '';
+            break;
+          case 1: // END
+            child.style.height = '';
+            child.style.top = (container.offsetHeight - childDecoHeight - child.offsetHeight) + 'px';
+            break;
+          case 2: // STRETCH
+            child.style.top = '0px';
+            child.style.height = (container.offsetHeight - childDecoHeight) + 'px';
+            break;
+        }
       }
     }
   }-*/;
diff --git a/user/test/com/google/gwt/layout/client/LayoutTest.java b/user/test/com/google/gwt/layout/client/LayoutTest.java
index 2a8248c..8e2d5fa 100644
--- a/user/test/com/google/gwt/layout/client/LayoutTest.java
+++ b/user/test/com/google/gwt/layout/client/LayoutTest.java
@@ -31,6 +31,7 @@
 import com.google.gwt.dom.client.Style.Position;
 import com.google.gwt.dom.client.Style.Unit;
 import com.google.gwt.junit.client.GWTTestCase;
+import com.google.gwt.layout.client.Layout.Alignment;
 import com.google.gwt.layout.client.Layout.Layer;
 import com.google.gwt.user.client.Window;
 
@@ -142,6 +143,40 @@
   }
 
   /**
+   * Tests child alignment within a layer.
+   */
+  public void testChildAlignment() {
+    child0.getStyle().setWidth(64, PX);
+    child0.getStyle().setHeight(128, PX);
+    layer0.setTopHeight(0, PX, 128, PX);
+    layer0.setLeftWidth(0, PX, 256, PX);
+
+    layer0.setChildHorizontalPosition(Alignment.STRETCH);
+    layer0.setChildVerticalPosition(Alignment.STRETCH);
+    layout.layout();
+    assertEquals(0, child0.getOffsetLeft());
+    assertEquals(0, child1.getOffsetTop());
+    assertEquals(128, child0.getOffsetWidth());
+    assertEquals(256, child1.getOffsetHeight());
+
+    layer0.setChildHorizontalPosition(Alignment.BEGIN);
+    layer0.setChildVerticalPosition(Alignment.BEGIN);
+    layout.layout();
+    assertEquals(0, child0.getOffsetLeft());
+    assertEquals(0, child1.getOffsetTop());
+    assertEquals(64, child0.getOffsetWidth());
+    assertEquals(128, child1.getOffsetHeight());
+
+    layer0.setChildHorizontalPosition(Alignment.END);
+    layer0.setChildVerticalPosition(Alignment.END);
+    layout.layout();
+    assertEquals(64, child0.getOffsetLeft());
+    assertEquals(128, child1.getOffsetTop());
+    assertEquals(64, child0.getOffsetWidth());
+    assertEquals(128, child1.getOffsetHeight());
+  }
+
+  /**
    * Test that fillParent() works properly when the outer div is a child of
    * another div, and that it correctly follows that div's size.
    */