const { Gtk, Gio } = imports.gi; const ExtensionUtils = imports.misc.extensionUtils; const Me = ExtensionUtils.getCurrentExtension(); function init() { } function buildPrefsWidget() { let settings = ExtensionUtils.getSettings(); // Create a vertical box to hold the widgets let box = new Gtk.Box({ orientation: Gtk.Orientation.VERTICAL, spacing: 10, margin_start: 10, margin_end: 10, margin_top: 10, margin_bottom: 10 }); let grid = new Gtk.Grid({ column_spacing: 10, row_spacing: 10 }); box.append(grid); function addExecutableInput(row, executable = '', icon = '', iconSize = 24) { // label and entry for app executable let appExecutableLabel = new Gtk.Label({ label: `App Executable ${row + 1}:`, halign: Gtk.Align.START }); let appExecutableEntry = new Gtk.Entry({ hexpand: true, text: executable }); // connect the entry to settings appExecutableEntry.connect('changed', (entry) => { settings.set_string(`app-executable-${row}`, entry.get_text()); }); // label and entry for the app icon SVG let appIconLabel = new Gtk.Label({ label: `App Icon SVG ${row + 1}:`, halign: Gtk.Align.START }); let appIconEntry = new Gtk.Entry({ hexpand: true, text: icon }); appIconEntry.connect('changed', (entry) => { settings.set_string(`app-icon-${row}`, entry.get_text()); }); // label and spin button for the icon size let iconSizeLabel = new Gtk.Label({ label: `Icon Size ${row + 1}:`, halign: Gtk.Align.START }); let iconSizeSpin = new Gtk.SpinButton({ adjustment: new Gtk.Adjustment({ value: iconSize, lower: 16, upper: 64, step_increment: 1, page_increment: 10 }), hexpand: true }); iconSizeSpin.connect('value-changed', (spin) => { settings.set_int(`icon-size-${row}`, spin.get_value_as_int()); }); let deleteButton = new Gtk.Button({ label: "Delete", halign: Gtk.Align.END }); deleteButton.connect('clicked', () => { // Clear settings for this row settings.set_string(`app-executable-${row}`, ''); settings.set_string(`app-icon-${row}`, ''); settings.set_int(`icon-size-${row}`, 24); grid.remove(appExecutableLabel); grid.remove(appExecutableEntry); grid.remove(appIconLabel); grid.remove(appIconEntry); grid.remove(iconSizeLabel); grid.remove(iconSizeSpin); grid.remove(deleteButton); reorganizeRows(row); }); grid.attach(appExecutableLabel, 0, row * 3, 1, 1); grid.attach(appExecutableEntry, 1, row * 3, 1, 1); grid.attach(appIconLabel, 0, row * 3 + 1, 1, 1); grid.attach(appIconEntry, 1, row * 3 + 1, 1, 1); grid.attach(iconSizeLabel, 0, row * 3 + 2, 1, 1); grid.attach(iconSizeSpin, 1, row * 3 + 2, 1, 1); grid.attach(deleteButton, 2, row * 3, 1, 3); // Span 3 rows for the button } // load existing launchers let row = 0; while (settings.get_string(`app-executable-${row}`) || settings.get_string(`app-icon-${row}`)) { let executable = settings.get_string(`app-executable-${row}`); let icon = settings.get_string(`app-icon-${row}`); addExecutableInput(row, executable, icon); row++; } // button to add new launchers let addButton = new Gtk.Button({ label: "Add New Launcher", halign: Gtk.Align.CENTER }); addButton.connect('clicked', () => { if (row < 10) { // Limit to 10 launchers addExecutableInput(row); row++; } else { let dialog = new Gtk.MessageDialog({ text: "Maximum of 10 launchers reached.", buttons: Gtk.ButtonsType.OK }); dialog.run(); dialog.destroy(); } }); box.append(addButton); box.show(); return box; }