123 lines
3.7 KiB
JavaScript
123 lines
3.7 KiB
JavaScript
"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);
|
|
}
|
|
|
|
};
|