Embedded SDK
Embedded SDK
nbgl_step.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_step.h"
13 #include "glyphs.h"
14 #include "os_pic.h"
15 #include "os_print.h"
16 #ifdef BUILD_SCREENSHOTS
17 #include "json_scenario.h"
18 #endif // BUILD_SCREENSHOTS
19 
20 /*********************
21  * DEFINES
22  *********************/
23 // string to store the title for a multi-pages text+subtext
24 #define TMP_STRING_MAX_LEN 24
25 
27 #define NB_MAX_LAYERS 3
28 
29 /**********************
30  * TYPEDEFS
31  **********************/
35 typedef enum {
36  TEXT_STEP = 0,
37  CENTERED_INFO_STEP,
38  MENU_LIST_STEP
39 } StepStype_t;
40 
44 typedef struct TextContext_s {
45  uint8_t nbPages;
46  uint8_t currentPage;
47  const char *txtStart;
48  const char *nextPageStart;
49  const char *subTxtStart;
50 
52  nbgl_stepButtonCallback_t onActionCallback;
54  char tmpString[TMP_STRING_MAX_LEN];
57  style;
58 } TextContext_t;
59 
63 typedef struct MenuListContext_s {
65  selectedCallback;
67  list;
68 } MenuListContext_t;
69 
70 typedef struct StepContext_s {
71  union {
72  TextContext_t textContext;
73  MenuListContext_t menuListContext;
74  };
76  nbgl_layout_t *layout;
77  StepStype_t type;
78  bool modal;
79 } StepContext_t;
80 
81 /**********************
82  * STATIC VARIABLES
83  **********************/
85 static StepContext_t contexts[NB_MAX_LAYERS];
86 
87 /**********************
88  * VARIABLES
89  **********************/
90 #ifdef BUILD_SCREENSHOTS
91 // Contains the last string index used
92 extern UX_LOC_STRINGS_INDEX last_string_id;
93 
94 // Variables used to store important values (nb lines, bold state etc)
95 extern uint16_t last_nb_lines;
96 extern uint16_t last_nb_pages;
97 extern bool last_bold_state;
98 #endif // BUILD_SCREENSHOTS
99 
100 /**********************
101  * STATIC PROTOTYPES
102  **********************/
103 
104 static void actionCallback(nbgl_layout_t *layout, nbgl_buttonEvent_t event);
105 static void menuListActionCallback(nbgl_layout_t *layout, nbgl_buttonEvent_t event);
106 
107 // returns a non-used step context from the contexts[] array, or NULL if not found
108 static StepContext_t *getFreeContext(StepStype_t type, bool modal)
109 {
110  StepContext_t *ctx = NULL;
111 
112  if (!modal) {
113  // Index 0 is reserved for background
114  ctx = &contexts[0];
115  }
116  else {
117  uint32_t i = 1;
118  while (i < NB_MAX_LAYERS) {
119  if (contexts[i].layout == NULL) {
120  ctx = &contexts[i];
121  break;
122  }
123  i++;
124  }
125  }
126  if (ctx == NULL) {
127  LOG_FATAL(STEP_LOGGER, "getFreeContext(): no available context\n");
128  }
129  else {
130  memset(ctx, 0, sizeof(StepContext_t));
131  ctx->type = type;
132  ctx->modal = modal;
133  }
134  return ctx;
135 }
136 
137 // returns the step context from the contexts[] array matching with the given layout handler, or
138 // NULL if not found
139 static StepContext_t *getContextFromLayout(nbgl_layout_t layout)
140 {
141  StepContext_t *ctx = NULL;
142  uint32_t i = 0;
143  while (i < NB_MAX_LAYERS) {
144  if (contexts[i].layout == layout) {
145  ctx = &contexts[i];
146  break;
147  }
148  i++;
149  }
150  if (ctx == NULL) {
151  LOG_WARN(STEP_LOGGER, "getContextFromLayout(): no matching context\n");
152  }
153  return ctx;
154 }
155 
156 // from the current details context, return a pointer on the details at the given page
157 static const char *getTextPageAt(StepContext_t *ctx, uint8_t textPage)
158 {
159  uint8_t page = 0;
160  const char *currentChar = ctx->textContext.txtStart;
161  while (page < textPage) {
162  if (page < (ctx->textContext.nbPages - 1)) {
163  uint16_t len;
165  currentChar,
167  NB_MAX_LINES,
168  &len,
169  true);
170  currentChar = currentChar + len;
171  }
172  page++;
173  }
174  return currentChar;
175 }
176 
177 // from the current details context, return a pointer on the details at the given page, for subText
178 static const char *getSubTextPageAt(StepContext_t *ctx, uint8_t textPage)
179 {
180  uint8_t page = 0;
181  const char *currentChar = ctx->textContext.subTxtStart;
182  while (page < textPage) {
183  if (page < (ctx->textContext.nbPages - 1)) {
184  uint16_t len;
186  currentChar,
188  NB_MAX_LINES - 1,
189  &len,
190  true);
191  currentChar = currentChar + len;
192  }
193  page++;
194  }
195  return currentChar;
196 }
197 
198 // utility function to compute navigation arrows
199 static nbgl_layoutNavIndication_t getNavigationInfo(nbgl_stepPosition_t pos,
200  uint8_t nbPages,
201  uint8_t currentPage)
202 {
204 
205  if (nbPages > 1) {
206  if (currentPage > 0) {
207  indication |= LEFT_ARROW;
208  }
209  if (currentPage < (nbPages - 1)) {
210  indication |= RIGHT_ARROW;
211  }
212  }
213  if (pos == FIRST_STEP) {
214  indication |= RIGHT_ARROW;
215  }
216  else if (pos == LAST_STEP) {
217  indication |= LEFT_ARROW;
218  }
219  else if (pos == NEITHER_FIRST_NOR_LAST_STEP) {
220  indication |= RIGHT_ARROW | LEFT_ARROW;
221  }
222  return indication;
223 }
224 
225 // function used to display the current page in details review mode
226 static void displayTextPage(StepContext_t *ctx, uint8_t textPage)
227 {
228  const char *txt;
229 
230  // if move backward or first page
231  if (textPage <= ctx->textContext.currentPage) {
232  // recompute current start from beginning
233  if (ctx->textContext.subTxtStart == NULL) {
234  txt = getTextPageAt(ctx, textPage);
235  }
236  else {
237  txt = getSubTextPageAt(ctx, textPage);
238  }
239  }
240  // else move forward
241  else {
242  txt = ctx->textContext.nextPageStart;
243  }
244  ctx->textContext.currentPage = textPage;
245 
246  if (ctx->textContext.currentPage < (ctx->textContext.nbPages - 1)) {
247  uint16_t len;
248  uint8_t nbLines
249  = (ctx->textContext.subTxtStart == NULL) ? NB_MAX_LINES : (NB_MAX_LINES - 1);
251  BAGL_FONT_OPEN_SANS_REGULAR_11px_1bpp, txt, AVAILABLE_WIDTH, nbLines, &len, true);
252  // memorize next position to save processing
253  ctx->textContext.nextPageStart = txt + len;
254  }
255  else {
256  ctx->textContext.nextPageStart = NULL;
257  }
258  nbgl_layoutDescription_t layoutDescription;
259  nbgl_layoutNavigation_t navInfo = {
261  };
262 
263  layoutDescription.modal = ctx->modal;
264  layoutDescription.onActionCallback = actionCallback;
265  layoutDescription.ticker.tickerCallback = ctx->ticker.tickerCallback;
266  layoutDescription.ticker.tickerIntervale = ctx->ticker.tickerIntervale;
267  layoutDescription.ticker.tickerValue = ctx->ticker.tickerValue;
268  ctx->layout = nbgl_layoutGet(&layoutDescription);
269 
270  navInfo.indication = getNavigationInfo(
271  ctx->textContext.pos, ctx->textContext.nbPages, ctx->textContext.currentPage);
272 
273  if (ctx->textContext.subTxtStart == NULL) {
274  nbgl_layoutAddText(ctx->layout, txt, NULL, ctx->textContext.style);
275  }
276  else {
277  if (ctx->textContext.nbPages == 1) {
278  nbgl_layoutAddText(ctx->layout, ctx->textContext.txtStart, txt, ctx->textContext.style);
279  }
280  else {
281  SPRINTF(ctx->textContext.tmpString,
282  "%s (%d/%d)",
283  ctx->textContext.txtStart,
284  ctx->textContext.currentPage + 1,
285  ctx->textContext.nbPages);
287  ctx->layout, ctx->textContext.tmpString, txt, ctx->textContext.style);
288  }
289  }
290  if (navInfo.indication != NO_ARROWS) {
291  nbgl_layoutAddNavigation(ctx->layout, &navInfo);
292  }
293  nbgl_layoutDraw(ctx->layout);
294  nbgl_refresh();
295 }
296 
297 // callback on key touch
298 static void actionCallback(nbgl_layout_t *layout, nbgl_buttonEvent_t event)
299 {
300  StepContext_t *ctx = getContextFromLayout(layout);
301 
302  if (!ctx) {
303  return;
304  }
305  if (event == BUTTON_LEFT_PRESSED) {
306  if (ctx->textContext.currentPage > 0) {
307  displayTextPage(ctx, ctx->textContext.currentPage - 1);
308  return;
309  }
310  else if ((ctx->textContext.pos == LAST_STEP)
311  || (ctx->textContext.pos == NEITHER_FIRST_NOR_LAST_STEP)) {
312  if (ctx->textContext.onActionCallback != NULL) {
313  ctx->textContext.onActionCallback((nbgl_step_t) ctx, event);
314  }
315  }
316  }
317  else if (event == BUTTON_RIGHT_PRESSED) {
318  if (ctx->textContext.currentPage < (ctx->textContext.nbPages - 1)) {
319  displayTextPage(ctx, ctx->textContext.currentPage + 1);
320  return;
321  }
322  else if ((ctx->textContext.pos == FIRST_STEP)
323  || (ctx->textContext.pos == NEITHER_FIRST_NOR_LAST_STEP)) {
324  if (ctx->textContext.onActionCallback != NULL) {
325  ctx->textContext.onActionCallback((nbgl_step_t) ctx, event);
326  }
327  }
328  }
329  else if (event == BUTTON_BOTH_PRESSED) {
330  if (ctx->textContext.onActionCallback != NULL) {
331  ctx->textContext.onActionCallback((nbgl_step_t) ctx, event);
332  }
333  }
334 }
335 
336 static void displayMenuList(StepContext_t *ctx)
337 {
338  nbgl_layoutDescription_t layoutDescription
339  = {.modal = ctx->modal, .onActionCallback = menuListActionCallback};
340  nbgl_layoutMenuList_t *list = &ctx->menuListContext.list;
341 
342  layoutDescription.ticker.tickerCallback = ctx->ticker.tickerCallback;
343  layoutDescription.ticker.tickerIntervale = ctx->ticker.tickerIntervale;
344  layoutDescription.ticker.tickerValue = ctx->ticker.tickerValue;
345 
346  ctx->layout = nbgl_layoutGet(&layoutDescription);
347  nbgl_layoutAddMenuList(ctx->layout, list);
348  if (list->nbChoices > 1) {
350  navInfo.indication = 0;
351  if (list->selectedChoice > 0) {
352  navInfo.indication |= LEFT_ARROW;
353  }
354  if (list->selectedChoice < (list->nbChoices - 1)) {
355  navInfo.indication |= RIGHT_ARROW;
356  }
357 
358  if (navInfo.indication != NO_ARROWS) {
359  nbgl_layoutAddNavigation(ctx->layout, &navInfo);
360  }
361  }
362  nbgl_layoutDraw(ctx->layout);
363  nbgl_refresh();
364 }
365 
366 // callback on key touch
367 static void menuListActionCallback(nbgl_layout_t *layout, nbgl_buttonEvent_t event)
368 {
369  StepContext_t *ctx = getContextFromLayout(layout);
370  if (!ctx) {
371  return;
372  }
373 
374  if (event == BUTTON_LEFT_PRESSED) {
375  if (ctx->menuListContext.list.selectedChoice > 0) {
376  ctx->menuListContext.list.selectedChoice--;
377  displayMenuList(ctx);
378  }
379  }
380  else if (event == BUTTON_RIGHT_PRESSED) {
381  if (ctx->menuListContext.list.selectedChoice < (ctx->menuListContext.list.nbChoices - 1)) {
382  ctx->menuListContext.list.selectedChoice++;
383  displayMenuList(ctx);
384  }
385  }
386  else if (event == BUTTON_BOTH_PRESSED) {
387  ctx->menuListContext.selectedCallback(ctx->menuListContext.list.selectedChoice);
388  }
389 }
390 
391 /**********************
392  * GLOBAL FUNCTIONS
393  **********************/
394 
410  nbgl_stepButtonCallback_t onActionCallback,
412  const char *text,
413  const char *subText,
415  bool modal)
416 {
417 #ifdef BUILD_SCREENSHOTS
418  // Initialize a default area
419  nbgl_area_t area;
420  area.x0 = area.y0 = 0;
421  area.width = AVAILABLE_WIDTH;
423 #endif // BUILD_SCREENSHOTS
424  StepContext_t *ctx = getFreeContext(TEXT_STEP, modal);
425  if (!ctx) {
426  return NULL;
427  }
428  // initialize context (already set to 0 by getFreeContext())
429  ctx->textContext.onActionCallback = onActionCallback;
430  if (ticker) {
431  ctx->ticker.tickerCallback = ticker->tickerCallback;
432  ctx->ticker.tickerIntervale = ticker->tickerIntervale;
433  ctx->ticker.tickerValue = ticker->tickerValue;
434  }
435 
436  // if no subText, get the number of pages for main text
437  if (subText == NULL) {
438  ctx->textContext.nbPages = nbgl_getTextNbPagesInWidth(
440 #ifdef BUILD_SCREENSHOTS
441  store_string_infos(text,
443  &area,
444  true,
445  last_nb_lines,
446  last_nb_pages,
447  last_bold_state);
448 #endif // BUILD_SCREENSHOTS
449  }
450  else {
451 #ifdef BUILD_SCREENSHOTS
452  uint16_t nb_lines_title;
453  // Call this function to get correct nb_lines/nb_pages for text field.
456  nb_lines_title = last_nb_lines;
457  // There is a sub text, so no more than 3 lines for title...
458  if (nb_lines_title > 3) {
459  nb_lines_title = 3;
460  }
461  area.height
463  store_string_infos(text,
465  &area,
466  true,
467  last_nb_lines,
468  last_nb_pages,
469  last_bold_state);
470 #endif // BUILD_SCREENSHOTS
471  // NB_MAX_LINES-1 because first line is for main text
472  ctx->textContext.nbPages = nbgl_getTextNbPagesInWidth(
474 #ifdef BUILD_SCREENSHOTS
475  area.height = (NB_MAX_LINES - nb_lines_title)
477  // If subTxtid is not valid, we'll use txtId for nb_lines/nb_pages values
478  store_string_infos(subText,
480  &area,
481  true,
482  last_nb_lines,
483  last_nb_pages,
484  last_bold_state);
485 #endif // BUILD_SCREENSHOTS
486  }
488  "nbgl_stepDrawText: ctx = %p, nbPages = %d, pos = 0x%X\n",
489  ctx,
490  ctx->textContext.nbPages,
491  pos);
492  if (pos & BACKWARD_DIRECTION) {
493  // start with last page
494  ctx->textContext.currentPage = ctx->textContext.nbPages - 1;
495  }
496  ctx->textContext.txtStart = text;
497  ctx->textContext.subTxtStart = subText;
498  // keep only direction part of position
499  ctx->textContext.pos = pos & (RIGHT_ARROW | LEFT_ARROW);
500  ctx->textContext.style = style;
501  displayTextPage(ctx, ctx->textContext.currentPage);
502 
503  return (nbgl_step_t) ctx;
504 }
505 
517  nbgl_stepButtonCallback_t onActionCallback,
520  bool modal)
521 {
522  nbgl_layoutDescription_t layoutDescription
523  = {.modal = modal, .onActionCallback = (nbgl_layoutButtonCallback_t) actionCallback};
524  nbgl_layoutNavigation_t navInfo = {
526  };
527  StepContext_t *ctx = getFreeContext(CENTERED_INFO_STEP, modal);
528  if (!ctx) {
529  return NULL;
530  }
531 
532  // initialize context (already set to 0 by getFreeContext())
533  ctx->textContext.onActionCallback = onActionCallback;
534  if (ticker) {
535  ctx->ticker.tickerCallback = ticker->tickerCallback;
536  ctx->ticker.tickerIntervale = ticker->tickerIntervale;
537  ctx->ticker.tickerValue = ticker->tickerValue;
538  layoutDescription.ticker.tickerCallback = ticker->tickerCallback;
539  layoutDescription.ticker.tickerIntervale = ticker->tickerIntervale;
540  layoutDescription.ticker.tickerValue = ticker->tickerValue;
541  }
542 
543  ctx->textContext.nbPages = 1;
544  // keep only direction part of position
545  ctx->textContext.pos = pos & (RIGHT_ARROW | LEFT_ARROW);
546  navInfo.indication = getNavigationInfo(
547  ctx->textContext.pos, ctx->textContext.nbPages, ctx->textContext.currentPage);
548 
549  ctx->layout = nbgl_layoutGet(&layoutDescription);
550  nbgl_layoutAddCenteredInfo(ctx->layout, info);
551  if (navInfo.indication != NO_ARROWS) {
552  nbgl_layoutAddNavigation(ctx->layout, &navInfo);
553  }
554  nbgl_layoutDraw(ctx->layout);
555  nbgl_refresh();
556 
557  LOG_DEBUG(STEP_LOGGER, "nbgl_stepDrawCenteredInfo(): step = %p\n", ctx);
558  return (nbgl_step_t) ctx;
559 }
560 
573  nbgl_layoutMenuList_t *list,
574  bool modal)
575 {
576  StepContext_t *ctx = getFreeContext(MENU_LIST_STEP, modal);
577  if (!ctx) {
578  return NULL;
579  }
580 
581  // initialize context (already set to 0 by getFreeContext())
582  if (ticker) {
583  ctx->ticker.tickerCallback = ticker->tickerCallback;
584  ctx->ticker.tickerIntervale = ticker->tickerIntervale;
585  ctx->ticker.tickerValue = ticker->tickerValue;
586  }
587 
588  ctx->menuListContext.list.nbChoices = list->nbChoices;
589  ctx->menuListContext.list.selectedChoice = list->selectedChoice;
590  ctx->menuListContext.list.callback = list->callback;
591  ctx->menuListContext.selectedCallback = onActionCallback;
592 
593  displayMenuList(ctx);
594 
595  LOG_DEBUG(STEP_LOGGER, "nbgl_stepDrawMenuList(): step = %p\n", ctx);
596 
597  return (nbgl_step_t) ctx;
598 }
599 
607 {
608  StepContext_t *ctx = (StepContext_t *) step;
609  if (!ctx) {
610  return 0;
611  }
612  return (ctx->menuListContext.list.selectedChoice);
613 }
614 
622 {
623  StepContext_t *ctx = (StepContext_t *) step;
624  int ret;
625 
626  LOG_DEBUG(STEP_LOGGER, "nbgl_stepRelease(): ctx = %p\n", ctx);
627  if (!ctx) {
628  return -1;
629  }
630  ret = nbgl_layoutRelease((nbgl_layout_t *) ctx->layout);
631 
632  ctx->layout = NULL;
633 
634  return ret;
635 }
636 
637 #endif // NBGL_STEP
nbgl_contentCenteredInfoStyle_t
possible styles for Centered Info Area
Definition: nbgl_content.h:34
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
@ STEP_LOGGER
Definition: nbgl_debug.h:40
uint8_t nbgl_getTextNbPagesInWidth(nbgl_font_id_e fontId, const char *text, uint8_t nbLinesPerPage, uint16_t maxWidth)
compute the number of pages of nbLinesPerPage lines per page of the given text fitting in the given m...
Definition: nbgl_fonts.c:877
bool nbgl_getTextMaxLenInNbLines(nbgl_font_id_e fontId, const char *text, uint16_t maxWidth, uint16_t maxNbLines, uint16_t *len, bool wrapping)
compute the len of the given text (in bytes) fitting in the given maximum nb lines,...
Definition: nbgl_fonts.c:564
@ BAGL_FONT_OPEN_SANS_REGULAR_11px_1bpp
Definition: nbgl_fonts.h:149
uint8_t nbgl_getFontLineHeight(nbgl_font_id_e fontId)
return the height in pixels of the line of font with the given font ID
Definition: nbgl_fonts.c:402
#define NB_MAX_LINES
Definition: nbgl_layout.h:68
@ VERTICAL_NAV
'\/' and '/\' are displayed, to navigate in a list (vertical scrolling)
Definition: nbgl_layout.h:142
@ HORIZONTAL_NAV
'<' and '>' are displayed, to navigate between pages and steps
Definition: nbgl_layout.h:141
int nbgl_layoutAddText(nbgl_layout_t *layout, const char *text, const char *subText)
Creates an area with given text (in bold) and sub text (in regular)
Definition: nbgl_layout.c:1301
nbgl_layoutNavIndication_t
possible styles for Navigation arrows (it's a bit field)
Definition: nbgl_layout.h:149
@ NO_ARROWS
Definition: nbgl_layout.h:150
@ LEFT_ARROW
left arrow is used
Definition: nbgl_layout.h:151
@ RIGHT_ARROW
right arrow is used
Definition: nbgl_layout.h:152
int nbgl_layoutAddCenteredInfo(nbgl_layout_t *layout, const nbgl_layoutCenteredInfo_t *info)
Creates an area on the center of the main panel, with a possible icon/image, a possible text in black...
Definition: nbgl_layout.c:1610
int nbgl_layoutDraw(nbgl_layout_t *layout)
Applies given layout. The screen will be redrawn.
Definition: nbgl_layout.c:3437
#define AVAILABLE_WIDTH
Definition: nbgl_layout.h:66
void * nbgl_layout_t
type shared externally
Definition: nbgl_layout.h:96
void(* nbgl_layoutButtonCallback_t)(nbgl_layout_t *layout, nbgl_buttonEvent_t event)
prototype of function to be called when buttons are touched on a screen
Definition: nbgl_layout.h:111
int nbgl_layoutRelease(nbgl_layout_t *layout)
Release the layout obtained with nbgl_layoutGet()
Definition: nbgl_layout.c:3468
nbgl_layout_t * nbgl_layoutGet(const nbgl_layoutDescription_t *description)
returns a layout of the given type. The layout is reset
Definition: nbgl_layout.c:995
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
struct PACKED__ nbgl_screenTickerConfiguration_s nbgl_screenTickerConfiguration_t
struct to configure a screen layer
Step construction API of NBGL.
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
Definition: nbgl_step.h:56
@ NEITHER_FIRST_NOR_LAST_STEP
neither first nor last in a multiple steps flow
Definition: nbgl_step.h:66
@ LAST_STEP
last in a multiple steps flow
Definition: nbgl_step.h:65
@ FIRST_STEP
first in a multiple steps flow
Definition: nbgl_step.h:64
uint8_t nbgl_stepGetMenuListCurrent(nbgl_step_t step)
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
nbgl_step_t nbgl_stepDrawMenuList(nbgl_stepMenuListCallback_t onActionCallback, nbgl_screenTickerConfiguration_t *ticker, nbgl_layoutMenuList_t *list, bool modal)
int nbgl_stepRelease(nbgl_step_t step)
void(* nbgl_stepMenuListCallback_t)(uint8_t choiceIndex)
prototype of chosen menu list item callback
Definition: nbgl_step.h:50
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_area_s nbgl_area_t
Represents a rectangle area of the screen.
This structure contains info to build a centered (vertically and horizontally) area,...
Definition: nbgl_content.h:57
Structure containing all information when creating a layout. This structure must be passed as argumen...
Definition: nbgl_layout.h:171
nbgl_screenTickerConfiguration_t ticker
Definition: nbgl_layout.h:190
nbgl_layoutTouchCallback_t onActionCallback
the callback to be called on any action on the layout
Definition: nbgl_layout.h:185
This structure contains a list of names to build a menu list on Nanos, with for each item a descripti...
Definition: nbgl_layout.h:235
nbgl_menuListCallback_t callback
function to call to retrieve a menu list item text
Definition: nbgl_layout.h:236
uint8_t nbChoices
total number of choices in the menu list
Definition: nbgl_layout.h:237
uint8_t selectedChoice
index of the selected choice (centered, in bold)
Definition: nbgl_layout.h:238
This structure contains info to build a navigation bar at the bottom of the screen.
Definition: nbgl_layout.h:160
nbgl_layoutNavDirection_t direction
vertical or horizontal navigation
Definition: nbgl_layout.h:161
nbgl_layoutNavIndication_t indication
specifies which arrows to use (left or right)
Definition: nbgl_layout.h:162
unsigned short uint16_t
Definition: usbd_conf.h:54
unsigned char uint8_t
Definition: usbd_conf.h:53
BOLOS_UX_LOC_STRINGS UX_LOC_STRINGS_INDEX