Ver Fonte

[RTL] Add tooltip support to meta/url tag.

Pāvels Nadtočajevs há 9 meses atrás
pai
commit
dc71fbacc5

+ 1 - 0
doc/classes/RichTextLabel.xml

@@ -442,6 +442,7 @@
 			<return type="void" />
 			<param index="0" name="data" type="Variant" />
 			<param index="1" name="underline_mode" type="int" enum="RichTextLabel.MetaUnderline" default="1" />
+			<param index="2" name="tooltip" type="String" default="&quot;&quot;" />
 			<description>
 				Adds a meta tag to the tag stack. Similar to the BBCode [code skip-lint][url=something]{text}[/url][/code], but supports non-[String] metadata types.
 				If [member meta_underlined] is [code]true[/code], meta tags display an underline. This behavior can be customized with [param underline_mode].

+ 1 - 1
misc/extension_api_validation/4.2-stable_4.3-stable.expected

@@ -207,7 +207,7 @@ Compatibility method registered.
 
 GH-89024
 --------
-Validate extension JSON: Error: Field 'classes/RichTextLabel/methods/push_meta/arguments': size changed value in new API, from 1 to 2.
+Validate extension JSON: Error: Field 'classes/RichTextLabel/methods/push_meta/arguments': size changed value in new API, from 1 to 3.
 
 Added optional argument. Compatibility method registered.
 

+ 7 - 0
misc/extension_api_validation/4.3-stable.expected

@@ -198,3 +198,10 @@ Validate extension JSON: JSON file: Field was added in a way that breaks compati
 Validate extension JSON: JSON file: Field was added in a way that breaks compatibility 'classes/FileAccess/methods/store_var': return_value
 
 Added return values. Compatibility method registered.
+
+
+GH-99481
+--------
+Validate extension JSON: Error: Field 'classes/RichTextLabel/methods/push_meta/arguments': size changed value in new API, from 2 to 3.
+
+Optional argument added to set tooltip. Compatibility method registered.

+ 6 - 1
scene/gui/rich_text_label.compat.inc

@@ -30,8 +30,12 @@
 
 #ifndef DISABLE_DEPRECATED
 
