You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

AbsoluteLayoutConnector.java 9.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275
  1. /*
  2. * Copyright 2000-2016 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.absolutelayout;
  17. import java.util.List;
  18. import com.google.gwt.dom.client.Element;
  19. import com.google.gwt.user.client.DOM;
  20. import com.vaadin.client.ComponentConnector;
  21. import com.vaadin.client.ConnectorHierarchyChangeEvent;
  22. import com.vaadin.client.DirectionalManagedLayout;
  23. import com.vaadin.client.Util;
  24. import com.vaadin.client.VCaption;
  25. import com.vaadin.client.communication.StateChangeEvent;
  26. import com.vaadin.client.communication.StateChangeEvent.StateChangeHandler;
  27. import com.vaadin.client.ui.AbstractComponentContainerConnector;
  28. import com.vaadin.client.ui.LayoutClickEventHandler;
  29. import com.vaadin.client.ui.VAbsoluteLayout;
  30. import com.vaadin.shared.ui.Connect;
  31. import com.vaadin.shared.ui.LayoutClickRpc;
  32. import com.vaadin.shared.ui.absolutelayout.AbsoluteLayoutServerRpc;
  33. import com.vaadin.shared.ui.absolutelayout.AbsoluteLayoutState;
  34. import com.vaadin.ui.AbsoluteLayout;
  35. /**
  36. * Connects the server side {@link AbsoluteLayout} with the client side
  37. * counterpart {@link VAbsoluteLayout}.
  38. */
  39. @Connect(AbsoluteLayout.class)
  40. public class AbsoluteLayoutConnector extends AbstractComponentContainerConnector
  41. implements DirectionalManagedLayout {
  42. private LayoutClickEventHandler clickEventHandler = new LayoutClickEventHandler(
  43. this) {
  44. @Override
  45. protected ComponentConnector getChildComponent(
  46. com.google.gwt.user.client.Element element) {
  47. return getConnectorForElement(element);
  48. }
  49. @Override
  50. protected LayoutClickRpc getLayoutClickRPC() {
  51. return getRpcProxy(AbsoluteLayoutServerRpc.class);
  52. }
  53. };
  54. private StateChangeHandler childStateChangeHandler = event -> {
  55. ComponentConnector child = (ComponentConnector) event.getConnector();
  56. List<String> childStyles = child.getState().styles;
  57. if (childStyles == null) {
  58. getWidget().setWidgetWrapperStyleNames(child.getWidget(),
  59. (String[]) null);
  60. } else {
  61. getWidget().setWidgetWrapperStyleNames(child.getWidget(),
  62. childStyles.toArray(new String[childStyles.size()]));
  63. }
  64. if (event.hasPropertyChanged("height")
  65. || event.hasPropertyChanged("width")) {
  66. setChildWidgetPosition(child);
  67. }
  68. };
  69. /**
  70. * Returns the deepest nested child component which contains "element". The
  71. * child component is also returned if "element" is part of its caption.
  72. *
  73. * @param element
  74. * An element that is a nested sub element of the root element in
  75. * this layout
  76. * @return The Paintable which the element is a part of. Null if the element
  77. * belongs to the layout and not to a child.
  78. * @deprecated As of 7.2, call or override
  79. * {@link #getConnectorForElement(Element)} instead
  80. */
  81. @Deprecated
  82. protected ComponentConnector getConnectorForElement(
  83. com.google.gwt.user.client.Element element) {
  84. return Util.getConnectorForElement(getConnection(), getWidget(),
  85. element);
  86. }
  87. /**
  88. * Returns the deepest nested child component which contains "element". The
  89. * child component is also returned if "element" is part of its caption.
  90. *
  91. * @param element
  92. * An element that is a nested sub element of the root element in
  93. * this layout
  94. * @return The Paintable which the element is a part of. Null if the element
  95. * belongs to the layout and not to a child.
  96. *
  97. * @since 7.2
  98. */
  99. protected ComponentConnector getConnectorForElement(Element element) {
  100. return getConnectorForElement(DOM.asOld(element));
  101. }
  102. /*
  103. * (non-Javadoc)
  104. *
  105. * @see com.vaadin.client.HasComponentsConnector#updateCaption(com.vaadin
  106. * .client.ComponentConnector)
  107. */
  108. @Override
  109. public void updateCaption(ComponentConnector childConnector) {
  110. VAbsoluteLayout absoluteLayoutWidget = getWidget();
  111. boolean captionIsNeeded = VCaption.isNeeded(childConnector);
  112. VCaption caption = absoluteLayoutWidget
  113. .getWidgetCaption(childConnector.getWidget());
  114. if (captionIsNeeded) {
  115. if (caption == null) {
  116. caption = new VCaption(childConnector, getConnection());
  117. }
  118. absoluteLayoutWidget.setWidgetCaption(childConnector.getWidget(),
  119. caption);
  120. } else if (caption != null) {
  121. absoluteLayoutWidget.setWidgetCaption(childConnector.getWidget(),
  122. null);
  123. }
  124. }
  125. /*
  126. * (non-Javadoc)
  127. *
  128. * @see com.vaadin.client.ui.AbstractComponentConnector#getWidget()
  129. */
  130. @Override
  131. public VAbsoluteLayout getWidget() {
  132. return (VAbsoluteLayout) super.getWidget();
  133. }
  134. /*
  135. * (non-Javadoc)
  136. *
  137. * @see com.vaadin.client.ui.AbstractComponentConnector#getState()
  138. */
  139. @Override
  140. public AbsoluteLayoutState getState() {
  141. return (AbsoluteLayoutState) super.getState();
  142. }
  143. /*
  144. * (non-Javadoc)
  145. *
  146. * @see
  147. * com.vaadin.client.ui.AbstractComponentConnector#onStateChanged(com.vaadin
  148. * .client.communication.StateChangeEvent)
  149. */
  150. @Override
  151. public void onStateChanged(StateChangeEvent stateChangeEvent) {
  152. super.onStateChanged(stateChangeEvent);
  153. clickEventHandler.handleEventHandlerRegistration();
  154. // TODO Margin handling
  155. for (ComponentConnector child : getChildComponents()) {
  156. setChildWidgetPosition(child);
  157. }
  158. }
  159. private void setChildWidgetPosition(ComponentConnector child) {
  160. String position = getState().connectorToCssPosition
  161. .get(child.getConnectorId());
  162. if (position == null) {
  163. position = "";
  164. }
  165. // make sure relative sizes get displayed correctly
  166. String width = child.getState().width;
  167. if (width != null && width.endsWith("%")) {
  168. position = addDefaultPositionIfMissing(position, "left");
  169. position = addDefaultPositionIfMissing(position, "right");
  170. }
  171. String height = child.getState().height;
  172. if (height != null && height.endsWith("%")) {
  173. position = addDefaultPositionIfMissing(position, "top");
  174. position = addDefaultPositionIfMissing(position, "bottom");
  175. }
  176. getWidget().setWidgetPosition(child.getWidget(), position);
  177. }
  178. /**
  179. * Adds default value of 0.0px for the given property if it's missing from
  180. * the position string altogether. If the property value is already set no
  181. * changes are needed.
  182. *
  183. * @param position
  184. * original position styles
  185. * @param property
  186. * the property that needs to have a value
  187. * @return updated position, or the original string if no updates were
  188. * needed
  189. */
  190. private String addDefaultPositionIfMissing(String position,
  191. String property) {
  192. if (!position.contains(property)) {
  193. position = position + property + ":0.0px;";
  194. }
  195. return position;
  196. }
  197. /*
  198. * (non-Javadoc)
  199. *
  200. * @see com.vaadin.client.ui.AbstractComponentContainerConnector#
  201. * onConnectorHierarchyChange
  202. * (com.vaadin.client.ConnectorHierarchyChangeEvent)
  203. */
  204. @Override
  205. public void onConnectorHierarchyChange(
  206. ConnectorHierarchyChangeEvent event) {
  207. for (ComponentConnector child : getChildComponents()) {
  208. if (!getWidget().contains(child.getWidget())) {
  209. getWidget().add(child.getWidget());
  210. child.addStateChangeHandler(childStateChangeHandler);
  211. setChildWidgetPosition(child);
  212. }
  213. }
  214. for (ComponentConnector oldChild : event.getOldChildren()) {
  215. if (oldChild.getParent() != this) {
  216. getWidget().remove(oldChild.getWidget());
  217. oldChild.removeStateChangeHandler(childStateChangeHandler);
  218. }
  219. }
  220. getWidget().cleanupWrappers();
  221. }
  222. /*
  223. * (non-Javadoc)
  224. *
  225. * @see com.vaadin.client.DirectionalManagedLayout#layoutVertically()
  226. */
  227. @Override
  228. public void layoutVertically() {
  229. getWidget().layoutVertically();
  230. for (ComponentConnector connector : getChildComponents()) {
  231. if (connector.isRelativeHeight()) {
  232. getLayoutManager().reportHeightAssignedToRelative(connector,
  233. getWidget().getWidgetSlotHeight(connector.getWidget()));
  234. }
  235. }
  236. }
  237. /*
  238. * (non-Javadoc)
  239. *
  240. * @see com.vaadin.client.DirectionalManagedLayout#layoutHorizontally()
  241. */
  242. @Override
  243. public void layoutHorizontally() {
  244. getWidget().layoutHorizontally();
  245. for (ComponentConnector connector : getChildComponents()) {
  246. if (connector.isRelativeWidth()) {
  247. getLayoutManager().reportWidthAssignedToRelative(connector,
  248. getWidget().getWidgetSlotWidth(connector.getWidget()));
  249. }
  250. }
  251. }
  252. }