summaryrefslogtreecommitdiff
path: root/src/gtkext/hexview.c
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2024-05-13 21:34:56 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2024-05-14 10:27:57 (GMT)
commite9f10d8fe1c5e9f8a70801c1cd4d3d342e290f15 (patch)
tree42a1d8560e8772e76e4e57db82a441d4a8152f74 /src/gtkext/hexview.c
parent071572b0df281cfa04442a636e84fbabd2acfe57 (diff)
Introduce a template for the widget providing a hex view.
Diffstat (limited to 'src/gtkext/hexview.c')
-rw-r--r--src/gtkext/hexview.c351
1 files changed, 190 insertions, 161 deletions
diff --git a/src/gtkext/hexview.c b/src/gtkext/hexview.c
index 32bd69b..56a167d 100644
--- a/src/gtkext/hexview.c
+++ b/src/gtkext/hexview.c
@@ -1,8 +1,8 @@
/* Chrysalide - Outil d'analyse de fichiers binaires
- * hexdisplay.c - affichage d'un contenu binaire sous forme hexadécimale
+ * hexview.c - affichage de contenus de binaire
*
- * Copyright (C) 2019 Cyrille Bagard
+ * Copyright (C) 2016-2024 Cyrille Bagard
*
* This file is part of Chrysalide.
*
@@ -17,71 +17,74 @@
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with Foobar. If not, see <http://www.gnu.org/licenses/>.
+ * along with Chrysalide. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "hexdisplay.h"
+#include "hexview.h"
-#include "gtkbufferdisplay-int.h"
-#include "../core/columns.h"
-#include "../core/params.h"
-#include "../format/format.h"
-#include "../glibext/generators/hex.h"
+#include "area.h"
-/* Composant d'affichage de contenu sous forme hexadécimale (instance) */
-struct _GtkHexDisplay
+
+
+/* Composant d'affichage générique (instance) */
+struct _GtkHexView
{
- GtkBufferDisplay parent; /* A laisser en premier */
+ GtkWidget parent; /* A laisser en premier */
- GBufferCache *cache; /* Cache pour l'affichage */
- GHexGenerator *generator; /* Générateur à la volée */
+ GtkWidget *offsets; /* Affichage des positions */
+ GtkWidget *hex; /* Affichage des octets brut */
+ GtkWidget *ascii; /* Affichage des imprimables */
};
-/* Composant d'affichage de contenu sous forme hexadécimale (classe) */
-struct _GtkHexDisplayClass
+/* Composant d'affichage générique (classe) */
+struct _GtkHexViewClass
{
- GtkBufferDisplayClass parent; /* A laisser en premier */
+ GtkWidgetClass parent; /* A laisser en premier */
};
-/* Procède à l'initialisation des afficheurs sous forme hexa. */
-static void gtk_hex_display_class_init(GtkHexDisplayClass *);
+/* Procède à l'initialisation de l'afficheur générique. */
+static void gtk_hex_view_class_init(GtkHexViewClass *);
-/* Procède à l'initialisation de l'afficheur sous forme hexa. */
-static void gtk_hex_display_init(GtkHexDisplay *);
+/* Procède à l'initialisation de l'afficheur générique. */
+static void gtk_hex_view_init(GtkHexView *);
/* Supprime toutes les références externes. */
-static void g_hex_display_dispose(GtkHexDisplay *);
+static void gtk_hex_view_dispose(GtkHexView *);
/* Procède à la libération totale de la mémoire. */
-static void g_hex_display_finalize(GtkHexDisplay *);
+static void gtk_hex_view_finalize(GtkHexView *);
+
-/* S'adapte à la surface concédée par le composant parent. */
-static void gtk_hex_display_size_allocate(GtkWidget *, GtkAllocation *);
-/* Indique les dimensions de travail du composant d'affichage. */
-static void gtk_hex_display_compute_requested_size(GtkHexDisplay *, gint *, gint *);
+void demo_snapshot (GtkWidget *widget, GtkSnapshot *snapshot);
-/* Adapte le cache de lignes hexadécimales à la taille courante. */
-static void gtk_hex_display_populate_cache(GtkHexDisplay *);
+void demo_measure (GtkWidget *widget,
+ GtkOrientation orientation,
+ int for_size,
+ int *minimum_size,
+ int *natural_size,
+ int *minimum_baseline,
+ int *natural_baseline);
-/* Détermine le type du composant d'affichage sous forme hexadécimale. */
-G_DEFINE_TYPE(GtkHexDisplay, gtk_hex_display, GTK_TYPE_BUFFER_DISPLAY)
+
+/* Détermine le type du composant d'affichage générique. */
+G_DEFINE_TYPE(GtkHexView, gtk_hex_view, GTK_TYPE_WIDGET);
/******************************************************************************
* *
* Paramètres : class = classe GTK à initialiser. *
* *
-* Description : Procède à l'initialisation des afficheurs sous forme hexa. *
+* Description : Procède à l'initialisation de l'afficheur générique. *
* *
* Retour : - *
* *
@@ -89,24 +92,54 @@ G_DEFINE_TYPE(GtkHexDisplay, gtk_hex_display, GTK_TYPE_BUFFER_DISPLAY)
* *
******************************************************************************/
-static void gtk_hex_display_class_init(GtkHexDisplayClass *class)
+static void gtk_hex_view_class_init(GtkHexViewClass *class)
{
- GObjectClass *object; /* Autre version de la classe */
- GtkWidgetClass *widget_class; /* Classe de haut niveau */
- GtkDisplayPanelClass *panel_class; /* Classe parente */
+ GObjectClass *object; /* Plus haut niveau équivalent */
+ GtkWidgetClass *widget; /* Classe de haut niveau */
object = G_OBJECT_CLASS(class);
- object->dispose = (GObjectFinalizeFunc/* ! */)g_hex_display_dispose;
- object->finalize = (GObjectFinalizeFunc)g_hex_display_finalize;
+ object->dispose = (GObjectFinalizeFunc/* ! */)gtk_hex_view_dispose;
+ object->finalize = (GObjectFinalizeFunc)gtk_hex_view_finalize;
+
+ widget = GTK_WIDGET_CLASS(class);
+
+ gtk_widget_class_set_css_name(widget, "GtkHexView");
+
+ gtk_widget_class_set_layout_manager_type(widget, GTK_TYPE_BOX_LAYOUT);
+
+ g_type_ensure(GTK_TYPE_COMPOSING_AREA);
+
+ gtk_widget_class_set_template_from_resource(widget, "/re/chrysalide/framework/gtkext/hexview.ui");
- widget_class = GTK_WIDGET_CLASS(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);
- widget_class->size_allocate = gtk_hex_display_size_allocate;
- panel_class = GTK_DISPLAY_PANEL_CLASS(class);
- panel_class->compute_size = (compute_requested_size_fc)gtk_hex_display_compute_requested_size;
+ //widget->snapshot = demo_snapshot;
+
+ //widget->measure = demo_measure;
+
+
+ /*
+
+
+
+
+
+
+ */
+
+
+ /*
+ widget->destroy = gtk_hex_view_destroy;
+ widget->realize = gtk_hex_view_realize;
+ widget->size_allocate = gtk_hex_view_size_allocate;
+ widget->get_preferred_height = gtk_hex_view_get_preferred_height;
+ widget->get_preferred_width = gtk_hex_view_get_preferred_width;
+ */
}
@@ -115,7 +148,7 @@ static void gtk_hex_display_class_init(GtkHexDisplayClass *class)
* *
* Paramètres : view = composant GTK à initialiser. *
* *
-* Description : Procède à l'initialisation de l'afficheur sous forme hexa. *
+* Description : Procède à l'initialisation de l'afficheur générique. *
* *
* Retour : - *
* *
@@ -123,40 +156,37 @@ static void gtk_hex_display_class_init(GtkHexDisplayClass *class)
* *
******************************************************************************/
-static void gtk_hex_display_init(GtkHexDisplay *view)
+static void gtk_hex_view_init(GtkHexView *view)
{
+ gtk_widget_init_template(GTK_WIDGET(view));
-}
-/******************************************************************************
-* *
-* Paramètres : display = instance d'objet GLib à traiter. *
-* *
-* Description : Supprime toutes les références externes. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-static void g_hex_display_dispose(GtkHexDisplay *display)
-{
- g_clear_object(&display->cache);
- g_clear_object(&display->generator);
+ g_object_set(G_OBJECT(view->offsets), "width-request", 30, NULL);
+
+ g_object_set(G_OBJECT(view->ascii), "width-request", 230, NULL);
+
+
+ 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->hex), demo_snapshot, GTK_WIDGET(view));
+
+ g_raw_scan_cache_register_snapshot(GTK_COMPOSING_AREA(view->ascii), demo_snapshot, GTK_WIDGET(view));
+
+
+
- G_OBJECT_CLASS(gtk_hex_display_parent_class)->dispose(G_OBJECT(display));
}
/******************************************************************************
* *
-* Paramètres : display = instance d'objet GLib à traiter. *
+* Paramètres : view = instance d'objet GLib à traiter. *
* *
-* Description : Procède à la libération totale de la mémoire. *
+* Description : Supprime toutes les références externes. *
* *
* Retour : - *
* *
@@ -164,113 +194,100 @@ static void g_hex_display_dispose(GtkHexDisplay *display)
* *
******************************************************************************/
-static void g_hex_display_finalize(GtkHexDisplay *display)
+static void gtk_hex_view_dispose(GtkHexView *view)
{
- G_OBJECT_CLASS(gtk_hex_display_parent_class)->finalize(G_OBJECT(display));
+ gtk_widget_dispose_template(GTK_WIDGET(view), GTK_TYPE_HEX_VIEW);
+
+ G_OBJECT_CLASS(gtk_hex_view_parent_class)->dispose(G_OBJECT(view));
}
/******************************************************************************
* *
-* Paramètres : content = contenu brut à représenter. *
+* Paramètres : view = instance d'objet GLib à traiter. *
* *
-* Description : Crée un nouveau composant pour l'affichage sous forme hexa. *
+* Description : Procède à la libération totale de la mémoire. *
* *
-* Retour : Composant GTK créé. *
+* Retour : - *
* *
* Remarques : - *
* *
******************************************************************************/
-GtkWidget *gtk_hex_display_new(GBinContent *content)
+static void gtk_hex_view_finalize(GtkHexView *view)
{
- GtkHexDisplay *result; /* Composant à retourner */
- GBufferView *view; /* Vue pointée sur un tampon */
- int padding; /* Bourrage entre colonnes */
- GWidthTracker *tracker; /* Gestionnaire de largeurs */
+ G_OBJECT_CLASS(gtk_hex_view_parent_class)->finalize(G_OBJECT(view));
- result = g_object_new(GTK_TYPE_HEX_DISPLAY, NULL);
+}
- result->cache = g_buffer_cache_new(content, HLC_COUNT, HLC_BINARY);
- g_object_ref_sink(G_OBJECT(result->cache));
- g_generic_config_get_value(get_main_configuration(), MPK_HEX_PADDING, &padding);
- tracker = g_buffer_cache_get_width_tracker(result->cache);
- g_width_tracker_set_column_min_width(tracker, HLC_PADDING, padding);
- g_object_unref(G_OBJECT(tracker));
- result->generator = g_hex_generator_new(content);
- gtk_hex_display_populate_cache(result);
+void demo_measure (GtkWidget *widget,
+ GtkOrientation orientation,
+ int for_size,
+ int *minimum_size,
+ int *natural_size,
+ int *minimum_baseline,
+ int *natural_baseline)
+{
+ printf("set size\n");
- view = g_buffer_view_new(result->cache, NULL);
+ *minimum_size = 100;
+ *natural_size = 200;
+}
- GTK_BUFFER_DISPLAY(result)->view = view;
- return GTK_WIDGET(result);
-}
-/******************************************************************************
-* *
-* 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_hex_display_size_allocate(GtkWidget *widget, GtkAllocation *allocation)
+void demo_snapshot (GtkWidget *widget, GtkSnapshot *snapshot)
{
- GtkHexDisplay *display; /* Autre version du composant */
- GBufferCache *cache; /* Contenu représenté */
- gint text_pos; /* Abscisse minimale du texte */
- bool show_pos; /* Affichage des positions ? */
- GWidthTracker *tracker; /* Gestionnaire de largeurs */
- gint padding; /* Bourrage supplémentaire */
- bool changed; /* Note toute variation */
+ GdkRGBA red, green, yellow, blue;
+ float w, h;
- display = GTK_HEX_DISPLAY(widget);
+ gdk_rgba_parse (&red, "red");
+ gdk_rgba_parse (&green, "green");
+ gdk_rgba_parse (&yellow, "yellow");
+ gdk_rgba_parse (&blue, "blue");
- cache = g_buffer_view_get_cache(GTK_BUFFER_DISPLAY(display)->view);
- text_pos = g_buffer_cache_get_text_position(cache);
- g_object_unref(G_OBJECT(cache));
+ w = gtk_widget_get_width (widget) / 2.0;
+ h = gtk_widget_get_height (widget) / 2.0;
- show_pos = g_display_options_get(GTK_DISPLAY_PANEL(widget)->options, 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));
- tracker = g_buffer_cache_get_width_tracker(display->cache);
- padding = g_width_tracker_get_column_min_width(tracker, HLC_PADDING);
- g_object_unref(G_OBJECT(tracker));
+ /*
+ printf("[widget] CSS name: %s\n", gtk_widget_get_css_name(widget));
- changed = g_hex_generator_auto_fit(display->generator, text_pos, show_pos, padding, allocation->width);
+ char **iter;
- if (changed)
- gtk_hex_display_populate_cache(display);
-
- /**
- * On fait appel au parent en dernier pour bénéficier des besoins
- * en espace actualisés avec les nouvelles dispositions.
- */
+ iter = gtk_widget_get_css_classes(widget);
- GTK_WIDGET_CLASS(gtk_hex_display_parent_class)->size_allocate(widget, allocation);
+ while (*iter)
+ printf("[widget] CSS classes: %s\n", *iter);
+ */
}
+
+#if 0
/******************************************************************************
* *
-* Paramètres : display = composant GTK à consulter. *
-* width = largeur requise à renseigner ou NULL. [OUT] *
-* height = hauteur requise à renseigner ou NULL. [OUT] *
+* Paramètres : widget = composant GTK à examiner. *
+* minimum = largeur minimale à préciser ou NULL. [OUT] *
+* natural = largeur idéale à préciser ou NULL. [OUT] *
* *
-* Description : Indique les dimensions de travail du composant d'affichage. *
+* Description : Fournit la largeur idéale pour le composant d'affichage. *
* *
* Retour : - *
* *
@@ -278,25 +295,31 @@ static void gtk_hex_display_size_allocate(GtkWidget *widget, GtkAllocation *allo
* *
******************************************************************************/
-static void gtk_hex_display_compute_requested_size(GtkHexDisplay *display, gint *width, gint *height)
+static void gtk_hex_view_get_preferred_width(GtkWidget *widget, gint *minimum, gint *natural)
{
- GtkDisplayPanel *pdisplay; /* Version parente */
+ GtkHexView *panel; /* Autre version du composant */
+ gint req; /* Dimension requise */
+
+ panel = GTK_HEX_VIEW(widget);
- pdisplay = GTK_DISPLAY_PANEL(display);
+ GTK_HEX_VIEW_GET_CLASS(widget)->compute_size(panel, &req, NULL);
- GTK_DISPLAY_PANEL_CLASS(gtk_hex_display_parent_class)->compute_size(pdisplay, width, height);
+ req *= panel->scale;
- if (width != NULL && *width != 0)
- *width = 1;
+ if (minimum != NULL) *minimum = req;
+ if (natural != NULL) *natural = req;
}
+
+
/******************************************************************************
* *
-* Paramètres : display = composant GTK à mettre à jour. *
+* Paramètres : panel = composant GTK à venir consulter. *
+* cr = contexte graphique associé à l'événement. *
* *
-* Description : Adapte le cache de lignes hexadécimales à la taille courante.*
+* Description : Dessine si besoin est une bordure autour du composant. *
* *
* Retour : - *
* *
@@ -304,44 +327,50 @@ static void gtk_hex_display_compute_requested_size(GtkHexDisplay *display, gint
* *
******************************************************************************/
-static void gtk_hex_display_populate_cache(GtkHexDisplay *display)
+void gtk_hex_view_draw_border(GtkHexView *panel, cairo_t *cr)
{
- 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*/
- size_t count; /* Nombre actuel de lignes */
+ GtkWidget *widget; /* Autre version du composant */
+ GtkStyleContext *context; /* Contexte du thème actuel */
+ GdkRGBA color; /* Couleur de thème récupérée */
+ GtkRequisition req; /* Taille allouée à l'élément */
+ GtkAllocation area; /* Emplacement à considérer */
- /* Détermination du besoin */
+ if (panel->show_border)
+ {
+ widget = GTK_WIDGET(panel);
- content = g_hex_generator_get_content(display->generator);
+ gtk_widget_get_preferred_size(widget, NULL, &req);
- full = g_binary_content_compute_size(content);
+ context = gtk_widget_get_style_context(widget);
- g_object_unref(G_OBJECT(content));
+ gtk_style_context_save(context);
- line = g_hex_generator_get_bytes_per_line(display->generator);
+ gtk_style_context_add_class(context, GTK_STYLE_CLASS_FRAME);
- needed = full / line;
+ gtk_style_context_get(gtk_widget_get_style_context(widget),
+ gtk_widget_get_state_flags(widget),
+ GTK_STYLE_PROPERTY_COLOR, &color, NULL);
- if (full % line > 0)
- needed++;
+ cairo_set_source_rgba(cr, color.red, color.green, color.blue, color.alpha);
- /* Adaptation du tampon interne */
+ cairo_set_line_width(cr, 1.0);
- g_buffer_cache_wlock(display->cache);
+ gtk_widget_get_preferred_size(GTK_WIDGET(panel), NULL, &req);
- count = g_buffer_cache_count_lines(display->cache);
+ area.x = 0;
+ area.y = 0;
+ area.width = req.width;
+ area.height = req.height;
- if (needed < count)
- g_buffer_cache_truncate(display->cache, needed);
+ gtk_hex_view_define_border_path(panel, cr, &area);
+ cairo_stroke(cr);
- else if (needed > count)
- g_buffer_cache_extend_with(display->cache, needed, G_LINE_GENERATOR(display->generator));
+ gtk_style_context_restore(context);
- g_buffer_cache_wunlock(display->cache);
-
- if (needed != count)
- gtk_widget_queue_resize(GTK_WIDGET(display));
+ }
}
+
+
+
+#endif