]> source.dussan.org Git - vaadin-framework.git/commitdiff
Window layouting changes attempt 2 (#8313)
authorLeif Åstrand <leif@vaadin.com>
Wed, 7 Mar 2012 14:50:15 +0000 (16:50 +0200)
committerLeif Åstrand <leif@vaadin.com>
Wed, 7 Mar 2012 14:50:15 +0000 (16:50 +0200)
WebContent/VAADIN/themes/base/window/window.css
WebContent/VAADIN/themes/reindeer/window/window.css
src/com/vaadin/terminal/gwt/client/ui/VWindow.java
src/com/vaadin/terminal/gwt/client/ui/WindowConnector.java
src/com/vaadin/terminal/gwt/server/ComponentSizeValidator.java
src/com/vaadin/ui/Window.java

index 986cfeaeb8ed45adfcc92236c7be41c19a4df09a..701140333ac289667f31614410f1c8df977ef7a5 100644 (file)
@@ -2,15 +2,20 @@
        background: #fff;
 }
 .v-window-outerheader {
-       padding: 0.3em 1em;
+       padding: 0.3em 0;
        height: 1em;
+       position: relative;
 }
 
 .v-window-outerheader,
 .v-window-draggingCurtain {
        cursor: move;   
 }
-
+.v-window-header.v-not-spanning {
+       position: absolute;
+       left: 0;
+       right: 0;
+}
 .v-window-header {
        font-weight: bold;
 }
@@ -20,7 +25,7 @@ div.v-window-header {
        text-overflow: ellipsis;
        -ms-text-overflow: ellipsis;
        overflow: hidden;
-       padding: 0;
+       padding: 0 1em;
 }
 .v-window-header .v-icon {
        vertical-align: middle; /* This has to be 'middle', not 'bottom', to allow larger icons than 16px */
index 25829b2f2b6d79e0706491a18a2ba657e9f43b2e..e24b00e4ea5ecbfbad0e58fbb3e345bdf3d04d45 100644 (file)
@@ -9,12 +9,12 @@
        border-color: rgba(0,0,0,.2);
 }
 .v-window-outerheader {
-       padding: 12px 32px 0 14px;
+       padding: 12px 0 0;
        height: 25px;
        background: black repeat-x;
        background-image: url(img/header-bg.png); /** sprite-ref: verticals; sprite-alignment: repeat */
 }
