summaryrefslogtreecommitdiffstats
path: root/server
diff options
context:
space:
mode:
Diffstat (limited to 'server')
-rw-r--r--server/src/com/vaadin/ui/AbsoluteLayout.java110
-rw-r--r--server/src/com/vaadin/ui/AbstractComponent.java4
-rw-r--r--server/src/com/vaadin/ui/AbstractOrderedLayout.java4
-rw-r--r--server/src/com/vaadin/ui/declarative/DesignAttributeHandler.java32
-rw-r--r--server/tests/src/com/vaadin/tests/server/component/absolutelayout/TestSynchronizeFromDesign.java111
-rw-r--r--server/tests/src/com/vaadin/tests/server/component/absolutelayout/TestSynchronizeToDesign.java100
6 files changed, 355 insertions, 6 deletions
diff --git a/server/src/com/vaadin/ui/AbsoluteLayout.java b/server/src/com/vaadin/ui/AbsoluteLayout.java
index afc73f5ecc..c4c0de764f 100644
--- a/server/src/com/vaadin/ui/AbsoluteLayout.java
+++ b/server/src/com/vaadin/ui/AbsoluteLayout.java
@@ -21,6 +21,10 @@ import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;
+import org.jsoup.nodes.Attributes;
+import org.jsoup.nodes.Element;
+import org.jsoup.nodes.Node;
+
import com.vaadin.event.LayoutEvents.LayoutClickEvent;
import com.vaadin.event.LayoutEvents.LayoutClickListener;
import com.vaadin.event.LayoutEvents.LayoutClickNotifier;
@@ -30,6 +34,8 @@ import com.vaadin.shared.EventId;
import com.vaadin.shared.MouseEventDetails;
import com.vaadin.shared.ui.absolutelayout.AbsoluteLayoutServerRpc;
import com.vaadin.shared.ui.absolutelayout.AbsoluteLayoutState;
+import com.vaadin.ui.declarative.DesignAttributeHandler;
+import com.vaadin.ui.declarative.DesignContext;
/**
* AbsoluteLayout is a layout implementation that mimics html absolute
@@ -40,6 +46,13 @@ import com.vaadin.shared.ui.absolutelayout.AbsoluteLayoutState;
public class AbsoluteLayout extends AbstractLayout implements
LayoutClickNotifier {
+ // constants for design attributes
+ private static final String ATTR_TOP = ":top";
+ private static final String ATTR_RIGHT = ":right";
+ private static final String ATTR_BOTTOM = ":bottom";
+ private static final String ATTR_LEFT = ":left";
+ private static final String ATTR_Z_INDEX = ":z-index";
+
private AbsoluteLayoutServerRpc rpc = new AbsoluteLayoutServerRpc() {
@Override
@@ -660,4 +673,101 @@ public class AbsoluteLayout extends AbstractLayout implements
public void removeListener(LayoutClickListener listener) {
removeLayoutClickListener(listener);
}
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * com.vaadin.ui.AbstractComponent#synchronizeFromDesign(org.jsoup.nodes
+ * .Node, com.vaadin.ui.declarative.DesignContext)
+ */
+ @Override
+ public void synchronizeFromDesign(Element design,
+ DesignContext designContext) {
+ // process default attributes
+ super.synchronizeFromDesign(design, designContext);
+ // remove current children
+ removeAllComponents();
+ // handle children
+ for (Element childComponent : design.children()) {
+ Attributes attr = childComponent.attributes();
+ DesignSynchronizable newChild = designContext
+ .createChild(childComponent);
+ StringBuilder css = new StringBuilder();
+ if (attr.hasKey(ATTR_TOP)) {
+ css.append("top:").append(attr.get(ATTR_TOP)).append(";");
+ }
+ if (attr.hasKey(ATTR_RIGHT)) {
+ css.append("right:").append(attr.get(ATTR_RIGHT)).append(";");
+ }
+ if (attr.hasKey(ATTR_BOTTOM)) {
+ css.append("bottom:").append(attr.get(ATTR_BOTTOM)).append(";");
+ }
+ if (attr.hasKey(ATTR_LEFT)) {
+ css.append("left:").append(attr.get(ATTR_LEFT)).append(";");
+ }
+ if (attr.hasKey(ATTR_Z_INDEX)) {
+ css.append("z-index:").append(attr.get(ATTR_Z_INDEX))
+ .append(";");
+ }
+ addComponent(newChild, css.toString());
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * com.vaadin.ui.AbstractComponent#synchronizeToDesign(org.jsoup.nodes.Node,
+ * com.vaadin.ui.declarative.DesignContext)
+ */
+ @Override
+ public void synchronizeToDesign(Element design, DesignContext designContext) {
+ super.synchronizeToDesign(design, designContext);
+ // handle children
+ Element designElement = design;
+ for (Component child : this) {
+ DesignSynchronizable childComponent = (DesignSynchronizable) child;
+ Element childNode = designContext.createNode(childComponent);
+ designElement.appendChild(childNode);
+ childComponent.synchronizeToDesign(childNode, designContext);
+ // handle position
+ ComponentPosition position = getPosition(child);
+ writePositionAttribute(childNode, ATTR_TOP, position.getTopUnits()
+ .getSymbol(), position.getTopValue());
+ writePositionAttribute(childNode, ATTR_RIGHT, position
+ .getRightUnits().getSymbol(), position.getRightValue());
+ writePositionAttribute(childNode, ATTR_BOTTOM, position
+ .getBottomUnits().getSymbol(), position.getBottomValue());
+ writePositionAttribute(childNode, ATTR_LEFT, position
+ .getLeftUnits().getSymbol(), position.getLeftValue());
+ // handle z-index
+ if (position.getZIndex() >= 0) {
+ childNode.attr(ATTR_Z_INDEX, String.valueOf(position.zIndex));
+ }
+ }
+ }
+
+ /**
+ * Private method for writing position attributes
+ *
+ * @since
+ * @param node
+ * target node
+ * @param key
+ * attribute key
+ * @param symbol
+ * value symbol
+ * @param value
+ * the value
+ */
+ private void writePositionAttribute(Node node, String key, String symbol,
+ Float value) {
+ if (value != null) {
+ String valueString = DesignAttributeHandler.formatFloat(value
+ .floatValue());
+ node.attr(key, valueString + symbol);
+ }
+ }
+
}
diff --git a/server/src/com/vaadin/ui/AbstractComponent.java b/server/src/com/vaadin/ui/AbstractComponent.java
index b5721a0bba..8ee3f722ab 100644
--- a/server/src/com/vaadin/ui/AbstractComponent.java
+++ b/server/src/com/vaadin/ui/AbstractComponent.java
@@ -1029,7 +1029,7 @@ public abstract class AbstractComponent extends AbstractClientConnector
attributes.put("width-auto", "true");
} else {
String widthString = DesignAttributeHandler
- .formatDesignAttribute(getWidth())
+ .formatFloat(getWidth())
+ getWidthUnits().getSymbol();
attributes.put("width", widthString);
@@ -1043,7 +1043,7 @@ public abstract class AbstractComponent extends AbstractClientConnector
attributes.put("height-auto", "true");
} else {
String heightString = DesignAttributeHandler
- .formatDesignAttribute(getHeight())
+ .formatFloat(getHeight())
+ getHeightUnits().getSymbol();
attributes.put("height", heightString);
}
diff --git a/server/src/com/vaadin/ui/AbstractOrderedLayout.java b/server/src/com/vaadin/ui/AbstractOrderedLayout.java
index bbaaffe789..139a4eb545 100644
--- a/server/src/com/vaadin/ui/AbstractOrderedLayout.java
+++ b/server/src/com/vaadin/ui/AbstractOrderedLayout.java
@@ -559,8 +559,8 @@ public abstract class AbstractOrderedLayout extends AbstractLayout implements
if (expandRatio == 1.0f) {
childNode.attr(":expand", "");
} else if (expandRatio > 0) {
- childNode.attr(":expand", DesignAttributeHandler
- .formatDesignAttribute(expandRatio));
+ childNode.attr(":expand",
+ DesignAttributeHandler.formatFloat(expandRatio));
}
}
}
diff --git a/server/src/com/vaadin/ui/declarative/DesignAttributeHandler.java b/server/src/com/vaadin/ui/declarative/DesignAttributeHandler.java
index 423b2fb60b..daebb1c09a 100644
--- a/server/src/com/vaadin/ui/declarative/DesignAttributeHandler.java
+++ b/server/src/com/vaadin/ui/declarative/DesignAttributeHandler.java
@@ -244,12 +244,35 @@ public class DesignAttributeHandler {
* the number to be formatted
* @return the formatted number
*/
- public static String formatDesignAttribute(float number) {
+ public static String formatFloat(float number) {
+ return getDecimalFormat().format(number);
+ }
+
+ /**
+ * Formats the given design attribute value. The method is provided to
+ * ensure consistent number formatting for design attribute values
+ *
+ * @since 7.4
+ * @param number
+ * the number to be formatted
+ * @return the formatted number
+ */
+ public static String formatDouble(double number) {
+ return getDecimalFormat().format(number);
+ }
+
+ /**
+ * Creates the decimal format used when writing attributes to the design
+ *
+ * @since 7.4
+ * @return the decimal format
+ */
+ private static DecimalFormat getDecimalFormat() {
DecimalFormatSymbols symbols = new DecimalFormatSymbols(new Locale(
"en_US"));
DecimalFormat fmt = new DecimalFormat("0.###", symbols);
fmt.setGroupingUsed(false);
- return fmt.format(number);
+ return fmt;
}
/**
@@ -359,8 +382,13 @@ public class DesignAttributeHandler {
"Unknown resource type " + value.getClass().getName());
return null;
}
+ } else if (sourceType == Float.class || sourceType == Float.TYPE) {
+ return formatFloat(((Float) value).floatValue());
+ } else if (sourceType == Double.class || sourceType == Double.TYPE) {
+ return formatDouble(((Double) value).doubleValue());
} else {
return value.toString();
+
}
}
diff --git a/server/tests/src/com/vaadin/tests/server/component/absolutelayout/TestSynchronizeFromDesign.java b/server/tests/src/com/vaadin/tests/server/component/absolutelayout/TestSynchronizeFromDesign.java
new file mode 100644
index 0000000000..95dc0ad996
--- /dev/null
+++ b/server/tests/src/com/vaadin/tests/server/component/absolutelayout/TestSynchronizeFromDesign.java
@@ -0,0 +1,111 @@
+/*
+ * 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.absolutelayout;
+
+import java.util.Iterator;
+
+import junit.framework.TestCase;
+
+import org.jsoup.nodes.Attributes;
+import org.jsoup.nodes.Element;
+import org.jsoup.parser.Tag;
+
+import com.vaadin.server.Sizeable;
+import com.vaadin.ui.AbsoluteLayout;
+import com.vaadin.ui.AbsoluteLayout.ComponentPosition;
+import com.vaadin.ui.Component;
+import com.vaadin.ui.DesignSynchronizable;
+import com.vaadin.ui.declarative.DesignContext;
+
+/**
+ * Test case for reading AbsoluteLayout from design
+ *
+ * @since
+ * @author Vaadin Ltd
+ */
+public class TestSynchronizeFromDesign extends TestCase {
+
+ private AbsoluteLayout root;
+
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+ root = createLayout();
+ }
+
+ public void testAttributes() {
+ assertEquals("test-layout", root.getCaption());
+ Iterator<Component> children = root.iterator();
+ assertEquals("test-label", children.next().getCaption());
+ assertEquals("test-button", children.next().getCaption());
+ }
+
+ public void testTopLeftPosition() {
+ ComponentPosition position = root.getPosition(root.iterator().next());
+ assertEquals(Sizeable.Unit.PIXELS, position.getTopUnits());
+ assertEquals(100.0f, position.getTopValue());
+ assertEquals(Sizeable.Unit.PERCENTAGE, position.getLeftUnits());
+ assertEquals(50.0f, position.getLeftValue());
+ }
+
+ public void testBottomRightPosition() {
+ Iterator<Component> children = root.iterator();
+ children.next();
+ ComponentPosition position = root.getPosition(children.next());
+ assertEquals(Sizeable.Unit.PIXELS, position.getBottomUnits());
+ assertEquals(100.0f, position.getBottomValue());
+ assertEquals(Sizeable.Unit.PERCENTAGE, position.getRightUnits());
+ assertEquals(50.0f, position.getRightValue());
+ }
+
+ public void testZIndex() {
+ ComponentPosition position = root.getPosition(root.iterator().next());
+ assertEquals(2, position.getZIndex());
+ }
+
+ private AbsoluteLayout createLayout() {
+ DesignContext ctx = new DesignContext();
+ Element design = createDesign();
+ DesignSynchronizable child = ctx.createChild(design);
+ return (AbsoluteLayout) child;
+ }
+
+ private Element createDesign() {
+
+ Attributes rootAttributes = new Attributes();
+ rootAttributes.put("caption", "test-layout");
+ Element node = new Element(Tag.valueOf("v-absolute-layout"), "",
+ rootAttributes);
+
+ Attributes firstChildAttributes = new Attributes();
+ firstChildAttributes.put("caption", "test-label");
+ firstChildAttributes.put(":top", "100px");
+ firstChildAttributes.put(":left", "50%");
+ firstChildAttributes.put(":z-index", "2");
+ Element firstChild = new Element(Tag.valueOf("v-label"), "",
+ firstChildAttributes);
+ node.appendChild(firstChild);
+
+ Attributes secondChildAttributes = new Attributes();
+ secondChildAttributes.put("caption", "test-button");
+ secondChildAttributes.put(":bottom", "100px");
+ secondChildAttributes.put(":right", "50%");
+ Element secondChild = new Element(Tag.valueOf("v-button"), "",
+ secondChildAttributes);
+ node.appendChild(secondChild);
+ return node;
+ }
+}
diff --git a/server/tests/src/com/vaadin/tests/server/component/absolutelayout/TestSynchronizeToDesign.java b/server/tests/src/com/vaadin/tests/server/component/absolutelayout/TestSynchronizeToDesign.java
new file mode 100644
index 0000000000..eb61d13684
--- /dev/null
+++ b/server/tests/src/com/vaadin/tests/server/component/absolutelayout/TestSynchronizeToDesign.java
@@ -0,0 +1,100 @@
+/*
+ * 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.absolutelayout;
+
+import junit.framework.TestCase;
+
+import org.jsoup.nodes.Attributes;
+import org.jsoup.nodes.Element;
+import org.jsoup.parser.Tag;
+
+import com.vaadin.ui.AbsoluteLayout;
+import com.vaadin.ui.Label;
+import com.vaadin.ui.declarative.DesignContext;
+
+/**
+ * Test case for writing AbsoluteLayout to design
+ *
+ * @since
+ * @author Vaadin Ltd
+ */
+public class TestSynchronizeToDesign extends TestCase {
+
+ public void testSynchronizeEmptyLayout() {
+ AbsoluteLayout layout = createTestLayout();
+ layout.removeAllComponents();
+ Element design = createDesign();
+ layout.synchronizeToDesign(design, createDesignContext());
+ assertEquals(0, design.childNodes().size());
+ assertEquals("changed-caption", design.attr("caption"));
+ }
+
+ public void testSynchronizeLayoutWithChildren() {
+ AbsoluteLayout layout = createTestLayout();
+ Element design = createDesign();
+ layout.synchronizeToDesign(design, createDesignContext());
+ assertEquals(2, design.childNodes().size());
+ assertEquals("v-label", ((Element) design.childNode(0)).tagName());
+ assertEquals("v-label", ((Element) design.childNode(1)).tagName());
+ }
+
+ public void testSynchronizePosition() {
+ AbsoluteLayout layout = createTestLayout();
+ Element design = createDesign();
+ layout.synchronizeToDesign(design, createDesignContext());
+ Attributes attributes = design.childNode(0).attributes();
+ assertEquals("50px", attributes.get(":top"));
+ assertEquals("50%", attributes.get(":left"));
+ assertEquals("2", attributes.get(":z-index"));
+ attributes = design.childNode(1).attributes();
+ assertEquals("50px", attributes.get(":bottom"));
+ assertEquals("50%", attributes.get(":right"));
+ }
+
+ private AbsoluteLayout createTestLayout() {
+ AbsoluteLayout layout = new AbsoluteLayout();
+ layout.setCaption("changed-caption");
+ layout.addComponent(new Label("test-label"),
+ "top:50px;left:50%;z-index:2");
+ layout.addComponent(new Label("test-label-2"),
+ "bottom:50px;right:50%;z-index:3");
+ return layout;
+ }
+
+ private Element createDesign() {
+ // make sure that the design node has old content that should be removed
+ Attributes rootAttributes = new Attributes();
+ rootAttributes.put("caption", "test-layout");
+ Element node = new Element(Tag.valueOf("v-absolute-layout"), "",
+ rootAttributes);
+ Attributes firstChildAttributes = new Attributes();
+ firstChildAttributes.put("caption", "test-label");
+ Element firstChild = new Element(Tag.valueOf("v-label"), "",
+ firstChildAttributes);
+ node.appendChild(firstChild);
+
+ Attributes secondChildAttributes = new Attributes();
+ secondChildAttributes.put("caption", "test-button");
+ Element secondChild = new Element(Tag.valueOf("v-button"), "",
+ secondChildAttributes);
+ node.appendChild(secondChild);
+ return node;
+ }
+
+ private DesignContext createDesignContext() {
+ return new DesignContext();
+ }
+}