guiGridCtrl.cc 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330
  1. #include "gui/containers/guiGridCtrl.h"
  2. //------------------------------------------------------------------------------
  3. IMPLEMENT_CONOBJECT(GuiGridControl);
  4. //------------------------------------------------------------------------------
  5. GuiGridControl::GuiGridControl()
  6. {
  7. mIsContainer = true;
  8. }
  9. //------------------------------------------------------------------------------
  10. void GuiGridControl::initPersistFields()
  11. {
  12. Parent::initPersistFields();
  13. addField("Rows", TypeStringTableEntryVector, Offset(mGridRows, GuiGridControl), "Number of rows in the grid");
  14. addField("Columns", TypeStringTableEntryVector, Offset(mGridCols, GuiGridControl), "Number of columns in the grid");
  15. }
  16. //------------------------------------------------------------------------------
  17. bool GuiGridControl::onWake()
  18. {
  19. if (!Parent::onWake())
  20. return false;
  21. return true;
  22. }
  23. //------------------------------------------------------------------------------
  24. void GuiGridControl::onSleep()
  25. {
  26. Parent::onSleep();
  27. }
  28. //------------------------------------------------------------------------------
  29. void GuiGridControl::inspectPostApply()
  30. {
  31. resize(getPosition(), getExtent());
  32. }
  33. //------------------------------------------------------------------------------
  34. bool GuiGridControl::IsPointInGridControl(GuiControl* ctrl, const Point2I& pt)
  35. {
  36. if (mRowSizes.size() > 0 && mColSizes.size() > 0)
  37. {
  38. RectI gridRect = GetGridRect(ctrl);
  39. RectI ctrlRect = ctrl->getBounds();
  40. Point2I chkPt = gridRect.point + ctrlRect.point;
  41. Point2I chkBound = chkPt + ctrlRect.extent;
  42. if (pt.x >= chkPt.x && pt.x <= chkBound.x && pt.y >= chkPt.y && pt.y <= chkBound.y)
  43. return true;
  44. else
  45. return false;
  46. }
  47. else
  48. {
  49. return false;
  50. }
  51. }
  52. //------------------------------------------------------------------------------
  53. void GuiGridControl::addObject(SimObject *obj)
  54. {
  55. if (mRowSizes.size() <= 0 && mRowSizes.size() <= 0)
  56. AdjustGrid(mBounds.extent);
  57. GuiControl *ctrl = static_cast<GuiControl *>(obj);
  58. if (ctrl)
  59. {
  60. RectI ctrlRect = GetGridRect(ctrl);
  61. if (ctrl->getExtent().isZero())
  62. {
  63. ctrl->setExtent(ctrlRect.extent);
  64. }
  65. else
  66. {
  67. if (ctrl->mBounds.extent.x > ctrlRect.extent.x)
  68. ctrl->mBounds.extent.x = ctrlRect.extent.x;
  69. if (ctrl->mBounds.extent.y > ctrlRect.extent.y)
  70. ctrl->mBounds.extent.y = ctrlRect.extent.y;
  71. }
  72. Point2I pt = ctrl->getPosition();
  73. mOrginalControlPos.push_back(pt);
  74. pt += ctrlRect.point;
  75. ctrl->setPosition(pt);
  76. }
  77. Parent::addObject(obj);
  78. }
  79. //------------------------------------------------------------------------------
  80. void GuiGridControl::removeObject(SimObject *obj)
  81. {
  82. for(int idx =0; idx < objectList.size();idx++)
  83. {
  84. if ( objectList[idx] == obj )
  85. {
  86. mOrginalControlPos.erase(idx);
  87. break;
  88. }
  89. }
  90. Parent::removeObject(obj);
  91. }
  92. //------------------------------------------------------------------------------
  93. void GuiGridControl::resize(const Point2I &newPosition, const Point2I &newExtent)
  94. {
  95. setUpdate();
  96. Point2I actualNewExtent = Point2I( getMax(mMinExtent.x, newExtent.x), getMax(mMinExtent.y, newExtent.y));
  97. mBounds.set(newPosition, actualNewExtent);
  98. bool bFirstResize = false;
  99. iterator i;
  100. Vector<Point2I> oldCtrlExtent;
  101. if (mRowSizes.size() == 0 && mColSizes.size() == 0)
  102. {
  103. bFirstResize = true;
  104. }
  105. else
  106. {
  107. for(i = begin(); i != end(); i++)
  108. {
  109. GuiControl *ctrl = static_cast<GuiControl *>(*i);
  110. if (ctrl)
  111. {
  112. RectI newRect = GetGridRect(ctrl);
  113. oldCtrlExtent.push_back(newRect.extent);
  114. }
  115. }
  116. }
  117. AdjustGrid(mBounds.extent);
  118. //resize and position all child controls.
  119. int idx = 0;
  120. for(i = begin(); i != end(); i++)
  121. {
  122. GuiControl *ctrl = static_cast<GuiControl *>(*i);
  123. if (ctrl)
  124. {
  125. RectI newRect = GetGridRect(ctrl);
  126. if (ctrl->getExtent().x == 0 && ctrl->getExtent().y == 0)
  127. ctrl->setExtent(newRect.extent);
  128. ctrl->setPosition(mOrginalControlPos[idx] + newRect.point);
  129. if (bFirstResize)
  130. {
  131. ctrl->parentResized(newRect.extent, newRect.extent);
  132. }
  133. else
  134. {
  135. ctrl->parentResized(oldCtrlExtent[idx++], newRect.extent);
  136. }
  137. }
  138. }
  139. GuiControl *parent = getParent();
  140. if (parent)
  141. parent->childResized(this);
  142. setUpdate();
  143. }
  144. //------------------------------------------------------------------------------
  145. RectI GuiGridControl::GetGridRect(GuiControl* ctrl)
  146. {
  147. S32 col = dAtoi(ctrl->getDataField( StringTable->insert("Col"), NULL));
  148. S32 row = dAtoi(ctrl->getDataField( StringTable->insert("Row"), NULL));
  149. S32 colSpan = dAtoi(ctrl->getDataField( StringTable->insert("ColSpan"), NULL));
  150. S32 rowSpan = dAtoi(ctrl->getDataField( StringTable->insert("RowSpan"), NULL));
  151. AssertFatal (col < mColSizes.size(), "Col is out of bounds");
  152. AssertFatal (row < mRowSizes.size(), "Row is out of bounds");
  153. if (colSpan < 1)
  154. colSpan = 1;
  155. if (rowSpan < 1)
  156. rowSpan = 1;
  157. RectI newRect(0,0,0,0);
  158. for(int i = 0; i < col; i++)
  159. {
  160. newRect.point.x += mColSizes[i];
  161. }
  162. for(int i =col; i < col+colSpan; i++)
  163. {
  164. newRect.extent.x += mColSizes[i];
  165. }
  166. for(int i = 0; i < row; i++)
  167. {
  168. newRect.point.y += mRowSizes[i];
  169. }
  170. for(int i =row; i < row+rowSpan; i++)
  171. {
  172. newRect.extent.y += mRowSizes[i];
  173. }
  174. return newRect;
  175. }
  176. //------------------------------------------------------------------------------
  177. void GuiGridControl::AdjustGrid(const Point2I& newExtent)
  178. {
  179. mColSizes.clear();
  180. mRowSizes.clear();
  181. AdjustGridItems(newExtent.x, mGridCols, mColSizes);
  182. AdjustGridItems(newExtent.y, mGridRows, mRowSizes);
  183. }
  184. //------------------------------------------------------------------------------
  185. void GuiGridControl::AdjustGridItems(S32 size, Vector<StringTableEntry>& strItems, Vector<S32>& items)
  186. {
  187. Vector<GridItem> GridItems;
  188. S32 bFoundStar = false;
  189. S32 IndexRemaining = -1;
  190. S32 totalSize = 0;
  191. S32 idx =0;
  192. //First step : Convert the string based column data into a GridItem vector.
  193. for(Vector<char const*>::iterator col = strItems.begin(); col != strItems.end(); ++col, idx++)
  194. {
  195. StringTableEntry str = *col;
  196. int len = dStrlen(str);
  197. AssertFatal(len >= 1, "Item can not be blank.");
  198. //we support three types of values (absolute size in pixels, percentage based, and remaining size in pixels).
  199. if (str[0] == '*') // use the remaining space left in the columns.
  200. {
  201. AssertFatal(!bFoundStar, "Can only use one * item field");
  202. GridItem gi;
  203. gi.IsAbsolute = false;
  204. gi.IsPercentage = false;
  205. gi.IsRemaining = true;
  206. gi.Size = 0;
  207. GridItems.push_back(gi);
  208. }
  209. else if ( len > 1 && str[len-1] == '%' ) //percentage based
  210. {
  211. char* tmp = new char[len-1];
  212. dStrncpy(tmp, str, len-1);
  213. int perc = dAtoi(tmp);
  214. delete tmp;
  215. GridItem gi;
  216. gi.IsAbsolute = false;
  217. gi.IsPercentage = true;
  218. gi.IsRemaining = false;
  219. gi.Size = perc;
  220. GridItems.push_back(gi);
  221. }
  222. else //standard absolute pixel based
  223. {
  224. int px = dAtoi(str);
  225. GridItem gi;
  226. gi.IsAbsolute = true;
  227. gi.IsPercentage = false;
  228. gi.IsRemaining = false;
  229. gi.Size = px;
  230. GridItems.push_back(gi);
  231. totalSize += px;
  232. }
  233. }
  234. //step two: iterate the grid columns again, and fill in any percentage based sizing, and setup the correct grid array.
  235. int remainingSize = size - totalSize;
  236. int sizeForPerc = remainingSize;
  237. for(int i = 0; i < GridItems.size(); ++i)
  238. {
  239. GridItem gi = GridItems[i];
  240. if (gi.IsAbsolute)
  241. {
  242. items.push_back(gi.Size);
  243. }
  244. else if (gi.IsPercentage)
  245. {
  246. F32 perc = gi.Size / 100.0f;
  247. S32 realSize = sizeForPerc * (S32)perc;
  248. remainingSize -= realSize;
  249. items.push_back(realSize);
  250. }
  251. else if(gi.IsRemaining)
  252. {
  253. //place holder for the moment.
  254. items.push_back(0);
  255. IndexRemaining = i;
  256. }
  257. }
  258. if (IndexRemaining >= 0)
  259. {
  260. items[IndexRemaining] = remainingSize;
  261. remainingSize = 0;
  262. }
  263. }