UIWidget.cpp 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510
  1. //--player --editor-resource-paths "/Users/josh/Dev/atomic/AtomicGameEngine/Data/AtomicPlayer/Resources/CoreData!/Users/josh/Dev/atomic/AtomicGameEngine/Data/AtomicPlayer/Resources/PlayerData!/Users/josh/Dev/atomic/AtomicExamples/UIExample/Resources"
  2. #include "../IO/Log.h"
  3. #include "UIEvents.h"
  4. #include "UI.h"
  5. #include "UIWidget.h"
  6. #include "UILayout.h"
  7. #include "UIFontDescription.h"
  8. using namespace tb;
  9. namespace Atomic
  10. {
  11. UIWidget::UIWidget(Context* context, bool createWidget) : Object(context),
  12. widget_(0)
  13. {
  14. AddRef();
  15. if (createWidget)
  16. {
  17. widget_ = new TBWidget();
  18. widget_->SetDelegate(this);
  19. GetSubsystem<UI>()->WrapWidget(this, widget_);
  20. }
  21. }
  22. UIWidget::~UIWidget()
  23. {
  24. }
  25. void UIWidget::SetIsFocusable(bool value)
  26. {
  27. if (!widget_)
  28. return;
  29. widget_->SetIsFocusable(value);
  30. }
  31. bool UIWidget::Load(const String& filename)
  32. {
  33. UI* ui = GetSubsystem<UI>();
  34. if (!ui->LoadResourceFile(widget_ , filename))
  35. return false;
  36. VariantMap eventData;
  37. eventData[WidgetLoaded::P_WIDGET] = this;
  38. SendEvent(E_WIDGETLOADED, eventData);
  39. return true;
  40. }
  41. UIWidget* UIWidget::GetWidget(const String& id)
  42. {
  43. if (!widget_)
  44. return 0;
  45. TBWidget* child = widget_->GetWidgetByID(TBID(id.CString()));
  46. if (!child)
  47. return 0;
  48. UI* ui = GetSubsystem<UI>();
  49. return ui->WrapWidget(child);
  50. }
  51. void UIWidget::SetWidget(tb::TBWidget* widget)
  52. {
  53. widget_ = widget;
  54. widget_->SetDelegate(this);
  55. }
  56. void UIWidget::ConvertEvent(UIWidget *handler, UIWidget* target, const tb::TBWidgetEvent &ev, VariantMap& data)
  57. {
  58. UI* ui = GetSubsystem<UI>();
  59. String id;
  60. ui->GetTBIDString(ev.ref_id, id);
  61. using namespace WidgetEvent;
  62. data[P_HANDLER] = handler;
  63. data[P_TARGET] = target;
  64. data[P_TYPE] = (unsigned) ev.type;
  65. data[P_X] = ev.target_x;
  66. data[P_Y] = ev.target_y;
  67. data[P_DELTAX] = ev.delta_x;
  68. data[P_DELTAY] = ev.delta_y;
  69. data[P_COUNT] = ev.count;
  70. data[P_KEY] = ev.key;
  71. data[P_SPECIALKEY] = (unsigned) ev.special_key;
  72. data[P_MODIFIERKEYS] = (unsigned) ev.modifierkeys;
  73. data[P_REFID] = id;
  74. data[P_TOUCH] = (unsigned) ev.touch;
  75. }
  76. void UIWidget::OnDelete()
  77. {
  78. if (widget_)
  79. {
  80. // if we don't have a UI subsystem, we are exiting
  81. UI* ui = GetSubsystem<UI>();
  82. if (ui)
  83. ui->UnwrapWidget(widget_);
  84. }
  85. widget_ = 0;
  86. VariantMap eventData;
  87. eventData[WidgetDeleted::P_WIDGET] = this;
  88. SendEvent(E_WIDGETDELETED, eventData);
  89. ReleaseRef();
  90. }
  91. void UIWidget::AddChild(UIWidget* child)
  92. {
  93. if (!widget_ || !child->widget_)
  94. return;
  95. widget_->AddChild(child->widget_);
  96. }
  97. void UIWidget::SetText(const String& text)
  98. {
  99. if (!widget_)
  100. return;
  101. widget_->SetText(text.CString());
  102. }
  103. void UIWidget::SetGravity(/*WIDGET_GRAVITY*/ unsigned gravity)
  104. {
  105. if (!widget_)
  106. return;
  107. widget_->SetGravity((WIDGET_GRAVITY) gravity);
  108. }
  109. void UIWidget::SetPosition(int x, int y)
  110. {
  111. if (!widget_)
  112. return;
  113. widget_->SetPosition(TBPoint(x, y));
  114. }
  115. IntRect UIWidget::GetRect()
  116. {
  117. IntRect rect(0, 0, 0, 0);
  118. if (!widget_)
  119. return rect;
  120. tb::TBRect tbrect = widget_->GetRect();
  121. rect.top_ = tbrect.y;
  122. rect.left_ = tbrect.x;
  123. rect.right_ = tbrect.x + tbrect.w;
  124. rect.bottom_ = tbrect.y + tbrect.h;
  125. return rect;
  126. }
  127. void UIWidget::SetRect(IntRect rect)
  128. {
  129. if (!widget_)
  130. return;
  131. tb::TBRect tbrect;
  132. tbrect.y = rect.top_;
  133. tbrect.x = rect.left_;
  134. tbrect.w = rect.right_ - rect.left_;
  135. tbrect.h = rect.bottom_ - rect.top_;
  136. widget_->SetRect(tbrect);
  137. }
  138. void UIWidget::SetSize(int width, int height)
  139. {
  140. if (!widget_)
  141. return;
  142. widget_->SetSize(width, height);
  143. }
  144. void UIWidget::Invalidate()
  145. {
  146. if (!widget_)
  147. return;
  148. widget_->Invalidate();
  149. }
  150. void UIWidget::Center()
  151. {
  152. if (!widget_)
  153. return;
  154. // this should center on parent widget, not root
  155. UI* ui = GetSubsystem<UI>();
  156. TBRect rect = widget_->GetRect();
  157. TBWidget* root = ui->GetRootWidget();
  158. TBRect bounds(0, 0, root->GetRect().w, root->GetRect().h);
  159. widget_->SetRect(rect.CenterIn(bounds).MoveIn(bounds).Clip(bounds));
  160. }
  161. UIWidget* UIWidget::GetParent()
  162. {
  163. if (!widget_)
  164. return 0;
  165. TBWidget* parent = widget_->GetParent();
  166. if (!parent)
  167. return 0;
  168. UI* ui = GetSubsystem<UI>();
  169. return ui->WrapWidget(parent);
  170. }
  171. UIWidget* UIWidget::GetContentRoot()
  172. {
  173. if (!widget_)
  174. return 0;
  175. TBWidget* root = widget_->GetContentRoot();
  176. if (!root)
  177. return 0;
  178. UI* ui = GetSubsystem<UI>();
  179. return ui->WrapWidget(root);
  180. }
  181. void UIWidget::Die()
  182. {
  183. if (!widget_)
  184. return;
  185. // clear delegate
  186. widget_->SetDelegate(NULL);
  187. // explictly die (can trigger an animation)
  188. widget_->Die();
  189. // call OnDelete, which unwraps the widget and does some bookkeeping
  190. OnDelete();
  191. }
  192. void UIWidget::SetLayoutParams(UILayoutParams* params)
  193. {
  194. if (!widget_)
  195. return;
  196. widget_->SetLayoutParams(*(params->GetTBLayoutParams()));
  197. }
  198. void UIWidget::SetFontDescription(UIFontDescription* fd)
  199. {
  200. if (!widget_)
  201. return;
  202. widget_->SetFontDescription(*(fd->GetTBFontDescription()));
  203. }
  204. void UIWidget::DeleteAllChildren()
  205. {
  206. if (!widget_)
  207. return;
  208. widget_->DeleteAllChildren();
  209. }
  210. void UIWidget::SetSkinBg(const String& id)
  211. {
  212. if (!widget_)
  213. return;
  214. widget_->SetSkinBg(TBIDC(id.CString()));
  215. }
  216. void UIWidget::RemoveChild(UIWidget* child, bool cleanup)
  217. {
  218. if (!widget_ || !child)
  219. return;
  220. TBWidget* childw = child->GetInternalWidget();
  221. if (!childw)
  222. return;
  223. widget_->RemoveChild(childw);
  224. if (cleanup)
  225. delete childw;
  226. }
  227. const String& UIWidget::GetId()
  228. {
  229. if (!widget_ || !widget_->GetID())
  230. {
  231. if (id_.Length())
  232. id_.Clear();
  233. return id_;
  234. }
  235. if (id_.Length())
  236. return id_;
  237. UI* ui = GetSubsystem<UI>();
  238. ui->GetTBIDString(widget_->GetID(), id_);
  239. return id_;
  240. }
  241. void UIWidget::SetId(const String& id)
  242. {
  243. if (!widget_)
  244. {
  245. if (id_.Length())
  246. id_.Clear();
  247. return;
  248. }
  249. id_ = id;
  250. widget_->SetID(TBIDC(id.CString()));
  251. }
  252. void UIWidget::SetState(/*WIDGET_STATE*/ unsigned state, bool on)
  253. {
  254. if (!widget_)
  255. return;
  256. widget_->SetState((WIDGET_STATE) state, on);
  257. }
  258. void UIWidget::SetFocus()
  259. {
  260. if (!widget_)
  261. return;
  262. widget_->SetFocus(WIDGET_FOCUS_REASON_UNKNOWN);
  263. }
  264. void UIWidget::SetVisibility(/*WIDGET_VISIBILITY*/ unsigned visibility)
  265. {
  266. if (!widget_)
  267. return;
  268. widget_->SetVisibilility((WIDGET_VISIBILITY) visibility);
  269. }
  270. UIWidget* UIWidget::GetFirstChild()
  271. {
  272. if (!widget_)
  273. return NULL;
  274. return GetSubsystem<UI>()->WrapWidget(widget_->GetFirstChild());
  275. }
  276. UIWidget* UIWidget::GetNext()
  277. {
  278. if (!widget_)
  279. return NULL;
  280. return GetSubsystem<UI>()->WrapWidget(widget_->GetNext());
  281. }
  282. void UIWidget::SetValue(double value)
  283. {
  284. if (!widget_)
  285. return;
  286. widget_->SetValueDouble(value);
  287. }
  288. double UIWidget::GetValue()
  289. {
  290. if (!widget_)
  291. return 0.0;
  292. return widget_->GetValueDouble();
  293. }
  294. bool UIWidget::GetState(/*WIDGET_STATE*/ unsigned state)
  295. {
  296. if (!widget_)
  297. return false;
  298. return widget_->GetState((WIDGET_STATE) state);
  299. }
  300. void UIWidget::SetStateRaw(/*WIDGET_STATE*/ unsigned state)
  301. {
  302. if (!widget_)
  303. return;
  304. widget_->SetStateRaw((WIDGET_STATE) state);
  305. }
  306. /*WIDGET_STATE*/ unsigned UIWidget::GetStateRaw()
  307. {
  308. if (!widget_)
  309. return false;
  310. return (unsigned) widget_->GetStateRaw();
  311. }
  312. bool UIWidget::OnEvent(const tb::TBWidgetEvent &ev)
  313. {
  314. UI* ui = GetSubsystem<UI>();
  315. if (ev.type == EVENT_TYPE_CHANGED)
  316. {
  317. if (!ev.target || ui->IsWidgetWrapped(ev.target))
  318. {
  319. VariantMap eventData;
  320. ConvertEvent(this, ui->WrapWidget(ev.target), ev, eventData);
  321. SendEvent(E_WIDGETEVENT, eventData);
  322. if (eventData[WidgetEvent::P_HANDLED].GetBool())
  323. return true;
  324. }
  325. }
  326. else if (ev.type == EVENT_TYPE_TAB_CHANGED)
  327. {
  328. if (!ev.target || ui->IsWidgetWrapped(ev.target))
  329. {
  330. VariantMap eventData;
  331. ConvertEvent(this, ui->WrapWidget(ev.target), ev, eventData);
  332. SendEvent(E_WIDGETEVENT, eventData);
  333. if (eventData[WidgetEvent::P_HANDLED].GetBool())
  334. return true;
  335. }
  336. }
  337. else if (ev.type == EVENT_TYPE_CLICK)
  338. {
  339. if (ev.target && ev.target->GetID() == TBID("__popup-menu"))
  340. {
  341. // popup menu
  342. if (JSGetHeapPtr())
  343. {
  344. VariantMap eventData;
  345. eventData[PopupMenuSelect::P_BUTTON] = this;
  346. String id;
  347. ui->GetTBIDString(ev.ref_id, id);
  348. eventData[PopupMenuSelect::P_REFID] = id;
  349. SendEvent(E_POPUPMENUSELECT, eventData);
  350. }
  351. return true;
  352. }
  353. else
  354. {
  355. if (!ev.target || ui->IsWidgetWrapped(ev.target))
  356. {
  357. VariantMap eventData;
  358. ConvertEvent(this, ui->WrapWidget(ev.target), ev, eventData);
  359. SendEvent(E_WIDGETEVENT, eventData);
  360. if (eventData[WidgetEvent::P_HANDLED].GetBool())
  361. return true;
  362. }
  363. }
  364. }
  365. return false;
  366. }
  367. }