Embedded SDK
Embedded SDK
Loading...
Searching...
No Matches
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 **********************/
35typedef enum {
36 TEXT_STEP = 0,
37 CENTERED_INFO_STEP,
38 MENU_LIST_STEP
39} StepStype_t;
40
44typedef 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 bool actionOnAnyButton;
53 nbgl_stepButtonCallback_t onActionCallback;
55 char tmpString[TMP_STRING_MAX_LEN];
58 style;
59} TextContext_t;
60
64typedef struct MenuListContext_s {
66 selectedCallback;
68 list;
69} MenuListContext_t;
70
71typedef struct StepContext_s {
72 union {
73 TextContext_t textContext;
74 MenuListContext_t menuListContext;
75 };
77 nbgl_layout_t *layout;
78 StepStype_t type;
79 bool modal;
80} StepContext_t;
81
82/**********************
83 * STATIC VARIABLES
84 **********************/
86static StepContext_t contexts[NB_MAX_LAYERS];
87
88/**********************
89 * VARIABLES
90 **********************/
91#ifdef BUILD_SCREENSHOTS
92// Variables used to store important values (nb lines, bold state etc)
93extern uint16_t last_nb_lines;
94extern uint16_t last_nb_pages;
95extern bool last_bold_state;
96#endif // BUILD_SCREENSHOTS
97
98/**********************
99 * STATIC PROTOTYPES
100 **********************/
101
102static void actionCallback(nbgl_layout_t *layout, nbgl_buttonEvent_t event);
103static void menuListActionCallback(nbgl_layout_t *layout, nbgl_buttonEvent_t event);
104
105// returns a non-used step context from the contexts[] array, or NULL if not found
106static StepContext_t *getFreeContext(StepStype_t type, bool modal)
107{
108 StepContext_t *ctx = NULL;
109
110 if (!modal) {
111 // Index 0 is reserved for background
112 ctx = &contexts[0];
113 }
114 else {
115 uint32_t i = 1;
116 while (i < NB_MAX_LAYERS) {
117 if (contexts[i].layout == NULL) {
118 ctx = &contexts[i];
119 break;
120 }
121 i++;
122 }
123 }
124 if (ctx == NULL) {
125 LOG_FATAL(STEP_LOGGER, "getFreeContext(): no available context\n");
126 }
127 else {
128 memset(ctx, 0, sizeof(StepContext_t));
129 ctx->type = type;
130 ctx->modal = modal;
131 }
132 return ctx;
133}
134
135// returns the step context from the contexts[] array matching with the given layout handler, or
136// NULL if not found
137static StepContext_t *getContextFromLayout(nbgl_layout_t layout)
138{
139 StepContext_t *ctx = NULL;
140 uint32_t i = 0;
141 while (i < NB_MAX_LAYERS) {
142 if (contexts[i].layout == layout) {
143 ctx = &contexts[i];
144 break;
145 }
146 i++;
147 }
148 if (ctx == NULL) {
149 LOG_WARN(STEP_LOGGER, "getContextFromLayout(): no matching context\n");
150 }
151 return ctx;
152}
153
154// from the current details context, return a pointer on the details at the given page
155static const char *getTextPageAt(StepContext_t *ctx, uint8_t textPage)
156{
157 uint8_t page = 0;
158 const char *currentChar = ctx->textContext.txtStart;
159 while (page < textPage) {
160 if (page < (ctx->textContext.nbPages - 1)) {
161 uint16_t len;
163 currentChar,
166 &len,
167 true);
168 currentChar = currentChar + len;
169 }
170 page++;
171 }
172 return currentChar;
173}
174
175// from the current details context, return a pointer on the details at the given page, for subText
176static const char *getSubTextPageAt(StepContext_t *ctx, uint8_t textPage)
177{
178 uint8_t page = 0;
179 const char *currentChar = ctx->textContext.subTxtStart;
180 while (page < textPage) {
181 if (page < (ctx->textContext.nbPages - 1)) {
182 uint16_t len;
184 currentChar,
186 NB_MAX_LINES - 1,
187 &len,
188 true);
189 currentChar = currentChar + len;
190 }
191 page++;
192 }
193 return currentChar;
194}
195
196// utility function to compute navigation arrows
197static nbgl_layoutNavIndication_t getNavigationInfo(nbgl_stepPosition_t pos,
198 uint8_t nbPages,
199 uint8_t currentPage)
200{
202
203 if (nbPages > 1) {
204 if (currentPage > 0) {
205 indication |= LEFT_ARROW;
206 }
207 if (currentPage < (nbPages - 1)) {
208 indication |= RIGHT_ARROW;
209 }
210 }
211 if (pos == FIRST_STEP) {
212 indication |= RIGHT_ARROW;
213 }
214 else if (pos == LAST_STEP) {
215 indication |= LEFT_ARROW;
216 }
217 else if (pos == NEITHER_FIRST_NOR_LAST_STEP) {
218 indication |= RIGHT_ARROW | LEFT_ARROW;
219 }
220 return indication;
221}
222
223// function used to display the current page in details review mode
224static void displayTextPage(StepContext_t *ctx, uint8_t textPage)
225{
226 const char *txt;
227 char intermediateString[36]; // a bit bigger but we know that one line cannot contain
228 // more than 23 chars
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 // if the next char is '\n', skip it to avoid starting with an empty line
255 if (*ctx->textContext.nextPageStart == '\n') {
256 ctx->textContext.nextPageStart++;
257 }
258 }
259 else {
260 ctx->textContext.nextPageStart = NULL;
261 }
262 nbgl_layoutDescription_t layoutDescription;
263 nbgl_layoutNavigation_t navInfo = {
265 };
266
267 layoutDescription.modal = ctx->modal;
268 layoutDescription.onActionCallback = actionCallback;
269 layoutDescription.ticker.tickerCallback = ctx->ticker.tickerCallback;
270 layoutDescription.ticker.tickerIntervale = ctx->ticker.tickerIntervale;
271 layoutDescription.ticker.tickerValue = ctx->ticker.tickerValue;
272 ctx->layout = nbgl_layoutGet(&layoutDescription);
273
274 navInfo.indication = getNavigationInfo(
275 ctx->textContext.pos, ctx->textContext.nbPages, ctx->textContext.currentPage);
276
277 if (ctx->textContext.subTxtStart == NULL) {
278 nbgl_layoutAddText(ctx->layout, txt, NULL, ctx->textContext.style);
279 }
280 else {
281 if (ctx->textContext.nbPages == 1) {
282 // truncate title to fit in one line, if necessary
284 ctx->textContext.txtStart,
286 false)
287 > 1) {
289 ctx->textContext.txtStart,
291 1,
292 ctx->textContext.tmpString,
293 TMP_STRING_MAX_LEN);
294 }
295 else {
296 if (ctx->textContext.txtStart != NULL) {
297 // simply copy
298 memcpy(ctx->textContext.tmpString,
299 ctx->textContext.txtStart,
300 TMP_STRING_MAX_LEN - 1);
301 ctx->textContext.tmpString[TMP_STRING_MAX_LEN - 1] = 0;
302 }
303 else {
304 ctx->textContext.tmpString[0] = 0;
305 }
306 }
307 }
308 else {
309 SPRINTF(intermediateString,
310 "%s (%d/%d)",
311 ctx->textContext.txtStart,
312 ctx->textContext.currentPage + 1,
313 ctx->textContext.nbPages);
314 // truncate title to fit in one line, if necessary
316 intermediateString,
318 false)
319 > 1) {
321 intermediateString,
323 1,
324 ctx->textContext.tmpString,
325 TMP_STRING_MAX_LEN);
326 }
327 else {
328 // simply copy
329 memcpy(ctx->textContext.tmpString, intermediateString, TMP_STRING_MAX_LEN - 1);
330 ctx->textContext.tmpString[TMP_STRING_MAX_LEN - 1] = 0;
331 }
332 }
333 nbgl_layoutAddText(ctx->layout, ctx->textContext.tmpString, txt, ctx->textContext.style);
334 }
335 if (navInfo.indication != NO_ARROWS) {
336 nbgl_layoutAddNavigation(ctx->layout, &navInfo);
337 }
338 nbgl_layoutDraw(ctx->layout);
339 nbgl_refresh();
340}
341
342// callback on key touch
343static void actionCallback(nbgl_layout_t *layout, nbgl_buttonEvent_t event)
344{
345 StepContext_t *ctx = getContextFromLayout(layout);
346
347 if (!ctx) {
348 return;
349 }
350 if (event == BUTTON_LEFT_PRESSED) {
351 if (ctx->textContext.currentPage > 0) {
352 displayTextPage(ctx, ctx->textContext.currentPage - 1);
353 return;
354 }
355 else if ((ctx->textContext.pos == LAST_STEP)
356 || (ctx->textContext.pos == NEITHER_FIRST_NOR_LAST_STEP)
357 || (ctx->textContext.actionOnAnyButton)) {
358 if (ctx->textContext.onActionCallback != NULL) {
359 ctx->textContext.onActionCallback((nbgl_step_t) ctx, event);
360 }
361 }
362 }
363 else if (event == BUTTON_RIGHT_PRESSED) {
364 if (ctx->textContext.currentPage < (ctx->textContext.nbPages - 1)) {
365 displayTextPage(ctx, ctx->textContext.currentPage + 1);
366 return;
367 }
368 else if ((ctx->textContext.pos == FIRST_STEP)
369 || (ctx->textContext.pos == NEITHER_FIRST_NOR_LAST_STEP)
370 || (ctx->textContext.actionOnAnyButton)) {
371 if (ctx->textContext.onActionCallback != NULL) {
372 ctx->textContext.onActionCallback((nbgl_step_t) ctx, event);
373 }
374 }
375 }
376 else if (event == BUTTON_BOTH_PRESSED) {
377 if (ctx->textContext.onActionCallback != NULL) {
378 ctx->textContext.onActionCallback((nbgl_step_t) ctx, event);
379 }
380 }
381}
382
383static void displayMenuList(StepContext_t *ctx)
384{
385 nbgl_layoutDescription_t layoutDescription
386 = {.modal = ctx->modal, .onActionCallback = menuListActionCallback};
387 nbgl_layoutMenuList_t *list = &ctx->menuListContext.list;
388
389 layoutDescription.ticker.tickerCallback = ctx->ticker.tickerCallback;
390 layoutDescription.ticker.tickerIntervale = ctx->ticker.tickerIntervale;
391 layoutDescription.ticker.tickerValue = ctx->ticker.tickerValue;
392
393 ctx->layout = nbgl_layoutGet(&layoutDescription);
394 nbgl_layoutAddMenuList(ctx->layout, list);
395 if (list->nbChoices > 1) {
397 navInfo.indication = 0;
398 if (list->selectedChoice > 0) {
399 navInfo.indication |= LEFT_ARROW;
400 }
401 if (list->selectedChoice < (list->nbChoices - 1)) {
402 navInfo.indication |= RIGHT_ARROW;
403 }
404
405 if (navInfo.indication != NO_ARROWS) {
406 nbgl_layoutAddNavigation(ctx->layout, &navInfo);
407 }
408 }
409 nbgl_layoutDraw(ctx->layout);
410 nbgl_refresh();
411}
412
413// callback on key touch
414static void menuListActionCallback(nbgl_layout_t *layout, nbgl_buttonEvent_t event)
415{
416 StepContext_t *ctx = getContextFromLayout(layout);
417 if (!ctx) {
418 return;
419 }
420
421 if (event == BUTTON_LEFT_PRESSED) {
422 if (ctx->menuListContext.list.selectedChoice > 0) {
423 ctx->menuListContext.list.selectedChoice--;
424 displayMenuList(ctx);
425 }
426 }
427 else if (event == BUTTON_RIGHT_PRESSED) {
428 if (ctx->menuListContext.list.selectedChoice < (ctx->menuListContext.list.nbChoices - 1)) {
429 ctx->menuListContext.list.selectedChoice++;
430 displayMenuList(ctx);
431 }
432 }
433 else if (event == BUTTON_BOTH_PRESSED) {
434 ctx->menuListContext.selectedCallback(ctx->menuListContext.list.selectedChoice);
435 }
436}
437
438/**********************
439 * GLOBAL FUNCTIONS
440 **********************/
441
457 nbgl_stepButtonCallback_t onActionCallback,
459 const char *text,
460 const char *subText,
462 bool modal)
463{
464#ifdef BUILD_SCREENSHOTS
465 // Initialize a default area
466 nbgl_area_t area;
467 area.x0 = area.y0 = 0;
468 area.width = AVAILABLE_WIDTH;
470#endif // BUILD_SCREENSHOTS
471 StepContext_t *ctx = getFreeContext(TEXT_STEP, modal);
472 if (!ctx) {
473 return NULL;
474 }
475 // initialize context (already set to 0 by getFreeContext())
476 ctx->textContext.onActionCallback = onActionCallback;
477 if (ticker) {
478 ctx->ticker.tickerCallback = ticker->tickerCallback;
479 ctx->ticker.tickerIntervale = ticker->tickerIntervale;
480 ctx->ticker.tickerValue = ticker->tickerValue;
481 }
482
483 // if no subText, get the number of pages for main text
484 if (subText == NULL) {
485 ctx->textContext.nbPages = nbgl_getTextNbPagesInWidth(
487#ifdef BUILD_SCREENSHOTS
488 store_string_infos(text,
490 &area,
491 true,
492 last_nb_lines,
493 last_nb_pages,
494 last_bold_state);
495#endif // BUILD_SCREENSHOTS
496 }
497 else {
498#ifdef BUILD_SCREENSHOTS
499 uint16_t nb_lines_title;
500 // Call this function to get correct nb_lines/nb_pages for text field.
503 nb_lines_title = last_nb_lines;
504 // There is a sub text, so no more than 3 lines for title...
505 if (nb_lines_title > 3) {
506 nb_lines_title = 3;
507 }
508 area.height
510 store_string_infos(text,
512 &area,
513 true,
514 last_nb_lines,
515 last_nb_pages,
516 last_bold_state);
517#endif // BUILD_SCREENSHOTS
518 // NB_MAX_LINES-1 because first line is for main text
519 ctx->textContext.nbPages = nbgl_getTextNbPagesInWidth(
521#ifdef BUILD_SCREENSHOTS
522 area.height = (NB_MAX_LINES - nb_lines_title)
524 // If subTxtid is not valid, we'll use txtId for nb_lines/nb_pages values
525 store_string_infos(subText,
527 &area,
528 true,
529 last_nb_lines,
530 last_nb_pages,
531 last_bold_state);
532#endif // BUILD_SCREENSHOTS
533 }
535 "nbgl_stepDrawText: ctx = %p, nbPages = %d, pos = 0x%X\n",
536 ctx,
537 ctx->textContext.nbPages,
538 pos);
539 if (pos & BACKWARD_DIRECTION) {
540 // start with last page
541 ctx->textContext.currentPage = ctx->textContext.nbPages - 1;
542 }
543 ctx->textContext.txtStart = text;
544 ctx->textContext.subTxtStart = subText;
545 // keep only direction part of position
546 ctx->textContext.pos = pos & STEP_POSITION_MASK;
547 ctx->textContext.actionOnAnyButton = (pos & ACTION_ON_ANY_BUTTON) != 0;
548 ctx->textContext.style = style;
549 displayTextPage(ctx, ctx->textContext.currentPage);
550
551 return (nbgl_step_t) ctx;
552}
553
565 nbgl_stepButtonCallback_t onActionCallback,
568 bool modal)
569{
570 nbgl_layoutDescription_t layoutDescription
571 = {.modal = modal, .onActionCallback = (nbgl_layoutButtonCallback_t) actionCallback};
572 nbgl_layoutNavigation_t navInfo = {
574 };
575 StepContext_t *ctx = getFreeContext(CENTERED_INFO_STEP, modal);
576 if (!ctx) {
577 return NULL;
578 }
579
580 // initialize context (already set to 0 by getFreeContext())
581 ctx->textContext.onActionCallback = onActionCallback;
582 if (ticker) {
583 ctx->ticker.tickerCallback = ticker->tickerCallback;
584 ctx->ticker.tickerIntervale = ticker->tickerIntervale;
585 ctx->ticker.tickerValue = ticker->tickerValue;
586 layoutDescription.ticker.tickerCallback = ticker->tickerCallback;
587 layoutDescription.ticker.tickerIntervale = ticker->tickerIntervale;
588 layoutDescription.ticker.tickerValue = ticker->tickerValue;
589 }
590
591 ctx->textContext.nbPages = 1;
592 // keep only direction part of position
593 ctx->textContext.pos = pos & (RIGHT_ARROW | LEFT_ARROW);
594 navInfo.indication = getNavigationInfo(
595 ctx->textContext.pos, ctx->textContext.nbPages, ctx->textContext.currentPage);
596
597 ctx->layout = nbgl_layoutGet(&layoutDescription);
598 nbgl_layoutAddCenteredInfo(ctx->layout, info);
599 if (navInfo.indication != NO_ARROWS) {
600 nbgl_layoutAddNavigation(ctx->layout, &navInfo);
601 }
602 nbgl_layoutDraw(ctx->layout);
603 nbgl_refresh();
604
605 LOG_DEBUG(STEP_LOGGER, "nbgl_stepDrawCenteredInfo(): step = %p\n", ctx);
606 return (nbgl_step_t) ctx;
607}
608
622 bool modal)
623{
624 StepContext_t *ctx = getFreeContext(MENU_LIST_STEP, modal);
625 if (!ctx) {
626 return NULL;
627 }
628
629 // initialize context (already set to 0 by getFreeContext())
630 if (ticker) {
631 ctx->ticker.tickerCallback = ticker->tickerCallback;
632 ctx->ticker.tickerIntervale = ticker->tickerIntervale;
633 ctx->ticker.tickerValue = ticker->tickerValue;
634 }
635
636 ctx->menuListContext.list.nbChoices = list->nbChoices;
637 ctx->menuListContext.list.selectedChoice = list->selectedChoice;
638 ctx->menuListContext.list.callback = list->callback;
639 ctx->menuListContext.selectedCallback = onActionCallback;
640
641 displayMenuList(ctx);
642
643 LOG_DEBUG(STEP_LOGGER, "nbgl_stepDrawMenuList(): step = %p\n", ctx);
644
645 return (nbgl_step_t) ctx;
646}
647
655{
656 StepContext_t *ctx = (StepContext_t *) step;
657 if (!ctx) {
658 return 0;
659 }
660 return (ctx->menuListContext.list.selectedChoice);
661}
662
676 nbgl_stepButtonCallback_t onActionCallback,
678 nbgl_layoutSwitch_t *switchInfo,
679 bool modal)
680{
681 nbgl_layoutDescription_t layoutDescription
682 = {.modal = modal, .onActionCallback = (nbgl_layoutButtonCallback_t) actionCallback};
683 nbgl_layoutNavigation_t navInfo = {
685 };
686 StepContext_t *ctx = getFreeContext(CENTERED_INFO_STEP, modal);
687 if (!ctx) {
688 return NULL;
689 }
690
691 // initialize context (already set to 0 by getFreeContext())
692 ctx->textContext.onActionCallback = onActionCallback;
693 if (ticker) {
694 ctx->ticker.tickerCallback = ticker->tickerCallback;
695 ctx->ticker.tickerIntervale = ticker->tickerIntervale;
696 ctx->ticker.tickerValue = ticker->tickerValue;
697 layoutDescription.ticker.tickerCallback = ticker->tickerCallback;
698 layoutDescription.ticker.tickerIntervale = ticker->tickerIntervale;
699 layoutDescription.ticker.tickerValue = ticker->tickerValue;
700 }
701
702 ctx->textContext.nbPages = 1;
703 // keep only direction part of position
704 ctx->textContext.pos = pos & (RIGHT_ARROW | LEFT_ARROW);
705 navInfo.indication = getNavigationInfo(
706 ctx->textContext.pos, ctx->textContext.nbPages, ctx->textContext.currentPage);
707
708 ctx->layout = nbgl_layoutGet(&layoutDescription);
709 nbgl_layoutAddSwitch(ctx->layout, switchInfo);
710 if (navInfo.indication != NO_ARROWS) {
711 nbgl_layoutAddNavigation(ctx->layout, &navInfo);
712 }
713 nbgl_layoutDraw(ctx->layout);
714 nbgl_refresh();
715
716 LOG_DEBUG(STEP_LOGGER, "nbgl_stepDrawSwitch(): ctx = %p\n", ctx);
717 return (nbgl_step_t) ctx;
718}
719
727{
728 StepContext_t *ctx = (StepContext_t *) step;
729 int ret;
730
731 LOG_DEBUG(STEP_LOGGER, "nbgl_stepRelease(): ctx = %p\n", ctx);
732 if (!ctx) {
733 return -1;
734 }
735 ret = nbgl_layoutRelease((nbgl_layout_t *) ctx->layout);
736
737 ctx->layout = NULL;
738
739 return ret;
740}
741
742#endif // NBGL_STEP
nbgl_contentCenteredInfoStyle_t
possible styles for Centered Info Area
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)
bool nbgl_getTextMaxLenInNbLines(nbgl_font_id_e fontId, const char *text, uint16_t maxWidth, uint16_t maxNbLines, uint16_t *len, bool wrapping)
@ BAGL_FONT_OPEN_SANS_REGULAR_11px_1bpp
Definition nbgl_fonts.h:141
@ BAGL_FONT_OPEN_SANS_EXTRABOLD_11px_1bpp
Definition nbgl_fonts.h:139
void nbgl_textReduceOnNbLines(nbgl_font_id_e fontId, const char *origText, uint16_t maxWidth, uint8_t nbLines, char *reducedText, uint16_t reducedTextLen)
uint16_t nbgl_getTextNbLinesInWidth(nbgl_font_id_e fontId, const char *text, uint16_t maxWidth, bool wrapping)
uint8_t nbgl_getFontLineHeight(nbgl_font_id_e fontId)
#define NB_MAX_LINES
@ VERTICAL_NAV
'\/' and '/\' are displayed, to navigate in a list (vertical scrolling)
@ HORIZONTAL_NAV
'<' and '>' are displayed, to navigate between pages and steps
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)
nbgl_layoutNavIndication_t
possible styles for Navigation arrows (it's a bit field)
@ NO_ARROWS
@ LEFT_ARROW
left arrow is used
@ RIGHT_ARROW
right arrow is used
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...
int nbgl_layoutDraw(nbgl_layout_t *layout)
Applies given layout. The screen will be redrawn.
#define AVAILABLE_WIDTH
void * nbgl_layout_t
type shared externally
int nbgl_layoutAddSwitch(nbgl_layout_t *layout, const nbgl_layoutSwitch_t *switchLayout)
Creates a switch with the given text and its state.
nbgl_layout_t * nbgl_layoutGet(const nbgl_layoutDescription_t *description)
returns a layout of the given type. The layout is reset
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
int nbgl_layoutRelease(nbgl_layout_t *layout)
Release the layout obtained with nbgl_layoutGet()
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
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:57
uint8_t nbgl_stepGetMenuListCurrent(nbgl_step_t step)
nbgl_step_t nbgl_stepDrawSwitch(nbgl_stepPosition_t pos, nbgl_stepButtonCallback_t onActionCallback, nbgl_screenTickerConfiguration_t *ticker, nbgl_layoutSwitch_t *switchInfo, bool modal)
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
#define STEP_POSITION_MASK
Definition nbgl_step.h:79
nbgl_step_t nbgl_stepDrawMenuList(nbgl_stepMenuListCallback_t onActionCallback, nbgl_screenTickerConfiguration_t *ticker, nbgl_layoutMenuList_t *list, bool modal)
#define ACTION_ON_ANY_BUTTON
When action callback applies only on both button press.
Definition nbgl_step.h:75
@ NEITHER_FIRST_NOR_LAST_STEP
neither first nor last in a multiple steps flow
Definition nbgl_step.h:67
@ LAST_STEP
last in a multiple steps flow
Definition nbgl_step.h:66
@ FIRST_STEP
first in a multiple steps flow
Definition nbgl_step.h:65
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
When action callback applies on any button press.
Definition nbgl_step.h:73
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,...
This structure contains info to build a switch (on the right) with a description (on the left),...
Structure containing all information when creating a layout. This structure must be passed as argumen...
nbgl_screenTickerConfiguration_t ticker
nbgl_layoutTouchCallback_t onActionCallback
the callback to be called on any action on the layout
This structure contains a list of names to build a menu list on Nanos, with for each item a descripti...
nbgl_menuListCallback_t callback
function to call to retrieve a menu list item text
uint8_t nbChoices
total number of choices in the menu list
uint8_t selectedChoice
index of the selected choice (centered, in bold)
This structure contains info to build a navigation bar at the bottom of the screen.
nbgl_layoutNavDirection_t direction
vertical or horizontal navigation
nbgl_layoutNavIndication_t indication
specifies which arrows to use (left or right)