]> source.dussan.org Git - vaadin-framework.git/commitdiff
Updated CssLayout to use new state and hierarchy change events
authorArtur Signell <artur@vaadin.com>
Tue, 3 Apr 2012 15:34:02 +0000 (18:34 +0300)
committerArtur Signell <artur@vaadin.com>
Wed, 4 Apr 2012 21:09:13 +0000 (00:09 +0300)
src/com/vaadin/terminal/gwt/client/ui/CssLayoutConnector.java
src/com/vaadin/terminal/gwt/client/ui/VCssLayout.java
src/com/vaadin/ui/CssLayout.java
tests/testbench/com/vaadin/tests/layouts/CssLayoutCustomCss.java [new file with mode: 0644]

index 0da7f21627c35644ed331e04806aa125265cf371..ac091f04845a2dccfc48e3457049335985bd6c5e 100644 (file)
@@ -3,27 +3,52 @@
  */
 package com.vaadin.terminal.gwt.client.ui;
 
+import java.util.HashMap;
+import java.util.Map;
+
 import com.google.gwt.core.client.GWT;
+import com.google.gwt.dom.client.Style;
 import com.google.gwt.user.client.Element;
 import com.google.gwt.user.client.ui.Widget;
 import com.vaadin.terminal.gwt.client.ApplicationConnection;
+import com.vaadin.terminal.gwt.client.BrowserInfo;
 import com.vaadin.terminal.gwt.client.ComponentConnector;
+import com.vaadin.terminal.gwt.client.ComponentState;
+import com.vaadin.terminal.gwt.client.ConnectorHierarchyChangeEvent;
 import com.vaadin.terminal.gwt.client.Paintable;
 import com.vaadin.terminal.gwt.client.UIDL;
+import com.vaadin.terminal.gwt.client.Util;
+import com.vaadin.terminal.gwt.client.VCaption;
 import com.vaadin.terminal.gwt.client.communication.RpcProxy;
 import com.vaadin.terminal.gwt.client.communication.ServerRpc;
+import com.vaadin.terminal.gwt.client.communication.StateChangeEvent;
+import com.vaadin.terminal.gwt.client.ui.VCssLayout.FlowPane;
 import com.vaadin.ui.CssLayout;
 
 @Component(CssLayout.class)
 public class CssLayoutConnector extends AbstractComponentContainerConnector
         implements Paintable {
 
+    public static class CssLayoutState extends ComponentState {
+        private Map<String, String> childCss = new HashMap<String, String>();
+
+        public Map<String, String> getChildCss() {
+            return childCss;
+        }
+
+        public void setChildCss(Map<String, String> childCss) {
+            this.childCss = childCss;
+        }
+
+    }
+
     private LayoutClickEventHandler clickEventHandler = new LayoutClickEventHandler(
             this) {
 
         @Override
         protected ComponentConnector getChildComponent(Element element) {
-            return getWidget().panel.getComponent(element);
+            return Util.getConnectorForElement(getConnection(), getWidget(),
+                    element);
         }
 
         @Override
@@ -38,23 +63,101 @@ public class CssLayoutConnector extends AbstractComponentContainerConnector
 
     private CssLayoutServerRPC rpc;
 
+    private Map<ComponentConnector, VCaption> childToCaption = new HashMap<ComponentConnector, VCaption>();
+
     @Override
     protected void init() {
         super.init();
         rpc = RpcProxy.create(CssLayoutServerRPC.class, this);
     }
 
+    @Override
+    public CssLayoutState getState() {
+        return (CssLayoutState) super.getState();
+    }
+
+    @Override
+    public void onStateChanged(StateChangeEvent stateChangeEvent) {
+        super.onStateChanged(stateChangeEvent);
+
+        for (ComponentConnector child : getChildren()) {
+            if (!getState().getChildCss().containsKey(child.getConnectorId())) {
+                continue;
+            }
+            String css = getState().getChildCss().get(child.getConnectorId());
+            Style style = child.getWidget().getElement().getStyle();
+            // should we remove styles also? How can we know what we have added
+            // as it is added directly to the child component?
+            String[] cssRules = css.split(";");
+            for (String cssRule : cssRules) {
+                String parts[] = cssRule.split(":");
+                if (parts.length == 2) {
+                    style.setProperty(makeCamelCase(parts[0].trim()),
+                            parts[1].trim());
+                }
+            }
+        }
+
+    }
+
+    @Override
+    public void onConnectorHierarchyChange(ConnectorHierarchyChangeEvent event) {
+        super.onConnectorHierarchyChange(event);
+
+        clickEventHandler.handleEventHandlerRegistration();
+
+        int index = 0;
+        FlowPane cssLayoutWidgetContainer = getWidget().panel;
+        for (ComponentConnector child : getChildren()) {
+            VCaption childCaption = childToCaption.get(child);
+            if (childCaption != null) {
+                cssLayoutWidgetContainer.addOrMove(childCaption, index++);
+            }
+            cssLayoutWidgetContainer.addOrMove(child.getWidget(), index++);
+        }
+
+        // Detach old child widgets and possibly their caption
+        for (ComponentConnector child : event.getOldChildren()) {
+            if (child.getParent() == this) {
+                // Skip current children
+                continue;
+            }
+            cssLayoutWidgetContainer.remove(child.getWidget());
+            VCaption vCaption = childToCaption.remove(child);
+            if (vCaption != null) {
+                cssLayoutWidgetContainer.remove(vCaption);
+            }
+        }
+    }
+
     public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
 
         if (!isRealUpdate(uidl)) {
             return;
         }
-        clickEventHandler.handleEventHandlerRegistration();
 
         getWidget().setMarginAndSpacingStyles(
                 new VMarginInfo(uidl.getIntAttribute("margins")),
                 uidl.hasAttribute("spacing"));
-        getWidget().panel.updateFromUIDL(uidl, client);
+
+    }
+
+    private static final String makeCamelCase(String cssProperty) {
+        // TODO this might be cleaner to implement with regexp
+        while (cssProperty.contains("-")) {
+            int indexOf = cssProperty.indexOf("-");
+            cssProperty = cssProperty.substring(0, indexOf)
+                    + String.valueOf(cssProperty.charAt(indexOf + 1))
+                            .toUpperCase() + cssProperty.substring(indexOf + 2);
+        }
+        if ("float".equals(cssProperty)) {
+            if (BrowserInfo.get().isIE()) {
+                return "styleFloat";
+            } else {
+                return "cssFloat";
+            }
+        }
+        return cssProperty;
     }
 
     @Override
@@ -67,8 +170,27 @@ public class CssLayoutConnector extends AbstractComponentContainerConnector
         return GWT.create(VCssLayout.class);
     }
 
