diff options
author | Cyrille Bagard <nocbos@gmail.com> | 2012-01-11 02:20:30 (GMT) |
---|---|---|
committer | Cyrille Bagard <nocbos@gmail.com> | 2012-01-11 02:20:30 (GMT) |
commit | 486f0bf0a27ffed3e9fde2f183974ae029b45c54 (patch) | |
tree | 8840eaab0629f83e7501506b91101ce4f2d42a5d /src/gui/panels/panel.c | |
parent | 6ebdbfbca9e7bc34fe0f280e4a6a65c24c5003e9 (diff) |
Defined new panel definitions for the editor GUI.
git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@223 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
Diffstat (limited to 'src/gui/panels/panel.c')
-rw-r--r-- | src/gui/panels/panel.c | 658 |
1 files changed, 658 insertions, 0 deletions
diff --git a/src/gui/panels/panel.c b/src/gui/panels/panel.c new file mode 100644 index 0000000..8cc79ce --- /dev/null +++ b/src/gui/panels/panel.c @@ -0,0 +1,658 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * panel.c - prototypes pour la gestion des éléments réactifs spécifiques aux panneaux + * + * Copyright (C) 2009-2012 Cyrille Bagard + * + * This file is part of OpenIDA. + * + * OpenIDA 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. + * + * OpenIDA 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 <ctype.h> +#include <string.h> + + +#include "log.h" +#include "panel-int.h" +#include "symbols.h" +#include "../../gtkext/easygtk.h" +#include "../../gtkext/gtkdockstation.h" + + + +/* Support de fond pour les composants */ +static GtkWidget *_support; + +/* Liste des panneaux en place */ +static GPanelItem *_panels_list = NULL; + + +/* Initialise la classe des éléments réactifs de l'éditeur. */ +static void g_panel_item_class_init(GPanelItemClass *); + +/* Initialise une instance d'élément réactif pour l'éditeur. */ +static void g_panel_item_init(GPanelItem *); + +/* Renvoie un élément du chemin d'insertion du panneau. */ +static char g_panel_item_get_path_at(GPanelItem *, size_t); + +/* Détermine le support faisant office d'étendue donnée. */ +static GtkWidget *get_panel_given_part(GtkWidget *, size_t, char); + +/* Fournit le premier morceau de chemin rencontré. */ +static char get_first_path_found(GtkWidget *, size_t); + +/* Introduit une nouvelle division sur le support indiqué. */ +static void create_panel_division(GtkWidget *, GtkWidget *, const char *, GtkWidget *, const char *, char); + +/* Place un panneau dans l'ensemble affiché. */ +static void _g_panel_item_dock(GtkWidget *, GEditorItem *, const char *, size_t); + + + +/* Indique le type défini pour un élément destiné à un panneau. */ +G_DEFINE_TYPE(GPanelItem, g_panel_item, G_TYPE_EDITOR_ITEM); + + +/****************************************************************************** +* * +* Paramètres : klass = classe à initialiser. * +* * +* Description : Initialise la classe des éléments réactifs de l'éditeur. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_panel_item_class_init(GPanelItemClass *klass) +{ + +} + + +/****************************************************************************** +* * +* Paramètres : item = instance à initialiser. * +* * +* Description : Initialise une instance d'élément réactif pour l'éditeur. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_panel_item_init(GPanelItem *item) +{ + DL_LIST_ITEM_INIT(&item->link); + +} + + +/****************************************************************************** +* * +* Paramètres : item = composant à présenter à l'affichage. * +* ref = espace de référencement global. * +* name = nom associé à l'élément. * +* lname = description longue du panneau. * +* widget = composant à présenter à l'affichage. * +* path = chemin vers la place idéale pour le futur panneau. * +* * +* Description : Initialise dynamique les propriétés de l'instance. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void g_panel_item_init_ext(GPanelItem *item, const char *name, const char *lname, GtkWidget *widget, const char *path) +{ + GEditorItem *parent; /* Autre version de l'élément */ + + parent = G_EDITOR_ITEM(item); + + parent->name = name; + item->lname = lname; + + g_object_ref(widget); + parent->widget = widget; + g_object_set_data(G_OBJECT(widget), "pitem", item); + + item->path = path; + + panels_list_add_tail(item, &_panels_list); + +} + + +/****************************************************************************** +* * +* Paramètres : ref = espace de référencement global. * +* name = nom associé à l'élément. * +* lname = description longue du panneau. * +* widget = composant à présenter à l'affichage. * +* path = chemin vers la place idéale pour le futur panneau. * +* * +* Description : Crée un élément de panneau réactif. * +* * +* Retour : Adresse de la structure mise en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GEditorItem *g_panel_item_new(const char *name, const char *lname, GtkWidget *widget, const char *path) +{ + GPanelItem *result; /* Structure à retourner */ + + result = g_object_new(G_TYPE_PANEL_ITEM, NULL); + + g_panel_item_init_ext(result, name, lname, widget, path); + + return G_EDITOR_ITEM(result); + +} + + + +/****************************************************************************** +* * +* Paramètres : item = composant d'affichage à consulter. * +* pos = position de la tête de lecture dans le chemin. * +* * +* Description : Renvoie un élément du chemin d'insertion du panneau. * +* * +* Retour : Lettre caractéristique ou '\0'. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static char g_panel_item_get_path_at(GPanelItem *item, size_t pos) +{ + if (pos >= strlen(item->path)) + return '\0'; + else + return item->path[pos]; + +} + + +/****************************************************************************** +* * +* Paramètres : name = désignation courte servant de clef. * +* * +* Description : Recherche un panneau à partir de son nom court. * +* * +* Retour : Panneau trouvé ou NULL si aucun. * +* * +* Remarques : Le parcours peut se faire aussi depuis la classe parente, * +* mais il est plus rapide par ici. * +* * +******************************************************************************/ + +GPanelItem *g_panel_item_get(const char *name) +{ + GPanelItem *iter; /* Boucle de parcours */ + + panels_list_for_each(iter, _panels_list) + { + if (strcmp(G_EDITOR_ITEM(iter)->name, name) == 0) + return iter; + + } + + return NULL; + +} + + +/****************************************************************************** +* * +* 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) +{ + GPanelItemClass *class; /* Encadrement global */ + GtkWidget *station; /* Premier support concentré */ + GEditorItem *editem; /* Autre vision des choses */ + + class = G_PANEL_ITEM_GET_CLASS(item); + + /* Tout est à faire... */ + if (class->first == NULL) + { + /** + * Note : on crée ici un support qui ne sera jamais déplacé, + * laissant ainsi la variable 'class->first' pour les départs + * de parcours toujours valide sans effort. + */ + class->first = GTK_BIN(qck_create_padded_alignment(0, 0, 0, 0)); + + gtk_widget_show(GTK_WIDGET(class->first)); + gtk_container_add(GTK_CONTAINER(_support), GTK_WIDGET(class->first)); + + station = gtk_dock_station_new(); + + gtk_widget_show(station); + gtk_container_add(GTK_CONTAINER(class->first), station); + + editem = G_EDITOR_ITEM(item); + gtk_dock_panel_add_widget(GTK_DOCK_STATION(station), + editem->widget, editem->name); + + } + else _g_panel_item_dock(gtk_bin_get_child(class->first), G_EDITOR_ITEM(item), item->path, 0); + +} + + +/****************************************************************************** +* * +* Paramètres : base = support sujet à analyse. * +* pos = position de la tête de lecture dans le chemin. * +* target = indentifiant de positionnement recherché. * +* * +* Description : Détermine le support faisant office d'étendue donnée. * +* * +* Retour : Composant en place retrouvé ou NULL si aucune correspondance.* +* * +* Remarques : - * +* * +******************************************************************************/ + +static GtkWidget *get_panel_given_part(GtkWidget *base, size_t pos, char target) +{ + GtkWidget *result; /* Trouvaille à retourner */ + GtkWidget *widget; /* Autre composant présent */ + GPanelItem *item; /* Autre version de l'instance */ + char path; /* Partie de chemin en place */ + + if (GTK_IS_DOCK_STATION(base)) + { + widget = gtk_dock_panel_get_widget(GTK_DOCK_STATION(base), 0); + item = G_PANEL_ITEM(g_object_get_data(G_OBJECT(widget), "pitem")); + + path = g_panel_item_get_path_at(item, pos); + + result = (path == target ? base : NULL); + + } + else + { + widget = gtk_paned_get_child1(GTK_PANED(base)); + result = get_panel_given_part(widget, pos, target); + + if (result == NULL) + { + widget = gtk_paned_get_child2(GTK_PANED(base)); + result = get_panel_given_part(widget, pos, target); + } + + } + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : base = support sujet à analyse. * +* pos = position de la tête de lecture dans le chemin. * +* * +* Description : Fournit le premier morceau de chemin rencontré. * +* * +* Retour : Premier élément de chemin rencontré. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static char get_first_path_found(GtkWidget *base, size_t pos) +{ + char result; /* Trouvaille à retourner */ + GtkWidget *widget; /* Autre composant présent */ + GPanelItem *item; /* Autre version de l'instance */ + + if (GTK_IS_DOCK_STATION(base)) + { + widget = gtk_dock_panel_get_widget(GTK_DOCK_STATION(base), 0); + item = G_PANEL_ITEM(g_object_get_data(G_OBJECT(widget), "pitem")); + + result = g_panel_item_get_path_at(item, pos); + + } + else + { + /** + * A un certain niveau, si deux éléments sont groupés, + * c'est qu'ils ont une base commune ! On ne parcourt donc + * que le premier d'entre eux. + */ + widget = gtk_paned_get_child1(GTK_PANED(base)); + result = get_first_path_found(widget, pos); + + } + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : parent = support où placer la nouvelle division. * +* child1 = composant GTK à placer en position 1. * +* name1 = éventuelle désignation en cas d'isolement. * +* child2 = composant GTK à placer en position 2. * +* name2 = éventuelle désignation en cas d'isolement. * +* orientation = sens de la division. * +* * +* Description : Introduit une nouvelle division sur le support indiqué. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void create_panel_division(GtkWidget *parent, GtkWidget *child1, const char *name1, GtkWidget *child2, const char *name2, char orientation) +{ + unsigned int index; /* Indice de la réinsertion */ + bool resize; /* Redimensionnement à garder */ + GtkWidget *station; /* Nouvelle concentration */ + GtkWidget *paned; /* Nouveau support */ + + orientation = toupper(orientation); + + /* Détermination de la localisation d'origine */ + + if (GTK_IS_PANED(parent)) + { + if (gtk_paned_get_child1(GTK_PANED(parent)) == child1 + || gtk_paned_get_child1(GTK_PANED(parent)) == child2) + { + index = 1; + resize = GTK_PANED(parent)->child1_resize; + } + else + { + index = 2; + resize = GTK_PANED(parent)->child2_resize; + } + } + else + { + index = -1; + resize = false; /* Pour gcc (Debian 4.4.5-8) 4.4.5 */ + } + + gtk_widget_ref(name1 == NULL ? child1 : child2); + + gtk_container_remove(GTK_CONTAINER(parent), child2); + + /* Enrobages éventuels */ + + if (!GTK_IS_DOCK_STATION(child1)) + { + station = gtk_dock_station_new(); + gtk_widget_show(station); + gtk_dock_panel_add_widget(GTK_DOCK_STATION(station), child1, name1); + + child1 = station; + + } + + if (!GTK_IS_DOCK_STATION(child2)) + { + station = gtk_dock_station_new(); + gtk_widget_show(station); + gtk_dock_panel_add_widget(GTK_DOCK_STATION(station), child2, name2); + + child2 = station; + + } + + /* Insertion complète */ + + if (orientation == 'N' || orientation == 'S') + paned = gtk_vpaned_new(); + else + paned = gtk_hpaned_new(); + + gtk_widget_show(paned); + + switch (index) + { + case 1: + gtk_paned_pack1(GTK_PANED(parent), paned, resize, FALSE); + break; + case 2: + gtk_paned_pack2(GTK_PANED(parent), paned, resize, FALSE); + break; + default: + gtk_container_add(GTK_CONTAINER(parent), paned); + break; + } + + switch (orientation) + { + case 'N': + break; + case 'E': + gtk_paned_pack1(GTK_PANED(paned), child1, TRUE, FALSE); + gtk_paned_pack2(GTK_PANED(paned), child2, FALSE, FALSE); + gtk_paned_set_position(GTK_PANED(paned), 450); + break; + case 'S': + gtk_paned_pack1(GTK_PANED(paned), child1, TRUE, FALSE); + gtk_paned_pack2(GTK_PANED(paned), child2, FALSE, FALSE); + gtk_paned_set_position(GTK_PANED(paned), 350); + break; + case 'W': + break; + } + +} + + +/****************************************************************************** +* * +* Paramètres : base = départ courant de la déscente. * +* item = composant à présenter à l'affichage. * +* path = chemin à consulter pour le placement idéal. * +* pos = position de la tête de lecture dans le chemin. * +* * +* Description : Place un panneau dans l'ensemble affiché. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void _g_panel_item_dock(GtkWidget *base, GEditorItem *item, const char *path, size_t pos) +{ + GtkWidget *part; /* Support principal détecté */ + GtkWidget *widget; /* Autre composant présent */ + GPanelItem *other; /* Autre version de l'instance */ + char path_i; /* Partie de chemin à insérer */ + char path_o; /* Partie de chemin en place */ + GtkWidget *parent; /* Support supérieur */ + char sel_path; /* Chemin à appliquer */ + + + //printf(" ============== PATH :: '%c' =======================\n", path[pos]); + + part = get_panel_given_part(base, pos, path[pos]); + + + //printf("-- trouve :: %p ( station ?= %d) ( base ?= %d)\n", part, GTK_IS_DOCK_STATION(part), GTK_IS_DOCK_STATION(base)); + + + if (GTK_IS_DOCK_STATION(part)) + { + + + path_i = g_panel_item_get_path_at(G_PANEL_ITEM(item), pos); + + widget = gtk_dock_panel_get_widget(GTK_DOCK_STATION(part), 0); + other = G_PANEL_ITEM(g_object_get_data(G_OBJECT(widget), "pitem")); + + path_o = g_panel_item_get_path_at(other, pos); + + //printf(" -- path -- '%c' vs '%c'\n", path_i, path_o); + + + if (path_i == path_o) + gtk_dock_panel_add_widget(GTK_DOCK_STATION(part), item->widget, item->name); + + else + { + /* On fait primer le chemin d'importance */ + if (path_i == 'M' || (isupper(path_o) && !isupper(path_i))) + sel_path = path_o; + else + sel_path = path_i; + + parent = gtk_widget_get_parent(base); + create_panel_division(parent, item->widget, item->name, base, NULL, sel_path); + } + + } + + else if (GTK_IS_PANED(part)) + { + + + + printf("Paf Paned !\n"); + exit(0); + + + } + + /* Si on n'a rien trouvé, alors on redivise */ + else /*if (part == NULL)*/ + { + if (!GTK_IS_DOCK_STATION(base)) + { + path_i = get_first_path_found(gtk_paned_get_child1(GTK_PANED(base)), pos); + path_o = get_first_path_found(gtk_paned_get_child2(GTK_PANED(base)), pos); + + if (path_i == 'M' || (isupper(path_o) && islower(path_i))) + base = gtk_paned_get_child1(GTK_PANED(base)); + else + base = gtk_paned_get_child2(GTK_PANED(base)); + + } + + path_i = g_panel_item_get_path_at(G_PANEL_ITEM(item), pos); + + widget = gtk_dock_panel_get_widget(GTK_DOCK_STATION(base), 0); + other = G_PANEL_ITEM(g_object_get_data(G_OBJECT(widget), "pitem")); + + path_o = g_panel_item_get_path_at(other, pos); + + /* On fait primer le chemin d'importance */ + if (path_i == 'M' || (islower(path_i) && isupper(path_o))) + sel_path = path_o; + else + sel_path = path_i; + + //printf(" ++>> DIR :: '%c' vs '%c' => '%c'\n", path[pos], path_o, sel_path); + + parent = gtk_widget_get_parent(base); + create_panel_division(parent, item->widget, item->name, base, NULL, sel_path); + + } + + + +} + + + +/* ---------------------------------------------------------------------------------- */ +/* PLACEMENTS DES DIFFERENTS PANNEAUX */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +* * +* Paramètres : - * +* * +* Description : Prépare le terrain pour l'affichage central. * +* * +* Retour : Composant de support sur lequel tout va se placer. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GtkWidget *init_panels2(void) +{ + GtkWidget *result; /* Support à retourner */ + + result = qck_create_padded_alignment(0, 0, 0, 0); + gtk_widget_show(result); + + _support = result; + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : - * +* * +* Description : Charge les principaux panneaux de l'éditeur. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void load_main_panels(void) +{ + GPanelItem *item; /* Panneau de base à charger */ + + item = create_log_panel(); + g_panel_item_dock(item); + + item = create_symbols_panel(); + g_panel_item_dock(item); + +} |