瀏覽代碼

Properly deliver localized coordinates when passing gui events through parents, closes #4215

Juan Linietsky 9 年之前
父節點
當前提交
47d6cc08bb
共有 4 個文件被更改,包括 74 次插入64 次删除
  1. 59 0
      core/os/input_event.cpp
  2. 3 1
      core/os/input_event.h
  3. 1 55
      scene/2d/canvas_item.cpp
  4. 11 8
      scene/main/viewport.cpp

+ 59 - 0
core/os/input_event.cpp

@@ -199,3 +199,62 @@ uint32_t InputEventKey::get_scancode_with_modifiers() const {
 	return sc;
 
 }
+
+InputEvent InputEvent::xform_by(const Matrix32& p_xform) const {
+
+
+	InputEvent ev=*this;
+
+	switch(ev.type) {
+
+		case InputEvent::MOUSE_BUTTON: {
+
+			Vector2 g = p_xform.xform(Vector2(ev.mouse_button.global_x,ev.mouse_button.global_y));
+			Vector2 l = p_xform.xform(Vector2(ev.mouse_button.x,ev.mouse_button.y));
+			ev.mouse_button.x=l.x;
+			ev.mouse_button.y=l.y;
+			ev.mouse_button.global_x=g.x;
+			ev.mouse_button.global_y=g.y;
+
+		} break;
+		case InputEvent::MOUSE_MOTION: {
+
+			Vector2 g = p_xform.xform(Vector2(ev.mouse_motion.global_x,ev.mouse_motion.global_y));
+			Vector2 l = p_xform.xform(Vector2(ev.mouse_motion.x,ev.mouse_motion.y));
+			Vector2 r = p_xform.basis_xform(Vector2(ev.mouse_motion.relative_x,ev.mouse_motion.relative_y));
+			Vector2 s = p_xform.basis_xform(Vector2(ev.mouse_motion.speed_x,ev.mouse_motion.speed_y));
+			ev.mouse_motion.x=l.x;
+			ev.mouse_motion.y=l.y;
+			ev.mouse_motion.global_x=g.x;
+			ev.mouse_motion.global_y=g.y;
+			ev.mouse_motion.relative_x=r.x;
+			ev.mouse_motion.relative_y=r.y;
+			ev.mouse_motion.speed_x=s.x;
+			ev.mouse_motion.speed_y=s.y;
+
+		} break;
+		case InputEvent::SCREEN_TOUCH: {
+
+
+			Vector2 t = p_xform.xform(Vector2(ev.screen_touch.x,ev.screen_touch.y));
+			ev.screen_touch.x=t.x;
+			ev.screen_touch.y=t.y;
+
+		} break;
+		case InputEvent::SCREEN_DRAG: {
+
+
+			Vector2 t = p_xform.xform(Vector2(ev.screen_drag.x,ev.screen_drag.y));
+			Vector2 r = p_xform.basis_xform(Vector2(ev.screen_drag.relative_x,ev.screen_drag.relative_y));
+			Vector2 s = p_xform.basis_xform(Vector2(ev.screen_drag.speed_x,ev.screen_drag.speed_y));
+			ev.screen_drag.x=t.x;
+			ev.screen_drag.y=t.y;
+			ev.screen_drag.relative_x=r.x;
+			ev.screen_drag.relative_y=r.y;
+			ev.screen_drag.speed_x=s.x;
+			ev.screen_drag.speed_y=s.y;
+		} break;
+	}
+
+	return ev;
+}

+ 3 - 1
core/os/input_event.h

@@ -33,7 +33,7 @@
 #include "typedefs.h"
 #include "os/copymem.h"
 #include "ustring.h"
-
+#include "math_2d.h"
 /**
 	@author Juan Linietsky <[email protected]>
 */
