Merge pull request #18082 from RandomShaper/improve-gui-touch-3.0
Implement universal translation of touch to mouse (3.0)
This commit is contained in:
commit
5917063192
|
@ -118,6 +118,7 @@ public:
|
||||||
void get_argument_options(const StringName &p_function, int p_idx, List<String> *r_options) const;
|
void get_argument_options(const StringName &p_function, int p_idx, List<String> *r_options) const;
|
||||||
|
|
||||||
virtual bool is_emulating_touchscreen() const = 0;
|
virtual bool is_emulating_touchscreen() const = 0;
|
||||||
|
virtual bool is_emulating_mouse_from_touch() const = 0;
|
||||||
|
|
||||||
virtual void set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape = CURSOR_ARROW, const Vector2 &p_hotspot = Vector2()) = 0;
|
virtual void set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape = CURSOR_ARROW, const Vector2 &p_hotspot = Vector2()) = 0;
|
||||||
virtual void set_mouse_in_window(bool p_in_window) = 0;
|
virtual void set_mouse_in_window(bool p_in_window) = 0;
|
||||||
|
|
|
@ -249,6 +249,11 @@ Vector3 InputDefault::get_gyroscope() const {
|
||||||
|
|
||||||
void InputDefault::parse_input_event(const Ref<InputEvent> &p_event) {
|
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_
|
_THREAD_SAFE_METHOD_
|
||||||
|
|
||||||
Ref<InputEventKey> k = p_event;
|
Ref<InputEventKey> k = p_event;
|
||||||
|
@ -272,25 +277,30 @@ void InputDefault::parse_input_event(const Ref<InputEvent> &p_event) {
|
||||||
mouse_button_mask &= ~(1 << (mb->get_button_index() - 1));
|
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 && !p_is_emulated && mb->get_button_index() == 1) {
|
||||||
Ref<InputEventScreenTouch> touch_event;
|
Ref<InputEventScreenTouch> touch_event;
|
||||||
touch_event.instance();
|
touch_event.instance();
|
||||||
touch_event->set_pressed(mb->is_pressed());
|
touch_event->set_pressed(mb->is_pressed());
|
||||||
touch_event->set_position(mb->get_position());
|
touch_event->set_position(mb->get_position());
|
||||||
main_loop->input_event(touch_event);
|
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;
|
Ref<InputEventMouseMotion> mm = p_event;
|
||||||
|
|
||||||
if (mm.is_valid()) {
|
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 && !p_is_emulated && mm->get_button_mask() & 1) {
|
||||||
Ref<InputEventScreenDrag> drag_event;
|
Ref<InputEventScreenDrag> drag_event;
|
||||||
drag_event.instance();
|
drag_event.instance();
|
||||||
|
|
||||||
|
@ -302,6 +312,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;
|
Ref<InputEventJoypadButton> jb = p_event;
|
||||||
|
|
||||||
if (jb.is_valid()) {
|
if (jb.is_valid()) {
|
||||||
|
@ -498,6 +560,36 @@ bool InputDefault::is_emulating_touchscreen() const {
|
||||||
return emulate_touch;
|
return emulate_touch;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
}
|
||||||
|
|
||||||
void InputDefault::set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape, const Vector2 &p_hotspot) {
|
void InputDefault::set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape, const Vector2 &p_hotspot) {
|
||||||
if (Engine::get_singleton()->is_editor_hint())
|
if (Engine::get_singleton()->is_editor_hint())
|
||||||
return;
|
return;
|
||||||
|
@ -815,6 +907,8 @@ InputDefault::InputDefault() {
|
||||||
|
|
||||||
mouse_button_mask = 0;
|
mouse_button_mask = 0;
|
||||||
emulate_touch = false;
|
emulate_touch = false;
|
||||||
|
emulate_mouse_from_touch = false;
|
||||||
|
mouse_from_touch_index = -1;
|
||||||
main_loop = NULL;
|
main_loop = NULL;
|
||||||
|
|
||||||
hat_map_default[HAT_UP].type = TYPE_BUTTON;
|
hat_map_default[HAT_UP].type = TYPE_BUTTON;
|
||||||
|
|
|
@ -60,6 +60,9 @@ class InputDefault : public Input {
|
||||||
Map<StringName, Action> action_state;
|
Map<StringName, Action> action_state;
|
||||||
|
|
||||||
bool emulate_touch;
|
bool emulate_touch;
|
||||||
|
bool emulate_mouse_from_touch;
|
||||||
|
|
||||||
|
int mouse_from_touch_index;
|
||||||
|
|
||||||
struct VibrationInfo {
|
struct VibrationInfo {
|
||||||
float weak_magnitude;
|
float weak_magnitude;
|
||||||
|
@ -175,6 +178,8 @@ private:
|
||||||
void _axis_event(int p_device, int p_axis, float p_value);
|
void _axis_event(int p_device, int p_axis, float p_value);
|
||||||
float _handle_deadzone(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:
|
public:
|
||||||
virtual bool is_key_pressed(int p_scancode) const;
|
virtual bool is_key_pressed(int p_scancode) const;
|
||||||
virtual bool is_mouse_button_pressed(int p_button) const;
|
virtual bool is_mouse_button_pressed(int p_button) const;
|
||||||
|
@ -225,6 +230,10 @@ public:
|
||||||
|
|
||||||
void set_emulate_touch(bool p_emulate);
|
void set_emulate_touch(bool p_emulate);
|
||||||
virtual bool is_emulating_touchscreen() const;
|
virtual bool is_emulating_touchscreen() const;
|
||||||
|
void ensure_touch_mouse_raised();
|
||||||
|
|
||||||
|
void set_emulate_mouse_from_touch(bool p_emulate);
|
||||||
|
virtual bool is_emulating_mouse_from_touch() const;
|
||||||
|
|
||||||
virtual void set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape = Input::CURSOR_ARROW, const Vector2 &p_hotspot = Vector2());
|
virtual void set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape = Input::CURSOR_ARROW, const Vector2 &p_hotspot = Vector2());
|
||||||
virtual void set_mouse_in_window(bool p_in_window);
|
virtual void set_mouse_in_window(bool p_in_window);
|
||||||
|
|
|
@ -1157,15 +1157,18 @@ Error Main::setup2(Thread::ID p_main_tid_override) {
|
||||||
GLOBAL_DEF("application/config/icon", String());
|
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"));
|
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) {
|
|
||||||
//only if no touchscreen ui hint, set emulation
|
|
||||||
InputDefault *id = Object::cast_to<InputDefault>(Input::get_singleton());
|
InputDefault *id = Object::cast_to<InputDefault>(Input::get_singleton());
|
||||||
if (id)
|
if (id) {
|
||||||
|
if (bool(GLOBAL_DEF("display/window/handheld/emulate_touchscreen", false)) && !editor) {
|
||||||
|
if (!OS::get_singleton()->has_touchscreen_ui_hint()) {
|
||||||
|
//only if no touchscreen ui hint, set emulation
|
||||||
id->set_emulate_touch(true);
|
id->set_emulate_touch(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
id->set_emulate_mouse_from_touch(bool(GLOBAL_DEF("display/window/handheld/emulate_mouse_from_touch", true)));
|
||||||
|
}
|
||||||
|
|
||||||
MAIN_PRINT("Main: Load Remaps");
|
MAIN_PRINT("Main: Load Remaps");
|
||||||
|
|
||||||
MAIN_PRINT("Main: Load Scene Types");
|
MAIN_PRINT("Main: Load Scene Types");
|
||||||
|
|
|
@ -332,17 +332,6 @@ void OS_Android::process_touch(int p_what, int p_pointer, const Vector<TouchPos>
|
||||||
|
|
||||||
if (touch.size()) {
|
if (touch.size()) {
|
||||||
//end all if exist
|
//end all if exist
|
||||||
{
|
|
||||||
Ref<InputEventMouseButton> ev;
|
|
||||||
ev.instance();
|
|
||||||
ev->set_button_index(BUTTON_LEFT);
|
|
||||||
ev->set_button_mask(BUTTON_MASK_LEFT);
|
|
||||||
ev->set_pressed(false);
|
|
||||||
ev->set_position(touch[0].pos);
|
|
||||||
ev->set_global_position(touch[0].pos);
|
|
||||||
input->parse_input_event(ev);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < touch.size(); i++) {
|
for (int i = 0; i < touch.size(); i++) {
|
||||||
|
|
||||||
Ref<InputEventScreenTouch> ev;
|
Ref<InputEventScreenTouch> ev;
|
||||||
|
@ -360,21 +349,6 @@ void OS_Android::process_touch(int p_what, int p_pointer, const Vector<TouchPos>
|
||||||
touch[i].pos = p_points[i].pos;
|
touch[i].pos = p_points[i].pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
|
||||||
//send mouse
|
|
||||||
Ref<InputEventMouseButton> ev;
|
|
||||||
ev.instance();
|
|
||||||
// ev.type = Ref<InputEvent>::MOUSE_BUTTON;
|
|
||||||
ev->set_button_index(BUTTON_LEFT);
|
|
||||||
ev->set_button_mask(BUTTON_MASK_LEFT);
|
|
||||||
ev->set_pressed(true);
|
|
||||||
ev->set_position(touch[0].pos);
|
|
||||||
ev->set_global_position(touch[0].pos);
|
|
||||||
input->set_mouse_position(Point2(touch[0].pos.x, touch[0].pos.y));
|
|
||||||
last_mouse = touch[0].pos;
|
|
||||||
input->parse_input_event(ev);
|
|
||||||
}
|
|
||||||
|
|
||||||
//send touch
|
//send touch
|
||||||
for (int i = 0; i < touch.size(); i++) {
|
for (int i = 0; i < touch.size(); i++) {
|
||||||
|
|
||||||
|
@ -389,19 +363,6 @@ void OS_Android::process_touch(int p_what, int p_pointer, const Vector<TouchPos>
|
||||||
} break;
|
} break;
|
||||||
case 1: { //motion
|
case 1: { //motion
|
||||||
|
|
||||||
if (p_points.size()) {
|
|
||||||
//send mouse, should look for point 0?
|
|
||||||
Ref<InputEventMouseMotion> ev;
|
|
||||||
ev.instance();
|
|
||||||
ev->set_button_mask(BUTTON_MASK_LEFT);
|
|
||||||
ev->set_position(p_points[0].pos);
|
|
||||||
input->set_mouse_position(Point2(ev->get_position().x, ev->get_position().y));
|
|
||||||
ev->set_speed(input->get_last_mouse_speed());
|
|
||||||
ev->set_relative(p_points[0].pos - last_mouse);
|
|
||||||
last_mouse = p_points[0].pos;
|
|
||||||
input->parse_input_event(ev);
|
|
||||||
}
|
|
||||||
|
|
||||||
ERR_FAIL_COND(touch.size() != p_points.size());
|
ERR_FAIL_COND(touch.size() != p_points.size());
|
||||||
|
|
||||||
for (int i = 0; i < touch.size(); i++) {
|
for (int i = 0; i < touch.size(); i++) {
|
||||||
|
@ -434,16 +395,6 @@ void OS_Android::process_touch(int p_what, int p_pointer, const Vector<TouchPos>
|
||||||
|
|
||||||
if (touch.size()) {
|
if (touch.size()) {
|
||||||
//end all if exist
|
//end all if exist
|
||||||
Ref<InputEventMouseButton> ev;
|
|
||||||
ev.instance();
|
|
||||||
ev->set_button_index(BUTTON_LEFT);
|
|
||||||
ev->set_button_mask(BUTTON_MASK_LEFT);
|
|
||||||
ev->set_pressed(false);
|
|
||||||
ev->set_position(touch[0].pos);
|
|
||||||
ev->set_global_position(touch[0].pos);
|
|
||||||
input->set_mouse_position(Point2(touch[0].pos.x, touch[0].pos.y));
|
|
||||||
input->parse_input_event(ev);
|
|
||||||
|
|
||||||
for (int i = 0; i < touch.size(); i++) {
|
for (int i = 0; i < touch.size(); i++) {
|
||||||
|
|
||||||
Ref<InputEventScreenTouch> ev;
|
Ref<InputEventScreenTouch> ev;
|
||||||
|
|
|
@ -93,7 +93,6 @@ public:
|
||||||
private:
|
private:
|
||||||
Vector<TouchPos> touch;
|
Vector<TouchPos> touch;
|
||||||
|
|
||||||
Point2 last_mouse;
|
|
||||||
GFXInitFunc gfx_init_func;
|
GFXInitFunc gfx_init_func;
|
||||||
void *gfx_init_ud;
|
void *gfx_init_ud;
|
||||||
|
|
||||||
|
|
|
@ -497,7 +497,7 @@ static void clear_touches() {
|
||||||
int tid = get_touch_id(touch);
|
int tid = get_touch_id(touch);
|
||||||
ERR_FAIL_COND(tid == -1);
|
ERR_FAIL_COND(tid == -1);
|
||||||
CGPoint touchPoint = [touch locationInView:self];
|
CGPoint touchPoint = [touch locationInView:self];
|
||||||
OSIPhone::get_singleton()->mouse_button(tid, touchPoint.x * self.contentScaleFactor, touchPoint.y * self.contentScaleFactor, true, touch.tapCount > 1, tid == 0);
|
OSIPhone::get_singleton()->touch_press(tid, touchPoint.x * self.contentScaleFactor, touchPoint.y * self.contentScaleFactor, true, touch.tapCount > 1);
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -514,10 +514,9 @@ static void clear_touches() {
|
||||||
continue;
|
continue;
|
||||||
int tid = get_touch_id(touch);
|
int tid = get_touch_id(touch);
|
||||||
ERR_FAIL_COND(tid == -1);
|
ERR_FAIL_COND(tid == -1);
|
||||||
int first = get_first_id(touch);
|
|
||||||
CGPoint touchPoint = [touch locationInView:self];
|
CGPoint touchPoint = [touch locationInView:self];
|
||||||
CGPoint prev_point = [touch previousLocationInView:self];
|
CGPoint prev_point = [touch previousLocationInView:self];
|
||||||
OSIPhone::get_singleton()->mouse_move(tid, prev_point.x * self.contentScaleFactor, prev_point.y * self.contentScaleFactor, touchPoint.x * self.contentScaleFactor, touchPoint.y * self.contentScaleFactor, first == tid);
|
OSIPhone::get_singleton()->touch_drag(tid, prev_point.x * self.contentScaleFactor, prev_point.y * self.contentScaleFactor, touchPoint.x * self.contentScaleFactor, touchPoint.y * self.contentScaleFactor);
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -533,9 +532,9 @@ static void clear_touches() {
|
||||||
continue;
|
continue;
|
||||||
int tid = get_touch_id(touch);
|
int tid = get_touch_id(touch);
|
||||||
ERR_FAIL_COND(tid == -1);
|
ERR_FAIL_COND(tid == -1);
|
||||||
int rem = remove_touch(touch);
|
remove_touch(touch);
|
||||||
CGPoint touchPoint = [touch locationInView:self];
|
CGPoint touchPoint = [touch locationInView:self];
|
||||||
OSIPhone::get_singleton()->mouse_button(tid, touchPoint.x * self.contentScaleFactor, touchPoint.y * self.contentScaleFactor, false, false, rem == 0);
|
OSIPhone::get_singleton()->touch_press(tid, touchPoint.x * self.contentScaleFactor, touchPoint.y * self.contentScaleFactor, false, false);
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -191,7 +191,7 @@ void OSIPhone::key(uint32_t p_key, bool p_pressed) {
|
||||||
queue_event(ev);
|
queue_event(ev);
|
||||||
};
|
};
|
||||||
|
|
||||||
void OSIPhone::mouse_button(int p_idx, int p_x, int p_y, bool p_pressed, bool p_doubleclick, bool p_use_as_mouse) {
|
void OSIPhone::touch_press(int p_idx, int p_x, int p_y, bool p_pressed, bool p_doubleclick) {
|
||||||
|
|
||||||
if (!GLOBAL_DEF("debug/disable_touch", false)) {
|
if (!GLOBAL_DEF("debug/disable_touch", false)) {
|
||||||
Ref<InputEventScreenTouch> ev;
|
Ref<InputEventScreenTouch> ev;
|
||||||
|
@ -203,28 +203,10 @@ void OSIPhone::mouse_button(int p_idx, int p_x, int p_y, bool p_pressed, bool p_
|
||||||
queue_event(ev);
|
queue_event(ev);
|
||||||
};
|
};
|
||||||
|
|
||||||
mouse_list.pressed[p_idx] = p_pressed;
|
touch_list.pressed[p_idx] = p_pressed;
|
||||||
|
|
||||||
if (p_use_as_mouse) {
|
|
||||||
|
|
||||||
Ref<InputEventMouseButton> ev;
|
|
||||||
ev.instance();
|
|
||||||
|
|
||||||
ev->set_position(Vector2(p_x, p_y));
|
|
||||||
ev->set_global_position(Vector2(p_x, p_y));
|
|
||||||
|
|
||||||
//mouse_list.pressed[p_idx] = p_pressed;
|
|
||||||
|
|
||||||
input->set_mouse_position(ev->get_position());
|
|
||||||
ev->set_button_index(BUTTON_LEFT);
|
|
||||||
ev->set_doubleclick(p_doubleclick);
|
|
||||||
ev->set_pressed(p_pressed);
|
|
||||||
|
|
||||||
queue_event(ev);
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
void OSIPhone::mouse_move(int p_idx, int p_prev_x, int p_prev_y, int p_x, int p_y, bool p_use_as_mouse) {
|
void OSIPhone::touch_drag(int p_idx, int p_prev_x, int p_prev_y, int p_x, int p_y) {
|
||||||
|
|
||||||
if (!GLOBAL_DEF("debug/disable_touch", false)) {
|
if (!GLOBAL_DEF("debug/disable_touch", false)) {
|
||||||
|
|
||||||
|
@ -235,21 +217,6 @@ void OSIPhone::mouse_move(int p_idx, int p_prev_x, int p_prev_y, int p_x, int p_
|
||||||
ev->set_relative(Vector2(p_x - p_prev_x, p_y - p_prev_y));
|
ev->set_relative(Vector2(p_x - p_prev_x, p_y - p_prev_y));
|
||||||
queue_event(ev);
|
queue_event(ev);
|
||||||
};
|
};
|
||||||
|
|
||||||
if (p_use_as_mouse) {
|
|
||||||
Ref<InputEventMouseMotion> ev;
|
|
||||||
ev.instance();
|
|
||||||
|
|
||||||
ev->set_position(Vector2(p_x, p_y));
|
|
||||||
ev->set_global_position(Vector2(p_x, p_y));
|
|
||||||
ev->set_relative(Vector2(p_x - p_prev_x, p_y - p_prev_y));
|
|
||||||
|
|
||||||
input->set_mouse_position(ev->get_position());
|
|
||||||
ev->set_speed(input->get_last_mouse_speed());
|
|
||||||
ev->set_button_mask(BUTTON_LEFT); // pressed
|
|
||||||
|
|
||||||
queue_event(ev);
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
void OSIPhone::queue_event(const Ref<InputEvent> &p_event) {
|
void OSIPhone::queue_event(const Ref<InputEvent> &p_event) {
|
||||||
|
@ -263,10 +230,10 @@ void OSIPhone::touches_cancelled() {
|
||||||
|
|
||||||
for (int i = 0; i < MAX_MOUSE_COUNT; i++) {
|
for (int i = 0; i < MAX_MOUSE_COUNT; i++) {
|
||||||
|
|
||||||
if (mouse_list.pressed[i]) {
|
if (touch_list.pressed[i]) {
|
||||||
|
|
||||||
// send a mouse_up outside the screen
|
// send a mouse_up outside the screen
|
||||||
mouse_button(i, -1, -1, false, false, false);
|
touch_press(i, -1, -1, false, false);
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -377,7 +344,7 @@ Point2 OSIPhone::get_mouse_position() const {
|
||||||
|
|
||||||
int OSIPhone::get_mouse_button_state() const {
|
int OSIPhone::get_mouse_button_state() const {
|
||||||
|
|
||||||
return mouse_list.pressed[0];
|
return false;
|
||||||
};
|
};
|
||||||
|
|
||||||
void OSIPhone::set_window_title(const String &p_title){};
|
void OSIPhone::set_window_title(const String &p_title){};
|
||||||
|
|
|
@ -106,7 +106,7 @@ private:
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
MouseList mouse_list;
|
MouseList touch_list;
|
||||||
|
|
||||||
Vector3 last_accel;
|
Vector3 last_accel;
|
||||||
|
|
||||||
|
@ -127,8 +127,8 @@ public:
|
||||||
|
|
||||||
uint8_t get_orientations() const;
|
uint8_t get_orientations() const;
|
||||||
|
|
||||||
void mouse_button(int p_idx, int p_x, int p_y, bool p_pressed, bool p_doubleclick, bool p_use_as_mouse);
|
void touch_press(int p_idx, int p_x, int p_y, bool p_pressed, bool p_doubleclick);
|
||||||
void mouse_move(int p_idx, int p_prev_x, int p_prev_y, int p_x, int p_y, bool p_use_as_mouse);
|
void touch_drag(int p_idx, int p_prev_x, int p_prev_y, int p_x, int p_y);
|
||||||
void touches_cancelled();
|
void touches_cancelled();
|
||||||
void key(uint32_t p_key, bool p_pressed);
|
void key(uint32_t p_key, bool p_pressed);
|
||||||
void set_virtual_keyboard_height(int p_height);
|
void set_virtual_keyboard_height(int p_height);
|
||||||
|
@ -151,7 +151,6 @@ public:
|
||||||
virtual void set_mouse_grab(bool p_grab);
|
virtual void set_mouse_grab(bool p_grab);
|
||||||
virtual bool is_mouse_grab_enabled() const;
|
virtual bool is_mouse_grab_enabled() const;
|
||||||
virtual Point2 get_mouse_position() const;
|
virtual Point2 get_mouse_position() const;
|
||||||
virtual int get_mouse_button_state() const;
|
|
||||||
virtual void set_window_title(const String &p_title);
|
virtual void set_window_title(const String &p_title);
|
||||||
|
|
||||||
virtual void alert(const String &p_alert, const String &p_title = "ALERT!");
|
virtual void alert(const String &p_alert, const String &p_title = "ALERT!");
|
||||||
|
|
|
@ -277,23 +277,6 @@ static EM_BOOL _touchpress_callback(int event_type, const EmscriptenTouchEvent *
|
||||||
|
|
||||||
_input->parse_input_event(ev);
|
_input->parse_input_event(ev);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (touch_event->touches[lowest_id_index].isChanged) {
|
|
||||||
|
|
||||||
Ref<InputEventMouseButton> ev_mouse;
|
|
||||||
ev_mouse.instance();
|
|
||||||
ev_mouse->set_button_mask(_input->get_mouse_button_mask());
|
|
||||||
dom2godot_mod(touch_event, ev_mouse);
|
|
||||||
|
|
||||||
const EmscriptenTouchPoint &first_touch = touch_event->touches[lowest_id_index];
|
|
||||||
ev_mouse->set_position(Point2(first_touch.canvasX, first_touch.canvasY));
|
|
||||||
ev_mouse->set_global_position(ev_mouse->get_position());
|
|
||||||
|
|
||||||
ev_mouse->set_button_index(BUTTON_LEFT);
|
|
||||||
ev_mouse->set_pressed(event_type == EMSCRIPTEN_EVENT_TOUCHSTART);
|
|
||||||
|
|
||||||
_input->parse_input_event(ev_mouse);
|
|
||||||
}
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -319,24 +302,6 @@ static EM_BOOL _touchmove_callback(int event_type, const EmscriptenTouchEvent *t
|
||||||
|
|
||||||
_input->parse_input_event(ev);
|
_input->parse_input_event(ev);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (touch_event->touches[lowest_id_index].isChanged) {
|
|
||||||
|
|
||||||
Ref<InputEventMouseMotion> ev_mouse;
|
|
||||||
ev_mouse.instance();
|
|
||||||
dom2godot_mod(touch_event, ev_mouse);
|
|
||||||
ev_mouse->set_button_mask(_input->get_mouse_button_mask());
|
|
||||||
|
|
||||||
const EmscriptenTouchPoint &first_touch = touch_event->touches[lowest_id_index];
|
|
||||||
ev_mouse->set_position(Point2(first_touch.canvasX, first_touch.canvasY));
|
|
||||||
ev_mouse->set_global_position(ev_mouse->get_position());
|
|
||||||
|
|
||||||
ev_mouse->set_relative(ev_mouse->get_position() - _input->get_mouse_position());
|
|
||||||
_input->set_mouse_position(ev_mouse->get_position());
|
|
||||||
ev_mouse->set_speed(_input->get_last_mouse_speed());
|
|
||||||
|
|
||||||
_input->parse_input_event(ev_mouse);
|
|
||||||
}
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -85,8 +85,7 @@ App::App() :
|
||||||
mWindowHeight(0),
|
mWindowHeight(0),
|
||||||
mEglDisplay(EGL_NO_DISPLAY),
|
mEglDisplay(EGL_NO_DISPLAY),
|
||||||
mEglContext(EGL_NO_CONTEXT),
|
mEglContext(EGL_NO_CONTEXT),
|
||||||
mEglSurface(EGL_NO_SURFACE),
|
mEglSurface(EGL_NO_SURFACE) {
|
||||||
number_of_contacts(0) {
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// The first method called when the IFrameworkView is being created.
|
// The first method called when the IFrameworkView is being created.
|
||||||
|
@ -271,10 +270,7 @@ void App::pointer_event(Windows::UI::Core::CoreWindow ^ sender, Windows::UI::Cor
|
||||||
last_touch_y[screen_touch->get_index()] = pos.Y;
|
last_touch_y[screen_touch->get_index()] = pos.Y;
|
||||||
|
|
||||||
os->input_event(screen_touch);
|
os->input_event(screen_touch);
|
||||||
if (number_of_contacts > 1)
|
} else {
|
||||||
return;
|
|
||||||
|
|
||||||
}; // fallthrought of sorts
|
|
||||||
|
|
||||||
Ref<InputEventMouseButton> mouse_button;
|
Ref<InputEventMouseButton> mouse_button;
|
||||||
mouse_button.instance();
|
mouse_button.instance();
|
||||||
|
@ -302,17 +298,16 @@ void App::pointer_event(Windows::UI::Core::CoreWindow ^ sender, Windows::UI::Cor
|
||||||
mouse_button->set_pressed(false);
|
mouse_button->set_pressed(false);
|
||||||
os->input_event(mouse_button);
|
os->input_event(mouse_button);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
void App::OnPointerPressed(Windows::UI::Core::CoreWindow ^ sender, Windows::UI::Core::PointerEventArgs ^ args) {
|
void App::OnPointerPressed(Windows::UI::Core::CoreWindow ^ sender, Windows::UI::Core::PointerEventArgs ^ args) {
|
||||||
|
|
||||||
number_of_contacts++;
|
|
||||||
pointer_event(sender, args, true);
|
pointer_event(sender, args, true);
|
||||||
};
|
};
|
||||||
|
|
||||||
void App::OnPointerReleased(Windows::UI::Core::CoreWindow ^ sender, Windows::UI::Core::PointerEventArgs ^ args) {
|
void App::OnPointerReleased(Windows::UI::Core::CoreWindow ^ sender, Windows::UI::Core::PointerEventArgs ^ args) {
|
||||||
|
|
||||||
number_of_contacts--;
|
|
||||||
pointer_event(sender, args, false);
|
pointer_event(sender, args, false);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -351,7 +346,7 @@ void App::OnPointerMoved(Windows::UI::Core::CoreWindow ^ sender, Windows::UI::Co
|
||||||
Windows::UI::Input::PointerPoint ^ point = args->CurrentPoint;
|
Windows::UI::Input::PointerPoint ^ point = args->CurrentPoint;
|
||||||
Windows::Foundation::Point pos = _get_pixel_position(window, point->Position, os);
|
Windows::Foundation::Point pos = _get_pixel_position(window, point->Position, os);
|
||||||
|
|
||||||
if (point->IsInContact && _is_touch(point)) {
|
if (_is_touch(point)) {
|
||||||
|
|
||||||
Ref<InputEventScreenDrag> screen_drag;
|
Ref<InputEventScreenDrag> screen_drag;
|
||||||
screen_drag.instance();
|
screen_drag.instance();
|
||||||
|
@ -361,10 +356,7 @@ void App::OnPointerMoved(Windows::UI::Core::CoreWindow ^ sender, Windows::UI::Co
|
||||||
screen_drag->set_relative(Vector2(screen_drag->get_position().x - last_touch_x[screen_drag->get_index()], screen_drag->get_position().y - last_touch_y[screen_drag->get_index()]));
|
screen_drag->set_relative(Vector2(screen_drag->get_position().x - last_touch_x[screen_drag->get_index()], screen_drag->get_position().y - last_touch_y[screen_drag->get_index()]));
|
||||||
|
|
||||||
os->input_event(screen_drag);
|
os->input_event(screen_drag);
|
||||||
if (number_of_contacts > 1)
|
} else {
|
||||||
return;
|
|
||||||
|
|
||||||
}; // fallthrought of sorts
|
|
||||||
|
|
||||||
// In case the mouse grabbed, MouseMoved will handle this
|
// In case the mouse grabbed, MouseMoved will handle this
|
||||||
if (os->get_mouse_mode() == OS::MouseMode::MOUSE_MODE_CAPTURED)
|
if (os->get_mouse_mode() == OS::MouseMode::MOUSE_MODE_CAPTURED)
|
||||||
|
@ -381,6 +373,7 @@ void App::OnPointerMoved(Windows::UI::Core::CoreWindow ^ sender, Windows::UI::Co
|
||||||
|
|
||||||
os->input_event(mouse_motion);
|
os->input_event(mouse_motion);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void App::OnMouseMoved(MouseDevice ^ mouse_device, MouseEventArgs ^ args) {
|
void App::OnMouseMoved(MouseDevice ^ mouse_device, MouseEventArgs ^ args) {
|
||||||
|
|
||||||
|
|
|
@ -107,7 +107,6 @@ namespace GodotUWP
|
||||||
|
|
||||||
int last_touch_x[32]; // 20 fingers, index 31 reserved for the mouse
|
int last_touch_x[32]; // 20 fingers, index 31 reserved for the mouse
|
||||||
int last_touch_y[32];
|
int last_touch_y[32];
|
||||||
int number_of_contacts;
|
|
||||||
Windows::Foundation::Point last_mouse_pos;
|
Windows::Foundation::Point last_mouse_pos;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -361,6 +361,14 @@ LRESULT OS_Windows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||||
} break;
|
} break;
|
||||||
case WM_MOUSEMOVE: {
|
case WM_MOUSEMOVE: {
|
||||||
|
|
||||||
|
if (input->is_emulating_mouse_from_touch()) {
|
||||||
|
// Universal translation enabled; ignore OS translation
|
||||||
|
LPARAM extra = GetMessageExtraInfo();
|
||||||
|
if (IsPenEvent(extra)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (outside) {
|
if (outside) {
|
||||||
//mouse enter
|
//mouse enter
|
||||||
|
|
||||||
|
@ -386,18 +394,6 @@ LRESULT OS_Windows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||||
// Don't calculate relative mouse movement if we don't have focus in CAPTURED mode.
|
// Don't calculate relative mouse movement if we don't have focus in CAPTURED mode.
|
||||||
if (!window_has_focus && mouse_mode == MOUSE_MODE_CAPTURED)
|
if (!window_has_focus && mouse_mode == MOUSE_MODE_CAPTURED)
|
||||||
break;
|
break;
|
||||||
/*
|
|
||||||
LPARAM extra = GetMessageExtraInfo();
|
|
||||||
if (IsPenEvent(extra)) {
|
|
||||||
|
|
||||||
int idx = extra & 0x7f;
|
|
||||||
_drag_event(idx, uMsg, wParam, lParam);
|
|
||||||
if (idx != 0) {
|
|
||||||
return 0;
|
|
||||||
};
|
|
||||||
// fallthrough for mouse event
|
|
||||||
};
|
|
||||||
*/
|
|
||||||
|
|
||||||
Ref<InputEventMouseMotion> mm;
|
Ref<InputEventMouseMotion> mm;
|
||||||
mm.instance();
|
mm.instance();
|
||||||
|
@ -467,18 +463,13 @@ LRESULT OS_Windows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||||
/*case WM_XBUTTONDOWN:
|
/*case WM_XBUTTONDOWN:
|
||||||
case WM_XBUTTONUP: */ {
|
case WM_XBUTTONUP: */ {
|
||||||
|
|
||||||
/*
|
if (input->is_emulating_mouse_from_touch()) {
|
||||||
|
// Universal translation enabled; ignore OS translation
|
||||||
LPARAM extra = GetMessageExtraInfo();
|
LPARAM extra = GetMessageExtraInfo();
|
||||||
if (IsPenEvent(extra)) {
|
if (IsPenEvent(extra)) {
|
||||||
|
break;
|
||||||
int idx = extra & 0x7f;
|
}
|
||||||
_touch_event(idx, uMsg, wParam, lParam);
|
}
|
||||||
if (idx != 0) {
|
|
||||||
return 0;
|
|
||||||
};
|
|
||||||
// fallthrough for mouse event
|
|
||||||
};
|
|
||||||
*/
|
|
||||||
|
|
||||||
Ref<InputEventMouseButton> mb;
|
Ref<InputEventMouseButton> mb;
|
||||||
mb.instance();
|
mb.instance();
|
||||||
|
|
|
@ -1680,6 +1680,11 @@ void OS_X11::process_xevents() {
|
||||||
if (touch.state.has(index)) // Defensive
|
if (touch.state.has(index)) // Defensive
|
||||||
break;
|
break;
|
||||||
touch.state[index] = pos;
|
touch.state[index] = pos;
|
||||||
|
if (touch.state.size() == 1) {
|
||||||
|
// X11 may send a motion event when a touch gesture begins, that would result
|
||||||
|
// in a spurious mouse motion event being sent to Godot; remember it to be able to filter it out
|
||||||
|
touch.mouse_pos_to_filter = pos;
|
||||||
|
}
|
||||||
input->parse_input_event(st);
|
input->parse_input_event(st);
|
||||||
} else {
|
} else {
|
||||||
if (!touch.state.has(index)) // Defensive
|
if (!touch.state.has(index)) // Defensive
|
||||||
|
@ -1886,6 +1891,18 @@ void OS_X11::process_xevents() {
|
||||||
// to be able to send relative motion events.
|
// to be able to send relative motion events.
|
||||||
Point2i pos(event.xmotion.x, event.xmotion.y);
|
Point2i pos(event.xmotion.x, event.xmotion.y);
|
||||||
|
|
||||||
|
// Avoidance of spurious mouse motion (see handling of touch)
|
||||||
|
bool filter = false;
|
||||||
|
// Adding some tolerance to match better Point2i to Vector2
|
||||||
|
if (touch.state.size() && Vector2(pos).distance_squared_to(touch.mouse_pos_to_filter) < 2) {
|
||||||
|
filter = true;
|
||||||
|
}
|
||||||
|
// Invalidate to avoid filtering a possible legitimate similar event coming later
|
||||||
|
touch.mouse_pos_to_filter = Vector2(1e10, 1e10);
|
||||||
|
if (filter) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if (mouse_mode == MOUSE_MODE_CAPTURED) {
|
if (mouse_mode == MOUSE_MODE_CAPTURED) {
|
||||||
|
|
||||||
if (pos == Point2i(current_videomode.width / 2, current_videomode.height / 2)) {
|
if (pos == Point2i(current_videomode.width / 2, current_videomode.height / 2)) {
|
||||||
|
|
|
@ -127,6 +127,7 @@ class OS_X11 : public OS_Unix {
|
||||||
Vector<int> devices;
|
Vector<int> devices;
|
||||||
XIEventMask event_mask;
|
XIEventMask event_mask;
|
||||||
Map<int, Vector2> state;
|
Map<int, Vector2> state;
|
||||||
|
Vector2 mouse_pos_to_filter;
|
||||||
} touch;
|
} touch;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -33,6 +33,7 @@
|
||||||
#include "editor/editor_node.h"
|
#include "editor/editor_node.h"
|
||||||
#include "io/marshalls.h"
|
#include "io/marshalls.h"
|
||||||
#include "io/resource_loader.h"
|
#include "io/resource_loader.h"
|
||||||
|
#include "main/input_default.h"
|
||||||
#include "message_queue.h"
|
#include "message_queue.h"
|
||||||
#include "node.h"
|
#include "node.h"
|
||||||
#include "os/keyboard.h"
|
#include "os/keyboard.h"
|
||||||
|
@ -620,6 +621,13 @@ void SceneTree::_notification(int p_notification) {
|
||||||
case NOTIFICATION_WM_FOCUS_IN:
|
case NOTIFICATION_WM_FOCUS_IN:
|
||||||
case NOTIFICATION_WM_FOCUS_OUT: {
|
case NOTIFICATION_WM_FOCUS_OUT: {
|
||||||
|
|
||||||
|
if (p_notification == NOTIFICATION_WM_FOCUS_IN) {
|
||||||
|
InputDefault *id = Object::cast_to<InputDefault>(Input::get_singleton());
|
||||||
|
if (id) {
|
||||||
|
id->ensure_touch_mouse_raised();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
get_root()->propagate_notification(p_notification);
|
get_root()->propagate_notification(p_notification);
|
||||||
} break;
|
} break;
|
||||||
case NOTIFICATION_TRANSLATION_CHANGED: {
|
case NOTIFICATION_TRANSLATION_CHANGED: {
|
||||||
|
|
Loading…
Reference in New Issue