1 /*   EXTRAITS DE LA LICENCE
2 	Copyright CEA, contributeurs : Damien
3 	CALISTE, laboratoire L_Sim, (2001-2014)
4 
5 	Adresse mèl :
6 	CALISTE, damien P caliste AT cea P fr.
7 
8 	Ce logiciel est un programme informatique servant à visualiser des
9 	structures atomiques dans un rendu pseudo-3D.
10 
11 	Ce logiciel est régi par la licence CeCILL soumise au droit français et
12 	respectant les principes de diffusion des logiciels libres. Vous pouvez
13 	utiliser, modifier et/ou redistribuer ce programme sous les conditions
14 	de la licence CeCILL telle que diffusée par le CEA, le CNRS et l'INRIA
15 	sur le site "http://www.cecill.info".
16 
17 	Le fait que vous puissiez accéder à cet en-tête signifie que vous avez
18 	pris connaissance de la licence CeCILL, et que vous en avez accepté les
19 	termes (cf. le fichier Documentation/licence.fr.txt fourni avec ce logiciel).
20 */
21 
22 /*   LICENCE SUM UP
23 	Copyright CEA, contributors : Damien
24 	CALISTE, laboratoire L_Sim, (2001-2014)
25 
26 	E-mail address:
27 	CALISTE, damien P caliste AT cea P fr.
28 
29 	This software is a computer program whose purpose is to visualize atomic
30 	configurations in 3D.
31 
32 	This software is governed by the CeCILL  license under French law and
33 	abiding by the rules of distribution of free software.  You can  use,
34 	modify and/ or redistribute the software under the terms of the CeCILL
35 	license as circulated by CEA, CNRS and INRIA at the following URL
36 	"http://www.cecill.info".
37 
38 	The fact that you are presently reading this means that you have had
39 	knowledge of the CeCILL license and that you accept its terms. You can
40 	find a copy of this licence shipped with this software at Documentation/licence.en.txt.
41 */
42 
43 #include "ui_boxTransform.h"
44 
45 #include <support.h>
46 #include <visu_tools.h>
47 
48 #include <coreTools/toolMatrix.h>
49 #include <extraGtkFunctions/gtk_stippleComboBoxWidget.h>
50 #include <extraGtkFunctions/gtk_colorComboBoxWidget.h>
51 
52 /**
53  * SECTION:ui_boxTransform
54  * @short_description: Defines a widget to setup box transformations.
55  *
56  * <para>A set of widgets to setup the transformation applied to a box
57  * (translations, expansions...).</para>
58  */
59 
60 /**
61  * VisuUiBoxTransformClass:
62  * @parent: the parent class;
63  *
64  * A short way to identify #_VisuUiBoxTransformClass structure.
65  *
66  * Since: 3.8
67  */
68 /**
69  * VisuUiBoxTransform:
70  *
71  * An opaque structure.
72  *
73  * Since: 3.8
74  */
75 /**
76  * VisuUiBoxTransformPrivate:
77  *
78  * Private fields for #VisuUiBoxTransform objects.
79  *
80  * Since: 3.8
81  */
82 struct _VisuUiBoxTransformPrivate
83 {
84   gboolean dispose_has_run;
85 
86   GtkWidget *checkAllowTranslations, *checkInBox, *checkAllowExpand;
87   GtkWidget *spinTransXYZ[3], *spinExpandXYZ[3];
88   GtkWidget *stippleExpandBox, *colorExpandBox;
89   GtkWidget *labelBc, *warnBc;
90   GtkWidget *comboUnit, *comboHide;
91 
92   VisuPointset *pointset;
93   gulong sig_box;
94   VisuBox *box;
95   GBinding *bind_bc, *bind_bcWarn;
96   GBinding *bind_trans[3], *bind_allowTrans, *bind_boxTrans;
97   GBinding *bind_expand[3], *bind_allowExpand;
98   GBinding *bind_units, *bind_hide;
99   gulong sig_boundary;
100 
101   VisuGlExtBox *glBox;
102   GBinding *bind_stipple, *bind_color;
103 };
104 
105 enum
106   {
107     PROP_0,
108     POINTSET_PROP,
109     GL_BOX_PROP,
110     N_PROP
111   };
112 static GParamSpec *properties[N_PROP];
113 
114 static void visu_ui_box_transform_finalize(GObject* obj);
115 static void visu_ui_box_transform_dispose(GObject* obj);
116 static void visu_ui_box_transform_get_property(GObject* obj, guint property_id,
117                                                GValue *value, GParamSpec *pspec);
118 static void visu_ui_box_transform_set_property(GObject* obj, guint property_id,
119                                                const GValue *value, GParamSpec *pspec);
120 
G_DEFINE_TYPE_WITH_CODE(VisuUiBoxTransform,visu_ui_box_transform,GTK_TYPE_BOX,G_ADD_PRIVATE (VisuUiBoxTransform))121 G_DEFINE_TYPE_WITH_CODE(VisuUiBoxTransform, visu_ui_box_transform, GTK_TYPE_BOX,
122                         G_ADD_PRIVATE(VisuUiBoxTransform))
123 
124 static void visu_ui_box_transform_class_init(VisuUiBoxTransformClass *klass)
125 {
126   DBG_fprintf(stderr, "Ui BoxTransform: creating the class of the widget.\n");
127   DBG_fprintf(stderr, "                     - adding new signals ;\n");
128 
129   /* Connect freeing methods. */
130   G_OBJECT_CLASS(klass)->dispose = visu_ui_box_transform_dispose;
131   G_OBJECT_CLASS(klass)->finalize = visu_ui_box_transform_finalize;
132   G_OBJECT_CLASS(klass)->set_property = visu_ui_box_transform_set_property;
133   G_OBJECT_CLASS(klass)->get_property = visu_ui_box_transform_get_property;
134 
135   /**
136    * VisuUiBoxTransform::pointset:
137    *
138    * Store the #VisuPointset model.
139    *
140    * Since: 3.8
141    */
142   properties[POINTSET_PROP] = g_param_spec_object("pointset", "Pointset",
143                                                   "Pointset to transform",
144                                                   VISU_TYPE_POINTSET, G_PARAM_READWRITE);
145   g_object_class_install_property(G_OBJECT_CLASS(klass), POINTSET_PROP,
146 				  properties[POINTSET_PROP]);
147   /**
148    * VisuUiBoxTransform::gl-box:
149    *
150    * Store the rendering box object of box.
151    *
152    * Since: 3.8
153    */
154   properties[GL_BOX_PROP] = g_param_spec_object("gl-box", "OpenGL box object",
155                                                 "rendering object used for box",
156                                                 VISU_TYPE_GL_EXT_BOX, G_PARAM_READWRITE);
157   g_object_class_install_property(G_OBJECT_CLASS(klass), GL_BOX_PROP,
158 				  properties[GL_BOX_PROP]);
159 }
visu_ui_box_transform_dispose(GObject * obj)160 static void visu_ui_box_transform_dispose(GObject *obj)
161 {
162   DBG_fprintf(stderr, "Ui BoxTransform: dispose object %p.\n", (gpointer)obj);
163 
164   if (VISU_UI_BOX_TRANSFORM(obj)->priv->dispose_has_run)
165     return;
166 
167   visu_ui_box_transform_bind(VISU_UI_BOX_TRANSFORM(obj), (VisuPointset*)0);
168   visu_ui_box_transform_bindGlExtBox(VISU_UI_BOX_TRANSFORM(obj), (VisuGlExtBox*)0);
169 
170   VISU_UI_BOX_TRANSFORM(obj)->priv->dispose_has_run = TRUE;
171   /* Chain up to the parent class */
172   G_OBJECT_CLASS(visu_ui_box_transform_parent_class)->dispose(obj);
173 }
visu_ui_box_transform_finalize(GObject * obj)174 static void visu_ui_box_transform_finalize(GObject *obj)
175 {
176   g_return_if_fail(obj);
177 
178   DBG_fprintf(stderr, "Ui BoxTransform: finalize object %p.\n", (gpointer)obj);
179 
180   /* Chain up to the parent class */
181   G_OBJECT_CLASS(visu_ui_box_transform_parent_class)->finalize(obj);
182 
183   DBG_fprintf(stderr, " | freeing ... OK.\n");
184 }
visu_ui_box_transform_get_property(GObject * obj,guint property_id,GValue * value,GParamSpec * pspec)185 static void visu_ui_box_transform_get_property(GObject* obj, guint property_id,
186                                                GValue *value, GParamSpec *pspec)
187 {
188   VisuUiBoxTransform *self = VISU_UI_BOX_TRANSFORM(obj);
189 
190   DBG_fprintf(stderr, "Ui BoxTransform: get property '%s'.\n",
191 	      g_param_spec_get_name(pspec));
192   switch (property_id)
193     {
194     case POINTSET_PROP:
195       g_value_set_object(value, self->priv->pointset);
196       break;
197     case GL_BOX_PROP:
198       g_value_set_object(value, self->priv->glBox);
199       break;
200     default:
201       /* We don't have any other property... */
202       G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, property_id, pspec);
203       break;
204     }
205 }
visu_ui_box_transform_set_property(GObject * obj,guint property_id,const GValue * value,GParamSpec * pspec)206 static void visu_ui_box_transform_set_property(GObject* obj, guint property_id,
207                                                const GValue *value, GParamSpec *pspec)
208 {
209   VisuUiBoxTransform *self = VISU_UI_BOX_TRANSFORM(obj);
210 
211   DBG_fprintf(stderr, "Ui BoxTransform: set property '%s'.\n",
212 	      g_param_spec_get_name(pspec));
213   switch (property_id)
214     {
215     case POINTSET_PROP:
216       visu_ui_box_transform_bind(self, VISU_POINTSET(g_value_get_object(value)));
217       break;
218     case GL_BOX_PROP:
219       visu_ui_box_transform_bindGlExtBox(self, VISU_GL_EXT_BOX(g_value_get_object(value)));
220       break;
221     default:
222       /* We don't have any other property... */
223       G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, property_id, pspec);
224       break;
225     }
226 }
227 
setPeriodicityWarning(GBinding * bind _U_,const GValue * source,GValue * target,gpointer user_data _U_)228 static gboolean setPeriodicityWarning(GBinding *bind _U_, const GValue *source,
229                                       GValue *target, gpointer user_data _U_)
230 {
231   g_value_set_boolean(target, g_value_get_uint(source) == VISU_BOX_FREE);
232   return TRUE;
233 }
setPeriodicity(GBinding * bind _U_,const GValue * source,GValue * target,gpointer user_data _U_)234 static gboolean setPeriodicity(GBinding *bind _U_, const GValue *source,
235                                GValue *target, gpointer user_data _U_)
236 {
237   gchar *lbl;
238 
239   switch (g_value_get_uint(source))
240     {
241     case VISU_BOX_FREE:
242       lbl = g_markup_printf_escaped("<i>%s</i>", _("non periodic data"));
243       g_value_take_string(target, lbl);
244       return TRUE;
245     case VISU_BOX_WIRE_X:
246       g_value_set_static_string(target, _("(wire X)"));
247       return TRUE;
248     case VISU_BOX_WIRE_Y:
249       g_value_set_static_string(target, _("(wire Y)"));
250       return TRUE;
251     case VISU_BOX_WIRE_Z:
252       g_value_set_static_string(target, _("(wire Z)"));
253       return TRUE;
254     case VISU_BOX_SURFACE_XY:
255       g_value_set_static_string(target, _("(surface XY)"));
256       return TRUE;
257     case VISU_BOX_SURFACE_YZ:
258       g_value_set_static_string(target, _("(surface YZ)"));
259       return TRUE;
260     case VISU_BOX_SURFACE_ZX:
261       g_value_set_static_string(target, _("(surface ZX)"));
262       return TRUE;
263     case VISU_BOX_PERIODIC:
264       g_value_set_static_string(target, _("(periodic)"));
265       return TRUE;
266     default:
267       g_value_set_static_string(target, _("unknown periodicity"));
268       return TRUE;
269     }
270   return TRUE;
271 }
setSensitive(VisuUiBoxTransform * obj)272 static void setSensitive(VisuUiBoxTransform *obj)
273 {
274   gboolean expanded;
275   VisuBoxBoundaries bc;
276 
277   expanded = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(obj->priv->checkAllowExpand));
278   bc = (obj->priv->box) ? visu_box_getBoundary(obj->priv->box) : VISU_BOX_PERIODIC;
279   /* For the translations. */
280   gtk_widget_set_sensitive(obj->priv->checkInBox,
281                            !expanded && obj->priv->box && (bc != VISU_BOX_FREE));
282   gtk_widget_set_sensitive(obj->priv->checkAllowTranslations,
283                            !expanded && obj->priv->box && (bc != VISU_BOX_FREE));
284   gtk_widget_set_sensitive(obj->priv->spinTransXYZ[0],
285                            !expanded && obj->priv->box && (bc & TOOL_XYZ_MASK_X));
286   gtk_widget_set_sensitive(obj->priv->spinTransXYZ[1],
287                            !expanded && obj->priv->box && (bc & TOOL_XYZ_MASK_Y));
288   gtk_widget_set_sensitive(obj->priv->spinTransXYZ[2],
289                            !expanded && obj->priv->box && (bc & TOOL_XYZ_MASK_Z));
290   /* For the extensions. */
291   gtk_widget_set_sensitive(obj->priv->checkAllowExpand,
292                            obj->priv->box && (bc != VISU_BOX_FREE));
293   gtk_widget_set_sensitive(obj->priv->spinExpandXYZ[0],
294                            obj->priv->box && (bc & TOOL_XYZ_MASK_X));
295   gtk_widget_set_sensitive(obj->priv->spinExpandXYZ[1],
296                            obj->priv->box && (bc & TOOL_XYZ_MASK_Y));
297   gtk_widget_set_sensitive(obj->priv->spinExpandXYZ[2],
298                            obj->priv->box && (bc & TOOL_XYZ_MASK_Z));
299 }
visu_ui_box_transform_init(VisuUiBoxTransform * obj)300 static void visu_ui_box_transform_init(VisuUiBoxTransform *obj)
301 {
302   GtkWidget *hbox, *label, *vbox;
303   guint i;
304 #define X_LABEL _("dx:")
305 #define Y_LABEL _("dy:")
306 #define Z_LABEL _("dz:")
307   char *xyz[3];
308   const gchar **units;
309 #if GTK_MAJOR_VERSION == 2 && GTK_MINOR_VERSION < 12
310   GtkTooltips *tooltips;
311 
312   tooltips = gtk_tooltips_new ();
313 #endif
314 
315   DBG_fprintf(stderr, "Extension BoxTransform: initializing a new object (%p).\n",
316 	      (gpointer)obj);
317 
318   gtk_orientable_set_orientation(GTK_ORIENTABLE(obj), GTK_ORIENTATION_VERTICAL);
319 
320   obj->priv = visu_ui_box_transform_get_instance_private(obj);
321   obj->priv->dispose_has_run = FALSE;
322 
323   obj->priv->box = (VisuBox*)0;
324   obj->priv->glBox = (VisuGlExtBox*)0;
325 
326   /**************************/
327   /* The periodicity stuff. */
328   /**************************/
329   hbox = gtk_hbox_new(FALSE, 0);
330   gtk_box_pack_start(GTK_BOX(obj), hbox, FALSE, FALSE, 0);
331   label = gtk_label_new(_("<b>Periodic operations</b>"));
332   gtk_widget_set_name(label, "label_head");
333   gtk_label_set_xalign(GTK_LABEL(label), 0.);
334   gtk_label_set_use_markup(GTK_LABEL(label), TRUE);
335   gtk_box_pack_start(GTK_BOX(hbox), label, TRUE, TRUE, 0);
336 
337   obj->priv->labelBc = gtk_label_new("");
338   gtk_box_pack_end(GTK_BOX(hbox), obj->priv->labelBc, FALSE, FALSE, 0);
339   gtk_label_set_use_markup(GTK_LABEL(obj->priv->labelBc), TRUE);
340   obj->priv->warnBc = gtk_image_new_from_icon_name("dialog-warning",
341                                                    GTK_ICON_SIZE_MENU);
342   gtk_widget_set_no_show_all(obj->priv->warnBc, TRUE);
343   gtk_box_pack_end(GTK_BOX(hbox), obj->priv->warnBc, FALSE, FALSE, 0);
344 
345   vbox = gtk_vbox_new(FALSE, 2);
346   gtk_widget_set_margin_start(vbox, 15);
347   gtk_box_pack_start(GTK_BOX(obj), vbox, FALSE, FALSE, 0);
348 
349   /* The translations. */
350   hbox = gtk_hbox_new(FALSE, 0);
351   g_object_bind_property(obj, "pointset", hbox, "sensitive",
352                          G_BINDING_SYNC_CREATE);
353   gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
354   obj->priv->checkAllowTranslations =
355     gtk_check_button_new_with_mnemonic(_("_Translations"));
356   gtk_widget_set_tooltip_text(obj->priv->checkAllowTranslations,
357 			      _("Translations are given in box coordinates."));
358   gtk_box_pack_start(GTK_BOX(hbox),
359                      obj->priv->checkAllowTranslations, TRUE, TRUE, 0);
360   obj->priv->checkInBox =
361     gtk_check_button_new_with_mnemonic(_("_Put in the box"));
362   gtk_widget_set_tooltip_text(obj->priv->checkInBox,
363 			      _("Nodes are automatically translated back into the bounding box."));
364   gtk_box_pack_start(GTK_BOX(hbox),
365                      obj->priv->checkInBox, TRUE, TRUE, 0);
366 
367   hbox = gtk_hbox_new(FALSE, 2);
368   g_object_bind_property(obj, "pointset", hbox, "sensitive",
369                          G_BINDING_SYNC_CREATE);
370   gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
371 
372   xyz[0] = X_LABEL;
373   xyz[1] = Y_LABEL;
374   xyz[2] = Z_LABEL;
375   for (i = 0; i < 3; i++)
376     {
377       label = gtk_label_new(xyz[i]);
378       gtk_box_pack_start(GTK_BOX(hbox), label, TRUE, TRUE, 0);
379       gtk_label_set_xalign(GTK_LABEL(label), 1.);
380 
381       obj->priv->spinTransXYZ[i] = gtk_spin_button_new_with_range(-1, 1, 0.05);
382       gtk_spin_button_set_value(GTK_SPIN_BUTTON(obj->priv->spinTransXYZ[i]), 0.);
383       gtk_spin_button_set_numeric(GTK_SPIN_BUTTON(obj->priv->spinTransXYZ[i]), TRUE);
384       gtk_box_pack_start(GTK_BOX(hbox), obj->priv->spinTransXYZ[i], FALSE, FALSE, 0);
385     }
386 
387   /* The replication. */
388   hbox = gtk_hbox_new(FALSE, 2);
389   g_object_bind_property(obj, "pointset", hbox, "sensitive",
390                          G_BINDING_SYNC_CREATE);
391   gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
392   obj->priv->checkAllowExpand =
393     gtk_check_button_new_with_mnemonic(_("_Expand nodes"));
394   gtk_widget_set_tooltip_text(obj->priv->checkAllowExpand,
395 			      _("The size of the expansion is given in box coordinates."
396 				" Nodes are automatically translated back into the new"
397 				" defined area. The drawn bounding box is kept to the"
398 				" original size."));
399   gtk_box_pack_start(GTK_BOX(hbox), obj->priv->checkAllowExpand, TRUE, TRUE, 0);
400   g_signal_connect_object(G_OBJECT(obj->priv->checkAllowExpand), "toggled",
401                           G_CALLBACK(setSensitive), (gpointer)obj, G_CONNECT_SWAPPED);
402   /* The rendering parameters. */
403   label = gtk_label_new(_("param.:"));
404   gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
405   /* The stipple pattern. */
406   obj->priv->stippleExpandBox = visu_ui_stipple_combobox_new();
407   gtk_box_pack_start(GTK_BOX(hbox), obj->priv->stippleExpandBox, FALSE, FALSE, 0);
408   /* The color widget. */
409   obj->priv->colorExpandBox = visu_ui_color_combobox_new(TRUE);
410   visu_ui_color_combobox_setPrintValues(VISU_UI_COLOR_COMBOBOX(obj->priv->colorExpandBox), FALSE);
411   gtk_box_pack_start(GTK_BOX(hbox), obj->priv->colorExpandBox, FALSE, FALSE, 0);
412 
413   hbox = gtk_hbox_new(FALSE, 2);
414   g_object_bind_property(obj, "pointset", hbox, "sensitive",
415                          G_BINDING_SYNC_CREATE);
416   gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
417 
418   xyz[0] = X_LABEL;
419   xyz[1] = Y_LABEL;
420   xyz[2] = Z_LABEL;
421   for (i = 0; i < 3; i++)
422     {
423       label = gtk_label_new(xyz[i]);
424       gtk_box_pack_start(GTK_BOX(hbox), label, TRUE, TRUE, 0);
425       gtk_label_set_xalign(GTK_LABEL(label), 1.);
426 
427       obj->priv->spinExpandXYZ[i] = gtk_spin_button_new_with_range(0, 5, 0.05);
428       gtk_spin_button_set_numeric(GTK_SPIN_BUTTON(obj->priv->spinExpandXYZ[i]), TRUE);
429       gtk_box_pack_start(GTK_BOX(hbox), obj->priv->spinExpandXYZ[i], FALSE, FALSE, 0);
430     }
431 
432   /********************/
433   /* The units stuff. */
434   /********************/
435   hbox = gtk_hbox_new(FALSE, 0);
436   gtk_box_pack_start(GTK_BOX(obj), hbox, FALSE, FALSE, 0);
437   label = gtk_label_new(_("<b>Box settings</b>"));
438   gtk_widget_set_name(label, "label_head");
439   gtk_label_set_xalign(GTK_LABEL(label), 0.);
440   gtk_label_set_use_markup(GTK_LABEL(label), TRUE);
441   gtk_box_pack_start(GTK_BOX(hbox), label, TRUE, TRUE, 0);
442 
443   hbox = gtk_hbox_new(FALSE, 2);
444   gtk_widget_set_margin_start(hbox, 15);
445   g_object_bind_property(obj, "pointset", hbox, "sensitive",
446                          G_BINDING_SYNC_CREATE);
447   gtk_box_pack_start(GTK_BOX(obj), hbox, FALSE, FALSE, 0);
448   label = gtk_label_new(_("Set the unit of the file:"));
449   gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
450 
451   obj->priv->comboUnit = gtk_combo_box_text_new();
452   units = tool_physic_getUnitNames();
453   for (i = 0; units[i]; i++)
454     gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(obj->priv->comboUnit),
455                               (const gchar*)0, units[i]);
456   gtk_box_pack_start(GTK_BOX(hbox), obj->priv->comboUnit, FALSE, FALSE, 0);
457 
458   hbox = gtk_hbox_new(FALSE, 2);
459   gtk_widget_set_margin_start(hbox, 15);
460   g_object_bind_property(obj, "pointset", hbox, "sensitive",
461                          G_BINDING_SYNC_CREATE);
462   gtk_box_pack_start(GTK_BOX(obj), hbox, FALSE, FALSE, 0);
463   label = gtk_label_new(_("Hide nodes with respect to box:"));
464   gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
465 
466   obj->priv->comboHide = gtk_combo_box_text_new();
467   gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(obj->priv->comboHide),
468                             (const gchar*)0, _("never"));
469   gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(obj->priv->comboHide),
470                             (const gchar*)0, _("outside"));
471   gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(obj->priv->comboHide),
472                             (const gchar*)0, _("inside"));
473   gtk_box_pack_start(GTK_BOX(hbox), obj->priv->comboHide, FALSE, FALSE, 0);
474 
475   gtk_widget_show_all(GTK_WIDGET(obj));
476 }
477 
478 
479 /**
480  * visu_ui_box_transform_new:
481  *
482  * Creates a new #VisuUiBoxTransform to allow to setup box_transform rendering characteristics.
483  *
484  * Since: 3.8
485  *
486  * Returns: a pointer to the newly created widget.
487  */
visu_ui_box_transform_new()488 GtkWidget* visu_ui_box_transform_new()
489 {
490   DBG_fprintf(stderr,"Ui BoxTransform: new object.\n");
491 
492   return GTK_WIDGET(g_object_new(VISU_TYPE_UI_BOX_TRANSFORM,
493                                  "orientation", GTK_ORIENTATION_VERTICAL, NULL));
494 }
495 
fromExpandToSpin(GBinding * bind,const GValue * source,GValue * target,gpointer data)496 static gboolean fromExpandToSpin(GBinding *bind, const GValue *source,
497                                  GValue *target, gpointer data)
498 {
499   float *expand;
500   VisuUiBoxTransform *boxT = VISU_UI_BOX_TRANSFORM(data);
501 
502   expand = (float*)g_value_get_boxed(source);
503   if (g_binding_get_target(bind) == (gpointer)boxT->priv->spinExpandXYZ[0])
504     g_value_set_double(target, (double)expand[0]);
505   else if (g_binding_get_target(bind) == (gpointer)boxT->priv->spinExpandXYZ[1])
506     g_value_set_double(target, (double)expand[1]);
507   else if (g_binding_get_target(bind) == (gpointer)boxT->priv->spinExpandXYZ[2])
508     g_value_set_double(target, (double)expand[2]);
509 
510   return TRUE;
511 }
fromSpinToExpand(GBinding * bind,const GValue * source,GValue * target,gpointer data)512 static gboolean fromSpinToExpand(GBinding *bind, const GValue *source,
513                                  GValue *target, gpointer data)
514 {
515   float expand[3];
516   VisuUiBoxTransform *boxT = VISU_UI_BOX_TRANSFORM(data);
517 
518   visu_box_getExtension(VISU_BOX(g_binding_get_source(bind)), expand);
519   if (g_binding_get_target(bind) == (gpointer)boxT->priv->spinExpandXYZ[0])
520     expand[0] = (float)g_value_get_double(source);
521   else if (g_binding_get_target(bind) == (gpointer)boxT->priv->spinExpandXYZ[1])
522     expand[1] = (float)g_value_get_double(source);
523   else if (g_binding_get_target(bind) == (gpointer)boxT->priv->spinExpandXYZ[2])
524     expand[2] = (float)g_value_get_double(source);
525   g_value_set_boxed(target, expand);
526 
527   return TRUE;
528 }
_bindBox(VisuUiBoxTransform * box_transform,VisuBox * box,VisuPointset * model _U_)529 static void _bindBox(VisuUiBoxTransform *box_transform, VisuBox *box, VisuPointset *model _U_)
530 {
531   int i;
532 
533   if (box_transform->priv->box == box)
534     return;
535 
536   if (box_transform->priv->box)
537     {
538       g_object_unref(G_OBJECT(box_transform->priv->bind_allowExpand));
539       g_object_unref(G_OBJECT(box_transform->priv->bind_expand[0]));
540       g_object_unref(G_OBJECT(box_transform->priv->bind_expand[1]));
541       g_object_unref(G_OBJECT(box_transform->priv->bind_expand[2]));
542       g_object_unref(G_OBJECT(box_transform->priv->bind_bc));
543       g_object_unref(G_OBJECT(box_transform->priv->bind_bcWarn));
544       g_signal_handler_disconnect(G_OBJECT(box_transform->priv->box),
545                                   box_transform->priv->sig_boundary);
546       g_object_unref(G_OBJECT(box_transform->priv->bind_units));
547       g_object_unref(G_OBJECT(box_transform->priv->bind_hide));
548       g_object_unref(G_OBJECT(box_transform->priv->box));
549     }
550   box_transform->priv->box = box;
551   if (box)
552     {
553       g_object_ref(G_OBJECT(box));
554       box_transform->priv->bind_allowExpand =
555         g_object_bind_property(box, "use-expansion",
556                                box_transform->priv->checkAllowExpand, "active",
557                                G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
558       for (i = 0; i < 3; i++)
559         {
560           box_transform->priv->bind_expand[i] =
561             g_object_bind_property_full(box, "expansion",
562                                         box_transform->priv->spinExpandXYZ[i], "value",
563                                         G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE,
564                                         fromExpandToSpin, fromSpinToExpand,
565                                         box_transform, (GDestroyNotify)0);
566         }
567       box_transform->priv->sig_boundary =
568         g_signal_connect_object(G_OBJECT(box), "notify::boundary",
569                                 G_CALLBACK(setSensitive),
570                                 box_transform, G_CONNECT_SWAPPED);
571       setSensitive(box_transform);
572       box_transform->priv->bind_bc =
573         g_object_bind_property_full(box, "boundary", box_transform->priv->labelBc, "label",
574                                     G_BINDING_SYNC_CREATE, setPeriodicity, NULL,
575                                     (gpointer)0, (GDestroyNotify)0);
576       box_transform->priv->bind_bcWarn =
577       g_object_bind_property_full(box, "boundary", box_transform->priv->warnBc, "visible",
578                                   G_BINDING_SYNC_CREATE, setPeriodicityWarning, NULL,
579                                   (gpointer)0, (GDestroyNotify)0);
580       box_transform->priv->bind_units =
581       g_object_bind_property(box, "units", box_transform->priv->comboUnit, "active",
582                              G_BINDING_SYNC_CREATE | G_BINDING_BIDIRECTIONAL);
583       box_transform->priv->bind_hide =
584       g_object_bind_property(box, "hidding-scheme", box_transform->priv->comboHide, "active",
585                              G_BINDING_SYNC_CREATE | G_BINDING_BIDIRECTIONAL);
586     }
587 }
fromTransToSpin(GBinding * bind,const GValue * source,GValue * target,gpointer data)588 static gboolean fromTransToSpin(GBinding *bind, const GValue *source,
589                                  GValue *target, gpointer data)
590 {
591   gfloat *box;
592   VisuUiBoxTransform *boxT = VISU_UI_BOX_TRANSFORM(data);
593 
594   box = (gfloat*)g_value_get_boxed(source);
595   if (g_binding_get_target(bind) == (gpointer)boxT->priv->spinTransXYZ[0])
596     g_value_set_double(target, (double)box[0]);
597   else if (g_binding_get_target(bind) == (gpointer)boxT->priv->spinTransXYZ[1])
598     g_value_set_double(target, (double)box[1]);
599   else if (g_binding_get_target(bind) == (gpointer)boxT->priv->spinTransXYZ[2])
600     g_value_set_double(target, (double)box[2]);
601 
602   return TRUE;
603 }
fromSpinToTrans(GBinding * bind _U_,const GValue * source _U_,GValue * target,gpointer data)604 static gboolean fromSpinToTrans(GBinding *bind _U_, const GValue *source _U_,
605                                  GValue *target, gpointer data)
606 {
607   float trans[3];
608   VisuUiBoxTransformPrivate *priv = VISU_UI_BOX_TRANSFORM(data)->priv;
609 
610   trans[0] = gtk_spin_button_get_value(GTK_SPIN_BUTTON(priv->spinTransXYZ[0]));
611   trans[1] = gtk_spin_button_get_value(GTK_SPIN_BUTTON(priv->spinTransXYZ[1]));
612   trans[2] = gtk_spin_button_get_value(GTK_SPIN_BUTTON(priv->spinTransXYZ[2]));
613   g_value_set_boxed(target, trans);
614 
615   return TRUE;
616 }
617 /**
618  * visu_ui_box_transform_bind:
619  * @box_transform: a #VisuUiBoxTransform object.
620  * @model: (transfer none): a #VisuPointset object.
621  *
622  * Bind the properties of @model to be displayed by @box_transform.
623  *
624  * Since: 3.8
625  **/
visu_ui_box_transform_bind(VisuUiBoxTransform * box_transform,VisuPointset * model)626 void visu_ui_box_transform_bind(VisuUiBoxTransform *box_transform, VisuPointset *model)
627 {
628   guint i;
629 
630   g_return_if_fail(VISU_IS_UI_BOX_TRANSFORM(box_transform));
631 
632   if (box_transform->priv->pointset == model)
633     return;
634 
635   _bindBox(box_transform, (model) ? visu_boxed_getBox(VISU_BOXED(model)) : (VisuBox*)0, model);
636   if (box_transform->priv->pointset)
637     {
638       g_signal_handler_disconnect(G_OBJECT(box_transform->priv->pointset),
639                                   box_transform->priv->sig_box);
640       g_object_unref(G_OBJECT(box_transform->priv->bind_trans[0]));
641       g_object_unref(G_OBJECT(box_transform->priv->bind_trans[1]));
642       g_object_unref(G_OBJECT(box_transform->priv->bind_trans[2]));
643       g_object_unref(G_OBJECT(box_transform->priv->bind_allowTrans));
644       g_object_unref(G_OBJECT(box_transform->priv->bind_boxTrans));
645       g_object_unref(G_OBJECT(box_transform->priv->pointset));
646     }
647   box_transform->priv->pointset = model;
648   g_object_notify_by_pspec(G_OBJECT(box_transform), properties[POINTSET_PROP]);
649   if (model)
650     {
651       g_object_ref(G_OBJECT(model));
652       box_transform->priv->sig_box = g_signal_connect_object
653         (G_OBJECT(model), "setBox",
654          G_CALLBACK(_bindBox), box_transform, G_CONNECT_SWAPPED);
655       for (i = 0; i < 3; i++)
656         box_transform->priv->bind_trans[i] =
657           g_object_bind_property_full(model, "reduced-translation",
658                                       box_transform->priv->spinTransXYZ[i], "value",
659                                       G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE,
660                                       fromTransToSpin, fromSpinToTrans,
661                                       box_transform, (GDestroyNotify)0);
662       box_transform->priv->bind_allowTrans =
663           g_object_bind_property(model, "use-translation",
664                                  box_transform->priv->checkAllowTranslations, "active",
665                                  G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
666       box_transform->priv->bind_boxTrans =
667           g_object_bind_property(model, "in-the-box",
668                                  box_transform->priv->checkInBox, "active",
669                                  G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
670     }
671 }
672 /**
673  * visu_ui_box_transform_bindGlExtBox:
674  * @box_transform: a #VisuUiBoxTransform object.
675  * @model: (transfer none): a #VisuGlExtBox object.
676  *
677  * Bind the properties of @model to be displayed by @box_transform.
678  *
679  * Since: 3.8
680  **/
visu_ui_box_transform_bindGlExtBox(VisuUiBoxTransform * box_transform,VisuGlExtBox * model)681 void visu_ui_box_transform_bindGlExtBox(VisuUiBoxTransform *box_transform,
682                                         VisuGlExtBox *model)
683 {
684   g_return_if_fail(VISU_IS_UI_BOX_TRANSFORM(box_transform));
685 
686   if (box_transform->priv->glBox == model)
687     return;
688 
689   if (box_transform->priv->glBox)
690     {
691       g_object_unref(G_OBJECT(box_transform->priv->bind_stipple));
692       g_object_unref(G_OBJECT(box_transform->priv->bind_color));
693       g_object_unref(G_OBJECT(box_transform->priv->glBox));
694     }
695   box_transform->priv->glBox = model;
696   g_object_notify_by_pspec(G_OBJECT(box_transform), properties[GL_BOX_PROP]);
697   if (model)
698     {
699       g_object_ref(G_OBJECT(model));
700       box_transform->priv->bind_stipple =
701         g_object_bind_property(model, "expand-stipple",
702                                box_transform->priv->stippleExpandBox, "value",
703                                G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
704       box_transform->priv->bind_color =
705         g_object_bind_property(model, "side-color",
706                                box_transform->priv->colorExpandBox, "color",
707                                G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
708     }
709 }
710