refactor(prefs): rewrite preferences panel #69

Merged
kiyui merged 10 commits from bicycle-rewrite-prefs into bicycle-rewrite 12 months ago
  1. 1
      .gitignore
  2. 3
      night-light-slider.timur@linux.com/extension.js
  3. 1
      night-light-slider.timur@linux.com/metadata.json
  4. 6
      night-light-slider.timur@linux.com/org.gnome.shell.extensions.nightlightslider.data.gresource.xml
  5. 329
      night-light-slider.timur@linux.com/prefs.js
  6. 226
      night-light-slider.timur@linux.com/prefs.ui
  7. 3
      night-light-slider.timur@linux.com/schemas/org.gnome.shell.extensions.nightlightslider.gschema.xml
  8. 5
      package.json

1
.gitignore

@ -1,3 +1,4 @@
node_modules/
night-light-slider.timur@linux.com.zip
*.compiled
*.gresource

3
night-light-slider.timur@linux.com/extension.js

@ -167,9 +167,8 @@ class Indicator extends PanelMenu.SystemIndicator {
this._options[option] = value;
switch (option) {
case 'showAlways':
return this._sync();
case 'showStatusIcon':
return this._updateIndicatorVisibility();
return this._sync();
}
}

1
night-light-slider.timur@linux.com/metadata.json

@ -2,6 +2,7 @@
"name": "Night Light Slider",
"description": "Change night light temperature",
"settings-schema": "org.gnome.shell.extensions.nightlightslider",
"data-gresource": "org.gnome.shell.extensions.nightlightslider.data.gresource",
"uuid": "night-light-slider.timur@linux.com",
"version": 16,
"url": "https://github.com/kiyui/gnome-shell-night-light-slider-extension",

6
night-light-slider.timur@linux.com/org.gnome.shell.extensions.nightlightslider.data.gresource.xml

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<gresources>
<gresource prefix="/org/gnome/shell/extensions/nightlightslider">
<file>prefs.ui</file>
</gresource>
</gresources>

329
night-light-slider.timur@linux.com/prefs.js

