mirror of
https://gitlab.gnome.org/julianschacher/top-bar-organizer.git
synced 2025-10-27 07:09:07 +00:00
Add settings UI for controlling how the extension should affect a top bar items visibility (whether to try to forcefully hide or show an item or not affect its visibility at all).
162 lines
6.9 KiB
TypeScript
162 lines
6.9 KiB
TypeScript
"use strict";
|
|
|
|
import Gtk from "gi://Gtk";
|
|
import Gdk from "gi://Gdk";
|
|
import GObject from "gi://GObject";
|
|
import Adw from "gi://Adw";
|
|
import GLib from "gi://GLib";
|
|
|
|
import PrefsBoxOrderItemOptionsDialog from "./PrefsBoxOrderItemOptionsDialog.js";
|
|
import type PrefsBoxOrderListBox from "./PrefsBoxOrderListBox.js";
|
|
|
|
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),
|
|
Signals: {
|
|
"move": {
|
|
param_types: [GObject.TYPE_STRING],
|
|
},
|
|
},
|
|
}, this);
|
|
this.install_action("row.forget", null, (self, _actionName, _param) => {
|
|
const parentListBox = self.get_parent() as PrefsBoxOrderListBox;
|
|
parentListBox.removeRow(self as PrefsBoxOrderItemRow);
|
|
parentListBox.saveBoxOrderToSettings();
|
|
parentListBox.determineRowMoveActionEnable();
|
|
});
|
|
this.install_action("row.options", null, (self, _actionName, _param) => {
|
|
const itemOptionsDialog = new PrefsBoxOrderItemOptionsDialog({
|
|
// Get the title from self as the constructor of
|
|
// PrefsBoxOrderItemRow already processes the item name into a
|
|
// nice title.
|
|
title: (self as PrefsBoxOrderItemRow).get_title()
|
|
}, (self as PrefsBoxOrderItemRow).item);
|
|
itemOptionsDialog.present(self);
|
|
});
|
|
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"));
|
|
}
|
|
|
|
item: string;
|
|
#drag_starting_point_x?: number;
|
|
#drag_starting_point_y?: number;
|
|
|
|
constructor(params = {}, item: string) {
|
|
super(params);
|
|
|
|
// Associate `this` with an item.
|
|
this.item = item;
|
|
if (this.item.startsWith("appindicator-kstatusnotifieritem-")) {
|
|
// Set the title to something nicer, if the associated item is an
|
|
// AppIndicator/KStatusNotifierItem item.
|
|
this.set_title(this.item.replace("appindicator-kstatusnotifieritem-", ""));
|
|
} else if (this.item === "item-role-group-task-up-ultralite") {
|
|
// Set the title to something nicer, if the item in question is the
|
|
// Task Up UltraLite item role group.
|
|
this.set_title("Task Up UltraLite Items");
|
|
} else {
|
|
// Otherwise just set it to `item`.
|
|
this.set_title(this.item);
|
|
}
|
|
}
|
|
|
|
onDragPrepare(_source: Gtk.DragSource, x: number, y: number): Gdk.ContentProvider {
|
|
const value = new GObject.Value();
|
|
value.init(PrefsBoxOrderItemRow.$gtype);
|
|
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: Gtk.DragSource, drag: Gdk.Drag): void {
|
|
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);
|
|
// Even tho this should always be the case, ensure the values for the hotspot aren't undefined.
|
|
if (typeof this.#drag_starting_point_x !== "undefined" &&
|
|
typeof this.#drag_starting_point_y !== "undefined") {
|
|
drag.set_hotspot(this.#drag_starting_point_x, this.#drag_starting_point_y);
|
|
}
|
|
}
|
|
|
|
// Handle a new drop on `this` properly.
|
|
// `value` is the thing getting dropped.
|
|
onDrop(_target: Gtk.DropTarget, value: any, _x: number, _y: number): boolean {
|
|
// According to the type annotations of Gtk.DropTarget, value is of type
|
|
// GObject.Value, so ensure the one we work with is of type
|
|
// PrefsBoxOrderItemRow.
|
|
if (!(value instanceof PrefsBoxOrderItemRow)) {
|
|
// TODO: maybe add logging
|
|
return false;
|
|
}
|
|
|
|
// If `this` got dropped onto itself, do nothing.
|
|
if (value === this) {
|
|
return false;
|
|
}
|
|
|
|
// Get the GtkListBoxes of `this` and the drop value.
|
|
const ownListBox = this.get_parent() as PrefsBoxOrderListBox;
|
|
const valueListBox = value.get_parent() as PrefsBoxOrderListBox;
|
|
|
|
// 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.removeRow(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.insertRow(value, updatedOwnPosition + 1);
|
|
} else {
|
|
// Otherwise, add the drop value where `this` currently is.
|
|
ownListBox.insertRow(value, updatedOwnPosition);
|
|
}
|
|
} else {
|
|
if (valuePosition < ownPosition) {
|
|
// If the drop value was before `this`, add the drop value
|
|
// after `this`.
|
|
ownListBox.insertRow(value, updatedOwnPosition + 1);
|
|
} else {
|
|
// Otherwise, add the drop value where `this` currently is.
|
|
ownListBox.insertRow(value, updatedOwnPosition);
|
|
}
|
|
}
|
|
|
|
/// Finally save the box order(/s) to settings and make sure move
|
|
/// actions are correctly enabled/disabled.
|
|
ownListBox.saveBoxOrderToSettings();
|
|
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();
|
|
}
|
|
|
|
return true;
|
|
}
|
|
}
|