From 15fb3dd92c5d893701d09320edbb23ba27138d21 Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Tue, 19 Apr 2016 19:13:57 -0400 Subject: [PATCH] Fix mouse scaling to scale by stream view size rather than screen size for better behavior on N and in general --- app/src/main/java/com/limelight/Game.java | 31 ++++++++++--------- .../limelight/binding/input/TouchContext.java | 20 +++++++++--- 2 files changed, 31 insertions(+), 20 deletions(-) diff --git a/app/src/main/java/com/limelight/Game.java b/app/src/main/java/com/limelight/Game.java index 0c7dee92..6c16082b 100644 --- a/app/src/main/java/com/limelight/Game.java +++ b/app/src/main/java/com/limelight/Game.java @@ -75,8 +75,8 @@ public class Game extends Activity implements SurfaceHolder.Callback, private final TouchContext[] touchContextMap = new TouchContext[2]; private long threeFingerDownTime = 0; - private static final double REFERENCE_HORIZ_RES = 1280; - private static final double REFERENCE_VERT_RES = 720; + private static final int REFERENCE_HORIZ_RES = 1280; + private static final int REFERENCE_VERT_RES = 720; private static final int THREE_FINGER_TAP_THRESHOLD = 300; @@ -85,7 +85,6 @@ public class Game extends Activity implements SurfaceHolder.Callback, private KeyboardTranslator keybTranslator; private PreferenceConfiguration prefConfig; - private final Point screenSize = new Point(0, 0); private NvConnection conn; private SpinnerDialog spinner; @@ -97,6 +96,7 @@ public class Game extends Activity implements SurfaceHolder.Callback, private int modifierFlags = 0; private boolean grabbedInput = true; private boolean grabComboDown = false; + private StreamView streamView; private EnhancedDecoderRenderer decoderRenderer; @@ -175,13 +175,10 @@ public class Game extends Activity implements SurfaceHolder.Callback, drFlags |= VideoDecoderRenderer.FLAG_FILL_SCREEN; } - Display display = getWindowManager().getDefaultDisplay(); - display.getSize(screenSize); - // Listen for events on the game surface - StreamView sv = (StreamView) findViewById(R.id.surfaceView); - sv.setOnGenericMotionListener(this); - sv.setOnTouchListener(this); + streamView = (StreamView) findViewById(R.id.surfaceView); + streamView.setOnGenericMotionListener(this); + streamView.setOnTouchListener(this); // Warn the user if they're on a metered connection checkDataConnection(); @@ -258,6 +255,10 @@ public class Game extends Activity implements SurfaceHolder.Callback, // >= 4K screens have exactly 4K screens, so we'll be able to hit this good path // on these devices. On Marshmallow, we can start changing to 4K manually but no // 4K devices run 6.0 at the moment. + Display display = getWindowManager().getDefaultDisplay(); + Point screenSize = new Point(0, 0); + display.getSize(screenSize); + double screenAspectRatio = ((double)screenSize.y) / screenSize.x; double streamAspectRatio = ((double)prefConfig.height) / prefConfig.width; if (Math.abs(screenAspectRatio - streamAspectRatio) < 0.001) { @@ -266,21 +267,21 @@ public class Game extends Activity implements SurfaceHolder.Callback, } } - SurfaceHolder sh = sv.getHolder(); + SurfaceHolder sh = streamView.getHolder(); if (prefConfig.stretchVideo || aspectRatioMatch) { // Set the surface to the size of the video sh.setFixedSize(prefConfig.width, prefConfig.height); } else { // Set the surface to scale based on the aspect ratio of the stream - sv.setDesiredAspectRatio((double)prefConfig.width / (double)prefConfig.height); + streamView.setDesiredAspectRatio((double)prefConfig.width / (double)prefConfig.height); } // Initialize touch contexts for (int i = 0; i < touchContextMap.length; i++) { touchContextMap[i] = new TouchContext(conn, i, - (REFERENCE_HORIZ_RES / (double)screenSize.x), - (REFERENCE_VERT_RES / (double)screenSize.y)); + REFERENCE_HORIZ_RES, REFERENCE_VERT_RES, + streamView); } if (LimelightBuildProps.ROOT_BUILD) { @@ -783,8 +784,8 @@ public class Game extends Activity implements SurfaceHolder.Callback, // Scale the deltas if the device resolution is different // than the stream resolution - deltaX = (int)Math.round((double)deltaX * (REFERENCE_HORIZ_RES / (double)screenSize.x)); - deltaY = (int)Math.round((double)deltaY * (REFERENCE_VERT_RES / (double)screenSize.y)); + deltaX = (int)Math.round((double)deltaX * (REFERENCE_HORIZ_RES / (double)streamView.getWidth())); + deltaY = (int)Math.round((double)deltaY * (REFERENCE_VERT_RES / (double)streamView.getHeight())); conn.sendMouseMove((short)deltaX, (short)deltaY); } diff --git a/app/src/main/java/com/limelight/binding/input/TouchContext.java b/app/src/main/java/com/limelight/binding/input/TouchContext.java index 409014bf..6c7cc59a 100644 --- a/app/src/main/java/com/limelight/binding/input/TouchContext.java +++ b/app/src/main/java/com/limelight/binding/input/TouchContext.java @@ -1,5 +1,7 @@ package com.limelight.binding.input; +import android.view.View; + import com.limelight.nvstream.NvConnection; import com.limelight.nvstream.input.MouseButtonPacket; @@ -17,23 +19,27 @@ public class TouchContext { private boolean confirmedDrag; private Timer dragTimer; private double distanceMoved; + private double xFactor, yFactor; private final NvConnection conn; private final int actionIndex; - private final double xFactor; - private final double yFactor; + private final int referenceWidth; + private final int referenceHeight; + private final View targetView; private static final int TAP_MOVEMENT_THRESHOLD = 20; private static final int TAP_DISTANCE_THRESHOLD = 25; private static final int TAP_TIME_THRESHOLD = 250; private static final int DRAG_TIME_THRESHOLD = 650; - public TouchContext(NvConnection conn, int actionIndex, double xFactor, double yFactor) + public TouchContext(NvConnection conn, int actionIndex, + int referenceWidth, int referenceHeight, View view) { this.conn = conn; this.actionIndex = actionIndex; - this.xFactor = xFactor; - this.yFactor = yFactor; + this.referenceWidth = referenceWidth; + this.referenceHeight = referenceHeight; + this.targetView = view; } public int getActionIndex() @@ -68,6 +74,10 @@ public class TouchContext { public boolean touchDownEvent(int eventX, int eventY) { + // Get the view dimensions to scale inputs on this touch + xFactor = referenceWidth / (double)targetView.getWidth(); + yFactor = referenceHeight / (double)targetView.getHeight(); + originalTouchX = lastTouchX = eventX; originalTouchY = lastTouchY = eventY; originalTouchTime = System.currentTimeMillis();