17#include "os_helpers.h"
23#define WITH_HORIZONTAL_CHOICES_LIST
24#define WITH_HORIZONTAL_BARS_LIST
31#define RISKY_OPERATION (1 << 6)
38#define NO_THREAT_OPERATION (1 << 7)
45#define REAL_TYPE_MASK 0x7
51typedef struct ReviewContext_s {
55 const char *reviewTitle;
56 const char *reviewSubTitle;
70typedef struct ChoiceContext_s {
73 const char *subMessage;
74 const char *confirmText;
75 const char *cancelText;
79typedef struct ConfirmContext_s {
81 const char *subMessage;
82 const char *confirmText;
83 const char *cancelText;
88typedef struct ContentContext_s {
91 const char *rejectText;
96typedef struct HomeContext_s {
107typedef struct KeypadContext_s {
124 GENERIC_REVIEW_USE_CASE,
125 ADDRESS_REVIEW_USE_CASE,
126 STREAMING_START_REVIEW_USE_CASE,
127 STREAMING_CONTINUE_REVIEW_USE_CASE,
128 STREAMING_FINISH_REVIEW_USE_CASE,
140typedef struct UseCaseContext_s {
148 ReviewContext_t review;
149 ChoiceContext_t choice;
150 ConfirmContext_t confirm;
152 ContentContext_t content;
154 KeypadContext_t keypad;
159typedef struct PageContent_s {
168typedef struct ReviewWithWarningContext_s {
173 const char *reviewTitle;
174 const char *reviewSubTitle;
175 const char *finishTitle;
182} ReviewWithWarningContext_t;
193static UseCaseContext_t context;
195static ReviewWithWarningContext_t reviewWithWarnCtx;
210static void displaySpinner(
const char *text);
212static void startUseCaseHome(
void);
213static void startUseCaseInfo(
void);
214static void startUseCaseSettings(
void);
215static void startUseCaseSettingsAtPage(
uint8_t initSettingPage);
216static void startUseCaseContent(
void);
218static void statusTickerCallback(
void);
221static void displayWarningStep(
void);
226 switch (content->
type) {
252 if (contentIdx < 0 || contentIdx >= genericContents->
nbContents) {
258 if (content == NULL) {
284 switch (context.type) {
285 case SETTINGS_USE_CASE:
287 case GENERIC_SETTINGS:
288 genericContents = context.home.settingContents;
290 case CONTENT_USE_CASE:
291 case GENERIC_REVIEW_USE_CASE:
292 genericContents = &context.content.genericContents;
297 for (
int i = 0; i < genericContents->
nbContents; i++) {
298 p_content = getContentAtIdx(genericContents, i, content);
299 elemNbPages = getContentNbElement(p_content);
300 if (nbPages + elemNbPages > elemIdx) {
301 *elemContentIdx = context.currentPage - nbPages;
304 nbPages += elemNbPages;
310static const char *getChoiceName(
uint8_t choiceIndex)
320 p_content = getContentElemAtIdx(context.currentPage, &elemIdx, &content);
321 if (p_content == NULL) {
324 switch (p_content->
type) {
327 names = (
char **) PIC(contentChoices->
names);
332 names = (
char **) PIC(contentBars->
barTexts);
333 nbValues = contentBars->
nbBars;
339 if (choiceIndex >= nbValues) {
343 return (
const char *) PIC(names[choiceIndex]);
346static void onChoiceSelected(
uint8_t choiceIndex)
355 p_content = getContentElemAtIdx(context.currentPage, &elemIdx, &content);
356 if (p_content == NULL) {
359 switch (p_content->
type) {
362 if (choiceIndex < contentChoices->nbChoices) {
363 token = contentChoices->
token;
368 if (choiceIndex < contentBars->nbBars) {
369 token = contentBars->
tokens[choiceIndex];
376 if ((token != 255) && (context.content.controlsCallback != NULL)) {
377 context.content.controlsCallback(token, 0);
379 else if (context.content.quitCallback != NULL) {
380 context.content.quitCallback();
392 if (tagValueList->
pairs != NULL) {
393 pair = PIC(&tagValueList->
pairs[index]);
396 pair = PIC(tagValueList->
callback(index));
399 *value = pair->
value;
408static void onReviewAccept(
void)
410 if (context.review.onChoice) {
411 context.review.onChoice(
true);
415static void onReviewReject(
void)
417 if (context.review.onChoice) {
418 context.review.onChoice(
false);
422static void onChoiceAccept(
void)
424 if (context.choice.onChoice) {
425 context.choice.onChoice(
true);
429static void onChoiceReject(
void)
431 if (context.choice.onChoice) {
432 context.choice.onChoice(
false);
436static void onConfirmAccept(
void)
438 if (context.confirm.currentStep) {
441 if (context.confirm.onConfirm) {
442 context.confirm.onConfirm();
446static void onConfirmReject(
void)
448 if (context.confirm.currentStep) {
455static void onSwitchAction(
void)
462 p_content = getContentElemAtIdx(context.currentPage, &elemIdx, &content);
468 switch (context.type) {
469 case SETTINGS_USE_CASE:
471 case GENERIC_SETTINGS:
474 case CONTENT_USE_CASE:
475 case GENERIC_REVIEW_USE_CASE:
483 actionCallback(contentSwitch->
token,
485 context.currentPage);
487 else if (context.content.controlsCallback != NULL) {
488 context.content.controlsCallback(contentSwitch->
token, 0);
498 ForcedType_t forcedType)
509 .tickerIntervale = 0,
515 if ((context.type == STREAMING_CONTINUE_REVIEW_USE_CASE)
516 && (context.review.skipCallback != NULL) && (context.review.nbDataSets > 1)) {
519 if ((context.type == STATUS_USE_CASE) || (context.type == SPINNER_USE_CASE)) {
522 if ((context.type == CONFIRM_USE_CASE) && (context.confirm.currentStep != NULL)) {
527 p_content = getContentElemAtIdx(context.currentPage, &elemIdx, &content);
529 switch (p_content->
type) {
551 else if ((icon == NULL) && (forcedType != FORCE_CENTERED_INFO)) {
553 if (subTxt != NULL) {
554 style = (forcedType == FORCE_BUTTON) ? BUTTON_INFO : BOLD_TEXT1_INFO;
557 style = REGULAR_INFO;
559 newStep =
nbgl_stepDrawText(pos, onActionCallback, p_ticker, txt, subTxt, style, modal);
567 if ((subTxt != NULL) || (context.stepCallback != NULL)) {
568 info.
style = BOLD_TEXT1_INFO;
571 info.
style = REGULAR_INFO;
575 if (context.type == CONFIRM_USE_CASE) {
576 context.confirm.currentStep = newStep;
582 const char *description,
591 switchInfo.
text = title;
592 switchInfo.
subText = description;
605 if (context.currentPage > 0) {
606 context.currentPage--;
610 else if ((context.type != STREAMING_CONTINUE_REVIEW_USE_CASE)
611 || (context.review.skipCallback == NULL) || (context.review.nbDataSets == 1)) {
618 if (context.currentPage < (
int) (context.nbPages - 1)) {
619 context.currentPage++;
629 if (context.stepCallback != NULL) {
630 context.stepCallback();
632 else if ((context.type == CONTENT_USE_CASE)
633 || (context.type == GENERIC_REVIEW_USE_CASE)) {
634 p_content = getContentElemAtIdx(context.currentPage, &elemIdx, &content);
635 if (p_content != NULL) {
636 switch (p_content->
type) {
651 index = context.currentPage;
660 else if (context.content.controlsCallback != NULL) {
661 context.content.controlsCallback(token, index);
676 if (!buttonGenericCallback(event, &pos)) {
680 displayReviewPage(pos);
691 if ((context.review.dataDirection ==
FORWARD_DIRECTION) && (context.currentPage > 0)) {
692 context.currentPage--;
699 && (context.currentPage < (
int) (context.nbPages - 1)) && (context.currentPage > 0)) {
700 context.currentPage++;
705 context.review.skipCallback();
711 displayStreamingReviewPage(pos);
719 if (!buttonGenericCallback(event, &pos)) {
724 context.review.dataDirection = pos;
727 displayStreamingReviewPage(pos);
735 if (!buttonGenericCallback(event, &pos)) {
739 displaySettingsPage(pos,
false);
747 if (!buttonGenericCallback(event, &pos)) {
751 displayInfoPage(pos);
759 if (!buttonGenericCallback(event, &pos)) {
763 displayHomePage(pos);
771 if (!buttonGenericCallback(event, &pos)) {
775 displayChoicePage(pos);
783 if (!buttonGenericCallback(event, &pos)) {
794 if (context.stepCallback != NULL) {
795 context.stepCallback();
805 if (!buttonGenericCallback(event, &pos)) {
809 displayContent(pos,
false);
813static void statusTickerCallback(
void)
815 if (context.stepCallback != NULL) {
816 context.stepCallback();
828 if (context.review.currentExtensionPage > 0) {
829 context.review.currentExtensionPage--;
835 if (context.review.currentExtensionPage < (context.review.nbExtensionPages - 1)) {
836 context.review.currentExtensionPage++;
842 if (context.review.currentExtensionPage == (context.review.nbExtensionPages - 1)) {
852 displayExtensionStep(pos);
860 if (context.review.extensionStepCtx != NULL) {
863 if (context.review.currentExtensionPage < (context.review.nbExtensionPages - 1)) {
864 if (context.review.currentExtensionPage == 0) {
871 if (context.review.extension->aliasType ==
ENS_ALIAS) {
875 context.review.extension->title,
876 context.review.extension->fullValue,
885 context.review.extension->infolist->infoTypes[context.review.currentExtensionPage],
886 context.review.extension->infolist
887 ->infoContents[context.review.currentExtensionPage],
892 else if (context.review.currentExtensionPage == (context.review.nbExtensionPages - 1)) {
894 info.
icon = &C_icon_back_x;
896 info.
style = BOLD_TEXT1_INFO;
898 context.review.extensionStepCtx
904static void displayAliasFullValue(
void)
906 const char *text = NULL;
907 const char *subText = NULL;
909 getPairData(context.review.tagValueList,
910 context.review.currentTagValueIndex,
913 &context.review.extension);
914 if (context.review.extension == NULL) {
917 "displayAliasFullValue: extension nor found for pair %d\n",
918 context.review.currentTagValueIndex);
921 context.review.currentExtensionPage = 0;
922 context.review.extensionStepCtx = NULL;
924 if (context.review.extension->aliasType ==
ENS_ALIAS) {
925 context.review.nbExtensionPages = 2;
928 context.review.nbExtensionPages = context.review.extension->infolist->nbInfos + 1;
932 "displayAliasFullValue: unsupported alias type %d\n",
933 context.review.extension->aliasType);
939static void getLastPageInfo(
bool approve,
const nbgl_icon_details_t **icon,
const char **text)
943 *icon = &C_icon_validate_14;
944 if (context.type == ADDRESS_REVIEW_USE_CASE) {
948 if (context.operationType & RISKY_OPERATION) {
949 *text =
"Accept risk and sign transaction";
952 *text =
"Sign transaction";
955 else if ((context.operationType & REAL_TYPE_MASK) ==
TYPE_MESSAGE) {
956 if (context.operationType & RISKY_OPERATION) {
957 *text =
"Accept risk and sign message";
960 *text =
"Sign message";
964 if (context.operationType & RISKY_OPERATION) {
965 *text =
"Accept risk and sign operation";
968 *text =
"Sign operation";
971 context.stepCallback = onReviewAccept;
975 *icon = &C_icon_crossmark;
976 if (context.type == ADDRESS_REVIEW_USE_CASE) {
980 *text =
"Reject transaction";
982 else if ((context.operationType & REAL_TYPE_MASK) ==
TYPE_MESSAGE) {
983 *text =
"Reject message";
986 *text =
"Reject operation";
988 context.stepCallback = onReviewReject;
998 const char *text = NULL;
999 const char *subText = NULL;
1008 context.stepCallback = NULL;
1012 titleIndex = currentIndex++;
1014 if (context.review.reviewSubTitle) {
1016 subIndex = currentIndex++;
1019 approveIndex = context.nbPages - 2;
1020 rejectIndex = context.nbPages - 1;
1021 finalPages = approveIndex;
1024 if (context.currentPage >= finalPages) {
1025 if (context.currentPage == approveIndex) {
1027 getLastPageInfo(
true, &icon, &text);
1029 else if (context.currentPage == rejectIndex) {
1031 getLastPageInfo(
false, &icon, &text);
1034 else if (context.currentPage < reviewPages) {
1035 if (context.currentPage == titleIndex) {
1037 icon = context.review.icon;
1038 text = context.review.reviewTitle;
1040 else if (context.currentPage == subIndex) {
1042 text = context.review.reviewSubTitle;
1045 else if ((context.review.address != NULL) && (context.currentPage == reviewPages)) {
1048 subText = context.review.address;
1051 pairIndex = context.currentPage - reviewPages;
1052 if (context.review.address != NULL) {
1055 getPairData(context.review.tagValueList, pairIndex, &text, &subText, &extension);
1056 if (extension != NULL) {
1057 context.stepCallback = displayAliasFullValue;
1058 context.review.currentTagValueIndex = pairIndex;
1068 (extension != NULL) ? FORCE_BUTTON : NO_FORCED_TYPE);
1075 const char *text = NULL;
1076 const char *subText = NULL;
1083 context.stepCallback = NULL;
1084 switch (context.type) {
1085 case STREAMING_START_REVIEW_USE_CASE:
1087 titleIndex = reviewPages++;
1088 if (context.review.reviewSubTitle) {
1090 subIndex = reviewPages++;
1093 if (context.currentPage >= reviewPages) {
1098 if (context.currentPage == titleIndex) {
1100 icon = context.review.icon;
1101 text = context.review.reviewTitle;
1103 else if (context.currentPage == subIndex) {
1105 text = context.review.reviewSubTitle;
1109 case STREAMING_CONTINUE_REVIEW_USE_CASE:
1110 if (context.currentPage >= context.review.tagValueList->nbPairs) {
1117 if ((context.review.skipCallback != NULL) && (context.review.skipDisplay ==
false)
1118 && ((context.review.nbDataSets > 1) || (context.currentPage > 0)
1122 if ((context.review.nbDataSets == 1) || (context.currentPage > 0)) {
1125 info.
icon = &C_Information_circle_14px;
1126 info.
text1 =
"Press right button to continue message or \bpress both to skip\b";
1129 context.review.skipDisplay =
true;
1132 context.review.skipDisplay =
false;
1134 context.review.tagValueList, context.currentPage, &text, &subText, &extension);
1137 case STREAMING_FINISH_REVIEW_USE_CASE:
1139 if (context.currentPage == 0) {
1141 getLastPageInfo(
true, &icon, &text);
1145 getLastPageInfo(
false, &icon, &text);
1154 streamingReviewCallback,
1156 (extension != NULL) ? FORCE_BUTTON : NO_FORCED_TYPE);
1163 const char *text = NULL;
1164 const char *subText = NULL;
1167 context.stepCallback = NULL;
1169 if (context.currentPage < (context.nbPages - 1)) {
1171 ((
const char *
const *) PIC(context.home.infosList->infoTypes))[context.currentPage]);
1173 ((
const char *
const *) PIC(context.home.infosList->infoContents))[context.currentPage]);
1176 icon = &C_icon_back_x;
1178 context.stepCallback = startUseCaseHome;
1181 drawStep(pos, icon, text, subText, infoCallback,
false, FORCE_CENTERED_INFO);
1186static void getContentPage(
bool toogle_state, PageContent_t *contentPage)
1192#ifdef WITH_HORIZONTAL_CHOICES_LIST
1194 char **names = NULL;
1197 p_content = getContentElemAtIdx(context.currentPage, &elemIdx, &content);
1198 if (p_content == NULL) {
1201 switch (p_content->
type) {
1215 &contentPage->subText,
1216 &contentPage->extension);
1219 contentPage->isSwitch =
true;
1222 contentPage->
text = contentSwitch->
text;
1223 contentPage->state = contentSwitch->
initState;
1227 context.stepCallback = onSwitchAction;
1228 contentPage->subText = contentSwitch->
subText;
1233 contentPage->subText
1237#ifdef WITH_HORIZONTAL_CHOICES_LIST
1238 if ((context.type == CONTENT_USE_CASE) && (context.content.title != NULL)) {
1239 contentPage->text = PIC(context.content.title);
1244 names = (
char **) PIC(contentChoices->
names);
1245 contentPage->text = (
const char *) PIC(names[elemIdx]);
1250#ifdef WITH_HORIZONTAL_BARS_LIST
1251 if ((context.type == CONTENT_USE_CASE) && (context.content.title != NULL)) {
1252 contentPage->text = PIC(context.content.title);
1268 PageContent_t contentPage = {0};
1270 context.stepCallback = NULL;
1272 if (context.currentPage < (context.nbPages - 1)) {
1273 getContentPage(toogle_state, &contentPage);
1276 contentPage.icon = &C_icon_back_x;
1277 contentPage.text =
"Back";
1278 if (context.type == GENERIC_SETTINGS) {
1279 context.stepCallback = context.home.quitCallback;
1282 context.stepCallback = startUseCaseHome;
1286 if (contentPage.isSwitch) {
1288 pos, contentPage.text, contentPage.subText, contentPage.state, settingsCallback,
false);
1294 contentPage.subText,
1303static void startUseCaseHome(
void)
1306 if (context.home.homeAction) {
1310 switch (context.type) {
1311 case SETTINGS_USE_CASE:
1313 context.currentPage = 1 + addPages;
1317 context.currentPage = 2 + addPages;
1321 context.currentPage = 0;
1325 context.type = HOME_USE_CASE;
1326 context.nbPages = 2;
1327 if (context.home.settingContents) {
1330 if (context.home.infosList) {
1333 if (context.home.homeAction) {
1334 context.nbPages += addPages;
1339static void startUseCaseInfo(
void)
1341 context.type = INFO_USE_CASE;
1342 context.nbPages = context.home.infosList->nbInfos + 1;
1343 context.currentPage = 0;
1348static void startUseCaseSettingsAtPage(
uint8_t initSettingPage)
1354 if (context.type != GENERIC_SETTINGS) {
1355 context.
type = SETTINGS_USE_CASE;
1358 context.nbPages = 1;
1359 for (
int i = 0; i < context.home.settingContents->nbContents; i++) {
1360 p_content = getContentAtIdx(context.home.settingContents, i, &content);
1361 context.nbPages += getContentNbElement(p_content);
1363 context.currentPage = initSettingPage;
1368static void startUseCaseSettings(
void)
1370 startUseCaseSettingsAtPage(0);
1373static void startUseCaseContent(
void)
1379 context.nbPages = 1;
1381 for (contentIdx = 0; contentIdx < context.content.genericContents.nbContents; contentIdx++) {
1382 p_content = getContentAtIdx(&context.content.genericContents, contentIdx, &content);
1383 context.nbPages += getContentNbElement(p_content);
1392 const char *text = NULL;
1393 const char *subText = NULL;
1401 context.stepCallback = NULL;
1404 homeIndex = currentIndex++;
1405 if (context.home.homeAction) {
1406 actionIndex = currentIndex++;
1408 if (context.home.settingContents) {
1409 settingsIndex = currentIndex++;
1411 if (context.home.infosList) {
1412 infoIndex = currentIndex++;
1415 if (context.currentPage == homeIndex) {
1417 icon = context.home.appIcon;
1418 if (context.home.tagline != NULL) {
1419 text = context.home.tagline;
1422 text = context.home.appName;
1423 subText =
"app is ready";
1426 else if (context.currentPage == actionIndex) {
1428 icon = context.home.homeAction->icon;
1429 text = PIC(context.home.homeAction->text);
1430 context.stepCallback = context.home.homeAction->callback;
1432 else if (context.currentPage == settingsIndex) {
1434 icon = &C_icon_coggle;
1435 text =
"App settings";
1436 context.stepCallback = startUseCaseSettings;
1438 else if (context.currentPage == infoIndex) {
1440 icon = &C_Information_circle_14px;
1442 context.stepCallback = startUseCaseInfo;
1445 icon = &C_Quit_14px;
1447 context.stepCallback = context.home.quitCallback;
1450 drawStep(pos, icon, text, subText, homeCallback,
false, NO_FORCED_TYPE);
1457 const char *text = NULL;
1458 const char *subText = NULL;
1461 context.stepCallback = NULL;
1464 if (context.currentPage == 1
1465 && (context.choice.icon == NULL || context.choice.subMessage == NULL)) {
1467 context.currentPage -= 1;
1470 context.currentPage += 1;
1474 if (context.currentPage == 0) {
1475 text = context.choice.message;
1476 if (context.choice.icon != NULL) {
1477 icon = context.choice.icon;
1480 subText = context.choice.subMessage;
1483 else if (context.currentPage == 1) {
1485 text = context.choice.message;
1486 subText = context.choice.subMessage;
1488 else if (context.currentPage == 2) {
1489 icon = &C_icon_validate_14;
1490 text = context.choice.confirmText;
1491 context.stepCallback = onChoiceAccept;
1494 icon = &C_icon_crossmark;
1495 text = context.choice.cancelText;
1496 context.stepCallback = onChoiceReject;
1499 drawStep(pos, icon, text, subText, genericChoiceCallback,
false, NO_FORCED_TYPE);
1506 const char *text = NULL;
1507 const char *subText = NULL;
1510 context.stepCallback = NULL;
1511 switch (context.currentPage) {
1514 text = context.confirm.message;
1515 subText = context.confirm.subMessage;
1519 icon = &C_icon_validate_14;
1520 text = context.confirm.confirmText;
1521 context.stepCallback = onConfirmAccept;
1525 icon = &C_icon_crossmark;
1526 text = context.confirm.cancelText;
1527 context.stepCallback = onConfirmReject;
1531 drawStep(pos, icon, text, subText, genericConfirmCallback,
true, NO_FORCED_TYPE);
1538 PageContent_t contentPage = {0};
1540 context.stepCallback = NULL;
1542 if (context.currentPage < (context.nbPages - 1)) {
1543 getContentPage(toogle_state, &contentPage);
1546 if (context.content.rejectText) {
1547 contentPage.text = context.content.rejectText;
1550 contentPage.text =
"Back";
1552 if (context.type == GENERIC_REVIEW_USE_CASE) {
1553 contentPage.icon = &C_icon_crossmark;
1556 contentPage.icon = &C_icon_back_x;
1558 context.stepCallback = context.content.quitCallback;
1561 if (contentPage.isSwitch) {
1563 pos, contentPage.text, contentPage.subText, contentPage.state, contentCallback,
false);
1569 contentPage.subText,
1578static void displaySpinner(
const char *text)
1580 drawStep(
SINGLE_STEP, &C_icon_processing, text, NULL, NULL,
false,
false);
1585static void useCaseReview(ContextType_t type,
1589 const char *reviewTitle,
1590 const char *reviewSubTitle,
1591 const char *finishTitle,
1594 UNUSED(finishTitle);
1596 memset(&context, 0,
sizeof(UseCaseContext_t));
1597 context.type = type;
1598 context.operationType = operationType;
1599 context.review.tagValueList = tagValueList;
1600 context.review.reviewTitle = reviewTitle;
1601 context.review.reviewSubTitle = reviewSubTitle;
1602 context.review.icon = icon;
1603 context.review.onChoice = choiceCallback;
1604 context.currentPage = 0;
1606 context.nbPages = tagValueList->
nbPairs + 3;
1607 if (reviewSubTitle) {
1615static void setPinCodeText(
void)
1617 bool enableValidate =
false;
1618 bool enableBackspace =
true;
1621 enableValidate = (context.keypad.pinLen >= context.keypad.pinMinDigits);
1623 enableBackspace = (context.keypad.pinLen > 0) || (context.keypad.backCallback != NULL);
1625 context.keypad.hidden,
1626 context.keypad.pinLen,
1627 (
const char *) context.keypad.pinEntry);
1629 context.keypad.layoutCtx, context.keypad.keypadIndex, enableValidate, enableBackspace);
1635static void keypadCallback(
char touchedKey)
1637 switch (touchedKey) {
1639 if (context.keypad.pinLen > 0) {
1640 context.keypad.pinLen--;
1641 context.keypad.pinEntry[context.keypad.pinLen] = 0;
1643 else if (context.keypad.backCallback != NULL) {
1644 context.keypad.backCallback();
1651 context.keypad.validatePin(context.keypad.pinEntry, context.keypad.pinLen);
1655 if ((touchedKey >= 0x30) && (touchedKey < 0x40)) {
1656 if (context.keypad.pinLen < context.keypad.pinMaxDigits) {
1657 context.keypad.pinEntry[context.keypad.pinLen] = touchedKey;
1658 context.keypad.pinLen++;
1667static void keypadGenericUseCase(
const char *title,
1679 memset(&context, 0,
sizeof(KeypadContext_t));
1680 context.type = KEYPAD_USE_CASE;
1681 context.currentPage = 0;
1682 context.nbPages = 1;
1683 context.keypad.validatePin = validatePinCallback;
1684 context.keypad.backCallback = backCallback;
1685 context.keypad.pinMinDigits = minDigits;
1686 context.keypad.pinMaxDigits = maxDigits;
1687 context.keypad.hidden = hidden;
1695 context.keypad.keypadIndex = status;
1703 if (context.keypad.backCallback != NULL) {
1718 if (reviewWithWarnCtx.warningPage > 0) {
1719 reviewWithWarnCtx.warningPage--;
1724 if (reviewWithWarnCtx.warningPage < (reviewWithWarnCtx.nbWarningPages - 1)) {
1725 reviewWithWarnCtx.warningPage++;
1730 if (reviewWithWarnCtx.warningPage == 0) {
1731 if (reviewWithWarnCtx.type == REVIEW_USE_CASE) {
1732 useCaseReview(reviewWithWarnCtx.type,
1733 reviewWithWarnCtx.operationType,
1734 reviewWithWarnCtx.tagValueList,
1735 reviewWithWarnCtx.icon,
1736 reviewWithWarnCtx.reviewTitle,
1737 reviewWithWarnCtx.reviewSubTitle,
1738 reviewWithWarnCtx.finishTitle,
1739 reviewWithWarnCtx.choiceCallback);
1741 else if (reviewWithWarnCtx.type == STREAMING_START_REVIEW_USE_CASE) {
1746 else if (reviewWithWarnCtx.warningPage == (reviewWithWarnCtx.nbWarningPages - 1)) {
1747 reviewWithWarnCtx.choiceCallback(
false);
1754 displayWarningStep();
1758static void displayWarningStep(
void)
1762 if (reviewWithWarnCtx.warningPage == 0) {
1764 info.
icon = &C_icon_warning;
1765 info.
text1 =
"Blind signing ahead";
1766 info.
text2 =
"To accept risk, press both buttons";
1769 else if (reviewWithWarnCtx.warningPage == (reviewWithWarnCtx.nbWarningPages - 1)) {
1770 getLastPageInfo(
false, &info.
icon, &info.
text1);
1773 info.
style = BOLD_TEXT1_INFO;
1779static void displayInitialWarning(
void)
1782 reviewWithWarnCtx.warningPage = 0;
1783 reviewWithWarnCtx.nbWarningPages = 2;
1784 displayWarningStep();
1805 bool *requireSpecificDisplay)
1808 UNUSED(tagValueList);
1810 *requireSpecificDisplay =
true;
1830 bool *requireSpecificDisplay)
1833 UNUSED(tagValueList);
1835 UNUSED(isSkippable);
1836 *requireSpecificDisplay =
true;
1874 UNUSED(switchesList);
1914 UNUSED(choicesList);
1934 while (i < tagValueList->nbPairs) {
1938 nbPairs -= nbPairsInPage;
1967 if (initPage >= nbPages) {
1971 if (navCallback(initPage, &pageContent) ==
false) {
1974 memset(&context, 0,
sizeof(UseCaseContext_t));
1975 context.type = CONTENT_USE_CASE;
1976 context.content.quitCallback = quitCallback;
1977 context.content.controlsCallback = controlsCallback;
1978 context.content.genericContents.callbackCallNeeded =
false;
1979 context.content.genericContents.nbContents = nbPages;
1981 contentsList.
type = pageContent.
type;
1982 switch (pageContent.
type) {
2000 context.content.title = title;
2005 context.content.title = title;
2010 context.content.genericContents.contentsList = (
const nbgl_content_t *) &contentsList;
2012 startUseCaseContent();
2031 const char *tagline,
2032 const uint8_t initSettingPage,
2038 memset(&context, 0,
sizeof(UseCaseContext_t));
2039 context.home.appName = appName;
2040 context.home.appIcon = appIcon;
2041 context.home.tagline = tagline;
2042 context.home.settingContents = PIC(settingContents);
2043 context.home.infosList = PIC(infosList);
2044 context.home.homeAction = action;
2045 context.home.quitCallback = quitCallback;
2048 startUseCaseSettingsAtPage(initSettingPage);
2073 memset(&context, 0,
sizeof(UseCaseContext_t));
2074 context.type = GENERIC_SETTINGS;
2075 context.home.appName = appName;
2076 context.home.settingContents = PIC(settingContents);
2077 context.home.infosList = PIC(infosList);
2078 context.home.quitCallback = quitCallback;
2080 startUseCaseSettingsAtPage(initPage);
2119 const char *reviewTitle,
2120 const char *reviewSubTitle,
2121 const char *finishTitle,
2124 useCaseReview(REVIEW_USE_CASE,
2159 const char *reviewTitle,
2160 const char *reviewSubTitle,
2161 const char *finishTitle,
2167 ContextType_t type = REVIEW_USE_CASE;
2170 if ((warning == NULL)
2184 operationType |= NO_THREAT_OPERATION;
2187 operationType |= RISKY_OPERATION;
2190 memset(&reviewWithWarnCtx, 0,
sizeof(reviewWithWarnCtx));
2191 reviewWithWarnCtx.type = type;
2192 reviewWithWarnCtx.operationType = operationType;
2193 reviewWithWarnCtx.tagValueList = tagValueList;
2194 reviewWithWarnCtx.icon = icon;
2195 reviewWithWarnCtx.reviewTitle = reviewTitle;
2196 reviewWithWarnCtx.reviewSubTitle = reviewSubTitle;
2197 reviewWithWarnCtx.finishTitle = finishTitle;
2198 reviewWithWarnCtx.warning = warning;
2199 reviewWithWarnCtx.choiceCallback = choiceCallback;
2215 displayInitialWarning();
2240 const char *reviewTitle,
2241 const char *reviewSubTitle,
2242 const char *finishTitle,
2253 &blindSigningWarning,
2274 const char *reviewTitle,
2275 const char *reviewSubTitle,
2276 const char *finishTitle,
2307 const char *reviewTitle,
2308 const char *reviewSubTitle,
2311 memset(&context, 0,
sizeof(UseCaseContext_t));
2312 context.type = ADDRESS_REVIEW_USE_CASE;
2313 context.review.address = address;
2314 context.review.reviewTitle = reviewTitle;
2315 context.review.reviewSubTitle = reviewSubTitle;
2316 context.review.icon = icon;
2317 context.review.onChoice = choiceCallback;
2318 context.currentPage = 0;
2320 context.nbPages = 4;
2321 if (additionalTagValueList) {
2322 context.review.tagValueList = PIC(additionalTagValueList);
2323 context.nbPages += additionalTagValueList->
nbPairs;
2338 const char *rejectText,
2341 memset(&context, 0,
sizeof(UseCaseContext_t));
2342 context.type = GENERIC_REVIEW_USE_CASE;
2343 context.content.rejectText = rejectText;
2344 context.content.quitCallback = rejectCallback;
2345 context.content.genericContents.nbContents = contents->
nbContents;
2351 context.content.genericContents.contentsList = PIC(contents->
contentsList);
2354 startUseCaseContent();
2367 memset(&context, 0,
sizeof(UseCaseContext_t));
2368 context.type = STATUS_USE_CASE;
2369 context.stepCallback = quitCallback;
2370 context.currentPage = 0;
2371 context.nbPages = 1;
2373 drawStep(
SINGLE_STEP, NULL, message, NULL, statusButtonCallback,
false, NO_FORCED_TYPE);
2387 switch (reviewStatusType) {
2389 msg =
"Operation signed";
2393 msg =
"Operation rejected";
2397 msg =
"Transaction signed";
2401 msg =
"Transaction rejected";
2405 msg =
"Message signed";
2409 msg =
"Message rejected";
2413 msg =
"Address verified";
2417 msg =
"Address verification cancelled";
2440 const char *reviewTitle,
2441 const char *reviewSubTitle,
2444 memset(&context, 0,
sizeof(UseCaseContext_t));
2445 context.type = STREAMING_START_REVIEW_USE_CASE;
2446 context.operationType = operationType;
2447 context.review.reviewTitle = reviewTitle;
2448 context.review.reviewSubTitle = reviewSubTitle;
2449 context.review.icon = icon;
2450 context.review.onChoice = choiceCallback;
2451 context.currentPage = 0;
2452 context.nbPages = 2;
2472 const char *reviewTitle,
2473 const char *reviewSubTitle,
2477 operationType, icon, reviewTitle, reviewSubTitle, &blindSigningWarning, choiceCallback);
2497 const char *reviewTitle,
2498 const char *reviewSubTitle,
2502 memset(&context, 0,
sizeof(UseCaseContext_t));
2503 context.type = STREAMING_START_REVIEW_USE_CASE;
2504 context.operationType = operationType;
2505 context.review.reviewTitle = reviewTitle;
2506 context.review.reviewSubTitle = reviewSubTitle;
2507 context.review.icon = icon;
2508 context.review.onChoice = choiceCallback;
2509 context.currentPage = 0;
2510 context.nbPages = 2;
2513 if ((warning == NULL)
2520 operationType |= NO_THREAT_OPERATION;
2523 operationType |= RISKY_OPERATION;
2525 memset(&reviewWithWarnCtx, 0,
sizeof(reviewWithWarnCtx));
2527 reviewWithWarnCtx.type = context.type;
2528 reviewWithWarnCtx.operationType = operationType;
2529 reviewWithWarnCtx.icon = icon;
2530 reviewWithWarnCtx.reviewTitle = reviewTitle;
2531 reviewWithWarnCtx.reviewSubTitle = reviewSubTitle;
2532 reviewWithWarnCtx.choiceCallback = choiceCallback;
2533 reviewWithWarnCtx.warning = warning;
2542 displayInitialWarning();
2562 uint8_t curNbDataSets = context.review.nbDataSets;
2565 memset(&context, 0,
sizeof(UseCaseContext_t));
2566 context.type = STREAMING_CONTINUE_REVIEW_USE_CASE;
2567 context.operationType = operationType;
2568 context.review.tagValueList = tagValueList;
2569 context.review.onChoice = choiceCallback;
2570 context.currentPage = 0;
2571 context.nbPages = tagValueList->
nbPairs + 1;
2572 context.review.skipCallback = skipCallback;
2573 context.review.nbDataSets = curNbDataSets + 1;
2598 UNUSED(finishTitle);
2600 memset(&context, 0,
sizeof(UseCaseContext_t));
2601 context.type = STREAMING_FINISH_REVIEW_USE_CASE;
2602 context.operationType = operationType;
2603 context.review.onChoice = choiceCallback;
2604 context.currentPage = 0;
2605 context.nbPages = 2;
2617 memset(&context, 0,
sizeof(UseCaseContext_t));
2618 context.type = SPINNER_USE_CASE;
2619 context.currentPage = 0;
2620 context.nbPages = 1;
2622 displaySpinner(text);
2626 const char *message,
2627 const char *subMessage,
2628 const char *confirmText,
2629 const char *cancelText,
2632 memset(&context, 0,
sizeof(UseCaseContext_t));
2633 context.type = CHOICE_USE_CASE;
2634 context.choice.icon = icon;
2635 context.choice.message = message;
2636 context.choice.subMessage = subMessage;
2637 context.choice.confirmText = confirmText;
2638 context.choice.cancelText = cancelText;
2639 context.choice.onChoice = callback;
2640 context.currentPage = 0;
2641 context.nbPages = 1 + 1 + 2;
2660 const char *subMessage,
2661 const char *confirmText,
2662 const char *cancelText,
2665 memset(&context, 0,
sizeof(UseCaseContext_t));
2666 context.type = CONFIRM_USE_CASE;
2667 context.confirm.message = message;
2668 context.confirm.subMessage = subMessage;
2669 context.confirm.confirmText = confirmText;
2670 context.confirm.cancelText = cancelText;
2671 context.confirm.onConfirm = callback;
2672 context.currentPage = 0;
2673 context.nbPages = 1 + 2;
2703 keypadGenericUseCase(
2704 title, minDigits, maxDigits, shuffled,
false, validatePinCallback, backCallback);
2732 keypadGenericUseCase(
2733 title, minDigits, maxDigits, shuffled,
true, validatePinCallback, backCallback);
nbgl_contentCenteredInfoStyle_t
possible styles for Centered Info Area
@ CHOICES_LIST
list of choices through radio buttons
@ CENTERED_INFO
a centered info
@ SWITCHES_LIST
list of switches with descriptions
@ INFOS_LIST
list of infos with titles
@ TAG_VALUE_LIST
list of tag/value pairs
@ BARS_LIST
list of touchable bars (with > on the right to go to sub-pages)
@ INFO_BUTTON
a centered info and a simple black button
@ INFO_LIST_ALIAS
alias is list of infos
@ ENS_ALIAS
alias comes from ENS
void(* nbgl_contentActionCallback_t)(int token, uint8_t index, int page)
prototype of function to be called when an action on a content object occurs
#define LOG_WARN(__logger,...)
#define LOG_DEBUG(__logger,...)
void(* nbgl_stepCallback_t)(void)
prototype of function to be called when a step is using a callback on "double-key" action
void(* nbgl_layoutTouchCallback_t)(int token, uint8_t index)
prototype of function to be called when an object is touched
int nbgl_layoutUpdateKeypad(nbgl_layout_t *layout, uint8_t index, bool enableValidate, bool enableBackspace, bool enableDigits)
Updates an existing keypad on bottom of the screen, with the given configuration.
int nbgl_layoutDraw(nbgl_layout_t *layout)
Applies given layout. The screen will be redrawn.
void * nbgl_layout_t
type shared externally
int nbgl_layoutAddKeypadContent(nbgl_layout_t *layout, const char *title, bool hidden, uint8_t nbDigits, const char *text)
Adds an area with a title and a placeholder for hidden digits on top of a keypad, to represent the en...
int nbgl_layoutUpdateKeypadContent(nbgl_layout_t *layout, bool hidden, uint8_t nbActiveDigits, const char *text)
Updates an existing set of hidden digits, with the given configuration.
nbgl_layout_t * nbgl_layoutGet(const nbgl_layoutDescription_t *description)
returns a layout of the given type. The layout is reset
int nbgl_layoutAddKeypad(nbgl_layout_t *layout, keyboardCallback_t callback, bool shuffled)
Adds a keypad on bottom of the screen, with the associated callback.
void nbgl_refresh(void)
This functions refreshes the actual screen on display with what has changed since the last refresh.
@ BUTTON_BOTH_PRESSED
Sent when both buttons are released.
@ BUTTON_LEFT_PRESSED
Sent when Left button is released.
@ BUTTON_RIGHT_PRESSED
Send when Right button is released.
struct PACKED__ nbgl_screenTickerConfiguration_s nbgl_screenTickerConfiguration_t
struct to configure a screen layer
void nbgl_screenRedraw(void)
This function redraws the whole screen on top of stack and its children.
void(* nbgl_stepButtonCallback_t)(nbgl_step_t stepCtx, nbgl_buttonEvent_t event)
prototype of function to be called when buttons are touched on a screen
#define GET_POS_OF_STEP(_step, _nb_steps)
nbgl_step_t nbgl_stepDrawSwitch(nbgl_stepPosition_t pos, nbgl_stepButtonCallback_t onActionCallback, nbgl_screenTickerConfiguration_t *ticker, nbgl_layoutSwitch_t *switchInfo, bool modal)
void * nbgl_step_t
type shared externally
uint8_t nbgl_stepPosition_t
this type contains nbgl_layoutNavIndication_t in its LSBs and direction in its MSB (using FORWARD_DIR...
@ NEITHER_FIRST_NOR_LAST_STEP
neither first nor last in a multiple steps flow
@ SINGLE_STEP
single step flow
@ LAST_STEP
last in a multiple steps flow
@ FIRST_STEP
first in a multiple steps flow
nbgl_step_t nbgl_stepDrawMenuList(nbgl_stepMenuListCallback_t onActionCallback, nbgl_screenTickerConfiguration_t *ticker, nbgl_layoutMenuList_t *list, bool modal)
int nbgl_stepRelease(nbgl_step_t step)
#define FORWARD_DIRECTION
When the flow is navigated from last to first step.
nbgl_step_t nbgl_stepDrawText(nbgl_stepPosition_t pos, nbgl_stepButtonCallback_t onActionCallback, nbgl_screenTickerConfiguration_t *ticker, const char *text, const char *subText, nbgl_contentCenteredInfoStyle_t style, bool modal)
nbgl_step_t nbgl_stepDrawCenteredInfo(nbgl_stepPosition_t pos, nbgl_stepButtonCallback_t onActionCallback, nbgl_screenTickerConfiguration_t *ticker, nbgl_layoutCenteredInfo_t *info, bool modal)
#define BACKWARD_DIRECTION
nbgl_state_t
to represent a boolean state.
struct PACKED__ nbgl_icon_details_s nbgl_icon_details_t
Represents all information about an icon.
API of the Advanced BOLOS Graphical Library, for typical application use-cases.
uint8_t nbgl_useCaseGetNbTagValuesInPageExt(uint8_t nbPairs, const nbgl_contentTagValueList_t *tagValueList, uint8_t startIndex, bool isSkippable, bool *requireSpecificDisplay)
void(* nbgl_callback_t)(void)
prototype of generic callback function
void nbgl_useCaseGenericSettings(const char *appName, uint8_t initPage, const nbgl_genericContents_t *settingContents, const nbgl_contentInfoList_t *infosList, nbgl_callback_t quitCallback)
void nbgl_useCaseKeypadPIN(const char *title, uint8_t minDigits, uint8_t maxDigits, uint8_t backToken, bool shuffled, tune_index_e tuneId, nbgl_pinValidCallback_t validatePinCallback, nbgl_layoutTouchCallback_t actionCallback)
uint32_t nbgl_operationType_t
This mask is used to describe the type of operation to review with additional options It is a mask of...
void nbgl_useCaseReview(nbgl_operationType_t operationType, const nbgl_contentTagValueList_t *tagValueList, const nbgl_icon_details_t *icon, const char *reviewTitle, const char *reviewSubTitle, const char *finishTitle, nbgl_choiceCallback_t choiceCallback)
uint8_t nbgl_useCaseGetNbTagValuesInPage(uint8_t nbPairs, const nbgl_contentTagValueList_t *tagValueList, uint8_t startIndex, bool *requireSpecificDisplay)
uint8_t nbgl_useCaseGetNbPagesForTagValueList(const nbgl_contentTagValueList_t *tagValueList)
void(* nbgl_pinValidCallback_t)(const uint8_t *pin, uint8_t pinLen)
prototype of pin validation callback function
void nbgl_useCaseReviewStreamingStart(nbgl_operationType_t operationType, const nbgl_icon_details_t *icon, const char *reviewTitle, const char *reviewSubTitle, nbgl_choiceCallback_t choiceCallback)
void nbgl_useCaseHomeAndSettings(const char *appName, const nbgl_icon_details_t *appIcon, const char *tagline, const uint8_t initSettingPage, const nbgl_genericContents_t *settingContents, const nbgl_contentInfoList_t *infosList, const nbgl_homeAction_t *action, nbgl_callback_t quitCallback)
uint8_t nbgl_useCaseGetNbInfosInPage(uint8_t nbInfos, const nbgl_contentInfoList_t *infosList, uint8_t startIndex, bool withNav)
void(* nbgl_choiceCallback_t)(bool confirm)
prototype of choice callback function
uint8_t nbgl_useCaseGetNbBarsInPage(uint8_t nbBars, const nbgl_contentBarsList_t *barsList, uint8_t startIndex, bool withNav)
void nbgl_useCaseNavigableContent(const char *title, uint8_t initPage, uint8_t nbPages, nbgl_callback_t quitCallback, nbgl_navCallback_t navCallback, nbgl_layoutTouchCallback_t controlsCallback)
void nbgl_useCaseReviewStreamingFinish(const char *finishTitle, nbgl_choiceCallback_t choiceCallback)
void nbgl_useCaseSpinner(const char *text)
void nbgl_useCaseConfirm(const char *message, const char *subMessage, const char *confirmText, const char *rejectText, nbgl_callback_t callback)
void nbgl_useCaseKeypadDigits(const char *title, uint8_t minDigits, uint8_t maxDigits, uint8_t backToken, bool shuffled, tune_index_e tuneId, nbgl_pinValidCallback_t validatePinCallback, nbgl_layoutTouchCallback_t actionCallback)
void nbgl_useCaseStatus(const char *message, bool isSuccess, nbgl_callback_t quitCallback)
@ W3C_THREAT_DETECTED_WARN
Web3 Checks: Threat detected (see reportRisk field)
@ BLIND_SIGNING_WARN
Blind signing.
@ W3C_NO_THREAT_WARN
Web3 Checks: No Threat detected.
@ W3C_RISK_DETECTED_WARN
Web3 Checks: Risk detected (see reportRisk field)
void nbgl_useCaseGenericConfiguration(const char *title, uint8_t initPage, const nbgl_genericContents_t *contents, nbgl_callback_t quitCallback)
#define INIT_HOME_PAGE
Value to pass to nbgl_useCaseHomeAndSettings() initSettingPage parameter to initialize the use case o...
void nbgl_useCaseReviewStreamingContinueExt(const nbgl_contentTagValueList_t *tagValueList, nbgl_choiceCallback_t choiceCallback, nbgl_callback_t skipCallback)
void nbgl_useCaseReviewBlindSigning(nbgl_operationType_t operationType, const nbgl_contentTagValueList_t *tagValueList, const nbgl_icon_details_t *icon, const char *reviewTitle, const char *reviewSubTitle, const char *finishTitle, const nbgl_tipBox_t *tipBox, nbgl_choiceCallback_t choiceCallback)
void nbgl_useCaseChoice(const nbgl_icon_details_t *icon, const char *message, const char *subMessage, const char *confirmText, const char *rejectString, nbgl_choiceCallback_t callback)
void nbgl_useCaseGenericReview(const nbgl_genericContents_t *contents, const char *rejectText, nbgl_callback_t rejectCallback)
#define STATUS_SCREEN_DURATION
void nbgl_useCaseReviewStreamingBlindSigningStart(nbgl_operationType_t operationType, const nbgl_icon_details_t *icon, const char *reviewTitle, const char *reviewSubTitle, nbgl_choiceCallback_t choiceCallback)
void nbgl_useCaseReviewStreamingContinue(const nbgl_contentTagValueList_t *tagValueList, nbgl_choiceCallback_t choiceCallback)
void nbgl_useCaseReviewLight(nbgl_operationType_t operationType, const nbgl_contentTagValueList_t *tagValueList, const nbgl_icon_details_t *icon, const char *reviewTitle, const char *reviewSubTitle, const char *finishTitle, nbgl_choiceCallback_t choiceCallback)
uint8_t nbgl_useCaseGetNbChoicesInPage(uint8_t nbChoices, const nbgl_contentRadioChoice_t *choicesList, uint8_t startIndex, bool withNav)
void nbgl_useCaseReviewStatus(nbgl_reviewStatusType_t reviewStatusType, nbgl_callback_t quitCallback)
nbgl_reviewStatusType_t
The different types of review status.
@ STATUS_TYPE_TRANSACTION_REJECTED
@ STATUS_TYPE_ADDRESS_REJECTED
@ STATUS_TYPE_TRANSACTION_SIGNED
@ STATUS_TYPE_OPERATION_REJECTED
@ STATUS_TYPE_OPERATION_SIGNED
@ STATUS_TYPE_ADDRESS_VERIFIED
@ STATUS_TYPE_MESSAGE_SIGNED
@ STATUS_TYPE_MESSAGE_REJECTED
bool(* nbgl_navCallback_t)(uint8_t page, nbgl_pageContent_t *content)
prototype of navigation callback function
void nbgl_useCaseAddressReview(const char *address, const nbgl_contentTagValueList_t *additionalTagValueList, const nbgl_icon_details_t *icon, const char *reviewTitle, const char *reviewSubTitle, nbgl_choiceCallback_t choiceCallback)
@ TYPE_TRANSACTION
For operations transferring a coin or taken from an account to another.
void nbgl_useCaseAdvancedReviewStreamingStart(nbgl_operationType_t operationType, const nbgl_icon_details_t *icon, const char *reviewTitle, const char *reviewSubTitle, const nbgl_warning_t *warning, nbgl_choiceCallback_t choiceCallback)
void nbgl_useCaseAdvancedReview(nbgl_operationType_t operationType, const nbgl_contentTagValueList_t *tagValueList, const nbgl_icon_details_t *icon, const char *reviewTitle, const char *reviewSubTitle, const char *finishTitle, const nbgl_tipBox_t *tipBox, const nbgl_warning_t *warning, nbgl_choiceCallback_t choiceCallback)
uint8_t nbgl_useCaseGetNbSwitchesInPage(uint8_t nbSwitches, const nbgl_contentSwitchesList_t *switchesList, uint8_t startIndex, bool withNav)
This structure contains data to build a BARS_LIST content.
const uint8_t * tokens
array of tokens, one for each bar (nbBars items)
const char *const * barTexts
array of texts for each bar (nbBars items, in black/bold)
uint8_t nbBars
number of elements in barTexts and tokens array
This structure contains info to build a centered (vertically and horizontally) area,...
const char * text2
second text (can be null)
const char * text1
first text (can be null)
bool onTop
if set to true, align only horizontally
nbgl_contentCenteredInfoStyle_t style
style to apply to this info
const nbgl_icon_details_t * icon
a buffer containing the 1BPP icon
const char * buttonText
text of the long press button
const nbgl_icon_details_t * icon
a buffer containing the 1BPP icon
const char * text
centered text in large case
This structure contains data to build a INFOS_LIST content.
const char *const * infoContents
array of contents of infos (in black)
const char *const * infoTypes
array of types of infos (in black/bold)
uint8_t nbInfos
number of elements in infoTypes and infoContents array
This structure contains a list of names to build a list of radio buttons (on the right part of screen...
uint8_t token
the token that will be used as argument of the callback
uint8_t initChoice
index of the current choice
const char *const * names
array of strings giving the choices (nbChoices)
uint8_t nbChoices
number of choices
This structure contains info to build a switch (on the right) with a description (on the left),...
const char * text
main text for the switch
uint8_t token
the token that will be used as argument of the callback (unused on Nano)
nbgl_state_t initState
initial state of the switch
const char * subText
description under main text (NULL terminated, single line, may be null)
This structure contains a list of [tag,value] pairs.
const nbgl_contentTagValue_t * pairs
array of [tag,value] pairs (nbPairs items). If NULL, callback is used instead
nbgl_contentTagValueCallback_t callback
function to call to retrieve a given pair
This structure contains a [tag,value] pair and possible extensions.
const nbgl_contentValueExt_t * extension
if not NULL, gives additional info on value field
const char * value
string giving the value name
const char * item
string giving the tag name
This structure contains additions to a tag/value pair, to be able to build a screen to display these ...
This structure contains data to build a content.
nbgl_contentActionCallback_t contentActionCallback
callback to be called when an action on an object occurs
nbgl_contentType_t type
type of page content in the content union
uint8_t nbContents
number of contents
const nbgl_content_t * contentsList
array of nbgl_content_t (nbContents items).
nbgl_contentCallback_t contentGetterCallback
function to call to retrieve a given content
Structure describing the action button in Home Screen.
Structure containing all information when creating a layout. This structure must be passed as argumen...
This structure contains data to build a page in multi-pages mode (nbgl_pageDrawGenericContent)
nbgl_contentRadioChoice_t choicesList
CHOICES_LIST type
nbgl_contentSwitchesList_t switchesList
SWITCHES_LIST type
nbgl_contentBarsList_t barsList
BARS_LIST type
nbgl_contentInfoButton_t infoButton
INFO_BUTTON type
nbgl_contentInfoList_t infosList
INFOS_LIST type
nbgl_contentTagValueList_t tagValueList
TAG_VALUE_LIST type
nbgl_contentType_t type
type of page content in the following union
nbgl_contentCenteredInfo_t centeredInfo
CENTERED_INFO type
This structure contains data to build a SWITCHES_LIST content.
uint8_t nbSwitches
number of elements in switches and tokens array
const nbgl_contentSwitch_t * switches
array of switches (nbSwitches items)
The necessary parameters to build a tip-box in first review page and the modal if this tip box is tou...
The necessary parameters to build a warning page preceding a review. One can either use predefinedSet...
const nbgl_warningDetails_t * introDetails
const nbgl_warningDetails_t * reviewDetails
nbgl_contentInfoList_t infosList
INFOS_LIST type
nbgl_contentTagValueList_t tagValueList
TAG_VALUE_LIST type
nbgl_contentCenteredInfo_t centeredInfo
CENTERED_INFO type
nbgl_contentBarsList_t barsList
BARS_LIST type
nbgl_contentSwitchesList_t switchesList
SWITCHES_LIST type
nbgl_contentInfoButton_t infoButton
INFO_BUTTON type
nbgl_contentRadioChoice_t choicesList
CHOICES_LIST type