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.

IExpandLayout.java 5.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. package com.itmill.toolkit.terminal.gwt.client.ui;
  2. import java.util.ArrayList;
  3. import java.util.Iterator;
  4. import com.google.gwt.user.client.DOM;
  5. import com.google.gwt.user.client.Element;
  6. import com.google.gwt.user.client.ui.Widget;
  7. import com.itmill.toolkit.terminal.gwt.client.ApplicationConnection;
  8. import com.itmill.toolkit.terminal.gwt.client.ContainerResizedListener;
  9. import com.itmill.toolkit.terminal.gwt.client.Paintable;
  10. import com.itmill.toolkit.terminal.gwt.client.UIDL;
  11. import com.itmill.toolkit.terminal.gwt.client.Util;
  12. /**
  13. * TODO make this work horizontally
  14. *
  15. * @author IT Mill Ltd
  16. */
  17. public class IExpandLayout extends IOrderedLayout implements
  18. ContainerResizedListener {
  19. public static final String CLASSNAME = "i-expandlayout";
  20. private Widget expandedWidget;
  21. private UIDL expandedWidgetUidl;
  22. public IExpandLayout() {
  23. super(IOrderedLayout.ORIENTATION_VERTICAL);
  24. setStyleName(CLASSNAME);
  25. }
  26. public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
  27. this.client = client;
  28. // Ensure correct implementation
  29. if (client.updateComponent(this, uidl, false))
  30. return;
  31. String h = uidl.getStringAttribute("height");
  32. setHeight(h);
  33. String w = uidl.getStringAttribute("width");
  34. setWidth(w);
  35. ArrayList uidlWidgets = new ArrayList();
  36. for (Iterator it = uidl.getChildIterator(); it.hasNext();) {
  37. UIDL cellUidl = (UIDL) it.next();
  38. Widget child = client.getWidget(cellUidl.getChildUIDL(0));
  39. uidlWidgets.add(child);
  40. if (cellUidl.hasAttribute("expanded")) {
  41. expandedWidget = child;
  42. expandedWidgetUidl = cellUidl.getChildUIDL(0);
  43. }
  44. }
  45. ArrayList oldWidgets = getPaintables();
  46. Iterator oldIt = oldWidgets.iterator();
  47. Iterator newIt = uidlWidgets.iterator();
  48. Iterator newUidl = uidl.getChildIterator();
  49. Widget oldChild = null;
  50. while (newIt.hasNext()) {
  51. Widget child = (Widget) newIt.next();
  52. UIDL childUidl = ((UIDL) newUidl.next()).getChildUIDL(0);
  53. if (oldChild == null && oldIt.hasNext()) {
  54. // search for next old Paintable which still exists in layout
  55. // and delete others
  56. while (oldIt.hasNext()) {
  57. oldChild = (Widget) oldIt.next();
  58. // now oldChild is an instance of Paintable
  59. if (uidlWidgets.contains(oldChild))
  60. break;
  61. else {
  62. removePaintable((Paintable) oldChild);
  63. oldChild = null;
  64. }
  65. }
  66. }
  67. if (oldChild == null) {
  68. // we are adding components to layout
  69. add(child);
  70. } else if (child == oldChild) {
  71. // child already attached and updated
  72. oldChild = null;
  73. } else if (hasChildComponent(child)) {
  74. // current child has been moved, re-insert before current
  75. // oldChild
  76. // TODO this might be optimized by moving only container element
  77. // to correct position
  78. removeCaption(child);
  79. int index = getWidgetIndex(oldChild);
  80. if (componentToCaption.containsKey(oldChild))
  81. index--;
  82. remove(child);
  83. this.insert(child, index);
  84. } else {
  85. // insert new child before old one
  86. int index = getWidgetIndex(oldChild);
  87. insert(child, index);
  88. }
  89. if (child != expandedWidget)
  90. ((Paintable) child).updateFromUIDL(childUidl, client);
  91. }
  92. // remove possibly remaining old Paintable object which were not updated
  93. while (oldIt.hasNext()) {
  94. oldChild = (Widget) oldIt.next();
  95. Paintable p = (Paintable) oldChild;
  96. if (!uidlWidgets.contains(p))
  97. removePaintable(p);
  98. }
  99. if (uidlWidgets.size() == 0)
  100. return;
  101. iLayout();
  102. /*
  103. * Expanded widget is updated after layout function so it has its
  104. * container fixed at the moment of updateFromUIDL.
  105. */
  106. ((Paintable) expandedWidget).updateFromUIDL(expandedWidgetUidl, client);
  107. }
  108. public void iLayout() {
  109. if (expandedWidget == null) {
  110. return;
  111. }
  112. // ApplicationConnection.getConsole().log("EL layouting...");
  113. Element expandedElement = DOM.getParent(expandedWidget.getElement());
  114. // take expanded element temporarely out of flow to make container
  115. // minimum sized
  116. String origiginalPositioning = DOM.getStyleAttribute(expandedWidget
  117. .getElement(), "position");
  118. DOM.setStyleAttribute(expandedWidget.getElement(), "position",
  119. "absolute");
  120. DOM.setStyleAttribute(expandedElement, "height", "");
  121. // add temp element to make some measurements
  122. Element meter = createWidgetWrappper();
  123. DOM.setStyleAttribute(meter, "overflow", "hidden");
  124. DOM.setStyleAttribute(meter, "height", "0");
  125. DOM.appendChild(childContainer, meter);
  126. int usedSpace = DOM.getElementPropertyInt(meter, "offsetTop")
  127. - DOM.getElementPropertyInt(DOM.getFirstChild(childContainer),
  128. "offsetTop");
  129. // ApplicationConnection.getConsole().log("EL h" + getOffsetHeight());
  130. // ApplicationConnection.getConsole().log("EL h" + getOffsetHeight());
  131. int freeSpace = getOffsetHeight() - usedSpace;
  132. DOM.setStyleAttribute(expandedElement, "height", freeSpace + "px");
  133. // Component margins will bleed if overflow is not hidden
  134. DOM.setStyleAttribute(expandedElement, "overflow", "hidden");
  135. DOM.setStyleAttribute(expandedWidget.getElement(), "position",
  136. origiginalPositioning);
  137. DOM.removeChild(childContainer, meter);
  138. // TODO save previous size and only propagate if really changed
  139. Util.runAnchestorsLayout(this);
  140. }
  141. }