2022-05-05 20:16:06 +00:00
//Multitap logic originally from here: http://www.espruino.com/Morse+Code+Texting
exports . input = function ( options ) {
2022-05-11 18:11:08 +00:00
options = options || { } ;
2022-05-05 20:16:06 +00:00
var text = options . text ;
if ( "string" != typeof text ) text = "" ;
2022-05-10 12:23:41 +00:00
var settings = require ( 'Storage' ) . readJSON ( "kbmulti.settings.json" , true ) || { } ;
2022-05-11 18:50:02 +00:00
if ( settings . firstLaunch === undefined ) { settings . firstLaunch = true ; }
2022-05-10 19:20:43 +00:00
if ( settings . charTimeout === undefined ) { settings . charTimeout = 500 ; }
2022-05-11 18:17:15 +00:00
if ( settings . showHelpBtn === undefined ) { settings . showHelpBtn = true ; }
2022-05-10 12:23:41 +00:00
2022-05-05 20:16:06 +00:00
var fontSize = "6x15" ;
var Layout = require ( "Layout" ) ;
var letters = {
"1" : ".,!?1" , "2" : "ABC2" , "3" : "DEF3" ,
"4" : "GHI4" , "5" : "JKL5" , "6" : "MNO6" ,
2022-05-09 12:43:38 +00:00
"7" : "PQRS7" , "8" : "TUV80" , "9" : "WXYZ9" ,
2022-05-05 20:16:06 +00:00
} ;
2022-05-14 22:24:18 +00:00
var helpMessage = 'Swipe:\nRight: Space\nLeft:Backspace\nUp/Down: Caps lock\n' ;
2022-05-05 20:16:06 +00:00
var charTimeout ; // timeout after a key is pressed
var charCurrent ; // current character (index in letters)
var charIndex ; // index in letters[charCurrent]
var caps = true ;
var layout ;
2022-05-11 17:49:40 +00:00
function displayText ( charTimeout ) {
2022-05-05 20:16:06 +00:00
layout . clear ( layout . text ) ;
2022-05-11 18:38:41 +00:00
layout . text . label = text . slice ( settings . showHelpBtn ? - 11 : - 13 ) + ( charTimeout ? " " : "_" ) ; // Implemented marker here.
2022-05-05 20:16:06 +00:00
layout . render ( layout . text ) ;
}
function backspace ( ) {
// remove the timeout if we had one
if ( charTimeout !== undefined ) {
clearTimeout ( charTimeout ) ;
charTimeout = undefined ;
}
text = text . slice ( 0 , - 1 ) ;
newCharacter ( ) ;
}
function setCaps ( ) {
caps = ! caps ;
for ( var key in letters ) {
layout [ key ] . label = caps ? letters [ key ] . toUpperCase ( ) : letters [ key ] . toLowerCase ( ) ;
}
layout . render ( ) ;
}
function newCharacter ( ch ) {
displayText ( ) ;
charCurrent = ch ;
charIndex = 0 ;
}
function onKeyPad ( key ) {
// remove the timeout if we had one
if ( charTimeout !== undefined ) {
clearTimeout ( charTimeout ) ;
charTimeout = undefined ;
}
// work out which char was pressed
if ( key == charCurrent ) {
charIndex = ( charIndex + 1 ) % letters [ charCurrent ] . length ;
text = text . slice ( 0 , - 1 ) ;
} else {
newCharacter ( key ) ;
}
var newLetter = letters [ charCurrent ] [ charIndex ] ;
text += ( caps ? newLetter . toUpperCase ( ) : newLetter . toLowerCase ( ) ) ;
// set a timeout
charTimeout = setTimeout ( function ( ) {
charTimeout = undefined ;
newCharacter ( ) ;
2022-05-10 12:23:41 +00:00
} , settings . charTimeout ) ;
2022-05-11 17:49:40 +00:00
displayText ( charTimeout ) ;
2022-05-05 20:16:06 +00:00
}
2022-05-09 12:43:38 +00:00
function onSwipe ( dirLeftRight , dirUpDown ) {
if ( dirUpDown ) {
setCaps ( ) ;
} else if ( dirLeftRight == 1 ) {
text += ' ' ;
newCharacter ( ) ;
} else if ( dirLeftRight == - 1 ) {
backspace ( ) ;
}
}
2022-05-10 12:23:41 +00:00
function onHelp ( resolve , reject ) {
Bangle . removeListener ( "swipe" , onSwipe ) ;
E . showPrompt (
helpMessage , { title : "Help" , buttons : { "Ok" : true } }
) . then ( function ( v ) {
Bangle . on ( 'swipe' , onSwipe ) ;
generateLayout ( resolve , reject ) ;
layout . render ( ) ;
} ) ;
}
2022-05-09 12:43:38 +00:00
2022-05-10 12:23:41 +00:00
function generateLayout ( resolve , reject ) {
2022-05-05 20:16:06 +00:00
layout = new Layout ( {
2022-05-10 12:23:41 +00:00
type : "v" , c : [
{ type : "h" , c : [
{ type : "txt" , font : "12x20" , label : text . slice ( - 12 ) , id : "text" , fillx : 1 } ,
2022-05-11 16:23:31 +00:00
( settings . showHelpBtn ? { type : "btn" , font : '6x8' , label : '?' , cb : l => onHelp ( resolve , reject ) , filly : 1 } : { } ) ,
2022-05-10 12:23:41 +00:00
] } ,
{ type : "h" , c : [
{ type : "btn" , font : fontSize , label : letters [ 1 ] , cb : l => onKeyPad ( 1 ) , id : '1' , fillx : 1 , filly : 1 } ,
{ type : "btn" , font : fontSize , label : letters [ 2 ] , cb : l => onKeyPad ( 2 ) , id : '2' , fillx : 1 , filly : 1 } ,
{ type : "btn" , font : fontSize , label : letters [ 3 ] , cb : l => onKeyPad ( 3 ) , id : '3' , fillx : 1 , filly : 1 } ,
] } ,
{ type : "h" , filly : 1 , c : [
{ type : "btn" , font : fontSize , label : letters [ 4 ] , cb : l => onKeyPad ( 4 ) , id : '4' , fillx : 1 , filly : 1 } ,
{ type : "btn" , font : fontSize , label : letters [ 5 ] , cb : l => onKeyPad ( 5 ) , id : '5' , fillx : 1 , filly : 1 } ,
{ type : "btn" , font : fontSize , label : letters [ 6 ] , cb : l => onKeyPad ( 6 ) , id : '6' , fillx : 1 , filly : 1 } ,
] } ,
{ type : "h" , filly : 1 , c : [
{ type : "btn" , font : fontSize , label : letters [ 7 ] , cb : l => onKeyPad ( 7 ) , id : '7' , fillx : 1 , filly : 1 } ,
{ type : "btn" , font : fontSize , label : letters [ 8 ] , cb : l => onKeyPad ( 8 ) , id : '8' , fillx : 1 , filly : 1 } ,
{ type : "btn" , font : fontSize , label : letters [ 9 ] , cb : l => onKeyPad ( 9 ) , id : '9' , fillx : 1 , filly : 1 } ,
] } ,
]
2022-05-05 20:16:06 +00:00
} , { back : ( ) => {
2022-05-11 18:38:41 +00:00
// charTimeout = undefined; // Tried this to see if it would stop the text from being drawn after closing keyboard when doing it too soon after pressing a key. It didn't help. This problem goes back to how I've implemented the marker above.
2022-05-05 20:16:06 +00:00
Bangle . setUI ( ) ;
2022-05-09 12:43:38 +00:00
Bangle . removeListener ( "swipe" , onSwipe ) ;
2022-05-05 20:16:06 +00:00
g . clearRect ( Bangle . appRect ) ;
resolve ( text ) ;
} } ) ;
2022-05-10 12:23:41 +00:00
}
return new Promise ( ( resolve , reject ) => {
2022-05-05 20:16:06 +00:00
g . clearRect ( Bangle . appRect ) ;
2022-05-11 18:50:02 +00:00
if ( settings . firstLaunch ) {
2022-05-10 12:23:41 +00:00
onHelp ( resolve , reject ) ;
settings . firstLaunch = false ;
require ( 'Storage' ) . writeJSON ( "kbmulti.settings.json" , settings ) ;
} else {
generateLayout ( resolve , reject ) ;
2022-05-11 18:01:49 +00:00
displayText ( true ) ;
2022-05-10 12:23:41 +00:00
Bangle . on ( 'swipe' , onSwipe ) ;
layout . render ( ) ;
}
2022-05-05 20:16:06 +00:00
} ) ;
2022-05-09 12:43:38 +00:00
} ;