16#ifdef BUILD_SCREENSHOTS
17#include "json_scenario.h"
24#define TMP_STRING_MAX_LEN 24
27#define NB_MAX_LAYERS 3
44typedef struct TextContext_s {
48 const char *nextPageStart;
49 const char *subTxtStart;
52 bool actionOnAnyButton;
55 char tmpString[TMP_STRING_MAX_LEN];
64typedef struct MenuListContext_s {
71typedef struct StepContext_s {
73 TextContext_t textContext;
74 MenuListContext_t menuListContext;
86static StepContext_t contexts[NB_MAX_LAYERS];
91#ifdef BUILD_SCREENSHOTS
95extern bool last_bold_state;
106static StepContext_t *getFreeContext(StepStype_t type,
bool modal)
108 StepContext_t *ctx = NULL;
116 while (i < NB_MAX_LAYERS) {
117 if (contexts[i].layout == NULL) {
128 memset(ctx, 0,
sizeof(StepContext_t));
137static StepContext_t *getContextFromLayout(
nbgl_layout_t layout)
139 StepContext_t *ctx = NULL;
141 while (i < NB_MAX_LAYERS) {
142 if (contexts[i].layout == layout) {
155static const char *getTextPageAt(StepContext_t *ctx,
uint8_t textPage)
158 const char *currentChar = ctx->textContext.txtStart;
159 while (page < textPage) {
160 if (page < (ctx->textContext.nbPages - 1)) {
168 currentChar = currentChar + len;
176static const char *getSubTextPageAt(StepContext_t *ctx,
uint8_t textPage)
179 const char *currentChar = ctx->textContext.subTxtStart;
180 while (page < textPage) {
181 if (page < (ctx->textContext.nbPages - 1)) {
189 currentChar = currentChar + len;
204 if (currentPage > 0) {
207 if (currentPage < (nbPages - 1)) {
224static void displayTextPage(StepContext_t *ctx,
uint8_t textPage)
227 char intermediateString[36];
231 if (textPage <= ctx->textContext.currentPage) {
233 if (ctx->textContext.subTxtStart == NULL) {
234 txt = getTextPageAt(ctx, textPage);
237 txt = getSubTextPageAt(ctx, textPage);
242 txt = ctx->textContext.nextPageStart;
244 ctx->textContext.currentPage = textPage;
246 if (ctx->textContext.currentPage < (ctx->textContext.nbPages - 1)) {
253 ctx->textContext.nextPageStart = txt + len;
255 if (*ctx->textContext.nextPageStart ==
'\n') {
256 ctx->textContext.nextPageStart++;
260 ctx->textContext.nextPageStart = NULL;
267 layoutDescription.
modal = ctx->modal;
269 layoutDescription.
ticker.tickerCallback = ctx->ticker.tickerCallback;
270 layoutDescription.
ticker.tickerIntervale = ctx->ticker.tickerIntervale;
271 layoutDescription.
ticker.tickerValue = ctx->ticker.tickerValue;
275 ctx->textContext.pos, ctx->textContext.nbPages, ctx->textContext.currentPage);
277 if (ctx->textContext.subTxtStart == NULL) {
281 if (ctx->textContext.nbPages == 1) {
284 ctx->textContext.txtStart,
289 ctx->textContext.txtStart,
292 ctx->textContext.tmpString,
298 ctx->textContext.tmpString, ctx->textContext.txtStart, TMP_STRING_MAX_LEN - 1);
299 ctx->textContext.tmpString[TMP_STRING_MAX_LEN - 1] = 0;
303 SPRINTF(intermediateString,
305 ctx->textContext.txtStart,
306 ctx->textContext.currentPage + 1,
307 ctx->textContext.nbPages);
318 ctx->textContext.tmpString,
323 memcpy(ctx->textContext.tmpString, intermediateString, TMP_STRING_MAX_LEN - 1);
324 ctx->textContext.tmpString[TMP_STRING_MAX_LEN - 1] = 0;
327 nbgl_layoutAddText(ctx->layout, ctx->textContext.tmpString, txt, ctx->textContext.style);
330 nbgl_layoutAddNavigation(ctx->layout, &navInfo);
339 StepContext_t *ctx = getContextFromLayout(layout);
345 if (ctx->textContext.currentPage > 0) {
346 displayTextPage(ctx, ctx->textContext.currentPage - 1);
349 else if ((ctx->textContext.pos ==
LAST_STEP)
351 || (ctx->textContext.actionOnAnyButton)) {
352 if (ctx->textContext.onActionCallback != NULL) {
353 ctx->textContext.onActionCallback((
nbgl_step_t) ctx, event);
358 if (ctx->textContext.currentPage < (ctx->textContext.nbPages - 1)) {
359 displayTextPage(ctx, ctx->textContext.currentPage + 1);
364 || (ctx->textContext.actionOnAnyButton)) {
365 if (ctx->textContext.onActionCallback != NULL) {
366 ctx->textContext.onActionCallback((
nbgl_step_t) ctx, event);
371 if (ctx->textContext.onActionCallback != NULL) {
372 ctx->textContext.onActionCallback((
nbgl_step_t) ctx, event);
377static void displayMenuList(StepContext_t *ctx)
380 = {.
modal = ctx->modal, .onActionCallback = menuListActionCallback};
383 layoutDescription.
ticker.tickerCallback = ctx->ticker.tickerCallback;
384 layoutDescription.
ticker.tickerIntervale = ctx->ticker.tickerIntervale;
385 layoutDescription.
ticker.tickerValue = ctx->ticker.tickerValue;
388 nbgl_layoutAddMenuList(ctx->layout, list);
400 nbgl_layoutAddNavigation(ctx->layout, &navInfo);
410 StepContext_t *ctx = getContextFromLayout(layout);
416 if (ctx->menuListContext.list.selectedChoice > 0) {
417 ctx->menuListContext.list.selectedChoice--;
418 displayMenuList(ctx);
422 if (ctx->menuListContext.list.selectedChoice < (ctx->menuListContext.list.nbChoices - 1)) {
423 ctx->menuListContext.list.selectedChoice++;
424 displayMenuList(ctx);
428 ctx->menuListContext.selectedCallback(ctx->menuListContext.list.selectedChoice);
458#ifdef BUILD_SCREENSHOTS
461 area.x0 = area.y0 = 0;
465 StepContext_t *ctx = getFreeContext(TEXT_STEP, modal);
470 ctx->textContext.onActionCallback = onActionCallback;
472 ctx->ticker.tickerCallback = ticker->tickerCallback;
473 ctx->ticker.tickerIntervale = ticker->tickerIntervale;
474 ctx->ticker.tickerValue = ticker->tickerValue;
478 if (subText == NULL) {
481#ifdef BUILD_SCREENSHOTS
482 store_string_infos(text,
492#ifdef BUILD_SCREENSHOTS
497 nb_lines_title = last_nb_lines;
499 if (nb_lines_title > 3) {
504 store_string_infos(text,
515#ifdef BUILD_SCREENSHOTS
519 store_string_infos(subText,
529 "nbgl_stepDrawText: ctx = %p, nbPages = %d, pos = 0x%X\n",
531 ctx->textContext.nbPages,
535 ctx->textContext.currentPage = ctx->textContext.nbPages - 1;
537 ctx->textContext.txtStart = text;
538 ctx->textContext.subTxtStart = subText;
542 ctx->textContext.style = style;
543 displayTextPage(ctx, ctx->textContext.currentPage);
569 StepContext_t *ctx = getFreeContext(CENTERED_INFO_STEP, modal);
575 ctx->textContext.onActionCallback = onActionCallback;
577 ctx->ticker.tickerCallback = ticker->tickerCallback;
578 ctx->ticker.tickerIntervale = ticker->tickerIntervale;
579 ctx->ticker.tickerValue = ticker->tickerValue;
580 layoutDescription.
ticker.tickerCallback = ticker->tickerCallback;
581 layoutDescription.
ticker.tickerIntervale = ticker->tickerIntervale;
582 layoutDescription.
ticker.tickerValue = ticker->tickerValue;
585 ctx->textContext.nbPages = 1;
589 ctx->textContext.pos, ctx->textContext.nbPages, ctx->textContext.currentPage);
594 nbgl_layoutAddNavigation(ctx->layout, &navInfo);
618 StepContext_t *ctx = getFreeContext(MENU_LIST_STEP, modal);
625 ctx->ticker.tickerCallback = ticker->tickerCallback;
626 ctx->ticker.tickerIntervale = ticker->tickerIntervale;
627 ctx->ticker.tickerValue = ticker->tickerValue;
630 ctx->menuListContext.list.nbChoices = list->
nbChoices;
632 ctx->menuListContext.list.callback = list->
callback;
633 ctx->menuListContext.selectedCallback = onActionCallback;
635 displayMenuList(ctx);
650 StepContext_t *ctx = (StepContext_t *) step;
654 return (ctx->menuListContext.list.selectedChoice);
680 StepContext_t *ctx = getFreeContext(CENTERED_INFO_STEP, modal);
686 ctx->textContext.onActionCallback = onActionCallback;
688 ctx->ticker.tickerCallback = ticker->tickerCallback;
689 ctx->ticker.tickerIntervale = ticker->tickerIntervale;
690 ctx->ticker.tickerValue = ticker->tickerValue;
691 layoutDescription.
ticker.tickerCallback = ticker->tickerCallback;
692 layoutDescription.
ticker.tickerIntervale = ticker->tickerIntervale;
693 layoutDescription.
ticker.tickerValue = ticker->tickerValue;
696 ctx->textContext.nbPages = 1;
700 ctx->textContext.pos, ctx->textContext.nbPages, ctx->textContext.currentPage);
705 nbgl_layoutAddNavigation(ctx->layout, &navInfo);
722 StepContext_t *ctx = (StepContext_t *) step;
nbgl_contentCenteredInfoStyle_t
possible styles for Centered Info Area
#define LOG_WARN(__logger,...)
#define LOG_DEBUG(__logger,...)
#define LOG_FATAL(__logger,...)
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...
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,...
@ BAGL_FONT_OPEN_SANS_REGULAR_11px_1bpp
@ BAGL_FONT_OPEN_SANS_EXTRABOLD_11px_1bpp
void nbgl_textReduceOnNbLines(nbgl_font_id_e fontId, const char *origText, uint16_t maxWidth, uint8_t nbLines, char *reducedText, uint16_t reducedTextLen)
Create a reduced version of given ASCII text to wrap it on the given max width (in pixels),...
uint16_t nbgl_getTextNbLinesInWidth(nbgl_font_id_e fontId, const char *text, uint16_t maxWidth, bool wrapping)
compute the number of lines of the given text fitting in the given maxWidth
uint8_t nbgl_getFontLineHeight(nbgl_font_id_e fontId)
return the height in pixels of the line of font with the given font ID
@ 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)
@ 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.
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)
This functions refreshes the actual screen on display with what has changed since the last refresh.
@ BUTTON_BOTH_PRESSED
Sent when both buttons are released.
@ BUTTON_LEFT_PRESSED
Sent when Left button is released.
@ BUTTON_RIGHT_PRESSED
Send when Right button is released.
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
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
uint8_t nbgl_stepPosition_t
this type is a bitfield containing:
@ NEITHER_FIRST_NOR_LAST_STEP
neither first nor last in a multiple steps flow
@ LAST_STEP
last in a multiple steps flow
@ FIRST_STEP
first in a multiple steps flow
#define STEP_POSITION_MASK
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.
int nbgl_stepRelease(nbgl_step_t step)
void(* nbgl_stepMenuListCallback_t)(uint8_t choiceIndex)
prototype of chosen menu list item callback
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.
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 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)