diff --git a/src/automaton.js b/src/automaton.js index 01ff947..44ec57b 100644 --- a/src/automaton.js +++ b/src/automaton.js @@ -5,9 +5,19 @@ function Automaton(async, dom, messaging, screen, session, ui) { {label: 'New Game', action: newGame}, {label: 'Settings', action: function() { console.log("Not implemented yet"); }} ], - cancel: intro - }, + cancel: intro, + name: 'start' + } + }; + var choices = { name: { + entries: [ + {label: 'Max', value: 'Max'}, + {label: 'Lenore', value: 'Lenore'}, + {label: 'Thomas', value: 'Thomas'}, + {label: null, size: 15} + ], + name: 'name' }, skin: { } @@ -41,8 +51,8 @@ function Automaton(async, dom, messaging, screen, session, ui) { {action: function() { screen.show(title); }, delay: 1000}, {action: function() { screen.show(subtitle); }, delay: null} ], { - 'B': function() { intro(); }, - 'Start': function() { ui.frame('StartMenu'); ui.menu(menus.start); } + B: function() { intro(); }, + Start: function() { ui.frame('StartMenu'); ui.menu(menus.start); } }) ); } @@ -52,7 +62,12 @@ function Automaton(async, dom, messaging, screen, session, ui) { async.run( ui.text("Bonjour ! Bienvenue dans le monde merveilleux des pokémons !"), ui.text("Pour certains, les pokemons sont des amis. Pour d'autres, ils sont une ressource. Pour ma part, hé bien l'étude des pokémons est mon métier mais aussi ma passion."), - ui.text("Mais, dis-moi, tu viens d'arriver dans la ville non ? Comment t'appelles-tu ?") + ui.text("Mais, dis-moi, tu viens d'arriver dans la ville non ? Comment t'appelles-tu ?"), + async.bind(ui.ask(choices.name), function(name) { + screen.clear('text'); + console.log('You picked : ' + name); + return async.wrap(); + }) ); } } diff --git a/src/buttons.js b/src/buttons.js index 97b0bcd..9d23f03 100644 --- a/src/buttons.js +++ b/src/buttons.js @@ -5,6 +5,7 @@ function Buttons(session) { document.addEventListener('keydown', function(event) { var button = session.getOptions().layout[event.key]; if(button != undefined && mapping[button] != undefined) { + event.preventDefault(); mapping[button](); } }); diff --git a/src/dom.js b/src/dom.js index 54d842e..649da2d 100644 --- a/src/dom.js +++ b/src/dom.js @@ -20,6 +20,9 @@ function Dom() { case "class": e.className = Array.isArray(value) ? value.join(' ') : value; break;; + case "maxlength": + e.setAttribute("maxlength", value); + break; case "onClick": e.addEventListener("click", value); break;; diff --git a/src/screen.css b/src/screen.css index 2423f6c..34051f8 100644 --- a/src/screen.css +++ b/src/screen.css @@ -1,5 +1,8 @@ body { background: #000; +} + +body, input { font-family: mono; line-height: 1.5em; } @@ -54,7 +57,15 @@ ul.menu .selected:before { float: left; } -/* 1st frame */ +input.framed { + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + font-size: 1em; + padding: 0.2em; +} + #screen.frameIntro * { position: absolute; } @@ -75,7 +86,10 @@ ul.menu .selected:before { top: 75%; } -/* 2nd frame */ -#screen.frameStartMenu ul { +ul#startMenu { width: 7em; } + +ul#nameMenu { + width: 6em; +} diff --git a/src/screen.js b/src/screen.js index 0c5ecea..4a735d5 100644 --- a/src/screen.js +++ b/src/screen.js @@ -5,6 +5,7 @@ function Screen(dom) { appendText: appendText, clear: clear, frame: frame, + input: input, markAsRead: markAsRead, menu: menu, select: select, @@ -17,7 +18,12 @@ function Screen(dom) { } function clear(elem) { - if(elem != undefined) { + if(elem == 'text') { + var textElem = findTextZone(); + if(textElem != undefined) { + root.removeChild(textElem); + } + } else if(elem != undefined) { root.removeChild(elem); } else { dom.clear(root); @@ -28,8 +34,12 @@ function Screen(dom) { root.className = "frame" + n; } + function findTextZone() { + return root.getElementsByClassName('text')[0]; + } + function getTextZone() { - var textZone = root.getElementsByClassName('text')[0]; + var textZone = findTextZone(); if(textZone == undefined) { textZone = dom.make('div', {class: ['text', 'framed']}, [ dom.make('p') @@ -39,6 +49,17 @@ function Screen(dom) { return textZone } + function input(size) { + var elem = dom.make('input', { + type: 'text', + class: 'framed', + maxlength: size, + size: size + }); + show(elem); + return elem; + } + function markAsRead(yes) { if(yes == undefined) { yes = true; @@ -46,15 +67,15 @@ function Screen(dom) { getTextZone().classList[yes ? 'add' : 'remove']('read'); } - function menu(entries) { + function menu(name, entries) { var domEntries = []; for(var i = 0; i < entries.length; i++) { domEntries.push(dom.make('li', { - class: i == 0 ? 'selected' : [], + class: [entries].concat(i == 0 ? ['selected'] : []), textContent: entries[i].label }, [])); } - var ul = dom.make('ul', {class: ['menu', 'framed']}, domEntries); + var ul = dom.make('ul', {class: ['menu', 'framed'], id: name}, domEntries); root.appendChild(ul); return ul; } diff --git a/src/ui.js b/src/ui.js index 9e58236..50ed967 100644 --- a/src/ui.js +++ b/src/ui.js @@ -9,6 +9,7 @@ function UI(async, buttons, screen, session) { return { animation: animation, + ask: ask, cinematic: cinematic, frame: frame, menu: menu, @@ -54,6 +55,11 @@ function UI(async, buttons, screen, session) { }; } + function close(elem) { + buttons.pop(); + screen.clear(elem); + } + function frame(id) { screen.clear(); screen.frame(id); @@ -61,19 +67,68 @@ function UI(async, buttons, screen, session) { function menu(config) { var cursor = 0; - var m = screen.menu(config.entries); + var m = screen.menu(config.name + 'Menu', config.entries); var sync = function() { screen.select(cursor); }; var mapping = { - 'Up': function() { cursor = Math.max(0, cursor - 1); sync(); }, - 'Down': function() { cursor = Math.min(config.entries.length - 1, cursor + 1); sync(); }, - 'A': function() { config.entries[cursor].action(); } + Up: function() { + cursor = (config.entries.length + cursor - 1) % config.entries.length; + sync(); + }, + Down: function() { + cursor = (cursor + 1) % config.entries.length; + sync(); + }, + A: function() { + var entry = config.entries[cursor]; + if(entry.action != undefined) { + entry.action(m); + } else if(entry.quit != undefined) { + close(m); + entry.quit(); + } + } }; if(config.cancel != undefined) { - mapping['B'] = function() { buttons.pop(); screen.clear(m); config.cancel(); } + mapping['B'] = function() { close(m); config.cancel(); } } buttons.push(mapping); } + function ask(config) { + var menuConfig = {entries: [], name: config.name}; + var apply = function(f, val) { return function() { return f(val); }; }; + return function(f) { + for(var i = 0; i < config.entries.length; i++) { + var entry; + if(config.entries[i].label != undefined) { + entry = {label: config.entries[i].label, quit: apply(f, config.entries[i].value)}; + } else { + entry = {label: '___', action: promptValue(config.entries[i].size, f)}; + } + menuConfig.entries.push(entry); + } + menu(menuConfig); + }; + } + + function promptValue(size, f) { + return function(m) { + var input = screen.input(size); + input.focus(); + buttons.push({}); + input.addEventListener('keydown', function(event) { + switch(event.key) { + case 'Escape': close(input); break; + case 'Enter': + var value = input.value; + close(input); + close(m); + return f(value); + } + }); + }; + } + function textScreen(message) { var characters = message.split(''); var frames = [];