Merge pull request #89024 from bruvzg/rtl_hover_meta
[RTL] Add optional `push_meta` argument to control how meta underline is drawn.
This commit is contained in:
commit
8e951fd0a9
5 changed files with 67 additions and 6 deletions
|
@ -428,8 +428,10 @@
|
|||
<method name="push_meta">
|
||||
<return type="void" />
|
||||
<param index="0" name="data" type="Variant" />
|
||||
<param index="1" name="underline_mode" type="int" enum="RichTextLabel.MetaUnderline" default="1" />
|
||||
<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].
|
||||
[b]Note:[/b] Meta tags do nothing by default when clicked. To assign behavior when clicked, connect [signal meta_clicked] to a function that is called when the meta tag is clicked.
|
||||
</description>
|
||||
</method>
|
||||
|
@ -723,6 +725,15 @@
|
|||
<constant name="MENU_MAX" value="2" enum="MenuItems">
|
||||
Represents the size of the [enum MenuItems] enum.
|
||||
</constant>
|
||||
<constant name="META_UNDERLINE_NEVER" value="0" enum="MetaUnderline">
|
||||
Meta tag does not display an underline, even if [member meta_underlined] is [code]true[/code].
|
||||
</constant>
|
||||
<constant name="META_UNDERLINE_ALWAYS" value="1" enum="MetaUnderline">
|
||||
If [member meta_underlined] is [code]true[/code], meta tag always display an underline.
|
||||
</constant>
|
||||
<constant name="META_UNDERLINE_ON_HOVER" value="2" enum="MetaUnderline">
|
||||
If [member meta_underlined] is [code]true[/code], meta tag display an underline when the mouse cursor is over it.
|
||||
</constant>
|
||||
<constant name="UPDATE_TEXTURE" value="1" enum="ImageUpdateMask" is_bitfield="true">
|
||||
If this bit is set, [method update_image] changes image texture.
|
||||
</constant>
|
||||
|
|
|
@ -224,3 +224,10 @@ Validate extension JSON: JSON file: Field was added in a way that breaks compati
|
|||
Added a return value for add_bone.
|
||||
Should not affect existing regular use - the return value would just be unused.
|
||||
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.
|
||||
|
||||
Added optional argument. Compatibility method registered.
|
||||
|
|
|
@ -30,11 +30,16 @@
|
|||
|
||||
#ifndef DISABLE_DEPRECATED
|
||||
|
||||
void RichTextLabel::_push_meta_bind_compat_89024(const Variant &p_meta) {
|
||||
push_meta(p_meta, RichTextLabel::MetaUnderline::META_UNDERLINE_ALWAYS);
|
||||
}
|
||||
|
||||
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) {
|
||||
add_image(p_image, p_width, p_height, p_color, p_alignment, p_region, Variant(), false, String(), false);
|
||||
}
|
||||
|
||||
void RichTextLabel::_bind_compatibility_methods() {
|
||||
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()));
|
||||
}
|
||||
|
||||
|
|
|
@ -1223,8 +1223,25 @@ int RichTextLabel::_draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_o
|
|||
for (int i = 0; i < gl_size; i++) {
|
||||
bool selected = selection.active && (sel_start != -1) && (glyphs[i].start >= sel_start) && (glyphs[i].end <= sel_end);
|
||||
Item *it = _get_item_at_pos(it_from, it_to, glyphs[i].start);
|
||||
bool has_ul = _find_underline(it);
|
||||
if (!has_ul && underline_meta) {
|
||||
ItemMeta *meta = nullptr;
|
||||
if (_find_meta(it, nullptr, &meta) && meta) {
|
||||
switch (meta->underline) {
|
||||
case META_UNDERLINE_ALWAYS: {
|
||||
has_ul = true;
|
||||
} break;
|
||||
case META_UNDERLINE_NEVER: {
|
||||
has_ul = false;
|
||||
} break;
|
||||
case META_UNDERLINE_ON_HOVER: {
|
||||
has_ul = (meta == meta_hovering);
|
||||
} break;
|
||||
}
|
||||
}
|
||||
}
|
||||
Color font_color = _find_color(it, p_base_color);
|
||||
if (_find_underline(it) || (_find_meta(it, nullptr) && underline_meta)) {
|
||||
if (has_ul) {
|
||||
if (ul_started && font_color != ul_color_prev) {
|
||||
float y_off = TS->shaped_text_get_underline_position(rid);
|
||||
float underline_width = MAX(1.0, TS->shaped_text_get_underline_thickness(rid) * theme_cache.base_scale);
|
||||
|
@ -2242,6 +2259,7 @@ void RichTextLabel::gui_input(const Ref<InputEvent> &p_event) {
|
|||
|
||||
Variant meta;
|
||||
ItemMeta *item_meta;
|
||||
ItemMeta *prev_meta = meta_hovering;
|
||||
if (c_item && !outside && _find_meta(c_item, &meta, &item_meta)) {
|
||||
if (meta_hovering != item_meta) {
|
||||
if (meta_hovering) {
|
||||
|
@ -2250,11 +2268,17 @@ void RichTextLabel::gui_input(const Ref<InputEvent> &p_event) {
|
|||
meta_hovering = item_meta;
|
||||
current_meta = meta;
|
||||
emit_signal(SNAME("meta_hover_started"), meta);
|
||||
if ((item_meta && item_meta->underline == META_UNDERLINE_ON_HOVER) || (prev_meta && prev_meta->underline == META_UNDERLINE_ON_HOVER)) {
|
||||
queue_redraw();
|
||||
}
|
||||
}
|
||||
} else if (meta_hovering) {
|
||||
meta_hovering = nullptr;
|
||||
emit_signal(SNAME("meta_hover_ended"), current_meta);
|
||||
current_meta = false;
|
||||
if (prev_meta->underline == META_UNDERLINE_ON_HOVER) {
|
||||
queue_redraw();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3650,7 +3674,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) {
|
||||
void RichTextLabel::push_meta(const Variant &p_meta, MetaUnderline p_underline_mode) {
|
||||
_stop_thread();
|
||||
MutexLock data_lock(data_mutex);
|
||||
|
||||
|
@ -3659,6 +3683,7 @@ void RichTextLabel::push_meta(const Variant &p_meta) {
|
|||
item->owner = get_instance_id();
|
||||
item->rid = items.make_rid(item);
|
||||
item->meta = p_meta;
|
||||
item->underline = p_underline_mode;
|
||||
_add_item(item, true);
|
||||
}
|
||||
|
||||
|
@ -4573,14 +4598,14 @@ void RichTextLabel::append_text(const String &p_bbcode) {
|
|||
end = p_bbcode.length();
|
||||
}
|
||||
String url = p_bbcode.substr(brk_end + 1, end - brk_end - 1).unquote();
|
||||
push_meta(url);
|
||||
push_meta(url, META_UNDERLINE_ALWAYS);
|
||||
|
||||
pos = brk_end + 1;
|
||||
tag_stack.push_front(tag);
|
||||
|
||||
} else if (tag.begins_with("url=")) {
|
||||
String url = tag.substr(4, tag.length()).unquote();
|
||||
push_meta(url);
|
||||
push_meta(url, META_UNDERLINE_ALWAYS);
|
||||
pos = brk_end + 1;
|
||||
tag_stack.push_front("url");
|
||||
} else if (tag.begins_with("hint=")) {
|
||||
|
@ -5891,7 +5916,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"), &RichTextLabel::push_meta);
|
||||
ClassDB::bind_method(D_METHOD("push_meta", "data", "underline_mode"), &RichTextLabel::push_meta, DEFVAL(META_UNDERLINE_ALWAYS));
|
||||
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);
|
||||
|
@ -6081,6 +6106,10 @@ void RichTextLabel::_bind_methods() {
|
|||
BIND_ENUM_CONSTANT(MENU_SELECT_ALL);
|
||||
BIND_ENUM_CONSTANT(MENU_MAX);
|
||||
|
||||
BIND_ENUM_CONSTANT(META_UNDERLINE_NEVER);
|
||||
BIND_ENUM_CONSTANT(META_UNDERLINE_ALWAYS);
|
||||
BIND_ENUM_CONSTANT(META_UNDERLINE_ON_HOVER);
|
||||
|
||||
BIND_BITFIELD_FLAG(UPDATE_TEXTURE);
|
||||
BIND_BITFIELD_FLAG(UPDATE_SIZE);
|
||||
BIND_BITFIELD_FLAG(UPDATE_COLOR);
|
||||
|
|
|
@ -51,6 +51,12 @@ public:
|
|||
LIST_DOTS
|
||||
};
|
||||
|
||||
enum MetaUnderline {
|
||||
META_UNDERLINE_NEVER,
|
||||
META_UNDERLINE_ALWAYS,
|
||||
META_UNDERLINE_ON_HOVER,
|
||||
};
|
||||
|
||||
enum ItemType {
|
||||
ITEM_FRAME,
|
||||
ITEM_TEXT,
|
||||
|
@ -117,6 +123,7 @@ protected:
|
|||
static void _bind_methods();
|
||||
|
||||
#ifndef DISABLE_DEPRECATED
|
||||
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);
|
||||
static void _bind_compatibility_methods();
|
||||
#endif
|
||||
|
@ -271,6 +278,7 @@ private:
|
|||
|
||||
struct ItemMeta : public Item {
|
||||
Variant meta;
|
||||
MetaUnderline underline = META_UNDERLINE_ALWAYS;
|
||||
ItemMeta() { type = ITEM_META; }
|
||||
};
|
||||
|
||||
|
@ -668,7 +676,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);
|
||||
void push_meta(const Variant &p_meta, MetaUnderline p_underline_mode = META_UNDERLINE_ALWAYS);
|
||||
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);
|
||||
|
@ -824,6 +832,7 @@ public:
|
|||
|
||||
VARIANT_ENUM_CAST(RichTextLabel::ListType);
|
||||
VARIANT_ENUM_CAST(RichTextLabel::MenuItems);
|
||||
VARIANT_ENUM_CAST(RichTextLabel::MetaUnderline);
|
||||
VARIANT_BITFIELD_CAST(RichTextLabel::ImageUpdateMask);
|
||||
|
||||
#endif // RICH_TEXT_LABEL_H
|
||||
|
|
Loading…
Reference in a new issue