Description
What MCU/Processor/Board and compiler are you using?
Raspberry Pi Pico board (RP2040), building using gcc version 14.2.1 20241119 (Arm GNU Toolchain 14.2.Rel1 (Build arm-14.52)).
What LVGL version are you using?
9cc9e7b50309715ebcb3ca851fda647b4605d333
What do you want to achieve?
I’d like to create an lv_menu based menu that is navigable with a keypad input device. The active item of the menu should be highlighted, and menu items should change when KEY_UP/KEY_DOWN are received.
What have you tried so far?
I tried creating an input group, affecting menu cont to the group. Nothing happened.
Code to reproduce
lv_obj_set_style_bg_color(screen, lv_color_hex(0x000000), LV_PART_MAIN);
lv_obj_t * settings_menu = lv_menu_create(screen);
lv_obj_set_size(settings_menu, 240, 240);
lv_obj_center(settings_menu);
lv_obj_t * label;
lv_obj_t * cont;
lv_group_t * group = lv_group_get_default();
lv_obj_t * settings_main_page = lv_menu_page_create(settings_menu, NULL);
cont = lv_menu_cont_create(settings_main_page);
lv_obj_clear_flag(cont, LV_OBJ_FLAG_SCROLLABLE);
lv_obj_add_flag(cont, LV_OBJ_FLAG_SCROLL_ON_FOCUS);
label = lv_label_create(cont);
lv_label_set_text(label, "Item 1");
lv_group_add_obj(group, cont);
cont = lv_menu_cont_create(settings_main_page);
lv_obj_clear_flag(cont, LV_OBJ_FLAG_SCROLLABLE);
lv_obj_add_flag(cont, LV_OBJ_FLAG_SCROLL_ON_FOCUS);
label = lv_label_create(cont);
lv_label_set_text(label, "Item 2");
lv_group_add_obj(group, cont);
cont = lv_menu_cont_create(settings_main_page);
lv_obj_clear_flag(cont, LV_OBJ_FLAG_SCROLLABLE);
lv_obj_add_flag(cont, LV_OBJ_FLAG_SCROLL_ON_FOCUS);
label = lv_label_create(cont);
lv_label_set_text(label, "Item 3");
lv_group_add_obj(group, cont);
lv_menu_set_page(settings_menu, settings_main_page);
I made a bit of progress. It turns out, in order to make a menu with keypad interactions, you need to:
- Put all your menu cont’s into a lv_group_t.
- Add some theming to visually distinguish the active item from all the disabled items.
- Emit the right keycode (LV_KEY_PREV/LV_KEY_NEXT).
Regarding that last aspect, this is causing me a bit of trouble since all my keypad keys are mapped to LV_KEY_{UP,DOWN,LEFT,RIGHT}. docs/overview/indev.rst
says that there is a translation mechanism. I could not make it work nor find where it was implemented. Is the documentation out of date here?
Hello,
I am struggling with the same thing. How hard can it be??
I have a button handler (this works).
static void settings_menu_button_handler(int button_id, int press_type) {
if (press_type != SHORT_PRESS) return;
uint32_t key;
switch (button_id) {
case 0: // LEFT = UP
key = LV_KEY_UP;
lv_event_send(menu, LV_EVENT_KEY, &key);
LOG_INF("Pressed UP");
break;
case 1: // RIGHT = DOWN
key = LV_KEY_DOWN;
lv_event_send(menu, LV_EVENT_KEY, &key);
LOG_INF("Pressed DOWN");
break;
case 2: // ENTER
key = LV_KEY_ENTER;
lv_event_send(menu, LV_EVENT_KEY, &key);
LOG_INF("Pressed ENTER");
}
}
But nothing happens when I send it down to the menu
// Create menu
menu = lv_menu_create(settings_screen);
lv_obj_set_style_bg_color(menu, lv_color_black(), 0);
lv_obj_set_size(menu, 200, 200);
lv_obj_center(menu);
// Create sub-page
lv_obj_t * sub_page = lv_menu_page_create(menu, NULL);
lv_obj_t * cont = lv_menu_cont_create(sub_page);
lv_obj_add_style(cont, &style_default, LV_STATE_DEFAULT); // Apply always
lv_obj_t * label = lv_label_create(cont);
lv_label_set_text(label, "Hello, I am hiding here");
// Create main page
lv_obj_t * main_page = lv_menu_page_create(menu, NULL);
cont = lv_menu_cont_create(main_page);
lv_obj_add_style(cont, &style_focused, LV_STATE_FOCUSED); // <- Apply to Item 1
lv_obj_add_style(cont, &style_default, LV_STATE_DEFAULT); // Apply always
label = lv_label_create(cont);
lv_label_set_text(label, LV_SYMBOL_BLUETOOTH " Communication");
did you work it out in the end
Hi,
I went with a dodgy workaround: my keypad inputs are handled by a custom lv_indev_t. This lv_indev_t implements two input modes. The first mode outputs direction keys (LV_KEY_UP, etc.) whereas the second outputs widget focus keys (LV_KEY_PREV).