UIWidget.cpp 7.4 KB

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