diff options
author | solb@chromium.org <solb@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-07-22 21:03:50 +0000 |
---|---|---|
committer | solb@chromium.org <solb@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-07-22 21:03:50 +0000 |
commit | 7c4a2e9aedf9e98c45a9dbea783cc49c41bbc091 (patch) | |
tree | 8ae0962b7df4b8777d35f965f0a5f63980d791ad /remoting | |
parent | 7d634398aa32888ce450b9fc82ec2b312e5b2d24 (diff) | |
download | chromium_src-7c4a2e9aedf9e98c45a9dbea783cc49c41bbc091.zip chromium_src-7c4a2e9aedf9e98c45a9dbea783cc49c41bbc091.tar.gz chromium_src-7c4a2e9aedf9e98c45a9dbea783cc49c41bbc091.tar.bz2 |
Change Android client desktop panning and zooming behavior
It's now possible to scroll out far enough to see the entire desktop. Scrolling out all the way centers the image, nesting it between two black bars of equal length.
Review URL: https://chromiumcodereview.appspot.com/19482019
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@212964 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'remoting')
-rw-r--r-- | remoting/android/java/src/org/chromium/chromoting/DesktopView.java | 91 | ||||
-rw-r--r-- | remoting/android/java/src/org/chromium/chromoting/jni/JniInterface.java | 6 |
2 files changed, 75 insertions, 22 deletions
diff --git a/remoting/android/java/src/org/chromium/chromoting/DesktopView.java b/remoting/android/java/src/org/chromium/chromoting/DesktopView.java index c722257..b7666b3 100644 --- a/remoting/android/java/src/org/chromium/chromoting/DesktopView.java +++ b/remoting/android/java/src/org/chromium/chromoting/DesktopView.java @@ -57,6 +57,12 @@ public class DesktopView extends SurfaceView implements Runnable, SurfaceHolder. /** Specifies the dimension by which the zoom level is being lower-bounded. */ private Constraint mConstraint; + /** Whether the right edge of the image was visible on-screen during the last render. */ + private boolean mRightUsedToBeOut; + + /** Whether the bottom edge of the image was visible on-screen during the last render. */ + private boolean mBottomUsedToBeOut; + /** Whether the device has just been rotated, necessitating a canvas redraw. */ private boolean mJustRotated; @@ -71,6 +77,11 @@ public class DesktopView extends SurfaceView implements Runnable, SurfaceHolder. mScreenWidth = 0; mScreenHeight = 0; mConstraint = Constraint.UNDEFINED; + + mRightUsedToBeOut = false; + mBottomUsedToBeOut = false; + + mJustRotated = false; } /** @@ -80,46 +91,88 @@ public class DesktopView extends SurfaceView implements Runnable, SurfaceHolder. */ @Override public void run() { - if (Looper.myLooper()==Looper.getMainLooper()) { + if (Looper.myLooper() == Looper.getMainLooper()) { Log.w("deskview", "Canvas being redrawn on UI thread"); } - Canvas canvas = getHolder().lockCanvas(); Bitmap image = JniInterface.retrieveVideoFrame(); + Canvas canvas = getHolder().lockCanvas(); synchronized (mTransform) { canvas.setMatrix(mTransform); + // Internal parameters of the transformation matrix. float[] values = new float[9]; mTransform.getValues(values); + + // Screen coordinates of two defining points of the image. float[] topleft = {0, 0}; mTransform.mapPoints(topleft); float[] bottomright = {image.getWidth(), image.getHeight()}; mTransform.mapPoints(bottomright); - if (mConstraint==Constraint.UNDEFINED) { + // Whether to rescale and recenter the view. + boolean recenter = false; + + if (mConstraint == Constraint.UNDEFINED) { mConstraint = image.getWidth()/image.getHeight() > mScreenWidth/mScreenHeight ? - Constraint.HEIGHT : Constraint.WIDTH; + Constraint.WIDTH : Constraint.HEIGHT; + recenter = true; // We always rescale and recenter after a rotation. } - if (mConstraint==Constraint.WIDTH && bottomright[0] - topleft[0] < mScreenWidth) { - mTransform.setPolyToPoly(new float[] {0, 0, image.getWidth(), 0}, 0, - new float[] {0, 0, mScreenWidth, 0}, 0, 2); - } else if (mConstraint==Constraint.HEIGHT && - bottomright[1] - topleft[1] < mScreenHeight) { - mTransform.setPolyToPoly(new float[] {0, 0, 0, image.getHeight()}, 0, - new float[] {0, 0, 0, mScreenHeight}, 0, 2); + if (mConstraint == Constraint.WIDTH && + ((int)(bottomright[0] - topleft[0] + 0.5) < mScreenWidth || recenter)) { + // The vertical edges of the image are flush against the device's screen edges + // when the entire host screen is visible, and the user has zoomed out too far. + float imageMiddle = (float)image.getHeight() / 2; + float screenMiddle = (float)mScreenHeight / 2; + mTransform.setPolyToPoly( + new float[] {0, imageMiddle, image.getWidth(), imageMiddle}, 0, + new float[] {0, screenMiddle, mScreenWidth, screenMiddle}, 0, 2); + } else if (mConstraint == Constraint.HEIGHT && + ((int)(bottomright[1] - topleft[1] + 0.5) < mScreenHeight || recenter)) { + // The horizontal image edges are flush against the device's screen edges when + // the entire host screen is visible, and the user has zoomed out too far. + float imageCenter = (float)image.getWidth() / 2; + float screenCenter = (float)mScreenWidth / 2; + mTransform.setPolyToPoly( + new float[] {imageCenter, 0, imageCenter, image.getHeight()}, 0, + new float[] {screenCenter, 0, screenCenter, mScreenHeight}, 0, 2); } else { - if (values[Matrix.MTRANS_X] > 0) { - values[Matrix.MTRANS_X] = 0; + // It's fine for both members of a pair of image edges to be within the screen + // edges (or "out of bounds"); that simply means that the image is zoomed out as + // far as permissible. And both members of a pair can obviously be outside the + // screen's edges, which indicates that the image is zoomed in to far to see the + // whole host screen. However, if only one of a pair of edges has entered the + // screen, the user is attempting to scroll into a blank area of the canvas. + + // A value of true means the corresponding edge has entered the screen's borders. + boolean leftEdgeOutOfBounds = values[Matrix.MTRANS_X] > 0; + boolean topEdgeOutOfBounds = values[Matrix.MTRANS_Y] > 0; + boolean rightEdgeOutOfBounds = bottomright[0] < mScreenWidth; + boolean bottomEdgeOutOfBounds = bottomright[1] < mScreenHeight; + + if (leftEdgeOutOfBounds != rightEdgeOutOfBounds) { + if (leftEdgeOutOfBounds != mRightUsedToBeOut) { + values[Matrix.MTRANS_X] = 0; + } + else { + values[Matrix.MTRANS_X] += mScreenWidth - bottomright[0]; + } } - if (values[Matrix.MTRANS_Y] > 0) { - values[Matrix.MTRANS_Y] = 0; + else { // The view would oscillate if this were updated while scrolling off-screen. + mRightUsedToBeOut = rightEdgeOutOfBounds; } - if (bottomright[0] < mScreenWidth) { - values[Matrix.MTRANS_X] += mScreenWidth - bottomright[0]; + + if (topEdgeOutOfBounds != bottomEdgeOutOfBounds) { + if (topEdgeOutOfBounds != mBottomUsedToBeOut) { + values[Matrix.MTRANS_Y] = 0; + } + else { + values[Matrix.MTRANS_Y] += mScreenHeight - bottomright[1]; + } } - if (bottomright[1] < mScreenHeight) { - values[Matrix.MTRANS_Y] += mScreenHeight - bottomright[1]; + else { // The view would oscillate if this were updated while scrolling off-screen. + mBottomUsedToBeOut = bottomEdgeOutOfBounds; } mTransform.setValues(values); diff --git a/remoting/android/java/src/org/chromium/chromoting/jni/JniInterface.java b/remoting/android/java/src/org/chromium/chromoting/jni/JniInterface.java index b00f6c5..7e30a68 100644 --- a/remoting/android/java/src/org/chromium/chromoting/jni/JniInterface.java +++ b/remoting/android/java/src/org/chromium/chromoting/jni/JniInterface.java @@ -118,12 +118,12 @@ public class JniInterface { /** Reports whenever the connection status changes. */ private static void reportConnectionStatus(int state, int error) { - if (state==SUCCESSFUL_CONNECTION) { + if (state == SUCCESSFUL_CONNECTION) { sSuccessCallback.run(); } Toast.makeText(sContext, sContext.getResources().getStringArray( - R.array.protoc_states)[state] + (error!=0 ? ": " + + R.array.protoc_states)[state] + (error != 0 ? ": " + sContext.getResources().getStringArray(R.array.protoc_errors)[error] : ""), Toast.LENGTH_SHORT).show(); } @@ -188,7 +188,7 @@ public class JniInterface { * This should not be called from the UI thread. (We prefer the native graphics thread.) */ public static Bitmap retrieveVideoFrame() { - if (Looper.myLooper()==Looper.getMainLooper()) { + if (Looper.myLooper() == Looper.getMainLooper()) { Log.w("deskview", "Canvas being redrawn on UI thread"); } |