sleeb

an experimental input method
git clone https://tongong.net/git/sleeb.git
Log | Files | Refs | README

commit a89eda6a1ae8f0ea25e55309cb9e1de9182cd202
parent c68d951cbe384c42a6510ae93b3aabfb6eb0aeeb
Author: tongong <tongong@gmx.net>
Date:   Thu, 13 Jan 2022 12:02:07 +0100

added gesture recognition

Diffstat:
Asrc/components/key-boxes.js | 50++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/components/page-input.js | 36+++++++++++-------------------------
Asrc/modules/input.js | 48++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/styles.css | 10++++++++++
4 files changed, 119 insertions(+), 25 deletions(-)

diff --git a/src/components/key-boxes.js b/src/components/key-boxes.js @@ -0,0 +1,50 @@ +const m = require("mithril"); +const input = require("../modules/input.js"); + +/* inputCallback: + * expects one argument: char to input + */ +module.exports = (vnode) => { + let cb = vnode.attrs.inputCallback; + let active = [false, false, false]; + // contains indizes of pressed key in the order in which they were pressed + let pressed = []; + // gestures that are not processed yet + let gestures = []; + return { + oncreate: () => { + document.onkeydown = (e) => { + let index = input.keys.indexOf(e.key); + if (!e.repeat && index != -1) { + active[index] = true; + pressed.push(index); + m.redraw(); + } + } + document.onkeyup = (e) => { + let index = input.keys.indexOf(e.key); + if (index != -1) { + active[index] = false; + if (active.every(e => !e)) { + gestures.push(input.pressed2gesture(pressed)); + pressed = []; + let charMaybe = input.gestures2char(gestures); + if (charMaybe) { + cb(charMaybe); + gestures = []; + } + } + m.redraw(); + } + } + }, + view: () => m(".keyBoxWrapWrap", + m(".keyBoxWrap", [0, 1, 2].map( + i => m(".keyBox", { + class: active[i] ? "keyBoxHighlight" : "" + }) + )), + m(".keyBoxHint", gestures.map(e => "G" + e).join(" ")) + ) + } +}; diff --git a/src/components/page-input.js b/src/components/page-input.js @@ -1,31 +1,17 @@ const m = require("mithril"); - -// maybe add a configuration option for this later -const keys = ["j", "k", "l"]; +const keyBoxes = require("./key-boxes.js"); module.exports = () => { - let active = [false, false, false]; + let written = ""; + let ongesture = (g) => { + written += g; + } return { - oncreate: () => { - document.onkeydown = (e) => { - if (!e.repeat && keys.indexOf(e.key) != -1) { - active[keys.indexOf(e.key)] = true; - m.redraw(); - } - } - document.onkeyup = (e) => { - if (keys.indexOf(e.key) != -1) { - active[keys.indexOf(e.key)] = false; - m.redraw(); - } - } - }, - view: () => { - return m(".keyBoxWrap", [0, 1, 2].map( - i => m(".keyBox", { - class: active[i] ? "keyBoxHighlight" : "" - }) - )); - } + view: () => m("div", + m("div", {style: "height:40%;width:100%"}, written), + m("div", {style: "height:60%;width:100%"}, + m(keyBoxes, {inputCallback: ongesture}) + ) + ) } }; diff --git a/src/modules/input.js b/src/modules/input.js @@ -0,0 +1,48 @@ +// maybe add a configuration option for this later +const keys = ["j", "k", "l"]; + +/* pressed is an array of pressed indizes from one gesture */ +function pressed2gesture(pressed) { + if (pressed.length == 1) return pressed[0] + 7; + else { + let m = [ + [0, 1, 5], + [2, 0, 3], + [6, 4, 0] + ]; + return m[pressed[0]][pressed[1]]; + } +} + +// returns false if gestures are not enough to create a character +function gestures2char(gestures) { + if (gestures.length == 0) return false; + if (gestures.length == 1) { + switch (gestures[0]) { + case 7: + return " "; + case 8: + return "-"; + case 9: + return "."; + default: + return false; + } + } + let m = [ + "abcdef", + "ghijkl", + "mnopqr", + "stuvwx", + "yz0123", + "456789" + ]; + return m[gestures[0] - 1][gestures[1] - 1]; +} + + +module.exports = { + keys, + pressed2gesture, + gestures2char +} diff --git a/src/styles.css b/src/styles.css @@ -58,6 +58,11 @@ h1 { /* key visualization boxes */ +.keyBoxWrapWrap { + width: 100%; + height: 100%; + position: relative; +} .keyBoxWrap { height: 100%; width: 100%; @@ -75,3 +80,8 @@ h1 { .keyBoxHighlight { background-color: #f08700; } +.keyBoxHint { + position: absolute; + top: 0; + right: 0; +}