tb_debug.cpp 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  1. // ================================================================================
  2. // == This file is a part of Turbo Badger. (C) 2011-2014, Emil Segerås ==
  3. // == See tb_core.h for more information. ==
  4. // ================================================================================
  5. #include "tb_core.h"
  6. #include "tb_widgets_reader.h"
  7. #include "tb_window.h"
  8. #include "tb_editfield.h"
  9. #include "tb_font_renderer.h"
  10. #include "tb_tempbuffer.h"
  11. #include <stdio.h>
  12. namespace tb {
  13. #ifdef TB_RUNTIME_DEBUG_INFO
  14. TBDebugInfo g_tb_debug;
  15. TBDebugInfo::TBDebugInfo()
  16. {
  17. memset(settings, 0, sizeof(int) * NUM_SETTINGS);
  18. }
  19. /** Window showing runtime debug settings. */
  20. class DebugSettingsWindow : public TBWindow, public TBWidgetListener
  21. {
  22. public:
  23. TBEditField *output;
  24. TBOBJECT_SUBCLASS(DebugSettingsWindow, TBWindow);
  25. DebugSettingsWindow(TBWidget *root)
  26. {
  27. SetText("Debug settings");
  28. g_widgets_reader->LoadData(this,
  29. "TBLayout: axis: y, distribution: available, position: left\n"
  30. " TBLayout: id: 'container', axis: y, size: available\n"
  31. " TBTextField: text: 'Event output:'\n"
  32. " TBEditField: id: 'output', gravity: all, multiline: 1, wrap: 0\n"
  33. " lp: pref-height: 100dp");
  34. AddCheckbox(TBDebugInfo::LAYOUT_BOUNDS, "Layout bounds");
  35. AddCheckbox(TBDebugInfo::LAYOUT_CLIPPING, "Layout clipping");
  36. AddCheckbox(TBDebugInfo::LAYOUT_PS_DEBUGGING, "Layout size calculation");
  37. AddCheckbox(TBDebugInfo::RENDER_BATCHES, "Render batches");
  38. AddCheckbox(TBDebugInfo::RENDER_SKIN_BITMAP_FRAGMENTS, "Render skin bitmap fragments");
  39. AddCheckbox(TBDebugInfo::RENDER_FONT_BITMAP_FRAGMENTS, "Render font bitmap fragments");
  40. output = GetWidgetByIDAndType<TBEditField>(TBIDC("output"));
  41. TBRect bounds(0, 0, root->GetRect().w, root->GetRect().h);
  42. SetRect(GetResizeToFitContentRect().CenterIn(bounds).MoveIn(bounds).Clip(bounds));
  43. root->AddChild(this);
  44. TBWidgetListener::AddGlobalListener(this);
  45. }
  46. ~DebugSettingsWindow()
  47. {
  48. TBWidgetListener::RemoveGlobalListener(this);
  49. }
  50. void AddCheckbox(TBDebugInfo::SETTING setting, const char *str)
  51. {
  52. TBCheckBox *check = new TBCheckBox();
  53. check->SetValue(g_tb_debug.settings[setting]);
  54. check->data.SetInt(setting);
  55. check->SetID(TBIDC("check"));
  56. TBClickLabel *label = new TBClickLabel();
  57. label->SetText(str);
  58. label->GetContentRoot()->AddChild(check, WIDGET_Z_BOTTOM);
  59. GetWidgetByID(TBIDC("container"))->AddChild(label);
  60. }
  61. virtual bool OnEvent(const TBWidgetEvent &ev)
  62. {
  63. if (ev.type == EVENT_TYPE_CLICK && ev.target->GetID() == TBIDC("check"))
  64. {
  65. // Update setting and invalidate
  66. g_tb_debug.settings[ev.target->data.GetInt()] = ev.target->GetValue();
  67. GetParentRoot()->Invalidate();
  68. return true;
  69. }
  70. return TBWindow::OnEvent(ev);
  71. }
  72. virtual void OnPaint(const PaintProps &paint_props)
  73. {
  74. // Draw stuff to the right of the debug window
  75. g_renderer->Translate(GetRect().w, 0);
  76. // Draw skin bitmap fragments
  77. if (TB_DEBUG_SETTING(RENDER_SKIN_BITMAP_FRAGMENTS))
  78. g_tb_skin->Debug();
  79. // Draw font glyph fragments (the font of the hovered widget)
  80. if (TB_DEBUG_SETTING(RENDER_FONT_BITMAP_FRAGMENTS))
  81. {
  82. TBWidget *widget = TBWidget::hovered_widget ? TBWidget::hovered_widget : TBWidget::focused_widget;
  83. g_font_manager->GetFontFace(widget ?
  84. widget->GetCalculatedFontDescription() :
  85. g_font_manager->GetDefaultFontDescription())->Debug();
  86. }
  87. g_renderer->Translate(-GetRect().w, 0);
  88. }
  89. TBStr GetIDString(const TBID &id)
  90. {
  91. TBStr str;
  92. #ifdef TB_RUNTIME_DEBUG_INFO
  93. str.Append("\"");
  94. str.Append(id.debug_string);
  95. str.Append("\"");
  96. #else
  97. str.SetFormatted("%u", (uint32)id);
  98. #endif
  99. return str;
  100. }
  101. // TBWidgetListener
  102. virtual bool OnWidgetInvokeEvent(TBWidget *widget, const TBWidgetEvent &ev)
  103. {
  104. // Skip these events for now
  105. if (ev.IsPointerEvent())
  106. return false;
  107. // Always ignore activity in this window (or we might get endless recursion)
  108. if (TBWindow *window = widget->GetParentWindow())
  109. if (TBSafeCast<DebugSettingsWindow>(window))
  110. return false;
  111. TBTempBuffer buf;
  112. buf.AppendString(GetEventTypeStr(ev.type));
  113. buf.AppendString(" (");
  114. buf.AppendString(widget->GetClassName());
  115. buf.AppendString(")");
  116. buf.AppendString(" id: ");
  117. buf.AppendString(GetIDString(ev.target->GetID()));
  118. if (ev.ref_id)
  119. {
  120. buf.AppendString(", ref_id: ");
  121. buf.AppendString(GetIDString(ev.ref_id));
  122. }
  123. if (ev.type == EVENT_TYPE_CHANGED)
  124. {
  125. TBStr extra, text;
  126. if (ev.target->GetText(text) && text.Length() > 24)
  127. sprintf(text.CStr() + 20, "...");
  128. extra.SetFormatted(", value: %.2f (\"%s\")", ev.target->GetValueDouble(), text.CStr());
  129. buf.AppendString(extra);
  130. }
  131. buf.AppendString("\n");
  132. // Append the line to the output textfield
  133. TBStyleEdit *se = output->GetStyleEdit();
  134. se->selection.SelectNothing();
  135. se->AppendText(buf.GetData(), TB_ALL_TO_TERMINATION, true);
  136. se->ScrollIfNeeded(false, true);
  137. // Remove lines from the top if we exceed the height limit.
  138. const int height_limit = 2000;
  139. int current_height = se->GetContentHeight();
  140. if (current_height > height_limit)
  141. {
  142. se->caret.Place(TBPoint(0, current_height - height_limit));
  143. se->selection.SelectToCaret(se->blocks.GetFirst(), 0);
  144. se->Delete();
  145. }
  146. return false;
  147. }
  148. const char *GetEventTypeStr(EVENT_TYPE type) const
  149. {
  150. switch (type)
  151. {
  152. case EVENT_TYPE_CLICK: return "CLICK";
  153. case EVENT_TYPE_LONG_CLICK: return "LONG_CLICK";
  154. case EVENT_TYPE_POINTER_DOWN: return "POINTER_DOWN";
  155. case EVENT_TYPE_POINTER_UP: return "POINTER_UP";
  156. case EVENT_TYPE_POINTER_MOVE: return "POINTER_MOVE";
  157. case EVENT_TYPE_RIGHT_POINTER_UP: return "RIGHT_POINTER_UP";
  158. case EVENT_TYPE_RIGHT_POINTER_DOWN: return "RIGHT_POINTER_DOWN";
  159. case EVENT_TYPE_TOUCH_DOWN: return "TOUCH_DOWN";
  160. case EVENT_TYPE_TOUCH_UP: return "TOUCH_UP";
  161. case EVENT_TYPE_TOUCH_MOVE: return "TOUCH_MOVE";
  162. case EVENT_TYPE_TOUCH_CANCEL: return "TOUCH_CANCEL";
  163. case EVENT_TYPE_WHEEL: return "WHEEL";
  164. case EVENT_TYPE_CHANGED: return "CHANGED";
  165. case EVENT_TYPE_KEY_DOWN: return "KEY_DOWN";
  166. case EVENT_TYPE_KEY_UP: return "KEY_UP";
  167. case EVENT_TYPE_SHORTCUT: return "SHORT_CUT";
  168. case EVENT_TYPE_CONTEXT_MENU: return "CONTEXT_MENU";
  169. default: return "[UNKNOWN]";
  170. };
  171. }
  172. };
  173. void ShowDebugInfoSettingsWindow(TBWidget *root)
  174. {
  175. new DebugSettingsWindow(root);
  176. }
  177. #endif // TB_RUNTIME_DEBUG_INFO
  178. }; // namespace tb