Merge pull request #17196 from RandomShaper/improve-gui-touch
Implement universal translation of touch to mouse (3.1)
This commit is contained in:
+106
-12
@@ -256,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;
|
||||
@@ -279,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();
|
||||
|
||||
@@ -309,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()) {
|
||||
@@ -493,14 +555,44 @@ 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 = p_emulate;
|
||||
emulate_touch_from_mouse = p_emulate;
|
||||
}
|
||||
|
||||
bool InputDefault::is_emulating_touchscreen() const {
|
||||
bool InputDefault::is_emulating_touch_from_mouse() const {
|
||||
|
||||
return emulate_touch;
|
||||
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_mouse_from_touch = p_emulate;
|
||||
}
|
||||
|
||||
bool InputDefault::is_emulating_mouse_from_touch() const {
|
||||
|
||||
return emulate_mouse_from_touch;
|
||||
}
|
||||
|
||||
Input::CursorShape InputDefault::get_default_cursor_shape() {
|
||||
@@ -537,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;
|
||||
|
||||
+12
-3
@@ -60,7 +60,10 @@ class InputDefault : public Input {
|
||||
|
||||
Map<StringName, Action> action_state;
|
||||
|
||||
bool emulate_touch;
|
||||
bool emulate_touch_from_mouse;
|
||||
bool emulate_mouse_from_touch;
|
||||
|
||||
int mouse_from_touch_index;
|
||||
|
||||
struct VibrationInfo {
|
||||
float weak_magnitude;
|
||||
@@ -176,6 +179,8 @@ private:
|
||||
void _axis_event(int p_device, int p_axis, float p_value);
|
||||
float _handle_deadzone(int p_device, int p_axis, float p_value);
|
||||
|
||||
void _parse_input_event_impl(const Ref<InputEvent> &p_event, bool p_is_emulated);
|
||||
|
||||
public:
|
||||
virtual bool is_key_pressed(int p_scancode) const;
|
||||
virtual bool is_mouse_button_pressed(int p_button) const;
|
||||
@@ -225,8 +230,12 @@ public:
|
||||
|
||||
void iteration(float p_step);
|
||||
|
||||
void set_emulate_touch(bool p_emulate);
|
||||
virtual bool is_emulating_touchscreen() const;
|
||||
void set_emulate_touch_from_mouse(bool p_emulate);
|
||||
virtual bool is_emulating_touch_from_mouse() const;
|
||||
void ensure_touch_mouse_raised();
|
||||
|
||||
void set_emulate_mouse_from_touch(bool p_emulate);
|
||||
virtual bool is_emulating_mouse_from_touch() const;
|
||||
|
||||
virtual CursorShape get_default_cursor_shape();
|
||||
virtual void set_default_cursor_shape(CursorShape p_shape);
|
||||
|
||||
+9
-6
@@ -1141,13 +1141,16 @@ Error Main::setup2(Thread::ID p_main_tid_override) {
|
||||
GLOBAL_DEF("application/config/icon", String());
|
||||
ProjectSettings::get_singleton()->set_custom_property_info("application/config/icon", PropertyInfo(Variant::STRING, "application/config/icon", PROPERTY_HINT_FILE, "*.png,*.webp"));
|
||||
|
||||
if (bool(GLOBAL_DEF("display/window/handheld/emulate_touchscreen", false))) {
|
||||
if (!OS::get_singleton()->has_touchscreen_ui_hint() && Input::get_singleton() && !(editor || project_manager)) {
|
||||
//only if no touchscreen ui hint, set emulation
|
||||
InputDefault *id = Object::cast_to<InputDefault>(Input::get_singleton());
|
||||
if (id)
|
||||
id->set_emulate_touch(true);
|
||||
InputDefault *id = Object::cast_to<InputDefault>(Input::get_singleton());
|
||||
if (id) {
|
||||
if (bool(GLOBAL_DEF("input/pointing_devices/emulate_touch_from_mouse", false)) && !(editor || project_manager)) {
|
||||
if (!OS::get_singleton()->has_touchscreen_ui_hint()) {
|
||||
//only if no touchscreen ui hint, set emulation
|
||||
id->set_emulate_touch_from_mouse(true);
|
||||
}
|
||||
}
|
||||
|
||||
id->set_emulate_mouse_from_touch(bool(GLOBAL_DEF("input/pointing_devices/emulate_mouse_from_touch", true)));
|
||||
}
|
||||
|
||||
MAIN_PRINT("Main: Load Remaps");
|
||||
|
||||
Reference in New Issue
Block a user