Prechádzať zdrojové kódy

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

Fredia Huya-Kouadio 2 rokov pred
rodič
commit
b28bcb4cfc
2 zmenil súbory, kde vykonal 18 pridanie a 5 odobranie
  1. 17 5
      scene/main/viewport.cpp
  2. 1 0
      scene/main/viewport.h

+ 17 - 5
scene/main/viewport.cpp

@@ -2309,9 +2309,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)) {
@@ -2331,14 +2333,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;
 		}
 	}
@@ -2370,7 +2380,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());
 		}

+ 1 - 0
scene/main/viewport.h

@@ -296,6 +296,7 @@ private:
 
 		bool key_event_accepted;
 		bool mouse_in_window;
+		Map<int, ObjectID> touch_focus;
 		Control *mouse_focus;
 		Control *last_mouse_focus;
 		Control *mouse_click_grabber;