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 
17 /*********************
18  * DEFINES
19  *********************/
21 #define NB_MAX_LAYERS 3
22 
23 /**********************
24  * TYPEDEFS
25  **********************/
26 typedef struct FlowContext_s {
27  const nbgl_stepDesc_t *steps;
28  uint8_t curStep;
29  uint8_t nbSteps;
30  bool loop;
31  bool modal;
32  nbgl_step_t stepCtx;
33 } FlowContext_t;
34 
35 /**********************
36  * STATIC VARIABLES
37  **********************/
38 static FlowContext_t contexts[NB_MAX_LAYERS];
39 
40 /**********************
41  * VARIABLES
42  **********************/
43 
44 /**********************
45  * STATIC PROTOTYPES
46  **********************/
47 static void actionCallback(nbgl_step_t stepCtx, nbgl_buttonEvent_t event);
48 
49 // returns a non-used flow context from the contexts[] array, or NULL if not found
50 static FlowContext_t *getFreeContext(bool modal)
51 {
52  FlowContext_t *ctx = NULL;
53 
54  if (!modal) {
55  // Index 0 is reserved for background
56  ctx = &contexts[0];
57  }
58  else {
59  uint32_t i = 1;
60  while (i < NB_MAX_LAYERS) {
61  if (contexts[i].stepCtx == NULL) {
62  ctx = &contexts[i];
63  break;
64  }
65  i++;
66  }
67  }
68  if (ctx == NULL) {
69  LOG_FATAL(FLOW_LOGGER, "getFreeContext(): no available context\n");
70  }
71  else {
72  ctx->modal = modal;
73  }
74  return ctx;
75 }
76 
77 // returns the flow context from the contexts[] array matching with the given step handler, or NULL
78 // if not found
79 static FlowContext_t *getContextFromStepCtx(nbgl_step_t stepCtx)
80 {
81  FlowContext_t *ctx = NULL;
82  uint32_t i = 0;
83  while (i < NB_MAX_LAYERS) {
84  if (contexts[i].stepCtx == stepCtx) {
85  ctx = &contexts[i];
86  break;
87  }
88  i++;
89  }
90  if (ctx == NULL) {
91  LOG_WARN(FLOW_LOGGER, "getContextFromStepCtx(): no matching context\n");
92  }
93  return ctx;
94 }
95 
96 // draws a step with the provided parameters, using the context provided as @ref ctx
97 static void drawStep(FlowContext_t *ctx,
99  bool modal,
100  const nbgl_icon_details_t *icon,
101  const char *txt,
102  const char *subTxt)
103 {
105  if ((ctx->loop) && (ctx->nbSteps > 1)) {
107  }
108  else {
109  pos |= GET_POS_OF_STEP(ctx->curStep, ctx->nbSteps);
110  }
111 
112  if (icon == NULL) {
113  ctx->stepCtx
114  = nbgl_stepDrawText(pos, actionCallback, NULL, txt, subTxt, REGULAR_INFO, modal);
115  }
116  else {
117  info.icon = icon;
118  info.text1 = txt;
119  info.text2 = subTxt;
120  info.onTop = false;
121  info.style = REGULAR_INFO;
122  ctx->stepCtx = nbgl_stepDrawCenteredInfo(pos, actionCallback, NULL, &info, modal);
123  }
124 }
125 
126 // function called on key action of the current step, if not an internal navigation in a multi-pages
127 // text step
128 static void actionCallback(nbgl_step_t stepCtx, nbgl_buttonEvent_t event)
129 {
131  FlowContext_t *ctx = getContextFromStepCtx(stepCtx);
132 
133  if (!ctx) {
134  return;
135  }
136  LOG_DEBUG(FLOW_LOGGER, "actionCallback: event = 0x%X, step = %d\n", event, ctx->curStep);
137  // if navigation to the previous step
138  if ((event == BUTTON_LEFT_PRESSED) && (ctx->curStep > 0)) {
139  ctx->curStep--;
140  pos = BACKWARD_DIRECTION;
141  }
142  // if navigation to the next step
143  else if ((event == BUTTON_RIGHT_PRESSED) && (ctx->curStep < (int) (ctx->nbSteps - 1))) {
144  ctx->curStep++;
145  pos = FORWARD_DIRECTION;
146  }
147  // if action on the current step
148  else if (event == BUTTON_BOTH_PRESSED) {
149  if (ctx->steps[ctx->curStep].callback != NULL) {
150  ctx->steps[ctx->curStep].callback();
151  }
152  return;
153  }
154  else {
155  return;
156  }
157  const nbgl_stepDesc_t *step = &ctx->steps[ctx->curStep];
158 #ifdef HAVE_LANGUAGE_PACK
159  const char *txt = (step->text != NULL)
160  ? step->text
161  : ((step->textId != INVALID_ID) ? get_ux_loc_string(step->textId) : NULL);
162 #else // HAVE_LANGUAGE_PACK
163  const char *txt = step->text;
164 #endif // HAVE_LANGUAGE_PACK
165  // release the current step before opening new one
166  nbgl_stepRelease((nbgl_step_t) ctx->stepCtx);
167  if (step->init != NULL) {
168  step->init();
169  }
170  drawStep(ctx, pos, ctx->modal, step->icon, txt, step->subText);
171  nbgl_refresh();
172 }
173 
174 /**********************
175  * GLOBAL FUNCTIONS
176  **********************/
177 
189  uint8_t nbSteps,
190  uint8_t initStep,
191  bool loop,
192  bool modal)
193 {
194  const nbgl_stepDesc_t *step = &steps[initStep];
195 #ifdef HAVE_LANGUAGE_PACK
196  const char *txt = (step->text != NULL)
197  ? step->text
198  : ((step->textId != INVALID_ID) ? get_ux_loc_string(step->textId) : NULL);
199 #else // HAVE_LANGUAGE_PACK
200  const char *txt = step->text;
201 #endif // HAVE_LANGUAGE_PACK
203  FlowContext_t *ctx = getFreeContext(modal);
204 
205  if (!ctx) {
206  return NULL;
207  }
208 
209  ctx->nbSteps = nbSteps;
210  ctx->curStep = initStep;
211  ctx->steps = steps;
212  ctx->loop = loop;
213  if (step->init != NULL) {
214  step->init();
215  }
216 
217  drawStep(ctx, pos, ctx->modal, step->icon, txt, step->subText);
218  nbgl_refresh();
219  return (nbgl_flow_t) ctx;
220 }
221 
227 void nbgl_flowRelease(nbgl_flow_t flow)
228 {
229  FlowContext_t *ctx = (FlowContext_t *) flow;
230 
231  if (!ctx) {
232  LOG_WARN(FLOW_LOGGER, "nbgl_flowRelease: NULL context!");
233  return;
234  }
235  nbgl_stepRelease(ctx->stepCtx);
236  ctx->stepCtx = NULL;
237 }
238 #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:1560
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:33
@ NEITHER_FIRST_NOR_LAST_STEP
neither first nor last in a multiple steps flow
Definition: nbgl_step.h:69
void * nbgl_step_t
type shared externally
Definition: nbgl_step.h:47
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:82
int nbgl_stepRelease(nbgl_step_t step)
#define FORWARD_DIRECTION
When the flow is navigated from last to first step.
Definition: nbgl_step.h:73
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:75
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