+void RichTextLabel::_push_meta_bind_compat_99481(const Variant &p_meta, MetaUnderline p_underline_mode) {
+	push_meta(p_meta, p_underline_mode, String());
+}
+
 void RichTextLabel::_push_meta_bind_compat_89024(const Variant &p_meta) {
-	push_meta(p_meta, RichTextLabel::MetaUnderline::META_UNDERLINE_ALWAYS);
+	push_meta(p_meta, RichTextLabel::MetaUnderline::META_UNDERLINE_ALWAYS, String());
 }
 
 void RichTextLabel::_add_image_bind_compat_80410(const Ref<Texture2D> &p_image, const int p_width, const int p_height, const Color &p_color, InlineAlignment p_alignment, const Rect2 &p_region) {
@@ -43,6 +47,7 @@ bool RichTextLabel::_remove_paragraph_bind_compat_91098(int p_paragraph) {
 }
 
 void RichTextLabel::_bind_compatibility_methods() {
+	ClassDB::bind_compatibility_method(D_METHOD("push_meta", "data", "underline_mode"), &RichTextLabel::_push_meta_bind_compat_99481, DEFVAL(META_UNDERLINE_ALWAYS));
 	ClassDB::bind_compatibility_method(D_METHOD("push_meta", "data"), &RichTextLabel::_push_meta_bind_compat_89024);
 	ClassDB::bind_compatibility_method(D_METHOD("add_image", "image", "width", "height", "color", "inline_align", "region"), &RichTextLabel::_add_image_bind_compat_80410, DEFVAL(0), DEFVAL(0), DEFVAL(Color(1.0, 1.0, 1.0)), DEFVAL(INLINE_ALIGNMENT_CENTER), DEFVAL(Rect2()));
 	ClassDB::bind_compatibility_method(D_METHOD("remove_paragraph", "paragraph"), &RichTextLabel::_remove_paragraph_bind_compat_91098);

+ 34 - 2
scene/gui/rich_text_label.cpp

@@ -2311,10 +2311,13 @@ String RichTextLabel::get_tooltip(const Point2 &p_pos) const {
 
 	String description;
 	if (c_item && !outside) {
+		ItemMeta *meta = nullptr;
 		if (const_cast<RichTextLabel *>(this)->_find_hint(c_item, &description)) {
 			return description;
 		} else if (c_item->type == ITEM_IMAGE && !static_cast<ItemImage *>(c_item)->tooltip.is_empty()) {
 			return static_cast<ItemImage *>(c_item)->tooltip;
+		} else if (const_cast<RichTextLabel *>(this)->_find_meta(c_item, nullptr, &meta) && meta && !meta->tooltip.is_empty()) {
+			return meta->tooltip;
 		}
 	}
 
@@ -3778,7 +3781,7 @@ void RichTextLabel::push_list(int p_level, ListType p_list, bool p_capitalize, c
 	_add_item(item, true, true);
 }
 
-void RichTextLabel::push_meta(const Variant &p_meta, MetaUnderline p_underline_mode) {
+void RichTextLabel::push_meta(const Variant &p_meta, MetaUnderline p_underline_mode, const String &p_tooltip) {
 	_stop_thread();
 	MutexLock data_lock(data_mutex);
 
@@ -3788,6 +3791,7 @@ void RichTextLabel::push_meta(const Variant &p_meta, MetaUnderline p_underline_m
 	item->rid = items.make_rid(item);
 	item->meta = p_meta;
 	item->underline = p_underline_mode;
+	item->tooltip = p_tooltip;
 	_add_item(item, true);
 }
 
@@ -4787,6 +4791,34 @@ void RichTextLabel::append_text(const String &p_bbcode) {
 			pos = brk_end + 1;
 			tag_stack.push_front(tag);
 
+		} else if (tag.begins_with("url ")) {
+			String url;
+			MetaUnderline underline = META_UNDERLINE_ALWAYS;
+			String tooltip;
+
+			OptionMap::Iterator underline_option = bbcode_options.find("underline");
+			if (underline_option) {
+				if (underline_option->value == "never") {
+					underline = META_UNDERLINE_NEVER;
+				} else if (underline_option->value == "always") {
+					underline = META_UNDERLINE_ALWAYS;
+				} else if (underline_option->value == "hover") {
+					underline = META_UNDERLINE_ON_HOVER;
+				}
+			}
+			OptionMap::Iterator tooltip_option = bbcode_options.find("tooltip");
+			if (tooltip_option) {
+				tooltip = tooltip_option->value;
+			}
+			OptionMap::Iterator href_option = bbcode_options.find("href");
+			if (href_option) {
+				url = href_option->value;
+			}
+
+			push_meta(url, underline, tooltip);
+
+			pos = brk_end + 1;
+			tag_stack.push_front("url");
 		} else if (tag.begins_with("url=")) {
 			String url = _get_tag_value(tag).unquote();
 			push_meta(url, META_UNDERLINE_ALWAYS);
@@ -6267,7 +6299,7 @@ void RichTextLabel::_bind_methods() {
 	ClassDB::bind_method(D_METHOD("push_paragraph", "alignment", "base_direction", "language", "st_parser", "justification_flags", "tab_stops"), &RichTextLabel::push_paragraph, DEFVAL(TextServer::DIRECTION_AUTO), DEFVAL(""), DEFVAL(TextServer::STRUCTURED_TEXT_DEFAULT), DEFVAL(TextServer::JUSTIFICATION_WORD_BOUND | TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_SKIP_LAST_LINE | TextServer::JUSTIFICATION_DO_NOT_SKIP_SINGLE_LINE), DEFVAL(PackedFloat32Array()));
 	ClassDB::bind_method(D_METHOD("push_indent", "level"), &RichTextLabel::push_indent);
 	ClassDB::bind_method(D_METHOD("push_list", "level", "type", "capitalize", "bullet"), &RichTextLabel::push_list, DEFVAL(String::utf8("•")));
-	ClassDB::bind_method(D_METHOD("push_meta", "data", "underline_mode"), &RichTextLabel::push_meta, DEFVAL(META_UNDERLINE_ALWAYS));
+	ClassDB::bind_method(D_METHOD("push_meta", "data", "underline_mode", "tooltip"), &RichTextLabel::push_meta, DEFVAL(META_UNDERLINE_ALWAYS), DEFVAL(String()));
 	ClassDB::bind_method(D_METHOD("push_hint", "description"), &RichTextLabel::push_hint);
 	ClassDB::bind_method(D_METHOD("push_language", "language"), &RichTextLabel::push_language);
 	ClassDB::bind_method(D_METHOD("push_underline"), &RichTextLabel::push_underline);

+ 3 - 1
scene/gui/rich_text_label.h

@@ -132,6 +132,7 @@ protected:
 	static void _bind_methods();
 
 #ifndef DISABLE_DEPRECATED
+	void _push_meta_bind_compat_99481(const Variant &p_meta, MetaUnderline p_underline_mode);
 	void _push_meta_bind_compat_89024(const Variant &p_meta);
 	void _add_image_bind_compat_80410(const Ref<Texture2D> &p_image, const int p_width, const int p_height, const Color &p_color, InlineAlignment p_alignment, const Rect2 &p_region);
 	bool _remove_paragraph_bind_compat_91098(int p_paragraph);
@@ -291,6 +292,7 @@ private:
 	struct ItemMeta : public Item {
 		Variant meta;
 		MetaUnderline underline = META_UNDERLINE_ALWAYS;
+		String tooltip;
 		ItemMeta() { type = ITEM_META; }
 	};
 
@@ -702,7 +704,7 @@ public:
 	void push_paragraph(HorizontalAlignment p_alignment, Control::TextDirection p_direction = Control::TEXT_DIRECTION_INHERITED, const String &p_language = "", TextServer::StructuredTextParser p_st_parser = TextServer::STRUCTURED_TEXT_DEFAULT, BitField<TextServer::JustificationFlag> p_jst_flags = TextServer::JUSTIFICATION_WORD_BOUND | TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_SKIP_LAST_LINE | TextServer::JUSTIFICATION_DO_NOT_SKIP_SINGLE_LINE, const PackedFloat32Array &p_tab_stops = PackedFloat32Array());
 	void push_indent(int p_level);
 	void push_list(int p_level, ListType p_list, bool p_capitalize, const String &p_bullet = String::utf8("•"));
-	void push_meta(const Variant &p_meta, MetaUnderline p_underline_mode = META_UNDERLINE_ALWAYS);
+	void push_meta(const Variant &p_meta, MetaUnderline p_underline_mode = META_UNDERLINE_ALWAYS, const String &p_tooltip = String());
 	void push_hint(const String &p_string);
 	void push_table(int p_columns, InlineAlignment p_alignment = INLINE_ALIGNMENT_TOP, int p_align_to_row = -1);
 	void push_fade(int p_start_index, int p_length);