How to navigate in menu cont?

Description

I want to navigate with an encoder in menu cont.But I found that it is unreachable.

What MCU/Processor/Board and compiler are you using?

visual studio 2019

What LVGL version are you using?

v8.1

What do you want to achieve?

navigate in menu with encoder

What have you tried so far?

test with below. it had no effect.

so test below.it had no effect.

Code to reproduce

void menu()
{
    lv_obj_t* _menu = lv_menu_create(lv_scr_act());
    lv_obj_t* label;
    lv_obj_t* cont;
    // // draw menu screen //
    _menu = lv_menu_create(lv_scr_act());
    lv_menu_set_mode_root_back_btn(_menu, LV_MENU_ROOT_BACK_BTN_ENABLED);
   
    lv_obj_set_size(_menu, lv_disp_get_hor_res(NULL), lv_disp_get_ver_res(NULL));
    lv_obj_center(_menu);
    char s1[] = "Page1", s2[] = "Page2";
    lv_obj_t* sub_1_page = lv_menu_page_create(_menu, s1);

    cont = lv_menu_cont_create(sub_1_page);
    label = lv_label_create(cont);
    lv_label_set_text(label, "Hello, I am hiding here on page 1");
    lv_obj_t* sub_2_page = lv_menu_page_create(_menu, s2);
    cont = lv_menu_cont_create(sub_2_page);
    label = lv_label_create(cont);
    lv_label_set_text(label, "Hello, I am hiding here on page 2");
    // Create a main page
    lv_obj_t* _mainPage = lv_menu_page_create(_menu, NULL);
    lv_obj_t* section =  lv_menu_section_create(_mainPage);
    cont = lv_menu_cont_create(_mainPage);
    label = lv_label_create(cont);
    lv_label_set_text(label, "Item 1");
    lv_menu_set_load_page_event(_menu, cont, sub_1_page);
    lv_group_add_obj(lv_obj_get_group(_menu), cont);
    lv_obj_add_flag(cont, LV_OBJ_FLAG_CHECKABLE);
    lv_obj_add_flag(cont, LV_OBJ_FLAG_CLICKABLE);
    lv_obj_add_flag(cont, LV_OBJ_FLAG_SCROLLABLE);
    lv_obj_add_flag(cont, LV_OBJ_FLAG_SCROLL_ON_FOCUS);
    cont = lv_menu_cont_create(_mainPage);
    label = lv_label_create(cont);
    lv_label_set_text(label, "Item 2");
    lv_menu_set_load_page_event(_menu, cont, sub_2_page);
    lv_group_add_obj(lv_obj_get_group(_menu), cont);
    lv_obj_add_flag(cont, LV_OBJ_FLAG_CHECKABLE);
    lv_obj_add_flag(cont, LV_OBJ_FLAG_CLICKABLE);
    lv_obj_add_flag(cont, LV_OBJ_FLAG_SCROLLABLE);
    lv_obj_add_flag(cont, LV_OBJ_FLAG_SCROLL_ON_FOCUS);
    lv_menu_set_sidebar_page(_menu, _mainPage);
}

Screenshot and/or video

with mousewheel. the selected box is just around with LV_MENU_ROOT_BACK_BTN,
it can not go to Item1 or Item2. I do not know how to deal with it.

I just started checking out LVGL to see if we can use it and ran into a similar problem. It seems like the menu cont is not implemented with keyboard/encoder navigation option. I did some debugging and got it working.

Firs of all, the menu_cont is not added to the default group automatically. To add it to all menu conts you can add .group_def to lv_menu_cont_class in lv_menu.c

const lv_obj_class_t lv_menu_cont_class = {
    .constructor_cb = lv_menu_cont_constructor,
    .base_class = &lv_obj_class,
    .width_def = LV_PCT(100),
    .height_def = LV_SIZE_CONTENT,
    .group_def = LV_OBJ_CLASS_GROUP_DEF_TRUE
};

You can also add it manually with lv_group_add_obj for all conts you’d like to include:

    g = lv_group_create();
    lv_group_set_default(g);

    lv_indev_t* cur_drv = NULL;
    for (;;) {
        cur_drv = lv_indev_get_next(cur_drv);
        if (!cur_drv) {
            break;
        }

        if (cur_drv->driver->type == LV_INDEV_TYPE_KEYPAD) {
            lv_indev_set_group(cur_drv, g);
        }

        if (cur_drv->driver->type == LV_INDEV_TYPE_ENCODER) {
            lv_indev_set_group(cur_drv, g);
        }
    }


cont = lv_menu_cont_create(_mainPage);
lv_group_add_obj(g, cont);

After this, it should be able to navigate in the menu, but you will not see what is in focus, which makes it a bit hard…
To at least see what is selected you could just add
lv_obj_add_style(obj, &styles->outline_primary, LV_STATE_FOCUS_KEY);
in lv_theme_default.c

    else if(lv_obj_check_type(obj, &lv_menu_cont_class)) {
        lv_obj_add_style(obj, &styles->menu_cont, 0);
        lv_obj_add_style(obj, &styles->menu_pressed, LV_STATE_PRESSED);
        lv_obj_add_style(obj, &styles->bg_color_primary_muted, LV_STATE_PRESSED | LV_STATE_CHECKED);
        lv_obj_add_style(obj, &styles->bg_color_primary_muted, LV_STATE_CHECKED);
        lv_obj_add_style(obj, &styles->outline_primary, LV_STATE_FOCUS_KEY);
    }

Then you should get blue lines around what is selected. To make it look good and work more smooth, you will have to do some other modifications as well, but this was as far as I got in my investigation. I guess it’s probably better to change the background color when in focus. I’m new to LVGL, so there may be better solutions to this.

I used code below. cnt == 0;
So the problem was that menu did not belong to any group .

unsigned int cnt = 0;
cnt = lv_group_get_obj_count(lv_obj_get_group(_menu));

Then I used codes below.
lv_obj_t* btn = lv_btn_create(_menu);
unsigned int cnt = 0;
cnt = lv_group_get_obj_count(lv_obj_get_group(btn));
It worked well.
Thanks to Jimbo.

1 Like

How to remove blue lines when moving?please