]> source.dussan.org Git - vaadin-framework.git/commitdiff
fixes #2518, window resize listener
authorMatti Tahvonen <matti.tahvonen@itmill.com>
Thu, 2 Apr 2009 08:22:54 +0000 (08:22 +0000)
committerMatti Tahvonen <matti.tahvonen@itmill.com>
Thu, 2 Apr 2009 08:22:54 +0000 (08:22 +0000)
svn changeset:7285/svn branch:6.0

src/com/itmill/toolkit/terminal/gwt/client/ui/IView.java
src/com/itmill/toolkit/terminal/gwt/client/ui/IWindow.java
src/com/itmill/toolkit/tests/components/window/WindowResizeListener.java [new file with mode: 0644]
src/com/itmill/toolkit/ui/Window.java

index 5d4e8c86d977cad8e9f7a37d7a0559481a0e5179..1e4badc439f7b7b37418085c803d515aad20a305 100644 (file)
@@ -72,6 +72,8 @@ public class IView extends SimplePanel implements Container,
 
     private boolean scrollable;
 
+    private boolean immediate;
+
     public IView(String elementId) {
         super();
         setStyleName(CLASSNAME);
@@ -138,6 +140,8 @@ public class IView extends SimplePanel implements Container,
         boolean firstPaint = connection == null;
         connection = client;
 
+        immediate = uidl.hasAttribute("immediate");
+
         String newTheme = uidl.getStringAttribute("theme");
         if (theme != null && !newTheme.equals(theme)) {
             // Complete page refresh is needed due css can affect layout
@@ -396,6 +400,8 @@ public class IView extends SimplePanel implements Container,
                                     .log(
                                             "Running layout functions due window resize");
                             connection.runDescendentsLayout(IView.this);
+
+                            sendClientResized();
                         }
                     }
                 };
@@ -419,10 +425,19 @@ public class IView extends SimplePanel implements Container,
             connection.runDescendentsLayout(this);
             Util.runWebkitOverflowAutoFix(getElement());
 
+            sendClientResized();
         }
 
     }
 
+    /**
+     * Send new dimensions to the server.
+     */
+    private void sendClientResized() {
+        connection.updateVariable(id, "height", height, false);
+        connection.updateVariable(id, "width", width, immediate);
+    }
+
     public native static void goTo(String url)
     /*-{
        $wnd.location = url;
index 764e400df9fd633bbf4bd44a44c40df03eb00042..e329d410c0b90bad364b7353aafcedcfdd6dae25 100644 (file)
@@ -132,6 +132,8 @@ public class IWindow extends IToolkitOverlay implements Container,
 
     private String height;
 
+    private boolean immediate;
+
     public IWindow() {
         super(false, false, true); // no autohide, not modal, shadow
         // Different style of shadow for windows
@@ -249,6 +251,8 @@ public class IWindow extends IToolkitOverlay implements Container,
             return;
         }
 
+        immediate = uidl.hasAttribute("immediate");
+
         if (uidl.getBooleanAttribute("resizable") != resizable) {
             setResizable(!resizable);
         }
@@ -756,7 +760,7 @@ public class IWindow extends IToolkitOverlay implements Container,
         if (updateVariables) {
             // sending width back always as pixels, no need for unit
             client.updateVariable(id, "width", w, false);
-            client.updateVariable(id, "height", h, false);
+            client.updateVariable(id, "height", h, immediate);
         }
 
         // Update child widget dimensions
diff --git a/src/com/itmill/toolkit/tests/components/window/WindowResizeListener.java b/src/com/itmill/toolkit/tests/components/window/WindowResizeListener.java
new file mode 100644 (file)
index 0000000..63956d5
--- /dev/null
@@ -0,0 +1,99 @@
+package com.itmill.toolkit.tests.components.window;
+
+import com.itmill.toolkit.terminal.Sizeable;
+import com.itmill.toolkit.tests.components.TestBase;
+import com.itmill.toolkit.ui.Button;
+import com.itmill.toolkit.ui.CheckBox;
+import com.itmill.toolkit.ui.Label;
+import com.itmill.toolkit.ui.Layout;
+import com.itmill.toolkit.ui.Window;
+import com.itmill.toolkit.ui.Button.ClickEvent;
+import com.itmill.toolkit.ui.Window.ResizeEvent;
+import com.itmill.toolkit.ui.Window.ResizeListener;
+
+public class WindowResizeListener extends TestBase {
+
+    @Override
+    protected String getDescription() {
+        return "Size changes from windows (both sub "
+                + "and browsers level) should get back to server."
+                + " If size changes, a separate server side event should occur.";
+    }
+
+    @Override
+    protected Integer getTicketNumber() {
+        return null;
+    }
+
+    Window subwin = new ResizeListenerWindow();
+
+    @Override
+    protected void setup() {
+
+        final Label l = new Label();
+        getLayout().addComponent(l);
+
+        getMainWindow().addListener(new ResizeListener() {
+            public void windowResized(ResizeEvent e) {
+                l.setValue("Current main window size: "
+                        + getMainWindow().getWidth() + " x "
+                        + getMainWindow().getHeight());
+            }
+        });
+
+        CheckBox subwindow = new CheckBox("show subwindow");
+        subwindow.setImmediate(true);
+        subwindow.addListener(new Button.ClickListener() {
+            public void buttonClick(ClickEvent event) {
+                if (event.getButton().booleanValue()) {
+                    getMainWindow().addWindow(subwin);
+                } else {
+                    getMainWindow().removeWindow(subwin);
+                }
+            }
+        });
+        getLayout().addComponent(subwindow);
+
+        CheckBox immediate = new CheckBox("immediate");
+        immediate.addListener(new Button.ClickListener() {
+            public void buttonClick(ClickEvent event) {
+                boolean booleanValue = event.getButton().booleanValue();
+                getMainWindow().setImmediate(booleanValue);
+                subwin.setImmediate(booleanValue);
+            }
+        });
+        immediate.setImmediate(true);
+        getLayout().addComponent(immediate);
+
+        getLayout().addComponent(new Button("Sync"));
+
+    }
+}
+
+class ResizeListenerWindow extends Window {
+    Label sizeLabel = new Label();
+
+    public ResizeListenerWindow() {
+        super("Subwindow");
+        setWidth("400px");
+
+        Layout hl = getLayout();
+        hl.addComponent(new Label("Current size: "));
+        hl.addComponent(sizeLabel);
+
+        addListener(new ResizeListener() {
+            public void windowResized(ResizeEvent e) {
+                updateLabel();
+            }
+        });
+
+        updateLabel();
+    }
+
+    public void updateLabel() {
+        sizeLabel
+                .setValue(getWidth() + Sizeable.UNIT_SYMBOLS[getWidthUnits()]
+                        + " x " + getHeight()
+                        + Sizeable.UNIT_SYMBOLS[getHeightUnits()]);
+    }
+}
index 2f8d3bcad2f6da216fa95a2474bba36d9ff383ae..530bd8441d033a94468c5e35bb25ba6c6c649154 100644 (file)
@@ -859,6 +859,21 @@ public class Window extends Panel implements URIHandler, ParameterHandler {
      */
     @Override
     public void changeVariables(Object source, Map variables) {
+
+        boolean sizeHasChanged = false;
+        // size is handled in super class, but resize events only in windows ->
+        // so detect if size change occurs before super.changeVariables()
+        if (variables.containsKey("height")
+                && (getHeightUnits() != UNITS_PIXELS || (Integer) variables
+                        .get("height") != getHeight())) {
+            sizeHasChanged = true;
+        }
+        if (variables.containsKey("width")
+                && (getWidthUnits() != UNITS_PIXELS || (Integer) variables
+                        .get("width") != getWidth())) {
+            sizeHasChanged = true;
+        }
+
         super.changeVariables(source, variables);
 
         // Positioning
@@ -880,6 +895,12 @@ public class Window extends Panel implements URIHandler, ParameterHandler {
                 close();
             }
         }
