]> source.dussan.org Git - vaadin-framework.git/commitdiff
Changed the way relative component sizes are handled. Relative sizes are now converte...
authorArtur Signell <artur.signell@itmill.com>
Wed, 1 Oct 2008 06:40:48 +0000 (06:40 +0000)
committerArtur Signell <artur.signell@itmill.com>
Wed, 1 Oct 2008 06:40:48 +0000 (06:40 +0000)
All containers MUST now implement Container which includes the getAllocatedSpace() method used by the relative size calculator.

This also fixes OrderedLayout bugs #2021, #2034, #2030, #2102
Also fixes #2127

svn changeset:5570/svn branch:trunk

31 files changed:
WebContent/ITMILL/themes/default/orderedlayout/orderedlayout.css
WebContent/ITMILL/themes/default/styles.css
src/com/itmill/toolkit/terminal/gwt/client/ApplicationConnection.java
src/com/itmill/toolkit/terminal/gwt/client/Container.java
src/com/itmill/toolkit/terminal/gwt/client/ContainerResizedListener.java
src/com/itmill/toolkit/terminal/gwt/client/ICaption.java
src/com/itmill/toolkit/terminal/gwt/client/RenderInformation.java [new file with mode: 0644]
src/com/itmill/toolkit/terminal/gwt/client/Util.java
src/com/itmill/toolkit/terminal/gwt/client/ui/IAccordion.java
src/com/itmill/toolkit/terminal/gwt/client/ui/IButton.java
src/com/itmill/toolkit/terminal/gwt/client/ui/ICoordinateLayout.java
src/com/itmill/toolkit/terminal/gwt/client/ui/ICustomComponent.java
src/com/itmill/toolkit/terminal/gwt/client/ui/ICustomLayout.java
src/com/itmill/toolkit/terminal/gwt/client/ui/IExpandLayout.java
src/com/itmill/toolkit/terminal/gwt/client/ui/IForm.java
src/com/itmill/toolkit/terminal/gwt/client/ui/IFormLayout.java
src/com/itmill/toolkit/terminal/gwt/client/ui/IGridLayout.java
src/com/itmill/toolkit/terminal/gwt/client/ui/IOrderedLayout.java
src/com/itmill/toolkit/terminal/gwt/client/ui/IPanel.java
src/com/itmill/toolkit/terminal/gwt/client/ui/IPopupView.java
src/com/itmill/toolkit/terminal/gwt/client/ui/IScrollTable.java
src/com/itmill/toolkit/terminal/gwt/client/ui/ISlider.java
src/com/itmill/toolkit/terminal/gwt/client/ui/ISplitPanel.java
src/com/itmill/toolkit/terminal/gwt/client/ui/ITabsheet.java
src/com/itmill/toolkit/terminal/gwt/client/ui/ITabsheetBase.java
src/com/itmill/toolkit/terminal/gwt/client/ui/ITextField.java
src/com/itmill/toolkit/terminal/gwt/client/ui/ITextualDate.java
src/com/itmill/toolkit/terminal/gwt/client/ui/IView.java
src/com/itmill/toolkit/terminal/gwt/client/ui/IWindow.java
src/com/itmill/toolkit/terminal/gwt/client/ui/absolutegrid/IAbsoluteGrid.java
src/com/itmill/toolkit/terminal/gwt/client/ui/absolutegrid/ISizeableGridLayout.java

index 9b18933db5647b198b8fa3dd1fa0ebeb1602d986..6e9ef37f9255c23975d302ac4720fbe196265085 100644 (file)
 }
 
 /* Placing error indicator right after the widget with empty caption */
-.i-orderedlayout-c * { float:left; display: block;}
+.i-orderedlayout-c * { float:left;}
 .i-orderedlayout-w-e { float:left;}
 * html .i-orderedlayout-c, * html .i-orderedlayout-w { height: 1%; }
