1 /* EXTRAITS DE LA LICENCE 2 Copyright CEA, contributeurs : Luc BILLARD et Damien 3 CALISTE, laboratoire L_Sim, (2001-2005) 4 5 Adresse mèl : 6 BILLARD, non joignable par mèl ; 7 CALISTE, damien P caliste AT cea P fr. 8 9 Ce logiciel est un programme informatique servant à visualiser des 10 structures atomiques dans un rendu pseudo-3D. 11 12 Ce logiciel est régi par la licence CeCILL soumise au droit français et 13 respectant les principes de diffusion des logiciels libres. Vous pouvez 14 utiliser, modifier et/ou redistribuer ce programme sous les conditions 15 de la licence CeCILL telle que diffusée par le CEA, le CNRS et l'INRIA 16 sur le site "http://www.cecill.info". 17 18 Le fait que vous puissiez accéder à cet en-tête signifie que vous avez 19 pris connaissance de la licence CeCILL, et que vous en avez accepté les 20 termes (cf. le fichier Documentation/licence.fr.txt fourni avec ce logiciel). 21 */ 22 23 /* LICENCE SUM UP 24 Copyright CEA, contributors : Luc BILLARD et Damien 25 CALISTE, laboratoire L_Sim, (2001-2005) 26 27 E-mail address: 28 BILLARD, not reachable any more ; 29 CALISTE, damien P caliste AT cea P fr. 30 31 This software is a computer program whose purpose is to visualize atomic 32 configurations in 3D. 33 34 This software is governed by the CeCILL license under French law and 35 abiding by the rules of distribution of free software. You can use, 36 modify and/ or redistribute the software under the terms of the CeCILL 37 license as circulated by CEA, CNRS and INRIA at the following URL 38 "http://www.cecill.info". 39 40 The fact that you are presently reading this means that you have had 41 knowledge of the CeCILL license and that you accept its terms. You can 42 find a copy of this licence shipped with this software at Documentation/licence.en.txt. 43 */ 44 #include "panelGeometry.h" 45 #include "panelBrowser.h" 46 47 #include <support.h> 48 #include <visu_tools.h> 49 #include <visu_data.h> 50 #include <visu_basic.h> 51 #include <visu_gtk.h> 52 #include <gtk_main.h> 53 #include <gtk_renderingWindowWidget.h> 54 #include <extensions/box.h> 55 #include <extensions/geodiff.h> 56 #include <extensions/paths.h> 57 #include <openGLFunctions/objectList.h> 58 #include <coreTools/toolColor.h> 59 #include <coreTools/toolPhysic.h> 60 #include <extraFunctions/finder.h> 61 #include <extraGtkFunctions/gtk_colorComboBoxWidget.h> 62 #include <extraGtkFunctions/gtk_stippleComboBoxWidget.h> 63 #include <extraGtkFunctions/gtk_shadeComboBoxWidget.h> 64 #include <uiElements/ui_boxTransform.h> 65 66 /** 67 * SECTION: panelGeometry 68 * @short_description: This tab gathers the geometry operation on a 69 * #VisuData, like periodic translation, physical units, ... 70 * 71 * <para>Nothing tunable here.</para> 72 */ 73 74 /* Local objects. */ 75 static GtkWidget *panelGeometry; 76 static GtkWidget *togglePathSave; 77 static GtkWidget *hboxIOVisuPaths; 78 static GtkWidget *copyGeodiff, *pasteGeodiff, *addGeodiff; 79 80 /* Local variables. */ 81 static gboolean disableCallbacks; 82 static gboolean widgetsNotBuilt; 83 static gchar *exportPathFile = NULL; 84 85 #define NO_PATH _("<span size=\"small\"><i>No stored path</i></span>") 86 #define PATH _("<span size=\"small\">Path has %d step(s)</span>") 87 88 /* Local routines. */ 89 static GtkWidget *createInteriorBox(VisuGlNodeScene *scene); 90 91 /* Local callbacks. */ 92 static void onEnter(VisuUiPanel *visu_ui_panel, VisuUiRenderingWindow *window); 93 static void onDataFocused(GObject *obj, VisuData* visuData, gpointer data); 94 static void onPathSaveToggled(GtkToggleButton *toggle, gpointer data); 95 static void onSavePathClicked(GtkButton *bt, gpointer data); 96 static void onLoadPathClicked(GtkButton *bt, gpointer data); 97 static void onDirBrowsed(VisuUiMain *obj, VisuUiDirectoryType type, gpointer user); 98 static void onCopyDiff(GtkButton *button, gpointer data); 99 static void onPasteDiff(GtkToggleButton *button, gpointer data); 100 static void onAddDiff(GtkButton *button, gpointer data); 101 102 /** 103 * visu_ui_panel_geometry_init: (skip) 104 * @ui: a #VisuUiMain object. 105 * 106 * Should be used in the list declared in externalModules.h to be loaded by 107 * V_Sim on start-up. This routine will create the #VisuUiPanel where the box 108 * stuff can be tuned, such as the bounding box, its colour, and the actions linked 109 * to the periodicity (translation, dupplication...). 110 * 111 * Returns: a newly created #VisuUiPanel object. 112 */ 113 VisuUiPanel* visu_ui_panel_geometry_init(VisuUiMain *ui) 114 { 115 panelGeometry = visu_ui_panel_newWithIconFromPath("Panel_geometry", 116 _("Geometry operations"), 117 _("Geometry"), 118 "stock-geometry_20.png"); 119 if (!panelGeometry) 120 return (VisuUiPanel*)0; 121 122 visu_ui_panel_setDockable(VISU_UI_PANEL(panelGeometry), TRUE); 123 124 /* Create the widgets that are needed even without the GTK interface be built. */ 125 togglePathSave = gtk_toggle_button_new(); 126 pasteGeodiff = gtk_toggle_button_new_with_label(_("Paste and align")); 127 copyGeodiff = gtk_button_new_from_icon_name("edit-copy", GTK_ICON_SIZE_BUTTON); 128 addGeodiff = gtk_button_new_from_icon_name("list-add", GTK_ICON_SIZE_BUTTON); 129 130 /* Create the callbacks of all the sensitive widgets. */ 131 g_signal_connect(panelGeometry, "page-entered", 132 G_CALLBACK(onEnter), (gpointer)visu_ui_main_getRendering(ui)); 133 g_signal_connect(ui, "DirectoryChanged", 134 G_CALLBACK(onDirBrowsed), (gpointer)0); 135 g_signal_connect(ui, "DataFocused", 136 G_CALLBACK(onDataFocused), (gpointer)0); 137 138 /* Private parameters. */ 139 disableCallbacks = FALSE; 140 widgetsNotBuilt = TRUE; 141 142 return VISU_UI_PANEL(panelGeometry); 143 } 144 145 static gboolean fromPathLength(GBinding *binding _U_, const GValue *source_value, 146 GValue *target_value, gpointer user_data _U_) 147 { 148 gchar *text; 149 150 if (g_value_get_uint(source_value)) 151 text = g_strdup_printf(PATH, g_value_get_uint(source_value)); 152 else 153 text = g_strdup(NO_PATH); 154 g_value_take_string(target_value, text); 155 return TRUE; 156 } 157 158 static gboolean toShadeToggle(GBinding *binding _U_, const GValue *source_value, 159 GValue *target_value, gpointer user_data _U_) 160 { 161 g_value_set_boolean(target_value, (g_value_get_boxed(source_value) != (gpointer)0)); 162 return TRUE; 163 } 164 165 static gboolean fromShadeToggle(GBinding *binding _U_, const GValue *source_value, 166 GValue *target_value, gpointer user_data) 167 { 168 if (g_value_get_boolean(source_value)) 169 g_value_set_boxed(target_value, visu_ui_shade_combobox_getSelection(VISU_UI_SHADE_COMBOBOX(user_data))); 170 else 171 g_value_set_boxed(target_value, (gconstpointer)0); 172 return TRUE; 173 } 174 175 static gboolean toShadeCombo(GBinding *binding _U_, const GValue *source_value, 176 GValue *target_value, gpointer user_data _U_) 177 { 178 g_value_set_boxed(target_value, g_value_get_boxed(source_value)); 179 return TRUE; 180 } 181 182 static gboolean fromShadeCombo(GBinding *binding _U_, const GValue *source_value, 183 GValue *target_value, gpointer user_data) 184 { 185 if (!gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(user_data))) 186 return FALSE; 187 188 g_value_set_boxed(target_value, g_value_get_boxed(source_value)); 189 return TRUE; 190 } 191 192 static GtkWidget *createInteriorBox(VisuGlNodeScene *scene) 193 { 194 GtkWidget *vbox, *vbox2, *hbox, *bt, *wd, *checkDiff, *checkOrdering, *labelVisuPaths; 195 GtkWidget *checkVisuPaths, *hboxVisuPaths, *hboxVisuPaths2, *checkAdjust; 196 GtkWidget *label; 197 GtkWidget *boxTransform; 198 #define X_LABEL _("dx:") 199 #define Y_LABEL _("dy:") 200 #define Z_LABEL _("dz:") 201 #if GTK_MAJOR_VERSION == 2 && GTK_MINOR_VERSION < 12 202 GtkTooltips *tooltips; 203 204 tooltips = gtk_tooltips_new (); 205 #endif 206 207 vbox = gtk_vbox_new(FALSE, 0); 208 209 boxTransform = visu_ui_box_transform_new(); 210 g_object_bind_property(scene, "data", boxTransform, "pointset", G_BINDING_SYNC_CREATE); 211 visu_ui_box_transform_bindGlExtBox(VISU_UI_BOX_TRANSFORM(boxTransform), 212 visu_gl_node_scene_getBox(scene)); 213 gtk_box_pack_start(GTK_BOX(vbox), boxTransform, FALSE, FALSE, 0); 214 215 /************************/ 216 /* The multifile stuff. */ 217 /************************/ 218 label = gtk_label_new(_("<b>Multi file actions</b>")); 219 gtk_widget_set_margin_top(label, 15); 220 gtk_label_set_xalign(GTK_LABEL(label), 0.); 221 gtk_widget_set_name(label, "label_head"); 222 gtk_label_set_use_markup(GTK_LABEL(label), TRUE); 223 gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0); 224 225 vbox2 = gtk_vbox_new(FALSE, 2); 226 gtk_widget_set_margin_start(vbox2, 15); 227 gtk_box_pack_start(GTK_BOX(vbox), vbox2, FALSE, FALSE, 0); 228 229 checkAdjust = gtk_check_button_new_with_mnemonic(_("Automatic zoom _adjustment on file loading")); 230 g_object_bind_property(visu_gl_node_scene_getGlView(scene), "auto-adjust", 231 checkAdjust, "active", 232 G_BINDING_SYNC_CREATE | G_BINDING_BIDIRECTIONAL); 233 gtk_box_pack_start(GTK_BOX(vbox2), checkAdjust, FALSE, FALSE, 0); 234 235 hbox = gtk_hbox_new(FALSE, 0); 236 gtk_box_pack_start(GTK_BOX(vbox2), hbox, FALSE, FALSE, 0); 237 checkOrdering = gtk_check_button_new_with_mnemonic(_("with re_ordering")); 238 g_object_bind_property(scene, "reorder-reference", checkOrdering, "active", 239 G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE); 240 gtk_widget_set_tooltip_text(checkOrdering, 241 _("On load of a new file, reorder the nodes to" 242 " minimize displacements.")); 243 gtk_box_pack_end(GTK_BOX(hbox), checkOrdering, FALSE, FALSE, 0); 244 checkDiff = gtk_check_button_new_with_mnemonic(_("Show node _displacements")); 245 g_object_bind_property(scene, "geometry-differences", checkDiff, "active", 246 G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE); 247 gtk_widget_set_tooltip_text(checkDiff, 248 _("When a new file is loaded, draw arrows on nodes that" 249 " represent their displacements with respect to their" 250 " previous positions.")); 251 gtk_box_pack_start(GTK_BOX(hbox), checkDiff, TRUE, TRUE, 0); 252 253 hbox = gtk_hbox_new(FALSE, 2); 254 gtk_widget_set_margin_start(hbox, 25); 255 gtk_box_pack_start(GTK_BOX(vbox2), hbox, FALSE, FALSE, 0); 256 gtk_box_pack_start(GTK_BOX(hbox), gtk_label_new("Current diff"), FALSE, FALSE, 0); 257 g_object_bind_property(pasteGeodiff, "active", addGeodiff, "sensitive", G_BINDING_SYNC_CREATE); 258 g_signal_connect(G_OBJECT(addGeodiff), "clicked", 259 G_CALLBACK(onAddDiff), (gpointer)pasteGeodiff); 260 gtk_box_pack_end(GTK_BOX(hbox), addGeodiff, FALSE, FALSE, 0); 261 gtk_widget_set_sensitive(pasteGeodiff, FALSE); 262 gtk_box_pack_end(GTK_BOX(hbox), pasteGeodiff, FALSE, FALSE, 0); 263 gtk_button_set_image_position(GTK_BUTTON(pasteGeodiff), GTK_POS_LEFT); 264 g_signal_connect(G_OBJECT(pasteGeodiff), "clicked", 265 G_CALLBACK(onPasteDiff), (gpointer)copyGeodiff); 266 gtk_widget_set_sensitive(copyGeodiff, FALSE); 267 gtk_box_pack_end(GTK_BOX(hbox), copyGeodiff, FALSE, FALSE, 0); 268 gtk_button_set_image_position(GTK_BUTTON(copyGeodiff), GTK_POS_LEFT); 269 g_signal_connect(G_OBJECT(copyGeodiff), "clicked", 270 G_CALLBACK(onCopyDiff), (gpointer)0); 271 272 hbox = gtk_hbox_new(FALSE, 0); 273 gtk_box_pack_start(GTK_BOX(vbox2), hbox, FALSE, FALSE, 0); 274 checkVisuPaths = gtk_check_button_new_with_mnemonic(_("Use _paths")); 275 g_object_bind_property(scene, "path-active", checkVisuPaths, "active", 276 G_BINDING_SYNC_CREATE | G_BINDING_BIDIRECTIONAL); 277 gtk_widget_set_tooltip_text(checkVisuPaths, 278 _("Store differences between files and plot" 279 " them as lines.")); 280 gtk_box_pack_start(GTK_BOX(hbox), checkVisuPaths, TRUE, TRUE, 0); 281 hboxVisuPaths = gtk_hbox_new(FALSE, 2); 282 g_object_bind_property(checkVisuPaths, "active", hboxVisuPaths, "sensitive", 283 G_BINDING_SYNC_CREATE); 284 gtk_box_pack_start(GTK_BOX(hbox), hboxVisuPaths, FALSE, FALSE, 0); 285 labelVisuPaths = gtk_label_new(NO_PATH); 286 gtk_label_set_use_markup(GTK_LABEL(labelVisuPaths), TRUE); 287 g_object_bind_property_full(scene, "path-length", labelVisuPaths, "label", 288 G_BINDING_SYNC_CREATE, fromPathLength, 289 (GBindingTransformFunc)0, (gpointer)0, (GDestroyNotify)0); 290 gtk_box_pack_start(GTK_BOX(hboxVisuPaths), labelVisuPaths, FALSE, FALSE, 0); 291 gtk_widget_set_tooltip_text(togglePathSave, _("When toggled, store differences" 292 " between files as paths" 293 " through nodes..")); 294 gtk_container_add(GTK_CONTAINER(togglePathSave), 295 gtk_image_new_from_icon_name("media-record", 296 GTK_ICON_SIZE_MENU)); 297 g_object_bind_property(scene, "record-path", togglePathSave, "active", 298 G_BINDING_SYNC_CREATE | G_BINDING_BIDIRECTIONAL); 299 g_signal_connect(G_OBJECT(togglePathSave), "toggled", 300 G_CALLBACK(onPathSaveToggled), (gpointer)0); 301 gtk_box_pack_start(GTK_BOX(hboxVisuPaths), togglePathSave, FALSE, FALSE, 0); 302 bt = gtk_button_new(); 303 gtk_widget_set_tooltip_text(bt, _("Remove all stored paths.")); 304 gtk_container_add(GTK_CONTAINER(bt), 305 gtk_image_new_from_icon_name("edit-clear", 306 GTK_ICON_SIZE_MENU)); 307 g_signal_connect_swapped(G_OBJECT(bt), "clicked", 308 G_CALLBACK(visu_gl_node_scene_clearPaths), scene); 309 gtk_box_pack_start(GTK_BOX(hboxVisuPaths), bt, FALSE, FALSE, 0); 310 311 hboxVisuPaths2 = gtk_hbox_new(FALSE, 2); 312 g_object_bind_property(checkVisuPaths, "active", hboxVisuPaths2, "sensitive", 313 G_BINDING_SYNC_CREATE); 314 gtk_box_pack_start(GTK_BOX(vbox2), hboxVisuPaths2, FALSE, FALSE, 0); 315 316 bt = gtk_check_button_new_with_mnemonic(_("colourise with: ")); 317 gtk_widget_set_tooltip_text(bt, _("If energy information was present" 318 " when loading file, colourise the paths" 319 " with shading colours.")); 320 gtk_box_pack_start(GTK_BOX(hboxVisuPaths2), bt, TRUE, TRUE, 0); 321 wd = visu_ui_shade_combobox_new(FALSE, FALSE); 322 g_object_bind_property_full(scene, "path-shade", bt, "active", 323 G_BINDING_SYNC_CREATE | G_BINDING_BIDIRECTIONAL, 324 toShadeToggle, fromShadeToggle, wd, (GDestroyNotify)0); 325 g_object_bind_property_full(scene, "path-shade", wd, "shade", 326 G_BINDING_SYNC_CREATE | G_BINDING_BIDIRECTIONAL, 327 toShadeCombo, fromShadeCombo, bt, (GDestroyNotify)0); 328 g_object_bind_property(bt, "active", wd, "sensitive", G_BINDING_SYNC_CREATE); 329 gtk_box_pack_start(GTK_BOX(hboxVisuPaths2), wd, FALSE, FALSE, 0); 330 hboxIOVisuPaths = gtk_hbox_new(FALSE, 2); 331 /* gtk_widget_set_sensitive(hboxIOVisuPaths, FALSE); */ 332 gtk_box_pack_start(GTK_BOX(hboxVisuPaths2), hboxIOVisuPaths, FALSE, FALSE, 0); 333 bt = gtk_button_new(); 334 gtk_widget_set_tooltip_text(bt, _("Read a set of paths from a file and" 335 " add them to the current set.")); 336 gtk_container_add(GTK_CONTAINER(bt), 337 gtk_image_new_from_icon_name("document-open", 338 GTK_ICON_SIZE_MENU)); 339 g_signal_connect(G_OBJECT(bt), "clicked", 340 G_CALLBACK(onLoadPathClicked), scene); 341 gtk_box_pack_start(GTK_BOX(hboxIOVisuPaths), bt, FALSE, FALSE, 0); 342 bt = gtk_button_new(); 343 gtk_widget_set_tooltip_text(bt, _("Save the current set of paths" 344 " to an XML file.")); 345 gtk_container_add(GTK_CONTAINER(bt), 346 gtk_image_new_from_icon_name("document-save", 347 GTK_ICON_SIZE_MENU)); 348 g_object_bind_property(scene, "path-length", bt, "sensitive", G_BINDING_SYNC_CREATE); 349 g_signal_connect(G_OBJECT(bt), "clicked", 350 G_CALLBACK(onSavePathClicked), scene); 351 gtk_box_pack_start(GTK_BOX(hboxIOVisuPaths), bt, FALSE, FALSE, 0); 352 353 gtk_widget_show_all(vbox); 354 355 widgetsNotBuilt = FALSE; 356 357 return vbox; 358 } 359 static void updateSensitive(VisuData *dataObj) 360 { 361 VisuNodeValues *vals = dataObj ? visu_data_getNodeProperties(dataObj, VISU_DATA_DIFF_DEFAULT_ID) : (VisuNodeValues*)0; 362 gtk_widget_set_sensitive(copyGeodiff, (vals != (VisuNodeValues*)0)); 363 gtk_widget_set_sensitive(pasteGeodiff, g_object_get_data(G_OBJECT(copyGeodiff), 364 "stored-geodiff") != NULL); 365 } 366 367 /*************/ 368 /* Callbacks */ 369 /*************/ 370 static void onEnter(VisuUiPanel *visu_ui_panel _U_, VisuUiRenderingWindow *window) 371 { 372 VisuData *dataObj; 373 374 if (widgetsNotBuilt) 375 { 376 DBG_fprintf(stderr, "Panel Geometry: first build on enter.\n"); 377 gtk_container_set_border_width(GTK_CONTAINER(panelGeometry), 5); 378 gtk_container_add(GTK_CONTAINER(panelGeometry), 379 createInteriorBox(visu_ui_rendering_window_getGlScene(window))); 380 } 381 dataObj = visu_ui_panel_getData(VISU_UI_PANEL(panelGeometry)); 382 updateSensitive(dataObj); 383 } 384 static void onDataFocused(GObject *obj _U_, VisuData* visuData, gpointer data _U_) 385 { 386 DBG_fprintf(stderr, "Panel Geometry: Catch 'DataFocused' signal," 387 " update values.\n"); 388 if (visuData) 389 updateSensitive(visuData); 390 } 391 static guint highlightMatching(VisuGlExtMarks *marks, VisuData *dataObj, VisuNodeFinder *finder, 392 const gfloat delta[3]) 393 { 394 VisuNodeArrayIter iter; 395 GArray *ids; 396 gfloat xyz[3]; 397 gint id; 398 guint ln; 399 400 /* Remove previous marks. */ 401 visu_gl_ext_marks_unHighlight(marks); 402 403 /* Add matching nodes. */ 404 ids = g_array_new(FALSE, FALSE, sizeof(guint)); 405 if (dataObj) 406 { 407 visu_node_array_iter_new(VISU_NODE_ARRAY(dataObj), &iter); 408 for (visu_node_array_iterStart(VISU_NODE_ARRAY(dataObj), &iter); iter.node; 409 visu_node_array_iterNext(VISU_NODE_ARRAY(dataObj), &iter)) 410 { 411 visu_data_getNodePosition(dataObj, iter.node, xyz); 412 xyz[0] += delta[0]; 413 xyz[1] += delta[1]; 414 xyz[2] += delta[2]; 415 id = visu_node_finder_lookup(finder, xyz, 1.f); 416 if (id >= 0) 417 g_array_append_val(ids, id); 418 } 419 } 420 visu_gl_ext_marks_setHighlight(marks, ids, MARKS_STATUS_SET); 421 ln = ids->len; 422 g_array_unref(ids); 423 424 return ln; 425 } 426 static void onDragGeodiff(VisuInteractive *inter _U_, const gfloat delta[3], gpointer data) 427 { 428 VisuUiRenderingWindow *window; 429 VisuGlExtGeodiff *extGeodiff; 430 /* VisuGlExtMarks *marks; */ 431 /* VisuNodeFinder *finder; */ 432 /* VisuData *dataObj; */ 433 guint ln; 434 gchar *mess; 435 436 window = visu_ui_main_class_getDefaultRendering(); 437 extGeodiff = g_object_get_data(G_OBJECT(data), "ext-geodiff"); 438 439 /* marks = visu_ui_rendering_window_getMarks(window); */ 440 /* finder = g_object_get_data(G_OBJECT(data), "finder-geodiff"); */ 441 /* dataObj = visu_gl_ext_node_vectors_getData(VISU_GL_EXT_NODE_VECTORS(extGeodiff)); */ 442 /* ln = highlightMatching(marks, dataObj, finder, delta); */ 443 444 ln = 123; 445 mess = g_strdup_printf(_("Displacement field match %d node(s)."), ln); 446 visu_ui_rendering_window_popMessage(window); 447 visu_ui_rendering_window_pushMessage(window, mess); 448 g_free(mess); 449 450 visu_gl_ext_setTranslation(VISU_GL_EXT(extGeodiff), delta); 451 } 452 static void onDropGeodiff(VisuInteractive *inter _U_, const gfloat delta[3], gpointer data) 453 { 454 gfloat trans[3]; 455 gfloat delta0[3] = {0.f, 0.f, 0.f}; 456 VisuNodeValues *vect; 457 VisuPointset *dataObj; 458 459 visu_gl_ext_setTranslation(VISU_GL_EXT(data), delta0); 460 461 vect = visu_sourceable_getNodeModel(VISU_SOURCEABLE(data)); 462 dataObj = VISU_POINTSET(visu_node_values_getArray(vect)); 463 visu_pointset_getTranslation(dataObj, trans); 464 delta0[0] = delta[0] + trans[0]; 465 delta0[1] = delta[1] + trans[1]; 466 delta0[2] = delta[2] + trans[2]; 467 visu_pointset_setTranslation(dataObj, delta0, FALSE); 468 g_object_unref(dataObj); 469 } 470 static void onCopyDiff(GtkButton *button, gpointer data _U_) 471 { 472 VisuData *dataObj; 473 474 dataObj = visu_ui_panel_getData(VISU_UI_PANEL(panelGeometry)); 475 476 g_object_ref(dataObj); 477 g_object_set_data_full(G_OBJECT(button), "stored-geodiff", (gpointer)dataObj, 478 (GDestroyNotify)g_object_unref); 479 480 gtk_widget_set_sensitive(pasteGeodiff, TRUE); 481 } 482 static void onPasteDiff(GtkToggleButton *button, gpointer data) 483 { 484 VisuData *dataObj; 485 VisuNodeFinder *finder; 486 VisuGlExtGeodiff *extGeodiff; 487 VisuInteractive *inter; 488 VisuUiRenderingWindow *window; 489 VisuGlExtMarks *marks; 490 gfloat delta[3] = {0.f, 0.f, 0.f}; 491 492 dataObj = g_object_get_data(G_OBJECT(data), "stored-geodiff"); 493 g_return_if_fail(dataObj); 494 495 extGeodiff = g_object_get_data(G_OBJECT(button), "ext-geodiff"); 496 if (!extGeodiff) 497 { 498 extGeodiff = visu_gl_ext_geodiff_new(NULL); 499 visu_gl_ext_set_add 500 (VISU_GL_EXT_SET(visu_ui_rendering_window_getGlScene(visu_ui_main_class_getDefaultRendering())), 501 VISU_GL_EXT(extGeodiff)); 502 g_object_set_data_full(G_OBJECT(button), "ext-geodiff", extGeodiff, g_object_unref); 503 } 504 505 finder = g_object_get_data(G_OBJECT(button), "finder-geodiff"); 506 if (!finder) 507 { 508 finder = visu_node_finder_new(visu_ui_panel_getData(VISU_UI_PANEL(panelGeometry))); 509 g_object_set_data_full(G_OBJECT(button), "finder-geodiff", finder, g_object_unref); 510 } 511 512 inter = g_object_get_data(G_OBJECT(button), "inter-geodiff"); 513 if (!inter) 514 { 515 inter = visu_interactive_new(interactive_drag); 516 visu_interactive_setMessage(inter, _("Drag the displacement field.")); 517 g_object_set_data_full(G_OBJECT(button), "inter-geodiff", inter, g_object_unref); 518 g_signal_connect(G_OBJECT(inter), "move", 519 G_CALLBACK(onDragGeodiff), (gpointer)button); 520 g_signal_connect(G_OBJECT(inter), "stop-move", 521 G_CALLBACK(onDropGeodiff), (gpointer)extGeodiff); 522 } 523 524 window = visu_ui_main_class_getDefaultRendering(); 525 marks = visu_gl_node_scene_getMarks(visu_ui_rendering_window_getGlScene(window)); 526 if (gtk_toggle_button_get_active(button)) 527 { 528 VisuNodeValues *vals = visu_data_getNodeProperties(dataObj, VISU_DATA_DIFF_DEFAULT_ID); 529 visu_sourceable_setNodeModel(VISU_SOURCEABLE(extGeodiff), 530 VISU_NODE_VALUES(vals)); 531 visu_gl_ext_node_vectors_setNodeRenderer(VISU_GL_EXT_NODE_VECTORS(extGeodiff), 532 VISU_NODE_ARRAY_RENDERER(visu_gl_node_scene_getNodes(visu_ui_rendering_window_getGlScene(window)))); 533 visu_gl_ext_setActive(VISU_GL_EXT(extGeodiff), TRUE); 534 visu_ui_rendering_window_pushInteractive(window, inter); 535 536 highlightMatching(marks, dataObj, finder, delta); 537 } 538 else 539 { 540 visu_sourceable_setNodeModel(VISU_SOURCEABLE(extGeodiff), (VisuNodeValues*)0); 541 visu_gl_ext_setActive(VISU_GL_EXT(extGeodiff), FALSE); 542 visu_ui_rendering_window_popInteractive(window, inter); 543 544 highlightMatching(marks, (VisuData*)0, finder, delta); 545 } 546 } 547 static void onAddDiff(GtkButton *button _U_, gpointer data) 548 { 549 VisuGlExtNodeVectors *extGeodiff; 550 VisuNodeFinder *finder; 551 VisuDataDiff *geodiff; 552 553 extGeodiff = g_object_get_data(G_OBJECT(data), "ext-geodiff"); 554 geodiff = VISU_DATA_DIFF(visu_sourceable_getNodeModel(VISU_SOURCEABLE(extGeodiff))); 555 finder = g_object_get_data(G_OBJECT(data), "finder-geodiff"); 556 visu_data_diff_applyWithFinder(geodiff, finder, 1.f); 557 558 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(data), FALSE); 559 } 560 561 static void onPathSaveToggled(GtkToggleButton *toggle, gpointer data _U_) 562 { 563 if (gtk_toggle_button_get_active(toggle)) 564 visu_ui_panel_browser_setMessage(_("Recording paths"), GTK_MESSAGE_INFO); 565 else 566 visu_ui_panel_browser_setMessage((const gchar*)0, GTK_MESSAGE_INFO); 567 } 568 static void onDirBrowsed(VisuUiMain *obj _U_, VisuUiDirectoryType type, gpointer user _U_) 569 { 570 if (type == VISU_UI_DIR_BROWSER) 571 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(togglePathSave), FALSE); 572 } 573 static void onSavePathClicked(GtkButton *bt _U_, gpointer data) 574 { 575 GtkWidget *wd; 576 gint response; 577 GError *error; 578 gchar *base; 579 580 wd = gtk_file_chooser_dialog_new(_("Export current set of paths."), (GtkWindow*)0, 581 GTK_FILE_CHOOSER_ACTION_SAVE, 582 TOOL_ICON_CANCEL, GTK_RESPONSE_CANCEL, 583 TOOL_ICON_SAVE, GTK_RESPONSE_ACCEPT, 584 NULL); 585 if (!exportPathFile) 586 exportPathFile = g_build_filename(g_get_current_dir(), _("paths.xml"), NULL); 587 base = g_path_get_basename(exportPathFile); 588 gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(wd), base); 589 g_free(base); 590 #if GTK_MAJOR_VERSION > 2 || GTK_MINOR_VERSION > 7 591 gtk_file_chooser_set_do_overwrite_confirmation(GTK_FILE_CHOOSER(wd), TRUE); 592 #endif 593 do 594 { 595 response = gtk_dialog_run(GTK_DIALOG(wd)); 596 if (exportPathFile) 597 g_free(exportPathFile); 598 exportPathFile = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(wd)); 599 switch (response) 600 { 601 case GTK_RESPONSE_ACCEPT: 602 error = (GError*)0; 603 if (!visu_gl_node_scene_exportPathsToXML(VISU_GL_NODE_SCENE(data), 604 exportPathFile, &error)) 605 { 606 visu_ui_raiseWarning(_("Export current set of paths."), 607 error->message, GTK_WINDOW(wd)); 608 g_error_free(error); 609 response = GTK_RESPONSE_NONE; 610 } 611 break; 612 default: 613 response = GTK_RESPONSE_ACCEPT; 614 break; 615 } 616 } 617 while (response != GTK_RESPONSE_ACCEPT); 618 gtk_widget_destroy(wd); 619 } 620 static void onLoadPathClicked(GtkButton *bt _U_, gpointer data) 621 { 622 GtkWidget *wd; 623 gint response; 624 GError *error; 625 const gchar *directory; 626 627 wd = gtk_file_chooser_dialog_new(_("Load a set of paths."), (GtkWindow*)0, 628 GTK_FILE_CHOOSER_ACTION_OPEN, 629 TOOL_ICON_CANCEL, GTK_RESPONSE_CANCEL, 630 TOOL_ICON_OPEN, GTK_RESPONSE_ACCEPT, 631 NULL); 632 directory = visu_ui_main_getLastOpenDirectory(visu_ui_main_class_getCurrentPanel()); 633 if (directory) 634 gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(wd), directory); 635 do 636 { 637 response = gtk_dialog_run(GTK_DIALOG(wd)); 638 if (exportPathFile) 639 g_free(exportPathFile); 640 exportPathFile = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(wd)); 641 switch (response) 642 { 643 case GTK_RESPONSE_ACCEPT: 644 error = (GError*)0; 645 if (!visu_gl_node_scene_parsePathsFromXML(VISU_GL_NODE_SCENE(data), 646 exportPathFile, &error)) 647 { 648 visu_ui_raiseWarning(_("Load a set of paths."), 649 error->message, GTK_WINDOW(wd)); 650 g_error_free(error); 651 response = GTK_RESPONSE_NONE; 652 } 653 break; 654 default: 655 response = GTK_RESPONSE_ACCEPT; 656 break; 657 } 658 } 659 while (response != GTK_RESPONSE_ACCEPT); 660 gtk_widget_destroy(wd); 661 } 662