feat: adding in demo settings page for gnome extensions

This commit is contained in:
Lucas Oskorep
2025-04-05 23:55:46 -04:00
parent 84777c4db1
commit 185a8e233c
9 changed files with 482 additions and 95 deletions

192
src/prefs.ts Normal file
View File

@@ -0,0 +1,192 @@
import Adw from 'gi://Adw';
import Gio from 'gi://Gio';
import Gtk from 'gi://Gtk';
import Gdk from 'gi://Gdk';
import { ExtensionPreferences, gettext as _ } from 'resource:///org/gnome/Shell/Extensions/js/extensions/prefs.js';
export default class MyExtensionPreferences extends ExtensionPreferences {
async fillPreferencesWindow(window: Adw.PreferencesWindow) {
// Create settings object
const settings = this.getSettings('org.gnome.shell.extensions.aerospike');
// Create a preferences page
const page = new Adw.PreferencesPage({
title: _('Settings'),
icon_name: 'preferences-system-symbolic',
});
window.add(page);
// Create keybindings group
const keybindingsGroup = new Adw.PreferencesGroup({
title: _('Keyboard Shortcuts'),
});
page.add(keybindingsGroup);
// Add keybinding rows
this.addKeybindingRow(keybindingsGroup, settings, 'keybinding-1', _('Action 1'));
this.addKeybindingRow(keybindingsGroup, settings, 'keybinding-2', _('Action 2'));
this.addKeybindingRow(keybindingsGroup, settings, 'keybinding-3', _('Action 3'));
this.addKeybindingRow(keybindingsGroup, settings, 'keybinding-4', _('Action 4'));
// Create options group
const optionsGroup = new Adw.PreferencesGroup({
title: _('Options'),
});
page.add(optionsGroup);
// Add dropdown
const dropdownRow = new Adw.ComboRow({
title: _('Select an option'),
});
optionsGroup.add(dropdownRow);
// Create dropdown model
const dropdownModel = new Gtk.StringList();
dropdownModel.append(_('Option 1'));
dropdownModel.append(_('Option 2'));
dropdownModel.append(_('Option 3'));
dropdownModel.append(_('Option 4'));
dropdownRow.set_model(dropdownModel);
// Set the active option based on settings
const currentOption = settings.get_string('dropdown-option');
switch (currentOption) {
case 'option1':
dropdownRow.set_selected(0);
break;
case 'option2':
dropdownRow.set_selected(1);
break;
case 'option3':
dropdownRow.set_selected(2);
break;
case 'option4':
dropdownRow.set_selected(3);
break;
default:
dropdownRow.set_selected(0);
}
// Connect dropdown change signal
dropdownRow.connect('notify::selected', () => {
const selected = dropdownRow.get_selected();
let optionValue: string;
switch (selected) {
case 0:
optionValue = 'option1';
break;
case 1:
optionValue = 'option2';
break;
case 2:
optionValue = 'option3';
break;
case 3:
optionValue = 'option4';
break;
default:
optionValue = 'option1';
}
settings.set_string('dropdown-option', optionValue);
});
// Add color button
const colorRow = new Adw.ActionRow({
title: _('Choose a color'),
});
optionsGroup.add(colorRow);
const colorButton = new Gtk.ColorButton();
colorRow.add_suffix(colorButton);
colorRow.set_activatable_widget(colorButton);
// Set current color from settings
const colorStr = settings.get_string('color-selection');
const rgba = new Gdk.RGBA();
rgba.parse(colorStr);
colorButton.set_rgba(rgba);
// Connect color button signal
colorButton.connect('color-set', () => {
const color = colorButton.get_rgba().to_string();
settings.set_string('color-selection', color);
});
}
private addKeybindingRow(
group: Adw.PreferencesGroup,
settings: Gio.Settings,
key: string,
title: string
) {
const shortcutsRow = new Adw.ActionRow({
title: title,
});
group.add(shortcutsRow);
// Create a button for setting shortcuts
const shortcutButton = new Gtk.Button({
valign: Gtk.Align.CENTER,
label: settings.get_strv(key)[0] || _("Disabled")
});
shortcutsRow.add_suffix(shortcutButton);
shortcutsRow.set_activatable_widget(shortcutButton);
// When clicking the button, show a dialog or start listening for keystroke
shortcutButton.connect('clicked', () => {
// Show a simple popup stating that the shortcut is being recorded
const dialog = new Gtk.MessageDialog({
modal: true,
text: _("Press a key combination to set as shortcut"),
secondary_text: _("Press Esc to cancel or Backspace to disable"),
buttons: Gtk.ButtonsType.CANCEL,
transient_for: group.get_root() as Gtk.Window
});
// Create a keypress event controller
const controller = new Gtk.EventControllerKey();
dialog.add_controller(controller);
controller.connect('key-pressed', (_controller, keyval, keycode, state) => {
// Get the key name
let keyName = Gdk.keyval_name(keyval);
// Handle special cases
if (keyName === 'Escape') {
dialog.response(Gtk.ResponseType.CANCEL);
return Gdk.EVENT_STOP;
} else if (keyName === 'BackSpace') {
// Clear the shortcut
settings.set_strv(key, []);
shortcutButton.set_label(_("Disabled"));
dialog.response(Gtk.ResponseType.OK);
return Gdk.EVENT_STOP;
}
// Convert modifier state to keybinding modifiers
let modifiers = state & Gtk.accelerator_get_default_mod_mask();
// Ignore standalone modifier keys
if (Gdk.ModifierType.SHIFT_MASK <= keyval && keyval <= Gdk.ModifierType.META_MASK)
return Gdk.EVENT_STOP;
// Create accelerator string
let accelerator = Gtk.accelerator_name(keyval, modifiers);
if (accelerator) {
settings.set_strv(key, [accelerator]);
shortcutButton.set_label(accelerator);
dialog.response(Gtk.ResponseType.OK);
}
return Gdk.EVENT_STOP;
});
dialog.present();
});
}
}

20
src/utils.ts Normal file
View File

@@ -0,0 +1,20 @@
// Utility functions and type definitions
/**
* Interface for the extension settings
*/
export interface ExtensionSettings {
keybinding1: string[];
keybinding2: string[];
keybinding3: string[];
keybinding4: string[];
dropdownOption: string;
colorSelection: string;
}
/**
* Log a message with the extension name prefix
*/
export function log(message: string): void {
console.log(`[MyExtension] ${message}`);
}