From b726064e653b0a4854cdb9ecbe1e7e97b850d7f6 Mon Sep 17 00:00:00 2001 From: Simon Schneegans Date: Sun, 9 Jan 2022 13:49:03 +0100 Subject: [PATCH] :wrench: Make effect classes static --- prefs.js | 111 ++++++++++++++++++++++++++++++++++---- src/prefs/FirePage.js | 66 +++++++++++------------ src/prefs/GeneralPage.js | 43 --------------- src/prefs/MatrixPage.js | 24 ++++----- src/prefs/PrefsPage.js | 102 ----------------------------------- src/prefs/TRexPage.js | 25 ++++----- src/prefs/TVEffectPage.js | 19 +++---- 7 files changed, 160 insertions(+), 230 deletions(-) delete mode 100644 src/prefs/GeneralPage.js delete mode 100644 src/prefs/PrefsPage.js diff --git a/prefs.js b/prefs.js index e002708..7b28134 100644 --- a/prefs.js +++ b/prefs.js @@ -23,7 +23,6 @@ const FirePage = Me.imports.src.prefs.FirePage.FirePage; const MatrixPage = Me.imports.src.prefs.MatrixPage.MatrixPage; const TVEffectPage = Me.imports.src.prefs.TVEffectPage.TVEffectPage; const TRexPage = Me.imports.src.prefs.TRexPage.TRexPage; -const GeneralPage = Me.imports.src.prefs.GeneralPage.GeneralPage; ////////////////////////////////////////////////////////////////////////////////////////// // For now, the preferences dialog of this extension is very simple. In the future, if // @@ -48,14 +47,20 @@ var PreferencesDialog = class PreferencesDialog { this._builder = new Gtk.Builder(); this._builder.add_from_resource(`/ui/common/main-menu.ui`); this._builder.add_from_resource(`/ui/${utils.isGTK4() ? 'gtk4' : 'gtk3'}/prefs.ui`); + this._builder.add_from_resource( + `/ui/${utils.isGTK4() ? 'gtk4' : 'gtk3'}/generalPage.ui`); - this._generalPAge = new GeneralPage(this._settings, this._builder); + // Bind general options properties. + this.bindSwitch('destroy-dialogs'); + + const stack = this._builder.get_object('main-stack'); + stack.add_titled( + this._builder.get_object('general-prefs'), 'general', 'General Options'); - this._effects = []; EFFECT_TYPES.forEach(Type => { const [minMajor, minMinor] = Type.getMinShellVersion(); if (utils.shellVersionIsAtLeast(minMajor, minMinor)) { - this._effects.push(new Type(this._settings, this._builder)); + Type.initPreferences(this); } }); @@ -102,15 +107,18 @@ var PreferencesDialog = class PreferencesDialog { const menu = this._builder.get_object('close-effect-menu'); - this._effects.forEach(effect => { - const prefix = effect.constructor.getSettingsPrefix(); - const label = effect.constructor.getLabel(); + EFFECT_TYPES.forEach(Type => { + const [minMajor, minMinor] = Type.getMinShellVersion(); + if (utils.shellVersionIsAtLeast(minMajor, minMinor)) { + const prefix = Type.getSettingsPrefix(); + const label = Type.getLabel(); - const action = this._settings.create_action(`${prefix}-close-effect`); - group.add_action(action); + const action = this._settings.create_action(`${prefix}-close-effect`); + group.add_action(action); - menu.append_item( - Gio.MenuItem.new(label, `close-effects.${prefix}-close-effect`)); + menu.append_item( + Gio.MenuItem.new(label, `close-effects.${prefix}-close-effect`)); + } }); } }); @@ -130,10 +138,91 @@ var PreferencesDialog = class PreferencesDialog { // -------------------------------------------------------------------- public interface + getBuilder() { + return this._builder; + } + + getSettings() { + return this._settings; + } + // Returns the widget used for the settings of this extension. getWidget() { return this._widget; } + + // Connects a Gtk.ComboBox (or anything else which has an 'active-id' property) to a + // settings key. It also binds the corresponding reset button. + bindCombobox(settingsKey) { + this._bind(settingsKey, 'active-id'); + } + + // Connects a Gtk.Adjustment (or anything else which has a 'value' property) to a + // settings key. It also binds the corresponding reset button. + bindAdjustment(settingsKey) { + this._bind(settingsKey, 'value'); + } + + // Connects a Gtk.Switch (or anything else which has an 'active' property) to a settings + // key. It also binds the corresponding reset button. + bindSwitch(settingsKey) { + this._bind(settingsKey, 'active'); + } + + // Colors are stored as strings like 'rgb(1, 0.5, 0)'. As Gio.Settings.bind_with_mapping + // is not available yet, we need to do the color conversion manually. It also binds the + // corresponding reset button. + bindColorButton(settingsKey) { + + const button = this._builder.get_object(settingsKey); + + if (button) { + + // Update the settings when the color is modified. + button.connect('color-set', () => { + this._settings.set_string(settingsKey, button.get_rgba().to_string()); + }); + + // Update the button state when the settings change. + const settingSignalHandler = () => { + const rgba = new Gdk.RGBA(); + rgba.parse(this._settings.get_string(settingsKey)); + button.rgba = rgba; + }; + + this._settings.connect('changed::' + settingsKey, settingSignalHandler); + + // Initialize the button with the state in the settings. + settingSignalHandler(); + } + + this._bindResetButton(settingsKey); + } + + // ----------------------------------------------------------------------- private stuff + + // Searches for a reset button for the given settings key and make it reset the settings + // key when clicked. + _bindResetButton(settingsKey) { + const resetButton = this._builder.get_object('reset-' + settingsKey); + if (resetButton) { + resetButton.connect('clicked', () => { + this._settings.reset(settingsKey); + }); + } + } + + // Connects any widget's property to a settings key. The widget must have the same ID as + // the settings key. It also binds the corresponding reset button. + _bind(settingsKey, property) { + const object = this._builder.get_object(settingsKey); + + if (object) { + this._settings.bind(settingsKey, object, property, Gio.SettingsBindFlags.DEFAULT); + } + + this._bindResetButton(settingsKey); + } } // Nothing to do for now... diff --git a/src/prefs/FirePage.js b/src/prefs/FirePage.js index 7dcc834..fc8fe64 100644 --- a/src/prefs/FirePage.js +++ b/src/prefs/FirePage.js @@ -18,12 +18,11 @@ const {Gio} = imports.gi; const ExtensionUtils = imports.misc.extensionUtils; const Me = imports.misc.extensionUtils.getCurrentExtension(); const utils = Me.imports.src.common.utils; -const PrefsPage = Me.imports.src.prefs.PrefsPage.PrefsPage; ////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////// -var FirePage = class FirePage extends PrefsPage { +var FirePage = class FirePage { // ---------------------------------------------------------------------- static methods @@ -39,46 +38,43 @@ var FirePage = class FirePage extends PrefsPage { return 'Fire'; } - // ------------------------------------------------------------ constructor / destructor + static initPreferences(dialog) { - constructor(settings, builder) { - super(settings, builder); - - this._builder.add_from_resource( + dialog.getBuilder().add_from_resource( `/ui/${utils.isGTK4() ? 'gtk4' : 'gtk3'}/firePage.ui`); // Bind all properties. - this._bindAdjustment('fire-animation-time'); - this._bindAdjustment('flame-movement-speed'); - this._bindAdjustment('flame-scale'); - this._bindSwitch('flame-3d-noise'); - this._bindColorButton('fire-color-1'); - this._bindColorButton('fire-color-2'); - this._bindColorButton('fire-color-3'); - this._bindColorButton('fire-color-4'); - this._bindColorButton('fire-color-5'); + dialog.bindAdjustment('fire-animation-time'); + dialog.bindAdjustment('flame-movement-speed'); + dialog.bindAdjustment('flame-scale'); + dialog.bindSwitch('flame-3d-noise'); + dialog.bindColorButton('fire-color-1'); + dialog.bindColorButton('fire-color-2'); + dialog.bindColorButton('fire-color-3'); + dialog.bindColorButton('fire-color-4'); + dialog.bindColorButton('fire-color-5'); // The fire-gradient-reset button needs to be bound explicitly. - this._builder.get_object('reset-fire-colors').connect('clicked', () => { - this._settings.reset('fire-color-1'); - this._settings.reset('fire-color-2'); - this._settings.reset('fire-color-3'); - this._settings.reset('fire-color-4'); - this._settings.reset('fire-color-5'); + dialog.getBuilder().get_object('reset-fire-colors').connect('clicked', () => { + dialog.getSettings().reset('fire-color-1'); + dialog.getSettings().reset('fire-color-2'); + dialog.getSettings().reset('fire-color-3'); + dialog.getSettings().reset('fire-color-4'); + dialog.getSettings().reset('fire-color-5'); }); // Initialize the fire-preset dropdown. - this._createFirePresets(); + FirePage._createFirePresets(dialog); - const stack = this._builder.get_object('main-stack'); - stack.add_titled(this._builder.get_object('fire-prefs'), 'fire', 'Fire'); + const stack = dialog.getBuilder().get_object('main-stack'); + stack.add_titled(dialog.getBuilder().get_object('fire-prefs'), 'fire', 'Fire'); } // ----------------------------------------------------------------------- private stuff // This populates the preset dropdown menu for the fire options. - _createFirePresets() { - this._builder.get_object('settings-widget').connect('realize', (widget) => { + static _createFirePresets(dialog) { + dialog.getBuilder().get_object('settings-widget').connect('realize', (widget) => { const presets = [ { name: 'Default Fire', @@ -144,19 +140,19 @@ var FirePage = class FirePage extends PrefsPage { // Load the preset on activation. action.connect('activate', () => { - this._settings.set_double('flame-movement-speed', preset.speed); - this._settings.set_double('flame-scale', preset.scale); - this._settings.set_string('fire-color-1', preset.color1); - this._settings.set_string('fire-color-2', preset.color2); - this._settings.set_string('fire-color-3', preset.color3); - this._settings.set_string('fire-color-4', preset.color4); - this._settings.set_string('fire-color-5', preset.color5); + dialog.getSettings().set_double('flame-movement-speed', preset.speed); + dialog.getSettings().set_double('flame-scale', preset.scale); + dialog.getSettings().set_string('fire-color-1', preset.color1); + dialog.getSettings().set_string('fire-color-2', preset.color2); + dialog.getSettings().set_string('fire-color-3', preset.color3); + dialog.getSettings().set_string('fire-color-4', preset.color4); + dialog.getSettings().set_string('fire-color-5', preset.color5); }); group.add_action(action); }); - this._builder.get_object('fire-preset-button').set_menu_model(menu); + dialog.getBuilder().get_object('fire-preset-button').set_menu_model(menu); const root = utils.isGTK4() ? widget.get_root() : widget.get_toplevel(); root.insert_action_group(groupName, group); diff --git a/src/prefs/GeneralPage.js b/src/prefs/GeneralPage.js deleted file mode 100644 index a58408d..0000000 --- a/src/prefs/GeneralPage.js +++ /dev/null @@ -1,43 +0,0 @@ -////////////////////////////////////////////////////////////////////////////////////////// -// ) ( // -// ( /( ( ( ) ( ( ( ( )\ ) ( ( // -// )\()) ))\ )( ( ( )\ ) )\))( )\ ( (()/( ( )\))( ( // -// ((_)\ /((_|()\ )\ ) )\ '(()/( ((_)()((_) )\ ) ((_)))\((_)()\ )\ // -// | |(_|_))( ((_)_(_/( _((_)) )(_)) _(()((_|_)_(_/( _| |((_)(()((_|(_) // -// | '_ \ || | '_| ' \)) | ' \()| || | \ V V / | ' \)) _` / _ \ V V (_-< // -// |_.__/\_,_|_| |_||_| |_|_|_| \_, | \_/\_/|_|_||_|\__,_\___/\_/\_//__/ // -// |__/ // -// Copyright (c) 2021 Simon Schneegans // -// Released under the GPLv3 or later. See LICENSE file for details. // -////////////////////////////////////////////////////////////////////////////////////////// - -'use strict'; - -const ExtensionUtils = imports.misc.extensionUtils; -const Me = imports.misc.extensionUtils.getCurrentExtension(); -const utils = Me.imports.src.common.utils; -const PrefsPage = Me.imports.src.prefs.PrefsPage.PrefsPage; - -////////////////////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////////////////////// - -var GeneralPage = class GeneralPage extends PrefsPage { - - // ------------------------------------------------------------ constructor / destructor - - constructor(settings, builder) { - super(settings, builder); - - this._builder.add_from_resource( - `/ui/${utils.isGTK4() ? 'gtk4' : 'gtk3'}/generalPage.ui`); - - // Bind all properties. - this._bindSwitch('destroy-dialogs'); - - const stack = this._builder.get_object('main-stack'); - stack.add_titled( - this._builder.get_object('general-prefs'), 'general', 'General Options'); - } - - // ---------------------------------------------------------------------- public methods -} \ No newline at end of file diff --git a/src/prefs/MatrixPage.js b/src/prefs/MatrixPage.js index 4ab405f..d4eb561 100644 --- a/src/prefs/MatrixPage.js +++ b/src/prefs/MatrixPage.js @@ -16,12 +16,11 @@ const ExtensionUtils = imports.misc.extensionUtils; const Me = imports.misc.extensionUtils.getCurrentExtension(); const utils = Me.imports.src.common.utils; -const PrefsPage = Me.imports.src.prefs.PrefsPage.PrefsPage; ////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////// -var MatrixPage = class MatrixPage extends PrefsPage { +var MatrixPage = class MatrixPage { // ---------------------------------------------------------------------- static methods @@ -37,21 +36,18 @@ var MatrixPage = class MatrixPage extends PrefsPage { return 'Matrix'; } - // ------------------------------------------------------------ constructor / destructor + static initPreferences(dialog) { - constructor(settings, builder) { - super(settings, builder); - - this._builder.add_from_resource('/ui/gtk4/matrixPage.ui'); + dialog.getBuilder().add_from_resource('/ui/gtk4/matrixPage.ui'); // Bind all properties. - this._bindAdjustment('matrix-animation-time'); - this._bindAdjustment('matrix-scale'); - this._bindAdjustment('matrix-randomness'); - this._bindColorButton('matrix-trail-color'); - this._bindColorButton('matrix-tip-color'); + dialog.bindAdjustment('matrix-animation-time'); + dialog.bindAdjustment('matrix-scale'); + dialog.bindAdjustment('matrix-randomness'); + dialog.bindColorButton('matrix-trail-color'); + dialog.bindColorButton('matrix-tip-color'); - const stack = this._builder.get_object('main-stack'); - stack.add_titled(this._builder.get_object('matrix-prefs'), 'matrix', 'Matrix'); + const stack = dialog.getBuilder().get_object('main-stack'); + stack.add_titled(dialog.getBuilder().get_object('matrix-prefs'), 'matrix', 'Matrix'); } } \ No newline at end of file diff --git a/src/prefs/PrefsPage.js b/src/prefs/PrefsPage.js deleted file mode 100644 index 156607b..0000000 --- a/src/prefs/PrefsPage.js +++ /dev/null @@ -1,102 +0,0 @@ -////////////////////////////////////////////////////////////////////////////////////////// -// ) ( // -// ( /( ( ( ) ( ( ( ( )\ ) ( ( // -// )\()) ))\ )( ( ( )\ ) )\))( )\ ( (()/( ( )\))( ( // -// ((_)\ /((_|()\ )\ ) )\ '(()/( ((_)()((_) )\ ) ((_)))\((_)()\ )\ // -// | |(_|_))( ((_)_(_/( _((_)) )(_)) _(()((_|_)_(_/( _| |((_)(()((_|(_) // -// | '_ \ || | '_| ' \)) | ' \()| || | \ V V / | ' \)) _` / _ \ V V (_-< // -// |_.__/\_,_|_| |_||_| |_|_|_| \_, | \_/\_/|_|_||_|\__,_\___/\_/\_//__/ // -// |__/ // -// Copyright (c) 2021 Simon Schneegans // -// Released under the GPLv3 or later. See LICENSE file for details. // -////////////////////////////////////////////////////////////////////////////////////////// - -'use strict'; - -const {Gdk, Gio} = imports.gi; - -////////////////////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////////////////////// - -var PrefsPage = class PrefsPage { - - // ------------------------------------------------------------ constructor / destructor - - constructor(settings, builder) { - this._settings = settings; - this._builder = builder; - } - - // ---------------------------------------------------------------------- public methods - - // Connects a Gtk.ComboBox (or anything else which has an 'active-id' property) to a - // settings key. It also binds the corresponding reset button. - _bindCombobox(settingsKey) { - this._bind(settingsKey, 'active-id'); - } - - // Connects a Gtk.Adjustment (or anything else which has a 'value' property) to a - // settings key. It also binds the corresponding reset button. - _bindAdjustment(settingsKey) { - this._bind(settingsKey, 'value'); - } - - // Connects a Gtk.Switch (or anything else which has an 'active' property) to a settings - // key. It also binds the corresponding reset button. - _bindSwitch(settingsKey) { - this._bind(settingsKey, 'active'); - } - - // Colors are stored as strings like 'rgb(1, 0.5, 0)'. As Gio.Settings.bind_with_mapping - // is not available yet, we need to do the color conversion manually. It also binds the - // corresponding reset button. - _bindColorButton(settingsKey) { - - const button = this._builder.get_object(settingsKey); - - if (button) { - - // Update the settings when the color is modified. - button.connect('color-set', () => { - this._settings.set_string(settingsKey, button.get_rgba().to_string()); - }); - - // Update the button state when the settings change. - const settingSignalHandler = () => { - const rgba = new Gdk.RGBA(); - rgba.parse(this._settings.get_string(settingsKey)); - button.rgba = rgba; - }; - - this._settings.connect('changed::' + settingsKey, settingSignalHandler); - - // Initialize the button with the state in the settings. - settingSignalHandler(); - } - - this._bindResetButton(settingsKey); - } - - // Connects any widget's property to a settings key. The widget must have the same ID as - // the settings key. It also binds the corresponding reset button. - _bind(settingsKey, property) { - const object = this._builder.get_object(settingsKey); - - if (object) { - this._settings.bind(settingsKey, object, property, Gio.SettingsBindFlags.DEFAULT); - } - - this._bindResetButton(settingsKey); - } - - // Searches for a reset button for the given settings key and make it reset the settings - // key when clicked. - _bindResetButton(settingsKey) { - const resetButton = this._builder.get_object('reset-' + settingsKey); - if (resetButton) { - resetButton.connect('clicked', () => { - this._settings.reset(settingsKey); - }); - } - } -} \ No newline at end of file diff --git a/src/prefs/TRexPage.js b/src/prefs/TRexPage.js index 113b02c..709cff9 100644 --- a/src/prefs/TRexPage.js +++ b/src/prefs/TRexPage.js @@ -16,12 +16,11 @@ const ExtensionUtils = imports.misc.extensionUtils; const Me = imports.misc.extensionUtils.getCurrentExtension(); const utils = Me.imports.src.common.utils; -const PrefsPage = Me.imports.src.prefs.PrefsPage.PrefsPage; ////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////// -var TRexPage = class TRexPage extends PrefsPage { +var TRexPage = class TRexPage { // ---------------------------------------------------------------------- static methods @@ -37,21 +36,19 @@ var TRexPage = class TRexPage extends PrefsPage { return 'T-Rex Attack'; } - // ------------------------------------------------------------ constructor / destructor + static initPreferences(dialog) { - constructor(settings, builder) { - super(settings, builder); - - this._builder.add_from_resource('/ui/gtk4/trexPage.ui'); + dialog.getBuilder().add_from_resource('/ui/gtk4/trexPage.ui'); // Bind all properties. - this._bindAdjustment('trex-animation-time'); - this._bindColorButton('claw-scratch-color'); - this._bindAdjustment('claw-scratch-scale'); - this._bindAdjustment('claw-scratch-count'); - this._bindAdjustment('claw-scratch-warp'); + dialog.bindAdjustment('trex-animation-time'); + dialog.bindColorButton('claw-scratch-color'); + dialog.bindAdjustment('claw-scratch-scale'); + dialog.bindAdjustment('claw-scratch-count'); + dialog.bindAdjustment('claw-scratch-warp'); - const stack = this._builder.get_object('main-stack'); - stack.add_titled(this._builder.get_object('trex-prefs'), 'trex', 'T-Rex Attack'); + const stack = dialog.getBuilder().get_object('main-stack'); + stack.add_titled( + dialog.getBuilder().get_object('trex-prefs'), 'trex', 'T-Rex Attack'); } } \ No newline at end of file diff --git a/src/prefs/TVEffectPage.js b/src/prefs/TVEffectPage.js index b919597..59973f6 100644 --- a/src/prefs/TVEffectPage.js +++ b/src/prefs/TVEffectPage.js @@ -16,12 +16,11 @@ const ExtensionUtils = imports.misc.extensionUtils; const Me = imports.misc.extensionUtils.getCurrentExtension(); const utils = Me.imports.src.common.utils; -const PrefsPage = Me.imports.src.prefs.PrefsPage.PrefsPage; ////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////// -var TVEffectPage = class TVEffectPage extends PrefsPage { +var TVEffectPage = class TVEffectPage { // ---------------------------------------------------------------------- static methods @@ -37,18 +36,16 @@ var TVEffectPage = class TVEffectPage extends PrefsPage { return 'TV Effect'; } - // ------------------------------------------------------------ constructor / destructor + static initPreferences(dialog) { - constructor(settings, builder) { - super(settings, builder); - - this._builder.add_from_resource(`/ui/${utils.isGTK4() ? 'gtk4' : 'gtk3'}/tvPage.ui`); + dialog.getBuilder().add_from_resource( + `/ui/${utils.isGTK4() ? 'gtk4' : 'gtk3'}/tvPage.ui`); // Bind all properties. - this._bindAdjustment('tv-animation-time'); - this._bindColorButton('tv-effect-color'); + dialog.bindAdjustment('tv-animation-time'); + dialog.bindColorButton('tv-effect-color'); - const stack = this._builder.get_object('main-stack'); - stack.add_titled(this._builder.get_object('tv-prefs'), 'tv', 'TV Effect'); + const stack = dialog.getBuilder().get_object('main-stack'); + stack.add_titled(dialog.getBuilder().get_object('tv-prefs'), 'tv', 'TV Effect'); } } \ No newline at end of file