Skip to content

Commit

Permalink
fix(prefs): dnd-center-layout dropdown
Browse files Browse the repository at this point in the history
It's not clear why the type information isn't gathered from the
schema, but since it's not, we can pass a type hint to the
dropdown row constructor
  • Loading branch information
bennypowers authored and jmmaranan committed Sep 18, 2023
1 parent 6b354ba commit 60f8cb6
Show file tree
Hide file tree
Showing 4 changed files with 107 additions and 91 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ build: clean metadata.json schemas compilemsgs metadata
msgfmt -c $< -o $@

debug:
sed -i 's/export const production = true/export const production = false/' temp/settings.js
sed -i 's/export const production = true/export const production = false/' temp/lib/shared/settings.js
sed -i 's/1.0-alpha/3999/' temp/metadata.json
sed -i 's/1.1-alpha/4999/' temp/metadata.json

Expand Down
1 change: 1 addition & 0 deletions lib/prefs/settings.js
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ export class SettingsPage extends PreferencesPage {
new DropDownRow({
title: _("Default Drag-and-Drop Center Layout"),
settings,
type: 's',
bind: "dnd-center-layout",
items: [
{ id: "tabbed", name: _("Tabbed") },
Expand Down
191 changes: 101 additions & 90 deletions lib/prefs/widgets.js
Original file line number Diff line number Diff line change
Expand Up @@ -106,98 +106,108 @@ export class DropDownRow extends Adw.ActionRow {
GObject.registerClass(this);
}

constructor({ title, settings, bind, items, subtitle = "" }) {
/**
* @type {string}
* Name of the gsetting key to bind to
*/
bind;

/**
* @type {'b'|'y'|'n'|'q'|'i'|'u'|'x'|'t'|'h'|'d'|'s'|'o'|'g'|'?'|'a'|'m'}
* - b: the type string of G_VARIANT_TYPE_BOOLEAN; a boolean value.
* - y: the type string of G_VARIANT_TYPE_BYTE; a byte.
* - n: the type string of G_VARIANT_TYPE_INT16; a signed 16 bit integer.
* - q: the type string of G_VARIANT_TYPE_UINT16; an unsigned 16 bit integer.
* - i: the type string of G_VARIANT_TYPE_INT32; a signed 32 bit integer.
* - u: the type string of G_VARIANT_TYPE_UINT32; an unsigned 32 bit integer.
* - x: the type string of G_VARIANT_TYPE_INT64; a signed 64 bit integer.
* - t: the type string of G_VARIANT_TYPE_UINT64; an unsigned 64 bit integer.
* - h: the type string of G_VARIANT_TYPE_HANDLE; a signed 32 bit value that, by convention, is used as an index into an array of file descriptors that are sent alongside a D-Bus message.
* - d: the type string of G_VARIANT_TYPE_DOUBLE; a double precision floating point value.
* - s: the type string of G_VARIANT_TYPE_STRING; a string.
* - o: the type string of G_VARIANT_TYPE_OBJECT_PATH; a string in the form of a D-Bus object path.
* - g: the type string of G_VARIANT_TYPE_SIGNATURE; a string in the form of a D-Bus type signature.
* - ?: the type string of G_VARIANT_TYPE_BASIC; an indefinite type that is a supertype of any of the basic types.
* - v: the type string of G_VARIANT_TYPE_VARIANT; a container type that contain any other type of value.
* - a: used as a prefix on another type string to mean an array of that type; the type string “ai”, for example, is the type of an array of signed 32-bit integers.
* - m: used as a prefix on another type string to mean a “maybe”, or “nullable”, version of that type; the type string “ms”, for example, is the type of a value that maybe contains a string, or maybe contains nothing.
*/
type;

selected = 0;

/** @type {{name: string; id: string}[]} */
items;

model = new Gtk.StringList();

/** @type {Gtk.DropDown} */
dropdown;

constructor({ title, settings, bind, items, subtitle = "", type }) {
super({ title, subtitle });
const model = new Gtk.StringList();
const type = settings.get_value(bind)?.get_type() ?? "?";
/**
* - b: the type string of G_VARIANT_TYPE_BOOLEAN; a boolean value.
* - y: the type string of G_VARIANT_TYPE_BYTE; a byte.
* - n: the type string of G_VARIANT_TYPE_INT16; a signed 16 bit integer.
* - q: the type string of G_VARIANT_TYPE_UINT16; an unsigned 16 bit integer.
* - i: the type string of G_VARIANT_TYPE_INT32; a signed 32 bit integer.
* - u: the type string of G_VARIANT_TYPE_UINT32; an unsigned 32 bit integer.
* - x: the type string of G_VARIANT_TYPE_INT64; a signed 64 bit integer.
* - t: the type string of G_VARIANT_TYPE_UINT64; an unsigned 64 bit integer.
* - h: the type string of G_VARIANT_TYPE_HANDLE; a signed 32 bit value that, by convention, is used as an index into an array of file descriptors that are sent alongside a D-Bus message.
* - d: the type string of G_VARIANT_TYPE_DOUBLE; a double precision floating point value.
* - s: the type string of G_VARIANT_TYPE_STRING; a string.
* - o: the type string of G_VARIANT_TYPE_OBJECT_PATH; a string in the form of a D-Bus object path.
* - g: the type string of G_VARIANT_TYPE_SIGNATURE; a string in the form of a D-Bus type signature.
* - ?: the type string of G_VARIANT_TYPE_BASIC; an indefinite type that is a supertype of any of the basic types.
* - v: the type string of G_VARIANT_TYPE_VARIANT; a container type that contain any other type of value.
* - a: used as a prefix on another type string to mean an array of that type; the type string “ai”, for example, is the type of an array of signed 32-bit integers.
* - m: used as a prefix on another type string to mean a “maybe”, or “nullable”, version of that type; the type string “ms”, for example, is the type of a value that maybe contains a string, or maybe contains nothing.
*/
const get = (x) => {
switch (type) {
case "b":
return settings.get_boolean(x);
case "y":
return settings.get_byte(x);
case "n":
return settings.get_int16(x);
case "q":
return settings.get_uint16(x);
case "i":
return settings.get_int32(x);
case "u":
return settings.get_uint(x);
case "x":
return settings.get_int64(x);
case "t":
return settings.get_uint64(x);
case "d":
return settings.get_double(x);
case "s":
return settings.get_string(x);
case "o":
return settings.get_objv(x);
}
};

const set = (x, y) => {
switch (type) {
case "b":
return settings.set_boolean(x, y);
case "y":
return settings.set_byte(x, y);
case "n":
return settings.set_int16(x, y);
case "q":
return settings.set_uint16(x, y);
case "i":
return settings.set_int32(x, y);
case "u":
return settings.set_uint(x, y);
case "x":
return settings.set_int64(x, y);
case "t":
return settings.set_uint64(x, y);
case "d":
return settings.set_double(x, y);
case "s":
return settings.set_string(x, y);
case "o":
return settings.set_objv(x, y);
}
};

let selected = 0;
for (const { name, id } of items) {
model.append(name);
if (get() === id) selected = items.findIndex((x) => x.id === id);
this.settings = settings;
this.items = items;
this.bind = bind;
this.type = type ?? this.settings.get_value(bind)?.get_type() ?? "?";
this.#build();
this.add_suffix(this.dropdown);
this.add_suffix(new ResetButton({ settings, bind, onReset: () => this.reset() }));
}

reset() {
this.dropdown.selected = 0;
this.selected = 0;
}

#build() {
for (const { name, id } of this.items) {
this.model.append(name);
if (this.#get() === id) this.selected = this.items.findIndex((x) => x.id === id);
}
const glist = new Gtk.DropDown({ valign: Gtk.Align.CENTER, model, selected });
glist.connect("notify::selected", (dropdown) => {
Logger.debug(Logger.format(dropdown.selected, glist.get_selected()));
const { id } = items[glist.get_selected()];
Logger.debug(id);
set(bind, id);
});
this.add_suffix(glist);
this.activatable_widget = glist;
this.add_suffix(new ResetButton({ settings, bind, onReset: () => (glist.selected = 0) }));
const { model, selected } = this;
this.dropdown = new Gtk.DropDown({ valign: Gtk.Align.CENTER, model, selected });
this.dropdown.connect("notify::selected", () => this.#onSelected());
this.activatable_widget = this.dropdown;
}

#onSelected() {
this.selected = this.dropdown.selected;
const { id } = this.items[this.selected];
Logger.debug('setting', id, this.selected);
this.#set(this.bind, id);
}

static #settingsTypes = {
b: "boolean",
y: "byte",
n: "int16",
q: "uint16",
i: "int32",
u: "uint",
x: "int64",
t: "uint64",
d: "double",
s: "string",
o: "objv",
};

/**
* @param {string} x
*/
#get(x = this.bind) {
const methodName = `get_${DropDownRow.#settingsTypes[this.type] ?? "value"}`;
return this.settings[methodName]?.(x);
}

/**
* @param {string} x
* @param {unknown} y
*/
#set(x, y) {
const methodName = `set_${DropDownRow.#settingsTypes[this.type] ?? "value"}`;
Logger.log(`${methodName}(${x}, ${y})`);
return this.settings[methodName]?.(x, y);
}
}

Expand Down Expand Up @@ -281,3 +291,4 @@ export class RadioRow extends Adw.ActionRow {
this.add_suffix(hbox);
}
}

4 changes: 4 additions & 0 deletions lib/shared/logger.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,4 +70,8 @@ export class Logger {
static trace(...args) {
if (!this.#level > Logger.LOG_LEVELS.DEBUG) console.debug(`[Forge] [TRACE]`, ...args);
}

static log(...args) {
if (!this.#level > Logger.LOG_LEVELS.OFF) console.log(`[Forge] [LOG]`, ...args);
}
}

0 comments on commit 60f8cb6

Please sign in to comment.