UNPKG

@woosh/meep-engine

Version:

Pure JavaScript game engine. Fully featured and production ready.

160 lines (116 loc) 3.33 kB
import { passThrough } from "../../core/function/passThrough.js"; import { UUID } from "../../engine/ecs/guid/UUID.js"; import View from '../View.js'; /** * @template T */ class DropDownSelectionView extends View { /** * @template T * @param {List<T>} model * @param {function(T):string} [transform] * @param {function(T)} [changeListener] */ constructor(model, { transform, changeListener } = {}) { super(); this.model = model; const elRoot = this.el = document.createElement('select'); elRoot.classList.add('ui-drop-dow-selection-view'); if (transform === undefined) { this.transfrom = passThrough; } else { this.transfrom = transform; } this.bindSignal(this.model.on.added, this.handleAdded, this); this.bindSignal(this.model.on.removed, this.handleRemoved, this); if (changeListener !== undefined) { elRoot.addEventListener('change', (event) => { const id = event.target.value; const v = this.getValueById(id); changeListener(v); }); } /** * ID mapping * @private * @type {Map<T, string>} */ this.mapping = new Map(); } /** * @private * @param {String} el * @param {number} index */ handleAdded(el, index) { const text = this.transfrom(el); const id = UUID.string(); this.mapping.set(el, id); const element = document.createElement('option'); element.setAttribute('value', id); element.innerText = text; this.el.appendChild(element); } /** * @private * @param {string} el */ handleRemoved(el) { const $el = this.el; let children = $el.children; let length = children.length; const id = this.mapping.get(el); for (let i = 0; i < length; i++) { let child = children[i]; if (child.value === id) { $el.removeChild(child); return; } } } clearOptions() { const children = this.el.children; while (children.length > 0) { let child = children[0]; this.el.removeChild(child); } } /** * * @param {string} id * @return {T} */ getValueById(id) { let result = null; this.mapping.forEach((_id, el) => { if (_id === id) { result = el; } }); return result; } /** * * @return {T} */ getSelectedValue() { const id = this.el.options[this.el.selectedIndex].value; return this.getValueById(id); } /** * * @param {T} v */ setSelectedValue(v) { this.el.selectedIndex = this.model.indexOf(v); } link() { this.model.forEach(this.handleAdded, this); super.link(); } unlink() { super.unlink(); this.clearOptions(); } } export default DropDownSelectionView;