From 8f78e7c8994a630ff7a09819074f3c11f1c1d976 Mon Sep 17 00:00:00 2001 From: Matti Tahvonen Date: Thu, 2 Apr 2009 08:22:54 +0000 Subject: [PATCH] fixes #2518, window resize listener svn changeset:7285/svn branch:6.0 --- .../toolkit/terminal/gwt/client/ui/IView.java | 15 +++ .../terminal/gwt/client/ui/IWindow.java | 6 +- .../window/WindowResizeListener.java | 99 +++++++++++++++++++ src/com/itmill/toolkit/ui/Window.java | 98 ++++++++++++++++++ 4 files changed, 217 insertions(+), 1 deletion(-) create mode 100644 src/com/itmill/toolkit/tests/components/window/WindowResizeListener.java diff --git a/src/com/itmill/toolkit/terminal/gwt/client/ui/IView.java b/src/com/itmill/toolkit/terminal/gwt/client/ui/IView.java index 5d4e8c86d9..1e4badc439 100644 --- a/src/com/itmill/toolkit/terminal/gwt/client/ui/IView.java +++ b/src/com/itmill/toolkit/terminal/gwt/client/ui/IView.java @@ -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; diff --git a/src/com/itmill/toolkit/terminal/gwt/client/ui/IWindow.java b/src/com/itmill/toolkit/terminal/gwt/client/ui/IWindow.java index 764e400df9..e329d410c0 100644 --- a/src/com/itmill/toolkit/terminal/gwt/client/ui/IWindow.java +++ b/src/com/itmill/toolkit/terminal/gwt/client/ui/IWindow.java @@ -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 index 0000000000..63956d524f --- /dev/null +++ b/src/com/itmill/toolkit/tests/components/window/WindowResizeListener.java @@ -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()]); + } +} diff --git a/src/com/itmill/toolkit/ui/Window.java b/src/com/itmill/toolkit/ui/Window.java index 2f8d3bcad2..530bd8441d 100644 --- a/src/com/itmill/toolkit/ui/Window.java +++ b/src/com/itmill/toolkit/ui/Window.java @@ -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); -- 2.39.5