From 596c8d3cdc34f8ce45b835deef11d725da82d44d Mon Sep 17 00:00:00 2001 From: Julian Schacher Date: Sun, 22 Jan 2023 20:06:02 +0100 Subject: [PATCH] Refactor: Setup Drag Source and Drop Targets in UI files --- data/ui/prefs-box-order-item-row.ui | 15 ++ .../prefs-box-order-list-empty-placeholder.ui | 7 + src/prefsModules/PrefsBoxOrderItemRow.js | 173 +++++++++--------- .../PrefsBoxOrderListEmptyPlaceholder.js | 52 +++--- 4 files changed, 129 insertions(+), 118 deletions(-) diff --git a/data/ui/prefs-box-order-item-row.ui b/data/ui/prefs-box-order-item-row.ui index 5ce9994..ba957d1 100644 --- a/data/ui/prefs-box-order-item-row.ui +++ b/data/ui/prefs-box-order-item-row.ui @@ -24,5 +24,20 @@ + + + move + + + + + + + + move + PrefsBoxOrderItemRow + + + diff --git a/data/ui/prefs-box-order-list-empty-placeholder.ui b/data/ui/prefs-box-order-list-empty-placeholder.ui index e4d1fd1..d113107 100644 --- a/data/ui/prefs-box-order-list-empty-placeholder.ui +++ b/data/ui/prefs-box-order-list-empty-placeholder.ui @@ -19,5 +19,12 @@ + + + move + PrefsBoxOrderItemRow + + + diff --git a/src/prefsModules/PrefsBoxOrderItemRow.js b/src/prefsModules/PrefsBoxOrderItemRow.js index 31adebe..037d64a 100644 --- a/src/prefsModules/PrefsBoxOrderItemRow.js +++ b/src/prefsModules/PrefsBoxOrderItemRow.js @@ -23,95 +23,6 @@ var PrefsBoxOrderItemRow = GObject.registerClass({ this._associateItem(item); this._configureMenu(); - - // Make `this` draggable by creating a drag source and adding it to - // `this`. - let dragSource = new Gtk.DragSource(); - dragSource.set_actions(Gdk.DragAction.MOVE); - dragSource.connect("prepare", (source, x, y) => { - this._drag_starting_point_x = x; - this._drag_starting_point_y = y; - return Gdk.ContentProvider.new_for_value(this); - }); - // Stop all scrolling, which is due to this DND operation. - dragSource.connect("drag-end", () => { - scrollManager.stopScrollAll(); - }); - dragSource.connect("drag-begin", (source, drag) => { - let dragWidget = new Gtk.ListBox(); - let allocation = this.get_allocation(); - dragWidget.set_size_request(allocation.width, allocation.height); - - let dragPrefsBoxOrderItemRow = new PrefsBoxOrderItemRow({}, this.item) - dragWidget.append(dragPrefsBoxOrderItemRow); - dragWidget.drag_highlight_row(dragPrefsBoxOrderItemRow); - - let currentDragIcon = Gtk.DragIcon.get_for_drag(drag); - currentDragIcon.set_child(dragWidget); - drag.set_hotspot(this._drag_starting_point_x, this._drag_starting_point_y); - }); - this.add_controller(dragSource); - - /// Make `this` accept drops by creating a drop target and adding it to - /// `this`. - let dropTarget = new Gtk.DropTarget(); - dropTarget.set_gtypes([this.constructor.$gtype]); - dropTarget.set_actions(Gdk.DragAction.MOVE); - // Handle a new drop on `this` properly. - // `value` is the thing getting dropped. - dropTarget.connect("drop", (target, value) => { - // If `this` got dropped onto itself, do nothing. - if (value === this) { - return; - } - - // Get the GtkListBoxes of `this` and the drop value. - const ownListBox = this.get_parent(); - const valueListBox = value.get_parent(); - - // Get the position of `this` and the drop value. - const ownPosition = this.get_index(); - const valuePosition = value.get_index(); - - // Remove the drop value from its list box. - valueListBox.remove(value); - - // Since an element got potentially removed from the list of `this`, - // get the position of `this` again. - const updatedOwnPosition = this.get_index(); - - if (ownListBox !== valueListBox) { - // First handle the case where `this` and the drop value are in - // different list boxes. - if ((ownListBox.boxOrder === "right-box-order" && valueListBox.boxOrder === "left-box-order") - || (ownListBox.boxOrder === "right-box-order" && valueListBox.boxOrder === "center-box-order") - || (ownListBox.boxOrder === "center-box-order" && valueListBox.boxOrder === "left-box-order")) { - // If the list box of the drop value comes before the list - // box of `this`, add the drop value after `this`. - ownListBox.insert(value, updatedOwnPosition + 1); - } else { - // Otherwise, add the drop value where `this` currently is. - ownListBox.insert(value, updatedOwnPosition); - } - } else { - if (valuePosition < ownPosition) { - // If the drop value was before `this`, add the drop value - // after `this`. - ownListBox.insert(value, updatedOwnPosition + 1); - } else { - // Otherwise, add the drop value where `this` currently is. - ownListBox.insert(value, updatedOwnPosition); - } - } - - /// Finally save the box order(/s) to settings. - ownListBox.saveBoxOrderToSettings(); - // If the list boxes of `this` and the drop value were different, - // save an updated box order for the list were the drop value was in - // as well. - if (ownListBox !== valueListBox) valueListBox.saveBoxOrderToSettings(); - }); - this.add_controller(dropTarget); } /** @@ -147,4 +58,88 @@ var PrefsBoxOrderItemRow = GObject.registerClass({ actionGroup.add_action(forgetAction); this.insert_action_group(`prefsBoxOrderItemRow-${this.item}`, actionGroup); } + + onDragPrepare(_source, x, y) { + const value = new GObject.Value(); + value.init(PrefsBoxOrderItemRow); + value.set_object(this); + + this._drag_starting_point_x = x; + this._drag_starting_point_y = y; + return Gdk.ContentProvider.new_for_value(value); + } + + onDragBegin(_source, drag) { + let dragWidget = new Gtk.ListBox(); + let allocation = this.get_allocation(); + dragWidget.set_size_request(allocation.width, allocation.height); + + let dragPrefsBoxOrderItemRow = new PrefsBoxOrderItemRow({}, this.item) + dragWidget.append(dragPrefsBoxOrderItemRow); + dragWidget.drag_highlight_row(dragPrefsBoxOrderItemRow); + + let currentDragIcon = Gtk.DragIcon.get_for_drag(drag); + currentDragIcon.set_child(dragWidget); + 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. + // `value` is the thing getting dropped. + onDrop(_target, value, _x, _y) { + // If `this` got dropped onto itself, do nothing. + if (value === this) { + return; + } + + // Get the GtkListBoxes of `this` and the drop value. + const ownListBox = this.get_parent(); + const valueListBox = value.get_parent(); + + // Get the position of `this` and the drop value. + const ownPosition = this.get_index(); + const valuePosition = value.get_index(); + + // Remove the drop value from its list box. + valueListBox.remove(value); + + // Since an element got potentially removed from the list of `this`, + // get the position of `this` again. + const updatedOwnPosition = this.get_index(); + + if (ownListBox !== valueListBox) { + // First handle the case where `this` and the drop value are in + // different list boxes. + if ((ownListBox.boxOrder === "right-box-order" && valueListBox.boxOrder === "left-box-order") + || (ownListBox.boxOrder === "right-box-order" && valueListBox.boxOrder === "center-box-order") + || (ownListBox.boxOrder === "center-box-order" && valueListBox.boxOrder === "left-box-order")) { + // If the list box of the drop value comes before the list + // box of `this`, add the drop value after `this`. + ownListBox.insert(value, updatedOwnPosition + 1); + } else { + // Otherwise, add the drop value where `this` currently is. + ownListBox.insert(value, updatedOwnPosition); + } + } else { + if (valuePosition < ownPosition) { + // If the drop value was before `this`, add the drop value + // after `this`. + ownListBox.insert(value, updatedOwnPosition + 1); + } else { + // Otherwise, add the drop value where `this` currently is. + ownListBox.insert(value, updatedOwnPosition); + } + } + + /// Finally save the box order(/s) to settings. + ownListBox.saveBoxOrderToSettings(); + // If the list boxes of `this` and the drop value were different, + // save an updated box order for the list were the drop value was in + // as well. + if (ownListBox !== valueListBox) valueListBox.saveBoxOrderToSettings(); + } }); diff --git a/src/prefsModules/PrefsBoxOrderListEmptyPlaceholder.js b/src/prefsModules/PrefsBoxOrderListEmptyPlaceholder.js index 60f24be..f7d0ed4 100644 --- a/src/prefsModules/PrefsBoxOrderListEmptyPlaceholder.js +++ b/src/prefsModules/PrefsBoxOrderListEmptyPlaceholder.js @@ -14,40 +14,34 @@ var PrefsBoxOrderListEmptyPlaceholder = GObject.registerClass({ }, class PrefsBoxOrderListEmptyPlaceholder extends Gtk.Box { constructor(params = {}) { super(params); + } - /// Make `this` accept drops by creating a drop target and adding it to - /// `this`. - let dropTarget = new Gtk.DropTarget(); - dropTarget.set_gtypes([GObject.type_from_name("PrefsBoxOrderItemRow")]); - dropTarget.set_actions(Gdk.DragAction.MOVE); - // Handle a new drop on `this` properly. - // `value` is the thing getting dropped. - dropTarget.connect("drop", (target, value) => { - // Get the GtkListBoxes of `this` and the drop value. - const ownListBox = this.get_parent(); - const valueListBox = value.get_parent(); + // Handle a new drop on `this` properly. + // `value` is the thing getting dropped. + onDrop(_target, value, _x, _y) { + // Get the GtkListBoxes of `this` and the drop value. + const ownListBox = this.get_parent(); + const valueListBox = value.get_parent(); - // Remove the drop value from its list box. - valueListBox.remove(value); + // Remove the drop value from its list box. + valueListBox.remove(value); - // Insert the drop value into the list box of `this`. - ownListBox.insert(value, 0); + // Insert the drop value into the list box of `this`. + ownListBox.insert(value, 0); - /// Finally save the box orders to settings. - settings.set_strv(ownListBox.boxOrder, [value.item]); + /// Finally save the box orders to settings. + settings.set_strv(ownListBox.boxOrder, [value.item]); - let updatedBoxOrder = [ ]; - for (let potentialListBoxRow of valueListBox) { - // Only process PrefsBoxOrderItemRows. - if (potentialListBoxRow.constructor.$gtype.name !== "PrefsBoxOrderItemRow") { - continue; - } - - const item = potentialListBoxRow.item; - updatedBoxOrder.push(item); + let updatedBoxOrder = [ ]; + for (let potentialListBoxRow of valueListBox) { + // Only process PrefsBoxOrderItemRows. + if (potentialListBoxRow.constructor.$gtype.name !== "PrefsBoxOrderItemRow") { + continue; } - settings.set_strv(valueListBox.boxOrder, updatedBoxOrder); - }); - this.add_controller(dropTarget); + + const item = potentialListBoxRow.item; + updatedBoxOrder.push(item); + } + settings.set_strv(valueListBox.boxOrder, updatedBoxOrder); } });