Container.cpp 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352
  1. #include "Base.h"
  2. #include "Container.h"
  3. #include "Layout.h"
  4. #include "AbsoluteLayout.h"
  5. #include "VerticalLayout.h"
  6. #include "Label.h"
  7. #include "Button.h"
  8. #include "CheckBox.h"
  9. #include "RadioButton.h"
  10. #include "Slider.h"
  11. #include "TextBox.h"
  12. namespace gameplay
  13. {
  14. static std::vector<Container*> __containers;
  15. Container::Container() : _layout(NULL)
  16. {
  17. }
  18. Container::Container(const Container& copy)
  19. {
  20. }
  21. Container::~Container()
  22. {
  23. std::vector<Control*>::iterator it;
  24. for (it = _controls.begin(); it < _controls.end(); it++)
  25. {
  26. SAFE_RELEASE((*it));
  27. }
  28. SAFE_RELEASE(_layout);
  29. }
  30. Container* Container::create(const char* id, Layout::Type type)
  31. {
  32. Layout* layout = NULL;
  33. switch(type)
  34. {
  35. case Layout::LAYOUT_ABSOLUTE:
  36. layout = AbsoluteLayout::create();
  37. break;
  38. case Layout::LAYOUT_FLOW:
  39. break;
  40. case Layout::LAYOUT_VERTICAL:
  41. layout = VerticalLayout::create();
  42. break;
  43. }
  44. Container* container = new Container();
  45. container->_id = id;
  46. container->_layout = layout;
  47. __containers.push_back(container);
  48. return container;
  49. }
  50. Container* Container::create(Theme::Style* style, Properties* properties, Theme* theme)
  51. {
  52. const char* id = properties->getId();
  53. const char* layoutString = properties->getString("layout");
  54. Container* container = Container::create(id, getLayoutType(layoutString));
  55. container->_style = style;
  56. properties->getVector2("position", &container->_position);
  57. properties->getVector2("size", &container->_size);
  58. container->addControls(theme, properties);
  59. return container;
  60. }
  61. void Container::addControls(Theme* theme, Properties* properties)
  62. {
  63. // Add all the controls to this container.
  64. Properties* controlSpace = properties->getNextNamespace();
  65. while (controlSpace != NULL)
  66. {
  67. Control* control = NULL;
  68. const char* controlStyleName = controlSpace->getString("style");
  69. Theme::Style* controlStyle = NULL;
  70. if (controlStyleName)
  71. {
  72. controlStyle = theme->getStyle(controlStyleName);
  73. }
  74. std::string controlName(controlSpace->getNamespace());
  75. std::transform(controlName.begin(), controlName.end(), controlName.begin(), (int(*)(int))toupper);
  76. if (controlName == "LABEL")
  77. {
  78. control = Label::create(controlStyle, controlSpace);
  79. }
  80. else if (controlName == "BUTTON")
  81. {
  82. control = Button::create(controlStyle, controlSpace);
  83. }
  84. else if (controlName == "CHECKBOX")
  85. {
  86. control = CheckBox::create(controlStyle, controlSpace);
  87. }
  88. else if (controlName == "RADIOBUTTON")
  89. {
  90. control = RadioButton::create(controlStyle, controlSpace);
  91. }
  92. else if (controlName == "CONTAINER")
  93. {
  94. control = Container::create(controlStyle, controlSpace, theme);
  95. }
  96. else if (controlName == "SLIDER")
  97. {
  98. control = Slider::create(controlStyle, controlSpace);
  99. }
  100. else if (controlName == "TEXTBOX")
  101. {
  102. control = TextBox::create(controlStyle, controlSpace);
  103. }
  104. // Add the new control to the form.
  105. if (control)
  106. {
  107. addControl(control);
  108. }
  109. // Get the next control.
  110. controlSpace = properties->getNextNamespace();
  111. }
  112. }
  113. Container* Container::getContainer(const char* id)
  114. {
  115. std::vector<Container*>::const_iterator it;
  116. for (it = __containers.begin(); it < __containers.end(); it++)
  117. {
  118. Container* c = *it;
  119. if (strcmp(id, c->getID()) == 0)
  120. {
  121. return c;
  122. }
  123. }
  124. return NULL;
  125. }
  126. Layout* Container::getLayout()
  127. {
  128. return _layout;
  129. }
  130. unsigned int Container::addControl(Control* control)
  131. {
  132. _controls.push_back(control);
  133. return _controls.size() - 1;
  134. }
  135. void Container::insertControl(Control* control, unsigned int index)
  136. {
  137. std::vector<Control*>::iterator it = _controls.begin() + index;
  138. _controls.insert(it, control);
  139. }
  140. void Container::removeControl(unsigned int index)
  141. {
  142. std::vector<Control*>::iterator it = _controls.begin() + index;
  143. _controls.erase(it);
  144. }
  145. void Container::removeControl(const char* id)
  146. {
  147. std::vector<Control*>::iterator it;
  148. for (it = _controls.begin(); it < _controls.end(); it++)
  149. {
  150. Control* c = *it;
  151. if (strcmp(id, c->getID()) == 0)
  152. {
  153. _controls.erase(it);
  154. }
  155. }
  156. }
  157. void Container::removeControl(Control* control)
  158. {
  159. std::vector<Control*>::iterator it;
  160. for (it = _controls.begin(); it < _controls.end(); it++)
  161. {
  162. if (*it == control)
  163. {
  164. _controls.erase(it);
  165. }
  166. }
  167. }
  168. Control* Container::getControl(unsigned int index) const
  169. {
  170. std::vector<Control*>::const_iterator it = _controls.begin() + index;
  171. return *it;
  172. }
  173. Control* Container::getControl(const char* id) const
  174. {
  175. std::vector<Control*>::const_iterator it;
  176. for (it = _controls.begin(); it < _controls.end(); it++)
  177. {
  178. Control* c = *it;
  179. if (strcmp(id, c->getID()) == 0)
  180. {
  181. return c;
  182. }
  183. }
  184. return NULL;
  185. }
  186. std::vector<Control*> Container::getControls() const
  187. {
  188. return _controls;
  189. }
  190. void Container::update(const Vector2& position)
  191. {
  192. // Should probably have sizeChanged() for this.
  193. if (isDirty())
  194. {
  195. _layout->update(this);
  196. }
  197. _dirty = false;
  198. }
  199. void Container::drawSprites(SpriteBatch* spriteBatch, const Vector2& position)
  200. {
  201. Vector2 pos(position.x + _position.x, position.y + _position.y);
  202. std::vector<Control*>::const_iterator it;
  203. for (it = _controls.begin(); it < _controls.end(); it++)
  204. {
  205. Control* control = *it;
  206. control->drawSprites(spriteBatch, pos);
  207. }
  208. _dirty = false;
  209. }
  210. void Container::drawText(const Vector2& position)
  211. {
  212. Vector2 pos(position.x + _position.x, position.y + _position.y);
  213. std::vector<Control*>::const_iterator it;
  214. for (it = _controls.begin(); it < _controls.end(); it++)
  215. {
  216. Control* control = *it;
  217. control->drawText(pos);
  218. }
  219. _dirty = false;
  220. }
  221. bool Container::isDirty()
  222. {
  223. if (_dirty)
  224. {
  225. return true;
  226. }
  227. else
  228. {
  229. std::vector<Control*>::const_iterator it;
  230. for (it = _controls.begin(); it < _controls.end(); it++)
  231. {
  232. if ((*it)->isDirty())
  233. {
  234. return true;
  235. }
  236. }
  237. }
  238. return false;
  239. }
  240. void Container::touchEvent(Touch::TouchEvent evt, int x, int y, unsigned int contactIndex)
  241. {
  242. if (getState() == Control::STATE_DISABLED)
  243. return;
  244. std::vector<Control*>::const_iterator it;
  245. for (it = _controls.begin(); it < _controls.end(); it++)
  246. {
  247. Control* control = *it;
  248. const Vector2& size = control->getSize();
  249. const Vector2& position = control->getPosition();
  250. if (control->getState() != Control::STATE_NORMAL ||
  251. (x >= position.x &&
  252. x <= position.x + size.x &&
  253. y >= position.y &&
  254. y <= position.y + size.y))
  255. {
  256. // Pass on the event's position relative to the control.
  257. control->touchEvent(evt, x - position.x, y - position.y, contactIndex);
  258. }
  259. }
  260. if (getState() == Control::STATE_DISABLED)
  261. return;
  262. switch (evt)
  263. {
  264. case Touch::TOUCH_PRESS:
  265. setState(Control::STATE_ACTIVE);
  266. break;
  267. case Touch::TOUCH_RELEASE:
  268. setState(Control::STATE_NORMAL);
  269. break;
  270. }
  271. }
  272. void Container::keyEvent(Keyboard::KeyEvent evt, int key)
  273. {
  274. if (getState() == Control::STATE_DISABLED)
  275. return;
  276. std::vector<Control*>::const_iterator it;
  277. for (it = _controls.begin(); it < _controls.end(); it++)
  278. {
  279. Control* control = *it;
  280. control->keyEvent(evt, key);
  281. }
  282. }
  283. Layout::Type Container::getLayoutType(const char* layoutString)
  284. {
  285. std::string layoutName(layoutString);
  286. std::transform(layoutName.begin(), layoutName.end(), layoutName.begin(), (int(*)(int))toupper);
  287. if (layoutName == "LAYOUT_ABSOLUTE")
  288. {
  289. return Layout::LAYOUT_ABSOLUTE;
  290. }
  291. else if (layoutName == "LAYOUT_VERTICAL")
  292. {
  293. return Layout::LAYOUT_VERTICAL;
  294. }
  295. else if (layoutName == "LAYOUT_FLOW")
  296. {
  297. return Layout::LAYOUT_FLOW;
  298. }
  299. else
  300. {
  301. // Default.
  302. return Layout::LAYOUT_ABSOLUTE;
  303. }
  304. }
  305. }