/* Chrysalide - Outil d'analyse de fichiers binaires * window.c - construction d'une fenêtre graphique principale * * Copyright (C) 2024 Cyrille Bagard * * This file is part of Chrysalide. * * Chrysalide is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * Chrysalide is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "window.h" #include "window-int.h" #include "core/panels.h" #include "dialogs/about.h" #include "panels/welcome.h" #include "../gtkext/helpers.h" #include "../gtkext/statusstack.h" /* Initialise la classe des applications majeures de Chrysalide. */ static void gtk_framework_window_class_init(GtkFrameworkWindowClass *); /* Initialise une application principale pour Chrysalide. */ static void gtk_framework_window_init(GtkFrameworkWindow *); /* Supprime toutes les références externes. */ static void gtk_framework_window_dispose(GtkFrameworkWindow *); /* Procède à la libération totale de la mémoire. */ static void gtk_framework_window_finalize(GtkFrameworkWindow *); /* Réagit à une activation du menu "A propos de" de la fenetre. */ static void gtk_framework_window_activate_about(GSimpleAction *, GVariant *, gpointer); /* Indique le type défini pour une fenêtre graphique principale de Chrysalide. */ G_DEFINE_TYPE(GtkFrameworkWindow, gtk_framework_window, GTK_TYPE_APPLICATION_WINDOW); /****************************************************************************** * * * Paramètres : class = classe à initialiser. * * * * Description : Initialise la classe des applications majeures de Chrysalide.* * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ static void gtk_framework_window_class_init(GtkFrameworkWindowClass *class) { GObjectClass *object; /* Plus haut niveau équivalent */ GtkWidgetClass *widget; /* Classe de haut niveau */ object = G_OBJECT_CLASS(class); object->dispose = (GObjectFinalizeFunc/* ! */)gtk_framework_window_dispose; object->finalize = (GObjectFinalizeFunc)gtk_framework_window_finalize; widget = GTK_WIDGET_CLASS(class); g_type_ensure(GTK_TYPE_STATUS_STACK); gtk_widget_class_set_template_from_resource(widget, "/re/chrysalide/framework/gui/window.ui"); gtk_widget_class_bind_template_child(widget, GtkFrameworkWindow, grid); /* Active une action native (cf. https://docs.gtk.org/gtk4/class.Window.html#actions) */ gtk_widget_class_add_binding_action(widget, GDK_KEY_Q, GDK_CONTROL_MASK, "window.close", NULL); } /****************************************************************************** * * * Paramètres : window = instance à initialiser. * * * * Description : Initialise une application principale pour Chrysalide. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ static void gtk_framework_window_init(GtkFrameworkWindow *window) { static GActionEntry app_entries[] = { { "about", gtk_framework_window_activate_about, NULL, NULL, NULL }, }; gtk_widget_init_template(GTK_WIDGET(window)); window->settings = g_settings_new(FRAMEWORK_WINDOW_ID); g_settings_bind(window->settings, "window-width", G_OBJECT(window), "default-width", G_SETTINGS_BIND_DEFAULT); g_settings_bind(window->settings, "window-height", G_OBJECT(window), "default-height", G_SETTINGS_BIND_DEFAULT); g_settings_bind(window->settings, "window-maximized", G_OBJECT(window), "maximized", G_SETTINGS_BIND_DEFAULT); g_action_map_add_action_entries(G_ACTION_MAP(window), app_entries, G_N_ELEMENTS(app_entries), window); } /****************************************************************************** * * * Paramètres : window = instance d'objet GLib à traiter. * * * * Description : Supprime toutes les références externes. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ static void gtk_framework_window_dispose(GtkFrameworkWindow *window) { gtk_widget_dispose_template(GTK_WIDGET(window), GTK_TYPE_FRAMEWORK_WINDOW); g_clear_object(&window->settings); G_OBJECT_CLASS(gtk_framework_window_parent_class)->dispose(G_OBJECT(window)); } /****************************************************************************** * * * Paramètres : window = instance d'objet GLib à traiter. * * * * Description : Procède à la libération totale de la mémoire. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ static void gtk_framework_window_finalize(GtkFrameworkWindow *window) { G_OBJECT_CLASS(gtk_framework_window_parent_class)->finalize(G_OBJECT(window)); } /****************************************************************************** * * * Paramètres : app = application GTK de rattachement. * * * * Description : Crée une nouvelle application principale pour Chrysalide. * * * * Retour : Mécanismes mis en place. * * * * Remarques : - * * * ******************************************************************************/ GtkApplicationWindow *gtk_framework_window_new(GtkApplication *app) { GtkApplicationWindow *result; /* Instance à retourner */ result = g_object_new(GTK_TYPE_FRAMEWORK_WINDOW, NULL); if (!gtk_framework_window_create(GTK_FRAMEWORK_WINDOW(result), app)) g_clear_object(&result); return result; } /****************************************************************************** * * * Paramètres : window = instance de fenêtre principale à remplir. * * app = application GTK de rattachement. * * * * Description : Met en place une fenêtre principale pour Chrysalide. * * * * Retour : Bilan de l'opération. * * * * Remarques : - * * * ******************************************************************************/ bool gtk_framework_window_create(GtkFrameworkWindow *window, GtkApplication *app) { bool result; /* Bilan à retourner */ GPanelItem *item; /* Définition de panneau */ GtkTiledPanel *panel; /* Panneau d'affichage */ GtkCssProvider *css; /* Feuille de style maison */ result = true; gtk_window_set_application(GTK_WINDOW(window), app); /* Inclusion d'un écran d'accueil */ item = find_item_panel_by_type(G_TYPE_WELCOME_PANEL); panel = g_panel_item_get_panel(item); gtk_framework_window_add(window, panel); unref_object(item); /* Chargement des extensions de thème */ css = gtk_css_provider_new(); gtk_css_provider_load_from_resource(css, "/re/chrysalide/framework/gtkext/hexview.css"); gtk_style_context_add_provider_for_display(gtk_widget_get_display(GTK_WIDGET(window)), GTK_STYLE_PROVIDER(css), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION); unref_object(css); css = gtk_css_provider_new(); gtk_css_provider_load_from_resource(css, "/re/chrysalide/framework/gui/style.css"); gtk_style_context_add_provider_for_display(gtk_widget_get_display(GTK_WIDGET(window)), GTK_STYLE_PROVIDER(css), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION); unref_object(css); /* Fin des chargements */ return result; } /****************************************************************************** * * * Paramètres : action = désignation de l'action concernée par l'appel. * * unused = adresse non utilisée ici. * * _window = instance de fenêtre principale à manipuler. * * * * Description : Réagit à une activation du menu "A propos de" de la fenetre. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ static void gtk_framework_window_activate_about(GSimpleAction *action, GVariant *unused, gpointer _window) { GtkFrameworkWindow *window; /* Fenêtre principale associée */ GtkWindow *dialog; /* Boîte de dialogue à afficher*/ window = _window; dialog = gtk_app_about_dialog_new(GTK_WINDOW(window)); gtk_window_present(dialog); } /****************************************************************************** * * * Paramètres : window = instance de fenêtre principale à remplir. * * panel = nouveau panneau à afficher. * * * * Description : Ajoute un panneau à la fenêtre principale de Chrysalide. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ void gtk_framework_window_add(GtkFrameworkWindow *window, /* __steal */GtkTiledPanel *panel) { GtkWidget *bar; /* Barre de titre */ GListStore *list; /* Liste éventuelle à intégrer */ guint count; /* Nombre d'élements présents */ guint i; /* Boucle de parcours */ GtkWidget *widget; /* Composant à intégrer */ gtk_stack_add_child(window->grid, GTK_WIDGET(panel)); gtk_stack_set_visible_child(window->grid, GTK_WIDGET(panel)); bar = gtk_window_get_titlebar(GTK_WINDOW(window)); if (bar == NULL) ////////// REMME { bar = gtk_header_bar_new(); gtk_window_set_titlebar(GTK_WINDOW(window), bar); } ///////////////////////////// list = gtk_tiled_panel_get_title_widgets(panel, false); if (list != NULL) { count = g_list_model_get_n_items(G_LIST_MODEL(list)); for (i = 0; i < count; i++) { widget = GTK_WIDGET(g_list_model_get_item(G_LIST_MODEL(list), i)); gtk_header_bar_pack_end(GTK_HEADER_BAR(bar), widget); } unref_object(list); } }