Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 package org.chromium.chromoting; | 5 package org.chromium.chromoting; |
| 6 | 6 |
| 7 import android.content.Context; | 7 import android.content.Context; |
| 8 import android.graphics.Bitmap; | 8 import android.graphics.Bitmap; |
| 9 import android.graphics.Canvas; | 9 import android.graphics.Canvas; |
| 10 import android.graphics.Color; | 10 import android.graphics.Color; |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 50 | 50 |
| 51 /** Stores pan and zoom configuration and converts image coordinates to scre en coordinates. */ | 51 /** Stores pan and zoom configuration and converts image coordinates to scre en coordinates. */ |
| 52 private Matrix mTransform; | 52 private Matrix mTransform; |
| 53 | 53 |
| 54 private int mScreenWidth; | 54 private int mScreenWidth; |
| 55 private int mScreenHeight; | 55 private int mScreenHeight; |
| 56 | 56 |
| 57 /** Specifies the dimension by which the zoom level is being lower-bounded. */ | 57 /** Specifies the dimension by which the zoom level is being lower-bounded. */ |
| 58 private Constraint mConstraint; | 58 private Constraint mConstraint; |
| 59 | 59 |
| 60 /** Whether the right edge of the image was visible on-screen during the las t render. */ | |
| 61 private boolean mRightUsedToBeOut; | |
| 62 | |
| 63 /** Whether the bottom edge of the image was visible on-screen during the la st render. */ | |
| 64 private boolean mBottomUsedToBeOut; | |
| 65 | |
| 60 /** Whether the device has just been rotated, necessitating a canvas redraw. */ | 66 /** Whether the device has just been rotated, necessitating a canvas redraw. */ |
| 61 private boolean mJustRotated; | 67 private boolean mJustRotated; |
| 62 | 68 |
| 63 public DesktopView(Context context) { | 69 public DesktopView(Context context) { |
| 64 super(context); | 70 super(context); |
| 65 getHolder().addCallback(this); | 71 getHolder().addCallback(this); |
| 66 DesktopListener listener = new DesktopListener(); | 72 DesktopListener listener = new DesktopListener(); |
| 67 mScroller = new GestureDetector(context, listener); | 73 mScroller = new GestureDetector(context, listener); |
| 68 mZoomer = new ScaleGestureDetector(context, listener); | 74 mZoomer = new ScaleGestureDetector(context, listener); |
| 69 | 75 |
| 70 mTransform = new Matrix(); | 76 mTransform = new Matrix(); |
| 71 mScreenWidth = 0; | 77 mScreenWidth = 0; |
| 72 mScreenHeight = 0; | 78 mScreenHeight = 0; |
| 73 mConstraint = Constraint.UNDEFINED; | 79 mConstraint = Constraint.UNDEFINED; |
| 80 | |
| 81 mRightUsedToBeOut = false; | |
| 82 mBottomUsedToBeOut = false; | |
| 83 | |
| 84 mJustRotated = false; | |
| 74 } | 85 } |
| 75 | 86 |
| 76 /** | 87 /** |
| 77 * Redraws the canvas. This should be done on a non-UI thread or it could | 88 * Redraws the canvas. This should be done on a non-UI thread or it could |
| 78 * cause the UI to lag. Specifically, it is currently invoked on the native | 89 * cause the UI to lag. Specifically, it is currently invoked on the native |
| 79 * graphics thread using a JNI. | 90 * graphics thread using a JNI. |
| 80 */ | 91 */ |
| 81 @Override | 92 @Override |
| 82 public void run() { | 93 public void run() { |
| 83 if (Looper.myLooper()==Looper.getMainLooper()) { | 94 if (Looper.myLooper() == Looper.getMainLooper()) { |
| 84 Log.w("deskview", "Canvas being redrawn on UI thread"); | 95 Log.w("deskview", "Canvas being redrawn on UI thread"); |
| 85 } | 96 } |
| 86 | 97 |
| 98 Bitmap image = JniInterface.retrieveVideoFrame(); | |
| 87 Canvas canvas = getHolder().lockCanvas(); | 99 Canvas canvas = getHolder().lockCanvas(); |
| 88 Bitmap image = JniInterface.retrieveVideoFrame(); | |
| 89 synchronized (mTransform) { | 100 synchronized (mTransform) { |
| 90 canvas.setMatrix(mTransform); | 101 canvas.setMatrix(mTransform); |
| 91 | 102 |
| 103 // Internal parameters of the transformation matrix. | |
| 92 float[] values = new float[9]; | 104 float[] values = new float[9]; |
| 93 mTransform.getValues(values); | 105 mTransform.getValues(values); |
| 106 | |
| 107 // Screen coordinates of two defining points of the image. | |
| 94 float[] topleft = {0, 0}; | 108 float[] topleft = {0, 0}; |
| 95 mTransform.mapPoints(topleft); | 109 mTransform.mapPoints(topleft); |
| 96 float[] bottomright = {image.getWidth(), image.getHeight()}; | 110 float[] bottomright = {image.getWidth(), image.getHeight()}; |
| 97 mTransform.mapPoints(bottomright); | 111 mTransform.mapPoints(bottomright); |
| 98 | 112 |
| 99 if (mConstraint==Constraint.UNDEFINED) { | 113 if (mConstraint == Constraint.UNDEFINED) { |
| 100 mConstraint = image.getWidth()/image.getHeight() > mScreenWidth/ mScreenHeight ? | 114 mConstraint = image.getWidth()/image.getHeight() > mScreenWidth/ mScreenHeight ? |
| 101 Constraint.HEIGHT : Constraint.WIDTH; | 115 Constraint.WIDTH : Constraint.HEIGHT; |
| 102 } | 116 } |
| 103 | 117 |
| 104 if (mConstraint==Constraint.WIDTH && bottomright[0] - topleft[0] < m ScreenWidth) { | 118 if (mConstraint == Constraint.WIDTH && |
| 105 mTransform.setPolyToPoly(new float[] {0, 0, image.getWidth(), 0} , 0, | 119 (int)(bottomright[0] - topleft[0] + 0.5) < mScreenWidth) { |
| 106 new float[] {0, 0, mScreenWidth, 0}, 0, 2); | 120 // The vertical edges of the image are flush against the dev ice's screen edges |
| 107 } else if (mConstraint==Constraint.HEIGHT && | 121 // when the entire host screen is visible, and the user has zoomed out too far. |
| 108 bottomright[1] - topleft[1] < mScreenHeight) { | 122 float imageMiddle = (float)image.getHeight() / 2; |
| 109 mTransform.setPolyToPoly(new float[] {0, 0, 0, image.getHeight() }, 0, | 123 float screenMiddle = (float)mScreenHeight / 2; |
| 110 new float[] {0, 0, 0, mScreenHeight}, 0, 2); | 124 mTransform.setPolyToPoly( |
| 125 new float[] {0, imageMiddle, image.getWidth(), imageMidd le}, 0, | |
| 126 new float[] {0, screenMiddle, mScreenWidth, screenMiddle }, 0, 2); | |
| 127 } else if (mConstraint == Constraint.HEIGHT && | |
| 128 (int)(bottomright[1] - topleft[1] + 0.5) < mScreenHeight) { | |
| 129 // The horizontal image edges are flush against the device's screen edges when | |
| 130 // the entire host screen is visible, and the user has zoome d out too far. | |
| 131 float imageCenter = (float)image.getWidth() / 2; | |
| 132 float screenCenter = (float)mScreenWidth / 2; | |
| 133 mTransform.setPolyToPoly( | |
| 134 new float[] {imageCenter, 0, imageCenter, image.getHeigh t()}, 0, | |
| 135 new float[] {screenCenter, 0, screenCenter, mScreenHeigh t}, 0, 2); | |
| 111 } else { | 136 } else { |
| 112 if (values[Matrix.MTRANS_X] > 0) { | 137 // It's fine for both members of a pair of image edges to be within the screen |
| 113 values[Matrix.MTRANS_X] = 0; | 138 // edges (or "out of bounds"); that simply means that the im age is zoomed out as |
| 139 // far as permissible. And both members of a pair can obviou sly be outside the | |
| 140 // screen's edges, which indicates that the image is zoomed in to far to see the | |
| 141 // whole host screen. However, if only one of a pair of edge s has entered the | |
| 142 // screen, the user is attempting to scroll into a blank are a of the canvas. | |
|
garykac
2013/07/20 21:10:44
These comments (here and above) seem indented stra
solb
2013/07/21 08:18:07
Okay; I'll bump them out one level.
| |
| 143 // A value of true means the corresponding edge has entered the screen's borders. | |
| 144 boolean leftEdgeOutOfBounds = values[Matrix.MTRANS_X] > 0; | |
| 145 boolean topEdgeOutOfBounds = values[Matrix.MTRANS_Y] > 0; | |
| 146 boolean rightEdgeOutOfBounds = bottomright[0] < mScreenWidth; | |
| 147 boolean bottomEdgeOutOfBounds = bottomright[1] < mScreenHeight; | |
| 148 | |
| 149 if (leftEdgeOutOfBounds != rightEdgeOutOfBounds) { | |
| 150 if (leftEdgeOutOfBounds != mRightUsedToBeOut) { | |
| 151 values[Matrix.MTRANS_X] = 0; | |
| 152 } | |
| 153 else { | |
| 154 values[Matrix.MTRANS_X] += mScreenWidth - bottomright[0] ; | |
| 155 } | |
| 114 } | 156 } |
| 115 if (values[Matrix.MTRANS_Y] > 0) { | 157 else { // Updating this value during an attempt to scroll away causes oscillation. |
|
garykac
2013/07/20 21:10:44
If these comments apply to the line below, then th
solb
2013/07/21 08:18:07
Actually, this comment was intended to explain the
| |
| 116 values[Matrix.MTRANS_Y] = 0; | 158 mRightUsedToBeOut = rightEdgeOutOfBounds; |
| 117 } | 159 } |
| 118 if (bottomright[0] < mScreenWidth) { | 160 |
| 119 values[Matrix.MTRANS_X] += mScreenWidth - bottomright[0]; | 161 if (topEdgeOutOfBounds != bottomEdgeOutOfBounds) { |
| 162 if (topEdgeOutOfBounds != mBottomUsedToBeOut) { | |
| 163 values[Matrix.MTRANS_Y] = 0; | |
| 164 } | |
| 165 else { | |
| 166 values[Matrix.MTRANS_Y] += mScreenHeight - bottomright[1 ]; | |
| 167 } | |
| 120 } | 168 } |
| 121 if (bottomright[1] < mScreenHeight) { | 169 else { // Updating this value during an attempt to scroll away causes oscillation. |
| 122 values[Matrix.MTRANS_Y] += mScreenHeight - bottomright[1]; | 170 mBottomUsedToBeOut = bottomEdgeOutOfBounds; |
| 123 } | 171 } |
| 124 | 172 |
| 125 mTransform.setValues(values); | 173 mTransform.setValues(values); |
| 126 } | 174 } |
| 127 | 175 |
| 128 canvas.setMatrix(mTransform); | 176 canvas.setMatrix(mTransform); |
| 129 } | 177 } |
| 130 | 178 |
| 131 canvas.drawColor(Color.BLACK); | 179 canvas.drawColor(Color.BLACK); |
| 132 canvas.drawBitmap(image, 0, 0, new Paint()); | 180 canvas.drawBitmap(image, 0, 0, new Paint()); |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 230 | 278 |
| 231 /** | 279 /** |
| 232 * Called when the user is done zooming. Defers to onScale()'s judgement . | 280 * Called when the user is done zooming. Defers to onScale()'s judgement . |
| 233 */ | 281 */ |
| 234 @Override | 282 @Override |
| 235 public void onScaleEnd(ScaleGestureDetector detector) { | 283 public void onScaleEnd(ScaleGestureDetector detector) { |
| 236 onScale(detector); | 284 onScale(detector); |
| 237 } | 285 } |
| 238 } | 286 } |
| 239 } | 287 } |
| OLD | NEW |