assassin-bug/framework/ui/menu/index.js

146 lines
5.5 KiB
JavaScript
Raw Permalink Normal View History

2022-11-26 01:22:02 +00:00
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
import * as EventEmitter from 'eventemitter3';
import { SoundManager } from './sound-manager';
import { KeyboardManager } from './keyboard-manager';
export class Menu extends EventEmitter {
constructor(title = 'Menu', menuItems = [], soundSet = null, defaultAction = null, cancelAction = null) {
super();
this.title = title;
this.menuItems = menuItems;
this.soundSet = soundSet;
this.defaultAction = defaultAction;
this.cancelAction = cancelAction;
this.currentIndex = 0;
this.DOMNodes = [];
this.currentIndex = 0;
this.currentItem = null;
this.soundManager = new SoundManager(soundSet);
this.keyboardManager = new KeyboardManager(this);
this.init();
}
init() {
this.menuItems[this.currentIndex] &&
this.menuItems[this.currentIndex].focus();
this.emit('init');
}
addItem(item) {
this.menuItems.push(item);
this.emit('item.add', item);
return this;
}
setTitle(title) {
this.title = title;
return this;
}
setSoundSet(soundSet) {
this.soundSet = soundSet;
this.soundManager.setSoundSet(this.soundSet);
return this;
}
setDefaultAction(id) {
this.defaultAction = id;
return this;
}
setCancelAction(id) {
this.cancelAction = id;
return this;
}
run(element) {
return __awaiter(this, void 0, void 0, function* () {
return new Promise((resolve, reject) => {
this.element = element;
this.container = document.createElement('div');
this.titleContainer = document.createElement('h1');
this.titleContainer.textContent = this.title;
this.container.appendChild(this.titleContainer);
this.menuItems.forEach((item) => {
this.appendToContainer(item.getDOMNode());
item.on('update', this.handleItemUpdate.bind(this));
item.on('focus', this.onItemFocus.bind(this));
item.on('choose', (event) => {
const menuMap = this.compile();
this.soundManager.handleSound('choose');
this.emit('choose', menuMap);
resolve(menuMap);
});
});
element.appendChild(this.container);
this.soundManager.handleSound('open');
this.keyboardManager.init();
// push some data onto the history stack so that we can use the browser's back button to exit out of the menu.
history.pushState({ menu: true }, null, null);
});
});
}
close() {
this.container.remove();
this.soundManager.handleSound('close');
this.keyboardManager.release();
this.DOMNodes.forEach((item) => {
this.container.removeChild(item);
});
this.emit('close');
}
appendToContainer(node) {
this.container.appendChild(node);
this.DOMNodes.push(node);
}
handleItemUpdate(value) {
this.soundManager.handleSound(value.type, value.value);
this.emit('update', this.compile());
}
onItemFocus(id) {
this.soundManager.handleSound('focus');
this.currentIndex = this.menuItems.indexOf(this.menuItems.find((item) => item.getID() == id));
this.emit('focus', this.menuItems[this.currentIndex]);
}
focusNext() {
if (this.currentIndex < this.menuItems.length - 1) {
this.currentIndex++;
}
this.focusCurrentIndex();
}
focusPrevious() {
if (this.currentIndex > 0) {
this.currentIndex--;
}
this.focusCurrentIndex();
}
focusCurrentIndex() {
this.menuItems[this.currentIndex].focus();
}
getCurrentFocus() {
return this.menuItems[this.currentIndex];
}
getContainer() {
return this.container;
}
clickDefaultAction() {
if (!this.defaultAction)
return;
const item = this.menuItems.find((item) => item.getID() === this.defaultAction);
item.click();
}
clickCancelAction() {
if (!this.cancelAction)
return;
const node = this.menuItems.find((item) => item.getID() === this.cancelAction);
node.click();
}
compile() {
const menuMap = new Map();
this.menuItems.forEach((item) => menuMap.set(item.getID(), item.getContents()));
menuMap.set('selected', this.menuItems[this.currentIndex].getID());
return menuMap;
}
}
export * from './items';