From 89d3946e7dc150da7c6b3e0957d14cf4b19119f5 Mon Sep 17 00:00:00 2001 From: Nicolas Roggeman Date: Wed, 18 Feb 2026 16:44:05 +0100 Subject: [PATCH] Support TAG_VALUE_CONFIRM generiic content for Nano (cherry picked from commit 55c21b018ae2713e945bd28426de7c68658a6f1f) --- lib_nbgl/include/nbgl_flow.h | 15 ++++++------ lib_nbgl/src/nbgl_use_case_nanos.c | 37 ++++++++++++++++++++++++++++-- 2 files changed, 43 insertions(+), 9 deletions(-) diff --git a/lib_nbgl/include/nbgl_flow.h b/lib_nbgl/include/nbgl_flow.h index 3143d7846..71c7ca1d3 100644 --- a/lib_nbgl/include/nbgl_flow.h +++ b/lib_nbgl/include/nbgl_flow.h @@ -58,13 +58,14 @@ typedef struct nbgl_stepDesc_s { typedef struct nbgl_pageContent_s { nbgl_contentType_t type; ///< type of page content in the following union union { - nbgl_contentCenteredInfo_t centeredInfo; ///< @ref CENTERED_INFO type - nbgl_contentInfoButton_t infoButton; ///< @ref INFO_BUTTON type - nbgl_contentTagValueList_t tagValueList; ///< @ref TAG_VALUE_LIST type - nbgl_contentSwitchesList_t switchesList; ///< @ref SWITCHES_LIST type - nbgl_contentInfoList_t infosList; ///< @ref INFOS_LIST type - nbgl_contentRadioChoice_t choicesList; ///< @ref CHOICES_LIST type - nbgl_contentBarsList_t barsList; ///< @ref BARS_LIST type + nbgl_contentCenteredInfo_t centeredInfo; ///< @ref CENTERED_INFO type + nbgl_contentInfoButton_t infoButton; ///< @ref INFO_BUTTON type + nbgl_contentTagValueList_t tagValueList; ///< @ref TAG_VALUE_LIST type + nbgl_contentTagValueConfirm_t tagValueConfirm; ///< @ref TAG_VALUE_CONFIRM type + nbgl_contentSwitchesList_t switchesList; ///< @ref SWITCHES_LIST type + nbgl_contentInfoList_t infosList; ///< @ref INFOS_LIST type + nbgl_contentRadioChoice_t choicesList; ///< @ref CHOICES_LIST type + nbgl_contentBarsList_t barsList; ///< @ref BARS_LIST type }; } nbgl_pageContent_t; diff --git a/lib_nbgl/src/nbgl_use_case_nanos.c b/lib_nbgl/src/nbgl_use_case_nanos.c index 59c5152d6..40c4e4499 100644 --- a/lib_nbgl/src/nbgl_use_case_nanos.c +++ b/lib_nbgl/src/nbgl_use_case_nanos.c @@ -144,6 +144,7 @@ typedef struct UseCaseContext_s { uint8_t nbPages; int8_t currentPage; int8_t firstPairPage; + bool forceAction; nbgl_stepCallback_t stepCallback; ///< if not NULL, function to be called on "double-key" action union { @@ -167,6 +168,7 @@ typedef struct PageContent_s { const nbgl_contentValueExt_t *extension; nbgl_state_t state; bool isCenteredInfo; + bool isAction; } PageContent_t; typedef struct ReviewWithWarningContext_s { @@ -238,6 +240,9 @@ static uint8_t getContentNbElement(const nbgl_content_t *content) return 1; case TAG_VALUE_LIST: return content->content.tagValueList.nbPairs; + case TAG_VALUE_CONFIRM: + // last element is for Confirm page + return content->content.tagValueConfirm.tagValueList.nbPairs + 1; case SWITCHES_LIST: return content->content.switchesList.nbSwitches; case INFOS_LIST: @@ -284,6 +289,9 @@ static const nbgl_content_t *getContentAtIdx(const nbgl_genericContents_t *gener case TAG_VALUE_LIST: content->content.tagValueList = pageContent.tagValueList; break; + case TAG_VALUE_CONFIRM: + content->content.tagValueConfirm = pageContent.tagValueConfirm; + break; case SWITCHES_LIST: content->content.switchesList = pageContent.switchesList; break; @@ -617,7 +625,7 @@ static void drawStep(nbgl_stepPosition_t pos, info.text1 = txt; info.text2 = subTxt; info.onTop = false; - if ((subTxt != NULL) || (context.stepCallback != NULL)) { + if ((subTxt != NULL) || (context.stepCallback != NULL) || context.forceAction) { info.style = BOLD_TEXT1_INFO; } else { @@ -704,6 +712,14 @@ static bool buttonGenericCallback(nbgl_buttonEvent_t event, nbgl_stepPosition_t token = p_content->content.choicesList.token; index = context.currentPage; break; + case TAG_VALUE_LIST: + return false; + case TAG_VALUE_CONFIRM: + if (elemIdx < p_content->content.tagValueConfirm.tagValueList.nbPairs) { + return false; + } + token = p_content->content.tagValueConfirm.confirmationToken; + break; default: break; } @@ -1367,6 +1383,22 @@ static void getContentPage(bool toogle_state, PageContent_t *contentPage) &contentPage->icon, &contentPage->isCenteredInfo); break; + case TAG_VALUE_CONFIRM: + if (elemIdx < p_content->content.tagValueConfirm.tagValueList.nbPairs) { + getPairData(&p_content->content.tagValueConfirm.tagValueList, + elemIdx, + &contentPage->text, + &contentPage->subText, + &contentPage->extension, + &contentPage->icon, + &contentPage->isCenteredInfo); + } + else { + contentPage->text = p_content->content.tagValueConfirm.confirmationText; + contentPage->icon = &C_icon_validate_14; + contentPage->isAction = true; + } + break; case SWITCHES_LIST: contentPage->isSwitch = true; contentSwitch = &( @@ -1728,6 +1760,7 @@ static void displayContent(nbgl_stepPosition_t pos, bool toogle_state) if (contentPage.isCenteredInfo) { forcedType = FORCE_CENTERED_INFO; } + context.forceAction = contentPage.isAction; } else { // last page is for quit if (context.content.rejectText) { @@ -1758,7 +1791,7 @@ static void displayContent(nbgl_stepPosition_t pos, bool toogle_state) false, forcedType); } - + context.forceAction = false; nbgl_refresh(); }