diff options
author | Artur Signell <artur@vaadin.com> | 2015-06-07 23:06:45 +0300 |
---|---|---|
committer | Vaadin Code Review <review@vaadin.com> | 2015-06-12 11:51:16 +0000 |
commit | 914eafd5fe7d43290abe0b6b07678df0a8f45ee0 (patch) | |
tree | d392d772393791ee6301c6b3e4023c6868b35ef9 | |
parent | 7f39ad337ec489d58cee6cb99d32f4364a93b1eb (diff) | |
download | vaadin-framework-914eafd5fe7d43290abe0b6b07678df0a8f45ee0.tar.gz vaadin-framework-914eafd5fe7d43290abe0b6b07678df0a8f45ee0.zip |
Ensure GridLayout rounds available space down instead of up (#15451)
Store measured widths and heights as doubles to be able to round later
Change-Id: Id0e91702dd62ba362f53317e8520f85b46f19769
8 files changed, 388 insertions, 49 deletions
diff --git a/client/src/com/vaadin/client/LayoutManager.java b/client/src/com/vaadin/client/LayoutManager.java index 3f189bcea8..102e618f5e 100644 --- a/client/src/com/vaadin/client/LayoutManager.java +++ b/client/src/com/vaadin/client/LayoutManager.java @@ -946,7 +946,7 @@ public class LayoutManager { * given element, provided that it has been measured. These elements are * guaranteed to be measured: * <ul> - * <li>ManagedLayotus and their child Connectors + * <li>ManagedLayouts and their child Connectors * <li>Elements for which there is at least one ElementResizeListener * <li>Elements for which at least one ManagedLayout has registered a * dependency @@ -954,6 +954,9 @@ public class LayoutManager { * * -1 is returned if the element has not been measured. If 0 is returned, it * might indicate that the element is not attached to the DOM. + * <p> + * The value returned by this method is always rounded up. To get the exact + * outer width, use {@link #getOuterHeightDouble(Element)} * * @param element * the element to get the measured size for @@ -962,6 +965,31 @@ public class LayoutManager { */ public final int getOuterHeight(Element element) { assert needsMeasure(element) : "Getting measurement for element that is not measured"; + return (int) Math.ceil(getMeasuredSize(element, nullSize) + .getOuterHeight()); + } + + /** + * Gets the outer height (including margins, paddings and borders) of the + * given element, provided that it has been measured. These elements are + * guaranteed to be measured: + * <ul> + * <li>ManagedLayouts and their child Connectors + * <li>Elements for which there is at least one ElementResizeListener + * <li>Elements for which at least one ManagedLayout has registered a + * dependency + * </ul> + * + * -1 is returned if the element has not been measured. If 0 is returned, it + * might indicate that the element is not attached to the DOM. + * + * @param element + * the element to get the measured size for + * @return the measured outer height (including margins, paddings and + * borders) of the element in pixels. + */ + public final double getOuterHeightDouble(Element element) { + assert needsMeasure(element) : "Getting measurement for element that is not measured"; return getMeasuredSize(element, nullSize).getOuterHeight(); } @@ -970,7 +998,7 @@ public class LayoutManager { * given element, provided that it has been measured. These elements are * guaranteed to be measured: * <ul> - * <li>ManagedLayotus and their child Connectors + * <li>ManagedLayouts and their child Connectors * <li>Elements for which there is at least one ElementResizeListener * <li>Elements for which at least one ManagedLayout has registered a * dependency @@ -978,6 +1006,9 @@ public class LayoutManager { * * -1 is returned if the element has not been measured. If 0 is returned, it * might indicate that the element is not attached to the DOM. + * <p> + * The value returned by this method is always rounded up. To get the exact + * outer width, use {@link #getOuterWidthDouble(Element)} * * @param element * the element to get the measured size for @@ -986,6 +1017,31 @@ public class LayoutManager { */ public final int getOuterWidth(Element element) { assert needsMeasure(element) : "Getting measurement for element that is not measured"; + return (int) Math.ceil(getMeasuredSize(element, nullSize) + .getOuterWidth()); + } + + /** + * Gets the outer width (including margins, paddings and borders) of the + * given element, provided that it has been measured. These elements are + * guaranteed to be measured: + * <ul> + * <li>ManagedLayouts and their child Connectors + * <li>Elements for which there is at least one ElementResizeListener + * <li>Elements for which at least one ManagedLayout has registered a + * dependency + * </ul> + * + * -1 is returned if the element has not been measured. If 0 is returned, it + * might indicate that the element is not attached to the DOM. + * + * @param element + * the element to get the measured size for + * @return the measured outer width (including margins, paddings and + * borders) of the element in pixels. + */ + public final double getOuterWidthDouble(Element element) { + assert needsMeasure(element) : "Getting measurement for element that is not measured"; return getMeasuredSize(element, nullSize).getOuterWidth(); } @@ -994,7 +1050,7 @@ public class LayoutManager { * given element, provided that it has been measured. These elements are * guaranteed to be measured: * <ul> - * <li>ManagedLayotus and their child Connectors + * <li>ManagedLayouts and their child Connectors * <li>Elements for which there is at least one ElementResizeListener * <li>Elements for which at least one ManagedLayout has registered a * dependency @@ -1002,6 +1058,9 @@ public class LayoutManager { * * -1 is returned if the element has not been measured. If 0 is returned, it * might indicate that the element is not attached to the DOM. + * <p> + * The value returned by this method is always rounded up. To get the exact + * outer width, use {@link #getInnerHeightDouble(Element)} * * @param element * the element to get the measured size for @@ -1010,6 +1069,31 @@ public class LayoutManager { */ public final int getInnerHeight(Element element) { assert needsMeasure(element) : "Getting measurement for element that is not measured"; + return (int) Math.ceil(getMeasuredSize(element, nullSize) + .getInnerHeight()); + } + + /** + * Gets the inner height (excluding margins, paddings and borders) of the + * given element, provided that it has been measured. These elements are + * guaranteed to be measured: + * <ul> + * <li>ManagedLayouts and their child Connectors + * <li>Elements for which there is at least one ElementResizeListener + * <li>Elements for which at least one ManagedLayout has registered a + * dependency + * </ul> + * + * -1 is returned if the element has not been measured. If 0 is returned, it + * might indicate that the element is not attached to the DOM. + * + * @param element + * the element to get the measured size for + * @return the measured inner height (excluding margins, paddings and + * borders) of the element in pixels. + */ + public final double getInnerHeightDouble(Element element) { + assert needsMeasure(element) : "Getting measurement for element that is not measured"; return getMeasuredSize(element, nullSize).getInnerHeight(); } @@ -1018,7 +1102,7 @@ public class LayoutManager { * given element, provided that it has been measured. These elements are * guaranteed to be measured: * <ul> - * <li>ManagedLayotus and their child Connectors + * <li>ManagedLayouts and their child Connectors * <li>Elements for which there is at least one ElementResizeListener * <li>Elements for which at least one ManagedLayout has registered a * dependency @@ -1026,6 +1110,9 @@ public class LayoutManager { * * -1 is returned if the element has not been measured. If 0 is returned, it * might indicate that the element is not attached to the DOM. + * <p> + * The value returned by this method is always rounded up. To get the exact + * outer width, use {@link #getOuterHeightDouble(Element)} * * @param element * the element to get the measured size for @@ -1034,6 +1121,31 @@ public class LayoutManager { */ public final int getInnerWidth(Element element) { assert needsMeasure(element) : "Getting measurement for element that is not measured"; + return (int) Math.ceil(getMeasuredSize(element, nullSize) + .getInnerWidth()); + } + + /** + * Gets the inner width (excluding margins, paddings and borders) of the + * given element, provided that it has been measured. These elements are + * guaranteed to be measured: + * <ul> + * <li>ManagedLayouts and their child Connectors + * <li>Elements for which there is at least one ElementResizeListener + * <li>Elements for which at least one ManagedLayout has registered a + * dependency + * </ul> + * + * -1 is returned if the element has not been measured. If 0 is returned, it + * might indicate that the element is not attached to the DOM. + * + * @param element + * the element to get the measured size for + * @return the measured inner width (excluding margins, paddings and + * borders) of the element in pixels. + */ + public final double getInnerWidthDouble(Element element) { + assert needsMeasure(element) : "Getting measurement for element that is not measured"; return getMeasuredSize(element, nullSize).getInnerWidth(); } @@ -1042,7 +1154,7 @@ public class LayoutManager { * provided that it has been measured. These elements are guaranteed to be * measured: * <ul> - * <li>ManagedLayotus and their child Connectors + * <li>ManagedLayouts and their child Connectors * <li>Elements for which there is at least one ElementResizeListener * <li>Elements for which at least one ManagedLayout has registered a * dependency @@ -1067,7 +1179,7 @@ public class LayoutManager { * element, provided that it has been measured. These elements are * guaranteed to be measured: * <ul> - * <li>ManagedLayotus and their child Connectors + * <li>ManagedLayouts and their child Connectors * <li>Elements for which there is at least one ElementResizeListener * <li>Elements for which at least one ManagedLayout has registered a * dependency @@ -1092,7 +1204,7 @@ public class LayoutManager { * provided that it has been measured. These elements are guaranteed to be * measured: * <ul> - * <li>ManagedLayotus and their child Connectors + * <li>ManagedLayouts and their child Connectors * <li>Elements for which there is at least one ElementResizeListener * <li>Elements for which at least one ManagedLayout has registered a * dependency @@ -1116,7 +1228,7 @@ public class LayoutManager { * Gets the top border of the given element, provided that it has been * measured. These elements are guaranteed to be measured: * <ul> - * <li>ManagedLayotus and their child Connectors + * <li>ManagedLayouts and their child Connectors * <li>Elements for which there is at least one ElementResizeListener * <li>Elements for which at least one ManagedLayout has registered a * dependency @@ -1139,7 +1251,7 @@ public class LayoutManager { * Gets the left border of the given element, provided that it has been * measured. These elements are guaranteed to be measured: * <ul> - * <li>ManagedLayotus and their child Connectors + * <li>ManagedLayouts and their child Connectors * <li>Elements for which there is at least one ElementResizeListener * <li>Elements for which at least one ManagedLayout has registered a * dependency @@ -1162,7 +1274,7 @@ public class LayoutManager { * Gets the bottom border of the given element, provided that it has been * measured. These elements are guaranteed to be measured: * <ul> - * <li>ManagedLayotus and their child Connectors + * <li>ManagedLayouts and their child Connectors * <li>Elements for which there is at least one ElementResizeListener * <li>Elements for which at least one ManagedLayout has registered a * dependency @@ -1185,7 +1297,7 @@ public class LayoutManager { * Gets the right border of the given element, provided that it has been * measured. These elements are guaranteed to be measured: * <ul> - * <li>ManagedLayotus and their child Connectors + * <li>ManagedLayouts and their child Connectors * <li>Elements for which there is at least one ElementResizeListener * <li>Elements for which at least one ManagedLayout has registered a * dependency @@ -1209,7 +1321,7 @@ public class LayoutManager { * element, provided that it has been measured. These elements are * guaranteed to be measured: * <ul> - * <li>ManagedLayotus and their child Connectors + * <li>ManagedLayouts and their child Connectors * <li>Elements for which there is at least one ElementResizeListener * <li>Elements for which at least one ManagedLayout has registered a * dependency @@ -1233,7 +1345,7 @@ public class LayoutManager { * Gets the top padding of the given element, provided that it has been * measured. These elements are guaranteed to be measured: * <ul> - * <li>ManagedLayotus and their child Connectors + * <li>ManagedLayouts and their child Connectors * <li>Elements for which there is at least one ElementResizeListener * <li>Elements for which at least one ManagedLayout has registered a * dependency @@ -1256,7 +1368,7 @@ public class LayoutManager { * Gets the left padding of the given element, provided that it has been * measured. These elements are guaranteed to be measured: * <ul> - * <li>ManagedLayotus and their child Connectors + * <li>ManagedLayouts and their child Connectors * <li>Elements for which there is at least one ElementResizeListener * <li>Elements for which at least one ManagedLayout has registered a * dependency @@ -1279,7 +1391,7 @@ public class LayoutManager { * Gets the bottom padding of the given element, provided that it has been * measured. These elements are guaranteed to be measured: * <ul> - * <li>ManagedLayotus and their child Connectors + * <li>ManagedLayouts and their child Connectors * <li>Elements for which there is at least one ElementResizeListener * <li>Elements for which at least one ManagedLayout has registered a * dependency @@ -1302,7 +1414,7 @@ public class LayoutManager { * Gets the right padding of the given element, provided that it has been * measured. These elements are guaranteed to be measured: * <ul> - * <li>ManagedLayotus and their child Connectors + * <li>ManagedLayouts and their child Connectors * <li>Elements for which there is at least one ElementResizeListener * <li>Elements for which at least one ManagedLayout has registered a * dependency @@ -1325,7 +1437,7 @@ public class LayoutManager { * Gets the top margin of the given element, provided that it has been * measured. These elements are guaranteed to be measured: * <ul> - * <li>ManagedLayotus and their child Connectors + * <li>ManagedLayouts and their child Connectors * <li>Elements for which there is at least one ElementResizeListener * <li>Elements for which at least one ManagedLayout has registered a * dependency @@ -1348,7 +1460,7 @@ public class LayoutManager { * Gets the right margin of the given element, provided that it has been * measured. These elements are guaranteed to be measured: * <ul> - * <li>ManagedLayotus and their child Connectors + * <li>ManagedLayouts and their child Connectors * <li>Elements for which there is at least one ElementResizeListener * <li>Elements for which at least one ManagedLayout has registered a * dependency @@ -1371,7 +1483,7 @@ public class LayoutManager { * Gets the bottom margin of the given element, provided that it has been * measured. These elements are guaranteed to be measured: * <ul> - * <li>ManagedLayotus and their child Connectors + * <li>ManagedLayouts and their child Connectors * <li>Elements for which there is at least one ElementResizeListener * <li>Elements for which at least one ManagedLayout has registered a * dependency @@ -1394,7 +1506,7 @@ public class LayoutManager { * Gets the left margin of the given element, provided that it has been * measured. These elements are guaranteed to be measured: * <ul> - * <li>ManagedLayotus and their child Connectors + * <li>ManagedLayouts and their child Connectors * <li>Elements for which there is at least one ElementResizeListener * <li>Elements for which at least one ManagedLayout has registered a * dependency @@ -1417,7 +1529,7 @@ public class LayoutManager { * Gets the combined top & bottom margin of the given element, provided that * they have been measured. These elements are guaranteed to be measured: * <ul> - * <li>ManagedLayotus and their child Connectors + * <li>ManagedLayouts and their child Connectors * <li>Elements for which there is at least one ElementResizeListener * <li>Elements for which at least one ManagedLayout has registered a * dependency @@ -1439,7 +1551,7 @@ public class LayoutManager { * Gets the combined left & right margin of the given element, provided that * they have been measured. These elements are guaranteed to be measured: * <ul> - * <li>ManagedLayotus and their child Connectors + * <li>ManagedLayouts and their child Connectors * <li>Elements for which there is at least one ElementResizeListener * <li>Elements for which at least one ManagedLayout has registered a * dependency diff --git a/client/src/com/vaadin/client/MeasuredSize.java b/client/src/com/vaadin/client/MeasuredSize.java index ba8fca417b..2099008350 100644 --- a/client/src/com/vaadin/client/MeasuredSize.java +++ b/client/src/com/vaadin/client/MeasuredSize.java @@ -45,8 +45,8 @@ public class MeasuredSize { } } - private int width = -1; - private int height = -1; + private double width = -1; + private double height = -1; private int[] paddings = new int[4]; private int[] borders = new int[4]; @@ -54,11 +54,11 @@ public class MeasuredSize { private FastStringSet dependents = FastStringSet.create(); - public int getOuterHeight() { + public double getOuterHeight() { return height; } - public int getOuterWidth() { + public double getOuterWidth() { return width; } @@ -86,17 +86,17 @@ public class MeasuredSize { return sizes[0] + sizes[2]; } - public int getInnerHeight() { + public double getInnerHeight() { return height - sumHeights(margins) - sumHeights(borders) - sumHeights(paddings); } - public int getInnerWidth() { + public double getInnerWidth() { return width - sumWidths(margins) - sumWidths(borders) - sumWidths(paddings); } - public boolean setOuterHeight(int height) { + public boolean setOuterHeight(double height) { if (this.height != height) { this.height = height; return true; @@ -105,7 +105,7 @@ public class MeasuredSize { } } - public boolean setOuterWidth(int width) { + public boolean setOuterWidth(double width) { if (this.width != width) { this.width = width; return true; @@ -238,20 +238,20 @@ public class MeasuredSize { Profiler.leave("Measure borders"); Profiler.enter("Measure height"); - int requiredHeight = WidgetUtil.getRequiredHeight(element); - int marginHeight = sumHeights(margins); - int oldHeight = height; - int oldWidth = width; - if (setOuterHeight(requiredHeight + marginHeight)) { + double requiredHeight = WidgetUtil.getRequiredHeightDouble(element); + double outerHeight = requiredHeight + sumHeights(margins); + double oldHeight = height; + if (setOuterHeight(outerHeight)) { debugSizeChange(element, "Height (outer)", oldHeight, height); heightChanged = true; } Profiler.leave("Measure height"); Profiler.enter("Measure width"); - int requiredWidth = WidgetUtil.getRequiredWidth(element); - int marginWidth = sumWidths(margins); - if (setOuterWidth(requiredWidth + marginWidth)) { + double requiredWidth = WidgetUtil.getRequiredWidthDouble(element); + double outerWidth = requiredWidth + sumWidths(margins); + double oldWidth = width; + if (setOuterWidth(outerWidth)) { debugSizeChange(element, "Width (outer)", oldWidth, width); widthChanged = true; } @@ -270,7 +270,7 @@ public class MeasuredSize { } private void debugSizeChange(Element element, String sizeChangeType, - int changedFrom, int changedTo) { + double changedFrom, double changedTo) { debugSizeChange(element, sizeChangeType, String.valueOf(changedFrom), String.valueOf(changedTo)); } diff --git a/client/src/com/vaadin/client/WidgetUtil.java b/client/src/com/vaadin/client/WidgetUtil.java index e89e875953..fca6fbccbc 100644 --- a/client/src/com/vaadin/client/WidgetUtil.java +++ b/client/src/com/vaadin/client/WidgetUtil.java @@ -541,6 +541,29 @@ public class WidgetUtil { } /** + * Gets the border-box width for the given element, i.e. element width + + * border + padding. + * + * @param element + * The element to check + * @return The border-box width for the element + */ + public static double getRequiredWidthDouble( + com.google.gwt.dom.client.Element element) { + double reqWidth = getRequiredWidthBoundingClientRectDouble(element); + if (BrowserInfo.get().isIE() && !BrowserInfo.get().isIE8()) { + double csWidth = getRequiredWidthComputedStyleDouble(element); + if (csWidth > reqWidth && csWidth < (reqWidth + 1)) { + // IE9 rounds reqHeight to integers BUT sometimes reports wrong + // csHeight it seems, so we only use csHeight if it is within a + // rounding error + return csWidth; + } + } + return reqWidth; + } + + /** * Gets the border-box height for the given element, i.e. element height + * border + padding. Always rounds up to nearest integer. * @@ -567,6 +590,29 @@ public class WidgetUtil { } /** + * Gets the border-box height for the given element, i.e. element height + + * border + padding. + * + * @param element + * The element to check + * @return The border-box height for the element + */ + public static double getRequiredHeightDouble( + com.google.gwt.dom.client.Element element) { + double reqHeight = getRequiredHeightBoundingClientRectDouble(element); + if (BrowserInfo.get().isIE() && !BrowserInfo.get().isIE8()) { + double csHeight = getRequiredHeightComputedStyleDouble(element); + if (csHeight > reqHeight && csHeight < (reqHeight + 1)) { + // IE9 rounds reqHeight to integers BUT sometimes reports wrong + // csHeight it seems, so we only use csHeight if it is within a + // rounding error + return csHeight; + } + } + return reqHeight; + } + + /** * Calculates the width of the element's bounding rectangle. * <p> * In case the browser doesn't support bounding rectangles, the returned @@ -605,34 +651,44 @@ public class WidgetUtil { } }-*/; - public static native int getRequiredHeightComputedStyle( + public static int getRequiredHeightComputedStyle( + com.google.gwt.dom.client.Element element) { + return (int) Math.ceil(getRequiredHeightComputedStyleDouble(element)); + } + + public static native double getRequiredHeightComputedStyleDouble( com.google.gwt.dom.client.Element element) /*-{ var cs = element.ownerDocument.defaultView.getComputedStyle(element); var heightPx = cs.height; if(heightPx == 'auto'){ // Fallback for inline elements - return @com.vaadin.client.WidgetUtil::getRequiredHeightBoundingClientRect(Lcom/google/gwt/dom/client/Element;)(element); + return @com.vaadin.client.WidgetUtil::getRequiredHeightBoundingClientRectDouble(Lcom/google/gwt/dom/client/Element;)(element); } var height = parseFloat(heightPx); // Will automatically skip "px" suffix var border = parseFloat(cs.borderTopWidth) + parseFloat(cs.borderBottomWidth); // Will automatically skip "px" suffix var padding = parseFloat(cs.paddingTop) + parseFloat(cs.paddingBottom); // Will automatically skip "px" suffix - return Math.ceil(height+border+padding); + return height+border+padding; }-*/; - public static native int getRequiredWidthComputedStyle( + public static int getRequiredWidthComputedStyle( + com.google.gwt.dom.client.Element element) { + return (int) Math.ceil(getRequiredWidthComputedStyleDouble(element)); + } + + public static native int getRequiredWidthComputedStyleDouble( com.google.gwt.dom.client.Element element) /*-{ var cs = element.ownerDocument.defaultView.getComputedStyle(element); var widthPx = cs.width; if(widthPx == 'auto'){ // Fallback for inline elements - return @com.vaadin.client.WidgetUtil::getRequiredWidthBoundingClientRect(Lcom/google/gwt/dom/client/Element;)(element); + return @com.vaadin.client.WidgetUtil::getRequiredWidthBoundingClientRectDouble(Lcom/google/gwt/dom/client/Element;)(element); } var width = parseFloat(widthPx); // Will automatically skip "px" suffix var border = parseFloat(cs.borderLeftWidth) + parseFloat(cs.borderRightWidth); // Will automatically skip "px" suffix var padding = parseFloat(cs.paddingLeft) + parseFloat(cs.paddingRight); // Will automatically skip "px" suffix - return Math.ceil(width+border+padding); + return width+border+padding; }-*/; /** diff --git a/client/src/com/vaadin/client/ui/VGridLayout.java b/client/src/com/vaadin/client/ui/VGridLayout.java index d1e055eb5d..0c1d4cec90 100644 --- a/client/src/com/vaadin/client/ui/VGridLayout.java +++ b/client/src/com/vaadin/client/ui/VGridLayout.java @@ -143,8 +143,10 @@ public class VGridLayout extends ComplexPanel { if (!isUndefinedHeight()) { int usedSpace = calcRowUsedSpace(); int[] actualExpandRatio = calcRowExpandRatio(); - int availableSpace = LayoutManager.get(client).getInnerHeight( - getElement()); + // Round down to avoid problems with fractions (100.1px available -> + // can use 100, not 101) + int availableSpace = (int) LayoutManager.get(client) + .getInnerHeightDouble(getElement()); int excessSpace = availableSpace - usedSpace; int distributed = 0; if (excessSpace > 0) { @@ -223,8 +225,10 @@ public class VGridLayout extends ComplexPanel { if (!isUndefinedWidth()) { int usedSpace = calcColumnUsedSpace(); int[] actualExpandRatio = calcColumnExpandRatio(); - int availableSpace = LayoutManager.get(client).getInnerWidth( - getElement()); + // Round down to avoid problems with fractions (100.1px available -> + // can use 100, not 101) + int availableSpace = (int) LayoutManager.get(client) + .getInnerWidthDouble(getElement()); int excessSpace = availableSpace - usedSpace; int distributed = 0; if (excessSpace > 0) { diff --git a/uitest/src/com/vaadin/tests/components/gridlayout/GridLayoutFractionalSizeAndAlignment.java b/uitest/src/com/vaadin/tests/components/gridlayout/GridLayoutFractionalSizeAndAlignment.java new file mode 100644 index 0000000000..32d01f9910 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/gridlayout/GridLayoutFractionalSizeAndAlignment.java @@ -0,0 +1,66 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * 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.vaadin.tests.components.gridlayout; + +import com.vaadin.annotations.Widgetset; +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUIWithLog; +import com.vaadin.tests.widgetset.TestingWidgetSet; +import com.vaadin.tests.widgetset.server.ScrollableGridLayout; +import com.vaadin.ui.Alignment; +import com.vaadin.ui.Button; +import com.vaadin.ui.GridLayout; + +@Widgetset(TestingWidgetSet.NAME) +public class GridLayoutFractionalSizeAndAlignment extends AbstractTestUIWithLog { + + @Override + protected void setup(VaadinRequest request) { + widthTest(); + heightTest(); + } + + private void widthTest() { + final GridLayout layout = new ScrollableGridLayout(1, 1); + layout.setMargin(false); + layout.setSpacing(true); + + layout.setWidth(525.04f, Unit.PIXELS); + + Button button = new Button("Button"); + + layout.addComponent(button); + layout.setComponentAlignment(button, Alignment.BOTTOM_RIGHT); + + addComponent(layout); + } + + private void heightTest() { + final GridLayout layout = new ScrollableGridLayout(1, 1); + layout.setMargin(false); + layout.setSpacing(true); + + layout.setWidth(525.04f, Unit.PIXELS); + layout.setHeight(525.04f, Unit.PIXELS); + + Button button = new Button("Button"); + + layout.addComponent(button); + layout.setComponentAlignment(button, Alignment.BOTTOM_RIGHT); + + addComponent(layout); + } +} diff --git a/uitest/src/com/vaadin/tests/components/gridlayout/GridLayoutFractionalSizeAndAlignmentTest.java b/uitest/src/com/vaadin/tests/components/gridlayout/GridLayoutFractionalSizeAndAlignmentTest.java new file mode 100644 index 0000000000..b60aea49f0 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/gridlayout/GridLayoutFractionalSizeAndAlignmentTest.java @@ -0,0 +1,31 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * 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.vaadin.tests.components.gridlayout; + +import java.io.IOException; + +import org.junit.Test; + +import com.vaadin.tests.tb3.MultiBrowserTest; + +public class GridLayoutFractionalSizeAndAlignmentTest extends MultiBrowserTest { + + @Test + public void ensureNoScrollbarsWithAlignBottomRight() throws IOException { + openTestURL(); + compareScreen("noscrollbars"); + } +} diff --git a/uitest/src/com/vaadin/tests/widgetset/client/ScrollableGridLayoutConnector.java b/uitest/src/com/vaadin/tests/widgetset/client/ScrollableGridLayoutConnector.java new file mode 100644 index 0000000000..d6431ac9f9 --- /dev/null +++ b/uitest/src/com/vaadin/tests/widgetset/client/ScrollableGridLayoutConnector.java @@ -0,0 +1,36 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * 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.vaadin.tests.widgetset.client; + +import com.vaadin.client.ConnectorHierarchyChangeEvent; +import com.vaadin.client.ui.VGridLayout; +import com.vaadin.client.ui.gridlayout.GridLayoutConnector; +import com.vaadin.client.ui.layout.MayScrollChildren; +import com.vaadin.shared.ui.Connect; +import com.vaadin.tests.widgetset.server.ScrollableGridLayout; + +@Connect(ScrollableGridLayout.class) +public class ScrollableGridLayoutConnector extends GridLayoutConnector + implements MayScrollChildren { + @Override + public void onConnectorHierarchyChange(ConnectorHierarchyChangeEvent event) { + super.onConnectorHierarchyChange(event); + + for (VGridLayout.Cell cell : getWidget().widgetToCell.values()) { + cell.slot.getWrapperElement().addClassName("v-scrollable"); + } + } +} diff --git a/uitest/src/com/vaadin/tests/widgetset/server/ScrollableGridLayout.java b/uitest/src/com/vaadin/tests/widgetset/server/ScrollableGridLayout.java new file mode 100644 index 0000000000..6958172aa8 --- /dev/null +++ b/uitest/src/com/vaadin/tests/widgetset/server/ScrollableGridLayout.java @@ -0,0 +1,34 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * 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.vaadin.tests.widgetset.server; + +import com.vaadin.ui.Component; +import com.vaadin.ui.GridLayout; + +public class ScrollableGridLayout extends GridLayout { + + public ScrollableGridLayout() { + super(); + } + + public ScrollableGridLayout(int columns, int rows, Component... children) { + super(columns, rows, children); + } + + public ScrollableGridLayout(int columns, int rows) { + super(columns, rows); + } +} |