Description
I can’t seem to get any KEY events on any objects I create. After searching this forum and spending a day trying to get this to work I’m posting this here hoping I’ve missed something silly and someone can point out my mistake.
What MCU/Processor/Board and compiler are you using?
Using Zephyr rtos with the following hardware targets
- nRF5340 on ublox Nora B1 devkit
- native_posix target
What LVGL version are you using?
8.2
What do you want to achieve?
I would like to use the buttons as encoder input to navigate menus and interact with widgets. I’ve followed the examples but my widgets do not seem to receive the KEY events.
What have you tried so far?
I have tried using different objects like menu, roller, and a simple button (exampled below). Also tried using the keypad input without success. When debugging I see that the encoder_buttons
is setting the indev_data values when physical buttons are pressed. Unfortunately my objects never seem to get those events. When I set the object’s event callback to LV_EVENT_ALL, I see a bunch of drawing events happening in the beginning but no KEY_ events seem to come through. I have made sure to add my objects to a group.
Any help would be greatly appreciated!
Code to reproduce
main_menu_init is called from the main thread at startup
// Objects must be added to the input group to receive input events
lv_group_t *input_group;
// Call back for input events
static bool encoder_buttons(lv_indev_drv_t *drv, lv_indev_data_t *data)
{
struct ButtonStateMessage *last_button = user_input_get_last_button();
if (last_button->name == UP_BUTTON)
{
data->key = LV_KEY_LEFT;
}
else if (last_button->name == DOWN_BUTTON)
{
data->key = LV_KEY_RIGHT;
}
else if (last_button->name == SELECT_BUTTON)
{
data->key = LV_KEY_ENTER;
}
if (last_button->state == BUTTON_PRESSED)
{
LOG_DBG("Pressed");
data->state = LV_INDEV_STATE_PRESSED;
}
else
{
data->state = LV_INDEV_STATE_RELEASED;
}
return false;
}
void register_input()
{
static lv_indev_drv_t indev_drv;
lv_indev_drv_init(&indev_drv);
indev_drv.type = LV_INDEV_TYPE_ENCODER;
indev_drv.read_cb = encoder_buttons;
lv_indev_t *my_indev = lv_indev_drv_register(&indev_drv);
if (my_indev == NULL)
{
LOG_ERR("Unable to register input");
}
lv_indev_set_group(my_indev, input_group);
lv_group_set_default(input_group);
}
void main_menu_init()
{
register_input();
lv_obj_t *btn = lv_btn_create(lv_scr_act());
lv_obj_set_size(btn, 100, 30);
lv_obj_center(btn);
lv_obj_add_event_cb(btn, event_cb, LV_EVENT_ALL, NULL);
lv_group_add_obj(lv_group_get_default(), btn);
lv_obj_t *label = lv_label_create(btn);
lv_label_set_text(label, "A Button");
lv_obj_center(label);
}
Calls to lv_task_handler are performed in a thread with a 2 sec startup delay.
void ui_thread_handler()
{
while (1)
{
lv_task_handler();
k_msleep(10);
}
}
K_THREAD_DEFINE(ui_thread, 4096, ui_thread_handler, NULL, NULL, NULL, 1, 0, 2000);