diff --git a/src/modules/Groups/ui/GroupSidebar.vala b/src/modules/Groups/ui/GroupSidebar.vala index fbe147d..d561cf3 100644 --- a/src/modules/Groups/ui/GroupSidebar.vala +++ b/src/modules/Groups/ui/GroupSidebar.vala @@ -146,6 +146,32 @@ namespace Queue.Groups { .printf(selector)); } } + + // We also apply styling for drag-and-drop reordering of tasks. + + // First, we cancel the default styling from this line: + // https://gitlab.gnome.org/GNOME/gtk/-/blob/55fde92174e23c1abe287e4d8879f47f9d6b14cc/gtk/theme/Default/_common.scss#L4391 + + stylesheet.append(""" + .upper-drop, .lower-drop { + box-shadow: none; + } + """); + + // We play we margins to show indicators of where dragged tasks are + // going to land. We define CSS rules here and we apply classes to + // task rows in the drag-and-drop handlers. + + stylesheet.append(""" + .upper-drop:not(.drag-source) { + border-top: solid 2px var(--accent-bg-color); + } + + .lower-drop:not(.drag-source) { + border-bottom: solid 2px var(--accent-bg-color); + } + """); + color_provider.load_from_string(stylesheet.str); } } diff --git a/src/modules/Tasks/ui/TaskListPanel.vala b/src/modules/Tasks/ui/TaskListPanel.vala index b0b5ec3..f34aaf5 100644 --- a/src/modules/Tasks/ui/TaskListPanel.vala +++ b/src/modules/Tasks/ui/TaskListPanel.vala @@ -183,17 +183,31 @@ namespace Queue.Tasks { var source = new Gtk.DragSource() { actions = Gdk.DragAction.MOVE }; + source.prepare.connect((x, y) => { var value = Value(typeof (Task)); value.set_object(task); return new Gdk.ContentProvider.for_value(value); }); + source.drag_begin.connect((drag) => { source.set_icon(new Gtk.WidgetPaintable(row), 0, 0); + row.add_css_class("drag-source"); + }); + + source.drag_cancel.connect((drag, reason) => { + row.remove_css_class("drag-source"); + return false; + }); + + source.drag_end.connect((drag, delete_data) => { + row.remove_css_class("drag-source"); }); + row.add_controller(source); var target = new Gtk.DropTarget(typeof (Task), Gdk.DragAction.MOVE); + target.drop.connect((value, x, y) => { var dragged = value.get_object() as Task; if (dragged == null) { @@ -202,7 +216,37 @@ namespace Queue.Tasks { controller.move(dragged, task, y > row.get_height() / 2); return true; }); + + target.enter.connect((_, y) => { + set_drop_css_classes(row, y); + + return Gdk.DragAction.MOVE; + }); + + target.motion.connect((_, y) => { + set_drop_css_classes(row, y); + + return Gdk.DragAction.MOVE; + }); + + target.leave.connect(() => { + row.remove_css_class("upper-drop"); + row.remove_css_class("lower-drop"); + }); + row.add_controller(target); + + } + + private static void set_drop_css_classes (TaskRow row, double y) + { + if (y < row.get_height() / 2) { + row.add_css_class("upper-drop"); + row.remove_css_class("lower-drop"); + } else { + row.add_css_class("lower-drop"); + row.remove_css_class("upper-drop"); + } } } }