]> source.dussan.org Git - vaadin-framework.git/commitdiff
Maximize Restore for Window #3400
authorPekka Hyvönen <pekka@vaadin.com>
Thu, 21 Feb 2013 15:04:48 +0000 (17:04 +0200)
committerVaadin Code Review <review@vaadin.com>
Thu, 4 Apr 2013 12:52:55 +0000 (12:52 +0000)
Change-Id: I164ae83bd6cf98f7a3d7e76d8e717a56e8cb5183

13 files changed:
WebContent/VAADIN/themes/base/window/window.scss
WebContent/VAADIN/themes/reindeer/window/img/maximize.png [new file with mode: 0644]
WebContent/VAADIN/themes/reindeer/window/img/restore.png [new file with mode: 0644]
WebContent/VAADIN/themes/reindeer/window/window.scss
WebContent/VAADIN/themes/runo/window/window.scss
client/src/com/vaadin/client/ui/AbstractComponentConnector.java
client/src/com/vaadin/client/ui/VWindow.java
client/src/com/vaadin/client/ui/window/WindowConnector.java
server/src/com/vaadin/ui/Window.java
shared/src/com/vaadin/shared/ui/window/WindowServerRpc.java
shared/src/com/vaadin/shared/ui/window/WindowState.java
uitest/src/com/vaadin/tests/components/window/WindowMaximizeRestoreTest.html [new file with mode: 0644]
uitest/src/com/vaadin/tests/components/window/WindowMaximizeRestoreTest.java [new file with mode: 0644]

index b9e7b541399dc045b0a0e9f1e31866b8231936e1..05f3b115ad7ed0e3f2f9a8b83966ba34f3dfaa48 100644 (file)
 }
 .#{$primaryStyleName}-header {
        font-weight: bold;
+       -khtml-user-select: none;
+       -moz-user-select: none;
+       -ie-user-select: none;
+       user-select: none;
 }
 /* A more specific selector to make sure padding isn't so easily overridden */
 div.#{$primaryStyleName}-header {
@@ -77,20 +81,37 @@ div.#{$primaryStyleName}-header {
 .#{$primaryStyleName} div.#{$primaryStyleName}-footer-noresize {
        height: 0;
 }
-.#{$primaryStyleName}-resizebox-disabled {
+.#{$primaryStyleName}-resizebox-disabled,
+.#{$primaryStyleName}-restorebox-disabled,
+.#{$primaryStyleName}-maximizebox-disabled {
        cursor: default;
        display: none;
 }
-.#{$primaryStyleName}-closebox {
+.#{$primaryStyleName}-closebox,
+.#{$primaryStyleName}-restorebox,
+.#{$primaryStyleName}-maximizebox {
        position: absolute;
        top: 0;
        right: 0;
        width: 1em;
        height: 1em;
-       background: red;
        cursor: pointer;
        overflow: hidden;
 }
+.#{$primaryStyleName}-maximizebox,
+.#{$primaryStyleName}-restorebox {
+       right: 1.1em;
+}
+
+.#{$primaryStyleName}-closebox {
+       background: red;
+}
+.#{$primaryStyleName}-maximizebox {
+       background: blue;
+}
+.#{$primaryStyleName}-restorebox {
+       background: yellow;
+}
 .#{$primaryStyleName}-modalitycurtain {
        top: 0;
        left: 0;
diff --git a/WebContent/VAADIN/themes/reindeer/window/img/maximize.png b/WebContent/VAADIN/themes/reindeer/window/img/maximize.png
new file mode 100644 (file)
index 0000000..86ffff9
Binary files /dev/null and b/WebContent/VAADIN/themes/reindeer/window/img/maximize.png differ
diff --git a/WebContent/VAADIN/themes/reindeer/window/img/restore.png b/WebContent/VAADIN/themes/reindeer/window/img/restore.png
new file mode 100644 (file)
index 0000000..119ea04
Binary files /dev/null and b/WebContent/VAADIN/themes/reindeer/window/img/restore.png differ
index e6a73ee2c0084ad89ea9b1011d48ef0953f232b8..7a05e52aecfd979accae0bbe5af2ba4a5c18c1ec 100644 (file)
@@ -14,7 +14,7 @@
        border-color: rgba(0,0,0,.2);
 }
 .#{$primaryStyleName}-outerheader {
-       padding: 12px 32px 0 14px;
+       padding: 12px 52px 0 14px;
        height: 37px;
        background: black repeat-x;
        background-image: url(img/header-bg.png); /** sprite-ref: verticals; sprite-alignment: repeat */
 .#{$primaryStyleName}-closebox:active {
        background-image: url(img/close-pressed.png); /** sprite-ref: verticals */
 }
+.#{$primaryStyleName}-maximizebox,
+.#{$primaryStyleName}-restorebox {
+       top: 12px;
+       right: 28px;
+       width: 15px;
+       height: 16px;
+       background: transparent;
+}
+.#{$primaryStyleName}-maximizebox {
+       &, &:hover,&:active {
+               background-image: url(img/maximize.png); /** sprite-ref: verticals */
+       }
+}
+.#{$primaryStyleName}-restorebox {
+       &, &:hover,&:active {
+               background-image: url(img/restore.png); /** sprite-ref: verticals */
+       }
+}
 .#{$primaryStyleName}-contents {
        background: #fff;
 }
index 994238f2ad344003dc49d2afffdb03c26fbccbea..db153243e983e0bc4bfaba547eab771547f2b86f 100644 (file)
        background: transparent;
        display: block;
 }
-.#{$primaryStyleName}-closebox {
+.#{$primaryStyleName}-closebox,
+.#{$primaryStyleName}-maximizebox,
+.#{$primaryStyleName}-restorebox {
        position: absolute;
        top: 21px;
-       right: 24px;
        width: 12px;
        height: 12px;
        background: transparent url(img/close.png);
 }
+.#{$primaryStyleName}-closebox {
+       right: 24px;
+       background: transparent url(img/close.png);
+}
+
+.#{$primaryStyleName}-maximizebox,
+.#{$primaryStyleName}-restorebox {
+       right: 42px;
+}
+
+.#{$primaryStyleName}-maximizebox {
+       background: transparent url(img/maximize.png);
+}
+
+.#{$primaryStyleName}-restorebox {
+       background: transparent url(img/restore.png);
+}
+
 .#{$primaryStyleName}-closebox:hover {
        background-position: 0 -12px;
 }
index ecd6abae08a0976f8b92c2767c1522e03df0c4e6..e7f73799940f4296843c1de4b88f1881777da826 100644 (file)
@@ -36,6 +36,8 @@ import com.vaadin.client.metadata.NoDataException;
 import com.vaadin.client.metadata.Type;
 import com.vaadin.client.metadata.TypeData;
 import com.vaadin.client.metadata.TypeDataStore;
+import com.vaadin.client.ui.AbstractFieldConnector;
+import com.vaadin.client.ui.ManagedLayout;
 import com.vaadin.client.ui.datefield.PopupDateFieldConnector;
 import com.vaadin.client.ui.ui.UIConnector;
 import com.vaadin.shared.AbstractComponentState;
@@ -205,12 +207,12 @@ public abstract class AbstractComponentConnector extends AbstractConnector
         }
     }
 
-    private void updateComponentSize() {
-        Profiler.enter("AbstractComponentConnector.updateComponentSize");
-
-        String newWidth = getState().width == null ? "" : getState().width;
-        String newHeight = getState().height == null ? "" : getState().height;
+    protected void updateComponentSize() {
+        updateComponentSize(getState().width == null ? "" : getState().width,
+                getState().height == null ? "" : getState().height);
+    }
 
+    protected void updateComponentSize(String newWidth, String newHeight) {
         // Parent should be updated if either dimension changed between relative
         // and non-relative
         if (newWidth.endsWith("%") != lastKnownWidth.endsWith("%")) {
index fd2a7013340c710f5c878602701ed5d86a2be81f..bd9a0ed07c1955e22c2ea7e2934e2f4292d45f2f 100644 (file)
@@ -49,6 +49,7 @@ import com.vaadin.client.LayoutManager;
 import com.vaadin.client.Util;
 import com.vaadin.client.ui.ShortcutActionHandler.ShortcutActionHandlerOwner;
 import com.vaadin.shared.EventId;
+import com.vaadin.shared.ui.window.WindowState.DisplayState;
 
 /**
  * "Sub window" component.
@@ -58,18 +59,6 @@ import com.vaadin.shared.EventId;
 public class VWindow extends VOverlay implements ShortcutActionHandlerOwner,
         ScrollHandler, KeyDownHandler, FocusHandler, BlurHandler, Focusable {
 
-    /**
-     * 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;
-
-    /**
-     * 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;
-
     private static ArrayList<VWindow> windowOrder = new ArrayList<VWindow>();
 
     private static boolean orderingDefered;
@@ -113,6 +102,9 @@ public class VWindow extends VOverlay implements ShortcutActionHandlerOwner,
     /** For internal use only. May be removed or replaced in the future. */
     public Element closeBox;
 
+    /** For internal use only. May be removed or replaced in the future. */
+    public Element maximizeRestoreBox;
+
     /** For internal use only. May be removed or replaced in the future. */
     public ApplicationConnection client;
 
@@ -262,6 +254,9 @@ public class VWindow extends VOverlay implements ShortcutActionHandlerOwner,
         resizeBox = DOM.createDiv();
         DOM.setElementProperty(resizeBox, "className", CLASSNAME + "-resizebox");
         closeBox = DOM.createDiv();
+        maximizeRestoreBox = DOM.createDiv();
+        DOM.setElementProperty(maximizeRestoreBox, "className", CLASSNAME
+                + "-maximizebox");
         DOM.setElementProperty(closeBox, "className", CLASSNAME + "-closebox");
         DOM.appendChild(footer, resizeBox);
 
@@ -269,14 +264,15 @@ public class VWindow extends VOverlay implements ShortcutActionHandlerOwner,
         DOM.setElementProperty(wrapper, "className", CLASSNAME + "-wrap");
 
         DOM.appendChild(wrapper, header);
+        DOM.appendChild(wrapper, maximizeRestoreBox);
         DOM.appendChild(wrapper, closeBox);
         DOM.appendChild(header, headerText);
         DOM.appendChild(wrapper, contents);
         DOM.appendChild(wrapper, footer);
         DOM.appendChild(super.getContainerElement(), wrapper);
 
-        sinkEvents(Event.MOUSEEVENTS | Event.TOUCHEVENTS | Event.ONCLICK
-                | Event.ONLOSECAPTURE);
+        sinkEvents(Event.ONDBLCLICK | Event.MOUSEEVENTS | Event.TOUCHEVENTS
+                | Event.ONCLICK | Event.ONLOSECAPTURE);
 
         setWidget(contentPanel);
 
@@ -575,6 +571,31 @@ public class VWindow extends VOverlay implements ShortcutActionHandlerOwner,
         }
     }
 
+    public void updateMaximizeRestoreClassName(boolean visible,
+            DisplayState state) {
+        String className;
+        if (state == DisplayState.MAXIMIZED) {
+            className = CLASSNAME + "-restorebox";
+        } else {
+            className = CLASSNAME + "-maximizebox";
+        }
+        if (!visible) {
+            className = className + " " + className + "-disabled";
+        }
+        maximizeRestoreBox.setClassName(className);
+    }
+
+    // TODO this will eventually be removed, currently used to avoid updating to
+    // server side.
+    public void setPopupPositionNoUpdate(int left, int top) {
+        if (top < 0) {
+            // ensure window is not moved out of browser window from top of the
+            // screen
+            top = 0;
+        }
+        super.setPopupPosition(left, top);
+    }
+
     @Override
     public void setPopupPosition(int left, int top) {
         if (top < 0) {
@@ -616,6 +637,8 @@ public class VWindow extends VOverlay implements ShortcutActionHandlerOwner,
         return contents;
     }
 
+    private Event headerDragPending;
+
     @Override
     public void onBrowserEvent(final Event event) {
         boolean bubble = true;
@@ -632,6 +655,28 @@ public class VWindow extends VOverlay implements ShortcutActionHandlerOwner,
                 onCloseClick();
             }
             bubble = false;
+        } else if (target == maximizeRestoreBox) {
+            // handled in connector
+            if (type != Event.ONCLICK) {
+                bubble = false;
+            }
+        } else if (header.isOrHasChild(target) && !dragging) {
+            // dblclick handled in connector
+            if (type != Event.ONDBLCLICK && draggable) {
+                if (type == Event.ONMOUSEDOWN) {
+                    headerDragPending = event;
+                } else if (type == Event.ONMOUSEMOVE
+                        && headerDragPending != null) {
+                    // ie won't work unless this is set here
+                    dragging = true;
+                    onDragEvent(headerDragPending);
+                    onDragEvent(event);
+                    headerDragPending = null;
+                } else {
+                    headerDragPending = null;
+                }
+                bubble = false;
+            }
         } else if (dragging || !contents.isOrHasChild(target)) {
             onDragEvent(event);
             bubble = false;
@@ -648,7 +693,7 @@ public class VWindow extends VOverlay implements ShortcutActionHandlerOwner,
          */
         if (type == Event.ONMOUSEDOWN
                 && !contentPanel.getElement().isOrHasChild(target)
-                && target != closeBox) {
+                && target != closeBox && target != maximizeRestoreBox) {
             contentPanel.focus();
         }
 
@@ -746,16 +791,7 @@ public class VWindow extends VOverlay implements ShortcutActionHandlerOwner,
         }
 
         int w = Util.getTouchOrMouseClientX(event) - startX + origW;
-        int minWidth = getMinWidth();
-        if (w < minWidth) {
-            w = minWidth;
-        }
-
         int h = Util.getTouchOrMouseClientY(event) - startY + origH;
-        int minHeight = getMinHeight();
-        if (h < minHeight) {
-            h = minHeight;
-        }
 
         setWidth(w + "px");
         setHeight(h + "px");
@@ -775,7 +811,7 @@ public class VWindow extends VOverlay implements ShortcutActionHandlerOwner,
         }
     }
 
