23 #include "os_helpers.h"
45 #define TEXT_ENTRY_NORMAL_HEIGHT 64
46 #define TEXT_ENTRY_COMPACT_HEIGHT 64
47 #define BOTTOM_NORMAL_MARGIN 24
48 #define BOTTOM_COMPACT_MARGIN 24
49 #define TOP_NORMAL_MARGIN 20
50 #define TOP_COMPACT_MARGIN 20
52 #define TEXT_ENTRY_NORMAL_HEIGHT 72
53 #define TEXT_ENTRY_COMPACT_HEIGHT 56
54 #define BOTTOM_NORMAL_MARGIN 24
55 #define BOTTOM_COMPACT_MARGIN 12
56 #define TOP_NORMAL_MARGIN 20
57 #define TOP_COMPACT_MARGIN 12
61 #define LINE_REAL_HEIGHT 4
63 #define NUMBER_WIDTH 56
66 #define NUMBER_TEXT_SPACE 8
81 static char numText[5];
97 bool needRefresh =
false;
102 && (currentLeftButtonIndex
108 = (
nbgl_obj_t *) choiceButtons[currentLeftButtonIndex];
111 if (currentLeftButtonIndex < (uint32_t) (nbActiveButtons - i)) {
113 = (
nbgl_obj_t *) choiceButtons[currentLeftButtonIndex + i];
129 = (
nbgl_obj_t *) choiceButtons[currentLeftButtonIndex + i];
151 if (container->children[THIRD_BUTTON_INDEX] != NULL) {
152 container->children[THIRD_BUTTON_INDEX]->alignmentMarginX = 0;
153 container->children[THIRD_BUTTON_INDEX]->alignmentMarginY =
INTERNAL_MARGIN;
154 container->children[THIRD_BUTTON_INDEX]->alignment =
BOTTOM_MIDDLE;
155 container->children[THIRD_BUTTON_INDEX]->alignTo = container->children[
FIRST_BUTTON_INDEX];
159 if (container->children[FOURTH_BUTTON_INDEX] != NULL) {
160 container->children[FOURTH_BUTTON_INDEX]->alignmentMarginX =
INTERNAL_MARGIN;
161 container->children[FOURTH_BUTTON_INDEX]->alignmentMarginY = 0;
162 container->children[FOURTH_BUTTON_INDEX]->alignment =
MID_RIGHT;
163 container->children[FOURTH_BUTTON_INDEX]->alignTo = container->children[THIRD_BUTTON_INDEX];
171 indicator->activePage = page;
175 if (currentLeftButtonIndex > 0) {
201 if ((container->nbChildren < 2) || (container->children[1]->type !=
CONTAINER)) {
210 while (i < (uint32_t) nbActiveButtons) {
218 if (i < (uint32_t) nbActiveButtons) {
219 if (updateSuggestionButtons(suggestionsContainer, eventType, i)) {
220 io_seproxyhal_play_tune(TUNE_TAP_CASUAL);
247 container->nbChildren = 4;
250 container->obj.alignment =
CENTER;
255 textArea->textColor =
BLACK;
256 textArea->text = title;
257 textArea->textAlignment =
CENTER;
258 textArea->fontId = SMALL_REGULAR_FONT;
259 textArea->wrapping =
true;
263 textArea->fontId, textArea->text, textArea->obj.area.width, textArea->wrapping);
264 container->children[0] = (
nbgl_obj_t *) textArea;
265 container->obj.area.height = textArea->obj.area.height + 4;
271 textArea->textColor =
BLACK;
272 snprintf(numText,
sizeof(numText),
"%d.", number);
273 textArea->text = numText;
274 textArea->textAlignment =
CENTER;
275 textArea->fontId = LARGE_MEDIUM_1BPP_FONT;
279 textArea->obj.alignTo = container->children[0];
288 container->children[1] = (
nbgl_obj_t *) textArea;
294 textArea->text = text;
296 textArea->fontId = LARGE_MEDIUM_1BPP_FONT;
299 textArea->obj.alignTo = container->children[0];
309 textArea->obj.area.width -= textArea->obj.alignmentMarginX;
312 textArea->autoHideLongLine =
true;
318 textArea->obj.touchMask = (1 <<
TOUCHED);
320 container->children[2] = (
nbgl_obj_t *) textArea;
321 container->obj.area.height += textEntryHeight;
341 const char **buttonTexts,
342 int firstButtonToken,
349 nbActiveButtons = nbUsedButtons;
351 suggestionsContainer->layout =
VERTICAL;
361 suggestionsContainer->children
365 suggestionsContainer->obj.alignmentMarginY
374 layoutInt, (
nbgl_obj_t *) choiceButtons[i], firstButtonToken + i, tuneId);
379 choiceButtons[i]->innerColor =
BLACK;
380 choiceButtons[i]->borderColor =
BLACK;
381 choiceButtons[i]->foregroundColor =
WHITE;
385 choiceButtons[i]->fontId = SMALL_BOLD_1BPP_FONT;
386 choiceButtons[i]->text = buttonTexts[i];
387 choiceButtons[i]->obj.touchMask = (1 <<
TOUCHED);
399 indicator->activePage = 0;
402 indicator->obj.area.width = 184;
410 partialButtonImages[0]->buffer = &C_left_half_64px;
411 partialButtonImages[0]->obj.alignment =
TOP_LEFT;
412 partialButtonImages[0]->foregroundColor =
BLACK;
414 partialButtonImages[1]->buffer = &C_left_half_64px;
415 partialButtonImages[1]->obj.alignment =
TOP_RIGHT;
416 partialButtonImages[1]->foregroundColor =
BLACK;
418 updateSuggestionButtons(suggestionsContainer, 0, 0);
421 return suggestionsContainer;
443 button->foregroundColor =
WHITE;
445 button->innerColor =
BLACK;
446 button->borderColor =
BLACK;
447 button->obj.touchMask = (1 <<
TOUCHED);
454 button->text = PIC(text);
455 button->fontId = SMALL_BOLD_1BPP_FONT;
480 if (layout == NULL) {
496 keyboard->obj.alignmentMarginY = 56;
500 keyboard->callback = PIC(kbdInfo->
callback);
502 keyboard->mode = kbdInfo->
mode;
503 keyboard->keyMask = kbdInfo->
keyMask;
504 keyboard->casing = kbdInfo->
casing;
514 = keyboard->obj.area.height + keyboard->obj.alignmentMarginY;
553 if (layout == NULL) {
560 if ((keyboard == NULL) || (keyboard->obj.type !=
KEYBOARD)) {
563 keyboard->keyMask = keyMask;
565 keyboard->casing = casing;
586 if (layout == NULL) {
593 if ((keyboard == NULL) || (keyboard->obj.type !=
KEYBOARD)) {
596 if (keyboard->needsRefresh) {
597 keyboard->needsRefresh =
false;
619 int firstButtonToken,
628 if (layout == NULL) {
632 container = addSuggestionButtons(
633 layoutInt, nbUsedButtons, buttonTexts, firstButtonToken, tuneId,
false);
636 if (layoutInt->
container->children[enteredTextIndex] != NULL) {
638 ->obj.alignmentMarginY
639 -= (container->obj.area.height + container->obj.alignmentMarginY + 20) / 2;
655 return (layoutInt->
container->nbChildren - 1);
679 if (layout == NULL) {
685 if ((container == NULL) || (container->obj.type !=
CONTAINER)) {
688 nbActiveButtons = nbUsedButtons;
693 choiceButtons[i]->text = buttonTexts[i];
706 choiceButtons[i]->obj.alignment =
TOP_LEFT;
712 choiceButtons[i]->obj.alignment =
MID_RIGHT;
713 choiceButtons[i]->obj.alignTo = (
nbgl_obj_t *) choiceButtons[i - 1];
721 container->forceClean =
true;
726 indicator->nbPages = (nbUsedButtons + 1) / 2;
727 indicator->activePage = 0;
728 updateSuggestionButtons(container, 0, 0);
764 bool compactMode = ((layoutInt->
container->children[enteredTextIndex + 1] != NULL)
765 && (layoutInt->
container->children[enteredTextIndex + 1]->type ==
BUTTON)
766 && (layoutInt->
container->nbChildren == 3));
769 if (layout == NULL) {
775 = addTextEntry(layoutInt, NULL, text, numbered, number, grayedOut, token, compactMode);
780 if (layoutInt->
container->children[enteredTextIndex + 1] != NULL) {
781 if (layoutInt->
container->children[enteredTextIndex + 1]->type ==
BUTTON) {
784 container->obj.alignmentMarginY
785 -= (button->obj.area.height + button->obj.alignmentMarginY
792 container->obj.alignmentMarginY
793 -= (suggestionContainer->obj.area.height + suggestionContainer->obj.alignmentMarginY
800 if (layoutInt->
container->nbChildren == 3) {
801 container->obj.alignmentMarginY += layoutInt->
container->children[0]->area.height / 2;
834 if (layout == NULL) {
841 if ((container == NULL) || (container->obj.type !=
CONTAINER)) {
845 if ((textArea == NULL) || (textArea->obj.type !=
TEXT_AREA)) {
848 textArea->text = text;
857 snprintf(numText,
sizeof(numText),
"%d.", number);
858 textArea->text = numText;
888 bool compactMode = (layoutInt->
container->nbChildren == 3);
891 if (layout == NULL) {
895 button = addConfirmationButton(layoutInt, active, text, token, tuneId, compactMode);
898 if (layoutInt->
container->children[enteredTextIndex] != NULL) {
900 ->obj.alignmentMarginY
901 -= (button->obj.area.height + button->obj.alignmentMarginY
932 if (layout == NULL) {
938 if ((button == NULL) || (button->obj.type !=
BUTTON)) {
944 button->innerColor =
BLACK;
945 button->borderColor =
BLACK;
946 button->obj.touchMask = (1 <<
TOUCHED);
972 if (layout == NULL) {
976 container = addTextEntry(layoutInt,
990 = addSuggestionButtons(layoutInt,
1006 container->obj.alignmentMarginY
1007 -= (suggestionsContainer->obj.area.height + suggestionsContainer->obj.alignmentMarginY
1020 container->obj.alignmentMarginY
1021 -= (button->obj.area.height + button->obj.alignmentMarginY
1026 return layoutInt->
container->obj.area.height;
1046 if (layout == NULL) {
1056 snprintf(numText,
sizeof(numText),
"%d.", content->
number);
1063 textArea->text = content->
text;
1084 suggestionsContainer->forceClean =
true;
1091 indicator->activePage = 0;
1092 updateSuggestionButtons(suggestionsContainer, 0, 0);
1099 if ((button == NULL) || (button->obj.type !=
BUTTON)) {
1105 button->innerColor =
BLACK;
1106 button->borderColor =
BLACK;
1107 button->obj.touchMask = (1 <<
TOUCHED);
#define LOG_DEBUG(__logger,...)
Middle Level API of the new BOLOS Graphical Library.
uint16_t nbgl_getSingleLineTextWidth(nbgl_font_id_e fontId, const char *text)
return the max width in pixels of the given text until the first or \0 is encountered
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.
Font screen low-Level driver API, to draw elementary forms.
void layoutAddObject(nbgl_layoutInternal_t *layout, nbgl_obj_t *obj)
adds the given obj to the main container
layoutObj_t * layoutAddCallbackObj(nbgl_layoutInternal_t *layout, nbgl_obj_t *obj, uint8_t token, tune_index_e tuneId)
#define NB_MAX_VISIBLE_SUGGESTION_BUTTONS
#define NB_MAX_SUGGESTION_BUTTONS
void * nbgl_layout_t
type shared externally
@ KEYBOARD_WITH_BUTTON
text entry area + confirmation button
@ KEYBOARD_WITH_SUGGESTIONS
text entry area + suggestion buttons
Internal functions/constants of NBGL layout layer.
@ SWIPE_USAGE_SUGGESTIONS
#define SMALL_BUTTON_HEIGHT
#define KEYBOARD_FOOTER_TYPE
int nbgl_layoutUpdateKeyboard(nbgl_layout_t *layout, uint8_t index, uint32_t keyMask, bool updateCasing, keyboardCase_t casing)
Updates an existing keyboard on bottom of the screen, with the given configuration.
int nbgl_layoutAddKeyboard(nbgl_layout_t *layout, const nbgl_layoutKbd_t *kbdInfo)
Creates a keyboard on bottom of the screen, with the given configuration.
#define BOTTOM_COMPACT_MARGIN
int nbgl_layoutAddSuggestionButtons(nbgl_layout_t *layout, uint8_t nbUsedButtons, const char *buttonTexts[NB_MAX_SUGGESTION_BUTTONS], int firstButtonToken, tune_index_e tuneId)
Adds up to 4 black suggestion buttons under the previously added object.
bool keyboardSwipeCallback(nbgl_obj_t *obj, nbgl_touchType_t eventType)
#define TEXT_ENTRY_NORMAL_HEIGHT
#define BOTTOM_NORMAL_MARGIN
int nbgl_layoutUpdateSuggestionButtons(nbgl_layout_t *layout, uint8_t index, uint8_t nbUsedButtons, const char *buttonTexts[NB_MAX_SUGGESTION_BUTTONS])
Updates the number and/or the text suggestion buttons created with nbgl_layoutAddSuggestionButtons()
int nbgl_layoutAddKeyboardContent(nbgl_layout_t *layout, nbgl_layoutKeyboardContent_t *content)
Adds an area containing a potential title, a text entry and either confirmation or suggestion buttons...
int nbgl_layoutAddEnteredText(nbgl_layout_t *layout, bool numbered, uint8_t number, const char *text, bool grayedOut, int offsetY, int token)
Adds a "text entry" area under the previously entered object. This area can be preceded (beginning of...
int nbgl_layoutUpdateConfirmationButton(nbgl_layout_t *layout, uint8_t index, bool active, const char *text)
Updates an existing black full width confirmation button on top of the previously added keyboard.
int nbgl_layoutUpdateEnteredText(nbgl_layout_t *layout, uint8_t index, bool numbered, uint8_t number, const char *text, bool grayedOut)
Updates an existing "text entry" area, created with nbgl_layoutAddEnteredText()
int nbgl_layoutUpdateKeyboardContent(nbgl_layout_t *layout, nbgl_layoutKeyboardContent_t *content)
Updates an area containing a potential title, a text entry and either confirmation or suggestion butt...
#define TOP_NORMAL_MARGIN
#define TEXT_ENTRY_COMPACT_HEIGHT
#define TOP_COMPACT_MARGIN
#define NUMBER_TEXT_SPACE
int nbgl_layoutAddConfirmationButton(nbgl_layout_t *layout, bool active, const char *text, int token, tune_index_e tuneId)
Adds a black full width confirmation button on top of the previously added keyboard.
bool nbgl_layoutKeyboardNeedsRefresh(nbgl_layout_t *layout, uint8_t index)
function called to know whether the keyboard has been redrawn and needs a refresh
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_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)
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.
keyboardCase_t
Letters casing in which to open/set the keyboard.
struct PACKED__ nbgl_keyboard_s nbgl_keyboard_t
struct to represent a keyboard (KEYBOARD type)
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)
int nbgl_objPoolGetArray(nbgl_obj_type_t type, uint8_t nbObjs, uint8_t layer, nbgl_obj_t **objArray)
Gets nbObjects new graphic object from the pool, with the given type, for the given layer (screen)....
struct PACKED__ nbgl_button_s nbgl_button_t
struct to represent a button (BUTTON type) that can contain a text and/or an icon
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.
#define KEYBOARD_KEY_HEIGHT
struct PACKED__ nbgl_container_s nbgl_container_t
struct to represent a container (CONTAINER type)
@ CURRENT_INDICATOR
only current page dash is black
struct PACKED__ nbgl_obj_s nbgl_obj_t
Common structure for all graphical objects.
@ RADIUS_32_PIXELS
32 pixels
nbgl_touchType_t
The different types of Touchscreen events.
@ VERTICAL
from top to bottom
@ HORIZONTAL
from left to right
@ NO_ALIGNMENT
used when parent container layout is used
@ IMAGE
Bitmap (y and height must be multiple of 4 on Stax)
@ BUTTON
Rounded rectangle button with icon and/or text.
@ 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)
#define NO_TRANSFORMATION
@ FULL_COLOR_PARTIAL_REFRESH
to be used for small partial refresh (radio buttons, switches)
Structure containing all information about the current layout.
nbgl_container_t * footerContainer
container used to store footer (buttons, nav....)
nbgl_swipe_usage_t swipeUsage
nbgl_container_t * container
nbgl_layoutFooterType_t footerType
type of footer
nbgl_obj_t ** children
children for main screen
This structure contains info to build a keyboard with nbgl_layoutAddKeyboard()
bool lettersOnly
if true, only display letter keys and Backspace
keyboardCallback_t callback
function called when an active key is pressed
keyboardMode_t mode
keyboard mode to start with
keyboardCase_t casing
keyboard casing mode (lower, upper once or upper locked)
This structure contains info to build a keyboard content (controls that are linked to keyboard)
uint8_t number
if numbered is true, number used to build 'number.' text
const char * text
already entered text
nbgl_layoutKeyboardContentType_t type
type of content
nbgl_layoutSuggestionButtons_t suggestionButtons
nbgl_layoutConfirmationButton_t confirmationButton
used if type is KEYBOARD_WITH_SUGGESTIONS
const char * title
centered title explaining the screen
bool numbered
if set to true, the text is preceded on the left by 'number.'
bool grayedOut
if true, the text is grayed out (but not the potential number)