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

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

Issue 2372663002: Separating cursor and viewport calculations in the desktop canvas (Closed)
Patch Set: Merging with ToT and doing some pre-review clean-up Created 4 years, 3 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/TouchInputHandler.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/DesktopCanvas.java
diff --git a/remoting/android/java/src/org/chromium/chromoting/DesktopCanvas.java b/remoting/android/java/src/org/chromium/chromoting/DesktopCanvas.java
index 35f9ee6709c1beefaa4272a8919d23fdb0364f99..9a15b0139f3796431e8bdd8c529c2598340f27b1 100644
--- a/remoting/android/java/src/org/chromium/chromoting/DesktopCanvas.java
+++ b/remoting/android/java/src/org/chromium/chromoting/DesktopCanvas.java
@@ -22,12 +22,19 @@ public class DesktopCanvas {
private final RenderData mRenderData;
/**
+ * Represents the actual center of the viewport. This value needs to be a pair of floats so the
+ * desktop image can be positioned with sub-pixel accuracy for smoother panning animations at
+ * high zoom levels.
+ */
+ private PointF mViewportPosition = new PointF();
+
+ /**
* Represents the desired center of the viewport. This value may not represent the actual
* center of the viewport as adjustments are made to ensure as much of the desktop is visible as
* possible. This value needs to be a pair of floats so the desktop image can be positioned
* with sub-pixel accuracy for smoother panning animations at high zoom levels.
*/
- private PointF mViewportPosition = new PointF();
+ private PointF mCursorPosition = new PointF();
/**
* Represents the amount of space, in pixels, used by System UI.
@@ -40,67 +47,47 @@ public class DesktopCanvas {
}
/**
- * Shifts the viewport by the passed in deltas (in image coordinates).
+ * Sets the desired center position of the viewport.
*
- * @param useScreenCenter Determines whether to use the desired viewport position or the actual
- * center of the screen for positioning.
- * @param deltaX The distance (in image coordinates) to move the viewport along the x-axis.
- * @param deltaY The distance (in image coordinates) to move the viewport along the y-axis.
- * @return A point representing the new center position of the viewport.
+ * @param newX The new x coordinate value for the desired center position.
+ * @param newY The new y coordinate value for the desired center position.
*/
- public PointF moveViewportCenter(boolean useScreenCenter, float deltaX, float deltaY) {
- PointF viewportCenter;
- if (useScreenCenter) {
- viewportCenter = getTrueViewportCenter();
- } else {
- viewportCenter = new PointF(mViewportPosition.x, mViewportPosition.y);
- }
- viewportCenter.offset(deltaX, deltaY);
-
- RectF bounds = new RectF(0, 0, mRenderData.imageWidth, mRenderData.imageHeight);
-
- if (viewportCenter.x < bounds.left) {
- viewportCenter.x = bounds.left;
- } else if (viewportCenter.x > bounds.right) {
- viewportCenter.x = bounds.right;
- }
-
- if (viewportCenter.y < bounds.top) {
- viewportCenter.y = bounds.top;
- } else if (viewportCenter.y > bounds.bottom) {
- viewportCenter.y = bounds.bottom;
- }
-
- mViewportPosition.set(viewportCenter);
-
- return viewportCenter;
+ public void setViewportCenter(float newX, float newY) {
Lambros 2016/09/27 02:16:37 This should probably be called setCursorAndViewpor
joedow 2016/09/27 20:09:29 Updating the name is fine, but I'd prefer to name
+ // First set the cursor position since its potential values are a superset of the viewport.
+ mCursorPosition.set(newX, newY);
+ constrainPointToBounds(mCursorPosition, getImageBounds());
+
+ // Now set the viewport position based on the cursor.
+ mViewportPosition.set(mCursorPosition);
+ constrainPointToBounds(mViewportPosition, getViewportBounds());
}
/**
- * Sets the desired center position of the viewport.
+ * Shifts the viewport by the passed in values (in image coordinates).
*
- * @param newX The new x coordinate value for the desired center position.
- * @param newY The new y coordinate value for the desired center position.
+ * @param deltaX The distance (in image coordinates) to move the viewport along the x-axis.
+ * @param deltaY The distance (in image coordinates) to move the viewport along the y-axis.
*/
- public void setViewportPosition(float newX, float newY) {
- mViewportPosition.set(newX, newY);
+ public void moveViewportCenter(float deltaX, float deltaY) {
Lambros 2016/09/27 02:16:37 Clarify this does not actually move the viewport -
joedow 2016/09/27 20:09:29 Acknowledged.
+ // Offset and adjust the viewport center position to fit the screen.
+ mViewportPosition.offset(deltaX, deltaY);
+ constrainPointToBounds(mViewportPosition, getViewportBounds());
+
+ // We don't need to constrain the cursor position as the viewport position is always within
+ // the bounds of the potential cursor positions.
+ mCursorPosition.set(mViewportPosition);
}
/**
- * Returns the true center position of the viewport (in image coordinates).
+ * Shifts the cursor by the passed in values (in image coordinates) and adjusts the viewport.
*
- * @return A point representing the true center position of the viewport.
+ * @param deltaX The distance (in image coordinates) to move the cursor along the x-axis.
+ * @param deltaY The distance (in image coordinates) to move the cursor along the y-axis.
+ * @return A point representing the new cursor position.
*/
- private PointF getTrueViewportCenter() {
- // Find the center point of the viewport on the screen.
- float[] viewportPosition = {
- ((float) mRenderData.screenWidth / 2), ((float) mRenderData.screenHeight / 2)};
-
- // Convert the screen position to an image position.
- Matrix screenToImage = new Matrix();
- mRenderData.transform.invert(screenToImage);
- screenToImage.mapPoints(viewportPosition);
- return new PointF(viewportPosition[0], viewportPosition[1]);
+ public PointF moveViewportWithCursor(float deltaX, float deltaY) {
Lambros 2016/09/27 02:16:36 Maybe offsetCursorAndSetViewportPosition() ?
joedow 2016/09/27 20:09:29 Renamed based on intention of the caller.
+ setViewportCenter(mCursorPosition.x + deltaX, mCursorPosition.y + deltaY);
+ return new PointF(mCursorPosition.x, mCursorPosition.y);
}
/**
@@ -136,44 +123,136 @@ public class DesktopCanvas {
if (screenToImageScale > 1.0f) {
mRenderData.transform.setScale(screenToImageScale, screenToImageScale);
}
-
- repositionImage(false);
}
/**
* Repositions the image by translating it (without affecting the zoom level).
- *
- * @param centerViewport Determines whether the viewport will be translated to the desired
- * center position before being adjusted to fit the screen boundaries.
*/
- public void repositionImage(boolean centerViewport) {
+ public void repositionImage() {
// The goal of the code below is to position the viewport as close to the desired center
Lambros 2016/09/27 02:16:36 The phrase 'desired center' is how you've describe
joedow 2016/09/27 20:09:29 Acknowledged.
// position as possible whilst keeping as much of the desktop in view as possible.
// To achieve these goals, we first position the desktop image at the desired center
// point and then re-position it to maximize the viewable area.
- if (centerViewport) {
- // Map the current viewport position to screen coordinates.
- float[] viewportPosition = {mViewportPosition.x, mViewportPosition.y};
- mRenderData.transform.mapPoints(viewportPosition);
+ moveViewportToPoint(mViewportPosition);
Lambros 2016/09/27 02:16:37 This call modifies the transformation matrix so th
joedow 2016/09/27 20:09:28 Acknowledged.
+ translateImageToFitScreen();
Lambros 2016/09/27 02:16:37 But this call will modify the matrix *without* upd
joedow 2016/09/27 20:09:29 Acknowledged.
+ }
+
+ /**
+ * Repositions the image by translating and zooming it, to keep the zoom level within sensible
+ * limits. The minimum zoom level is chosen to avoid black space around all 4 sides. The
+ * maximum zoom level is set arbitrarily, so that the user can zoom out again in a reasonable
+ * time, and to prevent arithmetic overflow problems from displaying the image.
+ *
+ * @param centerOnCursor Determines whether the viewport will be translated to the desired
+ * center position before being adjusted to fit the screen boundaries.
+ */
+ public void repositionImageWithZoom(boolean centerOnCursor) {
+ // Avoid division by zero in case this gets called before the image size is initialized.
+ if (mRenderData.imageWidth == 0 || mRenderData.imageHeight == 0) {
+ return;
+ }
- float viewportTransX = ((float) mRenderData.screenWidth / 2) - viewportPosition[0];
- float viewportTransY = ((float) mRenderData.screenHeight / 2) - viewportPosition[1];
+ // Zoom out if the zoom level is too high.
+ float currentZoomLevel = mRenderData.transform.mapRadius(1.0f);
+ if (currentZoomLevel > MAX_ZOOM_FACTOR) {
+ mRenderData.transform.setScale(MAX_ZOOM_FACTOR, MAX_ZOOM_FACTOR);
+ }
- // Translate so the viewport is displayed in the middle of the screen.
- mRenderData.transform.postTranslate(viewportTransX, viewportTransY);
+ // Get image size scaled to screen coordinates.
+ float[] imageSize = {mRenderData.imageWidth, mRenderData.imageHeight};
+ mRenderData.transform.mapVectors(imageSize);
+
+ if (imageSize[0] < mRenderData.screenWidth && imageSize[1] < mRenderData.screenHeight) {
+ // Displayed image is too small in both directions, so apply the minimum zoom
+ // level needed to fit either the width or height.
+ float scale = Math.min((float) mRenderData.screenWidth / mRenderData.imageWidth,
+ (float) mRenderData.screenHeight / mRenderData.imageHeight);
+ mRenderData.transform.setScale(scale, scale);
}
+ if (centerOnCursor) {
+ moveViewportToPoint(mCursorPosition);
+ }
+
+ translateImageToFitScreen();
+
+ // Update our position members to reflect the new position of the image.
+ PointF newPosition;
+ if (centerOnCursor) {
+ newPosition = new PointF(mCursorPosition.x, mCursorPosition.y);
+ } else {
+ float screenCenterX = (float) mRenderData.screenWidth / 2;
+ float screenCenterY = (float) mRenderData.screenHeight / 2;
+ float[] mappedPoints = {screenCenterX, screenCenterY};
+ Matrix screenToImage = new Matrix();
+ mRenderData.transform.invert(screenToImage);
+ screenToImage.mapPoints(mappedPoints);
+ newPosition = new PointF(mappedPoints[0], mappedPoints[1]);
+ }
+ setViewportCenter(newPosition.x, newPosition.y);
+ }
+
+ /**
+ * Updates the given point such that it refers to a coordinate within the bounds provided.
+ *
+ * @param point The point to adjust, the original object is modified.
+ * @param bounds The bounds used to constrain the point.
+ */
+ private void constrainPointToBounds(PointF point, RectF bounds) {
+ if (point.x < bounds.left) {
+ point.x = bounds.left;
+ } else if (point.x > bounds.right) {
+ point.x = bounds.right;
+ }
+
+ if (point.y < bounds.top) {
+ point.y = bounds.top;
+ } else if (point.y > bounds.bottom) {
+ point.y = bounds.bottom;
+ }
+ }
+
+ /** Returns a region which defines the set of valid cursor values in image space. */
+ private RectF getImageBounds() {
+ return new RectF(0, 0, mRenderData.imageWidth, mRenderData.imageHeight);
+ }
+
+ /** Returns a region which defines the set of valid viewport center values in image space. */
+ private RectF getViewportBounds() {
Lambros 2016/09/27 02:16:37 IIUC, this is precisely the set of points for whic
joedow 2016/09/27 20:09:29 I was moving to a place where multiple transforms
+ float[] screenVectors = {
+ ((float) mRenderData.screenWidth / 2), ((float) mRenderData.screenHeight / 2)};
+ Matrix screenToImage = new Matrix();
+ mRenderData.transform.invert(screenToImage);
+ screenToImage.mapVectors(screenVectors);
+ return new RectF(screenVectors[0], screenVectors[1],
+ mRenderData.imageWidth - screenVectors[0],
+ mRenderData.imageHeight - screenVectors[1]);
+ }
+
+ /** Centers the viewport on the passed in point. */
+ private void moveViewportToPoint(PointF point) {
+ // Map the current viewport position to screen coordinates.
+ float[] viewportPosition = {point.x, point.y};
+ mRenderData.transform.mapPoints(viewportPosition);
+
+ float viewportTransX = ((float) mRenderData.screenWidth / 2) - viewportPosition[0];
+ float viewportTransY = ((float) mRenderData.screenHeight / 2) - viewportPosition[1];
+
+ // Translate so the viewport is displayed in the middle of the screen.
+ mRenderData.transform.postTranslate(viewportTransX, viewportTransY);
+ }
+
+ /** Repositions the image by translating it to maximize the amount of viewable content. */
+ private void translateImageToFitScreen() {
// Get the coordinates of the desktop rectangle (top-left/bottom-right corners) in
// screen coordinates. Order is: left, top, right, bottom.
RectF rectScreen = new RectF(0, 0, mRenderData.imageWidth, mRenderData.imageHeight);
mRenderData.transform.mapRect(rectScreen);
float leftDelta = rectScreen.left;
- float rightDelta =
- rectScreen.right - mRenderData.screenWidth + mSystemUiOffsetPixels.right;
+ float rightDelta = rectScreen.right - mRenderData.screenWidth;
float topDelta = rectScreen.top;
- float bottomDelta =
- rectScreen.bottom - mRenderData.screenHeight + mSystemUiOffsetPixels.bottom;
+ float bottomDelta = rectScreen.bottom - mRenderData.screenHeight;
float xAdjust = 0;
float yAdjust = 0;
@@ -201,40 +280,4 @@ public class DesktopCanvas {
mRenderStub.setTransformation(mRenderData.transform);
}
-
- /**
- * Repositions the image by translating and zooming it, to keep the zoom level within sensible
- * limits. The minimum zoom level is chosen to avoid black space around all 4 sides. The
- * maximum zoom level is set arbitrarily, so that the user can zoom out again in a reasonable
- * time, and to prevent arithmetic overflow problems from displaying the image.
- *
- * @param centerViewport Determines whether the viewport will be translated to the desired
- * center position before being adjusted to fit the screen boundaries.
- */
- public void repositionImageWithZoom(boolean centerViewport) {
- // Avoid division by zero in case this gets called before the image size is initialized.
- if (mRenderData.imageWidth == 0 || mRenderData.imageHeight == 0) {
- return;
- }
-
- // Zoom out if the zoom level is too high.
- float currentZoomLevel = mRenderData.transform.mapRadius(1.0f);
- if (currentZoomLevel > MAX_ZOOM_FACTOR) {
- mRenderData.transform.setScale(MAX_ZOOM_FACTOR, MAX_ZOOM_FACTOR);
- }
-
- // Get image size scaled to screen coordinates.
- float[] imageSize = {mRenderData.imageWidth, mRenderData.imageHeight};
- mRenderData.transform.mapVectors(imageSize);
-
- if (imageSize[0] < mRenderData.screenWidth && imageSize[1] < mRenderData.screenHeight) {
- // Displayed image is too small in both directions, so apply the minimum zoom
- // level needed to fit either the width or height.
- float scale = Math.min((float) mRenderData.screenWidth / mRenderData.imageWidth,
- (float) mRenderData.screenHeight / mRenderData.imageHeight);
- mRenderData.transform.setScale(scale, scale);
- }
-
- repositionImage(centerViewport);
- }
}
« no previous file with comments | « no previous file | remoting/android/java/src/org/chromium/chromoting/TouchInputHandler.java » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698