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, 1, keyboard->borderColor); // 1st line (top)
167 rectArea.y0 += KEYBOARD_KEY_HEIGHT;
168 nbgl_frontDrawLine(&rectArea, 1, keyboard->borderColor); // 2nd line
169 rectArea.y0 += KEYBOARD_KEY_HEIGHT;
170 nbgl_frontDrawLine(&rectArea, 1, 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, 1, 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, 1, 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
195static void keyboardDrawGrid(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#ifdef TARGET_APEX
210 // On Apex, we start all lines 1px under the horizontal one
211 rectArea.y0++;
212 rectArea.height--;
213#endif
214
215 // First row of keys: 10 letters (qwertyuiop) or digits, so 9 separations
216 for (i = 0; i < 9; i++) {
217 rectArea.x0 += NORMAL_KEY_WIDTH;
218 nbgl_frontDrawLine(&rectArea, 2, keyboard->borderColor);
219 }
220
221 // Second row: 9 letters (asdfghjkl) or digits
222 rectArea.x0 = keyboard->obj.area.x0 + SECOND_LINE_OFFSET;
223 rectArea.y0 += KEYBOARD_KEY_HEIGHT;
224 nbgl_frontDrawLine(&rectArea, 2, keyboard->borderColor);
225 for (i = 10; i < 19; i++) {
226 rectArea.x0 += NORMAL_KEY_WIDTH;
227 nbgl_frontDrawLine(&rectArea, 2, keyboard->borderColor);
228 }
229
230 // Third row, it depends of the mode:
231 // - 9 keys: Shift, 7 letters (zxcvbnm) and backspace in normal mode
232 // - 8 keys: 7 letters (zxcvbnm) and backspace in letters only mode
233 // - 7 keys: Special char key, 5 keys and backspace in digits mode
234 uint8_t nbLines, firstShift;
235 if (keyboard->mode == MODE_LETTERS) {
236 if (keyboard->lettersOnly) {
237 nbLines = 7;
238 firstShift = NORMAL_KEY_WIDTH;
239 }
240 else {
241 nbLines = 8;
242 firstShift = SHIFT_KEY_WIDTH;
243 }
244 }
245 else {
246 nbLines = 6;
247 firstShift = SPECIAL_CHARS_KEY_WIDTH;
248 }
249 rectArea.x0 = keyboard->obj.area.x0 + firstShift;
250 rectArea.y0 += KEYBOARD_KEY_HEIGHT;
251 for (i = 0; i < nbLines; i++) {
252 nbgl_frontDrawLine(&rectArea, 2, keyboard->borderColor);
253 rectArea.x0 += NORMAL_KEY_WIDTH;
254 }
255
256 // 4th row, only in Full mode
257 if (!keyboard->lettersOnly || (keyboard->mode != MODE_LETTERS)) {
258 rectArea.x0 = keyboard->obj.area.x0 + SWITCH_KEY_WIDTH;
259 rectArea.y0 += KEYBOARD_KEY_HEIGHT;
260#ifdef TARGET_APEX
261 // On Apex, we start the last line 2px under the horizontal one
262 rectArea.y0 += 2;
263 rectArea.height -= 2;
264#endif
265 nbgl_frontDrawLine(&rectArea, 0, keyboard->borderColor);
266 }
267}
268
269// draw letters for letters mode
270static void keyboardDrawLetters(nbgl_keyboard_t *keyboard)
271{
272 uint8_t i;
273 nbgl_area_t rectArea;
274 const char *keys;
275
276 if (keyboard->casing != LOWER_CASE) {
277 keys = kbd_chars_upper;
278 }
279 else {
280 keys = kbd_chars;
281 }
282
283 rectArea.backgroundColor = keyboard->obj.area.backgroundColor;
284 rectArea.y0 = keyboard->obj.area.y0 + LETTER_OFFSET_Y;
285 rectArea.width = 1;
286 rectArea.height = KEYBOARD_KEY_HEIGHT * 3;
287 rectArea.x0 = keyboard->obj.area.x0;
288
289 // First row of keys: 10 letters (qwertyuiop)
290 for (i = 0; i < 10; i++) {
291 rectArea.x0 = keyboard->obj.area.x0 + i * NORMAL_KEY_WIDTH;
292
293 rectArea.x0
294 += (NORMAL_KEY_WIDTH - nbgl_getCharWidth(SMALL_REGULAR_1BPP_FONT, &keys[i])) / 2;
296 &rectArea, &keys[i], 1, SMALL_REGULAR_1BPP_FONT, (IS_KEY_MASKED(i)) ? WHITE : BLACK);
297 }
298 // Second row: 9 letters (asdfghjkl)
299 rectArea.y0 += KEYBOARD_KEY_HEIGHT;
300 for (i = 10; i < 19; i++) {
301 rectArea.x0 = keyboard->obj.area.x0 + SECOND_LINE_OFFSET + (i - 10) * NORMAL_KEY_WIDTH;
302 rectArea.x0
303 += (NORMAL_KEY_WIDTH - nbgl_getCharWidth(SMALL_REGULAR_1BPP_FONT, &keys[i])) / 2;
305 &rectArea, &keys[i], 1, SMALL_REGULAR_1BPP_FONT, (IS_KEY_MASKED(i)) ? WHITE : BLACK);
306 }
307 // Third row: Shift key, 7 letters (zxcvbnm) and backspace
308 rectArea.y0 += KEYBOARD_KEY_HEIGHT;
309 uint16_t offsetX;
310 if (!keyboard->lettersOnly) {
311 // draw background rectangle
312#if defined(TARGET_STAX)
313 rectArea.width = SHIFT_KEY_WIDTH - 1;
314 rectArea.height = KEYBOARD_KEY_HEIGHT;
315 rectArea.x0 = 1;
316#elif defined(TARGET_FLEX)
317 rectArea.width = SHIFT_KEY_WIDTH;
318 rectArea.height = KEYBOARD_KEY_HEIGHT;
319 rectArea.x0 = 0;
320#elif defined(TARGET_APEX)
321 if (keyboard->casing == LOWER_CASE) {
322 rectArea.width = SHIFT_KEY_WIDTH;
323 }
324 else {
325 rectArea.width = SHIFT_KEY_WIDTH + 1;
326 }
327 rectArea.height = KEYBOARD_KEY_HEIGHT + 1;
328 rectArea.x0 = 0;
329#endif
330 rectArea.bpp = NBGL_BPP_1;
331 rectArea.y0 = keyboard->obj.area.y0 + KEYBOARD_KEY_HEIGHT * 2;
332 rectArea.backgroundColor = (keyboard->casing != LOWER_CASE) ? BLACK : WHITE;
333 nbgl_frontDrawRect(&rectArea);
334
335 // draw top & bottom horizontal lines (on Apex, only if in lower case)
336#ifdef TARGET_APEX
337 if (keyboard->casing == LOWER_CASE)
338#endif
339 {
340 rectArea.width = SHIFT_KEY_WIDTH - 1;
341 rectArea.height = 1;
342 rectArea.x0 = 1;
343 rectArea.y0 = keyboard->obj.area.y0 + KEYBOARD_KEY_HEIGHT * 2;
344 rectArea.backgroundColor = (keyboard->casing != LOWER_CASE) ? BLACK : WHITE;
345 nbgl_frontDrawLine(&rectArea, 0, keyboard->borderColor);
346 rectArea.y0 += KEYBOARD_KEY_HEIGHT;
347 rectArea.backgroundColor = WHITE;
348 nbgl_frontDrawLine(&rectArea, 0, keyboard->borderColor);
349 }
350 // draw Shift key
351 rectArea.width = SHIFT_ICON.width;
352 rectArea.height = SHIFT_ICON.height;
353 rectArea.bpp = NBGL_BPP_1;
354 rectArea.y0 = (keyboard->obj.area.y0 + KEYBOARD_KEY_HEIGHT * 2
355 + (KEYBOARD_KEY_HEIGHT - rectArea.height) / 2);
356 rectArea.x0 = (SHIFT_KEY_WIDTH - rectArea.width) / 2;
358 rectArea.backgroundColor = WHITE;
359 nbgl_drawIcon(&rectArea, NO_TRANSFORMATION, WHITE, &SHIFT_LOCKED_ICON);
360 }
361 else {
362 rectArea.backgroundColor = (keyboard->casing != LOWER_CASE) ? BLACK : WHITE;
364 &rectArea,
366 (keyboard->casing != LOWER_CASE) ? WHITE : BLACK,
367 (keyboard->casing == LOCKED_UPPER_CASE) ? (&SHIFT_LOCKED_ICON) : (&SHIFT_ICON));
368 rectArea.backgroundColor = WHITE;
369 }
370 offsetX = keyboard->obj.area.x0 + SHIFT_KEY_WIDTH;
371 }
372 else {
373 offsetX = 0;
374 }
375 rectArea.y0 = keyboard->obj.area.y0 + KEYBOARD_KEY_HEIGHT * 2 + LETTER_OFFSET_Y;
376 for (i = 19; i < 26; i++) {
377 rectArea.x0 = offsetX + (i - 19) * NORMAL_KEY_WIDTH;
378 rectArea.x0
379 += (NORMAL_KEY_WIDTH - nbgl_getCharWidth(SMALL_REGULAR_1BPP_FONT, &keys[i])) / 2;
381 &rectArea, &keys[i], 1, SMALL_REGULAR_1BPP_FONT, (IS_KEY_MASKED(i)) ? WHITE : BLACK);
382 }
383 // draw backspace
384 rectArea.width = BACKSPACE_ICON.width;
385 rectArea.height = BACKSPACE_ICON.height;
386 rectArea.bpp = NBGL_BPP_1;
387 rectArea.x0 = offsetX + 7 * NORMAL_KEY_WIDTH;
388 rectArea.y0 = (keyboard->obj.area.y0 + KEYBOARD_KEY_HEIGHT * 2
389 + (KEYBOARD_KEY_HEIGHT - rectArea.height) / 2);
390 if (!keyboard->lettersOnly) {
391 rectArea.x0 += (BACKSPACE_KEY_WIDTH_FULL - rectArea.width) / 2;
392 }
393 else {
394 rectArea.x0 += (BACKSPACE_KEY_WIDTH_LETTERS_ONLY - rectArea.width) / 2;
395 }
396 nbgl_drawIcon(&rectArea,
399 &BACKSPACE_ICON);
400
401 // 4th row, only in Full mode
402 if (!keyboard->lettersOnly) {
403 rectArea.x0 = (SWITCH_KEY_WIDTH - nbgl_getTextWidth(SMALL_REGULAR_1BPP_FONT, ".?123")) / 2;
404 rectArea.y0 = keyboard->obj.area.y0 + KEYBOARD_KEY_HEIGHT * 3 + LETTER_OFFSET_Y;
405 nbgl_drawText(&rectArea,
406 ".?123",
407 5,
408 SMALL_REGULAR_1BPP_FONT,
410
411 rectArea.x0 = SWITCH_KEY_WIDTH + (SPACE_KEY_WIDTH - SPACE_ICON.width) / 2;
412 nbgl_drawIcon(&rectArea,
415 &SPACE_ICON);
416 }
417}
418
419// draw digits/special chars for digits/special mode
420static void keyboardDrawDigits(nbgl_keyboard_t *keyboard)
421{
422 uint8_t i;
423 nbgl_area_t rectArea;
424 const char *keys;
425
426 if (keyboard->mode == MODE_DIGITS) {
427 keys = kbd_digits;
428 }
429 else {
430 keys = kbd_specials;
431 }
432
433 rectArea.backgroundColor = keyboard->obj.area.backgroundColor;
434 rectArea.y0 = keyboard->obj.area.y0 + LETTER_OFFSET_Y;
435 rectArea.width = 1;
436 rectArea.height = KEYBOARD_KEY_HEIGHT * 3;
437 rectArea.x0 = keyboard->obj.area.x0;
438
439 // First row of keys: 10 digits (1234567890)
440 for (i = 0; i < 10; i++) {
441 rectArea.x0 = keyboard->obj.area.x0 + i * NORMAL_KEY_WIDTH;
442 rectArea.x0
443 += (NORMAL_KEY_WIDTH - nbgl_getCharWidth(SMALL_REGULAR_1BPP_FONT, &keys[i])) / 2;
445 &rectArea, &keys[i], 1, SMALL_REGULAR_1BPP_FONT, (IS_KEY_MASKED(i)) ? WHITE : BLACK);
446 }
447 // Second row: 9 keys ()
448 rectArea.y0 += KEYBOARD_KEY_HEIGHT;
449 for (i = 10; i < 19; i++) {
450 rectArea.x0 = keyboard->obj.area.x0 + (i - 10) * NORMAL_KEY_WIDTH + SECOND_LINE_OFFSET;
451 rectArea.x0
452 += (NORMAL_KEY_WIDTH - nbgl_getCharWidth(SMALL_REGULAR_1BPP_FONT, &keys[i])) / 2;
454 &rectArea, &keys[i], 1, SMALL_REGULAR_1BPP_FONT, (IS_KEY_MASKED(i)) ? WHITE : BLACK);
455 }
456 // Third row: special key, 5 keys and backspace
457
458 // draw "#+=" key
459 if (keyboard->mode == MODE_DIGITS) {
460 rectArea.x0
461 = (SPECIAL_CHARS_KEY_WIDTH - nbgl_getTextWidth(SMALL_REGULAR_1BPP_FONT, "#+=")) / 2;
462 rectArea.y0 = keyboard->obj.area.y0 + KEYBOARD_KEY_HEIGHT * 2 + LETTER_OFFSET_Y;
463 nbgl_drawText(&rectArea, "#+=", 3, SMALL_REGULAR_1BPP_FONT, BLACK);
464 }
465 else {
466 rectArea.x0
467 = (SPECIAL_CHARS_KEY_WIDTH - nbgl_getTextWidth(SMALL_REGULAR_1BPP_FONT, "123")) / 2;
468 rectArea.y0 = keyboard->obj.area.y0 + KEYBOARD_KEY_HEIGHT * 2 + LETTER_OFFSET_Y;
469 nbgl_drawText(&rectArea, "123", 3, SMALL_REGULAR_1BPP_FONT, BLACK);
470 }
471
472 for (i = 19; i < 24; i++) {
473 rectArea.x0 = SPECIAL_CHARS_KEY_WIDTH + (i - 19) * NORMAL_KEY_WIDTH;
474 rectArea.x0
475 += (NORMAL_KEY_WIDTH - nbgl_getCharWidth(SMALL_REGULAR_1BPP_FONT, &keys[i])) / 2;
477 &rectArea, &keys[i], 1, SMALL_REGULAR_1BPP_FONT, (IS_KEY_MASKED(i)) ? WHITE : BLACK);
478 }
479 // draw backspace
480 rectArea.width = BACKSPACE_ICON.width;
481 rectArea.height = BACKSPACE_ICON.height;
482 rectArea.bpp = NBGL_BPP_1;
483 rectArea.x0 = SPECIAL_CHARS_KEY_WIDTH + 5 * NORMAL_KEY_WIDTH;
484 rectArea.y0 = keyboard->obj.area.y0 + KEYBOARD_KEY_HEIGHT * 2
485 + ((KEYBOARD_KEY_HEIGHT - rectArea.height) / 2);
486 rectArea.x0 += (BACKSPACE_KEY_WIDTH_DIGITS - rectArea.width) / 2;
487 nbgl_drawIcon(&rectArea, NO_TRANSFORMATION, BLACK, &BACKSPACE_ICON);
488
489 // 4th row
490 rectArea.x0 = (SWITCH_KEY_WIDTH - nbgl_getTextWidth(SMALL_REGULAR_1BPP_FONT, "ABC")) / 2;
491 rectArea.y0 = keyboard->obj.area.y0 + KEYBOARD_KEY_HEIGHT * 3 + LETTER_OFFSET_Y;
492 nbgl_drawText(&rectArea, "ABC", 3, SMALL_REGULAR_1BPP_FONT, BLACK);
493
494 rectArea.x0 = SWITCH_KEY_WIDTH + (SPACE_KEY_WIDTH - SPACE_ICON.width) / 2;
495 nbgl_drawIcon(&rectArea,
498 &SPACE_ICON);
499}
500
501static void keyboardDraw(nbgl_keyboard_t *keyboard)
502{
503 // At first, draw grid
504 keyboardDrawGrid(keyboard);
505 if (keyboard->mode == MODE_LETTERS) {
506 // then draw key content
507 keyboardDrawLetters(keyboard);
508 }
509 else {
511 keyboardDrawDigits(keyboard);
512 }
513}
514
515/**********************
516 * GLOBAL FUNCTIONS
517 **********************/
518
527{
528 uint8_t firstIndex, lastIndex;
529 nbgl_touchStatePosition_t *firstPosition, *lastPosition;
530 nbgl_keyboard_t *keyboard = (nbgl_keyboard_t *) obj;
531
532 LOG_DEBUG(MISC_LOGGER, "keyboardTouchCallback(): eventType = %d\n", eventType);
533 if (eventType != TOUCHED) {
534 return;
535 }
536 if (nbgl_touchGetTouchedPosition(obj, &firstPosition, &lastPosition) == false) {
537 return;
538 }
539 // modify positions with keyboard position
540 firstPosition->x -= obj->area.x0;
541 firstPosition->y -= obj->area.y0;
542 lastPosition->x -= obj->area.x0;
543 lastPosition->y -= obj->area.y0;
544
545 firstIndex = getKeyboardIndex(keyboard, firstPosition);
546 if (firstIndex > SPECIAL_KEYS_INDEX) {
547 return;
548 }
549 lastIndex = getKeyboardIndex(keyboard, lastPosition);
550 if (lastIndex > SPECIAL_KEYS_INDEX) {
551 return;
552 }
553 // if position of finger has moved durinng press to another "key", drop it
554 if (lastIndex != firstIndex) {
555 return;
556 }
557
558 if (keyboard->mode == MODE_LETTERS) {
559 keyboardCase_t cur_casing = keyboard->casing;
560 // if the casing mode was upper (not-locked), go back to lower case
561 if ((keyboard->casing == UPPER_CASE) && (firstIndex != SHIFT_KEY_INDEX)
562 && ((IS_KEY_MASKED(firstIndex)) == 0)) {
563 keyboard->casing = LOWER_CASE;
564 // just redraw, refresh will be done by client (user of keyboard)
565 nbgl_objDraw((nbgl_obj_t *) keyboard);
566 keyboard->needsRefresh = true;
567 }
568 if ((firstIndex < 26) && ((IS_KEY_MASKED(firstIndex)) == 0)) {
569 keyboard->callback((cur_casing != LOWER_CASE) ? kbd_chars_upper[firstIndex]
570 : kbd_chars[firstIndex]);
571 }
572 else if (firstIndex == SHIFT_KEY_INDEX) {
573 switch (keyboard->casing) {
574 case LOWER_CASE:
575 keyboard->casing = UPPER_CASE;
576 break;
577 case UPPER_CASE:
578 keyboard->casing = LOCKED_UPPER_CASE;
579 break;
581 keyboard->casing = LOWER_CASE;
582 break;
583 }
584 nbgl_objDraw((nbgl_obj_t *) keyboard);
587 }
588 else if (firstIndex == DIGITS_SWITCH_KEY_INDEX) { // switch to digits
589 keyboard->mode = MODE_DIGITS;
590 nbgl_objDraw((nbgl_obj_t *) keyboard);
592 }
593 }
594 else if (keyboard->mode == MODE_DIGITS) {
595 if (firstIndex < 26) {
596 keyboard->callback(kbd_digits[firstIndex]);
597 }
598 else if (firstIndex == SPECIAL_KEYS_INDEX) {
599 keyboard->mode = MODE_SPECIAL;
600 nbgl_objDraw((nbgl_obj_t *) keyboard);
603 }
604 else if (firstIndex == DIGITS_SWITCH_KEY_INDEX) { // switch to letters
605 keyboard->mode = MODE_LETTERS;
606 nbgl_objDraw((nbgl_obj_t *) keyboard);
608 }
609 }
610 else if (keyboard->mode == MODE_SPECIAL) {
611 if (firstIndex < 26) {
612 keyboard->callback(kbd_specials[firstIndex]);
613 }
614 else if (firstIndex == SPECIAL_KEYS_INDEX) {
615 keyboard->mode = MODE_DIGITS;
616 nbgl_objDraw((nbgl_obj_t *) keyboard);
619 }
620 else if (firstIndex == DIGITS_SWITCH_KEY_INDEX) { // switch to letters
621 keyboard->mode = MODE_LETTERS;
622 nbgl_objDraw((nbgl_obj_t *) keyboard);
624 }
625 }
626 if (firstIndex == BACKSPACE_KEY_INDEX) { // backspace
627 keyboard->callback(BACKSPACE_KEY);
628 }
629 else if ((firstIndex == SPACE_KEY_INDEX) && ((IS_KEY_MASKED(SPACE_KEY_INDEX)) == 0)) { // space
630 keyboard->callback(' ');
631 }
632}
633
644bool nbgl_keyboardGetPosition(nbgl_keyboard_t *kbd, char index, uint16_t *x, uint16_t *y)
645{
646 uint8_t charIndex = 0;
647
648 while (charIndex < 26) {
649 if (index == kbd_chars[charIndex]) {
650 break;
651 }
652 charIndex++;
653 }
654
655 // if in first line
656 if (charIndex < FIRST_LINE_CHAR_COUNT) {
657 *x = kbd->obj.area.x0 + charIndex * NORMAL_KEY_WIDTH;
658 *y = kbd->obj.area.y0;
659 }
660 else if (charIndex < (FIRST_LINE_CHAR_COUNT + SECOND_LINE_CHAR_COUNT)) {
661 *x = kbd->obj.area.x0 + (charIndex - FIRST_LINE_CHAR_COUNT) * NORMAL_KEY_WIDTH
663 *y = kbd->obj.area.y0 + KEYBOARD_KEY_HEIGHT;
664 }
665 else if (charIndex < sizeof(kbd_chars)) {
666 if (kbd->mode == MODE_LETTERS) {
667 *x = kbd->obj.area.x0
668 + (charIndex - FIRST_LINE_CHAR_COUNT - SECOND_LINE_CHAR_COUNT) * NORMAL_KEY_WIDTH;
669 // shift does not exist in letters only mode
670 if (!kbd->lettersOnly) {
671 *x = *x + SHIFT_KEY_WIDTH;
672 }
673 }
674 else {
675 *x = kbd->obj.area.x0
676 + (charIndex - FIRST_LINE_CHAR_COUNT - SECOND_LINE_CHAR_COUNT) * NORMAL_KEY_WIDTH
678 }
679 *y = kbd->obj.area.y0 + 2 * KEYBOARD_KEY_HEIGHT;
680 }
681 else {
682 return false;
683 }
684 return true;
685}
686
693{
694 kbd->obj.touchMask = (1 << TOUCHED);
695 kbd->obj.touchId = KEYBOARD_ID;
696 kbd->needsRefresh = false;
697
698 keyboardDraw(kbd);
699
700#ifdef TARGET_STAX
701 // If a keyboard in the screen, exclude nothing from touch, to avoid missing touch on
702 // left keys
703 touch_exclude_borders(0);
704#endif // TARGET_STAX
705}
706#endif // HAVE_SE_TOUCH
707#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:535
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:584
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:1654
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:1723
@ 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