From 250de088e3a0f303a393405ebdaa40c7dce62550 Mon Sep 17 00:00:00 2001 From: Michael Alexsander Date: Sun, 15 Sep 2024 19:17:23 -0300 Subject: [PATCH] Fix `RichTextLabel`'s modified stack being wiped on translation changes --- scene/gui/rich_text_label.cpp | 42 ++++++++++++++++++++++++----------- scene/gui/rich_text_label.h | 3 +++ 2 files changed, 32 insertions(+), 13 deletions(-) diff --git a/scene/gui/rich_text_label.cpp b/scene/gui/rich_text_label.cpp index a349d5023687..b0886a95d7d9 100644 --- a/scene/gui/rich_text_label.cpp +++ b/scene/gui/rich_text_label.cpp @@ -1833,8 +1833,7 @@ void RichTextLabel::_notification(int p_what) { case NOTIFICATION_LAYOUT_DIRECTION_CHANGED: case NOTIFICATION_TRANSLATION_CHANGED: { - // If `text` is empty, it could mean that the tag stack is being used instead. Leave it be. - if (!text.is_empty()) { + if (!stack_externally_modified) { _apply_translation(); } @@ -3109,6 +3108,10 @@ void RichTextLabel::add_text(const String &p_text) { } void RichTextLabel::_add_item(Item *p_item, bool p_enter, bool p_ensure_newline) { + if (!internal_stack_editing) { + stack_externally_modified = true; + } + p_item->parent = current; p_item->E = current->subitems.push_back(p_item); p_item->index = current_idx++; @@ -3382,6 +3385,8 @@ bool RichTextLabel::remove_paragraph(int p_paragraph, bool p_no_invalidate) { return false; } + stack_externally_modified = true; + if (main->lines.size() == 1) { // Clear all. main->_clear_children(); @@ -4016,6 +4021,8 @@ void RichTextLabel::clear() { set_process_internal(false); MutexLock data_lock(data_mutex); + stack_externally_modified = false; + main->_clear_children(); current = main; current_frame = main; @@ -5818,11 +5825,19 @@ void RichTextLabel::set_text(const String &p_bbcode) { return; } + stack_externally_modified = false; + text = p_bbcode; _apply_translation(); } void RichTextLabel::_apply_translation() { + if (text.is_empty()) { + return; + } + + internal_stack_editing = true; + String xl_text = atr(text); if (use_bbcode) { parse_bbcode(xl_text); @@ -5830,6 +5845,8 @@ void RichTextLabel::_apply_translation() { clear(); add_text(xl_text); } + + internal_stack_editing = false; } String RichTextLabel::get_text() const { @@ -5843,8 +5860,7 @@ void RichTextLabel::set_use_bbcode(bool p_enable) { use_bbcode = p_enable; notify_property_list_changed(); - // If `text` is empty, it could mean that the tag stack is being used instead. Leave it be. - if (!text.is_empty()) { + if (!stack_externally_modified) { _apply_translation(); } } @@ -5854,7 +5870,7 @@ bool RichTextLabel::is_using_bbcode() const { } String RichTextLabel::get_parsed_text() const { - String txt = ""; + String txt; Item *it = main; while (it) { if (it->type == ITEM_DROPCAP) { @@ -5881,7 +5897,7 @@ void RichTextLabel::set_text_direction(Control::TextDirection p_text_direction) if (text_direction != p_text_direction) { text_direction = p_text_direction; - if (!text.is_empty()) { + if (!stack_externally_modified) { _apply_translation(); } else { main->first_invalid_line.store(0); // Invalidate all lines. @@ -5901,7 +5917,7 @@ void RichTextLabel::set_horizontal_alignment(HorizontalAlignment p_alignment) { if (default_alignment != p_alignment) { default_alignment = p_alignment; - if (!text.is_empty()) { + if (!stack_externally_modified) { _apply_translation(); } else { main->first_invalid_line.store(0); // Invalidate all lines. @@ -5920,7 +5936,7 @@ void RichTextLabel::set_justification_flags(BitFieldfirst_invalid_line.store(0); // Invalidate all lines. @@ -5939,7 +5955,7 @@ void RichTextLabel::set_tab_stops(const PackedFloat32Array &p_tab_stops) { if (default_tab_stops != p_tab_stops) { default_tab_stops = p_tab_stops; - if (!text.is_empty()) { + if (!stack_externally_modified) { _apply_translation(); } else { main->first_invalid_line.store(0); // Invalidate all lines. @@ -5958,7 +5974,7 @@ void RichTextLabel::set_structured_text_bidi_override(TextServer::StructuredText _stop_thread(); st_parser = p_parser; - if (!text.is_empty()) { + if (!stack_externally_modified) { _apply_translation(); } else { main->first_invalid_line.store(0); // Invalidate all lines. @@ -5992,7 +6008,7 @@ void RichTextLabel::set_language(const String &p_language) { _stop_thread(); language = p_language; - if (!text.is_empty()) { + if (!stack_externally_modified) { _apply_translation(); } else { main->first_invalid_line.store(0); // Invalidate all lines. @@ -6050,7 +6066,7 @@ float RichTextLabel::get_visible_ratio() const { void RichTextLabel::set_effects(Array p_effects) { custom_effects = p_effects; - if ((!text.is_empty()) && use_bbcode) { + if (!stack_externally_modified && use_bbcode) { parse_bbcode(atr(text)); } } @@ -6065,7 +6081,7 @@ void RichTextLabel::install_effect(const Variant effect) { ERR_FAIL_COND_MSG(rteffect.is_null(), "Invalid RichTextEffect resource."); custom_effects.push_back(effect); - if ((!text.is_empty()) && use_bbcode) { + if (!stack_externally_modified && use_bbcode) { parse_bbcode(atr(text)); } } diff --git a/scene/gui/rich_text_label.h b/scene/gui/rich_text_label.h index a01da02b2735..ef4d17b8aa3b 100644 --- a/scene/gui/rich_text_label.h +++ b/scene/gui/rich_text_label.h @@ -626,6 +626,9 @@ class RichTextLabel : public Control { String text; void _apply_translation(); + bool internal_stack_editing = false; + bool stack_externally_modified = false; + bool fit_content = false; struct ThemeCache {