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