From 9d0d5edf372a9f681bbfd0a3639ee8fc367ce96d Mon Sep 17 00:00:00 2001 From: Cyrille Bagard Date: Sun, 14 Jul 2024 19:58:45 +0200 Subject: Setup basic features for framework GUI panels. --- src/gtkext/Makefile.am | 7 +- src/gtkext/dockstation.c | 225 +++++++++- src/gtkext/dockstation.h | 36 +- src/gtkext/grid.c | 431 +++++++++--------- src/gtkext/grid.h | 37 +- src/gtkext/panel-int.h | 35 +- src/gtkext/panel.c | 123 ++++- src/gtkext/panel.h | 30 +- src/gui/panel-int.h | 138 ++++++ src/gui/panel.c | 1119 ++++++++++++++++++++++++++++++++++++++++++++++ src/gui/panel.h | 112 +++++ 11 files changed, 2054 insertions(+), 239 deletions(-) create mode 100644 src/gui/panel-int.h create mode 100644 src/gui/panel.c create mode 100644 src/gui/panel.h diff --git a/src/gtkext/Makefile.am b/src/gtkext/Makefile.am index b147f29..2eb6821 100644 --- a/src/gtkext/Makefile.am +++ b/src/gtkext/Makefile.am @@ -18,7 +18,6 @@ libgtkext_la_SOURCES = \ hexdisplay.h hexdisplay.c \ named-int.h \ named.h named.c \ - resources.h resources.c \ support.h support.c \ tmgt.h tmgt.c @@ -39,8 +38,14 @@ libgtkext4_la_SOURCES = \ bufferview.h bufferview.c \ contentview-int.h \ contentview.h contentview.c \ + dockstation-int.h \ + dockstation.h dockstation.c \ + grid-int.h \ + grid.h grid.c \ hexview-int.h \ hexview.h hexview.c \ + panel-int.h \ + panel.h panel.c \ resources.h resources.c libgtkext4_la_CFLAGS = $(LIBGTK4_CFLAGS) diff --git a/src/gtkext/dockstation.c b/src/gtkext/dockstation.c index 1757542..093f120 100644 --- a/src/gtkext/dockstation.c +++ b/src/gtkext/dockstation.c @@ -1,8 +1,8 @@ /* Chrysalide - Outil d'analyse de fichiers binaires - * gtkdockstation.c - manipulation et l'affichage de composants rassemblés + * dockstation.c - manipulation et l'affichage de composants rassemblés * - * Copyright (C) 2012-2019 Cyrille Bagard + * Copyright (C) 2012-2024 Cyrille Bagard * * This file is part of Chrysalide. * @@ -21,9 +21,224 @@ */ -#include "gtkdockstation.h" +#include "dockstation.h" +#include "dockstation-int.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 *); + +/* Supprime toutes les références externes. */ +static void gtk_dock_station_dispose(GtkDockStation *); + +/* Procède à la libération totale de la mémoire. */ +static void gtk_dock_station_finalize(GtkDockStation *); + + + + +/* Détermine le type du composant d'affichage concentré. */ +G_DEFINE_TYPE(GtkDockStation, gtk_dock_station, GTK_TYPE_WIDGET) + + +/****************************************************************************** +* * +* 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) +{ + GObjectClass *object; /* Autre version de la classe */ + + object = G_OBJECT_CLASS(class); + + object->dispose = (GObjectFinalizeFunc/* ! */)gtk_dock_station_dispose; + object->finalize = (GObjectFinalizeFunc)gtk_dock_station_finalize; + + 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) +{ +#if 0 + + 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); + +#endif + +} + + +/****************************************************************************** +* * +* Paramètres : station = instance d'objet GLib à traiter. * +* * +* Description : Supprime toutes les références externes. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void gtk_dock_station_dispose(GtkDockStation *station) +{ + G_OBJECT_CLASS(gtk_dock_station_parent_class)->dispose(G_OBJECT(station)); + +} + + +/****************************************************************************** +* * +* Paramètres : station = instance d'objet GLib à traiter. * +* * +* Description : Procède à la libération totale de la mémoire. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void gtk_dock_station_finalize(GtkDockStation *station) +{ + G_OBJECT_CLASS(gtk_dock_station_parent_class)->finalize(G_OBJECT(station)); + +} + + +/****************************************************************************** +* * +* Paramètres : - * +* * +* Description : Crée un nouveau composant pour support d'affichage concentré.* +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +GtkWidget *gtk_dock_station_new(void) +{ + GtkWidget *result; /* Instance à retourner */ + + result = g_object_new(GTK_TYPE_DOCK_STATION, NULL); + + return result; + +} + + + + + + + +#if 0 + #include #include @@ -465,3 +680,7 @@ static void on_click_for_close(GtkButton *button, GtkDockStation *station) g_signal_emit_by_name(station, "close-requested", button); } + + +#endif + diff --git a/src/gtkext/dockstation.h b/src/gtkext/dockstation.h index f286c1c..a857626 100644 --- a/src/gtkext/dockstation.h +++ b/src/gtkext/dockstation.h @@ -1,8 +1,8 @@ /* Chrysalide - Outil d'analyse de fichiers binaires - * gtkdockstation.h - prototypes pour la manipulation et l'affichage de composants rassemblés + * dockstation.h - prototypes pour la manipulation et l'affichage de composants rassemblés * - * Copyright (C) 2012-2018 Cyrille Bagard + * Copyright (C) 2012-2024 Cyrille Bagard * * This file is part of Chrysalide. * @@ -21,13 +21,35 @@ */ -#ifndef _GTKEXT_GTKDOCKSTATION_H -#define _GTKEXT_GTKDOCKSTATION_H +#ifndef _GTKEXT_DOCKSTATION_H +#define _GTKEXT_DOCKSTATION_H #include +#include "../glibext/helpers.h" + + + +#define GTK_TYPE_DOCK_STATION (gtk_dock_station_get_type()) + +DECLARE_GTYPE(GtkDockStation, gtk_dock_station, GTK, DOCK_STATION); + + +/* Crée un nouveau composant pour support d'affichage concentré. */ +GtkWidget *gtk_dock_station_new(void); + + + + + + +#if 0 + +#include + + #include "gtkdockable.h" @@ -76,9 +98,6 @@ struct _GtkDockStationClass /* 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 *); @@ -92,6 +111,7 @@ void gtk_dock_station_remove_dockable(GtkDockStation *, GtkDockable *); //G_END_DECLS +#endif -#endif /* _GTKEXT_GTKDOCKSTATION_H */ +#endif /* _GTKEXT_DOCKSTATION_H */ diff --git a/src/gtkext/grid.c b/src/gtkext/grid.c index 22b2680..1b9c909 100644 --- a/src/gtkext/grid.c +++ b/src/gtkext/grid.c @@ -1,8 +1,8 @@ /* Chrysalide - Outil d'analyse de fichiers binaires - * tiledgrid.c - composant d'affichage avec des chemins vers les composants contenus + * grid.c - composant d'affichage avec des chemins vers les composants contenus * - * Copyright (C) 2018-2019 Cyrille Bagard + * Copyright (C) 2018-2024 Cyrille Bagard * * This file is part of Chrysalide. * @@ -21,36 +21,17 @@ */ -#include "tiledgrid.h" +#include "grid.h" -#include -#include -#include -#include - +#include "grid-int.h" -#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; \ @@ -60,6 +41,214 @@ typedef struct _grid_tile_t }) +/* Supprime une tuile de la mémoire. */ +static void delete_tile(grid_tile_t *); + + + +/* --------------------------- INTERFACE DU COMPOSANT GTK --------------------------- */ + + +/* Initialise la classe des conteneurs d'affichage en tuiles. */ +static void gtk_tiling_grid_class_init(GtkTilingGridClass *); + +/* Initialise une instance de conteneur d'affichage en tuiles. */ +static void gtk_tiling_grid_init(GtkTilingGrid *); + +/* Supprime toutes les références externes. */ +static void gtk_tiling_grid_dispose(GtkTilingGrid *); + +/* Procède à la libération totale de la mémoire. */ +static void gtk_tiling_grid_finalize(GtkTilingGrid *); + + + + + +/* ---------------------------------------------------------------------------------- */ +/* GESTION DES TUILES AFFICHEES */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +* * +* 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); + + unref_object(tile->widget); + + free(tile); + +} + + + +/* ---------------------------------------------------------------------------------- */ +/* INTERFACE DU COMPOSANT GTK */ +/* ---------------------------------------------------------------------------------- */ + + +/* Détermine le type du conteneur d'affichage en tuiles nommées. */ +G_DEFINE_TYPE(GtkTilingGrid, gtk_tiling_grid, GTK_TYPE_WIDGET) + + +/****************************************************************************** +* * +* Paramètres : klass = classe GTK à initialiser. * +* * +* Description : Initialise la classe des conteneurs d'affichage en tuiles. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void gtk_tiling_grid_class_init(GtkTilingGridClass *klass) +{ + GObjectClass *object; /* Autre version de la classe */ + + object = G_OBJECT_CLASS(klass); + + object->dispose = (GObjectFinalizeFunc/* ! */)gtk_tiling_grid_dispose; + object->finalize = (GObjectFinalizeFunc)gtk_tiling_grid_finalize; + + g_signal_new("station-created", + GTK_TYPE_TILING_GRID, + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET(GtkTilingGridClass, station_created), + NULL, NULL, + g_cclosure_marshal_VOID__OBJECT, + G_TYPE_NONE, 1, GTK_TYPE_WIDGET/*DOCK_STATION FIXME */); + +} + + +/****************************************************************************** +* * +* Paramètres : tgrid = instance GTK à initialiser. * +* * +* Description : Initialise une instance de conteneur d'affichage en tuiles. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void gtk_tiling_grid_init(GtkTilingGrid *tgrid) +{ + tgrid->tiles = NULL; + + tgrid->def_panel = NULL; + +} + + +/****************************************************************************** +* * +* Paramètres : grid = instance d'objet GLib à traiter. * +* * +* Description : Supprime toutes les références externes. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void gtk_tiling_grid_dispose(GtkTilingGrid *grid) +{ + if (grid->tiles != NULL) + { + delete_tile(grid->tiles); + grid->tiles = NULL; + } + + g_clear_object(&grid->def_panel); + + G_OBJECT_CLASS(gtk_tiling_grid_parent_class)->dispose(G_OBJECT(grid)); + +} + + +/****************************************************************************** +* * +* Paramètres : grid = instance d'objet GLib à traiter. * +* * +* Description : Procède à la libération totale de la mémoire. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void gtk_tiling_grid_finalize(GtkTilingGrid *grid) +{ + G_OBJECT_CLASS(gtk_tiling_grid_parent_class)->finalize(G_OBJECT(grid)); + +} + + +/****************************************************************************** +* * +* Paramètres : - * +* * +* Description : Crée une nouvelle instance de conteneur avec tuiles. * +* * +* Retour : Composant GTK mis en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GtkWidget *gtk_tiling_grid_new(void) +{ + GtkWidget *result; /* Instance à retourner */ + + result = g_object_new(GTK_TYPE_TILING_GRID, NULL); + + return result; + +} + + + + + + +#if 0 + + +#include +#include +#include +#include + + +#include "../core/logs.h" + + + /* Valide un chemin d'accès à une tuile. */ static bool is_valid_tile_path(const char *); @@ -70,7 +259,7 @@ static grid_tile_t *create_leaf_tile(const char *, GtkTiledGrid *); 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 *); +//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 *); @@ -92,40 +281,6 @@ 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 *); @@ -186,7 +341,7 @@ static bool is_valid_tile_path(const char *path) /****************************************************************************** * * * Paramètres : path = chemin d'accès à la future tuile. * -* Paramètres : tgrid = conteneur d'affichage en tuiles à manipuler. * +* tgrid = conteneur d'affichage en tuiles à manipuler. * * * * Description : Crée une tuile finale d'affichage de panneaux. * * * @@ -278,35 +433,6 @@ static grid_tile_t *create_inter_tile(grid_tile_t *parent, bool horiz, grid_tile } -/****************************************************************************** -* * -* 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); - -} - /****************************************************************************** * * @@ -659,132 +785,6 @@ static grid_tile_t *find_tile_for_widget(grid_tile_t *tile, GtkWidget *widget) -/* ---------------------------------------------------------------------------------- */ -/* 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); - -} - /****************************************************************************** * * @@ -1141,3 +1141,6 @@ void gtk_tiled_grid_save_positions(const GtkTiledGrid *tgrid, GGenConfig *config visit_tiles_for_saving(tgrid->tiles, "gui.panels.positions.R"); } + + +#endif diff --git a/src/gtkext/grid.h b/src/gtkext/grid.h index 539e248..d9b7ef1 100644 --- a/src/gtkext/grid.h +++ b/src/gtkext/grid.h @@ -2,7 +2,7 @@ /* 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 + * Copyright (C) 2018-2024 Cyrille Bagard * * This file is part of Chrysalide. * @@ -21,13 +21,40 @@ */ -#ifndef _GTKEXT_TILEDGRID_H -#define _GTKEXT_TILEDGRID_H +#ifndef _GTKEXT_GRID_H +#define _GTKEXT_GRID_H #include +#include "dockstation.h" +#include "panel.h" +#include "../glibext/helpers.h" + + + +#define GTK_TYPE_TILING_GRID (gtk_tiling_grid_get_type()) + +DECLARE_GTYPE(GtkTilingGrid, gtk_tiling_grid, GTK, TILING_GRID); + + +/* Crée une nouvelle instance de conteneur avec tuiles. */ +GtkWidget *gtk_tiling_grid_new(void); + + + + + + + + + +#if 0 + +#include + + #include "gtkdockstation.h" #include "../glibext/configuration.h" #include "../gui/panel.h" @@ -81,5 +108,7 @@ void gtk_tiled_grid_restore_positions(const GtkTiledGrid *, GGenConfig *); void gtk_tiled_grid_save_positions(const GtkTiledGrid *, GGenConfig *); +#endif + -#endif /* _GTKEXT_TILEDGRID_H */ +#endif /* _GTKEXT_GRID_H */ diff --git a/src/gtkext/panel-int.h b/src/gtkext/panel-int.h index d54dc16..7699f73 100644 --- a/src/gtkext/panel-int.h +++ b/src/gtkext/panel-int.h @@ -2,7 +2,7 @@ /* 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 + * Copyright (C) 2019-2024 Cyrille Bagard * * This file is part of Chrysalide. * @@ -22,13 +22,37 @@ */ -#ifndef _GUI_PANELS_PANEL_INT_H -#define _GUI_PANELS_PANEL_INT_H +#ifndef _GTKEXT_PANEL_INT_H +#define _GTKEXT_PANEL_INT_H #include "panel.h" + +/* Elément réactif pour panneaux de l'éditeur (instance) */ +struct _GtkTiledPanel +{ + GtkWidget parent; /* A laisser en premier */ + +}; + +/* Elément réactif pour panneaux de l'éditeur (classe) */ +struct _GtkTiledPanelClass +{ + GtkWidgetClass parent; /* A laisser en premier */ + +}; + + + + + + + + +#if 0 + #include @@ -134,5 +158,8 @@ void g_panel_item_switch_to_updating_mask(GPanelItem *); void g_panel_item_switch_to_updated_content(GPanelItem *); +#endif + + -#endif /* _GUI_PANELS_PANEL_INT_H */ +#endif /* _GTKEXT_PANEL_INT_H */ diff --git a/src/gtkext/panel.c b/src/gtkext/panel.c index 5b21620..f0c39aa 100644 --- a/src/gtkext/panel.c +++ b/src/gtkext/panel.c @@ -2,7 +2,7 @@ /* Chrysalide - Outil d'analyse de fichiers binaires * panel.c - gestion des éléments réactifs spécifiques aux panneaux * - * Copyright (C) 2019 Cyrille Bagard + * Copyright (C) 2019-2024 Cyrille Bagard * * This file is part of Chrysalide. * @@ -25,6 +25,125 @@ #include "panel.h" +#include "panel-int.h" + + + + + +/* Initialise la classe des panneaux graphiques de l'éditeur. */ +static void gtk_tiled_panel_class_init(GtkTiledPanelClass *); + +/* Initialise une instance de panneau graphique pour l'éditeur. */ +static void gtk_tiled_panel_init(GtkTiledPanel *); + +/* Supprime toutes les références externes. */ +static void gtk_tiled_panel_dispose(GtkTiledPanel *); + +/* Procède à la libération totale de la mémoire. */ +static void gtk_tiled_panel_finalize(GtkTiledPanel *); + + + + + + + + +/* Détermine le type du conteneur d'affichage en tuiles nommées. */ +G_DEFINE_TYPE(GtkTiledPanel, gtk_tiled_panel, GTK_TYPE_WIDGET) + + +/****************************************************************************** +* * +* Paramètres : klass = classe GTK à initialiser. * +* * +* Description : Initialise la classe des panneaux graphiques de l'éditeur. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void gtk_tiled_panel_class_init(GtkTiledPanelClass *klass) +{ + GObjectClass *object; /* Autre version de la classe */ + + object = G_OBJECT_CLASS(klass); + + object->dispose = (GObjectFinalizeFunc/* ! */)gtk_tiled_panel_dispose; + object->finalize = (GObjectFinalizeFunc)gtk_tiled_panel_finalize; + +} + + +/****************************************************************************** +* * +* Paramètres : panel = instance GTK à initialiser. * +* * +* Description : Initialise une instance de panneau graphique pour l'éditeur. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void gtk_tiled_panel_init(GtkTiledPanel *panel) +{ + +} + + +/****************************************************************************** +* * +* Paramètres : panel = instance d'objet GLib à traiter. * +* * +* Description : Supprime toutes les références externes. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void gtk_tiled_panel_dispose(GtkTiledPanel *panel) +{ + G_OBJECT_CLASS(gtk_tiled_panel_parent_class)->dispose(G_OBJECT(panel)); + +} + + +/****************************************************************************** +* * +* Paramètres : panel = instance d'objet GLib à traiter. * +* * +* Description : Procède à la libération totale de la mémoire. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void gtk_tiled_panel_finalize(GtkTiledPanel *panel) +{ + G_OBJECT_CLASS(gtk_tiled_panel_parent_class)->finalize(G_OBJECT(panel)); + +} + + + + + + + + + + +#if 0 + #include #include #include @@ -1117,3 +1236,5 @@ void g_panel_item_switch_to_updated_content(GPanelItem *item) g_atomic_int_dec_and_test(&item->switched); } + +#endif diff --git a/src/gtkext/panel.h b/src/gtkext/panel.h index de8d2bf..407cb06 100644 --- a/src/gtkext/panel.h +++ b/src/gtkext/panel.h @@ -2,7 +2,7 @@ /* 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 + * Copyright (C) 2019-2024 Cyrille Bagard * * This file is part of Chrysalide. * @@ -22,10 +22,30 @@ */ -#ifndef _GUI_PANELS_PANEL_H -#define _GUI_PANELS_PANEL_H +#ifndef _GTKEXT_PANEL_H +#define _GTKEXT_PANEL_H +#include + + +#include "../glibext/helpers.h" + + + +#define GTK_TYPE_TILED_PANEL (gtk_tiled_panel_get_type()) + +DECLARE_GTYPE(GtkTiledPanel, gtk_tiled_panel, GTK, TILED_PANEL); + + + + + + + + +#if 0 + #include #include @@ -108,5 +128,7 @@ bool g_panel_item_is_docked(const GPanelItem *); void g_panel_item_undock(GPanelItem *); +#endif + -#endif /* _GUI_PANELS_PANEL_H */ +#endif /* _GTKEXT_PANEL_H */ diff --git a/src/gui/panel-int.h b/src/gui/panel-int.h new file mode 100644 index 0000000..d54dc16 --- /dev/null +++ b/src/gui/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/gui/panel.c b/src/gui/panel.c new file mode 100644 index 0000000..5b21620 --- /dev/null +++ b/src/gui/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/gui/panel.h b/src/gui/panel.h new file mode 100644 index 0000000..de8d2bf --- /dev/null +++ b/src/gui/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 */ -- cgit v0.11.2-87-g4458