mirror of
https://gitlab.gnome.org/julianschacher/top-bar-organizer.git
synced 2025-10-27 23:29:08 +00:00
Refactor: Setup Drag Source and Drop Targets in UI files
This commit is contained in:
parent
5362629f94
commit
596c8d3cdc
@ -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>
|
||||||
|
|||||||
@ -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>
|
||||||
|
|||||||
@ -23,95 +23,6 @@ var PrefsBoxOrderItemRow = GObject.registerClass({
|
|||||||
|
|
||||||
this._associateItem(item);
|
this._associateItem(item);
|
||||||
this._configureMenu();
|
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);
|
actionGroup.add_action(forgetAction);
|
||||||
this.insert_action_group(`prefsBoxOrderItemRow-${this.item}`, actionGroup);
|
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();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@ -14,40 +14,34 @@ 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
|
// Handle a new drop on `this` properly.
|
||||||
/// `this`.
|
// `value` is the thing getting dropped.
|
||||||
let dropTarget = new Gtk.DropTarget();
|
onDrop(_target, value, _x, _y) {
|
||||||
dropTarget.set_gtypes([GObject.type_from_name("PrefsBoxOrderItemRow")]);
|
// Get the GtkListBoxes of `this` and the drop value.
|
||||||
dropTarget.set_actions(Gdk.DragAction.MOVE);
|
const ownListBox = this.get_parent();
|
||||||
// Handle a new drop on `this` properly.
|
const valueListBox = value.get_parent();
|
||||||
// `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();
|
|
||||||
|
|
||||||
// Remove the drop value from its list box.
|
// Remove the drop value from its list box.
|
||||||
valueListBox.remove(value);
|
valueListBox.remove(value);
|
||||||
|
|
||||||
// Insert the drop value into the list box of `this`.
|
// Insert the drop value into the list box of `this`.
|
||||||
ownListBox.insert(value, 0);
|
ownListBox.insert(value, 0);
|
||||||
|
|
||||||
/// Finally save the box orders to settings.
|
/// Finally save the box orders to settings.
|
||||||
settings.set_strv(ownListBox.boxOrder, [value.item]);
|
settings.set_strv(ownListBox.boxOrder, [value.item]);
|
||||||
|
|
||||||
let updatedBoxOrder = [ ];
|
let updatedBoxOrder = [ ];
|
||||||
for (let potentialListBoxRow of valueListBox) {
|
for (let potentialListBoxRow of valueListBox) {
|
||||||
// Only process PrefsBoxOrderItemRows.
|
// Only process PrefsBoxOrderItemRows.
|
||||||
if (potentialListBoxRow.constructor.$gtype.name !== "PrefsBoxOrderItemRow") {
|
if (potentialListBoxRow.constructor.$gtype.name !== "PrefsBoxOrderItemRow") {
|
||||||
continue;
|
continue;
|
||||||
}
|
|
||||||
|
|
||||||
const item = potentialListBoxRow.item;
|
|
||||||
updatedBoxOrder.push(item);
|
|
||||||
}
|
}
|
||||||
settings.set_strv(valueListBox.boxOrder, updatedBoxOrder);
|
|
||||||
});
|
const item = potentialListBoxRow.item;
|
||||||
this.add_controller(dropTarget);
|
updatedBoxOrder.push(item);
|
||||||
|
}
|
||||||
|
settings.set_strv(valueListBox.boxOrder, updatedBoxOrder);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user