Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(270)

Unified Diff: remoting/android/java/src/org/chromium/chromoting/DesktopView.java

Issue 19482019: Change Android client desktop panning and zooming behavior (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rescale/recenter after device rotation, clarify comments Created 7 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | remoting/android/java/src/org/chromium/chromoting/jni/JniInterface.java » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: remoting/android/java/src/org/chromium/chromoting/DesktopView.java
diff --git a/remoting/android/java/src/org/chromium/chromoting/DesktopView.java b/remoting/android/java/src/org/chromium/chromoting/DesktopView.java
index c7222577c78ca576a9656fff46ac66c10cd7774d..b7666b303364faa325f5c534c1f1aab3c4edac87 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);
« no previous file with comments | « no previous file | remoting/android/java/src/org/chromium/chromoting/jni/JniInterface.java » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698