UIWidget.cpp 8.3 KB

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