From cfb737e1c0c49ee7929d259a8a555698d8a3a254 Mon Sep 17 00:00:00 2001 From: thyttan <97237430+thyttan@users.noreply.github.com> Date: Mon, 2 May 2022 01:36:24 +0200 Subject: [PATCH] kbtouch v0.02 - introduce settings for layout... ...and functionality. --- apps/kbtouch/ChangeLog | 1 + apps/kbtouch/README.md | 11 ++++++ apps/kbtouch/lib.js | 81 ++++++++++++++++++++++++++++---------- apps/kbtouch/metadata.json | 5 ++- apps/kbtouch/settings.js | 59 +++++++++++++++++++++++++++ 5 files changed, 135 insertions(+), 22 deletions(-) create mode 100644 apps/kbtouch/settings.js diff --git a/apps/kbtouch/ChangeLog b/apps/kbtouch/ChangeLog index 5560f00bc..17e824c00 100644 --- a/apps/kbtouch/ChangeLog +++ b/apps/kbtouch/ChangeLog @@ -1 +1,2 @@ 0.01: New App! +0.02: Introduced settings to customize the layout and functionality of the keyboard. diff --git a/apps/kbtouch/README.md b/apps/kbtouch/README.md index 513ba9239..07188ff0c 100644 --- a/apps/kbtouch/README.md +++ b/apps/kbtouch/README.md @@ -2,6 +2,17 @@ A library that provides an on-screen keyboard for text input. +## Settings ( -> Apps -> kbtouch ) +Text size - small or big text font. Default=Big. Suggested=Small. + +Offset keyboard - display the keyboard on top, making it faster to see what character you have selected. Default=No. Suggested=Yes. + +Loop around - should the keyboard highlight loop around when going past the edges? Default=Yes. Suggested=No. + +One-to-one input and release to select - should the input correspond directly to discrete areas on the screen, instead of being handled by scaled relative changes in position on swipes? Default=No. Suggested=Yes. + +Speed scaling - how much should a swipe move the highligt on the keyboard? Higher number corresponds to slower movement. Not applicable if using one-to-one input. Default=24. Suggested=15. + ## Usage In your app's metadata, add: diff --git a/apps/kbtouch/lib.js b/apps/kbtouch/lib.js index 3dfdce00c..a1c90795a 100644 --- a/apps/kbtouch/lib.js +++ b/apps/kbtouch/lib.js @@ -69,13 +69,29 @@ var KEYEXTRA = [ String.fromCharCode(27,91,53,126), // 0x84 page up String.fromCharCode(27,91,54,126), // 0x85 page down ]; + +var settings = Object.assign({ + // default values + textSize: 1, + offsetKeyboard: 0, + loopAround: 1, + oneToOne: 0, + speedScaling: 24 +}, require('Storage').readJSON("kbtouch.settings.json", true) || {}); +print(settings); + +//settings = { "textSize": 1, "offsetKeyboard": 0, "oneToOne": 1, +// "speedScaling": 15, "loopAround": 0 /*, "releaseToSelect": 0*/}; + +print(settings); // state const R = Bangle.appRect; var kbx = 0, kby = 0, kbdx = 0, kbdy = 0, kbShift = false, flashToggle = false; -const PX=12, PY=16, DRAGSCALE=24; -var xoff = 3, yoff = g.getHeight()-PY*4; +const PX=12, PY=16, DRAGSCALE=settings.speedScaling; +var xoff = 3, yoff = g.getHeight()-PY*(4+5*settings.offsetKeyboard); function draw() { + "ram"; var map = kbShift ? KEYMAPUPPER : KEYMAPLOWER; //g.drawImage(KEYIMG,0,yoff); g.reset().setFont("6x8:2"); @@ -88,9 +104,9 @@ function draw() { g.drawString(map[1],xoff,yoff+PY); g.drawString(map[2],xoff,yoff+PY*2); g.drawString(map[3],xoff,yoff+PY*3); - var l = g.setFont("6x8:4").wrapString(text+(flashToggle?"_":" "), R.w-8); - if (l.length>2) l=l.slice(-2); - g.drawString(l.join("\n"),R.x+4,R.y+4); + var l = g.setFont(settings.textSize ? "6x8:4":"6x8:2").wrapString(text+(flashToggle?"_":" "), R.w-8); + if (l.length>2+2*settings.textSize) l=l.slice(-(2+2*settings.textSize)); + g.drawString(l.join("\n"),R.x+4,R.y+4 +82*settings.offsetKeyboard); g.flip(); } @@ -104,24 +120,49 @@ function draw() { return new Promise((resolve,reject) => { Bangle.setUI({mode:"custom", drag:e=>{ - kbdx += e.dx; - kbdy += e.dy; - var dx = Math.round(kbdx/DRAGSCALE), dy = Math.round(kbdy/DRAGSCALE); - kbdx -= dx*DRAGSCALE; - kbdy -= dy*DRAGSCALE; - if (dx || dy) { - kbx = (kbx+dx+15)%15; - kby = (kby+dy+4)%4; + if (settings.oneToOne) { + kbx = Math.max(Math.min(Math.floor((e.x-16) / (6*2)) , 13) , 0); + kby = Math.max(Math.min(Math.floor((e.y-120) / (8*2)) , 4) , 0); + //print(e.y, kby, e.x, kbx); + } + + if (!settings.oneToOne) { + kbdx += e.dx; + kbdy += e.dy; + var dx = Math.round(kbdx/DRAGSCALE), dy = Math.round(kbdy/DRAGSCALE); + kbdx -= dx*DRAGSCALE; + kbdy -= dy*DRAGSCALE; + if (dx || dy) { + if (settings.loopAround) { + kbx = (kbx+dx+15)%15; + kby = (kby+dy+4)%4; + } else { + kbx = Math.max(Math.min((kbx+dx),13),0); + kby = Math.max(Math.min((kby+dy),3),0); + } + } + } + draw(); + + if (!e.b && e.y>Bangle.appRect.y && settings.oneToOne /*&& settings.releaseToSelect*/) { + var map = kbShift ? KEYMAPUPPER : KEYMAPLOWER; + var ch = map[kby][kbx]; + if (ch=="\2") kbShift=!kbShift; + else if (ch=="\b") text = text.slice(0,-1); + else text += ch; + Bangle.buzz(20); draw(); } },touch:()=>{ - var map = kbShift ? KEYMAPUPPER : KEYMAPLOWER; - var ch = map[kby][kbx]; - if (ch=="\2") kbShift=!kbShift; - else if (ch=="\b") text = text.slice(0,-1); - else text += ch; - Bangle.buzz(20); - draw(); + if ( !settings.oneToOne /*|| !settings.releaseToSelect*/) { + var map = kbShift ? KEYMAPUPPER : KEYMAPLOWER; + var ch = map[kby][kbx]; + if (ch=="\2") kbShift=!kbShift; + else if (ch=="\b") text = text.slice(0,-1); + else text += ch; + Bangle.buzz(20); + draw(); + } },back:()=>{ clearInterval(flashInterval); Bangle.setUI(); diff --git a/apps/kbtouch/metadata.json b/apps/kbtouch/metadata.json index da8b6c3c6..f6d6d5228 100644 --- a/apps/kbtouch/metadata.json +++ b/apps/kbtouch/metadata.json @@ -1,6 +1,6 @@ { "id": "kbtouch", "name": "Touch keyboard", - "version":"0.01", + "version":"0.02", "description": "A library for text input via onscreen keyboard", "icon": "app.png", "type":"textinput", @@ -9,6 +9,7 @@ "screenshots": [{"url":"screenshot.png"}], "readme": "README.md", "storage": [ - {"name":"textinput","url":"lib.js"} + {"name":"textinput","url":"lib.js"}, + {"name":"kbtouch.settings.js","url":"settings.js"} ] } diff --git a/apps/kbtouch/settings.js b/apps/kbtouch/settings.js new file mode 100644 index 000000000..871cc5d32 --- /dev/null +++ b/apps/kbtouch/settings.js @@ -0,0 +1,59 @@ +(function(back) { + function settings() { + let settings = require('Storage').readJSON("kbtouch.settings.json", true) || {}; + if (settings.textSize===undefined) settings.textSize=1; + if (settings.offsetKeyboard===undefined) settings.offsetKeyboard=0; + if (settings.loopAround===undefined) settings.loopAround=1; + if (settings.oneToOne===undefined) settings.oneToOne=0; + if (settings.speedScaling===undefined) settings.speedScaling=24; + return settings; + } + + function updateSetting(setting, value) { + let settings = require('Storage').readJSON("kbtouch.settings.json", true) || {}; + settings[setting] = value; + require('Storage').writeJSON("kbtouch.settings.json", settings); + } + + var mainmenu = { + "" : { "title" : /*LANG*/"Touch Keyboard" }, + "< Back" : back, + /*LANG*/'Text size': { + value: settings().textSize, + min: 0, max: 1, + format: v => [/*LANG*/"Small",/*LANG*/"Big"][v], + onchange: v => updateSetting("textSize", v) + }, + /*LANG*/'Offset keyboard': { + value: settings().offsetKeyboard, + min: 0, max: 1, + format: v => [/*LANG*/"No",/*LANG*/"Yes"][v], + onchange: v => updateSetting("offsetKeyboard", v) + }, + /*LANG*/'Loop around': { + value: settings().loopAround, + min: 0, max: 1, + format: v => [/*LANG*/"No",/*LANG*/"Yes"][v], + onchange: v => updateSetting("loopAround", v) + }, + /*LANG*/'One-to-one input and release to select': { + value: settings().oneToOne, + min: 0, max: 1, + format: v => [/*LANG*/"No",/*LANG*/"Yes"][v], + onchange: v => updateSetting("oneToOne", v) + }, + /*LANG*/'Speed scaling': { + value: settings().speedScaling, + min: 1, max: 24, step : 1, + format: v => v, + onchange: v => updateSetting("speedScaling", v) + } + ///*LANG*/'Release to select': { + // value: 1|settings().fontSize, + // min: 0, max: 1, + // format: v => [/*LANG*/"No",/*LANG*/"Yes"][v], + // onchange: v => updateSetting("releaseToSelect", v) + //} + }; + E.showMenu(mainmenu); +})