Fix the logic used to route `InputEventScreenDrag` events to `Control` nodes.

(cherry picked from commit b28bcb4cfc)
This commit is contained in:
Fredia Huya-Kouadio 2022-10-20 10:35:37 -07:00 committed by Haoyu Qiu
parent b07bcf5592
commit 26012ed6b6
2 changed files with 18 additions and 5 deletions

View File

@ -2303,9 +2303,11 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
Ref<InputEventScreenTouch> touch_event = p_event;
if (touch_event.is_valid()) {
Size2 pos = touch_event->get_position();
const int touch_index = touch_event->get_index();
if (touch_event->is_pressed()) {
Control *over = _gui_find_control(pos);
if (over) {
gui.touch_focus[touch_index] = over->get_instance_id();
if (!gui.modal_stack.empty()) {
Control *top = gui.modal_stack.back()->get();
if (over != top && !top->is_a_parent_of(over)) {
@ -2325,14 +2327,22 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
set_input_as_handled();
return;
}
} else if (touch_event->get_index() == 0 && gui.last_mouse_focus) {
if (gui.last_mouse_focus->can_process()) {
} else {
ObjectID control_id = gui.touch_focus[touch_index];
Control *over = Object::cast_to<Control>(ObjectDB::get_instance(control_id));
if (over && over->can_process()) {
touch_event = touch_event->xformed_by(Transform2D()); //make a copy
touch_event->set_position(gui.focus_inv_xform.xform(pos));
if (over == gui.last_mouse_focus) {
pos = gui.focus_inv_xform.xform(pos);
} else {
pos = over->get_global_transform_with_canvas().affine_inverse().xform(pos);
}
touch_event->set_position(pos);
_gui_call_input(gui.last_mouse_focus, touch_event);
_gui_call_input(over, touch_event);
}
set_input_as_handled();
gui.touch_focus.erase(touch_index);
return;
}
}
@ -2364,7 +2374,9 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
Ref<InputEventScreenDrag> drag_event = p_event;
if (drag_event.is_valid()) {
Control *over = gui.mouse_focus;
const int drag_event_index = drag_event->get_index();
ObjectID control_id = gui.touch_focus[drag_event_index];
Control *over = Object::cast_to<Control>(ObjectDB::get_instance(control_id));
if (!over) {
over = _gui_find_control(drag_event->get_position());
}

View File

@ -295,6 +295,7 @@ private:
// info used when this is a window
bool key_event_accepted;
Map<int, ObjectID> touch_focus;
Control *mouse_focus;
Control *last_mouse_focus;
Control *mouse_click_grabber;