-    private void updateContentsSize() {
+    public void updateContentsSize() {
         LayoutManager layoutManager = getLayoutManager();
         layoutManager.setNeedsMeasure(ConnectorMap.get(client).getConnector(
                 this));
@@ -959,10 +995,6 @@ public class VWindow extends VOverlay implements ShortcutActionHandlerOwner,
         contentPanel.focus();
     }
 
-    public int getMinHeight() {
-        return MIN_CONTENT_AREA_HEIGHT + getDecorationHeight();
-    }
-
     private int getDecorationHeight() {
         LayoutManager lm = getLayoutManager();
         int headerHeight = lm.getOuterHeight(header);
@@ -974,10 +1006,6 @@ public class VWindow extends VOverlay implements ShortcutActionHandlerOwner,
         return LayoutManager.get(client);
     }
 
-    public int getMinWidth() {
-        return MIN_CONTENT_AREA_WIDTH + getDecorationWidth();
-    }
-
     private int getDecorationWidth() {
         LayoutManager layoutManager = getLayoutManager();
         return layoutManager.getOuterWidth(getElement())
index 8cfc25a9dcf6ad18618d8e21299e518117605c26..66907fbfa479850a104de0b0cc63365bc55a246e 100644 (file)
@@ -20,7 +20,10 @@ import com.google.gwt.dom.client.NativeEvent;
 import com.google.gwt.dom.client.Style;
 import com.google.gwt.dom.client.Style.Position;
 import com.google.gwt.dom.client.Style.Unit;
-import com.google.gwt.user.client.DOM;
+import com.google.gwt.event.dom.client.ClickEvent;
+import com.google.gwt.event.dom.client.ClickHandler;
+import com.google.gwt.event.dom.client.DoubleClickEvent;
+import com.google.gwt.event.dom.client.DoubleClickHandler;
 import com.google.gwt.user.client.Event;
 import com.google.gwt.user.client.Window;
 import com.vaadin.client.ApplicationConnection;
@@ -31,6 +34,7 @@ import com.vaadin.client.LayoutManager;
 import com.vaadin.client.Paintable;
 import com.vaadin.client.UIDL;
 import com.vaadin.client.Util;
+import com.vaadin.client.communication.StateChangeEvent;
 import com.vaadin.client.ui.AbstractSingleComponentContainerConnector;
 import com.vaadin.client.ui.ClickEventHandler;
 import com.vaadin.client.ui.PostLayoutListener;
@@ -43,6 +47,7 @@ import com.vaadin.shared.MouseEventDetails;
 import com.vaadin.shared.ui.Connect;
 import com.vaadin.shared.ui.window.WindowServerRpc;
 import com.vaadin.shared.ui.window.WindowState;
+import com.vaadin.shared.ui.window.WindowState.DisplayState;
 
 @Connect(value = com.vaadin.ui.Window.class)
 public class WindowConnector extends AbstractSingleComponentContainerConnector
@@ -57,7 +62,32 @@ public class WindowConnector extends AbstractSingleComponentContainerConnector
         }
     };
 
-    boolean minWidthChecked = false;
+    abstract class WindowEventHandler implements ClickHandler,
+            DoubleClickHandler {
+    }
+
+    private WindowEventHandler maximizeRestoreClickHandler = new WindowEventHandler() {
+
+        @Override
+        public void onClick(ClickEvent event) {
+            final Element target = event.getNativeEvent().getEventTarget()
+                    .cast();
+            if (target == getWidget().maximizeRestoreBox) {
+                // Click on maximize/restore box
+                onMaximizeRestore();
+            }
+        }
+
+        @Override
+        public void onDoubleClick(DoubleClickEvent event) {
+            final Element target = event.getNativeEvent().getEventTarget()
+                    .cast();
+            if (getWidget().header.isOrHasChild(target)) {
+                // Double click on header
+                onMaximizeRestore();
+            }
+        }
+    };
 
     @Override
     public boolean delegateCaptionHandling() {
@@ -68,12 +98,18 @@ public class WindowConnector extends AbstractSingleComponentContainerConnector
     protected void init() {
         super.init();
 
+        VWindow window = getWidget();
+
         getLayoutManager().registerDependency(this,
-                getWidget().contentPanel.getElement());
-        getLayoutManager().registerDependency(this, getWidget().header);
-        getLayoutManager().registerDependency(this, getWidget().footer);
+                window.contentPanel.getElement());
+        getLayoutManager().registerDependency(this, window.header);
+        getLayoutManager().registerDependency(this, window.footer);
 
-        getWidget().setOwner(getConnection().getUIConnector().getWidget());
+        window.addHandler(maximizeRestoreClickHandler, ClickEvent.getType());
+        window.addHandler(maximizeRestoreClickHandler,
+                DoubleClickEvent.getType());
+
+        window.setOwner(getConnection().getUIConnector().getWidget());
     }
 
     @Override
@@ -87,109 +123,46 @@ public class WindowConnector extends AbstractSingleComponentContainerConnector
 
     @Override
     public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
-        getWidget().id = getConnectorId();
-        getWidget().client = client;
-
-        // Workaround needed for Testing Tools (GWT generates window DOM
-        // slightly different in different browsers).
-        DOM.setElementProperty(getWidget().closeBox, "id", getConnectorId()
-                + "_window_close");
 
-        if (isRealUpdate(uidl)) {
-            if (getState().modal != getWidget().vaadinModality) {
-                getWidget().setVaadinModality(!getWidget().vaadinModality);
-            }
-            if (!getWidget().isAttached()) {
-                getWidget().setVisible(false); // hide until
-                // possible centering
-                getWidget().show();
-            }
-            if (getState().resizable != getWidget().resizable) {
-                getWidget().setResizable(getState().resizable);
-            }
-            getWidget().resizeLazy = getState().resizeLazy;
+        VWindow window = getWidget();
+        String connectorId = getConnectorId();
 
-            getWidget().setDraggable(getState().draggable);
+        window.id = getConnectorId();
+        window.client = client;
 
-            // Caption must be set before required header size is measured. If
-            // the caption attribute is missing the caption should be cleared.
-            String iconURL = null;
-            if (getIcon() != null) {
-                iconURL = getIcon();
-            }
-            getWidget().setCaption(getState().caption, iconURL);
-        }
+        // Workaround needed for Testing Tools (GWT generates window DOM
+        // slightly different in different browsers).
+        window.closeBox.setId(connectorId + "_window_close");
+        window.maximizeRestoreBox
+                .setId(connectorId + "_window_maximizerestore");
 
