mirror of
https://github.com/AngelAuraMC/Amethyst-Android.git
synced 2026-04-21 10:07:15 -04:00
Fix[input]: implement scrolling gestures for touchpads
This commit is contained in:
@@ -15,10 +15,12 @@ import org.lwjgl.glfw.CallbackBridge;
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.O)
|
||||
public class AndroidPointerCapture implements ViewTreeObserver.OnWindowFocusChangeListener, View.OnCapturedPointerListener {
|
||||
private static final float TOUCHPAD_SCROLL_THRESHOLD = 1;
|
||||
private final AbstractTouchpad mTouchpad;
|
||||
private final View mHostView;
|
||||
private final float mScaleFactor;
|
||||
private final float mPointerPrescale = Tools.dpToPx(1);
|
||||
private final float mMousePrescale = Tools.dpToPx(1);
|
||||
private final Scroller mScroller = new Scroller(TOUCHPAD_SCROLL_THRESHOLD);
|
||||
|
||||
public AndroidPointerCapture(AbstractTouchpad touchpad, View hostView, float scaleFactor) {
|
||||
this.mScaleFactor = scaleFactor;
|
||||
@@ -47,13 +49,26 @@ public class AndroidPointerCapture implements ViewTreeObserver.OnWindowFocusChan
|
||||
|
||||
@Override
|
||||
public boolean onCapturedPointer(View view, MotionEvent event) {
|
||||
// Yes, we actually not only receive relative mouse events here, but also absolute touchpad ones!
|
||||
// Read from relative axis directly to work around.
|
||||
float relX = event.getAxisValue(MotionEvent.AXIS_RELATIVE_X);
|
||||
float relY = event.getAxisValue(MotionEvent.AXIS_RELATIVE_Y);
|
||||
if(!CallbackBridge.isGrabbing()) {
|
||||
enableTouchpadIfNecessary();
|
||||
mTouchpad.applyMotionVector(event.getX() * mPointerPrescale, event.getY() * mPointerPrescale);
|
||||
// Yes, if the user's touchpad is multi-touch we will also receive events for that.
|
||||
// So, handle the scrolling gesture ourselves.
|
||||
relX *= mMousePrescale;
|
||||
relY *= mMousePrescale;
|
||||
if(event.getPointerCount() < 2) {
|
||||
mTouchpad.applyMotionVector(relX, relY);
|
||||
mScroller.resetScrollOvershoot();
|
||||
} else {
|
||||
mScroller.performScroll(relX, relY);
|
||||
}
|
||||
} else {
|
||||
// Position is updated by many events, hence it is send regardless of the event value
|
||||
CallbackBridge.mouseX += (event.getX() * mScaleFactor);
|
||||
CallbackBridge.mouseY += (event.getY() * mScaleFactor);
|
||||
CallbackBridge.mouseX += (relX * mScaleFactor);
|
||||
CallbackBridge.mouseY += (relY * mScaleFactor);
|
||||
CallbackBridge.sendCursorPos(CallbackBridge.mouseX, CallbackBridge.mouseY);
|
||||
}
|
||||
|
||||
|
||||
@@ -11,13 +11,13 @@ import net.kdt.pojavlaunch.prefs.LauncherPreferences;
|
||||
import org.lwjgl.glfw.CallbackBridge;
|
||||
|
||||
public class InGUIEventProcessor implements TouchEventProcessor {
|
||||
public static final float FINGER_SCROLL_THRESHOLD = Tools.dpToPx(6);
|
||||
private final PointerTracker mTracker = new PointerTracker();
|
||||
private final GestureDetector mSingleTapDetector;
|
||||
private AbstractTouchpad mTouchpad;
|
||||
private boolean mIsMouseDown = false;
|
||||
private final float mScaleFactor;
|
||||
private float mScrollOvershootH, mScrollOvershootV;
|
||||
public static final float FINGER_SCROLL_THRESHOLD = Tools.dpToPx(6);
|
||||
private final Scroller mScroller = new Scroller(FINGER_SCROLL_THRESHOLD);
|
||||
public InGUIEventProcessor(float scaleFactor) {
|
||||
mSingleTapDetector = new GestureDetector(null, new SingleTapConfirm());
|
||||
mScaleFactor = scaleFactor;
|
||||
@@ -44,11 +44,11 @@ public class InGUIEventProcessor implements TouchEventProcessor {
|
||||
sendTouchCoordinates(mainPointerX, mainPointerY);
|
||||
if(!mIsMouseDown) enableMouse();
|
||||
}
|
||||
} else performScroll();
|
||||
} else mScroller.performScroll(mTracker.getMotionVector());
|
||||
break;
|
||||
case MotionEvent.ACTION_CANCEL:
|
||||
case MotionEvent.ACTION_UP:
|
||||
resetScrollOvershoot();
|
||||
mScroller.resetScrollOvershoot();
|
||||
mTracker.cancelTracking();
|
||||
if(mIsMouseDown) disableMouse();
|
||||
}
|
||||
@@ -64,20 +64,6 @@ public class InGUIEventProcessor implements TouchEventProcessor {
|
||||
mTouchpad = touchpad;
|
||||
}
|
||||
|
||||
private void performScroll() {
|
||||
float[] motionVector = mTracker.getMotionVector();
|
||||
float hScroll = (motionVector[0] / FINGER_SCROLL_THRESHOLD) + mScrollOvershootH;
|
||||
float vScroll = (motionVector[1] / FINGER_SCROLL_THRESHOLD) + mScrollOvershootV;
|
||||
int hScrollRound = (int) hScroll, vScrollRound = (int) vScroll;
|
||||
if(hScrollRound != 0 || vScrollRound != 0) CallbackBridge.sendScroll(hScroll, vScroll);
|
||||
mScrollOvershootH = hScroll - hScrollRound;
|
||||
mScrollOvershootV = vScroll - vScrollRound;
|
||||
}
|
||||
|
||||
private void resetScrollOvershoot() {
|
||||
mScrollOvershootH = mScrollOvershootV = 0f;
|
||||
}
|
||||
|
||||
private void sendTouchCoordinates(float x, float y) {
|
||||
CallbackBridge.sendCursorPos( x * mScaleFactor, y * mScaleFactor);
|
||||
}
|
||||
@@ -99,7 +85,7 @@ public class InGUIEventProcessor implements TouchEventProcessor {
|
||||
|
||||
@Override
|
||||
public void cancelPendingActions() {
|
||||
resetScrollOvershoot();
|
||||
mScroller.resetScrollOvershoot();
|
||||
disableMouse();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
package net.kdt.pojavlaunch.customcontrols.mouse;
|
||||
|
||||
import org.lwjgl.glfw.CallbackBridge;
|
||||
|
||||
public class Scroller {
|
||||
|
||||
private float mScrollOvershootH, mScrollOvershootV;
|
||||
private final float mScrollThreshold;
|
||||
|
||||
public Scroller(float mScrollThreshold) {
|
||||
this.mScrollThreshold = mScrollThreshold;
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform a scrolling gesture.
|
||||
* @param dx the X coordinate of the primary pointer's vector
|
||||
* @param dy the Y coordinate of the primary pointer's vector
|
||||
*/
|
||||
public void performScroll(float dx, float dy) {
|
||||
float hScroll = (dx / mScrollThreshold) + mScrollOvershootH;
|
||||
float vScroll = (dy / mScrollThreshold) + mScrollOvershootV;
|
||||
int hScrollRound = (int) hScroll, vScrollRound = (int) vScroll;
|
||||
if(hScrollRound != 0 || vScrollRound != 0) CallbackBridge.sendScroll(hScroll, vScroll);
|
||||
mScrollOvershootH = hScroll - hScrollRound;
|
||||
mScrollOvershootV = vScroll - vScrollRound;
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform a scrolling gesture.
|
||||
* @param vector a 2-component vector that stores the relative position of the primary pointer.
|
||||
*/
|
||||
public void performScroll(float[] vector) {
|
||||
performScroll(vector[0], vector[1]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset scroll overshoot values. Scroll overshoot makes the scrolling feel less
|
||||
* choppy, but will cause anomailes if not reset on the end of a scrolling gesture.
|
||||
*/
|
||||
public void resetScrollOvershoot() {
|
||||
mScrollOvershootH = mScrollOvershootV = 0f;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user