diff options
author | Cyrille Bagard <nocbos@gmail.com> | 2024-06-18 06:31:42 (GMT) |
---|---|---|
committer | Cyrille Bagard <nocbos@gmail.com> | 2024-06-18 06:31:58 (GMT) |
commit | 53edb30496d1065019406de16f9f9d96ba61cd3c (patch) | |
tree | 162cad07e27a01990d721f69f3270581417c31e7 /src/gtkext/bufferview.c | |
parent | 334126eb659bc310a72a9f7f9238b7cd205a0770 (diff) |
Rebuild hex views for large contents.
Diffstat (limited to 'src/gtkext/bufferview.c')
-rw-r--r-- | src/gtkext/bufferview.c | 449 |
1 files changed, 418 insertions, 31 deletions
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 |