Indev Keypad cannot get it work

What do you want to achieve?

I want to navigate through a lv_menu with a keypad. I do not have a touch screen.
The lv_menu is built dynamically and it is imho working fine.
Though, I cannot navigate with the up/down buttons

What have you tried so far?

Code to reproduce

void Screen::initKeypadInput()
{
    _keypadIndev = lv_indev_create();
    lv_indev_set_type(_keypadIndev, LV_INDEV_TYPE_KEYPAD);
    lv_indev_set_read_cb(_keypadIndev, read_keypad);
    lv_indev_set_user_data(_keypadIndev, this);

    _menuGroup = lv_group_create();
    lv_indev_set_group(_keypadIndev, _menuGroup);
}

void Screen::read_keypad(lv_indev_t *indev, lv_indev_data_t *data)
{
    static uint32_t last_key = 0; 

    Screen *screen = static_cast<Screen *>(lv_indev_get_user_data(indev));
    if (!screen || !screen->_registry)
        return;

    bool leftPressed = screen->_registry->getLeftButton()->isPressed();
    bool rightPressed = screen->_registry->getRightButton()->isPressed();
    bool actionPressed = screen->_registry->getActionButton()->isPressed();

    if (leftPressed && rightPressed)
    {
        data->state = LV_INDEV_STATE_PRESSED;
        data->key = LV_KEY_ESC;
        last_key = LV_KEY_ESC;
    }
    else if (leftPressed)
    {
        data->state = LV_INDEV_STATE_PRESSED;
        data->key = LV_KEY_UP;
        last_key = LV_KEY_UP;
    }
    else if (rightPressed)
    {
        data->state = LV_INDEV_STATE_PRESSED;
        data->key = LV_KEY_DOWN;
        last_key = LV_KEY_DOWN;
    }
    else if (actionPressed)
    {
        data->state = LV_INDEV_STATE_PRESSED;
        data->key = LV_KEY_ENTER;
        last_key = LV_KEY_ENTER;
    }
    else
    {
        data->state = LV_INDEV_STATE_RELEASED;
        data->key = last_key;
    }
}

void Screen::createMenuItem(lv_obj_t *parent, std::shared_ptr<MenuData> item)
{
    lv_obj_t *cont = lv_menu_cont_create(parent);
    lv_obj_add_flag(cont, LV_OBJ_FLAG_CLICKABLE);
    lv_obj_add_flag(cont, LV_OBJ_FLAG_SCROLLABLE);

    lv_group_add_obj(_menuGroup, cont);
    lv_obj_add_event_cb(cont, item_event_handler, LV_EVENT_CLICKED, this);
    lv_obj_set_user_data(cont, item.get());

    lv_obj_set_layout(cont, LV_LAYOUT_FLEX);
    lv_obj_set_flex_flow(cont, LV_FLEX_FLOW_ROW);
    lv_obj_set_flex_align(cont, LV_FLEX_ALIGN_SPACE_BETWEEN, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER);
    lv_obj_set_style_pad_all(cont, 8, LV_PART_MAIN);

    lv_obj_t *nameLabel = lv_label_create(cont);
    lv_label_set_text(nameLabel, item->getName().c_str());
    lv_obj_set_style_text_font(nameLabel, &lv_font_montserrat_medium_14, LV_PART_MAIN);

    switch (item->getType())
    {
    case MenuItemType::ACTION:
        // No right content for actions
        break;

    case MenuItemType::INFO:
    {
        lv_obj_t *valueLabel = lv_label_create(cont);
        lv_label_set_text(valueLabel, item->getValue().c_str());
        lv_obj_set_style_text_font(valueLabel, &lv_font_montserrat_medium_14, LV_PART_MAIN);
        lv_obj_set_style_text_color(valueLabel, lv_color_hex(0x666666), LV_PART_MAIN);
        break;
    }

    case MenuItemType::BOOLEAN_EDIT:
    case MenuItemType::BOOLEAN_READONLY:
    {
        lv_obj_t *checkbox = lv_checkbox_create(cont);
        lv_checkbox_set_text(checkbox, "");
        bool isChecked = item->getBoolValue();

        if (isChecked)
        {
            lv_obj_add_state(checkbox, LV_STATE_CHECKED);
        }

        if (item->getType() == MenuItemType::BOOLEAN_READONLY)
        {
            lv_obj_add_state(checkbox, LV_STATE_DISABLED);
            lv_obj_set_style_opa(checkbox, LV_OPA_50, LV_PART_MAIN);
        }
        break;
    }

    case MenuItemType::SUBMENU:
    {
        lv_obj_t *submenuPage = lv_menu_page_create(_menu, item->getName().c_str());
        buildMenuPage(submenuPage, item->getSubItems());
        lv_menu_set_load_page_event(_menu, cont, submenuPage);

        lv_obj_t *arrowLabel = lv_label_create(cont);
        lv_label_set_text(arrowLabel, ">");
        lv_obj_set_style_text_font(arrowLabel, &lv_font_montserrat_medium_14, LV_PART_MAIN);
        lv_obj_set_style_text_color(arrowLabel, lv_color_hex(0x007BFF), LV_PART_MAIN);
        break;
    }
    }
}

When pressing the ACTION button, I see that the entry is highlighted for the press event.
But I cannot navigate with the up/down keys. I was expecting that the menu items will be selected accordingly and at the beginning the very first item is automatically selected.

Environment

  • MCU/MPU/Board: macOS SDL Simulator
  • LVGL version: v9.3 - platform.io

I think I figured it out.
I used LV_KEY_UP and LV_KEY_DOWN, when using LV_KEY_RIGHT and LV_KEY_LEFT it is working …