Refactor: Setup and handle all of DND scroll. in #setupDNDScroll func.

Also handle drag events in this function so connecting to "drag-end" in
widgets with "GtkDragSource" and a `globalThis` `ScrollManager` instance
aren't needed.
This commit is contained in:
Julian 2023-01-24 18:33:15 +01:00
parent 398793d1a0
commit d7ec1156e2
Signed by: julian
GPG Key ID: 094C2AC34192FA11
3 changed files with 46 additions and 16 deletions

View File

@ -31,7 +31,6 @@
<property name="actions">move</property> <property name="actions">move</property>
<signal name="prepare" handler="onDragPrepare"/> <signal name="prepare" handler="onDragPrepare"/>
<signal name="drag-begin" handler="onDragBegin"/> <signal name="drag-begin" handler="onDragBegin"/>
<signal name="drag-end" handler="onDragEnd"/>
</object> </object>
</child> </child>
<child> <child>

View File

@ -81,11 +81,6 @@ var PrefsBoxOrderItemRow = GObject.registerClass({
drag.set_hotspot(this._drag_starting_point_x, this._drag_starting_point_y); drag.set_hotspot(this._drag_starting_point_x, this._drag_starting_point_y);
} }
onDragEnd() {
// Stop all scrolling, which is due to this DND operation.
scrollManager.stopScrollAll();
}
// Handle a new drop on `this` properly. // Handle a new drop on `this` properly.
// `value` is the thing getting dropped. // `value` is the thing getting dropped.
onDrop(_target, value, _x, _y) { onDrop(_target, value, _x, _y) {

View File

@ -20,28 +20,64 @@ var PrefsPage = GObject.registerClass({
constructor(params = {}) { constructor(params = {}) {
super(params); super(params);
// Scroll up or down, when a Drag-and-Drop operation is in progress and this.#setupDNDScroll();
// the user has their cursor either in the upper or lower 10% of this }
// widget respectively.
/**
* This function sets up Drag-and-Drop scrolling.
* This means that scroll up or down is happening when a Drag-and-Drop
* operation is in progress and the user has their cursor either in the
* upper or lower 10% of this widget respectively.
*/
#setupDNDScroll() {
// Pass `this.get_first_child()` to the ScrollManager, since this // Pass `this.get_first_child()` to the ScrollManager, since this
// `PrefsPage` extends an `Adw.PreferencesPage` and the first child of // `PrefsPage` extends an `Adw.PreferencesPage` and the first child of
// an `Adw.PreferencesPage` is the built-in `Gtk.ScrolledWindow`. // an `Adw.PreferencesPage` is the built-in `Gtk.ScrolledWindow`.
globalThis.scrollManager = new ScrollManager.ScrollManager(this.get_first_child()); this._scrollManager = new ScrollManager.ScrollManager(this.get_first_child());
/// Setup GtkDropControllerMotion event controller and make use of its
/// events.
let controller = new Gtk.DropControllerMotion(); let controller = new Gtk.DropControllerMotion();
controller.connect("motion", (_, x, y) => {
// Scroll, when the pointer is in the right places.
controller.connect("motion", (_, _x, y) => {
// If the pointer is currently in the upper ten percent of this // If the pointer is currently in the upper ten percent of this
// widget, then scroll up. // widget, then scroll up.
if (y <= this.get_allocated_height() * 0.1) scrollManager.startScrollUp(); if (y <= this.get_allocated_height() * 0.1) this._scrollManager.startScrollUp();
// If the pointer is currently in the lower ten percent of this // If the pointer is currently in the lower ten percent of this
// widget, then scroll down. // widget, then scroll down.
else if (y >= this.get_allocated_height() * 0.9) scrollManager.startScrollDown(); else if (y >= this.get_allocated_height() * 0.9) this._scrollManager.startScrollDown();
// Otherwise stop scrolling. // Otherwise stop scrolling.
else scrollManager.stopScrollAll(); else this._scrollManager.stopScrollAll();
}); });
// Make sure scrolling stops, when DND operation ends.
this._dndEnded = true;
const stopScrollAllAtDNDEnd = () => {
this._scrollManager.stopScrollAll();
this._dndEnded = true;
}
controller.connect("leave", () => { controller.connect("leave", () => {
// Stop scrolling on leave. stopScrollAllAtDNDEnd();
scrollManager.stopScrollAll();
}); });
controller.connect("enter", () => {
// Make use of `this._dndEnded` to setup stopScrollAtDNDEnd only
// once per DND operation.
if (this._dndEnded) {
let drag = controller.get_drop().get_drag();
drag.connect("drop-performed", () => {
stopScrollAllAtDNDEnd();
});
drag.connect("dnd-finished", () => {
stopScrollAllAtDNDEnd();
});
drag.connect("cancel", () => {
stopScrollAllAtDNDEnd();
});
this._dndEnded = false;
}
});
this.add_controller(controller); this.add_controller(controller);
} }
}); });