From 5216a0861736c511543fa4f2352d4729fdcbd3a8 Mon Sep 17 00:00:00 2001
From: bruvzg <7645683+bruvzg@users.noreply.github.com>
Date: Tue, 4 Jul 2023 09:52:50 +0300
Subject: [PATCH] [RTL] Add `pop_all`, `push_context` and `pop_context`
methods, and use it for `print_rich` to avoid unclosed tags.
---
doc/classes/RichTextLabel.xml | 18 +++++++++++++++
editor/editor_log.cpp | 8 +------
scene/gui/rich_text_label.cpp | 43 +++++++++++++++++++++++++++++++++++
scene/gui/rich_text_label.h | 10 +++++++-
4 files changed, 71 insertions(+), 8 deletions(-)
diff --git a/doc/classes/RichTextLabel.xml b/doc/classes/RichTextLabel.xml
index 07a0b8438f7..39be038e9e0 100644
--- a/doc/classes/RichTextLabel.xml
+++ b/doc/classes/RichTextLabel.xml
@@ -266,6 +266,18 @@
Terminates the current tag. Use after [code]push_*[/code] methods to close BBCodes manually. Does not need to follow [code]add_*[/code] methods.
+
+
+
+ Terminates all tags opened by [code]push_*[/code] methods.
+
+
+
+
+
+ Terminates tags opened after the last [method push_context] call (including context marker), or all tags if there's no context marker on the stack.
+
+
@@ -298,6 +310,12 @@
Adds a [code][color][/code] tag to the tag stack.
+
+
+
+ Adds a context marker to the tag stack. See [method pop_context].
+
+
diff --git a/editor/editor_log.cpp b/editor/editor_log.cpp
index 0fd9d646025..1bc9f00f08b 100644
--- a/editor/editor_log.cpp
+++ b/editor/editor_log.cpp
@@ -338,13 +338,7 @@ void EditorLog::_add_log_line(LogMessage &p_message, bool p_replace_previous) {
} else {
log->add_text(p_message.text);
}
-
- // Need to use pop() to exit out of the RichTextLabels current "push" stack.
- // We only "push" in the above switch when message type != STD and RICH, so only pop when that is the case.
- if (p_message.type != MSG_TYPE_STD && p_message.type != MSG_TYPE_STD_RICH) {
- log->pop();
- }
-
+ log->pop_all(); // Pop all unclosed tags.
log->add_newline();
if (p_replace_previous) {
diff --git a/scene/gui/rich_text_label.cpp b/scene/gui/rich_text_label.cpp
index 8fb2024e9cf..09c4ef444da 100644
--- a/scene/gui/rich_text_label.cpp
+++ b/scene/gui/rich_text_label.cpp
@@ -3444,6 +3444,7 @@ void RichTextLabel::push_fade(int p_start_index, int p_length) {
_stop_thread();
MutexLock data_lock(data_mutex);
+ ERR_FAIL_COND(current->type == ITEM_TABLE);
ItemFade *item = memnew(ItemFade);
item->starting_index = p_start_index;
item->length = p_length;
@@ -3454,6 +3455,7 @@ void RichTextLabel::push_shake(int p_strength = 10, float p_rate = 24.0f, bool p
_stop_thread();
MutexLock data_lock(data_mutex);
+ ERR_FAIL_COND(current->type == ITEM_TABLE);
ItemShake *item = memnew(ItemShake);
item->strength = p_strength;
item->rate = p_rate;
@@ -3465,6 +3467,7 @@ void RichTextLabel::push_wave(float p_frequency = 1.0f, float p_amplitude = 10.0
_stop_thread();
MutexLock data_lock(data_mutex);
+ ERR_FAIL_COND(current->type == ITEM_TABLE);
ItemWave *item = memnew(ItemWave);
item->frequency = p_frequency;
item->amplitude = p_amplitude;
@@ -3476,6 +3479,7 @@ void RichTextLabel::push_tornado(float p_frequency = 1.0f, float p_radius = 10.0
_stop_thread();
MutexLock data_lock(data_mutex);
+ ERR_FAIL_COND(current->type == ITEM_TABLE);
ItemTornado *item = memnew(ItemTornado);
item->frequency = p_frequency;
item->radius = p_radius;
@@ -3487,6 +3491,7 @@ void RichTextLabel::push_rainbow(float p_saturation, float p_value, float p_freq
_stop_thread();
MutexLock data_lock(data_mutex);
+ ERR_FAIL_COND(current->type == ITEM_TABLE);
ItemRainbow *item = memnew(ItemRainbow);
item->frequency = p_frequency;
item->saturation = p_saturation;
@@ -3520,6 +3525,7 @@ void RichTextLabel::push_customfx(Ref p_custom_effect, Dictionar
_stop_thread();
MutexLock data_lock(data_mutex);
+ ERR_FAIL_COND(current->type == ITEM_TABLE);
ItemCustomFX *item = memnew(ItemCustomFX);
item->custom_effect = p_custom_effect;
item->char_fx_transform->environment = p_environment;
@@ -3528,6 +3534,15 @@ void RichTextLabel::push_customfx(Ref p_custom_effect, Dictionar
set_process_internal(true);
}
+void RichTextLabel::push_context() {
+ _stop_thread();
+ MutexLock data_lock(data_mutex);
+
+ ERR_FAIL_COND(current->type == ITEM_TABLE);
+ ItemContext *item = memnew(ItemContext);
+ _add_item(item, true);
+}
+
void RichTextLabel::set_table_column_expand(int p_column, bool p_expand, int p_ratio) {
_stop_thread();
MutexLock data_lock(data_mutex);
@@ -3621,6 +3636,31 @@ void RichTextLabel::pop() {
current = current->parent;
}
+void RichTextLabel::pop_context() {
+ _stop_thread();
+ MutexLock data_lock(data_mutex);
+
+ ERR_FAIL_NULL(current->parent);
+
+ while (current->parent && current != main) {
+ if (current->type == ITEM_FRAME) {
+ current_frame = static_cast(current)->parent_frame;
+ } else if (current->type == ITEM_CONTEXT) {
+ current = current->parent;
+ return;
+ }
+ current = current->parent;
+ }
+}
+
+void RichTextLabel::pop_all() {
+ _stop_thread();
+ MutexLock data_lock(data_mutex);
+
+ current = main;
+ current_frame = main;
+}
+
void RichTextLabel::clear() {
_stop_thread();
MutexLock data_lock(data_mutex);
@@ -5508,7 +5548,10 @@ void RichTextLabel::_bind_methods() {
ClassDB::bind_method(D_METHOD("push_fgcolor", "fgcolor"), &RichTextLabel::push_fgcolor);
ClassDB::bind_method(D_METHOD("push_bgcolor", "bgcolor"), &RichTextLabel::push_bgcolor);
ClassDB::bind_method(D_METHOD("push_customfx", "effect", "env"), &RichTextLabel::push_customfx);
+ ClassDB::bind_method(D_METHOD("push_context"), &RichTextLabel::push_context);
+ ClassDB::bind_method(D_METHOD("pop_context"), &RichTextLabel::pop_context);
ClassDB::bind_method(D_METHOD("pop"), &RichTextLabel::pop);
+ ClassDB::bind_method(D_METHOD("pop_all"), &RichTextLabel::pop_all);
ClassDB::bind_method(D_METHOD("clear"), &RichTextLabel::clear);
diff --git a/scene/gui/rich_text_label.h b/scene/gui/rich_text_label.h
index 66891ab567d..c3690ab95cf 100644
--- a/scene/gui/rich_text_label.h
+++ b/scene/gui/rich_text_label.h
@@ -75,7 +75,8 @@ public:
ITEM_META,
ITEM_HINT,
ITEM_DROPCAP,
- ITEM_CUSTOMFX
+ ITEM_CUSTOMFX,
+ ITEM_CONTEXT
};
enum MenuItems {
@@ -370,6 +371,10 @@ private:
}
};
+ struct ItemContext : public Item {
+ ItemContext() { type = ITEM_CONTEXT; }
+ };
+
ItemFrame *main = nullptr;
Item *current = nullptr;
ItemFrame *current_frame = nullptr;
@@ -614,6 +619,7 @@ public:
void push_bgcolor(const Color &p_color);
void push_fgcolor(const Color &p_color);
void push_customfx(Ref p_custom_effect, Dictionary p_environment);
+ void push_context();
void set_table_column_expand(int p_column, bool p_expand, int p_ratio = 1);
void set_cell_row_background_color(const Color &p_odd_row_bg, const Color &p_even_row_bg);
void set_cell_border_color(const Color &p_color);
@@ -622,6 +628,8 @@ public:
int get_current_table_column() const;
void push_cell();
void pop();
+ void pop_context();
+ void pop_all();
void clear();