From 797df4f52f569eb76e469502e76516051703db80 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=BCllner?= Date: Mon, 10 Jul 2023 05:53:45 +0200 Subject: [PATCH] extensions: Make ExtensionPreferences more flexible Extensions must now export a class with a fillPreferencesWindow() method in their prefs. That is less convenient for extensions with simple preferences than the old buildPrefsWidget() hook, as they must wrap their widget in page/group widgets. Address this by adding a default fillPreferencesWindow() implementation that calls a getPreferencesWidget() method and wraps it as necessary. This is flexible enough to support different cases fairly conveniently, from simple single-widget prefs over tweaking the window to complex multi-page prefs: ```js class SimplePreferences extends ExtensionPreferences { getPreferencesWidget() { return new SimplePrefsWidget(); } } class TinkerPreferences extends ExtensionPreferences { getPreferencesWidget() { return new SimplePrefsWidget(); } fillPreferencesWindow(window) { super.fillPreferencesWindow(window); window.set_default_size(123, 456); } } class FullPreferences extends ExtensionPreferences { fillPreferencesWindow(window) { const page1 = new GeneralPage(); window.add(page1); const page2 = new FoobarPage(); window.add(page2); } } ``` Part-of: --- js/extensions/prefs.js | 39 ++++++++++++++++++++++++++++++++++++--- 1 file changed, 36 insertions(+), 3 deletions(-) diff --git a/js/extensions/prefs.js b/js/extensions/prefs.js index d60859a3d..f36b97138 100644 --- a/js/extensions/prefs.js +++ b/js/extensions/prefs.js @@ -1,3 +1,4 @@ +import Adw from 'gi://Adw'; import GObject from 'gi://GObject'; import {ExtensionBase, GettextWrapper} from './sharedInternals.js'; @@ -13,13 +14,45 @@ export class ExtensionPreferences extends ExtensionBase { return wrapper.defineTranslationFunctions(); } + /** + * Get the single widget that implements + * the extension's preferences. + * + * @returns {Gtk.Widget} + */ + getPreferencesWidget() { + throw new GObject.NotImplementedError(); + } + /** * Fill the preferences window with preferences. * - * @param {Adw.PreferencesWindow} _window - the preferences window + * The default implementation adds the widget + * returned by getPreferencesWidget(). + * + * @param {Adw.PreferencesWindow} window - the preferences window */ - fillPreferencesWindow(_window) { - throw new GObject.NotImplementedError(); + fillPreferencesWindow(window) { + const widget = this.getPreferencesWidget(); + const page = this._wrapWidget(widget); + window.add(page); + } + + _wrapWidget(widget) { + if (widget instanceof Adw.PreferencesPage) + return widget; + + const page = new Adw.PreferencesPage(); + if (widget instanceof Adw.PreferencesGroup) { + page.add(widget); + return page; + } + + const group = new Adw.PreferencesGroup(); + group.add(widget); + page.add(group); + + return page; } }