From beb69108d4efcebc5a6d70d0de6bdc9ea8026960 Mon Sep 17 00:00:00 2001 From: Cyrille Bagard Date: Tue, 9 Jul 2024 22:52:43 +0200 Subject: Rename some files. --- src/gtkext/Makefile.am | 2 - src/gtkext/dockstation.c | 467 ++++++++++++++++++ src/gtkext/dockstation.h | 97 ++++ src/gtkext/grid.c | 1143 +++++++++++++++++++++++++++++++++++++++++++ src/gtkext/grid.h | 85 ++++ src/gtkext/gtkdockstation.c | 467 ------------------ src/gtkext/gtkdockstation.h | 97 ---- src/gtkext/panel-int.h | 138 ++++++ src/gtkext/panel.c | 1119 ++++++++++++++++++++++++++++++++++++++++++ src/gtkext/panel.h | 112 +++++ src/gtkext/tiledgrid.c | 1143 ------------------------------------------- src/gtkext/tiledgrid.h | 85 ---- src/gui/Makefile.am | 2 - src/gui/panel-int.h | 138 ------ src/gui/panel.c | 1119 ------------------------------------------ src/gui/panel.h | 112 ----- 16 files changed, 3161 insertions(+), 3165 deletions(-) create mode 100644 src/gtkext/dockstation.c create mode 100644 src/gtkext/dockstation.h create mode 100644 src/gtkext/grid.c create mode 100644 src/gtkext/grid.h delete mode 100644 src/gtkext/gtkdockstation.c delete mode 100644 src/gtkext/gtkdockstation.h create mode 100644 src/gtkext/panel-int.h create mode 100644 src/gtkext/panel.c create mode 100644 src/gtkext/panel.h delete mode 100644 src/gtkext/tiledgrid.c delete mode 100644 src/gtkext/tiledgrid.h delete mode 100644 src/gui/panel-int.h delete mode 100644 src/gui/panel.c delete mode 100644 src/gui/panel.h diff --git a/src/gtkext/Makefile.am b/src/gtkext/Makefile.am index c9445e6..b147f29 100644 --- a/src/gtkext/Makefile.am +++ b/src/gtkext/Makefile.am @@ -13,7 +13,6 @@ libgtkext_la_SOURCES = \ gtkblockdisplay.h gtkblockdisplay.c \ gtkdockable-int.h \ gtkdockable.h gtkdockable.c \ - gtkdockstation.h gtkdockstation.c \ gtkgraphdisplay.h gtkgraphdisplay.c \ gtkstatusstack.h gtkstatusstack.c \ hexdisplay.h hexdisplay.c \ @@ -21,7 +20,6 @@ libgtkext_la_SOURCES = \ named.h named.c \ resources.h resources.c \ support.h support.c \ - tiledgrid.h tiledgrid.c \ tmgt.h tmgt.c libgtkext_la_LIBADD = \ diff --git a/src/gtkext/dockstation.c b/src/gtkext/dockstation.c new file mode 100644 index 0000000..1757542 --- /dev/null +++ b/src/gtkext/dockstation.c @@ -0,0 +1,467 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * gtkdockstation.c - manipulation et l'affichage de composants rassemblés + * + * Copyright (C) 2012-2019 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Chrysalide. If not, see . + */ + + +#include "gtkdockstation.h" + + +#include +#include + + +#include "easygtk.h" +#include "../core/params.h" +#include "../common/extstr.h" +#include "../glibext/chrysamarshal.h" + + + +/* Procède à l'initialisation de l'afficheur concentré. */ +static void gtk_dock_station_class_init(GtkDockStationClass *); + +/* Procède à l'initialisation du support d'affichage concentré. */ +static void gtk_dock_station_init(GtkDockStation *); + +/* Met à jour le titre du support de panneaux concentrés. */ +static gboolean gtk_dock_station_switch_panel(GtkNotebook *, gpointer *, guint, GtkDockStation *); + + + + +/* Révèle ou cache la zone de recherches. */ +static void on_toggle_revealer(GtkToggleButton *, GtkDockStation *); + +/* Demande l'apparition d'un menu pour inclure des composants. */ +static void on_click_for_menu(GtkButton *, GtkDockStation *); + +/* Demande la disparition du composant courant. */ +static void on_click_for_close(GtkButton *, GtkDockStation *); + + + + + + +/* Détermine le type du composant d'affichage concentré. */ +G_DEFINE_TYPE(GtkDockStation, gtk_dock_station, GTK_TYPE_NOTEBOOK) + + +/****************************************************************************** +* * +* Paramètres : class = classe GTK à initialiser. * +* * +* Description : Procède à l'initialisation de l'afficheur concentré. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void gtk_dock_station_class_init(GtkDockStationClass *class) +{ + g_signal_new("dock-widget", + GTK_TYPE_DOCK_STATION, + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET(GtkDockStationClass, dock_widget), + NULL, NULL, + g_cclosure_marshal_VOID__OBJECT, + G_TYPE_NONE, 1, GTK_TYPE_WIDGET); + + g_signal_new("undock-widget", + GTK_TYPE_DOCK_STATION, + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET(GtkDockStationClass, undock_widget), + NULL, NULL, + g_cclosure_marshal_VOID__OBJECT, + G_TYPE_NONE, 1, GTK_TYPE_WIDGET); + + g_signal_new("switch-widget", + GTK_TYPE_DOCK_STATION, + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET(GtkDockStationClass, switch_widget), + NULL, NULL, + g_cclosure_marshal_VOID__OBJECT, + G_TYPE_NONE, 1, GTK_TYPE_WIDGET); + + g_signal_new("menu-requested", + GTK_TYPE_DOCK_STATION, + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET(GtkDockStationClass, menu_requested), + NULL, NULL, + g_cclosure_marshal_VOID__OBJECT, + G_TYPE_NONE, 1, GTK_TYPE_WIDGET); + + g_signal_new("close-requested", + GTK_TYPE_DOCK_STATION, + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET(GtkDockStationClass, close_requested), + NULL, NULL, + g_cclosure_marshal_VOID__OBJECT, + G_TYPE_NONE, 1, GTK_TYPE_WIDGET); + +} + + +/****************************************************************************** +* * +* Paramètres : station = composant GTK à initialiser. * +* * +* Description : Procède à l'initialisation du support d'affichage concentré. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void gtk_dock_station_init(GtkDockStation *station) +{ + GtkNotebook *notebook; /* Autre version du composant */ + GtkWidget *hbox; /* Division supérieure */ + GtkWidget *button; /* Bouton de contrôle */ + + notebook = GTK_NOTEBOOK(station); + + gtk_notebook_set_show_border(notebook, FALSE); + gtk_notebook_set_scrollable(notebook, TRUE); + + /* Définition de la zone de contrôle */ + + hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0); + gtk_widget_set_valign(hbox, GTK_ALIGN_CENTER); + gtk_widget_set_margin_end(hbox, 8); + gtk_widget_show(hbox); + + button = qck_create_toggle_button_with_named_img(G_OBJECT(station), "search", + "edit-find-symbolic", GTK_ICON_SIZE_MENU, NULL, + G_CALLBACK(on_toggle_revealer), station); + gtk_button_set_relief(GTK_BUTTON(button), GTK_RELIEF_NONE); + gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0); + + button = qck_create_button_with_named_img(G_OBJECT(station), "menu", + "go-down-symbolic", GTK_ICON_SIZE_MENU, NULL, + G_CALLBACK(on_click_for_menu), station); + gtk_button_set_relief(GTK_BUTTON(button), GTK_RELIEF_NONE); + gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0); + + button = qck_create_button_with_named_img(G_OBJECT(station), "close", + "window-close-symbolic", GTK_ICON_SIZE_MENU, NULL, + G_CALLBACK(on_click_for_close), station); + gtk_button_set_relief(GTK_BUTTON(button), GTK_RELIEF_NONE); + gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0); + + gtk_notebook_set_action_widget(notebook, hbox, GTK_PACK_END); + + g_signal_connect(notebook, "switch-page", + G_CALLBACK(gtk_dock_station_switch_panel), station); + +} + + +/****************************************************************************** +* * +* Paramètres : - * +* * +* Description : Crée un nouveau composant pour support d'affichage concentré.* +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +GtkWidget *gtk_dock_station_new(void) +{ + return g_object_new(GTK_TYPE_DOCK_STATION, NULL); + +} + + +/****************************************************************************** +* * +* Paramètres : notebook = support à l'origine de la mise à jour. * +* page = onglet mis en avant. * +* index = indice de l'onglet actuellement actif. * +* station = conteneur de gestion supérieur. * +* * +* Description : Met à jour le titre du support de panneaux concentrés. * +* * +* Retour : TRUE ? * +* * +* Remarques : - * +* * +******************************************************************************/ + +static gboolean gtk_dock_station_switch_panel(GtkNotebook *notebook, gpointer *page, guint index, GtkDockStation *station) +{ + GtkWidget *widget; /* Panneau concerné */ + GtkDockable *dockable; /* Elément encapsulé */ + GtkWidget *button; /* Bouton de contrôle */ + + widget = gtk_notebook_get_nth_page(notebook, index); + + dockable = GTK_DOCKABLE(g_object_get_data(G_OBJECT(widget), "dockable")); + + /* Mise à jour des boutons utilisables */ + + button = GTK_WIDGET(g_object_get_data(G_OBJECT(station), "search")); + + if (gtk_dockable_can_search(dockable)) + gtk_widget_show(button); + else + gtk_widget_hide(button); + + /* Remontée du changement d'onglet */ + + g_signal_emit_by_name(station, "switch-widget", widget); + + return TRUE; + +} + + +/****************************************************************************** +* * +* Paramètres : station = plateforme GTK à compléter. * +* dockable = nouvel élément à intégrer. * +* * +* Description : Ajoute un paquet d'informations à l'affichage centralisé. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ +#include "gtkdisplaypanel.h" +#include "../gui/panels/history.h" +void gtk_dock_station_add_dockable(GtkDockStation *station, GtkDockable *dockable) +{ + GtkWidget *widget; /* Composant GTK à intégrer */ + char *name; /* Nom à donner à l'onglet */ + char *desc; /* Description à y associer */ + int max; /* Taille maximale des titres */ + GtkWidget *label; /* Etiquette d'onglet */ + GtkNotebook *notebook; /* Autre version du composant */ + + + + + + + + /* Récupération des éléments utiles */ + + widget = gtk_dockable_build_widget(dockable); + + //widget = gtk_button_new_with_label("123"); + gtk_widget_show(widget); + + + g_object_set_data(G_OBJECT(widget), "dockable", dockable); + + name = gtk_dockable_get_name(dockable); + desc = gtk_dockable_get_desc(dockable); + + /* Mise en place de la page */ + + if (!g_generic_config_get_value(get_main_configuration(), MPK_ELLIPSIS_TAB, &max)) + max = -1; + + name = ellipsis(name, max); + label = qck_create_label(NULL, NULL, name); + free(name); + + notebook = GTK_NOTEBOOK(station); + + if (gtk_notebook_get_n_pages(notebook) > 0) + g_signal_handlers_disconnect_by_func(notebook, + G_CALLBACK(gtk_dock_station_switch_panel), station); + + gtk_notebook_append_page(notebook, widget, label); + + gtk_widget_set_tooltip_text(label, desc); + + free(desc); + + if (gtk_notebook_get_n_pages(notebook) > 1) + g_signal_connect(notebook, "switch-page", + G_CALLBACK(gtk_dock_station_switch_panel), station); + + /* Lancement des mises à jour */ + + if (gtk_notebook_get_n_pages(notebook) > 1) + gtk_notebook_set_current_page(notebook, -1); + + //g_signal_emit_by_name(station, "dock-widget", widget); + +} + + +/****************************************************************************** +* * +* Paramètres : station = plateforme GTK à compléter. * +* widget = nouvel élément à intégrer. * +* * +* Description : Change le contenu de l'onglet courant uniquement. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void gtk_dock_panel_change_active_widget(GtkDockStation *station, GtkWidget *widget) +{ + GtkNotebook *notebook; /* Autre version du composant */ + gint index; /* Indice de l'onglet actif */ + GtkWidget *old; /* Ancien composant */ + GtkWidget *label; /* Etiquette d'onglet */ + char *str; /* Titre des prochaines fois */ + + notebook = GTK_NOTEBOOK(station); + + index = gtk_notebook_get_current_page(notebook); + + g_signal_handlers_disconnect_by_func(notebook, + G_CALLBACK(gtk_dock_station_switch_panel), station); + + old = gtk_notebook_get_nth_page(notebook, index); + label = gtk_notebook_get_tab_label(notebook, old); + + g_object_ref(G_OBJECT(label)); + str = g_object_get_data(G_OBJECT(old), "title"); + + gtk_notebook_remove_page(notebook, index); + gtk_notebook_insert_page(notebook, widget, label, index); + + g_object_unref(G_OBJECT(label)); + g_object_set_data(G_OBJECT(widget), "title", str); + + gtk_notebook_set_current_page(notebook, index); + + g_signal_connect(notebook, "switch-page", + G_CALLBACK(gtk_dock_station_switch_panel), station); + +} + + +/****************************************************************************** +* * +* Paramètres : station = plateforme GTK à compléter. * +* dockable = élément existant à retirer. * +* * +* Description : Retire un paquet d'informations de l'affichage centralisé. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void gtk_dock_station_remove_dockable(GtkDockStation *station, GtkDockable *dockable) +{ + GtkNotebook *notebook; /* Autre version du composant */ + GtkWidget *widget; /* Composant GTK à retirer */ + gint index; /* Indice de l'onglet visé */ + + notebook = GTK_NOTEBOOK(station); + + widget = gtk_dockable_decompose(dockable, NULL); + + index = gtk_notebook_page_num(notebook, widget); + + gtk_notebook_remove_page(notebook, index); + +} + + +/****************************************************************************** +* * +* Paramètres : button = bouton à l'origine de la procédure. * +* station = station d'accueil pour différents composants. * +* * +* Description : Révèle ou cache la zone de recherches. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void on_toggle_revealer(GtkToggleButton *button, GtkDockStation *station) +{ + GtkNotebook *notebook; /* Autre version du composant */ + gint index; /* Indice de l'onglet courant */ + GtkWidget *widget; /* Panneau concerné */ + GtkDockable *dockable; /* Elément encapsulé */ + + notebook = GTK_NOTEBOOK(station); + + index = gtk_notebook_get_current_page(notebook); + widget = gtk_notebook_get_nth_page(notebook, index); + + dockable = GTK_DOCKABLE(g_object_get_data(G_OBJECT(widget), "dockable")); + + gtk_dockable_toggle_revealer(dockable, widget, gtk_toggle_button_get_active(button)); + +} + + +/****************************************************************************** +* * +* Paramètres : button = bouton à l'origine de la procédure. * +* station = station d'accueil pour différents composants. * +* * +* Description : Demande l'apparition d'un menu pour inclure des composants. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void on_click_for_menu(GtkButton *button, GtkDockStation *station) +{ + g_signal_emit_by_name(station, "menu-requested", button); + +} + + +/****************************************************************************** +* * +* Paramètres : button = bouton à l'origine de la procédure. * +* station = station d'accueil pour différents composants. * +* * +* Description : Demande la disparition du composant courant. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void on_click_for_close(GtkButton *button, GtkDockStation *station) +{ + g_signal_emit_by_name(station, "close-requested", button); + +} diff --git a/src/gtkext/dockstation.h b/src/gtkext/dockstation.h new file mode 100644 index 0000000..f286c1c --- /dev/null +++ b/src/gtkext/dockstation.h @@ -0,0 +1,97 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * gtkdockstation.h - prototypes pour la manipulation et l'affichage de composants rassemblés + * + * Copyright (C) 2012-2018 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Chrysalide. If not, see . + */ + + +#ifndef _GTKEXT_GTKDOCKSTATION_H +#define _GTKEXT_GTKDOCKSTATION_H + + +#include + + +#include "gtkdockable.h" + + + +//G_BEGIN_DECLS + + +#define GTK_TYPE_DOCK_STATION (gtk_dock_station_get_type()) +#define GTK_DOCK_STATION(obj) G_TYPE_CHECK_INSTANCE_CAST(obj, gtk_dock_station_get_type (), GtkDockStation) +#define GTK_DOCK_STATION_CLASS(klass) G_TYPE_CHECK_CLASS_CAST(klass, gtk_dock_station_get_type(), GtkDockStationClass) +#define GTK_IS_DOCK_STATION(obj) G_TYPE_CHECK_INSTANCE_TYPE(obj, gtk_dock_station_get_type()) + + +/* Station de réception pour concentration d'éléments (instance) */ +typedef struct _GtkDockStation GtkDockStation; + +/* Station de réception pour concentration d'éléments (classe) */ +typedef struct _GtkDockStationClass GtkDockStationClass; + + +/* Station de réception pour concentration d'éléments (instance) */ +struct _GtkDockStation +{ + GtkNotebook parent; /* A laisser en premier */ + +}; + +/* Station de réception pour concentration d'éléments (classe) */ +struct _GtkDockStationClass +{ + GtkNotebookClass parent_class; /* A laisser en premier */ + + /* Signaux */ + + void (* dock_widget) (GtkDockStation *, GtkWidget *); + void (* undock_widget) (GtkDockStation *, GtkWidget *); + + void (* switch_widget) (GtkDockStation *, GtkWidget *); + + void (* menu_requested) (GtkDockStation *, GtkWidget *); + void (* close_requested) (GtkDockStation *, GtkWidget *); + +}; + + +/* Détermine le type du composant d'affichage concentré. */ +GType gtk_dock_station_get_type(void); + +/* Crée un nouveau composant pour support d'affichage concentré. */ +GtkWidget *gtk_dock_station_new(void); + +/* Ajoute un paquet d'informations à l'affichage centralisé. */ +void gtk_dock_station_add_dockable(GtkDockStation *, GtkDockable *); + +/* Change le contenu de l'onglet courant uniquement. */ +void gtk_dock_panel_change_active_widget(GtkDockStation *, GtkWidget *); + +/* Retire un paquet d'informations de l'affichage centralisé. */ +void gtk_dock_station_remove_dockable(GtkDockStation *, GtkDockable *); + + + +//G_END_DECLS + + + +#endif /* _GTKEXT_GTKDOCKSTATION_H */ diff --git a/src/gtkext/grid.c b/src/gtkext/grid.c new file mode 100644 index 0000000..22b2680 --- /dev/null +++ b/src/gtkext/grid.c @@ -0,0 +1,1143 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * tiledgrid.c - composant d'affichage avec des chemins vers les composants contenus + * + * Copyright (C) 2018-2019 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Chrysalide. If not, see . + */ + + +#include "tiledgrid.h" + + +#include +#include +#include +#include + + +#include "../core/logs.h" + + + +/* -------------------------- GESTION DES TUILES AFFICHEES -------------------------- */ + + +/* Informations concernant une tuile */ +typedef struct _grid_tile_t +{ + struct _grid_tile_t *parent; /* Tuile parente */ + + GtkWidget *widget; /* Support d'affichage */ + + char *path; /* Chemin d'accès */ + + struct _grid_tile_t *children[2]; /* Tuiles encastrées ou 2xNULL */ + +} grid_tile_t; + + +#define IS_LEAF_TILE(t) \ + ({ \ + bool __result; \ + __result = GTK_IS_DOCK_STATION((t)->widget); \ + assert(__result || GTK_IS_PANED((t)->widget)); \ + __result; \ + }) + + +/* Valide un chemin d'accès à une tuile. */ +static bool is_valid_tile_path(const char *); + +/* Crée une tuile finale d'affichage de panneaux. */ +static grid_tile_t *create_leaf_tile(const char *, GtkTiledGrid *); + +/* Crée une tuile intermédiaire d'affichage de panneaux. */ +static grid_tile_t *create_inter_tile(grid_tile_t *, bool, grid_tile_t *, grid_tile_t *); + +/* Supprime une tuile de la mémoire. */ +static void delete_tile(grid_tile_t *); + +/* Calcule la taille comme entre un chemin et celui d'une tuile. */ +static size_t compute_tile_score(const grid_tile_t *, const char *); + +/* Indique la tuile adaptée pour un chemin donné. */ +static grid_tile_t *find_suitable_tile(grid_tile_t **, const char *, GtkTiledGrid *); + +/* Découpe une tuile pour y insérer une zone. */ +static grid_tile_t *split_tile(grid_tile_t **, const char *, char, GtkTiledGrid *); + +/* Tente de mettre la main sur une station d'accueil. */ +static grid_tile_t *find_tile_for_widget(grid_tile_t *, GtkWidget *); + +/* Retire une moitié de tuile vide au plein profit de l'autre. */ +static void collapse_tile(grid_tile_t *, grid_tile_t *); + + + +/* --------------------------- INTERFACE DU COMPOSANT GTK --------------------------- */ + + +/* Conteneur pour un affichage en tuiles nommées (instance) */ +struct _GtkTiledGrid +{ + GtkBin parent; /* A laisser en premier */ + + grid_tile_t *tiles; /* Tuiles représentées */ + + GPanelItem *def_panel; /* Panneau principal par défaut*/ + +}; + +/* Conteneur pour un affichage en tuiles nommées (classe) */ +struct _GtkTiledGridClass +{ + GtkBinClass parent; /* A laisser en premier */ + + /* Signaux */ + + void (* station_created) (GtkTiledGrid *, GtkDockStation *, gpointer); + +}; + + +/* Initialise la classe des conteneurs d'affichage en tuiles. */ +static void gtk_tiled_grid_class_init(GtkTiledGridClass *); + +/* Initialise une instance de conteneur d'affichage en tuiles. */ +static void gtk_tiled_grid_init(GtkTiledGrid *); + +/* Supprime toutes les références externes. */ +static void gtk_tiled_grid_dispose(GtkTiledGrid *); + +/* Procède à la libération totale de la mémoire. */ +static void gtk_tiled_grid_finalize(GtkTiledGrid *); + + + +/* ---------------------------------------------------------------------------------- */ +/* GESTION DES TUILES AFFICHEES */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +* * +* Paramètres : path = chemin destiné à sélectionner une tuile. * +* * +* Description : Valide un chemin d'accès à une tuile. * +* * +* Retour : true si le chemin est utilisable, false sinon. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool is_valid_tile_path(const char *path) +{ + bool result; /* Bilan à retourner */ + size_t len; /* Taille du chemin */ + size_t i; /* Boucle de parcours */ + char c; /* Caractère de chemin analysé */ + + /** + * M[NESWnesw]* + */ + + len = strlen(path); + + result = (len >= 1); + + if (result) + result = (path[0] == 'M'); + + for (i = 1; i < len && result; i++) + { + c = path[i]; + + if (c == '\0') + break; + + result = (c == 'N' || c == 'n' + || c == 'E' || c == 'e' + || c == 'S' || c == 's' + || c == 'W' || c == 'w'); + + } + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : path = chemin d'accès à la future tuile. * +* Paramètres : tgrid = conteneur d'affichage en tuiles à manipuler. * +* * +* Description : Crée une tuile finale d'affichage de panneaux. * +* * +* Retour : Structure mise en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static grid_tile_t *create_leaf_tile(const char *path, GtkTiledGrid *tgrid) +{ + grid_tile_t *result; /* Structure à retourner */ + + result = (grid_tile_t *)malloc(sizeof(grid_tile_t)); + + result->parent = NULL; + + result->widget = gtk_dock_station_new(); + gtk_widget_show(result->widget); + + result->path = strdup(path); + + result->children[0] = NULL; + result->children[1] = NULL; + + g_signal_emit_by_name(tgrid, "station-created", result->widget); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : parent = tuile parente ou NULL si aucune. * +* horiz = indique le type d'orientation désiré. * +* first = première tuile à intégrer. * +* second = seconde tuile à intégrer. * +* * +* Description : Crée une tuile intermédiaire d'affichage de panneaux. * +* * +* Retour : Structure mise en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static grid_tile_t *create_inter_tile(grid_tile_t *parent, bool horiz, grid_tile_t *first, grid_tile_t *second) +{ + grid_tile_t *result; /* Structure à retourner */ + GtkWidget *container; /* Conteneur à vider */ + + result = (grid_tile_t *)malloc(sizeof(grid_tile_t)); + + result->parent = parent; + + if (horiz) + result->widget = gtk_paned_new(GTK_ORIENTATION_HORIZONTAL); + else + result->widget = gtk_paned_new(GTK_ORIENTATION_VERTICAL); + + gtk_widget_show(result->widget); + + result->path = NULL; + + result->children[0] = first; + result->children[1] = second; + + /* Changement de propriétaire */ + + container = gtk_widget_get_parent(first->widget); + + if (container != NULL) + gtk_container_remove(GTK_CONTAINER(container), first->widget); + + g_object_ref(G_OBJECT(first->widget)); + gtk_paned_pack1(GTK_PANED(result->widget), first->widget, TRUE, FALSE); + + container = gtk_widget_get_parent(second->widget); + + if (container != NULL) + gtk_container_remove(GTK_CONTAINER(container), second->widget); + + g_object_ref(G_OBJECT(second->widget)); + gtk_paned_pack2(GTK_PANED(result->widget), second->widget, TRUE, FALSE); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : tile = tuile à supprimer. * +* * +* Description : Supprime une tuile de la mémoire. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void delete_tile(grid_tile_t *tile) +{ + if (!IS_LEAF_TILE(tile)) + { + delete_tile(tile->children[0]); + delete_tile(tile->children[1]); + } + + else + free(tile->path); + + g_object_unref(G_OBJECT(tile->widget)); + + free(tile); + +} + + +/****************************************************************************** +* * +* Paramètres : tile = tuile à analyser. * +* path = chemin final complet recherché. * +* * +* Description : Calcule la taille comme entre un chemin et celui d'une tuile.* +* * +* Retour : Quantité de caractères communs. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static size_t compute_tile_score(const grid_tile_t *tile, const char *path) +{ + size_t result; /* Nombre de points à renvoyer */ + size_t max; /* Taille du chemin de la tuile*/ + size_t i; /* Boucle de parcours */ + size_t score_0; /* Score du sous-élément #1 */ + size_t score_1; /* Score du sous-élément #2 */ + + if (IS_LEAF_TILE(tile)) + { + max = strlen(tile->path); + + if (strlen(path) < max) + result = 0; + + else + { + result = 0; + + for (i = 0; i < max; i++) + { + if (tolower((unsigned char)tile->path[i]) == tolower((unsigned char)path[i])) + result++; + else + break; + } + + } + + } + else + { + score_0 = compute_tile_score(tile->children[0], path); + score_1 = compute_tile_score(tile->children[1], path); + + result = score_0 > score_1 ? score_0 : score_1; + + } + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : tile = tuile ou NULL si aucune. [OUT] * +* path = chemin d'accès à la tuile visée. * +* tgrid = conteneur d'affichage en tuiles à manipuler. * +* * +* Description : Indique la tuile adaptée pour un chemin donné. * +* * +* Retour : Structure d'acceuil à disposition. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static grid_tile_t *find_suitable_tile(grid_tile_t **tile, const char *path, GtkTiledGrid *tgrid) +{ + grid_tile_t *result; /* Structure à renvoyer */ + size_t best_len; /* Taille du chemin associé */ + size_t score_0; /* Score du sous-élément #1 */ + size_t score_1; /* Score du sous-élément #2 */ + char *sub_path; /* Nouvelle tentative d'accès */ + grid_tile_t **best; /* Direction à prendre */ + unsigned char next; /* Prochaine étape */ + + /* Cas d'école : appel initial */ + if (*tile == NULL) + { + assert(path[0] == 'M' && path[1] == '\0'); + + result = create_leaf_tile("M", tgrid); + *tile = result; + + } + + else + { + if (IS_LEAF_TILE(*tile)) + { + best_len = compute_tile_score(*tile, path); + + assert(best_len > 0); + + if (path[best_len] == '\0') + result = *tile; + + else + result = split_tile(tile, path, path[best_len], tgrid); + + } + + else + { + score_0 = compute_tile_score((*tile)->children[0], path); + score_1 = compute_tile_score((*tile)->children[1], path); + + assert(score_0 > 0 || score_0 > 0); + + if (score_0 == score_1) + { + sub_path = strndup(path, score_0); + + score_0 = compute_tile_score((*tile)->children[0], sub_path); + score_1 = compute_tile_score((*tile)->children[1], sub_path); + + free(sub_path); + + } + + if (score_0 == score_1) + result = split_tile(tile, path, path[score_0], tgrid); + + else + { + if (score_0 > score_1) + { + best = &(*tile)->children[0]; + best_len = score_0; + } + else + { + best = &(*tile)->children[1]; + best_len = score_1; + } + + /** + * Si on vient de tomber une feuille, trois cas de figure : + * - soit c'est elle qui est visée. + * - soit on veut la diviser. + * - soit on veut la diviser en englobant ses voisines. + */ + + if (IS_LEAF_TILE(*best)) + { + assert(best_len <= strlen(path)); + + next = path[best_len]; + + /* Premier cas */ + if (next == '\0') + result = *best; + + else + { + /* Second cas */ + if (islower(next)) + result = find_suitable_tile(best, path, tgrid); + + /* Troisième cas */ + else + result = split_tile(tile, path, next, tgrid); + + } + + } + + else + result = find_suitable_tile(best, path, tgrid); + + } + + } + + } + + assert(IS_LEAF_TILE(result)); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : tile = tuile à découper en deux. [OUT] * +* path = chemin d'accès à la future tuile. * +* endpoint = désignation de la zone représentée. * +* tgrid = conteneur d'affichage en tuiles à manipuler. * +* * +* Description : Découpe une tuile pour y insérer une zone. * +* * +* Retour : Structure fille mise en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static grid_tile_t *split_tile(grid_tile_t **tile, const char *path, char endpoint, GtkTiledGrid *tgrid) +{ + grid_tile_t *result; /* Création à retourner */ + GtkWidget *container; /* Conteneur à vider */ + grid_tile_t *new; /* Nouvelle tuile intermédiaire*/ + + container = gtk_widget_get_parent((*tile)->widget); + + /* Création */ + + result = create_leaf_tile(path, tgrid); + + /* Encapsulation */ + + switch (endpoint) + { + case 'N': + case 'n': + new = create_inter_tile((*tile)->parent, false, result, *tile); + break; + + case 'E': + case 'e': + new = create_inter_tile((*tile)->parent, true, *tile, result); + break; + + case 'S': + case 's': + new = create_inter_tile((*tile)->parent, false, *tile, result); + break; + + case 'W': + case 'w': + new = create_inter_tile((*tile)->parent, true, result, *tile); + break; + + default: + assert(false); + new = NULL; + break; + + } + + /* Connexions */ + + *tile = new; + + result->parent = new; + + if (container != NULL) + { + g_object_ref(G_OBJECT(new->widget)); + gtk_container_add(GTK_CONTAINER(container), new->widget); + } + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : tile = tuile parente, prochaine victime de promotion. * +* side = côté de tuile amené à disparaître. * +* * +* Description : Retire une moitié de tuile vide au plein profit de l'autre. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void collapse_tile(grid_tile_t *tile, grid_tile_t *side) +{ + grid_tile_t *promoted; /* Tuile à faire remonter */ + GtkWidget *container; /* Conteneur à vider */ + + assert(!IS_LEAF_TILE(tile)); + + /* Sélection du remplaçant */ + + if (side == tile->children[0]) + promoted = tile->children[1]; + else + promoted = tile->children[0]; + + /* Etablissement d'une place nette */ + + gtk_container_remove(GTK_CONTAINER(tile->widget), promoted->widget); + + container = gtk_widget_get_parent(tile->widget); + gtk_container_remove(GTK_CONTAINER(container), tile->widget); + + delete_tile(side); + + /* Promotion effective */ + + tile->widget = promoted->widget; + + tile->path = promoted->path; + + tile->children[0] = promoted->children[0]; + tile->children[1] = promoted->children[1]; + + g_object_ref(G_OBJECT(promoted->widget)); + gtk_container_add(GTK_CONTAINER(container), tile->widget); + + free(promoted); + +} + + +/****************************************************************************** +* * +* Paramètres : tile = point de départ des recherches locales. * +* widget = composant graphique à retrouver. * +* * +* Description : Tente de mettre la main sur une station d'accueil. * +* * +* Retour : Eventuelle tuile trouvée ou NULL. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static grid_tile_t *find_tile_for_widget(grid_tile_t *tile, GtkWidget *widget) +{ + grid_tile_t *result; /* Tuile à retourner */ + + if (IS_LEAF_TILE(tile)) + result = tile->widget == widget ? tile : NULL; + + else + { + result = find_tile_for_widget(tile->children[0], widget); + + if (result == NULL) + result = find_tile_for_widget(tile->children[1], widget); + + } + + return result; + +} + + + +/* ---------------------------------------------------------------------------------- */ +/* INTERFACE DU COMPOSANT GTK */ +/* ---------------------------------------------------------------------------------- */ + + +/* Détermine le type du conteneur d'affichage en tuiles nommées. */ +G_DEFINE_TYPE(GtkTiledGrid, gtk_tiled_grid, GTK_TYPE_BIN) + + +/****************************************************************************** +* * +* Paramètres : klass = classe GTK à initialiser. * +* * +* Description : Initialise la classe des conteneurs d'affichage en tuiles. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void gtk_tiled_grid_class_init(GtkTiledGridClass *klass) +{ + GObjectClass *object; /* Autre version de la classe */ + + object = G_OBJECT_CLASS(klass); + + object->dispose = (GObjectFinalizeFunc/* ! */)gtk_tiled_grid_dispose; + object->finalize = (GObjectFinalizeFunc)gtk_tiled_grid_finalize; + + g_signal_new("station-created", + GTK_TYPE_TILED_GRID, + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET(GtkTiledGridClass, station_created), + NULL, NULL, + g_cclosure_marshal_VOID__OBJECT, + G_TYPE_NONE, 1, GTK_TYPE_DOCK_STATION); + +} + + +/****************************************************************************** +* * +* Paramètres : tgrid = instance GTK à initialiser. * +* * +* Description : Initialise une instance de conteneur d'affichage en tuiles. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void gtk_tiled_grid_init(GtkTiledGrid *tgrid) +{ + tgrid->tiles = NULL; + + tgrid->def_panel = NULL; + +} + + +/****************************************************************************** +* * +* Paramètres : tgrid = instance d'objet GLib à traiter. * +* * +* Description : Supprime toutes les références externes. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void gtk_tiled_grid_dispose(GtkTiledGrid *tgrid) +{ + if (tgrid->tiles != NULL) + { + delete_tile(tgrid->tiles); + tgrid->tiles = NULL; + } + + g_clear_object(&tgrid->def_panel); + + G_OBJECT_CLASS(gtk_tiled_grid_parent_class)->dispose(G_OBJECT(tgrid)); + +} + + +/****************************************************************************** +* * +* Paramètres : tgrid = instance d'objet GLib à traiter. * +* * +* Description : Procède à la libération totale de la mémoire. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void gtk_tiled_grid_finalize(GtkTiledGrid *tgrid) +{ + G_OBJECT_CLASS(gtk_tiled_grid_parent_class)->finalize(G_OBJECT(tgrid)); + +} + + +/****************************************************************************** +* * +* Paramètres : - * +* * +* Description : Crée une nouvelle instance de conteneur avec tuiles. * +* * +* Retour : Composant GTK mis en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GtkWidget *gtk_tiled_grid_new(void) +{ + return g_object_new(GTK_TYPE_TILED_GRID, NULL); + +} + + +/****************************************************************************** +* * +* Paramètres : tgrid = conteneur d'affichage en tuiles à consulter. * +* * +* Description : Donne le panneau fourni par défaut pour la zone principale. * +* * +* Retour : Panneau d'affichage par défault ou NULL. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GPanelItem *gtk_tiled_grid_get_default_main_panel(const GtkTiledGrid *tgrid) +{ + GPanelItem *result; /* Panneau à retourner */ + + result = tgrid->def_panel; + + if (result != NULL) + g_object_ref(G_OBJECT(result)); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : tgrid = conteneur d'affichage en tuiles à modifier. * +* panel = panneau d'affichage par défault ou NULL. * +* * +* Description : Fournit le panneau par défaut pour la zone principale. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void gtk_tiled_grid_set_default_main_panel(GtkTiledGrid *tgrid, GPanelItem *panel) +{ + GtkWidget *widget; /* Composant GTK à retirer */ + GtkWidget *parent; /* Conteneur à vider */ + grid_tile_t *tile; /* Première tuile d'accueil */ + + if (tgrid->def_panel != NULL) + { + widget = gtk_dockable_build_widget(GTK_DOCKABLE(tgrid->def_panel)); + + parent = gtk_widget_get_parent(widget); + + if (parent != NULL) + gtk_container_remove(GTK_CONTAINER(parent), widget); + + g_object_unref(G_OBJECT(widget)); + + g_object_unref(G_OBJECT(tgrid->def_panel)); + + } + + tgrid->def_panel = panel; + + if (panel != NULL) + { + g_object_ref(G_OBJECT(panel)); + + if (tgrid->tiles == NULL) + gtk_tiled_grid_add(tgrid, panel); + + else + { + tile = find_suitable_tile(&tgrid->tiles, "M", tgrid); + + if (gtk_notebook_get_n_pages(GTK_NOTEBOOK(tile->widget)) == 0) + gtk_tiled_grid_add(tgrid, panel); + + } + + } + +} + + +/****************************************************************************** +* * +* Paramètres : tgrid = conteneur d'affichage en tuiles à modifier. * +* panel = panneau d'affichage à intégrer. * +* * +* Description : Incorpore un nouveau panneau dans le conteneur en tuiles. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void gtk_tiled_grid_add(GtkTiledGrid *tgrid, GPanelItem *panel) +{ + char *path; /* Chemin d'accès */ + char *name; /* Nom à donner à l'onglet */ + grid_tile_t *tile; /* Tuile d'accueil */ + + path = gtk_panel_item_class_get_path(G_PANEL_ITEM_GET_CLASS(panel)); + + if (!is_valid_tile_path(path)) + { + name = gtk_dockable_get_name(GTK_DOCKABLE(panel)); + log_variadic_message(LMT_ERROR, _("Invalid path '%s' for panel '%s'"), path, name); + free(name); + } + + else + { + tile = find_suitable_tile(&tgrid->tiles, path, tgrid); + assert(tile != NULL); + + gtk_dock_station_add_dockable(GTK_DOCK_STATION(tile->widget), GTK_DOCKABLE(panel)); + + g_panel_item_set_dock_at_startup(panel, true); + + /* Si c'est la toute première fois... */ + if (gtk_widget_get_parent(tile->widget) == NULL) + { + assert(tile == tgrid->tiles); + assert(tile->path[0] == 'M' && tile->path[1] == '\0'); + g_object_ref(G_OBJECT(tile->widget)); + gtk_container_add(GTK_CONTAINER(tgrid), tile->widget); + } + + /* Si on n'a plus besoin du panneau par défaut */ + if (tgrid->def_panel != NULL && tile->path[0] == 'M' && tile->path[1] == '\0') + { + /* Si ce n'est pas le panneau qu'on vient de rajouter...*/ + if (panel != tgrid->def_panel) + { + /* Enfin : si ce panneau par défaut est réellement en place */ + if (g_panel_item_is_docked(tgrid->def_panel)) + gtk_tiled_grid_remove(tgrid, tgrid->def_panel); + + } + + } + + } + + free(path); + +} + + +/****************************************************************************** +* * +* Paramètres : tgrid = conteneur d'affichage en tuiles à modifier. * +* panel = panneau d'affichage à supprimer. * +* * +* Description : Retire un panneau dans le conteneur en tuiles. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void gtk_tiled_grid_remove(GtkTiledGrid *tgrid, GPanelItem *panel) +{ + GtkWidget *station; /* Support courant */ + grid_tile_t *tile; /* Tuile d'accueil */ + + assert(g_panel_item_is_docked(panel)); + + gtk_dockable_decompose(GTK_DOCKABLE(panel), &station); + + tile = find_tile_for_widget(tgrid->tiles, station); + assert(tile != NULL); + + gtk_dock_station_remove_dockable(GTK_DOCK_STATION(station), GTK_DOCKABLE(panel)); + + g_panel_item_set_dock_at_startup(panel, false); + + if (gtk_notebook_get_n_pages(GTK_NOTEBOOK(station)) == 0) + { + /* Si le panneau par défaut devient nécessaire */ + if (tgrid->def_panel != NULL && tile->path[0] == 'M' && tile->path[1] == '\0') + gtk_tiled_grid_add(tgrid, tgrid->def_panel); + + else + { + /* La racine est concernée ! */ + if (tile->parent == NULL) + { + assert(tile == tgrid->tiles); + + g_object_ref(G_OBJECT(tile->widget)); + gtk_container_remove(GTK_CONTAINER(tgrid), tile->widget); + + delete_tile(tile); + tgrid->tiles = NULL; + + } + + else + collapse_tile(tile->parent, tile); + + } + + } + +} + + +/****************************************************************************** +* * +* Paramètres : tgrid = conteneur d'affichage en tuiles à consulter. * +* station = station d'accueil à retrouver. * +* * +* Description : Indique le chemin correspondant à une station intégrée. * +* * +* Retour : Copie de chemin trouvé, à libérer ensuite, ou NULL si échec. * +* * +* Remarques : - * +* * +******************************************************************************/ + +char *gtk_tiled_grid_get_path_for_station(const GtkTiledGrid *tgrid, GtkDockStation *station) +{ + char *result; /* Chemin d'accès à renvoyer */ + grid_tile_t *tile; /* Tuile d'accueil */ + + tile = find_tile_for_widget(tgrid->tiles, GTK_WIDGET(station)); + + if (tile == NULL) + result = NULL; + + else + result = strdup(tile->path); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : tgrid = conteneur d'affichage en tuiles à mettre à jour. * +* config = configuration à consulter. * +* * +* Description : Replace les positions des séparateurs de tuiles. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void gtk_tiled_grid_restore_positions(const GtkTiledGrid *tgrid, GGenConfig *config) +{ + + void visit_tiles_for_restoring(grid_tile_t *tile, const char *vpath) + { + GtkOrientation orientation; /* Direction de la tuile */ + char hint; /* Inutile donc indispensable */ + char *key; /* Clef d'accès à un paramètre */ + gint position; /* Nouvelle position de barre */ + size_t i; /* Boucle de parcours */ + char *child_key; /* Clef d'accès des suivants */ + + if (!IS_LEAF_TILE(tile)) + { + orientation = gtk_orientable_get_orientation(GTK_ORIENTABLE(tile->widget)); + + hint = orientation == GTK_ORIENTATION_HORIZONTAL ? 'h' : 'v'; + + asprintf(&key, "%s%c", vpath, hint); + + if (g_generic_config_get_value(config, key, &position)) + gtk_paned_set_position(GTK_PANED(tile->widget), position); + + for (i = 0; i < 2; i++) + { + asprintf(&child_key, "%s%zu", key, i); + + visit_tiles_for_restoring(tile->children[i], child_key); + + free(child_key); + + } + + free(key); + + } + + } + + + visit_tiles_for_restoring(tgrid->tiles, "gui.panels.positions.R"); + +} + + +/****************************************************************************** +* * +* Paramètres : tgrid = conteneur d'affichage en tuiles à consulter. * +* config = configuration à mettre à jour. * +* * +* Description : Sauvegarde les positions des séparateurs de tuiles. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void gtk_tiled_grid_save_positions(const GtkTiledGrid *tgrid, GGenConfig *config) +{ + + void visit_tiles_for_saving(grid_tile_t *tile, const char *vpath) + { + GtkOrientation orientation; /* Direction de la tuile */ + char hint; /* Inutile donc indispensable */ + char *key; /* Clef d'accès à un paramètre */ + gint position; /* Nouvelle position de barre */ + size_t i; /* Boucle de parcours */ + char *child_key; /* Clef d'accès des suivants */ + + if (!IS_LEAF_TILE(tile)) + { + orientation = gtk_orientable_get_orientation(GTK_ORIENTABLE(tile->widget)); + + hint = orientation == GTK_ORIENTATION_HORIZONTAL ? 'h' : 'v'; + + asprintf(&key, "%s%c", vpath, hint); + + position = gtk_paned_get_position(GTK_PANED(tile->widget)); + g_generic_config_create_or_udpdate_param(config, key, CPT_INTEGER, -1, position); + + for (i = 0; i < 2; i++) + { + asprintf(&child_key, "%s%zu", key, i); + + visit_tiles_for_saving(tile->children[i], child_key); + + free(child_key); + + } + + free(key); + + } + + } + + + visit_tiles_for_saving(tgrid->tiles, "gui.panels.positions.R"); + +} diff --git a/src/gtkext/grid.h b/src/gtkext/grid.h new file mode 100644 index 0000000..539e248 --- /dev/null +++ b/src/gtkext/grid.h @@ -0,0 +1,85 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * tiledgrid.h - prototypes pour un composant d'affichage avec des chemins vers les composants contenus + * + * Copyright (C) 2018-2019 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Chrysalide. If not, see . + */ + + +#ifndef _GTKEXT_TILEDGRID_H +#define _GTKEXT_TILEDGRID_H + + +#include + + +#include "gtkdockstation.h" +#include "../glibext/configuration.h" +#include "../gui/panel.h" + + + +/* --------------------------- INTERFACE DU COMPOSANT GTK --------------------------- */ + + +#define GTK_TYPE_TILED_GRID gtk_tiled_grid_get_type() +#define GTK_TILED_GRID(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GTK_TYPE_TILED_GRID, GtkTiledGrid)) +#define GTK_IS_TILED_GRID(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), GTK_TYPE_TILED_GRID)) +#define GTK_TILED_GRID_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), GTK_TYPE_TILED_GRID, GtkTiledGridClass)) +#define GTK_IS_TILED_GRID_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), GTK_TYPE_TILED_GRID)) +#define GTK_TILED_GRID_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GTK_TYPE_TILED_GRID, GtkTiledGridClass)) + + + +/* Conteneur pour un affichage en tuiles nommées (instance) */ +typedef struct _GtkTiledGrid GtkTiledGrid; + +/* Conteneur pour un affichage en tuiles nommées (classe) */ +typedef struct _GtkTiledGridClass GtkTiledGridClass; + + +/* Détermine le type du conteneur d'affichage en tuiles nommées. */ +GType gtk_tiled_grid_get_type(void); + +/* Crée une nouvelle instance de conteneur avec tuiles. */ +GtkWidget *gtk_tiled_grid_new(void); + +/* Donne le panneau fourni par défaut pour la zone principale. */ +GPanelItem *gtk_tiled_grid_get_default_main_panel(const GtkTiledGrid *); + +/* Fournit le panneau par défaut pour la zone principale. */ +void gtk_tiled_grid_set_default_main_panel(GtkTiledGrid *, GPanelItem *); + +/* Incorpore un nouveau panneau dans le conteneur en tuiles. */ +void gtk_tiled_grid_add(GtkTiledGrid *, GPanelItem *); + +/* Retire un panneau dans le conteneur en tuiles. */ +void gtk_tiled_grid_remove(GtkTiledGrid *, GPanelItem *); + +/* Indique le chemin correspondant à une station intégrée. */ +char *gtk_tiled_grid_get_path_for_station(const GtkTiledGrid *, GtkDockStation *); + +/* Replace les positions des séparateurs de tuiles. */ +void gtk_tiled_grid_restore_positions(const GtkTiledGrid *, GGenConfig *); + +/* Sauvegarde les positions des séparateurs de tuiles. */ +void gtk_tiled_grid_save_positions(const GtkTiledGrid *, GGenConfig *); + + + +#endif /* _GTKEXT_TILEDGRID_H */ diff --git a/src/gtkext/gtkdockstation.c b/src/gtkext/gtkdockstation.c deleted file mode 100644 index 1757542..0000000 --- a/src/gtkext/gtkdockstation.c +++ /dev/null @@ -1,467 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * gtkdockstation.c - manipulation et l'affichage de composants rassemblés - * - * Copyright (C) 2012-2019 Cyrille Bagard - * - * This file is part of Chrysalide. - * - * Chrysalide is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * Chrysalide is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Chrysalide. If not, see . - */ - - -#include "gtkdockstation.h" - - -#include -#include - - -#include "easygtk.h" -#include "../core/params.h" -#include "../common/extstr.h" -#include "../glibext/chrysamarshal.h" - - - -/* Procède à l'initialisation de l'afficheur concentré. */ -static void gtk_dock_station_class_init(GtkDockStationClass *); - -/* Procède à l'initialisation du support d'affichage concentré. */ -static void gtk_dock_station_init(GtkDockStation *); - -/* Met à jour le titre du support de panneaux concentrés. */ -static gboolean gtk_dock_station_switch_panel(GtkNotebook *, gpointer *, guint, GtkDockStation *); - - - - -/* Révèle ou cache la zone de recherches. */ -static void on_toggle_revealer(GtkToggleButton *, GtkDockStation *); - -/* Demande l'apparition d'un menu pour inclure des composants. */ -static void on_click_for_menu(GtkButton *, GtkDockStation *); - -/* Demande la disparition du composant courant. */ -static void on_click_for_close(GtkButton *, GtkDockStation *); - - - - - - -/* Détermine le type du composant d'affichage concentré. */ -G_DEFINE_TYPE(GtkDockStation, gtk_dock_station, GTK_TYPE_NOTEBOOK) - - -/****************************************************************************** -* * -* Paramètres : class = classe GTK à initialiser. * -* * -* Description : Procède à l'initialisation de l'afficheur concentré. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void gtk_dock_station_class_init(GtkDockStationClass *class) -{ - g_signal_new("dock-widget", - GTK_TYPE_DOCK_STATION, - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET(GtkDockStationClass, dock_widget), - NULL, NULL, - g_cclosure_marshal_VOID__OBJECT, - G_TYPE_NONE, 1, GTK_TYPE_WIDGET); - - g_signal_new("undock-widget", - GTK_TYPE_DOCK_STATION, - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET(GtkDockStationClass, undock_widget), - NULL, NULL, - g_cclosure_marshal_VOID__OBJECT, - G_TYPE_NONE, 1, GTK_TYPE_WIDGET); - - g_signal_new("switch-widget", - GTK_TYPE_DOCK_STATION, - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET(GtkDockStationClass, switch_widget), - NULL, NULL, - g_cclosure_marshal_VOID__OBJECT, - G_TYPE_NONE, 1, GTK_TYPE_WIDGET); - - g_signal_new("menu-requested", - GTK_TYPE_DOCK_STATION, - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET(GtkDockStationClass, menu_requested), - NULL, NULL, - g_cclosure_marshal_VOID__OBJECT, - G_TYPE_NONE, 1, GTK_TYPE_WIDGET); - - g_signal_new("close-requested", - GTK_TYPE_DOCK_STATION, - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET(GtkDockStationClass, close_requested), - NULL, NULL, - g_cclosure_marshal_VOID__OBJECT, - G_TYPE_NONE, 1, GTK_TYPE_WIDGET); - -} - - -/****************************************************************************** -* * -* Paramètres : station = composant GTK à initialiser. * -* * -* Description : Procède à l'initialisation du support d'affichage concentré. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void gtk_dock_station_init(GtkDockStation *station) -{ - GtkNotebook *notebook; /* Autre version du composant */ - GtkWidget *hbox; /* Division supérieure */ - GtkWidget *button; /* Bouton de contrôle */ - - notebook = GTK_NOTEBOOK(station); - - gtk_notebook_set_show_border(notebook, FALSE); - gtk_notebook_set_scrollable(notebook, TRUE); - - /* Définition de la zone de contrôle */ - - hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0); - gtk_widget_set_valign(hbox, GTK_ALIGN_CENTER); - gtk_widget_set_margin_end(hbox, 8); - gtk_widget_show(hbox); - - button = qck_create_toggle_button_with_named_img(G_OBJECT(station), "search", - "edit-find-symbolic", GTK_ICON_SIZE_MENU, NULL, - G_CALLBACK(on_toggle_revealer), station); - gtk_button_set_relief(GTK_BUTTON(button), GTK_RELIEF_NONE); - gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0); - - button = qck_create_button_with_named_img(G_OBJECT(station), "menu", - "go-down-symbolic", GTK_ICON_SIZE_MENU, NULL, - G_CALLBACK(on_click_for_menu), station); - gtk_button_set_relief(GTK_BUTTON(button), GTK_RELIEF_NONE); - gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0); - - button = qck_create_button_with_named_img(G_OBJECT(station), "close", - "window-close-symbolic", GTK_ICON_SIZE_MENU, NULL, - G_CALLBACK(on_click_for_close), station); - gtk_button_set_relief(GTK_BUTTON(button), GTK_RELIEF_NONE); - gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0); - - gtk_notebook_set_action_widget(notebook, hbox, GTK_PACK_END); - - g_signal_connect(notebook, "switch-page", - G_CALLBACK(gtk_dock_station_switch_panel), station); - -} - - -/****************************************************************************** -* * -* Paramètres : - * -* * -* Description : Crée un nouveau composant pour support d'affichage concentré.* -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -GtkWidget *gtk_dock_station_new(void) -{ - return g_object_new(GTK_TYPE_DOCK_STATION, NULL); - -} - - -/****************************************************************************** -* * -* Paramètres : notebook = support à l'origine de la mise à jour. * -* page = onglet mis en avant. * -* index = indice de l'onglet actuellement actif. * -* station = conteneur de gestion supérieur. * -* * -* Description : Met à jour le titre du support de panneaux concentrés. * -* * -* Retour : TRUE ? * -* * -* Remarques : - * -* * -******************************************************************************/ - -static gboolean gtk_dock_station_switch_panel(GtkNotebook *notebook, gpointer *page, guint index, GtkDockStation *station) -{ - GtkWidget *widget; /* Panneau concerné */ - GtkDockable *dockable; /* Elément encapsulé */ - GtkWidget *button; /* Bouton de contrôle */ - - widget = gtk_notebook_get_nth_page(notebook, index); - - dockable = GTK_DOCKABLE(g_object_get_data(G_OBJECT(widget), "dockable")); - - /* Mise à jour des boutons utilisables */ - - button = GTK_WIDGET(g_object_get_data(G_OBJECT(station), "search")); - - if (gtk_dockable_can_search(dockable)) - gtk_widget_show(button); - else - gtk_widget_hide(button); - - /* Remontée du changement d'onglet */ - - g_signal_emit_by_name(station, "switch-widget", widget); - - return TRUE; - -} - - -/****************************************************************************** -* * -* Paramètres : station = plateforme GTK à compléter. * -* dockable = nouvel élément à intégrer. * -* * -* Description : Ajoute un paquet d'informations à l'affichage centralisé. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ -#include "gtkdisplaypanel.h" -#include "../gui/panels/history.h" -void gtk_dock_station_add_dockable(GtkDockStation *station, GtkDockable *dockable) -{ - GtkWidget *widget; /* Composant GTK à intégrer */ - char *name; /* Nom à donner à l'onglet */ - char *desc; /* Description à y associer */ - int max; /* Taille maximale des titres */ - GtkWidget *label; /* Etiquette d'onglet */ - GtkNotebook *notebook; /* Autre version du composant */ - - - - - - - - /* Récupération des éléments utiles */ - - widget = gtk_dockable_build_widget(dockable); - - //widget = gtk_button_new_with_label("123"); - gtk_widget_show(widget); - - - g_object_set_data(G_OBJECT(widget), "dockable", dockable); - - name = gtk_dockable_get_name(dockable); - desc = gtk_dockable_get_desc(dockable); - - /* Mise en place de la page */ - - if (!g_generic_config_get_value(get_main_configuration(), MPK_ELLIPSIS_TAB, &max)) - max = -1; - - name = ellipsis(name, max); - label = qck_create_label(NULL, NULL, name); - free(name); - - notebook = GTK_NOTEBOOK(station); - - if (gtk_notebook_get_n_pages(notebook) > 0) - g_signal_handlers_disconnect_by_func(notebook, - G_CALLBACK(gtk_dock_station_switch_panel), station); - - gtk_notebook_append_page(notebook, widget, label); - - gtk_widget_set_tooltip_text(label, desc); - - free(desc); - - if (gtk_notebook_get_n_pages(notebook) > 1) - g_signal_connect(notebook, "switch-page", - G_CALLBACK(gtk_dock_station_switch_panel), station); - - /* Lancement des mises à jour */ - - if (gtk_notebook_get_n_pages(notebook) > 1) - gtk_notebook_set_current_page(notebook, -1); - - //g_signal_emit_by_name(station, "dock-widget", widget); - -} - - -/****************************************************************************** -* * -* Paramètres : station = plateforme GTK à compléter. * -* widget = nouvel élément à intégrer. * -* * -* Description : Change le contenu de l'onglet courant uniquement. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void gtk_dock_panel_change_active_widget(GtkDockStation *station, GtkWidget *widget) -{ - GtkNotebook *notebook; /* Autre version du composant */ - gint index; /* Indice de l'onglet actif */ - GtkWidget *old; /* Ancien composant */ - GtkWidget *label; /* Etiquette d'onglet */ - char *str; /* Titre des prochaines fois */ - - notebook = GTK_NOTEBOOK(station); - - index = gtk_notebook_get_current_page(notebook); - - g_signal_handlers_disconnect_by_func(notebook, - G_CALLBACK(gtk_dock_station_switch_panel), station); - - old = gtk_notebook_get_nth_page(notebook, index); - label = gtk_notebook_get_tab_label(notebook, old); - - g_object_ref(G_OBJECT(label)); - str = g_object_get_data(G_OBJECT(old), "title"); - - gtk_notebook_remove_page(notebook, index); - gtk_notebook_insert_page(notebook, widget, label, index); - - g_object_unref(G_OBJECT(label)); - g_object_set_data(G_OBJECT(widget), "title", str); - - gtk_notebook_set_current_page(notebook, index); - - g_signal_connect(notebook, "switch-page", - G_CALLBACK(gtk_dock_station_switch_panel), station); - -} - - -/****************************************************************************** -* * -* Paramètres : station = plateforme GTK à compléter. * -* dockable = élément existant à retirer. * -* * -* Description : Retire un paquet d'informations de l'affichage centralisé. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void gtk_dock_station_remove_dockable(GtkDockStation *station, GtkDockable *dockable) -{ - GtkNotebook *notebook; /* Autre version du composant */ - GtkWidget *widget; /* Composant GTK à retirer */ - gint index; /* Indice de l'onglet visé */ - - notebook = GTK_NOTEBOOK(station); - - widget = gtk_dockable_decompose(dockable, NULL); - - index = gtk_notebook_page_num(notebook, widget); - - gtk_notebook_remove_page(notebook, index); - -} - - -/****************************************************************************** -* * -* Paramètres : button = bouton à l'origine de la procédure. * -* station = station d'accueil pour différents composants. * -* * -* Description : Révèle ou cache la zone de recherches. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void on_toggle_revealer(GtkToggleButton *button, GtkDockStation *station) -{ - GtkNotebook *notebook; /* Autre version du composant */ - gint index; /* Indice de l'onglet courant */ - GtkWidget *widget; /* Panneau concerné */ - GtkDockable *dockable; /* Elément encapsulé */ - - notebook = GTK_NOTEBOOK(station); - - index = gtk_notebook_get_current_page(notebook); - widget = gtk_notebook_get_nth_page(notebook, index); - - dockable = GTK_DOCKABLE(g_object_get_data(G_OBJECT(widget), "dockable")); - - gtk_dockable_toggle_revealer(dockable, widget, gtk_toggle_button_get_active(button)); - -} - - -/****************************************************************************** -* * -* Paramètres : button = bouton à l'origine de la procédure. * -* station = station d'accueil pour différents composants. * -* * -* Description : Demande l'apparition d'un menu pour inclure des composants. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void on_click_for_menu(GtkButton *button, GtkDockStation *station) -{ - g_signal_emit_by_name(station, "menu-requested", button); - -} - - -/****************************************************************************** -* * -* Paramètres : button = bouton à l'origine de la procédure. * -* station = station d'accueil pour différents composants. * -* * -* Description : Demande la disparition du composant courant. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void on_click_for_close(GtkButton *button, GtkDockStation *station) -{ - g_signal_emit_by_name(station, "close-requested", button); - -} diff --git a/src/gtkext/gtkdockstation.h b/src/gtkext/gtkdockstation.h deleted file mode 100644 index f286c1c..0000000 --- a/src/gtkext/gtkdockstation.h +++ /dev/null @@ -1,97 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * gtkdockstation.h - prototypes pour la manipulation et l'affichage de composants rassemblés - * - * Copyright (C) 2012-2018 Cyrille Bagard - * - * This file is part of Chrysalide. - * - * Chrysalide is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * Chrysalide is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Chrysalide. If not, see . - */ - - -#ifndef _GTKEXT_GTKDOCKSTATION_H -#define _GTKEXT_GTKDOCKSTATION_H - - -#include - - -#include "gtkdockable.h" - - - -//G_BEGIN_DECLS - - -#define GTK_TYPE_DOCK_STATION (gtk_dock_station_get_type()) -#define GTK_DOCK_STATION(obj) G_TYPE_CHECK_INSTANCE_CAST(obj, gtk_dock_station_get_type (), GtkDockStation) -#define GTK_DOCK_STATION_CLASS(klass) G_TYPE_CHECK_CLASS_CAST(klass, gtk_dock_station_get_type(), GtkDockStationClass) -#define GTK_IS_DOCK_STATION(obj) G_TYPE_CHECK_INSTANCE_TYPE(obj, gtk_dock_station_get_type()) - - -/* Station de réception pour concentration d'éléments (instance) */ -typedef struct _GtkDockStation GtkDockStation; - -/* Station de réception pour concentration d'éléments (classe) */ -typedef struct _GtkDockStationClass GtkDockStationClass; - - -/* Station de réception pour concentration d'éléments (instance) */ -struct _GtkDockStation -{ - GtkNotebook parent; /* A laisser en premier */ - -}; - -/* Station de réception pour concentration d'éléments (classe) */ -struct _GtkDockStationClass -{ - GtkNotebookClass parent_class; /* A laisser en premier */ - - /* Signaux */ - - void (* dock_widget) (GtkDockStation *, GtkWidget *); - void (* undock_widget) (GtkDockStation *, GtkWidget *); - - void (* switch_widget) (GtkDockStation *, GtkWidget *); - - void (* menu_requested) (GtkDockStation *, GtkWidget *); - void (* close_requested) (GtkDockStation *, GtkWidget *); - -}; - - -/* Détermine le type du composant d'affichage concentré. */ -GType gtk_dock_station_get_type(void); - -/* Crée un nouveau composant pour support d'affichage concentré. */ -GtkWidget *gtk_dock_station_new(void); - -/* Ajoute un paquet d'informations à l'affichage centralisé. */ -void gtk_dock_station_add_dockable(GtkDockStation *, GtkDockable *); - -/* Change le contenu de l'onglet courant uniquement. */ -void gtk_dock_panel_change_active_widget(GtkDockStation *, GtkWidget *); - -/* Retire un paquet d'informations de l'affichage centralisé. */ -void gtk_dock_station_remove_dockable(GtkDockStation *, GtkDockable *); - - - -//G_END_DECLS - - - -#endif /* _GTKEXT_GTKDOCKSTATION_H */ diff --git a/src/gtkext/panel-int.h b/src/gtkext/panel-int.h new file mode 100644 index 0000000..d54dc16 --- /dev/null +++ b/src/gtkext/panel-int.h @@ -0,0 +1,138 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * panel-int.h - prototypes pour les définitions internes liées aux panneaux d'affichage + * + * Copyright (C) 2019 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + +#ifndef _GUI_PANELS_PANEL_INT_H +#define _GUI_PANELS_PANEL_INT_H + + +#include "panel.h" + + +#include + + +#include "item-int.h" +#include "../glibext/delayed.h" + + + +/* ------------------------- COEUR DES PANNEAUX D'AFFICHAGE ------------------------- */ + + +/* Fournit une indication sur la personnalité du panneau. */ +typedef PanelItemPersonality (* get_panel_personality_fc) (const GPanelItemClass *); + +/* Fournit une indication d'accroche du panneau au démarrage. */ +typedef bool (* dock_panel_at_startup_fc) (const GPanelItemClass *); + +/* Détermine si un panneau peut être filtré. */ +typedef bool (* can_search_panel_fc) (const GPanelItemClass *); + +/* Indique le chemin initial de la localisation d'un panneau. */ +typedef char * (* get_panel_path_fc) (const GPanelItemClass *); + +/* Indique la définition d'un éventuel raccourci clavier. */ +typedef char * (* get_panel_bindings_fc) (const GPanelItemClass *); + +/* Place un panneau dans l'ensemble affiché. */ +typedef void (* ack_dock_process_fc) (GPanelItem *); + +/* Supprime un panneau de l'ensemble affiché. */ +typedef void (* ack_undock_process_fc) (GPanelItem *); + +/* Démarre l'actualisation du filtrage du contenu. */ +typedef void (* update_filtered_fc) (GPanelItem *); + + +/* Elément réactif pour panneaux de l'éditeur (instance) */ +struct _GPanelItem +{ + GEditorItem parent; /* A laisser en premier */ + + bool docked; /* Panneau inscrusté ? */ + + GNamedWidget *widget; /* Composant avec noms */ + GtkWidget *cached_widget; /* Composant GTK récupéré */ + + char *filter; /* Eventuel filtre textuel */ + + cairo_surface_t *surface; /* Copie d'écran préalable */ + gdouble hadj_value; /* Sauvegarde de défilement #1 */ + gdouble vadj_value; /* Sauvegarde de défilement #2 */ + gint switched; /* Mémorise l'état de bascule */ + +}; + +/* Elément réactif pour panneaux de l'éditeur (classe) */ +struct _GPanelItemClass +{ + GEditorItemClass parent; /* A laisser en premier */ + + get_panel_personality_fc get_personality; /* Fourniture de nature */ + dock_panel_at_startup_fc dock_at_startup; /* Recommandation d'accroche */ + can_search_panel_fc can_search; /* Contenu fouillable ? */ + get_panel_path_fc get_path; /* Chemin vers la place idéale */ + get_panel_bindings_fc get_bindings; /* Raccourci clavier éventuel */ + + ack_dock_process_fc ack_dock; /* Prise en compte d'accroche */ + ack_undock_process_fc ack_undock; /* Prise en compte de décroche */ + + update_filtered_fc update_filtered; /* Lancement du filtrage */ + + wgroup_id_t gid; /* Groupe de travail dédié */ + + /* Signaux */ + + void (* dock_request) (GPanelItem); + void (* undock_request) (GPanelItem); + +}; + + +/* Fournit une indication sur la personnalité du panneau. */ +PanelItemPersonality gtk_panel_item_class_get_personality_singleton(const GPanelItemClass *); + +/* Renvoie false lors d'une consultation de la classe. */ +bool gtk_panel_item_class_return_false(const GPanelItemClass *); + +/* Renvoie true lors d'une consultation de la classe. */ +bool gtk_panel_item_class_return_true(const GPanelItemClass *); + + + +/* ---------------------- MECANISMES DE MISE A JOUR DE PANNEAU ---------------------- */ + + +/* Obtient le groupe de travail dédié à une mise à jour. */ +wgroup_id_t g_panel_item_get_group(const GPanelItem *); + +/* Bascule l'affichage d'un panneau avant sa mise à jour. */ +void g_panel_item_switch_to_updating_mask(GPanelItem *); + +/* Bascule l'affichage d'un panneau après sa mise à jour. */ +void g_panel_item_switch_to_updated_content(GPanelItem *); + + + +#endif /* _GUI_PANELS_PANEL_INT_H */ diff --git a/src/gtkext/panel.c b/src/gtkext/panel.c new file mode 100644 index 0000000..5b21620 --- /dev/null +++ b/src/gtkext/panel.c @@ -0,0 +1,1119 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * panel.c - gestion des éléments réactifs spécifiques aux panneaux + * + * Copyright (C) 2019 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + +#include "panel.h" + + +#include +#include +#include + + +#include "panel-int.h" +#include "core/global.h" +#include "core/items.h" +#include "../common/extstr.h" +#include "../core/params.h" +#include "../gtkext/gtkdockable-int.h" +#include "../gtkext/named.h" +#include "../plugins/dt.h" +#include "../plugins/pglist.h" + + + +/* ------------------------- COEUR DES PANNEAUX D'AFFICHAGE ------------------------- */ + + +/* Initialise la classe des panneaux graphiques de l'éditeur. */ +static void g_panel_item_class_init(GPanelItemClass *); + +/* Initialise une instance de panneau graphique pour l'éditeur. */ +static void g_panel_item_init(GPanelItem *); + +/* Procède à l'initialisation de l'interface d'incrustation. */ +static void g_panel_item_dockable_interface_init(GtkDockableInterface *); + +/* Supprime toutes les références externes. */ +static void g_panel_item_dispose(GPanelItem *); + +/* Procède à la libération totale de la mémoire. */ +static void g_panel_item_finalize(GPanelItem *); + +/* Construit la chaîne d'accès à un élément de configuration. */ +static char *gtk_panel_item_class_build_configuration_key(const GPanelItemClass *, const char *); + +/* Fournit le nom court du composant encapsulable. */ +static char *gtk_panel_item_get_name(const GPanelItem *); + +/* Fournit le nom long du composant encapsulable. */ +static char *gtk_panel_item_get_desc(const GPanelItem *); + +/* Détermine si un panneau peut être filtré. */ +static bool gtk_panel_item_can_search(const GPanelItem *); + +/* Fournit le composant graphique intégrable dans un ensemble. */ +static GtkWidget *gtk_panel_item_get_widget(GPanelItem *); + +/* Démarre l'actualisation du filtrage du contenu. */ +static void gtk_panel_item_update_filtered(GPanelItem *, const char *); + + + +/* ---------------------- MECANISMES DE MISE A JOUR DE PANNEAU ---------------------- */ + + +/* Présente une copie de l'affichage du composant rafraîchi. */ +static gboolean g_panel_item_draw_mask(GtkWidget *, cairo_t *, GPanelItem *); + + + +/* ---------------------------------------------------------------------------------- */ +/* COEUR DES PANNEAUX D'AFFICHAGE */ +/* ---------------------------------------------------------------------------------- */ + + +/* Indique le type défini pour un élément destiné à un panneau. */ +G_DEFINE_TYPE_WITH_CODE(GPanelItem, g_panel_item, G_TYPE_EDITOR_ITEM, + G_IMPLEMENT_INTERFACE(GTK_TYPE_DOCKABLE, g_panel_item_dockable_interface_init)); + + +/****************************************************************************** +* * +* Paramètres : class = classe à initialiser. * +* * +* Description : Initialise la classe des panneaux graphiques de l'éditeur. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_panel_item_class_init(GPanelItemClass *class) +{ + GObjectClass *object; /* Autre version de la classe */ + GEditorItemClass *item; /* Encore une autre vision... */ + + object = G_OBJECT_CLASS(class); + + object->dispose = (GObjectFinalizeFunc/* ! */)g_panel_item_dispose; + object->finalize = (GObjectFinalizeFunc)g_panel_item_finalize; + + item = G_EDITOR_ITEM_CLASS(class); + + item->get_widget = (get_item_widget_fc)gtk_panel_item_get_widget; + + class->get_personality = gtk_panel_item_class_get_personality_singleton; + class->dock_at_startup = gtk_panel_item_class_return_true; + class->can_search = gtk_panel_item_class_return_false; + + g_signal_new("dock-request", + G_TYPE_PANEL_ITEM, + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET(GPanelItemClass, dock_request), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); + + g_signal_new("undock-request", + G_TYPE_PANEL_ITEM, + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET(GPanelItemClass, undock_request), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); + +} + + +/****************************************************************************** +* * +* Paramètres : item = instance à initialiser. * +* * +* Description : Initialise une instance de panneau graphique pour l'éditeur. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_panel_item_init(GPanelItem *item) +{ + item->docked = false; + + item->widget = NULL; + item->cached_widget = NULL; + + item->filter = NULL; + + g_atomic_int_set(&item->switched, 0); + +} + + +/****************************************************************************** +* * +* Paramètres : iface = interface GTK à initialiser. * +* * +* Description : Procède à l'initialisation de l'interface d'incrustation. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_panel_item_dockable_interface_init(GtkDockableInterface *iface) +{ + iface->get_name = (get_dockable_name_fc)gtk_panel_item_get_name; + iface->get_desc = (get_dockable_desc_fc)gtk_panel_item_get_desc; + iface->can_search = (can_dockable_search_fc)gtk_panel_item_can_search; + + iface->get_widget = (get_dockable_widget_fc)gtk_panel_item_get_widget; + iface->update_filtered = (update_filtered_data_fc)gtk_panel_item_update_filtered; + +} + + +/****************************************************************************** +* * +* Paramètres : item = instance d'objet GLib à traiter. * +* * +* Description : Supprime toutes les références externes. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_panel_item_dispose(GPanelItem *item) +{ + g_clear_object(&item->widget); + g_clear_object(&item->cached_widget); + + G_OBJECT_CLASS(g_panel_item_parent_class)->dispose(G_OBJECT(item)); + +} + + +/****************************************************************************** +* * +* Paramètres : item = instance d'objet GLib à traiter. * +* * +* Description : Procède à la libération totale de la mémoire. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_panel_item_finalize(GPanelItem *item) +{ + if (item->filter != NULL) + free(item->filter); + + if (item->surface != NULL) + cairo_surface_destroy(item->surface); + + G_OBJECT_CLASS(g_panel_item_parent_class)->finalize(G_OBJECT(item)); + +} + + +/****************************************************************************** +* * +* Paramètres : class = classe à consulter. * +* * +* Description : Fournit une indication sur la personnalité du panneau. * +* * +* Retour : Identifiant lié à la nature du panneau. * +* * +* Remarques : - * +* * +******************************************************************************/ + +PanelItemPersonality gtk_panel_item_class_get_personality(const GPanelItemClass *class) +{ + PanelItemPersonality result; /* Personnalité à retourner */ + + result = class->get_personality(class); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : class = classe à consulter. * +* * +* Description : Fournit une indication sur la personnalité du panneau. * +* * +* Retour : Identifiant lié à la nature unique du panneau. * +* * +* Remarques : - * +* * +******************************************************************************/ + +PanelItemPersonality gtk_panel_item_class_get_personality_singleton(const GPanelItemClass *class) +{ + PanelItemPersonality result; /* Personnalité à retourner */ + + result = PIP_SINGLETON; + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : class = classe à consulter. * +* * +* Description : Fournit une indication d'accroche du panneau au démarrage. * +* * +* Retour : true si le panneau doit être affiché de prime abord. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool gtk_panel_item_class_dock_at_startup(const GPanelItemClass *class) +{ + bool result; /* Statut à retourner */ + GGenConfig *config; /* Configuration courante */ + char *key; /* Clef d'accès à un paramètre */ +#ifndef NDEBUG + bool status; /* Bilan de consultation */ +#endif + + config = get_main_configuration(); + + key = gtk_panel_item_class_build_configuration_key(class, "dock_at_startup"); + +#ifndef NDEBUG + status = g_generic_config_get_value(config, key, &result); + assert(status); +#else + g_generic_config_get_value(config, key, &result); +#endif + + free(key); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : class = classe associée à la consultation. * +* * +* Description : Renvoie false lors d'une consultation de la classe. * +* * +* Retour : false. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool gtk_panel_item_class_return_false(const GPanelItemClass *class) +{ + bool result; /* Statut à retourner */ + + result = false; + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : class = classe associée à la consultation. * +* * +* Description : Renvoie true lors d'une consultation de la classe. * +* * +* Retour : true. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool gtk_panel_item_class_return_true(const GPanelItemClass *class) +{ + bool result; /* Statut à retourner */ + + result = true; + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : class = classe à consulter. * +* * +* Description : Détermine si un panneau peut être filtré. * +* * +* Retour : Bilan de la consultation. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool gtk_panel_item_class_can_search(const GPanelItemClass *class) +{ + bool result; /* Statut à retourner */ + + result = class->can_search(class); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : class = classe à consulter. * +* * +* Description : Indique le chemin initial de la localisation d'un panneau. * +* * +* Retour : Chemin fixé associé à la position initiale. * +* * +* Remarques : - * +* * +******************************************************************************/ + +char *gtk_panel_item_class_get_path(const GPanelItemClass *class) +{ + char *result; /* Emplacement à retourner */ + GGenConfig *config; /* Configuration courante */ + char *key; /* Clef d'accès à un paramètre */ + const char *path; /* Nouveau chemin de placement */ +#ifndef NDEBUG + bool status; /* Statut de l'encapsulation */ +#endif + + config = get_main_configuration(); + + key = gtk_panel_item_class_build_configuration_key(class, "path"); + +#ifndef NDEBUG + status = g_generic_config_get_value(config, key, &path); + assert(status); +#else + g_generic_config_get_value(config, key, &path); +#endif + + free(key); + + result = strdup(path); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : class = classe à consulter. * +* * +* Description : Indique la définition d'un éventuel raccourci clavier. * +* * +* Retour : Description d'un raccourci ou NULL si aucun de défini. * +* * +* Remarques : - * +* * +******************************************************************************/ + +char *gtk_panel_item_class_get_key_bindings(const GPanelItemClass *class) +{ + char *result; /* Emplacement à retourner */ + + if (class->get_bindings != NULL) + result = class->get_bindings(class); + + else + result = NULL; + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : class = classe du type de panneau à traiter. * +* attrib = élément de configuration à inclure dans le résultat.* +* * +* Description : Construit la chaîne d'accès à un élément de configuration. * +* * +* Retour : Chaîne de caractères à libérer après usage. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static char *gtk_panel_item_class_build_configuration_key(const GPanelItemClass *class, const char *attrib) +{ + char *result; /* Construction à renvoyer */ + const char *name; /* Nom court du panneau */ + + name = g_editor_item_class_get_key(G_EDITOR_ITEM_CLASS(class)); + + asprintf(&result, "gui.panels.%s.%s", attrib, name); + + result = strrpl(result, " ", "_"); + + result = strlower(result); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : class = classe de panneau à consulter. * +* config = configuration à compléter. * +* * +* Description : Met en place les bases de la configuration d'un panneau. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool gtk_panel_item_class_setup_configuration(const GPanelItemClass *class, GGenConfig *config) +{ + bool result; /* Bilan à retourner */ + char *key; /* Clef d'accès à un paramètre */ + bool dock_at_startup; /* Affichage dès le départ ? */ + char *path; /* Localisation du panneau */ + + key = gtk_panel_item_class_build_configuration_key(class, "dock_at_startup"); + + dock_at_startup = class->dock_at_startup(class); + + result = g_generic_config_create_param_if_not_exist(config, key, CPT_BOOLEAN, dock_at_startup); + + free(key); + + if (!result) + goto exit; + + key = gtk_panel_item_class_build_configuration_key(class, "path"); + + path = class->get_path(class); + + result = g_generic_config_create_param_if_not_exist(config, key, CPT_STRING, path); + + free(path); + + free(key); + + exit: + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : type = type de panneau à mettre en place. * +* path = emplacement d'affichage ou NULL. * +* * +* Description : Crée un élément de panneau réactif. * +* * +* Retour : Adresse de la structure mise en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GPanelItem *g_panel_item_new(GType type, const char *path) +{ + GPanelItem *result; /* Structure à retourner */ + GPanelItemClass *class; /* Classe associée au type */ + PanelItemPersonality personality; /* Caractéristique de panneau */ + GtkTiledGrid *grid; /* Composant d'affichage */ + + class = g_type_class_ref(type); + + personality = gtk_panel_item_class_get_personality(class); + assert(path != NULL || personality == PIP_PERSISTENT_SINGLETON); + + g_type_class_unref(class); + + if (personality == PIP_PERSISTENT_SINGLETON || personality == PIP_SINGLETON) + { + result = G_PANEL_ITEM(find_editor_item_by_type(type)); + + if (result != NULL) + goto singleton; + + } + + result = create_object_from_type(type); + + grid = get_tiled_grid(); + + g_signal_connect_swapped(result, "dock-request", G_CALLBACK(gtk_tiled_grid_add), grid); + g_signal_connect_swapped(result, "undock-request", G_CALLBACK(gtk_tiled_grid_remove), grid); + + gtk_dockable_setup_dnd(GTK_DOCKABLE(result)); + + register_editor_item(G_EDITOR_ITEM(result)); + + notify_panel_creation(result); + + singleton: + + if (path != NULL) + { + if (path[0] != '\0') + gtk_panel_item_set_path(result, path); + + g_panel_item_dock(result); + + } + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : item = instance de panneau à consulter. * +* * +* Description : Indique le composant graphique principal du panneau. * +* * +* Retour : Composant graphique avec nom constituant le panneau. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GNamedWidget *gtk_panel_item_get_named_widget(const GPanelItem *item) +{ + GNamedWidget *result; /* Composant nommé à retourner */ + + result = item->widget; + + g_object_ref(G_OBJECT(result)); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : item = instance GTK dont l'interface est à consulter. * +* * +* Description : Fournit le nom court du composant encapsulable. * +* * +* Retour : Désignation humaine pour titre d'onglet ou de fenêtre. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static char *gtk_panel_item_get_name(const GPanelItem *item) +{ + char *result; /* Désignation à retourner */ + + result = g_named_widget_get_name(G_NAMED_WIDGET(item->widget), false); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : item = instance GTK dont l'interface est à consulter. * +* * +* Description : Fournit le nom long du composant encapsulable. * +* * +* Retour : Désignation humaine pour titre d'onglet ou de fenêtre. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static char *gtk_panel_item_get_desc(const GPanelItem *item) +{ + char *result; /* Description à retourner */ + + result = g_named_widget_get_name(G_NAMED_WIDGET(item->widget), true); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : item = instance GTK dont l'interface est à consulter. * +* * +* Description : Détermine si un panneau peut être filtré. * +* * +* Retour : Bilan de la consultation. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool gtk_panel_item_can_search(const GPanelItem *item) +{ + bool result; /* Indication à retourner */ + GPanelItemClass *class; /* Classe de l'élément visé */ + + class = G_PANEL_ITEM_GET_CLASS(item); + + result = gtk_panel_item_class_can_search(class); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : item = instance GTK dont l'interface est à consulter. * +* * +* Description : Fournit le composant graphique intégrable dans un ensemble. * +* * +* Retour : Composant graphique prêt à emploi. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static GtkWidget *gtk_panel_item_get_widget(GPanelItem *item) +{ + GtkWidget *result; /* Composant à retourner */ + + if (item->cached_widget == NULL) + item->cached_widget = g_named_widget_get_widget(G_NAMED_WIDGET(item->widget)); + + result = item->cached_widget; + + g_object_ref(G_OBJECT(result)); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : item = instance GTK dont l'interface est à sollicitée. * +* * +* Description : Démarre l'actualisation du filtrage du contenu. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void gtk_panel_item_update_filtered(GPanelItem *item, const char *filter) +{ + assert(gtk_panel_item_can_search(item)); + + if (item->filter != NULL) + free(item->filter); + + item->filter = (filter ? strdup(filter) : NULL); + + G_PANEL_ITEM_GET_CLASS(item)->update_filtered(item); + +} + + +/****************************************************************************** +* * +* Paramètres : item = instance GTK à consulter. * +* path = nouvelle emplacement d'inclusion. * +* * +* Description : Définit le chemin d'accès à utiliser pour les encapsulations.* +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void gtk_panel_item_set_path(GPanelItem *item, const char *path) +{ + GGenConfig *config; /* Configuration courante */ + char *key; /* Clef d'accès à un paramètre */ + + config = get_main_configuration(); + + key = gtk_panel_item_class_build_configuration_key(G_PANEL_ITEM_GET_CLASS(item), "path"); + + g_generic_config_set_value(config, key, path); + + free(key); + +} + + +/****************************************************************************** +* * +* Paramètres : item = composant à présenter à l'affichage. * +* * +* Description : Place un panneau dans l'ensemble affiché. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void g_panel_item_dock(GPanelItem *item) +{ + assert(!item->docked); + + g_signal_emit_by_name(item, "dock-request"); + + if (G_PANEL_ITEM_GET_CLASS(item)->ack_dock != NULL) + G_PANEL_ITEM_GET_CLASS(item)->ack_dock(item); + + notify_panel_docking(item, true); + +} + + +/****************************************************************************** +* * +* Paramètres : item = composant d'affichage à mettre à jour. * +* status = nouvel état d'encapsulation. * +* * +* Description : Définit si le composant repose sur un support de l'éditeur. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void g_panel_item_set_dock_at_startup(GPanelItem *item, bool status) +{ + char *key; /* Clef d'accès à un paramètre */ + + item->docked = status; + + key = gtk_panel_item_class_build_configuration_key(G_PANEL_ITEM_GET_CLASS(item), "dock_at_startup"); + + g_generic_config_set_value(get_main_configuration(), key, status); + + free(key); + +} + + +/****************************************************************************** +* * +* Paramètres : item = composant d'affichage à consulter. * +* * +* Description : Indique si le composant repose sur un support de l'éditeur. * +* * +* Retour : true si le composant est bien incrusté quelque part. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool g_panel_item_is_docked(const GPanelItem *item) +{ + bool result; /* Status à retourner */ + + result = item->docked; + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : item = composant à retirer de l'affichage. * +* * +* Description : Supprime un panneau de l'ensemble affiché. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void g_panel_item_undock(GPanelItem *item) +{ + PanelItemPersonality personality; /* Caractéristique de panneau */ + + assert(item->docked); + + g_signal_emit_by_name(item, "undock-request"); + + if (G_PANEL_ITEM_GET_CLASS(item)->ack_undock != NULL) + G_PANEL_ITEM_GET_CLASS(item)->ack_undock(item); + + notify_panel_docking(item, false); + + personality = gtk_panel_item_class_get_personality(G_PANEL_ITEM_GET_CLASS(item)); + + if (personality != PIP_PERSISTENT_SINGLETON) + unregister_editor_item(G_EDITOR_ITEM(item)); + +} + + + +/* ---------------------------------------------------------------------------------- */ +/* MECANISMES DE MISE A JOUR DE PANNEAU */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +* * +* Paramètres : item = panneau ciblé par une mise à jour. * +* * +* Description : Obtient le groupe de travail dédié à une mise à jour. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +wgroup_id_t g_panel_item_get_group(const GPanelItem *item) +{ + wgroup_id_t result; /* Identifiant à retourner */ + + result = G_PANEL_ITEM_GET_CLASS(item)->gid; + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : widget = composant graphique sur lequel dessiner. * +* cr = contexte graphique pour le dessin. * +* panel = panneau ciblé par une mise à jour. * +* * +* Description : Présente une copie de l'affichage du composant rafraîchi. * +* * +* Retour : FALSE afin de poursuivre les traitements. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static gboolean g_panel_item_draw_mask(GtkWidget *widget, cairo_t *cr, GPanelItem *item) +{ + int width; /* Largeur du composant actuel */ + int height; /* Hauteur du composant actuel */ + + width = gtk_widget_get_allocated_width(widget); + height = gtk_widget_get_allocated_height(widget); + + cairo_save(cr); + + cairo_set_source_surface(cr, item->surface, 0, 0); + cairo_rectangle(cr, 0, 0, width, height); + + cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE); + cairo_fill(cr); + + cairo_restore(cr); + + return FALSE; + +} + + +/****************************************************************************** +* * +* Paramètres : panel = panneau ciblé par une mise à jour. * +* * +* Description : Bascule l'affichage d'un panneau avant sa mise à jour. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void g_panel_item_switch_to_updating_mask(GPanelItem *item) +{ + GtkBuilder *builder; /* Constructeur sous-jacent */ + GtkWidget *content; /* Composant à faire évoluer */ + GdkWindow *window; /* Fenêtre au contenu à copier */ + int width; /* Largeur du composant actuel */ + int height; /* Hauteur du composant actuel */ + cairo_t *cr; /* Pinceau pour les dessins */ + GtkAdjustment *adj; /* Défilement éventuel */ + GtkStack *stack; /* Pile de composants GTK */ + GtkWidget *mask; /* Masque des travaux */ + + if (g_atomic_int_add(&item->switched, 1) > 0) + return; + + /* Copie de l'affichage courant */ + + assert(item->surface == NULL); + + builder = gtk_built_named_widget_get_builder(GTK_BUILT_NAMED_WIDGET(item->widget)); + + content = GTK_WIDGET(gtk_builder_get_object(builder, "content")); + + window = gtk_widget_get_window(content); + + if (window != NULL) + { + width = gtk_widget_get_allocated_width(content); + height = gtk_widget_get_allocated_height(content); + + item->surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height); + + cr = cairo_create(item->surface); + + gdk_cairo_set_source_window(cr, window, 0, 0); + + cairo_paint(cr); + + cairo_destroy(cr); + + } + + /* Sauvegarde de l'éventuelle position */ + + if (GTK_IS_SCROLLED_WINDOW(content)) + { + adj = gtk_scrolled_window_get_hadjustment(GTK_SCROLLED_WINDOW(content)); + item->hadj_value = gtk_adjustment_get_value(adj); + + adj = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(content)); + item->vadj_value = gtk_adjustment_get_value(adj); + + } + + /* Opération de basculement effectif */ + + stack = GTK_STACK(gtk_builder_get_object(builder, "stack")); + + mask = GTK_WIDGET(gtk_builder_get_object(builder, "mask")); + + gtk_spinner_start(GTK_SPINNER(mask)); + + if (item->surface != NULL) + g_signal_connect(mask, "draw", G_CALLBACK(g_panel_item_draw_mask), item); + + gtk_stack_set_visible_child(stack, mask); + + g_object_unref(G_OBJECT(builder)); + +} + + +/****************************************************************************** +* * +* Paramètres : panel = panneau ciblé par une mise à jour. * +* * +* Description : Bascule l'affichage d'un panneau après sa mise à jour. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void g_panel_item_switch_to_updated_content(GPanelItem *item) +{ + GtkBuilder *builder; /* Constructeur sous-jacent */ + GtkWidget *content; /* Composant à faire évoluer */ + GtkAdjustment *adj; /* Défilement éventuel */ + GtkStack *stack; /* Pile de composants GTK */ + GtkWidget *mask; /* Masque des travaux */ + + if (g_atomic_int_get(&item->switched) > 1) + goto skip; + + /* Restauration d'une éventuelle position */ + + builder = gtk_built_named_widget_get_builder(GTK_BUILT_NAMED_WIDGET(item->widget)); + + content = GTK_WIDGET(gtk_builder_get_object(builder, "content")); + + if (GTK_IS_SCROLLED_WINDOW(content)) + { + adj = gtk_scrolled_window_get_hadjustment(GTK_SCROLLED_WINDOW(content)); + gtk_adjustment_set_value(adj, item->hadj_value); + + adj = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(content)); + gtk_adjustment_set_value(adj, item->vadj_value); + + } + + /* Opération de basculement effectif */ + + stack = GTK_STACK(gtk_builder_get_object(builder, "stack")); + + gtk_stack_set_visible_child(stack, content); + + mask = GTK_WIDGET(gtk_builder_get_object(builder, "mask")); + + g_signal_handlers_disconnect_by_func(mask, G_CALLBACK(g_panel_item_draw_mask), item); + + gtk_spinner_stop(GTK_SPINNER(mask)); + + /* Supression de la copie d'affichage */ + + if (item->surface != NULL) + { + cairo_surface_destroy(item->surface); + item->surface = NULL; + } + + g_object_unref(G_OBJECT(builder)); + + skip: + + g_atomic_int_dec_and_test(&item->switched); + +} diff --git a/src/gtkext/panel.h b/src/gtkext/panel.h new file mode 100644 index 0000000..de8d2bf --- /dev/null +++ b/src/gtkext/panel.h @@ -0,0 +1,112 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * panel.h - prototypes pour la gestion des éléments réactifs spécifiques aux panneaux + * + * Copyright (C) 2019 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + +#ifndef _GUI_PANELS_PANEL_H +#define _GUI_PANELS_PANEL_H + + +#include +#include + + +#include "../glibext/configuration.h" +#include "../glibext/named.h" + + + +#define G_TYPE_PANEL_ITEM g_panel_item_get_type() +#define G_PANEL_ITEM(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_PANEL_ITEM, GPanelItem)) +#define G_IS_PANEL_ITEM(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_PANEL_ITEM)) +#define G_PANEL_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_PANEL_ITEM, GPanelItemClass)) +#define G_IS_PANEL_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_PANEL_ITEM)) +#define G_PANEL_ITEM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_PANEL_ITEM, GPanelItemClass)) + + +/* Elément réactif pour panneaux de l'éditeur (instance) */ +typedef struct _GPanelItem GPanelItem; + +/* Elément réactif pour panneaux de l'éditeur (classe) */ +typedef struct _GPanelItemClass GPanelItemClass; + + +/* Types de panneaux pour éditeur */ +typedef enum _PanelItemPersonality +{ + PIP_INVALID, /* Information non initialisée */ + + PIP_SINGLETON, /* Instance unique */ + PIP_PERSISTENT_SINGLETON, /* Instance unique permanente */ + PIP_BINARY_VIEW, /* Affichage d'un binaire */ + PIP_OTHER, /* Reste du monde */ + + PIP_COUNT + +} PanelItemPersonality; + + +/* Indique le type défini pour un élément destiné à un panneau. */ +GType g_panel_item_get_type(void); + +/* Fournit une indication sur la personnalité du panneau. */ +PanelItemPersonality gtk_panel_item_class_get_personality(const GPanelItemClass *); + +/* Fournit une indication d'accroche du panneau au démarrage. */ +bool gtk_panel_item_class_dock_at_startup(const GPanelItemClass *); + +/* Détermine si un panneau peut être filtré. */ +bool gtk_panel_item_class_can_search(const GPanelItemClass *); + +/* Indique le chemin initial de la localisation d'un panneau. */ +char *gtk_panel_item_class_get_path(const GPanelItemClass *); + +/* Indique la définition d'un éventuel raccourci clavier. */ +char *gtk_panel_item_class_get_key_bindings(const GPanelItemClass *); + +/* Met en place les bases de la configuration du panneau. */ +bool gtk_panel_item_class_setup_configuration(const GPanelItemClass *, GGenConfig *); + +/* Crée un élément de panneau réactif. */ +GPanelItem *g_panel_item_new(GType, const char *); + +/* Indique le composant graphique principal du panneau. */ +GNamedWidget *gtk_panel_item_get_named_widget(const GPanelItem *); + +/* Définit le chemin d'accès à utiliser pour les encapsulations. */ +void gtk_panel_item_set_path(GPanelItem *, const char *); + +/* Place un panneau dans l'ensemble affiché. */ +void g_panel_item_dock(GPanelItem *); + +/* Définit si le composant repose sur un support de l'éditeur. */ +void g_panel_item_set_dock_at_startup(GPanelItem *, bool); + +/* Indique si le composant repose sur un support de l'éditeur. */ +bool g_panel_item_is_docked(const GPanelItem *); + +/* Supprime un panneau de l'ensemble affiché. */ +void g_panel_item_undock(GPanelItem *); + + + +#endif /* _GUI_PANELS_PANEL_H */ diff --git a/src/gtkext/tiledgrid.c b/src/gtkext/tiledgrid.c deleted file mode 100644 index 22b2680..0000000 --- a/src/gtkext/tiledgrid.c +++ /dev/null @@ -1,1143 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * tiledgrid.c - composant d'affichage avec des chemins vers les composants contenus - * - * Copyright (C) 2018-2019 Cyrille Bagard - * - * This file is part of Chrysalide. - * - * Chrysalide is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * Chrysalide is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Chrysalide. If not, see . - */ - - -#include "tiledgrid.h" - - -#include -#include -#include -#include - - -#include "../core/logs.h" - - - -/* -------------------------- GESTION DES TUILES AFFICHEES -------------------------- */ - - -/* Informations concernant une tuile */ -typedef struct _grid_tile_t -{ - struct _grid_tile_t *parent; /* Tuile parente */ - - GtkWidget *widget; /* Support d'affichage */ - - char *path; /* Chemin d'accès */ - - struct _grid_tile_t *children[2]; /* Tuiles encastrées ou 2xNULL */ - -} grid_tile_t; - - -#define IS_LEAF_TILE(t) \ - ({ \ - bool __result; \ - __result = GTK_IS_DOCK_STATION((t)->widget); \ - assert(__result || GTK_IS_PANED((t)->widget)); \ - __result; \ - }) - - -/* Valide un chemin d'accès à une tuile. */ -static bool is_valid_tile_path(const char *); - -/* Crée une tuile finale d'affichage de panneaux. */ -static grid_tile_t *create_leaf_tile(const char *, GtkTiledGrid *); - -/* Crée une tuile intermédiaire d'affichage de panneaux. */ -static grid_tile_t *create_inter_tile(grid_tile_t *, bool, grid_tile_t *, grid_tile_t *); - -/* Supprime une tuile de la mémoire. */ -static void delete_tile(grid_tile_t *); - -/* Calcule la taille comme entre un chemin et celui d'une tuile. */ -static size_t compute_tile_score(const grid_tile_t *, const char *); - -/* Indique la tuile adaptée pour un chemin donné. */ -static grid_tile_t *find_suitable_tile(grid_tile_t **, const char *, GtkTiledGrid *); - -/* Découpe une tuile pour y insérer une zone. */ -static grid_tile_t *split_tile(grid_tile_t **, const char *, char, GtkTiledGrid *); - -/* Tente de mettre la main sur une station d'accueil. */ -static grid_tile_t *find_tile_for_widget(grid_tile_t *, GtkWidget *); - -/* Retire une moitié de tuile vide au plein profit de l'autre. */ -static void collapse_tile(grid_tile_t *, grid_tile_t *); - - - -/* --------------------------- INTERFACE DU COMPOSANT GTK --------------------------- */ - - -/* Conteneur pour un affichage en tuiles nommées (instance) */ -struct _GtkTiledGrid -{ - GtkBin parent; /* A laisser en premier */ - - grid_tile_t *tiles; /* Tuiles représentées */ - - GPanelItem *def_panel; /* Panneau principal par défaut*/ - -}; - -/* Conteneur pour un affichage en tuiles nommées (classe) */ -struct _GtkTiledGridClass -{ - GtkBinClass parent; /* A laisser en premier */ - - /* Signaux */ - - void (* station_created) (GtkTiledGrid *, GtkDockStation *, gpointer); - -}; - - -/* Initialise la classe des conteneurs d'affichage en tuiles. */ -static void gtk_tiled_grid_class_init(GtkTiledGridClass *); - -/* Initialise une instance de conteneur d'affichage en tuiles. */ -static void gtk_tiled_grid_init(GtkTiledGrid *); - -/* Supprime toutes les références externes. */ -static void gtk_tiled_grid_dispose(GtkTiledGrid *); - -/* Procède à la libération totale de la mémoire. */ -static void gtk_tiled_grid_finalize(GtkTiledGrid *); - - - -/* ---------------------------------------------------------------------------------- */ -/* GESTION DES TUILES AFFICHEES */ -/* ---------------------------------------------------------------------------------- */ - - -/****************************************************************************** -* * -* Paramètres : path = chemin destiné à sélectionner une tuile. * -* * -* Description : Valide un chemin d'accès à une tuile. * -* * -* Retour : true si le chemin est utilisable, false sinon. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static bool is_valid_tile_path(const char *path) -{ - bool result; /* Bilan à retourner */ - size_t len; /* Taille du chemin */ - size_t i; /* Boucle de parcours */ - char c; /* Caractère de chemin analysé */ - - /** - * M[NESWnesw]* - */ - - len = strlen(path); - - result = (len >= 1); - - if (result) - result = (path[0] == 'M'); - - for (i = 1; i < len && result; i++) - { - c = path[i]; - - if (c == '\0') - break; - - result = (c == 'N' || c == 'n' - || c == 'E' || c == 'e' - || c == 'S' || c == 's' - || c == 'W' || c == 'w'); - - } - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : path = chemin d'accès à la future tuile. * -* Paramètres : tgrid = conteneur d'affichage en tuiles à manipuler. * -* * -* Description : Crée une tuile finale d'affichage de panneaux. * -* * -* Retour : Structure mise en place. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static grid_tile_t *create_leaf_tile(const char *path, GtkTiledGrid *tgrid) -{ - grid_tile_t *result; /* Structure à retourner */ - - result = (grid_tile_t *)malloc(sizeof(grid_tile_t)); - - result->parent = NULL; - - result->widget = gtk_dock_station_new(); - gtk_widget_show(result->widget); - - result->path = strdup(path); - - result->children[0] = NULL; - result->children[1] = NULL; - - g_signal_emit_by_name(tgrid, "station-created", result->widget); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : parent = tuile parente ou NULL si aucune. * -* horiz = indique le type d'orientation désiré. * -* first = première tuile à intégrer. * -* second = seconde tuile à intégrer. * -* * -* Description : Crée une tuile intermédiaire d'affichage de panneaux. * -* * -* Retour : Structure mise en place. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static grid_tile_t *create_inter_tile(grid_tile_t *parent, bool horiz, grid_tile_t *first, grid_tile_t *second) -{ - grid_tile_t *result; /* Structure à retourner */ - GtkWidget *container; /* Conteneur à vider */ - - result = (grid_tile_t *)malloc(sizeof(grid_tile_t)); - - result->parent = parent; - - if (horiz) - result->widget = gtk_paned_new(GTK_ORIENTATION_HORIZONTAL); - else - result->widget = gtk_paned_new(GTK_ORIENTATION_VERTICAL); - - gtk_widget_show(result->widget); - - result->path = NULL; - - result->children[0] = first; - result->children[1] = second; - - /* Changement de propriétaire */ - - container = gtk_widget_get_parent(first->widget); - - if (container != NULL) - gtk_container_remove(GTK_CONTAINER(container), first->widget); - - g_object_ref(G_OBJECT(first->widget)); - gtk_paned_pack1(GTK_PANED(result->widget), first->widget, TRUE, FALSE); - - container = gtk_widget_get_parent(second->widget); - - if (container != NULL) - gtk_container_remove(GTK_CONTAINER(container), second->widget); - - g_object_ref(G_OBJECT(second->widget)); - gtk_paned_pack2(GTK_PANED(result->widget), second->widget, TRUE, FALSE); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : tile = tuile à supprimer. * -* * -* Description : Supprime une tuile de la mémoire. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void delete_tile(grid_tile_t *tile) -{ - if (!IS_LEAF_TILE(tile)) - { - delete_tile(tile->children[0]); - delete_tile(tile->children[1]); - } - - else - free(tile->path); - - g_object_unref(G_OBJECT(tile->widget)); - - free(tile); - -} - - -/****************************************************************************** -* * -* Paramètres : tile = tuile à analyser. * -* path = chemin final complet recherché. * -* * -* Description : Calcule la taille comme entre un chemin et celui d'une tuile.* -* * -* Retour : Quantité de caractères communs. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static size_t compute_tile_score(const grid_tile_t *tile, const char *path) -{ - size_t result; /* Nombre de points à renvoyer */ - size_t max; /* Taille du chemin de la tuile*/ - size_t i; /* Boucle de parcours */ - size_t score_0; /* Score du sous-élément #1 */ - size_t score_1; /* Score du sous-élément #2 */ - - if (IS_LEAF_TILE(tile)) - { - max = strlen(tile->path); - - if (strlen(path) < max) - result = 0; - - else - { - result = 0; - - for (i = 0; i < max; i++) - { - if (tolower((unsigned char)tile->path[i]) == tolower((unsigned char)path[i])) - result++; - else - break; - } - - } - - } - else - { - score_0 = compute_tile_score(tile->children[0], path); - score_1 = compute_tile_score(tile->children[1], path); - - result = score_0 > score_1 ? score_0 : score_1; - - } - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : tile = tuile ou NULL si aucune. [OUT] * -* path = chemin d'accès à la tuile visée. * -* tgrid = conteneur d'affichage en tuiles à manipuler. * -* * -* Description : Indique la tuile adaptée pour un chemin donné. * -* * -* Retour : Structure d'acceuil à disposition. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static grid_tile_t *find_suitable_tile(grid_tile_t **tile, const char *path, GtkTiledGrid *tgrid) -{ - grid_tile_t *result; /* Structure à renvoyer */ - size_t best_len; /* Taille du chemin associé */ - size_t score_0; /* Score du sous-élément #1 */ - size_t score_1; /* Score du sous-élément #2 */ - char *sub_path; /* Nouvelle tentative d'accès */ - grid_tile_t **best; /* Direction à prendre */ - unsigned char next; /* Prochaine étape */ - - /* Cas d'école : appel initial */ - if (*tile == NULL) - { - assert(path[0] == 'M' && path[1] == '\0'); - - result = create_leaf_tile("M", tgrid); - *tile = result; - - } - - else - { - if (IS_LEAF_TILE(*tile)) - { - best_len = compute_tile_score(*tile, path); - - assert(best_len > 0); - - if (path[best_len] == '\0') - result = *tile; - - else - result = split_tile(tile, path, path[best_len], tgrid); - - } - - else - { - score_0 = compute_tile_score((*tile)->children[0], path); - score_1 = compute_tile_score((*tile)->children[1], path); - - assert(score_0 > 0 || score_0 > 0); - - if (score_0 == score_1) - { - sub_path = strndup(path, score_0); - - score_0 = compute_tile_score((*tile)->children[0], sub_path); - score_1 = compute_tile_score((*tile)->children[1], sub_path); - - free(sub_path); - - } - - if (score_0 == score_1) - result = split_tile(tile, path, path[score_0], tgrid); - - else - { - if (score_0 > score_1) - { - best = &(*tile)->children[0]; - best_len = score_0; - } - else - { - best = &(*tile)->children[1]; - best_len = score_1; - } - - /** - * Si on vient de tomber une feuille, trois cas de figure : - * - soit c'est elle qui est visée. - * - soit on veut la diviser. - * - soit on veut la diviser en englobant ses voisines. - */ - - if (IS_LEAF_TILE(*best)) - { - assert(best_len <= strlen(path)); - - next = path[best_len]; - - /* Premier cas */ - if (next == '\0') - result = *best; - - else - { - /* Second cas */ - if (islower(next)) - result = find_suitable_tile(best, path, tgrid); - - /* Troisième cas */ - else - result = split_tile(tile, path, next, tgrid); - - } - - } - - else - result = find_suitable_tile(best, path, tgrid); - - } - - } - - } - - assert(IS_LEAF_TILE(result)); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : tile = tuile à découper en deux. [OUT] * -* path = chemin d'accès à la future tuile. * -* endpoint = désignation de la zone représentée. * -* tgrid = conteneur d'affichage en tuiles à manipuler. * -* * -* Description : Découpe une tuile pour y insérer une zone. * -* * -* Retour : Structure fille mise en place. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static grid_tile_t *split_tile(grid_tile_t **tile, const char *path, char endpoint, GtkTiledGrid *tgrid) -{ - grid_tile_t *result; /* Création à retourner */ - GtkWidget *container; /* Conteneur à vider */ - grid_tile_t *new; /* Nouvelle tuile intermédiaire*/ - - container = gtk_widget_get_parent((*tile)->widget); - - /* Création */ - - result = create_leaf_tile(path, tgrid); - - /* Encapsulation */ - - switch (endpoint) - { - case 'N': - case 'n': - new = create_inter_tile((*tile)->parent, false, result, *tile); - break; - - case 'E': - case 'e': - new = create_inter_tile((*tile)->parent, true, *tile, result); - break; - - case 'S': - case 's': - new = create_inter_tile((*tile)->parent, false, *tile, result); - break; - - case 'W': - case 'w': - new = create_inter_tile((*tile)->parent, true, result, *tile); - break; - - default: - assert(false); - new = NULL; - break; - - } - - /* Connexions */ - - *tile = new; - - result->parent = new; - - if (container != NULL) - { - g_object_ref(G_OBJECT(new->widget)); - gtk_container_add(GTK_CONTAINER(container), new->widget); - } - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : tile = tuile parente, prochaine victime de promotion. * -* side = côté de tuile amené à disparaître. * -* * -* Description : Retire une moitié de tuile vide au plein profit de l'autre. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void collapse_tile(grid_tile_t *tile, grid_tile_t *side) -{ - grid_tile_t *promoted; /* Tuile à faire remonter */ - GtkWidget *container; /* Conteneur à vider */ - - assert(!IS_LEAF_TILE(tile)); - - /* Sélection du remplaçant */ - - if (side == tile->children[0]) - promoted = tile->children[1]; - else - promoted = tile->children[0]; - - /* Etablissement d'une place nette */ - - gtk_container_remove(GTK_CONTAINER(tile->widget), promoted->widget); - - container = gtk_widget_get_parent(tile->widget); - gtk_container_remove(GTK_CONTAINER(container), tile->widget); - - delete_tile(side); - - /* Promotion effective */ - - tile->widget = promoted->widget; - - tile->path = promoted->path; - - tile->children[0] = promoted->children[0]; - tile->children[1] = promoted->children[1]; - - g_object_ref(G_OBJECT(promoted->widget)); - gtk_container_add(GTK_CONTAINER(container), tile->widget); - - free(promoted); - -} - - -/****************************************************************************** -* * -* Paramètres : tile = point de départ des recherches locales. * -* widget = composant graphique à retrouver. * -* * -* Description : Tente de mettre la main sur une station d'accueil. * -* * -* Retour : Eventuelle tuile trouvée ou NULL. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static grid_tile_t *find_tile_for_widget(grid_tile_t *tile, GtkWidget *widget) -{ - grid_tile_t *result; /* Tuile à retourner */ - - if (IS_LEAF_TILE(tile)) - result = tile->widget == widget ? tile : NULL; - - else - { - result = find_tile_for_widget(tile->children[0], widget); - - if (result == NULL) - result = find_tile_for_widget(tile->children[1], widget); - - } - - return result; - -} - - - -/* ---------------------------------------------------------------------------------- */ -/* INTERFACE DU COMPOSANT GTK */ -/* ---------------------------------------------------------------------------------- */ - - -/* Détermine le type du conteneur d'affichage en tuiles nommées. */ -G_DEFINE_TYPE(GtkTiledGrid, gtk_tiled_grid, GTK_TYPE_BIN) - - -/****************************************************************************** -* * -* Paramètres : klass = classe GTK à initialiser. * -* * -* Description : Initialise la classe des conteneurs d'affichage en tuiles. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void gtk_tiled_grid_class_init(GtkTiledGridClass *klass) -{ - GObjectClass *object; /* Autre version de la classe */ - - object = G_OBJECT_CLASS(klass); - - object->dispose = (GObjectFinalizeFunc/* ! */)gtk_tiled_grid_dispose; - object->finalize = (GObjectFinalizeFunc)gtk_tiled_grid_finalize; - - g_signal_new("station-created", - GTK_TYPE_TILED_GRID, - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET(GtkTiledGridClass, station_created), - NULL, NULL, - g_cclosure_marshal_VOID__OBJECT, - G_TYPE_NONE, 1, GTK_TYPE_DOCK_STATION); - -} - - -/****************************************************************************** -* * -* Paramètres : tgrid = instance GTK à initialiser. * -* * -* Description : Initialise une instance de conteneur d'affichage en tuiles. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void gtk_tiled_grid_init(GtkTiledGrid *tgrid) -{ - tgrid->tiles = NULL; - - tgrid->def_panel = NULL; - -} - - -/****************************************************************************** -* * -* Paramètres : tgrid = instance d'objet GLib à traiter. * -* * -* Description : Supprime toutes les références externes. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void gtk_tiled_grid_dispose(GtkTiledGrid *tgrid) -{ - if (tgrid->tiles != NULL) - { - delete_tile(tgrid->tiles); - tgrid->tiles = NULL; - } - - g_clear_object(&tgrid->def_panel); - - G_OBJECT_CLASS(gtk_tiled_grid_parent_class)->dispose(G_OBJECT(tgrid)); - -} - - -/****************************************************************************** -* * -* Paramètres : tgrid = instance d'objet GLib à traiter. * -* * -* Description : Procède à la libération totale de la mémoire. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void gtk_tiled_grid_finalize(GtkTiledGrid *tgrid) -{ - G_OBJECT_CLASS(gtk_tiled_grid_parent_class)->finalize(G_OBJECT(tgrid)); - -} - - -/****************************************************************************** -* * -* Paramètres : - * -* * -* Description : Crée une nouvelle instance de conteneur avec tuiles. * -* * -* Retour : Composant GTK mis en place. * -* * -* Remarques : - * -* * -******************************************************************************/ - -GtkWidget *gtk_tiled_grid_new(void) -{ - return g_object_new(GTK_TYPE_TILED_GRID, NULL); - -} - - -/****************************************************************************** -* * -* Paramètres : tgrid = conteneur d'affichage en tuiles à consulter. * -* * -* Description : Donne le panneau fourni par défaut pour la zone principale. * -* * -* Retour : Panneau d'affichage par défault ou NULL. * -* * -* Remarques : - * -* * -******************************************************************************/ - -GPanelItem *gtk_tiled_grid_get_default_main_panel(const GtkTiledGrid *tgrid) -{ - GPanelItem *result; /* Panneau à retourner */ - - result = tgrid->def_panel; - - if (result != NULL) - g_object_ref(G_OBJECT(result)); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : tgrid = conteneur d'affichage en tuiles à modifier. * -* panel = panneau d'affichage par défault ou NULL. * -* * -* Description : Fournit le panneau par défaut pour la zone principale. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void gtk_tiled_grid_set_default_main_panel(GtkTiledGrid *tgrid, GPanelItem *panel) -{ - GtkWidget *widget; /* Composant GTK à retirer */ - GtkWidget *parent; /* Conteneur à vider */ - grid_tile_t *tile; /* Première tuile d'accueil */ - - if (tgrid->def_panel != NULL) - { - widget = gtk_dockable_build_widget(GTK_DOCKABLE(tgrid->def_panel)); - - parent = gtk_widget_get_parent(widget); - - if (parent != NULL) - gtk_container_remove(GTK_CONTAINER(parent), widget); - - g_object_unref(G_OBJECT(widget)); - - g_object_unref(G_OBJECT(tgrid->def_panel)); - - } - - tgrid->def_panel = panel; - - if (panel != NULL) - { - g_object_ref(G_OBJECT(panel)); - - if (tgrid->tiles == NULL) - gtk_tiled_grid_add(tgrid, panel); - - else - { - tile = find_suitable_tile(&tgrid->tiles, "M", tgrid); - - if (gtk_notebook_get_n_pages(GTK_NOTEBOOK(tile->widget)) == 0) - gtk_tiled_grid_add(tgrid, panel); - - } - - } - -} - - -/****************************************************************************** -* * -* Paramètres : tgrid = conteneur d'affichage en tuiles à modifier. * -* panel = panneau d'affichage à intégrer. * -* * -* Description : Incorpore un nouveau panneau dans le conteneur en tuiles. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void gtk_tiled_grid_add(GtkTiledGrid *tgrid, GPanelItem *panel) -{ - char *path; /* Chemin d'accès */ - char *name; /* Nom à donner à l'onglet */ - grid_tile_t *tile; /* Tuile d'accueil */ - - path = gtk_panel_item_class_get_path(G_PANEL_ITEM_GET_CLASS(panel)); - - if (!is_valid_tile_path(path)) - { - name = gtk_dockable_get_name(GTK_DOCKABLE(panel)); - log_variadic_message(LMT_ERROR, _("Invalid path '%s' for panel '%s'"), path, name); - free(name); - } - - else - { - tile = find_suitable_tile(&tgrid->tiles, path, tgrid); - assert(tile != NULL); - - gtk_dock_station_add_dockable(GTK_DOCK_STATION(tile->widget), GTK_DOCKABLE(panel)); - - g_panel_item_set_dock_at_startup(panel, true); - - /* Si c'est la toute première fois... */ - if (gtk_widget_get_parent(tile->widget) == NULL) - { - assert(tile == tgrid->tiles); - assert(tile->path[0] == 'M' && tile->path[1] == '\0'); - g_object_ref(G_OBJECT(tile->widget)); - gtk_container_add(GTK_CONTAINER(tgrid), tile->widget); - } - - /* Si on n'a plus besoin du panneau par défaut */ - if (tgrid->def_panel != NULL && tile->path[0] == 'M' && tile->path[1] == '\0') - { - /* Si ce n'est pas le panneau qu'on vient de rajouter...*/ - if (panel != tgrid->def_panel) - { - /* Enfin : si ce panneau par défaut est réellement en place */ - if (g_panel_item_is_docked(tgrid->def_panel)) - gtk_tiled_grid_remove(tgrid, tgrid->def_panel); - - } - - } - - } - - free(path); - -} - - -/****************************************************************************** -* * -* Paramètres : tgrid = conteneur d'affichage en tuiles à modifier. * -* panel = panneau d'affichage à supprimer. * -* * -* Description : Retire un panneau dans le conteneur en tuiles. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void gtk_tiled_grid_remove(GtkTiledGrid *tgrid, GPanelItem *panel) -{ - GtkWidget *station; /* Support courant */ - grid_tile_t *tile; /* Tuile d'accueil */ - - assert(g_panel_item_is_docked(panel)); - - gtk_dockable_decompose(GTK_DOCKABLE(panel), &station); - - tile = find_tile_for_widget(tgrid->tiles, station); - assert(tile != NULL); - - gtk_dock_station_remove_dockable(GTK_DOCK_STATION(station), GTK_DOCKABLE(panel)); - - g_panel_item_set_dock_at_startup(panel, false); - - if (gtk_notebook_get_n_pages(GTK_NOTEBOOK(station)) == 0) - { - /* Si le panneau par défaut devient nécessaire */ - if (tgrid->def_panel != NULL && tile->path[0] == 'M' && tile->path[1] == '\0') - gtk_tiled_grid_add(tgrid, tgrid->def_panel); - - else - { - /* La racine est concernée ! */ - if (tile->parent == NULL) - { - assert(tile == tgrid->tiles); - - g_object_ref(G_OBJECT(tile->widget)); - gtk_container_remove(GTK_CONTAINER(tgrid), tile->widget); - - delete_tile(tile); - tgrid->tiles = NULL; - - } - - else - collapse_tile(tile->parent, tile); - - } - - } - -} - - -/****************************************************************************** -* * -* Paramètres : tgrid = conteneur d'affichage en tuiles à consulter. * -* station = station d'accueil à retrouver. * -* * -* Description : Indique le chemin correspondant à une station intégrée. * -* * -* Retour : Copie de chemin trouvé, à libérer ensuite, ou NULL si échec. * -* * -* Remarques : - * -* * -******************************************************************************/ - -char *gtk_tiled_grid_get_path_for_station(const GtkTiledGrid *tgrid, GtkDockStation *station) -{ - char *result; /* Chemin d'accès à renvoyer */ - grid_tile_t *tile; /* Tuile d'accueil */ - - tile = find_tile_for_widget(tgrid->tiles, GTK_WIDGET(station)); - - if (tile == NULL) - result = NULL; - - else - result = strdup(tile->path); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : tgrid = conteneur d'affichage en tuiles à mettre à jour. * -* config = configuration à consulter. * -* * -* Description : Replace les positions des séparateurs de tuiles. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void gtk_tiled_grid_restore_positions(const GtkTiledGrid *tgrid, GGenConfig *config) -{ - - void visit_tiles_for_restoring(grid_tile_t *tile, const char *vpath) - { - GtkOrientation orientation; /* Direction de la tuile */ - char hint; /* Inutile donc indispensable */ - char *key; /* Clef d'accès à un paramètre */ - gint position; /* Nouvelle position de barre */ - size_t i; /* Boucle de parcours */ - char *child_key; /* Clef d'accès des suivants */ - - if (!IS_LEAF_TILE(tile)) - { - orientation = gtk_orientable_get_orientation(GTK_ORIENTABLE(tile->widget)); - - hint = orientation == GTK_ORIENTATION_HORIZONTAL ? 'h' : 'v'; - - asprintf(&key, "%s%c", vpath, hint); - - if (g_generic_config_get_value(config, key, &position)) - gtk_paned_set_position(GTK_PANED(tile->widget), position); - - for (i = 0; i < 2; i++) - { - asprintf(&child_key, "%s%zu", key, i); - - visit_tiles_for_restoring(tile->children[i], child_key); - - free(child_key); - - } - - free(key); - - } - - } - - - visit_tiles_for_restoring(tgrid->tiles, "gui.panels.positions.R"); - -} - - -/****************************************************************************** -* * -* Paramètres : tgrid = conteneur d'affichage en tuiles à consulter. * -* config = configuration à mettre à jour. * -* * -* Description : Sauvegarde les positions des séparateurs de tuiles. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void gtk_tiled_grid_save_positions(const GtkTiledGrid *tgrid, GGenConfig *config) -{ - - void visit_tiles_for_saving(grid_tile_t *tile, const char *vpath) - { - GtkOrientation orientation; /* Direction de la tuile */ - char hint; /* Inutile donc indispensable */ - char *key; /* Clef d'accès à un paramètre */ - gint position; /* Nouvelle position de barre */ - size_t i; /* Boucle de parcours */ - char *child_key; /* Clef d'accès des suivants */ - - if (!IS_LEAF_TILE(tile)) - { - orientation = gtk_orientable_get_orientation(GTK_ORIENTABLE(tile->widget)); - - hint = orientation == GTK_ORIENTATION_HORIZONTAL ? 'h' : 'v'; - - asprintf(&key, "%s%c", vpath, hint); - - position = gtk_paned_get_position(GTK_PANED(tile->widget)); - g_generic_config_create_or_udpdate_param(config, key, CPT_INTEGER, -1, position); - - for (i = 0; i < 2; i++) - { - asprintf(&child_key, "%s%zu", key, i); - - visit_tiles_for_saving(tile->children[i], child_key); - - free(child_key); - - } - - free(key); - - } - - } - - - visit_tiles_for_saving(tgrid->tiles, "gui.panels.positions.R"); - -} diff --git a/src/gtkext/tiledgrid.h b/src/gtkext/tiledgrid.h deleted file mode 100644 index 539e248..0000000 --- a/src/gtkext/tiledgrid.h +++ /dev/null @@ -1,85 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * tiledgrid.h - prototypes pour un composant d'affichage avec des chemins vers les composants contenus - * - * Copyright (C) 2018-2019 Cyrille Bagard - * - * This file is part of Chrysalide. - * - * Chrysalide is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * Chrysalide is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Chrysalide. If not, see . - */ - - -#ifndef _GTKEXT_TILEDGRID_H -#define _GTKEXT_TILEDGRID_H - - -#include - - -#include "gtkdockstation.h" -#include "../glibext/configuration.h" -#include "../gui/panel.h" - - - -/* --------------------------- INTERFACE DU COMPOSANT GTK --------------------------- */ - - -#define GTK_TYPE_TILED_GRID gtk_tiled_grid_get_type() -#define GTK_TILED_GRID(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GTK_TYPE_TILED_GRID, GtkTiledGrid)) -#define GTK_IS_TILED_GRID(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), GTK_TYPE_TILED_GRID)) -#define GTK_TILED_GRID_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), GTK_TYPE_TILED_GRID, GtkTiledGridClass)) -#define GTK_IS_TILED_GRID_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), GTK_TYPE_TILED_GRID)) -#define GTK_TILED_GRID_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GTK_TYPE_TILED_GRID, GtkTiledGridClass)) - - - -/* Conteneur pour un affichage en tuiles nommées (instance) */ -typedef struct _GtkTiledGrid GtkTiledGrid; - -/* Conteneur pour un affichage en tuiles nommées (classe) */ -typedef struct _GtkTiledGridClass GtkTiledGridClass; - - -/* Détermine le type du conteneur d'affichage en tuiles nommées. */ -GType gtk_tiled_grid_get_type(void); - -/* Crée une nouvelle instance de conteneur avec tuiles. */ -GtkWidget *gtk_tiled_grid_new(void); - -/* Donne le panneau fourni par défaut pour la zone principale. */ -GPanelItem *gtk_tiled_grid_get_default_main_panel(const GtkTiledGrid *); - -/* Fournit le panneau par défaut pour la zone principale. */ -void gtk_tiled_grid_set_default_main_panel(GtkTiledGrid *, GPanelItem *); - -/* Incorpore un nouveau panneau dans le conteneur en tuiles. */ -void gtk_tiled_grid_add(GtkTiledGrid *, GPanelItem *); - -/* Retire un panneau dans le conteneur en tuiles. */ -void gtk_tiled_grid_remove(GtkTiledGrid *, GPanelItem *); - -/* Indique le chemin correspondant à une station intégrée. */ -char *gtk_tiled_grid_get_path_for_station(const GtkTiledGrid *, GtkDockStation *); - -/* Replace les positions des séparateurs de tuiles. */ -void gtk_tiled_grid_restore_positions(const GtkTiledGrid *, GGenConfig *); - -/* Sauvegarde les positions des séparateurs de tuiles. */ -void gtk_tiled_grid_save_positions(const GtkTiledGrid *, GGenConfig *); - - - -#endif /* _GTKEXT_TILEDGRID_H */ diff --git a/src/gui/Makefile.am b/src/gui/Makefile.am index 2faef41..da46844 100644 --- a/src/gui/Makefile.am +++ b/src/gui/Makefile.am @@ -12,8 +12,6 @@ libgui_la_SOURCES = \ item-int.h \ item.h item.c \ menubar.h menubar.c \ - panel-int.h \ - panel.h panel.c \ resources.h resources.c \ status.h status.c \ theme.h theme.c diff --git a/src/gui/panel-int.h b/src/gui/panel-int.h deleted file mode 100644 index d54dc16..0000000 --- a/src/gui/panel-int.h +++ /dev/null @@ -1,138 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * panel-int.h - prototypes pour les définitions internes liées aux panneaux d'affichage - * - * Copyright (C) 2019 Cyrille Bagard - * - * This file is part of Chrysalide. - * - * Chrysalide is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * Chrysalide is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - - -#ifndef _GUI_PANELS_PANEL_INT_H -#define _GUI_PANELS_PANEL_INT_H - - -#include "panel.h" - - -#include - - -#include "item-int.h" -#include "../glibext/delayed.h" - - - -/* ------------------------- COEUR DES PANNEAUX D'AFFICHAGE ------------------------- */ - - -/* Fournit une indication sur la personnalité du panneau. */ -typedef PanelItemPersonality (* get_panel_personality_fc) (const GPanelItemClass *); - -/* Fournit une indication d'accroche du panneau au démarrage. */ -typedef bool (* dock_panel_at_startup_fc) (const GPanelItemClass *); - -/* Détermine si un panneau peut être filtré. */ -typedef bool (* can_search_panel_fc) (const GPanelItemClass *); - -/* Indique le chemin initial de la localisation d'un panneau. */ -typedef char * (* get_panel_path_fc) (const GPanelItemClass *); - -/* Indique la définition d'un éventuel raccourci clavier. */ -typedef char * (* get_panel_bindings_fc) (const GPanelItemClass *); - -/* Place un panneau dans l'ensemble affiché. */ -typedef void (* ack_dock_process_fc) (GPanelItem *); - -/* Supprime un panneau de l'ensemble affiché. */ -typedef void (* ack_undock_process_fc) (GPanelItem *); - -/* Démarre l'actualisation du filtrage du contenu. */ -typedef void (* update_filtered_fc) (GPanelItem *); - - -/* Elément réactif pour panneaux de l'éditeur (instance) */ -struct _GPanelItem -{ - GEditorItem parent; /* A laisser en premier */ - - bool docked; /* Panneau inscrusté ? */ - - GNamedWidget *widget; /* Composant avec noms */ - GtkWidget *cached_widget; /* Composant GTK récupéré */ - - char *filter; /* Eventuel filtre textuel */ - - cairo_surface_t *surface; /* Copie d'écran préalable */ - gdouble hadj_value; /* Sauvegarde de défilement #1 */ - gdouble vadj_value; /* Sauvegarde de défilement #2 */ - gint switched; /* Mémorise l'état de bascule */ - -}; - -/* Elément réactif pour panneaux de l'éditeur (classe) */ -struct _GPanelItemClass -{ - GEditorItemClass parent; /* A laisser en premier */ - - get_panel_personality_fc get_personality; /* Fourniture de nature */ - dock_panel_at_startup_fc dock_at_startup; /* Recommandation d'accroche */ - can_search_panel_fc can_search; /* Contenu fouillable ? */ - get_panel_path_fc get_path; /* Chemin vers la place idéale */ - get_panel_bindings_fc get_bindings; /* Raccourci clavier éventuel */ - - ack_dock_process_fc ack_dock; /* Prise en compte d'accroche */ - ack_undock_process_fc ack_undock; /* Prise en compte de décroche */ - - update_filtered_fc update_filtered; /* Lancement du filtrage */ - - wgroup_id_t gid; /* Groupe de travail dédié */ - - /* Signaux */ - - void (* dock_request) (GPanelItem); - void (* undock_request) (GPanelItem); - -}; - - -/* Fournit une indication sur la personnalité du panneau. */ -PanelItemPersonality gtk_panel_item_class_get_personality_singleton(const GPanelItemClass *); - -/* Renvoie false lors d'une consultation de la classe. */ -bool gtk_panel_item_class_return_false(const GPanelItemClass *); - -/* Renvoie true lors d'une consultation de la classe. */ -bool gtk_panel_item_class_return_true(const GPanelItemClass *); - - - -/* ---------------------- MECANISMES DE MISE A JOUR DE PANNEAU ---------------------- */ - - -/* Obtient le groupe de travail dédié à une mise à jour. */ -wgroup_id_t g_panel_item_get_group(const GPanelItem *); - -/* Bascule l'affichage d'un panneau avant sa mise à jour. */ -void g_panel_item_switch_to_updating_mask(GPanelItem *); - -/* Bascule l'affichage d'un panneau après sa mise à jour. */ -void g_panel_item_switch_to_updated_content(GPanelItem *); - - - -#endif /* _GUI_PANELS_PANEL_INT_H */ diff --git a/src/gui/panel.c b/src/gui/panel.c deleted file mode 100644 index 5b21620..0000000 --- a/src/gui/panel.c +++ /dev/null @@ -1,1119 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * panel.c - gestion des éléments réactifs spécifiques aux panneaux - * - * Copyright (C) 2019 Cyrille Bagard - * - * This file is part of Chrysalide. - * - * Chrysalide is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * Chrysalide is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - - -#include "panel.h" - - -#include -#include -#include - - -#include "panel-int.h" -#include "core/global.h" -#include "core/items.h" -#include "../common/extstr.h" -#include "../core/params.h" -#include "../gtkext/gtkdockable-int.h" -#include "../gtkext/named.h" -#include "../plugins/dt.h" -#include "../plugins/pglist.h" - - - -/* ------------------------- COEUR DES PANNEAUX D'AFFICHAGE ------------------------- */ - - -/* Initialise la classe des panneaux graphiques de l'éditeur. */ -static void g_panel_item_class_init(GPanelItemClass *); - -/* Initialise une instance de panneau graphique pour l'éditeur. */ -static void g_panel_item_init(GPanelItem *); - -/* Procède à l'initialisation de l'interface d'incrustation. */ -static void g_panel_item_dockable_interface_init(GtkDockableInterface *); - -/* Supprime toutes les références externes. */ -static void g_panel_item_dispose(GPanelItem *); - -/* Procède à la libération totale de la mémoire. */ -static void g_panel_item_finalize(GPanelItem *); - -/* Construit la chaîne d'accès à un élément de configuration. */ -static char *gtk_panel_item_class_build_configuration_key(const GPanelItemClass *, const char *); - -/* Fournit le nom court du composant encapsulable. */ -static char *gtk_panel_item_get_name(const GPanelItem *); - -/* Fournit le nom long du composant encapsulable. */ -static char *gtk_panel_item_get_desc(const GPanelItem *); - -/* Détermine si un panneau peut être filtré. */ -static bool gtk_panel_item_can_search(const GPanelItem *); - -/* Fournit le composant graphique intégrable dans un ensemble. */ -static GtkWidget *gtk_panel_item_get_widget(GPanelItem *); - -/* Démarre l'actualisation du filtrage du contenu. */ -static void gtk_panel_item_update_filtered(GPanelItem *, const char *); - - - -/* ---------------------- MECANISMES DE MISE A JOUR DE PANNEAU ---------------------- */ - - -/* Présente une copie de l'affichage du composant rafraîchi. */ -static gboolean g_panel_item_draw_mask(GtkWidget *, cairo_t *, GPanelItem *); - - - -/* ---------------------------------------------------------------------------------- */ -/* COEUR DES PANNEAUX D'AFFICHAGE */ -/* ---------------------------------------------------------------------------------- */ - - -/* Indique le type défini pour un élément destiné à un panneau. */ -G_DEFINE_TYPE_WITH_CODE(GPanelItem, g_panel_item, G_TYPE_EDITOR_ITEM, - G_IMPLEMENT_INTERFACE(GTK_TYPE_DOCKABLE, g_panel_item_dockable_interface_init)); - - -/****************************************************************************** -* * -* Paramètres : class = classe à initialiser. * -* * -* Description : Initialise la classe des panneaux graphiques de l'éditeur. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void g_panel_item_class_init(GPanelItemClass *class) -{ - GObjectClass *object; /* Autre version de la classe */ - GEditorItemClass *item; /* Encore une autre vision... */ - - object = G_OBJECT_CLASS(class); - - object->dispose = (GObjectFinalizeFunc/* ! */)g_panel_item_dispose; - object->finalize = (GObjectFinalizeFunc)g_panel_item_finalize; - - item = G_EDITOR_ITEM_CLASS(class); - - item->get_widget = (get_item_widget_fc)gtk_panel_item_get_widget; - - class->get_personality = gtk_panel_item_class_get_personality_singleton; - class->dock_at_startup = gtk_panel_item_class_return_true; - class->can_search = gtk_panel_item_class_return_false; - - g_signal_new("dock-request", - G_TYPE_PANEL_ITEM, - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET(GPanelItemClass, dock_request), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - - g_signal_new("undock-request", - G_TYPE_PANEL_ITEM, - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET(GPanelItemClass, undock_request), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - -} - - -/****************************************************************************** -* * -* Paramètres : item = instance à initialiser. * -* * -* Description : Initialise une instance de panneau graphique pour l'éditeur. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void g_panel_item_init(GPanelItem *item) -{ - item->docked = false; - - item->widget = NULL; - item->cached_widget = NULL; - - item->filter = NULL; - - g_atomic_int_set(&item->switched, 0); - -} - - -/****************************************************************************** -* * -* Paramètres : iface = interface GTK à initialiser. * -* * -* Description : Procède à l'initialisation de l'interface d'incrustation. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void g_panel_item_dockable_interface_init(GtkDockableInterface *iface) -{ - iface->get_name = (get_dockable_name_fc)gtk_panel_item_get_name; - iface->get_desc = (get_dockable_desc_fc)gtk_panel_item_get_desc; - iface->can_search = (can_dockable_search_fc)gtk_panel_item_can_search; - - iface->get_widget = (get_dockable_widget_fc)gtk_panel_item_get_widget; - iface->update_filtered = (update_filtered_data_fc)gtk_panel_item_update_filtered; - -} - - -/****************************************************************************** -* * -* Paramètres : item = instance d'objet GLib à traiter. * -* * -* Description : Supprime toutes les références externes. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void g_panel_item_dispose(GPanelItem *item) -{ - g_clear_object(&item->widget); - g_clear_object(&item->cached_widget); - - G_OBJECT_CLASS(g_panel_item_parent_class)->dispose(G_OBJECT(item)); - -} - - -/****************************************************************************** -* * -* Paramètres : item = instance d'objet GLib à traiter. * -* * -* Description : Procède à la libération totale de la mémoire. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void g_panel_item_finalize(GPanelItem *item) -{ - if (item->filter != NULL) - free(item->filter); - - if (item->surface != NULL) - cairo_surface_destroy(item->surface); - - G_OBJECT_CLASS(g_panel_item_parent_class)->finalize(G_OBJECT(item)); - -} - - -/****************************************************************************** -* * -* Paramètres : class = classe à consulter. * -* * -* Description : Fournit une indication sur la personnalité du panneau. * -* * -* Retour : Identifiant lié à la nature du panneau. * -* * -* Remarques : - * -* * -******************************************************************************/ - -PanelItemPersonality gtk_panel_item_class_get_personality(const GPanelItemClass *class) -{ - PanelItemPersonality result; /* Personnalité à retourner */ - - result = class->get_personality(class); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : class = classe à consulter. * -* * -* Description : Fournit une indication sur la personnalité du panneau. * -* * -* Retour : Identifiant lié à la nature unique du panneau. * -* * -* Remarques : - * -* * -******************************************************************************/ - -PanelItemPersonality gtk_panel_item_class_get_personality_singleton(const GPanelItemClass *class) -{ - PanelItemPersonality result; /* Personnalité à retourner */ - - result = PIP_SINGLETON; - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : class = classe à consulter. * -* * -* Description : Fournit une indication d'accroche du panneau au démarrage. * -* * -* Retour : true si le panneau doit être affiché de prime abord. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool gtk_panel_item_class_dock_at_startup(const GPanelItemClass *class) -{ - bool result; /* Statut à retourner */ - GGenConfig *config; /* Configuration courante */ - char *key; /* Clef d'accès à un paramètre */ -#ifndef NDEBUG - bool status; /* Bilan de consultation */ -#endif - - config = get_main_configuration(); - - key = gtk_panel_item_class_build_configuration_key(class, "dock_at_startup"); - -#ifndef NDEBUG - status = g_generic_config_get_value(config, key, &result); - assert(status); -#else - g_generic_config_get_value(config, key, &result); -#endif - - free(key); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : class = classe associée à la consultation. * -* * -* Description : Renvoie false lors d'une consultation de la classe. * -* * -* Retour : false. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool gtk_panel_item_class_return_false(const GPanelItemClass *class) -{ - bool result; /* Statut à retourner */ - - result = false; - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : class = classe associée à la consultation. * -* * -* Description : Renvoie true lors d'une consultation de la classe. * -* * -* Retour : true. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool gtk_panel_item_class_return_true(const GPanelItemClass *class) -{ - bool result; /* Statut à retourner */ - - result = true; - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : class = classe à consulter. * -* * -* Description : Détermine si un panneau peut être filtré. * -* * -* Retour : Bilan de la consultation. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool gtk_panel_item_class_can_search(const GPanelItemClass *class) -{ - bool result; /* Statut à retourner */ - - result = class->can_search(class); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : class = classe à consulter. * -* * -* Description : Indique le chemin initial de la localisation d'un panneau. * -* * -* Retour : Chemin fixé associé à la position initiale. * -* * -* Remarques : - * -* * -******************************************************************************/ - -char *gtk_panel_item_class_get_path(const GPanelItemClass *class) -{ - char *result; /* Emplacement à retourner */ - GGenConfig *config; /* Configuration courante */ - char *key; /* Clef d'accès à un paramètre */ - const char *path; /* Nouveau chemin de placement */ -#ifndef NDEBUG - bool status; /* Statut de l'encapsulation */ -#endif - - config = get_main_configuration(); - - key = gtk_panel_item_class_build_configuration_key(class, "path"); - -#ifndef NDEBUG - status = g_generic_config_get_value(config, key, &path); - assert(status); -#else - g_generic_config_get_value(config, key, &path); -#endif - - free(key); - - result = strdup(path); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : class = classe à consulter. * -* * -* Description : Indique la définition d'un éventuel raccourci clavier. * -* * -* Retour : Description d'un raccourci ou NULL si aucun de défini. * -* * -* Remarques : - * -* * -******************************************************************************/ - -char *gtk_panel_item_class_get_key_bindings(const GPanelItemClass *class) -{ - char *result; /* Emplacement à retourner */ - - if (class->get_bindings != NULL) - result = class->get_bindings(class); - - else - result = NULL; - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : class = classe du type de panneau à traiter. * -* attrib = élément de configuration à inclure dans le résultat.* -* * -* Description : Construit la chaîne d'accès à un élément de configuration. * -* * -* Retour : Chaîne de caractères à libérer après usage. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static char *gtk_panel_item_class_build_configuration_key(const GPanelItemClass *class, const char *attrib) -{ - char *result; /* Construction à renvoyer */ - const char *name; /* Nom court du panneau */ - - name = g_editor_item_class_get_key(G_EDITOR_ITEM_CLASS(class)); - - asprintf(&result, "gui.panels.%s.%s", attrib, name); - - result = strrpl(result, " ", "_"); - - result = strlower(result); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : class = classe de panneau à consulter. * -* config = configuration à compléter. * -* * -* Description : Met en place les bases de la configuration d'un panneau. * -* * -* Retour : Bilan de l'opération. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool gtk_panel_item_class_setup_configuration(const GPanelItemClass *class, GGenConfig *config) -{ - bool result; /* Bilan à retourner */ - char *key; /* Clef d'accès à un paramètre */ - bool dock_at_startup; /* Affichage dès le départ ? */ - char *path; /* Localisation du panneau */ - - key = gtk_panel_item_class_build_configuration_key(class, "dock_at_startup"); - - dock_at_startup = class->dock_at_startup(class); - - result = g_generic_config_create_param_if_not_exist(config, key, CPT_BOOLEAN, dock_at_startup); - - free(key); - - if (!result) - goto exit; - - key = gtk_panel_item_class_build_configuration_key(class, "path"); - - path = class->get_path(class); - - result = g_generic_config_create_param_if_not_exist(config, key, CPT_STRING, path); - - free(path); - - free(key); - - exit: - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : type = type de panneau à mettre en place. * -* path = emplacement d'affichage ou NULL. * -* * -* Description : Crée un élément de panneau réactif. * -* * -* Retour : Adresse de la structure mise en place. * -* * -* Remarques : - * -* * -******************************************************************************/ - -GPanelItem *g_panel_item_new(GType type, const char *path) -{ - GPanelItem *result; /* Structure à retourner */ - GPanelItemClass *class; /* Classe associée au type */ - PanelItemPersonality personality; /* Caractéristique de panneau */ - GtkTiledGrid *grid; /* Composant d'affichage */ - - class = g_type_class_ref(type); - - personality = gtk_panel_item_class_get_personality(class); - assert(path != NULL || personality == PIP_PERSISTENT_SINGLETON); - - g_type_class_unref(class); - - if (personality == PIP_PERSISTENT_SINGLETON || personality == PIP_SINGLETON) - { - result = G_PANEL_ITEM(find_editor_item_by_type(type)); - - if (result != NULL) - goto singleton; - - } - - result = create_object_from_type(type); - - grid = get_tiled_grid(); - - g_signal_connect_swapped(result, "dock-request", G_CALLBACK(gtk_tiled_grid_add), grid); - g_signal_connect_swapped(result, "undock-request", G_CALLBACK(gtk_tiled_grid_remove), grid); - - gtk_dockable_setup_dnd(GTK_DOCKABLE(result)); - - register_editor_item(G_EDITOR_ITEM(result)); - - notify_panel_creation(result); - - singleton: - - if (path != NULL) - { - if (path[0] != '\0') - gtk_panel_item_set_path(result, path); - - g_panel_item_dock(result); - - } - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : item = instance de panneau à consulter. * -* * -* Description : Indique le composant graphique principal du panneau. * -* * -* Retour : Composant graphique avec nom constituant le panneau. * -* * -* Remarques : - * -* * -******************************************************************************/ - -GNamedWidget *gtk_panel_item_get_named_widget(const GPanelItem *item) -{ - GNamedWidget *result; /* Composant nommé à retourner */ - - result = item->widget; - - g_object_ref(G_OBJECT(result)); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : item = instance GTK dont l'interface est à consulter. * -* * -* Description : Fournit le nom court du composant encapsulable. * -* * -* Retour : Désignation humaine pour titre d'onglet ou de fenêtre. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static char *gtk_panel_item_get_name(const GPanelItem *item) -{ - char *result; /* Désignation à retourner */ - - result = g_named_widget_get_name(G_NAMED_WIDGET(item->widget), false); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : item = instance GTK dont l'interface est à consulter. * -* * -* Description : Fournit le nom long du composant encapsulable. * -* * -* Retour : Désignation humaine pour titre d'onglet ou de fenêtre. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static char *gtk_panel_item_get_desc(const GPanelItem *item) -{ - char *result; /* Description à retourner */ - - result = g_named_widget_get_name(G_NAMED_WIDGET(item->widget), true); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : item = instance GTK dont l'interface est à consulter. * -* * -* Description : Détermine si un panneau peut être filtré. * -* * -* Retour : Bilan de la consultation. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static bool gtk_panel_item_can_search(const GPanelItem *item) -{ - bool result; /* Indication à retourner */ - GPanelItemClass *class; /* Classe de l'élément visé */ - - class = G_PANEL_ITEM_GET_CLASS(item); - - result = gtk_panel_item_class_can_search(class); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : item = instance GTK dont l'interface est à consulter. * -* * -* Description : Fournit le composant graphique intégrable dans un ensemble. * -* * -* Retour : Composant graphique prêt à emploi. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static GtkWidget *gtk_panel_item_get_widget(GPanelItem *item) -{ - GtkWidget *result; /* Composant à retourner */ - - if (item->cached_widget == NULL) - item->cached_widget = g_named_widget_get_widget(G_NAMED_WIDGET(item->widget)); - - result = item->cached_widget; - - g_object_ref(G_OBJECT(result)); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : item = instance GTK dont l'interface est à sollicitée. * -* * -* Description : Démarre l'actualisation du filtrage du contenu. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void gtk_panel_item_update_filtered(GPanelItem *item, const char *filter) -{ - assert(gtk_panel_item_can_search(item)); - - if (item->filter != NULL) - free(item->filter); - - item->filter = (filter ? strdup(filter) : NULL); - - G_PANEL_ITEM_GET_CLASS(item)->update_filtered(item); - -} - - -/****************************************************************************** -* * -* Paramètres : item = instance GTK à consulter. * -* path = nouvelle emplacement d'inclusion. * -* * -* Description : Définit le chemin d'accès à utiliser pour les encapsulations.* -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void gtk_panel_item_set_path(GPanelItem *item, const char *path) -{ - GGenConfig *config; /* Configuration courante */ - char *key; /* Clef d'accès à un paramètre */ - - config = get_main_configuration(); - - key = gtk_panel_item_class_build_configuration_key(G_PANEL_ITEM_GET_CLASS(item), "path"); - - g_generic_config_set_value(config, key, path); - - free(key); - -} - - -/****************************************************************************** -* * -* Paramètres : item = composant à présenter à l'affichage. * -* * -* Description : Place un panneau dans l'ensemble affiché. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void g_panel_item_dock(GPanelItem *item) -{ - assert(!item->docked); - - g_signal_emit_by_name(item, "dock-request"); - - if (G_PANEL_ITEM_GET_CLASS(item)->ack_dock != NULL) - G_PANEL_ITEM_GET_CLASS(item)->ack_dock(item); - - notify_panel_docking(item, true); - -} - - -/****************************************************************************** -* * -* Paramètres : item = composant d'affichage à mettre à jour. * -* status = nouvel état d'encapsulation. * -* * -* Description : Définit si le composant repose sur un support de l'éditeur. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void g_panel_item_set_dock_at_startup(GPanelItem *item, bool status) -{ - char *key; /* Clef d'accès à un paramètre */ - - item->docked = status; - - key = gtk_panel_item_class_build_configuration_key(G_PANEL_ITEM_GET_CLASS(item), "dock_at_startup"); - - g_generic_config_set_value(get_main_configuration(), key, status); - - free(key); - -} - - -/****************************************************************************** -* * -* Paramètres : item = composant d'affichage à consulter. * -* * -* Description : Indique si le composant repose sur un support de l'éditeur. * -* * -* Retour : true si le composant est bien incrusté quelque part. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool g_panel_item_is_docked(const GPanelItem *item) -{ - bool result; /* Status à retourner */ - - result = item->docked; - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : item = composant à retirer de l'affichage. * -* * -* Description : Supprime un panneau de l'ensemble affiché. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void g_panel_item_undock(GPanelItem *item) -{ - PanelItemPersonality personality; /* Caractéristique de panneau */ - - assert(item->docked); - - g_signal_emit_by_name(item, "undock-request"); - - if (G_PANEL_ITEM_GET_CLASS(item)->ack_undock != NULL) - G_PANEL_ITEM_GET_CLASS(item)->ack_undock(item); - - notify_panel_docking(item, false); - - personality = gtk_panel_item_class_get_personality(G_PANEL_ITEM_GET_CLASS(item)); - - if (personality != PIP_PERSISTENT_SINGLETON) - unregister_editor_item(G_EDITOR_ITEM(item)); - -} - - - -/* ---------------------------------------------------------------------------------- */ -/* MECANISMES DE MISE A JOUR DE PANNEAU */ -/* ---------------------------------------------------------------------------------- */ - - -/****************************************************************************** -* * -* Paramètres : item = panneau ciblé par une mise à jour. * -* * -* Description : Obtient le groupe de travail dédié à une mise à jour. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -wgroup_id_t g_panel_item_get_group(const GPanelItem *item) -{ - wgroup_id_t result; /* Identifiant à retourner */ - - result = G_PANEL_ITEM_GET_CLASS(item)->gid; - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : widget = composant graphique sur lequel dessiner. * -* cr = contexte graphique pour le dessin. * -* panel = panneau ciblé par une mise à jour. * -* * -* Description : Présente une copie de l'affichage du composant rafraîchi. * -* * -* Retour : FALSE afin de poursuivre les traitements. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static gboolean g_panel_item_draw_mask(GtkWidget *widget, cairo_t *cr, GPanelItem *item) -{ - int width; /* Largeur du composant actuel */ - int height; /* Hauteur du composant actuel */ - - width = gtk_widget_get_allocated_width(widget); - height = gtk_widget_get_allocated_height(widget); - - cairo_save(cr); - - cairo_set_source_surface(cr, item->surface, 0, 0); - cairo_rectangle(cr, 0, 0, width, height); - - cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE); - cairo_fill(cr); - - cairo_restore(cr); - - return FALSE; - -} - - -/****************************************************************************** -* * -* Paramètres : panel = panneau ciblé par une mise à jour. * -* * -* Description : Bascule l'affichage d'un panneau avant sa mise à jour. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void g_panel_item_switch_to_updating_mask(GPanelItem *item) -{ - GtkBuilder *builder; /* Constructeur sous-jacent */ - GtkWidget *content; /* Composant à faire évoluer */ - GdkWindow *window; /* Fenêtre au contenu à copier */ - int width; /* Largeur du composant actuel */ - int height; /* Hauteur du composant actuel */ - cairo_t *cr; /* Pinceau pour les dessins */ - GtkAdjustment *adj; /* Défilement éventuel */ - GtkStack *stack; /* Pile de composants GTK */ - GtkWidget *mask; /* Masque des travaux */ - - if (g_atomic_int_add(&item->switched, 1) > 0) - return; - - /* Copie de l'affichage courant */ - - assert(item->surface == NULL); - - builder = gtk_built_named_widget_get_builder(GTK_BUILT_NAMED_WIDGET(item->widget)); - - content = GTK_WIDGET(gtk_builder_get_object(builder, "content")); - - window = gtk_widget_get_window(content); - - if (window != NULL) - { - width = gtk_widget_get_allocated_width(content); - height = gtk_widget_get_allocated_height(content); - - item->surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height); - - cr = cairo_create(item->surface); - - gdk_cairo_set_source_window(cr, window, 0, 0); - - cairo_paint(cr); - - cairo_destroy(cr); - - } - - /* Sauvegarde de l'éventuelle position */ - - if (GTK_IS_SCROLLED_WINDOW(content)) - { - adj = gtk_scrolled_window_get_hadjustment(GTK_SCROLLED_WINDOW(content)); - item->hadj_value = gtk_adjustment_get_value(adj); - - adj = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(content)); - item->vadj_value = gtk_adjustment_get_value(adj); - - } - - /* Opération de basculement effectif */ - - stack = GTK_STACK(gtk_builder_get_object(builder, "stack")); - - mask = GTK_WIDGET(gtk_builder_get_object(builder, "mask")); - - gtk_spinner_start(GTK_SPINNER(mask)); - - if (item->surface != NULL) - g_signal_connect(mask, "draw", G_CALLBACK(g_panel_item_draw_mask), item); - - gtk_stack_set_visible_child(stack, mask); - - g_object_unref(G_OBJECT(builder)); - -} - - -/****************************************************************************** -* * -* Paramètres : panel = panneau ciblé par une mise à jour. * -* * -* Description : Bascule l'affichage d'un panneau après sa mise à jour. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void g_panel_item_switch_to_updated_content(GPanelItem *item) -{ - GtkBuilder *builder; /* Constructeur sous-jacent */ - GtkWidget *content; /* Composant à faire évoluer */ - GtkAdjustment *adj; /* Défilement éventuel */ - GtkStack *stack; /* Pile de composants GTK */ - GtkWidget *mask; /* Masque des travaux */ - - if (g_atomic_int_get(&item->switched) > 1) - goto skip; - - /* Restauration d'une éventuelle position */ - - builder = gtk_built_named_widget_get_builder(GTK_BUILT_NAMED_WIDGET(item->widget)); - - content = GTK_WIDGET(gtk_builder_get_object(builder, "content")); - - if (GTK_IS_SCROLLED_WINDOW(content)) - { - adj = gtk_scrolled_window_get_hadjustment(GTK_SCROLLED_WINDOW(content)); - gtk_adjustment_set_value(adj, item->hadj_value); - - adj = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(content)); - gtk_adjustment_set_value(adj, item->vadj_value); - - } - - /* Opération de basculement effectif */ - - stack = GTK_STACK(gtk_builder_get_object(builder, "stack")); - - gtk_stack_set_visible_child(stack, content); - - mask = GTK_WIDGET(gtk_builder_get_object(builder, "mask")); - - g_signal_handlers_disconnect_by_func(mask, G_CALLBACK(g_panel_item_draw_mask), item); - - gtk_spinner_stop(GTK_SPINNER(mask)); - - /* Supression de la copie d'affichage */ - - if (item->surface != NULL) - { - cairo_surface_destroy(item->surface); - item->surface = NULL; - } - - g_object_unref(G_OBJECT(builder)); - - skip: - - g_atomic_int_dec_and_test(&item->switched); - -} diff --git a/src/gui/panel.h b/src/gui/panel.h deleted file mode 100644 index de8d2bf..0000000 --- a/src/gui/panel.h +++ /dev/null @@ -1,112 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * panel.h - prototypes pour la gestion des éléments réactifs spécifiques aux panneaux - * - * Copyright (C) 2019 Cyrille Bagard - * - * This file is part of Chrysalide. - * - * Chrysalide is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * Chrysalide is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - - -#ifndef _GUI_PANELS_PANEL_H -#define _GUI_PANELS_PANEL_H - - -#include -#include - - -#include "../glibext/configuration.h" -#include "../glibext/named.h" - - - -#define G_TYPE_PANEL_ITEM g_panel_item_get_type() -#define G_PANEL_ITEM(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_PANEL_ITEM, GPanelItem)) -#define G_IS_PANEL_ITEM(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_PANEL_ITEM)) -#define G_PANEL_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_PANEL_ITEM, GPanelItemClass)) -#define G_IS_PANEL_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_PANEL_ITEM)) -#define G_PANEL_ITEM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_PANEL_ITEM, GPanelItemClass)) - - -/* Elément réactif pour panneaux de l'éditeur (instance) */ -typedef struct _GPanelItem GPanelItem; - -/* Elément réactif pour panneaux de l'éditeur (classe) */ -typedef struct _GPanelItemClass GPanelItemClass; - - -/* Types de panneaux pour éditeur */ -typedef enum _PanelItemPersonality -{ - PIP_INVALID, /* Information non initialisée */ - - PIP_SINGLETON, /* Instance unique */ - PIP_PERSISTENT_SINGLETON, /* Instance unique permanente */ - PIP_BINARY_VIEW, /* Affichage d'un binaire */ - PIP_OTHER, /* Reste du monde */ - - PIP_COUNT - -} PanelItemPersonality; - - -/* Indique le type défini pour un élément destiné à un panneau. */ -GType g_panel_item_get_type(void); - -/* Fournit une indication sur la personnalité du panneau. */ -PanelItemPersonality gtk_panel_item_class_get_personality(const GPanelItemClass *); - -/* Fournit une indication d'accroche du panneau au démarrage. */ -bool gtk_panel_item_class_dock_at_startup(const GPanelItemClass *); - -/* Détermine si un panneau peut être filtré. */ -bool gtk_panel_item_class_can_search(const GPanelItemClass *); - -/* Indique le chemin initial de la localisation d'un panneau. */ -char *gtk_panel_item_class_get_path(const GPanelItemClass *); - -/* Indique la définition d'un éventuel raccourci clavier. */ -char *gtk_panel_item_class_get_key_bindings(const GPanelItemClass *); - -/* Met en place les bases de la configuration du panneau. */ -bool gtk_panel_item_class_setup_configuration(const GPanelItemClass *, GGenConfig *); - -/* Crée un élément de panneau réactif. */ -GPanelItem *g_panel_item_new(GType, const char *); - -/* Indique le composant graphique principal du panneau. */ -GNamedWidget *gtk_panel_item_get_named_widget(const GPanelItem *); - -/* Définit le chemin d'accès à utiliser pour les encapsulations. */ -void gtk_panel_item_set_path(GPanelItem *, const char *); - -/* Place un panneau dans l'ensemble affiché. */ -void g_panel_item_dock(GPanelItem *); - -/* Définit si le composant repose sur un support de l'éditeur. */ -void g_panel_item_set_dock_at_startup(GPanelItem *, bool); - -/* Indique si le composant repose sur un support de l'éditeur. */ -bool g_panel_item_is_docked(const GPanelItem *); - -/* Supprime un panneau de l'ensemble affiché. */ -void g_panel_item_undock(GPanelItem *); - - - -#endif /* _GUI_PANELS_PANEL_H */ -- cgit v0.11.2-87-g4458