Skip to content

Conversation

@ColinSORourke
Copy link
Contributor

@ColinSORourke ColinSORourke commented Jan 9, 2026

Resolves:

Also Resolves:

Implements:

Godot's RichTextLabels parse and convert BBCode Text into a TagStack / ItemTree. Since Godot 4.0 (?), rendering / logic is primarily driven by this Tag Stack / Item Tree; the Text Property exists mostly for inspector convenience, and the occasional hard overwrite via code. This frequently leads to confusion when scripts modify a Label via Add_text and the such, but the changes are not reflected in the Text property. See the 6 open Duplicate Issue reports linked above, and the numerous notes about the text property being out of sync in the RichTextLabel documentation.

This PR seeks to address this issue by having the RichTextLabel update the Text Property as the ItemTree is modified to keep the two in sync. I accomplish this by:

  • Adding utility functions to the Item Classes that output appropriate BBCode tags, hopefully making the BBCode <-> ItemTree conversions 2-way
  • Having RichTextLabel store a Sync_text, representing all of the TagStack generated by push_*() & pop() calls. Whenever a user interacts with the Text property, they are actually interacting with the concatenation of text + sync_text.
  • User-generated BBCode is never over-written, duplicated, or regenerated. The internal_stack_editing flag makes it clear when the items being added are not directly from user-written text.

I have verified most simple behaviors produce correct BBCode - I may have missed some edge cases, but in the current build, every time I read the Text property it contained exactly the full BBCode I expected, and if I pasted the output back into another RichTextLabel node, they displayed identically.

Existing Behaviors Changed:

  • The Text property and the Tag Stack are functionally identical from a user perspective. There should be no way to modify one or the other that doesn't sync them together.
  • Fixed a minor issue where RTL.push_bold() then RTL.append_text("[i]bi") would not correctly create a BoldItalics node in the tree.
  • All other logic should remain the same, and similarly performant. No extra tree traversals are performed

Extremely open to feedback - is this the right approach? Is it performant enough? Are there edge cases that keeping Sync_Text does not account for? Should this be pursued at all?

@ColinSORourke
Copy link
Contributor Author

ColinSORourke commented Jan 9, 2026

Hypothetically this structure can also resolve #100772. The problem occurring there is that

  1. Label is Instantiated, has a value directly assigned to Text
  2. Label has text added to the TagStack/ItemTree via Add_text
  3. Label is added to SceneTree, which triggers NOTIFICATION_ENTER_TREE, triggering a set_text to original Text value, discarding the TagStack/Item Tree

Changing the set text call in Notification Enter Tree to _set_text(text + leading_text + terminating_text) would not discard any information that was added before the Node entered tree, and would behave the same in all other cases as far as I understand.

@ColinSORourke ColinSORourke force-pushed the RTLSyncText branch 3 times, most recently from 4efc754 to 043e966 Compare January 11, 2026 00:29
@ColinSORourke
Copy link
Contributor Author

ColinSORourke commented Jan 11, 2026

Just pushed more functionality for this.

  • Improved Internal Logic, and fixed a few errors
  • Added parameter generation for many BBCode tags
  • Caught an error where append_text would ignore existing open Bold / Italics tags. (Unrelated to this PR, or existing issue reports - present in Godot Master & 4.5.1)

Sample Test Case:

Original BBCode String: "It's also possible to include [img=24x25]res://unicorn_icon.png[/img] [font_size=24]custom images[/font_size], as well as [color=aqua][url=https://godotengine.org]custom URLs[/url][/color]. [hint=This displays a hint.]Hover this to display a tooltip![/hint]"

GDScript recreation Code:

RTL.add_text("It's also...")
	RTL.add_image(unicorn, 24, 25)
	RTL.add_text(" ")
	RTL.push_font_size(24)
	RTL.add_text("custom images")
	RTL.pop()
	RTL.add_text("as well as ")
	RTL.push_color(Color.AQUA)
	RTL.append_text("[url=https://godotengine.org]custom URLs")
	RTL.pop_all()
	RTL.add_text(". ")
	RTL.push_hint("This displays a hint")
	RTL.add_text("Hover this")
	RTL.pop()
	print(RTL.text)

Generated BBScript String: "It's also...[img color=ffffffff height=25.0 width=24.0 region=0.0,0.0,0.0,0.0 pad=false tooltip= valign=c,c alt=]res://unicorn_icon.png[/img] [font_size=24]custom images[/font_size]as well as [color=00ffffff][url=https://godotengine.org]custom URLs[/url][/color]. [hint="This displays a hint"]Hover this[/hint]"

@ColinSORourke ColinSORourke changed the title [DRAFT] Syncs RichTextLabels Text field with the Item Tree Syncs RichTextLabels Text field with the Item Tree Jan 18, 2026
@ColinSORourke ColinSORourke marked this pull request as ready for review January 18, 2026 05:08
@ColinSORourke ColinSORourke requested a review from a team as a code owner January 18, 2026 05:08
@ColinSORourke
Copy link
Contributor Author

Just pushed a 'finished' build and removed the Draft Flag from this PR. The code should be able to generate correct BBCode for all Items, and in my testing so far it has. Updated the top-level comment with current info/description.

Adds code for all RichTextLabel Items to generate appropriate BBCode tags for themselves. The RichTextLabel utilizes this behavior to keep a stack of the BBCode generated by push/pop calls without overwriting any user-generated BBCode Text
@AThousandShips AThousandShips changed the title Syncs RichTextLabels Text field with the Item Tree Make RichTextLabel's text represent the tag stack Jan 18, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants