"use strict"; // Top-level state and UI manager globalThis.App = class App { // Object constructor constructor() { // Configure themes Bundle.get("app/theme/kiosk.css").style(); this.themes = { dark : Bundle.get("app/theme/dark.css" ).style(false), light : Bundle.get("app/theme/light.css" ).style(true ), virtual: Bundle.get("app/theme/virtual.css").style(false) }; this.theme = this.themes["light"]; // Produce toolkit instance this.gui = new Toolkit.Application({ layout: "grid", rows : "max-content auto" }); document.body.appendChild(this.gui.element); window.addEventListener("resize", ()=>{ this.gui.setSize(window.innerWidth+"px", window.innerHeight+"px"); }); window.dispatchEvent(new Event("resize")); // Configure locales this.gui.addLocale(Bundle.get("app/locale/en-US.js").toString()); this.gui.setLocale(navigator.language); // Menu bar this.mainMenu = this.gui.newMenuBar({ name: "{menu._}" }); this.gui.add(this.mainMenu); this.gui.addPropagationListener(e=>this.mainMenu.restoreFocus()); // File menu let menu = this.mainMenu.newMenu({ text: "{menu.file._}"}); let item = menu.newMenuItem({ text: "{menu.file.loadROM}"}); item.addClickListener(()=>this.loadROM()); // Theme menu menu = this.mainMenu.newMenu({ text: "{menu.theme._}"}); item = menu.newMenuItem({ text: "{menu.theme.light}"}); item.addClickListener(()=>this.setTheme("light")); item = menu.newMenuItem({ text: "{menu.theme.dark}"}); item.addClickListener(()=>this.setTheme("dark")); item = menu.newMenuItem({ text: "{menu.theme.virtual}"}); item.addClickListener(()=>this.setTheme("virtual")); // Desktop pane let desktop = this.gui.newPanel({ layout: "desktop" }); desktop.setRole("group"); desktop.element.setAttribute("desktop", ""); this.gui.add(desktop); let wnd = this.gui.newWindow({ title: "{memory._}" }); desktop.add(wnd); wnd.setLocation ( 20, 10); wnd.setClientSize(384, 224); } ///////////////////////////// Private Methods ///////////////////////////// // Prompt the user to select a ROM file loadROM() { let file = document.createElement("input"); file.type = "file"; file.addEventListener("input", ()=>this.setROM(file.files[0])); file.click(); } // Specify a ROM file async setROM(file) { // No file is specified (perhaps the user canceled) if (file == null) return; // Check the file's size if ( file.size < 1024 || file.size > 0x1000000 || (file.size - 1 & file.size) != 0 ) { alert(this.gui.translate("{app.romNotVB}")); return; } // Load the file data into a byte buffer let filename = file.name; try { file = new Uint8Array(await file.arrayBuffer()); } catch { alert(this.gui.translate("{app.readFileError}")); return; } // Testing output pending further features alert(this.gui.translate("{app.romLoaded}", { filename: filename, size : file.length + " byte" + (file.length == 1 ? "" : "s") })); } // Specify the current color theme setTheme(key) { let theme = this.themes[key]; if (theme == this.theme) return; let old = this.theme; this.theme = theme; theme.setEnabled(true); old.setEnabled(false); } };