2022-03-01 05:54:27 +00:00
/* Copyright (c) 2022 Bangle.js contributors. See the file LICENSE for copying permission. */
2021-08-25 16:00:44 +00:00
2022-05-24 20:25:44 +00:00
// See Layout.md for documentation
2021-07-27 16:01:21 +00:00
2022-06-09 09:41:03 +00:00
/ * M i n i f y t o ' L a y o u t . m i n . j s ' b y :
* checking out : https : //github.com/espruino/EspruinoDocs
* run : . . / EspruinoDocs / bin / minify . js modules / Layout . js modules / Layout . min . js
2022-06-10 08:19:53 +00:00
* /
2022-06-09 09:41:03 +00:00
2022-11-24 10:19:27 +00:00
function Layout ( layout , options ) {
2021-07-27 16:01:21 +00:00
this . _l = this . l = layout ;
2021-08-25 16:00:44 +00:00
// Do we have >1 physical buttons?
2022-11-24 10:19:27 +00:00
2021-07-27 16:01:21 +00:00
2022-05-23 10:53:25 +00:00
this . options = options || { } ;
this . lazy = this . options . lazy || false ;
2022-11-24 10:19:27 +00:00
this . physBtns = 1 ;
2022-06-29 08:16:45 +00:00
let btnList ;
2021-10-18 10:32:46 +00:00
if ( process . env . HWVERSION != 2 ) {
2022-11-24 10:19:27 +00:00
this . physBtns = 3 ;
2021-10-18 10:32:46 +00:00
// no touchscreen, find any buttons in 'layout'
btnList = [ ] ;
2022-11-24 10:19:27 +00:00
function btnRecurser ( l ) { "ram" ;
2021-10-18 10:32:46 +00:00
if ( l . type == "btn" ) btnList . push ( l ) ;
if ( l . c ) l . c . forEach ( btnRecurser ) ;
}
btnRecurser ( layout ) ;
if ( btnList . length ) { // there are buttons in 'layout'
// disable physical buttons - use them for back/next/select
this . physBtns = 0 ;
this . buttons = btnList ;
this . selectedButton = - 1 ;
}
}
2022-05-23 10:53:25 +00:00
if ( this . options . btns ) {
var buttons = this . options . btns ;
2021-08-25 16:00:44 +00:00
if ( this . physBtns >= buttons . length ) {
// enough physical buttons
2022-06-28 12:39:46 +00:00
this . b = buttons ;
2021-10-27 15:50:16 +00:00
let btnHeight = Math . floor ( Bangle . appRect . h / this . physBtns ) ;
2021-08-25 16:00:44 +00:00
if ( this . physBtns > 2 && buttons . length == 1 )
buttons . unshift ( { label : "" } ) ; // pad so if we have a button in the middle
while ( this . physBtns > buttons . length )
buttons . push ( { label : "" } ) ;
2021-07-27 16:01:21 +00:00
this . _l . width = g . getWidth ( ) - 8 ; // text width
2021-08-25 16:00:44 +00:00
this . _l = { type : "h" , filly : 1 , c : [
2021-07-27 16:01:21 +00:00
this . _l ,
2021-08-25 16:00:44 +00:00
{ type : "v" , pad : 1 , filly : 1 , c : buttons . map ( b => ( b . type = "txt" , b . font = "6x8" , b . height = btnHeight , b . r = 1 , b ) ) }
2021-07-27 16:01:21 +00:00
] } ;
2021-08-25 16:00:44 +00:00
} else {
2021-10-18 10:32:46 +00:00
// add 'soft' buttons
this . _l . width = g . getWidth ( ) - 32 ; // button width
2021-08-25 16:00:44 +00:00
this . _l = { type : "h" , c : [
2021-07-27 16:01:21 +00:00
this . _l ,
2021-10-18 10:32:46 +00:00
{ type : "v" , c : buttons . map ( b => ( b . type = "btn" , b . filly = 1 , b . width = 32 , b . r = 1 , b ) ) }
2021-07-27 16:01:21 +00:00
] } ;
2021-10-18 10:32:46 +00:00
// if we're selecting with physical buttons, add these to the list
if ( btnList ) btnList . push . apply ( btnList , this . _l . c [ 1 ] . c ) ;
2021-07-27 16:01:21 +00:00
}
}
2022-05-23 10:53:25 +00:00
// Link in all buttons/touchscreen/etc
this . setUI ( ) ;
2021-10-20 19:28:28 +00:00
// recurse over layout doing some fixing up if needed
2021-08-25 16:00:44 +00:00
var ll = this ;
2022-11-24 10:19:27 +00:00
function recurser ( l ) { "ram" ;
2021-10-20 19:28:28 +00:00
// add IDs
2021-08-25 16:00:44 +00:00
if ( l . id ) ll [ l . id ] = l ;
2021-10-20 19:28:28 +00:00
// fix type up
2021-09-16 10:27:52 +00:00
if ( ! l . type ) l . type = "" ;
2021-10-20 19:28:28 +00:00
if ( l . c ) l . c . forEach ( recurser ) ;
2021-08-25 16:00:44 +00:00
}
2021-10-20 19:28:28 +00:00
recurser ( this . _l ) ;
2021-10-04 22:45:57 +00:00
this . updateNeeded = true ;
2021-07-27 16:01:21 +00:00
}
2022-05-23 10:53:25 +00:00
Layout . prototype . setUI = function ( ) {
Bangle . setUI ( ) ; // remove all existing input handlers
2022-06-10 08:19:53 +00:00
let uiSet ;
2022-05-23 10:53:25 +00:00
if ( this . buttons ) {
// multiple buttons so we'll jus use back/next/select
2022-10-23 14:12:09 +00:00
Bangle . setUI ( { mode : "updown" , back : this . options . back , remove : this . options . remove } , dir => {
2022-05-23 10:53:25 +00:00
var s = this . selectedButton , l = this . buttons . length ;
if ( dir === undefined && this . buttons [ s ] )
return this . buttons [ s ] . cb ( ) ;
if ( this . buttons [ s ] ) {
delete this . buttons [ s ] . selected ;
this . render ( this . buttons [ s ] ) ;
}
s = ( s + l + dir ) % l ;
if ( this . buttons [ s ] ) {
this . buttons [ s ] . selected = 1 ;
this . render ( this . buttons [ s ] ) ;
}
this . selectedButton = s ;
} ) ;
uiSet = true ;
2021-07-27 16:01:21 +00:00
}
2022-10-23 14:12:09 +00:00
if ( ( this . options . back || this . options . remove ) && ! uiSet ) Bangle . setUI ( { mode : "custom" , back : this . options . back , remove : this . options . remove } ) ;
2022-05-23 10:53:25 +00:00
// physical buttons -> actual applications
if ( this . b ) {
// Handler for button watch events
function pressHandler ( btn , e ) {
if ( e . time - e . lastTime > 0.75 && this . b [ btn ] . cbl )
this . b [ btn ] . cbl ( e ) ;
else
if ( this . b [ btn ] . cb ) this . b [ btn ] . cb ( e ) ;
}
if ( Bangle . btnWatches ) Bangle . btnWatches . forEach ( clearWatch ) ;
Bangle . btnWatches = [ ] ;
if ( this . b [ 0 ] ) Bangle . btnWatches . push ( setWatch ( pressHandler . bind ( this , 0 ) , BTN1 , { repeat : true , edge : - 1 } ) ) ;
if ( this . b [ 1 ] ) Bangle . btnWatches . push ( setWatch ( pressHandler . bind ( this , 1 ) , BTN2 , { repeat : true , edge : - 1 } ) ) ;
if ( this . b [ 2 ] ) Bangle . btnWatches . push ( setWatch ( pressHandler . bind ( this , 2 ) , BTN3 , { repeat : true , edge : - 1 } ) ) ;
2021-07-27 16:01:21 +00:00
}
2022-05-23 10:53:25 +00:00
// Handle touch events on new Bangle.js
if ( process . env . HWVERSION == 2 ) {
function touchHandler ( l , e ) {
if ( l . cb && e . x >= l . x && e . y >= l . y && e . x <= l . x + l . w && e . y <= l . y + l . h ) {
if ( e . type == 2 && l . cbl ) l . cbl ( e ) ; else if ( l . cb ) l . cb ( e ) ;
}
if ( l . c ) l . c . forEach ( n => touchHandler ( n , e ) ) ;
}
Bangle . touchHandler = ( _ , e ) => touchHandler ( this . _l , e ) ;
Bangle . on ( 'touch' , Bangle . touchHandler ) ;
}
}
2021-07-27 16:01:21 +00:00
2021-09-27 15:00:22 +00:00
function prepareLazyRender ( l , rectsToClear , drawList , rects , parentBg ) {
var bgCol = l . bgCol == null ? parentBg : g . toColor ( l . bgCol ) ;
if ( bgCol != parentBg || l . type == "txt" || l . type == "btn" || l . type == "img" || l . type == "custom" ) {
2021-09-15 13:36:17 +00:00
// Hash the layoutObject without including its children
2021-09-27 15:00:22 +00:00
var c = l . c ;
2021-09-15 13:36:17 +00:00
delete l . c ;
2021-09-27 15:00:22 +00:00
var hash = "H" + E . CRC32 ( E . toJS ( l ) ) ; // String keys maintain insertion order
2021-09-15 13:36:17 +00:00
if ( c ) l . c = c ;
2021-07-27 16:01:21 +00:00
2021-09-15 23:53:35 +00:00
if ( ! delete rectsToClear [ hash ] ) {
2021-09-29 13:22:36 +00:00
var r = rects [ hash ] = [ l . x , l . y , l . x + l . w - 1 , l . y + l . h - 1 ] ;
r . bg = parentBg == null ? g . theme . bg : parentBg ;
2021-09-15 13:36:17 +00:00
if ( drawList ) {
drawList . push ( l ) ;
drawList = null ; // Prevent children from being redundantly added to the drawList
2021-08-25 16:00:44 +00:00
}
2021-07-27 16:01:21 +00:00
}
}
2021-09-15 13:36:17 +00:00
2021-09-27 15:00:22 +00:00
if ( l . c ) for ( var ch of l . c ) prepareLazyRender ( ch , rectsToClear , drawList , rects , bgCol ) ;
2021-07-27 16:01:21 +00:00
}
2021-09-15 00:02:09 +00:00
2021-07-27 16:01:21 +00:00
Layout . prototype . render = function ( l ) {
if ( ! l ) l = this . _l ;
2021-10-04 22:45:57 +00:00
if ( this . updateNeeded ) this . update ( ) ;
2021-09-28 10:19:35 +00:00
2022-11-24 10:19:27 +00:00
var gfx = g ; // define locally, because this is faster
function render ( l ) { "ram" ;
gfx . reset ( ) ;
if ( l . col !== undefined ) gfx . setColor ( l . col ) ;
if ( l . bgCol !== undefined ) gfx . setBgColor ( l . bgCol ) . clearRect ( l . x , l . y , l . x + l . w - 1 , l . y + l . h - 1 ) ;
2021-09-16 09:49:14 +00:00
cb [ l . type ] ( l ) ;
}
2021-09-28 10:19:35 +00:00
2021-09-16 09:49:14 +00:00
var cb = {
2021-09-16 10:27:52 +00:00
"" : function ( ) { } ,
2022-11-24 10:19:27 +00:00
"txt" : function ( l ) { "ram" ;
2021-10-04 19:48:43 +00:00
if ( l . wrap ) {
2022-11-24 10:19:27 +00:00
var lines = gfx . setFont ( l . font ) . setFontAlign ( 0 , - 1 ) . wrapString ( l . label , l . w ) ;
var y = l . y + ( ( l . h - gfx . getFontHeight ( ) * lines . length ) >> 1 ) ;
gfx . drawString ( lines . join ( "\n" ) , l . x + ( l . w >> 1 ) , y ) ;
2021-10-04 19:48:43 +00:00
} else {
2022-11-24 10:19:27 +00:00
gfx . setFont ( l . font ) . setFontAlign ( 0 , 0 , l . r ) . drawString ( l . label , l . x + ( l . w >> 1 ) , l . y + ( l . h >> 1 ) ) ;
2021-10-04 19:48:43 +00:00
}
2022-11-24 10:19:27 +00:00
} , "btn" : function ( l ) { "ram" ;
2021-11-04 17:16:02 +00:00
var x = l . x + ( 0 | l . pad ) , y = l . y + ( 0 | l . pad ) ,
w = l . w - ( l . pad << 1 ) , h = l . h - ( l . pad << 1 ) ;
2022-04-29 09:26:44 +00:00
var poly = [
x , y + 4 ,
x + 4 , y ,
x + w - 5 , y ,
x + w - 1 , y + 4 ,
x + w - 1 , y + h - 5 ,
x + w - 5 , y + h - 1 ,
x + 4 , y + h - 1 ,
x , y + h - 5 ,
x , y + 4
2023-09-13 21:25:22 +00:00
] , bg = l . bgCol !== undefined ? l . bgCol : gfx . theme . bg ,
2023-09-14 21:17:43 +00:00
btnborder = l . btnBorderCol !== undefined ? l . btnBorderCol : gfx . theme . fg2 ,
btnface = l . btnFaceCol !== undefined ? l . btnFaceCol : gfx . theme . bg2 ;
2023-01-21 04:54:13 +00:00
if ( l . selected ) {
2023-09-14 20:39:50 +00:00
btnface = gfx . theme . bgH , btnborder = gfx . theme . fgH ;
2023-01-21 04:54:13 +00:00
}
2023-09-13 21:25:22 +00:00
gfx . setColor ( btnface ) . fillPoly ( poly ) . setColor ( btnborder ) . drawPoly ( poly ) ;
2022-11-24 10:19:27 +00:00
if ( l . col !== undefined ) gfx . setColor ( l . col ) ;
2023-09-13 21:25:22 +00:00
if ( l . src ) gfx . setBgColor ( btnface ) . drawImage (
2022-04-29 08:55:31 +00:00
"function" == typeof l . src ? l . src ( ) : l . src ,
2022-04-29 10:16:48 +00:00
l . x + l . w / 2 ,
l . y + l . h / 2 ,
2022-05-03 09:06:10 +00:00
{ scale : l . scale || undefined , rotate : Math . PI * 0.5 * ( l . r || 0 ) }
2022-04-29 08:55:31 +00:00
) ;
2022-11-24 10:19:27 +00:00
else gfx . setFont ( l . font || "6x8:2" ) . setFontAlign ( 0 , 0 , l . r ) . drawString ( l . label , l . x + l . w / 2 , l . y + l . h / 2 ) ;
} , "img" : function ( l ) { "ram" ;
gfx . drawImage (
2022-04-29 08:55:31 +00:00
"function" == typeof l . src ? l . src ( ) : l . src ,
2022-04-29 10:16:48 +00:00
l . x + l . w / 2 ,
l . y + l . h / 2 ,
2022-05-03 09:06:10 +00:00
{ scale : l . scale || undefined , rotate : Math . PI * 0.5 * ( l . r || 0 ) }
2022-04-29 08:55:31 +00:00
) ;
2022-11-24 10:19:27 +00:00
} , "custom" : function ( l ) { "ram" ; l . render ( l ) ;
} , "h" : function ( l ) { "ram" ; l . c . forEach ( render ) ;
} , "v" : function ( l ) { "ram" ; l . c . forEach ( render ) ; }
2021-09-16 09:49:14 +00:00
} ;
2021-07-27 16:01:21 +00:00
2021-09-15 00:02:09 +00:00
if ( this . lazy ) {
2021-09-16 10:27:52 +00:00
// we have to use 'var' here not 'let', otherwise the minifier
// renames vars to the same name, which causes problems as Espruino
// doesn't yet honour the scoping of 'let'
2021-09-15 23:53:35 +00:00
if ( ! this . rects ) this . rects = { } ;
2021-09-16 10:27:52 +00:00
var rectsToClear = this . rects . clone ( ) ;
var drawList = [ ] ;
2021-09-27 15:00:22 +00:00
prepareLazyRender ( l , rectsToClear , drawList , this . rects , null ) ;
2021-09-16 10:27:52 +00:00
for ( var h in rectsToClear ) delete this . rects [ h ] ;
var clearList = Object . keys ( rectsToClear ) . map ( k => rectsToClear [ k ] ) . reverse ( ) ; // Rects are cleared in reverse order so that the original bg color is restored
2022-11-24 10:19:27 +00:00
for ( var r of clearList ) gfx . setBgColor ( r . bg ) . clearRect . apply ( g , r ) ;
2021-09-15 09:58:04 +00:00
drawList . forEach ( render ) ;
2021-09-16 10:27:52 +00:00
} else { // non-lazy
2021-09-15 00:02:09 +00:00
render ( l ) ;
}
2021-07-27 16:01:21 +00:00
} ;
2021-10-06 00:57:10 +00:00
Layout . prototype . forgetLazyState = function ( ) {
this . rects = { } ;
}
2021-07-27 16:01:21 +00:00
Layout . prototype . layout = function ( l ) {
// l = current layout element
2022-11-24 10:19:27 +00:00
var cb = {
"h" : function ( l ) { "ram" ;
2021-09-29 02:16:34 +00:00
var acc _w = l . x + ( 0 | l . pad ) ;
var accfillx = 0 ;
2021-09-16 09:49:14 +00:00
var fillx = l . c && l . c . reduce ( ( a , l ) => a + ( 0 | l . fillx ) , 0 ) ;
2021-09-29 08:20:56 +00:00
if ( ! fillx ) { acc _w += ( l . w - l . _w ) >> 1 ; fillx = 1 ; }
2021-09-29 02:16:34 +00:00
var x = acc _w ;
2021-08-25 16:00:44 +00:00
l . c . forEach ( c => {
2021-09-29 02:16:34 +00:00
c . x = 0 | x ;
acc _w += c . _w ;
accfillx += 0 | c . fillx ;
2021-09-29 08:20:56 +00:00
x = acc _w + Math . floor ( accfillx * ( l . w - l . _w ) / fillx ) ;
2021-09-29 02:16:34 +00:00
c . w = 0 | ( x - c . x ) ;
c . h = 0 | ( c . filly ? l . h - ( l . pad << 1 ) : c . _h ) ;
c . y = 0 | ( l . y + ( 0 | l . pad ) + ( ( 1 + ( 0 | c . valign ) ) * ( l . h - ( l . pad << 1 ) - c . h ) >> 1 ) ) ;
2022-11-24 10:19:27 +00:00
if ( c . c ) cb [ c . type ] ( c ) ;
2021-07-27 16:01:21 +00:00
} ) ;
2022-11-24 10:19:27 +00:00
} ,
"v" : function ( l ) { "ram" ;
2021-09-29 02:16:34 +00:00
var acc _h = l . y + ( 0 | l . pad ) ;
var accfilly = 0 ;
2021-09-16 09:49:14 +00:00
var filly = l . c && l . c . reduce ( ( a , l ) => a + ( 0 | l . filly ) , 0 ) ;
2021-09-29 08:20:56 +00:00
if ( ! filly ) { acc _h += ( l . h - l . _h ) >> 1 ; filly = 1 ; }
2021-09-29 02:16:34 +00:00
var y = acc _h ;
2021-08-25 16:00:44 +00:00
l . c . forEach ( c => {
2021-09-29 02:16:34 +00:00
c . y = 0 | y ;
acc _h += c . _h ;
accfilly += 0 | c . filly ;
2021-09-29 08:20:56 +00:00
y = acc _h + Math . floor ( accfilly * ( l . h - l . _h ) / filly ) ;
2021-09-29 02:16:34 +00:00
c . h = 0 | ( y - c . y ) ;
c . w = 0 | ( c . fillx ? l . w - ( l . pad << 1 ) : c . _w ) ;
c . x = 0 | ( l . x + ( 0 | l . pad ) + ( ( 1 + ( 0 | c . halign ) ) * ( l . w - ( l . pad << 1 ) - c . w ) >> 1 ) ) ;
2022-11-24 10:19:27 +00:00
if ( c . c ) cb [ c . type ] ( c ) ;
2021-07-27 16:01:21 +00:00
} ) ;
}
2022-11-24 10:19:27 +00:00
} ;
2023-01-09 14:21:27 +00:00
if ( cb [ l . type ] ) cb [ l . type ] ( l ) ;
2021-07-27 16:01:21 +00:00
} ;
Layout . prototype . debug = function ( l , c ) {
if ( ! l ) l = this . _l ;
c = c || 1 ;
g . setColor ( c & 1 , c & 2 , c & 4 ) . drawRect ( l . x + c - 1 , l . y + c - 1 , l . x + l . w - c , l . y + l . h - c ) ;
2021-09-23 11:47:12 +00:00
if ( l . pad )
g . drawRect ( l . x + l . pad - 1 , l . y + l . pad - 1 , l . x + l . w - l . pad , l . y + l . h - l . pad ) ;
2021-07-27 16:01:21 +00:00
c ++ ;
2021-08-25 16:00:44 +00:00
if ( l . c ) l . c . forEach ( n => this . debug ( n , c ) ) ;
2021-07-27 16:01:21 +00:00
} ;
Layout . prototype . update = function ( ) {
2021-10-04 22:45:57 +00:00
delete this . updateNeeded ;
2022-11-24 10:19:27 +00:00
var gfx = g ; // define locally, because this is faster
2021-07-27 16:01:21 +00:00
// update sizes
2022-11-24 10:19:27 +00:00
function updateMin ( l ) { "ram" ;
2021-09-16 09:49:14 +00:00
cb [ l . type ] ( l ) ;
if ( l . r & 1 ) { // rotation
var t = l . _w ; l . _w = l . _h ; l . _h = t ;
}
2022-11-24 10:19:27 +00:00
l . _w = Math . max ( l . _w + ( l . pad << 1 ) , 0 | l . width ) ;
l . _h = Math . max ( l . _h + ( l . pad << 1 ) , 0 | l . height ) ;
2021-09-16 09:49:14 +00:00
}
var cb = {
2022-11-24 10:19:27 +00:00
"txt" : function ( l ) { "ram" ;
2021-09-16 09:49:14 +00:00
if ( l . font . endsWith ( "%" ) )
2022-11-24 10:19:27 +00:00
l . font = "Vector" + Math . round ( gfx . getHeight ( ) * l . font . slice ( 0 , - 1 ) / 100 ) ;
2021-10-04 19:48:43 +00:00
if ( l . wrap ) {
l . _h = l . _w = 0 ;
} else {
2022-05-03 09:06:10 +00:00
var m = g . setFont ( l . font ) . stringMetrics ( l . label ) ;
2021-10-18 11:01:40 +00:00
l . _w = m . width ; l . _h = m . height ;
2021-10-04 19:48:43 +00:00
}
2022-11-24 10:19:27 +00:00
} , "btn" : function ( l ) { "ram" ;
2022-04-29 10:16:48 +00:00
if ( l . font && l . font . endsWith ( "%" ) )
2022-11-24 10:19:27 +00:00
l . font = "Vector" + Math . round ( gfx . getHeight ( ) * l . font . slice ( 0 , - 1 ) / 100 ) ;
var m = l . src ? gfx . imageMetrics ( "function" == typeof l . src ? l . src ( ) : l . src ) : gfx . setFont ( l . font || "6x8:2" ) . stringMetrics ( l . label ) ;
2021-11-04 17:16:02 +00:00
l . _h = 16 + m . height ;
l . _w = 20 + m . width ;
2022-11-24 10:19:27 +00:00
} , "img" : function ( l ) { "ram" ;
var m = gfx . imageMetrics ( "function" == typeof l . src ? l . src ( ) : l . src ) , s = l . scale || 1 ; // get width and height out of image
2021-11-04 17:16:02 +00:00
l . _w = m . width * s ;
l . _h = m . height * s ;
2022-11-24 10:19:27 +00:00
} , "" : function ( l ) { "ram" ;
2021-09-16 09:49:14 +00:00
// size should already be set up in width/height
l . _w = 0 ;
l . _h = 0 ;
2022-11-24 10:19:27 +00:00
} , "custom" : function ( l ) { "ram" ;
2021-09-16 09:49:14 +00:00
// size should already be set up in width/height
l . _w = 0 ;
l . _h = 0 ;
2022-11-24 10:19:27 +00:00
} , "h" : function ( l ) { "ram" ;
2021-09-16 09:49:14 +00:00
l . c . forEach ( updateMin ) ;
2021-09-24 21:42:47 +00:00
l . _h = l . c . reduce ( ( a , b ) => Math . max ( a , b . _h ) , 0 ) ;
l . _w = l . c . reduce ( ( a , b ) => a + b . _w , 0 ) ;
2021-09-24 02:21:32 +00:00
if ( l . fillx == null && l . c . some ( c => c . fillx ) ) l . fillx = 1 ;
if ( l . filly == null && l . c . some ( c => c . filly ) ) l . filly = 1 ;
2022-11-24 10:19:27 +00:00
} , "v" : function ( l ) { "ram" ;
2021-09-16 09:49:14 +00:00
l . c . forEach ( updateMin ) ;
2021-09-24 21:42:47 +00:00
l . _h = l . c . reduce ( ( a , b ) => a + b . _h , 0 ) ;
l . _w = l . c . reduce ( ( a , b ) => Math . max ( a , b . _w ) , 0 ) ;
2021-09-24 02:21:32 +00:00
if ( l . fillx == null && l . c . some ( c => c . fillx ) ) l . fillx = 1 ;
if ( l . filly == null && l . c . some ( c => c . filly ) ) l . filly = 1 ;
2021-09-16 09:49:14 +00:00
}
} ;
2021-10-27 15:50:16 +00:00
var l = this . _l ;
2021-07-27 16:01:21 +00:00
updateMin ( l ) ;
2022-11-24 10:19:27 +00:00
delete cb ;
2021-10-27 15:50:16 +00:00
if ( l . fillx || l . filly ) { // fill all
l . w = Bangle . appRect . w ;
l . h = Bangle . appRect . h ;
l . x = Bangle . appRect . x ;
l . y = Bangle . appRect . y ;
} else { // or center
2021-07-27 16:01:21 +00:00
l . w = l . _w ;
l . h = l . _h ;
2021-10-27 15:50:16 +00:00
l . x = ( Bangle . appRect . w - l . w ) >> 1 ;
l . y = Bangle . appRect . y + ( ( Bangle . appRect . h - l . h ) >> 1 ) ;
2021-07-27 16:01:21 +00:00
}
// layout children
this . layout ( l ) ;
} ;
Layout . prototype . clear = function ( l ) {
if ( ! l ) l = this . _l ;
2021-08-25 16:00:44 +00:00
g . reset ( ) ;
if ( l . bgCol !== undefined ) g . setBgColor ( l . bgCol ) ;
g . clearRect ( l . x , l . y , l . x + l . w - 1 , l . y + l . h - 1 ) ;
2021-07-27 16:01:21 +00:00
} ;
2022-04-29 10:28:58 +00:00
exports = Layout ;