How to force Container to recalculate own rect_size?

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By mr746866

I have a scene setup as the following.

root_node
    center_container
        panel_container
            hbox_container

All 3 containers have ‘Shrink Center’ as horizontal and vertical size flags.

I dynamically insert other instanced scenes into the hbox_container and also remove them from time to time using script.

My intended behavior is that the panel_container as well as the hbox_container will resize themselves to the smallest possible rect.

It acts as expected when I insert new children, and both panel_container and hbox_container expands to accommodate them. However, when I remove them, they don’t shrink back and remain at the last expanded size. Only when I insert new children they change to appropriate size.

How do I force the containers to recalculate size upon removing children?

:bust_in_silhouette: Reply From: markopolo

My trick for forcing a control to update itself is to hide() and then immediately show() it. Not sure if that works here, fingers crossed :slight_smile:

:bust_in_silhouette: Reply From: ginobean

What seems to work for me is to hide the top level container, that needs to have it’s layout recalculated, and then add a deferred call to show it again.

In your case, your top level container of interest is panel_container.

var panel_container = $".".find_node("panel_container")
panel_container.visible = false
panel_container.call_deferred("set_visible", true)

This works for me, but it’s pretty hacky and I’d like to avoid the 1 frame delay. Any other good workaround?

fmoo | 2022-09-17 15:46

:bust_in_silhouette: Reply From: adxlv

Probably not entirely related, but I had a similar problem trying to retrieve the position property of a Container node after dynamically manipulating instanced scenes inside of it, with the values coming outdated.

The Container calculation seems to happen at the end of the frame. To fix this in Godot 4, you may use await get_tree().process_frame before requesting the updated values.

For Godot 3.x you may try using yield.

1 Like