-.v-window-header {
+div.v-window-header {
        font-weight: bold;
        font-size: 12px;
        line-height: normal;
@@ -24,6 +24,7 @@
        overflow: hidden;
        text-overflow: ellipsis;
        -ms-text-overflow: ellipsis;
+       padding: 0 32px 0 14px
 }
 .v-window-error .v-window-header {
        padding-left: 13px;
index 4b6c7e54f410ad6b2373d74e42d290a41250d542..c498cac807671bbabe3ca974050f6f2ee27d8425 100644 (file)
@@ -47,13 +47,13 @@ public class VWindow extends VOverlay implements ShortcutActionHandlerOwner,
      * Minimum allowed height of a window. This refers to the content area, not
      * the outer borders.
      */
-    private static final int MIN_CONTENT_AREA_HEIGHT = 100;
+    public static final int MIN_CONTENT_AREA_HEIGHT = 100;
 
     /**
      * Minimum allowed width of a window. This refers to the content area, not
      * the outer borders.
      */
-    private static final int MIN_CONTENT_AREA_WIDTH = 150;
+    public static final int MIN_CONTENT_AREA_WIDTH = 150;
 
     private static ArrayList<VWindow> windowOrder = new ArrayList<VWindow>();
 
@@ -61,19 +61,6 @@ public class VWindow extends VOverlay implements ShortcutActionHandlerOwner,
 
     public static final String CLASSNAME = "v-window";
 
-    /**
-     * Difference between offsetWidth and inner width for the content area.
-     */
-    private int contentAreaBorderPadding = -1;
-    /**
-     * Pixels used by inner borders and paddings horizontally (calculated only
-     * once). This is the difference between the width of the root element and
-     * the content area, such that if root element width is set to "XYZpx" the
-     * inner width (width-border-padding) of the content area is
-     * X-contentAreaRootDifference.
-     */
-    private int contentAreaToRootDifference = -1;
-
     private static final int STACKING_OFFSET_PIXELS = 15;
 
     public static final int Z_INDEX = 10000;
@@ -82,7 +69,7 @@ public class VWindow extends VOverlay implements ShortcutActionHandlerOwner,
 
     Element contents;
 
-    private Element header;
+    Element header;
 
     private Element footer;
 
@@ -136,23 +123,14 @@ public class VWindow extends VOverlay implements ShortcutActionHandlerOwner,
 
     private boolean closable = true;
 
-    boolean dynamicWidth = false;
-    boolean dynamicHeight = false;
-    boolean layoutRelativeWidth = false;
-    boolean layoutRelativeHeight = false;
-
     // If centered (via UIDL), the window should stay in the centered -mode
     // until a position is received from the server, or the user moves or
     // resizes the window.
     boolean centered = false;
 
-    private String width;
-
-    private String height;
-
     boolean immediate;
 
-    private Element wrapper, wrapper2;
+    private Element wrapper;
 
     boolean visibilityChangesDisabled;
 
@@ -243,15 +221,11 @@ public class VWindow extends VOverlay implements ShortcutActionHandlerOwner,
         wrapper = DOM.createDiv();
         DOM.setElementProperty(wrapper, "className", CLASSNAME + "-wrap");
 
-        wrapper2 = DOM.createDiv();
-        DOM.setElementProperty(wrapper2, "className", CLASSNAME + "-wrap2");
-
-        DOM.appendChild(wrapper2, closeBox);
-        DOM.appendChild(wrapper2, header);
+        DOM.appendChild(wrapper, header);
+        DOM.appendChild(wrapper, closeBox);
         DOM.appendChild(header, headerText);
-        DOM.appendChild(wrapper2, contents);
-        DOM.appendChild(wrapper2, footer);
-        DOM.appendChild(wrapper, wrapper2);
+        DOM.appendChild(wrapper, contents);
+        DOM.appendChild(wrapper, footer);
         DOM.appendChild(super.getContainerElement(), wrapper);
 
         sinkEvents(Event.MOUSEEVENTS | Event.TOUCHEVENTS | Event.ONCLICK
@@ -341,52 +315,6 @@ public class VWindow extends VOverlay implements ShortcutActionHandlerOwner,
         }
     }
 
-    void setNaturalWidth() {
-        /*
-         * Use max(layout width, window width) i.e layout content width or
-         * caption width. We remove the previous set width so the width is
-         * allowed to shrink. All widths are measured as outer sizes, i.e. the
-         * borderWidth is added to the content.
-         */
-
-        DOM.setStyleAttribute(getElement(), "width", "");
-
-        // Content
-        int contentWidth = contentPanel.getElement().getScrollWidth();
-        contentWidth += getContentAreaToRootDifference();
-
-        // Window width (caption)
-        int windowCaptionWidth = getOffsetWidth();
-
-        int naturalWidth = (contentWidth > windowCaptionWidth ? contentWidth
-                : windowCaptionWidth);
-
-        setWidth(naturalWidth + "px");
-    }
-
-    private int getContentAreaToRootDifference() {
-        if (contentAreaToRootDifference < 0) {
-            measure();
-        }
-        return contentAreaToRootDifference;
-    }
-
-    private void measure() {
-        if (!isAttached()) {
-            return;
-        }
-
-        contentAreaBorderPadding = Util.measureHorizontalPaddingAndBorder(
-                contents, 4);
-        int wrapperPaddingBorder = Util.measureHorizontalPaddingAndBorder(
-                wrapper, 0)
-                + Util.measureHorizontalPaddingAndBorder(wrapper2, 0);
-
-        contentAreaToRootDifference = wrapperPaddingBorder
-                + contentAreaBorderPadding;
-
-    }
-
     /**
      * Sets the closable state of the window. Additionally hides/shows the close
      * button according to the new state.
@@ -650,8 +578,8 @@ public class VWindow extends VOverlay implements ShortcutActionHandlerOwner,
                 resizing = true;
                 startX = Util.getTouchOrMouseClientX(event);
                 startY = Util.getTouchOrMouseClientY(event);
-                origW = getElement().getOffsetWidth();
-                origH = getElement().getOffsetHeight();
+                origW = contents.getOffsetWidth();
+                origH = contents.getOffsetHeight();
                 DOM.setCapture(getElement());
                 event.preventDefault();
                 break;
@@ -716,13 +644,13 @@ public class VWindow extends VOverlay implements ShortcutActionHandlerOwner,
         }
 
         int w = Util.getTouchOrMouseClientX(event) - startX + origW;
-        if (w < MIN_CONTENT_AREA_WIDTH + getContentAreaToRootDifference()) {
-            w = MIN_CONTENT_AREA_WIDTH + getContentAreaToRootDifference();
+        if (w < MIN_CONTENT_AREA_WIDTH) {
+            w = MIN_CONTENT_AREA_WIDTH;
         }
 
         int h = Util.getTouchOrMouseClientY(event) - startY + origH;
-        if (h < MIN_CONTENT_AREA_HEIGHT + getExtraHeight()) {
-            h = MIN_CONTENT_AREA_HEIGHT + getExtraHeight();
+        if (h < MIN_CONTENT_AREA_HEIGHT) {
+            h = MIN_CONTENT_AREA_HEIGHT;
         }
 
         setWidth(w + "px");
@@ -730,8 +658,10 @@ public class VWindow extends VOverlay implements ShortcutActionHandlerOwner,
 
         if (updateVariables) {
             // sending width back always as pixels, no need for unit
-            client.updateVariable(id, "width", w, false);
-            client.updateVariable(id, "height", h, immediate);
+            client.updateVariable(id, "width", getWidget().getOffsetWidth(),
+                    false);
+            client.updateVariable(id, "height", getWidget().getOffsetHeight(),
+                    immediate);
         }
 
         if (updateVariables || !resizeLazy) {
@@ -755,87 +685,15 @@ public class VWindow extends VOverlay implements ShortcutActionHandlerOwner,
     }
 
     @Override
-    /**
-     * Width is set to the out-most element (v-window).
-     * 
-     * This function should never be called with percentage values (it will
-     * throw an exception)
-     */
     public void setWidth(String width) {
-        this.width = width;
-        if (!isAttached()) {
-            return;
-        }
-        if (width != null && !"".equals(width)) {
-            int rootPixelWidth = -1;
-            if (width.indexOf("px") < 0) {
-                /*
-                 * Convert non-pixel values to pixels by setting the width and
-                 * then measuring it. Updates the "width" variable with the
-                 * pixel width.
-                 */
-                DOM.setStyleAttribute(getElement(), "width", width);
-                rootPixelWidth = getElement().getOffsetWidth();
-                width = rootPixelWidth + "px";
-            } else {
-                rootPixelWidth = Integer.parseInt(width.substring(0,
-                        width.indexOf("px")));
-            }
-
-            // "width" now contains the new width in pixels
-
-            // Apply the new pixel width
-            getElement().getStyle().setProperty("width", width);
-
-            // Caculate the inner width of the content area
-            int contentAreaInnerWidth = rootPixelWidth
-                    - getContentAreaToRootDifference();
-            if (contentAreaInnerWidth < MIN_CONTENT_AREA_WIDTH) {
-                contentAreaInnerWidth = MIN_CONTENT_AREA_WIDTH;
-                int rootWidth = contentAreaInnerWidth
-                        + getContentAreaToRootDifference();
-                DOM.setStyleAttribute(getElement(), "width", rootWidth + "px");
-            }
-
-            updateShadowSizeAndPosition();
-        }
-    }
-
-    @Override
-    /**
-     * Height is set to the out-most element (v-window).
-     * 
-     * This function should never be called with percentage values (it will
-     * throw an exception)
-     * 
-     * @param height A CSS string specifying the new height of the window.
-     *               An empty string or null clears the height and lets
-     *               the browser to compute it based on the window contents. 
-     */
-    public void setHeight(String height) {
-        if (!isAttached()
-                || (height == null ? this.height == null : height
-                        .equals(this.height))) {
-            return;
-        }
-        if (height == null || "".equals(height)) {
-            getElement().getStyle().clearHeight();
-            contentPanel.getElement().getStyle().clearHeight();
+        super.setWidth(width);
+        // Let the width of the heading affect the total width if the window has
+        // undefined width
+        if (width == null || width.length() == 0) {
+            headerText.removeClassName("v-not-spanning");
         } else {
-            getElement().getStyle().setProperty("height", height);
-            int contentHeight = getElement().getOffsetHeight()
-                    - getExtraHeight();
-            if (contentHeight < MIN_CONTENT_AREA_HEIGHT) {
-                contentHeight = MIN_CONTENT_AREA_HEIGHT;
-                int rootHeight = contentHeight + getExtraHeight();
-                getElement().getStyle()
-                        .setProperty("height", rootHeight + "px");
-            }
-            contentPanel.getElement().getStyle()
-                    .setProperty("height", contentHeight + "px");
+            headerText.addClassName("v-not-spanning");
         }
-        this.height = height;
-        updateShadowSizeAndPosition();
     }
 
     int getExtraHeight() {
@@ -949,22 +807,6 @@ public class VWindow extends VOverlay implements ShortcutActionHandlerOwner,
                 true);
     }
 
-    @Override
-    protected void onAttach() {
-        super.onAttach();
-
-        setWidth(width);
-        setHeight(height);
-    }
-
-    void requestLayout() {
-        if (dynamicWidth && !layoutRelativeWidth) {
-            setNaturalWidth();
-        }
-        // layout size change may affect its available space (scrollbars)
-        client.handleComponentRelativeSize(layout.getWidget());
-    }
-
     public ShortcutActionHandler getShortcutActionHandler() {
         return shortcutHandler;
     }
index 7c912756e9914e5a77436cc48459111203f6648b..4ae20af90dfd50f131ae4ef4f27fb3ca082022a1 100644 (file)
@@ -4,6 +4,7 @@
 package com.vaadin.terminal.gwt.client.ui;
 
 import com.google.gwt.core.client.GWT;
+import com.google.gwt.dom.client.Element;
 import com.google.gwt.event.dom.client.DomEvent.Type;
 import com.google.gwt.event.shared.EventHandler;
 import com.google.gwt.event.shared.HandlerRegistration;
@@ -14,8 +15,8 @@ import com.google.gwt.user.client.ui.Frame;
 import com.google.gwt.user.client.ui.Widget;
 import com.vaadin.terminal.gwt.client.ApplicationConnection;
 import com.vaadin.terminal.gwt.client.ComponentConnector;
+import com.vaadin.terminal.gwt.client.LayoutManager;
 import com.vaadin.terminal.gwt.client.UIDL;
-import com.vaadin.terminal.gwt.client.Util;
 import com.vaadin.terminal.gwt.client.ui.ShortcutActionHandler.BeforeShortcutActionListener;
 
 public class WindowConnector extends AbstractComponentContainerConnector
@@ -39,6 +40,13 @@ public class WindowConnector extends AbstractComponentContainerConnector
         return false;
     };
 
