diff --git a/doc/classes/LineEdit.xml b/doc/classes/LineEdit.xml index c40d0f62d96..de4cec7bba2 100644 --- a/doc/classes/LineEdit.xml +++ b/doc/classes/LineEdit.xml @@ -145,6 +145,17 @@ Maximum amount of characters that can be entered inside the [LineEdit]. If [code]0[/code], there is no limit. + When a limit is defined, characters that would exceed [member max_length] are truncated. This happens both for existing [member text] contents when setting the max length, or for new text inserted in the [LineEdit], including pasting. If any input text is truncated, the [signal text_change_rejected] signal is emitted with the truncated substring as parameter. + [b]Example:[/b] + [codeblock] + text = "Hello world" + max_length = 5 + # `text` becomes "Hello". + max_length = 10 + text += " goodbye" + # `text` becomes "Hello good". + # `text_change_rejected` is emitted with "bye" as parameter. + [/codeblock] @@ -178,8 +189,10 @@ + + - Emitted when trying to append text that would overflow the [member max_length]. + Emitted when appending text that overflows the [member max_length]. The appended text is truncated to fit [member max_length], and the part that couldn't fit is passed as the [code]rejected_substring[/code] argument. diff --git a/scene/gui/line_edit.cpp b/scene/gui/line_edit.cpp index b537f11a9c4..a9c51dd64ea 100644 --- a/scene/gui/line_edit.cpp +++ b/scene/gui/line_edit.cpp @@ -1389,15 +1389,19 @@ int LineEdit::get_scroll_offset() const { } void LineEdit::append_at_cursor(String p_text) { - if ((max_length <= 0) || (text.length() + p_text.length() <= max_length)) { - String pre = text.substr(0, cursor_pos); - String post = text.substr(cursor_pos, text.length() - cursor_pos); - text = pre + p_text + post; - update_cached_width(); - set_cursor_position(cursor_pos + p_text.length()); - } else { - emit_signal("text_change_rejected"); + if (max_length > 0) { + // Truncate text to append to fit in max_length, if needed. + int available_chars = max_length - text.length(); + if (p_text.length() > available_chars) { + emit_signal("text_change_rejected", p_text.substr(available_chars)); + p_text = p_text.substr(0, available_chars); + } } + String pre = text.substr(0, cursor_pos); + String post = text.substr(cursor_pos, text.length() - cursor_pos); + text = pre + p_text + post; + update_cached_width(); + set_cursor_position(cursor_pos + p_text.length()); } void LineEdit::clear_internal() { @@ -1845,7 +1849,7 @@ void LineEdit::_bind_methods() { ClassDB::bind_method(D_METHOD("get_right_icon"), &LineEdit::get_right_icon); ADD_SIGNAL(MethodInfo("text_changed", PropertyInfo(Variant::STRING, "new_text"))); - ADD_SIGNAL(MethodInfo("text_change_rejected")); + ADD_SIGNAL(MethodInfo("text_change_rejected", PropertyInfo(Variant::STRING, "rejected_substring"))); ADD_SIGNAL(MethodInfo("text_entered", PropertyInfo(Variant::STRING, "new_text"))); BIND_ENUM_CONSTANT(ALIGN_LEFT); @@ -1864,7 +1868,7 @@ void LineEdit::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::STRING, "text"), "set_text", "get_text"); ADD_PROPERTY(PropertyInfo(Variant::INT, "align", PROPERTY_HINT_ENUM, "Left,Center,Right,Fill"), "set_align", "get_align"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "max_length"), "set_max_length", "get_max_length"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "max_length", PROPERTY_HINT_RANGE, "0,1000,1,or_greater"), "set_max_length", "get_max_length"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "editable"), "set_editable", "is_editable"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "secret"), "set_secret", "is_secret"); ADD_PROPERTY(PropertyInfo(Variant::STRING, "secret_character"), "set_secret_character", "get_secret_character"); @@ -1881,7 +1885,7 @@ void LineEdit::_bind_methods() { ADD_GROUP("Caret", "caret_"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "caret_blink"), "cursor_set_blink_enabled", "cursor_get_blink_enabled"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "caret_blink_speed", PROPERTY_HINT_RANGE, "0.1,10,0.01"), "cursor_set_blink_speed", "cursor_get_blink_speed"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "caret_position"), "set_cursor_position", "get_cursor_position"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "caret_position", PROPERTY_HINT_RANGE, "0,1000,1,or_greater"), "set_cursor_position", "get_cursor_position"); } LineEdit::LineEdit() { diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp index 7aa94a778d8..408d193ccf4 100644 --- a/scene/gui/text_edit.cpp +++ b/scene/gui/text_edit.cpp @@ -5040,14 +5040,6 @@ bool TextEdit::is_wrap_enabled() const { return wrap_enabled; } -void TextEdit::set_max_chars(int p_max_chars) { - max_chars = p_max_chars; -} - -int TextEdit::get_max_chars() const { - return max_chars; -} - void TextEdit::_reset_caret_blink_timer() { if (caret_blink_enabled) { draw_caret = true; @@ -7216,7 +7208,6 @@ TextEdit::TextEdit() { draw_spaces = false; override_selected_font_color = false; draw_caret = true; - max_chars = 0; clear(); wrap_enabled = false; wrap_at = 0; diff --git a/scene/gui/text_edit.h b/scene/gui/text_edit.h index 01c167d2656..f73dea0d8ed 100644 --- a/scene/gui/text_edit.h +++ b/scene/gui/text_edit.h @@ -336,7 +336,6 @@ private: uint32_t version; uint32_t saved_version; - int max_chars; bool readonly; bool syntax_coloring; bool indent_using_spaces; @@ -670,9 +669,6 @@ public: void set_readonly(bool p_readonly); bool is_readonly() const; - void set_max_chars(int p_max_chars); - int get_max_chars() const; - void set_wrap_enabled(bool p_wrap_enabled); bool is_wrap_enabled() const;