diff options
Diffstat (limited to 'main/input_default.cpp')
| -rw-r--r-- | main/input_default.cpp | 64 |
1 files changed, 48 insertions, 16 deletions
diff --git a/main/input_default.cpp b/main/input_default.cpp index 4363fc1c88..b1084900d6 100644 --- a/main/input_default.cpp +++ b/main/input_default.cpp @@ -30,9 +30,9 @@ #include "input_default.h" -#include "default_controller_mappings.h" -#include "input_map.h" -#include "os/os.h" +#include "core/input_map.h" +#include "core/os/os.h" +#include "main/default_controller_mappings.h" #include "scene/resources/texture.h" #include "servers/visual_server.h" @@ -261,13 +261,17 @@ void InputDefault::parse_input_event(const Ref<InputEvent> &p_event) { void InputDefault::_parse_input_event_impl(const Ref<InputEvent> &p_event, bool p_is_emulated) { + // Notes on mouse-touch emulation: + // - Emulated mouse events are parsed, that is, re-routed to this method, so they make the same effects + // as true mouse events. The only difference is the situation is flagged as emulated so they are not + // emulated back to touch events in an endless loop. + // - Emulated touch events are handed right to the main loop (i.e., the SceneTree) because they don't + // require additional handling by this class. + _THREAD_SAFE_METHOD_ Ref<InputEventKey> k = p_event; if (k.is_valid() && !k->is_echo() && k->get_scancode() != 0) { - - //print_line(p_event); - if (k->is_pressed()) keys_pressed.insert(k->get_scancode()); else @@ -319,11 +323,21 @@ void InputDefault::_parse_input_event_impl(const Ref<InputEvent> &p_event, bool } } - if (emulate_mouse_from_touch) { + Ref<InputEventScreenTouch> st = p_event; - Ref<InputEventScreenTouch> st = p_event; + if (st.is_valid()) { + + if (st->is_pressed()) { + SpeedTrack &track = touch_speed_track[st->get_index()]; + track.reset(); + } else { + // Since a pointer index may not occur again (OSs may or may not reuse them), + // imperatively remove it from the map to keep no fossil entries in it + touch_speed_track.erase(st->get_index()); + } + + if (emulate_mouse_from_touch) { - if (st.is_valid()) { bool translate = false; if (st->is_pressed()) { if (mouse_from_touch_index == -1) { @@ -346,18 +360,26 @@ void InputDefault::_parse_input_event_impl(const Ref<InputEvent> &p_event, bool button_event->set_pressed(st->is_pressed()); button_event->set_button_index(BUTTON_LEFT); if (st->is_pressed()) { - button_event->set_button_mask(mouse_button_mask | (1 << BUTTON_LEFT - 1)); + button_event->set_button_mask(mouse_button_mask | (1 << (BUTTON_LEFT - 1))); } else { - button_event->set_button_mask(mouse_button_mask & ~(1 << BUTTON_LEFT - 1)); + button_event->set_button_mask(mouse_button_mask & ~(1 << (BUTTON_LEFT - 1))); } _parse_input_event_impl(button_event, true); } } + } + + Ref<InputEventScreenDrag> sd = p_event; + + if (sd.is_valid()) { + + SpeedTrack &track = touch_speed_track[sd->get_index()]; + track.update(sd->get_relative()); + sd->set_speed(track.speed); - Ref<InputEventScreenDrag> sd = p_event; + if (emulate_mouse_from_touch && sd->get_index() == mouse_from_touch_index) { - if (sd.is_valid() && sd->get_index() == mouse_from_touch_index) { Ref<InputEventMouseMotion> motion_event; motion_event.instance(); @@ -407,6 +429,7 @@ void InputDefault::_parse_input_event_impl(const Ref<InputEvent> &p_event, bool action.physics_frame = Engine::get_singleton()->get_physics_frames(); action.idle_frame = Engine::get_singleton()->get_idle_frames(); action.pressed = p_event->is_action_pressed(E->key()); + action.strength = 0.f; action_state[E->key()] = action; } action_state[E->key()].strength = p_event->get_action_strength(E->key()); @@ -533,13 +556,14 @@ Point2i InputDefault::warp_mouse_motion(const Ref<InputEventMouseMotion> &p_moti void InputDefault::iteration(float p_step) { } -void InputDefault::action_press(const StringName &p_action) { +void InputDefault::action_press(const StringName &p_action, float p_strength) { Action action; action.physics_frame = Engine::get_singleton()->get_physics_frames(); action.idle_frame = Engine::get_singleton()->get_idle_frames(); action.pressed = true; + action.strength = p_strength; action_state[p_action] = action; } @@ -551,6 +575,7 @@ void InputDefault::action_release(const StringName &p_action) { action.physics_frame = Engine::get_singleton()->get_physics_frames(); action.idle_frame = Engine::get_singleton()->get_idle_frames(); action.pressed = false; + action.strength = 0.f; action_state[p_action] = action; } @@ -579,7 +604,7 @@ void InputDefault::ensure_touch_mouse_raised() { button_event->set_global_position(mouse_pos); button_event->set_pressed(false); button_event->set_button_index(BUTTON_LEFT); - button_event->set_button_mask(mouse_button_mask & ~(1 << BUTTON_LEFT - 1)); + button_event->set_button_mask(mouse_button_mask & ~(1 << (BUTTON_LEFT - 1))); _parse_input_event_impl(button_event, true); } @@ -601,7 +626,13 @@ Input::CursorShape InputDefault::get_default_cursor_shape() { void InputDefault::set_default_cursor_shape(CursorShape p_shape) { default_shape = p_shape; - OS::get_singleton()->set_cursor_shape((OS::CursorShape)p_shape); + // The default shape is set in Viewport::_gui_input_event. To instantly + // see the shape in the viewport we need to trigger a mouse motion event. + Ref<InputEventMouseMotion> mm; + mm.instance(); + mm->set_position(mouse_pos); + mm->set_global_position(mouse_pos); + parse_input_event(mm); } void InputDefault::set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape, const Vector2 &p_hotspot) { @@ -633,6 +664,7 @@ InputDefault::InputDefault() { emulate_mouse_from_touch = false; mouse_from_touch_index = -1; main_loop = NULL; + default_shape = CURSOR_ARROW; hat_map_default[HAT_UP].type = TYPE_BUTTON; hat_map_default[HAT_UP].index = JOY_DPAD_UP; |