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>
|
</child>
|
||||||
</template>
|
</template>
|
||||||
<menu id="optionsMenuModel">
|
<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>
|
<section>
|
||||||
<item>
|
<item>
|
||||||
<attribute name="label">Forget</attribute>
|
<attribute name="label">Forget</attribute>
|
||||||
|
|||||||
@ -13,8 +13,9 @@
|
|||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="PrefsBoxOrderListBox">
|
<object class="PrefsBoxOrderListBox" id="left-box-order-list-box">
|
||||||
<property name="box-order">left-box-order</property>
|
<property name="box-order">left-box-order</property>
|
||||||
|
<signal name="row-move" handler="onRowMove"/>
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
@ -26,8 +27,9 @@
|
|||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="PrefsBoxOrderListBox">
|
<object class="PrefsBoxOrderListBox" id="center-box-order-list-box">
|
||||||
<property name="box-order">center-box-order</property>
|
<property name="box-order">center-box-order</property>
|
||||||
|
<signal name="row-move" handler="onRowMove"/>
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
@ -39,8 +41,9 @@
|
|||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="PrefsBoxOrderListBox">
|
<object class="PrefsBoxOrderListBox" id="right-box-order-list-box">
|
||||||
<property name="box-order">right-box-order</property>
|
<property name="box-order">right-box-order</property>
|
||||||
|
<signal name="row-move" handler="onRowMove"/>
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
</object>
|
</object>
|
||||||
|
|||||||
@ -7,13 +7,24 @@ import GObject from "gi://GObject";
|
|||||||
import Adw from "gi://Adw";
|
import Adw from "gi://Adw";
|
||||||
import GLib from "gi://GLib";
|
import GLib from "gi://GLib";
|
||||||
|
|
||||||
const PrefsBoxOrderItemRow = GObject.registerClass({
|
export default class PrefsBoxOrderItemRow extends Adw.ActionRow {
|
||||||
GTypeName: "PrefsBoxOrderItemRow",
|
static {
|
||||||
Template: GLib.uri_resolve_relative(import.meta.url, "../ui/prefs-box-order-item-row.ui", GLib.UriFlags.NONE),
|
GObject.registerClass({
|
||||||
InternalChildren: [
|
GTypeName: "PrefsBoxOrderItemRow",
|
||||||
"item-name-display-label"
|
Template: GLib.uri_resolve_relative(import.meta.url, "../ui/prefs-box-order-item-row.ui", GLib.UriFlags.NONE),
|
||||||
]
|
InternalChildren: [
|
||||||
}, class PrefsBoxOrderItemRow extends Adw.ActionRow {
|
"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_x;
|
||||||
#drag_starting_point_y;
|
#drag_starting_point_y;
|
||||||
|
|
||||||
@ -52,8 +63,9 @@ const PrefsBoxOrderItemRow = GObject.registerClass({
|
|||||||
});
|
});
|
||||||
forgetAction.connect("activate", (_action, _params) => {
|
forgetAction.connect("activate", (_action, _params) => {
|
||||||
const parentListBox = this.get_parent();
|
const parentListBox = this.get_parent();
|
||||||
parentListBox.remove(this);
|
parentListBox.removeRow(this);
|
||||||
parentListBox.saveBoxOrderToSettings();
|
parentListBox.saveBoxOrderToSettings();
|
||||||
|
parentListBox.determineRowMoveActionEnable();
|
||||||
});
|
});
|
||||||
actionGroup.add_action(forgetAction);
|
actionGroup.add_action(forgetAction);
|
||||||
|
|
||||||
@ -101,7 +113,7 @@ const PrefsBoxOrderItemRow = GObject.registerClass({
|
|||||||
const valuePosition = value.get_index();
|
const valuePosition = value.get_index();
|
||||||
|
|
||||||
// Remove the drop value from its list box.
|
// 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`,
|
// Since an element got potentially removed from the list of `this`,
|
||||||
// get the position of `this` again.
|
// get the position of `this` again.
|
||||||
@ -115,31 +127,31 @@ const PrefsBoxOrderItemRow = GObject.registerClass({
|
|||||||
|| (ownListBox.boxOrder === "center-box-order" && valueListBox.boxOrder === "left-box-order")) {
|
|| (ownListBox.boxOrder === "center-box-order" && valueListBox.boxOrder === "left-box-order")) {
|
||||||
// If the list box of the drop value comes before the list
|
// If the list box of the drop value comes before the list
|
||||||
// box of `this`, add the drop value after `this`.
|
// box of `this`, add the drop value after `this`.
|
||||||
ownListBox.insert(value, updatedOwnPosition + 1);
|
ownListBox.insertRow(value, updatedOwnPosition + 1);
|
||||||
} else {
|
} else {
|
||||||
// Otherwise, add the drop value where `this` currently is.
|
// Otherwise, add the drop value where `this` currently is.
|
||||||
ownListBox.insert(value, updatedOwnPosition);
|
ownListBox.insertRow(value, updatedOwnPosition);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (valuePosition < ownPosition) {
|
if (valuePosition < ownPosition) {
|
||||||
// If the drop value was before `this`, add the drop value
|
// If the drop value was before `this`, add the drop value
|
||||||
// after `this`.
|
// after `this`.
|
||||||
ownListBox.insert(value, updatedOwnPosition + 1);
|
ownListBox.insertRow(value, updatedOwnPosition + 1);
|
||||||
} else {
|
} else {
|
||||||
// Otherwise, add the drop value where `this` currently is.
|
// 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();
|
ownListBox.saveBoxOrderToSettings();
|
||||||
// If the list boxes of `this` and the drop value were different,
|
ownListBox.determineRowMoveActionEnable();
|
||||||
// save an updated box order for the list were the drop value was in
|
// If the list boxes of `this` and the drop value were different, handle
|
||||||
// as well.
|
// the former list box of the drop value as well.
|
||||||
if (ownListBox !== valueListBox) {
|
if (ownListBox !== valueListBox) {
|
||||||
valueListBox.saveBoxOrderToSettings();
|
valueListBox.saveBoxOrderToSettings();
|
||||||
|
valueListBox.determineRowMoveActionEnable();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
|
||||||
export default PrefsBoxOrderItemRow;
|
|
||||||
|
|||||||
@ -17,12 +17,18 @@ const PrefsBoxOrderListBox = GObject.registerClass({
|
|||||||
"box-order",
|
"box-order",
|
||||||
"Box Order",
|
"Box Order",
|
||||||
"The box order this PrefsBoxOrderListBox is associated with.",
|
"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 {
|
}, class PrefsBoxOrderListBox extends Gtk.ListBox {
|
||||||
#settings;
|
#settings;
|
||||||
|
#rowSignalHandlerIds = new Map();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {Object} params
|
* @param {Object} params
|
||||||
@ -45,21 +51,49 @@ const PrefsBoxOrderListBox = GObject.registerClass({
|
|||||||
set boxOrder(value) {
|
set boxOrder(value) {
|
||||||
this._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.
|
// 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
|
// Populate this GtkListBox with GtkListBoxRows for the items of the
|
||||||
// given configured box order.
|
// given configured box order.
|
||||||
for (const item of boxOrder) {
|
for (const item of boxOrder) {
|
||||||
const listBoxRow = new PrefsBoxOrderItemRow({}, item);
|
const row = new PrefsBoxOrderItemRow({}, item);
|
||||||
this.append(listBoxRow);
|
this.insertRow(row, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.determineRowMoveActionEnable();
|
||||||
this.notify("box-order");
|
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
|
* Saves the box order represented by `this` (and its
|
||||||
* `PrefsBoxOrderItemRows`) to settings.
|
* `PrefsBoxOrderItemRows`) to settings.
|
||||||
@ -77,6 +111,38 @@ const PrefsBoxOrderListBox = GObject.registerClass({
|
|||||||
}
|
}
|
||||||
this.#settings.set_strv(this.boxOrder, currentBoxOrder);
|
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;
|
export default PrefsBoxOrderListBox;
|
||||||
|
|||||||
@ -16,14 +16,17 @@ const PrefsBoxOrderListEmptyPlaceholder = GObject.registerClass({
|
|||||||
const valueListBox = value.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.removeRow(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.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.saveBoxOrderToSettings();
|
||||||
|
ownListBox.determineRowMoveActionEnable();
|
||||||
valueListBox.saveBoxOrderToSettings();
|
valueListBox.saveBoxOrderToSettings();
|
||||||
|
valueListBox.determineRowMoveActionEnable();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -6,13 +6,19 @@ import Adw from "gi://Adw";
|
|||||||
import GLib from "gi://GLib";
|
import GLib from "gi://GLib";
|
||||||
|
|
||||||
import ScrollManager from "./ScrollManager.js";
|
import ScrollManager from "./ScrollManager.js";
|
||||||
|
import PrefsBoxOrderListEmptyPlaceholder from "./PrefsBoxOrderListEmptyPlaceholder.js";
|
||||||
|
|
||||||
// Imports to make UI file work.
|
// Imports to make UI file work.
|
||||||
import PrefsBoxOrderListBox from "./PrefsBoxOrderListBox.js";
|
import PrefsBoxOrderListBox from "./PrefsBoxOrderListBox.js";
|
||||||
|
|
||||||
const PrefsPage = GObject.registerClass({
|
const PrefsPage = GObject.registerClass({
|
||||||
GTypeName: "PrefsPage",
|
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 {
|
}, class PrefsPage extends Adw.PreferencesPage {
|
||||||
constructor(params = {}) {
|
constructor(params = {}) {
|
||||||
super(params);
|
super(params);
|
||||||
@ -81,6 +87,91 @@ const PrefsPage = GObject.registerClass({
|
|||||||
|
|
||||||
this.add_controller(controller);
|
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;
|
export default PrefsPage;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user