-    public void updateCaption(ComponentConnector component) {
-        getWidget().panel.updateCaption(component);
+    public void updateCaption(ComponentConnector child) {
+        Widget childWidget = child.getWidget();
+        FlowPane cssLayoutWidgetContainer = getWidget().panel;
+        int widgetPosition = cssLayoutWidgetContainer
+                .getWidgetIndex(childWidget);
+
+        VCaption caption = childToCaption.get(child);
+        if (VCaption.isNeeded(child.getState())) {
+            if (caption == null) {
+                caption = new VCaption(child, getConnection());
+                childToCaption.put(child, caption);
+            }
+            if (!caption.isAttached()) {
+                // Insert caption at widget index == before widget
+                cssLayoutWidgetContainer.insert(caption, widgetPosition);
+            }
+            caption.updateCaption();
+        } else if (caption != null) {
+            childToCaption.remove(child);
+            cssLayoutWidgetContainer.remove(caption);
+        }
     }
 
 }
index b32ea7b88d4f201e793b54abd05de6553770066a..64f7ba3240fef828d3544a455ac3dcc4aad4141f 100644 (file)
@@ -4,27 +4,12 @@
 
 package com.vaadin.terminal.gwt.client.ui;
 
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-
-import com.google.gwt.dom.client.Style;
 import com.google.gwt.user.client.DOM;
 import com.google.gwt.user.client.Element;
 import com.google.gwt.user.client.ui.FlowPanel;
 import com.google.gwt.user.client.ui.SimplePanel;
 import com.google.gwt.user.client.ui.Widget;
-import com.vaadin.terminal.gwt.client.ApplicationConnection;
-import com.vaadin.terminal.gwt.client.BrowserInfo;
-import com.vaadin.terminal.gwt.client.ComponentConnector;
-import com.vaadin.terminal.gwt.client.ConnectorMap;
 import com.vaadin.terminal.gwt.client.StyleConstants;
