[ghex/gtk4-port: 51/91] Implement layout manager and many fixes and tweaks.
- From: Logan Rathbone <larathbone src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [ghex/gtk4-port: 51/91] Implement layout manager and many fixes and tweaks.
- Date: Thu, 12 Aug 2021 23:35:10 +0000 (UTC)
commit 5bcb010c37feaf2f6629d8bdd104d12ce645f9a5
Author: Logan Rathbone <poprocks gmail com>
Date: Sat Jan 23 22:50:16 2021 -0500
Implement layout manager and many fixes and tweaks.
src/Makefile | 3 +-
src/STUB.c | 110 ----
src/chartable.c | 56 +-
src/chartable.h | 6 +
src/common-ui.c | 35 +-
src/common-ui.h | 3 +-
src/debug-test.sh | 2 +-
src/findreplace.c | 143 ++---
src/findreplace.h | 4 +-
src/ghex-application-window.c | 23 +-
src/ghex-ui.xml | 59 --
src/ghex-window.c | 1377 -----------------------------------------
src/ghex-window.h | 114 ----
src/gtkhex-layout-manager.c | 418 +++++++++++++
src/gtkhex-layout-manager.h | 52 ++
src/gtkhex.c | 655 ++++----------------
src/meson.build | 5 +-
17 files changed, 752 insertions(+), 2313 deletions(-)
---
diff --git a/src/Makefile b/src/Makefile
index 9a1a6bed..24dc351f 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -7,12 +7,11 @@ CFLAGS=-Wall -Wextra -Werror=implicit -std=c11 -pedantic \
-Wno-unused-variable -Wno-unused-parameter \
$(GTK_CFLAGS) \
-I../build -I. \
- -DHAVE_CONFIG_H \
$(DEBUG)
.PHONY: clean compile-resources
-STUB: gtkhex.o hex-document.o ghex-application-window.o hex-dialog.o findreplace.o chartable.o converter.o
resources.o configuration.o preferences.o common-ui.o print.o
+main: gtkhex.o hex-document.o ghex-application-window.o hex-dialog.o findreplace.o chartable.o converter.o
resources.o configuration.o preferences.o common-ui.o print.o gtkhex-layout-manager.o
compile-resources:
glib-compile-resources ghex.gresource.xml --target=resources.c --generate-source
diff --git a/src/chartable.c b/src/chartable.c
index 5773d68b..769372e4 100644
--- a/src/chartable.c
+++ b/src/chartable.c
@@ -4,6 +4,8 @@
/* chartable.c - a window with a character table
Copyright (C) 1998 - 2004 Free Software Foundation
+ Copyright © 2005-2020 FIXME
+ Copyright © Logan Rathbone <poprocks gmail com>
GHex is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
@@ -20,24 +22,15 @@
If not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- Author: Jaka Mocnik <jaka gnu org>
+ Original Author: Jaka Mocnik <jaka gnu org>
*/
+#include "chartable.h"
+
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif /* HAVE_CONFIG_H */
-#include <stdlib.h>
-
-#include <gtk/gtk.h>
-#include <gdk/gdkkeysyms.h>
-#include <glib/gi18n.h>
-
-#include <gtkhex.h>
-#include "chartable.h"
-//#include "ghex-window.h"
-//#include "ui.h"
-
/* STATIC GLOBALS */
static GtkTreeSelection *sel_row = NULL;
@@ -121,19 +114,23 @@ chartable_row_activated_cb (GtkTreeView *tree_view,
insert_char (tree_view, model);
}
-
-#if 0
-static gboolean select_chartable_row_cb(GtkTreeView *treeview, GdkEventButton *event, gpointer data)
+static void
+inbtn_clicked_cb (GtkButton *button, gpointer user_data)
{
- GtkTreeModel *model = GTK_TREE_MODEL(data);
+ GtkTreeView *treeview = GTK_TREE_VIEW(user_data);
+ GtkTreeModel *model;
+
+ g_return_if_fail (GTK_IS_TREE_VIEW(treeview));
- if(event->type == GDK_2BUTTON_PRESS)
- insert_char(treeview, model);
- return FALSE;
+ (void)button; /* unused */
+
+ model = gtk_tree_view_get_model (treeview);
+
+ insert_char (treeview, model);
}
-#endif
-static void hide_chartable_cb (GtkButton *button, gpointer user_data)
+static void
+hide_chartable_cb (GtkButton *button, gpointer user_data)
{
GtkWindow *win = GTK_WINDOW(user_data);
@@ -148,7 +145,7 @@ GtkWidget *create_char_table(GtkWindow *parent_win, GtkHex *gh)
static gchar *titles[] = { N_("ASCII"), N_("Hex"), N_("Decimal"),
N_("Octal"), N_("Binary") };
gchar *real_titles[5];
- GtkWidget *ct, *sw, *ctv, *cbtn, *vbox, *hbox, *lbl;
+ GtkWidget *ct, *sw, *ctv, *inbtn, *cbtn, *vbox, *hbox, *lbl;
GtkListStore *store;
GtkCellRenderer *cell_renderer;
GtkTreeViewColumn *column;
@@ -238,18 +235,12 @@ GtkWidget *create_char_table(GtkWindow *parent_win, GtkHex *gh)
g_signal_connect (ctv, "row-activated",
G_CALLBACK(chartable_row_activated_cb), GTK_TREE_MODEL(store));
- // REWRITE
-#if 0
- g_signal_connect(G_OBJECT(ct), "delete-event",
- G_CALLBACK(delete_event_cb), ct);
- g_signal_connect(G_OBJECT(ctv), "button_press_event",
- G_CALLBACK(select_chartable_row_cb), GTK_TREE_MODEL(store));
- g_signal_connect(G_OBJECT(ctv), "key_press_event",
- G_CALLBACK(key_press_cb), GTK_TREE_MODEL(store));
-#endif
-
gtk_widget_grab_focus(ctv);
+ inbtn = gtk_button_new_with_mnemonic (_("_Insert Character"));
+ g_signal_connect(G_OBJECT (inbtn), "clicked",
+ G_CALLBACK(inbtn_clicked_cb), ctv);
+
cbtn = gtk_button_new_with_mnemonic (_("_Close"));
g_signal_connect(G_OBJECT (cbtn), "clicked",
G_CALLBACK(hide_chartable_cb), ct);
@@ -260,6 +251,7 @@ GtkWidget *create_char_table(GtkWindow *parent_win, GtkHex *gh)
gtk_box_append (GTK_BOX(vbox), sw);
gtk_box_append (GTK_BOX(hbox), lbl);
+ gtk_box_append (GTK_BOX(hbox), inbtn);
gtk_box_append (GTK_BOX(hbox), cbtn);
gtk_box_append (GTK_BOX(vbox), hbox);
diff --git a/src/chartable.h b/src/chartable.h
index a0d4640d..5b2ac47e 100644
--- a/src/chartable.h
+++ b/src/chartable.h
@@ -24,7 +24,13 @@
#ifndef GHEX_CHARTABLE_H
#define GHEX_CHARTABLE_H
+#include <stdlib.h>
+
#include <gtk/gtk.h>
+#include <glib/gi18n.h>
+
+#include "gtkhex.h"
+#include "common-ui.h"
G_BEGIN_DECLS
diff --git a/src/common-ui.c b/src/common-ui.c
index d6fa90f6..876cb655 100644
--- a/src/common-ui.c
+++ b/src/common-ui.c
@@ -24,10 +24,11 @@
Original Author: Jaka Mocnik <jaka gnu org>
*/
-#include <config.h> /* Not optional for this. */
-
#include "common-ui.h"
+/* Not optional. */
+#include <config.h>
+
#if 0
static void ghex_print(GtkHex *gh, gboolean preview);
@@ -892,29 +893,41 @@ common_print (GtkWindow *parent, GtkHex *gh, gboolean preview)
g_free (gtk_file_name);
}
-void
-display_error_dialog (GtkWindow *parent, const char *msg)
+static void
+display_dialog (GtkWindow *parent, const char *msg, GtkMessageType type)
{
- GtkWidget *error_dlg;
+ GtkWidget *dialog;
g_return_if_fail (GTK_IS_WINDOW(parent));
g_return_if_fail (msg);
- error_dlg = gtk_message_dialog_new (parent,
+ dialog = gtk_message_dialog_new (parent,
GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
- GTK_MESSAGE_ERROR,
+ type,
GTK_BUTTONS_CLOSE,
"%s", msg);
- gtk_dialog_set_default_response (GTK_DIALOG (error_dlg),
+ gtk_dialog_set_default_response (GTK_DIALOG (dialog),
GTK_RESPONSE_CLOSE);
- gtk_window_set_resizable (GTK_WINDOW (error_dlg), FALSE);
- gtk_widget_show (error_dlg);
+ gtk_window_set_resizable (GTK_WINDOW (dialog), FALSE);
+ gtk_widget_show (dialog);
- g_signal_connect (error_dlg, "response",
+ g_signal_connect (dialog, "response",
G_CALLBACK (gtk_window_destroy), NULL);
}
+void
+display_error_dialog (GtkWindow *parent, const char *msg)
+{
+ display_dialog (parent, msg, GTK_MESSAGE_ERROR);
+}
+
+void
+display_info_dialog (GtkWindow *parent, const char *msg)
+{
+ display_dialog (parent, msg, GTK_MESSAGE_INFO);
+}
+
#if 0
void
display_info_dialog (GHexWindow *win, const gchar *msg, ...)
diff --git a/src/common-ui.h b/src/common-ui.h
index 40ae4728..cbbca4ad 100644
--- a/src/common-ui.h
+++ b/src/common-ui.h
@@ -29,8 +29,8 @@
#include <gtk/gtk.h>
#include <glib/gi18n.h>
-#include <gtkhex.h>
+#include "gtkhex.h"
#include "configuration.h"
#include "print.h"
@@ -42,6 +42,7 @@ void common_help_cb (GtkWindow *parent);
void common_about_cb (GtkWindow *parent);
void common_print (GtkWindow *parent, GtkHex *gh, gboolean preview);
void display_error_dialog (GtkWindow *parent, const char *msg);
+void display_info_dialog (GtkWindow *parent, const char *msg);
G_END_DECLS
diff --git a/src/debug-test.sh b/src/debug-test.sh
index e97a0a4e..2f1c91de 100755
--- a/src/debug-test.sh
+++ b/src/debug-test.sh
@@ -1,6 +1,6 @@
#!/bin/sh
-TEST_PROG="./STUB"
+TEST_PROG="./main"
# GTK_DEBUG=interactive \
G_ENABLE_DIAGNOSTIC=1 \
diff --git a/src/findreplace.c b/src/findreplace.c
index 935a953c..70de85d0 100644
--- a/src/findreplace.c
+++ b/src/findreplace.c
@@ -30,19 +30,13 @@
Author: Jaka Mocnik <jaka gnu org>
*/
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
-
-#include <gtk/gtk.h>
-#include <glib/gi18n.h>
-
#include "findreplace.h"
-//#include "ui.h"
-#include "gtkhex.h"
-#include "configuration.h"
+
+/* Not optional. */
+#include <config.h>
/* DEFINES */
+
#define JUMP_DIALOG_CSS_NAME "jumpdialog"
/* GOBJECT DEFINITIONS */
@@ -104,8 +98,6 @@ G_DEFINE_TYPE (ReplaceDialog, replace_dialog, GTK_TYPE_WIDGET)
/* PRIVATE FUNCTION DECLARATIONS */
-//static gint find_delete_event_cb(GtkWidget *w, GdkEventAny *e,
-// FindDialog *dialog);
static void find_cancel_cb(GtkButton *button, gpointer user_data);
static void replace_cancel_cb (GtkButton *button, gpointer user_data);
static void jump_cancel_cb (GtkButton *button, gpointer user_data);
@@ -121,11 +113,11 @@ static gint get_search_string(HexDocument *doc, gchar **str);
static GtkWidget *
create_hex_view(HexDocument *doc)
{
- GtkWidget *gh = hex_document_add_view(doc);
+ GtkWidget *gh = hex_document_add_view (doc);
+
+ gtk_widget_set_hexpand (gh, TRUE);
- // TEST
- gtk_hex_set_group_type(GTK_HEX(gh), GROUP_BYTE);
-// gtk_hex_set_group_type(GTK_HEX(gh), def_group_type);
+ gtk_hex_set_group_type (GTK_HEX(gh), def_group_type);
// FIXME - JUST DELETE?
#if 0
@@ -134,8 +126,8 @@ create_hex_view(HexDocument *doc)
}
#endif
- gtk_hex_set_insert_mode(GTK_HEX(gh), TRUE);
- gtk_hex_set_geometry(GTK_HEX(gh), 16, 4);
+ gtk_hex_set_insert_mode (GTK_HEX(gh), TRUE);
+ gtk_hex_set_geometry (GTK_HEX(gh), 16, 4);
return gh;
}
@@ -152,23 +144,6 @@ static gint get_search_string(HexDocument *doc, gchar **str)
return size;
}
-#if 0
-/* find and advanced find need special close dialogs, since they
- * need to do stuff with the highlights
- */
-static gint find_delete_event_cb(GtkWidget *w, GdkEventAny *e, FindDialog *dialog)
-{
- GHexWindow *win = ghex_window_get_active();
- GtkHex *gh = win->gh;
-
- if (dialog->auto_highlight) gtk_hex_delete_autohighlight(gh, dialog->auto_highlight);
- dialog->auto_highlight = NULL;
- gtk_widget_hide(w);
-
- return TRUE;
-}
-#endif
-
static void
replace_cancel_cb (GtkButton *button, gpointer user_data)
{
@@ -219,6 +194,7 @@ find_next_cb(GtkButton *button, gpointer user_data)
{
FindDialog *self = FIND_DIALOG(user_data);
GtkWidget *widget = GTK_WIDGET(user_data);
+ GtkWindow *parent;
HexDocument *doc;
guint cursor_pos;
guint offset, str_len;
@@ -229,13 +205,16 @@ find_next_cb(GtkButton *button, gpointer user_data)
(void)button; /* unused */
+ parent = GTK_WINDOW(gtk_widget_get_native (widget));
+ if (! GTK_IS_WINDOW(parent))
+ parent = NULL;
+
doc = gtk_hex_get_document(self->gh);
cursor_pos = gtk_hex_get_cursor(self->gh);
- if ((str_len = get_search_string(self->f_doc, &str)) == 0) {
- g_debug(_("There is no string to search for!"));
- // FIXME
-// display_error_dialog (self, _("There is no string to search for!"));
+ if ((str_len = get_search_string(self->f_doc, &str)) == 0)
+ {
+ display_error_dialog (parent, _("There is no string to search for!"));
return;
}
@@ -256,9 +235,7 @@ find_next_cb(GtkButton *button, gpointer user_data)
gtk_hex_set_cursor(self->gh, offset);
}
else {
- // FIXME - NOT IMPLEMENTED
-// ghex_window_flash(win, _("End Of File reached"));
-// display_info_dialog(self, _("String was not found!\n"));
+ display_info_dialog (parent, _("String was not found!\n"));
}
if (str)
@@ -270,6 +247,7 @@ find_prev_cb(GtkButton *button, gpointer user_data)
{
FindDialog *self = FIND_DIALOG(user_data);
GtkWidget *widget = GTK_WIDGET(user_data);
+ GtkWindow *parent;
HexDocument *doc;
guint cursor_pos;
guint offset, str_len;
@@ -280,12 +258,15 @@ find_prev_cb(GtkButton *button, gpointer user_data)
(void)button; /* unused */
+ parent = GTK_WINDOW(gtk_widget_get_native (widget));
+ if (! GTK_IS_WINDOW(parent))
+ parent = NULL;
+
doc = gtk_hex_get_document(self->gh);
cursor_pos = gtk_hex_get_cursor(self->gh);
if ((str_len = get_search_string(self->f_doc, &str)) == 0) {
- // FIXME
-// display_error_dialog (self, _("There is no string to search for!"));
+ display_error_dialog (parent, _("There is no string to search for!"));
return;
}
@@ -304,9 +285,7 @@ find_prev_cb(GtkButton *button, gpointer user_data)
gtk_hex_set_cursor(self->gh, offset);
}
else {
- // FIXME - NOT IMPLEMENTED
-// ghex_window_flash(win, _("Beginning Of File reached"));
-// display_info_dialog(self, _("String was not found!\n"));
+ display_info_dialog (parent, _("String was not found!\n"));
}
if (str)
g_free(str);
@@ -317,6 +296,7 @@ goto_byte_cb(GtkButton *button, gpointer user_data)
{
JumpDialog *self = JUMP_DIALOG(user_data);
GtkWidget *widget = GTK_WIDGET(user_data);
+ GtkWindow *parent;
HexDocument *doc;
guint cursor_pos;
GtkEntry *entry;
@@ -331,6 +311,10 @@ goto_byte_cb(GtkButton *button, gpointer user_data)
(void)button; /* unused */
+ parent = GTK_WINDOW(gtk_widget_get_native (widget));
+ if (! GTK_IS_WINDOW(parent))
+ parent = NULL;
+
doc = gtk_hex_get_document(self->gh);
cursor_pos = gtk_hex_get_cursor(self->gh);
@@ -352,8 +336,7 @@ goto_byte_cb(GtkButton *button, gpointer user_data)
}
if (len == 0) {
- // FIXME
-// display_error_dialog (self, _("No offset has been specified!"));
+ display_error_dialog (parent, _("No offset has been specified!"));
return;
}
@@ -377,36 +360,27 @@ goto_byte_cb(GtkButton *button, gpointer user_data)
(sscanf(byte_str, "%d", &byte) == 1))) {
if(is_relative) {
if(is_relative == -1 && byte > cursor_pos) {
- // FIXME
-#if 0
- display_error_dialog(self,
+ display_error_dialog(parent,
_("The specified offset is beyond the "
" file boundaries!"));
-#endif
return;
}
byte = byte * is_relative + cursor_pos;
}
if (byte >= doc->file_size) {
- // FIXME
-#if 0
- display_error_dialog(self,
+ display_error_dialog(parent,
_("Can not position cursor beyond the "
"End Of File!"));
-#endif
} else {
gtk_hex_set_cursor(self->gh, byte);
}
}
else {
- // FIXME
-#if 0
- display_error_dialog(self,
+ display_error_dialog(parent,
_("You may only give the offset as:\n"
" - a positive decimal number, or\n"
" - a hex number, beginning with '0x', or\n"
" - a '+' or '-' sign, followed by a relative offset"));
-#endif
}
}
@@ -415,6 +389,7 @@ replace_next_cb (GtkButton *button, gpointer user_data)
{
ReplaceDialog *self = REPLACE_DIALOG(user_data);
GtkWidget *widget = GTK_WIDGET(user_data);
+ GtkWindow *parent;
HexDocument *doc;
guint cursor_pos;
guint offset, str_len;
@@ -423,12 +398,15 @@ replace_next_cb (GtkButton *button, gpointer user_data)
g_return_if_fail (REPLACE_IS_DIALOG(self));
g_return_if_fail (GTK_IS_HEX(self->gh));
+ parent = GTK_WINDOW(gtk_widget_get_native (widget));
+ if (! GTK_IS_WINDOW(parent))
+ parent = NULL;
+
doc = gtk_hex_get_document (self->gh);
cursor_pos = gtk_hex_get_cursor (self->gh);
if ((str_len = get_search_string(self->f_doc, &str)) == 0) {
- // FIXME
-// display_error_dialog (self, _("There is no string to search for!"));
+ display_error_dialog (parent, _("There is no string to search for!"));
return;
}
@@ -438,9 +416,7 @@ replace_next_cb (GtkButton *button, gpointer user_data)
gtk_hex_set_cursor(self->gh, offset);
}
else {
- // FIXME - NOT IMPLEMENTED
-// display_info_dialog (self, _("String was not found!\n"));
-// ghex_window_flash(win, _("End Of File reached"));
+ display_info_dialog (parent, _("String was not found!\n"));
}
if (str)
@@ -452,6 +428,7 @@ replace_one_cb(GtkButton *button, gpointer user_data)
{
ReplaceDialog *self = REPLACE_DIALOG(user_data);
GtkWidget *widget = GTK_WIDGET(user_data);
+ GtkWindow *parent;
HexDocument *doc;
guint cursor_pos;
gchar *find_str = NULL, *rep_str = NULL;
@@ -462,12 +439,15 @@ replace_one_cb(GtkButton *button, gpointer user_data)
(void)button; /* unused */
+ parent = GTK_WINDOW(gtk_widget_get_native (widget));
+ if (! GTK_IS_WINDOW(parent))
+ parent = NULL;
+
doc = gtk_hex_get_document (self->gh);
cursor_pos = gtk_hex_get_cursor (self->gh);
if ((find_len = get_search_string(self->f_doc, &find_str)) == 0) {
- // FIXME
-// display_error_dialog (self, _("There is no string to search for!"));
+ display_error_dialog (parent, _("There is no string to search for!"));
return;
}
rep_len = get_search_string(self->r_doc, &rep_str);
@@ -487,9 +467,7 @@ replace_one_cb(GtkButton *button, gpointer user_data)
gtk_hex_set_cursor(self->gh, offset);
}
else {
- // FIXME - NOT IMPLEMENTED
-// display_info_dialog(self, _("End Of File reached!"));
-// ghex_window_flash(win, _("End Of File reached!"));
+ display_info_dialog (parent, _("String was not found!"));
}
clean_up:
@@ -505,9 +483,10 @@ replace_all_cb (GtkButton *button, gpointer user_data)
{
ReplaceDialog *self = REPLACE_DIALOG(user_data);
GtkWidget *widget = GTK_WIDGET(user_data);
+ GtkWindow *parent;
HexDocument *doc;
guint cursor_pos;
- gchar *find_str = NULL, *rep_str = NULL, *flash;
+ gchar *find_str = NULL, *rep_str = NULL;
guint find_len, rep_len, offset, count;
g_return_if_fail (REPLACE_IS_DIALOG(self));
@@ -515,12 +494,15 @@ replace_all_cb (GtkButton *button, gpointer user_data)
(void)button; /* unused */
+ parent = GTK_WINDOW(gtk_widget_get_native (widget));
+ if (! GTK_IS_WINDOW(parent))
+ parent = NULL;
+
doc = gtk_hex_get_document (self->gh);
cursor_pos = gtk_hex_get_cursor (self->gh);
if ((find_len = get_search_string(self->f_doc, &find_str)) == 0) {
- // FIXME
-// display_error_dialog (self, _("There is no string to search for!"));
+ display_error_dialog (parent, _("There is no string to search for!"));
return;
}
rep_len = get_search_string(self->r_doc, &rep_str);
@@ -541,17 +523,9 @@ replace_all_cb (GtkButton *button, gpointer user_data)
gtk_hex_set_cursor(self->gh, MIN(offset, doc->file_size));
if(count == 0) {
- // FIXME
-// display_info_dialog (self, _("No occurrences were found."));
+ display_info_dialog (parent, _("No occurrences were found."));
}
- flash = g_strdup_printf(ngettext("Replaced %d occurrence.",
- "Replaced %d occurrences.",
- count), count);
- // FIXME - NOT IMPLEMENTED
-// ghex_window_flash(win, flash);
- g_free(flash);
-
clean_up:
if (find_str)
g_free(find_str);
@@ -620,7 +594,6 @@ find_dialog_init (FindDialog *self)
}
-// TODO - see: find_delete_event_cb for some possible destructor hints here?
static void
find_dialog_dispose(GObject *object)
{
@@ -866,7 +839,7 @@ jump_dialog_init (JumpDialog *self)
/* Widget */
- self->box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
+ self->box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 12);
gtk_widget_set_parent (self->box, widget);
/* FIXME/TODO - this is not very intuitive. */
diff --git a/src/findreplace.h b/src/findreplace.h
index 76917bcc..327328f2 100644
--- a/src/findreplace.h
+++ b/src/findreplace.h
@@ -29,9 +29,11 @@
#define FINDREPLACE_H
#include <gtk/gtk.h>
+#include <glib/gi18n.h>
#include "gtkhex.h"
-#include "findreplace.h"
+#include "configuration.h"
+#include "common-ui.h"
G_BEGIN_DECLS
diff --git a/src/ghex-application-window.c b/src/ghex-application-window.c
index 426b833c..23d4173f 100644
--- a/src/ghex-application-window.c
+++ b/src/ghex-application-window.c
@@ -1,5 +1,26 @@
/* vim: ts=4 sw=4 colorcolumn=80
- */
+ * -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* ghex-application-window.c - GHex main application window
+
+ Copyright © 2021 Logan Rathbone <poprocks gmail com>
+
+ GHex 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 2 of the
+ License, or (at your option) any later version.
+
+ GHex 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 GHex; see the file COPYING.
+ If not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+ Original GHex Author: Jaka Mocnik <jaka gnu org>
+*/
#include "ghex-application-window.h"
diff --git a/src/gtkhex-layout-manager.c b/src/gtkhex-layout-manager.c
new file mode 100644
index 00000000..51cecae2
--- /dev/null
+++ b/src/gtkhex-layout-manager.c
@@ -0,0 +1,418 @@
+/* vim: ts=4 sw=4 colorcolumn=80
+ * -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* gtkhex-layout-manager.h - declaration of a GtkHex layout manager
+
+ Copyright © 2021 Logan Rathbone <poprocks gmail com>
+
+ GHex 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 2 of the
+ License, or (at your option) any later version.
+
+ GHex 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 GHex; see the file COPYING.
+ If not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+ Original GHex Author: Jaka Mocnik <jaka gnu org>
+*/
+
+#include "gtkhex-layout-manager.h"
+
+#define OFFSETS_CPL 10
+#define HEX_RATIO 0.75
+#define ASCII_RATIO 0.25
+
+struct _GtkHexLayout {
+ GtkLayoutManager parent_instance;
+
+ GtkWidget *offets;
+ GtkWidget *hex;
+ GtkWidget *ascii;
+
+ guint char_width;
+// guint group_type;
+
+ int hex_width;
+ int ascii_width;
+};
+
+G_DEFINE_TYPE (GtkHexLayout, gtk_hex_layout, GTK_TYPE_LAYOUT_MANAGER)
+
+struct _GtkHexLayoutChild {
+ GtkLayoutChild parent_instance;
+
+ GtkHexLayoutColumn column;
+};
+
+enum {
+ PROP_CHILD_COLUMN = 1,
+
+ N_CHILD_PROPERTIES
+};
+
+static GParamSpec *child_props[N_CHILD_PROPERTIES];
+
+/* Some code required to use g_param_spec_enum below. */
+
+#define GTK_HEX_LAYOUT_COLUMN (gtk_hex_layout_column_get_type ())
+static GType
+gtk_hex_layout_column_get_type (void)
+{
+ static GType hex_layout_column_type = 0;
+ static const GEnumValue format_types[] = {
+ {OFFSETS_COLUMN, "Offsets", "offsets"},
+ {HEX_COLUMN, "Hex", "hex"},
+ {ASCII_COLUMN, "ASCII", "ascii"},
+ {0, NULL, NULL}
+ };
+ if (! hex_layout_column_type) {
+ hex_layout_column_type =
+ g_enum_register_static ("GstAudioParseFormat", format_types);
+ }
+ return hex_layout_column_type;
+}
+
+
+G_DEFINE_TYPE (GtkHexLayoutChild, gtk_hex_layout_child, GTK_TYPE_LAYOUT_CHILD)
+
+
+/* LAYOUT CHILD METHODS */
+
+static void
+gtk_hex_layout_child_set_property (GObject *gobject,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ GtkHexLayoutChild *self = GTK_HEX_LAYOUT_CHILD(gobject);
+
+ switch (prop_id)
+ {
+ case PROP_CHILD_COLUMN:
+ self->column = g_value_get_enum (value);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+gtk_hex_layout_child_get_property (GObject *gobject,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ GtkHexLayoutChild *self = GTK_HEX_LAYOUT_CHILD(gobject);
+
+ switch (prop_id)
+ {
+ case PROP_CHILD_COLUMN:
+ g_value_set_enum (value, self->column);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+gtk_hex_layout_child_finalize (GObject *gobject)
+{
+ GtkHexLayoutChild *self = GTK_HEX_LAYOUT_CHILD (gobject);
+
+ G_OBJECT_CLASS (gtk_hex_layout_child_parent_class)->finalize (gobject);
+}
+
+static void
+gtk_hex_layout_child_dispose (GObject *gobject)
+{
+ GtkHexLayoutChild *self = GTK_HEX_LAYOUT_CHILD (gobject);
+
+ G_OBJECT_CLASS (gtk_hex_layout_child_parent_class)->finalize (gobject);
+}
+
+static void
+gtk_hex_layout_child_class_init (GtkHexLayoutChildClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+
+ gobject_class->set_property = gtk_hex_layout_child_set_property;
+ gobject_class->get_property = gtk_hex_layout_child_get_property;
+ gobject_class->finalize = gtk_hex_layout_child_finalize;
+ gobject_class->dispose = gtk_hex_layout_child_dispose;
+
+ child_props[PROP_CHILD_COLUMN] = g_param_spec_enum ("column",
+ "Column type",
+ "The column type of a child of a hex layout",
+ GTK_HEX_LAYOUT_COLUMN,
+ HEX_COLUMN,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
+ G_PARAM_EXPLICIT_NOTIFY);
+
+ g_object_class_install_properties (gobject_class,
+ N_CHILD_PROPERTIES, child_props);
+}
+
+static void
+gtk_hex_layout_child_init (GtkHexLayoutChild *self)
+{
+}
+
+
+/* LAYOUT MANAGER METHODS */
+
+static void
+gtk_hex_layout_measure (GtkLayoutManager *layout_manager,
+ GtkWidget *widget,
+ GtkOrientation orientation,
+ int for_size,
+ int *minimum,
+ int *natural,
+ int *minimum_baseline,
+ int *natural_baseline)
+{
+ GtkHexLayoutChild *child_info;
+ GtkWidget *child;
+ int minimum_size = 0;
+ int natural_size = 0;
+
+ for (child = gtk_widget_get_first_child (widget);
+ child != NULL;
+ child = gtk_widget_get_next_sibling (child))
+ {
+ int child_min = 0, child_nat = 0;
+
+ if (!gtk_widget_should_layout (child))
+ continue;
+
+ child_info =
+ GTK_HEX_LAYOUT_CHILD(gtk_layout_manager_get_layout_child
+ (layout_manager, child));
+
+ gtk_widget_measure (child, orientation,
+ /* for-size: */ -1, /* == unknown. */
+ &child_min, &child_nat,
+ NULL, NULL);
+ minimum_size = MAX (minimum_size, child_min);
+ natural_size = MAX (natural_size, child_nat);
+ }
+
+ // TEST - I have no idea what I'm supposed to be doing here.
+
+ if (minimum != NULL)
+ *minimum = minimum_size;
+ if (natural != NULL)
+ *natural = natural_size;
+}
+
+static void
+gtk_hex_layout_allocate (GtkLayoutManager *layout_manager,
+ GtkWidget *widget,
+ int width,
+ int height,
+ int baseline)
+{
+ GtkHexLayout *self = GTK_HEX_LAYOUT (layout_manager);
+ GtkHexLayoutChild *child_info;
+ GtkWidget *child;
+ gboolean have_offsets = FALSE;
+ gboolean have_hex = FALSE;
+ gboolean have_ascii = FALSE;
+ GtkAllocation base_alloc = {.x = 0, .y = 0, .width = 0, .height = height};
+ GtkAllocation off_alloc = base_alloc; /* GdkRectangle */
+ GtkAllocation hex_alloc = base_alloc;
+ GtkAllocation asc_alloc = base_alloc;
+ GtkAllocation scr_alloc = base_alloc;
+ GtkAllocation tmp_alloc = {0};
+
+ for (child = gtk_widget_get_first_child (widget);
+ child != NULL;
+ child = gtk_widget_get_next_sibling (child))
+ {
+ GtkRequisition child_req = { .width = 0, .height = 0 };
+
+ if (! gtk_widget_should_layout (child))
+ continue;
+
+ /* Get preferred size of the child widget
+ */
+ gtk_widget_get_preferred_size (child, &child_req, NULL);
+
+ /* Setup allocation depending on what column we're in.
+ */
+ child_info =
+ GTK_HEX_LAYOUT_CHILD(gtk_layout_manager_get_layout_child (layout_manager,
+ child));
+
+ switch (child_info->column)
+ {
+ case OFFSETS_COLUMN:
+ have_offsets = TRUE;
+ off_alloc.width = OFFSETS_CPL * self->char_width;
+ break;
+ case HEX_COLUMN:
+ have_hex = TRUE;
+ break;
+ case ASCII_COLUMN:
+ have_ascii = TRUE;
+ break;
+ case SCROLLBAR_COLUMN:
+ scr_alloc.x = width;
+ scr_alloc.width = child_req.width;
+ scr_alloc.height = height;
+ break;
+ default:
+ g_error ("%s: Programming error. The requested column is invalid.",
+ __func__);
+ break;
+ }
+ }
+
+ for (child = gtk_widget_get_first_child (widget);
+ child != NULL;
+ child = gtk_widget_get_next_sibling (child))
+ {
+ GtkRequisition child_req = { .width = 0, .height = 0 };
+
+ if (! gtk_widget_should_layout (child))
+ continue;
+
+ /* Get preferred size of the child widget
+ */
+ gtk_widget_get_preferred_size (child, &child_req, NULL);
+
+ /* Setup allocation depending on what column we're in.
+ */
+ child_info =
+ GTK_HEX_LAYOUT_CHILD(gtk_layout_manager_get_layout_child
+ (layout_manager, child));
+
+ switch (child_info->column)
+ {
+ case OFFSETS_COLUMN:
+ tmp_alloc = off_alloc;
+ break;
+
+ case HEX_COLUMN:
+ hex_alloc.width = width - off_alloc.width;
+ hex_alloc.width -= scr_alloc.width;
+ if (have_ascii) {
+ hex_alloc.width *= HEX_RATIO;
+ hex_alloc.x += off_alloc.width;
+ }
+ tmp_alloc = hex_alloc;
+ break;
+
+ case ASCII_COLUMN:
+ asc_alloc.x += off_alloc.width;
+ asc_alloc.width = width;
+ asc_alloc.width -= off_alloc.width;
+ asc_alloc.width -= scr_alloc.width;
+ if (have_hex) {
+ asc_alloc.width *= ASCII_RATIO;
+ asc_alloc.x += (width - off_alloc.width - scr_alloc.width)
+ * HEX_RATIO;
+ }
+ tmp_alloc = asc_alloc;
+ break;
+
+ case SCROLLBAR_COLUMN:
+ tmp_alloc = scr_alloc;
+ break;
+
+ default:
+ g_error ("%s: Programming error. The requested column is invalid.",
+ __func__);
+ break;
+ }
+
+ gtk_widget_size_allocate (child,
+ &tmp_alloc,
+ -1); /* baseline, or -1 */
+ }
+}
+
+static GtkSizeRequestMode
+gtk_hex_layout_get_request_mode (GtkLayoutManager *layout_manager,
+ GtkWidget *widget)
+{
+ /* I understand this is the default return type anyway; but I guess it
+ * makes sense to explicit.
+ */
+ return GTK_SIZE_REQUEST_CONSTANT_SIZE;
+}
+
+static GtkLayoutChild *
+gtk_hex_layout_create_layout_child (GtkLayoutManager *manager,
+ GtkWidget *widget,
+ GtkWidget *for_child)
+{
+ return g_object_new (GTK_TYPE_HEX_LAYOUT_CHILD,
+ "layout-manager", manager,
+ "child-widget", for_child,
+ NULL);
+}
+
+static void
+gtk_hex_layout_class_init (GtkHexLayoutClass *klass)
+{
+ GtkLayoutManagerClass *layout_class = GTK_LAYOUT_MANAGER_CLASS (klass);
+
+ layout_class->get_request_mode = gtk_hex_layout_get_request_mode;
+ layout_class->measure = gtk_hex_layout_measure;
+ layout_class->allocate = gtk_hex_layout_allocate;
+ layout_class->create_layout_child = gtk_hex_layout_create_layout_child;
+}
+
+static void
+gtk_hex_layout_init (GtkHexLayout *self)
+{
+ g_debug ("%s: TEST - SETTING A DEFAULT MINIMUM CHAR-WIDTH",
+ __func__);
+ self->char_width = 20;
+}
+
+/* GtkHexLayout - Public Methods */
+
+GtkLayoutManager *
+gtk_hex_layout_new (void)
+{
+ return g_object_new (GTK_TYPE_HEX_LAYOUT, NULL);
+}
+
+void
+gtk_hex_layout_set_char_width (GtkHexLayout *layout, guint width)
+{
+ layout->char_width = width;
+
+ gtk_layout_manager_layout_changed (GTK_LAYOUT_MANAGER(layout));
+}
+
+/* GtkHexLayoutChild - Public Methods */
+
+void
+gtk_hex_layout_child_set_column (GtkHexLayoutChild *child,
+ GtkHexLayoutColumn column)
+{
+ g_return_if_fail (GTK_IS_HEX_LAYOUT_CHILD (child));
+
+ if (child->column == column)
+ return;
+
+ child->column = column;
+
+ gtk_layout_manager_layout_changed
+ (gtk_layout_child_get_layout_manager (GTK_LAYOUT_CHILD(child)));
+
+ g_object_notify_by_pspec (G_OBJECT(child),
+ child_props[PROP_CHILD_COLUMN]);
+}
diff --git a/src/gtkhex-layout-manager.h b/src/gtkhex-layout-manager.h
new file mode 100644
index 00000000..58fce879
--- /dev/null
+++ b/src/gtkhex-layout-manager.h
@@ -0,0 +1,52 @@
+/* vim: ts=4 sw=4 colorcolumn=80
+ * -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* gtkhex-layout-manager.h - declaration of a GtkHex layout manager
+
+ Copyright © 2021 Logan Rathbone <poprocks gmail com>
+
+ GHex 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 2 of the
+ License, or (at your option) any later version.
+
+ GHex 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 GHex; see the file COPYING.
+ If not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+ Original GHex Author: Jaka Mocnik <jaka gnu org>
+*/
+
+#ifndef GTK_HEX_LAYOUT_MANAGER_H
+#define GTK_HEX_LAYOUT_MANAGER_H
+
+#include <gtk/gtk.h>
+
+#define GTK_TYPE_HEX_LAYOUT (gtk_hex_layout_get_type ())
+G_DECLARE_FINAL_TYPE (GtkHexLayout, gtk_hex_layout, GTK, HEX_LAYOUT,
+ GtkLayoutManager)
+
+typedef enum {
+ OFFSETS_COLUMN,
+ HEX_COLUMN,
+ ASCII_COLUMN,
+ SCROLLBAR_COLUMN
+} GtkHexLayoutColumn;
+
+#define GTK_TYPE_HEX_LAYOUT_CHILD (gtk_hex_layout_child_get_type ())
+G_DECLARE_FINAL_TYPE (GtkHexLayoutChild, gtk_hex_layout_child,
+ GTK, HEX_LAYOUT_CHILD,
+ GtkLayoutChild)
+
+GtkLayoutManager * gtk_hex_layout_new (void);
+void gtk_hex_layout_set_char_width (GtkHexLayout *layout,
+ guint width);
+void gtk_hex_layout_child_set_column (GtkHexLayoutChild *child,
+ GtkHexLayoutColumn column);
+
+#endif
diff --git a/src/gtkhex.c b/src/gtkhex.c
index 37a07d88..c5ef6253 100644
--- a/src/gtkhex.c
+++ b/src/gtkhex.c
@@ -30,21 +30,32 @@
Original Author: Jaka Mocnik <jaka gnu org>
*/
-#include <config.h>
+#include "gtkhex.h"
#include <string.h>
-#include "hex-document.h"
-#include "gtkhex.h"
+/* Not optional. */
+#include <config.h>
+
+/* Don't move these from the source file as they are not part of the public
+ * header.
+ */
+#include "gtkhex-layout-manager.h"
/* LAR - TEMPORARY FOR TESTING ONLY */
#ifdef ENABLE_DEBUG
-#define TEST_DEBUG_FUNCTION_START g_debug ("%s: start", __func__);
+#define TEST_DEBUG_FUNCTION_START g_debug ("%s: [START]", __func__);
#else
#define TEST_DEBUG_FUNCTION_START /* */
#endif
+#ifdef ENABLE_DEBUG
+#define TEST_DEBUG_FUNCTION_END g_debug ("%s: [END]", __func__);
+#else
+#define TEST_DEBUG_FUNCTION_END /* */
+#endif
+
#define NOT_IMPLEMENTED \
g_critical("%s: NOT IMPLEMENTED", __func__);
@@ -53,7 +64,7 @@
//#define CSS_NAME "entry"
/* default minimum drawing area size (for ascii and hex widgets) in pixels. */
-#define DEFAULT_DA_SIZE 100
+#define DEFAULT_DA_SIZE 50
/* LAR - defines copied from the old header. */
@@ -83,6 +94,7 @@ enum {
CUT_CLIPBOARD_SIGNAL,
COPY_CLIPBOARD_SIGNAL,
PASTE_CLIPBOARD_SIGNAL,
+ DRAW_COMPLETE_SIGNAL,
LAST_SIGNAL
};
@@ -139,6 +151,7 @@ struct _GtkHex
HexDocument *document;
+ GtkLayoutManager *layout_manager;
GtkWidget *box; /* main box for layout */
GtkWidget *xdisp, *adisp; /* DrawingArea */
@@ -399,6 +412,11 @@ get_char_width (GtkHex *gh)
/* scale down from pango units to pixels */
width = PANGO_PIXELS(width);
+ /* update layout manager */
+ if (GTK_IS_HEX_LAYOUT(gh->layout_manager)) {
+ gtk_hex_layout_set_char_width (gh->layout_manager, width);
+ }
+
return width;
}
@@ -626,8 +644,6 @@ render_xc (GtkHex *gh,
g_return_if_fail (gtk_widget_get_realized (gh->xdisp));
- TEST_DEBUG_FUNCTION_START
-
context = gtk_widget_get_style_context (gh->xdisp);
state = gtk_widget_get_state_flags (gh->xdisp);
@@ -941,16 +957,11 @@ render_hex_lines (GtkHex *gh,
g_return_if_fail (gtk_widget_get_realized (GTK_WIDGET(gh)));
g_return_if_fail (gh->cpl > 0);
- TEST_DEBUG_FUNCTION_START
-
context = gtk_widget_get_style_context (widget);
state = gtk_widget_get_state_flags (widget);
cursor_line = gh->cursor_pos / gh->cpl - gh->top_line;
gtk_widget_get_allocation (widget, &allocation);
- g_debug("%s: WIDTH: %d HEIGHT: %d",
- __func__, allocation.width, allocation.height);
-
/* render background. */
gtk_render_background (context, cr,
/* x: */ 0,
@@ -966,9 +977,9 @@ render_hex_lines (GtkHex *gh,
* it to make it clearer?
*/
frm_len = format_xblock (gh, gh->disp_buffer,
- (gh->top_line+min_lines)*gh->cpl,
- MIN((gh->top_line+max_lines+1)*gh->cpl,
- gh->document->file_size) );
+ (gh->top_line + min_lines) * gh->cpl,
+ MIN( (gh->top_line + max_lines + 1) * gh->cpl,
+ gh->document->file_size ));
for (int i = min_lines; i <= max_lines; i++)
{
@@ -991,9 +1002,6 @@ render_hex_lines (GtkHex *gh,
gh->xlayout);
}
- // TEST
- g_debug("%s: cursor_line: %d - min_lines: %d - max_lines: %d - cursor_shown: %d",
- __func__, cursor_line, min_lines, max_lines, gh->cursor_shown);
if ( (cursor_line >= min_lines) && (cursor_line <= max_lines) &&
(gh->cursor_shown) )
{
@@ -1017,8 +1025,6 @@ render_ascii_lines (GtkHex *gh,
g_return_if_fail (gtk_widget_get_realized (GTK_WIDGET(gh)));
g_return_if_fail (gh->cpl);
- TEST_DEBUG_FUNCTION_START
-
context = gtk_widget_get_style_context (widget);
state = gtk_widget_get_state_flags (widget);
cursor_line = gh->cursor_pos / gh->cpl - gh->top_line;
@@ -1035,9 +1041,9 @@ render_ascii_lines (GtkHex *gh,
max_lines = MIN(max_lines, gh->lines);
frm_len = format_ablock (gh, gh->disp_buffer,
- (gh->top_line+min_lines)*gh->cpl,
- MIN((gh->top_line+max_lines+1)*gh->cpl,
- gh->document->file_size));
+ (gh->top_line + min_lines) * gh->cpl,
+ MIN( (gh->top_line + max_lines + 1) * gh->cpl,
+ gh->document->file_size ));
for (int i = min_lines; i <= max_lines; i++)
{
@@ -1079,8 +1085,6 @@ render_offsets (GtkHex *gh,
/* offset chars (8) + 1 (null terminator) */
char offstr[9];
- TEST_DEBUG_FUNCTION_START
-
g_return_if_fail (gtk_widget_get_realized (GTK_WIDGET (gh)));
context = gtk_widget_get_style_context (widget);
@@ -1126,9 +1130,10 @@ hex_draw (GtkDrawingArea *drawing_area,
GtkHex *gh = GTK_HEX(user_data);
int xcpl = 0;
- TEST_DEBUG_FUNCTION_START
g_return_if_fail(GTK_IS_HEX(gh));
+ TEST_DEBUG_FUNCTION_START
+
/* Here's the idea here: the hex drawing widget can expand at will,
* and we generate our cpl as a whole and to be passed to the ascii draw
* function based on that.
@@ -1137,9 +1142,6 @@ hex_draw (GtkDrawingArea *drawing_area,
* the hex lines and before proceeding to draw the ascii widget.
*/
- g_debug("%s: width: %d - height: %d",
- __func__, width, height);
-
/* Total number of characters that can be displayed per line on the hex
* widget (xcpl) is the simplest calculation:
*/
@@ -1169,11 +1171,7 @@ hex_draw (GtkDrawingArea *drawing_area,
/* pixel width of ascii drawing area */
gh->adisp_width = gh->cpl * gh->char_width;
- /* set visible lines */
- gh->vis_lines = height / gh->char_height;
-
/* If gh->cpl is not greater than 0, something has gone wrong. */
- g_debug("%s: gh->cpl: %d", __func__, gh->cpl);
g_return_if_fail (gh->cpl > 0);
/* Now that we have gh->cpl defined, run this function to bump all
@@ -1185,6 +1183,8 @@ hex_draw (GtkDrawingArea *drawing_area,
* lines!
*/
render_hex_lines (gh, cr, 0, gh->vis_lines);
+
+ TEST_DEBUG_FUNCTION_END
}
@@ -1197,13 +1197,9 @@ ascii_draw (GtkDrawingArea *drawing_area,
{
GtkHex *gh = GTK_HEX(user_data);
- TEST_DEBUG_FUNCTION_START
g_return_if_fail(GTK_IS_HEX(gh));
- gtk_drawing_area_set_content_width (drawing_area, gh->adisp_width);
-
- g_debug("%s: width: %d - height: %d",
- __func__, width, height);
+ TEST_DEBUG_FUNCTION_START
render_ascii_lines (gh, cr, 0, gh->vis_lines);
@@ -1224,6 +1220,8 @@ ascii_draw (GtkDrawingArea *drawing_area,
render_ascii_lines (gh, cr, imin, imax);
#endif
+
+ TEST_DEBUG_FUNCTION_END
}
static void
@@ -1234,17 +1232,7 @@ offsets_draw (GtkDrawingArea *drawing_area,
gpointer user_data)
{
GtkHex *gh = GTK_HEX(user_data);
-
g_return_if_fail(GTK_IS_HEX(gh));
- TEST_DEBUG_FUNCTION_START
-
- /* FIXME - MAGIC NUMBER - set the width to 8 + 1 = 9 characters
- * (this is fixed based on offset length always being 8 chars.) */
- gtk_drawing_area_set_content_width (drawing_area,
- 9 * gh->char_width);
-
- g_debug("%s: width: %d - height: %d",
- __func__, width, height);
render_offsets (gh, cr, 0, gh->vis_lines);
@@ -1268,9 +1256,7 @@ offsets_draw (GtkDrawingArea *drawing_area,
#endif
}
-// FIXME - CLEAN UP THIS MESS! Not touching it right now because I don't
-// know whether we'll need to 'revive' some variables that aren't really
-// used here, like 'old_cpl'
+// FIXME - CLEAN UP FURTHER.
/*
* this calculates how many bytes we can stuff into one line and how many
* lines we can display according to the current size of the widget
@@ -1279,87 +1265,12 @@ static void
recalc_displays(GtkHex *gh)
{
GtkWidget *widget = GTK_WIDGET (gh);
- int old_cpl = gh->cpl;
- gboolean scroll_to_cursor;
- gdouble value;
- int total_cpl, xcpl;
- // TEST
- GtkStyleContext *context;
- GtkBorder padding;
- GtkBorder border;
-
- // TEST - no longer needed??
-#if 0
- context = gtk_widget_get_style_context (widget);
-
- gtk_style_context_get_padding (context, &padding);
- gtk_style_context_get_border (context, &border);
-#endif
+ int xcpl;
/*
* Only change the value of the adjustment to put the cursor on screen
* if the cursor is currently within the displayed portion.
*/
- // FIXME - WTF??
- scroll_to_cursor = (gh->cpl == 0) ||
- ((gh->cursor_pos / gh->cpl >= gtk_adjustment_get_value (gh->adj)) &&
- (gh->cursor_pos / gh->cpl <= gtk_adjustment_get_value (gh->adj) +
- gh->vis_lines - 1));
-
- // TEST - no longer needed?
-#if 0
- gh->xdisp_width = 1;
- gh->adisp_width = 1;
-#endif
-
-#if 0
- // API CHANGE
- total_width -= 20 + // LAR DUMB TEST
- 2 * padding.left + 2 * padding.right + req.width;
-
-// total_width -= 2*gtk_container_get_border_width(GTK_CONTAINER(gh)) +
-// 2 * padding.left + 2 * padding.right + req.width;
-
- if(gh->show_offsets)
- total_width -= padding.left + padding.right + 9 * gh->char_width;
-#endif
-
- // TEST - MOVED TO HEX_DRAW
-#if 0
- // TEST - DUMB HACK
- total_width = total_width - padding.left - padding.right -
- border.left - border.right - 100;
-
- total_cpl = total_width / gh->char_width;
-
- /* Sanity check. */
- if (total_cpl == 0 || total_width < 0) {
- gh->cpl = gh->lines = gh->vis_lines = 0;
- g_critical("%s: Something has gone wrong; total cpl is 0 or "
- "width is too small.");
- return;
- }
-
- /* calculate how many bytes we can stuff in one line */
- gh->cpl = 0;
- do {
- if (gh->cpl % gh->group_type == 0 && total_cpl < gh->group_type * 3)
- break;
-
- gh->cpl++; /* just added one more char */
- total_cpl -= 3; /* 2 for xdisp, 1 for adisp */
-
- if (gh->cpl % gh->group_type == 0) /* just ended a group */
- total_cpl--;
-
- } while (total_cpl > 0);
-
- /* If gh->cpl is not greater than 0, something has gone wrong. */
- g_debug("%s: gh->cpl: %d", __func__, gh->cpl);
- g_return_if_fail (gh->cpl > 0);
-#endif
-
- // TEST
if (gh->document->file_size == 0 || gh->cpl == 0)
// if (gh->document->file_size == 0)
gh->lines = 1;
@@ -1369,40 +1280,32 @@ recalc_displays(GtkHex *gh)
gh->lines++;
}
- // TEST - TRYING MOVING TO HEX_DRAW
-#if 0
- /* set visible lines */
- gh->vis_lines = height / gh->char_height;
-#endif
-
- // MOVED TO HEX_DRAW
-#if 0
- /* display width of ascii drawing area */
- gh->adisp_width = gh->cpl * gh->char_width;
-#endif
/* set number of hex characters per line */
+ // FIXME - different than 'xcpl' in hex_draw. confusing.
xcpl = gh->cpl * 2 + (gh->cpl - 1) / gh->group_type;
-#if 0
- /* display width of hex drawing area */
- gh->xdisp_width = xcpl * gh->char_width;
-
- gh->extra_width = total_width - gh->xdisp_width - gh->adisp_width;
- g_debug("%s: TOTAL_WIDTH: %d - GH->ADISP_WIDTH: %d - GH->XDISP_WIDTH: %d - GH->EXTRA_WIDTH: %d",
- __func__,
- total_width, gh->adisp_width, gh->xdisp_width, gh->extra_width);
-#endif
-
if (gh->disp_buffer)
g_free (gh->disp_buffer);
gh->disp_buffer = g_malloc ((xcpl + 1) * (gh->vis_lines + 1));
+}
+
+static void
+recalc_scrolling (GtkHex *gh)
+{
+ gboolean scroll_to_cursor;
+ gdouble value;
+
+ scroll_to_cursor = (gh->cpl == 0) ||
+ ((gh->cursor_pos / gh->cpl >= gtk_adjustment_get_value (gh->adj)) &&
+ (gh->cursor_pos / gh->cpl <= gtk_adjustment_get_value (gh->adj) +
+ gh->vis_lines - 1));
/* calculate new display position */
if (gh->cpl == 0) // TEST to avoid divide by zero
value = 0;
else
- value = MIN (gh->top_line * old_cpl / gh->cpl, gh->lines - gh->vis_lines);
+ value = MIN (gh->top_line, gh->lines - gh->vis_lines);
/* clamp value */
value = MAX (0, value);
@@ -1433,7 +1336,7 @@ recalc_displays(GtkHex *gh)
* connected to value-changed signal of scrollbar's GtkAdjustment
*/
static void
-display_scrolled(GtkAdjustment *adj, GtkHex *gh)
+display_scrolled (GtkAdjustment *adj, GtkHex *gh)
{
gint dx;
gint dy;
@@ -1443,20 +1346,25 @@ display_scrolled(GtkAdjustment *adj, GtkHex *gh)
g_return_if_fail (gtk_widget_is_drawable (gh->xdisp) &&
gtk_widget_is_drawable (gh->adisp));
- g_debug("%s: ADJ: %f",
+ g_debug("%s: ADJ - VALUE: %f",
__func__,
- gtk_adjustment_get_page_size (gh->adj));
+ gtk_adjustment_get_value (gh->adj));
- gh->top_line = gtk_adjustment_get_value(adj);
+ gh->top_line = gtk_adjustment_get_value (adj);
gtk_hex_update_all_auto_highlights(gh, TRUE, TRUE);
gtk_hex_invalidate_all_highlights(gh);
- // TEST FOR SCROLLING - yes it's needed.. not the best appraoch, but for
- // now it works.
+ /* FIXME - this works, but feels hackish. The problem is, _snapshot_child
+ * does nothing if it 'detects' that a widget does not need to be redrawn
+ * which is what it seems to think re: our drawing areas on a scroll event.
+ */
gtk_widget_queue_draw (GTK_WIDGET(gh->adisp));
gtk_widget_queue_draw (GTK_WIDGET(gh->xdisp));
gtk_widget_queue_draw (GTK_WIDGET(gh->offsets));
+ gtk_widget_queue_draw (GTK_WIDGET(gh));
+
+ TEST_DEBUG_FUNCTION_END
}
/*
@@ -1475,7 +1383,6 @@ scroll_timeout_handler(GtkHex *gh)
return TRUE;
}
-/* REWRITE */
static gboolean
scroll_cb (GtkEventControllerScroll *controller,
double dx,
@@ -1483,12 +1390,9 @@ scroll_cb (GtkEventControllerScroll *controller,
gpointer user_data)
{
GtkHex *gh = GTK_HEX (user_data);
-// GtkWidget *widget = GTK_WIDGET (gh->xdisp);
guint button;
double old_value, new_value;
- TEST_DEBUG_FUNCTION_START
-
g_return_val_if_fail (GTK_IS_HEX(gh), FALSE);
old_value = gtk_adjustment_get_value(gh->adj);
@@ -1513,16 +1417,12 @@ hex_pressed_cb (GtkGestureClick *gesture,
GtkWidget *widget = GTK_WIDGET (gh->xdisp);
guint button;
- TEST_DEBUG_FUNCTION_START
g_return_if_fail (GTK_IS_HEX(gh));
g_return_if_fail (GTK_IS_WIDGET(widget));
button = gtk_gesture_single_get_current_button
(GTK_GESTURE_SINGLE(gesture));
- g_debug("%s: n_press: %d, x: %f - y: %f - button: %u",
- __func__, n_press, x, y, button);
-
/* Single-press */
if (button == GDK_BUTTON_PRIMARY)
{
@@ -1591,7 +1491,6 @@ hex_released_cb (GtkGestureClick *gesture,
GtkWidget *widget = GTK_WIDGET (gh->xdisp);
guint button;
- TEST_DEBUG_FUNCTION_START
g_return_if_fail (GTK_IS_HEX(gh));
g_return_if_fail (GTK_IS_WIDGET(widget));
@@ -1612,6 +1511,8 @@ hex_released_cb (GtkGestureClick *gesture,
}
}
+// FIXME - UNUSED FOR NOW - HERE'S BOILERPLATE IF NEEDED LATER
+#if 0
static void
hex_drag_begin_cb (GtkGestureDrag *gesture,
double start_x,
@@ -1622,7 +1523,6 @@ hex_drag_begin_cb (GtkGestureDrag *gesture,
GtkWidget *widget = GTK_WIDGET (gh->xdisp);
guint button;
- TEST_DEBUG_FUNCTION_START
g_return_if_fail (GTK_IS_HEX(gh));
g_return_if_fail (GTK_IS_WIDGET(widget));
@@ -1641,13 +1541,13 @@ hex_drag_end_cb (GtkGestureDrag *gesture,
GtkWidget *widget = GTK_WIDGET (gh->xdisp);
guint button;
- TEST_DEBUG_FUNCTION_START
g_return_if_fail (GTK_IS_HEX(gh));
g_return_if_fail (GTK_IS_WIDGET(widget));
g_debug("%s: offset_x: %f - offset_y: %f",
__func__, offset_x, offset_y);
}
+#endif
static void
hex_drag_update_cb (GtkGestureDrag *gesture,
@@ -1658,35 +1558,19 @@ hex_drag_update_cb (GtkGestureDrag *gesture,
GtkHex *gh = GTK_HEX (user_data);
GtkWidget *widget = GTK_WIDGET (gh->xdisp);
guint button;
-
- // TEST
double start_x, start_y;
double x, y;
-
- // TEST - FROM OLD CODE:
GtkAllocation allocation;
- TEST_DEBUG_FUNCTION_START
g_return_if_fail (GTK_IS_HEX(gh));
g_return_if_fail (GTK_IS_WIDGET(widget));
- g_debug("%s: offset_x: %f - offset_y: %f",
- __func__, offset_x, offset_y);
-
- gtk_widget_get_allocation(widget, &allocation);
-
- g_debug("%s: allocation: x: %d - y: %d - width: %d - height: %d",
- __func__,
- allocation.x, allocation.y, allocation.width, allocation.height);
-
- gtk_gesture_drag_get_start_point(gesture, &start_x, &start_y);
+ gtk_widget_get_allocation (widget, &allocation);
+ gtk_gesture_drag_get_start_point (gesture, &start_x, &start_y);
x = start_x + offset_x;
y = start_y + offset_y;
- g_debug("%s: x: %f - y: %f",
- __func__, x, y);
-
if (y < 0) {
gh->scroll_dir = -1;
} else if (y >= allocation.height) {
@@ -1702,8 +1586,6 @@ hex_drag_update_cb (GtkGestureDrag *gesture,
G_SOURCE_FUNC(scroll_timeout_handler),
gh);
}
- // FIXME - don't really like this - seems like it's setting up for
- // silent failure. Maybe put a debugging msg once understand better.
return;
}
else {
@@ -1731,16 +1613,12 @@ ascii_pressed_cb (GtkGestureClick *gesture,
GtkWidget *widget = GTK_WIDGET (gh->adisp);
guint button;
- TEST_DEBUG_FUNCTION_START
g_return_if_fail (GTK_IS_HEX(gh));
g_return_if_fail (GTK_IS_WIDGET(widget));
button = gtk_gesture_single_get_current_button
(GTK_GESTURE_SINGLE(gesture));
- g_debug("%s: n_press: %d, x: %f - y: %f",
- __func__, n_press, x, y);
-
/* Single-press */
if (button == GDK_BUTTON_PRIMARY)
{
@@ -1767,8 +1645,6 @@ ascii_pressed_cb (GtkGestureClick *gesture,
/* Right-click */
else if (button == GDK_BUTTON_SECONDARY)
{
- g_debug("%s: RIGHT CLICK - TRYING TO POPUP CONTEXT MENU.", __func__);
-
popup_context_menu(widget, x, y);
}
/* Middle-click press. */
@@ -1809,7 +1685,6 @@ ascii_released_cb (GtkGestureClick *gesture,
GtkWidget *widget = GTK_WIDGET (gh->adisp);
guint button;
- TEST_DEBUG_FUNCTION_START
g_return_if_fail (GTK_IS_HEX(gh));
g_return_if_fail (GTK_IS_WIDGET(widget));
@@ -1841,35 +1716,19 @@ ascii_drag_update_cb (GtkGestureDrag *gesture,
GtkHex *gh = GTK_HEX (user_data);
GtkWidget *widget = GTK_WIDGET (gh->adisp);
guint button;
-
- // TEST
double start_x, start_y;
double x, y;
-
- // TEST - FROM OLD CODE:
GtkAllocation allocation;
- TEST_DEBUG_FUNCTION_START
g_return_if_fail (GTK_IS_HEX(gh));
g_return_if_fail (GTK_IS_WIDGET(widget));
- g_debug("%s: offset_x: %f - offset_y: %f",
- __func__, offset_x, offset_y);
-
gtk_widget_get_allocation(widget, &allocation);
-
- g_debug("%s: allocation: x: %d - y: %d - width: %d - height: %d",
- __func__,
- allocation.x, allocation.y, allocation.width, allocation.height);
-
gtk_gesture_drag_get_start_point(gesture, &start_x, &start_y);
x = start_x + offset_x;
y = start_y + offset_y;
- g_debug("%s: x: %f - y: %f",
- __func__, x, y);
-
if (y < 0) {
gh->scroll_dir = -1;
} else if (y >= allocation.height) {
@@ -1885,8 +1744,6 @@ ascii_drag_update_cb (GtkGestureDrag *gesture,
G_SOURCE_FUNC(scroll_timeout_handler),
gh);
}
- // FIXME - don't really like this - seems like it's setting up for
- // silent failure. Maybe put a debugging msg once understand better.
return;
}
else {
@@ -1913,8 +1770,6 @@ key_press_cb (GtkEventControllerKey *controller,
GtkWidget *widget = GTK_WIDGET(user_data);
gboolean ret = TRUE;
- TEST_DEBUG_FUNCTION_START
-
hide_cursor(gh);
/* don't trample over Ctrl */
@@ -1932,7 +1787,7 @@ key_press_cb (GtkEventControllerKey *controller,
}
switch(keyval) {
- // TEST - COPY
+ // FIXME TEST - COPY
case GDK_KEY_F12:
g_debug("F12 PRESSED - TESTING CLIPBOARD COPY");
gtk_hex_copy_to_clipboard (gh);
@@ -2096,8 +1951,6 @@ key_release_cb (GtkEventControllerKey *controller,
GtkWidget *widget = GTK_WIDGET(user_data);
gboolean ret = TRUE;
- TEST_DEBUG_FUNCTION_START
-
/* avoid shift key getting 'stuck' */
if (state & GDK_SHIFT_MASK) {
@@ -2111,8 +1964,6 @@ show_offsets_widget(GtkHex *gh)
{
g_return_if_fail (GTK_IS_WIDGET (gh->offsets));
- TEST_DEBUG_FUNCTION_START
-
gtk_widget_show (gh->offsets);
}
@@ -2121,8 +1972,6 @@ hide_offsets_widget(GtkHex *gh)
{
g_return_if_fail (gtk_widget_get_realized (gh->offsets));
- TEST_DEBUG_FUNCTION_START
-
gtk_widget_hide (gh->offsets);
}
@@ -2130,7 +1979,8 @@ hide_offsets_widget(GtkHex *gh)
/*
* default data_changed signal handler
*/
-static void gtk_hex_real_data_changed(GtkHex *gh, gpointer data) {
+static void gtk_hex_real_data_changed (GtkHex *gh, gpointer data)
+{
HexChangeData *change_data = (HexChangeData *)data;
gint start_line, end_line;
guint lines;
@@ -2180,22 +2030,26 @@ static void gtk_hex_real_data_changed(GtkHex *gh, gpointer data) {
{
invalidate_offsets (gh, start_line, end_line);
}
+
+ TEST_DEBUG_FUNCTION_END
}
static void
-bytes_changed(GtkHex *gh, int start, int end)
+bytes_changed (GtkHex *gh, int start, int end)
{
int start_line;
int end_line;
- g_return_if_fail(gh->cpl); /* check for divide-by-zero issues */
+ g_return_if_fail (gh->cpl); /* check for divide-by-zero issues */
- start_line = start/gh->cpl - gh->top_line;
- start_line = MAX(start_line, 0);
+ start_line = start / gh->cpl - gh->top_line;
+ start_line = MAX (start_line, 0);
- end_line = end/gh->cpl - gh->top_line;
+ end_line = end / gh->cpl - gh->top_line;
- g_return_if_fail(end_line >=0 && start_line <= gh->vis_lines);
+ /* Nothing needs to be done in some instances */
+ if (end_line < 0 || start_line > gh->vis_lines)
+ return;
invalidate_hex_lines (gh, start_line, end_line);
invalidate_ascii_lines (gh, start_line, end_line);
@@ -2607,6 +2461,18 @@ static void gtk_hex_real_paste_from_clipboard(GtkHex *gh,
#endif
}
+static void
+gtk_hex_real_draw_complete (GtkHex *gh,
+ gpointer user_data)
+{
+ TEST_DEBUG_FUNCTION_START
+
+ (void)user_data;
+ recalc_scrolling (gh);
+
+ TEST_DEBUG_FUNCTION_END
+}
+
static void gtk_hex_finalize(GObject *gobject) {
GtkHex *gh = GTK_HEX(gobject);
@@ -2627,200 +2493,6 @@ static void gtk_hex_finalize(GObject *gobject) {
G_OBJECT_CLASS(gtk_hex_parent_class)->finalize(gobject);
}
-
-
-// REWRITE FOR GESTURES/EVENT CONTROLLERS
-#if 0
-static gboolean gtk_hex_key_press(GtkWidget *w, GdkEventKey *event) {
- GtkHex *gh = GTK_HEX(w);
- gint ret = TRUE;
-
- hide_cursor(gh);
-
- if(!(event->state & GDK_SHIFT_MASK)) {
- gh->selecting = FALSE;
- }
- else {
- gh->selecting = TRUE;
- }
- switch(event->keyval) {
- case GDK_KEY_BackSpace:
- if(gh->cursor_pos > 0) {
- hex_document_set_data(gh->document, gh->cursor_pos - 1,
- 0, 1, NULL, TRUE);
- if (gh->selecting)
- gh->selecting = FALSE;
- gtk_hex_set_cursor(gh, gh->cursor_pos - 1);
- }
- break;
- case GDK_KEY_Tab:
- case GDK_KEY_KP_Tab:
- if (gh->active_view == VIEW_ASCII) {
- gh->active_view = VIEW_HEX;
- }
- else {
- gh->active_view = VIEW_ASCII;
- }
- break;
- case GDK_KEY_Delete:
- if(gh->cursor_pos < gh->document->file_size) {
- hex_document_set_data(gh->document, gh->cursor_pos,
- 0, 1, NULL, TRUE);
- gtk_hex_set_cursor(gh, gh->cursor_pos);
- }
- break;
- case GDK_KEY_Up:
- gtk_hex_set_cursor(gh, gh->cursor_pos - gh->cpl);
- break;
- case GDK_KEY_Down:
- gtk_hex_set_cursor(gh, gh->cursor_pos + gh->cpl);
- break;
- case GDK_KEY_Page_Up:
- gtk_hex_set_cursor(gh, MAX(0, (gint)gh->cursor_pos - gh->vis_lines*gh->cpl));
- break;
- case GDK_KEY_Page_Down:
- gtk_hex_set_cursor(gh, MIN((gint)gh->document->file_size, (gint)gh->cursor_pos +
gh->vis_lines*gh->cpl));
- break;
- default:
- if (event->state & GDK_MOD1_MASK) {
- show_cursor(gh);
- return FALSE;
- }
- if(gh->active_view == VIEW_HEX)
- switch(event->keyval) {
- case GDK_KEY_Left:
- if(!(event->state & GDK_SHIFT_MASK)) {
- gh->lower_nibble = !gh->lower_nibble;
- if(gh->lower_nibble)
- gtk_hex_set_cursor(gh, gh->cursor_pos - 1);
- }
- else {
- gtk_hex_set_cursor(gh, gh->cursor_pos - 1);
- }
- break;
- case GDK_KEY_Right:
- if(gh->cursor_pos >= gh->document->file_size)
- break;
- if(!(event->state & GDK_SHIFT_MASK)) {
- gh->lower_nibble = !gh->lower_nibble;
- if(!gh->lower_nibble)
- gtk_hex_set_cursor(gh, gh->cursor_pos + 1);
- }
- else {
- gtk_hex_set_cursor(gh, gh->cursor_pos + 1);
- }
- break;
- default:
- if(event->length != 1)
- ret = FALSE;
- else if((event->keyval >= '0')&&(event->keyval <= '9')) {
- hex_document_set_nibble(gh->document, event->keyval - '0',
- gh->cursor_pos,
gh->lower_nibble,
- gh->insert, TRUE);
- if (gh->selecting)
- gh->selecting = FALSE;
- gh->lower_nibble = !gh->lower_nibble;
- if(!gh->lower_nibble)
- gtk_hex_set_cursor(gh, gh->cursor_pos + 1);
- }
- else if((event->keyval >= 'A')&&(event->keyval <= 'F')) {
- hex_document_set_nibble(gh->document, event->keyval - 'A' + 10,
- gh->cursor_pos,
gh->lower_nibble,
- gh->insert, TRUE);
- if (gh->selecting)
- gh->selecting = FALSE;
- gh->lower_nibble = !gh->lower_nibble;
- if(!gh->lower_nibble)
- gtk_hex_set_cursor(gh, gh->cursor_pos + 1);
- }
- else if((event->keyval >= 'a')&&(event->keyval <= 'f')) {
- hex_document_set_nibble(gh->document, event->keyval - 'a' + 10,
- gh->cursor_pos,
gh->lower_nibble,
- gh->insert, TRUE);
- if (gh->selecting)
- gh->selecting = FALSE;
- gh->lower_nibble = !gh->lower_nibble;
- if(!gh->lower_nibble)
- gtk_hex_set_cursor(gh, gh->cursor_pos + 1);
- }
- else if((event->keyval >= GDK_KEY_KP_0)&&(event->keyval <= GDK_KEY_KP_9)) {
- hex_document_set_nibble(gh->document, event->keyval - GDK_KEY_KP_0,
- gh->cursor_pos,
gh->lower_nibble,
- gh->insert, TRUE);
- if (gh->selecting)
- gh->selecting = FALSE;
- gh->lower_nibble = !gh->lower_nibble;
- if(!gh->lower_nibble)
- gtk_hex_set_cursor(gh, gh->cursor_pos + 1);
- }
- else
- ret = FALSE;
-
- break;
- }
- else if(gh->active_view == VIEW_ASCII)
- switch(event->keyval) {
- case GDK_KEY_Left:
- gtk_hex_set_cursor(gh, gh->cursor_pos - 1);
- break;
- case GDK_KEY_Right:
- gtk_hex_set_cursor(gh, gh->cursor_pos + 1);
- break;
- default:
- if(event->length != 1)
- ret = FALSE;
- else if(is_displayable(event->keyval)) {
- hex_document_set_byte(gh->document, event->keyval,
- gh->cursor_pos, gh->insert,
TRUE);
- if (gh->selecting)
- gh->selecting = FALSE;
- gtk_hex_set_cursor(gh, gh->cursor_pos + 1);
- }
- else if((event->keyval >= GDK_KEY_KP_0)&&(event->keyval <= GDK_KEY_KP_9)) {
- hex_document_set_byte(gh->document, event->keyval - GDK_KEY_KP_0 +
'0',
- gh->cursor_pos,
gh->insert, TRUE);
- if (gh->selecting)
- gh->selecting = FALSE;
- gtk_hex_set_cursor(gh, gh->cursor_pos + 1);
- }
- else
- ret = FALSE;
-
- break;
- }
- break;
- }
-
- show_cursor(gh);
-
- return ret;
-}
-#endif
-
-// SWITCH TO GESTURES/EVENT CONTROLLERS
-#if 0
-static gboolean gtk_hex_key_release(GtkWidget *w, GdkEventKey *event) {
- GtkHex *gh = GTK_HEX(w);
-
- if (event->keyval == GDK_KEY_Shift_L || event->keyval == GDK_KEY_Shift_R) {
- gh->selecting = FALSE;
- }
-
- return TRUE;
-}
-
-static gboolean gtk_hex_button_release(GtkWidget *w, GdkEventButton *event) {
- GtkHex *gh = GTK_HEX(w);
-
- if(event->state & GDK_SHIFT_MASK) {
- gh->selecting = FALSE;
- }
-
- return TRUE;
-}
-#endif
-
-
static void
gtk_hex_snapshot (GtkWidget *widget, GtkSnapshot *snapshot)
{
@@ -2830,7 +2502,7 @@ gtk_hex_snapshot (GtkWidget *widget, GtkSnapshot *snapshot)
cairo_t *cr;
GtkWidget *child;
- TEST_DEBUG_FUNCTION_START
+ TEST_DEBUG_FUNCTION_START
/* Update character width & height */
gh->char_width = get_char_width(gh);
@@ -2854,27 +2526,18 @@ gtk_hex_snapshot (GtkWidget *widget, GtkSnapshot *snapshot)
cr = gtk_snapshot_append_cairo (snapshot, &rect);
- g_debug("%s: width: %f - height: %f",
- __func__, width, height);
-
- // TEST for trying render_xc
- show_cursor(gh);
-
- /* queue draw functions for drawing areas - order matters here as
- * we're pegging certain elements of the ascii widget being drawn
- * to after the hex widget is drawn.
+ /* queue child draw functions
*/
- gtk_widget_snapshot_child (widget, gh->xdisp, snapshot);
- gtk_widget_snapshot_child (widget, gh->adisp, snapshot);
-
- /* queue draw functions for other children */
for (child = gtk_widget_get_first_child (widget);
- /* don't draw these as we already did above. */
- child != NULL && child != gh->xdisp && child != gh->adisp;
+ child != NULL;
child = gtk_widget_get_next_sibling (child))
{
gtk_widget_snapshot_child (widget, child, snapshot);
}
+
+ g_signal_emit_by_name(G_OBJECT(gh), "draw-complete");
+
+ TEST_DEBUG_FUNCTION_END
}
static void
@@ -2884,8 +2547,6 @@ gtk_hex_document_changed (HexDocument* doc, gpointer change_data,
GtkHex *gh = GTK_HEX(data);
g_return_if_fail (GTK_IS_HEX (gh));
- TEST_DEBUG_FUNCTION_START
-
gtk_hex_real_data_changed (gh, change_data);
gtk_widget_action_set_enabled (GTK_WIDGET(gh),
@@ -2902,7 +2563,7 @@ gtk_hex_class_init (GtkHexClass *klass)
/* Layout manager: box-style layout. */
gtk_widget_class_set_layout_manager_type (widget_class,
- GTK_TYPE_BOX_LAYOUT);
+ GTK_TYPE_HEX_LAYOUT);
/* CSS name */
@@ -2966,6 +2627,16 @@ gtk_hex_class_init (GtkHexClass *klass)
G_TYPE_NONE,
0);
+ gtkhex_signals[DRAW_COMPLETE_SIGNAL] =
+ g_signal_new_class_handler ("draw-complete",
+ G_OBJECT_CLASS_TYPE(object_class),
+ G_SIGNAL_RUN_FIRST,
+ G_CALLBACK(gtk_hex_real_draw_complete),
+ NULL, NULL,
+ NULL,
+ G_TYPE_NONE,
+ 0);
+
/* ACTIONS */
gtk_widget_class_install_action (widget_class, "gtkhex.copy",
@@ -3004,30 +2675,7 @@ gtk_hex_class_init (GtkHexClass *klass)
"gtkhex.redo",
NULL); // no args.
- // API CHANGES
-// klass->primary = gtk_clipboard_get(GDK_SELECTION_PRIMARY);
-// klass->clipboard = gtk_clipboard_get(GDK_NONE);
-
- // LAR - NOTE - GTK4, THIS IS ONLY CALLED IF THE WIDGET DOES *NOT* HAVE
- // A LAYOUT MANAGER
- //
- // POSSIBLE TODO - subclass a GtkLayoutManager and set the `allocate'
- // vfunc.
-// GTK_WIDGET_CLASS(klass)->size_allocate = gtk_hex_size_allocate;
-
-
- // GONESVILLE WITH GTK4
-// GTK_WIDGET_CLASS(klass)->get_preferred_width = gtk_hex_get_preferred_width;
-// GTK_WIDGET_CLASS(klass)->get_preferred_height = gtk_hex_get_preferred_height;
- // LAR - no can do, gtk4 - just seems to draw a border??
-// LAR - TEST FOR GTK4
widget_class->snapshot = gtk_hex_snapshot;
-
-// GTK4 API CHANGES - SWITCH TO GESTURES / EVENT CONTROLLERS
-// GTK_WIDGET_CLASS(klass)->key_press_event = gtk_hex_key_press;
-// GTK_WIDGET_CLASS(klass)->key_release_event = gtk_hex_key_release;
-// GTK_WIDGET_CLASS(klass)->button_release_event = gtk_hex_button_release;
-
object_class->finalize = gtk_hex_finalize;
}
@@ -3036,12 +2684,16 @@ gtk_hex_init(GtkHex *gh)
{
GtkWidget *widget = GTK_WIDGET(gh);
+ GtkHexLayoutChild *child_info;
+
GtkCssProvider *provider;
GtkStyleContext *context;
GtkGesture *gesture;
GtkEventController *controller;
+ gh->layout_manager = gtk_widget_get_layout_manager (widget);
+
gh->disp_buffer = NULL;
gh->default_cpl = DEFAULT_CPL;
gh->default_lines = DEFAULT_LINES;
@@ -3074,8 +2726,8 @@ gtk_hex_init(GtkHex *gh)
gtk_widget_set_can_focus (widget, TRUE);
gtk_widget_set_focusable (widget, TRUE);
- gtk_widget_set_vexpand (widget, TRUE);
- gtk_widget_set_hexpand (widget, TRUE);
+// gtk_widget_set_vexpand (widget, TRUE);
+// gtk_widget_set_hexpand (widget, TRUE);
/* Init CSS */
@@ -3110,8 +2762,12 @@ gtk_hex_init(GtkHex *gh)
gh->offsets = gtk_drawing_area_new();
gtk_widget_set_parent (gh->offsets, widget);
- gtk_widget_set_halign (gh->offsets, GTK_ALIGN_START);
- gtk_widget_set_hexpand (gh->offsets, FALSE);
+ child_info = GTK_HEX_LAYOUT_CHILD (gtk_layout_manager_get_layout_child
+ (gh->layout_manager, gh->offsets));
+ gtk_hex_layout_child_set_column (child_info, OFFSETS_COLUMN);
+
+// gtk_widget_set_halign (gh->offsets, GTK_ALIGN_START);
+// gtk_widget_set_hexpand (gh->offsets, FALSE);
/* Create the pango layout for the widget */
gh->olayout = gtk_widget_create_pango_layout (gh->offsets, "");
@@ -3127,50 +2783,27 @@ gtk_hex_init(GtkHex *gh)
context = gtk_widget_get_style_context (GTK_WIDGET (gh->offsets));
gtk_style_context_add_class (context, "header");
-
/* hide it by default. */
gtk_widget_hide (gh->offsets);
-
-
/* Setup our Hex drawing area. */
gh->xdisp = gtk_drawing_area_new();
gtk_widget_set_parent (gh->xdisp, widget);
- gtk_widget_set_hexpand (gh->xdisp, TRUE);
+ child_info = GTK_HEX_LAYOUT_CHILD (gtk_layout_manager_get_layout_child
+ (gh->layout_manager, gh->xdisp));
+ gtk_hex_layout_child_set_column (child_info, HEX_COLUMN);
/* Create the pango layout for the widget */
gh->xlayout = gtk_widget_create_pango_layout (gh->xdisp, "");
- // TEST / MONITOR - not sure if needed for keyboard events. - NOT
- // needed for mouse events.
-// gtk_widget_set_can_focus (gh->xdisp, TRUE);
-
gtk_drawing_area_set_draw_func (GTK_DRAWING_AREA (gh->xdisp),
hex_draw, // GtkDrawingAreaDrawFunc draw_func,
gh, // gpointer user_data,
NULL); // GDestroyNotify destroy);
-
- // REWRITE - LAR
-#if 0
-
- gtk_widget_set_events (gh->xdisp, GDK_EXPOSURE_MASK |
- GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK |
- GDK_BUTTON_MOTION_MASK | GDK_SCROLL_MASK);
-
- g_signal_connect(G_OBJECT(gh->xdisp), "button_press_event",
- G_CALLBACK(hex_button_cb), gh);
- g_signal_connect(G_OBJECT(gh->xdisp), "button_release_event",
- G_CALLBACK(hex_button_cb), gh);
- g_signal_connect(G_OBJECT(gh->xdisp), "motion_notify_event",
- G_CALLBACK(hex_motion_cb), gh);
- g_signal_connect(G_OBJECT(gh->xdisp), "scroll_event",
- G_CALLBACK(hex_scroll_cb), gh);
-#endif
-
/* Set context var to hex widget's context... */
context = gtk_widget_get_style_context (GTK_WIDGET (gh->xdisp));
/* ... and add view class so we get certain theme colours for free. */
@@ -3182,16 +2815,15 @@ gtk_hex_init(GtkHex *gh)
gh->adisp = gtk_drawing_area_new();
gtk_widget_set_parent (gh->adisp, widget);
- gtk_widget_set_halign (gh->adisp, GTK_ALIGN_START);
- gtk_widget_set_hexpand (gh->adisp, FALSE);
+ child_info = GTK_HEX_LAYOUT_CHILD (gtk_layout_manager_get_layout_child
+ (gh->layout_manager, gh->adisp));
+ gtk_hex_layout_child_set_column (child_info, ASCII_COLUMN);
+
gtk_widget_set_name (gh->adisp, "asciidisplay");
/* Create the pango layout for the widget */
gh->alayout = gtk_widget_create_pango_layout (gh->adisp, "");
- // LAR - TEST - dont' know if needed - NOT needed for mouse clicks.
-// gtk_widget_set_can_focus (gh->adisp, TRUE);
-
gtk_drawing_area_set_draw_func (GTK_DRAWING_AREA (gh->adisp),
ascii_draw, /* GtkDrawingAreaDrawFunc draw_func, */
gh, /* gpointer user_data, */
@@ -3204,22 +2836,6 @@ gtk_hex_init(GtkHex *gh)
GTK_STYLE_PROVIDER (provider),
GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
- // LAR - REWRITE
-#if 0
- gtk_widget_set_events (gh->adisp, GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK
- | GDK_BUTTON_RELEASE_MASK | GDK_BUTTON_MOTION_MASK |
- GDK_SCROLL_MASK);
-
- g_signal_connect(G_OBJECT(gh->adisp), "button_press_event",
- G_CALLBACK(ascii_button_cb), gh);
- g_signal_connect(G_OBJECT(gh->adisp), "button_release_event",
- G_CALLBACK(ascii_button_cb), gh);
- g_signal_connect(G_OBJECT(gh->adisp), "motion_notify_event",
- G_CALLBACK(ascii_motion_cb), gh);
- g_signal_connect(G_OBJECT(gh->adisp), "scroll_event",
- G_CALLBACK(ascii_scroll_cb), gh);
-#endif
-
/* Set a minimum size for hex/ascii drawing areas. */
gtk_widget_set_size_request (gh->adisp,
@@ -3227,7 +2843,6 @@ gtk_hex_init(GtkHex *gh)
gtk_widget_set_size_request (gh->xdisp,
DEFAULT_DA_SIZE, DEFAULT_DA_SIZE);
-
/* Initialize Adjustment */
gh->adj = gtk_adjustment_new (0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
@@ -3235,7 +2850,11 @@ gtk_hex_init(GtkHex *gh)
/* Setup scrollbar. */
gh->scrollbar = gtk_scrollbar_new (GTK_ORIENTATION_VERTICAL,
gh->adj);
+
gtk_widget_set_parent (gh->scrollbar, widget);
+ child_info = GTK_HEX_LAYOUT_CHILD (gtk_layout_manager_get_layout_child
+ (gh->layout_manager, gh->scrollbar));
+ gtk_hex_layout_child_set_column (child_info, SCROLLBAR_COLUMN);
/* Connect gestures to ascii/hex drawing areas.
*/
@@ -3260,12 +2879,15 @@ gtk_hex_init(GtkHex *gh)
/* drag gestures */
gesture = gtk_gesture_drag_new ();
+ // TODO - IF NEEDED
+#if 0
g_signal_connect (gesture, "drag-begin",
G_CALLBACK(hex_drag_begin_cb),
gh);
g_signal_connect (gesture, "drag-end",
G_CALLBACK(hex_drag_end_cb),
gh);
+#endif
g_signal_connect (gesture, "drag-update",
G_CALLBACK (hex_drag_update_cb),
gh);
@@ -3346,7 +2968,6 @@ gtk_hex_init(GtkHex *gh)
"gtkhex.undo", FALSE);
gtk_widget_action_set_enabled (GTK_WIDGET(gh),
"gtkhex.redo", FALSE);
-
}
GtkWidget *gtk_hex_new(HexDocument *owner) {
@@ -3551,8 +3172,6 @@ void gtk_hex_set_group_type(GtkHex *gh, guint gt) {
*/
void gtk_hex_show_offsets(GtkHex *gh, gboolean show)
{
- TEST_DEBUG_FUNCTION_START
-
g_return_if_fail(gh != NULL);
g_return_if_fail(GTK_IS_HEX(gh));
diff --git a/src/meson.build b/src/meson.build
index 45950341..9861eab3 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -1,6 +1,7 @@
libghex_sources = [
'gtkhex.c',
- 'hex-document.c'
+ 'hex-document.c',
+ 'gtkhex-layout-manager.c'
]
libghex_headers = [
@@ -60,6 +61,8 @@ ghex_sources = [
'ghex-application-window.h',
'gtkhex.c',
'gtkhex.h',
+ 'gtkhex-layout-manager.c',
+ 'gtkhex-layout-manager.h',
'hex-dialog.c',
'hex-dialog.h',
'hex-document.c',
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]