Merge pull request #77498 from m4gr3d/improve_touchpad_mouse_support_main
Improve touchpad and mouse support for the Android editor
This commit is contained in:
commit
e730a5b59f
7 changed files with 63 additions and 17 deletions
|
@ -166,8 +166,10 @@ public class GodotGLRenderView extends GLSurfaceView implements GodotRenderView
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void requestPointerCapture() {
|
public void requestPointerCapture() {
|
||||||
super.requestPointerCapture();
|
if (canCapturePointer()) {
|
||||||
inputHandler.onPointerCaptureChange(true);
|
super.requestPointerCapture();
|
||||||
|
inputHandler.onPointerCaptureChange(true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -51,4 +51,8 @@ public interface GodotRenderView {
|
||||||
void configurePointerIcon(int pointerType, String imagePath, float hotSpotX, float hotSpotY);
|
void configurePointerIcon(int pointerType, String imagePath, float hotSpotX, float hotSpotY);
|
||||||
|
|
||||||
void setPointerIcon(int pointerType);
|
void setPointerIcon(int pointerType);
|
||||||
|
|
||||||
|
default boolean canCapturePointer() {
|
||||||
|
return getInputHandler().canCapturePointer();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -134,8 +134,10 @@ public class GodotVulkanRenderView extends VkSurfaceView implements GodotRenderV
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void requestPointerCapture() {
|
public void requestPointerCapture() {
|
||||||
super.requestPointerCapture();
|
if (canCapturePointer()) {
|
||||||
mInputHandler.onPointerCaptureChange(true);
|
super.requestPointerCapture();
|
||||||
|
mInputHandler.onPointerCaptureChange(true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -227,16 +227,14 @@ internal class GodotGestureHandler : SimpleOnGestureListener(), OnScaleGestureLi
|
||||||
)
|
)
|
||||||
dragInProgress = false
|
dragInProgress = false
|
||||||
}
|
}
|
||||||
return true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dragInProgress = true
|
|
||||||
|
|
||||||
val x = terminusEvent.x
|
val x = terminusEvent.x
|
||||||
val y = terminusEvent.y
|
val y = terminusEvent.y
|
||||||
if (terminusEvent.pointerCount >= 2 && panningAndScalingEnabled && !pointerCaptureInProgress) {
|
if (terminusEvent.pointerCount >= 2 && panningAndScalingEnabled && !pointerCaptureInProgress) {
|
||||||
GodotLib.pan(x, y, distanceX / 5f, distanceY / 5f)
|
GodotLib.pan(x, y, distanceX / 5f, distanceY / 5f)
|
||||||
} else {
|
} else if (!scaleInProgress){
|
||||||
|
dragInProgress = true
|
||||||
GodotInputHandler.handleMotionEvent(terminusEvent)
|
GodotInputHandler.handleMotionEvent(terminusEvent)
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
|
@ -246,11 +244,14 @@ internal class GodotGestureHandler : SimpleOnGestureListener(), OnScaleGestureLi
|
||||||
if (!panningAndScalingEnabled || pointerCaptureInProgress) {
|
if (!panningAndScalingEnabled || pointerCaptureInProgress) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
GodotLib.magnify(
|
|
||||||
detector.focusX,
|
if (detector.scaleFactor >= 0.8f && detector.scaleFactor != 1f && detector.scaleFactor <= 1.2f) {
|
||||||
detector.focusY,
|
GodotLib.magnify(
|
||||||
detector.scaleFactor
|
detector.focusX,
|
||||||
)
|
detector.focusY,
|
||||||
|
detector.scaleFactor
|
||||||
|
)
|
||||||
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -66,6 +66,11 @@ public class GodotInputHandler implements InputManager.InputDeviceListener {
|
||||||
private final ScaleGestureDetector scaleGestureDetector;
|
private final ScaleGestureDetector scaleGestureDetector;
|
||||||
private final GodotGestureHandler godotGestureHandler;
|
private final GodotGestureHandler godotGestureHandler;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used to decide whether mouse capture can be enabled.
|
||||||
|
*/
|
||||||
|
private int lastSeenToolType = MotionEvent.TOOL_TYPE_UNKNOWN;
|
||||||
|
|
||||||
public GodotInputHandler(GodotRenderView godotView) {
|
public GodotInputHandler(GodotRenderView godotView) {
|
||||||
final Context context = godotView.getView().getContext();
|
final Context context = godotView.getView().getContext();
|
||||||
mRenderView = godotView;
|
mRenderView = godotView;
|
||||||
|
@ -105,6 +110,10 @@ public class GodotInputHandler implements InputManager.InputDeviceListener {
|
||||||
return (source & InputDevice.SOURCE_JOYSTICK) == InputDevice.SOURCE_JOYSTICK || (source & InputDevice.SOURCE_DPAD) == InputDevice.SOURCE_DPAD || (source & InputDevice.SOURCE_GAMEPAD) == InputDevice.SOURCE_GAMEPAD;
|
return (source & InputDevice.SOURCE_JOYSTICK) == InputDevice.SOURCE_JOYSTICK || (source & InputDevice.SOURCE_DPAD) == InputDevice.SOURCE_DPAD || (source & InputDevice.SOURCE_GAMEPAD) == InputDevice.SOURCE_GAMEPAD;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean canCapturePointer() {
|
||||||
|
return lastSeenToolType == MotionEvent.TOOL_TYPE_MOUSE;
|
||||||
|
}
|
||||||
|
|
||||||
public void onPointerCaptureChange(boolean hasCapture) {
|
public void onPointerCaptureChange(boolean hasCapture) {
|
||||||
godotGestureHandler.onPointerCaptureChange(hasCapture);
|
godotGestureHandler.onPointerCaptureChange(hasCapture);
|
||||||
}
|
}
|
||||||
|
@ -174,6 +183,8 @@ public class GodotInputHandler implements InputManager.InputDeviceListener {
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean onTouchEvent(final MotionEvent event) {
|
public boolean onTouchEvent(final MotionEvent event) {
|
||||||
|
lastSeenToolType = event.getToolType(0);
|
||||||
|
|
||||||
this.scaleGestureDetector.onTouchEvent(event);
|
this.scaleGestureDetector.onTouchEvent(event);
|
||||||
if (this.gestureDetector.onTouchEvent(event)) {
|
if (this.gestureDetector.onTouchEvent(event)) {
|
||||||
// The gesture detector has handled the event.
|
// The gesture detector has handled the event.
|
||||||
|
@ -198,6 +209,8 @@ public class GodotInputHandler implements InputManager.InputDeviceListener {
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean onGenericMotionEvent(MotionEvent event) {
|
public boolean onGenericMotionEvent(MotionEvent event) {
|
||||||
|
lastSeenToolType = event.getToolType(0);
|
||||||
|
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && gestureDetector.onGenericMotionEvent(event)) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && gestureDetector.onGenericMotionEvent(event)) {
|
||||||
// The gesture detector has handled the event.
|
// The gesture detector has handled the event.
|
||||||
return true;
|
return true;
|
||||||
|
@ -471,15 +484,27 @@ public class GodotInputHandler implements InputManager.InputDeviceListener {
|
||||||
}
|
}
|
||||||
|
|
||||||
static boolean handleMouseEvent(int eventAction, int buttonsMask, float x, float y, float deltaX, float deltaY, boolean doubleClick, boolean sourceMouseRelative) {
|
static boolean handleMouseEvent(int eventAction, int buttonsMask, float x, float y, float deltaX, float deltaY, boolean doubleClick, boolean sourceMouseRelative) {
|
||||||
|
// Fix the buttonsMask
|
||||||
|
switch (eventAction) {
|
||||||
|
case MotionEvent.ACTION_CANCEL:
|
||||||
|
case MotionEvent.ACTION_UP:
|
||||||
|
// Zero-up the button state
|
||||||
|
buttonsMask = 0;
|
||||||
|
break;
|
||||||
|
case MotionEvent.ACTION_DOWN:
|
||||||
|
case MotionEvent.ACTION_MOVE:
|
||||||
|
if (buttonsMask == 0) {
|
||||||
|
buttonsMask = MotionEvent.BUTTON_PRIMARY;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
// We don't handle ACTION_BUTTON_PRESS and ACTION_BUTTON_RELEASE events as they typically
|
// We don't handle ACTION_BUTTON_PRESS and ACTION_BUTTON_RELEASE events as they typically
|
||||||
// follow ACTION_DOWN and ACTION_UP events. As such, handling them would result in duplicate
|
// follow ACTION_DOWN and ACTION_UP events. As such, handling them would result in duplicate
|
||||||
// stream of events to the engine.
|
// stream of events to the engine.
|
||||||
switch (eventAction) {
|
switch (eventAction) {
|
||||||
case MotionEvent.ACTION_CANCEL:
|
case MotionEvent.ACTION_CANCEL:
|
||||||
case MotionEvent.ACTION_UP:
|
case MotionEvent.ACTION_UP:
|
||||||
// Zero-up the button state
|
|
||||||
buttonsMask = 0;
|
|
||||||
// FALL THROUGH
|
|
||||||
case MotionEvent.ACTION_DOWN:
|
case MotionEvent.ACTION_DOWN:
|
||||||
case MotionEvent.ACTION_HOVER_ENTER:
|
case MotionEvent.ACTION_HOVER_ENTER:
|
||||||
case MotionEvent.ACTION_HOVER_EXIT:
|
case MotionEvent.ACTION_HOVER_EXIT:
|
||||||
|
|
|
@ -49,6 +49,8 @@ GodotJavaViewWrapper::GodotJavaViewWrapper(jobject godot_view) {
|
||||||
_request_pointer_capture = env->GetMethodID(_cls, "requestPointerCapture", "()V");
|
_request_pointer_capture = env->GetMethodID(_cls, "requestPointerCapture", "()V");
|
||||||
_release_pointer_capture = env->GetMethodID(_cls, "releasePointerCapture", "()V");
|
_release_pointer_capture = env->GetMethodID(_cls, "releasePointerCapture", "()V");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_can_capture_pointer = env->GetMethodID(_cls, "canCapturePointer", "()Z");
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GodotJavaViewWrapper::can_update_pointer_icon() const {
|
bool GodotJavaViewWrapper::can_update_pointer_icon() const {
|
||||||
|
@ -56,7 +58,16 @@ bool GodotJavaViewWrapper::can_update_pointer_icon() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GodotJavaViewWrapper::can_capture_pointer() const {
|
bool GodotJavaViewWrapper::can_capture_pointer() const {
|
||||||
return _request_pointer_capture != nullptr && _release_pointer_capture != nullptr;
|
// We can capture the pointer if the other jni capture method ids are initialized,
|
||||||
|
// and GodotView#canCapturePointer() returns true.
|
||||||
|
if (_request_pointer_capture != nullptr && _release_pointer_capture != nullptr && _can_capture_pointer != nullptr) {
|
||||||
|
JNIEnv *env = get_jni_env();
|
||||||
|
ERR_FAIL_NULL_V(env, false);
|
||||||
|
|
||||||
|
return env->CallBooleanMethod(_godot_view, _can_capture_pointer);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GodotJavaViewWrapper::request_pointer_capture() {
|
void GodotJavaViewWrapper::request_pointer_capture() {
|
||||||
|
|
|
@ -44,6 +44,7 @@ private:
|
||||||
|
|
||||||
jobject _godot_view;
|
jobject _godot_view;
|
||||||
|
|
||||||
|
jmethodID _can_capture_pointer = 0;
|
||||||
jmethodID _request_pointer_capture = 0;
|
jmethodID _request_pointer_capture = 0;
|
||||||
jmethodID _release_pointer_capture = 0;
|
jmethodID _release_pointer_capture = 0;
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue