From d85caf2c71ab0b8f95a268dbadb66f2a4627871b Mon Sep 17 00:00:00 2001 From: Relintai Date: Mon, 25 Jul 2022 19:46:09 +0200 Subject: [PATCH] Ported: [3.x] Add option to make selection unique - ConteZero https://github.com/godotengine/godot/commit/0ffacff998476b3947deeebb3e63a3f4cd942598 --- doc/classes/LineEdit.xml | 3 +++ doc/classes/RichTextLabel.xml | 3 +++ doc/classes/TextEdit.xml | 3 +++ editor/code_editor.cpp | 17 +++++++++-------- editor/editor_log.cpp | 2 +- scene/gui/line_edit.cpp | 19 +++++++++++++++++++ scene/gui/line_edit.h | 4 ++++ scene/gui/rich_text_label.cpp | 26 +++++++++++++++++++++++++- scene/gui/rich_text_label.h | 4 ++++ scene/gui/text_edit.cpp | 21 +++++++++++++++++++++ scene/gui/text_edit.h | 4 ++++ 11 files changed, 96 insertions(+), 10 deletions(-) diff --git a/doc/classes/LineEdit.xml b/doc/classes/LineEdit.xml index 8ac44a195..57a241b2b 100644 --- a/doc/classes/LineEdit.xml +++ b/doc/classes/LineEdit.xml @@ -139,6 +139,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 34ef2e51f..68ed02849 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 bf8cc77e8..8dfcf39aa 100644 --- a/doc/classes/TextEdit.xml +++ b/doc/classes/TextEdit.xml @@ -485,6 +485,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 88547f485..45ae0de52 100644 --- a/editor/code_editor.cpp +++ b/editor/code_editor.cpp @@ -30,26 +30,24 @@ #include "code_editor.h" -#include "core/os/input.h" -#include "core/os/keyboard.h" -#include "core/string_builder.h" -#include "editor/editor_scale.h" -#include "editor_node.h" -#include "editor_settings.h" -#include "scene/gui/texture_button.h" -#include "scene/resources/dynamic_font.h" #include "core/array.h" #include "core/class_db.h" #include "core/dictionary.h" #include "core/math/math_funcs.h" #include "core/math/vector2.h" +#include "core/os/input.h" #include "core/os/input_event.h" +#include "core/os/keyboard.h" #include "core/os/memory.h" #include "core/resource.h" #include "core/script_language.h" +#include "core/string_builder.h" #include "core/typedefs.h" #include "core/vector.h" +#include "editor/editor_scale.h" #include "editor/plugins/script_editor_plugin.h" +#include "editor_node.h" +#include "editor_settings.h" #include "scene/2d/canvas_item.h" #include "scene/gui/button.h" #include "scene/gui/check_box.h" @@ -59,9 +57,11 @@ #include "scene/gui/scroll_container.h" #include "scene/gui/shortcut.h" #include "scene/gui/text_edit.h" +#include "scene/gui/texture_button.h" #include "scene/gui/tool_button.h" #include "scene/main/node.h" #include "scene/main/timer.h" +#include "scene/resources/dynamic_font.h" #include "scene/resources/font.h" #include "scene/resources/texture.h" @@ -1735,6 +1735,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/editor/editor_log.cpp b/editor/editor_log.cpp index 61fc55c02..d8b14247a 100644 --- a/editor/editor_log.cpp +++ b/editor/editor_log.cpp @@ -190,7 +190,7 @@ EditorLog::EditorLog() { log->set_custom_minimum_size(Size2(0, 180) * EDSCALE); log->set_v_size_flags(SIZE_EXPAND_FILL); log->set_h_size_flags(SIZE_EXPAND_FILL); - //log->set_deselect_on_focus_loss_enabled(false); + log->set_deselect_on_focus_loss_enabled(false); vb->add_child(log); add_message(VERSION_FULL_NAME " (c) 2007-2022 Juan Linietsky, Ariel Manzur & Godot Contributors."); diff --git a/scene/gui/line_edit.cpp b/scene/gui/line_edit.cpp index 170ff8bee..d762836bb 100644 --- a/scene/gui/line_edit.cpp +++ b/scene/gui/line_edit.cpp @@ -980,6 +980,10 @@ 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()) { @@ -1748,6 +1752,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; @@ -1904,6 +1919,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); @@ -1937,6 +1954,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"); @@ -1964,6 +1982,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 90c2a7dfd..b27e432df 100644 --- a/scene/gui/line_edit.h +++ b/scene/gui/line_edit.h @@ -75,6 +75,7 @@ private: Point2 ime_selection; bool selecting_enabled; + bool deselect_on_focus_loss_enabled; bool context_menu_enabled; PopupMenu *menu; @@ -241,6 +242,9 @@ public: 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 1f1ce1007..1cdb1c75b 100644 --- a/scene/gui/rich_text_label.cpp +++ b/scene/gui/rich_text_label.cpp @@ -1064,7 +1064,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; } } @@ -2501,6 +2507,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(); + } +} + bool RichTextLabel::search(const String &p_string, bool p_from_selection, bool p_search_previous) { ERR_FAIL_COND_V(!selection.enabled, false); Item *it = main; @@ -2612,6 +2626,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) { @@ -2772,6 +2790,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); @@ -2819,6 +2840,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))); @@ -3010,6 +3033,7 @@ RichTextLabel::RichTextLabel() { selection.click = nullptr; selection.active = false; selection.enabled = 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 30c642470..42d62baec 100644 --- a/scene/gui/rich_text_label.h +++ b/scene/gui/rich_text_label.h @@ -363,6 +363,7 @@ private: }; Selection selection; + bool deselect_on_focus_loss_enabled; int visible_characters; float percent_visible; @@ -473,6 +474,9 @@ public: 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 858a7a26a..90e0377e6 100644 --- a/scene/gui/text_edit.cpp +++ b/scene/gui/text_edit.cpp @@ -1889,12 +1889,18 @@ 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()) { ime_text = OS::get_singleton()->get_ime_text(); ime_selection = OS::get_singleton()->get_ime_selection(); update(); + } else if (deselect_on_focus_loss_enabled) { + deselect(); } } break; } @@ -7153,6 +7159,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; } @@ -7261,6 +7278,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); @@ -7372,6 +7391,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"); @@ -7537,6 +7557,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 d2ad1abb2..64984af2f 100644 --- a/scene/gui/text_edit.h +++ b/scene/gui/text_edit.h @@ -434,6 +434,7 @@ private: int search_result_col; bool selecting_enabled; + bool deselect_on_focus_loss_enabled; bool context_menu_enabled; bool shortcut_keys_enabled; @@ -844,6 +845,9 @@ public: 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;