]> source.dussan.org Git - vaadin-framework.git/commitdiff
Extensive refactoring of BoxLayout
authorJouni Koivuviita <jouni@jounikoivuviita.com>
Sun, 20 May 2012 19:13:31 +0000 (22:13 +0300)
committerJouni Koivuviita <jouni@jounikoivuviita.com>
Sun, 20 May 2012 19:13:31 +0000 (22:13 +0300)
Reduced many unnecessary element resize listeners and layout methods.

Refactored ComponentConnector style name handling so that it will now
only alter the style names and not completely override them on each
update.

12 files changed:
WebContent/VAADIN/themes/base/absolutelayout/absolutelayout.css
WebContent/VAADIN/themes/base/boxlayout/boxlayout.css
WebContent/VAADIN/themes/base/label/label.css
src/com/vaadin/terminal/gwt/client/ComponentState.java
src/com/vaadin/terminal/gwt/client/LayoutManager.java
src/com/vaadin/terminal/gwt/client/ui/AbstractBoxLayoutConnector.java
src/com/vaadin/terminal/gwt/client/ui/AbstractComponentConnector.java
src/com/vaadin/terminal/gwt/client/ui/HorizontalBoxLayoutConnector.java
src/com/vaadin/terminal/gwt/client/ui/VBoxLayout.java
src/com/vaadin/terminal/gwt/client/ui/VerticalBoxLayoutConnector.java
tests/testbench/com/vaadin/tests/components/orderedlayout/BoxLayoutTest.java
tests/testbench/com/vaadin/tests/components/orderedlayout/LayoutResizeTest.java

index 637d829d786dd8afb677bb8596b06675857582d9..0eb557560ef95c36a93634977794cefd3798344f 100644 (file)
@@ -1,5 +1,6 @@
 /* THIS IS HERE ONLY BECAUSE WE WANT TO DEFINE IT FIRST, TO MAKE IT EASY TO OVERRIDE */
