/* Chrysalide - Outil d'analyse de fichiers binaires * grid.c - composant d'affichage avec des chemins vers les composants contenus * * Copyright (C) 2018-2024 Cyrille Bagard * * This file is part of Chrysalide. * * Chrysalide is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * Chrysalide is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Chrysalide. If not, see . */ #include "grid.h" #include #include #include #include "grid-int.h" #include "helpers.h" #include "bindings/grid-enums.h" /* --------------------------- INTERFACE DU COMPOSANT GTK --------------------------- */ /* Liste des propriétés */ typedef enum _TilingGridProperty { PROP_0, /* Réservé */ PROP_LAYOUT, /* Disposition générale */ 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 } TilingGridProperty; static GParamSpec *_tiling_grid_properties[N_PROPERTIES] = { NULL, }; /* Initialise la classe des conteneurs d'affichage en tuiles. */ static void gtk_tiling_grid_class_init(GtkTilingGridClass *); /* Initialise une instance de conteneur d'affichage en tuiles. */ static void gtk_tiling_grid_init(GtkTilingGrid *); /* Supprime toutes les références externes. */ static void gtk_tiling_grid_dispose(GObject *); /* Procède à la libération totale de la mémoire. */ 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 -------------------- */ /* Initie un redimensionnement par drag-and-drop. */ static void gtk_tiling_grid_on_gesture_drag_begin(GtkGestureDrag *, double, double, GtkTilingGrid *); /* Applique l'effet d'un redimensionnement drag-and-drop donné. */ static void gtk_tiling_grid_on_gesture_drag_update(GtkTilingGrid *, TilingGridBorder, double, double); /* Actualise l'effet d'un redimensionnement drag-and-drop. */ static void gtk_tiling_grid_on_top_gesture_drag_update(GtkGestureDrag *, double, double, GtkTilingGrid *); /* Actualise l'effet d'un redimensionnement drag-and-drop. */ static void gtk_tiling_grid_on_left_gesture_drag_update(GtkGestureDrag *, double, double, GtkTilingGrid *); /* Actualise l'effet d'un redimensionnement drag-and-drop. */ static void gtk_tiling_grid_on_right_gesture_drag_update(GtkGestureDrag *, double, double, GtkTilingGrid *); /* 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 *); /* ---------------------------------------------------------------------------------- */ /* INTERFACE DU COMPOSANT GTK */ /* ---------------------------------------------------------------------------------- */ /* Détermine le type du conteneur d'affichage en tuiles nommées. */ G_DEFINE_TYPE(GtkTilingGrid, gtk_tiling_grid, GTK_TYPE_GRID) /****************************************************************************** * * * Paramètres : class = classe GTK à initialiser. * * * * Description : Initialise la classe des conteneurs d'affichage en tuiles. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ 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); gtk_widget_class_set_template_from_resource(widget, "/re/chrysalide/framework/gtkext/grid.ui"); 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, G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET(GtkTilingGridClass, station_created), NULL, NULL, g_cclosure_marshal_VOID__OBJECT, G_TYPE_NONE, 1, GTK_TYPE_WIDGET/*DOCK_STATION FIXME */); } /****************************************************************************** * * * Paramètres : grid = instance GTK à initialiser. * * * * Description : Initialise une instance de conteneur d'affichage en tuiles. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ static void gtk_tiling_grid_init(GtkTilingGrid *grid) { 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); 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 : object = instance d'objet GLib à traiter. * * * * Description : Supprime toutes les références externes. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ static void gtk_tiling_grid_dispose(GObject *object) { 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->settings); G_OBJECT_CLASS(gtk_tiling_grid_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_tiling_grid_finalize(GObject *object) { G_OBJECT_CLASS(gtk_tiling_grid_parent_class)->finalize(object); } /****************************************************************************** * * * Paramètres : - * * * * Description : Crée une nouvelle instance de conteneur avec tuiles. * * * * Retour : Composant GTK mis en place. * * * * Remarques : - * * * ******************************************************************************/ GtkWidget *gtk_tiling_grid_new(void) { GtkWidget *result; /* Instance à retourner */ result = g_object_new(GTK_TYPE_TILING_GRID, NULL); return result; } /****************************************************************************** * * * Paramètres : grid = zone d'affichage en tuiles à manipuler. * * border = sélection de la zone à considérer. * * visible = nouveau statut de visibilité à appliquer. * * * * Description : Affiche ou masque une zone du conteneur en tuiles. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ void gtk_tiling_grid_set_visible(GtkTilingGrid *grid, TilingGridBorder border, bool visible) { GtkRevealer *revealer; /* Cible visée par l'opération */ GtkDockStation *station; /* Apport d'une contrainte */ if (grid->visible[border] != visible) { grid->visible[border] = visible; 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; } gtk_revealer_set_reveal_child(revealer, visible && !gtk_dock_station_is_empty(station)); g_object_notify_by_pspec(G_OBJECT(grid), _tiling_grid_properties[PROP_VISIBLE_TOP + border]); } } /****************************************************************************** * * * Paramètres : grid = zone d'affichage en tuiles à manipuler. * * border = sélection de la zone à considérer. * * * * Description : Fournit la visibilité d'une zone du conteneur en tuiles. * * * * Retour : Visibilité de la zone considérée. * * * * Remarques : - * * * ******************************************************************************/ bool gtk_tiling_grid_get_visible(GtkTilingGrid *grid, TilingGridBorder border) { bool result; /* Statut à retourner */ result = grid->visible[border]; return result; } /****************************************************************************** * * * Paramètres : grid = zone d'affichage en tuiles à manipuler. * * panel = nouveau panneau à afficher. * * keep = indique si le panneau est à conserver présent. * * * * Description : Ajoute un panneau à un conteneur en tuiles. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ void gtk_tiling_grid_add_panel(GtkTilingGrid *grid, GtkTiledPanel *panel, bool keep) { char *path; /* Chemin visé par le panneau */ bool static_path; /* Nature du chemin à traiter */ path = gtk_tiled_panel_get_path(panel); static_path = (path == NULL); if (static_path) path = ""; 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; case 'W': if (keep) gtk_dock_station_keep_panel(grid->left_station, panel); else gtk_dock_station_add_panel(grid->left_station, panel); break; 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; case 'E': if (keep) gtk_dock_station_keep_panel(grid->right_station, panel); else gtk_dock_station_add_panel(grid->right_station, panel); break; case 'S': if (keep) gtk_dock_station_keep_panel(grid->bottom_station, panel); else gtk_dock_station_add_panel(grid->bottom_station, panel); break; default: break; } if (!static_path) free(path); } /****************************************************************************** * * * Paramètres : station = plateforme GTK ayant connu un changement. * * widget = nouvel élément à intégrer. * * grid = gestionnaire de placement en tuile concerné. * * * * Description : Réagit à une intégration ou à un retrait de panneau. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ static void gtk_tiling_grid_on_panel_un_docked(GtkDockStation *station, GtkTiledPanel *panel, GtkTilingGrid *grid) { 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 (station == grid->top_station) { border = TGB_TOP; revealer = grid->top; } 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 assert(false); 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); /** * 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 : 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 : Initie un redimensionnement par drag-and-drop. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ static void gtk_tiling_grid_on_gesture_drag_begin(GtkGestureDrag *gesture, double start_x, double start_y, GtkTilingGrid *grid) { gtk_gesture_set_state(GTK_GESTURE(gesture), GTK_EVENT_SEQUENCE_CLAIMED); grid->panning = true; } /****************************************************************************** * * * 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 : Applique l'effet d'un redimensionnement drag-and-drop donné. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ static void gtk_tiling_grid_on_gesture_drag_update(GtkTilingGrid *grid, TilingGridBorder border, double offset_x, double offset_y) { 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; case TGB_RIGHT: station = grid->right_station; break; case TGB_BOTTOM: station = grid->bottom_station; break; } /* Détermination d'une nouvelle position et application */ switch (border) { case TGB_TOP: case TGB_BOTTOM: g_object_get(G_OBJECT(station), "height-request", &request, NULL); break; case TGB_LEFT: case TGB_RIGHT: g_object_get(G_OBJECT(station), "width-request", &request, NULL); break; } switch (border) { case TGB_TOP: request += offset_y; break; case TGB_LEFT: request += offset_x; break; case TGB_RIGHT: request += -offset_x; break; case TGB_BOTTOM: request += -offset_y; break; } if (request > 0) { switch (border) { case TGB_TOP: case TGB_BOTTOM: g_object_set(G_OBJECT(station), "height-request", request, NULL); break; case TGB_LEFT: case TGB_RIGHT: g_object_set(G_OBJECT(station), "width-request", request, NULL); break; } } } /****************************************************************************** * * * 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 : Actualise l'effet d'un redimensionnement drag-and-drop. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ static void gtk_tiling_grid_on_top_gesture_drag_update(GtkGestureDrag *gesture, double offset_x, double offset_y, GtkTilingGrid *grid) { gtk_tiling_grid_on_gesture_drag_update(grid, TGB_TOP, offset_x, offset_y); } /****************************************************************************** * * * 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 : Actualise l'effet d'un redimensionnement drag-and-drop. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ static void gtk_tiling_grid_on_left_gesture_drag_update(GtkGestureDrag *gesture, double offset_x, double offset_y, GtkTilingGrid *grid) { gtk_tiling_grid_on_gesture_drag_update(grid, TGB_LEFT, offset_x, offset_y); } /****************************************************************************** * * * 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 : Actualise l'effet d'un redimensionnement drag-and-drop. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ static void gtk_tiling_grid_on_right_gesture_drag_update(GtkGestureDrag *gesture, double offset_x, double offset_y, GtkTilingGrid *grid) { gtk_tiling_grid_on_gesture_drag_update(grid, TGB_RIGHT, offset_x, offset_y); } /****************************************************************************** * * * 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 : Actualise l'effet d'un redimensionnement drag-and-drop. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ static void gtk_tiling_grid_on_bottom_gesture_drag_update(GtkGestureDrag *gesture, double offset_x, double offset_y, GtkTilingGrid *grid) { gtk_tiling_grid_on_gesture_drag_update(grid, TGB_BOTTOM, offset_x, offset_y); } /****************************************************************************** * * * 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 : Clôture un drag-and-drop de redimensionnement. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ static void gtk_tiling_grid_on_gesture_drag_end(GtkGestureDrag *gesture, double offset_x, double offset_y, GtkTilingGrid *grid) { if (!grid->panning) gtk_gesture_set_state(GTK_GESTURE(gesture), GTK_EVENT_SEQUENCE_DENIED); else grid->panning = false; } /* ---------------------------------------------------------------------------------- */ /* 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_tiling_grid_set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) { GtkTilingGrid *grid; /* Version spécialisée */ grid = GTK_TILING_GRID(object); switch (prop_id) { case PROP_LAYOUT: if (grid->layout != g_value_get_flags(value)) { grid->layout = g_value_get_flags(value); 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) }); g_object_notify_by_pspec(object, pspec); } break; gtk_tiling_grid_set_visible(grid, TGB_TOP, g_value_get_boolean(value)); break; case PROP_VISIBLE_TOP: gtk_tiling_grid_set_visible(grid, TGB_TOP, g_value_get_boolean(value)); break; case PROP_VISIBLE_LEFT: gtk_tiling_grid_set_visible(grid, TGB_LEFT, g_value_get_boolean(value)); break; case PROP_VISIBLE_RIGHT: gtk_tiling_grid_set_visible(grid, TGB_RIGHT, g_value_get_boolean(value)); break; case PROP_VISIBLE_BOTTOM: gtk_tiling_grid_set_visible(grid, TGB_BOTTOM, 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_tiling_grid_get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) { GtkTilingGrid *grid; /* Version spécialisée */ grid = GTK_TILING_GRID(object); switch (prop_id) { case PROP_EMPTY_TOP: g_value_set_boolean(value, gtk_dock_station_is_empty(grid->top_station)); break; case PROP_EMPTY_LEFT: g_value_set_boolean(value, gtk_dock_station_is_empty(grid->left_station)); break; case PROP_EMPTY_RIGHT: g_value_set_boolean(value, gtk_dock_station_is_empty(grid->right_station)); break; case PROP_EMPTY_BOTTOM: g_value_set_boolean(value, gtk_dock_station_is_empty(grid->bottom_station)); break; case PROP_VISIBLE_TOP: g_value_set_boolean(value, gtk_tiling_grid_get_visible(grid, TGB_TOP)); break; 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; 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; } } /* ---------------------------------------------------------------------------------- */ /* FORME GENERIQUE DE MISE EN DISPOSITION */ /* ---------------------------------------------------------------------------------- */ /****************************************************************************** * * * 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 : Met en place une disposition particulière de panneaux. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ void apply_tiling_grid_layout(GtkGrid *grid, LayoutReachOptions options, GtkWidget *panels[TGB_COUNT]) { 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) { top_panel_column = 1; top_panel_span--; left_panel_row = 0; } else { top_panel_column = 0; left_panel_row = 1; left_panel_span--; } if (options & LRO_LEFT_BOTTOM_REACH) { bottom_panel_column = 1; bottom_panel_span--; } else { left_panel_span--; bottom_panel_column = 0; } if (options & LRO_RIGHT_TOP_REACH) { top_panel_span--; right_panel_row = 0; } else { right_panel_row = 1; right_panel_span--; } if (options & LRO_RIGHT_BOTTOM_REACH) bottom_panel_span--; else right_panel_span--; /* Mise en application des contraintes */ 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])); 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); gtk_layout_manager_layout_changed(layout); }