diff options
Diffstat (limited to 'main/input_default.cpp')
-rw-r--r-- | main/input_default.cpp | 158 |
1 files changed, 130 insertions, 28 deletions
diff --git a/main/input_default.cpp b/main/input_default.cpp index c3bc83b2de..29d30110e3 100644 --- a/main/input_default.cpp +++ b/main/input_default.cpp @@ -127,6 +127,14 @@ bool InputDefault::is_action_just_released(const StringName &p_action) const { } } +float InputDefault::get_action_strength(const StringName &p_action) const { + const Map<StringName, Action>::Element *E = action_state.find(p_action); + if (!E) + return 0.0f; + + return E->get().strength; +} + float InputDefault::get_joy_axis(int p_device, int p_axis) const { _THREAD_SAFE_METHOD_ @@ -186,8 +194,6 @@ void InputDefault::joy_connection_changed(int p_idx, bool p_connected, String p_ Joypad js; js.name = p_connected ? p_name : ""; js.uid = p_connected ? p_guid : ""; - js.mapping = -1; - js.hat_current = 0; if (p_connected) { @@ -250,6 +256,11 @@ Vector3 InputDefault::get_gyroscope() const { void InputDefault::parse_input_event(const Ref<InputEvent> &p_event) { + _parse_input_event_impl(p_event, false); +} + +void InputDefault::_parse_input_event_impl(const Ref<InputEvent> &p_event, bool p_is_emulated) { + _THREAD_SAFE_METHOD_ Ref<InputEventKey> k = p_event; @@ -273,25 +284,30 @@ void InputDefault::parse_input_event(const Ref<InputEvent> &p_event) { mouse_button_mask &= ~(1 << (mb->get_button_index() - 1)); } - if (main_loop && emulate_touch && mb->get_button_index() == 1) { + Point2 pos = mb->get_global_position(); + if (mouse_pos != pos) { + set_mouse_position(pos); + } + + if (main_loop && emulate_touch_from_mouse && !p_is_emulated && mb->get_button_index() == 1) { Ref<InputEventScreenTouch> touch_event; touch_event.instance(); touch_event->set_pressed(mb->is_pressed()); touch_event->set_position(mb->get_position()); main_loop->input_event(touch_event); } - - Point2 pos = mb->get_global_position(); - if (mouse_pos != pos) { - set_mouse_position(pos); - } } Ref<InputEventMouseMotion> mm = p_event; if (mm.is_valid()) { - if (main_loop && emulate_touch && mm->get_button_mask() & 1) { + Point2 pos = mm->get_global_position(); + if (mouse_pos != pos) { + set_mouse_position(pos); + } + + if (main_loop && emulate_touch_from_mouse && !p_is_emulated && mm->get_button_mask() & 1) { Ref<InputEventScreenDrag> drag_event; drag_event.instance(); @@ -303,6 +319,58 @@ void InputDefault::parse_input_event(const Ref<InputEvent> &p_event) { } } + if (emulate_mouse_from_touch) { + + Ref<InputEventScreenTouch> st = p_event; + + if (st.is_valid()) { + bool translate = false; + if (st->is_pressed()) { + if (mouse_from_touch_index == -1) { + translate = true; + mouse_from_touch_index = st->get_index(); + } + } else { + if (st->get_index() == mouse_from_touch_index) { + translate = true; + mouse_from_touch_index = -1; + } + } + + if (translate) { + Ref<InputEventMouseButton> button_event; + button_event.instance(); + + button_event->set_position(st->get_position()); + button_event->set_global_position(st->get_position()); + 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)); + } else { + 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() && sd->get_index() == mouse_from_touch_index) { + Ref<InputEventMouseMotion> motion_event; + motion_event.instance(); + + motion_event->set_position(sd->get_position()); + motion_event->set_global_position(sd->get_position()); + motion_event->set_relative(sd->get_relative()); + motion_event->set_speed(sd->get_speed()); + motion_event->set_button_mask(mouse_button_mask); + + _parse_input_event_impl(motion_event, true); + } + } + Ref<InputEventJoypadButton> jb = p_event; if (jb.is_valid()) { @@ -330,16 +398,18 @@ void InputDefault::parse_input_event(const Ref<InputEvent> &p_event) { } } - if (!p_event->is_echo()) { - for (const Map<StringName, InputMap::Action>::Element *E = InputMap::get_singleton()->get_action_map().front(); E; E = E->next()) { + for (const Map<StringName, InputMap::Action>::Element *E = InputMap::get_singleton()->get_action_map().front(); E; E = E->next()) { + if (InputMap::get_singleton()->event_is_action(p_event, E->key())) { - if (InputMap::get_singleton()->event_is_action(p_event, E->key()) && is_action_pressed(E->key()) != p_event->is_pressed()) { + // Save the action's state + if (!p_event->is_echo() && is_action_pressed(E->key()) != p_event->is_action_pressed(E->key())) { Action action; action.physics_frame = Engine::get_singleton()->get_physics_frames(); action.idle_frame = Engine::get_singleton()->get_idle_frames(); - action.pressed = p_event->is_pressed(); + action.pressed = p_event->is_action_pressed(E->key()); action_state[E->key()] = action; } + action_state[E->key()].strength = p_event->get_action_strength(E->key()); } } @@ -413,10 +483,6 @@ void InputDefault::set_mouse_position(const Point2 &p_posf) { mouse_speed_track.update(p_posf - mouse_pos); mouse_pos = p_posf; - if (custom_cursor.is_valid()) { - //removed, please insist that we implement hardware cursors - // VisualServer::get_singleton()->cursor_set_pos(get_mouse_position()); - } } Point2 InputDefault::get_mouse_position() const { @@ -489,25 +555,59 @@ void InputDefault::action_release(const StringName &p_action) { action_state[p_action] = action; } -void InputDefault::set_emulate_touch(bool p_emulate) { +void InputDefault::set_emulate_touch_from_mouse(bool p_emulate) { + + emulate_touch_from_mouse = p_emulate; +} + +bool InputDefault::is_emulating_touch_from_mouse() const { + + return emulate_touch_from_mouse; +} + +// Calling this whenever the game window is focused helps unstucking the "touch mouse" +// if the OS or its abstraction class hasn't properly reported that touch pointers raised +void InputDefault::ensure_touch_mouse_raised() { + + if (mouse_from_touch_index != -1) { + mouse_from_touch_index = -1; + + Ref<InputEventMouseButton> button_event; + button_event.instance(); + + button_event->set_position(mouse_pos); + 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)); + + _parse_input_event_impl(button_event, true); + } +} + +void InputDefault::set_emulate_mouse_from_touch(bool p_emulate) { - emulate_touch = p_emulate; + emulate_mouse_from_touch = p_emulate; } -bool InputDefault::is_emulating_touchscreen() const { +bool InputDefault::is_emulating_mouse_from_touch() const { - return emulate_touch; + return emulate_mouse_from_touch; +} + +Input::CursorShape InputDefault::get_default_cursor_shape() { + return default_shape; +} + +void InputDefault::set_default_cursor_shape(CursorShape p_shape) { + default_shape = p_shape; + OS::get_singleton()->set_cursor_shape((OS::CursorShape)p_shape); } void InputDefault::set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape, const Vector2 &p_hotspot) { if (Engine::get_singleton()->is_editor_hint()) return; - if (custom_cursor == p_cursor) - return; - - custom_cursor = p_cursor; - OS::get_singleton()->set_custom_mouse_cursor(p_cursor, (OS::CursorShape)p_shape, p_hotspot); } @@ -529,7 +629,9 @@ void InputDefault::set_mouse_in_window(bool p_in_window) { InputDefault::InputDefault() { mouse_button_mask = 0; - emulate_touch = false; + emulate_touch_from_mouse = false; + emulate_mouse_from_touch = false; + mouse_from_touch_index = -1; main_loop = NULL; hat_map_default[HAT_UP].type = TYPE_BUTTON; @@ -787,12 +889,12 @@ InputDefault::JoyEvent InputDefault::_find_to_event(String p_to) { JoyEvent ret; ret.type = -1; + ret.index = 0; int i = 0; while (buttons[i]) { if (p_to == buttons[i]) { - //printf("mapping button %s\n", buttons[i]); ret.type = TYPE_BUTTON; ret.index = i; ret.value = 0; |