Embedded SDK
Embedded SDK
Loading...
Searching...
No Matches
nbgl_obj_keyboard_nanos.c
Go to the documentation of this file.
1
8#ifdef NBGL_KEYBOARD
9#ifndef HAVE_SE_TOUCH
10
11/*********************
12 * INCLUDES
13 *********************/
14#include <string.h>
15#include "nbgl_debug.h"
16#include "nbgl_front.h"
17#include "nbgl_draw.h"
18#include "nbgl_obj.h"
19#include "nbgl_fonts.h"
20#include "nbgl_touch.h"
21#include "glyphs.h"
22#include "os_io.h"
23
24/*********************
25 * DEFINES
26 *********************/
27
28#define BACKSPACE_KEY_INDEX 26
29#define VALIDATE_INDEX 27
30#define SHIFT_KEY_INDEX 28
31#define LETTER_TO_DIGITS_OFFSET (sizeof(keysByMode[DIGITS_AND_SPECIALS]) - 29)
32#define GET_CHAR(mode, char_idx) ((const char *) PIC(screen_keyboard_keys_by_mode[mode]))[char_idx]
33
34/**********************
35 * TYPEDEFS
36 **********************/
37typedef enum {
38 LOWER_LETTERS,
39 UPPER_LETTERS,
40 DIGITS_AND_SPECIALS
41} KbdMode_t;
42
43/**********************
44 * STATIC PROTOTYPES
45 **********************/
46
47/**********************
48 * STATIC VARIABLES
49 **********************/
50const char *const keysByMode[] = {
51 // when first letter is already entered
52 "abcdefghijklmnopqrstuvwxyz\b\n\r",
53 "ABCDEFGHIJKLMNOPQRSTUVWXYZ\b\n\r",
54 "0123456789 '\"`&/?!:;.,~*$=+-[](){}^<>\\_#@|%\b\n\r",
55};
56
57// these icons will be centered
58const nbgl_icon_details_t *const keyboardIcons[] = {
59 &C_icon_lowercase,
60 &C_icon_uppercase,
61 &C_icon_digits,
62 &C_icon_backspace,
63 &C_icon_validate,
64 &C_icon_classes,
65 &C_icon_lowercase_invert,
66 &C_icon_uppercase_invert,
67 &C_icon_digits_invert,
68 &C_icon_backspace_invert,
69 &C_icon_validate_invert,
70 &C_icon_classes_invert,
71};
72
73static const nbgl_icon_details_t *const modeIcons[] = {
74 &C_icon_lowercase,
75 &C_icon_uppercase,
76 &C_icon_digits,
77};
78
79/**********************
80 * VARIABLES
81 **********************/
82
83/**********************
84 * STATIC FUNCTIONS
85 **********************/
86
87static void keyboardDrawIcon(int16_t x0, int8_t y0, bool inverted, const nbgl_icon_details_t *icon)
88{
89 nbgl_area_t rectArea;
90
91 rectArea.backgroundColor = inverted ? WHITE : BLACK;
92 rectArea.width = icon->width;
93 rectArea.height = icon->height;
94 rectArea.bpp = NBGL_BPP_1;
95 // center
96 rectArea.x0 = x0 + (KEYBOARD_KEY_WIDTH - icon->width) / 2;
97 rectArea.y0 = y0 + (KEYBOARD_KEY_HEIGHT - icon->height) / 2;
98 nbgl_drawIcon(&rectArea, NO_TRANSFORMATION, inverted ? BLACK : WHITE, icon);
99}
100
101static void keyboardDrawChar(int16_t x0, int8_t y0, bool inverted, const char *charPtr)
102{
103 nbgl_area_t rectArea;
104
105 rectArea.backgroundColor = inverted ? WHITE : BLACK;
107 rectArea.height = 12;
108 rectArea.bpp = NBGL_BPP_1;
109 // center
110 rectArea.x0 = x0 + (KEYBOARD_KEY_WIDTH - rectArea.width) / 2;
111 rectArea.y0 = y0 + (KEYBOARD_KEY_HEIGHT - rectArea.height) / 2 - 3;
113 &rectArea, charPtr, 1, BAGL_FONT_OPEN_SANS_EXTRABOLD_11px_1bpp, inverted ? BLACK : WHITE);
114}
115
116static void keyboardDrawCommon(nbgl_keyboard_t *keyboard)
117{
118 nbgl_area_t rectArea;
119
120 // clean full area
121 rectArea.backgroundColor = BLACK;
122 rectArea.x0 = keyboard->obj.area.x0;
123 rectArea.y0 = keyboard->obj.area.y0;
124 rectArea.width = keyboard->obj.area.width;
125 rectArea.height = keyboard->obj.area.height;
126 nbgl_frontDrawRect(&rectArea);
127
128 // draw select 'key' in white
129 rectArea.x0 = keyboard->obj.area.x0 + 2 * KEYBOARD_KEY_WIDTH;
130 rectArea.y0 = keyboard->obj.area.y0;
131 rectArea.width = KEYBOARD_KEY_WIDTH;
132 rectArea.height = keyboard->obj.area.height;
133 nbgl_drawRoundedRect(&rectArea, RADIUS_3_PIXELS, WHITE);
134
135 // draw separating '-' in white
136 rectArea.backgroundColor = WHITE;
137 rectArea.x0 = keyboard->obj.area.x0 + KEYBOARD_KEY_WIDTH + 5;
138 rectArea.y0 = keyboard->obj.area.y0 + 6;
139 rectArea.width = 3;
140 rectArea.height = 1;
141 nbgl_frontDrawRect(&rectArea);
142 rectArea.x0 = keyboard->obj.area.x0 + 3 * KEYBOARD_KEY_WIDTH + 5;
143 nbgl_frontDrawRect(&rectArea);
144}
145
146// draw letters for letters mode
147static void keyboardDrawLettersOnly(nbgl_keyboard_t *keyboard)
148{
149 uint8_t i;
150 const char *keys = keysByMode[keyboard->mode];
151
152 if (keyboard->keyMask == 0x07FFFFFF) {
153 return;
154 }
155
156 keyboardDrawCommon(keyboard);
157
158 // if selectedChar is masked, move to the first unmasked
159 while (keyboard->keyMask & (1 << keyboard->selectedCharIndex)) {
160 if (keyboard->selectedCharIndex < BACKSPACE_KEY_INDEX) {
161 keyboard->selectedCharIndex++;
162 }
163 else {
164 keyboard->selectedCharIndex = 0;
165 }
166 }
167
168 // fill the letters at position middle and right
169 uint8_t j = 1;
170 i = keyboard->selectedCharIndex;
171 while (j < 3) {
172 // use the provided mask to check what letters(+backspace at 27th position) to use
173 if ((keyboard->keyMask & (1 << i)) == 0) {
174 if (i == BACKSPACE_KEY_INDEX) { // backspace
175 keyboardDrawIcon(keyboard->obj.area.x0 + 2 * j * KEYBOARD_KEY_WIDTH,
176 keyboard->obj.area.y0,
177 (j == 1),
178 &C_icon_backspace);
179 }
180 else { // any char
181 keyboardDrawChar(keyboard->obj.area.x0 + 2 * j * KEYBOARD_KEY_WIDTH,
182 keyboard->obj.area.y0,
183 (j == 1),
184 &keys[i]);
185 }
186 j++;
187 }
188 i++;
189 i %= 27;
190 // safe check in case mask is full of 1s
191 if (i == keyboard->selectedCharIndex) {
192 break;
193 }
194 }
195 // fill the letters at left position from end
196 i = (keyboard->selectedCharIndex + 26) % 27;
197 while (true) {
198 if ((keyboard->keyMask & (1 << i)) == 0) {
199 if (i == BACKSPACE_KEY_INDEX) { // backspace
200 keyboardDrawIcon(
201 keyboard->obj.area.x0, keyboard->obj.area.y0, false, &C_icon_backspace);
202 }
203 else { // any char
204 keyboardDrawChar(keyboard->obj.area.x0, keyboard->obj.area.y0, false, &keys[i]);
205 }
206 break;
207 }
208 if (i > 0) {
209 i--;
210 }
211 else {
213 }
214 // safe check in case mask is full of 1s
215 if (i == (keyboard->selectedCharIndex + 26) % 27) {
216 break;
217 }
218 }
219}
220
221// draw letters for regular mode
222static void keyboardDrawRegular(nbgl_keyboard_t *keyboard)
223{
224 int8_t i;
225
226 keyboardDrawCommon(keyboard);
227
228 // if mode is not already defined, display the 3 icons of keyboard modes to let user choose it:
229 // "ab, AB and 0? "
230 if (keyboard->mode == MODE_NONE) {
231 for (i = 0; i < 3; i++) {
232 uint8_t charIndex = (keyboard->selectedCharIndex + 2 + i) % 3;
233 keyboardDrawIcon(keyboard->obj.area.x0 + 2 * i * KEYBOARD_KEY_WIDTH,
234 keyboard->obj.area.y0,
235 (i == 1),
236 modeIcons[charIndex]);
237 }
238 return;
239 }
240
241 const char *keys = keysByMode[keyboard->mode];
242 uint8_t maxLen = strlen(keys);
243
244 // mode is defined, so draw the proper 3 letters (or icons)
245 for (i = 0; i < 3; i++) {
246 uint8_t charIndex = (keyboard->selectedCharIndex + maxLen - 1 + i) % maxLen;
247 if (keys[charIndex] == '\r') {
248 keyboardDrawIcon(keyboard->obj.area.x0 + 2 * i * KEYBOARD_KEY_WIDTH,
249 keyboard->obj.area.y0,
250 (i == 1),
251 &C_icon_classes);
252 }
253 else if (keys[charIndex] == '\n') {
254 keyboardDrawIcon(keyboard->obj.area.x0 + 2 * i * KEYBOARD_KEY_WIDTH,
255 keyboard->obj.area.y0,
256 (i == 1),
257 &C_icon_validate_10);
258 }
259 else if (keys[charIndex] == '\b') {
260 keyboardDrawIcon(keyboard->obj.area.x0 + 2 * i * KEYBOARD_KEY_WIDTH,
261 keyboard->obj.area.y0,
262 (i == 1),
263 &C_icon_backspace);
264 }
265 else {
266 keyboardDrawChar(keyboard->obj.area.x0 + 2 * i * KEYBOARD_KEY_WIDTH,
267 keyboard->obj.area.y0,
268 (i == 1),
269 &keys[charIndex]);
270 }
271 }
272}
273
274/**********************
275 * GLOBAL FUNCTIONS
276 **********************/
277
285void nbgl_keyboardCallback(nbgl_obj_t *obj, nbgl_buttonEvent_t buttonEvent)
286{
287 nbgl_keyboard_t *keyboard = (nbgl_keyboard_t *) obj;
288 uint8_t nbMax;
289
290 LOG_DEBUG(MISC_LOGGER, "nbgl_keyboardCallback(): buttonEvent = %d\n", buttonEvent);
291
292 if (keyboard->mode == MODE_NONE) {
293 nbMax = 2;
294 }
295 else {
296 if (keyboard->lettersOnly) {
297 nbMax = BACKSPACE_KEY_INDEX;
298 }
299 else {
300 nbMax = strlen(keysByMode[keyboard->mode]) - 1;
301 }
302 }
303 if (buttonEvent == BUTTON_BOTH_PRESSED) {
304 if (keyboard->mode == MODE_NONE) {
305 // apply the selected mode
306 keyboard->mode = keyboard->selectedCharIndex;
307 // reset the selected index to start with "a" (or first char of selected mode)
308 keyboard->selectedCharIndex = 0;
309 }
310 else {
311 if (keyboard->lettersOnly) {
312 if ((keyboard->selectedCharIndex < 26)
313 && ((keyboard->keyMask & (1 << keyboard->selectedCharIndex)) == 0)) {
314 const char *keys = keysByMode[keyboard->mode];
315 keyboard->callback(keys[keyboard->selectedCharIndex]);
316 }
317 else if (keyboard->selectedCharIndex == BACKSPACE_KEY_INDEX) { // backspace
318 keyboard->callback(BACKSPACE_KEY);
319 }
320 }
321 else {
322 char key = keysByMode[keyboard->mode][keyboard->selectedCharIndex];
323 if (key == '\r') {
324 // go back to mode choice
325 keyboard->mode = MODE_NONE;
326 // reset the selected index
327 keyboard->selectedCharIndex = 0;
328 nbgl_objDraw((nbgl_obj_t *) keyboard);
329 nbgl_refresh();
330 }
331 else if (key == '\n') {
332 keyboard->callback(VALIDATE_KEY);
333 }
334 else if (key == '\b') {
335 keyboard->callback(BACKSPACE_KEY);
336 }
337 else {
338 keyboard->callback(key);
339 }
340 }
341 return;
342 }
343 }
344 else if (buttonEvent == BUTTON_LEFT_PRESSED) {
345 do {
346 if (keyboard->selectedCharIndex > 0) {
347 keyboard->selectedCharIndex--;
348 }
349 else {
350 keyboard->selectedCharIndex = nbMax;
351 }
352 } while (keyboard->keyMask & (1 << keyboard->selectedCharIndex));
353 }
354 else if (buttonEvent == BUTTON_RIGHT_PRESSED) {
355 do {
356 if (keyboard->selectedCharIndex < nbMax) {
357 keyboard->selectedCharIndex++;
358 }
359 else {
360 keyboard->selectedCharIndex = 0;
361 }
362 } while (keyboard->keyMask & (1 << keyboard->selectedCharIndex));
363 }
364 else {
365 return;
366 }
367 nbgl_objDraw((nbgl_obj_t *) keyboard);
368 nbgl_refresh();
369}
370
377{
378 if (kbd->lettersOnly) {
379 keyboardDrawLettersOnly(kbd);
380 }
381 else {
382 keyboardDrawRegular(kbd);
383 }
384}
385#endif // HAVE_SE_TOUCH
386#endif // NBGL_KEYBOARD
debug traces management
#define LOG_DEBUG(__logger,...)
Definition nbgl_debug.h:86
@ MISC_LOGGER
Definition nbgl_debug.h:39
Middle Level API of the new BOLOS Graphical Library.
void nbgl_drawIcon(nbgl_area_t *area, nbgl_transformation_t transformation, nbgl_color_map_t color_map, const nbgl_icon_details_t *icon)
Helper function to render an icon directly from its nbgl_icon_details_t structure.
Definition nbgl_draw.c:489
nbgl_font_id_e nbgl_drawText(const nbgl_area_t *area, const char *text, uint16_t textLen, nbgl_font_id_e fontId, color_t fontColor)
This function draws the given single-line text, with the given parameters.
Definition nbgl_draw.c:538
void nbgl_drawRoundedRect(const nbgl_area_t *area, nbgl_radius_t radius, color_t innerColor)
This functions draws a rounded corners rectangle (without border), with the given parameters.
Definition nbgl_draw.c:249
uint8_t nbgl_getCharWidth(nbgl_font_id_e fontId, const char *text)
return the width in pixels of the given UTF-8 character
Definition nbgl_fonts.c:362
@ BAGL_FONT_OPEN_SANS_EXTRABOLD_11px_1bpp
Definition nbgl_fonts.h:143
Font screen low-Level driver API, to draw elementary forms.
void nbgl_frontDrawRect(const nbgl_area_t *area)
API to draw all basic graphic objects.
#define BACKSPACE_KEY_INDEX
Definition nbgl_obj.h:41
void nbgl_objDraw(nbgl_obj_t *obj)
This function draws or redraws the given object and its children (recursive version)
Definition nbgl_obj.c:1520
void nbgl_refresh(void)
This functions refreshes the actual screen on display with what has changed since the last refresh.
Definition nbgl_obj.c:1559
struct PACKED__ nbgl_keyboard_s nbgl_keyboard_t
struct to represent a keyboard (KEYBOARD type)
nbgl_buttonEvent_t
Definition nbgl_obj.h:203
@ BUTTON_BOTH_PRESSED
Sent when both buttons are released.
Definition nbgl_obj.h:210
@ BUTTON_LEFT_PRESSED
Sent when Left button is released.
Definition nbgl_obj.h:204
@ BUTTON_RIGHT_PRESSED
Send when Right button is released.
Definition nbgl_obj.h:205
#define BACKSPACE_KEY
Definition nbgl_obj.h:26
void nbgl_objDrawKeyboard(nbgl_keyboard_t *kbd)
This function draws a keyboard object.
#define VALIDATE_KEY
Definition nbgl_obj.h:27
struct PACKED__ nbgl_obj_s nbgl_obj_t
Common structure for all graphical objects.
@ WHITE
Definition nbgl_types.h:124
@ BLACK
Definition nbgl_types.h:121
struct PACKED__ nbgl_icon_details_s nbgl_icon_details_t
Represents all information about an icon.
#define NO_TRANSFORMATION
Definition nbgl_types.h:74
@ NBGL_BPP_1
1 bit per pixel
Definition nbgl_types.h:264
struct PACKED__ nbgl_area_s nbgl_area_t
Represents a rectangle area of the screen.
signed short int16_t
Definition usbd_conf.h:50
unsigned char uint8_t
Definition usbd_conf.h:53
signed char int8_t
Definition usbd_conf.h:49