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.

ISplitPanel.java 8.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310
  1. package com.itmill.toolkit.terminal.gwt.client.ui;
  2. import com.google.gwt.user.client.DOM;
  3. import com.google.gwt.user.client.Element;
  4. import com.google.gwt.user.client.Event;
  5. import com.google.gwt.user.client.ui.ComplexPanel;
  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. public class ISplitPanel extends ComplexPanel implements Paintable,
  13. ContainerResizedListener {
  14. public static final String CLASSNAME = "i-splitpanel";
  15. public static final int ORIENTATION_HORIZONTAL = 0;
  16. public static final int ORIENTATION_VERTICAL = 1;
  17. private static final int SPLITTER_SIZE = 10;
  18. private static final String MIN_SIZE = (3 * SPLITTER_SIZE) + "px";
  19. private int orientation;
  20. private Widget firstChild;
  21. private Widget secondChild;
  22. private Element wrapper = DOM.createDiv();
  23. private Element firstContainer = DOM.createDiv();
  24. private Element secondContainer = DOM.createDiv();
  25. private Element splitter = DOM.createDiv();
  26. private boolean resizing;
  27. private int origX;
  28. private int origY;
  29. private int origMouseX;
  30. private int origMouseY;
  31. public ISplitPanel() {
  32. this(ORIENTATION_HORIZONTAL);
  33. }
  34. public ISplitPanel(int orientation) {
  35. setElement(DOM.createDiv());
  36. switch (orientation) {
  37. case ORIENTATION_HORIZONTAL:
  38. setStyleName(CLASSNAME + "-horizontal");
  39. break;
  40. case ORIENTATION_VERTICAL:
  41. default:
  42. setStyleName(CLASSNAME + "-vertical");
  43. break;
  44. }
  45. // size below will be overridden in update from uidl, initial size
  46. // needed to keep IE alive
  47. setWidth(MIN_SIZE);
  48. setHeight(MIN_SIZE);
  49. constructDom();
  50. setOrientation(orientation);
  51. setSplitPosition("50%");
  52. DOM.sinkEvents(splitter, (Event.MOUSEEVENTS));
  53. DOM.sinkEvents(getElement(), (Event.MOUSEEVENTS));
  54. }
  55. protected void constructDom() {
  56. DOM.appendChild(getElement(), wrapper);
  57. DOM.setStyleAttribute(wrapper, "position", "relative");
  58. DOM.setStyleAttribute(wrapper, "width", "100%");
  59. DOM.setStyleAttribute(wrapper, "height", "100%");
  60. DOM.appendChild(wrapper, splitter);
  61. DOM.appendChild(wrapper, secondContainer);
  62. DOM.appendChild(wrapper, firstContainer);
  63. DOM.setStyleAttribute(splitter, "position", "absolute");
  64. DOM.setStyleAttribute(secondContainer, "position", "absolute");
  65. DOM.setElementProperty(splitter, "className", "splitter");
  66. DOM.setStyleAttribute(firstContainer, "overflow", "hidden");
  67. DOM.setStyleAttribute(secondContainer, "overflow", "hidden");
  68. }
  69. private void setOrientation(int orientation) {
  70. this.orientation = orientation;
  71. if (orientation == ORIENTATION_HORIZONTAL) {
  72. DOM.setStyleAttribute(splitter, "height", "100%");
  73. DOM.setStyleAttribute(splitter, "width", SPLITTER_SIZE + "px");
  74. DOM.setStyleAttribute(firstContainer, "height", "100%");
  75. DOM.setStyleAttribute(secondContainer, "height", "100%");
  76. } else {
  77. DOM.setStyleAttribute(splitter, "width", "100%");
  78. DOM.setStyleAttribute(splitter, "height", SPLITTER_SIZE + "px");
  79. DOM.setStyleAttribute(firstContainer, "width", "100%");
  80. DOM.setStyleAttribute(secondContainer, "width", "100%");
  81. }
  82. }
  83. public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
  84. client.updateComponent(this, uidl, true);
  85. setWidth(uidl.getStringAttribute("width"));
  86. setHeight(uidl.getStringAttribute("height"));
  87. setSplitPosition(uidl.getStringAttribute("position"));
  88. Paintable newFirstChild = (Paintable) client.getWidget(uidl
  89. .getChildUIDL(0));
  90. Paintable newSecondChild = (Paintable) client.getWidget(uidl
  91. .getChildUIDL(1));
  92. if (firstChild != newFirstChild) {
  93. if (firstChild != null)
  94. client.unregisterPaintable((Paintable) firstChild);
  95. setFirstWidget((Widget) newFirstChild);
  96. }
  97. if (secondChild != newSecondChild) {
  98. if (secondChild != null)
  99. client.unregisterPaintable((Paintable) secondChild);
  100. setSecondWidget((Widget) newSecondChild);
  101. }
  102. newFirstChild.updateFromUIDL(uidl.getChildUIDL(0), client);
  103. newSecondChild.updateFromUIDL(uidl.getChildUIDL(1), client);
  104. }
  105. private void setSplitPosition(String pos) {
  106. if (orientation == ORIENTATION_HORIZONTAL) {
  107. DOM.setStyleAttribute(splitter, "left", pos);
  108. } else {
  109. DOM.setStyleAttribute(splitter, "top", pos);
  110. }
  111. iLayout();
  112. }
  113. /*
  114. * Calculates absolutely positioned container places/sizes (non-Javadoc)
  115. *
  116. * @see com.itmill.toolkit.terminal.gwt.client.NeedsLayout#layout()
  117. */
  118. public void iLayout() {
  119. if (!isAttached()) {
  120. return;
  121. }
  122. int wholeSize;
  123. int pixelPosition;
  124. ApplicationConnection.getConsole().log("splitterpaneeeli");
  125. switch (orientation) {
  126. case ORIENTATION_HORIZONTAL:
  127. wholeSize = DOM.getElementPropertyInt(wrapper, "clientWidth");
  128. pixelPosition = DOM.getElementPropertyInt(splitter, "offsetLeft");
  129. // reposition splitter in case it is out of box
  130. if (pixelPosition + SPLITTER_SIZE > wholeSize) {
  131. pixelPosition = wholeSize - SPLITTER_SIZE;
  132. setSplitPosition(pixelPosition + "px");
  133. return;
  134. }
  135. DOM
  136. .setStyleAttribute(firstContainer, "width", pixelPosition
  137. + "px");
  138. int secondContainerWidth = (wholeSize - pixelPosition - SPLITTER_SIZE);
  139. if (secondContainerWidth < 0)
  140. secondContainerWidth = 0;
  141. DOM.setStyleAttribute(secondContainer, "width",
  142. secondContainerWidth + "px");
  143. DOM.setStyleAttribute(secondContainer, "left",
  144. (pixelPosition + SPLITTER_SIZE) + "px");
  145. break;
  146. case ORIENTATION_VERTICAL:
  147. wholeSize = DOM.getElementPropertyInt(wrapper, "clientHeight");
  148. pixelPosition = DOM.getElementPropertyInt(splitter, "offsetTop");
  149. // reposition splitter in case it is out of box
  150. if (pixelPosition + SPLITTER_SIZE > wholeSize) {
  151. pixelPosition = wholeSize - SPLITTER_SIZE;
  152. setSplitPosition(pixelPosition + "px");
  153. return;
  154. }
  155. DOM.setStyleAttribute(firstContainer, "height", pixelPosition
  156. + "px");
  157. int secondContainerHeight = (wholeSize - pixelPosition - SPLITTER_SIZE);
  158. if (secondContainerHeight < 0)
  159. secondContainerHeight = 0;
  160. DOM.setStyleAttribute(secondContainer, "height",
  161. secondContainerHeight + "px");
  162. DOM.setStyleAttribute(secondContainer, "top",
  163. (pixelPosition + SPLITTER_SIZE) + "px");
  164. default:
  165. ApplicationConnection.getConsole().log("???");
  166. break;
  167. }
  168. Util.runAnchestorsLayout(this);
  169. }
  170. private void setFirstWidget(Widget w) {
  171. if (firstChild != null) {
  172. firstChild.removeFromParent();
  173. }
  174. super.add(w, firstContainer);
  175. firstChild = w;
  176. }
  177. private void setSecondWidget(Widget w) {
  178. if (secondChild != null) {
  179. secondChild.removeFromParent();
  180. }
  181. super.add(w, secondContainer);
  182. secondChild = w;
  183. }
  184. public void setHeight(String height) {
  185. super.setHeight(height);
  186. // give sane height
  187. getOffsetHeight(); // shake IE
  188. if (getOffsetHeight() < SPLITTER_SIZE)
  189. super.setHeight((SPLITTER_SIZE * 3) + "px");
  190. }
  191. public void setWidth(String width) {
  192. super.setWidth(width);
  193. // give sane width
  194. getOffsetWidth(); // shake IE
  195. if (getOffsetWidth() < SPLITTER_SIZE)
  196. super.setWidth((SPLITTER_SIZE * 3) + "px");
  197. }
  198. public void onBrowserEvent(Event event) {
  199. switch (DOM.eventGetType(event)) {
  200. case Event.ONMOUSEMOVE:
  201. if (resizing) {
  202. onMouseMove(event);
  203. }
  204. break;
  205. case Event.ONMOUSEDOWN:
  206. onMouseDown(event);
  207. break;
  208. case Event.ONMOUSEUP:
  209. if (resizing)
  210. onMouseUp(event);
  211. break;
  212. case Event.ONCLICK:
  213. resizing = false;
  214. break;
  215. }
  216. }
  217. public void onMouseDown(Event event) {
  218. if (DOM.compare(DOM.eventGetTarget(event), splitter)) {
  219. resizing = true;
  220. DOM.setCapture(getElement());
  221. origX = DOM.getElementPropertyInt(splitter, "offsetLeft");
  222. origY = DOM.getElementPropertyInt(splitter, "offsetTop");
  223. origMouseX = DOM.eventGetClientX(event);
  224. origMouseY = DOM.eventGetClientY(event);
  225. DOM.eventCancelBubble(event, true);
  226. DOM.eventPreventDefault(event);
  227. }
  228. }
  229. public void onMouseMove(Event event) {
  230. switch (orientation) {
  231. case ORIENTATION_HORIZONTAL:
  232. int x = DOM.eventGetClientX(event);
  233. onHorizontalMouseMove(x);
  234. break;
  235. case ORIENTATION_VERTICAL:
  236. default:
  237. int y = DOM.eventGetClientY(event);
  238. onVerticalMouseMove(y);
  239. break;
  240. }
  241. iLayout();
  242. }
  243. private void onHorizontalMouseMove(int x) {
  244. int newX = origX + x - origMouseX;
  245. if (newX < 0)
  246. newX = 0;
  247. if (newX + SPLITTER_SIZE > getOffsetWidth())
  248. newX = getOffsetWidth() - SPLITTER_SIZE;
  249. DOM.setStyleAttribute(splitter, "left", newX + "px");
  250. }
  251. private void onVerticalMouseMove(int y) {
  252. int newY = origY + y - origMouseY;
  253. if (newY < 0)
  254. newY = 0;
  255. if (newY + SPLITTER_SIZE > getOffsetHeight())
  256. newY = getOffsetHeight() - SPLITTER_SIZE;
  257. DOM.setStyleAttribute(splitter, "top", newY + "px");
  258. }
  259. public void onMouseUp(Event event) {
  260. DOM.releaseCapture(getElement());
  261. resizing = false;
  262. onMouseMove(event);
  263. }
  264. }