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.

AbstractOrderedLayoutConnector.java 9.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281
  1. /*
  2. @VaadinApache2LicenseForJavaFiles@
  3. */
  4. package com.vaadin.terminal.gwt.client.ui;
  5. import java.util.List;
  6. import com.google.gwt.dom.client.Style;
  7. import com.google.gwt.event.dom.client.DomEvent.Type;
  8. import com.google.gwt.event.shared.EventHandler;
  9. import com.google.gwt.event.shared.HandlerRegistration;
  10. import com.google.gwt.user.client.Element;
  11. import com.google.gwt.user.client.ui.Widget;
  12. import com.vaadin.terminal.gwt.client.ApplicationConnection;
  13. import com.vaadin.terminal.gwt.client.ComponentConnector;
  14. import com.vaadin.terminal.gwt.client.DirectionalManagedLayout;
  15. import com.vaadin.terminal.gwt.client.EventId;
  16. import com.vaadin.terminal.gwt.client.LayoutManager;
  17. import com.vaadin.terminal.gwt.client.UIDL;
  18. import com.vaadin.terminal.gwt.client.Util;
  19. import com.vaadin.terminal.gwt.client.VCaption;
  20. import com.vaadin.terminal.gwt.client.ValueMap;
  21. import com.vaadin.terminal.gwt.client.ui.layout.ComponentConnectorLayoutSlot;
  22. import com.vaadin.terminal.gwt.client.ui.layout.VLayoutSlot;
  23. public abstract class AbstractOrderedLayoutConnector extends
  24. AbstractComponentContainerConnector implements DirectionalManagedLayout {
  25. private LayoutClickEventHandler clickEventHandler = new LayoutClickEventHandler(
  26. this, EventId.LAYOUT_CLICK) {
  27. @Override
  28. protected ComponentConnector getChildComponent(Element element) {
  29. return Util.getConnectorForElement(getConnection(), getWidget(),
  30. element);
  31. }
  32. @Override
  33. protected <H extends EventHandler> HandlerRegistration registerHandler(
  34. H handler, Type<H> type) {
  35. return getWidget().addDomHandler(handler, type);
  36. }
  37. };
  38. @Override
  39. public void init() {
  40. getLayoutManager().registerDependency(this,
  41. getWidget().spacingMeasureElement);
  42. }
  43. public void updateCaption(ComponentConnector component) {
  44. VMeasuringOrderedLayout layout = getWidget();
  45. if (VCaption.isNeeded(component.getState())) {
  46. VLayoutSlot layoutSlot = layout.getSlotForChild(component
  47. .getWidget());
  48. VCaption caption = layoutSlot.getCaption();
  49. if (caption == null) {
  50. caption = new VCaption(component, getConnection());
  51. Widget widget = component.getWidget();
  52. layout.setCaption(widget, caption);
  53. }
  54. caption.updateCaption();
  55. } else {
  56. layout.setCaption(component.getWidget(), null);
  57. getLayoutManager().setNeedsUpdate(this);
  58. }
  59. }
  60. @Override
  61. public VMeasuringOrderedLayout getWidget() {
  62. return (VMeasuringOrderedLayout) super.getWidget();
  63. }
  64. @Override
  65. public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
  66. super.updateFromUIDL(uidl, client);
  67. if (!isRealUpdate(uidl)) {
  68. return;
  69. }
  70. clickEventHandler.handleEventHandlerRegistration();
  71. VMeasuringOrderedLayout layout = getWidget();
  72. ValueMap expandRatios = uidl.getMapAttribute("expandRatios");
  73. ValueMap alignments = uidl.getMapAttribute("alignments");
  74. for (ComponentConnector child : getChildren()) {
  75. VLayoutSlot slot = layout.getSlotForChild(child.getWidget());
  76. String pid = child.getConnectorId();
  77. AlignmentInfo alignment;
  78. if (alignments.containsKey(pid)) {
  79. alignment = new AlignmentInfo(alignments.getInt(pid));
  80. } else {
  81. alignment = AlignmentInfo.TOP_LEFT;
  82. }
  83. slot.setAlignment(alignment);
  84. double expandRatio;
  85. if (expandRatios.containsKey(pid)) {
  86. expandRatio = expandRatios.getRawNumber(pid);
  87. } else {
  88. expandRatio = 0;
  89. }
  90. slot.setExpandRatio(expandRatio);
  91. }
  92. int bitMask = uidl.getIntAttribute("margins");
  93. layout.updateMarginStyleNames(new VMarginInfo(bitMask));
  94. layout.updateSpacingStyleName(uidl.getBooleanAttribute("spacing"));
  95. getLayoutManager().setNeedsUpdate(this);
  96. }
  97. private int getSizeForInnerSize(int size, boolean isVertical) {
  98. LayoutManager layoutManager = getLayoutManager();
  99. Element element = getWidget().getElement();
  100. if (isVertical) {
  101. return size + layoutManager.getBorderHeight(element)
  102. + layoutManager.getPaddingHeight(element);
  103. } else {
  104. return size + layoutManager.getBorderWidth(element)
  105. + layoutManager.getPaddingWidth(element);
  106. }
  107. }
  108. private static String getSizeProperty(boolean isVertical) {
  109. return isVertical ? "height" : "width";
  110. }
  111. private boolean isUndefinedInDirection(boolean isVertical) {
  112. if (isVertical) {
  113. return isUndefinedHeight();
  114. } else {
  115. return isUndefinedWidth();
  116. }
  117. }
  118. private int getInnerSizeInDirection(boolean isVertical) {
  119. if (isVertical) {
  120. return getLayoutManager().getInnerHeight(getWidget().getElement());
  121. } else {
  122. return getLayoutManager().getInnerWidth(getWidget().getElement());
  123. }
  124. }
  125. private void layoutPrimaryDirection() {
  126. VMeasuringOrderedLayout layout = getWidget();
  127. boolean isVertical = layout.isVertical;
  128. boolean isUndefined = isUndefinedInDirection(isVertical);
  129. int startPadding = getStartPadding(isVertical);
  130. int spacingSize = getSpacingInDirection(isVertical);
  131. int allocatedSize;
  132. if (isUndefined) {
  133. allocatedSize = -1;
  134. } else {
  135. allocatedSize = getInnerSizeInDirection(isVertical);
  136. }
  137. allocatedSize = layout.layoutPrimaryDirection(spacingSize,
  138. allocatedSize, startPadding);
  139. Style ownStyle = getWidget().getElement().getStyle();
  140. if (isUndefined) {
  141. ownStyle.setPropertyPx(getSizeProperty(isVertical),
  142. getSizeForInnerSize(allocatedSize, isVertical));
  143. } else {
  144. ownStyle.setProperty(getSizeProperty(isVertical),
  145. getDefinedSize(isVertical));
  146. }
  147. }
  148. private int getSpacingInDirection(boolean isVertical) {
  149. if (isVertical) {
  150. return getLayoutManager().getOuterHeight(
  151. getWidget().spacingMeasureElement);
  152. } else {
  153. return getLayoutManager().getOuterWidth(
  154. getWidget().spacingMeasureElement);
  155. }
  156. }
  157. private void layoutSecondaryDirection() {
  158. VMeasuringOrderedLayout layout = getWidget();
  159. boolean isVertical = layout.isVertical;
  160. boolean isUndefined = isUndefinedInDirection(!isVertical);
  161. int startPadding = getStartPadding(!isVertical);
  162. int allocatedSize;
  163. if (isUndefined) {
  164. allocatedSize = -1;
  165. } else {
  166. allocatedSize = getInnerSizeInDirection(!isVertical);
  167. }
  168. allocatedSize = layout.layoutSecondaryDirection(allocatedSize,
  169. startPadding);
  170. Style ownStyle = getWidget().getElement().getStyle();
  171. if (isUndefined) {
  172. ownStyle.setPropertyPx(getSizeProperty(!getWidget().isVertical),
  173. getSizeForInnerSize(allocatedSize, !getWidget().isVertical));
  174. } else {
  175. ownStyle.setProperty(getSizeProperty(!getWidget().isVertical),
  176. getDefinedSize(!getWidget().isVertical));
  177. }
  178. }
  179. private String getDefinedSize(boolean isVertical) {
  180. if (isVertical) {
  181. return getState().getHeight();
  182. } else {
  183. return getState().getWidth();
  184. }
  185. }
  186. private int getStartPadding(boolean isVertical) {
  187. if (isVertical) {
  188. return getLayoutManager().getPaddingTop(getWidget().getElement());
  189. } else {
  190. return getLayoutManager().getPaddingLeft(getWidget().getElement());
  191. }
  192. }
  193. public void layoutHorizontally() {
  194. if (getWidget().isVertical) {
  195. layoutSecondaryDirection();
  196. } else {
  197. layoutPrimaryDirection();
  198. }
  199. }
  200. public void layoutVertically() {
  201. if (getWidget().isVertical) {
  202. layoutPrimaryDirection();
  203. } else {
  204. layoutSecondaryDirection();
  205. }
  206. }
  207. @Override
  208. public void connectorHierarchyChanged(
  209. com.vaadin.terminal.gwt.client.ConnectorHierarchyChangedEvent event) {
  210. super.connectorHierarchyChanged(event);
  211. List<ComponentConnector> previousChildren = event.getOldChildren();
  212. int currentIndex = 0;
  213. VMeasuringOrderedLayout layout = getWidget();
  214. for (ComponentConnector child : getChildren()) {
  215. Widget childWidget = child.getWidget();
  216. VLayoutSlot slot = layout.getSlotForChild(childWidget);
  217. if (childWidget.getParent() != layout) {
  218. // If the child widget was previously attached to another
  219. // AbstractOrderedLayout a slot might be found that belongs to
  220. // another AbstractOrderedLayout. In this case we discard it and
  221. // create a new slot.
  222. slot = new ComponentConnectorLayoutSlot(getWidget()
  223. .getStylePrimaryName(), child, this);
  224. }
  225. layout.addOrMove(slot, currentIndex++);
  226. }
  227. for (ComponentConnector child : previousChildren) {
  228. if (child.getParent() != this) {
  229. // Remove slot if the connector is no longer a child of this
  230. // layout
  231. layout.removeSlotForWidget(child.getWidget());
  232. }
  233. }
  234. };
  235. }