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.

VAbsoluteLayout.java 7.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. /*
  2. @VaadinApache2LicenseForJavaFiles@
  3. */
  4. package com.vaadin.terminal.gwt.client.ui;
  5. import java.util.HashMap;
  6. import java.util.Map;
  7. import com.google.gwt.dom.client.DivElement;
  8. import com.google.gwt.dom.client.Document;
  9. import com.google.gwt.dom.client.Style;
  10. import com.google.gwt.user.client.DOM;
  11. import com.google.gwt.user.client.Element;
  12. import com.google.gwt.user.client.ui.ComplexPanel;
  13. import com.google.gwt.user.client.ui.SimplePanel;
  14. import com.google.gwt.user.client.ui.Widget;
  15. import com.vaadin.terminal.gwt.client.ApplicationConnection;
  16. import com.vaadin.terminal.gwt.client.ComponentConnector;
  17. import com.vaadin.terminal.gwt.client.ConnectorMap;
  18. import com.vaadin.terminal.gwt.client.UIDL;
  19. import com.vaadin.terminal.gwt.client.Util;
  20. import com.vaadin.terminal.gwt.client.VCaption;
  21. public class VAbsoluteLayout extends ComplexPanel {
  22. /** Tag name for widget creation */
  23. public static final String TAGNAME = "absolutelayout";
  24. /** Class name, prefix in styling */
  25. public static final String CLASSNAME = "v-absolutelayout";
  26. private DivElement marginElement;
  27. protected final Element canvas = DOM.createDiv();
  28. private Object previousStyleName;
  29. Map<String, AbsoluteWrapper> pidToComponentWrappper = new HashMap<String, AbsoluteWrapper>();
  30. protected ApplicationConnection client;
  31. public VAbsoluteLayout() {
  32. setElement(Document.get().createDivElement());
  33. setStyleName(CLASSNAME);
  34. marginElement = Document.get().createDivElement();
  35. canvas.getStyle().setProperty("position", "relative");
  36. canvas.getStyle().setProperty("overflow", "hidden");
  37. marginElement.appendChild(canvas);
  38. getElement().appendChild(marginElement);
  39. canvas.setClassName(CLASSNAME + "-canvas");
  40. canvas.setClassName(CLASSNAME + "-margin");
  41. }
  42. AbsoluteWrapper getWrapper(ApplicationConnection client, UIDL componentUIDL) {
  43. AbsoluteWrapper wrapper = pidToComponentWrappper.get(componentUIDL
  44. .getId());
  45. if (wrapper == null) {
  46. wrapper = new AbsoluteWrapper(client.getPaintable(componentUIDL));
  47. pidToComponentWrappper.put(componentUIDL.getId(), wrapper);
  48. add(wrapper);
  49. }
  50. return wrapper;
  51. }
  52. @Override
  53. public void add(Widget child) {
  54. super.add(child, canvas);
  55. }
  56. public class AbsoluteWrapper extends SimplePanel {
  57. private String css;
  58. String left;
  59. String top;
  60. String right;
  61. String bottom;
  62. private String zIndex;
  63. private ComponentConnector paintable;
  64. private VCaption caption;
  65. public AbsoluteWrapper(ComponentConnector paintable) {
  66. this.paintable = paintable;
  67. setStyleName(CLASSNAME + "-wrapper");
  68. }
  69. public void updateCaption() {
  70. boolean captionIsNeeded = VCaption.isNeeded(paintable.getState());
  71. if (captionIsNeeded) {
  72. if (caption == null) {
  73. caption = new VCaption(paintable, client);
  74. VAbsoluteLayout.this.add(caption);
  75. }
  76. caption.updateCaption();
  77. updateCaptionPosition();
  78. } else {
  79. if (caption != null) {
  80. caption.removeFromParent();
  81. caption = null;
  82. }
  83. }
  84. }
  85. @Override
  86. public void setWidget(Widget w) {
  87. // this fixes #5457 (Widget implementation can change on-the-fly)
  88. paintable = ConnectorMap.get(client).getConnector(w);
  89. super.setWidget(w);
  90. }
  91. public void destroy() {
  92. if (caption != null) {
  93. caption.removeFromParent();
  94. }
  95. client.unregisterPaintable(paintable);
  96. removeFromParent();
  97. }
  98. public void updateFromUIDL(UIDL componentUIDL) {
  99. setPosition(componentUIDL.getStringAttribute("css"));
  100. if (getWidget() != paintable.getWidget()) {
  101. setWidget(paintable.getWidget());
  102. }
  103. UIDL childUIDL = componentUIDL.getChildUIDL(0);
  104. paintable.updateFromUIDL(childUIDL, client);
  105. if (childUIDL.hasAttribute("cached")) {
  106. // child may need relative size adjustment if wrapper details
  107. // have changed this could be optimized (check if wrapper size
  108. // has changed)
  109. client.handleComponentRelativeSize(paintable.getWidget());
  110. }
  111. }
  112. public void setPosition(String stringAttribute) {
  113. if (css == null || !css.equals(stringAttribute)) {
  114. css = stringAttribute;
  115. top = right = bottom = left = zIndex = null;
  116. if (!css.equals("")) {
  117. String[] properties = css.split(";");
  118. for (int i = 0; i < properties.length; i++) {
  119. String[] keyValue = properties[i].split(":");
  120. if (keyValue[0].equals("left")) {
  121. left = keyValue[1];
  122. } else if (keyValue[0].equals("top")) {
  123. top = keyValue[1];
  124. } else if (keyValue[0].equals("right")) {
  125. right = keyValue[1];
  126. } else if (keyValue[0].equals("bottom")) {
  127. bottom = keyValue[1];
  128. } else if (keyValue[0].equals("z-index")) {
  129. zIndex = keyValue[1];
  130. }
  131. }
  132. }
  133. // ensure ne values
  134. Style style = getElement().getStyle();
  135. /*
  136. * IE8 dies when nulling zIndex, even in IE7 mode. All other css
  137. * properties (and even in older IE's) accept null values just
  138. * fine. Assign empty string instead of null.
  139. */
  140. if (zIndex != null) {
  141. style.setProperty("zIndex", zIndex);
  142. } else {
  143. style.setProperty("zIndex", "");
  144. }
  145. style.setProperty("top", top);
  146. style.setProperty("left", left);
  147. style.setProperty("right", right);
  148. style.setProperty("bottom", bottom);
  149. }
  150. updateCaptionPosition();
  151. }
  152. void updateCaptionPosition() {
  153. if (caption != null) {
  154. Style style = caption.getElement().getStyle();
  155. style.setProperty("position", "absolute");
  156. style.setPropertyPx("left", getElement().getOffsetLeft());
  157. style.setPropertyPx("top", getElement().getOffsetTop()
  158. - caption.getHeight());
  159. }
  160. }
  161. }
  162. /**
  163. * Returns the deepest nested child component which contains "element". The
  164. * child component is also returned if "element" is part of its caption.
  165. *
  166. * @param element
  167. * An element that is a nested sub element of the root element in
  168. * this layout
  169. * @return The Paintable which the element is a part of. Null if the element
  170. * belongs to the layout and not to a child.
  171. */
  172. ComponentConnector getComponent(Element element) {
  173. return Util.getConnectorForElement(client, this, element);
  174. }
  175. }