set up the treeview reflections
[hkl.git] / gui / hkl-gui-pseudoaxes.c
blobb2691a54a04258b89a0c39ff2c497d48e01d2a23
1 /* This file is part of the hkl library.
3 * The hkl library is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 3 of the License, or
6 * (at your option) any later version.
8 * The hkl library is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
13 * You should have received a copy of the GNU General Public License
14 * along with the hkl library. If not, see <http://www.gnu.org/licenses/>.
16 * Copyright (C) 2003-2013 Synchrotron SOLEIL
17 * L'Orme des Merisiers Saint-Aubin
18 * BP 48 91192 GIF-sur-YVETTE CEDEX
20 * Authors: Picca Frédéric-Emmanuel <picca@synchrotron-soleil.fr>
23 #include "hkl-gui-pseudoaxes.h"
24 #include "hkl.h"
25 #include <gtk/gtk.h>
26 #include <stdlib.h>
27 #include <string.h>
28 #include <float.h>
29 #include <math.h>
31 G_DEFINE_TYPE (HklGuiEngine, hkl_gui_engine, G_TYPE_OBJECT);
33 enum {
34 PROP_0,
36 PROP_ENGINE,
38 N_PROPERTIES
41 /* Keep a pointer to the properties definition */
42 static GParamSpec *obj_properties[N_PROPERTIES] = { NULL, };
44 enum {
45 CHANGED,
47 N_SIGNALS
50 static guint signals[N_SIGNALS] = { 0 };
52 struct _HklGuiEnginePrivate {
53 /* Properties */
54 HklEngine* engine;
55 /* Properties */
57 GtkBuilder *builder;
58 GtkFrame* frame1;
59 GtkLabel* label2;
60 GtkComboBox* combobox1;
61 GtkExpander* expander1;
62 GtkTreeView* treeview1;
63 GtkButton* button1;
64 GtkButton* button2;
65 GtkListStore* store_mode;
66 GtkListStore* store_pseudo;
67 GtkListStore* store_mode_parameter;
70 #define HKL_GUI_ENGINE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), HKL_GUI_TYPE_ENGINE, HklGuiEnginePrivate))
72 static void
73 set_property (GObject *object, guint prop_id,
74 const GValue *value, GParamSpec *pspec)
76 HklGuiEngine *self = HKL_GUI_ENGINE (object);
77 HklGuiEnginePrivate *priv = HKL_GUI_ENGINE_GET_PRIVATE(self);
79 switch (prop_id) {
80 case PROP_ENGINE:
81 hkl_gui_engine_set_engine(self, g_value_get_pointer (value));
82 break;
83 default:
84 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
85 break;
89 static void
90 get_property (GObject *object, guint prop_id,
91 GValue *value, GParamSpec *pspec)
93 HklGuiEngine *self = HKL_GUI_ENGINE (object);
94 HklGuiEnginePrivate *priv = HKL_GUI_ENGINE_GET_PRIVATE(self);
96 switch (prop_id)
98 case PROP_ENGINE:
99 g_value_set_pointer (value, hkl_gui_engine_get_engine (self));
100 break;
101 default:
102 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
103 break;
107 static void
108 finalize (GObject* object)
110 HklGuiEnginePrivate *priv = HKL_GUI_ENGINE_GET_PRIVATE(object);
112 g_object_unref(priv->builder);
114 G_OBJECT_CLASS (hkl_gui_engine_parent_class)->finalize (object);
118 HklGuiEngine*
119 hkl_gui_engine_new (HklEngine* engine)
121 return g_object_new (HKL_GUI_TYPE_ENGINE,
122 "engine", engine,
123 NULL);
127 HklEngine*
128 hkl_gui_engine_get_engine (HklGuiEngine *self)
130 HklGuiEnginePrivate *priv = HKL_GUI_ENGINE_GET_PRIVATE(self);
132 return priv->engine;
136 GtkFrame*
137 hkl_gui_engine_get_frame(HklGuiEngine *self)
139 HklGuiEnginePrivate *priv = HKL_GUI_ENGINE_GET_PRIVATE(self);
141 return priv->frame1;
145 static void
146 update_pseudo_axis (HklGuiEngine* self)
148 HklGuiEnginePrivate *priv = HKL_GUI_ENGINE_GET_PRIVATE(self);
149 GtkTreeIter iter = {0};
150 darray_parameter *parameters;
151 HklParameter **parameter;
153 g_return_if_fail (self != NULL);
155 gtk_list_store_clear (priv->store_pseudo);
156 parameters = hkl_engine_pseudo_axes (priv->engine);
157 darray_foreach(parameter, *parameters){
158 gtk_list_store_append (priv->store_pseudo,
159 &iter);
160 gtk_list_store_set (priv->store_pseudo,
161 &iter,
162 PSEUDO_COL_NAME, hkl_parameter_name_get (*parameter),
163 PSEUDO_COL_VALUE, hkl_parameter_value_unit_get (*parameter),
164 PSEUDO_COL_PSEUDO, *parameter,
165 -1);
170 static void
171 update_mode (HklGuiEngine* self)
173 HklGuiEnginePrivate *priv = HKL_GUI_ENGINE_GET_PRIVATE(self);
174 GtkTreeIter iter = {0};
175 GtkTreeIter current = {0};
176 darray_mode *modes;
177 HklMode **mode;
179 g_return_if_fail (self != NULL);
181 modes = hkl_engine_modes(priv->engine);
182 gtk_list_store_clear (priv->store_mode);
183 darray_foreach(mode, *modes){
184 gtk_list_store_append (priv->store_mode,
185 &iter);
186 gtk_list_store_set (priv->store_mode,
187 &iter,
188 MODE_COL_NAME, hkl_mode_name(*mode),
189 -1);
190 if(*mode == hkl_engine_mode(priv->engine))
191 current = iter;
194 /* now set the active row with the current mode */
195 gtk_combo_box_set_active_iter(priv->combobox1, &current);
199 static void
200 update_mode_parameters (HklGuiEngine* self)
202 HklGuiEnginePrivate *priv = HKL_GUI_ENGINE_GET_PRIVATE(self);
203 HklMode *mode;
205 g_return_if_fail (self != NULL);
207 mode = hkl_engine_mode (priv->engine);
208 if (mode){
209 darray_parameter *parameters;
210 HklParameter **parameter;
212 parameters = hkl_mode_parameters(mode);
213 if(darray_size (*parameters)){
214 GtkTreeIter iter = {0};
216 gtk_list_store_clear (priv->store_mode_parameter);
217 darray_foreach (parameter, *parameters){
218 gtk_list_store_append (priv->store_mode_parameter, &iter);
219 gtk_list_store_set (priv->store_mode_parameter,
220 &iter,
221 PSEUDO_COL_NAME, hkl_parameter_name_get (*parameter),
222 PSEUDO_COL_VALUE, hkl_parameter_value_unit_get (*parameter),
223 -1);
225 gtk_expander_set_expanded (priv->expander1, TRUE);
226 gtk_widget_show (GTK_WIDGET (priv->expander1));
227 }else
228 gtk_widget_hide (GTK_WIDGET (priv->expander1));
229 }else
230 gtk_widget_hide (GTK_WIDGET (priv->expander1));
234 void
235 hkl_gui_engine_update (HklGuiEngine* self)
237 HklGuiEnginePrivate *priv = HKL_GUI_ENGINE_GET_PRIVATE(self);
238 GtkTreeViewColumn* col;
239 GList* cells;
241 g_return_if_fail (self != NULL);
243 update_pseudo_axis (self);
245 col = gtk_tree_view_get_column(priv->treeview1, 1);
246 cells = gtk_cell_layout_get_cells(GTK_CELL_LAYOUT(col));
247 g_object_set (G_OBJECT(cells->data), "background", NULL, NULL);
248 g_list_free(cells);
252 void hkl_gui_engine_set_engine (HklGuiEngine *self,
253 HklEngine *engine)
255 HklGuiEnginePrivate *priv = HKL_GUI_ENGINE_GET_PRIVATE(self);
257 g_return_if_fail (self != NULL);
258 g_return_if_fail (engine != NULL);
260 priv->engine = engine;
262 gtk_label_set_label (priv->label2,
263 hkl_engine_name(priv->engine));
265 update_pseudo_axis (self);
266 update_mode (self);
267 update_mode_parameters (self);
269 hkl_gui_engine_update(self);
272 static void
273 combobox1_changed_cb (GtkComboBox* combobox, HklGuiEngine* self)
275 HklGuiEnginePrivate *priv = HKL_GUI_ENGINE_GET_PRIVATE(self);
276 gchar *mode;
277 GtkTreeIter iter = {0};
279 g_return_if_fail (self != NULL);
280 g_return_if_fail (combobox != NULL);
282 if(gtk_combo_box_get_active_iter(combobox, &iter)){
283 gtk_tree_model_get(GTK_TREE_MODEL(priv->store_mode),
284 &iter,
285 MODE_COL_NAME, &mode,
286 -1);
287 hkl_engine_select_mode_by_name(priv->engine, mode);
288 update_mode_parameters(self);
292 static gboolean
293 _set_pseudo(GtkTreeModel *model,
294 GtkTreePath *path,
295 GtkTreeIter *iter,
296 gpointer data)
298 HklParameter *parameter;
299 double value;
301 gtk_tree_model_get (model, iter,
302 PSEUDO_COL_PSEUDO, &parameter,
303 PSEUDO_COL_VALUE, &value,
304 -1);
305 hkl_parameter_value_unit_set(parameter, value, NULL);
307 return FALSE;
310 static void
311 button1_clicked_cb (GtkButton* button, HklGuiEngine* self)
313 HklGuiEnginePrivate *priv = HKL_GUI_ENGINE_GET_PRIVATE(self);
315 g_return_if_fail (self != NULL);
316 g_return_if_fail (button != NULL);
318 gtk_tree_model_foreach(GTK_TREE_MODEL(priv->store_pseudo),
319 _set_pseudo,
320 self);
322 g_signal_emit(self, signals[CHANGED], 0);
326 static void
327 button2_clicked_cb (GtkButton* button, HklGuiEngine* self)
329 HklGuiEnginePrivate *priv = HKL_GUI_ENGINE_GET_PRIVATE(self);
331 g_return_if_fail (self != NULL);
332 g_return_if_fail (button != NULL);
334 if(hkl_engine_initialize(priv->engine, NULL)){
335 /* some init method update the parameters */
336 update_mode_parameters(self);
341 static void
342 cell_tree_view_pseudo_axis_value_edited_cb (GtkCellRendererText* renderer,
343 const gchar* path,
344 const gchar* new_text,
345 HklGuiEngine* self)
347 HklGuiEnginePrivate *priv = HKL_GUI_ENGINE_GET_PRIVATE(self);
348 GtkTreeIter iter = {0};
349 GtkListStore* model = NULL;
351 g_return_if_fail (self != NULL);
352 g_return_if_fail (renderer != NULL);
353 g_return_if_fail (path != NULL);
354 g_return_if_fail (new_text != NULL);
356 if (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL(priv->store_pseudo),
357 &iter, path)) {
358 gdouble value = 0.0;
359 HklPseudoAxis* pseudo = NULL;
361 value = atof(new_text);
362 gtk_tree_model_get (GTK_TREE_MODEL(priv->store_pseudo),
363 &iter,
364 PSEUDO_COL_PSEUDO, &pseudo, -1);
366 if (pseudo) {
367 g_object_set (G_OBJECT(renderer), "background", "red", NULL, NULL);
368 gtk_list_store_set (priv->store_pseudo,
369 &iter,
370 PSEUDO_COL_VALUE, value,
371 -1);
376 static void hkl_gui_engine_class_init (HklGuiEngineClass * class)
378 GObjectClass *gobject_class = G_OBJECT_CLASS (class);
380 g_type_class_add_private (class, sizeof (HklGuiEnginePrivate));
382 /* virtual methods */
383 gobject_class->finalize = finalize;
384 gobject_class->set_property = set_property;
385 gobject_class->get_property = get_property;
387 /* properties */
388 obj_properties[PROP_ENGINE] =
389 g_param_spec_pointer ("engine",
390 "Engine",
391 "The Hkl Engine used underneath",
392 G_PARAM_CONSTRUCT_ONLY |
393 G_PARAM_READWRITE |
394 G_PARAM_STATIC_STRINGS);
396 g_object_class_install_properties (gobject_class,
397 N_PROPERTIES,
398 obj_properties);
400 /* signals */
401 signals[CHANGED] =
402 g_signal_new ("changed",
403 HKL_GUI_TYPE_ENGINE,
404 G_SIGNAL_RUN_LAST,
405 0, /* class offset */
406 NULL, /* accumulator */
407 NULL, /* accu_data */
408 g_cclosure_marshal_VOID__VOID,
409 G_TYPE_NONE, /* return_type */
414 static void _connect_renderer(gpointer data, gpointer user_data)
416 GtkCellRenderer *renderer = GTK_CELL_RENDERER(data);
417 HklGuiEngine *self = HKL_GUI_ENGINE(user_data);
419 g_signal_connect_object (renderer,
420 "edited",
421 (GCallback) cell_tree_view_pseudo_axis_value_edited_cb,
422 self, 0);
425 static void hkl_gui_engine_init (HklGuiEngine * self)
427 HklGuiEnginePrivate *priv = HKL_GUI_ENGINE_GET_PRIVATE(self);
428 GtkBuilder *builder;
429 GtkTreeViewColumn* col;
430 GList* cells;
432 priv->engine = NULL;
433 priv->builder = builder = gtk_builder_new ();
435 gtk_builder_add_from_file (builder, "pseudo.ui", NULL);
437 priv->frame1 = GTK_FRAME(gtk_builder_get_object(builder, "frame1"));
438 priv->label2 = GTK_LABEL(gtk_builder_get_object(builder, "label2"));
439 priv->combobox1 = GTK_COMBO_BOX(gtk_builder_get_object(builder, "combobox1"));
440 priv->expander1 = GTK_EXPANDER(gtk_builder_get_object(builder, "expander1"));
441 priv->treeview1 = GTK_TREE_VIEW(gtk_builder_get_object(builder, "treeview1"));
442 priv->button1 = GTK_BUTTON(gtk_builder_get_object(builder, "button1"));
443 priv->button2 = GTK_BUTTON(gtk_builder_get_object(builder, "button2"));
445 priv->store_mode = GTK_LIST_STORE(gtk_builder_get_object (builder, "liststore1"));
446 priv->store_pseudo = GTK_LIST_STORE(gtk_builder_get_object (builder, "liststore2"));
447 priv->store_mode_parameter = GTK_LIST_STORE(gtk_builder_get_object (builder, "liststore3"));
449 gtk_builder_connect_signals (builder, self);
451 g_signal_connect_object (priv->combobox1,
452 "changed",
453 (GCallback) combobox1_changed_cb,
454 self, 0);
456 g_signal_connect_object (priv->button1,
457 "clicked",
458 (GCallback) button1_clicked_cb,
459 self, 0);
461 g_signal_connect_object (priv->button2,
462 "clicked",
463 (GCallback) button2_clicked_cb,
464 self, 0);
466 col = gtk_tree_view_get_column (priv->treeview1, 1);
467 cells = gtk_cell_layout_get_cells(GTK_CELL_LAYOUT(col));
468 g_list_foreach(cells, _connect_renderer, self);
469 g_list_free(cells);