[contrib] a [Transformation] is also a Transformation
[hkl.git] / gui / hkl-gui-pseudoaxes.c
blob46cf0677992afc1b7a360b0efc9e301fed012cfd
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-macros.h"
24 #include "hkl-gui-pseudoaxes.h"
25 #include "hkl.h"
26 #include <gtk/gtk.h>
27 #include <stdlib.h>
28 #include <string.h>
29 #include <float.h>
30 #include <math.h>
32 G_DEFINE_TYPE (HklGuiEngine, hkl_gui_engine, G_TYPE_OBJECT);
34 enum {
35 PROP_0,
37 PROP_ENGINE,
38 PROP_LISTSTORE,
40 N_PROPERTIES
43 /* Keep a pointer to the properties definition */
44 static GParamSpec *obj_properties[N_PROPERTIES] = { NULL, };
46 enum {
47 CHANGED,
49 N_SIGNALS
52 static guint signals[N_SIGNALS] = { 0 };
54 struct _HklGuiEnginePrivate {
55 /* Properties */
56 HklEngine* engine;
57 /* Properties */
59 GtkBuilder *builder;
60 GtkFrame* frame1;
61 GtkLabel* label2;
62 GtkComboBox* combobox1;
63 GtkExpander* expander1;
64 GtkTreeView* treeview1;
65 GtkButton* button1;
66 GtkButton* button2;
67 GtkListStore* store_mode;
68 GtkListStore* store_pseudo;
69 GtkListStore* store_mode_parameter;
72 #define HKL_GUI_ENGINE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), HKL_GUI_TYPE_ENGINE, HklGuiEnginePrivate))
74 static void
75 set_property (GObject *object, guint prop_id,
76 const GValue *value, GParamSpec *pspec)
78 HklGuiEngine *self = HKL_GUI_ENGINE (object);
79 HklGuiEnginePrivate *priv = HKL_GUI_ENGINE_GET_PRIVATE(self);
81 switch (prop_id) {
82 case PROP_ENGINE:
83 hkl_gui_engine_set_engine(self, g_value_get_pointer (value));
84 break;
85 default:
86 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
87 break;
91 static void
92 get_property (GObject *object, guint prop_id,
93 GValue *value, GParamSpec *pspec)
95 HklGuiEngine *self = HKL_GUI_ENGINE (object);
96 HklGuiEnginePrivate *priv = HKL_GUI_ENGINE_GET_PRIVATE(self);
98 switch (prop_id)
100 case PROP_ENGINE:
101 g_value_set_pointer (value, hkl_gui_engine_get_engine (self));
102 break;
103 case PROP_LISTSTORE:
104 g_value_set_object(value, hkl_gui_engine_get_liststore (self));
105 break;
106 default:
107 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
108 break;
112 static void
113 finalize (GObject* object)
115 HklGuiEnginePrivate *priv = HKL_GUI_ENGINE_GET_PRIVATE(object);
117 g_object_unref(priv->builder);
119 G_OBJECT_CLASS (hkl_gui_engine_parent_class)->finalize (object);
123 HklGuiEngine*
124 hkl_gui_engine_new (HklEngine* engine)
126 return g_object_new (HKL_GUI_TYPE_ENGINE,
127 "engine", engine,
128 NULL);
132 HklEngine*
133 hkl_gui_engine_get_engine (HklGuiEngine *self)
135 HklGuiEnginePrivate *priv = HKL_GUI_ENGINE_GET_PRIVATE(self);
137 return priv->engine;
141 GtkListStore*
142 hkl_gui_engine_get_liststore (HklGuiEngine *self)
144 HklGuiEnginePrivate *priv = HKL_GUI_ENGINE_GET_PRIVATE(self);
146 return priv->store_pseudo;
149 GtkFrame*
150 hkl_gui_engine_get_frame(HklGuiEngine *self)
152 HklGuiEnginePrivate *priv = HKL_GUI_ENGINE_GET_PRIVATE(self);
154 return priv->frame1;
157 static void
158 update_pseudo_axis (HklGuiEngine* self)
160 HklGuiEnginePrivate *priv = HKL_GUI_ENGINE_GET_PRIVATE(self);
161 GtkTreeIter iter = {0};
162 const darray_string *parameters = hkl_engine_pseudo_axis_names_get (priv->engine);
163 unsigned int n_values = darray_size(*parameters);
164 double values[n_values];
165 GError *error = NULL;
166 unsigned int i;
168 g_return_if_fail (self != NULL);
170 gtk_list_store_clear (priv->store_pseudo);
171 if(!hkl_engine_pseudo_axis_values_get(priv->engine, values, n_values, HKL_UNIT_USER, &error)){
172 /* TODO check for the error */
173 g_clear_error(&error);
174 return;
177 for(i=0; i<n_values; ++i){
178 gtk_list_store_append (priv->store_pseudo,
179 &iter);
180 gtk_list_store_set (priv->store_pseudo,
181 &iter,
182 PSEUDO_COL_NAME, darray_item(*parameters, i),
183 PSEUDO_COL_IDX, i,
184 PSEUDO_COL_VALUE, values[i],
185 -1);
190 static void
191 update_mode (HklGuiEngine* self)
193 HklGuiEnginePrivate *priv = HKL_GUI_ENGINE_GET_PRIVATE(self);
194 GtkTreeIter iter = {0};
195 GtkTreeIter current = {0};
196 const darray_string *modes;
197 const char **mode;
199 g_return_if_fail (self != NULL);
201 modes = hkl_engine_modes_names_get(priv->engine);
202 gtk_list_store_clear (priv->store_mode);
203 darray_foreach(mode, *modes){
204 gtk_list_store_append (priv->store_mode,
205 &iter);
206 gtk_list_store_set (priv->store_mode,
207 &iter,
208 MODE_COL_NAME, *mode,
209 -1);
210 if(*mode == hkl_engine_current_mode_get(priv->engine))
211 current = iter;
214 /* now set the active row with the current mode */
215 gtk_combo_box_set_active_iter(priv->combobox1, &current);
219 static void
220 update_mode_parameters (HklGuiEngine* self)
222 HklGuiEnginePrivate *priv = HKL_GUI_ENGINE_GET_PRIVATE(self);
223 const darray_string *parameters = hkl_engine_parameters_names_get(priv->engine);
224 unsigned int n_values = darray_size(*parameters);
225 double values[n_values];
226 unsigned int i;
228 if(n_values){
229 GtkTreeIter iter = {0};
231 gtk_list_store_clear (priv->store_mode_parameter);
232 hkl_engine_parameters_values_get(priv->engine, values, n_values, HKL_UNIT_USER);
233 for(i=0; i<n_values; ++i){
234 gtk_list_store_append (priv->store_mode_parameter, &iter);
235 gtk_list_store_set (priv->store_mode_parameter,
236 &iter,
237 PSEUDO_COL_NAME, darray_item(*parameters, i),
238 PSEUDO_COL_IDX, i,
239 PSEUDO_COL_VALUE, values[i],
240 -1);
242 gtk_expander_set_expanded (priv->expander1, TRUE);
243 gtk_widget_show (GTK_WIDGET (priv->expander1));
244 }else
245 gtk_widget_hide (GTK_WIDGET (priv->expander1));
249 void
250 hkl_gui_engine_update (HklGuiEngine* self)
252 HklGuiEnginePrivate *priv = HKL_GUI_ENGINE_GET_PRIVATE(self);
253 GtkTreeViewColumn* col;
254 GList* cells;
256 g_return_if_fail (self != NULL);
258 update_pseudo_axis (self);
260 col = gtk_tree_view_get_column(priv->treeview1, 1);
261 cells = gtk_cell_layout_get_cells(GTK_CELL_LAYOUT(col));
262 g_object_set (G_OBJECT(cells->data), "background", NULL, NULL);
263 g_list_free(cells);
267 void hkl_gui_engine_set_engine (HklGuiEngine *self,
268 HklEngine *engine)
270 HklGuiEnginePrivate *priv = HKL_GUI_ENGINE_GET_PRIVATE(self);
272 g_return_if_fail (self != NULL);
273 g_return_if_fail (engine != NULL);
275 priv->engine = engine;
277 gtk_label_set_label (priv->label2,
278 hkl_engine_name_get(priv->engine));
280 update_pseudo_axis (self);
281 update_mode (self);
282 update_mode_parameters (self);
284 hkl_gui_engine_update(self);
287 static void
288 combobox1_changed_cb (GtkComboBox* combobox, HklGuiEngine* self)
290 HklGuiEnginePrivate *priv = HKL_GUI_ENGINE_GET_PRIVATE(self);
291 gchar *mode;
292 GtkTreeIter iter = {0};
294 g_return_if_fail (self != NULL);
295 g_return_if_fail (combobox != NULL);
297 if(gtk_combo_box_get_active_iter(combobox, &iter)){
298 gtk_tree_model_get(GTK_TREE_MODEL(priv->store_mode),
299 &iter,
300 MODE_COL_NAME, &mode,
301 -1);
302 if(!hkl_engine_current_mode_set(priv->engine, mode, NULL))
303 return;
304 update_mode_parameters(self);
308 static void
309 button1_clicked_cb (GtkButton* button, HklGuiEngine* self)
311 g_signal_emit(self, signals[CHANGED], 0);
315 static void
316 button2_clicked_cb (GtkButton* button, HklGuiEngine* self)
318 HklGuiEnginePrivate *priv = HKL_GUI_ENGINE_GET_PRIVATE(self);
320 if (HKL_ENGINE_CAPABILITIES_INITIALIZABLE & hkl_engine_capabilities_get(priv->engine)){
321 if(hkl_engine_initialized_set(priv->engine, TRUE, NULL)){
322 /* some init method update the parameters */
323 update_mode_parameters(self);
329 static void
330 cell_tree_view_pseudo_axis_value_edited_cb (GtkCellRendererText* renderer,
331 const gchar* path,
332 const gchar* new_text,
333 HklGuiEngine* self)
335 HklGuiEnginePrivate *priv = HKL_GUI_ENGINE_GET_PRIVATE(self);
336 GtkTreeIter iter = {0};
337 GtkListStore* model = NULL;
339 if (gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL(priv->store_pseudo),
340 &iter, path)) {
341 gdouble value = 0.0;
343 value = atof(new_text);
344 g_object_set (G_OBJECT(renderer), "background", "red", NULL, NULL);
345 gtk_list_store_set (priv->store_pseudo,
346 &iter,
347 PSEUDO_COL_VALUE, value,
348 -1);
352 static void hkl_gui_engine_class_init (HklGuiEngineClass * class)
354 GObjectClass *gobject_class = G_OBJECT_CLASS (class);
356 g_type_class_add_private (class, sizeof (HklGuiEnginePrivate));
358 /* virtual methods */
359 gobject_class->finalize = finalize;
360 gobject_class->set_property = set_property;
361 gobject_class->get_property = get_property;
363 /* properties */
364 obj_properties[PROP_ENGINE] =
365 g_param_spec_pointer ("engine",
366 "Engine",
367 "The Hkl Engine used underneath",
368 G_PARAM_CONSTRUCT_ONLY |
369 G_PARAM_READWRITE |
370 G_PARAM_STATIC_STRINGS);
372 obj_properties[PROP_LISTSTORE] =
373 g_param_spec_object ("liststore",
374 "Liststore",
375 "The liststore contaning all the pseudo axes values",
376 GTK_TYPE_LIST_STORE,
377 G_PARAM_READABLE |
378 G_PARAM_STATIC_STRINGS);
380 g_object_class_install_properties (gobject_class,
381 N_PROPERTIES,
382 obj_properties);
384 /* signals */
385 signals[CHANGED] =
386 g_signal_new ("changed",
387 HKL_GUI_TYPE_ENGINE,
388 G_SIGNAL_RUN_LAST,
389 0, /* class offset */
390 NULL, /* accumulator */
391 NULL, /* accu_data */
392 g_cclosure_marshal_VOID__VOID,
393 G_TYPE_NONE, /* return_type */
398 static void _connect_renderer(gpointer data, gpointer user_data)
400 GtkCellRenderer *renderer = GTK_CELL_RENDERER(data);
401 HklGuiEngine *self = HKL_GUI_ENGINE(user_data);
403 g_signal_connect_object (renderer,
404 "edited",
405 (GCallback) cell_tree_view_pseudo_axis_value_edited_cb,
406 self, 0);
409 static void hkl_gui_engine_init (HklGuiEngine * self)
411 HklGuiEnginePrivate *priv = HKL_GUI_ENGINE_GET_PRIVATE(self);
412 GtkBuilder *builder;
413 GtkTreeViewColumn* col;
414 GList* cells;
416 priv->engine = NULL;
417 priv->builder = builder = gtk_builder_new ();
419 get_ui(builder, "pseudo.ui");
421 get_object(builder, GTK_FRAME, priv, frame1);
422 get_object(builder, GTK_LABEL, priv, label2);
423 get_object(builder, GTK_COMBO_BOX, priv, combobox1);
424 get_object(builder, GTK_EXPANDER, priv, expander1);
425 get_object(builder, GTK_TREE_VIEW, priv, treeview1);
426 get_object(builder, GTK_BUTTON, priv, button1);
427 get_object(builder, GTK_BUTTON, priv, button2);
429 get_object(builder, GTK_LIST_STORE, priv, store_mode);
430 get_object(builder, GTK_LIST_STORE, priv, store_pseudo);
431 get_object(builder, GTK_LIST_STORE, priv, store_mode_parameter);
433 gtk_builder_connect_signals (builder, self);
435 g_signal_connect_object (priv->combobox1,
436 "changed",
437 (GCallback) combobox1_changed_cb,
438 self, 0);
440 g_signal_connect_object (priv->button1,
441 "clicked",
442 (GCallback) button1_clicked_cb,
443 self, 0);
445 g_signal_connect_object (priv->button2,
446 "clicked",
447 (GCallback) button2_clicked_cb,
448 self, 0);
450 col = gtk_tree_view_get_column (priv->treeview1, 1);
451 cells = gtk_cell_layout_get_cells(GTK_CELL_LAYOUT(col));
452 g_list_foreach(cells, _connect_renderer, self);
453 g_list_free(cells);