UIWidget.cpp 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209
  1. //
  2. // Copyright (c) 2014-2015, THUNDERBEAST GAMES LLC All rights reserved
  3. //
  4. // Permission is hereby granted, free of charge, to any person obtaining a copy
  5. // of this software and associated documentation files (the "Software"), to deal
  6. // in the Software without restriction, including without limitation the rights
  7. // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  8. // copies of the Software, and to permit persons to whom the Software is
  9. // furnished to do so, subject to the following conditions:
  10. //
  11. // The above copyright notice and this permission notice shall be included in
  12. // all copies or substantial portions of the Software.
  13. //
  14. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  19. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  20. // THE SOFTWARE.
  21. //
  22. #include "../IO/Log.h"
  23. #include "../Input/InputEvents.h"
  24. #include "UIEvents.h"
  25. #include "UI.h"
  26. #include "UIWidget.h"
  27. #include "UILayout.h"
  28. #include "UIFontDescription.h"
  29. #include "UIView.h"
  30. using namespace tb;
  31. namespace Atomic
  32. {
  33. UIWidget::UIWidget(Context* context, bool createWidget) : Object(context),
  34. widget_(0),
  35. preferredSize_(new UIPreferredSize()),
  36. multiTouch_(false)
  37. {
  38. if (createWidget)
  39. {
  40. widget_ = new TBWidget();
  41. widget_->SetDelegate(this);
  42. GetSubsystem<UI>()->WrapWidget(this, widget_);
  43. }
  44. }
  45. UIWidget::~UIWidget()
  46. {
  47. }
  48. void UIWidget::SetIsFocusable(bool value)
  49. {
  50. if (!widget_)
  51. return;
  52. widget_->SetIsFocusable(value);
  53. }
  54. bool UIWidget::Load(const String& filename)
  55. {
  56. UI* ui = GetSubsystem<UI>();
  57. if (!ui->LoadResourceFile(widget_ , filename))
  58. return false;
  59. VariantMap eventData;
  60. eventData[WidgetLoaded::P_WIDGET] = this;
  61. SendEvent(E_WIDGETLOADED, eventData);
  62. return true;
  63. }
  64. UIPreferredSize* UIWidget::GetPreferredSize()
  65. {
  66. // error
  67. if (!widget_)
  68. return preferredSize_;
  69. preferredSize_->SetFromTBPreferredSize(widget_->GetPreferredSize());
  70. return preferredSize_;
  71. }
  72. UIWidget* UIWidget::GetWidget(const String& id)
  73. {
  74. if (!widget_)
  75. return 0;
  76. TBWidget* child = widget_->GetWidgetByID(TBID(id.CString()));
  77. if (!child)
  78. return 0;
  79. UI* ui = GetSubsystem<UI>();
  80. return ui->WrapWidget(child);
  81. }
  82. void UIWidget::SetWidget(tb::TBWidget* widget)
  83. {
  84. widget_ = widget;
  85. widget_->SetDelegate(this);
  86. }
  87. /*
  88. enum SPECIAL_KEY
  89. {
  90. TB_KEY_UNDEFINED = 0,
  91. TB_KEY_UP, TB_KEY_DOWN, TB_KEY_LEFT, TB_KEY_RIGHT,
  92. TB_KEY_PAGE_UP, TB_KEY_PAGE_DOWN, TB_KEY_HOME, TB_KEY_END,
  93. TB_KEY_TAB, TB_KEY_BACKSPACE, TB_KEY_INSERT, TB_KEY_DELETE,
  94. TB_KEY_ENTER, TB_KEY_ESC,
  95. TB_KEY_F1, TB_KEY_F2, TB_KEY_F3, TB_KEY_F4, TB_KEY_F5, TB_KEY_F6,
  96. TB_KEY_F7, TB_KEY_F8, TB_KEY_F9, TB_KEY_F10, TB_KEY_F11, TB_KEY_F12
  97. };
  98. */
  99. void UIWidget::ConvertEvent(UIWidget *handler, UIWidget* target, const tb::TBWidgetEvent &ev, VariantMap& data)
  100. {
  101. UI* ui = GetSubsystem<UI>();
  102. String refid;
  103. ui->GetTBIDString(ev.ref_id, refid);
  104. int key = ev.key;
  105. if (ev.special_key)
  106. {
  107. switch (ev.special_key)
  108. {
  109. case TB_KEY_ENTER:
  110. key = KEY_RETURN;
  111. break;
  112. case TB_KEY_BACKSPACE:
  113. key = KEY_BACKSPACE;
  114. break;
  115. case TB_KEY_DELETE:
  116. key = KEY_DELETE;
  117. break;
  118. case TB_KEY_DOWN:
  119. key = KEY_DOWN;
  120. break;
  121. case TB_KEY_UP:
  122. key = KEY_UP;
  123. break;
  124. case TB_KEY_LEFT:
  125. key = KEY_LEFT;
  126. break;
  127. case TB_KEY_RIGHT:
  128. key = KEY_RIGHT;
  129. break;
  130. default:
  131. break;
  132. }
  133. }
  134. unsigned modifierKeys = 0;
  135. if( ev.special_key && TB_SHIFT)
  136. modifierKeys |= QUAL_SHIFT;
  137. if( ev.special_key && TB_CTRL)
  138. modifierKeys |= QUAL_CTRL;
  139. if( ev.special_key && TB_ALT)
  140. modifierKeys |= QUAL_ALT;
  141. using namespace WidgetEvent;
  142. data[P_HANDLER] = handler;
  143. data[P_TARGET] = target;
  144. data[P_TYPE] = (unsigned) ev.type;
  145. data[P_X] = ev.target_x;
  146. data[P_Y] = ev.target_y;
  147. data[P_DELTAX] = ev.delta_x;
  148. data[P_DELTAY] = ev.delta_y;
  149. data[P_COUNT] = ev.count;
  150. data[P_KEY] = key;
  151. data[P_SPECIALKEY] = (unsigned) ev.special_key;
  152. data[P_MODIFIERKEYS] = modifierKeys;
  153. data[P_REFID] = refid;
  154. data[P_TOUCH] = (unsigned) ev.touch;
  155. }
  156. void UIWidget::OnDelete()
  157. {
  158. VariantMap eventData;
  159. eventData[WidgetDeleted::P_WIDGET] = this;
  160. this->SendEvent(E_WIDGETDELETED, eventData);
  161. UnsubscribeFromAllEvents();
  162. if (widget_)
  163. {
  164. // if we don't have a UI subsystem, we are exiting
  165. UI* ui = GetSubsystem<UI>();
  166. if (ui)
  167. {
  168. ui->UnwrapWidget(widget_);
  169. }
  170. }
  171. widget_ = 0;
  172. }
  173. void UIWidget::AddChildAfter(UIWidget* child, UIWidget* otherChild)
  174. {
  175. if (!widget_ || !child || !child->widget_ || !otherChild || !otherChild->widget_)
  176. return;
  177. widget_->AddChildRelative(child->widget_, tb::WIDGET_Z_REL_AFTER, otherChild->widget_);
  178. }
  179. void UIWidget::AddChildBefore(UIWidget* child, UIWidget* otherChild)
  180. {
  181. if (!widget_ || !child || !child->widget_ || !otherChild || !otherChild->widget_)
  182. return;
  183. widget_->AddChildRelative(child->widget_, tb::WIDGET_Z_REL_BEFORE, otherChild->widget_);
  184. }
  185. void UIWidget::AddChild(UIWidget* child)
  186. {
  187. if (!widget_ || !child || !child->widget_)
  188. return;
  189. widget_->AddChild(child->widget_);
  190. }
  191. void UIWidget::AddChildRelative(UIWidget* child, UI_WIDGET_Z_REL z, UIWidget* reference)
  192. {
  193. if (!widget_ || !child || !child->widget_ || !reference || !reference->widget_)
  194. return;
  195. widget_->AddChildRelative(child->widget_, (WIDGET_Z_REL) z, reference->widget_);
  196. }
  197. String UIWidget::GetText()
  198. {
  199. if (!widget_)
  200. return String::EMPTY;
  201. return widget_->GetText().CStr();
  202. }
  203. void UIWidget::SetText(const String& text)
  204. {
  205. if (!widget_)
  206. return;
  207. widget_->SetText(text.CString());
  208. }
  209. void UIWidget::SetGravity(UI_GRAVITY gravity)
  210. {
  211. if (!widget_)
  212. return;
  213. widget_->SetGravity((WIDGET_GRAVITY) gravity);
  214. }
  215. void UIWidget::SetAxis(UI_AXIS axis)
  216. {
  217. if (!widget_)
  218. return;
  219. widget_->SetAxis((AXIS) axis);
  220. }
  221. bool UIWidget::IsAncestorOf(UIWidget* widget)
  222. {
  223. if (!widget_ || !widget || !widget->widget_)
  224. return false;
  225. return widget_->IsAncestorOf(widget->widget_);
  226. }
  227. void UIWidget::SetPosition(int x, int y)
  228. {
  229. if (!widget_)
  230. return;
  231. widget_->SetPosition(TBPoint(x, y));
  232. }
  233. IntRect UIWidget::GetRect()
  234. {
  235. IntRect rect(0, 0, 0, 0);
  236. if (!widget_)
  237. return rect;
  238. tb::TBRect tbrect = widget_->GetRect();
  239. rect.top_ = tbrect.y;
  240. rect.left_ = tbrect.x;
  241. rect.right_ = tbrect.x + tbrect.w;
  242. rect.bottom_ = tbrect.y + tbrect.h;
  243. return rect;
  244. }
  245. void UIWidget::SetRect(IntRect rect)
  246. {
  247. if (!widget_)
  248. return;
  249. tb::TBRect tbrect;
  250. tbrect.y = rect.top_;
  251. tbrect.x = rect.left_;
  252. tbrect.w = rect.right_ - rect.left_;
  253. tbrect.h = rect.bottom_ - rect.top_;
  254. widget_->SetRect(tbrect);
  255. }
  256. bool UIWidget::SetSize(int width, int height)
  257. {
  258. if (!widget_)
  259. return false;
  260. widget_->SetSize(width, height);
  261. return true;
  262. }
  263. void UIWidget::Invalidate()
  264. {
  265. if (!widget_)
  266. return;
  267. widget_->Invalidate();
  268. }
  269. void UIWidget::Center()
  270. {
  271. if (!widget_)
  272. return;
  273. TBRect rect = widget_->GetRect();
  274. TBWidget* root = widget_->GetParent();
  275. if (!root)
  276. {
  277. UI* ui = GetSubsystem<UI>();
  278. root = ui->GetRootWidget();
  279. }
  280. TBRect bounds(0, 0, root->GetRect().w, root->GetRect().h);
  281. widget_->SetRect(rect.CenterIn(bounds).MoveIn(bounds).Clip(bounds));
  282. }
  283. UIWidget* UIWidget::GetParent()
  284. {
  285. if (!widget_)
  286. return 0;
  287. TBWidget* parent = widget_->GetParent();
  288. if (!parent)
  289. return 0;
  290. UI* ui = GetSubsystem<UI>();
  291. return ui->WrapWidget(parent);
  292. }
  293. UIWidget* UIWidget::GetContentRoot()
  294. {
  295. if (!widget_)
  296. return 0;
  297. TBWidget* root = widget_->GetContentRoot();
  298. if (!root)
  299. return 0;
  300. UI* ui = GetSubsystem<UI>();
  301. return ui->WrapWidget(root);
  302. }
  303. void UIWidget::Die()
  304. {
  305. if (!widget_)
  306. return;
  307. // clear delegate
  308. widget_->SetDelegate(NULL);
  309. // explictly die (can trigger an animation)
  310. widget_->Die();
  311. // call OnDelete, which unwraps the widget and does some bookkeeping
  312. OnDelete();
  313. }
  314. void UIWidget::SetLayoutParams(UILayoutParams* params)
  315. {
  316. if (!widget_)
  317. return;
  318. widget_->SetLayoutParams(*(params->GetTBLayoutParams()));
  319. }
  320. void UIWidget::SetFontDescription(UIFontDescription* fd)
  321. {
  322. if (!widget_)
  323. return;
  324. widget_->SetFontDescription(*(fd->GetTBFontDescription()));
  325. }
  326. void UIWidget::SetFontId(const String& fontId)
  327. {
  328. if (!widget_)
  329. return;
  330. tb::TBFontDescription fd(widget_->GetFontDescription());
  331. fd.SetID(fontId.CString());
  332. widget_->SetFontDescription(fd);
  333. }
  334. String UIWidget::GetFontId()
  335. {
  336. if (!widget_)
  337. return "";
  338. tb::TBFontDescription fd(widget_->GetFontDescription());
  339. if (!g_font_manager->HasFontFace(fd))
  340. {
  341. return "";
  342. }
  343. return g_font_manager->GetFontInfo(fd.GetID())->GetName();
  344. }
  345. void UIWidget::SetFontSize(int size)
  346. {
  347. if (!widget_)
  348. return;
  349. tb::TBFontDescription fd(widget_->GetFontDescription());
  350. fd.SetSize(size);
  351. widget_->SetFontDescription(fd);
  352. }
  353. int UIWidget::GetFontSize()
  354. {
  355. if (!widget_)
  356. return 0;
  357. tb::TBFontDescription fd(widget_->GetFontDescription());
  358. return fd.GetSize();
  359. }
  360. void UIWidget::SetLayoutWidth(int width)
  361. {
  362. if (!widget_)
  363. return;
  364. tb::LayoutParams lp;
  365. const tb::LayoutParams *oldLp(widget_->GetLayoutParams());
  366. if (oldLp)
  367. lp = *oldLp;
  368. lp.SetWidth(width);
  369. widget_->SetLayoutParams(lp);
  370. }
  371. int UIWidget::GetLayoutWidth()
  372. {
  373. if (!widget_)
  374. return tb::LayoutParams::UNSPECIFIED;
  375. const tb::LayoutParams *lp(widget_->GetLayoutParams());
  376. if (!lp)
  377. return tb::LayoutParams::UNSPECIFIED;
  378. return lp->pref_w;
  379. }
  380. void UIWidget::SetLayoutHeight(int height)
  381. {
  382. if (!widget_)
  383. return;
  384. tb::LayoutParams lp;
  385. const tb::LayoutParams *oldLp(widget_->GetLayoutParams());
  386. if (oldLp)
  387. lp = *oldLp;
  388. lp.SetHeight(height);
  389. widget_->SetLayoutParams(lp);
  390. }
  391. int UIWidget::GetLayoutHeight()
  392. {
  393. if (!widget_)
  394. return tb::LayoutParams::UNSPECIFIED;
  395. const tb::LayoutParams *lp(widget_->GetLayoutParams());
  396. if (!lp)
  397. return tb::LayoutParams::UNSPECIFIED;
  398. return lp->pref_h;
  399. }
  400. void UIWidget::SetLayoutPrefWidth(int width)
  401. {
  402. if (!widget_)
  403. return;
  404. tb::LayoutParams lp;
  405. const tb::LayoutParams *oldLp(widget_->GetLayoutParams());
  406. if (oldLp)
  407. lp = *oldLp;
  408. lp.pref_w = width;
  409. widget_->SetLayoutParams(lp);
  410. }
  411. int UIWidget::GetLayoutPrefWidth()
  412. {
  413. if (!widget_)
  414. return tb::LayoutParams::UNSPECIFIED;
  415. const tb::LayoutParams *lp(widget_->GetLayoutParams());
  416. if (!lp)
  417. return tb::LayoutParams::UNSPECIFIED;
  418. return lp->pref_w;
  419. }
  420. void UIWidget::SetLayoutPrefHeight(int height)
  421. {
  422. if (!widget_)
  423. return;
  424. tb::LayoutParams lp;
  425. const tb::LayoutParams *oldLp(widget_->GetLayoutParams());
  426. if (oldLp)
  427. lp = *oldLp;
  428. lp.pref_h = height;
  429. widget_->SetLayoutParams(lp);
  430. }
  431. int UIWidget::GetLayoutPrefHeight()
  432. {
  433. if (!widget_)
  434. return tb::LayoutParams::UNSPECIFIED;
  435. const tb::LayoutParams *lp(widget_->GetLayoutParams());
  436. if (!lp)
  437. return tb::LayoutParams::UNSPECIFIED;
  438. return lp->pref_h;
  439. }
  440. void UIWidget::SetLayoutMinWidth(int width)
  441. {
  442. if (!widget_)
  443. return;
  444. tb::LayoutParams lp;
  445. const tb::LayoutParams *oldLp(widget_->GetLayoutParams());
  446. if (oldLp)
  447. lp = *oldLp;
  448. lp.min_w = width;
  449. widget_->SetLayoutParams(lp);
  450. }
  451. int UIWidget::GetLayoutMinWidth()
  452. {
  453. if (!widget_)
  454. return tb::LayoutParams::UNSPECIFIED;
  455. const tb::LayoutParams *lp(widget_->GetLayoutParams());
  456. if (!lp)
  457. return tb::LayoutParams::UNSPECIFIED;
  458. return lp->min_w;
  459. }
  460. void UIWidget::SetLayoutMinHeight(int height)
  461. {
  462. if (!widget_)
  463. return;
  464. tb::LayoutParams lp;
  465. const tb::LayoutParams *oldLp(widget_->GetLayoutParams());
  466. if (oldLp)
  467. lp = *oldLp;
  468. lp.min_h = height;
  469. widget_->SetLayoutParams(lp);
  470. }
  471. int UIWidget::GetLayoutMinHeight()
  472. {
  473. if (!widget_)
  474. return tb::LayoutParams::UNSPECIFIED;
  475. const tb::LayoutParams *lp(widget_->GetLayoutParams());
  476. if (!lp)
  477. return tb::LayoutParams::UNSPECIFIED;
  478. return lp->min_h;
  479. }
  480. void UIWidget::SetLayoutMaxWidth(int width)
  481. {
  482. if (!widget_)
  483. return;
  484. tb::LayoutParams lp;
  485. const tb::LayoutParams *oldLp(widget_->GetLayoutParams());
  486. if (oldLp)
  487. lp = *oldLp;
  488. lp.max_w = width;
  489. widget_->SetLayoutParams(lp);
  490. }
  491. int UIWidget::GetLayoutMaxWidth()
  492. {
  493. if (!widget_)
  494. return tb::LayoutParams::UNSPECIFIED;
  495. const tb::LayoutParams *lp(widget_->GetLayoutParams());
  496. if (!lp)
  497. return tb::LayoutParams::UNSPECIFIED;
  498. return lp->max_w;
  499. }
  500. void UIWidget::SetLayoutMaxHeight(int height)
  501. {
  502. if (!widget_)
  503. return;
  504. tb::LayoutParams lp;
  505. const tb::LayoutParams *oldLp(widget_->GetLayoutParams());
  506. if (oldLp)
  507. lp = *oldLp;
  508. lp.max_h = height;
  509. widget_->SetLayoutParams(lp);
  510. }
  511. int UIWidget::GetLayoutMaxHeight()
  512. {
  513. if (!widget_)
  514. return tb::LayoutParams::UNSPECIFIED;
  515. const tb::LayoutParams *lp(widget_->GetLayoutParams());
  516. if (!lp)
  517. return tb::LayoutParams::UNSPECIFIED;
  518. return lp->max_h;
  519. }
  520. void UIWidget::SetOpacity(float opacity)
  521. {
  522. if (!widget_)
  523. return;
  524. widget_->SetOpacity(opacity);
  525. }
  526. float UIWidget::GetOpacity()
  527. {
  528. if (!widget_)
  529. return -0.0f;
  530. return widget_->GetOpacity();
  531. }
  532. void UIWidget::SetAutoOpacity(float autoOpacity)
  533. {
  534. if (!widget_)
  535. return;
  536. if (autoOpacity == 0.0f)
  537. {
  538. widget_->SetOpacity(autoOpacity);
  539. widget_->SetVisibilility(tb::WIDGET_VISIBILITY_INVISIBLE);
  540. }
  541. else
  542. {
  543. widget_->SetVisibilility(tb::WIDGET_VISIBILITY_VISIBLE);
  544. widget_->SetOpacity(autoOpacity);
  545. }
  546. }
  547. float UIWidget::GetAutoOpacity()
  548. {
  549. if (!widget_)
  550. return -0.0f;
  551. float autoOpacity(widget_->GetOpacity());
  552. if (autoOpacity == 0.0f)
  553. {
  554. if (widget_->GetVisibility() == tb::WIDGET_VISIBILITY_VISIBLE)
  555. return 0.0001f; // Don't say that it's completly invisible.
  556. }
  557. else
  558. {
  559. if (widget_->GetVisibility() != tb::WIDGET_VISIBILITY_VISIBLE)
  560. return 0.0f; // Say it's invisible.
  561. }
  562. return autoOpacity;
  563. }
  564. void UIWidget::DeleteAllChildren()
  565. {
  566. if (!widget_)
  567. return;
  568. widget_->DeleteAllChildren();
  569. }
  570. void UIWidget::SetSkinBg(const String& id)
  571. {
  572. if (!widget_)
  573. return;
  574. widget_->SetSkinBg(TBIDC(id.CString()));
  575. }
  576. void UIWidget::Remove()
  577. {
  578. if (!widget_ || !widget_->GetParent())
  579. return;
  580. widget_->GetParent()->RemoveChild(widget_);
  581. }
  582. void UIWidget::RemoveChild(UIWidget* child, bool cleanup)
  583. {
  584. if (!widget_ || !child)
  585. return;
  586. TBWidget* childw = child->GetInternalWidget();
  587. if (!childw)
  588. return;
  589. widget_->RemoveChild(childw);
  590. if (cleanup)
  591. delete childw;
  592. }
  593. const String& UIWidget::GetId()
  594. {
  595. if (!widget_ || !widget_->GetID())
  596. {
  597. if (id_.Length())
  598. id_.Clear();
  599. return id_;
  600. }
  601. if (id_.Length())
  602. return id_;
  603. UI* ui = GetSubsystem<UI>();
  604. ui->GetTBIDString(widget_->GetID(), id_);
  605. return id_;
  606. }
  607. void UIWidget::SetId(const String& id)
  608. {
  609. if (!widget_)
  610. {
  611. if (id_.Length())
  612. id_.Clear();
  613. return;
  614. }
  615. id_ = id;
  616. widget_->SetID(TBIDC(id.CString()));
  617. }
  618. void UIWidget::SetState(UI_WIDGET_STATE state, bool on)
  619. {
  620. if (!widget_)
  621. return;
  622. widget_->SetState((WIDGET_STATE) state, on);
  623. }
  624. void UIWidget::SetFocus()
  625. {
  626. if (!widget_)
  627. return;
  628. widget_->SetFocus(WIDGET_FOCUS_REASON_UNKNOWN);
  629. }
  630. bool UIWidget::GetFocus() const
  631. {
  632. if (!widget_)
  633. return false;
  634. return widget_->GetIsFocused();
  635. }
  636. void UIWidget::SetFocusRecursive()
  637. {
  638. if (!widget_)
  639. return;
  640. widget_->SetFocusRecursive(WIDGET_FOCUS_REASON_UNKNOWN);
  641. }
  642. void UIWidget::SetVisibility(UI_WIDGET_VISIBILITY visibility)
  643. {
  644. if (!widget_)
  645. return;
  646. widget_->SetVisibilility((WIDGET_VISIBILITY) visibility);
  647. }
  648. UI_WIDGET_VISIBILITY UIWidget::GetVisibility()
  649. {
  650. if (!widget_)
  651. return UI_WIDGET_VISIBILITY_GONE;
  652. return (UI_WIDGET_VISIBILITY) widget_->GetVisibility();
  653. }
  654. UIWidget* UIWidget::GetFirstChild()
  655. {
  656. if (!widget_)
  657. return NULL;
  658. return GetSubsystem<UI>()->WrapWidget(widget_->GetFirstChild());
  659. }
  660. UIWidget* UIWidget::GetNext()
  661. {
  662. if (!widget_)
  663. return NULL;
  664. return GetSubsystem<UI>()->WrapWidget(widget_->GetNext());
  665. }
  666. void UIWidget::SetValue(double value)
  667. {
  668. if (!widget_)
  669. return;
  670. widget_->SetValueDouble(value);
  671. }
  672. double UIWidget::GetValue()
  673. {
  674. if (!widget_)
  675. return 0.0;
  676. return widget_->GetValueDouble();
  677. }
  678. void UIWidget::Enable()
  679. {
  680. if (!widget_)
  681. return;
  682. widget_->SetState(WIDGET_STATE_DISABLED, false);
  683. }
  684. void UIWidget::Disable()
  685. {
  686. if (!widget_)
  687. return;
  688. widget_->SetState(WIDGET_STATE_DISABLED, true);
  689. }
  690. bool UIWidget::GetState(UI_WIDGET_STATE state)
  691. {
  692. if (!widget_)
  693. return false;
  694. return widget_->GetState((WIDGET_STATE) state);
  695. }
  696. void UIWidget::SetStateRaw(UI_WIDGET_STATE state)
  697. {
  698. if (!widget_)
  699. return;
  700. widget_->SetStateRaw((WIDGET_STATE) state);
  701. }
  702. UI_WIDGET_STATE UIWidget::GetStateRaw()
  703. {
  704. if (!widget_)
  705. return UI_WIDGET_STATE_NONE;
  706. return (UI_WIDGET_STATE) widget_->GetStateRaw();
  707. }
  708. UIView* UIWidget::GetView()
  709. {
  710. if (!widget_)
  711. return 0;
  712. if (GetType() == UIView::GetTypeStatic())
  713. return (UIView*) this;
  714. TBWidget* tbw = widget_->GetParent();
  715. while(tbw)
  716. {
  717. TBWidgetDelegate* delegate = tbw->GetDelegate();
  718. if (delegate)
  719. {
  720. UIWidget* d = (UIWidget*) delegate;
  721. if (d->GetType() == UIView::GetTypeStatic())
  722. return (UIView*) d;
  723. }
  724. tbw = tbw->GetParent();
  725. }
  726. return 0;
  727. }
  728. void UIWidget::OnFocusChanged(bool focused)
  729. {
  730. using namespace WidgetFocusChanged;
  731. VariantMap eventData;
  732. eventData[P_WIDGET] = this;
  733. eventData[P_FOCUSED] = focused;
  734. SendEvent(E_WIDGETFOCUSCHANGED, eventData);
  735. }
  736. bool UIWidget::OnEvent(const tb::TBWidgetEvent &ev)
  737. {
  738. UI* ui = GetSubsystem<UI>();
  739. if ((ev.type == EVENT_TYPE_CHANGED && !ui->GetBlockChangedEvents()) || ev.type == EVENT_TYPE_KEY_UP)
  740. {
  741. if (!ev.target || ui->IsWidgetWrapped(ev.target))
  742. {
  743. VariantMap eventData;
  744. ConvertEvent(this, ui->WrapWidget(ev.target), ev, eventData);
  745. SendEvent(E_WIDGETEVENT, eventData);
  746. if (eventData[WidgetEvent::P_HANDLED].GetBool())
  747. return true;
  748. }
  749. }
  750. else if (ev.type == EVENT_TYPE_RIGHT_POINTER_UP)
  751. {
  752. if (!ev.target || ui->IsWidgetWrapped(ev.target))
  753. {
  754. VariantMap eventData;
  755. ConvertEvent(this, ui->WrapWidget(ev.target), ev, eventData);
  756. SendEvent(E_WIDGETEVENT, eventData);
  757. if (eventData[WidgetEvent::P_HANDLED].GetBool())
  758. return true;
  759. }
  760. }
  761. else if (ev.type == EVENT_TYPE_POINTER_DOWN)
  762. {
  763. if (!ev.target || ui->IsWidgetWrapped(ev.target))
  764. {
  765. VariantMap eventData;
  766. ConvertEvent(this, ui->WrapWidget(ev.target), ev, eventData);
  767. SendEvent(E_WIDGETEVENT, eventData);
  768. if (eventData[WidgetEvent::P_HANDLED].GetBool())
  769. return true;
  770. }
  771. }
  772. else if (ev.type == EVENT_TYPE_SHORTCUT)
  773. {
  774. if (!ev.target || ui->IsWidgetWrapped(ev.target))
  775. {
  776. VariantMap eventData;
  777. ConvertEvent(this, ui->WrapWidget(ev.target), ev, eventData);
  778. SendEvent(E_WIDGETEVENT, eventData);
  779. if (eventData[WidgetEvent::P_HANDLED].GetBool())
  780. return true;
  781. }
  782. }
  783. else if (ev.type == EVENT_TYPE_TAB_CHANGED)
  784. {
  785. if (!ev.target || ui->IsWidgetWrapped(ev.target))
  786. {
  787. VariantMap eventData;
  788. ConvertEvent(this, ui->WrapWidget(ev.target), ev, eventData);
  789. SendEvent(E_WIDGETEVENT, eventData);
  790. if (eventData[WidgetEvent::P_HANDLED].GetBool())
  791. return true;
  792. }
  793. }
  794. else if (ev.type == EVENT_TYPE_CLICK)
  795. {
  796. if (ev.target && ev.target->GetID() == TBID("__popup-menu"))
  797. {
  798. // popup menu
  799. if (JSGetHeapPtr())
  800. {
  801. VariantMap eventData;
  802. eventData[PopupMenuSelect::P_BUTTON] = this;
  803. String id;
  804. ui->GetTBIDString(ev.ref_id, id);
  805. eventData[PopupMenuSelect::P_REFID] = id;
  806. SendEvent(E_POPUPMENUSELECT, eventData);
  807. }
  808. return true;
  809. }
  810. else
  811. {
  812. if (!ev.target || ui->IsWidgetWrapped(ev.target))
  813. {
  814. VariantMap eventData;
  815. ConvertEvent(this, ui->WrapWidget(ev.target), ev, eventData);
  816. SendEvent(E_WIDGETEVENT, eventData);
  817. if (eventData[WidgetEvent::P_HANDLED].GetBool())
  818. return true;
  819. }
  820. }
  821. }
  822. if (ev.type == EVENT_TYPE_CUSTOM)
  823. {
  824. if (!ev.target || ui->IsWidgetWrapped(ev.target))
  825. {
  826. VariantMap eventData;
  827. ConvertEvent(this, ui->WrapWidget(ev.target), ev, eventData);
  828. SendEvent(E_WIDGETEVENT, eventData);
  829. if (eventData[WidgetEvent::P_HANDLED].GetBool())
  830. return true;
  831. }
  832. }
  833. return false;
  834. }
  835. bool UIWidget::GetCaptured()
  836. {
  837. if (!widget_)
  838. return false;
  839. return widget_->IsCaptured();
  840. }
  841. void UIWidget::SetCapturing(bool capturing)
  842. {
  843. if (!widget_)
  844. return;
  845. widget_->SetCapturing(capturing);
  846. }
  847. bool UIWidget::GetCapturing()
  848. {
  849. if (!widget_)
  850. return false;
  851. return widget_->GetCapturing();
  852. }
  853. void UIWidget::InvalidateLayout()
  854. {
  855. if (!widget_)
  856. return;
  857. widget_->InvalidateLayout(tb::TBWidget::INVALIDATE_LAYOUT_TARGET_ONLY);
  858. }
  859. void UIWidget::InvokeShortcut(const String& shortcut)
  860. {
  861. TBWidgetEvent ev(EVENT_TYPE_SHORTCUT);
  862. ev.ref_id = TBIDC(shortcut.CString());
  863. widget_->OnEvent(ev);
  864. }
  865. bool UIWidget::GetShortened()
  866. {
  867. if (!widget_)
  868. return false;
  869. return widget_->GetShortened();
  870. }
  871. void UIWidget::SetShortened(bool shortened)
  872. {
  873. if (!widget_)
  874. return;
  875. widget_->SetShortened(shortened);
  876. }
  877. String UIWidget::GetTooltip()
  878. {
  879. if (!widget_)
  880. return String::EMPTY;
  881. return widget_->GetTooltip().CStr();
  882. }
  883. void UIWidget::SetTooltip(const String& tooltip)
  884. {
  885. if (!widget_)
  886. return;
  887. widget_->SetTooltip(tooltip.CString());
  888. }
  889. IntVector2 UIWidget::ConvertToRoot(const IntVector2 position) const
  890. {
  891. IntVector2 result = position;
  892. if (widget_)
  893. widget_->ConvertToRoot(result.x_, result.y_);
  894. return result;
  895. }
  896. IntVector2 UIWidget::ConvertFromRoot(const IntVector2 position) const
  897. {
  898. IntVector2 result = position;
  899. if (widget_)
  900. widget_->ConvertFromRoot(result.x_, result.y_);
  901. return result;
  902. }
  903. }