+    @Override
+    protected void init() {
+        super.init();
+        getLayoutManager().registerDependency(this,
+                getWidget().contentPanel.getElement());
+    }
+
     @Override
     public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
         getWidget().id = getId();
@@ -144,44 +152,7 @@ public class WindowConnector extends AbstractComponentContainerConnector
             getWidget().layout = lo;
         }
 
-        getWidget().dynamicWidth = getState().isUndefinedWidth();
-        getWidget().dynamicHeight = getState().isUndefinedHeight();
-
-        getWidget().layoutRelativeWidth = uidl
-                .hasAttribute("layoutRelativeWidth");
-        getWidget().layoutRelativeHeight = uidl
-                .hasAttribute("layoutRelativeHeight");
-
-        if (getWidget().dynamicWidth && getWidget().layoutRelativeWidth) {
-            /*
-             * Relative layout width, fix window width before rendering (width
-             * according to caption)
-             */
-            getWidget().setNaturalWidth();
-        }
-
         getWidget().layout.updateFromUIDL(childUidl, client);
-        if (!getWidget().dynamicHeight && getWidget().layoutRelativeWidth) {
-            /*
-             * Relative layout width, and fixed height. Must update the size to
-             * be able to take scrollbars into account (layout gets narrower
-             * space if it is higher than the window) -> only vertical scrollbar
-             */
-            client.runDescendentsLayout(getWidget());
-        }
-
-        /*
-         * No explicit width is set and the layout does not have relative width
-         * so fix the size according to the layout.
-         */
-        if (getWidget().dynamicWidth && !getWidget().layoutRelativeWidth) {
-            getWidget().setNaturalWidth();
-        }
-
-        if (getWidget().dynamicHeight && getWidget().layoutRelativeHeight) {
-            // Prevent resizing until height has been fixed
-            getWidget().resizable = false;
-        }
 
         // we may have actions and notifications
         if (uidl.getChildCount() > 1) {
@@ -206,54 +177,25 @@ public class WindowConnector extends AbstractComponentContainerConnector
                 .getIntVariable("scrollLeft"));
 
         // Center this window on screen if requested
