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. Icon drawing code courtesy ebassi's tutorial: https://blog.gtk.org/2017/04/23/drag-and-drop-in-lists/
This commit is contained in:
parent
9aab053382
commit
f630e03485
2 changed files with 81 additions and 1 deletions
|
|
@ -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_) {
|
||||
|
|
|
|||
10
ui/geary.css
10
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;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue