How to make an lv_win a child of another lv_win

Description

I am trying to make a window (lv_win) be a child of another window (lv_win), but the child window is being positioned in the content area of the parent window, instead of fully over the top of it (to occupy the entire display area).

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

PIC32MZ

What LVGL version are you using?

v8.3

What do you want to achieve?

I am trying to create a “chain” (tree) of windows that build upon lv_scr_act() like this:

 * Run-Time Object Tree:
 *
 *        lv_scr_act()   <-------- Note that lv_scr_act() never changes during
 *            |                      settings-window session.
 *        Hub Window
 *            |
 *       Child Window
 *            |
 *     Child Child Window
 *            |
 *           etc.

Each window will have a BACK button and a CLOSE button. The BACK button merely performs a

lv_obj_del(curr_window);

and the CLOSE button will delete the HUB (root) window, thus deleting the whole tree.

lv_obj_del(hub_window);

Reason: lv_obj_del() automatically deletes all its children, and this is exactly what I want to take advantage of in my user interface.

What have you tried so far?

I studied the v8.3 documentation for lv_win (more than once).

See code below. I am about to try just going with objects (lv_obj) without making the background container a FLEX-FLOW COLUMN container, manually aligning the header (title bar) and making the content area a FLEX-FLOW COLUMN container instead of the the whole container.

Code to reproduce

Hub (root) window:

	SHW_sWindowTreeHub.ipRootWindow = win = lv_win_create(lv_scr_act(), 38);
	lv_obj_set_style_text_font(win, &lv_font_montserrat_30, LV_PART_MAIN);
	btn = lv_win_add_btn(win, HM_SYMBOL_LEFT, 36);
	lv_win_add_title(win, "Root Window");
	btn = lv_win_add_btn(win, HM_SYMBOL_CLOSE, 36);
	content_area = lv_win_get_content(win);
	lv_obj_set_flex_flow(content_area, LV_FLEX_FLOW_COLUMN);
	lv_obj_set_style_flex_main_place(content_area, LV_FLEX_ALIGN_SPACE_EVENLY, LV_PART_MAIN);

	itm = &SHW_saItems[SHWItem_basics];
	itm->ipContainer = nvc = wdtNVC_Create(content_area, itm, "Basics...");
	lv_obj_add_event_cb(nvc, SHW_OnEvent, LV_EVENT_CLICKED, (void *)SHWItem_basics);

	itm = &SHW_saItems[SHWItem_display];
	itm->ipContainer = nvc = wdtNVC_Create(content_area, itm, "Display...");
	lv_obj_add_event_cb(nvc, SHW_OnEvent, LV_EVENT_CLICKED, (void *)SHWItem_display);

where wdtNVC_Create() merely creates a horizontal lv_obj_t (FLEX-FLOW ROW) that intercepts CLICKED events to take actions. The above code creates this:

image

Then passing SHW_sWindowTreeHub.ipRootWindow as apParent, the child window:

	SBasics_spThisWindow = win = lv_win_create(apParent, 38);
	lv_obj_set_style_text_font(win, &lv_font_montserrat_30, LV_PART_MAIN);
	btn = lv_win_add_btn(win, HM_SYMBOL_LEFT, 36);
	lv_win_add_title(win, "Child Window 1");
	btn = lv_win_add_btn(win, HM_SYMBOL_CLOSE, 36);
	content_area = lv_win_get_content(win);
	lv_obj_set_flex_flow(content_area, LV_FLEX_FLOW_COLUMN);
	lv_obj_set_style_flex_main_place(content_area, LV_FLEX_ALIGN_SPACE_EVENLY, LV_PART_MAIN);

	itm = &SBasics_saItems[SBasicsItem_basics];
	itm->ipContainer = nvc = wdtNVC_Create(content_area, itm, "Make/Model...");
	lv_obj_add_event_cb(nvc, SBasics_OnEvent, LV_EVENT_CLICKED, (void *)eSBasicsItem_basics);

	itm = &SBasics_saItems[SBasicsItem_wireless_telemetry];
	itm->ipContainer = nvc = wdtNVC_Create(content_area, itm, "Wireless Telemetry...");
	lv_obj_add_event_cb(nvc, SBasics_OnEvent, LV_EVENT_CLICKED, (void *)eSBasicsItem_wireless_telemetry);

creates this:

image

But I am trying to get the child window (and subsequent child windows) to be positioned at (0,0) instead of (0,38). Is the FLEX layout feature of the parent window protecting the visibility of the root window’s header by shifting the child window down? (Calling lv_obj_set_style_y(child_win, 0) does not cause any change in layout.) I’d like the child window to look like this:

image

Screenshot and/or video

See above.

Does anyone know why the child lv_win_t is being forced to be positioned below the header (title bar)? Is it something I can turn off?

Kind regards,
Vic

Partially solved: As soon as the background container (the lv_win_t itself) had this removed

    lv_obj_set_flex_flow(win, LV_FLEX_FLOW_COLUMN);

which in turn called

    lv_obj_set_style_flex_flow(obj, flow, 0);
    lv_obj_set_style_layout(obj, LV_LAYOUT_FLEX, 0);

then child windows started occupying the whole display area instead of being placed below the header (title bar) of the parent window. Note: positioning and sizing of the “content area” had to be done manually since the FLEX-FLOW COLUMN and FLEX-GROW attribute was no longer governing its position and size.

What I still don’t know is WHEN in the flow of execution does the child window get forced to be below the parent window’s header (title bar)? Is it in the DRAWING? Or perhaps refreshing child object layout before that? I’m guessing the latter.

Hi there,
We are working on a similar hardware setup (PIC32MZ2048EFH144, ILI9488 display, custom PCB) and looking to migrate a project from Microchip’s old “aria” UI library to LVGL. If you don’t mind, I’d like to ask for a couple pointers (not like these https://imgs.xkcd.com/comics/pointers.png).

LVGL docs say you only need to write two “native” functions for the library to work, are these functions do you call gfx/hal functions? if not, how do we implement the native part to get LVGL to work?

The drivers/touchpad section of LVGL docs seems a little sparse, did you use a touchscreen interface? Did you face any challenges getting LVGL widgets to respond to touch events?

I’ll appreciate any information you can share.

Best regards!

1 Like

Hello! I’m sorry I didn’t see this until just now (19-Nov-2024). Where I would start is that I know that the LVGL introductory and project set-up documentation has been largely re-written and re-organized, and so I would say start with the (completely re-written) introduction to LVGL which gives a overview of how it actually works. This will allow you to work out flow of control and flow of data questions. And then continue reading forward and it will walk you through setting up LVGL with your project.