From 0ffacff998476b3947deeebb3e63a3f4cd942598 Mon Sep 17 00:00:00 2001 From: ConteZero Date: Thu, 28 Oct 2021 16:48:17 +0200 Subject: [PATCH] [3.x] Add option to make selection unique --- doc/classes/LineEdit.xml | 3 +++ doc/classes/RichTextLabel.xml | 3 +++ doc/classes/TextEdit.xml | 3 +++ editor/code_editor.cpp | 1 + scene/gui/line_edit.cpp | 18 ++++++++++++++++++ scene/gui/line_edit.h | 4 ++++ scene/gui/rich_text_label.cpp | 26 +++++++++++++++++++++++++- scene/gui/rich_text_label.h | 3 +++ scene/gui/text_edit.cpp | 21 +++++++++++++++++++++ scene/gui/text_edit.h | 4 ++++ 10 files changed, 85 insertions(+), 1 deletion(-) diff --git a/doc/classes/LineEdit.xml b/doc/classes/LineEdit.xml index 3c43738aea76..1b02ea02f2cf 100644 --- a/doc/classes/LineEdit.xml +++ b/doc/classes/LineEdit.xml @@ -121,6 +121,9 @@ If [code]true[/code], the context menu will appear when right-clicked. + + If [code]true[/code], the selected text will be deselected when focus is lost. + If [code]false[/code], existing text cannot be modified and new text cannot be added. diff --git a/doc/classes/RichTextLabel.xml b/doc/classes/RichTextLabel.xml index 34ef2e51f26c..68ed028495a5 100644 --- a/doc/classes/RichTextLabel.xml +++ b/doc/classes/RichTextLabel.xml @@ -249,6 +249,9 @@ The currently installed custom effects. This is an array of [RichTextEffect]s. To add a custom effect, it's more convenient to use [method install_effect]. + + If [code]true[/code], the selected text will be deselected when focus is lost. + If [code]true[/code], the label's height will be automatically updated to fit its content. [b]Note:[/b] This property is used as a workaround to fix issues with [RichTextLabel] in [Container]s, but it's unreliable in some cases and will be removed in future versions. diff --git a/doc/classes/TextEdit.xml b/doc/classes/TextEdit.xml index 4add620c0760..0f0218da1d6a 100644 --- a/doc/classes/TextEdit.xml +++ b/doc/classes/TextEdit.xml @@ -492,6 +492,9 @@ If [code]true[/code], a right-click displays the context menu. + + If [code]true[/code], the selected text will be deselected when focus is lost. + If [code]true[/code], the "space" character will have a visible representation. diff --git a/editor/code_editor.cpp b/editor/code_editor.cpp index a6ca391976e9..265c6f1203fc 100644 --- a/editor/code_editor.cpp +++ b/editor/code_editor.cpp @@ -1710,6 +1710,7 @@ CodeTextEditor::CodeTextEditor() { text_editor->set_show_line_numbers(true); text_editor->set_brace_matching(true); text_editor->set_auto_indent(true); + text_editor->set_deselect_on_focus_loss_enabled(false); status_bar = memnew(HBoxContainer); add_child(status_bar); diff --git a/scene/gui/line_edit.cpp b/scene/gui/line_edit.cpp index fed8f5439201..3a509a130d95 100644 --- a/scene/gui/line_edit.cpp +++ b/scene/gui/line_edit.cpp @@ -1011,6 +1011,9 @@ void LineEdit::_notification(int p_what) { OS::get_singleton()->hide_virtual_keyboard(); } + if (deselect_on_focus_loss_enabled) { + deselect(); + } } break; case MainLoop::NOTIFICATION_OS_IME_UPDATE: { if (has_focus()) { @@ -1790,6 +1793,17 @@ bool LineEdit::is_selecting_enabled() const { return selecting_enabled; } +void LineEdit::set_deselect_on_focus_loss_enabled(const bool p_enabled) { + deselect_on_focus_loss_enabled = p_enabled; + if (p_enabled && selection.enabled && !has_focus()) { + deselect(); + } +} + +bool LineEdit::is_deselect_on_focus_loss_enabled() const { + return deselect_on_focus_loss_enabled; +} + void LineEdit::set_right_icon(const Ref &p_icon) { if (right_icon == p_icon) { return; @@ -1943,6 +1957,8 @@ void LineEdit::_bind_methods() { ClassDB::bind_method(D_METHOD("is_shortcut_keys_enabled"), &LineEdit::is_shortcut_keys_enabled); ClassDB::bind_method(D_METHOD("set_selecting_enabled", "enable"), &LineEdit::set_selecting_enabled); ClassDB::bind_method(D_METHOD("is_selecting_enabled"), &LineEdit::is_selecting_enabled); + ClassDB::bind_method(D_METHOD("set_deselect_on_focus_loss_enabled", "enable"), &LineEdit::set_deselect_on_focus_loss_enabled); + ClassDB::bind_method(D_METHOD("is_deselect_on_focus_loss_enabled"), &LineEdit::is_deselect_on_focus_loss_enabled); ClassDB::bind_method(D_METHOD("set_right_icon", "icon"), &LineEdit::set_right_icon); ClassDB::bind_method(D_METHOD("get_right_icon"), &LineEdit::get_right_icon); @@ -1976,6 +1992,7 @@ void LineEdit::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::BOOL, "clear_button_enabled"), "set_clear_button_enabled", "is_clear_button_enabled"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "shortcut_keys_enabled"), "set_shortcut_keys_enabled", "is_shortcut_keys_enabled"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "selecting_enabled"), "set_selecting_enabled", "is_selecting_enabled"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "deselect_on_focus_loss_enabled"), "set_deselect_on_focus_loss_enabled", "is_deselect_on_focus_loss_enabled"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "right_icon", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_right_icon", "get_right_icon"); ADD_GROUP("Placeholder", "placeholder_"); ADD_PROPERTY(PropertyInfo(Variant::STRING, "placeholder_text"), "set_placeholder", "get_placeholder"); @@ -2003,6 +2020,7 @@ LineEdit::LineEdit() { clear_button_status.pressing_inside = false; shortcut_keys_enabled = true; selecting_enabled = true; + deselect_on_focus_loss_enabled = true; undo_stack_pos = nullptr; _create_undo_state(); diff --git a/scene/gui/line_edit.h b/scene/gui/line_edit.h index 2cea72ed02bc..758b75fd33b3 100644 --- a/scene/gui/line_edit.h +++ b/scene/gui/line_edit.h @@ -75,6 +75,7 @@ class LineEdit : public Control { Point2 ime_selection; bool selecting_enabled; + bool deselect_on_focus_loss_enabled; bool context_menu_enabled; PopupMenu *menu; @@ -241,6 +242,9 @@ class LineEdit : public Control { void set_selecting_enabled(bool p_enabled); bool is_selecting_enabled() const; + void set_deselect_on_focus_loss_enabled(const bool p_enabled); + bool is_deselect_on_focus_loss_enabled() const; + void set_right_icon(const Ref &p_icon); Ref get_right_icon(); diff --git a/scene/gui/rich_text_label.cpp b/scene/gui/rich_text_label.cpp index 3e9271bbbcd2..6ef65bcbe9ff 100644 --- a/scene/gui/rich_text_label.cpp +++ b/scene/gui/rich_text_label.cpp @@ -1062,7 +1062,13 @@ void RichTextLabel::_notification(int p_what) { _update_fx(main, dt); update(); } - } + } break; + case NOTIFICATION_FOCUS_EXIT: { + if (deselect_on_focus_loss_enabled) { + selection.active = false; + update(); + } + } break; case Control::NOTIFICATION_DRAG_END: { selection.drag_attempt = false; } break; @@ -2531,6 +2537,14 @@ void RichTextLabel::set_selection_enabled(bool p_enabled) { } } +void RichTextLabel::set_deselect_on_focus_loss_enabled(const bool p_enabled) { + deselect_on_focus_loss_enabled = p_enabled; + if (p_enabled && selection.active && !has_focus()) { + selection.active = false; + update(); + } +} + Variant RichTextLabel::get_drag_data(const Point2 &p_point) { if (selection.drag_attempt && selection.enabled) { String t = get_selected_text(); @@ -2658,6 +2672,10 @@ bool RichTextLabel::is_selection_enabled() const { return selection.enabled; } +bool RichTextLabel::is_deselect_on_focus_loss_enabled() const { + return deselect_on_focus_loss_enabled; +} + void RichTextLabel::set_bbcode(const String &p_bbcode) { bbcode = p_bbcode; if (is_inside_tree() && use_bbcode) { @@ -2818,6 +2836,9 @@ void RichTextLabel::_bind_methods() { ClassDB::bind_method(D_METHOD("set_selection_enabled", "enabled"), &RichTextLabel::set_selection_enabled); ClassDB::bind_method(D_METHOD("is_selection_enabled"), &RichTextLabel::is_selection_enabled); + ClassDB::bind_method(D_METHOD("set_deselect_on_focus_loss_enabled", "enable"), &RichTextLabel::set_deselect_on_focus_loss_enabled); + ClassDB::bind_method(D_METHOD("is_deselect_on_focus_loss_enabled"), &RichTextLabel::is_deselect_on_focus_loss_enabled); + ClassDB::bind_method(D_METHOD("parse_bbcode", "bbcode"), &RichTextLabel::parse_bbcode); ClassDB::bind_method(D_METHOD("append_bbcode", "bbcode"), &RichTextLabel::append_bbcode); @@ -2865,6 +2886,8 @@ void RichTextLabel::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::BOOL, "selection_enabled"), "set_selection_enabled", "is_selection_enabled"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "override_selected_font_color"), "set_override_selected_font_color", "is_overriding_selected_font_color"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "deselect_on_focus_loss_enabled"), "set_deselect_on_focus_loss_enabled", "is_deselect_on_focus_loss_enabled"); + ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "custom_effects", PROPERTY_HINT_RESOURCE_TYPE, "17/17:RichTextEffect", (PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_SCRIPT_VARIABLE), "RichTextEffect"), "set_effects", "get_effects"); ADD_SIGNAL(MethodInfo("meta_clicked", PropertyInfo(Variant::NIL, "meta", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NIL_IS_VARIANT))); @@ -3057,6 +3080,7 @@ RichTextLabel::RichTextLabel() { selection.active = false; selection.enabled = false; selection.drag_attempt = false; + deselect_on_focus_loss_enabled = true; visible_characters = -1; percent_visible = 1; diff --git a/scene/gui/rich_text_label.h b/scene/gui/rich_text_label.h index a2d0989d77f0..c80e2b91076a 100644 --- a/scene/gui/rich_text_label.h +++ b/scene/gui/rich_text_label.h @@ -362,6 +362,7 @@ class RichTextLabel : public Control { }; Selection selection; + bool deselect_on_focus_loss_enabled; int visible_characters; float percent_visible; @@ -473,6 +474,8 @@ class RichTextLabel : public Control { bool is_selection_enabled() const; String get_selected_text(); void selection_copy(); + void set_deselect_on_focus_loss_enabled(const bool p_enabled); + bool is_deselect_on_focus_loss_enabled() const; Error parse_bbcode(const String &p_bbcode); Error append_bbcode(const String &p_bbcode); diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp index 0725e2b77431..db6842188a30 100644 --- a/scene/gui/text_edit.cpp +++ b/scene/gui/text_edit.cpp @@ -1889,6 +1889,10 @@ void TextEdit::_notification(int p_what) { if (OS::get_singleton()->has_virtual_keyboard() && virtual_keyboard_enabled) { OS::get_singleton()->hide_virtual_keyboard(); } + + if (deselect_on_focus_loss_enabled) { + deselect(); + } } break; case MainLoop::NOTIFICATION_OS_IME_UPDATE: { if (has_focus()) { @@ -1916,6 +1920,8 @@ void TextEdit::_notification(int p_what) { selection.active = false; selection.selecting_mode = Selection::MODE_NONE; update(); + } else if (deselect_on_focus_loss_enabled) { + deselect(); } } } else { @@ -7307,6 +7313,17 @@ bool TextEdit::is_selecting_enabled() const { return selecting_enabled; } +void TextEdit::set_deselect_on_focus_loss_enabled(const bool p_enabled) { + deselect_on_focus_loss_enabled = p_enabled; + if (p_enabled && selection.active && !has_focus()) { + deselect(); + } +} + +bool TextEdit::is_deselect_on_focus_loss_enabled() const { + return deselect_on_focus_loss_enabled; +} + bool TextEdit::is_shortcut_keys_enabled() const { return shortcut_keys_enabled; } @@ -7415,6 +7432,8 @@ void TextEdit::_bind_methods() { ClassDB::bind_method(D_METHOD("is_virtual_keyboard_enabled"), &TextEdit::is_virtual_keyboard_enabled); ClassDB::bind_method(D_METHOD("set_selecting_enabled", "enable"), &TextEdit::set_selecting_enabled); ClassDB::bind_method(D_METHOD("is_selecting_enabled"), &TextEdit::is_selecting_enabled); + ClassDB::bind_method(D_METHOD("set_deselect_on_focus_loss_enabled", "enable"), &TextEdit::set_deselect_on_focus_loss_enabled); + ClassDB::bind_method(D_METHOD("is_deselect_on_focus_loss_enabled"), &TextEdit::is_deselect_on_focus_loss_enabled); ClassDB::bind_method(D_METHOD("is_line_set_as_safe", "line"), &TextEdit::is_line_set_as_safe); ClassDB::bind_method(D_METHOD("set_line_as_safe", "line", "safe"), &TextEdit::set_line_as_safe); ClassDB::bind_method(D_METHOD("is_line_set_as_bookmark", "line"), &TextEdit::is_line_set_as_bookmark); @@ -7527,6 +7546,7 @@ void TextEdit::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::BOOL, "shortcut_keys_enabled"), "set_shortcut_keys_enabled", "is_shortcut_keys_enabled"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "virtual_keyboard_enabled"), "set_virtual_keyboard_enabled", "is_virtual_keyboard_enabled"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "selecting_enabled"), "set_selecting_enabled", "is_selecting_enabled"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "deselect_on_focus_loss_enabled"), "set_deselect_on_focus_loss_enabled", "is_deselect_on_focus_loss_enabled"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "smooth_scrolling"), "set_smooth_scroll_enable", "is_smooth_scroll_enabled"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "v_scroll_speed"), "set_v_scroll_speed", "get_v_scroll_speed"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "hiding_enabled"), "set_hiding_enabled", "is_hiding_enabled"); @@ -7692,6 +7712,7 @@ TextEdit::TextEdit() { minimap_line_spacing = 1; selecting_enabled = true; + deselect_on_focus_loss_enabled = true; context_menu_enabled = true; shortcut_keys_enabled = true; menu = memnew(PopupMenu); diff --git a/scene/gui/text_edit.h b/scene/gui/text_edit.h index 9ac751601be1..8980ab79c07a 100644 --- a/scene/gui/text_edit.h +++ b/scene/gui/text_edit.h @@ -437,6 +437,7 @@ class TextEdit : public Control { int search_result_col; bool selecting_enabled; + bool deselect_on_focus_loss_enabled; bool context_menu_enabled; bool shortcut_keys_enabled; @@ -854,6 +855,9 @@ class TextEdit : public Control { void set_selecting_enabled(bool p_enabled); bool is_selecting_enabled() const; + void set_deselect_on_focus_loss_enabled(const bool p_enabled); + bool is_deselect_on_focus_loss_enabled() const; + void set_shortcut_keys_enabled(bool p_enabled); bool is_shortcut_keys_enabled() const;