Control.cpp 36 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387
  1. #include "Base.h"
  2. #include "Game.h"
  3. #include "Control.h"
  4. namespace gameplay
  5. {
  6. Control::Control()
  7. : _id(""), _state(Control::NORMAL), _bounds(Rectangle::empty()), _clipBounds(Rectangle::empty()), _viewportClipBounds(Rectangle::empty()),
  8. _clearBounds(Rectangle::empty()), _dirty(true), _consumeInputEvents(true), _listeners(NULL), _contactIndex(INVALID_CONTACT_INDEX),
  9. _styleOverridden(false), _skin(NULL)
  10. {
  11. }
  12. Control::Control(const Control& copy)
  13. {
  14. }
  15. Control::~Control()
  16. {
  17. if (_listeners)
  18. {
  19. for (std::map<Listener::EventType, std::list<Listener*>*>::const_iterator itr = _listeners->begin(); itr != _listeners->end(); itr++)
  20. {
  21. std::list<Listener*>* list = itr->second;
  22. SAFE_DELETE(list);
  23. }
  24. SAFE_DELETE(_listeners);
  25. }
  26. if (_styleOverridden)
  27. {
  28. SAFE_DELETE(_style);
  29. }
  30. }
  31. void Control::initialize(Theme::Style* style, Properties* properties)
  32. {
  33. GP_ASSERT(properties);
  34. _style = style;
  35. // Properties not defined by the style.
  36. _alignment = getAlignment(properties->getString("alignment"));
  37. _autoWidth = properties->getBool("autoWidth");
  38. _autoHeight = properties->getBool("autoHeight");
  39. if (properties->exists("zIndex"))
  40. {
  41. _zIndex = properties->getInt("zIndex");
  42. }
  43. else
  44. {
  45. _zIndex = -1;
  46. }
  47. if (properties->exists("focusIndex"))
  48. {
  49. _focusIndex = properties->getInt("focusIndex");
  50. }
  51. else
  52. {
  53. _focusIndex = -1;
  54. }
  55. Vector2 position;
  56. Vector2 size;
  57. if (properties->exists("position"))
  58. {
  59. properties->getVector2("position", &position);
  60. }
  61. else
  62. {
  63. position.x = properties->getFloat("x");
  64. position.y = properties->getFloat("y");
  65. }
  66. if (properties->exists("size"))
  67. {
  68. properties->getVector2("size", &size);
  69. }
  70. else
  71. {
  72. size.x = properties->getFloat("width");
  73. size.y = properties->getFloat("height");
  74. }
  75. setBounds(Rectangle(position.x, position.y, size.x, size.y));
  76. const char* id = properties->getId();
  77. if (id)
  78. _id = id;
  79. // Potentially override themed properties for all states.
  80. overrideThemedProperties(properties, STATE_ALL);
  81. // Override themed properties on specific states.
  82. Properties* innerSpace = properties->getNextNamespace();
  83. while (innerSpace != NULL)
  84. {
  85. std::string spaceName(innerSpace->getNamespace());
  86. std::transform(spaceName.begin(), spaceName.end(), spaceName.begin(), (int(*)(int))toupper);
  87. if (spaceName == "STATENORMAL")
  88. {
  89. overrideThemedProperties(innerSpace, NORMAL);
  90. }
  91. else if (spaceName == "STATEFOCUS")
  92. {
  93. overrideThemedProperties(innerSpace, FOCUS);
  94. }
  95. else if (spaceName == "STATEACTIVE")
  96. {
  97. overrideThemedProperties(innerSpace, ACTIVE);
  98. }
  99. else if (spaceName == "STATEDISABLED")
  100. {
  101. overrideThemedProperties(innerSpace, DISABLED);
  102. }
  103. else if (spaceName == "MARGIN")
  104. {
  105. setMargin(innerSpace->getFloat("top"), innerSpace->getFloat("bottom"),
  106. innerSpace->getFloat("left"), innerSpace->getFloat("right"));
  107. }
  108. else if (spaceName == "PADDING")
  109. {
  110. setPadding(innerSpace->getFloat("top"), innerSpace->getFloat("bottom"),
  111. innerSpace->getFloat("left"), innerSpace->getFloat("right"));
  112. }
  113. innerSpace = properties->getNextNamespace();
  114. }
  115. }
  116. void initialize(const char* id, Theme::Style* style, const Vector2& position, const Vector2& size)
  117. {
  118. }
  119. const char* Control::getId() const
  120. {
  121. return _id.c_str();
  122. }
  123. void Control::setPosition(float x, float y)
  124. {
  125. if (x != _bounds.x || y != _bounds.y)
  126. {
  127. _bounds.x = x;
  128. _bounds.y = y;
  129. _dirty = true;
  130. }
  131. }
  132. void Control::setSize(float width, float height)
  133. {
  134. if (width != _bounds.width || height != _bounds.height)
  135. {
  136. _bounds.width = width;
  137. _bounds.height = height;
  138. _dirty = true;
  139. }
  140. }
  141. void Control::setBounds(const Rectangle& bounds)
  142. {
  143. if (bounds != _bounds)
  144. {
  145. _bounds.set(bounds);
  146. _dirty = true;
  147. }
  148. }
  149. const Rectangle& Control::getBounds() const
  150. {
  151. return _bounds;
  152. }
  153. float Control::getX() const
  154. {
  155. return _bounds.x;
  156. }
  157. float Control::getY() const
  158. {
  159. return _bounds.y;
  160. }
  161. float Control::getWidth() const
  162. {
  163. return _bounds.width;
  164. }
  165. float Control::getHeight() const
  166. {
  167. return _bounds.height;
  168. }
  169. void Control::setAlignment(Alignment alignment)
  170. {
  171. _alignment = alignment;
  172. }
  173. Control::Alignment Control::getAlignment() const
  174. {
  175. return _alignment;
  176. }
  177. void Control::setAutoWidth(bool autoWidth)
  178. {
  179. if (_autoWidth != autoWidth)
  180. {
  181. _autoWidth = autoWidth;
  182. _dirty = true;
  183. }
  184. }
  185. bool Control::getAutoWidth() const
  186. {
  187. return _autoWidth;
  188. }
  189. void Control::setAutoHeight(bool autoHeight)
  190. {
  191. if (_autoHeight != autoHeight)
  192. {
  193. _autoHeight = autoHeight;
  194. _dirty = true;
  195. }
  196. }
  197. void Control::setOpacity(float opacity, unsigned char states)
  198. {
  199. overrideStyle();
  200. Theme::Style::Overlay* overlays[Theme::Style::OVERLAY_MAX] = { 0 };
  201. getOverlays(states, overlays);
  202. for (int i = 0; i < Theme::Style::OVERLAY_MAX - 1 && overlays[i]; ++i)
  203. {
  204. overlays[i]->setOpacity(opacity);
  205. }
  206. _dirty = true;
  207. }
  208. float Control::getOpacity(State state) const
  209. {
  210. Theme::Style::Overlay* overlay = getOverlay(state);
  211. GP_ASSERT(overlay);
  212. return overlay->getOpacity();
  213. }
  214. void Control::setBorder(float top, float bottom, float left, float right, unsigned char states)
  215. {
  216. overrideStyle();
  217. Theme::Style::Overlay* overlays[Theme::Style::OVERLAY_MAX] = { 0 };
  218. getOverlays(states, overlays);
  219. for (int i = 0; i < Theme::Style::OVERLAY_MAX - 1 && overlays[i]; ++i)
  220. {
  221. overlays[i]->setBorder(top, bottom, left, right);
  222. }
  223. _dirty = true;
  224. }
  225. const Theme::Border& Control::getBorder(State state) const
  226. {
  227. Theme::Style::Overlay* overlay = getOverlay(state);
  228. GP_ASSERT(overlay);
  229. return overlay->getBorder();
  230. }
  231. void Control::setSkinRegion(const Rectangle& region, unsigned char states)
  232. {
  233. overrideStyle();
  234. Theme::Style::Overlay* overlays[Theme::Style::OVERLAY_MAX] = { 0 };
  235. getOverlays(states, overlays);
  236. for (int i = 0; i < Theme::Style::OVERLAY_MAX - 1 && overlays[i]; ++i)
  237. {
  238. overlays[i]->setSkinRegion(region, _style->_tw, _style->_th);
  239. }
  240. _dirty = true;
  241. }
  242. const Rectangle& Control::getSkinRegion(State state) const
  243. {
  244. Theme::Style::Overlay* overlay = getOverlay(state);
  245. GP_ASSERT(overlay);
  246. return overlay->getSkinRegion();
  247. }
  248. const Theme::UVs& Control::getSkinUVs(Theme::Skin::SkinArea area, State state) const
  249. {
  250. Theme::Style::Overlay* overlay = getOverlay(state);
  251. GP_ASSERT(overlay);
  252. return overlay->getSkinUVs(area);
  253. }
  254. void Control::setSkinColor(const Vector4& color, unsigned char states)
  255. {
  256. overrideStyle();
  257. Theme::Style::Overlay* overlays[Theme::Style::OVERLAY_MAX] = { 0 };
  258. getOverlays(states, overlays);
  259. for (int i = 0; i < Theme::Style::OVERLAY_MAX - 1 && overlays[i]; ++i)
  260. {
  261. overlays[i]->setSkinColor(color);
  262. }
  263. _dirty = true;
  264. }
  265. const Vector4& Control::getSkinColor(State state) const
  266. {
  267. Theme::Style::Overlay* overlay = getOverlay(state);
  268. GP_ASSERT(overlay);
  269. return overlay->getSkinColor();
  270. }
  271. void Control::setMargin(float top, float bottom, float left, float right)
  272. {
  273. GP_ASSERT(_style);
  274. overrideStyle();
  275. _style->setMargin(top, bottom, left, right);
  276. _dirty = true;
  277. }
  278. const Theme::Margin& Control::getMargin() const
  279. {
  280. GP_ASSERT(_style);
  281. return _style->getMargin();
  282. }
  283. void Control::setPadding(float top, float bottom, float left, float right)
  284. {
  285. GP_ASSERT(_style);
  286. overrideStyle();
  287. _style->setPadding(top, bottom, left, right);
  288. _dirty = true;
  289. }
  290. const Theme::Padding& Control::getPadding() const
  291. {
  292. GP_ASSERT(_style);
  293. return _style->getPadding();
  294. }
  295. void Control::setImageRegion(const char* id, const Rectangle& region, unsigned char states)
  296. {
  297. overrideStyle();
  298. Theme::Style::Overlay* overlays[Theme::Style::OVERLAY_MAX] = { 0 };
  299. getOverlays(states, overlays);
  300. for (int i = 0; i < Theme::Style::OVERLAY_MAX - 1 && overlays[i]; ++i)
  301. {
  302. overlays[i]->setImageRegion(id, region, _style->_tw, _style->_th);
  303. }
  304. _dirty = true;
  305. }
  306. const Rectangle& Control::getImageRegion(const char* id, State state) const
  307. {
  308. Theme::Style::Overlay* overlay = getOverlay(state);
  309. GP_ASSERT(overlay);
  310. return overlay->getImageRegion(id);
  311. }
  312. void Control::setImageColor(const char* id, const Vector4& color, unsigned char states)
  313. {
  314. overrideStyle();
  315. Theme::Style::Overlay* overlays[Theme::Style::OVERLAY_MAX] = { 0 };
  316. getOverlays(states, overlays);
  317. for (int i = 0; i < Theme::Style::OVERLAY_MAX - 1 && overlays[i]; ++i)
  318. {
  319. overlays[i]->setImageColor(id, color);
  320. }
  321. _dirty = true;
  322. }
  323. const Vector4& Control::getImageColor(const char* id, State state) const
  324. {
  325. Theme::Style::Overlay* overlay = getOverlay(state);
  326. GP_ASSERT(overlay);
  327. return overlay->getImageColor(id);
  328. }
  329. const Theme::UVs& Control::getImageUVs(const char* id, State state) const
  330. {
  331. Theme::Style::Overlay* overlay = getOverlay(state);
  332. GP_ASSERT(overlay);
  333. return overlay->getImageUVs(id);
  334. }
  335. void Control::setCursorRegion(const Rectangle& region, unsigned char states)
  336. {
  337. overrideStyle();
  338. Theme::Style::Overlay* overlays[Theme::Style::OVERLAY_MAX] = { 0 };
  339. getOverlays(states, overlays);
  340. for (int i = 0; i < Theme::Style::OVERLAY_MAX - 1 && overlays[i]; ++i)
  341. {
  342. overlays[i]->setCursorRegion(region, _style->_tw, _style->_th);
  343. }
  344. _dirty = true;
  345. }
  346. const Rectangle& Control::getCursorRegion(State state) const
  347. {
  348. Theme::Style::Overlay* overlay = getOverlay(state);
  349. GP_ASSERT(overlay);
  350. return overlay->getCursorRegion();
  351. }
  352. void Control::setCursorColor(const Vector4& color, unsigned char states)
  353. {
  354. overrideStyle();
  355. Theme::Style::Overlay* overlays[Theme::Style::OVERLAY_MAX] = { 0 };
  356. getOverlays(states, overlays);
  357. for (int i = 0; i < Theme::Style::OVERLAY_MAX - 1 && overlays[i]; ++i)
  358. {
  359. overlays[i]->setCursorColor(color);
  360. }
  361. _dirty = true;
  362. }
  363. const Vector4& Control::getCursorColor(State state)
  364. {
  365. Theme::Style::Overlay* overlay = getOverlay(state);
  366. GP_ASSERT(overlay);
  367. return overlay->getCursorColor();
  368. }
  369. const Theme::UVs& Control::getCursorUVs(State state)
  370. {
  371. Theme::Style::Overlay* overlay = getOverlay(state);
  372. GP_ASSERT(overlay);
  373. return overlay->getCursorUVs();
  374. }
  375. void Control::setFont(Font* font, unsigned char states)
  376. {
  377. overrideStyle();
  378. Theme::Style::Overlay* overlays[Theme::Style::OVERLAY_MAX] = { 0 };
  379. getOverlays(states, overlays);
  380. for (int i = 0; i < Theme::Style::OVERLAY_MAX - 1 && overlays[i]; ++i)
  381. {
  382. overlays[i]->setFont(font);
  383. }
  384. _dirty = true;
  385. }
  386. Font* Control::getFont(State state) const
  387. {
  388. Theme::Style::Overlay* overlay = getOverlay(state);
  389. GP_ASSERT(overlay);
  390. return overlay->getFont();
  391. }
  392. void Control::setFontSize(unsigned int fontSize, unsigned char states)
  393. {
  394. overrideStyle();
  395. Theme::Style::Overlay* overlays[Theme::Style::OVERLAY_MAX] = { 0 };
  396. getOverlays(states, overlays);
  397. for (int i = 0; i < Theme::Style::OVERLAY_MAX - 1 && overlays[i]; ++i)
  398. {
  399. overlays[i]->setFontSize(fontSize);
  400. }
  401. _dirty = true;
  402. }
  403. unsigned int Control::getFontSize(State state) const
  404. {
  405. Theme::Style::Overlay* overlay = getOverlay(state);
  406. GP_ASSERT(overlay);
  407. return overlay->getFontSize();
  408. }
  409. void Control::setTextColor(const Vector4& color, unsigned char states)
  410. {
  411. overrideStyle();
  412. Theme::Style::Overlay* overlays[Theme::Style::OVERLAY_MAX] = { 0 };
  413. getOverlays(states, overlays);
  414. for (int i = 0; i < Theme::Style::OVERLAY_MAX - 1 && overlays[i]; ++i)
  415. {
  416. overlays[i]->setTextColor(color);
  417. }
  418. _dirty = true;
  419. }
  420. const Vector4& Control::getTextColor(State state) const
  421. {
  422. Theme::Style::Overlay* overlay = getOverlay(state);
  423. GP_ASSERT(overlay);
  424. return overlay->getTextColor();
  425. }
  426. void Control::setTextAlignment(Font::Justify alignment, unsigned char states)
  427. {
  428. overrideStyle();
  429. Theme::Style::Overlay* overlays[Theme::Style::OVERLAY_MAX] = { 0 };
  430. getOverlays(states, overlays);
  431. for (int i = 0; i < Theme::Style::OVERLAY_MAX - 1 && overlays[i]; ++i)
  432. {
  433. overlays[i]->setTextAlignment(alignment);
  434. }
  435. _dirty = true;
  436. }
  437. Font::Justify Control::getTextAlignment(State state) const
  438. {
  439. Theme::Style::Overlay* overlay = getOverlay(state);
  440. GP_ASSERT(overlay);
  441. return overlay->getTextAlignment();
  442. }
  443. void Control::setTextRightToLeft(bool rightToLeft, unsigned char states)
  444. {
  445. overrideStyle();
  446. Theme::Style::Overlay* overlays[Theme::Style::OVERLAY_MAX] = { 0 };
  447. getOverlays(states, overlays);
  448. for (int i = 0; i < Theme::Style::OVERLAY_MAX - 1 && overlays[i]; ++i)
  449. {
  450. overlays[i]->setTextRightToLeft(rightToLeft);
  451. }
  452. _dirty = true;
  453. }
  454. bool Control::getTextRightToLeft(State state) const
  455. {
  456. Theme::Style::Overlay* overlay = getOverlay(state);
  457. GP_ASSERT(overlay);
  458. return overlay->getTextRightToLeft();
  459. }
  460. const Rectangle& Control::getClipBounds() const
  461. {
  462. return _clipBounds;
  463. }
  464. const Rectangle& Control::getClip() const
  465. {
  466. return _viewportClipBounds;
  467. }
  468. void Control::setStyle(Theme::Style* style)
  469. {
  470. if (style != _style)
  471. {
  472. _dirty = true;
  473. }
  474. _style = style;
  475. }
  476. Theme::Style* Control::getStyle() const
  477. {
  478. return _style;
  479. }
  480. void Control::setState(State state)
  481. {
  482. if (getOverlay(_state) != getOverlay(state))
  483. _dirty = true;
  484. _state = state;
  485. }
  486. Control::State Control::getState() const
  487. {
  488. return _state;
  489. }
  490. void Control::disable()
  491. {
  492. _state = DISABLED;
  493. _dirty = true;
  494. }
  495. void Control::enable()
  496. {
  497. _state = NORMAL;
  498. _dirty = true;
  499. }
  500. bool Control::isEnabled()
  501. {
  502. return _state != DISABLED;
  503. }
  504. Theme::Style::OverlayType Control::getOverlayType() const
  505. {
  506. switch (_state)
  507. {
  508. case Control::NORMAL:
  509. return Theme::Style::OVERLAY_NORMAL;
  510. case Control::FOCUS:
  511. return Theme::Style::OVERLAY_FOCUS;
  512. case Control::ACTIVE:
  513. return Theme::Style::OVERLAY_ACTIVE;
  514. case Control::DISABLED:
  515. return Theme::Style::OVERLAY_DISABLED;
  516. default:
  517. return Theme::Style::OVERLAY_NORMAL;
  518. }
  519. }
  520. void Control::setConsumeInputEvents(bool consume)
  521. {
  522. _consumeInputEvents = consume;
  523. }
  524. bool Control::getConsumeInputEvents()
  525. {
  526. return _consumeInputEvents;
  527. }
  528. int Control::getZIndex() const
  529. {
  530. return _zIndex;
  531. }
  532. void Control::setZIndex(int zIndex)
  533. {
  534. if (zIndex != _zIndex)
  535. {
  536. _zIndex = zIndex;
  537. _dirty = true;
  538. }
  539. }
  540. int Control::getFocusIndex() const
  541. {
  542. return _focusIndex;
  543. }
  544. void Control::setFocusIndex(int focusIndex)
  545. {
  546. _focusIndex = focusIndex;
  547. }
  548. void Control::addListener(Control::Listener* listener, int eventFlags)
  549. {
  550. GP_ASSERT(listener);
  551. if ((eventFlags & Listener::PRESS) == Listener::PRESS)
  552. {
  553. addSpecificListener(listener, Listener::PRESS);
  554. }
  555. if ((eventFlags & Listener::RELEASE) == Listener::RELEASE)
  556. {
  557. addSpecificListener(listener, Listener::RELEASE);
  558. }
  559. if ((eventFlags & Listener::CLICK) == Listener::CLICK)
  560. {
  561. addSpecificListener(listener, Listener::CLICK);
  562. }
  563. if ((eventFlags & Listener::VALUE_CHANGED) == Listener::VALUE_CHANGED)
  564. {
  565. addSpecificListener(listener, Listener::VALUE_CHANGED);
  566. }
  567. if ((eventFlags & Listener::TEXT_CHANGED) == Listener::TEXT_CHANGED)
  568. {
  569. addSpecificListener(listener, Listener::TEXT_CHANGED);
  570. }
  571. }
  572. void Control::addSpecificListener(Control::Listener* listener, Listener::EventType eventType)
  573. {
  574. GP_ASSERT(listener);
  575. if (!_listeners)
  576. {
  577. _listeners = new std::map<Listener::EventType, std::list<Listener*>*>();
  578. }
  579. std::map<Listener::EventType, std::list<Listener*>*>::const_iterator itr = _listeners->find(eventType);
  580. if (itr == _listeners->end())
  581. {
  582. _listeners->insert(std::make_pair(eventType, new std::list<Listener*>()));
  583. itr = _listeners->find(eventType);
  584. }
  585. std::list<Listener*>* listenerList = itr->second;
  586. listenerList->push_back(listener);
  587. }
  588. bool Control::touchEvent(Touch::TouchEvent evt, int x, int y, unsigned int contactIndex)
  589. {
  590. if (!isEnabled())
  591. return false;
  592. switch (evt)
  593. {
  594. case Touch::TOUCH_PRESS:
  595. // Controls that don't have an ACTIVE state go to the FOCUS state when pressed.
  596. // (Other controls, such as buttons and sliders, become ACTIVE when pressed and go to the FOCUS state on release.)
  597. // Labels are never any state other than NORMAL.
  598. if (x > _clipBounds.x && x <= _clipBounds.x + _clipBounds.width &&
  599. y > _clipBounds.y && y <= _clipBounds.y + _clipBounds.height)
  600. {
  601. _contactIndex = (int) contactIndex;
  602. notifyListeners(Listener::PRESS);
  603. return _consumeInputEvents;
  604. }
  605. else
  606. {
  607. // If this control was in focus, it's not any more.
  608. _state = NORMAL;
  609. _contactIndex = INVALID_CONTACT_INDEX;
  610. }
  611. break;
  612. case Touch::TOUCH_RELEASE:
  613. _contactIndex = INVALID_CONTACT_INDEX;
  614. // Always trigger Listener::RELEASE
  615. notifyListeners(Listener::RELEASE);
  616. // Only trigger Listener::CLICK if both PRESS and RELEASE took place within the control's bounds.
  617. if (x > _clipBounds.x && x <= _clipBounds.x + _clipBounds.width &&
  618. y > _clipBounds.y && y <= _clipBounds.y + _clipBounds.height)
  619. {
  620. // Leave this control in the FOCUS state.
  621. notifyListeners(Listener::CLICK);
  622. }
  623. return _consumeInputEvents;
  624. }
  625. return false;
  626. }
  627. bool Control::keyEvent(Keyboard::KeyEvent evt, int key)
  628. {
  629. return false;
  630. }
  631. bool Control::mouseEvent(Mouse::MouseEvent evt, int x, int y, int wheelDelta)
  632. {
  633. if (!isEnabled())
  634. {
  635. return false;
  636. }
  637. // By default, mouse events are either interpreted as touch events or ignored.
  638. switch (evt)
  639. {
  640. case Mouse::MOUSE_PRESS_LEFT_BUTTON:
  641. return touchEvent(Touch::TOUCH_PRESS, x, y, 0);
  642. case Mouse::MOUSE_RELEASE_LEFT_BUTTON:
  643. return touchEvent(Touch::TOUCH_RELEASE, x, y, 0);
  644. case Mouse::MOUSE_MOVE:
  645. return touchEvent(Touch::TOUCH_MOVE, x, y, 0);
  646. default:
  647. break;
  648. }
  649. return false;
  650. }
  651. void Control::notifyListeners(Listener::EventType eventType)
  652. {
  653. if (_listeners)
  654. {
  655. std::map<Listener::EventType, std::list<Listener*>*>::const_iterator itr = _listeners->find(eventType);
  656. if (itr != _listeners->end())
  657. {
  658. std::list<Listener*>* listenerList = itr->second;
  659. for (std::list<Listener*>::iterator listenerItr = listenerList->begin(); listenerItr != listenerList->end(); listenerItr++)
  660. {
  661. GP_ASSERT(*listenerItr);
  662. (*listenerItr)->controlEvent(this, eventType);
  663. }
  664. }
  665. }
  666. }
  667. void Control::update(const Control* container, const Vector2& offset)
  668. {
  669. const Rectangle& clip = container->getClip();
  670. const Rectangle& absoluteViewport = container->_viewportBounds;
  671. _clearBounds.set(_absoluteClipBounds);
  672. // Calculate the clipped bounds.
  673. float x = _bounds.x + offset.x;
  674. float y = _bounds.y + offset.y;
  675. float width = _bounds.width;
  676. float height = _bounds.height;
  677. float clipX2 = clip.x + clip.width;
  678. float x2 = clip.x + x + width;
  679. if (x2 > clipX2)
  680. width -= x2 - clipX2;
  681. float clipY2 = clip.y + clip.height;
  682. float y2 = clip.y + y + height;
  683. if (y2 > clipY2)
  684. height -= y2 - clipY2;
  685. if (x < 0)
  686. {
  687. width += x;
  688. x = -x;
  689. }
  690. else
  691. {
  692. x = 0;
  693. }
  694. if (y < 0)
  695. {
  696. height += y;
  697. y = -y;
  698. }
  699. else
  700. {
  701. y = 0;
  702. }
  703. _clipBounds.set(x, y, width, height);
  704. // Calculate the absolute bounds.
  705. x = _bounds.x + offset.x + absoluteViewport.x;
  706. y = _bounds.y + offset.y + absoluteViewport.y;
  707. _absoluteBounds.set(x, y, _bounds.width, _bounds.height);
  708. // Calculate the absolute viewport bounds.
  709. // Absolute bounds minus border and padding.
  710. const Theme::Border& border = getBorder(_state);
  711. const Theme::Padding& padding = getPadding();
  712. x += border.left + padding.left;
  713. y += border.top + padding.top;
  714. width = _bounds.width - border.left - padding.left - border.right - padding.right;
  715. height = _bounds.height - border.top - padding.top - border.bottom - padding.bottom;
  716. _viewportBounds.set(x, y, width, height);
  717. // Calculate the clip area.
  718. // Absolute bounds, minus border and padding,
  719. // clipped to the parent container's clip area.
  720. clipX2 = clip.x + clip.width;
  721. x2 = x + width;
  722. if (x2 > clipX2)
  723. width = clipX2 - x;
  724. clipY2 = clip.y + clip.height;
  725. y2 = y + height;
  726. if (y2 > clipY2)
  727. height = clipY2 - y;
  728. if (x < clip.x)
  729. {
  730. float dx = clip.x - x;
  731. width -= dx;
  732. x = clip.x;
  733. }
  734. if (y < clip.y)
  735. {
  736. float dy = clip.y - y;
  737. height -= dy;
  738. y = clip.y;
  739. }
  740. _viewportClipBounds.set(x, y, width, height);
  741. _absoluteClipBounds.set(x - border.left - padding.left, y - border.top - padding.top,
  742. width + border.left + padding.left + border.right + padding.right,
  743. height + border.top + padding.top + border.bottom + padding.bottom);
  744. if (_clearBounds.isEmpty())
  745. {
  746. _clearBounds.set(_absoluteClipBounds);
  747. }
  748. // Cache themed attributes for performance.
  749. _skin = getSkin(_state);
  750. _opacity = getOpacity(_state);
  751. }
  752. void Control::drawBorder(SpriteBatch* spriteBatch, const Rectangle& clip)
  753. {
  754. if (!spriteBatch || !_skin || _bounds.width <= 0 || _bounds.height <= 0)
  755. return;
  756. // Get the border and background images for this control's current state.
  757. const Theme::UVs& topLeft = _skin->getUVs(Theme::Skin::TOP_LEFT);
  758. const Theme::UVs& top = _skin->getUVs(Theme::Skin::TOP);
  759. const Theme::UVs& topRight = _skin->getUVs(Theme::Skin::TOP_RIGHT);
  760. const Theme::UVs& left = _skin->getUVs(Theme::Skin::LEFT);
  761. const Theme::UVs& center = _skin->getUVs(Theme::Skin::CENTER);
  762. const Theme::UVs& right = _skin->getUVs(Theme::Skin::RIGHT);
  763. const Theme::UVs& bottomLeft = _skin->getUVs(Theme::Skin::BOTTOM_LEFT);
  764. const Theme::UVs& bottom = _skin->getUVs(Theme::Skin::BOTTOM);
  765. const Theme::UVs& bottomRight = _skin->getUVs(Theme::Skin::BOTTOM_RIGHT);
  766. // Calculate screen-space positions.
  767. const Theme::Border& border = getBorder(_state);
  768. const Theme::Padding& padding = getPadding();
  769. Vector4 skinColor = _skin->getColor();
  770. skinColor.w *= _opacity;
  771. float midWidth = _bounds.width - border.left - border.right;
  772. float midHeight = _bounds.height - border.top - border.bottom;
  773. float midX = _absoluteBounds.x + border.left;
  774. float midY = _absoluteBounds.y + border.top;
  775. float rightX = _absoluteBounds.x + _bounds.width - border.right;
  776. float bottomY = _absoluteBounds.y + _bounds.height - border.bottom;
  777. // Draw themed border sprites.
  778. if (!border.left && !border.right && !border.top && !border.bottom)
  779. {
  780. // No border, just draw the image.
  781. spriteBatch->draw(_absoluteBounds.x, _absoluteBounds.y, _bounds.width, _bounds.height, center.u1, center.v1, center.u2, center.v2, skinColor, clip);
  782. }
  783. else
  784. {
  785. if (border.left && border.top)
  786. spriteBatch->draw(_absoluteBounds.x, _absoluteBounds.y, border.left, border.top, topLeft.u1, topLeft.v1, topLeft.u2, topLeft.v2, skinColor, clip);
  787. if (border.top)
  788. spriteBatch->draw(_absoluteBounds.x + border.left, _absoluteBounds.y, midWidth, border.top, top.u1, top.v1, top.u2, top.v2, skinColor, clip);
  789. if (border.right && border.top)
  790. spriteBatch->draw(rightX, _absoluteBounds.y, border.right, border.top, topRight.u1, topRight.v1, topRight.u2, topRight.v2, skinColor, clip);
  791. if (border.left)
  792. spriteBatch->draw(_absoluteBounds.x, midY, border.left, midHeight, left.u1, left.v1, left.u2, left.v2, skinColor, clip);
  793. if (border.left && border.right && border.top && border.bottom)
  794. spriteBatch->draw(_absoluteBounds.x + border.left, _absoluteBounds.y + border.top, _bounds.width - border.left - border.right, _bounds.height - border.top - border.bottom,
  795. center.u1, center.v1, center.u2, center.v2, skinColor, clip);
  796. if (border.right)
  797. spriteBatch->draw(rightX, midY, border.right, midHeight, right.u1, right.v1, right.u2, right.v2, skinColor, clip);
  798. if (border.bottom && border.left)
  799. spriteBatch->draw(_absoluteBounds.x, bottomY, border.left, border.bottom, bottomLeft.u1, bottomLeft.v1, bottomLeft.u2, bottomLeft.v2, skinColor, clip);
  800. if (border.bottom)
  801. spriteBatch->draw(midX, bottomY, midWidth, border.bottom, bottom.u1, bottom.v1, bottom.u2, bottom.v2, skinColor, clip);
  802. if (border.bottom && border.right)
  803. spriteBatch->draw(rightX, bottomY, border.right, border.bottom, bottomRight.u1, bottomRight.v1, bottomRight.u2, bottomRight.v2, skinColor, clip);
  804. }
  805. }
  806. void Control::drawImages(SpriteBatch* spriteBatch, const Rectangle& position)
  807. {
  808. }
  809. void Control::drawText(const Rectangle& position)
  810. {
  811. }
  812. void Control::draw(SpriteBatch* spriteBatch, const Rectangle& clip, bool needsClear, bool cleared, float targetHeight)
  813. {
  814. if (needsClear)
  815. {
  816. GL_ASSERT( glEnable(GL_SCISSOR_TEST) );
  817. GL_ASSERT( glScissor(_clearBounds.x, targetHeight - _clearBounds.y - _clearBounds.height, _clearBounds.width, _clearBounds.height) );
  818. Game::getInstance()->clear(Game::CLEAR_COLOR, Vector4::zero(), 1.0f, 0);
  819. GL_ASSERT( glDisable(GL_SCISSOR_TEST) );
  820. }
  821. spriteBatch->begin();
  822. drawBorder(spriteBatch, clip);
  823. drawImages(spriteBatch, clip);
  824. spriteBatch->end();
  825. drawText(clip);
  826. _dirty = false;
  827. }
  828. bool Control::isDirty()
  829. {
  830. return _dirty;
  831. }
  832. bool Control::isContainer() const
  833. {
  834. return false;
  835. }
  836. Control::State Control::getState(const char* state)
  837. {
  838. if (!state)
  839. {
  840. return NORMAL;
  841. }
  842. if (strcmp(state, "NORMAL") == 0)
  843. {
  844. return NORMAL;
  845. }
  846. else if (strcmp(state, "ACTIVE") == 0)
  847. {
  848. return ACTIVE;
  849. }
  850. else if (strcmp(state, "FOCUS") == 0)
  851. {
  852. return FOCUS;
  853. }
  854. else if (strcmp(state, "DISABLED") == 0)
  855. {
  856. return DISABLED;
  857. }
  858. return NORMAL;
  859. }
  860. Theme::ThemeImage* Control::getImage(const char* id, State state)
  861. {
  862. Theme::Style::Overlay* overlay = getOverlay(state);
  863. GP_ASSERT(overlay);
  864. Theme::ImageList* imageList = overlay->getImageList();
  865. if (!imageList)
  866. return NULL;
  867. return imageList->getImage(id);
  868. }
  869. const char* Control::getType() const
  870. {
  871. return "control";
  872. }
  873. // Implementation of AnimationHandler
  874. unsigned int Control::getAnimationPropertyComponentCount(int propertyId) const
  875. {
  876. switch(propertyId)
  877. {
  878. case ANIMATE_POSITION:
  879. case ANIMATE_SIZE:
  880. return 2;
  881. case ANIMATE_POSITION_X:
  882. case ANIMATE_POSITION_Y:
  883. case ANIMATE_SIZE_WIDTH:
  884. case ANIMATE_SIZE_HEIGHT:
  885. case ANIMATE_OPACITY:
  886. return 1;
  887. default:
  888. return -1;
  889. }
  890. }
  891. void Control::getAnimationPropertyValue(int propertyId, AnimationValue* value)
  892. {
  893. GP_ASSERT(value);
  894. switch(propertyId)
  895. {
  896. case ANIMATE_POSITION:
  897. value->setFloat(0, _bounds.x);
  898. value->setFloat(1, _bounds.y);
  899. break;
  900. case ANIMATE_SIZE:
  901. value->setFloat(0, _bounds.width);
  902. value->setFloat(1, _bounds.height);
  903. break;
  904. case ANIMATE_POSITION_X:
  905. value->setFloat(0, _bounds.x);
  906. break;
  907. case ANIMATE_POSITION_Y:
  908. value->setFloat(0, _bounds.y);
  909. break;
  910. case ANIMATE_SIZE_WIDTH:
  911. value->setFloat(0, _bounds.width);
  912. break;
  913. case ANIMATE_SIZE_HEIGHT:
  914. value->setFloat(0, _bounds.height);
  915. break;
  916. case ANIMATE_OPACITY:
  917. default:
  918. break;
  919. }
  920. }
  921. void Control::setAnimationPropertyValue(int propertyId, AnimationValue* value, float blendWeight)
  922. {
  923. GP_ASSERT(value);
  924. switch(propertyId)
  925. {
  926. case ANIMATE_POSITION:
  927. _bounds.x = Curve::lerp(blendWeight, _bounds.x, value->getFloat(0));
  928. _bounds.y = Curve::lerp(blendWeight, _bounds.y, value->getFloat(1));
  929. _dirty = true;
  930. break;
  931. case ANIMATE_POSITION_X:
  932. _bounds.x = Curve::lerp(blendWeight, _bounds.x, value->getFloat(0));
  933. _dirty = true;
  934. break;
  935. case ANIMATE_POSITION_Y:
  936. _bounds.y = Curve::lerp(blendWeight, _bounds.y, value->getFloat(0));
  937. _dirty = true;
  938. break;
  939. case ANIMATE_SIZE:
  940. _bounds.width = Curve::lerp(blendWeight, _bounds.width, value->getFloat(0));
  941. _bounds.height = Curve::lerp(blendWeight, _bounds.height, value->getFloat(1));
  942. _dirty = true;
  943. break;
  944. case ANIMATE_SIZE_WIDTH:
  945. _bounds.width = Curve::lerp(blendWeight, _bounds.width, value->getFloat(0));
  946. _dirty = true;
  947. break;
  948. case ANIMATE_SIZE_HEIGHT:
  949. _bounds.height = Curve::lerp(blendWeight, _bounds.height, value->getFloat(0));
  950. _dirty = true;
  951. break;
  952. case ANIMATE_OPACITY:
  953. _dirty = true;
  954. break;
  955. }
  956. }
  957. Theme::Style::Overlay** Control::getOverlays(unsigned char overlayTypes, Theme::Style::Overlay** overlays)
  958. {
  959. GP_ASSERT(overlays);
  960. GP_ASSERT(_style);
  961. unsigned int index = 0;
  962. if ((overlayTypes & NORMAL) == NORMAL)
  963. {
  964. overlays[index++] = _style->getOverlay(Theme::Style::OVERLAY_NORMAL);
  965. }
  966. if ((overlayTypes & FOCUS) == FOCUS)
  967. {
  968. overlays[index++] = _style->getOverlay(Theme::Style::OVERLAY_FOCUS);
  969. }
  970. if ((overlayTypes & ACTIVE) == ACTIVE)
  971. {
  972. overlays[index++] = _style->getOverlay(Theme::Style::OVERLAY_ACTIVE);
  973. }
  974. if ((overlayTypes & DISABLED) == DISABLED)
  975. {
  976. overlays[index++] = _style->getOverlay(Theme::Style::OVERLAY_DISABLED);
  977. }
  978. return overlays;
  979. }
  980. Theme::Style::Overlay* Control::getOverlay(State state) const
  981. {
  982. GP_ASSERT(_style);
  983. switch(state)
  984. {
  985. case Control::NORMAL:
  986. return _style->getOverlay(Theme::Style::OVERLAY_NORMAL);
  987. case Control::FOCUS:
  988. return _style->getOverlay(Theme::Style::OVERLAY_FOCUS);
  989. case Control::ACTIVE:
  990. return _style->getOverlay(Theme::Style::OVERLAY_ACTIVE);
  991. case Control::DISABLED:
  992. return _style->getOverlay(Theme::Style::OVERLAY_DISABLED);
  993. default:
  994. return NULL;
  995. }
  996. }
  997. void Control::overrideStyle()
  998. {
  999. if (_styleOverridden)
  1000. {
  1001. return;
  1002. }
  1003. // Copy the style.
  1004. GP_ASSERT(_style);
  1005. _style = new Theme::Style(*_style);
  1006. _styleOverridden = true;
  1007. }
  1008. void Control::overrideThemedProperties(Properties* properties, unsigned char states)
  1009. {
  1010. GP_ASSERT(properties);
  1011. GP_ASSERT(_style);
  1012. GP_ASSERT(_style->_theme);
  1013. Theme::ImageList* imageList = NULL;
  1014. Theme::ThemeImage* cursor = NULL;
  1015. Theme::Skin* skin = NULL;
  1016. _style->_theme->lookUpSprites(properties, &imageList, &cursor, &skin);
  1017. if (imageList)
  1018. {
  1019. setImageList(imageList, states);
  1020. }
  1021. if (cursor)
  1022. {
  1023. setCursor(cursor, states);
  1024. }
  1025. if (skin)
  1026. {
  1027. setSkin(skin, states);
  1028. }
  1029. if (properties->exists("font"))
  1030. {
  1031. Font* font = Font::create(properties->getString("font"));
  1032. setFont(font, states);
  1033. font->release();
  1034. }
  1035. if (properties->exists("fontSize"))
  1036. {
  1037. setFontSize(properties->getInt("fontSize"), states);
  1038. }
  1039. if (properties->exists("textColor"))
  1040. {
  1041. Vector4 textColor(0, 0, 0, 1);
  1042. properties->getColor("textColor", &textColor);
  1043. setTextColor(textColor, states);
  1044. }
  1045. if (properties->exists("textAlignment"))
  1046. {
  1047. setTextAlignment(Font::getJustify(properties->getString("textAlignment")), states);
  1048. }
  1049. if (properties->exists("rightToLeft"))
  1050. {
  1051. setTextRightToLeft(properties->getBool("rightToLeft"), states);
  1052. }
  1053. if (properties->exists("opacity"))
  1054. {
  1055. setOpacity(properties->getFloat("opacity"), states);
  1056. }
  1057. }
  1058. void Control::setImageList(Theme::ImageList* imageList, unsigned char states)
  1059. {
  1060. overrideStyle();
  1061. Theme::Style::Overlay* overlays[Theme::Style::OVERLAY_MAX] = { 0 };
  1062. getOverlays(states, overlays);
  1063. for (int i = 0; i < Theme::Style::OVERLAY_MAX - 1 && overlays[i]; ++i)
  1064. {
  1065. overlays[i]->setImageList(imageList);
  1066. }
  1067. _dirty = true;
  1068. }
  1069. void Control::setCursor(Theme::ThemeImage* cursor, unsigned char states)
  1070. {
  1071. overrideStyle();
  1072. Theme::Style::Overlay* overlays[Theme::Style::OVERLAY_MAX] = { 0 };
  1073. getOverlays(states, overlays);
  1074. for (int i = 0; i < Theme::Style::OVERLAY_MAX - 1 && overlays[i]; ++i)
  1075. {
  1076. overlays[i]->setCursor(cursor);
  1077. }
  1078. _dirty = true;
  1079. }
  1080. void Control::setSkin(Theme::Skin* skin, unsigned char states)
  1081. {
  1082. overrideStyle();
  1083. Theme::Style::Overlay* overlays[Theme::Style::OVERLAY_MAX] = { 0 };
  1084. getOverlays(states, overlays);
  1085. for (int i = 0; i < Theme::Style::OVERLAY_MAX - 1 && overlays[i]; ++i)
  1086. {
  1087. overlays[i]->setSkin(skin);
  1088. }
  1089. _dirty = true;
  1090. }
  1091. Theme::Skin* Control::getSkin(State state)
  1092. {
  1093. Theme::Style::Overlay* overlay = getOverlay(state);
  1094. GP_ASSERT(overlay);
  1095. return overlay->getSkin();
  1096. }
  1097. Control::Alignment Control::getAlignment(const char* alignment)
  1098. {
  1099. if (!alignment)
  1100. {
  1101. return Control::ALIGN_TOP_LEFT;
  1102. }
  1103. if (strcmp(alignment, "ALIGN_LEFT") == 0)
  1104. {
  1105. return Control::ALIGN_LEFT;
  1106. }
  1107. else if (strcmp(alignment, "ALIGN_HCENTER") == 0)
  1108. {
  1109. return Control::ALIGN_HCENTER;
  1110. }
  1111. else if (strcmp(alignment, "ALIGN_RIGHT") == 0)
  1112. {
  1113. return Control::ALIGN_RIGHT;
  1114. }
  1115. else if (strcmp(alignment, "ALIGN_TOP") == 0)
  1116. {
  1117. return Control::ALIGN_TOP;
  1118. }
  1119. else if (strcmp(alignment, "ALIGN_VCENTER") == 0)
  1120. {
  1121. return Control::ALIGN_VCENTER;
  1122. }
  1123. else if (strcmp(alignment, "ALIGN_BOTTOM") == 0)
  1124. {
  1125. return Control::ALIGN_BOTTOM;
  1126. }
  1127. else if (strcmp(alignment, "ALIGN_TOP_LEFT") == 0)
  1128. {
  1129. return Control::ALIGN_TOP_LEFT;
  1130. }
  1131. else if (strcmp(alignment, "ALIGN_VCENTER_LEFT") == 0)
  1132. {
  1133. return Control::ALIGN_VCENTER_LEFT;
  1134. }
  1135. else if (strcmp(alignment, "ALIGN_BOTTOM_LEFT") == 0)
  1136. {
  1137. return Control::ALIGN_BOTTOM_LEFT;
  1138. }
  1139. else if (strcmp(alignment, "ALIGN_TOP_HCENTER") == 0)
  1140. {
  1141. return Control::ALIGN_TOP_HCENTER;
  1142. }
  1143. else if (strcmp(alignment, "ALIGN_VCENTER_HCENTER") == 0)
  1144. {
  1145. return Control::ALIGN_VCENTER_HCENTER;
  1146. }
  1147. else if (strcmp(alignment, "ALIGN_BOTTOM_HCENTER") == 0)
  1148. {
  1149. return Control::ALIGN_BOTTOM_HCENTER;
  1150. }
  1151. else if (strcmp(alignment, "ALIGN_TOP_RIGHT") == 0)
  1152. {
  1153. return Control::ALIGN_TOP_RIGHT;
  1154. }
  1155. else if (strcmp(alignment, "ALIGN_VCENTER_RIGHT") == 0)
  1156. {
  1157. return Control::ALIGN_VCENTER_RIGHT;
  1158. }
  1159. else if (strcmp(alignment, "ALIGN_BOTTOM_RIGHT") == 0)
  1160. {
  1161. return Control::ALIGN_BOTTOM_RIGHT;
  1162. }
  1163. else
  1164. {
  1165. GP_ERROR("Failed to get corresponding control alignment for unsupported value '%s'.", alignment);
  1166. }
  1167. // Default.
  1168. return Control::ALIGN_TOP_LEFT;
  1169. }
  1170. }