-        getWidget().visibilityChangesDisabled = true;
+        window.visibilityChangesDisabled = true;
         if (!isRealUpdate(uidl)) {
             return;
         }
-        getWidget().visibilityChangesDisabled = false;
-
-        clickEventHandler.handleEventHandlerRegistration();
-
-        getWidget().immediate = getState().immediate;
-
-        getWidget().setClosable(!isReadOnly());
-
-        // Initialize the position form UIDL
-        int positionx = getState().positionX;
-        int positiony = getState().positionY;
-        if (positionx >= 0 || positiony >= 0) {
-            if (positionx < 0) {
-                positionx = 0;
-            }
-            if (positiony < 0) {
-                positiony = 0;
-            }
-            getWidget().setPopupPosition(positionx, positiony);
-        }
-
-        int childIndex = 0;
+        window.visibilityChangesDisabled = false;
 
         // we may have actions
         for (int i = 0; i < uidl.getChildCount(); i++) {
             UIDL childUidl = uidl.getChildUIDL(i);
             if (childUidl.getTag().equals("actions")) {
-                if (getWidget().shortcutHandler == null) {
-                    getWidget().shortcutHandler = new ShortcutActionHandler(
-                            getConnectorId(), client);
+                if (window.shortcutHandler == null) {
+                    window.shortcutHandler = new ShortcutActionHandler(
+                            connectorId, client);
                 }
-                getWidget().shortcutHandler.updateActionMap(childUidl);
+                window.shortcutHandler.updateActionMap(childUidl);
             }
 
         }
 
-        // setting scrollposition must happen after children is rendered
-        getWidget().contentPanel.setScrollPosition(getState().scrollTop);
-        getWidget().contentPanel
-                .setHorizontalScrollPosition(getState().scrollLeft);
-
-        // Center this window on screen if requested
-        // This had to be here because we might not know the content size before
-        // everything is painted into the window
-
-        // centered is this is unset on move/resize
-        getWidget().centered = getState().centered;
-        getWidget().setVisible(true);
-
-        // ensure window is not larger than browser window
-        if (getWidget().getOffsetWidth() > Window.getClientWidth()) {
-            getWidget().setWidth(Window.getClientWidth() + "px");
-        }
-        if (getWidget().getOffsetHeight() > Window.getClientHeight()) {
-            getWidget().setHeight(Window.getClientHeight() + "px");
-        }
-
         if (uidl.hasAttribute("bringToFront")) {
             /*
              * Focus as a side-effect. Will be overridden by
              * ApplicationConnection if another component was focused by the
              * server side.
              */
-            getWidget().contentPanel.focus();
-            getWidget().bringToFrontSequence = uidl
-                    .getIntAttribute("bringToFront");
+            window.contentPanel.focus();
+            window.bringToFrontSequence = uidl.getIntAttribute("bringToFront");
             VWindow.deferOrdering();
         }
     }
@@ -224,26 +197,6 @@ public class WindowConnector extends AbstractSingleComponentContainerConnector
         boolean hasContent = (content != null);
         Element contentElement = window.contentPanel.getElement();
 
-        if (!minWidthChecked) {
-            boolean needsMinWidth = !isUndefinedWidth() || !hasContent
-                    || content.isRelativeWidth();
-            int minWidth = window.getMinWidth();
-            if (needsMinWidth && lm.getInnerWidth(contentElement) < minWidth) {
-                minWidthChecked = true;
-                // Use minimum width if less than a certain size
-                window.setWidth(minWidth + "px");
-            }
-            minWidthChecked = true;
-        }
-
-        boolean needsMinHeight = !isUndefinedHeight() || !hasContent
-                || content.isRelativeHeight();
-        int minHeight = window.getMinHeight();
-        if (needsMinHeight && lm.getInnerHeight(contentElement) < minHeight) {
-            // Use minimum height if less than a certain size
-            window.setHeight(minHeight + "px");
-        }
-
         Style contentStyle = window.contents.getStyle();
 
         int headerHeight = lm.getOuterHeight(window.header);