-.v-connector {
+/* TODO fix by using a better build script that allows us to define the order of the imports */
+.v {
        -webkit-box-sizing: border-box;
        -moz-box-sizing: border-box;
        box-sizing: border-box;
index 3188d68520880b67dfe93faed43e1e30a2d7c9ae..f899e8f4ac34b39499ea374806f9a18fb6e64c64 100644 (file)
@@ -20,8 +20,8 @@ TODO
        display: inline-block;
 }
 
-.v-boxlayout.v-horizontal {
-       white-space: nowrap !important;
+div.v-boxlayout.v-horizontal.v {
+       white-space: nowrap;
 }
 
 .v-boxlayout > .v-expand {
@@ -40,7 +40,7 @@ TODO
 }
 
 /* Clear any floats inside the slot, to prevent unwanted collapsing */
-.v-slot:after {
+.v-vertical > .v-slot:after {
        content: "";
        display: inline-block;
        clear: both;
@@ -88,16 +88,18 @@ TODO
        white-space: nowrap;
 }
 
-.v-align-middle > .v-connector,
-.v-align-bottom > .v-connector {
+.v-align-middle > .v,
+.v-align-bottom > .v {
        display: inline-block;
 }
 
-.v-align-middle > .v-connector {
+.v-align-middle,
+.v-align-middle > .v {
        vertical-align: middle;
 }
 
-.v-align-bottom > .v-connector {
+.v-align-bottom,
+.v-align-bottom > .v {
        vertical-align: bottom;
 }
 
@@ -105,7 +107,7 @@ TODO
        text-align: center;
 }
 
-.v-align-center > .v-connector {
+.v-align-center > .v {
        margin-left: auto;
        margin-right: auto;
 }
@@ -114,7 +116,7 @@ TODO
        text-align: right;
 }
 
-.v-align-right > .v-connector {
+.v-align-right > .v {
        margin-left: auto;
 }
 
@@ -146,17 +148,17 @@ TODO
        padding-left: .5em;
 }
 
-.v-caption-on-left > .v-connector,
-.v-caption-on-right > .v-connector {
+.v-caption-on-left > .v,
+.v-caption-on-right > .v {
        display: inline-block;
        vertical-align: middle;
 }
 
-.v-has-caption.v-has-width > .v-connector {
+.v-has-caption.v-has-width > .v {
        width: 100% !important;
 }
 
-.v-has-caption.v-has-height > .v-connector {
+.v-has-caption.v-has-height > .v {
        height: 100% !important;
 }
 
index 366dbdf26ff5b29cc18f1526318aad0f584980a0..953584ffd7932d844d6fcde5e7f4dbc6af093c78 100644 (file)
@@ -1,3 +1,7 @@
 .v-label {
        overflow: hidden;
+}
+
+.v-label.v-has-width {
+       white-space: normal;
 }
\ No newline at end of file
index 10cd14251b65b606a99450f00d51504a04d6b8cf..7f01300d6861d750a68475198a4c0e4cf3e07aae 100644 (file)
@@ -81,6 +81,16 @@ public class ComponentState extends SharedState {
         return "".equals(getHeight());
     }
 
+    /**
+     * Returns true if the component height is relative to the parent, i.e.
+     * percentage, false if it is fixed/auto.
+     * 
+     * @return true if component height is relative (percentage)
+     */
+    public boolean isRelativeHeight() {
+        return getHeight().endsWith("%");
+    }
+
     /**
      * Returns the component width as set by the server.
      * 
@@ -119,6 +129,16 @@ public class ComponentState extends SharedState {
         return "".equals(getWidth());
     }
 
+    /**
+     * Returns true if the component width is relative to the parent, i.e.
+     * percentage, false if it is fixed/auto.
+     * 
+     * @return true if component width is relative (percentage)
+     */
+    public boolean isRelativeWidth() {
+        return getWidth().endsWith("%");
+    }
+
     /**
      * Returns true if the component is in read-only mode.
      * 
index 0a2e90f2f2165aced192577f398d383c1c87fe92..239a948a10ed62d095e6ed03501ae2bab01dd3ac 100644 (file)
@@ -277,6 +277,9 @@ public class LayoutManager {
                 for (Element element : listenersToFire) {
                     Collection<ElementResizeListener> listeners = elementResizeListeners
                             .get(element);
+                    if (listeners == null) {
+                        continue;
+                    }
                     ElementResizeListener[] array = listeners
                             .toArray(new ElementResizeListener[listeners.size()]);
                     ElementResizeEvent event = new ElementResizeEvent(this,
index 26ec96003ec771bb2a7eb97012d1fe886d3b48ad..752e567f4c2fd4ced77ed23d1c20f74dab171e12 100644 (file)
@@ -12,13 +12,9 @@ import com.google.gwt.dom.client.Style.Unit;
 import com.google.gwt.user.client.Element;
 import com.google.gwt.user.client.ui.Widget;
 import com.vaadin.terminal.gwt.client.AbstractFieldState;
-import com.vaadin.terminal.gwt.client.ApplicationConnection;
 import com.vaadin.terminal.gwt.client.ComponentConnector;
 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.ValueMap;
 import com.vaadin.terminal.gwt.client.communication.RpcProxy;
 import com.vaadin.terminal.gwt.client.communication.StateChangeEvent;
 import com.vaadin.terminal.gwt.client.communication.StateChangeEvent.StateChangeHandler;
@@ -30,8 +26,7 @@ import com.vaadin.terminal.gwt.client.ui.orderedlayout.AbstractOrderedLayoutServ
 import com.vaadin.terminal.gwt.client.ui.orderedlayout.AbstractOrderedLayoutState;
 
 public abstract class AbstractBoxLayoutConnector extends
-        AbstractLayoutConnector implements Paintable, /* PreLayoutListener, */
-PostLayoutListener {
+        AbstractLayoutConnector /* implements PostLayoutListener */{
 
     AbstractOrderedLayoutServerRpc rpc;
 
@@ -105,103 +100,6 @@ PostLayoutListener {
      */
     private HashMap<Element, Integer> childCaptionElementHeight = new HashMap<Element, Integer>();
 
-    // For debugging
-    private static int resizeCount = 0;
-
-    public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
-        if (!isRealUpdate(uidl)) {
-            return;
-        }
-
-        clickEventHandler.handleEventHandlerRegistration();
-
-        VBoxLayout layout = getWidget();
-
-        ValueMap expandRatios = uidl.getMapAttribute("expandRatios");
-        ValueMap alignments = uidl.getMapAttribute("alignments");
-
-        for (ComponentConnector child : getChildren()) {
-            Slot slot = layout.getSlot(child);
-            String pid = child.getConnectorId();
-
-            AlignmentInfo alignment;
-            if (alignments.containsKey(pid)) {
-                alignment = new AlignmentInfo(alignments.getInt(pid));
-                if (alignment.isVerticalCenter() || alignment.isBottom()) {
-                    hasVerticalAlignment.add(child);
-                } else {
-                    hasVerticalAlignment.remove(child);
-                }
-            } else {
-                alignment = AlignmentInfo.TOP_LEFT;
-                hasVerticalAlignment.remove(child);
-            }
-            slot.setAlignment(alignment);
-
-            double expandRatio;
-            // TODO discuss the layout specs, is this what we want: distribute
-            // extra space equally if no expand ratios are specified inside a
-            // layout with specified size
-            if (expandRatios.getKeySet().size() == 0
-                    && ((getWidget().vertical && !isUndefinedHeight()) || (!getWidget().vertical && !isUndefinedWidth()))) {
-                expandRatio = 1;
-                hasExpandRatio.add(child);
-            } else if (expandRatios.containsKey(pid)
-                    && expandRatios.getRawNumber(pid) > 0) {
-                expandRatio = expandRatios.getRawNumber(pid);
-                hasExpandRatio.add(child);
-            } else {
-                expandRatio = -1;
-                hasExpandRatio.remove(child);
-                if (expandRatios.getKeySet().size() > 0
-                        || hasExpandRatio.size() > 0) {
-                    // Only add resize listeners if there are expand ratios in
-                    // use
-                    getLayoutManager().addElementResizeListener(
-                            child.getWidget().getElement(),
-                            childComponentResizeListener);
-                    if (slot.hasCaption()) {
-                        getLayoutManager().addElementResizeListener(
-                                slot.getCaptionElement(),
-                                slotCaptionResizeListener);
-                    }
-                }
-            }
-            slot.setExpandRatio(expandRatio);
-
-            // TODO only needed if expand ratios are used
-            if (slot.getSpacingElement() != null) {
-                getLayoutManager().addElementResizeListener(
-                        slot.getSpacingElement(), spacingResizeListener);
-            } else if (slot.getSpacingElement() != null) {
-                getLayoutManager().removeElementResizeListener(
-                        slot.getSpacingElement(), spacingResizeListener);
-            }
-
-        }
-
-        if (needsFixedHeight()) {
-            for (ComponentConnector child : getChildren()) {
-                Slot slot = layout.getSlot(child);
-                getLayoutManager().addElementResizeListener(
-                        child.getWidget().getElement(),
-                        childComponentResizeListener);
-                if (slot.hasCaption()) {
-                    getLayoutManager()
-                            .addElementResizeListener(slot.getCaptionElement(),
-                                    slotCaptionResizeListener);
-                }
-            }
-        }
-
-        if (needsExpand()) {
-            updateExpand();
-        } else {
-            getWidget().clearExpand();
-        }
-
-    }
-
     public void updateCaption(ComponentConnector child) {
         Slot slot = getWidget().getSlot(child);
 
@@ -241,19 +139,9 @@ PostLayoutListener {
                 getWidget().updateCaptionOffset(slot.getCaptionElement());
             }
         } else {
-            // getLayoutManager().removeElementResizeListener(
-            // slot.getCaptionElement(), slotCaptionResizeListener);
-        }
-
-        if (!slot.hasCaption()) {
             childCaptionElementHeight.remove(child.getWidget().getElement());
         }
 
-        if (needsFixedHeight()) {
-            getWidget().clearHeight();
-            getLayoutManager().setNeedsMeasure(this);
-        }
-
         updateLayoutHeight();
 
         if (needsExpand()) {
@@ -270,7 +158,6 @@ PostLayoutListener {
         VBoxLayout layout = getWidget();
 
         for (ComponentConnector child : getChildren()) {
-            Widget childWidget = child.getWidget();
             Slot slot = layout.getSlot(child);
             if (slot.getParent() != layout) {
                 child.addStateChangeHandler(childStateChangeHandler);
@@ -306,8 +193,9 @@ PostLayoutListener {
             }
         }
 
+        // If some component is added/removed, we need to recalculate the expand
         if (needsExpand()) {
-            getWidget().updateExpand();
+            updateExpand();
         } else {
             getWidget().clearExpand();
         }
@@ -318,22 +206,55 @@ PostLayoutListener {
     public void onStateChanged(StateChangeEvent stateChangeEvent) {
         super.onStateChanged(stateChangeEvent);
 
+        clickEventHandler.handleEventHandlerRegistration();
+
         getWidget().setMargin(new VMarginInfo(getState().getMarginsBitmask()));
         getWidget().setSpacing(getState().isSpacing());
 
-        if (needsFixedHeight()) {
-            getWidget().clearHeight();
-            setLayoutHeightListener(true);
-            getLayoutManager().setNeedsMeasure(this);
-        } else {
-            setLayoutHeightListener(false);
+        hasExpandRatio.clear();
+        hasVerticalAlignment.clear();
+        hasRelativeHeight.clear();
+        needsMeasure.clear();
+
+        for (ComponentConnector child : getChildren()) {
+            Slot slot = getWidget().getSlot(child);
+
+            AlignmentInfo alignment = new AlignmentInfo(getState()
+                    .getChildData().get(child).getAlignmentBitmask());
+            slot.setAlignment(alignment);
+
+            double expandRatio = getState().getChildData().get(child)
+                    .getExpandRatio();
+            if (expandRatio == 0) {
+                expandRatio = -1;
+            }
+            slot.setExpandRatio(expandRatio);
+
+            // Bookkeeping to identify special cases that need extra
+            // calculations
+            if (alignment.isVerticalCenter() || alignment.isBottom()) {
+                hasVerticalAlignment.add(child);
+            }
+
+            if (expandRatio > 0) {
+                hasExpandRatio.add(child);
+            }
+
+            if (child.getState().isRelativeHeight()) {
+                hasRelativeHeight.add(child);
+            } else {
+                needsMeasure.add(child.getWidget().getElement());
+            }
         }
 
-        // TODO recognize special cases here, using child states
+        updateAllSlotListeners();
+
+        updateLayoutHeight();
     }
 
     StateChangeHandler childStateChangeHandler = new StateChangeHandler() {
         public void onStateChanged(StateChangeEvent stateChangeEvent) {
+
             ComponentConnector child = (ComponentConnector) stateChangeEvent
                     .getConnector();
 
@@ -344,77 +265,30 @@ PostLayoutListener {
             slot.setRelativeHeight(child.isRelativeHeight());
 
             // For relative sized widgets, we need to set the caption offset
-            if (slot.hasCaption()) {
-                CaptionPosition pos = slot.getCaptionPosition();
-                if (child.isRelativeHeight()
-                        && (pos == CaptionPosition.TOP || pos == CaptionPosition.BOTTOM)) {
-                    getWidget().updateCaptionOffset(slot.getCaptionElement());
-                } else if (child.isRelativeWidth()
-                        && (pos == CaptionPosition.LEFT || pos == CaptionPosition.RIGHT)) {
-                    getWidget().updateCaptionOffset(slot.getCaptionElement());
-                }
-            }
-
-            // TODO 'needsExpand' might return false during the first render,
-            // since updateFromUidl is called last
-
-            // If the slot has caption, we need to listen for it's size changes
-            // in order to update the padding/margin offset for relative sized
-            // components
-            if ((child.isRelativeHeight() || needsFixedHeight())
-                    && slot.hasCaption()) {
-                getLayoutManager().addElementResizeListener(
-                        slot.getCaptionElement(), slotCaptionResizeListener);
-            } else if (!needsExpand()) {
-                // TODO recheck if removing the listener here breaks anything.
-                // Should be cleaned up.
-                // getLayoutManager().removeElementResizeListener(
-                // slot.getCaptionElement(), slotCaptionResizeListener);
-            }
-
-            if (slot.getSpacingElement() != null && needsExpand()) {
-                // Spacing is on
-                getLayoutManager().addElementResizeListener(
-                        slot.getSpacingElement(), spacingResizeListener);
-            } else if (slot.getSpacingElement() != null) {
-                getLayoutManager().removeElementResizeListener(
-                        slot.getSpacingElement(), spacingResizeListener);
-            }
-
-            if (child.isRelativeHeight()) {
-                hasRelativeHeight.add(child);
-                needsMeasure.remove(child.getWidget().getElement());
-            } else {
-                hasRelativeHeight.remove(child);
-                needsMeasure.add(child.getWidget().getElement());
-            }
-
-            if (needsFixedHeight()) {
-                getLayoutManager().addElementResizeListener(
-                        child.getWidget().getElement(),
-                        childComponentResizeListener);
-            } else if (!needsExpand()) {
-                getLayoutManager().removeElementResizeListener(
-                        child.getWidget().getElement(),
-                        childComponentResizeListener);
-            }
-
-            if (needsFixedHeight()) {
-                getWidget().clearHeight();
-                setLayoutHeightListener(true);
-                getLayoutManager().setNeedsMeasure(
-                        AbstractBoxLayoutConnector.this);
-            } else {
-                setLayoutHeightListener(false);
-            }
+            // if (slot.hasCaption()) {
+            // CaptionPosition pos = slot.getCaptionPosition();
+            // if (child.isRelativeHeight()
+            // && (pos == CaptionPosition.TOP || pos == CaptionPosition.BOTTOM))
+            // {
+            // getWidget().updateCaptionOffset(slot.getCaptionElement());
+            // } else if (child.isRelativeWidth()
+            // && (pos == CaptionPosition.LEFT || pos == CaptionPosition.RIGHT))
+            // {
+            // getWidget().updateCaptionOffset(slot.getCaptionElement());
+            // }
+            // }
 
+            updateSlotListeners(child);
         }
     };
 
     private boolean needsFixedHeight() {
-        if (!getWidget().vertical
-                && isUndefinedHeight()
-                && (hasRelativeHeight.size() > 0 || hasVerticalAlignment.size() > 0)) {
+        if (!getWidget().vertical && isUndefinedHeight()
+                && (hasRelativeHeight.size() > 0 /*
+                                                  * ||
+                                                  * hasVerticalAlignment.size()
+                                                  * > 0
+                                                  */)) {
             return true;
         }
         return false;
@@ -426,72 +300,121 @@ PostLayoutListener {
         return hasExpandRatio.size() > 0 && canApplyExpand;
     }
 
-    // public void preLayout() {
-    // resizeCount = 0;
-    // }
+    private void updateAllSlotListeners() {
+        for (ComponentConnector child : getChildren()) {
+            updateSlotListeners(child);
+        }
+        // if (needsFixedHeight()) {
+        // getWidget().clearHeight();
+        // setLayoutHeightListener(true);
+        // getLayoutManager().setNeedsMeasure(AbstractBoxLayoutConnector.this);
+        // } else {
+        // setLayoutHeightListener(false);
+        // }
+    }
 
-    public void postLayout() {
-        if (needsFixedHeight()) {
-            // Re-measure all elements that are available
-            for (Element el : needsMeasure) {
-                childElementHeight.put(el, getLayoutManager()
-                        .getOuterHeight(el));
+    /**
+     * Add/remove necessary ElementResizeListeners for one slot. This should be
+     * called after each update to the slot's or it's widget.
+     */
+    private void updateSlotListeners(ComponentConnector child) {
+        Slot slot = getWidget().getSlot(child);
 
-                Element captionElement = el.getParentElement()
-                        .getFirstChildElement().cast();
-                if (captionElement.getClassName().contains("v-caption")) {
-                    childCaptionElementHeight.put(el, getLayoutManager()
-                            .getOuterHeight(captionElement));
-                }
+        // Clear all possible listeners first
+        dontListen(slot.getWidget().getElement(), childComponentResizeListener);
+        if (slot.hasCaption()) {
+            dontListen(slot.getCaptionElement(), slotCaptionResizeListener);
+        }
+        if (slot.hasSpacing()) {
+            dontListen(slot.getSpacingElement(), spacingResizeListener);
+        }
+
+        // Add all necessary listeners
+        if (needsFixedHeight()) {
+            listen(slot.getWidget().getElement(), childComponentResizeListener);
+            if (slot.hasCaption()) {
+                listen(slot.getCaptionElement(), slotCaptionResizeListener);
             }
-            System.out.println("  ###  Child sizes: "
-                    + childElementHeight.values().toString());
-            System.out.println("  ###  Caption sizes: "
-                    + childCaptionElementHeight.values().toString());
-
-            // If no height has been set, use the natural height for the
-            // component (this is mostly just a precaution so that something
-            // renders correctly)
-            // String h = getWidget().getElement().getStyle().getHeight();
-            // if (h == null || h.equals("")) {
-            // int height = getLayoutManager().getOuterHeight(
-            // getWidget().getElement())
-            // - getLayoutManager().getMarginHeight(
-            // getWidget().getElement());
-            int height = getMaxHeight()
-                    + getLayoutManager().getBorderHeight(
-                            getWidget().getElement())
-                    + getLayoutManager().getPaddingHeight(
-                            getWidget().getElement());
-            getWidget().getElement().getStyle().setHeight(height, Unit.PX);
-            // }
+        } else if ((child.isRelativeHeight() || child.isRelativeWidth())
+                && slot.hasCaption()) {
+            // If the slot has caption, we need to listen for it's size changes
+            // in order to update the padding/margin offset for relative sized
+            // components
+            listen(slot.getCaptionElement(), slotCaptionResizeListener);
         }
-        // System.err.println("Element resize listeners fired for " +
-        // resizeCount
-        // + " times");
-    }
 
-    private ElementResizeListener layoutResizeListener = new ElementResizeListener() {
-        public void onElementResize(ElementResizeEvent e) {
-            resizeCount++;
-            updateLayoutHeight();
-            if (needsExpand() && (isUndefinedHeight() || isUndefinedWidth())) {
-                updateExpand();
+        if (needsExpand()) {
+            listen(slot.getWidget().getElement(), childComponentResizeListener);
+            if (slot.hasSpacing()) {
+                listen(slot.getSpacingElement(), spacingResizeListener);
             }
         }
-    };
+
+        if (child.isRelativeHeight()) {
+            hasRelativeHeight.add(child);
+            needsMeasure.remove(child.getWidget().getElement());
+        } else {
+            hasRelativeHeight.remove(child);
+            needsMeasure.add(child.getWidget().getElement());
+        }
+
+    }
+
+    // public void postLayout() {
+    // if (needsFixedHeight()) {
+    // // Re-measure all elements that are available
+    // for (Element el : needsMeasure) {
+    // childElementHeight.put(el, getLayoutManager()
+    // .getOuterHeight(el));
+    //
+    // Element captionElement = el.getParentElement()
+    // .getFirstChildElement().cast();
+    // if (captionElement.getClassName().contains("v-caption")) {
+    // childCaptionElementHeight.put(el, getLayoutManager()
+    // .getOuterHeight(captionElement));
+    // }
+    // }
+    // // System.out.println("  ###  Child sizes: "
+    // // + childElementHeight.values().toString());
+    // // System.out.println("  ###  Caption sizes: "
+    // // + childCaptionElementHeight.values().toString());
+    //
+    // int height = getMaxHeight()
+    // + getLayoutManager().getBorderHeight(
+    // getWidget().getElement())
+    // + getLayoutManager().getPaddingHeight(
+    // getWidget().getElement());
+    // getWidget().getElement().getStyle().setHeight(height, Unit.PX);
+    // }
+    // }
+
+    // private ElementResizeListener layoutResizeListener = new
+    // ElementResizeListener() {
+    // public void onElementResize(ElementResizeEvent e) {
+    // updateLayoutHeight();
+    // if (needsExpand() && (isUndefinedHeight() || isUndefinedWidth())) {
+    // updateExpand();
+    // }
+    // }
+    // };
 
     private ElementResizeListener slotCaptionResizeListener = new ElementResizeListener() {
         public void onElementResize(ElementResizeEvent e) {
-            resizeCount++;
 
+            // Get all needed element references
             Element captionElement = (Element) e.getElement().cast();
 
+            // Caption position determines if the widget element is the first or
+            // last child inside the caption wrap
             CaptionPosition pos = getWidget().getCaptionPositionFromElement(
                     (Element) captionElement.getParentElement().cast());
 
+            // The default is the last child
             Element widgetElement = captionElement.getParentElement()
                     .getLastChild().cast();
+
+            // ...but if caption position is bottom or right, the widget is the
+            // first child
             if (pos == CaptionPosition.BOTTOM || pos == CaptionPosition.RIGHT) {
                 widgetElement = captionElement.getParentElement()
                         .getFirstChildElement().cast();
@@ -499,8 +422,7 @@ PostLayoutListener {
 
             if (captionElement == widgetElement) {
                 // Caption element already detached
-                getLayoutManager().removeElementResizeListener(captionElement,
-                        slotCaptionResizeListener);
+                dontListen(captionElement, slotCaptionResizeListener);
                 childCaptionElementHeight.remove(widgetElement);
                 return;
             }
@@ -519,13 +441,12 @@ PostLayoutListener {
             int h = getLayoutManager().getOuterHeight(captionElement)
                     - getLayoutManager().getMarginHeight(captionElement);
             childCaptionElementHeight.put(widgetElement, h);
-            // System.out.println("Caption size: " + h);
 
-            if (needsFixedHeight()) {
-                getWidget().clearHeight();
-                getLayoutManager().setNeedsMeasure(
-                        AbstractBoxLayoutConnector.this);
-            }
+            // if (needsFixedHeight()) {
+            // getWidget().clearHeight();
+            // getLayoutManager().setNeedsMeasure(
+            // AbstractBoxLayoutConnector.this);
+            // }
 
             updateLayoutHeight();
 
@@ -537,7 +458,6 @@ PostLayoutListener {
 
     private ElementResizeListener childComponentResizeListener = new ElementResizeListener() {
         public void onElementResize(ElementResizeEvent e) {
-            resizeCount++;
             int h = getLayoutManager().getOuterHeight(e.getElement());
             childElementHeight.put((Element) e.getElement().cast(), h);
             updateLayoutHeight();
@@ -550,7 +470,6 @@ PostLayoutListener {
 
     private ElementResizeListener spacingResizeListener = new ElementResizeListener() {
         public void onElementResize(ElementResizeEvent e) {
-            resizeCount++;
             if (needsExpand()) {
                 updateExpand();
             }
@@ -576,8 +495,12 @@ PostLayoutListener {
     }
 
     private int getMaxHeight() {
+        // TODO should use layout manager instead of inner lists of element
+        // sizes
         int highestNonRelative = -1;
         int highestRelative = -1;
+        // System.out.println("Child sizes: "
+        // + childElementHeight.values().toString());
         for (Element el : childElementHeight.keySet()) {
             // TODO would be more efficient to measure the slot element if both
             // caption and child widget elements need to be measured. Keeping
@@ -616,44 +539,48 @@ PostLayoutListener {
     public void onUnregister() {
         // Cleanup all ElementResizeListeners
 
-        getLayoutManager().removeElementResizeListener(
-                getWidget().getElement(), layoutResizeListener);
-
-        for (int i = 0; i < getWidget().getWidgetCount(); i++) {
-            // TODO unsafe
-            Slot slot = (Slot) getWidget().getWidget(i);
+        // dontListen(getWidget().getElement(), layoutResizeListener);
 
+        for (ComponentConnector child : getChildren()) {
+            Slot slot = getWidget().getSlot(child);
             if (slot.hasCaption()) {
-                getLayoutManager().removeElementResizeListener(
-                        slot.getCaptionElement(), slotCaptionResizeListener);
+                dontListen(slot.getCaptionElement(), slotCaptionResizeListener);
             }
 
             if (slot.getSpacingElement() != null) {
-                getLayoutManager().removeElementResizeListener(
-                        slot.getSpacingElement(), spacingResizeListener);
+                dontListen(slot.getSpacingElement(), spacingResizeListener);
             }
 
-            getLayoutManager()
-                    .removeElementResizeListener(slot.getWidget().getElement(),
-                            childComponentResizeListener);
-
+            dontListen(slot.getWidget().getElement(),
+                    childComponentResizeListener);
         }
 
         super.onUnregister();
     }
 
-    private void setLayoutHeightListener(boolean add) {
-        if (add) {
-            getLayoutManager().addElementResizeListener(
-                    getWidget().getElement(), layoutResizeListener);
-        } else {
-            getLayoutManager().removeElementResizeListener(
-                    getWidget().getElement(), layoutResizeListener);
-            if (!needsExpand()) {
-                childElementHeight.clear();
-                childCaptionElementHeight.clear();
-            }
-        }
+    // private void setLayoutHeightListener(boolean add) {
+    // if (add) {
+    // listen(getWidget().getElement(), layoutResizeListener);
+    // } else {
+    // dontListen(getWidget().getElement(), layoutResizeListener);
+    // if (!needsExpand()) {
+    // System.out.println("Clearing element sizes");
+    // childElementHeight.clear();
+    // childCaptionElementHeight.clear();
+    // }
+    // }
+    // }
+
+    /*
+     * Convenience methods
+     */
+
+    private void listen(Element el, ElementResizeListener listener) {
+        getLayoutManager().addElementResizeListener(el, listener);
+    }
+
+    private void dontListen(Element el, ElementResizeListener listener) {
+        getLayoutManager().removeElementResizeListener(el, listener);
     }
 
 }
index d690bdded18f605a06c2a35efdc8a09403de074d..1caec0428e0c36f01398f3dcff9cdcec56a6de25 100644 (file)
@@ -3,6 +3,8 @@
  */
 package com.vaadin.terminal.gwt.client.ui;
 
+import java.util.LinkedList;
+import java.util.List;
 import java.util.Set;
 
 import com.google.gwt.user.client.ui.Focusable;
@@ -31,6 +33,8 @@ public abstract class AbstractComponentConnector extends AbstractConnector
     private String lastKnownWidth = "";
     private String lastKnownHeight = "";
 
+    List<String> styleNames;
+
     /**
      * Default constructor
      */
@@ -97,8 +101,9 @@ public abstract class AbstractComponentConnector extends AbstractConnector
         setWidgetEnabled(isEnabled());
 
         // Style names
-        String styleName = getStyleNames(getWidget().getStylePrimaryName());
-        getWidget().setStyleName(styleName);
+        // String styleName = getStyleNames(getWidget().getStylePrimaryName());
+        // getWidget().setStyleName(styleName);
+        updateStyleNames();
 
         // Update tooltip
         TooltipInfo tooltipInfo = paintableMap.getTooltipInfo(this, null);
@@ -270,6 +275,54 @@ public abstract class AbstractComponentConnector extends AbstractConnector
         return styleBuf.toString();
     }
 
+    protected void updateStyleNames() {
+        Widget widget = getWidget();
+
+        widget.addStyleName("v");
+
+        // Disabled
+        if (!isEnabled()) {
+            widget.addStyleName(ApplicationConnection.DISABLED_CLASSNAME);
+        } else {
+            widget.removeStyleName(ApplicationConnection.DISABLED_CLASSNAME);
+        }
+
+        // Read-only
+        if (isReadOnly()) {
+            widget.addStyleName("v-readonly");
+        } else {
+            widget.removeStyleName("v-readonly");
+        }
+
+        // Error
+        if (null != getState().getErrorMessage()) {
+            widget.addStyleDependentName("error");
+        } else {
+            widget.removeStyleDependentName("error");
+        }
+
+        // Additional style names
+        List<String> newStyleNames = getState().getStyles();
+        if (newStyleNames == null) {
+            newStyleNames = new LinkedList<String>();
+        }
+        if (styleNames != null) {
+            // Remove previous styles which are no longer in the current list
+            for (String style : styleNames) {
+                if (!newStyleNames.contains(style)) {
+                    widget.removeStyleName(style);
+                    widget.removeStyleDependentName(style);
+                }
+            }
+        }
+        // Add any new styles
+        for (String style : newStyleNames) {
+            widget.addStyleName(style);
+            widget.addStyleDependentName(style);
+        }
+        styleNames = newStyleNames;
+    }
+
     /*
      * (non-Javadoc)
      * 
index dd15528cf79b783cc25ce58563f0237f1fe17ef4..53477571ed420575e426444ea8fce99326a3297d 100644 (file)
@@ -3,8 +3,6 @@
  */
 package com.vaadin.terminal.gwt.client.ui;
 
-import com.vaadin.terminal.gwt.client.ApplicationConnection;
-import com.vaadin.terminal.gwt.client.UIDL;
 import com.vaadin.terminal.gwt.client.ui.Connect.LoadStyle;
 import com.vaadin.ui.HorizontalLayout;
 
@@ -17,13 +15,4 @@ public class HorizontalBoxLayoutConnector extends AbstractBoxLayoutConnector {
         getWidget().setVertical(false);
     }
 
-    @Override
-    public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
-        // TODO remove when Vaadin style name handling is improved so that it
-        // won't override extra client side style names
-        getWidget().setVertical(false);
-        super.updateFromUIDL(uidl, client);
-        getWidget().setVertical(false);
-    }
-
 }
index 3a6beaa48a69ac097688eafc4c6c8f8f10416b96..c49587c29bd41031509ba1ff3701d65368ebf7e1 100644 (file)
@@ -187,6 +187,10 @@ public class VBoxLayout extends FlowPanel {
             return spacer;
         }
 
+        public boolean hasSpacing() {
+            return getSpacingElement() != null;
+        }
+
         protected int getSpacingSize(boolean vertical) {
             if (spacer == null) {
                 return 0;
@@ -246,7 +250,7 @@ public class VBoxLayout extends FlowPanel {
                 if (caption == null) {
                     caption = DOM.createDiv();
                     captionWrap = DOM.createDiv();
-                    captionWrap.addClassName("v-connector");
+                    captionWrap.addClassName("v");
                     captionWrap.addClassName("v-has-caption");
                     getElement().appendChild(captionWrap);
                     captionWrap.appendChild(getWidget().getElement());
index 7e10680afb536b0b4477e0af217e6a25ec495d82..9953b02b2de300a768ad07ce554b9d97bd6fde1d 100644 (file)
@@ -3,8 +3,6 @@
  */
 package com.vaadin.terminal.gwt.client.ui;
 
-import com.vaadin.terminal.gwt.client.ApplicationConnection;
-import com.vaadin.terminal.gwt.client.UIDL;
 import com.vaadin.terminal.gwt.client.ui.Connect.LoadStyle;
 import com.vaadin.ui.VerticalLayout;
 
@@ -17,13 +15,4 @@ public class VerticalBoxLayoutConnector extends AbstractBoxLayoutConnector {
         getWidget().setVertical(true);
     }
 
-    @Override
-    public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
-        // TODO fix when Vaadin style name handling is improved so that it won't
-        // override extra client side style names
-        getWidget().setVertical(true);
-        super.updateFromUIDL(uidl, client);
-        getWidget().setVertical(true);
-    }
-
 }
index 6b3f1efde7de451c9ab1de451fb9908ee4d4a583..5e2de2f262c70fe7fd8230113eb9123c479c3b37 100644 (file)
@@ -11,6 +11,7 @@ import com.vaadin.event.LayoutEvents.LayoutClickListener;
 import com.vaadin.terminal.ThemeResource;
 import com.vaadin.terminal.UserError;
 import com.vaadin.terminal.WrappedRequest;
+import com.vaadin.terminal.gwt.client.ui.label.ContentMode;
 import com.vaadin.tests.components.AbstractTestRoot;
 import com.vaadin.ui.AbstractComponent;
 import com.vaadin.ui.AbstractField;
@@ -23,7 +24,6 @@ import com.vaadin.ui.Component;
 import com.vaadin.ui.GridLayout;
 import com.vaadin.ui.HorizontalLayout;
 import com.vaadin.ui.Label;
-import com.vaadin.ui.Label.ContentMode;
 import com.vaadin.ui.NativeSelect;
 import com.vaadin.ui.TextField;
 import com.vaadin.ui.VerticalLayout;
@@ -61,10 +61,36 @@ public class BoxLayoutTest extends AbstractTestRoot {
         view.addComponent(createTestLayout(false));
         view.setExpandRatio(view.getComponent(1), 1);
 
+        // for (int i = 0; i < 20; i++) {
+        // view.addComponent(createHorizontalTest());
+        // }
+
         setContent(view);
         getApplication().setRootPreserved(true);
     }
 
+    private Component createHorizontalTest() {
+        HorizontalLayout l = new HorizontalLayout();
+        l.setWidth("100%");
+
+        Label exp;
+
+        // l.addComponent(new Embedded(null, new ThemeResource(
+        // "../runo/icons/32/document.png")));
+        l.addComponent(exp = new Label(
+                "Mauris iaculis porttitor posuere. Praesent id metus massa, ut blandit odio. Proin quis tortor orci. Etiam at risus et justo dignissim congue. Donec."));
+        // exp.setWidth("300px");
+        l.addComponent(new Button("Edit"));
+        l.addComponent(new Button("Delete"));
+        l.setExpandRatio(exp, 1);
+
+        for (int i = 0; i < l.getComponentCount(); i++) {
+            l.setComponentAlignment(l.getComponent(i), Alignment.MIDDLE_LEFT);
+        }
+
+        return l;
+    }
+
     protected AbstractOrderedLayout createControls(boolean horizontal) {
         VerticalLayout root = new VerticalLayout();
         root.setSpacing(true);
@@ -344,6 +370,11 @@ public class BoxLayoutTest extends AbstractTestRoot {
         });
         component.addComponent(componentRequired);
 
+        for (int i = 0; i < component.getComponentCount(); i++) {
+            component.setComponentAlignment(component.getComponent(i),
+                    Alignment.MIDDLE_LEFT);
+        }
+
         return root;
     }
 
index 70777b644181b03d151463dfbf90e1dcce82c72c..c493b03eb509cd085278f3b98dd5bd85c060823c 100644 (file)
@@ -1,6 +1,7 @@
 package com.vaadin.tests.components.orderedlayout;
 
 import com.vaadin.terminal.ThemeResource;
+import com.vaadin.terminal.gwt.client.ui.label.ContentMode;
 import com.vaadin.tests.components.TestBase;
 import com.vaadin.ui.Alignment;
 import com.vaadin.ui.Button;
@@ -32,7 +33,7 @@ public class LayoutResizeTest extends TestBase {
         left.setMargin(true);
 
         left.addComponent(new Label("<h2>Layout resize test</h2>",
-                Label.ContentMode.XHTML));
+                ContentMode.XHTML));
 
         Button resize = new Button("Resize to 700x400",
                 new Button.ClickListener() {