From 9594c6987ff70f3630eb47435c7f00f11e289db7 Mon Sep 17 00:00:00 2001 From: Alex Chau Date: Tue, 13 Apr 2021 21:59:42 +0100 Subject: [PATCH] Handle page offset for grid overview - Use TaskView's actual position with grid/fullscreen translation considered for taskPosition calculation - Shift taskPosition by midpoint scroll, and no longer assumes midpoint is on middle of the screen - Handle situation that TaskView is on left/right of midpoint, making the calculation generic to be able to handle grid situation Bug: 175939487 Test: Launch modal view with wide/, RTL/non-RTL, orientation/simulated landscape combinations Change-Id: Idd0cc9c5e24f453d830e1420319a38d3d784270d --- .../android/quickstep/views/RecentsView.java | 130 +++++++++++++----- .../com/android/quickstep/views/TaskView.java | 33 +++-- .../touch/LandscapePagedViewHandler.java | 15 ++ .../touch/PagedOrientationHandler.java | 3 + .../touch/PortraitPagedViewHandler.java | 15 ++ 5 files changed, 150 insertions(+), 46 deletions(-) diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java index 5d3e0b8bf7..1df3d3c18a 100644 --- a/quickstep/src/com/android/quickstep/views/RecentsView.java +++ b/quickstep/src/com/android/quickstep/views/RecentsView.java @@ -270,7 +270,8 @@ public abstract class RecentsView= 0 - ? -getOffsetSize(modalMidpoint - 1, modalMidpoint, modalOffset) - : 0; - float modalRightOffsetSize = modalMidpoint + 1 < count - ? getOffsetSize(modalMidpoint + 1, modalMidpoint, modalOffset) - : 0; + float modalLeftOffsetSize = 0; + float modalRightOffsetSize = 0; + float gridOffsetSize = 0; + + if (showAsGrid) { + // In grid, we only focus the task on the side. The reference index used for offset + // calculation is the task directly next to the focus task in the grid. + int referenceIndex = modalMidpoint == 0 ? 1 : 0; + gridOffsetSize = referenceIndex < count + ? getOffsetSize(referenceIndex, modalMidpoint, modalOffset) + : 0; + } else { + modalLeftOffsetSize = modalMidpoint - 1 >= 0 + ? getOffsetSize(modalMidpoint - 1, modalMidpoint, modalOffset) + : 0; + modalRightOffsetSize = modalMidpoint + 1 < count + ? getOffsetSize(modalMidpoint + 1, modalMidpoint, modalOffset) + : 0; + } for (int i = 0; i < count; i++) { float translation = i == midpoint @@ -2511,20 +2524,36 @@ public abstract class RecentsView -1) { // When there is a midpoint reference task, adjacent tasks have less distance to travel // to reach offscreen. Offset the task position to the task's starting point. - View child = getChildAt(childIndex); - View midpointChild = getChildAt(midpointIndex); - int distanceFromMidpoint = Math.abs(mOrientationHandler.getChildStart(child) - - mOrientationHandler.getChildStart(midpointChild) - + getDisplacementFromScreenCenter(midpointIndex)); - taskPosition.offset(distanceFromMidpoint, 0); + int midpointScroll = getScrollForPage(midpointIndex); + getPersistentChildPosition(midpointIndex, midpointScroll, taskPosition); + float midpointStart = mOrientationHandler.getStart(taskPosition); + + getPersistentChildPosition(childIndex, midpointScroll, taskPosition); + // Assume child does not overlap with midPointChild. + isStartShift = mOrientationHandler.getStart(taskPosition) < midpointStart; + } else { + // Position the task at scroll position. + getPersistentChildPosition(childIndex, getScrollForPage(childIndex), taskPosition); + isStartShift = mIsRtl; } - float distanceToOffscreen = desiredLeft - taskPosition.left; - // Finally, we need to account for RecentsView scale, because it moves tasks based on its - // pivot. To do this, we move the task position to where it would be offscreen at scale = 1 - // (computed above), then we apply the scale via getMatrix() to determine how much that - // moves the task from its desired position, and adjust the computed distance accordingly. - if (mLastComputedTaskPushOutDistance == null) { - taskPosition.offsetTo(desiredLeft, 0); - getMatrix().mapRect(taskPosition); - mLastComputedTaskPushOutDistance = (taskPosition.left - desiredLeft) / getScaleX(); + + // Next, calculate the distance to move the task off screen. We also need to account for + // RecentsView scale, because it moves tasks based on its pivot. To do this, we move the + // task position to where it would be offscreen at scale = 1 (computed above), then we + // apply the scale via getMatrix() to determine how much that moves the task from its + // desired position, and adjust the computed distance accordingly. + float distanceToOffscreen; + if (isStartShift) { + float desiredStart = -mOrientationHandler.getPrimarySize(taskPosition); + distanceToOffscreen = -mOrientationHandler.getEnd(taskPosition); + if (mLastComputedTaskStartPushOutDistance == null) { + taskPosition.offsetTo( + mOrientationHandler.getPrimaryValue(desiredStart, 0f), + mOrientationHandler.getSecondaryValue(desiredStart, 0f)); + getMatrix().mapRect(taskPosition); + mLastComputedTaskStartPushOutDistance = mOrientationHandler.getEnd(taskPosition) + / mOrientationHandler.getPrimaryScale(this); + } + distanceToOffscreen -= mLastComputedTaskStartPushOutDistance; + } else { + float desiredStart = mOrientationHandler.getPrimarySize(this); + distanceToOffscreen = desiredStart - mOrientationHandler.getStart(taskPosition); + if (mLastComputedTaskEndPushOutDistance == null) { + taskPosition.offsetTo( + mOrientationHandler.getPrimaryValue(desiredStart, 0f), + mOrientationHandler.getSecondaryValue(desiredStart, 0f)); + getMatrix().mapRect(taskPosition); + mLastComputedTaskEndPushOutDistance = (mOrientationHandler.getStart(taskPosition) + - desiredStart) / mOrientationHandler.getPrimaryScale(this); + } + distanceToOffscreen -= mLastComputedTaskEndPushOutDistance; } - distanceToOffscreen -= mLastComputedTaskPushOutDistance; return distanceToOffscreen * offsetProgress; } diff --git a/quickstep/src/com/android/quickstep/views/TaskView.java b/quickstep/src/com/android/quickstep/views/TaskView.java index e6143fb055..8f22622058 100644 --- a/quickstep/src/com/android/quickstep/views/TaskView.java +++ b/quickstep/src/com/android/quickstep/views/TaskView.java @@ -987,20 +987,30 @@ public class TaskView extends FrameLayout implements Reusable { private void applyTranslationX() { setTranslationX(mDismissTranslationX + mTaskOffsetTranslationX + mTaskResistanceTranslationX - + getFullscreenTrans(mFullscreenTranslationX) - + getNonFullscreenTrans(mNonFullscreenTranslationX) - + getGridTrans(mGridTranslationX)); + + getPersistentTranslationX()); } private void applyTranslationY() { - setTranslationY( - mDismissTranslationY + mTaskOffsetTranslationY + mTaskResistanceTranslationY - + getGridTrans(mGridTranslationY) + mBoxTranslationY); + setTranslationY(mDismissTranslationY + mTaskOffsetTranslationY + mTaskResistanceTranslationY + + getPersistentTranslationY()); } - private float getGridTrans(float endTranslation) { - float progress = ACCEL_DEACCEL.getInterpolation(mGridProgress); - return Utilities.mapRange(progress, 0, endTranslation); + /** + * Returns addition of translationX that is persistent (e.g. fullscreen and grid), and does not + * change according to a temporary state (e.g. task offset). + */ + public float getPersistentTranslationX() { + return getFullscreenTrans(mFullscreenTranslationX) + + getNonFullscreenTrans(mNonFullscreenTranslationX) + + getGridTrans(mGridTranslationX); + } + + /** + * Returns addition of translationY that is persistent (e.g. fullscreen and grid), and does not + * change according to a temporary state (e.g. task offset). + */ + public float getPersistentTranslationY() { + return getGridTrans(mGridTranslationY) + mBoxTranslationY; } public FloatProperty getPrimaryDismissTranslationProperty() { @@ -1275,6 +1285,11 @@ public class TaskView extends FrameLayout implements Reusable { return endTranslation - getFullscreenTrans(endTranslation); } + private float getGridTrans(float endTranslation) { + float progress = ACCEL_DEACCEL.getInterpolation(mGridProgress); + return Utilities.mapRange(progress, 0, endTranslation); + } + public boolean isRunningTask() { if (getRecentsView() == null) { return false; diff --git a/src/com/android/launcher3/touch/LandscapePagedViewHandler.java b/src/com/android/launcher3/touch/LandscapePagedViewHandler.java index a241e637be..18e27a4ba5 100644 --- a/src/com/android/launcher3/touch/LandscapePagedViewHandler.java +++ b/src/com/android/launcher3/touch/LandscapePagedViewHandler.java @@ -121,11 +121,26 @@ public class LandscapePagedViewHandler implements PagedOrientationHandler { return view.getMeasuredHeight(); } + @Override + public int getPrimarySize(View view) { + return view.getHeight(); + } + @Override public float getPrimarySize(RectF rect) { return rect.height(); } + @Override + public float getStart(RectF rect) { + return rect.top; + } + + @Override + public float getEnd(RectF rect) { + return rect.bottom; + } + @Override public int getClearAllSidePadding(View view, boolean isRtl) { return (isRtl ? view.getPaddingBottom() : - view.getPaddingTop()) / 2; diff --git a/src/com/android/launcher3/touch/PagedOrientationHandler.java b/src/com/android/launcher3/touch/PagedOrientationHandler.java index b85d08addd..560df86379 100644 --- a/src/com/android/launcher3/touch/PagedOrientationHandler.java +++ b/src/com/android/launcher3/touch/PagedOrientationHandler.java @@ -65,7 +65,10 @@ public interface PagedOrientationHandler { float getPrimaryDirection(MotionEvent event, int pointerIndex); float getPrimaryVelocity(VelocityTracker velocityTracker, int pointerId); int getMeasuredSize(View view); + int getPrimarySize(View view); float getPrimarySize(RectF rect); + float getStart(RectF rect); + float getEnd(RectF rect); int getClearAllSidePadding(View view, boolean isRtl); int getSecondaryDimension(View view); FloatProperty getPrimaryViewTranslate(); diff --git a/src/com/android/launcher3/touch/PortraitPagedViewHandler.java b/src/com/android/launcher3/touch/PortraitPagedViewHandler.java index 2fb5952372..86508c4ee2 100644 --- a/src/com/android/launcher3/touch/PortraitPagedViewHandler.java +++ b/src/com/android/launcher3/touch/PortraitPagedViewHandler.java @@ -117,11 +117,26 @@ public class PortraitPagedViewHandler implements PagedOrientationHandler { return view.getMeasuredWidth(); } + @Override + public int getPrimarySize(View view) { + return view.getWidth(); + } + @Override public float getPrimarySize(RectF rect) { return rect.width(); } + @Override + public float getStart(RectF rect) { + return rect.left; + } + + @Override + public float getEnd(RectF rect) { + return rect.right; + } + @Override public int getClearAllSidePadding(View view, boolean isRtl) { return (isRtl ? view.getPaddingRight() : - view.getPaddingLeft()) / 2;