@@ -291,9 +244,9 @@ public class WindowConnector extends AbstractSingleComponentContainerConnector
 
     @Override
     public void postLayout() {
-        minWidthChecked = false;
         VWindow window = getWidget();
-        if (window.centered) {
+        if (window.centered
+                && getState().displayState != DisplayState.MAXIMIZED) {
             window.center();
         }
         window.positionOrSizeUpdated();
@@ -304,6 +257,124 @@ public class WindowConnector extends AbstractSingleComponentContainerConnector
         return (WindowState) super.getState();
     }
 
+    @Override
+    public void onStateChanged(StateChangeEvent stateChangeEvent) {
+        super.onStateChanged(stateChangeEvent);
+
+        VWindow window = getWidget();
+        WindowState state = getState();
+
+        if (state.modal != window.vaadinModality) {
+            window.setVaadinModality(!window.vaadinModality);
+        }
+        if (!window.isAttached()) {
+            window.setVisible(false); // hide until possible centering
+            window.show();
+        }
+        boolean resizeable = state.resizable
+                && state.displayState == DisplayState.NORMAL;
+        window.setResizable(resizeable);
+
+        window.resizeLazy = state.resizeLazy;
+
+        window.setDraggable(state.draggable
+                && state.displayState == DisplayState.NORMAL);
+
+        window.updateMaximizeRestoreClassName(state.resizable,
+                state.displayState);
+
+        // Caption must be set before required header size is measured. If
+        // the caption attribute is missing the caption should be cleared.
+        String iconURL = null;
+        if (getIcon() != null) {
+            iconURL = getIcon();
+        }
+        window.setCaption(state.caption, iconURL);
+
+        clickEventHandler.handleEventHandlerRegistration();
+
+        window.immediate = state.immediate;
+
+        window.setClosable(!isReadOnly());
+        // initialize position from state
+        updateWindowPosition();
+
+        // setting scrollposition must happen after children is rendered
+        window.contentPanel.setScrollPosition(state.scrollTop);
+        window.contentPanel.setHorizontalScrollPosition(state.scrollLeft);
+
+        // Center this window on screen if requested
+        // This had to be here because we might not know the content size before
+        // everything is painted into the window
+
+        // centered is this is unset on move/resize
+        window.centered = state.centered;
+        window.setVisible(true);
+
+        // ensure window is not larger than browser window
+        if (window.getOffsetWidth() > Window.getClientWidth()) {
+            window.setWidth(Window.getClientWidth() + "px");
+        }
+        if (window.getOffsetHeight() > Window.getClientHeight()) {
+            window.setHeight(Window.getClientHeight() + "px");
+        }
+    }
+
+    // Need to override default because of DisplayState
+    @Override
+    protected void updateComponentSize() {
+        if (getState().displayState == DisplayState.NORMAL) {
+            super.updateComponentSize();
+        } else if (getState().displayState == DisplayState.MAXIMIZED) {
+            super.updateComponentSize("100%", "100%");
+        }
+    }
+
+    protected void updateWindowPosition() {
+        VWindow window = getWidget();
+        WindowState state = getState();
+        if (state.displayState == DisplayState.NORMAL) {
+            // if centered, position handled in postLayout()
+            if (!state.centered) {
+                window.setPopupPosition(state.positionX, state.positionY);
+            }
+        } else if (state.displayState == DisplayState.MAXIMIZED) {
+            window.setPopupPositionNoUpdate(0, 0);
+            window.bringToFront();
+        }
+    }
+
+    protected void updateDisplayState() {
+        VWindow window = getWidget();
+        WindowState state = getState();
+
+        // update draggable on widget
+        window.setDraggable(state.draggable
+                && state.displayState == DisplayState.NORMAL);
+        // update resizable on widget
+        window.setResizable(state.resizable
+                && state.displayState == DisplayState.NORMAL);
+        updateComponentSize();
+        updateWindowPosition();
+        window.updateMaximizeRestoreClassName(state.resizable,
+                state.displayState);
+        window.updateContentsSize();
+    }
+
+    protected void onMaximizeRestore() {
+        WindowState state = getState();
+        if (state.resizable) {
+            if (state.displayState == DisplayState.MAXIMIZED) {
+                state.displayState = DisplayState.NORMAL;
+            } else {
+                state.displayState = DisplayState.MAXIMIZED;
+            }
+            updateDisplayState();
+            getRpcProxy(WindowServerRpc.class).windowDisplayStateChanged(
+                    state.displayState);
+        }
+    }
+
     /**
      * Gives the WindowConnector an order number. As a side effect, moves the
      * window according to its order number so the windows are stacked. This
index d8b33e6b25d2513bc9673b51928b7b048c74bcc0..0c1509663abb3f12e0618d1b04fb9a1783d49bde 100644 (file)
@@ -37,6 +37,8 @@ import com.vaadin.server.PaintTarget;
 import com.vaadin.shared.MouseEventDetails;
 import com.vaadin.shared.ui.window.WindowServerRpc;
 import com.vaadin.shared.ui.window.WindowState;
+import com.vaadin.shared.ui.window.WindowState.DisplayState;
+import com.vaadin.util.ReflectTools;
 
 /**
  * A component that represents a floating popup window that can be added to a
@@ -71,6 +73,11 @@ public class Window extends Panel implements FocusNotifier, BlurNotifier,
         public void click(MouseEventDetails mouseDetails) {
             fireEvent(new ClickEvent(Window.this, mouseDetails));
         }
+
+        @Override
+        public void windowDisplayStateChanged(DisplayState newState) {
+            setDisplayState(newState);
+        }
     };
 
     /**
@@ -234,10 +241,11 @@ public class Window extends Panel implements FocusNotifier, BlurNotifier,
 
     /**
      * Gets the distance of Window left border in pixels from left border of the
-     * containing (main window).
+     * containing (main window) when the window is in
+     * {@link DisplayState#NORMAL}.
      * 
      * @return the Distance of Window left border in pixels from left border of
-     *         the containing (main window). or -1 if unspecified.
+     *         the containing (main window).or -1 if unspecified
      * @since 4.0.0
      */
     public int getPositionX() {
@@ -246,7 +254,8 @@ public class Window extends Panel implements FocusNotifier, BlurNotifier,
 
     /**
      * Sets the distance of Window left border in pixels from left border of the
-     * containing (main window).
+     * containing (main window). Has effect only if in
+     * {@link DisplayState#NORMAL} mode.
      * 
      * @param positionX
      *            the Distance of Window left border in pixels from left border
@@ -260,10 +269,11 @@ public class Window extends Panel implements FocusNotifier, BlurNotifier,
 
     /**
      * Gets the distance of Window top border in pixels from top border of the
-     * containing (main window).
+     * containing (main window) when the window is in
+     * {@link DisplayState#NORMAL} state, or when next set to that state.
      * 
      * @return Distance of Window top border in pixels from top border of the
-     *         containing (main window). or -1 if unspecified .
+     *         containing (main window). or -1 if unspecified
      * 
      * @since 4.0.0
      */
@@ -273,7 +283,8 @@ public class Window extends Panel implements FocusNotifier, BlurNotifier,
 
     /**
      * Sets the distance of Window top border in pixels from top border of the
-     * containing (main window).
+     * containing (main window). Has effect only if in
+     * {@link DisplayState#NORMAL} mode.
      * 
      * @param positionY
      *            the Distance of Window top border in pixels from top border of
@@ -401,6 +412,104 @@ public class Window extends Panel implements FocusNotifier, BlurNotifier,
         fireEvent(new Window.CloseEvent(this));
     }
 
+    /**
+     * Event which is fired when the display state of the Window changes.
+     * 
+     * @author Vaadin Ltd
+     * @since 7.1
+     * 
+     */
+    public static class DisplayStateChangeEvent extends Component.Event {
+
+        private final DisplayState displayState;
+
+        /**
+         * 
+         * @param source
+         */
+        public DisplayStateChangeEvent(Component source,
+                DisplayState displayState) {
+            super(source);
+            this.displayState = displayState;
+        }
+
+        /**
+         * Gets the Window.
+         * 
+         * @return the window
+         */
+        public Window getWindow() {
+            return (Window) getSource();
+        }
+
+        /**
+         * Gets the new DisplayState.
+         * 
+         * @return the displayState
+         */
+        public DisplayState getDisplayState() {
+            return displayState;
+        }
+    }
+
+    /**
+     * An interface used for listening to Window maximize / restore events. Add
+     * the DisplayStateChangeListener to a window and
+     * {@link DisplayStateChangeListener#displayStateChanged(DisplayStateChangeEvent)}
+     * will be called whenever the window is maximized (
+     * {@link DisplayState#MAXIMIZED}) or restored ({@link DisplayState#NORMAL}
+     * ).
+     */
+    public interface DisplayStateChangeListener extends Serializable {
+
+        public static final Method displayStateChangeMethod = ReflectTools
+                .findMethod(DisplayStateChangeListener.class,
+                        "displayStateChanged", DisplayStateChangeEvent.class);
+
+        /**
+         * Called when the user maximizes / restores a window. Use
+         * {@link DisplayStateChangeEvent#getWindow()} to get a reference to the
+         * {@link Window} that was maximized / restored. Use
+         * {@link DisplayStateChangeEvent#getDisplayState()} to get a reference
+         * to the new state.
+         * 
+         * @param event
+         */
+        public void displayStateChanged(DisplayStateChangeEvent event);
+    }
+
+    /**
+     * Adds a DisplayStateChangeListener to the window.
+     * 
+     * The DisplayStateChangeEvent is fired when the user changed the display
+     * state by clicking the maximize/restore button or by double clicking on
+     * the window header. The event is also fired if the state is changed using
+     * {@link #setDisplayState(DisplayState)}.
+     * 
+     * @param listener
+     *            the DisplayStateChangeListener to add.
+     */
+    public void addDisplayStateChangeListener(DisplayStateChangeListener listener) {
+        addListener(DisplayStateChangeEvent.class, listener,
+                DisplayStateChangeListener.displayStateChangeMethod);
+    }
+
+    /**
+     * Removes the DisplayStateChangeListener from the window.
+     * 
+     * @param listener
+     *            the DisplayStateChangeListener to remove.
+     */
+    public void removeDisplayStateChangeListener(DisplayStateChangeListener listener) {
+        removeListener(DisplayStateChangeEvent.class, listener,
+                DisplayStateChangeListener.displayStateChangeMethod);
+    }
+
+    protected void fireWindowDisplayStateChange() {
+        fireEvent(new Window.DisplayStateChangeEvent(this,
+                getState().displayState));
+    }
+
     /**
      * Method for the resize event.
      */
@@ -670,6 +779,27 @@ public class Window extends Panel implements FocusNotifier, BlurNotifier,
         getState().draggable = draggable;
     }
 
+    /**
+     * Gets the current DisplayState of the window.
+     * 
+     * @return displayState the current DisplayState.
+     */
+    public DisplayState getDisplayState() {
+        return getState(false).displayState;
+    }
+
+    /**
+     * Sets the DisplayState for the window.
+     * 
+     * @param displayState
+     */
+    public void setDisplayState(DisplayState displayState) {
+        if (displayState != getDisplayState()) {
+            getState().displayState = displayState;
+            fireWindowDisplayStateChange();
+        }
+    }
+
     /*
      * Actions
      */
@@ -873,4 +1003,9 @@ public class Window extends Panel implements FocusNotifier, BlurNotifier,
     protected WindowState getState() {
         return (WindowState) super.getState();
     }
+
+    @Override
+    protected WindowState getState(boolean markAsDirty) {
+        return (WindowState) super.getState(markAsDirty);
+    }
 }
