[ghex] gtkhex: Bugfixes to layout manager.



commit f6e3279307d3ecfcb4c4a39b76203fd488272c22
Author: Logan Rathbone <poprocks gmail com>
Date:   Thu Dec 9 23:30:39 2021 -0500

    gtkhex: Bugfixes to layout manager.
    
    This allows us to lay out the widget with CSS and not worry about any
    characters being cut off.
    
    Next step in this avenue would be to tweak further, especially the
    allocation - not of the widget itself, but of the number of characters
    that can be drawn on the hex widget.

 src/ghex.css                | 12 +++++---
 src/gtkhex-layout-manager.c | 74 ++++++++++++++++++++++++++++++++-------------
 src/gtkhex.c                | 13 ++++----
 3 files changed, 67 insertions(+), 32 deletions(-)
---
diff --git a/src/ghex.css b/src/ghex.css
index eb68bb5..5b6b684 100644
--- a/src/ghex.css
+++ b/src/ghex.css
@@ -21,16 +21,18 @@
 }
 
 .hex #offsets {
-       background-color: shade(@theme_bg_color, 0.95);
-       padding-left: 8px;
+        padding-left: 12px;
+       padding-right: 12px;
        border-right: solid @borders 2px;
+       background-color: shade(@theme_bg_color, 0.9);
 }
 
 .hex #hex-display {
-       border-right: dotted 2px @borders;
-       padding-left: 8px;
+        border-right: dotted 2px @borders;
+        padding-left: 12px;
 }
 
 .hex #ascii-display {
-       padding-left: 8px;
+        padding-left: 12px;
 }
+
diff --git a/src/gtkhex-layout-manager.c b/src/gtkhex-layout-manager.c
index 91ac4b4..4af40bd 100644
--- a/src/gtkhex-layout-manager.c
+++ b/src/gtkhex-layout-manager.c
@@ -24,7 +24,10 @@
 
 #include "gtkhex-layout-manager.h"
 
-#define OFFSETS_CPL            10
+/* The CPL of the offsets column is constant; easier to just punch it in here
+ * than to use config.h. Don't change unless you change code in gtkhex.c as well.
+ */
+#define OFFSETS_CPL            8
 #define HEX_RATIO              0.75
 #define ASCII_RATIO            0.25
 
