From: Artur Signell Date: Tue, 3 Apr 2012 15:34:02 +0000 (+0300) Subject: Updated CssLayout to use new state and hierarchy change events X-Git-Tag: 7.0.0.alpha2~136 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=6ac1b1580596b1fcac28cb6b16f1c431300fe32e;p=vaadin-framework.git Updated CssLayout to use new state and hierarchy change events --- diff --git a/src/com/vaadin/terminal/gwt/client/ui/CssLayoutConnector.java b/src/com/vaadin/terminal/gwt/client/ui/CssLayoutConnector.java index 0da7f21627..ac091f0484 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/CssLayoutConnector.java +++ b/src/com/vaadin/terminal/gwt/client/ui/CssLayoutConnector.java @@ -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 childCss = new HashMap(); + + public Map getChildCss() { + return childCss; + } + + public void setChildCss(Map 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 childToCaption = new HashMap(); + @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); + } } } diff --git a/src/com/vaadin/terminal/gwt/client/ui/VCssLayout.java b/src/com/vaadin/terminal/gwt/client/ui/VCssLayout.java index b32ea7b88d..64f7ba3240 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VCssLayout.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VCssLayout.java @@ -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 widgetToCaption = new HashMap(); - 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 oldWidgets = new HashSet(); - for (final Iterator iterator = iterator(); iterator - .hasNext();) { - oldWidgets.add(iterator.next()); - } - - ValueMap mapAttribute = null; - if (uidl.hasAttribute("css")) { - mapAttribute = uidl.getMapAttribute("css"); - } - - lastIndex = 0; - for (final Iterator 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; } /** diff --git a/src/com/vaadin/ui/CssLayout.java b/src/com/vaadin/ui/CssLayout.java index ddee26f0c0..27dc9b8306 100644 --- a/src/com/vaadin/ui/CssLayout.java +++ b/src/com/vaadin/ui/CssLayout.java @@ -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 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(); - } - 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 index 0000000000..b2712fc54c --- /dev/null +++ b/tests/testbench/com/vaadin/tests/layouts/CssLayoutCustomCss.java @@ -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 css = new HashMap(); + 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(); + + } + +}