diff --git a/doc/classes/LinkButton.xml b/doc/classes/LinkButton.xml index ab1b9882e75..e42a3bccec5 100644 --- a/doc/classes/LinkButton.xml +++ b/doc/classes/LinkButton.xml @@ -27,6 +27,9 @@ Base text writing direction. + + Sets the clipping behavior when the text exceeds the node's bounding rectangle. + The underline mode to use for the text. diff --git a/editor/asset_library/asset_library_editor_plugin.cpp b/editor/asset_library/asset_library_editor_plugin.cpp index 7ce7641f77c..16667f10772 100644 --- a/editor/asset_library/asset_library_editor_plugin.cpp +++ b/editor/asset_library/asset_library_editor_plugin.cpp @@ -67,20 +67,6 @@ void EditorAssetLibraryItem::configure(const String &p_title, int p_asset_id, co price->set_text(p_cost); } -// TODO: Refactor this method to use the TextServer. -void EditorAssetLibraryItem::clamp_width(int p_max_width) { - int text_pixel_width = title->get_button_font()->get_string_size(title_text).x * EDSCALE; - - if (text_pixel_width > p_max_width) { - // Truncate title text to within the current column width. - int max_length = p_max_width / (text_pixel_width / title_text.length()); - String truncated_text = title_text.left(max_length - 3) + "..."; - title->set_text(truncated_text); - } else { - title->set_text(title_text); - } -} - void EditorAssetLibraryItem::set_image(int p_type, int p_index, const Ref &p_image) { ERR_FAIL_COND(p_type != EditorAssetLibrary::IMAGE_QUEUE_ICON); ERR_FAIL_COND(p_index != 0); @@ -148,11 +134,13 @@ EditorAssetLibraryItem::EditorAssetLibraryItem(bool p_clickable) { title = memnew(LinkButton); title->set_accessibility_name(TTRC("Title")); title->set_auto_translate_mode(AutoTranslateMode::AUTO_TRANSLATE_MODE_DISABLED); + title->set_text_overrun_behavior(TextServer::OVERRUN_TRIM_ELLIPSIS); title->set_underline_mode(LinkButton::UNDERLINE_MODE_ON_HOVER); vb->add_child(title); category = memnew(LinkButton); category->set_accessibility_name(TTRC("Category")); + category->set_text_overrun_behavior(TextServer::OVERRUN_TRIM_ELLIPSIS); category->set_underline_mode(LinkButton::UNDERLINE_MODE_ON_HOVER); vb->add_child(category); @@ -162,6 +150,7 @@ EditorAssetLibraryItem::EditorAssetLibraryItem(bool p_clickable) { author = memnew(LinkButton); author->set_tooltip_text(TTRC("Author")); + author->set_text_overrun_behavior(TextServer::OVERRUN_TRIM_ELLIPSIS); author->set_accessibility_name(TTRC("Author")); author_price_hbox->add_child(author); @@ -1398,7 +1387,6 @@ void EditorAssetLibrary::_http_request_completed(int p_status, int p_code, const EditorAssetLibraryItem *item = memnew(EditorAssetLibraryItem(true)); asset_items->add_child(item); item->configure(r["title"], r["asset_id"], category_map[r["category_id"]], r["category_id"], r["author"], r["author_id"], r["cost"]); - item->clamp_width(asset_items_column_width); item->connect("asset_selected", callable_mp(this, &EditorAssetLibrary::_select_asset)); item->connect("author_selected", callable_mp(this, &EditorAssetLibrary::_select_author)); item->connect("category_selected", callable_mp(this, &EditorAssetLibrary::_select_category)); @@ -1534,16 +1522,6 @@ void EditorAssetLibrary::_update_asset_items_columns() { if (new_columns != asset_items->get_columns()) { asset_items->set_columns(new_columns); } - - asset_items_column_width = (get_size().x / new_columns) - (120 * EDSCALE); - - for (int i = 0; i < asset_items->get_child_count(); i++) { - EditorAssetLibraryItem *item = Object::cast_to(asset_items->get_child(i)); - if (!item || !item->is_visible()) { - continue; - } - item->clamp_width(asset_items_column_width); - } } void EditorAssetLibrary::_set_library_message(const String &p_message) { diff --git a/editor/asset_library/asset_library_editor_plugin.h b/editor/asset_library/asset_library_editor_plugin.h index c24d9989048..2628dfdaabb 100644 --- a/editor/asset_library/asset_library_editor_plugin.h +++ b/editor/asset_library/asset_library_editor_plugin.h @@ -76,8 +76,6 @@ protected: public: void configure(const String &p_title, int p_asset_id, const String &p_category, int p_category_id, const String &p_author, int p_author_id, const String &p_cost); - void clamp_width(int p_max_width); - EditorAssetLibraryItem(bool p_clickable = false); }; @@ -312,8 +310,6 @@ class EditorAssetLibrary : public PanelContainer { void _install_external_asset(String p_zip_path, String p_title); - int asset_items_column_width = 0; - void _update_asset_items_columns(); friend class EditorAssetLibraryItemDescription; diff --git a/scene/gui/link_button.cpp b/scene/gui/link_button.cpp index 1af8117d80b..abb12ec2cde 100644 --- a/scene/gui/link_button.cpp +++ b/scene/gui/link_button.cpp @@ -37,6 +37,7 @@ void LinkButton::_shape() { int font_size = theme_cache.font_size; text_buf->clear(); + text_buf->set_width(-1); if (text_direction == Control::TEXT_DIRECTION_INHERITED) { text_buf->set_direction(is_layout_rtl() ? TextServer::DIRECTION_RTL : TextServer::DIRECTION_LTR); } else { @@ -45,6 +46,7 @@ void LinkButton::_shape() { TS->shaped_text_set_bidi_override(text_buf->get_rid(), structured_text_parser(st_parser, st_args, xl_text)); const String &lang = language.is_empty() ? _get_locale() : language; text_buf->add_string(xl_text, font, font_size, lang); + text_buf->set_text_overrun_behavior(overrun_behavior); queue_accessibility_update(); } @@ -64,6 +66,19 @@ String LinkButton::get_text() const { return text; } +void LinkButton::set_text_overrun_behavior(TextServer::OverrunBehavior p_behavior) { + if (overrun_behavior != p_behavior) { + overrun_behavior = p_behavior; + _shape(); + update_minimum_size(); + queue_redraw(); + } +} + +TextServer::OverrunBehavior LinkButton::get_text_overrun_behavior() const { + return overrun_behavior; +} + void LinkButton::set_structured_text_bidi_override(TextServer::StructuredTextParser p_parser) { if (st_parser != p_parser) { st_parser = p_parser; @@ -148,7 +163,12 @@ void LinkButton::pressed() { } Size2 LinkButton::get_minimum_size() const { - return text_buf->get_size(); + Size2 minsize = text_buf->get_size(); + if (overrun_behavior != TextServer::OVERRUN_NO_TRIMMING) { + minsize.width = 0; + } + + return minsize; } void LinkButton::_notification(int p_what) { @@ -178,6 +198,7 @@ void LinkButton::_notification(int p_what) { queue_redraw(); } break; + case NOTIFICATION_RESIZED: case NOTIFICATION_THEME_CHANGED: { _shape(); update_minimum_size(); @@ -228,6 +249,9 @@ void LinkButton::_notification(int p_what) { style->draw(ci, Rect2(Point2(), size)); } + if (overrun_behavior != TextServer::OVERRUN_NO_TRIMMING) { + text_buf->set_width(MAX(1.0f, size.width)); + } int width = text_buf->get_line_width(); Color font_outline_color = theme_cache.font_outline_color; @@ -262,6 +286,8 @@ void LinkButton::_notification(int p_what) { void LinkButton::_bind_methods() { ClassDB::bind_method(D_METHOD("set_text", "text"), &LinkButton::set_text); ClassDB::bind_method(D_METHOD("get_text"), &LinkButton::get_text); + ClassDB::bind_method(D_METHOD("set_text_overrun_behavior", "overrun_behavior"), &LinkButton::set_text_overrun_behavior); + ClassDB::bind_method(D_METHOD("get_text_overrun_behavior"), &LinkButton::get_text_overrun_behavior); ClassDB::bind_method(D_METHOD("set_text_direction", "direction"), &LinkButton::set_text_direction); ClassDB::bind_method(D_METHOD("get_text_direction"), &LinkButton::get_text_direction); ClassDB::bind_method(D_METHOD("set_language", "language"), &LinkButton::set_language); @@ -283,6 +309,9 @@ void LinkButton::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::INT, "underline", PROPERTY_HINT_ENUM, "Always,On Hover,Never"), "set_underline_mode", "get_underline_mode"); ADD_PROPERTY(PropertyInfo(Variant::STRING, "uri"), "set_uri", "get_uri"); + ADD_GROUP("Text Behavior", ""); + ADD_PROPERTY(PropertyInfo(Variant::INT, "text_overrun_behavior", PROPERTY_HINT_ENUM, "Trim Nothing,Trim Characters,Trim Words,Ellipsis (6+ Characters),Word Ellipsis (6+ Characters),Ellipsis (Always),Word Ellipsis (Always)"), "set_text_overrun_behavior", "get_text_overrun_behavior"); + ADD_GROUP("BiDi", ""); ADD_PROPERTY(PropertyInfo(Variant::INT, "text_direction", PROPERTY_HINT_ENUM, "Auto,Left-to-Right,Right-to-Left,Inherited"), "set_text_direction", "get_text_direction"); ADD_PROPERTY(PropertyInfo(Variant::STRING, "language", PROPERTY_HINT_LOCALE_ID, ""), "set_language", "get_language"); diff --git a/scene/gui/link_button.h b/scene/gui/link_button.h index 4847bad9c45..a833c2c024d 100644 --- a/scene/gui/link_button.h +++ b/scene/gui/link_button.h @@ -54,6 +54,7 @@ private: TextDirection text_direction = TEXT_DIRECTION_AUTO; TextServer::StructuredTextParser st_parser = TextServer::STRUCTURED_TEXT_DEFAULT; Array st_args; + TextServer::OverrunBehavior overrun_behavior = TextServer::OVERRUN_NO_TRIMMING; struct ThemeCache { Ref focus; @@ -88,6 +89,9 @@ public: void set_uri(const String &p_uri); String get_uri() const; + void set_text_overrun_behavior(TextServer::OverrunBehavior p_behavior); + TextServer::OverrunBehavior get_text_overrun_behavior() const; + void set_structured_text_bidi_override(TextServer::StructuredTextParser p_parser); TextServer::StructuredTextParser get_structured_text_bidi_override() const; diff --git a/scene/resources/text_line.cpp b/scene/resources/text_line.cpp index 6f39e093f1a..b402b3c3686 100644 --- a/scene/resources/text_line.cpp +++ b/scene/resources/text_line.cpp @@ -321,6 +321,9 @@ String TextLine::get_ellipsis_char() const { } void TextLine::set_width(float p_width) { + if (width == p_width) { + return; + } width = p_width; if (alignment == HORIZONTAL_ALIGNMENT_FILL || overrun_behavior != TextServer::OVERRUN_NO_TRIMMING) { dirty = true;