Skip to content

Commit

Permalink
Merge pull request #65398 from m4gr3d/cleanup_input_logic_3x
Browse files Browse the repository at this point in the history
  • Loading branch information
akien-mga authored Sep 8, 2022
2 parents 92fa638 + 63df48a commit 973457e
Show file tree
Hide file tree
Showing 12 changed files with 575 additions and 327 deletions.
2 changes: 2 additions & 0 deletions editor/progress_dialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,9 @@ bool ProgressDialog::task_step(const String &p_task, const String &p_state, int
OS::get_singleton()->force_process_input();
}

#ifndef ANDROID_ENABLED
Main::iteration(); // this will not work on a lot of platforms, so it's only meant for the editor
#endif
return cancelled;
}

Expand Down
200 changes: 112 additions & 88 deletions platform/android/android_input_handler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,10 +57,6 @@ void AndroidInputHandler::_set_key_modifier_state(Ref<InputEventWithModifiers> e
ev->set_control(control_mem);
}

void AndroidInputHandler::process_event(Ref<InputEvent> &p_event) {
input->parse_input_event(p_event);
}

void AndroidInputHandler::process_key_event(int p_scancode, int p_physical_scancode, int p_unicode, bool p_pressed) {
Ref<InputEventKey> ev;
ev.instance();
Expand Down Expand Up @@ -104,20 +100,31 @@ void AndroidInputHandler::process_key_event(int p_scancode, int p_physical_scanc
input->parse_input_event(ev);
}

void AndroidInputHandler::process_touch(int p_event, int p_pointer, const Vector<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.instance();
ev->set_index(touch[i].id);
ev->set_pressed(p_pressed);
ev->set_position(touch[i].pos);
input->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.instance();
ev->set_index(touch[i].id);
ev->set_pressed(false);
ev->set_position(touch[i].pos);
input->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++) {
Expand All @@ -126,18 +133,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.instance();
ev->set_index(touch[i].id);
ev->set_pressed(true);
ev->set_position(touch[i].pos);
input->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;
Expand Down Expand Up @@ -166,18 +168,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.instance();
ev->set_index(touch[i].id);
ev->set_pressed(false);
ev->set_position(touch[i].pos);
input->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++) {
Expand Down Expand Up @@ -215,73 +206,102 @@ 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(int buttons_mask, bool p_pressed, bool p_double_click) {
if (!mouse_event_info.valid) {
return;
}

Ref<InputEventMouseButton> ev;
ev.instance();
_set_key_modifier_state(ev);
ev->set_position(mouse_event_info.pos);
ev->set_global_position(mouse_event_info.pos);
ev->set_pressed(p_pressed);
int changed_button_mask = buttons_state ^ buttons_mask;

buttons_state = buttons_mask;

ev->set_button_index(_button_index_from_mask(changed_button_mask));
ev->set_button_mask(buttons_mask);
ev->set_doubleclick(p_double_click);
input->parse_input_event(ev);
hover_prev_pos = mouse_event_info.pos;
}

void AndroidInputHandler::_release_mouse_event_info() {
_parse_mouse_event_info(0, false, false);
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) {
int 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.instance();
_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->parse_input_event(ev);
hover_prev_pos = p_pos;
hover_prev_pos = p_event_pos;
} break;
}
}

void AndroidInputHandler::process_mouse_event(int event_action, int event_android_buttons_mask, Point2 event_pos, float event_vertical_factor, float event_horizontal_factor) {
int 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_BUTTON_RELEASE: {
Ref<InputEventMouseButton> ev;
ev.instance();
_set_key_modifier_state(ev);
ev->set_position(event_pos);
ev->set_global_position(event_pos);
ev->set_pressed(event_action == AMOTION_EVENT_ACTION_BUTTON_PRESS);
int changed_button_mask = buttons_state ^ event_buttons_mask;
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();

buttons_state = event_buttons_mask;
mouse_event_info.valid = true;
mouse_event_info.pos = p_event_pos;
_parse_mouse_event_info(event_buttons_mask, true, p_double_click);
} break;

ev->set_button_index(_button_index_from_mask(changed_button_mask));
ev->set_button_mask(event_buttons_mask);
input->parse_input_event(ev);
case AMOTION_EVENT_ACTION_UP:
case AMOTION_EVENT_ACTION_CANCEL:
case AMOTION_EVENT_ACTION_BUTTON_RELEASE: {
_release_mouse_event_info();
} break;

case AMOTION_EVENT_ACTION_MOVE: {
if (!mouse_event_info.valid) {
return;
}

Ref<InputEventMouseMotion> ev;
ev.instance();
_set_key_modifier_state(ev);
ev->set_position(event_pos);
ev->set_global_position(event_pos);
ev->set_relative(event_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);
ev->set_button_mask(event_buttons_mask);
input->parse_input_event(ev);
hover_prev_pos = event_pos;
mouse_event_info.pos = p_event_pos;
hover_prev_pos = p_event_pos;
} break;

case AMOTION_EVENT_ACTION_SCROLL: {
Ref<InputEventMouseButton> ev;
ev.instance();
_set_key_modifier_state(ev);
ev->set_position(event_pos);
ev->set_global_position(event_pos);
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, BUTTON_WHEEL_UP, event_vertical_factor);
} else if (event_vertical_factor < 0) {
_wheel_button_click(event_buttons_mask, ev, BUTTON_WHEEL_DOWN, -event_vertical_factor);
if (p_delta.y > 0) {
_wheel_button_click(event_buttons_mask, ev, BUTTON_WHEEL_UP, p_delta.y);
} else if (p_delta.y < 0) {
_wheel_button_click(event_buttons_mask, ev, BUTTON_WHEEL_DOWN, -p_delta.y);
}

if (event_horizontal_factor > 0) {
_wheel_button_click(event_buttons_mask, ev, BUTTON_WHEEL_RIGHT, event_horizontal_factor);
} else if (event_horizontal_factor < 0) {
_wheel_button_click(event_buttons_mask, ev, BUTTON_WHEEL_LEFT, -event_horizontal_factor);
if (p_delta.x > 0) {
_wheel_button_click(event_buttons_mask, ev, BUTTON_WHEEL_RIGHT, p_delta.x);
} else if (p_delta.x < 0) {
_wheel_button_click(event_buttons_mask, ev, BUTTON_WHEEL_LEFT, -p_delta.x);
}
} break;
}
Expand All @@ -299,18 +319,22 @@ void AndroidInputHandler::_wheel_button_click(int event_buttons_mask, const Ref<
input->parse_input_event(evdd);
}

