24#include "os_helpers.h"
31#define INTERNAL_SPACE 16
33#define INNER_MARGIN 12
35#define NB_MAX_LAYOUTS 3
38#define NB_MAX_CONTAINER_CHILDREN 20
40#define TAG_VALUE_ICON_WIDTH 32
42#if defined(TARGET_STAX)
43#define RADIO_CHOICE_HEIGHT 96
44#define FOOTER_HEIGHT 80
45#define BAR_INTERVALE 12
46#define BACK_KEY_WIDTH 88
47#define FOOTER_BUTTON_HEIGHT 128
48#define UP_FOOTER_BUTTON_HEIGHT 120
49#define ROUNDED_AND_FOOTER_FOOTER_HEIGHT 192
50#define ACTION_AND_FOOTER_FOOTER_HEIGHT 216
51#define FOOTER_TEXT_AND_NAV_WIDTH 160
52#define TAP_TO_CONTINUE_MARGIN 24
53#define SUB_HEADER_MARGIN (2 * 24)
54#define PRE_FIRST_TEXT_MARGIN 24
55#define INTER_PARAGRAPHS_MARGIN 40
56#define PRE_TITLE_MARGIN 24
57#define PRE_DESCRIPTION_MARGIN 16
58#define INTER_ROWS_MARGIN 16
59#define QR_INTER_TEXTS_MARGIN 40
60#define SPINNER_TEXT_MARGIN 20
61#define SPINNER_INTER_TEXTS_MARGIN 20
62#define BAR_TEXT_MARGIN 24
63#define BAR_INTER_TEXTS_MARGIN 16
64#define PROGRESSBAR_ALIGNMENT_MARGIN_Y 28
65#define LEFT_CONTENT_TEXT_PADDING 0
66#elif defined(TARGET_FLEX)
67#define RADIO_CHOICE_HEIGHT 92
68#define FOOTER_HEIGHT 80
69#define BAR_INTERVALE 16
70#define BACK_KEY_WIDTH 104
71#define FOOTER_BUTTON_HEIGHT 136
72#define UP_FOOTER_BUTTON_HEIGHT 136
73#define ROUNDED_AND_FOOTER_FOOTER_HEIGHT 208
74#define ACTION_AND_FOOTER_FOOTER_HEIGHT 232
75#define FOOTER_TEXT_AND_NAV_WIDTH 192
76#define TAP_TO_CONTINUE_MARGIN 30
77#define SUB_HEADER_MARGIN (2 * 28)
78#define PRE_FIRST_TEXT_MARGIN 0
79#define INTER_PARAGRAPHS_MARGIN 24
80#define PRE_TITLE_MARGIN 16
81#define PRE_DESCRIPTION_MARGIN 24
82#define INTER_ROWS_MARGIN 26
83#define QR_INTER_TEXTS_MARGIN 28
84#define SPINNER_TEXT_MARGIN 24
85#define SPINNER_INTER_TEXTS_MARGIN 16
86#define BAR_TEXT_MARGIN 24
87#define BAR_INTER_TEXTS_MARGIN 16
88#define PROGRESSBAR_ALIGNMENT_MARGIN_Y 32
89#define LEFT_CONTENT_TEXT_PADDING 4
91#error Undefined target
95#define PROGRESSBAR_WIDTH 120
96#define PROGRESSBAR_HEIGHT 12
99#define SPINNER_REFRESH_PERIOD 400
127#ifdef HAVE_PIEZO_SOUND
143static uint8_t nbTouchableControls = 0;
150#ifdef HAVE_FAST_HOLD_TO_APPROVE
152#define HOLD_TO_APPROVE_STEP_PERCENT (7)
156#define HOLD_TO_APPROVE_STEP_DURATION_MS (100)
158#define HOLD_TO_APPROVE_STEP_PERCENT (25)
159#define HOLD_TO_APPROVE_STEP_DURATION_MS (400)
162static inline uint8_t get_hold_to_approve_percent(uint32_t touch_duration)
164#ifdef HAVE_FAST_HOLD_TO_APPROVE
173static bool getLayoutAndLayoutObj(
nbgl_obj_t *obj,
183 if (gLayout[i].nbChildren > 0) {
188 if (obj == gLayout[i].callbackObjPool[j].obj) {
190 "getLayoutAndLayoutObj(): obj found in layout[%d], index = %d, "
191 "nbUsedCallbackObjs = %d\n",
194 gLayout[i].nbUsedCallbackObjs);
195 *layout = &gLayout[i];
206static void radioTouchCallback(
nbgl_obj_t *obj,
219 bool needRefresh =
false;
225 if (getLayoutAndLayoutObj(obj, &layout, &layoutObj) ==
false) {
227 if (getLayoutAndLayoutObj(obj->parent, &layout, &layoutObj) ==
false) {
230 "touchCallback(): eventType = %d, obj = %p, no active layout or obj not found\n",
248 layoutObj->
index = eventType;
297 layoutObj->
index = lSwitch->state;
303 radioTouchCallback(obj, eventType, layout);
310 longTouchCallback(obj, eventType, layout, layoutObj);
315#ifdef HAVE_PIEZO_SOUND
317 io_seproxyhal_play_tune(layoutObj->
tuneId);
338 "longTouchCallback(): eventType = %d, obj = %p, gLayout[1].nbChildren = %d\n",
341 gLayout[1].nbChildren);
348 uint8_t new_state = get_hold_to_approve_percent(touchDuration);
352 bool trigger_callback = (new_state >= 100) && (progressBar->state < 100);
355 if (new_state >= 100) {
360 if (new_state != progressBar->state) {
361 progressBar->partialRedraw =
true;
362 progressBar->state = new_state;
371 if (trigger_callback) {
382 progressBar->partialRedraw =
true;
383 progressBar->state = 0;
390static void radioTouchCallback(
nbgl_obj_t *obj,
402 while (i < layout->nbUsedCallbackObjs) {
412 foundRadioIndex = radioIndex;
414 textArea->textColor =
BLACK;
415 textArea->fontId = SMALL_BOLD_FONT;
437 textArea->fontId = SMALL_REGULAR_FONT;
445 if (foundRadio != 0xFF) {
447#ifdef HAVE_PIEZO_SOUND
459static void spinnerTickerCallback(
void)
466 if (gLayout[1].nbChildren > 0) {
467 layout = &gLayout[1];
470 layout = &gLayout[0];
474 while (i < layout->container->nbChildren) {
477 if (container->nbChildren && (container->children[0]->type ==
SPINNER)) {
482 spinner->position = 0;
494static void animTickerCallback(
void)
501 if (gLayout[1].nbChildren > 0) {
502 layout = &gLayout[1];
505 layout = &gLayout[0];
513 while (i < layout->container->nbChildren) {
516 if (container->children[1]->type ==
IMAGE) {
561 line->obj.area.width = SCREEN_WIDTH;
562 line->obj.area.height = 4;
574 line->obj.area.width = 1;
575 line->obj.area.height = SCREEN_HEIGHT;
594 layoutObj->
obj = obj;
595 layoutObj->
token = token;
596 layoutObj->
tuneId = tuneId;
645 layoutInt->
container->obj.touchMask = swipesMask;
672 layoutInt, (
nbgl_obj_t *) container, itemDesc->
token, itemDesc->tuneId);
679 container->nbChildren = 0;
682 container->obj.area.height = itemDesc->
large ? TOUCHABLE_MAIN_BAR_HEIGHT : TOUCHABLE_BAR_HEIGHT;
684 container->obj.alignmentMarginX = BORDER_MARGIN;
686 container->obj.alignTo = NULL;
691 container->obj.touchMask = (1 <<
TOUCHED);
692 container->obj.touchId =
CONTROLS_ID + nbTouchableControls;
693 nbTouchableControls++;
698 textArea->textColor = color;
699 textArea->text = PIC(itemDesc->
text);
700 textArea->onDrawCallback = NULL;
701 textArea->fontId = SMALL_BOLD_FONT;
702 textArea->wrapping =
true;
703 textArea->obj.area.width = container->obj.area.width;
706 textArea->obj.area.width
711 textArea->obj.area.width
715 textArea->obj.area.width -= 60 + BAR_INTERVALE;
718 textArea->fontId, textArea->text, textArea->obj.area.width, textArea->wrapping);
719 usedHeight =
MAX(usedHeight, textArea->obj.area.height);
723 container->children[container->nbChildren] = (
nbgl_obj_t *) textArea;
724 container->nbChildren++;
729 imageLeft->foregroundColor = color;
730 imageLeft->buffer = PIC(itemDesc->
iconLeft);
732 imageLeft->obj.alignment =
MID_LEFT;
733 imageLeft->obj.alignTo = (
nbgl_obj_t *) textArea;
734 imageLeft->obj.alignmentMarginX = BAR_INTERVALE;
735 container->children[container->nbChildren] = (
nbgl_obj_t *) imageLeft;
736 container->nbChildren++;
738 textArea->obj.alignmentMarginX = imageLeft->buffer->width + BAR_INTERVALE;
740 usedHeight =
MAX(usedHeight, imageLeft->buffer->height);
745 imageRight->foregroundColor = color;
746 imageRight->buffer = PIC(itemDesc->
iconRight);
749 imageRight->obj.alignmentMarginX = BAR_INTERVALE;
750 imageRight->obj.alignTo = (
nbgl_obj_t *) textArea;
752 container->children[container->nbChildren] = (
nbgl_obj_t *) imageRight;
753 container->nbChildren++;
755 usedHeight =
MAX(usedHeight, imageRight->buffer->height);
759 switchObj->onColor =
BLACK;
761 switchObj->state = itemDesc->
state;
763 switchObj->obj.alignmentMarginX = BAR_INTERVALE;
764 switchObj->obj.alignTo = (
nbgl_obj_t *) textArea;
766 container->children[container->nbChildren] = (
nbgl_obj_t *) switchObj;
767 container->nbChildren++;
770 if (itemDesc->
subText != NULL) {
774 subTextArea->textColor = color;
775 subTextArea->text = PIC(itemDesc->
subText);
776 subTextArea->textAlignment =
MID_LEFT;
777 subTextArea->fontId = SMALL_REGULAR_FONT;
779 subTextArea->wrapping =
true;
780 subTextArea->obj.alignment =
MID_LEFT;
781 subTextArea->obj.area.width = container->obj.area.width;
784 subTextArea->obj.area.width,
785 subTextArea->wrapping);
786 container->children[container->nbChildren] = (
nbgl_obj_t *) subTextArea;
787 container->nbChildren++;
788 container->obj.area.height += subTextArea->obj.area.height + 12;
791 textArea->obj.alignmentMarginY = -(subTextArea->obj.area.height + 12) / 2;
792 subTextArea->obj.alignmentMarginY = (usedHeight + 12) / 2;
820 container->nbChildren = 0;
825 if (info->
icon != NULL) {
827 image->foregroundColor =
BLACK;
828 image->buffer = PIC(info->
icon);
830 image->obj.alignmentMarginY = info->
iconHug;
832 fullHeight += image->buffer->height + info->
iconHug;
833 container->children[container->nbChildren] = (
nbgl_obj_t *) image;
834 container->nbChildren++;
839 anim->foregroundColor =
BLACK;
845 container->children[container->nbChildren] = (
nbgl_obj_t *) anim;
846 container->nbChildren++;
857 tickerCfg.tickerCallback = &animTickerCallback;
862 if (info->
title != NULL) {
864 textArea->textColor =
BLACK;
865 textArea->text = PIC(info->
title);
866 textArea->textAlignment =
CENTER;
867 textArea->fontId = LARGE_MEDIUM_FONT;
868 textArea->wrapping =
true;
871 textArea->fontId, textArea->text, textArea->obj.area.width, textArea->wrapping);
874 if (container->nbChildren > 0) {
877 textArea->obj.alignmentMarginY = BOTTOM_BORDER_MARGIN + info->
iconHug;
883 fullHeight += textArea->obj.area.height + textArea->obj.alignmentMarginY;
885 container->children[container->nbChildren] = (
nbgl_obj_t *) textArea;
886 container->nbChildren++;
891 textArea->textColor =
BLACK;
893 textArea->textAlignment =
CENTER;
894 textArea->fontId = SMALL_BOLD_FONT;
895 textArea->wrapping =
true;
898 textArea->fontId, textArea->text, textArea->obj.area.width, textArea->wrapping);
901 if (container->nbChildren > 0) {
903 textArea->obj.alignTo = (
nbgl_obj_t *) container->children[container->nbChildren - 1];
904 textArea->obj.alignmentMarginY = BOTTOM_BORDER_MARGIN;
905 if (container->children[container->nbChildren - 1]->type ==
IMAGE) {
906 textArea->obj.alignmentMarginY = BOTTOM_BORDER_MARGIN + info->
iconHug;
909 textArea->obj.alignmentMarginY = 16;
916 fullHeight += textArea->obj.area.height + textArea->obj.alignmentMarginY;
918 container->children[container->nbChildren] = (
nbgl_obj_t *) textArea;
919 container->nbChildren++;
924 textArea->textColor =
BLACK;
926 textArea->textAlignment =
CENTER;
927 textArea->fontId = SMALL_REGULAR_FONT;
928 textArea->wrapping =
true;
931 textArea->fontId, textArea->text, textArea->obj.area.width, textArea->wrapping);
934 if (container->nbChildren > 0) {
936 textArea->obj.alignTo = (
nbgl_obj_t *) container->children[container->nbChildren - 1];
937 if (container->children[container->nbChildren - 1]->type ==
TEXT_AREA) {
939 textArea->obj.alignmentMarginY = 16;
942 textArea->obj.alignmentMarginY = BOTTOM_BORDER_MARGIN + info->
iconHug;
949 fullHeight += textArea->obj.area.height + textArea->obj.alignmentMarginY;
951 container->children[container->nbChildren] = (
nbgl_obj_t *) textArea;
952 container->nbChildren++;
958 textArea->text = PIC(info->
subText);
959 textArea->textAlignment =
CENTER;
960 textArea->fontId = SMALL_REGULAR_FONT;
961 textArea->wrapping =
true;
964 textArea->fontId, textArea->text, textArea->obj.area.width, textArea->wrapping);
966 textArea->obj.area.height += 2 * 8;
968 if (container->nbChildren > 0) {
970 textArea->obj.alignTo = (
nbgl_obj_t *) container->children[container->nbChildren - 1];
971 textArea->obj.alignmentMarginY = 16;
972 if (container->children[container->nbChildren - 1]->type ==
IMAGE) {
973 textArea->obj.alignmentMarginY += info->
iconHug;
980 fullHeight += textArea->obj.area.height + textArea->obj.alignmentMarginY;
982 container->children[container->nbChildren] = (
nbgl_obj_t *) textArea;
983 container->nbChildren++;
986 container->obj.alignment =
CENTER;
988 container->obj.area.height = fullHeight;
990 container->obj.area.height += 40;
1001 const char *subText,
1012 if (layout == NULL) {
1024 textArea->textColor =
BLACK;
1025 textArea->text = PIC(text);
1026 textArea->textAlignment =
MID_LEFT;
1027 textArea->fontId = SMALL_BOLD_FONT;
1029 textArea->wrapping =
true;
1031 textArea->obj.alignmentMarginY = PRE_TEXT_MARGIN;
1032 textArea->obj.area.width = container->obj.area.width;
1033 if (withAlias ==
true) {
1034 textArea->obj.area.width -= 12 + MINI_PUSH_ICON.width;
1037 textArea->fontId, textArea->text, textArea->obj.area.width, textArea->wrapping);
1038 fullHeight += textArea->obj.area.height + textArea->obj.alignmentMarginY;
1039 container->children[container->nbChildren] = (
nbgl_obj_t *) textArea;
1040 container->nbChildren++;
1041 if (withAlias ==
true) {
1047 image->foregroundColor =
BLACK;
1048 image->buffer = &PUSH_ICON;
1050 image->obj.alignmentMarginX = 12;
1051 image->obj.alignTo = (
nbgl_obj_t *) textArea;
1052 container->obj.touchMask = (1 <<
TOUCHED);
1055 container->children[container->nbChildren] = (
nbgl_obj_t *) image;
1056 container->nbChildren++;
1059 if (subText != NULL) {
1061 subTextArea->textColor =
BLACK;
1062 subTextArea->text = PIC(subText);
1063 subTextArea->fontId = SMALL_REGULAR_FONT;
1065 subTextArea->wrapping =
true;
1066 subTextArea->obj.area.width = container->obj.area.width;
1069 subTextArea->obj.area.width,
1070 subTextArea->wrapping);
1071 subTextArea->textAlignment =
MID_LEFT;
1074 subTextArea->obj.alignmentMarginY = TEXT_SUBTEXT_MARGIN;
1077 subTextArea->obj.alignmentMarginY = PRE_SUBTEXT_MARGIN;
1079 fullHeight += subTextArea->obj.alignmentMarginY;
1080 container->children[container->nbChildren] = (
nbgl_obj_t *) subTextArea;
1081 container->nbChildren++;
1082 fullHeight += subTextArea->obj.area.height + subTextArea->obj.alignmentMarginY;
1085 fullHeight += PRE_TEXT_MARGIN;
1087 container->obj.area.height = fullHeight;
1089 container->obj.alignmentMarginX = BORDER_MARGIN;
1094 return container->obj.area.height;
1112 if (description->
modal) {
1113 if (gLayout[1].nbChildren == 0) {
1114 layout = &gLayout[1];
1116 else if (gLayout[2].nbChildren == 0) {
1117 layout = &gLayout[2];
1123 layout = &gLayout[0];
1125 if (layout == NULL) {
1133 nbTouchableControls = 0;
1138 if (description->
modal) {
1152 layout->
container->obj.area.width = SCREEN_WIDTH;
1153 layout->
container->obj.area.height = SCREEN_HEIGHT;
1170 obj->
tuneId = description->tapTuneId;
1178 footerDesc.
text.tuneId = description->tapTuneId;
1200 tune_index_e tuneId)
1205 if (layout == NULL) {
1212 layoutInt->
tapText->text = PIC(text);
1214 layoutInt->
tapText->fontId = SMALL_REGULAR_FONT;
1218 layoutInt->
tapText->obj.alignmentMarginY = TAP_TO_CONTINUE_MARGIN;
1236 tune_index_e tuneId)
1243 if (layout == NULL) {
1252 button->obj.area.width = BUTTON_DIAMETER;
1253 button->obj.area.height = BUTTON_DIAMETER;
1254 button->radius = BUTTON_RADIUS;
1255 button->obj.alignmentMarginX = BORDER_MARGIN;
1256 button->obj.alignmentMarginY = BORDER_MARGIN;
1257 button->foregroundColor =
BLACK;
1258 button->innerColor =
WHITE;
1260 button->obj.touchMask = (1 <<
TOUCHED);
1262 button->icon = PIC(icon);
1307 bool separationLine,
1308 tune_index_e tuneId)
1318 footerDesc.
button.tuneId = tuneId;
1337 if (layout == NULL) {
1341 if (barLayout->
text == NULL) {
1350 itemDesc.tuneId = barLayout->tuneId;
1354 container = addListItem(layoutInt, &itemDesc);
1356 if (container == NULL) {
1359 return container->obj.area.height;
1376 if (layout == NULL) {
1380 if (switchLayout->
text == NULL) {
1386 itemDesc.
text = switchLayout->
text;
1389 itemDesc.tuneId = switchLayout->tuneId;
1391 itemDesc.
large =
false;
1393 container = addListItem(layoutInt, &itemDesc);
1395 if (container == NULL) {
1398 return container->obj.area.height;
1412 return addText(layout, text, subText, 0, 0,
false);
1428 const char *subText,
1433 return addText(layout, text, subText, token, index,
true);
1449 if (layout == NULL) {
1454 textArea->textColor =
BLACK;
1455 textArea->text = PIC(text);
1456 textArea->textAlignment =
MID_LEFT;
1457 textArea->fontId = SMALL_REGULAR_FONT;
1459 textArea->wrapping =
true;
1461 textArea->obj.alignmentMarginX = BORDER_MARGIN;
1464 textArea->fontId, textArea->text, textArea->obj.area.width, textArea->wrapping);
1465 textArea->obj.area.height += SUB_HEADER_MARGIN;
1470 return textArea->obj.area.height;
1487 if (layout == NULL) {
1493 textArea->text = PIC(text);
1494 textArea->textAlignment =
MID_LEFT;
1495 textArea->fontId = LARGE_MEDIUM_FONT;
1497 textArea->wrapping =
true;
1499 textArea->fontId, textArea->text, textArea->obj.area.width, textArea->wrapping);
1502 textArea->obj.alignmentMarginX = BORDER_MARGIN;
1503 if (layoutInt->
container->nbChildren == 0) {
1505 textArea->obj.alignmentMarginY += PRE_FIRST_TEXT_MARGIN;
1508 textArea->obj.alignmentMarginY = INTER_PARAGRAPHS_MARGIN;
1531 const char *description,
1538 if (layout == NULL) {
1544 textArea->textColor =
BLACK;
1545 textArea->text = PIC(title);
1546 textArea->textAlignment =
MID_LEFT;
1547 textArea->fontId = LARGE_MEDIUM_FONT;
1549 textArea->wrapping =
true;
1551 textArea->obj.alignmentMarginX = BORDER_MARGIN;
1552 textArea->obj.alignmentMarginY = PRE_TITLE_MARGIN;
1555 textArea->fontId, textArea->text, textArea->obj.area.width, textArea->wrapping);
1561 textArea->textColor =
BLACK;
1562 textArea->text = PIC(description);
1563 textArea->fontId = SMALL_REGULAR_FONT;
1565 textArea->wrapping =
true;
1568 textArea->fontId, textArea->text, textArea->obj.area.width, textArea->wrapping);
1569 textArea->textAlignment =
MID_LEFT;
1571 textArea->obj.alignmentMarginX = BORDER_MARGIN;
1572 textArea->obj.alignmentMarginY = PRE_DESCRIPTION_MARGIN;
1579 textArea->text = PIC(info);
1580 textArea->fontId = SMALL_REGULAR_FONT;
1582 textArea->wrapping =
true;
1585 textArea->fontId, textArea->text, textArea->obj.area.width, textArea->wrapping);
1586 textArea->textAlignment =
MID_LEFT;
1588 textArea->obj.alignmentMarginX = BORDER_MARGIN;
1589 textArea->obj.alignmentMarginY = 40;
1593 return layoutInt->
container->obj.area.height;
1610 if (layout == NULL) {
1613 for (i = 0; i < choices->
nbChoices; i++) {
1624 layoutInt, (
nbgl_obj_t *) container, choices->
token, choices->tuneId);
1630 container->nbChildren = 2;
1633 container->obj.area.height = RADIO_CHOICE_HEIGHT;
1635 container->obj.alignmentMarginX = BORDER_MARGIN;
1636 container->obj.alignTo = (
nbgl_obj_t *) NULL;
1639 button->activeColor =
BLACK;
1641 button->obj.alignTo = (
nbgl_obj_t *) container;
1644 container->children[1] = (
nbgl_obj_t *) button;
1648#ifdef HAVE_LANGUAGE_PACK
1653 textArea->text = PIC(choices->
names[i]);
1655 textArea->textAlignment =
MID_LEFT;
1656 textArea->obj.area.width = container->obj.area.width - RADIO_WIDTH;
1658 textArea->obj.alignment =
MID_LEFT;
1659 textArea->obj.alignTo = (
nbgl_obj_t *) container;
1660 container->children[0] = (
nbgl_obj_t *) textArea;
1663 container->obj.touchMask = (1 <<
TOUCHED);
1664 container->obj.touchId =
CONTROLS_ID + nbTouchableControls;
1665 nbTouchableControls++;
1670 textArea->textColor =
BLACK;
1671 textArea->fontId = SMALL_BOLD_FONT;
1676 textArea->fontId = SMALL_REGULAR_FONT;
1680 line = createHorizontalLine(layoutInt->
layer);
1681 line->obj.alignmentMarginY = -4;
1707 if (layout == NULL) {
1714 if (info->
text1 != NULL) {
1722 if (info->
text2 != NULL) {
1730 if (info->
text3 != NULL) {
1738 container = addContentCenter(layoutInt, ¢eredInfo);
1741 container->obj.alignmentMarginX = BORDER_MARGIN;
1742 container->obj.alignmentMarginY = BORDER_MARGIN + info->
offsetY;
1746 container->obj.alignmentMarginY = info->
offsetY;
1749 return container->obj.area.height;
1766 if (layout == NULL) {
1770 container = addContentCenter(layoutInt, info);
1772 return container->obj.area.height;
1790 if (layout == NULL) {
1796 container->nbChildren = info->
nbRows + 1;
1800 container->obj.alignmentMarginX = BORDER_MARGIN;
1804 textArea->textColor =
BLACK;
1805 textArea->text = PIC(info->
title);
1806 textArea->textAlignment =
MID_LEFT;
1807 textArea->fontId = LARGE_MEDIUM_FONT;
1808 textArea->wrapping =
true;
1811 textArea->fontId, textArea->text, textArea->obj.area.width, textArea->wrapping);
1813 container->obj.area.height += textArea->obj.area.height;
1815 container->children[0] = (
nbgl_obj_t *) textArea;
1817 for (row = 0; row < info->
nbRows; row++) {
1823 rowContainer->nbChildren = 2;
1828 image->foregroundColor =
BLACK;
1829 image->buffer = info->
rowIcons[row];
1830 rowContainer->children[0] = (
nbgl_obj_t *) image;
1833 textArea->textColor =
BLACK;
1834 textArea->text = info->
rowTexts[row];
1835 textArea->textAlignment =
MID_LEFT;
1836 textArea->fontId = SMALL_REGULAR_FONT;
1837 textArea->wrapping =
true;
1838 textArea->obj.area.width =
AVAILABLE_WIDTH - image->buffer->width - 16;
1840 textArea->fontId, textArea->text, textArea->obj.area.width, textArea->wrapping);
1842 rowContainer->children[1] = (
nbgl_obj_t *) textArea;
1843 rowContainer->obj.area.height
1844 =
MAX(image->buffer->height, textArea->obj.area.height + LEFT_CONTENT_TEXT_PADDING);
1847 rowContainer->obj.alignmentMarginY = 32;
1850 rowContainer->obj.alignmentMarginY = INTER_ROWS_MARGIN;
1852 container->children[1 + row] = (
nbgl_obj_t *) rowContainer;
1853 container->obj.area.height
1854 += rowContainer->obj.area.height + rowContainer->obj.alignmentMarginY;
1858 return container->obj.area.height;
1879 if (layout == NULL) {
1887 container->nbChildren = 0;
1891 if (strlen(PIC(info->
url)) > 62) {
1907 fullHeight +=
qrcode->obj.area.height;
1909 container->nbChildren++;
1911 if (info->
text1 != NULL) {
1913 textArea->textColor =
BLACK;
1914 textArea->text = PIC(info->
text1);
1915 textArea->textAlignment =
CENTER;
1916 textArea->fontId = (info->
largeText1 ==
true) ? LARGE_MEDIUM_FONT : SMALL_REGULAR_FONT;
1917 textArea->wrapping =
true;
1920 textArea->fontId, textArea->text, textArea->obj.area.width, textArea->wrapping);
1922 textArea->obj.alignTo = (
nbgl_obj_t *) container->children[container->nbChildren - 1];
1923 textArea->obj.alignmentMarginY = 24;
1925 fullHeight += textArea->obj.area.height + textArea->obj.alignmentMarginY;
1927 container->children[container->nbChildren] = (
nbgl_obj_t *) textArea;
1928 container->nbChildren++;
1930 if (info->
text2 != NULL) {
1933 textArea->text = PIC(info->
text2);
1934 textArea->textAlignment =
CENTER;
1935 textArea->fontId = SMALL_REGULAR_FONT;
1936 textArea->wrapping =
true;
1939 textArea->fontId, textArea->text, textArea->obj.area.width, textArea->wrapping);
1941 textArea->obj.alignTo = (
nbgl_obj_t *) container->children[container->nbChildren - 1];
1942 if (info->
text1 != NULL) {
1943 textArea->obj.alignmentMarginY = QR_INTER_TEXTS_MARGIN;
1946 textArea->obj.alignmentMarginY = 32;
1950 fullHeight += textArea->obj.area.height + textArea->obj.alignmentMarginY;
1952 container->children[container->nbChildren] = (
nbgl_obj_t *) textArea;
1953 container->nbChildren++;
1956 if ((fullHeight >= (layoutInt->
container->obj.area.height - 16))
1964 container->obj.area.height = fullHeight;
1967 container->obj.alignment =
CENTER;
1971 container->obj.alignTo
1974 container->obj.alignmentMarginY = info->
offsetY;
2020 .horizontalButtons.leftIcon = info->
leftIcon,
2021 .horizontalButtons.leftToken = info->
leftToken,
2022 .horizontalButtons.rightText = info->
rightText,
2023 .horizontalButtons.rightToken = info->
rightToken,
2024 .horizontalButtons.tuneId = info->tuneId};
2046 if (layout == NULL) {
2050 for (i = 0; i < list->
nbPairs; i++) {
2055 if (list->
pairs != NULL) {
2056 pair = &list->
pairs[i];
2073 itemTextArea->text = PIC(pair->
item);
2074 itemTextArea->textAlignment =
MID_LEFT;
2075 itemTextArea->fontId = SMALL_REGULAR_FONT;
2076 itemTextArea->wrapping =
true;
2079 itemTextArea->fontId, itemTextArea->text,
AVAILABLE_WIDTH, itemTextArea->wrapping);
2082 itemTextArea->obj.alignmentMarginX = 0;
2083 itemTextArea->obj.alignmentMarginY = 0;
2084 itemTextArea->obj.alignTo = NULL;
2085 container->children[container->nbChildren] = (
nbgl_obj_t *) itemTextArea;
2086 container->nbChildren++;
2088 fullHeight += itemTextArea->obj.area.height;
2091 valueTextArea->textColor =
BLACK;
2092 valueTextArea->text = PIC(pair->
value);
2093 valueTextArea->textAlignment =
MID_LEFT;
2095 valueTextArea->fontId = SMALL_BOLD_FONT;
2098 valueTextArea->fontId = LARGE_MEDIUM_FONT;
2106 valueIcon = &MINI_PUSH_ICON;
2113 valueTextArea->obj.area.width =
AVAILABLE_WIDTH - valueIcon->width - 12;
2119 valueTextArea->text,
2120 valueTextArea->obj.area.width,
2128 valueTextArea->obj.area.height = nbLines * font->
line_height;
2131 valueTextArea->obj.alignmentMarginY = 4;
2132 valueTextArea->obj.alignTo = (
nbgl_obj_t *) itemTextArea;
2133 valueTextArea->wrapping = list->
wrapping;
2134 container->children[container->nbChildren] = (
nbgl_obj_t *) valueTextArea;
2135 container->nbChildren++;
2137 fullHeight += valueTextArea->obj.area.height + valueTextArea->obj.alignmentMarginY;
2138 if (valueIcon != NULL) {
2143 image->foregroundColor =
BLACK;
2144 image->buffer = valueIcon;
2146 image->obj.alignmentMarginX = 12;
2147 image->obj.alignTo = (
nbgl_obj_t *) valueTextArea;
2148 image->obj.touchMask = (1 <<
TOUCHED);
2151 container->children[container->nbChildren] = (
nbgl_obj_t *) image;
2152 container->nbChildren++;
2156 container->obj.area.height = fullHeight;
2158 container->obj.alignmentMarginX = BORDER_MARGIN;
2160 container->obj.alignmentMarginY = INTER_TAG_VALUE_MARGIN;
2163 container->obj.alignmentMarginY = PRE_TAG_VALUE_MARGIN;
2187 const char *subText,
2196 if (layout == NULL) {
2203 container->nbChildren = (subText != NULL) ? 3 : 2;
2208 container->obj.alignment =
CENTER;
2212 progress->foregroundColor =
BLACK;
2213 progress->withBorder =
true;
2214 progress->state = percentage;
2220 container->children[0] = (
nbgl_obj_t *) progress;
2223 container->obj.area.height = progress->obj.alignmentMarginY + progress->obj.area.height;
2227 textArea->textColor =
BLACK;
2228 textArea->text = PIC(text);
2229 textArea->textAlignment =
CENTER;
2230 textArea->fontId = LARGE_MEDIUM_FONT;
2231 textArea->wrapping =
true;
2232 textArea->obj.alignmentMarginY = BAR_TEXT_MARGIN;
2233 textArea->obj.alignTo = (
nbgl_obj_t *) progress;
2237 textArea->fontId, textArea->text, textArea->obj.area.width, textArea->wrapping);
2241 container->obj.area.height += textArea->obj.alignmentMarginY + textArea->obj.area.height;
2244 container->children[1] = (
nbgl_obj_t *) textArea;
2246 if (subText != NULL) {
2250 subTextArea->textColor =
BLACK;
2251 subTextArea->text = PIC(subText);
2252 subTextArea->textAlignment =
CENTER;
2253 subTextArea->fontId = SMALL_REGULAR_FONT;
2254 subTextArea->wrapping =
true;
2255 subTextArea->obj.alignmentMarginY = BAR_INTER_TEXTS_MARGIN;
2256 subTextArea->obj.alignTo = (
nbgl_obj_t *) textArea;
2261 subTextArea->obj.area.width,
2262 subTextArea->wrapping);
2266 container->obj.area.height
2267 += subTextArea->obj.alignmentMarginY + subTextArea->obj.area.height;
2270 container->children[2] = (
nbgl_obj_t *) subTextArea;
2273 container->obj.area.height = (container->obj.area.height + 7) & 0xFFF8;
2294 const char *subText,
2304 if ((layout == NULL) || (layoutInt->
container->nbChildren == 0)) {
2309 if ((container->obj.type !=
CONTAINER) || (container->nbChildren < 2)) {
2319 if (progress->state != percentage) {
2320 progress->partialRedraw =
true;
2321 progress->state = percentage;
2332 const char *newText = PIC(text);
2333 size_t newTextLen = strlen(newText);
2335 if ((newTextLen != strlen(textArea->text)) || memcmp(textArea->text, newText, newTextLen)) {
2336 textArea->text = newText;
2341 if (subText != NULL) {
2344 if (container->nbChildren != 3) {
2349 if (subTextArea->obj.type !=
TEXT_AREA) {
2352 const char *newSubText = PIC(subText);
2353 size_t newSubTextLen = strlen(newSubText);
2355 if ((newSubTextLen != strlen(subTextArea->text))
2356 || memcmp(subTextArea->text, newSubText, newSubTextLen)) {
2357 subTextArea->text = newSubText;
2378 line = createHorizontalLine(layoutInt->
layer);
2379 line->obj.alignmentMarginY = -4;
2399 if (layout == NULL) {
2411 footerDesc.
button.tuneId = buttonInfo->tuneId;
2421 upFooterDesc.
button.tuneId = buttonInfo->tuneId;
2430 layoutInt, (
nbgl_obj_t *) button, buttonInfo->
token, buttonInfo->tuneId);
2435 button->obj.alignmentMarginX = BORDER_MARGIN;
2436 button->obj.alignmentMarginY = 12;
2439 button->innerColor =
BLACK;
2440 button->foregroundColor =
WHITE;
2443 button->innerColor =
WHITE;
2444 button->foregroundColor =
BLACK;
2447 button->borderColor =
WHITE;
2451 button->borderColor =
BLACK;
2457 button->text = PIC(buttonInfo->
text);
2458 button->fontId = SMALL_BOLD_FONT;
2459 button->icon = PIC(buttonInfo->
icon);
2462 + SMALL_BUTTON_HEIGHT
2463 + ((button->icon) ? (button->icon->width + 12) : 0);
2464 button->obj.area.height = SMALL_BUTTON_HEIGHT;
2465 button->radius = SMALL_BUTTON_RADIUS_INDEX;
2466 if (buttonInfo->
onBottom !=
true) {
2467 button->obj.alignmentMarginX
2468 += (SCREEN_WIDTH - 2 * BORDER_MARGIN - button->obj.area.width) / 2;
2473 button->obj.area.height = BUTTON_DIAMETER;
2474 button->radius = BUTTON_RADIUS;
2476 button->obj.alignTo = NULL;
2477 button->obj.touchMask = (1 <<
TOUCHED);
2497 tune_index_e tuneId)
2500 .longPress.text = text,
2501 .longPress.token = token,
2502 .longPress.tuneId = tuneId};
2505 if (layout == NULL) {
2525 tune_index_e tuneId)
2550 const char *leftText,
2552 const char *rightText,
2554 tune_index_e tuneId)
2585 if (layout == NULL) {
2599 switch (headerDesc->
type) {
2629 button->innerColor =
WHITE;
2631 button->borderColor =
WHITE;
2632 button->obj.area.width = BACK_KEY_WIDTH;
2633 button->obj.area.height = TOUCHABLE_HEADER_BAR_HEIGHT;
2634 button->text = NULL;
2635 button->icon = PIC(&LEFT_ARROW_ICON);
2648 image->foregroundColor =
BLACK;
2649 image->obj.alignment =
CENTER;
2664 textArea->obj.touchMask = (1 <<
TOUCHED);
2666 textArea->obj.alignment =
CENTER;
2667 textArea->textColor =
BLACK;
2668 textArea->obj.area.width
2672 textArea->obj.area.width -= 16 + image->buffer->width;
2674 textArea->obj.area.height = TOUCHABLE_HEADER_BAR_HEIGHT;
2675 textArea->text = text;
2676 textArea->fontId = SMALL_BOLD_FONT;
2677 textArea->textAlignment =
CENTER;
2678 textArea->wrapping =
true;
2683 textArea->obj.area.width,
2687 "nbgl_layoutAddHeader: text [%s] is too long for header\n",
2698 textArea->obj.alignmentMarginX = 8 + image->buffer->width / 2;
2699 image->obj.alignmentMarginX = -8 - textArea->obj.area.width / 2;
2715 button->obj.touchMask = (1 <<
TOUCHED);
2719 button->innerColor =
WHITE;
2720 button->foregroundColor
2723 button->borderColor =
WHITE;
2724 button->obj.area.width = BACK_KEY_WIDTH;
2725 button->obj.area.height = TOUCHABLE_HEADER_BAR_HEIGHT;
2726 button->text = NULL;
2734 layoutInt->
headerContainer->obj.area.height = TOUCHABLE_HEADER_BAR_HEIGHT;
2751 button->innerColor =
WHITE;
2752 button->foregroundColor =
BLACK;
2753 button->borderColor =
WHITE;
2754 button->obj.area.width = BACK_KEY_WIDTH;
2755 button->obj.area.height = TOUCHABLE_HEADER_BAR_HEIGHT;
2756 button->text = NULL;
2757 button->icon = PIC(&LEFT_ARROW_ICON);
2758 button->obj.touchMask = (1 <<
TOUCHED);
2775 progress->obj.area.width = 224;
2776 progress->obj.alignment =
CENTER;
2784 layoutInt->
headerContainer->obj.area.height = TOUCHABLE_HEADER_BAR_HEIGHT;
2790 textArea->textColor =
BLACK;
2792 textArea->obj.area.height = TOUCHABLE_HEADER_BAR_HEIGHT;
2793 textArea->text = PIC(headerDesc->
title.
text);
2794 textArea->fontId = SMALL_BOLD_FONT;
2795 textArea->textAlignment =
CENTER;
2796 textArea->wrapping =
true;
2800 layoutInt->
headerContainer->obj.area.height = textArea->obj.area.height;
2813 textArea->obj.alignmentMarginX = BORDER_MARGIN;
2814 textArea->textColor =
BLACK;
2816 textArea->obj.area.height = TOUCHABLE_HEADER_BAR_HEIGHT;
2818 textArea->fontId = SMALL_BOLD_FONT;
2820 textArea->obj.touchMask = (1 <<
TOUCHED);
2826 layoutInt->
headerContainer->obj.area.height = textArea->obj.area.height;
2834 line = createHorizontalLine(layoutInt->
layer);
2841 if (separationLine != NULL) {
2876 if (layout == NULL) {
2890 switch (footerDesc->
type) {
2908 textArea->obj.area.height
2913 textArea->textAlignment =
CENTER;
2914 textArea->obj.touchMask = (1 <<
TOUCHED);
2919 layoutInt->
footerContainer->obj.area.height = textArea->obj.area.height;
2932 textArea->textColor =
BLACK;
2934 textArea->obj.area.height = SIMPLE_FOOTER_HEIGHT;
2936 textArea->fontId = SMALL_BOLD_FONT;
2937 textArea->textAlignment =
CENTER;
2938 textArea->obj.touchMask = (1 <<
TOUCHED);
2956 textArea->textColor =
BLACK;
2958 textArea->obj.area.height = SIMPLE_FOOTER_HEIGHT;
2960 textArea->fontId = SMALL_BOLD_FONT;
2961 textArea->textAlignment =
CENTER;
2962 textArea->obj.touchMask = (1 <<
TOUCHED);
2968 layoutInt->
footerContainer->obj.area.height = textArea->obj.area.height;
2973 separationLine->obj.area.width = 1;
2974 separationLine->obj.area.height = layoutInt->
footerContainer->obj.area.height;
2975 separationLine->direction =
VERTICAL;
2976 separationLine->thickness = 1;
2977 separationLine->obj.alignment =
MID_LEFT;
2978 separationLine->obj.alignTo = (
nbgl_obj_t *) textArea;
2979 separationLine->obj.alignmentMarginX = -1;
2995 textArea->textColor =
BLACK;
2996 textArea->obj.area.width = FOOTER_TEXT_AND_NAV_WIDTH;
2997 textArea->obj.area.height = SIMPLE_FOOTER_HEIGHT;
2999 textArea->fontId = SMALL_BOLD_FONT;
3000 textArea->textAlignment =
CENTER;
3001 textArea->obj.touchMask = (1 <<
TOUCHED);
3013 navContainer->nbChildren = 4;
3014 navContainer->children
3017 navContainer->obj.area.width = SCREEN_WIDTH - textArea->obj.area.width;
3018 navContainer->obj.area.height = SIMPLE_FOOTER_HEIGHT;
3031 separationLine->obj.area.width = 1;
3032 separationLine->obj.area.height = layoutInt->
footerContainer->obj.area.height;
3033 separationLine->direction =
VERTICAL;
3034 separationLine->thickness = 1;
3035 separationLine->obj.alignment =
MID_LEFT;
3036 separationLine->obj.alignTo = (
nbgl_obj_t *) navContainer;
3037 separationLine->obj.alignmentMarginX = -1;
3070 footerDesc->
button.tuneId);
3075 button->obj.alignment =
CENTER;
3077 button->innerColor =
BLACK;
3078 button->foregroundColor =
WHITE;
3081 button->innerColor =
WHITE;
3082 button->foregroundColor =
BLACK;
3086 button->borderColor =
WHITE;
3090 button->borderColor =
BLACK;
3097 button->fontId = SMALL_BOLD_FONT;
3099 button->radius = BUTTON_RADIUS;
3100 button->obj.area.height = BUTTON_DIAMETER;
3103 button->obj.area.width = BUTTON_DIAMETER;
3108 button->obj.touchMask = (1 <<
TOUCHED);
3136 button->innerColor =
WHITE;
3138 button->obj.alignmentMarginY
3139 = BOTTOM_BORDER_MARGIN;
3143 button->obj.alignmentMarginY = 4;
3144 button->borderColor =
WHITE;
3146 button->foregroundColor =
BLACK;
3148 button->obj.area.height = BUTTON_DIAMETER;
3149 button->radius = BUTTON_RADIUS;
3151 button->fontId = SMALL_BOLD_FONT;
3152 button->obj.touchMask = (1 <<
TOUCHED);
3162 line = createHorizontalLine(layoutInt->
layer);
3164 line->obj.alignmentMarginY = 4;
3183 button->obj.alignmentMarginY = BOTTOM_BORDER_MARGIN;
3185 button->innerColor =
WHITE;
3187 button->foregroundColor =
BLACK;
3190 button->innerColor =
BLACK;
3191 button->borderColor =
BLACK;
3192 button->foregroundColor =
WHITE;
3195 button->obj.area.height = BUTTON_DIAMETER;
3196 button->radius = BUTTON_RADIUS;
3201 button->fontId = SMALL_BOLD_FONT;
3202 button->obj.touchMask = (1 <<
TOUCHED);
3210 layoutInt->
footerContainer->obj.area.height = ACTION_AND_FOOTER_FOOTER_HEIGHT;
3213 layoutInt->
footerContainer->obj.area.height = ROUNDED_AND_FOOTER_FOOTER_HEIGHT;
3224 addSwipeInternal(layoutInt,
3235 line = createHorizontalLine(layoutInt->
layer);
3241 if (separationLine != NULL) {
3274 if (layout == NULL) {
3291 switch (upFooterDesc->
type) {
3310 button->obj.alignmentMarginX = BORDER_MARGIN;
3312 button->innerColor =
BLACK;
3313 button->foregroundColor =
WHITE;
3314 button->borderColor =
BLACK;
3315 button->obj.area.width = BUTTON_DIAMETER;
3316 button->obj.area.height = BUTTON_DIAMETER;
3317 button->radius = BUTTON_RADIUS;
3318 button->icon = PIC(&VALIDATE_ICON);
3322 textArea->textColor =
BLACK;
3324 textArea->textAlignment =
MID_LEFT;
3325 textArea->fontId = LARGE_MEDIUM_FONT;
3326 textArea->wrapping =
true;
3327 textArea->obj.area.width = SCREEN_WIDTH - 3 * BORDER_MARGIN - button->obj.area.width;
3329 textArea->fontId, textArea->text, textArea->obj.area.width, textArea->wrapping);
3331 textArea->obj.alignment =
MID_LEFT;
3332 textArea->obj.alignmentMarginX = BORDER_MARGIN;
3335 line = createHorizontalLine(layoutInt->
layer);
3341 progressBar->withBorder =
false;
3342 progressBar->obj.area.width = SCREEN_WIDTH;
3343 progressBar->obj.area.height = 8;
3345 progressBar->obj.alignmentMarginY = 4;
3346 progressBar->obj.alignTo = NULL;
3355 upFooterDesc->
button.tuneId);
3362 button->obj.alignment =
CENTER;
3365 button->innerColor =
BLACK;
3366 button->foregroundColor =
WHITE;
3369 button->innerColor =
WHITE;
3370 button->foregroundColor =
BLACK;
3373 button->borderColor =
WHITE;
3377 button->borderColor =
BLACK;
3383 button->text = PIC(upFooterDesc->
button.
text);
3384 button->fontId = SMALL_BOLD_FONT;
3385 button->icon = PIC(upFooterDesc->
button.
icon);
3387 button->obj.area.height = BUTTON_DIAMETER;
3388 button->radius = BUTTON_RADIUS;
3390 button->obj.alignTo = NULL;
3391 button->obj.touchMask = (1 <<
TOUCHED);
3418 button->obj.alignmentMarginX = BORDER_MARGIN;
3420 button->innerColor =
WHITE;
3421 button->foregroundColor =
BLACK;
3422 button->obj.area.width = BUTTON_DIAMETER;
3423 button->obj.area.height = BUTTON_DIAMETER;
3424 button->radius = BUTTON_RADIUS;
3426 button->fontId = SMALL_BOLD_FONT;
3427 button->obj.touchMask = (1 <<
TOUCHED);
3443 button->obj.alignmentMarginX = BORDER_MARGIN;
3444 button->innerColor =
BLACK;
3445 button->borderColor =
BLACK;
3446 button->foregroundColor =
WHITE;
3448 button->obj.area.height = BUTTON_DIAMETER;
3449 button->radius = BUTTON_RADIUS;
3451 button->fontId = SMALL_BOLD_FONT;
3452 button->obj.touchMask = (1 <<
TOUCHED);
3465 upFooterDesc->
tipBox.tuneId);
3474 textArea->textColor =
BLACK;
3475 textArea->text = PIC(upFooterDesc->
tipBox.
text);
3476 textArea->textAlignment =
MID_LEFT;
3477 textArea->fontId = SMALL_REGULAR_FONT;
3478 textArea->wrapping =
true;
3481 textArea->obj.area.width
3486 textArea->fontId, textArea->text, textArea->obj.area.width, textArea->wrapping);
3487 textArea->obj.alignment =
MID_LEFT;
3488 textArea->obj.alignmentMarginX = BORDER_MARGIN;
3492 line = createHorizontalLine(layoutInt->
layer);
3499 image->obj.alignmentMarginX = BORDER_MARGIN;
3501 image->foregroundColor =
BLACK;
3502 image->buffer = PIC(upFooterDesc->
tipBox.
icon);
3515 upFooterDesc->
text.token,
3516 upFooterDesc->
text.tuneId);
3527 textArea->text = PIC(upFooterDesc->
text.text);
3528 textArea->textAlignment =
CENTER;
3529 textArea->fontId = SMALL_REGULAR_FONT;
3530 textArea->wrapping =
true;
3533 textArea->fontId, textArea->text, textArea->obj.area.width, textArea->wrapping);
3534 textArea->obj.alignment =
CENTER;
3570 tune_index_e tuneId)
3573 .separationLine =
false,
3574 .progressAndBack.activePage = activePage,
3575 .progressAndBack.nbPages = nbPages,
3576 .progressAndBack.token = backToken,
3577 .progressAndBack.tuneId = tuneId,
3578 .progressAndBack.withBack = withBack,
3579 .progressAndBack.actionIcon = NULL,
3598 const char *subText,
3607 if (layout == NULL) {
3613 container->nbChildren = 3;
3618 container->obj.alignment =
CENTER;
3622 spinner->position = initPosition;
3625 container->children[0] = (
nbgl_obj_t *) spinner;
3628 container->obj.area.height += SPINNER_HEIGHT;
3632 textArea->textColor =
BLACK;
3633 textArea->text = PIC(text);
3634 textArea->textAlignment =
CENTER;
3635 textArea->fontId = (subText != NULL) ? LARGE_MEDIUM_FONT : SMALL_REGULAR_FONT;
3636 textArea->wrapping =
true;
3637 textArea->obj.alignmentMarginY = SPINNER_TEXT_MARGIN;
3638 textArea->obj.alignTo = (
nbgl_obj_t *) spinner;
3642 textArea->fontId, textArea->text, textArea->obj.area.width, textArea->wrapping);
3646 container->obj.area.height += textArea->obj.alignmentMarginY + textArea->obj.area.height;
3649 container->children[1] = (
nbgl_obj_t *) textArea;
3651 if (subText != NULL) {
3655 subTextArea->textColor =
BLACK;
3656 subTextArea->text = PIC(subText);
3657 subTextArea->textAlignment =
CENTER;
3658 subTextArea->fontId = SMALL_REGULAR_FONT;
3659 subTextArea->wrapping =
true;
3660 subTextArea->obj.alignmentMarginY = SPINNER_INTER_TEXTS_MARGIN;
3661 subTextArea->obj.alignTo = (
nbgl_obj_t *) textArea;
3666 subTextArea->obj.area.width,
3667 subTextArea->wrapping);
3671 container->obj.area.height
3672 += subTextArea->obj.alignmentMarginY + subTextArea->obj.area.height;
3675 container->children[2] = (
nbgl_obj_t *) subTextArea;
3685 tickerCfg.tickerCallback = &spinnerTickerCallback;
3705 const char *subText,
3715 if ((layout == NULL) || (layoutInt->
container->nbChildren == 0)) {
3720 if ((container->obj.type !=
CONTAINER) || (container->nbChildren < 2)) {
3725 if (spinner->obj.type !=
SPINNER) {
3729 if (spinner->position != position) {
3730 spinner->position = position;
3740 const char *newText = PIC(text);
3741 size_t newTextLen = strlen(newText);
3743 if ((newTextLen != strlen(textArea->text)) || memcmp(textArea->text, newText, newTextLen)) {
3744 textArea->text = newText;
3749 if (subText != NULL) {
3752 if (container->nbChildren != 3) {
3756 if (subTextArea->obj.type !=
TEXT_AREA) {
3759 const char *newSubText = PIC(subText);
3760 size_t newSubTextLen = strlen(newSubText);
3762 if ((newSubTextLen != strlen(subTextArea->text))
3763 || memcmp(subTextArea->text, newSubText, newSubTextLen)) {
3764 subTextArea->text = newSubText;
3783 if (layout == NULL) {
3787 "nbgl_layoutDraw(): container.nbChildren =%d, layout->nbChildren = %d\n",
3814 if (layout == NULL) {
3818 if (layout->
modal) {
Random Number Generation.
@ ANIM_ILLUSTRATION
animation
@ ICON_ILLUSTRATION
simple icon
#define LOG_WARN(__logger,...)
#define LOG_DEBUG(__logger,...)
#define LOG_FATAL(__logger,...)
Middle Level API of the new BOLOS Graphical Library.
#define QR_V10_NB_PIX_SIZE
#define QR_V4_NB_PIX_SIZE
uint8_t nbgl_getFontHeight(nbgl_font_id_e fontId)
return the height in pixels of the font with the given font ID
uint16_t nbgl_getTextWidth(nbgl_font_id_e fontId, const char *text)
return the max width in pixels of the given text (can be multiline)
uint16_t nbgl_getTextHeightInWidth(nbgl_font_id_e fontId, const char *text, uint16_t maxWidth, bool wrapping)
return the height of the given multiline text, with the given font.
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
const nbgl_font_t * nbgl_getFont(nbgl_font_id_e fontId)
uint8_t nbgl_getFontLineHeight(nbgl_font_id_e fontId)
return the height in pixels of the line of font with the given font ID
Font screen low-Level driver API, to draw elementary forms.
int nbgl_layoutAddTagValueList(nbgl_layout_t *layout, const nbgl_layoutTagValueList_t *list)
Creates a list of [tag,value] pairs.
int nbgl_layoutAddContentCenter(nbgl_layout_t *layout, const nbgl_contentCenter_t *info)
Creates an area on the center of the main panel, with a possible icon, and possible texts under it.
#define HOLD_TO_APPROVE_STEP_PERCENT
int nbgl_layoutAddUpFooter(nbgl_layout_t *layout, const nbgl_layoutUpFooter_t *upFooterDesc)
Creates a touchable area on top of the footer of the screen, containing various controls,...
int nbgl_layoutDraw(nbgl_layout_t *layoutParam)
Applies given layout. The screen will be redrawn.
#define PROGRESSBAR_HEIGHT
#define NB_MAX_CONTAINER_CHILDREN
int nbgl_layoutAddTextContent(nbgl_layout_t *layout, const char *title, const char *description, const char *info)
Creates in the main container three text areas:
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)
int nbgl_layoutUpdateProgressBar(nbgl_layout_t *layout, const char *text, const char *subText, uint8_t percentage)
Update an existing progress Bar (must be the only object of the layout)
int nbgl_layoutAddProgressIndicator(nbgl_layout_t *layout, uint8_t activePage, uint8_t nbPages, bool withBack, uint8_t backToken, tune_index_e tuneId)
Creates a kind of navigation bar with an optional <- arrow on the left. This widget is placed on top ...
int nbgl_layoutAddNavigationBar(nbgl_layout_t *layout, const nbgl_layoutNavigationBar_t *info)
Creates a navigation bar on bottom of main container.
int nbgl_layoutAddSeparationLine(nbgl_layout_t *layout)
adds a separation line on bottom of the last added item
int nbgl_layoutAddQRCode(nbgl_layout_t *layout, const nbgl_layoutQRCode_t *info)
Creates an area on the center of the main panel, with a QRCode, a possible text in black (bold) under...
int nbgl_layoutAddRadioChoice(nbgl_layout_t *layout, const nbgl_layoutRadioChoice_t *choices)
Creates a list of radio buttons (on the right)
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_layoutAddSplitFooter(nbgl_layout_t *layout, const char *leftText, uint8_t leftToken, const char *rightText, uint8_t rightToken, tune_index_e tuneId)
Creates 2 touchable texts at the footer of the screen, separated with a thin line from the rest of th...
int nbgl_layoutAddSubHeaderText(nbgl_layout_t *layout, const char *text)
Creates an area with given text in small regular font, under the header.
int nbgl_layoutAddTextWithAlias(nbgl_layout_t *layout, const char *text, const char *subText, uint8_t token, uint8_t index)
Creates an area with given text (in bold) and sub text (in regular), with a icon on right of text to...
int nbgl_layoutAddTouchableBar(nbgl_layout_t *layout, const nbgl_layoutBar_t *barLayout)
Creates a touchable bar in main panel.
#define SPINNER_REFRESH_PERIOD
int nbgl_layoutAddTopRightButton(nbgl_layout_t *layout, const nbgl_icon_details_t *icon, uint8_t token, tune_index_e tuneId)
Creates a Top-right button in the top right corner of the top panel.
int nbgl_layoutAddSwipe(nbgl_layout_t *layout, uint16_t swipesMask, const char *text, uint8_t token, tune_index_e tuneId)
Creates a swipe interaction on the main container.
int nbgl_layoutAddSwitch(nbgl_layout_t *layout, const nbgl_layoutSwitch_t *switchLayout)
Creates a switch with the given text and its state.
int nbgl_layoutAddHorizontalButtons(nbgl_layout_t *layout, const nbgl_layoutHorizontalButtons_t *info)
Creates two buttons to make a choice. Both buttons are mandatory The left one contains only an icon a...
int nbgl_layoutAddButton(nbgl_layout_t *layout, const nbgl_layoutButton_t *buttonInfo)
Creates a rounded button in the main container.
nbgl_layout_t * nbgl_layoutGet(const nbgl_layoutDescription_t *description)
returns a layout of the given type. The layout is reset
int nbgl_layoutAddExtendedFooter(nbgl_layout_t *layout, const nbgl_layoutFooter_t *footerDesc)
Creates a touchable area at the footer of the screen, containing various controls,...
int nbgl_layoutAddLeftContent(nbgl_layout_t *layout, const nbgl_layoutLeftContent_t *info)
Creates an area with a title, and rows of icon + text, left aligned.
const char * get_ux_loc_string(uint32_t index)
int nbgl_layoutAddChoiceButtons(nbgl_layout_t *layout, const nbgl_layoutChoiceButtons_t *info)
Creates two buttons to make a choice. Both buttons are mandatory. Both buttons are full width,...
int nbgl_layoutRelease(nbgl_layout_t *layoutParam)
Release the layout obtained with nbgl_layoutGet()
int nbgl_layoutAddSpinner(nbgl_layout_t *layout, const char *text, const char *subText, uint8_t initPosition)
Creates a centered (vertically & horizontally) spinner with a text under it.
int nbgl_layoutUpdateSpinner(nbgl_layout_t *layout, const char *text, const char *subText, uint8_t position)
Update an existing spinner (must be the only object of the layout)
int nbgl_layoutAddLongPressButton(nbgl_layout_t *layout, const char *text, uint8_t token, tune_index_e tuneId)
Creates a long press button in the main container.
void layoutAddObject(nbgl_layoutInternal_t *layout, nbgl_obj_t *obj)
adds the given obj to the main container
int nbgl_layoutAddProgressBar(nbgl_layout_t *layout, const char *text, const char *subText, uint8_t percentage)
Creates an area in main panel to display a progress bar, with a title text and a subtext if needed.
int nbgl_layoutAddHeader(nbgl_layout_t *layout, const nbgl_layoutHeader_t *headerDesc)
Creates a touchable (or not) area at the header of the screen, containing various controls,...
#define PROGRESSBAR_WIDTH
int nbgl_layoutAddBottomButton(nbgl_layout_t *layout, const nbgl_icon_details_t *icon, uint8_t token, bool separationLine, tune_index_e tuneId)
Creates a centered button at bottom of main container.
#define HOLD_TO_APPROVE_STEP_DURATION_MS
int nbgl_layoutAddFooter(nbgl_layout_t *layout, const char *text, uint8_t token, tune_index_e tuneId)
Creates a touchable text at the footer of the screen, separated with a thin line from the rest of the...
int nbgl_layoutAddLargeCaseText(nbgl_layout_t *layout, const char *text, bool grayedOut)
Creates an area with given text in 32px font (in Black or Light Gray)
layoutObj_t * layoutAddCallbackObj(nbgl_layoutInternal_t *layout, nbgl_obj_t *obj, uint8_t token, tune_index_e tuneId)
void(* nbgl_layoutTouchCallback_t)(int token, uint8_t index)
prototype of function to be called when an object is touched
@ WHITE_BACKGROUND
rounded bordered button, with text/icon in black, on white background
@ NO_BORDER
simple clickable text, in black
@ BLACK_BACKGROUND
rounded bordered button, with text/icon in white, on black background
@ UP_FOOTER_TEXT
grayed-out text, for example "Tap to continue"
@ UP_FOOTER_BUTTON
simple button
@ UP_FOOTER_LONG_PRESS
long-press button
@ UP_FOOTER_TIP_BOX
Tip-box.
@ UP_FOOTER_HORIZONTAL_BUTTONS
2 buttons, on the same line
void * nbgl_layout_t
type shared externally
@ HEADER_TITLE
simple centered text
@ HEADER_BACK_AND_PROGRESS
optional back key and progress indicator (only on Stax)
@ HEADER_EMPTY
empty space, to have a better vertical centering of centered info
@ HEADER_EXTENDED_BACK
back key, centered text and touchable key on the right
@ HEADER_BACK_AND_TEXT
back key and optional text
@ HEADER_RIGHT_TEXT
touchable text on the right, with a vertical separation line
@ HEADER_BACK_ICON_AND_TEXT
back key and optional icon and text
#define NBGL_INVALID_TOKEN
#define SPINNER_FIXED
position to use for a "fixed" spinner
@ SOFT_ACTION_AND_FOOTER_STYLE
A white button on top of a footer, with a separation line.
@ BOTH_ROUNDED_STYLE
A black button on top of a white button.
@ ROUNDED_AND_FOOTER_STYLE
A black background button on top of a footer.
#define NBGL_NO_PROGRESS_INDICATOR
To be used when a control token shall not be used.
@ FOOTER_SIMPLE_TEXT
simple touchable text in bold
@ FOOTER_NAV
navigation bar
@ FOOTER_SIMPLE_BUTTON
simple black or white button (see nbgl_layoutButtonStyle_t)
@ FOOTER_DOUBLE_TEXT
2 touchable texts in bold, separated by a vertical line (only on Stax)
@ FOOTER_EMPTY
empty space, to have a better vertical centering of centered info
@ FOOTER_CHOICE_BUTTONS
double buttons (see nbgl_layoutChoiceButtonsStyle_t)
Internal functions/constants of NBGL layout layer.
@ SWIPE_USAGE_SUGGESTIONS
bool keyboardSwipeCallback(nbgl_obj_t *obj, nbgl_touchType_t eventType)
void layoutNavigationPopulate(nbgl_container_t *navContainer, const nbgl_layoutNavigationBar_t *navConfig, uint8_t layer)
This function creates a full navigation bar "object", with buttons and returns it as a container.
#define LAYOUT_OBJ_POOL_LEN
Max number of complex objects with callback retrievable from pool.
bool layoutNavigationCallback(nbgl_obj_t *obj, nbgl_touchType_t eventType, uint8_t nbPages, uint8_t *activePage)
function to be called when any of the controls in navigation bar is touched
API to draw all basic graphic objects.
struct PACKED__ nbgl_line_s nbgl_line_t
struct to represent a vertical or horizontal line
struct PACKED__ nbgl_navigation_bar_s nbgl_page_indicator_t
struct to represent a navigation bar (PAGE_INDICATOR type) There can be up to 5 page indicators,...
struct PACKED__ nbgl_radio_s nbgl_radio_t
struct to represent a radio button (RADIO_BUTTON type)
#define NB_SPINNER_POSITIONS
void(* nbgl_touchCallback_t)(void *obj, nbgl_touchType_t eventType)
prototype of function to be called when a touch event is received by an object
struct PACKED__ nbgl_text_area_s nbgl_text_area_t
struct to represent a text area (TEXT_AREA type)
void nbgl_objDraw(nbgl_obj_t *obj)
This function draws or redraws the given object and its children (recursive version)
struct PACKED__ nbgl_progress_bar_s nbgl_progress_bar_t
struct to represent a progress bar (PROGRESS_BAR type)
nbgl_obj_t ** nbgl_containerPoolGet(uint8_t nbObjs, uint8_t layer)
Gets a new container from the pool, with the given number of obj pointers.
nbgl_obj_t * nbgl_objPoolGet(nbgl_obj_type_t type, uint8_t layer)
Gets a new graphic object from the pool, with the given type. The type field of the object is set.
void nbgl_refreshSpecial(nbgl_refresh_mode_t mode)
This functions refreshes the actual screen on display with what has changed since the last refresh,...
struct PACKED__ nbgl_image_s nbgl_image_t
struct to represent an image (IMAGE type)
struct PACKED__ nbgl_button_s nbgl_button_t
struct to represent a button (BUTTON type) that can contain a text and/or an icon
void nbgl_refreshSpecialWithPostRefresh(nbgl_refresh_mode_t mode, nbgl_post_refresh_t post_refresh)
struct PACKED__ nbgl_container_s nbgl_container_t
struct to represent a container (CONTAINER type)
struct PACKED__ nbgl_switch_s nbgl_switch_t
struct to represent a switch (size is fixed) (SWITCH type)
struct PACKED__ nbgl_obj_s nbgl_obj_t
Common structure for all graphical objects.
struct PACKED__ nbgl_spinner_s nbgl_spinner_t
struct to represent a "spinner", represented by the Ledger corners, in gray, with one of the corners ...
struct PACKED__ nbgl_qrcode_s nbgl_qrcode_t
struct to represent a QR code (QR_CODE type), whose size is fixed
int nbgl_screenSet(nbgl_obj_t ***elements, uint8_t nbElements, const nbgl_screenTickerConfiguration_t *ticker, nbgl_touchCallback_t touchCallback)
Configures the lowest layer screen. To be used by applications A nbgl_screenRedraw() can be called af...
int nbgl_screenPush(nbgl_obj_t ***elements, uint8_t nbElements, const nbgl_screenTickerConfiguration_t *ticker, nbgl_touchCallback_t touchCallback)
Pushes a screen on top of the stack, with the given number of elements, if possible....
void nbgl_wait_pipeline(void)
int nbgl_screenUpdateTicker(uint8_t screenIndex, const nbgl_screenTickerConfiguration_t *ticker)
Updates the ticker configuration of the screen at the given screenIndex, always set at WHITE in.
int nbgl_screenPop(uint8_t screenIndex)
Release the screen at the given index in screen array (index returned by nbgl_screenPush())....
struct PACKED__ nbgl_screenTickerConfiguration_s nbgl_screenTickerConfiguration_t
struct to configure a screen layer
void nbgl_screenRedraw(void)
This function redraws the whole screen on top of stack and its children.
uint32_t nbgl_touchGetTouchDuration(nbgl_obj_t *obj)
nbgl_state_t
to represent a boolean state.
@ POST_REFRESH_FORCE_POWER_OFF
Force screen power off after refresh.
@ POST_REFRESH_FORCE_POWER_ON
Force screen power on after refresh.
@ POST_REFRESH_FORCE_POWER_ON_WITH_PIPELINE
Force screen power on and enable pipeline.
nbgl_touchType_t
The different types of Touchscreen events.
@ TOUCHING
corresponding to an object that is currently touched
@ QRCODE_V10
QRCode V10, can encode text len up to 1500 chars, display size = 228*228.
@ QRCODE_V4_SMALL
QRCode V4, can encode text len up to 1500 chars, display size = 132*132.
@ QRCODE_V4
QRCode V4, can encode text len up to 62 chars, display size = 264*264.
@ VERTICAL
from top to bottom
@ HORIZONTAL
from left to right
@ LOOP_PARSING
0, 1, 2, 0, 1, 2, ...
struct PACKED__ nbgl_icon_details_s nbgl_icon_details_t
Represents all information about an icon.
@ NO_ALIGNMENT
used when parent container layout is used
@ RIGHT_TOP
on outside right
@ IMAGE
Bitmap (y and height must be multiple of 4 on Stax)
@ SWITCH
Switch to turn on/off something.
@ RADIO_BUTTON
Indicator to inform whether something is on or off.
@ BUTTON
Rounded rectangle button with icon and/or text.
@ PROGRESS_BAR
horizontal bar to indicate progression of something (between 0% and 100%)
@ PAGE_INDICATOR
horizontal bar to indicate position within pages
@ LINE
Vertical or Horizontal line.
@ CONTAINER
Empty container.
@ TEXT_AREA
Area to contain text line(s)
@ NBGL_BPP_1
1 bit per pixel
@ BLACK_AND_WHITE_REFRESH
to be used for pure B&W area, when contrast is important
@ BLACK_AND_WHITE_FAST_REFRESH
to be used for pure B&W area, when contrast is not priority
@ FULL_COLOR_PARTIAL_REFRESH
to be used for small partial refresh (radio buttons, switches)
const nbgl_icon_details_t * iconRight
const nbgl_icon_details_t * iconLeft
uint16_t delayMs
delay between 2 drawings
uint8_t nbIcons
number of icons in icons array
const nbgl_icon_details_t ** icons
array of nbIcons pointers on icons
nbgl_parsingType_t parsing
This structure contains info to build a centered (vertically and horizontally) area,...
uint16_t iconHug
vertical margin to apply on top and bottom of the icon
const nbgl_icon_details_t * icon
the icon (can be null)
const char * title
title in black large (can be null)
const char * description
description in black small regular case (can be null)
const char * subText
sub-text in dark gray regular small case
uint16_t animOffsetY
vertical offset of animation in icon if integrated (but usually 0)
bool padding
if true, apply a padding of 40px at the bottom
const nbgl_animation_t * animation
the animation (can be null), used if illustrType is ANIM_ILLUSTRATION
const char * smallTitle
sub-title in black small bold case (can be null)
uint16_t animOffsetX
horizontal offset of animation in icon if integrated (but usually 0)
nbgl_contentIllustrationType_t illustrType
This structure contains info to build a centered (vertically and horizontally) area,...
const char * text2
second text (can be null)
const char * text1
first text (can be null)
bool onTop
if set to true, align only horizontally
nbgl_contentCenteredInfoStyle_t style
style to apply to this info
int16_t offsetY
vertical shift to apply to this info (if >0, shift to bottom)
const char * text3
third text (can be null)
const nbgl_icon_details_t * icon
a buffer containing the 1BPP icon
This structure contains a list of names to build a list of radio buttons (on the right part of screen...
uint8_t token
the token that will be used as argument of the callback
bool localized
if set to true, use nameIds and not names
uint8_t initChoice
index of the current choice
const char *const * names
array of strings giving the choices (nbChoices)
uint8_t nbChoices
number of choices
This structure contains info to build a switch (on the right) with a description (on the left),...
const char * text
main text for the switch
uint8_t token
the token that will be used as argument of the callback (unused on Nano)
nbgl_state_t initState
initial state of the switch
const char * subText
description under main text (NULL terminated, single line, may be null)
This structure contains a list of [tag,value] pairs.
const nbgl_contentTagValue_t * pairs
array of [tag,value] pairs (nbPairs items). If NULL, callback is used instead
bool wrapping
if set to true, value text will be wrapped on ' ' to avoid cutting words
uint8_t startIndex
index of the first pair to get with callback
nbgl_contentTagValueCallback_t callback
function to call to retrieve a given pair
uint8_t nbMaxLinesForValue
This structure contains a [tag,value] pair and possible extensions.
const nbgl_icon_details_t * valueIcon
const char * value
string giving the value name
const char * item
string giving the tag name
const char * text
text of the tip-box
const nbgl_icon_details_t * icon
icon of the tip-box
uint8_t token
token used when tip-box is tapped
structure defining an ASCII font
uint8_t line_height
height of a line for all characters in pixels
This structure contains info to build a clickable "bar" with a text and an icon.
bool inactive
if set to true, the bar is grayed-out and cannot be touched
const char * text
text (can be NULL)
uint8_t token
the token that will be used as argument of the callback
bool large
set to true only for the main level of OS settings
const char * subText
sub text (can be NULL)
const nbgl_icon_details_t * iconLeft
a buffer containing the 1BPP icon for icon on left (can be NULL)
const nbgl_icon_details_t * iconRight
Structure containing all information when creating a layout. This structure must be passed as argumen...
nbgl_screenTickerConfiguration_t ticker
const char * tapActionText
Light gray text used when main container is "tapable".
nbgl_layoutTouchCallback_t onActionCallback
the callback to be called on any action on the layout
Structure containing all information about the current layout.
uint8_t nbUsedCallbackObjs
nbgl_container_t * footerContainer
container used to store footer (buttons, nav....)
bool incrementAnim
if true, means that animation index is currently incrementing
uint8_t activePage
index of active page for navigation bar
nbgl_swipe_usage_t swipeUsage
nbgl_layoutTouchCallback_t callback
nbgl_container_t * container
uint8_t iconIdxInAnim
current icon index in animation
nbgl_container_t * headerContainer
container used to store header (progress, back, empty space...)
nbgl_layoutFooterType_t footerType
type of footer
bool modal
if true, means the screen is a modal
uint8_t nbChildren
number of children in above array
nbgl_layoutHeaderType_t headerType
type of header
nbgl_container_t * upFooterContainer
uint8_t nbPages
number of pages for navigation bar
nbgl_layoutUpFooterType_t upFooterType
type of up-footer
layoutObj_t callbackObjPool[LAYOUT_OBJ_POOL_LEN]
nbgl_text_area_t * tapText
nbgl_obj_t ** children
children for main screen
const nbgl_animation_t * animation
current animation (if not NULL)
This structure contains info to build a left content area.
uint8_t nbRows
number of rows in the area
const char * title
title of area in bold
const nbgl_icon_details_t ** rowIcons
array of nbRows icon
const char ** rowTexts
array of nbRows texts (displayed in regular)
This structure contains info to build a navigation bar at the bottom of the screen.
uint8_t activePage
index of active page (from 0 to nbPages-1).
bool withBackKey
if set to true, the "back" key is drawn
bool withExitKey
if set to true, an exit button is drawn (X on the left)
uint8_t token
the token that will be used as argument of the callback
uint8_t nbPages
number of pages. (if 0, no navigation)
This structure contains info to build a centered (vertically and horizontally) area,...
const char * text2
second text (can be null)
const char * text1
first text (can be null)
const char * url
URL for QR code.
bool largeText1
if set to true, use 32px font for text1
int16_t offsetY
vertical shift to apply to this info (if > 0, shift to bottom)
bool centered
if set to true, center vertically