diff options
Diffstat (limited to 'src/gtkext')
| -rw-r--r-- | src/gtkext/Makefile.am | 5 | ||||
| -rw-r--r-- | src/gtkext/bufferview-int.h | 49 | ||||
| -rw-r--r-- | src/gtkext/bufferview.c | 449 | ||||
| -rw-r--r-- | src/gtkext/bufferview.h | 38 | ||||
| -rw-r--r-- | src/gtkext/contentview-int.h | 52 | ||||
| -rw-r--r-- | src/gtkext/contentview.c | 532 | ||||
| -rw-r--r-- | src/gtkext/hexview-int.h | 71 | ||||
| -rw-r--r-- | src/gtkext/hexview.c | 437 | ||||
| -rw-r--r-- | src/gtkext/hexview.h | 8 | ||||
| -rw-r--r-- | src/gtkext/hexview.ui | 7 | 
10 files changed, 1134 insertions, 514 deletions
diff --git a/src/gtkext/Makefile.am b/src/gtkext/Makefile.am index e33e09e..c9445e6 100644 --- a/src/gtkext/Makefile.am +++ b/src/gtkext/Makefile.am @@ -11,8 +11,6 @@ libgtkext_la_SOURCES =						\  	easygtk.h easygtk.c						\  	gtkbinarystrip.h gtkbinarystrip.c		\  	gtkblockdisplay.h gtkblockdisplay.c		\ -	gtkbufferdisplay-int.h					\ -	gtkbufferdisplay.h gtkbufferdisplay.c	\  	gtkdockable-int.h						\  	gtkdockable.h gtkdockable.c				\  	gtkdockstation.h gtkdockstation.c		\ @@ -39,8 +37,11 @@ RES_FILES =									\  libgtkext4_la_SOURCES =						\  	area-int.h								\  	area.h area.c							\ +	bufferview-int.h						\ +	bufferview.h bufferview.c				\  	contentview-int.h						\  	contentview.h contentview.c				\ +	hexview-int.h							\  	hexview.h hexview.c						\  	resources.h resources.c diff --git a/src/gtkext/bufferview-int.h b/src/gtkext/bufferview-int.h index d02aa37..7c9c8e1 100644 --- a/src/gtkext/bufferview-int.h +++ b/src/gtkext/bufferview-int.h @@ -1,8 +1,8 @@  /* Chrysalide - Outil d'analyse de fichiers binaires - * gtkbufferdisplay-int.h - prototypes internes pour l'affichage de tampons de lignes + * bufferview-int.h - prototypes internes pour l'affichage de tampons de lignes   * - * Copyright (C) 2016-2019 Cyrille Bagard + * Copyright (C) 2016-2024 Cyrille Bagard   *   *  This file is part of Chrysalide.   * @@ -21,27 +21,38 @@   */ -#ifndef _GTK_BUFFERDISPLAY_INT_H -#define _GTK_BUFFERDISPLAY_INT_H +#ifndef _GTKEXT_BUFFERVIEW_INT_H +#define _GTKEXT_BUFFERVIEW_INT_H -#include "gtkbufferdisplay.h" +#include "bufferview.h" +#include "contentview-int.h" -#include "gtkdisplaypanel-int.h" - +#if 0  /* Réagit à un déplacement de curseur. */ -typedef bool (* notify_caret_relocation_fc) (GtkBufferDisplay *, const GdkRectangle *); +typedef bool (* notify_caret_relocation_fc) (GtkBufferView *, const GdkRectangle *); +#endif + +  /* Composant d'affichage de tampon de lignes (instance) */ -struct _GtkBufferDisplay +struct _GtkBufferView  { -    GtkDisplayPanel parent;                 /* A laisser en premier        */ +    GtkContentView parent;                  /* A laisser en premier        */ + +    GBufferView *view;                      /* Vue choisie sur un tampon   */ +    GTokenStyle *style;                     /* Centralisation des styles   */ + +    int virt_top;                           /* Première ordonnée affichée  */ + -    GBufferView *view;                      /* Vue sur le contenu affiché  */ + + +#if 0      cairo_rectangle_int_t caret;            /* Emplacement du curseur #1   */      GLineCursor *cursor;                    /* Emplacement du curseur #2   */ @@ -51,23 +62,29 @@ struct _GtkBufferDisplay      GtkBuilder *builder;                    /* Constructeur à manipuler    */      GtkWidget *bar;                         /* Barre d'outils intégrée     */ +#endif +  };  /* Composant d'affichage de tampon de lignes (classe) */ -struct _GtkBufferDisplayClass +struct _GtkBufferViewClass  { -    GtkDisplayPanelClass parent;            /* A laisser en premier        */ +    GtkContentViewClass parent;             /* A laisser en premier        */ + +#if 0      notify_caret_relocation_fc notify_caret;/* Accompagne un déplacement   */      /* Signaux */ -    void (* reach_limit) (GtkBufferDisplay *, GdkScrollDirection); +    void (* reach_limit) (GtkBufferView *, GdkScrollDirection); + +    void (* prepare_collapsing) (GtkBufferView *, gboolean); -    void (* prepare_collapsing) (GtkBufferDisplay *, gboolean); +#endif  }; -#endif  /* _GTK_BUFFERDISPLAY_INT_H */ +#endif  /* _GTKEXT_BUFFERVIEW_INT_H */ diff --git a/src/gtkext/bufferview.c b/src/gtkext/bufferview.c index 4566cc5..4a700c3 100644 --- a/src/gtkext/bufferview.c +++ b/src/gtkext/bufferview.c @@ -1,8 +1,8 @@  /* Chrysalide - Outil d'analyse de fichiers binaires - * gtkbufferdisplay.c - affichage de tampons de lignes + * bufferview.c - affichage de tampons de lignes   * - * Copyright (C) 2016-2019 Cyrille Bagard + * Copyright (C) 2016-2024 Cyrille Bagard   *   *  This file is part of Chrysalide.   * @@ -21,9 +21,418 @@   */ -#include "gtkbufferdisplay.h" +#include "bufferview.h" +#include "bufferview-int.h" + + + + + +/* ------------------------- BASES D'UN COMPOSANT GRAPHIQUE ------------------------- */ + + +/* Procède à l'initialisation de l'afficheur de tampons. */ +static void gtk_buffer_view_class_init(GtkBufferViewClass *); + +/* Procède à l'initialisation de l'afficheur de tampons. */ +static void gtk_buffer_view_init(GtkBufferView *); + +/* Supprime toutes les références externes. */ +static void gtk_buffer_view_dispose(GtkBufferView *); + +/* Procède à la libération totale de la mémoire. */ +static void gtk_buffer_view_finalize(GtkBufferView *); + + + + +/* --------------------- IMPLEMENTATION DES FONCTIONS DE CLASSE --------------------- */ + + +/* Prend acte de la taille allouée au composant d'affichage. */ +static void gtk_buffer_view_size_allocate(GtkWidget *, int, int, int); + +/* Réagit à un défilement chez une barre associée au composant. */ +static void gtk_buffer_view_adjust_scroll_value(GtkBufferView *, GtkOrientation, GtkAdjustment *); + + + +/* ---------------------------------------------------------------------------------- */ +/*                           BASES D'UN COMPOSANT GRAPHIQUE                           */ +/* ---------------------------------------------------------------------------------- */ + + +/* Détermine le type du composant d'affichage générique. */ +G_DEFINE_TYPE(GtkBufferView, gtk_buffer_view, GTK_TYPE_CONTENT_VIEW); + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : class = classe GTK à initialiser.                            * +*                                                                             * +*  Description : Procède à l'initialisation de l'afficheur de tampons.        * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void gtk_buffer_view_class_init(GtkBufferViewClass *class) +{ +    GObjectClass *object;                   /* Autre version de la classe  */ +    GtkWidgetClass *widget;                 /* Classe version Widget       */ +    GtkContentViewClass *content;           /* Base d'affichage            */ + +    object = G_OBJECT_CLASS(class); + +    object->dispose = (GObjectFinalizeFunc/* ! */)gtk_buffer_view_dispose; +    object->finalize = (GObjectFinalizeFunc)gtk_buffer_view_finalize; + +    widget = GTK_WIDGET_CLASS(class); + +    widget->size_allocate = gtk_buffer_view_size_allocate; + +    content = GTK_CONTENT_VIEW_CLASS(class); + +    content->adjust = (adjust_scroll_value_fc)gtk_buffer_view_adjust_scroll_value; + + + +#if 0 + +    widget_class->focus_in_event = gtk_buffer_view_focus; +    widget_class->focus_out_event = gtk_buffer_view_focus; +    widget_class->button_press_event = gtk_buffer_view_button_press; +    widget_class->draw = gtk_buffer_view_draw; +    widget_class->key_press_event = gtk_buffer_view_key_press; + +    panel_class = GTK_DISPLAY_PANEL_CLASS(class); + +    panel_class->compute_size = (compute_requested_size_fc)gtk_buffer_view_compute_requested_size; +    panel_class->compute_inc = (compute_scroll_inc_fc)gtk_buffer_view_compute_scroll_inc; +    panel_class->adjust = (adjust_scroll_value_fc)gtk_buffer_view_adjust_scroll_value; +    panel_class->get_coordinates = (get_coordinates_fc)gtk_buffer_view_get_cursor_coordinates; +    panel_class->get_active = (get_active_object_fc)gtk_buffer_view_get_active_object; +    panel_class->move_caret_to = (move_caret_to_fc)_gtk_buffer_view_move_caret_to; +    panel_class->cache_glance = (cache_glance_fc)gtk_buffer_view_cache_glance; + +    panel_class->get_cursor = (get_cursor_fc)gtk_buffer_view_get_cursor; + +    /* Signaux */ + +    g_signal_new("reach-limit", +                 GTK_TYPE_BUFFER_DISPLAY, +                 G_SIGNAL_RUN_LAST, +                 G_STRUCT_OFFSET(GtkBufferViewClass, reach_limit), +                 NULL, NULL, +                 g_cclosure_marshal_VOID__ENUM, +                 G_TYPE_NONE, 1, GTK_TYPE_SCROLL_TYPE); + +    g_signal_new("prepare-collapsing", +                 GTK_TYPE_BUFFER_DISPLAY, +                 G_SIGNAL_RUN_LAST, +                 G_STRUCT_OFFSET(GtkBufferViewClass, prepare_collapsing), +                 NULL, NULL, +                 g_cclosure_marshal_VOID__BOOLEAN, +                 G_TYPE_NONE, 1, G_TYPE_BOOLEAN); + +#endif + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : display = composant GTK à initialiser.                       * +*                                                                             * +*  Description : Procède à l'initialisation de l'afficheur de tampons.        * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void gtk_buffer_view_init(GtkBufferView *view) +{ +    view->view = NULL; +    view->style = g_token_style_new(GTK_WIDGET(view)); + +    view->virt_top = 0; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : display = instance d'objet GLib à traiter.                   * +*                                                                             * +*  Description : Supprime toutes les références externes.                     * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void gtk_buffer_view_dispose(GtkBufferView *view) +{ +#if 0 + +    if (display->caret_timer != 0) +    { +        g_source_remove(display->caret_timer); +        display->caret_timer = 0; +    } + +    g_clear_object(&display->cursor); + +    g_clear_object(&display->builder); +    g_clear_object(&display->bar); + +#endif + + + + +    g_clear_object(&view->view); +    g_clear_object(&view->style); + +    G_OBJECT_CLASS(gtk_buffer_view_parent_class)->dispose(G_OBJECT(view)); + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : display = instance d'objet Gtk à traiter.                    * +*                                                                             * +*  Description : Procède à la libération totale de la mémoire.                * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void gtk_buffer_view_finalize(GtkBufferView *view) +{ +    G_OBJECT_CLASS(gtk_buffer_view_parent_class)->finalize(G_OBJECT(view)); + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : view = composant GTK à consulter.                            * +*                                                                             * +*  Description : Fournit la vue associée au tampon de lignes courant.         * +*                                                                             * +*  Retour      : Vue mise en place.                                           * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +GBufferView *gtk_buffer_view_get_view(const GtkBufferView *view) +{ +    GBufferView *result;                    /* Instance à retourner        */ + +    result = view->view; + +    ref_object(result); + +    return result; + +} + + + + + + + + + + + + + + + + + + + + + + + + +/* ---------------------------------------------------------------------------------- */ +/*                       IMPLEMENTATION DES FONCTIONS DE CLASSE                       */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : widget = composant GTK à examiner.                           * +*                width  = largeur affectée au composant graphique.            * +*                height = hauteur affectée au composant graphique.            * +*                baseline = ligne de base affectée au composant graphique.    * +*                                                                             * +*  Description : Prend acte de la taille allouée au composant d'affichage.    * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void gtk_buffer_view_size_allocate(GtkWidget *widget, int width, int height, int baseline) +{ +    GtkContentView *base;                   /* Version de base             */ +    GtkBufferView *view;                    /* Version spécialisée         */ +    int full_width;                         /* Largeur idéale complète     */ +    int full_height;                        /* Hauteur idéale complète     */ +    int *min_widths;                        /* Largeurs minimales imposées */ +    int *min_heights;                       /* Hauteurs minimales imposées */ +    size_t i;                               /* Boucle de parcours          */ +    int upper;                              /* Valeur maximale retenue     */ +    GtkAdjustment *adj;                     /* Ajustement à mettre à jour  */ +    int line_height;                        /* Hauteur d'une ligne unique  */ +    int lines_per_page;                     /* Nombre de lignes sur l'écran*/ +    GtkAllocation allocated;                /* Zone allouée                */ +    GWidthTracker *tracker;                 /* Collecteur de largeurs      */ + +    base = GTK_CONTENT_VIEW(widget); +    view = GTK_BUFFER_VIEW(widget); + +    /* Détermination de la surface idéale à afficher */ + +    g_buffer_view_compute_size(view->view, &full_width, &full_height); + +    min_widths = alloca(base->sub_count * sizeof(int)); +    min_heights = alloca(base->sub_count * sizeof(int)); + +    for (i = 0; i < base->sub_count; i++) +    { +        gtk_widget_measure(base->sub_children[i], GTK_ORIENTATION_HORIZONTAL, -1, +                           &min_widths[i], NULL, NULL, NULL); +        full_width += min_widths[i]; + +        gtk_widget_measure(base->sub_children[i], GTK_ORIENTATION_VERTICAL, -1, +                           &min_heights[i], NULL, NULL, NULL); +        full_height += min_heights[i]; + +    } + +    /* Définition des besoins en défilement */ + +    upper = MAX(width, full_width); + +    adj = base->adjustments[GTK_ORIENTATION_HORIZONTAL]; + +    gtk_adjustment_configure(adj, +                             gtk_adjustment_get_value(adj), +                             0, upper, +                             0.1 * width, +                             0.9 * width, +                             width); + +    upper = MAX(height, full_height); + +    line_height = g_token_style_get_line_height(view->style); + +    lines_per_page = height / line_height; +    if (lines_per_page == 0) lines_per_page = 1; + +    adj = base->adjustments[GTK_ORIENTATION_VERTICAL]; + +    gtk_adjustment_configure(adj, +                             gtk_adjustment_get_value(adj), +                             0, upper, +                             line_height * lines_per_page, +                             line_height * lines_per_page * 10, +                             height); + +    /* Placement des composants d'affichage */ + +    tracker = g_buffer_view_get_tracker(view->view); + +    allocated.x = 0; +    allocated.y = 0; +    allocated.height = height; + +    for (i = 0; i < base->sub_count; i++) +    { +        allocated.width = g_width_tracker_get_column_min_width(tracker, i); + +        if ((i + 1) == base->sub_count && allocated.width < (width - allocated.x)) +            allocated.width = width - allocated.x; + +        gtk_widget_size_allocate(base->sub_children[i], &allocated, baseline); + +        allocated.x += allocated.width; + +    } + +    unref_object(tracker); + +    /* Mise à jour des éléments plus internes */ + +    GTK_WIDGET_CLASS(gtk_buffer_view_parent_class)->size_allocate(widget, width, height, baseline); + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : view        = panneau d'affichage concerné.                  * +*                orientation = indication sur le défilement à traiter.        * +*                adj         = nouvel ajustement à prendre en compte.         * +*                                                                             * +*  Description : Réagit à un défilement chez une barre associée au composant. * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void gtk_buffer_view_adjust_scroll_value(GtkBufferView *view, GtkOrientation orientation, GtkAdjustment *adj) +{ +    GtkContentView *base;                   /* Version de base             */ +    size_t i;                               /* Boucle de parcours          */ + +    base = GTK_CONTENT_VIEW(view); + +    if (orientation == GTK_ORIENTATION_HORIZONTAL) +        printf("TODO...\n"); + +    else +    { +        view->virt_top = gtk_adjustment_get_value(adj); + +        for (i = 0; i < base->sub_count; i++) +            gtk_widget_queue_draw(base->sub_children[i]); + +    } + +} + + + + + + + + +#if 0 +  #include <assert.h> @@ -38,16 +447,16 @@  /* Procède à l'initialisation de l'afficheur de tampons. */ -static void gtk_buffer_display_class_init(GtkBufferDisplayClass *); +//static void gtk_buffer_display_class_init(GtkBufferDisplayClass *);  /* Procède à l'initialisation de l'afficheur de tampons. */ -static void gtk_buffer_display_init(GtkBufferDisplay *); +//static void gtk_buffer_display_init(GtkBufferDisplay *);  /* Supprime toutes les références externes. */ -static void gtk_buffer_display_dispose(GtkBufferDisplay *); +//static void gtk_buffer_display_dispose(GtkBufferDisplay *);  /* Procède à la libération totale de la mémoire. */ -static void gtk_buffer_display_finalize(GtkBufferDisplay *); +//static void gtk_buffer_display_finalize(GtkBufferDisplay *);  /* Intègre le focus dans le rendu du composant. */  static gboolean gtk_buffer_display_focus(GtkWidget *, GdkEventFocus *); @@ -882,30 +1291,6 @@ static GLineCursor *gtk_buffer_display_get_cursor(const GtkBufferDisplay *displa  } -/****************************************************************************** -*                                                                             * -*  Paramètres  : display = composant GTK à consulter.                         * -*                                                                             * -*  Description : Fournit la vue associée au tampon de lignes courant.         * -*                                                                             * -*  Retour      : Vue mise en place.                                           * -*                                                                             * -*  Remarques   : -                                                            * -*                                                                             * -******************************************************************************/ - -GBufferView *gtk_buffer_display_get_view(const GtkBufferDisplay *display) -{ -    GBufferView *result;                    /* Instance à retourner        */ - -    result = display->view; - -    g_object_ref(G_OBJECT(result)); - -    return result; - -} -  /* ---------------------------------------------------------------------------------- */ @@ -1437,3 +1822,5 @@ static gboolean on_block_bar_collapsing_leave(GtkWidget *widget, GdkEventCrossin      return FALSE;  } + +#endif diff --git a/src/gtkext/bufferview.h b/src/gtkext/bufferview.h index 8f2d63c..1bdfc80 100644 --- a/src/gtkext/bufferview.h +++ b/src/gtkext/bufferview.h @@ -1,8 +1,8 @@  /* Chrysalide - Outil d'analyse de fichiers binaires - * gtkbufferdisplay.h - prototypes pour l'affichage de tampons de lignes + * bufferview.h - prototypes pour l'affichage de tampons de lignes   * - * Copyright (C) 2016-2019 Cyrille Bagard + * Copyright (C) 2016-2024 Cyrille Bagard   *   *  This file is part of Chrysalide.   * @@ -21,41 +21,36 @@   */ -#ifndef _GTKEXT_GTKBUFFER_DISPLAY_H -#define _GTKEXT_GTKBUFFER_DISPLAY_H +#ifndef _GTKEXT_BUFFERVIEW_H +#define _GTKEXT_BUFFERVIEW_H -#include <glib-object.h>  #include <gtk/gtk.h>  #include "../glibext/bufferview.h" +#include "../glibext/helpers.h" -#define GTK_TYPE_BUFFER_DISPLAY             (gtk_buffer_display_get_type()) -#define GTK_BUFFER_DISPLAY(obj)             (G_TYPE_CHECK_INSTANCE_CAST((obj), GTK_TYPE_BUFFER_DISPLAY, GtkBufferDisplay)) -#define GTK_BUFFER_DISPLAY_CLASS(klass)     (G_TYPE_CHECK_CLASS_CAST((klass), GTK_TYPE_BUFFER_DISPLAY, GtkBufferDisplayClass)) -#define GTK_IS_BUFFER_DISPLAY(obj)          (G_TYPE_CHECK_INSTANCE_TYPE((obj), GTK_TYPE_BUFFER_DISPLAY)) -#define GTK_IS_BUFFER_DISPLAY_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE((klass), GTK_TYPE_BUFFER_DISPLAY)) -#define GTK_BUFFER_DISPLAY_GET_CLASS(obj)   (G_TYPE_INSTANCE_GET_CLASS((obj), GTK_TYPE_BUFFER_VIEW, GtkBufferDisplayClass)) +#define GTK_TYPE_BUFFER_VIEW (gtk_buffer_view_get_type()) +DECLARE_GTYPE(GtkBufferView, gtk_buffer_view, GTK, BUFFER_VIEW); -/* Composant d'affichage de tampon de lignes (instance) */ -typedef struct _GtkBufferDisplay GtkBufferDisplay; -/* Composant d'affichage de tampon de lignes (classe) */ -typedef struct _GtkBufferDisplayClass GtkBufferDisplayClass; + +/* Fournit la vue associée au tampon de lignes courant. */ +GBufferView *gtk_buffer_view_get_view(const GtkBufferView *); + -/* Détermine le type du composant d'affichage de tampon de lignes. */ -GType gtk_buffer_display_get_type(void); -/* Fournit la vue associée au tampon de lignes courant. */ -GBufferView *gtk_buffer_display_get_view(const GtkBufferDisplay *); + +#if 0 +  /* ------------------------------ ANIMATION DU CURSEUR ------------------------------ */ @@ -73,6 +68,9 @@ bool gtk_buffer_display_move_caret_to(GtkBufferDisplay *, bool, gint *);  /* Ajoute une nouvelle barre d'outils pour bloc au composant. */  void gtk_buffer_display_add_block_bar(GtkBufferDisplay *); +#endif + + -#endif  /* _GTKEXT_GTKBUFFER_DISPLAY_H */ +#endif  /* _GTKEXT_BUFFERVIEW_H */ diff --git a/src/gtkext/contentview-int.h b/src/gtkext/contentview-int.h index 25c9ddb..01c0c7a 100644 --- a/src/gtkext/contentview-int.h +++ b/src/gtkext/contentview-int.h @@ -28,11 +28,19 @@  #include "contentview.h" +#include "../glibext/bufferview.h"  #include "../glibext/tokenstyle.h" +/* Réagit à un défilement chez une barre associée au composant. */ +typedef void (* adjust_scroll_value_fc) (GtkContentView *, GtkOrientation, GtkAdjustment *); + + + + +  #if 0  #include <stdbool.h> @@ -52,10 +60,10 @@  typedef void (* compute_requested_size_fc) (GtkDisplayPanel *, gint *, gint *);  /* Détermine la taille des bonds lors de défilements. */ -typedef void (* compute_scroll_inc_fc) (GtkDisplayPanel *, gint, GtkOrientation, gdouble *, gdouble *); +//typedef void (* compute_scroll_inc_fc) (GtkDisplayPanel *, gint, GtkOrientation, gdouble *, gdouble *);  /* Réagit à un défilement chez une barre associée au composant. */ -typedef void (* adjust_scroll_value_fc) (GtkDisplayPanel *, GtkAdjustment *, GtkOrientation); +//typedef void (* adjust_scroll_value_fc) (GtkDisplayPanel *, GtkAdjustment *, GtkOrientation);  /* Ajuste au besoin la zone affichée pour un curseur. */  typedef void (* prepare_for_cursor_fc) (GtkDisplayPanel *, const GLineCursor *); @@ -94,15 +102,18 @@ struct _GtkContentView  {      GtkWidget parent;                       /* A laisser en premier        */ +    GtkAdjustment *adjustments[2];          /* Barres de défilement h. & v.*/ +    GtkScrollablePolicy scroll_policies[2]; /* Politiques de défilement    */ +      GDisplayOptions *options;               /* Options de rendu            */ -    GTokenStyle *style;                     /* Centralisation des styles   */ -#if 0 +    /* Propriété des implémentations */ -    GtkAdjustment *hadjustment;             /* Barre de défilement horiz.  */ -    GtkAdjustment *vadjustment;             /* Barre de défilement vert.   */ -    GtkScrollablePolicy hscroll_policy;     /* Politique horizontale       */            -    GtkScrollablePolicy vscroll_policy;     /* Politique verticale         */            +    GtkWidget * const *sub_children;        /* Composants embarqués        */ +    size_t sub_count;                       /* Quantité de ces composants  */ + + +#if 0      double scale;                           /* Echelle de l'affichage      */ @@ -121,13 +132,14 @@ struct _GtkContentView  /* Composant d'affichage générique (classe) */  struct _GtkContentViewClass  { -    GtkFixedClass parent;                   /* A laisser en premier        */ +    GtkWidgetClass parent;                  /* A laisser en premier        */  #if 0 -      compute_requested_size_fc compute_size; /* Calcul de la taille requise */ -    compute_scroll_inc_fc compute_inc;      /* Calcul des bonds            */ +#endif      adjust_scroll_value_fc adjust;          /* Réaction à un défilement    */ + +#if 0      prepare_for_cursor_fc prepare;          /* Préparation de zone affichée*/      get_coordinates_fc get_coordinates;     /* Conversion adresse <-> pos. */      get_active_object_fc get_active;        /* Infos sur l'objet actif     */ @@ -149,20 +161,20 @@ struct _GtkContentViewClass  }; -#if 0 -  /* Propriétés propres au composant d'affichage */ -typedef enum _ViewPanelProps +typedef enum _ContentViewProps  { -    VPP_0, -    VPP_HADJUSTMENT, -    VPP_VADJUSTMENT, -    VPP_HSCROLL_POLICY, -    VPP_VSCROLL_POLICY +    CVP_0, +    CVP_HADJUSTMENT, +    CVP_VADJUSTMENT, +    CVP_HSCROLL_POLICY, +    CVP_VSCROLL_POLICY -} ViewPanelProps; +} ContentViewProps; +#if 0 +  /* Définit un chemin décrivant la bordure autour du panneau. */  void gtk_display_panel_define_border_path(GtkDisplayPanel *, cairo_t *, const GtkAllocation *); diff --git a/src/gtkext/contentview.c b/src/gtkext/contentview.c index 4b7f79d..77bbb7b 100644 --- a/src/gtkext/contentview.c +++ b/src/gtkext/contentview.c @@ -59,22 +59,51 @@ static void gtk_content_view_dispose(GtkContentView *);  /* Procède à la libération totale de la mémoire. */  static void gtk_content_view_finalize(GtkContentView *); + + + + +/* --------------------- IMPLEMENTATION DES FONCTIONS DE CLASSE --------------------- */ + + +/* Définit une propriété du composant d'affichage. */ +static void gtk_content_view_set_property(GObject *, guint, const GValue *, GParamSpec *); + +/* Se débarrsse d'un ajustement pour un défilement donné. */ +static void _gtk_content_view_disconnect_adjustment(GtkContentView *, GtkOrientation); + +/* S'associe à un ajustement pour un défilement donné. */ +static void _gtk_content_view_set_adjustment(GtkContentView *, GtkOrientation, GtkAdjustment *); + +/* Réagit à un défilement chez une barre associée au composant. */ +static void _gtk_content_view_adjustment_value_changed(GtkAdjustment *, GtkContentView *); + +/* Fournit une propriété du composant d'affichage. */ +static void gtk_content_view_get_property(GObject *, guint, GValue *, GParamSpec *); + +/* Fournit les mesures mainimale et idéale du composant. */ +static void gtk_content_view_measure(GtkWidget *, GtkOrientation, int, int *, int *, int *, int *); + + + + +  #if 0  /* Définit une propriété du composant d'affichage. */ -static void gtk_display_panel_set_property(GObject *, guint, const GValue *, GParamSpec *); +//static void gtk_display_panel_set_property(GObject *, guint, const GValue *, GParamSpec *);  /* Fournit une propriété du composant d'affichage. */ -static void gtk_display_panel_get_property(GObject *, guint, GValue *, GParamSpec *); +//static void gtk_display_panel_get_property(GObject *, guint, GValue *, GParamSpec *);  /* Détruit un composant d'affichage. */ -static void gtk_display_panel_destroy(GtkWidget *); +//static void gtk_display_panel_destroy(GtkWidget *);  /* Encadre la construction graphique initiale de l'affichage. */  static void gtk_display_panel_realize(GtkWidget *);  /* S'adapte à la surface concédée par le composant parent. */ -static void gtk_display_panel_size_allocate(GtkWidget *, GtkAllocation *); +//static void gtk_display_panel_size_allocate(GtkWidget *, GtkAllocation *);  /* Fournit la hauteur idéale pour le composant d'affichage. */  static void gtk_display_panel_get_preferred_height(GtkWidget *, gint *, gint *); @@ -83,22 +112,22 @@ static void gtk_display_panel_get_preferred_height(GtkWidget *, gint *, gint *);  static void gtk_display_panel_get_preferred_width(GtkWidget *, gint *, gint *);  /* Détermine la taille des bonds lors de défilements. */ -static void gtk_display_panel_compute_scroll_inc(GtkDisplayPanel *, gint, GtkOrientation, gdouble *, gdouble *); +//static void gtk_display_panel_compute_scroll_inc(GtkDisplayPanel *, gint, GtkOrientation, gdouble *, gdouble *);  /* Détermine la taille allouée pour le contenu. */  static void gtk_display_panel_compute_allocation(GtkDisplayPanel *, GtkAllocation *);  /* Se débarrsse d'un ajustement pour un défilement donné. */ -static void gtk_display_panel_disconnect_adjustment(GtkDisplayPanel *, GtkOrientation); +//static void gtk_display_panel_disconnect_adjustment(GtkDisplayPanel *, GtkOrientation);  /* S'associe à un ajustement pour un défilement donné. */ -static void gtk_display_panel_set_adjustment(GtkDisplayPanel *, GtkOrientation, GtkAdjustment *); +//static void gtk_display_panel_set_adjustment(GtkDisplayPanel *, GtkOrientation, GtkAdjustment *);  /* Ajuste les paramètres de défilement du composant. */ -static void gtk_display_panel_update_adjustment(GtkDisplayPanel *, GtkOrientation); +//static void gtk_display_panel_update_adjustment(GtkDisplayPanel *, GtkOrientation);  /* Réagit à un défilement chez une barre associée au composant.*/ -static void gtk_display_panel_adjustment_value_changed(GtkAdjustment *, GtkDisplayPanel *); +//static void gtk_display_panel_adjustment_value_changed(GtkAdjustment *, GtkDisplayPanel *); @@ -136,8 +165,8 @@ G_DEFINE_TYPE_WITH_CODE(GtkDisplayPanel, gtk_display_panel, GTK_TYPE_FIXED,  /* Détermine le type du composant d'affichage générique. */ -G_DEFINE_TYPE(GtkContentView, gtk_content_view, GTK_TYPE_WIDGET); - +G_DEFINE_TYPE_WITH_CODE(GtkContentView, gtk_content_view, GTK_TYPE_WIDGET, +                        G_IMPLEMENT_INTERFACE(GTK_TYPE_SCROLLABLE, NULL));  /****************************************************************************** @@ -155,35 +184,43 @@ G_DEFINE_TYPE(GtkContentView, gtk_content_view, GTK_TYPE_WIDGET);  static void gtk_content_view_class_init(GtkContentViewClass *class)  {      GObjectClass *object;                   /* Plus haut niveau équivalent */ -    //GtkWidgetClass *widget;                 /* Classe de haut niveau       */ -    //GtkContentViewClass *panel;            /* Classe de lus bas niveau    */ +    GtkWidgetClass *widget;                 /* Classe de haut niveau       */      object = G_OBJECT_CLASS(class); +    object->set_property = gtk_content_view_set_property; +    object->get_property = gtk_content_view_get_property;      object->dispose = (GObjectFinalizeFunc/* ! */)gtk_content_view_dispose;      object->finalize = (GObjectFinalizeFunc)gtk_content_view_finalize; +    /* Implémentation de l'interface "GtkScrollable" */ +    g_object_class_override_property(object, CVP_HADJUSTMENT, "hadjustment"); +    g_object_class_override_property(object, CVP_VADJUSTMENT, "vadjustment"); +    g_object_class_override_property(object, CVP_HSCROLL_POLICY, "hscroll-policy"); +    g_object_class_override_property(object, CVP_VSCROLL_POLICY, "vscroll-policy"); + + + + + +    widget = GTK_WIDGET_CLASS(class); + +    widget->measure = gtk_content_view_measure; + + + +  #if 0 -    object->set_property = gtk_display_panel_set_property; -    object->get_property = gtk_display_panel_get_property; -    /* Implémentation de l'interface "GtkScrollable" */ -    g_object_class_override_property(object, VPP_HADJUSTMENT, "hadjustment"); -    g_object_class_override_property(object, VPP_VADJUSTMENT, "vadjustment"); -    g_object_class_override_property(object, VPP_HSCROLL_POLICY, "hscroll-policy"); -    g_object_class_override_property(object, VPP_VSCROLL_POLICY, "vscroll-policy");      widget = GTK_WIDGET_CLASS(class); -    widget->destroy = gtk_display_panel_destroy; +    //widget->destroy = gtk_display_panel_destroy;      widget->realize = gtk_display_panel_realize;      widget->size_allocate = gtk_display_panel_size_allocate;      widget->get_preferred_height = gtk_display_panel_get_preferred_height;      widget->get_preferred_width = gtk_display_panel_get_preferred_width; -    panel = GTK_DISPLAY_PANEL_CLASS(class); - -    panel->compute_inc = gtk_display_panel_compute_scroll_inc;      /* Signaux */ @@ -214,8 +251,13 @@ static void gtk_content_view_class_init(GtkContentViewClass *class)  static void gtk_content_view_init(GtkContentView *view)  { +    view->adjustments[GTK_ORIENTATION_HORIZONTAL] = NULL; +    view->adjustments[GTK_ORIENTATION_VERTICAL] = NULL; + +    view->scroll_policies[GTK_ORIENTATION_HORIZONTAL] = GTK_POLICY_AUTOMATIC; +    view->scroll_policies[GTK_ORIENTATION_VERTICAL] = GTK_POLICY_AUTOMATIC; +      view->options = NULL; -    view->style = g_token_style_new(GTK_WIDGET(view)); @@ -272,13 +314,16 @@ static void gtk_display_panel_loaded_interface_init(GLoadedPanelInterface *iface  static void gtk_content_view_dispose(GtkContentView *view)  { +    _gtk_content_view_disconnect_adjustment(view, GTK_ORIENTATION_HORIZONTAL); +    _gtk_content_view_disconnect_adjustment(view, GTK_ORIENTATION_VERTICAL); + +    g_clear_object(&view->adjustments[GTK_ORIENTATION_HORIZONTAL]); +    g_clear_object(&view->adjustments[GTK_ORIENTATION_VERTICAL]); +      g_clear_object(&view->options); -    g_clear_object(&view->style);      /* -    g_clear_object(&panel->hadjustment); -    g_clear_object(&panel->vadjustment);      g_clear_object(&panel->options); @@ -309,7 +354,16 @@ static void gtk_content_view_finalize(GtkContentView *view)  } -#if 0 + + + + + +/* ---------------------------------------------------------------------------------- */ +/*                       IMPLEMENTATION DES FONCTIONS DE CLASSE                       */ +/* ---------------------------------------------------------------------------------- */ + +  /******************************************************************************  *                                                                             *  *  Paramètres  : object  = instance de composant GTK à manipuler.             * @@ -325,25 +379,25 @@ static void gtk_content_view_finalize(GtkContentView *view)  *                                                                             *  ******************************************************************************/ -static void gtk_display_panel_set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) +static void gtk_content_view_set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)  { -    GtkDisplayPanel *panel;                 /* Autre vision de l'instance  */ +    GtkContentView *view;                   /* Autre vision de l'instance  */ -    panel = GTK_DISPLAY_PANEL(object); +    view = GTK_CONTENT_VIEW(object);      switch (prop_id)      { -        case VPP_HADJUSTMENT: -            gtk_display_panel_set_adjustment(panel, GTK_ORIENTATION_HORIZONTAL, g_value_get_object(value)); +        case CVP_HADJUSTMENT: +            _gtk_content_view_set_adjustment(view, GTK_ORIENTATION_HORIZONTAL, g_value_get_object(value));              break; -        case VPP_VADJUSTMENT: -            gtk_display_panel_set_adjustment(panel, GTK_ORIENTATION_VERTICAL, g_value_get_object(value)); +        case CVP_VADJUSTMENT: +            _gtk_content_view_set_adjustment(view, GTK_ORIENTATION_VERTICAL, g_value_get_object(value));              break; -        case VPP_HSCROLL_POLICY: +        case CVP_HSCROLL_POLICY:              //viewport->priv->hscroll_policy = g_value_get_enum (value);              //gtk_widget_queue_resize (GTK_WIDGET (viewport));              break; -        case VPP_VSCROLL_POLICY: +        case CVP_VSCROLL_POLICY:              //viewport->priv->vscroll_policy = g_value_get_enum (value);              //gtk_widget_queue_resize (GTK_WIDGET (viewport));              break; @@ -357,6 +411,105 @@ static void gtk_display_panel_set_property(GObject *object, guint prop_id, const  /******************************************************************************  *                                                                             * +*  Paramètres  : view        = composant GTK d'affichage à mettre à jour.     * +*                orientation = indication sur le défilement à traiter.        * +*                                                                             * +*  Description : Se débarrsse d'un ajustement pour un défilement donné.       * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void _gtk_content_view_disconnect_adjustment(GtkContentView *view, GtkOrientation orientation) +{ +    GtkAdjustment **adjp;                   /* Ajustement à manipuler      */ + +    adjp = &view->adjustments[orientation]; + +    if (*adjp != NULL) +    { +        g_signal_handlers_disconnect_by_func(*adjp, _gtk_content_view_adjustment_value_changed, view); +        g_clear_object(adjp); +    } + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : view        = composant GTK d'affichage à mettre à jour.     * +*                orientation = indication sur le défilement à traiter.        * +*                adj         = nouvel ajustement à prendre en compte.         * +*                                                                             * +*  Description : S'associe à un ajustement pour un défilement donné.          * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void _gtk_content_view_set_adjustment(GtkContentView *view, GtkOrientation orientation, GtkAdjustment *adj) +{ +    GtkAdjustment **adjp;                   /* Ajustement à manipuler      */ + +    adjp = &view->adjustments[orientation]; + +    /* S'il n'y a rien à faire... */ +    if (adj != NULL && adj == *adjp) +        return; + +    if (adj == NULL) +        adj = gtk_adjustment_new(0.0, 0.0, 0.0, 0.0, 0.0, 0.0); +    else +        ref_object(adj); + +    _gtk_content_view_disconnect_adjustment(view, orientation); + +    *adjp = adj; + +    g_signal_connect(adj, "value-changed", G_CALLBACK(_gtk_content_view_adjustment_value_changed), view); + +    gtk_widget_queue_allocate(GTK_WIDGET(view)); + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : adj  = défilement dont une valeur a changé.                  * +*                view = panneau d'affichage concerné.                         * +*                                                                             * +*  Description : Réagit à un défilement chez une barre associée au composant. * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void _gtk_content_view_adjustment_value_changed(GtkAdjustment *adj, GtkContentView *view) +{ +    GtkOrientation orientation;             /* Indification de la barre    */ +    GtkContentViewClass *class;             /* Classe de l'instance        */ + +    if (adj == view->adjustments[GTK_ORIENTATION_HORIZONTAL]) +        orientation = GTK_ORIENTATION_HORIZONTAL; +    else +        orientation = GTK_ORIENTATION_VERTICAL; + +    class = GTK_CONTENT_VIEW_GET_CLASS(view); + +    if (class->adjust != NULL) +        class->adjust(view, orientation, adj); + +} + + +/****************************************************************************** +*                                                                             *  *  Paramètres  : object  = instance de composant GTK à manipuler.             *  *                prop_id = identifiant de la propriété concernée.             *  *                value   = valeur à renvoyer.                                 * @@ -370,25 +523,25 @@ static void gtk_display_panel_set_property(GObject *object, guint prop_id, const  *                                                                             *  ******************************************************************************/ -static void gtk_display_panel_get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) +static void gtk_content_view_get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)  { -    GtkDisplayPanel *panel;                 /* Autre vision de l'instance  */ +    GtkContentView *view;                   /* Autre vision de l'instance  */ -    panel = GTK_DISPLAY_PANEL(object); +    view = GTK_CONTENT_VIEW(object);      switch (prop_id)      { -        case VPP_HADJUSTMENT: -            g_value_set_object(value, panel->hadjustment); +        case CVP_HADJUSTMENT: +            g_value_set_object(value, view->adjustments[GTK_ORIENTATION_HORIZONTAL]);              break; -        case VPP_VADJUSTMENT: -            g_value_set_object(value, panel->vadjustment); +        case CVP_VADJUSTMENT: +            g_value_set_object(value, view->adjustments[GTK_ORIENTATION_VERTICAL]);              break; -        case VPP_HSCROLL_POLICY: -            g_value_set_enum(value, panel->hscroll_policy); +        case CVP_HSCROLL_POLICY: +            g_value_set_enum(value, view->scroll_policies[GTK_ORIENTATION_HORIZONTAL]);              break; -        case VPP_VSCROLL_POLICY: -            g_value_set_enum(value, panel->vscroll_policy); +        case CVP_VSCROLL_POLICY: +            g_value_set_enum(value, view->scroll_policies[GTK_ORIENTATION_VERTICAL]);              break;          default:              G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); @@ -400,6 +553,88 @@ static void gtk_display_panel_get_property(GObject *object, guint prop_id, GValu  /******************************************************************************  *                                                                             * +*  Paramètres  : widget       = composant GTK à examiner.                     * +*                orientation  = direction à observer pour les calculs.        * +*                for_size     = taille de la direction opposée.               * +*                minimum      = taille minimale pour le composant. [OUT]      * +*                natural      = taille idéale pour le composant. [OUT]        * +*                min_baseline = ligne de base minimale. [OUT]                 * +*                nat_baseline = ligne de base idéale. [OUT]                   * +*                                                                             * +*  Description : Fournit les mesures mainimale et idéale du composant.        * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void gtk_content_view_measure(GtkWidget *widget, GtkOrientation orientation, int for_size, int *minimum, int *natural, int *min_baseline, int *nat_baseline) +{ +    GtkContentView *view;                   /* Version spécialisée         */ +    size_t i;                               /* Boucle de parcours          */ +    int min;                                /* Valeur minimale locale      */ +    int nat;                                /* Valeur idéale locale        */ + +    view = GTK_CONTENT_VIEW(widget); + +    if (minimum != NULL) *minimum = 0; +    if (natural != NULL) *natural = 0; + +    /* Demande de hauteur minimale / idéale */ +    if (orientation == GTK_ORIENTATION_VERTICAL) +    { +        for (i = 0; i < view->sub_count; i++) +        { +            gtk_widget_measure(view->sub_children[i], GTK_ORIENTATION_VERTICAL, -1, &min, &nat, NULL, NULL); + +            if (minimum != NULL && min > *minimum) +                *minimum = min; + +            if (natural != NULL && nat > *natural) +                *natural = nat; + +        } + +    } + +    /* Demande de largeur minimale / idéale */ +    else +    { +        for (i = 0; i < view->sub_count; i++) +        { +            gtk_widget_measure(view->sub_children[i], GTK_ORIENTATION_HORIZONTAL, -1, &min, &nat, NULL, NULL); + +            if (minimum != NULL) *minimum += min; +            if (natural != NULL) *natural += nat; + +        } + +    } + +    if (min_baseline != NULL) *min_baseline = -1; +    if (nat_baseline != NULL) *nat_baseline = -1; + +} + + + + + + + + + + + + + + +#if 0 + + +/****************************************************************************** +*                                                                             *  *  Paramètres  : widget = composant GTK à détruire.                           *  *                                                                             *  *  Description : Détruit un composant d'affichage.                            * @@ -416,8 +651,11 @@ static void gtk_display_panel_destroy(GtkWidget *widget)      panel = GTK_DISPLAY_PANEL(widget); -    gtk_display_panel_disconnect_adjustment(panel, GTK_ORIENTATION_HORIZONTAL); -    gtk_display_panel_disconnect_adjustment(panel, GTK_ORIENTATION_VERTICAL); +    GtkContentView *view;                   /* Autre vision de l'instance  */ + +    view = GTK_CONTENT_VIEW(widget); + +      GTK_WIDGET_CLASS(gtk_display_panel_parent_class)->destroy(widget); @@ -471,32 +709,6 @@ static void gtk_display_panel_realize(GtkWidget *widget)  } -/****************************************************************************** -*                                                                             * -*  Paramètres  : widget     = composant GTK à mettre à jour.                  * -*                allocation = étendue accordée à la vue.                      * -*                                                                             * -*  Description : S'adapte à la surface concédée par le composant parent.      * -*                                                                             * -*  Retour      : -                                                            * -*                                                                             * -*  Remarques   : -                                                            * -*                                                                             * -******************************************************************************/ - -static void gtk_display_panel_size_allocate(GtkWidget *widget, GtkAllocation *allocation) -{ -    GtkDisplayPanel *panel;                 /* Autre version du composant  */ - -    GTK_WIDGET_CLASS(gtk_display_panel_parent_class)->size_allocate(widget, allocation); - -    panel = GTK_DISPLAY_PANEL(widget); - -    gtk_display_panel_update_adjustment(panel, GTK_ORIENTATION_HORIZONTAL); -    gtk_display_panel_update_adjustment(panel, GTK_ORIENTATION_VERTICAL); - -} -  /******************************************************************************  *                                                                             * @@ -560,29 +772,6 @@ static void gtk_display_panel_get_preferred_width(GtkWidget *widget, gint *minim  } -/****************************************************************************** -*                                                                             * -*  Paramètres  : panel       = composant GTK d'affichage à mettre à jour.     * -*                size        = taille de l'espace dans la direction donnée.   * -*                orientation = indication sur le défilement à traiter.        * -*                step        = valeur d'un petit pas de défilement. [OUT]     * -*                page        = valeur d'un grand pas de défilement. [OUT]     * -*                                                                             * -*  Description : Détermine la taille des bonds lors de défilements.           * -*                                                                             * -*  Retour      : -                                                            * -*                                                                             * -*  Remarques   : -                                                            * -*                                                                             * -******************************************************************************/ - -static void gtk_display_panel_compute_scroll_inc(GtkDisplayPanel *panel, gint size, GtkOrientation orientation, gdouble *step, gdouble *page) -{ -    *step = size * 0.1; -    *page = size * 0.9; - -} -  /******************************************************************************  *                                                                             * @@ -653,151 +842,8 @@ static void gtk_display_panel_compute_allocation(GtkDisplayPanel *panel, GtkAllo  } -/****************************************************************************** -*                                                                             * -*  Paramètres  : panel       = composant GTK d'affichage à mettre à jour.     * -*                orientation = indication sur le défilement à traiter.        * -*                                                                             * -*  Description : Se débarrsse d'un ajustement pour un défilement donné.       * -*                                                                             * -*  Retour      : -                                                            * -*                                                                             * -*  Remarques   : -                                                            * -*                                                                             * -******************************************************************************/ - -static void gtk_display_panel_disconnect_adjustment(GtkDisplayPanel *panel, GtkOrientation orientation) -{ -    GtkAdjustment **adjp;                   /* Ajustement à manipuler      */ - -    adjp = orientation == GTK_ORIENTATION_HORIZONTAL ? &panel->hadjustment : &panel->vadjustment; - -    if (*adjp != NULL) -    { -        g_signal_handlers_disconnect_by_func(*adjp, gtk_display_panel_adjustment_value_changed, panel); -        g_object_unref(G_OBJECT(*adjp)); -        *adjp = NULL; -    } - -} - - -/****************************************************************************** -*                                                                             * -*  Paramètres  : panel       = composant GTK d'affichage à mettre à jour.     * -*                orientation = indication sur le défilement à traiter.        * -*                adj         = nouvel ajustement à prendre en compte.         * -*                                                                             * -*  Description : S'associe à un ajustement pour un défilement donné.          * -*                                                                             * -*  Retour      : -                                                            * -*                                                                             * -*  Remarques   : -                                                            * -*                                                                             * -******************************************************************************/ - -static void gtk_display_panel_set_adjustment(GtkDisplayPanel *panel, GtkOrientation orientation, GtkAdjustment *adj) -{ -    GtkAdjustment **adjp;                   /* Ajustement à manipuler      */ -    adjp = orientation == GTK_ORIENTATION_HORIZONTAL ? &panel->hadjustment : &panel->vadjustment; -    /* S'il n'y a rien à faire... */ -    if (adj != NULL && adj == *adjp) -        return; - -    if (!adj) -        adj = gtk_adjustment_new(0.0, 0.0, 0.0, 0.0, 0.0, 0.0); - -    gtk_display_panel_disconnect_adjustment(panel, orientation); - -    *adjp = adj; -    g_object_ref_sink(adj); - -    gtk_display_panel_update_adjustment(panel, orientation); - -    g_signal_connect(adj, "value-changed", G_CALLBACK(gtk_display_panel_adjustment_value_changed), panel); - -    gtk_display_panel_adjustment_value_changed(adj, panel); - -} - - -/****************************************************************************** -*                                                                             * -*  Paramètres  : panel       = composant GTK d'affichage à mettre à jour.     * -*                orientation = indication sur le défilement à traiter.        * -*                                                                             * -*  Description : Ajuste les paramètres de défilement du composant.            * -*                                                                             * -*  Retour      : -                                                            * -*                                                                             * -*  Remarques   : -                                                            * -*                                                                             * -******************************************************************************/ - -static void gtk_display_panel_update_adjustment(GtkDisplayPanel *panel, GtkOrientation orientation) -{ -    GtkAllocation allocation;               /* Emplacement du contenu      */ -    GtkAdjustment *adj;                     /* Ajustement à manipuler      */ -    gint req;                               /* Dimension requise           */ -    gint allocated;                         /* Dimension allouée           */ -    gdouble step_inc;                       /* Pas de défilement           */ -    gdouble page_inc;                       /* ENjambée de défilement      */ - -    gtk_display_panel_compute_allocation(panel, &allocation); - -    if (orientation == GTK_ORIENTATION_HORIZONTAL) -    { -        adj = panel->hadjustment; - -        gtk_widget_get_preferred_width(GTK_WIDGET(panel), &req, NULL); -        allocated = allocation.width; - -    } -    else -    { -        adj = panel->vadjustment; - -        gtk_widget_get_preferred_height(GTK_WIDGET(panel), &req, NULL); -        allocated = allocation.height; - -    } - -    GTK_DISPLAY_PANEL_GET_CLASS(panel)->compute_inc(panel, allocated, orientation, &step_inc, &page_inc); - -    gtk_adjustment_configure(adj, gtk_adjustment_get_value(adj), -                             0, MAX(req, allocated), -                             step_inc, -                             page_inc, -                             allocated); - -} - - -/****************************************************************************** -*                                                                             * -*  Paramètres  : adj   = défilement dont une valeur a changé.                 * -*                panel = panneau d'affichage concerné.                        * -*                                                                             * -*  Description : Réagit à un défilement chez une barre associée au composant. * -*                                                                             * -*  Retour      : -                                                            * -*                                                                             * -*  Remarques   : -                                                            * -*                                                                             * -******************************************************************************/ - -static void gtk_display_panel_adjustment_value_changed(GtkAdjustment *adj, GtkDisplayPanel *panel) -{ -    GtkOrientation orientation;             /* Indification de la barre    */ - -    orientation = (adj == panel->hadjustment ? GTK_ORIENTATION_HORIZONTAL : GTK_ORIENTATION_VERTICAL); - -    if (GTK_DISPLAY_PANEL_GET_CLASS(panel)->adjust != NULL) -        GTK_DISPLAY_PANEL_GET_CLASS(panel)->adjust(panel, adj, orientation); - -}  /****************************************************************************** diff --git a/src/gtkext/hexview-int.h b/src/gtkext/hexview-int.h new file mode 100644 index 0000000..2b1c570 --- /dev/null +++ b/src/gtkext/hexview-int.h @@ -0,0 +1,71 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * hexview-int.h - définitions internes pour l'affichage de contenus de binaire + * + * Copyright (C) 2016-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 <http://www.gnu.org/licenses/>. + */ + + +#ifndef _GTKEXT_HEXVIEW_INT_H +#define _GTKEXT_HEXVIEW_INT_H + + +#include "bufferview-int.h" +#include "hexview.h" +#include "../glibext/generators/hex.h" + + + +/* Composant d'affichage d'octets bruts et imprimables (instance) */ +struct _GtkHexView +{ +    GtkBufferView parent;                   /* A laisser en premier        */ + +    union +    { +#define _CHILDREN_COUNT 3 + +        GtkWidget *children[_CHILDREN_COUNT];/* Sous-composants d'affichage*/ + +        struct +        { +            GtkWidget *offsets;             /* Affichage des positions     */ +            GtkWidget *hex;                 /* Affichage des octets brut   */ +            GtkWidget *ascii;               /* Affichage des imprimables   */ +        }; + +    }; + +    GHexGenerator *generator;               /* Générateur unique dédié     */ + +}; + +/* Composant d'affichage d'octets bruts et imprimables (classe) */ +struct _GtkHexViewClass +{ +    GtkBufferViewClass parent;              /* A laisser en premier        */ + +}; + + +/* Met en place un nouveau composant d'affichage d'octets bruts. */ +bool gtk_hex_view_create(GtkHexView *, GBinContent *); + + + +#endif  /* _GTKEXT_HEXVIEW_INT_H */ diff --git a/src/gtkext/hexview.c b/src/gtkext/hexview.c index 717c1bc..7363079 100644 --- a/src/gtkext/hexview.c +++ b/src/gtkext/hexview.c @@ -24,45 +24,17 @@  #include "hexview.h" -#include "area.h" -#include "contentview-int.h" - - - -/* ------------------------- BASES D'UN COMPOSANT GRAPHIQUE ------------------------- */ - +#include <alloca.h> +#include <sys/param.h> -/* Composant d'affichage d'octets bruts et imprimables (instance) */ -struct _GtkHexView -{ -    GtkContentView parent;                  /* A laisser en premier        */ - -    union -    { -#define _CHILDREN_COUNT 4 - -        GtkWidget *children[_CHILDREN_COUNT];/* Sous-composants d'affichage*/ - -        struct -        { -            GtkWidget *offsets;             /* Affichage des positions     */ -            GtkWidget *hex;                 /* Affichage des octets brut   */ -            GtkWidget *ascii;               /* Affichage des imprimables   */ -            GtkWidget *vscroll;             /* Barre de défilement         */ -        }; -    }; - -    bool need_vscrolling;                   /* Besoin de défilement ?      */ +#include "area.h" +#include "hexview-int.h" +#include "../glibext/options/hex.h" -}; -/* Composant d'affichage d'octets bruts et imprimables (classe) */ -struct _GtkHexViewClass -{ -    GtkContentViewClass parent;             /* A laisser en premier        */ -}; +/* ------------------------- BASES D'UN COMPOSANT GRAPHIQUE ------------------------- */  /* Procède à l'initialisation de l'afficheur générique. */ @@ -77,6 +49,12 @@ static void gtk_hex_view_dispose(GtkHexView *);  /* Procède à la libération totale de la mémoire. */  static void gtk_hex_view_finalize(GtkHexView *); +/* Procède à l'actualisation de l'affichage d'un sous-composant. */ +static void gtk_hex_view_dispatch_sub_snapshot(GtkWidget *, GtkSnapshot *, GtkWidget *); + +/* Adapte le cache de lignes hexadécimales à la taille courante. */ +static void gtk_hex_view_populate_cache(GtkHexView *); +  void demo_snapshot (GtkWidget *widget, GtkSnapshot *snapshot, GtkWidget *parent); @@ -105,7 +83,7 @@ static void gtk_hex_view_measure(GtkWidget *, GtkOrientation, int, int *, int *,  /* Détermine le type du composant d'affichage générique. */ -G_DEFINE_TYPE(GtkHexView, gtk_hex_view, GTK_TYPE_CONTENT_VIEW); +G_DEFINE_TYPE(GtkHexView, gtk_hex_view, GTK_TYPE_BUFFER_VIEW);  /****************************************************************************** @@ -141,7 +119,6 @@ static void gtk_hex_view_class_init(GtkHexViewClass *class)      gtk_widget_class_bind_template_child(widget, GtkHexView, offsets);      gtk_widget_class_bind_template_child(widget, GtkHexView, hex);      gtk_widget_class_bind_template_child(widget, GtkHexView, ascii); -    gtk_widget_class_bind_template_child(widget, GtkHexView, vscroll);      widget->size_allocate = gtk_hex_view_size_allocate;      widget->get_request_mode = gtk_hex_view_get_request_mode; @@ -164,15 +141,31 @@ static void gtk_hex_view_class_init(GtkHexViewClass *class)  static void gtk_hex_view_init(GtkHexView *view)  { +    GtkContentView *base;                   /* Base d'instance supérieure  */ + +    /* Niveau supérieur */ + +    base = GTK_CONTENT_VIEW(view); + +    base->options = G_DISPLAY_OPTIONS(g_hex_options_new()); + +    base->sub_children = view->children; +    base->sub_count = _CHILDREN_COUNT; + +    /* Instance courante */ +      gtk_widget_init_template(GTK_WIDGET(view)); -    g_raw_scan_cache_register_snapshot(GTK_COMPOSING_AREA(view->offsets), demo_snapshot, GTK_WIDGET(view)); +    g_raw_scan_cache_register_snapshot(GTK_COMPOSING_AREA(view->offsets), +                                       gtk_hex_view_dispatch_sub_snapshot, GTK_WIDGET(view)); -    g_raw_scan_cache_register_snapshot(GTK_COMPOSING_AREA(view->hex), demo_snapshot, GTK_WIDGET(view)); +    g_raw_scan_cache_register_snapshot(GTK_COMPOSING_AREA(view->hex), +                                       gtk_hex_view_dispatch_sub_snapshot, GTK_WIDGET(view)); -    g_raw_scan_cache_register_snapshot(GTK_COMPOSING_AREA(view->ascii), demo_snapshot, GTK_WIDGET(view)); +    g_raw_scan_cache_register_snapshot(GTK_COMPOSING_AREA(view->ascii), +                                       gtk_hex_view_dispatch_sub_snapshot, GTK_WIDGET(view)); -    view->need_vscrolling = true; +    view->generator = NULL;  } @@ -193,6 +186,8 @@ static void gtk_hex_view_dispose(GtkHexView *view)  {      gtk_widget_dispose_template(GTK_WIDGET(view), GTK_TYPE_HEX_VIEW); +    g_clear_object(&view->generator); +      G_OBJECT_CLASS(gtk_hex_view_parent_class)->dispose(G_OBJECT(view));  } @@ -217,130 +212,225 @@ static void gtk_hex_view_finalize(GtkHexView *view)  } +/****************************************************************************** +*                                                                             * +*  Paramètres  : content = contenu binaire à exposer de façon brute.          * +*                                                                             * +*  Description : Crée un composant d'affichage d'octets bruts et imprimables. * +*                                                                             * +*  Retour      : Centralisateur mis en place pour un composant GTK donné.     * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ +GtkHexView *gtk_hex_view_new(GBinContent *content) +{ +    GtkHexView *result;                     /* Nouvelle instance à renvoyer*/ +    result = g_object_new(GTK_TYPE_HEX_VIEW, NULL); +    if (!gtk_hex_view_create(result, content)) +        g_clear_object(&result); +    return result; +} -void demo_snapshot (GtkWidget *widget, GtkSnapshot *snapshot, GtkWidget *parent) -{ -  GdkRGBA red, green, yellow, blue; -  float w, h; +/****************************************************************************** +*                                                                             * +*  Paramètres  : view    = composant d'affichage à initialiser pleinement.    * +*                content = contenu binaire à exposer de façon brute.          * +*                                                                             * +*  Description : Met en place un nouveau composant d'affichage d'octets bruts.* +*                                                                             * +*  Retour      : Bilan de l'opération.                                        * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ -  gdk_rgba_parse (&red, "red"); -  gdk_rgba_parse (&green, "green"); -  gdk_rgba_parse (&yellow, "yellow"); -  gdk_rgba_parse (&blue, "blue"); +bool gtk_hex_view_create(GtkHexView *view, GBinContent *content) +{ +    bool result;                            /* Bilan à retourner           */ +    GtkBufferView *parent;                  /* Version parente du composant*/ +    GBufferCache *cache;                    /* Tampon à représenter        */ -  w = gtk_widget_get_width (widget) / 2.0; -  h = gtk_widget_get_height (widget) / 2.0; +    result = true; -  h /= 2.0; +    assert(g_display_options_count(GTK_CONTENT_VIEW(view)->options) == 1); -  gtk_snapshot_append_color (snapshot, &red, -                             &GRAPHENE_RECT_INIT(0, 0, w, h)); -  gtk_snapshot_append_color (snapshot, &green, -                             &GRAPHENE_RECT_INIT(w, 0, w, h)); -  gtk_snapshot_append_color (snapshot, &yellow, -                             &GRAPHENE_RECT_INIT(0, h, w, h)); -  gtk_snapshot_append_color (snapshot, &blue, -                             &GRAPHENE_RECT_INIT(w, h, w, h)); +    parent = GTK_BUFFER_VIEW(view); +    cache = g_buffer_cache_new(1, 2); +    parent->view = g_buffer_view_new(cache, parent->style); +    unref_object(cache); -  cairo_t *cr; -  int x; +    view->generator = g_hex_generator_new(content); -  x = 0; +    return result; -  cr = gtk_snapshot_append_cairo(snapshot, &GRAPHENE_RECT_INIT(0, 0, w * 2, h * 2)); +} -  g_token_style_draw_text(GTK_CONTENT_VIEW(parent)->style, -                          TRT_RAW_FULL, -                          cr, -                          &x, 0, -                          "A.A", 3); -  g_token_style_draw_text(GTK_CONTENT_VIEW(parent)->style, -                          TRT_RAW_NULL, -                          cr, -                          &x, 0, -                          "A.A", 3); +/****************************************************************************** +*                                                                             * +*  Paramètres  : widget   = composant GTK à redessiner.                       * +*                snapshot = gestionnaire de noeuds de rendu à solliciter.     * +*                parent   = composant GTK parent et cadre de l'appel.         * +*                                                                             * +*  Description : Procède à l'actualisation de l'affichage d'un sous-composant.* +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ -  cairo_destroy(cr); +static void gtk_hex_view_dispatch_sub_snapshot(GtkWidget *widget, GtkSnapshot *snapshot, GtkWidget *parent) +{ +    GtkHexView *view;                       /* Version spécialisée         */ +    size_t column;                          /* Indice de colonne à traiter */ +    int width;                              /* Largeur à disposition       */ +    int height;                             /* Hauteur à disposition       */ +    cairo_t *cr;                            /* Pinceau pour les dessins    */ +    view = GTK_HEX_VIEW(parent); +    if (widget == view->offsets) +        column = HCO_OFFSET; -} +    else if (widget == view->hex) +        column = HCO_COUNT + 0; +    else +    { +        assert(widget == view->ascii); +        column = HCO_COUNT + 1; +    } +    width = gtk_widget_get_width(widget); +    height = gtk_widget_get_height(widget); +    cr = gtk_snapshot_append_cairo(snapshot, &GRAPHENE_RECT_INIT(0, 0, width, height)); +    g_buffer_view_draw(GTK_BUFFER_VIEW(parent)->view, cr, column, GTK_BUFFER_VIEW(parent)->virt_top, height); +    cairo_destroy(cr); +} -bool g_buffer_view_allocate_widths(void *ptr, int width, int height, int fill, int *out); +/****************************************************************************** +*                                                                             * +*  Paramètres  : view = composant GTK à mettre à jour.                        * +*                                                                             * +*  Description : Adapte le cache de lignes hexadécimales à la taille courante.* +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ -bool g_buffer_view_allocate_widths(void *ptr, int width, int height, int fill, int *out) +static void gtk_hex_view_populate_cache(GtkHexView *view)  { +    GBinContent *content;                   /* Contenu binaire affiché     */ +    phys_t full;                            /* Taille totale à représenter */ +    phys_t line;                            /* Taille représentée par ligne*/ +    size_t needed;                          /* Nombre de lignes nécessaires*/ +    GBufferCache *cache;                    /* Tampon à représenter        */ +    size_t count;                           /* Nombre actuel de lignes     */ -    int i;                                  /* Boucle de parcours          */ +    /* Détermination du besoin */ +    content = g_hex_generator_get_content(view->generator); -    for (i = 0; i < fill; i++) -    { +    full = g_binary_content_compute_size(content); -        if (i == 0) -        { -            out[0] = 40; -        } +    unref_object(content); -        else if ((i + 1) == fill) -        { -            out[i] = width; -        } +    line = g_hex_generator_get_bytes_per_line(view->generator); -        else -        { -            out[i] = 230; -        } +    needed = full / line; +    if (full % line > 0) +        needed++; -        width -= out[i]; +    /* Adaptation du tampon interne ? */ +    cache = g_buffer_view_get_cache(GTK_BUFFER_VIEW(view)->view); +    g_buffer_cache_wlock(cache); -    } +    count = g_buffer_cache_count_lines(cache); + +    if (needed < count) +        g_buffer_cache_truncate(cache, needed); + +    else if (needed > count) +        g_buffer_cache_extend_with(cache, needed, G_TOKEN_GENERATOR(view->generator)); -    return false; +    g_buffer_cache_wunlock(cache); +    unref_object(cache); + +    /* Mise à jour de l'affichage ? */ + +    if (needed != count) +        gtk_widget_queue_resize(GTK_WIDGET(view));  } -int g_buffer_view_measure_height(void *ptr, int width); -int g_buffer_view_measure_height(void *ptr, int width) + + + + + +void demo_snapshot (GtkWidget *widget, GtkSnapshot *snapshot, GtkWidget *parent)  { -    int result;                             /* Mesure à retourner          */ +  GdkRGBA red, green, yellow, blue; +  float w, h; -    if (width == -1) -        result = 1; +  gdk_rgba_parse (&red, "red"); +  gdk_rgba_parse (&green, "green"); +  gdk_rgba_parse (&yellow, "yellow"); +  gdk_rgba_parse (&blue, "blue"); -    else -        result = 5000 / width; +  w = gtk_widget_get_width (widget) / 2.0; +  h = gtk_widget_get_height (widget) / 2.0; + +  h /= 2.0; + +  gtk_snapshot_append_color (snapshot, &red, +                             &GRAPHENE_RECT_INIT(0, 0, w, h)); +  gtk_snapshot_append_color (snapshot, &green, +                             &GRAPHENE_RECT_INIT(w, 0, w, h)); +  gtk_snapshot_append_color (snapshot, &yellow, +                             &GRAPHENE_RECT_INIT(0, h, w, h)); +  gtk_snapshot_append_color (snapshot, &blue, +                             &GRAPHENE_RECT_INIT(w, h, w, h)); -    result *= 16; -    return result;  } + + + + + + + + + +  /* ---------------------------------------------------------------------------------- */  /*                       IMPLEMENTATION DES FONCTIONS DE CLASSE                       */  /* ---------------------------------------------------------------------------------- */ @@ -364,68 +454,56 @@ int g_buffer_view_measure_height(void *ptr, int width)  static void gtk_hex_view_size_allocate(GtkWidget *widget, int width, int height, int baseline)  {      GtkHexView *view;                       /* Version spécialisée         */ -    int vscroll_width;                      /* Largeur idéale de la barre  */ - -    GtkAllocation allocated;                /* Zone allouée                */ +    int *min_widths;                        /* Tailles minimales imposées  */ +    int *final_widths;                      /* Tailles finales retenues    */      size_t i;                               /* Boucle de parcours          */ -    int sub_widths[_CHILDREN_COUNT - 1];    /* Sous-largeurs calculées     */ +    int available;                          /* Largeur disponible          */ +    bool changed;                           /* Détection de variation      */ +    GWidthTracker *tracker;                 /* Collecteur de largeurs      */      view = GTK_HEX_VIEW(widget); -    allocated.y = 0; -    allocated.height = height; - -    /* Barre de défilement ? */ - -    view->need_vscrolling = g_buffer_view_allocate_widths(NULL, width, height, _CHILDREN_COUNT - 1, sub_widths); +    min_widths = alloca(_CHILDREN_COUNT * sizeof(int)); +    final_widths = alloca(_CHILDREN_COUNT * sizeof(int)); -    gtk_widget_set_visible(view->vscroll, view->need_vscrolling); +    for (i = 0; i < _CHILDREN_COUNT; i++) +        gtk_widget_measure(view->children[i], GTK_ORIENTATION_HORIZONTAL, -1, &min_widths[i], NULL, NULL, NULL); -    if (view->need_vscrolling) -    { -        gtk_widget_remove_css_class(widget, "without_vscroll"); -        gtk_widget_add_css_class(widget, "with_vscroll"); -    } -    else -    { -        gtk_widget_remove_css_class(widget, "with_vscroll"); -        gtk_widget_add_css_class(widget, "without_vscroll"); -    } +    /* Passe 1 : tentative sans défilement vertical */ -    /** -     * Validité de la consistence des feuilles CSS : le changement de classe -     * ne doit pas faire évoluer les tailles. -     */ -    assert(view->need_vscrolling == g_buffer_view_allocate_widths(NULL, width, height, _CHILDREN_COUNT - 1, sub_widths)); +    available = width; -    if (view->need_vscrolling) -    { -        gtk_widget_measure(view->vscroll, GTK_ORIENTATION_HORIZONTAL, height, &vscroll_width, NULL, NULL, NULL); +    for (i = 0; i < _CHILDREN_COUNT; i++) +        available -= min_widths[i]; -        allocated.x = width - vscroll_width; -        allocated.width = vscroll_width; +    changed = g_hex_generator_allocate(view->generator, +                                       GTK_CONTENT_VIEW(view)->options, +                                       GTK_BUFFER_VIEW(view)->style, +                                       available, final_widths); -        gtk_widget_size_allocate(view->vscroll, &allocated, baseline); +    /* Application des largeurs calculées */ -        width -= vscroll_width; +    if (changed) +    { +        gtk_hex_view_populate_cache(view); -    } +        tracker = g_buffer_view_get_tracker(GTK_BUFFER_VIEW(view)->view); -    /* Placement des composants d'affichage */ +        for (i = 0; i < _CHILDREN_COUNT; i++) +        { +            final_widths[i] += min_widths[i]; -    g_buffer_view_allocate_widths(NULL, width, height, _CHILDREN_COUNT - 1, sub_widths); +            g_width_tracker_set_column_min_width(tracker, i, final_widths[i]); -    allocated.x = 0; +        } -    for (i = 0; i < (_CHILDREN_COUNT - 1); i++) -    { -        allocated.width = sub_widths[i]; +        unref_object(tracker); -        gtk_widget_size_allocate(view->children[i], &allocated, baseline); +    } -        allocated.x += sub_widths[i]; +    /* Mise à jour des éléments plus internes */ -    } +    GTK_WIDGET_CLASS(gtk_hex_view_parent_class)->size_allocate(widget, width, height, baseline);  } @@ -453,6 +531,17 @@ static GtkSizeRequestMode gtk_hex_view_get_request_mode(GtkWidget *widget)  } + + + + + + + + + + +  /******************************************************************************  *                                                                             *  *  Paramètres  : widget       = composant GTK à examiner.                     * @@ -473,54 +562,60 @@ static GtkSizeRequestMode gtk_hex_view_get_request_mode(GtkWidget *widget)  static void gtk_hex_view_measure(GtkWidget *widget, GtkOrientation orientation, int for_size, int *minimum, int *natural, int *min_baseline, int *nat_baseline)  { +    bool processed;                         /* Calcul de hauteur effectué  */      GtkHexView *view;                       /* Version spécialisée         */      int requested;                          /* Taille requise à priori     */      size_t i;                               /* Boucle de parcours          */      int min;                                /* Valeur minimale locale      */      int nat;                                /* Valeur idéale locale        */ -    view = GTK_HEX_VIEW(widget); +    processed = false;      /* Demande de hauteur minimale / idéale */ -    if (orientation == GTK_ORIENTATION_VERTICAL) +    if (orientation == GTK_ORIENTATION_VERTICAL && for_size != -1)      { -        requested = g_buffer_view_measure_height(NULL, for_size); +        view = GTK_HEX_VIEW(widget); -        if (minimum != NULL) *minimum = requested; -        if (natural != NULL) *natural = requested; +        requested = 0;          for (i = 0; i < _CHILDREN_COUNT; i++)          { -            gtk_widget_measure(view->children[i], GTK_ORIENTATION_VERTICAL, -1, &min, &nat, NULL, NULL); +            gtk_widget_measure(view->children[i], GTK_ORIENTATION_HORIZONTAL, -1, &min, NULL, NULL, NULL); +            requested += min; +        } -            if (minimum != NULL && min > *minimum) -                *minimum = min; +        for_size -= requested; -            if (natural != NULL && nat > *natural) -                *natural = nat; +        if (for_size > 0) +        { +            requested = g_hex_generator_mesure_height_for_width(view->generator, +                                                                GTK_CONTENT_VIEW(view)->options, +                                                                GTK_BUFFER_VIEW(view)->style, +                                                                for_size); -        } +            if (minimum != NULL) *minimum = 0; +            if (natural != NULL) *natural = requested; -    } +            for (i = 0; i < _CHILDREN_COUNT; i++) +            { +                gtk_widget_measure(view->children[i], GTK_ORIENTATION_VERTICAL, -1, &min, &nat, NULL, NULL); -    /* Demande de largeur minimale / idéale */ -    else -    { -        if (minimum != NULL) *minimum = 0; -        if (natural != NULL) *natural = 0; +                if (minimum != NULL && min > *minimum) +                    *minimum = min; -        for (i = 0; i < _CHILDREN_COUNT; i++) -        { -            gtk_widget_measure(view->children[i], GTK_ORIENTATION_HORIZONTAL, -1, &min, &nat, NULL, NULL); +                if (natural != NULL && nat > *natural) +                    *natural = nat; + +            } -            if (minimum != NULL) *minimum += min; -            if (natural != NULL) *natural += nat; +            processed = true;          }      } -    if (min_baseline != NULL) *min_baseline = -1; -    if (nat_baseline != NULL) *nat_baseline = -1; +    if (!processed) +        GTK_WIDGET_CLASS(gtk_hex_view_parent_class)->measure(widget, orientation, for_size, +                                                           minimum, natural, min_baseline, nat_baseline);  } diff --git a/src/gtkext/hexview.h b/src/gtkext/hexview.h index 8d3129d..2199786 100644 --- a/src/gtkext/hexview.h +++ b/src/gtkext/hexview.h @@ -28,6 +28,7 @@  #include <gtk/gtk.h> +#include "../analysis/content.h"  #include "../glibext/helpers.h" @@ -37,11 +38,8 @@  DECLARE_GTYPE(GtkHexView, gtk_hex_view, GTK, HEX_VIEW); - - - - - +/* Crée un composant d'affichage d'octets bruts et imprimables. */ +GtkHexView *gtk_hex_view_new(GBinContent *); diff --git a/src/gtkext/hexview.ui b/src/gtkext/hexview.ui index df657ca..ae4586c 100644 --- a/src/gtkext/hexview.ui +++ b/src/gtkext/hexview.ui @@ -1,5 +1,5 @@  <interface> -  <template class="GtkHexView" parent="GtkContentView"> +  <template class="GtkHexView" parent="GtkBufferView">      <property name="css-name">GtkHexView</property>      <child>        <object class="GtkComposingArea" id="offsets"> @@ -23,10 +23,5 @@          </style>        </object>      </child> -    <child> -      <object class="GtkScrollbar" id="vscroll"> -        <property name="orientation">1</property> -      </object> -    </child>    </template>  </interface>  | 
