mirror of
https://gitlab.gnome.org/julianschacher/top-bar-organizer.git
synced 2025-10-27 07:09:07 +00:00
Feature: Add move up and down buttons to make the prefs keyboard access.
Don't use CONSTRUCT_ONLY anymore to be able to use private properties (or any properties at all it seems).
This commit is contained in:
parent
a1188d5684
commit
9b7ab0614c
@ -42,6 +42,16 @@
|
||||
</child>
|
||||
</template>
|
||||
<menu id="optionsMenuModel">
|
||||
<section>
|
||||
<item>
|
||||
<attribute name="label">Move Up</attribute>
|
||||
<attribute name="action">row.move-up</attribute>
|
||||
</item>
|
||||
<item>
|
||||
<attribute name="label">Move Down</attribute>
|
||||
<attribute name="action">row.move-down</attribute>
|
||||
</item>
|
||||
</section>
|
||||
<section>
|
||||
<item>
|
||||
<attribute name="label">Forget</attribute>
|
||||
|
||||
@ -13,8 +13,9 @@
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="PrefsBoxOrderListBox">
|
||||
<object class="PrefsBoxOrderListBox" id="left-box-order-list-box">
|
||||
<property name="box-order">left-box-order</property>
|
||||
<signal name="row-move" handler="onRowMove"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
@ -26,8 +27,9 @@
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="PrefsBoxOrderListBox">
|
||||
<object class="PrefsBoxOrderListBox" id="center-box-order-list-box">
|
||||
<property name="box-order">center-box-order</property>
|
||||
<signal name="row-move" handler="onRowMove"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
@ -39,8 +41,9 @@
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="PrefsBoxOrderListBox">
|
||||
<object class="PrefsBoxOrderListBox" id="right-box-order-list-box">
|
||||
<property name="box-order">right-box-order</property>
|
||||
<signal name="row-move" handler="onRowMove"/>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
|
||||
@ -7,13 +7,24 @@ import GObject from "gi://GObject";
|
||||
import Adw from "gi://Adw";
|
||||
import GLib from "gi://GLib";
|
||||
|
||||
const PrefsBoxOrderItemRow = GObject.registerClass({
|
||||
GTypeName: "PrefsBoxOrderItemRow",
|
||||
Template: GLib.uri_resolve_relative(import.meta.url, "../ui/prefs-box-order-item-row.ui", GLib.UriFlags.NONE),
|
||||
InternalChildren: [
|
||||
"item-name-display-label"
|
||||
]
|
||||
}, class PrefsBoxOrderItemRow extends Adw.ActionRow {
|
||||
export default class PrefsBoxOrderItemRow extends Adw.ActionRow {
|
||||
static {
|
||||
GObject.registerClass({
|
||||
GTypeName: "PrefsBoxOrderItemRow",
|
||||
Template: GLib.uri_resolve_relative(import.meta.url, "../ui/prefs-box-order-item-row.ui", GLib.UriFlags.NONE),
|
||||
InternalChildren: [
|
||||
"item-name-display-label"
|
||||
],
|
||||
Signals: {
|
||||
"move": {
|
||||
param_types: [GObject.TYPE_STRING]
|
||||
}
|
||||
}
|
||||
}, this);
|
||||
this.install_action("row.move-up", null, (self, _actionName, _param) => self.emit("move", "up"));
|
||||
this.install_action("row.move-down", null, (self, _actionName, _param) => self.emit("move", "down"));
|
||||
}
|
||||
|
||||
#drag_starting_point_x;
|
||||
#drag_starting_point_y;
|
||||
|
||||
@ -52,8 +63,9 @@ const PrefsBoxOrderItemRow = GObject.registerClass({
|
||||
});
|
||||
forgetAction.connect("activate", (_action, _params) => {
|
||||
const parentListBox = this.get_parent();
|
||||
parentListBox.remove(this);
|
||||
parentListBox.removeRow(this);
|
||||
parentListBox.saveBoxOrderToSettings();
|
||||
parentListBox.determineRowMoveActionEnable();
|
||||
});
|
||||
actionGroup.add_action(forgetAction);
|
||||
|
||||
@ -101,7 +113,7 @@ const PrefsBoxOrderItemRow = GObject.registerClass({
|
||||
const valuePosition = value.get_index();
|
||||
|
||||
// Remove the drop value from its list box.
|
||||
valueListBox.remove(value);
|
||||
valueListBox.removeRow(value);
|
||||
|
||||
// Since an element got potentially removed from the list of `this`,
|
||||
// get the position of `this` again.
|
||||
@ -115,31 +127,31 @@ const PrefsBoxOrderItemRow = GObject.registerClass({
|
||||
|| (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);
|
||||
ownListBox.insertRow(value, updatedOwnPosition + 1);
|
||||
} else {
|
||||
// Otherwise, add the drop value where `this` currently is.
|
||||
ownListBox.insert(value, updatedOwnPosition);
|
||||
ownListBox.insertRow(value, updatedOwnPosition);
|
||||
}
|
||||
} else {
|
||||
if (valuePosition < ownPosition) {
|
||||
// If the drop value was before `this`, add the drop value
|
||||
// after `this`.
|
||||
ownListBox.insert(value, updatedOwnPosition + 1);
|
||||
ownListBox.insertRow(value, updatedOwnPosition + 1);
|
||||
} else {
|
||||
// Otherwise, add the drop value where `this` currently is.
|
||||
ownListBox.insert(value, updatedOwnPosition);
|
||||
ownListBox.insertRow(value, updatedOwnPosition);
|
||||
}
|
||||
}
|
||||
|
||||
/// Finally save the box order(/s) to settings.
|
||||
/// Finally save the box order(/s) to settings and make sure move
|
||||
/// actions are correctly enabled/disabled.
|
||||
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.
|
||||
ownListBox.determineRowMoveActionEnable();
|
||||
// If the list boxes of `this` and the drop value were different, handle
|
||||
// the former list box of the drop value as well.
|
||||
if (ownListBox !== valueListBox) {
|
||||
valueListBox.saveBoxOrderToSettings();
|
||||
valueListBox.determineRowMoveActionEnable();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
export default PrefsBoxOrderItemRow;
|
||||
}
|
||||
|
||||
@ -17,12 +17,18 @@ const PrefsBoxOrderListBox = GObject.registerClass({
|
||||
"box-order",
|
||||
"Box Order",
|
||||
"The box order this PrefsBoxOrderListBox is associated with.",
|
||||
GObject.ParamFlags.READWRITE | GObject.ParamFlags.CONSTRUCT_ONLY,
|
||||
GObject.ParamFlags.READWRITE,
|
||||
""
|
||||
)
|
||||
},
|
||||
Signals: {
|
||||
"row-move": {
|
||||
param_types: [PrefsBoxOrderItemRow, GObject.TYPE_STRING]
|
||||
}
|
||||
}
|
||||
}, class PrefsBoxOrderListBox extends Gtk.ListBox {
|
||||
#settings;
|
||||
#rowSignalHandlerIds = new Map();
|
||||
|
||||
/**
|
||||
* @param {Object} params
|
||||
@ -45,21 +51,49 @@ const PrefsBoxOrderListBox = GObject.registerClass({
|
||||
set boxOrder(value) {
|
||||
this._boxOrder = value;
|
||||
|
||||
// Load the settings here as well, since a `CONSTRUCT_ONLY` property
|
||||
// apparently can't access `this.#settings`.
|
||||
const settings = ExtensionPreferences.lookupByURL(import.meta.url).getSettings();
|
||||
// Get the actual box order for the given box order name from settings.
|
||||
const boxOrder = settings.get_strv(this._boxOrder);
|
||||
const boxOrder = this.#settings.get_strv(this._boxOrder);
|
||||
// Populate this GtkListBox with GtkListBoxRows for the items of the
|
||||
// given configured box order.
|
||||
for (const item of boxOrder) {
|
||||
const listBoxRow = new PrefsBoxOrderItemRow({}, item);
|
||||
this.append(listBoxRow);
|
||||
const row = new PrefsBoxOrderItemRow({}, item);
|
||||
this.insertRow(row, -1);
|
||||
}
|
||||
|
||||
this.determineRowMoveActionEnable();
|
||||
this.notify("box-order");
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts the given PrefsBoxOrderItemRow to this list box at the given
|
||||
* position.
|
||||
* Also handles stuff like connecting signals.
|
||||
*/
|
||||
insertRow(row, position) {
|
||||
this.insert(row, position);
|
||||
|
||||
const signalHandlerIds = [];
|
||||
signalHandlerIds.push(row.connect("move", (row, direction) => {
|
||||
this.emit("row-move", row, direction);
|
||||
}));
|
||||
|
||||
this.#rowSignalHandlerIds.set(row, signalHandlerIds);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the given PrefsBoxOrderItemRow from this list box.
|
||||
* Also handles stuff like disconnecting signals.
|
||||
*/
|
||||
removeRow(row) {
|
||||
const signalHandlerIds = this.#rowSignalHandlerIds.get(row);
|
||||
|
||||
for (const id of signalHandlerIds) {
|
||||
row.disconnect(id);
|
||||
}
|
||||
|
||||
this.remove(row);
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves the box order represented by `this` (and its
|
||||
* `PrefsBoxOrderItemRows`) to settings.
|
||||
@ -77,6 +111,38 @@ const PrefsBoxOrderListBox = GObject.registerClass({
|
||||
}
|
||||
this.#settings.set_strv(this.boxOrder, currentBoxOrder);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether or not each move action of each PrefsBoxOrderItemRow
|
||||
* should be enabled or disabled.
|
||||
*/
|
||||
determineRowMoveActionEnable() {
|
||||
for (let potentialPrefsBoxOrderItemRow of this) {
|
||||
// Only process PrefsBoxOrderItemRows.
|
||||
if (potentialPrefsBoxOrderItemRow.constructor.$gtype.name !== "PrefsBoxOrderItemRow") {
|
||||
continue;
|
||||
}
|
||||
|
||||
const row = potentialPrefsBoxOrderItemRow;
|
||||
|
||||
// If the current row is the topmost row in the topmost list box,
|
||||
// then disable the move-up action.
|
||||
if (row.get_index() === 0 && this.boxOrder === "left-box-order") {
|
||||
row.action_set_enabled("row.move-up", false);
|
||||
} else { // Else enable it.
|
||||
row.action_set_enabled("row.move-up", true);
|
||||
}
|
||||
|
||||
// If the current row is the bottommost row in the bottommost list
|
||||
// box, then disable the move-down action.
|
||||
const rowNextSibling = row.get_next_sibling();
|
||||
if ((rowNextSibling instanceof PrefsBoxOrderListEmptyPlaceholder || rowNextSibling === null) && this.boxOrder === "right-box-order") {
|
||||
row.action_set_enabled("row.move-down", false);
|
||||
} else { // Else enable it.
|
||||
row.action_set_enabled("row.move-down", true);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
export default PrefsBoxOrderListBox;
|
||||
|
||||
@ -16,14 +16,17 @@ const PrefsBoxOrderListEmptyPlaceholder = GObject.registerClass({
|
||||
const valueListBox = value.get_parent();
|
||||
|
||||
// Remove the drop value from its list box.
|
||||
valueListBox.remove(value);
|
||||
valueListBox.removeRow(value);
|
||||
|
||||
// Insert the drop value into the list box of `this`.
|
||||
ownListBox.insert(value, 0);
|
||||
ownListBox.insertRow(value, 0);
|
||||
|
||||
/// Finally save the box orders to settings.
|
||||
/// Finally save the box orders to settings and make sure move actions
|
||||
/// are correctly enabled/disabled.
|
||||
ownListBox.saveBoxOrderToSettings();
|
||||
ownListBox.determineRowMoveActionEnable();
|
||||
valueListBox.saveBoxOrderToSettings();
|
||||
valueListBox.determineRowMoveActionEnable();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@ -6,13 +6,19 @@ import Adw from "gi://Adw";
|
||||
import GLib from "gi://GLib";
|
||||
|
||||
import ScrollManager from "./ScrollManager.js";
|
||||
import PrefsBoxOrderListEmptyPlaceholder from "./PrefsBoxOrderListEmptyPlaceholder.js";
|
||||
|
||||
// Imports to make UI file work.
|
||||
import PrefsBoxOrderListBox from "./PrefsBoxOrderListBox.js";
|
||||
|
||||
const PrefsPage = GObject.registerClass({
|
||||
GTypeName: "PrefsPage",
|
||||
Template: GLib.uri_resolve_relative(import.meta.url, "../ui/prefs-page.ui", GLib.UriFlags.NONE)
|
||||
Template: GLib.uri_resolve_relative(import.meta.url, "../ui/prefs-page.ui", GLib.UriFlags.NONE),
|
||||
InternalChildren: [
|
||||
"left-box-order-list-box",
|
||||
"center-box-order-list-box",
|
||||
"right-box-order-list-box"
|
||||
]
|
||||
}, class PrefsPage extends Adw.PreferencesPage {
|
||||
constructor(params = {}) {
|
||||
super(params);
|
||||
@ -81,6 +87,91 @@ const PrefsPage = GObject.registerClass({
|
||||
|
||||
this.add_controller(controller);
|
||||
}
|
||||
|
||||
onRowMove(listBox, row, direction) {
|
||||
const rowPosition = row.get_index();
|
||||
|
||||
if (direction === "up") { // If the direction of the move is up.
|
||||
// Handle the case, where the row is the topmost row in the list box.
|
||||
if (rowPosition === 0) {
|
||||
switch (listBox.boxOrder) {
|
||||
// If the row is also in the topmost list box, then do
|
||||
// nothing and return.
|
||||
case "left-box-order":
|
||||
log("The row is already the topmost row in the topmost box order.");
|
||||
return;
|
||||
// If the row is in the center list box, then move it up to
|
||||
// the left one.
|
||||
case "center-box-order":
|
||||
listBox.removeRow(row);
|
||||
this._left_box_order_list_box.insertRow(row, -1);
|
||||
// First save the box order of the destination, then do
|
||||
// "a save for clean up".
|
||||
this._left_box_order_list_box.saveBoxOrderToSettings();
|
||||
this._left_box_order_list_box.determineRowMoveActionEnable();
|
||||
listBox.saveBoxOrderToSettings();
|
||||
listBox.determineRowMoveActionEnable();
|
||||
return;
|
||||
// If the row is in the right list box, then move it up to
|
||||
// the center one.
|
||||
case "right-box-order":
|
||||
listBox.removeRow(row);
|
||||
this._center_box_order_list_box.insertRow(row, -1);
|
||||
this._center_box_order_list_box.saveBoxOrderToSettings();
|
||||
this._center_box_order_list_box.determineRowMoveActionEnable();
|
||||
listBox.saveBoxOrderToSettings();
|
||||
listBox.determineRowMoveActionEnable();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Else just move the row up in the box.
|
||||
listBox.removeRow(row);
|
||||
listBox.insertRow(row, rowPosition - 1);
|
||||
listBox.saveBoxOrderToSettings();
|
||||
listBox.determineRowMoveActionEnable();
|
||||
return;
|
||||
} else { // Else the direction of the move must be down.
|
||||
// Handle the case, where the row is the bottommost row in the list box.
|
||||
const rowNextSibling = row.get_next_sibling();
|
||||
if (rowNextSibling instanceof PrefsBoxOrderListEmptyPlaceholder || rowNextSibling === null) {
|
||||
switch (listBox.boxOrder) {
|
||||
// If the row is also in the bottommost list box, then do
|
||||
// nothing and return.
|
||||
case "right-box-order":
|
||||
log("The row is already the bottommost row in the bottommost box order.");
|
||||
return;
|
||||
// If the row is in the center list box, then move it down
|
||||
// to the right one.
|
||||
case "center-box-order":
|
||||
listBox.removeRow(row);
|
||||
this._right_box_order_list_box.insertRow(row, 0);
|
||||
this._right_box_order_list_box.saveBoxOrderToSettings();
|
||||
this._right_box_order_list_box.determineRowMoveActionEnable();
|
||||
listBox.saveBoxOrderToSettings();
|
||||
listBox.determineRowMoveActionEnable();
|
||||
return;
|
||||
// If the row is in the left list box, then move it down to
|
||||
// the center one.
|
||||
case "left-box-order":
|
||||
listBox.removeRow(row);
|
||||
this._center_box_order_list_box.insertRow(row, 0);
|
||||
this._center_box_order_list_box.saveBoxOrderToSettings();
|
||||
this._center_box_order_list_box.determineRowMoveActionEnable();
|
||||
listBox.saveBoxOrderToSettings();
|
||||
listBox.determineRowMoveActionEnable();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Else just move the row down in the box.
|
||||
listBox.removeRow(row);
|
||||
listBox.insertRow(row, rowPosition + 1);
|
||||
listBox.saveBoxOrderToSettings();
|
||||
listBox.determineRowMoveActionEnable();
|
||||
return;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
export default PrefsPage;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user