-import com.vaadin.terminal.gwt.client.UIDL;
-import com.vaadin.terminal.gwt.client.Util;
-import com.vaadin.terminal.gwt.client.VCaption;
-import com.vaadin.terminal.gwt.client.VConsole;
-import com.vaadin.terminal.gwt.client.ValueMap;
 
 public class VCssLayout extends SimplePanel {
     public static final String TAGNAME = "csslayout";
@@ -49,89 +34,12 @@ public class VCssLayout extends SimplePanel {
 
     public class FlowPane extends FlowPanel {
 
-        private final HashMap<Widget, VCaption> widgetToCaption = new HashMap<Widget, VCaption>();
-        private ApplicationConnection client;
-        private int lastIndex;
-
         public FlowPane() {
             super();
             setStyleName(CLASSNAME + "-container");
         }
 
-        public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
-
-            // for later requests
-            this.client = client;
-
-            final Collection<Widget> oldWidgets = new HashSet<Widget>();
-            for (final Iterator<Widget> iterator = iterator(); iterator
-                    .hasNext();) {
-                oldWidgets.add(iterator.next());
-            }
-
-            ValueMap mapAttribute = null;
-            if (uidl.hasAttribute("css")) {
-                mapAttribute = uidl.getMapAttribute("css");
-            }
-
-            lastIndex = 0;
-            for (final Iterator<Object> i = uidl.getChildIterator(); i
-                    .hasNext();) {
-                final UIDL r = (UIDL) i.next();
-                final ComponentConnector child = client.getPaintable(r);
-                final Widget widget = child.getWidget();
-                if (widget.getParent() == this) {
-                    oldWidgets.remove(widget);
-                    VCaption vCaption = widgetToCaption.get(widget);
-                    if (vCaption != null) {
-                        addOrMove(vCaption, lastIndex++);
-                        oldWidgets.remove(vCaption);
-                    }
-                }
-
-                addOrMove(widget, lastIndex++);
-                if (mapAttribute != null && mapAttribute.containsKey(r.getId())) {
-                    String css = null;
-                    try {
-                        Style style = widget.getElement().getStyle();
-                        css = mapAttribute.getString(r.getId());
-                        String[] cssRules = css.split(";");
-                        for (int j = 0; j < cssRules.length; j++) {
-                            String[] rule = cssRules[j].split(":");
-                            if (rule.length == 0) {
-                                continue;
-                            } else {
-                                style.setProperty(
-                                        makeCamelCase(rule[0].trim()),
-                                        rule[1].trim());
-                            }
-                        }
-                    } catch (Exception e) {
-                        VConsole.log("CssLayout encounterd invalid css string: "
-                                + css);
-                    }
-                }
-
-            }
-
-            // loop oldWidgetWrappers that where not re-attached and unregister
-            // them
-            for (Widget w : oldWidgets) {
-                remove(w);
-                ConnectorMap paintableMap = ConnectorMap.get(client);
-                if (paintableMap.isConnector(w)) {
-                    final ComponentConnector p = ConnectorMap.get(client)
-                            .getConnector(w);
-                    client.unregisterPaintable(p);
-                }
-                VCaption vCaption = widgetToCaption.remove(w);
-                if (vCaption != null) {
-                    remove(vCaption);
-                }
-            }
-        }
-
-        private void addOrMove(Widget child, int index) {
+        void addOrMove(Widget child, int index) {
             if (child.getParent() == this) {
                 int currentIndex = getWidgetIndex(child);
                 if (index == currentIndex) {
@@ -141,49 +49,6 @@ public class VCssLayout extends SimplePanel {
             insert(child, index);
         }
 
-        public void updateCaption(ComponentConnector paintable) {
-            Widget widget = paintable.getWidget();
-            VCaption caption = widgetToCaption.get(widget);
-            if (VCaption.isNeeded(paintable.getState())) {
-                if (caption == null) {
-                    caption = new VCaption(paintable, client);
-                    widgetToCaption.put(widget, caption);
-                    insert(caption, getWidgetIndex(widget));
-                    lastIndex++;
-                } else if (!caption.isAttached()) {
-                    insert(caption, getWidgetIndex(widget));
-                    lastIndex++;
-                }
-                caption.updateCaption();
-            } else if (caption != null) {
-                remove(caption);
-                widgetToCaption.remove(widget);
-            }
-        }
-
-        ComponentConnector getComponent(Element element) {
-            return Util
-                    .getConnectorForElement(client, VCssLayout.this, element);
-        }
-
-    }
-
-    private static final String makeCamelCase(String cssProperty) {
-        // TODO this might be cleaner to implement with regexp
-        while (cssProperty.contains("-")) {
-            int indexOf = cssProperty.indexOf("-");
-            cssProperty = cssProperty.substring(0, indexOf)
-                    + String.valueOf(cssProperty.charAt(indexOf + 1))
-                            .toUpperCase() + cssProperty.substring(indexOf + 2);
-        }
-        if ("float".equals(cssProperty)) {
-            if (BrowserInfo.get().isIE()) {
-                return "styleFloat";
-            } else {
-                return "cssFloat";
-            }
-        }
-        return cssProperty;
     }
 
     /**
index ddee26f0c020d9333e05ca75cd70a504f0c11df8..27dc9b830669bbc385c6e26120638ee67a8686fe 100644 (file)
@@ -3,20 +3,17 @@
  */
 package com.vaadin.ui;
 
-import java.util.HashMap;
 import java.util.Iterator;
 import java.util.LinkedList;
 
 import com.vaadin.event.LayoutEvents.LayoutClickEvent;
 import com.vaadin.event.LayoutEvents.LayoutClickListener;
 import com.vaadin.event.LayoutEvents.LayoutClickNotifier;
-import com.vaadin.terminal.PaintException;
-import com.vaadin.terminal.PaintTarget;
-import com.vaadin.terminal.Paintable;
 import com.vaadin.terminal.gwt.client.Connector;
 import com.vaadin.terminal.gwt.client.MouseEventDetails;
 import com.vaadin.terminal.gwt.client.ui.CssLayoutConnector;
 import com.vaadin.terminal.gwt.client.ui.CssLayoutConnector.CssLayoutServerRPC;
+import com.vaadin.terminal.gwt.client.ui.CssLayoutConnector.CssLayoutState;
 import com.vaadin.terminal.gwt.client.ui.LayoutClickEventHandler;
 
 /**
@@ -185,33 +182,23 @@ public class CssLayout extends AbstractLayout implements LayoutClickNotifier {
         return components.size();
     }
 
-    /**
-     * Paints the content of this component.
-     * 
-     * @param target
-     *            the Paint Event.
-     * @throws PaintException
-     *             if the paint operation failed.
-     */
     @Override
-    public void paintContent(PaintTarget target) throws PaintException {
-        super.paintContent(target);
-        HashMap<Paintable, String> componentCss = null;
-        // Adds all items in all the locations
-        for (Component c : components) {
-            // Paint child component UIDL
-            c.paint(target);
-            String componentCssString = getCss(c);
+    public void updateState() {
+        super.updateState();
+        getState().getChildCss().clear();
+        for (Component child : this) {
+            String componentCssString = getCss(child);
             if (componentCssString != null) {
-                if (componentCss == null) {
-                    componentCss = new HashMap<Paintable, String>();
-                }
-                componentCss.put(c, componentCssString);
+                getState().getChildCss().put(child.getConnectorId(),
+                        componentCssString);
             }
+
         }
-        if (componentCss != null) {
-            target.addAttribute("css", componentCss);
-        }
+    }
+
+    @Override
+    public CssLayoutState getState() {
+        return (CssLayoutState) super.getState();
     }
 
     /**
diff --git a/tests/testbench/com/vaadin/tests/layouts/CssLayoutCustomCss.java b/tests/testbench/com/vaadin/tests/layouts/CssLayoutCustomCss.java
new file mode 100644 (file)
index 0000000..b2712fc
--- /dev/null
@@ -0,0 +1,68 @@
+package com.vaadin.tests.layouts;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import com.vaadin.tests.components.TestBase;
+import com.vaadin.ui.Button;
+import com.vaadin.ui.Button.ClickEvent;
+import com.vaadin.ui.Button.ClickListener;
+import com.vaadin.ui.Component;
+import com.vaadin.ui.CssLayout;
+import com.vaadin.ui.NativeButton;
+
+public class CssLayoutCustomCss extends TestBase implements ClickListener {
+
+    protected Map<Component, String> css = new HashMap<Component, String>();
+    private CssLayout layout;
+
+    @Override
+    protected void setup() {
+        setTheme("tests-tickets");
+        layout = new CssLayout() {
+            @Override
+            protected String getCss(com.vaadin.ui.Component c) {
+                return css.get(c);
+            }
+        };
+        layout.setSizeFull();
+        addComponent(layout);
+
+        layout.addComponent(createButton("color:red"));
+        layout.addComponent(createButton("color: blue"));
+        layout.addComponent(createButton("color: green"));
+    }
+
+    private Component createButton(String string) {
+        NativeButton button = new NativeButton(string);
+        css.put(button, string);
+        button.addListener(this);
+        return button;
+    }
+
+    @Override
+    protected String getDescription() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    protected Integer getTicketNumber() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    public void buttonClick(ClickEvent event) {
+        Button b = event.getButton();
+        if (b.getCaption().contains("not ")) {
+            b.setCaption(b.getCaption().substring(4));
+            css.put(b, b.getCaption());
+        } else {
+            css.remove(b);
+            b.setCaption("not " + b.getCaption());
+        }
+        layout.requestRepaint();
+
+    }
+
+}