UIWidget.cpp 26 KB

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