@@ -208,13 +211,25 @@ gtk_hex_layout_measure (GtkLayoutManager *layout_manager,
 
 /* Helper */
 static void
-get_cpl_from_ascii_width (GtkHexLayout *self, int width)
+get_cpl_from_ascii_width (GtkHexLayout *self, GtkWidget *widget, int width)
 {
        int hex_cpl, ascii_cpl;
+       int real_width;
+       GtkStyleContext *context;
+       GtkBorder margins, padding;
 
-       /* Hex characters per line is a simple calculation: */
+       /* Need to grab padding and margins - can't assume that the number of
+        * ascii chars that can be crammed into the widget is equal to its width
+        * divided by the width of a single character.
+        */
+       context = gtk_widget_get_style_context (widget);
+       gtk_style_context_get_margin (context, &margins);
+       gtk_style_context_get_padding (context, &padding);
+
+       real_width = width -
+               margins.left - margins.right - padding.left - padding.right;
 
-       ascii_cpl = width / self->char_width;
+       ascii_cpl = real_width / self->char_width;
        while (ascii_cpl % self->group_type != 0)
                --ascii_cpl;
 
@@ -237,11 +252,12 @@ gtk_hex_layout_allocate (GtkLayoutManager *layout_manager,
        GtkWidget *child;
        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;
+#define BASE_ALLOC {.x = 0, .y = 0, .width = 0, .height = height}
+       GtkAllocation off_alloc = BASE_ALLOC;
+       GtkAllocation hex_alloc = BASE_ALLOC;
+       GtkAllocation asc_alloc = BASE_ALLOC;
+       GtkAllocation scr_alloc = BASE_ALLOC;
+#undef BASE_ALLOC
        GtkAllocation tmp_alloc = {0};
 
        for (child = gtk_widget_get_first_child (widget);
@@ -257,31 +273,46 @@ gtk_hex_layout_allocate (GtkLayoutManager *layout_manager,
 
                gtk_widget_get_preferred_size (child, &child_req, NULL);
 
-               /* Setup allocation depending on what column we're in. */
+               /* Setup allocation depending on what column we're in.
+                * This loop is run through again once we obtain some initial values. */
 
-               child_info =
-                       GTK_HEX_LAYOUT_CHILD(gtk_layout_manager_get_layout_child (layout_manager,
-                                               child));
+               child_info = GTK_HEX_LAYOUT_CHILD(
+                               gtk_layout_manager_get_layout_child (layout_manager, child));
 
                switch (child_info->column)
                {
                        case OFFSETS_COLUMN:
-                               off_alloc.width = OFFSETS_CPL * self->char_width;
+                       {
+                               GtkStyleContext *context = gtk_widget_get_style_context (child);
+                               GtkBorder margins, padding, borders;
+
+                               gtk_style_context_get_margin (context, &margins);
+                               gtk_style_context_get_padding (context, &padding);
+                               gtk_style_context_get_border (context, &borders);
+
+                               off_alloc.width = OFFSETS_CPL * self->char_width +
+                                       margins.left + margins.right +
+                                       padding.left + padding.right +
+                                       borders.left + borders.right;
+                       }
                                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.",
+                               g_error ("%s: Programmer error. Requested column invalid.",
                                                __func__);
                                break;
                }
@@ -302,9 +333,8 @@ gtk_hex_layout_allocate (GtkLayoutManager *layout_manager,
 
                /* Setup allocation depending on what column we're in. */
 
-               child_info =
-                       GTK_HEX_LAYOUT_CHILD(gtk_layout_manager_get_layout_child
-                                       (layout_manager, child));
+               child_info = GTK_HEX_LAYOUT_CHILD(
+                               gtk_layout_manager_get_layout_child (layout_manager, child));
 
                switch (child_info->column)
                {
@@ -315,6 +345,7 @@ gtk_hex_layout_allocate (GtkLayoutManager *layout_manager,
                        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;
@@ -327,6 +358,7 @@ gtk_hex_layout_allocate (GtkLayoutManager *layout_manager,
                                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)
@@ -334,7 +366,7 @@ gtk_hex_layout_allocate (GtkLayoutManager *layout_manager,
                                }
                                tmp_alloc = asc_alloc;
 
-                               get_cpl_from_ascii_width (self, asc_alloc.width);
+                               get_cpl_from_ascii_width (self, child, asc_alloc.width);
 
                                break;
 
@@ -343,7 +375,7 @@ gtk_hex_layout_allocate (GtkLayoutManager *layout_manager,
                                break;
 
                        default:
-                               g_error ("%s: Programming error. The requested column is invalid.",
+                               g_error ("%s: Programmer error. The requested column is invalid.",
                                                __func__);
                                break;
                }
diff --git a/src/gtkhex.c b/src/gtkhex.c
index 4a2a037..a78ef56 100644
--- a/src/gtkhex.c
+++ b/src/gtkhex.c
@@ -421,8 +421,9 @@ get_char_width (GtkHex *gh)
 }
 
 /*
- * format_[x|a]block() formats contents of the buffer
- * into displayable text in hex or ascii, respectively
+ * format_[x|a]block() formats contents of the buffer (out) into displayable
+ * text in hex or ascii, respectively.
+ * Returns: length of resulting number of bytes/characters in buffer.
  */
 static int
 format_xblock (GtkHex *gh, char *out, int start, int end)
@@ -430,13 +431,14 @@ format_xblock (GtkHex *gh, char *out, int start, int end)
        int i, j, low, high;
        guchar c;
 
-       for (i = start + 1, j = 0; i <= end; i++) {
+       for (i = start + 1, j = 0; i <= end; i++)
+       {
                c = gtk_hex_get_byte(gh, i - 1);
                low = c & 0x0F;
                high = (c & 0xF0) >> 4;
                
-               out[j++] = ((high < 10)?(high + '0'):(high - 10 + 'A'));
-               out[j++] = ((low < 10)?(low + '0'):(low - 10 + 'A'));
+               out[j++] = (high < 10) ? (high + '0') : (high - 10 + 'A');
+               out[j++] = (low < 10) ? (low + '0') : (low - 10 + 'A');
                
                if (i % gh->group_type == 0)
                        out[j++] = ' ';
@@ -1047,7 +1049,6 @@ render_offsets (GtkHex *gh,
 
        gtk_widget_get_allocation (widget, &allocation);
 
-       /* render background. */
        gtk_render_background (context, cr,
                        /* x: */                0,
                        /* y: */                min_lines * gh->char_height,


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]