Embedded SDK
Embedded SDK
Loading...
Searching...
No Matches
nbgl_flow.c
Go to the documentation of this file.
1
6#ifdef NBGL_STEP
7/*********************
8 * INCLUDES
9 *********************/
10#include <string.h>
11
12#include "nbgl_debug.h"
13#include "nbgl_flow.h"
14#include "glyphs.h"
15#include "os_pic.h"
16#include "ux.h"
17
18#ifdef HAVE_BOLOS
19#include "bolos_ux_loc_strings.h"
20#include "localization.h"
21#endif // HAVE_BOLOS
22
23/*********************
24 * DEFINES
25 *********************/
27#define NB_MAX_LAYERS 3
28
29/**********************
30 * TYPEDEFS
31 **********************/
32typedef struct FlowContext_s {
33 const nbgl_stepDesc_t *steps;
34 uint8_t curStep;
35 uint8_t nbSteps;
36 bool loop;
37 bool modal;
38 nbgl_step_t stepCtx;
39} FlowContext_t;
40
41/**********************
42 * STATIC VARIABLES
43 **********************/
44static FlowContext_t contexts[NB_MAX_LAYERS];
45
46/**********************
47 * VARIABLES
48 **********************/
49
50/**********************
51 * STATIC PROTOTYPES
52 **********************/
53static void actionCallback(nbgl_step_t stepCtx, nbgl_buttonEvent_t event);
54
55// returns a non-used flow context from the contexts[] array, or NULL if not found
56static FlowContext_t *getFreeContext(bool modal)
57{
58 FlowContext_t *ctx = NULL;
59
60 if (!modal) {
61 // Index 0 is reserved for background
62 ctx = &contexts[0];
63 }
64 else {
65 uint32_t i = 1;
66 while (i < NB_MAX_LAYERS) {
67 if (contexts[i].stepCtx == NULL) {
68 ctx = &contexts[i];
69 break;
70 }
71 i++;
72 }
73 }
74 if (ctx == NULL) {
75 LOG_FATAL(FLOW_LOGGER, "getFreeContext(): no available context\n");
76 }
77 else {
78 ctx->modal = modal;
79 }
80 return ctx;
81}
82
83// returns the flow context from the contexts[] array matching with the given step handler, or NULL
84// if not found
85static FlowContext_t *getContextFromStepCtx(nbgl_step_t stepCtx)
86{
87 FlowContext_t *ctx = NULL;
88 uint32_t i = 0;
89 while (i < NB_MAX_LAYERS) {
90 if (contexts[i].stepCtx == stepCtx) {
91 ctx = &contexts[i];
92 break;
93 }
94 i++;
95 }
96 if (ctx == NULL) {
97 LOG_WARN(FLOW_LOGGER, "getContextFromStepCtx(): no matching context\n");
98 }
99 return ctx;
100}
101
102// draws a step with the provided parameters, using the context provided as @ref ctx
103static void drawStep(FlowContext_t *ctx,
105 bool modal,
106 const nbgl_icon_details_t *icon,
107 const char *txt,
108 const char *subTxt)
109{
110 nbgl_layoutCenteredInfo_t info = {0};
111 if ((ctx->loop) && (ctx->nbSteps > 1)) {
113 }
114 else {
115 pos |= GET_POS_OF_STEP(ctx->curStep, ctx->nbSteps);
116 }
117
118 if (icon == NULL) {
119 ctx->stepCtx
120 = nbgl_stepDrawText(pos, actionCallback, NULL, txt, subTxt, REGULAR_INFO, modal);
121 }
122 else {
123 info.icon = icon;
124 info.text1 = txt;
125 info.text2 = subTxt;
126 info.style = REGULAR_INFO;
127 ctx->stepCtx = nbgl_stepDrawCenteredInfo(pos, actionCallback, NULL, &info, modal);
128 }
129}
130
131// function called on key action of the current step, if not an internal navigation in a multi-pages
132// text step
133static void actionCallback(nbgl_step_t stepCtx, nbgl_buttonEvent_t event)
134{
136 FlowContext_t *ctx = getContextFromStepCtx(stepCtx);
137
138 if (!ctx) {
139 return;
140 }
141 LOG_DEBUG(FLOW_LOGGER, "actionCallback: event = 0x%X, step = %d\n", event, ctx->curStep);
142 // if navigation to the previous step
143 if ((event == BUTTON_LEFT_PRESSED) && (ctx->curStep > 0)) {
144 ctx->curStep--;
145 pos = BACKWARD_DIRECTION;
146 }
147 // if navigation to the next step
148 else if ((event == BUTTON_RIGHT_PRESSED) && (ctx->curStep < (int) (ctx->nbSteps - 1))) {
149 ctx->curStep++;
150 pos = FORWARD_DIRECTION;
151 }
152 // if action on the current step
153 else if (event == BUTTON_BOTH_PRESSED) {
154 if (ctx->steps[ctx->curStep].callback != NULL) {
155 ctx->steps[ctx->curStep].callback();
156 }
157 return;
158 }
159 else {
160 return;
161 }
162 const nbgl_stepDesc_t *step = &ctx->steps[ctx->curStep];
163#ifdef HAVE_LANGUAGE_PACK
164 const char *txt = (step->text != NULL)
165 ? step->text
166 : ((step->textId != INVALID_ID) ? get_ux_loc_string(step->textId) : NULL);
167#else // HAVE_LANGUAGE_PACK
168 const char *txt = step->text;
169#endif // HAVE_LANGUAGE_PACK
170 // release the current step before opening new one
171 nbgl_stepRelease((nbgl_step_t) ctx->stepCtx);
172 if (step->init != NULL) {
173 step->init();
174 }
175 drawStep(ctx, pos, ctx->modal, step->icon, txt, step->subText);
176 nbgl_refresh();
177}
178
179/**********************
180 * GLOBAL FUNCTIONS
181 **********************/
182
194 uint8_t nbSteps,
195 uint8_t initStep,
196 bool loop,
197 bool modal)
198{
199 const nbgl_stepDesc_t *step = &steps[initStep];
200#ifdef HAVE_LANGUAGE_PACK
201 const char *txt = (step->text != NULL)
202 ? step->text
203 : ((step->textId != INVALID_ID) ? get_ux_loc_string(step->textId) : NULL);
204#else // HAVE_LANGUAGE_PACK
205 const char *txt = step->text;
206#endif // HAVE_LANGUAGE_PACK
208 FlowContext_t *ctx = getFreeContext(modal);
209
210 if (!ctx) {
211 return NULL;
212 }
213
214 ctx->nbSteps = nbSteps;
215 ctx->curStep = initStep;
216 ctx->steps = steps;
217 ctx->loop = loop;
218 if (step->init != NULL) {
219 step->init();
220 }
221
222 drawStep(ctx, pos, ctx->modal, step->icon, txt, step->subText);
223 nbgl_refresh();
224 return (nbgl_flow_t) ctx;
225}
226
233{
234 FlowContext_t *ctx = (FlowContext_t *) flow;
235
236 if (!ctx) {
237 LOG_WARN(FLOW_LOGGER, "nbgl_flowRelease: NULL context!");
238 return;
239 }
240 nbgl_stepRelease(ctx->stepCtx);
241 ctx->stepCtx = NULL;
242}
243#endif // NBGL_STEP
debug traces management
#define LOG_WARN(__logger,...)
Definition nbgl_debug.h:87
#define LOG_DEBUG(__logger,...)
Definition nbgl_debug.h:86
#define LOG_FATAL(__logger,...)
Definition nbgl_debug.h:88
@ FLOW_LOGGER
Definition nbgl_debug.h:41
Flow construction API of NBGL.
void nbgl_flowRelease(nbgl_flow_t flow)
void * nbgl_flow_t
type shared externally
Definition nbgl_flow.h:33
nbgl_flow_t nbgl_flowDraw(const nbgl_stepDesc_t *steps, uint8_t nbSteps, uint8_t initStep, bool loop, bool modal)
void nbgl_refresh(void)
nbgl_buttonEvent_t
Definition nbgl_obj.h:315
@ BUTTON_BOTH_PRESSED
Sent when both buttons are released.
Definition nbgl_obj.h:322
@ BUTTON_LEFT_PRESSED
Sent when Left button is released.
Definition nbgl_obj.h:316
@ BUTTON_RIGHT_PRESSED
Send when Right button is released.
Definition nbgl_obj.h:317
#define GET_POS_OF_STEP(_step, _nb_steps)
Definition nbgl_step.h:30
void * nbgl_step_t
type shared externally
Definition nbgl_step.h:44
uint8_t nbgl_stepPosition_t
this type is a bitfield containing:
Definition nbgl_step.h:88
@ NEITHER_FIRST_NOR_LAST_STEP
neither first nor last in a multiple steps flow
Definition nbgl_step.h:67
int nbgl_stepRelease(nbgl_step_t step)
#define FORWARD_DIRECTION
When the flow is navigated from last to first step.
Definition nbgl_step.h:71
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.
Definition nbgl_step.h:73
struct PACKED__ nbgl_icon_details_s nbgl_icon_details_t
Represents all information about an icon.
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)
nbgl_contentCenteredInfoStyle_t style
style to apply to this info
const nbgl_icon_details_t * icon
a buffer containing the 1BPP icon
Structure containing all specific information when creating a NBGL step.
Definition nbgl_flow.h:43
const char * subText
sub-text to display in step (NULL most of the time)
Definition nbgl_flow.h:47
const nbgl_icon_details_t * icon
icon to display in step (text must be single-page)
Definition nbgl_flow.h:48
nbgl_stepCallback_t init
if not NULL, function to be called when the step is entered
Definition nbgl_flow.h:44
const char * text
text to display in step (can be multi-pages if icon == NULL)
Definition nbgl_flow.h:46