Browse Source

Merge pull request #77117 from Calinou/richtextlabel-add-pulse-effect

Add a `[pulse]` built-in effect to RichTextLabel
Yuri Sizov 2 years ago
parent
commit
7550b02dfc
2 changed files with 55 additions and 2 deletions
  1. 45 2
      scene/gui/rich_text_label.cpp
  2. 10 0
      scene/gui/rich_text_label.h

+ 45 - 2
scene/gui/rich_text_label.cpp

@@ -1097,6 +1097,11 @@ int RichTextLabel::_draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_o
 					ItemRainbow *item_rainbow = static_cast<ItemRainbow *>(item_fx);
 					ItemRainbow *item_rainbow = static_cast<ItemRainbow *>(item_fx);
 
 
 					font_color = font_color.from_hsv(item_rainbow->frequency * (item_rainbow->elapsed_time + ((p_ofs.x + gloff.x) / 50)), item_rainbow->saturation, item_rainbow->value, font_color.a);
 					font_color = font_color.from_hsv(item_rainbow->frequency * (item_rainbow->elapsed_time + ((p_ofs.x + gloff.x) / 50)), item_rainbow->saturation, item_rainbow->value, font_color.a);
+				} else if (item_fx->type == ITEM_PULSE) {
+					ItemPulse *item_pulse = static_cast<ItemPulse *>(item_fx);
+
+					const float sined_time = (Math::ease(Math::pingpong(item_pulse->elapsed_time, 1.0 / item_pulse->frequency) * item_pulse->frequency, item_pulse->ease));
+					font_color = font_color.lerp(font_color * item_pulse->color, sined_time);
 				}
 				}
 			}
 			}
 
 
@@ -1315,6 +1320,11 @@ int RichTextLabel::_draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_o
 					ItemRainbow *item_rainbow = static_cast<ItemRainbow *>(item_fx);
 					ItemRainbow *item_rainbow = static_cast<ItemRainbow *>(item_fx);
 
 
 					font_color = font_color.from_hsv(item_rainbow->frequency * (item_rainbow->elapsed_time + ((p_ofs.x + off.x) / 50)), item_rainbow->saturation, item_rainbow->value, font_color.a);
 					font_color = font_color.from_hsv(item_rainbow->frequency * (item_rainbow->elapsed_time + ((p_ofs.x + off.x) / 50)), item_rainbow->saturation, item_rainbow->value, font_color.a);
+				} else if (item_fx->type == ITEM_PULSE) {
+					ItemPulse *item_pulse = static_cast<ItemPulse *>(item_fx);
+
+					const float sined_time = (Math::ease(Math::pingpong(item_pulse->elapsed_time, 1.0 / item_pulse->frequency) * item_pulse->frequency, item_pulse->ease));
+					font_color = font_color.lerp(font_color * item_pulse->color, sined_time);
 				}
 				}
 			}
 			}
 
 
