TreeControl.cpp 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318
  1. /*
  2. GWEN
  3. Copyright (c) 2010 Facepunch Studios
  4. See license in Gwen.h
  5. */
  6. #include "Gwen/Controls/TreeControl.h"
  7. #include "Gwen/Controls/ScrollControl.h"
  8. #include "Gwen/Utility.h"
  9. using namespace Gwen;
  10. using namespace Gwen::Controls;
  11. GWEN_CONTROL_CONSTRUCTOR( TreeControl )
  12. {
  13. m_TreeControl = this;
  14. m_bUpdateScrollBar = 2;
  15. m_ToggleButton->DelayedDelete();
  16. m_ToggleButton = NULL;
  17. m_Title->DelayedDelete();
  18. m_Title = NULL;
  19. m_InnerPanel->DelayedDelete();
  20. m_InnerPanel = NULL;
  21. m_bAllowMultipleSelection = false;
  22. m_ScrollControl = new ScrollControl( this );
  23. m_ScrollControl->Dock( Pos::Fill );
  24. m_ScrollControl->SetScroll( false, true );
  25. m_ScrollControl->SetAutoHideBars( true );
  26. m_ScrollControl->SetMargin( Margin( 1, 1, 1, 1 ) );
  27. m_InnerPanel = m_ScrollControl;
  28. m_ScrollControl->SetInnerSize( 1000, 1000 );
  29. }
  30. void TreeControl::Render( Skin::Base* skin )
  31. {
  32. if ( ShouldDrawBackground() )
  33. skin->DrawTreeControl( this );
  34. }
  35. void TreeControl::ForceUpdateScrollBars()
  36. {
  37. m_ScrollControl->UpdateScrollBars();
  38. }
  39. void TreeControl::OnChildBoundsChanged( Gwen::Rect /*oldChildBounds*/, Base* /*pChild*/ )
  40. {
  41. }
  42. void TreeControl::Clear()
  43. {
  44. m_ScrollControl->Clear();
  45. }
  46. void TreeControl::Layout( Skin::Base* skin )
  47. {
  48. BaseClass::BaseClass::Layout( skin );
  49. }
  50. void TreeControl::PostLayout( Skin::Base* skin )
  51. {
  52. BaseClass::BaseClass::PostLayout( skin );
  53. }
  54. void TreeControl::OnNodeAdded( TreeNode* pNode )
  55. {
  56. pNode->onNamePress.Add( this, &TreeControl::OnNodeSelection );
  57. }
  58. void TreeControl::OnNodeSelection( Controls::Base* /*control*/ )
  59. {
  60. //printf("TreeControl::OnNodeSelection\n");
  61. if ( !m_bAllowMultipleSelection || !Gwen::Input::IsKeyDown( Key::Control ) )
  62. DeselectAll();
  63. }
  64. void TreeControl::iterate(int action, int* maxItem, int* curItem)
  65. {
  66. Base::List& children = m_InnerPanel->GetChildren();
  67. for ( Base::List::iterator iter = children.begin(); iter != children.end(); ++iter )
  68. {
  69. TreeNode* pChild = (*iter)->DynamicCastTreeNode();
  70. if ( !pChild )
  71. continue;
  72. pChild->iterate(action ,maxItem, curItem);
  73. }
  74. }
  75. bool TreeControl::OnKeyUp( bool bDown )
  76. {
  77. if (bDown)
  78. {
  79. // int maxIndex = 0;
  80. int newIndex = 0;
  81. int maxItem=0;
  82. int curItem=-1;
  83. iterate(ITERATE_ACTION_FIND_SELECTED_INDEX,&maxItem,&curItem);
  84. // maxIndex = maxItem;
  85. int targetItem = curItem;
  86. if (curItem>0)
  87. {
  88. maxItem=0;
  89. int deselectIndex = targetItem;
  90. targetItem--;
  91. newIndex = targetItem;
  92. iterate(ITERATE_ACTION_SELECT,&maxItem,&targetItem);
  93. if (targetItem<0)
  94. {
  95. maxItem=0;
  96. iterate(ITERATE_ACTION_DESELECT_INDEX,&maxItem,&deselectIndex);
  97. }
  98. curItem = newIndex;
  99. // float amount = float(newIndex)/float(maxIndex);
  100. float viewSize = m_ScrollControl->m_VerticalScrollBar->getViewableContentSize();
  101. float contSize = m_ScrollControl->m_VerticalScrollBar->getContentSize();
  102. float curAmount = m_ScrollControl->m_VerticalScrollBar->GetScrolledAmount();
  103. // float minCoordViewableWindow = curAmount*contSize;
  104. //float maxCoordViewableWindow = minCoordViewableWindow+viewSize;
  105. float minCoordSelectedItem = curItem*16.f;
  106. // float maxCoordSelectedItem = (curItem+1)*16.f;
  107. if (contSize!=viewSize)
  108. {
  109. {
  110. float newAmount = float(minCoordSelectedItem)/(contSize-viewSize);
  111. if (newAmount<curAmount)
  112. {
  113. m_ScrollControl->m_VerticalScrollBar->SetScrolledAmount(newAmount,true);
  114. }
  115. }
  116. {
  117. int numItems = (viewSize)/16-1;
  118. float newAmount = float((curItem-numItems)*16)/(contSize-viewSize);
  119. if (newAmount>curAmount)
  120. {
  121. m_ScrollControl->m_VerticalScrollBar->SetScrolledAmount(newAmount,true);
  122. }
  123. }
  124. }
  125. }
  126. }
  127. ForceUpdateScrollBars();
  128. return true;
  129. }
  130. bool TreeControl::OnKeyDown( bool bDown )
  131. {
  132. if (bDown)
  133. {
  134. // int maxIndex = 0;
  135. int newIndex = 0;
  136. int maxItem=0;
  137. int curItem=-1;
  138. iterate(ITERATE_ACTION_FIND_SELECTED_INDEX,&maxItem,&curItem);
  139. // maxIndex = maxItem;
  140. int targetItem = curItem;
  141. if (curItem>=0)
  142. {
  143. maxItem=0;
  144. int deselectIndex = targetItem;
  145. targetItem++;
  146. newIndex = targetItem;
  147. iterate(ITERATE_ACTION_SELECT,&maxItem,&targetItem);
  148. if (targetItem<0)
  149. {
  150. maxItem=0;
  151. iterate(ITERATE_ACTION_DESELECT_INDEX,&maxItem,&deselectIndex);
  152. }
  153. curItem= newIndex;
  154. // float amount = (int)float(newIndex)/float(maxIndex);
  155. float viewSize = m_ScrollControl->m_VerticalScrollBar->getViewableContentSize();
  156. float contSize = m_ScrollControl->m_VerticalScrollBar->getContentSize();
  157. float curAmount = m_ScrollControl->m_VerticalScrollBar->GetScrolledAmount();
  158. // float minCoordViewableWindow = curAmount*contSize;
  159. //float maxCoordViewableWindow = minCoordViewableWindow+viewSize;
  160. float minCoordSelectedItem = curItem*16.f;
  161. //float maxCoordSelectedItem = (curItem+1)*16.f;
  162. if (contSize!=viewSize)
  163. {
  164. {
  165. float newAmount = float(minCoordSelectedItem)/(contSize-viewSize);
  166. if (newAmount<curAmount)
  167. {
  168. m_ScrollControl->m_VerticalScrollBar->SetScrolledAmount(newAmount,true);
  169. }
  170. }
  171. {
  172. int numItems = (viewSize)/16-1;
  173. float newAmount = float((curItem-numItems)*16)/(contSize-viewSize);
  174. if (newAmount>curAmount)
  175. {
  176. m_ScrollControl->m_VerticalScrollBar->SetScrolledAmount(newAmount,true);
  177. }
  178. }
  179. }
  180. }
  181. }
  182. ForceUpdateScrollBars();
  183. return true;
  184. }
  185. extern int avoidUpdate;
  186. bool TreeControl::OnKeyRight( bool bDown )
  187. {
  188. if (bDown)
  189. {
  190. avoidUpdate = -3;
  191. iterate(ITERATE_ACTION_OPEN,0,0);
  192. int maxItem=0;
  193. int curItem=0;
  194. iterate(ITERATE_ACTION_FIND_SELECTED_INDEX,&maxItem,&curItem);
  195. // float amount = float(curItem)/float(maxItem);
  196. float viewSize = m_ScrollControl->m_VerticalScrollBar->getViewableContentSize();
  197. float contSize = m_ScrollControl->m_VerticalScrollBar->getContentSize();
  198. float curAmount = m_ScrollControl->m_VerticalScrollBar->GetScrolledAmount();
  199. // float minCoordViewableWindow = curAmount*contSize;
  200. // float maxCoordViewableWindow = minCoordViewableWindow+viewSize;
  201. float minCoordSelectedItem = curItem*16.f;
  202. // float maxCoordSelectedItem = (curItem+1)*16.f;
  203. if (contSize!=viewSize)
  204. {
  205. {
  206. float newAmount = float(minCoordSelectedItem)/(contSize-viewSize);
  207. if (newAmount<curAmount)
  208. {
  209. m_ScrollControl->m_VerticalScrollBar->SetScrolledAmount(newAmount,true);
  210. }
  211. }
  212. {
  213. int numItems = (viewSize)/16-1;
  214. float newAmount = float((curItem-numItems)*16)/(contSize-viewSize);
  215. if (newAmount>curAmount)
  216. {
  217. m_ScrollControl->m_VerticalScrollBar->SetScrolledAmount(newAmount,true);
  218. }
  219. }
  220. }
  221. Invalidate();
  222. }
  223. ForceUpdateScrollBars();
  224. return true;
  225. }
  226. bool TreeControl::OnKeyLeft( bool bDown )
  227. {
  228. if (bDown)
  229. {
  230. avoidUpdate = -3;
  231. iterate(ITERATE_ACTION_CLOSE,0,0);
  232. int maxItems=0;
  233. int curItem=0;
  234. iterate(ITERATE_ACTION_FIND_SELECTED_INDEX,&maxItems,&curItem);
  235. // float amount = float(curItem)/float(maxItems);
  236. // m_ScrollControl->m_VerticalScrollBar->SetScrolledAmount(amount,true);
  237. float viewSize = m_ScrollControl->m_VerticalScrollBar->getViewableContentSize();
  238. float contSize = m_ScrollControl->m_VerticalScrollBar->getContentSize();
  239. float curAmount = m_ScrollControl->m_VerticalScrollBar->GetScrolledAmount();
  240. // float minCoordViewableWindow = curAmount*contSize;
  241. // float maxCoordViewableWindow = minCoordViewableWindow+viewSize;
  242. float minCoordSelectedItem = curItem*16.f;
  243. // float maxCoordSelectedItem = (curItem+1)*16.f;
  244. if (contSize!=viewSize)
  245. {
  246. {
  247. float newAmount = float(minCoordSelectedItem)/(contSize-viewSize);
  248. if (newAmount<curAmount)
  249. {
  250. m_ScrollControl->m_VerticalScrollBar->SetScrolledAmount(newAmount,true);
  251. }
  252. }
  253. {
  254. int numItems = (viewSize)/16-1;
  255. float newAmount = float((curItem-numItems)*16)/(contSize-viewSize);
  256. if (newAmount>curAmount)
  257. {
  258. m_ScrollControl->m_VerticalScrollBar->SetScrolledAmount(newAmount,true);
  259. }
  260. Invalidate();
  261. }
  262. }
  263. //viewSize/contSize
  264. //printf("!\n");
  265. //this->Layout(0);
  266. }
  267. ForceUpdateScrollBars();
  268. return true;
  269. }