Embedded SDK
Embedded SDK
nbgl_obj_keypad_nanos.c
Go to the documentation of this file.
1 
8 #ifdef NBGL_KEYPAD
9 #ifndef 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_screen.h"
20 #include "glyphs.h"
21 #include "os_io_seproxyhal.h"
22 #include "lcx_rng.h"
23 
24 /*********************
25  * DEFINES
26  *********************/
27 #define KEY_WIDTH 9
28 #define DIGIT_HEIGHT 12
29 #define DIGIT_OFFSET_X 13
30 #define DIGIT_OFFSET_Y ((KEYPAD_HEIGHT - DIGIT_HEIGHT) / 2)
31 #define INIT_DIGIT_VALUE 5
32 
33 /**********************
34  * TYPEDEFS
35  **********************/
36 
37 /**********************
38  * STATIC VARIABLES
39  **********************/
40 static const nbgl_icon_details_t *digits_icons[] = {&C_digit_0,
41  &C_digit_1,
42  &C_digit_2,
43  &C_digit_3,
44  &C_digit_4,
45  &C_digit_5,
46  &C_digit_6,
47  &C_digit_7,
48  &C_digit_8,
49  &C_digit_9};
50 /**********************
51  * VARIABLES
52  **********************/
53 
54 /**********************
55  * STATIC FUNCTIONS
56  **********************/
57 static char positionToChar(uint8_t pos)
58 {
59  if (pos == 0) {
60  return BACKSPACE_KEY;
61  }
62  else if (pos == 11) {
63  return VALIDATE_KEY;
64  }
65  else {
66  return 0x30 + (pos - 1);
67  }
68 }
69 
70 static void keypadDrawDigits(nbgl_keypad_t *keypad)
71 {
72  uint8_t i;
73  nbgl_area_t rectArea;
74 
75  // clean full area
76  rectArea.backgroundColor = BLACK;
77  rectArea.x0 = keypad->obj.area.x0;
78  rectArea.y0 = keypad->obj.area.y0;
79  rectArea.width = keypad->obj.area.width;
80  rectArea.height = keypad->obj.area.height;
81  nbgl_frontDrawRect(&rectArea);
82 
83  rectArea.backgroundColor = BLACK;
84  rectArea.y0 = keypad->obj.area.y0 + DIGIT_OFFSET_Y;
85  rectArea.bpp = NBGL_BPP_1;
86  // row of digits: 0 1 2 3... 9
87  for (i = 0; i < 10; i++) {
88  rectArea.width = digits_icons[i]->width;
89  rectArea.height = digits_icons[i]->height;
90 
91  rectArea.x0 = keypad->obj.area.x0 + DIGIT_OFFSET_X + i * KEY_WIDTH;
92  nbgl_frontDrawImage(&rectArea, digits_icons[i]->bitmap, NO_TRANSFORMATION, WHITE);
93  }
94  // draw backspace
95  if (keypad->enableBackspace) {
96  rectArea.width = C_icon_backspace.width;
97  rectArea.height = C_icon_backspace.height;
98  rectArea.x0 = keypad->obj.area.x0;
99  rectArea.y0 = keypad->obj.area.y0 + ((KEYPAD_HEIGHT - C_icon_backspace.height) / 2);
100  nbgl_frontDrawImage(&rectArea, C_icon_backspace.bitmap, NO_TRANSFORMATION, WHITE);
101  }
102 
103  // draw validate
104  if (keypad->enableValidate) {
105  rectArea.width = C_digit_validate_bold.width;
106  rectArea.height = C_digit_validate_bold.height;
107  rectArea.x0 = keypad->obj.area.x0 + KEYPAD_WIDTH - C_digit_validate_bold.width;
108  rectArea.y0 = keypad->obj.area.y0 + ((KEYPAD_HEIGHT - C_digit_validate_bold.height) / 2);
109  nbgl_frontDrawImage(&rectArea, C_digit_validate_bold.bitmap, NO_TRANSFORMATION, WHITE);
110  }
111 }
112 
113 static void keypadDrawSelected(nbgl_keypad_t *keypad)
114 {
115  nbgl_area_t rectArea;
117  rectArea.backgroundColor = WHITE;
118 
119  if (keypad->selectedKey == 0) {
120  rectArea.x0 = keypad->obj.area.x0;
121  }
122  else if (keypad->selectedKey < 11) { // if it's a digit
123  rectArea.x0 = keypad->obj.area.x0 + DIGIT_OFFSET_X + (keypad->selectedKey - 1) * KEY_WIDTH;
124  }
125  else if (keypad->selectedKey == 11) {
126  rectArea.x0 = keypad->obj.area.x0 + KEYPAD_WIDTH - C_digit_validate_bold.width;
127  }
128  else {
129  return;
130  }
131  rectArea.y0 = keypad->obj.area.y0 + keypad->obj.area.height - 2;
132  rectArea.width = 8;
133  rectArea.height = 2;
134  nbgl_frontDrawRect(&rectArea);
135 }
136 
137 static void keypadDrawSelectedTouched(nbgl_keypad_t *keypad)
138 {
139  nbgl_area_t rectArea;
141  rectArea.backgroundColor = WHITE;
142 
143  if (keypad->selectedKey == 0) {
144  rectArea.x0 = keypad->obj.area.x0;
145  }
146  else if (keypad->selectedKey < 11) { // if it's a digit
147  rectArea.x0 = keypad->obj.area.x0 + DIGIT_OFFSET_X + (keypad->selectedKey - 1) * KEY_WIDTH;
148  }
149  else if (keypad->selectedKey == 11) {
150  rectArea.x0 = keypad->obj.area.x0 + KEYPAD_WIDTH - C_digit_validate_bold.width;
151  }
152  else {
153  return;
154  }
155  rectArea.y0 = keypad->obj.area.y0;
156  rectArea.width = 8;
157  rectArea.height = 2;
158  nbgl_frontDrawRect(&rectArea);
160 }
161 
162 static void keypadInitSelected(nbgl_keypad_t *keypad)
163 {
164  if (!keypad->shuffled) {
165  keypad->selectedKey = 1 + INIT_DIGIT_VALUE;
166  }
167  else {
168  uint8_t nbChoices = 10;
169  uint8_t random;
170  if (keypad->enableBackspace) {
171  nbChoices++;
172  }
173  if (keypad->enableValidate) {
174  nbChoices++;
175  }
176  random = cx_rng_u32_range(0, nbChoices);
177  if (random < 10) {
178  keypad->selectedKey = 1 + random;
179  }
180  else if (random == 10) {
181  keypad->selectedKey = 0;
182  }
183  else if (random == 11) {
184  keypad->selectedKey = 11;
185  }
186  }
187 }
188 
189 /**********************
190  * GLOBAL FUNCTIONS
191  **********************/
192 
200 void nbgl_keypadCallback(nbgl_obj_t *obj, nbgl_buttonEvent_t buttonEvent)
201 {
202  nbgl_keypad_t *keypad = (nbgl_keypad_t *) obj;
203 
204  LOG_DEBUG(OBJ_LOGGER, "nbgl_keypadCallback(): buttonEvent = %d\n", buttonEvent);
205 
206  if (buttonEvent == BUTTON_BOTH_TOUCHED) {
207  // draw bar upper selected key
208  keypadDrawSelectedTouched(keypad);
209  }
210  else if (buttonEvent == BUTTON_BOTH_PRESSED) {
211  keypad->callback(positionToChar(keypad->selectedKey));
212  }
213  else if ((buttonEvent == BUTTON_LEFT_PRESSED)
214  || (buttonEvent == BUTTON_LEFT_CONTINUOUS_PRESSED)) {
215  switch (keypad->selectedKey) {
216  case 1:
217  if (keypad->enableBackspace) {
218  keypad->selectedKey = 0;
219  }
220  else {
221  keypad->selectedKey = 10;
222  }
223  break;
224  case 0: // backspace
225  if (keypad->enableValidate) {
226  keypad->selectedKey = 11;
227  }
228  else {
229  keypad->selectedKey = 10;
230  }
231  break;
232  default:
233  keypad->selectedKey--;
234  break;
235  }
237  }
238  else if ((buttonEvent == BUTTON_RIGHT_PRESSED)
239  || (buttonEvent == BUTTON_RIGHT_CONTINUOUS_PRESSED)) {
240  switch (keypad->selectedKey) {
241  case 10: // '9'
242  if (keypad->enableValidate) {
243  keypad->selectedKey = 11;
244  }
245  else if (keypad->enableBackspace) {
246  keypad->selectedKey = 0;
247  }
248  else {
249  keypad->selectedKey = 1;
250  }
251  break;
252  case 11: // validate
253  keypad->selectedKey = 0;
254  break;
255  default:
256  keypad->selectedKey++;
257  break;
258  }
260  }
261 }
262 
269 void nbgl_objDrawKeypad(nbgl_keypad_t *keypad)
270 {
271  LOG_DEBUG(OBJ_LOGGER, "nbgl_objDrawKeypad keypad->shuffled= %d\n", keypad->shuffled);
272  // draw digits content
273  keypadDrawDigits(keypad);
274  if (keypad->selectedKey == 0xFF) {
275  keypadInitSelected(keypad);
276  }
277  keypadDrawSelected(keypad);
278 }
279 
280 #endif // HAVE_SE_TOUCH
281 #endif // NBGL_KEYPAD
Random Number Generation.
debug traces management
#define LOG_DEBUG(__logger,...)
Definition: nbgl_debug.h:86
@ OBJ_LOGGER
Definition: nbgl_debug.h:30
Middle Level API of the new BOLOS Graphical Library.
Font screen low-Level driver API, to draw elementary forms.
void nbgl_frontDrawImage(const nbgl_area_t *area, const uint8_t *buffer, nbgl_transformation_t transformation, nbgl_color_map_t colorMap)
void nbgl_frontRefreshArea(const nbgl_area_t *area, nbgl_refresh_mode_t mode, nbgl_post_refresh_t post_refresh)
void nbgl_frontDrawRect(const nbgl_area_t *area)
API to draw all basic graphic objects.
struct PACKED__ nbgl_keypad_s nbgl_keypad_t
struct to represent a keypad (KEYPAD type)
nbgl_buttonEvent_t
Definition: nbgl_obj.h:182
@ BUTTON_BOTH_TOUCHED
Sent when both buttons are touched.
Definition: nbgl_obj.h:190
@ BUTTON_LEFT_CONTINUOUS_PRESSED
Definition: nbgl_obj.h:185
@ BUTTON_BOTH_PRESSED
Sent when both buttons are released.
Definition: nbgl_obj.h:189
@ BUTTON_RIGHT_CONTINUOUS_PRESSED
Definition: nbgl_obj.h:187
@ BUTTON_LEFT_PRESSED
Sent when Left button is released.
Definition: nbgl_obj.h:183
@ BUTTON_RIGHT_PRESSED
Send when Right button is released.
Definition: nbgl_obj.h:184
#define BACKSPACE_KEY
Definition: nbgl_obj.h:26
void nbgl_objDrawKeypad(nbgl_keypad_t *kbd)
This function draws a keypad object.
#define VALIDATE_KEY
Definition: nbgl_obj.h:27
struct PACKED__ nbgl_obj_s nbgl_obj_t
Common structure for all graphical objects.
#define KEY_WIDTH
#define DIGIT_OFFSET_Y
API to manage screens.
void nbgl_screenRedraw(void)
This function redraws the whole screen on top of stack and its children.
Definition: nbgl_screen.c:66
@ WHITE
Definition: nbgl_types.h:105
@ BLACK
Definition: nbgl_types.h:102
@ POST_REFRESH_KEEP_POWER_STATE
Keep state after refresh.
Definition: nbgl_types.h:319
struct PACKED__ nbgl_icon_details_s nbgl_icon_details_t
Represents all information about an icon.
#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.
@ FULL_COLOR_CLEAN_REFRESH
to be used for lock screen display (cleaner but longer refresh)
Definition: nbgl_types.h:290
unsigned char uint8_t
Definition: usbd_conf.h:53