Embedded SDK
Embedded SDK
Loading...
Searching...
No Matches
nbgl_layout_nanos.c
Go to the documentation of this file.
1
6#ifndef HAVE_SE_TOUCH
7/*********************
8 * INCLUDES
9 *********************/
10#include <string.h>
11#include <stdlib.h>
12#include "nbgl_debug.h"
13#include "nbgl_front.h"
15#include "nbgl_obj.h"
16#include "nbgl_draw.h"
17#include "nbgl_screen.h"
18#include "nbgl_touch.h"
19#include "glyphs.h"
20#include "os_pic.h"
21#include "os_helpers.h"
22#include "lcx_rng.h"
23
24/*********************
25 * DEFINES
26 *********************/
27
28#define NB_MAX_LAYOUTS 3
29
30// used by screen
31#define NB_MAX_SCREEN_CHILDREN 7
32
33#define BUTTON_MARGIN_Y 12
34
35// this is the maximum number of chars fitting in a line
36#define NB_MAX_CHAR_IN_LINE 20
37
38/**********************
39 * MACROS
40 **********************/
41
42/**********************
43 * TYPEDEFS
44 **********************/
45
46/**********************
47 * VARIABLES
48 **********************/
49
54static nbgl_layoutInternal_t gLayout[NB_MAX_LAYOUTS] = {0};
55
56/**********************
57 * STATIC PROTOTYPES
58 **********************/
59
60static void buttonCallback(nbgl_screen_t *screen, nbgl_buttonEvent_t buttonEvent)
61{
63 nbgl_layoutInternal_t *layout = NULL;
64
65 // parse all layouts (starting with modals) to find the object
66 while (i > 0) {
67 i--;
68 if ((screen->index == gLayout[i].layer) && (gLayout[i].nbChildren > 0)) {
69 // found
70 layout = &gLayout[i];
71 break;
72 }
73 }
74 if (layout == NULL) {
77 "touchCallback(): screen->index = %d, buttonEvent = %d, no matching active layout\n",
78 screen->index,
79 buttonEvent);
80 return;
81 }
82
83#ifdef NBGL_KEYPAD
84 // special case of keypad
86 if (kpd) {
87 nbgl_keypadCallback(kpd, buttonEvent);
88 return;
89 }
90 else
91#endif // NBGL_KEYPAD
92#ifdef NBGL_KEYBOARD
93 {
95 if (kbd) {
96 nbgl_keyboardCallback(kbd, buttonEvent);
97 return;
98 }
99 }
100#endif // NBGL_KEYBOARD
101 if (layout->callback != NULL) {
102 layout->callback((nbgl_layout_t *) layout, buttonEvent);
103 }
104}
105
113{
114 if (layout->nbChildren == NB_MAX_SCREEN_CHILDREN) {
115 LOG_FATAL(LAYOUT_LOGGER, "layoutAddObject(): No more object\n");
116 }
117 layout->children[layout->nbChildren] = obj;
118 layout->nbChildren++;
119}
120
121/**********************
122 * GLOBAL FUNCTIONS
123 **********************/
124
132{
133 nbgl_layoutInternal_t *layout = NULL;
134
135 // find an empty layout in the proper "layer"
136 if (description->modal) {
137 if (gLayout[1].nbChildren == 0) {
138 layout = &gLayout[1];
139 }
140 else if (gLayout[2].nbChildren == 0) {
141 layout = &gLayout[2];
142 }
143 }
144 else {
145 // automatically "release" a potentially opened non-modal layout
146 gLayout[0].nbChildren = 0;
147 layout = &gLayout[0];
148 }
149 if (layout == NULL) {
150 LOG_WARN(LAYOUT_LOGGER, "nbgl_layoutGet(): impossible to get a layout!\n");
151 return NULL;
152 }
153
154 // reset globals
155 memset(layout, 0, sizeof(nbgl_layoutInternal_t));
156
157 layout->callback = (nbgl_layoutButtonCallback_t) PIC(description->onActionCallback);
158 layout->modal = description->modal;
159 if (description->modal) {
160 layout->layer = nbgl_screenPush(&layout->children,
162 &description->ticker,
163 (nbgl_buttonCallback_t) buttonCallback);
164 }
165 else {
166 nbgl_screenSet(&layout->children,
168 &description->ticker,
169 (nbgl_buttonCallback_t) buttonCallback);
170 layout->layer = 0;
171 }
172
173 return (nbgl_layout_t *) layout;
174}
175
183int nbgl_layoutAddNavigation(nbgl_layout_t *layout, nbgl_layoutNavigation_t *info)
184{
185 nbgl_layoutInternal_t *layoutInt = (nbgl_layoutInternal_t *) layout;
186
187 LOG_DEBUG(LAYOUT_LOGGER, "nbgl_layoutAddNavigation():\n");
188 if (layout == NULL) {
189 return -1;
190 }
191
192 nbgl_image_t *image;
193 if (info->indication & LEFT_ARROW) {
194 image = (nbgl_image_t *) nbgl_objPoolGet(IMAGE, layoutInt->layer);
195 image->foregroundColor = WHITE;
196 image->buffer = (info->direction == HORIZONTAL_NAV) ? &C_icon_left : &C_icon_up;
197 image->obj.area.bpp = NBGL_BPP_1;
198 image->obj.alignment = MID_LEFT;
199 layoutAddObject(layoutInt, (nbgl_obj_t *) image);
200 }
201 if (info->indication & RIGHT_ARROW) {
202 image = (nbgl_image_t *) nbgl_objPoolGet(IMAGE, layoutInt->layer);
203 image->foregroundColor = WHITE;
204 image->buffer = (info->direction == HORIZONTAL_NAV) ? &C_icon_right : &C_icon_down;
205 image->obj.area.bpp = NBGL_BPP_1;
206 image->obj.alignment = MID_RIGHT;
207 layoutAddObject(layoutInt, (nbgl_obj_t *) image);
208 }
209 return 0;
210}
211
223 const char *text,
224 const char *subText,
226{
227 nbgl_layoutInternal_t *layoutInt = (nbgl_layoutInternal_t *) layout;
228 nbgl_container_t *container;
229 nbgl_text_area_t *textArea;
230 uint16_t fullHeight = 0;
231
232 LOG_DEBUG(LAYOUT_LOGGER, "nbgl_layoutAddText():\n");
233 if (layout == NULL) {
234 return -1;
235 }
236 container = (nbgl_container_t *) nbgl_objPoolGet(CONTAINER, layoutInt->layer);
237
238 // get container children
239 container->nbChildren = 1;
240 if (subText != NULL) {
241 container->nbChildren += 2; // possibly 2 buttons
242 }
243
244 container->children = nbgl_containerPoolGet(container->nbChildren, layoutInt->layer);
245 container->obj.area.width = AVAILABLE_WIDTH;
246
247 textArea = (nbgl_text_area_t *) nbgl_objPoolGet(TEXT_AREA, layoutInt->layer);
248 textArea->textColor = WHITE;
249 textArea->text = PIC(text);
250 textArea->textAlignment = CENTER;
251 textArea->fontId = (style == REGULAR_INFO) ? BAGL_FONT_OPEN_SANS_REGULAR_11px_1bpp
253 textArea->obj.area.width = AVAILABLE_WIDTH;
254
255 uint16_t nbLines
256 = nbgl_getTextNbLinesInWidth(textArea->fontId, textArea->text, AVAILABLE_WIDTH, true);
257 // if more than available lines on screen
258 if (nbLines > NB_MAX_LINES) {
259 uint16_t len;
260
261 nbLines = NB_MAX_LINES;
262 textArea->nbMaxLines = NB_MAX_LINES;
264 textArea->fontId, textArea->text, AVAILABLE_WIDTH, nbLines, &len, true);
265 textArea->len = len;
266 }
267 const nbgl_font_t *font = nbgl_getFont(textArea->fontId);
268 textArea->obj.area.height = nbLines * font->line_height;
269 textArea->wrapping = true;
270 textArea->obj.alignment = TOP_MIDDLE;
271 fullHeight += textArea->obj.area.height;
272 container->children[0] = (nbgl_obj_t *) textArea;
273
274 if (subText != NULL) {
275 if (style != BUTTON_INFO) {
276 textArea = (nbgl_text_area_t *) nbgl_objPoolGet(TEXT_AREA, layoutInt->layer);
277 textArea->textColor = WHITE;
278 textArea->text = PIC(subText);
279 textArea->wrapping = true;
280 textArea->fontId = BAGL_FONT_OPEN_SANS_REGULAR_11px_1bpp;
281 textArea->obj.area.width = AVAILABLE_WIDTH;
283 textArea->fontId, textArea->text, AVAILABLE_WIDTH, true);
284 // if more than available lines on screen
285 if (nbLines > (NB_MAX_LINES - 1)) {
286 uint16_t len;
287 nbLines = NB_MAX_LINES - 1;
288 textArea->nbMaxLines = nbLines;
290 textArea->fontId, textArea->text, AVAILABLE_WIDTH, nbLines, &len, true);
291 textArea->len = len;
292 }
293 if (style == REGULAR_INFO) {
294 textArea->obj.area.height = nbLines * font->line_height;
295 }
296 else {
297 // the sub text must be vertically centered in a 3 lines container
298 textArea->obj.area.height = 3 * font->line_height;
299 }
300 textArea->textAlignment = CENTER;
301 textArea->obj.alignment = NO_ALIGNMENT;
302 textArea->obj.alignmentMarginY = 2;
303 fullHeight += textArea->obj.area.height + textArea->obj.alignmentMarginY;
304 container->children[1] = (nbgl_obj_t *) textArea;
305 }
306 else {
307 nbgl_button_t *button = (nbgl_button_t *) nbgl_objPoolGet(BUTTON, layoutInt->layer);
308 uint16_t textWidth;
309 uint16_t len = 0;
310 uint16_t width = 0;
311 static char tmpString[NB_MAX_CHAR_IN_LINE];
312
313 button->foregroundColor = BLACK;
314 button->innerColor = WHITE;
315 button->borderColor = WHITE;
316 button->radius = RADIUS_3_PIXELS;
317 button->text = (const char *) PIC(subText);
319 button->obj.area.height = 14;
320 button->obj.alignment = CENTER;
321
322 textWidth = nbgl_getTextWidth(button->fontId, button->text);
323 if ((textWidth + BUTTON_MARGIN_Y) >= AVAILABLE_WIDTH) {
324 nbgl_getTextMaxLenAndWidth(button->fontId,
325 button->text,
326 AVAILABLE_WIDTH - BUTTON_MARGIN_Y,
327 &len,
328 &width,
329 true);
330 button->obj.area.width = width + BUTTON_MARGIN_Y;
331 // copy the first 'len' chars in the tmp string buffer (max is
332 // NB_MAX_CHAR_IN_LINE-1)
333 memcpy(tmpString, button->text, MIN(len, (NB_MAX_CHAR_IN_LINE - 1)));
334 // NULL termination
335 tmpString[MIN(len, (NB_MAX_CHAR_IN_LINE - 1))] = '\0';
336 button->text = tmpString;
337 button->obj.alignmentMarginY = 8 - 7;
338 }
339 else {
340 button->obj.area.width = textWidth + BUTTON_MARGIN_Y;
341 button->obj.alignmentMarginY = 8;
342 }
343 container->children[1] = (nbgl_obj_t *) button;
344
345 // if too long text, draw a second button under the first one, with the remaining text
346 if (width > 0) {
347 button = (nbgl_button_t *) nbgl_objPoolGet(BUTTON, layoutInt->layer);
348 button->foregroundColor = BLACK;
349 button->innerColor = WHITE;
350 button->borderColor = WHITE;
351 button->radius = RADIUS_3_PIXELS;
352 button->text = (const char *) PIC(subText + len);
354 button->obj.area.height = 14;
355 button->obj.area.width
356 = nbgl_getTextWidth(button->fontId, button->text) + BUTTON_MARGIN_Y;
357 button->obj.alignment = CENTER;
358 button->obj.alignmentMarginY = 8 + 7;
359 container->children[2] = (nbgl_obj_t *) button;
360 }
361
362 fullHeight += 44;
363 }
364 }
365 container->obj.area.height = fullHeight;
366 container->layout = VERTICAL;
367 container->obj.alignment = CENTER;
368 // set this new obj as child of main container
369 layoutAddObject(layoutInt, (nbgl_obj_t *) container);
370
371 return 0;
372}
373
382int nbgl_layoutAddMenuList(nbgl_layout_t *layout, nbgl_layoutMenuList_t *list)
383{
384 nbgl_layoutInternal_t *layoutInt = (nbgl_layoutInternal_t *) layout;
385 uint8_t i;
386
387 LOG_DEBUG(LAYOUT_LOGGER, "nbgl_layoutAddMenuList():\n");
388 if (layout == NULL) {
389 return -1;
390 }
391 for (i = 0; i < list->nbChoices; i++) {
392 nbgl_text_area_t *textArea;
393
394 // check whether this object is visible or not
395 // only the two objects above or below the selected one are visible
396 if (((list->selectedChoice > 2) && (i < (list->selectedChoice - 2)))
397 || (i > (list->selectedChoice + 2))) {
398 continue;
399 }
400
401 textArea = (nbgl_text_area_t *) nbgl_objPoolGet(TEXT_AREA, layoutInt->layer);
402
403 // init text area for this choice
404 textArea->text = list->callback(i);
405 textArea->textAlignment = CENTER;
406 textArea->obj.area.width = AVAILABLE_WIDTH;
407 textArea->obj.area.height = 12;
408 textArea->style = NO_STYLE;
409 textArea->obj.alignment = CENTER;
410 textArea->obj.alignmentMarginY = ((i - list->selectedChoice) * 16);
411 textArea->textColor = WHITE;
412
413 // highlight init choice
414 if (i == list->selectedChoice) {
416 }
417 else {
418 textArea->fontId = BAGL_FONT_OPEN_SANS_REGULAR_11px_1bpp;
419 }
420
421 // set this new obj as child of main container
422 layoutAddObject(layoutInt, (nbgl_obj_t *) textArea);
423 }
424
425 return 0;
426}
427
437{
438 nbgl_layoutInternal_t *layoutInt = (nbgl_layoutInternal_t *) layout;
439 nbgl_container_t *container;
440 nbgl_text_area_t *textArea = NULL;
441 nbgl_image_t *image = NULL;
442 uint16_t fullHeight = 0;
443
444 LOG_DEBUG(LAYOUT_LOGGER, "nbgl_layoutAddCenteredInfo():\n");
445 if (layout == NULL) {
446 return -1;
447 }
448
449 container = (nbgl_container_t *) nbgl_objPoolGet(CONTAINER, layoutInt->layer);
450
451 // 3 children at max
452 container->children = nbgl_containerPoolGet(3, layoutInt->layer);
453 container->nbChildren = 0;
454 if (info->icon != NULL) {
455 image = (nbgl_image_t *) nbgl_objPoolGet(IMAGE, layoutInt->layer);
456 image->foregroundColor = WHITE;
457 image->buffer = PIC(info->icon);
458 image->obj.area.bpp = NBGL_BPP_1;
459 image->obj.alignment = TOP_MIDDLE;
460 image->obj.alignTo = NULL;
461
462 fullHeight += image->buffer->height;
463 container->children[container->nbChildren] = (nbgl_obj_t *) image;
464 container->nbChildren++;
465 }
466 if (info->text1 != NULL) {
467 textArea = (nbgl_text_area_t *) nbgl_objPoolGet(TEXT_AREA, layoutInt->layer);
468 textArea->textColor = WHITE;
469 textArea->text = PIC(info->text1);
470 textArea->textAlignment = CENTER;
471 textArea->fontId = (info->style == REGULAR_INFO) ? BAGL_FONT_OPEN_SANS_REGULAR_11px_1bpp
473 textArea->obj.area.width = AVAILABLE_WIDTH;
474 textArea->wrapping = true;
475 uint16_t nbLines
476 = nbgl_getTextNbLinesInWidth(textArea->fontId, textArea->text, AVAILABLE_WIDTH, true);
477 // if more than available lines on screen
478 if (nbLines > NB_MAX_LINES) {
479 uint16_t len;
480 nbLines = NB_MAX_LINES;
481 textArea->nbMaxLines = NB_MAX_LINES;
483 textArea->fontId, textArea->text, AVAILABLE_WIDTH, nbLines, &len, true);
484 textArea->len = len;
485 }
486 const nbgl_font_t *font = nbgl_getFont(textArea->fontId);
487 textArea->obj.area.height = nbLines * font->line_height;
488 textArea->style = NO_STYLE;
489 if (info->icon != NULL) {
490 textArea->obj.alignment = BOTTOM_MIDDLE; // under icon
491 textArea->obj.alignTo = (nbgl_obj_t *) container->children[container->nbChildren - 1];
492 textArea->obj.alignmentMarginY = (nbLines < 3) ? 4 : 0;
493 }
494 else if (info->text2 == NULL) {
495 textArea->obj.alignment = CENTER;
496 textArea->obj.alignTo = NULL;
497 }
498 else {
499 textArea->obj.alignment = TOP_MIDDLE;
500 textArea->obj.alignTo = NULL;
501 }
502
503 fullHeight += textArea->obj.area.height + textArea->obj.alignmentMarginY;
504
505 container->children[container->nbChildren] = (nbgl_obj_t *) textArea;
506 container->nbChildren++;
507 }
508 if (info->text2 != NULL) {
509 textArea = (nbgl_text_area_t *) nbgl_objPoolGet(TEXT_AREA, layoutInt->layer);
510 textArea->textColor = WHITE;
511 textArea->text = PIC(info->text2);
512 textArea->textAlignment = CENTER;
513 textArea->fontId = BAGL_FONT_OPEN_SANS_REGULAR_11px_1bpp;
514 textArea->obj.area.width = AVAILABLE_WIDTH;
515 textArea->wrapping = true;
516 uint16_t nbLines
517 = nbgl_getTextNbLinesInWidth(textArea->fontId, textArea->text, AVAILABLE_WIDTH, true);
518 // if more than available lines on screen
519 if (nbLines > (NB_MAX_LINES - 1)) {
520 uint16_t len;
521 nbLines = NB_MAX_LINES - 1;
522 textArea->nbMaxLines = nbLines;
524 textArea->fontId, textArea->text, AVAILABLE_WIDTH, nbLines, &len, true);
525 textArea->len = len;
526 }
527 const nbgl_font_t *font = nbgl_getFont(textArea->fontId);
528 textArea->obj.area.height = nbLines * font->line_height;
529
530 textArea->style = NO_STYLE;
531 textArea->obj.alignment = BOTTOM_MIDDLE;
532 textArea->obj.alignTo = (nbgl_obj_t *) container->children[container->nbChildren - 1];
533 textArea->obj.alignmentMarginY = 2;
534
535 fullHeight += textArea->obj.area.height + textArea->obj.alignmentMarginY;
536
537 container->children[container->nbChildren] = (nbgl_obj_t *) textArea;
538 container->nbChildren++;
539 }
540 container->obj.area.height = fullHeight;
541 container->layout = VERTICAL;
542 container->obj.alignmentMarginY = 0;
543 if (info->onTop) {
544 container->obj.alignment = TOP_MIDDLE;
545 }
546 else {
547 container->obj.alignment = CENTER;
548 }
549
550 container->obj.area.width = AVAILABLE_WIDTH;
551
552 // set this new container as child of main container
553 layoutAddObject(layoutInt, (nbgl_obj_t *) container);
554
555 return 0;
556}
557
567{
568 nbgl_layoutInternal_t *layoutInt = (nbgl_layoutInternal_t *) layout;
569 nbgl_progress_bar_t *progress;
570
571 LOG_DEBUG(LAYOUT_LOGGER, "nbgl_layoutAddProgressBar():\n");
572 if (layout == NULL) {
573 return -1;
574 }
575 if (barLayout->text != NULL) {
576 nbgl_text_area_t *textArea;
577
579 ((nbgl_layoutInternal_t *) layout)->layer);
580 textArea->textColor = WHITE;
581 textArea->text = PIC(barLayout->text);
582 textArea->textAlignment = CENTER;
583 textArea->fontId = BAGL_FONT_OPEN_SANS_REGULAR_11px_1bpp;
584 textArea->obj.area.width = AVAILABLE_WIDTH;
585 textArea->obj.area.height = nbgl_getTextHeight(textArea->fontId, textArea->text);
586 textArea->obj.alignment = TOP_MIDDLE;
587 textArea->obj.alignmentMarginX = 0;
588 textArea->obj.alignmentMarginY = 16; // 16 px from top
589 layoutAddObject(layoutInt, (nbgl_obj_t *) textArea);
590 }
592 ((nbgl_layoutInternal_t *) layout)->layer);
593 progress->foregroundColor = WHITE;
594 progress->withBorder = true;
595 progress->state = barLayout->percentage;
596 progress->obj.area.width = 102;
597 progress->obj.area.height = 14;
598 progress->obj.alignment = TOP_MIDDLE;
599 progress->obj.alignmentMarginX = 0;
600 progress->obj.alignmentMarginY = 33; // 33px from top
601 layoutAddObject(layoutInt, (nbgl_obj_t *) progress);
602
603 if (barLayout->subText != NULL) {
604 nbgl_text_area_t *subTextArea;
605
606 subTextArea = (nbgl_text_area_t *) nbgl_objPoolGet(
607 TEXT_AREA, ((nbgl_layoutInternal_t *) layout)->layer);
608 subTextArea->textColor = WHITE;
609 subTextArea->text = PIC(barLayout->subText);
610 subTextArea->textAlignment = CENTER;
611 subTextArea->fontId = BAGL_FONT_OPEN_SANS_REGULAR_11px_1bpp;
612 subTextArea->obj.area.width = AVAILABLE_WIDTH;
613 subTextArea->obj.area.height = nbgl_getTextHeight(subTextArea->fontId, subTextArea->text);
614 subTextArea->obj.alignment = BOTTOM_MIDDLE;
615 subTextArea->obj.alignTo = (nbgl_obj_t *) progress;
616 subTextArea->obj.alignmentMarginX = 0;
617 subTextArea->obj.alignmentMarginY = 4;
618 layoutAddObject(layoutInt, (nbgl_obj_t *) subTextArea);
619 }
620
621 return 0;
622}
623
631int nbgl_layoutAddButton(nbgl_layout_t *layout, const nbgl_layoutButton_t *buttonInfo)
632{
633 nbgl_layoutInternal_t *layoutInt = (nbgl_layoutInternal_t *) layout;
634 nbgl_button_t *button;
635
636 LOG_DEBUG(LAYOUT_LOGGER, "nbgl_layoutAddButton():\n");
637 if (layout == NULL) {
638 return -1;
639 }
640 button = (nbgl_button_t *) nbgl_objPoolGet(BUTTON, ((nbgl_layoutInternal_t *) layout)->layer);
641 button->foregroundColor = BLACK;
642 button->innerColor = WHITE;
643 button->borderColor = WHITE;
644 button->radius = RADIUS_3_PIXELS;
645 button->text = (const char *) PIC(buttonInfo->text);
647 button->icon = (const nbgl_icon_details_t *) PIC(buttonInfo->icon);
648 button->obj.area.width = nbgl_getTextWidth(button->fontId, button->text) + BUTTON_MARGIN_Y;
649 button->obj.area.height = 14;
650 layoutAddObject(layoutInt, (nbgl_obj_t *) button);
651
652 return 0;
653}
654
662int nbgl_layoutAddSwitch(nbgl_layout_t *layout, const nbgl_layoutSwitch_t *switchLayout)
663{
664 nbgl_layoutInternal_t *layoutInt = (nbgl_layoutInternal_t *) layout;
665 nbgl_button_t *button;
666 nbgl_text_area_t *textArea;
667
668 LOG_DEBUG(LAYOUT_LOGGER, "nbgl_layoutAddSwitch():\n");
669 if (layout == NULL) {
670 return -1;
671 }
672 // add switch name as title
673 textArea = (nbgl_text_area_t *) nbgl_objPoolGet(TEXT_AREA, layoutInt->layer);
674 textArea->textColor = WHITE;
675 textArea->text = PIC(switchLayout->text);
676 textArea->textAlignment = CENTER;
678 textArea->obj.area.width = AVAILABLE_WIDTH;
679 textArea->wrapping = true;
680 uint16_t nbLines
681 = nbgl_getTextNbLinesInWidth(textArea->fontId, textArea->text, AVAILABLE_WIDTH, true);
682 // if more than 1 line on screen
683 if (nbLines > 1) {
684 // TODO: warning for screenshots
685 return -1;
686 }
687 textArea->obj.area.height = nbgl_getFontLineHeight(textArea->fontId);
688 textArea->obj.alignment = TOP_MIDDLE;
689 textArea->obj.alignmentMarginY = 3;
690 layoutAddObject(layoutInt, (nbgl_obj_t *) textArea);
691
692 // add switch description
693 textArea = (nbgl_text_area_t *) nbgl_objPoolGet(TEXT_AREA, layoutInt->layer);
694 textArea->textColor = WHITE;
695 textArea->text = PIC(switchLayout->subText);
696 textArea->textAlignment = CENTER;
697 textArea->fontId = BAGL_FONT_OPEN_SANS_REGULAR_11px_1bpp;
698 textArea->obj.area.width = AVAILABLE_WIDTH;
699 textArea->obj.area.height = 2 * nbgl_getFontLineHeight(textArea->fontId);
700 textArea->wrapping = true;
701 nbLines = nbgl_getTextNbLinesInWidth(textArea->fontId, textArea->text, AVAILABLE_WIDTH, true);
702 // if more than 2 lines on screen
703 if (nbLines > 2) {
704 // TODO: warning for screenshots
705 return -1;
706 }
707 textArea->obj.alignment = CENTER;
708 textArea->obj.alignmentMarginY = 1; // not exactly centered
709 layoutAddObject(layoutInt, (nbgl_obj_t *) textArea);
710
711 button = (nbgl_button_t *) nbgl_objPoolGet(BUTTON, ((nbgl_layoutInternal_t *) layout)->layer);
712 button->foregroundColor = BLACK;
713 button->innerColor = WHITE;
714 button->borderColor = WHITE;
715 button->radius = RADIUS_3_PIXELS;
716 button->text = (switchLayout->initState == ON_STATE) ? "Enabled" : "Disabled";
718 button->icon = (switchLayout->initState == ON_STATE) ? &C_Switch_On_8px : &C_Switch_Off_8px;
719 // 2 pixels between icon & text, and 4 pixels on each side
720 button->obj.area.width
721 = nbgl_getTextWidth(button->fontId, button->text) + 2 + C_Switch_Off_8px.width + 8;
722 button->obj.area.height = 12;
723 button->obj.alignment = BOTTOM_MIDDLE;
724 button->obj.alignmentMarginY = 3;
725 layoutAddObject(layoutInt, (nbgl_obj_t *) button);
726
727 return 0;
728}
729
736int nbgl_layoutDraw(nbgl_layout_t *layoutParam)
737{
738 nbgl_layoutInternal_t *layout = (nbgl_layoutInternal_t *) layoutParam;
739
740 if (layout == NULL) {
741 return -1;
742 }
743 LOG_DEBUG(LAYOUT_LOGGER, "nbgl_layoutDraw(): layout->nbChildren = %d\n", layout->nbChildren);
745
746 return 0;
747}
748
755int nbgl_layoutRelease(nbgl_layout_t *layoutParam)
756{
757 nbgl_layoutInternal_t *layout = (nbgl_layoutInternal_t *) layoutParam;
758 LOG_DEBUG(PAGE_LOGGER, "nbgl_layoutRelease(): \n");
759 if (layout == NULL) {
760 return -1;
761 }
762 // if modal
763 if (layout->modal) {
764 nbgl_screenPop(layout->layer);
765 }
766 layout->nbChildren = 0;
767 return 0;
768}
769#endif // HAVE_SE_TOUCH
Random Number Generation.
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
@ LAYOUT_LOGGER
Definition nbgl_debug.h:33
@ PAGE_LOGGER
Definition nbgl_debug.h:34
Middle Level API of the new BOLOS Graphical Library.
void nbgl_getTextMaxLenAndWidth(nbgl_font_id_e fontId, const char *text, uint16_t maxWidth, uint16_t *len, uint16_t *width, bool wrapping)
compute the max width of the first line of the given text fitting in maxWidth
Definition nbgl_fonts.c:472
bool nbgl_getTextMaxLenInNbLines(nbgl_font_id_e fontId, const char *text, uint16_t maxWidth, uint16_t maxNbLines, uint16_t *len, bool wrapping)
compute the len of the given text (in bytes) fitting in the given maximum nb lines,...
Definition nbgl_fonts.c:562
@ BAGL_FONT_OPEN_SANS_REGULAR_11px_1bpp
Definition nbgl_fonts.h:145
@ BAGL_FONT_OPEN_SANS_EXTRABOLD_11px_1bpp
Definition nbgl_fonts.h:143
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)
Definition nbgl_fonts.c:350
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
Definition nbgl_fonts.c:721
const nbgl_font_t * nbgl_getFont(nbgl_font_id_e fontId)
uint16_t nbgl_getTextHeight(nbgl_font_id_e fontId, const char *text)
return the height of the given multiline text, with the given font.
Definition nbgl_fonts.c:431
uint8_t nbgl_getFontLineHeight(nbgl_font_id_e fontId)
return the height in pixels of the line of font with the given font ID
Definition nbgl_fonts.c:400
Font screen low-Level driver API, to draw elementary forms.
#define NB_MAX_LAYOUTS
Definition nbgl_layout.c:35
void layoutAddObject(nbgl_layoutInternal_t *layout, nbgl_obj_t *obj)
adds the given obj to the main container
#define NB_MAX_LINES
Definition nbgl_layout.h:88
@ 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)
@ 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
Definition nbgl_layout.h:86
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.
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_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.
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()
@ NB_MAX_SCREEN_CHILDREN
Internal functions/constants of NBGL layout layer.
API to draw all basic graphic objects.
struct PACKED__ nbgl_text_area_s nbgl_text_area_t
struct to represent a text area (TEXT_AREA type)
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.
nbgl_buttonEvent_t
Definition nbgl_obj.h:207
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_buttonCallback_t)(void *obj, nbgl_buttonEvent_t buttonEvent)
prototype of function to be called when a button event is received by an object (TODO: change to scre...
Definition nbgl_obj.h:225
struct PACKED__ nbgl_container_s nbgl_container_t
struct to represent a container (CONTAINER type)
struct PACKED__ nbgl_obj_s nbgl_obj_t
Common structure for all graphical objects.
API to manage screens.
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....
struct PACKED__ nbgl_screen_s nbgl_screen_t
struct to represent a screen (SCREEN type)
int nbgl_screenPop(uint8_t screenIndex)
Release the screen at the given index in screen array (index returned by nbgl_screenPush())....
nbgl_obj_t * nbgl_screenContainsObjType(nbgl_screen_t *screen, nbgl_obj_type_t type)
return an object of the given type in the given screen
void nbgl_screenRedraw(void)
This function redraws the whole screen on top of stack and its children.
Definition nbgl_screen.c:66
@ WHITE
Definition nbgl_types.h:126
@ BLACK
Definition nbgl_types.h:123
@ ON_STATE
Definition nbgl_types.h:183
@ VERTICAL
from top to bottom
Definition nbgl_types.h:191
#define MIN(x, y)
Definition nbgl_types.h:100
struct PACKED__ nbgl_icon_details_s nbgl_icon_details_t
Represents all information about an icon.
@ TOP_MIDDLE
Definition nbgl_types.h:164
@ CENTER
Definition nbgl_types.h:167
@ NO_ALIGNMENT
used when parent container layout is used
Definition nbgl_types.h:162
@ MID_RIGHT
Definition nbgl_types.h:168
@ MID_LEFT
Definition nbgl_types.h:166
@ BOTTOM_MIDDLE
Definition nbgl_types.h:170
@ KEYPAD
Keypad.
Definition nbgl_types.h:149
@ IMAGE
Bitmap (y and height must be multiple of 4 on Stax)
Definition nbgl_types.h:139
@ BUTTON
Rounded rectangle button with icon and/or text.
Definition nbgl_types.h:142
@ PROGRESS_BAR
horizontal bar to indicate progression of something (between 0% and 100%)
Definition nbgl_types.h:145
@ KEYBOARD
Keyboard.
Definition nbgl_types.h:148
@ CONTAINER
Empty container.
Definition nbgl_types.h:138
@ TEXT_AREA
Area to contain text line(s)
Definition nbgl_types.h:141
@ NBGL_BPP_1
1 bit per pixel
Definition nbgl_types.h:266
@ NO_STYLE
no border
Definition nbgl_types.h:200
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
const nbgl_icon_details_t * icon
a buffer containing the 1BPP icon
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
nbgl_state_t initState
initial state of the switch
const char * subText
description under main text (NULL terminated, single line, may be null)
structure defining an ASCII font
Definition nbgl_fonts.h:76
uint8_t line_height
height of a line for all characters in pixels
Definition nbgl_fonts.h:81
This structure contains info to build a single button.
const char * text
button text
const nbgl_icon_details_t * icon
a buffer containing the 1BPP icon for button
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
Structure containing all information about the current layout.
nbgl_layoutTouchCallback_t callback
bool modal
if true, means the screen is a modal
uint8_t nbChildren
number of children in above array
nbgl_obj_t ** children
children for main screen
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)
This structure contains info to build a progress bar with info. The progress bar itself is 120px widt...
uint8_t percentage
percentage of completion, from 0 to 100.
const char * text
text in black, on top of progress bar
const char * subText
text in gray, under progress bar
unsigned short uint16_t
Definition usbd_conf.h:54
unsigned char uint8_t
Definition usbd_conf.h:53