Touchpad: two-finger scroll and pinch zoom, fix selection row offset; v0.1.1
This commit is contained in:
+2
-2
@@ -10,8 +10,8 @@ android {
|
||||
applicationId "xyz.whcself.whcshell"
|
||||
minSdk 26
|
||||
targetSdk 35
|
||||
versionCode 1
|
||||
versionName "0.1.0"
|
||||
versionCode 2
|
||||
versionName "0.1.1"
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
|
||||
@@ -284,10 +284,15 @@ public final class TermView extends View {
|
||||
return Math.max(0, Math.min(cols - 1, c));
|
||||
}
|
||||
|
||||
/** Top of the first text row; the renderer starts rows below the padding by this offset. */
|
||||
private int textTop() {
|
||||
return getPaddingTop() + renderer.getFontLineSpacingAndAscent();
|
||||
}
|
||||
|
||||
/** Visible row, 0-based. */
|
||||
private int row(MotionEvent ev) {
|
||||
int rows = emulator().mRows;
|
||||
int r = (int) Math.floor((ev.getY() - getPaddingTop()) / renderer.getFontLineSpacing());
|
||||
int r = (int) Math.floor((ev.getY() - textTop()) / renderer.getFontLineSpacing());
|
||||
return Math.max(0, Math.min(rows - 1, r));
|
||||
}
|
||||
|
||||
@@ -448,6 +453,49 @@ public final class TermView extends View {
|
||||
return m;
|
||||
}
|
||||
|
||||
private float gestureY, pinchDist;
|
||||
|
||||
/**
|
||||
* Touchpad gestures arrive as mouse-source events with a finger tool and no buttons: a fake
|
||||
* finger classified as a two-finger swipe for scrolling (the gesture axes stay 0, so the finger's
|
||||
* movement is the distance), two fake fingers for a pinch, and stray single-finger strokes around
|
||||
* taps. None of them are button presses.
|
||||
*/
|
||||
private boolean onTouchpadGesture(MotionEvent ev) {
|
||||
int action = ev.getActionMasked();
|
||||
if (ev.getPointerCount() >= 2) {
|
||||
float d = (float) Math.hypot(ev.getX(0) - ev.getX(1), ev.getY(0) - ev.getY(1));
|
||||
if (action == MotionEvent.ACTION_POINTER_DOWN) {
|
||||
pinchDist = d;
|
||||
} else if (action == MotionEvent.ACTION_MOVE && pinchDist > 0 && actions != null) {
|
||||
if (d > pinchDist * 1.25f) {
|
||||
actions.zoom(1);
|
||||
pinchDist = d;
|
||||
} else if (d < pinchDist / 1.25f) {
|
||||
actions.zoom(-1);
|
||||
pinchDist = d;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
pinchDist = 0;
|
||||
boolean swipe = android.os.Build.VERSION.SDK_INT >= 34
|
||||
&& ev.getClassification() == MotionEvent.CLASSIFICATION_TWO_FINGER_SWIPE;
|
||||
if (action == MotionEvent.ACTION_DOWN) {
|
||||
gestureY = ev.getY();
|
||||
scrollAccum = 0;
|
||||
} else if (action == MotionEvent.ACTION_MOVE && swipe) {
|
||||
scrollAccum += (gestureY - ev.getY()) / renderer.getFontLineSpacing();
|
||||
gestureY = ev.getY();
|
||||
int lines = (int) scrollAccum;
|
||||
if (lines != 0) {
|
||||
scrollAccum -= lines;
|
||||
scrollLines(lines, ev);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private static final int[][] BUTTONS = {
|
||||
{MotionEvent.BUTTON_PRIMARY, TerminalEmulator.MOUSE_LEFT_BUTTON},
|
||||
{MotionEvent.BUTTON_TERTIARY, 1},
|
||||
@@ -459,11 +507,12 @@ public final class TermView extends View {
|
||||
* button, so presses and releases are derived from changes in the button state.
|
||||
*/
|
||||
private boolean onMouse(MotionEvent ev) {
|
||||
if (ev.getToolType(0) == MotionEvent.TOOL_TYPE_FINGER) return onTouchpadGesture(ev);
|
||||
TerminalEmulator e = emulator();
|
||||
int action = ev.getActionMasked();
|
||||
int state = ev.getButtonState()
|
||||
& (MotionEvent.BUTTON_PRIMARY | MotionEvent.BUTTON_SECONDARY | MotionEvent.BUTTON_TERTIARY);
|
||||
// Touchpad taps and injected events can come as DOWN/UP without any button state.
|
||||
// Injected events (adb input mouse) come as DOWN/UP without any button state.
|
||||
if (action == MotionEvent.ACTION_DOWN && state == 0) implicitPrimary = true;
|
||||
if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL) implicitPrimary = false;
|
||||
if (implicitPrimary) state |= MotionEvent.BUTTON_PRIMARY;
|
||||
@@ -524,8 +573,8 @@ public final class TermView extends View {
|
||||
} else if (selDragging && (state & MotionEvent.BUTTON_PRIMARY) != 0
|
||||
&& action == MotionEvent.ACTION_MOVE) {
|
||||
float y = ev.getY();
|
||||
if (y < getPaddingTop()) scrollTranscript(-1);
|
||||
else if (y > getHeight() - getPaddingBottom()) scrollTranscript(1);
|
||||
if (y < textTop()) scrollTranscript(-1);
|
||||
else if (y >= textTop() + emulator().mRows * renderer.getFontLineSpacing()) scrollTranscript(1);
|
||||
extendSelection(col, row + topRow);
|
||||
}
|
||||
if ((released & MotionEvent.BUTTON_PRIMARY) != 0 && selDragging) {
|
||||
|
||||
Reference in New Issue
Block a user