-        // This has to be here because we might not know the content size before
+        // This had to be here because we might not know the content size before
         // everything is painted into the window
         if (uidl.getBooleanAttribute("center")) {
             // mark as centered - this is unset on move/resize
             getWidget().centered = true;
-            getWidget().center();
         } else {
             // don't try to center the window anymore
             getWidget().centered = false;
         }
-        getWidget().updateShadowSizeAndPosition();
         getWidget().setVisible(true);
 
-        boolean sizeReduced = false;
         // ensure window is not larger than browser window
         if (getWidget().getOffsetWidth() > Window.getClientWidth()) {
             getWidget().setWidth(Window.getClientWidth() + "px");
-            sizeReduced = true;
         }
         if (getWidget().getOffsetHeight() > Window.getClientHeight()) {
             getWidget().setHeight(Window.getClientHeight() + "px");
-            sizeReduced = true;
-        }
-
-        if (getWidget().dynamicHeight && getWidget().layoutRelativeHeight) {
-            /*
-             * Window height is undefined, layout is 100% high so the layout
-             * should define the initial window height but on resize the layout
-             * should be as high as the window. We fix the height to deal with
-             * this.
-             */
-
-            int h = getWidget().contents.getOffsetHeight()
-                    + getWidget().getExtraHeight();
-            int w = getWidget().getElement().getOffsetWidth();
-
-            client.updateVariable(getId(), "height", h, false);
-            client.updateVariable(getId(), "width", w, true);
         }
 
