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.

IAbsoluteGrid.java 9.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310
  1. package com.itmill.toolkit.terminal.gwt.client.ui.absolutegrid;
  2. import java.util.HashMap;
  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.AbsolutePanel;
  7. import com.google.gwt.user.client.ui.Composite;
  8. import com.google.gwt.user.client.ui.SimplePanel;
  9. import com.google.gwt.user.client.ui.Widget;
  10. import com.itmill.toolkit.terminal.gwt.client.BrowserInfo;
  11. import com.itmill.toolkit.terminal.gwt.client.ICaption;
  12. import com.itmill.toolkit.terminal.gwt.client.ContainerResizedListener;
  13. import com.itmill.toolkit.terminal.gwt.client.Util;
  14. import com.itmill.toolkit.terminal.gwt.client.ui.AlignmentInfo;
  15. /**
  16. * Prototype helper widget to implement complex sized Toolkit layouts like
  17. * GridLayout and OrderedLayout. Supports size, margins, spacing, but has bit
  18. * expensive layout function.
  19. */
  20. public class IAbsoluteGrid extends Composite implements
  21. ContainerResizedListener {
  22. protected HashMap cells = new HashMap();
  23. private int cols = 1;
  24. private int rows = 1;
  25. private AbsolutePanel ap;
  26. protected int marginTop;
  27. protected int marginBottom;
  28. protected int marginLeft;
  29. protected int marginRight;
  30. private int offsetWidth;
  31. private int offsetHeight;
  32. public IAbsoluteGrid() {
  33. ap = new AbsolutePanel();
  34. initWidget(ap);
  35. }
  36. public IAbsoluteGridCell getCell(int col, int row) {
  37. IAbsoluteGridCell p = (IAbsoluteGridCell) cells.get(col + "." + row);
  38. if (p == null) {
  39. p = new IAbsoluteGridCell(col, row);
  40. cells.put(col + "." + row, p);
  41. ap.add(p);
  42. }
  43. return p;
  44. }
  45. public void clear() {
  46. ap.clear();
  47. cells.clear();
  48. }
  49. public Iterator getCellIterator() {
  50. return cells.values().iterator();
  51. }
  52. private float getCellWidth(int colspan) {
  53. int total = ap.getOffsetWidth();
  54. total -= getMarginWidth();
  55. total -= getSpacingSize() * (cols - colspan);
  56. if (total < 0) {
  57. return 0;
  58. }
  59. return total * colspan / (float) cols;
  60. }
  61. /**
  62. *
  63. * @return space used by left and right margin
  64. */
  65. private int getMarginWidth() {
  66. return marginLeft + marginRight;
  67. }
  68. /**
  69. * @return pixels reserved for space between components
  70. */
  71. protected int getSpacingSize() {
  72. return 0;
  73. }
  74. private float getCellHeight(int rowspan) {
  75. int total = ap.getOffsetHeight();
  76. total -= getMarginHeight();
  77. total -= getSpacingSize() * (rows - rowspan);
  78. if (total < 0) {
  79. return 0;
  80. }
  81. return total * rowspan / (float) rows;
  82. }
  83. /**
  84. *
  85. * @return space used by top and bottom margin
  86. */
  87. private int getMarginHeight() {
  88. return marginBottom + marginTop;
  89. }
  90. /**
  91. * TODO contains Caption (which is a widget) in a very bad way, cannot be
  92. * simple panel
  93. */
  94. public class IAbsoluteGridCell extends SimplePanel {
  95. int rowIndex;
  96. int colIndex;
  97. int colSpan = 1;
  98. int rowSpan = 1;
  99. private Element container = DOM.createDiv();
  100. private ICaption caption;
  101. private AlignmentInfo alignmentInfo = new AlignmentInfo(
  102. AlignmentInfo.ALIGNMENT_TOP + AlignmentInfo.ALIGNMENT_LEFT);
  103. IAbsoluteGridCell(int colIndex, int rowIndex) {
  104. super();
  105. if (BrowserInfo.get().isIE6()) {
  106. DOM.setStyleAttribute(getElement(), "overflow", "hidden");
  107. }
  108. DOM.appendChild(getElement(), container);
  109. this.rowIndex = rowIndex;
  110. this.colIndex = colIndex;
  111. }
  112. public void clear() {
  113. super.clear();
  114. if (caption != null) {
  115. DOM.removeChild(getElement(), caption.getElement());
  116. caption = null;
  117. }
  118. }
  119. protected Element getContainerElement() {
  120. return container;
  121. }
  122. void setColSpan(int s) {
  123. // TODO Should remove possibly collapsing cells
  124. colSpan = s;
  125. }
  126. void setRowSpan(int s) {
  127. // TODO Should remove possibly collapsing cells
  128. rowSpan = s;
  129. }
  130. private int getLeft() {
  131. int left = marginLeft;
  132. left += colIndex * getCellWidth(1);
  133. left += getSpacingSize() * colIndex;
  134. return left;
  135. }
  136. private int getTop() {
  137. int top = marginTop;
  138. top += rowIndex * getCellHeight(1);
  139. top += getSpacingSize() * rowIndex;
  140. return top;
  141. }
  142. public void render() {
  143. setPixelSize((int) getCellWidth(colSpan),
  144. (int) getCellHeight(rowSpan));
  145. ap.setWidgetPosition(this, getLeft(), getTop());
  146. }
  147. /**
  148. * Does vertical positioning based on DOM values
  149. */
  150. public void vAling() {
  151. DOM.setStyleAttribute(getElement(), "paddingTop", "0");
  152. if (!alignmentInfo.isTop()) {
  153. Widget c = getWidget();
  154. if (c != null) {
  155. int oh = getOffsetHeight();
  156. int wt = DOM.getElementPropertyInt(container, "offsetTop");
  157. int wh = c.getOffsetHeight();
  158. int freeSpace = getOffsetHeight()
  159. - (DOM
  160. .getElementPropertyInt(container,
  161. "offsetTop") + c.getOffsetHeight());
  162. if (Util.isIE()) {
  163. freeSpace -= DOM.getElementPropertyInt(c.getElement(),
  164. "offsetTop");
  165. }
  166. if (freeSpace < 0) {
  167. freeSpace = 0; // clipping rest of contents when object
  168. // larger than reserved area
  169. }
  170. if (alignmentInfo.isVerticalCenter()) {
  171. DOM.setStyleAttribute(getElement(), "paddingTop",
  172. (freeSpace / 2) + "px");
  173. } else {
  174. DOM.setStyleAttribute(getElement(), "paddingTop",
  175. (freeSpace) + "px");
  176. }
  177. }
  178. }
  179. }
  180. public void setPixelSize(int width, int height) {
  181. super.setPixelSize(width, height);
  182. DOM.setStyleAttribute(container, "width", width + "px");
  183. int contHeight = height - getCaptionHeight();
  184. if (contHeight < 0) {
  185. contHeight = 0;
  186. }
  187. DOM.setStyleAttribute(container, "height", contHeight + "px");
  188. }
  189. private int getCaptionHeight() {
  190. // remove hard coded caption height
  191. return (caption == null) ? 0 : caption.getOffsetHeight();
  192. }
  193. public ICaption getCaption() {
  194. return caption;
  195. }
  196. public void setCaption(ICaption newCaption) {
  197. // TODO check for existing, shouldn't happen though
  198. caption = newCaption;
  199. DOM.insertChild(getElement(), caption.getElement(), 0);
  200. }
  201. public void setAlignment(int bitmask) {
  202. if (alignmentInfo.getBitMask() != bitmask) {
  203. alignmentInfo = new AlignmentInfo(bitmask);
  204. setHorizontalAling();
  205. // vertical align is set in render() method
  206. }
  207. }
  208. private void setHorizontalAling() {
  209. DOM.setStyleAttribute(getElement(), "textAlign", alignmentInfo
  210. .getHorizontalAlignment());
  211. if (getWidget() != null) {
  212. Element el = getWidget().getElement();
  213. if (alignmentInfo.isHorizontalCenter()
  214. || alignmentInfo.isRight()) {
  215. DOM.setStyleAttribute(el, "marginLeft", "auto");
  216. } else {
  217. DOM.setStyleAttribute(el, "marginLeft", "");
  218. }
  219. if (alignmentInfo.isHorizontalCenter()
  220. || alignmentInfo.isLeft()) {
  221. DOM.setStyleAttribute(el, "marginRight", "auto");
  222. } else {
  223. DOM.setStyleAttribute(el, "marginRight", "");
  224. }
  225. }
  226. }
  227. }
  228. public void iLayout() {
  229. boolean sizeChanged = false;
  230. int newWidth = getOffsetWidth();
  231. if (offsetWidth != newWidth) {
  232. offsetWidth = newWidth;
  233. sizeChanged = true;
  234. }
  235. int newHeight = getOffsetHeight();
  236. if (offsetHeight != newHeight) {
  237. offsetHeight = newHeight;
  238. sizeChanged = true;
  239. }
  240. if (sizeChanged) {
  241. for (Iterator it = cells.values().iterator(); it.hasNext();) {
  242. IAbsoluteGridCell cell = (IAbsoluteGridCell) it.next();
  243. cell.render();
  244. cell.vAling();
  245. }
  246. Util.runDescendentsLayout(ap);
  247. }
  248. }
  249. public int getCols() {
  250. return cols;
  251. }
  252. public void setCols(int cols) {
  253. this.cols = cols;
  254. // force relayout
  255. offsetHeight = 0;
  256. offsetWidth = 0;
  257. }
  258. public int getRows() {
  259. return rows;
  260. }
  261. public void setRows(int rows) {
  262. this.rows = rows;
  263. // force relayout
  264. offsetHeight = 0;
  265. offsetWidth = 0;
  266. }
  267. }