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{
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.onTop = false;
127 info.style = REGULAR_INFO;
128 ctx->stepCtx = nbgl_stepDrawCenteredInfo(pos, actionCallback, NULL, &info, modal);
129 }
130}
131
132// function called on key action of the current step, if not an internal navigation in a multi-pages
133// text step
134static void actionCallback(nbgl_step_t stepCtx, nbgl_buttonEvent_t event)
135{
137 FlowContext_t *ctx = getContextFromStepCtx(stepCtx);
138
139 if (!ctx) {
140 return;
141 }
142 LOG_DEBUG(FLOW_LOGGER, "actionCallback: event = 0x%X, step = %d\n", event, ctx->curStep);
143 // if navigation to the previous step
144 if ((event == BUTTON_LEFT_PRESSED) && (ctx->curStep > 0)) {
145 ctx->curStep--;
146 pos = BACKWARD_DIRECTION;
147 }
148 // if navigation to the next step
149 else if ((event == BUTTON_RIGHT_PRESSED) && (ctx->curStep < (int) (ctx->nbSteps - 1))) {
150 ctx->curStep++;
151 pos = FORWARD_DIRECTION;
152 }
153 // if action on the current step
154 else if (event == BUTTON_BOTH_PRESSED) {
155 if (ctx->steps[ctx->curStep].callback != NULL) {
156 ctx->steps[ctx->curStep].callback();
157 }
158 return;
159 }
160 else {
161 return;
162 }
163 const nbgl_stepDesc_t *step = &ctx->steps[ctx->curStep];
164#ifdef HAVE_LANGUAGE_PACK
165 const char *txt = (step->text != NULL)
166 ? step->text
167 : ((step->textId != INVALID_ID) ? get_ux_loc_string(step->textId) : NULL);
168#else // HAVE_LANGUAGE_PACK
169 const char *txt = step->text;
170#endif // HAVE_LANGUAGE_PACK
171 // release the current step before opening new one
172 nbgl_stepRelease((nbgl_step_t) ctx->stepCtx);
173 if (step->init != NULL) {
174 step->init();
175 }
176 drawStep(ctx, pos, ctx->modal, step->icon, txt, step->subText);
177 nbgl_refresh();
178}
179
180/**********************
181 * GLOBAL FUNCTIONS
182 **********************/
183
195 uint8_t nbSteps,
196 uint8_t initStep,
197 bool loop,
198 bool modal)
199{
200 const nbgl_stepDesc_t *step = &steps[initStep];
201#ifdef HAVE_LANGUAGE_PACK
202 const char *txt = (step->text != NULL)
203 ? step->text
204 : ((step->textId != INVALID_ID) ? get_ux_loc_string(step->textId) : NULL);
205#else // HAVE_LANGUAGE_PACK
206 const char *txt = step->text;
207#endif // HAVE_LANGUAGE_PACK
209 FlowContext_t *ctx = getFreeContext(modal);
210
211 if (!ctx) {
212 return NULL;
213 }
214
215 ctx->nbSteps = nbSteps;
216 ctx->curStep = initStep;
217 ctx->steps = steps;
218 ctx->loop = loop;
219 if (step->init != NULL) {
220 step->init();
221 }
222
223 drawStep(ctx, pos, ctx->modal, step->icon, txt, step->subText);
224 nbgl_refresh();
225 return (nbgl_flow_t) ctx;
226}
227
234{
235 FlowContext_t *ctx = (FlowContext_t *) flow;
236
237 if (!ctx) {
238 LOG_WARN(FLOW_LOGGER, "nbgl_flowRelease: NULL context!");
239 return;
240 }
241 nbgl_stepRelease(ctx->stepCtx);
242 ctx->stepCtx = NULL;
243}
244#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:307
@ BUTTON_BOTH_PRESSED
Sent when both buttons are released.
Definition nbgl_obj.h:314
@ BUTTON_LEFT_PRESSED
Sent when Left button is released.
Definition nbgl_obj.h:308
@ BUTTON_RIGHT_PRESSED
Send when Right button is released.
Definition nbgl_obj.h:309
#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)
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
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