Resizing sidebar in a complex menu

Hello,

I am currently experimenting with lv_menu. I have been able to start menu disposition with a first page “Home”, using mostly lv_menu and flex layout. So far so good.
Problem is that for now I have been unable to resize (or at least tune its dynamic behaviour) the sidebar, which takes a good chunk of the screen.

Test setup

LVGL port on Windows for Visual studio (8.3.?)

Visual result so far

Source code

void GUI::Create(lv_obj_t* parent)
{
    lv_obj_t* cont;
    lv_obj_t* section;
    /* Création du système de menu */
    lv_obj_t* menu = lv_menu_create(parent);
    lv_obj_set_size(menu, lv_pct(100), lv_pct(100));
    /* Page Menu principal */
    lv_obj_t* main_menu_page = lv_menu_page_create(menu, NULL);
    lv_obj_set_style_pad_hor(main_menu_page, lv_obj_get_style_pad_left(lv_menu_get_main_header(menu), 0), 0);
    section = lv_menu_section_create(main_menu_page);
    lv_obj_set_style_max_width(main_menu_page, 100, LV_STATE_DEFAULT);
    lv_menu_set_sidebar_page(menu, main_menu_page);
    lv_obj_set_style_max_width(lv_menu_get_cur_sidebar_page(menu), 100, LV_STATE_DEFAULT);
    /* Page Overview */
    lv_obj_t* page_overview = lv_menu_page_create(menu, NULL);
    cont = create_text(section, LV_SYMBOL_HOME, "Home");
    Overview::Create(page_overview);
    lv_menu_set_load_page_event(menu, cont, page_overview);
    lv_event_send(lv_obj_get_child(lv_obj_get_child(lv_menu_get_cur_sidebar_page(menu), 0), 0), LV_EVENT_CLICKED, NULL);
}

I’ll skip on Overview::Create (it contains the logic for the page_overview creation) and create_text (which is pretty much LVGL example menu 5).

I tried some stuff like setting max width of the section, of the sidebar reference itself, as well as calling …_set_flex_grow(…), but no luck so far.

Any tips to avoid the sidebar taking a massive chunk of the available space ?

Thanks in advance.

I was running into this problem recently. This is my workaround (hopefully not too hacky):

// set sidebar
lv_menu_set_sidebar_page(menu, sidebar);
// cast menu from lv_obj_t* to lv_menu_t* to access members of the latter
lv_menu_t* menu_t = (lv_menu_t*)menu;
// set sidebar width
lv_obj_set_width(menu_t->sidebar, LV_PCT(20));

LVGL objects are often cast to their specific typedef when the object specific functions are called. I pretty much did this, but grabbed the struct member I wanted.

Quick example:

// create menu
lv_obj_t* menu = lv_menu_create(lv_scr_act());

// set some menu styles
lv_menu_set_mode_root_back_btn(menu, LV_MENU_ROOT_BACK_BTN_DISABLED);
lv_obj_set_size(menu, lv_disp_get_hor_res(NULL), lv_disp_get_ver_res(NULL));
lv_obj_center(menu);

// declare vars
lv_obj_t* cont;
lv_obj_t* section;
lv_obj_t* label;

// create sub page for item 0
lv_obj_t* item_0 = lv_menu_page_create(menu, "item 0");
section = lv_menu_section_create(item_0);

// create sub page for item 1
lv_obj_t* item_1 = lv_menu_page_create(menu, "item 1");
section = lv_menu_section_create(item_1);

// create sidebar
lv_obj_t* sidebar = lv_menu_page_create(menu, "Items");

// create sidebar element for item 0
section = lv_menu_section_create(sidebar);
cont = lv_menu_cont_create(section);
label = lv_label_create(cont);
lv_label_set_text(label, "item 0");
lv_menu_set_load_page_event(menu, cont, item_0);

// create sidebar element for item 1
section = lv_menu_section_create(sidebar);
cont = lv_menu_cont_create(section);
label = lv_label_create(cont);
lv_label_set_text(label, "item 1");
lv_menu_set_load_page_event(menu, cont, item_1);

// set sidebar
lv_menu_set_sidebar_page(menu, sidebar);
// cast menu from lv_obj_t* to lv_menu_t* to access members of the latter
lv_menu_t* menu_t = (lv_menu_t*)menu;
// set sidebar width
lv_obj_set_width(menu_t->sidebar, LV_PCT(20));

lv_event_send(lv_obj_get_child(lv_obj_get_child(lv_menu_get_cur_sidebar_page(menu), 0), 0), LV_EVENT_CLICKED, NULL);

Could probably write a function for it too:

void set_sidebar_width(lv_obj_t* menu, lv_coord_t width) {
  lv_menu_t* obj = (lv_menu_t*)menu;
  lv_obj_set_width(obj->sidebar, width);
}

Hope this helps!

1 Like