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

Side by Side Diff: remoting/android/java/src/org/chromium/chromoting/DesktopCanvas.java

Issue 2375113003: Allow Desktop Canvas to be scrolled out from under System UI. (Closed)
Patch Set: Pre-CR tweaks Created 4 years, 2 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 unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 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.graphics.Matrix; 7 import android.graphics.Matrix;
8 import android.graphics.PointF; 8 import android.graphics.PointF;
9 import android.graphics.Rect; 9 import android.graphics.Rect;
10 import android.graphics.RectF; 10 import android.graphics.RectF;
11 11
12 /** 12 /**
13 * This class is responsible for transforming the desktop image matrix. 13 * This class is responsible for transforming the desktop image matrix.
14 */ 14 */
15 public class DesktopCanvas { 15 public class DesktopCanvas {
16 /** 16 /**
17 * Maximum allowed zoom level - see {@link #repositionImageWithZoom()}. 17 * Maximum allowed zoom level - see {@link #repositionImageWithZoom()}.
18 */ 18 */
19 private static final float MAX_ZOOM_FACTOR = 100.0f; 19 private static final float MAX_ZOOM_FACTOR = 100.0f;
20 20
21 /**
22 * Used to smoothly reduce the amount of padding whle the user is zooming.
Lambros 2016/09/30 01:59:37 s/whle/while/
joedow 2016/09/30 19:42:57 Done.
23 */
24 private static final float PADDING_REDUCTION_FACTOR = 0.85f;
25
21 private final RenderStub mRenderStub; 26 private final RenderStub mRenderStub;
22 private final RenderData mRenderData; 27 private final RenderData mRenderData;
23 28
24 /** 29 /**
25 * Represents the actual center of the viewport. This value needs to be a p air of floats so the 30 * Represents the actual center of the viewport. This value needs to be a p air of floats so the
26 * desktop image can be positioned with sub-pixel accuracy for smoother pann ing animations at 31 * desktop image can be positioned with sub-pixel accuracy for smoother pann ing animations at
27 * high zoom levels. 32 * high zoom levels.
28 */ 33 */
29 private PointF mViewportPosition = new PointF(); 34 private PointF mViewportPosition = new PointF();
30 35
31 /** 36 /**
32 * Represents the desired center of the viewport. This value may not repres ent the actual 37 * Represents the desired center of the viewport. This value may not repres ent the actual
33 * center of the viewport as adjustments are made to ensure as much of the d esktop is visible as 38 * center of the viewport as adjustments are made to ensure as much of the d esktop is visible as
34 * possible. This value needs to be a pair of floats so the desktop image c an be positioned 39 * possible. This value needs to be a pair of floats so the desktop image c an be positioned
35 * with sub-pixel accuracy for smoother panning animations at high zoom leve ls. 40 * with sub-pixel accuracy for smoother panning animations at high zoom leve ls.
36 */ 41 */
37 private PointF mCursorPosition = new PointF(); 42 private PointF mCursorPosition = new PointF();
38 43
39 /** 44 /**
40 * Represents the amount of space, in pixels, used by System UI. 45 * Represents the amount of space, in pixels, used by System UI.
41 */ 46 */
42 private Rect mSystemUiOffsetPixels = new Rect(); 47 private Rect mSystemUiOffsetPixels = new Rect();
43 48
49 /**
50 * Represents the additional space, in pixels, for each edge of the desktop image. Used for
51 * positioning the desktop canvas to allow the user to scroll it below any v isible System UI.
Lambros 2016/09/30 01:59:36 Is this in screen or image coordinates? Can you ex
joedow 2016/09/30 19:42:56 Added a block of text at the top of the class givi
52 */
53 private RectF mImagePadding = new RectF();
54
44 public DesktopCanvas(RenderStub renderStub, RenderData renderData) { 55 public DesktopCanvas(RenderStub renderStub, RenderData renderData) {
45 mRenderStub = renderStub; 56 mRenderStub = renderStub;
46 mRenderData = renderData; 57 mRenderData = renderData;
47 } 58 }
48 59
49 /** 60 /**
50 * Sets the desired center position of the viewport (a.k.a. the cursor posit ion) and ensures 61 * Sets the desired center position of the viewport (a.k.a. the cursor posit ion) and ensures
51 * the viewport is updated to include the cursor within it. 62 * the viewport is updated to include the cursor within it.
52 * 63 *
53 * @param newX The new x coordinate value for the desired center position. 64 * @param newX The new x coordinate value for the desired center position.
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
162 mRenderData.transform.mapVectors(imageSize); 173 mRenderData.transform.mapVectors(imageSize);
163 174
164 if (imageSize[0] < mRenderData.screenWidth && imageSize[1] < mRenderData .screenHeight) { 175 if (imageSize[0] < mRenderData.screenWidth && imageSize[1] < mRenderData .screenHeight) {
165 // Displayed image is too small in both directions, so apply the min imum zoom 176 // Displayed image is too small in both directions, so apply the min imum zoom
166 // level needed to fit either the width or height. 177 // level needed to fit either the width or height.
167 float scale = Math.min((float) mRenderData.screenWidth / mRenderData .imageWidth, 178 float scale = Math.min((float) mRenderData.screenWidth / mRenderData .imageWidth,
168 (float) mRenderData.screenHeight / mRenderDat a.imageHeight); 179 (float) mRenderData.screenHeight / mRenderDat a.imageHeight);
169 mRenderData.transform.setScale(scale, scale); 180 mRenderData.transform.setScale(scale, scale);
170 } 181 }
171 182
183 // Trim the image padding if the user is zooming out. This prevents cas es where the image
184 // pops to the center when it reaches its minimum size. Note that we do not need to do
185 // anything when the user is zooming in as the canvas will expand and ab sorb the padding.
186 if (scaleFactor < 1.0f) {
187 mImagePadding.set(mImagePadding.left * PADDING_REDUCTION_FACTOR,
188 mImagePadding.top * PADDING_REDUCTION_FACTOR,
189 mImagePadding.right * PADDING_REDUCTION_FACTOR,
190 mImagePadding.bottom * PADDING_REDUCTION_FACTOR);
191 }
192
172 if (centerOnCursor) { 193 if (centerOnCursor) {
173 setCursorPosition(mCursorPosition.x, mCursorPosition.y); 194 setCursorPosition(mCursorPosition.x, mCursorPosition.y);
174 } else { 195 } else {
175 // Find the new screen center (it was probably changed during the zo om operation) and 196 // Find the new screen center (it was probably changed during the zo om operation) and
176 // update the viewport and cursor. 197 // update the viewport and cursor.
177 float[] mappedPoints = { 198 float[] mappedPoints = {
178 ((float) mRenderData.screenWidth / 2), ((float) mRenderData. screenHeight / 2)}; 199 ((float) mRenderData.screenWidth / 2), ((float) mRenderData. screenHeight / 2)};
179 Matrix screenToImage = new Matrix(); 200 Matrix screenToImage = new Matrix();
180 mRenderData.transform.invert(screenToImage); 201 mRenderData.transform.invert(screenToImage);
181 screenToImage.mapPoints(mappedPoints); 202 screenToImage.mapPoints(mappedPoints);
182 // The cursor is mapped to the center of the viewport in this case. 203 // The cursor is mapped to the center of the viewport in this case.
183 setCursorPosition(mappedPoints[0], mappedPoints[1]); 204 setCursorPosition(mappedPoints[0], mappedPoints[1]);
184 } 205 }
185 } 206 }
186 207
187 /** 208 /**
188 * Repositions the image by translating it (without affecting the zoom level ). 209 * Repositions the image by translating it (without affecting the zoom level ).
189 */ 210 */
190 private void repositionImage() { 211 private void repositionImage() {
191 // Map the current viewport position to screen coordinates and adjust th e image position. 212 // Map the current viewport position to screen coordinates and adjust th e image position.
192 float[] viewportPosition = {mViewportPosition.x, mViewportPosition.y}; 213 float[] viewportPosition = {mViewportPosition.x, mViewportPosition.y};
193 mRenderData.transform.mapPoints(viewportPosition); 214 mRenderData.transform.mapPoints(viewportPosition);
194 215
195 float viewportTransX = ((float) mRenderData.screenWidth / 2) - viewportP osition[0]; 216 float viewportTransX = ((float) mRenderData.screenWidth / 2) - viewportP osition[0];
196 float viewportTransY = ((float) mRenderData.screenHeight / 2) - viewport Position[1]; 217 float viewportTransY = ((float) mRenderData.screenHeight / 2) - viewport Position[1];
197 218
198 // Translate the image so the viewport center is displayed in the middle of the screen. 219 // Translate the image so the viewport center is displayed in the middle of the screen.
199 mRenderData.transform.postTranslate(viewportTransX, viewportTransY); 220 mRenderData.transform.postTranslate(viewportTransX, viewportTransY);
200 221
222 // Remove or add image padding based on the new position.
Lambros 2016/09/30 01:59:37 How is padding based on position?
joedow 2016/09/30 19:42:56 Removed comment since it wan't useful.
223 adjustImagePadding();
224
201 mRenderStub.setTransformation(mRenderData.transform); 225 mRenderStub.setTransformation(mRenderData.transform);
202 } 226 }
203 227
204 /** 228 /**
205 * Updates the given point such that it refers to a coordinate within the bo unds provided. 229 * Updates the given point such that it refers to a coordinate within the bo unds provided.
206 * 230 *
207 * @param point The point to adjust, the original object is modified. 231 * @param point The point to adjust, the original object is modified.
208 * @param bounds The bounds used to constrain the point. 232 * @param bounds The bounds used to constrain the point.
209 */ 233 */
210 private void constrainPointToBounds(PointF point, RectF bounds) { 234 private void constrainPointToBounds(PointF point, RectF bounds) {
211 if (point.x < bounds.left) { 235 if (point.x < bounds.left) {
212 point.x = bounds.left; 236 point.x = bounds.left;
213 } else if (point.x > bounds.right) { 237 } else if (point.x > bounds.right) {
214 point.x = bounds.right; 238 point.x = bounds.right;
215 } 239 }
216 240
217 if (point.y < bounds.top) { 241 if (point.y < bounds.top) {
218 point.y = bounds.top; 242 point.y = bounds.top;
219 } else if (point.y > bounds.bottom) { 243 } else if (point.y > bounds.bottom) {
220 point.y = bounds.bottom; 244 point.y = bounds.bottom;
221 } 245 }
222 } 246 }
223 247
224 /** Returns a region which defines the set of valid cursor values in image s pace. */ 248 /** Returns a region which defines the set of valid cursor values in image s pace. */
225 private RectF getImageBounds() { 249 private RectF getImageBounds() {
226 return new RectF(0, 0, mRenderData.imageWidth, mRenderData.imageHeight); 250 float[] maxPadding = getMaxPadding();
251 return new RectF(-maxPadding[0], -maxPadding[1], mRenderData.imageWidth + maxPadding[2],
Lambros 2016/09/30 01:59:36 If my reading is correct, this is the full image r
joedow 2016/09/30 19:42:56 I'll remove the maxPadding method since it is conf
252 mRenderData.imageHeight + maxPadding[3]);
227 } 253 }
228 254
229 /** Returns a region which defines the set of valid viewport center values i n image space. */ 255 /** Returns a region which defines the set of valid viewport center values i n image space. */
230 private RectF getViewportBounds() { 256 private RectF getViewportBounds() {
231 float[] screenVectors = {(float) mRenderData.screenWidth, (float) mRende rData.screenHeight}; 257 float[] screenVectors = {(float) mRenderData.screenWidth, (float) mRende rData.screenHeight};
232 Matrix screenToImage = new Matrix(); 258 Matrix screenToImage = new Matrix();
233 mRenderData.transform.invert(screenToImage); 259 mRenderData.transform.invert(screenToImage);
234 screenToImage.mapVectors(screenVectors); 260 screenToImage.mapVectors(screenVectors);
235 261
236 float xAdjust = 0.0f; 262 float[] letterBoxPadding = getLetterboxPadding();
237 if (mRenderData.imageWidth < screenVectors[0]) { 263 screenToImage.mapVectors(letterBoxPadding);
238 // Image is narrower than the screen, so adjust the bounds to center it.
239 xAdjust = (screenVectors[0] - mRenderData.imageWidth) / 2.0f;
240 }
241
242 float yAdjust = 0.0f;
243 if (mRenderData.imageHeight < screenVectors[1]) {
244 // Image is shorter than the screen, so adjust the bounds to center it.
245 yAdjust = (screenVectors[1] - mRenderData.imageHeight) / 2.0f;
246 }
247 264
248 // screenCenter values are 1/2 of a particular screen dimension mapped t o image space. 265 // screenCenter values are 1/2 of a particular screen dimension mapped t o image space.
249 float screenCenterX = screenVectors[0] / 2.0f; 266 float screenCenterX = (screenVectors[0] / 2.0f) - letterBoxPadding[0];
250 float screenCenterY = screenVectors[1] / 2.0f; 267 float screenCenterY = (screenVectors[1] / 2.0f) - letterBoxPadding[1];
251 return new RectF(screenCenterX - xAdjust, screenCenterY - yAdjust, 268 RectF imageBounds = getImageBounds();
252 mRenderData.imageWidth - screenCenterX + xAdjust, 269 return new RectF(imageBounds.left + screenCenterX, imageBounds.top + scr eenCenterY,
Lambros 2016/09/30 01:59:36 return imageBounds.inset(screenCenterX, screenCent
joedow 2016/09/30 19:42:57 Done.
253 mRenderData.imageHeight - screenCenterY + yAdjust); 270 imageBounds.right - screenCenterX, imageBounds.bottom - screenCe nterY);
271 }
272
273 /** Returns the maximum amount of padding per edge (left, top, right, bottom ) in image space. */
274 private float[] getMaxPadding() {
275 RectF systemUiOffsetPixels = getAdjustedSystemUiOffsets();
276 float[] maxPadding = {Math.max(mImagePadding.left, systemUiOffsetPixels. left),
277 Math.max(mImagePadding.top, systemUiOffsetPixels.top),
278 Math.max(mImagePadding.right, systemUiOffsetPixels.right),
279 Math.max(mImagePadding.bottom, systemUiOffsetPixels.bottom)};
280 Matrix screenToImage = new Matrix();
281 mRenderData.transform.invert(screenToImage);
282 screenToImage.mapVectors(maxPadding);
283
284 return maxPadding;
285 }
286
287 /** Returns the letter box padding needed in each dimension (x and y) in scr een coordinates. */
Lambros 2016/09/30 01:59:37 Maybe explain in a little more detail: This is the
joedow 2016/09/30 19:42:57 Explained in detail at the top of the class.
288 private float[] getLetterboxPadding() {
Lambros 2016/09/30 01:59:36 Maybe return PointF ?
joedow 2016/09/30 19:42:57 I had originally left this as a float [] to make t
289 float[] imageVectors = {mRenderData.imageWidth, mRenderData.imageHeight} ;
290 mRenderData.transform.mapVectors(imageVectors);
291
292 // We want to letterbox when the image is smaller than the screen in a s pecific dimension.
293 // Since we center the image, split the difference so it is equally dist ributed.
294 float widthAdjust =
295 Math.max(0.0f, ((float) mRenderData.screenWidth - imageVectors[0 ]) / 2.0f);
296 float heightAdjust =
297 Math.max(0.0f, ((float) mRenderData.screenHeight - imageVectors[ 1]) / 2.0f);
298
299 return new float[] {widthAdjust, heightAdjust};
300 }
301
302 /**
303 * Returns the amount of System UI, adjusted for letter boxing, which should be used for
304 * padding calculations.
305 */
306 private RectF getAdjustedSystemUiOffsets() {
307 float[] letterBoxPadding = getLetterboxPadding();
308 return new RectF(Math.max(mSystemUiOffsetPixels.left - letterBoxPadding[ 0], 0.0f),
309 Math.max(mSystemUiOffsetPixels.top - letterBoxPadding[1], 0.0f),
310 Math.max(mSystemUiOffsetPixels.right - letterBoxPadding[0], 0.0f ),
311 Math.max(mSystemUiOffsetPixels.bottom - letterBoxPadding[1], 0.0 f));
312 }
313
314 /** Updates the padding used to allow the user to scroll the image out from under System UI. */
315 private void adjustImagePadding() {
316 float[] letterBoxPadding = getLetterboxPadding();
317 RectF systemUiOffsetPixels = getAdjustedSystemUiOffsets();
318 float[] imagePoints = {0.0f, 0.0f, mRenderData.imageWidth, mRenderData.i mageHeight};
319 mRenderData.transform.mapPoints(imagePoints);
320
321 mImagePadding.set(
322 adjustEdge(systemUiOffsetPixels.left, mImagePadding.left,
323 imagePoints[0] - letterBoxPadding[0]),
324 adjustEdge(systemUiOffsetPixels.top, mImagePadding.top,
325 imagePoints[1] - letterBoxPadding[1]),
326 adjustEdge(systemUiOffsetPixels.right, mImagePadding.right,
327 mRenderData.screenWidth - imagePoints[2] - letterBoxPadd ing[0]),
328 adjustEdge(systemUiOffsetPixels.bottom, mImagePadding.bottom,
329 mRenderData.screenHeight - imagePoints[3] - letterBoxPad ding[1]));
330 }
331
332 /**
333 * Update the current edge padding based on the current System UI and image postion state.
Lambros 2016/09/30 01:59:36 s/postion/position/
joedow 2016/09/30 19:42:56 Done.
334 *
335 * @param systemUiPadding Amount of visible System UI in pixels.
336 * @param currentPadding Amount of padding used, in pixels, for position cal culations.
337 * @param visiblePixels Amount of padding actually visible, in pixels.
338 * @return The new value, in pixels, to be used for positioning.
339 */
340 private float adjustEdge(float systemUiPadding, float currentPadding, float visiblePixels) {
341 float edgeValue;
342 visiblePixels = Math.max(visiblePixels, 0.0f);
343 if (systemUiPadding > 0.0f) {
344 if (systemUiPadding > currentPadding) {
345 // Add enough padding to allow scrolling the desktop out from un der the System UI.
346 edgeValue = Math.min(systemUiPadding, visiblePixels);
347 } else if (systemUiPadding < currentPadding) {
348 // Remove unneeded padding from the canvas.
349 edgeValue = Math.max(systemUiPadding, Math.min(currentPadding, v isiblePixels));
350 } else {
351 // If current and system padding sizes are the same, then keep t he visible portion.
352 edgeValue = Math.min(currentPadding, visiblePixels);
353 }
354 } else if (currentPadding > 0.0f) {
355 // If we have existing padding, then trim if possible, otherwise kee p the same value.
356 edgeValue = Math.min(currentPadding, visiblePixels);
357 } else {
358 // Use zero padding if there is no system or current padding specifi ed.
359 edgeValue = 0.0f;
360 }
361 return edgeValue;
254 } 362 }
255 } 363 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698