void AndroidInputHandler::process_double_tap(int event_android_button_mask, Point2 p_pos) {
int event_button_mask = _android_button_mask_to_godot_button_mask(event_android_button_mask);
Ref<InputEventMouseButton> ev;
ev.instance();
_set_key_modifier_state(ev);
ev->set_position(p_pos);
ev->set_global_position(p_pos);
ev->set_pressed(event_button_mask != 0);
ev->set_button_index(_button_index_from_mask(event_button_mask));
ev->set_button_mask(event_button_mask);
ev->set_doubleclick(true);
input->parse_input_event(ev);
void AndroidInputHandler::process_magnify(Point2 p_pos, float p_factor) {
Ref<InputEventMagnifyGesture> magnify_event;
magnify_event.instance();
_set_key_modifier_state(magnify_event);
magnify_event->set_position(p_pos);
magnify_event->set_factor(p_factor);
input->parse_input_event(magnify_event);
}

void AndroidInputHandler::process_pan(Point2 p_pos, Vector2 p_delta) {
Ref<InputEventPanGesture> pan_event;
pan_event.instance();
_set_key_modifier_state(pan_event);
pan_event->set_position(p_pos);
pan_event->set_delta(p_delta);
input->parse_input_event(pan_event);
}

int AndroidInputHandler::_button_index_from_mask(int button_mask) {
Expand Down
23 changes: 18 additions & 5 deletions platform/android/android_input_handler.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,11 @@ class AndroidInputHandler {
Point2 pos;
};

struct MouseEventInfo {
bool valid = false;
Point2 pos;
};

enum {
JOY_EVENT_BUTTON = 0,
JOY_EVENT_AXIS = 1,
Expand All @@ -61,6 +66,7 @@ class AndroidInputHandler {

private:
Vector<TouchPos> touch;
MouseEventInfo mouse_event_info;
Point2 hover_prev_pos; // needed to calculate the relative position on hover events

bool alt_mem = false;
Expand All @@ -80,14 +86,21 @@ class AndroidInputHandler {

void _wheel_button_click(int event_buttons_mask, const Ref<InputEventMouseButton> &ev, int wheel_button, float factor);

void _parse_mouse_event_info(int buttons_mask, bool p_pressed, bool p_double_click);

void _release_mouse_event_info();

void _parse_all_touch(bool p_pressed);

void _release_all_touch();

public:
void process_event(Ref<InputEvent> &p_event);
void process_joy_event(const JoypadEvent &p_event);
void process_key_event(int p_scancode, int p_physical_scancode, int p_unicode, bool p_pressed);
void process_touch(int p_event, int p_pointer, const Vector<TouchPos> &p_points);
void process_hover(int p_type, Point2 p_pos);
void process_mouse_event(int event_action, int event_android_buttons_mask, Point2 event_pos, float event_vertical_factor, float event_horizontal_factor);
void process_double_tap(int event_android_button_mask, Point2 p_pos);
void process_mouse_event(int p_event_action, int p_event_android_buttons_mask, Point2 p_event_pos, Vector2 p_delta, bool p_double_click);
void process_touch_event(int p_event, int p_pointer, const Vector<TouchPos> &p_points);
void process_magnify(Point2 p_pos, float p_factor);
void process_pan(Point2 p_pos, Vector2 p_delta);
void joy_connection_changed(int p_device, bool p_connected, String p_name);
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,12 @@ open class GodotEditor : FullScreenGodotApp() {
}

super.onCreate(savedInstanceState)

// Enable long press, panning and scaling gestures
godotFragment?.mView?.inputHandler?.apply {
enableLongPress(enableLongPressGestures())
enablePanningAndScalingGestures(enablePanAndScaleGestures())
}
}

private fun updateCommandLineParams(args: Array<String>?) {
Expand Down Expand Up @@ -148,6 +154,16 @@ open class GodotEditor : FullScreenGodotApp() {
*/
protected open fun overrideOrientationRequest() = true

/**
* Enable long press gestures for the Godot Android editor.
*/
protected open fun enableLongPressGestures() = true

/**
* Enable pan and scale gestures for the Godot Android editor.
*/
protected open fun enablePanAndScaleGestures() = true

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
// Check if we got the MANAGE_EXTERNAL_STORAGE permission
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,8 @@ package org.godotengine.editor
*/
class GodotGame : GodotEditor() {
override fun overrideOrientationRequest() = false

override fun enableLongPressGestures() = false

override fun enablePanAndScaleGestures() = false
}
Loading

0 comments on commit 973457e

Please sign in to comment.