From d813539290743935242fb001b8e3c1e64c3a5122 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Leif=20=C3=85strand?= Date: Tue, 17 Apr 2012 10:00:07 +0300 Subject: [PATCH] Explicitly reserve space for layout paddings to avoid slot growing. Without this feature, CssLayout could cause the slot to grow to over then parent's padding, which in the next layout phase would cause the CssLayout to be measured as a little bigger, causing a parent layout with undefined size to grow to make room for the bigger child, which again would make the CssLayout grow... --- .../gwt/client/ui/gridlayout/VGridLayout.java | 30 +++++++++++++++---- .../gwt/client/ui/layout/VLayoutSlot.java | 27 ++++++++++++----- .../AbstractOrderedLayoutConnector.java | 15 ++++++++-- .../VMeasuringOrderedLayout.java | 24 +++++++++++---- 4 files changed, 75 insertions(+), 21 deletions(-) diff --git a/src/com/vaadin/terminal/gwt/client/ui/gridlayout/VGridLayout.java b/src/com/vaadin/terminal/gwt/client/ui/gridlayout/VGridLayout.java index 6c5d018161..151705b1af 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/gridlayout/VGridLayout.java +++ b/src/com/vaadin/terminal/gwt/client/ui/gridlayout/VGridLayout.java @@ -193,6 +193,7 @@ public class VGridLayout extends ComplexPanel { LayoutManager layoutManager = LayoutManager.get(client); Element element = getElement(); int paddingTop = layoutManager.getPaddingTop(element); + int paddingBottom = layoutManager.getPaddingBottom(element); int y = paddingTop; for (int i = 0; i < cells.length; i++) { @@ -200,7 +201,15 @@ public class VGridLayout extends ComplexPanel { for (int j = 0; j < cells[i].length; j++) { Cell cell = cells[i][j]; if (cell != null) { - cell.layoutVertically(y); + int effectivePadding; + if (cell.rowspan + j >= cells[i].length) { + // Make room for layout padding for cells reaching the + // bottom of the layout + effectivePadding = paddingBottom; + } else { + effectivePadding = 0; + } + cell.layoutVertically(y, effectivePadding); } y += rowHeights[j] + verticalSpacing; } @@ -220,12 +229,21 @@ public class VGridLayout extends ComplexPanel { LayoutManager layoutManager = LayoutManager.get(client); Element element = getElement(); int x = layoutManager.getPaddingLeft(element); + int paddingRight = layoutManager.getPaddingRight(element); int horizontalSpacing = getHorizontalSpacing(); for (int i = 0; i < cells.length; i++) { for (int j = 0; j < cells[i].length; j++) { Cell cell = cells[i][j]; if (cell != null) { - cell.layoutHorizontally(x); + int effectivePadding; + // Make room for layout padding for cells reaching the + // right edge of the layout + if (i + cell.colspan >= cells.length) { + effectivePadding = paddingRight; + } else { + effectivePadding = 0; + } + cell.layoutHorizontally(x, effectivePadding); } } x += columnWidths[i] + horizontalSpacing; @@ -489,15 +507,15 @@ public class VGridLayout extends ComplexPanel { return height; } - public void layoutHorizontally(int x) { + public void layoutHorizontally(int x, int paddingRight) { if (slot != null) { - slot.positionHorizontally(x, getAvailableWidth()); + slot.positionHorizontally(x, getAvailableWidth(), paddingRight); } } - public void layoutVertically(int y) { + public void layoutVertically(int y, int paddingBottom) { if (slot != null) { - slot.positionVertically(y, getAvailableHeight()); + slot.positionVertically(y, getAvailableHeight(), paddingBottom); } } diff --git a/src/com/vaadin/terminal/gwt/client/ui/layout/VLayoutSlot.java b/src/com/vaadin/terminal/gwt/client/ui/layout/VLayoutSlot.java index c02061a2fe..1ef63bcc88 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/layout/VLayoutSlot.java +++ b/src/com/vaadin/terminal/gwt/client/ui/layout/VLayoutSlot.java @@ -60,7 +60,7 @@ public abstract class VLayoutSlot { } public void positionHorizontally(double currentLocation, - double allocatedSpace) { + double allocatedSpace, double paddingRight) { Style style = wrapper.getStyle(); double availableWidth = allocatedSpace; @@ -73,21 +73,25 @@ public abstract class VLayoutSlot { boolean captionAboveCompnent; if (caption == null) { captionAboveCompnent = false; - style.clearPaddingRight(); } else { captionAboveCompnent = !caption.shouldBePlacedAfterComponent(); if (!captionAboveCompnent) { - style.setPaddingRight(captionWidth, Unit.PX); + paddingRight += captionWidth; availableWidth -= captionWidth; captionStyle.clearLeft(); captionStyle.setRight(0, Unit.PX); } else { - style.clearPaddingRight(); captionStyle.setLeft(0, Unit.PX); captionStyle.clearRight(); } } + if (paddingRight > 0) { + style.setPaddingRight(paddingRight, Unit.PX); + } else { + style.clearPaddingRight(); + } + if (isRelativeWidth()) { style.setPropertyPx("width", (int) availableWidth); } else { @@ -137,7 +141,8 @@ public abstract class VLayoutSlot { return Double.parseDouble(size.replaceAll("%", "")); } - public void positionVertically(double currentLocation, double allocatedSpace) { + public void positionVertically(double currentLocation, + double allocatedSpace, double paddingBottom) { Style style = wrapper.getStyle(); double contentHeight = allocatedSpace; @@ -156,6 +161,12 @@ public abstract class VLayoutSlot { style.setPaddingTop(captionHeight, Unit.PX); } + if (paddingBottom > 0) { + style.setPaddingBottom(paddingBottom, Unit.PX); + } else { + style.clearPaddingBottom(); + } + if (isRelativeHeight()) { style.setHeight(contentHeight, Unit.PX); } else { @@ -198,11 +209,11 @@ public abstract class VLayoutSlot { } public void positionInDirection(double currentLocation, - double allocatedSpace, boolean isVertical) { + double allocatedSpace, double endingPadding, boolean isVertical) { if (isVertical) { - positionVertically(currentLocation, allocatedSpace); + positionVertically(currentLocation, allocatedSpace, endingPadding); } else { - positionHorizontally(currentLocation, allocatedSpace); + positionHorizontally(currentLocation, allocatedSpace, endingPadding); } } diff --git a/src/com/vaadin/terminal/gwt/client/ui/orderedlayout/AbstractOrderedLayoutConnector.java b/src/com/vaadin/terminal/gwt/client/ui/orderedlayout/AbstractOrderedLayoutConnector.java index 47c16e7c40..d36046d6cb 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/orderedlayout/AbstractOrderedLayoutConnector.java +++ b/src/com/vaadin/terminal/gwt/client/ui/orderedlayout/AbstractOrderedLayoutConnector.java @@ -178,6 +178,7 @@ public abstract class AbstractOrderedLayoutConnector extends boolean isUndefined = isUndefinedInDirection(isVertical); int startPadding = getStartPadding(isVertical); + int endPadding = getEndPadding(isVertical); int spacingSize = getSpacingInDirection(isVertical); int allocatedSize; @@ -188,7 +189,7 @@ public abstract class AbstractOrderedLayoutConnector extends } allocatedSize = layout.layoutPrimaryDirection(spacingSize, - allocatedSize, startPadding); + allocatedSize, startPadding, endPadding); Style ownStyle = getWidget().getElement().getStyle(); if (isUndefined) { @@ -225,6 +226,7 @@ public abstract class AbstractOrderedLayoutConnector extends boolean isUndefined = isUndefinedInDirection(!isVertical); int startPadding = getStartPadding(!isVertical); + int endPadding = getEndPadding(!isVertical); int allocatedSize; if (isUndefined) { @@ -234,7 +236,7 @@ public abstract class AbstractOrderedLayoutConnector extends } allocatedSize = layout.layoutSecondaryDirection(allocatedSize, - startPadding); + startPadding, endPadding); Style ownStyle = getWidget().getElement().getStyle(); @@ -266,6 +268,15 @@ public abstract class AbstractOrderedLayoutConnector extends } } + private int getEndPadding(boolean isVertical) { + if (isVertical) { + return getLayoutManager() + .getPaddingBottom(getWidget().getElement()); + } else { + return getLayoutManager().getPaddingRight(getWidget().getElement()); + } + } + public void layoutHorizontally() { if (getWidget().isVertical) { layoutSecondaryDirection(); diff --git a/src/com/vaadin/terminal/gwt/client/ui/orderedlayout/VMeasuringOrderedLayout.java b/src/com/vaadin/terminal/gwt/client/ui/orderedlayout/VMeasuringOrderedLayout.java index 03cf1a5dfb..41c48883ec 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/orderedlayout/VMeasuringOrderedLayout.java +++ b/src/com/vaadin/terminal/gwt/client/ui/orderedlayout/VMeasuringOrderedLayout.java @@ -14,6 +14,7 @@ import com.google.gwt.dom.client.Style.Position; import com.google.gwt.user.client.Element; import com.google.gwt.user.client.ui.ComplexPanel; import com.google.gwt.user.client.ui.Widget; +import com.google.gwt.user.client.ui.WidgetCollection; import com.vaadin.terminal.gwt.client.VCaption; import com.vaadin.terminal.gwt.client.ui.VMarginInfo; import com.vaadin.terminal.gwt.client.ui.layout.VLayoutSlot; @@ -116,7 +117,7 @@ public class VMeasuringOrderedLayout extends ComplexPanel { } public int layoutPrimaryDirection(int spacingSize, int allocatedSize, - int startPadding) { + int startPadding, int endPadding) { int actuallyAllocated = 0; double totalExpand = 0; @@ -146,7 +147,9 @@ public class VMeasuringOrderedLayout extends ComplexPanel { double currentLocation = startPadding; - for (Widget child : this) { + WidgetCollection children = getChildren(); + for (int i = 0; i < children.size(); i++) { + Widget child = children.get(i); if (child instanceof VCaption) { continue; } @@ -187,7 +190,16 @@ public class VMeasuringOrderedLayout extends ComplexPanel { */ double roundedSpace = Math.round(endLocation) - roundedLocation; - slot.positionInDirection(roundedLocation, roundedSpace, isVertical); + // Reserve room for the padding if we're at the end + double slotEndPadding; + if (i == children.size() - 1) { + slotEndPadding = endPadding; + } else { + slotEndPadding = 0; + } + + slot.positionInDirection(roundedLocation, roundedSpace, + slotEndPadding, isVertical); currentLocation = endLocation + spacingSize; } @@ -195,7 +207,8 @@ public class VMeasuringOrderedLayout extends ComplexPanel { return allocatedSize; } - public int layoutSecondaryDirection(int allocatedSize, int startPadding) { + public int layoutSecondaryDirection(int allocatedSize, int startPadding, + int endPadding) { int maxSize = 0; for (Widget child : this) { if (child instanceof VCaption) { @@ -219,7 +232,8 @@ public class VMeasuringOrderedLayout extends ComplexPanel { } VLayoutSlot slot = getSlotForChild(child); - slot.positionInDirection(startPadding, allocatedSize, !isVertical); + slot.positionInDirection(startPadding, allocatedSize, endPadding, + !isVertical); } return allocatedSize; -- 2.39.5