-        if (sizeReduced) {
-            // If we changed the size we need to update the size of the child
-            // component if it is relative (#3407)
-            client.runDescendentsLayout(getWidget());
-        }
-
-        Util.runWebkitOverflowAutoFix(getWidget().contentPanel.getElement());
-
         client.getView().getWidget().scrollIntoView(uidl);
 
         if (uidl.hasAttribute("bringToFront")) {
@@ -289,15 +231,29 @@ public class WindowConnector extends AbstractComponentContainerConnector
     }
 
     public void layout() {
-        getWidget().requestLayout();
+        LayoutManager lm = getLayoutManager();
+        VWindow window = getWidget();
+        Element contentElement = window.contentPanel.getElement();
+        if (!window.layout.isUndefinedWidth()
+                && lm.getOuterWidth(contentElement) < VWindow.MIN_CONTENT_AREA_WIDTH) {
+            // Use minimum width if less than a certain size
+            window.setWidth(VWindow.MIN_CONTENT_AREA_WIDTH + "px");
+        }
+
+        if (!window.layout.isUndefinedHeight()
+                && lm.getOuterHeight(contentElement) < VWindow.MIN_CONTENT_AREA_HEIGHT) {
+            // Use minimum height if less than a certain size
+            window.setHeight(VWindow.MIN_CONTENT_AREA_HEIGHT + "px");
+        }
+
     }
 
     public void postLayout() {
         VWindow window = getWidget();
         if (window.centered) {
             window.center();
-            window.updateShadowSizeAndPosition();
         }
+        window.updateShadowSizeAndPosition();
     }
 
 }