+
+        // fire event if size has really changed
+        if (sizeHasChanged) {
+            fireResize();
+        }
+
     }
 
     /**
@@ -1030,6 +1051,83 @@ public class Window extends Panel implements URIHandler, ParameterHandler {
         fireEvent(new Window.CloseEvent(this));
     }
 
+    /**
+     * Method for the resize event.
+     */
+    private static final Method WINDOW_RESIZE_METHOD;
+    static {
+        try {
+            WINDOW_RESIZE_METHOD = ResizeListener.class.getDeclaredMethod(
+                    "windowResized", new Class[] { ResizeEvent.class });
+        } catch (final java.lang.NoSuchMethodException e) {
+            // This should never happen
+            throw new java.lang.RuntimeException(
+                    "Internal error, window resized method not found");
+        }
+    }
+
+    /**
+     * Resize events are fired whenever the client-side fires a resize-event
+     * (e.g. the browser window is resized). The frequency may vary across
+     * browsers.
+     */
+    public class ResizeEvent extends Component.Event {
+
+        // Generated serial
+        private static final long serialVersionUID = 8569831802323447687L;
+
+        /**
+         * 
+         * @param source
+         */
+        public ResizeEvent(Component source) {
+            super(source);
+        }
+
+        /**
+         * Get the window form which this event originated
+         * 
+         * @return the window
+         */
+        public Window getWindow() {
+            return (Window) getSource();
+        }
+    }
+
+    /**
+     * Listener for window resize events.
+     * 
+     * @see com.itmill.toolkit.ui.Window.ResizeEvent
+     */
+    public interface ResizeListener {
+        public void windowResized(ResizeEvent e);
+    }
+
+    /**
+     * Add a resize listener.
+     * 
+     * @param listener
+     */
+    public void addListener(ResizeListener listener) {
+        addListener(ResizeEvent.class, listener, WINDOW_RESIZE_METHOD);
+    }
+
+    /**
+     * Remove a resize listener.
+     * 
+     * @param listener
+     */
+    public void removeListener(ResizeListener listener) {
+        removeListener(ResizeEvent.class, this);
+    }
+
+    /**
+     * Fire the resize event.
+     */
+    protected void fireResize() {
+        fireEvent(new ResizeEvent(this));
+    }
+
     private void attachWindow(Window w) {
         subwindows.add(w);
         w.setParent(this);