1 /* EXTRAITS DE LA LICENCE
2 Copyright CEA, contributeurs : Luc BILLARD et Damien
3 CALISTE, laboratoire L_Sim, (2001-2005)
4
5 Adresse mèl :
6 BILLARD, non joignable par mèl ;
7 CALISTE, damien P caliste AT cea P fr.
8
9 Ce logiciel est un programme informatique servant à visualiser des
10 structures atomiques dans un rendu pseudo-3D.
11
12 Ce logiciel est régi par la licence CeCILL soumise au droit français et
13 respectant les principes de diffusion des logiciels libres. Vous pouvez
14 utiliser, modifier et/ou redistribuer ce programme sous les conditions
15 de la licence CeCILL telle que diffusée par le CEA, le CNRS et l'INRIA
16 sur le site "http://www.cecill.info".
17
18 Le fait que vous puissiez accéder à cet en-tête signifie que vous avez
19 pris connaissance de la licence CeCILL, et que vous en avez accepté les
20 termes (cf. le fichier Documentation/licence.fr.txt fourni avec ce logiciel).
21 */
22
23 /* LICENCE SUM UP
24 Copyright CEA, contributors : Luc BILLARD et Damien
25 CALISTE, laboratoire L_Sim, (2001-2005)
26
27 E-mail address:
28 BILLARD, not reachable any more ;
29 CALISTE, damien P caliste AT cea P fr.
30
31 This software is a computer program whose purpose is to visualize atomic
32 configurations in 3D.
33
34 This software is governed by the CeCILL license under French law and
35 abiding by the rules of distribution of free software. You can use,
36 modify and/ or redistribute the software under the terms of the CeCILL
37 license as circulated by CEA, CNRS and INRIA at the following URL
38 "http://www.cecill.info".
39
40 The fact that you are presently reading this means that you have had
41 knowledge of the CeCILL license and that you accept its terms. You can
42 find a copy of this licence shipped with this software at Documentation/licence.en.txt.
43 */
44 #include <gtk/gtk.h>
45
46 #include "gtk_colorComboBoxWidget.h"
47 #include <support.h>
48 #include <visu_tools.h>
49
50 /**
51 * SECTION:gtk_colorComboBoxWidget
52 * @short_description: Defines a specialised #GtkComboBox to choose
53 * stored colours.
54 * @see_also: #ToolColor, #VisuUiStippleCombobox, #VisuUiShadeCombobox
55 * @include: coreTools/toolColor.h
56 *
57 * <para>This widget looks like a #GtkComboBox and it displays a list
58 * of stored colours. These colours may come from the configuration
59 * files or can be selected and stored by the user actions. To do it,
60 * the first entry of the combo box is 'new / modify', that opens a GTK
61 * colour picker. The new values are used to craete a new colour entry
62 * in the combo box. In a complete version, the combo box can have a
63 * #GtkVBox associated to modify colours without creating new entries, see
64 * visu_ui_color_combobox_newWithRanges() method. Otherwise, only already
65 * selected colours are available. The stored colours are shared by
66 * all widgets of this class. It is thus a convenient way to have
67 * coherent colour picker through V_Sim.</para>
68 *
69 * <para>When the widget is created with ranges, the additional part
70 * can be retrieve with visu_ui_color_combobox_getRangeWidgets() and attached
71 * whereever is convenient. When the ranges are modified, the new
72 * colour is not added to the combo box. It can be read using
73 * visu_ui_color_combobox_getRangeColor() or visu_ui_color_combobox_getRangeMaterial(). The combo
74 * box is set thus to an unselected state and
75 * visu_ui_color_combobox_getSelection() will return a NULL
76 * pointer. Besides the colour ranges, there is an add button to
77 * insert the newly defined colour into the combo box.</para>
78 *
79 * <para>This widget can emit a #VisuUiColorCombobox::color-selected
80 * signal that is a wrapper around the #GtkComboBox::changed signal,
81 * but it is emitted only when a new colour is selected (either an
82 * existing one or a newly created from the picker). This colour
83 * is passed to the callback. The two other signals,
84 * #VisuUiColorCombobox::color-value-changed and
85 * #VisuUiColorCombobox::material-value-changed, are generated when the
86 * widget have been created with ranges and that one of these ranges
87 * is modified.</para>
88 *
89 * Since: 3.1
90 */
91
92 enum {
93 COLOR_SELECTED_SIGNAL,
94 COLOR_VALUE_CHANGED_SIGNAL,
95 MATERIAL_VALUE_CHANGED_SIGNAL,
96 LAST_SIGNAL
97 };
98 static guint signals[LAST_SIGNAL] = { 0 };
99 enum
100 {
101 PROP_0,
102 COLOR_PROP,
103 MATERIAL_PROP,
104 N_PROP
105 };
106 static GParamSpec *properties[N_PROP];
107
108 /* This enum is used to access the column of the GtkListStore
109 that contains the informations of stroed colors. */
110 enum
111 {
112 /* This has a pointer to a 16x16 image to represent the color,
113 including the alpha channel. */
114 COLUMN_COLOR_PIXBUF_ALPHA,
115 /* This has a pointer to a 16x16 image to represent the color,
116 without the alpha channel. */
117 COLUMN_COLOR_PIXBUF,
118 /* This is a pointer to a label that describes the color :
119 "(n_red;n_green;n_blue;n_alpha)" with n_xxx from 0 to 255. */
120 COLUMN_COLOR_LABEL_ALPHA,
121 /* This is the same label than above but without the alpha value. */
122 COLUMN_COLOR_LABEL,
123 /* This a pointer to the #ToolColor as defined in visuTools.h */
124 COLUMN_COLOR_POINTER_TO,
125 N_COLUMN_COLOR
126 };
127
128 /* Labels for the ranges part. */
129 #define RED_ELE_LABEL _("R:")
130 #define GREEN_ELE_LABEL _("G:")
131 #define BLUE_ELE_LABEL _("B:")
132 #define ALPHA_ELE_LABEL _("Alph:")
133 #define AMB_ELE_LABEL _("amb:")
134 #define DIF_ELE_LABEL _("dif:")
135 #define SHI_ELE_LABEL _("shi:")
136 #define SPE_ELE_LABEL _("spe:")
137 #define EMI_ELE_LABEL _("emi:")
138
139 static void visu_ui_color_combobox_changed (GtkWidget *widget, VisuUiColorCombobox *colorComboBox);
140 static void visu_ui_color_combobox_dispose (GObject *obj);
141 static void visu_ui_color_combobox_finalize(GObject *obj);
142 static void visu_ui_color_combobox_get_property(GObject* obj, guint property_id,
143 GValue *value, GParamSpec *pspec);
144 static void visu_ui_color_combobox_set_property(GObject* obj, guint property_id,
145 const GValue *value, GParamSpec *pspec);
146
147 /**
148 * VisuUiColorCombobox
149 *
150 * Private structure to store informations of a #VisuUiColorCombobox object.
151 *
152 * Since: 3.1
153 */
154 struct _VisuUiColorCombobox
155 {
156 GtkComboBox comboColor;
157 ToolColor* previouslySelectedColor;
158
159 gboolean withRanges;
160 GtkWidget *expandRanges;
161 GtkWidget *rgbRanges[4];
162 GtkWidget *materialRanges[TOOL_MATERIAL_N_VALUES];
163 gulong rgbSignals[4];
164 gulong materialSignals[TOOL_MATERIAL_N_VALUES];
165 gulong comboSignal;
166 GtkWidget *addButton;
167
168 gboolean hasAlphaChannel;
169
170 GtkCellRenderer *rendererRGB;
171
172 /* Memory gestion. */
173 gboolean dispose_has_run;
174 };
175 /**
176 * VisuUiColorComboboxClass
177 *
178 * Private structure to store informations of a #VisuUiColorComboboxClass object.
179 *
180 * Since: 3.1
181 */
182 struct _VisuUiColorComboboxClass
183 {
184 GtkComboBoxClass parent_class;
185
186 void (*colorComboBox) (VisuUiColorCombobox *colorCombo);
187
188 /* This listStore contains all the colors
189 known by widgets of this class. It is used
190 as TreeModel for the combobox in the widget. */
191 GtkListStore *listStoredColors;
192
193 gulong colorAddedSignalId;
194 };
195
196 /* Local callbacks. */
197 static void visu_ui_color_combobox_materialChanged(GtkRange *rg, gpointer data);
198 static void visu_ui_color_combobox_rgbChanged(GtkRange *rg, gpointer data);
199 static void visu_ui_color_combobox_addButtonClicked(GtkButton *button, gpointer data);
200
201 /* Local methods. */
202 static void addColorToModel(GtkTreeIter *iter, VisuUiColorComboboxClass* klass,
203 ToolColor* color);
204 static void onNewColorAvailable(ToolPool *pool, ToolColor* newColor, gpointer data);
205
206 /**
207 * visu_ui_color_combobox_get_type
208 *
209 * #GType are unique numbers to identify objects.
210 *
211 * Returns: the #GType associated with #VisuUiColorCombobox objects.
212 *
213 * Since: 3.1
214 */
G_DEFINE_TYPE(VisuUiColorCombobox,visu_ui_color_combobox,GTK_TYPE_COMBO_BOX)215 G_DEFINE_TYPE(VisuUiColorCombobox, visu_ui_color_combobox, GTK_TYPE_COMBO_BOX)
216
217 static void visu_ui_color_combobox_class_init(VisuUiColorComboboxClass *klass)
218 {
219 GtkTreeIter iter;
220 GList *colorLst;
221
222 DBG_fprintf(stderr, "Gtk VisuUiColorCombobox: creating the class of the widget.\n");
223 DBG_fprintf(stderr, " - adding new signals ;\n");
224 /**
225 * VisuUiColorCombobox::color-selected:
226 * @combo: the #VisuUiColorCombobox that emits the signal ;
227 * @color: the newly selected #ToolColor.
228 *
229 * This signal is emitted when a new valid colour is selected,
230 * either an existing one or newly created one.
231 *
232 * Since: 3.1
233 */
234 signals[COLOR_SELECTED_SIGNAL] =
235 g_signal_new ("color-selected",
236 G_TYPE_FROM_CLASS (klass),
237 G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
238 G_STRUCT_OFFSET (VisuUiColorComboboxClass, colorComboBox),
239 NULL,
240 NULL,
241 g_cclosure_marshal_VOID__POINTER,
242 G_TYPE_NONE, 1, G_TYPE_POINTER);
243 /**
244 * VisuUiColorCombobox::color-value-changed:
245 * @combo: the #VisuUiColorCombobox that emits the signal ;
246 * @RGBA: the modified channel.
247 *
248 * This signal is emitted when the range of a colour is modified.
249 *
250 * Since: 3.3
251 */
252 signals[COLOR_VALUE_CHANGED_SIGNAL] =
253 g_signal_new ("color-value-changed",
254 G_TYPE_FROM_CLASS (klass),
255 G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
256 G_STRUCT_OFFSET (VisuUiColorComboboxClass, colorComboBox),
257 NULL,
258 NULL,
259 g_cclosure_marshal_VOID__UINT,
260 G_TYPE_NONE, 1, G_TYPE_UINT);
261 /**
262 * VisuUiColorCombobox::material-value-changed:
263 * @combo: the #VisuUiColorCombobox that emits the signal ;
264 * @mat: the modified material channel (see #ToolMaterialIds).
265 *
266 * This signal is emitted when the range of a material is modified.
267 *
268 * Since: 3.3
269 */
270 signals[MATERIAL_VALUE_CHANGED_SIGNAL] =
271 g_signal_new ("material-value-changed",
272 G_TYPE_FROM_CLASS (klass),
273 G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
274 G_STRUCT_OFFSET (VisuUiColorComboboxClass, colorComboBox),
275 NULL,
276 NULL,
277 g_cclosure_marshal_VOID__UINT,
278 G_TYPE_NONE, 1, G_TYPE_UINT);
279
280 DBG_fprintf(stderr, " - initializing the listStore of colors.\n");
281 /* Init the listStore of colors. */
282 klass->listStoredColors = gtk_list_store_new (N_COLUMN_COLOR,
283 GDK_TYPE_PIXBUF,
284 GDK_TYPE_PIXBUF,
285 G_TYPE_STRING,
286 G_TYPE_STRING,
287 G_TYPE_POINTER);
288 gtk_list_store_append(klass->listStoredColors, &iter);
289 gtk_list_store_set(klass->listStoredColors, &iter,
290 COLUMN_COLOR_PIXBUF_ALPHA, NULL,
291 COLUMN_COLOR_PIXBUF , NULL,
292 COLUMN_COLOR_LABEL_ALPHA , _("New / modify"),
293 COLUMN_COLOR_LABEL , _("New / modify"),
294 COLUMN_COLOR_POINTER_TO , NULL,
295 -1);
296 klass->colorAddedSignalId = g_signal_connect(tool_color_getStorage(), "new-element",
297 G_CALLBACK(onNewColorAvailable),
298 (gpointer)klass);
299 DBG_fprintf(stderr, " - add stored colours.\n");
300 colorLst = tool_pool_asList(tool_color_getStorage());
301 while (colorLst)
302 {
303 addColorToModel(&iter, klass, (ToolColor*)colorLst->data);
304 colorLst = g_list_next(colorLst);
305 }
306
307 /* Connect freeing methods. */
308 G_OBJECT_CLASS(klass)->dispose = visu_ui_color_combobox_dispose;
309 G_OBJECT_CLASS(klass)->finalize = visu_ui_color_combobox_finalize;
310 G_OBJECT_CLASS(klass)->set_property = visu_ui_color_combobox_set_property;
311 G_OBJECT_CLASS(klass)->get_property = visu_ui_color_combobox_get_property;
312
313 /**
314 * VisuUiColorCombobox::color:
315 *
316 * Store the color of the current selection.
317 *
318 * Since: 3.8
319 */
320 properties[COLOR_PROP] = g_param_spec_boxed("color", "Color",
321 "color of the current selection",
322 TOOL_TYPE_COLOR, G_PARAM_READWRITE);
323 /**
324 * VisuUiColorCombobox::material:
325 *
326 * Store the material of the current selection.
327 *
328 * Since: 3.8
329 */
330 properties[MATERIAL_PROP] = g_param_spec_boxed("material", "Material",
331 "material of the current selection",
332 TOOL_TYPE_MATERIAL, G_PARAM_READWRITE);
333
334 g_object_class_install_properties(G_OBJECT_CLASS(klass), N_PROP, properties);
335 }
336
visu_ui_color_combobox_dispose(GObject * obj)337 static void visu_ui_color_combobox_dispose(GObject *obj)
338 {
339 DBG_fprintf(stderr, "Gtk VisuUiColorCombobox: dispose object %p.\n", (gpointer)obj);
340
341 if (VISU_UI_COLOR_COMBOBOX(obj)->dispose_has_run)
342 return;
343
344 VISU_UI_COLOR_COMBOBOX(obj)->dispose_has_run = TRUE;
345 /* Chain up to the parent class */
346 G_OBJECT_CLASS(visu_ui_color_combobox_parent_class)->dispose(obj);
347 }
visu_ui_color_combobox_finalize(GObject * obj)348 static void visu_ui_color_combobox_finalize(GObject *obj)
349 {
350 /* VisuUiColorCombobox *colorComboBox; */
351
352 g_return_if_fail(obj);
353
354 DBG_fprintf(stderr, "Gtk VisuUiColorCombobox: finalize object %p.\n", (gpointer)obj);
355
356 /* colorComboBox = VISU_UI_COLOR_COMBOBOX(obj); */
357 /* if (colorComboBox->expandRanges) */
358 /* gtk_widget_destroy(colorComboBox->expandRanges); */
359
360 /* Chain up to the parent class */
361 G_OBJECT_CLASS(visu_ui_color_combobox_parent_class)->finalize(obj);
362
363 DBG_fprintf(stderr, "Gtk VisuUiColorCombobox: freeing ... OK.\n");
364 }
visu_ui_color_combobox_get_property(GObject * obj,guint property_id,GValue * value,GParamSpec * pspec)365 static void visu_ui_color_combobox_get_property(GObject* obj, guint property_id,
366 GValue *value, GParamSpec *pspec)
367 {
368 VisuUiColorCombobox *self = VISU_UI_COLOR_COMBOBOX(obj);
369 const ToolColor *color;
370 ToolColor _color;
371
372 DBG_fprintf(stderr, "Gtk VisuUiColorCombobox: get property '%s'.\n",
373 g_param_spec_get_name(pspec));
374 switch (property_id)
375 {
376 case COLOR_PROP:
377 color = visu_ui_color_combobox_getSelection(self);
378 if (color)
379 g_value_set_static_boxed(value, color);
380 else
381 {
382 _color.rgba[0] = gtk_range_get_value(GTK_RANGE(self->rgbRanges[0]));
383 _color.rgba[1] = gtk_range_get_value(GTK_RANGE(self->rgbRanges[1]));
384 _color.rgba[2] = gtk_range_get_value(GTK_RANGE(self->rgbRanges[2]));
385 _color.rgba[3] = gtk_range_get_value(GTK_RANGE(self->rgbRanges[3]));
386 g_value_set_boxed(value, &_color);
387 }
388 DBG_fprintf(stderr, " | color pointer is %p.\n",
389 (gpointer)g_value_get_boxed(value));
390 break;
391 case MATERIAL_PROP:
392 g_value_take_boxed(value, visu_ui_color_combobox_getRangeMaterial(self));
393 DBG_fprintf(stderr, " | material pointer is %p.\n",
394 (gpointer)g_value_get_boxed(value));
395 break;
396 default:
397 /* We don't have any other property... */
398 G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, property_id, pspec);
399 break;
400 }
401 }
visu_ui_color_combobox_set_property(GObject * obj,guint property_id,const GValue * value,GParamSpec * pspec)402 static void visu_ui_color_combobox_set_property(GObject* obj, guint property_id,
403 const GValue *value, GParamSpec *pspec)
404 {
405 GtkTreeIter iter;
406 VisuUiColorCombobox *self = VISU_UI_COLOR_COMBOBOX(obj);
407
408 DBG_fprintf(stderr, "Gtk VisuUiColorCombobox: set property '%s'.\n",
409 g_param_spec_get_name(pspec));
410 switch (property_id)
411 {
412 case COLOR_PROP:
413 if (!visu_ui_color_combobox_setSelection(self, (ToolColor*)g_value_get_boxed(value)))
414 {
415 addColorToModel(&iter, VISU_UI_COLOR_COMBOBOX_GET_CLASS(obj),
416 (ToolColor*)g_value_get_boxed(value));
417 gtk_combo_box_set_active_iter(GTK_COMBO_BOX(obj), &iter);
418 }
419 break;
420 case MATERIAL_PROP:
421 visu_ui_color_combobox_setRangeMaterial(self, (float*)g_value_get_boxed(value), FALSE);
422 break;
423 default:
424 /* We don't have any other property... */
425 G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, property_id, pspec);
426 break;
427 }
428 }
429
430
visu_ui_color_combobox_init(VisuUiColorCombobox * colorComboBox)431 static void visu_ui_color_combobox_init(VisuUiColorCombobox *colorComboBox)
432 {
433 DBG_fprintf(stderr, "Gtk VisuUiColorCombobox: initializing new object (%p).\n",
434 (gpointer)colorComboBox);
435
436 colorComboBox->hasAlphaChannel = TRUE;
437 colorComboBox->dispose_has_run = FALSE;
438 colorComboBox->previouslySelectedColor = tool_pool_getById(tool_color_getStorage(), 0);
439 }
440
_drawPix(GtkCellLayout * layout _U_,GtkCellRenderer * cell,GtkTreeModel * model,GtkTreeIter * iter,gpointer data)441 static void _drawPix(GtkCellLayout *layout _U_, GtkCellRenderer *cell,
442 GtkTreeModel *model, GtkTreeIter *iter, gpointer data)
443 {
444 GdkPixbuf *pix;
445
446 if (GPOINTER_TO_INT(data))
447 gtk_tree_model_get(model, iter, COLUMN_COLOR_PIXBUF_ALPHA, &pix, -1);
448 else
449 gtk_tree_model_get(model, iter, COLUMN_COLOR_PIXBUF, &pix, -1);
450
451 if (pix)
452 {
453 g_object_set(G_OBJECT(cell), "pixbuf", pix, NULL);
454 g_object_unref(pix);
455 }
456 else
457 g_object_set(G_OBJECT(cell), "icon-name", "list-add", NULL);
458 }
buildWidgets(VisuUiColorCombobox * colorComboBox)459 static void buildWidgets(VisuUiColorCombobox *colorComboBox)
460 {
461 GObjectClass *klass;
462 GtkCellRenderer *renderer;
463 GtkWidget *vboxExpand, *table, *label, *hbox, *image;
464 char *rgb[4];
465 char *rgbName[4] = {"scroll_r", "scroll_g", "scroll_b", "scroll_a"};
466 char *material[5];
467 int i, j;
468
469 klass = G_OBJECT_GET_CLASS(colorComboBox);
470 gtk_combo_box_set_model(GTK_COMBO_BOX(colorComboBox),
471 GTK_TREE_MODEL(VISU_UI_COLOR_COMBOBOX_CLASS(klass)->listStoredColors));
472 DBG_fprintf(stderr, "Gtk VisuUiColorCombobox: build widgets.\n");
473 renderer = gtk_cell_renderer_pixbuf_new();
474 gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(colorComboBox), renderer, FALSE);
475 gtk_cell_layout_set_cell_data_func(GTK_CELL_LAYOUT(colorComboBox), renderer, _drawPix,
476 GINT_TO_POINTER(colorComboBox->hasAlphaChannel),
477 (GDestroyNotify)0);
478 /* if (colorComboBox->hasAlphaChannel) */
479 /* gtk_cell_layout_add_attribute(GTK_CELL_LAYOUT(colorComboBox), renderer, */
480 /* "pixbuf", COLUMN_COLOR_PIXBUF_ALPHA); */
481 /* else */
482 /* gtk_cell_layout_add_attribute(GTK_CELL_LAYOUT(colorComboBox), renderer, */
483 /* "pixbuf", COLUMN_COLOR_PIXBUF); */
484 renderer = gtk_cell_renderer_text_new();
485 g_object_set(G_OBJECT(renderer), "scale", 0.85, NULL);
486 gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(colorComboBox), renderer, FALSE);
487 if (colorComboBox->hasAlphaChannel)
488 gtk_cell_layout_add_attribute(GTK_CELL_LAYOUT(colorComboBox), renderer,
489 "text", COLUMN_COLOR_LABEL_ALPHA);
490 else
491 gtk_cell_layout_add_attribute(GTK_CELL_LAYOUT(colorComboBox), renderer,
492 "text", COLUMN_COLOR_LABEL);
493 colorComboBox->rendererRGB = renderer;
494 DBG_fprintf(stderr, " | renderers OK\n");
495
496 gtk_combo_box_set_active(GTK_COMBO_BOX(colorComboBox), 1);
497 DBG_fprintf(stderr, " | selection OK\n");
498
499 colorComboBox->expandRanges = (GtkWidget*)0;
500 if (colorComboBox->withRanges)
501 {
502 DBG_fprintf(stderr, "Gtk VisuUiColorCombobox: add range widgets.\n");
503 rgb[0] = RED_ELE_LABEL;
504 rgb[1] = GREEN_ELE_LABEL;
505 rgb[2] = BLUE_ELE_LABEL;
506 rgb[3] = ALPHA_ELE_LABEL;
507 material[0] = AMB_ELE_LABEL;
508 material[1] = DIF_ELE_LABEL;
509 material[2] = SHI_ELE_LABEL;
510 material[3] = SPE_ELE_LABEL;
511 material[4] = EMI_ELE_LABEL;
512
513 colorComboBox->expandRanges = gtk_expander_new(_("More options"));
514 gtk_expander_set_expanded(GTK_EXPANDER(colorComboBox->expandRanges), FALSE);
515
516 vboxExpand = gtk_vbox_new(FALSE, 0);
517 gtk_container_add(GTK_CONTAINER(colorComboBox->expandRanges), vboxExpand);
518
519 hbox = gtk_hbox_new(FALSE, 0);
520 gtk_box_pack_start(GTK_BOX(vboxExpand), hbox, FALSE, FALSE, 5);
521
522 table = gtk_grid_new();
523 tool_grid_resize(table, 3, 2);
524 gtk_box_pack_start(GTK_BOX(hbox), table, TRUE, TRUE, 0);
525 gtk_widget_show(table);
526 for (i = 0; i < 3; i++)
527 {
528 label = gtk_label_new(rgb[i]);
529 gtk_grid_attach(GTK_GRID(table), label, 0, i, 1, 1);
530 colorComboBox->rgbRanges[i] = gtk_hscale_new_with_range(0., 1., 0.001);
531 gtk_widget_set_hexpand(colorComboBox->rgbRanges[i], TRUE);
532 gtk_scale_set_value_pos(GTK_SCALE(colorComboBox->rgbRanges[i]),
533 GTK_POS_RIGHT);
534 gtk_widget_set_name(colorComboBox->rgbRanges[i], rgbName[i]);
535 gtk_grid_attach(GTK_GRID(table), colorComboBox->rgbRanges[i],
536 1, i, 1, 1);
537 }
538 colorComboBox->addButton = gtk_button_new();
539 gtk_box_pack_start(GTK_BOX(hbox), colorComboBox->addButton, FALSE, FALSE, 2);
540 image = gtk_image_new_from_icon_name("list-add", GTK_ICON_SIZE_BUTTON);
541 gtk_container_add(GTK_CONTAINER(colorComboBox->addButton), image);
542 DBG_fprintf(stderr, " | color OK\n");
543
544 table = gtk_grid_new();
545 tool_grid_resize(table, 3, 4);
546 gtk_box_pack_start(GTK_BOX(vboxExpand), table, FALSE, FALSE, 5);
547 for (i = 0; i < 2; i++)
548 {
549 for (j = 0; j < 2; j++)
550 {
551 label = gtk_label_new(material[i * 2 + j]);
552 gtk_label_set_xalign(GTK_LABEL(label), 1.);
553 gtk_grid_attach(GTK_GRID(table), label, j * 2, i, 1, 1);
554 colorComboBox->materialRanges[i * 2 + j] =
555 gtk_hscale_new_with_range(0., 1., 0.01);
556 gtk_widget_set_hexpand(colorComboBox->materialRanges[i * 2 + j], TRUE);
557 gtk_scale_set_value_pos(GTK_SCALE(colorComboBox->materialRanges[i * 2 + j]),
558 GTK_POS_RIGHT);
559 gtk_widget_set_name(colorComboBox->materialRanges[i * 2 +j], "scroll_mat");
560 gtk_grid_attach(GTK_GRID(table), colorComboBox->materialRanges[i * 2 + j],
561 2 * j + 1, i, 1, 1);
562 }
563 }
564 label = gtk_label_new(material[4]);
565 gtk_label_set_xalign(GTK_LABEL(label), 1);
566 gtk_grid_attach(GTK_GRID(table), label, 0, i, 1, 1);
567 colorComboBox->materialRanges[4] =
568 gtk_hscale_new_with_range(0., 1., 0.01);
569 gtk_scale_set_value_pos(GTK_SCALE(colorComboBox->materialRanges[4]),
570 GTK_POS_RIGHT);
571 gtk_widget_set_name(colorComboBox->materialRanges[4], "scroll_mat");
572 gtk_grid_attach(GTK_GRID(table), colorComboBox->materialRanges[4],
573 1, i, 1, 1);
574 label = gtk_label_new(rgb[3]);
575 gtk_label_set_xalign(GTK_LABEL(label), 1.);
576 gtk_grid_attach(GTK_GRID(table), label, 2, i, 1, 1);
577 colorComboBox->rgbRanges[3] = gtk_hscale_new_with_range(0., 1., 0.01);
578 gtk_scale_set_value_pos(GTK_SCALE(colorComboBox->rgbRanges[3]),
579 GTK_POS_RIGHT);
580 gtk_widget_set_name(colorComboBox->rgbRanges[3], rgbName[3]);
581 gtk_grid_attach(GTK_GRID(table), colorComboBox->rgbRanges[3], 3, i, 1, 1);
582 DBG_fprintf(stderr, " | material OK\n");
583 /* Attach the callbacks. */
584 for (i = 0; i < 4; i++)
585 colorComboBox->rgbSignals[i] =
586 g_signal_connect(G_OBJECT(colorComboBox->rgbRanges[i]), "value-changed",
587 G_CALLBACK(visu_ui_color_combobox_rgbChanged), (gpointer)colorComboBox);
588 for (i = 0; i < TOOL_MATERIAL_N_VALUES; i++)
589 colorComboBox->materialSignals[i] =
590 g_signal_connect(G_OBJECT(colorComboBox->materialRanges[i]), "value-changed",
591 G_CALLBACK(visu_ui_color_combobox_materialChanged), (gpointer)colorComboBox);
592 g_signal_connect(G_OBJECT(colorComboBox->addButton), "clicked",
593 G_CALLBACK(visu_ui_color_combobox_addButtonClicked), (gpointer)colorComboBox);
594 DBG_fprintf(stderr, " | signals OK\n");
595 }
596 colorComboBox->comboSignal = g_signal_connect(G_OBJECT(colorComboBox), "changed",
597 G_CALLBACK(visu_ui_color_combobox_changed),
598 (gpointer)colorComboBox);
599 }
600
601 /**
602 * visu_ui_color_combobox_newWithRanges:
603 * @hasAlphaChannel: a boolean.
604 *
605 * Create a color combo and several ranges.
606 *
607 * Returns: (transfer full): a newly created #VisuUiColorCombobox widget.
608 *
609 * Since: 3.3
610 */
visu_ui_color_combobox_newWithRanges(gboolean hasAlphaChannel)611 GtkWidget* visu_ui_color_combobox_newWithRanges(gboolean hasAlphaChannel)
612 {
613 VisuUiColorCombobox *colorComboBox;
614
615 DBG_fprintf(stderr, "Gtk VisuUiColorCombobox: creating new object with alpha & ranges: %d.\n",
616 hasAlphaChannel);
617
618 colorComboBox = VISU_UI_COLOR_COMBOBOX(g_object_new(visu_ui_color_combobox_get_type (), NULL));
619 colorComboBox->hasAlphaChannel = hasAlphaChannel;
620 colorComboBox->withRanges = TRUE;
621
622 buildWidgets(colorComboBox);
623
624 DBG_fprintf(stderr, "Gtk VisuUiColorCombobox: object ready.\n");
625 return GTK_WIDGET(colorComboBox);
626 }
627 /**
628 * visu_ui_color_combobox_new:
629 * @hasAlphaChannel: a boolean.
630 *
631 * A #VisuUiColorCombobox widget is like a #GtkComboBox widget, but it is already filled
632 * with the colors stores in the structures adhoc in visu_tools.h. Using this widget
633 * is a convienient way to share colors between all part of V_Sim and to give a consistent
634 * look of all color selection. If the argument @hasAlphaChannel is FALSE, the widget
635 * display all colors but without their alpha channel, assuming it to be fully opaque.
636 *
637 * Returns: (transfer full): a newly created #VisuUiColorCombobox widget.
638 *
639 * Since: 3.1
640 */
visu_ui_color_combobox_new(gboolean hasAlphaChannel)641 GtkWidget* visu_ui_color_combobox_new(gboolean hasAlphaChannel)
642 {
643 VisuUiColorCombobox *colorComboBox;
644
645 DBG_fprintf(stderr, "Gtk VisuUiColorCombobox: creating new object with alpha: %d.\n",
646 hasAlphaChannel);
647
648 colorComboBox = VISU_UI_COLOR_COMBOBOX(g_object_new(visu_ui_color_combobox_get_type (), NULL));
649 colorComboBox->hasAlphaChannel = hasAlphaChannel;
650 colorComboBox->withRanges = FALSE;
651
652 buildWidgets(colorComboBox);
653
654 DBG_fprintf(stderr, "Gtk VisuUiColorCombobox: object ready.\n");
655 return GTK_WIDGET(colorComboBox);
656 }
657 /**
658 * visu_ui_color_combobox_setExpanded:
659 * @colorComboBox: a #ToolColor object ;
660 * @value: a boolean value.
661 *
662 * Set the expanded state of the ranges. This is usable only if the colorComboBox
663 * has been created with ranges.
664 *
665 * Since: 3.3
666 */
visu_ui_color_combobox_setExpanded(VisuUiColorCombobox * colorComboBox,gboolean value)667 void visu_ui_color_combobox_setExpanded(VisuUiColorCombobox *colorComboBox, gboolean value)
668 {
669 g_return_if_fail(VISU_IS_UI_COLOR_COMBOBOX(colorComboBox));
670 g_return_if_fail(colorComboBox->withRanges);
671
672 gtk_expander_set_expanded(GTK_EXPANDER(colorComboBox->expandRanges), value);
673 }
674 /**
675 * visu_ui_color_combobox_setPrintValues:
676 * @colorComboBox: a #ToolColor object ;
677 * @value: a boolean.
678 *
679 * Print or not the RGB values.
680 *
681 * Since: 3.4
682 */
visu_ui_color_combobox_setPrintValues(VisuUiColorCombobox * colorComboBox,gboolean value)683 void visu_ui_color_combobox_setPrintValues(VisuUiColorCombobox *colorComboBox, gboolean value)
684 {
685 g_object_set(G_OBJECT(colorComboBox->rendererRGB),
686 "visible", value, NULL);
687 }
688 /**
689 * visu_ui_color_combobox_getRangeWidgets:
690 * @colorComboBox: a #ToolColor object.
691 *
692 * Retrieve the wiodget using to represent the ranges, or NULL if the object
693 * has no ranges.
694 *
695 * Returns: (transfer none): a widget owned by @color.
696 *
697 * Since: 3.3
698 */
visu_ui_color_combobox_getRangeWidgets(VisuUiColorCombobox * colorComboBox)699 GtkWidget* visu_ui_color_combobox_getRangeWidgets(VisuUiColorCombobox *colorComboBox)
700 {
701 g_return_val_if_fail(VISU_IS_UI_COLOR_COMBOBOX(colorComboBox), (GtkWidget*)0);
702
703 return colorComboBox->expandRanges;
704 }
705
visu_ui_color_combobox_changed(GtkWidget * widget _U_,VisuUiColorCombobox * colorComboBox)706 static void visu_ui_color_combobox_changed(GtkWidget *widget _U_, VisuUiColorCombobox *colorComboBox)
707 {
708 int selected, i;
709 GdkRGBA gdkcolor;
710 GtkWidget *selection;
711 gint code;
712 float rgba[4];
713 GtkTreeIter iter;
714 GObjectClass *klass;
715 ToolColor *color;
716
717 selected = gtk_combo_box_get_active(GTK_COMBO_BOX(colorComboBox));
718 DBG_fprintf(stderr, "Gtk VisuUiColorCombobox: internal combobox changed signal -> %d.\n", selected);
719 if (selected < 0)
720 {
721 if (colorComboBox->withRanges)
722 gtk_widget_set_sensitive(colorComboBox->addButton, TRUE);
723 colorComboBox->previouslySelectedColor = (ToolColor*)0;
724 return;
725 }
726
727 if (colorComboBox->withRanges)
728 gtk_widget_set_sensitive(colorComboBox->addButton, FALSE);
729
730 if (selected != 0)
731 {
732 gtk_combo_box_get_active_iter(GTK_COMBO_BOX(colorComboBox), &iter);
733 klass = G_OBJECT_GET_CLASS(colorComboBox);
734 gtk_tree_model_get(GTK_TREE_MODEL(VISU_UI_COLOR_COMBOBOX_CLASS(klass)->listStoredColors), &iter,
735 COLUMN_COLOR_POINTER_TO, &color,
736 -1);
737 if (color != colorComboBox->previouslySelectedColor)
738 {
739 colorComboBox->previouslySelectedColor = color;
740 /* Set the ranges. */
741 if (colorComboBox->withRanges)
742 for (i = 0; i <4; i++)
743 {
744 g_signal_handler_block(G_OBJECT(colorComboBox->rgbRanges[i]),
745 colorComboBox->rgbSignals[i]);
746 gtk_range_set_value(GTK_RANGE(colorComboBox->rgbRanges[i]),
747 (gdouble)color->rgba[i]);
748 g_signal_handler_unblock(G_OBJECT(colorComboBox->rgbRanges[i]),
749 colorComboBox->rgbSignals[i]);
750 }
751 DBG_fprintf(stderr, "Gtk VisuUiColorCombobox: emitting 'color-selected' signal.\n");
752 g_object_notify_by_pspec(G_OBJECT(colorComboBox), properties[COLOR_PROP]);
753 g_signal_emit(G_OBJECT(colorComboBox),
754 signals[COLOR_SELECTED_SIGNAL], 0, (gpointer)color, NULL);
755 }
756 else
757 DBG_fprintf(stderr, "Gtk VisuUiColorCombobox: aborting 'color-selected' signal.\n");
758 return;
759 }
760 if (colorComboBox->previouslySelectedColor)
761 {
762 gdkcolor.red = colorComboBox->previouslySelectedColor->rgba[0];
763 gdkcolor.green = colorComboBox->previouslySelectedColor->rgba[1];
764 gdkcolor.blue = colorComboBox->previouslySelectedColor->rgba[2];
765 gdkcolor.alpha = colorComboBox->previouslySelectedColor->rgba[3];
766 }
767 else
768 {
769 gdkcolor.red = 0.;
770 gdkcolor.green = 0.;
771 gdkcolor.blue = 0.;
772 gdkcolor.alpha = 1.;
773 }
774
775 /* Create the selection. */
776 selection = gtk_color_chooser_dialog_new(_("Select a color"), NULL);
777 gtk_color_chooser_set_use_alpha(GTK_COLOR_CHOOSER(selection),
778 colorComboBox->hasAlphaChannel);
779 /* createColorSelectionCustomList(GTK_COLOR_SELECTION_DIALOG(selection)); */
780
781 /* Initialise its values. */
782 gtk_color_chooser_set_rgba(GTK_COLOR_CHOOSER(selection), &gdkcolor);
783
784 /* Run the dialog window. */
785 code = gtk_dialog_run(GTK_DIALOG(selection));
786 if (code == GTK_RESPONSE_OK || code == GTK_RESPONSE_ACCEPT)
787 {
788 gtk_color_chooser_get_rgba(GTK_COLOR_CHOOSER(selection), &gdkcolor);
789 rgba[0] = (float)gdkcolor.red;
790 rgba[1] = (float)gdkcolor.green;
791 rgba[2] = (float)gdkcolor.blue;
792 rgba[3] = (float)gdkcolor.alpha;
793
794 klass = G_OBJECT_GET_CLASS(colorComboBox);
795 g_signal_handler_block(tool_color_getStorage(), VISU_UI_COLOR_COMBOBOX_CLASS(klass)->colorAddedSignalId);
796 color = tool_color_addFloatRGBA(rgba, &selected);
797 g_signal_handler_unblock(tool_color_getStorage(), VISU_UI_COLOR_COMBOBOX_CLASS(klass)->colorAddedSignalId);
798 addColorToModel(&iter, VISU_UI_COLOR_COMBOBOX_CLASS(klass), color);
799 gtk_combo_box_set_active_iter(GTK_COMBO_BOX(colorComboBox), &iter);
800 }
801 else
802 {
803 /* Return the combobox to the previously selected color. */
804 if (colorComboBox->previouslySelectedColor)
805 visu_ui_color_combobox_setSelection(colorComboBox,
806 colorComboBox->previouslySelectedColor);
807 else
808 gtk_combo_box_set_active(GTK_COMBO_BOX(colorComboBox), -1);
809 }
810 gtk_widget_destroy(selection);
811 }
812
visu_ui_color_combobox_materialChanged(GtkRange * rg,gpointer data)813 static void visu_ui_color_combobox_materialChanged(GtkRange *rg, gpointer data)
814 {
815 int i;
816 VisuUiColorCombobox *colorComboBox;
817
818 g_return_if_fail(VISU_IS_UI_COLOR_COMBOBOX(data));
819
820 g_object_notify_by_pspec(G_OBJECT(data), properties[MATERIAL_PROP]);
821
822 colorComboBox = VISU_UI_COLOR_COMBOBOX(data);
823 DBG_fprintf(stderr, "Gtk VisuUiColorCombobox: internal material range changed signal.\n");
824
825 DBG_fprintf(stderr, "Gtk VisuUiColorCombobox: emitting 'material-value-changed' signal.\n");
826 for (i = 0; i < TOOL_MATERIAL_N_VALUES; i++)
827 if (GTK_WIDGET(rg) == colorComboBox->materialRanges[i])
828 {
829 g_signal_emit(G_OBJECT(colorComboBox),
830 signals[MATERIAL_VALUE_CHANGED_SIGNAL], 0,
831 (ToolMaterialIds)i, NULL);
832 return;
833 }
834 g_warning("Internal error, unrecognized range.");
835 }
visu_ui_color_combobox_rgbChanged(GtkRange * rg,gpointer data)836 static void visu_ui_color_combobox_rgbChanged(GtkRange *rg, gpointer data)
837 {
838 int i;
839 VisuUiColorCombobox *colorComboBox;
840 float *rgba;
841
842 g_return_if_fail(VISU_IS_UI_COLOR_COMBOBOX(data));
843
844 colorComboBox = VISU_UI_COLOR_COMBOBOX(data);
845 DBG_fprintf(stderr, "Gtk VisuUiColorCombobox: internal color range changed signal.\n");
846 rgba = visu_ui_color_combobox_getRangeColor(colorComboBox);
847 tool_color_getByValues(&i, rgba[0], rgba[1], rgba[2], rgba[3]);
848 if (i < 0)
849 {
850 gtk_combo_box_set_active(GTK_COMBO_BOX(colorComboBox), -1);
851 g_object_notify_by_pspec(G_OBJECT(data), properties[COLOR_PROP]);
852 }
853 else
854 gtk_combo_box_set_active(GTK_COMBO_BOX(colorComboBox), i + 1);
855 g_free(rgba);
856
857 DBG_fprintf(stderr, "Gtk VisuUiColorCombobox: emitting 'color-value-changed' signal.\n");
858 for (i = 0; i < 4; i++)
859 if (GTK_WIDGET(rg) == colorComboBox->rgbRanges[i])
860 {
861 g_signal_emit(G_OBJECT(colorComboBox),
862 signals[COLOR_VALUE_CHANGED_SIGNAL], 0,
863 (ToolMaterialIds)i, NULL);
864 return;
865 }
866 g_warning("Internal error, unrecognized range.");
867 }
visu_ui_color_combobox_addButtonClicked(GtkButton * button _U_,gpointer data)868 static void visu_ui_color_combobox_addButtonClicked(GtkButton *button _U_, gpointer data)
869 {
870 GtkTreeIter iter;
871 GObjectClass *klass;
872 ToolColor *color;
873 VisuUiColorCombobox *colorComboBox;
874 float *rgba;
875 int selected;
876
877 g_return_if_fail(VISU_IS_UI_COLOR_COMBOBOX(data));
878 colorComboBox = VISU_UI_COLOR_COMBOBOX(data);
879
880 DBG_fprintf(stderr, "Gtk VisuUiColorCombobox: adding a new color from ranges.\n");
881
882 rgba = visu_ui_color_combobox_getRangeColor(colorComboBox);
883 klass = G_OBJECT_GET_CLASS(colorComboBox);
884 g_signal_handler_block(tool_color_getStorage(), VISU_UI_COLOR_COMBOBOX_CLASS(klass)->colorAddedSignalId);
885 color = tool_color_addFloatRGBA(rgba, &selected);
886 g_signal_handler_unblock(tool_color_getStorage(), VISU_UI_COLOR_COMBOBOX_CLASS(klass)->colorAddedSignalId);
887 addColorToModel(&iter, VISU_UI_COLOR_COMBOBOX_CLASS(klass), color);
888 gtk_combo_box_set_active_iter(GTK_COMBO_BOX(colorComboBox), &iter);
889 g_free(rgba);
890 }
891
addColorToModel(GtkTreeIter * iter,VisuUiColorComboboxClass * klass,ToolColor * color)892 static void addColorToModel(GtkTreeIter *iter, VisuUiColorComboboxClass* klass,
893 ToolColor* color)
894 {
895 char str[20], strAlpha[20];
896 GdkPixbuf *pixbufColorBox;
897 GdkPixbuf *pixbufColorAlphaBox;
898
899 if (!color || !klass)
900 return;
901 sprintf(strAlpha, "(#%02x%02x%02x%02x)", (int)(color->rgba[0] * 255.),
902 (int)(color->rgba[1] * 255.),
903 (int)(color->rgba[2] * 255.),
904 (int)(color->rgba[3] * 255.));
905 sprintf(str, "(#%02x%02x%02x)", (int)(color->rgba[0] * 255.),
906 (int)(color->rgba[1] * 255.),
907 (int)(color->rgba[2] * 255.));
908 pixbufColorAlphaBox = tool_color_get_stamp(color, TRUE);
909 pixbufColorBox = tool_color_get_stamp(color, FALSE);
910 gtk_list_store_append(klass->listStoredColors, iter);
911 gtk_list_store_set(klass->listStoredColors, iter,
912 COLUMN_COLOR_PIXBUF_ALPHA, pixbufColorAlphaBox,
913 COLUMN_COLOR_PIXBUF , pixbufColorBox,
914 COLUMN_COLOR_LABEL_ALPHA , strAlpha,
915 COLUMN_COLOR_LABEL , str,
916 COLUMN_COLOR_POINTER_TO , (gpointer)color,
917 -1);
918 DBG_fprintf(stderr, "Gtk VisuUiColorCombobox: appending a new color '%s'.\n",
919 strAlpha);
920 g_object_unref(pixbufColorAlphaBox);
921 g_object_unref(pixbufColorBox);
922 }
923 /**
924 * visu_ui_color_combobox_setSelection:
925 * @colorComboBox: a #VisuUiColorCombobox widget ;
926 * @color: a #ToolColor object.
927 *
928 * Use this method to set the ComboBox on the given color. This emits a 'color-channel'
929 * signal if the color is changed, which means, a previous color has been modified,
930 * or a new color is selected.
931 *
932 * Returns: TRUE if the @color already exists in the model.
933 *
934 * Since: 3.1
935 */
visu_ui_color_combobox_setSelection(VisuUiColorCombobox * colorComboBox,ToolColor * color)936 gboolean visu_ui_color_combobox_setSelection(VisuUiColorCombobox* colorComboBox, ToolColor *color)
937 {
938 GtkTreeIter iter;
939 gboolean validIter;
940 GObjectClass *klass;
941 GtkListStore *model;
942 ToolColor *tmpColor;
943
944 g_return_val_if_fail(color && VISU_IS_UI_COLOR_COMBOBOX(colorComboBox), FALSE);
945
946 DBG_fprintf(stderr, "Gtk VisuUiColorCombobox: select a new color %p.\n", (gpointer)color);
947 klass = G_OBJECT_GET_CLASS(colorComboBox);
948 model = GTK_LIST_STORE(VISU_UI_COLOR_COMBOBOX_CLASS(klass)->listStoredColors);
949 validIter = gtk_tree_model_get_iter_first(GTK_TREE_MODEL(model), &iter);
950 while (validIter)
951 {
952 gtk_tree_model_get(GTK_TREE_MODEL(model), &iter,
953 COLUMN_COLOR_POINTER_TO, &tmpColor,
954 -1);
955 if (tmpColor && tool_color_equal(tmpColor, color))
956 {
957 gtk_combo_box_set_active_iter(GTK_COMBO_BOX(colorComboBox), &iter);
958 return TRUE;
959 }
960 validIter = gtk_tree_model_iter_next(GTK_TREE_MODEL(model), &iter);
961 }
962 return FALSE;
963 }
964 /**
965 * visu_ui_color_combobox_setRangeColor:
966 * @colorComboBox: a #VisuUiColorCombobox widget ;
967 * @rgba: 4 floating point values ;
968 * @raiseSignal: if TRUE a material-value-changed can be raised.
969 *
970 * Change the values for the ranges that control the color. If the color exists
971 * in the list, it is also selected.
972 * This is possible only if the @colorComboBox has been created with
973 * visu_ui_color_combobox_newWithRanges().
974 *
975 * Since: 3.3
976 */
visu_ui_color_combobox_setRangeColor(VisuUiColorCombobox * colorComboBox,const float rgba[4],gboolean raiseSignal)977 void visu_ui_color_combobox_setRangeColor(VisuUiColorCombobox *colorComboBox,
978 const float rgba[4],
979 gboolean raiseSignal)
980 {
981 int pos, i;
982 ToolColor *color;
983
984 color = tool_color_getByValues(&pos, rgba[0], rgba[1], rgba[2], rgba[3]);
985 if (!color)
986 {
987 gtk_combo_box_set_active(GTK_COMBO_BOX(colorComboBox), -1);
988 if (raiseSignal)
989 for (i = 0; i < 4; i++)
990 gtk_range_set_value(GTK_RANGE(colorComboBox->rgbRanges[i]),
991 (gdouble)rgba[i]);
992 else
993 for (i = 0; i < 4; i++)
994 {
995 g_signal_handler_block(G_OBJECT(colorComboBox->rgbRanges[i]),
996 colorComboBox->rgbSignals[i]);
997 gtk_range_set_value(GTK_RANGE(colorComboBox->rgbRanges[i]),
998 (gdouble)rgba[i]);
999 g_signal_handler_unblock(G_OBJECT(colorComboBox->rgbRanges[i]),
1000 colorComboBox->rgbSignals[i]);
1001 }
1002 }
1003 else
1004 {
1005 if (raiseSignal)
1006 gtk_combo_box_set_active(GTK_COMBO_BOX(colorComboBox), pos + 1);
1007 else
1008 {
1009 colorComboBox->previouslySelectedColor = color;
1010 g_signal_handler_block(G_OBJECT(colorComboBox),
1011 colorComboBox->comboSignal);
1012 gtk_combo_box_set_active(GTK_COMBO_BOX(colorComboBox), pos + 1);
1013 g_signal_handler_unblock(G_OBJECT(colorComboBox),
1014 colorComboBox->comboSignal);
1015 for (i = 0; i < 4; i++)
1016 {
1017 g_signal_handler_block(G_OBJECT(colorComboBox->rgbRanges[i]),
1018 colorComboBox->rgbSignals[i]);
1019 gtk_range_set_value(GTK_RANGE(colorComboBox->rgbRanges[i]),
1020 (gdouble)rgba[i]);
1021 g_signal_handler_unblock(G_OBJECT(colorComboBox->rgbRanges[i]),
1022 colorComboBox->rgbSignals[i]);
1023 }
1024 }
1025 }
1026 }
1027
1028
onNewColorAvailable(ToolPool * pool _U_,ToolColor * newColor,gpointer data)1029 static void onNewColorAvailable(ToolPool *pool _U_, ToolColor* newColor, gpointer data)
1030 {
1031 VisuUiColorComboboxClass *klass;
1032 GtkTreeIter iter;
1033
1034 g_return_if_fail(data);
1035
1036 DBG_fprintf(stderr, "Gtk VisuUiColorComboboxClass: catch the 'new-element' signal.\n");
1037 klass = VISU_UI_COLOR_COMBOBOX_CLASS(data);
1038 addColorToModel(&iter, klass, newColor);
1039 }
1040 /**
1041 * visu_ui_color_combobox_getSelection:
1042 * @colorComboBox: a #VisuUiColorCombobox widget.
1043 *
1044 * The user can access to the selected #ToolColor object using this method.
1045 *
1046 * Returns: (transfer none): a pointer to the selected #ToolColor
1047 * object (or NULL). This object is read-only.
1048 *
1049 * Since: 3.1
1050 */
visu_ui_color_combobox_getSelection(VisuUiColorCombobox * colorComboBox)1051 const ToolColor* visu_ui_color_combobox_getSelection(VisuUiColorCombobox *colorComboBox)
1052 {
1053 gboolean validIter;
1054 GtkTreeIter iter;
1055 ToolColor *color;
1056 GObjectClass *klass;
1057
1058 g_return_val_if_fail(VISU_IS_UI_COLOR_COMBOBOX(colorComboBox), (ToolColor*)0);
1059
1060 validIter = gtk_combo_box_get_active_iter(GTK_COMBO_BOX(colorComboBox), &iter);
1061 if (!validIter)
1062 return (const ToolColor*)0;
1063
1064 color = (ToolColor*)0;
1065 klass = G_OBJECT_GET_CLASS(colorComboBox);
1066 gtk_tree_model_get(GTK_TREE_MODEL(VISU_UI_COLOR_COMBOBOX_CLASS(klass)->listStoredColors), &iter,
1067 COLUMN_COLOR_POINTER_TO, &color,
1068 -1);
1069 return color;
1070 }
1071 /**
1072 * visu_ui_color_combobox_getPixbufFromColor:
1073 * @colorComboBox: a #VisuUiColorCombobox widget ;
1074 * @color: a #ToolColor object.
1075 *
1076 * The @colorComboBox has little pixbufs to represent the color. User methods can
1077 * use these pixbufs but should considered them read-only.
1078 *
1079 * Returns: (transfer full): a pixbuf pointer corresponding to the
1080 * little image shown on the @colorComboBox.
1081 *
1082 * Since: 3.1
1083 */
visu_ui_color_combobox_getPixbufFromColor(VisuUiColorCombobox * colorComboBox,ToolColor * color)1084 GdkPixbuf* visu_ui_color_combobox_getPixbufFromColor(VisuUiColorCombobox *colorComboBox, ToolColor *color)
1085 {
1086 GtkTreeIter iter;
1087 gboolean validIter;
1088 GdkPixbuf *pixbuf;
1089 ToolColor *cl;
1090 GtkListStore *model;
1091
1092 g_return_val_if_fail(colorComboBox && color, (GdkPixbuf*)0);
1093
1094 model = VISU_UI_COLOR_COMBOBOX_CLASS(G_OBJECT_GET_CLASS(colorComboBox))->listStoredColors;
1095 validIter = gtk_tree_model_get_iter_first(GTK_TREE_MODEL(model), &iter);
1096 while (validIter)
1097 {
1098 pixbuf = (GdkPixbuf*)0;
1099 cl = (ToolColor*)0;
1100 if (colorComboBox->hasAlphaChannel)
1101 gtk_tree_model_get(GTK_TREE_MODEL(model), &iter,
1102 COLUMN_COLOR_PIXBUF_ALPHA, &pixbuf,
1103 COLUMN_COLOR_POINTER_TO, &cl,
1104 -1);
1105 else
1106 gtk_tree_model_get(GTK_TREE_MODEL(model), &iter,
1107 COLUMN_COLOR_PIXBUF, &pixbuf,
1108 COLUMN_COLOR_POINTER_TO, &cl,
1109 -1);
1110 if (cl && tool_color_equal(color, cl))
1111 return pixbuf;
1112 if (pixbuf)
1113 g_object_unref(pixbuf);
1114 validIter = gtk_tree_model_iter_next(GTK_TREE_MODEL(model), &iter);
1115 }
1116 return (GdkPixbuf*)0;
1117 }
1118 /**
1119 * visu_ui_color_combobox_setRangeMaterial:
1120 * @colorComboBox: a #VisuUiColorCombobox widget ;
1121 * @material: TOOL_MATERIAL_N_VALUES (see #ToolMaterialIds) floating point values ;
1122 * @raiseSignal: if TRUE a material-value-changed can be raised.
1123 *
1124 * Change the values for the ranges that control the light (emission, diffuse...).
1125 * This is possible only if the @colorComboBox has been created with
1126 * visu_ui_color_combobox_newWithRanges().
1127 *
1128 * Since: 3.3
1129 */
visu_ui_color_combobox_setRangeMaterial(VisuUiColorCombobox * colorComboBox,const float material[TOOL_MATERIAL_N_VALUES],gboolean raiseSignal)1130 void visu_ui_color_combobox_setRangeMaterial(VisuUiColorCombobox *colorComboBox,
1131 const float material[TOOL_MATERIAL_N_VALUES],
1132 gboolean raiseSignal)
1133 {
1134 int i;
1135
1136 g_return_if_fail(VISU_IS_UI_COLOR_COMBOBOX(colorComboBox));
1137 g_return_if_fail(colorComboBox->withRanges);
1138
1139 if (raiseSignal)
1140 for (i = 0; i < TOOL_MATERIAL_N_VALUES; i++)
1141 gtk_range_set_value(GTK_RANGE(colorComboBox->materialRanges[i]),
1142 (gdouble)material[i]);
1143 else
1144 for (i = 0; i < TOOL_MATERIAL_N_VALUES; i++)
1145 {
1146 g_signal_handler_block(G_OBJECT(colorComboBox->materialRanges[i]),
1147 colorComboBox->materialSignals[i]);
1148 gtk_range_set_value(GTK_RANGE(colorComboBox->materialRanges[i]),
1149 (gdouble)material[i]);
1150 g_signal_handler_unblock(G_OBJECT(colorComboBox->materialRanges[i]),
1151 colorComboBox->materialSignals[i]);
1152 }
1153 }
1154 /**
1155 * visu_ui_color_combobox_getRangeMaterial:
1156 * @colorComboBox: a #VisuUiColorCombobox widget.
1157 *
1158 * If the @colorComboBox uses ranges (see visu_ui_color_combobox_newWithRanges()), this method
1159 * is used to get the values from the material ranges.
1160 *
1161 * Returns: (array fixed-size=5) (transfer full): a newly created array of size
1162 * TOOL_MATERIAL_N_VALUES (see #ToolMaterialIds). Use g_free() to delete it.
1163 *
1164 * Since: 3.3
1165 */
visu_ui_color_combobox_getRangeMaterial(VisuUiColorCombobox * colorComboBox)1166 float* visu_ui_color_combobox_getRangeMaterial(VisuUiColorCombobox *colorComboBox)
1167 {
1168 int i;
1169 float *values;
1170
1171 g_return_val_if_fail(VISU_IS_UI_COLOR_COMBOBOX(colorComboBox), (float*)0);
1172 g_return_val_if_fail(colorComboBox->withRanges, (float*)0);
1173
1174 values = g_malloc(sizeof(float) * TOOL_MATERIAL_N_VALUES);
1175 for (i = 0; i < TOOL_MATERIAL_N_VALUES; i++)
1176 values[i] = (float)gtk_range_get_value(GTK_RANGE(colorComboBox->materialRanges[i]));
1177
1178 return values;
1179 }
1180 /**
1181 * visu_ui_color_combobox_getRangeColor:
1182 * @colorComboBox: a #VisuUiColorCombobox widget.
1183 *
1184 * If the @colorComboBox uses ranges (see visu_ui_color_combobox_newWithRanges()), this method
1185 * is used to get the values from the color ranges.
1186 *
1187 * Returns: (array fixed-size=4) (transfer full): a newly created
1188 * array of size 4. Use g_free() to delete it.
1189 *
1190 * Since: 3.2
1191 */
visu_ui_color_combobox_getRangeColor(VisuUiColorCombobox * colorComboBox)1192 float* visu_ui_color_combobox_getRangeColor(VisuUiColorCombobox *colorComboBox)
1193 {
1194 int i;
1195 float *values;
1196
1197 g_return_val_if_fail(VISU_IS_UI_COLOR_COMBOBOX(colorComboBox), (float*)0);
1198 g_return_val_if_fail(colorComboBox->withRanges, (float*)0);
1199
1200 values = g_malloc(sizeof(float) * 4);
1201 for (i = 0; i < 4; i++)
1202 values[i] = (float)gtk_range_get_value(GTK_RANGE(colorComboBox->rgbRanges[i]));
1203
1204 return values;
1205 }
1206
1207
1208 /* Under developpement method, not used at the present time. */
1209 /* void createColorSelectionCustomList(GtkColorSelectionDialog *selection) */
1210 /* { */
1211 /* GtkWidget *hbox; */
1212 /* GtkWidget *buttonF, *buttonB, *button; */
1213 /* GtkWidget *image; */
1214 /* GtkWidget *table; */
1215 /* GtkWidget *label; */
1216 /* GtkWidget *align; */
1217 /* gboolean validIter; */
1218 /* GdkPixbuf *pixbuf; */
1219 /* int i; */
1220 /* gboolean usedPrevNext; */
1221 /* #define N_SHOW_COLOR 15 */
1222 /* GtkTreeIter iter; */
1223 /* GtkWidget *imageGroup; */
1224 /* GtkTreeIter *iterStored; */
1225
1226 /* hbox = gtk_hbox_new(FALSE, 0); */
1227 /* gtk_widget_show(hbox); */
1228 /* gtk_box_pack_start(GTK_BOX(GTK_DIALOG(selection)->vbox), hbox, FALSE, FALSE, 2); */
1229
1230 /* label = gtk_label_new(_("Stored colors:")); */
1231 /* gtk_misc_set_alignment(GTK_MISC(label), 0., 0.5); */
1232 /* gtk_widget_show(label); */
1233 /* gtk_box_pack_start(GTK_BOX(hbox), label, TRUE, TRUE, 2); */
1234
1235 /* button = gtk_button_new_from_stock(GTK_STOCK_REMOVE); */
1236 /* gtk_widget_show(button); */
1237 /* gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 2); */
1238
1239 /* usedPrevNext = (gtk_tree_model_iter_n_children(GTK_TREE_MODEL(listStoredColors), NULL) >= N_SHOW_COLOR); */
1240
1241 /* hbox = gtk_hbox_new(FALSE, 0); */
1242 /* gtk_widget_show(hbox); */
1243 /* gtk_box_pack_start(GTK_BOX(GTK_DIALOG(selection)->vbox), hbox, FALSE, FALSE, 2); */
1244
1245 /* if (usedPrevNext) */
1246 /* { */
1247 /* buttonB = gtk_button_new (); */
1248 /* gtk_widget_show(buttonB); */
1249 /* gtk_box_pack_start(GTK_BOX(hbox), buttonB, FALSE, FALSE, 2); */
1250 /* image = gtk_image_new_from_stock(GTK_STOCK_GO_BACK, GTK_ICON_SIZE_BUTTON); */
1251 /* gtk_widget_show (image); */
1252 /* gtk_container_add(GTK_CONTAINER(buttonB), image); */
1253 /* } */
1254
1255 /* align= gtk_alignment_new(0.5, 0.5, 0., 0.); */
1256 /* gtk_widget_show(align); */
1257 /* gtk_box_pack_start(GTK_BOX(hbox), align, FALSE, FALSE, 2); */
1258 /* table = gtk_table_new(1, 10, FALSE); */
1259 /* gtk_widget_show(table); */
1260 /* gtk_container_add(GTK_CONTAINER(align), table); */
1261
1262 /* if (usedPrevNext) */
1263 /* { */
1264 /* buttonF = gtk_button_new (); */
1265 /* gtk_widget_show(buttonF); */
1266 /* gtk_box_pack_start(GTK_BOX(hbox), buttonF, FALSE, FALSE, 2); */
1267 /* image = gtk_image_new_from_stock(GTK_STOCK_GO_FORWARD, GTK_ICON_SIZE_BUTTON); */
1268 /* gtk_widget_show (image); */
1269 /* gtk_container_add(GTK_CONTAINER(buttonF), image); */
1270 /* } */
1271
1272 /* Put all the colors. */
1273 /* imageGroup = (GtkWidget*)0; */
1274 /* i = 0; */
1275 /* validIter = gtk_tree_model_get_iter_first(GTK_TREE_MODEL(listStoredColors), &iter); */
1276 /* while (validIter && i < N_SHOW_COLOR) */
1277 /* { */
1278 /* pixbuf = (GdkPixbuf*)0; */
1279 /* gtk_tree_model_get(GTK_TREE_MODEL(listStoredColors), */
1280 /* &iter, COLUMN_COLOR_PIXBUF_ALPHA, */
1281 /* &pixbuf, -1); */
1282 /* if (pixbuf) */
1283 /* { */
1284 /* if (!imageGroup) */
1285 /* { */
1286 /* imageGroup = gtk_radio_button_new(NULL); */
1287 /* button = imageGroup; */
1288 /* } */
1289 /* else */
1290 /* button = gtk_radio_button_new_from_widget(GTK_RADIO_BUTTON(imageGroup)); */
1291 /* gtk_widget_show(button); */
1292 /* gtk_table_attach(GTK_TABLE(table), button, i, i + 1, 0, 1, GTK_FILL, GTK_FILL, 2, 2); */
1293 /* image = gtk_image_new_from_pixbuf(pixbuf); */
1294 /* gtk_widget_show(image); */
1295 /* gtk_container_add(GTK_CONTAINER(button), image); */
1296
1297 /* iterStored = gtk_tree_iter_copy(&iter); */
1298 /* i += 1; */
1299 /* } */
1300 /* validIter = gtk_tree_model_iter_next(GTK_TREE_MODEL(listStoredColors), &iter); */
1301 /* } */
1302 /* } */
1303