tb_inline_select.cpp 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  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_inline_select.h"
  6. #include <assert.h>
  7. #include <math.h>
  8. #include <stdlib.h>
  9. namespace tb {
  10. // FIX: axis should affect the buttons arrow skin!
  11. // FIX: unfocus should set the correct text!
  12. // == TBInlineSelect ========================================================================================
  13. TBInlineSelect::TBInlineSelect()
  14. : m_value(0)
  15. , m_min(0)
  16. , m_max(100)
  17. , m_modified(false)
  18. {
  19. SetSkinBg(TBIDC("TBInlineSelect"));
  20. AddChild(&m_layout);
  21. m_layout.AddChild(&m_buttons[0]);
  22. m_layout.AddChild(&m_editfield);
  23. m_layout.AddChild(&m_buttons[1]);
  24. m_layout.SetRect(GetPaddingRect());
  25. m_layout.SetGravity(WIDGET_GRAVITY_ALL);
  26. m_layout.SetSpacing(0);
  27. m_buttons[0].SetSkinBg(TBIDC("TBButton.flat"));
  28. m_buttons[1].SetSkinBg(TBIDC("TBButton.flat"));
  29. m_buttons[0].GetContentRoot()->AddChild(new TBSkinImage(TBIDC("arrowdark.left")));
  30. m_buttons[1].GetContentRoot()->AddChild(new TBSkinImage(TBIDC("arrowdark.right")));
  31. m_buttons[0].SetIsFocusable(false);
  32. m_buttons[1].SetIsFocusable(false);
  33. m_buttons[0].SetID(TBIDC("dec"));
  34. m_buttons[1].SetID(TBIDC("inc"));
  35. m_buttons[0].SetAutoRepeat(true);
  36. m_buttons[1].SetAutoRepeat(true);
  37. m_editfield.SetTextAlign(TB_TEXT_ALIGN_CENTER);
  38. m_editfield.SetEditType(EDIT_TYPE_NUMBER);
  39. m_editfield.SetText("0");
  40. m_editfield.AddListener(this);
  41. }
  42. TBInlineSelect::~TBInlineSelect()
  43. {
  44. m_editfield.RemoveListener(this);
  45. m_layout.RemoveChild(&m_buttons[1]);
  46. m_layout.RemoveChild(&m_editfield);
  47. m_layout.RemoveChild(&m_buttons[0]);
  48. RemoveChild(&m_layout);
  49. }
  50. void TBInlineSelect::SetEditFieldLayoutParams(LayoutParams& lp)
  51. {
  52. m_editfield.SetLayoutParams(lp);
  53. }
  54. void TBInlineSelect::SetLimits(double min, double max)
  55. {
  56. assert(min <= max);
  57. m_min = min;
  58. m_max = max;
  59. SetValueDouble(m_value);
  60. }
  61. void TBInlineSelect::SetValueInternal(double value, bool update_text)
  62. {
  63. value = CLAMP(value, m_min, m_max);
  64. if (value == m_value)
  65. return;
  66. m_value = value;
  67. if (update_text)
  68. {
  69. TBStr strval;
  70. double prec = m_value - floor(m_value);
  71. if (prec < .001)
  72. {
  73. strval.SetFormatted("%.0f", m_value);
  74. }
  75. else
  76. strval.SetFormatted("%.2f", m_value);
  77. m_editfield.SetText(strval);
  78. }
  79. TBWidgetEvent ev(EVENT_TYPE_CHANGED);
  80. InvokeEvent(ev);
  81. // Warning: Do nothing here since the event might have deleted us.
  82. // If needed, check if we are alive using a safe pointer first.
  83. }
  84. void TBInlineSelect::OnSkinChanged()
  85. {
  86. m_layout.SetRect(GetPaddingRect());
  87. }
  88. bool TBInlineSelect::OnEvent(const TBWidgetEvent &ev)
  89. {
  90. if (ev.type == EVENT_TYPE_KEY_DOWN)
  91. {
  92. if (ev.special_key == TB_KEY_UP || ev.special_key == TB_KEY_DOWN)
  93. {
  94. double dv = ev.special_key == TB_KEY_UP ? 1 : -1;
  95. SetValueDouble(GetValueDouble() + dv);
  96. return true;
  97. }
  98. }
  99. else if (ev.type == EVENT_TYPE_CLICK && ev.target->GetID() == TBIDC("dec"))
  100. {
  101. SetValueDouble(GetValueDouble() - 1);
  102. return true;
  103. }
  104. else if (ev.type == EVENT_TYPE_CLICK && ev.target->GetID() == TBIDC("inc"))
  105. {
  106. SetValueDouble(GetValueDouble() + 1);
  107. return true;
  108. }
  109. else if (ev.type == EVENT_TYPE_CHANGED && ev.target == &m_editfield)
  110. {
  111. TBStr text;
  112. m_editfield.GetText(text);
  113. SetValueInternal((double) atof(text), false);
  114. }
  115. // catch mouse up/mouse down on buttons for modifications
  116. if (ev.target == &m_buttons[0] || ev.target == &m_buttons[1])
  117. {
  118. if (ev.type == EVENT_TYPE_POINTER_DOWN)
  119. {
  120. m_modified = true;
  121. }
  122. else if (ev.type == EVENT_TYPE_POINTER_UP)
  123. {
  124. if (m_modified)
  125. InvokeModifiedEvent();
  126. }
  127. }
  128. return false;
  129. }
  130. void TBInlineSelect::InvokeModifiedEvent()
  131. {
  132. TBWidgetEvent ev(EVENT_TYPE_CUSTOM);
  133. ev.ref_id = TBIDC("edit_complete");
  134. // forward to delegate
  135. TBWidget::OnEvent(ev);
  136. m_modified = false;
  137. m_editfield.GetText(m_initial_edit_value);
  138. }
  139. bool TBInlineSelect::OnWidgetInvokeEvent(TBWidget *widget, const TBWidgetEvent &ev)
  140. {
  141. return false;
  142. }
  143. void TBInlineSelect::OnWidgetFocusChanged(TBWidget *widget, bool focused)
  144. {
  145. if (widget == &m_editfield)
  146. {
  147. if (focused)
  148. m_editfield.GetText(m_initial_edit_value);
  149. else
  150. {
  151. TBStr editvalue;
  152. m_editfield.GetText(editvalue);
  153. if (m_modified || !editvalue.Equals(m_initial_edit_value.CStr()))
  154. {
  155. InvokeModifiedEvent();
  156. }
  157. }
  158. }
  159. }
  160. }; // namespace tb