Properly deliver localized coordinates when passing gui events through parents, closes #4215
This commit is contained in:
parent
2c59f77885
commit
47d6cc08bb
|
@ -199,3 +199,62 @@ uint32_t InputEventKey::get_scancode_with_modifiers() const {
|
||||||
return sc;
|
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;
|
||||||
|
}
|
||||||
|
|
|
@ -33,7 +33,7 @@
|
||||||
#include "typedefs.h"
|
#include "typedefs.h"
|
||||||
#include "os/copymem.h"
|
#include "os/copymem.h"
|
||||||
#include "ustring.h"
|
#include "ustring.h"
|
||||||
|
#include "math_2d.h"
|
||||||
/**
|
/**
|
||||||
@author Juan Linietsky <reduzio@gmail.com>
|
@author Juan Linietsky <reduzio@gmail.com>
|
||||||
*/
|
*/
|
||||||
|
@ -297,6 +297,8 @@ struct InputEvent {
|
||||||
bool is_echo() const;
|
bool is_echo() const;
|
||||||
void set_as_action(const String& p_action, bool p_pressed);
|
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;
|
bool operator==(const InputEvent &p_event) const;
|
||||||
operator String() const;
|
operator String() const;
|
||||||
InputEvent() { zeromem(this,sizeof(InputEvent)); }
|
InputEvent() { zeromem(this,sizeof(InputEvent)); }
|
||||||
|
|
|
@ -953,62 +953,8 @@ InputEvent CanvasItem::make_input_local(const InputEvent& p_event) const {
|
||||||
|
|
||||||
ERR_FAIL_COND_V(!is_inside_tree(),p_event);
|
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1575,35 +1575,38 @@ void Viewport::_gui_call_input(Control *p_control,const InputEvent& p_input) {
|
||||||
// _block();
|
// _block();
|
||||||
|
|
||||||
|
|
||||||
|
InputEvent ev = p_input;
|
||||||
|
|
||||||
//mouse wheel events can't be stopped
|
//mouse wheel events can't be stopped
|
||||||
bool cant_stop_me_now = (p_input.type==InputEvent::MOUSE_BUTTON &&
|
bool cant_stop_me_now = (ev.type==InputEvent::MOUSE_BUTTON &&
|
||||||
(p_input.mouse_button.button_index==BUTTON_WHEEL_DOWN ||
|
(ev.mouse_button.button_index==BUTTON_WHEEL_DOWN ||
|
||||||
p_input.mouse_button.button_index==BUTTON_WHEEL_UP ||
|
ev.mouse_button.button_index==BUTTON_WHEEL_UP ||
|
||||||
p_input.mouse_button.button_index==BUTTON_WHEEL_LEFT ||
|
ev.mouse_button.button_index==BUTTON_WHEEL_LEFT ||
|
||||||
p_input.mouse_button.button_index==BUTTON_WHEEL_RIGHT ) );
|
ev.mouse_button.button_index==BUTTON_WHEEL_RIGHT ) );
|
||||||
|
|
||||||
CanvasItem *ci=p_control;
|
CanvasItem *ci=p_control;
|
||||||
while(ci) {
|
while(ci) {
|
||||||
|
|
||||||
Control *control = ci->cast_to<Control>();
|
Control *control = ci->cast_to<Control>();
|
||||||
if (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)
|
if (gui.key_event_accepted)
|
||||||
break;
|
break;
|
||||||
if (!control->is_inside_tree())
|
if (!control->is_inside_tree())
|
||||||
break;
|
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())
|
if (!control->is_inside_tree() || control->is_set_as_toplevel())
|
||||||
break;
|
break;
|
||||||
if (gui.key_event_accepted)
|
if (gui.key_event_accepted)
|
||||||
break;
|
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;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ci->is_set_as_toplevel())
|
if (ci->is_set_as_toplevel())
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
ev=ev.xform_by(ci->get_transform()); //transform event upwards
|
||||||
ci=ci->get_parent_item();
|
ci=ci->get_parent_item();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue