Godot Version
v4.7.2.stable.mono.official [ed1daf0bf]
Question
This is something that I was regularly returning to, but every time I’ve failed. So I think it’s time to admit defeat and ask for help.
Node layout:
- HBoxContainer (the owner)
-
- TextureRectA (it can be anything honestly)
-
- HBoxContainer (the thing that is meant to be centered)
-
-
-
Rough layout:
TextureRectA <- equal space -> TextureRect Label <- equal space -> TextureRectB
Achieving basic layout is easy - set only HboxContainer as fill and expand, and TextureRectA and B are going to be on the opposite sides placed on the edges, and HBoxContainer will be in the center. But it will not be centered. In reality it will look like this:
TextureRectA TextureRect Label <- big empty space -> TextureRectB
It always gets moved to the left. Even if you use CenterContainer, it will not actually be centered - it will just start being displayed from the center, and Label will intersect with TextureRectB.
I’ve had good results by adding Control nodes as spacers and setting them to Fill/Expand and leaving the other nodes at their default settings. In this example from a Create or Cancel bar on a dialog, whatever the error message text is set to the 2 Control nodes end up as matching sizes with the error message nicely in the middle..
I’ve also tried it but it doesn’t work in my case. I forgot to mention it, but Label has autowrap mode set to word (smart), so if you disable fill and expand on the owner (the target HboxContainer) it will get squashed horizontally and elongated vertically, which completely destroyes the layout. Then the Controls that act as fill will just take entire space.
Is this what your trying to do?
If so you’ll likely have to set the custom minimum size for your label. In the above example the top level hbox (owner) is set layout mode anchors and full rect. The texture rects that act as bookends are just default layout settings. The centered hbox container sizing: horiziontal is shrink center and Expand. label layout’s custom minimum size is set to 200 and container sizing:horizontal is set to fill and expand. vertical is set to shrink center.
depending how dynamic it has to be you may want to add a script to the top level hbox that responds to resizing, and then sets an appropriate minimum size on the label.
I’ve made some tests and it works, I’ve initially thought it works automatically, but it’s as you say - minimum size needs to be set dynamically. If you set it in advance it will not display properly in some cases.
I will mark your answer as solution if no one provides automatic solution in a few days. Assuming automatic solution exists at all.
Labels with autowrap enabled, inside a parent container need to have a custom minimum size.
A warning should show in the editor when enabling autowrap on the label without setting a minimum size.
Also note it might be easier to just use a grid container with 3 columns as the top level (owner).
In which case set the hbox to be centered with an alignment of center, and set horizontal sizing to be expand and fill. You still have to set the cusom minimum size on the label, but it might be easier to work with. Here’s what both look like, top is grid container, bottom in hbox container as top level owner.
Behavior seems to be mostly the same to me.
As for the custom minimum size, I know it’s needed when autowrap is enabled (the warning icon). I don’t know if it’s proper approach, but I always set it to x = 1 y = 1 to silence it, since with proper settings label will take as much space as it can. If it gets squashed it’s usually a sign that you forgot to enable fill and expand. It doesn’t apply here though.
Applying custom minimum size based on real text length (with some maximum value to avoid overflow) should not be an issue, but I really want to know if there is an automatic solution, so I will let the topic be up for a day or two.
As you pointed out both ways basically behave the same way. The difference is in how the center hbox behaves. In the version with the hbox being the top level owner, the centered hbox is shrunk to the center. In the grid version the centered hbox will always fill the entire second column, and then be centered in it. Thus using the grid version you should be able to get the size of the centered hbox and use it to calculate the custom minimum size of the label based on the width of the texture rect beside it.
The following image tries to illustrate the difference. Grid version is on top, and hbox version below.
Highlighted area is the centered hbox.