Refactor: Setup Drag Source and Drop Targets in UI files

This commit is contained in:
Julian 2023-01-22 20:06:02 +01:00
parent 5362629f94
commit 596c8d3cdc
Signed by: julian
GPG Key ID: 094C2AC34192FA11
4 changed files with 129 additions and 118 deletions

View File

@ -24,5 +24,20 @@
</style> </style>
</object> </object>
</child> </child>
<child>
<object class="GtkDragSource">
<property name="actions">move</property>
<signal name="prepare" handler="onDragPrepare"/>
<signal name="drag-begin" handler="onDragBegin"/>
<signal name="drag-end" handler="onDragEnd"/>
</object>
</child>
<child>
<object class="GtkDropTarget">
<property name="actions">move</property>
<property name="formats">PrefsBoxOrderItemRow</property>
<signal name="drop" handler="onDrop"/>
</object>
</child>
</template> </template>
</interface> </interface>

View File

@ -19,5 +19,12 @@
</child> </child>
</object> </object>
</child> </child>
<child>
<object class="GtkDropTarget">
<property name="actions">move</property>
<property name="formats">PrefsBoxOrderItemRow</property>
<signal name="drop" handler="onDrop"/>
</object>
</child>
</template> </template>
</interface> </interface>

View File

@ -23,21 +23,53 @@ var PrefsBoxOrderItemRow = GObject.registerClass({
this._associateItem(item); this._associateItem(item);
this._configureMenu(); this._configureMenu();
}
/**
* Associate `this` with an item.
* @param {String} item
*/
_associateItem(item) {
this.item = item;
// Set `this._item_name_display_label` to something nicer, if the
// associated item is an AppIndicator/KStatusNotifierItem item.
if (item.startsWith("appindicator-kstatusnotifieritem-")) this._item_name_display_label.set_label(item.replace("appindicator-kstatusnotifieritem-", ""));
// Otherwise just set it to `item`.
else this._item_name_display_label.set_label(item);
}
/**
* Configure the menu.
*/
_configureMenu() {
let menu = new Gio.Menu();
menu.append("Forget", `prefsBoxOrderItemRow-${this.item}.forget`);
this._menu_button.set_menu_model(menu);
const forgetAction = new Gio.SimpleAction({ name: "forget" });
forgetAction.connect("activate", () => {
const parentListBox = this.get_parent();
parentListBox.remove(this);
parentListBox.saveBoxOrderToSettings();
});
const actionGroup = new Gio.SimpleActionGroup();
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);
// 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_x = x;
this._drag_starting_point_y = y; this._drag_starting_point_y = y;
return Gdk.ContentProvider.new_for_value(this); return Gdk.ContentProvider.new_for_value(value);
}); }
// Stop all scrolling, which is due to this DND operation.
dragSource.connect("drag-end", () => { onDragBegin(_source, drag) {
scrollManager.stopScrollAll();
});
dragSource.connect("drag-begin", (source, drag) => {
let dragWidget = new Gtk.ListBox(); let dragWidget = new Gtk.ListBox();
let allocation = this.get_allocation(); let allocation = this.get_allocation();
dragWidget.set_size_request(allocation.width, allocation.height); dragWidget.set_size_request(allocation.width, allocation.height);
@ -49,17 +81,16 @@ var PrefsBoxOrderItemRow = GObject.registerClass({
let currentDragIcon = Gtk.DragIcon.get_for_drag(drag); let currentDragIcon = Gtk.DragIcon.get_for_drag(drag);
currentDragIcon.set_child(dragWidget); currentDragIcon.set_child(dragWidget);
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);
}); }
this.add_controller(dragSource);
onDragEnd() {
// Stop all scrolling, which is due to this DND operation.
scrollManager.stopScrollAll();
}
/// 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. // Handle a new drop on `this` properly.
// `value` is the thing getting dropped. // `value` is the thing getting dropped.
dropTarget.connect("drop", (target, value) => { onDrop(_target, value, _x, _y) {
// If `this` got dropped onto itself, do nothing. // If `this` got dropped onto itself, do nothing.
if (value === this) { if (value === this) {
return; return;
@ -110,41 +141,5 @@ var PrefsBoxOrderItemRow = GObject.registerClass({
// save an updated box order for the list were the drop value was in // save an updated box order for the list were the drop value was in
// as well. // as well.
if (ownListBox !== valueListBox) valueListBox.saveBoxOrderToSettings(); if (ownListBox !== valueListBox) valueListBox.saveBoxOrderToSettings();
});
this.add_controller(dropTarget);
}
/**
* Associate `this` with an item.
* @param {String} item
*/
_associateItem(item) {
this.item = item;
// Set `this._item_name_display_label` to something nicer, if the
// associated item is an AppIndicator/KStatusNotifierItem item.
if (item.startsWith("appindicator-kstatusnotifieritem-")) this._item_name_display_label.set_label(item.replace("appindicator-kstatusnotifieritem-", ""));
// Otherwise just set it to `item`.
else this._item_name_display_label.set_label(item);
}
/**
* Configure the menu.
*/
_configureMenu() {
let menu = new Gio.Menu();
menu.append("Forget", `prefsBoxOrderItemRow-${this.item}.forget`);
this._menu_button.set_menu_model(menu);
const forgetAction = new Gio.SimpleAction({ name: "forget" });
forgetAction.connect("activate", () => {
const parentListBox = this.get_parent();
parentListBox.remove(this);
parentListBox.saveBoxOrderToSettings();
});
const actionGroup = new Gio.SimpleActionGroup();
actionGroup.add_action(forgetAction);
this.insert_action_group(`prefsBoxOrderItemRow-${this.item}`, actionGroup);
} }
}); });

View File

@ -14,15 +14,11 @@ var PrefsBoxOrderListEmptyPlaceholder = GObject.registerClass({
}, class PrefsBoxOrderListEmptyPlaceholder extends Gtk.Box { }, class PrefsBoxOrderListEmptyPlaceholder extends Gtk.Box {
constructor(params = {}) { constructor(params = {}) {
super(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. // Handle a new drop on `this` properly.
// `value` is the thing getting dropped. // `value` is the thing getting dropped.
dropTarget.connect("drop", (target, value) => { onDrop(_target, value, _x, _y) {
// Get the GtkListBoxes of `this` and the drop value. // Get the GtkListBoxes of `this` and the drop value.
const ownListBox = this.get_parent(); const ownListBox = this.get_parent();
const valueListBox = value.get_parent(); const valueListBox = value.get_parent();
@ -47,7 +43,5 @@ var PrefsBoxOrderListEmptyPlaceholder = GObject.registerClass({
updatedBoxOrder.push(item); updatedBoxOrder.push(item);
} }
settings.set_strv(valueListBox.boxOrder, updatedBoxOrder); settings.set_strv(valueListBox.boxOrder, updatedBoxOrder);
});
this.add_controller(dropTarget);
} }
}); });