From cfe98c57b9d93e962e03005e448fc05c968665f3 Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 16 Jul 2023 20:32:00 -0400 Subject: [PATCH] Add drag and drop option for line edit and rich text label --- doc/classes/LineEdit.xml | 3 +++ doc/classes/RichTextLabel.xml | 3 +++ scene/gui/line_edit.cpp | 27 ++++++++++++++++++++------- scene/gui/line_edit.h | 4 ++++ scene/gui/rich_text_label.cpp | 14 +++++++++++++- scene/gui/rich_text_label.h | 6 ++++++ 6 files changed, 49 insertions(+), 8 deletions(-) diff --git a/doc/classes/LineEdit.xml b/doc/classes/LineEdit.xml index cea0adbe0f7..f5cb2e32a28 100644 --- a/doc/classes/LineEdit.xml +++ b/doc/classes/LineEdit.xml @@ -210,6 +210,9 @@ If [code]true[/code], the selected text will be deselected when focus is lost. + + If [code]true[/code], allow drag and drop of selected text. + If [code]true[/code], control characters are displayed. diff --git a/doc/classes/RichTextLabel.xml b/doc/classes/RichTextLabel.xml index e2030f5927e..b951566707e 100644 --- a/doc/classes/RichTextLabel.xml +++ b/doc/classes/RichTextLabel.xml @@ -551,6 +551,9 @@ If [code]true[/code], the selected text will be deselected when focus is lost. + + If [code]true[/code], allow drag and drop of selected text. + If [code]true[/code], the label's minimum size will be automatically updated to fit its content, matching the behavior of [Label]. diff --git a/scene/gui/line_edit.cpp b/scene/gui/line_edit.cpp index a73e952eca7..42ee6cb0bcd 100644 --- a/scene/gui/line_edit.cpp +++ b/scene/gui/line_edit.cpp @@ -341,13 +341,15 @@ void LineEdit::gui_input(const Ref &p_event) { } selection.drag_attempt = false; - - if ((caret_column < selection.begin) || (caret_column > selection.end) || !selection.enabled) { - deselect(); - selection.start_column = caret_column; - selection.creating = true; - } else if (selection.enabled && !selection.double_click) { - selection.drag_attempt = true; + if (!selection.double_click) { + bool is_inside_sel = selection.enabled && caret_column >= selection.begin && caret_column <= selection.end; + if (drag_and_drop_selection_enabled && is_inside_sel) { + selection.drag_attempt = true; + } else { + deselect(); + selection.start_column = caret_column; + selection.creating = true; + } } } @@ -2224,6 +2226,14 @@ bool LineEdit::is_deselect_on_focus_loss_enabled() const { return deselect_on_focus_loss_enabled; } +void LineEdit::set_drag_and_drop_selection_enabled(const bool p_enabled) { + drag_and_drop_selection_enabled = p_enabled; +} + +bool LineEdit::is_drag_and_drop_selection_enabled() const { + return drag_and_drop_selection_enabled; +} + void LineEdit::set_right_icon(const Ref &p_icon) { if (right_icon == p_icon) { return; @@ -2570,6 +2580,8 @@ void LineEdit::_bind_methods() { 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_drag_and_drop_selection_enabled", "enable"), &LineEdit::set_drag_and_drop_selection_enabled); + ClassDB::bind_method(D_METHOD("is_drag_and_drop_selection_enabled"), &LineEdit::is_drag_and_drop_selection_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); ClassDB::bind_method(D_METHOD("set_flat", "enabled"), &LineEdit::set_flat); @@ -2638,6 +2650,7 @@ void LineEdit::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::BOOL, "middle_mouse_paste_enabled"), "set_middle_mouse_paste_enabled", "is_middle_mouse_paste_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, "drag_and_drop_selection_enabled"), "set_drag_and_drop_selection_enabled", "is_drag_and_drop_selection_enabled"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "right_icon", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_right_icon", "get_right_icon"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "flat"), "set_flat", "is_flat"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "draw_control_chars"), "set_draw_control_chars", "get_draw_control_chars"); diff --git a/scene/gui/line_edit.h b/scene/gui/line_edit.h index 8acb4896c55..dba81b7b502 100644 --- a/scene/gui/line_edit.h +++ b/scene/gui/line_edit.h @@ -106,6 +106,7 @@ private: bool selecting_enabled = true; bool deselect_on_focus_loss_enabled = true; + bool drag_and_drop_selection_enabled = true; bool context_menu_enabled = true; PopupMenu *menu = nullptr; @@ -367,6 +368,9 @@ public: void set_deselect_on_focus_loss_enabled(const bool p_enabled); bool is_deselect_on_focus_loss_enabled() const; + void set_drag_and_drop_selection_enabled(const bool p_enabled); + bool is_drag_and_drop_selection_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 7cd346056a7..f6bf619d6db 100644 --- a/scene/gui/rich_text_label.cpp +++ b/scene/gui/rich_text_label.cpp @@ -1954,7 +1954,7 @@ void RichTextLabel::gui_input(const Ref &p_event) { // Erase previous selection. if (selection.active) { - if (_is_click_inside_selection()) { + if (drag_and_drop_selection_enabled && _is_click_inside_selection()) { selection.drag_attempt = true; selection.click_item = nullptr; } else { @@ -5317,6 +5317,14 @@ bool RichTextLabel::is_deselect_on_focus_loss_enabled() const { return deselect_on_focus_loss_enabled; } +void RichTextLabel::set_drag_and_drop_selection_enabled(const bool p_enabled) { + drag_and_drop_selection_enabled = p_enabled; +} + +bool RichTextLabel::is_drag_and_drop_selection_enabled() const { + return drag_and_drop_selection_enabled; +} + int RichTextLabel::get_selection_from() const { if (!selection.active || !selection.enabled) { return -1; @@ -5647,6 +5655,9 @@ void RichTextLabel::_bind_methods() { 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("set_drag_and_drop_selection_enabled", "enable"), &RichTextLabel::set_drag_and_drop_selection_enabled); + ClassDB::bind_method(D_METHOD("is_drag_and_drop_selection_enabled"), &RichTextLabel::is_drag_and_drop_selection_enabled); + ClassDB::bind_method(D_METHOD("get_selection_from"), &RichTextLabel::get_selection_from); ClassDB::bind_method(D_METHOD("get_selection_to"), &RichTextLabel::get_selection_to); @@ -5736,6 +5747,7 @@ void RichTextLabel::_bind_methods() { ADD_GROUP("Text Selection", ""); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "selection_enabled"), "set_selection_enabled", "is_selection_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, "drag_and_drop_selection_enabled"), "set_drag_and_drop_selection_enabled", "is_drag_and_drop_selection_enabled"); ADD_GROUP("Displayed Text", ""); // Note: "visible_characters" and "visible_ratio" should be set after "text" to be correctly applied. diff --git a/scene/gui/rich_text_label.h b/scene/gui/rich_text_label.h index 30adf03f84c..46bf5641bc5 100644 --- a/scene/gui/rich_text_label.h +++ b/scene/gui/rich_text_label.h @@ -468,6 +468,7 @@ private: Selection selection; bool deselect_on_focus_loss_enabled = true; + bool drag_and_drop_selection_enabled = true; bool context_menu_enabled = false; bool shortcut_keys_enabled = true; @@ -699,8 +700,13 @@ public: String get_selected_text() const; void select_all(); void selection_copy(); + void set_deselect_on_focus_loss_enabled(const bool p_enabled); bool is_deselect_on_focus_loss_enabled() const; + + void set_drag_and_drop_selection_enabled(const bool p_enabled); + bool is_drag_and_drop_selection_enabled() const; + void deselect(); int get_pending_paragraphs() const;