index d3095512bbf01e16072be1f0ef536a8133154024..9fc8aa6bf06de1fd4096729e7216c4dd9a0eb959 100644 (file)
@@ -408,11 +408,8 @@ public class ComponentSizeValidator implements Serializable {
         if (parent.getHeight() < 0) {
             // Undefined height
             if (parent instanceof Window) {
-                Window w = (Window) parent;
-                if (w.getParent() == null) {
-                    // main window is considered to have size
-                    return true;
-                }
+                // Sub window with undefined size has a min-height
+                return true;
             }
 
             if (parent instanceof AbstractOrderedLayout) {
@@ -503,12 +500,8 @@ public class ComponentSizeValidator implements Serializable {
             return true;
         }
         if (parent instanceof Window) {
-            Window w = (Window) parent;
-            if (w.getParent() == null) {
-                // main window is considered to have size
-                return true;
-            }
-
+            // Sub window with undefined size has a min-width
+            return true;
         }
 
         if (parent.getWidth() < 0) {
index 886a14d1c75123c7c690e52f9aece50c4869b6fb..5793bcbd0a6bc8b02c03440911e954ea9177050e 100644 (file)
@@ -21,7 +21,6 @@ import com.vaadin.event.ShortcutAction.ModifierKey;
 import com.vaadin.event.ShortcutListener;
 import com.vaadin.terminal.PaintException;
 import com.vaadin.terminal.PaintTarget;
-import com.vaadin.terminal.Sizeable;
 import com.vaadin.terminal.gwt.client.ui.VView;
 import com.vaadin.terminal.gwt.client.ui.WindowConnector;
 
@@ -196,15 +195,6 @@ public class Window extends Panel implements FocusNotifier, BlurNotifier {
             centerRequested = false;
         }
 
-        if (getContent() != null) {
-            if (getContent().getHeightUnits() == Sizeable.UNITS_PERCENTAGE) {
-                target.addAttribute("layoutRelativeHeight", true);
-            }
-            if (getContent().getWidthUnits() == Sizeable.UNITS_PERCENTAGE) {
-                target.addAttribute("layoutRelativeWidth", true);
-            }
-        }
-
         // Contents of the window panel is painted
         super.paintContent(target);
 
@@ -232,6 +222,8 @@ public class Window extends Panel implements FocusNotifier, BlurNotifier {
                 && (getHeightUnits() != UNITS_PIXELS || (Integer) variables
                         .get("height") != getHeight())) {
             sizeHasChanged = true;
+            System.out.println("Got height from server: "
+                    + variables.get("height"));
         }
         if (variables.containsKey("width")
                 && (getWidthUnits() != UNITS_PIXELS || (Integer) variables