Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add drag'n'drop text option for LineEdit and RichTextLabel #79563

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions doc/classes/LineEdit.xml
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,9 @@
<member name="deselect_on_focus_loss_enabled" type="bool" setter="set_deselect_on_focus_loss_enabled" getter="is_deselect_on_focus_loss_enabled" default="true">
If [code]true[/code], the selected text will be deselected when focus is lost.
</member>
<member name="drag_and_drop_selection_enabled" type="bool" setter="set_drag_and_drop_selection_enabled" getter="is_drag_and_drop_selection_enabled" default="true">
If [code]true[/code], allow drag and drop of selected text.
</member>
<member name="draw_control_chars" type="bool" setter="set_draw_control_chars" getter="get_draw_control_chars" default="false">
If [code]true[/code], control characters are displayed.
</member>
Expand Down
3 changes: 3 additions & 0 deletions doc/classes/RichTextLabel.xml
Original file line number Diff line number Diff line change
Expand Up @@ -551,6 +551,9 @@
<member name="deselect_on_focus_loss_enabled" type="bool" setter="set_deselect_on_focus_loss_enabled" getter="is_deselect_on_focus_loss_enabled" default="true">
If [code]true[/code], the selected text will be deselected when focus is lost.
</member>
<member name="drag_and_drop_selection_enabled" type="bool" setter="set_drag_and_drop_selection_enabled" getter="is_drag_and_drop_selection_enabled" default="true">
If [code]true[/code], allow drag and drop of selected text.
</member>
<member name="fit_content" type="bool" setter="set_fit_content" getter="is_fit_content_enabled" default="false">
If [code]true[/code], the label's minimum size will be automatically updated to fit its content, matching the behavior of [Label].
</member>
Expand Down
27 changes: 20 additions & 7 deletions scene/gui/line_edit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -341,13 +341,15 @@ void LineEdit::gui_input(const Ref<InputEvent> &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) {
KoBeWi marked this conversation as resolved.
Show resolved Hide resolved
selection.drag_attempt = true;
} else {
deselect();
selection.start_column = caret_column;
selection.creating = true;
}
}
}

Expand Down Expand Up @@ -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<Texture2D> &p_icon) {
if (right_icon == p_icon) {
return;
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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");
Expand Down
4 changes: 4 additions & 0 deletions scene/gui/line_edit.h
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ class LineEdit : public Control {

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;
Expand Down Expand Up @@ -367,6 +368,9 @@ class LineEdit : public Control {
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<Texture2D> &p_icon);
Ref<Texture2D> get_right_icon();

Expand Down
14 changes: 13 additions & 1 deletion scene/gui/rich_text_label.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1954,7 +1954,7 @@ void RichTextLabel::gui_input(const Ref<InputEvent> &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 {
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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);

Expand Down Expand Up @@ -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.
Expand Down
6 changes: 6 additions & 0 deletions scene/gui/rich_text_label.h
Original file line number Diff line number Diff line change
Expand Up @@ -468,6 +468,7 @@ class RichTextLabel : public Control {

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;
Expand Down Expand Up @@ -699,8 +700,13 @@ class RichTextLabel : public Control {
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;
Expand Down
Loading