summaryrefslogtreecommitdiff
path: root/main/input_default.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'main/input_default.cpp')
-rw-r--r--main/input_default.cpp64
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;