431 lines
16 KiB
C
431 lines
16 KiB
C
|
|
/**
|
|
* @file lv_keyboard.c
|
|
*
|
|
*/
|
|
|
|
/*********************
|
|
* INCLUDES
|
|
*********************/
|
|
#include "lv_keyboard.h"
|
|
#if LV_USE_KEYBOARD
|
|
|
|
#include "../../../widgets/lv_textarea.h"
|
|
#include "../../../misc/lv_assert.h"
|
|
|
|
#include <stdlib.h>
|
|
|
|
/*********************
|
|
* DEFINES
|
|
*********************/
|
|
#define MY_CLASS &lv_keyboard_class
|
|
#define LV_KB_BTN(width) LV_BTNMATRIX_CTRL_POPOVER | width
|
|
|
|
/**********************
|
|
* TYPEDEFS
|
|
**********************/
|
|
|
|
/**********************
|
|
* STATIC PROTOTYPES
|
|
**********************/
|
|
static void lv_keyboard_constructor(const lv_obj_class_t * class_p, lv_obj_t * obj);
|
|
|
|
static void lv_keyboard_update_map(lv_obj_t * obj);
|
|
|
|
static void lv_keyboard_update_ctrl_map(lv_obj_t * obj);
|
|
|
|
/**********************
|
|
* STATIC VARIABLES
|
|
**********************/
|
|
const lv_obj_class_t lv_keyboard_class = {
|
|
.constructor_cb = lv_keyboard_constructor,
|
|
.width_def = LV_PCT(100),
|
|
.height_def = LV_PCT(50),
|
|
.instance_size = sizeof(lv_keyboard_t),
|
|
.editable = 1,
|
|
.base_class = &lv_btnmatrix_class
|
|
};
|
|
|
|
static const char * const default_kb_map_lc[] = {"1#", "q", "w", "e", "r", "t", "y", "u", "i", "o", "p", LV_SYMBOL_BACKSPACE, "\n",
|
|
"ABC", "a", "s", "d", "f", "g", "h", "j", "k", "l", LV_SYMBOL_NEW_LINE, "\n",
|
|
"_", "-", "z", "x", "c", "v", "b", "n", "m", ".", ",", ":", "\n",
|
|
LV_SYMBOL_KEYBOARD, LV_SYMBOL_LEFT, " ", LV_SYMBOL_RIGHT, LV_SYMBOL_OK, ""
|
|
};
|
|
|
|
static const lv_btnmatrix_ctrl_t default_kb_ctrl_lc_map[] = {
|
|
LV_KEYBOARD_CTRL_BTN_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_BTNMATRIX_CTRL_CHECKED | 7,
|
|
LV_KEYBOARD_CTRL_BTN_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_BTNMATRIX_CTRL_CHECKED | 7,
|
|
LV_BTNMATRIX_CTRL_CHECKED | LV_KB_BTN(1), LV_BTNMATRIX_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_BTNMATRIX_CTRL_CHECKED | LV_KB_BTN(1), LV_BTNMATRIX_CTRL_CHECKED | LV_KB_BTN(1), LV_BTNMATRIX_CTRL_CHECKED | LV_KB_BTN(1),
|
|
LV_KEYBOARD_CTRL_BTN_FLAGS | 2, LV_BTNMATRIX_CTRL_CHECKED | 2, 6, LV_BTNMATRIX_CTRL_CHECKED | 2, LV_KEYBOARD_CTRL_BTN_FLAGS | 2
|
|
};
|
|
|
|
static const char * const default_kb_map_uc[] = {"1#", "Q", "W", "E", "R", "T", "Y", "U", "I", "O", "P", LV_SYMBOL_BACKSPACE, "\n",
|
|
"abc", "A", "S", "D", "F", "G", "H", "J", "K", "L", LV_SYMBOL_NEW_LINE, "\n",
|
|
"_", "-", "Z", "X", "C", "V", "B", "N", "M", ".", ",", ":", "\n",
|
|
LV_SYMBOL_KEYBOARD, LV_SYMBOL_LEFT, " ", LV_SYMBOL_RIGHT, LV_SYMBOL_OK, ""
|
|
};
|
|
|
|
static const lv_btnmatrix_ctrl_t default_kb_ctrl_uc_map[] = {
|
|
LV_KEYBOARD_CTRL_BTN_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_BTNMATRIX_CTRL_CHECKED | 7,
|
|
LV_KEYBOARD_CTRL_BTN_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_BTNMATRIX_CTRL_CHECKED | 7,
|
|
LV_BTNMATRIX_CTRL_CHECKED | LV_KB_BTN(1), LV_BTNMATRIX_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_BTNMATRIX_CTRL_CHECKED | LV_KB_BTN(1), LV_BTNMATRIX_CTRL_CHECKED | LV_KB_BTN(1), LV_BTNMATRIX_CTRL_CHECKED | LV_KB_BTN(1),
|
|
LV_KEYBOARD_CTRL_BTN_FLAGS | 2, LV_BTNMATRIX_CTRL_CHECKED | 2, 6, LV_BTNMATRIX_CTRL_CHECKED | 2, LV_KEYBOARD_CTRL_BTN_FLAGS | 2
|
|
};
|
|
|
|
static const char * const default_kb_map_spec[] = {"1", "2", "3", "4", "5", "6", "7", "8", "9", "0", LV_SYMBOL_BACKSPACE, "\n",
|
|
"abc", "+", "-", "/", "*", "=", "%", "!", "?", "#", "<", ">", "\n",
|
|
"\\", "@", "$", "(", ")", "{", "}", "[", "]", ";", "\"", "'", "\n",
|
|
LV_SYMBOL_KEYBOARD, LV_SYMBOL_LEFT, " ", LV_SYMBOL_RIGHT, LV_SYMBOL_OK, ""
|
|
};
|
|
|
|
static const lv_btnmatrix_ctrl_t default_kb_ctrl_spec_map[] = {
|
|
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_BTNMATRIX_CTRL_CHECKED | 2,
|
|
LV_KEYBOARD_CTRL_BTN_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),
|
|
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_KEYBOARD_CTRL_BTN_FLAGS | 2, LV_BTNMATRIX_CTRL_CHECKED | 2, 6, LV_BTNMATRIX_CTRL_CHECKED | 2, LV_KEYBOARD_CTRL_BTN_FLAGS | 2
|
|
};
|
|
|
|
static const char * const default_kb_map_num[] = {"1", "2", "3", LV_SYMBOL_KEYBOARD, "\n",
|
|
"4", "5", "6", LV_SYMBOL_OK, "\n",
|
|
"7", "8", "9", LV_SYMBOL_BACKSPACE, "\n",
|
|
"+/-", "0", ".", LV_SYMBOL_LEFT, LV_SYMBOL_RIGHT, ""
|
|
};
|
|
|
|
static const lv_btnmatrix_ctrl_t default_kb_ctrl_num_map[] = {
|
|
1, 1, 1, LV_KEYBOARD_CTRL_BTN_FLAGS | 2,
|
|
1, 1, 1, LV_KEYBOARD_CTRL_BTN_FLAGS | 2,
|
|
1, 1, 1, 2,
|
|
1, 1, 1, 1, 1
|
|
};
|
|
|
|
static const char * * kb_map[9] = {
|
|
(const char * *)default_kb_map_lc,
|
|
(const char * *)default_kb_map_uc,
|
|
(const char * *)default_kb_map_spec,
|
|
(const char * *)default_kb_map_num,
|
|
(const char * *)default_kb_map_lc,
|
|
(const char * *)default_kb_map_lc,
|
|
(const char * *)default_kb_map_lc,
|
|
(const char * *)default_kb_map_lc,
|
|
(const char * *)NULL,
|
|
};
|
|
static const lv_btnmatrix_ctrl_t * kb_ctrl[9] = {
|
|
default_kb_ctrl_lc_map,
|
|
default_kb_ctrl_uc_map,
|
|
default_kb_ctrl_spec_map,
|
|
default_kb_ctrl_num_map,
|
|
default_kb_ctrl_lc_map,
|
|
default_kb_ctrl_lc_map,
|
|
default_kb_ctrl_lc_map,
|
|
default_kb_ctrl_lc_map,
|
|
NULL,
|
|
};
|
|
|
|
/**********************
|
|
* MACROS
|
|
**********************/
|
|
|
|
/**********************
|
|
* GLOBAL FUNCTIONS
|
|
**********************/
|
|
|
|
/**
|
|
* Create a Keyboard object
|
|
* @param parent pointer to an object, it will be the parent of the new keyboard
|
|
* @return pointer to the created keyboard
|
|
*/
|
|
lv_obj_t * lv_keyboard_create(lv_obj_t * parent)
|
|
{
|
|
LV_LOG_INFO("begin");
|
|
lv_obj_t * obj = lv_obj_class_create_obj(&lv_keyboard_class, parent);
|
|
lv_obj_class_init_obj(obj);
|
|
return obj;
|
|
}
|
|
|
|
/*=====================
|
|
* Setter functions
|
|
*====================*/
|
|
|
|
/**
|
|
* Assign a Text Area to the Keyboard. The pressed characters will be put there.
|
|
* @param kb pointer to a Keyboard object
|
|
* @param ta pointer to a Text Area object to write there
|
|
*/
|
|
void lv_keyboard_set_textarea(lv_obj_t * obj, lv_obj_t * ta)
|
|
{
|
|
if(ta) {
|
|
LV_ASSERT_OBJ(ta, &lv_textarea_class);
|
|
}
|
|
|
|
LV_ASSERT_OBJ(obj, MY_CLASS);
|
|
lv_keyboard_t * keyboard = (lv_keyboard_t *)obj;
|
|
|
|
/*Hide the cursor of the old Text area if cursor management is enabled*/
|
|
if(keyboard->ta) {
|
|
lv_obj_clear_state(obj, LV_STATE_FOCUSED);
|
|
}
|
|
|
|
keyboard->ta = ta;
|
|
|
|
/*Show the cursor of the new Text area if cursor management is enabled*/
|
|
if(keyboard->ta) {
|
|
lv_obj_add_flag(obj, LV_STATE_FOCUSED);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Set a new a mode (text or number map)
|
|
* @param kb pointer to a Keyboard object
|
|
* @param mode the mode from 'lv_keyboard_mode_t'
|
|
*/
|
|
void lv_keyboard_set_mode(lv_obj_t * obj, lv_keyboard_mode_t mode)
|
|
{
|
|
LV_ASSERT_OBJ(obj, MY_CLASS);
|
|
lv_keyboard_t * keyboard = (lv_keyboard_t *)obj;
|
|
if(keyboard->mode == mode) return;
|
|
|
|
keyboard->mode = mode;
|
|
lv_keyboard_update_map(obj);
|
|
}
|
|
|
|
/**
|
|
* Show the button title in a popover when pressed.
|
|
* @param kb pointer to a Keyboard object
|
|
* @param en whether "popovers" mode is enabled
|
|
*/
|
|
void lv_keyboard_set_popovers(lv_obj_t * obj, bool en)
|
|
{
|
|
lv_keyboard_t * keyboard = (lv_keyboard_t *)obj;
|
|
|
|
if(keyboard->popovers == en) {
|
|
return;
|
|
}
|
|
|
|
keyboard->popovers = en;
|
|
lv_keyboard_update_ctrl_map(obj);
|
|
}
|
|
|
|
/**
|
|
* Set a new map for the keyboard
|
|
* @param kb pointer to a Keyboard object
|
|
* @param mode keyboard map to alter 'lv_keyboard_mode_t'
|
|
* @param map pointer to a string array to describe the map.
|
|
* See 'lv_btnmatrix_set_map()' for more info.
|
|
*/
|
|
void lv_keyboard_set_map(lv_obj_t * obj, lv_keyboard_mode_t mode, const char * map[],
|
|
const lv_btnmatrix_ctrl_t ctrl_map[])
|
|
{
|
|
kb_map[mode] = map;
|
|
kb_ctrl[mode] = ctrl_map;
|
|
lv_keyboard_update_map(obj);
|
|
}
|
|
|
|
/*=====================
|
|
* Getter functions
|
|
*====================*/
|
|
|
|
/**
|
|
* Assign a Text Area to the Keyboard. The pressed characters will be put there.
|
|
* @param kb pointer to a Keyboard object
|
|
* @return pointer to the assigned Text Area object
|
|
*/
|
|
lv_obj_t * lv_keyboard_get_textarea(const lv_obj_t * obj)
|
|
{
|
|
LV_ASSERT_OBJ(obj, MY_CLASS);
|
|
lv_keyboard_t * keyboard = (lv_keyboard_t *)obj;
|
|
return keyboard->ta;
|
|
}
|
|
|
|
/**
|
|
* Set a new a mode (text or number map)
|
|
* @param kb pointer to a Keyboard object
|
|
* @return the current mode from 'lv_keyboard_mode_t'
|
|
*/
|
|
lv_keyboard_mode_t lv_keyboard_get_mode(const lv_obj_t * obj)
|
|
{
|
|
LV_ASSERT_OBJ(obj, MY_CLASS);
|
|
lv_keyboard_t * keyboard = (lv_keyboard_t *)obj;
|
|
return keyboard->mode;
|
|
}
|
|
|
|
/**
|
|
* Tell whether "popovers" mode is enabled or not.
|
|
* @param kb pointer to a Keyboard object
|
|
* @return true: "popovers" mode is enabled; false: disabled
|
|
*/
|
|
bool lv_btnmatrix_get_popovers(const lv_obj_t * obj)
|
|
{
|
|
lv_keyboard_t * keyboard = (lv_keyboard_t *)obj;
|
|
return keyboard->popovers;
|
|
}
|
|
|
|
/*=====================
|
|
* Other functions
|
|
*====================*/
|
|
|
|
/**
|
|
* Default keyboard event to add characters to the Text area and change the map.
|
|
* If a custom `event_cb` is added to the keyboard this function can be called from it to handle the
|
|
* button clicks
|
|
* @param kb pointer to a keyboard
|
|
* @param event the triggering event
|
|
*/
|
|
void lv_keyboard_def_event_cb(lv_event_t * e)
|
|
{
|
|
lv_obj_t * obj = lv_event_get_target(e);
|
|
|
|
LV_ASSERT_OBJ(obj, MY_CLASS);
|
|
lv_keyboard_t * keyboard = (lv_keyboard_t *)obj;
|
|
uint16_t btn_id = lv_btnmatrix_get_selected_btn(obj);
|
|
if(btn_id == LV_BTNMATRIX_BTN_NONE) return;
|
|
|
|
const char * txt = lv_btnmatrix_get_btn_text(obj, lv_btnmatrix_get_selected_btn(obj));
|
|
if(txt == NULL) return;
|
|
|
|
if(strcmp(txt, "abc") == 0) {
|
|
keyboard->mode = LV_KEYBOARD_MODE_TEXT_LOWER;
|
|
lv_btnmatrix_set_map(obj, kb_map[LV_KEYBOARD_MODE_TEXT_LOWER]);
|
|
lv_keyboard_update_ctrl_map(obj);
|
|
return;
|
|
}
|
|
else if(strcmp(txt, "ABC") == 0) {
|
|
keyboard->mode = LV_KEYBOARD_MODE_TEXT_UPPER;
|
|
lv_btnmatrix_set_map(obj, kb_map[LV_KEYBOARD_MODE_TEXT_UPPER]);
|
|
lv_keyboard_update_ctrl_map(obj);
|
|
return;
|
|
}
|
|
else if(strcmp(txt, "1#") == 0) {
|
|
keyboard->mode = LV_KEYBOARD_MODE_SPECIAL;
|
|
lv_btnmatrix_set_map(obj, kb_map[LV_KEYBOARD_MODE_SPECIAL]);
|
|
lv_keyboard_update_ctrl_map(obj);
|
|
return;
|
|
}
|
|
else if(strcmp(txt, LV_SYMBOL_CLOSE) == 0 || strcmp(txt, LV_SYMBOL_KEYBOARD) == 0) {
|
|
lv_res_t res = lv_event_send(obj, LV_EVENT_CANCEL, NULL);
|
|
if(res != LV_RES_OK) return;
|
|
|
|
if(keyboard->ta) {
|
|
res = lv_event_send(keyboard->ta, LV_EVENT_CANCEL, NULL);
|
|
if(res != LV_RES_OK) return;
|
|
}
|
|
return;
|
|
}
|
|
else if(strcmp(txt, LV_SYMBOL_OK) == 0) {
|
|
lv_res_t res = lv_event_send(obj, LV_EVENT_READY, NULL);
|
|
if(res != LV_RES_OK) return;
|
|
|
|
if(keyboard->ta) {
|
|
res = lv_event_send(keyboard->ta, LV_EVENT_READY, NULL);
|
|
if(res != LV_RES_OK) return;
|
|
}
|
|
return;
|
|
}
|
|
|
|
/*Add the characters to the text area if set*/
|
|
if(keyboard->ta == NULL) return;
|
|
|
|
if(strcmp(txt, "Enter") == 0 || strcmp(txt, LV_SYMBOL_NEW_LINE) == 0) {
|
|
lv_textarea_add_char(keyboard->ta, '\n');
|
|
if(lv_textarea_get_one_line(keyboard->ta)) {
|
|
lv_res_t res = lv_event_send(keyboard->ta, LV_EVENT_READY, NULL);
|
|
if(res != LV_RES_OK) return;
|
|
}
|
|
}
|
|
else if(strcmp(txt, LV_SYMBOL_LEFT) == 0) {
|
|
lv_textarea_cursor_left(keyboard->ta);
|
|
}
|
|
else if(strcmp(txt, LV_SYMBOL_RIGHT) == 0) {
|
|
lv_textarea_cursor_right(keyboard->ta);
|
|
}
|
|
else if(strcmp(txt, LV_SYMBOL_BACKSPACE) == 0) {
|
|
lv_textarea_del_char(keyboard->ta);
|
|
}
|
|
else if(strcmp(txt, "+/-") == 0) {
|
|
uint16_t cur = lv_textarea_get_cursor_pos(keyboard->ta);
|
|
const char * ta_txt = lv_textarea_get_text(keyboard->ta);
|
|
if(ta_txt[0] == '-') {
|
|
lv_textarea_set_cursor_pos(keyboard->ta, 1);
|
|
lv_textarea_del_char(keyboard->ta);
|
|
lv_textarea_add_char(keyboard->ta, '+');
|
|
lv_textarea_set_cursor_pos(keyboard->ta, cur);
|
|
}
|
|
else if(ta_txt[0] == '+') {
|
|
lv_textarea_set_cursor_pos(keyboard->ta, 1);
|
|
lv_textarea_del_char(keyboard->ta);
|
|
lv_textarea_add_char(keyboard->ta, '-');
|
|
lv_textarea_set_cursor_pos(keyboard->ta, cur);
|
|
}
|
|
else {
|
|
lv_textarea_set_cursor_pos(keyboard->ta, 0);
|
|
lv_textarea_add_char(keyboard->ta, '-');
|
|
lv_textarea_set_cursor_pos(keyboard->ta, cur + 1);
|
|
}
|
|
}
|
|
else {
|
|
lv_textarea_add_text(keyboard->ta, txt);
|
|
}
|
|
}
|
|
|
|
/**********************
|
|
* STATIC FUNCTIONS
|
|
**********************/
|
|
|
|
static void lv_keyboard_constructor(const lv_obj_class_t * class_p, lv_obj_t * obj)
|
|
{
|
|
LV_UNUSED(class_p);
|
|
lv_obj_clear_flag(obj, LV_OBJ_FLAG_CLICK_FOCUSABLE);
|
|
|
|
lv_keyboard_t * keyboard = (lv_keyboard_t *)obj;
|
|
keyboard->ta = NULL;
|
|
keyboard->mode = LV_KEYBOARD_MODE_TEXT_LOWER;
|
|
keyboard->popovers = 0;
|
|
|
|
lv_obj_align(obj, LV_ALIGN_BOTTOM_MID, 0, 0);
|
|
lv_obj_add_event_cb(obj, lv_keyboard_def_event_cb, LV_EVENT_VALUE_CHANGED, NULL);
|
|
lv_obj_set_style_base_dir(obj, LV_BASE_DIR_LTR, 0);
|
|
|
|
lv_keyboard_update_map(obj);
|
|
}
|
|
|
|
/**
|
|
* Update the key and control map for the current mode
|
|
* @param obj pointer to a keyboard object
|
|
*/
|
|
static void lv_keyboard_update_map(lv_obj_t * obj)
|
|
{
|
|
lv_keyboard_t * keyboard = (lv_keyboard_t *)obj;
|
|
lv_btnmatrix_set_map(obj, kb_map[keyboard->mode]);
|
|
lv_keyboard_update_ctrl_map(obj);
|
|
}
|
|
|
|
/**
|
|
* Update the control map for the current mode
|
|
* @param obj pointer to a keyboard object
|
|
*/
|
|
static void lv_keyboard_update_ctrl_map(lv_obj_t * obj)
|
|
{
|
|
lv_keyboard_t * keyboard = (lv_keyboard_t *)obj;
|
|
|
|
if(keyboard->popovers) {
|
|
/*Apply the current control map (already includes LV_BTNMATRIX_CTRL_POPOVER flags)*/
|
|
lv_btnmatrix_set_ctrl_map(obj, kb_ctrl[keyboard->mode]);
|
|
}
|
|
else {
|
|
/*Make a copy of the current control map*/
|
|
lv_btnmatrix_t * btnm = (lv_btnmatrix_t *)obj;
|
|
lv_btnmatrix_ctrl_t * ctrl_map = lv_mem_alloc(btnm->btn_cnt * sizeof(lv_btnmatrix_ctrl_t));
|
|
lv_memcpy(ctrl_map, kb_ctrl[keyboard->mode], sizeof(lv_btnmatrix_ctrl_t) * btnm->btn_cnt);
|
|
|
|
/*Remove all LV_BTNMATRIX_CTRL_POPOVER flags*/
|
|
for(uint16_t i = 0; i < btnm->btn_cnt; i++) {
|
|
ctrl_map[i] &= (~LV_BTNMATRIX_CTRL_POPOVER);
|
|
}
|
|
|
|
/*Apply new control map and clean up*/
|
|
lv_btnmatrix_set_ctrl_map(obj, ctrl_map);
|
|
lv_mem_free(ctrl_map);
|
|
}
|
|
}
|
|
|
|
#endif /*LV_USE_KEYBOARD*/
|