From a1bf032939185c17d813d84f935c5a8dc7c40b65 Mon Sep 17 00:00:00 2001 From: artdeell Date: Fri, 12 Jan 2024 23:23:55 +0300 Subject: [PATCH] Feat[touch_input]: Begin reimplementing touch input --- .../kdt/pojavlaunch/MinecraftGLSurface.java | 105 +++-------- .../java/net/kdt/pojavlaunch/Touchpad.java | 2 +- .../mouse/InGUIEventProcessor.java | 68 +++++++ .../mouse/IngameEventProcessor.java | 175 ++++++++++++++++++ .../customcontrols/mouse/PointerTracker.java | 39 ++++ .../mouse/TouchEventProcessor.java | 8 + 6 files changed, 312 insertions(+), 85 deletions(-) create mode 100644 app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/mouse/InGUIEventProcessor.java create mode 100644 app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/mouse/IngameEventProcessor.java create mode 100644 app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/mouse/PointerTracker.java create mode 100644 app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/mouse/TouchEventProcessor.java diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/MinecraftGLSurface.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/MinecraftGLSurface.java index 892b9c962d..bcbdcef49b 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/MinecraftGLSurface.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/MinecraftGLSurface.java @@ -1,9 +1,7 @@ package net.kdt.pojavlaunch; import static net.kdt.pojavlaunch.MainActivity.touchCharInput; -import static net.kdt.pojavlaunch.prefs.LauncherPreferences.PREF_DISABLE_SWAP_HAND; import static net.kdt.pojavlaunch.utils.MCOptionUtils.getMcScale; -import static org.lwjgl.glfw.CallbackBridge.sendKeyPress; import static org.lwjgl.glfw.CallbackBridge.sendMouseButton; import static org.lwjgl.glfw.CallbackBridge.windowHeight; import static org.lwjgl.glfw.CallbackBridge.windowWidth; @@ -12,9 +10,6 @@ import android.app.Activity; import android.content.Context; import android.graphics.SurfaceTexture; -import android.os.Handler; -import android.os.Looper; -import android.os.Message; import android.util.AttributeSet; import android.util.Log; import android.view.InputDevice; @@ -32,10 +27,12 @@ import net.kdt.pojavlaunch.customcontrols.ControlLayout; import net.kdt.pojavlaunch.customcontrols.gamepad.Gamepad; +import net.kdt.pojavlaunch.customcontrols.mouse.InGUIEventProcessor; +import net.kdt.pojavlaunch.customcontrols.mouse.IngameEventProcessor; +import net.kdt.pojavlaunch.customcontrols.mouse.TouchEventProcessor; import net.kdt.pojavlaunch.prefs.LauncherPreferences; import net.kdt.pojavlaunch.utils.JREUtils; import net.kdt.pojavlaunch.utils.MCOptionUtils; -import net.kdt.pojavlaunch.utils.MathUtils; import org.lwjgl.glfw.CallbackBridge; @@ -69,69 +66,18 @@ public class MinecraftGLSurface extends View implements GrabListener { /* Sensitivity, adjusted according to screen size */ private final double mSensitivityFactor = (1.4 * (1080f/ Tools.getDisplayMetrics((Activity) getContext()).heightPixels)); /* Use to detect simple and double taps */ - private final TapDetector mSingleTapDetector = new TapDetector(1, TapDetector.DETECTION_METHOD_BOTH); - private final TapDetector mDoubleTapDetector = new TapDetector(2, TapDetector.DETECTION_METHOD_DOWN); - /* MC GUI scale, listened by MCOptionUtils */ - private int mGuiScale; - @SuppressWarnings("FieldCanBeLocal") // it can't, otherwise the weak reference will disappear - private final MCOptionUtils.MCOptionListener mGuiScaleListener = () -> mGuiScale = getMcScale(); + //private final TapDetector mSingleTapDetector = new TapDetector(1, TapDetector.DETECTION_METHOD_BOTH); + //private final TapDetector mDoubleTapDetector = new TapDetector(2, TapDetector.DETECTION_METHOD_DOWN); + /* Surface ready listener, used by the activity to launch minecraft */ SurfaceReadyListener mSurfaceReadyListener = null; final Object mSurfaceReadyListenerLock = new Object(); /* View holding the surface, either a SurfaceView or a TextureView */ View mSurface; - /* List of hotbarKeys, used when clicking on the hotbar */ - private static final int[] HOTBAR_KEYS = { - LwjglGlfwKeycode.GLFW_KEY_1, LwjglGlfwKeycode.GLFW_KEY_2, LwjglGlfwKeycode.GLFW_KEY_3, - LwjglGlfwKeycode.GLFW_KEY_4, LwjglGlfwKeycode.GLFW_KEY_5, LwjglGlfwKeycode.GLFW_KEY_6, - LwjglGlfwKeycode.GLFW_KEY_7, LwjglGlfwKeycode.GLFW_KEY_8, LwjglGlfwKeycode.GLFW_KEY_9}; - /* Last hotbar button (0-9) registered */ - private int mLastHotbarKey = -1; - /* Events can start with only a move instead of an pointerDown due to mouse passthrough */ - private boolean mShouldBeDown = false; - /* When fingers are really near to each other, it tends to either swap or remove a pointer ! */ - private int mLastPointerCount = 0; - /* Previous MotionEvent position, not scale */ - private float mPrevX, mPrevY; - /* PointerID used for the moving camera */ - private int mCurrentPointerID = -1000; - /* Initial first pointer positions non-scaled, used to test touch sloppiness */ - private float mInitialX, mInitialY; - /* Last first pointer positions non-scaled, used to scroll distance */ - private float mScrollLastInitialX, mScrollLastInitialY; - /* How much distance a finger has to go for touch sloppiness to be disabled */ - public static final int FINGER_STILL_THRESHOLD = (int) Tools.dpToPx(9); - /* How much distance a finger has to go to scroll */ - public static final int FINGER_SCROLL_THRESHOLD = (int) Tools.dpToPx(6); - /* Whether the button was triggered, used by the handler */ - private static boolean triggeredLeftMouseButton = false; - /* Handle hotbar throw button and mouse mining button */ - public static final int MSG_LEFT_MOUSE_BUTTON_CHECK = 1028; - public static final int MSG_DROP_ITEM_BUTTON_CHECK = 1029; - private final Handler mHandler = new Handler(Looper.getMainLooper()) { - public void handleMessage(Message msg) { - if(msg.what == MSG_LEFT_MOUSE_BUTTON_CHECK) { - if (LauncherPreferences.PREF_DISABLE_GESTURES) return; - float x = CallbackBridge.mouseX; - float y = CallbackBridge.mouseY; - if (CallbackBridge.isGrabbing() && - MathUtils.dist(x, y, mInitialX, mInitialY) < FINGER_STILL_THRESHOLD) { - triggeredLeftMouseButton = true; - sendMouseButton(LwjglGlfwKeycode.GLFW_MOUSE_BUTTON_LEFT, true); - } - return; - } - if(msg.what == MSG_DROP_ITEM_BUTTON_CHECK) { - if(CallbackBridge.isGrabbing()){ - sendKeyPress(LwjglGlfwKeycode.GLFW_KEY_Q); - mHandler.sendEmptyMessageDelayed(MSG_DROP_ITEM_BUTTON_CHECK, 600); - } - } - } - }; - - + private final TouchEventProcessor mIngameProcessor = new IngameEventProcessor(mScaleFactor, mSensitivityFactor); + private final TouchEventProcessor mInGUIProcessor = new InGUIEventProcessor(mScaleFactor); + private boolean mLastGrabState = false; public MinecraftGLSurface(Context context) { this(context, null); @@ -140,8 +86,6 @@ public MinecraftGLSurface(Context context) { public MinecraftGLSurface(Context context, AttributeSet attributeSet) { super(context, attributeSet); setFocusable(true); - - MCOptionUtils.addMCOptionListener(mGuiScaleListener); } /** Initialize the view and all its settings @@ -241,7 +185,7 @@ public boolean onTouchEvent(MotionEvent e) { //Getting scaled position from the event /* Tells if a double tap happened [MOUSE GRAB ONLY]. Doesn't tell where though. */ - if(!CallbackBridge.isGrabbing()) { + /*if(!CallbackBridge.isGrabbing()) { CallbackBridge.mouseX = (e.getX() * mScaleFactor); CallbackBridge.mouseY = (e.getY() * mScaleFactor); //One android click = one MC click @@ -393,6 +337,17 @@ public boolean onTouchEvent(MotionEvent e) { mLastPointerCount = e.getPointerCount(); return true; + */ + boolean isGrabbing = CallbackBridge.isGrabbing(); + if(mLastGrabState != isGrabbing) { + pickEventProcessor(mLastGrabState).cancelPendingActions(); + mLastGrabState = isGrabbing; + } + return pickEventProcessor(isGrabbing).processTouchEvent(e); + } + + private TouchEventProcessor pickEventProcessor(boolean isGrabbing) { + return isGrabbing ? mIngameProcessor : mInGUIProcessor; } /** @@ -545,25 +500,7 @@ public static boolean sendMouseButtonUnconverted(int button, boolean status) { - /** @return the hotbar key, given the position. -1 if no key are pressed */ - public int handleGuiBar(int x, int y) { - if (!CallbackBridge.isGrabbing()) return -1; - - int barHeight = mcscale(20); - int barY = CallbackBridge.physicalHeight - barHeight; - if(y < barY) return -1; - int barWidth = mcscale(180); - int barX = (CallbackBridge.physicalWidth / 2) - (barWidth / 2); - if(x < barX || x >= barX + barWidth) return -1; - - return HOTBAR_KEYS[(int) net.kdt.pojavlaunch.utils.MathUtils.map(x, barX, barX + barWidth, 0, 9)]; - } - - /** Return the size, given the UI scale size */ - private int mcscale(int input) { - return (int)((mGuiScale * input)/ mScaleFactor); - } /** Called when the size need to be set at any point during the surface lifecycle **/ public void refreshSize(){ diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/Touchpad.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/Touchpad.java index 388278093b..72dee1a91b 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/Touchpad.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/Touchpad.java @@ -1,6 +1,6 @@ package net.kdt.pojavlaunch; -import static net.kdt.pojavlaunch.MinecraftGLSurface.FINGER_SCROLL_THRESHOLD; +import static net.kdt.pojavlaunch.customcontrols.mouse.InGUIEventProcessor.FINGER_SCROLL_THRESHOLD; import static net.kdt.pojavlaunch.Tools.currentDisplayMetrics; import static net.kdt.pojavlaunch.prefs.LauncherPreferences.DEFAULT_PREF; diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/mouse/InGUIEventProcessor.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/mouse/InGUIEventProcessor.java new file mode 100644 index 0000000000..0579af1ae4 --- /dev/null +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/mouse/InGUIEventProcessor.java @@ -0,0 +1,68 @@ +package net.kdt.pojavlaunch.customcontrols.mouse; + +import android.view.MotionEvent; + +import net.kdt.pojavlaunch.LwjglGlfwKeycode; +import net.kdt.pojavlaunch.Tools; +import net.kdt.pojavlaunch.prefs.LauncherPreferences; + +import org.lwjgl.glfw.CallbackBridge; + +public class InGUIEventProcessor implements TouchEventProcessor { + private final PointerTracker mTracker = new PointerTracker(); + private boolean mIsMouseDown = false; + private final float mScaleFactor; + public static final int FINGER_SCROLL_THRESHOLD = (int) Tools.dpToPx(6); + public InGUIEventProcessor(float scaleFactor) { + mScaleFactor = scaleFactor; + } + @Override + public boolean processTouchEvent(MotionEvent motionEvent) { + switch (motionEvent.getActionMasked()) { + case MotionEvent.ACTION_DOWN: + mTracker.startTracking(motionEvent); + sendTouchCoords(motionEvent.getX(), motionEvent.getY()); + enableMouse(); + break; + case MotionEvent.ACTION_MOVE: + int pointerCount = motionEvent.getPointerCount(); + int pointerIndex = mTracker.trackEvent(motionEvent); + float mainPointerX = motionEvent.getX(pointerIndex); + float mainPointerY = motionEvent.getY(pointerIndex); + if(pointerCount == 1 || LauncherPreferences.PREF_DISABLE_GESTURES) { + sendTouchCoords(mainPointerX, mainPointerY); + if(!mIsMouseDown) enableMouse(); + }else { + float[] motionVector = mTracker.getMotionVector(); + int hScroll = ((int) motionVector[0]) / FINGER_SCROLL_THRESHOLD; + int vScroll = ((int) motionVector[1]) / FINGER_SCROLL_THRESHOLD; + if(hScroll != 0 | vScroll != 0) CallbackBridge.sendScroll(hScroll, vScroll); + } + break; + case MotionEvent.ACTION_UP: + disableMouse(); + } + return true; + } + + private void sendTouchCoords(float x, float y) { + CallbackBridge.mouseX = x * mScaleFactor; + CallbackBridge.mouseY = y * mScaleFactor; + CallbackBridge.sendCursorPos(CallbackBridge.mouseX, CallbackBridge.mouseY); + } + + private void enableMouse() { + CallbackBridge.sendMouseButton(LwjglGlfwKeycode.GLFW_MOUSE_BUTTON_LEFT, true); + mIsMouseDown = true; + } + + private void disableMouse() { + CallbackBridge.sendMouseButton(LwjglGlfwKeycode.GLFW_MOUSE_BUTTON_LEFT, false); + mIsMouseDown = false; + } + + @Override + public void cancelPendingActions() { + disableMouse(); + } +} diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/mouse/IngameEventProcessor.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/mouse/IngameEventProcessor.java new file mode 100644 index 0000000000..e79eff1665 --- /dev/null +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/mouse/IngameEventProcessor.java @@ -0,0 +1,175 @@ +package net.kdt.pojavlaunch.customcontrols.mouse; + +import static net.kdt.pojavlaunch.utils.MCOptionUtils.getMcScale; + +import static org.lwjgl.glfw.CallbackBridge.sendKeyPress; +import static org.lwjgl.glfw.CallbackBridge.sendMouseButton; + +import android.os.Handler; +import android.os.Looper; +import android.os.Message; +import android.view.MotionEvent; + +import androidx.annotation.NonNull; + +import net.kdt.pojavlaunch.LwjglGlfwKeycode; +import net.kdt.pojavlaunch.Tools; +import net.kdt.pojavlaunch.prefs.LauncherPreferences; +import net.kdt.pojavlaunch.utils.MCOptionUtils; +import net.kdt.pojavlaunch.utils.MathUtils; + +import org.lwjgl.glfw.CallbackBridge; + +public class IngameEventProcessor implements TouchEventProcessor { + + private int mGuiScale; + @SuppressWarnings("FieldCanBeLocal") // it can't, otherwise the weak reference will disappear + private final MCOptionUtils.MCOptionListener mGuiScaleListener = () -> mGuiScale = getMcScale(); + public static final int FINGER_STILL_THRESHOLD = (int) Tools.dpToPx(9); + public static final int MSG_LEFT_MOUSE_BUTTON_CHECK = 1028; + public static final int MSG_DROP_ITEM_BUTTON_CHECK = 1029; + private final Handler mGestureHandler = new Handler(Looper.getMainLooper()) { + public void handleMessage(@NonNull Message msg) {IngameEventProcessor.this.handleMessage(msg);} + }; + + private static final int[] HOTBAR_KEYS = { + LwjglGlfwKeycode.GLFW_KEY_1, LwjglGlfwKeycode.GLFW_KEY_2, LwjglGlfwKeycode.GLFW_KEY_3, + LwjglGlfwKeycode.GLFW_KEY_4, LwjglGlfwKeycode.GLFW_KEY_5, LwjglGlfwKeycode.GLFW_KEY_6, + LwjglGlfwKeycode.GLFW_KEY_7, LwjglGlfwKeycode.GLFW_KEY_8, LwjglGlfwKeycode.GLFW_KEY_9}; + private float mGestureStartX, mGestureStartY; + private boolean mHasPendingLongpressGesture; + private boolean mHasPendingDropGesture; + private boolean mGestureTriggered; + private int mLastHudKey; + private final float mScaleFactor; + private final double mSensitivity; + private final PointerTracker mTracker = new PointerTracker(); + + public IngameEventProcessor(float scaleFactor, double sensitivity) { + MCOptionUtils.addMCOptionListener(mGuiScaleListener); + mScaleFactor = scaleFactor; + mSensitivity = sensitivity; + } + + @Override + public boolean processTouchEvent(MotionEvent motionEvent) { + switch (motionEvent.getActionMasked()) { + case MotionEvent.ACTION_DOWN: + mTracker.startTracking(motionEvent); + break; + case MotionEvent.ACTION_MOVE: + mTracker.trackEvent(motionEvent); + float[] motionVector = mTracker.getMotionVector(); + CallbackBridge.mouseX += motionVector[0] * mSensitivity; + CallbackBridge.mouseY += motionVector[1] * mSensitivity; + CallbackBridge.sendCursorPos(CallbackBridge.mouseX, CallbackBridge.mouseY); + boolean hasGuiBarHit = handleGuiBar(motionEvent); + if(LauncherPreferences.PREF_DISABLE_GESTURES) break; + checkLongpressGesture(); + checkGuiBarGesture(hasGuiBarHit); + break; + case MotionEvent.ACTION_UP: + cancelGestures(); + } + return true; + } + + @Override + public void cancelPendingActions() { + cancelGestures(); + } + + private void cancelGestures() { + cancelLongpressGesture(); + cancelDropGesture(); + if(mGestureTriggered) sendMouseButton(LwjglGlfwKeycode.GLFW_MOUSE_BUTTON_LEFT, false); + } + + private boolean handleGuiBar(MotionEvent motionEvent) { + int hudKeyHandled = -1; + for(int i = 0; i < motionEvent.getPointerCount(); i++) { + hudKeyHandled = handleGuiBar( + (int)motionEvent.getX(i), (int)motionEvent.getY(i) + ); + if(hudKeyHandled != -1) break; + } + boolean hasGuiBarHit = hudKeyHandled != -1; + if(hasGuiBarHit && hudKeyHandled != mLastHudKey) { + CallbackBridge.sendKeyPress(hudKeyHandled); + mLastHudKey = hudKeyHandled; + } + return hasGuiBarHit; + } + + private void checkGuiBarGesture(boolean hasGuiBarHit) { + if(hasGuiBarHit && !mHasPendingDropGesture) submitDropGesture(); + if(!hasGuiBarHit) cancelDropGesture(); + } + + private void checkLongpressGesture() { + if(mHasPendingLongpressGesture && + MathUtils.dist(CallbackBridge.mouseX, CallbackBridge.mouseY, mGestureStartX, mGestureStartY) + >= FINGER_STILL_THRESHOLD) { + cancelLongpressGesture(); + } + if(!mHasPendingLongpressGesture) submitLongpressGesture(); + } + + private void cancelLongpressGesture() { + mGestureHandler.removeMessages(MSG_LEFT_MOUSE_BUTTON_CHECK); + mHasPendingLongpressGesture = false; + } + + private void submitLongpressGesture() { + mGestureStartX = CallbackBridge.mouseX; + mGestureStartY = CallbackBridge.mouseY; + mGestureHandler.sendEmptyMessageDelayed(MSG_LEFT_MOUSE_BUTTON_CHECK, LauncherPreferences.PREF_LONGPRESS_TRIGGER); + mHasPendingLongpressGesture = true; + } + + private void cancelDropGesture() { + mGestureHandler.removeMessages(MSG_DROP_ITEM_BUTTON_CHECK); + mHasPendingDropGesture = false; + } + + private void submitDropGesture() { + mGestureHandler.sendEmptyMessageDelayed(MSG_DROP_ITEM_BUTTON_CHECK, 350); + mHasPendingDropGesture = true; + } + + /** @return the hotbar key, given the position. -1 if no key are pressed */ + public int handleGuiBar(int x, int y) { + if (!CallbackBridge.isGrabbing()) return -1; + + int barHeight = mcscale(20); + int barY = CallbackBridge.physicalHeight - barHeight; + if(y < barY) return -1; + + int barWidth = mcscale(180); + int barX = (CallbackBridge.physicalWidth / 2) - (barWidth / 2); + if(x < barX || x >= barX + barWidth) return -1; + + return HOTBAR_KEYS[(int) net.kdt.pojavlaunch.utils.MathUtils.map(x, barX, barX + barWidth, 0, 9)]; + } + + /** Return the size, given the UI scale size */ + private int mcscale(int input) { + return (int)((mGuiScale * input)/ mScaleFactor); + } + + private void handleMessage(Message message) { + switch (message.what) { + case MSG_LEFT_MOUSE_BUTTON_CHECK: + float x = CallbackBridge.mouseX; + float y = CallbackBridge.mouseY; + if (MathUtils.dist(x, y, mGestureStartX, mGestureStartY) < FINGER_STILL_THRESHOLD) { + sendMouseButton(LwjglGlfwKeycode.GLFW_MOUSE_BUTTON_LEFT, true); + mGestureTriggered = true; + } + return; + case MSG_DROP_ITEM_BUTTON_CHECK: + sendKeyPress(LwjglGlfwKeycode.GLFW_KEY_Q); + mGestureHandler.sendEmptyMessageDelayed(MSG_DROP_ITEM_BUTTON_CHECK, 600); + } + } +} diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/mouse/PointerTracker.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/mouse/PointerTracker.java new file mode 100644 index 0000000000..1bf985a787 --- /dev/null +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/mouse/PointerTracker.java @@ -0,0 +1,39 @@ +package net.kdt.pojavlaunch.customcontrols.mouse; + +import android.view.MotionEvent; + +public class PointerTracker { + private boolean mColdStart = true; + private int mTrackedPointerId; + private int mPointerCount; + private float mLastX, mLastY; + private final float[] mMotionVector = new float[2]; + + public void startTracking(MotionEvent motionEvent) { + mColdStart = false; + mTrackedPointerId = motionEvent.getPointerId(0); + mPointerCount = motionEvent.getPointerCount(); + mLastX = motionEvent.getX(); + mLastY = motionEvent.getY(); + } + + public int trackEvent(MotionEvent motionEvent) { + int trackedPointerIndex = motionEvent.findPointerIndex(mTrackedPointerId); + int pointerCount = motionEvent.getPointerCount(); + if(trackedPointerIndex == -1 || mPointerCount != pointerCount || mColdStart) { + startTracking(motionEvent); + trackedPointerIndex = 0; + } + float trackedX = motionEvent.getX(trackedPointerIndex); + float trackedY = motionEvent.getY(trackedPointerIndex); + mMotionVector[0] = trackedX - mLastX; + mMotionVector[1] = trackedY - mLastY; + mLastX = trackedX; + mLastY = trackedY; + return trackedPointerIndex; + } + + public float[] getMotionVector() { + return mMotionVector; + } +} diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/mouse/TouchEventProcessor.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/mouse/TouchEventProcessor.java new file mode 100644 index 0000000000..5bf6431e25 --- /dev/null +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/mouse/TouchEventProcessor.java @@ -0,0 +1,8 @@ +package net.kdt.pojavlaunch.customcontrols.mouse; + +import android.view.MotionEvent; + +public interface TouchEventProcessor { + boolean processTouchEvent(MotionEvent motionEvent); + void cancelPendingActions(); +}