summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLeif Åstrand <leif@vaadin.com>2013-01-03 11:13:17 +0200
committerLeif Åstrand <leif@vaadin.com>2013-01-03 11:17:54 +0200
commit40d9b11ed9542db451358a8ba0591282971d17b3 (patch)
tree17627acad4045bd623dfbe9c094c513e9cbe24c4
parentbe39a69211330310848778af9096c50dd53b93ad (diff)
downloadvaadin-framework-40d9b11ed9542db451358a8ba0591282971d17b3.tar.gz
vaadin-framework-40d9b11ed9542db451358a8ba0591282971d17b3.zip
Update AbstractOrderedLayout calculation logic
* Always use expansion logic if the layout's size is fixed * Ensure e.g. expansion changes happen even if no hierarchy or measurement changes (#10161) * Separate the calculation of expand ratios from the adjustment for the sizes of children without expansion * Ensure there are element resize listeners for all elements that should be measured (#10488) * Postpone calculations if there are elements that have not yet been measured * Use measurements for fixing the height under more circumstances * Only update based on hierarchy & state if something might have changed Change-Id: I8542afbcb7e93d44bd0dff751a56ed10033937fc
-rw-r--r--client/src/com/vaadin/client/ui/orderedlayout/AbstractOrderedLayoutConnector.java313
-rw-r--r--client/src/com/vaadin/client/ui/orderedlayout/Slot.java10
-rw-r--r--client/src/com/vaadin/client/ui/orderedlayout/VAbstractOrderedLayout.java115
-rw-r--r--uitest/src/com/vaadin/tests/components/orderedlayout/OrderedLayoutCases.java12
4 files changed, 233 insertions, 217 deletions
diff --git a/client/src/com/vaadin/client/ui/orderedlayout/AbstractOrderedLayoutConnector.java b/client/src/com/vaadin/client/ui/orderedlayout/AbstractOrderedLayoutConnector.java
index e062d37dd6..ce16b67d8b 100644
--- a/client/src/com/vaadin/client/ui/orderedlayout/AbstractOrderedLayoutConnector.java
+++ b/client/src/com/vaadin/client/ui/orderedlayout/AbstractOrderedLayoutConnector.java
@@ -15,14 +15,15 @@
*/
package com.vaadin.client.ui.orderedlayout;
-import java.util.HashMap;
-import java.util.HashSet;
import java.util.List;
import com.google.gwt.dom.client.Style.Unit;
import com.google.gwt.user.client.Element;
+import com.vaadin.client.ApplicationConnection;
import com.vaadin.client.ComponentConnector;
import com.vaadin.client.ConnectorHierarchyChangeEvent;
+import com.vaadin.client.LayoutManager;
+import com.vaadin.client.ServerConnector;
import com.vaadin.client.Util;
import com.vaadin.client.communication.StateChangeEvent;
import com.vaadin.client.communication.StateChangeEvent.StateChangeHandler;
@@ -62,35 +63,28 @@ public abstract class AbstractOrderedLayoutConnector extends
@Override
protected LayoutClickRpc getLayoutClickRPC() {
return getRpcProxy(AbstractOrderedLayoutServerRpc.class);
- };
+ }
};
private StateChangeHandler childStateChangeHandler = new StateChangeHandler() {
@Override
public void onStateChanged(StateChangeEvent stateChangeEvent) {
-
- ComponentConnector child = (ComponentConnector) stateChangeEvent
- .getConnector();
-
- // We need to update the slot size if the component size is changed
- // to relative
- Slot slot = getWidget().getSlot(child.getWidget());
- slot.setRelativeWidth(child.isRelativeWidth());
- slot.setRelativeHeight(child.isRelativeHeight());
-
- // Update slot style names
- List<String> childStyles = child.getState().styles;
- if (childStyles == null) {
- getWidget().setSlotStyleNames(child.getWidget(),
- (String[]) null);
- } else {
- getWidget().setSlotStyleNames(child.getWidget(),
- childStyles.toArray(new String[childStyles.size()]));
+ // Child state has changed, update stuff it hasn't already been done
+ updateInternalState();
+
+ /*
+ * Some changes must always be done after each child's own state
+ * change handler has been run because it might have changed some
+ * styles that are overridden here.
+ */
+ ServerConnector child = stateChangeEvent.getConnector();
+ if (child instanceof ComponentConnector) {
+ ComponentConnector component = (ComponentConnector) child;
+ Slot slot = getWidget().getSlot(component.getWidget());
+
+ slot.setRelativeWidth(component.isRelativeWidth());
+ slot.setRelativeHeight(component.isRelativeHeight());
}
-
- updateSlotListeners(child);
-
- updateLayoutHeight();
}
};
@@ -123,7 +117,6 @@ public abstract class AbstractOrderedLayoutConnector extends
if (slot != null) {
slot.setCaptionResizeListener(null);
}
- childCaptionElementHeight.remove(widgetElement);
return;
}
@@ -138,14 +131,10 @@ public abstract class AbstractOrderedLayoutConnector extends
getWidget().updateCaptionOffset(captionElement);
}
- int h = getLayoutManager().getOuterHeight(captionElement)
- - getLayoutManager().getMarginHeight(captionElement);
- childCaptionElementHeight.put(widgetElement, h);
-
updateLayoutHeight();
if (needsExpand()) {
- getWidget().updateExpand();
+ getWidget().updateExpandCompensation();
}
}
};
@@ -155,7 +144,7 @@ public abstract class AbstractOrderedLayoutConnector extends
public void onElementResize(ElementResizeEvent e) {
updateLayoutHeight();
if (needsExpand()) {
- getWidget().updateExpand();
+ getWidget().updateExpandCompensation();
}
}
};
@@ -164,7 +153,7 @@ public abstract class AbstractOrderedLayoutConnector extends
@Override
public void onElementResize(ElementResizeEvent e) {
if (needsExpand()) {
- getWidget().updateExpand();
+ getWidget().updateExpandCompensation();
}
}
};
@@ -201,42 +190,44 @@ public abstract class AbstractOrderedLayoutConnector extends
}
/**
- * For bookkeeping. Used to determine if extra calculations are needed for
- * horizontal layout.
- */
- private HashSet<ComponentConnector> hasVerticalAlignment = new HashSet<ComponentConnector>();
-
- /**
- * For bookkeeping. Used to determine if extra calculations are needed for
- * horizontal layout.
- */
- private HashSet<ComponentConnector> hasRelativeHeight = new HashSet<ComponentConnector>();
-
- /**
- * For bookkeeping. Used to determine if extra calculations are needed for
- * horizontal layout.
+ * Keep track of whether any child has relative height. Used to determine
+ * whether measurements are needed to make relative child heights work
+ * together with undefined container height.
*/
- private HashSet<ComponentConnector> hasExpandRatio = new HashSet<ComponentConnector>();
+ private boolean hasChildrenWithRelativeHeight = false;
/**
- * For bookkeeping. Used in extra calculations for horizontal layout.
+ * Keeps track of whether slots should be expanded based on available space.
*/
- private HashSet<Element> needsMeasure = new HashSet<Element>();
+ private boolean needsExpand = false;
/**
- * For bookkeeping. Used in extra calculations for horizontal layout.
+ * The id of the previous response for which state changes have been
+ * processed. If this is the same as the
+ * {@link ApplicationConnection#getLastResponseId()}, it means that we can
+ * skip some quite expensive calculations because we know that the state
+ * hasn't changed since the last time the values were calculated.
*/
- private HashMap<Element, Integer> childCaptionElementHeight = new HashMap<Element, Integer>();
+ private int processedResponseId = -1;
/*
* (non-Javadoc)
*
- * @see
- * com.vaadin.client.HasComponentsConnector#updateCaption(com.vaadin
+ * @see com.vaadin.client.HasComponentsConnector#updateCaption(com.vaadin
* .client.ComponentConnector)
*/
@Override
- public void updateCaption(ComponentConnector child) {
+ public void updateCaption(ComponentConnector connector) {
+ /*
+ * Don't directly update captions here to avoid calling e.g.
+ * updateLayoutHeight() before everything is initialized.
+ * updateInternalState() will ensure all captions are updated when
+ * appropriate.
+ */
+ updateInternalState();
+ }
+
+ private void updateCaptionInternal(ComponentConnector child) {
Slot slot = getWidget().getSlot(child.getWidget());
String caption = child.getState().caption;
@@ -274,15 +265,8 @@ public abstract class AbstractOrderedLayoutConnector extends
&& (pos == CaptionPosition.LEFT || pos == CaptionPosition.RIGHT)) {
getWidget().updateCaptionOffset(slot.getCaptionElement());
}
- } else {
- childCaptionElementHeight.remove(child.getWidget().getElement());
}
- updateLayoutHeight();
-
- if (needsExpand()) {
- getWidget().updateExpand();
- }
}
/*
@@ -312,12 +296,6 @@ public abstract class AbstractOrderedLayoutConnector extends
for (ComponentConnector child : previousChildren) {
if (child.getParent() != this) {
Slot slot = layout.getSlot(child.getWidget());
- hasVerticalAlignment.remove(child);
- hasRelativeHeight.remove(child);
- hasExpandRatio.remove(child);
- needsMeasure.remove(child.getWidget().getElement());
- childCaptionElementHeight
- .remove(child.getWidget().getElement());
slot.setWidgetResizeListener(null);
if (slot.hasCaption()) {
slot.setCaptionResizeListener(null);
@@ -330,13 +308,7 @@ public abstract class AbstractOrderedLayoutConnector extends
}
}
- // If some component is added/removed, we need to recalculate the expand
- if (needsExpand()) {
- getWidget().updateExpand();
- } else {
- getWidget().clearExpand();
- }
-
+ updateInternalState();
}
/*
@@ -354,51 +326,91 @@ public abstract class AbstractOrderedLayoutConnector extends
getWidget().setMargin(new MarginInfo(getState().marginsBitmask));
getWidget().setSpacing(getState().spacing);
- hasExpandRatio.clear();
- hasVerticalAlignment.clear();
- hasRelativeHeight.clear();
- needsMeasure.clear();
+ updateInternalState();
+ }
- boolean equalExpandRatio = getWidget().vertical ? !isUndefinedHeight()
+ /**
+ * Updates DOM properties and listeners based on the current state of this
+ * layout and its children.
+ */
+ private void updateInternalState() {
+ // Avoid updating again for the same data
+ int lastResponseId = getConnection().getLastResponseId();
+ if (processedResponseId == lastResponseId) {
+ return;
+ }
+ // Remember that everything is updated for this response
+ processedResponseId = lastResponseId;
+
+ hasChildrenWithRelativeHeight = false;
+
+ needsExpand = getWidget().vertical ? !isUndefinedHeight()
: !isUndefinedWidth();
- for (ComponentConnector child : getChildComponents()) {
- double expandRatio = getState().childData.get(child).expandRatio;
- if (expandRatio > 0) {
- equalExpandRatio = false;
- break;
+
+ boolean onlyZeroExpands = true;
+ if (needsExpand) {
+ for (ComponentConnector child : getChildComponents()) {
+ double expandRatio = getState().childData.get(child).expandRatio;
+ if (expandRatio != 0) {
+ onlyZeroExpands = false;
+ break;
+ }
}
}
+ // First update bookkeeping for all children
for (ComponentConnector child : getChildComponents()) {
+ if (child.delegateCaptionHandling()) {
+ updateCaptionInternal(child);
+ }
+
Slot slot = getWidget().getSlot(child.getWidget());
+ // Update slot style names
+ List<String> childStyles = child.getState().styles;
+ if (childStyles == null) {
+ getWidget().setSlotStyleNames(child.getWidget(),
+ (String[]) null);
+ } else {
+ getWidget().setSlotStyleNames(child.getWidget(),
+ childStyles.toArray(new String[childStyles.size()]));
+ }
+
AlignmentInfo alignment = new AlignmentInfo(
getState().childData.get(child).alignmentBitmask);
slot.setAlignment(alignment);
- double expandRatio = getState().childData.get(child).expandRatio;
+ double expandRatio = onlyZeroExpands ? 1 : getState().childData
+ .get(child).expandRatio;
- if (equalExpandRatio) {
- expandRatio = 1;
- } else if (expandRatio == 0) {
- expandRatio = -1;
- }
slot.setExpandRatio(expandRatio);
- // Bookkeeping to identify special cases that need extra
- // calculations
- if (alignment.isVerticalCenter() || alignment.isBottom()) {
- hasVerticalAlignment.add(child);
+ if (child.isRelativeHeight()) {
+ hasChildrenWithRelativeHeight = true;
}
+ }
- if (expandRatio > 0) {
- hasExpandRatio.add(child);
- }
+ if (needsFixedHeight()) {
+ // Add resize listener to ensure the widget itself is measured
+ getLayoutManager().addElementResizeListener(
+ getWidget().getElement(), childComponentResizeListener);
+ } else {
+ getLayoutManager().removeElementResizeListener(
+ getWidget().getElement(), childComponentResizeListener);
}
+ // Then update listeners based on bookkeeping
updateAllSlotListeners();
+ // Update the layout at this point to ensure it's OK even if we get no
+ // element resize events
updateLayoutHeight();
+ if (needsExpand()) {
+ getWidget().updateExpandedSizes();
+ getWidget().updateExpandCompensation();
+ } else {
+ getWidget().clearExpand();
+ }
}
/**
@@ -406,29 +418,19 @@ public abstract class AbstractOrderedLayoutConnector extends
*/
private boolean needsFixedHeight() {
boolean isVertical = getWidget().vertical;
- boolean hasChildrenWithVerticalAlignmentCenterOrBottom = !hasVerticalAlignment
- .isEmpty();
- boolean allChildrenHasVerticalAlignmentCenterOrBottom = hasVerticalAlignment
- .size() == getChildren().size();
- boolean hasChildrenWithRelativeHeight = !hasRelativeHeight.isEmpty();
if (isVertical) {
+ // Doesn't need height fix for vertical layouts
return false;
}
else if (!isUndefinedHeight()) {
+ // Fix not needed unless the height is undefined
return false;
}
else if (!hasChildrenWithRelativeHeight) {
- return false;
- }
-
- else if (!hasChildrenWithVerticalAlignmentCenterOrBottom) {
- return false;
- }
-
- else if (allChildrenHasVerticalAlignmentCenterOrBottom) {
+ // Already works if there are no relative heights
return false;
}
@@ -439,9 +441,7 @@ public abstract class AbstractOrderedLayoutConnector extends
* Does the layout need to expand?
*/
private boolean needsExpand() {
- boolean canApplyExpand = (getWidget().vertical && !isUndefinedHeight())
- || (!getWidget().vertical && !isUndefinedWidth());
- return hasExpandRatio.size() > 0 && canApplyExpand;
+ return needsExpand;
}
/**
@@ -477,27 +477,24 @@ public abstract class AbstractOrderedLayoutConnector extends
}
} else if ((child.isRelativeHeight() || child.isRelativeWidth())
&& slot.hasCaption()) {
- // If the slot has caption, we need to listen for it's size changes
- // in order to update the padding/margin offset for relative sized
- // components
+ /*
+ * If the slot has caption, we need to listen for its size changes
+ * in order to update the padding/margin offset for relative sized
+ * components.
+ *
+ * TODO might only be needed if the caption is in the same direction
+ * as the relative size?
+ */
slot.setCaptionResizeListener(slotCaptionResizeListener);
}
if (needsExpand()) {
+ // TODO widget resize only be needed for children without expand?
slot.setWidgetResizeListener(childComponentResizeListener);
if (slot.hasSpacing()) {
slot.setSpacingResizeListener(spacingResizeListener);
}
}
-
- if (child.isRelativeHeight()) {
- hasRelativeHeight.add(child);
- needsMeasure.remove(child.getWidget().getElement());
- } else {
- hasRelativeHeight.remove(child);
- needsMeasure.add(child.getWidget().getElement());
- }
-
}
/**
@@ -506,7 +503,11 @@ public abstract class AbstractOrderedLayoutConnector extends
private void updateLayoutHeight() {
if (needsFixedHeight()) {
int h = getMaxHeight();
- assert (h >= 0);
+ if (h < 0) {
+ // Postpone change if there are elements that have not yet been
+ // measured
+ return;
+ }
h += getLayoutManager().getBorderHeight(getWidget().getElement())
+ getLayoutManager().getPaddingHeight(
getWidget().getElement());
@@ -522,37 +523,49 @@ public abstract class AbstractOrderedLayoutConnector extends
int highestNonRelative = -1;
int highestRelative = -1;
+ LayoutManager layoutManager = getLayoutManager();
+
for (ComponentConnector child : getChildComponents()) {
- // TODO would be more efficient to measure the slot element if both
- // caption and child widget elements need to be measured. Keeping
- // track of what to measure is the most difficult part of this
- // layout.
- Element el = child.getWidget().getElement();
- CaptionPosition pos = getWidget().getCaptionPositionFromElement(
- (Element) el.getParentElement().cast());
- int h = getLayoutManager().getOuterHeight(el);
+ Slot slot = getWidget().getSlot(child.getWidget());
+ Element captionElement = slot.getCaptionElement();
+ CaptionPosition pos = slot.getCaptionPosition();
+
+ Element childElement = child.getWidget().getElement();
+ int h = layoutManager.getOuterHeight(childElement);
if (h == -1) {
- // Height has not yet been measured so using a more
- // conventional method instead.
- h = Util.getRequiredHeight(el);
+ // Height has not yet been measured -> postpone actions that
+ // depend on the max height
+ return -1;
}
- if (needsMeasure.contains(el)) {
- String sHeight = el.getStyle().getHeight();
- // Only add the caption size to the height of the slot if
- // coption position is top or bottom
- if (childCaptionElementHeight.containsKey(el)
- && (sHeight == null || !sHeight.endsWith("%"))
- && (pos == CaptionPosition.TOP || pos == CaptionPosition.BOTTOM)) {
- h += childCaptionElementHeight.get(el);
+
+ boolean hasRelativeHeight = slot.hasRelativeHeight();
+
+ boolean includeCaptionHeight = captionElement != null
+ && (pos == CaptionPosition.TOP || pos == CaptionPosition.BOTTOM);
+ if (!hasRelativeHeight && !includeCaptionHeight
+ && captionElement != null) {
+ String sHeight = childElement.getStyle().getHeight();
+ includeCaptionHeight = (sHeight == null || !sHeight
+ .endsWith("%"));
+ }
+
+ if (includeCaptionHeight) {
+ int captionHeight = layoutManager
+ .getOuterHeight(captionElement)
+ - getLayoutManager().getMarginHeight(captionElement);
+ if (captionHeight == -1) {
+ // Height has not yet been measured -> postpone actions that
+ // depend on the max height
+ return -1;
}
+ h += captionHeight;
+ }
+
+ if (!hasRelativeHeight) {
if (h > highestNonRelative) {
highestNonRelative = h;
}
} else {
- if (childCaptionElementHeight.containsKey(el)
- && (pos == CaptionPosition.TOP || pos == CaptionPosition.BOTTOM)) {
- h += childCaptionElementHeight.get(el);
- }
if (h > highestRelative) {
highestRelative = h;
}
diff --git a/client/src/com/vaadin/client/ui/orderedlayout/Slot.java b/client/src/com/vaadin/client/ui/orderedlayout/Slot.java
index 094a7f1f0a..fc1c10de68 100644
--- a/client/src/com/vaadin/client/ui/orderedlayout/Slot.java
+++ b/client/src/com/vaadin/client/ui/orderedlayout/Slot.java
@@ -276,7 +276,11 @@ public final class Slot extends SimplePanel {
}
/**
- * Set how the slot should be expanded relative to the other slots
+ * Set how the slot should be expanded relative to the other slots. 0 means
+ * that the slot should not participate in the division of space based on
+ * the expand ratios but instead be allocated space based on its natural
+ * size. Other values causes the slot to get a share of the otherwise
+ * unallocated space in proportion to the slot's expand ratio value.
*
* @param expandRatio
* The ratio of the space the slot should occupy
@@ -290,7 +294,9 @@ public final class Slot extends SimplePanel {
* Get the expand ratio for the slot. The expand ratio describes how the
* slot should be resized compared to other slots in the layout
*
- * @return
+ * @return the expand ratio of the slot
+ *
+ * @see #setExpandRatio(double)
*/
public double getExpandRatio() {
return expandRatio;
diff --git a/client/src/com/vaadin/client/ui/orderedlayout/VAbstractOrderedLayout.java b/client/src/com/vaadin/client/ui/orderedlayout/VAbstractOrderedLayout.java
index 00b7092d81..0199e95c58 100644
--- a/client/src/com/vaadin/client/ui/orderedlayout/VAbstractOrderedLayout.java
+++ b/client/src/com/vaadin/client/ui/orderedlayout/VAbstractOrderedLayout.java
@@ -26,10 +26,10 @@ import com.google.gwt.regexp.shared.RegExp;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.ui.FlowPanel;
+import com.google.gwt.user.client.ui.RequiresResize;
import com.google.gwt.user.client.ui.Widget;
import com.vaadin.client.LayoutManager;
import com.vaadin.client.Util;
-import com.vaadin.shared.ui.AlignmentInfo;
import com.vaadin.shared.ui.MarginInfo;
/**
@@ -50,6 +50,12 @@ public class VAbstractOrderedLayout extends FlowPanel {
private LayoutManager layoutManager;
+ /**
+ * Keep track of the last allocated expand size to help detecting when it
+ * changes.
+ */
+ private int lastExpandSize = -1;
+
public VAbstractOrderedLayout(boolean vertical) {
this.vertical = vertical;
}
@@ -332,12 +338,25 @@ public class VAbstractOrderedLayout extends FlowPanel {
}
/**
- * Triggers a recalculation of the expand width and heights
+ * Assigns relative sizes to the children that should expand based on their
+ * expand ratios.
*/
- private void recalculateExpands() {
+ public void updateExpandedSizes() {
+ // Ensure the expand wrapper is in place
+ if (expandWrapper == null) {
+ expandWrapper = DOM.createDiv();
+ expandWrapper.setClassName("v-expand");
+ while (getElement().getChildCount() > 0) {
+ Node el = getElement().getChild(0);
+ expandWrapper.appendChild(el);
+ }
+ getElement().appendChild(expandWrapper);
+ }
+
+ // Sum up expand ratios to get the denominator
double total = 0;
for (Slot slot : widgetToSlot.values()) {
- if (slot.getExpandRatio() > -1) {
+ if (slot.getExpandRatio() != 0) {
total += slot.getExpandRatio();
} else {
if (vertical) {
@@ -346,9 +365,13 @@ public class VAbstractOrderedLayout extends FlowPanel {
slot.getElement().getStyle().clearWidth();
}
}
+ slot.getElement().getStyle().clearMarginLeft();
+ slot.getElement().getStyle().clearMarginTop();
}
+
+ // Give each child its own share
for (Slot slot : widgetToSlot.values()) {
- if (slot.getExpandRatio() > -1) {
+ if (slot.getExpandRatio() != 0) {
if (vertical) {
slot.setHeight((100 * (slot.getExpandRatio() / total))
+ "%");
@@ -372,7 +395,8 @@ public class VAbstractOrderedLayout extends FlowPanel {
*/
public void clearExpand() {
if (expandWrapper != null) {
- for (; expandWrapper.getChildCount() > 0;) {
+ lastExpandSize = -1;
+ while (expandWrapper.getChildCount() > 0) {
Element el = expandWrapper.getChild(0).cast();
getElement().appendChild(el);
if (vertical) {
@@ -389,39 +413,23 @@ public class VAbstractOrderedLayout extends FlowPanel {
}
/**
- * Adds elements used to expand a slot
+ * Updates the expand compensation based on the measured sizes of children
+ * without expand.
*/
- public void updateExpand() {
+ public void updateExpandCompensation() {
boolean isExpanding = false;
for (Widget slot : getChildren()) {
- if (((Slot) slot).getExpandRatio() > -1) {
+ if (((Slot) slot).getExpandRatio() != 0) {
isExpanding = true;
- } else {
- if (vertical) {
- slot.getElement().getStyle().clearHeight();
- } else {
- slot.getElement().getStyle().clearWidth();
- }
+ break;
}
- slot.getElement().getStyle().clearMarginLeft();
- slot.getElement().getStyle().clearMarginTop();
}
if (isExpanding) {
- if (expandWrapper == null) {
- expandWrapper = DOM.createDiv();
- expandWrapper.setClassName("v-expand");
- for (; getElement().getChildCount() > 0;) {
- Node el = getElement().getChild(0);
- expandWrapper.appendChild(el);
- }
- getElement().appendChild(expandWrapper);
- }
-
int totalSize = 0;
for (Widget w : getChildren()) {
Slot slot = (Slot) w;
- if (slot.getExpandRatio() == -1) {
+ if (slot.getExpandRatio() == 0) {
if (layoutManager != null) {
// TODO check caption position
@@ -483,44 +491,21 @@ public class VAbstractOrderedLayout extends FlowPanel {
.setMarginLeft(-totalSize, Unit.PX);
}
- recalculateExpands();
- }
- }
-
- /**
- * Perform a recalculation of the layout height
- */
- public void recalculateLayoutHeight() {
- // Only needed if a horizontal layout is undefined high, and contains
- // relative height children or vertical alignments
- if (vertical || definedHeight) {
- return;
- }
-
- boolean hasRelativeHeightChildren = false;
- boolean hasVAlign = false;
-
- for (Widget slot : getChildren()) {
- Widget widget = ((Slot) slot).getWidget();
- String h = widget.getElement().getStyle().getHeight();
- if (h != null && h.indexOf("%") > -1) {
- hasRelativeHeightChildren = true;
- }
- AlignmentInfo a = ((Slot) slot).getAlignment();
- if (a != null && (a.isVerticalCenter() || a.isBottom())) {
- hasVAlign = true;
- }
- }
-
- if (hasRelativeHeightChildren || hasVAlign) {
- int newHeight;
- if (layoutManager != null) {
- newHeight = layoutManager.getOuterHeight(getElement())
- - layoutManager.getMarginHeight(getElement());
- } else {
- newHeight = getElement().getOffsetHeight();
+ // Measure expanded children again if their size might have changed
+ if (totalSize != lastExpandSize) {
+ lastExpandSize = totalSize;
+ for (Widget w : getChildren()) {
+ Slot slot = (Slot) w;
+ if (slot.getExpandRatio() != 0) {
+ if (layoutManager != null) {
+ layoutManager.setNeedsMeasure(Util
+ .findConnectorFor(slot.getWidget()));
+ } else if (slot.getWidget() instanceof RequiresResize) {
+ ((RequiresResize) slot.getWidget()).onResize();
+ }
+ }
+ }
}
- getElement().getStyle().setHeight(newHeight, Unit.PX);
}
}
diff --git a/uitest/src/com/vaadin/tests/components/orderedlayout/OrderedLayoutCases.java b/uitest/src/com/vaadin/tests/components/orderedlayout/OrderedLayoutCases.java
index da6946f432..fe1dfe3e6d 100644
--- a/uitest/src/com/vaadin/tests/components/orderedlayout/OrderedLayoutCases.java
+++ b/uitest/src/com/vaadin/tests/components/orderedlayout/OrderedLayoutCases.java
@@ -321,6 +321,18 @@ public class OrderedLayoutCases extends AbstractTestUI {
setChildState(0, 2, 1);
// Height: 100% to middle child
setChildState(1, 1, 4);
+ }
+ }));
+
+ caseBar.addComponent(new Button("Undefined + alignments",
+ new ClickListener() {
+ @Override
+ public void buttonClick(ClickEvent event) {
+ resetState();
+ // Height: 350px to left child
+ setChildState(0, 1, 2);
+ // Short caption to left child
+ setChildState(0, 2, 1);
// Alignment: bottom left to right child
setChildState(2, 4, 7);
}