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';