From: Artur Signell Date: Tue, 31 Jan 2012 11:52:09 +0000 (+0200) Subject: #8324 Split VView and VWindow into paintable and widget X-Git-Tag: 7.0.0.alpha2~498 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=daa428b4fa04ae5f93278406f3b7a1ecbd13a64f;p=vaadin-framework.git #8324 Split VView and VWindow into paintable and widget --- diff --git a/src/com/vaadin/terminal/gwt/client/ComponentLocator.java b/src/com/vaadin/terminal/gwt/client/ComponentLocator.java index b03bc708e2..f49f99a477 100644 --- a/src/com/vaadin/terminal/gwt/client/ComponentLocator.java +++ b/src/com/vaadin/terminal/gwt/client/ComponentLocator.java @@ -375,7 +375,7 @@ public class ComponentLocator { } else if (w instanceof VWindow) { VWindow win = (VWindow) w; ArrayList subWindowList = client.getView() - .getSubWindowList(); + .getWidgetForPaintable().getSubWindowList(); int indexOfSubWindow = subWindowList.indexOf(win); return PARENTCHILD_SEPARATOR + "VWindow[" + indexOfSubWindow + "]"; } else if (w instanceof RootPanel) { @@ -435,7 +435,7 @@ public class ComponentLocator { if (part.equals(ROOT_ID)) { w = RootPanel.get(); } else if (part.equals("")) { - w = client.getView(); + w = client.getView().getWidgetForPaintable(); } else if (w == null) { // Must be static pid (PID_S*) w = ((VPaintableWidget) VPaintableMap.get(client).getPaintable( @@ -465,7 +465,8 @@ public class ComponentLocator { * compatibility */ if (widgetClassName.equals("VWindow")) { - iterator = client.getView().getSubWindowList().iterator(); + iterator = client.getView().getWidgetForPaintable() + .getSubWindowList().iterator(); } else if (widgetClassName.equals("VContextMenu")) { return client.getContextMenu(); } else { diff --git a/src/com/vaadin/terminal/gwt/client/VDebugConsole.java b/src/com/vaadin/terminal/gwt/client/VDebugConsole.java index fdaf944b9f..76c312676a 100644 --- a/src/com/vaadin/terminal/gwt/client/VDebugConsole.java +++ b/src/com/vaadin/terminal/gwt/client/VDebugConsole.java @@ -91,7 +91,7 @@ public class VDebugConsole extends VOverlay implements Console { for (ApplicationConnection a : ApplicationConfiguration .getRunningApplications()) { VPaintableWidget paintable = Util.getPaintableForElement(a, - a.getView(), eventTarget); + a.getView().getWidgetForPaintable(), eventTarget); if (paintable == null) { paintable = Util.getPaintableForElement(a, RootPanel.get(), eventTarget); @@ -120,7 +120,7 @@ public class VDebugConsole extends VOverlay implements Console { for (ApplicationConnection a : ApplicationConfiguration .getRunningApplications()) { VPaintableWidget paintable = Util.getPaintableForElement(a, - a.getView(), eventTarget); + a.getView().getWidgetForPaintable(), eventTarget); if (paintable == null) { paintable = Util.getPaintableForElement(a, RootPanel.get(), eventTarget); @@ -534,8 +534,7 @@ public class VDebugConsole extends VOverlay implements Console { emphasisInUi.addClickHandler(new ClickHandler() { public void onClick(ClickEvent event) { if (paintable != null) { - Element element2 = layout.getWidgetForPaintable() - .getElement(); + Element element2 = ((Widget) layout).getElement(); Widget.setStyleName(element2, "invalidlayout", emphasisInUi.getValue()); } diff --git a/src/com/vaadin/terminal/gwt/client/ui/VView.java b/src/com/vaadin/terminal/gwt/client/ui/VView.java index e3aba21096..7002c6279f 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VView.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VView.java @@ -5,8 +5,6 @@ package com.vaadin.terminal.gwt.client.ui; import java.util.ArrayList; -import java.util.HashSet; -import java.util.Iterator; import java.util.LinkedHashSet; import java.util.Set; @@ -17,12 +15,10 @@ import com.google.gwt.dom.client.Document; import com.google.gwt.dom.client.Element; import com.google.gwt.dom.client.Style; import com.google.gwt.dom.client.Style.Display; -import com.google.gwt.event.dom.client.DomEvent.Type; import com.google.gwt.event.logical.shared.ResizeEvent; import com.google.gwt.event.logical.shared.ResizeHandler; import com.google.gwt.event.logical.shared.ValueChangeEvent; import com.google.gwt.event.logical.shared.ValueChangeHandler; -import com.google.gwt.event.shared.EventHandler; import com.google.gwt.event.shared.HandlerRegistration; import com.google.gwt.user.client.Command; import com.google.gwt.user.client.DOM; @@ -30,7 +26,6 @@ import com.google.gwt.user.client.Event; import com.google.gwt.user.client.History; import com.google.gwt.user.client.Timer; import com.google.gwt.user.client.Window; -import com.google.gwt.user.client.ui.RootPanel; import com.google.gwt.user.client.ui.SimplePanel; import com.google.gwt.user.client.ui.Widget; import com.vaadin.terminal.gwt.client.ApplicationConnection; @@ -56,15 +51,15 @@ public class VView extends SimplePanel implements Container, ResizeHandler, public static final String NOTIFICATION_HTML_CONTENT_NOT_ALLOWED = "useplain"; - private String theme; + String theme; - private VPaintableWidget layout; + VPaintableWidget layout; - private final LinkedHashSet subWindows = new LinkedHashSet(); + final LinkedHashSet subWindows = new LinkedHashSet(); - private String id; + String id; - private ShortcutActionHandler actionHandler; + ShortcutActionHandler actionHandler; /** stored width for IE resize optimization */ private int width; @@ -72,7 +67,7 @@ public class VView extends SimplePanel implements Container, ResizeHandler, /** stored height for IE resize optimization */ private int height; - private ApplicationConnection connection; + ApplicationConnection connection; /** Identifies the click event */ public static final String CLICK_EVENT_ID = "click"; @@ -85,17 +80,17 @@ public class VView extends SimplePanel implements Container, ResizeHandler, */ private Timer resizeTimer; - private int scrollTop; + int scrollTop; - private int scrollLeft; + int scrollLeft; - private boolean rendering; + boolean rendering; - private boolean scrollable; + boolean scrollable; - private boolean immediate; + boolean immediate; - private boolean resizeLazy = false; + boolean resizeLazy = false; /** * Attribute name for the lazy resize setting . @@ -106,7 +101,7 @@ public class VView extends SimplePanel implements Container, ResizeHandler, * Reference to the parent frame/iframe. Null if there is no parent (i)frame * or if the application and parent frame are in different domains. */ - private Element parentFrame; + Element parentFrame; private HandlerRegistration historyHandlerRegistration; @@ -114,7 +109,7 @@ public class VView extends SimplePanel implements Container, ResizeHandler, * The current URI fragment, used to avoid sending updates if nothing has * changed. */ - private String currentFragment; + String currentFragment; /** * Listener for URI fragment changes. Notifies the server of the new value @@ -133,16 +128,6 @@ public class VView extends SimplePanel implements Container, ResizeHandler, } }; - private ClickEventHandler clickEventHandler = new ClickEventHandler(this, - VPanel.CLICK_EVENT_IDENTIFIER) { - - @Override - protected HandlerRegistration registerHandler( - H handler, Type type) { - return addDomHandler(handler, type); - } - }; - private VLazyExecutor delayedResizeExecutor = new VLazyExecutor(200, new ScheduledCommand() { public void execute() { @@ -212,7 +197,7 @@ public class VView extends SimplePanel implements Container, ResizeHandler, /** * Used to reload host page on theme changes. */ - private static native void reloadHostPage() + static native void reloadHostPage() /*-{ $wnd.location.reload(); }-*/; @@ -223,7 +208,7 @@ public class VView extends SimplePanel implements Container, ResizeHandler, * @param script * Script to be executed. */ - private static native void eval(String script) + static native void eval(String script) /*-{ try { if (script == null) return; @@ -244,229 +229,6 @@ public class VView extends SimplePanel implements Container, ResizeHandler, .contains(ApplicationConnection.GENERATED_BODY_CLASSNAME); } - public void updateFromUIDL(final UIDL uidl, ApplicationConnection client) { - rendering = true; - - id = uidl.getId(); - boolean firstPaint = connection == null; - connection = client; - - immediate = uidl.hasAttribute("immediate"); - resizeLazy = uidl.hasAttribute(RESIZE_LAZY); - String newTheme = uidl.getStringAttribute("theme"); - if (theme != null && !newTheme.equals(theme)) { - // Complete page refresh is needed due css can affect layout - // calculations etc - reloadHostPage(); - } else { - theme = newTheme; - } - if (uidl.hasAttribute("style")) { - setStyleName(getStylePrimaryName() + " " - + uidl.getStringAttribute("style")); - } - - clickEventHandler.handleEventHandlerRegistration(client); - - if (!isEmbedded() && uidl.hasAttribute("caption")) { - // only change window title if we're in charge of the whole page - com.google.gwt.user.client.Window.setTitle(uidl - .getStringAttribute("caption")); - } - - // Process children - int childIndex = 0; - - // Open URL:s - boolean isClosed = false; // was this window closed? - while (childIndex < uidl.getChildCount() - && "open".equals(uidl.getChildUIDL(childIndex).getTag())) { - final UIDL open = uidl.getChildUIDL(childIndex); - final String url = client.translateVaadinUri(open - .getStringAttribute("src")); - final String target = open.getStringAttribute("name"); - if (target == null) { - // source will be opened to this browser window, but we may have - // to finish rendering this window in case this is a download - // (and window stays open). - Scheduler.get().scheduleDeferred(new Command() { - public void execute() { - goTo(url); - } - }); - } else if ("_self".equals(target)) { - // This window is closing (for sure). Only other opens are - // relevant in this change. See #3558, #2144 - isClosed = true; - goTo(url); - } else { - String options; - if (open.hasAttribute("border")) { - if (open.getStringAttribute("border").equals("minimal")) { - options = "menubar=yes,location=no,status=no"; - } else { - options = "menubar=no,location=no,status=no"; - } - - } else { - options = "resizable=yes,menubar=yes,toolbar=yes,directories=yes,location=yes,scrollbars=yes,status=yes"; - } - - if (open.hasAttribute("width")) { - int w = open.getIntAttribute("width"); - options += ",width=" + w; - } - if (open.hasAttribute("height")) { - int h = open.getIntAttribute("height"); - options += ",height=" + h; - } - - Window.open(url, target, options); - } - childIndex++; - } - if (isClosed) { - // don't render the content, something else will be opened to this - // browser view - rendering = false; - return; - } - - // Draw this application level window - UIDL childUidl = uidl.getChildUIDL(childIndex); - final VPaintableWidget lo = client.getPaintable(childUidl); - - if (layout != null) { - if (layout != lo) { - // remove old - client.unregisterPaintable(layout); - // add new - setWidget(lo.getWidgetForPaintable()); - layout = lo; - } - } else { - setWidget(lo.getWidgetForPaintable()); - layout = lo; - } - - layout.updateFromUIDL(childUidl, client); - if (!childUidl.getBooleanAttribute("cached")) { - updateParentFrameSize(); - } - - // Save currently open subwindows to track which will need to be closed - final HashSet removedSubWindows = new HashSet( - subWindows); - - // Handle other UIDL children - while ((childUidl = uidl.getChildUIDL(++childIndex)) != null) { - String tag = childUidl.getTag().intern(); - if (tag == "actions") { - if (actionHandler == null) { - actionHandler = new ShortcutActionHandler(id, client); - } - actionHandler.updateActionMap(childUidl); - } else if (tag == "execJS") { - String script = childUidl.getStringAttribute("script"); - eval(script); - } else if (tag == "notifications") { - for (final Iterator it = childUidl.getChildIterator(); it - .hasNext();) { - final UIDL notification = (UIDL) it.next(); - VNotification.showNotification(client, notification); - } - } else { - // subwindows - final VPaintableWidget w = client.getPaintable(childUidl); - if (subWindows.contains(w)) { - removedSubWindows.remove(w); - } else { - subWindows.add((VWindow) w); - } - w.updateFromUIDL(childUidl, client); - } - } - - // Close old windows which where not in UIDL anymore - for (final Iterator rem = removedSubWindows.iterator(); rem - .hasNext();) { - final VWindow w = rem.next(); - client.unregisterPaintable(w); - subWindows.remove(w); - w.hide(); - } - - if (uidl.hasAttribute("focused")) { - // set focused component when render phase is finished - Scheduler.get().scheduleDeferred(new Command() { - public void execute() { - VPaintableWidget paintable = (VPaintableWidget) uidl - .getPaintableAttribute("focused", connection); - - final Widget toBeFocused = paintable - .getWidgetForPaintable(); - /* - * Two types of Widgets can be focused, either implementing - * GWT HasFocus of a thinner Vaadin specific Focusable - * interface. - */ - if (toBeFocused instanceof com.google.gwt.user.client.ui.Focusable) { - final com.google.gwt.user.client.ui.Focusable toBeFocusedWidget = (com.google.gwt.user.client.ui.Focusable) toBeFocused; - toBeFocusedWidget.setFocus(true); - } else if (toBeFocused instanceof Focusable) { - ((Focusable) toBeFocused).focus(); - } else { - VConsole.log("Could not focus component"); - } - } - }); - } - - // Add window listeners on first paint, to prevent premature - // variablechanges - if (firstPaint) { - Window.addWindowClosingHandler(this); - Window.addResizeHandler(this); - } - - onResize(); - - // finally set scroll position from UIDL - if (uidl.hasVariable("scrollTop")) { - scrollable = true; - scrollTop = uidl.getIntVariable("scrollTop"); - DOM.setElementPropertyInt(getElement(), "scrollTop", scrollTop); - scrollLeft = uidl.getIntVariable("scrollLeft"); - DOM.setElementPropertyInt(getElement(), "scrollLeft", scrollLeft); - } else { - scrollable = false; - } - - // Safari workaround must be run after scrollTop is updated as it sets - // scrollTop using a deferred command. - if (BrowserInfo.get().isSafari()) { - Util.runWebkitOverflowAutoFix(getElement()); - } - - scrollIntoView(uidl); - - if (uidl.hasAttribute(FRAGMENT_VARIABLE)) { - currentFragment = uidl.getStringAttribute(FRAGMENT_VARIABLE); - if (!currentFragment.equals(History.getToken())) { - History.newItem(currentFragment, true); - } - } else { - // Initial request for which the server doesn't yet have a fragment - // (and haven't shown any interest in getting one) - currentFragment = History.getToken(); - - // Include current fragment in the next request - client.updateVariable(id, FRAGMENT_VARIABLE, currentFragment, false); - } - - rendering = false; - } - /** * Tries to scroll paintable referenced from given UIDL snippet to be * visible. @@ -530,7 +292,7 @@ public class VView extends SimplePanel implements Container, ResizeHandler, /** * Called when a resize event is received. */ - private void onResize() { + void onResize() { /* * IE (pre IE9 at least) will give us some false resize events due to * problems with scrollbars. Firefox 3 might also produce some extra @@ -742,7 +504,7 @@ public class VView extends SimplePanel implements Container, ResizeHandler, } - private void updateParentFrameSize() { + void updateParentFrameSize() { if (parentFrame == null) { return; } @@ -754,7 +516,7 @@ public class VView extends SimplePanel implements Container, ResizeHandler, parentFrame.getStyle().setPropertyPx("height", childHeight); } - private static native Element getParentFrame() + static native Element getParentFrame() /*-{ try { var frameElement = $wnd.frameElement; @@ -769,10 +531,6 @@ public class VView extends SimplePanel implements Container, ResizeHandler, return null; }-*/; - public void updateCaption(VPaintableWidget component, UIDL uidl) { - // NOP Subwindows never draw caption for their first child (layout) - } - /** * Return an iterator for current subwindows. This method is meant for * testing purposes only. @@ -787,42 +545,6 @@ public class VView extends SimplePanel implements Container, ResizeHandler, return windows; } - public void init(String rootPanelId, - ApplicationConnection applicationConnection) { - DOM.sinkEvents(getElement(), Event.ONKEYDOWN | Event.ONSCROLL); - - // iview is focused when created so element needs tabIndex - // 1 due 0 is at the end of natural tabbing order - DOM.setElementProperty(getElement(), "tabIndex", "1"); - - RootPanel root = RootPanel.get(rootPanelId); - - // Remove the v-app-loading or any splash screen added inside the div by - // the user - root.getElement().setInnerHTML(""); - // For backwards compatibility with static index pages only. - // No longer added by AbstractApplicationServlet/Portlet - root.removeStyleName("v-app-loading"); - - String themeUri = applicationConnection.getConfiguration() - .getThemeUri(); - String themeName = themeUri.substring(themeUri.lastIndexOf('/')); - themeName = themeName.replaceAll("[^a-zA-Z0-9]", ""); - root.addStyleName("v-theme-" + themeName); - - root.add(this); - - if (applicationConnection.getConfiguration().isStandalone()) { - // set focus to iview element by default to listen possible keyboard - // shortcuts. For embedded applications this is unacceptable as we - // don't want to steal focus from the main page nor we don't want - // side-effects from focusing (scrollIntoView). - getElement().focus(); - } - - parentFrame = getParentFrame(); - } - public ShortcutActionHandler getShortcutActionHandler() { return actionHandler; } diff --git a/src/com/vaadin/terminal/gwt/client/ui/VViewPaintable.java b/src/com/vaadin/terminal/gwt/client/ui/VViewPaintable.java new file mode 100644 index 0000000000..ebec292ecb --- /dev/null +++ b/src/com/vaadin/terminal/gwt/client/ui/VViewPaintable.java @@ -0,0 +1,331 @@ +package com.vaadin.terminal.gwt.client.ui; + +import java.util.HashSet; +import java.util.Iterator; + +import com.google.gwt.core.client.GWT; +import com.google.gwt.core.client.Scheduler; +import com.google.gwt.event.dom.client.DomEvent.Type; +import com.google.gwt.event.shared.EventHandler; +import com.google.gwt.event.shared.HandlerRegistration; +import com.google.gwt.user.client.Command; +import com.google.gwt.user.client.DOM; +import com.google.gwt.user.client.Event; +import com.google.gwt.user.client.History; +import com.google.gwt.user.client.Window; +import com.google.gwt.user.client.ui.RootPanel; +import com.google.gwt.user.client.ui.Widget; +import com.vaadin.terminal.gwt.client.ApplicationConnection; +import com.vaadin.terminal.gwt.client.BrowserInfo; +import com.vaadin.terminal.gwt.client.Focusable; +import com.vaadin.terminal.gwt.client.UIDL; +import com.vaadin.terminal.gwt.client.Util; +import com.vaadin.terminal.gwt.client.VConsole; +import com.vaadin.terminal.gwt.client.VPaintableMap; +import com.vaadin.terminal.gwt.client.VPaintableWidget; + +public class VViewPaintable extends VAbstractPaintableWidgetContainer { + + private static final String CLICK_EVENT_IDENTIFIER = VPanelPaintable.CLICK_EVENT_IDENTIFIER; + + public void updateFromUIDL(final UIDL uidl, ApplicationConnection client) { + getWidgetForPaintable().rendering = true; + + getWidgetForPaintable().id = uidl.getId(); + boolean firstPaint = getWidgetForPaintable().connection == null; + getWidgetForPaintable().connection = client; + + getWidgetForPaintable().immediate = uidl.hasAttribute("immediate"); + getWidgetForPaintable().resizeLazy = uidl + .hasAttribute(VView.RESIZE_LAZY); + String newTheme = uidl.getStringAttribute("theme"); + if (getWidgetForPaintable().theme != null + && !newTheme.equals(getWidgetForPaintable().theme)) { + // Complete page refresh is needed due css can affect layout + // calculations etc + getWidgetForPaintable().reloadHostPage(); + } else { + getWidgetForPaintable().theme = newTheme; + } + if (uidl.hasAttribute("style")) { + getWidgetForPaintable().setStyleName( + getWidgetForPaintable().getStylePrimaryName() + " " + + uidl.getStringAttribute("style")); + } + + clickEventHandler.handleEventHandlerRegistration(client); + + if (!getWidgetForPaintable().isEmbedded() + && uidl.hasAttribute("caption")) { + // only change window title if we're in charge of the whole page + com.google.gwt.user.client.Window.setTitle(uidl + .getStringAttribute("caption")); + } + + // Process children + int childIndex = 0; + + // Open URL:s + boolean isClosed = false; // was this window closed? + while (childIndex < uidl.getChildCount() + && "open".equals(uidl.getChildUIDL(childIndex).getTag())) { + final UIDL open = uidl.getChildUIDL(childIndex); + final String url = client.translateVaadinUri(open + .getStringAttribute("src")); + final String target = open.getStringAttribute("name"); + if (target == null) { + // source will be opened to this browser window, but we may have + // to finish rendering this window in case this is a download + // (and window stays open). + Scheduler.get().scheduleDeferred(new Command() { + public void execute() { + VView.goTo(url); + } + }); + } else if ("_self".equals(target)) { + // This window is closing (for sure). Only other opens are + // relevant in this change. See #3558, #2144 + isClosed = true; + VView.goTo(url); + } else { + String options; + if (open.hasAttribute("border")) { + if (open.getStringAttribute("border").equals("minimal")) { + options = "menubar=yes,location=no,status=no"; + } else { + options = "menubar=no,location=no,status=no"; + } + + } else { + options = "resizable=yes,menubar=yes,toolbar=yes,directories=yes,location=yes,scrollbars=yes,status=yes"; + } + + if (open.hasAttribute("width")) { + int w = open.getIntAttribute("width"); + options += ",width=" + w; + } + if (open.hasAttribute("height")) { + int h = open.getIntAttribute("height"); + options += ",height=" + h; + } + + Window.open(url, target, options); + } + childIndex++; + } + if (isClosed) { + // don't render the content, something else will be opened to this + // browser view + getWidgetForPaintable().rendering = false; + return; + } + + // Draw this application level window + UIDL childUidl = uidl.getChildUIDL(childIndex); + final VPaintableWidget lo = client.getPaintable(childUidl); + + if (getWidgetForPaintable().layout != null) { + if (getWidgetForPaintable().layout != lo) { + // remove old + client.unregisterPaintable(getWidgetForPaintable().layout); + // add new + getWidgetForPaintable().setWidget(lo.getWidgetForPaintable()); + getWidgetForPaintable().layout = lo; + } + } else { + getWidgetForPaintable().setWidget(lo.getWidgetForPaintable()); + getWidgetForPaintable().layout = lo; + } + + getWidgetForPaintable().layout.updateFromUIDL(childUidl, client); + if (!childUidl.getBooleanAttribute("cached")) { + getWidgetForPaintable().updateParentFrameSize(); + } + + // Save currently open subwindows to track which will need to be closed + final HashSet removedSubWindows = new HashSet( + getWidgetForPaintable().subWindows); + + // Handle other UIDL children + while ((childUidl = uidl.getChildUIDL(++childIndex)) != null) { + String tag = childUidl.getTag().intern(); + if (tag == "actions") { + if (getWidgetForPaintable().actionHandler == null) { + getWidgetForPaintable().actionHandler = new ShortcutActionHandler( + getWidgetForPaintable().id, client); + } + getWidgetForPaintable().actionHandler + .updateActionMap(childUidl); + } else if (tag == "execJS") { + String script = childUidl.getStringAttribute("script"); + VView.eval(script); + } else if (tag == "notifications") { + for (final Iterator it = childUidl.getChildIterator(); it + .hasNext();) { + final UIDL notification = (UIDL) it.next(); + VNotification.showNotification(client, notification); + } + } else { + // subwindows + final VPaintableWidget w = client.getPaintable(childUidl); + if (getWidgetForPaintable().subWindows.contains(w)) { + removedSubWindows.remove(w); + } else { + getWidgetForPaintable().subWindows.add((VWindow) w); + } + w.updateFromUIDL(childUidl, client); + } + } + + // Close old windows which where not in UIDL anymore + for (final Iterator rem = removedSubWindows.iterator(); rem + .hasNext();) { + final VWindow w = rem.next(); + client.unregisterPaintable(VPaintableMap.get(getConnection()) + .getPaintable(w)); + getWidgetForPaintable().subWindows.remove(w); + w.hide(); + } + + if (uidl.hasAttribute("focused")) { + // set focused component when render phase is finished + Scheduler.get().scheduleDeferred(new Command() { + public void execute() { + VPaintableWidget paintable = (VPaintableWidget) uidl + .getPaintableAttribute("focused", getConnection()); + + final Widget toBeFocused = paintable + .getWidgetForPaintable(); + /* + * Two types of Widgets can be focused, either implementing + * GWT HasFocus of a thinner Vaadin specific Focusable + * interface. + */ + if (toBeFocused instanceof com.google.gwt.user.client.ui.Focusable) { + final com.google.gwt.user.client.ui.Focusable toBeFocusedWidget = (com.google.gwt.user.client.ui.Focusable) toBeFocused; + toBeFocusedWidget.setFocus(true); + } else if (toBeFocused instanceof Focusable) { + ((Focusable) toBeFocused).focus(); + } else { + VConsole.log("Could not focus component"); + } + } + }); + } + + // Add window listeners on first paint, to prevent premature + // variablechanges + if (firstPaint) { + Window.addWindowClosingHandler(getWidgetForPaintable()); + Window.addResizeHandler(getWidgetForPaintable()); + } + + getWidgetForPaintable().onResize(); + + // finally set scroll position from UIDL + if (uidl.hasVariable("scrollTop")) { + getWidgetForPaintable().scrollable = true; + getWidgetForPaintable().scrollTop = uidl + .getIntVariable("scrollTop"); + DOM.setElementPropertyInt(getWidgetForPaintable().getElement(), + "scrollTop", getWidgetForPaintable().scrollTop); + getWidgetForPaintable().scrollLeft = uidl + .getIntVariable("scrollLeft"); + DOM.setElementPropertyInt(getWidgetForPaintable().getElement(), + "scrollLeft", getWidgetForPaintable().scrollLeft); + } else { + getWidgetForPaintable().scrollable = false; + } + + // Safari workaround must be run after scrollTop is updated as it sets + // scrollTop using a deferred command. + if (BrowserInfo.get().isSafari()) { + Util.runWebkitOverflowAutoFix(getWidgetForPaintable().getElement()); + } + + getWidgetForPaintable().scrollIntoView(uidl); + + if (uidl.hasAttribute(VView.FRAGMENT_VARIABLE)) { + getWidgetForPaintable().currentFragment = uidl + .getStringAttribute(VView.FRAGMENT_VARIABLE); + if (!getWidgetForPaintable().currentFragment.equals(History + .getToken())) { + History.newItem(getWidgetForPaintable().currentFragment, true); + } + } else { + // Initial request for which the server doesn't yet have a fragment + // (and haven't shown any interest in getting one) + getWidgetForPaintable().currentFragment = History.getToken(); + + // Include current fragment in the next request + client.updateVariable(getWidgetForPaintable().id, + VView.FRAGMENT_VARIABLE, + getWidgetForPaintable().currentFragment, false); + } + + getWidgetForPaintable().rendering = false; + } + + public void init(String rootPanelId, + ApplicationConnection applicationConnection) { + DOM.sinkEvents(getWidgetForPaintable().getElement(), Event.ONKEYDOWN + | Event.ONSCROLL); + + // iview is focused when created so element needs tabIndex + // 1 due 0 is at the end of natural tabbing order + DOM.setElementProperty(getWidgetForPaintable().getElement(), + "tabIndex", "1"); + + RootPanel root = RootPanel.get(rootPanelId); + + // Remove the v-app-loading or any splash screen added inside the div by + // the user + root.getElement().setInnerHTML(""); + // For backwards compatibility with static index pages only. + // No longer added by AbstractApplicationServlet/Portlet + root.removeStyleName("v-app-loading"); + + String themeUri = applicationConnection.getConfiguration() + .getThemeUri(); + String themeName = themeUri.substring(themeUri.lastIndexOf('/')); + themeName = themeName.replaceAll("[^a-zA-Z0-9]", ""); + root.addStyleName("v-theme-" + themeName); + + root.add(getWidgetForPaintable()); + + if (applicationConnection.getConfiguration().isStandalone()) { + // set focus to iview element by default to listen possible keyboard + // shortcuts. For embedded applications this is unacceptable as we + // don't want to steal focus from the main page nor we don't want + // side-effects from focusing (scrollIntoView). + getWidgetForPaintable().getElement().focus(); + } + + getWidgetForPaintable().parentFrame = VView.getParentFrame(); + } + + private ClickEventHandler clickEventHandler = new ClickEventHandler(this, + CLICK_EVENT_IDENTIFIER) { + + @Override + protected HandlerRegistration registerHandler( + H handler, Type type) { + return getWidgetForPaintable().addDomHandler(handler, type); + } + }; + + public void updateCaption(VPaintableWidget component, UIDL uidl) { + // NOP The main view never draws caption for its layout + } + + @Override + public VView getWidgetForPaintable() { + return (VView) super.getWidgetForPaintable(); + } + + @Override + protected Widget createWidget() { + return GWT.create(VView.class); + } + +} diff --git a/src/com/vaadin/terminal/gwt/client/ui/VWindow.java b/src/com/vaadin/terminal/gwt/client/ui/VWindow.java index 95ab0dc773..662b77a7b0 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VWindow.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VWindow.java @@ -13,21 +13,17 @@ import com.google.gwt.core.client.Scheduler; import com.google.gwt.core.client.Scheduler.ScheduledCommand; import com.google.gwt.event.dom.client.BlurEvent; import com.google.gwt.event.dom.client.BlurHandler; -import com.google.gwt.event.dom.client.DomEvent.Type; import com.google.gwt.event.dom.client.FocusEvent; import com.google.gwt.event.dom.client.FocusHandler; import com.google.gwt.event.dom.client.KeyDownEvent; import com.google.gwt.event.dom.client.KeyDownHandler; import com.google.gwt.event.dom.client.ScrollEvent; import com.google.gwt.event.dom.client.ScrollHandler; -import com.google.gwt.event.shared.EventHandler; -import com.google.gwt.event.shared.HandlerRegistration; import com.google.gwt.user.client.Command; import com.google.gwt.user.client.DOM; import com.google.gwt.user.client.Element; import com.google.gwt.user.client.Event; import com.google.gwt.user.client.Window; -import com.google.gwt.user.client.ui.Frame; import com.google.gwt.user.client.ui.HasWidgets; import com.google.gwt.user.client.ui.RootPanel; import com.google.gwt.user.client.ui.Widget; @@ -38,10 +34,8 @@ import com.vaadin.terminal.gwt.client.Container; import com.vaadin.terminal.gwt.client.EventId; import com.vaadin.terminal.gwt.client.Focusable; import com.vaadin.terminal.gwt.client.RenderSpace; -import com.vaadin.terminal.gwt.client.UIDL; import com.vaadin.terminal.gwt.client.Util; import com.vaadin.terminal.gwt.client.VPaintableWidget; -import com.vaadin.terminal.gwt.client.ui.ShortcutActionHandler.BeforeShortcutActionListener; import com.vaadin.terminal.gwt.client.ui.ShortcutActionHandler.ShortcutActionHandlerOwner; /** @@ -51,7 +45,7 @@ import com.vaadin.terminal.gwt.client.ui.ShortcutActionHandler.ShortcutActionHan */ public class VWindow extends VOverlay implements Container, ShortcutActionHandlerOwner, ScrollHandler, KeyDownHandler, - FocusHandler, BlurHandler, BeforeShortcutActionListener, Focusable { + FocusHandler, BlurHandler, Focusable { /** * Minimum allowed height of a window. This refers to the content area, not @@ -88,9 +82,9 @@ public class VWindow extends VOverlay implements Container, public static final int Z_INDEX = 10000; - private VPaintableWidget layout; + VPaintableWidget layout; - private Element contents; + Element contents; private Element header; @@ -98,7 +92,7 @@ public class VWindow extends VOverlay implements Container, private Element resizeBox; - private final FocusableScrollPanel contentPanel = new FocusableScrollPanel(); + final FocusableScrollPanel contentPanel = new FocusableScrollPanel(); private boolean dragging; @@ -116,11 +110,11 @@ public class VWindow extends VOverlay implements Container, private int origH; - private Element closeBox; + Element closeBox; protected ApplicationConnection client; - private String id; + String id; ShortcutActionHandler shortcutHandler; @@ -130,13 +124,13 @@ public class VWindow extends VOverlay implements Container, /** Last known positiony read from UIDL or updated to application connection */ private int uidlPositionY = -1; - private boolean vaadinModality = false; + boolean vaadinModality = false; - private boolean resizable = true; + boolean resizable = true; private boolean draggable = true; - private boolean resizeLazy = false; + boolean resizeLazy = false; private Element modalityCurtain; private Element draggingCurtain; @@ -163,23 +157,13 @@ public class VWindow extends VOverlay implements Container, private String height; - private boolean immediate; + boolean immediate; private Element wrapper, wrapper2; - private ClickEventHandler clickEventHandler = new ClickEventHandler(this, - VPanel.CLICK_EVENT_IDENTIFIER) { + boolean visibilityChangesDisabled; - @Override - protected HandlerRegistration registerHandler( - H handler, Type type) { - return addDomHandler(handler, type); - } - }; - - private boolean visibilityChangesDisabled; - - private int bringToFrontSequence = -1; + int bringToFrontSequence = -1; private VLazyExecutor delayedContentsSizeUpdater = new VLazyExecutor(200, new ScheduledCommand() { @@ -284,230 +268,12 @@ public class VWindow extends VOverlay implements Container, } - public void updateFromUIDL(UIDL uidl, ApplicationConnection client) { - id = uidl.getId(); - this.client = client; - - // Workaround needed for Testing Tools (GWT generates window DOM - // slightly different in different browsers). - DOM.setElementProperty(closeBox, "id", id + "_window_close"); - - if (uidl.hasAttribute("invisible")) { - hide(); - return; - } - - if (!uidl.hasAttribute("cached")) { - if (uidl.getBooleanAttribute("modal") != vaadinModality) { - setVaadinModality(!vaadinModality); - } - if (!isAttached()) { - setVisible(false); // hide until possible centering - show(); - } - if (uidl.getBooleanAttribute("resizable") != resizable) { - setResizable(!resizable); - } - resizeLazy = uidl.hasAttribute(VView.RESIZE_LAZY); - - setDraggable(!uidl.hasAttribute("fixedposition")); - - // Caption must be set before required header size is measured. If - // the caption attribute is missing the caption should be cleared. - setCaption(uidl.getStringAttribute("caption"), - uidl.getStringAttribute("icon")); - } - - visibilityChangesDisabled = true; - if (client.updateComponent(this, uidl, false)) { - return; - } - visibilityChangesDisabled = false; - - clickEventHandler.handleEventHandlerRegistration(client); - - immediate = uidl.hasAttribute("immediate"); - - setClosable(!uidl.getBooleanAttribute("readonly")); - - // Initialize the position form UIDL - int positionx = uidl.getIntVariable("positionx"); - int positiony = uidl.getIntVariable("positiony"); - if (positionx >= 0 || positiony >= 0) { - if (positionx < 0) { - positionx = 0; - } - if (positiony < 0) { - positiony = 0; - } - setPopupPosition(positionx, positiony); - } - - boolean showingUrl = false; - int childIndex = 0; - UIDL childUidl = uidl.getChildUIDL(childIndex++); - while ("open".equals(childUidl.getTag())) { - // TODO multiple opens with the same target will in practice just - // open the last one - should we fix that somehow? - final String parsedUri = client.translateVaadinUri(childUidl - .getStringAttribute("src")); - if (!childUidl.hasAttribute("name")) { - final Frame frame = new Frame(); - DOM.setStyleAttribute(frame.getElement(), "width", "100%"); - DOM.setStyleAttribute(frame.getElement(), "height", "100%"); - DOM.setStyleAttribute(frame.getElement(), "border", "0px"); - frame.setUrl(parsedUri); - contentPanel.setWidget(frame); - showingUrl = true; - } else { - final String target = childUidl.getStringAttribute("name"); - Window.open(parsedUri, target, ""); - } - childUidl = uidl.getChildUIDL(childIndex++); - } - - final VPaintableWidget lo = client.getPaintable(childUidl); - if (layout != null) { - if (layout != lo) { - // remove old - client.unregisterPaintable(layout); - contentPanel.remove(layout.getWidgetForPaintable()); - // add new - if (!showingUrl) { - contentPanel.setWidget(lo.getWidgetForPaintable()); - } - layout = lo; - } - } else if (!showingUrl) { - contentPanel.setWidget(lo.getWidgetForPaintable()); - layout = lo; - } - - dynamicWidth = !uidl.hasAttribute("width"); - dynamicHeight = !uidl.hasAttribute("height"); - - layoutRelativeWidth = uidl.hasAttribute("layoutRelativeWidth"); - layoutRelativeHeight = uidl.hasAttribute("layoutRelativeHeight"); - - if (dynamicWidth && layoutRelativeWidth) { - /* - * Relative layout width, fix window width before rendering (width - * according to caption) - */ - setNaturalWidth(); - } - - layout.updateFromUIDL(childUidl, client); - if (!dynamicHeight && 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(this); - } - - /* - * No explicit width is set and the layout does not have relative width - * so fix the size according to the layout. - */ - if (dynamicWidth && !layoutRelativeWidth) { - setNaturalWidth(); - } - - if (dynamicHeight && layoutRelativeHeight) { - // Prevent resizing until height has been fixed - resizable = false; - } - - // we may have actions and notifications - if (uidl.getChildCount() > 1) { - final int cnt = uidl.getChildCount(); - for (int i = 1; i < cnt; i++) { - childUidl = uidl.getChildUIDL(i); - if (childUidl.getTag().equals("actions")) { - if (shortcutHandler == null) { - shortcutHandler = new ShortcutActionHandler(id, client); - } - shortcutHandler.updateActionMap(childUidl); - } - } - - } - - // setting scrollposition must happen after children is rendered - contentPanel.setScrollPosition(uidl.getIntVariable("scrollTop")); - contentPanel.setHorizontalScrollPosition(uidl - .getIntVariable("scrollLeft")); - - // Center this window on screen if requested - // This has 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 - centered = true; - center(); - } else { - // don't try to center the window anymore - centered = false; - } - updateShadowSizeAndPosition(); - setVisible(true); - - boolean sizeReduced = false; - // ensure window is not larger than browser window - if (getOffsetWidth() > Window.getClientWidth()) { - setWidth(Window.getClientWidth() + "px"); - sizeReduced = true; - } - if (getOffsetHeight() > Window.getClientHeight()) { - setHeight(Window.getClientHeight() + "px"); - sizeReduced = true; - } - - if (dynamicHeight && 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 = contents.getOffsetHeight() + getExtraHeight(); - int w = getElement().getOffsetWidth(); - - client.updateVariable(id, "height", h, false); - client.updateVariable(id, "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(this); - } - - Util.runWebkitOverflowAutoFix(contentPanel.getElement()); - - client.getView().scrollIntoView(uidl); - - if (uidl.hasAttribute("bringToFront")) { - /* - * Focus as a side-efect. Will be overridden by - * ApplicationConnection if another component was focused by the - * server side. - */ - contentPanel.focus(); - bringToFrontSequence = uidl.getIntAttribute("bringToFront"); - deferOrdering(); - } - } - /** * Calling this method will defer ordering algorithm, to order windows based * on servers bringToFront and modality instructions. Non changed windows * will be left intact. */ - private static void deferOrdering() { + static void deferOrdering() { if (!orderingDefered) { orderingDefered = true; Scheduler.get().scheduleFinally(new Command() { @@ -562,7 +328,7 @@ public class VWindow extends VOverlay implements Container, } } - private void setDraggable(boolean draggable) { + void setDraggable(boolean draggable) { if (this.draggable == draggable) { return; } @@ -573,7 +339,7 @@ public class VWindow extends VOverlay implements Container, } private void setCursorProperties() { - if (!this.draggable) { + if (!draggable) { header.getStyle().setProperty("cursor", "default"); footer.getStyle().setProperty("cursor", "default"); } else { @@ -582,7 +348,7 @@ public class VWindow extends VOverlay implements Container, } } - private void setNaturalWidth() { + 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 @@ -676,7 +442,7 @@ public class VWindow extends VOverlay implements Container, super.hide(); } - private void setVaadinModality(boolean modality) { + void setVaadinModality(boolean modality) { vaadinModality = modality; if (vaadinModality) { if (isAttached()) { @@ -767,7 +533,7 @@ public class VWindow extends VOverlay implements Container, return curtain; } - private void setResizable(boolean resizability) { + void setResizable(boolean resizability) { resizable = resizability; if (resizability) { DOM.setElementProperty(footer, "className", CLASSNAME + "-footer"); @@ -832,7 +598,7 @@ public class VWindow extends VOverlay implements Container, if (client != null && header.isOrHasChild(target)) { // Handle window caption tooltips - client.handleTooltipEvent(event, this); + client.handleWidgetTooltipEvent(event, this); } if (resizing || resizeBox == target) { @@ -1088,7 +854,7 @@ public class VWindow extends VOverlay implements Container, private int extraH = 0; - private int getExtraHeight() { + int getExtraHeight() { extraH = header.getOffsetHeight() + footer.getOffsetHeight(); return extraH; } @@ -1238,10 +1004,6 @@ public class VWindow extends VOverlay implements Container, return true; } - public void updateCaption(VPaintableWidget component, UIDL uidl) { - // NOP, window has own caption, layout captio not rendered - } - public ShortcutActionHandler getShortcutActionHandler() { return shortcutHandler; } @@ -1263,22 +1025,17 @@ public class VWindow extends VOverlay implements Container, } public void onBlur(BlurEvent event) { - if (client.hasEventListeners(this, EventId.BLUR)) { + if (client.hasWidgetEventListeners(this, EventId.BLUR)) { client.updateVariable(id, EventId.BLUR, "", true); } } public void onFocus(FocusEvent event) { - if (client.hasEventListeners(this, EventId.FOCUS)) { + if (client.hasWidgetEventListeners(this, EventId.FOCUS)) { client.updateVariable(id, EventId.FOCUS, "", true); } } - public void onBeforeShortcutAction(Event e) { - // NOP, nothing to update just avoid workaround ( causes excess - // blur/focus ) - } - public void focus() { contentPanel.focus(); } diff --git a/src/com/vaadin/terminal/gwt/client/ui/VWindowPaintable.java b/src/com/vaadin/terminal/gwt/client/ui/VWindowPaintable.java new file mode 100644 index 0000000000..25fd951dd9 --- /dev/null +++ b/src/com/vaadin/terminal/gwt/client/ui/VWindowPaintable.java @@ -0,0 +1,296 @@ +package com.vaadin.terminal.gwt.client.ui; + +import com.google.gwt.core.client.GWT; +import com.google.gwt.event.dom.client.DomEvent.Type; +import com.google.gwt.event.shared.EventHandler; +import com.google.gwt.event.shared.HandlerRegistration; +import com.google.gwt.user.client.DOM; +import com.google.gwt.user.client.Event; +import com.google.gwt.user.client.Window; +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.UIDL; +import com.vaadin.terminal.gwt.client.Util; +import com.vaadin.terminal.gwt.client.VPaintableWidget; +import com.vaadin.terminal.gwt.client.ui.ShortcutActionHandler.BeforeShortcutActionListener; + +public class VWindowPaintable extends VAbstractPaintableWidgetContainer + implements BeforeShortcutActionListener { + + private static final String CLICK_EVENT_IDENTIFIER = VPanelPaintable.CLICK_EVENT_IDENTIFIER; + + private ClickEventHandler clickEventHandler = new ClickEventHandler(this, + CLICK_EVENT_IDENTIFIER) { + + @Override + protected HandlerRegistration registerHandler( + H handler, Type type) { + return getWidgetForPaintable().addDomHandler(handler, type); + } + }; + + public void updateFromUIDL(UIDL uidl, ApplicationConnection client) { + getWidgetForPaintable().id = uidl.getId(); + getWidgetForPaintable().client = client; + + // Workaround needed for Testing Tools (GWT generates window DOM + // slightly different in different browsers). + DOM.setElementProperty(getWidgetForPaintable().closeBox, "id", + getWidgetForPaintable().id + "_window_close"); + + if (uidl.hasAttribute("invisible")) { + getWidgetForPaintable().hide(); + return; + } + + if (!uidl.hasAttribute("cached")) { + if (uidl.getBooleanAttribute("modal") != getWidgetForPaintable().vaadinModality) { + getWidgetForPaintable().setVaadinModality( + !getWidgetForPaintable().vaadinModality); + } + if (!getWidgetForPaintable().isAttached()) { + getWidgetForPaintable().setVisible(false); // hide until + // possible centering + getWidgetForPaintable().show(); + } + if (uidl.getBooleanAttribute("resizable") != getWidgetForPaintable().resizable) { + getWidgetForPaintable().setResizable( + !getWidgetForPaintable().resizable); + } + getWidgetForPaintable().resizeLazy = uidl + .hasAttribute(VView.RESIZE_LAZY); + + getWidgetForPaintable().setDraggable( + !uidl.hasAttribute("fixedposition")); + + // Caption must be set before required header size is measured. If + // the caption attribute is missing the caption should be cleared. + getWidgetForPaintable().setCaption( + uidl.getStringAttribute("caption"), + uidl.getStringAttribute("icon")); + } + + getWidgetForPaintable().visibilityChangesDisabled = true; + if (client.updateComponent(this, uidl, false)) { + return; + } + getWidgetForPaintable().visibilityChangesDisabled = false; + + clickEventHandler.handleEventHandlerRegistration(client); + + getWidgetForPaintable().immediate = uidl.hasAttribute("immediate"); + + getWidgetForPaintable().setClosable( + !uidl.getBooleanAttribute("readonly")); + + // Initialize the position form UIDL + int positionx = uidl.getIntVariable("positionx"); + int positiony = uidl.getIntVariable("positiony"); + if (positionx >= 0 || positiony >= 0) { + if (positionx < 0) { + positionx = 0; + } + if (positiony < 0) { + positiony = 0; + } + getWidgetForPaintable().setPopupPosition(positionx, positiony); + } + + boolean showingUrl = false; + int childIndex = 0; + UIDL childUidl = uidl.getChildUIDL(childIndex++); + while ("open".equals(childUidl.getTag())) { + // TODO multiple opens with the same target will in practice just + // open the last one - should we fix that somehow? + final String parsedUri = client.translateVaadinUri(childUidl + .getStringAttribute("src")); + if (!childUidl.hasAttribute("name")) { + final Frame frame = new Frame(); + DOM.setStyleAttribute(frame.getElement(), "width", "100%"); + DOM.setStyleAttribute(frame.getElement(), "height", "100%"); + DOM.setStyleAttribute(frame.getElement(), "border", "0px"); + frame.setUrl(parsedUri); + getWidgetForPaintable().contentPanel.setWidget(frame); + showingUrl = true; + } else { + final String target = childUidl.getStringAttribute("name"); + Window.open(parsedUri, target, ""); + } + childUidl = uidl.getChildUIDL(childIndex++); + } + + final VPaintableWidget lo = client.getPaintable(childUidl); + if (getWidgetForPaintable().layout != null) { + if (getWidgetForPaintable().layout != lo) { + // remove old + client.unregisterPaintable(getWidgetForPaintable().layout); + getWidgetForPaintable().contentPanel + .remove(getWidgetForPaintable().layout + .getWidgetForPaintable()); + // add new + if (!showingUrl) { + getWidgetForPaintable().contentPanel.setWidget(lo + .getWidgetForPaintable()); + } + getWidgetForPaintable().layout = lo; + } + } else if (!showingUrl) { + getWidgetForPaintable().contentPanel.setWidget(lo + .getWidgetForPaintable()); + getWidgetForPaintable().layout = lo; + } + + getWidgetForPaintable().dynamicWidth = !uidl.hasAttribute("width"); + getWidgetForPaintable().dynamicHeight = !uidl.hasAttribute("height"); + + getWidgetForPaintable().layoutRelativeWidth = uidl + .hasAttribute("layoutRelativeWidth"); + getWidgetForPaintable().layoutRelativeHeight = uidl + .hasAttribute("layoutRelativeHeight"); + + if (getWidgetForPaintable().dynamicWidth + && getWidgetForPaintable().layoutRelativeWidth) { + /* + * Relative layout width, fix window width before rendering (width + * according to caption) + */ + getWidgetForPaintable().setNaturalWidth(); + } + + getWidgetForPaintable().layout.updateFromUIDL(childUidl, client); + if (!getWidgetForPaintable().dynamicHeight + && getWidgetForPaintable().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(getWidgetForPaintable()); + } + + /* + * No explicit width is set and the layout does not have relative width + * so fix the size according to the layout. + */ + if (getWidgetForPaintable().dynamicWidth + && !getWidgetForPaintable().layoutRelativeWidth) { + getWidgetForPaintable().setNaturalWidth(); + } + + if (getWidgetForPaintable().dynamicHeight + && getWidgetForPaintable().layoutRelativeHeight) { + // Prevent resizing until height has been fixed + getWidgetForPaintable().resizable = false; + } + + // we may have actions and notifications + if (uidl.getChildCount() > 1) { + final int cnt = uidl.getChildCount(); + for (int i = 1; i < cnt; i++) { + childUidl = uidl.getChildUIDL(i); + if (childUidl.getTag().equals("actions")) { + if (getWidgetForPaintable().shortcutHandler == null) { + getWidgetForPaintable().shortcutHandler = new ShortcutActionHandler( + getId(), client); + } + getWidgetForPaintable().shortcutHandler + .updateActionMap(childUidl); + } + } + + } + + // setting scrollposition must happen after children is rendered + getWidgetForPaintable().contentPanel.setScrollPosition(uidl + .getIntVariable("scrollTop")); + getWidgetForPaintable().contentPanel.setHorizontalScrollPosition(uidl + .getIntVariable("scrollLeft")); + + // Center this window on screen if requested + // This has 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 + getWidgetForPaintable().centered = true; + getWidgetForPaintable().center(); + } else { + // don't try to center the window anymore + getWidgetForPaintable().centered = false; + } + getWidgetForPaintable().updateShadowSizeAndPosition(); + getWidgetForPaintable().setVisible(true); + + boolean sizeReduced = false; + // ensure window is not larger than browser window + if (getWidgetForPaintable().getOffsetWidth() > Window.getClientWidth()) { + getWidgetForPaintable().setWidth(Window.getClientWidth() + "px"); + sizeReduced = true; + } + if (getWidgetForPaintable().getOffsetHeight() > Window + .getClientHeight()) { + getWidgetForPaintable().setHeight(Window.getClientHeight() + "px"); + sizeReduced = true; + } + + if (getWidgetForPaintable().dynamicHeight + && getWidgetForPaintable().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 = getWidgetForPaintable().contents.getOffsetHeight() + + getWidgetForPaintable().getExtraHeight(); + int w = getWidgetForPaintable().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(getWidgetForPaintable()); + } + + Util.runWebkitOverflowAutoFix(getWidgetForPaintable().contentPanel + .getElement()); + + client.getView().getWidgetForPaintable().scrollIntoView(uidl); + + if (uidl.hasAttribute("bringToFront")) { + /* + * Focus as a side-efect. Will be overridden by + * ApplicationConnection if another component was focused by the + * server side. + */ + getWidgetForPaintable().contentPanel.focus(); + getWidgetForPaintable().bringToFrontSequence = uidl + .getIntAttribute("bringToFront"); + VWindow.deferOrdering(); + } + } + + public void updateCaption(VPaintableWidget component, UIDL uidl) { + // NOP, window has own caption, layout captio not rendered + } + + public void onBeforeShortcutAction(Event e) { + // NOP, nothing to update just avoid workaround ( causes excess + // blur/focus ) + } + + @Override + public VWindow getWidgetForPaintable() { + return (VWindow) super.getWidgetForPaintable(); + } + + @Override + protected Widget createWidget() { + return GWT.create(VWindow.class); + } + +} diff --git a/src/com/vaadin/terminal/gwt/widgetsetutils/WidgetMapGenerator.java b/src/com/vaadin/terminal/gwt/widgetsetutils/WidgetMapGenerator.java index d8115aac86..76178baa6e 100644 --- a/src/com/vaadin/terminal/gwt/widgetsetutils/WidgetMapGenerator.java +++ b/src/com/vaadin/terminal/gwt/widgetsetutils/WidgetMapGenerator.java @@ -25,6 +25,7 @@ import com.google.gwt.user.rebind.SourceWriter; import com.vaadin.terminal.Paintable; import com.vaadin.terminal.gwt.client.VPaintableWidget; import com.vaadin.terminal.gwt.client.ui.VView; +import com.vaadin.terminal.gwt.client.ui.VViewPaintable; import com.vaadin.ui.ClientWidget; import com.vaadin.ui.ClientWidget.LoadStyle; import com.vaadin.ui.Root; @@ -384,7 +385,7 @@ public class WidgetMapGenerator extends Generator { Class class1) { Class clientClass; if (Root.class == class1) { - clientClass = VView.class; + clientClass = VViewPaintable.class; } else { ClientWidget annotation = class1.getAnnotation(ClientWidget.class); clientClass = annotation.value(); diff --git a/src/com/vaadin/ui/Window.java b/src/com/vaadin/ui/Window.java index a860d371b0..e6c8642b84 100644 --- a/src/com/vaadin/ui/Window.java +++ b/src/com/vaadin/ui/Window.java @@ -23,7 +23,7 @@ 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.VWindow; +import com.vaadin.terminal.gwt.client.ui.VWindowPaintable; /** * A component that represents an application (browser native) window or a sub @@ -71,7 +71,7 @@ import com.vaadin.terminal.gwt.client.ui.VWindow; * @since 3.0 */ @SuppressWarnings("serial") -@ClientWidget(VWindow.class) +@ClientWidget(VWindowPaintable.class) public class Window extends Panel implements FocusNotifier, BlurNotifier { /**