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)
44typedef struct ReviewContext_s {
48 const char *reviewTitle;
49 const char *reviewSubTitle;
50 const char *finishTitle;
64typedef struct ChoiceContext_s {
67 const char *subMessage;
68 const char *confirmText;
69 const char *cancelText;
73typedef struct ConfirmContext_s {
75 const char *subMessage;
76 const char *confirmText;
77 const char *cancelText;
82typedef struct ContentContext_s {
85 const char *rejectText;
91typedef struct HomeContext_s {
101typedef struct ActionContext_s {
106typedef struct KeypadContext_s {
123 GENERIC_REVIEW_USE_CASE,
124 ADDRESS_REVIEW_USE_CASE,
125 STREAMING_START_REVIEW_USE_CASE,
126 STREAMING_CONTINUE_REVIEW_USE_CASE,
127 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;
156 ActionContext_t action;
160typedef struct PageContent_s {
170typedef struct ReviewWithWarningContext_s {
175 const char *reviewTitle;
176 const char *reviewSubTitle;
177 const char *finishTitle;
184} ReviewWithWarningContext_t;
195static UseCaseContext_t context;
197static ReviewWithWarningContext_t reviewWithWarnCtx;
215static void displaySpinner(
const char *text);
217static void startUseCaseHome(
void);
218static void startUseCaseInfo(
void);
219static void startUseCaseSettings(
void);
220static void startUseCaseSettingsAtPage(
uint8_t initSettingPage);
221static void startUseCaseContent(
void);
223static void statusTickerCallback(
void);
226static void displayWarningStep(
void);
231 switch (content->
type) {
258 if (contentIdx < 0 || contentIdx >= genericContents->
nbContents) {
264 if (content == NULL) {
270 if (context.content.navCallback) {
271 if (context.content.navCallback(contentIdx, &pageContent) ==
true) {
274 switch (content->
type) {
328 switch (context.type) {
329 case SETTINGS_USE_CASE:
331 case GENERIC_SETTINGS:
332 genericContents = context.home.settingContents;
334 case CONTENT_USE_CASE:
335 case GENERIC_REVIEW_USE_CASE:
336 genericContents = &context.content.genericContents;
341 for (
int i = 0; i < genericContents->
nbContents; i++) {
342 p_content = getContentAtIdx(genericContents, i, content);
343 elemNbPages = getContentNbElement(p_content);
344 if (nbPages + elemNbPages > elemIdx) {
345 *elemContentIdx = context.currentPage - nbPages;
348 nbPages += elemNbPages;
354static const char *getChoiceName(
uint8_t choiceIndex)
364 p_content = getContentElemAtIdx(context.currentPage, &elemIdx, &content);
365 if (p_content == NULL) {
368 switch (p_content->
type) {
371 names = (
char **) PIC(contentChoices->
names);
376 names = (
char **) PIC(contentBars->
barTexts);
377 nbValues = contentBars->
nbBars;
383 if (choiceIndex >= nbValues) {
387 return (
const char *) PIC(names[choiceIndex]);
390static void onChoiceSelected(
uint8_t choiceIndex)
399 p_content = getContentElemAtIdx(context.currentPage, &elemIdx, &content);
400 if (p_content == NULL) {
403 switch (p_content->
type) {
406 if (choiceIndex < contentChoices->nbChoices) {
407 token = contentChoices->
token;
412 if (choiceIndex < contentBars->nbBars) {
413 token = contentBars->
tokens[choiceIndex];
420 if ((token != 255) && (context.content.controlsCallback != NULL)) {
421 context.content.controlsCallback(token, 0);
423 else if (context.content.quitCallback != NULL) {
424 context.content.quitCallback();
434 bool *isCenteredInfo)
438 if (tagValueList->
pairs != NULL) {
439 pair = PIC(&tagValueList->
pairs[index]);
442 pair = PIC(tagValueList->
callback(index));
445 *value = pair->
value;
450 *isCenteredInfo =
true;
458static void onReviewAccept(
void)
460 if (context.review.onChoice) {
461 context.review.onChoice(
true);
465static void onReviewReject(
void)
467 if (context.review.onChoice) {
468 context.review.onChoice(
false);
472static void onChoiceAccept(
void)
474 if (context.choice.onChoice) {
475 context.choice.onChoice(
true);
479static void onChoiceReject(
void)
481 if (context.choice.onChoice) {
482 context.choice.onChoice(
false);
486static void onConfirmAccept(
void)
488 if (context.confirm.currentStep) {
491 if (context.confirm.onConfirm) {
492 context.confirm.onConfirm();
496static void onConfirmReject(
void)
498 if (context.confirm.currentStep) {
505static void onSwitchAction(
void)
512 p_content = getContentElemAtIdx(context.currentPage, &elemIdx, &content);
518 switch (context.type) {
519 case SETTINGS_USE_CASE:
521 case GENERIC_SETTINGS:
524 case CONTENT_USE_CASE:
525 case GENERIC_REVIEW_USE_CASE:
533 actionCallback(contentSwitch->
token,
535 context.currentPage);
537 else if (context.content.controlsCallback != NULL) {
538 context.content.controlsCallback(contentSwitch->
token, 0);
548 ForcedType_t forcedType)
559 .tickerIntervale = 0,
565 if ((context.type == STREAMING_CONTINUE_REVIEW_USE_CASE)
566 && (context.review.skipCallback != NULL) && (context.review.nbDataSets > 1)) {
569 if ((context.type == STATUS_USE_CASE) || (context.type == SPINNER_USE_CASE)) {
572 if ((context.type == CONFIRM_USE_CASE) && (context.confirm.currentStep != NULL)) {
577 p_content = getContentElemAtIdx(context.currentPage, &elemIdx, &content);
579 switch (p_content->
type) {
601 else if ((icon == NULL) && (forcedType != FORCE_CENTERED_INFO)) {
603 if (subTxt != NULL) {
604 style = (forcedType == FORCE_BUTTON) ? BUTTON_INFO : BOLD_TEXT1_INFO;
607 style = REGULAR_INFO;
609 newStep =
nbgl_stepDrawText(pos, onActionCallback, p_ticker, txt, subTxt, style, modal);
617 if ((subTxt != NULL) || (context.stepCallback != NULL)) {
618 info.
style = BOLD_TEXT1_INFO;
621 info.
style = REGULAR_INFO;
625 if (context.type == CONFIRM_USE_CASE) {
626 context.confirm.currentStep = newStep;
632 const char *description,
641 switchInfo.
text = title;
642 switchInfo.
subText = description;
655 if (context.currentPage > 0) {
656 context.currentPage--;
660 else if ((context.type != STREAMING_CONTINUE_REVIEW_USE_CASE)
661 || (context.review.skipCallback == NULL) || (context.review.nbDataSets == 1)) {
668 if (context.currentPage < (
int) (context.nbPages - 1)) {
669 context.currentPage++;
679 if (context.stepCallback != NULL) {
680 context.stepCallback();
682 else if ((context.type == CONTENT_USE_CASE) || (context.type == SETTINGS_USE_CASE)
683 || (context.type == GENERIC_SETTINGS)
684 || (context.type == GENERIC_REVIEW_USE_CASE)) {
685 p_content = getContentElemAtIdx(context.currentPage, &elemIdx, &content);
686 if (p_content != NULL) {
687 switch (p_content->
type) {
702 index = context.currentPage;
711 else if (context.content.controlsCallback != NULL) {
712 context.content.controlsCallback(token, index);
727 if (!buttonGenericCallback(event, &pos)) {
731 displayReviewPage(pos);
742 if ((context.review.dataDirection ==
FORWARD_DIRECTION) && (context.currentPage > 0)) {
743 context.currentPage--;
750 && (context.currentPage < (
int) (context.nbPages - 1)) && (context.currentPage > 0)) {
751 context.currentPage++;
756 context.review.skipCallback();
762 displayStreamingReviewPage(pos);
771 context.action.actionCallback();
780 if (!buttonGenericCallback(event, &pos)) {
785 context.review.dataDirection = pos;
788 displayStreamingReviewPage(pos);
796 if (!buttonGenericCallback(event, &pos)) {
800 displaySettingsPage(pos,
false);
808 if (!buttonGenericCallback(event, &pos)) {
812 displayInfoPage(pos);
820 if (!buttonGenericCallback(event, &pos)) {
824 displayHomePage(pos);
832 if (!buttonGenericCallback(event, &pos)) {
836 displayChoicePage(pos);
844 if (!buttonGenericCallback(event, &pos)) {
857 if (context.stepCallback != NULL) {
858 context.stepCallback();
868 if (!buttonGenericCallback(event, &pos)) {
872 displayContent(pos,
false);
876static void statusTickerCallback(
void)
878 if (context.stepCallback != NULL) {
879 context.stepCallback();
891 if (context.review.currentExtensionPage > 0) {
892 context.review.currentExtensionPage--;
898 if (context.review.currentExtensionPage < (context.review.nbExtensionPages - 1)) {
899 context.review.currentExtensionPage++;
905 if (context.review.currentExtensionPage == (context.review.nbExtensionPages - 1)) {
915 displayExtensionStep(pos);
923 if (context.review.extensionStepCtx != NULL) {
926 if (context.review.currentExtensionPage < (context.review.nbExtensionPages - 1)) {
927 if (context.review.currentExtensionPage == 0) {
934 if (context.review.extension->aliasType ==
ENS_ALIAS) {
938 context.review.extension->title,
939 context.review.extension->fullValue,
948 context.review.extension->infolist->infoTypes[context.review.currentExtensionPage],
949 context.review.extension->infolist
950 ->infoContents[context.review.currentExtensionPage],
955 else if (context.review.currentExtensionPage == (context.review.nbExtensionPages - 1)) {
957 info.
icon = &C_icon_back_x;
959 info.
style = BOLD_TEXT1_INFO;
961 context.review.extensionStepCtx
967static void displayAliasFullValue(
void)
969 const char *text = NULL;
970 const char *subText = NULL;
974 getPairData(context.review.tagValueList,
975 context.review.currentTagValueIndex,
978 &context.review.extension,
981 if (context.review.extension == NULL) {
984 "displayAliasFullValue: extension nor found for pair %d\n",
985 context.review.currentTagValueIndex);
988 context.review.currentExtensionPage = 0;
989 context.review.extensionStepCtx = NULL;
991 if (context.review.extension->aliasType ==
ENS_ALIAS) {
992 context.review.nbExtensionPages = 2;
995 context.review.nbExtensionPages = context.review.extension->infolist->nbInfos + 1;
999 "displayAliasFullValue: unsupported alias type %d\n",
1000 context.review.extension->aliasType);
1006static void getLastPageInfo(
bool approve,
const nbgl_icon_details_t **icon,
const char **text)
1010 *icon = &C_icon_validate_14;
1011 if (context.type == ADDRESS_REVIEW_USE_CASE) {
1016 if (context.review.finishTitle != NULL) {
1017 *text = context.review.finishTitle;
1022 if (context.operationType & RISKY_OPERATION) {
1023 *text =
"Accept risk and sign transaction";
1026 *text =
"Sign transaction";
1030 if (context.operationType & RISKY_OPERATION) {
1031 *text =
"Accept risk and sign message";
1034 *text =
"Sign message";
1038 if (context.operationType & RISKY_OPERATION) {
1039 *text =
"Accept risk and sign operation";
1042 *text =
"Sign operation";
1048 context.stepCallback = onReviewAccept;
1052 *icon = &C_icon_crossmark;
1053 if (context.type == ADDRESS_REVIEW_USE_CASE) {
1057 *text =
"Reject transaction";
1060 *text =
"Reject message";
1063 *text =
"Reject operation";
1065 context.stepCallback = onReviewReject;
1075 const char *text = NULL;
1076 const char *subText = NULL;
1084 ForcedType_t forcedType = NO_FORCED_TYPE;
1086 context.stepCallback = NULL;
1090 titleIndex = currentIndex++;
1092 if (context.review.reviewSubTitle) {
1094 subIndex = currentIndex++;
1097 approveIndex = context.nbPages - 2;
1098 rejectIndex = context.nbPages - 1;
1099 finalPages = approveIndex;
1102 if (context.currentPage >= finalPages) {
1103 if (context.currentPage == approveIndex) {
1105 getLastPageInfo(
true, &icon, &text);
1107 else if (context.currentPage == rejectIndex) {
1109 getLastPageInfo(
false, &icon, &text);
1112 else if (context.currentPage < reviewPages) {
1113 if (context.currentPage == titleIndex) {
1115 icon = context.review.icon;
1116 text = context.review.reviewTitle;
1118 else if (context.currentPage == subIndex) {
1120 text = context.review.reviewSubTitle;
1123 else if ((context.review.address != NULL) && (context.currentPage == reviewPages)) {
1126 subText = context.review.address;
1129 bool isCenteredInfo =
false;
1130 pairIndex = context.currentPage - reviewPages;
1131 if (context.review.address != NULL) {
1134 getPairData(context.review.tagValueList,
1141 if (extension != NULL) {
1142 context.stepCallback = displayAliasFullValue;
1143 context.review.currentTagValueIndex = pairIndex;
1144 forcedType = FORCE_BUTTON;
1147 if (isCenteredInfo) {
1148 forcedType = FORCE_CENTERED_INFO;
1153 drawStep(pos, icon, text, subText, reviewCallback,
false, forcedType);
1160 const char *text = NULL;
1161 const char *subText = NULL;
1167 ForcedType_t forcedType = NO_FORCED_TYPE;
1169 context.stepCallback = NULL;
1170 switch (context.type) {
1171 case STREAMING_START_REVIEW_USE_CASE:
1173 titleIndex = reviewPages++;
1174 if (context.review.reviewSubTitle) {
1176 subIndex = reviewPages++;
1179 if (context.currentPage >= reviewPages) {
1184 if (context.currentPage == titleIndex) {
1186 icon = context.review.icon;
1187 text = context.review.reviewTitle;
1189 else if (context.currentPage == subIndex) {
1191 text = context.review.reviewSubTitle;
1195 case STREAMING_CONTINUE_REVIEW_USE_CASE:
1196 if (context.currentPage >= context.review.tagValueList->nbPairs) {
1203 if ((context.review.skipCallback != NULL) && (context.review.skipDisplay ==
false)
1204 && ((context.review.nbDataSets > 1) || (context.currentPage > 0)
1208 if ((context.review.nbDataSets == 1) || (context.currentPage > 0)) {
1211 info.
icon = &C_Information_circle_14px;
1212 info.
text1 =
"Press right button to continue message or \bpress both to skip\b";
1215 context.review.skipDisplay =
true;
1218 context.review.skipDisplay =
false;
1219 bool isCenteredInfo =
false;
1220 getPairData(context.review.tagValueList,
1221 context.currentPage,
1227 if (extension != NULL) {
1228 forcedType = FORCE_BUTTON;
1231 if (isCenteredInfo) {
1232 forcedType = FORCE_CENTERED_INFO;
1237 case STREAMING_FINISH_REVIEW_USE_CASE:
1239 if (context.currentPage == 0) {
1241 getLastPageInfo(
true, &icon, &text);
1245 getLastPageInfo(
false, &icon, &text);
1250 drawStep(pos, icon, text, subText, streamingReviewCallback,
false, forcedType);
1257 const char *text = NULL;
1258 const char *subText = NULL;
1261 context.stepCallback = NULL;
1263 if (context.currentPage < (context.nbPages - 1)) {
1265 ((
const char *
const *) PIC(context.home.infosList->infoTypes))[context.currentPage]);
1267 ((
const char *
const *) PIC(context.home.infosList->infoContents))[context.currentPage]);
1270 icon = &C_icon_back_x;
1272 context.stepCallback = startUseCaseHome;
1275 drawStep(pos, icon, text, subText, infoCallback,
false, FORCE_CENTERED_INFO);
1280static void getContentPage(
bool toogle_state, PageContent_t *contentPage)
1286#ifdef WITH_HORIZONTAL_CHOICES_LIST
1288 char **names = NULL;
1290#ifdef WITH_HORIZONTAL_BARS_LIST
1292 char **texts = NULL;
1294 p_content = getContentElemAtIdx(context.currentPage, &elemIdx, &content);
1295 if (p_content == NULL) {
1298 switch (p_content->
type) {
1312 &contentPage->subText,
1313 &contentPage->extension,
1315 &contentPage->isCenteredInfo);
1318 contentPage->isSwitch =
true;
1321 contentPage->
text = contentSwitch->
text;
1322 contentPage->state = contentSwitch->
initState;
1326 context.stepCallback = onSwitchAction;
1327 contentPage->subText = contentSwitch->
subText;
1332 contentPage->subText
1336#ifdef WITH_HORIZONTAL_CHOICES_LIST
1338 names = (
char **) PIC(contentChoices->
names);
1339 if ((context.type == CONTENT_USE_CASE) && (context.content.title != NULL)) {
1340 contentPage->text = PIC(context.content.title);
1341 contentPage->subText = (
const char *) PIC(names[elemIdx]);
1343 else if ((context.type == GENERIC_SETTINGS) && (context.home.appName != NULL)) {
1344 contentPage->text = PIC(context.home.appName);
1345 contentPage->subText = (
const char *) PIC(names[elemIdx]);
1348 contentPage->text = (
const char *) PIC(names[elemIdx]);
1353#ifdef WITH_HORIZONTAL_BARS_LIST
1355 texts = (
char **) PIC(contentBars->
barTexts);
1356 if ((context.type == CONTENT_USE_CASE) && (context.content.title != NULL)) {
1357 contentPage->text = PIC(context.content.title);
1358 contentPage->subText = PIC(texts[elemIdx]);
1360 else if ((context.type == GENERIC_SETTINGS) && (context.home.appName != NULL)) {
1361 contentPage->text = PIC(context.home.appName);
1362 contentPage->subText = PIC(texts[elemIdx]);
1365 contentPage->text = PIC(texts[elemIdx]);
1377 PageContent_t contentPage = {0};
1379 context.stepCallback = NULL;
1381 if (context.currentPage < (context.nbPages - 1)) {
1382 getContentPage(toogle_state, &contentPage);
1385 contentPage.icon = &C_icon_back_x;
1386 contentPage.text =
"Back";
1387 if (context.type == GENERIC_SETTINGS) {
1388 context.stepCallback = context.home.quitCallback;
1391 context.stepCallback = startUseCaseHome;
1395 if (contentPage.isSwitch) {
1397 pos, contentPage.text, contentPage.subText, contentPage.state, settingsCallback,
false);
1403 contentPage.subText,
1412static void startUseCaseHome(
void)
1414 switch (context.type) {
1415 case SETTINGS_USE_CASE:
1417 context.currentPage = 1;
1418 if (context.home.homeAction) {
1420 context.currentPage++;
1425 context.currentPage = 1;
1426 if (context.home.homeAction) {
1428 context.currentPage++;
1430 if (context.home.settingContents) {
1432 context.currentPage++;
1437 context.currentPage = 0;
1441 context.type = HOME_USE_CASE;
1442 context.nbPages = 2;
1443 if (context.home.settingContents) {
1446 if (context.home.infosList) {
1449 if (context.home.homeAction) {
1455static void startUseCaseInfo(
void)
1457 context.type = INFO_USE_CASE;
1458 context.nbPages = context.home.infosList->nbInfos + 1;
1459 context.currentPage = 0;
1464static void startUseCaseSettingsAtPage(
uint8_t initSettingPage)
1470 if (context.type != GENERIC_SETTINGS) {
1471 context.
type = SETTINGS_USE_CASE;
1474 context.nbPages = 1;
1475 for (
int i = 0; i < context.home.settingContents->nbContents; i++) {
1476 p_content = getContentAtIdx(context.home.settingContents, i, &content);
1477 context.nbPages += getContentNbElement(p_content);
1479 context.currentPage = initSettingPage;
1484static void startUseCaseSettings(
void)
1486 startUseCaseSettingsAtPage(0);
1489static void startUseCaseContent(
void)
1495 context.nbPages = 1;
1497 for (contentIdx = 0; contentIdx < context.content.genericContents.nbContents; contentIdx++) {
1498 p_content = getContentAtIdx(&context.content.genericContents, contentIdx, &content);
1499 context.nbPages += getContentNbElement(p_content);
1503 if (context.currentPage >= context.nbPages) {
1513 const char *text = NULL;
1514 const char *subText = NULL;
1522 context.stepCallback = NULL;
1525 homeIndex = currentIndex++;
1526 if (context.home.homeAction) {
1527 actionIndex = currentIndex++;
1529 if (context.home.settingContents) {
1530 settingsIndex = currentIndex++;
1532 if (context.home.infosList) {
1533 infoIndex = currentIndex++;
1536 if (context.currentPage == homeIndex) {
1538 icon = context.home.appIcon;
1539 if (context.home.tagline != NULL) {
1540 text = context.home.tagline;
1543 text = context.home.appName;
1544 subText =
"app is ready";
1547 else if (context.currentPage == actionIndex) {
1549 icon = context.home.homeAction->icon;
1550 text = PIC(context.home.homeAction->text);
1551 context.stepCallback = context.home.homeAction->callback;
1553 else if (context.currentPage == settingsIndex) {
1555 icon = &C_icon_coggle;
1556 text =
"App settings";
1557 context.stepCallback = startUseCaseSettings;
1559 else if (context.currentPage == infoIndex) {
1561 icon = &C_Information_circle_14px;
1563 context.stepCallback = startUseCaseInfo;
1566 icon = &C_Quit_14px;
1568 context.stepCallback = context.home.quitCallback;
1571 drawStep(pos, icon, text, subText, homeCallback,
false, NO_FORCED_TYPE);
1578 const char *text = NULL;
1579 const char *subText = NULL;
1582 context.stepCallback = NULL;
1585 if (context.currentPage == 1
1586 && (context.choice.icon == NULL || context.choice.subMessage == NULL)) {
1588 context.currentPage -= 1;
1591 context.currentPage += 1;
1595 if (context.currentPage == 0) {
1596 text = context.choice.message;
1597 if (context.choice.icon != NULL) {
1598 icon = context.choice.icon;
1601 subText = context.choice.subMessage;
1604 else if (context.currentPage == 1) {
1606 text = context.choice.message;
1607 subText = context.choice.subMessage;
1609 else if (context.currentPage == 2) {
1610 icon = &C_icon_validate_14;
1611 text = context.choice.confirmText;
1612 context.stepCallback = onChoiceAccept;
1615 icon = &C_icon_crossmark;
1616 text = context.choice.cancelText;
1617 context.stepCallback = onChoiceReject;
1620 drawStep(pos, icon, text, subText, genericChoiceCallback,
false, NO_FORCED_TYPE);
1627 const char *text = NULL;
1628 const char *subText = NULL;
1631 context.stepCallback = NULL;
1632 switch (context.currentPage) {
1635 text = context.confirm.message;
1636 subText = context.confirm.subMessage;
1640 icon = &C_icon_validate_14;
1641 text = context.confirm.confirmText;
1642 context.stepCallback = onConfirmAccept;
1646 icon = &C_icon_crossmark;
1647 text = context.confirm.cancelText;
1648 context.stepCallback = onConfirmReject;
1652 drawStep(pos, icon, text, subText, genericConfirmCallback,
true, NO_FORCED_TYPE);
1659 PageContent_t contentPage = {0};
1660 ForcedType_t forcedType = NO_FORCED_TYPE;
1662 context.stepCallback = NULL;
1664 if (context.currentPage < (context.nbPages - 1)) {
1665 getContentPage(toogle_state, &contentPage);
1666 if (contentPage.isCenteredInfo) {
1667 forcedType = FORCE_CENTERED_INFO;
1671 if (context.content.rejectText) {
1672 contentPage.text = context.content.rejectText;
1675 contentPage.text =
"Back";
1677 if (context.type == GENERIC_REVIEW_USE_CASE) {
1678 contentPage.icon = &C_icon_crossmark;
1681 contentPage.icon = &C_icon_back_x;
1683 context.stepCallback = context.content.quitCallback;
1686 if (contentPage.isSwitch) {
1688 pos, contentPage.text, contentPage.subText, contentPage.state, contentCallback,
false);
1694 contentPage.subText,
1703static void displaySpinner(
const char *text)
1705 drawStep(
SINGLE_STEP, &C_icon_processing, text, NULL, NULL,
false,
false);
1710static void useCaseReview(ContextType_t type,
1714 const char *reviewTitle,
1715 const char *reviewSubTitle,
1716 const char *finishTitle,
1719 memset(&context, 0,
sizeof(UseCaseContext_t));
1720 context.type = type;
1721 context.operationType = operationType;
1722 context.review.tagValueList = tagValueList;
1723 context.review.reviewTitle = reviewTitle;
1724 context.review.reviewSubTitle = reviewSubTitle;
1725 context.review.finishTitle = finishTitle;
1726 context.review.icon = icon;
1727 context.review.onChoice = choiceCallback;
1728 context.currentPage = 0;
1730 context.nbPages = tagValueList->
nbPairs + 3;
1731 if (reviewSubTitle) {
1739static void setPinCodeText(
void)
1741 bool enableValidate =
false;
1742 bool enableBackspace =
true;
1745 enableValidate = (context.keypad.pinLen >= context.keypad.pinMinDigits);
1747 enableBackspace = (context.keypad.pinLen > 0) || (context.keypad.backCallback != NULL);
1749 context.keypad.hidden,
1750 context.keypad.pinLen,
1751 (
const char *) context.keypad.pinEntry);
1753 context.keypad.layoutCtx, context.keypad.keypadIndex, enableValidate, enableBackspace);
1759static void keypadCallback(
char touchedKey)
1761 switch (touchedKey) {
1763 if (context.keypad.pinLen > 0) {
1764 context.keypad.pinLen--;
1765 context.keypad.pinEntry[context.keypad.pinLen] = 0;
1767 else if (context.keypad.backCallback != NULL) {
1768 context.keypad.backCallback();
1775 context.keypad.validatePin(context.keypad.pinEntry, context.keypad.pinLen);
1779 if ((touchedKey >= 0x30) && (touchedKey < 0x40)) {
1780 if (context.keypad.pinLen < context.keypad.pinMaxDigits) {
1781 context.keypad.pinEntry[context.keypad.pinLen] = touchedKey;
1782 context.keypad.pinLen++;
1791static void keypadGenericUseCase(
const char *title,
1803 memset(&context, 0,
sizeof(KeypadContext_t));
1804 context.type = KEYPAD_USE_CASE;
1805 context.currentPage = 0;
1806 context.nbPages = 1;
1807 context.keypad.validatePin = validatePinCallback;
1808 context.keypad.backCallback = backCallback;
1809 context.keypad.pinMinDigits = minDigits;
1810 context.keypad.pinMaxDigits = maxDigits;
1811 context.keypad.hidden = hidden;
1819 context.keypad.keypadIndex = status;
1827 if (context.keypad.backCallback != NULL) {
1842 if (reviewWithWarnCtx.warningPage > 0) {
1843 reviewWithWarnCtx.warningPage--;
1848 if (reviewWithWarnCtx.warningPage < (reviewWithWarnCtx.nbWarningPages - 1)) {
1849 reviewWithWarnCtx.warningPage++;
1854 if (reviewWithWarnCtx.warningPage == 0) {
1855 if (reviewWithWarnCtx.type == REVIEW_USE_CASE) {
1856 useCaseReview(reviewWithWarnCtx.type,
1857 reviewWithWarnCtx.operationType,
1858 reviewWithWarnCtx.tagValueList,
1859 reviewWithWarnCtx.icon,
1860 reviewWithWarnCtx.reviewTitle,
1861 reviewWithWarnCtx.reviewSubTitle,
1862 reviewWithWarnCtx.finishTitle,
1863 reviewWithWarnCtx.choiceCallback);
1865 else if (reviewWithWarnCtx.type == STREAMING_START_REVIEW_USE_CASE) {
1870 else if (reviewWithWarnCtx.warningPage == (reviewWithWarnCtx.nbWarningPages - 1)) {
1871 reviewWithWarnCtx.choiceCallback(
false);
1878 displayWarningStep();
1882static void displayWarningStep(
void)
1886 if (reviewWithWarnCtx.warningPage == 0) {
1888 info.
icon = &C_icon_warning;
1889 info.
text1 =
"Blind signing ahead";
1890 info.
text2 =
"To accept risk, press both buttons";
1893 else if (reviewWithWarnCtx.warningPage == (reviewWithWarnCtx.nbWarningPages - 1)) {
1894 getLastPageInfo(
false, &info.
icon, &info.
text1);
1897 info.
style = BOLD_TEXT1_INFO;
1903static void displayInitialWarning(
void)
1906 reviewWithWarnCtx.warningPage = 0;
1907 reviewWithWarnCtx.nbWarningPages = 2;
1908 displayWarningStep();
1929 bool *requireSpecificDisplay)
1932 UNUSED(tagValueList);
1934 *requireSpecificDisplay =
true;
1954 bool *requireSpecificDisplay)
1957 UNUSED(tagValueList);
1959 UNUSED(isSkippable);
1960 *requireSpecificDisplay =
true;
1998 UNUSED(switchesList);
2038 UNUSED(choicesList);
2058 while (i < tagValueList->nbPairs) {
2062 nbPairs -= nbPairsInPage;
2088 memset(&context, 0,
sizeof(UseCaseContext_t));
2089 context.type = CONTENT_USE_CASE;
2090 context.currentPage = initPage;
2091 context.content.title = title;
2092 context.content.quitCallback = quitCallback;
2093 context.content.navCallback = navCallback;
2094 context.content.controlsCallback = controlsCallback;
2095 context.content.genericContents.callbackCallNeeded =
true;
2096 context.content.genericContents.nbContents = nbPages;
2098 startUseCaseContent();
2117 const char *tagline,
2118 const uint8_t initSettingPage,
2124 memset(&context, 0,
sizeof(UseCaseContext_t));
2125 context.home.appName = appName;
2126 context.home.appIcon = appIcon;
2127 context.home.tagline = tagline;
2128 context.home.settingContents = PIC(settingContents);
2129 context.home.infosList = PIC(infosList);
2130 context.home.homeAction = action;
2131 context.home.quitCallback = quitCallback;
2133 if ((initSettingPage !=
INIT_HOME_PAGE) && (settingContents != NULL)) {
2134 startUseCaseSettingsAtPage(initSettingPage);
2159 memset(&context, 0,
sizeof(UseCaseContext_t));
2160 context.type = GENERIC_SETTINGS;
2161 context.home.appName = appName;
2162 context.home.settingContents = PIC(settingContents);
2163 context.home.infosList = PIC(infosList);
2164 context.home.quitCallback = quitCallback;
2166 startUseCaseSettingsAtPage(initPage);
2205 const char *reviewTitle,
2206 const char *reviewSubTitle,
2207 const char *finishTitle,
2210 useCaseReview(REVIEW_USE_CASE,
2245 const char *reviewTitle,
2246 const char *reviewSubTitle,
2247 const char *finishTitle,
2253 ContextType_t type = REVIEW_USE_CASE;
2256 if ((warning == NULL)
2270 operationType |= NO_THREAT_OPERATION;
2273 operationType |= RISKY_OPERATION;
2276 memset(&reviewWithWarnCtx, 0,
sizeof(reviewWithWarnCtx));
2277 reviewWithWarnCtx.type = type;
2278 reviewWithWarnCtx.operationType = operationType;
2279 reviewWithWarnCtx.tagValueList = tagValueList;
2280 reviewWithWarnCtx.icon = icon;
2281 reviewWithWarnCtx.reviewTitle = reviewTitle;
2282 reviewWithWarnCtx.reviewSubTitle = reviewSubTitle;
2283 reviewWithWarnCtx.finishTitle = finishTitle;
2284 reviewWithWarnCtx.warning = warning;
2285 reviewWithWarnCtx.choiceCallback = choiceCallback;
2301 displayInitialWarning();
2326 const char *reviewTitle,
2327 const char *reviewSubTitle,
2328 const char *finishTitle,
2339 &blindSigningWarning,
2360 const char *reviewTitle,
2361 const char *reviewSubTitle,
2362 const char *finishTitle,
2393 const char *reviewTitle,
2394 const char *reviewSubTitle,
2397 memset(&context, 0,
sizeof(UseCaseContext_t));
2398 context.type = ADDRESS_REVIEW_USE_CASE;
2399 context.review.address = address;
2400 context.review.reviewTitle = reviewTitle;
2401 context.review.reviewSubTitle = reviewSubTitle;
2402 context.review.icon = icon;
2403 context.review.onChoice = choiceCallback;
2404 context.currentPage = 0;
2406 context.nbPages = 4;
2407 if (additionalTagValueList) {
2408 context.review.tagValueList = PIC(additionalTagValueList);
2409 context.nbPages += additionalTagValueList->
nbPairs;
2424 const char *rejectText,
2427 memset(&context, 0,
sizeof(UseCaseContext_t));
2428 context.type = GENERIC_REVIEW_USE_CASE;
2429 context.content.rejectText = rejectText;
2430 context.content.quitCallback = rejectCallback;
2431 context.content.genericContents.nbContents = contents->
nbContents;
2437 context.content.genericContents.contentsList = PIC(contents->
contentsList);
2440 startUseCaseContent();
2454 memset(&context, 0,
sizeof(UseCaseContext_t));
2455 context.type = STATUS_USE_CASE;
2456 context.stepCallback = quitCallback;
2457 context.currentPage = 0;
2458 context.nbPages = 1;
2464 statusButtonCallback,
2480 switch (reviewStatusType) {
2482 msg =
"Operation signed";
2486 msg =
"Operation rejected";
2490 msg =
"Transaction signed";
2494 msg =
"Transaction rejected";
2498 msg =
"Message signed";
2502 msg =
"Message rejected";
2506 msg =
"Address verified";
2510 msg =
"Address verification cancelled";
2533 const char *reviewTitle,
2534 const char *reviewSubTitle,
2538 streamingOpType = operationType;
2540 memset(&context, 0,
sizeof(UseCaseContext_t));
2541 context.type = STREAMING_START_REVIEW_USE_CASE;
2542 context.operationType = operationType;
2543 context.review.reviewTitle = reviewTitle;
2544 context.review.reviewSubTitle = reviewSubTitle;
2545 context.review.icon = icon;
2546 context.review.onChoice = choiceCallback;
2547 context.currentPage = 0;
2548 context.nbPages = 2;
2568 const char *reviewTitle,
2569 const char *reviewSubTitle,
2573 operationType, icon, reviewTitle, reviewSubTitle, &blindSigningWarning, choiceCallback);
2593 const char *reviewTitle,
2594 const char *reviewSubTitle,
2598 memset(&context, 0,
sizeof(UseCaseContext_t));
2599 context.type = STREAMING_START_REVIEW_USE_CASE;
2600 context.operationType = operationType;
2601 context.review.reviewTitle = reviewTitle;
2602 context.review.reviewSubTitle = reviewSubTitle;
2603 context.review.icon = icon;
2604 context.review.onChoice = choiceCallback;
2605 context.currentPage = 0;
2606 context.nbPages = 2;
2609 streamingOpType = operationType;
2612 if ((warning == NULL)
2619 operationType |= NO_THREAT_OPERATION;
2622 operationType |= RISKY_OPERATION;
2624 memset(&reviewWithWarnCtx, 0,
sizeof(reviewWithWarnCtx));
2626 reviewWithWarnCtx.type = context.type;
2627 reviewWithWarnCtx.operationType = operationType;
2628 reviewWithWarnCtx.icon = icon;
2629 reviewWithWarnCtx.reviewTitle = reviewTitle;
2630 reviewWithWarnCtx.reviewSubTitle = reviewSubTitle;
2631 reviewWithWarnCtx.choiceCallback = choiceCallback;
2632 reviewWithWarnCtx.warning = warning;
2641 displayInitialWarning();
2661 uint8_t curNbDataSets = context.review.nbDataSets;
2663 memset(&context, 0,
sizeof(UseCaseContext_t));
2664 context.type = STREAMING_CONTINUE_REVIEW_USE_CASE;
2665 context.operationType = streamingOpType;
2666 context.review.tagValueList = tagValueList;
2667 context.review.onChoice = choiceCallback;
2668 context.currentPage = 0;
2669 context.nbPages = tagValueList->
nbPairs + 1;
2670 context.review.skipCallback = skipCallback;
2671 context.review.nbDataSets = curNbDataSets + 1;
2695 memset(&context, 0,
sizeof(UseCaseContext_t));
2696 context.type = STREAMING_FINISH_REVIEW_USE_CASE;
2697 context.operationType = streamingOpType;
2698 context.review.onChoice = choiceCallback;
2699 context.review.finishTitle = finishTitle;
2700 context.currentPage = 0;
2701 context.nbPages = 2;
2713 memset(&context, 0,
sizeof(UseCaseContext_t));
2714 context.type = SPINNER_USE_CASE;
2715 context.currentPage = 0;
2716 context.nbPages = 1;
2718 displaySpinner(text);
2722 const char *message,
2723 const char *subMessage,
2724 const char *confirmText,
2725 const char *cancelText,
2728 memset(&context, 0,
sizeof(UseCaseContext_t));
2729 context.type = CHOICE_USE_CASE;
2730 context.choice.icon = icon;
2731 context.choice.message = message;
2732 context.choice.subMessage = subMessage;
2733 context.choice.confirmText = confirmText;
2734 context.choice.cancelText = cancelText;
2735 context.choice.onChoice = callback;
2736 context.currentPage = 0;
2737 context.nbPages = 1 + 1 + 2;
2756 const char *subMessage,
2757 const char *confirmText,
2758 const char *cancelText,
2761 memset(&context, 0,
sizeof(UseCaseContext_t));
2762 context.type = CONFIRM_USE_CASE;
2763 context.confirm.message = message;
2764 context.confirm.subMessage = subMessage;
2765 context.confirm.confirmText = confirmText;
2766 context.confirm.cancelText = cancelText;
2767 context.confirm.onConfirm = callback;
2768 context.currentPage = 0;
2769 context.nbPages = 1 + 2;
2784 const char *message,
2785 const char *actionText,
2793 memset(&context, 0,
sizeof(UseCaseContext_t));
2794 context.type = ACTION_USE_CASE;
2795 context.action.actionCallback = callback;
2797 centeredInfo.
icon = icon;
2798 centeredInfo.
text1 = message;
2799 centeredInfo.
style = BOLD_TEXT1_INFO;
2828 keypadGenericUseCase(
2829 title, minDigits, maxDigits, shuffled,
false, validatePinCallback, backCallback);
2857 keypadGenericUseCase(
2858 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 is a bitfield containing:
@ 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)
#define ACTION_ON_ANY_BUTTON
When action callback applies only on both button press.
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
When action callback applies on any button press.
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)
void nbgl_useCaseAction(const nbgl_icon_details_t *icon, const char *message, const char *actionText, nbgl_callback_t callback)
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)
#define REAL_TYPE_MASK
This is the mask to apply on nbgl_operationType_t to get the real type provided by app.
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 nbgl_icon_details_t * valueIcon
int8_t centeredInfo
if set to 1, the tag will be displayed as a centered info
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