godotengine / godot-proposals

Godot Improvement Proposals (GIPs)
MIT License
1.12k stars 69 forks source link

Add a way for RichTextLabel BBCode to set relative `font_size` instead of absolute numbers (e.g. `[font_size=+2]` or `[font_size=-4]`) #10279

Open DanielSnd opened 1 month ago

DanielSnd commented 1 month ago

Describe the project you are working on

Multiple Games in Godot that use RichTextLabel with BBCode to format their text in the UI.

Describe the problem or limitation you are having in your project

Sometimes the same code that is setting the RichTextLabel text might be used in different RichTextLabels with different base font sizes. So when writing the code with the [font_size=number] if I want this part of the text to be smaller or bigger than the rest (Think a title, or a sub-header) I need to set the number in a way that it makes sense with the regular font size. Which becomes a problem when I don't know what that font size is ahead of time.

Describe the feature / enhancement and how it helps to overcome the problem or limitation

Instead of only being able to define the font_size in absolute numbers like [font_size=30] I would like to define a relative font_size, for example: [font_size=-5] (5 less than the base font size) or [font_size=+3] (3 more than the base font size).

Describe how your proposal will work, with code, pseudo-code, mock-ups, and/or diagrams

On rich_text_label.cpp where we have:

} else if (tag.begins_with("font_size=")) {
            int fnt_size = tag.substr(10, tag.length()).to_int();
            push_font_size(fnt_size);
            pos = brk_end + 1;
            tag_stack.push_front("font_size");
        }

It could be something like this:

} else if (tag.begins_with("font_size=")) {
            int fnt_size = tag.substr(10, tag.length()).to_int();
            if (tag.length() > 10 && (tag[10] == static_cast<char32_t>('+') || tag[10] == static_cast<char32_t>('-'))) {
                int add_font_size = tag.substr(11, tag.length()).to_int();
                if (tag[10] == static_cast<char32_t>('+')) {
                    fnt_size = theme_cache.normal_font_size + add_font_size;
                } else {
                    fnt_size = theme_cache.normal_font_size - add_font_size;
                }
            }
            push_font_size(fnt_size);
            pos = brk_end + 1;
            tag_stack.push_front("font_size");
        }

I'm fairly new to C++ so not sure if this is a good way to do it, but it seems to work.

image

If this enhancement will not be used often, can it be worked around with a few lines of script?

The work around would be getting the base font number via script, and then use string formatting to place the adjusted number where the [font_size] bbcode is being used, which is cumbersome and makes for way more complicated.

Is there a reason why this should be core and not an add-on in the asset library?

I don't think it's possible to do something like this in an addon. I believe BBCode can only be modified/improved in the core.

Calinou commented 1 month ago

I feel units in percentages would make more sense. I'm not aware of any app that supports relative font size adjustments using pixel size differences (not even CSS has this feature without relying on variables).

DanielSnd commented 1 month ago

I feel units in percentages would make more sense. I'm not aware of any app that supports relative font size adjustments using pixel size differences (not even CSS has this feature without relying on variables).

Unity does in this case, but they also support setting it with font units, or percentage.

From their manual:

Use the tag to adjust the font size of your text. You can specify the new size in pixels, font units, or percentage. Pixel adjustments can be absolute (5px, 10px, and so on) or relative (+1 or -1, for example). Relative sizes are based on the original font size, so they're not cumulative. https://docs.unity3d.com/Packages/com.unity.textmeshpro@4.0/manual/RichTextSize.html

I feel like both are good options to have. Percentages doesn't give the same control that specific relative values do. If the current font value is 8 and I say -2 it'd mean something vastly different than if the base font value was 32.