From 94ad663c0f8dfd56a7643f45a609266dd4c2293b Mon Sep 17 00:00:00 2001 From: bruvzg <7645683+bruvzg@users.noreply.github.com> Date: Tue, 16 Jul 2024 11:36:17 +0300 Subject: [PATCH] [RTL] Expose missing default properties, ensure bbcode is reparserd when these are changed. --- doc/classes/Label.xml | 2 +- doc/classes/Label3D.xml | 2 +- doc/classes/RichTextLabel.xml | 9 +++ doc/classes/TextMesh.xml | 2 +- doc/classes/TextParagraph.xml | 2 +- scene/gui/rich_text_label.cpp | 131 +++++++++++++++++++++++++++------- scene/gui/rich_text_label.h | 10 +++ 7 files changed, 129 insertions(+), 29 deletions(-) diff --git a/doc/classes/Label.xml b/doc/classes/Label.xml index 8acd05cbd14..e6eba30ab71 100644 --- a/doc/classes/Label.xml +++ b/doc/classes/Label.xml @@ -59,7 +59,7 @@ Controls the text's horizontal alignment. Supports left, center, right, and fill, or justify. Set it to one of the [enum HorizontalAlignment] constants. - Line fill alignment rules. For more info see [enum TextServer.JustificationFlag]. + Line fill alignment rules. See [enum TextServer.JustificationFlag] for more information. A [LabelSettings] resource that can be shared between multiple [Label] nodes. Takes priority over theme properties. diff --git a/doc/classes/Label3D.xml b/doc/classes/Label3D.xml index 4c708974525..ff26c5490dd 100644 --- a/doc/classes/Label3D.xml +++ b/doc/classes/Label3D.xml @@ -73,7 +73,7 @@ Controls the text's horizontal alignment. Supports left, center, right, and fill, or justify. Set it to one of the [enum HorizontalAlignment] constants. - Line fill alignment rules. For more info see [enum TextServer.JustificationFlag]. + Line fill alignment rules. See [enum TextServer.JustificationFlag] for more information. Language code used for line-breaking and text shaping algorithms, if left empty current locale is used instead. diff --git a/doc/classes/RichTextLabel.xml b/doc/classes/RichTextLabel.xml index 9a772835a6c..4a2cbbc3d8e 100644 --- a/doc/classes/RichTextLabel.xml +++ b/doc/classes/RichTextLabel.xml @@ -631,6 +631,12 @@ If [code]true[/code], the label underlines hint tags such as [code skip-lint][hint=description]{text}[/hint][/code]. + + Controls the text's horizontal alignment. Supports left, center, right, and fill, or justify. Set it to one of the [enum HorizontalAlignment] constants. + + + Line fill alignment rules. See [enum TextServer.JustificationFlag] for more information. + Language code used for line-breaking and text shaping algorithms, if left empty current locale is used instead. @@ -662,6 +668,9 @@ The number of spaces associated with a single tab length. Does not affect [code]\t[/code] in text tags, only indent tags. + + Aligns text to the given tab-stops. + The label's text in BBCode format. Is not representative of manual modifications to the internal tag stack. Erases changes made by other methods when edited. [b]Note:[/b] If [member bbcode_enabled] is [code]true[/code], it is unadvised to use the [code]+=[/code] operator with [member text] (e.g. [code]text += "some string"[/code]) as it replaces the whole text and can cause slowdowns. It will also erase all BBCode that was added to stack using [code]push_*[/code] methods. Use [method append_text] for adding text instead, unless you absolutely need to close a tag that was opened in an earlier method call. diff --git a/doc/classes/TextMesh.xml b/doc/classes/TextMesh.xml index 9e705311c56..898d19aed39 100644 --- a/doc/classes/TextMesh.xml +++ b/doc/classes/TextMesh.xml @@ -31,7 +31,7 @@ Controls the text's horizontal alignment. Supports left, center, right, and fill, or justify. Set it to one of the [enum HorizontalAlignment] constants. - Line fill alignment rules. For more info see [enum TextServer.JustificationFlag]. + Line fill alignment rules. See [enum TextServer.JustificationFlag] for more information. Language code used for text shaping algorithms, if left empty current locale is used instead. diff --git a/doc/classes/TextParagraph.xml b/doc/classes/TextParagraph.xml index c6511a2b8e9..46197f19b88 100644 --- a/doc/classes/TextParagraph.xml +++ b/doc/classes/TextParagraph.xml @@ -278,7 +278,7 @@ Ellipsis character used for text clipping. - Line fill alignment rules. For more info see [enum TextServer.JustificationFlag]. + Line fill alignment rules. See [enum TextServer.JustificationFlag] for more information. Limits the lines of text shown. diff --git a/scene/gui/rich_text_label.cpp b/scene/gui/rich_text_label.cpp index 457392fb2c0..9bb6130742f 100644 --- a/scene/gui/rich_text_label.cpp +++ b/scene/gui/rich_text_label.cpp @@ -1800,13 +1800,13 @@ void RichTextLabel::_notification(int p_what) { case NOTIFICATION_RESIZED: { _stop_thread(); - main->first_resized_line.store(0); //invalidate ALL + main->first_resized_line.store(0); // Invalidate all lines. queue_redraw(); } break; case NOTIFICATION_THEME_CHANGED: { _stop_thread(); - main->first_invalid_font_line.store(0); //invalidate ALL + main->first_invalid_font_line.store(0); // Invalidate all lines. queue_redraw(); } break; @@ -1816,7 +1816,7 @@ void RichTextLabel::_notification(int p_what) { set_text(text); } - main->first_invalid_line.store(0); //invalidate ALL + main->first_invalid_line.store(0); // Invalidate all lines. queue_redraw(); } break; @@ -2528,7 +2528,7 @@ PackedFloat32Array RichTextLabel::_find_tab_stops(Item *p_item) { item = item->parent; } - return PackedFloat32Array(); + return default_tab_stops; } HorizontalAlignment RichTextLabel::_find_alignment(Item *p_item) { @@ -4444,19 +4444,19 @@ void RichTextLabel::append_text(const String &p_bbcode) { add_text(String::chr(0x00AD)); pos = brk_end + 1; } else if (tag == "center") { - push_paragraph(HORIZONTAL_ALIGNMENT_CENTER); + push_paragraph(HORIZONTAL_ALIGNMENT_CENTER, text_direction, language, st_parser, default_jst_flags, default_tab_stops); pos = brk_end + 1; tag_stack.push_front(tag); } else if (tag == "fill") { - push_paragraph(HORIZONTAL_ALIGNMENT_FILL); + push_paragraph(HORIZONTAL_ALIGNMENT_FILL, text_direction, language, st_parser, default_jst_flags, default_tab_stops); pos = brk_end + 1; tag_stack.push_front(tag); } else if (tag == "left") { - push_paragraph(HORIZONTAL_ALIGNMENT_LEFT); + push_paragraph(HORIZONTAL_ALIGNMENT_LEFT, text_direction, language, st_parser, default_jst_flags, default_tab_stops); pos = brk_end + 1; tag_stack.push_front(tag); } else if (tag == "right") { - push_paragraph(HORIZONTAL_ALIGNMENT_RIGHT); + push_paragraph(HORIZONTAL_ALIGNMENT_RIGHT, text_direction, language, st_parser, default_jst_flags, default_tab_stops); pos = brk_end + 1; tag_stack.push_front(tag); } else if (tag == "ul") { @@ -4515,8 +4515,8 @@ void RichTextLabel::append_text(const String &p_bbcode) { HorizontalAlignment alignment = HORIZONTAL_ALIGNMENT_LEFT; Control::TextDirection dir = Control::TEXT_DIRECTION_INHERITED; - String lang; - PackedFloat32Array tab_stops; + String lang = language; + PackedFloat32Array tab_stops = default_tab_stops; TextServer::StructuredTextParser st_parser_type = TextServer::STRUCTURED_TEXT_DEFAULT; BitField jst_flags = default_jst_flags; for (int i = 0; i < subtag.size(); i++) { @@ -5734,19 +5734,89 @@ void RichTextLabel::set_text_direction(Control::TextDirection p_text_direction) if (text_direction != p_text_direction) { text_direction = p_text_direction; - main->first_invalid_line.store(0); //invalidate ALL - _validate_line_caches(); + if (!text.is_empty()) { + _apply_translation(); + } else { + main->first_invalid_line.store(0); // Invalidate all lines. + _validate_line_caches(); + } queue_redraw(); } } +Control::TextDirection RichTextLabel::get_text_direction() const { + return text_direction; +} + +void RichTextLabel::set_horizontal_alignment(HorizontalAlignment p_alignment) { + ERR_FAIL_INDEX((int)p_alignment, 4); + _stop_thread(); + + if (default_alignment != p_alignment) { + default_alignment = p_alignment; + if (!text.is_empty()) { + _apply_translation(); + } else { + main->first_invalid_line.store(0); // Invalidate all lines. + _validate_line_caches(); + } + queue_redraw(); + } +} + +HorizontalAlignment RichTextLabel::get_horizontal_alignment() const { + return default_alignment; +} + +void RichTextLabel::set_justification_flags(BitField p_flags) { + _stop_thread(); + + if (default_jst_flags != p_flags) { + default_jst_flags = p_flags; + if (!text.is_empty()) { + _apply_translation(); + } else { + main->first_invalid_line.store(0); // Invalidate all lines. + _validate_line_caches(); + } + queue_redraw(); + } +} + +BitField RichTextLabel::get_justification_flags() const { + return default_jst_flags; +} + +void RichTextLabel::set_tab_stops(const PackedFloat32Array &p_tab_stops) { + _stop_thread(); + + if (default_tab_stops != p_tab_stops) { + default_tab_stops = p_tab_stops; + if (!text.is_empty()) { + _apply_translation(); + } else { + main->first_invalid_line.store(0); // Invalidate all lines. + _validate_line_caches(); + } + queue_redraw(); + } +} + +PackedFloat32Array RichTextLabel::get_tab_stops() const { + return default_tab_stops; +} + void RichTextLabel::set_structured_text_bidi_override(TextServer::StructuredTextParser p_parser) { if (st_parser != p_parser) { _stop_thread(); st_parser = p_parser; - main->first_invalid_line.store(0); //invalidate ALL - _validate_line_caches(); + if (!text.is_empty()) { + _apply_translation(); + } else { + main->first_invalid_line.store(0); // Invalidate all lines. + _validate_line_caches(); + } queue_redraw(); } } @@ -5760,7 +5830,7 @@ void RichTextLabel::set_structured_text_bidi_override_options(Array p_args) { _stop_thread(); st_args = p_args; - main->first_invalid_line.store(0); //invalidate ALL + main->first_invalid_line.store(0); // Invalidate all lines. _validate_line_caches(); queue_redraw(); } @@ -5770,17 +5840,17 @@ Array RichTextLabel::get_structured_text_bidi_override_options() const { return st_args; } -Control::TextDirection RichTextLabel::get_text_direction() const { - return text_direction; -} - void RichTextLabel::set_language(const String &p_language) { if (language != p_language) { _stop_thread(); language = p_language; - main->first_invalid_line.store(0); //invalidate ALL - _validate_line_caches(); + if (!text.is_empty()) { + _apply_translation(); + } else { + main->first_invalid_line.store(0); // Invalidate all lines. + _validate_line_caches(); + } queue_redraw(); } } @@ -5794,7 +5864,7 @@ void RichTextLabel::set_autowrap_mode(TextServer::AutowrapMode p_mode) { _stop_thread(); autowrap_mode = p_mode; - main->first_invalid_line = 0; //invalidate ALL + main->first_invalid_line = 0; // Invalidate all lines. _validate_line_caches(); queue_redraw(); } @@ -5820,7 +5890,7 @@ void RichTextLabel::set_visible_ratio(float p_ratio) { } if (visible_chars_behavior == TextServer::VC_CHARS_BEFORE_SHAPING) { - main->first_invalid_line.store(0); // Invalidate ALL. + main->first_invalid_line.store(0); // Invalidate all lines.. _validate_line_caches(); } queue_redraw(); @@ -5948,6 +6018,13 @@ void RichTextLabel::_bind_methods() { ClassDB::bind_method(D_METHOD("set_language", "language"), &RichTextLabel::set_language); ClassDB::bind_method(D_METHOD("get_language"), &RichTextLabel::get_language); + ClassDB::bind_method(D_METHOD("set_horizontal_alignment", "alignment"), &RichTextLabel::set_horizontal_alignment); + ClassDB::bind_method(D_METHOD("get_horizontal_alignment"), &RichTextLabel::get_horizontal_alignment); + ClassDB::bind_method(D_METHOD("set_justification_flags", "justification_flags"), &RichTextLabel::set_justification_flags); + ClassDB::bind_method(D_METHOD("get_justification_flags"), &RichTextLabel::get_justification_flags); + ClassDB::bind_method(D_METHOD("set_tab_stops", "tab_stops"), &RichTextLabel::set_tab_stops); + ClassDB::bind_method(D_METHOD("get_tab_stops"), &RichTextLabel::get_tab_stops); + ClassDB::bind_method(D_METHOD("set_autowrap_mode", "autowrap_mode"), &RichTextLabel::set_autowrap_mode); ClassDB::bind_method(D_METHOD("get_autowrap_mode"), &RichTextLabel::get_autowrap_mode); @@ -6068,6 +6145,10 @@ void RichTextLabel::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::BOOL, "context_menu_enabled"), "set_context_menu_enabled", "is_context_menu_enabled"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "shortcut_keys_enabled"), "set_shortcut_keys_enabled", "is_shortcut_keys_enabled"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "horizontal_alignment", PROPERTY_HINT_ENUM, "Left,Center,Right,Fill"), "set_horizontal_alignment", "get_horizontal_alignment"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "justification_flags", PROPERTY_HINT_FLAGS, "Kashida Justification:1,Word Justification:2,Justify Only After Last Tab:8,Skip Last Line:32,Skip Last Line With Visible Characters:64,Do Not Skip Single Line:128"), "set_justification_flags", "get_justification_flags"); + ADD_PROPERTY(PropertyInfo(Variant::PACKED_FLOAT32_ARRAY, "tab_stops"), "set_tab_stops", "get_tab_stops"); + ADD_GROUP("Markup", ""); ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "custom_effects", PROPERTY_HINT_ARRAY_TYPE, MAKE_RESOURCE_TYPE_HINT("RichTextEffect"), (PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_SCRIPT_VARIABLE)), "set_effects", "get_effects"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "meta_underlined"), "set_meta_underline", "is_meta_underlined"); @@ -6170,7 +6251,7 @@ void RichTextLabel::set_visible_characters_behavior(TextServer::VisibleCharacter _stop_thread(); visible_chars_behavior = p_behavior; - main->first_invalid_line.store(0); //invalidate ALL + main->first_invalid_line.store(0); // Invalidate all lines. _validate_line_caches(); queue_redraw(); } @@ -6190,7 +6271,7 @@ void RichTextLabel::set_visible_characters(int p_visible) { } } if (visible_chars_behavior == TextServer::VC_CHARS_BEFORE_SHAPING) { - main->first_invalid_line.store(0); //invalidate ALL + main->first_invalid_line.store(0); // Invalidate all lines. _validate_line_caches(); } queue_redraw(); diff --git a/scene/gui/rich_text_label.h b/scene/gui/rich_text_label.h index 9f81674454a..6da13e7b2de 100644 --- a/scene/gui/rich_text_label.h +++ b/scene/gui/rich_text_label.h @@ -482,6 +482,7 @@ private: HorizontalAlignment default_alignment = HORIZONTAL_ALIGNMENT_LEFT; BitField default_jst_flags = TextServer::JUSTIFICATION_WORD_BOUND | TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_SKIP_LAST_LINE | TextServer::JUSTIFICATION_DO_NOT_SKIP_SINGLE_LINE; + PackedFloat32Array default_tab_stops; ItemMeta *meta_hovering = nullptr; Variant current_meta; @@ -808,6 +809,15 @@ public: void set_text(const String &p_bbcode); String get_text() const; + void set_horizontal_alignment(HorizontalAlignment p_alignment); + HorizontalAlignment get_horizontal_alignment() const; + + void set_justification_flags(BitField p_flags); + BitField get_justification_flags() const; + + void set_tab_stops(const PackedFloat32Array &p_tab_stops); + PackedFloat32Array get_tab_stops() const; + void set_text_direction(TextDirection p_text_direction); TextDirection get_text_direction() const;