Cleanup the Android input logic implementation

This commit is contained in:
Fredia Huya-Kouadio 2022-08-14 23:07:43 -07:00
parent 337e4d185a
commit 1b3511ad49
10 changed files with 693 additions and 356 deletions

View file

@ -118,20 +118,31 @@ void AndroidInputHandler::process_key_event(int p_keycode, int p_physical_keycod
Input::get_singleton()->parse_input_event(ev);
}
void AndroidInputHandler::process_touch(int p_event, int p_pointer, const Vector<AndroidInputHandler::TouchPos> &p_points) {
void AndroidInputHandler::_parse_all_touch(bool p_pressed) {
if (touch.size()) {
//end all if exist
for (int i = 0; i < touch.size(); i++) {
Ref<InputEventScreenTouch> ev;
ev.instantiate();
ev->set_index(touch[i].id);
ev->set_pressed(p_pressed);
ev->set_position(touch[i].pos);
Input::get_singleton()->parse_input_event(ev);
}
}
}
void AndroidInputHandler::_release_all_touch() {
_parse_all_touch(false);
touch.clear();
}
void AndroidInputHandler::process_touch_event(int p_event, int p_pointer, const Vector<TouchPos> &p_points) {
switch (p_event) {
case AMOTION_EVENT_ACTION_DOWN: { //gesture begin
if (touch.size()) {
//end all if exist
for (int i = 0; i < touch.size(); i++) {
Ref<InputEventScreenTouch> ev;
ev.instantiate();
ev->set_index(touch[i].id);
ev->set_pressed(false);
ev->set_position(touch[i].pos);
Input::get_singleton()->parse_input_event(ev);
}
}
// Release any remaining touches or mouse event
_release_mouse_event_info();
_release_all_touch();
touch.resize(p_points.size());
for (int i = 0; i < p_points.size(); i++) {
@ -140,18 +151,13 @@ void AndroidInputHandler::process_touch(int p_event, int p_pointer, const Vector
}
//send touch
for (int i = 0; i < touch.size(); i++) {
Ref<InputEventScreenTouch> ev;
ev.instantiate();
ev->set_index(touch[i].id);
ev->set_pressed(true);
ev->set_position(touch[i].pos);
Input::get_singleton()->parse_input_event(ev);
}
_parse_all_touch(true);
} break;
case AMOTION_EVENT_ACTION_MOVE: { //motion
ERR_FAIL_COND(touch.size() != p_points.size());
if (touch.size() != p_points.size()) {
return;
}
for (int i = 0; i < touch.size(); i++) {
int idx = -1;
@ -180,18 +186,7 @@ void AndroidInputHandler::process_touch(int p_event, int p_pointer, const Vector
} break;
case AMOTION_EVENT_ACTION_CANCEL:
case AMOTION_EVENT_ACTION_UP: { //release
if (touch.size()) {
//end all if exist
for (int i = 0; i < touch.size(); i++) {
Ref<InputEventScreenTouch> ev;
ev.instantiate();
ev->set_index(touch[i].id);
ev->set_pressed(false);
ev->set_position(touch[i].pos);
Input::get_singleton()->parse_input_event(ev);
}
touch.clear();
}
_release_all_touch();
} break;
case AMOTION_EVENT_ACTION_POINTER_DOWN: { // add touch
for (int i = 0; i < p_points.size(); i++) {
@ -229,88 +224,118 @@ void AndroidInputHandler::process_touch(int p_event, int p_pointer, const Vector
}
}
void AndroidInputHandler::process_hover(int p_type, Point2 p_pos) {
// https://developer.android.com/reference/android/view/MotionEvent.html#ACTION_HOVER_ENTER
switch (p_type) {
void AndroidInputHandler::_parse_mouse_event_info(MouseButton event_buttons_mask, bool p_pressed, bool p_double_click, bool p_source_mouse_relative) {
if (!mouse_event_info.valid) {
return;
}
Ref<InputEventMouseButton> ev;
ev.instantiate();
_set_key_modifier_state(ev);
if (p_source_mouse_relative) {
ev->set_position(hover_prev_pos);
ev->set_global_position(hover_prev_pos);
} else {
ev->set_position(mouse_event_info.pos);
ev->set_global_position(mouse_event_info.pos);
hover_prev_pos = mouse_event_info.pos;
}
ev->set_pressed(p_pressed);
MouseButton changed_button_mask = MouseButton(buttons_state ^ event_buttons_mask);
buttons_state = event_buttons_mask;
ev->set_button_index(_button_index_from_mask(changed_button_mask));
ev->set_button_mask(event_buttons_mask);
ev->set_double_click(p_double_click);
Input::get_singleton()->parse_input_event(ev);
}
void AndroidInputHandler::_release_mouse_event_info(bool p_source_mouse_relative) {
_parse_mouse_event_info(MouseButton::NONE, false, false, p_source_mouse_relative);
mouse_event_info.valid = false;
}
void AndroidInputHandler::process_mouse_event(int p_event_action, int p_event_android_buttons_mask, Point2 p_event_pos, Vector2 p_delta, bool p_double_click, bool p_source_mouse_relative) {
MouseButton event_buttons_mask = _android_button_mask_to_godot_button_mask(p_event_android_buttons_mask);
switch (p_event_action) {
case AMOTION_EVENT_ACTION_HOVER_MOVE: // hover move
case AMOTION_EVENT_ACTION_HOVER_ENTER: // hover enter
case AMOTION_EVENT_ACTION_HOVER_EXIT: { // hover exit
// https://developer.android.com/reference/android/view/MotionEvent.html#ACTION_HOVER_ENTER
Ref<InputEventMouseMotion> ev;
ev.instantiate();
_set_key_modifier_state(ev);
ev->set_position(p_pos);
ev->set_global_position(p_pos);
ev->set_relative(p_pos - hover_prev_pos);
ev->set_position(p_event_pos);
ev->set_global_position(p_event_pos);
ev->set_relative(p_event_pos - hover_prev_pos);
Input::get_singleton()->parse_input_event(ev);
hover_prev_pos = p_pos;
hover_prev_pos = p_event_pos;
} break;
}
}
void AndroidInputHandler::process_mouse_event(int input_device, int event_action, int event_android_buttons_mask, Point2 event_pos, float event_vertical_factor, float event_horizontal_factor) {
MouseButton event_buttons_mask = _android_button_mask_to_godot_button_mask(event_android_buttons_mask);
switch (event_action) {
case AMOTION_EVENT_ACTION_BUTTON_PRESS:
case AMOTION_EVENT_ACTION_DOWN:
case AMOTION_EVENT_ACTION_BUTTON_PRESS: {
// Release any remaining touches or mouse event
_release_mouse_event_info();
_release_all_touch();
mouse_event_info.valid = true;
mouse_event_info.pos = p_event_pos;
_parse_mouse_event_info(event_buttons_mask, true, p_double_click, p_source_mouse_relative);
} break;
case AMOTION_EVENT_ACTION_UP:
case AMOTION_EVENT_ACTION_CANCEL:
case AMOTION_EVENT_ACTION_BUTTON_RELEASE: {
Ref<InputEventMouseButton> ev;
ev.instantiate();
_set_key_modifier_state(ev);
if ((input_device & AINPUT_SOURCE_MOUSE) == AINPUT_SOURCE_MOUSE) {
ev->set_position(event_pos);
ev->set_global_position(event_pos);
} else {
ev->set_position(hover_prev_pos);
ev->set_global_position(hover_prev_pos);
}
ev->set_pressed(event_action == AMOTION_EVENT_ACTION_BUTTON_PRESS);
MouseButton changed_button_mask = MouseButton(buttons_state ^ event_buttons_mask);
buttons_state = event_buttons_mask;
ev->set_button_index(_button_index_from_mask(changed_button_mask));
ev->set_button_mask(event_buttons_mask);
Input::get_singleton()->parse_input_event(ev);
_release_mouse_event_info(p_source_mouse_relative);
} break;
case AMOTION_EVENT_ACTION_MOVE: {
if (!mouse_event_info.valid) {
return;
}
Ref<InputEventMouseMotion> ev;
ev.instantiate();
_set_key_modifier_state(ev);
if ((input_device & AINPUT_SOURCE_MOUSE) == AINPUT_SOURCE_MOUSE) {
ev->set_position(event_pos);
ev->set_global_position(event_pos);
ev->set_relative(event_pos - hover_prev_pos);
hover_prev_pos = event_pos;
} else {
if (p_source_mouse_relative) {
ev->set_position(hover_prev_pos);
ev->set_global_position(hover_prev_pos);
ev->set_relative(event_pos);
ev->set_relative(p_event_pos);
} else {
ev->set_position(p_event_pos);
ev->set_global_position(p_event_pos);
ev->set_relative(p_event_pos - hover_prev_pos);
mouse_event_info.pos = p_event_pos;
hover_prev_pos = p_event_pos;
}
ev->set_button_mask(event_buttons_mask);
Input::get_singleton()->parse_input_event(ev);
} break;
case AMOTION_EVENT_ACTION_SCROLL: {
Ref<InputEventMouseButton> ev;
ev.instantiate();
if ((input_device & AINPUT_SOURCE_MOUSE) == AINPUT_SOURCE_MOUSE) {
ev->set_position(event_pos);
ev->set_global_position(event_pos);
} else {
_set_key_modifier_state(ev);
if (p_source_mouse_relative) {
ev->set_position(hover_prev_pos);
ev->set_global_position(hover_prev_pos);
} else {
ev->set_position(p_event_pos);
ev->set_global_position(p_event_pos);
}
ev->set_pressed(true);
buttons_state = event_buttons_mask;
if (event_vertical_factor > 0) {
_wheel_button_click(event_buttons_mask, ev, MouseButton::WHEEL_UP, event_vertical_factor);
} else if (event_vertical_factor < 0) {
_wheel_button_click(event_buttons_mask, ev, MouseButton::WHEEL_DOWN, -event_vertical_factor);
if (p_delta.y > 0) {
_wheel_button_click(event_buttons_mask, ev, MouseButton::WHEEL_UP, p_delta.y);
} else if (p_delta.y < 0) {
_wheel_button_click(event_buttons_mask, ev, MouseButton::WHEEL_DOWN, -p_delta.y);
}
if (event_horizontal_factor > 0) {
_wheel_button_click(event_buttons_mask, ev, MouseButton::WHEEL_RIGHT, event_horizontal_factor);
} else if (event_horizontal_factor < 0) {
_wheel_button_click(event_buttons_mask, ev, MouseButton::WHEEL_LEFT, -event_horizontal_factor);
if (p_delta.x > 0) {
_wheel_button_click(event_buttons_mask, ev, MouseButton::WHEEL_RIGHT, p_delta.x);
} else if (p_delta.x < 0) {
_wheel_button_click(event_buttons_mask, ev, MouseButton::WHEEL_LEFT, -p_delta.x);
}
} break;
}
@ -329,18 +354,22 @@ void AndroidInputHandler::_wheel_button_click(MouseButton event_buttons_mask, co
Input::get_singleton()->parse_input_event(evdd);
}
void AndroidInputHandler::process_double_tap(int event_android_button_mask, Point2 p_pos) {
MouseButton event_button_mask = _android_button_mask_to_godot_button_mask(event_android_button_mask);
Ref<InputEventMouseButton> ev;
ev.instantiate();
_set_key_modifier_state(ev);
ev->set_position(p_pos);
ev->set_global_position(p_pos);
ev->set_pressed(event_button_mask != MouseButton::NONE);
ev->set_button_index(_button_index_from_mask(event_button_mask));
ev->set_button_mask(event_button_mask);
ev->set_double_click(true);
Input::get_singleton()->parse_input_event(ev);
void AndroidInputHandler::process_magnify(Point2 p_pos, float p_factor) {
Ref<InputEventMagnifyGesture> magnify_event;
magnify_event.instantiate();
_set_key_modifier_state(magnify_event);
magnify_event->set_position(p_pos);
magnify_event->set_factor(p_factor);
Input::get_singleton()->parse_input_event(magnify_event);
}
void AndroidInputHandler::process_pan(Point2 p_pos, Vector2 p_delta) {
Ref<InputEventPanGesture> pan_event;
pan_event.instantiate();
_set_key_modifier_state(pan_event);
pan_event->set_position(p_pos);
pan_event->set_delta(p_delta);
Input::get_singleton()->parse_input_event(pan_event);
}
MouseButton AndroidInputHandler::_button_index_from_mask(MouseButton button_mask) {