-
Notifications
You must be signed in to change notification settings - Fork 15
/
main.js
86 lines (65 loc) · 2.16 KB
/
main.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
import Adw from "gi://Adw";
import GObject from "gi://GObject";
import Gdk from "gi://Gdk?version=4.0";
import Gtk from "gi://Gtk?version=4.0";
const list = workbench.builder.get_object("list");
const drop_target = Gtk.DropTarget.new(Gtk.ListBoxRow, Gdk.DragAction.MOVE);
list.add_controller(drop_target);
// Iterate over ListBox children
for (const row of list) {
let drag_x;
let drag_y;
const drop_controller = new Gtk.DropControllerMotion();
const drag_source = new Gtk.DragSource({
actions: Gdk.DragAction.MOVE,
});
row.add_controller(drag_source);
row.add_controller(drop_controller);
// Drag handling
drag_source.connect("prepare", (_source, x, y) => {
drag_x = x;
drag_y = y;
const value = new GObject.Value();
value.init(Gtk.ListBoxRow);
value.set_object(row);
return Gdk.ContentProvider.new_for_value(value);
});
drag_source.connect("drag-begin", (_source, drag) => {
const drag_widget = new Gtk.ListBox();
drag_widget.set_size_request(row.get_width(), row.get_height());
drag_widget.add_css_class("boxed-list");
const drag_row = new Adw.ActionRow({ title: row.title });
drag_row.add_prefix(
new Gtk.Image({
icon_name: "list-drag-handle-symbolic",
css_classes: ["dim-label"],
}),
);
drag_widget.append(drag_row);
drag_widget.drag_highlight_row(drag_row);
const icon = Gtk.DragIcon.get_for_drag(drag);
icon.child = drag_widget;
drag.set_hotspot(drag_x, drag_y);
});
// Update row visuals during DnD operation
drop_controller.connect("enter", () => {
list.drag_highlight_row(row);
});
drop_controller.connect("leave", () => {
list.drag_unhighlight_row();
});
}
// Drop Handling
drop_target.connect("drop", (_drop, value, _x, y) => {
const target_row = list.get_row_at_y(y);
const target_index = target_row.get_index();
// If value or the target row is null, do not accept the drop
if (!value || !target_row) {
return false;
}
list.remove(value);
list.insert(value, target_index);
target_row.set_state_flags(Gtk.StateFlags.NORMAL, true);
// If everything is successful, return true to accept the drop
return true;
});