Godot: Label node size does not auto-update through code

Created on 21 Jan 2017  路  8Comments  路  Source: godotengine/godot

Operating system or device - Godot version: Windows 10 64-bit, Godot on Steam

Issue description:
If you change the text field on a Label, it will update the margins, and update the length with get_size().x on the Label. However, these do not update automatically when setting the text field through GDScript.

Steps to reproduce:
Create a Label. Write some text in it. Delete the text, or leave it.
Adjust the Label's text field using set_text("something") in a script.
Use get_size().x or get_margin(MARGIN_RIGHT) to retrieve the text's X size.
It will retrieve the same size as it had when the text was first entered in the Inspector, and not the new size.

To get the new updated size, you have to force Godot to update its Inspector through code. This can be done by creating var update = get_size(), and then set_size(update), which forces it to re-check.

bug core

Most helpful comment

It might not be a bug, but we need to know information like this before the next frame comes, to properly position controls. So we need a way to force update it, force update the UI, before the next frame comes, if we can't get the information.

Personally I've had to "reverse-engineer" a wordwrapped textbox by pulling font size, calculate word length, etc, to avoid epileptic seizures for players. Shouldn't have to do that. Should just call tree.force_update or whatever. Other game engines have functionality like that, it should be standard.

All 8 comments

First of all thank you for your report and sorry for the delay.

We released Godot 3.0 in January 2018 after 18 months of work, fixing many old issues either directly, or by obsoleting/replacing the features they were referring to.

We still have hundreds of issues whose relevance/reproducibility needs to be checked against the current stable version, and that's where you can help us.
Could you check if the issue that you described initially is still relevant/reproducible in Godot 3.0 or any newer version, and comment about it here?

For bug reports, please also make sure that the issue contains detailed steps to reproduce the bug and, if possible, a zipped project that can be used to reproduce it right away. This greatly speeds up debugging and bugfixing tasks for our contributors.

Our Bugsquad will review this issue more in-depth in 15 days, and potentially close it if its relevance could not be confirmed.

Thanks in advance.

Note: This message is being copy-pasted to many "stale" issues (90+ days without activity). It might happen that it is not meaningful for this specific issue or appears oblivious of the issue's context, if so please comment to notify the Bugsquad about it.

I can confirm that this issue is still present (not fixed) in Godot 3.1 latest source from GitHub.

Also having this issue with RichTextLabel, get_size() returns 0,0 after set_text. In fact, it just returns 0,0 even when the Inspector shows an actual size.

However, this is after creation, it does update+show the size after one draw call, but it doesn't update based on the text size. What we need is a way to know the boundaries of the text rendered on screen, in my case to draw a ninepatch texture around the text.

EDIT: I've figured some ways around this. For example, get the font from the label, then use font.get_string_size(text).x as well as font.get_height() + font.get_descent() for the line height. It's not 100% accurate for me yet, but close, and I still have to calculate 'backwards'. At the end of the day, what I need to know is, given a width, how high will a block of text be, wrapped in that width? I'm able to find that out fairly closely with get_string_size.

This is not a bug, size is not updated immediately after you modify controls. Instead, size becomes dirty and eventually the UI is adjusted in one go. This is done to ensure best performance and is a common practice in GUI toolkits.

What you are looking for can most likely be obtained via this function:

Control.get_minimum_size()

It might not be a bug, but we need to know information like this before the next frame comes, to properly position controls. So we need a way to force update it, force update the UI, before the next frame comes, if we can't get the information.

Personally I've had to "reverse-engineer" a wordwrapped textbox by pulling font size, calculate word length, etc, to avoid epileptic seizures for players. Shouldn't have to do that. Should just call tree.force_update or whatever. Other game engines have functionality like that, it should be standard.

I've had to "reverse-engineer" a wordwrapped textbox

I did this too, and that's what caused me to find this "bug" in the first place which they're not calling a bug. If it's not a bug then it should be consistent in how updates are made, and it should have documentation.

I like naturally-intelligent's idea. I think an additional function that favors utility over performance is a good compromise. It can return the text dimensions and update the value only when the function is requested and if the value has changed since last time the function was called. Something like that.

Created a related issue here: https://github.com/godotengine/godot/issues/20623

@agameraaron @pikmeir and others, please make some noise there as it isn't closed yet! :)

Was this page helpful?
0 / 5 - 0 ratings