diff options
author | Cyrille Bagard <nocbos@gmail.com> | 2018-08-11 08:40:45 (GMT) |
---|---|---|
committer | Cyrille Bagard <nocbos@gmail.com> | 2018-08-11 08:40:45 (GMT) |
commit | 45c220eb6c7cb1076788307ace4b6f3df2e5e941 (patch) | |
tree | b018cf25fc23190ec430afec0a612d29cb142757 /src | |
parent | d19bfec27f4ed528c5ca569dcbb6621185db0c48 (diff) |
Created a new widget to handle tiled panels.
Diffstat (limited to 'src')
-rw-r--r-- | src/core/logs.c | 3 | ||||
-rw-r--r-- | src/gtkext/Makefile.am | 1 | ||||
-rw-r--r-- | src/gtkext/gtkdockstation.c | 49 | ||||
-rw-r--r-- | src/gtkext/tiledgrid.c | 1029 | ||||
-rw-r--r-- | src/gtkext/tiledgrid.h | 81 | ||||
-rw-r--r-- | src/gui/core/core.c | 44 | ||||
-rw-r--r-- | src/gui/core/global.c | 41 | ||||
-rw-r--r-- | src/gui/core/global.h | 7 | ||||
-rw-r--r-- | src/gui/core/panels.c | 27 | ||||
-rw-r--r-- | src/gui/core/panels.h | 5 | ||||
-rw-r--r-- | src/gui/editor.c | 825 | ||||
-rw-r--r-- | src/gui/menus/view.c | 20 | ||||
-rw-r--r-- | src/gui/menus/view.h | 3 | ||||
-rw-r--r-- | src/gui/panels/bintree.c | 2 | ||||
-rw-r--r-- | src/gui/panels/bookmarks.c | 2 | ||||
-rw-r--r-- | src/gui/panels/errors.c | 2 | ||||
-rw-r--r-- | src/gui/panels/glance.c | 2 | ||||
-rw-r--r-- | src/gui/panels/history.c | 2 | ||||
-rw-r--r-- | src/gui/panels/log.c | 2 | ||||
-rw-r--r-- | src/gui/panels/regedit.c | 2 | ||||
-rw-r--r-- | src/gui/panels/strings.c | 2 | ||||
-rw-r--r-- | src/gui/panels/symbols.c | 2 | ||||
-rw-r--r-- | src/gui/panels/welcome.c | 4 | ||||
-rw-r--r-- | src/main.c | 6 |
24 files changed, 1277 insertions, 886 deletions
diff --git a/src/core/logs.c b/src/core/logs.c index ae69758..417039b 100644 --- a/src/core/logs.c +++ b/src/core/logs.c @@ -106,7 +106,10 @@ void log_simple_message(LogMessageType type, const char *msg) item = get_panel_item_by_name(PANEL_LOG_ID); if (item != NULL) + { g_log_panel_add_message(G_LOG_PANEL(item), type, msg); + g_object_unref(G_OBJECT(item)); + } else print_message_without_gui(type, msg); diff --git a/src/gtkext/Makefile.am b/src/gtkext/Makefile.am index 42905fb..00ce40b 100644 --- a/src/gtkext/Makefile.am +++ b/src/gtkext/Makefile.am @@ -16,6 +16,7 @@ libgtkext_la_SOURCES = \ gtkstatusstack.h gtkstatusstack.c \ rendering.h rendering.c \ support.h support.c \ + tiledgrid.h tiledgrid.c \ tmgt.h tmgt.c libgtkext_la_LIBADD = \ diff --git a/src/gtkext/gtkdockstation.c b/src/gtkext/gtkdockstation.c index 634b007..688fe4b 100644 --- a/src/gtkext/gtkdockstation.c +++ b/src/gtkext/gtkdockstation.c @@ -271,28 +271,15 @@ void gtk_dock_station_add_dockable(GtkDockStation *station, GtkDockable *dockabl GtkWidget *label; /* Etiquette d'onglet */ GtkNotebook *notebook; /* Autre version du composant */ - /* Récupération des éléments utiles */ - widget = gtk_dockable_build_widget(dockable); - if (strcmp(gtk_dockable_get_name(dockable), "History") == 0) - { - GtkRequisition req; - gtk_widget_get_preferred_size(widget, &req, NULL); - fprintf(stderr, "Histo req :: %d x %d\n", req.width, req.height); - } - /* - if (!GTK_IS_SCROLLED_WINDOW(widget) - && ( - strcmp(gtk_dockable_get_name(dockable), "History2") != 0 - ) - ) - widget = gtk_button_new_with_label("123"); - */ + /* Récupération des éléments utiles */ + + widget = gtk_dockable_build_widget(dockable); //widget = gtk_button_new_with_label("123"); gtk_widget_show(widget); @@ -318,7 +305,8 @@ void gtk_dock_station_add_dockable(GtkDockStation *station, GtkDockable *dockabl g_signal_handlers_disconnect_by_func(notebook, G_CALLBACK(gtk_dock_station_switch_panel), station); - gtk_notebook_insert_page(notebook, widget, label, -1); + gtk_notebook_append_page(notebook, widget, label); + gtk_widget_set_tooltip_text(label, desc); if (gtk_notebook_get_n_pages(notebook) > 1) @@ -330,33 +318,6 @@ void gtk_dock_station_add_dockable(GtkDockStation *station, GtkDockable *dockabl if (gtk_notebook_get_n_pages(notebook) > 1) gtk_notebook_set_current_page(notebook, -1); - - // Renéociation des tailles - //gtk_widget_queue_resize(GTK_WIDGET(notebook)); - - - if (false) - { - GtkRequisition req; - - gtk_widget_get_preferred_size(GTK_WIDGET(notebook), &req, NULL); - fprintf(stderr, "=== SUPPORT req :: %d x %d\n", req.width, req.height); - - - gtk_widget_set_size_request(GTK_WIDGET(notebook), req.width, req.height); - - - - } - - - - - - - - - //g_signal_emit_by_name(station, "dock-widget", widget); } diff --git a/src/gtkext/tiledgrid.c b/src/gtkext/tiledgrid.c new file mode 100644 index 0000000..31358f7 --- /dev/null +++ b/src/gtkext/tiledgrid.c @@ -0,0 +1,1029 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * tiledgrid.c - compsoant d'affichage avec des chemins vers les composants contenus + * + * Copyright (C) 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 <http://www.gnu.org/licenses/>. + */ + + +#include "tiledgrid.h" + + +#include <assert.h> +#include <ctype.h> +#include <malloc.h> +#include <string.h> + + +#include "gtkdockstation.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; \ + __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 *); + + + +/* --------------------------- 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; + + } + + /* 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 = 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 : stack = 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) +{ + const char *path; /* Chemin d'accès */ + grid_tile_t *tile; /* Tuile d'accueil */ + + path = gtk_panel_item_get_path(panel); + + if (!is_valid_tile_path(path)) + { + log_variadic_message(LMT_ERROR, _("Invalid path '%s' for panel '%s'"), + path, gtk_dockable_get_name(GTK_DOCKABLE(panel))); + } + + 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_status(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); + + } + + } + + } + +} + + +/****************************************************************************** +* * +* 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_status(panel, false); + + if (gtk_notebook_get_n_pages(GTK_NOTEBOOK(station)) == 0) + { + //delete_panel_node(node); + + /* 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); + + } + +} + + +/****************************************************************************** +* * +* 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 new file mode 100644 index 0000000..25d3b26 --- /dev/null +++ b/src/gtkext/tiledgrid.h @@ -0,0 +1,81 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * tiledgrid.h - prototypes pour un compsoant d'affichage avec des chemins vers les composants contenus + * + * Copyright (C) 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 <http://www.gnu.org/licenses/>. + */ + + +#ifndef _GTKEXT_TILEDGRID_H +#define _GTKEXT_TILEDGRID_H + + +#include <gtk/gtk.h> + + +#include "../glibext/configuration.h" +#include "../gui/panels/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 *); + +/* 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/core/core.c b/src/gui/core/core.c index 598a8eb..2cb75b1 100644 --- a/src/gui/core/core.c +++ b/src/gui/core/core.c @@ -24,12 +24,15 @@ #include "core.h" +#include "global.h" #include "panels.h" - - #include "theme.h" +#include "../menus/menubar.h" +#include "../menus/view.h" +#include "../panels/welcome.h" #include "../../core/params.h" #include "../../glibext/linesegment.h" +#include "../../gtkext/tiledgrid.h" @@ -48,6 +51,9 @@ bool load_all_gui_components(void) { bool result; /* Bilan à retourner */ + GObject *ref; /* Espace de référencements */ + GMenuBar *bar; /* Gestion des menus */ + GtkMenuItem *submenuitem; /* Sous-élément de menu */ load_main_panels(); @@ -55,6 +61,17 @@ bool load_all_gui_components(void) result = load_segment_rendering_parameters(); + /** + * Charge une liste initiale pour activer les raccourcis clavier. + */ + + ref = get_global_ref(); + + bar = G_MENU_BAR(g_object_get_data(ref, "menubar")); + submenuitem = GTK_MENU_ITEM(g_object_get_data(ref, "mnu_view_side_panels")); + + mcb_view_update_side_panels_list(submenuitem, bar); + return result; } @@ -75,8 +92,29 @@ bool load_all_gui_components(void) bool complete_loading_of_all_gui_components(GGenConfig *config) { bool result; /* Bilan à faire remonter */ + GtkTiledGrid *grid; /* Composant d'affichage */ + GPanelItem *welcome; /* Panneau d'accueil */ + + grid = get_tiled_grid(); + + welcome = get_panel_item_by_name(PANEL_WELCOME_ID); + gtk_tiled_grid_set_default_main_panel(grid, welcome); + g_object_unref(G_OBJECT(welcome)); + + /** + * Le fait d'avoir défini le panneau d'accueil par défaut va l'afficher, + * comme il n'y a encore aucun autre panneau. Ce qui va mémoriser son + * paramètre d'affichage par défaut au démarrage à vrai. + * + * Or gtk_panel_item_apply_configuration() s'occupe précisément de + * restaurer les affichages de panneaux au démarrage. + * + * Donc on doit sauter ce panneau d'accueil lors de l'appel suivant. + */ + + result = _browse_all_item_panels(true, (handle_panel_item_fc)gtk_panel_item_apply_configuration, config); - result = browse_all_item_panels((handle_panel_item_fc)gtk_panel_item_apply_configuration, config); + gtk_tiled_grid_restore_positions(grid, config); return result; diff --git a/src/gui/core/global.c b/src/gui/core/global.c index dadece0..bfc2426 100644 --- a/src/gui/core/global.c +++ b/src/gui/core/global.c @@ -31,6 +31,9 @@ static GtkWindow *_editor = NULL; /* Gestion des raccourcis clavier */ static GtkAccelGroup *_accgroup = NULL; +/* Composant d'affichage en tuile */ +static GtkTiledGrid *_grid = NULL; + /* Barre de statut principale */ static GtkStatusStack *_status = NULL; @@ -143,6 +146,44 @@ GtkAccelGroup *get_accel_group(void) /****************************************************************************** * * +* Paramètres : grid = composant GTK à conserver. * +* * +* Description : Note l'adresse du composant d'affichage en tuiles. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void set_tiled_grid(GtkTiledGrid *grid) +{ + _grid = grid; + +} + + +/****************************************************************************** +* * +* Paramètres : - * +* * +* Description : Fournit l'adresse du composant d'affichage en tuiles. * +* * +* Retour : Composant GTK à manipuler. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GtkTiledGrid *get_tiled_grid(void) +{ + return _grid; + +} + + +/****************************************************************************** +* * * Paramètres : status = barre de statut à tenir informée. * * * * Description : Note l'adresse de la barre de statut principale. * diff --git a/src/gui/core/global.h b/src/gui/core/global.h index c80bcb5..86a1ea4 100644 --- a/src/gui/core/global.h +++ b/src/gui/core/global.h @@ -28,6 +28,7 @@ #include "../../analysis/loaded.h" #include "../../glibext/gloadedpanel.h" #include "../../gtkext/gtkstatusstack.h" +#include "../../gtkext/tiledgrid.h" @@ -46,6 +47,12 @@ void set_accel_group(GtkAccelGroup *); /* Fournit le groupe de raccourcis clavier globaux. */ GtkAccelGroup *get_accel_group(void); +/* Note l'adresse du composant d'affichage en tuiles. */ +void set_tiled_grid(GtkTiledGrid *); + +/* Fournit l'adresse du composant d'affichage en tuiles. */ +GtkTiledGrid *get_tiled_grid(void); + /* Note l'adresse de la barre de statut principale. */ void set_global_status(GtkStatusStack *); diff --git a/src/gui/core/panels.c b/src/gui/core/panels.c index 9d11e58..60ff6f2 100644 --- a/src/gui/core/panels.c +++ b/src/gui/core/panels.c @@ -25,6 +25,7 @@ #include "panels.h" +#include "global.h" #include "items.h" #include "../panels/bintree.h" #include "../panels/bookmarks.h" @@ -115,6 +116,7 @@ void load_main_panels(void) void register_panel_item(GPanelItem *item, GGenConfig *config) { GEditorItem *parent; /* Autre version de l'élément */ + GtkTiledGrid *grid; /* Composant d'affichage */ parent = G_EDITOR_ITEM(item); @@ -122,11 +124,10 @@ void register_panel_item(GPanelItem *item, GGenConfig *config) register_editor_item(parent); panels_list_add_tail(item, &_panels_list); - extern void on_panel_item_dock_request(GPanelItem *item, void *data); - extern void on_panel_item_undock_request(GPanelItem *item, void *data); + grid = get_tiled_grid(); - g_signal_connect(item, "dock-request", G_CALLBACK(on_panel_item_dock_request), NULL); - g_signal_connect(item, "undock-request", G_CALLBACK(on_panel_item_undock_request), NULL); + g_signal_connect_swapped(item, "dock-request", G_CALLBACK(gtk_tiled_grid_add), grid); + g_signal_connect_swapped(item, "undock-request", G_CALLBACK(gtk_tiled_grid_remove), grid); gtk_dockable_setup_dnd(GTK_DOCKABLE(item)); @@ -137,7 +138,8 @@ void register_panel_item(GPanelItem *item, GGenConfig *config) /****************************************************************************** * * -* Paramètres : handle = routine à appeler pour chaque panneau. * +* Paramètres : skip = saute le panneau d'accueil lors du parcours ? * +* handle = routine à appeler pour chaque panneau. * * data = données fournies pour accompagner cet appel. * * * * Description : Effectue le parcours de tous les panneaux chargés. * @@ -148,21 +150,31 @@ void register_panel_item(GPanelItem *item, GGenConfig *config) * * ******************************************************************************/ -bool browse_all_item_panels(handle_panel_item_fc handle, void *data) +bool _browse_all_item_panels(bool skip, handle_panel_item_fc handle, void *data) { bool result; /* Résultat à renvoyer */ + GPanelItem *welcome; /* Panneau d'accueil */ GPanelItem *iter; /* Boucle de parcours */ result = true; + if (skip) + welcome = get_panel_item_by_name(PANEL_WELCOME_ID); + panels_list_for_each(iter, _panels_list) { + if (skip && iter == welcome) + continue; + result = handle(iter, data); if (!result) break; } + if (skip) + g_object_unref(G_OBJECT(welcome)); + return result; } @@ -208,6 +220,9 @@ GPanelItem *get_panel_item_by_name(const char *name) browse_all_item_panels((handle_panel_item_fc)look_for_named_panel, &result); + if (result != NULL) + g_object_ref(G_OBJECT(result)); + return result; } diff --git a/src/gui/core/panels.h b/src/gui/core/panels.h index 0c55417..477c1e0 100644 --- a/src/gui/core/panels.h +++ b/src/gui/core/panels.h @@ -44,7 +44,10 @@ void register_panel_item(GPanelItem *, GGenConfig *); typedef bool (* handle_panel_item_fc) (GPanelItem *, void *); /* Effectue le parcours de tous les panneaux chargés. */ -bool browse_all_item_panels(handle_panel_item_fc, void *); +bool _browse_all_item_panels(bool, handle_panel_item_fc, void *); + +#define browse_all_item_panels(h, d) \ + _browse_all_item_panels(false, h, d) /* Recherche un panneau à partir de son nom court. */ GPanelItem *get_panel_item_by_name(const char *); diff --git a/src/gui/editor.c b/src/gui/editor.c index faf98a4..b4e13b0 100644 --- a/src/gui/editor.c +++ b/src/gui/editor.c @@ -42,8 +42,6 @@ #include "core/panels.h" #include "core/global.h" #include "core/items.h" -#include "panels/panel.h" -#include "panels/welcome.h" #include "tb/portions.h" #include "../common/extstr.h" #include "../core/global.h" @@ -53,6 +51,7 @@ #include "../gtkext/gtkdisplaypanel.h" #include "../gtkext/gtkdockable.h" #include "../gtkext/gtkdockstation.h" +#include "../gtkext/tiledgrid.h" #include "../gtkext/support.h" @@ -90,11 +89,6 @@ static gboolean on_key_event(GtkWidget *, GdkEventKey *, GObject *); - - - - - /* ------------------------ INTEGRATION DE LA BARRE D'OUTILS ------------------------ */ @@ -103,94 +97,11 @@ static GtkWidget *build_editor_toolbar(GObject *); - - -/* -------------------- MECANISMES DE (DE)PLACEMENT DES PANNEAUX -------------------- */ - - -/* Elément de la hiérarchie des panneaux */ -typedef struct _panel_node -{ - struct _panel_node *parent; /* Noeud parent */ - - char *path; /* Chemin du nom courant */ - - union - { - GtkWidget *widget; /* Accès généraliste */ - GtkWidget *station; /* Station d'accueil simple */ - GtkWidget *paned; /* Station d'accueil composée */ - - }; - - union - { - /* Version simple */ - /* ... */ - - /* Version composée */ - struct - { - struct _panel_node *first; /* Premier sous élément */ - struct _panel_node *second; /* Second sous élément */ - }; - - }; - -} panel_node; - - -#define IS_SIMPLE_NODE(nd) \ - ({ \ - bool __result; \ - __result = GTK_IS_DOCK_STATION(nd->station); \ - assert(__result || GTK_IS_PANED(nd->paned)); \ - __result; \ - }) - - -/* Support de fond pour les composants. */ -static GtkWidget *_support = NULL; -static panel_node *_nodes = NULL; - - -/* Crée un nouveau noeud pour un panneau particulier. */ -static panel_node *create_simple_panel_node_for_item(GPanelItem *, const char *); - -/* Prépare une nouvelle sous-division pour deux panneaux. */ -static void switch_panel_node_into_paned(panel_node *, bool, bool); - -/* Met en place un nouveau noeud dans une division. */ -static void attach_panel_node_to_paned(panel_node *, panel_node *, bool); - -/* Met à jour en cascade les chemins d'accès aux noeuds. */ -static void update_path_of_paned_nodes(panel_node *, const char *, const char *); - -/* Détermine la plus grande longueur commune entre éléments. */ -static size_t compute_path_common_length(const panel_node *, const char *); - -/* Place au bon endroit un panneau donné. */ -static panel_node *insert_item_as_panel_node(GPanelItem *, panel_node *, const char *, size_t); - -/* Tente de mettre la main sur une station d'accueil. */ -static panel_node *find_node_for_station(panel_node *, GtkWidget *); - -/* Tente de mettre la main sur un panneau de division graphique. */ -static panel_node *find_node_for_paned(panel_node *, GtkWidget *); - -/* Efface de l'organisation un noeud donné en place. */ -static void delete_panel_node(panel_node *); - - - /* ------------------- INTERACTIONS GRAPHIQUES LIEES AUX PANNEAUX ------------------- */ -/* Réagit à une demande de placement d'un panneau d'affichage. */ -void on_panel_item_dock_request(GPanelItem *, gpointer); - -/* Réagit à une demande de suppression d'un panneau d'affichage. */ -void on_panel_item_undock_request(GPanelItem *, gpointer); +/* Réagit à la mise en place d'une nouvelle station d'accueil. */ +static void on_dock_station_created(GtkTiledGrid *, GtkDockStation *, gpointer); /* Réagit au changement d'onglet d'un panneau quelconque. */ static void on_dock_item_switch(GtkDockStation *, GtkWidget *, gpointer); @@ -204,9 +115,6 @@ static void on_dock_menu_request(GtkDockStation *, GtkWidget *, gpointer); /* Réagit à une demande de fermeture du panneau courant. */ static void on_dock_close_request(GtkDockStation *, GtkWidget *, gpointer); -/* Réagit à une variation dans une séparation de panneaux. */ -static void notify_paned_handle_position_change(GObject *, GParamSpec *, gpointer); - /* ------------------------- INTEGRATION ET SUIVI DE PROJET ------------------------- */ @@ -288,6 +196,7 @@ GtkWidget *create_editor(void) GtkWidget *menuboard; /* Barre de menus principale */ GtkWidget *toolbar; /* Barre d'outils */ + GtkWidget *grid; /* Affichage en tuiles */ GtkWidget *vbox1; @@ -347,29 +256,26 @@ GtkWidget *create_editor(void) menuboard = g_editor_item_get_widget(editem); gtk_box_pack_start(GTK_BOX(vbox1), menuboard, FALSE, FALSE, 0); + g_object_set_data(ref, "menubar", editem); g_object_set_data(ref, "menuboard", menuboard); gtk_widget_hide(menuboard); - /* Barre d'outils */ toolbar = build_editor_toolbar(ref); gtk_box_pack_start(GTK_BOX(vbox1), toolbar, FALSE, FALSE, 0); - do - { - _support = gtk_event_box_new(); - gtk_widget_show(_support); - - //_support = init_panels2(G_CALLBACK(on_dock_item_switch), ref); - gtk_box_pack_start(GTK_BOX(vbox1), _support, TRUE, TRUE, 0); - + /* Coeur de la fenêtre principale */ - } while(0); + grid = gtk_tiled_grid_new(); + gtk_widget_show(grid); + set_tiled_grid(GTK_TILED_GRID(grid)); + g_signal_connect(grid, "station-created", G_CALLBACK(on_dock_station_created), NULL); + gtk_box_pack_start(GTK_BOX(vbox1), grid, TRUE, TRUE, 0); /* Barre de statut générale */ @@ -487,6 +393,8 @@ static void on_destroy_editor(GtkWidget *widget, GObject *ref) { /* Fermeture propre */ + gtk_tiled_grid_save_positions(get_tiled_grid(), get_main_configuration()); + /* ... */ on_focus_out(widget, NULL, ref); @@ -676,694 +584,39 @@ static GtkWidget *build_editor_toolbar(GObject *ref) gtk_widget_show(result); g_object_set_data(ref, "toolbar", result); - item = create_portions_tb_item(ref); register_editor_item(item); - return result; } - - - - - - - - - - - - - - - /* ---------------------------------------------------------------------------------- */ -/* MECANISMES DE (DE)PLACEMENT DES PANNEAUX */ +/* INTERACTIONS GRAPHIQUES LIEES AUX PANNEAUX */ /* ---------------------------------------------------------------------------------- */ /****************************************************************************** * * -* Paramètres : item = composant à présenter à l'affichage. * -* path = partie du chemin représentée ici. * +* Paramètres : grid = composant d'affichage en tuiles concerné. * +* station = nouvelle station créée. * +* unused = adresse non utilisée ici. * * * -* Description : Crée un nouveau noeud pour un panneau particulier. * +* Description : Réagit à la mise en place d'une nouvelle station d'accueil. * * * -* Retour : Structure d'accueil mise en place. * +* Retour : - * * * * Remarques : - * * * ******************************************************************************/ -static panel_node *create_simple_panel_node_for_item(GPanelItem *item, const char *path) +static void on_dock_station_created(GtkTiledGrid *grid, GtkDockStation *station, gpointer unused) { - panel_node *result; /* Structure à retourner */ - GtkWidget *station; /* Premier support concentré */ - - /* Partie graphique */ - - station = gtk_dock_station_new(); g_signal_connect(station, "switch-widget", G_CALLBACK(on_dock_item_switch), NULL); g_signal_connect(station, "menu-requested", G_CALLBACK(on_dock_menu_request), NULL); g_signal_connect(station, "close-requested", G_CALLBACK(on_dock_close_request), NULL); - gtk_widget_show(station); - - gtk_dock_station_add_dockable(GTK_DOCK_STATION(station), GTK_DOCKABLE(item)); - - /* Partie invisible */ - - result = (panel_node *)calloc(1, sizeof(panel_node)); - - result->station = station; - - result->path = strdup(path); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : node = noeud à diviser. * -* horiz = indique le type d'orientation désiré. * -* first = indication sur l'emplacement à utiliser. * -* * -* Description : Prépare une nouvelle sous-division pour deux panneaux. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void switch_panel_node_into_paned(panel_node *node, bool horiz, bool first) -{ - GtkWidget *widget; /* Composant à traiter */ - panel_node *parent; /* Lien de parenté à conserver */ - panel_node *moved; /* Noeud descendu d'un étage */ - - /* Décroche graphiquement le support */ - - widget = node->widget; - - g_object_ref(G_OBJECT(widget)); - gtk_container_remove(GTK_CONTAINER(gtk_widget_get_parent(widget)), widget); - - /* Descend l'élément actuel */ - - parent = node->parent; - - moved = (panel_node *)calloc(1, sizeof(panel_node)); - - memcpy(moved, node, sizeof(panel_node)); - - node->path = NULL; - - if (!IS_SIMPLE_NODE(moved)) - { - moved->first->parent = moved; - moved->second->parent = moved; - } - - /* Création du nouveau niveau intermédiaire */ - - if (horiz) - node->paned = gtk_paned_new(GTK_ORIENTATION_HORIZONTAL); - else - node->paned = gtk_paned_new(GTK_ORIENTATION_VERTICAL); - - g_signal_connect(node->paned, "notify::position", G_CALLBACK(notify_paned_handle_position_change), NULL); - - gtk_widget_show(node->paned); - - if (parent == NULL) - attach_panel_node_to_paned(parent, node, true); - else - attach_panel_node_to_paned(parent, node, parent->first == node); - - /* Replace le composant d'origine */ - - attach_panel_node_to_paned(node, moved, first); - -} - - -/****************************************************************************** -* * -* Paramètres : parent = noeud d'accueil pour le nouveau noeud. * -* node = nouveau noeud à intégrer dans l'ensemble. * -* first = indication sur l'emplacement à utiliser. * -* * -* Description : Met en place un nouveau noeud dans une division. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void attach_panel_node_to_paned(panel_node *parent, panel_node *node, bool first) -{ - node->parent = parent; - - /* On se trouve à la racine... */ - - if (parent == NULL) - { - gtk_container_add(GTK_CONTAINER(_support), node->widget); - - update_path_of_paned_nodes(node, "", "R"); - - } - - else - { - /* Raccordement hiérarchique */ - - if (first) - parent->first = node; - else - parent->second = node; - - /* Raccordement graphique */ - - assert(!IS_SIMPLE_NODE(parent)); - - if (first) - gtk_paned_pack1(GTK_PANED(parent->paned), node->widget, TRUE, FALSE); - else - gtk_paned_pack2(GTK_PANED(parent->paned), node->widget, TRUE, FALSE); - - /* Mise à jour des chemins */ - - update_path_of_paned_nodes(node, parent->path, first ? "1" : "2"); - - } - -} - - -/****************************************************************************** -* * -* Paramètres : node = noeud dont le chemin est à mettre à jour. * -* root = chemin menant au niveau précédent. * -* sub = sous-chemin vers lequel l'orientation penche. * -* * -* Description : Met à jour en cascade les chemins d'accès aux noeuds. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void update_path_of_paned_nodes(panel_node *node, const char *root, const char *sub) -{ - GtkOrientation orientation; /* Orientation du support */ - char *key; /* Clef d'accès à un paramètre */ - gint position; /* Nouvelle position de barre */ - - if (!IS_SIMPLE_NODE(node)) - { - /* Reconstruction locale */ - - if (node->path != NULL) - free(node->path); - - node->path = strdup(root); - node->path = stradd(node->path, sub); - - orientation = gtk_orientable_get_orientation(GTK_ORIENTABLE(node->paned)); - - if (orientation == GTK_ORIENTATION_HORIZONTAL) - node->path = stradd(node->path, "h"); - else - node->path = stradd(node->path, "v"); - - /* Rechargement de la position ? */ - - asprintf(&key, "gui.panels.positions.%s", node->path); - - if (g_generic_config_get_value(get_main_configuration(), key, &position)) - gtk_paned_set_position(GTK_PANED(node->paned), position); - - free(key); - - /* Propagation de la mise à jour */ - - if (node->first) - update_path_of_paned_nodes(node->first, node->path, "1"); - - if (node->second != NULL) - update_path_of_paned_nodes(node->second, node->path, "2"); - - } - -} - - -/****************************************************************************** -* * -* Paramètres : node = noeud d'où lancer les recherches. * -* target = identifiant de la position visée. * -* * -* Description : Détermine la plus grande longueur commune entre éléments. * -* * -* Retour : Bilan de l'évaluation. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static size_t compute_path_common_length(const panel_node *node, const char *target) -{ - size_t result; /* Taille à retourner */ - size_t len; /* Longueur de comparaison */ - size_t common1; /* Tron common avec le côté #1 */ - size_t common2; /* Tron common avec le côté #2 */ - - if (IS_SIMPLE_NODE(node)) - { - len = MIN(strlen(node->path), strlen(target)); - - /** - * Il n'y a pas forcément de base commune entre deux branches, - * donc on parcourt les chemins depuis leur base respective. - */ - for (result = 0; result < len; result++) - if (node->path[result] != target[result]) - break; - - } - - else - { - common1 = compute_path_common_length(node->first, target); - common2 = compute_path_common_length(node->second, target); - - result = MAX(common1, common2); - - } - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : item = composant à présenter à l'affichage. * -* node = point d'insertion courant. * -* path = partie du chemin représentée ici. * -* consumed = profondeur du chemin utilisé. * -* * -* Description : Place au bon endroit un panneau donné. * -* * -* Retour : Noeud final inséré dans la liste. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static panel_node *insert_item_as_panel_node(GPanelItem *item, panel_node *node, const char *path, size_t consumed) -{ - panel_node *result; /* Noeud ultime à renvoyer */ - char div; /* Division demandée */ - bool horiz; /* Traduction en composant */ - bool first; /* Point d'insertion */ - size_t common1; /* Tron common avec le côté #1 */ - size_t common2; /* Tron common avec le côté #2 */ - - - fprintf(stderr, "=== INSERTING '%s' (%zu)... -> '%s'\n", path, consumed, - IS_SIMPLE_NODE(node) ? node->path : "-"); - - - - if (IS_SIMPLE_NODE(node)) - { - /* Le parcours s'arrête ici ! */ - if (strcmp(node->path, path) == 0) - { - gtk_dock_station_add_dockable(GTK_DOCK_STATION(node->station), GTK_DOCKABLE(item)); - result = node; - } - - /* On ne peut aller plus loin, on doit diviser... */ - else - { - div = toupper(path[consumed]); - first = (div == 'W' || div == 'N'); - horiz = (div == 'W' || div == 'E'); - - fprintf(stderr, "---%%<--- first=%d horiz=%d\n", first, horiz); - - fprintf(stderr, "--- cutting %p\n", node->station); - - switch_panel_node_into_paned(node, horiz, !first); - - result = create_simple_panel_node_for_item(item, path); - - attach_panel_node_to_paned(node, result, first); - - - fprintf(stderr, "1# [%p] widget = %p --- split :: %p // %p\n", - node, node->station, node->first, node->second); - - } - - } - - /* On regarde des autres côtés... */ - - else - { - common1 = compute_path_common_length(node->first, path); - common2 = compute_path_common_length(node->second, path); - - - - fprintf(stderr, " - L1 :: %zu <-> '%s'\n", common1, node->first->path); - fprintf(stderr, " - L2 :: %zu <-> '%s'\n", common2, node->second->path); - - - /* Si une descente est possible... */ - if (common1 > 0 || common2 > 0) - { - if (common1 > common2) - result = insert_item_as_panel_node(item, node->first, path, common1); - - else - result = insert_item_as_panel_node(item, node->second, path, common2); - - } - - /* Sinon, on doit diviser qqch... */ - else - { - div = toupper(path[consumed]); - first = (div == 'W' || div == 'N'); - horiz = (div == 'W' || div == 'E'); - - fprintf(stderr, "---%%<--- first=%d horiz=%d\n", first, horiz); - - switch_panel_node_into_paned(node, horiz, !first); - - result = create_simple_panel_node_for_item(item, path); - - attach_panel_node_to_paned(node, result, first); - - - fprintf(stderr, "2# [%p] split :: %p-%p // %p-%p\n", node, - node->first, node->first->widget, - node->second, node->second->widget); - - } - - } - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : node = point de départ des recherches locales. * -* station = composant graphique à retrouver. * -* * -* Description : Tente de mettre la main sur une station d'accueil. * -* * -* Retour : Eventuel noeud trouvé ou NULL. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static panel_node *find_node_for_station(panel_node *node, GtkWidget *station) -{ - panel_node *result; /* Bilan à remonter */ - - if (IS_SIMPLE_NODE(node)) - result = (node->station == station ? node : NULL); - - else - { - result = find_node_for_station(node->first, station); - - if (result == NULL) - result = find_node_for_station(node->second, station); - - } - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : node = point de départ des recherches locales. * -* paned = composant graphique à retrouver. * -* * -* Description : Tente de mettre la main sur un panneau de division graphique.* -* * -* Retour : Eventuel noeud trouvé ou NULL. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static panel_node *find_node_for_paned(panel_node *node, GtkWidget *paned) -{ - panel_node *result; /* Bilan à remonter */ - - if (IS_SIMPLE_NODE(node)) - result = NULL; - - else - { - if (node->paned == paned) - result = node; - - else - { - result = find_node_for_paned(node->first, paned); - - if (result == NULL) - result = find_node_for_paned(node->second, paned); - - } - - } - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : node = noeud à supprimer de l'arbre des noeuds. * -* * -* Description : Efface de l'organisation un noeud donné en place. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void delete_panel_node(panel_node *node) -{ - panel_node *parent; /* Noeud parent à transformer */ - GtkWidget *widget; /* Composant à traiter */ - panel_node *grandparent; /* Noeud supérieur au parent */ - panel_node *remaining; /* Noeud restant */ - - assert(IS_SIMPLE_NODE(node)); - - parent = node->parent; - - /* Destruction du noeud */ - - widget = node->station; - gtk_container_remove(GTK_CONTAINER(gtk_widget_get_parent(widget)), widget); - - free(node->path); - - free(node); - - /* Suppression du niveau intermédiaire */ - - if (parent != NULL) - { - remaining = (node == parent->first ? parent->second : parent->first); - - /* Décroche graphiquement le support */ - - widget = remaining->widget; - - g_object_ref(G_OBJECT(widget)); - gtk_container_remove(GTK_CONTAINER(parent->paned), widget); - - /* Supprime le composant graphique intermédiaire */ - - gtk_container_remove(GTK_CONTAINER(gtk_widget_get_parent(parent->paned)), parent->paned); - - /* Réinsère la partie restante */ - - grandparent = parent->parent; - - memcpy(parent, remaining, sizeof(panel_node)); - - if (!IS_SIMPLE_NODE(parent)) - { - parent->first->parent = parent; - parent->second->parent = parent; - } - - free(remaining); - - if (grandparent == NULL) - attach_panel_node_to_paned(grandparent, parent, true); - else - attach_panel_node_to_paned(grandparent, parent, grandparent->first == parent); - - } - -} - - - -/* ---------------------------------------------------------------------------------- */ -/* INTERACTIONS GRAPHIQUES LIEES AUX PANNEAUX */ -/* ---------------------------------------------------------------------------------- */ - - -/****************************************************************************** -* * -* Paramètres : panel = composant à placer dans l'affichage. * -* unused = adresse non utilisée ici. * -* * -* Description : Réagit à une demande de placement d'un panneau d'affichage. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void on_panel_item_dock_request(GPanelItem *panel, gpointer unused) -{ - const char *path; /* Chemin d'accès */ - panel_node *node; /* Noeud à supprimer */ - const char *name; /* Nom du dernier panneau */ - GPanelItem *welcome; /* Panneau d'accueil */ - - path = gtk_panel_item_get_path(panel); - - /* Tout est à faire... */ - if (_nodes == NULL) - { - _nodes = create_simple_panel_node_for_item(panel, path); - gtk_container_add(GTK_CONTAINER(_support), _nodes->widget); - } - else - { - node = insert_item_as_panel_node(panel, _nodes, path, 0); - - if (strncmp(node->path, "N", 1) == 0) - { - name = g_editor_item_get_name(G_EDITOR_ITEM(panel)); - - if (strcmp(name, PANEL_WELCOME_ID) != 0) - { - welcome = get_panel_item_by_name(PANEL_WELCOME_ID); - - if (!g_welcome_panel_get_user_origin(G_WELCOME_PANEL(welcome))) - { - /* Equivalent d'un appel "g_panel_item_undock(welcome)", avec effet immédiat */ - /////on_panel_item_undock_request(welcome, NULL); - } - - } - - } - - } - - g_panel_item_set_dock_status(panel, true); - -} - - -/****************************************************************************** -* * -* Paramètres : panel = composant à retirer de l'affichage. * -* unused = adresse non utilisée ici. * -* * -* Description : Réagit à une demande de suppression d'un panneau d'affichage.* -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void on_panel_item_undock_request(GPanelItem *panel, gpointer unused) -{ - GtkWidget *station; /* Support courant */ - GtkNotebook *notebook; /* Version parente de station */ - panel_node *node; /* Noeud à supprimer */ - bool allowed; /* Fermture permise ? */ - const char *name; /* Nom du dernier panneau */ - GPanelItem *welcome; /* Panneau d'accueil */ - - gtk_dockable_decompose(GTK_DOCKABLE(panel), &station); - - notebook = GTK_NOTEBOOK(station); - - node = find_node_for_station(_nodes, station); - assert(node != NULL); - - allowed = true; - - if (strcmp(node->path, "N") == 0 && gtk_notebook_get_n_pages(notebook) == 1) - { - name = g_editor_item_get_name(G_EDITOR_ITEM(panel)); - - if (strcmp(name, PANEL_WELCOME_ID) == 0) - allowed = false; - - else - { - welcome = get_panel_item_by_name(PANEL_WELCOME_ID); - g_welcome_panel_set_user_origin(G_WELCOME_PANEL(welcome), false); - - /* Equivalent d'un appel "g_panel_item_dock(welcome)", avec effet immédiat */ - on_panel_item_dock_request(welcome, NULL); - - } - - } - - if (allowed) - { - gtk_dock_station_remove_dockable(GTK_DOCK_STATION(station), GTK_DOCKABLE(panel)); - - if (gtk_notebook_get_n_pages(notebook) == 0) - delete_panel_node(node); - - g_panel_item_set_dock_status(panel, false); - - } } @@ -1558,42 +811,6 @@ static void on_dock_close_request(GtkDockStation *station, GtkWidget *button, gp } -/****************************************************************************** -* * -* Paramètres : obj = objet à l'origine de la procédure. * -* pspec = spécification de l'attribut qui a varié. * -* unused = adresse non utilisée ici. * -* * -* Description : Réagit à une variation dans une séparation de panneaux. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void notify_paned_handle_position_change(GObject *obj, GParamSpec *pspec, gpointer unused) -{ - GtkPaned *paned; /* Panneau concerné */ - panel_node *node; /* Noeud hiérarchique associé */ - gint position; /* Nouvelle position de barre */ - char *key; /* Clef d'accès à un paramètre */ - - paned = GTK_PANED(obj); - - node = find_node_for_paned(_nodes, GTK_WIDGET(paned)); - - position = gtk_paned_get_position(paned); - - asprintf(&key, "gui.panels.positions.%s", node->path); - - g_generic_config_create_or_udpdate_param(get_main_configuration(), key, CPT_INTEGER, position); - - free(key); - -} - - /* ---------------------------------------------------------------------------------- */ /* INTEGRATION ET SUIVI DE PROJET */ @@ -1671,7 +888,7 @@ void on_editor_loaded_content_added(GStudyProject *project, GLoadedContent *cont name = g_loaded_content_describe(content, false); lname = g_loaded_content_describe(content, true); - panel = g_panel_item_new(PIP_BINARY_VIEW, name, lname, selected, true, "N"); + panel = g_panel_item_new(PIP_BINARY_VIEW, name, lname, selected, true, "M"); register_panel_item(panel, get_main_configuration()); g_signal_connect(selected, "size-allocate", G_CALLBACK(scroll_for_the_first_time), content); diff --git a/src/gui/menus/view.c b/src/gui/menus/view.c index 4dca039..bf8976c 100644 --- a/src/gui/menus/view.c +++ b/src/gui/menus/view.c @@ -46,9 +46,6 @@ /* Met à jour les accès du menu "Affichage -> Basculer...". */ static void update_switch_access_in_menu_view(void); -/* Réagit avec le menu "Affichage -> Panneaux latéraux". */ -static void mcb_view_update_side_panels_list(GtkMenuItem *, GMenuBar *); - /* Réagit avec le menu "Affichage -> Panneaux latéraux -> ...". */ static void mcb_view_change_panel_docking(GtkCheckMenuItem *, GPanelItem *); @@ -98,17 +95,12 @@ GtkWidget *build_menu_view(GObject *ref, GMenuBar *bar) /* Affichage -> Panneaux latéraux */ - submenuitem = qck_create_menu_item(NULL, NULL, _("Side panels"), NULL, NULL); + submenuitem = qck_create_menu_item(ref, "mnu_view_side_panels", _("Side panels"), NULL, NULL); g_signal_connect(submenuitem, "select", G_CALLBACK(mcb_view_update_side_panels_list), bar); gtk_container_add(GTK_CONTAINER(menubar), submenuitem); qck_create_menu(GTK_MENU_ITEM(submenuitem)); - /** - * Charge une liste initiale pour activer les raccourcis clavier. - */ - mcb_view_update_side_panels_list(GTK_MENU_ITEM(submenuitem), bar); - /* Séparation */ submenuitem = qck_create_menu_separator(); @@ -117,12 +109,12 @@ GtkWidget *build_menu_view(GObject *ref, GMenuBar *bar) /* Types de panneau de code */ - submenuitem = qck_create_menu_item(ref, "mcb_view_switch_to_next_support", _("Switch to next"), + submenuitem = qck_create_menu_item(ref, "mnu_view_switch_to_next_support", _("Switch to next"), G_CALLBACK(mcb_view_switch_to_next_support), NULL); add_accelerator_to_widget(submenuitem, "Tab"); gtk_container_add(GTK_CONTAINER(menubar), submenuitem); - submenuitem = qck_create_menu_item(ref, "mcb_view_switch_to_prev_support", _("Switch to previous"), + submenuitem = qck_create_menu_item(ref, "mnu_view_switch_to_prev_support", _("Switch to previous"), G_CALLBACK(mcb_view_switch_to_prev_support), NULL); add_accelerator_to_widget(submenuitem, "<Shift>Tab"); gtk_container_add(GTK_CONTAINER(menubar), submenuitem); @@ -463,12 +455,12 @@ static void update_switch_access_in_menu_view(void) access = (panel != NULL && (index + 1) < count); - item = GTK_WIDGET(g_object_get_data(ref, "mcb_view_switch_to_next_support")); + item = GTK_WIDGET(g_object_get_data(ref, "mnu_view_switch_to_next_support")); gtk_widget_set_sensitive(item, access); access = (panel != NULL && index > 0); - item = GTK_WIDGET(g_object_get_data(ref, "mcb_view_switch_to_prev_support")); + item = GTK_WIDGET(g_object_get_data(ref, "mnu_view_switch_to_prev_support")); gtk_widget_set_sensitive(item, access); if (panel != NULL) @@ -493,7 +485,7 @@ static void update_switch_access_in_menu_view(void) * * ******************************************************************************/ -static void mcb_view_update_side_panels_list(GtkMenuItem *menuitem, GMenuBar *bar) +void mcb_view_update_side_panels_list(GtkMenuItem *menuitem, GMenuBar *bar) { GtkWidget *menubar; /* Support pour éléments */ diff --git a/src/gui/menus/view.h b/src/gui/menus/view.h index a6491bd..2271d4c 100644 --- a/src/gui/menus/view.h +++ b/src/gui/menus/view.h @@ -46,6 +46,9 @@ void rebuild_menu_view_for_view(GtkWidget *, GLoadedPanel *); /* Met à jour les accès du menu "Affichage" selon le contenu. */ void update_access_for_view_in_menu_view(GObject *, GLoadedPanel *); +/* Réagit avec le menu "Affichage -> Panneaux latéraux". */ +void mcb_view_update_side_panels_list(GtkMenuItem *, GMenuBar *); + #endif /* _GUI_MENUS_VIEW_H */ diff --git a/src/gui/panels/bintree.c b/src/gui/panels/bintree.c index e425e92..d45fa0b 100644 --- a/src/gui/panels/bintree.c +++ b/src/gui/panels/bintree.c @@ -273,7 +273,7 @@ static void g_bintree_panel_init(GBintreePanel *panel) pitem->personality = PIP_SINGLETON; pitem->lname = _("Binary tree"); pitem->dock_at_startup = true; - pitem->path = strdup("eN"); + pitem->path = strdup("MEN"); /* Compléments propres */ diff --git a/src/gui/panels/bookmarks.c b/src/gui/panels/bookmarks.c index 3c1e719..b6a5deb 100644 --- a/src/gui/panels/bookmarks.c +++ b/src/gui/panels/bookmarks.c @@ -267,7 +267,7 @@ static void g_bookmarks_panel_init(GBookmarksPanel *panel) pitem->personality = PIP_SINGLETON; pitem->lname = _("Bookmarks"); pitem->dock_at_startup = false; - pitem->path = strdup("SE"); + pitem->path = strdup("Ms"); /* Représentation graphique */ diff --git a/src/gui/panels/errors.c b/src/gui/panels/errors.c index fa86a84..b405d04 100644 --- a/src/gui/panels/errors.c +++ b/src/gui/panels/errors.c @@ -281,7 +281,7 @@ static void g_error_panel_init(GErrorPanel *panel) pitem->personality = PIP_SINGLETON; pitem->lname = _("Disassembling errors"); pitem->dock_at_startup = true; - pitem->path = strdup("S"); + pitem->path = strdup("Ms"); /* Compléments propres */ diff --git a/src/gui/panels/glance.c b/src/gui/panels/glance.c index b7ce9da..638adc7 100644 --- a/src/gui/panels/glance.c +++ b/src/gui/panels/glance.c @@ -188,7 +188,7 @@ static void g_glance_panel_init(GGlancePanel *panel) pitem->personality = PIP_SINGLETON; pitem->lname = _("Glance"); pitem->dock_at_startup = true; - pitem->path = strdup("es"); + pitem->path = strdup("MEs"); /* Support de dessin */ diff --git a/src/gui/panels/history.c b/src/gui/panels/history.c index 50e72da..179c46f 100644 --- a/src/gui/panels/history.c +++ b/src/gui/panels/history.c @@ -178,7 +178,7 @@ static void g_history_panel_init(GHistoryPanel *panel) pitem->personality = PIP_SINGLETON; pitem->lname = _("Change history"); pitem->dock_at_startup = true; - pitem->path = strdup("eN"); + pitem->path = strdup("MEN"); /* Représentation graphique */ diff --git a/src/gui/panels/log.c b/src/gui/panels/log.c index e547a03..3a2e102 100644 --- a/src/gui/panels/log.c +++ b/src/gui/panels/log.c @@ -159,7 +159,7 @@ static void g_log_panel_init(GLogPanel *panel) pitem->personality = PIP_SINGLETON; pitem->lname = _("Misc information"); pitem->dock_at_startup = true; - pitem->path = strdup("S"); + pitem->path = strdup("Ms"); /* Représentation graphique */ diff --git a/src/gui/panels/regedit.c b/src/gui/panels/regedit.c index a0761aa..16887e7 100644 --- a/src/gui/panels/regedit.c +++ b/src/gui/panels/regedit.c @@ -227,7 +227,7 @@ static void g_regedit_panel_init(GRegeditPanel *panel) pitem->personality = PIP_SINGLETON; pitem->lname = _("Configuration parameters"); pitem->dock_at_startup = false; - pitem->path = strdup("N"); + pitem->path = strdup("M"); /* Représentation graphique */ diff --git a/src/gui/panels/strings.c b/src/gui/panels/strings.c index 0c147d5..f25cf52 100644 --- a/src/gui/panels/strings.c +++ b/src/gui/panels/strings.c @@ -303,7 +303,7 @@ static void g_strings_panel_init(GStringsPanel *panel) pitem->personality = PIP_SINGLETON; pitem->lname = _("Strings"); pitem->dock_at_startup = false; - pitem->path = strdup("S"); + pitem->path = strdup("Ms"); /* Représentation graphique */ diff --git a/src/gui/panels/symbols.c b/src/gui/panels/symbols.c index 8168313..a6cfb32 100644 --- a/src/gui/panels/symbols.c +++ b/src/gui/panels/symbols.c @@ -332,7 +332,7 @@ static void g_symbols_panel_init(GSymbolsPanel *panel) pitem->personality = PIP_SINGLETON; pitem->lname = _("Binary symbols"); pitem->dock_at_startup = true; - pitem->path = strdup("eN"); + pitem->path = strdup("MEN"); /* Représentation graphique */ diff --git a/src/gui/panels/welcome.c b/src/gui/panels/welcome.c index fc4b314..30652d8 100644 --- a/src/gui/panels/welcome.c +++ b/src/gui/panels/welcome.c @@ -198,8 +198,8 @@ static void g_welcome_panel_init(GWelcomePanel *panel) pitem->personality = PIP_SINGLETON; pitem->lname = _("Welcome"); - pitem->dock_at_startup = true; - pitem->path = strdup("N"); + pitem->dock_at_startup = false; + pitem->path = strdup("M"); panel->uorigin = !pitem->dock_at_startup; @@ -278,12 +278,12 @@ int main(int argc, char **argv) if (!batch_mode) { - status = load_all_gui_components(); - if (!status) goto failed_to_load_editor; - editor = create_editor(); if (editor == NULL) goto failed_to_load_editor; + status = load_all_gui_components(); + if (!status) goto failed_to_load_editor; + gtk_widget_show_now(editor); } |