-
-
Notifications
You must be signed in to change notification settings - Fork 21.6k
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
Fix drag and drop on LineEdit #54339
Fix drag and drop on LineEdit #54339
Conversation
ea7742a
to
696583c
Compare
696583c
to
9593d15
Compare
Yes, you are right, I force-pushed a change that should fix undo/redo. |
9593d15
to
7a04245
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems ok, but core changes need additional review.
btw, the unreported issue fixed by this PR is actually a regression, because drag and drop works in 3.x (except undo/redo is broken).
7a04245
to
b9c65aa
Compare
Are you sure? I've tested in 3.3.4 and drag and drop in lineedit does not work for me, and this is confirmed by looking at the code, the
is never executed. |
I've added some lines of code to LineEdit::drop_data to handle the case where deselect_on_focus_loss_enabled is false. |
Well, I think we can call it the "Schrödinger's Drag and Drop", it works and doesn't work at the same time. |
scene/gui/line_edit.cpp
Outdated
delete_text(selection.begin, selection.end); | ||
deselect(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can call selection_delete()
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
if (b->is_shift_pressed()) { | ||
shift_selection_check_pre(true); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would it be worth checking drag_action
inside shift_selection_check_pre
so we don't have to special case it here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wouldn't moving the control inside shift_selection_check_pre cause unwanted side effects?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't do as this is the only call that is used for the mouse, though that does raise a good point, we should probably prevent any another input whilst dragging text.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, preventing other input while dragging will avoid unwanted behavior, but I believe this needs to be done in another pull request because it should be done in a generic way, not limited to just Lineedit.
scene/gui/line_edit.cpp
Outdated
selection.begin = caret_column - selected; | ||
selection.end = caret_column; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems as though the old code tried to persevere the selection, should this behaviour be kept?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've restored the previous behavior and I've also fixed a bug in the undo/redo code by adding a deselect()
scene/gui/line_edit.cpp
Outdated
set_caret_column(caret_column_tmp); | ||
insert_text_at_caret(p_data); | ||
} | ||
} else if (!deselect_on_focus_loss_enabled && selection.enabled && caret_column >= selection.begin && caret_column <= selection.end) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Doesn't selection.enabled
tell us if deselect_on_focus_loss_enabled
is enabled?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed
b9c65aa
to
9765e33
Compare
scene/gui/line_edit.cpp
Outdated
delete_text(selection.begin, selection.end); | ||
deselect(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can call selection_delete
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed
scene/gui/line_edit.cpp
Outdated
delete_text(selection.begin, selection.end); | ||
deselect(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can call selection_delete
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed
scene/gui/line_edit.cpp
Outdated
if (selecting_enabled) { | ||
selection.enabled = true; | ||
selection.begin = caret_column_tmp; | ||
selection.end = caret_column; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can call select()
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed
scene/gui/line_edit.cpp
Outdated
insert_text_at_caret(p_data); | ||
grab_focus(); | ||
} else { | ||
deselect(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can remove this call to deselect
as we're immediately selecting afterwords.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed
if (b->is_shift_pressed()) { | ||
shift_selection_check_pre(true); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't do as this is the only call that is used for the mouse, though that does raise a good point, we should probably prevent any another input whilst dragging text.
9765e33
to
272b48a
Compare
Be sure to check how it behaves with non |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Line edit changes look okay.
However, I'm not sure on the new NOTIFICATION
s, kind of makes NOTIFICATION_DRAG_END
redundant. We can also handle quite easily inside of LineEdit
rather then pushing up to viewport
, though I can see the use case for it.
Would need some other opinions on this.
scene/gui/line_edit.cpp
Outdated
} | ||
|
||
void LineEdit::drop_data(const Point2 &p_point, const Variant &p_data) { | ||
Control::drop_data(p_point, p_data); | ||
|
||
if (p_data.get_type() == Variant::STRING) { | ||
if (is_editable() && p_data.get_type() == Variant::STRING) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: Can invert this.
Indeed, I don't see much added value for those notifications, and changing the core like this requires thorougher design review than only ad-hoc LineEdit changes. See https://docs.godotengine.org/en/latest/community/contributing/best_practices_for_engine_contributors.html#prefer-local-solutions The two new notifications only serve to say "drag end with success" or "drag end with failure", and success or failure is determined by a method implemented in LineEdit. So LineEdit already knows if it's drag is a success or a failure, and can pass this information (e.g. via a member variable) to the existing |
I've not understood what you are suggesting when you talk about a member variable, you mean a member variable of Lineedit? |
As I've tried to explain in the previous comment I don't think it is possible to handle the drag and drop operation without using Viewport. |
I'll try to make it clearer with an example, suppose we have two LineEdit nodes LineEdit_A contains textA This is what happens during a drag and drop operation (only relevant method calls are shown):
|
272b48a
to
a70834e
Compare
An alternative solution, which already has a precedent in So we could add This way we don't have to touch notifications. |
At first I thought about using a getter, but then I chose to create the two new notifications because it seemed simpler to implement and easier for users to understand. If you think that the getter is a better choice I can modify the code to use it instead of notifications, in the end the thing that interests me most is to have a drag and drop functionality that works (especially for the 3.x branch which is what I use for my projects). |
a70834e
to
8d86ad9
Compare
@Paulb23 I've removed the notifications and added the getter as you suggested |
413915f
to
d1b2c75
Compare
d1b2c75
to
2b1787b
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good to me as far as Control
/Viewport
changes are concerned.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM.
Thanks! |
LineEdit contains the code to handle drag and drop but it never gets executed, I don't know if it's excluded on purpose or it's a bug.
I have improved the existing code to make it possible to cut and paste the selection (the current code only makes a copy).
I don't know if this is the best way to implement this functionality, but from my tests it works and with some tweaks it could be used for the TextEdit node as well.
Bugsquad edit: Fixes #54744.