[baobab/wip/gtk4: 16/16] Fix scrolling and item highlighting



commit 05810e6f2376dd4f8669054f82634b018c25dc02
Author: Stefano Facchini <stefano facchini gmail com>
Date:   Sun Oct 29 19:05:37 2017 +0100

    Fix scrolling and item highlighting

 src/baobab-chart.vala      |   66 +++++++++++++++++++++++++++++++------------
 src/baobab-ringschart.vala |   60 ++++++++++++++-------------------------
 src/baobab-treemap.vala    |   48 ++++++++++++++-----------------
 3 files changed, 91 insertions(+), 83 deletions(-)
---
diff --git a/src/baobab-chart.vala b/src/baobab-chart.vala
index 1aa7665..11e2978 100644
--- a/src/baobab-chart.vala
+++ b/src/baobab-chart.vala
@@ -72,6 +72,12 @@ namespace Baobab {
         Gtk.Menu context_menu = null;
 
         List<ChartItem> items;
+        bool need_recalculate_geometry = true;
+
+        double total_delta_y = 0;
+
+        protected int width;
+        protected int height;
 
         uint max_depth_ = MAX_DEPTH;
         public uint max_depth {
@@ -174,10 +180,12 @@ namespace Baobab {
                 }
 
                 if (highlighted_item_ != null) {
-                    get_window ().invalidate_rect (highlighted_item_.rect, true);
+                    queue_draw ();
+                    //get_window ().invalidate_rect (highlighted_item_.rect, true);
                 }
                 if (value != null) {
-                    get_window ().invalidate_rect (value.rect, true);
+                    queue_draw ();
+                    //get_window ().invalidate_rect (value.rect, true);
                 }
 
                 highlighted_item_ = value;
@@ -228,11 +236,13 @@ namespace Baobab {
 
         public override void size_allocate (Gtk.Allocation allocation, int baseline, out Gtk.Allocation 
clip) {
             base.size_allocate (allocation, baseline, out clip);
-            foreach (ChartItem item in items) {
+            need_recalculate_geometry = true;
+            /*foreach (ChartItem item in items) {
                 item.has_visible_children = false;
                 item.visible = false;
                 calculate_item_geometry (item);
             }
+            */
         }
 
         bool highlight_item_at_point (double x, double y) {
@@ -411,15 +421,19 @@ namespace Baobab {
             update_draw (path);
         }
 
-        public void draw_func (Gtk.DrawingArea area, Cairo.Context cr, int width, int height) {
+        public void draw_func (Gtk.DrawingArea area, Cairo.Context cr, int w, int h) {
             if (name_column == percentage_column) {
                 // Columns not set
                 return;
             }
 
+            width = w;
+            height = h;
+
             if (model != null) {
-                if (model_changed || items == null) {
+                if (model_changed || items == null || need_recalculate_geometry) {
                     get_items (root);
+                    need_recalculate_geometry = false;
                 } else {
                     var current_path = model.get_path (items.data.iter);
                     if (root.compare (current_path) != 0) {
@@ -522,20 +536,34 @@ namespace Baobab {
         protected override bool scroll_event (Gdk.EventScroll event) {
             Gdk.EventMotion e = (Gdk.EventMotion) event;
             Gdk.ScrollDirection direction;
-            event.get_scroll_direction (out direction);
-            switch (direction) {
-            case Gdk.ScrollDirection.LEFT:
-            case Gdk.ScrollDirection.UP:
-                zoom_out ();
-                motion_notify_event (e);
-                break;
-            case Gdk.ScrollDirection.RIGHT:
-            case Gdk.ScrollDirection.DOWN:
-                zoom_in ();
-                motion_notify_event (e);
-                break;
-            case Gdk.ScrollDirection.SMOOTH:
-                break;
+            double delta_x, delta_y;
+
+            if (event.get_scroll_direction (out direction)) {
+                switch (direction) {
+                case Gdk.ScrollDirection.LEFT:
+                case Gdk.ScrollDirection.UP:
+                    zoom_out ();
+                    motion_notify_event (e);
+                    break;
+                case Gdk.ScrollDirection.RIGHT:
+                case Gdk.ScrollDirection.DOWN:
+                    zoom_in ();
+                    motion_notify_event (e);
+                    break;
+                case Gdk.ScrollDirection.SMOOTH:
+                    break;
+                }
+            } else if (event.get_scroll_deltas (out delta_x, out delta_y)) {
+                total_delta_y += delta_y;
+                if (total_delta_y > 1) {
+                    zoom_in ();
+                    motion_notify_event (e);
+                    total_delta_y = 0;
+                } else if (total_delta_y < -1) {
+                    zoom_out ();
+                    motion_notify_event (e);
+                    total_delta_y = 0;
+                }
             }
 
             return false;
diff --git a/src/baobab-ringschart.vala b/src/baobab-ringschart.vala
index 6173edf..37f0aa3 100644
--- a/src/baobab-ringschart.vala
+++ b/src/baobab-ringschart.vala
@@ -101,19 +101,12 @@ namespace Baobab {
             context.save ();
             context.add_class ("subfolder-tip");
 
-            Gtk.Allocation allocation;
-            get_allocation (out allocation);
-
-            var q_width = allocation.width / 2;
-            var q_height = allocation.height / 2;
+            var q_width = width / 2;
+            var q_height = height / 2;
             var q_angle = Math.atan2 (q_height, q_width);
 
             Gdk.Rectangle last_rect = Gdk.Rectangle ();
 
-            var padding = context.get_padding ();
-            var vpadding = padding.top + padding.bottom;
-            var hpadding = padding.left + padding.right;
-
             foreach (ChartItem item in subtip_items) {
                 RingschartItem ringsitem = item as RingschartItem;
 
@@ -140,28 +133,28 @@ namespace Baobab {
                 // get the center point of the tooltip rectangle
                 double tip_x, tip_y;
                 if (middle_angle_n < q_angle) {
-                    tip_x = q_width - layout_rect.width / 2 - hpadding;
+                    tip_x = q_width - layout_rect.width / 2;
                     tip_y = Math.tan (middle_angle_n) * tip_x;
                 } else {
-                    tip_y = q_height - layout_rect.height / 2 - vpadding;
+                    tip_y = q_height - layout_rect.height / 2;
                     tip_x = tip_y / Math.tan (middle_angle_n);
                 }
 
                 // get the tooltip rectangle
                 Cairo.Rectangle tooltip_rect = Cairo.Rectangle ();
-                tooltip_rect.x = q_width + tip_x - layout_rect.width / 2 - padding.left;
-                tooltip_rect.y = q_height + tip_y - layout_rect.height / 2 - padding.top;
-                tooltip_rect.width = layout_rect.width + hpadding;
-                tooltip_rect.height = layout_rect.height + vpadding;
+                tooltip_rect.x = q_width + tip_x - layout_rect.width / 2;
+                tooltip_rect.y = q_height + tip_y - layout_rect.height / 2;
+                tooltip_rect.width = layout_rect.width;
+                tooltip_rect.height = layout_rect.height;
 
                 // translate tooltip rectangle and edge angles to the original quadrant
                 var a = middle_angle;
                 int i = 0;
                 while (a > Math.PI / 2) {
                     if (i % 2 == 0) {
-                        tooltip_rect.x = allocation.width - tooltip_rect.x - tooltip_rect.width;
+                        tooltip_rect.x = width - tooltip_rect.x - tooltip_rect.width;
                     } else {
-                        tooltip_rect.y = allocation.height - tooltip_rect.y - tooltip_rect.height;
+                        tooltip_rect.y = height - tooltip_rect.y - tooltip_rect.height;
                     }
                     i++;
                     a -= Math.PI / 2;
@@ -193,7 +186,7 @@ namespace Baobab {
 
                     // clip to avoid drawing inside tooltip area (tooltip background
                     // could be transparent, depending on the theme)
-                    cr.rectangle (0, 0, allocation.width, allocation.height);
+                    cr.rectangle (0, 0, width, height);
                     cr.rectangle (tooltip_rect.x + tooltip_rect.width, tooltip_rect.y, -tooltip_rect.width, 
tooltip_rect.height);
                     cr.clip ();
 
@@ -214,7 +207,7 @@ namespace Baobab {
                     // draw tooltip box
                     context.render_background (cr, tooltip_rect.x, tooltip_rect.y, tooltip_rect.width, 
tooltip_rect.height);
                     context.render_frame (cr, tooltip_rect.x, tooltip_rect.y, tooltip_rect.width, 
tooltip_rect.height);
-                    context.render_layout (cr, tooltip_rect.x + padding.left, tooltip_rect.y + padding.top, 
layout);
+                    context.render_layout (cr, tooltip_rect.x, tooltip_rect.y, layout);
                 }
             }
 
@@ -234,9 +227,6 @@ namespace Baobab {
 
             cr.set_line_width (ITEM_BORDER_WIDTH);
 
-            Gtk.Allocation allocation;
-            get_allocation (out allocation);
-
             var context = get_style_context ();
             context.save ();
 
@@ -245,8 +235,8 @@ namespace Baobab {
             var border_color = context.get_border_color ();
             var bg_color = toplevel_context.get_background_color ();
 
-            var center_x = allocation.width / 2;
-            var center_y = allocation.height / 2;
+            var center_x = width / 2;
+            var center_y = height / 2;
             var final_angle = ringsitem.start_angle + ringsitem.angle;
 
             if (item.depth == 0) {
@@ -300,13 +290,10 @@ namespace Baobab {
             ringsitem.continued = false;
             ringsitem.visible = false;
 
-            Gtk.Allocation allocation;
-            get_allocation (out allocation);
-
             var context = get_style_context ();
 
-            var padding = context.get_padding ();
-            var max_radius = int.min (allocation.width / 2, allocation.height / 2) - padding.left; // 
Assuming that padding is the same for all sides
+            var max_radius = int.min (width / 2, height / 2);
+
             var thickness = max_radius / (max_depth + 1);
 
             if (ringsitem.parent == null) {
@@ -355,15 +342,15 @@ namespace Baobab {
             Gtk.Allocation allocation;
 
             get_allocation (out allocation);
-            cx = allocation.width / 2;
-            cy = allocation.height / 2;
+            cx = width / 2;
+            cy = height / 2;
             r1 = ringsitem.min_radius;
             r2 = ringsitem.max_radius;
             a1 = ringsitem.start_angle;
             a2 = ringsitem.start_angle + ringsitem.angle;
 
-            rect.x = allocation.width;
-            rect.y = allocation.height;
+            rect.x = width;
+            rect.y = height;
             rect.width = 0;
             rect.height = 0;
 
@@ -397,11 +384,8 @@ namespace Baobab {
         protected override bool is_point_over_item (ChartItem item, double x, double y) {
             var ringsitem = item as RingschartItem;
 
-            Gtk.Allocation allocation;
-            get_allocation (out allocation);
-
-            x -= allocation.width / 2;
-            y -= allocation.height / 2;
+            x -= width / 2;
+            y -= height / 2;
 
             var radius = Math.sqrt (x * x + y * y);
             var angle = Math.atan2 (y, x);
diff --git a/src/baobab-treemap.vala b/src/baobab-treemap.vala
index d58fa19..323a369 100644
--- a/src/baobab-treemap.vala
+++ b/src/baobab-treemap.vala
@@ -51,8 +51,8 @@ namespace Baobab {
         void draw_rectangle (Cairo.Context cr,
                              double x,
                              double y,
-                             double width,
-                             double height,
+                             double r_width,
+                             double r_height,
                              Gdk.RGBA fill_color,
                              string text,
                              bool show_text) {
@@ -63,7 +63,7 @@ namespace Baobab {
             context.set_state (Gtk.StateFlags.NORMAL);
 
             cr.set_line_width (border);
-            cr.rectangle (x + border, y + border, width - border * 2, height - border * 2);
+            cr.rectangle (x + border, y + border, r_width - border * 2, r_height - border * 2);
             Gdk.cairo_set_source_rgba (cr, fill_color);
             cr.fill_preserve ();
             var border_color = context.get_border_color ();
@@ -78,9 +78,9 @@ namespace Baobab {
                 Pango.Rectangle rect;
                 layout.get_pixel_extents (null, out rect);
 
-                if ((rect.width + ITEM_TEXT_PADDING * 2 <= width) &&
-                    (rect.height + ITEM_TEXT_PADDING * 2 <= height)) {
-                    context.render_layout (cr, x + width / 2 - rect.width / 2, y + height / 2 - rect.height 
/ 2, layout);
+                if ((rect.width + ITEM_TEXT_PADDING * 2 <= r_width) &&
+                    (rect.height + ITEM_TEXT_PADDING * 2 <= r_height)) {
+                    context.render_layout (cr, x + r_width / 2 - rect.width / 2, y + r_height / 2 - 
rect.height / 2, layout);
                 }
             }
 
@@ -90,25 +90,23 @@ namespace Baobab {
         protected override void draw_item (Cairo.Context cr, ChartItem item, bool highlighted) {
             Cairo.Rectangle rect;
             Gdk.RGBA fill_color = Gdk.RGBA ();
-            Gtk.Allocation allocation;
-            double width = 0, height = 0;
+            double r_width = 0, r_height = 0;
 
             rect = (item as TreemapItem).cr_rect;
-            get_allocation (out allocation);
 
             if ((item.depth % 2) != 0) {
-                fill_color = get_item_color (rect.x / allocation.width * 200,
+                fill_color = get_item_color (rect.x / width * 200,
                                              item.depth, highlighted);
-                width = rect.width - ITEM_PADDING;
-                height = rect.height;
+                r_width = rect.width - ITEM_PADDING;
+                r_height = rect.height;
             } else {
-                fill_color = get_item_color (rect.y / allocation.height * 200,
+                fill_color = get_item_color (rect.y / height * 200,
                                              item.depth, highlighted);
-                width = rect.width;
-                height = rect.height - ITEM_PADDING;
+                r_width = rect.width;
+                r_height = rect.height - ITEM_PADDING;
             }
 
-            draw_rectangle (cr, rect.x, rect.y, width, height, fill_color, item.name, 
(!item.has_visible_children));
+            draw_rectangle (cr, rect.x, rect.y, r_width, r_height, fill_color, item.name, 
(!item.has_visible_children));
         }
 
         protected override void calculate_item_geometry (ChartItem item) {
@@ -122,30 +120,28 @@ namespace Baobab {
 
             item.visible = false;
             if (item.parent == null) {
-                Gtk.Allocation allocation;
-                get_allocation (out allocation);
                 p_area.x = -ITEM_PADDING / 2;
                 p_area.y = -ITEM_PADDING / 2;
-                p_area.width = allocation.width + ITEM_PADDING * 2;
-                p_area.height = allocation.height + ITEM_PADDING * 2;
+                p_area.width = width + ITEM_PADDING * 2;
+                p_area.height = height + ITEM_PADDING * 2;
             } else {
                 p_area = (item.parent.data as TreemapItem).cr_rect;
             }
 
             if (item.depth % 2 != 0) {
-                var width = p_area.width - ITEM_PADDING;
+                var r_width = p_area.width - ITEM_PADDING;
 
-                treemapitem.cr_rect.x = p_area.x + (item.rel_start * width / 100) + ITEM_PADDING;
+                treemapitem.cr_rect.x = p_area.x + (item.rel_start * r_width / 100) + ITEM_PADDING;
                 treemapitem.cr_rect.y = p_area.y + ITEM_PADDING;
-                treemapitem.cr_rect.width = width * item.rel_size / 100;
+                treemapitem.cr_rect.width = r_width * item.rel_size / 100;
                 treemapitem.cr_rect.height = p_area.height - ITEM_PADDING * 3;
             } else {
-                var height = p_area.height - ITEM_PADDING;
+                var r_height = p_area.height - ITEM_PADDING;
 
                 treemapitem.cr_rect.x = p_area.x + ITEM_PADDING;
-                treemapitem.cr_rect.y = p_area.y + (item.rel_start * height / 100) + ITEM_PADDING;
+                treemapitem.cr_rect.y = p_area.y + (item.rel_start * r_height / 100) + ITEM_PADDING;
                 treemapitem.cr_rect.width = p_area.width - ITEM_PADDING * 3;
-                treemapitem.cr_rect.height = height * item.rel_size / 100;
+                treemapitem.cr_rect.height = r_height * item.rel_size / 100;
             }
             if ((treemapitem.cr_rect.width - ITEM_PADDING < ITEM_MIN_WIDTH) ||
                 (treemapitem.cr_rect.height - ITEM_PADDING < ITEM_MIN_HEIGHT)) {


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