diff options
author | Cyrille Bagard <nocbos@gmail.com> | 2012-08-19 22:40:33 (GMT) |
---|---|---|
committer | Cyrille Bagard <nocbos@gmail.com> | 2012-08-19 22:40:33 (GMT) |
commit | 09d07908465d462101d27ecb1b60df52d63bbe5d (patch) | |
tree | e9c8dc53425017efd68feee73ecf9587bd0ba196 | |
parent | b226ca8a19e746521f6f0c1e3b71deed7ea9ab2e (diff) |
Rewritten a cleaner way to dock panels.
git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@261 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
28 files changed, 636 insertions, 328 deletions
@@ -1,3 +1,52 @@ +12-08-20 Cyrille Bagard <nocbos@gmail.com> + + * pixmaps/drop_bottom_hover.png: + * pixmaps/drop_bottom.png: + * pixmaps/drop_center_hover.png: + * pixmaps/drop_center.png: + * pixmaps/drop_left_hover.png: + * pixmaps/drop_left.png: + * pixmaps/drop_right_hover.png: + * pixmaps/drop_right.png: + * pixmaps/drop_top_hover.png: + * pixmaps/drop_top.png: + * pixmaps/dropwin_back.png: + Delete unused pictures. + + * pixmaps/Makefile.am: + Handle the new 'welcome.png' picture. + + * pixmaps/welcome.png: + Create a background for the welcome panel. + + * src/editor.c: + Disable old code which was still displayed. + + * src/gui/menus/file.c: + * src/gui/panels/log.c: + * src/gui/panels/log.h: + Update code when loading panels. + + * src/gui/panels/Makefile.am: + Add the 'welcome.[ch]' files to libguipanels_la_SOURCES. + + * src/gui/panels/panel.c: + * src/gui/panels/panel.h: + * src/gui/panels/panel-int.h: + Rewrite a cleaner way to dock panels. + + * src/gui/panels/symbols.h: + Typo. + + * src/gui/panels/welcome.c: + * src/gui/panels/welcome.h: + New entries: provide a welcome panel for empty startup. + + * src/main.c: + * src/project.c: + * src/project.h: + Update code when loading panels. + 12-08-17 Cyrille Bagard <nocbos@gmail.com> * src/gtkext/gtkdockpanel.c: diff --git a/pixmaps/Makefile.am b/pixmaps/Makefile.am index bc88f48..2029a8a 100644 --- a/pixmaps/Makefile.am +++ b/pixmaps/Makefile.am @@ -29,6 +29,9 @@ LIST_ICONS = \ symbol_package.png \ symbol_routine_classic.png +MISC = \ + welcome.png + EXTRA_DIST = \ breakpoint_disabled.png \ breakpoint_normal.png \ @@ -37,8 +40,8 @@ EXTRA_DIST = \ $(REVISION_PIX) \ $(TOOLBAR_BUTTONS) \ $(LIST_ICONS) \ - dropwin_back.png + $(MISC) oidapixdir = $(datadir)/openida -oidapix_DATA = dropwin_back.png $(APP_ICONS) $(REVISION_PIX) $(TOOLBAR_BUTTONS) $(LIST_ICONS) +oidapix_DATA = $(APP_ICONS) $(REVISION_PIX) $(TOOLBAR_BUTTONS) $(LIST_ICONS) $(MISC) diff --git a/pixmaps/drop_bottom.png b/pixmaps/drop_bottom.png Binary files differdeleted file mode 100644 index e141d87..0000000 --- a/pixmaps/drop_bottom.png +++ /dev/null diff --git a/pixmaps/drop_bottom_hover.png b/pixmaps/drop_bottom_hover.png Binary files differdeleted file mode 100644 index 645b437..0000000 --- a/pixmaps/drop_bottom_hover.png +++ /dev/null diff --git a/pixmaps/drop_center.png b/pixmaps/drop_center.png Binary files differdeleted file mode 100644 index a47901b..0000000 --- a/pixmaps/drop_center.png +++ /dev/null diff --git a/pixmaps/drop_center_hover.png b/pixmaps/drop_center_hover.png Binary files differdeleted file mode 100644 index b589d50..0000000 --- a/pixmaps/drop_center_hover.png +++ /dev/null diff --git a/pixmaps/drop_left.png b/pixmaps/drop_left.png Binary files differdeleted file mode 100644 index b4668ee..0000000 --- a/pixmaps/drop_left.png +++ /dev/null diff --git a/pixmaps/drop_left_hover.png b/pixmaps/drop_left_hover.png Binary files differdeleted file mode 100644 index e240b49..0000000 --- a/pixmaps/drop_left_hover.png +++ /dev/null diff --git a/pixmaps/drop_right.png b/pixmaps/drop_right.png Binary files differdeleted file mode 100644 index f46792b..0000000 --- a/pixmaps/drop_right.png +++ /dev/null diff --git a/pixmaps/drop_right_hover.png b/pixmaps/drop_right_hover.png Binary files differdeleted file mode 100644 index 102eb6c..0000000 --- a/pixmaps/drop_right_hover.png +++ /dev/null diff --git a/pixmaps/drop_top.png b/pixmaps/drop_top.png Binary files differdeleted file mode 100644 index 4435134..0000000 --- a/pixmaps/drop_top.png +++ /dev/null diff --git a/pixmaps/drop_top_hover.png b/pixmaps/drop_top_hover.png Binary files differdeleted file mode 100644 index 281e793..0000000 --- a/pixmaps/drop_top_hover.png +++ /dev/null diff --git a/pixmaps/dropwin_back.png b/pixmaps/dropwin_back.png Binary files differdeleted file mode 100644 index bd962b9..0000000 --- a/pixmaps/dropwin_back.png +++ /dev/null diff --git a/pixmaps/welcome.png b/pixmaps/welcome.png Binary files differnew file mode 100644 index 0000000..5c312fb --- /dev/null +++ b/pixmaps/welcome.png diff --git a/src/editor.c b/src/editor.c index 3c861d1..81feb14 100644 --- a/src/editor.c +++ b/src/editor.c @@ -286,7 +286,7 @@ GtkWidget *create_editor(void) menuboard = gtk_menu_bar_new(); gtk_widget_show(menuboard); - gtk_box_pack_start(GTK_BOX(vbox1), menuboard, FALSE, FALSE, 0); + //gtk_box_pack_start(GTK_BOX(vbox1), menuboard, FALSE, FALSE, 0); /* Affichage */ @@ -397,7 +397,7 @@ GtkWidget *create_editor(void) -#if 1 +#if 0 vpaned1 = gtk_vpaned_new (); gtk_widget_show (vpaned1); //gtk_box_pack_start (GTK_BOX (vbox1), vpaned1, TRUE, TRUE, 0); diff --git a/src/gui/menus/file.c b/src/gui/menus/file.c index 8d218c1..3c204e0 100644 --- a/src/gui/menus/file.c +++ b/src/gui/menus/file.c @@ -34,10 +34,10 @@ /* Réagit au menu "Fichier -> Nouveau projet". */ -static void mcb_file_new_project(GtkMenuItem *, gpointer); +static void mcb_file_new_project(GtkMenuItem *, GObject *); /* Réagit au menu "Fichier -> Ouvrir un projet". */ -static void mcb_file_open_project(GtkMenuItem *, gpointer); +static void mcb_file_open_project(GtkMenuItem *, GObject *); /* Réagit au menu "Fichier -> Enregistrer le projet". */ static void mcb_file_save_project(GtkMenuItem *, gpointer); @@ -130,7 +130,7 @@ GtkWidget *build_menu_file(GObject *ref, GtkAccelGroup *accgroup) /****************************************************************************** * * * Paramètres : menuitem = élément de menu sélectionné. * -* data = adresse de l'espace de référencement global. * +* ref = adresse de l'espace de référencement global. * * * * Description : Réagit au menu "Fichier -> Nouveau projet". * * * @@ -140,11 +140,11 @@ GtkWidget *build_menu_file(GObject *ref, GtkAccelGroup *accgroup) * * ******************************************************************************/ -static void mcb_file_new_project(GtkMenuItem *menuitem, gpointer data) +static void mcb_file_new_project(GtkMenuItem *menuitem, GObject *ref) { GStudyProject *project; /* Nouveau projet courant */ - project = g_study_project_new(); + project = g_study_project_new(ref); set_current_project(project); @@ -156,7 +156,7 @@ static void mcb_file_new_project(GtkMenuItem *menuitem, gpointer data) /****************************************************************************** * * * Paramètres : menuitem = élément de menu sélectionné. * -* data = adresse de l'espace de référencement global. * +* ref = adresse de l'espace de référencement global. * * * * Description : Réagit au menu "Fichier -> Ouvrir un projet". * * * @@ -166,13 +166,13 @@ static void mcb_file_new_project(GtkMenuItem *menuitem, gpointer data) * * ******************************************************************************/ -static void mcb_file_open_project(GtkMenuItem *menuitem, gpointer data) +static void mcb_file_open_project(GtkMenuItem *menuitem, GObject *ref) { GtkWidget *dialog; /* Boîte à afficher */ GStudyProject *project; /* Projet chargé */ gchar *filename; /* Nom du fichier à intégrer */ - dialog = gtk_file_chooser_dialog_new(_("Open a project"), GTK_WINDOW(data), + dialog = gtk_file_chooser_dialog_new(_("Open a project"), GTK_WINDOW(ref), GTK_FILE_CHOOSER_ACTION_OPEN, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, @@ -188,7 +188,7 @@ static void mcb_file_open_project(GtkMenuItem *menuitem, gpointer data) { filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog)); - project = g_study_project_open(filename); + project = g_study_project_open(ref, filename); if (project != NULL) { diff --git a/src/gui/panels/Makefile.am b/src/gui/panels/Makefile.am index 0d43844..2678d54 100644 --- a/src/gui/panels/Makefile.am +++ b/src/gui/panels/Makefile.am @@ -4,7 +4,8 @@ noinst_LTLIBRARIES = libguipanels.la libguipanels_la_SOURCES = \ log.h log.c \ panel.h panel.c \ - symbols.h symbols.c + symbols.h symbols.c \ + welcome.h welcome.c libguipanels_la_LDFLAGS = diff --git a/src/gui/panels/log.c b/src/gui/panels/log.c index 6bda922..0baa3a4 100644 --- a/src/gui/panels/log.c +++ b/src/gui/panels/log.c @@ -50,7 +50,7 @@ static GtkWidget *build_log_panel(void); /****************************************************************************** * * -* Paramètres : - * +* Paramètres : ref = espace de référencement global. * * * * Description : Construit le panneau d'affichage des messages système. * * * @@ -60,14 +60,14 @@ static GtkWidget *build_log_panel(void); * * ******************************************************************************/ -GPanelItem *create_log_panel(void) +GPanelItem *create_log_panel(GObject *ref) { GEditorItem *result; /* Elément réactif à renvoyer */ GtkWidget *panel; /* Composant GTK visuel */ panel = build_log_panel(); - result = g_panel_item_new(PANEL_LOG_ID, _("Misc information"), panel, "S"); + result = g_panel_item_new(ref, PANEL_LOG_ID, _("Misc information"), panel, "S"); return G_PANEL_ITEM(result); diff --git a/src/gui/panels/log.h b/src/gui/panels/log.h index 264078c..4644d76 100644 --- a/src/gui/panels/log.h +++ b/src/gui/panels/log.h @@ -55,7 +55,7 @@ typedef enum _LogMessageType /* Construit le panneau d'affichage des messages système. */ -GPanelItem *create_log_panel(void); +GPanelItem *create_log_panel(GObject *); /* Affiche un message dans le journal des messages système. */ void log_simple_message(LogMessageType, const char *); diff --git a/src/gui/panels/panel-int.h b/src/gui/panels/panel-int.h index 133f1a3..e1c8932 100644 --- a/src/gui/panels/panel-int.h +++ b/src/gui/panels/panel-int.h @@ -51,6 +51,35 @@ struct _GPanelItem }; +/* Elément de la hiérarchie des panneaux */ +typedef struct _panel_node +{ + struct _panel_node *parent; /* Noeud parent */ + + char path; /* Chemin du nom courant */ + size_t depth; /* Profondeur utilisée */ + + bool simple; /* Noeud sans division */ + + union + { + GtkWidget *station; /* Station d'accueil simple */ + + struct + { + GtkWidget *paned; /* Station d'accueil composée */ + struct _panel_node *first; /* Premier sous élément */ + struct _panel_node *second; /* Second sous élément */ + }; + + }; + +} panel_node; + + +#define GET_PANEL_NODE_WIDGET(node) (node->simple ? node->station : node->paned) + + /* Elément réactif pour panneaux de l'éditeur (classe) */ struct _GPanelItemClass { diff --git a/src/gui/panels/panel.c b/src/gui/panels/panel.c index b13c074..f70a1ab 100644 --- a/src/gui/panels/panel.c +++ b/src/gui/panels/panel.c @@ -32,6 +32,7 @@ #include "log.h" #include "panel-int.h" #include "symbols.h" +#include "welcome.h" #include "../../gtkext/easygtk.h" #include "../../gtkext/gtkdockstation.h" @@ -39,6 +40,7 @@ /* Support de fond pour les composants. */ static GtkWidget *_support; +static panel_node *_nodes = NULL; /* Procédure à appeler lors des changements de panneaux. */ static GCallback _handler; @@ -54,20 +56,28 @@ 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); +/* ---------------------- MECANISMES DE PLACEMENT DES PANNEAUX ---------------------- */ -/* 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); +/* Crée un nouveau noeud pour un panneau particulier. */ +static panel_node *create_simple_panel_node_for_item(GPanelItem *, const char *, size_t); + +/* 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); + +/* Indique si un noeud correspond à la branche recherchée. */ +static bool is_panel_node_matching(const panel_node *, char); + +/* Place au bon endroit un panneau donné. */ +static void insert_item_as_panel_node(GPanelItem *, panel_node *, const char *, size_t); + +/* Met à jour l'affichage suite à un changement hiérarchique. */ +static void rebuild_panels_interface(const panel_node *); @@ -168,43 +178,19 @@ void g_panel_item_init_ext(GPanelItem *item, GObject *ref, const char *name, con * * ******************************************************************************/ -GEditorItem *g_panel_item_new(const char *name, const char *lname, GtkWidget *widget, const char *path) +GEditorItem *g_panel_item_new(GObject *ref, 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, NULL/* FIXME */, name, lname, widget, path); + g_panel_item_init_ext(result, ref, 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. * @@ -248,37 +234,13 @@ GPanelItem *g_panel_item_get(const char *name) 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) + if (_nodes == 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(); - g_signal_connect(station, "switch-widget", _handler, _data); - - 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); - + _nodes = create_simple_panel_node_for_item(item, item->path, 0); + gtk_container_add(GTK_CONTAINER(_support), _nodes->station); } - else _g_panel_item_dock(gtk_bin_get_child(class->first), G_EDITOR_ITEM(item), item->path, 0); + else insert_item_as_panel_node(item, _nodes, item->path, 0); } @@ -307,93 +269,110 @@ void g_panel_item_undock(GPanelItem *item) } + +/* ---------------------------------------------------------------------------------- */ +/* PLACEMENTS DES DIFFERENTS PANNEAUX */ +/* ---------------------------------------------------------------------------------- */ + + /****************************************************************************** * * -* Paramètres : base = support sujet à analyse. * -* pos = position de la tête de lecture dans le chemin. * -* target = indentifiant de positionnement recherché. * +* Paramètres : handler = procédure à réveiller en cas de changements. * +* data = donnée à faire suivre. * * * -* Description : Détermine le support faisant office d'étendue donnée. * +* Description : Prépare le terrain pour l'affichage central. * * * -* Retour : Composant en place retrouvé ou NULL si aucune correspondance.* +* Retour : Composant de support sur lequel tout va se placer. * * * * Remarques : - * * * ******************************************************************************/ -static GtkWidget *get_panel_given_part(GtkWidget *base, size_t pos, char target) +GtkWidget *init_panels2(GCallback handler, gpointer data) { - GtkWidget *result; /* Trouvaille à retourner */ - GtkWidget *widget; /* Autre composant présent */ - GPanelItem *item; /* Autre version de l'instance */ - char path; /* Partie de chemin en place */ + GtkWidget *result; /* Support à retourner */ - 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 = qck_create_padded_alignment(0, 0, 0, 0); + gtk_widget_show(result); - path = g_panel_item_get_path_at(item, pos); + _support = result; + _handler = handler; + _data = data; - result = (path == target ? base : NULL); + return result; - } - 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); - } - } +/****************************************************************************** +* * +* Paramètres : ref = espace de référencement global. * +* * +* Description : Charge les principaux panneaux de l'éditeur. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ - return result; +void load_main_panels(GObject *ref) +{ + GPanelItem *item; /* Panneau de base à charger */ + + item = create_welcome_panel(ref); + g_panel_item_dock(item); + + item = create_log_panel(ref); + g_panel_item_dock(item); + + item = create_symbols_panel(ref); + g_panel_item_dock(item); } +/* ---------------------------------------------------------------------------------- */ +/* MECANISMES DE PLACEMENT DES PANNEAUX */ +/* ---------------------------------------------------------------------------------- */ + + /****************************************************************************** * * -* Paramètres : base = support sujet à analyse. * -* pos = position de la tête de lecture dans le chemin. * +* Paramètres : item = composant à présenter à l'affichage. * +* path = partie du chemin représentée ici. * +* depth = profondeur du chemin utilisé. * * * -* Description : Fournit le premier morceau de chemin rencontré. * +* Description : Crée un nouveau noeud pour un panneau particulier. * * * -* Retour : Premier élément de chemin rencontré. * +* Retour : Structure d'accueil mise en place. * * * * Remarques : - * * * ******************************************************************************/ -static char get_first_path_found(GtkWidget *base, size_t pos) +static panel_node *create_simple_panel_node_for_item(GPanelItem *item, const char *path, size_t depth) { - char result; /* Trouvaille à retourner */ - GtkWidget *widget; /* Autre composant présent */ - GPanelItem *item; /* Autre version de l'instance */ + panel_node *result; /* Structure à retourner */ + GtkWidget *station; /* Premier support concentré */ + GEditorItem *editem; /* Autre vision des choses */ - 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 = (panel_node *)calloc(1, sizeof(panel_node)); - result = g_panel_item_get_path_at(item, pos); + result->path = path[depth]; + result->depth = depth; - } - 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); + result->simple = true; - } + station = gtk_dock_station_new(); + g_signal_connect(station, "switch-widget", _handler, _data); + gtk_widget_show(station); + + result->station = station; + + editem = G_EDITOR_ITEM(item); + gtk_dock_panel_add_widget(GTK_DOCK_STATION(station), + editem->widget, editem->name); return result; @@ -402,14 +381,11 @@ static char get_first_path_found(GtkWidget *base, size_t pos) /****************************************************************************** * * -* 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. * +* Paramètres : item = composant à présenter à l'affichage. * +* horiz = indique le type d'orientation désiré. * +* first = indication sur l'emplacement à utiliser. * * * -* Description : Introduit une nouvelle division sur le support indiqué. * +* Description : Prépare une nouvelle sous-division pour deux panneaux. * * * * Retour : - * * * @@ -417,281 +393,282 @@ static char get_first_path_found(GtkWidget *base, size_t pos) * * ******************************************************************************/ -static void create_panel_division(GtkWidget *parent, GtkWidget *child1, const char *name1, GtkWidget *child2, const char *name2, char orientation) +static void switch_panel_node_into_paned(panel_node *current, bool horiz, bool first) { - unsigned int index; /* Indice de la réinsertion */ - bool resize; /* Redimensionnement à garder */ - GtkWidget *station; /* Nouvelle concentration */ - GtkWidget *paned; /* Nouveau support */ + panel_node *moved; /* Noeud descendu d'un étage */ + GtkWidget *widget; /* Composant à traiter */ - orientation = toupper(orientation); + /* Descend l'élément actuel */ - /* Détermination de la localisation d'origine */ + moved = (panel_node *)calloc(1, sizeof(panel_node)); - 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; - } - } + memcpy(moved, current, sizeof(panel_node)); + moved->parent = current; + + widget = GET_PANEL_NODE_WIDGET(current); + + g_object_ref(G_OBJECT(widget)); + gtk_container_remove(GTK_CONTAINER(gtk_widget_get_parent(widget)), widget); + + if (first) + current->first = moved; else - { - index = -1; - resize = false; /* Pour gcc (Debian 4.4.5-8) 4.4.5 */ - } + current->second = moved; - gtk_widget_ref(name1 == NULL ? child1 : child2); + /* Achève la transformation */ - gtk_container_remove(GTK_CONTAINER(parent), child2); + current->path = '\0'; - /* Enrobages éventuels */ + current->simple = false; - if (!GTK_IS_DOCK_STATION(child1)) - { - station = gtk_dock_station_new(); - g_signal_connect(station, "switch-widget", _handler, _data); + current->station = NULL; - gtk_widget_show(station); - gtk_dock_panel_add_widget(GTK_DOCK_STATION(station), child1, name1); + if (horiz) + current->paned = gtk_hpaned_new(); + else + current->paned = gtk_vpaned_new(); - child1 = station; + gtk_widget_show(current->paned); - } + /* Replace le composant d'origine */ - if (!GTK_IS_DOCK_STATION(child2)) - { - station = gtk_dock_station_new(); - g_signal_connect(station, "switch-widget", _handler, _data); + if (first) + gtk_paned_add1(GTK_PANED(current->paned), widget); + else + gtk_paned_add2(GTK_PANED(current->paned), widget); - gtk_widget_show(station); - gtk_dock_panel_add_widget(GTK_DOCK_STATION(station), child2, name2); + g_object_unref(G_OBJECT(widget)); - child2 = station; +} - } - /* Insertion complète */ +/****************************************************************************** +* * +* 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) +{ + GtkWidget *widget; /* Composant à traiter */ + + /* Raccordement hiérarchique */ - if (orientation == 'N' || orientation == 'S') - paned = gtk_vpaned_new(); + if (first) + parent->first = node; else - paned = gtk_hpaned_new(); + parent->second = node; - gtk_widget_show(paned); + /* Raccordement graphique */ - 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; - } + widget = GET_PANEL_NODE_WIDGET(node); - 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; - } + if (first) + gtk_paned_add1(GTK_PANED(parent->paned), widget); + else + gtk_paned_add2(GTK_PANED(parent->paned), widget); } /****************************************************************************** * * -* 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. * +* Paramètres : node = noeud d'où lancer les recherches. * +* target = identifiant de la position visée. * * * -* Description : Place un panneau dans l'ensemble affiché. * +* Description : Indique si un noeud correspond à la branche recherchée. * * * -* Retour : - * +* Retour : Bilan de l'évaluation. * * * * Remarques : - * * * ******************************************************************************/ -static void _g_panel_item_dock(GtkWidget *base, GEditorItem *item, const char *path, size_t pos) +static bool is_panel_node_matching(const panel_node *node, char target) { - 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 */ + if (node->path == target) + return true; + if (node->simple) + return false; - //printf(" ============== PATH :: '%c' =======================\n", path[pos]); + return is_panel_node_matching(node->first, target) + || is_panel_node_matching(node->second, target); - 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)); +/****************************************************************************** +* * +* Paramètres : item = composant à présenter à l'affichage. * +* node = point d'insertion courant. * +* path = partie du chemin représentée ici. * +* depth = profondeur du chemin utilisé. * +* * +* Description : Place au bon endroit un panneau donné. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ +static void insert_item_as_panel_node(GPanelItem *item, panel_node *node, const char *path, size_t depth) +{ + char div; /* Division demandée */ + bool horiz; /* Traduction en composant */ + bool first; /* Point d'insertion */ + panel_node *new; /* Nouveau noeud créé */ + panel_node *support; /* Noeud d'accueil désigné */ - if (GTK_IS_DOCK_STATION(part)) + if (node->simple) { + /* Si on est sur la bonne voie... */ + if (path[depth] == '\0' || path[depth] == node->path) + { + /* Le parcours s'arrête ici ! */ + if (path[depth] == '\0' || path[depth + 1] == '\0') + gtk_dock_panel_add_widget(GTK_DOCK_STATION(node->station), + G_EDITOR_ITEM(item)->widget, + G_EDITOR_ITEM(item)->name); + /* On ne peut aller plus loin, on doit diviser... */ + else + { + div = toupper(path[depth + 1]); + first = (div == 'E' || div == 'S'); + horiz = (div == 'W' || div == 'E'); - path_i = g_panel_item_get_path_at(G_PANEL_ITEM(item), pos); + switch_panel_node_into_paned(node, horiz, first); - widget = gtk_dock_panel_get_widget(GTK_DOCK_STATION(part), 0); - other = G_PANEL_ITEM(g_object_get_data(G_OBJECT(widget), "pitem")); + new = create_simple_panel_node_for_item(item, path, depth + 1); - path_o = g_panel_item_get_path_at(other, pos); + attach_panel_node_to_paned(node, new, !first); - //printf(" -- path -- '%c' vs '%c'\n", path_i, path_o); + rebuild_panels_interface(node); + } - if (path_i == path_o) - gtk_dock_panel_add_widget(GTK_DOCK_STATION(part), item->widget, item->name); + } + /* On ne peut aller plus loin, on doit diviser... */ 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; + div = toupper(path[depth]); + first = (div == 'E' || div == 'S'); + horiz = (div == 'W' || div == 'E'); - parent = gtk_widget_get_parent(base); - create_panel_division(parent, item->widget, item->name, base, NULL, sel_path); - } + switch_panel_node_into_paned(node, horiz, first); - } + new = create_simple_panel_node_for_item(item, path, depth); - else if (GTK_IS_PANED(part)) - { + attach_panel_node_to_paned(node, new, !first); + rebuild_panels_interface(node); + } - printf("Paf Paned !\n"); - exit(0); + } + /* On regarde des autres côtés... */ - } + else if (is_panel_node_matching(node->first, path[depth])) + insert_item_as_panel_node(item, node->first, path, depth + (node->first->simple ? 1 : 0)); - /* Si on n'a rien trouvé, alors on redivise */ - else /*if (part == NULL)*/ + else if (is_panel_node_matching(node->second, path[depth])) + insert_item_as_panel_node(item, node->second, path, depth + (node->second->simple ? 1 : 0)); + + /* On doit diviser qqch... */ + else { - if (!GTK_IS_DOCK_STATION(base)) + /* Si l'élément doit passer en force */ + if (isupper(path[depth])) { - 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); + div = path[depth]; + first = (div == 'E' || div == 'S'); + horiz = (div == 'W' || div == 'E'); - 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)); + switch_panel_node_into_paned(node, horiz, first); - } + new = create_simple_panel_node_for_item(item, path, depth); - path_i = g_panel_item_get_path_at(G_PANEL_ITEM(item), pos); + attach_panel_node_to_paned(node, new, !first); - widget = gtk_dock_panel_get_widget(GTK_DOCK_STATION(base), 0); - other = G_PANEL_ITEM(g_object_get_data(G_OBJECT(widget), "pitem")); + rebuild_panels_interface(node); - 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); + { + if (is_panel_node_matching(node->second, 'M')) + support = node->second; + else + support = node->first; - parent = gtk_widget_get_parent(base); - create_panel_division(parent, item->widget, item->name, base, NULL, sel_path); + div = toupper(path[depth]); + first = (div == 'E' || div == 'S'); + horiz = (div == 'W' || div == 'E'); - } + switch_panel_node_into_paned(support, horiz, first); + new = create_simple_panel_node_for_item(item, path, depth); + attach_panel_node_to_paned(support, new, !first); -} + rebuild_panels_interface(support); + } + } -/* ---------------------------------------------------------------------------------- */ -/* PLACEMENTS DES DIFFERENTS PANNEAUX */ -/* ---------------------------------------------------------------------------------- */ +} /****************************************************************************** * * -* Paramètres : handler = procédure à réveiller en cas de changements. * -* data = donnée à faire suivre. * +* Paramètres : current = point de départ de la réorganisation graphique. * * * -* Description : Prépare le terrain pour l'affichage central. * +* Description : Met à jour l'affichage suite à un changement hiérarchique. * * * -* Retour : Composant de support sur lequel tout va se placer. * +* Retour : - * * * * Remarques : - * * * ******************************************************************************/ -GtkWidget *init_panels2(GCallback handler, gpointer data) +static void rebuild_panels_interface(const panel_node *current) { - GtkWidget *result; /* Support à retourner */ - - result = qck_create_padded_alignment(0, 0, 0, 0); - gtk_widget_show(result); - - _support = result; - _handler = handler; - _data = data; + GtkWidget *widget; /* Composant à traiter */ + panel_node *parent; /* Raccourci confortable */ - return result; + widget = GET_PANEL_NODE_WIDGET(current); -} + /* On se trouve à la racine... */ + if (current->parent == NULL) + gtk_container_add(GTK_CONTAINER(_support), widget); + /* Sinon, une sous-division ne peut venir que d'une division... */ + else + { + /* BUG_ON(parent->simple) */ -/****************************************************************************** -* * -* Paramètres : ref = espace de référencement global. * -* * -* Description : Charge les principaux panneaux de l'éditeur. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ + parent = current->parent; -void load_main_panels(GObject *ref) -{ - GPanelItem *item; /* Panneau de base à charger */ + if (current == parent->first) + gtk_paned_add1(GTK_PANED(parent->paned), widget); + else + gtk_paned_add2(GTK_PANED(parent->paned), widget); - item = create_log_panel(); - g_panel_item_dock(item); + } - item = create_symbols_panel(ref); - g_panel_item_dock(item); + //g_object_unref(G_OBJECT(widget)); } diff --git a/src/gui/panels/panel.h b/src/gui/panels/panel.h index 893c48b..0dd25a9 100644 --- a/src/gui/panels/panel.h +++ b/src/gui/panels/panel.h @@ -49,7 +49,7 @@ typedef struct _GPanelItemClass GPanelItemClass; GType g_panel_item_get_type(void); /* Crée un élément de panneau réactif. */ -GEditorItem *g_panel_item_new(const char *, const char *, GtkWidget *, const char *); +GEditorItem *g_panel_item_new(GObject *, const char *, const char *, GtkWidget *, const char *); /* Recherche un panneau à partir de son nom court. */ GPanelItem *g_panel_item_get(const char *); diff --git a/src/gui/panels/symbols.h b/src/gui/panels/symbols.h index f18a2ea..182238a 100644 --- a/src/gui/panels/symbols.h +++ b/src/gui/panels/symbols.h @@ -33,7 +33,7 @@ -#define PANEL_SYMBOL_ID _("Symboles") +#define PANEL_SYMBOL_ID _("Symbols") #define G_TYPE_SYMBOLS_PANEL g_symbols_panel_get_type() diff --git a/src/gui/panels/welcome.c b/src/gui/panels/welcome.c new file mode 100644 index 0000000..018f12a --- /dev/null +++ b/src/gui/panels/welcome.c @@ -0,0 +1,179 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * welcome.c - panneau d'affichage d'accueil + * + * Copyright (C) 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 "welcome.h" + + +#include <string.h> +#include <gtk/gtk.h> + + +#include "panel-int.h" +#include "../../gtkext/easygtk.h" +#include "../../gtkext/support.h" + + + +/* -------------------------- PARTIE PRINCIPALE DU PANNEAU -------------------------- */ + + +/* Panneau d'aperçu de graphiques (instance) */ +struct _GWelcomePanel +{ + GPanelItem parent; /* A laisser en premier */ + +}; + + +/* Panneau d'aperçu de graphiques (classe) */ +struct _GWelcomePanelClass +{ + GPanelItemClass parent; /* A laisser en premier */ + +}; + + +/* Initialise la classe des panneaux d'accueil. */ +static void g_welcome_panel_class_init(GWelcomePanelClass *); + +/* Initialise une instance de panneau d'accueil. */ +static void g_welcome_panel_init(GWelcomePanel *); + + + +/* ---------------------------------------------------------------------------------- */ +/* PARTIE PRINCIPALE DU PANNEAU */ +/* ---------------------------------------------------------------------------------- */ + + +/* Indique le type définit pour un panneau d'accueil. */ +G_DEFINE_TYPE(GWelcomePanel, g_welcome_panel, G_TYPE_PANEL_ITEM); + + +/****************************************************************************** +* * +* Paramètres : klass = classe à initialiser. * +* * +* Description : Initialise la classe des panneaux d'accueil. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_welcome_panel_class_init(GWelcomePanelClass *klass) +{ + +} + + +/****************************************************************************** +* * +* Paramètres : panel = instance à initialiser. * +* * +* Description : Initialise une instance de panneau d'accueil. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_welcome_panel_init(GWelcomePanel *panel) +{ + GtkWidget *support; /* Fond du panneau */ + GtkWidget *align; /* Alignement centré */ + gchar *filename; /* Chemin d'accès au fichier */ + GtkWidget *image; /* Image chargée */ + GEditorItem *base; /* Version basique d'instance */ + + support = gtk_handle_box_new(); + gtk_widget_modify_bg(support, GTK_STATE_NORMAL, &support->style->bg[GTK_STATE_NORMAL]); + gtk_widget_show(support); + + align = gtk_alignment_new(0.5f, 0.5f, 0.0f, 0.0f); + gtk_widget_show(align); + gtk_container_add(GTK_CONTAINER(support), align); + + filename = find_pixmap_file("welcome.png"); + image = qck_create_image(NULL, NULL, filename); + gtk_container_add(GTK_CONTAINER(align), image); + + base = G_EDITOR_ITEM(panel); + base->widget = support; + +} + + +/****************************************************************************** +* * +* Paramètres : ref = espace de référencement global. * +* * +* Description : Crée un panneau d'accueil. * +* * +* Retour : Adresse de la structure mise en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GEditorItem *g_welcome_panel_new(GObject *ref) +{ + GEditorItem *result; /* Structure à retourner */ + + result = g_object_new(G_TYPE_WELCOME_PANEL, NULL); + + g_panel_item_init_ext(G_PANEL_ITEM(result), ref, PANEL_WELCOME_ID, + _("Welcome"), G_EDITOR_ITEM(result)->widget, "M"); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : ref = espace de référencement global. * +* * +* Description : Construit et intègre un panneau d'accueil. * +* * +* Retour : Adresse du panneau mis en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GPanelItem *create_welcome_panel(GObject *ref) +{ + GEditorItem *result; /* Elément réactif à renvoyer */ + + result = g_welcome_panel_new(ref); + + /* Enregistre correctement le tout */ + register_editor_item(result); + + return G_PANEL_ITEM(result); + +} diff --git a/src/gui/panels/welcome.h b/src/gui/panels/welcome.h new file mode 100644 index 0000000..2bf5002 --- /dev/null +++ b/src/gui/panels/welcome.h @@ -0,0 +1,65 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * welcome.h - prototypes pour le panneau d'affichage d'accueil + * + * Copyright (C) 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 + */ + + +#ifndef _GUI_PANELS_WELCOME_H +#define _GUI_PANELS_WELCOME_H + + +#include <i18n.h> + + +#include "panel.h" + + + +#define PANEL_WELCOME_ID _("Welcome") + + +#define G_TYPE_WELCOME_PANEL g_welcome_panel_get_type() +#define G_WELCOME_PANEL(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), g_welcome_panel_get_type(), GWelcomePanel)) +#define G_IS_WELCOME_PANEL(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_welcome_panel_get_type())) +#define G_WELCOME_PANEL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_WELCOME_PANEL, GWelcomePanelClass)) +#define G_IS_WELCOME_PANEL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_WELCOME_PANEL)) +#define G_WELCOME_PANEL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_WELCOME_PANEL, GWelcomePanelClass)) + + +/* Panneau d'affichage des symboles (instance) */ +typedef struct _GWelcomePanel GWelcomePanel; + +/* Panneau d'affichage des symboles (classe) */ +typedef struct _GWelcomePanelClass GWelcomePanelClass; + + +/* Indique le type définit pour un panneau d'accueil. */ +GType g_welcome_panel_get_type(void); + +/* Crée un panneau d'accueil. */ +GEditorItem *g_welcome_panel_new(GObject *); + +/* Construit et intègre un panneau d'accueil. */ +GPanelItem *create_welcome_panel(GObject *); + + + +#endif /* _GUI_PANELS_WELCOME_H */ @@ -149,8 +149,8 @@ int main(int argc, char **argv) filename = get_string_config_value(config, MPT_LAST_PROJECT); - if (filename == NULL) project = g_study_project_new(); - else project = g_study_project_open(filename); + if (filename == NULL) project = g_study_project_new(G_OBJECT(editor)); + else project = g_study_project_open(G_OBJECT(editor), filename); set_current_project(project); diff --git a/src/project.c b/src/project.c index c3c1844..37fc3e5 100644 --- a/src/project.c +++ b/src/project.c @@ -61,6 +61,8 @@ struct _GStudyProject { GObject parent; /* A laisser en premier */ + GObject *ref; /* Espace de référencement */ + char *filename; /* Lieu d'enregistrement */ loaded_binary **binaries; /* Fichiers binaires associés */ @@ -148,12 +150,15 @@ static void g_study_project_init(GStudyProject *project) * * ******************************************************************************/ -GStudyProject *g_study_project_new(void) +GStudyProject *g_study_project_new(GObject *ref) { GStudyProject *result; /* Composant à retourner */ result = g_object_new(G_TYPE_STUDY_PROJECT, NULL); + g_object_ref(ref); + result->ref = ref; + return result; } @@ -171,7 +176,7 @@ GStudyProject *g_study_project_new(void) * * ******************************************************************************/ -GStudyProject *g_study_project_open(const char *filename) +GStudyProject *g_study_project_open(GObject *ref, const char *filename) { GStudyProject *result; /* Adresse à retourner */ xmlDocPtr xdoc; /* Structure XML chargée */ @@ -184,7 +189,7 @@ GStudyProject *g_study_project_open(const char *filename) if (!open_xml_file(filename, &xdoc, &context)) return NULL; - result = g_study_project_new(); + result = g_study_project_new(ref); result->filename = strdup(filename); @@ -405,7 +410,7 @@ size_t g_study_project_attach_binary(GStudyProject *project, GLoadedBinary *bina scroll = loaded->scrollwindows[BVW_BLOCK]; title = g_loaded_binary_get_filename(binary, false); - loaded->item = g_panel_item_new(title, title, scroll, "M"); + loaded->item = g_panel_item_new(project->ref, title, title, scroll, "M"); /* Enregistrement dans le projet */ diff --git a/src/project.h b/src/project.h index de5badb..0665ec0 100644 --- a/src/project.h +++ b/src/project.h @@ -67,10 +67,10 @@ typedef struct _GStudyProjectClass GStudyProjectClass; GType g_study_project_get_type(void); /* Crée un nouveau projet vierge. */ -GStudyProject *g_study_project_new(void); +GStudyProject *g_study_project_new(GObject *); /* Crée un projet à partir du contenu XML d'un fichier. */ -GStudyProject *g_study_project_open(const char *); +GStudyProject *g_study_project_open(GObject *, const char *); /* Procède à l'enregistrement d'un projet donné. */ bool g_study_project_save(GStudyProject *, const char *); |