選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

WindowConnector.java 11KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314
  1. /*
  2. * Copyright 2011 Vaadin Ltd.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License"); you may not
  5. * use this file except in compliance with the License. You may obtain a copy of
  6. * the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  12. * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
  13. * License for the specific language governing permissions and limitations under
  14. * the License.
  15. */
  16. package com.vaadin.client.ui.window;
  17. import com.google.gwt.dom.client.Element;
  18. import com.google.gwt.dom.client.NativeEvent;
  19. import com.google.gwt.dom.client.Style;
  20. import com.google.gwt.dom.client.Style.Position;
  21. import com.google.gwt.dom.client.Style.Unit;
  22. import com.google.gwt.user.client.DOM;
  23. import com.google.gwt.user.client.Event;
  24. import com.google.gwt.user.client.Window;
  25. import com.google.gwt.user.client.ui.Widget;
  26. import com.vaadin.client.ApplicationConnection;
  27. import com.vaadin.client.BrowserInfo;
  28. import com.vaadin.client.ComponentConnector;
  29. import com.vaadin.client.ConnectorHierarchyChangeEvent;
  30. import com.vaadin.client.LayoutManager;
  31. import com.vaadin.client.Paintable;
  32. import com.vaadin.client.UIDL;
  33. import com.vaadin.client.ui.AbstractComponentContainerConnector;
  34. import com.vaadin.client.ui.ClickEventHandler;
  35. import com.vaadin.client.ui.PostLayoutListener;
  36. import com.vaadin.client.ui.ShortcutActionHandler;
  37. import com.vaadin.client.ui.ShortcutActionHandler.BeforeShortcutActionListener;
  38. import com.vaadin.client.ui.SimpleManagedLayout;
  39. import com.vaadin.client.ui.layout.MayScrollChildren;
  40. import com.vaadin.shared.MouseEventDetails;
  41. import com.vaadin.shared.ui.Connect;
  42. import com.vaadin.shared.ui.window.WindowServerRpc;
  43. import com.vaadin.shared.ui.window.WindowState;
  44. @Connect(value = com.vaadin.ui.Window.class)
  45. public class WindowConnector extends AbstractComponentContainerConnector
  46. implements Paintable, BeforeShortcutActionListener,
  47. SimpleManagedLayout, PostLayoutListener, MayScrollChildren {
  48. private ClickEventHandler clickEventHandler = new ClickEventHandler(this) {
  49. @Override
  50. protected void fireClick(NativeEvent event,
  51. MouseEventDetails mouseDetails) {
  52. getRpcProxy(WindowServerRpc.class).click(mouseDetails);
  53. }
  54. };
  55. boolean minWidthChecked = false;
  56. @Override
  57. public boolean delegateCaptionHandling() {
  58. return false;
  59. };
  60. @Override
  61. protected void init() {
  62. super.init();
  63. getLayoutManager().registerDependency(this,
  64. getWidget().contentPanel.getElement());
  65. getLayoutManager().registerDependency(this, getWidget().header);
  66. getLayoutManager().registerDependency(this, getWidget().footer);
  67. getWidget().setOwner(getConnection().getUIConnector().getWidget());
  68. }
  69. @Override
  70. public void onUnregister() {
  71. LayoutManager lm = getLayoutManager();
  72. VWindow window = getWidget();
  73. lm.unregisterDependency(this, window.contentPanel.getElement());
  74. lm.unregisterDependency(this, window.header);
  75. lm.unregisterDependency(this, window.footer);
  76. }
  77. @Override
  78. public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
  79. getWidget().id = getConnectorId();
  80. getWidget().client = client;
  81. // Workaround needed for Testing Tools (GWT generates window DOM
  82. // slightly different in different browsers).
  83. DOM.setElementProperty(getWidget().closeBox, "id", getConnectorId()
  84. + "_window_close");
  85. if (isRealUpdate(uidl)) {
  86. if (getState().modal != getWidget().vaadinModality) {
  87. getWidget().setVaadinModality(!getWidget().vaadinModality);
  88. }
  89. if (!getWidget().isAttached()) {
  90. getWidget().setVisible(false); // hide until
  91. // possible centering
  92. getWidget().show();
  93. }
  94. if (getState().resizable != getWidget().resizable) {
  95. getWidget().setResizable(getState().resizable);
  96. }
  97. getWidget().resizeLazy = getState().resizeLazy;
  98. getWidget().setDraggable(getState().draggable);
  99. // Caption must be set before required header size is measured. If
  100. // the caption attribute is missing the caption should be cleared.
  101. String iconURL = null;
  102. if (getIcon() != null) {
  103. iconURL = getIcon();
  104. }
  105. getWidget().setCaption(getState().caption, iconURL);
  106. }
  107. getWidget().visibilityChangesDisabled = true;
  108. if (!isRealUpdate(uidl)) {
  109. return;
  110. }
  111. getWidget().visibilityChangesDisabled = false;
  112. clickEventHandler.handleEventHandlerRegistration();
  113. getWidget().immediate = getState().immediate;
  114. getWidget().setClosable(!isReadOnly());
  115. // Initialize the position form UIDL
  116. int positionx = getState().positionX;
  117. int positiony = getState().positionY;
  118. if (positionx >= 0 || positiony >= 0) {
  119. if (positionx < 0) {
  120. positionx = 0;
  121. }
  122. if (positiony < 0) {
  123. positiony = 0;
  124. }
  125. getWidget().setPopupPosition(positionx, positiony);
  126. }
  127. int childIndex = 0;
  128. // we may have actions
  129. for (int i = 0; i < uidl.getChildCount(); i++) {
  130. UIDL childUidl = uidl.getChildUIDL(i);
  131. if (childUidl.getTag().equals("actions")) {
  132. if (getWidget().shortcutHandler == null) {
  133. getWidget().shortcutHandler = new ShortcutActionHandler(
  134. getConnectorId(), client);
  135. }
  136. getWidget().shortcutHandler.updateActionMap(childUidl);
  137. }
  138. }
  139. // setting scrollposition must happen after children is rendered
  140. getWidget().contentPanel.setScrollPosition(getState().scrollTop);
  141. getWidget().contentPanel
  142. .setHorizontalScrollPosition(getState().scrollLeft);
  143. // Center this window on screen if requested
  144. // This had to be here because we might not know the content size before
  145. // everything is painted into the window
  146. // centered is this is unset on move/resize
  147. getWidget().centered = getState().centered;
  148. getWidget().setVisible(true);
  149. // ensure window is not larger than browser window
  150. if (getWidget().getOffsetWidth() > Window.getClientWidth()) {
  151. getWidget().setWidth(Window.getClientWidth() + "px");
  152. }
  153. if (getWidget().getOffsetHeight() > Window.getClientHeight()) {
  154. getWidget().setHeight(Window.getClientHeight() + "px");
  155. }
  156. if (uidl.hasAttribute("bringToFront")) {
  157. /*
  158. * Focus as a side-effect. Will be overridden by
  159. * ApplicationConnection if another component was focused by the
  160. * server side.
  161. */
  162. getWidget().contentPanel.focus();
  163. getWidget().bringToFrontSequence = uidl
  164. .getIntAttribute("bringToFront");
  165. VWindow.deferOrdering();
  166. }
  167. }
  168. @Override
  169. public void updateCaption(ComponentConnector component) {
  170. // NOP, window has own caption, layout caption not rendered
  171. }
  172. @Override
  173. public void onBeforeShortcutAction(Event e) {
  174. // NOP, nothing to update just avoid workaround ( causes excess
  175. // blur/focus )
  176. }
  177. @Override
  178. public VWindow getWidget() {
  179. return (VWindow) super.getWidget();
  180. }
  181. @Override
  182. public void onConnectorHierarchyChange(ConnectorHierarchyChangeEvent event) {
  183. // We always have 1 child, unless the child is hidden
  184. Widget newChildWidget = null;
  185. ComponentConnector newChild = null;
  186. if (getChildComponents().size() == 1) {
  187. newChild = getChildComponents().get(0);
  188. newChildWidget = newChild.getWidget();
  189. }
  190. getWidget().layout = newChild;
  191. getWidget().contentPanel.setWidget(newChildWidget);
  192. }
  193. @Override
  194. public void layout() {
  195. LayoutManager lm = getLayoutManager();
  196. VWindow window = getWidget();
  197. ComponentConnector layout = window.layout;
  198. Element contentElement = window.contentPanel.getElement();
  199. if (!minWidthChecked) {
  200. boolean needsMinWidth = !isUndefinedWidth()
  201. || layout.isRelativeWidth();
  202. int minWidth = window.getMinWidth();
  203. if (needsMinWidth && lm.getInnerWidth(contentElement) < minWidth) {
  204. minWidthChecked = true;
  205. // Use minimum width if less than a certain size
  206. window.setWidth(minWidth + "px");
  207. }
  208. minWidthChecked = true;
  209. }
  210. boolean needsMinHeight = !isUndefinedHeight()
  211. || layout.isRelativeHeight();
  212. int minHeight = window.getMinHeight();
  213. if (needsMinHeight && lm.getInnerHeight(contentElement) < minHeight) {
  214. // Use minimum height if less than a certain size
  215. window.setHeight(minHeight + "px");
  216. }
  217. Style contentStyle = window.contents.getStyle();
  218. int headerHeight = lm.getOuterHeight(window.header);
  219. contentStyle.setPaddingTop(headerHeight, Unit.PX);
  220. contentStyle.setMarginTop(-headerHeight, Unit.PX);
  221. int footerHeight = lm.getOuterHeight(window.footer);
  222. contentStyle.setPaddingBottom(footerHeight, Unit.PX);
  223. contentStyle.setMarginBottom(-footerHeight, Unit.PX);
  224. /*
  225. * Must set absolute position if the child has relative height and
  226. * there's a chance of horizontal scrolling as some browsers will
  227. * otherwise not take the scrollbar into account when calculating the
  228. * height.
  229. */
  230. Element layoutElement = layout.getWidget().getElement();
  231. Style childStyle = layoutElement.getStyle();
  232. if (layout.isRelativeHeight() && !BrowserInfo.get().isIE9()) {
  233. childStyle.setPosition(Position.ABSOLUTE);
  234. Style wrapperStyle = contentElement.getStyle();
  235. if (window.getElement().getStyle().getWidth().length() == 0
  236. && !layout.isRelativeWidth()) {
  237. /*
  238. * Need to lock width to make undefined width work even with
  239. * absolute positioning
  240. */
  241. int contentWidth = lm.getOuterWidth(layoutElement);
  242. wrapperStyle.setWidth(contentWidth, Unit.PX);
  243. } else {
  244. wrapperStyle.clearWidth();
  245. }
  246. } else {
  247. childStyle.clearPosition();
  248. }
  249. }
  250. @Override
  251. public void postLayout() {
  252. minWidthChecked = false;
  253. VWindow window = getWidget();
  254. if (window.centered) {
  255. window.center();
  256. }
  257. window.positionOrSizeUpdated();
  258. }
  259. @Override
  260. public WindowState getState() {
  261. return (WindowState) super.getState();
  262. }
  263. /**
  264. * Gives the WindowConnector an order number. As a side effect, moves the
  265. * window according to its order number so the windows are stacked. This
  266. * method should be called for each window in the order they should appear.
  267. */
  268. public void setWindowOrderAndPosition() {
  269. getWidget().setWindowOrderAndPosition();
  270. }
  271. }