Embedded SDK
Embedded SDK
nbgl_layout_navigation.c
Go to the documentation of this file.
1 
8 #ifdef HAVE_SE_TOUCH
9 
10 /*********************
11  * INCLUDES
12  *********************/
13 #include "nbgl_debug.h"
14 #include "nbgl_draw.h"
15 #include "nbgl_obj.h"
16 #include "nbgl_layout_internal.h"
17 #include "os_print.h"
18 #include "os_helpers.h"
19 #include "glyphs.h"
20 
21 /*********************
22  * DEFINES
23  *********************/
24 #define INTERNAL_SMALL_MARGIN 8
25 
26 #define BORDER_COLOR WHITE
27 #ifdef TARGET_STAX
28 #define NAVIGATION_HEIGHT 92
29 #define NAV_BUTTON_HEIGHT 80
30 #define NAV_BUTTON_WIDTH 80
31 #else // TARGET_STAX
32 #define NAVIGATION_HEIGHT 96
33 #define NAV_BUTTON_HEIGHT NAVIGATION_HEIGHT
34 #define NAV_BUTTON_WIDTH 104
35 #endif // TARGET_STAX
36 
37 /**********************
38  * TYPEDEFS
39  **********************/
40 enum {
46 };
47 
48 /**********************
49  * STATIC VARIABLES
50  **********************/
51 static char navText[11]; // worst case is "ccc of nnn"
52 
53 /**********************
54  * VARIABLES
55  **********************/
56 
57 /**********************
58  * STATIC PROTOTYPES
59  **********************/
60 
61 static void configButtons(nbgl_container_t *navContainer, uint8_t navNbPages, uint8_t navActivePage)
62 {
63  nbgl_button_t *buttonPrevious = (nbgl_button_t *) navContainer->children[PREVIOUS_PAGE_INDEX];
64  nbgl_button_t *buttonNext = (nbgl_button_t *) navContainer->children[NEXT_PAGE_INDEX];
65 
66  if (buttonPrevious) {
67  buttonPrevious->foregroundColor = (navActivePage == 0) ? LIGHT_GRAY : BLACK;
68  }
69  if (navNbPages > 1) {
70  buttonNext->foregroundColor = (navActivePage == (navNbPages - 1)) ? LIGHT_GRAY : BLACK;
71  }
72 }
73 
74 /**********************
75  * GLOBAL FUNCTIONS
76  **********************/
77 
88  nbgl_touchType_t eventType,
89  uint8_t nbPages,
90  uint8_t *activePage)
91 {
92  // if direct touch of buttons within the navigation bar, the given obj is
93  // the touched object
94  if (eventType == TOUCHED) {
95  nbgl_container_t *navContainer = (nbgl_container_t *) obj->parent;
96 
97  if (obj == navContainer->children[EXIT_BUTTON_INDEX]) {
98  // fake page when Quit button is touched
99  *activePage = EXIT_PAGE;
100  return true;
101  }
102  else if (obj == navContainer->children[PREVIOUS_PAGE_INDEX]) {
103  if (*activePage > 0) {
104  *activePage = *activePage - 1;
105  configButtons(navContainer, nbPages, *activePage);
106  return true;
107  }
108  }
109  else if (obj == navContainer->children[NEXT_PAGE_INDEX]) {
110  if ((nbPages < 2) || (*activePage < (nbPages - 1))) {
111  *activePage = *activePage + 1;
112  configButtons(navContainer, nbPages, *activePage);
113  return true;
114  }
115  }
116  }
117  // otherwise the given object is the navigation container itself
118  else if (eventType == SWIPED_RIGHT) {
119  if (*activePage > 0) {
120  *activePage = *activePage - 1;
121  configButtons((nbgl_container_t *) obj, nbPages, *activePage);
122  return true;
123  }
124  }
125  else if (eventType == SWIPED_LEFT) {
126  if ((nbPages < 2) || (*activePage < (nbPages - 1))) {
127  *activePage = *activePage + 1;
128  configButtons((nbgl_container_t *) obj, nbPages, *activePage);
129  return true;
130  }
131  }
132  return false;
133 }
134 
145  const nbgl_layoutNavigationBar_t *navConfig,
146  uint8_t layer)
147 {
148  nbgl_button_t *button;
149 
150  if (navConfig->withExitKey) {
151  button = (nbgl_button_t *) nbgl_objPoolGet(BUTTON, layer);
152  button->innerColor = WHITE;
153  button->borderColor = BORDER_COLOR;
154  button->obj.area.width = BUTTON_DIAMETER;
155  button->obj.area.height = BUTTON_DIAMETER;
156  button->radius = BUTTON_RADIUS;
157  button->icon = &CLOSE_ICON;
158 #ifdef TARGET_FLEX
159  button->obj.alignmentMarginX = (navConfig->nbPages > 1) ? 8 : 0;
160 #endif // TARGET_FLEX
161 
162  button->obj.alignment = (navConfig->nbPages > 1) ? MID_LEFT : CENTER;
163  button->obj.touchMask = (1 << TOUCHED);
164  button->obj.touchId = BOTTOM_BUTTON_ID;
165  navContainer->children[EXIT_BUTTON_INDEX] = (nbgl_obj_t *) button;
166  }
167  // create previous page button (back)
168  if (navConfig->withBackKey) {
169  button = (nbgl_button_t *) nbgl_objPoolGet(BUTTON, layer);
170  button->innerColor = WHITE;
171  button->borderColor = BORDER_COLOR;
172  button->obj.area.width = NAV_BUTTON_WIDTH;
173  button->obj.area.height = NAV_BUTTON_HEIGHT;
174  button->radius = BUTTON_RADIUS;
175  button->icon = &CHEVRON_BACK_ICON;
176  // align on the right of the container, leaving space for "Next" button
177  button->obj.alignment = MID_RIGHT;
178  button->obj.alignmentMarginX = NAV_BUTTON_WIDTH;
179  button->obj.touchMask = (1 << TOUCHED);
180  button->obj.touchId = LEFT_BUTTON_ID;
181  navContainer->children[PREVIOUS_PAGE_INDEX] = (nbgl_obj_t *) button;
182  }
183 
184  // create next page button
185  button = (nbgl_button_t *) nbgl_objPoolGet(BUTTON, layer);
186  button->innerColor = WHITE;
187  button->borderColor = BORDER_COLOR;
188  button->foregroundColor = BLACK;
189  button->obj.area.width = NAV_BUTTON_WIDTH;
190  button->obj.area.height = NAV_BUTTON_HEIGHT;
191  button->radius = BUTTON_RADIUS;
192  button->icon = &CHEVRON_NEXT_ICON;
193  button->obj.alignment = MID_RIGHT;
194  button->obj.touchMask = (1 << TOUCHED);
195  button->obj.touchId = RIGHT_BUTTON_ID;
196  navContainer->children[NEXT_PAGE_INDEX] = (nbgl_obj_t *) button;
197 
198  // potentially create page indicator (with a text area, and "page of nb_page")
199  if (navConfig->withPageIndicator) {
200  if (navConfig->visibleIndicator) {
202  uint16_t marginX = (NAV_BUTTON_WIDTH - CHEVRON_NEXT_ICON.width) / 2;
203 
204  SPRINTF(navText, "%d of %d", navConfig->activePage + 1, navConfig->nbPages);
205 
206  textArea->textColor = DARK_GRAY;
207  // the max width is the width of the whole container, but not overriding the < and >
208  // icons
209  textArea->obj.area.width
210  = navContainer->obj.area.width - (2 * (marginX + CHEVRON_NEXT_ICON.width));
211  textArea->text = navText;
212  textArea->fontId = SMALL_REGULAR_FONT;
213  textArea->obj.area.height = NAV_BUTTON_HEIGHT;
214  textArea->textAlignment = CENTER;
215  textArea->obj.alignment = CENTER;
216  navContainer->children[PAGE_INDICATOR_INDEX] = (nbgl_obj_t *) textArea;
217  }
218  if (navConfig->withBackKey) {
219  navContainer->children[PREVIOUS_PAGE_INDEX]->alignmentMarginX += 79;
220  }
221  }
222 
223  // configure enabling/disabling of button
224  configButtons(navContainer, navConfig->nbPages, navConfig->activePage);
225 
226  return;
227 }
228 
229 #endif // HAVE_SE_TOUCH
debug traces management
Middle Level API of the new BOLOS Graphical Library.
#define EXIT_PAGE
Definition: nbgl_layout.h:38
Internal functions/constants of NBGL layout layer.
@ PAGE_INDICATOR_INDEX
@ NB_MAX_CHILDREN
@ NEXT_PAGE_INDEX
@ EXIT_BUTTON_INDEX
@ PREVIOUS_PAGE_INDEX
#define NAV_BUTTON_HEIGHT
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 BORDER_COLOR
#define NAV_BUTTON_WIDTH
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_text_area_s nbgl_text_area_t
struct to represent a text area (TEXT_AREA type)
#define CHEVRON_BACK_ICON
Definition: nbgl_obj.h:141
#define CHEVRON_NEXT_ICON
Definition: nbgl_obj.h:142
#define BUTTON_RADIUS
Definition: nbgl_obj.h:87
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 BUTTON_DIAMETER
Definition: nbgl_obj.h:88
struct PACKED__ nbgl_container_s nbgl_container_t
struct to represent a container (CONTAINER type)
@ LEFT_BUTTON_ID
Definition: nbgl_obj.h:546
@ RIGHT_BUTTON_ID
Definition: nbgl_obj.h:547
@ BOTTOM_BUTTON_ID
Definition: nbgl_obj.h:545
#define CLOSE_ICON
Definition: nbgl_obj.h:143
struct PACKED__ nbgl_obj_s nbgl_obj_t
Common structure for all graphical objects.
@ WHITE
Definition: nbgl_types.h:105
@ DARK_GRAY
Definition: nbgl_types.h:103
@ LIGHT_GRAY
Definition: nbgl_types.h:104
@ BLACK
Definition: nbgl_types.h:102
nbgl_touchType_t
The different types of Touchscreen events.
Definition: nbgl_types.h:220
@ SWIPED_LEFT
Definition: nbgl_types.h:236
@ SWIPED_RIGHT
Definition: nbgl_types.h:235
@ TOUCHED
Definition: nbgl_types.h:221
@ CENTER
Definition: nbgl_types.h:146
@ MID_RIGHT
Definition: nbgl_types.h:147
@ MID_LEFT
Definition: nbgl_types.h:145
@ BUTTON
Rounded rectangle button with icon and/or text.
Definition: nbgl_types.h:121
@ TEXT_AREA
Area to contain text line(s)
Definition: nbgl_types.h:120
This structure contains info to build a navigation bar at the bottom of the screen.
Definition: nbgl_layout.h:118
uint8_t activePage
index of active page (from 0 to nbPages-1).
Definition: nbgl_layout.h:121
bool withBackKey
if set to true, the "back" key is drawn
Definition: nbgl_layout.h:123
bool withExitKey
if set to true, an exit button is drawn (X on the left)
Definition: nbgl_layout.h:122
uint8_t nbPages
number of pages. (if 0, no navigation)
Definition: nbgl_layout.h:120
unsigned short uint16_t
Definition: usbd_conf.h:54
unsigned char uint8_t
Definition: usbd_conf.h:53