diff options
author | Cyrille Bagard <nocbos@gmail.com> | 2015-08-13 00:35:42 (GMT) |
---|---|---|
committer | Cyrille Bagard <nocbos@gmail.com> | 2015-08-13 00:35:42 (GMT) |
commit | 50a657889a32a6df365bf9880a6f56bf3a0e828c (patch) | |
tree | cf6218848a0119aafa4610baee73adcc1ef6c10b /src/gtkext | |
parent | 4c611d6f41d82603a5d37baf88b0bb213044eb60 (diff) |
Improved the look of dock stations and saved screen space.
git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@571 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
Diffstat (limited to 'src/gtkext')
-rw-r--r-- | src/gtkext/Makefile.am | 2 | ||||
-rw-r--r-- | src/gtkext/easygtk.c | 186 | ||||
-rw-r--r-- | src/gtkext/easygtk.h | 8 | ||||
-rw-r--r-- | src/gtkext/gtkdockable-int.h | 69 | ||||
-rw-r--r-- | src/gtkext/gtkdockable.c | 381 | ||||
-rw-r--r-- | src/gtkext/gtkdockable.h | 72 | ||||
-rw-r--r-- | src/gtkext/gtkdockstation.c | 157 | ||||
-rw-r--r-- | src/gtkext/gtkdockstation.h | 9 |
8 files changed, 807 insertions, 77 deletions
diff --git a/src/gtkext/Makefile.am b/src/gtkext/Makefile.am index 6d713d9..6849585 100644 --- a/src/gtkext/Makefile.am +++ b/src/gtkext/Makefile.am @@ -8,6 +8,8 @@ libgtkext_la_SOURCES = \ gtkblockview.h gtkblockview.c \ gtkbufferview-int.h \ gtkbufferview.h gtkbufferview.c \ + gtkdockable-int.h \ + gtkdockable.h gtkdockable.c \ gtkdockstation.h gtkdockstation.c \ gtkgraphview.h gtkgraphview.c \ gtksourceview.h gtksourceview.c \ diff --git a/src/gtkext/easygtk.c b/src/gtkext/easygtk.c index fcbaa19..61e8953 100644 --- a/src/gtkext/easygtk.c +++ b/src/gtkext/easygtk.c @@ -28,6 +28,10 @@ +/* Termine la construction d'un composant 'GtkButton'. */ +static void _finish_button_with_img(GtkWidget *, GObject *, const char *, GtkWidget *, const char *); + + /****************************************************************************** * * @@ -399,6 +403,113 @@ GtkWidget *qck_create_button_with_img(GObject *object, const char *name, const c /****************************************************************************** * * +* Paramètres : button = composant graphique dont la définition est à finir.* +* object = espace dédié à l'inscription de références. * +* name = nom à donner au nouveau composant. * +* picture = éventuelle image sous forme de composant GTK. * +* label = contenu de l'étiquette éventuelle associée. * +* * +* Description : Termine la construction d'un composant 'GtkButton'. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void _finish_button_with_img(GtkWidget *button, GObject *object, const char *name, GtkWidget *picture, const char *label) +{ + GtkWidget *caption; /* Etiquette à coller */ + GtkWidget *hbox; /* Séparation horizontale */ + + /* Création des éléments internes (2/2) */ + + if (label != NULL) + { + caption = gtk_label_new_with_mnemonic(label); + gtk_widget_show(caption); + } + + /* Mise en place */ + + if (picture != NULL && label != NULL) + { + hbox = gtk_hbox_new(FALSE, 2); + gtk_widget_show(hbox); + gtk_container_add(GTK_CONTAINER(button), hbox); + + gtk_box_pack_start(GTK_BOX(hbox), picture, FALSE, FALSE, 0); + gtk_box_pack_start(GTK_BOX(hbox), caption, FALSE, FALSE, 0); + + } + + else if (picture != NULL) + gtk_container_add(GTK_CONTAINER(button), picture); + + else /*if (label != NULL)*/ + gtk_container_add(GTK_CONTAINER(button), caption); + + /* Interactions GTK... */ + + if (G_IS_OBJECT(object) && name != NULL) + { + g_object_ref(G_OBJECT(button)); + g_object_set_data_full(object, name, button, (GDestroyNotify)g_object_unref); + } + + gtk_widget_show(button); + +} + + +/****************************************************************************** +* * +* Paramètres : object = espace dédié à l'inscription de références. * +* name = nom à donner au nouveau composant. * +* image = nom de l'image stockée dans GTK. * +* size = taille de l'image éventuelle à faire figurer. * +* label = contenu de l'étiquette éventuelle associée. * +* handler = éventuelle fonction de sélection associée. * +* data = données à transmettre avec l'événement si besoin. * +* * +* Description : Crée et enregistre un composant 'GtkButton'. * +* * +* Retour : Simple bouton mis en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GtkWidget *qck_create_button_with_named_img(GObject *object, const char *name, const char *image, GtkIconSize size, const char *label, GCallback handler, gpointer data) +{ + GtkWidget *result; /* Résultat à renvoyer */ + GtkWidget *picture; /* Image de représentation */ + + result = gtk_button_new(); + gtk_widget_set_can_default(result, TRUE); + + /* Création des éléments internes (1/2) */ + + if (image != NULL) + { + picture = gtk_image_new_from_icon_name(image, size); + gtk_widget_show(picture); + } + else + picture = NULL; + + _finish_button_with_img(result, object, name, picture, label); + + if (handler != NULL) + g_signal_connect(result, "clicked", handler, data); + + return result; + +} + + +/****************************************************************************** +* * * Paramètres : object = espace dédié à l'inscription de références. * * name = nom à donner au nouveau composant. * * image = nom de l'image stockée dans GTK. * @@ -418,13 +529,11 @@ GtkWidget *qck_create_button_with_css_img(GObject *object, const char *name, con { GtkWidget *result; /* Résultat à renvoyer */ GtkWidget *picture; /* Image de représentation */ - GtkWidget *caption; /* Etiquette à coller */ - GtkWidget *hbox; /* Séparation horizontale */ result = gtk_button_new(); gtk_widget_set_can_default(result, TRUE); - /* Création des éléments internes */ + /* Création des éléments internes (1/2) */ if (image != NULL) { @@ -434,44 +543,59 @@ GtkWidget *qck_create_button_with_css_img(GObject *object, const char *name, con gtk_widget_set_name(picture, image); } + else + picture = NULL; - if (label != NULL) - { - caption = gtk_label_new_with_mnemonic(label); - gtk_widget_show(caption); - } + _finish_button_with_img(result, object, name, picture, label); - /* Mise en place */ + if (handler != NULL) + g_signal_connect(result, "clicked", handler, data); - if (image != NULL && label != NULL) - { - hbox = gtk_hbox_new(FALSE, 2); - gtk_widget_show(hbox); - gtk_container_add(GTK_CONTAINER(result), hbox); + return result; - gtk_box_pack_start(GTK_BOX(hbox), picture, FALSE, FALSE, 0); - gtk_box_pack_start(GTK_BOX(hbox), caption, FALSE, FALSE, 0); +} - } - else if (image != NULL) - gtk_container_add(GTK_CONTAINER(result), picture); +/****************************************************************************** +* * +* Paramètres : object = espace dédié à l'inscription de références. * +* name = nom à donner au nouveau composant. * +* image = nom de l'image stockée dans GTK. * +* size = taille de l'image éventuelle à faire figurer. * +* label = contenu de l'étiquette éventuelle associée. * +* handler = éventuelle fonction de sélection associée. * +* data = données à transmettre avec l'événement si besoin. * +* * +* Description : Crée et enregistre un composant 'GtkCheckButton'. * +* * +* Retour : Simple bouton mis en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GtkWidget *qck_create_toggle_button_with_named_img(GObject *object, const char *name, const char *image, GtkIconSize size, const char *label, GCallback handler, gpointer data) +{ + GtkWidget *result; /* Résultat à renvoyer */ + GtkWidget *picture; /* Image de représentation */ - else /*if (label != NULL)*/ - gtk_container_add(GTK_CONTAINER(result), caption); + result = gtk_toggle_button_new(); + gtk_widget_set_can_default(result, TRUE); - /* Interactions GTK... */ + /* Création des éléments internes (1/2) */ - if (G_IS_OBJECT(object) && name != NULL) + if (image != NULL) { - g_object_ref(G_OBJECT(result)); - g_object_set_data_full(object, name, result, (GDestroyNotify)g_object_unref); + picture = gtk_image_new_from_icon_name(image, size); + gtk_widget_show(picture); } + else + picture = NULL; - gtk_widget_show(result); + _finish_button_with_img(result, object, name, picture, label); if (handler != NULL) - g_signal_connect(result, "clicked", handler, data); + g_signal_connect(result, "toggled", handler, data); return result; @@ -802,6 +926,14 @@ void add_accelerator_to_menu_item(GtkWidget *item, const char *accelerator, GtkA gtk_accelerator_parse(accelerator, &key, &mods); + + gboolean force_accel_activation(GtkWidget *widget, guint signal_id, gpointer data) + { + return TRUE; + } + + g_signal_connect(item, "can-activate-accel", force_accel_activation, NULL); + gtk_widget_add_accelerator(item, "activate", group, key, mods, GTK_ACCEL_VISIBLE); diff --git a/src/gtkext/easygtk.h b/src/gtkext/easygtk.h index 58229af..13cb7fd 100644 --- a/src/gtkext/easygtk.h +++ b/src/gtkext/easygtk.h @@ -60,12 +60,18 @@ GtkWidget *qck_create_textview(GObject *, const char *, GCallback, gpointer); GtkWidget *qck_create_button(GObject *, const char *, const char *, GCallback, gpointer); /* Crée et enregistre un composant 'GtkButton'. */ -GtkWidget *qck_create_button_with_img(GObject *, const char *, const char *, GCallback, gpointer); +GtkWidget *qck_create_button_with_img(GObject *, const char *, const char *, GCallback, gpointer) __attribute__ ((deprecated)); + +/* Crée et enregistre un composant 'GtkButton'. */ +GtkWidget *qck_create_button_with_named_img(GObject *, const char *, const char *, GtkIconSize, const char *, GCallback, gpointer); /* Crée et enregistre un composant 'GtkButton'. */ GtkWidget *qck_create_button_with_css_img(GObject *, const char *, const char *, const char *, GCallback, gpointer); /* Crée et enregistre un composant 'GtkCheckButton'. */ +GtkWidget *qck_create_toggle_button_with_named_img(GObject *, const char *, const char *, GtkIconSize, const char *, GCallback, gpointer); + +/* Crée et enregistre un composant 'GtkCheckButton'. */ GtkWidget *qck_create_check_button(GObject *, const char *, const char *, GCallback, gpointer); /* Crée et enregistre un composant 'GtkRadioButton'. */ diff --git a/src/gtkext/gtkdockable-int.h b/src/gtkext/gtkdockable-int.h new file mode 100644 index 0000000..95e1d0c --- /dev/null +++ b/src/gtkext/gtkdockable-int.h @@ -0,0 +1,69 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * gtkdockable-int.h - définitions internes propres aux éléments acceptés dans les composants de rassemblement + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * 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 Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +#ifndef _GTK_DOCKABLE_INT_H +#define _GTK_DOCKABLE_INT_H + + +#include "gtkdockable.h" + + +#include <regex.h> + + + +/* Fournit le nom court du composant encapsulable. */ +typedef const char * (* get_dockable_name_fc) (const GtkDockable *); + +/* Fournit le nom court du composant encapsulable. */ +typedef const char * (* get_dockable_desc_fc) (const GtkDockable *); + +/* Fournit le composant principal à encapsuler au besoin. */ +typedef GtkWidget * (* get_dockable_widget_fc) (const GtkDockable *); + +/* Démarre l'actualisation du filtrage des paramètres. */ +typedef void (* update_filtered_data_fc) (GtkDockable *, const regex_t *); + + +/* Elément accepté dans les rassemblements (interface) */ +struct _GtkDockableIface +{ + GTypeInterface base_iface; /* A laisser en premier */ + + bool can_search; /* Contenu fouillable ? */ + bool can_be_closed; /* Fermeture possible ? */ + + get_dockable_name_fc get_name; /* Nom pour titre */ + get_dockable_desc_fc get_desc; /* Description humaine */ + get_dockable_widget_fc get_widget; /* Composant à représenter */ + update_filtered_data_fc update_filtered;/* Mise à jour du filtrage */ + +}; + + +/* Redéfinition */ +typedef GtkDockableIface GtkDockableInterface; + + + +#endif /* _GTK_DOCKABLE_INT_H */ diff --git a/src/gtkext/gtkdockable.c b/src/gtkext/gtkdockable.c new file mode 100644 index 0000000..8819108 --- /dev/null +++ b/src/gtkext/gtkdockable.c @@ -0,0 +1,381 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * gtkdockable.c - éléments acceptés dans les composants de rassemblement + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * 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 Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +#include "gtkdockable.h" + + +#include <assert.h> +#include <malloc.h> + + +#include <i18n.h> + + +#include "easygtk.h" +#include "gtkdockable-int.h" + + + +/* --------------------- DEFINITIONS PRINCIPALES DE L'INTERFACE --------------------- */ + + +/* Procède à l'initialisation de l'interface de rassemblement. */ +static void gtk_dockable_default_init(GtkDockableInterface *); + + + +/* ------------------------ FONCTIONS DE RECHERCHE INTEGREES ------------------------ */ + + +/* Construit une zone de recherches vouée à être intégrée. */ +static GtkWidget *build_search_area(GtkDockable *, GtkWidget **); + +/* Met à jour l'expression de filtrage de la zone intégrée. */ +static void on_dockable_search_changed(GtkSearchEntry *, GtkDockable *); + + + +/* ---------------------------------------------------------------------------------- */ +/* DEFINITIONS PRINCIPALES DE L'INTERFACE */ +/* ---------------------------------------------------------------------------------- */ + + +/* Détermine le type d'une interface pour rassemblement. */ +G_DEFINE_INTERFACE(GtkDockable, gtk_dockable, G_TYPE_OBJECT) + + +/****************************************************************************** +* * +* Paramètres : iface = interface GTK à initialiser. * +* * +* Description : Procède à l'initialisation de l'interface de rassemblement. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void gtk_dockable_default_init(GtkDockableInterface *iface) +{ + +} + + +/****************************************************************************** +* * +* Paramètres : dockable = instance GTK dont l'interface est à consulter. * +* * +* Description : Fournit le nom court du composant encapsulable. * +* * +* Retour : Désignation humaine pour titre d'onglet ou de fenêtre. * +* * +* Remarques : - * +* * +******************************************************************************/ + +const char *gtk_dockable_get_name(const GtkDockable *dockable) +{ + GtkDockableIface *iface; /* Interface utilisée */ + + iface = GTK_DOCKABLE_GET_IFACE(dockable); + + return iface->get_name(dockable); + +} + + +/****************************************************************************** +* * +* Paramètres : dockable = instance GTK dont l'interface est à consulter. * +* * +* Description : Fournit le nom long du composant encapsulable. * +* * +* Retour : Désignation humaine pour titre d'onglet ou de fenêtre. * +* * +* Remarques : - * +* * +******************************************************************************/ + +const char *gtk_dockable_get_desc(const GtkDockable *dockable) +{ + GtkDockableIface *iface; /* Interface utilisée */ + + iface = GTK_DOCKABLE_GET_IFACE(dockable); + + return iface->get_desc(dockable); + +} + + +/****************************************************************************** +* * +* Paramètres : dockable = instance GTK dont l'interface est à consulter. * +* * +* Description : Indique si le composant représenté à du contenu à fouiller. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool gtk_dockable_can_search(const GtkDockable *dockable) +{ + GtkDockableIface *iface; /* Interface utilisée */ + + iface = GTK_DOCKABLE_GET_IFACE(dockable); + + return iface->can_search; + +} + + +/****************************************************************************** +* * +* Paramètres : dockable = instance GTK dont l'interface est à consulter. * +* * +* Description : Indique si le composant peut être désencapsulé manuellement. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool gtk_dockable_can_be_closed(const GtkDockable *dockable) +{ + GtkDockableIface *iface; /* Interface utilisée */ + + iface = GTK_DOCKABLE_GET_IFACE(dockable); + + return iface->can_be_closed; + +} + + +/****************************************************************************** +* * +* Paramètres : dockable = instance GTK dont l'interface est à consulter. * +* * +* Description : Fournit le composant graphique intégrable dans un ensemble. * +* * +* Retour : Composant graphique prêt à emploi. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GtkWidget *gtk_dockable_get_widget(GtkDockable *dockable) +{ + GtkWidget *result; /* Composant à retourner */ + GtkDockableIface *iface; /* Interface utilisée */ + GtkWidget *widget; /* Composant graphique interne */ + GtkWidget *revealer; /* Révélateur à intégrer ? */ + GtkWidget *search; /* Zone de recherche */ + + iface = GTK_DOCKABLE_GET_IFACE(dockable); + + widget = iface->get_widget(dockable); + g_object_ref(G_OBJECT(widget)); + + /* Encapsulation avec un panneau coulissant ? */ + + if (iface->can_search) + { + revealer = gtk_revealer_new(); + gtk_widget_show(revealer); + + gtk_container_add(GTK_CONTAINER(revealer), build_search_area(dockable, &search)); + + result = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0); + gtk_widget_show(result); + + gtk_box_pack_start(GTK_BOX(result), revealer, FALSE, TRUE, 0); + gtk_box_pack_start(GTK_BOX(result), widget, TRUE, TRUE, 0); + + g_object_set_data(G_OBJECT(result), "revealer", revealer); + g_object_set_data(G_OBJECT(result), "search", search); + + } + + /* Ou bien non ! */ + else + result = widget; + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : dockable = instance GTK dont l'interface est à consulter. * +* built = composant graphique d'encapsulation mis en place. * +* reveal = détermine l'action à mener. * +* * +* Description : Révèle ou cache la zone de recherches. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void gtk_dockable_toggle_revealer(GtkDockable *dockable, GtkWidget *built, gboolean reveal) +{ + GtkRevealer *revealer; /* Révélateur à actionner */ + GtkWidget *entry; /* Zone de recherche à activer */ + + revealer = GTK_REVEALER(g_object_get_data(G_OBJECT(built), "revealer")); + assert(revealer != NULL); + + gtk_revealer_set_reveal_child(revealer, reveal); + + if (reveal) + { + entry = GTK_WIDGET(g_object_get_data(G_OBJECT(built), "search")); + gtk_widget_grab_focus(entry); + } + +} + + + +/* ---------------------------------------------------------------------------------- */ +/* FONCTIONS DE RECHERCHE INTEGREES */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +* * +* Paramètres : dockable = élément encapsulable à avertir des changements. * +* search = zone de saisie pour lancer les recherches. * +* * +* Description : Construit une zone de recherches vouée à être intégrée. * +* * +* Retour : Composant GTK prêt à être intégré. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static GtkWidget *build_search_area(GtkDockable *dockable, GtkWidget **search) +{ + GtkWidget *result; /* Support à retourner */ + GtkWidget *label; /* Etiquette à utiliser */ + + result = gtk_grid_new(); + gtk_grid_set_row_spacing(GTK_GRID(result), 8); + gtk_widget_show(result); + + label = qck_create_label(NULL, NULL, _("Look for:")); + g_object_set(label, "margin", 8, NULL); + gtk_grid_attach(GTK_GRID(result), label, 0, 0, 1, 1); + + *search = gtk_search_entry_new(); + g_signal_connect(*search, "search-changed", G_CALLBACK(on_dockable_search_changed), dockable); + gtk_widget_set_hexpand(*search, TRUE); + gtk_widget_show(*search); + gtk_grid_attach_next_to(GTK_GRID(result), *search, label, GTK_POS_RIGHT, 1, 1); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : entry = entrée de texte contenant le filtre brut. * +* Paramètres : dockable = élément encapsulable à avertir des changements. * +* * +* Description : Met à jour l'expression de filtrage de la zone intégrée. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void on_dockable_search_changed(GtkSearchEntry *entry, GtkDockable *dockable) +{ + regex_t *filter; /* Expression régulière */ + const gchar *text; /* Texte de l'utilisateur */ + int ret; /* Bilan de mise en place */ + GdkRGBA error; /* Couleur d'erreur */ + GtkDockableIface *iface; /* Interface utilisée */ + + filter = g_object_get_data(G_OBJECT(entry), "preg_filter"); + + text = gtk_entry_get_text(GTK_ENTRY(entry)); + + /* Mise en place d'une nouvelle règle */ + if (strlen(text) > 0) + { + if (filter == NULL) + { + void destroy_filter(regex_t *preg) + { + regfree(preg); + free(preg); + } + + filter = (regex_t *)calloc(1, sizeof(regex_t)); + g_object_set_data_full(G_OBJECT(entry), "preg_filter", filter, (GDestroyNotify)destroy_filter); + + } + else + regfree(filter); + + ret = regcomp(filter, text, REG_EXTENDED); + + if (ret != 0) + { + error.red = 1.0; + error.green = 0.0; + error.blue = 0.0; + error.alpha = 1.0; + gtk_widget_override_color(GTK_WIDGET(entry), GTK_STATE_NORMAL, &error); + + return; + + } + + } + + /* Suppresion de toute règle existante */ + else if (filter != NULL) + { + g_object_set_data(G_OBJECT(entry), "preg_filter", NULL); + filter = NULL; + } + + /* Mises à jour */ + + gtk_widget_override_color(GTK_WIDGET(entry), GTK_STATE_NORMAL, NULL); + + iface = GTK_DOCKABLE_GET_IFACE(dockable); + + iface->update_filtered(dockable, filter); + +} diff --git a/src/gtkext/gtkdockable.h b/src/gtkext/gtkdockable.h new file mode 100644 index 0000000..91a6bda --- /dev/null +++ b/src/gtkext/gtkdockable.h @@ -0,0 +1,72 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * gtkdockable.h - prototypes pour les éléments acceptés dans les composants de rassemblement + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * 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 Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +#ifndef _GTKEXT_GTKDOCKABLE_H +#define _GTKEXT_GTKDOCKABLE_H + + +#include <stdbool.h> +#include <gtk/gtk.h> + + + +#define GTK_TYPE_DOCKABLE (gtk_dockable_get_type()) +#define GTK_DOCKABLE(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GTK_TYPE_DOCKABLE, GtkDockable)) +#define GTK_DOCKABLE_CLASS(vtable) (G_TYPE_CHECK_CLASS_CAST((vtable), GTK_TYPE_DOCKABLE, GtkDockableIface)) +#define GTK_IS_DOCKABLE(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), GTK_TYPE_DOCKABLE)) +#define GTK_IS_DOCKABLE_CLASS(vtable) (G_TYPE_CHECK_CLASS_TYPE((vtable), GTK_TYPE_DOCKABLE)) +#define GTK_DOCKABLE_GET_IFACE(inst) (G_TYPE_INSTANCE_GET_INTERFACE((inst), GTK_TYPE_DOCKABLE, GtkDockableIface)) + + +/* Elément accepté dans les rassemblements (coquille vide) */ +typedef struct _GtkDockable GtkDockable; + +/* Elément accepté dans les rassemblements (interface) */ +typedef struct _GtkDockableIface GtkDockableIface; + + + +/* Détermine le type d'une interface pour rassemblement. */ +GType gtk_dockable_get_type(void) G_GNUC_CONST; + +/* Indique si le composant représenté à du contenu à fouiller. */ +bool gtk_dockable_can_search(const GtkDockable *); + +/* Indique si le composant peut être désencapsulé manuellement. */ +bool gtk_dockable_can_be_closed(const GtkDockable *); + +/* Fournit le nom court du composant encapsulable. */ +const char *gtk_dockable_get_name(const GtkDockable *); + +/* Fournit le nom long du composant encapsulable. */ +const char *gtk_dockable_get_desc(const GtkDockable *); + +/* Fournit le composant graphique intégrable dans un ensemble. */ +GtkWidget *gtk_dockable_get_widget(GtkDockable *); + +/* Révèle ou cache la zone de recherches. */ +void gtk_dockable_toggle_revealer(GtkDockable *, GtkWidget *, gboolean); + + + +#endif /* _GTKEXT_GTKDOCKABLE_H */ diff --git a/src/gtkext/gtkdockstation.c b/src/gtkext/gtkdockstation.c index 2737557..e10e55f 100644 --- a/src/gtkext/gtkdockstation.c +++ b/src/gtkext/gtkdockstation.c @@ -42,7 +42,17 @@ static void gtk_dock_station_class_init(GtkDockStationClass *); static void gtk_dock_station_init(GtkDockStation *); /* Met à jour le titre du support de panneaux concentrés. */ -static gboolean gtk_dock_station_switch_panel(GtkNotebook *, gpointer *, guint, gpointer); +static gboolean gtk_dock_station_switch_panel(GtkNotebook *, gpointer *, guint, GtkDockStation *); + + + + +/* Révèle ou cache la zone de recherches. */ +static void on_toggle_revealer(GtkToggleButton *, GtkDockStation *); + + + + @@ -114,7 +124,7 @@ static void gtk_dock_station_init(GtkDockStation *station) eventbox = gtk_event_box_new(); gtk_widget_show(eventbox); - gtk_box_pack_start(GTK_BOX(station), eventbox, FALSE, TRUE, 0); + //gtk_box_pack_start(GTK_BOX(station), eventbox, FALSE, TRUE, 0); hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0); gtk_widget_show(hbox); @@ -144,13 +154,42 @@ static void gtk_dock_station_init(GtkDockStation *station) gtk_container_add(GTK_CONTAINER(button), image); gtk_widget_set_size_request(image, 10, 10); + + + station->notebook = GTK_NOTEBOOK(gtk_notebook_new()); gtk_widget_show(GTK_WIDGET(station->notebook)); gtk_box_pack_start(GTK_BOX(station), GTK_WIDGET(station->notebook), TRUE, TRUE, 0); gtk_notebook_set_show_border(station->notebook, FALSE); - gtk_notebook_set_tab_pos(station->notebook, GTK_POS_BOTTOM); gtk_notebook_set_scrollable(station->notebook, TRUE); + /* Définition de la zone de contrôle */ + + hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0); + gtk_widget_set_valign(hbox, GTK_ALIGN_CENTER); + gtk_widget_set_margin_end(hbox, 8); + gtk_widget_show(hbox); + + button = qck_create_toggle_button_with_named_img(G_OBJECT(station), "search", + "edit-find-symbolic", GTK_ICON_SIZE_MENU, NULL, + G_CALLBACK(on_toggle_revealer), station); + gtk_button_set_relief(GTK_BUTTON(button), GTK_RELIEF_NONE); + gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0); + + button = qck_create_button_with_named_img(G_OBJECT(station), "menu", + "go-down-symbolic", GTK_ICON_SIZE_MENU, NULL, + G_CALLBACK(NULL), station); + gtk_button_set_relief(GTK_BUTTON(button), GTK_RELIEF_NONE); + gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0); + + button = qck_create_button_with_named_img(G_OBJECT(station), "close", + "window-close-symbolic", GTK_ICON_SIZE_MENU, NULL, + G_CALLBACK(NULL), station); + gtk_button_set_relief(GTK_BUTTON(button), GTK_RELIEF_NONE); + gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0); + + gtk_notebook_set_action_widget(station->notebook, hbox, GTK_PACK_END); + g_signal_connect(station->notebook, "switch-page", G_CALLBACK(gtk_dock_station_switch_panel), station); @@ -181,7 +220,7 @@ GtkWidget *gtk_dock_station_new(void) * Paramètres : notebook = support à l'origine de la mise à jour. * * page = onglet mis en avant. * * index = indice de l'onglet actuellement actif. * -* data = adresse du conteneur supérieur. * +* station = conteneur de gestion supérieur. * * * * Description : Met à jour le titre du support de panneaux concentrés. * * * @@ -191,17 +230,35 @@ GtkWidget *gtk_dock_station_new(void) * * ******************************************************************************/ -static gboolean gtk_dock_station_switch_panel(GtkNotebook *notebook, gpointer *page, guint index, gpointer data) +static gboolean gtk_dock_station_switch_panel(GtkNotebook *notebook, gpointer *page, guint index, GtkDockStation *station) { GtkWidget *widget; /* Panneau concerné */ - char *str; /* Texte à redonner */ + GtkDockable *dockable; /* Elément encapsulé */ + GtkWidget *button; /* Bouton de contrôle */ widget = gtk_notebook_get_nth_page(notebook, index); - str = g_object_get_data(G_OBJECT(widget), "title"); - gtk_dock_panel_update_title(GTK_DOCK_STATION(data), widget, str); + dockable = GTK_DOCKABLE(g_object_get_data(G_OBJECT(widget), "dockable")); + + /* Mise à jour des boutons utilisables */ - g_signal_emit_by_name(GTK_DOCK_STATION(data), "switch-widget", widget); + button = GTK_WIDGET(g_object_get_data(G_OBJECT(station), "search")); + + if (gtk_dockable_can_search(dockable)) + gtk_widget_show(button); + else + gtk_widget_hide(button); + + button = GTK_WIDGET(g_object_get_data(G_OBJECT(station), "close")); + + if (gtk_dockable_can_be_closed(dockable)) + gtk_widget_show(button); + else + gtk_widget_hide(button); + + /* Remontée du changement d'onglet */ + + g_signal_emit_by_name(station, "switch-widget", widget); return TRUE; @@ -223,12 +280,26 @@ static gboolean gtk_dock_station_switch_panel(GtkNotebook *notebook, gpointer *p * * ******************************************************************************/ -void gtk_dock_panel_add_widget(GtkDockStation *station, GtkWidget *widget, const char *caption, const char *desc) +void gtk_dock_station_add_dockable(GtkDockStation *station, GtkDockable *dockable) { + GtkWidget *widget; /* Composant GTK à intégrer */ + const char *caption; /* Nom à donner à l'onglet */ + const char *desc; /* Description à y associer */ size_t max; /* Taille maximale des titres */ char *str; /* Titre des prochaines fois */ GtkWidget *label; /* Etiquette d'onglet */ + /* Récupération des éléments utiles */ + + widget = gtk_dockable_get_widget(dockable); + + g_object_set_data(G_OBJECT(widget), "dockable", dockable); + + caption = gtk_dockable_get_name(dockable); + desc = gtk_dockable_get_desc(dockable); + + /* Mise en place de la page */ + if (!g_generic_config_get_value(get_main_configuration(), MPK_ELLIPSIS_TAB, &max)) max = -1; @@ -236,28 +307,22 @@ void gtk_dock_panel_add_widget(GtkDockStation *station, GtkWidget *widget, const label = qck_create_label(NULL, NULL, str); free(str); + if (gtk_notebook_get_n_pages(station->notebook) > 0) g_signal_handlers_disconnect_by_func(station->notebook, G_CALLBACK(gtk_dock_station_switch_panel), station); gtk_notebook_insert_page(station->notebook, widget, label, -1); gtk_widget_set_tooltip_text(label, desc); + if (gtk_notebook_get_n_pages(station->notebook) > 1) g_signal_connect(station->notebook, "switch-page", G_CALLBACK(gtk_dock_station_switch_panel), station); - gtk_notebook_set_show_tabs(station->notebook, gtk_notebook_get_n_pages(station->notebook) > 1); - - str = g_object_get_data(G_OBJECT(widget), "title"); - if (str != NULL) free(str); - - if (!g_generic_config_get_value(get_main_configuration(), MPK_ELLIPSIS_HEADER, &max)) - max = -1; - - g_object_set_data(G_OBJECT(widget), "title", ellipsis(strdup(desc), max)); + /* Lancement des mises à jour */ - gtk_dock_panel_update_title(station, widget, desc); + if (gtk_notebook_get_n_pages(station->notebook) > 1) + gtk_notebook_set_current_page(station->notebook, -1); - gtk_notebook_set_current_page(station->notebook, -1); g_signal_emit_by_name(station, "dock-widget", widget); @@ -328,13 +393,17 @@ void gtk_dock_panel_remove_widget(GtkDockStation *station, GtkWidget *widget) gint index; /* Indice de l'onglet visé */ gint count; /* Nombre d'onglets en place */ + + return; + + index = gtk_notebook_page_num(station->notebook, widget); gtk_notebook_remove_page(station->notebook, index); count = gtk_notebook_get_n_pages(station->notebook); - gtk_notebook_set_show_tabs(station->notebook, count > 1); + //gtk_notebook_set_show_tabs(station->notebook, count > 1); if (count == 0) gtk_container_remove(GTK_CONTAINER(gtk_widget_get_parent(GTK_WIDGET(station))), @@ -345,50 +414,48 @@ void gtk_dock_panel_remove_widget(GtkDockStation *station, GtkWidget *widget) /****************************************************************************** * * -* Paramètres : station = plateforme GTK à compléter. * -* widget = nouvel élément à intégrer. * -* caption = intitulé court à afficher sur les onglets. * +* Paramètres : station = plateforme GTK à consulter. * +* index = indice de l'onglet visé. * * * -* Description : Met à jour, si besoin est, le titre de l'affichage concentré.* +* Description : Renvoie un composant intégré dans l'affichage centralisé. * * * -* Retour : - * +* Retour : Composant associé à l'indice donné. * * * * Remarques : - * * * ******************************************************************************/ -void gtk_dock_panel_update_title(GtkDockStation *station, GtkWidget *widget, const char *caption) +GtkWidget *gtk_dock_panel_get_widget(GtkDockStation *station, gint index) { - char *str; /* Valeur finale reconstituée */ - - str = calloc(strlen("<b>") + strlen(caption) + strlen("</b>") + 1, sizeof(char)); - - strcpy(str, "<b>"); - strcat(str, caption); - strcat(str, "</b>"); - - gtk_label_set_markup(station->title, str); - - free(str); + return gtk_notebook_get_nth_page(station->notebook, index); } /****************************************************************************** * * -* Paramètres : station = plateforme GTK à consulter. * -* index = indice de l'onglet visé. * +* Paramètres : button = bouton à l'origine de la procédure. * +* station = station d'accueil pour différents composants. * * * -* Description : Renvoie un composant intégré dans l'affichage centralisé. * +* Description : Révèle ou cache la zone de recherches. * * * -* Retour : Composant associé à l'indice donné. * +* Retour : - * * * * Remarques : - * * * ******************************************************************************/ -GtkWidget *gtk_dock_panel_get_widget(GtkDockStation *station, gint index) +static void on_toggle_revealer(GtkToggleButton *button, GtkDockStation *station) { - return gtk_notebook_get_nth_page(station->notebook, index); + gint index; /* Indice de l'onglet courant */ + GtkWidget *widget; /* Panneau concerné */ + GtkDockable *dockable; /* Elément encapsulé */ + + index = gtk_notebook_get_current_page(station->notebook); + widget = gtk_notebook_get_nth_page(station->notebook, index); + + dockable = GTK_DOCKABLE(g_object_get_data(G_OBJECT(widget), "dockable")); + + gtk_dockable_toggle_revealer(dockable, widget, gtk_toggle_button_get_active(button)); } diff --git a/src/gtkext/gtkdockstation.h b/src/gtkext/gtkdockstation.h index 7cc2263..d64a0b8 100644 --- a/src/gtkext/gtkdockstation.h +++ b/src/gtkext/gtkdockstation.h @@ -28,6 +28,10 @@ #include <gtk/gtk.h> +#include "gtkdockable.h" + + + //G_BEGIN_DECLS @@ -76,7 +80,7 @@ GType gtk_dock_station_get_type(void); GtkWidget *gtk_dock_station_new(void); /* Ajoute un paquet d'informations à l'affichage centralisé. */ -void gtk_dock_panel_add_widget(GtkDockStation *, GtkWidget *, const char *, const char *); +void gtk_dock_station_add_dockable(GtkDockStation *, GtkDockable *); /* Change le contenu de l'onglet courant uniquement. */ void gtk_dock_panel_change_active_widget(GtkDockStation *, GtkWidget *); @@ -84,9 +88,6 @@ void gtk_dock_panel_change_active_widget(GtkDockStation *, GtkWidget *); /* Retire un paquet d'informations de l'affichage centralisé. */ void gtk_dock_panel_remove_widget(GtkDockStation *, GtkWidget *); -/* Met à jour, si besoin est, le titre de l'affichage concentré. */ -void gtk_dock_panel_update_title(GtkDockStation *, GtkWidget *, const char *); - /* Renvoie un composant intégré dans l'affichage centralisé. */ GtkWidget *gtk_dock_panel_get_widget(GtkDockStation *, gint); |