@ -1,241 +1,108 @@
/* global imports log */
/* exported buildPrefsWidget init */
imports.gi.versions.Gtk = '3.0';
imports.gi.versions.Handy = '0.0';
const {GObject, Gio, Gtk, Handy} = imports.gi;
const Gtk = imports.gi.Gtk;
const ExtensionUtils = imports.misc.extensionUtils;
const Me = ExtensionUtils.getCurrentExtension();
// Extension specific
const Me = imports.misc.extensionUtils.getCurrentExtension();
const Convenience = Me.imports.convenience;
// Register resources
const resource = Me.metadata['data-gresource'];
const resourceFile = Me.dir.get_child(resource);
Gio.resources_register(Gio.Resource.load(resourceFile.get_path()));
function buildPrefsWidget() {
// eslint-disable-line no-unused-vars
const schema = Convenience.getSettings();
// Text and descriptions
const showAlwaysName = schema.settings_schema
.get_key("show-always")
.get_summary();
const showAlwaysDescription = schema.settings_schema
.get_key("show-always")
.get_description();
const showIconName = schema.settings_schema
.get_key("show-status-icon")
.get_summary();
const showIconDescription = schema.settings_schema
.get_key("show-status-icon")
.get_description();
const enableAlwaysName = schema.settings_schema
.get_key("enable-always")
.get_summary();
const enableAlwaysDescription = schema.settings_schema
.get_key("enable-always")
.get_description();
const minimumName = schema.settings_schema.get_key("minimum").get_summary();
const minimumDescription = schema.settings_schema
.get_key("minimum")
.get_description();
const maximumName = schema.settings_schema.get_key("maximum").get_summary();
const maximumDescription = schema.settings_schema
.get_key("maximum")
.get_description();
const brightnessSyncName = schema.settings_schema
.get_key("brightness-sync")
.get_summary();
const brightnessSyncDescription = schema.settings_schema
.get_key("brightness-sync")
.get_description();
const showInSubmenuName = schema.settings_schema
.get_key("show-in-submenu")
.get_summary();
const showInSubmenuDescription = schema.settings_schema
.get_key("show-in-submenu")
.get_description();
// Create children objects
const widgets = [
{
type: "Label",
params: { label: `${showAlwaysName}: ` },
tooltip: showAlwaysDescription,
align: Gtk.Align.END,
attach: [0, 1, 1, 1],
},
{
type: "Switch",
params: { active: schema.get_boolean("show-always") },
tooltip: showAlwaysDescription,
align: Gtk.Align.START,
attach: [1, 1, 1, 1],
connect: {
"state-set": (self) => {
schema.set_boolean("show-always", self.active);
},
},
},
{
type: "Label",
params: { label: `${showIconName}: ` },
tooltip: showAlwaysDescription,
align: Gtk.Align.END,
attach: [0, 2, 1, 1],
},
{
type: "Switch",
params: { active: schema.get_boolean("show-status-icon") },
tooltip: showIconDescription,
align: Gtk.Align.START,
attach: [1, 2, 1, 1],
connect: {
"state-set": (self) => {
schema.set_boolean("show-status-icon", self.active);
},
},
},
{
type: "Label",
params: { label: `${enableAlwaysName}: ` },
tooltip: enableAlwaysDescription,
align: Gtk.Align.END,
attach: [0, 3, 1, 1],
},
{
type: "Switch",
params: { active: schema.get_boolean("enable-always") },
tooltip: enableAlwaysDescription,
align: Gtk.Align.START,
attach: [1, 3, 1, 1],
connect: {
"state-set": (self) => {
schema.set_boolean("enable-always", self.active);
},
},
},
{
type: "Label",
params: { label: `${brightnessSyncName}: ` },
tooltip: brightnessSyncDescription,
align: Gtk.Align.END,
attach: [0, 4, 1, 1],
},
{
type: "Switch",
params: { active: schema.get_boolean("brightness-sync") },
tooltip: brightnessSyncDescription,
align: Gtk.Align.START,
attach: [1, 4, 1, 1],
connect: {
"state-set": (self) => {
schema.set_boolean("brightness-sync", self.active);
},
},
},
{
type: "Label",
params: { label: `${showInSubmenuName}: ` },
tooltip: showInSubmenuDescription,
align: Gtk.Align.END,
attach: [0, 5, 1, 1],
},
{
type: "Switch",
params: { active: schema.get_boolean("show-in-submenu") },
tooltip: showInSubmenuDescription,
align: Gtk.Align.START,
attach: [1, 5, 1, 1],
connect: {
"state-set": (self) => {
schema.set_boolean("show-in-submenu", self.active);
},
},
},
{
type: "Label",
params: { label: `${minimumName}: ` },
tooltip: minimumDescription,
align: Gtk.Align.END,
attach: [0, 6, 1, 1],
},
{
type: "Entry",
params: { text: schema.get_int("minimum").toString() },
tooltip: minimumDescription,
align: Gtk.Align.START,
attach: [1, 6, 1, 1],
connect: {
changed: (self) => {
schema.set_int("minimum", parseInt(self.text));
},
},
},
{
type: "Label",
params: { label: `${maximumName}: ` },
tooltip: maximumDescription,
align: Gtk.Align.END,
attach: [0, 7, 1, 1],
},
{
type: "Entry",
params: { text: schema.get_int("maximum").toString() },
tooltip: maximumDescription,
align: Gtk.Align.START,
attach: [1, 7, 1, 1],
connect: {
changed: (self) => {
schema.set_int("maximum", parseInt(self.text));
},
},
},
{
type: "Label",
params: {
label:
"Changes require restarting shell (logging in and out) to take place.",
},
tooltip: showAlwaysDescription,
align: Gtk.Align.CENTER,
attach: [0, 8, 2, 1],
},
];
// Perform side-effects
const vbox = new Gtk.Grid({
column_spacing: 20,
row_spacing: 20,
margin: 10,
});
widgets.map(function createWidget({
type,
params,
tooltip,
align,
attach,
connect,
}) {
const widget = new Gtk[type](params);
// Set description
widget.set_tooltip_text(tooltip);
// Set alignment
widget.set_halign(align);
widget.set_hexpand(true);
// Add event handler if exists
if (connect) {
Object.keys(connect).map(function performConnect(signal) {
widget.connect(signal, () => connect[signal](widget));
});
// GSettings schema
const COLOR_SCHEMA = 'org.gnome.settings-daemon.plugins.color';
var NightLightExtensionPrefs = GObject.registerClass({
GTypeName: 'NightLightExtensionPrefs',
Template: 'resource:///org/gnome/shell/extensions/nightlightslider/prefs.ui',
InternalChildren: [
/* Night Light status infobar */
'infobar_status', 'btn_enable_night_light',
/* Slider position option */
'show_in_submenu_combo',
/* Boolean switch options */
'show_always_toggle_switch',
'show_status_icon_toggle_switch',
'swap_axis_toggle_switch',
'brightness_sync_toggle_switch',
'enable_always_toggle_switch',
/* Temperature range */
'spinbutton_maximum', 'spinbutton_minimum',
],
}, class NightLightExtensionPrefs extends Gtk.Box {
_init(preferences) {
super._init();
this._preferences = preferences;
this._settings = new Gio.Settings({schema_id: COLOR_SCHEMA});
// Initialize application state
this._syncInfobar();
this._syncPreferences();
// Connect settings change signals
this._settings.connect('changed::night-light-enabled', this._syncInfobar.bind(this));
this._preferences.connect('changed', this._syncPreferences.bind(this));
// Set up alert CTA to enable night light
this._btn_enable_night_light.connect('clicked',
() => this._settings.set_boolean('night-light-enabled', true));
// Set up combo changed listener
this._show_in_submenu_combo.connect('changed',
self => this._preferences.set_boolean('show-in-submenu',
// The possible options are show_in_submenu_{true,false}
self.active_id === 'show_in_submenu_true'));
// Set up switch state-set listeners
// We negate the returns of `set_boolean` such that the state updates
this._show_always_toggle_switch.connect('state-set',
(_, state) => !this._preferences.set_boolean('show-always', state));
this._show_status_icon_toggle_switch.connect('state-set',
(_, state) => !this._preferences.set_boolean('show-status-icon', state));
this._swap_axis_toggle_switch.connect('state-set',
(_, state) => !this._preferences.set_boolean('swap-axis', state));
this._brightness_sync_toggle_switch.connect('state-set',
(_, state) => !this._preferences.set_boolean('brightness-sync', state));
this._enable_always_toggle_switch.connect('state-set',
(_, state) => !this._preferences.set_boolean('enable-always', state));
// Set up spinner value-changed listeners
this._spinbutton_maximum.connect('value-changed',
self => this._preferences.set_int('maximum', self.value));
this._spinbutton_minimum.connect('value-changed',
self => this._preferences.set_int('minimum', self.value));
}
_syncInfobar() {
const visible = !this._settings.get_boolean('night-light-enabled');
this._infobar_status.set_revealed(visible);
}
vbox.attach(widget, ...attach);
});
_syncPreferences() {
// Focus on slider position option based on index
this._show_in_submenu_combo.set_active(this._preferences.get_boolean('show-in-submenu') ? 1 : 0);
// Update switch active states
this._show_always_toggle_switch.active = this._preferences.get_boolean('show-always');
this._show_status_icon_toggle_switch.active = this._preferences.get_boolean('show-status-icon');
this._swap_axis_toggle_switch.active = this._preferences.get_boolean('swap-axis');
this._brightness_sync_toggle_switch.active = this._preferences.get_boolean('brightness-sync');
this._enable_always_toggle_switch.active = this._preferences.get_boolean('enable-always');
vbox.show_all();
return vbox;
// Update temperature range values
this._spinbutton_maximum.value = this._preferences.get_int('maximum');
this._spinbutton_minimum.value = this._preferences.get_int('minimum');
}
});
function buildPrefsWidget() {
const preferences = ExtensionUtils.getSettings();
return new NightLightExtensionPrefs(preferences);
}
function init() {
// eslint-disable-line
log("Setting up night light slider preferences");
Gtk.init(null);
Handy.init(null);
}

226
night-light-slider.timur@linux.com/prefs.ui

@ -0,0 +1,226 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.36.0 -->
<interface>
<requires lib="gtk+" version="3.22"/>
<requires lib="libhandy" version="0.0"/>
<template class="NightLightExtensionPrefs" parent="GtkBox">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkInfoBar" id="infobar_status">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<property name="message_type">warning</property>
<child internal-child="action_area">
<object class="GtkButtonBox">
<property name="can_focus">False</property>
<property name="spacing">6</property>
<property name="layout_style">end</property>
<child>
<object class="GtkButton" id="btn_enable_night_light">
<property name="label" translatable="yes">Enable</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
<child internal-child="content_area">
<object class="GtkBox">
<property name="can_focus">False</property>
<property name="spacing">16</property>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Night Light is disabled in system preferences</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkListBox">
<property name="name">listbox</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="selection_mode">none</property>
<child>
<object class="HdyActionRow">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="subtitle" translatable="yes">Manage where in the aggregate menu the slider should show</property>
<property name="title" translatable="yes">Slider position</property>
<child type="action">
<object class="GtkComboBoxText" id="show_in_submenu_combo">
<property name="visible">True</property>
<property name="valign">center</property>
<items>
<item id="show_in_submenu_false" translatable="yes">Top-level menu</item>
<item id="show_in_submenu_true" translatable="yes">Night Light submenu</item>
</items>
</object>
</child>
</object>
</child>
<child>
<object class="HdyActionRow">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="subtitle" translatable="yes">Show the slider even when night light is disabled or off</property>
<property name="title" translatable="yes">Always show slider</property>
<property name="activatable-widget">show_always_toggle_switch</property>
<child type="action">
<object class="GtkSwitch" id="show_always_toggle_switch">
<property name="visible">True</property>
<property name="valign">center</property>
</object>
</child>
</object>
</child>
<child>
<object class="HdyActionRow">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="subtitle" translatable="yes">Show the night light indicator in the status area when night light is enabled</property>
<property name="title" translatable="yes">Show indicator</property>
<property name="activatable-widget">show_status_icon_toggle_switch</property>
<child type="action">
<object class="GtkSwitch" id="show_status_icon_toggle_switch">
<property name="visible">True</property>
<property name="valign">center</property>
</object>
</child>
</object>
</child>
<child>
<object class="HdyActionRow">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="subtitle" translatable="yes">Invert the slider axis such that lower is cooler and higher is warmer</property>
<property name="title" translatable="yes">Swap slider axis</property>
<property name="activatable-widget">swap_axis_toggle_switch</property>
<child type="action">
<object class="GtkSwitch" id="swap_axis_toggle_switch">
<property name="visible">True</property>
<property name="valign">center</property>
</object>
</child>
</object>
</child>
<child>
<object class="HdyActionRow">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="subtitle" translatable="yes">Adjust both brightness and night light warmth</property>
<property name="title" translatable="yes">Sync brightness percentage</property>
<property name="activatable-widget">brightness_sync_toggle_switch</property>
<child type="action">
<object class="GtkSwitch" id="brightness_sync_toggle_switch">
<property name="visible">True</property>
<property name="valign">center</property>
</object>
</child>
</object>
</child>
<child>
<object class="HdyActionRow">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="subtitle" translatable="yes">Constantly update the night light schedule such that it is enabled throughout the day</property>
<property name="title" translatable="yes">Enable permanent night light</property>
<property name="activatable-widget">enable_always_toggle_switch</property>
<child type="action">
<object class="GtkSwitch" id="enable_always_toggle_switch">
<property name="visible">True</property>
<property name="valign">center</property>
</object>
</child>
</object>
</child>
<child>
<object class="HdyActionRow">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="subtitle" translatable="yes">Maximum slider value, higher is cooler</property>
<property name="title" translatable="yes">Highest temperature</property>
<child type="action">
<object class="GtkSpinButton" id="spinbutton_maximum">
<property name="visible">True</property>
<property name="valign">center</property>
<property name="can_focus">True</property>
<property name="placeholder_text">5000</property>
<property name="input_purpose">number</property>
<property name="adjustment">temperature_adjustment_maximum</property>
</object>
</child>
</object>
</child>
<child>
<object class="HdyActionRow">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="subtitle" translatable="yes">Minimum slider value, lower is warmer</property>
<property name="title" translatable="yes">Lowest temperature</property>
<child type="action">
<object class="GtkSpinButton" id="spinbutton_minimum">
<property name="visible">True</property>
<property name="valign">center</property>
<property name="can_focus">True</property>
<property name="placeholder_text">1500</property>
<property name="input_purpose">number</property>
<property name="adjustment">temperature_adjustment_minimum</property>
</object>
</child>
</object>
</child>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</template>
<object class="GtkAdjustment" id="temperature_adjustment_maximum">
<property name="lower" bind-source="temperature_adjustment_minimum" bind-property="value" bind-flags="default|sync-create" />
<property name="upper">9000</property>
<property name="step_increment">100</property>
<property name="page_increment">10</property>
</object>
<object class="GtkAdjustment" id="temperature_adjustment_minimum">
<property name="lower">1000</property>
<property name="upper" bind-source="temperature_adjustment_maximum" bind-property="value" bind-flags="default|sync-create" />
<property name="step_increment">100</property>
<property name="page_increment">10</property>
</object>
</interface>

3
night-light-slider.timur@linux.com/schemas/org.gnome.shell.extensions.nightlightslider.gschema.xml

@ -1,8 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<schemalist>
<schema id="org.gnome.shell.extensions.nightlightslider" path="/org/gnome/shell/extensions/nightlightslider/">
<key name="show-always" type="b">
<default>false</default>
<summary>Show always</summary>
<summary>Always show slider</summary>
<description>Show the slider even when night light is disabled or off</description>
</key>
<key name="show-status-icon" type="b">

5
package.json

@ -2,10 +2,11 @@
"name": "gnome-shell-night-light-slider-extension",
"description": "Change night light temperature",
"scripts": {
"build:resources": "glib-compile-resources --sourcedir night-light-slider.timur@linux.com/ night-light-slider.timur@linux.com/org.gnome.shell.extensions.nightlightslider.data.gresource.xml",
"build:schema": "glib-compile-schemas night-light-slider.timur@linux.com/schemas/",
"build:copy": "cp -rvf night-light-slider.timur@linux.com/ ~/.local/share/gnome-shell/extensions/",
"build:link": "ln -s $(pwd)/night-light-slider.timur@linux.com/ ~/.local/share/gnome-shell/extensions/",
"build:zip": "cd night-light-slider.timur@linux.com/ && zip -r ../night-light-slider.timur@linux.com.zip ./*",
"build": "npm run build:schema && npm run build:zip"
"build": "npm run build:resources && npm run build:schema && npm run build:zip"
},
"repository": {
"type": "git",

Loading…
Cancel
Save