tb_widget_value.cpp 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  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_widget_value.h"
  6. #include "tb_widgets.h"
  7. namespace tb {
  8. // == TBWidgetValueConnection ===========================================================
  9. void TBWidgetValueConnection::Connect(TBWidgetValue *value, TBWidget *widget)
  10. {
  11. Unconnect();
  12. m_widget = widget;
  13. m_value = value;
  14. m_value->m_connections.AddLast(this);
  15. m_value->SyncToWidget(m_widget);
  16. }
  17. void TBWidgetValueConnection::Unconnect()
  18. {
  19. if (m_value)
  20. m_value->m_connections.Remove(this);
  21. m_value = nullptr;
  22. m_widget = nullptr;
  23. }
  24. void TBWidgetValueConnection::SyncFromWidget(TBWidget *source_widget)
  25. {
  26. if (m_value)
  27. m_value->SetFromWidget(source_widget);
  28. }
  29. // == TBWidgetValue =====================================================================
  30. TBWidgetValue::TBWidgetValue(const TBID &name, TBValue::TYPE type)
  31. : m_name(name)
  32. , m_value(type)
  33. , m_syncing(false)
  34. {
  35. }
  36. TBWidgetValue::~TBWidgetValue()
  37. {
  38. while (m_connections.GetFirst())
  39. m_connections.GetFirst()->Unconnect();
  40. }
  41. void TBWidgetValue::SetFromWidget(TBWidget *source_widget)
  42. {
  43. if (m_syncing)
  44. return; // We ended up here because syncing is in progress.
  45. // Get the value in the format
  46. TBStr text;
  47. switch (m_value.GetType())
  48. {
  49. case TBValue::TYPE_STRING:
  50. if (!source_widget->GetText(text))
  51. return;
  52. m_value.SetString(text, TBValue::SET_NEW_COPY);
  53. break;
  54. case TBValue::TYPE_NULL:
  55. case TBValue::TYPE_INT:
  56. m_value.SetInt(source_widget->GetValue());
  57. break;
  58. case TBValue::TYPE_FLOAT:
  59. // FIX: TBValue should use double instead of float?
  60. m_value.SetFloat((float)source_widget->GetValueDouble());
  61. break;
  62. default:
  63. assert(!"Unsupported value type!");
  64. }
  65. SyncToWidgets(source_widget);
  66. }
  67. bool TBWidgetValue::SyncToWidgets(TBWidget *exclude_widget)
  68. {
  69. // FIX: Assign group to each value. Currently we only have one global group.
  70. g_value_group.InvokeOnValueChanged(this);
  71. bool fail = false;
  72. TBLinkListOf<TBWidgetValueConnection>::Iterator iter = m_connections.IterateForward();
  73. while (TBWidgetValueConnection *connection = iter.GetAndStep())
  74. {
  75. if (connection->m_widget != exclude_widget)
  76. fail |= !SyncToWidget(connection->m_widget);
  77. }
  78. return !fail;
  79. }
  80. bool TBWidgetValue::SyncToWidget(TBWidget *dst_widget)
  81. {
  82. if (m_syncing)
  83. return true; // We ended up here because syncing is in progress.
  84. m_syncing = true;
  85. bool ret = true;
  86. switch (m_value.GetType())
  87. {
  88. case TBValue::TYPE_STRING:
  89. ret = dst_widget->SetText(m_value.GetString());
  90. break;
  91. case TBValue::TYPE_NULL:
  92. case TBValue::TYPE_INT:
  93. dst_widget->SetValue(m_value.GetInt());
  94. break;
  95. case TBValue::TYPE_FLOAT:
  96. // FIX: TBValue should use double instead of float?
  97. dst_widget->SetValueDouble(m_value.GetFloat());
  98. break;
  99. default:
  100. assert(!"Unsupported value type!");
  101. }
  102. m_syncing = false;
  103. return ret;
  104. }
  105. void TBWidgetValue::SetInt(int value)
  106. {
  107. m_value.SetInt(value);
  108. SyncToWidgets(nullptr);
  109. }
  110. bool TBWidgetValue::SetText(const char *text)
  111. {
  112. m_value.SetString(text, TBValue::SET_NEW_COPY);
  113. return SyncToWidgets(nullptr);
  114. }
  115. void TBWidgetValue::SetDouble(double value)
  116. {
  117. // FIX: TBValue should use double instead of float?
  118. m_value.SetFloat((float)value);
  119. SyncToWidgets(nullptr);
  120. }
  121. // == TBValueGroup ================================================================================
  122. /*extern*/ TBValueGroup g_value_group;
  123. TBWidgetValue *TBValueGroup::CreateValueIfNeeded(const TBID &name, TBValue::TYPE type)
  124. {
  125. if (TBWidgetValue *val = GetValue(name))
  126. return val;
  127. if (TBWidgetValue *val = new TBWidgetValue(name, type))
  128. {
  129. if (m_values.Add(name, val))
  130. return val;
  131. else
  132. delete val;
  133. }
  134. return nullptr;
  135. }
  136. void TBValueGroup::InvokeOnValueChanged(const TBWidgetValue *value)
  137. {
  138. TBLinkListOf<TBValueGroupListener>::Iterator iter = m_listeners.IterateForward();
  139. while (TBValueGroupListener *listener = iter.GetAndStep())
  140. listener->OnValueChanged(this, value);
  141. }
  142. }; // namespace tb