[shotwell/wip/gtk4: 16/88] Restore left clicks on checkerboard




commit 38832e9649ad8d4e0e257143628d72268f787e02
Author: Jens Georg <mail jensge org>
Date:   Sun Apr 3 22:04:02 2022 +0200

    Restore left clicks on checkerboard

 src/CheckerboardLayout.vala |  34 +++++++--------
 src/CheckerboardPage.vala   |  35 +++++++++-------
 src/Page.vala               | 100 ++++++++++++++++++++++++++++++++------------
 3 files changed, 107 insertions(+), 62 deletions(-)
---
diff --git a/src/CheckerboardLayout.vala b/src/CheckerboardLayout.vala
index e7da76ce..4d9a9e25 100644
--- a/src/CheckerboardLayout.vala
+++ b/src/CheckerboardLayout.vala
@@ -83,6 +83,12 @@ public class CheckerboardLayout : Gtk.DrawingArea {
         // CheckerboardItems offer tooltips
         has_tooltip = true;
         set_draw_func (on_draw);
+
+        var focus_controller = new Gtk.EventControllerFocus ();
+        focus_controller.set_name ("CheckerboardLayout focus watcher");
+        add_controller (focus_controller);
+        focus_controller.enter.connect (focus_in_event);
+        focus_controller.leave.connect (focus_out_event);
     }
     
     ~CheckerboardLayout() {
@@ -1072,25 +1078,21 @@ public class CheckerboardLayout : Gtk.DrawingArea {
     }
 
     private void set_colors(bool in_focus = true) {
-    #if 0
         // set up selected/unselected colors
         var ctx = get_style_context();
         ctx.save();
         ctx.add_class("view");
-        var val = ctx.get_property("border-color", Gtk.StateFlags.NORMAL);
-        focus_color = *(Gdk.RGBA*)val.get_boxed();
+        ctx.set_state (Gtk.StateFlags.NORMAL);
+        ctx.lookup_color("borders", out focus_color);
+        ctx.lookup_color("theme_fg_color", out unselected_color);
 
-        val = ctx.get_property("border-color", Gtk.StateFlags.FOCUSED);
-        border_color = *(Gdk.RGBA*)val.get_boxed();
+        ctx.set_state (Gtk.StateFlags.FOCUSED);
+        ctx.lookup_color("borders", out border_color);
 
         // Checked in GtkIconView - The selection is drawn using render_background
-        val = ctx.get_property("background-color", Gtk.StateFlags.FOCUSED | Gtk.StateFlags.SELECTED);
-        selected_color = *(Gdk.RGBA*)val.get_boxed();
-
-        val = ctx.get_property("color", Gtk.StateFlags.NORMAL);
-        unselected_color = *(Gdk.RGBA*)val.get_boxed();
+        ctx.set_state (Gtk.StateFlags.FOCUSED | Gtk.StateFlags.SELECTED);
+        ctx.lookup_color("theme_selected_bg_color", out selected_color);
         ctx.restore();
-        #endif
     }
     
     public override void size_allocate(int a, int b, int c)  {
@@ -1172,19 +1174,13 @@ public class CheckerboardLayout : Gtk.DrawingArea {
         queue_draw();
     }
 
-#if 0
-    public override bool focus_in_event(Gdk.EventFocus event) {
+    public void focus_in_event() {
         set_colors(true);
         items_dirty("focus_in_event", view.get_selected());
-        
-        return base.focus_in_event(event);
     }
 
-    public override bool focus_out_event(Gdk.EventFocus event) {
+    public void focus_out_event() {
         set_colors(false);
         items_dirty("focus_out_event", view.get_selected());
-        
-        return base.focus_out_event(event);
     }
-    #endif
 }
diff --git a/src/CheckerboardPage.vala b/src/CheckerboardPage.vala
index 9b9e8481..15893ef4 100644
--- a/src/CheckerboardPage.vala
+++ b/src/CheckerboardPage.vala
@@ -328,22 +328,24 @@ public abstract class CheckerboardPage : Page {
 
         return (base.key_press_event != null) ? base.key_press_event(event) : true;
     }
+    #endif
 
-    protected override bool on_left_click(Gdk.EventButton event) {
+    protected override bool on_left_click(Gtk.EventController event, int press, double x, double y) {
         // only interested in single-click and double-clicks for now
-        if ((event.type != Gdk.EventType.BUTTON_PRESS) && (event.type != Gdk.EventType.2BUTTON_PRESS))
+        if (press != 1 && press != 2)
             return false;
 
         // mask out the modifiers we're interested in
-        uint state = event.state & (Gdk.ModifierType.CONTROL_MASK | Gdk.ModifierType.SHIFT_MASK);
+        var state = event.get_current_event_state () &
+                (Gdk.ModifierType.CONTROL_MASK | Gdk.ModifierType.SHIFT_MASK);
 
         // use clicks for multiple selection and activation only; single selects are handled by
         // button release, to allow for multiple items to be selected then dragged ...
-        CheckerboardItem item = get_item_at_pixel(event.x, event.y);
+        CheckerboardItem item = get_item_at_pixel(x, y);
         if (item != null) {
             // ... however, there is no dragging if the user clicks on an interactive part of the
             // CheckerboardItem (e.g. a tag)
-            if (layout.handle_left_click(item, event.x, event.y, event.state))
+            if (layout.handle_left_click(item, x, y, event.get_current_event_state()))
                 return true;
 
             switch (state) {
@@ -355,7 +357,7 @@ public abstract class CheckerboardPage : Page {
 
                     if (item.is_selected()) {
                         anchor = item;
-                        cursor = item;
+                        current_cursor = item;
                     }
                 break;
 
@@ -367,7 +369,7 @@ public abstract class CheckerboardPage : Page {
 
                     select_between_items(anchor, item);
 
-                    cursor = item;
+                    current_cursor = item;
                 break;
 
                 case Gdk.ModifierType.CONTROL_MASK | Gdk.ModifierType.SHIFT_MASK:
@@ -380,11 +382,11 @@ public abstract class CheckerboardPage : Page {
 
                     select_between_items(anchor, item);
 
-                    cursor = item;
+                    current_cursor = item;
                 break;
 
                 default:
-                    if (event.type == Gdk.EventType.2BUTTON_PRESS) {
+                    if (press == 2) {
                         activated_item = item;
                     } else {
                         // if the user has selected one or more items and is preparing for a drag,
@@ -400,7 +402,7 @@ public abstract class CheckerboardPage : Page {
                     }
 
                     anchor = item;
-                    cursor = item;
+                    current_cursor = item;
                 break;
             }
             layout.set_cursor(item);
@@ -415,7 +417,7 @@ public abstract class CheckerboardPage : Page {
             foreach (DataView view in get_view().get_selected())
                 previously_selected.add((CheckerboardItem) view);
 
-            layout.set_drag_select_origin((int) event.x, (int) event.y);
+            layout.set_drag_select_origin((int) x, (int) y);
 
             return true;
         }
@@ -426,19 +428,19 @@ public abstract class CheckerboardPage : Page {
         return get_view().get_selected_count() == 0;
     }
 
-    protected override bool on_left_released(Gdk.EventButton event) {
+    protected override bool on_left_released(Gtk.EventController event, int press, double x, double y) {
         previously_selected = null;
 
         // if drag-selecting, stop here and do nothing else
         if (layout.is_drag_select_active()) {
             layout.clear_drag_select();
-            anchor = cursor;
+            anchor = current_cursor;
 
             return true;
         }
 
         // only interested in non-modified button releases
-        if ((event.state & (Gdk.ModifierType.CONTROL_MASK | Gdk.ModifierType.SHIFT_MASK)) != 0)
+        if ((event.get_current_event_state() & (Gdk.ModifierType.CONTROL_MASK | 
Gdk.ModifierType.SHIFT_MASK)) != 0)
             return false;
 
         // if the item was activated in the double-click, report it now
@@ -449,13 +451,13 @@ public abstract class CheckerboardPage : Page {
             return true;
         }
 
-        CheckerboardItem item = get_item_at_pixel(event.x, event.y);
+        CheckerboardItem item = get_item_at_pixel(x, y);
         if (item == null) {
             // released button on "dead" area
             return true;
         }
 
-        if (cursor != item) {
+        if (current_cursor != item) {
             // user released mouse button after moving it off the initial item, or moved from dead
             // space onto one.  either way, unselect everything
             get_view().unselect_all();
@@ -471,6 +473,7 @@ public abstract class CheckerboardPage : Page {
         return true;
     }
 
+#if 0
     protected override bool on_right_click(Gdk.EventButton event) {
         // only interested in single-clicks for now
         if (event.type != Gdk.EventType.BUTTON_PRESS)
diff --git a/src/Page.vala b/src/Page.vala
index d16a6943..dbaf42a4 100644
--- a/src/Page.vala
+++ b/src/Page.vala
@@ -86,6 +86,9 @@ public abstract class Page : Gtk.Box {
     private int cursor_hide_time_cached = 0;
     private bool are_actions_attached = false;
     private OneShotScheduler? update_actions_scheduler = null;
+
+    // Event controllers
+    private Gtk.GestureClick clicks;
     
     protected Page(string page_name) {
         Object (orientation: Gtk.Orientation.HORIZONTAL);
@@ -172,12 +175,21 @@ public abstract class Page : Gtk.Box {
     }
     
     public void set_event_source(Gtk.Widget event_source) {
-    #if 0
         assert(this.event_source == null);
 
         this.event_source = event_source;
-        event_source.set_can_focus(true);
+        event_source.focusable = true;
+
+        clicks = new Gtk.GestureClick();
+        clicks.set_name ("CheckerboardPage click source");
+        clicks.set_button (0); // Listen to all buttons
+        clicks.set_exclusive (true); // TODO: Need to be true or false?
+        event_source.add_controller (clicks);
+
+        clicks.pressed.connect (on_button_pressed_internal);
+        clicks.released.connect (on_button_released_internal);
 
+#if 0
         // interested in mouse button and motion events on the event source
         event_source.add_events(Gdk.EventMask.BUTTON_PRESS_MASK | Gdk.EventMask.BUTTON_RELEASE_MASK
             | Gdk.EventMask.POINTER_MOTION_MASK | Gdk.EventMask.POINTER_MOTION_HINT_MASK
@@ -193,10 +205,13 @@ public abstract class Page : Gtk.Box {
     }
     
     private void detach_event_source() {
-    #if 0
         if (event_source == null)
             return;
+
+        event_source.remove_controller (clicks);
+        clicks = null;
         
+    #if 0
         event_source.button_press_event.disconnect(on_button_pressed_internal);
         event_source.button_release_event.disconnect(on_button_released_internal);
         event_source.motion_notify_event.disconnect(on_motion_internal);
@@ -661,73 +676,104 @@ public abstract class Page : Gtk.Box {
         return true;
     }
     
-    #if 0
-    protected virtual bool on_left_click(Gdk.EventButton event) {
+    protected virtual bool on_left_click(Gtk.EventController event, int press, double x, double y) {
         return false;
     }
     
-    protected virtual bool on_middle_click(Gdk.EventButton event) {
+    protected virtual bool on_middle_click(Gtk.EventController event, int press, double x, double y) {
         return false;
     }
     
-    protected virtual bool on_right_click(Gdk.EventButton event) {
+    protected virtual bool on_right_click(Gtk.EventController event, int press, double x, double y) {
         return false;
     }
     
-    protected virtual bool on_left_released(Gdk.EventButton event) {
+    protected virtual bool on_left_released(Gtk.EventController event, int press, double x, double y) {
         return false;
     }
     
-    protected virtual bool on_middle_released(Gdk.EventButton event) {
+    protected virtual bool on_middle_released(Gtk.EventController event, int press, double x, double y) {
         return false;
     }
     
-    protected virtual bool on_right_released(Gdk.EventButton event) {
+    protected virtual bool on_right_released(Gtk.EventController event, int press, double x, double y) {
         return false;
     }
     
-    private bool on_button_pressed_internal(Gdk.EventButton event) {
-        switch (event.button) {
+    private void on_button_pressed_internal(Gtk.GestureClick gesture, int press, double x, double y) {
+        var sequence = gesture.get_current_sequence ();
+        var event = gesture.get_last_event (sequence);
+
+        if (press != 1)
+            return;
+
+        bool result = false;
+
+        switch (gesture.get_current_button()) {
             case 1:
                 if (event_source != null)
                     event_source.grab_focus();
                 
                 // stash location of mouse down for drag fixups
-                last_down.x = (int) event.x;
-                last_down.y = (int) event.y;
+                last_down.x = (int) x;
+                last_down.y = (int) y;
                 
-                return on_left_click(event);
+                result = on_left_click(gesture, press, x, y);
+                break;
 
             case 2:
-                return on_middle_click(event);
+                result = on_middle_click(gesture, press, x, y);
+                break;
             
             case 3:
-                return on_right_click(event);
+                result = on_right_click(gesture, press, x, y);
+                break;
             
             default:
-                return false;
+                break;
+        }
+
+        if (result) {
+            gesture.set_sequence_state (sequence, Gtk.EventSequenceState.CLAIMED);
         }
     }
     
-    private bool on_button_released_internal(Gdk.EventButton event) {
-        switch (event.button) {
+    private void on_button_released_internal(Gtk.GestureClick gesture, int press, double x, double y) {
+        var sequence = gesture.get_current_sequence ();
+        var event = gesture.get_last_event (sequence);
+
+        bool result = false;
+
+        switch (gesture.get_current_button()) {
             case 1:
-                // clear when button released, only for drag fixups
-                last_down = { -1, -1 };
+                if (event_source != null)
+                    event_source.grab_focus();
                 
-                return on_left_released(event);
-            
+                // stash location of mouse down for drag fixups
+                last_down.x = -1;
+                last_down.y = -1;
+                
+                result = on_left_released(gesture, press, x, y);
+                break;
+
             case 2:
-                return on_middle_released(event);
+                result = on_middle_released(gesture, press, x, y);
+                break;
             
             case 3:
-                return on_right_released(event);
+                result = on_right_released(gesture, press, x, y);
+                break;
             
             default:
-                return false;
+                break;
+        }
+
+        if (result) {
+            gesture.set_sequence_state (sequence, Gtk.EventSequenceState.CLAIMED);
         }
     }
 
+#if 0
     protected virtual bool on_ctrl_pressed(Gdk.EventKey? event) {
         return false;
     }


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