exports.input = function(options) { options = options||{}; var text = options.text; if ("string"!=typeof text) text=""; let settings = require('Storage').readJSON('dragboard.json',1)||{} var R = Bangle.appRect; const paramToColor = (param) => g.toColor(`#${settings[param].toString(16).padStart(3,0)}`); var BGCOLOR = g.theme.bg; var HLCOLOR = settings.Highlight ? paramToColor("Highlight") : g.theme.fg; var ABCCOLOR = settings.ABC ? paramToColor("ABC") : g.toColor(1,0,0);//'#FF0000'; var NUMCOLOR = settings.Num ? paramToColor("Num") : g.toColor(0,1,0);//'#00FF00'; var BIGFONT = '6x8:3'; var BIGFONTWIDTH = parseInt(BIGFONT.charAt(0)*parseInt(BIGFONT.charAt(-1))); var SMALLFONT = '6x8:1'; var SMALLFONTWIDTH = parseInt(SMALLFONT.charAt(0)*parseInt(SMALLFONT.charAt(-1))); var ABC = 'abcdefghijklmnopqrstuvwxyz'.toUpperCase(); var ABCPADDING = ((R.x+R.w)-6*ABC.length)/2; var NUM = ' 1234567890!?,.- '; var NUMHIDDEN = ' 1234567890!?,.- '; var NUMPADDING = ((R.x+R.w)-6*NUM.length)/2; var rectHeight = 40; var delSpaceLast; function drawAbcRow() { g.clear(); try { // Draw widgets if they are present in the current app. if (WIDGETS) Bangle.drawWidgets(); } catch (_) {} g.setFont(SMALLFONT); g.setColor(ABCCOLOR); g.setFontAlign(-1, -1, 0); g.drawString(ABC, ABCPADDING, (R.y+R.h)/2); g.fillRect(0, (R.y+R.h)-26, (R.x+R.w), (R.y+R.h)); } function drawNumRow() { g.setFont(SMALLFONT); g.setColor(NUMCOLOR); g.setFontAlign(-1, -1, 0); g.drawString(NUM, NUMPADDING, (R.y+R.h)/4); g.fillRect(NUMPADDING, (R.y+R.h)-rectHeight*4/3, (R.x+R.w)-NUMPADDING, (R.y+R.h)-rectHeight*2/3); } function updateTopString() { g.setColor(BGCOLOR); g.fillRect(0,4+20,176,13+20); g.setColor(0.2,0,0); var rectLen = text.length<27? text.length*6:27*6; g.fillRect(3,4+20,5+rectLen,13+20); g.setColor(0.7,0,0); g.fillRect(rectLen+5,4+20,rectLen+10,13+20); g.setColor(1,1,1); g.setFontAlign(-1, -1, 0); g.drawString(text.length<=27? text.substr(-27, 27) : '<- '+text.substr(-24,24), 5, 5+20); } var abcHL; var abcHLPrev = -10; var numHL; var numHLPrev = -10; var type = ''; var typePrev = ''; var largeCharOffset = 6; function resetChars(char, HLPrev, typePadding, heightDivisor, rowColor) { "ram"; // Small character in list g.setColor(rowColor); g.setFont(SMALLFONT); g.setFontAlign(-1, -1, 0); g.drawString(char, typePadding + HLPrev*6, (R.y+R.h)/heightDivisor); // Large character g.setColor(BGCOLOR); g.fillRect(0,(R.y+R.h)/3,176,(R.y+R.h)/3+24); //g.drawString(charSet.charAt(HLPrev), typePadding + HLPrev*6 -largeCharOffset, (R.y+R.h)/3);; //Old implementation where I find the shape and place of letter to remove instead of just a rectangle. // mark in the list } function showChars(char, HL, typePadding, heightDivisor) { "ram"; // mark in the list g.setColor(HLCOLOR); g.setFont(SMALLFONT); g.setFontAlign(-1, -1, 0); if (char != 'del' && char != 'space') g.drawString(char, typePadding + HL*6, (R.y+R.h)/heightDivisor); // show new large character g.setFont(BIGFONT); g.drawString(char, typePadding + HL*6 -largeCharOffset, (R.y+R.h)/3); g.setFont(SMALLFONT); } function initDraw() { //var R = Bangle.appRect; // To make sure it's properly updated. Not sure if this is needed. drawAbcRow(); drawNumRow(); updateTopString(); } initDraw(); //setTimeout(initDraw, 0); // So Bangle.appRect reads the correct environment. It would draw off to the side sometimes otherwise. function changeCase(abcHL) { if (settings.uppercase) return; g.setColor(BGCOLOR); g.setFontAlign(-1, -1, 0); g.drawString(ABC, ABCPADDING, (R.y+R.h)/2); if (ABC.charAt(abcHL) == ABC.charAt(abcHL).toUpperCase()) ABC = ABC.toLowerCase(); else ABC = ABC.toUpperCase(); g.setColor(ABCCOLOR); g.drawString(ABC, ABCPADDING, (R.y+R.h)/2); } return new Promise((resolve,reject) => { // Interpret touch input Bangle.setUI({ mode: 'custom', back: ()=>{ Bangle.setUI(); g.clearRect(Bangle.appRect); resolve(text); }, drag: function(event) { "ram"; // ABCDEFGHIJKLMNOPQRSTUVWXYZ // Choose character by draging along red rectangle at bottom of screen if (event.y >= ( (R.y+R.h) - 12 )) { // Translate x-position to character if (event.x < ABCPADDING) { abcHL = 0; } else if (event.x >= 176-ABCPADDING) { abcHL = 25; } else { abcHL = Math.floor((event.x-ABCPADDING)/6); } // Datastream for development purposes //print(event.x, event.y, event.b, ABC.charAt(abcHL), ABC.charAt(abcHLPrev)); // Unmark previous character and mark the current one... // Handling switching between letters and numbers/punctuation if (typePrev != 'abc') resetChars(NUM.charAt(numHLPrev), numHLPrev, NUMPADDING, 4, NUMCOLOR); if (abcHL != abcHLPrev) { resetChars(ABC.charAt(abcHLPrev), abcHLPrev, ABCPADDING, 2, ABCCOLOR); showChars(ABC.charAt(abcHL), abcHL, ABCPADDING, 2); } // Print string at top of screen if (event.b == 0) { text = text + ABC.charAt(abcHL); updateTopString(); // Autoswitching letter case if (ABC.charAt(abcHL) == ABC.charAt(abcHL).toUpperCase()) changeCase(abcHL); } // Update previous character to current one abcHLPrev = abcHL; typePrev = 'abc'; } // 12345678901234567890 // Choose number or puctuation by draging on green rectangle else if ((event.y < ( (R.y+R.h) - 12 )) && (event.y > ( (R.y+R.h) - 52 ))) { // Translate x-position to character if (event.x < NUMPADDING) { numHL = 0; } else if (event.x > 176-NUMPADDING) { numHL = NUM.length-1; } else { numHL = Math.floor((event.x-NUMPADDING)/6); } // Datastream for development purposes //print(event.x, event.y, event.b, NUM.charAt(numHL), NUM.charAt(numHLPrev)); // Unmark previous character and mark the current one... // Handling switching between letters and numbers/punctuation if (typePrev != 'num') resetChars(ABC.charAt(abcHLPrev), abcHLPrev, ABCPADDING, 2, ABCCOLOR); if (numHL != numHLPrev) { resetChars(NUM.charAt(numHLPrev), numHLPrev, NUMPADDING, 4, NUMCOLOR); showChars(NUM.charAt(numHL), numHL, NUMPADDING, 4); } // Print string at top of screen if (event.b == 0) { g.setColor(HLCOLOR); // Backspace if releasing before list of numbers/punctuation if (event.x < NUMPADDING) { // show delete sign showChars('del', 0, (R.x+R.w)/2 +6 -27 , 4); delSpaceLast = 1; text = text.slice(0, -1); updateTopString(); //print(text); } // Append space if releasing after list of numbers/punctuation else if (event.x > (R.x+R.w)-NUMPADDING) { //show space sign showChars('space', 0, (R.x+R.w)/2 +6 -6*3*5/2 , 4); delSpaceLast = 1; text = text + ' '; updateTopString(); //print(text); } // Append selected number/punctuation else { text = text + NUMHIDDEN.charAt(numHL); updateTopString(); // Autoswitching letter case if ((text.charAt(text.length-1) == '.') || (text.charAt(text.length-1) == '!')) changeCase(); } } // Update previous character to current one numHLPrev = numHL; typePrev = 'num'; } // Make a space or backspace by swiping right or left on screen above green rectangle else if (event.y > 20+4) { if (event.b == 0) { g.setColor(HLCOLOR); if (event.x < (R.x+R.w)/2) { resetChars(ABC.charAt(abcHLPrev), abcHLPrev, ABCPADDING, 2, ABCCOLOR); resetChars(NUM.charAt(numHLPrev), numHLPrev, NUMPADDING, 4, NUMCOLOR); // show delete sign showChars('del', 0, (R.x+R.w)/2 +6 -27 , 4); delSpaceLast = 1; // Backspace and draw string upper right corner text = text.slice(0, -1); updateTopString(); if (text.length==0) changeCase(abcHL); //print(text, 'undid'); } else { resetChars(ABC.charAt(abcHLPrev), abcHLPrev, ABCPADDING, 2, ABCCOLOR); resetChars(NUM.charAt(numHLPrev), numHLPrev, NUMPADDING, 4, NUMCOLOR); //show space sign showChars('space', 0, (R.x+R.w)/2 +6 -6*3*5/2 , 4); delSpaceLast = 1; // Append space and draw string upper right corner text = text + NUMHIDDEN.charAt(0); updateTopString(); //print(text, 'made space'); } } } } }); }); };