From 0b63cc80aaa596c9fd45abcd4e27eeb261f3b33c Mon Sep 17 00:00:00 2001 From: Nicolas Roggeman Date: Tue, 23 Apr 2024 13:21:09 +0200 Subject: [PATCH] Fix FWEO-1133 - APP SDK - Streamed transactions shouldn't have a back arrow navigation --- lib_nbgl/include/nbgl_layout.h | 7 ++- lib_nbgl/include/nbgl_page.h | 10 ++-- lib_nbgl/src/nbgl_layout.c | 34 +++++------- lib_nbgl/src/nbgl_layout_internal.h | 10 ++-- lib_nbgl/src/nbgl_layout_navigation.c | 78 ++++++++++++--------------- lib_nbgl/src/nbgl_obj.c | 8 +++ lib_nbgl/src/nbgl_page.c | 22 ++++---- lib_nbgl/src/nbgl_use_case.c | 22 +++++--- 8 files changed, 97 insertions(+), 94 deletions(-) diff --git a/lib_nbgl/include/nbgl_layout.h b/lib_nbgl/include/nbgl_layout.h index 6161a3220..11a6dc619 100644 --- a/lib_nbgl/include/nbgl_layout.h +++ b/lib_nbgl/include/nbgl_layout.h @@ -104,10 +104,15 @@ typedef struct { uint8_t token; ///< the token that will be used as argument of the callback uint8_t nbPages; ///< number of pages. (if 0, no navigation) uint8_t activePage; ///< index of active page (from 0 to nbPages-1). - bool withExitKey; ///< if set to true, an exit button is drawn + bool withExitKey; ///< if set to true, an exit button is drawn (X on the left) bool withBackKey; ///< if set to true, the "back" key is drawn bool withSeparationLine; ///< if set to true, an horizontal line is drawn on top of bar in ///< light gray + bool withPageIndicator; ///< on Flex, a "page on nb_pages" text can be added between back and + ///< forward keys + bool visibleIndicator; ///< on Flex, the page indicator can be visible or not. + ///< if withPageIndicator is true and this boolean false, the back key + ///< is placed as if there was an indicator #ifdef HAVE_PIEZO_SOUND tune_index_e tuneId; ///< if not @ref NBGL_NO_TUNE, a tune will be played when pressing keys) #endif // HAVE_PIEZO_SOUND diff --git a/lib_nbgl/include/nbgl_page.h b/lib_nbgl/include/nbgl_page.h index 1885185ae..64af7ec84 100644 --- a/lib_nbgl/include/nbgl_page.h +++ b/lib_nbgl/include/nbgl_page.h @@ -106,10 +106,12 @@ typedef struct nbgl_pageNavWithTap_s { * */ typedef struct nbgl_pageNavWithButtons_s { - bool quitButton; ///< if set to true, a quit button (X) is displayed in the nav bar - bool backButton; ///< if set to true, a back button (<-) is displayed in the nav bar - uint8_t navToken; ///< the token used as argument of the actionCallback when the nav buttons - ///< are pressed (index param gives the page) + bool quitButton; ///< if set to true, a quit button (X) is displayed in the nav bar + bool backButton; ///< if set to true, a back button (<-) is displayed in the nav bar + bool + visiblePageIndicator; ///< if set to true, the page indicator will be visible in navigation + uint8_t navToken; ///< the token used as argument of the actionCallback when the nav buttons + ///< are pressed (index param gives the page) const char *quitText; ///< the text displayed in footer (on the left), used to quit (only on Flex) } nbgl_pageNavWithButtons_t; diff --git a/lib_nbgl/src/nbgl_layout.c b/lib_nbgl/src/nbgl_layout.c index caeeb0ba6..403eeb9eb 100644 --- a/lib_nbgl/src/nbgl_layout.c +++ b/lib_nbgl/src/nbgl_layout.c @@ -889,14 +889,15 @@ int nbgl_layoutAddTopRightButton(nbgl_layout_t *layout, int nbgl_layoutAddNavigationBar(nbgl_layout_t *layout, const nbgl_layoutNavigationBar_t *info) { nbgl_layoutFooter_t footerDesc; - footerDesc.type = FOOTER_NAV; - footerDesc.separationLine = info->withSeparationLine; - footerDesc.navigation.activePage = info->activePage; - footerDesc.navigation.nbPages = info->nbPages; - footerDesc.navigation.withExitKey = info->withExitKey; - footerDesc.navigation.withBackKey = info->withBackKey; - footerDesc.navigation.token = info->token; - footerDesc.navigation.tuneId = info->tuneId; + footerDesc.type = FOOTER_NAV; + footerDesc.separationLine = info->withSeparationLine; + footerDesc.navigation.activePage = info->activePage; + footerDesc.navigation.nbPages = info->nbPages; + footerDesc.navigation.withExitKey = info->withExitKey; + footerDesc.navigation.withBackKey = info->withBackKey; + footerDesc.navigation.withPageIndicator = false; + footerDesc.navigation.token = info->token; + footerDesc.navigation.tuneId = info->tuneId; return nbgl_layoutAddExtendedFooter(layout, &footerDesc); } @@ -2575,13 +2576,7 @@ int nbgl_layoutAddExtendedFooter(nbgl_layout_t *layout, const nbgl_layoutFooter_ navContainer->obj.alignment = BOTTOM_RIGHT; navContainer->obj.area.width = SCREEN_WIDTH - textArea->obj.area.width; navContainer->obj.area.height = SIMPLE_FOOTER_HEIGHT; - layoutNavigationPopulate(navContainer, - footerDesc->textAndNav.navigation.nbPages, - footerDesc->textAndNav.navigation.activePage, - footerDesc->textAndNav.navigation.withExitKey, - footerDesc->textAndNav.navigation.withBackKey, - true, - layoutInt->layer); + layoutNavigationPopulate(navContainer, &footerDesc->navigation, layoutInt->layer); obj = layoutAddCallbackObj(layoutInt, (nbgl_obj_t *) navContainer, footerDesc->textAndNav.navigation.token, @@ -2615,13 +2610,8 @@ int nbgl_layoutAddExtendedFooter(nbgl_layout_t *layout, const nbgl_layoutFooter_ layoutInt->footerContainer->obj.area.width = SCREEN_WIDTH; #endif // TARGET_STAX layoutInt->footerContainer->obj.area.height = SIMPLE_FOOTER_HEIGHT; - layoutNavigationPopulate(layoutInt->footerContainer, - footerDesc->navigation.nbPages, - footerDesc->navigation.activePage, - footerDesc->navigation.withExitKey, - footerDesc->navigation.withBackKey, - false, - layoutInt->layer); + layoutNavigationPopulate( + layoutInt->footerContainer, &footerDesc->navigation, layoutInt->layer); layoutInt->footerContainer->nbChildren = 4; obj = layoutAddCallbackObj(layoutInt, (nbgl_obj_t *) layoutInt->footerContainer, diff --git a/lib_nbgl/src/nbgl_layout_internal.h b/lib_nbgl/src/nbgl_layout_internal.h index 832a056e0..cbff2384c 100644 --- a/lib_nbgl/src/nbgl_layout_internal.h +++ b/lib_nbgl/src/nbgl_layout_internal.h @@ -92,13 +92,9 @@ layoutObj_t *layoutAddCallbackObj(nbgl_layoutInternal_t *layout, nbgl_obj_t *obj, uint8_t token, tune_index_e tuneId); -void layoutNavigationPopulate(nbgl_container_t *navContainer, - uint8_t nbPages, - uint8_t activePage, - bool withExitKey, - bool withBackKey, - bool withPageIndicator, - uint8_t layer); +void layoutNavigationPopulate(nbgl_container_t *navContainer, + const nbgl_layoutNavigationBar_t *navConfig, + uint8_t layer); bool layoutNavigationCallback(nbgl_obj_t *obj, nbgl_touchType_t eventType, uint8_t nbPages, diff --git a/lib_nbgl/src/nbgl_layout_navigation.c b/lib_nbgl/src/nbgl_layout_navigation.c index a69937466..fad6ff34c 100644 --- a/lib_nbgl/src/nbgl_layout_navigation.c +++ b/lib_nbgl/src/nbgl_layout_navigation.c @@ -142,30 +142,17 @@ bool layoutNavigationCallback(nbgl_obj_t *obj, * container * * @param navContainer container used for the objects of the navigation - * @param nbPages max number of pages for navigation (if < 2, no navigation keys) - * @param activePage active page at start-up in [0-(nbPages-1)] - * @param withExitKey if set to true, an exit key is added on the left - * @param withBackKey if set to false, the back key is not drawn - * @param withPageIndicator if set to true, " on " is added between - * navigation arrows (if more than 1 page) + * @param navConfig configuration to create the navigation bar, at the bottom of the screen * @param layer layer (screen) to create the navigation bar in * */ -void layoutNavigationPopulate(nbgl_container_t *navContainer, - uint8_t nbPages, - uint8_t activePage, - bool withExitKey, - bool withBackKey, - bool withPageIndicator, - uint8_t layer) +void layoutNavigationPopulate(nbgl_container_t *navContainer, + const nbgl_layoutNavigationBar_t *navConfig, + uint8_t layer) { nbgl_button_t *button; -#ifdef TARGET_STAX - UNUSED(withPageIndicator); -#endif // TARGET_STAX - - if (withExitKey) { + if (navConfig->withExitKey) { button = (nbgl_button_t *) nbgl_objPoolGet(BUTTON, layer); button->innerColor = WHITE; button->borderColor = BORDER_COLOR; @@ -173,21 +160,21 @@ void layoutNavigationPopulate(nbgl_container_t *navContainer, button->obj.area.height = BUTTON_DIAMETER; button->radius = BUTTON_RADIUS; button->icon = &CLOSE_ICON; -#ifndef TARGET_STAX - button->obj.alignmentMarginX = (nbPages > 1) ? 8 : 0; -#endif // TARGET_STAX +#ifdef TARGET_FLEX + button->obj.alignmentMarginX = (navConfig->nbPages > 1) ? 8 : 0; +#endif // TARGET_FLEX - button->obj.alignment = (nbPages > 1) ? MID_LEFT : CENTER; + button->obj.alignment = (navConfig->nbPages > 1) ? MID_LEFT : CENTER; button->obj.touchMask = (1 << TOUCHED); button->obj.touchId = BOTTOM_BUTTON_ID; navContainer->children[EXIT_BUTTON_INDEX] = (nbgl_obj_t *) button; } // create previous page button (back) - if (withBackKey) { + if (navConfig->withBackKey) { button = (nbgl_button_t *) nbgl_objPoolGet(BUTTON, layer); button->innerColor = WHITE; button->borderColor = BORDER_COLOR; - if (withExitKey) { + if (navConfig->withExitKey) { button->obj.area.width = NAV_BUTTON_WIDTH; } else { @@ -198,7 +185,7 @@ void layoutNavigationPopulate(nbgl_container_t *navContainer, #ifdef TARGET_STAX button->icon = &LEFT_ARROW_ICON; // align either on the right of Exit key, or on the inner left of the container - if (withExitKey) { + if (navConfig->withExitKey) { button->obj.alignmentMarginX = INTERNAL_SMALL_MARGIN; button->obj.alignment = MID_RIGHT; button->obj.alignTo = navContainer->children[EXIT_BUTTON_INDEX]; @@ -222,7 +209,7 @@ void layoutNavigationPopulate(nbgl_container_t *navContainer, button->innerColor = WHITE; button->borderColor = BORDER_COLOR; button->foregroundColor = BLACK; - if (withExitKey) { + if (navConfig->withExitKey) { button->obj.area.width = NAV_BUTTON_WIDTH; } else { @@ -243,32 +230,33 @@ void layoutNavigationPopulate(nbgl_container_t *navContainer, button->obj.touchId = RIGHT_BUTTON_ID; navContainer->children[NEXT_PAGE_INDEX] = (nbgl_obj_t *) button; - // potentially create page indicator (with a text area) -#ifndef TARGET_STAX - if (withPageIndicator && withBackKey - && (nbPages > 1 && nbPages != NBGL_NO_PROGRESS_INDICATOR)) { - nbgl_text_area_t *textArea = (nbgl_text_area_t *) nbgl_objPoolGet(TEXT_AREA, layer); +#ifdef TARGET_FLEX + // potentially create page indicator (with a text area, and "page of nb_page") + if (navConfig->withPageIndicator) { + if (navConfig->visibleIndicator) { + nbgl_text_area_t *textArea = (nbgl_text_area_t *) nbgl_objPoolGet(TEXT_AREA, layer); - SPRINTF(navText, "%d of %d", activePage + 1, nbPages); + SPRINTF(navText, "%d of %d", navConfig->activePage + 1, navConfig->nbPages); - textArea->obj.alignment = BOTTOM_RIGHT; - textArea->textColor = DARK_GRAY; - textArea->obj.area.width = 109; - textArea->text = navText; - textArea->fontId = SMALL_REGULAR_FONT; - textArea->obj.area.height = NAV_BUTTON_HEIGHT; - textArea->textAlignment = CENTER; - textArea->obj.alignment = MID_RIGHT; - textArea->obj.alignmentMarginX = NAV_BUTTON_WIDTH - 15; - navContainer->children[PAGE_INDICATOR_INDEX] = (nbgl_obj_t *) textArea; - if (withBackKey) { + textArea->obj.alignment = BOTTOM_RIGHT; + textArea->textColor = DARK_GRAY; + textArea->obj.area.width = 109; + textArea->text = navText; + textArea->fontId = SMALL_REGULAR_FONT; + textArea->obj.area.height = NAV_BUTTON_HEIGHT; + textArea->textAlignment = CENTER; + textArea->obj.alignment = MID_RIGHT; + textArea->obj.alignmentMarginX = NAV_BUTTON_WIDTH - 15; + navContainer->children[PAGE_INDICATOR_INDEX] = (nbgl_obj_t *) textArea; + } + if (navConfig->withBackKey) { navContainer->children[PREVIOUS_PAGE_INDEX]->alignmentMarginX += 79; } } -#endif // TARGET_STAX +#endif // TARGET_FLEX // configure enabling/disabling of button - configButtons(navContainer, nbPages, activePage); + configButtons(navContainer, navConfig->nbPages, navConfig->activePage); return; } diff --git a/lib_nbgl/src/nbgl_obj.c b/lib_nbgl/src/nbgl_obj.c index 7c45e5adc..21dfe1bc3 100644 --- a/lib_nbgl/src/nbgl_obj.c +++ b/lib_nbgl/src/nbgl_obj.c @@ -23,7 +23,11 @@ /********************* * DEFINES *********************/ +#ifdef TARGET_STAX #define NB_MAX_PAGES_WITH_DASHES 10 +#else // TARGET_STAX +#define NB_MAX_PAGES_WITH_DASHES 6 +#endif // TARGET_STAX // max number of letters in TEXT_ENTRY #define NB_MAX_LETTERS 9 @@ -734,7 +738,11 @@ static void draw_pageIndicator(nbgl_page_indicator_t *obj, if (obj->nbPages <= NB_MAX_PAGES_WITH_DASHES) { int i; +#ifdef TARGET_STAX #define INTER_DASHES 10 // pixels +#else // TARGET_STAX +#define INTER_DASHES 8 // pixels +#endif // TARGET_STAX // force height obj->obj.area.height = 4; diff --git a/lib_nbgl/src/nbgl_page.c b/lib_nbgl/src/nbgl_page.c index 984f95c3e..4db978475 100644 --- a/lib_nbgl/src/nbgl_page.c +++ b/lib_nbgl/src/nbgl_page.c @@ -543,13 +543,14 @@ nbgl_page_t *nbgl_pageDrawGenericContentExt(nbgl_layoutTouchCallback_t onA footerDesc.separationLine = true; if (nav->nbPages > 1) { if (nav->navWithButtons.quitText == NULL) { - footerDesc.type = FOOTER_NAV; - footerDesc.navigation.activePage = nav->activePage; - footerDesc.navigation.nbPages = nav->nbPages; - footerDesc.navigation.withExitKey = nav->navWithButtons.quitButton; - footerDesc.navigation.withBackKey = nav->navWithButtons.backButton; - footerDesc.navigation.token = nav->navWithButtons.navToken; - footerDesc.navigation.tuneId = nav->tuneId; + footerDesc.type = FOOTER_NAV; + footerDesc.navigation.activePage = nav->activePage; + footerDesc.navigation.nbPages = nav->nbPages; + footerDesc.navigation.withExitKey = nav->navWithButtons.quitButton; + footerDesc.navigation.withBackKey = nav->navWithButtons.backButton; + footerDesc.navigation.withPageIndicator = false; + footerDesc.navigation.token = nav->navWithButtons.navToken; + footerDesc.navigation.tuneId = nav->tuneId; } else { footerDesc.type = FOOTER_TEXT_AND_NAV; @@ -560,8 +561,11 @@ nbgl_page_t *nbgl_pageDrawGenericContentExt(nbgl_layoutTouchCallback_t onA footerDesc.textAndNav.navigation.nbPages = nav->nbPages; footerDesc.textAndNav.navigation.withExitKey = false; footerDesc.textAndNav.navigation.withBackKey = nav->navWithButtons.backButton; - footerDesc.textAndNav.navigation.token = nav->navWithButtons.navToken; - footerDesc.textAndNav.navigation.tuneId = nav->tuneId; + footerDesc.textAndNav.navigation.visibleIndicator + = nav->navWithButtons.visiblePageIndicator; + footerDesc.textAndNav.navigation.withPageIndicator = true; + footerDesc.textAndNav.navigation.token = nav->navWithButtons.navToken; + footerDesc.textAndNav.navigation.tuneId = nav->tuneId; } } else if (nav->navWithButtons.quitText != NULL) { diff --git a/lib_nbgl/src/nbgl_use_case.c b/lib_nbgl/src/nbgl_use_case.c index 43c4e0134..d44b6a569 100644 --- a/lib_nbgl/src/nbgl_use_case.c +++ b/lib_nbgl/src/nbgl_use_case.c @@ -333,10 +333,12 @@ static void prepareNavInfo(bool isReview, uint8_t nbPages, const char *rejectTex navInfo.navWithTap.backToken = BACK_TOKEN; #else // TARGET_STAX UNUSED(rejectText); - navInfo.navType = NAV_WITH_BUTTONS; - navInfo.navWithButtons.quitText = "Reject"; - navInfo.navWithButtons.navToken = NAV_TOKEN; - navInfo.navWithButtons.backButton = true; + navInfo.navType = NAV_WITH_BUTTONS; + navInfo.navWithButtons.quitText = "Reject"; + navInfo.navWithButtons.navToken = NAV_TOKEN; + navInfo.navWithButtons.backButton + = ((navType == STREAMING_NAV) && (nbPages < 2)) ? false : true; + navInfo.navWithButtons.visiblePageIndicator = (navType != STREAMING_NAV); #endif // TARGET_STAX } } @@ -352,7 +354,7 @@ static void prepareReviewFirstPage(nbgl_contentCenteredInfo_t *centeredInfo, #ifdef TARGET_STAX centeredInfo->text3 = NULL; #else // TARGET_STAX - centeredInfo->text3 = "Swipe to continue"; + centeredInfo->text3 = "Swipe to review"; #endif // TARGET_STAX centeredInfo->style = LARGE_CASE_GRAY_INFO; centeredInfo->offsetY = 0; @@ -795,6 +797,10 @@ static bool genericContextPreparePageContent(const nbgl_content_t *p_content, pageContent->type = CENTERED_INFO; prepareReviewFirstPage( &pageContent->centeredInfo, pair->valueIcon, pair->item, pair->value); +#ifdef TARGET_FLEX + // use "Swipe to continue" instead of "Swipe to review" for intermediate pages + pageContent->centeredInfo.text3 = "Swipe to continue"; +#endif // TARGET_FLEX // Skip population of nbgl_contentTagValueList_t structure p_tagValueList = NULL; @@ -1443,7 +1449,7 @@ static void bundleNavReviewStreamingChoice(bool confirm) { if (confirm) { // Display a spinner if it wasn't the finish step - if (navInfo.nbPages == NBGL_NO_PROGRESS_INDICATOR) { + if (localContentsList[0].type != INFO_LONG_PRESS) { nbgl_useCaseSpinner("Processing"); } bundleNavContext.reviewStreaming.choiceCallback(true); @@ -2537,6 +2543,10 @@ void nbgl_useCaseReviewStreamingStart(nbgl_operationType_t operationType, bundleNavContext.reviewStreaming.stepPageNb = nbgl_useCaseGetNbPagesForGenericContents(&genericContext.genericContents, 0); prepareNavInfo(true, NBGL_NO_PROGRESS_INDICATOR, getRejectReviewText(operationType)); +#ifdef TARGET_FLEX + // no back button on first page + navInfo.navWithButtons.backButton = false; +#endif // TARGET_STAX displayGenericContextPage(0, true); }