Embedded SDK
Embedded SDK
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 #else
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 #ifdef TARGET_STAX
40 #define SPACE_KEY_WIDTH 276
41 #else // TARGET_STAX
42 #define SPACE_KEY_WIDTH 336
43 #endif // TARGET_STAX
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  **********************/
63 static const char kbd_chars[] = "qwertyuiopasdfghjklzxcvbnm";
64 static const char kbd_chars_upper[] = "QWERTYUIOPASDFGHJKLZXCVBNM";
65 const char kbd_digits[] = "1234567890-/:;()&@\".,?!\'";
66 static const char kbd_specials[] = "[]{}#%^*+=_\\|~<>$`\".,?!\'";
67 
68 /**********************
69  * VARIABLES
70  **********************/
71 
72 /**********************
73  * STATIC FUNCTIONS
74  **********************/
75 static 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:
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) {
96  i = SHIFT_KEY_INDEX;
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 {
109  // Backspace key is larger...
110  if (i >= 26) {
112  }
113  }
114  }
115  else {
116  if (position->x < SPECIAL_CHARS_KEY_WIDTH) {
117  i = SPECIAL_KEYS_INDEX;
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
142 static 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 = 4;
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
188 static 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
244 static 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
288 static 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 = 4;
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;
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
416 static 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;
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 
497 static 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;
580  case LOCKED_UPPER_CASE:
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
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
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:372
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:360
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
#define BACKSPACE_ICON
Definition: nbgl_obj.h:132
void nbgl_objDraw(nbgl_obj_t *obj)
This function draws or redraws the given object and its children (recursive version)
Definition: nbgl_obj.c:1521
#define SHIFT_LOCKED_ICON
Definition: nbgl_obj.h:134
keyboardCase_t
Letters casing in which to open/set the keyboard.
Definition: nbgl_obj.h:489
@ LOCKED_UPPER_CASE
locked upper case mode
Definition: nbgl_obj.h:492
@ LOWER_CASE
lower case mode
Definition: nbgl_obj.h:490
@ UPPER_CASE
upper case mode for one character
Definition: nbgl_obj.h:491
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:476
@ MODE_DIGITS
digits and some special characters mode
Definition: nbgl_obj.h:475
@ MODE_LETTERS
letters mode
Definition: nbgl_obj.h:474
void nbgl_refreshSpecialWithPostRefresh(nbgl_refresh_mode_t mode, nbgl_post_refresh_t post_refresh)
Definition: nbgl_obj.c:1586
#define KEYBOARD_KEY_HEIGHT
Definition: nbgl_obj.h:35
#define SHIFT_ICON
Definition: nbgl_obj.h:133
#define SPACE_ICON
Definition: nbgl_obj.h:131
@ KEYBOARD_ID
Definition: nbgl_obj.h:556
#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
#define SPACE_KEY_WIDTH
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 LETTER_OFFSET_Y
#define SWITCH_KEY_WIDTH
#define FIRST_LINE_CHAR_COUNT
#define BACKSPACE_KEY_WIDTH_FULL
#define SECOND_LINE_CHAR_COUNT
#define NORMAL_KEY_WIDTH
#define IS_KEY_MASKED(_index)
bool nbgl_touchGetTouchedPosition(nbgl_obj_t *obj, nbgl_touchStatePosition_t **firstPos, nbgl_touchStatePosition_t **lastPos)
Definition: nbgl_touch.c:364
@ WHITE
Definition: nbgl_types.h:105
@ BLACK
Definition: nbgl_types.h:102
@ POST_REFRESH_FORCE_POWER_ON
Force screen power on after refresh.
Definition: nbgl_types.h:317
nbgl_touchType_t
The different types of Touchscreen events.
Definition: nbgl_types.h:220
@ TOUCHED
Definition: nbgl_types.h:221
#define NO_TRANSFORMATION
Definition: nbgl_types.h:55
@ NBGL_BPP_1
1 bit per pixel
Definition: nbgl_types.h:245
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:291
@ FULL_COLOR_REFRESH
to be used for normal refresh
Definition: nbgl_types.h:288
The low level Touchscreen event, coming from driver.
Definition: nbgl_obj.h:206
int16_t y
vertical position of the touch (or for a RELEASED the last touched point)
Definition: nbgl_obj.h:213
int16_t x
horizontal position of the touch (or for a RELEASED the last touched point)
Definition: nbgl_obj.h:212
unsigned short uint16_t
Definition: usbd_conf.h:54
unsigned char uint8_t
Definition: usbd_conf.h:53