@@ -177,6 +177,30 @@ namespace microgui {
177177 }
178178 }
179179
180+ /**
181+ * This is from microcode-v2/assets.ts
182+ * TODO: Move this asset into user-interface-base/coreAssets.ts
183+ * and make both microgui and microcode-v2 reference that instead.
184+ */
185+ const btn_delete : Bitmap = bmp `
186+ . . . . . . . . . . . . . . . .
187+ . . . . . . c f f . . . . . . .
188+ . . . . . c . . . f . . . . . .
189+ . . . . c c c f f f f . . . . .
190+ . . . c 1 1 d d d b b f . . . .
191+ . . c c c c c f f f f f f . . .
192+ . . . c b c b c b c c f . . . .
193+ . . . c 1 c d c d c b f d . . .
194+ . . . c 1 c d c d c b f d . . .
195+ . . . c 1 c d c d c b f d . . .
196+ . . . c 1 c d c d c b f d . . .
197+ . . . c 1 1 d d d b b f d . . .
198+ . . . c 1 1 d d d b b f d . . .
199+ . . . . c c c f f f f d . . . .
200+ . . . . . . . . . . . . . . . .
201+ . . . . . . . . . . . . . . . .
202+ `
203+
180204 export enum KeyboardLayouts {
181205 QWERTY ,
182206 NUMERIC
@@ -190,13 +214,14 @@ namespace microgui {
190214 textLen ( ) : number ;
191215 getText ( ) : string ;
192216 shakeText ( ) : void ;
217+ deleteFn ( ) : void ;
193218 }
194219
195220 type KeyboardBtnFn = ( btn : Button , kb : IKeyboard ) => void ;
196221 type SpecialBtnData = { btnRow : number , btnCol : number , behaviour : ( btn : Button , kb : IKeyboard ) => void } ;
197222 type KeyboardLayoutData = {
198223 [ id : number ] : {
199- btnTexts : string [ ] [ ] ,
224+ btnTexts : ( string | Bitmap ) [ ] [ ] ,
200225 defaultBtnBehaviour : KeyboardBtnFn ,
201226 specialBtnBehaviours : SpecialBtnData [ ]
202227 }
@@ -230,21 +255,42 @@ namespace microgui {
230255 btnTexts : [
231256 [ "0" , "1" , "2" , "3" , "4" ] ,
232257 [ "5" , "6" , "7" , "8" , "9" ] ,
233- [ "<-" , "-" , "." , "ENTER" ]
258+ [ btn_delete , "<-" , "-" , "." , "ENTER" ]
234259 ] ,
235- defaultBtnBehaviour : ( btn : Button , kb : IKeyboard ) => {
236- kb . appendText ( btn . state [ 0 ] )
237- } ,
260+ defaultBtnBehaviour : ( btn : Button , kb : IKeyboard ) => { // Default Behaviour: Prevent leading zeroes
261+ const btnChar = btn . state [ 0 ] ;
262+ const txt = kb . getText ( ) ;
263+ const txtLen = txt . length ;
264+
265+ if ( txtLen == 0 ) {
266+ kb . appendText ( btnChar )
267+ return ;
268+ }
269+
270+ // Illegal cases: where there's a "0" or a "-0" and you want to add anything except a '.'
271+ // The decimal point '.' is allowed via the specialBtnBehaviour.
272+ const leadingZeroCase1 = txtLen == 1 && txt [ 0 ] == "0" ;
273+ const leadingZeroCase2 = txtLen == 2 && txt [ 0 ] == "-" && txt [ 1 ] == "0" ;
274+ if ( leadingZeroCase1 || leadingZeroCase2 )
275+ kb . shakeText ( )
276+ else
277+ kb . appendText ( btnChar )
278+
279+ } , // End of: default behaviour: Prevent leading zeroes
238280 specialBtnBehaviours : [
239- { btnRow : 2 , btnCol : 0 , behaviour : ( btn : Button , kb : IKeyboard ) => kb . deletePriorCharacters ( 1 ) } , // Backspace
240- { btnRow : 2 , btnCol : 1 , behaviour : ( btn : Button , kb : IKeyboard ) => {
281+ { btnRow : 2 , btnCol : 0 , behaviour : ( btn : Button , kb : IKeyboard ) => { // btn_delete
282+ kb . deleteFn ( ) ;
283+ }
284+ } , // END OF: btn_delete
285+ { btnRow : 2 , btnCol : 1 , behaviour : ( btn : Button , kb : IKeyboard ) => kb . deletePriorCharacters ( 1 ) } , // Backspace
286+ { btnRow : 2 , btnCol : 2 , behaviour : ( btn : Button , kb : IKeyboard ) => { // Minus symbol: Add a "-", but only if first symbol,
241287 if ( kb . textLen ( ) == 0 )
242288 kb . appendText ( btn . state [ 0 ] )
243289 else
244290 kb . shakeText ( )
245291 }
246- } , // Add a "-", but only if first symbol,
247- { btnRow : 2 , btnCol : 2 , behaviour : ( btn : Button , kb : IKeyboard ) => {
292+ } , // END OF: Minus symbol: Add a "-", but only if first symbol,
293+ { btnRow : 2 , btnCol : 3 , behaviour : ( btn : Button , kb : IKeyboard ) => { // Decimal point
248294 const txt = kb . getText ( ) ;
249295 const len = txt . length ;
250296 const decimalAlreadyPresent = txt . includes ( "." )
@@ -253,16 +299,16 @@ namespace microgui {
253299 else
254300 kb . appendText ( "." )
255301 }
256- } , // Decimal point
257- { btnRow : 2 , btnCol : 3 , behaviour : ( btn : Button , kb : IKeyboard ) => {
302+ } , // END OF: Decimal point
303+ { btnRow : 2 , btnCol : 4 , behaviour : ( btn : Button , kb : IKeyboard ) => { // Enter
258304 const txt = kb . getText ( ) ;
259305 const len = txt . length ;
260306 if ( len > 0 && txt [ len - 1 ] != "-" && txt [ len - 1 ] != "." ) // Last rule could be removed, casting "1." to number is valid.
261307 kb . nextScene ( )
262308 else
263309 kb . shakeText ( )
264310 }
265- } // ENTER
311+ } // END OF: ENTER
266312 ]
267313 }
268314 } ;
@@ -283,20 +329,25 @@ namespace microgui {
283329 private shakingText : boolean ;
284330 private shakeTextCounter : number ;
285331 private shakeStrength : number = 5
332+ private txtColor : number ;
286333
287334 private readonly FRAME_COUNTER_CURSOR_ON = 20 ;
288335 private readonly FRAME_COUNTER_CURSOR_OFF = 60 ;
289336 private readonly MAX_TEXT_LENGTH = 22 ;
290337
291338 private foregroundColor : number ;
339+ private passedDeleteFn : ( ) => void ;
292340
293341 constructor ( opts : {
294342 app : AppInterface ,
295343 layout : KeyboardLayouts ,
296344 cb : ( keyboardText : string ) => void ,
297345 foregroundColor ?: number ,
298346 backgroundColor ?: number ,
299- maxTxtLength ?: number
347+ maxTxtLength ?: number ,
348+ txtColor ?: number ,
349+ deleteFn ?: ( ) => void ,
350+ backBtn ?: ( ) => void
300351 } ) {
301352 super ( opts . app , new GridNavigator ( [ [ ] ] ) ) // GridNavigator setup in startup()
302353 this . text = ""
@@ -319,8 +370,12 @@ namespace microgui {
319370
320371 this . foregroundColor = ( opts . foregroundColor ) ? opts . foregroundColor : 4 ; // Default to orange
321372 this . backgroundColor = ( opts . backgroundColor ) ? opts . backgroundColor : 6 ; // Default to blue
373+
374+ this . txtColor = ( opts . txtColor ) ? opts . txtColor : 1 ;
375+ this . passedDeleteFn = ( opts . deleteFn ) ? opts . deleteFn : ( ) => { } ;
322376 }
323377
378+
324379 startup ( controlSetupFn ?: ( ) => void ) {
325380 super . startup ( controlSetupFn )
326381
@@ -333,25 +388,32 @@ namespace microgui {
333388 const ySpacing = ( this . keyboardBounds . height - charHeight ) / ( data . btnTexts . length ) ;
334389
335390 for ( let row = 0 ; row < data . btnTexts . length ; row ++ ) {
336- const bitmapWidths = data . btnTexts [ row ] . map ( ( txt : string ) => ( charWidth * ( txt . length + 1 ) - 4 ) ) ;
337- const totalWidth : number = bitmapWidths . reduce ( ( total : number , w : number ) => total + w , 0 ) ;
391+ const bitmapWidths = data . btnTexts [ row ] . map ( ( txtOrBitmap : string | Bitmap ) => {
392+ if ( typeof ( txtOrBitmap ) == "string" )
393+ return charWidth * ( txtOrBitmap . length + 1 ) - 4 ;
394+ else
395+ return txtOrBitmap . width + 3 ;
396+ } ) ;
338397
398+ const totalWidth : number = bitmapWidths . reduce ( ( total : number , w : number ) => total + w , 0 ) ;
339399 const xSpacing = ( this . keyboardBounds . width - totalWidth ) / ( bitmapWidths . length + 2 ) ;
340400
341401 let x = - Screen . HALF_WIDTH + xSpacing ;
342402 for ( let col = 0 ; col < data . btnTexts [ row ] . length ; col ++ ) {
403+ const btnState : ( string | Bitmap ) = data . btnTexts [ row ] [ col ] ;
343404 const bitmapWidth = bitmapWidths [ col ]
405+
344406 x += ( bitmapWidths [ col ] + xSpacing ) >> 1
345407 this . btns [ row ] [ col ] =
346408 new Button ( {
347409 parent : null ,
348410 style : ButtonStyles . Transparent ,
349- icon : bitmaps . create ( bitmapWidth , charHeight ) ,
411+ icon : ( typeof ( btnState ) == "string" ) ? bitmaps . create ( bitmapWidth , charHeight ) : btnState ,
350412 ariaId : "" ,
351413 x,
352414 y : - ( charHeight >> 1 ) + ( ySpacing * row ) ,
353415 onClick : ( btn : Button ) => data . defaultBtnBehaviour ( btn , this ) ,
354- state : [ data . btnTexts [ row ] [ col ] ]
416+ state : ( typeof ( btnState ) == "string" ) ? [ btnState ] : [ ]
355417 } )
356418 x += ( bitmapWidths [ col ] + xSpacing ) >> 1
357419 }
@@ -416,6 +478,10 @@ namespace microgui {
416478 }
417479 }
418480
481+ public deleteFn ( ) : void {
482+ this . passedDeleteFn ( ) ;
483+ }
484+
419485 public getText ( ) {
420486 return this . text
421487 }
@@ -539,18 +605,20 @@ namespace microgui {
539605 for ( let i = 0 ; i < this . btns . length ; i ++ ) {
540606 for ( let j = 0 ; j < this . btns [ i ] . length ; j ++ ) {
541607 const btn = this . btns [ i ] [ j ] ;
542- const btnText = btn . state [ 0 ] ;
608+ const btnText = ( btn . state . length > 0 ) ? btn . state [ 0 ] : null ;
543609
544610 const x = ( screen ( ) . width / 2 ) + btn . xfrm . localPos . x - ( btn . icon . width / 2 ) + 1
545611 const y = ( screen ( ) . height / 2 ) + btn . xfrm . localPos . y + charHeight - 12
546612
547613 btn . draw ( )
548- screen ( ) . print (
549- btnText ,
550- x ,
551- y ,
552- white
553- )
614+
615+ if ( btnText )
616+ screen ( ) . print (
617+ btnText ,
618+ x ,
619+ y ,
620+ this . txtColor
621+ )
554622 }
555623 }
556624
@@ -563,6 +631,10 @@ namespace microgui {
563631 const KEYBOARD_FRAME_COUNTER_CURSOR_OFF = 40 ;
564632 const KEYBOARD_MAX_TEXT_LENGTH = 20
565633
634+
635+ /**
636+ * Deprecated.
637+ */
566638 export class KeyboardMenu extends CursorSceneWithPriorPage {
567639 private static WIDTHS : number [ ] = [ 10 , 10 , 10 , 10 , 4 ]
568640 private btns : Button [ ] [ ]
@@ -1099,3 +1171,4 @@ namespace microgui {
10991171 }
11001172 }
11011173}
1174+
0 commit comments