diff --git a/js/term/buttons.js b/js/term/buttons.js new file mode 100644 index 0000000..ceb5e69 --- /dev/null +++ b/js/term/buttons.js @@ -0,0 +1,59 @@ +const { qs } = require('../utils') + +module.exports = function initButtons (input) { + let container = qs('#action-buttons') + + // button labels + let labels = [] + + // button elements + let buttons = [] + + // add a button element + let pushButton = function pushButton () { + let button = document.createElement('button') + button.classList.add('action-button') + button.setAttribute('data-n', buttons.length) + buttons.push(button) + container.appendChild(button) + + button.addEventListener('click', e => { + // might as well use the attribute ¯\_(ツ)_/¯ + let index = +button.getAttribute('data-n') + input.sendButton(index) + }) + + return button + } + + // remove a button element + let popButton = function popButton () { + let button = buttons.pop() + button.parentNode.removeChild(button) + } + + // sync with DOM + let update = function updateButtons () { + console.log(labels) + if (labels.length > buttons.length) { + for (let i = buttons.length; i < labels.length; i++) { + pushButton() + } + } else if (buttons.length > labels.length) { + for (let i = labels.length; i < buttons.length; i++) { + popButton() + } + } + + for (let i = 0; i < labels.length; i++) { + let label = labels[i].trim() + let button = buttons[i] + button.textContent = label || '\u00a0' // label or nbsp + if (!label) { + button.classList.add('inactive') + } + } + } + + return { update, labels } +} diff --git a/js/term/index.js b/js/term/index.js index 6600abd..7f4337c 100644 --- a/js/term/index.js +++ b/js/term/index.js @@ -6,6 +6,7 @@ const TermInput = require('./input') const TermUpload = require('./upload') const initSoftKeyboard = require('./soft_keyboard') const attachDebugScreen = require('./debug_screen') +const initButtons = require('./buttons') /** Init the terminal sub-module - called from HTML */ module.exports = function (opts) { @@ -17,6 +18,13 @@ module.exports = function (opts) { screen.conn = conn input.termUpload = termUpload + const buttons = initButtons(input) + screen.on('button-labels', labels => { + // TODO: don't use pointers for this + buttons.labels.splice(0, buttons.labels.length, ...labels) + buttons.update() + }) + let showSplashTimeout = null let showSplash = (obj, delay = 250) => { clearTimeout(showSplashTimeout) diff --git a/js/term/input.js b/js/term/input.js index c0649d0..1f319c7 100644 --- a/js/term/input.js +++ b/js/term/input.js @@ -242,8 +242,8 @@ module.exports = function (conn, screen) { } /** Send a button event */ - function sendButton (n) { - conn.send('b' + String.fromCharCode(n)) + function sendButton (index) { + conn.send('b' + String.fromCharCode(index + 1)) } const shouldAcceptEvent = function () { @@ -354,13 +354,6 @@ module.exports = function (conn, screen) { function init (opts) { initKeys(opts) - // Button presses - $('#action-buttons button').forEach(s => { - s.addEventListener('click', function (evt) { - sendButton(+this.dataset['n']) - }) - }) - // global mouse state tracking - for motion reporting window.addEventListener('mousedown', evt => { if (evt.button === 0) mb1 = 1 @@ -404,6 +397,7 @@ module.exports = function (conn, screen) { /** Send a literal string message */ sendString, + sendButton, /** Enable alternate key modes (cursors, numpad, fn) */ setAlts: function (cu, np, fn, crlf) { diff --git a/js/term/screen_parser.js b/js/term/screen_parser.js index cd48554..16400a6 100644 --- a/js/term/screen_parser.js +++ b/js/term/screen_parser.js @@ -193,11 +193,9 @@ module.exports = class ScreenParser { qs('title').textContent = `${text} :: ESPTerm` } else if (topic === TOPIC_BUTTONS) { - - // TODO optimize this const count = du(strArray[ci++]) - let buttons = [] + let labels = [] for (let j = 0; j < count; j++) { text = '' while (ci < strArray.length) { @@ -205,17 +203,10 @@ module.exports = class ScreenParser { if (c === '\x01') break text += c } - buttons.push(text) + labels.push(text) } - $('#action-buttons button').forEach((button, i) => { - let label = buttons[i].trim() - // if empty string, use the "dim" effect and put nbsp instead to - // stretch the button vertically - button.innerHTML = label.length ? $.htmlEscape(label) : ' ' - button.style.opacity = label.length ? 1 : 0.2 - }) - + this.screen.emit('button-labels', labels) } else if (topic === TOPIC_BELL) { this.screen.beep() diff --git a/pages/term.php b/pages/term.php index feb3c92..55e26bc 100644 --- a/pages/term.php +++ b/pages/term.php @@ -55,13 +55,7 @@
- +