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 <!DOCTYPE> + * 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 <!DOCTYPE> + * 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 <!DOCTYPE> * 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 -~----------~----~----~----~------~----~------~--~---
