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) & 0xFFC)
34#elif (SCREEN_WIDTH == 480)
35#define NORMAL_KEY_WIDTH 48
36#define LETTER_OFFSET_Y (((KEYBOARD_KEY_HEIGHT - 36) / 2) & 0xFFC)
37#endif
38#define SHIFT_KEY_WIDTH (NORMAL_KEY_WIDTH + SECOND_LINE_OFFSET)
39#define SECOND_LINE_OFFSET ((SCREEN_WIDTH - (SECOND_LINE_CHAR_COUNT * NORMAL_KEY_WIDTH)) / 2)
40#if defined(TARGET_STAX)
41#define SPACE_KEY_WIDTH 276
42#elif defined(TARGET_FLEX)
43#define SPACE_KEY_WIDTH 336
44#endif // TARGETS
45#define SWITCH_KEY_WIDTH (SCREEN_WIDTH - SPACE_KEY_WIDTH)
46#define SPECIAL_CHARS_KEY_WIDTH (NORMAL_KEY_WIDTH * 2 + SECOND_LINE_OFFSET)
47#define BACKSPACE_KEY_WIDTH_FULL SHIFT_KEY_WIDTH
48#define BACKSPACE_KEY_WIDTH_DIGITS SPECIAL_CHARS_KEY_WIDTH
49#define BACKSPACE_KEY_WIDTH_LETTERS_ONLY (SCREEN_WIDTH - 7 * NORMAL_KEY_WIDTH)
50
51#define IS_KEY_MASKED(_index) (keyboard->keyMask & (1 << _index))
52
53/**********************
54 * TYPEDEFS
55 **********************/
56
57/**********************
58 * STATIC PROTOTYPES
59 **********************/
60
61/**********************
62 * STATIC VARIABLES
63 **********************/
64static const char kbd_chars[] = "qwertyuiopasdfghjklzxcvbnm";
65static const char kbd_chars_upper[] = "QWERTYUIOPASDFGHJKLZXCVBNM";
66const char kbd_digits[] = "1234567890-/:;()&@\".,?!\'";
67static const char kbd_specials[] = "[]{}#%^*+=_\\|~<>$`\".,?!\'";
68
69/**********************
70 * VARIABLES
71 **********************/
72
73/**********************
74 * STATIC FUNCTIONS
75 **********************/
76static uint8_t getKeyboardIndex(nbgl_keyboard_t *keyboard, nbgl_touchStatePosition_t *position)
77{
78 uint8_t i = 0;
79 // get index of key pressed
80 if (position->y < KEYBOARD_KEY_HEIGHT) {
81 // 1st row:
82 i = position->x / NORMAL_KEY_WIDTH;
83 }
84 else if (position->y < (2 * KEYBOARD_KEY_HEIGHT)) {
85 // 2nd row:
86 i = FIRST_LINE_CHAR_COUNT + (position->x - SECOND_LINE_OFFSET) / NORMAL_KEY_WIDTH;
89 }
90 }
91 else if (position->y < (3 * KEYBOARD_KEY_HEIGHT)) {
92 // 3rd row:
93 if (keyboard->mode == MODE_LETTERS) {
94 // shift does not exist in letters only mode
95 if (!keyboard->lettersOnly) {
96 if (position->x < SHIFT_KEY_WIDTH) {
98 }
99 else {
101 + (position->x - SHIFT_KEY_WIDTH) / NORMAL_KEY_WIDTH;
102 // Backspace key is a bit larger...
103 if (i >= 26) {
105 }
106 }
107 }
108 else {
109 i = FIRST_LINE_CHAR_COUNT + SECOND_LINE_CHAR_COUNT + position->x / NORMAL_KEY_WIDTH;
110 // Backspace key is larger...
111 if (i >= 26) {
113 }
114 }
115 }
116 else {
117 if (position->x < SPECIAL_CHARS_KEY_WIDTH) {
119 }
120 else {
122 + (position->x - SPECIAL_CHARS_KEY_WIDTH) / NORMAL_KEY_WIDTH;
123 // Backspace key is a bit larger...
124 if (i >= 24) {
126 }
127 }
128 }
129 }
130 else if (!keyboard->lettersOnly && (position->y < (4 * KEYBOARD_KEY_HEIGHT))) {
131 // 4th row
132 if (position->x < SWITCH_KEY_WIDTH) {
134 }
135 else {
136 i = SPACE_KEY_INDEX;
137 }
138 }
139 return i;
140}
141
142// draw parts common to all modes of keyboard
143static void keyboardDrawCommonLines(nbgl_keyboard_t *keyboard)
144{
145 nbgl_area_t rectArea;
146
147 // clean full area
148 rectArea.backgroundColor = keyboard->obj.area.backgroundColor;
149 rectArea.x0 = keyboard->obj.area.x0;
150 rectArea.y0 = keyboard->obj.area.y0;
151 rectArea.width = keyboard->obj.area.width;
152 rectArea.height = keyboard->obj.area.height;
153 nbgl_frontDrawRect(&rectArea);
154
156 rectArea.backgroundColor = keyboard->obj.area.backgroundColor;
157 rectArea.x0 = keyboard->obj.area.x0;
158 rectArea.y0 = keyboard->obj.area.y0;
159 rectArea.width = keyboard->obj.area.width;
160 rectArea.height = VERTICAL_ALIGNMENT;
161 nbgl_frontDrawHorizontalLine(&rectArea, 0x1, keyboard->borderColor); // 1st line (top)
162 rectArea.y0 += KEYBOARD_KEY_HEIGHT;
163 nbgl_frontDrawHorizontalLine(&rectArea, 0x1, keyboard->borderColor); // 2nd line
164 rectArea.y0 += KEYBOARD_KEY_HEIGHT;
165 nbgl_frontDrawHorizontalLine(&rectArea, 0x1, keyboard->borderColor); // 3rd line
166 // in letter only mode, only draw the last line if not at bottom of screen
167 if ((keyboard->obj.alignmentMarginY > 0) || (!keyboard->lettersOnly)) {
168 rectArea.y0 += KEYBOARD_KEY_HEIGHT;
169 nbgl_frontDrawHorizontalLine(&rectArea, 0x1, keyboard->borderColor); // 4th line
170 }
171 // in non 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_frontDrawHorizontalLine(&rectArea, 0x1, keyboard->borderColor); // 5th line
175 }
177 rectArea.backgroundColor = keyboard->borderColor;
178 rectArea.x0 = keyboard->obj.area.x0;
179 rectArea.y0 = keyboard->obj.area.y0;
180 rectArea.width = 1;
181 rectArea.height = KEYBOARD_KEY_HEIGHT * 3;
182 if (!keyboard->lettersOnly) {
183 rectArea.height += KEYBOARD_KEY_HEIGHT;
184 }
185 nbgl_frontDrawRect(&rectArea); // 1st full line, on the left
186}
187
188// draw full grid for letters mode
189static void keyboardDrawLetterGrid(nbgl_keyboard_t *keyboard)
190{
191 nbgl_area_t rectArea;
192 uint8_t i;
193
195 keyboardDrawCommonLines(keyboard);
196
197 // then all vertical lines separating keys
198 rectArea.backgroundColor = keyboard->borderColor;
199 rectArea.x0 = keyboard->obj.area.x0;
200 rectArea.y0 = keyboard->obj.area.y0;
201 rectArea.width = 1;
202 rectArea.height = KEYBOARD_KEY_HEIGHT;
203 // First row of keys: 10 letters (qwertyuiop)
204 for (i = 0; i < 9; i++) {
205 rectArea.x0 += NORMAL_KEY_WIDTH;
206 nbgl_frontDrawRect(&rectArea);
207 }
208
209 // Second row: 9 letters (asdfghjkl)
210 rectArea.x0 = keyboard->obj.area.x0 + SECOND_LINE_OFFSET;
211 rectArea.y0 += KEYBOARD_KEY_HEIGHT;
212 nbgl_frontDrawRect(&rectArea);
213 for (i = 10; i < 19; i++) {
214 rectArea.x0 += NORMAL_KEY_WIDTH;
215 nbgl_frontDrawRect(&rectArea);
216 }
217 // Third row: Shift key, 7 letters (zxcvbnm) and backspace in normal mode
218 // Third row: 7 letters (zxcvbnm) and backspace in letters only mode
219 rectArea.y0 += KEYBOARD_KEY_HEIGHT;
220 if (!keyboard->lettersOnly) {
221 rectArea.x0 = keyboard->obj.area.x0 + SHIFT_KEY_WIDTH;
222 }
223 else {
224 rectArea.x0 = NORMAL_KEY_WIDTH;
225 }
226 for (i = 0; i < 6; i++) {
227 nbgl_frontDrawRect(&rectArea);
228 rectArea.x0 += NORMAL_KEY_WIDTH;
229 }
230 if (!keyboard->lettersOnly) {
231 nbgl_frontDrawRect(&rectArea);
232 rectArea.x0 += NORMAL_KEY_WIDTH;
233 }
234 nbgl_frontDrawRect(&rectArea);
235
236 // 4th row, only in Full mode
237 if (!keyboard->lettersOnly) {
238 rectArea.y0 += KEYBOARD_KEY_HEIGHT;
239 rectArea.x0 = keyboard->obj.area.x0 + SWITCH_KEY_WIDTH;
240 nbgl_frontDrawRect(&rectArea);
241 }
242}
243
244// draw full grid for digits/special mode
245static void keyboardDrawDigitsGrid(nbgl_keyboard_t *keyboard)
246{
247 nbgl_area_t rectArea;
248 uint8_t i;
249
251 keyboardDrawCommonLines(keyboard);
252
253 // then all vertical lines separating keys
254 rectArea.backgroundColor = keyboard->borderColor;
255 rectArea.x0 = keyboard->obj.area.x0;
256 rectArea.y0 = keyboard->obj.area.y0;
257 rectArea.width = 1;
258 rectArea.height = KEYBOARD_KEY_HEIGHT;
259 // First row of keys: 10 keys so 9 separations
260 for (i = 0; i < 9; i++) {
261 rectArea.x0 += NORMAL_KEY_WIDTH;
262 nbgl_frontDrawRect(&rectArea);
263 }
264
265 // Second row: 9 keys
266 rectArea.x0 = keyboard->obj.area.x0 + SECOND_LINE_OFFSET;
267 rectArea.y0 += KEYBOARD_KEY_HEIGHT;
268 nbgl_frontDrawRect(&rectArea);
269 for (i = 10; i < 19; i++) {
270 rectArea.x0 += NORMAL_KEY_WIDTH;
271 nbgl_frontDrawRect(&rectArea);
272 }
273 // Third row: Special char key, 5 keys and backspace
274 rectArea.x0 = keyboard->obj.area.x0 + SPECIAL_CHARS_KEY_WIDTH;
275 rectArea.y0 += KEYBOARD_KEY_HEIGHT;
276 nbgl_frontDrawRect(&rectArea);
277 for (i = 0; i < 5; i++) {
278 rectArea.x0 += NORMAL_KEY_WIDTH;
279 nbgl_frontDrawRect(&rectArea);
280 }
281
282 // 4th row, switch to letters and space
283 rectArea.y0 += KEYBOARD_KEY_HEIGHT;
284 rectArea.x0 = keyboard->obj.area.x0 + SWITCH_KEY_WIDTH;
285 nbgl_frontDrawRect(&rectArea);
286}
287
288// draw letters for letters mode
289static void keyboardDrawLetters(nbgl_keyboard_t *keyboard)
290{
291 uint8_t i;
292 nbgl_area_t rectArea;
293 const char *keys;
294
295 if (keyboard->casing != LOWER_CASE) {
296 keys = kbd_chars_upper;
297 }
298 else {
299 keys = kbd_chars;
300 }
301
302 rectArea.backgroundColor = keyboard->obj.area.backgroundColor;
303 rectArea.y0 = keyboard->obj.area.y0 + LETTER_OFFSET_Y;
304 rectArea.width = 1;
305 rectArea.height = KEYBOARD_KEY_HEIGHT * 3;
306 rectArea.x0 = keyboard->obj.area.x0;
307
308 // First row of keys: 10 letters (qwertyuiop)
309 for (i = 0; i < 10; i++) {
310 rectArea.x0 = keyboard->obj.area.x0 + i * NORMAL_KEY_WIDTH;
311
312 rectArea.x0
313 += (NORMAL_KEY_WIDTH - nbgl_getCharWidth(SMALL_REGULAR_1BPP_FONT, &keys[i])) / 2;
315 &rectArea, &keys[i], 1, SMALL_REGULAR_1BPP_FONT, (IS_KEY_MASKED(i)) ? WHITE : BLACK);
316 }
317 // Second row: 9 letters (asdfghjkl)
318 rectArea.y0 += KEYBOARD_KEY_HEIGHT;
319 for (i = 10; i < 19; i++) {
320 rectArea.x0 = keyboard->obj.area.x0 + SECOND_LINE_OFFSET + (i - 10) * NORMAL_KEY_WIDTH;
321 rectArea.x0
322 += (NORMAL_KEY_WIDTH - nbgl_getCharWidth(SMALL_REGULAR_1BPP_FONT, &keys[i])) / 2;
324 &rectArea, &keys[i], 1, SMALL_REGULAR_1BPP_FONT, (IS_KEY_MASKED(i)) ? WHITE : BLACK);
325 }
326 // Third row: Shift key, 7 letters (zxcvbnm) and backspace
327 rectArea.y0 += KEYBOARD_KEY_HEIGHT;
328 uint16_t offsetX;
329 if (!keyboard->lettersOnly) {
330 // draw background rectangle
331 rectArea.width = SHIFT_KEY_WIDTH - 1;
332 rectArea.height = KEYBOARD_KEY_HEIGHT;
333 rectArea.bpp = NBGL_BPP_1;
334 rectArea.y0 = keyboard->obj.area.y0 + KEYBOARD_KEY_HEIGHT * 2;
335 rectArea.x0 = 1;
336 rectArea.backgroundColor = (keyboard->casing != LOWER_CASE) ? BLACK : WHITE;
337 nbgl_frontDrawRect(&rectArea);
338 // draw horizontal line
339 rectArea.width = SHIFT_KEY_WIDTH - 1;
340 rectArea.height = VERTICAL_ALIGNMENT;
341 rectArea.x0 = 1;
342 rectArea.y0 = keyboard->obj.area.y0 + KEYBOARD_KEY_HEIGHT * 2;
343 rectArea.backgroundColor = (keyboard->casing != LOWER_CASE) ? BLACK : WHITE;
344 nbgl_frontDrawHorizontalLine(&rectArea, 0x1, keyboard->borderColor);
345 // draw Shift key
346 rectArea.width = SHIFT_ICON.width;
347 rectArea.height = SHIFT_ICON.height;
348 rectArea.bpp = NBGL_BPP_1;
349 rectArea.y0 = (keyboard->obj.area.y0 + KEYBOARD_KEY_HEIGHT * 2
350 + (KEYBOARD_KEY_HEIGHT - rectArea.height) / 2)
351 & 0xFFC;
352 rectArea.x0 = (SHIFT_KEY_WIDTH - rectArea.width) / 2;
354 rectArea.backgroundColor = WHITE;
355 nbgl_drawIcon(&rectArea, NO_TRANSFORMATION, WHITE, &SHIFT_LOCKED_ICON);
356 }
357 else {
358 rectArea.backgroundColor = (keyboard->casing != LOWER_CASE) ? BLACK : WHITE;
360 &rectArea,
362 (keyboard->casing != LOWER_CASE) ? WHITE : BLACK,
363 (keyboard->casing == LOCKED_UPPER_CASE) ? (&SHIFT_LOCKED_ICON) : (&SHIFT_ICON));
364 rectArea.backgroundColor = WHITE;
365 }
366 offsetX = keyboard->obj.area.x0 + SHIFT_KEY_WIDTH;
367 }
368 else {
369 offsetX = 0;
370 }
371 rectArea.y0 = keyboard->obj.area.y0 + KEYBOARD_KEY_HEIGHT * 2 + LETTER_OFFSET_Y;
372 for (i = 19; i < 26; i++) {
373 rectArea.x0 = offsetX + (i - 19) * NORMAL_KEY_WIDTH;
374 rectArea.x0
375 += (NORMAL_KEY_WIDTH - nbgl_getCharWidth(SMALL_REGULAR_1BPP_FONT, &keys[i])) / 2;
377 &rectArea, &keys[i], 1, SMALL_REGULAR_1BPP_FONT, (IS_KEY_MASKED(i)) ? WHITE : BLACK);
378 }
379 // draw backspace
380 rectArea.width = BACKSPACE_ICON.width;
381 rectArea.height = BACKSPACE_ICON.height;
382 rectArea.bpp = NBGL_BPP_1;
383 rectArea.x0 = offsetX + 7 * NORMAL_KEY_WIDTH;
384 rectArea.y0 = (keyboard->obj.area.y0 + KEYBOARD_KEY_HEIGHT * 2
385 + (KEYBOARD_KEY_HEIGHT - rectArea.height) / 2)
386 & 0xFFC;
387 if (!keyboard->lettersOnly) {
388 rectArea.x0 += (BACKSPACE_KEY_WIDTH_FULL - rectArea.width) / 2;
389 }
390 else {
391 rectArea.x0 += (BACKSPACE_KEY_WIDTH_LETTERS_ONLY - rectArea.width) / 2;
392 }
393 nbgl_drawIcon(&rectArea,
396 &BACKSPACE_ICON);
397
398 // 4th row, only in Full mode
399 if (!keyboard->lettersOnly) {
400 rectArea.x0 = (SWITCH_KEY_WIDTH - nbgl_getTextWidth(SMALL_REGULAR_1BPP_FONT, ".?123")) / 2;
401 rectArea.y0 = keyboard->obj.area.y0 + KEYBOARD_KEY_HEIGHT * 3 + LETTER_OFFSET_Y;
402 nbgl_drawText(&rectArea,
403 ".?123",
404 5,
405 SMALL_REGULAR_1BPP_FONT,
407
408 rectArea.x0 = SWITCH_KEY_WIDTH + (SPACE_KEY_WIDTH - SPACE_ICON.width) / 2;
409 nbgl_drawIcon(&rectArea,
412 &SPACE_ICON);
413 }
414}
415
416// draw digits/special chars for digits/special mode
417static void keyboardDrawDigits(nbgl_keyboard_t *keyboard)
418{
419 uint8_t i;
420 nbgl_area_t rectArea;
421 const char *keys;
422
423 if (keyboard->mode == MODE_DIGITS) {
424 keys = kbd_digits;
425 }
426 else {
427 keys = kbd_specials;
428 }
429
430 rectArea.backgroundColor = keyboard->obj.area.backgroundColor;
431 rectArea.y0 = keyboard->obj.area.y0 + LETTER_OFFSET_Y;
432 rectArea.width = 1;
433 rectArea.height = KEYBOARD_KEY_HEIGHT * 3;
434 rectArea.x0 = keyboard->obj.area.x0;
435
436 // First row of keys: 10 digits (1234567890)
437 for (i = 0; i < 10; i++) {
438 rectArea.x0 = keyboard->obj.area.x0 + i * NORMAL_KEY_WIDTH;
439 rectArea.x0
440 += (NORMAL_KEY_WIDTH - nbgl_getCharWidth(SMALL_REGULAR_1BPP_FONT, &keys[i])) / 2;
442 &rectArea, &keys[i], 1, SMALL_REGULAR_1BPP_FONT, (IS_KEY_MASKED(i)) ? WHITE : BLACK);
443 }
444 // Second row: 9 keys ()
445 rectArea.y0 += KEYBOARD_KEY_HEIGHT;
446 for (i = 10; i < 19; i++) {
447 rectArea.x0 = keyboard->obj.area.x0 + (i - 10) * NORMAL_KEY_WIDTH + SECOND_LINE_OFFSET;
448 rectArea.x0
449 += (NORMAL_KEY_WIDTH - nbgl_getCharWidth(SMALL_REGULAR_1BPP_FONT, &keys[i])) / 2;
451 &rectArea, &keys[i], 1, SMALL_REGULAR_1BPP_FONT, (IS_KEY_MASKED(i)) ? WHITE : BLACK);
452 }
453 // Third row: special key, 5 keys and backspace
454
455 // draw "#+=" key
456 if (keyboard->mode == MODE_DIGITS) {
457 rectArea.x0
458 = (SPECIAL_CHARS_KEY_WIDTH - nbgl_getTextWidth(SMALL_REGULAR_1BPP_FONT, "#+=")) / 2;
459 rectArea.y0 = keyboard->obj.area.y0 + KEYBOARD_KEY_HEIGHT * 2 + LETTER_OFFSET_Y;
460 nbgl_drawText(&rectArea, "#+=", 3, SMALL_REGULAR_1BPP_FONT, BLACK);
461 }
462 else {
463 rectArea.x0
464 = (SPECIAL_CHARS_KEY_WIDTH - nbgl_getTextWidth(SMALL_REGULAR_1BPP_FONT, "123")) / 2;
465 rectArea.y0 = keyboard->obj.area.y0 + KEYBOARD_KEY_HEIGHT * 2 + LETTER_OFFSET_Y;
466 nbgl_drawText(&rectArea, "123", 3, SMALL_REGULAR_1BPP_FONT, BLACK);
467 }
468
469 for (i = 19; i < 24; i++) {
470 rectArea.x0 = SPECIAL_CHARS_KEY_WIDTH + (i - 19) * NORMAL_KEY_WIDTH;
471 rectArea.x0
472 += (NORMAL_KEY_WIDTH - nbgl_getCharWidth(SMALL_REGULAR_1BPP_FONT, &keys[i])) / 2;
474 &rectArea, &keys[i], 1, SMALL_REGULAR_1BPP_FONT, (IS_KEY_MASKED(i)) ? WHITE : BLACK);
475 }
476 // draw backspace
477 rectArea.width = BACKSPACE_ICON.width;
478 rectArea.height = BACKSPACE_ICON.height;
479 rectArea.bpp = NBGL_BPP_1;
480 rectArea.x0 = SPECIAL_CHARS_KEY_WIDTH + 5 * NORMAL_KEY_WIDTH;
481 rectArea.y0 = keyboard->obj.area.y0 + KEYBOARD_KEY_HEIGHT * 2
482 + (((KEYBOARD_KEY_HEIGHT - rectArea.height) / 2) & 0xFFC);
483 rectArea.x0 += (BACKSPACE_KEY_WIDTH_DIGITS - rectArea.width) / 2;
484 nbgl_drawIcon(&rectArea, NO_TRANSFORMATION, BLACK, &BACKSPACE_ICON);
485
486 // 4th row
487 rectArea.x0 = (SWITCH_KEY_WIDTH - nbgl_getTextWidth(SMALL_REGULAR_1BPP_FONT, "ABC")) / 2;
488 rectArea.y0 = keyboard->obj.area.y0 + KEYBOARD_KEY_HEIGHT * 3 + LETTER_OFFSET_Y;
489 nbgl_drawText(&rectArea, "ABC", 3, SMALL_REGULAR_1BPP_FONT, BLACK);
490
491 rectArea.x0 = SWITCH_KEY_WIDTH + (SPACE_KEY_WIDTH - SPACE_ICON.width) / 2;
492 nbgl_drawIcon(&rectArea,
495 &SPACE_ICON);
496}
497
498static void keyboardDraw(nbgl_keyboard_t *keyboard)
499{
500 if (keyboard->mode == MODE_LETTERS) {
501 // At first, draw grid
502 keyboardDrawLetterGrid(keyboard);
503
504 // then draw key content
505 keyboardDrawLetters(keyboard);
506 }
507 else {
509 keyboardDrawDigitsGrid(keyboard);
510
512 keyboardDrawDigits(keyboard);
513 }
514}
515
516/**********************
517 * GLOBAL FUNCTIONS
518 **********************/
519
528{
529 uint8_t firstIndex, lastIndex;
530 nbgl_touchStatePosition_t *firstPosition, *lastPosition;
531 nbgl_keyboard_t *keyboard = (nbgl_keyboard_t *) obj;
532
533 LOG_DEBUG(MISC_LOGGER, "keyboardTouchCallback(): eventType = %d\n", eventType);
534 if (eventType != TOUCHED) {
535 return;
536 }
537 if (nbgl_touchGetTouchedPosition(obj, &firstPosition, &lastPosition) == false) {
538 return;
539 }
540 // modify positions with keyboard position
541 firstPosition->x -= obj->area.x0;
542 firstPosition->y -= obj->area.y0;
543 lastPosition->x -= obj->area.x0;
544 lastPosition->y -= obj->area.y0;
545
546 firstIndex = getKeyboardIndex(keyboard, firstPosition);
547 if (firstIndex > SPECIAL_KEYS_INDEX) {
548 return;
549 }
550 lastIndex = getKeyboardIndex(keyboard, lastPosition);
551 if (lastIndex > SPECIAL_KEYS_INDEX) {
552 return;
553 }
554 // if position of finger has moved durinng press to another "key", drop it
555 if (lastIndex != firstIndex) {
556 return;
557 }
558
559 if (keyboard->mode == MODE_LETTERS) {
560 keyboardCase_t cur_casing = keyboard->casing;
561 // if the casing mode was upper (not-locked), go back to lower case
562 if ((keyboard->casing == UPPER_CASE) && (firstIndex != SHIFT_KEY_INDEX)
563 && ((IS_KEY_MASKED(firstIndex)) == 0)) {
564 keyboard->casing = LOWER_CASE;
565 // just redraw, refresh will be done by client (user of keyboard)
566 nbgl_objDraw((nbgl_obj_t *) keyboard);
567 keyboard->needsRefresh = true;
568 }
569 if ((firstIndex < 26) && ((IS_KEY_MASKED(firstIndex)) == 0)) {
570 keyboard->callback((cur_casing != LOWER_CASE) ? kbd_chars_upper[firstIndex]
571 : kbd_chars[firstIndex]);
572 }
573 else if (firstIndex == SHIFT_KEY_INDEX) {
574 switch (keyboard->casing) {
575 case LOWER_CASE:
576 keyboard->casing = UPPER_CASE;
577 break;
578 case UPPER_CASE:
579 keyboard->casing = LOCKED_UPPER_CASE;
580 break;
582 keyboard->casing = LOWER_CASE;
583 break;
584 }
585 nbgl_objDraw((nbgl_obj_t *) keyboard);
588 }
589 else if (firstIndex == DIGITS_SWITCH_KEY_INDEX) { // switch to digits
590 keyboard->mode = MODE_DIGITS;
591 nbgl_objDraw((nbgl_obj_t *) keyboard);
593 }
594 }
595 else if (keyboard->mode == MODE_DIGITS) {
596 if (firstIndex < 26) {
597 keyboard->callback(kbd_digits[firstIndex]);
598 }
599 else if (firstIndex == SPECIAL_KEYS_INDEX) {
600 keyboard->mode = MODE_SPECIAL;
601 nbgl_objDraw((nbgl_obj_t *) keyboard);
604 }
605 else if (firstIndex == DIGITS_SWITCH_KEY_INDEX) { // switch to letters
606 keyboard->mode = MODE_LETTERS;
607 nbgl_objDraw((nbgl_obj_t *) keyboard);
609 }
610 }
611 else if (keyboard->mode == MODE_SPECIAL) {
612 if (firstIndex < 26) {
613 keyboard->callback(kbd_specials[firstIndex]);
614 }
615 else if (firstIndex == SPECIAL_KEYS_INDEX) {
616 keyboard->mode = MODE_DIGITS;
617 nbgl_objDraw((nbgl_obj_t *) keyboard);
620 }
621 else if (firstIndex == DIGITS_SWITCH_KEY_INDEX) { // switch to letters
622 keyboard->mode = MODE_LETTERS;
623 nbgl_objDraw((nbgl_obj_t *) keyboard);
625 }
626 }
627 if (firstIndex == BACKSPACE_KEY_INDEX) { // backspace
628 keyboard->callback(BACKSPACE_KEY);
629 }
630 else if ((firstIndex == SPACE_KEY_INDEX) && ((IS_KEY_MASKED(SPACE_KEY_INDEX)) == 0)) { // space
631 keyboard->callback(' ');
632 }
633}
634
645bool nbgl_keyboardGetPosition(nbgl_keyboard_t *kbd, char index, uint16_t *x, uint16_t *y)
646{
647 uint8_t charIndex = 0;
648
649 while (charIndex < 26) {
650 if (index == kbd_chars[charIndex]) {
651 break;
652 }
653 charIndex++;
654 }
655
656 // if in first line
657 if (charIndex < FIRST_LINE_CHAR_COUNT) {
658 *x = kbd->obj.area.x0 + charIndex * NORMAL_KEY_WIDTH;
659 *y = kbd->obj.area.y0;
660 }
661 else if (charIndex < (FIRST_LINE_CHAR_COUNT + SECOND_LINE_CHAR_COUNT)) {
662 *x = kbd->obj.area.x0 + (charIndex - FIRST_LINE_CHAR_COUNT) * NORMAL_KEY_WIDTH
664 *y = kbd->obj.area.y0 + KEYBOARD_KEY_HEIGHT;
665 }
666 else if (charIndex < sizeof(kbd_chars)) {
667 if (kbd->mode == MODE_LETTERS) {
668 *x = kbd->obj.area.x0
669 + (charIndex - FIRST_LINE_CHAR_COUNT - SECOND_LINE_CHAR_COUNT) * NORMAL_KEY_WIDTH;
670 // shift does not exist in letters only mode
671 if (!kbd->lettersOnly) {
672 *x = *x + SHIFT_KEY_WIDTH;
673 }
674 }
675 else {
676 *x = kbd->obj.area.x0
677 + (charIndex - FIRST_LINE_CHAR_COUNT - SECOND_LINE_CHAR_COUNT) * NORMAL_KEY_WIDTH
679 }
680 *y = kbd->obj.area.y0 + 2 * KEYBOARD_KEY_HEIGHT;
681 }
682 else {
683 return false;
684 }
685 return true;
686}
687
694{
695 kbd->obj.touchMask = (1 << TOUCHED);
696 kbd->obj.touchId = KEYBOARD_ID;
697 kbd->needsRefresh = false;
698
699 keyboardDraw(kbd);
700
701#ifdef TARGET_STAX
702 // If a keyboard in the screen, exclude nothing from touch, to avoid missing touch on
703 // left keys
704 touch_exclude_borders(0);
705#endif // TARGET_STAX
706}
707#endif // HAVE_SE_TOUCH
708#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:1621
keyboardCase_t
Letters casing in which to open/set the keyboard.
Definition nbgl_obj.h:514
@ LOCKED_UPPER_CASE
locked upper case mode
Definition nbgl_obj.h:517
@ LOWER_CASE
lower case mode
Definition nbgl_obj.h:515
@ UPPER_CASE
upper case mode for one character
Definition nbgl_obj.h:516
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:501
@ MODE_DIGITS
digits and some special characters mode
Definition nbgl_obj.h:500
@ MODE_LETTERS
letters mode
Definition nbgl_obj.h:499
void nbgl_refreshSpecialWithPostRefresh(nbgl_refresh_mode_t mode, nbgl_post_refresh_t post_refresh)
Definition nbgl_obj.c:1686
@ KEYBOARD_ID
Definition nbgl_obj.h:582
#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:389
@ WHITE
Definition nbgl_types.h:126
@ BLACK
Definition nbgl_types.h:123
@ POST_REFRESH_FORCE_POWER_ON
Force screen power on after refresh.
Definition nbgl_types.h:336
nbgl_touchType_t
The different types of Touchscreen events.
Definition nbgl_types.h:241
@ TOUCHED
Definition nbgl_types.h:242
#define NO_TRANSFORMATION
Definition nbgl_types.h:76
@ NBGL_BPP_1
1 bit per pixel
Definition nbgl_types.h:266
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:312
@ FULL_COLOR_REFRESH
to be used for normal refresh
Definition nbgl_types.h:309
The low level Touchscreen event, coming from driver.
Definition nbgl_obj.h:231
int16_t y
vertical position of the touch (or for a RELEASED the last touched point)
Definition nbgl_obj.h:238
int16_t x
horizontal position of the touch (or for a RELEASED the last touched point)
Definition nbgl_obj.h:237