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
45 #include <gtk/gtk.h>
46 #include <gdk/gdkkeysyms.h>
47 #include <string.h>
48
49 #include "gtk_toolPanelWidget.h"
50
51 #include <support.h>
52 #include <visu_basic.h>
53 #include <visu_tools.h>
54 #include <visu_configFile.h>
55 #include <gtk_main.h>
56 #include <visu_gtk.h>
57 #include <gtk_renderingWindowWidget.h>
58
59 /**
60 * SECTION:gtk_toolPanelWidget
61 * @short_description: Defines a widget that hold a set of V_Sim panel.
62 *
63 * <para>This widget is a complex association of a #GtkComboBox and a
64 * #GtkNotebook with V_Sim panels. It can have its own window or be
65 * attached into the main command panel.</para>
66 *
67 * <para>This widget also has a built-in menu to exchange V_Sim panel
68 * between different instances of a #VisuUiPanel. A #VisuUiPanel is
69 * refered by its name and has a position and a size. These values can
70 * be stored in the parameter files.</para>
71 */
72
73 enum {
74 NOTEBOOK_ENTERED,
75 LAST_SIGNAL
76 };
77
78 enum
79 {
80 TOOL_LIST_ICON, /* The icon shown */
81 TOOL_LIST_STOCK, /* or the stock icon shown */
82 TOOL_LIST_NAME, /* The label shown */
83 TOOL_LIST_POINTER_TO_DATA, /* Pointer to the tool panel. */
84 TOOL_LIST_N_COLUMNS
85 };
86
87 /**
88 * VisuUiDockWindow:
89 *
90 * Short name for the structure of containers of #VisuUiPanel.
91 */
92 struct _VisuUiDockWindow
93 {
94 guint refCount;
95
96 /* The name of the dock window. */
97 gchar *name;
98 /* The window holding the notebook of tools.
99 Maybe NULL if the VisuUiDockWindow is integrated
100 in something else.*/
101 GtkWidget *window;
102 /* The top container widget for the VisuUiDockWindow. */
103 GtkWidget *vbox;
104 /* The header line with the combobox. */
105 GtkWidget *hbox;
106 /* The notebook holding the tools. */
107 GtkWidget *notebook;
108 /* The combo list of accessible tool panels. */
109 GtkWidget *combo;
110 /* The list store associated to the combo. */
111 GtkListStore *list;
112 /* Handler on the change signals. */
113 gulong notebookChanged, comboChanged;
114 /* TRUE if the dock is visible. */
115 gboolean show;
116 };
117
118 /**
119 * VisuUiPanel
120 *
121 * Short form for a #VisuUiPanel_struct structure.
122 */
123 struct _VisuUiPanel
124 {
125 GtkFrame alignment;
126
127 /* Set if the visu_ui_panel can be separate from the main
128 window and be hosted in its own window. */
129 gboolean dockable;
130
131 /* An id, untranslated, used to identify the panel
132 in a configuration file. It should not contain
133 any space character. */
134 gchar *id;
135
136 /* Value that is shown in the combo box, which
137 is a "long" label. */
138 gchar *comboLabel;
139
140 /* Value that appears in te tab of the
141 GtkNoteBook */
142 gchar *tabLabel;
143
144 /* An image representing the tool. */
145 GtkWidget *icon;
146 gchar *stockIcon;
147
148 /* The hosting container. */
149 VisuUiDockWindow *container;
150
151 /* Internal widgets. */
152 GtkWidget *headerWidget;
153
154 /* Memory gestion. */
155 gboolean dispose_has_run;
156 };
157 /**
158 * VisuUiPanelClass
159 *
160 * Opaque structure.
161 */
162 struct _VisuUiPanelClass
163 {
164 GtkFrameClass parent_class;
165
166 void (*visu_ui_panel) (VisuUiPanel *tool);
167
168 /* This list holds pointer on active hosting windows. */
169 GList* hostingWindows;
170
171 /* This list holds tools than have no containers. */
172 GList* orphanVisuUiPanel;
173
174 /* This is the VisuUiDockWindow of the command panel. */
175 VisuUiDockWindow *commandPanel;
176
177 /* Give a quick access from id of tool panels to pointers. */
178 GHashTable *allVisuUiPanels;
179
180 /* Pointer on current handled VisuData.
181 No reference is hold. */
182 VisuData *dataObj;
183 VisuGlView *viewObj;
184
185 /* If TRUE, the labels are always shown in the tabs. */
186 gboolean showHeader;
187 };
188
189 /**
190 * visu_ui_panel_get_type
191 *
192 * #GType are unique numbers to identify objects.
193 *
194 * Returns: the #GType associated with #VisuUiPanel objects.
195 */
196 G_DEFINE_TYPE(VisuUiPanel, visu_ui_panel, GTK_TYPE_FRAME)
197
198 #define MAIN_PANEL_NAME _("Command panel")
199
200 #define FLAG_PARAMETER_TABVIEW_CONFIG "config_subPanelTabView"
201 #define DESC_PARAMETER_TABVIEW_CONFIG "See or not the labels on tabs ; boolean 0 or 1"
202 #define PARAMETER_CONFIG_TABVIEW_DEFAULT FALSE
203 static gboolean _tabView = PARAMETER_CONFIG_TABVIEW_DEFAULT;
204
205 /* Local variables. */
206 static VisuUiPanelClass *local_class = NULL;
207 static GQuark CURRENT_TOOLPANEL_POINTER;
208 static guint visu_ui_panel_signals[LAST_SIGNAL] = { 0 };
209
210 /* Local methods. */
211 static void visu_ui_panel_class_init(VisuUiPanelClass *klass);
212 static void visu_ui_panel_init(VisuUiPanel *visu_ui_panel);
213 static void visu_ui_panel_dispose(GObject *visu_ui_panel);
214 static void visu_ui_panel_finalize(GObject *obj);
215 static GtkWidget* buildDockMenu(VisuUiPanel *visu_ui_panel, GList *listOfDocks);
216 static GtkWidget* buildMainMenu(VisuUiDockWindow *window);
217 static VisuUiDockWindow* dock_window_new(gchar *name, gboolean withWindow);
218 static VisuUiDockWindow* dock_window_ref(VisuUiDockWindow *dock);
219 static void dock_window_unref(VisuUiDockWindow *dock);
220 static void exportParameters(GString *data, VisuData* dataObj);
221
222 /* Local callbacks. */
223 static gboolean onHomePressed(GtkWidget *widget _U_, GdkEventKey *event,
224 gpointer data);
225 static void onDockButtonClicked(VisuUiPanel *visu_ui_panel, gpointer data);
226 static void onMainButtonClicked(GtkButton *button, gpointer data);
227 static void onRaiseButtonClicked(GtkButton *button, gpointer data);
228 static void onDockMenuClicked(GtkMenuItem *menuitem, gpointer user_data);
229 static void onDockMenuNewClicked(GtkMenuItem *menuitem, gpointer user_data);
230 static void onDockMenuHideClicked(GtkMenuItem *menuitem, gpointer user_data);
231 static void onDockMenuSelected(GtkMenuShell *menushell, gpointer user_data);
232 static void onMainMenuClicked(GtkMenuItem *menuitem, gpointer user_data);
233 static void onMainMenuShowClicked(GtkMenuItem *menuitem, gpointer user_data);
234 static void onMainMenuHideClicked(GtkMenuItem *menuitem, gpointer user_data);
235 static void onMainMenuSelected(GtkMenuShell *menushell, gpointer user_data);
236 static gboolean onKillVisuUiDockWindowEvent(GtkWidget *widget, GdkEvent *event, gpointer user_data);
237 static void onPageChanged(GtkNotebook *book, GtkWidget *child,
238 gint num, gpointer data);
239 static void onComboChanged(GtkComboBox *combo, gpointer data);
240 static void onEntryTabview(VisuConfigFile *obj, VisuConfigFileEntry *entry, VisuUiPanelClass *klass);
241
visu_ui_panel_class_init(VisuUiPanelClass * klass)242 static void visu_ui_panel_class_init(VisuUiPanelClass *klass)
243 {
244 DBG_fprintf(stderr, "Gtk VisuUiPanel : creating the class of the widget.\n");
245
246 local_class = klass;
247
248 DBG_fprintf(stderr, " - adding new signals ;\n");
249 /**
250 * VisuUiPanel::page-entered:
251 * @panel: the #VisuUiPanel that emits the signal.
252 *
253 * This signal is emitted when a page of the #GtkNotebook with all
254 * the V_Sim panels is entered.
255 *
256 * Since: 3.3
257 */
258 visu_ui_panel_signals[NOTEBOOK_ENTERED] =
259 g_signal_new ("page-entered",
260 G_TYPE_FROM_CLASS(klass),
261 G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
262 G_STRUCT_OFFSET(VisuUiPanelClass, visu_ui_panel),
263 NULL,
264 NULL,
265 g_cclosure_marshal_VOID__VOID,
266 G_TYPE_NONE, 0, NULL);
267
268 DBG_fprintf(stderr, " - initializing the list of hosting windows.\n");
269 klass->hostingWindows = (GList*)0;
270 klass->orphanVisuUiPanel = (GList*)0;
271 klass->commandPanel = (VisuUiDockWindow*)0;
272 klass->dataObj = (VisuData*)0;
273 klass->viewObj = (VisuGlView*)0;
274 klass->allVisuUiPanels = g_hash_table_new_full(g_str_hash, g_str_equal,
275 NULL, NULL);
276 klass->showHeader = PARAMETER_CONFIG_TABVIEW_DEFAULT;
277
278 visu_config_file_addBooleanEntry(VISU_CONFIG_FILE_PARAMETER,
279 FLAG_PARAMETER_TABVIEW_CONFIG,
280 DESC_PARAMETER_TABVIEW_CONFIG,
281 &_tabView, FALSE);
282 g_signal_connect(VISU_CONFIG_FILE_PARAMETER, "parsed::" FLAG_PARAMETER_TABVIEW_CONFIG,
283 G_CALLBACK(onEntryTabview), klass);
284 visu_config_file_addExportFunction(VISU_CONFIG_FILE_PARAMETER,
285 exportParameters);
286
287 CURRENT_TOOLPANEL_POINTER =
288 g_quark_from_static_string("VisuUiPanel_currentVisuUiPanel");
289
290 /* Set the pixmap directory for the Glade stuff. */
291 add_pixmap_directory(visu_basic_getPixmapsDir());
292
293 /* Connect freeing methods. */
294 G_OBJECT_CLASS(klass)->dispose = visu_ui_panel_dispose;
295 G_OBJECT_CLASS(klass)->finalize = visu_ui_panel_finalize;
296 }
297
298 /* This method can be called several times.
299 It should unref all of its reference to
300 GObjects. */
visu_ui_panel_dispose(GObject * visu_ui_panel)301 static void visu_ui_panel_dispose(GObject *visu_ui_panel)
302 {
303 DBG_fprintf(stderr, "Gtk VisuUiPanel : dispose object %p (%s).\n",
304 (gpointer)visu_ui_panel, VISU_UI_PANEL(visu_ui_panel)->id);
305
306 if (VISU_UI_PANEL(visu_ui_panel)->dispose_has_run)
307 return;
308
309 VISU_UI_PANEL(visu_ui_panel)->dispose_has_run = TRUE;
310 /* Chain up to the parent class */
311 G_OBJECT_CLASS(visu_ui_panel_parent_class)->dispose(visu_ui_panel);
312 }
313 /* This method is called once only. */
visu_ui_panel_finalize(GObject * obj)314 static void visu_ui_panel_finalize(GObject *obj)
315 {
316 VisuUiPanel *visu_ui_panel;
317
318 g_return_if_fail(obj);
319
320 DBG_fprintf(stderr, "Gtk VisuUiPanel : finalize object %p.\n", (gpointer)obj);
321
322 visu_ui_panel = VISU_UI_PANEL(obj);
323
324 /* Remove me from the list of visu_ui_panels. */
325 g_hash_table_remove(local_class->allVisuUiPanels, visu_ui_panel->id);
326
327 if (visu_ui_panel->comboLabel)
328 g_free(visu_ui_panel->comboLabel);
329 if (visu_ui_panel->tabLabel)
330 g_free(visu_ui_panel->tabLabel);
331 if (visu_ui_panel->id)
332 g_free(visu_ui_panel->id);
333 if (visu_ui_panel->stockIcon)
334 g_free(visu_ui_panel->stockIcon);
335 if (visu_ui_panel->headerWidget)
336 g_object_unref(visu_ui_panel->headerWidget);
337
338 /* Chain up to the parent class */
339 G_OBJECT_CLASS(visu_ui_panel_parent_class)->finalize(obj);
340
341 DBG_fprintf(stderr, "Gtk VisuUiPanel : freeing ... OK.\n");
342 }
343
344
visu_ui_panel_init(VisuUiPanel * visu_ui_panel)345 static void visu_ui_panel_init(VisuUiPanel *visu_ui_panel)
346 {
347 DBG_fprintf(stderr, "Gtk VisuUiPanel : initializing new object (%p).\n",
348 (gpointer)visu_ui_panel);
349
350 visu_ui_panel->dispose_has_run = FALSE;
351
352 visu_ui_panel->dockable = FALSE;
353 visu_ui_panel->id = (gchar*)0;
354 visu_ui_panel->comboLabel = (gchar*)0;
355 visu_ui_panel->tabLabel = (gchar*)0;
356 visu_ui_panel->icon = (GtkWidget*)0;
357 visu_ui_panel->stockIcon = (gchar*)0;
358 visu_ui_panel->headerWidget = (GtkWidget*)0;
359 visu_ui_panel->container = (VisuUiDockWindow*)0;
360
361 gtk_frame_set_shadow_type(GTK_FRAME(visu_ui_panel), GTK_SHADOW_NONE);
362 }
363
364 /**
365 * visu_ui_panel_new:
366 * @id: (type filename): a string without space and non internationalised ;
367 * @name: a string in UTF-8 that can be internationalised ;
368 * @tabName: a shorter name than @name, in UTF-8 that can be
369 * internationalised.
370 *
371 * Create a new #VisuUiPanel with the given @id, displaying @name in the
372 * combo box of a #VisuUiDockWindow and @tabName in the tab of the page
373 * notebook.
374 *
375 * Returns: a newly created widget.
376 */
visu_ui_panel_new(gchar * id,gchar * name,gchar * tabName)377 GtkWidget* visu_ui_panel_new(gchar *id, gchar* name, gchar *tabName)
378 {
379 VisuUiPanel *visu_ui_panel;
380
381 g_return_val_if_fail(id && id[0] && !strstr(id, " "), (GtkWidget*)0);
382 g_return_val_if_fail(name && name[0], (GtkWidget*)0);
383 g_return_val_if_fail(tabName && tabName[0], (GtkWidget*)0);
384
385 visu_ui_panel = VISU_UI_PANEL(g_object_new(visu_ui_panel_get_type(), NULL));
386
387 DBG_fprintf(stderr, "Gtk VisuUiPanel : creating new object '%s' : %p.\n",
388 name, (gpointer)visu_ui_panel);
389
390 visu_ui_panel->id = g_strdup(id);
391 visu_ui_panel->comboLabel = g_strdup(name);
392 visu_ui_panel->tabLabel = g_strdup(tabName);
393
394 /* Add me to the list of visu_ui_panels. */
395 g_hash_table_insert(local_class->allVisuUiPanels, visu_ui_panel->id,
396 (gpointer)visu_ui_panel);
397
398 return GTK_WIDGET(visu_ui_panel);
399 }
400 /**
401 * visu_ui_panel_newWithIconFromPath:
402 * @id: a string without space and non internationalised ;
403 * @name: a string in UTF-8 that can be internationalised ;
404 * @tabName: a shorter name than @name, in UTF-8 that can be
405 * internationalised ;
406 * @iconPath: a path to an icon (should be 20x20).
407 *
408 * Create a new #VisuUiPanel with the given @id, displaying @name in the
409 * combo box of a #VisuUiDockWindow and @tabName in the tab of the page
410 * notebook. The displayed icon will be read from the @iconPath.
411 *
412 * Returns: (transfer full): a newly created widget.
413 */
visu_ui_panel_newWithIconFromPath(gchar * id,gchar * name,gchar * tabName,const gchar * iconPath)414 GtkWidget* visu_ui_panel_newWithIconFromPath(gchar *id, gchar* name, gchar *tabName,
415 const gchar* iconPath)
416 {
417 VisuUiPanel *visu_ui_panel;
418
419 visu_ui_panel = VISU_UI_PANEL(visu_ui_panel_new(id, name, tabName));
420 if (!visu_ui_panel)
421 return (GtkWidget*)0;
422
423 /* TODO : mettre un truc qui limite la taille des images
424 effichées à 20x20 par exemple en chargeant de GdkImage et en
425 regardant sa taille. */
426 visu_ui_panel->icon = create_pixmap((GtkWidget*)0, iconPath);
427 return GTK_WIDGET(visu_ui_panel);
428 }
429 /**
430 * visu_ui_panel_newWithIconFromIconName:
431 * @id: a string without space and non internationalised ;
432 * @name: a string in UTF-8 that can be internationalised ;
433 * @tabName: a shorter name than @name, in UTF-8 that can be
434 * internationalised ;
435 * @icon: the name of a stock icon.
436 *
437 * Create a new #VisuUiPanel with the given @id, displaying @name in the
438 * combo box of a #VisuUiDockWindow and @tabName in the tab of the page
439 * notebook. The displayed icon will be taken from the @stock.
440 *
441 * Returns: (transfer full): a newly created widget.
442 */
visu_ui_panel_newWithIconFromIconName(gchar * id,gchar * name,gchar * tabName,const gchar * icon)443 GtkWidget* visu_ui_panel_newWithIconFromIconName(gchar *id, gchar* name, gchar *tabName,
444 const gchar* icon)
445 {
446 VisuUiPanel *visu_ui_panel;
447
448 visu_ui_panel = VISU_UI_PANEL(visu_ui_panel_new(id, name, tabName));
449 if (!visu_ui_panel)
450 return (GtkWidget*)0;
451
452 visu_ui_panel->stockIcon = g_strdup(icon);
453 visu_ui_panel->icon = gtk_image_new_from_icon_name(icon, GTK_ICON_SIZE_MENU);
454 return GTK_WIDGET(visu_ui_panel);
455 }
456 /**
457 * visu_ui_panel_getHeaderWidget:
458 * @visu_ui_panel: a #VisuUiPanel.
459 *
460 * The #VisuUiPanel should be used in a page of a #GtkNotebook. This
461 * routine is used to get the widget that should be used in the
462 * tab. This widget is a container with an icon and a label.
463 *
464 * Returns: (transfer none): a container widget that should be put in the tab of a
465 * #GtkNotebook.
466 */
visu_ui_panel_getHeaderWidget(VisuUiPanel * visu_ui_panel)467 GtkWidget* visu_ui_panel_getHeaderWidget(VisuUiPanel *visu_ui_panel)
468 {
469 GtkWidget *label, *wd, *image;
470 #if GTK_MAJOR_VERSION == 2 && GTK_MINOR_VERSION < 12
471 GtkTooltips *tooltips;
472 #endif
473
474 g_return_val_if_fail(visu_ui_panel, (GtkWidget*)0);
475
476 /* If the header has never been created,
477 we do it now. */
478 if (!visu_ui_panel->headerWidget)
479 {
480 #if GTK_MAJOR_VERSION == 2 && GTK_MINOR_VERSION < 12
481 tooltips = gtk_tooltips_new ();
482 #endif
483
484 visu_ui_panel->headerWidget = gtk_hbox_new(FALSE, 0);
485 wd = gtk_event_box_new();
486 gtk_event_box_set_visible_window(GTK_EVENT_BOX(wd), FALSE);
487 gtk_box_pack_start(GTK_BOX(visu_ui_panel->headerWidget),
488 wd, FALSE, FALSE, 0);
489 gtk_widget_set_tooltip_text(wd, visu_ui_panel->comboLabel);
490 if (visu_ui_panel->icon)
491 gtk_container_add(GTK_CONTAINER(wd), visu_ui_panel->icon);
492 else
493 gtk_container_add(GTK_CONTAINER(wd),
494 gtk_image_new_from_icon_name("image-missing",
495 GTK_ICON_SIZE_MENU));
496 label = gtk_label_new(visu_ui_panel->tabLabel);
497 gtk_widget_set_margin_start(label, 2);
498 gtk_box_pack_start(GTK_BOX(visu_ui_panel->headerWidget), label, FALSE, FALSE, 0);
499
500 if (visu_ui_panel->dockable)
501 {
502 wd = gtk_button_new();
503 gtk_widget_set_no_show_all(wd, TRUE);
504 gtk_box_pack_start(GTK_BOX(visu_ui_panel->headerWidget), wd, TRUE, TRUE, 0);
505 gtk_button_set_relief(GTK_BUTTON(wd), GTK_RELIEF_NONE);
506 g_signal_connect_swapped(G_OBJECT(wd), "clicked",
507 G_CALLBACK(onDockButtonClicked), (gpointer)visu_ui_panel);
508 image = create_pixmap((GtkWidget*)0, "stock-menu-detach.png");
509 gtk_container_add(GTK_CONTAINER(wd), image);
510
511 gtk_widget_set_tooltip_text(wd,
512 _("Manage this subpanel: attach/detach"
513 " or hide it."));
514 gtk_widget_show(image);
515 }
516
517 g_object_ref(G_OBJECT(visu_ui_panel->headerWidget));
518 gtk_widget_show_all(visu_ui_panel->headerWidget);
519 gtk_widget_hide(label);
520 }
521
522 return visu_ui_panel->headerWidget;
523 }
524 /**
525 * visu_ui_panel_getLabel:
526 * @visu_ui_panel: a #VisuUiPanel.
527 *
528 * The #VisuUiPanel has two label, a short one, used in the tab of a
529 * #GtkNotebook and one longer. This routine gets the longer.
530 *
531 * Returns: an UTF-8 internationalised name (property of V_Sim, should
532 * not be freed).
533 */
visu_ui_panel_getLabel(VisuUiPanel * visu_ui_panel)534 const gchar* visu_ui_panel_getLabel(VisuUiPanel *visu_ui_panel)
535 {
536 g_return_val_if_fail(visu_ui_panel, (gchar*)0);
537
538 return visu_ui_panel->comboLabel;
539 }
540 /**
541 * visu_ui_panel_getId:
542 * @visu_ui_panel: a #VisuUiPanel.
543 *
544 * The #VisuUiPanel can be identifyed by an id (a string without space,
545 * usually using ASCII characters only).
546 *
547 * Returns: a constant string identifying this #VisuUiPanel.
548 */
visu_ui_panel_getId(VisuUiPanel * visu_ui_panel)549 const gchar* visu_ui_panel_getId(VisuUiPanel *visu_ui_panel)
550 {
551 g_return_val_if_fail(visu_ui_panel, (gchar*)0);
552
553 return visu_ui_panel->id;
554 }
555 /**
556 * visu_ui_panel_setDockable:
557 * @visu_ui_panel: a #VisuUiPanel ;
558 * @value: a boolean.
559 *
560 * A #VisuUiPanel can be moved between different #VisuUiDockWindow or
561 * not. This ability is controlled by the dockable flag. Change it
562 * with this method. If @visu_ui_panel is set dockable, then, it can be
563 * hidden or moved to another or a new #VisuUiDockWindow with the pop-up
564 * memu that is triggered by a small button in the header widget (see
565 * visu_ui_panel_getHeaderWidget()).
566 */
visu_ui_panel_setDockable(VisuUiPanel * visu_ui_panel,gboolean value)567 void visu_ui_panel_setDockable(VisuUiPanel *visu_ui_panel, gboolean value)
568 {
569 g_return_if_fail(visu_ui_panel);
570
571 visu_ui_panel->dockable = value;
572 }
573 /**
574 * visu_ui_panel_getContainer:
575 * @visu_ui_panel: a #VisuUiPanel.
576 *
577 * Return the #VisuUiDockWindow that the given @visu_ui_panel is attached to or
578 * NULL if the @visu_ui_panel is currently dettached.
579 *
580 * Returns: a #VisuUiDockWindow object.
581 */
visu_ui_panel_getContainer(VisuUiPanel * visu_ui_panel)582 VisuUiDockWindow* visu_ui_panel_getContainer(VisuUiPanel *visu_ui_panel)
583 {
584 g_return_val_if_fail(VISU_IS_UI_PANEL(visu_ui_panel), (VisuUiDockWindow*)0);
585
586 return visu_ui_panel->container;
587 }
588 /**
589 * visu_ui_panel_getContainerWindow:
590 * @visu_ui_panel: a #VisuUiPanel.
591 *
592 * Return the #GtkWindow that the given @visu_ui_panel is rendered in or
593 * NULL if the @visu_ui_panel is currently dettached.
594 *
595 * Returns: (transfer none): a #GtkWindow object.
596 */
visu_ui_panel_getContainerWindow(VisuUiPanel * visu_ui_panel)597 GtkWindow* visu_ui_panel_getContainerWindow(VisuUiPanel *visu_ui_panel)
598 {
599 g_return_val_if_fail(VISU_IS_UI_PANEL(visu_ui_panel), (GtkWindow*)0);
600
601 if (visu_ui_panel->container)
602 {
603 if (visu_ui_panel->container->window)
604 return GTK_WINDOW(visu_ui_panel->container->window);
605 else
606 return GTK_WINDOW(visu_ui_main_class_getCurrentPanel());
607 }
608 else
609 return (GtkWindow*)0;
610 }
611 /**
612 * visu_ui_panel_setContainer:
613 * @visu_ui_panel: a #VisuUiPanel ;
614 * @window: a #VisuUiDockWindow.
615 *
616 * Change the container of a visu_ui_panel. If it is currently attached to
617 * a #VisuUiDockWindow, it firstly detachs it.
618 */
visu_ui_panel_setContainer(VisuUiPanel * visu_ui_panel,VisuUiDockWindow * container)619 void visu_ui_panel_setContainer(VisuUiPanel *visu_ui_panel, VisuUiDockWindow *container)
620 {
621 g_return_if_fail(VISU_IS_UI_PANEL(visu_ui_panel));
622
623 if (container == visu_ui_panel->container)
624 return;
625
626 /* If the panel is already attached, we detach it. */
627 if (visu_ui_panel->container)
628 {
629 DBG_fprintf(stderr, "Gtk VisuUiPanel : detaching panel '%s' (%p).\n",
630 visu_ui_panel->tabLabel, (gpointer)visu_ui_panel);
631 g_object_ref(G_OBJECT(visu_ui_panel));
632 visu_ui_panel_detach(visu_ui_panel);
633 }
634
635 /* If a new container is given, we attach it. */
636 if (container)
637 {
638 DBG_fprintf(stderr, "Gtk VisuUiPanel : attaching panel '%s' (%p) to %p.\n",
639 visu_ui_panel->tabLabel, (gpointer)visu_ui_panel, (gpointer)container);
640 visu_ui_panel_attach(visu_ui_panel, container);
641 g_object_unref(G_OBJECT(visu_ui_panel));
642 }
643 }
644 /**
645 * visu_ui_panel_getContainerId:
646 * @visu_ui_panel: a #VisuUiPanel.
647 *
648 * Return the identifying string of the #VisuUiDockWindow that the given
649 * @visu_ui_panel is attached to or NULL if the @visu_ui_panel is currently dettached.
650 *
651 * Returns: a string owned by V_Sim.
652 */
visu_ui_panel_getContainerId(VisuUiPanel * visu_ui_panel)653 const gchar* visu_ui_panel_getContainerId(VisuUiPanel *visu_ui_panel)
654 {
655 g_return_val_if_fail(VISU_IS_UI_PANEL(visu_ui_panel), (gchar*)0);
656
657 if (!visu_ui_panel->container)
658 return "None";
659
660 if (visu_ui_panel->container == VISU_UI_PANEL_CLASS(G_OBJECT_GET_CLASS(visu_ui_panel))->commandPanel)
661 return "Main";
662
663 return visu_ui_panel->container->name;
664 }
665 /**
666 * visu_ui_panel_setContainerId:
667 * @visu_ui_panel: a #VisuUiPanel ;
668 * @id: a #VisuUiDockWindow identifier.
669 *
670 * Change the container of a visu_ui_panel using the given @id. If it is
671 * currently attached to a #VisuUiDockWindow, it firstly detachs it.
672 */
visu_ui_panel_setContainerId(VisuUiPanel * visu_ui_panel,const gchar * id)673 void visu_ui_panel_setContainerId(VisuUiPanel *visu_ui_panel, const gchar *id)
674 {
675 g_return_if_fail(VISU_IS_UI_PANEL(visu_ui_panel) && id && id[0]);
676
677 visu_ui_panel_setContainer(visu_ui_panel, visu_ui_panel_class_getDockById(id));
678 }
679 /**
680 * visu_ui_panel_getData:
681 * @visu_ui_panel: a #VisuUiPanel.
682 *
683 * The @visu_ui_panel is supposed to work on a #VisuData, this routine can
684 * be used to get it.
685 *
686 * Returns: (transfer none): the currently focused #VisuData (can be NULL if none).
687 */
visu_ui_panel_getData(VisuUiPanel * visu_ui_panel)688 VisuData* visu_ui_panel_getData(VisuUiPanel *visu_ui_panel)
689 {
690 g_return_val_if_fail(VISU_IS_UI_PANEL(visu_ui_panel), (VisuData*)0);
691
692 return VISU_UI_PANEL_CLASS(G_OBJECT_GET_CLASS(visu_ui_panel))->dataObj;
693 }
694 /**
695 * visu_ui_panel_getFocused:
696 * @visu_ui_panel: a #VisuUiPanel.
697 *
698 * Retrieves the currently focused #VisuBoxed object in the default #VisuUiRenderingWindow.
699 *
700 * Since: 3.7
701 *
702 * Returns: (transfer none) (allow-none): the currently focused
703 * #VisuBoxed (can be %NULL if none).
704 */
visu_ui_panel_getFocused(VisuUiPanel * visu_ui_panel)705 VisuBoxed* visu_ui_panel_getFocused(VisuUiPanel *visu_ui_panel)
706 {
707 g_return_val_if_fail(VISU_IS_UI_PANEL(visu_ui_panel), (VisuBoxed*)0);
708
709 return VISU_BOXED(VISU_UI_PANEL_CLASS(G_OBJECT_GET_CLASS(visu_ui_panel))->dataObj);
710 }
711 /**
712 * visu_ui_panel_getView:
713 * @visu_ui_panel: a #VisuUiPanel object.
714 *
715 * Convenient routine to get the current #VisuGlView, see
716 * visu_ui_panel_class_setCurrent().
717 *
718 * Since: 3.7
719 *
720 * Returns: (transfer none): the current #VisuGlView, or NULL.
721 */
visu_ui_panel_getView(VisuUiPanel * visu_ui_panel)722 VisuGlView* visu_ui_panel_getView(VisuUiPanel *visu_ui_panel)
723 {
724 g_return_val_if_fail(VISU_IS_UI_PANEL(visu_ui_panel), (VisuGlView*)0);
725
726 return VISU_UI_PANEL_CLASS(G_OBJECT_GET_CLASS(visu_ui_panel))->viewObj;
727 }
728 /**
729 * visu_ui_panel_getVisible:
730 * @visu_ui_panel: a #VisuUiPanel.
731 *
732 * This is used to retrieve if the @visu_ui_panel is currently realised
733 * and the visualised page of the #GtkNotebook it is associated to.
734 *
735 * Returns: TRUE if the given @visu_ui_panel is potentialy visible to the user.
736 */
visu_ui_panel_getVisible(VisuUiPanel * visu_ui_panel)737 gboolean visu_ui_panel_getVisible(VisuUiPanel *visu_ui_panel)
738 {
739 g_return_val_if_fail(VISU_IS_UI_PANEL(visu_ui_panel), FALSE);
740
741 /* If the tool panel is not shown, we return fFALSE. */
742 if (!visu_ui_panel->container || !visu_ui_panel->container->show)
743 return FALSE;
744
745 /* If the tool panel is attached to a visible dock, we
746 test if the current page of the notebook is our tool panel. */
747 return (visu_ui_panel == VISU_UI_PANEL(gtk_notebook_get_nth_page
748 (GTK_NOTEBOOK(visu_ui_panel->container->notebook),
749 gtk_notebook_get_current_page
750 (GTK_NOTEBOOK(visu_ui_panel->container->notebook)))));
751 }
752
753
754 /*****************/
755 /* Menu gestion. */
756 /*****************/
onDockButtonClicked(VisuUiPanel * visu_ui_panel,gpointer data)757 static void onDockButtonClicked(VisuUiPanel *visu_ui_panel, gpointer data)
758 {
759 GtkWidget *wd;
760
761 g_return_if_fail(VISU_IS_UI_PANEL(visu_ui_panel));
762
763 wd = buildDockMenu(visu_ui_panel, VISU_UI_PANEL_CLASS(G_OBJECT_GET_CLASS(visu_ui_panel))->hostingWindows);
764 g_signal_connect(G_OBJECT(wd), "selection-done",
765 G_CALLBACK(onDockMenuSelected), (gpointer)0);
766
767 gtk_widget_show_all(wd);
768 #if GTK_MAJOR_VERSION < 2 || (GTK_MAJOR_VERSION == 3 && GTK_MINOR_VERSION < 22)
769 gtk_menu_popup(GTK_MENU(wd), NULL, NULL, NULL, NULL,
770 1, gtk_get_current_event_time());
771 (void)data;
772 #else
773 gtk_menu_popup_at_widget(GTK_MENU(wd), GTK_WIDGET(data), GDK_GRAVITY_SOUTH, GDK_GRAVITY_NORTH, NULL);
774 #endif
775 }
776
buildDockMenu(VisuUiPanel * visu_ui_panel,GList * listOfDocks)777 static GtkWidget* buildDockMenu(VisuUiPanel *visu_ui_panel, GList *listOfDocks)
778 {
779 GtkWidget *menu, *item;
780 VisuUiDockWindow *window;
781 gchar *lbl;
782
783 menu = gtk_menu_new();
784
785 /* All dock windows. */
786 while (listOfDocks)
787 {
788 window = (VisuUiDockWindow*)listOfDocks->data;
789 if (window->show)
790 {
791 lbl = g_strdup_printf(_("Send to '%s'"), window->name);
792 item = gtk_menu_item_new_with_label(lbl);
793 g_free(lbl);
794 g_signal_connect(G_OBJECT(item), "activate",
795 G_CALLBACK(onDockMenuClicked), listOfDocks->data);
796 g_object_set_qdata_full(G_OBJECT(item), CURRENT_TOOLPANEL_POINTER,
797 (gpointer)visu_ui_panel, NULL);
798 gtk_widget_set_sensitive(item, (visu_ui_panel->container != window));
799 gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
800 }
801 listOfDocks = g_list_next(listOfDocks);
802 }
803 /* Separator. */
804 item = gtk_separator_menu_item_new();
805 gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
806 /* Create a new dock window. */
807 item = gtk_menu_item_new_with_label(_("New dock"));
808 g_signal_connect(G_OBJECT(item), "activate",
809 G_CALLBACK(onDockMenuNewClicked), (gpointer)visu_ui_panel);
810 gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
811 /* Remove the current tool panel. */
812 lbl = g_strdup_printf(_("Hide tool '%s'"), visu_ui_panel->tabLabel);
813 item = gtk_menu_item_new_with_label(lbl);
814 g_free(lbl);
815 g_signal_connect(G_OBJECT(item), "activate",
816 G_CALLBACK(onDockMenuHideClicked), (gpointer)visu_ui_panel);
817 gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
818
819 DBG_fprintf(stderr, "Gtk VisuUiPanel : create the dock menu %p.\n", (gpointer)menu);
820
821 return menu;
822 }
823
onDockMenuClicked(GtkMenuItem * menuitem,gpointer user_data)824 static void onDockMenuClicked(GtkMenuItem *menuitem, gpointer user_data)
825 {
826 VisuUiPanel *visu_ui_panel;
827
828 visu_ui_panel = (VisuUiPanel*)0;
829 visu_ui_panel = VISU_UI_PANEL(g_object_get_qdata(G_OBJECT(menuitem),
830 CURRENT_TOOLPANEL_POINTER));
831 g_return_if_fail(VISU_IS_UI_PANEL(visu_ui_panel));
832
833 visu_ui_panel_setContainer(visu_ui_panel, (VisuUiDockWindow*)user_data);
834 }
onDockMenuNewClicked(GtkMenuItem * menuitem _U_,gpointer user_data)835 static void onDockMenuNewClicked(GtkMenuItem *menuitem _U_, gpointer user_data)
836 {
837 GList **lst;
838 VisuUiPanel *visu_ui_panel;
839 VisuUiDockWindow *window;
840 guint nb;
841 gchar *name;
842
843 lst = &local_class->hostingWindows;
844 nb = g_list_length(*lst);
845 name = g_strdup_printf(_("Dock window (%d)"), nb);
846 window = dock_window_new(name, TRUE);
847 *lst = g_list_append(*lst, (gpointer)window);
848 window->show = TRUE;
849 gtk_widget_show_all(window->window);
850
851 visu_ui_panel = VISU_UI_PANEL(user_data);
852 if (visu_ui_panel)
853 visu_ui_panel_setContainer(visu_ui_panel, window);
854 }
onDockMenuHideClicked(GtkMenuItem * menuitem _U_,gpointer user_data)855 static void onDockMenuHideClicked(GtkMenuItem *menuitem _U_, gpointer user_data)
856 {
857 DBG_fprintf(stderr, "Gtk VisuUiPanel : hide the panel %p.\n", (gpointer)user_data);
858 visu_ui_panel_setContainer(VISU_UI_PANEL(user_data), (VisuUiDockWindow*)0);
859 }
860
onDockMenuSelected(GtkMenuShell * menushell,gpointer user_data _U_)861 static void onDockMenuSelected(GtkMenuShell *menushell, gpointer user_data _U_)
862 {
863 DBG_fprintf(stderr, "Gtk VisuUiPanel : destroy the dock menu %p.\n", (gpointer)menushell);
864 gtk_widget_destroy(GTK_WIDGET(menushell));
865 }
866
emitPageEnter(gpointer data)867 static gboolean emitPageEnter(gpointer data)
868 {
869 g_return_val_if_fail(VISU_IS_UI_PANEL(data), FALSE);
870
871 DBG_fprintf(stderr, "Gtk VisuUiPanel: '%s' (%p) emits 'page-entered' signal.\n",
872 VISU_UI_PANEL(data)->id, data);
873 g_signal_emit(G_OBJECT(data), visu_ui_panel_signals[NOTEBOOK_ENTERED],
874 0, NULL);
875
876 return FALSE;
877 }
878
changeHeaderVisibility(VisuUiPanel * panel,gboolean status)879 static void changeHeaderVisibility(VisuUiPanel *panel, gboolean status)
880 {
881 GList *list, *tmpLst;
882
883 g_return_if_fail(VISU_IS_UI_PANEL(panel) && panel->headerWidget);
884
885 list = gtk_container_get_children(GTK_CONTAINER(panel->headerWidget));
886 tmpLst = list->next;
887 while(tmpLst)
888 {
889 if (status)
890 gtk_widget_show(GTK_WIDGET(tmpLst->data));
891 else
892 gtk_widget_hide(GTK_WIDGET(tmpLst->data));
893 tmpLst = g_list_next(tmpLst);
894 }
895 g_list_free(list);
896 }
897
onHomePressed(GtkWidget * widget _U_,GdkEventKey * event,gpointer data)898 static gboolean onHomePressed(GtkWidget *widget _U_, GdkEventKey *event,
899 gpointer data)
900 {
901 DBG_fprintf(stderr, "Gtk VisuUiPanel: get key pressed.\n");
902 if(event->keyval == GDK_KEY_Home)
903 {
904 onRaiseButtonClicked((GtkButton*)0, data);
905 return TRUE;
906 }
907 return FALSE;
908 }
onPageChanged(GtkNotebook * book,GtkWidget * child,gint num,gpointer data)909 static void onPageChanged(GtkNotebook *book, GtkWidget *child,
910 gint num, gpointer data)
911 {
912 VisuUiDockWindow *window;
913 int numOld;
914 #if GTK_MAJOR_VERSION == 2
915 child = gtk_notebook_get_nth_page(book, num);
916 #endif
917
918 window = (VisuUiDockWindow*)data;
919 g_return_if_fail(window);
920 g_return_if_fail(VISU_IS_UI_PANEL(child));
921
922 DBG_fprintf(stderr, "Gtk VisuUiPanel: caught 'page-switch' signal, jump to %d.\n", num);
923 /* Change the visibility of the header labels. */
924 if (!local_class->showHeader)
925 {
926 numOld = gtk_combo_box_get_active(GTK_COMBO_BOX(window->combo));
927 if ((gint)num != numOld)
928 {
929 /* We don't come from the combo so we change the
930 visibility. */
931 changeHeaderVisibility
932 (VISU_UI_PANEL(gtk_notebook_get_nth_page(book, numOld)), FALSE);
933 changeHeaderVisibility
934 (VISU_UI_PANEL(gtk_notebook_get_nth_page(book, num)), TRUE);
935 }
936 }
937
938 /* Change the combo to the right one. */
939 g_signal_handler_block(G_OBJECT(window->combo), window->comboChanged);
940 gtk_combo_box_set_active(GTK_COMBO_BOX(window->combo), num);
941 g_signal_handler_unblock(G_OBJECT(window->combo), window->comboChanged);
942
943 g_idle_add(emitPageEnter, child);
944 }
945
onComboChanged(GtkComboBox * combo,gpointer data)946 static void onComboChanged(GtkComboBox *combo, gpointer data)
947 {
948 int index, numOld;
949 VisuUiDockWindow *window;
950 GtkNotebook *book;
951
952 window = (VisuUiDockWindow*)data;
953 g_return_if_fail(window);
954
955 index = gtk_combo_box_get_active(combo);
956
957 /* Change the visibility of the header labels. */
958 if (!local_class->showHeader)
959 {
960 book = GTK_NOTEBOOK(window->notebook);
961 numOld = gtk_notebook_get_current_page(book);
962 changeHeaderVisibility
963 (VISU_UI_PANEL(gtk_notebook_get_nth_page(book, numOld)), FALSE);
964 changeHeaderVisibility
965 (VISU_UI_PANEL(gtk_notebook_get_nth_page(book, index)), TRUE);
966 }
967
968 /* Change the page to the right one. */
969 gtk_notebook_set_current_page(GTK_NOTEBOOK(window->notebook), index);
970 }
971
972
onKillVisuUiDockWindowEvent(GtkWidget * widget,GdkEvent * event _U_,gpointer user_data)973 static gboolean onKillVisuUiDockWindowEvent(GtkWidget *widget, GdkEvent *event _U_,
974 gpointer user_data)
975 {
976 g_return_val_if_fail(user_data, TRUE);
977
978 DBG_fprintf(stderr, "Gtk VisuUiPanel: delete or destroy event cancelled.\n");
979 gtk_widget_hide(widget);
980 ((VisuUiDockWindow*)user_data)->show = FALSE;
981 return TRUE;
982 }
983
984 /**
985 * visu_ui_panel_attach:
986 * @visu_ui_panel: a #VisuUiPanel ;
987 * @dock: a #VisuUiDockWindow.
988 *
989 * Put the given @visu_ui_panel in the given @dock window. It adds in this
990 * dock window a new page in the #GtkNotebook using as tab header the
991 * widget returned by visu_ui_panel_getHeaderWidget().
992 */
visu_ui_panel_attach(VisuUiPanel * visu_ui_panel,VisuUiDockWindow * dock)993 void visu_ui_panel_attach(VisuUiPanel *visu_ui_panel, VisuUiDockWindow *dock)
994 {
995 GtkTreeIter iter;
996 VisuUiPanelClass *klass;
997 GdkPixbuf *pixbuf;
998
999 DBG_fprintf(stderr, "Gtk VisuUiPanel: attach a visu_ui_panel (%p) to a dock"
1000 " window (%s).\n", (gpointer)visu_ui_panel, dock->name);
1001
1002 g_return_if_fail(dock && visu_ui_panel);
1003
1004 if (visu_ui_panel->icon &&
1005 gtk_image_get_storage_type(GTK_IMAGE(visu_ui_panel->icon)) == GTK_IMAGE_PIXBUF)
1006 pixbuf = gtk_image_get_pixbuf(GTK_IMAGE(visu_ui_panel->icon));
1007 else
1008 pixbuf = (GdkPixbuf*)0;
1009
1010 /* We add the window in the list store. */
1011 gtk_list_store_append(dock->list, &iter);
1012 gtk_list_store_set(dock->list, &iter,
1013 TOOL_LIST_ICON, pixbuf,
1014 TOOL_LIST_STOCK, visu_ui_panel->stockIcon,
1015 TOOL_LIST_NAME, visu_ui_panel->comboLabel,
1016 TOOL_LIST_POINTER_TO_DATA, visu_ui_panel,
1017 -1);
1018
1019 gtk_notebook_append_page(GTK_NOTEBOOK(dock->notebook), GTK_WIDGET(visu_ui_panel),
1020 visu_ui_panel_getHeaderWidget(visu_ui_panel));
1021 gtk_widget_show(GTK_WIDGET(visu_ui_panel));
1022 visu_ui_panel->container = dock;
1023
1024 if (gtk_notebook_get_n_pages(GTK_NOTEBOOK(dock->notebook)) > 1)
1025 gtk_widget_show(dock->hbox);
1026 else
1027 gtk_widget_hide(dock->hbox);
1028
1029 klass = VISU_UI_PANEL_CLASS(G_OBJECT_GET_CLASS(visu_ui_panel));
1030 klass->orphanVisuUiPanel = g_list_remove(klass->orphanVisuUiPanel,
1031 (gpointer)visu_ui_panel);
1032
1033 }
1034 /**
1035 * visu_ui_panel_detach:
1036 * @visu_ui_panel: a #VisuUiPanel.
1037 *
1038 * Remove the given @visu_ui_panel from its current container and add it
1039 * to the list of hidden tool panels. It can be added again using the
1040 * pop-up menu of any #VisuUiDockWindow.
1041 */
visu_ui_panel_detach(VisuUiPanel * visu_ui_panel)1042 void visu_ui_panel_detach(VisuUiPanel *visu_ui_panel)
1043 {
1044 gint page;
1045 VisuUiDockWindow *window;
1046 GtkTreeIter iter;
1047 GtkTreePath* path;
1048 gboolean valid;
1049 VisuUiPanelClass *klass;
1050
1051 g_return_if_fail(visu_ui_panel && visu_ui_panel->container);
1052
1053 window = visu_ui_panel->container;
1054
1055 /* Get the id. */
1056 page = gtk_notebook_page_num(GTK_NOTEBOOK(window->notebook), GTK_WIDGET(visu_ui_panel));
1057
1058 DBG_fprintf(stderr, "Gtk VisuUiPanel : detach a visu_ui_panel (%s) from page %d of dock"
1059 " (%s).\n", visu_ui_panel->tabLabel, page, window->name);
1060
1061 /* We remove the page for the notebook. */
1062 gtk_notebook_remove_page(GTK_NOTEBOOK(window->notebook), page);
1063
1064 if (gtk_notebook_get_n_pages(GTK_NOTEBOOK(window->notebook)) < 2)
1065 gtk_widget_hide(window->hbox);
1066
1067 /* We remove the tool from the combo list. */
1068 path = gtk_tree_path_new_from_indices(page, -1);
1069 valid = gtk_tree_model_get_iter(GTK_TREE_MODEL(window->list), &iter, path);
1070 if (valid)
1071 gtk_list_store_remove(window->list, &iter);
1072 gtk_tree_path_free(path);
1073
1074 /* If there is no more tool in this window, we delete it. */
1075 if (gtk_notebook_get_n_pages(GTK_NOTEBOOK(window->notebook)) == 0 &&
1076 window != VISU_UI_PANEL_CLASS(G_OBJECT_GET_CLASS(visu_ui_panel))->commandPanel)
1077 {
1078 DBG_fprintf(stderr, "Gtk VisuUiPanel: destroying dock window %p (%s).\n",
1079 (gpointer)window, window->name);
1080 gtk_widget_destroy(window->window);
1081 VISU_UI_PANEL_CLASS(G_OBJECT_GET_CLASS(visu_ui_panel))->hostingWindows =
1082 g_list_remove(VISU_UI_PANEL_CLASS(G_OBJECT_GET_CLASS(visu_ui_panel))->hostingWindows,
1083 (gconstpointer)window);
1084 g_free(window->name);
1085 g_object_unref(window->list);
1086 g_free(window);
1087 }
1088
1089 visu_ui_panel->container = (VisuUiDockWindow*)0;
1090 klass = VISU_UI_PANEL_CLASS(G_OBJECT_GET_CLASS(visu_ui_panel));
1091 klass->orphanVisuUiPanel = g_list_prepend(klass->orphanVisuUiPanel,
1092 (gpointer)visu_ui_panel);
1093 DBG_fprintf(stderr, "Gtk VisuUiPanel: number of orphan tool panels %d.\n",
1094 g_list_length(klass->orphanVisuUiPanel));
1095 }
1096
onMainButtonClicked(GtkButton * button,gpointer data)1097 static void onMainButtonClicked(GtkButton *button, gpointer data)
1098 {
1099 GtkWidget *wd;
1100
1101 wd = buildMainMenu((VisuUiDockWindow*)data);
1102 g_signal_connect(G_OBJECT(wd), "selection-done",
1103 G_CALLBACK(onMainMenuSelected), (gpointer)0);
1104
1105 gtk_widget_show_all(wd);
1106 #if GTK_MAJOR_VERSION < 2 || (GTK_MAJOR_VERSION == 3 && GTK_MINOR_VERSION < 22)
1107 gtk_menu_popup(GTK_MENU(wd), NULL, NULL, NULL, NULL,
1108 1, gtk_get_current_event_time());
1109 (void)button;
1110 #else
1111 gtk_menu_popup_at_widget(GTK_MENU(wd), GTK_WIDGET(button), GDK_GRAVITY_SOUTH, GDK_GRAVITY_NORTH, NULL);
1112 #endif
1113 }
1114
buildMainMenu(VisuUiDockWindow * window)1115 static GtkWidget* buildMainMenu(VisuUiDockWindow *window)
1116 {
1117 GtkWidget *menu, *item;
1118 GList* tmpLst;
1119 gchar *label;
1120 VisuUiPanel *panel;
1121 VisuUiDockWindow *dock;
1122 gboolean haveHiddenDock;
1123
1124 menu = gtk_menu_new();
1125
1126 tmpLst = local_class->orphanVisuUiPanel;
1127 /* All dock windows. */
1128 while (tmpLst)
1129 {
1130 panel = (VisuUiPanel*)tmpLst->data;
1131 label = g_strdup_printf(_("Show '%s'"), panel->comboLabel);
1132 item = gtk_menu_item_new_with_label(label);
1133 g_free(label);
1134 g_signal_connect(G_OBJECT(item), "activate",
1135 G_CALLBACK(onMainMenuClicked), window);
1136 g_object_set_qdata_full(G_OBJECT(item), CURRENT_TOOLPANEL_POINTER,
1137 (gpointer)panel, NULL);
1138 gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
1139 tmpLst = g_list_next(tmpLst);
1140 }
1141 if (!local_class->orphanVisuUiPanel)
1142 {
1143 item = gtk_menu_item_new_with_label(_("No hidden tool"));
1144 gtk_widget_set_sensitive(item, FALSE);
1145 gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
1146 }
1147 /* Separator. */
1148 item = gtk_separator_menu_item_new();
1149 gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
1150 /* Hidden dock. */
1151 haveHiddenDock = FALSE;
1152 tmpLst = local_class->hostingWindows;
1153 while (tmpLst)
1154 {
1155 dock = (VisuUiDockWindow*)tmpLst->data;
1156 if (!dock->show)
1157 {
1158 haveHiddenDock = TRUE;
1159 label = g_strdup_printf(_("Show '%s'"), dock->name);
1160 item = gtk_menu_item_new_with_label(label);
1161 g_free(label);
1162 g_signal_connect(G_OBJECT(item), "activate",
1163 G_CALLBACK(onMainMenuShowClicked), dock);
1164 gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
1165 }
1166 tmpLst = g_list_next(tmpLst);
1167 }
1168 if (!haveHiddenDock)
1169 {
1170 item = gtk_menu_item_new_with_label(_("No hidden dock"));
1171 gtk_widget_set_sensitive(item, FALSE);
1172 gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
1173 }
1174 if (window->window)
1175 {
1176 /* Separator. */
1177 item = gtk_separator_menu_item_new();
1178 gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
1179 /* Hide action */
1180 item = gtk_menu_item_new_with_label(_("Hide dock"));
1181 g_signal_connect(G_OBJECT(item), "activate",
1182 G_CALLBACK(onMainMenuHideClicked), window);
1183 gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
1184 }
1185
1186 DBG_fprintf(stderr, "Gtk VisuUiPanel: create the main menu %p.\n", (gpointer)menu);
1187
1188 return menu;
1189 }
onMainMenuClicked(GtkMenuItem * menuitem,gpointer user_data)1190 static void onMainMenuClicked(GtkMenuItem *menuitem, gpointer user_data)
1191 {
1192 VisuUiPanel *visu_ui_panel;
1193 VisuUiDockWindow *window;
1194
1195 visu_ui_panel = (VisuUiPanel*)0;
1196 visu_ui_panel = VISU_UI_PANEL(g_object_get_qdata(G_OBJECT(menuitem),
1197 CURRENT_TOOLPANEL_POINTER));
1198 g_return_if_fail(VISU_IS_UI_PANEL(visu_ui_panel));
1199
1200 window = (VisuUiDockWindow*)user_data;
1201
1202 DBG_fprintf(stderr, "Gtk VisuUiPanel: attaching panel '%s' (%p) to %p.\n",
1203 visu_ui_panel->tabLabel, (gpointer)visu_ui_panel, (gpointer)window);
1204 visu_ui_panel_attach(visu_ui_panel, window);
1205 g_object_unref(G_OBJECT(visu_ui_panel));
1206 }
onMainMenuShowClicked(GtkMenuItem * menuitem _U_,gpointer user_data)1207 static void onMainMenuShowClicked(GtkMenuItem *menuitem _U_, gpointer user_data)
1208 {
1209 VisuUiDockWindow *dock;
1210
1211 g_return_if_fail(user_data);
1212
1213 dock = (VisuUiDockWindow*)user_data;
1214 if (dock->window)
1215 gtk_widget_show(dock->window);
1216 dock->show = TRUE;
1217 }
onMainMenuHideClicked(GtkMenuItem * menuitem _U_,gpointer user_data)1218 static void onMainMenuHideClicked(GtkMenuItem *menuitem _U_, gpointer user_data)
1219 {
1220 VisuUiDockWindow *dock;
1221
1222 g_return_if_fail(user_data);
1223
1224 dock = (VisuUiDockWindow*)user_data;
1225 if (dock->window)
1226 gtk_widget_hide(dock->window);
1227 dock->show = FALSE;
1228 }
onMainMenuSelected(GtkMenuShell * menushell,gpointer user_data _U_)1229 static void onMainMenuSelected(GtkMenuShell *menushell, gpointer user_data _U_)
1230 {
1231 DBG_fprintf(stderr, "Gtk VisuUiPanel: destroy the main menu %p.\n", (gpointer)menushell);
1232 gtk_widget_destroy(GTK_WIDGET(menushell));
1233 }
onRaiseButtonClicked(GtkButton * button _U_,gpointer data _U_)1234 static void onRaiseButtonClicked(GtkButton *button _U_, gpointer data _U_)
1235 {
1236 GtkWindow *window;
1237
1238 window = visu_ui_getRenderWindow();
1239 g_return_if_fail(window);
1240 /* We raised the rendering window, if required. */
1241 gtk_window_present(window);
1242 }
1243
1244
1245 /******************/
1246 /* Class methods. */
1247 /******************/
1248
1249 /**
1250 * visu_ui_panel_class_getCommandPanel:
1251 *
1252 * There is always a #VisuUiDockWindow that is inside the command
1253 * panel. This routine gets it.
1254 *
1255 * Returns: (transfer none):the #VisuUiDockWindow that is inside the command panel.
1256 */
visu_ui_panel_class_getCommandPanel(void)1257 VisuUiDockWindow* visu_ui_panel_class_getCommandPanel(void)
1258 {
1259 if (!local_class)
1260 g_type_class_ref(VISU_TYPE_UI_PANEL);
1261
1262 if (!local_class->commandPanel)
1263 {
1264 local_class->commandPanel = dock_window_new(MAIN_PANEL_NAME, FALSE);
1265 local_class->hostingWindows = g_list_prepend(local_class->hostingWindows,
1266 local_class->commandPanel);
1267 }
1268
1269 return local_class->commandPanel;
1270 }
1271 /**
1272 * visu_ui_panel_class_setCurrent:
1273 * @dataObj: a #VisuData object.
1274 * @view: a #VisuGlView object.
1275 *
1276 * Set the currently focussed #VisuData. It then can be retrieve using
1277 * visu_ui_panel_getData().
1278 *
1279 * Since: 3.7
1280 */
visu_ui_panel_class_setCurrent(VisuData * dataObj,VisuGlView * view)1281 void visu_ui_panel_class_setCurrent(VisuData *dataObj, VisuGlView *view)
1282 {
1283 if (!local_class)
1284 g_type_class_ref(VISU_TYPE_UI_PANEL);
1285
1286 local_class->dataObj = dataObj;
1287 local_class->viewObj = view;
1288 }
1289 /**
1290 * visu_ui_panel_class_getPanelById:
1291 * @id: a #VisuUiPanel identifier.
1292 *
1293 * This routine associates a #VisuUiPanel identifier to the object pointer.
1294 *
1295 * Returns: (transfer none): the #VisuUiPanel that corresponds to this identifier or NULL
1296 * if none exists.
1297 */
visu_ui_panel_class_getPanelById(const gchar * id)1298 VisuUiPanel* visu_ui_panel_class_getPanelById(const gchar *id)
1299 {
1300 gpointer panel;
1301
1302 if (!local_class)
1303 g_type_class_ref(VISU_TYPE_UI_PANEL);
1304
1305 DBG_fprintf(stderr, "Gtk VisuUiPanel: search panel '%s'.\n", id);
1306 panel = g_hash_table_lookup(local_class->allVisuUiPanels, id);
1307 if (!panel)
1308 return (VisuUiPanel*)0;
1309 else
1310 return VISU_UI_PANEL(panel);
1311 }
1312 /**
1313 * visu_ui_panel_class_getDockById:
1314 * @id: a #VisuUiDockWindow identifier.
1315 *
1316 * This routine associates a #VisuUiDockWindow identifier to the object pointer.
1317 *
1318 * Returns: the #VisuUiDockWindow that corresponds to this identifier. The
1319 * dock window is built if not currently exist.
1320 */
visu_ui_panel_class_getDockById(const gchar * id)1321 VisuUiDockWindow* visu_ui_panel_class_getDockById(const gchar *id)
1322 {
1323 VisuUiDockWindow *window;
1324 GList *tmplst;
1325
1326 if (!local_class)
1327 g_type_class_ref(VISU_TYPE_UI_PANEL);
1328
1329 if (!strcmp(id, "None"))
1330 return (VisuUiDockWindow*)0;
1331
1332 if (!strcmp(id, "Main"))
1333 return local_class->commandPanel;
1334
1335 tmplst = local_class->hostingWindows;
1336 while (tmplst)
1337 {
1338 if (!strcmp(((VisuUiDockWindow*)tmplst->data)->name, id))
1339 return (VisuUiDockWindow*)tmplst->data;
1340 tmplst = g_list_next(tmplst);
1341 };
1342 /* No matching name found, we create a new window. */
1343 window = dock_window_new(g_strdup(id), TRUE);
1344 local_class->hostingWindows = g_list_prepend(local_class->hostingWindows,
1345 (gpointer)window);
1346
1347 return window;
1348 }
1349 /**
1350 * visu_ui_panel_class_getAllPanels:
1351 *
1352 * This routine can be used to know all existing #VisuUiPanel.
1353 *
1354 * Returns: (transfer full) (element-type VisuUiPanel*): a newly
1355 * created list (use g_list_free() on it after use).
1356 */
visu_ui_panel_class_getAllPanels(void)1357 GList* visu_ui_panel_class_getAllPanels(void)
1358 {
1359 GList *tmplst, *returnlst;
1360 gboolean valid;
1361 GtkTreeIter iter;
1362 VisuUiPanel *tool;
1363 GtkTreeModel *treeModel;
1364
1365 if (!local_class)
1366 g_type_class_ref(VISU_TYPE_UI_PANEL);
1367
1368 DBG_fprintf(stderr, "Gtk VisuUiPanel: create list of all panels.\n");
1369 returnlst = (GList*)0;
1370 tmplst = local_class->hostingWindows;
1371 while (tmplst)
1372 {
1373 treeModel = GTK_TREE_MODEL(((VisuUiDockWindow*)tmplst->data)->list);
1374 valid = gtk_tree_model_get_iter_first(treeModel, &iter);
1375 while (valid)
1376 {
1377 gtk_tree_model_get(treeModel, &iter, TOOL_LIST_POINTER_TO_DATA, &tool, -1);
1378 DBG_fprintf(stderr, " | add '%s'\n", tool->id);
1379 returnlst = g_list_prepend(returnlst, (gpointer)tool);
1380 valid = gtk_tree_model_iter_next(treeModel, &iter);
1381 }
1382 tmplst = g_list_next(tmplst);
1383 }
1384 returnlst = g_list_concat(returnlst, g_list_copy(local_class->orphanVisuUiPanel));
1385 return returnlst;
1386 }
1387 /**
1388 * visu_ui_panel_class_getAllWindows:
1389 *
1390 * This routine can be used to know all existing #VisuUiDockWindow.
1391 *
1392 * Returns: (transfer container) (element-type VisuUiDockWindow*): a
1393 * newly created list (use g_list_free() on it after use).
1394 */
visu_ui_panel_class_getAllWindows(void)1395 GList* visu_ui_panel_class_getAllWindows(void)
1396 {
1397 GList *returnlst;
1398
1399 if (!local_class)
1400 g_type_class_ref(VISU_TYPE_UI_PANEL);
1401
1402 DBG_fprintf(stderr, "Gtk VisuUiPanel : create list of all windows.\n");
1403 returnlst = g_list_copy(local_class->hostingWindows);
1404 returnlst = g_list_remove(returnlst, local_class->commandPanel);
1405 return returnlst;
1406 }
1407 /**
1408 * visu_ui_panel_class_setHeaderVisibility:
1409 * @status: a boolean.
1410 *
1411 * The header can be represented using the full image and label always
1412 * or only the image when the tab is not on top.
1413 */
visu_ui_panel_class_setHeaderVisibility(gboolean status)1414 void visu_ui_panel_class_setHeaderVisibility(gboolean status)
1415 {
1416 GList *tmpLst;
1417 int num, i;
1418 GtkNotebook *notebook;
1419
1420 if (!local_class)
1421 g_type_class_ref(VISU_TYPE_UI_PANEL);
1422
1423 DBG_fprintf(stderr, "Gtk VisuUiPanel : set the header visibility.\n");
1424 if (local_class->showHeader == status)
1425 return;
1426
1427 tmpLst = local_class->hostingWindows;
1428 while(tmpLst)
1429 {
1430 notebook = GTK_NOTEBOOK(((VisuUiDockWindow*)tmpLst->data)->notebook);
1431 num = gtk_notebook_get_current_page(notebook);
1432 for (i = 0; i < gtk_notebook_get_n_pages(notebook); i++)
1433 changeHeaderVisibility(VISU_UI_PANEL(gtk_notebook_get_nth_page(notebook, i)),
1434 status || (i == num));
1435 tmpLst = g_list_next(tmpLst);
1436 }
1437 local_class->showHeader = status;
1438 }
1439 /**
1440 * visu_ui_panel_class_getHeaderVisibility:
1441 *
1442 * The header can be represented using the full image and label always
1443 * or only the image when the tab is not on top.
1444 *
1445 * Since: 3.8
1446 *
1447 * Returns: TRUE if the header uses text and label.
1448 **/
visu_ui_panel_class_getHeaderVisibility(void)1449 gboolean visu_ui_panel_class_getHeaderVisibility(void)
1450 {
1451 if (!local_class)
1452 g_type_class_ref(VISU_TYPE_UI_PANEL);
1453
1454 return local_class->showHeader;
1455 }
1456
1457 /************************/
1458 /* Dock window methods. */
1459 /************************/
visu_ui_dock_window_get_type(void)1460 GType visu_ui_dock_window_get_type(void)
1461 {
1462 static GType g_define_type_id = 0;
1463
1464 if (g_define_type_id == 0)
1465 g_define_type_id =
1466 g_boxed_type_register_static("VisuUiDockWindow",
1467 (GBoxedCopyFunc)dock_window_ref,
1468 (GBoxedFreeFunc)dock_window_unref);
1469 return g_define_type_id;
1470 }
dock_window_new(gchar * name,gboolean withWindow)1471 static VisuUiDockWindow* dock_window_new(gchar *name, gboolean withWindow)
1472 {
1473 VisuUiDockWindow *window;
1474 GtkWidget *wd, *image;
1475 GtkCellRenderer *renderer;
1476 /* GtkBindingSet *keys; */
1477 #if GTK_MAJOR_VERSION == 2 && GTK_MINOR_VERSION < 12
1478 GtkTooltips *tooltips;
1479
1480 tooltips = gtk_tooltips_new ();
1481 #endif
1482
1483 window = g_malloc(sizeof(VisuUiDockWindow));
1484 window->refCount = 1;
1485
1486 DBG_fprintf(stderr, "Gtk VisuUiPanel: create a new dock window %p (%s).\n",
1487 (gpointer)window, name);
1488
1489 window->name = name;
1490
1491 window->show = !strcmp(name, MAIN_PANEL_NAME);
1492
1493 window->vbox = gtk_vbox_new(FALSE, 0);
1494
1495 if (withWindow)
1496 {
1497 window->window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
1498 gtk_window_set_title(GTK_WINDOW(window->window), window->name);
1499 gtk_window_set_default_size(GTK_WINDOW(window->window), 350, 350);
1500 gtk_window_set_type_hint(GTK_WINDOW(window->window), GDK_WINDOW_TYPE_HINT_UTILITY);
1501 gtk_window_set_skip_pager_hint(GTK_WINDOW(window->window), TRUE);
1502 g_signal_connect(G_OBJECT(window->window), "delete-event",
1503 G_CALLBACK(onKillVisuUiDockWindowEvent), (gpointer)window);
1504 g_signal_connect(G_OBJECT(window->window), "destroy-event",
1505 G_CALLBACK(onKillVisuUiDockWindowEvent), (gpointer)window);
1506 g_signal_connect(G_OBJECT(window->window), "key-press-event",
1507 G_CALLBACK(onHomePressed), (gpointer)window);
1508
1509 gtk_container_set_border_width(GTK_CONTAINER(window->window), 3);
1510 gtk_container_add(GTK_CONTAINER(window->window), window->vbox);
1511 /* gtk_widget_show(window->window); */
1512 }
1513 else
1514 window->window = (GtkWidget*)0;
1515
1516 window->notebook = gtk_notebook_new();
1517 gtk_widget_set_margin_top(window->notebook, 5);
1518 gtk_notebook_set_scrollable(GTK_NOTEBOOK(window->notebook), TRUE);
1519 gtk_box_pack_end(GTK_BOX(window->vbox), window->notebook, TRUE, TRUE, 0);
1520 window->notebookChanged =
1521 g_signal_connect(G_OBJECT(window->notebook), "switch-page",
1522 G_CALLBACK(onPageChanged), (gpointer)window);
1523
1524 window->hbox = gtk_hbox_new(FALSE, 0);
1525 gtk_box_pack_start(GTK_BOX(window->vbox), window->hbox, FALSE, FALSE, 0);
1526
1527 /* Define the key bindings. */
1528 /* keys = gtk_binding_set_new("commandPanel"); */
1529 /* gtk_binding_entry_add_signal(keys, GDK_KEY_space, 0, "clicked", 1, (gpointer)window); */
1530
1531 /* Raise render area. */
1532 wd = gtk_button_new();
1533 g_object_set(G_OBJECT(wd), "can-default", TRUE, "can-focus", TRUE,
1534 "has-default", FALSE, "has-focus", FALSE, NULL);
1535 /* gtk_button_set_relief(GTK_BUTTON(wd), GTK_RELIEF_NONE); */
1536 gtk_box_pack_start(GTK_BOX(window->hbox), wd, FALSE, FALSE, 0);
1537 g_signal_connect(G_OBJECT(wd), "clicked",
1538 G_CALLBACK(onRaiseButtonClicked), (gpointer)window);
1539 image = gtk_image_new_from_icon_name("go-up", GTK_ICON_SIZE_MENU);
1540 gtk_container_add(GTK_CONTAINER(wd), image);
1541 gtk_widget_set_tooltip_text(wd, _("Raise the rendering window.\n"
1542 " Use <home> as key binding."));
1543
1544 /* The Label to introduce the combo list. */
1545 wd = gtk_label_new(_("Tool: "));
1546 gtk_box_pack_start(GTK_BOX(window->hbox), wd, FALSE, FALSE, 2);
1547
1548 /* We create the list store. */
1549 window->list = gtk_list_store_new(TOOL_LIST_N_COLUMNS,
1550 GDK_TYPE_PIXBUF, G_TYPE_STRING,
1551 G_TYPE_STRING, G_TYPE_POINTER);
1552 /* The combo list. */
1553 window->combo = gtk_combo_box_new_with_model(GTK_TREE_MODEL(window->list));
1554 renderer = gtk_cell_renderer_pixbuf_new();
1555 gtk_cell_renderer_set_fixed_size(renderer, 22, -1);
1556 gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(window->combo), renderer, FALSE);
1557 gtk_cell_layout_add_attribute(GTK_CELL_LAYOUT(window->combo),
1558 renderer, "pixbuf", TOOL_LIST_ICON);
1559 gtk_cell_layout_add_attribute(GTK_CELL_LAYOUT(window->combo),
1560 renderer, "stock-id", TOOL_LIST_STOCK);
1561 renderer = gtk_cell_renderer_text_new();
1562 gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(window->combo), renderer, FALSE);
1563 gtk_cell_layout_add_attribute(GTK_CELL_LAYOUT(window->combo),
1564 renderer, "text", TOOL_LIST_NAME);
1565 gtk_box_pack_start(GTK_BOX(window->hbox), window->combo, TRUE, TRUE, 0);
1566 window->comboChanged = g_signal_connect(G_OBJECT(window->combo), "changed",
1567 G_CALLBACK(onComboChanged),
1568 (gpointer)window);
1569
1570 /* Add a menu button. */
1571 wd = gtk_button_new();
1572 gtk_button_set_relief(GTK_BUTTON(wd), GTK_RELIEF_NONE);
1573 gtk_box_pack_start(GTK_BOX(window->hbox), wd, FALSE, FALSE, 2);
1574 g_signal_connect(G_OBJECT(wd), "clicked",
1575 G_CALLBACK(onMainButtonClicked), (gpointer)window);
1576 image = create_pixmap((GtkWidget*)0, "stock-menu-detach.png");
1577 gtk_container_add(GTK_CONTAINER(wd), image);
1578 gtk_widget_set_tooltip_text(wd,
1579 _("Manage hidden subpanels and dock windows."));
1580
1581 /* Add a help tooltips. */
1582 wd = gtk_event_box_new();
1583 gtk_event_box_set_visible_window(GTK_EVENT_BOX(wd), FALSE);
1584 gtk_widget_set_tooltip_text(wd,
1585 _("Positions, sizes, names, contains... of dock" \
1586 " windows are stored in the parameters file, " \
1587 "see the 'Config. files' button on the command panel."));
1588 gtk_box_pack_end(GTK_BOX(window->hbox), wd, FALSE, FALSE, 2);
1589 image = gtk_image_new_from_icon_name("help-browser", GTK_ICON_SIZE_MENU);
1590 gtk_container_add(GTK_CONTAINER(wd), image);
1591
1592 gtk_widget_show_all(window->vbox);
1593 return window;
1594 }
dock_window_ref(VisuUiDockWindow * dock)1595 static VisuUiDockWindow* dock_window_ref(VisuUiDockWindow *dock)
1596 {
1597 dock->refCount += 1;
1598 return dock;
1599 }
dock_window_unref(VisuUiDockWindow * dock)1600 static void dock_window_unref(VisuUiDockWindow *dock)
1601 {
1602 dock->refCount -= 1;
1603 if (!dock->refCount)
1604 {
1605 if (dock->window)
1606 gtk_widget_destroy(dock->window);
1607 else
1608 gtk_widget_destroy(dock->vbox);
1609 }
1610 }
1611 /**
1612 * visu_ui_dock_window_getCharacteristics:
1613 * @dock: a #VisuUiDockWindow object ;
1614 * @id: a location to store the identifier (owned by V_Sim) ;
1615 * @visibility: a location to store the status of the dock, hidden or
1616 * not ;
1617 * @x: a location to store its x position on the root window ;
1618 * @y: a location to store its y position on the root window ;
1619 * @width: a location to store its width ;
1620 * @height: a location to store its height.
1621 *
1622 * A routine to know everything about a #VisuUiDockWindow.
1623 */
visu_ui_dock_window_getCharacteristics(VisuUiDockWindow * dock,gchar ** id,gboolean * visibility,gint * x,gint * y,gint * width,gint * height)1624 void visu_ui_dock_window_getCharacteristics(VisuUiDockWindow *dock, gchar **id,
1625 gboolean *visibility,
1626 gint *x, gint *y,
1627 gint *width, gint *height)
1628 {
1629 g_return_if_fail(dock);
1630
1631 *id = dock->name;
1632 *visibility = dock->show;
1633 gtk_window_get_position(GTK_WINDOW(dock->window), x, y);
1634 gtk_window_get_size(GTK_WINDOW(dock->window), width, height);
1635 }
1636 /**
1637 * visu_ui_dock_window_getContainer:
1638 * @dock: a dock window descriptor.
1639 *
1640 * A dock window is a small utility window with a list of #VisuUiPanel.
1641 * This window can be embedded in a container or have its own
1642 * GtkWindow. This routine get the top-level container inside a given
1643 * #VisuUiDockWindow. If you prefer to get the GtkWindow containing the
1644 * #VisuUiDockWindow use visu_ui_dock_window_getWindow() instead.
1645 *
1646 * Returns: (transfer none): a top-level container (usually a #GtkVBox).
1647 */
visu_ui_dock_window_getContainer(VisuUiDockWindow * dock)1648 GtkWidget* visu_ui_dock_window_getContainer(VisuUiDockWindow *dock)
1649 {
1650 g_return_val_if_fail(dock, (GtkWidget*)0);
1651
1652 return dock->vbox;
1653 }
1654 /**
1655 * visu_ui_dock_window_getNotebook:
1656 * @dock: a dock window descriptor.
1657 *
1658 * A dock window is a small utility window with a list of #VisuUiPanel.
1659 * All #VisuUiPanel are contained in a #GtkNotebook. This routine gets it.
1660 *
1661 * Returns: (transfer none): the #GtkNotebook containing the #VisuUiPanel of this
1662 * #VisuUiDockWindow.
1663 */
visu_ui_dock_window_getNotebook(VisuUiDockWindow * dock)1664 GtkWidget* visu_ui_dock_window_getNotebook(VisuUiDockWindow *dock)
1665 {
1666 g_return_val_if_fail(dock, (GtkWidget*)0);
1667
1668 return dock->notebook;
1669 }
1670 /**
1671 * visu_ui_dock_window_getWindow:
1672 * @dock: a dock window descriptor.
1673 *
1674 * A dock window is a small utility window with a list of #VisuUiPanel.
1675 * This window can be embedded in a container or have its own
1676 * GtkWindow. This routine get the #GtkWindow containing the
1677 * #VisuUiDockWindow in the case the dock is stand-alone. If not NULL is returned.
1678 *
1679 * Returns: (transfer none): a top-level container (usually a #GtkWindow) or NULL.
1680 */
visu_ui_dock_window_getWindow(VisuUiDockWindow * dock)1681 GtkWidget* visu_ui_dock_window_getWindow(VisuUiDockWindow *dock)
1682 {
1683 g_return_val_if_fail(dock, (GtkWidget*)0);
1684
1685 if (dock->window)
1686 return dock->window;
1687 else
1688 return GTK_WIDGET(visu_ui_main_class_getCurrentPanel());
1689 }
1690 /**
1691 * visu_ui_dock_window_setSize:
1692 * @dock: a #VisuUiDockWindow object ;
1693 * @width: the requested width ;
1694 * @height: the requested height.
1695 *
1696 * Change the size of the given #VisuUiDockWindow. The size is possibly
1697 * adapted to avoid been out of screen.
1698 */
visu_ui_dock_window_setSize(VisuUiDockWindow * dock,guint width,guint height)1699 void visu_ui_dock_window_setSize(VisuUiDockWindow *dock, guint width, guint height)
1700 {
1701 GdkScreen *screen;
1702 gint widthScreen, heightScreen;
1703 gint widthSet, heightSet;
1704
1705 g_return_if_fail(dock && dock->window);
1706 g_return_if_fail(dock != visu_ui_panel_class_getCommandPanel());
1707
1708 /* Before setting (width, height), we check that it is coherent with
1709 the screen size. */
1710 if (gtk_widget_is_drawable(dock->window))
1711 screen = gdk_window_get_screen
1712 (GDK_WINDOW(gtk_widget_get_window(dock->window)));
1713 else
1714 screen = gdk_screen_get_default();
1715 #if GTK_MAJOR_VERSION < 3 || (GTK_MAJOR_VERSION == 3 && GTK_MINOR_VERSION < 22)
1716 widthScreen = gdk_screen_get_width(screen);
1717 heightScreen = gdk_screen_get_height(screen);
1718 #else
1719 (void)screen;
1720 widthScreen = 10240;
1721 heightScreen = 10240;
1722 #endif
1723
1724 widthSet = ((gint)width > widthScreen)?widthScreen:(gint)width;
1725 heightSet = ((gint)height > heightScreen)?heightScreen:(gint)height;
1726 if (widthSet < 0) widthSet = 50;
1727 if (heightSet < 0) heightSet = 50;
1728 DBG_fprintf(stderr, "Gtk VisuUiPanel: set window (%s) size %dx%d.\n",
1729 dock->name, widthSet, heightSet);
1730 gtk_window_resize(GTK_WINDOW(dock->window), widthSet, heightSet);
1731 }
1732 /**
1733 * visu_ui_dock_window_setPosition:
1734 * @dock: a #VisuUiDockWindow object ;
1735 * @x: the requested x position ;
1736 * @y: the requested y position.
1737 *
1738 * Change the position of the given #VisuUiDockWindow. The position is possibly
1739 * adapted to avoid been out of screen.
1740 */
visu_ui_dock_window_setPosition(VisuUiDockWindow * dock,guint x,guint y)1741 void visu_ui_dock_window_setPosition(VisuUiDockWindow *dock, guint x, guint y)
1742 {
1743 GdkScreen *screen;
1744 gint xScreen, yScreen;
1745 gint xPosition, yPosition;
1746 gint width, height;
1747
1748 g_return_if_fail(dock && dock->window);
1749 g_return_if_fail(dock != visu_ui_panel_class_getCommandPanel());
1750
1751 /* Before setting (x, y), we check that it is coherent with
1752 the screen definition. */
1753 if (gtk_widget_is_drawable(dock->window))
1754 screen = gdk_window_get_screen
1755 (GDK_WINDOW(gtk_widget_get_window(dock->window)));
1756 else
1757 screen = gdk_screen_get_default();
1758 #if GTK_MAJOR_VERSION < 3 || (GTK_MAJOR_VERSION == 3 && GTK_MINOR_VERSION < 22)
1759 xScreen = gdk_screen_get_width(screen);
1760 yScreen = gdk_screen_get_height(screen);
1761 #else
1762 (void)screen;
1763 xScreen = 10240;
1764 yScreen = 10240;
1765 #endif
1766 gtk_window_get_size(GTK_WINDOW(dock->window), &width, &height);
1767
1768 xPosition = ((gint)x + width > xScreen)?xScreen - width:(gint)x;
1769 yPosition = ((gint)y + height > yScreen)?yScreen - height:(gint)y;
1770 if (xPosition < 0) xPosition = 0;
1771 if (yPosition < 0) yPosition = 0;
1772 DBG_fprintf(stderr, "Gtk VisuUiPanel: set window (%s) position %dx%d.\n",
1773 dock->name, xPosition, yPosition);
1774 gtk_window_move(GTK_WINDOW(dock->window), xPosition, yPosition);
1775 }
1776 /**
1777 * visu_ui_dock_window_setVisibility:
1778 * @dock: a #VisuUiDockWindow object ;
1779 * @visible: a boolean.
1780 *
1781 * Change the visibility of a #VisuUiDockWindow. If hidden, the dock is
1782 * added to the list of hidden #VisuUiDockWindow that can be shown again
1783 * using the pop-up menu on every visible #VisuUiDockWindow. The 'Main' dock
1784 * window can not be hidden.
1785 */
visu_ui_dock_window_setVisibility(VisuUiDockWindow * dock,gboolean visible)1786 void visu_ui_dock_window_setVisibility(VisuUiDockWindow *dock, gboolean visible)
1787 {
1788 g_return_if_fail(dock && dock->window);
1789 g_return_if_fail(dock != visu_ui_panel_class_getCommandPanel());
1790
1791 dock->show = visible;
1792 if (!visible)
1793 gtk_widget_hide(dock->window);
1794 else
1795 gtk_widget_show(dock->window);
1796 }
1797
onEntryTabview(VisuConfigFile * obj _U_,VisuConfigFileEntry * entry _U_,VisuUiPanelClass * klass _U_)1798 static void onEntryTabview(VisuConfigFile *obj _U_, VisuConfigFileEntry *entry _U_, VisuUiPanelClass *klass _U_)
1799 {
1800 visu_ui_panel_class_setHeaderVisibility(_tabView);
1801 }
1802 /* These functions write all the element list to export there associated resources. */
exportParameters(GString * data,VisuData * dataObj _U_)1803 static void exportParameters(GString *data, VisuData *dataObj _U_)
1804 {
1805 g_string_append_printf(data, "# %s\n", DESC_PARAMETER_TABVIEW_CONFIG);
1806 g_string_append_printf(data, "%s[gtk]: %d\n\n", FLAG_PARAMETER_TABVIEW_CONFIG,
1807 local_class->showHeader);
1808 }
1809