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.h"
22
23/*********************
24 * DEFINES
25 *********************/
26
27#define FIRST_LINE_CHAR_COUNT 10
28#define SECOND_LINE_CHAR_COUNT 9
29
30#if (SCREEN_WIDTH == 400)
31#define NORMAL_KEY_WIDTH 40
32#define LETTER_OFFSET_Y (((KEYBOARD_KEY_HEIGHT - 32) / 2) & 0xFFC)
33#elif (SCREEN_WIDTH == 480)
34#define NORMAL_KEY_WIDTH 48
35#define LETTER_OFFSET_Y (((KEYBOARD_KEY_HEIGHT - 36) / 2) & 0xFFC)
36#endif
37#define SHIFT_KEY_WIDTH (NORMAL_KEY_WIDTH + SECOND_LINE_OFFSET)
38#define SECOND_LINE_OFFSET ((SCREEN_WIDTH - (SECOND_LINE_CHAR_COUNT * NORMAL_KEY_WIDTH)) / 2)
39#if defined(TARGET_STAX)
40#define SPACE_KEY_WIDTH 276
41#elif defined(TARGET_FLEX)
42#define SPACE_KEY_WIDTH 336
43#endif // TARGETS
44#define SWITCH_KEY_WIDTH (SCREEN_WIDTH - SPACE_KEY_WIDTH)
45#define SPECIAL_CHARS_KEY_WIDTH (NORMAL_KEY_WIDTH * 2 + SECOND_LINE_OFFSET)
46#define BACKSPACE_KEY_WIDTH_FULL SHIFT_KEY_WIDTH
47#define BACKSPACE_KEY_WIDTH_DIGITS SPECIAL_CHARS_KEY_WIDTH
48#define BACKSPACE_KEY_WIDTH_LETTERS_ONLY (SCREEN_WIDTH - 7 * NORMAL_KEY_WIDTH)
49
50#define IS_KEY_MASKED(_index) (keyboard->keyMask & (1 << _index))
51
52/**********************
53 * TYPEDEFS
54 **********************/
55
56/**********************
57 * STATIC PROTOTYPES
58 **********************/
59
60/**********************
61 * STATIC VARIABLES
62 **********************/
63static const char kbd_chars[] = "qwertyuiopasdfghjklzxcvbnm";
64static const char kbd_chars_upper[] = "QWERTYUIOPASDFGHJKLZXCVBNM";
65const char kbd_digits[] = "1234567890-/:;()&@\".,?!\'";
66static const char kbd_specials[] = "[]{}#%^*+=_\\|~<>$`\".,?!\'";
67
68/**********************
69 * VARIABLES
70 **********************/
71
72/**********************
73 * STATIC FUNCTIONS
74 **********************/
75static uint8_t getKeyboardIndex(nbgl_keyboard_t *keyboard, nbgl_touchStatePosition_t *position)
76{
77 uint8_t i = 0;
78 // get index of key pressed
79 if (position->y < KEYBOARD_KEY_HEIGHT) {
80 // 1st row:
81 i = position->x / NORMAL_KEY_WIDTH;
82 }
83 else if (position->y < (2 * KEYBOARD_KEY_HEIGHT)) {
84 // 2nd row:
85 i = FIRST_LINE_CHAR_COUNT + (position->x - SECOND_LINE_OFFSET) / NORMAL_KEY_WIDTH;
88 }
89 }
90 else if (position->y < (3 * KEYBOARD_KEY_HEIGHT)) {
91 // 3rd row:
92 if (keyboard->mode == MODE_LETTERS) {
93 // shift does not exist in letters only mode
94 if (!keyboard->lettersOnly) {
95 if (position->x < SHIFT_KEY_WIDTH) {
97 }
98 else {
100 + (position->x - SHIFT_KEY_WIDTH) / NORMAL_KEY_WIDTH;
101 // Backspace key is a bit larger...
102 if (i >= 26) {
104 }
105 }
106 }
107 else {
108 i = FIRST_LINE_CHAR_COUNT + SECOND_LINE_CHAR_COUNT + position->x / NORMAL_KEY_WIDTH;
109 // Backspace key is larger...
110 if (i >= 26) {
112 }
113 }
114 }
115 else {
116 if (position->x < SPECIAL_CHARS_KEY_WIDTH) {
118 }
119 else {
121 + (position->x - SPECIAL_CHARS_KEY_WIDTH) / NORMAL_KEY_WIDTH;
122 // Backspace key is a bit larger...
123 if (i >= 24) {
125 }
126 }
127 }
128 }
129 else if (!keyboard->lettersOnly && (position->y < (4 * KEYBOARD_KEY_HEIGHT))) {
130 // 4th row
131 if (position->x < SWITCH_KEY_WIDTH) {
133 }
134 else {
135 i = SPACE_KEY_INDEX;
136 }
137 }
138 return i;
139}
140
141// draw parts common to all modes of keyboard
142static void keyboardDrawCommonLines(nbgl_keyboard_t *keyboard)
143{
144 nbgl_area_t rectArea;
145
146 // clean full area
147 rectArea.backgroundColor = keyboard->obj.area.backgroundColor;
148 rectArea.x0 = keyboard->obj.area.x0;
149 rectArea.y0 = keyboard->obj.area.y0;
150 rectArea.width = keyboard->obj.area.width;
151 rectArea.height = keyboard->obj.area.height;
152 nbgl_frontDrawRect(&rectArea);
153
155 rectArea.backgroundColor = keyboard->obj.area.backgroundColor;
156 rectArea.x0 = keyboard->obj.area.x0;
157 rectArea.y0 = keyboard->obj.area.y0;
158 rectArea.width = keyboard->obj.area.width;
159 rectArea.height = VERTICAL_ALIGNMENT;
160 nbgl_frontDrawHorizontalLine(&rectArea, 0x1, keyboard->borderColor); // 1st line (top)
161 rectArea.y0 += KEYBOARD_KEY_HEIGHT;
162 nbgl_frontDrawHorizontalLine(&rectArea, 0x1, keyboard->borderColor); // 2nd line
163 rectArea.y0 += KEYBOARD_KEY_HEIGHT;
164 nbgl_frontDrawHorizontalLine(&rectArea, 0x1, keyboard->borderColor); // 3rd line
165 // in letter only mode, only draw the last line if not at bottom of screen
166 if ((keyboard->obj.alignmentMarginY > 0) || (!keyboard->lettersOnly)) {
167 rectArea.y0 += KEYBOARD_KEY_HEIGHT;
168 nbgl_frontDrawHorizontalLine(&rectArea, 0x1, keyboard->borderColor); // 4th line
169 }
170 // in non letter only mode, only draw the last line if not at bottom of screen
171 if ((keyboard->obj.alignmentMarginY > 0) && (!keyboard->lettersOnly)) {
172 rectArea.y0 += KEYBOARD_KEY_HEIGHT;
173 nbgl_frontDrawHorizontalLine(&rectArea, 0x1, keyboard->borderColor); // 5th line
174 }
176 rectArea.backgroundColor = keyboard->borderColor;
177 rectArea.x0 = keyboard->obj.area.x0;
178 rectArea.y0 = keyboard->obj.area.y0;
179 rectArea.width = 1;
180 rectArea.height = KEYBOARD_KEY_HEIGHT * 3;
181 if (!keyboard->lettersOnly) {
182 rectArea.height += KEYBOARD_KEY_HEIGHT;
183 }
184 nbgl_frontDrawRect(&rectArea); // 1st full line, on the left
185}
186
187// draw full grid for letters mode
188static void keyboardDrawLetterGrid(nbgl_keyboard_t *keyboard)
189{
190 nbgl_area_t rectArea;
191 uint8_t i;
192
194 keyboardDrawCommonLines(keyboard);
195
196 // then all vertical lines separating keys
197 rectArea.backgroundColor = keyboard->borderColor;
198 rectArea.x0 = keyboard->obj.area.x0;
199 rectArea.y0 = keyboard->obj.area.y0;
200 rectArea.width = 1;
201 rectArea.height = KEYBOARD_KEY_HEIGHT;
202 // First row of keys: 10 letters (qwertyuiop)
203 for (i = 0; i < 9; i++) {
204 rectArea.x0 += NORMAL_KEY_WIDTH;
205 nbgl_frontDrawRect(&rectArea);
206 }
207
208 // Second row: 9 letters (asdfghjkl)
209 rectArea.x0 = keyboard->obj.area.x0 + SECOND_LINE_OFFSET;
210 rectArea.y0 += KEYBOARD_KEY_HEIGHT;
211 nbgl_frontDrawRect(&rectArea);
212 for (i = 10; i < 19; i++) {
213 rectArea.x0 += NORMAL_KEY_WIDTH;
214 nbgl_frontDrawRect(&rectArea);
215 }
216 // Third row: Shift key, 7 letters (zxcvbnm) and backspace in normal mode
217 // Third row: 7 letters (zxcvbnm) and backspace in letters only mode
218 rectArea.y0 += KEYBOARD_KEY_HEIGHT;
219 if (!keyboard->lettersOnly) {
220 rectArea.x0 = keyboard->obj.area.x0 + SHIFT_KEY_WIDTH;
221 }
222 else {
223 rectArea.x0 = NORMAL_KEY_WIDTH;
224 }
225 for (i = 0; i < 6; i++) {
226 nbgl_frontDrawRect(&rectArea);
227 rectArea.x0 += NORMAL_KEY_WIDTH;
228 }
229 if (!keyboard->lettersOnly) {
230 nbgl_frontDrawRect(&rectArea);
231 rectArea.x0 += NORMAL_KEY_WIDTH;
232 }
233 nbgl_frontDrawRect(&rectArea);
234
235 // 4th row, only in Full mode
236 if (!keyboard->lettersOnly) {
237 rectArea.y0 += KEYBOARD_KEY_HEIGHT;
238 rectArea.x0 = keyboard->obj.area.x0 + SWITCH_KEY_WIDTH;
239 nbgl_frontDrawRect(&rectArea);
240 }
241}
242
243// draw full grid for digits/special mode
244static void keyboardDrawDigitsGrid(nbgl_keyboard_t *keyboard)
245{
246 nbgl_area_t rectArea;
247 uint8_t i;
248
250 keyboardDrawCommonLines(keyboard);
251
252 // then all vertical lines separating keys
253 rectArea.backgroundColor = keyboard->borderColor;
254 rectArea.x0 = keyboard->obj.area.x0;
255 rectArea.y0 = keyboard->obj.area.y0;
256 rectArea.width = 1;
257 rectArea.height = KEYBOARD_KEY_HEIGHT;
258 // First row of keys: 10 keys so 9 separations
259 for (i = 0; i < 9; i++) {
260 rectArea.x0 += NORMAL_KEY_WIDTH;
261 nbgl_frontDrawRect(&rectArea);
262 }
263
264 // Second row: 9 keys
265 rectArea.x0 = keyboard->obj.area.x0 + SECOND_LINE_OFFSET;
266 rectArea.y0 += KEYBOARD_KEY_HEIGHT;
267 nbgl_frontDrawRect(&rectArea);
268 for (i = 10; i < 19; i++) {
269 rectArea.x0 += NORMAL_KEY_WIDTH;
270 nbgl_frontDrawRect(&rectArea);
271 }
272 // Third row: Special char key, 5 keys and backspace
273 rectArea.x0 = keyboard->obj.area.x0 + SPECIAL_CHARS_KEY_WIDTH;
274 rectArea.y0 += KEYBOARD_KEY_HEIGHT;
275 nbgl_frontDrawRect(&rectArea);
276 for (i = 0; i < 5; i++) {
277 rectArea.x0 += NORMAL_KEY_WIDTH;
278 nbgl_frontDrawRect(&rectArea);
279 }
280
281 // 4th row, switch to letters and space
282 rectArea.y0 += KEYBOARD_KEY_HEIGHT;
283 rectArea.x0 = keyboard->obj.area.x0 + SWITCH_KEY_WIDTH;
284 nbgl_frontDrawRect(&rectArea);
285}
286
287// draw letters for letters mode
288static void keyboardDrawLetters(nbgl_keyboard_t *keyboard)
289{
290 uint8_t i;
291 nbgl_area_t rectArea;
292 const char *keys;
293
294 if (keyboard->casing != LOWER_CASE) {
295 keys = kbd_chars_upper;
296 }
297 else {
298 keys = kbd_chars;
299 }
300
301 rectArea.backgroundColor = keyboard->obj.area.backgroundColor;
302 rectArea.y0 = keyboard->obj.area.y0 + LETTER_OFFSET_Y;
303 rectArea.width = 1;
304 rectArea.height = KEYBOARD_KEY_HEIGHT * 3;
305 rectArea.x0 = keyboard->obj.area.x0;
306
307 // First row of keys: 10 letters (qwertyuiop)
308 for (i = 0; i < 10; i++) {
309 rectArea.x0 = keyboard->obj.area.x0 + i * NORMAL_KEY_WIDTH;
310
311 rectArea.x0
312 += (NORMAL_KEY_WIDTH - nbgl_getCharWidth(SMALL_REGULAR_1BPP_FONT, &keys[i])) / 2;
314 &rectArea, &keys[i], 1, SMALL_REGULAR_1BPP_FONT, (IS_KEY_MASKED(i)) ? WHITE : BLACK);
315 }
316 // Second row: 9 letters (asdfghjkl)
317 rectArea.y0 += KEYBOARD_KEY_HEIGHT;
318 for (i = 10; i < 19; i++) {
319 rectArea.x0 = keyboard->obj.area.x0 + SECOND_LINE_OFFSET + (i - 10) * NORMAL_KEY_WIDTH;
320 rectArea.x0
321 += (NORMAL_KEY_WIDTH - nbgl_getCharWidth(SMALL_REGULAR_1BPP_FONT, &keys[i])) / 2;
323 &rectArea, &keys[i], 1, SMALL_REGULAR_1BPP_FONT, (IS_KEY_MASKED(i)) ? WHITE : BLACK);
324 }
325 // Third row: Shift key, 7 letters (zxcvbnm) and backspace
326 rectArea.y0 += KEYBOARD_KEY_HEIGHT;
327 uint16_t offsetX;
328 if (!keyboard->lettersOnly) {
329 // draw background rectangle
330 rectArea.width = SHIFT_KEY_WIDTH - 1;
331 rectArea.height = KEYBOARD_KEY_HEIGHT;
332 rectArea.bpp = NBGL_BPP_1;
333 rectArea.y0 = keyboard->obj.area.y0 + KEYBOARD_KEY_HEIGHT * 2;
334 rectArea.x0 = 1;
335 rectArea.backgroundColor = (keyboard->casing != LOWER_CASE) ? BLACK : WHITE;
336 nbgl_frontDrawRect(&rectArea);
337 // draw horizontal line
338 rectArea.width = SHIFT_KEY_WIDTH - 1;
339 rectArea.height = VERTICAL_ALIGNMENT;
340 rectArea.x0 = 1;
341 rectArea.y0 = keyboard->obj.area.y0 + KEYBOARD_KEY_HEIGHT * 2;
342 rectArea.backgroundColor = (keyboard->casing != LOWER_CASE) ? BLACK : WHITE;
343 nbgl_frontDrawHorizontalLine(&rectArea, 0x1, keyboard->borderColor);
344 // draw Shift key
345 rectArea.width = SHIFT_ICON.width;
346 rectArea.height = SHIFT_ICON.height;
347 rectArea.bpp = NBGL_BPP_1;
348 rectArea.y0 = (keyboard->obj.area.y0 + KEYBOARD_KEY_HEIGHT * 2
349 + (KEYBOARD_KEY_HEIGHT - rectArea.height) / 2)
350 & 0xFFC;
351 rectArea.x0 = (SHIFT_KEY_WIDTH - rectArea.width) / 2;
353 rectArea.backgroundColor = WHITE;
354 nbgl_drawIcon(&rectArea, NO_TRANSFORMATION, WHITE, &SHIFT_LOCKED_ICON);
355 }
356 else {
357 rectArea.backgroundColor = (keyboard->casing != LOWER_CASE) ? BLACK : WHITE;
359 &rectArea,
361 (keyboard->casing != LOWER_CASE) ? WHITE : BLACK,
362 (keyboard->casing == LOCKED_UPPER_CASE) ? (&SHIFT_LOCKED_ICON) : (&SHIFT_ICON));
363 rectArea.backgroundColor = WHITE;
364 }
365 offsetX = keyboard->obj.area.x0 + SHIFT_KEY_WIDTH;
366 }
367 else {
368 offsetX = 0;
369 }
370 rectArea.y0 = keyboard->obj.area.y0 + KEYBOARD_KEY_HEIGHT * 2 + LETTER_OFFSET_Y;
371 for (i = 19; i < 26; i++) {
372 rectArea.x0 = offsetX + (i - 19) * NORMAL_KEY_WIDTH;
373 rectArea.x0
374 += (NORMAL_KEY_WIDTH - nbgl_getCharWidth(SMALL_REGULAR_1BPP_FONT, &keys[i])) / 2;
376 &rectArea, &keys[i], 1, SMALL_REGULAR_1BPP_FONT, (IS_KEY_MASKED(i)) ? WHITE : BLACK);
377 }
378 // draw backspace
379 rectArea.width = BACKSPACE_ICON.width;
380 rectArea.height = BACKSPACE_ICON.height;
381 rectArea.bpp = NBGL_BPP_1;
382 rectArea.x0 = offsetX + 7 * NORMAL_KEY_WIDTH;
383 rectArea.y0 = (keyboard->obj.area.y0 + KEYBOARD_KEY_HEIGHT * 2
384 + (KEYBOARD_KEY_HEIGHT - rectArea.height) / 2)
385 & 0xFFC;
386 if (!keyboard->lettersOnly) {
387 rectArea.x0 += (BACKSPACE_KEY_WIDTH_FULL - rectArea.width) / 2;
388 }
389 else {
390 rectArea.x0 += (BACKSPACE_KEY_WIDTH_LETTERS_ONLY - rectArea.width) / 2;
391 }
392 nbgl_drawIcon(&rectArea,
395 &BACKSPACE_ICON);
396
397 // 4th row, only in Full mode
398 if (!keyboard->lettersOnly) {
399 rectArea.x0 = (SWITCH_KEY_WIDTH - nbgl_getTextWidth(SMALL_REGULAR_1BPP_FONT, ".?123")) / 2;
400 rectArea.y0 = keyboard->obj.area.y0 + KEYBOARD_KEY_HEIGHT * 3 + LETTER_OFFSET_Y;
401 nbgl_drawText(&rectArea,
402 ".?123",
403 5,
404 SMALL_REGULAR_1BPP_FONT,
406
407 rectArea.x0 = SWITCH_KEY_WIDTH + (SPACE_KEY_WIDTH - SPACE_ICON.width) / 2;
408 nbgl_drawIcon(&rectArea,
411 &SPACE_ICON);
412 }
413}
414
415// draw digits/special chars for digits/special mode
416static void keyboardDrawDigits(nbgl_keyboard_t *keyboard)
417{
418 uint8_t i;
419 nbgl_area_t rectArea;
420 const char *keys;
421
422 if (keyboard->mode == MODE_DIGITS) {
423 keys = kbd_digits;
424 }
425 else {
426 keys = kbd_specials;
427 }
428
429 rectArea.backgroundColor = keyboard->obj.area.backgroundColor;
430 rectArea.y0 = keyboard->obj.area.y0 + LETTER_OFFSET_Y;
431 rectArea.width = 1;
432 rectArea.height = KEYBOARD_KEY_HEIGHT * 3;
433 rectArea.x0 = keyboard->obj.area.x0;
434
435 // First row of keys: 10 digits (1234567890)
436 for (i = 0; i < 10; i++) {
437 rectArea.x0 = keyboard->obj.area.x0 + i * NORMAL_KEY_WIDTH;
438 rectArea.x0
439 += (NORMAL_KEY_WIDTH - nbgl_getCharWidth(SMALL_REGULAR_1BPP_FONT, &keys[i])) / 2;
441 &rectArea, &keys[i], 1, SMALL_REGULAR_1BPP_FONT, (IS_KEY_MASKED(i)) ? WHITE : BLACK);
442 }
443 // Second row: 9 keys ()
444 rectArea.y0 += KEYBOARD_KEY_HEIGHT;
445 for (i = 10; i < 19; i++) {
446 rectArea.x0 = keyboard->obj.area.x0 + (i - 10) * NORMAL_KEY_WIDTH + SECOND_LINE_OFFSET;
447 rectArea.x0
448 += (NORMAL_KEY_WIDTH - nbgl_getCharWidth(SMALL_REGULAR_1BPP_FONT, &keys[i])) / 2;
450 &rectArea, &keys[i], 1, SMALL_REGULAR_1BPP_FONT, (IS_KEY_MASKED(i)) ? WHITE : BLACK);
451 }
452 // Third row: special key, 5 keys and backspace
453
454 // draw "#+=" key
455 if (keyboard->mode == MODE_DIGITS) {
456 rectArea.x0
457 = (SPECIAL_CHARS_KEY_WIDTH - nbgl_getTextWidth(SMALL_REGULAR_1BPP_FONT, "#+=")) / 2;
458 rectArea.y0 = keyboard->obj.area.y0 + KEYBOARD_KEY_HEIGHT * 2 + LETTER_OFFSET_Y;
459 nbgl_drawText(&rectArea, "#+=", 3, SMALL_REGULAR_1BPP_FONT, BLACK);
460 }
461 else {
462 rectArea.x0
463 = (SPECIAL_CHARS_KEY_WIDTH - nbgl_getTextWidth(SMALL_REGULAR_1BPP_FONT, "123")) / 2;
464 rectArea.y0 = keyboard->obj.area.y0 + KEYBOARD_KEY_HEIGHT * 2 + LETTER_OFFSET_Y;
465 nbgl_drawText(&rectArea, "123", 3, SMALL_REGULAR_1BPP_FONT, BLACK);
466 }
467
468 for (i = 19; i < 24; i++) {
469 rectArea.x0 = SPECIAL_CHARS_KEY_WIDTH + (i - 19) * NORMAL_KEY_WIDTH;
470 rectArea.x0
471 += (NORMAL_KEY_WIDTH - nbgl_getCharWidth(SMALL_REGULAR_1BPP_FONT, &keys[i])) / 2;
473 &rectArea, &keys[i], 1, SMALL_REGULAR_1BPP_FONT, (IS_KEY_MASKED(i)) ? WHITE : BLACK);
474 }
475 // draw backspace
476 rectArea.width = BACKSPACE_ICON.width;
477 rectArea.height = BACKSPACE_ICON.height;
478 rectArea.bpp = NBGL_BPP_1;
479 rectArea.x0 = SPECIAL_CHARS_KEY_WIDTH + 5 * NORMAL_KEY_WIDTH;
480 rectArea.y0 = keyboard->obj.area.y0 + KEYBOARD_KEY_HEIGHT * 2
481 + (((KEYBOARD_KEY_HEIGHT - rectArea.height) / 2) & 0xFFC);
482 rectArea.x0 += (BACKSPACE_KEY_WIDTH_DIGITS - rectArea.width) / 2;
483 nbgl_drawIcon(&rectArea, NO_TRANSFORMATION, BLACK, &BACKSPACE_ICON);
484
485 // 4th row
486 rectArea.x0 = (SWITCH_KEY_WIDTH - nbgl_getTextWidth(SMALL_REGULAR_1BPP_FONT, "ABC")) / 2;
487 rectArea.y0 = keyboard->obj.area.y0 + KEYBOARD_KEY_HEIGHT * 3 + LETTER_OFFSET_Y;
488 nbgl_drawText(&rectArea, "ABC", 3, SMALL_REGULAR_1BPP_FONT, BLACK);
489
490 rectArea.x0 = SWITCH_KEY_WIDTH + (SPACE_KEY_WIDTH - SPACE_ICON.width) / 2;
491 nbgl_drawIcon(&rectArea,
494 &SPACE_ICON);
495}
496
497static void keyboardDraw(nbgl_keyboard_t *keyboard)
498{
499 if (keyboard->mode == MODE_LETTERS) {
500 // At first, draw grid
501 keyboardDrawLetterGrid(keyboard);
502
503 // then draw key content
504 keyboardDrawLetters(keyboard);
505 }
506 else {
508 keyboardDrawDigitsGrid(keyboard);
509
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
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: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
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
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:350
Font screen low-Level driver API, to draw elementary forms.
void nbgl_frontDrawHorizontalLine(const nbgl_area_t *area, uint8_t mask, 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:41
#define SHIFT_KEY_INDEX
Definition nbgl_obj.h:39
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
keyboardCase_t
Letters casing in which to open/set the keyboard.
Definition nbgl_obj.h:510
@ LOCKED_UPPER_CASE
locked upper case mode
Definition nbgl_obj.h:513
@ LOWER_CASE
lower case mode
Definition nbgl_obj.h:511
@ UPPER_CASE
upper case mode for one character
Definition nbgl_obj.h:512
struct PACKED__ nbgl_keyboard_s nbgl_keyboard_t
struct to represent a keyboard (KEYBOARD type)
#define DIGITS_SWITCH_KEY_INDEX
Definition nbgl_obj.h:40
#define BACKSPACE_KEY
Definition nbgl_obj.h:26
#define SPACE_KEY_INDEX
Definition nbgl_obj.h:42
@ MODE_SPECIAL
extended special characters mode
Definition nbgl_obj.h:497
@ MODE_DIGITS
digits and some special characters mode
Definition nbgl_obj.h:496
@ MODE_LETTERS
letters mode
Definition nbgl_obj.h:495
void nbgl_refreshSpecialWithPostRefresh(nbgl_refresh_mode_t mode, nbgl_post_refresh_t post_refresh)
Definition nbgl_obj.c:1585
@ KEYBOARD_ID
Definition nbgl_obj.h:578
#define SPECIAL_KEYS_INDEX
Definition nbgl_obj.h:43
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:388
@ WHITE
Definition nbgl_types.h:124
@ BLACK
Definition nbgl_types.h:121
@ POST_REFRESH_FORCE_POWER_ON
Force screen power on after refresh.
Definition nbgl_types.h:334
nbgl_touchType_t
The different types of Touchscreen events.
Definition nbgl_types.h:239
@ TOUCHED
Definition nbgl_types.h:240
#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.
@ BLACK_AND_WHITE_REFRESH
to be used for pure B&W area, when contrast is important
Definition nbgl_types.h:310
@ FULL_COLOR_REFRESH
to be used for normal refresh
Definition nbgl_types.h:307
The low level Touchscreen event, coming from driver.
Definition nbgl_obj.h:227
int16_t y
vertical position of the touch (or for a RELEASED the last touched point)
Definition nbgl_obj.h:234
int16_t x
horizontal position of the touch (or for a RELEASED the last touched point)
Definition nbgl_obj.h:233
unsigned short uint16_t
Definition usbd_conf.h:54
unsigned char uint8_t
Definition usbd_conf.h:53