summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--configure.ac5
-rw-r--r--src/gtkext/Makefile.am6
-rw-r--r--src/gtkext/bindings/Makefile.am42
-rw-r--r--src/gtkext/bindings/generated-enums.c.template41
-rw-r--r--src/gtkext/bindings/generated-enums.h.template23
-rw-r--r--src/gtkext/dockstation-int.h18
-rw-r--r--src/gtkext/dockstation.c427
-rw-r--r--src/gtkext/dockstation.h7
-rw-r--r--src/gtkext/dockstation.ui80
-rw-r--r--src/gtkext/gresource.xml2
-rw-r--r--src/gtkext/grid-int.h42
-rw-r--r--src/gtkext/grid.c1305
-rw-r--r--src/gtkext/grid.h43
-rw-r--r--src/gtkext/grid.ui217
-rw-r--r--src/gtkext/panel-int.h6
-rw-r--r--src/gtkext/panel.c31
-rw-r--r--src/gtkext/panel.h5
-rw-r--r--src/gtkext/statusstack-int.h2
-rw-r--r--src/gtkext/statusstack.c116
-rw-r--r--src/gtkext/statusstack.ui3
-rw-r--r--src/gui/dialogs/preferences.c3
-rw-r--r--src/gui/dialogs/prefs/Makefile.am3
-rw-r--r--src/gui/dialogs/prefs/appearance-int.h64
-rw-r--r--src/gui/dialogs/prefs/appearance.c251
-rw-r--r--src/gui/dialogs/prefs/appearance.h41
-rw-r--r--src/gui/dialogs/prefs/appearance.ui184
-rw-r--r--src/gui/dialogs/prefs/gresource.xml1
-rw-r--r--src/gui/style.css12
-rw-r--r--src/gui/window-int.h2
-rw-r--r--src/gui/window.c196
-rw-r--r--src/gui/window.ui20
-rw-r--r--src/schemas/re.chrysalide.framework.gschema.xml66
33 files changed, 2497 insertions, 768 deletions
diff --git a/.gitignore b/.gitignore
index d43ca32..bb8db02 100644
--- a/.gitignore
+++ b/.gitignore
@@ -66,6 +66,7 @@ plugins/dalvik/v35/opcodes/
# GLib
src/glibext/chrysamarshal.*
resources.[ch]
+src/gtkext/bindings/*-enums.[ch]
# Binaries
src/chrysalide
diff --git a/configure.ac b/configure.ac
index 92a35de..5ac8f62 100644
--- a/configure.ac
+++ b/configure.ac
@@ -35,6 +35,10 @@ AC_PROG_INSTALL
AC_PROG_MAKE_SET
LT_INIT
+PKG_PROG_PKG_CONFIG([0.28])
+
+PKG_CHECK_VAR([GLIB_MKENUMS], [glib-2.0], [glib_mkenums])
+
CFLAGS=""
AC_EGREP_CPP(yes,
@@ -870,6 +874,7 @@ AC_CONFIG_FILES([Makefile
src/glibext/generators/Makefile
src/glibext/options/Makefile
src/gtkext/Makefile
+ src/gtkext/bindings/Makefile
src/gtkext/graph/Makefile
src/gui/Makefile
src/gui/core/Makefile
diff --git a/src/gtkext/Makefile.am b/src/gtkext/Makefile.am
index 839ee8f..c6908dd 100644
--- a/src/gtkext/Makefile.am
+++ b/src/gtkext/Makefile.am
@@ -29,6 +29,8 @@ libgtkext_la_CFLAGS = $(LIBGTK_CFLAGS) $(LIBXML_CFLAGS)
IMG_PATH = ../../data/images
RES_FILES = \
+ grid.ui \
+ dockstation.ui \
hexview.css \
hexview.ui \
launcher.ui \
@@ -64,6 +66,9 @@ libgtkext4_la_SOURCES = \
libgtkext4_la_CFLAGS = $(LIBGTK4_CFLAGS)
+libgtkext4_la_LIBADD = \
+ bindings/libgtkextbindings.la
+
devdir = $(includedir)/chrysalide/$(subdir:src/%=core/%)
@@ -71,6 +76,7 @@ dev_HEADERS = $(libgtkext4_la_SOURCES:%c=)
#SUBDIRS = graph
+SUBDIRS = bindings
resources.c: gresource.xml $(RES_FILES)
diff --git a/src/gtkext/bindings/Makefile.am b/src/gtkext/bindings/Makefile.am
new file mode 100644
index 0000000..71e770d
--- /dev/null
+++ b/src/gtkext/bindings/Makefile.am
@@ -0,0 +1,42 @@
+
+EXTRA_DIST = \
+ generated-enums.c.template \
+ generated-enums.h.template
+
+
+noinst_LTLIBRARIES = libgtkextbindings.la
+
+
+nodist_libgtkextbindings_la_SOURCES = \
+ grid-enums.h grid-enums.c
+
+libgtkextbindings_la_CFLAGS = $(LIBGTK4_CFLAGS)
+
+
+BUILT_SOURCES = $(nodist_libgtkextbindings_la_SOURCES)
+CLEANFILES = $(nodist_libgtkextbindings_la_SOURCES)
+
+
+devdir = $(includedir)/chrysalide/$(subdir:src/%=core/%)
+
+dev_HEADERS = $(nodist_libgtkextbindings_la_SOURCES:%c=)
+
+
+grid-enums.c: ../../gtkext/grid.h generated-enums.c.template
+ $(AM_V_GEN)$(GLIB_MKENUMS) \
+ --fhead "#include \"$(subst .c,.h,$@)\"\n" \
+ --template=$(srcdir)/generated-enums.c.template \
+ --output=$(srcdir)/$@ \
+ $<
+
+grid-enums.h: ../../gtkext/grid.h generated-enums.h.template
+ $(AM_V_GEN)$(GLIB_MKENUMS) \
+ --fhead "#ifndef _GTKEXT_BINDINGS_GRID_ENUM_H\n" \
+ --fhead "#define _GTKEXT_BINDINGS_GRID_ENUM_H\n" \
+ --fhead "\n" \
+ --fhead "#include \"$<\"\n" \
+ --fhead "\n" \
+ --ftail "#endif /* _GTKEXT_BINDINGS_GRID_ENUM_H */\n" \
+ --template=$(srcdir)/generated-enums.h.template \
+ --output=$(srcdir)/$@ \
+ $<
diff --git a/src/gtkext/bindings/generated-enums.c.template b/src/gtkext/bindings/generated-enums.c.template
new file mode 100644
index 0000000..8f54149
--- /dev/null
+++ b/src/gtkext/bindings/generated-enums.c.template
@@ -0,0 +1,41 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// SPDX-FileCopyrightText: 2023 Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
+
+/*** BEGIN file-header ***/
+
+/*** END file-header ***/
+
+/*** BEGIN file-production ***/
+
+/* Enumerations de "@filename@" */
+
+/*** END file-production ***/
+
+/*** BEGIN value-header ***/
+
+GType @enum_name@_get_type(void)
+{
+ static gsize static_g_@type@_type_id;
+
+ if (g_once_init_enter(&static_g_@type@_type_id)) {
+ static const G@Type@Value values[] = {
+/*** END value-header ***/
+
+/*** BEGIN value-production ***/
+ {@VALUENAME@, "@VALUENAME@", "@valuenick@"},
+/*** END value-production ***/
+
+/*** BEGIN value-tail ***/
+ { 0, NULL, NULL }
+ };
+
+ GType g_@type@_type_id = g_@type@_register_static(
+ g_intern_static_string("@EnumName@"), values);
+
+ g_once_init_leave (&static_g_@type@_type_id, g_@type@_type_id);
+ }
+
+ return static_g_@type@_type_id;
+}
+
+/*** END value-tail ***/
diff --git a/src/gtkext/bindings/generated-enums.h.template b/src/gtkext/bindings/generated-enums.h.template
new file mode 100644
index 0000000..58c772d
--- /dev/null
+++ b/src/gtkext/bindings/generated-enums.h.template
@@ -0,0 +1,23 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+// SPDX-FileCopyrightText: 2023-2024 Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
+
+/*** BEGIN file-header ***/
+
+G_BEGIN_DECLS
+
+/*** END file-header ***/
+
+/*** BEGIN file-production ***/
+
+/*** END file-production ***/
+
+/*** BEGIN value-header ***/
+GType @enum_name@_get_type(void) G_GNUC_CONST;
+#define @ENUMPREFIX@_@ENUMSHORT@_TYPE (@enum_name@_get_type())
+/*** END value-header ***/
+
+/*** BEGIN file-tail ***/
+
+G_END_DECLS
+
+/*** END file-tail ***/
diff --git a/src/gtkext/dockstation-int.h b/src/gtkext/dockstation-int.h
index a44371a..17ed828 100644
--- a/src/gtkext/dockstation-int.h
+++ b/src/gtkext/dockstation-int.h
@@ -32,19 +32,29 @@
/* Station de réception pour concentration d'éléments (instance) */
struct _GtkDockStation
{
- GtkWidget parent; /* A laisser en premier */
+ GtkBox parent; /* A laisser en premier */
+
+ GtkOrientation orientation; /* Spécification d'orientation */
+
+ GtkWidget *tabs; /* Bascule entre panneaux */
+ GtkWidget *toolbar; /* Boutons d'action */
+ GtkWidget *sep1; /* Séparateur #1 */
+ GtkStack *stack; /* Pile de panneaux affichés */
+ GtkWidget *sep2; /* Séparateur #2 */
+
+ GtkTiledPanel *def_panel; /* Eventuel panneau à maintenir*/
};
/* Station de réception pour concentration d'éléments (classe) */
struct _GtkDockStationClass
{
- GtkWidgetClass parent; /* A laisser en premier */
+ GtkBoxClass parent; /* A laisser en premier */
/* Signaux */
- void (* dock_widget) (GtkDockStation *, GtkWidget *);
- void (* undock_widget) (GtkDockStation *, GtkWidget *);
+ void (* panel_docked) (GtkDockStation *, GtkTiledPanel *);
+ void (* panel_undocked) (GtkDockStation *, GtkTiledPanel *);
void (* switch_widget) (GtkDockStation *, GtkWidget *);
diff --git a/src/gtkext/dockstation.c b/src/gtkext/dockstation.c
index 093f120..359e3a1 100644
--- a/src/gtkext/dockstation.c
+++ b/src/gtkext/dockstation.c
@@ -28,6 +28,25 @@
+/* --------------------------- INTERFACE DU COMPOSANT GTK --------------------------- */
+
+
+/* Liste des propriétés */
+
+typedef enum _DockStationProperty {
+
+ PROP_0, /* Réservé */
+
+ /* Interface GtkOrientable */
+ PROP_ORIENTATION,
+
+ N_PROPERTIES = PROP_ORIENTATION
+
+} DockStationProperty;
+
+//static GParamSpec *_dock_station_properties[N_PROPERTIES] = { NULL, };
+
+
/* Procède à l'initialisation de l'afficheur concentré. */
static void gtk_dock_station_class_init(GtkDockStationClass *);
@@ -35,16 +54,31 @@ static void gtk_dock_station_class_init(GtkDockStationClass *);
static void gtk_dock_station_init(GtkDockStation *);
/* Supprime toutes les références externes. */
-static void gtk_dock_station_dispose(GtkDockStation *);
+static void gtk_dock_station_dispose(GObject *);
/* Procède à la libération totale de la mémoire. */
-static void gtk_dock_station_finalize(GtkDockStation *);
+static void gtk_dock_station_finalize(GObject *);
+
+
+
+/* --------------------- IMPLEMENTATION DES FONCTIONS DE CLASSE --------------------- */
+
+/* Met à jour une propriété d'instance GObject. */
+static void gtk_dock_station_set_property(GObject *, guint, const GValue *, GParamSpec *);
+/* Fournit la valeur d'une propriété d'instance GObject. */
+static void gtk_dock_station_get_property(GObject *, guint, GValue *, GParamSpec *);
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/* INTERFACE DU COMPOSANT GTK */
+/* ---------------------------------------------------------------------------------- */
/* Détermine le type du composant d'affichage concentré. */
-G_DEFINE_TYPE(GtkDockStation, gtk_dock_station, GTK_TYPE_WIDGET)
+G_DEFINE_TYPE(GtkDockStation, gtk_dock_station, GTK_TYPE_GRID)
/******************************************************************************
@@ -62,28 +96,47 @@ G_DEFINE_TYPE(GtkDockStation, gtk_dock_station, GTK_TYPE_WIDGET)
static void gtk_dock_station_class_init(GtkDockStationClass *class)
{
GObjectClass *object; /* Autre version de la classe */
+ GtkWidgetClass *widget; /* Classe de haut niveau */
object = G_OBJECT_CLASS(class);
- object->dispose = (GObjectFinalizeFunc/* ! */)gtk_dock_station_dispose;
- object->finalize = (GObjectFinalizeFunc)gtk_dock_station_finalize;
+ object->dispose = gtk_dock_station_dispose;
+ object->finalize = gtk_dock_station_finalize;
+ object->set_property = gtk_dock_station_set_property;
+ object->get_property = gtk_dock_station_get_property;
- g_signal_new("dock-widget",
+ //g_object_class_install_properties(object, N_PROPERTIES, _dock_station_properties);
+ g_object_class_override_property(object, PROP_ORIENTATION, "orientation");
+
+ widget = GTK_WIDGET_CLASS(class);
+
+ gtk_widget_class_set_template_from_resource(widget, "/re/chrysalide/framework/gtkext/dockstation.ui");
+
+ //gtk_widget_class_bind_template_callback_full(widget, BUILDER_CB(gtk_status_stack_on_zoom_icon_press));
+
+ gtk_widget_class_bind_template_child(widget, GtkDockStation, tabs);
+ gtk_widget_class_bind_template_child(widget, GtkDockStation, toolbar);
+ gtk_widget_class_bind_template_child(widget, GtkDockStation, sep1);
+ gtk_widget_class_bind_template_child(widget, GtkDockStation, stack);
+ gtk_widget_class_bind_template_child(widget, GtkDockStation, sep2);
+
+ g_signal_new("panel-docked",
GTK_TYPE_DOCK_STATION,
G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET(GtkDockStationClass, dock_widget),
+ G_STRUCT_OFFSET(GtkDockStationClass, panel_docked),
NULL, NULL,
g_cclosure_marshal_VOID__OBJECT,
G_TYPE_NONE, 1, GTK_TYPE_WIDGET);
- g_signal_new("undock-widget",
+ g_signal_new("panel-undocked",
GTK_TYPE_DOCK_STATION,
G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET(GtkDockStationClass, undock_widget),
+ G_STRUCT_OFFSET(GtkDockStationClass, panel_undocked),
NULL, NULL,
g_cclosure_marshal_VOID__OBJECT,
G_TYPE_NONE, 1, GTK_TYPE_WIDGET);
+ /*
g_signal_new("switch-widget",
GTK_TYPE_DOCK_STATION,
G_SIGNAL_RUN_LAST,
@@ -107,6 +160,7 @@ static void gtk_dock_station_class_init(GtkDockStationClass *class)
NULL, NULL,
g_cclosure_marshal_VOID__OBJECT,
G_TYPE_NONE, 1, GTK_TYPE_WIDGET);
+ */
}
@@ -125,57 +179,66 @@ static void gtk_dock_station_class_init(GtkDockStationClass *class)
static void gtk_dock_station_init(GtkDockStation *station)
{
-#if 0
+ gtk_widget_init_template(GTK_WIDGET(station));
- GtkNotebook *notebook; /* Autre version du composant */
- GtkWidget *hbox; /* Division supérieure */
- GtkWidget *button; /* Bouton de contrôle */
+ station->orientation = GTK_ORIENTATION_HORIZONTAL;
- notebook = GTK_NOTEBOOK(station);
+ station->def_panel = NULL;
- gtk_notebook_set_show_border(notebook, FALSE);
- gtk_notebook_set_scrollable(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);
+/******************************************************************************
+* *
+* Paramètres : object = instance d'objet GLib à traiter. *
+* *
+* Description : Supprime toutes les références externes. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
- 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);
+static void gtk_dock_station_dispose(GObject *object)
+{
+ GtkDockStation *station; /* Version spécialisée */
- button = qck_create_button_with_named_img(G_OBJECT(station), "menu",
- "go-down-symbolic", GTK_ICON_SIZE_MENU, NULL,
- G_CALLBACK(on_click_for_menu), station);
- gtk_button_set_relief(GTK_BUTTON(button), GTK_RELIEF_NONE);
- gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0);
+ station = GTK_DOCK_STATION(object);
- button = qck_create_button_with_named_img(G_OBJECT(station), "close",
- "window-close-symbolic", GTK_ICON_SIZE_MENU, NULL,
- G_CALLBACK(on_click_for_close), station);
- gtk_button_set_relief(GTK_BUTTON(button), GTK_RELIEF_NONE);
- gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0);
+ gtk_widget_dispose_template(GTK_WIDGET(object), GTK_TYPE_DOCK_STATION);
- gtk_notebook_set_action_widget(notebook, hbox, GTK_PACK_END);
+ g_clear_object(&station->def_panel);
- g_signal_connect(notebook, "switch-page",
- G_CALLBACK(gtk_dock_station_switch_panel), station);
+ G_OBJECT_CLASS(gtk_dock_station_parent_class)->dispose(object);
+
+}
-#endif
+
+/******************************************************************************
+* *
+* Paramètres : object = instance d'objet GLib à traiter. *
+* *
+* Description : Procède à la libération totale de la mémoire. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void gtk_dock_station_finalize(GObject *object)
+{
+ G_OBJECT_CLASS(gtk_dock_station_parent_class)->finalize(object);
}
/******************************************************************************
* *
-* Paramètres : station = instance d'objet GLib à traiter. *
+* Paramètres : - *
* *
-* Description : Supprime toutes les références externes. *
+* Description : Crée un nouveau composant pour support d'affichage concentré.*
* *
* Retour : - *
* *
@@ -183,18 +246,23 @@ static void gtk_dock_station_init(GtkDockStation *station)
* *
******************************************************************************/
-static void gtk_dock_station_dispose(GtkDockStation *station)
+GtkWidget *gtk_dock_station_new(void)
{
- G_OBJECT_CLASS(gtk_dock_station_parent_class)->dispose(G_OBJECT(station));
+ GtkWidget *result; /* Instance à retourner */
+
+ result = g_object_new(GTK_TYPE_DOCK_STATION, NULL);
+
+ return result;
}
/******************************************************************************
* *
-* Paramètres : station = instance d'objet GLib à traiter. *
+* Paramètres : station = station d'accueil pour panneau à compléter. *
+* panel = nouveau panneau à afficher. *
* *
-* Description : Procède à la libération totale de la mémoire. *
+* Description : Ajoute un panneau à un groupe de tuiles. *
* *
* Retour : - *
* *
@@ -202,18 +270,33 @@ static void gtk_dock_station_dispose(GtkDockStation *station)
* *
******************************************************************************/
-static void gtk_dock_station_finalize(GtkDockStation *station)
+void gtk_dock_station_add_panel(GtkDockStation *station, GtkTiledPanel *panel)
{
- G_OBJECT_CLASS(gtk_dock_station_parent_class)->finalize(G_OBJECT(station));
+ GtkStackPage *page; /* Nouvelle page insérée */
+
+ page = gtk_stack_add_child(station->stack, GTK_WIDGET(panel));
+
+ if (0) // TODO
+ gtk_stack_page_set_title(page, "settings");
+
+ else
+ gtk_stack_page_set_icon_name(page, "logs-symbolic");
+
+ gtk_stack_set_visible_child(station->stack, GTK_WIDGET(panel));
+
+
+ g_signal_emit_by_name(station, "panel-docked", panel);
+
}
/******************************************************************************
* *
-* Paramètres : - *
+* Paramètres : station = station d'accueil pour panneau à compléter. *
+* panel = nouveau panneau à afficher. *
* *
-* Description : Crée un nouveau composant pour support d'affichage concentré.*
+* Description : Ajoute un panneau à conserver à un groupe de tuiles. *
* *
* Retour : - *
* *
@@ -221,17 +304,255 @@ static void gtk_dock_station_finalize(GtkDockStation *station)
* *
******************************************************************************/
-GtkWidget *gtk_dock_station_new(void)
+void gtk_dock_station_keep_panel(GtkDockStation *station, GtkTiledPanel *panel)
{
- GtkWidget *result; /* Instance à retourner */
+ bool visible; /* Visibilité des barres */
+
+ g_clear_object(&station->def_panel);
+
+ if (panel != NULL)
+ {
+ station->def_panel = panel;
+ ref_object(panel);
+
+ if (gtk_stack_get_page(station->stack, GTK_WIDGET(panel)) == NULL)
+ gtk_dock_station_add_panel(station, panel);
+
+ }
+
+ visible = (station->def_panel == NULL);
+
+ gtk_widget_set_visible(station->tabs, visible);
+ gtk_widget_set_visible(station->toolbar, visible);
+ gtk_widget_set_visible(station->sep1, visible);
+ gtk_widget_set_visible(station->sep2, visible && station->orientation == GTK_ORIENTATION_HORIZONTAL);
+
+}
- result = g_object_new(GTK_TYPE_DOCK_STATION, NULL);
+
+/******************************************************************************
+* *
+* Paramètres : station = station d'accueil pour panneau à consulter. *
+* *
+* Description : Indique si la station d'accueil contient au moins un panneau.*
+* *
+* Retour : true si aucun panneau n'est intégré, false sinon. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool gtk_dock_station_is_empty(const GtkDockStation *station)
+{
+ bool result; /* Bilan à retourner */
+ GtkSelectionModel *model; /* Modèle pour la pile */
+ guint count; /* Nombre de panneaux présents */
+
+ model = gtk_stack_get_pages(station->stack);
+
+ count = g_list_model_get_n_items(G_LIST_MODEL(model));
+
+ result = (count == 0);
+
+ unref_object(model);
return result;
}
+/* ---------------------------------------------------------------------------------- */
+/* IMPLEMENTATION DES FONCTIONS DE CLASSE */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+* *
+* Paramètres : object = instance d'objet GLib à mamnipuler. *
+* prop_id = identifiant de la propriété visée. *
+* value = valeur à prendre en compte. *
+* pspec = définition de la propriété. *
+* *
+* Description : Met à jour une propriété d'instance GObject. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void gtk_dock_station_set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
+{
+ GtkDockStation *station; /* Version spécialisée */
+ GtkOrientation orientation; /* Spécification d'orientation */
+ GtkLayoutManager *layout; /* Gestionnaire de disposition */
+ GtkLayoutChild *child_layout; /* Disposition de composant */
+
+ station = GTK_DOCK_STATION(object);
+
+ switch (prop_id)
+ {
+ case PROP_ORIENTATION:
+
+ orientation = g_value_get_enum(value);
+
+ if (station->orientation != orientation)
+ {
+ station->orientation = orientation;
+
+ gtk_orientable_set_orientation(GTK_ORIENTABLE(station->tabs), orientation);
+ gtk_orientable_set_orientation(GTK_ORIENTABLE(station->toolbar), orientation);
+
+ layout = gtk_widget_get_layout_manager(GTK_WIDGET(object));
+
+ if (orientation == GTK_ORIENTATION_VERTICAL)
+ {
+ g_object_set(G_OBJECT(station->tabs),
+ "halign", GTK_ALIGN_START,
+ "valign", GTK_ALIGN_CENTER,
+ NULL);
+
+ g_object_set(G_OBJECT(station->toolbar),
+ "halign", GTK_ALIGN_END,
+ "valign", GTK_ALIGN_CENTER,
+ NULL);
+
+ child_layout = gtk_layout_manager_get_layout_child(layout, station->toolbar);
+
+ g_object_set(G_OBJECT(child_layout),
+ "column", 1,
+ "row", 0,
+ NULL);
+
+ child_layout = gtk_layout_manager_get_layout_child(layout, station->sep1);
+
+ g_object_set(G_OBJECT(child_layout),
+ "column", 0,
+ "row", 1,
+ "column-span", 2,
+ NULL);
+
+ gtk_widget_set_visible(station->sep2, FALSE);
+
+ child_layout = gtk_layout_manager_get_layout_child(layout, GTK_WIDGET(station->stack));
+
+ g_object_set(G_OBJECT(child_layout),
+ "column", 0,
+ "row", 2,
+ "column-span", 2,
+ NULL);
+
+ }
+ else
+ {
+ g_object_set(G_OBJECT(station->tabs),
+ "halign", GTK_ALIGN_START,
+ "valign", GTK_ALIGN_START,
+ NULL);
+
+ g_object_set(G_OBJECT(station->toolbar),
+ "halign", GTK_ALIGN_END,
+ "valign", GTK_ALIGN_START,
+ NULL);
+
+ child_layout = gtk_layout_manager_get_layout_child(layout, station->sep1);
+
+ g_object_set(G_OBJECT(child_layout),
+ "column", 1,
+ "row", 0,
+ "column-span", 1,
+ NULL);
+
+ child_layout = gtk_layout_manager_get_layout_child(layout, GTK_WIDGET(station->stack));
+
+ g_object_set(G_OBJECT(child_layout),
+ "column", 2,
+ "row", 0,
+ "column-span", 1,
+ NULL);
+
+ gtk_widget_set_visible(station->sep2, TRUE);
+
+ child_layout = gtk_layout_manager_get_layout_child(layout, station->sep2);
+
+ g_object_set(G_OBJECT(child_layout),
+ "column", 3,
+ "row", 0,
+ NULL);
+
+ child_layout = gtk_layout_manager_get_layout_child(layout, station->toolbar);
+
+ g_object_set(G_OBJECT(child_layout),
+ "column", 4,
+ "row", 0,
+ NULL);
+
+ }
+
+ g_object_notify_by_pspec(object, pspec);
+
+ }
+
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+ break;
+
+ }
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : object = instance d'objet GLib à mamnipuler. *
+* prop_id = identifiant de la propriété visée. *
+* value = valeur à transmettre. [OUT] *
+* pspec = définition de la propriété. *
+* *
+* Description : Fournit la valeur d'une propriété d'instance GObject. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void gtk_dock_station_get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
+{
+ GtkDockStation *station; /* Version spécialisée */
+
+ station = GTK_DOCK_STATION(object);
+
+ switch (prop_id)
+ {
+ case PROP_ORIENTATION:
+ g_value_set_enum(value, station->orientation);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+ break;
+
+ }
+
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/gtkext/dockstation.h b/src/gtkext/dockstation.h
index a857626..3106dae 100644
--- a/src/gtkext/dockstation.h
+++ b/src/gtkext/dockstation.h
@@ -28,6 +28,7 @@
#include <gtk/gtk.h>
+#include "panel.h"
#include "../glibext/helpers.h"
@@ -40,8 +41,14 @@ DECLARE_GTYPE(GtkDockStation, gtk_dock_station, GTK, DOCK_STATION);
/* Crée un nouveau composant pour support d'affichage concentré. */
GtkWidget *gtk_dock_station_new(void);
+/* Ajoute un panneau à un groupe de tuiles. */
+void gtk_dock_station_add_panel(GtkDockStation *, GtkTiledPanel *);
+/* Ajoute un panneau à conserver à un groupe de tuiles. */
+void gtk_dock_station_keep_panel(GtkDockStation *, GtkTiledPanel *);
+/* Indique si la station d'accueil contient au moins un panneau. */
+bool gtk_dock_station_is_empty(const GtkDockStation *);
diff --git a/src/gtkext/dockstation.ui b/src/gtkext/dockstation.ui
new file mode 100644
index 0000000..4d25134
--- /dev/null
+++ b/src/gtkext/dockstation.ui
@@ -0,0 +1,80 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+ <template class="GtkDockStation" parent="GtkGrid">
+ <property name="orientation">horizontal</property>
+
+ <child>
+ <object class="GtkStackSwitcher" id="tabs">
+ <property name="orientation">horizontal</property>
+ <property name="halign">start</property>
+ <property name="valign">start</property>
+ <property name="margin-start">2</property>
+ <property name="margin-top">2</property>
+ <property name="margin-end">2</property>
+ <property name="margin-bottom">2</property>
+ <property name="stack">stack</property>
+ <layout>
+ <property name="column">0</property>
+ <property name="row">0</property>
+ </layout>
+ </object>
+ </child>
+
+ <child>
+ <object class="GtkBox" id="toolbar">
+ <property name="orientation">horizontal</property>
+ <property name="halign">end</property>
+ <property name="valign">start</property>
+
+ <child>
+ <object class="GtkButton">
+ <property name="icon-name">window-close-symbolic</property>
+ <style>
+ <class name="circular"/>
+ <class name="flat"/>
+ <class name="control-button"/>
+ </style>
+ </object>
+ </child>
+
+ <layout>
+ <property name="column">4</property>
+ <property name="row">0</property>
+ </layout>
+ </object>
+ </child>
+
+ <child>
+ <object class="GtkSeparator" id="sep1">
+ <property name="orientation">horizontal</property>
+ <layout>
+ <property name="column">1</property>
+ <property name="row">0</property>
+ <property name="column-span">1</property>
+ </layout>
+ </object>
+ </child>
+
+ <child>
+ <object class="GtkStack" id="stack">
+ <property name="hexpand">true</property>
+ <layout>
+ <property name="column">2</property>
+ <property name="row">0</property>
+ <property name="column-span">1</property>
+ </layout>
+ </object>
+ </child>
+
+ <child>
+ <object class="GtkSeparator" id="sep2">
+ <property name="orientation">horizontal</property>
+ <layout>
+ <property name="column">3</property>
+ <property name="row">0</property>
+ </layout>
+ </object>
+ </child>
+
+ </template>
+</interface>
diff --git a/src/gtkext/gresource.xml b/src/gtkext/gresource.xml
index 640985f..26943a6 100644
--- a/src/gtkext/gresource.xml
+++ b/src/gtkext/gresource.xml
@@ -1,6 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<gresources>
<gresource prefix="/re/chrysalide/framework/gtkext">
+ <file compressed="true">dockstation.ui</file>
+ <file compressed="true">grid.ui</file>
<file compressed="true">hexview.css</file>
<file compressed="true">hexview.ui</file>
<file compressed="true">launcher.ui</file>
diff --git a/src/gtkext/grid-int.h b/src/gtkext/grid-int.h
index 5ae48ad..8a2702b 100644
--- a/src/gtkext/grid-int.h
+++ b/src/gtkext/grid-int.h
@@ -25,46 +25,50 @@
#define _GTKEXT_GRID_INT_H
+#include "dockstation.h"
#include "grid.h"
-/* -------------------------- GESTION DES TUILES AFFICHEES -------------------------- */
-
-
-/* Informations concernant une tuile */
-typedef struct _grid_tile_t
+/* Conteneur pour un affichage en tuiles nommées (instance) */
+struct _GtkTilingGrid
{
- struct _grid_tile_t *parent; /* Tuile parente */
+ GtkGrid parent; /* A laisser en premier */
- GtkWidget *widget; /* Support d'affichage */
+ GSettings *settings; /* Configuration du conteneur */
- char *path; /* Chemin d'accès */
+ LayoutReachOptions layout; /* Disposition générale */
- struct _grid_tile_t *children[2]; /* Tuiles encastrées ou 2xNULL */
+ bool visible[TGB_COUNT]; /* Visibilités souhaitées */
-} grid_tile_t;
+ GtkRevealer *top; /* Zone d'accueil #1 */
+ GtkWidget *top_handle; /* Poignée de redimensionnement*/
+ GtkDockStation *top_station; /* Station entière */
+ GtkRevealer *left; /* Zone d'accueil #2 */
+ GtkWidget *left_handle; /* Poignée de redimensionnement*/
+ GtkDockStation *left_station; /* Station entière */
+ GtkDockStation *main_station; /* Zone d'accueil #3 */
-/* --------------------------- INTERFACE DU COMPOSANT GTK --------------------------- */
+ GtkRevealer *right; /* Zone d'accueil #4 */
+ GtkWidget *right_handle; /* Poignée de redimensionnement*/
+ GtkDockStation *right_station; /* Station entière */
+ GtkRevealer *bottom; /* Zone d'accueil #5 */
+ GtkWidget *bottom_handle; /* Poignée de redimensionnement*/
+ GtkDockStation *bottom_station; /* Station entière */
-/* Conteneur pour un affichage en tuiles nommées (instance) */
-struct _GtkTilingGrid
-{
- GtkWidget parent; /* A laisser en premier */
-
- grid_tile_t *tiles; /* Tuiles représentées */
+ GtkGesture *tpad_gesture[TGB_COUNT]; /* Gestionnaires du touchpad */
- GtkTiledPanel *def_panel; /* Panneau principal par défaut*/
+ bool panning; /* Redimensionnement en cours */
};
/* Conteneur pour un affichage en tuiles nommées (classe) */
struct _GtkTilingGridClass
{
- GtkWidgetClass parent; /* A laisser en premier */
+ GtkGridClass parent; /* A laisser en premier */
/* Signaux */
diff --git a/src/gtkext/grid.c b/src/gtkext/grid.c
index 1b9c909..afc74b7 100644
--- a/src/gtkext/grid.c
+++ b/src/gtkext/grid.c
@@ -24,29 +24,43 @@
#include "grid.h"
+#include <assert.h>
+#include <malloc.h>
+#include <string.h>
+
+
#include "grid-int.h"
+#include "helpers.h"
+#include "bindings/grid-enums.h"
+
+/* --------------------------- INTERFACE DU COMPOSANT GTK --------------------------- */
-/* -------------------------- GESTION DES TUILES AFFICHEES -------------------------- */
+/* Liste des propriétés */
+typedef enum _TilingGridProperty {
-#define IS_LEAF_TILE(t) \
- ({ \
- bool __result; \
- __result = GTK_IS_DOCK_STATION((t)->widget); \
- assert(__result || GTK_IS_PANED((t)->widget)); \
- __result; \
- })
+ PROP_0, /* Réservé */
+ PROP_LAYOUT, /* Disposition générale */
-/* Supprime une tuile de la mémoire. */
-static void delete_tile(grid_tile_t *);
+ PROP_EMPTY_TOP, /* Vide de la zone supérieure */
+ PROP_EMPTY_LEFT, /* Vide de la zone de gauche */
+ PROP_EMPTY_RIGHT, /* Vide de la zone de droite */
+ PROP_EMPTY_BOTTOM, /* Vide de la zone inférieure */
+ PROP_VISIBLE_TOP, /* Visibilité de zone sup. */
+ PROP_VISIBLE_LEFT, /* Visibilité de zone de gauche*/
+ PROP_VISIBLE_RIGHT, /* Visibilité de zone de droite*/
+ PROP_VISIBLE_BOTTOM, /* Visibilité de zone inf. */
+ N_PROPERTIES
-/* --------------------------- INTERFACE DU COMPOSANT GTK --------------------------- */
+} TilingGridProperty;
+
+static GParamSpec *_tiling_grid_properties[N_PROPERTIES] = { NULL, };
/* Initialise la classe des conteneurs d'affichage en tuiles. */
@@ -56,48 +70,50 @@ static void gtk_tiling_grid_class_init(GtkTilingGridClass *);
static void gtk_tiling_grid_init(GtkTilingGrid *);
/* Supprime toutes les références externes. */
-static void gtk_tiling_grid_dispose(GtkTilingGrid *);
+static void gtk_tiling_grid_dispose(GObject *);
/* Procède à la libération totale de la mémoire. */
-static void gtk_tiling_grid_finalize(GtkTilingGrid *);
+static void gtk_tiling_grid_finalize(GObject *);
+/* Réagit à une intégration ou à un retrait de panneau. */
+static void gtk_tiling_grid_on_panel_un_docked(GtkDockStation *, GtkTiledPanel *, GtkTilingGrid *);
+/* -------------------- REDIMENSIONNEMENT DE ZONES POUR PANNEAUX -------------------- */
-/* ---------------------------------------------------------------------------------- */
-/* GESTION DES TUILES AFFICHEES */
-/* ---------------------------------------------------------------------------------- */
+/* Initie un redimensionnement par drag-and-drop. */
+static void gtk_tiling_grid_on_gesture_drag_begin(GtkGestureDrag *, double, double, GtkTilingGrid *);
-/******************************************************************************
-* *
-* Paramètres : tile = tuile à supprimer. *
-* *
-* Description : Supprime une tuile de la mémoire. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
+/* Applique l'effet d'un redimensionnement drag-and-drop donné. */
+static void gtk_tiling_grid_on_gesture_drag_update(GtkTilingGrid *, TilingGridBorder, double, double);
-static void delete_tile(grid_tile_t *tile)
-{
- if (!IS_LEAF_TILE(tile))
- {
- delete_tile(tile->children[0]);
- delete_tile(tile->children[1]);
- }
+/* Actualise l'effet d'un redimensionnement drag-and-drop. */
+static void gtk_tiling_grid_on_top_gesture_drag_update(GtkGestureDrag *, double, double, GtkTilingGrid *);
- else
- free(tile->path);
+/* Actualise l'effet d'un redimensionnement drag-and-drop. */
+static void gtk_tiling_grid_on_left_gesture_drag_update(GtkGestureDrag *, double, double, GtkTilingGrid *);
- unref_object(tile->widget);
+/* Actualise l'effet d'un redimensionnement drag-and-drop. */
+static void gtk_tiling_grid_on_right_gesture_drag_update(GtkGestureDrag *, double, double, GtkTilingGrid *);
- free(tile);
+/* Actualise l'effet d'un redimensionnement drag-and-drop. */
+static void gtk_tiling_grid_on_bottom_gesture_drag_update(GtkGestureDrag *, double, double, GtkTilingGrid *);
-}
+/* Clôture un drag-and-drop de redimensionnement. */
+static void gtk_tiling_grid_on_gesture_drag_end(GtkGestureDrag *, double, double, GtkTilingGrid *);
+
+
+
+/* --------------------- IMPLEMENTATION DES FONCTIONS DE CLASSE --------------------- */
+
+
+/* Met à jour une propriété d'instance GObject. */
+static void gtk_tiling_grid_set_property(GObject *, guint, const GValue *, GParamSpec *);
+
+/* Fournit la valeur d'une propriété d'instance GObject. */
+static void gtk_tiling_grid_get_property(GObject *, guint, GValue *, GParamSpec *);
@@ -107,12 +123,12 @@ static void delete_tile(grid_tile_t *tile)
/* Détermine le type du conteneur d'affichage en tuiles nommées. */
-G_DEFINE_TYPE(GtkTilingGrid, gtk_tiling_grid, GTK_TYPE_WIDGET)
+G_DEFINE_TYPE(GtkTilingGrid, gtk_tiling_grid, GTK_TYPE_GRID)
/******************************************************************************
* *
-* Paramètres : klass = classe GTK à initialiser. *
+* Paramètres : class = classe GTK à initialiser. *
* *
* Description : Initialise la classe des conteneurs d'affichage en tuiles. *
* *
@@ -122,14 +138,101 @@ G_DEFINE_TYPE(GtkTilingGrid, gtk_tiling_grid, GTK_TYPE_WIDGET)
* *
******************************************************************************/
-static void gtk_tiling_grid_class_init(GtkTilingGridClass *klass)
+static void gtk_tiling_grid_class_init(GtkTilingGridClass *class)
{
GObjectClass *object; /* Autre version de la classe */
+ GtkWidgetClass *widget; /* Classe de haut niveau */
+
+ object = G_OBJECT_CLASS(class);
+
+ object->dispose = gtk_tiling_grid_dispose;
+ object->finalize = gtk_tiling_grid_finalize;
+ object->set_property = gtk_tiling_grid_set_property;
+ object->get_property = gtk_tiling_grid_get_property;
+
+ _tiling_grid_properties[PROP_LAYOUT] =
+ g_param_spec_flags("layout", NULL, NULL,
+ LAYOUT_REACH_OPTIONS_TYPE,
+ LRO_NONE,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_EXPLICIT_NOTIFY);
+
+ _tiling_grid_properties[PROP_EMPTY_TOP] =
+ g_param_spec_boolean("empty-top", NULL, NULL,
+ TRUE,
+ G_PARAM_READABLE | G_PARAM_STATIC_STRINGS | G_PARAM_EXPLICIT_NOTIFY);
+
+ _tiling_grid_properties[PROP_EMPTY_LEFT] =
+ g_param_spec_boolean("empty-left", NULL, NULL,
+ TRUE,
+ G_PARAM_READABLE | G_PARAM_STATIC_STRINGS | G_PARAM_EXPLICIT_NOTIFY);
+
+ _tiling_grid_properties[PROP_EMPTY_RIGHT] =
+ g_param_spec_boolean("empty-right", NULL, NULL,
+ TRUE,
+ G_PARAM_READABLE | G_PARAM_STATIC_STRINGS | G_PARAM_EXPLICIT_NOTIFY);
+
+ _tiling_grid_properties[PROP_EMPTY_BOTTOM] =
+ g_param_spec_boolean("empty-bottom", NULL, NULL,
+ TRUE,
+ G_PARAM_READABLE | G_PARAM_STATIC_STRINGS | G_PARAM_EXPLICIT_NOTIFY);
+
+ /**
+ * La valeur initiale des champs suivants est à maintenir synchronisée avec
+ * les initialisations de gtk_tiling_grid_init().
+ */
+
+ _tiling_grid_properties[PROP_VISIBLE_TOP] =
+ g_param_spec_boolean("visible-top", NULL, NULL,
+ TRUE,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_EXPLICIT_NOTIFY);
+
+ _tiling_grid_properties[PROP_VISIBLE_LEFT] =
+ g_param_spec_boolean("visible-left", NULL, NULL,
+ TRUE,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_EXPLICIT_NOTIFY);
+
+ _tiling_grid_properties[PROP_VISIBLE_RIGHT] =
+ g_param_spec_boolean("visible-right", NULL, NULL,
+ TRUE,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_EXPLICIT_NOTIFY);
+
+ _tiling_grid_properties[PROP_VISIBLE_BOTTOM] =
+ g_param_spec_boolean("visible-bottom", NULL, NULL,
+ TRUE,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_EXPLICIT_NOTIFY);
+
+ g_object_class_install_properties(object, N_PROPERTIES, _tiling_grid_properties);
+
+ widget = GTK_WIDGET_CLASS(class);
+
+ g_type_ensure(GTK_TYPE_DOCK_STATION);
- object = G_OBJECT_CLASS(klass);
+ gtk_widget_class_set_template_from_resource(widget, "/re/chrysalide/framework/gtkext/grid.ui");
- object->dispose = (GObjectFinalizeFunc/* ! */)gtk_tiling_grid_dispose;
- object->finalize = (GObjectFinalizeFunc)gtk_tiling_grid_finalize;
+ gtk_widget_class_bind_template_callback_full(widget, BUILDER_CB(gtk_tiling_grid_on_panel_un_docked));
+ gtk_widget_class_bind_template_callback_full(widget, BUILDER_CB(gtk_tiling_grid_on_gesture_drag_begin));
+ gtk_widget_class_bind_template_callback_full(widget, BUILDER_CB(gtk_tiling_grid_on_top_gesture_drag_update));
+ gtk_widget_class_bind_template_callback_full(widget, BUILDER_CB(gtk_tiling_grid_on_left_gesture_drag_update));
+ gtk_widget_class_bind_template_callback_full(widget, BUILDER_CB(gtk_tiling_grid_on_right_gesture_drag_update));
+ gtk_widget_class_bind_template_callback_full(widget, BUILDER_CB(gtk_tiling_grid_on_bottom_gesture_drag_update));
+ gtk_widget_class_bind_template_callback_full(widget, BUILDER_CB(gtk_tiling_grid_on_gesture_drag_end));
+
+ gtk_widget_class_bind_template_child(widget, GtkTilingGrid, top);
+ gtk_widget_class_bind_template_child(widget, GtkTilingGrid, top_handle);
+ gtk_widget_class_bind_template_child(widget, GtkTilingGrid, top_station);
+ gtk_widget_class_bind_template_child(widget, GtkTilingGrid, left);
+ gtk_widget_class_bind_template_child(widget, GtkTilingGrid, left_handle);
+ gtk_widget_class_bind_template_child(widget, GtkTilingGrid, left_station);
+ gtk_widget_class_bind_template_child(widget, GtkTilingGrid, main_station);
+ gtk_widget_class_bind_template_child(widget, GtkTilingGrid, right);
+ gtk_widget_class_bind_template_child(widget, GtkTilingGrid, right_handle);
+ gtk_widget_class_bind_template_child(widget, GtkTilingGrid, right_station);
+ gtk_widget_class_bind_template_child(widget, GtkTilingGrid, bottom);
+ gtk_widget_class_bind_template_child(widget, GtkTilingGrid, bottom_handle);
+ gtk_widget_class_bind_template_child(widget, GtkTilingGrid, bottom_station);
+
+
+ /////////////
g_signal_new("station-created",
GTK_TYPE_TILING_GRID,
@@ -144,7 +247,7 @@ static void gtk_tiling_grid_class_init(GtkTilingGridClass *klass)
/******************************************************************************
* *
-* Paramètres : tgrid = instance GTK à initialiser. *
+* Paramètres : grid = instance GTK à initialiser. *
* *
* Description : Initialise une instance de conteneur d'affichage en tuiles. *
* *
@@ -154,18 +257,70 @@ static void gtk_tiling_grid_class_init(GtkTilingGridClass *klass)
* *
******************************************************************************/
-static void gtk_tiling_grid_init(GtkTilingGrid *tgrid)
+static void gtk_tiling_grid_init(GtkTilingGrid *grid)
{
- tgrid->tiles = NULL;
+ gtk_widget_init_template(GTK_WIDGET(grid));
+
+ grid->settings = g_settings_new_with_path("re.chrysalide.framework.tiledgrid",
+ "/re/chrysalide/framework/gui/tiles/");
+
+ g_settings_bind(grid->settings, "layout",
+ grid, "layout",
+ G_SETTINGS_BIND_DEFAULT);
+
+ /**
+ * L'initialisation des champs suivants est à maintenir synchronisée avec
+ * les valeurs initiales de gtk_tiling_grid_class_init().
+ */
+
+ grid->visible[TGB_TOP] = true;
+ grid->visible[TGB_LEFT] = true;
+ grid->visible[TGB_RIGHT] = true;
+ grid->visible[TGB_BOTTOM] = true;
+
+ g_settings_bind(grid->settings, "top-request",
+ grid->top_station, "height-request",
+ G_SETTINGS_BIND_DEFAULT);
+
+ g_settings_bind(grid->settings, "top-visibility",
+ grid, "visible-top",
+ G_SETTINGS_BIND_DEFAULT);
+
+ g_settings_bind(grid->settings, "left-request",
+ grid->left_station, "width-request",
+ G_SETTINGS_BIND_DEFAULT);
- tgrid->def_panel = NULL;
+ g_settings_bind(grid->settings, "left-visibility",
+ grid, "visible-left",
+ G_SETTINGS_BIND_DEFAULT);
+
+ g_settings_bind(grid->settings, "right-request",
+ grid->right_station, "width-request",
+ G_SETTINGS_BIND_DEFAULT);
+
+ g_settings_bind(grid->settings, "right-visibility",
+ grid, "visible-right",
+ G_SETTINGS_BIND_DEFAULT);
+
+ g_settings_bind(grid->settings, "bottom-request",
+ grid->bottom_station, "height-request",
+ G_SETTINGS_BIND_DEFAULT);
+
+ g_settings_bind(grid->settings, "bottom-visibility",
+ grid, "visible-bottom",
+ G_SETTINGS_BIND_DEFAULT);
+
+ gtk_widget_set_cursor_from_name(grid->top_handle, "row-resize");
+ gtk_widget_set_cursor_from_name(grid->left_handle, "col-resize");
+ gtk_widget_set_cursor_from_name(grid->right_handle, "col-resize");
+ gtk_widget_set_cursor_from_name(grid->bottom_handle, "row-resize");
}
/******************************************************************************
* *
-* Paramètres : grid = instance d'objet GLib à traiter. *
+* Paramètres : object = instance d'objet GLib à traiter. *
* *
* Description : Supprime toutes les références externes. *
* *
@@ -175,24 +330,24 @@ static void gtk_tiling_grid_init(GtkTilingGrid *tgrid)
* *
******************************************************************************/
-static void gtk_tiling_grid_dispose(GtkTilingGrid *grid)
+static void gtk_tiling_grid_dispose(GObject *object)
{
- if (grid->tiles != NULL)
- {
- delete_tile(grid->tiles);
- grid->tiles = NULL;
- }
+ GtkTilingGrid *grid; /* Version spécialisée */
+
+ gtk_widget_dispose_template(GTK_WIDGET(object), GTK_TYPE_DOCK_STATION);
+
+ grid = GTK_TILING_GRID(object);
- g_clear_object(&grid->def_panel);
+ g_clear_object(&grid->settings);
- G_OBJECT_CLASS(gtk_tiling_grid_parent_class)->dispose(G_OBJECT(grid));
+ G_OBJECT_CLASS(gtk_tiling_grid_parent_class)->dispose(object);
}
/******************************************************************************
* *
-* Paramètres : grid = instance d'objet GLib à traiter. *
+* Paramètres : object = instance d'objet GLib à traiter. *
* *
* Description : Procède à la libération totale de la mémoire. *
* *
@@ -202,9 +357,9 @@ static void gtk_tiling_grid_dispose(GtkTilingGrid *grid)
* *
******************************************************************************/
-static void gtk_tiling_grid_finalize(GtkTilingGrid *grid)
+static void gtk_tiling_grid_finalize(GObject *object)
{
- G_OBJECT_CLASS(gtk_tiling_grid_parent_class)->finalize(G_OBJECT(grid));
+ G_OBJECT_CLASS(gtk_tiling_grid_parent_class)->finalize(object);
}
@@ -232,142 +387,80 @@ GtkWidget *gtk_tiling_grid_new(void)
}
-
-
-
-
-#if 0
-
-
-#include <assert.h>
-#include <ctype.h>
-#include <malloc.h>
-#include <string.h>
-
-
-#include "../core/logs.h"
-
-
-
-/* Valide un chemin d'accès à une tuile. */
-static bool is_valid_tile_path(const char *);
-
-/* Crée une tuile finale d'affichage de panneaux. */
-static grid_tile_t *create_leaf_tile(const char *, GtkTiledGrid *);
-
-/* Crée une tuile intermédiaire d'affichage de panneaux. */
-static grid_tile_t *create_inter_tile(grid_tile_t *, bool, grid_tile_t *, grid_tile_t *);
-
-/* Supprime une tuile de la mémoire. */
-//static void delete_tile(grid_tile_t *);
-
-/* Calcule la taille comme entre un chemin et celui d'une tuile. */
-static size_t compute_tile_score(const grid_tile_t *, const char *);
-
-/* Indique la tuile adaptée pour un chemin donné. */
-static grid_tile_t *find_suitable_tile(grid_tile_t **, const char *, GtkTiledGrid *);
-
-/* Découpe une tuile pour y insérer une zone. */
-static grid_tile_t *split_tile(grid_tile_t **, const char *, char, GtkTiledGrid *);
-
-/* Tente de mettre la main sur une station d'accueil. */
-static grid_tile_t *find_tile_for_widget(grid_tile_t *, GtkWidget *);
-
-/* Retire une moitié de tuile vide au plein profit de l'autre. */
-static void collapse_tile(grid_tile_t *, grid_tile_t *);
-
-
-
-/* --------------------------- INTERFACE DU COMPOSANT GTK --------------------------- */
-
-
-
-
-
-/* ---------------------------------------------------------------------------------- */
-/* GESTION DES TUILES AFFICHEES */
-/* ---------------------------------------------------------------------------------- */
-
-
/******************************************************************************
* *
-* Paramètres : path = chemin destiné à sélectionner une tuile. *
+* Paramètres : grid = zone d'affichage en tuiles à manipuler. *
+* border = sélection de la zone à considérer. *
+* visible = nouveau statut de visibilité à appliquer. *
* *
-* Description : Valide un chemin d'accès à une tuile. *
+* Description : Affiche ou masque une zone du conteneur en tuiles. *
* *
-* Retour : true si le chemin est utilisable, false sinon. *
+* Retour : - *
* *
* Remarques : - *
* *
******************************************************************************/
-static bool is_valid_tile_path(const char *path)
+void gtk_tiling_grid_set_visible(GtkTilingGrid *grid, TilingGridBorder border, bool visible)
{
- bool result; /* Bilan à retourner */
- size_t len; /* Taille du chemin */
- size_t i; /* Boucle de parcours */
- char c; /* Caractère de chemin analysé */
-
- /**
- * M[NESWnesw]*
- */
+ GtkRevealer *revealer; /* Cible visée par l'opération */
+ GtkDockStation *station; /* Apport d'une contrainte */
- len = strlen(path);
-
- result = (len >= 1);
+ if (grid->visible[border] != visible)
+ {
+ grid->visible[border] = visible;
- if (result)
- result = (path[0] == 'M');
+ switch (border)
+ {
+ case TGB_TOP:
+ revealer = grid->top;
+ station = grid->top_station;
+ break;
+
+ case TGB_LEFT:
+ revealer = grid->left;
+ station = grid->left_station;
+ break;
+
+ case TGB_RIGHT:
+ revealer = grid->right;
+ station = grid->right_station;
+ break;
+
+ case TGB_BOTTOM:
+ revealer = grid->bottom;
+ station = grid->bottom_station;
+ break;
- for (i = 1; i < len && result; i++)
- {
- c = path[i];
+ }
- if (c == '\0')
- break;
+ gtk_revealer_set_reveal_child(revealer, visible && !gtk_dock_station_is_empty(station));
- result = (c == 'N' || c == 'n'
- || c == 'E' || c == 'e'
- || c == 'S' || c == 's'
- || c == 'W' || c == 'w');
+ g_object_notify_by_pspec(G_OBJECT(grid), _tiling_grid_properties[PROP_VISIBLE_TOP + border]);
}
- return result;
-
}
/******************************************************************************
* *
-* Paramètres : path = chemin d'accès à la future tuile. *
-* tgrid = conteneur d'affichage en tuiles à manipuler. *
+* Paramètres : grid = zone d'affichage en tuiles à manipuler. *
+* border = sélection de la zone à considérer. *
* *
-* Description : Crée une tuile finale d'affichage de panneaux. *
+* Description : Fournit la visibilité d'une zone du conteneur en tuiles. *
* *
-* Retour : Structure mise en place. *
+* Retour : Visibilité de la zone considérée. *
* *
* Remarques : - *
* *
******************************************************************************/
-static grid_tile_t *create_leaf_tile(const char *path, GtkTiledGrid *tgrid)
+bool gtk_tiling_grid_get_visible(GtkTilingGrid *grid, TilingGridBorder border)
{
- grid_tile_t *result; /* Structure à retourner */
-
- result = (grid_tile_t *)malloc(sizeof(grid_tile_t));
-
- result->parent = NULL;
-
- result->widget = gtk_dock_station_new();
- gtk_widget_show(result->widget);
-
- result->path = strdup(path);
+ bool result; /* Statut à retourner */
- result->children[0] = NULL;
- result->children[1] = NULL;
-
- g_signal_emit_by_name(tgrid, "station-created", result->widget);
+ result = grid->visible[border];
return result;
@@ -376,333 +469,278 @@ static grid_tile_t *create_leaf_tile(const char *path, GtkTiledGrid *tgrid)
/******************************************************************************
* *
-* Paramètres : parent = tuile parente ou NULL si aucune. *
-* horiz = indique le type d'orientation désiré. *
-* first = première tuile à intégrer. *
-* second = seconde tuile à intégrer. *
+* Paramètres : grid = zone d'affichage en tuiles à manipuler. *
+* panel = nouveau panneau à afficher. *
+* keep = indique si le panneau est à conserver présent. *
* *
-* Description : Crée une tuile intermédiaire d'affichage de panneaux. *
+* Description : Ajoute un panneau à un conteneur en tuiles. *
* *
-* Retour : Structure mise en place. *
+* Retour : - *
* *
* Remarques : - *
* *
******************************************************************************/
-static grid_tile_t *create_inter_tile(grid_tile_t *parent, bool horiz, grid_tile_t *first, grid_tile_t *second)
+void gtk_tiling_grid_add_panel(GtkTilingGrid *grid, GtkTiledPanel *panel, bool keep)
{
- grid_tile_t *result; /* Structure à retourner */
- GtkWidget *container; /* Conteneur à vider */
-
- result = (grid_tile_t *)malloc(sizeof(grid_tile_t));
-
- result->parent = parent;
-
- if (horiz)
- result->widget = gtk_paned_new(GTK_ORIENTATION_HORIZONTAL);
- else
- result->widget = gtk_paned_new(GTK_ORIENTATION_VERTICAL);
+ char *path; /* Chemin visé par le panneau */
+ bool static_path; /* Nature du chemin à traiter */
- gtk_widget_show(result->widget);
+ path = gtk_tiled_panel_get_path(panel);
- result->path = NULL;
+ static_path = (path == NULL);
- result->children[0] = first;
- result->children[1] = second;
+ if (static_path)
+ path = "";
- /* Changement de propriétaire */
+ switch (path[0])
+ {
+ case 'N':
+ if (keep)
+ gtk_dock_station_keep_panel(grid->top_station, panel);
+ else
+ gtk_dock_station_add_panel(grid->top_station, panel);
+ break;
- container = gtk_widget_get_parent(first->widget);
+ case 'W':
+ if (keep)
+ gtk_dock_station_keep_panel(grid->left_station, panel);
+ else
+ gtk_dock_station_add_panel(grid->left_station, panel);
+ break;
- if (container != NULL)
- gtk_container_remove(GTK_CONTAINER(container), first->widget);
+ case '\0':
+ case 'M':
+ if (keep)
+ gtk_dock_station_keep_panel(grid->main_station, panel);
+ else
+ gtk_dock_station_add_panel(grid->main_station, panel);
+ break;
- g_object_ref(G_OBJECT(first->widget));
- gtk_paned_pack1(GTK_PANED(result->widget), first->widget, TRUE, FALSE);
+ case 'E':
+ if (keep)
+ gtk_dock_station_keep_panel(grid->right_station, panel);
+ else
+ gtk_dock_station_add_panel(grid->right_station, panel);
+ break;
- container = gtk_widget_get_parent(second->widget);
+ case 'S':
+ if (keep)
+ gtk_dock_station_keep_panel(grid->bottom_station, panel);
+ else
+ gtk_dock_station_add_panel(grid->bottom_station, panel);
+ break;
- if (container != NULL)
- gtk_container_remove(GTK_CONTAINER(container), second->widget);
+ default:
+ break;
- g_object_ref(G_OBJECT(second->widget));
- gtk_paned_pack2(GTK_PANED(result->widget), second->widget, TRUE, FALSE);
+ }
- return result;
+ if (!static_path)
+ free(path);
}
-
/******************************************************************************
* *
-* Paramètres : tile = tuile à analyser. *
-* path = chemin final complet recherché. *
+* Paramètres : station = plateforme GTK ayant connu un changement. *
+* widget = nouvel élément à intégrer. *
+* grid = gestionnaire de placement en tuile concerné. *
* *
-* Description : Calcule la taille comme entre un chemin et celui d'une tuile.*
+* Description : Réagit à une intégration ou à un retrait de panneau. *
* *
-* Retour : Quantité de caractères communs. *
+* Retour : - *
* *
* Remarques : - *
* *
******************************************************************************/
-static size_t compute_tile_score(const grid_tile_t *tile, const char *path)
+static void gtk_tiling_grid_on_panel_un_docked(GtkDockStation *station, GtkTiledPanel *panel, GtkTilingGrid *grid)
{
- size_t result; /* Nombre de points à renvoyer */
- size_t max; /* Taille du chemin de la tuile*/
- size_t i; /* Boucle de parcours */
- size_t score_0; /* Score du sous-élément #1 */
- size_t score_1; /* Score du sous-élément #2 */
+ TilingGridBorder border; /* Aire concernée par l'action */
+ GtkRevealer *revealer; /* Cible visée par l'opération */
+ bool new_state; /* Nouveau statut d'affichage */
- if (IS_LEAF_TILE(tile))
+ if (station == grid->top_station)
{
- max = strlen(tile->path);
-
- if (strlen(path) < max)
- result = 0;
-
- else
- {
- result = 0;
+ border = TGB_TOP;
+ revealer = grid->top;
+ }
- for (i = 0; i < max; i++)
- {
- if (tolower((unsigned char)tile->path[i]) == tolower((unsigned char)path[i]))
- result++;
- else
- break;
- }
+ else if (station == grid->left_station)
+ {
+ border = TGB_LEFT;
+ revealer = grid->left;
+ }
- }
+ else if (station == grid->right_station)
+ {
+ border = TGB_RIGHT;
+ revealer = grid->right;
+ }
+ else if (station == grid->bottom_station)
+ {
+ border = TGB_BOTTOM;
+ revealer = grid->bottom;
}
+
else
- {
- score_0 = compute_tile_score(tile->children[0], path);
- score_1 = compute_tile_score(tile->children[1], path);
+ assert(false);
- result = score_0 > score_1 ? score_0 : score_1;
+ new_state = grid->visible[border] && !gtk_dock_station_is_empty(station);
- }
+ if (gtk_revealer_get_reveal_child(revealer) != new_state)
+ gtk_revealer_set_reveal_child(revealer, new_state);
- return result;
+ /**
+ * On ne sait pas si l'état a réellement changé, mais on avertit
+ * d'une mise à jour quand même, au cas où.
+ */
+
+ g_object_notify_by_pspec(G_OBJECT(grid), _tiling_grid_properties[PROP_EMPTY_TOP + border]);
}
+
+/* ---------------------------------------------------------------------------------- */
+/* REDIMENSIONNEMENT DE ZONES POUR PANNEAUX */
+/* ---------------------------------------------------------------------------------- */
+
+
/******************************************************************************
* *
-* Paramètres : tile = tuile ou NULL si aucune. [OUT] *
-* path = chemin d'accès à la tuile visée. *
-* tgrid = conteneur d'affichage en tuiles à manipuler. *
+* Paramètres : gesture = encadrement de déplacement à l'origine de l'appel. *
+* start_x = pointe de départ sur l'axe des abscisses. *
+* start_y = pointe de départ sur l'axe des ordonnées. *
+* grid = gestionnaire de placement en tuile concerné. *
* *
-* Description : Indique la tuile adaptée pour un chemin donné. *
+* Description : Initie un redimensionnement par drag-and-drop. *
* *
-* Retour : Structure d'acceuil à disposition. *
+* Retour : - *
* *
* Remarques : - *
* *
******************************************************************************/
-static grid_tile_t *find_suitable_tile(grid_tile_t **tile, const char *path, GtkTiledGrid *tgrid)
+static void gtk_tiling_grid_on_gesture_drag_begin(GtkGestureDrag *gesture, double start_x, double start_y, GtkTilingGrid *grid)
{
- grid_tile_t *result; /* Structure à renvoyer */
- size_t best_len; /* Taille du chemin associé */
- size_t score_0; /* Score du sous-élément #1 */
- size_t score_1; /* Score du sous-élément #2 */
- char *sub_path; /* Nouvelle tentative d'accès */
- grid_tile_t **best; /* Direction à prendre */
- unsigned char next; /* Prochaine étape */
-
- /* Cas d'école : appel initial */
- if (*tile == NULL)
- {
- assert(path[0] == 'M' && path[1] == '\0');
-
- result = create_leaf_tile("M", tgrid);
- *tile = result;
-
- }
-
- else
- {
- if (IS_LEAF_TILE(*tile))
- {
- best_len = compute_tile_score(*tile, path);
-
- assert(best_len > 0);
-
- if (path[best_len] == '\0')
- result = *tile;
-
- else
- result = split_tile(tile, path, path[best_len], tgrid);
-
- }
-
- else
- {
- score_0 = compute_tile_score((*tile)->children[0], path);
- score_1 = compute_tile_score((*tile)->children[1], path);
-
- assert(score_0 > 0 || score_0 > 0);
-
- if (score_0 == score_1)
- {
- sub_path = strndup(path, score_0);
-
- score_0 = compute_tile_score((*tile)->children[0], sub_path);
- score_1 = compute_tile_score((*tile)->children[1], sub_path);
+ gtk_gesture_set_state(GTK_GESTURE(gesture), GTK_EVENT_SEQUENCE_CLAIMED);
- free(sub_path);
-
- }
-
- if (score_0 == score_1)
- result = split_tile(tile, path, path[score_0], tgrid);
-
- else
- {
- if (score_0 > score_1)
- {
- best = &(*tile)->children[0];
- best_len = score_0;
- }
- else
- {
- best = &(*tile)->children[1];
- best_len = score_1;
- }
-
- /**
- * Si on vient de tomber une feuille, trois cas de figure :
- * - soit c'est elle qui est visée.
- * - soit on veut la diviser.
- * - soit on veut la diviser en englobant ses voisines.
- */
-
- if (IS_LEAF_TILE(*best))
- {
- assert(best_len <= strlen(path));
-
- next = path[best_len];
-
- /* Premier cas */
- if (next == '\0')
- result = *best;
-
- else
- {
- /* Second cas */
- if (islower(next))
- result = find_suitable_tile(best, path, tgrid);
-
- /* Troisième cas */
- else
- result = split_tile(tile, path, next, tgrid);
-
- }
-
- }
-
- else
- result = find_suitable_tile(best, path, tgrid);
-
- }
-
- }
-
- }
-
- assert(IS_LEAF_TILE(result));
-
- return result;
+ grid->panning = true;
}
/******************************************************************************
* *
-* Paramètres : tile = tuile à découper en deux. [OUT] *
-* path = chemin d'accès à la future tuile. *
-* endpoint = désignation de la zone représentée. *
-* tgrid = conteneur d'affichage en tuiles à manipuler. *
+* Paramètres : grid = zone d'affichage en tuiles à manipuler. *
+* border = sélection de la zone à considérer. *
+* offset_x = déplacement sur l'axe des abscisses. *
+* offset_y = déplacement sur l'axe des ordonnées. *
* *
-* Description : Découpe une tuile pour y insérer une zone. *
+* Description : Applique l'effet d'un redimensionnement drag-and-drop donné. *
* *
-* Retour : Structure fille mise en place. *
+* Retour : - *
* *
* Remarques : - *
* *
******************************************************************************/
-static grid_tile_t *split_tile(grid_tile_t **tile, const char *path, char endpoint, GtkTiledGrid *tgrid)
+static void gtk_tiling_grid_on_gesture_drag_update(GtkTilingGrid *grid, TilingGridBorder border, double offset_x, double offset_y)
{
- grid_tile_t *result; /* Création à retourner */
- GtkWidget *container; /* Conteneur à vider */
- grid_tile_t *new; /* Nouvelle tuile intermédiaire*/
+ GtkDockStation *station; /* Station entière */
+ int request; /* Taille requise */
+
+ /* Sélection de la poignée adaptée */
+
+ switch (border)
+ {
+ case TGB_TOP:
+ station = grid->top_station;
+ break;
+
+ case TGB_LEFT:
+ station = grid->left_station;
+ break;
- container = gtk_widget_get_parent((*tile)->widget);
+ case TGB_RIGHT:
+ station = grid->right_station;
+ break;
- /* Création */
+ case TGB_BOTTOM:
+ station = grid->bottom_station;
+ break;
- result = create_leaf_tile(path, tgrid);
+ }
- /* Encapsulation */
+ /* Détermination d'une nouvelle position et application */
- switch (endpoint)
+ switch (border)
{
- case 'N':
- case 'n':
- new = create_inter_tile((*tile)->parent, false, result, *tile);
+ case TGB_TOP:
+ case TGB_BOTTOM:
+ g_object_get(G_OBJECT(station), "height-request", &request, NULL);
break;
- case 'E':
- case 'e':
- new = create_inter_tile((*tile)->parent, true, *tile, result);
+ case TGB_LEFT:
+ case TGB_RIGHT:
+ g_object_get(G_OBJECT(station), "width-request", &request, NULL);
break;
- case 'S':
- case 's':
- new = create_inter_tile((*tile)->parent, false, *tile, result);
+ }
+
+ switch (border)
+ {
+ case TGB_TOP:
+ request += offset_y;
break;
- case 'W':
- case 'w':
- new = create_inter_tile((*tile)->parent, true, result, *tile);
+ case TGB_LEFT:
+ request += offset_x;
break;
- default:
- assert(false);
- new = NULL;
+ case TGB_RIGHT:
+ request += -offset_x;
+ break;
+
+ case TGB_BOTTOM:
+ request += -offset_y;
break;
}
- /* Connexions */
+ if (request > 0)
+ {
+ switch (border)
+ {
+ case TGB_TOP:
+ case TGB_BOTTOM:
+ g_object_set(G_OBJECT(station), "height-request", request, NULL);
+ break;
- *tile = new;
+ case TGB_LEFT:
+ case TGB_RIGHT:
+ g_object_set(G_OBJECT(station), "width-request", request, NULL);
+ break;
- result->parent = new;
+ }
- if (container != NULL)
- {
- g_object_ref(G_OBJECT(new->widget));
- gtk_container_add(GTK_CONTAINER(container), new->widget);
}
- return result;
-
}
/******************************************************************************
* *
-* Paramètres : tile = tuile parente, prochaine victime de promotion. *
-* side = côté de tuile amené à disparaître. *
+* Paramètres : gesture = encadrement de déplacement à l'origine de l'appel. *
+* offset_x = déplacement sur l'axe des abscisses. *
+* offset_y = déplacement sur l'axe des ordonnées. *
+* grid = gestionnaire de placement en tuile concerné. *
* *
-* Description : Retire une moitié de tuile vide au plein profit de l'autre. *
+* Description : Actualise l'effet d'un redimensionnement drag-and-drop. *
* *
* Retour : - *
* *
@@ -710,114 +748,65 @@ static grid_tile_t *split_tile(grid_tile_t **tile, const char *path, char endpoi
* *
******************************************************************************/
-static void collapse_tile(grid_tile_t *tile, grid_tile_t *side)
+static void gtk_tiling_grid_on_top_gesture_drag_update(GtkGestureDrag *gesture, double offset_x, double offset_y, GtkTilingGrid *grid)
{
- grid_tile_t *promoted; /* Tuile à faire remonter */
- GtkWidget *container; /* Conteneur à vider */
-
- assert(!IS_LEAF_TILE(tile));
-
- /* Sélection du remplaçant */
-
- if (side == tile->children[0])
- promoted = tile->children[1];
- else
- promoted = tile->children[0];
-
- /* Etablissement d'une place nette */
-
- gtk_container_remove(GTK_CONTAINER(tile->widget), promoted->widget);
-
- container = gtk_widget_get_parent(tile->widget);
- gtk_container_remove(GTK_CONTAINER(container), tile->widget);
-
- delete_tile(side);
-
- /* Promotion effective */
-
- tile->widget = promoted->widget;
-
- tile->path = promoted->path;
-
- tile->children[0] = promoted->children[0];
- tile->children[1] = promoted->children[1];
-
- g_object_ref(G_OBJECT(promoted->widget));
- gtk_container_add(GTK_CONTAINER(container), tile->widget);
-
- free(promoted);
+ gtk_tiling_grid_on_gesture_drag_update(grid, TGB_TOP, offset_x, offset_y);
}
/******************************************************************************
* *
-* Paramètres : tile = point de départ des recherches locales. *
-* widget = composant graphique à retrouver. *
+* Paramètres : gesture = encadrement de déplacement à l'origine de l'appel. *
+* offset_x = déplacement sur l'axe des abscisses. *
+* offset_y = déplacement sur l'axe des ordonnées. *
+* grid = gestionnaire de placement en tuile concerné. *
* *
-* Description : Tente de mettre la main sur une station d'accueil. *
+* Description : Actualise l'effet d'un redimensionnement drag-and-drop. *
* *
-* Retour : Eventuelle tuile trouvée ou NULL. *
+* Retour : - *
* *
* Remarques : - *
* *
******************************************************************************/
-static grid_tile_t *find_tile_for_widget(grid_tile_t *tile, GtkWidget *widget)
+static void gtk_tiling_grid_on_left_gesture_drag_update(GtkGestureDrag *gesture, double offset_x, double offset_y, GtkTilingGrid *grid)
{
- grid_tile_t *result; /* Tuile à retourner */
-
- if (IS_LEAF_TILE(tile))
- result = tile->widget == widget ? tile : NULL;
-
- else
- {
- result = find_tile_for_widget(tile->children[0], widget);
-
- if (result == NULL)
- result = find_tile_for_widget(tile->children[1], widget);
-
- }
-
- return result;
+ gtk_tiling_grid_on_gesture_drag_update(grid, TGB_LEFT, offset_x, offset_y);
}
-
-
/******************************************************************************
* *
-* Paramètres : tgrid = conteneur d'affichage en tuiles à consulter. *
+* Paramètres : gesture = encadrement de déplacement à l'origine de l'appel. *
+* offset_x = déplacement sur l'axe des abscisses. *
+* offset_y = déplacement sur l'axe des ordonnées. *
+* grid = gestionnaire de placement en tuile concerné. *
* *
-* Description : Donne le panneau fourni par défaut pour la zone principale. *
+* Description : Actualise l'effet d'un redimensionnement drag-and-drop. *
* *
-* Retour : Panneau d'affichage par défault ou NULL. *
+* Retour : - *
* *
* Remarques : - *
* *
******************************************************************************/
-GPanelItem *gtk_tiled_grid_get_default_main_panel(const GtkTiledGrid *tgrid)
+static void gtk_tiling_grid_on_right_gesture_drag_update(GtkGestureDrag *gesture, double offset_x, double offset_y, GtkTilingGrid *grid)
{
- GPanelItem *result; /* Panneau à retourner */
-
- result = tgrid->def_panel;
-
- if (result != NULL)
- g_object_ref(G_OBJECT(result));
-
- return result;
+ gtk_tiling_grid_on_gesture_drag_update(grid, TGB_RIGHT, offset_x, offset_y);
}
/******************************************************************************
* *
-* Paramètres : tgrid = conteneur d'affichage en tuiles à modifier. *
-* panel = panneau d'affichage par défault ou NULL. *
+* Paramètres : gesture = encadrement de déplacement à l'origine de l'appel. *
+* offset_x = déplacement sur l'axe des abscisses. *
+* offset_y = déplacement sur l'axe des ordonnées. *
+* grid = gestionnaire de placement en tuile concerné. *
* *
-* Description : Fournit le panneau par défaut pour la zone principale. *
+* Description : Actualise l'effet d'un redimensionnement drag-and-drop. *
* *
* Retour : - *
* *
@@ -825,56 +814,21 @@ GPanelItem *gtk_tiled_grid_get_default_main_panel(const GtkTiledGrid *tgrid)
* *
******************************************************************************/
-void gtk_tiled_grid_set_default_main_panel(GtkTiledGrid *tgrid, GPanelItem *panel)
+static void gtk_tiling_grid_on_bottom_gesture_drag_update(GtkGestureDrag *gesture, double offset_x, double offset_y, GtkTilingGrid *grid)
{
- GtkWidget *widget; /* Composant GTK à retirer */
- GtkWidget *parent; /* Conteneur à vider */
- grid_tile_t *tile; /* Première tuile d'accueil */
-
- if (tgrid->def_panel != NULL)
- {
- widget = gtk_dockable_build_widget(GTK_DOCKABLE(tgrid->def_panel));
-
- parent = gtk_widget_get_parent(widget);
-
- if (parent != NULL)
- gtk_container_remove(GTK_CONTAINER(parent), widget);
-
- g_object_unref(G_OBJECT(widget));
-
- g_object_unref(G_OBJECT(tgrid->def_panel));
-
- }
-
- tgrid->def_panel = panel;
-
- if (panel != NULL)
- {
- g_object_ref(G_OBJECT(panel));
-
- if (tgrid->tiles == NULL)
- gtk_tiled_grid_add(tgrid, panel);
-
- else
- {
- tile = find_suitable_tile(&tgrid->tiles, "M", tgrid);
-
- if (gtk_notebook_get_n_pages(GTK_NOTEBOOK(tile->widget)) == 0)
- gtk_tiled_grid_add(tgrid, panel);
-
- }
-
- }
+ gtk_tiling_grid_on_gesture_drag_update(grid, TGB_BOTTOM, offset_x, offset_y);
}
/******************************************************************************
* *
-* Paramètres : tgrid = conteneur d'affichage en tuiles à modifier. *
-* panel = panneau d'affichage à intégrer. *
+* Paramètres : gesture = encadrement de déplacement à l'origine de l'appel. *
+* offset_x = déplacement final sur l'axe des abscisses. *
+* offset_y = déplacement final sur l'axe des ordonnées. *
+* grid = gestionnaire de placement en tuile concerné. *
* *
-* Description : Incorpore un nouveau panneau dans le conteneur en tuiles. *
+* Description : Clôture un drag-and-drop de redimensionnement. *
* *
* Retour : - *
* *
@@ -882,66 +836,30 @@ void gtk_tiled_grid_set_default_main_panel(GtkTiledGrid *tgrid, GPanelItem *pane
* *
******************************************************************************/
-void gtk_tiled_grid_add(GtkTiledGrid *tgrid, GPanelItem *panel)
+static void gtk_tiling_grid_on_gesture_drag_end(GtkGestureDrag *gesture, double offset_x, double offset_y, GtkTilingGrid *grid)
{
- char *path; /* Chemin d'accès */
- char *name; /* Nom à donner à l'onglet */
- grid_tile_t *tile; /* Tuile d'accueil */
-
- path = gtk_panel_item_class_get_path(G_PANEL_ITEM_GET_CLASS(panel));
-
- if (!is_valid_tile_path(path))
- {
- name = gtk_dockable_get_name(GTK_DOCKABLE(panel));
- log_variadic_message(LMT_ERROR, _("Invalid path '%s' for panel '%s'"), path, name);
- free(name);
- }
-
+ if (!grid->panning)
+ gtk_gesture_set_state(GTK_GESTURE(gesture), GTK_EVENT_SEQUENCE_DENIED);
else
- {
- tile = find_suitable_tile(&tgrid->tiles, path, tgrid);
- assert(tile != NULL);
-
- gtk_dock_station_add_dockable(GTK_DOCK_STATION(tile->widget), GTK_DOCKABLE(panel));
-
- g_panel_item_set_dock_at_startup(panel, true);
-
- /* Si c'est la toute première fois... */
- if (gtk_widget_get_parent(tile->widget) == NULL)
- {
- assert(tile == tgrid->tiles);
- assert(tile->path[0] == 'M' && tile->path[1] == '\0');
- g_object_ref(G_OBJECT(tile->widget));
- gtk_container_add(GTK_CONTAINER(tgrid), tile->widget);
- }
+ grid->panning = false;
- /* Si on n'a plus besoin du panneau par défaut */
- if (tgrid->def_panel != NULL && tile->path[0] == 'M' && tile->path[1] == '\0')
- {
- /* Si ce n'est pas le panneau qu'on vient de rajouter...*/
- if (panel != tgrid->def_panel)
- {
- /* Enfin : si ce panneau par défaut est réellement en place */
- if (g_panel_item_is_docked(tgrid->def_panel))
- gtk_tiled_grid_remove(tgrid, tgrid->def_panel);
-
- }
-
- }
+}
- }
- free(path);
-}
+/* ---------------------------------------------------------------------------------- */
+/* IMPLEMENTATION DES FONCTIONS DE CLASSE */
+/* ---------------------------------------------------------------------------------- */
/******************************************************************************
* *
-* Paramètres : tgrid = conteneur d'affichage en tuiles à modifier. *
-* panel = panneau d'affichage à supprimer. *
+* Paramètres : object = instance d'objet GLib à mamnipuler. *
+* prop_id = identifiant de la propriété visée. *
+* value = valeur à prendre en compte. *
+* pspec = définition de la propriété. *
* *
-* Description : Retire un panneau dans le conteneur en tuiles. *
+* Description : Met à jour une propriété d'instance GObject. *
* *
* Retour : - *
* *
@@ -949,90 +867,65 @@ void gtk_tiled_grid_add(GtkTiledGrid *tgrid, GPanelItem *panel)
* *
******************************************************************************/
-void gtk_tiled_grid_remove(GtkTiledGrid *tgrid, GPanelItem *panel)
+static void gtk_tiling_grid_set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
{
- GtkWidget *station; /* Support courant */
- grid_tile_t *tile; /* Tuile d'accueil */
-
- assert(g_panel_item_is_docked(panel));
+ GtkTilingGrid *grid; /* Version spécialisée */
- gtk_dockable_decompose(GTK_DOCKABLE(panel), &station);
+ grid = GTK_TILING_GRID(object);
- tile = find_tile_for_widget(tgrid->tiles, station);
- assert(tile != NULL);
-
- gtk_dock_station_remove_dockable(GTK_DOCK_STATION(station), GTK_DOCKABLE(panel));
-
- g_panel_item_set_dock_at_startup(panel, false);
-
- if (gtk_notebook_get_n_pages(GTK_NOTEBOOK(station)) == 0)
+ switch (prop_id)
{
- /* Si le panneau par défaut devient nécessaire */
- if (tgrid->def_panel != NULL && tile->path[0] == 'M' && tile->path[1] == '\0')
- gtk_tiled_grid_add(tgrid, tgrid->def_panel);
-
- else
- {
- /* La racine est concernée ! */
- if (tile->parent == NULL)
+ case PROP_LAYOUT:
+ if (grid->layout != g_value_get_flags(value))
{
- assert(tile == tgrid->tiles);
+ grid->layout = g_value_get_flags(value);
- g_object_ref(G_OBJECT(tile->widget));
- gtk_container_remove(GTK_CONTAINER(tgrid), tile->widget);
+ apply_tiling_grid_layout(GTK_GRID(grid), grid->layout, (GtkWidget *[]) {
+ GTK_WIDGET(grid->top), GTK_WIDGET(grid->left),
+ GTK_WIDGET(grid->right), GTK_WIDGET(grid->bottom)
+ });
- delete_tile(tile);
- tgrid->tiles = NULL;
+ g_object_notify_by_pspec(object, pspec);
}
+ break;
- else
- collapse_tile(tile->parent, tile);
-
- }
-
- }
-
-}
-
+ gtk_tiling_grid_set_visible(grid, TGB_TOP, g_value_get_boolean(value));
+ break;
-/******************************************************************************
-* *
-* Paramètres : tgrid = conteneur d'affichage en tuiles à consulter. *
-* station = station d'accueil à retrouver. *
-* *
-* Description : Indique le chemin correspondant à une station intégrée. *
-* *
-* Retour : Copie de chemin trouvé, à libérer ensuite, ou NULL si échec. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
+ case PROP_VISIBLE_TOP:
+ gtk_tiling_grid_set_visible(grid, TGB_TOP, g_value_get_boolean(value));
+ break;
-char *gtk_tiled_grid_get_path_for_station(const GtkTiledGrid *tgrid, GtkDockStation *station)
-{
- char *result; /* Chemin d'accès à renvoyer */
- grid_tile_t *tile; /* Tuile d'accueil */
+ case PROP_VISIBLE_LEFT:
+ gtk_tiling_grid_set_visible(grid, TGB_LEFT, g_value_get_boolean(value));
+ break;
- tile = find_tile_for_widget(tgrid->tiles, GTK_WIDGET(station));
+ case PROP_VISIBLE_RIGHT:
+ gtk_tiling_grid_set_visible(grid, TGB_RIGHT, g_value_get_boolean(value));
+ break;
- if (tile == NULL)
- result = NULL;
+ case PROP_VISIBLE_BOTTOM:
+ gtk_tiling_grid_set_visible(grid, TGB_BOTTOM, g_value_get_boolean(value));
+ break;
- else
- result = strdup(tile->path);
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+ break;
- return result;
+ }
}
/******************************************************************************
* *
-* Paramètres : tgrid = conteneur d'affichage en tuiles à mettre à jour. *
-* config = configuration à consulter. *
+* Paramètres : object = instance d'objet GLib à mamnipuler. *
+* prop_id = identifiant de la propriété visée. *
+* value = valeur à transmettre. [OUT] *
+* pspec = définition de la propriété. *
* *
-* Description : Replace les positions des séparateurs de tuiles. *
+* Description : Fournit la valeur d'une propriété d'instance GObject. *
* *
* Retour : - *
* *
@@ -1040,57 +933,68 @@ char *gtk_tiled_grid_get_path_for_station(const GtkTiledGrid *tgrid, GtkDockStat
* *
******************************************************************************/
-void gtk_tiled_grid_restore_positions(const GtkTiledGrid *tgrid, GGenConfig *config)
+static void gtk_tiling_grid_get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
{
+ GtkTilingGrid *grid; /* Version spécialisée */
- void visit_tiles_for_restoring(grid_tile_t *tile, const char *vpath)
- {
- GtkOrientation orientation; /* Direction de la tuile */
- char hint; /* Inutile donc indispensable */
- char *key; /* Clef d'accès à un paramètre */
- gint position; /* Nouvelle position de barre */
- size_t i; /* Boucle de parcours */
- char *child_key; /* Clef d'accès des suivants */
-
- if (!IS_LEAF_TILE(tile))
- {
- orientation = gtk_orientable_get_orientation(GTK_ORIENTABLE(tile->widget));
+ grid = GTK_TILING_GRID(object);
- hint = orientation == GTK_ORIENTATION_HORIZONTAL ? 'h' : 'v';
+ switch (prop_id)
+ {
+ case PROP_EMPTY_TOP:
+ g_value_set_boolean(value, gtk_dock_station_is_empty(grid->top_station));
+ break;
- asprintf(&key, "%s%c", vpath, hint);
+ case PROP_EMPTY_LEFT:
+ g_value_set_boolean(value, gtk_dock_station_is_empty(grid->left_station));
+ break;
- if (g_generic_config_get_value(config, key, &position))
- gtk_paned_set_position(GTK_PANED(tile->widget), position);
+ case PROP_EMPTY_RIGHT:
+ g_value_set_boolean(value, gtk_dock_station_is_empty(grid->right_station));
+ break;
- for (i = 0; i < 2; i++)
- {
- asprintf(&child_key, "%s%zu", key, i);
+ case PROP_EMPTY_BOTTOM:
+ g_value_set_boolean(value, gtk_dock_station_is_empty(grid->bottom_station));
+ break;
- visit_tiles_for_restoring(tile->children[i], child_key);
+ case PROP_VISIBLE_TOP:
+ g_value_set_boolean(value, gtk_tiling_grid_get_visible(grid, TGB_TOP));
+ break;
- free(child_key);
+ case PROP_VISIBLE_LEFT:
+ g_value_set_boolean(value, gtk_tiling_grid_get_visible(grid, TGB_LEFT));
+ break;
- }
+ case PROP_VISIBLE_RIGHT:
+ g_value_set_boolean(value, gtk_tiling_grid_get_visible(grid, TGB_RIGHT));
+ break;
- free(key);
+ case PROP_VISIBLE_BOTTOM:
+ g_value_set_boolean(value, gtk_tiling_grid_get_visible(grid, TGB_BOTTOM));
+ break;
- }
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+ break;
}
+}
- visit_tiles_for_restoring(tgrid->tiles, "gui.panels.positions.R");
-}
+
+/* ---------------------------------------------------------------------------------- */
+/* FORME GENERIQUE DE MISE EN DISPOSITION */
+/* ---------------------------------------------------------------------------------- */
/******************************************************************************
* *
-* Paramètres : tgrid = conteneur d'affichage en tuiles à consulter. *
-* config = configuration à mettre à jour. *
+* Paramètres : grid = composant GTK dont le contenu est à arranger. *
+* options = options de mise en place. *
+* panels = liste organisée de composants à déplacer. *
* *
-* Description : Sauvegarde les positions des séparateurs de tuiles. *
+* Description : Met en place une disposition particulière de panneaux. *
* *
* Retour : - *
* *
@@ -1098,49 +1002,98 @@ void gtk_tiled_grid_restore_positions(const GtkTiledGrid *tgrid, GGenConfig *con
* *
******************************************************************************/
-void gtk_tiled_grid_save_positions(const GtkTiledGrid *tgrid, GGenConfig *config)
+void apply_tiling_grid_layout(GtkGrid *grid, LayoutReachOptions options, GtkWidget *panels[TGB_COUNT])
{
-
- void visit_tiles_for_saving(grid_tile_t *tile, const char *vpath)
+ int top_panel_span; /* Etendue d'un composant #1 */
+ int left_panel_span; /* Etendue d'un composant #2 */
+ int right_panel_span; /* Etendue d'un composant #3 */
+ int bottom_panel_span; /* Etendue d'un composant #4 */
+ int top_panel_column; /* Position de composant #1 */
+ int left_panel_row; /* Position de composant #2 */
+ int right_panel_row; /* Position de composant #3 */
+ int bottom_panel_column; /* Position de composant #4 */
+ GtkLayoutManager *layout; /* Gestionnaire de disposition */
+ GtkGridLayoutChild *top_panel_layout; /* Disposition de composant #1 */
+ GtkGridLayoutChild *left_panel_layout; /* Disposition de composant #2 */
+ GtkGridLayoutChild *right_panel_layout; /* Disposition de composant #3 */
+ GtkGridLayoutChild *bottom_panel_layout;/* Disposition de composant #4 */
+
+ /* Calcul des placements */
+
+ top_panel_span = 3;
+ left_panel_span = 3;
+ right_panel_span = 3;
+ bottom_panel_span = 3;
+
+ if (options & LRO_LEFT_TOP_REACH)
{
- GtkOrientation orientation; /* Direction de la tuile */
- char hint; /* Inutile donc indispensable */
- char *key; /* Clef d'accès à un paramètre */
- gint position; /* Nouvelle position de barre */
- size_t i; /* Boucle de parcours */
- char *child_key; /* Clef d'accès des suivants */
-
- if (!IS_LEAF_TILE(tile))
- {
- orientation = gtk_orientable_get_orientation(GTK_ORIENTABLE(tile->widget));
-
- hint = orientation == GTK_ORIENTATION_HORIZONTAL ? 'h' : 'v';
+ top_panel_column = 1;
+ top_panel_span--;
+ left_panel_row = 0;
+ }
+ else
+ {
+ top_panel_column = 0;
+ left_panel_row = 1;
+ left_panel_span--;
+ }
- asprintf(&key, "%s%c", vpath, hint);
+ if (options & LRO_LEFT_BOTTOM_REACH)
+ {
+ bottom_panel_column = 1;
+ bottom_panel_span--;
+ }
+ else
+ {
+ left_panel_span--;
+ bottom_panel_column = 0;
+ }
- position = gtk_paned_get_position(GTK_PANED(tile->widget));
- g_generic_config_create_or_udpdate_param(config, key, CPT_INTEGER, -1, position);
+ if (options & LRO_RIGHT_TOP_REACH)
+ {
+ top_panel_span--;
+ right_panel_row = 0;
+ }
+ else
+ {
+ right_panel_row = 1;
+ right_panel_span--;
+ }
- for (i = 0; i < 2; i++)
- {
- asprintf(&child_key, "%s%zu", key, i);
+ if (options & LRO_RIGHT_BOTTOM_REACH)
+ bottom_panel_span--;
+ else
+ right_panel_span--;
- visit_tiles_for_saving(tile->children[i], child_key);
+ /* Mise en application des contraintes */
- free(child_key);
+ layout = gtk_widget_get_layout_manager(GTK_WIDGET(grid));
- }
+ top_panel_layout = GTK_GRID_LAYOUT_CHILD(gtk_layout_manager_get_layout_child(layout, panels[TGB_TOP]));
+ left_panel_layout = GTK_GRID_LAYOUT_CHILD(gtk_layout_manager_get_layout_child(layout, panels[TGB_LEFT]));
+ right_panel_layout = GTK_GRID_LAYOUT_CHILD(gtk_layout_manager_get_layout_child(layout, panels[TGB_RIGHT]));
+ bottom_panel_layout = GTK_GRID_LAYOUT_CHILD(gtk_layout_manager_get_layout_child(layout, panels[TGB_BOTTOM]));
- free(key);
+ g_object_set(G_OBJECT(top_panel_layout),
+ "column", top_panel_column,
+ "column-span", top_panel_span,
+ NULL);
- }
+ g_object_set(G_OBJECT(left_panel_layout),
+ "row", left_panel_row,
+ "row-span", left_panel_span,
+ NULL);
- }
+ g_object_set(G_OBJECT(right_panel_layout),
+ "row", right_panel_row,
+ "row-span", right_panel_span,
+ NULL);
+ g_object_set(G_OBJECT(bottom_panel_layout),
+ "column", bottom_panel_column,
+ "column-span", bottom_panel_span,
+ NULL);
- visit_tiles_for_saving(tgrid->tiles, "gui.panels.positions.R");
+ gtk_layout_manager_layout_changed(layout);
}
-
-
-#endif
diff --git a/src/gtkext/grid.h b/src/gtkext/grid.h
index d9b7ef1..f02cf38 100644
--- a/src/gtkext/grid.h
+++ b/src/gtkext/grid.h
@@ -25,10 +25,10 @@
#define _GTKEXT_GRID_H
+#include <stdbool.h>
#include <gtk/gtk.h>
-#include "dockstation.h"
#include "panel.h"
#include "../glibext/helpers.h"
@@ -42,7 +42,48 @@ DECLARE_GTYPE(GtkTilingGrid, gtk_tiling_grid, GTK, TILING_GRID);
/* Crée une nouvelle instance de conteneur avec tuiles. */
GtkWidget *gtk_tiling_grid_new(void);
+/* Liste des zones de bordure */
+typedef enum _TilingGridBorder /*< skip (glib-mkenums) >*/
+{
+ TGB_TOP, /* Zone supérieure */
+ TGB_LEFT, /* Zone de gauche */
+ TGB_RIGHT, /* Zone de droite */
+ TGB_BOTTOM, /* Zone inférieure */
+} TilingGridBorder;
+
+/**
+ * Fixe le nombre de combinaisons sans le rendre visible dans l'énumération.
+ */
+#define TGB_COUNT (TGB_BOTTOM + 1)
+
+/* Affiche ou masque une zone du conteneur en tuiles. */
+void gtk_tiling_grid_set_visible(GtkTilingGrid *, TilingGridBorder, bool);
+
+/* Fournit la visibilité d'une zone du conteneur en tuiles. */
+bool gtk_tiling_grid_get_visible(GtkTilingGrid *, TilingGridBorder);
+
+/* Ajoute un panneau à un conteneur en tuiles. */
+void gtk_tiling_grid_add_panel(GtkTilingGrid *, GtkTiledPanel *, bool);
+
+
+
+/* --------------------- FORME GENERIQUE DE MISE EN DISPOSITION --------------------- */
+
+
+/* Options de dispositions cumulables */
+typedef enum _LayoutReachOptions /*< flags (glib-mkenums) >*/
+{
+ LRO_NONE = (0 << 0), /* Aucune atteinte des bords */
+ LRO_LEFT_TOP_REACH = (1 << 0), /* Atteinte du bord haut à G. */
+ LRO_LEFT_BOTTOM_REACH = (1 << 1), /* Atteinte du bord bas à G. */
+ LRO_RIGHT_TOP_REACH = (1 << 2), /* Atteinte du bord haut à D. */
+ LRO_RIGHT_BOTTOM_REACH = (1 << 3), /* Atteinte du bord bas à D. */
+
+} LayoutReachOptions;
+
+/* Met en place une disposition particulière de panneaux. */
+void apply_tiling_grid_layout(GtkGrid *, LayoutReachOptions, GtkWidget *[TGB_COUNT]);
diff --git a/src/gtkext/grid.ui b/src/gtkext/grid.ui
new file mode 100644
index 0000000..b14ced2
--- /dev/null
+++ b/src/gtkext/grid.ui
@@ -0,0 +1,217 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+ <template class="GtkTilingGrid" parent="GtkGrid">
+
+ <!-- Zone supérieure -->
+
+ <child>
+ <object class="GtkRevealer" id="top">
+ <property name="transition-type">slide-up</property>
+ <property name="reveal-child">false</property>
+
+ <child>
+ <object class="GtkBox">
+ <property name="orientation">vertical</property>
+
+ <child>
+ <object class="GtkDockStation" id="top_station">
+ <property name="orientation">vertical</property>
+ <property name="hexpand">true</property>
+ <property name="vexpand">false</property>
+ <property name="height-request">30</property>
+ <signal name="panel-docked" handler="gtk_tiling_grid_on_panel_un_docked"/>
+ <signal name="panel-undocked" handler="gtk_tiling_grid_on_panel_un_docked"/>
+ </object>
+ </child>
+
+ <child>
+ <object class="GtkSeparator" id="top_handle">
+ <property name="orientation">vertical</property>
+ <property name="height-request">5</property>
+
+ <child>
+ <object class="GtkGestureDrag">
+ <property name="propagation-phase">capture</property>
+ <signal name="drag-begin" handler="gtk_tiling_grid_on_gesture_drag_begin"/>
+ <signal name="drag-update" handler="gtk_tiling_grid_on_top_gesture_drag_update"/>
+ <signal name="drag-end" handler="gtk_tiling_grid_on_gesture_drag_end"/>
+ </object>
+ </child>
+
+ </object>
+ </child>
+
+ </object>
+ </child>
+
+ <layout>
+ <property name="column">0</property>
+ <property name="row">0</property>
+ <property name="column-span">3</property>
+ </layout>
+ </object>
+ </child>
+
+ <!-- Zone de gauche -->
+
+ <child>
+ <object class="GtkRevealer" id="left">
+ <property name="transition-type">slide-right</property>
+ <property name="reveal-child">false</property>
+
+ <child>
+ <object class="GtkBox">
+ <property name="orientation">horizontal</property>
+
+ <child>
+ <object class="GtkDockStation" id="left_station">
+ <property name="orientation">vertical</property>
+ <property name="hexpand">false</property>
+ <property name="vexpand">true</property>
+ <property name="width-request">300</property>
+ <signal name="panel-docked" handler="gtk_tiling_grid_on_panel_un_docked"/>
+ <signal name="panel-undocked" handler="gtk_tiling_grid_on_panel_un_docked"/>
+ </object>
+ </child>
+
+ <child>
+ <object class="GtkSeparator" id="left_handle">
+ <property name="orientation">horizontal</property>
+ <property name="width-request">5</property>
+
+ <child>
+ <object class="GtkGestureDrag">
+ <property name="propagation-phase">capture</property>
+ <signal name="drag-begin" handler="gtk_tiling_grid_on_gesture_drag_begin"/>
+ <signal name="drag-update" handler="gtk_tiling_grid_on_left_gesture_drag_update"/>
+ <signal name="drag-end" handler="gtk_tiling_grid_on_gesture_drag_end"/>
+ </object>
+ </child>
+
+ </object>
+ </child>
+
+ </object>
+ </child>
+
+ <layout>
+ <property name="column">0</property>
+ <property name="row">1</property>
+ </layout>
+ </object>
+ </child>
+
+ <!-- Zone centrale -->
+
+ <child>
+ <object class="GtkDockStation" id="main_station">
+ <property name="hexpand">true</property>
+ <property name="vexpand">true</property>
+ <layout>
+ <property name="column">1</property>
+ <property name="row">1</property>
+ </layout>
+ </object>
+ </child>
+
+ <!-- Zone de droite -->
+
+ <child>
+ <object class="GtkRevealer" id="right">
+ <property name="transition-type">slide-left</property>
+ <property name="reveal-child">false</property>
+
+ <child>
+ <object class="GtkBox">
+ <property name="orientation">horizontal</property>
+
+ <child>
+ <object class="GtkSeparator" id="right_handle">
+ <property name="orientation">horizontal</property>
+ <property name="width-request">5</property>
+
+ <child>
+ <object class="GtkGestureDrag">
+ <property name="propagation-phase">capture</property>
+ <signal name="drag-begin" handler="gtk_tiling_grid_on_gesture_drag_begin"/>
+ <signal name="drag-update" handler="gtk_tiling_grid_on_right_gesture_drag_update"/>
+ <signal name="drag-end" handler="gtk_tiling_grid_on_gesture_drag_end"/>
+ </object>
+ </child>
+
+ </object>
+ </child>
+
+ <child>
+ <object class="GtkDockStation" id="right_station">
+ <property name="orientation">vertical</property>
+ <property name="hexpand">false</property>
+ <property name="vexpand">true</property>
+ <property name="width-request">300</property>
+ <signal name="panel-docked" handler="gtk_tiling_grid_on_panel_un_docked"/>
+ <signal name="panel-undocked" handler="gtk_tiling_grid_on_panel_un_docked"/>
+ </object>
+ </child>
+
+ </object>
+ </child>
+
+ <layout>
+ <property name="column">2</property>
+ <property name="row">1</property>
+ </layout>
+ </object>
+ </child>
+
+ <!-- Zone inférieure -->
+
+ <child>
+ <object class="GtkRevealer" id="bottom">
+ <property name="transition-type">slide-up</property>
+ <property name="reveal-child">false</property>
+
+ <child>
+ <object class="GtkBox">
+ <property name="orientation">vertical</property>
+
+ <child>
+ <object class="GtkSeparator" id="bottom_handle">
+ <property name="orientation">vertical</property>
+ <property name="height-request">5</property>
+
+ <child>
+ <object class="GtkGestureDrag">
+ <property name="propagation-phase">capture</property>
+ <signal name="drag-begin" handler="gtk_tiling_grid_on_gesture_drag_begin"/>
+ <signal name="drag-update" handler="gtk_tiling_grid_on_bottom_gesture_drag_update"/>
+ <signal name="drag-end" handler="gtk_tiling_grid_on_gesture_drag_end"/>
+ </object>
+ </child>
+
+ </object>
+ </child>
+
+ <child>
+ <object class="GtkDockStation" id="bottom_station">
+ <property name="orientation">horizontal</property>
+ <property name="hexpand">true</property>
+ <property name="vexpand">false</property>
+ <property name="height-request">250</property>
+ <signal name="panel-docked" handler="gtk_tiling_grid_on_panel_un_docked"/>
+ <signal name="panel-undocked" handler="gtk_tiling_grid_on_panel_un_docked"/>
+ </object>
+ </child>
+
+ </object>
+ </child>
+
+ <layout>
+ <property name="column">0</property>
+ <property name="row">2</property>
+ <property name="column-span">3</property>
+ </layout>
+ </object>
+ </child>
+
+ </template>
+</interface>
diff --git a/src/gtkext/panel-int.h b/src/gtkext/panel-int.h
index 07ade20..cb210d9 100644
--- a/src/gtkext/panel-int.h
+++ b/src/gtkext/panel-int.h
@@ -30,8 +30,11 @@
+/* Indique l'emplacement par défaut pour un affichage. */
+typedef char * (* get_tiled_panel_path) (const GtkTiledPanel *);
+
/* Fournit les composants adaptés pour la barre de titre. */
-typedef GListStore * (* get_tiled_panel_widgets_cb) (GtkTiledPanel *, bool);
+typedef GListStore * (* get_tiled_panel_widgets_cb) (const GtkTiledPanel *, bool);
@@ -47,6 +50,7 @@ struct _GtkTiledPanelClass
{
GtkBoxClass parent; /* A laisser en premier */
+ get_tiled_panel_path get_default_path; /* Localisation de l'affichage */
get_tiled_panel_widgets_cb get_widgets; /* Récupération de composants */
};
diff --git a/src/gtkext/panel.c b/src/gtkext/panel.c
index de55917..48019dc 100644
--- a/src/gtkext/panel.c
+++ b/src/gtkext/panel.c
@@ -137,6 +137,35 @@ static void gtk_tiled_panel_finalize(GtkTiledPanel *panel)
/******************************************************************************
* *
* Paramètres : panel = panneau graphique à consulter. *
+* *
+* Description : Indique l'emplacement attendu pour un affichage. *
+* *
+* Retour : Chemin représenté ou NULL pour l'emplacement "M" par défaut. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+char *gtk_tiled_panel_get_path(const GtkTiledPanel *panel)
+{
+ char *result; /* Chemin à retourner */
+ GtkTiledPanelClass *class; /* Classe à actionner */
+
+ class = GTK_TILED_PANEL_GET_CLASS(panel);
+
+ if (class->get_default_path != NULL)
+ result = class->get_default_path(panel);
+ else
+ result = NULL;
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : panel = panneau graphique à consulter. *
* left = indication quant au côté ciblé. *
* *
* Description : Fournit les composants adaptés pour la barre de titre. *
@@ -147,7 +176,7 @@ static void gtk_tiled_panel_finalize(GtkTiledPanel *panel)
* *
******************************************************************************/
-GListStore *gtk_tiled_panel_get_title_widgets(GtkTiledPanel *panel, bool left)
+GListStore *gtk_tiled_panel_get_title_widgets(const GtkTiledPanel *panel, bool left)
{
GListStore *result; /* Composant(s) à retourner */
GtkTiledPanelClass *class; /* Classe à actionner */
diff --git a/src/gtkext/panel.h b/src/gtkext/panel.h
index d2259ef..3b0361e 100644
--- a/src/gtkext/panel.h
+++ b/src/gtkext/panel.h
@@ -38,8 +38,11 @@
DECLARE_GTYPE(GtkTiledPanel, gtk_tiled_panel, GTK, TILED_PANEL);
+/* Indique l'emplacement attendu pour un affichage. */
+char *gtk_tiled_panel_get_path(const GtkTiledPanel *);
+
/* Fournit les composants adaptés pour la barre de titre. */
-GListStore *gtk_tiled_panel_get_title_widgets(GtkTiledPanel *, bool);
+GListStore *gtk_tiled_panel_get_title_widgets(const GtkTiledPanel *, bool);
diff --git a/src/gtkext/statusstack-int.h b/src/gtkext/statusstack-int.h
index 2a9e99e..df9db35 100644
--- a/src/gtkext/statusstack-int.h
+++ b/src/gtkext/statusstack-int.h
@@ -84,6 +84,8 @@ struct _GtkStatusStack
guint network_update_tag; /* Identifiant de mise à jour */
+ GtkToggleButton *bottom_toggler; /* Bascule de panneaux inf. */
+
};
/* Gestion de barre de statut adaptable (classe) */
diff --git a/src/gtkext/statusstack.c b/src/gtkext/statusstack.c
index 76dbee8..492d888 100644
--- a/src/gtkext/statusstack.c
+++ b/src/gtkext/statusstack.c
@@ -41,6 +41,21 @@
/* -------------------------- GESTION GENERALE DES STATUTS -------------------------- */
+/* Liste des propriétés */
+
+typedef enum _StatusStackProperty {
+
+ PROP_0, /* Réservé */
+
+ PROP_SHOW_BOTTOM, /* Affichage de la zone inf. */
+
+ N_PROPERTIES
+
+} StatusStackProperty;
+
+static GParamSpec *_status_stack_properties[N_PROPERTIES] = { NULL, };
+
+
/* Initialise la classe des barres de statut améliorées. */
static void gtk_status_stack_class_init(GtkStatusStackClass *);
@@ -61,6 +76,17 @@ static gboolean gtk_status_stack_update_network_stats(GtkStatusStack *);
+/* --------------------- IMPLEMENTATION DES FONCTIONS DE CLASSE --------------------- */
+
+
+/* Met à jour une propriété d'instance GObject. */
+static void gtk_status_stack_set_property(GObject *, guint, const GValue *, GParamSpec *);
+
+/* Fournit la valeur d'une propriété d'instance GObject. */
+static void gtk_status_stack_get_property(GObject *, guint, GValue *, GParamSpec *);
+
+
+
/* -------------------- STATUT DES INFORMATIONS DE DESASSEMBLAGE -------------------- */
@@ -173,6 +199,15 @@ static void gtk_status_stack_class_init(GtkStatusStackClass *class)
object->dispose = (GObjectFinalizeFunc/* ! */)gtk_status_stack_dispose;
object->finalize = (GObjectFinalizeFunc)gtk_status_stack_finalize;
+ object->set_property = gtk_status_stack_set_property;
+ object->get_property = gtk_status_stack_get_property;
+
+ _status_stack_properties[PROP_SHOW_BOTTOM] =
+ g_param_spec_boolean("show-bottom", NULL, NULL,
+ TRUE,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
+
+ g_object_class_install_properties(object, N_PROPERTIES, _status_stack_properties);
widget = GTK_WIDGET_CLASS(class);
@@ -198,6 +233,8 @@ static void gtk_status_stack_class_init(GtkStatusStackClass *class)
gtk_widget_class_bind_template_child(widget, GtkStatusStack, net_recv_speed);
gtk_widget_class_bind_template_child(widget, GtkStatusStack, net_send_speed);
+ gtk_widget_class_bind_template_child(widget, GtkStatusStack, bottom_toggler);
+
}
@@ -497,6 +534,85 @@ static gboolean gtk_status_stack_update_network_stats(GtkStatusStack *stack)
+
+/* ---------------------------------------------------------------------------------- */
+/* IMPLEMENTATION DES FONCTIONS DE CLASSE */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+* *
+* Paramètres : object = instance d'objet GLib à mamnipuler. *
+* prop_id = identifiant de la propriété visée. *
+* value = valeur à prendre en compte. *
+* pspec = définition de la propriété. *
+* *
+* Description : Met à jour une propriété d'instance GObject. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void gtk_status_stack_set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
+{
+ GtkStatusStack *stack; /* Version spécialisée */
+
+ stack = GTK_STATUS_STACK(object);
+
+ switch (prop_id)
+ {
+ case PROP_SHOW_BOTTOM:
+ gtk_toggle_button_set_active(stack->bottom_toggler, g_value_get_boolean(value));
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+ break;
+
+ }
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : object = instance d'objet GLib à mamnipuler. *
+* prop_id = identifiant de la propriété visée. *
+* value = valeur à transmettre. [OUT] *
+* pspec = définition de la propriété. *
+* *
+* Description : Fournit la valeur d'une propriété d'instance GObject. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void gtk_status_stack_get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
+{
+ GtkStatusStack *stack; /* Version spécialisée */
+
+ stack = GTK_STATUS_STACK(object);
+
+ switch (prop_id)
+ {
+ case PROP_SHOW_BOTTOM:
+ g_value_set_boolean(value, gtk_toggle_button_get_active(stack->bottom_toggler));
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+ break;
+
+ }
+
+}
+
+
+
/* ---------------------------------------------------------------------------------- */
/* STATUT DES INFORMATIONS DE DESASSEMBLAGE */
/* ---------------------------------------------------------------------------------- */
diff --git a/src/gtkext/statusstack.ui b/src/gtkext/statusstack.ui
index a9dae28..2a6e256 100644
--- a/src/gtkext/statusstack.ui
+++ b/src/gtkext/statusstack.ui
@@ -2,6 +2,8 @@
<interface>
<template class="GtkStatusStack" parent="GtkBox">
+ <!--property name="show-bottom" bind-source="bottom_toggler" bind-property="active" bind-flags="bidirectional|sync-create"/-->
+
<child>
<object class="GtkStack" id="main">
<property name="margin-start">8</property>
@@ -201,6 +203,7 @@
<object class="GtkToggleButton" id="bottom_toggler">
<property name="has-frame">false</property>
<property name="icon-name">dock-station-bottom-symbolic</property>
+ <property name="action-name">win.toggle-bottom</property>
</object>
</child>
diff --git a/src/gui/dialogs/preferences.c b/src/gui/dialogs/preferences.c
index 68e7fd9..0369241 100644
--- a/src/gui/dialogs/preferences.c
+++ b/src/gui/dialogs/preferences.c
@@ -34,6 +34,7 @@
#include "preferences-int.h"
+#include "prefs/appearance.h"
#include "prefs/security.h"
#include "../../common/cpp.h"
#include "../../gtkext/tweak.h"
@@ -140,6 +141,8 @@ static void gtk_preferences_dialog_init(GtkPreferencesDialog *dialog)
tweak_info_t infos[] = {
TWEAK_SIMPLE_DEF("root", "Basics",
+ "security-high-symbolic", "appearance", "Appearance", GTK_TYPE_APPEARANCE_TWEAK_PANEL),
+ TWEAK_SIMPLE_DEF("root", "Basics",
"security-high-symbolic", "security", "Security", GTK_TYPE_SECURITY_TWEAK_PANEL),
};
diff --git a/src/gui/dialogs/prefs/Makefile.am b/src/gui/dialogs/prefs/Makefile.am
index fa1af96..50bc3c8 100644
--- a/src/gui/dialogs/prefs/Makefile.am
+++ b/src/gui/dialogs/prefs/Makefile.am
@@ -4,9 +4,12 @@ BUILT_SOURCES = resources.h resources.c
noinst_LTLIBRARIES = libguidialogsprefs.la
UI_FILES = \
+ appearance.ui \
security.ui
libguidialogsprefs_la_SOURCES = \
+ appearance-int.h \
+ appearance.h appearance.c \
resources.h resources.c \
security-int.h \
security.h security.c
diff --git a/src/gui/dialogs/prefs/appearance-int.h b/src/gui/dialogs/prefs/appearance-int.h
new file mode 100644
index 0000000..886a562
--- /dev/null
+++ b/src/gui/dialogs/prefs/appearance-int.h
@@ -0,0 +1,64 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * appearance-int.h - définitions internes pour la configuration des paramètres liés aux apparences
+ *
+ * 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 _GUI_DIALOGS_PREFS_APPEARANCE_INT_H
+#define _GUI_DIALOGS_PREFS_APPEARANCE_INT_H
+
+
+#include "appearance.h"
+
+
+
+/* Composant d'édition des paramètres liés aux apparences (instance) */
+struct _GtkAppearanceTweakPanel
+{
+ GtkBox parent; /* A laisser en premier */
+
+ /* Disposition des panneaux */
+
+ GSettings *tiles_settings; /* Configuration sollicitée */
+
+ GtkWidget *layout_preview; /* Zone d'aperçu de dispositon*/
+
+ GtkWidget *top_panel; /* Composant d'aperçu #1 */
+ GtkWidget *left_panel; /* Composant d'aperçu #2 */
+ GtkWidget *right_panel; /* Composant d'aperçu #3 */
+ GtkWidget *bottom_panel; /* Composant d'aperçu #4 */
+
+ GtkCheckButton *left_top_reach; /* Paramètre de disposition #1 */
+ GtkCheckButton *left_bottom_reach; /* Paramètre de disposition #2 */
+ GtkCheckButton *right_top_reach; /* Paramètre de disposition #3 */
+ GtkCheckButton *right_bottom_reach; /* Paramètre de disposition #4 */
+
+};
+
+/* Composant d'édition des paramètres liés aux apparences (classe) */
+struct _GtkAppearanceTweakPanelClass
+{
+ GtkBoxClass parent; /* A laisser en premier */
+
+};
+
+
+
+#endif /* _GUI_DIALOGS_PREFS_APPEARANCE_INT_H */
diff --git a/src/gui/dialogs/prefs/appearance.c b/src/gui/dialogs/prefs/appearance.c
new file mode 100644
index 0000000..a8585fa
--- /dev/null
+++ b/src/gui/dialogs/prefs/appearance.c
@@ -0,0 +1,251 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * appearance.c - configuration des paramètres liés aux apparences
+ *
+ * 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 "appearance.h"
+
+
+#include "appearance-int.h"
+#include "../../../gtkext/grid.h"
+#include "../../../gtkext/helpers.h"
+
+
+
+/* Procède à l'initialisation de classe des configurations. */
+static void gtk_appearance_tweak_panel_class_init(GtkAppearanceTweakPanelClass *);
+
+/* Procède à l'initialisation des configurations de sécurité. */
+static void gtk_appearance_tweak_panel_init(GtkAppearanceTweakPanel *);
+
+/* Supprime toutes les références externes. */
+static void gtk_appearance_tweak_panel_dispose(GObject *);
+
+/* Procède à la libération totale de la mémoire. */
+static void gtk_appearance_tweak_panel_finalize(GObject *);
+
+/* Réagit à un changement de paramètre de configuration. */
+static void gtk_appearance_tweak_panel_on_tiles_settings_changed(GSettings *, const gchar *, GtkAppearanceTweakPanel *);
+
+/* Change la disposition des panneaux de la fenêtre principale. */
+static void gtk_appearance_tweak_panel_on_panel_reach_toggled(GtkCheckButton *, GtkAppearanceTweakPanel *);
+
+
+/* Indique le type du composant de configuration des notes. */
+G_DEFINE_TYPE(GtkAppearanceTweakPanel, gtk_appearance_tweak_panel, GTK_TYPE_BOX);
+
+
+/******************************************************************************
+* *
+* Paramètres : class = classe GTK à initialiser. *
+* *
+* Description : Procède à l'initialisation de classe des configurations. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void gtk_appearance_tweak_panel_class_init(GtkAppearanceTweakPanelClass *class)
+{
+ GObjectClass *object; /* Plus haut niveau équivalent */
+ GtkWidgetClass *widget; /* Classe de haut niveau */
+
+ object = G_OBJECT_CLASS(class);
+
+ object->dispose = gtk_appearance_tweak_panel_dispose;
+ object->finalize = gtk_appearance_tweak_panel_finalize;
+
+ widget = GTK_WIDGET_CLASS(class);
+
+ gtk_widget_class_set_template_from_resource(widget, "/re/chrysalide/framework/gui/dialogs/prefs/appearance.ui");
+
+ gtk_widget_class_bind_template_callback_full(widget, BUILDER_CB(gtk_appearance_tweak_panel_on_panel_reach_toggled));
+
+ gtk_widget_class_bind_template_child(widget, GtkAppearanceTweakPanel, layout_preview);
+
+ gtk_widget_class_bind_template_child(widget, GtkAppearanceTweakPanel, top_panel);
+ gtk_widget_class_bind_template_child(widget, GtkAppearanceTweakPanel, left_panel);
+ gtk_widget_class_bind_template_child(widget, GtkAppearanceTweakPanel, right_panel);
+ gtk_widget_class_bind_template_child(widget, GtkAppearanceTweakPanel, bottom_panel);
+
+ gtk_widget_class_bind_template_child(widget, GtkAppearanceTweakPanel, left_top_reach);
+ gtk_widget_class_bind_template_child(widget, GtkAppearanceTweakPanel, left_bottom_reach);
+ gtk_widget_class_bind_template_child(widget, GtkAppearanceTweakPanel, right_top_reach);
+ gtk_widget_class_bind_template_child(widget, GtkAppearanceTweakPanel, right_bottom_reach);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : panel = composant GTK à initialiser. *
+* *
+* Description : Procède à l'initialisation des configurations de sécurité. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void gtk_appearance_tweak_panel_init(GtkAppearanceTweakPanel *panel)
+{
+ LayoutReachOptions options; /* Détails de disposition */
+
+ gtk_widget_init_template(GTK_WIDGET(panel));
+
+ panel->tiles_settings = g_settings_new_with_path("re.chrysalide.framework.tiledgrid",
+ "/re/chrysalide/framework/gui/tiles/");
+
+ options = g_settings_get_flags(panel->tiles_settings, "layout");
+
+ gtk_check_button_set_active(panel->left_top_reach, options & LRO_LEFT_TOP_REACH);
+ gtk_check_button_set_active(panel->left_bottom_reach, options & LRO_LEFT_BOTTOM_REACH);
+ gtk_check_button_set_active(panel->right_top_reach, options & LRO_RIGHT_TOP_REACH);
+ gtk_check_button_set_active(panel->right_bottom_reach, options & LRO_RIGHT_BOTTOM_REACH);
+
+ gtk_appearance_tweak_panel_on_tiles_settings_changed(panel->tiles_settings, "layout", panel);
+
+ g_signal_connect(panel->tiles_settings, "changed",
+ G_CALLBACK(gtk_appearance_tweak_panel_on_tiles_settings_changed), panel);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : object = instance d'objet GLib à traiter. *
+* *
+* Description : Supprime toutes les références externes. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void gtk_appearance_tweak_panel_dispose(GObject *object)
+{
+ GtkAppearanceTweakPanel *panel; /* Version spécialisée */
+
+ gtk_widget_dispose_template(GTK_WIDGET(object), GTK_TYPE_APPEARANCE_TWEAK_PANEL);
+
+ panel = GTK_APPEARANCE_TWEAK_PANEL(object);
+
+ g_clear_object(&panel->tiles_settings);
+
+ G_OBJECT_CLASS(gtk_appearance_tweak_panel_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_appearance_tweak_panel_finalize(GObject *object)
+{
+ G_OBJECT_CLASS(gtk_appearance_tweak_panel_parent_class)->finalize(object);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : settings = ensemble de paramètres connaissant une évolution. *
+* key = identifiant du paramètre ayant changé. *
+* panel = panneau de paramétrage concerné par l'appel. *
+* *
+* Description : Réagit à un changement de paramètre de configuration. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void gtk_appearance_tweak_panel_on_tiles_settings_changed(GSettings *settings, const gchar *key, GtkAppearanceTweakPanel *panel)
+{
+ LayoutReachOptions options; /* Détails de disposition */
+
+ if (strcmp(key, "layout") == 0)
+ {
+ options = g_settings_get_flags(panel->tiles_settings, "layout");
+
+ apply_tiling_grid_layout(GTK_GRID(panel->layout_preview), options, (GtkWidget *[]) {
+ panel->top_panel, panel->left_panel, panel->right_panel, panel->bottom_panel
+ });
+
+ }
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : button = composant radio dont l'état vient de basculer. *
+* panel = panneau d'édition des préférences courant. *
+* *
+* Description : Change la disposition des panneaux de la fenêtre principale. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void gtk_appearance_tweak_panel_on_panel_reach_toggled(GtkCheckButton *button, GtkAppearanceTweakPanel *panel)
+{
+ gboolean left_top_reach; /* Paramètre de disposition #1 */
+ gboolean left_bottom_reach; /* Paramètre de disposition #2 */
+ gboolean right_top_reach; /* Paramètre de disposition #3 */
+ gboolean right_bottom_reach; /* Paramètre de disposition #4 */
+ LayoutReachOptions options; /* Options à appliquer */
+
+ /* Récupération des indications */
+
+ left_top_reach = gtk_check_button_get_active(panel->left_top_reach);
+ left_bottom_reach = gtk_check_button_get_active(panel->left_bottom_reach);
+ right_top_reach = gtk_check_button_get_active(panel->right_top_reach);
+ right_bottom_reach = gtk_check_button_get_active(panel->right_bottom_reach);
+
+ /* Conversion et application */
+
+ options = LRO_NONE;
+
+ if (left_top_reach) options |= LRO_LEFT_TOP_REACH;
+ if (left_bottom_reach) options |= LRO_LEFT_BOTTOM_REACH;
+ if (right_top_reach) options |= LRO_RIGHT_TOP_REACH;
+ if (right_bottom_reach) options |= LRO_RIGHT_BOTTOM_REACH;
+
+ g_settings_set_flags(panel->tiles_settings, "layout", options);
+
+}
diff --git a/src/gui/dialogs/prefs/appearance.h b/src/gui/dialogs/prefs/appearance.h
new file mode 100644
index 0000000..916b194
--- /dev/null
+++ b/src/gui/dialogs/prefs/appearance.h
@@ -0,0 +1,41 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * appearance.h - prototypes pour la configuration des paramètres liés aux apparences
+ *
+ * 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 _GUI_DIALOGS_PREFS_APPEARANCE_H
+#define _GUI_DIALOGS_PREFS_APPEARANCE_H
+
+
+#include <gtk/gtk.h>
+
+
+#include "../../../glibext/helpers.h"
+
+
+
+#define GTK_TYPE_APPEARANCE_TWEAK_PANEL (gtk_appearance_tweak_panel_get_type())
+
+DECLARE_GTYPE(GtkAppearanceTweakPanel, gtk_appearance_tweak_panel, GTK, APPEARANCE_TWEAK_PANEL);
+
+
+
+#endif /* _GUI_DIALOGS_PREFS_APPEARANCE_H */
diff --git a/src/gui/dialogs/prefs/appearance.ui b/src/gui/dialogs/prefs/appearance.ui
new file mode 100644
index 0000000..3410115
--- /dev/null
+++ b/src/gui/dialogs/prefs/appearance.ui
@@ -0,0 +1,184 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+
+ <template class="GtkAppearanceTweakPanel" parent="GtkBox">
+
+ <property name="orientation">vertical</property>
+ <property name="margin-start">20</property>
+ <property name="margin-end">20</property>
+ <property name="margin-top">20</property>
+ <property name="margin-bottom">20</property>
+ <property name="spacing">10</property>
+
+ <!-- Disposition des panneaux -->
+
+ <child>
+ <object class="GtkLabel">
+ <property name="label">Layout</property>
+ <property name="use-markup">true</property>
+ <property name="xalign">0</property>
+ <style>
+ <class name="heading"/>
+ </style>
+ </object>
+ </child>
+
+ <child>
+ <object class="GtkLabel">
+ <property name="label">Layout defines the global panel organization of the main window.</property>
+ <property name="wrap">true</property>
+ <property name="use-markup">true</property>
+ <property name="xalign">0</property>
+ <style>
+ <class name="dim-label"/>
+ </style>
+ </object>
+ </child>
+
+
+ <child>
+ <object class="GtkBox">
+ <property name="orientation">horizontal</property>
+
+ <!-- Aperçu -->
+
+ <child>
+ <object class="GtkGrid" id="layout_preview">
+ <property name="margin-start">20</property>
+ <property name="margin-end">20</property>
+ <property name="margin-top">10</property>
+ <property name="margin-bottom">10</property>
+ <property name="row-spacing">5</property>
+ <property name="column-spacing">5</property>
+ <property name="hexpand">false</property>
+ <property name="vexpand">false</property>
+ <property name="height-request">200</property>
+ <property name="width-request">300</property>
+
+ <child>
+ <object class="GtkFrame" id="top_panel">
+ <property name="hexpand">true</property>
+ <property name="vexpand">false</property>
+ <property name="height-request">20</property>
+ <layout>
+ <property name="column">0</property>
+ <property name="row">0</property>
+ <property name="column-span">3</property>
+ </layout>
+ <style>
+ <class name="view"/>
+ </style>
+ </object>
+ </child>
+
+ <child>
+ <object class="GtkFrame" id="left_panel">
+ <property name="hexpand">false</property>
+ <property name="vexpand">true</property>
+ <property name="width-request">50</property>
+ <layout>
+ <property name="column">0</property>
+ <property name="row">1</property>
+ </layout>
+ <style>
+ <class name="view"/>
+ </style>
+ </object>
+ </child>
+
+ <child>
+ <object class="GtkFrame">
+ <property name="hexpand">true</property>
+ <property name="vexpand">true</property>
+ <layout>
+ <property name="column">1</property>
+ <property name="row">1</property>
+ </layout>
+ <style>
+ <class name="view"/>
+ </style>
+ </object>
+ </child>
+
+ <child>
+ <object class="GtkFrame" id="right_panel">
+ <property name="hexpand">false</property>
+ <property name="vexpand">true</property>
+ <property name="width-request">50</property>
+ <layout>
+ <property name="column">2</property>
+ <property name="row">1</property>
+ </layout>
+ <style>
+ <class name="view"/>
+ </style>
+ </object>
+ </child>
+
+ <child>
+ <object class="GtkFrame" id="bottom_panel">
+ <property name="hexpand">true</property>
+ <property name="vexpand">false</property>
+ <property name="height-request">50</property>
+ <layout>
+ <property name="column">0</property>
+ <property name="row">2</property>
+ <property name="column-span">3</property>
+ </layout>
+ <style>
+ <class name="view"/>
+ </style>
+ </object>
+ </child>
+
+ </object>
+ </child>
+
+ <!-- Options -->
+
+ <child>
+ <object class="GtkBox">
+ <property name="orientation">vertical</property>
+ <property name="valign">center</property>
+ <property name="spacing">10</property>
+
+ <child>
+ <object class="GtkCheckButton" id="left_top_reach">
+ <property name="label">Left panels reach the top of the window</property>
+ <property name="active">false</property>
+ <signal name="toggled" handler="gtk_appearance_tweak_panel_on_panel_reach_toggled"/>
+ </object>
+ </child>
+
+ <child>
+ <object class="GtkCheckButton" id="left_bottom_reach">
+ <property name="label">Left panels reach the bottom of the window</property>
+ <property name="active">false</property>
+ <signal name="toggled" handler="gtk_appearance_tweak_panel_on_panel_reach_toggled"/>
+ </object>
+ </child>
+
+ <child>
+ <object class="GtkCheckButton" id="right_top_reach">
+ <property name="label">Right panels reach the top of the window</property>
+ <property name="active">false</property>
+ <signal name="toggled" handler="gtk_appearance_tweak_panel_on_panel_reach_toggled"/>
+ </object>
+ </child>
+
+ <child>
+ <object class="GtkCheckButton" id="right_bottom_reach">
+ <property name="label">Right panels reach the bottom of the window</property>
+ <property name="active">false</property>
+ <signal name="toggled" handler="gtk_appearance_tweak_panel_on_panel_reach_toggled"/>
+ </object>
+ </child>
+
+ </object>
+ </child>
+
+ </object>
+ </child>
+
+ </template>
+</interface>
diff --git a/src/gui/dialogs/prefs/gresource.xml b/src/gui/dialogs/prefs/gresource.xml
index 7b18143..ad0f97f 100644
--- a/src/gui/dialogs/prefs/gresource.xml
+++ b/src/gui/dialogs/prefs/gresource.xml
@@ -1,6 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<gresources>
<gresource prefix="/re/chrysalide/framework/gui/dialogs/prefs">
+ <file compressed="true">appearance.ui</file>
<file compressed="true">security.ui</file>
</gresource>
</gresources>
diff --git a/src/gui/style.css b/src/gui/style.css
index 9078310..e21d931 100644
--- a/src/gui/style.css
+++ b/src/gui/style.css
@@ -61,3 +61,15 @@ grid.hints > box {
min-width: 130px;
}
+
+
+/* dockstation.css */
+
+.control-button {
+
+ min-height: 0;
+ min-width: 0;
+
+ padding: 6px;
+
+}
diff --git a/src/gui/window-int.h b/src/gui/window-int.h
index d79e189..b72a499 100644
--- a/src/gui/window-int.h
+++ b/src/gui/window-int.h
@@ -37,7 +37,7 @@ struct _GtkFrameworkWindow
GSettings *settings; /* Paramètres globaux */
- GtkStack *grid; /* Réceptacle de panneaux */
+ GtkTilingGrid *grid; /* Réceptacle de panneaux */
};
diff --git a/src/gui/window.c b/src/gui/window.c
index f45cec9..dbe7e87 100644
--- a/src/gui/window.c
+++ b/src/gui/window.c
@@ -29,7 +29,9 @@
#include "core/panels.h"
#include "dialogs/about.h"
#include "dialogs/preferences.h"
+#include "panels/logs.h"
#include "panels/welcome.h"
+#include "../gtkext/grid.h"
#include "../gtkext/helpers.h"
#include "../gtkext/statusstack.h"
@@ -42,10 +44,25 @@ static void gtk_framework_window_class_init(GtkFrameworkWindowClass *);
static void gtk_framework_window_init(GtkFrameworkWindow *);
/* Supprime toutes les références externes. */
-static void gtk_framework_window_dispose(GtkFrameworkWindow *);
+static void gtk_framework_window_dispose(GObject *);
/* Procède à la libération totale de la mémoire. */
-static void gtk_framework_window_finalize(GtkFrameworkWindow *);
+static void gtk_framework_window_finalize(GObject *);
+
+/* Bascule l'affichage d'un panneau de bordure. */
+static void gtk_framework_window_toggle_pannel_visibility(GtkFrameworkWindow *, TilingGridBorder);
+
+/* Réagit à une activation de bascule du panneau supérieur. */
+static void gtk_framework_window_activate_toggle_top(GSimpleAction *, GVariant *, gpointer);
+
+/* Réagit à une activation de bascule du panneau de gauche. */
+static void gtk_framework_window_activate_toggle_left(GSimpleAction *action, GVariant *, gpointer);
+
+/* Réagit à une activation de bascule du panneau de droite. */
+static void gtk_framework_window_activate_toggle_right(GSimpleAction *, GVariant *, gpointer);
+
+/* Réagit à une activation de bascule du panneau inférieur. */
+static void gtk_framework_window_activate_toggle_bottom(GSimpleAction *, GVariant *, gpointer);
/* Réagit à une activation du menu "Préférences" de la fenetre. */
static void gtk_framework_window_activate_preferences(GSimpleAction *, GVariant *, gpointer);
@@ -83,6 +100,7 @@ static void gtk_framework_window_class_init(GtkFrameworkWindowClass *class)
widget = GTK_WIDGET_CLASS(class);
+ g_type_ensure(GTK_TYPE_TILING_GRID);
g_type_ensure(GTK_TYPE_STATUS_STACK);
gtk_widget_class_set_template_from_resource(widget, "/re/chrysalide/framework/gui/window.ui");
@@ -111,7 +129,13 @@ static void gtk_framework_window_class_init(GtkFrameworkWindowClass *class)
static void gtk_framework_window_init(GtkFrameworkWindow *window)
{
+ GAction *action; /* Action mise en place */
+
static GActionEntry app_entries[] = {
+ { "toggle-top", gtk_framework_window_activate_toggle_top, NULL, NULL, NULL },
+ { "toggle-left", gtk_framework_window_activate_toggle_left, NULL, NULL, NULL },
+ { "toggle-right", gtk_framework_window_activate_toggle_right, NULL, NULL, NULL },
+ { "toggle-bottom", gtk_framework_window_activate_toggle_bottom, NULL, NULL, NULL },
{ "preferences", gtk_framework_window_activate_preferences, NULL, NULL, NULL },
{ "about", gtk_framework_window_activate_about, NULL, NULL, NULL },
};
@@ -128,12 +152,41 @@ static void gtk_framework_window_init(GtkFrameworkWindow *window)
app_entries, G_N_ELEMENTS(app_entries),
window);
+ /**
+ * Définition de l'accès aux actions pour obtenir un effet de bord sur
+ * l'accès aux boutons graphiques de déclenchement.
+ */
+
+ action = g_action_map_lookup_action(G_ACTION_MAP(window), "toggle-top");
+
+ g_object_bind_property(G_OBJECT(window->grid), "empty-top",
+ G_OBJECT(action), "enabled",
+ G_BINDING_SYNC_CREATE | G_BINDING_INVERT_BOOLEAN);
+
+ action = g_action_map_lookup_action(G_ACTION_MAP(window), "toggle-left");
+
+ g_object_bind_property(G_OBJECT(window->grid), "empty-left",
+ G_OBJECT(action), "enabled",
+ G_BINDING_SYNC_CREATE | G_BINDING_INVERT_BOOLEAN);
+
+ action = g_action_map_lookup_action(G_ACTION_MAP(window), "toggle-right");
+
+ g_object_bind_property(G_OBJECT(window->grid), "empty-right",
+ G_OBJECT(action), "enabled",
+ G_BINDING_SYNC_CREATE | G_BINDING_INVERT_BOOLEAN);
+
+ action = g_action_map_lookup_action(G_ACTION_MAP(window), "toggle-bottom");
+
+ g_object_bind_property(G_OBJECT(window->grid), "empty-bottom",
+ G_OBJECT(action), "enabled",
+ G_BINDING_SYNC_CREATE | G_BINDING_INVERT_BOOLEAN);
+
}
/******************************************************************************
* *
-* Paramètres : window = instance d'objet GLib à traiter. *
+* Paramètres : object = instance d'objet GLib à traiter. *
* *
* Description : Supprime toutes les références externes. *
* *
@@ -143,20 +196,24 @@ static void gtk_framework_window_init(GtkFrameworkWindow *window)
* *
******************************************************************************/
-static void gtk_framework_window_dispose(GtkFrameworkWindow *window)
+static void gtk_framework_window_dispose(GObject *object)
{
+ GtkFrameworkWindow *window; /* Version spécialisée */
+
+ window = GTK_FRAMEWORK_WINDOW(object);
+
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));
+ G_OBJECT_CLASS(gtk_framework_window_parent_class)->dispose(object);
}
/******************************************************************************
* *
-* Paramètres : window = instance d'objet GLib à traiter. *
+* Paramètres : object = instance d'objet GLib à traiter. *
* *
* Description : Procède à la libération totale de la mémoire. *
* *
@@ -166,9 +223,9 @@ static void gtk_framework_window_dispose(GtkFrameworkWindow *window)
* *
******************************************************************************/
-static void gtk_framework_window_finalize(GtkFrameworkWindow *window)
+static void gtk_framework_window_finalize(GObject *object)
{
- G_OBJECT_CLASS(gtk_framework_window_parent_class)->finalize(G_OBJECT(window));
+ G_OBJECT_CLASS(gtk_framework_window_parent_class)->finalize(object);
}
@@ -228,6 +285,14 @@ bool gtk_framework_window_create(GtkFrameworkWindow *window, GtkApplication *app
gtk_framework_window_add(window, panel);
+ if (1/* FIXME : first time */)
+ {
+ panel = get_framework_panel_singleton(GTK_TYPE_LOGS_PANEL);
+
+ gtk_framework_window_add(window, panel);
+
+ }
+
/* Chargement des extensions de thème */
css = gtk_css_provider_new();
@@ -257,6 +322,116 @@ bool gtk_framework_window_create(GtkFrameworkWindow *window, GtkApplication *app
/******************************************************************************
* *
+* Paramètres : window = instance de fenêtre principale à manipuler. *
+* border = sélection de la zone à considérer. *
+* *
+* Description : Bascule l'affichage d'un panneau de bordure. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void gtk_framework_window_toggle_pannel_visibility(GtkFrameworkWindow *window, TilingGridBorder border)
+{
+ bool state; /* Etat courant à basculer */
+
+ state = gtk_tiling_grid_get_visible(window->grid, border);
+
+ state = !state;
+
+ gtk_tiling_grid_set_visible(window->grid, border, state);
+
+}
+
+
+/******************************************************************************
+* *
+* 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 de bascule du panneau supérieur. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void gtk_framework_window_activate_toggle_top(GSimpleAction *action, GVariant *unused, gpointer _window)
+{
+ gtk_framework_window_toggle_pannel_visibility(_window, TGB_TOP);
+
+}
+
+
+/******************************************************************************
+* *
+* 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 de bascule du panneau de gauche. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void gtk_framework_window_activate_toggle_left(GSimpleAction *action, GVariant *unused, gpointer _window)
+{
+ gtk_framework_window_toggle_pannel_visibility(_window, TGB_LEFT);
+
+}
+
+
+/******************************************************************************
+* *
+* 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 de bascule du panneau de droite. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void gtk_framework_window_activate_toggle_right(GSimpleAction *action, GVariant *unused, gpointer _window)
+{
+ gtk_framework_window_toggle_pannel_visibility(_window, TGB_RIGHT);
+
+}
+
+
+/******************************************************************************
+* *
+* 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 de bascule du panneau inférieur. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void gtk_framework_window_activate_toggle_bottom(GSimpleAction *action, GVariant *unused, gpointer _window)
+{
+ gtk_framework_window_toggle_pannel_visibility(_window, TGB_BOTTOM);
+
+}
+
+
+/******************************************************************************
+* *
* 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. *
@@ -332,9 +507,10 @@ void gtk_framework_window_add(GtkFrameworkWindow *window, /* __steal */GtkTiledP
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));
+
+ gtk_tiling_grid_add_panel(window->grid, panel, G_OBJECT_TYPE(panel) == GTK_TYPE_WELCOME_PANEL);
+
diff --git a/src/gui/window.ui b/src/gui/window.ui
index 363ea54..1c6a89a 100644
--- a/src/gui/window.ui
+++ b/src/gui/window.ui
@@ -22,6 +22,23 @@
<child type="titlebar">
<object class="GtkHeaderBar">
+
+ <child type="start">
+ <object class="GtkToggleButton">
+ <property name="icon-name">dock-station-left-symbolic</property>
+ <property name="action-name">win.toggle-left</property>
+ <property name="active" bind-source="grid" bind-property="visible-left" bind-flags="sync-create"/>
+ </object>
+ </child>
+
+ <child type="end">
+ <object class="GtkToggleButton">
+ <property name="icon-name">dock-station-right-symbolic</property>
+ <property name="action-name">win.toggle-right</property>
+ <property name="active" bind-source="grid" bind-property="visible-right" bind-flags="sync-create"/>
+ </object>
+ </child>
+
<child type="end">
<object class="GtkMenuButton">
<property name="icon-name">open-menu-symbolic</property>
@@ -37,7 +54,7 @@
<property name="orientation">vertical</property>
<child>
- <object class="GtkStack" id="grid">
+ <object class="GtkTilingGrid" id="grid">
<property name="vexpand">TRUE</property>
</object>
</child>
@@ -50,6 +67,7 @@
<child>
<object class="GtkStatusStack" id="status">
+ <property name="show-bottom" bind-source="grid" bind-property="visible-bottom" bind-flags="sync-create"/>
</object>
</child>
diff --git a/src/schemas/re.chrysalide.framework.gschema.xml b/src/schemas/re.chrysalide.framework.gschema.xml
index 80a20db..534f735 100644
--- a/src/schemas/re.chrysalide.framework.gschema.xml
+++ b/src/schemas/re.chrysalide.framework.gschema.xml
@@ -3,6 +3,7 @@
<schema id="re.chrysalide.framework" path="/re/chrysalide/framework/">
<child schema="re.chrysalide.framework.paths" name="paths"/>
<child schema="re.chrysalide.framework.gui" name="gui"/>
+ <child schema="re.chrysalide.framework.tiledgrid" name="tiles"/>
<child schema="re.chrysalide.framework.secstorage" name="secstorage"/>
</schema>
@@ -28,6 +29,71 @@
</key>
</schema>
+ <flags id="re.chrysalide.framework.tiledgrid.LayoutReachOptions">
+ <value nick="left-top-reach" value="1"/>
+ <value nick="left-bottom-reach" value="2"/>
+ <value nick="right-top-reach" value="4"/>
+ <value nick="right-bottom-reach" value="8"/>
+ </flags>
+
+ <schema id="re.chrysalide.framework.tiledgrid">
+
+ <key name="layout" flags="re.chrysalide.framework.tiledgrid.LayoutReachOptions">
+ <default>["left-top-reach","right-top-reach"]</default>
+ <summary>Main panel layout</summary>
+ <description>Layout details describing the border panel locations</description>
+ </key>
+
+ <key name="top-visibility" type="b">
+ <default>false</default>
+ <summary>Top panel visibility</summary>
+ <description>Visbility of the panel located at the top of a tiling grid</description>
+ </key>
+
+ <key name="top-request" type="u">
+ <default>300</default>
+ <summary>Top panel height</summary>
+ <description>Height request for the panel located at the top of a tiling grid</description>
+ </key>
+
+ <key name="left-visibility" type="b">
+ <default>false</default>
+ <summary>Left panel visibility</summary>
+ <description>Visbility of the panel located at the left of a tiling grid</description>
+ </key>
+
+ <key name="left-request" type="u">
+ <default>300</default>
+ <summary>Left panel height</summary>
+ <description>Width request for the panel located at the left of a tiling grid</description>
+ </key>
+
+ <key name="right-visibility" type="b">
+ <default>false</default>
+ <summary>Right panel visibility</summary>
+ <description>Visbility of the panel located at the right of a tiling grid</description>
+ </key>
+
+ <key name="right-request" type="u">
+ <default>300</default>
+ <summary>Right panel height</summary>
+ <description>Width request for the panel located at the right of a tiling grid</description>
+ </key>
+
+ <key name="bottom-visibility" type="b">
+ <default>false</default>
+ <summary>Bottom panel visibility</summary>
+ <description>Visbility of the panel located at the bottom of a tiling grid</description>
+ </key>
+
+ <key name="bottom-request" type="u">
+ <default>250</default>
+ <summary>Bottom panel height</summary>
+ <description>Height request for the panel located at the bottom of a tiling grid</description>
+ </key>
+
+ </schema>
+
<schema id="re.chrysalide.framework.secstorage" path="/re/chrysalide/framework/secstorage/">
<key name="salt" type="ay">
<default>[]</default>