@@ -297,6 +297,8 @@ struct InputEvent {
 	bool is_echo() const;
 	void set_as_action(const String& p_action, bool p_pressed);
 
+
+	InputEvent xform_by(const Matrix32& p_xform) const;
 	bool operator==(const InputEvent &p_event) const;
 	operator String() const;
 	InputEvent() { zeromem(this,sizeof(InputEvent)); }

+ 1 - 55
scene/2d/canvas_item.cpp

@@ -953,62 +953,8 @@ InputEvent CanvasItem::make_input_local(const InputEvent& p_event) const {
 
 	ERR_FAIL_COND_V(!is_inside_tree(),p_event);
 
-	InputEvent ev = p_event;
+	return p_event.xform_by( (get_canvas_transform() * get_global_transform()).affine_inverse() );
 
-	Matrix32 local_matrix = (get_canvas_transform() * get_global_transform()).affine_inverse();
-
-	switch(ev.type) {
-
-		case InputEvent::MOUSE_BUTTON: {
-
-			Vector2 g = local_matrix.xform(Vector2(ev.mouse_button.global_x,ev.mouse_button.global_y));
-			Vector2 l = local_matrix.xform(Vector2(ev.mouse_button.x,ev.mouse_button.y));
-			ev.mouse_button.x=l.x;
-			ev.mouse_button.y=l.y;
-			ev.mouse_button.global_x=g.x;
-			ev.mouse_button.global_y=g.y;
-
-		} break;
-		case InputEvent::MOUSE_MOTION: {
-
-			Vector2 g = local_matrix.xform(Vector2(ev.mouse_motion.global_x,ev.mouse_motion.global_y));
-			Vector2 l = local_matrix.xform(Vector2(ev.mouse_motion.x,ev.mouse_motion.y));
-			Vector2 r = local_matrix.basis_xform(Vector2(ev.mouse_motion.relative_x,ev.mouse_motion.relative_y));
-			Vector2 s = local_matrix.basis_xform(Vector2(ev.mouse_motion.speed_x,ev.mouse_motion.speed_y));
-			ev.mouse_motion.x=l.x;
-			ev.mouse_motion.y=l.y;
-			ev.mouse_motion.global_x=g.x;
-			ev.mouse_motion.global_y=g.y;
-			ev.mouse_motion.relative_x=r.x;
-			ev.mouse_motion.relative_y=r.y;
-			ev.mouse_motion.speed_x=s.x;
-			ev.mouse_motion.speed_y=s.y;
-
-		} break;
-		case InputEvent::SCREEN_TOUCH: {
-
-
-			Vector2 t = local_matrix.xform(Vector2(ev.screen_touch.x,ev.screen_touch.y));
-			ev.screen_touch.x=t.x;
-			ev.screen_touch.y=t.y;
-
-		} break;
-		case InputEvent::SCREEN_DRAG: {
-
-
-			Vector2 t = local_matrix.xform(Vector2(ev.screen_drag.x,ev.screen_drag.y));
-			Vector2 r = local_matrix.basis_xform(Vector2(ev.screen_drag.relative_x,ev.screen_drag.relative_y));
-			Vector2 s = local_matrix.basis_xform(Vector2(ev.screen_drag.speed_x,ev.screen_drag.speed_y));
-			ev.screen_drag.x=t.x;
-			ev.screen_drag.y=t.y;
-			ev.screen_drag.relative_x=r.x;
-			ev.screen_drag.relative_y=r.y;
-			ev.screen_drag.speed_x=s.x;
-			ev.screen_drag.speed_y=s.y;
-		} break;
-	}
-
-	return ev;
 }
 
 

+ 11 - 8
scene/main/viewport.cpp

@@ -1575,35 +1575,38 @@ void Viewport::_gui_call_input(Control *p_control,const InputEvent& p_input) {
 //	_block();
 
 
+	InputEvent ev = p_input;
+
 	//mouse wheel events can't be stopped
-	bool cant_stop_me_now = (p_input.type==InputEvent::MOUSE_BUTTON &&
-				 (p_input.mouse_button.button_index==BUTTON_WHEEL_DOWN ||
-				  p_input.mouse_button.button_index==BUTTON_WHEEL_UP ||
-				  p_input.mouse_button.button_index==BUTTON_WHEEL_LEFT ||
-				  p_input.mouse_button.button_index==BUTTON_WHEEL_RIGHT ) );
+	bool cant_stop_me_now = (ev.type==InputEvent::MOUSE_BUTTON &&
+				 (ev.mouse_button.button_index==BUTTON_WHEEL_DOWN ||
+				  ev.mouse_button.button_index==BUTTON_WHEEL_UP ||
+				  ev.mouse_button.button_index==BUTTON_WHEEL_LEFT ||
+				  ev.mouse_button.button_index==BUTTON_WHEEL_RIGHT ) );
 
 	CanvasItem *ci=p_control;
 	while(ci) {
 
 		Control *control = ci->cast_to<Control>();
 		if (control) {
-			control->call_multilevel(SceneStringNames::get_singleton()->_input_event,p_input);
+			control->call_multilevel(SceneStringNames::get_singleton()->_input_event,ev);
 			if (gui.key_event_accepted)
 				break;
 			if (!control->is_inside_tree())
 				break;
-			control->emit_signal(SceneStringNames::get_singleton()->input_event,p_input);
+			control->emit_signal(SceneStringNames::get_singleton()->input_event,ev);
 			if (!control->is_inside_tree() || control->is_set_as_toplevel())
 				break;
 			if (gui.key_event_accepted)
 				break;
-			if (!cant_stop_me_now && control->data.stop_mouse && (p_input.type==InputEvent::MOUSE_BUTTON || p_input.type==InputEvent::MOUSE_MOTION))
+			if (!cant_stop_me_now && control->data.stop_mouse && (ev.type==InputEvent::MOUSE_BUTTON || ev.type==InputEvent::MOUSE_MOTION))
 				break;
 		}
 
 		if (ci->is_set_as_toplevel())
 			break;
 
+		ev=ev.xform_by(ci->get_transform()); //transform event upwards
 		ci=ci->get_parent_item();
 	}