Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

PanelConnector.java 10KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273
  1. /*
  2. * Copyright 2000-2018 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.panel;
  17. import com.google.gwt.dom.client.NativeEvent;
  18. import com.google.gwt.dom.client.Style;
  19. import com.google.gwt.dom.client.Style.Unit;
  20. import com.vaadin.client.ApplicationConnection;
  21. import com.vaadin.client.ComponentConnector;
  22. import com.vaadin.client.ConnectorHierarchyChangeEvent;
  23. import com.vaadin.client.LayoutManager;
  24. import com.vaadin.client.Paintable;
  25. import com.vaadin.client.Profiler;
  26. import com.vaadin.client.UIDL;
  27. import com.vaadin.client.ui.AbstractSingleComponentContainerConnector;
  28. import com.vaadin.client.ui.ClickEventHandler;
  29. import com.vaadin.client.ui.PostLayoutListener;
  30. import com.vaadin.client.ui.ShortcutActionHandler;
  31. import com.vaadin.client.ui.SimpleManagedLayout;
  32. import com.vaadin.client.ui.VPanel;
  33. import com.vaadin.client.ui.layout.MayScrollChildren;
  34. import com.vaadin.shared.MouseEventDetails;
  35. import com.vaadin.shared.ui.ComponentStateUtil;
  36. import com.vaadin.shared.ui.Connect;
  37. import com.vaadin.shared.ui.panel.PanelServerRpc;
  38. import com.vaadin.shared.ui.panel.PanelState;
  39. import com.vaadin.ui.Panel;
  40. @Connect(Panel.class)
  41. public class PanelConnector extends AbstractSingleComponentContainerConnector
  42. implements Paintable, SimpleManagedLayout, PostLayoutListener,
  43. MayScrollChildren {
  44. private Integer uidlScrollTop;
  45. private ClickEventHandler clickEventHandler = new ClickEventHandler(this) {
  46. @Override
  47. protected void fireClick(NativeEvent event,
  48. MouseEventDetails mouseDetails) {
  49. getRpcProxy(PanelServerRpc.class).click(mouseDetails);
  50. }
  51. };
  52. private Integer uidlScrollLeft;
  53. @Override
  54. public void init() {
  55. super.init();
  56. VPanel panel = getWidget();
  57. LayoutManager layoutManager = getLayoutManager();
  58. layoutManager.registerDependency(this, panel.captionNode);
  59. layoutManager.registerDependency(this, panel.bottomDecoration);
  60. layoutManager.registerDependency(this, panel.contentNode);
  61. }
  62. @Override
  63. public void onUnregister() {
  64. VPanel panel = getWidget();
  65. LayoutManager layoutManager = getLayoutManager();
  66. layoutManager.unregisterDependency(this, panel.captionNode);
  67. layoutManager.unregisterDependency(this, panel.bottomDecoration);
  68. layoutManager.unregisterDependency(this, panel.contentNode);
  69. }
  70. @Override
  71. public boolean delegateCaptionHandling() {
  72. return false;
  73. }
  74. @Override
  75. public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
  76. if (isRealUpdate(uidl)) {
  77. // Handle caption displaying and style names, prior generics.
  78. // Affects size calculations
  79. // Restore default stylenames
  80. getWidget().contentNode.setClassName(VPanel.CLASSNAME + "-content");
  81. getWidget().bottomDecoration
  82. .setClassName(VPanel.CLASSNAME + "-deco");
  83. getWidget().captionNode.setClassName(VPanel.CLASSNAME + "-caption");
  84. boolean hasCaption = hasCaption();
  85. if (hasCaption) {
  86. getWidget().setCaption(getState().caption,getState().captionAsHtml);
  87. } else {
  88. getWidget().setCaption("",false);
  89. getWidget().captionNode.setClassName(VPanel.CLASSNAME + "-nocaption");
  90. }
  91. // Add proper stylenames for all elements. This way we can prevent
  92. // unwanted CSS selector inheritance.
  93. final String captionBaseClass = VPanel.CLASSNAME
  94. + (hasCaption ? "-caption" : "-nocaption");
  95. final String contentBaseClass = VPanel.CLASSNAME + "-content";
  96. final String decoBaseClass = VPanel.CLASSNAME + "-deco";
  97. String captionClass = captionBaseClass;
  98. String contentClass = contentBaseClass;
  99. String decoClass = decoBaseClass;
  100. if (ComponentStateUtil.hasStyles(getState())) {
  101. for (String style : getState().styles) {
  102. captionClass += " " + captionBaseClass + "-" + style;
  103. contentClass += " " + contentBaseClass + "-" + style;
  104. decoClass += " " + decoBaseClass + "-" + style;
  105. }
  106. }
  107. getWidget().captionNode.setClassName(captionClass);
  108. getWidget().contentNode.setClassName(contentClass);
  109. getWidget().bottomDecoration.setClassName(decoClass);
  110. getWidget().makeScrollable();
  111. }
  112. if (!isRealUpdate(uidl)) {
  113. return;
  114. }
  115. clickEventHandler.handleEventHandlerRegistration();
  116. getWidget().client = client;
  117. getWidget().id = uidl.getId();
  118. if (getIconUri() != null) {
  119. getWidget().setIconUri(getIconUri(), client);
  120. } else {
  121. getWidget().setIconUri(null, client);
  122. }
  123. getWidget().setErrorIndicatorVisible(null != getState().errorMessage,
  124. getState().errorLevel);
  125. // We may have actions attached to this panel
  126. if (uidl.getChildCount() > 0) {
  127. final int cnt = uidl.getChildCount();
  128. for (int i = 0; i < cnt; i++) {
  129. UIDL childUidl = uidl.getChildUIDL(i);
  130. if (childUidl.getTag().equals("actions")) {
  131. if (getWidget().shortcutHandler == null) {
  132. getWidget().shortcutHandler = new ShortcutActionHandler(
  133. getConnectorId(), client);
  134. }
  135. getWidget().shortcutHandler.updateActionMap(childUidl);
  136. }
  137. }
  138. }
  139. if (getState().scrollTop != getWidget().scrollTop) {
  140. // Sizes are not yet up to date, so changing the scroll position
  141. // is deferred to after the layout phase
  142. uidlScrollTop = getState().scrollTop;
  143. }
  144. if (getState().scrollLeft != getWidget().scrollLeft) {
  145. // Sizes are not yet up to date, so changing the scroll position
  146. // is deferred to after the layout phase
  147. uidlScrollLeft = getState().scrollLeft;
  148. }
  149. // And apply tab index
  150. getWidget().contentNode.setTabIndex(getState().tabIndex);
  151. }
  152. /**
  153. * Detects if caption div should be visible.
  154. *
  155. * @return {@code true} if caption div should be shown
  156. */
  157. protected boolean hasCaption() {
  158. return getState().caption != null && !getState().caption.isEmpty();
  159. }
  160. @Override
  161. public void updateCaption(ComponentConnector component) {
  162. // NOP: layouts caption, errors etc not rendered in Panel
  163. }
  164. @Override
  165. public VPanel getWidget() {
  166. return (VPanel) super.getWidget();
  167. }
  168. @Override
  169. public void layout() {
  170. updateSizes();
  171. }
  172. void updateSizes() {
  173. VPanel panel = getWidget();
  174. LayoutManager layoutManager = getLayoutManager();
  175. Profiler.enter("PanelConnector.layout getHeights");
  176. int top = layoutManager.getOuterHeight(panel.captionNode);
  177. int bottom = layoutManager.getInnerHeight(panel.bottomDecoration);
  178. Profiler.leave("PanelConnector.layout getHeights");
  179. Profiler.enter("PanelConnector.layout modify style");
  180. Style style = panel.getElement().getStyle();
  181. panel.captionNode.getParentElement().getStyle().setMarginTop(-top,
  182. Unit.PX);
  183. panel.bottomDecoration.getStyle().setMarginBottom(-bottom, Unit.PX);
  184. style.setPaddingTop(top, Unit.PX);
  185. style.setPaddingBottom(bottom, Unit.PX);
  186. Profiler.leave("PanelConnector.layout modify style");
  187. // Update scroll positions
  188. Profiler.enter("PanelConnector.layout update scroll positions");
  189. panel.contentNode.setScrollTop(panel.scrollTop);
  190. panel.contentNode.setScrollLeft(panel.scrollLeft);
  191. Profiler.leave("PanelConnector.layout update scroll positions");
  192. // Read actual value back to ensure update logic is correct
  193. Profiler.enter("PanelConnector.layout read scroll positions");
  194. panel.scrollTop = panel.contentNode.getScrollTop();
  195. panel.scrollLeft = panel.contentNode.getScrollLeft();
  196. Profiler.leave("PanelConnector.layout read scroll positions");
  197. }
  198. @Override
  199. public void postLayout() {
  200. VPanel panel = getWidget();
  201. if (uidlScrollTop != null) {
  202. // IE / Safari fix for when scroll top is set to greater than panel
  203. // height
  204. int maxScroll = panel.getWidget().getOffsetHeight();
  205. if (uidlScrollTop > maxScroll) {
  206. uidlScrollTop = maxScroll;
  207. }
  208. panel.contentNode.setScrollTop(uidlScrollTop.intValue());
  209. // Read actual value back to ensure update logic is correct
  210. // TODO Does this trigger reflows?
  211. panel.scrollTop = panel.contentNode.getScrollTop();
  212. uidlScrollTop = null;
  213. }
  214. if (uidlScrollLeft != null) {
  215. panel.contentNode.setScrollLeft(uidlScrollLeft.intValue());
  216. // Read actual value back to ensure update logic is correct
  217. // TODO Does this trigger reflows?
  218. panel.scrollLeft = panel.contentNode.getScrollLeft();
  219. uidlScrollLeft = null;
  220. }
  221. }
  222. @Override
  223. public PanelState getState() {
  224. return (PanelState) super.getState();
  225. }
  226. @Override
  227. public void onConnectorHierarchyChange(
  228. ConnectorHierarchyChangeEvent event) {
  229. // We always have 1 child, unless the child is hidden
  230. getWidget().setWidget(getContentWidget());
  231. }
  232. }