Container which resizes its contents to the "Best Fit"

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

I need a Container or Control that automatically resizes its contents to the “Best Fit”. Meaning the contents should fill as much available space as they can without going outside the borders, but maintain their aspect ratio instead of stretching. An example would look like the green box in this image:

The grid always scales up as much as it can, without changing the 1:1 ratio of the squares.

I can code this behavior on a Node2D by recalculating the scale whenever there’s a change, but I want to figure out the right way to pull this off with Controls. This seems like a common enough use case that it should be built-in, but no combination I’ve tried of controls and size flags behaves like this. What else should I try?

Assuming each smaller square is the “managed” control, it’s not clear to me why you’d expect the grid dimensions you show in some cases. For example, in the case of the 2 columns, why only 2 columns with so much space left over on the left/right? And with the denser, yellow grid - why so many rows with so much space left above/below?

Or, maybe you expect to specify the grid dimensions and then have the contents “fit” to the available space.

I don’t necessarily have an answer, but you might want to clarify exactly what your expectations are.

jgodfrey | 2023-03-20 02:00

More to the point I guess, if you’re just passing a set of “N” controls to some container for automatic arrangement (and scaling), what do you consider “best fit”?

jgodfrey | 2023-03-20 02:02

jgodfrey: The user chooses how many rows and columns there are, and each cell of the grid must remain a 1:1 square. Best Fit means it should scale the width and height of the grid equally in both dimensions until there’s either no more room to grow horizontally OR no more room vertically. I’m not worried about extra leftover space in one dimension as long as the other is filled.

The 2x5 and 10x6 examples are edge cases to demonstrate what I’m looking for. The squares of the grid remain 1:1 squares, and the number of columns/rows do not change to fill in empty space. It just scales up the contents as far as it can before either the height or width maxes out. Does that answer your question?

almightyFaceplant | 2023-03-20 02:18

Yep, that’s what I assumed. But, it wasn’t clear whether you intended to specify the grid or have the container “figure it out”. And, I was just trying to point out that I wouldn’t expect a container to be filled in exactly the ways you indicated just by being handed a set of child controls.

That’s clear - thanks. And, nice example image. :slight_smile:

jgodfrey | 2023-03-20 02:22

Appreciate it!

Best real-life example I can think of is a Wordle app. (If the player could choose the number of rows and columns.)

almightyFaceplant | 2023-03-20 02:55

:bust_in_silhouette: Reply From: aidave

You may want to look at it from another perspective: using a Viewport, where you render your whole scene, then use the Viewport settings to scale everything up or down to the total size.

Also look at the apps made with Godot and see if there are any that have achieved what you’re trying to do: https://godotengine.org/showcase/ Some of them are opensource

Can you elaborate? I can set a Viewport and ViewportContainer to fill the available space , but the contents of the Viewport still don’t resize to make the best use of the space. It just puts me back to square one. If I attempt to recreate the examples in my example image, they won’t scale up to fill the available space, or clip outside the bounds of the Viewport.

None of the showcase apps or sample programs appear to use this behavior, I’m not able to make use of them in this case.

almightyFaceplant | 2023-03-22 00:58

Well you would have to calculate the size of the viewport. A viewport isn’t the ideal solution anyways, because fonts won’t render well.

TBH I don’t think Godot has anything that does what you want built-in. Unfortunately it doesnt have the ability like CSS or other languages to do advanced layout. v4 has some better stuff like Center mode on VBox that helps center RichTextLabels.

You may find others widgets/discussions on this useful:

GitHub - Nif-kun/godot-flex-container: An adjustable flex container.

Add a Flow Layout Container · Issue #1980 · godotengine/godot-proposals · GitHub

GitHub - gilzoide/godot-fixed-cell-grid-container: Simple grid Container with fixed size cells for Godot

GitHub - gilzoide/godot-dockable-container: Dockable/tiling UI panels Container addon for Godot

Godot Asset Library

aidave | 2023-03-22 12:24