// Copyright (c) 2026 Dominic Masters // // This software is released under the MIT License. // https://opensource.org/licenses/MIT var Menu = require('./Menu.js'); var Tab = require('./Tab.js'); var Confirm = require('./Confirm.js'); var SettingsGeneral = require('./SettingsGeneral.js'); var SettingsInput = require('./SettingsInput.js'); // Display/Audio pages are deliberately not here -- neither has any real // engine system behind it, even in the old code (no resolution/ // fullscreen system, no audio subsystem at all). var TABS = [ { name: 'General', ctor: SettingsGeneral }, { name: 'Input', ctor: SettingsInput } ]; // Owns a tabs Menu (General/Input) and swaps in the active tab's page // widgets into a second, page-scoped Menu -- both Menus are open on the // navigation stack simultaneously (tabsMenu below, pageMenu on top), // matching the old settings screen's nested-menu behavior. Switching // away from a dirty page opens a Confirm first. class Settings extends UIElement { init() { this.tabsMenu = new Menu(); this.tabsMenu.cols = TABS.length; this.add(this.tabsMenu); this.tabs = TABS.map((def, index) => { const tab = new Tab(); tab.text = def.name; tab.x = index * 90; this.tabsMenu.addItem(tab); return tab; }); this.tabsMenu.onSelected = (index) => this._activateTab(index); this.page = null; this.pageMenu = null; this._activeTabIndex = -1; } open() { UI.add(this); this.tabsMenu.open(); this._activateTab(0); } close() { this.tabsMenu.close(); if(this.pageMenu) this.pageMenu.close(); UI.remove(this); } _activateTab(index) { if(index === this._activeTabIndex) return; if(this.page && this.page.hasChanges && this.page.hasChanges()) { Confirm.open('Discard changes?', (confirmed) => { if(confirmed) this._swapTab(index); }); return; } this._swapTab(index); } _swapTab(index) { // pageMenu.dispose() cascades to every widget the outgoing page // handed it via menuItems -- the page itself is a plain object (see // SettingsGeneral.js), nothing else to release. if(this.pageMenu) this.pageMenu.dispose(); for(let i = 0; i < this.tabs.length; i++) { this.tabs[i].setHighlighted(i === index); } const def = TABS[index]; this.page = new def.ctor(); if(this.page.load) this.page.load(); this.pageMenu = new Menu(); this.pageMenu.y = 40; const items = this.page.menuItems || []; for(let i = 0; i < items.length; i++) this.pageMenu.addItem(items[i]); this.add(this.pageMenu); this.pageMenu.open(); this._activeTabIndex = index; } } module.exports = Settings;