1
2 /**
3 * @file lv_keyboard.c
4 *
5 */
6
7 /*********************
8 * INCLUDES
9 *********************/
10 #include "lv_keyboard_private.h"
11 #include "../../core/lv_obj_class_private.h"
12 #if LV_USE_KEYBOARD
13
14 #include "../textarea/lv_textarea.h"
15 #include "../../misc/lv_assert.h"
16 #include "../../stdlib/lv_string.h"
17
18 /*********************
19 * DEFINES
20 *********************/
21 #define MY_CLASS (&lv_keyboard_class)
22 #define LV_KB_BTN(width) LV_BUTTONMATRIX_CTRL_POPOVER | width
23
24 /**********************
25 * TYPEDEFS
26 **********************/
27
28 /**********************
29 * STATIC PROTOTYPES
30 **********************/
31 static void lv_keyboard_constructor(const lv_obj_class_t * class_p, lv_obj_t * obj);
32
33 static void lv_keyboard_update_map(lv_obj_t * obj);
34
35 static void lv_keyboard_update_ctrl_map(lv_obj_t * obj);
36
37 /**********************
38 * STATIC VARIABLES
39 **********************/
40 #if LV_USE_OBJ_PROPERTY
41 static const lv_property_ops_t properties[] = {
42 {
43 .id = LV_PROPERTY_KEYBOARD_TEXTAREA,
44 .setter = lv_keyboard_set_textarea,
45 .getter = lv_keyboard_get_textarea,
46 },
47 {
48 .id = LV_PROPERTY_KEYBOARD_MODE,
49 .setter = lv_keyboard_set_mode,
50 .getter = lv_keyboard_get_mode,
51 },
52 {
53 .id = LV_PROPERTY_KEYBOARD_POPOVERS,
54 .setter = lv_keyboard_set_popovers,
55 .getter = lv_keyboard_get_popovers,
56 },
57 {
58 .id = LV_PROPERTY_KEYBOARD_SELECTED_BUTTON,
59 .setter = lv_buttonmatrix_set_selected_button,
60 .getter = lv_keyboard_get_selected_button,
61 },
62 };
63 #endif
64
65 const lv_obj_class_t lv_keyboard_class = {
66 .constructor_cb = lv_keyboard_constructor,
67 .width_def = LV_PCT(100),
68 .height_def = LV_PCT(50),
69 .instance_size = sizeof(lv_keyboard_t),
70 .editable = 1,
71 .base_class = &lv_buttonmatrix_class,
72 .name = "keyboard",
73 #if LV_USE_OBJ_PROPERTY
74 .prop_index_start = LV_PROPERTY_KEYBOARD_START,
75 .prop_index_end = LV_PROPERTY_KEYBOARD_END,
76 .properties = properties,
77 .properties_count = sizeof(properties) / sizeof(properties[0]),
78
79 #if LV_USE_OBJ_PROPERTY_NAME
80 .property_names = lv_keyboard_property_names,
81 .names_count = sizeof(lv_keyboard_property_names) / sizeof(lv_property_name_t),
82 #endif
83
84 #endif
85 };
86
87 static const char * const default_kb_map_lc[] = {"1#", "q", "w", "e", "r", "t", "y", "u", "i", "o", "p", LV_SYMBOL_BACKSPACE, "\n",
88 "ABC", "a", "s", "d", "f", "g", "h", "j", "k", "l", LV_SYMBOL_NEW_LINE, "\n",
89 "_", "-", "z", "x", "c", "v", "b", "n", "m", ".", ",", ":", "\n",
90 LV_SYMBOL_KEYBOARD,
91 #if LV_USE_ARABIC_PERSIAN_CHARS == 1
92 "أب",
93 #endif
94 LV_SYMBOL_LEFT, " ", LV_SYMBOL_RIGHT, LV_SYMBOL_OK, ""
95 };
96
97 static const lv_buttonmatrix_ctrl_t default_kb_ctrl_lc_map[] = {
98 LV_KEYBOARD_CTRL_BUTTON_FLAGS | 5, LV_KB_BTN(4), LV_KB_BTN(4), LV_KB_BTN(4), LV_KB_BTN(4), LV_KB_BTN(4), LV_KB_BTN(4), LV_KB_BTN(4), LV_KB_BTN(4), LV_KB_BTN(4), LV_KB_BTN(4), LV_BUTTONMATRIX_CTRL_CHECKED | 7,
99 LV_KEYBOARD_CTRL_BUTTON_FLAGS | 6, LV_KB_BTN(3), LV_KB_BTN(3), LV_KB_BTN(3), LV_KB_BTN(3), LV_KB_BTN(3), LV_KB_BTN(3), LV_KB_BTN(3), LV_KB_BTN(3), LV_KB_BTN(3), LV_BUTTONMATRIX_CTRL_CHECKED | 7,
100 LV_BUTTONMATRIX_CTRL_CHECKED | LV_KB_BTN(1), LV_BUTTONMATRIX_CTRL_CHECKED | LV_KB_BTN(1), LV_KB_BTN(1), LV_KB_BTN(1), LV_KB_BTN(1), LV_KB_BTN(1), LV_KB_BTN(1), LV_KB_BTN(1), LV_KB_BTN(1), LV_BUTTONMATRIX_CTRL_CHECKED | LV_KB_BTN(1), LV_BUTTONMATRIX_CTRL_CHECKED | LV_KB_BTN(1), LV_BUTTONMATRIX_CTRL_CHECKED | LV_KB_BTN(1),
101 LV_KEYBOARD_CTRL_BUTTON_FLAGS | 2,
102 #if LV_USE_ARABIC_PERSIAN_CHARS == 1
103 LV_KEYBOARD_CTRL_BUTTON_FLAGS | 2,
104 #endif
105 LV_BUTTONMATRIX_CTRL_CHECKED | 2, 6, LV_BUTTONMATRIX_CTRL_CHECKED | 2, LV_KEYBOARD_CTRL_BUTTON_FLAGS | 2
106 };
107
108 static const char * const default_kb_map_uc[] = {"1#", "Q", "W", "E", "R", "T", "Y", "U", "I", "O", "P", LV_SYMBOL_BACKSPACE, "\n",
109 "abc", "A", "S", "D", "F", "G", "H", "J", "K", "L", LV_SYMBOL_NEW_LINE, "\n",
110 "_", "-", "Z", "X", "C", "V", "B", "N", "M", ".", ",", ":", "\n",
111 LV_SYMBOL_CLOSE,
112 #if LV_USE_ARABIC_PERSIAN_CHARS == 1
113 "أب",
114 #endif
115 LV_SYMBOL_LEFT, " ", LV_SYMBOL_RIGHT, LV_SYMBOL_OK, ""
116 };
117
118 static const lv_buttonmatrix_ctrl_t default_kb_ctrl_uc_map[] = {
119 LV_KEYBOARD_CTRL_BUTTON_FLAGS | 5, LV_KB_BTN(4), LV_KB_BTN(4), LV_KB_BTN(4), LV_KB_BTN(4), LV_KB_BTN(4), LV_KB_BTN(4), LV_KB_BTN(4), LV_KB_BTN(4), LV_KB_BTN(4), LV_KB_BTN(4), LV_BUTTONMATRIX_CTRL_CHECKED | 7,
120 LV_KEYBOARD_CTRL_BUTTON_FLAGS | 6, LV_KB_BTN(3), LV_KB_BTN(3), LV_KB_BTN(3), LV_KB_BTN(3), LV_KB_BTN(3), LV_KB_BTN(3), LV_KB_BTN(3), LV_KB_BTN(3), LV_KB_BTN(3), LV_BUTTONMATRIX_CTRL_CHECKED | 7,
121 LV_BUTTONMATRIX_CTRL_CHECKED | LV_KB_BTN(1), LV_BUTTONMATRIX_CTRL_CHECKED | LV_KB_BTN(1), LV_KB_BTN(1), LV_KB_BTN(1), LV_KB_BTN(1), LV_KB_BTN(1), LV_KB_BTN(1), LV_KB_BTN(1), LV_KB_BTN(1), LV_BUTTONMATRIX_CTRL_CHECKED | LV_KB_BTN(1), LV_BUTTONMATRIX_CTRL_CHECKED | LV_KB_BTN(1), LV_BUTTONMATRIX_CTRL_CHECKED | LV_KB_BTN(1),
122 LV_KEYBOARD_CTRL_BUTTON_FLAGS | 2,
123 #if LV_USE_ARABIC_PERSIAN_CHARS == 1
124 LV_KEYBOARD_CTRL_BUTTON_FLAGS | 2,
125 #endif
126 LV_BUTTONMATRIX_CTRL_CHECKED | 2, 6, LV_BUTTONMATRIX_CTRL_CHECKED | 2, LV_KEYBOARD_CTRL_BUTTON_FLAGS | 2
127 };
128
129 #if LV_USE_ARABIC_PERSIAN_CHARS == 1
130 static const char * const default_kb_map_ar[] = {
131 "1#", "ض", "ص", "ث", "ق", "ف", "غ", "ع", "ه", "خ", "ح", "ج", "\n",
132 "ش", "س", "ي", "ب", "ل", "ا", "ت", "ن", "م", "ك", "ط", LV_SYMBOL_BACKSPACE, "\n",
133 "ذ", "ء", "ؤ", "ر", "ى", "ة", "و", "ز", "ظ", "د", "ز", "ظ", "د", "\n",
134 LV_SYMBOL_CLOSE, "abc", LV_SYMBOL_LEFT, " ", LV_SYMBOL_RIGHT, LV_SYMBOL_NEW_LINE, LV_SYMBOL_OK, ""
135 };
136
137 static const lv_buttonmatrix_ctrl_t default_kb_ctrl_ar_map[] = {
138 LV_KEYBOARD_CTRL_BUTTON_FLAGS | 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
139 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 7,
140 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
141 LV_KEYBOARD_CTRL_BUTTON_FLAGS | 2, LV_KEYBOARD_CTRL_BUTTON_FLAGS | 2, 2, 6, 2, 3, LV_KEYBOARD_CTRL_BUTTON_FLAGS | 2
142 };
143 #endif
144
145 static const char * const default_kb_map_spec[] = {"1", "2", "3", "4", "5", "6", "7", "8", "9", "0", LV_SYMBOL_BACKSPACE, "\n",
146 "abc", "+", "&", "/", "*", "=", "%", "!", "?", "#", "<", ">", "\n",
147 "\\", "@", "$", "(", ")", "{", "}", "[", "]", ";", "\"", "'", "\n",
148 LV_SYMBOL_KEYBOARD,
149 #if LV_USE_ARABIC_PERSIAN_CHARS == 1
150 "أب",
151 #endif
152 LV_SYMBOL_LEFT, " ", LV_SYMBOL_RIGHT, LV_SYMBOL_OK, ""
153 };
154
155 static const lv_buttonmatrix_ctrl_t default_kb_ctrl_spec_map[] = {
156 LV_KB_BTN(1), LV_KB_BTN(1), LV_KB_BTN(1), LV_KB_BTN(1), LV_KB_BTN(1), LV_KB_BTN(1), LV_KB_BTN(1), LV_KB_BTN(1), LV_KB_BTN(1), LV_KB_BTN(1), LV_BUTTONMATRIX_CTRL_CHECKED | 2,
157 LV_KEYBOARD_CTRL_BUTTON_FLAGS | 2, LV_KB_BTN(1), LV_KB_BTN(1), LV_KB_BTN(1), LV_KB_BTN(1), LV_KB_BTN(1), LV_KB_BTN(1), LV_KB_BTN(1), LV_KB_BTN(1), LV_KB_BTN(1), LV_KB_BTN(1), LV_KB_BTN(1), LV_KB_BTN(1),
158 LV_KB_BTN(1), LV_KB_BTN(1), LV_KB_BTN(1), LV_KB_BTN(1), LV_KB_BTN(1), LV_KB_BTN(1), LV_KB_BTN(1), LV_KB_BTN(1), LV_KB_BTN(1), LV_KB_BTN(1), LV_KB_BTN(1),
159 LV_KEYBOARD_CTRL_BUTTON_FLAGS | 2,
160 #if LV_USE_ARABIC_PERSIAN_CHARS == 1
161 LV_KEYBOARD_CTRL_BUTTON_FLAGS | 2,
162 #endif
163 LV_BUTTONMATRIX_CTRL_CHECKED | 2, 6, LV_BUTTONMATRIX_CTRL_CHECKED | 2, LV_KEYBOARD_CTRL_BUTTON_FLAGS | 2
164 };
165
166 static const char * const default_kb_map_num[] = {"1", "2", "3", LV_SYMBOL_KEYBOARD, "\n",
167 "4", "5", "6", LV_SYMBOL_OK, "\n",
168 "7", "8", "9", LV_SYMBOL_BACKSPACE, "\n",
169 "+/-", "0", ".", LV_SYMBOL_LEFT, LV_SYMBOL_RIGHT, ""
170 };
171
172 static const lv_buttonmatrix_ctrl_t default_kb_ctrl_num_map[] = {
173 1, 1, 1, LV_KEYBOARD_CTRL_BUTTON_FLAGS | 2,
174 1, 1, 1, LV_KEYBOARD_CTRL_BUTTON_FLAGS | 2,
175 1, 1, 1, 2,
176 1, 1, 1, 1, 1
177 };
178
179 static const char * const * kb_map[10] = {
180 default_kb_map_lc,
181 default_kb_map_uc,
182 default_kb_map_spec,
183 default_kb_map_num,
184 default_kb_map_lc,
185 default_kb_map_lc,
186 default_kb_map_lc,
187 default_kb_map_lc,
188 #if LV_USE_ARABIC_PERSIAN_CHARS == 1
189 default_kb_map_ar,
190 #endif
191 NULL
192 };
193 static const lv_buttonmatrix_ctrl_t * kb_ctrl[10] = {
194 default_kb_ctrl_lc_map,
195 default_kb_ctrl_uc_map,
196 default_kb_ctrl_spec_map,
197 default_kb_ctrl_num_map,
198 default_kb_ctrl_lc_map,
199 default_kb_ctrl_lc_map,
200 default_kb_ctrl_lc_map,
201 default_kb_ctrl_lc_map,
202 #if LV_USE_ARABIC_PERSIAN_CHARS == 1
203 default_kb_ctrl_ar_map,
204 #endif
205 NULL
206 };
207
208 /**********************
209 * MACROS
210 **********************/
211
212 /**********************
213 * GLOBAL FUNCTIONS
214 **********************/
215
lv_keyboard_create(lv_obj_t * parent)216 lv_obj_t * lv_keyboard_create(lv_obj_t * parent)
217 {
218 LV_LOG_INFO("begin");
219 lv_obj_t * obj = lv_obj_class_create_obj(&lv_keyboard_class, parent);
220 lv_obj_class_init_obj(obj);
221 return obj;
222 }
223
224 /*=====================
225 * Setter functions
226 *====================*/
227
lv_keyboard_set_textarea(lv_obj_t * obj,lv_obj_t * ta)228 void lv_keyboard_set_textarea(lv_obj_t * obj, lv_obj_t * ta)
229 {
230 if(ta) {
231 LV_ASSERT_OBJ(ta, &lv_textarea_class);
232 }
233
234 LV_ASSERT_OBJ(obj, MY_CLASS);
235 lv_keyboard_t * keyboard = (lv_keyboard_t *)obj;
236
237 /*Hide the cursor of the old Text area if cursor management is enabled*/
238 if(keyboard->ta) {
239 lv_obj_remove_state(obj, LV_STATE_FOCUSED);
240 }
241
242 keyboard->ta = ta;
243
244 /*Show the cursor of the new Text area if cursor management is enabled*/
245 if(keyboard->ta) {
246 lv_obj_add_state(obj, LV_STATE_FOCUSED);
247 }
248 }
249
lv_keyboard_set_mode(lv_obj_t * obj,lv_keyboard_mode_t mode)250 void lv_keyboard_set_mode(lv_obj_t * obj, lv_keyboard_mode_t mode)
251 {
252 LV_ASSERT_OBJ(obj, MY_CLASS);
253 lv_keyboard_t * keyboard = (lv_keyboard_t *)obj;
254 if(keyboard->mode == mode) return;
255
256 keyboard->mode = mode;
257 lv_keyboard_update_map(obj);
258 }
259
lv_keyboard_set_popovers(lv_obj_t * obj,bool en)260 void lv_keyboard_set_popovers(lv_obj_t * obj, bool en)
261 {
262 lv_keyboard_t * keyboard = (lv_keyboard_t *)obj;
263
264 if(keyboard->popovers == en) {
265 return;
266 }
267
268 keyboard->popovers = en;
269 lv_keyboard_update_ctrl_map(obj);
270 }
271
lv_keyboard_set_map(lv_obj_t * obj,lv_keyboard_mode_t mode,const char * const map[],const lv_buttonmatrix_ctrl_t ctrl_map[])272 void lv_keyboard_set_map(lv_obj_t * obj, lv_keyboard_mode_t mode, const char * const map[],
273 const lv_buttonmatrix_ctrl_t ctrl_map[])
274 {
275 LV_ASSERT_OBJ(obj, MY_CLASS);
276 kb_map[mode] = map;
277 kb_ctrl[mode] = ctrl_map;
278 lv_keyboard_update_map(obj);
279 }
280
281 /*=====================
282 * Getter functions
283 *====================*/
284
lv_keyboard_get_textarea(const lv_obj_t * obj)285 lv_obj_t * lv_keyboard_get_textarea(const lv_obj_t * obj)
286 {
287 LV_ASSERT_OBJ(obj, MY_CLASS);
288 lv_keyboard_t * keyboard = (lv_keyboard_t *)obj;
289 return keyboard->ta;
290 }
291
lv_keyboard_get_mode(const lv_obj_t * obj)292 lv_keyboard_mode_t lv_keyboard_get_mode(const lv_obj_t * obj)
293 {
294 LV_ASSERT_OBJ(obj, MY_CLASS);
295 lv_keyboard_t * keyboard = (lv_keyboard_t *)obj;
296 return keyboard->mode;
297 }
298
lv_keyboard_get_popovers(const lv_obj_t * obj)299 bool lv_keyboard_get_popovers(const lv_obj_t * obj)
300 {
301 lv_keyboard_t * keyboard = (lv_keyboard_t *)obj;
302 return keyboard->popovers;
303 }
304
305 /*=====================
306 * Other functions
307 *====================*/
308
lv_keyboard_def_event_cb(lv_event_t * e)309 void lv_keyboard_def_event_cb(lv_event_t * e)
310 {
311 lv_obj_t * obj = lv_event_get_current_target(e);
312
313 LV_ASSERT_OBJ(obj, MY_CLASS);
314 lv_keyboard_t * keyboard = (lv_keyboard_t *)obj;
315 uint32_t btn_id = lv_buttonmatrix_get_selected_button(obj);
316 if(btn_id == LV_BUTTONMATRIX_BUTTON_NONE) return;
317
318 const char * txt = lv_buttonmatrix_get_button_text(obj, btn_id);
319 if(txt == NULL) return;
320
321 if(lv_strcmp(txt, "abc") == 0) {
322 keyboard->mode = LV_KEYBOARD_MODE_TEXT_LOWER;
323 lv_buttonmatrix_set_map(obj, kb_map[LV_KEYBOARD_MODE_TEXT_LOWER]);
324 lv_keyboard_update_ctrl_map(obj);
325 return;
326 }
327 #if LV_USE_ARABIC_PERSIAN_CHARS == 1
328 else if(lv_strcmp(txt, "أب") == 0) {
329 keyboard->mode = LV_KEYBOARD_MODE_TEXT_ARABIC;
330 lv_buttonmatrix_set_map(obj, kb_map[LV_KEYBOARD_MODE_TEXT_ARABIC]);
331 lv_keyboard_update_ctrl_map(obj);
332 return;
333 }
334 #endif
335 else if(lv_strcmp(txt, "ABC") == 0) {
336 keyboard->mode = LV_KEYBOARD_MODE_TEXT_UPPER;
337 lv_buttonmatrix_set_map(obj, kb_map[LV_KEYBOARD_MODE_TEXT_UPPER]);
338 lv_keyboard_update_ctrl_map(obj);
339 return;
340 }
341 else if(lv_strcmp(txt, "1#") == 0) {
342 keyboard->mode = LV_KEYBOARD_MODE_SPECIAL;
343 lv_buttonmatrix_set_map(obj, kb_map[LV_KEYBOARD_MODE_SPECIAL]);
344 lv_keyboard_update_ctrl_map(obj);
345 return;
346 }
347 else if(lv_strcmp(txt, LV_SYMBOL_CLOSE) == 0 || lv_strcmp(txt, LV_SYMBOL_KEYBOARD) == 0) {
348 lv_result_t res = lv_obj_send_event(obj, LV_EVENT_CANCEL, NULL);
349 if(res != LV_RESULT_OK) return;
350
351 if(keyboard->ta) {
352 res = lv_obj_send_event(keyboard->ta, LV_EVENT_CANCEL, NULL);
353 if(res != LV_RESULT_OK) return;
354 }
355 return;
356 }
357 else if(lv_strcmp(txt, LV_SYMBOL_OK) == 0) {
358 lv_result_t res = lv_obj_send_event(obj, LV_EVENT_READY, NULL);
359 if(res != LV_RESULT_OK) return;
360
361 if(keyboard->ta) {
362 res = lv_obj_send_event(keyboard->ta, LV_EVENT_READY, NULL);
363 if(res != LV_RESULT_OK) return;
364 }
365 return;
366 }
367
368 /*Add the characters to the text area if set*/
369 if(keyboard->ta == NULL) return;
370
371 if(lv_strcmp(txt, "Enter") == 0 || lv_strcmp(txt, LV_SYMBOL_NEW_LINE) == 0) {
372 lv_textarea_add_char(keyboard->ta, '\n');
373 if(lv_textarea_get_one_line(keyboard->ta)) {
374 lv_result_t res = lv_obj_send_event(keyboard->ta, LV_EVENT_READY, NULL);
375 if(res != LV_RESULT_OK) return;
376 }
377 }
378 else if(lv_strcmp(txt, LV_SYMBOL_LEFT) == 0) {
379 lv_textarea_cursor_left(keyboard->ta);
380 }
381 else if(lv_strcmp(txt, LV_SYMBOL_RIGHT) == 0) {
382 lv_textarea_cursor_right(keyboard->ta);
383 }
384 else if(lv_strcmp(txt, LV_SYMBOL_BACKSPACE) == 0) {
385 lv_textarea_delete_char(keyboard->ta);
386 }
387 else if(lv_strcmp(txt, "+/-") == 0) {
388 uint32_t cur = lv_textarea_get_cursor_pos(keyboard->ta);
389 const char * ta_txt = lv_textarea_get_text(keyboard->ta);
390 if(ta_txt[0] == '-') {
391 lv_textarea_set_cursor_pos(keyboard->ta, 1);
392 lv_textarea_delete_char(keyboard->ta);
393 lv_textarea_add_char(keyboard->ta, '+');
394 lv_textarea_set_cursor_pos(keyboard->ta, cur);
395 }
396 else if(ta_txt[0] == '+') {
397 lv_textarea_set_cursor_pos(keyboard->ta, 1);
398 lv_textarea_delete_char(keyboard->ta);
399 lv_textarea_add_char(keyboard->ta, '-');
400 lv_textarea_set_cursor_pos(keyboard->ta, cur);
401 }
402 else {
403 lv_textarea_set_cursor_pos(keyboard->ta, 0);
404 lv_textarea_add_char(keyboard->ta, '-');
405 lv_textarea_set_cursor_pos(keyboard->ta, cur + 1);
406 }
407 }
408 else {
409 lv_textarea_add_text(keyboard->ta, txt);
410 }
411 }
412
lv_keyboard_get_map_array(const lv_obj_t * kb)413 const char * const * lv_keyboard_get_map_array(const lv_obj_t * kb)
414 {
415 return lv_buttonmatrix_get_map(kb);
416 }
417
lv_keyboard_get_selected_button(const lv_obj_t * obj)418 uint32_t lv_keyboard_get_selected_button(const lv_obj_t * obj)
419 {
420 return lv_buttonmatrix_get_selected_button(obj);
421 }
422
lv_keyboard_get_button_text(const lv_obj_t * obj,uint32_t btn_id)423 const char * lv_keyboard_get_button_text(const lv_obj_t * obj, uint32_t btn_id)
424 {
425 return lv_buttonmatrix_get_button_text(obj, btn_id);
426 }
427
428 /**********************
429 * STATIC FUNCTIONS
430 **********************/
431
lv_keyboard_constructor(const lv_obj_class_t * class_p,lv_obj_t * obj)432 static void lv_keyboard_constructor(const lv_obj_class_t * class_p, lv_obj_t * obj)
433 {
434 LV_UNUSED(class_p);
435 lv_obj_remove_flag(obj, LV_OBJ_FLAG_CLICK_FOCUSABLE);
436
437 lv_keyboard_t * keyboard = (lv_keyboard_t *)obj;
438 keyboard->ta = NULL;
439 keyboard->mode = LV_KEYBOARD_MODE_TEXT_LOWER;
440 keyboard->popovers = 0;
441
442 lv_obj_align(obj, LV_ALIGN_BOTTOM_MID, 0, 0);
443 lv_obj_add_event_cb(obj, lv_keyboard_def_event_cb, LV_EVENT_VALUE_CHANGED, NULL);
444 lv_obj_set_style_base_dir(obj, LV_BASE_DIR_LTR, 0);
445
446 lv_keyboard_update_map(obj);
447 }
448
449 /**
450 * Update the key and control map for the current mode
451 * @param obj pointer to a keyboard object
452 */
lv_keyboard_update_map(lv_obj_t * obj)453 static void lv_keyboard_update_map(lv_obj_t * obj)
454 {
455 lv_keyboard_t * keyboard = (lv_keyboard_t *)obj;
456 lv_buttonmatrix_set_map(obj, kb_map[keyboard->mode]);
457 lv_keyboard_update_ctrl_map(obj);
458 }
459
460 /**
461 * Update the control map for the current mode
462 * @param obj pointer to a keyboard object
463 */
lv_keyboard_update_ctrl_map(lv_obj_t * obj)464 static void lv_keyboard_update_ctrl_map(lv_obj_t * obj)
465 {
466 lv_keyboard_t * keyboard = (lv_keyboard_t *)obj;
467
468 if(keyboard->popovers) {
469 /*Apply the current control map (already includes LV_BUTTONMATRIX_CTRL_POPOVER flags)*/
470 lv_buttonmatrix_set_ctrl_map(obj, kb_ctrl[keyboard->mode]);
471 }
472 else {
473 /*Make a copy of the current control map*/
474 lv_buttonmatrix_t * btnm = (lv_buttonmatrix_t *)obj;
475 lv_buttonmatrix_ctrl_t * ctrl_map = lv_malloc(btnm->btn_cnt * sizeof(lv_buttonmatrix_ctrl_t));
476 lv_memcpy(ctrl_map, kb_ctrl[keyboard->mode], sizeof(lv_buttonmatrix_ctrl_t) * btnm->btn_cnt);
477
478 /*Remove all LV_BUTTONMATRIX_CTRL_POPOVER flags*/
479 uint32_t i;
480 for(i = 0; i < btnm->btn_cnt; i++) {
481 ctrl_map[i] &= (~LV_BUTTONMATRIX_CTRL_POPOVER);
482 }
483
484 /*Apply new control map and clean up*/
485 lv_buttonmatrix_set_ctrl_map(obj, ctrl_map);
486 lv_free(ctrl_map);
487 }
488 }
489
490 #endif /*LV_USE_KEYBOARD*/
491