17 #include "os_helpers.h"
28 typedef struct ReviewContext_s {
32 const char *reviewTitle;
36 typedef struct ChoiceContext_s {
39 const char *subMessage;
40 const char *confirmText;
41 const char *cancelText;
45 typedef struct HomeContext_s {
57 ADDRESS_REVIEW_USE_CASE,
58 STREAMING_START_REVIEW_USE_CASE,
59 STREAMING_CONTINUE_REVIEW_USE_CASE,
60 STREAMING_FINISH_REVIEW_USE_CASE,
67 typedef struct UseCaseContext_s {
74 ReviewContext_t review;
75 ChoiceContext_t choice;
83 static UseCaseContext_t context;
95 static void startUseCaseHome(
void);
96 static void startUseCaseInfo(
void);
97 static void startUseCaseSettings(
void);
98 static void startUseCaseSettingsAtPage(
uint8_t initSettingPage);
103 switch (content->
type) {
121 if (contentIdx < 0 || contentIdx >= genericContents->
nbContents) {
149 for (
int i = 0; i < genericContents->
nbContents; i++) {
150 p_content = getContentAtIdx(genericContents, i, content);
151 elemNbPages = getContentNbElement(p_content);
152 if (nbPages + elemNbPages > elemIdx) {
153 *elemContentIdx = context.currentPage - nbPages;
156 nbPages += elemNbPages;
169 if (tagValueList->
pairs != NULL) {
170 pair = PIC(&tagValueList->
pairs[index]);
173 pair = PIC(tagValueList->
callback(index));
176 *value = pair->
value;
179 static void onReviewAccept(
void)
181 if (context.review.onChoice) {
182 context.review.onChoice(
true);
186 static void onReviewReject(
void)
188 if (context.review.onChoice) {
189 context.review.onChoice(
false);
193 static void onChoiceAccept(
void)
195 if (context.choice.onChoice) {
196 context.choice.onChoice(
true);
200 static void onChoiceReject(
void)
202 if (context.choice.onChoice) {
203 context.choice.onChoice(
false);
207 static void onSettingsAction(
void)
213 context.home.settingContents, context.currentPage, &elemIdx, &content);
215 switch (p_content->
type) {
224 onContentAction(contentSwitch->
token, state, context.currentPage);
242 nbgl_stepDrawText(pos, onActionCallback, NULL, txt, subTxt, BOLD_TEXT1_INFO,
false);
250 info.
style = BOLD_TEXT1_INFO;
258 if (context.currentPage > 0) {
259 context.currentPage--;
268 if (context.currentPage < (
int) (context.nbPages - 1)) {
269 context.currentPage++;
279 context.stepCallback();
291 if (!buttonGenericCallback(event, &pos)) {
295 displayReviewPage(pos);
303 if (!buttonGenericCallback(event, &pos)) {
307 displayStreamingReviewPage(pos);
315 if (!buttonGenericCallback(event, &pos)) {
319 displaySettingsPage(pos,
false);
327 if (!buttonGenericCallback(event, &pos)) {
331 displayInfoPage(pos);
339 if (!buttonGenericCallback(event, &pos)) {
343 displayHomePage(pos);
351 if (!buttonGenericCallback(event, &pos)) {
355 displayChoicePage(pos);
362 if (context.stepCallback != NULL) {
363 context.stepCallback();
369 static void statusTickerCallback(
void)
371 if (context.stepCallback != NULL) {
372 context.stepCallback();
379 const char *text = NULL;
380 const char *subText = NULL;
383 context.stepCallback = NULL;
385 if (context.currentPage == 0) {
386 icon = context.review.icon;
387 text = context.review.reviewTitle;
389 else if (context.currentPage == (context.nbPages - 2)) {
390 icon = &C_icon_validate_14;
392 context.stepCallback = onReviewAccept;
394 else if (context.currentPage == (context.nbPages - 1)) {
395 icon = &C_icon_crossmark;
397 context.stepCallback = onReviewReject;
399 else if ((context.review.address != NULL)
400 && (context.currentPage == 1)) {
402 subText = context.review.address;
405 uint8_t pairIndex = (context.review.address != NULL) ? (context.currentPage - 2)
406 : (context.currentPage - 1);
407 getPairData(context.review.tagValueList, pairIndex, &text, &subText);
410 drawStep(pos, icon, text, subText, reviewCallback);
417 const char *text = NULL;
418 const char *subText = NULL;
421 context.stepCallback = NULL;
423 if (context.type == STREAMING_START_REVIEW_USE_CASE) {
424 if (context.currentPage == 0) {
425 icon = context.review.icon;
426 text = context.review.reviewTitle;
434 else if (context.type == STREAMING_CONTINUE_REVIEW_USE_CASE) {
435 if (context.currentPage < context.review.tagValueList->nbPairs) {
436 getPairData(context.review.tagValueList, context.currentPage, &text, &subText);
445 if (context.currentPage == 0) {
446 icon = &C_icon_validate_14;
448 context.stepCallback = onReviewAccept;
451 icon = &C_icon_crossmark;
453 context.stepCallback = onReviewReject;
457 drawStep(pos, icon, text, subText, streamingReviewCallback);
464 const char *text = NULL;
465 const char *subText = NULL;
468 context.stepCallback = NULL;
470 if (context.currentPage < (context.nbPages - 1)) {
472 ((
const char *
const *) PIC(context.home.infosList->infoTypes))[context.currentPage]);
474 ((
const char *
const *) PIC(context.home.infosList->infoContents))[context.currentPage]);
477 icon = &C_icon_back_x;
479 context.stepCallback = startUseCaseHome;
482 drawStep(pos, icon, text, subText, infoCallback);
489 const char *text = NULL;
490 const char *subText = NULL;
493 context.stepCallback = NULL;
495 if (context.currentPage < (context.nbPages - 1)) {
500 context.home.settingContents, context.currentPage, &elemIdx, &nbgl_content);
502 switch (p_nbgl_content->
type) {
509 text = contentSwitch->
text;
519 subText =
"Disabled";
521 context.stepCallback = onSettingsAction;
525 text = ((
const char *
const *) PIC(
527 subText = ((
const char *
const *) PIC(
535 icon = &C_icon_back_x;
537 context.stepCallback = startUseCaseHome;
540 drawStep(pos, icon, text, subText, settingsCallback);
544 static void startUseCaseHome(
void)
546 if (context.type == SETTINGS_USE_CASE) {
547 context.currentPage = 1;
549 else if (context.type == INFO_USE_CASE) {
550 context.currentPage = 2;
553 context.currentPage = 0;
555 context.type = HOME_USE_CASE;
561 static void startUseCaseInfo(
void)
563 context.type = INFO_USE_CASE;
564 context.nbPages = context.home.infosList->nbInfos + 1;
565 context.currentPage = 0;
570 static void startUseCaseSettingsAtPage(
uint8_t initSettingPage)
575 context.
type = SETTINGS_USE_CASE;
577 for (
int i = 0; i < context.home.settingContents->nbContents; i++) {
578 p_content = getContentAtIdx(context.home.settingContents, i, &content);
579 context.nbPages += getContentNbElement(p_content);
581 context.currentPage = initSettingPage;
586 static void startUseCaseSettings(
void)
588 startUseCaseSettingsAtPage(0);
594 const char *text = NULL;
595 const char *subText = NULL;
598 context.stepCallback = NULL;
601 if (context.home.settingContents == NULL && context.currentPage == 1) {
603 context.currentPage -= 1;
606 context.currentPage += 1;
607 if (context.home.infosList == NULL) {
608 context.currentPage += 1;
614 if (context.home.infosList == NULL && context.currentPage == 2) {
616 context.currentPage -= 1;
617 if (context.home.settingContents == NULL) {
618 context.currentPage -= 1;
622 context.currentPage += 1;
626 switch (context.currentPage) {
628 icon = context.home.appIcon;
629 if (context.home.tagline != NULL) {
630 text = context.home.tagline;
633 text = context.home.appName;
634 subText =
"is ready";
638 icon = &C_icon_coggle;
640 context.stepCallback = startUseCaseSettings;
643 icon = &C_icon_certificate;
645 context.stepCallback = startUseCaseInfo;
648 icon = &C_icon_dashboard_x;
650 context.stepCallback = context.home.quitCallback;
654 drawStep(pos, icon, text, subText, homeCallback);
661 const char *text = NULL;
662 const char *subText = NULL;
665 context.stepCallback = NULL;
668 if (context.currentPage == 1
669 && (context.choice.icon == NULL || context.choice.subMessage == NULL)) {
671 context.currentPage -= 1;
674 context.currentPage += 1;
678 if (context.currentPage == 0) {
679 text = context.choice.message;
680 if (context.choice.icon != NULL) {
681 icon = context.choice.icon;
684 subText = context.choice.subMessage;
687 else if (context.currentPage == 1) {
689 text = context.choice.message;
690 subText = context.choice.subMessage;
692 else if (context.currentPage == 2) {
693 icon = &C_icon_validate_14;
694 text = context.choice.confirmText;
695 context.stepCallback = onChoiceAccept;
698 icon = &C_icon_crossmark;
699 text = context.choice.cancelText;
700 context.stepCallback = onChoiceReject;
703 drawStep(pos, icon, text, subText, genericChoiceCallback);
736 memset(&context, 0,
sizeof(UseCaseContext_t));
737 context.home.appName = appName;
738 context.home.appIcon = appIcon;
739 context.home.tagline = tagline;
740 context.home.settingContents = PIC(settingContents);
741 context.home.infosList = PIC(infosList);
742 context.home.quitCallback = quitCallback;
745 startUseCaseSettingsAtPage(initSettingPage);
769 const char *reviewTitle,
770 const char *reviewSubTitle,
771 const char *finishTitle,
774 UNUSED(operationType);
775 UNUSED(reviewSubTitle);
778 memset(&context, 0,
sizeof(UseCaseContext_t));
779 context.type = REVIEW_USE_CASE;
780 context.review.tagValueList = tagValueList;
781 context.review.reviewTitle = reviewTitle;
782 context.review.icon = icon;
783 context.review.onChoice = choiceCallback;
784 context.currentPage = 0;
786 context.nbPages = tagValueList->
nbPairs + 3;
808 const char *reviewTitle,
809 const char *reviewSubTitle,
810 const char *finishTitle,
841 const char *reviewTitle,
842 const char *reviewSubTitle,
845 UNUSED(reviewSubTitle);
847 memset(&context, 0,
sizeof(UseCaseContext_t));
848 context.type = ADDRESS_REVIEW_USE_CASE;
849 context.review.address = address;
850 context.review.reviewTitle = reviewTitle;
851 context.review.icon = icon;
852 context.review.onChoice = choiceCallback;
853 context.currentPage = 0;
856 if (additionalTagValueList) {
857 memcpy(&context.review.tagValueList,
858 additionalTagValueList,
860 context.nbPages += additionalTagValueList->
nbPairs;
877 memset(&context, 0,
sizeof(UseCaseContext_t));
878 context.stepCallback = quitCallback;
879 context.currentPage = 0;
883 .tickerCallback = PIC(statusTickerCallback),
884 .tickerIntervale = 0,
889 SINGLE_STEP, statusButtonCallback, &ticker, message, NULL, BOLD_TEXT1_INFO,
false);
904 switch (reviewStatusType) {
906 msg =
"Operation signed";
910 msg =
"Operation rejected";
914 msg =
"Transaction signed";
918 msg =
"Transaction rejected";
922 msg =
"Message signed";
926 msg =
"Message rejected";
930 msg =
"Address verified";
934 msg =
"Verification\ncancelled";
957 const char *reviewTitle,
958 const char *reviewSubTitle,
961 UNUSED(operationType);
962 UNUSED(reviewSubTitle);
964 memset(&context, 0,
sizeof(UseCaseContext_t));
965 context.type = STREAMING_START_REVIEW_USE_CASE;
966 context.review.reviewTitle = reviewTitle;
967 context.review.icon = icon;
968 context.review.onChoice = choiceCallback;
969 context.currentPage = 0;
970 context.nbPages = 1 + 1;
990 UNUSED(skipCallback);
992 memset(&context, 0,
sizeof(UseCaseContext_t));
993 context.type = STREAMING_CONTINUE_REVIEW_USE_CASE;
994 context.review.tagValueList = tagValueList;
995 context.review.onChoice = choiceCallback;
996 context.currentPage = 0;
997 context.nbPages = tagValueList->
nbPairs + 1;
1021 UNUSED(finishTitle);
1023 memset(&context, 0,
sizeof(UseCaseContext_t));
1024 context.type = STREAMING_FINISH_REVIEW_USE_CASE;
1025 context.review.onChoice = choiceCallback;
1026 context.currentPage = 0;
1027 context.nbPages = 2;
1039 drawStep(
SINGLE_STEP, &C_icon_processing, text, NULL, NULL);
1044 const char *message,
1045 const char *subMessage,
1046 const char *confirmText,
1047 const char *cancelText,
1050 memset(&context, 0,
sizeof(UseCaseContext_t));
1051 context.type = CHOICE_USE_CASE;
1052 context.choice.icon = icon;
1053 context.choice.message = message;
1054 context.choice.subMessage = subMessage;
1055 context.choice.confirmText = confirmText;
1056 context.choice.cancelText = cancelText;
1057 context.choice.onChoice = callback;
1058 context.currentPage = 0;
1059 context.nbPages = 1 + 1 + 2;
@ SWITCHES_LIST
list of switches with descriptions
@ INFOS_LIST
list of infos with titles
@ TAG_VALUE_LIST
list of tag/value pairs
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_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_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_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)
@ SINGLE_STEP
single step flow
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...
#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.
void(* nbgl_callback_t)(void)
prototype of generic callback function
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_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)
void(* nbgl_choiceCallback_t)(bool confirm)
prototype of choice callback function
void nbgl_useCaseReviewStreamingFinish(const char *finishTitle, nbgl_choiceCallback_t choiceCallback)
void nbgl_useCaseSpinner(const char *text)
void nbgl_useCaseStatus(const char *message, bool isSuccess, 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_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_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)
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
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)
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
This structure contains data to build a INFOS_LIST content.
uint8_t nbInfos
number of elements in infoTypes and infoContents array
const char *const * infoContents
array of contents of infos (in black)
const char *const * infoTypes
array of types of infos (in black/bold)
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
nbgl_state_t initState
initial state of the switch
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.
const char * value
string giving the value name
const char * item
string giving the tag name
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.
uint8_t nbSwitches
number of elements in switches and tokens array
const nbgl_contentSwitch_t * switches
array of switches (nbSwitches items)
nbgl_contentInfoList_t infosList
INFOS_LIST type
nbgl_contentTagValueList_t tagValueList
TAG_VALUE_LIST type
nbgl_contentSwitchesList_t switchesList
SWITCHES_LIST type