index c42f91c00670fb0118263082566801ba82b5937c..0128adca407c5c26263d1f462bf782ca2513a0c5 100644 (file)
  */
 package com.vaadin.shared.ui.window;
 
+import com.vaadin.shared.annotations.Delayed;
 import com.vaadin.shared.communication.ServerRpc;
 import com.vaadin.shared.ui.ClickRpc;
+import com.vaadin.shared.ui.window.WindowState.DisplayState;
 
 public interface WindowServerRpc extends ClickRpc, ServerRpc {
+
+    @Delayed(lastOnly = true)
+    public void windowDisplayStateChanged(DisplayState newState);
+
 }
\ No newline at end of file
index 4afc20f2b168b1069fc9ba58af46aa7c0dd398b2..eb6f1c758acffc237b5b35a84d2ca7247fd4937b 100644 (file)
@@ -21,6 +21,11 @@ public class WindowState extends PanelState {
     {
         primaryStyleName = "v-window";
     }
+
+    public enum DisplayState {
+        NORMAL, MAXIMIZED;
+    }
+
     public boolean modal = false;
     public boolean resizable = true;
     public boolean resizeLazy = false;
@@ -28,4 +33,5 @@ public class WindowState extends PanelState {
     public boolean centered = false;;
     public int positionX = -1;
     public int positionY = -1;
+    public DisplayState displayState = DisplayState.NORMAL;
 }
\ No newline at end of file
diff --git a/uitest/src/com/vaadin/tests/components/window/WindowMaximizeRestoreTest.html b/uitest/src/com/vaadin/tests/components/window/WindowMaximizeRestoreTest.html
new file mode 100644 (file)
index 0000000..090579d
--- /dev/null
@@ -0,0 +1,228 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head profile="http://selenium-ide.openqa.org/profiles/test-case">
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+<link rel="selenium.base" href="http://localhost:8888/run/" />
+<title>WindowMaximizeRestoreTest</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">WindowMaximizeRestoreTest</td></tr>
+</thead><tbody>
+<tr>
+       <td>open</td>
+       <td>/run/com.vaadin.tests.components.window.WindowMaximizeRestoreTest?restartApplication</td>
+       <td></td>
+</tr>
+<!--Test maximize-restore button-->
+<tr>
+       <td>assertCSSClass</td>
+       <td>vaadin=runcomvaadintestscomponentswindowWindowMaximizeRestoreTest::/VWindow[0]/domChild[0]/domChild[0]/domChild[1]</td>
+       <td>v-window-maximizebox</td>
+</tr>
+<tr>
+       <td>assertText</td>
+       <td>vaadin=runcomvaadintestscomponentswindowWindowMaximizeRestoreTest::/VWindow[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]</td>
+       <td>Window 1</td>
+</tr>
+<tr>
+       <td>mouseClick</td>
+       <td>vaadin=runcomvaadintestscomponentswindowWindowMaximizeRestoreTest::/VWindow[0]/domChild[0]/domChild[0]/domChild[1]</td>
+       <td>7,8</td>
+</tr>
+<tr>
+       <td>assertCSSClass</td>
+       <td>vaadin=runcomvaadintestscomponentswindowWindowMaximizeRestoreTest::/VWindow[0]/domChild[0]/domChild[0]/domChild[1]</td>
+       <td>v-window-restorebox</td>
+</tr>
+<tr>
+       <td>mouseClick</td>
+       <td>vaadin=runcomvaadintestscomponentswindowWindowMaximizeRestoreTest::/VWindow[0]/domChild[0]/domChild[0]/domChild[1]</td>
+       <td>9,7</td>
+</tr>
+<tr>
+       <td>assertCSSClass</td>
+       <td>vaadin=runcomvaadintestscomponentswindowWindowMaximizeRestoreTest::/VWindow[0]/domChild[0]/domChild[0]/domChild[1]</td>
+       <td>v-window-maximizebox</td>
+</tr>
+<!--test double click on header-->
+<tr>
+       <td>doubleClickAt</td>
+       <td>vaadin=runcomvaadintestscomponentswindowWindowMaximizeRestoreTest::/VWindow[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]</td>
+       <td></td>
+</tr>
+<tr>
+       <td>assertCSSClass</td>
+       <td>vaadin=runcomvaadintestscomponentswindowWindowMaximizeRestoreTest::/VWindow[0]/domChild[0]/domChild[0]/domChild[1]</td>
+       <td>v-window-restorebox</td>
+</tr>
+<tr>
+       <td>doubleClickAt</td>
+       <td>vaadin=runcomvaadintestscomponentswindowWindowMaximizeRestoreTest::/VWindow[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]</td>
+       <td></td>
+</tr>
+<tr>
+       <td>assertCSSClass</td>
+       <td>vaadin=runcomvaadintestscomponentswindowWindowMaximizeRestoreTest::/VWindow[0]/domChild[0]/domChild[0]/domChild[1]</td>
+       <td>v-window-maximizebox</td>
+</tr>
+<!--Resizable = false should hide max-restore button-->
+<tr>
+       <td>assertVisible</td>
+       <td>vaadin=runcomvaadintestscomponentswindowWindowMaximizeRestoreTest::/VWindow[0]/domChild[0]/domChild[0]/domChild[1]</td>
+       <td></td>
+</tr>
+<tr>
+       <td>mouseClick</td>
+       <td>vaadin=runcomvaadintestscomponentswindowWindowMaximizeRestoreTest::/VWindow[0]/FocusableScrollPanel[0]/VVerticalLayout[0]/Slot[1]/VCheckBox[0]/domChild[0]</td>
+       <td>8,3</td>
+</tr>
+<tr>
+       <td>assertNotVisible</td>
+       <td>vaadin=runcomvaadintestscomponentswindowWindowMaximizeRestoreTest::/VWindow[0]/domChild[0]/domChild[0]/domChild[1]</td>
+       <td></td>
+</tr>
+<!--Test server side max-restore-->
+<tr>
+       <td>mouseClick</td>
+       <td>vaadin=runcomvaadintestscomponentswindowWindowMaximizeRestoreTest::/VWindow[0]/FocusableScrollPanel[0]/VVerticalLayout[0]/Slot[0]/VNativeButton[0]</td>
+       <td>34,6</td>
+</tr>
+<tr>
+       <td>assertCSSClass</td>
+       <td>vaadin=runcomvaadintestscomponentswindowWindowMaximizeRestoreTest::/VWindow[0]/domChild[0]/domChild[0]/domChild[1]</td>
+       <td>v-window-restorebox</td>
+</tr>
+<tr>
+       <td>mouseClick</td>
+       <td>vaadin=runcomvaadintestscomponentswindowWindowMaximizeRestoreTest::/VWindow[0]/FocusableScrollPanel[0]/VVerticalLayout[0]/Slot[0]/VNativeButton[0]</td>
+       <td>34,6</td>
+</tr>
+<tr>
+       <td>assertCSSClass</td>
+       <td>vaadin=runcomvaadintestscomponentswindowWindowMaximizeRestoreTest::/VWindow[0]/domChild[0]/domChild[0]/domChild[1]</td>
+       <td>v-window-maximizebox</td>
+</tr>
+<!--test double click on header doesn't work-->
+<tr>
+       <td>doubleClickAt</td>
+       <td>vaadin=runcomvaadintestscomponentswindowWindowMaximizeRestoreTest::/VWindow[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]</td>
+       <td></td>
+</tr>
+<tr>
+       <td>assertCSSClass</td>
+       <td>vaadin=runcomvaadintestscomponentswindowWindowMaximizeRestoreTest::/VWindow[0]/domChild[0]/domChild[0]/domChild[1]</td>
+       <td>v-window-maximizebox</td>
+</tr>
+<tr>
+       <td>doubleClickAt</td>
+       <td>vaadin=runcomvaadintestscomponentswindowWindowMaximizeRestoreTest::/VWindow[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]</td>
+       <td></td>
+</tr>
+<tr>
+       <td>assertCSSClass</td>
+       <td>vaadin=runcomvaadintestscomponentswindowWindowMaximizeRestoreTest::/VWindow[0]/domChild[0]/domChild[0]/domChild[1]</td>
+       <td>v-window-maximizebox</td>
+</tr>
+<tr>
+       <td>mouseClick</td>
+       <td>vaadin=runcomvaadintestscomponentswindowWindowMaximizeRestoreTest::/VWindow[0]/FocusableScrollPanel[0]/VVerticalLayout[0]/Slot[1]/VCheckBox[0]/domChild[0]</td>
+       <td>8,3</td>
+</tr>
+<tr>
+       <td>mouseClick</td>
+       <td>vaadin=runcomvaadintestscomponentswindowWindowMaximizeRestoreTest::/VWindow[0]/FocusableScrollPanel[0]/VVerticalLayout[0]/Slot[4]/VNativeButton[0]</td>
+       <td>26,9</td>
+</tr>
+<tr>
+       <td>mouseClick</td>
+       <td>vaadin=runcomvaadintestscomponentswindowWindowMaximizeRestoreTest::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[0]/VButton[0]/domChild[0]/domChild[0]</td>
+       <td></td>
+</tr>
+<!--test two windows with screen shot-->
+<tr>
+       <td>screenCapture</td>
+       <td>window-2-original-pos-window-1-centered</td>
+       <td></td>
+</tr>
+<tr>
+       <td>mouseClick</td>
+       <td>vaadin=runcomvaadintestscomponentswindowWindowMaximizeRestoreTest::/VWindow[0]/domChild[0]/domChild[0]/domChild[1]</td>
+       <td>10,8</td>
+</tr>
+<tr>
+       <td>screenCapture</td>
+       <td>window-1-maximized-on-top-of-window-2</td>
+       <td></td>
+</tr>
+<tr>
+       <td>mouseClick</td>
+       <td>vaadin=runcomvaadintestscomponentswindowWindowMaximizeRestoreTest::/VWindow[0]/FocusableScrollPanel[0]/VVerticalLayout[0]/Slot[0]/VNativeButton[0]</td>
+       <td>43,12</td>
+</tr>
+<!--maximize window 2 content-->
+<tr>
+       <td>mouseClick</td>
+       <td>vaadin=runcomvaadintestscomponentswindowWindowMaximizeRestoreTest::/VWindow[1]/FocusableScrollPanel[0]/VVerticalLayout[0]/Slot[3]/VNativeButton[0]</td>
+       <td>100,9</td>
+</tr>
+<tr>
+       <td>screenCapture</td>
+       <td>window-2-original-pos-window-1-centered</td>
+       <td></td>
+</tr>
+<tr>
+       <td>mouseClick</td>
+       <td>vaadin=runcomvaadintestscomponentswindowWindowMaximizeRestoreTest::/VWindow[1]/domChild[0]/domChild[0]/domChild[1]</td>
+       <td>6,11</td>
+</tr>
+<tr>
+       <td>screenCapture</td>
+       <td>window-2-maximized-on-top-of-window-1</td>
+       <td></td>
+</tr>
+<tr>
+       <td>mouseClick</td>
+       <td>vaadin=runcomvaadintestscomponentswindowWindowMaximizeRestoreTest::/VWindow[1]/domChild[0]/domChild[0]/domChild[2]</td>
+       <td>7,5</td>
+</tr>
+<tr>
+       <td>screenCapture</td>
+       <td>window-2-closed-window-1-centered</td>
+       <td></td>
+</tr>
+<tr>
+       <td>mouseClick</td>
+       <td>vaadin=runcomvaadintestscomponentswindowWindowMaximizeRestoreTest::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[1]/VFilterSelect[0]/domChild[1]</td>
+       <td>1,17</td>
+</tr>
+<tr>
+       <td>mouseClick</td>
+       <td>//div[@id='VAADIN_COMBOBOX_OPTIONLIST']/div/div[2]/table/tbody/tr[2]/td</td>
+       <td>122,6</td>
+</tr>
+<tr>
+       <td>screenCapture</td>
+       <td>window-2-added-maximized-on-top-of-window-1</td>
+       <td></td>
+</tr>
+<tr>
+       <td>mouseClick</td>
+       <td>vaadin=runcomvaadintestscomponentswindowWindowMaximizeRestoreTest::/VWindow[1]/domChild[0]/domChild[0]/domChild[1]</td>
+       <td>6,11</td>
+</tr>
+<tr>
+       <td>doubleClickAt</td>
+       <td>vaadin=runcomvaadintestscomponentswindowWindowMaximizeRestoreTest::/VWindow[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]</td>
+       <td>113,10</td>
+</tr>
+<tr>
+       <td>screenCapture</td>
+       <td>window-1-maximized-with-doubleclick</td>
+       <td></td>
+</tr>
+</tbody></table>
+</body>
+</html>
diff --git a/uitest/src/com/vaadin/tests/components/window/WindowMaximizeRestoreTest.java b/uitest/src/com/vaadin/tests/components/window/WindowMaximizeRestoreTest.java
new file mode 100644 (file)
index 0000000..fe45b03
--- /dev/null
@@ -0,0 +1,165 @@
+package com.vaadin.tests.components.window;
+
+import com.vaadin.data.Item;
+import com.vaadin.data.Property.ValueChangeEvent;
+import com.vaadin.data.Property.ValueChangeListener;
+import com.vaadin.server.VaadinRequest;
+import com.vaadin.shared.ui.window.WindowState.DisplayState;
+import com.vaadin.tests.components.AbstractTestUI;
+import com.vaadin.ui.Button;
+import com.vaadin.ui.Button.ClickEvent;
+import com.vaadin.ui.CheckBox;
+import com.vaadin.ui.ComboBox;
+import com.vaadin.ui.ComponentContainer;
+import com.vaadin.ui.NativeButton;
+import com.vaadin.ui.UI;
+import com.vaadin.ui.VerticalLayout;
+import com.vaadin.ui.Window;
+import com.vaadin.ui.Window.CloseEvent;
+import com.vaadin.ui.Window.CloseListener;
+import com.vaadin.ui.Window.DisplayStateChangeEvent;
+import com.vaadin.ui.Window.DisplayStateChangeListener;
+
+public class WindowMaximizeRestoreTest extends AbstractTestUI {
+    Button.ClickListener addListener = new Button.ClickListener() {
+
+        @Override
+        public void buttonClick(ClickEvent event) {
+            addWindow(createNewWindow());
+        }
+    };
+
+    @Override
+    protected void setup(VaadinRequest request) {
+        Button addButton = new Button("Add new Window");
+        addButton.addListener(addListener);
+        addComponent(addButton);
+
+        addWindowAgain = new ComboBox("Add Window Again");
+        addWindowAgain.setBuffered(false);
+        addWindowAgain.setImmediate(true);
+        addWindowAgain.addValueChangeListener(new ValueChangeListener() {
+
+            @Override
+            public void valueChange(ValueChangeEvent event) {
+
+                Object value = event.getProperty().getValue();
+                if (value != null && value instanceof Window) {
+                    UI.getCurrent().addWindow((Window) value);
+                    addWindowAgain.removeItem(value);
+                }
+            }
+        });
+        addComponent(addWindowAgain);
+
+        addWindow(createNewWindow());
+    }
+
+    private int windowCount = 0;
+    private ComboBox addWindowAgain;
+
+    private Window createNewWindow() {
+        final Window w = new Window("Window " + (++windowCount));
+        final VerticalLayout content = new VerticalLayout();
+        w.setContent(content);
+        w.setData(windowCount);
+        w.setWidth("200px");
+        w.setHeight("300px");
+        w.setPositionX(200);
+        w.setPositionY(200);
+        final NativeButton maximize = new NativeButton("Maximize");
+        Button.ClickListener listener = new Button.ClickListener() {
+
+            @Override
+            public void buttonClick(ClickEvent event) {
+                if (w.getDisplayState() == DisplayState.MAXIMIZED) {
+                    w.setDisplayState(DisplayState.NORMAL);
+                    maximize.setCaption("Maximize");
+                } else {
+                    w.setDisplayState(DisplayState.MAXIMIZED);
+                    maximize.setCaption("Restore");
+                }
+            }
+
+        };
+        maximize.addClickListener(listener);
+        ((ComponentContainer) w.getContent()).addComponent(maximize);
+
+        w.addDisplayStateChangeListener(new DisplayStateChangeListener() {
+
+            @Override
+            public void displayStateChanged(DisplayStateChangeEvent event) {
+                DisplayState state = (event.getWindow().getDisplayState());
+                if (state == DisplayState.NORMAL) {
+                    w.setCaption("Window " + w.getData() + " Normal");
+                    maximize.setCaption("Maximize");
+                } else if (state == DisplayState.MAXIMIZED) {
+                    w.setCaption("Window " + w.getData() + " Maximized");
+                    maximize.setCaption("Restore");
+                }
+            }
+        });
+        final CheckBox resizeable = new CheckBox("Resizeable");
+        resizeable.setValue(w.isResizable());
+        resizeable.addValueChangeListener(new ValueChangeListener() {
+
+            @Override
+            public void valueChange(ValueChangeEvent event) {
+                w.setResizable(resizeable.getValue());
+            }
+        });
+        ((ComponentContainer) w.getContent()).addComponent(resizeable);
+        final CheckBox closeable = new CheckBox("Closeable");
+        closeable.setValue(w.isClosable());
+        closeable.addValueChangeListener(new ValueChangeListener() {
+
+            @Override
+            public void valueChange(ValueChangeEvent event) {
+                w.setClosable(closeable.getValue());
+            }
+        });
+        ((ComponentContainer) w.getContent()).addComponent(closeable);
+        NativeButton contentFull = new NativeButton("Set Content Size Full",
+                new Button.ClickListener() {
+
+                    @Override
+                    public void buttonClick(ClickEvent event) {
+                        w.getContent().setSizeFull();
+                    }
+                });
+        contentFull.setWidth("100%");
+        ((ComponentContainer) w.getContent()).addComponent(contentFull);
+
+        NativeButton center = new NativeButton("Center");
+        center.addClickListener(new Button.ClickListener() {
+
+            @Override
+            public void buttonClick(ClickEvent event) {
+                w.center();
+            }
+        });
+        ((ComponentContainer) w.getContent()).addComponent(center);
+
+        w.addCloseListener(new CloseListener() {
+
+            @Override
+            public void windowClose(CloseEvent e) {
+                Item item = addWindowAgain.addItem(w);
+                addWindowAgain.setItemCaption(w, "Window "
+                        + w.getData().toString());
+            }
+        });
+
+        return w;
+    }
+
+    @Override
+    protected Integer getTicketNumber() {
+        return 3400;
+    }
+
+    @Override
+    protected String getTestDescription() {
+        return "Tests the default maximize & restore funtionality. Max. makes window 100%*100% and pos(0, 0), and restore returns it to the values that are set in windows state.";
+    }
+}