From 6813c8902157c0afe37c5c7892bb83b78a623d01 Mon Sep 17 00:00:00 2001 From: Juan Linietsky Date: Mon, 27 Jun 2016 09:59:43 -0300 Subject: [PATCH] Properly deliver localized coordinates when passing gui events through parents, closes #4215 (cherry picked from commit 47d6cc08bbd745d63829e02ae408c4ce09ce1299) --- core/os/input_event.cpp | 59 ++++++++++++++++++++++++++++++++++++++++ core/os/input_event.h | 4 ++- scene/2d/canvas_item.cpp | 56 +------------------------------------- scene/main/viewport.cpp | 19 +++++++------ 4 files changed, 74 insertions(+), 64 deletions(-) diff --git a/core/os/input_event.cpp b/core/os/input_event.cpp index 2d47645a66c..8c79657c641 100644 --- a/core/os/input_event.cpp +++ b/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; +} diff --git a/core/os/input_event.h b/core/os/input_event.h index 0588374790e..1c4f1dcf96c 100644 --- a/core/os/input_event.h +++ b/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 */ @@ -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)); } diff --git a/scene/2d/canvas_item.cpp b/scene/2d/canvas_item.cpp index 7d60f90e82b..d280b3ab276 100644 --- a/scene/2d/canvas_item.cpp +++ b/scene/2d/canvas_item.cpp @@ -959,62 +959,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; } diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp index 344478e48cd..d99aeb1d4b2 100644 --- a/scene/main/viewport.cpp +++ b/scene/main/viewport.cpp @@ -1482,35 +1482,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(); 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(); }