[geary/wip/714104-refine-account-dialog] Add some polish to account edditor list drag and drop



commit f707962158dbc5d11a080e286f0e71762a8fd92e
Author: Michael Gratton <mike vee net>
Date:   Sun Dec 2 15:11:15 2018 +1100

    Add some polish to account edditor list drag and drop
    
    Paint the row that was picked up as the drag icon, dim the actual row
    and don't highlight it when dragging over itself.

 src/client/accounts/accounts-editor-row.vala | 72 +++++++++++++++++++++++++++-
 ui/geary.css                                 | 10 ++++
 2 files changed, 81 insertions(+), 1 deletion(-)
---
diff --git a/src/client/accounts/accounts-editor-row.vala b/src/client/accounts/accounts-editor-row.vala
index 681faa48..31927004 100644
--- a/src/client/accounts/accounts-editor-row.vala
+++ b/src/client/accounts/accounts-editor-row.vala
@@ -17,6 +17,8 @@ internal class Accounts.EditorRow<PaneType> : Gtk.ListBoxRow {
     protected Gtk.Grid layout { get; private set; default = new Gtk.Grid(); }
 
     private Gtk.Container drag_handle;
+    private bool drag_picked_up = false;
+    private bool drag_entered = false;
 
 
     public signal void dropped(EditorRow target);
@@ -64,13 +66,21 @@ internal class Accounts.EditorRow<PaneType> : Gtk.ListBoxRow {
 
         Gtk.drag_dest_set(
             this,
-            Gtk.DestDefaults.ALL,
+            // No highlight, we'll take care of that ourselves so we
+            // can avoid highlighting the row that was picked up
+            Gtk.DestDefaults.MOTION | Gtk.DestDefaults.DROP,
             DRAG_ENTRIES,
             Gdk.DragAction.MOVE
         );
 
+        this.drag_handle.drag_begin.connect(on_drag_begin);
+        this.drag_handle.drag_end.connect(on_drag_end);
         this.drag_handle.drag_data_get.connect(on_drag_data_get);
+
+        this.drag_motion.connect(on_drag_motion);
+        this.drag_leave.connect(on_drag_leave);
         this.drag_data_received.connect(on_drag_data_received);
+
         this.drag_handle.get_style_context().add_class("geary-drag-handle");
         this.drag_handle.show();
 
@@ -78,6 +88,66 @@ internal class Accounts.EditorRow<PaneType> : Gtk.ListBoxRow {
     }
 
 
+    private void on_drag_begin(Gdk.DragContext context) {
+        // Draw a nice drag icon
+        Gtk.Allocation alloc = Gtk.Allocation();
+        this.get_allocation(out alloc);
+
+        Cairo.ImageSurface surface = new Cairo.ImageSurface(
+            Cairo.Format.ARGB32, alloc.width, alloc.height
+        );
+        Cairo.Context paint = new Cairo.Context(surface);
+
+
+        Gtk.StyleContext style = get_style_context();
+        style.add_class("geary-drag-icon");
+        draw(paint);
+        style.remove_class("geary-drag-icon");
+
+        int x, y;
+        this.drag_handle.translate_coordinates(this, 0, 0, out x, out y);
+        surface.set_device_offset(-x, -y);
+        Gtk.drag_set_icon_surface(context, surface);
+
+        // Set a visual hint that the row is being dragged
+        style.add_class("geary-drag-source");
+        this.drag_picked_up = true;
+    }
+
+    private void on_drag_end(Gdk.DragContext context) {
+        get_style_context().remove_class("geary-drag-source");
+        this.drag_picked_up = false;
+    }
+
+    private bool on_drag_motion(Gdk.DragContext context,
+                                int x, int y,
+                                uint time_) {
+        if (!this.drag_entered) {
+            this.drag_entered = true;
+
+            // Don't highlight the same row that was picked up
+            if (!this.drag_picked_up) {
+                Gtk.ListBox? parent = get_parent() as Gtk.ListBox;
+                if (parent != null) {
+                    parent.drag_highlight_row(this);
+                }
+            }
+        }
+
+        return true;
+    }
+
+    private void on_drag_leave(Gdk.DragContext context,
+                               uint time_) {
+        if (!this.drag_picked_up) {
+            Gtk.ListBox? parent = get_parent() as Gtk.ListBox;
+            if (parent != null) {
+                parent.drag_unhighlight_row();
+            }
+        }
+        this.drag_entered = false;
+    }
+
     private void on_drag_data_get(Gdk.DragContext context,
                                   Gtk.SelectionData selection_data,
                                   uint info, uint time_) {
diff --git a/ui/geary.css b/ui/geary.css
index 3cbc9afc..d1cf79f4 100644
--- a/ui/geary.css
+++ b/ui/geary.css
@@ -212,6 +212,16 @@ row.geary-settings image {
   padding: 0px 6px;
 }
 
+row.geary-settings.geary-drag-source {
+  color: @insensitive_fg_color;
+  background-color: @insensitive_bg_color;
+}
+
+row.geary-settings.geary-drag-icon {
+  background-color: @theme_base_color;
+  border: 1px solid @borders;
+}
+
 row.geary-settings > grid > * {
   margin: 18px 6px;
 }


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