From 8f6a7b9d36caf30b39d5fe5e2a517f81ab7062d2 Mon Sep 17 00:00:00 2001 From: Teemu Suo-Anttila Date: Wed, 8 Apr 2015 13:40:49 +0300 Subject: Add DesignerAttributeHelper.readAttribute with default value (#17416) Change-Id: Ic746e761942c3d801c8e1c71bd5866bbd5daeaf4 --- .../ui/declarative/DesignAttributeHandler.java | 80 ++++++++++++++-------- 1 file changed, 51 insertions(+), 29 deletions(-) (limited to 'server/src/com') diff --git a/server/src/com/vaadin/ui/declarative/DesignAttributeHandler.java b/server/src/com/vaadin/ui/declarative/DesignAttributeHandler.java index 2b446bda0e..e93a5c51cb 100644 --- a/server/src/com/vaadin/ui/declarative/DesignAttributeHandler.java +++ b/server/src/com/vaadin/ui/declarative/DesignAttributeHandler.java @@ -218,17 +218,67 @@ public class DesignAttributeHandler implements Serializable { } /** - * Reads the given attribute from a set of attributes. + * Writes the given attribute value to a set of attributes if it differs + * from the default attribute value. + * + * @param attribute + * the attribute key + * @param attributes + * the set of attributes where the new attribute is written + * @param value + * the attribute value + * @param defaultValue + * the default attribute value + * @param inputType + * the type of the input value + */ + public static void writeAttribute(String attribute, + Attributes attributes, T value, T defaultValue, Class inputType) { + if (!getFormatter().canConvert(inputType)) { + throw new IllegalArgumentException("input type: " + + inputType.getName() + " not supported"); + } + if (!SharedUtil.equals(value, defaultValue)) { + String attributeValue = toAttributeValue(inputType, value); + attributes.put(attribute, attributeValue); + } + } + + /** + * Reads the given attribute from a set of attributes. If attribute does not + * exist return a given default value. * * @param attribute * the attribute key * @param attributes * the set of attributes to read from + * @param defaultValue + * the default value to return if attribute does not exist * @param outputType * the output type for the attribute * @return the attribute value or the default value if the attribute is not * found */ + public static T readAttribute(String attribute, Attributes attributes, + T defaultValue, Class outputType) { + T value = readAttribute(attribute, attributes, outputType); + if (value != null) { + return value; + } + return defaultValue; + } + + /** + * Reads the given attribute from a set of attributes. + * + * @param attribute + * the attribute key + * @param attributes + * the set of attributes to read from + * @param outputType + * the output type for the attribute + * @return the attribute value or null + */ public static T readAttribute(String attribute, Attributes attributes, Class outputType) { if (!getFormatter().canConvert(outputType)) { @@ -248,33 +298,6 @@ public class DesignAttributeHandler implements Serializable { } } - /** - * Writes the given attribute value to a set of attributes if it differs - * from the default attribute value. - * - * @param attribute - * the attribute key - * @param attributes - * the set of attributes where the new attribute is written - * @param value - * the attribute value - * @param defaultValue - * the default attribute value - * @param inputType - * the type of the input value - */ - public static void writeAttribute(String attribute, - Attributes attributes, T value, T defaultValue, Class inputType) { - if (!getFormatter().canConvert(inputType)) { - throw new IllegalArgumentException("input type: " - + inputType.getName() + " not supported"); - } - if (!SharedUtil.equals(value, defaultValue)) { - String attributeValue = toAttributeValue(inputType, value); - attributes.put(attribute, attributeValue); - } - } - /** * Returns the design attribute name corresponding the given method name. * For example given a method name setPrimaryStyleName the @@ -425,5 +448,4 @@ public class DesignAttributeHandler implements Serializable { return (methods != null && methods.length > 1) ? methods[1] : null; } } - } -- cgit v1.2.3 From 9f95ac117ac55c54f6a3d69ab3bd9aa3d8f1ef76 Mon Sep 17 00:00:00 2001 From: Teemu Suo-Anttila Date: Thu, 2 Apr 2015 13:49:17 +0300 Subject: Fix MenuBar MenuItem caption reading from design (#17361) Change-Id: I438039ab8ad83bf0b2153939502903571f231bbb --- server/src/com/vaadin/ui/MenuBar.java | 3 +- .../components/menubar/MenuBarDeclarativeTest.java | 62 +++++++++++++++++++++- 2 files changed, 63 insertions(+), 2 deletions(-) (limited to 'server/src/com') diff --git a/server/src/com/vaadin/ui/MenuBar.java b/server/src/com/vaadin/ui/MenuBar.java index 747ce42727..c11cf02aaf 100644 --- a/server/src/com/vaadin/ui/MenuBar.java +++ b/server/src/com/vaadin/ui/MenuBar.java @@ -1008,8 +1008,9 @@ public class MenuBar extends AbstractComponent implements LegacyComponent, if (node instanceof Element && ((Element) node).tagName().equals("menu")) { subMenus.add((Element) node); + } else { + caption += node.toString(); } - caption += node.toString(); } MenuItem menu = new MenuItem(caption.trim(), icon, null); diff --git a/server/tests/src/com/vaadin/tests/components/menubar/MenuBarDeclarativeTest.java b/server/tests/src/com/vaadin/tests/components/menubar/MenuBarDeclarativeTest.java index e6dee44812..3bc1ebfbf9 100644 --- a/server/tests/src/com/vaadin/tests/components/menubar/MenuBarDeclarativeTest.java +++ b/server/tests/src/com/vaadin/tests/components/menubar/MenuBarDeclarativeTest.java @@ -16,7 +16,9 @@ package com.vaadin.tests.components.menubar; import java.io.IOException; +import java.util.List; +import org.junit.Assert; import org.junit.Test; import com.vaadin.server.ExternalResource; @@ -128,7 +130,7 @@ public class MenuBarDeclarativeTest extends DeclarativeTestBase { MenuBar menuBar = new MenuBar(); menuBar.setHtmlContentAllowed(true); MenuItem fileMenu = menuBar.addItem("File", null); - fileMenu.addItem("Save", null); + fileMenu.addItem("Save", null); fileMenu.addItem("Open", new ThemeResource( "../runo/icons/16/folder.png"), null); fileMenu.addSeparator(); @@ -136,4 +138,62 @@ public class MenuBarDeclarativeTest extends DeclarativeTestBase { testRead(design, menuBar); testWrite(design, menuBar); } + + @Override + public MenuBar testRead(String design, MenuBar expected) { + MenuBar result = super.testRead(design, expected); + + List expectedMenuItems = expected.getItems(); + List actualMenuItems = result.getItems(); + Assert.assertEquals("Different amount of menu items", + expectedMenuItems.size(), actualMenuItems.size()); + + for (int i = 0; i < expectedMenuItems.size(); ++i) { + compareMenus(expectedMenuItems.get(i), actualMenuItems.get(i)); + } + + return result; + } + + private void compareMenus(MenuItem expected, MenuItem actual) { + String baseError = "Error Comparing MenuItem " + expected.getText() + + ": "; + Assert.assertEquals(baseError + "Visibile", expected.isVisible(), + actual.isVisible()); + Assert.assertEquals(baseError + "Checkable", expected.isCheckable(), + actual.isCheckable()); + Assert.assertEquals(baseError + "Checked", expected.isChecked(), + actual.isChecked()); + Assert.assertEquals(baseError + "Separator", expected.isSeparator(), + actual.isSeparator()); + Assert.assertEquals(baseError + "Enabled", expected.isEnabled(), + actual.isEnabled()); + + Assert.assertEquals(baseError + "Text", expected.getText(), + actual.getText()); + Assert.assertEquals(baseError + "Description", + expected.getDescription(), actual.getDescription()); + Assert.assertEquals(baseError + "Style Name", expected.getStyleName(), + actual.getStyleName()); + + if (expected.getIcon() != null) { + Assert.assertNotNull(baseError + "Icon was null", actual.getIcon()); + } else { + if (actual.getIcon() != null) { + Assert.fail(baseError + "Icon should've been null"); + } + } + + Assert.assertEquals(baseError + "Has Children", expected.hasChildren(), + actual.hasChildren()); + if (expected.hasChildren()) { + List children = expected.getChildren(); + List actualChildren = actual.getChildren(); + Assert.assertEquals(baseError + "Child count", children.size(), + actualChildren.size()); + for (int i = 0; i < children.size(); ++i) { + compareMenus(children.get(i), actualChildren.get(i)); + } + } + } } \ No newline at end of file -- cgit v1.2.3 From a1a154bcd56185ee1607d1d4ec0d50af3036cc08 Mon Sep 17 00:00:00 2001 From: Leif Ã…strand Date: Thu, 9 Apr 2015 10:07:46 +0300 Subject: Javadoc fix Change-Id: Ib60e2f7ffa70030b93715adc453855c4bad7a372 --- server/src/com/vaadin/data/fieldgroup/FieldGroup.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'server/src/com') diff --git a/server/src/com/vaadin/data/fieldgroup/FieldGroup.java b/server/src/com/vaadin/data/fieldgroup/FieldGroup.java index 8f1bf8b40a..d370c3906b 100644 --- a/server/src/com/vaadin/data/fieldgroup/FieldGroup.java +++ b/server/src/com/vaadin/data/fieldgroup/FieldGroup.java @@ -702,7 +702,7 @@ public class FieldGroup implements Serializable { /** * Called after changes are committed to the fields and the item is - * updated.. + * updated. *

* Throw a {@link CommitException} to abort the commit. * -- cgit v1.2.3 From 8a50c558bcee3ede27ff5553785065e23c74748d Mon Sep 17 00:00:00 2001 From: patrik Date: Wed, 8 Apr 2015 10:00:57 +0300 Subject: Add granular declarative margin support (#17190) Change-Id: I36227feeeaf08f41a9d5c179547dfcb575a1fb09 --- .../src/com/vaadin/ui/AbstractOrderedLayout.java | 57 ++++++++++- .../AbstractLayoutDeclarativeMarginTest.java | 104 +++++++++++++++++++++ shared/src/com/vaadin/shared/ui/MarginInfo.java | 5 + 3 files changed, 162 insertions(+), 4 deletions(-) create mode 100644 server/tests/src/com/vaadin/tests/server/component/AbstractLayoutDeclarativeMarginTest.java (limited to 'server/src/com') diff --git a/server/src/com/vaadin/ui/AbstractOrderedLayout.java b/server/src/com/vaadin/ui/AbstractOrderedLayout.java index 3aec3b2d7a..0214ff4be1 100644 --- a/server/src/com/vaadin/ui/AbstractOrderedLayout.java +++ b/server/src/com/vaadin/ui/AbstractOrderedLayout.java @@ -477,11 +477,32 @@ public abstract class AbstractOrderedLayout extends AbstractLayout implements public void readDesign(Element design, DesignContext designContext) { // process default attributes super.readDesign(design, designContext); - // handle margin + + // handle margins if (design.hasAttr("margin")) { setMargin(DesignAttributeHandler.readAttribute("margin", design.attributes(), Boolean.class)); + } else { + boolean marginLeft = DesignAttributeHandler.readAttribute( + "margin-left", design.attributes(), getMargin().hasLeft(), + Boolean.class); + + boolean marginRight = DesignAttributeHandler.readAttribute( + "margin-right", design.attributes(), + getMargin().hasRight(), Boolean.class); + + boolean marginTop = DesignAttributeHandler.readAttribute( + "margin-top", design.attributes(), getMargin().hasTop(), + Boolean.class); + + boolean marginBottom = DesignAttributeHandler.readAttribute( + "margin-bottom", design.attributes(), getMargin() + .hasBottom(), Boolean.class); + + setMargin(new MarginInfo(marginTop, marginBottom, marginLeft, + marginRight)); } + // handle children for (Element childComponent : design.children()) { Attributes attr = childComponent.attributes(); @@ -532,12 +553,36 @@ public abstract class AbstractOrderedLayout extends AbstractLayout implements public void writeDesign(Element design, DesignContext designContext) { // write default attributes super.writeDesign(design, designContext); - // handle margin + AbstractOrderedLayout def = (AbstractOrderedLayout) designContext .getDefaultInstance(this); - if (getMargin().getBitMask() != def.getMargin().getBitMask()) { - design.attr("margin", ""); + + // handle margin + MarginInfo marginInfo = getMargin(); + + if (marginInfo.hasAll()) { + DesignAttributeHandler.writeAttribute("margin", + design.attributes(), marginInfo.hasAll(), def.getMargin() + .hasAll(), Boolean.class); + } else { + + DesignAttributeHandler.writeAttribute("margin-left", design + .attributes(), marginInfo.hasLeft(), def.getMargin() + .hasLeft(), Boolean.class); + + DesignAttributeHandler.writeAttribute("margin-right", design + .attributes(), marginInfo.hasRight(), def.getMargin() + .hasRight(), Boolean.class); + + DesignAttributeHandler.writeAttribute("margin-top", design + .attributes(), marginInfo.hasTop(), def.getMargin() + .hasTop(), Boolean.class); + + DesignAttributeHandler.writeAttribute("margin-bottom", design + .attributes(), marginInfo.hasBottom(), def.getMargin() + .hasBottom(), Boolean.class); } + // handle children if (!designContext.shouldWriteChildren(this, def)) { return; @@ -578,6 +623,10 @@ public abstract class AbstractOrderedLayout extends AbstractLayout implements protected Collection getCustomAttributes() { Collection customAttributes = super.getCustomAttributes(); customAttributes.add("margin"); + customAttributes.add("margin-left"); + customAttributes.add("margin-right"); + customAttributes.add("margin-top"); + customAttributes.add("margin-bottom"); return customAttributes; } diff --git a/server/tests/src/com/vaadin/tests/server/component/AbstractLayoutDeclarativeMarginTest.java b/server/tests/src/com/vaadin/tests/server/component/AbstractLayoutDeclarativeMarginTest.java new file mode 100644 index 0000000000..70855f67dc --- /dev/null +++ b/server/tests/src/com/vaadin/tests/server/component/AbstractLayoutDeclarativeMarginTest.java @@ -0,0 +1,104 @@ +/* + * 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.server.component; + +import org.junit.Test; + +import com.vaadin.shared.ui.MarginInfo; +import com.vaadin.tests.design.DeclarativeTestBase; +import com.vaadin.ui.AbstractLayout; +import com.vaadin.ui.VerticalLayout; + +public class AbstractLayoutDeclarativeMarginTest extends + DeclarativeTestBase { + + @Test + public void testMarginInfo() { + VerticalLayout vl = new VerticalLayout(); + + String left = getMarginTag(true, false, false, false); + MarginInfo leftInfo = getMarginInfo(true, false, false, false); + + String right = getMarginTag(false, true, false, false); + MarginInfo rightInfo = getMarginInfo(false, true, false, false); + + String top = getMarginTag(false, false, true, false); + MarginInfo topInfo = getMarginInfo(false, false, true, false); + + String bottom = getMarginTag(false, false, false, true); + MarginInfo bottomInfo = getMarginInfo(false, false, false, true); + + String topLeft = getMarginTag(true, false, true, false); + MarginInfo topLeftInfo = getMarginInfo(true, false, true, false); + + String topRight = getMarginTag(false, true, true, false); + MarginInfo topRightInfo = getMarginInfo(false, true, true, false); + + String bottomLeft = getMarginTag(true, false, false, true); + MarginInfo bottomLeftInfo = getMarginInfo(true, false, false, true); + + String bottomRight = getMarginTag(false, true, false, true); + MarginInfo bottomRightInfo = getMarginInfo(false, true, false, true); + + testRW(vl, left, leftInfo); + testRW(vl, right, rightInfo); + testRW(vl, top, topInfo); + testRW(vl, bottom, bottomInfo); + + testRW(vl, topLeft, topLeftInfo); + testRW(vl, topRight, topRightInfo); + testRW(vl, bottomLeft, bottomLeftInfo); + testRW(vl, bottomRight, bottomRightInfo); + + // Test special case of all edges margin'ed + testRW(vl, getMarginTag(true, true, true, true), new MarginInfo(true)); + } + + private void testRW(VerticalLayout vl, String design, MarginInfo margin) { + vl.setMargin(margin); + testWrite(design, vl); + testRead(design, vl); + } + + private String getMarginTag(boolean left, boolean right, boolean top, + boolean bottom) { + String s = ""; + } + + private MarginInfo getMarginInfo(boolean left, boolean right, boolean top, + boolean bottom) { + return new MarginInfo(top, right, bottom, left); + } + +} diff --git a/shared/src/com/vaadin/shared/ui/MarginInfo.java b/shared/src/com/vaadin/shared/ui/MarginInfo.java index 3b1fece88a..4c0255a9ba 100644 --- a/shared/src/com/vaadin/shared/ui/MarginInfo.java +++ b/shared/src/com/vaadin/shared/ui/MarginInfo.java @@ -24,6 +24,7 @@ public class MarginInfo implements Serializable { private static final int RIGHT = 2; private static final int BOTTOM = 4; private static final int LEFT = 8; + private static final int ALL = TOP | RIGHT | BOTTOM | LEFT; private int bitMask; @@ -51,6 +52,10 @@ public class MarginInfo implements Serializable { bitMask = marginInfo.bitMask; } + public boolean hasAll() { + return (bitMask & ALL) == ALL; + } + public boolean hasLeft() { return (bitMask & LEFT) == LEFT; } -- cgit v1.2.3 From 8f02bfd384be1276b50b3ef2bfafec7a17523100 Mon Sep 17 00:00:00 2001 From: Artur Signell Date: Mon, 19 Jan 2015 15:03:11 +0200 Subject: Remove unusable code Change-Id: I5bfa459695da3fe4d2cb271952b8c112b7052e97 --- server/src/com/vaadin/ui/Tree.java | 13 ------------- 1 file changed, 13 deletions(-) (limited to 'server/src/com') diff --git a/server/src/com/vaadin/ui/Tree.java b/server/src/com/vaadin/ui/Tree.java index a86a9bd64b..3c5758c1ea 100644 --- a/server/src/com/vaadin/ui/Tree.java +++ b/server/src/com/vaadin/ui/Tree.java @@ -1301,19 +1301,6 @@ public class Tree extends AbstractSelect implements Container.Hierarchical, } } - /** - * Tree does not support lazy options loading mode. Setting this true will - * throw UnsupportedOperationException. - * - * @see com.vaadin.ui.Select#setLazyLoading(boolean) - */ - public void setLazyLoading(boolean useLazyLoading) { - if (useLazyLoading) { - throw new UnsupportedOperationException( - "Lazy options loading is not supported by Tree."); - } - } - private ItemStyleGenerator itemStyleGenerator; private DropHandler dropHandler; -- cgit v1.2.3 From 4217d7bbc8552e822367fac9d7d3cc9ee48821dd Mon Sep 17 00:00:00 2001 From: Denis Anisimov Date: Fri, 13 Mar 2015 10:52:35 +0200 Subject: Don't use !important for ColorPicker width in Valo (#17140). Change-Id: I47feff9c78a39e30233f388b938c7e4e53b52051 --- .../themes/base/colorpicker/colorpicker.scss | 3 + .../themes/valo/components/_colorpicker.scss | 2 +- .../colorpicker/AbstractColorPickerConnector.java | 16 +++++ server/src/com/vaadin/ui/ColorPicker.java | 12 ---- .../colorpicker/DefaultCaptionWidth.java | 72 ++++++++++++++++++++++ .../colorpicker/DefaultCaptionWidthTest.java | 67 ++++++++++++++++++++ .../tests/themes/valo/ValoDefaultCaptionWidth.java | 29 +++++++++ .../themes/valo/ValoDefaultCaptionWidthTest.java | 56 +++++++++++++++++ 8 files changed, 244 insertions(+), 13 deletions(-) create mode 100644 uitest/src/com/vaadin/tests/components/colorpicker/DefaultCaptionWidth.java create mode 100644 uitest/src/com/vaadin/tests/components/colorpicker/DefaultCaptionWidthTest.java create mode 100644 uitest/src/com/vaadin/tests/themes/valo/ValoDefaultCaptionWidth.java create mode 100644 uitest/src/com/vaadin/tests/themes/valo/ValoDefaultCaptionWidthTest.java (limited to 'server/src/com') diff --git a/WebContent/VAADIN/themes/base/colorpicker/colorpicker.scss b/WebContent/VAADIN/themes/base/colorpicker/colorpicker.scss index b2558d8df3..70705dcee3 100644 --- a/WebContent/VAADIN/themes/base/colorpicker/colorpicker.scss +++ b/WebContent/VAADIN/themes/base/colorpicker/colorpicker.scss @@ -18,6 +18,9 @@ margin: 1px auto; } +.#{$name}.v-default-caption-width { + width: 100px; +} /***************** COLOR HISTORY COMPONENT *****************************/ .#{$name}-history { diff --git a/WebContent/VAADIN/themes/valo/components/_colorpicker.scss b/WebContent/VAADIN/themes/valo/components/_colorpicker.scss index b859904e59..18f92500dc 100644 --- a/WebContent/VAADIN/themes/valo/components/_colorpicker.scss +++ b/WebContent/VAADIN/themes/valo/components/_colorpicker.scss @@ -198,7 +198,7 @@ } .#{$primary-stylename} { - width: auto !important; + width: auto; } .#{$primary-stylename}-button-color { diff --git a/client/src/com/vaadin/client/ui/colorpicker/AbstractColorPickerConnector.java b/client/src/com/vaadin/client/ui/colorpicker/AbstractColorPickerConnector.java index ac168d1f9a..cba2a667ca 100644 --- a/client/src/com/vaadin/client/ui/colorpicker/AbstractColorPickerConnector.java +++ b/client/src/com/vaadin/client/ui/colorpicker/AbstractColorPickerConnector.java @@ -30,6 +30,8 @@ import com.vaadin.shared.ui.colorpicker.ColorPickerState; public abstract class AbstractColorPickerConnector extends AbstractComponentConnector implements ClickHandler { + private static final String DEFAULT_WIDTH_STYLE = "v-default-caption-width"; + @Override public ColorPickerState getState() { return (ColorPickerState) super.getState(); @@ -59,6 +61,7 @@ public abstract class AbstractColorPickerConnector extends || stateChangeEvent.hasPropertyChanged("showDefaultCaption")) { setCaption(getCaption()); + refreshDefaultCaptionStyle(); } } @@ -83,6 +86,19 @@ public abstract class AbstractColorPickerConnector extends return getState().caption; } + /** + * Add/remove default caption style. + */ + protected void refreshDefaultCaptionStyle() { + if (getState().showDefaultCaption + && (getState().caption == null || getState().caption.isEmpty()) + && getState().width.isEmpty()) { + getWidget().addStyleName(DEFAULT_WIDTH_STYLE); + } else { + getWidget().removeStyleName(DEFAULT_WIDTH_STYLE); + } + } + /** * Set caption of the color picker widget. * diff --git a/server/src/com/vaadin/ui/ColorPicker.java b/server/src/com/vaadin/ui/ColorPicker.java index f65b67db72..9e46c4e718 100644 --- a/server/src/com/vaadin/ui/ColorPicker.java +++ b/server/src/com/vaadin/ui/ColorPicker.java @@ -64,16 +64,4 @@ public class ColorPicker extends AbstractColorPicker { addStyleName(STYLENAME_DEFAULT); } - @Override - public void beforeClientResponse(boolean initial) { - super.beforeClientResponse(initial); - - if (isDefaultCaptionEnabled() - && ((getState().caption == null || "" - .equals(getState().caption))) - && "".equals(getState().width)) { - getState().width = "100px"; - } - } - } diff --git a/uitest/src/com/vaadin/tests/components/colorpicker/DefaultCaptionWidth.java b/uitest/src/com/vaadin/tests/components/colorpicker/DefaultCaptionWidth.java new file mode 100644 index 0000000000..d3dd0aeccc --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/colorpicker/DefaultCaptionWidth.java @@ -0,0 +1,72 @@ +/* + * 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.colorpicker; + +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUI; +import com.vaadin.ui.Button; +import com.vaadin.ui.Button.ClickEvent; +import com.vaadin.ui.ColorPicker; + +/** + * Test for color picker with default caption. + * + * @author Vaadin Ltd + */ +public class DefaultCaptionWidth extends AbstractTestUI { + + @Override + protected void setup(VaadinRequest request) { + final ColorPicker colorPicker = new ColorPicker(); + addComponent(colorPicker); + colorPicker.setDefaultCaptionEnabled(true); + + Button setWidth = new Button("Set explicit width", + new Button.ClickListener() { + + @Override + public void buttonClick(ClickEvent event) { + colorPicker.setCaption(null); + colorPicker.setWidth("150px"); + } + }); + setWidth.addStyleName("set-width"); + addComponent(setWidth); + + Button setCaption = new Button("Set explicit caption", + new Button.ClickListener() { + + @Override + public void buttonClick(ClickEvent event) { + colorPicker.setCaption("caption"); + colorPicker.setWidthUndefined(); + } + }); + setCaption.addStyleName("set-caption"); + addComponent(setCaption); + + } + + @Override + protected String getTestDescription() { + return "Color picker with default caption enabled should get appropriate style"; + } + + @Override + protected Integer getTicketNumber() { + return 17140; + } +} diff --git a/uitest/src/com/vaadin/tests/components/colorpicker/DefaultCaptionWidthTest.java b/uitest/src/com/vaadin/tests/components/colorpicker/DefaultCaptionWidthTest.java new file mode 100644 index 0000000000..78b7120b4e --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/colorpicker/DefaultCaptionWidthTest.java @@ -0,0 +1,67 @@ +/* + * 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.colorpicker; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.openqa.selenium.By; + +import com.vaadin.testbench.elements.ColorPickerElement; +import com.vaadin.tests.tb3.MultiBrowserTest; + +/** + * Test for default caption behavior in color picker. + * + * @author Vaadin Ltd + */ +public class DefaultCaptionWidthTest extends MultiBrowserTest { + + @Before + public void setUp() { + openTestURL(); + } + + @Test + public void setDefaultCaption_sizeAndCaptionAreNotSet_pickerGetsStyle() { + checkStylePresence(true); + } + + @Test + public void setDefaultCaption_explicitSizeIsSet_pickerNoCaptionStyle() { + findElement(By.className("set-width")).click(); + checkStylePresence(false); + } + + @Test + public void setDefaultCaption_explicitCaptionIsSet_pickerNoCaptionStyle() { + findElement(By.className("set-caption")).click(); + checkStylePresence(false); + } + + protected void checkStylePresence(boolean expectedStyle) { + String clazz = $(ColorPickerElement.class).first() + .getAttribute("class"); + if (expectedStyle) { + Assert.assertTrue("Default caption style is not found", + clazz.contains("v-default-caption-width")); + } else { + Assert.assertFalse("Found unexpected default caption style", + clazz.contains("v-default-caption-width")); + } + } + +} diff --git a/uitest/src/com/vaadin/tests/themes/valo/ValoDefaultCaptionWidth.java b/uitest/src/com/vaadin/tests/themes/valo/ValoDefaultCaptionWidth.java new file mode 100644 index 0000000000..6ef585cc12 --- /dev/null +++ b/uitest/src/com/vaadin/tests/themes/valo/ValoDefaultCaptionWidth.java @@ -0,0 +1,29 @@ +/* + * 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.themes.valo; + +import com.vaadin.annotations.Theme; +import com.vaadin.tests.components.colorpicker.DefaultCaptionWidth; + +/** + * Test for color picker with default caption. + * + * @author Vaadin Ltd + */ +@Theme("valo") +public class ValoDefaultCaptionWidth extends DefaultCaptionWidth { + +} diff --git a/uitest/src/com/vaadin/tests/themes/valo/ValoDefaultCaptionWidthTest.java b/uitest/src/com/vaadin/tests/themes/valo/ValoDefaultCaptionWidthTest.java new file mode 100644 index 0000000000..7651b641de --- /dev/null +++ b/uitest/src/com/vaadin/tests/themes/valo/ValoDefaultCaptionWidthTest.java @@ -0,0 +1,56 @@ +/* + * 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.themes.valo; + +import static org.hamcrest.Matchers.greaterThan; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.lessThan; +import static org.junit.Assert.assertThat; + +import org.junit.Test; + +import com.vaadin.testbench.elements.ColorPickerElement; +import com.vaadin.tests.components.colorpicker.DefaultCaptionWidthTest; + +/** + * Test for default caption behavior in color picker using Valo theme. + * + * @author Vaadin Ltd + */ +public class ValoDefaultCaptionWidthTest extends DefaultCaptionWidthTest { + + @Override + @Test + public void setDefaultCaption_sizeAndCaptionAreNotSet_pickerGetsStyle() { + super.setDefaultCaption_sizeAndCaptionAreNotSet_pickerGetsStyle(); + int width = $(ColorPickerElement.class).first().getSize().getWidth(); + // Make sure that implicit width is less than one that will be + // explicitly set by the test + assertThat("Width of color picker is overriden by " + + "default caption feature", width, is(lessThan(148))); + } + + @Override + @Test + public void setDefaultCaption_explicitSizeIsSet_pickerNoCaptionStyle() { + super.setDefaultCaption_explicitSizeIsSet_pickerNoCaptionStyle(); + int width = $(ColorPickerElement.class).first().getSize().getWidth(); + // Width should be 150px but let's just check that it's not which is + // used when default caption is used and at least >= 150-1 + assertThat("Width of color picker is overriden by " + + "default caption feature", width, is(greaterThan(149))); + } +} -- cgit v1.2.3 From 3cb1cfec55f568838798a5afb5bf27b13ba82b42 Mon Sep 17 00:00:00 2001 From: Teemu Suo-Anttila Date: Wed, 8 Apr 2015 13:41:37 +0300 Subject: Fix GridLayout declarative support (#16594) Change-Id: I25e52a9246c9ccbc406d1f162b4e9ff69bb411ff --- server/src/com/vaadin/ui/GridLayout.java | 325 ++++++++++++++++++++- .../design/AbstractComponentSetResponsiveTest.java | 17 +- .../gridlayout/GridLayoutDeclarativeTest.java | 200 +++++++++++++ 3 files changed, 533 insertions(+), 9 deletions(-) create mode 100644 server/tests/src/com/vaadin/tests/server/component/gridlayout/GridLayoutDeclarativeTest.java (limited to 'server/src/com') diff --git a/server/src/com/vaadin/ui/GridLayout.java b/server/src/com/vaadin/ui/GridLayout.java index 96854c5b1b..35110b39ab 100644 --- a/server/src/com/vaadin/ui/GridLayout.java +++ b/server/src/com/vaadin/ui/GridLayout.java @@ -17,12 +17,21 @@ package com.vaadin.ui; import java.io.Serializable; +import java.util.ArrayList; +import java.util.Collection; import java.util.Collections; import java.util.HashMap; +import java.util.HashSet; import java.util.Iterator; import java.util.LinkedList; +import java.util.List; import java.util.Map; import java.util.Map.Entry; +import java.util.Set; + +import org.jsoup.nodes.Attributes; +import org.jsoup.nodes.Element; +import org.jsoup.select.Elements; import com.vaadin.event.LayoutEvents.LayoutClickEvent; import com.vaadin.event.LayoutEvents.LayoutClickListener; @@ -36,6 +45,8 @@ import com.vaadin.shared.ui.MarginInfo; import com.vaadin.shared.ui.gridlayout.GridLayoutServerRpc; import com.vaadin.shared.ui.gridlayout.GridLayoutState; import com.vaadin.shared.ui.gridlayout.GridLayoutState.ChildComponentData; +import com.vaadin.ui.declarative.DesignAttributeHandler; +import com.vaadin.ui.declarative.DesignContext; /** * A layout where the components are laid out on a grid using cell coordinates. @@ -1282,4 +1293,316 @@ public class GridLayout extends AbstractLayout implements public boolean isHideEmptyRowsAndColumns() { return getState(false).hideEmptyRowsAndColumns; } -} + + /** + * {@inheritDoc} + *

+ * After reading the design, cursorY is set to point to a row outside of the + * GridLayout area. CursorX is reset to 0. + */ + @Override + public void readDesign(Element design, DesignContext designContext) { + super.readDesign(design, designContext); + + // Prepare a 2D map for reading column contents + Elements rowElements = design.getElementsByTag("row"); + List> rows = new ArrayList>(); + for (int i = 0; i < rowElements.size(); ++i) { + rows.add(new HashMap()); + } + setRows(Math.max(rows.size(), 1)); + + List columnExpandRatios = new ArrayList(); + for (int row = 0; row < rowElements.size(); ++row) { + Element rowElement = rowElements.get(row); + + // Row Expand + if (rowElement.hasAttr("expand")) { + int expand = DesignAttributeHandler.readAttribute("expand", + rowElement.attributes(), int.class); + setRowExpandRatio(row, expand); + } + + Elements cols = rowElement.children(); + + // Amount of skipped columns due to spanned components + int skippedColumns = 0; + + for (int column = 0; column < cols.size(); ++column) { + while (rows.get(row).containsKey(column + skippedColumns)) { + // Skip any spanned components + skippedColumns++; + } + + Element col = cols.get(column); + Component child = null; + + if (col.children().size() > 0) { + child = designContext.readDesign(col.child(0)); + // TODO: Currently ignoring any extra children. + // Needs Error handling? + } // Else: Empty placeholder. No child component. + + // Handle rowspan and colspan for this child component + Attributes attr = col.attributes(); + int colspan = DesignAttributeHandler.readAttribute("colspan", + attr, 1, int.class); + int rowspan = DesignAttributeHandler.readAttribute("rowspan", + attr, 1, int.class); + + for (int rowIndex = row; rowIndex < row + rowspan; ++rowIndex) { + for (int colIndex = column; colIndex < column + colspan; ++colIndex) { + if (rowIndex == rows.size()) { + // Rowspan with not enough rows. Fix by adding rows. + rows.add(new HashMap()); + } + rows.get(rowIndex) + .put(colIndex + skippedColumns, child); + } + } + + // Read column expand ratios if handling the first row. + if (row == 0) { + if (col.hasAttr("expand")) { + for (String expand : col.attr("expand").split(",")) { + columnExpandRatios.add(Integer.parseInt(expand)); + } + } else { + for (int c = 0; c < colspan; ++c) { + columnExpandRatios.add(0); + } + } + } + + skippedColumns += (colspan - 1); + } + } + + // Calculate highest column count and set columns + int colMax = 0; + for (Map cols : rows) { + if (colMax < cols.size()) { + colMax = cols.size(); + } + } + setColumns(Math.max(colMax, 1)); + + for (int i = 0; i < columnExpandRatios.size(); ++i) { + setColumnExpandRatio(i, columnExpandRatios.get(i)); + } + + // Reiterate through the 2D map and add components to GridLayout + Set visited = new HashSet(); + + // Ignore any missing components + visited.add(null); + + for (int i = 0; i < rows.size(); ++i) { + Map row = rows.get(i); + for (int j = 0; j < colMax; ++j) { + Component child = row.get(j); + if (visited.contains(child)) { + // Empty location or already handled child + continue; + } + visited.add(child); + + // Figure out col and rowspan from 2D map + int colspan = 0; + while (j + colspan + 1 < row.size() + && row.get(j + colspan + 1) == child) { + ++colspan; + } + + int rowspan = 0; + while (i + rowspan + 1 < rows.size() + && rows.get(i + rowspan + 1).get(j) == child) { + ++rowspan; + } + + // Add component with area + addComponent(child, j, i, j + colspan, i + rowspan); + } + } + // Set cursor position explicitly + setCursorY(getRows()); + setCursorX(0); + } + + @Override + public void writeDesign(Element design, DesignContext designContext) { + super.writeDesign(design, designContext); + + GridLayout def = designContext.getDefaultInstance(this); + if (components.isEmpty() + || !designContext.shouldWriteChildren(this, def)) { + return; + } + + final Map childData = getState().childData; + + // Make a 2D map of component areas. + Component[][] componentMap = new Component[getState().rows][getState().columns]; + final Component dummyComponent = new Label(""); + + for (Component component : components) { + ChildComponentData coords = childData.get(component); + for (int row = coords.row1; row <= coords.row2; ++row) { + for (int col = coords.column1; col <= coords.column2; ++col) { + componentMap[row][col] = component; + } + } + } + + // Go through the map and write only needed column tags + Set visited = new HashSet(); + + // Skip the dummy placeholder + visited.add(dummyComponent); + + for (int i = 0; i < componentMap.length; ++i) { + Element row = design.appendElement("row"); + + // Row Expand + DesignAttributeHandler.writeAttribute("expand", row.attributes(), + (int) getRowExpandRatio(i), 0, int.class); + + int colspan = 1; + Element col; + for (int j = 0; j < componentMap[i].length; ++j) { + Component child = componentMap[i][j]; + if (child != null) { + if (visited.contains(child)) { + // Child has already been written in the design + continue; + } + visited.add(child); + + Element childElement = designContext.createElement(child); + col = row.appendElement("column"); + + // Write child data into design + ChildComponentData coords = childData.get(child); + + Alignment alignment = getComponentAlignment(child); + if (alignment.isMiddle()) { + childElement.attr(":middle", ""); + } else if (alignment.isBottom()) { + childElement.attr(":bottom", ""); + } + if (alignment.isCenter()) { + childElement.attr(":center", ""); + } else if (alignment.isRight()) { + childElement.attr(":right", ""); + } + + col.appendChild(childElement); + if (coords.row1 != coords.row2) { + col.attr("rowspan", "" + + (1 + coords.row2 - coords.row1)); + } + + colspan = 1 + coords.column2 - coords.column1; + if (colspan > 1) { + col.attr("colspan", "" + colspan); + } + + } else { + boolean hasExpands = false; + if (i == 0 + && lastComponentOnRow(componentMap[i], j, visited)) { + // A column with expand and no content in the end of + // first row needs to be present. + for (int c = j; c < componentMap[i].length; ++c) { + if ((int) getColumnExpandRatio(c) > 0) { + hasExpands = true; + } + } + } + + if (lastComponentOnRow(componentMap[i], j, visited) + && !hasExpands) { + continue; + } + + // Empty placeholder tag. + col = row.appendElement("column"); + + // Use colspan to make placeholders more pleasant + while (j + colspan < componentMap[i].length + && componentMap[i][j + colspan] == child) { + ++colspan; + } + + int rowspan = getRowSpan(componentMap, i, j, colspan, child); + if (colspan > 1) { + col.attr("colspan", "" + colspan); + } + if (rowspan > 1) { + col.attr("rowspan", "" + rowspan); + } + for (int x = 0; x < rowspan; ++x) { + for (int y = 0; y < colspan; ++y) { + // Mark handled columns + componentMap[i + x][j + y] = dummyComponent; + } + } + } + + // Column expands + if (i == 0) { + // Only do expands on first row + String expands = ""; + boolean expandRatios = false; + for (int c = 0; c < colspan; ++c) { + int colExpand = (int) getColumnExpandRatio(j + c); + if (colExpand > 0) { + expandRatios = true; + } + expands += (c > 0 ? "," : "") + colExpand; + } + if (expandRatios) { + col.attr("expand", expands); + } + } + + j += colspan - 1; + } + } + } + + private int getRowSpan(Component[][] compMap, int i, int j, int colspan, + Component child) { + int rowspan = 1; + while (i + rowspan < compMap.length && compMap[i + rowspan][j] == child) { + for (int k = 0; k < colspan; ++k) { + if (compMap[i + rowspan][j + k] != child) { + return rowspan; + } + } + rowspan++; + } + return rowspan; + } + + private boolean lastComponentOnRow(Component[] componentArray, int j, + Set visited) { + while ((++j) < componentArray.length) { + Component child = componentArray[j]; + if (child != null && !visited.contains(child)) { + return false; + } + } + return true; + } + + @Override + protected Collection getCustomAttributes() { + Collection result = super.getCustomAttributes(); + result.add("cursor-x"); + result.add("cursor-y"); + result.add("rows"); + result.add("columns"); + return result; + } +} \ No newline at end of file diff --git a/server/tests/src/com/vaadin/tests/design/AbstractComponentSetResponsiveTest.java b/server/tests/src/com/vaadin/tests/design/AbstractComponentSetResponsiveTest.java index f7dbd0c97e..83b3e577dc 100644 --- a/server/tests/src/com/vaadin/tests/design/AbstractComponentSetResponsiveTest.java +++ b/server/tests/src/com/vaadin/tests/design/AbstractComponentSetResponsiveTest.java @@ -17,21 +17,22 @@ package com.vaadin.tests.design; import org.junit.Test; -import com.vaadin.tests.design.DeclarativeTestBase; -import com.vaadin.ui.GridLayout; +import com.vaadin.shared.ui.label.ContentMode; +import com.vaadin.ui.Label; public class AbstractComponentSetResponsiveTest extends - DeclarativeTestBase { + DeclarativeTestBase