pre-release
[hkl.git] / gui / hkl-gui.c
blobf2c59b913369ff4853c0de8ce8134139f9073256
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-2017 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 <stdlib.h>
24 #include <string.h>
25 #include <float.h>
26 #include <math.h>
27 #include <stdio.h>
29 #include <glib.h>
30 #include <glib-object.h>
31 #include <gtk/gtk.h>
32 #include <gdk/gdk.h>
34 #include "hkl.h"
35 #include "hkl-gui.h"
36 #include "hkl-gui-macros.h"
37 #if HKL3D
38 # include <gtk/gtkgl.h>
39 # include "hkl-gui-3d.h"
40 #endif
41 #include "hkl-gui-pseudoaxes.h"
43 #define HKL_GUI_TYPE_WINDOW (hkl_gui_window_get_type ())
44 #define HKL_GUI_WINDOW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), HKL_GUI_TYPE_WINDOW, HklGuiWindow))
45 #define HKL_GUI_WINDOW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), HKL_GUI_TYPE_WINDOW, HklGuiWindowClass))
46 #define HKL_GUI_IS_WINDOW(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), HKL_GUI_TYPE_WINDOW))
47 #define HKL_GUI_IS_WINDOW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), HKL_GUI_TYPE_WINDOW))
48 #define HKL_GUI_WINDOW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), HKL_GUI_TYPE_WINDOW, HklGuiWindowClass))
50 #define EMBED_BREAKPOINT asm volatile ("int3;")
52 G_DEFINE_TYPE (HklGuiWindow, hkl_gui_window, G_TYPE_OBJECT);
54 typedef enum {
55 REFLECTION_COL_INDEX = 0,
56 REFLECTION_COL_H,
57 REFLECTION_COL_K,
58 REFLECTION_COL_L,
59 REFLECTION_COL_FLAG,
60 REFLECTION_COL_REFLECTION,
61 REFLECTION_COL_N_COLUMNS
62 } ReflectionCol;
64 typedef enum {
65 AXIS_COL_AXIS = 0,
66 AXIS_COL_NAME,
67 AXIS_COL_READ,
68 AXIS_COL_WRITE,
69 AXIS_COL_MIN,
70 AXIS_COL_MAX,
71 AXIS_COL_N_COLUMNS
72 } AxisCol;
74 typedef enum {
75 PSEUDO_AXIS_COL_IDX = 0,
76 PSEUDO_AXIS_COL_ENGINE,
77 PSEUDO_AXIS_COL_NAME,
78 PSEUDO_AXIS_COL_READ,
79 PSEUDO_AXIS_COL_WRITE,
80 PSEUDO_AXIS_COL_N_COLUMNS
81 } PseudoAxisCol;
83 typedef enum {
84 PARAMETER_COL_PARAMETER = 0,
85 PARAMETER_COL_NAME,
86 PARAMETER_COL_VALUE,
87 PARAMETER_COL_N_COLUMNS
88 } ParameterCol;
90 typedef enum {
91 SAMPLE_COL_SAMPLE = 0,
92 SAMPLE_COL_NAME,
93 SAMPLE_COL_A,
94 SAMPLE_COL_B,
95 SAMPLE_COL_C,
96 SAMPLE_COL_ALPHA,
97 SAMPLE_COL_BETA,
98 SAMPLE_COL_GAMMA,
99 SAMPLE_COL_N_COLUMNS
100 } SampleCol;
102 typedef enum {
103 SOLUTION_COL_INDEX = 0,
104 SOLUTION_COL_HKL_GEOMETRY_LIST_ITEM,
105 SOLUTION_COL_N_COLUMNS
106 } SolutionCol;
108 typedef enum {
109 DIFFRACTOMETER_COL_NAME = 0,
110 DIFFRACTOMETER_COL_FACTORY,
111 DIFFRACTOMETER_COL_DIFFRACTOMETER,
112 DIFFRACTOMETER_COL_N_COLUMNS
113 } DiffractometerCol;
115 /******************/
116 /* Diffractometer */
117 /******************/
119 struct diffractometer_t {
120 HklFactory *factory;
121 HklGeometry *geometry;
122 HklDetector *detector;
123 HklEngineList *engines;
124 HklGeometryList *solutions;
128 static struct diffractometer_t *
129 create_diffractometer(HklFactory *factory)
131 struct diffractometer_t *self;
133 self = malloc(sizeof(*self));
135 self->factory = factory;
136 self->geometry = hkl_factory_create_new_geometry (factory);
137 self->engines = hkl_factory_create_new_engine_list (factory);
138 self->detector = hkl_detector_factory_new (HKL_DETECTOR_TYPE_0D);
139 self->solutions = NULL;
141 return self;
144 static void
145 delete_diffractometer(struct diffractometer_t *self)
147 hkl_geometry_free(self->geometry);
148 hkl_engine_list_free(self->engines);
149 hkl_detector_free(self->detector);
150 if(self->solutions)
151 hkl_geometry_list_free(self->solutions);
154 static void
155 diffractometer_set_sample(struct diffractometer_t *self,
156 HklSample *sample)
158 hkl_engine_list_init(self->engines,
159 self->geometry,
160 self->detector,
161 sample);
162 hkl_engine_list_get(self->engines);
165 static void
166 diffractometer_set_wavelength(struct diffractometer_t *self,
167 double wavelength)
169 if(hkl_geometry_wavelength_set(self->geometry,
170 wavelength, HKL_UNIT_USER, NULL))
171 hkl_engine_list_get(self->engines);
174 static gboolean
175 diffractometer_set_solutions(struct diffractometer_t *self, HklGeometryList *solutions)
177 if(solutions){
178 if(self->solutions)
179 hkl_geometry_list_free(self->solutions);
180 self->solutions = solutions;
183 return NULL != solutions;
186 static gboolean
187 diffractometer_pseudo_axis_values_set(struct diffractometer_t *self,
188 HklEngine *engine, gdouble values[], guint n_values,
189 GError **error)
191 HklGeometryList *solutions;
194 solutions = hkl_engine_pseudo_axis_values_set(engine, values, n_values, HKL_UNIT_USER, error);
196 return diffractometer_set_solutions(self, solutions);
199 static void
200 diffractometer_set_solution(struct diffractometer_t *self,
201 const HklGeometryListItem *item)
203 hkl_engine_list_select_solution(self->engines, item);
207 /****************/
208 /* HklGuiWindow */
209 /****************/
211 struct _HklGuiWindowPrivate {
212 GtkBuilder* builder;
213 GtkLabel* label_UB11;
214 GtkLabel* label_UB12;
215 GtkLabel* label_UB13;
216 GtkLabel* label_UB21;
217 GtkLabel* label_UB22;
218 GtkLabel* label_UB23;
219 GtkLabel* label_UB31;
220 GtkLabel* label_UB32;
221 GtkLabel* label_UB33;
222 GtkButton* button2;
223 GtkSpinButton* spinbutton_a;
224 GtkSpinButton* spinbutton_b;
225 GtkSpinButton* spinbutton_c;
226 GtkSpinButton* spinbutton_alpha;
227 GtkSpinButton* spinbutton_beta;
228 GtkSpinButton* spinbutton_gamma;
229 GtkSpinButton* spinbutton_a_min;
230 GtkSpinButton* spinbutton_b_min;
231 GtkSpinButton* spinbutton_c_min;
232 GtkSpinButton* spinbutton_alpha_min;
233 GtkSpinButton* spinbutton_beta_min;
234 GtkSpinButton* spinbutton_gamma_min;
235 GtkSpinButton* spinbutton_a_max;
236 GtkSpinButton* spinbutton_b_max;
237 GtkSpinButton* spinbutton_c_max;
238 GtkSpinButton* spinbutton_alpha_max;
239 GtkSpinButton* spinbutton_beta_max;
240 GtkSpinButton* spinbutton_gamma_max;
241 GtkSpinButton* spinbutton_lambda;
242 GtkSpinButton* spinbutton_a_star;
243 GtkSpinButton* spinbutton_b_star;
244 GtkSpinButton* spinbutton_c_star;
245 GtkSpinButton* spinbutton_alpha_star;
246 GtkSpinButton* spinbutton_beta_star;
247 GtkSpinButton* spinbutton_gamma_star;
248 GtkSpinButton* spinbutton_ux;
249 GtkSpinButton* spinbutton_uy;
250 GtkSpinButton* spinbutton_uz;
251 GtkSpinButton* spinbutton_U11;
252 GtkSpinButton* spinbutton_U12;
253 GtkSpinButton* spinbutton_U13;
254 GtkSpinButton* spinbutton_U21;
255 GtkSpinButton* spinbutton_U22;
256 GtkSpinButton* spinbutton_U23;
257 GtkSpinButton* spinbutton_U31;
258 GtkSpinButton* spinbutton_U32;
259 GtkSpinButton* spinbutton_U33;
260 GtkCheckButton* checkbutton_a;
261 GtkCheckButton* checkbutton_b;
262 GtkCheckButton* checkbutton_c;
263 GtkCheckButton* checkbutton_alpha;
264 GtkCheckButton* checkbutton_beta;
265 GtkCheckButton* checkbutton_gamma;
266 GtkCheckButton* checkbutton_ux;
267 GtkCheckButton* checkbutton_uy;
268 GtkCheckButton* checkbutton_uz;
269 GtkTreeView* treeview_reflections;
270 GtkTreeView* treeview_crystals;
271 GtkTreeView* treeview_axes;
272 GtkTreeView* treeview_pseudo_axes;
273 GtkTreeView* treeview_solutions;
274 GtkToolButton* toolbutton_add_reflection;
275 GtkToolButton* toolbutton_goto_reflection;
276 GtkToolButton* toolbutton_del_reflection;
277 GtkToolButton* toolbutton_setUB;
278 GtkToolButton* toolbutton_computeUB;
279 GtkToolButton* toolbutton_add_crystal;
280 GtkToolButton* toolbutton_copy_crystal;
281 GtkToolButton* toolbutton_del_crystal;
282 GtkToolButton* toolbutton_affiner;
283 GtkStatusbar* statusbar;
284 GtkImageMenuItem* menuitem5;
285 GtkVBox* box_info_bar; /* fake for the infor bar */
286 GtkVBox* vbox7;
287 GtkVBox* vbox2;
288 GtkDialog* dialog1;
289 GtkButton* button1;
290 GtkComboBox* combobox1;
291 GtkListStore* liststore_diffractometer;
292 GtkListStore* liststore_axis;
293 GtkListStore* liststore_pseudo_axes;
294 GtkListStore* liststore_solutions;
295 GtkListStore* liststore_reflections;
296 GtkListStore* liststore_crystals;
298 GtkInfoBar *info_bar;
299 GtkLabel *info_message;
301 darray(HklGuiEngine *) pseudo_frames;
303 #if HKL3D
304 HklGui3D *frame3d;
305 #endif
306 struct diffractometer_t *diffractometer; /* unowned */
307 HklSample *sample; /* unowned */
308 HklLattice *reciprocal;
311 #define HKL_GUI_WINDOW_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), HKL_GUI_TYPE_WINDOW, HklGuiWindowPrivate))
313 static gboolean
314 finalize_liststore_diffractometer(GtkTreeModel *model,
315 GtkTreePath *path,
316 GtkTreeIter *iter,
317 gpointer data)
319 struct diffractometer_t *diffractometer;
321 gtk_tree_model_get(model, iter,
322 DIFFRACTOMETER_COL_DIFFRACTOMETER, &diffractometer,
323 -1);
324 delete_diffractometer(diffractometer);
325 return FALSE;
328 static gboolean
329 finalize_liststore_samples(GtkTreeModel *model,
330 GtkTreePath *path,
331 GtkTreeIter *iter,
332 gpointer data)
334 HklSample *sample = NULL;
336 gtk_tree_model_get(model, iter,
337 SAMPLE_COL_SAMPLE, &sample,
338 -1);
339 hkl_sample_free(sample);
340 return FALSE;
343 static void
344 finalize (GObject* object)
346 HklGuiWindowPrivate *priv = HKL_GUI_WINDOW_GET_PRIVATE(object);
348 g_object_unref(priv->builder);
350 darray_free(priv->pseudo_frames);
352 gtk_tree_model_foreach(GTK_TREE_MODEL(priv->liststore_diffractometer),
353 finalize_liststore_diffractometer,
354 NULL);
356 gtk_tree_model_foreach(GTK_TREE_MODEL(priv->liststore_crystals),
357 finalize_liststore_samples,
358 NULL);
360 G_OBJECT_CLASS (hkl_gui_window_parent_class)->finalize (object);
363 HklGuiWindow* hkl_gui_window_new (void)
365 return g_object_new (HKL_GUI_TYPE_WINDOW, NULL);
368 static void
369 hkl_gui_window_get_widgets_and_objects_from_ui (HklGuiWindow* self)
371 HklGuiWindowPrivate *priv = HKL_GUI_WINDOW_GET_PRIVATE(self);
372 GtkBuilder* builder;
374 g_return_if_fail (self != NULL);
376 priv->builder = builder = gtk_builder_new ();
377 get_ui(builder, "ghkl.ui");
379 get_object(builder, GTK_LIST_STORE, priv, liststore_diffractometer);
380 get_object(builder, GTK_LIST_STORE, priv, liststore_axis);
381 get_object(builder, GTK_LIST_STORE, priv, liststore_pseudo_axes);
382 get_object(builder, GTK_LIST_STORE, priv, liststore_reflections);
383 get_object(builder, GTK_LIST_STORE, priv, liststore_crystals);
385 get_object(builder, GTK_LABEL, priv, label_UB11);
386 get_object(builder, GTK_LABEL, priv, label_UB12);
387 get_object(builder, GTK_LABEL, priv, label_UB13);
388 get_object(builder, GTK_LABEL, priv, label_UB21);
389 get_object(builder, GTK_LABEL, priv, label_UB22);
390 get_object(builder, GTK_LABEL, priv, label_UB23);
391 get_object(builder, GTK_LABEL, priv, label_UB31);
392 get_object(builder, GTK_LABEL, priv, label_UB32);
393 get_object(builder, GTK_LABEL, priv, label_UB33);
395 get_object(builder, GTK_BUTTON, priv, button2);
397 get_object(builder, GTK_SPIN_BUTTON, priv, spinbutton_a);
398 get_object(builder, GTK_SPIN_BUTTON, priv, spinbutton_a_min);
399 get_object(builder, GTK_SPIN_BUTTON, priv, spinbutton_a_max);
400 get_object(builder, GTK_SPIN_BUTTON, priv, spinbutton_a_star);
402 get_object(builder, GTK_SPIN_BUTTON, priv, spinbutton_b);
403 get_object(builder, GTK_SPIN_BUTTON, priv, spinbutton_b_min);
404 get_object(builder, GTK_SPIN_BUTTON, priv, spinbutton_b_max);
405 get_object(builder, GTK_SPIN_BUTTON, priv, spinbutton_b_star);
407 get_object(builder, GTK_SPIN_BUTTON, priv, spinbutton_c);
408 get_object(builder, GTK_SPIN_BUTTON, priv, spinbutton_c_min);
409 get_object(builder, GTK_SPIN_BUTTON, priv, spinbutton_c_max);
410 get_object(builder, GTK_SPIN_BUTTON, priv, spinbutton_c_star);
412 get_object(builder, GTK_SPIN_BUTTON, priv, spinbutton_alpha);
413 get_object(builder, GTK_SPIN_BUTTON, priv, spinbutton_alpha_min);
414 get_object(builder, GTK_SPIN_BUTTON, priv, spinbutton_alpha_max);
415 get_object(builder, GTK_SPIN_BUTTON, priv, spinbutton_alpha_star);
417 get_object(builder, GTK_SPIN_BUTTON, priv, spinbutton_beta);
418 get_object(builder, GTK_SPIN_BUTTON, priv, spinbutton_beta_min);
419 get_object(builder, GTK_SPIN_BUTTON, priv, spinbutton_beta_max);
420 get_object(builder, GTK_SPIN_BUTTON, priv, spinbutton_beta_star);
422 get_object(builder, GTK_SPIN_BUTTON, priv, spinbutton_gamma);
423 get_object(builder, GTK_SPIN_BUTTON, priv, spinbutton_gamma_min);
424 get_object(builder, GTK_SPIN_BUTTON, priv, spinbutton_gamma_max);
425 get_object(builder, GTK_SPIN_BUTTON, priv, spinbutton_gamma_star);
427 get_object(builder, GTK_SPIN_BUTTON, priv, spinbutton_lambda);
429 get_object(builder, GTK_SPIN_BUTTON, priv, spinbutton_ux);
430 get_object(builder, GTK_SPIN_BUTTON, priv, spinbutton_uy);
431 get_object(builder, GTK_SPIN_BUTTON, priv, spinbutton_uz);
433 get_object(builder, GTK_SPIN_BUTTON, priv, spinbutton_U11);
434 get_object(builder, GTK_SPIN_BUTTON, priv, spinbutton_U12);
435 get_object(builder, GTK_SPIN_BUTTON, priv, spinbutton_U13);
436 get_object(builder, GTK_SPIN_BUTTON, priv, spinbutton_U21);
437 get_object(builder, GTK_SPIN_BUTTON, priv, spinbutton_U22);
438 get_object(builder, GTK_SPIN_BUTTON, priv, spinbutton_U23);
439 get_object(builder, GTK_SPIN_BUTTON, priv, spinbutton_U31);
440 get_object(builder, GTK_SPIN_BUTTON, priv, spinbutton_U32);
441 get_object(builder, GTK_SPIN_BUTTON, priv, spinbutton_U33);
444 get_object(builder, GTK_CHECK_BUTTON, priv, checkbutton_a);
445 get_object(builder, GTK_CHECK_BUTTON, priv, checkbutton_b);
446 get_object(builder, GTK_CHECK_BUTTON, priv, checkbutton_c);
447 get_object(builder, GTK_CHECK_BUTTON, priv, checkbutton_alpha);
448 get_object(builder, GTK_CHECK_BUTTON, priv, checkbutton_beta);
449 get_object(builder, GTK_CHECK_BUTTON, priv, checkbutton_gamma);
450 get_object(builder, GTK_CHECK_BUTTON, priv, checkbutton_ux);
451 get_object(builder, GTK_CHECK_BUTTON, priv, checkbutton_uy);
452 get_object(builder, GTK_CHECK_BUTTON, priv, checkbutton_uz);
455 get_object(builder, GTK_TREE_VIEW, priv, treeview_reflections);
456 get_object(builder, GTK_TREE_VIEW, priv, treeview_crystals);
457 get_object(builder, GTK_TREE_VIEW, priv, treeview_axes);
458 get_object(builder, GTK_TREE_VIEW, priv, treeview_pseudo_axes);
459 get_object(builder, GTK_TREE_VIEW, priv, treeview_solutions);
461 get_object(builder, GTK_TOOL_BUTTON, priv, toolbutton_add_reflection);
462 get_object(builder, GTK_TOOL_BUTTON, priv, toolbutton_goto_reflection);
463 get_object(builder, GTK_TOOL_BUTTON, priv, toolbutton_del_reflection);
464 get_object(builder, GTK_TOOL_BUTTON, priv, toolbutton_setUB);
465 get_object(builder, GTK_TOOL_BUTTON, priv, toolbutton_computeUB);
466 get_object(builder, GTK_TOOL_BUTTON, priv, toolbutton_add_crystal);
467 get_object(builder, GTK_TOOL_BUTTON, priv, toolbutton_copy_crystal);
468 get_object(builder, GTK_TOOL_BUTTON, priv, toolbutton_del_crystal);
469 get_object(builder, GTK_TOOL_BUTTON, priv, toolbutton_affiner);
471 get_object(builder, GTK_STATUSBAR, priv, statusbar);
473 get_object(builder, GTK_IMAGE_MENU_ITEM, priv, menuitem5);
475 get_object(builder, GTK_VBOX, priv, vbox7);
476 get_object(builder, GTK_VBOX, priv, vbox2);
477 get_object(builder, GTK_VBOX, priv, box_info_bar);
479 get_object(builder, GTK_DIALOG, priv, dialog1);
481 get_object(builder, GTK_COMBO_BOX, priv, combobox1);
483 gtk_builder_connect_signals (builder, self);
486 static void
487 update_pseudo_axes_frames (HklGuiWindow* self)
489 HklGuiWindowPrivate *priv = HKL_GUI_WINDOW_GET_PRIVATE(self);
490 HklGuiEngine **engine;
492 g_return_if_fail (self != NULL);
494 darray_foreach(engine, priv->pseudo_frames){
495 hkl_gui_engine_update(*engine);
499 static void
500 raise_error(HklGuiWindow *self, GError **error)
502 HklGuiWindowPrivate *priv = HKL_GUI_WINDOW_GET_PRIVATE(self);
504 g_return_if_fail (error != NULL);
506 /* show an error message */
507 gtk_label_set_text (GTK_LABEL (priv->info_message),
508 (*error)->message);
509 gtk_info_bar_set_message_type (priv->info_bar,
510 GTK_MESSAGE_ERROR);
511 gtk_widget_show (GTK_WIDGET(priv->info_bar));
513 g_clear_error(error);
516 static gboolean
517 _update_axis (GtkTreeModel *model, GtkTreePath *path,
518 GtkTreeIter *iter, gpointer data)
520 HklGuiWindowPrivate *priv = HKL_GUI_WINDOW_GET_PRIVATE(data);
521 const char *name;
522 const HklParameter *axis;
523 gdouble value, min, max;
525 gtk_tree_model_get (model, iter,
526 AXIS_COL_NAME, &name,
527 -1);
529 axis = hkl_geometry_axis_get(priv->diffractometer->geometry, name, NULL);
530 hkl_parameter_min_max_get(axis, &min, &max, HKL_UNIT_USER);
531 value = hkl_parameter_value_get(axis, HKL_UNIT_USER);
533 gtk_list_store_set(GTK_LIST_STORE(model), iter,
534 AXIS_COL_READ, value,
535 AXIS_COL_WRITE, value,
536 AXIS_COL_MIN, min,
537 AXIS_COL_MAX, max,
538 -1);
539 return FALSE;
542 static void
543 update_axes (HklGuiWindow* self)
545 HklGuiWindowPrivate *priv = HKL_GUI_WINDOW_GET_PRIVATE(self);
547 g_return_if_fail (self != NULL);
549 gtk_tree_model_foreach(GTK_TREE_MODEL(priv->liststore_axis),
550 _update_axis,
551 self);
554 static gboolean
555 _update_pseudo_axes (GtkTreeModel *model, GtkTreePath *path,
556 GtkTreeIter *iter, gpointer data)
558 const char *name;
559 const HklEngine *engine;
560 const HklParameter *pseudo_axis;
561 gdouble value, min, max;
563 gtk_tree_model_get (model, iter,
564 PSEUDO_AXIS_COL_ENGINE, &engine,
565 PSEUDO_AXIS_COL_NAME, &name,
566 -1);
568 pseudo_axis = hkl_engine_pseudo_axis_get(engine, name, NULL);
569 hkl_parameter_min_max_get(pseudo_axis, &min, &max, HKL_UNIT_USER);
570 value = hkl_parameter_value_get(pseudo_axis, HKL_UNIT_USER);
572 gtk_list_store_set(GTK_LIST_STORE(model), iter,
573 PSEUDO_AXIS_COL_READ, value,
574 PSEUDO_AXIS_COL_WRITE, value,
575 -1);
576 return FALSE;
579 static void
580 update_pseudo_axes (HklGuiWindow* self)
582 HklGuiWindowPrivate *priv = HKL_GUI_WINDOW_GET_PRIVATE(self);
584 g_return_if_fail (self != NULL);
586 gtk_tree_model_foreach(GTK_TREE_MODEL(priv->liststore_pseudo_axes),
587 _update_pseudo_axes,
588 self);
591 static void
592 update_solutions (HklGuiWindow* self)
594 HklGuiWindowPrivate *priv = HKL_GUI_WINDOW_GET_PRIVATE(self);
595 GtkTreeIter iter = {0};
597 g_return_if_fail (self != NULL);
598 g_return_if_fail (priv->diffractometer->solutions != NULL);
600 const HklGeometryListItem *item;
601 gtk_list_store_clear(priv->liststore_solutions);
603 gint n_values = gtk_tree_model_get_n_columns (GTK_TREE_MODEL(priv->liststore_solutions));
604 GValue *values = g_new0(GValue, n_values);
605 gint *columns = g_new0(gint, n_values);
606 gint i;
608 /* prepare the GValue before using them */
609 g_value_init(&values[SOLUTION_COL_INDEX], G_TYPE_INT);
610 g_value_init(&values[SOLUTION_COL_HKL_GEOMETRY_LIST_ITEM], G_TYPE_POINTER);
611 for(i=SOLUTION_COL_N_COLUMNS; i<n_values; ++i)
612 g_value_init(&values[i], G_TYPE_DOUBLE);
614 i=0;
615 HKL_GEOMETRY_LIST_FOREACH(item, priv->diffractometer->solutions){
616 const HklGeometry *geometry = hkl_geometry_list_item_geometry_get(item);
617 unsigned int n_v = darray_size(*hkl_geometry_axis_names_get(geometry));
618 double v[n_v];
620 hkl_geometry_axis_values_get(geometry, v, n_v, HKL_UNIT_USER);
622 g_value_set_int(&values[SOLUTION_COL_INDEX], i);
623 g_value_set_pointer(&values[SOLUTION_COL_HKL_GEOMETRY_LIST_ITEM], (gpointer)item);
624 columns[SOLUTION_COL_INDEX] = SOLUTION_COL_INDEX;
625 columns[SOLUTION_COL_HKL_GEOMETRY_LIST_ITEM] = SOLUTION_COL_HKL_GEOMETRY_LIST_ITEM;
627 for(unsigned int j=0; j<n_v; ++j){
628 g_value_set_double(&values[SOLUTION_COL_N_COLUMNS + j], v[j]);
629 columns[SOLUTION_COL_N_COLUMNS + j] = SOLUTION_COL_N_COLUMNS + j;
631 gtk_list_store_insert_with_valuesv(priv->liststore_solutions,
632 &iter, i,
633 columns, values, n_values);
634 i++;
636 g_free(columns);
637 g_free(values);
640 static void
641 update_source (HklGuiWindow* self)
643 HklGuiWindowPrivate *priv = HKL_GUI_WINDOW_GET_PRIVATE(self);
645 g_return_if_fail (self != NULL);
647 gtk_spin_button_set_value (priv->spinbutton_lambda,
648 hkl_geometry_wavelength_get(priv->diffractometer->geometry,
649 HKL_UNIT_USER));
652 static void
653 update_reflections (HklGuiWindow *self)
655 HklGuiWindowPrivate *priv = HKL_GUI_WINDOW_GET_PRIVATE(self);
657 gtk_list_store_clear (priv->liststore_reflections);
659 if(priv->sample){
660 HklSampleReflection* reflection;
661 guint index = 0;
663 HKL_SAMPLE_REFLECTIONS_FOREACH(reflection, priv->sample){
664 GtkTreeIter iter = {0};
665 gdouble h, k, l;
666 gboolean flag;
668 hkl_sample_reflection_hkl_get(reflection, &h, &k, &l);
669 flag = hkl_sample_reflection_flag_get(reflection);
671 gtk_list_store_append (priv->liststore_reflections, &iter);
673 gtk_list_store_set (priv->liststore_reflections,
674 &iter,
675 REFLECTION_COL_INDEX, index++,
676 REFLECTION_COL_H, h,
677 REFLECTION_COL_K, k,
678 REFLECTION_COL_L, l,
679 REFLECTION_COL_FLAG, flag,
680 REFLECTION_COL_REFLECTION, reflection,
681 -1);
686 static void
687 update_3d(HklGuiWindow *self)
689 #ifdef HKL3D
690 HklGuiWindowPrivate *priv = HKL_GUI_WINDOW_GET_PRIVATE(self);
692 if(priv->frame3d){
693 hkl_gui_3d_is_colliding(priv->frame3d);
694 hkl_gui_3d_invalidate(priv->frame3d);
696 #endif
699 static void
700 pseudo_axes_frame_changed_cb (HklGuiEngine *gui_engine, HklGuiWindow *self)
702 HklGuiWindowPrivate *priv = HKL_GUI_WINDOW_GET_PRIVATE(self);
703 HklEngine *engine;
704 GtkListStore *liststore;
705 guint n_values;
706 GtkTreeIter iter = {0};
707 gboolean valid;
708 GError *error = NULL;
710 g_object_get(gui_engine,
711 "engine", &engine,
712 "liststore", &liststore,
713 NULL);
715 n_values = darray_size(*hkl_engine_pseudo_axis_names_get(engine));
716 gdouble values[n_values];
718 /* extract all the values from the listore */
719 valid = gtk_tree_model_get_iter_first(GTK_TREE_MODEL(liststore), &iter);
720 while(valid){
721 guint it_idx;
722 gdouble it_value;
724 gtk_tree_model_get (GTK_TREE_MODEL(liststore), &iter,
725 PSEUDO_COL_IDX, &it_idx,
726 PSEUDO_COL_VALUE, &it_value,
727 -1);
729 values[it_idx] = it_value;
731 valid = gtk_tree_model_iter_next(GTK_TREE_MODEL(liststore), &iter);
734 if(diffractometer_pseudo_axis_values_set(priv->diffractometer, engine,
735 values, n_values, &error)){
736 update_axes (self);
737 update_pseudo_axes (self);
738 update_pseudo_axes_frames (self);
739 update_solutions (self);
740 update_3d(self);
741 }else
742 raise_error(self, &error);
744 g_object_unref(liststore);
748 static void
749 set_up_pseudo_axes_frames (HklGuiWindow* self)
751 HklGuiWindowPrivate *priv = HKL_GUI_WINDOW_GET_PRIVATE(self);
752 HklGuiEngine **pseudo;
753 HklEngine **engine;
754 darray_engine *engines;
756 g_return_if_fail (self != NULL);
758 darray_foreach (pseudo, priv->pseudo_frames){
759 gtk_container_remove(GTK_CONTAINER(priv->vbox2),
760 GTK_WIDGET (hkl_gui_engine_get_frame (*pseudo)));
761 g_object_unref(*pseudo);
763 darray_size (priv->pseudo_frames) = 0;
765 engines = hkl_engine_list_engines_get (priv->diffractometer->engines);
766 darray_foreach (engine, *engines){
767 HklGuiEngine *pseudo;
769 pseudo = hkl_gui_engine_new (*engine);
770 darray_append(priv->pseudo_frames, pseudo);
771 gtk_container_add (GTK_CONTAINER (priv->vbox2),
772 GTK_WIDGET (hkl_gui_engine_get_frame(pseudo)));
774 g_signal_connect_object (pseudo,
775 "changed",
776 G_CALLBACK(pseudo_axes_frame_changed_cb),
777 self, 0);
780 gtk_widget_show_all (GTK_WIDGET (priv->vbox2));
784 static void
785 set_up_diffractometer_model (HklGuiWindow* self)
787 HklGuiWindowPrivate *priv = HKL_GUI_WINDOW_GET_PRIVATE(self);
788 unsigned int i, n;
789 HklFactory **factories;
791 g_return_if_fail (self != NULL);
793 factories = hkl_factory_get_all(&n);
794 for(i=0; i<n; ++i){
795 GtkTreeIter iter = {0};
797 gtk_list_store_append (priv->liststore_diffractometer, &iter);
798 gtk_list_store_set (priv->liststore_diffractometer, &iter,
799 DIFFRACTOMETER_COL_NAME, hkl_factory_name_get(factories[i]),
800 DIFFRACTOMETER_COL_FACTORY, factories[i],
801 DIFFRACTOMETER_COL_DIFFRACTOMETER, NULL,
802 -1);
806 static void
807 set_up_tree_view_axes (HklGuiWindow* self)
809 HklGuiWindowPrivate *priv = HKL_GUI_WINDOW_GET_PRIVATE(self);
810 const darray_string *axes;
811 const char **axis;
812 GtkTreeIter iter = {0};
814 gtk_list_store_clear (priv->liststore_axis);
816 axes = hkl_geometry_axis_names_get(priv->diffractometer->geometry);
817 darray_foreach (axis, *axes){
818 gtk_list_store_append (priv->liststore_axis, &iter);
819 gtk_list_store_set (priv->liststore_axis, &iter,
820 AXIS_COL_NAME, *axis,
821 -1);
824 update_axes (self);
827 static void
828 set_up_tree_view_pseudo_axes (HklGuiWindow* self)
830 HklGuiWindowPrivate *priv = HKL_GUI_WINDOW_GET_PRIVATE(self);
831 HklEngine **engine;
832 const darray_engine *engines;
834 gtk_list_store_clear(priv->liststore_pseudo_axes);
836 engines = hkl_engine_list_engines_get(priv->diffractometer->engines);
837 darray_foreach(engine, *engines){
838 const darray_string *pseudo_axes = hkl_engine_pseudo_axis_names_get(*engine);
839 GtkTreeIter iter = {0};
840 guint idx;
842 for(idx=0; idx<darray_size(*pseudo_axes); ++idx){
843 gtk_list_store_append (priv->liststore_pseudo_axes, &iter);
844 gtk_list_store_set (priv->liststore_pseudo_axes, &iter,
845 PSEUDO_AXIS_COL_IDX, idx,
846 PSEUDO_AXIS_COL_ENGINE, *engine,
847 PSEUDO_AXIS_COL_NAME, darray_item(*pseudo_axes, idx),
848 -1);
852 update_pseudo_axes (self);
855 static void
856 _delete_column(gpointer data,
857 gpointer user_data)
859 gtk_tree_view_remove_column (GTK_TREE_VIEW(user_data),
860 GTK_TREE_VIEW_COLUMN(data));
863 static void
864 set_up_tree_view_solutions (HklGuiWindow* self)
866 HklGuiWindowPrivate *priv = HKL_GUI_WINDOW_GET_PRIVATE(self);
867 const darray_string *axes;
868 int i;
869 GtkCellRenderer* renderer = NULL;
870 GtkTreeViewColumn* column = NULL;
871 GList* columns;
872 GType* types;
873 gint n_columns;
875 axes = hkl_geometry_axis_names_get(priv->diffractometer->geometry);
877 n_columns = SOLUTION_COL_N_COLUMNS + darray_size(*axes);
879 /* prepare types for the liststore */
880 types = g_new0 (GType, n_columns);
882 /* first remove all the columns */
883 columns = gtk_tree_view_get_columns (priv->treeview_solutions);
884 g_list_foreach(columns, _delete_column, priv->treeview_solutions);
885 g_list_free(columns);
887 /* now add the index column */
888 renderer = gtk_cell_renderer_text_new ();
889 column = gtk_tree_view_column_new_with_attributes ("index",
890 renderer, "text",
891 SOLUTION_COL_INDEX, NULL);
893 gtk_tree_view_append_column (priv->treeview_solutions, column);
895 types[0] = G_TYPE_INT;
896 types[1] = G_TYPE_POINTER;
898 /* add the axes column */
899 for(i=SOLUTION_COL_N_COLUMNS; i<n_columns; ++i){
900 const char *axis;
902 axis = darray_item(*axes, i - SOLUTION_COL_N_COLUMNS);
903 renderer = gtk_cell_renderer_text_new ();
904 column = gtk_tree_view_column_new_with_attributes (axis,
905 renderer, "text",
906 i, NULL);
908 gtk_tree_view_append_column (priv->treeview_solutions, column);
909 types[i] = G_TYPE_DOUBLE;
912 if (priv->liststore_solutions)
913 g_object_unref(priv->liststore_solutions);
914 priv->liststore_solutions = gtk_list_store_newv (n_columns, types);
915 g_free (types);
917 gtk_tree_view_set_model (priv->treeview_solutions,
918 GTK_TREE_MODEL(priv->liststore_solutions));
920 update_solutions (self);
923 void
924 set_up_info_bar(HklGuiWindow *self)
926 HklGuiWindowPrivate *priv = HKL_GUI_WINDOW_GET_PRIVATE(self);
927 GtkWidget *content_area;
929 g_return_if_fail (self != NULL);
931 /* set up info bar until we can use glade for this purpose or
932 * switch to gtk3 */
933 if (priv->info_bar)
934 return;
936 priv->info_bar = GTK_INFO_BAR(gtk_info_bar_new ());
937 gtk_widget_set_no_show_all (GTK_WIDGET(priv->info_bar), TRUE);
939 priv->info_message = GTK_LABEL(gtk_label_new (""));
940 gtk_widget_show (GTK_WIDGET(priv->info_message));
942 content_area = gtk_info_bar_get_content_area (GTK_INFO_BAR (priv->info_bar));
943 gtk_container_add (GTK_CONTAINER (content_area),
944 GTK_WIDGET(priv->info_message));
945 gtk_info_bar_add_button (priv->info_bar,
946 GTK_STOCK_OK, GTK_RESPONSE_OK);
947 g_signal_connect (priv->info_bar, "response",
948 G_CALLBACK (gtk_widget_hide), NULL);
950 gtk_box_pack_start(GTK_BOX(priv->box_info_bar),
951 GTK_WIDGET(priv->info_bar),
952 TRUE, TRUE, 0);
955 static void
956 set_up_lambda(HklGuiWindow *self)
958 HklGuiWindowPrivate *priv = HKL_GUI_WINDOW_GET_PRIVATE(self);
960 g_object_set(G_OBJECT(priv->spinbutton_lambda),
961 "sensitive", TRUE,
962 NULL);
964 gtk_spin_button_set_value(priv->spinbutton_lambda,
965 hkl_geometry_wavelength_get(priv->diffractometer->geometry,
966 HKL_UNIT_USER));
969 static void
970 set_up_3D (HklGuiWindow* self)
972 #if HKL3D
974 HklGuiWindowPrivate *priv = HKL_GUI_WINDOW_GET_PRIVATE(self);
975 char *filename = NULL;
976 const char *name = hkl_factory_name_get(priv->diffractometer->factory);
978 if(!strcmp("K6C", name))
979 filename = get_model("diffabs.yaml");
980 else if (!strcmp("K4CV", name))
981 filename = get_model("cristal4C.yaml");
983 if(priv->frame3d){
984 gtk_widget_destroy(GTK_WIDGET(hkl_gui_3d_frame_get(priv->frame3d)));
985 g_object_unref(priv->frame3d);
986 priv->frame3d = NULL;
989 if (filename){
990 priv->frame3d = hkl_gui_3d_new(filename, priv->diffractometer->geometry);
992 gtk_box_pack_start (GTK_BOX(priv->vbox7),
993 GTK_WIDGET(hkl_gui_3d_frame_get(priv->frame3d)),
994 TRUE, TRUE, (guint) 0);
996 gtk_widget_show_all (GTK_WIDGET(priv->vbox7));
998 #endif
1001 /* select diffractometer */
1002 void
1003 hkl_gui_window_combobox1_changed_cb(GtkComboBox *combobox, gpointer *user_data)
1005 HklGuiWindow *self = HKL_GUI_WINDOW(user_data);
1006 HklGuiWindowPrivate *priv = HKL_GUI_WINDOW_GET_PRIVATE(user_data);
1007 HklFactory *factory;
1008 struct diffractometer_t *dif = NULL;
1010 GtkTreeIter iter = {0};
1012 if(gtk_combo_box_get_active_iter (combobox, &iter)){
1013 gtk_tree_model_get(GTK_TREE_MODEL(priv->liststore_diffractometer),
1014 &iter,
1015 DIFFRACTOMETER_COL_FACTORY, &factory,
1016 DIFFRACTOMETER_COL_DIFFRACTOMETER, &dif,
1017 -1);
1019 if (!dif){
1020 dif = create_diffractometer(factory);
1021 gtk_list_store_set(priv->liststore_diffractometer,
1022 &iter,
1023 DIFFRACTOMETER_COL_DIFFRACTOMETER, dif,
1024 -1);
1027 if(dif != priv->diffractometer){
1028 priv->diffractometer = dif;
1030 diffractometer_set_sample(dif, priv->sample);
1032 set_up_lambda(self);
1033 set_up_pseudo_axes_frames(self);
1034 set_up_tree_view_axes(self);
1035 set_up_tree_view_pseudo_axes(self);
1036 set_up_tree_view_solutions(self);
1037 set_up_info_bar(self);
1038 set_up_3D(self);
1043 /* axis read cb */
1044 void
1045 hkl_gui_window_cellrendererspin1_edited_cb(GtkCellRendererText *renderer,
1046 gchar *path,
1047 gchar *new_text,
1048 gpointer user_data)
1050 HklGuiWindow *self = HKL_GUI_WINDOW(user_data);
1051 HklGuiWindowPrivate *priv = HKL_GUI_WINDOW_GET_PRIVATE(user_data);
1052 GtkTreeIter iter = {0};
1053 gdouble value = 0.0;
1054 const char *axis;
1055 HklParameter *parameter;
1057 g_return_if_fail (renderer != NULL);
1058 g_return_if_fail (path != NULL);
1059 g_return_if_fail (new_text != NULL);
1060 g_return_if_fail (user_data != NULL);
1062 gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL(priv->liststore_axis),
1063 &iter,
1064 path);
1065 gtk_tree_model_get (GTK_TREE_MODEL(priv->liststore_axis), &iter,
1066 AXIS_COL_NAME, &axis,
1067 -1);
1069 value = atof(new_text); /* TODO need to check for the right conversion */
1071 /* set the axis value */
1072 parameter = hkl_parameter_new_copy(hkl_geometry_axis_get(priv->diffractometer->geometry,
1073 axis, NULL));
1074 if(NULL == parameter)
1075 return;
1077 if(FALSE == hkl_parameter_value_set (parameter, value, HKL_UNIT_USER, NULL))
1078 goto out;
1080 if(FALSE == hkl_geometry_axis_set(priv->diffractometer->geometry,
1081 axis, parameter, NULL))
1082 goto out;
1084 hkl_engine_list_get(priv->diffractometer->engines);
1086 /* ok so set the model with the new value */
1087 gtk_list_store_set (priv->liststore_axis, &iter,
1088 AXIS_COL_READ, value,
1089 AXIS_COL_WRITE, value,
1090 -1);
1092 update_pseudo_axes (self);
1093 update_pseudo_axes_frames (self);
1094 update_3d(self);
1096 out:
1097 hkl_parameter_free(parameter);
1098 return;
1101 /* axis min cb */
1102 void
1103 hkl_gui_window_cellrendererspin3_edited_cb(GtkCellRendererText *renderer,
1104 gchar *path,
1105 gchar *new_text,
1106 gpointer user_data)
1108 HklGuiWindow *self = HKL_GUI_WINDOW(user_data);
1109 HklGuiWindowPrivate *priv = HKL_GUI_WINDOW_GET_PRIVATE(user_data);
1110 GtkTreeIter iter = {0};
1111 gdouble value = 0.0;
1112 const char *axis;
1113 HklParameter* parameter = NULL;
1114 gdouble shit, max;
1116 g_return_if_fail (renderer != NULL);
1117 g_return_if_fail (path != NULL);
1118 g_return_if_fail (new_text != NULL);
1119 g_return_if_fail (user_data != NULL);
1121 gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL(priv->liststore_axis),
1122 &iter,
1123 path);
1124 gtk_tree_model_get (GTK_TREE_MODEL(priv->liststore_axis), &iter,
1125 AXIS_COL_NAME, &axis,
1126 -1);
1128 value = atof(new_text); /* TODO need to check for the right conversion */
1130 parameter = hkl_parameter_new_copy(hkl_geometry_axis_get(priv->diffractometer->geometry,
1131 axis, NULL));
1132 if(NULL == parameter)
1133 goto out;
1135 hkl_parameter_min_max_get (parameter, &shit, &max, HKL_UNIT_USER);
1136 if(FALSE == hkl_parameter_min_max_set (parameter, value, max, HKL_UNIT_USER, NULL))
1137 goto free_parameter;
1139 if(FALSE == hkl_geometry_axis_set(priv->diffractometer->geometry,
1140 axis, parameter, NULL))
1141 goto free_parameter;
1143 gtk_list_store_set (priv->liststore_axis, &iter,
1144 AXIS_COL_MIN, value,
1145 -1);
1147 update_pseudo_axes (self);
1149 free_parameter:
1150 hkl_parameter_free(parameter);
1151 out:
1152 return;
1156 /* axis max cb */
1157 void
1158 hkl_gui_window_cellrendererspin4_edited_cb(GtkCellRendererText *renderer,
1159 gchar *path,
1160 gchar *new_text,
1161 gpointer user_data)
1163 HklGuiWindow *self = HKL_GUI_WINDOW(user_data);
1164 HklGuiWindowPrivate *priv = HKL_GUI_WINDOW_GET_PRIVATE(user_data);
1165 GtkTreeIter iter = {0};
1166 gdouble value = 0.0;
1167 const char *axis;
1168 HklParameter* parameter = NULL;
1169 gdouble shit, min;
1171 g_return_if_fail (renderer != NULL);
1172 g_return_if_fail (path != NULL);
1173 g_return_if_fail (new_text != NULL);
1174 g_return_if_fail (user_data != NULL);
1176 gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL(priv->liststore_axis),
1177 &iter,
1178 path);
1179 gtk_tree_model_get (GTK_TREE_MODEL(priv->liststore_axis), &iter,
1180 AXIS_COL_NAME, &axis,
1181 -1);
1183 value = atof(new_text); /* TODO need to check for the right conversion */
1186 parameter = hkl_parameter_new_copy(hkl_geometry_axis_get(priv->diffractometer->geometry,
1187 axis, NULL));
1188 if(NULL == parameter)
1189 goto out;
1191 hkl_parameter_min_max_get (parameter, &min, &shit, HKL_UNIT_USER);
1192 if(FALSE == hkl_parameter_min_max_set (parameter, min, value, HKL_UNIT_USER, NULL))
1193 goto free_parameter;
1195 if (FALSE == hkl_geometry_axis_set(priv->diffractometer->geometry,
1196 axis, parameter, NULL))
1197 goto free_parameter;
1199 gtk_list_store_set (priv->liststore_axis, &iter,
1200 AXIS_COL_MAX, value,
1201 -1);
1203 update_pseudo_axes (self);
1205 free_parameter:
1206 hkl_parameter_free(parameter);
1207 out:
1208 return;
1212 /* pseudo axis write */
1213 void
1214 hkl_gui_window_cellrenderertext5_edited_cb(GtkCellRendererText *renderer,
1215 gchar *path,
1216 gchar *new_text,
1217 gpointer user_data)
1219 HklGuiWindow *self = HKL_GUI_WINDOW(user_data);
1220 HklGuiWindowPrivate *priv = HKL_GUI_WINDOW_GET_PRIVATE(user_data);
1221 GtkTreeIter iter = {0};
1222 gdouble value = 0.0;
1223 gdouble old_value;
1224 unsigned int idx;
1225 HklEngine *engine = NULL;
1226 gboolean valid;
1227 GtkTreeIter it = {0};
1228 guint n_values;
1229 GError *error = NULL;
1231 gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL(priv->liststore_pseudo_axes),
1232 &iter,
1233 path);
1234 gtk_tree_model_get (GTK_TREE_MODEL(priv->liststore_pseudo_axes), &iter,
1235 PSEUDO_AXIS_COL_IDX, &idx,
1236 PSEUDO_AXIS_COL_ENGINE, &engine,
1237 PSEUDO_AXIS_COL_WRITE, &old_value,
1238 -1);
1240 n_values = darray_size(*hkl_engine_pseudo_axis_names_get(engine));
1241 gdouble values[n_values];
1243 /* extract all the values from the listore */
1245 valid = gtk_tree_model_get_iter_first(GTK_TREE_MODEL(priv->liststore_pseudo_axes), &it);
1246 while(valid){
1247 guint it_idx;
1248 HklEngine *it_engine;
1249 gdouble it_value;
1251 gtk_tree_model_get (GTK_TREE_MODEL(priv->liststore_pseudo_axes), &it,
1252 PSEUDO_AXIS_COL_IDX, &it_idx,
1253 PSEUDO_AXIS_COL_ENGINE, &it_engine,
1254 PSEUDO_AXIS_COL_WRITE, &it_value,
1255 -1);
1257 if(engine == it_engine)
1258 values[it_idx] = it_value;
1260 valid = gtk_tree_model_iter_next(GTK_TREE_MODEL(priv->liststore_pseudo_axes), &it);
1263 /* replace with the new value */
1264 value = atof(new_text); /* TODO need to check for the right conversion */
1265 values[idx] = value;
1267 if(diffractometer_pseudo_axis_values_set(priv->diffractometer, engine,
1268 values, n_values, &error)){
1269 gtk_list_store_set (priv->liststore_pseudo_axes,
1270 &iter,
1271 PSEUDO_AXIS_COL_WRITE, value,
1272 -1);
1274 update_axes (self);
1275 update_pseudo_axes (self);
1276 update_pseudo_axes_frames (self);
1277 update_solutions (self);
1278 update_3d(self);
1279 }else
1280 raise_error(self, &error);
1284 void
1285 hkl_gui_window_treeview_solutions_cursor_changed_cb (GtkTreeView *tree_view,
1286 gpointer user_data)
1288 HklGuiWindow* self = HKL_GUI_WINDOW(user_data);
1289 HklGuiWindowPrivate *priv = HKL_GUI_WINDOW_GET_PRIVATE(user_data);
1291 GtkTreePath* path = NULL;
1292 GtkTreeViewColumn* focus_column = NULL;
1293 GtkTreeIter iter = {0};
1294 const HklGeometryListItem *solution;
1296 gtk_tree_view_get_cursor (tree_view, &path, &focus_column);
1297 gtk_tree_model_get_iter (GTK_TREE_MODEL(priv->liststore_solutions), &iter, path);
1298 gtk_tree_model_get (GTK_TREE_MODEL(priv->liststore_solutions), &iter,
1299 SOLUTION_COL_HKL_GEOMETRY_LIST_ITEM, &solution,
1300 -1);
1302 diffractometer_set_solution(priv->diffractometer, solution);
1304 update_axes (self);
1305 update_pseudo_axes (self);
1306 update_pseudo_axes_frames (self);
1307 update_3d(self);
1309 gtk_tree_path_free (path);
1312 /* reflection h k l */
1313 #define HKL_GUI_WINDOW_CELLRENDERERTEXT_HKL_EDITED_CB(_number, _hkl, _HKL) \
1314 void \
1315 hkl_gui_window_cellrenderertext ## _number ## _edited_cb(GtkCellRendererText* _sender, const gchar* path, \
1316 const gchar* new_text, gpointer user_data) \
1318 HklGuiWindow *self = HKL_GUI_WINDOW(user_data); \
1319 HklGuiWindowPrivate *priv = HKL_GUI_WINDOW_GET_PRIVATE(user_data); \
1321 g_return_if_fail (self != NULL); \
1322 g_return_if_fail (path != NULL); \
1323 g_return_if_fail (new_text != NULL); \
1325 if (priv->sample){ \
1326 gdouble h = 0.0; \
1327 gdouble k = 0.0; \
1328 gdouble l = 0.0; \
1329 HklSampleReflection* reflection = NULL; \
1330 GtkTreeIter iter = {0}; \
1331 GError *error = NULL; \
1333 gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL(priv->liststore_reflections), \
1334 &iter, path); \
1335 gtk_tree_model_get (GTK_TREE_MODEL(priv->liststore_reflections), \
1336 &iter, \
1337 REFLECTION_COL_REFLECTION, &reflection, \
1338 -1); \
1340 hkl_sample_reflection_hkl_get (reflection, &h, &k, &l); \
1341 _hkl = atof(new_text); \
1342 if(!hkl_sample_reflection_hkl_set (reflection, h, k, l, NULL)) \
1343 raise_error(self, &error); \
1344 else \
1345 gtk_list_store_set (priv->liststore_reflections, \
1346 &iter, \
1347 REFLECTION_COL_ ## _HKL, _hkl, \
1348 -1); \
1352 HKL_GUI_WINDOW_CELLRENDERERTEXT_HKL_EDITED_CB(7, h, H);
1353 HKL_GUI_WINDOW_CELLRENDERERTEXT_HKL_EDITED_CB(8, k, K);
1354 HKL_GUI_WINDOW_CELLRENDERERTEXT_HKL_EDITED_CB(9, l, L);
1357 /* reflection flag */
1358 void
1359 hkl_gui_window_cellrenderertoggle1_toggled_cb (GtkCellRendererToggle* renderer, const gchar* path,
1360 gpointer self)
1362 HklGuiWindowPrivate *priv = HKL_GUI_WINDOW_GET_PRIVATE(self);
1364 g_return_if_fail (self != NULL);
1365 g_return_if_fail (path != NULL);
1367 if (priv->sample){
1368 gboolean flag;
1369 HklSampleReflection* reflection = NULL;
1370 GtkTreeIter iter = {0};
1372 gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL(priv->liststore_reflections),
1373 &iter, path);
1374 gtk_tree_model_get (GTK_TREE_MODEL(priv->liststore_reflections),
1375 &iter,
1376 REFLECTION_COL_REFLECTION, &reflection,
1377 -1);
1379 flag = gtk_cell_renderer_toggle_get_active(renderer);
1380 hkl_sample_reflection_flag_set (reflection, flag);
1381 gtk_list_store_set (priv->liststore_reflections,
1382 &iter,
1383 REFLECTION_COL_FLAG, flag,
1384 -1);
1388 gboolean
1389 hkl_gui_window_treeview_reflections_key_press_event_cb (GtkWidget* _sender, GdkEventKey* event,
1390 gpointer self)
1392 return TRUE;
1395 void
1396 hkl_gui_window_toolbutton_add_reflection_clicked_cb(GtkToolButton* _sender,
1397 gpointer self)
1399 HklGuiWindowPrivate *priv = HKL_GUI_WINDOW_GET_PRIVATE(self);
1401 if (priv->diffractometer == NULL){
1402 gtk_statusbar_push (priv->statusbar, 0,
1403 "Please select a diffractometer before adding reflections");
1404 return;
1407 if (priv->sample) {
1408 HklSampleReflection *reflection = NULL;
1409 GtkTreeIter iter = {0};
1410 gboolean flag;
1411 gint n_rows;
1412 GError *error = NULL;
1414 reflection = hkl_sample_reflection_new(priv->diffractometer->geometry,
1415 priv->diffractometer->detector,
1416 0, 0, 0, &error);
1417 if(!reflection)
1418 raise_error(self, &error);
1419 else{
1420 hkl_sample_add_reflection(priv->sample, reflection);
1421 flag = hkl_sample_reflection_flag_get(reflection);
1423 n_rows = gtk_tree_model_iter_n_children(GTK_TREE_MODEL(priv->liststore_reflections),
1424 NULL);
1425 gtk_list_store_insert_with_values (priv->liststore_reflections,
1426 &iter, -1,
1427 REFLECTION_COL_INDEX, n_rows,
1428 REFLECTION_COL_H, 0.,
1429 REFLECTION_COL_K, 0.,
1430 REFLECTION_COL_L, 0.,
1431 REFLECTION_COL_FLAG, flag,
1432 REFLECTION_COL_REFLECTION, reflection,
1433 -1);
1438 void
1439 hkl_gui_window_toolbutton_goto_reflection_clicked_cb (GtkToolButton* _sender, gpointer user_data)
1441 HklGuiWindow *self = HKL_GUI_WINDOW(user_data);
1442 HklGuiWindowPrivate *priv = HKL_GUI_WINDOW_GET_PRIVATE(user_data);
1444 g_return_if_fail (self != NULL);
1446 if (priv->sample) {
1447 GtkTreeSelection* selection = NULL;
1448 guint nb_rows = 0U;
1450 selection = gtk_tree_view_get_selection (priv->treeview_reflections);
1451 nb_rows = gtk_tree_selection_count_selected_rows (selection);
1453 if (nb_rows == 1) {
1454 HklSampleReflection *reflection;
1455 GtkTreeIter iter = {0};
1456 GtkTreeModel* model = NULL;
1457 GtkTreePath *treepath;
1458 GList* list;
1460 model = GTK_TREE_MODEL(priv->liststore_reflections);
1462 list = gtk_tree_selection_get_selected_rows (selection,
1463 &model);
1465 treepath = g_list_nth_data(list, 0);
1467 gtk_tree_model_get_iter (GTK_TREE_MODEL(priv->liststore_reflections),
1468 &iter, treepath);
1470 gtk_tree_model_get (GTK_TREE_MODEL(priv->liststore_reflections),
1471 &iter,
1472 REFLECTION_COL_REFLECTION, &reflection,
1473 -1);
1475 hkl_geometry_set (priv->diffractometer->geometry,
1476 hkl_sample_reflection_geometry_get(reflection));
1478 update_source (self);
1479 update_axes (self);
1480 update_pseudo_axes (self);
1481 update_3d(self);
1483 g_list_free_full (list, (GDestroyNotify) gtk_tree_path_free);
1484 } else
1485 if (nb_rows > 1)
1486 gtk_statusbar_push (priv->statusbar, 0,
1487 "Please select only one reflection.");
1488 else
1489 gtk_statusbar_push (priv->statusbar, 0,
1490 "Please select at least one reflection.");
1494 static void
1495 _del_reflection(gpointer data, gpointer user_data)
1497 HklSampleReflection *reflection;
1498 GtkTreeIter iter = {0};
1499 GtkTreePath *treepath = data;
1500 HklGuiWindowPrivate *priv = HKL_GUI_WINDOW_GET_PRIVATE(user_data);
1502 gtk_tree_model_get_iter (GTK_TREE_MODEL(priv->liststore_reflections),
1503 &iter, treepath);
1505 gtk_tree_model_get (GTK_TREE_MODEL(priv->liststore_reflections),
1506 &iter,
1507 REFLECTION_COL_REFLECTION, &reflection,
1508 -1);
1509 hkl_sample_del_reflection(priv->sample, reflection);
1512 void
1513 hkl_gui_window_toolbutton_del_reflection_clicked_cb (GtkToolButton* _sender, gpointer user_data)
1515 HklGuiWindow *self = HKL_GUI_WINDOW(user_data);
1516 HklGuiWindowPrivate *priv = HKL_GUI_WINDOW_GET_PRIVATE(user_data);
1518 g_return_if_fail (self != NULL);
1520 if (priv->sample) {
1521 GtkTreeSelection* selection = NULL;
1522 guint nb_rows = 0U;
1524 selection = gtk_tree_view_get_selection (priv->treeview_reflections);
1525 nb_rows = gtk_tree_selection_count_selected_rows (selection);
1526 if (nb_rows > 0) {
1527 GtkTreeModel* model = NULL;
1528 GList* list;
1529 GtkMessageDialog* dialog;
1531 model = GTK_TREE_MODEL(priv->liststore_reflections);
1532 list = gtk_tree_selection_get_selected_rows (selection, &model);
1535 dialog = GTK_MESSAGE_DIALOG(
1536 gtk_message_dialog_new (NULL,
1537 GTK_DIALOG_DESTROY_WITH_PARENT,
1538 GTK_MESSAGE_WARNING,
1539 GTK_BUTTONS_YES_NO,
1540 "Are you sure that you want to delete reflections"));
1542 switch (gtk_dialog_run (GTK_DIALOG(dialog))) {
1543 case GTK_RESPONSE_YES:
1545 g_list_foreach(list, _del_reflection, self);
1546 update_reflections (self);
1547 break;
1549 default:
1550 break;
1552 gtk_widget_destroy (GTK_WIDGET(dialog));
1553 g_list_free_full (list, (GDestroyNotify) gtk_tree_path_free);
1554 } else {
1555 gtk_statusbar_push (priv->statusbar, 0,
1556 "Please select at least one reflection.");
1561 static void
1562 set_up_tree_view_reflections(HklGuiWindow *self)
1564 HklGuiWindowPrivate *priv = HKL_GUI_WINDOW_GET_PRIVATE(self);
1565 GtkTreeSelection* selection = NULL;
1567 selection = gtk_tree_view_get_selection (priv->treeview_reflections);
1568 gtk_tree_selection_set_mode(selection, GTK_SELECTION_MULTIPLE);
1571 /* crystal name */
1572 void
1573 hkl_gui_window_cellrenderertext10_edited_cb(GtkCellRendererText* _sender, const gchar* path,
1574 const gchar* new_text, gpointer user_data)
1576 HklGuiWindowPrivate *priv = HKL_GUI_WINDOW_GET_PRIVATE(user_data);
1578 GtkTreeModel* model = NULL;
1579 GtkTreeIter iter = {0};
1580 HklSample* sample = NULL;
1582 g_return_if_fail (user_data != NULL);
1583 g_return_if_fail (path != NULL);
1584 g_return_if_fail (new_text != NULL);
1586 model = GTK_TREE_MODEL(priv->liststore_crystals);
1588 gtk_tree_model_get_iter_from_string (model, &iter, path);
1590 gtk_tree_model_get (model, &iter,
1591 SAMPLE_COL_SAMPLE, &sample,
1592 -1);
1594 hkl_sample_name_set (sample, new_text);
1596 gtk_list_store_set(priv->liststore_crystals, &iter,
1597 SAMPLE_COL_NAME, new_text,
1598 -1);
1601 #define set_lattice(lattice, parameter) do{ \
1602 const HklParameter *p; \
1603 gdouble min, max, value; \
1604 gboolean fit; \
1605 p = hkl_lattice_## parameter ##_get((lattice)); \
1606 value = hkl_parameter_value_get(p, HKL_UNIT_USER); \
1607 hkl_parameter_min_max_get(p, &min, &max, HKL_UNIT_USER); \
1608 fit = hkl_parameter_fit_get(p); \
1609 gtk_spin_button_set_value(priv->spinbutton_## parameter, value); \
1610 gtk_spin_button_set_value(priv->spinbutton_## parameter ##_min, min); \
1611 gtk_spin_button_set_value(priv->spinbutton_## parameter ##_max, max); \
1612 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(priv->checkbutton_ ## parameter), fit); \
1613 }while(0)
1615 static void
1616 update_lattice (HklGuiWindow* self)
1618 HklGuiWindowPrivate *priv = HKL_GUI_WINDOW_GET_PRIVATE(self);
1620 g_return_if_fail (self != NULL);
1622 if (priv->sample != NULL) {
1623 const HklLattice *lattice;
1624 lattice = hkl_sample_lattice_get(priv->sample);
1625 set_lattice(lattice, a);
1626 set_lattice(lattice, b);
1627 set_lattice(lattice, c);
1628 set_lattice(lattice, alpha);
1629 set_lattice(lattice, beta);
1630 set_lattice(lattice, gamma);
1634 #define set_reciprocal_lattice(lattice, parameter) do{ \
1635 const HklParameter *p; \
1636 gdouble value; \
1637 p = hkl_lattice_## parameter ##_get((lattice)); \
1638 value = hkl_parameter_value_get(p, HKL_UNIT_USER); \
1639 gtk_spin_button_set_value(priv->spinbutton_## parameter ##_star, value); \
1640 }while(0)
1642 static void
1643 update_reciprocal_lattice (HklGuiWindow* self)
1645 HklGuiWindowPrivate *priv = HKL_GUI_WINDOW_GET_PRIVATE(self);
1647 g_return_if_fail (self != NULL);
1649 if (priv->sample != NULL) {
1650 hkl_lattice_reciprocal (hkl_sample_lattice_get(priv->sample),
1651 priv->reciprocal);
1653 set_reciprocal_lattice(priv->reciprocal, a);
1654 set_reciprocal_lattice(priv->reciprocal, b);
1655 set_reciprocal_lattice(priv->reciprocal, c);
1656 set_reciprocal_lattice(priv->reciprocal, alpha);
1657 set_reciprocal_lattice(priv->reciprocal, beta);
1658 set_reciprocal_lattice(priv->reciprocal, gamma);
1662 #define set_ux_uy_uz(sample, parameter) do { \
1663 const HklParameter *p; \
1664 p = hkl_sample_## parameter ##_get((sample)); \
1665 gboolean fit = hkl_parameter_fit_get(p); \
1666 gtk_spin_button_set_value(priv->spinbutton_## parameter, \
1667 hkl_parameter_value_get(p, HKL_UNIT_USER)); \
1668 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(priv->checkbutton_## parameter), fit); \
1669 }while(0)
1671 static void
1672 update_ux_uy_uz (HklGuiWindow* self)
1674 HklGuiWindowPrivate *priv = HKL_GUI_WINDOW_GET_PRIVATE(self);
1676 g_return_if_fail (self != NULL);
1678 if (priv->sample != NULL) {
1679 set_ux_uy_uz(priv->sample, ux);
1680 set_ux_uy_uz(priv->sample, uy);
1681 set_ux_uy_uz(priv->sample, uz);
1685 #define set_UB(i, j) do{ \
1686 gtk_label_set_markup(priv->label_UB ## i ## j, \
1687 g_ascii_formatd(text, \
1688 G_ASCII_DTOSTR_BUF_SIZE, \
1689 "<tt> %+.4f </tt>", \
1690 hkl_matrix_get(UB, i - 1, j - 1))); \
1691 }while(0)
1693 static void
1694 update_UB (HklGuiWindow* self)
1696 HklGuiWindowPrivate *priv = HKL_GUI_WINDOW_GET_PRIVATE(self);
1698 g_return_if_fail (self != NULL);
1700 if (priv->sample != NULL) {
1701 const HklMatrix *UB = hkl_sample_UB_get (priv->sample);
1702 gchar *text = g_new0 (gchar, G_ASCII_DTOSTR_BUF_SIZE);
1704 set_UB(1, 1);
1705 set_UB(1, 2);
1706 set_UB(1, 3);
1707 set_UB(2, 1);
1708 set_UB(2, 2);
1709 set_UB(2, 3);
1710 set_UB(3, 1);
1711 set_UB(3, 2);
1712 set_UB(3, 3);
1714 g_free(text);
1718 void
1719 hkl_gui_window_treeview_crystals_cursor_changed_cb (GtkTreeView* _sender, gpointer user_data)
1721 GtkTreePath* path = NULL;
1722 GtkTreeViewColumn* column = NULL;
1723 GtkTreeIter iter = {0};
1725 HklGuiWindow *self = HKL_GUI_WINDOW(user_data);
1726 HklGuiWindowPrivate *priv = HKL_GUI_WINDOW_GET_PRIVATE(user_data);
1727 HklSample *sample;
1729 g_return_if_fail (user_data != NULL);
1731 gtk_tree_view_get_cursor (priv->treeview_crystals, &path, &column);
1732 if(path){
1733 if (gtk_tree_model_get_iter (GTK_TREE_MODEL(priv->liststore_crystals),
1734 &iter, path) == TRUE){
1735 gtk_tree_model_get (GTK_TREE_MODEL(priv->liststore_crystals),
1736 &iter,
1737 SAMPLE_COL_SAMPLE, &sample,
1738 -1);
1740 if(sample && sample != priv->sample){
1741 priv->sample = sample;
1743 update_reflections(self);
1744 update_lattice(self);
1745 update_reciprocal_lattice (self);
1746 update_ux_uy_uz (self);
1747 update_UB (self);
1749 if(priv->diffractometer){
1750 diffractometer_set_sample(priv->diffractometer,
1751 priv->sample);
1753 update_pseudo_axes (self);
1754 update_pseudo_axes_frames (self);
1755 update_solutions(self);
1759 gtk_tree_path_free (path);
1765 static GtkTreeIter
1766 _add_sample(HklGuiWindow *self, HklSample *sample)
1768 HklGuiWindowPrivate *priv = HKL_GUI_WINDOW_GET_PRIVATE(self);
1769 GtkTreeIter iter = {0};
1770 const HklLattice *lattice;
1771 gdouble a, b, c, alpha, beta, gamma;
1773 g_return_val_if_fail (self != NULL, iter);
1775 lattice = hkl_sample_lattice_get(sample);
1776 a = hkl_parameter_value_get(hkl_lattice_a_get(lattice), HKL_UNIT_USER);
1777 b = hkl_parameter_value_get(hkl_lattice_b_get(lattice), HKL_UNIT_USER);
1778 c = hkl_parameter_value_get(hkl_lattice_c_get(lattice), HKL_UNIT_USER);
1779 alpha = hkl_parameter_value_get(hkl_lattice_alpha_get(lattice),
1780 HKL_UNIT_USER);
1781 beta = hkl_parameter_value_get(hkl_lattice_beta_get(lattice),
1782 HKL_UNIT_USER);
1783 gamma = hkl_parameter_value_get(hkl_lattice_gamma_get(lattice),
1784 HKL_UNIT_USER);
1786 gtk_list_store_insert_with_values(priv->liststore_crystals,
1787 &iter, -1,
1788 SAMPLE_COL_SAMPLE, sample,
1789 SAMPLE_COL_NAME, hkl_sample_name_get(sample),
1790 SAMPLE_COL_A, a,
1791 SAMPLE_COL_B, b,
1792 SAMPLE_COL_C, c,
1793 SAMPLE_COL_ALPHA, alpha,
1794 SAMPLE_COL_BETA, beta,
1795 SAMPLE_COL_GAMMA, gamma,
1796 -1);
1797 return iter;
1800 static void
1801 set_up_tree_view_crystals (HklGuiWindow* self)
1803 HklGuiWindowPrivate *priv = HKL_GUI_WINDOW_GET_PRIVATE(self);
1804 GtkTreeIter iter = {0};
1805 GtkTreePath *path = NULL;
1807 g_return_if_fail (self != NULL);
1809 iter = _add_sample(self, hkl_sample_new("default"));
1811 path = gtk_tree_model_get_path(GTK_TREE_MODEL(priv->liststore_crystals),
1812 &iter);
1814 gtk_tree_view_set_cursor(priv->treeview_crystals, path, NULL, FALSE);
1816 gtk_tree_path_free(path);
1819 static void
1820 _add_sample_and_edit_name(HklGuiWindow *self, HklSample *sample)
1822 HklGuiWindowPrivate *priv = HKL_GUI_WINDOW_GET_PRIVATE(self);
1823 GtkTreeIter iter = {0};
1824 GtkTreePath* path = NULL;
1825 GtkTreeViewColumn* column = NULL;
1827 iter = _add_sample(self, sample);
1829 path = gtk_tree_model_get_path(GTK_TREE_MODEL(priv->liststore_crystals),
1830 &iter);
1831 column = gtk_tree_view_get_column (priv->treeview_crystals, 0);
1832 gtk_tree_view_set_cursor (priv->treeview_crystals, path, column, TRUE);
1834 gtk_tree_path_free(path);
1837 void
1838 hkl_gui_window_toolbutton_add_crystal_clicked_cb (GtkToolButton* _sender, gpointer user_data)
1840 HklGuiWindow *self = HKL_GUI_WINDOW(user_data);
1841 HklSample *sample;
1843 g_return_if_fail (user_data != NULL);
1845 sample = hkl_sample_new ("new");
1846 if(sample)
1847 _add_sample_and_edit_name(self, sample);
1850 void
1851 hkl_gui_window_toolbutton_copy_crystal_clicked_cb (GtkToolButton* _sender, gpointer user_data)
1853 HklGuiWindow *self = HKL_GUI_WINDOW(user_data);
1854 HklGuiWindowPrivate *priv = HKL_GUI_WINDOW_GET_PRIVATE(user_data);
1855 HklSample *copy = NULL;
1857 g_return_if_fail (self != NULL);
1859 if(priv->sample) {
1860 copy = hkl_sample_new_copy(priv->sample);
1861 if (copy)
1862 _add_sample_and_edit_name(self, copy);
1863 }else
1864 gtk_statusbar_push (priv->statusbar, (guint) 0, "Please select a crystal to copy.");
1867 void
1868 hkl_gui_window_toolbutton_del_crystal_clicked_cb (GtkToolButton* _sender, gpointer user_data)
1870 HklGuiWindowPrivate *priv = HKL_GUI_WINDOW_GET_PRIVATE(user_data);
1872 g_return_if_fail (user_data != NULL);
1874 if (priv->sample != NULL) {
1875 guint n_rows;
1877 n_rows = gtk_tree_model_iter_n_children(GTK_TREE_MODEL(priv->liststore_crystals),
1878 NULL );
1879 if (n_rows == 1)
1880 return;
1881 else {
1882 GtkTreeIter iter = {0};
1883 GtkTreePath *path = NULL;
1884 GtkTreeViewColumn *column = NULL;
1886 gtk_tree_view_get_cursor(priv->treeview_crystals,
1887 &path, &column);
1888 if (path){
1889 if (gtk_tree_model_get_iter (GTK_TREE_MODEL(priv->liststore_crystals),
1890 &iter, path) == TRUE) {
1891 gtk_tree_path_free(path);
1893 hkl_sample_free(priv->sample);
1894 if (gtk_list_store_remove(priv->liststore_crystals,
1895 &iter) == TRUE){
1896 path = gtk_tree_model_get_path(GTK_TREE_MODEL(priv->liststore_crystals),
1897 &iter);
1898 gtk_tree_view_set_cursor(priv->treeview_crystals,
1899 path, NULL, FALSE);
1907 #define get_lattice_parameter(lattice, parameter, _error) do{ \
1908 HklParameter *p = hkl_parameter_new_copy(hkl_lattice_## parameter ##_get(lattice)); \
1909 if(!hkl_parameter_min_max_set(p, \
1910 gtk_spin_button_get_value(priv->spinbutton_## parameter ##_min), \
1911 gtk_spin_button_get_value(priv->spinbutton_## parameter ##_max), \
1912 HKL_UNIT_USER, _error)){ \
1913 raise_error(self, _error); \
1914 hkl_parameter_free(p); \
1915 return; \
1916 }else{ \
1917 hkl_parameter_fit_set(p, gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(priv->checkbutton_## parameter))); \
1918 if(!hkl_lattice_ ## parameter ## _set(lattice, p, _error)){ \
1919 raise_error(self, _error); \
1920 hkl_parameter_free(p); \
1921 return; \
1924 hkl_parameter_free(p); \
1925 } while(0)
1927 #define get_ux_uy_uz(sample, parameter, _error) do { \
1928 HklParameter *p; \
1929 p = hkl_parameter_new_copy(hkl_sample_## parameter ##_get(sample)); \
1930 if(!hkl_parameter_value_set(p, \
1931 gtk_spin_button_get_value (priv->spinbutton_## parameter), \
1932 HKL_UNIT_USER, _error)){ \
1933 raise_error(self, _error); \
1934 hkl_parameter_free(p); \
1935 return; \
1936 }else{ \
1937 hkl_parameter_fit_set(p, \
1938 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(priv->checkbutton_## parameter))); \
1939 if(!hkl_sample_ ## parameter ## _set(sample, p, _error)){ \
1940 raise_error(self, _error); \
1941 hkl_parameter_free(p); \
1942 return; \
1945 hkl_parameter_free(p); \
1946 }while(0)
1949 static gboolean
1950 _update_crystal_model(GtkTreeModel *model,
1951 GtkTreePath *path,
1952 GtkTreeIter *iter,
1953 gpointer data)
1955 HklGuiWindowPrivate *priv = HKL_GUI_WINDOW_GET_PRIVATE(data);
1956 HklSample *sample = NULL;
1958 gtk_tree_model_get(model, iter,
1959 SAMPLE_COL_SAMPLE, &sample,
1960 -1);
1961 if(priv->sample == sample){
1962 const HklLattice *lattice;
1963 gdouble a, b, c, alpha, beta, gamma;
1965 lattice = hkl_sample_lattice_get(sample);
1966 a = hkl_parameter_value_get(hkl_lattice_a_get(lattice),
1967 HKL_UNIT_USER);
1968 b = hkl_parameter_value_get(hkl_lattice_b_get(lattice),
1969 HKL_UNIT_USER);
1970 c = hkl_parameter_value_get(hkl_lattice_c_get(lattice),
1971 HKL_UNIT_USER);
1972 alpha = hkl_parameter_value_get(hkl_lattice_alpha_get(lattice),
1973 HKL_UNIT_USER);
1974 beta = hkl_parameter_value_get(hkl_lattice_beta_get(lattice),
1975 HKL_UNIT_USER);
1976 gamma = hkl_parameter_value_get(hkl_lattice_gamma_get(lattice),
1977 HKL_UNIT_USER);
1979 gtk_list_store_set(priv->liststore_crystals,
1980 iter,
1981 SAMPLE_COL_NAME, hkl_sample_name_get(sample),
1982 SAMPLE_COL_A, a,
1983 SAMPLE_COL_B, b,
1984 SAMPLE_COL_C, c,
1985 SAMPLE_COL_ALPHA, alpha,
1986 SAMPLE_COL_BETA, beta,
1987 SAMPLE_COL_GAMMA, gamma,
1988 -1);
1989 return TRUE;
1991 return FALSE;
1994 static void
1995 update_crystal_model(HklGuiWindow *self)
1997 HklGuiWindowPrivate *priv = HKL_GUI_WINDOW_GET_PRIVATE(self);
1999 gtk_tree_model_foreach(GTK_TREE_MODEL(priv->liststore_crystals),
2000 _update_crystal_model,
2001 self);
2004 /* apply crystal parameters */
2005 void
2006 hkl_gui_window_button2_clicked_cb (GtkButton* _sender, gpointer user_data)
2008 HklGuiWindow *self = HKL_GUI_WINDOW(user_data);
2009 HklGuiWindowPrivate *priv = HKL_GUI_WINDOW_GET_PRIVATE(user_data);
2011 g_return_if_fail (self != NULL);
2013 if (priv->sample != NULL) {
2014 gdouble a, b, c, alpha, beta, gamma;
2015 HklLattice *lattice;
2016 GError *error = NULL;
2018 fprintf(stderr, "%s\n", __func__);
2019 /* lattice parameters */
2020 a = gtk_spin_button_get_value (priv->spinbutton_a);
2021 b = gtk_spin_button_get_value (priv->spinbutton_b);
2022 c = gtk_spin_button_get_value (priv->spinbutton_c);
2023 alpha = gtk_spin_button_get_value (priv->spinbutton_alpha);
2024 beta = gtk_spin_button_get_value (priv->spinbutton_beta);
2025 gamma = gtk_spin_button_get_value (priv->spinbutton_gamma);
2027 lattice = hkl_lattice_new(a, b, c,
2028 alpha * HKL_DEGTORAD,
2029 beta * HKL_DEGTORAD,
2030 gamma * HKL_DEGTORAD, &error);
2031 if(!lattice)
2032 raise_error(self, &error);
2033 else{
2035 get_lattice_parameter(lattice, a, &error);
2036 get_lattice_parameter(lattice, b, &error);
2037 get_lattice_parameter(lattice, c, &error);
2038 get_lattice_parameter(lattice, alpha, &error);
2039 get_lattice_parameter(lattice, beta, &error);
2040 get_lattice_parameter(lattice, gamma, &error);
2042 hkl_sample_lattice_set(priv->sample, lattice);
2044 hkl_lattice_free(lattice);
2046 /* UB */
2047 get_ux_uy_uz(priv->sample, ux, &error);
2048 get_ux_uy_uz(priv->sample, uy, &error);
2049 get_ux_uy_uz(priv->sample, uz, &error);
2051 if(priv->diffractometer)
2052 diffractometer_set_sample(priv->diffractometer,
2053 priv->sample);
2055 update_crystal_model (self);
2056 update_reciprocal_lattice (self);
2057 update_UB (self);
2058 update_pseudo_axes (self);
2059 update_pseudo_axes_frames (self);
2064 void
2065 hkl_gui_window_spinbutton_lambda_value_changed_cb (GtkSpinButton* _sender, gpointer user_data)
2067 HklGuiWindow *self = HKL_GUI_WINDOW(user_data);
2068 HklGuiWindowPrivate *priv = HKL_GUI_WINDOW_GET_PRIVATE(user_data);
2070 diffractometer_set_wavelength(priv->diffractometer,
2071 gtk_spin_button_get_value(_sender));
2072 update_pseudo_axes (self);
2073 update_pseudo_axes_frames (self);
2076 void
2077 hkl_gui_window_spinbutton_ux_value_changed_cb (GtkSpinButton *_senser, gpointer user_data)
2079 HklGuiWindow *self = HKL_GUI_WINDOW(user_data);
2080 HklGuiWindowPrivate *priv = HKL_GUI_WINDOW_GET_PRIVATE(user_data);
2081 GError *error = NULL;
2083 get_ux_uy_uz(priv->sample, ux, &error);
2085 if(priv->diffractometer)
2086 diffractometer_set_sample(priv->diffractometer,
2087 priv->sample);
2089 update_UB (self);
2090 update_pseudo_axes (self);
2091 update_pseudo_axes_frames (self);
2094 void
2095 hkl_gui_window_spinbutton_uy_value_changed_cb (GtkSpinButton *_senser, gpointer user_data)
2097 HklGuiWindow *self = HKL_GUI_WINDOW(user_data);
2098 HklGuiWindowPrivate *priv = HKL_GUI_WINDOW_GET_PRIVATE(user_data);
2099 GError *error = NULL;
2101 get_ux_uy_uz(priv->sample, uy, &error);
2103 if(priv->diffractometer)
2104 diffractometer_set_sample(priv->diffractometer,
2105 priv->sample);
2107 update_UB (self);
2108 update_pseudo_axes (self);
2109 update_pseudo_axes_frames (self);
2112 void
2113 hkl_gui_window_spinbutton_uz_value_changed_cb (GtkSpinButton *_senser, gpointer user_data)
2115 HklGuiWindow *self = HKL_GUI_WINDOW(user_data);
2116 HklGuiWindowPrivate *priv = HKL_GUI_WINDOW_GET_PRIVATE(user_data);
2117 GError *error = NULL;
2119 get_ux_uy_uz(priv->sample, uz, &error);
2121 if(priv->diffractometer)
2122 diffractometer_set_sample(priv->diffractometer,
2123 priv->sample);
2125 update_UB (self);
2126 update_pseudo_axes (self);
2127 update_pseudo_axes_frames (self);
2130 void
2131 hkl_gui_window_toolbutton_setUB_clicked_cb(GtkToolButton* _sender, gpointer user_data)
2133 HklGuiWindow *self = HKL_GUI_WINDOW(user_data);
2134 HklGuiWindowPrivate *priv = HKL_GUI_WINDOW_GET_PRIVATE(user_data);
2136 HklMatrix *UB;
2137 GError *error = NULL;
2139 UB = hkl_matrix_new_full(gtk_spin_button_get_value(priv->spinbutton_U11),
2140 gtk_spin_button_get_value(priv->spinbutton_U12),
2141 gtk_spin_button_get_value(priv->spinbutton_U13),
2142 gtk_spin_button_get_value(priv->spinbutton_U21),
2143 gtk_spin_button_get_value(priv->spinbutton_U22),
2144 gtk_spin_button_get_value(priv->spinbutton_U23),
2145 gtk_spin_button_get_value(priv->spinbutton_U31),
2146 gtk_spin_button_get_value(priv->spinbutton_U32),
2147 gtk_spin_button_get_value(priv->spinbutton_U33));
2149 if(!hkl_sample_UB_set (priv->sample, UB, &error))
2150 raise_error(self, &error);
2151 else{
2152 if(priv->diffractometer){
2153 diffractometer_set_sample(priv->diffractometer,
2154 priv->sample);
2156 update_lattice (self);
2157 update_crystal_model (self);
2158 update_reciprocal_lattice (self);
2159 update_UB (self);
2160 update_ux_uy_uz (self);
2161 update_pseudo_axes (self);
2162 update_pseudo_axes_frames (self);
2166 hkl_matrix_free(UB);
2169 void
2170 hkl_gui_window_toolbutton_computeUB_clicked_cb (GtkToolButton* _sender, gpointer user_data)
2172 HklGuiWindow *self = HKL_GUI_WINDOW(user_data);
2173 HklGuiWindowPrivate *priv = HKL_GUI_WINDOW_GET_PRIVATE(user_data);
2174 GtkTreeSelection* selection = NULL;
2175 guint nb_rows = 0U;
2177 selection = gtk_tree_view_get_selection (priv->treeview_reflections);
2178 nb_rows = gtk_tree_selection_count_selected_rows (selection);
2179 if (nb_rows > 1) {
2180 GtkTreeModel* model = NULL;
2181 GList* list;
2182 GtkTreeIter iter = {0};
2183 GtkTreePath *path;
2184 HklSampleReflection *ref1, *ref2;
2185 GError *error = NULL;
2187 model = GTK_TREE_MODEL(priv->liststore_reflections);
2188 list = gtk_tree_selection_get_selected_rows (selection, &model);
2190 /* get the first reflection */
2191 path = g_list_nth_data(list, 0);
2192 gtk_tree_model_get_iter (GTK_TREE_MODEL(priv->liststore_reflections),
2193 &iter,
2194 path);
2195 gtk_tree_model_get (GTK_TREE_MODEL(priv->liststore_reflections), &iter,
2196 REFLECTION_COL_REFLECTION, &ref1,
2197 -1);
2199 /* get the second one */
2200 path = g_list_nth_data(list, 1);
2201 gtk_tree_model_get_iter (GTK_TREE_MODEL(priv->liststore_reflections),
2202 &iter,
2203 path);
2204 gtk_tree_model_get (GTK_TREE_MODEL(priv->liststore_reflections), &iter,
2205 REFLECTION_COL_REFLECTION, &ref2,
2206 -1);
2208 if(!hkl_sample_compute_UB_busing_levy(priv->sample,
2209 ref1, ref2, &error)){
2210 raise_error(self, &error);
2211 }else{
2212 if(priv->diffractometer)
2213 diffractometer_set_sample(priv->diffractometer,
2214 priv->sample);
2216 update_UB (self);
2217 update_ux_uy_uz (self);
2218 update_pseudo_axes (self);
2219 update_pseudo_axes_frames (self);
2221 g_list_free_full (list, (GDestroyNotify) gtk_tree_path_free);
2222 } else {
2223 gtk_statusbar_push (priv->statusbar, 0,
2224 "Please select at least two reflection.");
2228 void
2229 hkl_gui_window_toolbutton_affiner_clicked_cb (GtkToolButton* _sender, gpointer user_data)
2231 HklGuiWindow *self = HKL_GUI_WINDOW(user_data);
2232 HklGuiWindowPrivate *priv = HKL_GUI_WINDOW_GET_PRIVATE(user_data);
2233 GError *error = NULL;
2235 if(!hkl_sample_affine (priv->sample, &error)){
2236 raise_error(self, &error);
2237 }else{
2238 if(priv->diffractometer)
2239 diffractometer_set_sample(priv->diffractometer,
2240 priv->sample);
2242 update_lattice (self);
2243 update_crystal_model (self);
2244 update_reciprocal_lattice (self);
2245 update_UB (self);
2246 update_ux_uy_uz (self);
2247 update_pseudo_axes (self);
2248 update_pseudo_axes_frames (self);
2252 #define TOGGLE_LATTICE_CB(_parameter) \
2253 void hkl_gui_window_checkbutton_ ## _parameter ## _toggled_cb(GtkCheckButton *checkbutton, \
2254 gpointer user_data) \
2256 HklGuiWindow *self = HKL_GUI_WINDOW(user_data); \
2257 HklGuiWindowPrivate *priv = HKL_GUI_WINDOW_GET_PRIVATE(user_data); \
2258 HklLattice *lattice; \
2259 HklParameter *p; \
2260 GError *error = NULL; \
2261 lattice = hkl_lattice_new_copy(hkl_sample_lattice_get(priv->sample)); \
2262 p = hkl_parameter_new_copy(hkl_lattice_## _parameter ##_get(lattice)); \
2263 hkl_parameter_fit_set(p, \
2264 gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(checkbutton))); \
2265 if(!hkl_lattice_## _parameter ##_set(lattice, p, &error)){ \
2266 raise_error(self, &error); \
2267 }else{ \
2268 hkl_sample_lattice_set(priv->sample, lattice); \
2270 hkl_parameter_free(p); \
2271 hkl_lattice_free(lattice); \
2274 TOGGLE_LATTICE_CB(a);
2275 TOGGLE_LATTICE_CB(b);
2276 TOGGLE_LATTICE_CB(c);
2277 TOGGLE_LATTICE_CB(alpha);
2278 TOGGLE_LATTICE_CB(beta);
2279 TOGGLE_LATTICE_CB(gamma);
2281 #define TOGGLE_UX_UY_UZ(_parameter) \
2282 void hkl_gui_window_checkbutton_ ## _parameter ## _toggled_cb(GtkCheckButton *checkbutton, \
2283 gpointer user_data) \
2285 HklGuiWindow *self = HKL_GUI_WINDOW(user_data); \
2286 HklGuiWindowPrivate *priv = HKL_GUI_WINDOW_GET_PRIVATE(user_data); \
2287 HklParameter *p; \
2288 GError *error = NULL; \
2289 p = hkl_parameter_new_copy(hkl_sample_ ## _parameter ## _get(priv->sample)); \
2290 hkl_parameter_fit_set(p, \
2291 gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(checkbutton))); \
2292 if(!hkl_sample_ ## _parameter ## _set(priv->sample, p, &error)){ \
2293 raise_error(self, &error); \
2295 hkl_parameter_free(p); \
2298 TOGGLE_UX_UY_UZ(ux);
2299 TOGGLE_UX_UY_UZ(uy);
2300 TOGGLE_UX_UY_UZ(uz);
2304 static gboolean _hkl_gui_window_on_tree_view_crystals_key_press_event_gtk_widget_key_press_event (GtkWidget* _sender, GdkEventKey* event, gpointer self) {
2305 gboolean result;
2306 result = hkl_gui_window_on_tree_view_crystals_key_press_event (event, self);
2308 return result;
2312 static gboolean hkl_gui_window_on_tree_view_crystals_key_press_event (GdkEventKey* event, HklGuiWindow* self) {
2313 gboolean result = FALSE;
2315 g_return_val_if_fail (self != NULL, FALSE);
2317 g_return_val_if_fail (event != NULL, FALSE);
2319 result = TRUE;
2321 return result;
2327 static void
2328 hkl_gui_window_class_init (HklGuiWindowClass *class)
2330 GObjectClass *gobject_class = G_OBJECT_CLASS (class);
2332 g_type_class_add_private (class, sizeof (HklGuiWindowPrivate));
2334 /* virtual method */
2335 gobject_class->finalize = finalize;
2339 static void hkl_gui_window_init (HklGuiWindow * self)
2341 HklGuiWindowPrivate *priv = HKL_GUI_WINDOW_GET_PRIVATE(self);
2343 priv->diffractometer = NULL;
2344 priv->sample = NULL;
2346 darray_init(priv->pseudo_frames);
2348 priv->reciprocal = hkl_lattice_new_default ();
2350 hkl_gui_window_get_widgets_and_objects_from_ui (self);
2352 set_up_diffractometer_model (self);
2354 set_up_tree_view_crystals (self);
2356 set_up_tree_view_reflections(self);
2359 int main (int argc, char ** argv)
2361 gtk_init (&argc, &argv);
2362 #ifdef HKL3D
2363 gtk_gl_init(&argc, &argv);
2364 #endif
2365 hkl_gui_window_new ();
2367 gtk_main ();
2369 return 0;