@@ -1675,7 +1685,7 @@ void RichTextLabel::_update_fx(RichTextLabel::ItemFrame *p_frame, double p_delta
 	while (it) {
 	while (it) {
 		ItemFX *ifx = nullptr;
 		ItemFX *ifx = nullptr;
 
 
-		if (it->type == ITEM_CUSTOMFX || it->type == ITEM_SHAKE || it->type == ITEM_WAVE || it->type == ITEM_TORNADO || it->type == ITEM_RAINBOW) {
+		if (it->type == ITEM_CUSTOMFX || it->type == ITEM_SHAKE || it->type == ITEM_WAVE || it->type == ITEM_TORNADO || it->type == ITEM_RAINBOW || it->type == ITEM_PULSE) {
 			ifx = static_cast<ItemFX *>(it);
 			ifx = static_cast<ItemFX *>(it);
 		}
 		}
 
 
@@ -2616,7 +2626,7 @@ bool RichTextLabel::_find_strikethrough(Item *p_item) {
 void RichTextLabel::_fetch_item_fx_stack(Item *p_item, Vector<ItemFX *> &r_stack) {
 void RichTextLabel::_fetch_item_fx_stack(Item *p_item, Vector<ItemFX *> &r_stack) {
 	Item *item = p_item;
 	Item *item = p_item;
 	while (item) {
 	while (item) {
-		if (item->type == ITEM_CUSTOMFX || item->type == ITEM_SHAKE || item->type == ITEM_WAVE || item->type == ITEM_TORNADO || item->type == ITEM_RAINBOW) {
+		if (item->type == ITEM_CUSTOMFX || item->type == ITEM_SHAKE || item->type == ITEM_WAVE || item->type == ITEM_TORNADO || item->type == ITEM_RAINBOW || item->type == ITEM_PULSE) {
 			r_stack.push_back(static_cast<ItemFX *>(item));
 			r_stack.push_back(static_cast<ItemFX *>(item));
 		}
 		}
 
 
@@ -3494,6 +3504,17 @@ void RichTextLabel::push_rainbow(float p_saturation, float p_value, float p_freq
 	_add_item(item, true);
 	_add_item(item, true);
 }
 }
 
 
+void RichTextLabel::push_pulse(const Color &p_color, float p_frequency, float p_ease) {
+	_stop_thread();
+	MutexLock data_lock(data_mutex);
+
+	ItemPulse *item = memnew(ItemPulse);
+	item->color = p_color;
+	item->frequency = p_frequency;
+	item->ease = p_ease;
+	_add_item(item, true);
+}
+
 void RichTextLabel::push_bgcolor(const Color &p_color) {
 void RichTextLabel::push_bgcolor(const Color &p_color) {
 	_stop_thread();
 	_stop_thread();
 	MutexLock data_lock(data_mutex);
 	MutexLock data_lock(data_mutex);
@@ -4677,7 +4698,29 @@ void RichTextLabel::append_text(const String &p_bbcode) {
 			pos = brk_end + 1;
 			pos = brk_end + 1;
 			tag_stack.push_front("rainbow");
 			tag_stack.push_front("rainbow");
 			set_process_internal(true);
 			set_process_internal(true);
+		} else if (bbcode_name == "pulse") {
+			Color color = Color(1, 1, 1, 0.25);
+			OptionMap::Iterator color_option = bbcode_options.find("color");
+			if (color_option) {
+				color = Color::from_string(color_option->value, color);
+			}
+
+			float frequency = 1.0;
+			OptionMap::Iterator freq_option = bbcode_options.find("freq");
+			if (freq_option) {
+				frequency = freq_option->value.to_float();
+			}
 
 
+			float ease = -2.0;
+			OptionMap::Iterator ease_option = bbcode_options.find("ease");
+			if (ease_option) {
+				ease = ease_option->value.to_float();
+			}
+
+			push_pulse(color, frequency, ease);
+			pos = brk_end + 1;
+			tag_stack.push_front("pulse");
+			set_process_internal(true);
 		} else if (tag.begins_with("bgcolor=")) {
 		} else if (tag.begins_with("bgcolor=")) {
 			String color_str = tag.substr(8, tag.length()).unquote();
 			String color_str = tag.substr(8, tag.length()).unquote();
 			Color color = Color::from_string(color_str, theme_cache.default_color);
 			Color color = Color::from_string(color_str, theme_cache.default_color);

+ 10 - 0
scene/gui/rich_text_label.h

@@ -70,6 +70,7 @@ public:
 		ITEM_WAVE,
 		ITEM_WAVE,
 		ITEM_TORNADO,
 		ITEM_TORNADO,
 		ITEM_RAINBOW,
 		ITEM_RAINBOW,
+		ITEM_PULSE,
 		ITEM_BGCOLOR,
 		ITEM_BGCOLOR,
 		ITEM_FGCOLOR,
 		ITEM_FGCOLOR,
 		ITEM_META,
 		ITEM_META,
@@ -343,6 +344,14 @@ private:
 		ItemRainbow() { type = ITEM_RAINBOW; }
 		ItemRainbow() { type = ITEM_RAINBOW; }
 	};
 	};
 
 
+	struct ItemPulse : public ItemFX {
+		Color color = Color(1.0, 1.0, 1.0, 0.25);
+		float frequency = 1.0f;
+		float ease = -2.0f;
+
+		ItemPulse() { type = ITEM_PULSE; }
+	};
+
 	struct ItemBGColor : public Item {
 	struct ItemBGColor : public Item {
 		Color color;
 		Color color;
 		ItemBGColor() { type = ITEM_BGCOLOR; }
 		ItemBGColor() { type = ITEM_BGCOLOR; }
@@ -611,6 +620,7 @@ public:
 	void push_wave(float p_frequency, float p_amplitude, bool p_connected);
 	void push_wave(float p_frequency, float p_amplitude, bool p_connected);
 	void push_tornado(float p_frequency, float p_radius, bool p_connected);
 	void push_tornado(float p_frequency, float p_radius, bool p_connected);
 	void push_rainbow(float p_saturation, float p_value, float p_frequency);
 	void push_rainbow(float p_saturation, float p_value, float p_frequency);
+	void push_pulse(const Color &p_color, float p_frequency, float p_ease);
 	void push_bgcolor(const Color &p_color);
 	void push_bgcolor(const Color &p_color);
 	void push_fgcolor(const Color &p_color);
 	void push_fgcolor(const Color &p_color);
 	void push_customfx(Ref<RichTextEffect> p_custom_effect, Dictionary p_environment);
 	void push_customfx(Ref<RichTextEffect> p_custom_effect, Dictionary p_environment);