Description
What MCU/Processor/Board and compiler are you using?
Simulator/GCC.
What LVGL version are you using?
v7.2.0
What do you want to achieve?
I have a GUI that’s laid out basically with:
- a region at the top that should shrink to fit the contents (think a container with
LV_FIT_TIGHT
) - a similar region at the bottom
- some stuff in the middle that should be centered between them
The regions at the top and bottom are set up when the GUI is created and don’t change, but the actual heights might be different from one deployment to another.
I’d like to be able to add components to the area between them so that it’s vertically centered between them, while keeping the header at the top and the footer at the bottom. Is there a way to structure containers and their layouts so that some children have a “tight” layout and others fill the leftover space? Or, to put it another way, so the centre region “pushes” the header and footer to the upper and lower edges of the screen?
What have you tried so far?
First approach
- Create a top level container with
LV_FIT_PARENT
. - To this, add:
- a container (top region) with
LV_FIT_PARENT
horizontally andLV_FIT_TIGHT
vertically - a container (centre region) `LV_FIT_PARENT
- a container (bottom region)
LV_FIT_PARENT
/LV_FIT_TIGHT
.
- a container (top region) with
This results in the centre region pushing the footer off the screen. If I try to add containers to the centre region with LV_FIT_PARENT
I get segfaults, but I haven’t had time to debug this more.
Second approach:
Set up the top and bottom regions with LV_LAYOUT_OFF
and align them to the top and bottom instead, measure their heights, create a container to fit the remaining space. This is annoying because I want similar functionality for other parts of the UI and I have to do it in a lot of places.
Code to reproduce
Here’s some UI code (hardware code omitted). Play around with adding containers or other widgets to the centre area and you’ll see what I mean.
void ui_init(void)
{
// Screen.
lv_obj_t * screen = lv_disp_get_scr_act(NULL);
// Cover the whole screen with a container.
lv_obj_t * page = lv_cont_create(screen, NULL);
lv_cont_set_fit(page, LV_FIT_PARENT);
lv_cont_set_layout(page, LV_LAYOUT_COLUMN_MID);
// Title area.
lv_obj_t * top = lv_cont_create(page, NULL);
lv_obj_set_auto_realign(top, true);
lv_cont_set_fit2(top, LV_FIT_PARENT, LV_FIT_TIGHT);
lv_cont_set_layout(top, LV_LAYOUT_COLUMN_MID);
lv_obj_t * title = lv_label_create(top, NULL);
lv_label_set_text(title, "TITLE");
lv_label_set_align(title, LV_LABEL_ALIGN_CENTER);
// Centre area.
lv_obj_t * main_area = lv_cont_create(page, NULL);
lv_obj_set_auto_realign(main_area, true);
lv_cont_set_fit2(main_area, LV_FIT_PARENT, LV_FIT_PARENT);
lv_cont_set_layout(main_area, LV_LAYOUT_COLUMN_MID);
// Footer area.
lv_obj_t * bottom = lv_cont_create(page, NULL);
lv_obj_set_auto_realign(bottom, true);
lv_cont_set_fit2(bottom, LV_FIT_PARENT, LV_FIT_TIGHT);
lv_cont_set_layout(bottom, LV_LAYOUT_COLUMN_MID);
lv_obj_t * footer = lv_label_create(bottom, NULL);
lv_label_set_text(footer, "FOOTER");
lv_label_set_align(footer, LV_LABEL_ALIGN_CENTER);
}