@@ -181,6 +181,9 @@ typedef struct {
181
181
*/
182
182
static nbgl_layoutInternal_t gLayout [NB_MAX_LAYOUTS ] = {0 };
183
183
184
+ // current top of stack
185
+ static nbgl_layoutInternal_t * topLayout ;
186
+
184
187
// numbers of touchable controls for the whole page
185
188
static uint8_t nbTouchableControls = 0 ;
186
189
@@ -216,28 +219,23 @@ static bool getLayoutAndLayoutObj(nbgl_obj_t *obj,
216
219
nbgl_layoutInternal_t * * layout ,
217
220
layoutObj_t * * layoutObj )
218
221
{
219
- uint8_t i = NB_MAX_LAYOUTS ;
220
-
221
- // parse all layouts (starting with modals) to find the object
222
+ // only try to find the object on top layout on the stack (the other cannot receive touch
223
+ // events)
222
224
* layout = NULL ;
223
- while (i > 0 ) {
224
- i -- ;
225
- if (gLayout [i ].nbChildren > 0 ) {
226
- uint8_t j ;
227
-
228
- // search index of obj in this layout
229
- for (j = 0 ; j < gLayout [i ].nbUsedCallbackObjs ; j ++ ) {
230
- if (obj == gLayout [i ].callbackObjPool [j ].obj ) {
231
- LOG_DEBUG (LAYOUT_LOGGER ,
232
- "getLayoutAndLayoutObj(): obj found in layout[%d], index = %d, "
233
- "nbUsedCallbackObjs = %d\n" ,
234
- i ,
235
- j ,
236
- gLayout [i ].nbUsedCallbackObjs );
237
- * layout = & gLayout [i ];
238
- * layoutObj = & (gLayout [i ].callbackObjPool [j ]);
239
- return true;
240
- }
225
+ if ((topLayout ) && (topLayout -> isUsed )) {
226
+ uint8_t j ;
227
+
228
+ // search index of obj in this layout
229
+ for (j = 0 ; j < topLayout -> nbUsedCallbackObjs ; j ++ ) {
230
+ if (obj == topLayout -> callbackObjPool [j ].obj ) {
231
+ LOG_DEBUG (LAYOUT_LOGGER ,
232
+ "getLayoutAndLayoutObj(): obj found in layout %p "
233
+ "nbUsedCallbackObjs = %d\n" ,
234
+ topLayout ,
235
+ topLayout -> nbUsedCallbackObjs );
236
+ * layout = topLayout ;
237
+ * layoutObj = & (topLayout -> callbackObjPool [j ]);
238
+ return true;
241
239
}
242
240
}
243
241
}
@@ -376,11 +374,7 @@ static void longTouchCallback(nbgl_obj_t *obj,
376
374
// 4th child of container is the progress bar
377
375
nbgl_progress_bar_t * progressBar = (nbgl_progress_bar_t * ) container -> children [3 ];
378
376
379
- LOG_DEBUG (LAYOUT_LOGGER ,
380
- "longTouchCallback(): eventType = %d, obj = %p, gLayout[1].nbChildren = %d\n" ,
381
- eventType ,
382
- obj ,
383
- gLayout [1 ].nbChildren );
377
+ LOG_DEBUG (LAYOUT_LOGGER , "longTouchCallback(): eventType = %d, obj = %p\n" , eventType , obj );
384
378
385
379
// case of pressing a long press button
386
380
if (eventType == TOUCHING ) {
@@ -505,22 +499,17 @@ static void radioTouchCallback(nbgl_obj_t *obj,
505
499
// callback for spinner ticker
506
500
static void spinnerTickerCallback (void )
507
501
{
508
- nbgl_spinner_t * spinner ;
509
- uint8_t i = 0 ;
510
- nbgl_layoutInternal_t * layout ;
502
+ nbgl_spinner_t * spinner ;
503
+ uint8_t i = 0 ;
511
504
512
- // gLayout[1] is on top of gLayout[0] so if gLayout[1] is active, it must catch the event
513
- if (gLayout [1 ].nbChildren > 0 ) {
514
- layout = & gLayout [1 ];
515
- }
516
- else {
517
- layout = & gLayout [0 ];
505
+ if (!topLayout || !topLayout -> isUsed ) {
506
+ return ;
518
507
}
519
508
520
509
// get index of obj
521
- while (i < layout -> container -> nbChildren ) {
522
- if (layout -> container -> children [i ]-> type == CONTAINER ) {
523
- nbgl_container_t * container = (nbgl_container_t * ) layout -> container -> children [i ];
510
+ while (i < topLayout -> container -> nbChildren ) {
511
+ if (topLayout -> container -> children [i ]-> type == CONTAINER ) {
512
+ nbgl_container_t * container = (nbgl_container_t * ) topLayout -> container -> children [i ];
524
513
if (container -> nbChildren && (container -> children [0 ]-> type == SPINNER )) {
525
514
spinner = (nbgl_spinner_t * ) container -> children [0 ];
526
515
spinner -> position ++ ;
@@ -541,18 +530,10 @@ static void spinnerTickerCallback(void)
541
530
static void animTickerCallback (void )
542
531
{
543
532
nbgl_image_t * image ;
544
- uint8_t i = 0 ;
545
- nbgl_layoutInternal_t * layout ;
546
-
547
- // gLayout[1] is on top of gLayout[0] so if gLayout[1] is active, it must catch the event
548
- if (gLayout [1 ].nbChildren > 0 ) {
549
- layout = & gLayout [1 ];
550
- }
551
- else {
552
- layout = & gLayout [0 ];
553
- }
533
+ uint8_t i = 0 ;
534
+ nbgl_layoutInternal_t * layout = topLayout ;
554
535
555
- if (layout -> animation == NULL ) {
536
+ if (! layout || ! layout -> isUsed || ( layout -> animation == NULL ) ) {
556
537
return ;
557
538
}
558
539
@@ -1081,27 +1062,48 @@ nbgl_layout_t *nbgl_layoutGet(const nbgl_layoutDescription_t *description)
1081
1062
{
1082
1063
nbgl_layoutInternal_t * layout = NULL ;
1083
1064
1084
- // find an empty layout in the proper "layer"
1085
1065
if (description -> modal ) {
1086
- if (gLayout [1 ].nbChildren == 0 ) {
1087
- layout = & gLayout [1 ];
1088
- }
1089
- else if (gLayout [2 ].nbChildren == 0 ) {
1090
- layout = & gLayout [2 ];
1066
+ int i ;
1067
+ // find an empty layout in the array of layouts (0 is reserved for background)
1068
+ for (i = 1 ; i < NB_MAX_LAYOUTS ; i ++ ) {
1069
+ if (!gLayout [i ].isUsed ) {
1070
+ layout = & gLayout [i ];
1071
+ }
1091
1072
}
1092
1073
}
1093
1074
else {
1094
- // automatically "release" a potentially opened non-modal layout
1095
- gLayout [0 ].nbChildren = 0 ;
1096
- layout = & gLayout [0 ];
1075
+ // always use layout 0 for background
1076
+ layout = & gLayout [0 ];
1077
+ if (topLayout == NULL ) {
1078
+ topLayout = layout ;
1079
+ }
1097
1080
}
1098
1081
if (layout == NULL ) {
1099
1082
LOG_WARN (LAYOUT_LOGGER , "nbgl_layoutGet(): impossible to get a layout!\n" );
1100
1083
return NULL ;
1101
1084
}
1102
1085
1103
1086
// reset globals
1087
+ nbgl_layoutInternal_t * backgroundTop = gLayout [0 ].top ;
1104
1088
memset (layout , 0 , sizeof (nbgl_layoutInternal_t ));
1089
+ // link layout to other ones
1090
+ if (description -> modal ) {
1091
+ if (topLayout != NULL ) {
1092
+ // if topLayout already existing, push this new one on top of it
1093
+ topLayout -> top = layout ;
1094
+ layout -> bottom = topLayout ;
1095
+ }
1096
+ else {
1097
+ // otherwise put it on top of background layout
1098
+ layout -> bottom = & gLayout [0 ];
1099
+ gLayout [0 ].top = layout ;
1100
+ }
1101
+ topLayout = layout ;
1102
+ }
1103
+ else {
1104
+ // restore potentially valid background top layer
1105
+ gLayout [0 ].top = backgroundTop ;
1106
+ }
1105
1107
1106
1108
nbTouchableControls = 0 ;
1107
1109
@@ -1130,7 +1132,7 @@ nbgl_layout_t *nbgl_layoutGet(const nbgl_layoutDescription_t *description)
1130
1132
layout -> container -> obj .alignment = TOP_LEFT ;
1131
1133
// main container is always the second object, leaving space for header
1132
1134
layout -> children [MAIN_CONTAINER_INDEX ] = (nbgl_obj_t * ) layout -> container ;
1133
- layout -> nbChildren = NB_MAX_SCREEN_CHILDREN ;
1135
+ layout -> isUsed = true ;
1134
1136
1135
1137
// if a tap text is defined, make the container tapable and display this text in gray
1136
1138
if (description -> tapActionText != NULL ) {
@@ -3759,10 +3761,7 @@ int nbgl_layoutDraw(nbgl_layout_t *layoutParam)
3759
3761
if (layout == NULL ) {
3760
3762
return -1 ;
3761
3763
}
3762
- LOG_DEBUG (LAYOUT_LOGGER ,
3763
- "nbgl_layoutDraw(): container.nbChildren =%d, layout->nbChildren = %d\n" ,
3764
- layout -> container -> nbChildren ,
3765
- layout -> nbChildren );
3764
+ LOG_DEBUG (LAYOUT_LOGGER , "nbgl_layoutDraw(): layout->isUsed = %d\n" , layout -> isUsed );
3766
3765
if (layout -> tapText ) {
3767
3766
// set this new container as child of main container
3768
3767
layoutAddObject (layout , (nbgl_obj_t * ) layout -> tapText );
@@ -3789,14 +3788,24 @@ int nbgl_layoutRelease(nbgl_layout_t *layoutParam)
3789
3788
{
3790
3789
nbgl_layoutInternal_t * layout = (nbgl_layoutInternal_t * ) layoutParam ;
3791
3790
LOG_DEBUG (PAGE_LOGGER , "nbgl_layoutRelease(): \n" );
3792
- if (layout == NULL ) {
3791
+ if (( layout == NULL ) || (! layout -> isUsed ) ) {
3793
3792
return -1 ;
3794
3793
}
3795
3794
// if modal
3796
3795
if (layout -> modal ) {
3797
3796
nbgl_screenPop (layout -> layer );
3797
+ // if this layout was on top, use its bottom layout as top
3798
+ if (layout == topLayout ) {
3799
+ topLayout = layout -> bottom ;
3800
+ topLayout -> top = NULL ;
3801
+ }
3802
+ else {
3803
+ // otherwise connect top to bottom
3804
+ layout -> bottom -> top = layout -> top ;
3805
+ layout -> top -> bottom = layout -> bottom ;
3806
+ }
3798
3807
}
3799
- layout -> nbChildren = 0 ;
3808
+ layout -> isUsed = false ;
3800
3809
return 0 ;
3801
3810
}
3802
3811
0 commit comments