Embedded SDK
Embedded SDK
Loading...
Searching...
No Matches
nbgl_obj_keyboard.c
Go to the documentation of this file.
1
8#ifdef NBGL_KEYBOARD
9#ifdef HAVE_SE_TOUCH
10
11/*********************
12 * INCLUDES
13 *********************/
14#include "nbgl_debug.h"
15#include "nbgl_front.h"
16#include "nbgl_draw.h"
17#include "nbgl_obj.h"
18#include "nbgl_fonts.h"
19#include "nbgl_touch.h"
20#include "glyphs.h"
21#include "os_io_seph_cmd.h"
22#include "os_io_seph_ux.h"
23
24/*********************
25 * DEFINES
26 *********************/
27
28#define FIRST_LINE_CHAR_COUNT 10
29#define SECOND_LINE_CHAR_COUNT 9
30
31#if (SCREEN_WIDTH == 400)
32#define NORMAL_KEY_WIDTH 40
33#define LETTER_OFFSET_Y ((KEYBOARD_KEY_HEIGHT - 32) / 2)
34#elif (SCREEN_WIDTH == 480)
35#define NORMAL_KEY_WIDTH 48
36#define LETTER_OFFSET_Y ((KEYBOARD_KEY_HEIGHT - 36) / 2)
37#elif (SCREEN_WIDTH == 300)
38#define NORMAL_KEY_WIDTH 30
39#define LETTER_OFFSET_Y ((KEYBOARD_KEY_HEIGHT - 22) / 2)
40#endif
41#define SHIFT_KEY_WIDTH (NORMAL_KEY_WIDTH + SECOND_LINE_OFFSET)
42#define SECOND_LINE_OFFSET ((SCREEN_WIDTH - (SECOND_LINE_CHAR_COUNT * NORMAL_KEY_WIDTH)) / 2)
43#if defined(TARGET_STAX)
44#define SPACE_KEY_WIDTH 276
45#elif defined(TARGET_FLEX)
46#define SPACE_KEY_WIDTH 336
47#elif defined(TARGET_APEX)
48#define SPACE_KEY_WIDTH 209
49#endif // TARGETS
50#define SWITCH_KEY_WIDTH (SCREEN_WIDTH - SPACE_KEY_WIDTH)
51#define SPECIAL_CHARS_KEY_WIDTH (NORMAL_KEY_WIDTH * 2 + SECOND_LINE_OFFSET)
52#define BACKSPACE_KEY_WIDTH_FULL SHIFT_KEY_WIDTH
53#define BACKSPACE_KEY_WIDTH_DIGITS SPECIAL_CHARS_KEY_WIDTH
54#define BACKSPACE_KEY_WIDTH_LETTERS_ONLY (SCREEN_WIDTH - 7 * NORMAL_KEY_WIDTH)
55
56#define IS_KEY_MASKED(_index) (keyboard->keyMask & (1 << _index))
57
58/**********************
59 * TYPEDEFS
60 **********************/
61
62/**********************
63 * STATIC PROTOTYPES
64 **********************/
65
66/**********************
67 * STATIC VARIABLES
68 **********************/
69static const char kbd_chars[] = "qwertyuiopasdfghjklzxcvbnm";
70static const char kbd_chars_upper[] = "QWERTYUIOPASDFGHJKLZXCVBNM";
71const char kbd_digits[] = "1234567890-/:;()&@\".,?!\'";
72static const char kbd_specials[] = "[]{}#%^*+=_\\|~<>$`\".,?!\'";
73
74/**********************
75 * VARIABLES
76 **********************/
77
78/**********************
79 * STATIC FUNCTIONS
80 **********************/
81static uint8_t getKeyboardIndex(nbgl_keyboard_t *keyboard, nbgl_touchStatePosition_t *position)
82{
83 uint8_t i = 0;
84 // get index of key pressed
85 if (position->y < KEYBOARD_KEY_HEIGHT) {
86 // 1st row:
87 i = position->x / NORMAL_KEY_WIDTH;
88 }
89 else if (position->y < (2 * KEYBOARD_KEY_HEIGHT)) {
90 // 2nd row:
91 i = FIRST_LINE_CHAR_COUNT + (position->x - SECOND_LINE_OFFSET) / NORMAL_KEY_WIDTH;
94 }
95 }
96 else if (position->y < (3 * KEYBOARD_KEY_HEIGHT)) {
97 // 3rd row:
98 if (keyboard->mode == MODE_LETTERS) {
99 // shift does not exist in letters only mode
100 if (!keyboard->lettersOnly) {
101 if (position->x < SHIFT_KEY_WIDTH) {
102 i = SHIFT_KEY_INDEX;
103 }
104 else {
106 + (position->x - SHIFT_KEY_WIDTH) / NORMAL_KEY_WIDTH;
107 // Backspace key is a bit larger...
108 if (i >= 26) {
110 }
111 }
112 }
113 else {
114 i = FIRST_LINE_CHAR_COUNT + SECOND_LINE_CHAR_COUNT + position->x / NORMAL_KEY_WIDTH;
115 // Backspace key is larger...
116 if (i >= 26) {
118 }
119 }
120 }
121 else {
122 if (position->x < SPECIAL_CHARS_KEY_WIDTH) {
124 }
125 else {
127 + (position->x - SPECIAL_CHARS_KEY_WIDTH) / NORMAL_KEY_WIDTH;
128 // Backspace key is a bit larger...
129 if (i >= 24) {
131 }
132 }
133 }
134 }
135 else if (!keyboard->lettersOnly && (position->y < (4 * KEYBOARD_KEY_HEIGHT))) {
136 // 4th row
137 if (position->x < SWITCH_KEY_WIDTH) {
139 }
140 else {
141 i = SPACE_KEY_INDEX;
142 }
143 }
144 return i;
145}
146
147// draw parts common to all modes of keyboard
148static void keyboardDrawCommonLines(nbgl_keyboard_t *keyboard)
149{
150 nbgl_area_t rectArea;
151
152 // clean full area
153 rectArea.backgroundColor = keyboard->obj.area.backgroundColor;
154 rectArea.x0 = keyboard->obj.area.x0;
155 rectArea.y0 = keyboard->obj.area.y0;
156 rectArea.width = keyboard->obj.area.width;
157 rectArea.height = keyboard->obj.area.height;
158 nbgl_frontDrawRect(&rectArea);
159
161 rectArea.backgroundColor = keyboard->obj.area.backgroundColor;
162 rectArea.x0 = keyboard->obj.area.x0;
163 rectArea.y0 = keyboard->obj.area.y0;
164 rectArea.width = keyboard->obj.area.width;
165 rectArea.height = 1;
166 nbgl_frontDrawLine(&rectArea, 0, keyboard->borderColor); // 1st line (top)
167 rectArea.y0 += KEYBOARD_KEY_HEIGHT;
168 nbgl_frontDrawLine(&rectArea, 0, keyboard->borderColor); // 2nd line
169 rectArea.y0 += KEYBOARD_KEY_HEIGHT;
170 nbgl_frontDrawLine(&rectArea, 0, keyboard->borderColor); // 3rd line
171 // in letter only mode, only draw the last line if not at bottom of screen
172 if ((keyboard->obj.alignmentMarginY > 0) || (!keyboard->lettersOnly)) {
173 rectArea.y0 += KEYBOARD_KEY_HEIGHT;
174 nbgl_frontDrawLine(&rectArea, 0, keyboard->borderColor); // 4th line
175 }
176 // in non letter only mode, only draw the last line if not at bottom of screen
177 if ((keyboard->obj.alignmentMarginY > 0) && (!keyboard->lettersOnly)) {
178 rectArea.y0 += KEYBOARD_KEY_HEIGHT;
179 nbgl_frontDrawLine(&rectArea, 0, keyboard->borderColor); // 5th line
180 }
181#ifdef TARGET_STAX
183 rectArea.x0 = keyboard->obj.area.x0;
184 rectArea.y0 = keyboard->obj.area.y0;
185 rectArea.width = 1;
186 rectArea.height = KEYBOARD_KEY_HEIGHT * 3;
187 if (!keyboard->lettersOnly) {
188 rectArea.height += KEYBOARD_KEY_HEIGHT;
189 }
190 nbgl_frontDrawLine(&rectArea, 0, keyboard->borderColor); // 1st full line, on the left
191#endif // TARGET_STAX
192}
193
194// draw full grid for letters mode
195static void keyboardDrawLetterGrid(nbgl_keyboard_t *keyboard)
196{
197 nbgl_area_t rectArea;
198 uint8_t i;
199
201 keyboardDrawCommonLines(keyboard);
202
203 // then all vertical lines separating keys
204 rectArea.backgroundColor = keyboard->obj.area.backgroundColor;
205 rectArea.x0 = keyboard->obj.area.x0;
206 rectArea.y0 = keyboard->obj.area.y0;
207 rectArea.width = 1;
208 rectArea.height = KEYBOARD_KEY_HEIGHT;
209 // First row of keys: 10 letters (qwertyuiop)
210 for (i = 0; i < 9; i++) {
211 rectArea.x0 += NORMAL_KEY_WIDTH;
212 nbgl_frontDrawLine(&rectArea, 0, keyboard->borderColor);
213 }
214
215 // Second row: 9 letters (asdfghjkl)
216 rectArea.x0 = keyboard->obj.area.x0 + SECOND_LINE_OFFSET;
217 rectArea.y0 += KEYBOARD_KEY_HEIGHT;
218 nbgl_frontDrawLine(&rectArea, 0, keyboard->borderColor);
219 for (i = 10; i < 19; i++) {
220 rectArea.x0 += NORMAL_KEY_WIDTH;
221 nbgl_frontDrawLine(&rectArea, 0, keyboard->borderColor);
222 }
223 // Third row: Shift key, 7 letters (zxcvbnm) and backspace in normal mode
224 // Third row: 7 letters (zxcvbnm) and backspace in letters only mode
225 rectArea.y0 += KEYBOARD_KEY_HEIGHT;
226 if (!keyboard->lettersOnly) {
227 rectArea.x0 = keyboard->obj.area.x0 + SHIFT_KEY_WIDTH;
228 }
229 else {
230 rectArea.x0 = NORMAL_KEY_WIDTH;
231 }
232 for (i = 0; i < 6; i++) {
233 nbgl_frontDrawLine(&rectArea, 0, keyboard->borderColor);
234 rectArea.x0 += NORMAL_KEY_WIDTH;
235 }
236 if (!keyboard->lettersOnly) {
237 nbgl_frontDrawLine(&rectArea, 0, keyboard->borderColor);
238 rectArea.x0 += NORMAL_KEY_WIDTH;
239 }
240 nbgl_frontDrawLine(&rectArea, 0, keyboard->borderColor);
241
242 // 4th row, only in Full mode
243 if (!keyboard->lettersOnly) {
244 rectArea.y0 += KEYBOARD_KEY_HEIGHT;
245 rectArea.x0 = keyboard->obj.area.x0 + SWITCH_KEY_WIDTH;
246 nbgl_frontDrawLine(&rectArea, 0, keyboard->borderColor);
247 }
248}
249
250// draw full grid for digits/special mode
251static void keyboardDrawDigitsGrid(nbgl_keyboard_t *keyboard)
252{
253 nbgl_area_t rectArea;
254 uint8_t i;
255
257 keyboardDrawCommonLines(keyboard);
258
259 // then all vertical lines separating keys
260 rectArea.backgroundColor = keyboard->obj.area.backgroundColor;
261 rectArea.x0 = keyboard->obj.area.x0;
262 rectArea.y0 = keyboard->obj.area.y0;
263 rectArea.width = 1;
264 rectArea.height = KEYBOARD_KEY_HEIGHT;
265 // First row of keys: 10 keys so 9 separations
266 for (i = 0; i < 9; i++) {
267 rectArea.x0 += NORMAL_KEY_WIDTH;
268 nbgl_frontDrawLine(&rectArea, 0, keyboard->borderColor);
269 }
270
271 // Second row: 9 keys
272 rectArea.x0 = keyboard->obj.area.x0 + SECOND_LINE_OFFSET;
273 rectArea.y0 += KEYBOARD_KEY_HEIGHT;
274 nbgl_frontDrawLine(&rectArea, 0, keyboard->borderColor);
275 for (i = 10; i < 19; i++) {
276 rectArea.x0 += NORMAL_KEY_WIDTH;
277 nbgl_frontDrawLine(&rectArea, 0, keyboard->borderColor);
278 }
279 // Third row: Special char key, 5 keys and backspace
280 rectArea.x0 = keyboard->obj.area.x0 + SPECIAL_CHARS_KEY_WIDTH;
281 rectArea.y0 += KEYBOARD_KEY_HEIGHT;
282 nbgl_frontDrawLine(&rectArea, 0, keyboard->borderColor);
283 for (i = 0; i < 5; i++) {
284 rectArea.x0 += NORMAL_KEY_WIDTH;
285 nbgl_frontDrawLine(&rectArea, 0, keyboard->borderColor);
286 }
287
288 // 4th row, switch to letters and space
289 rectArea.y0 += KEYBOARD_KEY_HEIGHT;
290 rectArea.x0 = keyboard->obj.area.x0 + SWITCH_KEY_WIDTH;
291 nbgl_frontDrawLine(&rectArea, 0, keyboard->borderColor);
292}
293
294// draw letters for letters mode
295static void keyboardDrawLetters(nbgl_keyboard_t *keyboard)
296{
297 uint8_t i;
298 nbgl_area_t rectArea;
299 const char *keys;
300
301 if (keyboard->casing != LOWER_CASE) {
302 keys = kbd_chars_upper;
303 }
304 else {
305 keys = kbd_chars;
306 }
307
308 rectArea.backgroundColor = keyboard->obj.area.backgroundColor;
309 rectArea.y0 = keyboard->obj.area.y0 + LETTER_OFFSET_Y;
310 rectArea.width = 1;
311 rectArea.height = KEYBOARD_KEY_HEIGHT * 3;
312 rectArea.x0 = keyboard->obj.area.x0;
313
314 // First row of keys: 10 letters (qwertyuiop)
315 for (i = 0; i < 10; i++) {
316 rectArea.x0 = keyboard->obj.area.x0 + i * NORMAL_KEY_WIDTH;
317
318 rectArea.x0
319 += (NORMAL_KEY_WIDTH - nbgl_getCharWidth(SMALL_REGULAR_1BPP_FONT, &keys[i])) / 2;
321 &rectArea, &keys[i], 1, SMALL_REGULAR_1BPP_FONT, (IS_KEY_MASKED(i)) ? WHITE : BLACK);
322 }
323 // Second row: 9 letters (asdfghjkl)
324 rectArea.y0 += KEYBOARD_KEY_HEIGHT;
325 for (i = 10; i < 19; i++) {
326 rectArea.x0 = keyboard->obj.area.x0 + SECOND_LINE_OFFSET + (i - 10) * NORMAL_KEY_WIDTH;
327 rectArea.x0
328 += (NORMAL_KEY_WIDTH - nbgl_getCharWidth(SMALL_REGULAR_1BPP_FONT, &keys[i])) / 2;
330 &rectArea, &keys[i], 1, SMALL_REGULAR_1BPP_FONT, (IS_KEY_MASKED(i)) ? WHITE : BLACK);
331 }
332 // Third row: Shift key, 7 letters (zxcvbnm) and backspace
333 rectArea.y0 += KEYBOARD_KEY_HEIGHT;
334 uint16_t offsetX;
335 if (!keyboard->lettersOnly) {
336 // draw background rectangle
337#if defined(TARGET_STAX)
338 rectArea.width = SHIFT_KEY_WIDTH - 1;
339 rectArea.height = KEYBOARD_KEY_HEIGHT;
340 rectArea.x0 = 1;
341#elif defined(TARGET_FLEX)
342 rectArea.width = SHIFT_KEY_WIDTH;
343 rectArea.height = KEYBOARD_KEY_HEIGHT;
344 rectArea.x0 = 0;
345#elif defined(TARGET_APEX)
346 if (keyboard->casing == LOWER_CASE) {
347 rectArea.width = SHIFT_KEY_WIDTH;
348 }
349 else {
350 rectArea.width = SHIFT_KEY_WIDTH + 1;
351 }
352 rectArea.height = KEYBOARD_KEY_HEIGHT + 1;
353 rectArea.x0 = 0;
354#endif
355 rectArea.bpp = NBGL_BPP_1;
356 rectArea.y0 = keyboard->obj.area.y0 + KEYBOARD_KEY_HEIGHT * 2;
357 rectArea.backgroundColor = (keyboard->casing != LOWER_CASE) ? BLACK : WHITE;
358 nbgl_frontDrawRect(&rectArea);
359
360 // draw top & bottom horizontal lines (on Apex, only if in lower case)
361#ifdef TARGET_APEX
362 if (keyboard->casing == LOWER_CASE)
363#endif
364 {
365 rectArea.width = SHIFT_KEY_WIDTH - 1;
366 rectArea.height = 1;
367 rectArea.x0 = 1;
368 rectArea.y0 = keyboard->obj.area.y0 + KEYBOARD_KEY_HEIGHT * 2;
369 rectArea.backgroundColor = (keyboard->casing != LOWER_CASE) ? BLACK : WHITE;
370 nbgl_frontDrawLine(&rectArea, 0, keyboard->borderColor);
371 rectArea.y0 += KEYBOARD_KEY_HEIGHT;
372 rectArea.backgroundColor = WHITE;
373 nbgl_frontDrawLine(&rectArea, 0, keyboard->borderColor);
374 }
375 // draw Shift key
376 rectArea.width = SHIFT_ICON.width;
377 rectArea.height = SHIFT_ICON.height;
378 rectArea.bpp = NBGL_BPP_1;
379 rectArea.y0 = (keyboard->obj.area.y0 + KEYBOARD_KEY_HEIGHT * 2
380 + (KEYBOARD_KEY_HEIGHT - rectArea.height) / 2);
381 rectArea.x0 = (SHIFT_KEY_WIDTH - rectArea.width) / 2;
383 rectArea.backgroundColor = WHITE;
384 nbgl_drawIcon(&rectArea, NO_TRANSFORMATION, WHITE, &SHIFT_LOCKED_ICON);
385 }
386 else {
387 rectArea.backgroundColor = (keyboard->casing != LOWER_CASE) ? BLACK : WHITE;
389 &rectArea,
391 (keyboard->casing != LOWER_CASE) ? WHITE : BLACK,
392 (keyboard->casing == LOCKED_UPPER_CASE) ? (&SHIFT_LOCKED_ICON) : (&SHIFT_ICON));
393 rectArea.backgroundColor = WHITE;
394 }
395 offsetX = keyboard->obj.area.x0 + SHIFT_KEY_WIDTH;
396 }
397 else {
398 offsetX = 0;
399 }
400 rectArea.y0 = keyboard->obj.area.y0 + KEYBOARD_KEY_HEIGHT * 2 + LETTER_OFFSET_Y;
401 for (i = 19; i < 26; i++) {
402 rectArea.x0 = offsetX + (i - 19) * NORMAL_KEY_WIDTH;
403 rectArea.x0
404 += (NORMAL_KEY_WIDTH - nbgl_getCharWidth(SMALL_REGULAR_1BPP_FONT, &keys[i])) / 2;
406 &rectArea, &keys[i], 1, SMALL_REGULAR_1BPP_FONT, (IS_KEY_MASKED(i)) ? WHITE : BLACK);
407 }
408 // draw backspace
409 rectArea.width = BACKSPACE_ICON.width;
410 rectArea.height = BACKSPACE_ICON.height;
411 rectArea.bpp = NBGL_BPP_1;
412 rectArea.x0 = offsetX + 7 * NORMAL_KEY_WIDTH;
413 rectArea.y0 = (keyboard->obj.area.y0 + KEYBOARD_KEY_HEIGHT * 2
414 + (KEYBOARD_KEY_HEIGHT - rectArea.height) / 2);
415 if (!keyboard->lettersOnly) {
416 rectArea.x0 += (BACKSPACE_KEY_WIDTH_FULL - rectArea.width) / 2;
417 }
418 else {
419 rectArea.x0 += (BACKSPACE_KEY_WIDTH_LETTERS_ONLY - rectArea.width) / 2;
420 }
421 nbgl_drawIcon(&rectArea,
424 &BACKSPACE_ICON);
425
426 // 4th row, only in Full mode
427 if (!keyboard->lettersOnly) {
428 rectArea.x0 = (SWITCH_KEY_WIDTH - nbgl_getTextWidth(SMALL_REGULAR_1BPP_FONT, ".?123")) / 2;
429 rectArea.y0 = keyboard->obj.area.y0 + KEYBOARD_KEY_HEIGHT * 3 + LETTER_OFFSET_Y;
430 nbgl_drawText(&rectArea,
431 ".?123",
432 5,
433 SMALL_REGULAR_1BPP_FONT,
435
436 rectArea.x0 = SWITCH_KEY_WIDTH + (SPACE_KEY_WIDTH - SPACE_ICON.width) / 2;
437 nbgl_drawIcon(&rectArea,
440 &SPACE_ICON);
441 }
442}
443
444// draw digits/special chars for digits/special mode
445static void keyboardDrawDigits(nbgl_keyboard_t *keyboard)
446{
447 uint8_t i;
448 nbgl_area_t rectArea;
449 const char *keys;
450
451 if (keyboard->mode == MODE_DIGITS) {
452 keys = kbd_digits;
453 }
454 else {
455 keys = kbd_specials;
456 }
457
458 rectArea.backgroundColor = keyboard->obj.area.backgroundColor;
459 rectArea.y0 = keyboard->obj.area.y0 + LETTER_OFFSET_Y;
460 rectArea.width = 1;
461 rectArea.height = KEYBOARD_KEY_HEIGHT * 3;
462 rectArea.x0 = keyboard->obj.area.x0;
463
464 // First row of keys: 10 digits (1234567890)
465 for (i = 0; i < 10; i++) {
466 rectArea.x0 = keyboard->obj.area.x0 + i * NORMAL_KEY_WIDTH;
467 rectArea.x0
468 += (NORMAL_KEY_WIDTH - nbgl_getCharWidth(SMALL_REGULAR_1BPP_FONT, &keys[i])) / 2;
470 &rectArea, &keys[i], 1, SMALL_REGULAR_1BPP_FONT, (IS_KEY_MASKED(i)) ? WHITE : BLACK);
471 }
472 // Second row: 9 keys ()
473 rectArea.y0 += KEYBOARD_KEY_HEIGHT;
474 for (i = 10; i < 19; i++) {
475 rectArea.x0 = keyboard->obj.area.x0 + (i - 10) * NORMAL_KEY_WIDTH + SECOND_LINE_OFFSET;
476 rectArea.x0
477 += (NORMAL_KEY_WIDTH - nbgl_getCharWidth(SMALL_REGULAR_1BPP_FONT, &keys[i])) / 2;
479 &rectArea, &keys[i], 1, SMALL_REGULAR_1BPP_FONT, (IS_KEY_MASKED(i)) ? WHITE : BLACK);
480 }
481 // Third row: special key, 5 keys and backspace
482
483 // draw "#+=" key
484 if (keyboard->mode == MODE_DIGITS) {
485 rectArea.x0
486 = (SPECIAL_CHARS_KEY_WIDTH - nbgl_getTextWidth(SMALL_REGULAR_1BPP_FONT, "#+=")) / 2;
487 rectArea.y0 = keyboard->obj.area.y0 + KEYBOARD_KEY_HEIGHT * 2 + LETTER_OFFSET_Y;
488 nbgl_drawText(&rectArea, "#+=", 3, SMALL_REGULAR_1BPP_FONT, BLACK);
489 }
490 else {
491 rectArea.x0
492 = (SPECIAL_CHARS_KEY_WIDTH - nbgl_getTextWidth(SMALL_REGULAR_1BPP_FONT, "123")) / 2;
493 rectArea.y0 = keyboard->obj.area.y0 + KEYBOARD_KEY_HEIGHT * 2 + LETTER_OFFSET_Y;
494 nbgl_drawText(&rectArea, "123", 3, SMALL_REGULAR_1BPP_FONT, BLACK);
495 }
496
497 for (i = 19; i < 24; i++) {
498 rectArea.x0 = SPECIAL_CHARS_KEY_WIDTH + (i - 19) * NORMAL_KEY_WIDTH;
499 rectArea.x0
500 += (NORMAL_KEY_WIDTH - nbgl_getCharWidth(SMALL_REGULAR_1BPP_FONT, &keys[i])) / 2;
502 &rectArea, &keys[i], 1, SMALL_REGULAR_1BPP_FONT, (IS_KEY_MASKED(i)) ? WHITE : BLACK);
503 }
504 // draw backspace
505 rectArea.width = BACKSPACE_ICON.width;
506 rectArea.height = BACKSPACE_ICON.height;
507 rectArea.bpp = NBGL_BPP_1;
508 rectArea.x0 = SPECIAL_CHARS_KEY_WIDTH + 5 * NORMAL_KEY_WIDTH;
509 rectArea.y0 = keyboard->obj.area.y0 + KEYBOARD_KEY_HEIGHT * 2
510 + ((KEYBOARD_KEY_HEIGHT - rectArea.height) / 2);
511 rectArea.x0 += (BACKSPACE_KEY_WIDTH_DIGITS - rectArea.width) / 2;
512 nbgl_drawIcon(&rectArea, NO_TRANSFORMATION, BLACK, &BACKSPACE_ICON);
513
514 // 4th row
515 rectArea.x0 = (SWITCH_KEY_WIDTH - nbgl_getTextWidth(SMALL_REGULAR_1BPP_FONT, "ABC")) / 2;
516 rectArea.y0 = keyboard->obj.area.y0 + KEYBOARD_KEY_HEIGHT * 3 + LETTER_OFFSET_Y;
517 nbgl_drawText(&rectArea, "ABC", 3, SMALL_REGULAR_1BPP_FONT, BLACK);
518
519 rectArea.x0 = SWITCH_KEY_WIDTH + (SPACE_KEY_WIDTH - SPACE_ICON.width) / 2;
520 nbgl_drawIcon(&rectArea,
523 &SPACE_ICON);
524}
525
526static void keyboardDraw(nbgl_keyboard_t *keyboard)
527{
528 if (keyboard->mode == MODE_LETTERS) {
529 // At first, draw grid
530 keyboardDrawLetterGrid(keyboard);
531
532 // then draw key content
533 keyboardDrawLetters(keyboard);
534 }
535 else {
537 keyboardDrawDigitsGrid(keyboard);
538
540 keyboardDrawDigits(keyboard);
541 }
542}
543
544/**********************
545 * GLOBAL FUNCTIONS
546 **********************/
547
556{
557 uint8_t firstIndex, lastIndex;
558 nbgl_touchStatePosition_t *firstPosition, *lastPosition;
559 nbgl_keyboard_t *keyboard = (nbgl_keyboard_t *) obj;
560
561 LOG_DEBUG(MISC_LOGGER, "keyboardTouchCallback(): eventType = %d\n", eventType);
562 if (eventType != TOUCHED) {
563 return;
564 }
565 if (nbgl_touchGetTouchedPosition(obj, &firstPosition, &lastPosition) == false) {
566 return;
567 }
568 // modify positions with keyboard position
569 firstPosition->x -= obj->area.x0;
570 firstPosition->y -= obj->area.y0;
571 lastPosition->x -= obj->area.x0;
572 lastPosition->y -= obj->area.y0;
573
574 firstIndex = getKeyboardIndex(keyboard, firstPosition);
575 if (firstIndex > SPECIAL_KEYS_INDEX) {
576 return;
577 }
578 lastIndex = getKeyboardIndex(keyboard, lastPosition);
579 if (lastIndex > SPECIAL_KEYS_INDEX) {
580 return;
581 }
582 // if position of finger has moved durinng press to another "key", drop it
583 if (lastIndex != firstIndex) {
584 return;
585 }
586
587 if (keyboard->mode == MODE_LETTERS) {
588 keyboardCase_t cur_casing = keyboard->casing;
589 // if the casing mode was upper (not-locked), go back to lower case
590 if ((keyboard->casing == UPPER_CASE) && (firstIndex != SHIFT_KEY_INDEX)
591 && ((IS_KEY_MASKED(firstIndex)) == 0)) {
592 keyboard->casing = LOWER_CASE;
593 // just redraw, refresh will be done by client (user of keyboard)
594 nbgl_objDraw((nbgl_obj_t *) keyboard);
595 keyboard->needsRefresh = true;
596 }
597 if ((firstIndex < 26) && ((IS_KEY_MASKED(firstIndex)) == 0)) {
598 keyboard->callback((cur_casing != LOWER_CASE) ? kbd_chars_upper[firstIndex]
599 : kbd_chars[firstIndex]);
600 }
601 else if (firstIndex == SHIFT_KEY_INDEX) {
602 switch (keyboard->casing) {
603 case LOWER_CASE:
604 keyboard->casing = UPPER_CASE;
605 break;
606 case UPPER_CASE:
607 keyboard->casing = LOCKED_UPPER_CASE;
608 break;
610 keyboard->casing = LOWER_CASE;
611 break;
612 }
613 nbgl_objDraw((nbgl_obj_t *) keyboard);
616 }
617 else if (firstIndex == DIGITS_SWITCH_KEY_INDEX) { // switch to digits
618 keyboard->mode = MODE_DIGITS;
619 nbgl_objDraw((nbgl_obj_t *) keyboard);
621 }
622 }
623 else if (keyboard->mode == MODE_DIGITS) {
624 if (firstIndex < 26) {
625 keyboard->callback(kbd_digits[firstIndex]);
626 }
627 else if (firstIndex == SPECIAL_KEYS_INDEX) {
628 keyboard->mode = MODE_SPECIAL;
629 nbgl_objDraw((nbgl_obj_t *) keyboard);
632 }
633 else if (firstIndex == DIGITS_SWITCH_KEY_INDEX) { // switch to letters
634 keyboard->mode = MODE_LETTERS;
635 nbgl_objDraw((nbgl_obj_t *) keyboard);
637 }
638 }
639 else if (keyboard->mode == MODE_SPECIAL) {
640 if (firstIndex < 26) {
641 keyboard->callback(kbd_specials[firstIndex]);
642 }
643 else if (firstIndex == SPECIAL_KEYS_INDEX) {
644 keyboard->mode = MODE_DIGITS;
645 nbgl_objDraw((nbgl_obj_t *) keyboard);
648 }
649 else if (firstIndex == DIGITS_SWITCH_KEY_INDEX) { // switch to letters
650 keyboard->mode = MODE_LETTERS;
651 nbgl_objDraw((nbgl_obj_t *) keyboard);
653 }
654 }
655 if (firstIndex == BACKSPACE_KEY_INDEX) { // backspace
656 keyboard->callback(BACKSPACE_KEY);
657 }
658 else if ((firstIndex == SPACE_KEY_INDEX) && ((IS_KEY_MASKED(SPACE_KEY_INDEX)) == 0)) { // space
659 keyboard->callback(' ');
660 }
661}
662
673bool nbgl_keyboardGetPosition(nbgl_keyboard_t *kbd, char index, uint16_t *x, uint16_t *y)
674{
675 uint8_t charIndex = 0;
676
677 while (charIndex < 26) {
678 if (index == kbd_chars[charIndex]) {
679 break;
680 }
681 charIndex++;
682 }
683
684 // if in first line
685 if (charIndex < FIRST_LINE_CHAR_COUNT) {
686 *x = kbd->obj.area.x0 + charIndex * NORMAL_KEY_WIDTH;
687 *y = kbd->obj.area.y0;
688 }
689 else if (charIndex < (FIRST_LINE_CHAR_COUNT + SECOND_LINE_CHAR_COUNT)) {
690 *x = kbd->obj.area.x0 + (charIndex - FIRST_LINE_CHAR_COUNT) * NORMAL_KEY_WIDTH
692 *y = kbd->obj.area.y0 + KEYBOARD_KEY_HEIGHT;
693 }
694 else if (charIndex < sizeof(kbd_chars)) {
695 if (kbd->mode == MODE_LETTERS) {
696 *x = kbd->obj.area.x0
697 + (charIndex - FIRST_LINE_CHAR_COUNT - SECOND_LINE_CHAR_COUNT) * NORMAL_KEY_WIDTH;
698 // shift does not exist in letters only mode
699 if (!kbd->lettersOnly) {
700 *x = *x + SHIFT_KEY_WIDTH;
701 }
702 }
703 else {
704 *x = kbd->obj.area.x0
705 + (charIndex - FIRST_LINE_CHAR_COUNT - SECOND_LINE_CHAR_COUNT) * NORMAL_KEY_WIDTH
707 }
708 *y = kbd->obj.area.y0 + 2 * KEYBOARD_KEY_HEIGHT;
709 }
710 else {
711 return false;
712 }
713 return true;
714}
715
722{
723 kbd->obj.touchMask = (1 << TOUCHED);
724 kbd->obj.touchId = KEYBOARD_ID;
725 kbd->needsRefresh = false;
726
727 keyboardDraw(kbd);
728
729#ifdef TARGET_STAX
730 // If a keyboard in the screen, exclude nothing from touch, to avoid missing touch on
731 // left keys
732 touch_exclude_borders(0);
733#endif // TARGET_STAX
734}
735#endif // HAVE_SE_TOUCH
736#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:531
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:580
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:366
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:354
Font screen low-Level driver API, to draw elementary forms.
void nbgl_frontDrawLine(const nbgl_area_t *area, uint8_t dotStartIdx, color_t lineColor)
void nbgl_frontDrawRect(const nbgl_area_t *area)
API to draw all basic graphic objects.
#define BACKSPACE_KEY_INDEX
Definition nbgl_obj.h:43
#define SHIFT_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:1626
keyboardCase_t
Letters casing in which to open/set the keyboard.
Definition nbgl_obj.h:616
@ LOCKED_UPPER_CASE
locked upper case mode
Definition nbgl_obj.h:619
@ LOWER_CASE
lower case mode
Definition nbgl_obj.h:617
@ UPPER_CASE
upper case mode for one character
Definition nbgl_obj.h:618
struct PACKED__ nbgl_keyboard_s nbgl_keyboard_t
struct to represent a keyboard (KEYBOARD type)
#define DIGITS_SWITCH_KEY_INDEX
Definition nbgl_obj.h:42
#define BACKSPACE_KEY
Definition nbgl_obj.h:26
#define SPACE_KEY_INDEX
Definition nbgl_obj.h:44
@ MODE_SPECIAL
extended special characters mode
Definition nbgl_obj.h:603
@ MODE_DIGITS
digits and some special characters mode
Definition nbgl_obj.h:602
@ MODE_LETTERS
letters mode
Definition nbgl_obj.h:601
void nbgl_refreshSpecialWithPostRefresh(nbgl_refresh_mode_t mode, nbgl_post_refresh_t post_refresh)
Definition nbgl_obj.c:1695
@ KEYBOARD_ID
Definition nbgl_obj.h:687
#define SPECIAL_KEYS_INDEX
Definition nbgl_obj.h:45
struct PACKED__ nbgl_obj_s nbgl_obj_t
Common structure for all graphical objects.
#define BACKSPACE_KEY_WIDTH_LETTERS_ONLY
void nbgl_keyboardTouchCallback(nbgl_obj_t *obj, nbgl_touchType_t eventType)
function to be called when the keyboard object is touched
#define BACKSPACE_KEY_WIDTH_DIGITS
const char kbd_digits[]
bool nbgl_keyboardGetPosition(nbgl_keyboard_t *kbd, char index, uint16_t *x, uint16_t *y)
This function gets the position (top-left corner) of the key at the given index. (to be used for Test...
#define SECOND_LINE_OFFSET
void nbgl_objDrawKeyboard(nbgl_keyboard_t *kbd)
This function draws a keyboard object.
#define SHIFT_KEY_WIDTH
#define SPECIAL_CHARS_KEY_WIDTH
#define SWITCH_KEY_WIDTH
#define FIRST_LINE_CHAR_COUNT
#define BACKSPACE_KEY_WIDTH_FULL
#define SECOND_LINE_CHAR_COUNT
#define IS_KEY_MASKED(_index)
bool nbgl_touchGetTouchedPosition(nbgl_obj_t *obj, nbgl_touchStatePosition_t **firstPos, nbgl_touchStatePosition_t **lastPos)
Definition nbgl_touch.c:389
@ WHITE
Definition nbgl_types.h:144
@ BLACK
Definition nbgl_types.h:141
@ POST_REFRESH_FORCE_POWER_ON
Force screen power on after refresh.
Definition nbgl_types.h:354
nbgl_touchType_t
The different types of Touchscreen events.
Definition nbgl_types.h:259
@ TOUCHED
Definition nbgl_types.h:260
#define NO_TRANSFORMATION
Definition nbgl_types.h:91
@ NBGL_BPP_1
1 bit per pixel
Definition nbgl_types.h:284
struct PACKED__ nbgl_area_s nbgl_area_t
Represents a rectangle area of the screen.
@ BLACK_AND_WHITE_REFRESH
to be used for pure B&W area, when contrast is important
Definition nbgl_types.h:330
@ FULL_COLOR_REFRESH
to be used for normal refresh
Definition nbgl_types.h:327
The low level Touchscreen event, coming from driver.
Definition nbgl_obj.h:331
int16_t y
vertical position of the touch (or for a RELEASED the last touched point)
Definition nbgl_obj.h:338
int16_t x
horizontal position of the touch (or for a RELEASED the last touched point)
Definition nbgl_obj.h:337