summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJuan Linietsky <reduzio@gmail.com>2016-06-27 09:59:43 -0300
committerJuan Linietsky <reduzio@gmail.com>2016-06-27 10:00:36 -0300
commit47d6cc08bbd745d63829e02ae408c4ce09ce1299 (patch)
tree3929118695e9f77356b916362bd2214d82d4cc80
parent2c59f778850dc4450481680e859efd66660c9119 (diff)
Properly deliver localized coordinates when passing gui events through parents, closes #4215
-rw-r--r--core/os/input_event.cpp59
-rw-r--r--core/os/input_event.h4
-rw-r--r--scene/2d/canvas_item.cpp56
-rw-r--r--scene/main/viewport.cpp19
4 files changed, 74 insertions, 64 deletions
diff --git a/core/os/input_event.cpp b/core/os/input_event.cpp
index 2d47645a66..8c79657c64 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 0588374790..1c4f1dcf96 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 <reduzio@gmail.com>
*/
@@ -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 21a3ecef32..bc5bff3b8e 100644
--- a/scene/2d/canvas_item.cpp
+++ b/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;
}
diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp
index 3c52af1c1e..76af81c325 100644
--- a/scene/main/viewport.cpp
+++ b/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();
}