/src/celleditor.ts
import { Cell } from './cell'; import { GameEvent, GameEventType } from './event'; import FragmentManager from './fragmentmanager'; export type CellEditorCallback = (cell: Cell) => void; export default class CellEditor { container: FragmentManager titleRef: HTMLInputElement descriptionRef: HTMLTextAreaElement events: FragmentManager[] cell: Cell onClose: (cell: Cell) => void constructor() { this.container = new FragmentManager(` <div class="box hflex"> <div class="vflex flex-auto"> <h1>Cell Editor</h1> <h2>Title</h2> <input name="title"> <h2>Description</h2> <textarea name="description" class="flex-auto"></textarea> <h2>Exits</h2> <div class="hflex"> <label><input type="checkbox" name="exit-n">North</label> <label><input type="checkbox" name="exit-e">East</label> <label><input type="checkbox" name="exit-s">South</label> <label><input type="checkbox" name="exit-w">West</label> </div> <div class="hflex"> <button id="cell-editor-close">Close</button> </div> </div> <div class="events"> <h2>Events</h2> <div id="event-list"></div> <button id="add-event">Add Event</button> </div> </div> `); this.container.mountInto('cell-editor-container'); this.container.elem.addEventListener('keydown', function(e: KeyboardEvent) { e.cancelBubble = true; }); this.titleRef = <HTMLInputElement>this.container.q('[name=title]'); this.descriptionRef = <HTMLTextAreaElement>this.container.q('[name=description]'); const addEventButton = this.container.q('#add-event'); addEventButton.addEventListener('click', this.addEventHandler.bind(this)); this.events = [] const closeButton = this.container.q('#cell-editor-close'); closeButton.addEventListener('click', this.closeHandler.bind(this)); } open(cell: Cell) { this.cell = cell; this.titleRef.value = cell.title; this.descriptionRef.value = cell.description; ['n', 'e', 's', 'w'].forEach( (dir, index) => { const checkbox = <HTMLInputElement>this.container.q(`input[name="exit-${dir}"]`); checkbox.checked = cell.exits[index]; }); for (let [k, e] of cell.events) { this.addEvent(e); } this.container.elem.classList.add('visible'); this.titleRef.focus(); } addEventHandler() { this.addEvent(); } addEvent(event?: GameEvent) { const eventForm = new FragmentManager(` <h3>ID</h3> <input name="id"> <h3>Type</h3> <select name="type"> <option value="0">Enter</option> <option value="1">Leave</option> <option value="2">Random</option> <option value="3">Action</option> </select> <h3>Title</h3> <input name="title"> <h3>Script</h3> <textarea name="script"></textarea> <div> <button name="delete">Delete Event</button> </div> `, 'div', { className: 'vflex' }); eventForm.mount('event-list'); this.events.push(eventForm); const deleteButton = eventForm.q('[name=delete]'); deleteButton.addEventListener('click', () => { eventForm.unmount(); const i = this.events.indexOf(eventForm); this.events.splice(i, 1); }); if (!event) { event = new GameEvent(); } (<HTMLInputElement>eventForm.q('[name=id]')) .value = event.id; (<HTMLSelectElement>eventForm.q('[name=type]')) .value = event.type.toString(); (<HTMLInputElement>eventForm.q('[name=title]')) .value = event.title; (<HTMLTextAreaElement>eventForm.q('[name=script]')) .value = event.script; } close() { this.closeHandler(); } closeHandler() { this.cell.title = this.titleRef.value; this.cell.description = this.descriptionRef.value; ['n', 'e', 's', 'w'].forEach( (dir, index) => { const checkbox = <HTMLInputElement>this.container.q(`input[name="exit-${dir}"]`); this.cell.exits[index] = checkbox.checked; }); // We recreate all of the cell's events to make sure we remove any deleted ones this.cell.events.clear(); for (let eventForm of this.events) { const id = (<HTMLInputElement>eventForm.q('[name=id]')).value; const type = <GameEventType>parseInt((<HTMLInputElement>eventForm.q('[name=type]')).value); const title = (<HTMLInputElement>eventForm.q('[name=title]')).value; const script = (<HTMLInputElement>eventForm.q('[name=script]')).value; const e = new GameEvent(); e.id = id; e.type = type; e.title = title; e.script = script; this.cell.events.set(id, e); } for (let ev of this.events) ev.unmount(); this.events = []; if (this.onClose) { this.onClose(this.cell); this.onClose = null; } this.container.elem.classList.remove('visible'); } }