You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

ovdCColorGradientSettingView.cpp 9.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250
  1. #include "ovdCColorGradientSettingView.h"
  2. #include "../ovd_base.h"
  3. #include <visualization-toolkit/ovvizColorGradient.h>
  4. #include <cmath>
  5. namespace OpenViBE {
  6. namespace Designer {
  7. namespace Setting {
  8. static void OnColorGradientColorButtonPressed(GtkColorButton* button, gpointer data) { static_cast<CColorGradientSettingView*>(data)->colorChange(button); }
  9. static void OnButtonSettingColorGradientConfigurePressed(GtkButton* /*button*/, gpointer data)
  10. {
  11. static_cast<CColorGradientSettingView*>(data)->configurePressed();
  12. }
  13. static void OnRefreshColorGradient(GtkWidget* /*widget*/, GdkEventExpose* /*event*/, gpointer data)
  14. {
  15. static_cast<CColorGradientSettingView*>(data)->refreshColorGradient();
  16. }
  17. static void OnGTKWidgetDestroy(GtkWidget* widget, gpointer /*data*/) { gtk_widget_destroy(widget); }
  18. static void OnInitializeColorGradient(GtkWidget* /*widget*/, gpointer data) { static_cast<CColorGradientSettingView*>(data)->initializeGradient(); }
  19. static void OnButtonColorGradientAddPressed(GtkButton* /*button*/, gpointer data) { static_cast<CColorGradientSettingView*>(data)->addColor(); }
  20. static void OnButtonColorGradientRemovePressed(GtkButton* /*button*/, gpointer data) { static_cast<CColorGradientSettingView*>(data)->removeColor(); }
  21. static void OnColorGradientSpinButtonValueChanged(GtkSpinButton* button, gpointer data) { static_cast<CColorGradientSettingView*>(data)->spinChange(button); }
  22. static void OnChange(GtkEntry* /*entry*/, gpointer data) { static_cast<CColorGradientSettingView*>(data)->onChange(); }
  23. CColorGradientSettingView::CColorGradientSettingView(Kernel::IBox& box, const size_t index, CString& builderName, const Kernel::IKernelContext& ctx)
  24. : CAbstractSettingView(box, index, builderName, "settings_collection-hbox_setting_color_gradient"), m_kernelCtx(ctx), m_builderName(builderName)
  25. {
  26. GtkWidget* settingWidget = CAbstractSettingView::getEntryFieldWidget();
  27. std::vector<GtkWidget*> widgets;
  28. CAbstractSettingView::extractWidget(settingWidget, widgets);
  29. m_entry = GTK_ENTRY(widgets[0]);
  30. g_signal_connect(G_OBJECT(m_entry), "changed", G_CALLBACK(OnChange), this);
  31. g_signal_connect(G_OBJECT(widgets[1]), "clicked", G_CALLBACK(OnButtonSettingColorGradientConfigurePressed), this);
  32. CAbstractSettingView::initializeValue();
  33. }
  34. void CColorGradientSettingView::getValue(CString& value) const { value = CString(gtk_entry_get_text(m_entry)); }
  35. void CColorGradientSettingView::setValue(const CString& value)
  36. {
  37. m_onValueSetting = true;
  38. gtk_entry_set_text(m_entry, value);
  39. m_onValueSetting = false;
  40. }
  41. void CColorGradientSettingView::configurePressed()
  42. {
  43. GtkBuilder* builder = gtk_builder_new();
  44. gtk_builder_add_from_file(builder, m_builderName.toASCIIString(), nullptr);
  45. gtk_builder_connect_signals(builder, nullptr);
  46. m_dialog = GTK_WIDGET(gtk_builder_get_object(builder, "setting_editor-color_gradient-dialog"));
  47. const CString initialGradient = m_kernelCtx.getConfigurationManager().expand(gtk_entry_get_text(m_entry));
  48. CMatrix colorGradient;
  49. VisualizationToolkit::ColorGradient::parse(colorGradient, initialGradient);
  50. m_colorGradient.resize(std::max<size_t>(colorGradient.getDimensionSize(1), 2));
  51. for (size_t i = 0; i < colorGradient.getDimensionSize(1); ++i)
  52. {
  53. const size_t idx = i * 4;
  54. m_colorGradient[i].percent = colorGradient[idx];
  55. m_colorGradient[i].color.red = guint(colorGradient[idx + 1] * .01 * 65535.);
  56. m_colorGradient[i].color.green = guint(colorGradient[idx + 2] * .01 * 65535.);
  57. m_colorGradient[i].color.blue = guint(colorGradient[idx + 3] * .01 * 65535.);
  58. }
  59. m_container = GTK_WIDGET(gtk_builder_get_object(builder, "setting_editor-color_gradient-vbox"));
  60. m_drawingArea = GTK_WIDGET(gtk_builder_get_object(builder, "setting_editor-color_gradient-drawingarea"));
  61. g_signal_connect(G_OBJECT(m_dialog), "show", G_CALLBACK(OnInitializeColorGradient), this);
  62. g_signal_connect(G_OBJECT(m_drawingArea), "expose_event", G_CALLBACK(OnRefreshColorGradient), this);
  63. g_signal_connect(G_OBJECT(gtk_builder_get_object(builder, "setting_editor-color_gradient-add_button")), "pressed",
  64. G_CALLBACK(OnButtonColorGradientAddPressed), this);
  65. g_signal_connect(G_OBJECT(gtk_builder_get_object(builder, "setting_editor-color_gradient-remove_button")), "pressed",
  66. G_CALLBACK(OnButtonColorGradientRemovePressed), this);
  67. if (gtk_dialog_run(GTK_DIALOG(m_dialog)) == GTK_RESPONSE_APPLY)
  68. {
  69. CString finalGradient;
  70. CMatrix finalColorGradient(4, m_colorGradient.size());
  71. size_t idx = 0;
  72. for (size_t i = 0; i < m_colorGradient.size(); ++i)
  73. {
  74. finalColorGradient[idx++] = m_colorGradient[i].percent;
  75. finalColorGradient[idx++] = round(m_colorGradient[i].color.red * 100. / 65535.);
  76. finalColorGradient[idx++] = round(m_colorGradient[i].color.green * 100. / 65535.);
  77. finalColorGradient[idx++] = round(m_colorGradient[i].color.blue * 100. / 65535.);
  78. }
  79. VisualizationToolkit::ColorGradient::format(finalGradient, finalColorGradient);
  80. if (!m_onValueSetting) { getBox().setSettingValue(getSettingIndex(), finalGradient.toASCIIString()); }
  81. setValue(finalGradient.toASCIIString());
  82. }
  83. gtk_widget_destroy(m_dialog);
  84. g_object_unref(builder);
  85. }
  86. void CColorGradientSettingView::initializeGradient()
  87. {
  88. gtk_widget_hide(m_container);
  89. gtk_container_foreach(GTK_CONTAINER(m_container), OnGTKWidgetDestroy, nullptr);
  90. size_t i = 0;
  91. const size_t count = m_colorGradient.size();
  92. m_colorButtons.clear();
  93. m_spinButtons.clear();
  94. for (auto& cg : m_colorGradient)
  95. {
  96. GtkBuilder* builder = gtk_builder_new();
  97. gtk_builder_add_from_file(builder, m_builderName.toASCIIString(), nullptr);
  98. gtk_builder_connect_signals(builder, nullptr);
  99. GtkWidget* widget = GTK_WIDGET(gtk_builder_get_object(builder, "setting_editor-color_gradient-hbox"));
  100. cg.colorButton = GTK_COLOR_BUTTON(gtk_builder_get_object(builder, "setting_editor-color_gradient-colorbutton"));
  101. cg.spinButton = GTK_SPIN_BUTTON(gtk_builder_get_object(builder, "setting_editor-color_gradient-spinbutton"));
  102. gtk_color_button_set_color(cg.colorButton, &cg.color);
  103. gtk_spin_button_set_value(cg.spinButton, cg.percent);
  104. g_signal_connect(G_OBJECT(cg.colorButton), "color-set", G_CALLBACK(OnColorGradientColorButtonPressed), this);
  105. g_signal_connect(G_OBJECT(cg.spinButton), "value-changed", G_CALLBACK(OnColorGradientSpinButtonValueChanged), this);
  106. g_object_ref(widget);
  107. gtk_container_remove(GTK_CONTAINER(gtk_widget_get_parent(widget)), widget);
  108. gtk_container_add(GTK_CONTAINER(m_container), widget);
  109. g_object_unref(widget);
  110. g_object_unref(builder);
  111. m_colorButtons[cg.colorButton] = i;
  112. m_spinButtons[cg.spinButton] = i;
  113. i++;
  114. }
  115. gtk_spin_button_set_value(m_colorGradient[0].spinButton, 0);
  116. gtk_spin_button_set_value(m_colorGradient[count - 1].spinButton, 100);
  117. gtk_widget_show(m_container);
  118. }
  119. void CColorGradientSettingView::refreshColorGradient()
  120. {
  121. const size_t steps = 100;
  122. gint sizex = 0;
  123. gint sizey = 0;
  124. gdk_drawable_get_size(m_drawingArea->window, &sizex, &sizey);
  125. CMatrix gradient(4, m_colorGradient.size());
  126. for (size_t i = 0; i < m_colorGradient.size(); ++i)
  127. {
  128. const size_t idx = i * 4;
  129. gradient[idx] = m_colorGradient[i].percent;
  130. gradient[idx + 1] = m_colorGradient[i].color.red * 100. / 65535.;
  131. gradient[idx + 2] = m_colorGradient[i].color.green * 100. / 65535.;
  132. gradient[idx + 3] = m_colorGradient[i].color.blue * 100. / 65535.;
  133. }
  134. CMatrix interpolated;
  135. VisualizationToolkit::ColorGradient::interpolate(interpolated, gradient, steps);
  136. GdkGC* gc = gdk_gc_new(m_drawingArea->window);
  137. GdkColor color;
  138. for (size_t i = 0; i < steps; ++i)
  139. {
  140. color.red = guint(interpolated[i * 4 + 1] * 65535 * .01);
  141. color.green = guint(interpolated[i * 4 + 2] * 65535 * .01);
  142. color.blue = guint(interpolated[i * 4 + 3] * 65535 * .01);
  143. gdk_gc_set_rgb_fg_color(gc, &color);
  144. gdk_draw_rectangle(m_drawingArea->window, gc, TRUE, gint((sizex * i) / steps), 0, gint((sizex * (i + 1)) / steps), sizey);
  145. }
  146. g_object_unref(gc);
  147. }
  148. void CColorGradientSettingView::addColor()
  149. {
  150. m_colorGradient.resize(m_colorGradient.size() + 1);
  151. m_colorGradient[m_colorGradient.size() - 1].percent = 100;
  152. initializeGradient();
  153. refreshColorGradient();
  154. }
  155. void CColorGradientSettingView::removeColor()
  156. {
  157. if (m_colorGradient.size() > 2)
  158. {
  159. m_colorGradient.resize(m_colorGradient.size() - 1);
  160. m_colorGradient[m_colorGradient.size() - 1].percent = 100;
  161. initializeGradient();
  162. refreshColorGradient();
  163. }
  164. }
  165. void CColorGradientSettingView::spinChange(GtkSpinButton* button)
  166. {
  167. gtk_spin_button_update(button);
  168. const size_t i = m_spinButtons[button];
  169. GtkSpinButton* prevSpinButton = i > 0 ? m_colorGradient[i - 1].spinButton : nullptr;
  170. GtkSpinButton* nextSpinButton = i < m_colorGradient.size() - 1 ? m_colorGradient[i + 1].spinButton : nullptr;
  171. if (!prevSpinButton) { gtk_spin_button_set_value(button, 0); }
  172. if (!nextSpinButton) { gtk_spin_button_set_value(button, 100); }
  173. if (prevSpinButton && gtk_spin_button_get_value(button) < gtk_spin_button_get_value(prevSpinButton))
  174. {
  175. gtk_spin_button_set_value(button, gtk_spin_button_get_value(prevSpinButton));
  176. }
  177. if (nextSpinButton && gtk_spin_button_get_value(button) > gtk_spin_button_get_value(nextSpinButton))
  178. {
  179. gtk_spin_button_set_value(button, gtk_spin_button_get_value(nextSpinButton));
  180. }
  181. m_colorGradient[i].percent = gtk_spin_button_get_value(button);
  182. refreshColorGradient();
  183. }
  184. void CColorGradientSettingView::colorChange(GtkColorButton* button)
  185. {
  186. GdkColor color;
  187. gtk_color_button_get_color(button, &color);
  188. m_colorGradient[m_colorButtons[button]].color = color;
  189. refreshColorGradient();
  190. }
  191. void CColorGradientSettingView::onChange()
  192. {
  193. if (!m_onValueSetting)
  194. {
  195. const gchar* value = gtk_entry_get_text(m_entry);
  196. getBox().setSettingValue(getSettingIndex(), value);
  197. }
  198. }
  199. } // namespace Setting
  200. } // namespace Designer
  201. } // namespace OpenViBE