-.i-orderedlayout-w { display: block; }
 .i-orderedlayout-c { float:left; display: block;}
 .i-orderedlayout-w:after, .i-orderedlayout-c:after  {
        content: ".";
index 35f42be16ea8110af337e592b2621351911c36f5..93510852c4ed9e19b8e1dce5c4ecb26cf58fb4f3 100644 (file)
  * needs application specific planning and CSS tuning.
  */
 @media print {
+       
        .i-generated-body {
                height: auto;
                min-height: 20cm;
                overflow: visible;
        }
+
        .i-app {
                height:auto;
                min-height: 20cm;
@@ -881,10 +883,9 @@ input.i-modified,
 }
 
 /* Placing error indicator right after the widget with empty caption */
-.i-orderedlayout-c * { float:left; display: block;}
+.i-orderedlayout-c * { float:left;}
 .i-orderedlayout-w-e { float:left;}
 * html .i-orderedlayout-c, * html .i-orderedlayout-w { height: 1%; }
-.i-orderedlayout-w { display: block; }
 .i-orderedlayout-c { float:left; display: block;}
 .i-orderedlayout-w:after, .i-orderedlayout-c:after  {
        content: ".";
index f6d85e483027508fbe30be13b4c660b10ace6069..76c70c36b39132722a8adc07729552eba6fb77e0 100755 (executable)
@@ -35,6 +35,8 @@ import com.google.gwt.user.client.impl.HTTPRequestImpl;
 import com.google.gwt.user.client.ui.FocusWidget;
 import com.google.gwt.user.client.ui.HasWidgets;
 import com.google.gwt.user.client.ui.Widget;
+import com.itmill.toolkit.terminal.gwt.client.RenderInformation.FloatSize;
+import com.itmill.toolkit.terminal.gwt.client.RenderInformation.Size;
 import com.itmill.toolkit.terminal.gwt.client.ui.Field;
 import com.itmill.toolkit.terminal.gwt.client.ui.IContextMenu;
 import com.itmill.toolkit.terminal.gwt.client.ui.INotification;
@@ -65,12 +67,15 @@ public class ApplicationConnection {
 
     private final Vector pendingVariables = new Vector();
 
-    private final HashMap idToPaintable = new HashMap();
+    private final HashMap<String, Paintable> idToPaintable = new HashMap<String, Paintable>();
 
-    private final HashMap paintableToId = new HashMap();
+    private final HashMap<Paintable, String> paintableToId = new HashMap<Paintable, String>();
 
     /** Contains ExtendedTitleInfo by paintable id */
-    private final HashMap paintableToTitle = new HashMap();
+    private final HashMap<Paintable, TooltipInfo> paintableToTitle = new HashMap<Paintable, TooltipInfo>();
+
+    private final HashMap<Widget, FloatSize> componentRelativeSizes = new HashMap<Widget, FloatSize>();
+    private final HashMap<Widget, Size> componentOffsetSizes = new HashMap<Widget, Size>();
 
     private final WidgetSet widgetSet;
 
@@ -525,7 +530,7 @@ public class ApplicationConnection {
         final JSONArray changes = (JSONArray) ((JSONObject) json)
                 .get("changes");
 
-        Set<Widget> sizeUpdatedWidgets = new HashSet<Widget>();
+        Vector<Widget> updatedWidgets = new Vector<Widget>();
 
         for (int i = 0; i < changes.size(); i++) {
             try {
@@ -542,15 +547,10 @@ public class ApplicationConnection {
                 final Paintable paintable = getPaintable(uidl.getId());
                 if (paintable != null) {
                     Widget widget = (Widget) paintable;
-                    int w = widget.getOffsetWidth();
-                    int h = widget.getOffsetHeight();
 
                     paintable.updateFromUIDL(uidl, this);
 
-                    if (w != widget.getOffsetWidth()
-                            || h != widget.getOffsetHeight()) {
-                        sizeUpdatedWidgets.add((Widget) paintable);
-                    }
+                    updatedWidgets.add(widget);
                 } else {
                     if (!uidl.getTag().equals("window")) {
                         ClientExceptionHandler
@@ -567,6 +567,21 @@ public class ApplicationConnection {
             }
         }
 
+        // Check which widgets' size has been updated
+        Set<Widget> sizeUpdatedWidgets = new HashSet<Widget>();
+
+        for (Widget widget : updatedWidgets) {
+            Size oldSize = componentOffsetSizes.get(widget);
+            Size newSize = new Size(widget.getOffsetWidth(), widget
+                    .getOffsetHeight());
+
+            if (oldSize == null || !oldSize.equals(newSize)) {
+                sizeUpdatedWidgets.add(widget);
+                componentOffsetSizes.put(widget, newSize);
+            }
+
+        }
+
         Util.componentSizeUpdated(sizeUpdatedWidgets);
 
         if (meta != null) {
@@ -588,7 +603,7 @@ public class ApplicationConnection {
                 }
 
                 if (html.length() != 0) {
-                    INotification n = new INotification(1000 * 60 * 45); //45min
+                    INotification n = new INotification(1000 * 60 * 45); // 45min
                     n.addEventListener(new NotificationRedirect(url));
                     n.show(html, INotification.CENTERED_TOP,
                             INotification.STYLE_SYSTEM);
@@ -637,7 +652,7 @@ public class ApplicationConnection {
     }
 
     public void unregisterPaintable(Paintable p) {
-        Object id = paintableToId.get(p);
+        String id = paintableToId.get(p);
         idToPaintable.remove(id);
         paintableToTitle.remove(id);
         paintableToId.remove(p);
@@ -666,7 +681,7 @@ public class ApplicationConnection {
      *            Paintable ID
      */
     public Paintable getPaintable(String id) {
-        return (Paintable) idToPaintable.get(id);
+        return idToPaintable.get(id);
     }
 
     private void addVariableToQueue(String paintableId, String variableName,
@@ -857,7 +872,7 @@ public class ApplicationConnection {
 
         // Switch to correct implementation if needed
         if (!widgetSet.isCorrectImplementation(component, uidl)) {
-            final Container parent = Util.getParentLayout(component);
+            final Container parent = Util.getLayout(component);
             if (parent != null) {
                 final Widget w = (Widget) widgetSet.createWidget(uidl);
                 parent.replaceChildComponent(component, w);
@@ -867,8 +882,6 @@ public class ApplicationConnection {
             }
         }
 
-        updateComponentSize(component, uidl);
-
         boolean enabled = !uidl.getBooleanAttribute("disabled");
         if (component instanceof FocusWidget) {
             FocusWidget fw = (FocusWidget) component;
@@ -940,7 +953,7 @@ public class ApplicationConnection {
 
         // Set captions
         if (manageCaption) {
-            final Container parent = Util.getParentLayout(component);
+            final Container parent = Util.getLayout(component);
             if (parent != null) {
                 parent.updateCaption((Paintable) component, uidl);
             }
@@ -950,16 +963,129 @@ public class ApplicationConnection {
             DOM.setElementProperty(component.getElement(), "id", uidl.getId());
         }
 
+        /*
+         * updateComponentSize need to be after caption update so caption can be
+         * taken into account
+         */
+
+        updateComponentSize(component, uidl);
+
         return false;
     }
 
     private void updateComponentSize(Widget component, UIDL uidl) {
         String w = uidl.hasAttribute("width") ? uidl
                 .getStringAttribute("width") : "";
-        component.setWidth(w);
+
         String h = uidl.hasAttribute("height") ? uidl
                 .getStringAttribute("height") : "";
-        component.setHeight(h);
+
+        float relativeWidth = Util.parseRelativeSize(w);
+        float relativeHeight = Util.parseRelativeSize(h);
+
+        if (relativeHeight >= 0.0 || relativeWidth >= 0.0) {
+            // One or both is relative
+            FloatSize relativeSize = new FloatSize(relativeWidth,
+                    relativeHeight);
+            componentRelativeSizes.put(component, relativeSize);
+            handleComponentRelativeSize(component);
+        } else if (relativeHeight < 0.0 && relativeWidth < 0.0) {
+            // No relative sizes
+            componentRelativeSizes.remove(component);
+        }
+
+        if (relativeHeight < 0.0) {
+            component.setHeight(h);
+        }
+        if (relativeWidth < 0.0) {
+            component.setWidth(w);
+        }
+    }
+
+    /**
+     * Traverses recursively ancestors until ContainerResizedListener child
+     * widget is found. They will delegate it further if needed.
+     * 
+     * @param container
+     */
+    public void runDescendentsLayout(HasWidgets container) {
+//        getConsole().log(
+//                "runDescendentsLayout("
+//                        + container.getClass().getName().replaceAll(
+//                                "[^\\.]*\\.", "") + "/" + container.hashCode()
+//                        + ")");
+        final Iterator childWidgets = container.iterator();
+        while (childWidgets.hasNext()) {
+            final Widget child = (Widget) childWidgets.next();
+
+            if (child instanceof Paintable) {
+                handleComponentRelativeSize(child);
+            }
+
+            if (child instanceof ContainerResizedListener) {
+                ((ContainerResizedListener) child).iLayout();
+            } else if (child instanceof HasWidgets) {
+                final HasWidgets childContainer = (HasWidgets) child;
+                runDescendentsLayout(childContainer);
+            }
+
+        }
+    }
+
+    public void handleComponentRelativeSize(Widget child) {
+        Widget widget = child;
+        FloatSize relativeSize = componentRelativeSizes.get(widget);
+        if (relativeSize == null) {
+            return;
+        }
+
+        Size availPixels = Util.getLayout(widget).getAllocatedSpace(widget);
+        if (relativeSize.getWidth() >= 0) {
+
+            if (availPixels != null) {
+
+                int width = availPixels.getWidth();
+                width *= relativeSize.getWidth() / 100.0;
+
+                if (width >= 0) {
+//                    getConsole().log(
+//                            "Widget " + widget.getClass().getName() + "/"
+//                                    + widget.hashCode() + " relative width "
+//                                    + relativeSize.getWidth() + "%: " + width
+//                                    + "px");
+                    widget.setWidth(width + "px");
+                }
+            } else {
+                widget.setWidth(relativeSize.getWidth() + "%");
+                ApplicationConnection.getConsole().error(
+                        Util.getLayout(widget).getClass().getName()
+                                + " did not produce allocatedSpace for "
+                                + widget.getClass().getName());
+            }
+        }
+        if (relativeSize.getHeight() >= 0) {
+            if (availPixels != null) {
+
+                int height = availPixels.getHeight();
+                height *= relativeSize.getHeight() / 100.0;
+
+                if (height >= 0) {
+//                    getConsole().log(
+//                            "Widget " + widget.getClass().getName() + "/"
+//                                    + widget.hashCode() + " relative height "
+//                                    + relativeSize.getHeight() + "%: " + height
+//                                    + "px");
+                    widget.setHeight(height + "px");
+                }
+            } else {
+                widget.setHeight(relativeSize.getHeight() + "%");
+                ApplicationConnection.getConsole().error(
+                        Util.getLayout(widget).getClass().getName()
+                                + " did not produce allocatedSpace for "
+                                + widget.getClass().getName());
+            }
+        }
+
     }
 
     /**
@@ -1062,7 +1188,7 @@ public class ApplicationConnection {
      * 
      */
     public TooltipInfo getTitleInfo(Paintable titleOwner) {
-        TooltipInfo info = (TooltipInfo) paintableToTitle.get(titleOwner);
+        TooltipInfo info = paintableToTitle.get(titleOwner);
         if (info == null) {
             info = new TooltipInfo();
             paintableToTitle.put(titleOwner, info);
@@ -1119,7 +1245,7 @@ public class ApplicationConnection {
         public void run() {
             getConsole().log(
                     "Running re-layout of " + view.getClass().getName());
-            Util.runDescendentsLayout(view);
+            runDescendentsLayout(view);
             isPending = false;
         }
     };
index 8675a0cb5523749c7fa23fdbd2cd17c0fe9b1af8..f6303c584c6a7b8187c373c7746f4fef85c9493f 100644 (file)
@@ -4,7 +4,10 @@
 
 package com.itmill.toolkit.terminal.gwt.client;
 
+import java.util.Set;
+
 import com.google.gwt.user.client.ui.Widget;
+import com.itmill.toolkit.terminal.gwt.client.RenderInformation.Size;
 
 public interface Container extends Paintable {
 
@@ -53,8 +56,19 @@ public interface Container extends Paintable {
      * Called when a child components size has been updated in the rendering
      * phase.
      * 
+     * @param child
+     *            Set of child widgets whose size have changed
      * @return true if the size of the Container remains the same, false if the
      *         event need to be propagated to the Containers parent
      */
-    boolean childComponentSizesUpdated();
+    boolean requestLayout(Set<Paintable> child);
+
+    /**
+     * Returns the size currently allocated for the child component.
+     * 
+     * @param child
+     * @return
+     */
+    Size getAllocatedSpace(Widget child);
+
 }
index 0ad667782bf1d2ff63d7903c6f45671e5e2d6ca2..f762caa368bd448ee9c73ed9b458f0a0936beb4c 100644 (file)
@@ -16,17 +16,6 @@ public interface ContainerResizedListener {
      * container has resized. runAnchestorsLayout(HasWidgets parent) function
      * from Util class may be a good helper for this.
      * 
-     * The width and height parameters specifies the space available for the
-     * component (in pixels) if the parent container can or want to produce
-     * these numbers. If the parent container does not know (has not calculated)
-     * or cannot produce (undefined dimensions) one of these numbers -1 is
-     * passed.
-     * 
-     * Note that these numbers should not be considered the maximum size for the
-     * widget if the layout has undefined dimension. In that case the currently
-     * allocated space is passed (eg. OrderedLayout with undefined width might
-     * pass availableWidth 100 if the widest component in the layout is 100 but
-     * it will still stretch if another 200 pixel wide component is rendered)
      */
-    public void iLayout(int availableWidth, int availableHeight);
+    public void iLayout();
 }
index fb2a2e51f45a8d7c163c0fbf1ed5737ba7de6c79..644d05c5edfb772c45e67dd0d4f5652efd05353d 100644 (file)
@@ -8,6 +8,7 @@ import com.google.gwt.user.client.DOM;
 import com.google.gwt.user.client.Element;
 import com.google.gwt.user.client.Event;
 import com.google.gwt.user.client.ui.HTML;
+import com.itmill.toolkit.terminal.gwt.client.RenderInformation.Size;
 import com.itmill.toolkit.terminal.gwt.client.ui.Icon;
 
 public class ICaption extends HTML {
@@ -28,6 +29,8 @@ public class ICaption extends HTML {
 
     private boolean placedAfterComponent = false;
 
+    private Size requiredSpace = new Size(0, 0);
+
     /**
      * 
      * @param component
@@ -138,6 +141,8 @@ public class ICaption extends HTML {
 
         }
 
+        requiredSpace.setWidth(getOffsetWidth());
+        requiredSpace.setHeight(getOffsetHeight());
     }
 
     public void onBrowserEvent(Event event) {
@@ -177,4 +182,42 @@ public class ICaption extends HTML {
     public boolean shouldBePlacedAfterComponent() {
         return placedAfterComponent;
     }
+
+    public Size getRequiredSpace() {
+        return requiredSpace;
+    }
+
+    public int getWidth() {
+        int width = 0;
+        if (icon != null) {
+            width += icon.getOffsetWidth();
+        }
+        if (captionText != null) {
+            width += captionText.getOffsetWidth();
+        }
+        if (requiredFieldIndicator != null) {
+            width += requiredFieldIndicator.getOffsetWidth();
+        }
+        if (errorIndicatorElement != null) {
+            width += errorIndicatorElement.getOffsetWidth();
+        }
+
+        if (BrowserInfo.get().isIE6() && shouldBePlacedAfterComponent()) {
+            // FIXME: Should find out what the real issue is
+            // Workaround for IE6 weirdness
+            width += 3;
+        }
+
+        return width;
+
+    }
+
+    public int getHeight() {
+        return getOffsetHeight();
+    }
+
+    public void setAlignment(String alignment) {
+        DOM.setStyleAttribute(getElement(), "textAlign", alignment);
+
+    }
 }
diff --git a/src/com/itmill/toolkit/terminal/gwt/client/RenderInformation.java b/src/com/itmill/toolkit/terminal/gwt/client/RenderInformation.java
new file mode 100644 (file)
index 0000000..060d704
--- /dev/null
@@ -0,0 +1,122 @@
+package com.itmill.toolkit.terminal.gwt.client;\r
+\r
+import com.google.gwt.user.client.Element;\r
+\r
+/**\r
+ * Contains size information about a rendered container and its content area.\r
+ * \r
+ * @author Artur Signell\r
+ * \r
+ */\r
+public class RenderInformation {\r
+\r
+    private Size contentArea = new Size(0, 0);\r
+    private Size renderedSize = new Size(-1, -1);\r
+\r
+    public void setContentAreaWidth(int w) {\r
+        contentArea.setWidth(w);\r
+    }\r
+\r
+    public void setContentAreaHeight(int h) {\r
+        contentArea.setHeight(h);\r
+    }\r
+\r
+    public Size getContentAreaSize() {\r
+        return contentArea;\r
+\r
+    }\r
+\r
+    public Size getRenderedSize() {\r
+        return renderedSize;\r
+    }\r
+\r
+    /**\r
+     * Update the size of the widget.\r
+     * \r
+     * @param widget\r
+     * \r
+     * @return true if the size has changed since last update\r
+     */\r
+    public boolean updateSize(Element element) {\r
+        Size newSize = new Size(element.getOffsetWidth(), element\r
+                .getOffsetHeight());\r
+        if (newSize.equals(renderedSize)) {\r
+            return false;\r
+        } else {\r
+            renderedSize = newSize;\r
+            return true;\r
+        }\r
+    }\r
+\r
+    @Override\r
+    public String toString() {\r
+        return "RenderInformation [contentArea=" + contentArea\r
+                + ",renderedSize=" + renderedSize + "]";\r
+\r
+    }\r
+\r
+    public static class FloatSize {\r
+\r
+        private float width, height;\r
+\r
+        public FloatSize(float width, float height) {\r
+            this.width = width;\r
+            this.height = height;\r
+        }\r
+\r
+        public float getWidth() {\r
+            return width;\r
+        }\r
+\r
+        public void setWidth(float width) {\r
+            this.width = width;\r
+        }\r
+\r
+        public float getHeight() {\r
+            return height;\r
+        }\r
+\r
+        public void setHeight(float height) {\r
+            this.height = height;\r
+        }\r
+\r
+    }\r
+\r
+    public static class Size {\r
+\r
+        private int width, height;\r
+\r
+        @Override\r
+        public boolean equals(Object obj) {\r
+            Size other = (Size) obj;\r
+            return other.width == width && other.height == height;\r
+        }\r
+\r
+        public Size(int width, int height) {\r
+            this.height = height;\r
+            this.width = width;\r
+        }\r
+\r
+        public int getWidth() {\r
+            return width;\r
+        }\r
+\r
+        public void setWidth(int width) {\r
+            this.width = width;\r
+        }\r
+\r
+        public int getHeight() {\r
+            return height;\r
+        }\r
+\r
+        public void setHeight(int height) {\r
+            this.height = height;\r
+        }\r
+\r
+        @Override\r
+        public String toString() {\r
+            return "Size [width=" + width + ",height=" + height + "]";\r
+        }\r
+    }\r
+\r
+}\r
index 164d3e0d32152ec92233ec888efc9878f807e733..396a2fd3260383d1012bfa09cf8a940ec0bca2c6 100644 (file)
@@ -4,13 +4,13 @@
 
 package com.itmill.toolkit.terminal.gwt.client;
 
+import java.util.HashMap;
 import java.util.HashSet;
-import java.util.Iterator;
+import java.util.Map;
 import java.util.Set;
 
 import com.google.gwt.user.client.DOM;
 import com.google.gwt.user.client.Element;
-import com.google.gwt.user.client.ui.HasWidgets;
 import com.google.gwt.user.client.ui.Widget;
 
 public class Util {
@@ -50,7 +50,7 @@ public class Util {
             return;
         }
 
-        Set<Container> parents = new HashSet<Container>();
+        Map<Container, Set<Paintable>> childWidgets = new HashMap<Container, Set<Paintable>>();
 
         for (Widget widget : widgets) {
             Widget parent = widget.getParent();
@@ -58,13 +58,18 @@ public class Util {
                 parent = parent.getParent();
             }
             if (parent != null) {
-                parents.add((Container) parent);
+                Set<Paintable> set = childWidgets.get(parent);
+                if (set == null) {
+                    set = new HashSet<Paintable>();
+                    childWidgets.put((Container) parent, set);
+                }
+                set.add((Paintable) widget);
             }
         }
 
         Set<Widget> parentChanges = new HashSet<Widget>();
-        for (Container parent : parents) {
-            if (!parent.childComponentSizesUpdated()) {
+        for (Container parent : childWidgets.keySet()) {
+            if (!parent.requestLayout(childWidgets.get(parent))) {
                 parentChanges.add((Widget) parent);
             }
         }
@@ -72,38 +77,19 @@ public class Util {
         componentSizeUpdated(parentChanges);
     }
 
-    /**
-     * Traverses recursively ancestors until ContainerResizedListener child
-     * widget is found. They will delegate it futher if needed.
-     * 
-     * @param container
-     */
-    public static void runDescendentsLayout(HasWidgets container) {
-        final Iterator childWidgets = container.iterator();
-        while (childWidgets.hasNext()) {
-            final Widget child = (Widget) childWidgets.next();
-            if (child instanceof ContainerResizedListener) {
-                int w = -1, h = -1;
-
-                if (container instanceof WidgetSpaceAllocator) {
-                    w = ((WidgetSpaceAllocator) container)
-                            .getAllocatedWidth(child);
-                    h = ((WidgetSpaceAllocator) container)
-                            .getAllocatedHeight(child);
-                }
-
-                ((ContainerResizedListener) child).iLayout(w, h);
-            } else if (child instanceof HasWidgets) {
-                final HasWidgets childContainer = (HasWidgets) child;
-                runDescendentsLayout(childContainer);
-            }
+    public static float parseRelativeSize(String size) {
+        if (size == null || !size.endsWith("%")) {
+            return -1;
         }
-    }
 
-    public interface WidgetSpaceAllocator {
-        int getAllocatedWidth(Widget child);
+        try {
+            return Float.parseFloat(size.substring(0, size.length() - 1));
+        } catch (Exception e) {
+            ClientExceptionHandler.displayError(
+                    "Unable to parse relative size", e);
+        }
 
-        int getAllocatedHeight(Widget child);
+        return -1;
     }
 
     /**
@@ -113,12 +99,14 @@ public class Util {
      * @param component
      * @return closest parent Container
      */
-    public static Container getParentLayout(Widget component) {
+    public static Container getLayout(Widget component) {
         Widget parent = component.getParent();
         while (parent != null && !(parent instanceof Container)) {
             parent = parent.getParent();
         }
-        if (parent != null && ((Container) parent).hasChildComponent(component)) {
+        if (parent != null) {
+            assert ((Container) parent).hasChildComponent(component);
+
             return (Container) parent;
         }
         return null;
index e08cb19c7e4f67585a05ca022d48e78fcc778bcc..b09b8510511057ef843e3849d8fa180d2534b8f9 100644 (file)
@@ -19,7 +19,7 @@ import com.itmill.toolkit.terminal.gwt.client.ContainerResizedListener;
 import com.itmill.toolkit.terminal.gwt.client.ICaption;
 import com.itmill.toolkit.terminal.gwt.client.Paintable;
 import com.itmill.toolkit.terminal.gwt.client.UIDL;
-import com.itmill.toolkit.terminal.gwt.client.Util;
+import com.itmill.toolkit.terminal.gwt.client.RenderInformation.Size;
 
 public class IAccordion extends ITabsheetBase implements
         ContainerResizedListener {
@@ -128,11 +128,7 @@ public class IAccordion extends ITabsheetBase implements
         super.setHeight(height);
     }
 
-    private void iLayout() {
-        iLayout(-1, -1);
-    }
-
-    public void iLayout(int availableWidth, int availableHeight) {
+    public void iLayout() {
         StackItem item = getSelectedStack();
         if (item == null) {
             return;
@@ -160,7 +156,7 @@ public class IAccordion extends ITabsheetBase implements
             item.setHeight("");
         }
 
-        Util.runDescendentsLayout(item);
+        client.runDescendentsLayout(item);
     }
 
     /**
@@ -334,9 +330,14 @@ public class IAccordion extends ITabsheetBase implements
         }
     }
 
-    public boolean childComponentSizesUpdated() {
+    public boolean requestLayout(Set<Paintable> child) {
         // TODO Auto-generated method stub
         return false;
     }
 
+    public Size getAllocatedSpace(Widget child) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
 }
index 561e7cb787f762fb42ffc337322c650354ba08d6..15641acff81fc6883030142c1a5e67d699e0b748 100644 (file)
@@ -18,6 +18,8 @@ import com.itmill.toolkit.terminal.gwt.client.UIDL;
 
 public class IButton extends Button implements Paintable {
 
+    private String width = null;
+
     public static final String CLASSNAME = "i-button";
 
     String id;
@@ -108,20 +110,6 @@ public class IButton extends Button implements Paintable {
         }
     }
 
-    public void setStyleName(String style) {
-        super.setStyleName(style);
-        if (BrowserInfo.get().isIE7()) {
-            /*
-             * Workaround for IE7 bug (#2014) where button width is growing when
-             * changing styles
-             */
-            Element e = getElement();
-            String w = DOM.getStyleAttribute(e, "width");
-            DOM.setStyleAttribute(e, "width", "1px");
-            DOM.setStyleAttribute(e, "width", w);
-        }
-    }
-
     public void setText(String text) {
         DOM.setInnerText(captionElement, text);
     }
@@ -150,4 +138,26 @@ public class IButton extends Button implements Paintable {
         }
     }
 
+    @Override
+    public void setWidth(String width) {
+        /* Workaround for IE7 button size part 1 (#2014) */
+        if (BrowserInfo.get().isIE7() && this.width != null) {
+            if (this.width.equals(width)) {
+                return;
+            }
+
+            if (width == null) {
+                width = "";
+            }
+        }
+
+        this.width = width;
+        super.setWidth(width);
+
+        /* Workaround for IE7 button size part 2 (#2014) */
+        if (BrowserInfo.get().isIE7()) {
+            super.setWidth(width);
+        }
+    }
+
 }
index 93b0fcbf0eaa20722b494e2c3511e5a6d43110b6..233f30f5a2dde0403bcb690bc3b114ae3ada096c 100644 (file)
@@ -3,6 +3,7 @@ package com.itmill.toolkit.terminal.gwt.client.ui;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.Iterator;
+import java.util.Set;
 
 import com.google.gwt.core.client.GWT;
 import com.google.gwt.user.client.DOM;
@@ -18,11 +19,10 @@ import com.itmill.toolkit.terminal.gwt.client.ContainerResizedListener;
 import com.itmill.toolkit.terminal.gwt.client.ICaption;
 import com.itmill.toolkit.terminal.gwt.client.Paintable;
 import com.itmill.toolkit.terminal.gwt.client.UIDL;
-import com.itmill.toolkit.terminal.gwt.client.Util;
-import com.itmill.toolkit.terminal.gwt.client.Util.WidgetSpaceAllocator;
+import com.itmill.toolkit.terminal.gwt.client.RenderInformation.Size;
 
 public class ICoordinateLayout extends ComplexPanel implements Container,
-        ContainerResizedListener, WidgetSpaceAllocator {
+        ContainerResizedListener {
 
     /** Class name, prefix in styling */
     public static final String CLASSNAME = "i-coordinatelayout";
@@ -222,7 +222,7 @@ public class ICoordinateLayout extends ComplexPanel implements Container,
         if (!toUpdate.isEmpty()) {
 
             // Run layout functions for children
-            Util.runDescendentsLayout(this);
+            client.runDescendentsLayout(this);
 
             // Go over all children and calculate their positions
             for (Iterator<Widget> componentIterator = toUpdate.iterator(); componentIterator
@@ -230,9 +230,9 @@ public class ICoordinateLayout extends ComplexPanel implements Container,
 
                 Widget componentWidget = componentIterator.next();
                 CustomCaption componentHeader = componentToHeader
-                        .get((Paintable) componentWidget);
+                        .get(componentWidget);
                 CustomCaption componentMarker = componentToMarker
-                        .get((Paintable) componentWidget);
+                        .get(componentWidget);
 
                 // Reset position info
                 resetPositionAttributes(componentWidget);
@@ -360,8 +360,8 @@ public class ICoordinateLayout extends ComplexPanel implements Container,
         resetPositionAttributes(w);
         Element widgetElement = w.getElement();
         Element areaElement;
-        CustomCaption componentHeader = componentToHeader.get((Paintable) w);
-        CustomCaption componentMarker = componentToMarker.get((Paintable) w);
+        CustomCaption componentHeader = componentToHeader.get(w);
+        CustomCaption componentMarker = componentToMarker.get(w);
 
         // Attach the widget to the sides of the surrounding area element
         if (sidesToAttach[TOP] || sidesToAttach[HEIGHT]) {
@@ -536,7 +536,7 @@ public class ICoordinateLayout extends ComplexPanel implements Container,
             DOM.appendChild(areaElement, c.getElement());
         }
 
-        resetPositionAttributes((Widget) c);
+        resetPositionAttributes(c);
 
         parentTop = getPositionValue(parentElement, "top");
         parentRight = getPositionValue(parentElement, "right");
@@ -591,12 +591,12 @@ public class ICoordinateLayout extends ComplexPanel implements Container,
         componentToZ.put(component, new Integer(zIndex));
 
         // Set caption z-index (same as parent components z)
-        if (componentToHeader.get((Paintable) component) != null) {
-            CustomCaption h = componentToHeader.get((Paintable) component);
+        if (componentToHeader.get(component) != null) {
+            CustomCaption h = componentToHeader.get(component);
             DOM.setStyleAttribute(h.getElement(), "zIndex", "" + zIndex);
         }
-        if (componentToMarker.get((Paintable) component) != null) {
-            CustomCaption m = componentToMarker.get((Paintable) component);
+        if (componentToMarker.get(component) != null) {
+            CustomCaption m = componentToMarker.get(component);
             DOM.setStyleAttribute(m.getElement(), "zIndex", "" + zIndex);
         }
     }
@@ -680,10 +680,10 @@ public class ICoordinateLayout extends ComplexPanel implements Container,
                 float multiplier = (float) relative[i] / 100;
 
                 if (i == LEFT || i == RIGHT || i == WIDTH) {
-                    float width = (float) layout[WIDTH];
+                    float width = layout[WIDTH];
                     relative[i] = (int) (width * multiplier);
                 } else {
-                    float height = (float) layout[HEIGHT];
+                    float height = layout[HEIGHT];
                     relative[i] = (int) (height * multiplier);
                 }
             }
@@ -703,9 +703,8 @@ public class ICoordinateLayout extends ComplexPanel implements Container,
         newSize[TOP] = marginInfo.hasTop() ? margins[0] : 0;
         newSize[BOTTOM] = marginInfo.hasBottom() ? margins[2] : 0;
         newSize[RIGHT] = marginInfo.hasRight() ? margins[1] : 0;
-        newSize[WIDTH] = this.getOffsetWidth() - newSize[LEFT] - newSize[RIGHT];
-        newSize[HEIGHT] = this.getOffsetHeight() - newSize[TOP]
-                - newSize[BOTTOM];
+        newSize[WIDTH] = getOffsetWidth() - newSize[LEFT] - newSize[RIGHT];
+        newSize[HEIGHT] = getOffsetHeight() - newSize[TOP] - newSize[BOTTOM];
 
         return newSize;
     }
@@ -801,7 +800,7 @@ public class ICoordinateLayout extends ComplexPanel implements Container,
         String[] cssValues = new String[cssProperties.length];
 
         Element e = DOM.createDiv();
-        DOM.appendChild(this.getElement(), e);
+        DOM.appendChild(getElement(), e);
         DOM.setStyleAttribute(e, "position", "absolute");
         DOM.setStyleAttribute(e, "height", "100px");
         DOM.setStyleAttribute(e, "width", "100px");
@@ -853,7 +852,7 @@ public class ICoordinateLayout extends ComplexPanel implements Container,
                 margins[i] = 0;
             }
         }
-        DOM.removeChild(this.getElement(), e);
+        DOM.removeChild(getElement(), e);
         return margins;
     }
 
@@ -870,8 +869,8 @@ public class ICoordinateLayout extends ComplexPanel implements Container,
      * @return
      */
     protected native String getMargin(Element e, String CSSProp)/*-{
-                                                                                                                                                                                                                                                                                                                                                                                                        return $wnd.getComputedStyle(e,null).getPropertyValue(CSSProp);
-                                                                                                                                                                                                                                                                                                                                                                                                        }-*/;
+                                                                                                                                                                                                                                                                                                                                                                                                                            return $wnd.getComputedStyle(e,null).getPropertyValue(CSSProp);
+                                                                                                                                                                                                                                                                                                                                                                                                                            }-*/;
 
     /**
      * Retrieves margin info in IE
@@ -880,8 +879,8 @@ public class ICoordinateLayout extends ComplexPanel implements Container,
      * @return
      */
     protected native String getIEMargin(Element e)/*-{ 
-                                                                                                                                                                                                                                                                                                                                                                                                        return e.currentStyle.margin;
-                                                                                                                                                                                                                                                                                                                                                                                                        }-*/;
+                                                                                                                                                                                                                                                                                                                                                                                                                            return e.currentStyle.margin;
+                                                                                                                                                                                                                                                                                                                                                                                                                            }-*/;
 
     /**
      * @return all components that are not captions
@@ -968,7 +967,7 @@ public class ICoordinateLayout extends ComplexPanel implements Container,
 
             // If removing a component, remove its area
             if (!(w instanceof CustomCaption)) {
-                DOM.removeChild(this.getElement(), componentToArea.get(w));
+                DOM.removeChild(getElement(), componentToArea.get(w));
             }
 
             componentList.remove(w);
@@ -978,24 +977,6 @@ public class ICoordinateLayout extends ComplexPanel implements Container,
         return wasRemoved;
     }
 
-    public int getAllocatedHeight(Widget child) {
-        Element area = componentToArea.get(child);
-        if (area != null) {
-            return area.getOffsetHeight();
-        } else {
-            return layout[HEIGHT];
-        }
-    }
-
-    public int getAllocatedWidth(Widget child) {
-        Element area = componentToArea.get(child);
-        if (area != null) {
-            return area.getOffsetWidth();
-        } else {
-            return layout[WIDTH];
-        }
-    }
-
     /**
      * Custom caption class to encapsulate different caption parts
      */
@@ -1162,4 +1143,23 @@ public class ICoordinateLayout extends ComplexPanel implements Container,
         }
     }
 
+    public Size getAllocatedSpace(Widget child) {
+        Element area = componentToArea.get(child);
+        if (area != null) {
+            return new Size(area.getOffsetWidth(), area.getOffsetHeight());
+        } else {
+            return new Size(layout[WIDTH], layout[HEIGHT]);
+        }
+    }
+
+    public boolean requestLayout(Set<Paintable> child) {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    public void iLayout() {
+        // TODO Auto-generated method stub
+
+    }
+
 }// class ICoordinateLayout
index 3de0b5761ad1bcbe757c8c51050b2c5dde297d53..207005635f0e237e0c859f4e7f20ff9082a584ec 100644 (file)
@@ -4,12 +4,15 @@
 
 package com.itmill.toolkit.terminal.gwt.client.ui;
 
+import java.util.Set;
+
 import com.google.gwt.user.client.ui.SimplePanel;
 import com.google.gwt.user.client.ui.Widget;
 import com.itmill.toolkit.terminal.gwt.client.ApplicationConnection;
 import com.itmill.toolkit.terminal.gwt.client.Container;
 import com.itmill.toolkit.terminal.gwt.client.Paintable;
 import com.itmill.toolkit.terminal.gwt.client.UIDL;
+import com.itmill.toolkit.terminal.gwt.client.RenderInformation.Size;
 
 public class ICustomComponent extends SimplePanel implements Container {
 
@@ -61,9 +64,16 @@ public class ICustomComponent extends SimplePanel implements Container {
         // TODO custom component could handle its composition roots caption
     }
 
-    public boolean childComponentSizesUpdated() {
+    public boolean requestLayout(Set<Paintable> child) {
         // TODO Auto-generated method stub
         return false;
     }
 
+    public Size getAllocatedSpace(Widget child) {
+        Size space = new Size(getElement().getOffsetWidth(), getElement()
+                .getOffsetHeight());
+
+        return space;
+    }
+
 }
index 9307b31ffa77214b206eb6595c7f6377f689b02e..c5a73c788dcf0a331e132fcf527370ed2d97eedd 100644 (file)
@@ -20,7 +20,7 @@ import com.itmill.toolkit.terminal.gwt.client.ICaption;
 import com.itmill.toolkit.terminal.gwt.client.ICaptionWrapper;
 import com.itmill.toolkit.terminal.gwt.client.Paintable;
 import com.itmill.toolkit.terminal.gwt.client.UIDL;
-import com.itmill.toolkit.terminal.gwt.client.Util;
+import com.itmill.toolkit.terminal.gwt.client.RenderInformation.Size;
 
 /**
  * Custom Layout implements complex layout defined with HTML template.
@@ -412,13 +412,9 @@ public class ICustomLayout extends ComplexPanel implements Paintable,
         widgetToCaptionWrapper.clear();
     }
 
-    private void iLayout() {
-        iLayout(-1, -1);
-    }
-
-    public void iLayout(int availableWidth, int availableHeight) {
+    public void iLayout() {
         if (!iLayoutJS(DOM.getFirstChild(getElement()))) {
-            Util.runDescendentsLayout(this);
+            client.runDescendentsLayout(this);
         }
     }
 
@@ -428,7 +424,7 @@ public class ICustomLayout extends ComplexPanel implements Paintable,
      * containers in custom layout he/she can notify children after resize.
      */
     public void notifyChildrenOfSizeChange() {
-        Util.runDescendentsLayout(this);
+        client.runDescendentsLayout(this);
     }
 
     public void onDetach() {
@@ -477,9 +473,14 @@ public class ICustomLayout extends ComplexPanel implements Paintable,
        }
     }-*/;
 
-    public boolean childComponentSizesUpdated() {
+    public boolean requestLayout(Set<Paintable> child) {
         // TODO Auto-generated method stub
         return false;
     }
 
+    public Size getAllocatedSpace(Widget child) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
 }
index ce128de91b359b6b6a21650ee90377cd544932bf..6ec950c5f06c1b71fdc2ffb7ddab1e091f96c9a3 100644 (file)
@@ -7,6 +7,7 @@ package com.itmill.toolkit.terminal.gwt.client.ui;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.Iterator;
+import java.util.Set;
 
 import com.google.gwt.user.client.Command;
 import com.google.gwt.user.client.DOM;
@@ -22,9 +23,10 @@ import com.itmill.toolkit.terminal.gwt.client.Container;
 import com.itmill.toolkit.terminal.gwt.client.ContainerResizedListener;
 import com.itmill.toolkit.terminal.gwt.client.ICaption;
 import com.itmill.toolkit.terminal.gwt.client.Paintable;
+import com.itmill.toolkit.terminal.gwt.client.RenderInformation;
 import com.itmill.toolkit.terminal.gwt.client.StyleConstants;
 import com.itmill.toolkit.terminal.gwt.client.UIDL;
-import com.itmill.toolkit.terminal.gwt.client.Util;
+import com.itmill.toolkit.terminal.gwt.client.RenderInformation.Size;
 
 /**
  * @author IT Mill Ltd
@@ -51,15 +53,15 @@ public class IExpandLayout extends ComplexPanel implements
      */
     protected Element childContainer;
 
-    protected ApplicationConnection client;
+    protected ApplicationConnection client = null;
 
-    protected HashMap componentToCaption = new HashMap();
+    protected HashMap<Paintable, ICaption> componentToCaption = new HashMap<Paintable, ICaption>();
 
     /*
      * Elements that provides the Layout interface implementation.
      */
     protected Element element;
-    private Widget expandedWidget;
+    private Widget expandedWidget = null;
 
     private UIDL expandedWidgetUidl;
 
@@ -75,6 +77,9 @@ public class IExpandLayout extends ComplexPanel implements
     private int spacingSize = -1;
     private boolean rendering;
 
+    private RenderInformation renderInformation = new RenderInformation();
+    private int spaceForExpandedWidget;
+
     public IExpandLayout() {
         this(IExpandLayout.ORIENTATION_VERTICAL);
     }
@@ -373,11 +378,9 @@ public class IExpandLayout extends ComplexPanel implements
         return getWidgetIndex(component) >= 0;
     }
 
-    private void iLayout() {
-        iLayout(-1, -1);
-    }
+    public void iLayout() {
+        renderInformation.updateSize(getElement());
 
-    public void iLayout(int availableWidth, int availableHeight) {
         if (orientationMode == ORIENTATION_HORIZONTAL) {
             int pixels;
             if ("".equals(height)) {
@@ -408,9 +411,21 @@ public class IExpandLayout extends ComplexPanel implements
 
         final int availableSpace = getAvailableSpace();
 
+        // Cannot use root element for layout as it contains margins
+        Element expandElement = expandedWidget.getElement();
+        Element expandedParentElement = DOM.getParent(expandElement);
+        if (orientationMode == ORIENTATION_VERTICAL) {
+            renderInformation.setContentAreaWidth(expandedParentElement
+                    .getOffsetWidth());
+        } else {
+            renderInformation.setContentAreaHeight(expandedParentElement
+                    .getOffsetHeight());
+
+        }
+
         final int usedSpace = getUsedSpace();
 
-        int spaceForExpandedWidget = availableSpace - usedSpace;
+        spaceForExpandedWidget = availableSpace - usedSpace;
 
         if (spaceForExpandedWidget < EXPANDED_ELEMENTS_MIN_WIDTH) {
             // TODO fire warning for developer
@@ -437,15 +452,15 @@ public class IExpandLayout extends ComplexPanel implements
         }
 
         // setting overflow auto lazy off during layout function
-        DOM.setStyleAttribute(DOM.getParent(expandedWidget.getElement()),
-                "overflow", "hidden");
+        DOM.setStyleAttribute(expandedParentElement, "overflow", "hidden");
 
         // TODO save previous size and only propagate if really changed
-        Util.runDescendentsLayout(this);
+        if (client != null) {
+            client.runDescendentsLayout(this);
+        }
 
         // setting overflow back to auto
-        DOM.setStyleAttribute(DOM.getParent(expandedWidget.getElement()),
-                "overflow", "auto");
+        DOM.setStyleAttribute(expandedParentElement, "overflow", "auto");
 
     }
 
@@ -596,7 +611,7 @@ public class IExpandLayout extends ComplexPanel implements
     }
 
     public void removeCaption(Widget w) {
-        final ICaption c = (ICaption) componentToCaption.get(w);
+        final ICaption c = componentToCaption.get(w);
         if (c != null) {
             this.remove(c);
             componentToCaption.remove(w);
@@ -604,7 +619,7 @@ public class IExpandLayout extends ComplexPanel implements
     }
 
     public boolean removePaintable(Paintable p) {
-        final ICaption c = (ICaption) componentToCaption.get(p);
+        final ICaption c = componentToCaption.get(p);
         if (c != null) {
             componentToCaption.remove(c);
             remove(c);
@@ -618,7 +633,7 @@ public class IExpandLayout extends ComplexPanel implements
 
     public void replaceChildComponent(Widget from, Widget to) {
         client.unregisterPaintable((Paintable) from);
-        final ICaption c = (ICaption) componentToCaption.get(from);
+        final ICaption c = componentToCaption.get(from);
         if (c != null) {
             remove(c);
             componentToCaption.remove(c);
@@ -632,7 +647,7 @@ public class IExpandLayout extends ComplexPanel implements
 
     public void updateCaption(Paintable component, UIDL uidl) {
 
-        ICaption c = (ICaption) componentToCaption.get(component);
+        ICaption c = componentToCaption.get(component);
 
         boolean captionSizeMayHaveChanged = false;
         if (ICaption.isNeeded(uidl)) {
@@ -783,6 +798,14 @@ public class IExpandLayout extends ComplexPanel implements
             // functions
             DOM.setStyleAttribute(DOM.getParent(expandedWidget.getElement()),
                     "overflow", "auto");
+
+            /*
+             * If a caption has been added we need to recalculate the space
+             * available for the component
+             */
+            getWidgetWrapperFor(expandedWidget).setExpandedSize(
+                    spaceForExpandedWidget);
+
         }
 
         // workaround for safari bug #1870
@@ -797,9 +820,56 @@ public class IExpandLayout extends ComplexPanel implements
         rendering = false;
     }
 
-    public boolean childComponentSizesUpdated() {
-        // TODO Auto-generated method stub
-        return false;
+    public boolean requestLayout(Set<Paintable> child) {
+        if (height != null && width != null) {
+            /*
+             * If the height and width has been specified for this container the
+             * child components cannot make the size of the layout change
+             */
+
+            return true;
+        }
+
+        if (renderInformation.updateSize(getElement())) {
+            /*
+             * Size has changed so we let the child components know about the
+             * new size.
+             */
+            iLayout();
+
+            return false;
+        } else {
+            /*
+             * Size has not changed so we do not need to propagate the event
+             * further
+             */
+            return true;
+        }
+
+    }
+
+    public Size getAllocatedSpace(Widget child) {
+        int width = 0, height = 0;
+
+        if (orientationMode == ORIENTATION_HORIZONTAL) {
+            height = renderInformation.getContentAreaSize().getHeight();
+            if (child == expandedWidget) {
+                width = spaceForExpandedWidget;
+            }
+        } else {
+            // VERTICAL
+            width = renderInformation.getContentAreaSize().getWidth();
+            if (child == expandedWidget) {
+                height = spaceForExpandedWidget;
+
+                ICaption caption = componentToCaption.get(child);
+                if (caption != null) {
+                    height -= caption.getOffsetHeight();
+                }
+            }
+        }
+
+        return new Size(width, height);
     }
 
 }
index 596574dfe09e0d42d77e25fd9fbe9dd33229428c..c68d6c854a8fbeedb4552637d140838012ea5750 100644 (file)
@@ -4,21 +4,29 @@
 \r
 package com.itmill.toolkit.terminal.gwt.client.ui;\r
 \r
+import java.util.Set;\r
+\r
 import com.google.gwt.user.client.DOM;\r
 import com.google.gwt.user.client.Element;\r
 import com.google.gwt.user.client.ui.ComplexPanel;\r
 import com.google.gwt.user.client.ui.Widget;\r
 import com.itmill.toolkit.terminal.gwt.client.ApplicationConnection;\r
+import com.itmill.toolkit.terminal.gwt.client.ClientExceptionHandler;\r
 import com.itmill.toolkit.terminal.gwt.client.Container;\r
 import com.itmill.toolkit.terminal.gwt.client.ContainerResizedListener;\r
 import com.itmill.toolkit.terminal.gwt.client.IErrorMessage;\r
 import com.itmill.toolkit.terminal.gwt.client.Paintable;\r
+import com.itmill.toolkit.terminal.gwt.client.RenderInformation;\r
 import com.itmill.toolkit.terminal.gwt.client.UIDL;\r
-import com.itmill.toolkit.terminal.gwt.client.Util;\r
+import com.itmill.toolkit.terminal.gwt.client.RenderInformation.Size;\r
 \r
-public class IForm extends ComplexPanel implements Paintable,\r
+public class IForm extends ComplexPanel implements Container,\r
         ContainerResizedListener {\r
 \r
+    private String height;\r
+\r
+    private String width;\r
+\r
     public static final String CLASSNAME = "i-form";\r
 \r
     private Container lo;\r
@@ -35,6 +43,14 @@ public class IForm extends ComplexPanel implements Paintable,
 \r
     private Container footer;\r
 \r
+    private ApplicationConnection client;\r
+\r
+    private RenderInformation renderInformation = new RenderInformation();\r
+\r
+    private int borderPaddingHorizontal;\r
+\r
+    private int borderPaddingVertical;\r
+\r
     public IForm() {\r
         setElement(DOM.createFieldSet());\r
         setStyleName(CLASSNAME);\r
@@ -54,6 +70,8 @@ public class IForm extends ComplexPanel implements Paintable,
     }\r
 \r
     public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {\r
+        this.client = client;\r
+\r
         if (client.updateComponent(this, uidl, false)) {\r
             return;\r
         }\r
@@ -98,7 +116,7 @@ public class IForm extends ComplexPanel implements Paintable,
             DOM.setInnerHTML(desc, "");\r
         }\r
 \r
-        iLayout(-1, -1);\r
+        iLayout();\r
 \r
         final UIDL layoutUidl = uidl.getChildUIDL(0);\r
         Container newLo = (Container) client.getPaintable(layoutUidl);\r
@@ -135,8 +153,89 @@ public class IForm extends ComplexPanel implements Paintable,
         }\r
     }\r
 \r
-    public void iLayout(int availableWidth, int availableHeight) {\r
-        Util.runDescendentsLayout(this);\r
+    public void iLayout() {\r
+\r
+        renderInformation.updateSize(getElement());\r
+\r
+        renderInformation.setContentAreaHeight(renderInformation\r
+                .getRenderedSize().getHeight()\r
+                - borderPaddingVertical);\r
+        renderInformation.setContentAreaWidth(renderInformation\r
+                .getRenderedSize().getWidth()\r
+                - borderPaddingHorizontal);\r
+\r
+        client.runDescendentsLayout(this);\r
+    }\r
+\r
+    public Size getAllocatedSpace(Widget child) {\r
+        return renderInformation.getContentAreaSize();\r
+    }\r
+\r
+    public boolean hasChildComponent(Widget component) {\r
+        return component != null && (component == lo || component == footer);\r
+    }\r
+\r
+    public void replaceChildComponent(Widget oldComponent, Widget newComponent) {\r
+        // TODO Auto-generated method stub\r
+\r
+    }\r
+\r
+    public boolean requestLayout(Set<Paintable> child) {\r
+\r
+        if (height != null && width != null) {\r
+            /*\r
+             * If the height and width has been specified the child components\r
+             * cannot make the size of the layout change\r
+             */\r
+\r
+            return true;\r
+        }\r
+\r
+        if (renderInformation.updateSize(getElement())) {\r
+            return false;\r
+        } else {\r
+            return true;\r
+        }\r
+\r
+    }\r
+\r
+    public void updateCaption(Paintable component, UIDL uidl) {\r
+        // TODO Auto-generated method stub\r
+\r
     }\r
 \r
+    @Override\r
+    public void setHeight(String height) {\r
+        this.height = height;\r
+\r
+        super.setHeight(height);\r
+\r
+        if (height.endsWith("px")) {\r
+            try {\r
+                borderPaddingVertical = getElement().getOffsetHeight()\r
+                        - Integer.parseInt(height.substring(0,\r
+                                height.length() - 2));\r
+            } catch (Exception e) {\r
+                ClientExceptionHandler.displayError(e);\r
+            }\r
+        }\r
+\r
+    }\r
+\r
+    @Override\r
+    public void setWidth(String width) {\r
+        this.width = width;\r
+\r
+        super.setWidth(width);\r
+\r
+        if (width.endsWith("px")) {\r
+            try {\r
+                borderPaddingHorizontal = getElement().getOffsetWidth()\r
+                        - Integer.parseInt(width.substring(0,\r
+                                width.length() - 2));\r
+            } catch (Exception e) {\r
+                ClientExceptionHandler.displayError(e);\r
+            }\r
+        }\r
+    }\r
 }\r
index 0fe7226c4497f465dce5d0bdaa628cd3e20217ad..cbff24e00d81ef5ba8c6e091fcc6ecb878473b7a 100644 (file)
@@ -6,6 +6,7 @@ package com.itmill.toolkit.terminal.gwt.client.ui;
 
 import java.util.HashMap;
 import java.util.Iterator;
+import java.util.Set;
 
 import com.google.gwt.user.client.DOM;
 import com.google.gwt.user.client.Element;
@@ -19,6 +20,7 @@ import com.itmill.toolkit.terminal.gwt.client.Paintable;
 import com.itmill.toolkit.terminal.gwt.client.StyleConstants;
 import com.itmill.toolkit.terminal.gwt.client.UIDL;
 import com.itmill.toolkit.terminal.gwt.client.Util;
+import com.itmill.toolkit.terminal.gwt.client.RenderInformation.Size;
 
 /**
  * Two col Layout that places caption on left col and field on right col
@@ -302,9 +304,14 @@ public class IFormLayout extends FlexTable implements Container {
 
     }
 
-    public boolean childComponentSizesUpdated() {
+    public boolean requestLayout(Set<Paintable> child) {
         // TODO Auto-generated method stub
         return false;
     }
 
+    public Size getAllocatedSpace(Widget child) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
 }
index df86e676eb878ed9168d97e0276e8d4269b9b4b0..fba04b6d8ff8559c8966deedccf2aced77ca1f75 100644 (file)
@@ -7,6 +7,7 @@ package com.itmill.toolkit.terminal.gwt.client.ui;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.Iterator;
+import java.util.Set;
 
 import com.google.gwt.user.client.Command;
 import com.google.gwt.user.client.DOM;
@@ -27,7 +28,7 @@ import com.itmill.toolkit.terminal.gwt.client.ICaptionWrapper;
 import com.itmill.toolkit.terminal.gwt.client.Paintable;
 import com.itmill.toolkit.terminal.gwt.client.StyleConstants;
 import com.itmill.toolkit.terminal.gwt.client.UIDL;
-import com.itmill.toolkit.terminal.gwt.client.Util;
+import com.itmill.toolkit.terminal.gwt.client.RenderInformation.Size;
 
 public class IGridLayout extends SimplePanel implements Paintable, Container,
         ContainerResizedListener {
@@ -46,6 +47,8 @@ public class IGridLayout extends SimplePanel implements Paintable, Container,
 
     private String width;
 
+    private ApplicationConnection client;
+
     public IGridLayout() {
         super();
         DOM.appendChild(getElement(), margin);
@@ -69,6 +72,7 @@ public class IGridLayout extends SimplePanel implements Paintable, Container,
     }
 
     public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
+        this.client = client;
 
         if (client.updateComponent(this, uidl, true)) {
             return;
@@ -286,18 +290,19 @@ public class IGridLayout extends SimplePanel implements Paintable, Container,
             wrapper.updateCaption(uidl);
         }
 
-        public boolean childComponentSizesUpdated() {
+        public boolean requestLayout(Set<Paintable> child) {
             // TODO Auto-generated method stub
             return false;
         }
 
-    }
+        public Size getAllocatedSpace(Widget child) {
+            // TODO Auto-generated method stub
+            return null;
+        }
 
-    private void iLayout() {
-        iLayout(-1, -1);
     }
 
-    public void iLayout(int availableWidth, int availableHeight) {
+    public void iLayout() {
         if (needsLayout) {
             super.setWidth(width);
             if (meterElement == null) {
@@ -314,12 +319,17 @@ public class IGridLayout extends SimplePanel implements Paintable, Container,
         } else {
             grid.setWidth("");
         }
-        Util.runDescendentsLayout(this);
+        client.runDescendentsLayout(this);
     }
 
-    public boolean childComponentSizesUpdated() {
+    public boolean requestLayout(Set<Paintable> child) {
         // TODO Auto-generated method stub
         return false;
     }
 
+    public Size getAllocatedSpace(Widget child) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
 }
index 8c5daf45519cb8a71bd707c75a1ef5db6cb41e25..97de88939de5d627a3f4a7ec82bda29f5539478e 100644 (file)
@@ -6,6 +6,7 @@ package com.itmill.toolkit.terminal.gwt.client.ui;
 
 import java.util.HashMap;
 import java.util.Iterator;
+import java.util.Set;
 import java.util.Vector;
 
 import com.google.gwt.user.client.DOM;
@@ -18,9 +19,9 @@ import com.itmill.toolkit.terminal.gwt.client.Container;
 import com.itmill.toolkit.terminal.gwt.client.ContainerResizedListener;
 import com.itmill.toolkit.terminal.gwt.client.ICaption;
 import com.itmill.toolkit.terminal.gwt.client.Paintable;
+import com.itmill.toolkit.terminal.gwt.client.RenderInformation;
 import com.itmill.toolkit.terminal.gwt.client.UIDL;
-import com.itmill.toolkit.terminal.gwt.client.Util;
-import com.itmill.toolkit.terminal.gwt.client.Util.WidgetSpaceAllocator;
+import com.itmill.toolkit.terminal.gwt.client.RenderInformation.Size;
 
 /**
  * Full implementation of OrderedLayout client peer.
@@ -240,7 +241,7 @@ import com.itmill.toolkit.terminal.gwt.client.Util.WidgetSpaceAllocator;
  * @author IT Mill Ltd
  */
 public class IOrderedLayout extends Panel implements Container,
-        ContainerResizedListener, WidgetSpaceAllocator {
+        ContainerResizedListener {
 
     public static final String CLASSNAME = "i-orderedlayout";
 
@@ -320,9 +321,9 @@ public class IOrderedLayout extends Panel implements Container,
      */
     private boolean childLayoutsHaveChanged = false;
 
-    private int renderedHeight;
+    private boolean isRendering = false;
 
-    private int renderedWidth;
+    private RenderInformation renderInformation = new RenderInformation();
 
     /**
      * Construct the DOM of the orderder layout.
@@ -435,7 +436,7 @@ public class IOrderedLayout extends Panel implements Container,
 
     /** Update the contents of the layout from UIDL. */
     public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
-
+        isRendering = true;
         this.client = client;
 
         // Only non-cached UIDL:s can introduce changes
@@ -546,7 +547,7 @@ public class IOrderedLayout extends Panel implements Container,
         handleAlignmentsSpacingAndMargins(uidl);
 
         // Reset sizes for the children
-        updateChildSizes(-1, -1);
+        updateChildSizes();
 
         // Paint children
         for (int i = 0; i < childsToPaint.size(); i++) {
@@ -557,14 +558,17 @@ public class IOrderedLayout extends Panel implements Container,
         // Update child layouts
         // TODO This is most probably unnecessary and should be done within
         // update Child H/W
-        if (childLayoutsHaveChanged) {
-            Util.runDescendentsLayout(this);
-            childLayoutsHaveChanged = false;
-        }
+        // if (childLayoutsHaveChanged) {
+        // client.runDescendentsLayout(this);
+        // childLayoutsHaveChanged = false;
+        // }
 
         /* Store the rendered size so we later can see if it has changed */
-        renderedWidth = root.getOffsetWidth();
-        renderedHeight = root.getOffsetHeight();
+        if (renderInformation.updateSize(root)) {
+            client.runDescendentsLayout(this);
+        }
+
+        isRendering = false;
 
     }
 
@@ -650,11 +654,11 @@ public class IOrderedLayout extends Panel implements Container,
      */
     public void setWidth(String newWidth) {
 
-        width = newWidth == null || "".equals(newWidth) ? null : newWidth;
-
-        // As we use divs at root - for them using 100% width should be
-        // calculated with ""
-        super.setWidth("");
+        if (newWidth == null || newWidth.equals("")) {
+            width = null;
+        } else {
+            width = newWidth;
+        }
 
         // Update child layouts
         childLayoutsHaveChanged = true;
@@ -673,7 +677,7 @@ public class IOrderedLayout extends Panel implements Container,
     }
 
     /** Recalculate and apply the space given for each child in this layout. */
-    private void updateChildSizes(int renderedWidth, int renderedHeight) {
+    private void updateChildSizes() {
 
         int numChild = childWidgets.size();
         int childHeightTotal = -1;
@@ -684,39 +688,18 @@ public class IOrderedLayout extends Panel implements Container,
         // Vertical layout is calculated by us
         if (height != null) {
 
-            // Calculate the space for fixed contents minus marginals
-            if (tableMode) {
-
-                // If we know explicitly set pixel-size, use that
-                if (height.endsWith("px")) {
-                    try {
-                        childHeightTotal = Integer.parseInt(height.substring(0,
-                                height.length() - 2));
-
-                        // For negative sizes, use measurements
-                        if (childHeightTotal < 0) {
-                            childHeightTotal = rootOffsetMeasure("offsetHeight");
-                        }
-                    } catch (NumberFormatException e) {
-
-                        // In case of invalid number, try to measure the size;
-                        childHeightTotal = rootOffsetMeasure("offsetHeight");
-                    }
-                } else if (height.endsWith("%") && renderedHeight >= 0) {
-                    // If we have a relative height and know how large we are we
-                    // can
-                    // simply use that
-                    childWidthTotal = renderedHeight;
-                } else {
-                    // If not pixels, nor percentage, try to measure the size
-                    childHeightTotal = rootOffsetMeasure("offsetHeight");
-                }
-
+            if (height.endsWith("px")) {
+                childHeightTotal = Integer.parseInt(height.substring(0, height
+                        .length() - 2));
             } else {
-                childHeightTotal = DOM.getElementPropertyInt(getElement(),
-                        "offsetHeight");
+                // TODO This might be wrong but only reached if height is
+                // specified by other means than pixels or %
+                childHeightTotal = getElement().getOffsetHeight();
             }
 
+            // Calculate the space for fixed contents minus marginals
+            childHeightTotal = getElement().getOffsetHeight();
+
             childHeightTotal -= margins.hasTop() ? marginTop : 0;
             childHeightTotal -= margins.hasBottom() ? marginBottom : 0;
 
@@ -736,30 +719,13 @@ public class IOrderedLayout extends Panel implements Container,
         // layout is calculated by us
         if (width != null) {
 
-            // Calculate the space for fixed contents minus marginals
-            // If we know explicitly set pixel-size, use that
             if (width.endsWith("px")) {
-                try {
-                    childWidthTotal = Integer.parseInt(width.substring(0, width
-                            .length() - 2));
-
-                    // For negative sizes, use measurements
-                    if (childWidthTotal < 0) {
-                        childWidthTotal = rootOffsetMeasure("offsetWidth");
-                    }
-
-                } catch (NumberFormatException e) {
-
-                    // In case of invalid number, try to measure the size;
-                    childWidthTotal = rootOffsetMeasure("offsetWidth");
-                }
-            } else if (width.endsWith("%") && renderedWidth >= 0) {
-                // If we have a relative width and know how large we are we can
-                // simply use that
-                childWidthTotal = renderedWidth;
+                childWidthTotal = Integer.parseInt(width.substring(0, width
+                        .length() - 2));
             } else {
-                // If not pixels, nor percentage, try to measure the size
-                childWidthTotal = rootOffsetMeasure("offsetWidth");
+                // TODO This might be wrong but only reached if width is
+                // specified by other means than pixels or %
+                childWidthTotal = getElement().getOffsetWidth();
             }
 
             childWidthTotal -= margins.hasLeft() ? marginLeft : 0;
@@ -796,34 +762,8 @@ public class IOrderedLayout extends Panel implements Container,
             }
             WidgetWrapper ww = (WidgetWrapper) i.next();
             ww.forceSize(w, h);
-        }
-    }
 
-    /**
-     * Measure how much space the root element could get.
-     * 
-     * This measures the space allocated by the parent for the root element
-     * without letting root element to affect the calculation.
-     * 
-     * @param offset
-     *            offsetWidth or offsetHeight
-     */
-    private int rootOffsetMeasure(String offset) {
-        // TODO This method must be optimized!
-        Element measure = DOM.createDiv();
-        DOM.setStyleAttribute(measure, "height", "100%");
-        Element parent = DOM.getParent(getElement());
-        DOM.insertBefore(parent, measure, getElement());
-        // FIXME Do not detach from DOM this way. At least proper detach, attach
-        // must be called. Affects odd behavior in childs, performance issues
-        // and flickering. See #2102
-        DOM.removeChild(parent, getElement());
-        int size = DOM.getElementPropertyInt(measure, offset);
-        DOM.insertBefore(parent, getElement(), measure);
-        DOM.removeChild(parent, measure);
-        // In case the no space would be given for this element
-        // without pushing, use the current side of the root
-        return size;
+        }
     }
 
     /** Parse alignments from UIDL and pass whem to correct widgetwrappers */
@@ -885,6 +825,7 @@ public class IOrderedLayout extends Panel implements Container,
 
         /** Caption element when used. */
         ICaption caption = null;
+        Size captionSize = new Size(-1, -1);
 
         /**
          * Last set pixel height for the wrapper. -1 if vertical clipping is not
@@ -893,7 +834,7 @@ public class IOrderedLayout extends Panel implements Container,
         int lastForcedPixelHeight = -1;
 
         /**
-         * Last set pidel width for the wrapper. -1 if horizontal clipping is
+         * Last set pixel width for the wrapper. -1 if horizontal clipping is
          * not used.
          */
         int lastForcedPixelWidth = -1;
@@ -903,6 +844,10 @@ public class IOrderedLayout extends Panel implements Container,
         /** Widget Wrapper root element */
         Element wrapperElement;
 
+        private String horizontalAlignment = "left";
+
+        private String verticalAlignment = "top";
+
         /** Set the root element */
         public WidgetWrapper() {
             resetRootElement();
@@ -947,9 +892,15 @@ public class IOrderedLayout extends Panel implements Container,
             // Set size
             DOM.setStyleAttribute(e, "width", pixelWidth < 0 ? "" : pixelWidth
                     + "px");
-            DOM.setStyleAttribute(e, "height",
-                    pixelHeight < 0 ? (e == clipperDiv ? "100%" : "")
-                            : pixelHeight + "px");
+
+            if (pixelHeight >= 0) {
+                DOM.setStyleAttribute(e, "height", pixelHeight + "px");
+            } else {
+                if (e == clipperDiv && !BrowserInfo.get().isIE()) {
+                    DOM.setStyleAttribute(e, "height", "100%");
+                }
+
+            }
 
             // Set cached values
             lastForcedPixelWidth = pixelWidth;
@@ -960,23 +911,37 @@ public class IOrderedLayout extends Panel implements Container,
         private void createClipperDiv() {
             clipperDiv = DOM.createDiv();
             final Element e = getElementWrappingClipperDiv();
-            String classe = DOM.getElementAttribute(e, "class");
+            String clipperClass = "i-orderedlayout-cl-"
+                    + (orientationMode == ORIENTATION_HORIZONTAL ? "h" : "v");
+
+            String elementClass = e.getClassName();
+
+            if (elementClass != null && elementClass.length() > 0) {
+                clipperClass += " " + elementClass;
+            }
+
             while (DOM.getChildCount(e) > 0) {
                 final Element c = DOM.getFirstChild(e);
                 DOM.removeChild(e, c);
                 DOM.appendChild(clipperDiv, c);
             }
-            if (classe != null && classe.length() > 0) {
-                DOM.removeElementAttribute(e, "class");
-                DOM.setElementAttribute(clipperDiv, "class", classe);
+
+            if (elementClass != null && elementClass.length() > 0) {
+                e.setClassName("");
             }
+
             DOM.appendChild(e, clipperDiv);
+            clipperDiv.setClassName(clipperClass);
+
         }
 
         /** Undo createClipperDiv() */
         private void removeClipperDiv() {
             final Element e = getElementWrappingClipperDiv();
-            String classe = DOM.getElementAttribute(clipperDiv, "class");
+            String clipperClass = clipperDiv.getClassName();
+
+            String elementClass = clipperClass.replaceAll(
+                    "i-orderedlayout-cl-.", "").trim();
             while (DOM.getChildCount(clipperDiv) > 0) {
                 final Element c = DOM.getFirstChild(clipperDiv);
                 DOM.removeChild(clipperDiv, c);
@@ -984,8 +949,8 @@ public class IOrderedLayout extends Panel implements Container,
             }
             DOM.removeChild(e, clipperDiv);
             clipperDiv = null;
-            if (classe != null && classe.length() > 0) {
-                DOM.setElementAttribute(e, "class", classe);
+            if (elementClass != null && elementClass.length() > 0) {
+                e.setClassName(elementClass);
             }
         }
 
@@ -1082,6 +1047,7 @@ public class IOrderedLayout extends Panel implements Container,
             if (tableMode) {
                 if (orientationMode == ORIENTATION_HORIZONTAL) {
                     wrapperElement = DOM.createTD();
+                    DOM.setStyleAttribute(wrapperElement, "height", "100%");
                 } else {
                     wrapperElement = DOM.createTR();
                     DOM.appendChild(wrapperElement, DOM.createTD());
@@ -1105,6 +1071,8 @@ public class IOrderedLayout extends Panel implements Container,
             final Widget widget = (Widget) paintable;
             final Element captionWrapper = getElementWrappingWidgetAndCaption();
 
+            boolean captionDimensionOrPositionUpdated = false;
+
             // The widget needs caption
             if (ICaption.isNeeded(uidl)) {
 
@@ -1118,6 +1086,16 @@ public class IOrderedLayout extends Panel implements Container,
                 // Update caption contents
                 caption.updateCaption(uidl);
 
+                caption.setAlignment(horizontalAlignment);
+
+                int captionHeight = caption.getElement().getOffsetHeight();
+                int captionWidth = caption.getElement().getOffsetWidth();
+                if (captionHeight != captionSize.getHeight()
+                        || captionWidth != captionSize.getWidth()) {
+                    captionSize = new Size(captionWidth, captionHeight);
+                    captionDimensionOrPositionUpdated = true;
+                }
+
                 final boolean after = caption.shouldBePlacedAfterComponent();
                 final Element captionElement = caption.getElement();
                 final Element widgetElement = widget.getElement();
@@ -1135,6 +1113,7 @@ public class IOrderedLayout extends Panel implements Container,
                         DOM.insertChild(captionWrapper, captionElement, 0);
                     }
 
+                    captionDimensionOrPositionUpdated = true;
                 } else
 
                 // Caption exists. Move it to correct position if needed
@@ -1155,12 +1134,12 @@ public class IOrderedLayout extends Panel implements Container,
                         widget.removeStyleName("i-orderedlayout-w-e");
                         caption.removeStyleName("i-orderedlayout-w-c");
                     }
-                }
 
-            }
+                    captionDimensionOrPositionUpdated = true;
+                }
 
-            // Caption is not needed
-            else {
+            } else {
+                // Caption is not needed
 
                 // Remove existing caption from DOM
                 if (caption != null) {
@@ -1168,14 +1147,22 @@ public class IOrderedLayout extends Panel implements Container,
                     caption = null;
                     DOM.setElementAttribute(captionWrapper, "class", "");
                     widget.removeStyleName("i-orderedlayout-w-e");
+
+                    captionDimensionOrPositionUpdated = true;
                 }
             }
+
+            if (captionDimensionOrPositionUpdated) {
+                client.handleComponentRelativeSize((Widget) paintable);
+            }
         }
 
         /**
          * Set alignments for this wrapper.
          */
         void setAlignment(String verticalAlignment, String horizontalAlignment) {
+            this.verticalAlignment = verticalAlignment;
+            this.horizontalAlignment = horizontalAlignment;
 
             // use one-cell table to implement horizontal alignments, only
             // for values other than top-left (which is default)
@@ -1279,6 +1266,10 @@ public class IOrderedLayout extends Panel implements Container,
                     alignmentTD = innermostTDinAlignmnetStructure = null;
                 }
             }
+
+            DOM.setStyleAttribute(getElementWrappingWidgetAndCaption(),
+                    "textAlign", horizontalAlignment);
+
         }
 
         /** Set class for spacing */
@@ -1342,39 +1333,60 @@ public class IOrderedLayout extends Panel implements Container,
         }
 
         public int getAllocatedHeight() {
+            int reduce = verticalPadding;
+            if (caption != null) {
+                if (orientationMode == ORIENTATION_VERTICAL
+                        || (orientationMode == ORIENTATION_HORIZONTAL && !caption
+                                .shouldBePlacedAfterComponent())) {
+                    reduce += caption.getHeight();
+                }
+            }
+
             if (lastForcedPixelHeight == -1) {
                 if (height == null) {
                     /*
                      * We have no height specified so return the space allocated
                      * by components so far
                      */
+
                     return getElementWrappingClipperDiv().getOffsetHeight()
-                            - horizontalPadding;
+                            - reduce;
                 }
 
-                return -1;
+                // This should not be possible...
+                return 0;
             }
 
             int available = lastForcedPixelHeight;
+            available -= reduce;
+
             // Must remove caption height to report correct size to child
-            if (caption != null) {
-                available -= caption.getOffsetHeight();
-            }
+            // if (caption != null) {
+            // available -= caption.getOffsetHeight();
+            // }
+
             return available;
         }
 
         public int getAllocatedWidth() {
+            int reduce = horizontalPadding;
+            if (caption != null && caption.shouldBePlacedAfterComponent()) {
+                reduce += caption.getWidth();
+            }
+
             if (width == null) {
                 /*
                  * We have no width specified so return the space allocated by
                  * components so far
                  */
-                return getElementWrappingClipperDiv().getOffsetWidth()
-                        - horizontalPadding;
+                return getElementWrappingClipperDiv().getOffsetWidth() - reduce;
+            } else if (lastForcedPixelWidth > -1) {
+                return lastForcedPixelWidth - reduce;
+            } else {
+                return 0;
             }
-
-            return lastForcedPixelWidth;
         }
+
     }
 
     /* documented at super */
@@ -1534,51 +1546,35 @@ public class IOrderedLayout extends Panel implements Container,
     }
 
     /* documented at super */
-    public void iLayout(int availableWidth, int availableHeight) {
-        updateChildSizes(availableWidth, availableHeight);
-        Util.runDescendentsLayout(this);
-        childLayoutsHaveChanged = false;
-    }
-
-    public int getAllocatedHeight(Widget child) {
-        final int index = childWidgets.indexOf(child);
-        if (index >= 0) {
-            WidgetWrapper wrapper = childWidgetWrappers.get(index);
-            return wrapper.getAllocatedHeight();
+    public void iLayout() {
+        if (isRendering) {
+            return;
         }
 
-        return -1;
-    }
-
-    public int getAllocatedWidth(Widget child) {
-        final int index = childWidgets.indexOf(child);
-        if (index >= 0) {
-            WidgetWrapper wrapper = childWidgetWrappers.get(index);
-            return wrapper.getAllocatedWidth();
+        updateChildSizes();
+        if (client != null) {
+            client.runDescendentsLayout(this);
         }
-
-        return -1;
+        childLayoutsHaveChanged = false;
     }
 
-    public boolean childComponentSizesUpdated() {
+    public boolean requestLayout(Set<Paintable> children) {
         if (height != null && width != null) {
             /*
-             * If the height and width has been specified for this layout the
+             * If the height and width has been specified for this container the
              * child components cannot make the size of the layout change
              */
 
             return true;
         }
 
-        int currentHeight = getElement().getOffsetHeight();
-        int currentWidth = getElement().getOffsetWidth();
-
-        if (currentHeight != renderedHeight || currentWidth != renderedWidth) {
+        if (renderInformation.updateSize(root)) {
             /*
              * Size has changed so we let the child components know about the
              * new size.
              */
-            iLayout(-1, -1);
+            iLayout();
+
             return false;
         } else {
             /*
@@ -1590,4 +1586,17 @@ public class IOrderedLayout extends Panel implements Container,
 
     }
 
+    public Size getAllocatedSpace(Widget child) {
+        final int index = childWidgets.indexOf(child);
+        if (index >= 0) {
+            WidgetWrapper wrapper = childWidgetWrappers.get(index);
+            int w = wrapper.getAllocatedWidth();
+            int h = wrapper.getAllocatedHeight();
+
+            return new Size(w, h);
+
+        }
+
+        return new Size(0, 0);
+    }
 }
index 57ac865b25acf0ad98cd8658c672063c1db79fcc..be8655f9f4256a0d879ecd7788d2d79096dd02c1 100644 (file)
@@ -4,6 +4,8 @@
 
 package com.itmill.toolkit.terminal.gwt.client.ui;
 
+import java.util.Set;
+
 import com.google.gwt.user.client.DOM;
 import com.google.gwt.user.client.Element;
 import com.google.gwt.user.client.Event;
@@ -11,13 +13,17 @@ import com.google.gwt.user.client.ui.SimplePanel;
 import com.google.gwt.user.client.ui.Widget;
 import com.itmill.toolkit.terminal.gwt.client.ApplicationConnection;
 import com.itmill.toolkit.terminal.gwt.client.BrowserInfo;
+import com.itmill.toolkit.terminal.gwt.client.ClientExceptionHandler;
+import com.itmill.toolkit.terminal.gwt.client.Container;
 import com.itmill.toolkit.terminal.gwt.client.ContainerResizedListener;
 import com.itmill.toolkit.terminal.gwt.client.IErrorMessage;
 import com.itmill.toolkit.terminal.gwt.client.Paintable;
+import com.itmill.toolkit.terminal.gwt.client.RenderInformation;
 import com.itmill.toolkit.terminal.gwt.client.UIDL;
 import com.itmill.toolkit.terminal.gwt.client.Util;
+import com.itmill.toolkit.terminal.gwt.client.RenderInformation.Size;
 
-public class IPanel extends SimplePanel implements Paintable,
+public class IPanel extends SimplePanel implements Container,
         ContainerResizedListener {
 
     public static final String CLASSNAME = "i-panel";
@@ -54,6 +60,10 @@ public class IPanel extends SimplePanel implements Paintable,
 
     private int scrollLeft;
 
+    private RenderInformation renderInformation = new RenderInformation();
+
+    private int borderPaddingHorizontal = 0;
+
     public IPanel() {
         super();
         DOM.appendChild(getElement(), captionNode);
@@ -91,12 +101,6 @@ public class IPanel extends SimplePanel implements Paintable,
         this.client = client;
         id = uidl.getId();
 
-        // Panel size. Height needs to be saved for later use
-        height = uidl.hasAttribute("height") ? uidl
-                .getStringAttribute("height") : null;
-        setWidth(uidl.hasAttribute("width") ? uidl.getStringAttribute("width")
-                : "");
-
         // Restore default stylenames
         DOM
                 .setElementProperty(captionNode, "className", CLASSNAME
@@ -234,11 +238,12 @@ public class IPanel extends SimplePanel implements Paintable,
         }
     }
 
-    public void iLayout(int availableWidth, int availableHeight) {
+    public void iLayout() {
         iLayout(true);
     }
 
     public void iLayout(boolean runGeckoFix) {
+        renderInformation.updateSize(getElement());
 
         if (BrowserInfo.get().isIE6() && width != null && !width.equals("")) {
             /*
@@ -296,26 +301,37 @@ public class IPanel extends SimplePanel implements Paintable,
 
             // Calculate used height
             super.setHeight("");
-            final int usedHeight = DOM.getElementPropertyInt(bottomDecoration,
-                    "offsetTop")
-                    + DOM.getElementPropertyInt(bottomDecoration,
-                            "offsetHeight")
-                    - DOM.getElementPropertyInt(getElement(), "offsetTop");
+            if (BrowserInfo.get().isIE() && !hasChildren) {
+                DOM.setStyleAttribute(contentNode, "height", "0px");
+            }
+
+            final int bottomTop = DOM.getElementPropertyInt(bottomDecoration,
+                    "offsetTop");
+            final int bottomHeight = DOM.getElementPropertyInt(
+                    bottomDecoration, "offsetHeight");
+            final int elementTop = DOM.getElementPropertyInt(getElement(),
+                    "offsetTop");
+
+            final int usedHeight = bottomTop + bottomHeight - elementTop;
 
             // Calculate content area height (don't allow negative values)
-            int h = targetHeight - usedHeight;
-            if (h < 0) {
-                h = 0;
+            int contentAreaHeight = targetHeight - usedHeight;
+            if (contentAreaHeight < 0) {
+                contentAreaHeight = 0;
             }
 
+            renderInformation.setContentAreaHeight(contentAreaHeight);
+
             // Set proper values for content element
-            DOM.setStyleAttribute(contentNode, "height", h + "px");
+            DOM.setStyleAttribute(contentNode, "height", contentAreaHeight
+                    + "px");
             DOM.setStyleAttribute(contentNode, "overflow", "auto");
 
             // Restore content to flow
             if (hasChildren) {
                 DOM.setStyleAttribute(contentEl, "position", origPositioning);
             }
+
             // restore scroll position
             DOM.setElementPropertyInt(contentNode, "scrollTop", scrollTop);
             DOM.setElementPropertyInt(contentNode, "scrollLeft", scrollLeft);
@@ -324,6 +340,12 @@ public class IPanel extends SimplePanel implements Paintable,
             DOM.setStyleAttribute(contentNode, "height", "");
         }
 
+        if (width != null && !width.equals("")) {
+            renderInformation.setContentAreaWidth(renderInformation
+                    .getRenderedSize().getWidth()
+                    - borderPaddingHorizontal);
+        }
+
         if (runGeckoFix && BrowserInfo.get().isGecko()) {
             // workaround for #1764
             if (width == null || width.equals("")) {
@@ -347,7 +369,8 @@ public class IPanel extends SimplePanel implements Paintable,
                 }
             }
         }
-        Util.runDescendentsLayout(this);
+
+        client.runDescendentsLayout(this);
     }
 
     @Override
@@ -398,7 +421,7 @@ public class IPanel extends SimplePanel implements Paintable,
      */
     @Override
     public void setHeight(String height) {
-        // NOP
+        this.height = height;
     }
 
     /**
@@ -407,14 +430,61 @@ public class IPanel extends SimplePanel implements Paintable,
     @Override
     public void setWidth(String width) {
         this.width = width;
-        // Let browser handle 100% width (DIV element takes all size by
-        // default).
-        // This way we can specify borders for Panel's outer element.
-        if (width.equals("100%")) {
-            super.setWidth("");
+
+        super.setWidth(width);
+
+        if (width.endsWith("px")) {
+            try {
+                // FIXME: More sane implementation
+                borderPaddingHorizontal = Util.measureHorizontalPadding(
+                        contentNode, -2);
+                if (borderPaddingHorizontal < 0) {
+                    borderPaddingHorizontal = -borderPaddingHorizontal;
+                }
+            } catch (Exception e) {
+                ClientExceptionHandler.displayError(e);
+            }
+        }
+
+    }
+
+    public boolean hasChildComponent(Widget component) {
+        if (component != null && component == layout) {
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+    public void replaceChildComponent(Widget oldComponent, Widget newComponent) {
+        // TODO
+    }
+
+    public Size getAllocatedSpace(Widget child) {
+        return renderInformation.getContentAreaSize();
+    }
+
+    public boolean requestLayout(Set<Paintable> child) {
+
+        if (height != null && width != null) {
+            /*
+             * If the height and width has been specified the child components
+             * cannot make the size of the layout change
+             */
+
+            return true;
+        }
+
+        if (renderInformation.updateSize(getElement())) {
+            return false;
         } else {
-            super.setWidth(width);
+            return true;
         }
+
+    }
+
+    public void updateCaption(Paintable component, UIDL uidl) {
+        // TODO
     }
 
 }
index 305f4a6b61a990e2a9424bad461997485c90bee3..2ab507bd8c714dd96f8d780812b0da656ab46041 100644 (file)
@@ -21,6 +21,7 @@ import com.itmill.toolkit.terminal.gwt.client.ICaption;
 import com.itmill.toolkit.terminal.gwt.client.ICaptionWrapper;
 import com.itmill.toolkit.terminal.gwt.client.Paintable;
 import com.itmill.toolkit.terminal.gwt.client.UIDL;
+import com.itmill.toolkit.terminal.gwt.client.RenderInformation.Size;
 
 public class IPopupView extends HTML implements Paintable {
 
@@ -169,10 +170,10 @@ public class IPopupView extends HTML implements Paintable {
     }
 
     public static native void nativeBlur(Element e) /*-{ 
-                                              if(e.focus) {
-                                              e.blur();
-                                              }
-                                              }-*/;
+                                                    if(e.focus) {
+                                                    e.blur();
+                                                    }
+                                                    }-*/;
 
     private class CustomPopup extends IToolkitOverlay implements Container {
 
@@ -310,11 +311,16 @@ public class IPopupView extends HTML implements Paintable {
             }
         }
 
-        public boolean childComponentSizesUpdated() {
+        public boolean requestLayout(Set<Paintable> child) {
             // TODO Auto-generated method stub
             return false;
         }
 
+        public Size getAllocatedSpace(Widget child) {
+            // TODO Auto-generated method stub
+            return null;
+        }
+
     }// class CustomPopup
 
 }// class IPopupView
index a0b0885c8048f79a6eff0624876814903173160e..1375196461facc427175984fb2beb3bae211435d 100644 (file)
@@ -678,11 +678,7 @@ public class IScrollTable extends Composite implements Table, ScrollListener,
         initializedAndAttached = true;
     }
 
-    private void iLayout() {
-        iLayout(-1, -1);
-    }
-
-    public void iLayout(int availableWidth, int availableHeight) {
+    public void iLayout() {
         if (height != null) {
             if (height.equals("100%")) {
                 /*
index 196187b2e563b6d6999a744d969130289dc0b447..a6d5b6e2a210cc80f553df1a0fda757a8181a865 100644 (file)
@@ -391,7 +391,7 @@ public class ISlider extends Widget implements Paintable, Field,
         setValue(new Double(v), animate, roundup);\r
     }\r
 \r
-    public void iLayout(int availableWidth, int availableHeight) {\r
+    public void iLayout() {\r
         if (vertical) {\r
             setHeight();\r
         }\r
index 7e2acebb531e85768f76d7b5e25bb1814a5a8699..4c42222c4bf9dad8cd730c916b378e8d2c6a0648 100644 (file)
@@ -4,6 +4,8 @@
 
 package com.itmill.toolkit.terminal.gwt.client.ui;
 
+import java.util.Set;
+
 import com.google.gwt.user.client.Command;
 import com.google.gwt.user.client.DOM;
 import com.google.gwt.user.client.DeferredCommand;
@@ -14,12 +16,15 @@ import com.google.gwt.user.client.ui.RootPanel;
 import com.google.gwt.user.client.ui.Widget;
 import com.itmill.toolkit.terminal.gwt.client.ApplicationConnection;
 import com.itmill.toolkit.terminal.gwt.client.BrowserInfo;
+import com.itmill.toolkit.terminal.gwt.client.Container;
 import com.itmill.toolkit.terminal.gwt.client.ContainerResizedListener;
 import com.itmill.toolkit.terminal.gwt.client.Paintable;
+import com.itmill.toolkit.terminal.gwt.client.RenderInformation;
 import com.itmill.toolkit.terminal.gwt.client.UIDL;
 import com.itmill.toolkit.terminal.gwt.client.Util;
+import com.itmill.toolkit.terminal.gwt.client.RenderInformation.Size;
 
-public class ISplitPanel extends ComplexPanel implements Paintable,
+public class ISplitPanel extends ComplexPanel implements Container,
         ContainerResizedListener {
     public static final String CLASSNAME = "i-splitpanel";
 
@@ -59,6 +64,15 @@ public class ISplitPanel extends ComplexPanel implements Paintable,
 
     private Element draggingCurtain;
 
+    private ApplicationConnection client;
+
+    private String width = null;
+
+    private String height = null;
+
+    private RenderInformation renderInformationFirst = new RenderInformation();
+    private RenderInformation renderInformationSecond = new RenderInformation();
+
     public ISplitPanel() {
         this(ORIENTATION_HORIZONTAL);
     }
@@ -131,10 +145,14 @@ public class ISplitPanel extends ComplexPanel implements Paintable,
     }
 
     public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
+        this.client = client;
+
         if (client.updateComponent(this, uidl, true)) {
             return;
         }
 
+        renderInformationFirst.updateSize(getElement());
+
         setSplitPosition(uidl.getStringAttribute("position"));
 
         locked = uidl.hasAttribute("locked");
@@ -183,19 +201,18 @@ public class ISplitPanel extends ComplexPanel implements Paintable,
         iLayout();
     }
 
-    private void iLayout() {
-        iLayout(-1, -1);
-    }
-
     /*
      * Calculates absolutely positioned container places/sizes (non-Javadoc)
      * 
      * @see com.itmill.toolkit.terminal.gwt.client.NeedsLayout#layout()
      */
-    public void iLayout(int availableWidth, int availableHeight) {
+    public void iLayout() {
         if (!isAttached()) {
             return;
         }
+
+        renderInformationFirst.updateSize(getElement());
+
         int wholeSize;
         int pixelPosition;
 
@@ -232,6 +249,13 @@ public class ISplitPanel extends ComplexPanel implements Paintable,
             DOM.setStyleAttribute(secondContainer, "left",
                     (pixelPosition + getSplitterSize()) + "px");
 
+            int contentHeight = renderInformationFirst.getRenderedSize()
+                    .getHeight();
+            renderInformationFirst.setContentAreaHeight(contentHeight);
+            renderInformationFirst.setContentAreaWidth(getSplitterSize());
+            renderInformationSecond.setContentAreaHeight(contentHeight);
+            renderInformationSecond.setContentAreaWidth(secondContainerWidth);
+
             break;
         case ORIENTATION_VERTICAL:
             wholeSize = DOM.getElementPropertyInt(wrapper, "clientHeight");
@@ -258,12 +282,20 @@ public class ISplitPanel extends ComplexPanel implements Paintable,
                     secondContainerHeight + "px");
             DOM.setStyleAttribute(secondContainer, "top",
                     (pixelPosition + getSplitterSize()) + "px");
+
+            int contentWidth = renderInformationFirst.getRenderedSize()
+                    .getWidth();
+            renderInformationFirst.setContentAreaHeight(getSplitterSize());
+            renderInformationFirst.setContentAreaWidth(contentWidth);
+            renderInformationSecond.setContentAreaHeight(secondContainerHeight);
+            renderInformationSecond.setContentAreaWidth(contentWidth);
+
             break;
         }
 
         if (Util.isIE7()) {
             // Part I of IE7 weirdness hack, will be set to auto in layout phase
-            Util.runDescendentsLayout(this);
+            client.runDescendentsLayout(this);
             DeferredCommand.addCommand(new Command() {
                 public void execute() {
                     DOM.setStyleAttribute(firstContainer, "overflow", "auto");
@@ -271,13 +303,15 @@ public class ISplitPanel extends ComplexPanel implements Paintable,
                 }
             });
         } else {
-            Util.runDescendentsLayout(this);
+            client.runDescendentsLayout(this);
             if (!(resizing && BrowserInfo.get().isGecko())) {
                 DOM.setStyleAttribute(firstContainer, "overflow", "auto");
                 DOM.setStyleAttribute(secondContainer, "overflow", "auto");
             }
         }
 
+        renderInformationFirst.updateSize(getElement());
+
     }
 
     private void setFirstWidget(Widget w) {
@@ -434,4 +468,57 @@ public class ISplitPanel extends ComplexPanel implements Paintable,
         return splitterSize;
     }
 
+    @Override
+    public void setHeight(String height) {
+        this.height = height;
+        super.setHeight(height);
+    }
+
+    @Override
+    public void setWidth(String width) {
+        this.width = width;
+        super.setWidth(width);
+    }
+
+    public Size getAllocatedSpace(Widget child) {
+        if (child == firstChild) {
+            return renderInformationFirst.getContentAreaSize();
+        } else if (child == secondChild) {
+            return renderInformationSecond.getContentAreaSize();
+        }
+
+        return null;
+    }
+
+    public boolean hasChildComponent(Widget component) {
+        return (component != null && (component == firstChild || component == secondChild));
+    }
+
+    public void replaceChildComponent(Widget oldComponent, Widget newComponent) {
+        // TODO Auto-generated method stub
+    }
+
+    public boolean requestLayout(Set<Paintable> child) {
+        if (height != null && width != null) {
+            /*
+             * If the height and width has been specified the child components
+             * cannot make the size of the layout change
+             */
+
+            return true;
+        }
+
+        if (renderInformationFirst.updateSize(getElement())) {
+            return false;
+        } else {
+            return true;
+        }
+
+    }
+
+    public void updateCaption(Paintable component, UIDL uidl) {
+        // TODO Auto-generated method stub
+
+    }
+
 }
index b52b0543d619a0d1df6d1772e4b146c1856307f6..161c2e8091570471994393964d8a33cf96b8ceb2 100644 (file)
@@ -6,6 +6,7 @@ package com.itmill.toolkit.terminal.gwt.client.ui;
 
 import java.util.HashMap;
 import java.util.Iterator;
+import java.util.Set;
 
 import com.google.gwt.user.client.Command;
 import com.google.gwt.user.client.DOM;
@@ -20,8 +21,9 @@ import com.itmill.toolkit.terminal.gwt.client.ApplicationConnection;
 import com.itmill.toolkit.terminal.gwt.client.ContainerResizedListener;
 import com.itmill.toolkit.terminal.gwt.client.ICaption;
 import com.itmill.toolkit.terminal.gwt.client.Paintable;
+import com.itmill.toolkit.terminal.gwt.client.RenderInformation;
 import com.itmill.toolkit.terminal.gwt.client.UIDL;
-import com.itmill.toolkit.terminal.gwt.client.Util;
+import com.itmill.toolkit.terminal.gwt.client.RenderInformation.Size;
 
 public class ITabsheet extends ITabsheetBase implements
         ContainerResizedListener {
@@ -124,6 +126,8 @@ public class ITabsheet extends ITabsheetBase implements
 
     private boolean waitingForResponse;
 
+    private RenderInformation renderInformation = new RenderInformation();
+
     /**
      * Previous visible widget is set invisible with CSS (not display: none, but
      * visibility: hidden), to avoid flickering during render process. Normal
@@ -372,15 +376,13 @@ public class ITabsheet extends ITabsheetBase implements
                 || (this.width == null && width != null)
                 || !width.equals(oldWidth)) {
             // Run descendant layout functions
-            Util.runDescendentsLayout(this);
+            client.runDescendentsLayout(this);
         }
     }
 
-    private void iLayout() {
-        iLayout(-1, -1);
-    }
+    public void iLayout() {
+        renderInformation.updateSize(getElement());
 
-    public void iLayout(int availableWidth, int availableHeight) {
         if (height != null && height != "") {
             super.setHeight(height);
 
@@ -400,9 +402,17 @@ public class ITabsheet extends ITabsheetBase implements
             DOM.setStyleAttribute(contentNode, "height", "");
             DOM.setStyleAttribute(contentNode, "overflow", "");
         }
-        Util.runDescendentsLayout(this);
+
+        if (client != null) {
+            client.runDescendentsLayout(this);
+        }
+
+        renderInformation.setContentAreaWidth(tp.getElement().getOffsetWidth());
+        renderInformation.setContentAreaHeight(tp.getElement()
+                .getOffsetHeight());
 
         updateTabScroller();
+
     }
 
     /**
@@ -479,8 +489,37 @@ public class ITabsheet extends ITabsheetBase implements
         c.updateCaption(uidl);
     }
 
-    public boolean childComponentSizesUpdated() {
-        // TODO Auto-generated method stub
-        return false;
+    public boolean requestLayout(Set<Paintable> child) {
+        if (height != null && width != null) {
+            /*
+             * If the height and width has been specified for this container the
+             * child components cannot make the size of the layout change
+             */
+
+            return true;
+        }
+
+        if (renderInformation.updateSize(getElement())) {
+            /*
+             * Size has changed so we let the child components know about the
+             * new size.
+             */
+            iLayout();
+
+            return false;
+        } else {
+            /*
+             * Size has not changed so we do not need to propagate the event
+             * further
+             */
+            return true;
+        }
+
+    }
+
+    public Size getAllocatedSpace(Widget child) {
+        // All tabs have equal amount of space allocated
+
+        return renderInformation.getContentAreaSize();
     }
 }
index 65e1a1f07e9c31e13eaeaaa570fe5834d5a63ec0..c66d6980b1743afb235feb91db9914595ccb8863 100644 (file)
@@ -30,6 +30,7 @@ abstract class ITabsheetBase extends ComplexPanel implements Container {
     }
 
     public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
+        this.client = client;
 
         // Ensure correct implementation
         if (client.updateComponent(this, uidl, true)) {
@@ -37,7 +38,6 @@ abstract class ITabsheetBase extends ComplexPanel implements Container {
         }
 
         // Update member references
-        this.client = client;
         id = uidl.getId();
         disabled = uidl.hasAttribute("disabled");
 
index 836b9b03d9cf3a5a47c9583d4c5a822cb012d0d7..e02d48fb36c7a3cb8d5ee737dddd5c58570d3f17 100644 (file)
@@ -26,7 +26,7 @@ import com.itmill.toolkit.terminal.gwt.client.Util;
  * 
  */
 public class ITextField extends TextBoxBase implements Paintable, Field,
-        ChangeListener, FocusListener, ContainerResizedListener {
+        ChangeListener, FocusListener {
 
     /**
      * The input node CSS classname.
@@ -44,8 +44,6 @@ public class ITextField extends TextBoxBase implements Paintable, Field,
     private String valueBeforeEdit = null;
 
     private boolean immediate = false;
-    private float proportionalHeight = -1;
-    private float proportionalWidth = -1;
     private int extraHorizontalPixels = -1;
     private int extraVerticalPixels = -1;
 
@@ -142,63 +140,6 @@ public class ITextField extends TextBoxBase implements Paintable, Field,
     } catch (e) {}
     }-*/;
 
-    public void setHeight(String height) {
-        if (height != null && height.indexOf("%") > 0) {
-            // special handling for proportional height
-            proportionalHeight = Float.parseFloat(height.substring(0, height
-                    .indexOf("%"))) / 100;
-            iLayout();
-        } else {
-            super.setHeight(height);
-            proportionalHeight = -1;
-        }
-    }
-
-    public void setWidth(String width) {
-        if (width != null && width.indexOf("%") > 0) {
-            // special handling for proportional w
-            proportionalWidth = Float.parseFloat(width.substring(0, width
-                    .indexOf("%"))) / 100;
-            iLayout();
-        } else {
-            super.setWidth(width);
-            proportionalWidth = -1;
-        }
-    }
-
-    private void iLayout() {
-        iLayout(-1, -1);
-    }
-
-    public void iLayout(int availableWidth, int availableHeight) {
-        if (proportionalWidth >= 0) {
-            int availPixels = availableWidth;
-            if (availPixels < 0) {
-                availPixels = (DOM.getElementPropertyInt(DOM
-                        .getParent(getElement()), "clientWidth"));
-            }
-            availPixels *= proportionalWidth;
-
-            availPixels -= getExtraHorizontalPixels();
-            if (availPixels >= 0) {
-                super.setWidth(availPixels + "px");
-            }
-        }
-        if (proportionalHeight >= 0) {
-            int availPixels = availableHeight;
-            if (availPixels < 0) {
-                availPixels = (DOM.getElementPropertyInt(DOM
-                        .getParent(getElement()), "clientHeight"));
-            }
-            availPixels *= proportionalHeight;
-            availPixels -= getExtraVerticalPixels();
-
-            if (availPixels >= 0) {
-                super.setHeight(availPixels + "px");
-            }
-        }
-    }
-
     /**
      * @return space used by components paddings and borders
      */
@@ -242,4 +183,30 @@ public class ITextField extends TextBoxBase implements Paintable, Field,
         DOM.removeChild(DOM.getParent(getElement()), clone);
     }
 
+    @Override
+    public void setHeight(String height) {
+        if (height.endsWith("px")) {
+            int h = Integer.parseInt(height.substring(0, height.length() - 2));
+            h -= getExtraVerticalPixels();
+            super.setHeight(h + "px");
+        } else {
+            super.setHeight(height);
+        }
+    }
+
+    @Override
+    public void setWidth(String width) {
+        if (width.endsWith("px")) {
+            int h = Integer.parseInt(width.substring(0, width.length() - 2));
+            h -= getExtraHorizontalPixels();
+            if (h <= 0) {
+                h = 0;
+            }
+
+            super.setWidth(h + "px");
+        } else {
+            super.setWidth(width);
+        }
+    }
+
 }
index a115c238aeea4e4403ba56f8574f88ef9a0daed0..46ae202986eac7a3cb349658b0f2cebe4e7f4eea 100644 (file)
@@ -272,11 +272,7 @@ public class ITextualDate extends IDateField implements Paintable, Field,
         return fieldExtraWidth;\r
     }\r
 \r
-    private void iLayout() {\r
-        iLayout(-1, -1);\r
-    }\r
-\r
-    public void iLayout(int availableWidth, int availableHeight) {\r
+    public void iLayout() {\r
         if (needLayout) {\r
             text.setWidth((getOffsetWidth() - getFieldExtraWidth()) + "px");\r
         }\r
index 1f55fba6a5f3969a357b5c694bfe9cb48697f7e2..4d77a5d38d457f057129b4ad8b9de52258c505aa 100644 (file)
@@ -6,6 +6,7 @@ package com.itmill.toolkit.terminal.gwt.client.ui;
 
 import java.util.HashSet;
 import java.util.Iterator;
+import java.util.Set;
 
 import com.google.gwt.user.client.Command;
 import com.google.gwt.user.client.DOM;
@@ -22,15 +23,18 @@ import com.google.gwt.user.client.ui.SimplePanel;
 import com.google.gwt.user.client.ui.Widget;
 import com.itmill.toolkit.terminal.gwt.client.ApplicationConnection;
 import com.itmill.toolkit.terminal.gwt.client.BrowserInfo;
+import com.itmill.toolkit.terminal.gwt.client.Container;
 import com.itmill.toolkit.terminal.gwt.client.Focusable;
 import com.itmill.toolkit.terminal.gwt.client.Paintable;
+import com.itmill.toolkit.terminal.gwt.client.RenderInformation;
 import com.itmill.toolkit.terminal.gwt.client.UIDL;
 import com.itmill.toolkit.terminal.gwt.client.Util;
+import com.itmill.toolkit.terminal.gwt.client.RenderInformation.Size;
 
 /**
  * 
  */
-public class IView extends SimplePanel implements Paintable,
+public class IView extends SimplePanel implements Container,
         WindowResizeListener, WindowCloseListener {
 
     private static final String CLASSNAME = "i-view";
@@ -61,6 +65,8 @@ public class IView extends SimplePanel implements Paintable,
      */
     private Timer resizeTimer;
 
+    private RenderInformation renderInformation = new RenderInformation();
+
     public IView(String elementId) {
         super();
         setStyleName(CLASSNAME);
@@ -178,6 +184,9 @@ public class IView extends SimplePanel implements Paintable,
             setWidget((Widget) lo);
             layout = lo;
         }
+
+        updateContentAreaSize();
+
         layout.updateFromUIDL(childUidl, client);
 
         // Update subwindows
@@ -275,8 +284,16 @@ public class IView extends SimplePanel implements Paintable,
         onWindowResized(Window.getClientWidth(), Window.getClientHeight());
         // IE somehow fails some layout on first run, force layout
         // functions
-        // Util.runDescendentsLayout(this);
+        // client.runDescendentsLayout(this);
+
+    }
 
+    private void updateContentAreaSize() {
+        renderInformation.setContentAreaWidth(getElement().getOffsetWidth());
+
+        // For some reason IView has a 1 pixel padding
+        renderInformation
+                .setContentAreaHeight(getElement().getOffsetHeight() - 1);
     }
 
     public void onBrowserEvent(Event event) {
@@ -315,7 +332,7 @@ public class IView extends SimplePanel implements Paintable,
                                     .getConsole()
                                     .log(
                                             "Running layout functions due window resize");
-                            Util.runDescendentsLayout(IView.this);
+                            connection.runDescendentsLayout(IView.this);
                         }
                     }
                 };
@@ -340,9 +357,12 @@ public class IView extends SimplePanel implements Paintable,
             DOM.setStyleAttribute(getElement(), "overflow", "hidden");
             ApplicationConnection.getConsole().log(
                     "Running layout functions due window resize");
-            Util.runDescendentsLayout(this);
+            connection.runDescendentsLayout(this);
             DOM.setStyleAttribute(getElement(), "overflow", overflow);
         }
+
+        updateContentAreaSize();
+
     }
 
     public native static void goTo(String url)
@@ -369,4 +389,29 @@ public class IView extends SimplePanel implements Paintable,
         return null;
     }
 
+    public Size getAllocatedSpace(Widget child) {
+        return renderInformation.getContentAreaSize();
+    }
+
+    public boolean hasChildComponent(Widget component) {
+        return (component != null && component == layout);
+    }
+
+    public void replaceChildComponent(Widget oldComponent, Widget newComponent) {
+        // TODO Auto-generated method stub
+    }
+
+    public boolean requestLayout(Set<Paintable> child) {
+        /*
+         * Can never propagate further and we do not want need to re-layout the
+         * layout which has caused this request.
+         */
+        return true;
+
+    }
+
+    public void updateCaption(Paintable component, UIDL uidl) {
+        // TODO Auto-generated method stub
+    }
+
 }
index 40d4d0222aeb288b016269e94fb55868b466d966..5aca69c3a802d5776548337c2cc005957ceffc0a 100644 (file)
@@ -665,7 +665,7 @@ public class IWindow extends PopupPanel implements Paintable, ScrollListener {
             client.updateVariable(id, "height", h, false);
         }
         // Update child widget dimensions
-        Util.runDescendentsLayout(this);
+        client.runDescendentsLayout(this);
     }
 
     @Override
index 87bb203924afc083ed719420ea4911aaab8f83af..54f81f44b23d361536241187045a71dc6c2a0181 100644 (file)
@@ -9,9 +9,11 @@ import com.google.gwt.user.client.ui.AbsolutePanel;
 import com.google.gwt.user.client.ui.Composite;
 import com.google.gwt.user.client.ui.SimplePanel;
 import com.google.gwt.user.client.ui.Widget;
+import com.itmill.toolkit.terminal.gwt.client.ApplicationConnection;
 import com.itmill.toolkit.terminal.gwt.client.BrowserInfo;
 import com.itmill.toolkit.terminal.gwt.client.ContainerResizedListener;
 import com.itmill.toolkit.terminal.gwt.client.ICaption;
+import com.itmill.toolkit.terminal.gwt.client.UIDL;
 import com.itmill.toolkit.terminal.gwt.client.Util;
 import com.itmill.toolkit.terminal.gwt.client.ui.AlignmentInfo;
 
@@ -39,6 +41,8 @@ public class IAbsoluteGrid extends Composite implements
 
     private int offsetHeight;
 
+    protected ApplicationConnection client;
+
     public IAbsoluteGrid() {
         ap = new AbsolutePanel();
         initWidget(ap);
@@ -264,7 +268,7 @@ public class IAbsoluteGrid extends Composite implements
         }
     }
 
-    public void iLayout(int availableWidth, int availableHeight) {
+    public void iLayout() {
         boolean sizeChanged = false;
         int newWidth = getOffsetWidth();
         if (offsetWidth != newWidth) {
@@ -282,7 +286,7 @@ public class IAbsoluteGrid extends Composite implements
                 cell.render();
                 cell.vAling();
             }
-            Util.runDescendentsLayout(ap);
+            client.runDescendentsLayout(ap);
         }
     }
 
@@ -307,4 +311,9 @@ public class IAbsoluteGrid extends Composite implements
         offsetHeight = 0;
         offsetWidth = 0;
     }
+
+    public void updateFromUIDL(UIDL uidl, final ApplicationConnection client) {
+        this.client = client;
+    }
+
 }
index c1788b5f9b3dc45d04561826aa61e333bd7867ce..e639c99b48e71b4a6897731ca46123c8ede91094 100644 (file)
@@ -3,6 +3,7 @@ package com.itmill.toolkit.terminal.gwt.client.ui.absolutegrid;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.Iterator;
+import java.util.Set;
 
 import com.google.gwt.user.client.Command;
 import com.google.gwt.user.client.DOM;
@@ -14,6 +15,7 @@ import com.itmill.toolkit.terminal.gwt.client.Container;
 import com.itmill.toolkit.terminal.gwt.client.ICaption;
 import com.itmill.toolkit.terminal.gwt.client.Paintable;
 import com.itmill.toolkit.terminal.gwt.client.UIDL;
+import com.itmill.toolkit.terminal.gwt.client.RenderInformation.Size;
 import com.itmill.toolkit.terminal.gwt.client.ui.MarginInfo;
 
 /**
@@ -27,7 +29,6 @@ public class ISizeableGridLayout extends IAbsoluteGrid implements Paintable,
     public static final String CLASSNAME = "i-gridlayout";
     private int spacing;
     private HashMap paintableToCellMap = new HashMap();
-    private ApplicationConnection client;
     private MarginPixels mp;
     private String oldStyleString = "";
 
@@ -41,7 +42,7 @@ public class ISizeableGridLayout extends IAbsoluteGrid implements Paintable,
     }
 
     public void updateFromUIDL(UIDL uidl, final ApplicationConnection client) {
-        this.client = client;
+        super.updateFromUIDL(uidl, client);
 
         if (client.updateComponent(this, uidl, true)) {
             return;
@@ -249,11 +250,16 @@ public class ISizeableGridLayout extends IAbsoluteGrid implements Paintable,
         return marginPixels;
     }
 
-    public boolean childComponentSizesUpdated() {
+    public boolean requestLayout(Set<Paintable> child) {
         // TODO Auto-generated method stub
         return false;
     }
 
+    public Size getAllocatedSpace(Widget child) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
 }
 
 class MarginPixels {