summaryrefslogtreecommitdiff
path: root/src/gtkext
diff options
context:
space:
mode:
Diffstat (limited to 'src/gtkext')
-rw-r--r--src/gtkext/Makefile.am18
-rw-r--r--src/gtkext/bufferview.c6
-rw-r--r--src/gtkext/gresource.xml7
-rw-r--r--src/gtkext/hexview.c6
-rw-r--r--src/gtkext/launcher-int.h56
-rw-r--r--src/gtkext/launcher.c211
-rw-r--r--src/gtkext/launcher.h45
-rw-r--r--src/gtkext/launcher.ui76
-rw-r--r--src/gtkext/statusstack-int.h4
-rw-r--r--src/gtkext/statusstack.c56
-rw-r--r--src/gtkext/statusstack.ui15
-rw-r--r--src/gtkext/tweak-int.h65
-rw-r--r--src/gtkext/tweak.c319
-rw-r--r--src/gtkext/tweak.h90
-rw-r--r--src/gtkext/tweak.ui46
15 files changed, 1011 insertions, 9 deletions
diff --git a/src/gtkext/Makefile.am b/src/gtkext/Makefile.am
index 2a2738a..839ee8f 100644
--- a/src/gtkext/Makefile.am
+++ b/src/gtkext/Makefile.am
@@ -26,10 +26,17 @@ libgtkext_la_LIBADD = \
libgtkext_la_CFLAGS = $(LIBGTK_CFLAGS) $(LIBXML_CFLAGS)
+IMG_PATH = ../../data/images
+
RES_FILES = \
hexview.css \
hexview.ui \
- statusstack.ui
+ launcher.ui \
+ statusstack.ui \
+ $(IMG_PATH)/nolock-symbolic.svg \
+ $(IMG_PATH)/locked-symbolic.svg \
+ $(IMG_PATH)/unlocked-symbolic.svg \
+ tweak.ui
libgtkext4_la_SOURCES = \
area-int.h \
@@ -45,17 +52,22 @@ libgtkext4_la_SOURCES = \
helpers.h \
hexview-int.h \
hexview.h hexview.c \
+ launcher-int.h \
+ launcher.h launcher.c \
panel-int.h \
panel.h panel.c \
resources.h resources.c \
- statusstack.h statusstack.c
+ statusstack-int.h \
+ statusstack.h statusstack.c \
+ tweak-int.h \
+ tweak.h tweak.c
libgtkext4_la_CFLAGS = $(LIBGTK4_CFLAGS)
devdir = $(includedir)/chrysalide/$(subdir:src/%=core/%)
-dev_HEADERS = $(libgtkext_la_SOURCES:%c=)
+dev_HEADERS = $(libgtkext4_la_SOURCES:%c=)
#SUBDIRS = graph
diff --git a/src/gtkext/bufferview.c b/src/gtkext/bufferview.c
index 6b8f17c..13c2632 100644
--- a/src/gtkext/bufferview.c
+++ b/src/gtkext/bufferview.c
@@ -279,9 +279,9 @@ GBufferView *gtk_buffer_view_get_view(const GtkBufferView *view)
/******************************************************************************
* *
-* Paramètres : widget = composant GTK à examiner. *
-* width = largeur affectée au composant graphique. *
-* height = hauteur affectée au composant graphique. *
+* Paramètres : widget = composant GTK à examiner. *
+* width = largeur affectée au composant graphique. *
+* height = hauteur affectée au composant graphique. *
* baseline = ligne de base affectée au composant graphique. *
* *
* Description : Prend acte de la taille allouée au composant d'affichage. *
diff --git a/src/gtkext/gresource.xml b/src/gtkext/gresource.xml
index 3bfd8c5..640985f 100644
--- a/src/gtkext/gresource.xml
+++ b/src/gtkext/gresource.xml
@@ -3,6 +3,13 @@
<gresource prefix="/re/chrysalide/framework/gtkext">
<file compressed="true">hexview.css</file>
<file compressed="true">hexview.ui</file>
+ <file compressed="true">launcher.ui</file>
<file compressed="true">statusstack.ui</file>
+ <file compressed="true">tweak.ui</file>
+ </gresource>
+ <gresource prefix="/re/chrysalide/framework/gui/icons/scalable/actions">
+ <file compressed="true" alias="nolock-symbolic.svg">../../data/images/nolock-symbolic.svg</file>
+ <file compressed="true" alias="locked-symbolic.svg">../../data/images/locked-symbolic.svg</file>
+ <file compressed="true" alias="unlocked-symbolic.svg">../../data/images/unlocked-symbolic.svg</file>
</gresource>
</gresources>
diff --git a/src/gtkext/hexview.c b/src/gtkext/hexview.c
index 6df1140..5a8dd04 100644
--- a/src/gtkext/hexview.c
+++ b/src/gtkext/hexview.c
@@ -438,9 +438,9 @@ void demo_snapshot (GtkWidget *widget, GtkSnapshot *snapshot, GtkWidget *parent)
/******************************************************************************
* *
-* Paramètres : widget = composant GTK à examiner. *
-* width = largeur affectée au composant graphique. *
-* height = hauteur affectée au composant graphique. *
+* Paramètres : widget = composant GTK à examiner. *
+* width = largeur affectée au composant graphique. *
+* height = hauteur affectée au composant graphique. *
* baseline = ligne de base affectée au composant graphique. *
* *
* Description : Prend acte de la taille allouée au composant d'affichage. *
diff --git a/src/gtkext/launcher-int.h b/src/gtkext/launcher-int.h
new file mode 100644
index 0000000..07152f0
--- /dev/null
+++ b/src/gtkext/launcher-int.h
@@ -0,0 +1,56 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * tweak-int.h - définitions internes pour un lanceur de panneau majeur
+ *
+ * Copyright (C) 2025 Cyrille Bagard
+ *
+ * This file is part of Chrysalide.
+ *
+ * Chrysalide is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Chrysalide is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Chrysalide. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef _GTKEXT_LAUNCHER_INT_H
+#define _GTKEXT_LAUNCHER_INT_H
+
+
+#include "launcher.h"
+
+
+
+/* Elément de lancement d'un panneau majeur pour l'interface (instance) */
+struct _GtkPanelLauncher
+{
+ GtkListBoxRow parent; /* A laisser en premier */
+
+ GtkImage *icon; /* Eventuelle image */
+ GtkLabel *title; /* Etiquette associée */
+ GtkLabel *desc; /* Description du panneau */
+
+};
+
+/* Elément de lancement d'un panneau majeur pour l'interface (classe) */
+struct _GtkPanelLauncherClass
+{
+ GtkListBoxRowClass parent; /* A laisser en premier */
+
+};
+
+
+/* Met en place un nouveau lanceur de panneau majeur. */
+bool gtk_panel_launcher_create(GtkPanelLauncher *, const char *, const char *, const char *);
+
+
+
+#endif /* _GTKEXT_LAUNCHER_INT_H */
diff --git a/src/gtkext/launcher.c b/src/gtkext/launcher.c
new file mode 100644
index 0000000..5bb850b
--- /dev/null
+++ b/src/gtkext/launcher.c
@@ -0,0 +1,211 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * launcher.c - lanceur de panneau majeur
+ *
+ * Copyright (C) 2025 Cyrille Bagard
+ *
+ * This file is part of Chrysalide.
+ *
+ * Chrysalide is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Chrysalide is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Chrysalide. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "launcher.h"
+
+
+#include <malloc.h>
+#include <string.h>
+
+
+#include "helpers.h"
+#include "launcher-int.h"
+#include "../common/extstr.h"
+
+
+
+/* Initialise la classe des sections d'éléments paramétrables. */
+static void gtk_panel_launcher_class_init(GtkPanelLauncherClass *);
+
+/* Initialise une instance de lanceur de panneau majeur. */
+static void gtk_panel_launcher_init(GtkPanelLauncher *);
+
+/* Supprime toutes les références externes. */
+static void gtk_panel_launcher_dispose(GObject *);
+
+/* Procède à la libération totale de la mémoire. */
+static void gtk_panel_launcher_finalize(GObject *);
+
+
+
+/* Détermine le type du composant d'affichage générique. */
+G_DEFINE_TYPE(GtkPanelLauncher, gtk_panel_launcher, GTK_TYPE_LIST_BOX_ROW);
+
+
+/******************************************************************************
+* *
+* Paramètres : class = classe GTK à initialiser. *
+* *
+* Description : Initialise la classe des sections d'éléments paramétrables. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void gtk_panel_launcher_class_init(GtkPanelLauncherClass *class)
+{
+ GObjectClass *object; /* Plus haut niveau équivalent */
+ GtkWidgetClass *widget; /* Classe de haut niveau */
+
+ object = G_OBJECT_CLASS(class);
+
+ object->dispose = gtk_panel_launcher_dispose;
+ object->finalize = gtk_panel_launcher_finalize;
+
+ widget = GTK_WIDGET_CLASS(class);
+
+ gtk_widget_class_set_template_from_resource(widget, "/re/chrysalide/framework/gtkext/launcher.ui");
+
+ gtk_widget_class_bind_template_child(widget, GtkPanelLauncher, icon);
+ gtk_widget_class_bind_template_child(widget, GtkPanelLauncher, title);
+ gtk_widget_class_bind_template_child(widget, GtkPanelLauncher, desc);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : launcher = composant GTK à initialiser. *
+* *
+* Description : Initialise une instance de lanceur de panneau majeur. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void gtk_panel_launcher_init(GtkPanelLauncher *launcher)
+{
+ gtk_widget_init_template(GTK_WIDGET(launcher));
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : object = instance d'objet GLib à traiter. *
+* *
+* Description : Supprime toutes les références externes. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void gtk_panel_launcher_dispose(GObject *object)
+{
+ gtk_widget_dispose_template(GTK_WIDGET(object), GTK_TYPE_PANEL_LAUNCHER);
+
+ G_OBJECT_CLASS(gtk_panel_launcher_parent_class)->dispose(object);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : object = instance d'objet GLib à traiter. *
+* *
+* Description : Procède à la libération totale de la mémoire. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void gtk_panel_launcher_finalize(GObject *object)
+{
+ G_OBJECT_CLASS(gtk_panel_launcher_parent_class)->finalize(object);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : icon = désignation de l'image de représentation. *
+* title = titre principal à afficher. *
+* desc = description du panneau ciblé. *
+* *
+* Description : Crée un nouveau lanceur de panneau majeur. *
+* *
+* Retour : Composant GTK mis en place. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GtkPanelLauncher *gtk_panel_launcher_new(const char *icon, const char *title, const char *desc)
+{
+ GtkPanelLauncher *result; /* Instance à retourner */
+
+ result = g_object_new(GTK_TYPE_PANEL_LAUNCHER, NULL);
+
+ if (!gtk_panel_launcher_create(result, icon, title, desc))
+ g_clear_object(&result);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : launcher = lanceur à initialiser pleinement. *
+* icon = désignation de l'image de représentation. *
+* title = titre principal à afficher. *
+* desc = description du panneau ciblé. *
+* *
+* Description : Met en place un nouveau lanceur de panneau majeur. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool gtk_panel_launcher_create(GtkPanelLauncher *launcher, const char *icon, const char *title, const char *desc)
+{
+ bool result; /* Bilan à retourner */
+ char *bold; /* Titre sublimé */
+
+ result = true;
+
+ gtk_image_set_from_icon_name(launcher->icon, icon);
+
+ bold = strdup(title);
+ bold = strprep(bold, "<b>");
+ bold = stradd(bold, "</b>");
+
+ gtk_label_set_label(launcher->title, bold);
+
+ free(bold);
+
+ gtk_label_set_label(launcher->desc, desc);
+
+ return result;
+
+}
diff --git a/src/gtkext/launcher.h b/src/gtkext/launcher.h
new file mode 100644
index 0000000..3857216
--- /dev/null
+++ b/src/gtkext/launcher.h
@@ -0,0 +1,45 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * launcher.h - prototypes pour pour un lanceur de panneau majeur
+ *
+ * Copyright (C) 2025 Cyrille Bagard
+ *
+ * This file is part of Chrysalide.
+ *
+ * Chrysalide is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Chrysalide is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Chrysalide. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef _GTKEXT_LAUNCHER_H
+#define _GTKEXT_LAUNCHER_H
+
+
+#include <gtk/gtk.h>
+
+
+#include "../glibext/helpers.h"
+
+
+
+#define GTK_TYPE_PANEL_LAUNCHER (gtk_panel_launcher_get_type())
+
+DECLARE_GTYPE(GtkPanelLauncher, gtk_panel_launcher, GTK, PANEL_LAUNCHER);
+
+
+/* Crée un nouveau lanceur de panneau majeur. */
+GtkPanelLauncher *gtk_panel_launcher_new(const char *, const char *, const char *);
+
+
+
+#endif /* _GTKEXT_LAUNCHER_H */
diff --git a/src/gtkext/launcher.ui b/src/gtkext/launcher.ui
new file mode 100644
index 0000000..f6f4fec
--- /dev/null
+++ b/src/gtkext/launcher.ui
@@ -0,0 +1,76 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+ <template class="GtkPanelLauncher" parent="GtkListBoxRow">
+
+ <property name="child">
+
+ <object class="GtkGrid">
+ <property name="margin-bottom">12</property>
+ <property name="margin-end">12</property>
+ <property name="margin-start">12</property>
+ <property name="margin-top">12</property>
+ <property name="column-spacing">12</property>
+
+ <child>
+ <object class="GtkImage" id="icon">
+ <property name="icon-name"></property>
+ <property name="pixel-size">48</property>
+ <layout>
+ <property name="column">0</property>
+ <property name="row">0</property>
+ <property name="row-span">2</property>
+ </layout>
+ <style>
+ <class name="icon-dropshadow"/>
+ </style>
+ </object>
+ </child>
+
+ <child>
+ <object class="GtkLabel" id="title">
+ <property name="label"></property>
+ <property name="use-markup">TRUE</property>
+ <property name="xalign">0</property>
+ <layout>
+ <property name="column">1</property>
+ <property name="row">0</property>
+ </layout>
+ </object>
+ </child>
+
+ <child>
+ <object class="GtkLabel" id="desc">
+ <property name="label"></property>
+ <property name="hexpand">true</property>
+ <property name="xalign">0</property>
+ <layout>
+ <property name="column">1</property>
+ <property name="row">1</property>
+ </layout>
+ <style>
+ <class name="dim-label"/>
+ </style>
+ </object>
+ </child>
+
+ <child>
+ <object class="GtkImage">
+ <property name="icon-name">go-next-symbolic</property>
+ <property name="margin-start">12</property>
+ <layout>
+ <property name="column">2</property>
+ <property name="row">0</property>
+ <property name="row-span">2</property>
+ </layout>
+ <style>
+ <class name="icon-dropshadow"/>
+ </style>
+ </object>
+ </child>
+
+ </object>
+
+ </property>
+
+ </template>
+</interface>
diff --git a/src/gtkext/statusstack-int.h b/src/gtkext/statusstack-int.h
index facc5af..2a9e99e 100644
--- a/src/gtkext/statusstack-int.h
+++ b/src/gtkext/statusstack-int.h
@@ -26,6 +26,7 @@
#include "statusstack.h"
+#include "../glibext/secstorage.h"
@@ -70,6 +71,9 @@ struct _GtkStatusStack
/* Tronc commun */
+ GSecretStorage *storage; /* Stockage des secrets */
+ GtkToggleButton *lock_update; /* Activation des accès */
+
GtkLabel *net_recv_speed; /* Débit en réception */
GtkLabel *net_send_speed; /* Débit en émission */
diff --git a/src/gtkext/statusstack.c b/src/gtkext/statusstack.c
index 0d8ef62..76dbee8 100644
--- a/src/gtkext/statusstack.c
+++ b/src/gtkext/statusstack.c
@@ -53,6 +53,9 @@ static void gtk_status_stack_dispose(GtkStatusStack *);
/* Procède à la libération totale de la mémoire. */
static void gtk_status_stack_finalize(GtkStatusStack *);
+/* Note le changement de verrouillage du stockage sécurisé. */
+static void gtk_status_stack_on_secret_storage_lock_update(GSecretStorage *, GtkStatusStack *);
+
/* Met à jour dans la barre les débits réseau observés. */
static gboolean gtk_status_stack_update_network_stats(GtkStatusStack *);
@@ -190,6 +193,8 @@ static void gtk_status_stack_class_init(GtkStatusStackClass *class)
gtk_widget_class_bind_template_child(widget, GtkStatusStack, activity_message);
gtk_widget_class_bind_template_child(widget, GtkStatusStack, activity_progress);
+ gtk_widget_class_bind_template_child(widget, GtkStatusStack, lock_update);
+
gtk_widget_class_bind_template_child(widget, GtkStatusStack, net_recv_speed);
gtk_widget_class_bind_template_child(widget, GtkStatusStack, net_send_speed);
@@ -220,6 +225,17 @@ static void gtk_status_stack_init(GtkStatusStack *stack)
stack->activity_info = calloc(1, sizeof(activity_info_t));
init_activity_info(stack->activity_info);
+ /* Suivi des évolutions relatives au stockage sécurisé */
+
+ stack->storage = get_secret_storage();
+
+ g_signal_connect(stack->storage, "lock-update",
+ G_CALLBACK(gtk_status_stack_on_secret_storage_lock_update), stack);
+
+ gtk_status_stack_on_secret_storage_lock_update(stack->storage, stack);
+
+ /* Suivi des débits de connexion */
+
stack->next_index = 0;
stack->network_update_tag = g_timeout_add(NETWORK_UPDATE_INTERVAL,
@@ -242,6 +258,12 @@ static void gtk_status_stack_init(GtkStatusStack *stack)
static void gtk_status_stack_dispose(GtkStatusStack *stack)
{
+ if (stack->storage != NULL)
+ g_signal_handlers_disconnect_by_func(stack->storage,
+ gtk_status_stack_on_secret_storage_lock_update, stack);
+
+ g_clear_object(&stack->storage);
+
g_source_remove(stack->network_update_tag);
gtk_widget_dispose_template(GTK_WIDGET(stack), GTK_TYPE_STATUS_STACK);
@@ -322,6 +344,40 @@ void gtk_status_stack_reset(GtkStatusStack *stack)
/******************************************************************************
* *
+* Paramètres : storage = gardien des secrets impliqué. *
+* stack = barre de statut à actualiser. *
+* *
+* Description : Note le changement de verrouillage du stockage sécurisé. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void gtk_status_stack_on_secret_storage_lock_update(GSecretStorage *storage, GtkStatusStack *stack)
+{
+ if (!g_secret_storage_has_key(stack->storage))
+ {
+ gtk_widget_set_sensitive(GTK_WIDGET(stack->lock_update), false);
+ gtk_button_set_icon_name(GTK_BUTTON(stack->lock_update), "nolock-symbolic");
+ }
+ else
+ {
+ gtk_widget_set_sensitive(GTK_WIDGET(stack->lock_update), true);
+
+ if (g_secret_storage_is_locked(stack->storage))
+ gtk_button_set_icon_name(GTK_BUTTON(stack->lock_update), "locked-symbolic");
+ else
+ gtk_button_set_icon_name(GTK_BUTTON(stack->lock_update), "unlocked-symbolic");
+
+ }
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : stack = barre de statut à actualiser. *
* *
* Description : Met à jour dans la barre les débits réseau observés. *
diff --git a/src/gtkext/statusstack.ui b/src/gtkext/statusstack.ui
index 422f95d..8469e6e 100644
--- a/src/gtkext/statusstack.ui
+++ b/src/gtkext/statusstack.ui
@@ -1,3 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
<interface>
<template class="GtkStatusStack" parent="GtkBox">
@@ -148,6 +149,20 @@
</child>
<child>
+ <object class="GtkToggleButton" id="lock_update">
+ <property name="sensitive">false</property>
+ <property name="has-frame">false</property>
+ <property name="icon-name">nolock-symbolic</property>
+ </object>
+ </child>
+
+ <child>
+ <object class="GtkSeparator">
+ <property name="orientation">vertical</property>
+ </object>
+ </child>
+
+ <child>
<object class="GtkImage">
<property name="margin-start">8</property>
<property name="icon-name">pan-down-symbolic</property>
diff --git a/src/gtkext/tweak-int.h b/src/gtkext/tweak-int.h
new file mode 100644
index 0000000..0d2c213
--- /dev/null
+++ b/src/gtkext/tweak-int.h
@@ -0,0 +1,65 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * tweak-int.h - définitions internes pour une section d'éléments à paramétrer
+ *
+ * Copyright (C) 2025 Cyrille Bagard
+ *
+ * This file is part of Chrysalide.
+ *
+ * Chrysalide is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Chrysalide is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Chrysalide. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef _GTKEXT_TWEAK_INT_H
+#define _GTKEXT_TWEAK_INT_H
+
+
+#include "tweak.h"
+
+
+
+/* Section de paramétrage pour liste d'éléments à configurer (instance) */
+struct _GtkTweakSection
+{
+ GtkListBoxRow parent; /* A laisser en premier */
+
+ GtkImage *icon; /* Eventuelle image */
+ GtkLabel *label; /* Etiquette associée */
+ GtkWidget *next; /* Eventuelle progression */
+
+ char *category; /* Groupe de rassemblement */
+
+ union
+ {
+ GType panel; /* Accès à la page de config. */
+ char *sub; /* Sous-ensemble à presenter */
+ };
+ bool has_sub_section; /* Choix du champ valide */
+
+};
+
+/* Section de paramétrage pour liste d'éléments à configurer (classe) */
+struct _GtkTweakSectionClass
+{
+ GtkListBoxRowClass parent; /* A laisser en premier */
+
+};
+
+
+/* Met en place une nouvelle section de configuration. */
+bool gtk_tweak_section_create(GtkTweakSection *, const tweak_info_t *);
+
+
+
+#endif /* _GTKEXT_TWEAK_INT_H */
diff --git a/src/gtkext/tweak.c b/src/gtkext/tweak.c
new file mode 100644
index 0000000..b03cf17
--- /dev/null
+++ b/src/gtkext/tweak.c
@@ -0,0 +1,319 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * tweak.c - section d'éléments à paramétrer
+ *
+ * Copyright (C) 2025 Cyrille Bagard
+ *
+ * This file is part of Chrysalide.
+ *
+ * Chrysalide is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Chrysalide is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Chrysalide. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "tweak.h"
+
+
+#include <assert.h>
+#include <malloc.h>
+#include <string.h>
+
+
+#include "helpers.h"
+#include "tweak-int.h"
+
+
+
+/* Initialise la classe des sections d'éléments paramétrables. */
+static void gtk_tweak_section_class_init(GtkTweakSectionClass *);
+
+/* Initialise une instance de section d'éléments paramétrables. */
+static void gtk_tweak_section_init(GtkTweakSection *);
+
+/* Supprime toutes les références externes. */
+static void gtk_tweak_section_dispose(GtkTweakSection *);
+
+/* Procède à la libération totale de la mémoire. */
+static void gtk_tweak_section_finalize(GtkTweakSection *);
+
+
+
+/* Détermine le type du composant d'affichage générique. */
+G_DEFINE_TYPE(GtkTweakSection, gtk_tweak_section, GTK_TYPE_LIST_BOX_ROW);
+
+
+/******************************************************************************
+* *
+* Paramètres : class = classe GTK à initialiser. *
+* *
+* Description : Initialise la classe des sections d'éléments paramétrables. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void gtk_tweak_section_class_init(GtkTweakSectionClass *class)
+{
+ GObjectClass *object; /* Plus haut niveau équivalent */
+ GtkWidgetClass *widget; /* Classe de haut niveau */
+
+ object = G_OBJECT_CLASS(class);
+
+ object->dispose = (GObjectFinalizeFunc/* ! */)gtk_tweak_section_dispose;
+ object->finalize = (GObjectFinalizeFunc)gtk_tweak_section_finalize;
+
+ widget = GTK_WIDGET_CLASS(class);
+
+ gtk_widget_class_set_template_from_resource(widget, "/re/chrysalide/framework/gtkext/tweak.ui");
+
+ gtk_widget_class_bind_template_child(widget, GtkTweakSection, icon);
+ gtk_widget_class_bind_template_child(widget, GtkTweakSection, label);
+ gtk_widget_class_bind_template_child(widget, GtkTweakSection, next);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : section = composant GTK à initialiser. *
+* *
+* Description : Initialise une instance de section d'éléments paramétrables. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void gtk_tweak_section_init(GtkTweakSection *section)
+{
+ gtk_widget_init_template(GTK_WIDGET(section));
+
+ section->category = NULL;
+
+ section->sub = NULL;
+ section->has_sub_section = true;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : section = instance d'objet GLib à traiter. *
+* *
+* Description : Supprime toutes les références externes. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void gtk_tweak_section_dispose(GtkTweakSection *section)
+{
+ gtk_widget_dispose_template(GTK_WIDGET(section), GTK_TYPE_TWEAK_SECTION);
+
+ G_OBJECT_CLASS(gtk_tweak_section_parent_class)->dispose(G_OBJECT(section));
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : section = instance d'objet GLib à traiter. *
+* *
+* Description : Procède à la libération totale de la mémoire. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void gtk_tweak_section_finalize(GtkTweakSection *section)
+{
+ if (section->category != NULL)
+ free(section->category);
+
+ if (section->has_sub_section && section->sub != NULL)
+ free(section->sub);
+
+ G_OBJECT_CLASS(gtk_tweak_section_parent_class)->finalize(G_OBJECT(section));
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : info = informations associées à la section. *
+* *
+* Description : Crée une nouvelle section de configuration. *
+* *
+* Retour : Composant GTK mis en place. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GtkTweakSection *gtk_tweak_section_new(const tweak_info_t *info)
+{
+ GtkTweakSection *result; /* Instance à retourner */
+
+ result = g_object_new(GTK_TYPE_TWEAK_SECTION, NULL);
+
+ if (!gtk_tweak_section_create(result, info))
+ g_clear_object(&result);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : section = section à initialiser pleinement. *
+* info = informations associées à la section. *
+* *
+* Description : Met en place une nouvelle section de configuration. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool gtk_tweak_section_create(GtkTweakSection *section, const tweak_info_t *info)
+{
+ bool result; /* Bilan à retourner */
+
+ result = true;
+
+ gtk_image_set_from_icon_name(section->icon, info->image);
+ gtk_label_set_label(section->label, info->label);
+
+ gtk_widget_set_visible(section->next, info->has_sub_section);
+
+ section->category = strdup(info->category);
+
+ if (info->has_sub_section)
+ {
+ section->sub = strdup(info->sub);
+ section->has_sub_section = true;
+ }
+ else
+ {
+ section->panel = info->panel;
+ section->has_sub_section = false;
+ }
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : section = section à consulter. *
+* *
+* Description : Fournit l'étiquette associée à une section de configuration. *
+* *
+* Retour : Désignation humaine de la section. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+const char *gtk_tweak_section_get_label(const GtkTweakSection *section)
+{
+ const char *result; /* Texte à retourner */
+
+ result = gtk_label_get_text(section->label);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : section = section à consulter. *
+* *
+* Description : Indique si la section renvoie vers une sous-section. *
+* *
+* Retour : Bilan de la consultation. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool gtk_tweak_section_has_sub_section(const GtkTweakSection *section)
+{
+ bool result; /* Statut à retourner */
+
+ result = section->has_sub_section;
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : section = section à consulter. *
+* *
+* Description : Fournit le type d'un éventuel panneau de configuration lié. *
+* *
+* Retour : Bilan de la consultation. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GType gtk_tweak_section_get_panel(const GtkTweakSection *section)
+{
+ GType result; /* Type d'objet à retourner */
+
+ assert(!section->has_sub_section);
+
+ result = section->panel;
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : section = section à consulter. *
+* *
+* Description : Fournit la désignation d'une éventuelle sous-section liée. *
+* *
+* Retour : Désignation associée à la sous-section. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+const char *gtk_tweak_section_get_sub_section(const GtkTweakSection *section)
+{
+ const char *result; /* Désignation à renvoyer */
+
+ assert(section->has_sub_section);
+
+ result = section->sub;
+
+ return result;
+
+}
diff --git a/src/gtkext/tweak.h b/src/gtkext/tweak.h
new file mode 100644
index 0000000..8c44844
--- /dev/null
+++ b/src/gtkext/tweak.h
@@ -0,0 +1,90 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * tweak.h - prototypes pour pour une section d'éléments à paramétrer
+ *
+ * Copyright (C) 2025 Cyrille Bagard
+ *
+ * This file is part of Chrysalide.
+ *
+ * Chrysalide is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Chrysalide is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Chrysalide. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef _GTKEXT_TWEAK_H
+#define _GTKEXT_TWEAK_H
+
+
+#include <stdbool.h>
+#include <gtk/gtk.h>
+
+
+#include "../glibext/helpers.h"
+
+
+
+/* Définition d'une section de configuration */
+typedef struct _tweak_info_t
+{
+ const char *parent; /* Ensemble d'appartenance */
+
+ const char *category; /* Groupe de rassemblement */
+
+ const char *image; /* Eventuelle image associée */
+ const char *key; /* Désignation de la section */
+ const char *label; /* Désignation humaine */
+
+ union
+ {
+ GType panel; /* Accès à la page de config. */
+ const char *sub; /* Sous-ensemble à presenter */
+ };
+ bool has_sub_section; /* Choix du champ valide */
+
+} tweak_info_t;
+
+
+#define TWEAK_SIMPLE_DEF(p, c, i, k, l, t) \
+ { \
+ .parent = p, \
+ .category = c, \
+ .image = i, \
+ .key = k, \
+ .label = l, \
+ .panel = t, \
+ .has_sub_section = false, \
+ }
+
+#define GTK_TYPE_TWEAK_SECTION (gtk_tweak_section_get_type())
+
+DECLARE_GTYPE(GtkTweakSection, gtk_tweak_section, GTK, TWEAK_SECTION);
+
+
+/* Crée une nouvelle section de configuration. */
+GtkTweakSection *gtk_tweak_section_new(const tweak_info_t *);
+
+/* Fournit l'étiquette associée à une section de configuration. */
+const char *gtk_tweak_section_get_label(const GtkTweakSection *);
+
+/* Indique si la section renvoie vers une sous-section. */
+bool gtk_tweak_section_has_sub_section(const GtkTweakSection *);
+
+/* Fournit le type d'un éventuel panneau de configuration lié. */
+GType gtk_tweak_section_get_panel(const GtkTweakSection *);
+
+/* Fournit la désignation d'une éventuelle sous-section liée. */
+const char *gtk_tweak_section_get_sub_section(const GtkTweakSection *);
+
+
+
+#endif /* _GTKEXT_TWEAK_H */
diff --git a/src/gtkext/tweak.ui b/src/gtkext/tweak.ui
new file mode 100644
index 0000000..576e25e
--- /dev/null
+++ b/src/gtkext/tweak.ui
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+ <template class="GtkTweakSection" parent="GtkListBoxRow">
+
+ <property name="child">
+
+ <object class="GtkBox">
+ <property name="orientation">horizontal</property>
+ <property name="margin-top">14</property>
+ <property name="margin-bottom">14</property>
+
+ <child>
+ <object class="GtkImage" id="icon">
+ <property name="icon-name">security-high-symbolic</property>
+ <property name="margin-start">12</property>
+ <property name="margin-end">12</property>
+ <style>
+ <class name="icon-dropshadow"/>
+ </style>
+ </object>
+ </child>
+
+ <child>
+ <object class="GtkLabel" id="label">
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">Security</property>
+ <property name="hexpand">true</property>
+ </object>
+ </child>
+
+ <child>
+ <object class="GtkImage" id="next">
+ <property name="icon-name">go-next-symbolic</property>
+ <property name="margin-start">12</property>
+ <property name="margin-end">12</property>
+ <style>
+ <class name="icon-dropshadow"/>
+ </style>
+ </object>
+ </child>
+
+ </object>
+ </property>
+
+ </template>
+</interface>