]> source.dussan.org Git - vaadin-framework.git/commitdiff
Fixed the sizing of relative-sized components in AbsoluteLayout (#13131)
authorAnna Koskinen <anna@vaadin.com>
Fri, 10 Oct 2014 07:51:11 +0000 (10:51 +0300)
committerVaadin Code Review <review@vaadin.com>
Tue, 14 Oct 2014 07:03:05 +0000 (07:03 +0000)
Change-Id: Ibc0757fa383b15dbf33f0b75a7d20ee78db5e88a

client/src/com/vaadin/client/ui/absolutelayout/AbsoluteLayoutConnector.java
uitest/src/com/vaadin/tests/components/absolutelayout/AbsoluteLayoutRelativeSizeContent.java [new file with mode: 0644]
uitest/src/com/vaadin/tests/components/absolutelayout/AbsoluteLayoutRelativeSizeContentTest.java [new file with mode: 0644]

index 366775e9a2dad4ea8f9ae4674a3e0c337dbe314c..e1234d436a50d3bdfa164f5a4da4e1e4587c2349 100644 (file)
@@ -183,8 +183,42 @@ public class AbsoluteLayoutConnector extends
     }
 
     private void setChildWidgetPosition(ComponentConnector child) {
-        getWidget().setWidgetPosition(child.getWidget(),
-                getState().connectorToCssPosition.get(child.getConnectorId()));
+        String position = getState().connectorToCssPosition.get(child
+                .getConnectorId());
+        if (position == null) {
+            position = "";
+        }
+        // make sure relative sizes get displayed correctly
+        String width = child.getState().width;
+        if (width != null && width.endsWith("%")) {
+            position = addDefaultPositionIfMissing(position, "left");
+            position = addDefaultPositionIfMissing(position, "right");
+        }
+        String height = child.getState().height;
+        if (height != null && height.endsWith("%")) {
+            position = addDefaultPositionIfMissing(position, "top");
+            position = addDefaultPositionIfMissing(position, "bottom");
+        }
+        getWidget().setWidgetPosition(child.getWidget(), position);
+    }
+
+    /**
+     * Adds default value of 0.0px for the given property if it's missing from
+     * the position string altogether. If the property value is already set no
+     * changes are needed.
+     * 
+     * @param position
+     *            original position styles
+     * @param property
+     *            the property that needs to have a value
+     * @return updated position, or the original string if no updates were
+     *         needed
+     */
+    private String addDefaultPositionIfMissing(String position, String property) {
+        if (!position.contains(property)) {
+            position = position + property + ":0.0px;";
+        }
+        return position;
     }
 
     /*
diff --git a/uitest/src/com/vaadin/tests/components/absolutelayout/AbsoluteLayoutRelativeSizeContent.java b/uitest/src/com/vaadin/tests/components/absolutelayout/AbsoluteLayoutRelativeSizeContent.java
new file mode 100644 (file)
index 0000000..4e1c8f5
--- /dev/null
@@ -0,0 +1,218 @@
+/*
+ * 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.absolutelayout;
+
+import com.vaadin.annotations.Theme;
+import com.vaadin.server.VaadinRequest;
+import com.vaadin.shared.ui.MarginInfo;
+import com.vaadin.tests.components.AbstractTestUI;
+import com.vaadin.ui.AbsoluteLayout;
+import com.vaadin.ui.Component;
+import com.vaadin.ui.HorizontalLayout;
+import com.vaadin.ui.Table;
+
+/**
+ * Tests how AbsoluteLayout handles relative sized contents.
+ * 
+ * @author Vaadin Ltd
+ */
+@Theme("tests-tickets")
+public class AbsoluteLayoutRelativeSizeContent extends AbstractTestUI {
+
+    @Override
+    protected void setup(VaadinRequest request) {
+        HorizontalLayout level1 = new HorizontalLayout(
+                createComparisonTableOnFixed(), createTableOnFixed(),
+                createHalfTableOnFixed(),
+                createHalfTableAndFixedTableOnFixed(), createHalfTableOnFull());
+        level1.setSpacing(true);
+        level1.setWidth(100, Unit.PERCENTAGE);
+        level1.setExpandRatio(
+                level1.getComponent(level1.getComponentCount() - 1), 1);
+        level1.setMargin(new MarginInfo(true, false, false, false));
+
+        HorizontalLayout level2 = new HorizontalLayout(createFullOnFixed(),
+                createFullOnFull());
+        level2.setSpacing(true);
+        level2.setWidth(100, Unit.PERCENTAGE);
+        level2.setExpandRatio(
+                level2.getComponent(level2.getComponentCount() - 1), 1);
+        level2.setMargin(new MarginInfo(true, false, false, false));
+
+        addComponent(level1);
+        addComponent(level2);
+    }
+
+    /**
+     * Creates an {@link AbsoluteLayout} of fixed size that contains a
+     * full-sized {@link Table} that has been forced to full size with css.
+     * Represents the workaround given for this ticket.
+     * 
+     * @return the created layout
+     */
+    private Component createComparisonTableOnFixed() {
+        AbsoluteLayout absoluteLayout = new AbsoluteLayout();
+        absoluteLayout.setWidth(200, Unit.PIXELS);
+        absoluteLayout.setHeight(200, Unit.PIXELS);
+        absoluteLayout.setCaption("comparison table in full size");
+
+        Table table = new Table();
+        table.setSizeFull();
+        table.setId("comparison-table");
+        absoluteLayout.addComponent(table, "top:0;bottom:0;left:0;right:0;");
+        return absoluteLayout;
+    }
+
+    /**
+     * Creates an {@link AbsoluteLayout} of fixed size that contains a
+     * full-sized {@link Table}.
+     * 
+     * @return the created layout
+     */
+    private Component createTableOnFixed() {
+        AbsoluteLayout absoluteLayout = new AbsoluteLayout();
+        absoluteLayout.setWidth(200, Unit.PIXELS);
+        absoluteLayout.setHeight(200, Unit.PIXELS);
+        absoluteLayout.setCaption("full-sized table expected");
+
+        Table table = new Table();
+        table.setSizeFull();
+        table.setId("full-table");
+        absoluteLayout.addComponent(table);
+        return absoluteLayout;
+    }
+
+    /**
+     * Creates an {@link AbsoluteLayout} of fixed size that contains a
+     * half-sized {@link Table}.
+     * 
+     * @return the created layout
+     */
+    private Component createHalfTableOnFixed() {
+        AbsoluteLayout absoluteLayout = new AbsoluteLayout();
+        absoluteLayout.setWidth(200, Unit.PIXELS);
+        absoluteLayout.setHeight(200, Unit.PIXELS);
+        absoluteLayout.setCaption("half-sized table expected");
+
+        Table table = new Table();
+        table.setWidth(50, Unit.PERCENTAGE);
+        table.setHeight(50, Unit.PERCENTAGE);
+        table.setId("half-table");
+        absoluteLayout.addComponent(table);
+        return absoluteLayout;
+    }
+
+    /**
+     * Creates an {@link AbsoluteLayout} of fixed size that contains a
+     * half-sized {@link Table} and a fixed size {@link Table}.
+     *
+     * @return the created layout
+     */
+    private Component createHalfTableAndFixedTableOnFixed() {
+        AbsoluteLayout absoluteLayout = new AbsoluteLayout();
+        absoluteLayout.setWidth(200, Unit.PIXELS);
+        absoluteLayout.setHeight(200, Unit.PIXELS);
+        absoluteLayout.setCaption("half-sized and tiny expected");
+
+        Table table = new Table();
+        table.setWidth(50, Unit.PERCENTAGE);
+        table.setHeight(50, Unit.PERCENTAGE);
+        table.setId("halfwithtiny-table");
+        absoluteLayout.addComponent(table);
+
+        Table tableTiny = new Table();
+        tableTiny.setWidth(50, Unit.PIXELS);
+        tableTiny.setHeight(50, Unit.PIXELS);
+        absoluteLayout.addComponent(tableTiny, "right:50;");
+        return absoluteLayout;
+    }
+
+    /**
+     * Creates an {@link AbsoluteLayout} of full size that contains a half-sized
+     * {@link Table}.
+     *
+     * @return the created layout
+     */
+    private Component createHalfTableOnFull() {
+        AbsoluteLayout absoluteLayout = new AbsoluteLayout();
+        absoluteLayout.setSizeFull();
+        absoluteLayout.setId("halfinfull-layout");
+        absoluteLayout.setCaption("half-sized table expected");
+
+        Table table = new Table();
+        table.setWidth(50, Unit.PERCENTAGE);
+        table.setHeight(50, Unit.PERCENTAGE);
+        table.setId("halfinfull-table");
+        absoluteLayout.addComponent(table);
+        return absoluteLayout;
+    }
+
+    /**
+     * Creates an {@link AbsoluteLayout} of fixed size that contains a
+     * fixed-sized {@link AbsoluteLayout}.
+     * 
+     * @return the created layout
+     */
+    private Component createFullOnFixed() {
+        AbsoluteLayout absoluteLayout = new AbsoluteLayout();
+        absoluteLayout.setWidth(200, Unit.PIXELS);
+        absoluteLayout.setHeight(200, Unit.PIXELS);
+        absoluteLayout.setId("fullonfixed-outer");
+        absoluteLayout.addStyleName("green");
+        absoluteLayout.setCaption("yellow area expected");
+
+        AbsoluteLayout absoluteLayout2 = new AbsoluteLayout();
+        absoluteLayout2.setSizeFull();
+        absoluteLayout2.setId("fullonfixed-inner");
+        absoluteLayout2.addStyleName("yellow");
+
+        absoluteLayout.addComponent(absoluteLayout2, "top:50px;left:100px;");
+        return absoluteLayout;
+    }
+
+    /**
+     * Creates an {@link AbsoluteLayout} of full size that contains another
+     * full-sized {@link AbsoluteLayout}.
+     * 
+     * @return the created layout
+     */
+    private AbsoluteLayout createFullOnFull() {
+        AbsoluteLayout absoluteLayout = new AbsoluteLayout();
+        absoluteLayout.setSizeFull();
+        absoluteLayout.setId("fullonfull-outer");
+        absoluteLayout.addStyleName("cyan");
+        absoluteLayout.setCaption("area with red border expected");
+
+        AbsoluteLayout absoluteLayout2 = new AbsoluteLayout();
+        absoluteLayout2.setSizeFull();
+        absoluteLayout2.setId("fullonfull-inner");
+        absoluteLayout2.addStyleName("redborder");
+
+        absoluteLayout.addComponent(absoluteLayout2, "top:50px;left:100px;");
+        return absoluteLayout;
+    }
+
+    @Override
+    protected String getTestDescription() {
+        return "Full size component in AbsoluteLayout shouldn't get undefined size";
+    }
+
+    @Override
+    protected Integer getTicketNumber() {
+        return 13131;
+    }
+
+}
diff --git a/uitest/src/com/vaadin/tests/components/absolutelayout/AbsoluteLayoutRelativeSizeContentTest.java b/uitest/src/com/vaadin/tests/components/absolutelayout/AbsoluteLayoutRelativeSizeContentTest.java
new file mode 100644 (file)
index 0000000..6cb8c47
--- /dev/null
@@ -0,0 +1,120 @@
+/*
+ * 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.absolutelayout;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.core.Is.is;
+import static org.hamcrest.number.IsCloseTo.closeTo;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.openqa.selenium.By;
+import org.openqa.selenium.WebElement;
+
+import com.vaadin.tests.tb3.MultiBrowserTest;
+
+/**
+ * Tests how AbsoluteLayout handles relative sized contents.
+ * 
+ * @author Vaadin Ltd
+ */
+public class AbsoluteLayoutRelativeSizeContentTest extends MultiBrowserTest {
+
+    @Override
+    @Before
+    public void setup() throws Exception {
+        super.setup();
+        openTestURL();
+
+        waitForElementPresent(By.id("comparison-table"));
+    };
+
+    @Test
+    public void testFullAgainstComparison() {
+        WebElement comparison = findElement(By.id("comparison-table"));
+        WebElement full = findElement(By.id("full-table"));
+
+        assertThat("Full table should be as wide as comparison table",
+                full.getSize().width, is(comparison.getSize().width));
+        assertThat("Full table should be as high as comparison table",
+                full.getSize().height, is(comparison.getSize().height));
+    }
+
+    @Test
+    public void testHalfAgainstComparison() {
+        WebElement comparison = findElement(By.id("comparison-table"));
+        WebElement half = findElement(By.id("half-table"));
+
+        assertThat(
+                "Half-sized table should be half as wide as comparison table",
+                half.getSize().width, is(comparison.getSize().width / 2));
+        assertThat(
+                "Half-sized table should be half as high as comparison table",
+                half.getSize().height, is(comparison.getSize().height / 2));
+    }
+
+    @Test
+    public void testHalfWithTinyAgainstComparison() {
+        WebElement comparison = findElement(By.id("comparison-table"));
+        WebElement half = findElement(By.id("halfwithtiny-table"));
+
+        assertThat(
+                "Half-sized table should be half as wide as comparison table even if there are other components in the layout",
+                half.getSize().width, is(comparison.getSize().width / 2));
+        assertThat(
+                "Half-sized table should be half as high as comparison table even if there are other components in the layout",
+                half.getSize().height, is(comparison.getSize().height / 2));
+    }
+
+    @Test
+    public void testHalfAgainstFullLayout() {
+        WebElement layout = findElement(By.id("halfinfull-layout"));
+        WebElement half = findElement(By.id("halfinfull-table"));
+
+        assertThat("Half-sized table should be half as wide as full layout",
+                (double) half.getSize().width,
+                closeTo(((double) layout.getSize().width) / 2, 0.5));
+        assertThat("Half-sized table should be half as high as full layout",
+                (double) half.getSize().height,
+                closeTo(((double) layout.getSize().height) / 2, 0.5));
+    }
+
+    @Test
+    public void testFullOnFixedWithSetLocation() {
+        WebElement outer = findElement(By.id("fullonfixed-outer"));
+        WebElement inner = findElement(By.id("fullonfixed-inner"));
+
+        assertThat(
+                "Inner layout should be as wide as outer layout minus left position",
+                inner.getSize().width, is(outer.getSize().width - 100));
+        assertThat(
+                "Inner layout should be as high as outer layout minus top position",
+                inner.getSize().height, is(outer.getSize().height - 50));
+    }
+
+    @Test
+    public void testFullOnFullWithSetLocation() {
+        WebElement outer = findElement(By.id("fullonfull-outer"));
+        WebElement inner = findElement(By.id("fullonfull-inner"));
+
+        assertThat(
+                "Inner layout should be as wide as outer layout minus left position",
+                inner.getSize().width, is(outer.getSize().width - 100));
+        assertThat(
+                "Inner layout should be as high as outer layout minus top position",
+                inner.getSize().height, is(outer.getSize().height - 50));
+    }
+}