diff --git a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/TaskViewTouchController.java b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/TaskViewTouchController.java index 7675a7968a..c2e5cdabf2 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/TaskViewTouchController.java +++ b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/TaskViewTouchController.java @@ -32,6 +32,7 @@ import com.android.launcher3.Utilities; import com.android.launcher3.anim.AnimatorPlaybackController; import com.android.launcher3.anim.Interpolators; import com.android.launcher3.anim.PendingAnimation; +import com.android.launcher3.config.FeatureFlags; import com.android.launcher3.touch.BaseSwipeDetector; import com.android.launcher3.touch.PagedOrientationHandler; import com.android.launcher3.touch.SingleAxisSwipeDetector; @@ -150,9 +151,11 @@ public abstract class TaskViewTouchController mTaskBeingDragged = view; int upDirection = mRecentsView.getPagedOrientationHandler() .getUpDirection(mIsRtl); - if (!SysUINavigationMode.getMode(mActivity).hasGestures) { + if (!SysUINavigationMode.getMode(mActivity).hasGestures || ( + mActivity.getDeviceProfile().isTablet + && FeatureFlags.ENABLE_OVERVIEW_GRID.get())) { // Don't allow swipe down to open if we don't support swipe up - // to enter overview. + // to enter overview, or when grid layout is enabled. directionsToDetectScroll = upDirection; mAllowGoingUp = true; mAllowGoingDown = false; diff --git a/quickstep/src/com/android/quickstep/TaskViewUtils.java b/quickstep/src/com/android/quickstep/TaskViewUtils.java index 9da306eec0..25c0928e8d 100644 --- a/quickstep/src/com/android/quickstep/TaskViewUtils.java +++ b/quickstep/src/com/android/quickstep/TaskViewUtils.java @@ -49,6 +49,7 @@ import com.android.launcher3.anim.AnimationSuccessListener; import com.android.launcher3.anim.AnimatorPlaybackController; import com.android.launcher3.anim.Interpolators; import com.android.launcher3.anim.PendingAnimation; +import com.android.launcher3.config.FeatureFlags; import com.android.launcher3.model.data.ItemInfo; import com.android.launcher3.statehandlers.DepthController; import com.android.launcher3.statemanager.StateManager; @@ -174,11 +175,13 @@ public final class TaskViewUtils { final RecentsView recentsView = v.getRecentsView(); int taskIndex = recentsView.indexOfChild(v); - boolean parallaxCenterAndAdjacentTask = taskIndex != recentsView.getCurrentPage(); - int startScroll = recentsView.getScrollOffset(taskIndex); - Context context = v.getContext(); DeviceProfile dp = BaseActivity.fromContext(context).getDeviceProfile(); + boolean parallaxCenterAndAdjacentTask = + taskIndex != recentsView.getCurrentPage() && !(dp.isTablet + && FeatureFlags.ENABLE_OVERVIEW_GRID.get()); + int startScroll = recentsView.getScrollOffset(taskIndex); + TaskViewSimulator topMostSimulator = null; if (tsv == null && targets.apps.length > 0) { diff --git a/quickstep/src/com/android/quickstep/util/TaskViewSimulator.java b/quickstep/src/com/android/quickstep/util/TaskViewSimulator.java index 65bcf26305..6f16781c64 100644 --- a/quickstep/src/com/android/quickstep/util/TaskViewSimulator.java +++ b/quickstep/src/com/android/quickstep/util/TaskViewSimulator.java @@ -276,8 +276,9 @@ public class TaskViewSimulator implements TransformParams.BuilderProxy { int start = mOrientationState.getOrientationHandler() .getPrimaryValue(mTaskRect.left, mTaskRect.top); mScrollState.screenCenter = start + mScrollState.scroll + mScrollState.halfPageSize; - mScrollState.updateInterpolation(start); - mCurveScale = TaskView.getCurveScaleForInterpolation(mScrollState.linearInterpolation); + mScrollState.updateInterpolation(mDp, start); + mCurveScale = TaskView.getCurveScaleForInterpolation(mDp, + mScrollState.linearInterpolation); } float progress = Utilities.boundToRange(fullScreenProgress.value, 0, 1); diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java index d9d0a936b2..38d488c470 100644 --- a/quickstep/src/com/android/quickstep/views/RecentsView.java +++ b/quickstep/src/com/android/quickstep/views/RecentsView.java @@ -898,9 +898,14 @@ public abstract class RecentsView extends PagedView public void setFullscreenProgress(float fullscreenProgress) { mFullscreenProgress = fullscreenProgress; int taskCount = getTaskViewCount(); + float accumulatedTranslationX = 0; for (int i = 0; i < taskCount; i++) { - getTaskViewAt(i).setFullscreenProgress(mFullscreenProgress); + TaskView taskView = getTaskViewAt(i); + taskView.setFullscreenProgress(mFullscreenProgress); + taskView.setAccumulatedTranslationX(accumulatedTranslationX); + accumulatedTranslationX += taskView.getFullscreenTranslationX(); } + // Fade out the actions view quickly (0.1 range) mActionsView.getFullscreenAlpha().setValue( mapToRange(fullscreenProgress, 0, 0.1f, 1f, 0f, LINEAR)); @@ -934,6 +939,11 @@ public abstract class RecentsView extends PagedView setPadding(mTempRect.left - mInsets.left, mTempRect.top - mInsets.top, dp.widthPx - mInsets.right - mTempRect.right, dp.heightPx - mInsets.bottom - mTempRect.bottom); + // Force TaskView to update size from thumbnail + final int taskCount = getTaskViewCount(); + for (int i = 0; i < taskCount; i++) { + getTaskViewAt(i).updateTaskSize(); + } } public void getTaskSize(Rect outRect) { @@ -942,6 +952,11 @@ public abstract class RecentsView extends PagedView mLastComputedTaskSize.set(outRect); } + /** Gets the last computed task size */ + public Rect getLastComputedTaskSize() { + return mLastComputedTaskSize; + } + /** Gets the task size for modal state. */ public void getModalTaskSize(Rect outRect) { mSizeStrategy.calculateModalTaskSize(mActivity, mActivity.getDeviceProfile(), outRect); @@ -987,7 +1002,7 @@ public abstract class RecentsView extends PagedView final int pageCount = getPageCount(); for (int i = 0; i < pageCount; i++) { View page = getPageAt(i); - mScrollState.updateInterpolation( + mScrollState.updateInterpolation(mActivity.getDeviceProfile(), mOrientationHandler.getChildStartWithTranslation(page)); ((PageCallbacks) page).onPageScroll(mScrollState); } @@ -1422,13 +1437,13 @@ public abstract class RecentsView extends PagedView /** * Updates linearInterpolation for the provided child position */ - public void updateInterpolation(float childStart) { + public void updateInterpolation(DeviceProfile deviceProfile, float childStart) { float pageCenter = childStart + halfPageSize; float distanceFromScreenCenter = screenCenter - pageCenter; // How far the page has to move from the center to be offscreen, taking into account // the EDGE_SCALE_DOWN_FACTOR that will be applied at that position. float distanceToReachEdge = halfScreenSize - + halfPageSize * (1 - TaskView.EDGE_SCALE_DOWN_FACTOR); + + halfPageSize * (1 - TaskView.getEdgeScaleDownFactor(deviceProfile)); linearInterpolation = Math.min(1, Math.abs(distanceFromScreenCenter) / distanceToReachEdge); } @@ -1444,12 +1459,13 @@ public abstract class RecentsView extends PagedView } } - private void addDismissedTaskAnimations(View taskView, long duration, PendingAnimation anim) { + private void addDismissedTaskAnimations(TaskView taskView, long duration, + PendingAnimation anim) { // Use setFloat instead of setViewAlpha as we want to keep the view visible even when it's // alpha is set to 0 so that it can be recycled in the view pool properly anim.setFloat(taskView, VIEW_ALPHA, 0, ACCEL_2); - FloatProperty secondaryViewTranslate = - mOrientationHandler.getSecondaryViewTranslate(); + FloatProperty secondaryViewTranslate = + taskView.getDismissTaskTranslationProperty(); int secondaryTaskDimension = mOrientationHandler.getSecondaryDimension(taskView); int verticalFactor = mOrientationHandler.getSecondaryTranslationDirectionFactor(); @@ -1515,7 +1531,7 @@ public abstract class RecentsView extends PagedView int scrollDiff = newScroll[i] - oldScroll[i] + offset; if (scrollDiff != 0) { FloatProperty translationProperty = child instanceof TaskView - ? ((TaskView) child).getPrimaryFillDismissGapTranslationProperty() + ? ((TaskView) child).getFillDismissGapTranslationProperty() : mOrientationHandler.getPrimaryViewTranslate(); ResourceProvider rp = DynamicResource.provider(mActivity); @@ -1971,7 +1987,8 @@ public abstract class RecentsView extends PagedView // Find the task's scale based on its offscreen progress, then see how far it still needs to // move to be completely offscreen. Utilities.scaleRectFAboutCenter(taskPosition, - TaskView.getCurveScaleForInterpolation(centerToOffscreenProgress)); + TaskView.getCurveScaleForInterpolation(mActivity.getDeviceProfile(), + centerToOffscreenProgress)); 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 @@ -1990,7 +2007,7 @@ public abstract class RecentsView extends PagedView mTaskViewsSecondaryTranslation = translation; for (int i = 0; i < getTaskViewCount(); i++) { TaskView task = getTaskViewAt(i); - mOrientationHandler.getSecondaryViewTranslate().set(task, translation / getScaleY()); + task.getTaskResistanceTranslationProperty().set(task, translation / getScaleY()); } mLiveTileTaskViewSimulator.recentsViewSecondaryTranslation.value = translation; } @@ -2358,6 +2375,52 @@ public abstract class RecentsView extends PagedView return super.computeMinScroll(); } + @Override + protected boolean getPageScrolls(int[] outPageScrolls, boolean layoutChildren, + ComputePageScrollsLogic scrollLogic) { + boolean pageScrollChanged = super.getPageScrolls(outPageScrolls, layoutChildren, + scrollLogic); + + final int taskCount = getTaskViewCount(); + final int childCount = getChildCount(); + for (int i = 0; i < childCount; i++) { + if (childCount < mTaskViewStartIndex) { + continue; + } + + final TaskView taskView = getTaskViewAt( + Utilities.boundToRange(i, mTaskViewStartIndex, taskCount - 1)); + float scrollDiff = + taskView.getFullscreenTranslationX() + taskView.getAccumulatedTranslationX(); + if (scrollDiff != 0) { + outPageScrolls[i] += scrollDiff; + pageScrollChanged = true; + } + } + return pageScrollChanged; + } + + @Override + protected int getChildOffset(int index) { + if (index < mTaskViewStartIndex) { + return super.getChildOffset(index); + } + + final TaskView taskView = getTaskViewAt( + Utilities.boundToRange(index, mTaskViewStartIndex, getTaskViewCount() - 1)); + return super.getChildOffset(index) + (int) taskView.getFullscreenTranslationX() + + (int) taskView.getAccumulatedTranslationX(); + } + + @Override + protected int getChildVisibleSize(int index) { + final TaskView taskView = getTaskViewAtByAbsoluteIndex(index); + if (taskView == null) { + return super.getChildVisibleSize(index); + } + return super.getChildVisibleSize(index) - (int) taskView.getFullscreenTranslationX(); + } + @Override protected int computeMaxScroll() { if (getTaskViewCount() > 0) { diff --git a/quickstep/src/com/android/quickstep/views/TaskThumbnailView.java b/quickstep/src/com/android/quickstep/views/TaskThumbnailView.java index 445e49085b..3bd883ddc4 100644 --- a/quickstep/src/com/android/quickstep/views/TaskThumbnailView.java +++ b/quickstep/src/com/android/quickstep/views/TaskThumbnailView.java @@ -51,6 +51,7 @@ import com.android.launcher3.BaseActivity; import com.android.launcher3.DeviceProfile; import com.android.launcher3.R; import com.android.launcher3.Utilities; +import com.android.launcher3.config.FeatureFlags; import com.android.launcher3.uioverrides.plugins.PluginManagerWrapper; import com.android.launcher3.util.MainThreadInitializedObject; import com.android.launcher3.util.SystemUiController; @@ -110,6 +111,9 @@ public class TaskThumbnailView extends View implements PluginListener FILL_DISMISS_GAP_TRANSLATION_X = - new FloatProperty("fillDismissGapTranslationX") { + private static final FloatProperty DISMISS_TRANSLATION_X = + new FloatProperty("dismissTranslationX") { @Override public void setValue(TaskView taskView, float v) { - taskView.setFillDismissGapTranslationX(v); + taskView.setDismissTranslationX(v); } @Override public Float get(TaskView taskView) { - return taskView.mFillDismissGapTranslationX; + return taskView.mDismissTranslationX; } }; - private static final FloatProperty FILL_DISMISS_GAP_TRANSLATION_Y = - new FloatProperty("fillDismissGapTranslationY") { + private static final FloatProperty DISMISS_TRANSLATION_Y = + new FloatProperty("dismissTranslationY") { @Override public void setValue(TaskView taskView, float v) { - taskView.setFillDismissGapTranslationY(v); + taskView.setDismissTranslationY(v); } @Override public Float get(TaskView taskView) { - return taskView.mFillDismissGapTranslationY; + return taskView.mDismissTranslationY; } }; @@ -204,6 +206,32 @@ public class TaskView extends FrameLayout implements PageCallbacks, Reusable { } }; + private static final FloatProperty TASK_RESISTANCE_TRANSLATION_X = + new FloatProperty("taskResistanceTranslationX") { + @Override + public void setValue(TaskView taskView, float v) { + taskView.setTaskResistanceTranslationX(v); + } + + @Override + public Float get(TaskView taskView) { + return taskView.mTaskResistanceTranslationX; + } + }; + + private static final FloatProperty TASK_RESISTANCE_TRANSLATION_Y = + new FloatProperty("taskResistanceTranslationY") { + @Override + public void setValue(TaskView taskView, float v) { + taskView.setTaskResistanceTranslationY(v); + } + + @Override + public Float get(TaskView taskView) { + return taskView.mTaskResistanceTranslationY; + } + }; + private final OnAttachStateChangeListener mTaskMenuStateListener = new OnAttachStateChangeListener() { @Override @@ -228,15 +256,22 @@ public class TaskView extends FrameLayout implements PageCallbacks, Reusable { private final DigitalWellBeingToast mDigitalWellBeingToast; private float mCurveScale; private float mFullscreenProgress; + private float mScaleAtFullscreen = 1; + private float mFullscreenScale = 1; private final FullscreenDrawParams mCurrentFullscreenParams; private final StatefulActivity mActivity; // Various causes of changing primary translation, which we aggregate to setTranslationX/Y(). - // TODO: We should do this for secondary translation properties as well. - private float mFillDismissGapTranslationX; - private float mFillDismissGapTranslationY; + private float mDismissTranslationX; + private float mDismissTranslationY; private float mTaskOffsetTranslationX; private float mTaskOffsetTranslationY; + private float mTaskResistanceTranslationX; + private float mTaskResistanceTranslationY; + // The following translation variables should only be used in the same orientation as Launcher. + private float mFullscreenTranslationX; + private float mAccumulatedTranslationX; + private float mBoxTranslationY; private ObjectAnimator mIconAndDimAnimator; private float mIconScaleAnimStartProgress = 0; @@ -425,6 +460,7 @@ public class TaskView extends FrameLayout implements PageCallbacks, Reusable { cancelPendingLoadTasks(); mTask = task; mSnapshotView.bind(task); + updateTaskSize(); setOrientationState(orientedState); } @@ -668,10 +704,12 @@ public class TaskView extends FrameLayout implements PageCallbacks, Reusable { protected void resetViewTransforms() { setCurveScale(1); - mFillDismissGapTranslationX = mTaskOffsetTranslationX = 0f; - mFillDismissGapTranslationY = mTaskOffsetTranslationY = 0f; - setTranslationX(0f); - setTranslationY(0f); + // fullscreenTranslation and accumulatedTranslation should not be reset, as + // resetViewTransforms is called during Quickswitch scrolling. + mDismissTranslationX = mTaskOffsetTranslationX = mTaskResistanceTranslationX = 0f; + mDismissTranslationY = mTaskOffsetTranslationY = mTaskResistanceTranslationY = 0f; + applyTranslationX(); + applyTranslationY(); setTranslationZ(0); setAlpha(mStableAlpha); setIconScaleAndDim(1); @@ -684,6 +722,7 @@ public class TaskView extends FrameLayout implements PageCallbacks, Reusable { @Override public void onRecycle() { + mFullscreenTranslationX = mAccumulatedTranslationX = mBoxTranslationY = 0f; resetViewTransforms(); // Clear any references to the thumbnail (it will be re-read either from the cache or the // system on next bind) @@ -702,7 +741,7 @@ public class TaskView extends FrameLayout implements PageCallbacks, Reusable { float curveInterpolation = CURVE_INTERPOLATOR.getInterpolation(scrollState.linearInterpolation); float curveScaleForCurveInterpolation = getCurveScaleForCurveInterpolation( - curveInterpolation); + mActivity.getDeviceProfile(), curveInterpolation); mSnapshotView.setDimAlpha(curveInterpolation * MAX_PAGE_SCRIM_ALPHA); setCurveScale(curveScaleForCurveInterpolation); @@ -787,40 +826,70 @@ public class TaskView extends FrameLayout implements PageCallbacks, Reusable { @Override protected void onLayout(boolean changed, int left, int top, int right, int bottom) { super.onLayout(changed, left, top, right, bottom); - setPivotX((right - left) * 0.5f); - setPivotY(mSnapshotView.getTop() + mSnapshotView.getHeight() * 0.5f); + if (mActivity.getDeviceProfile().isTablet && FeatureFlags.ENABLE_OVERVIEW_GRID.get()) { + setPivotX(getLayoutDirection() == LAYOUT_DIRECTION_RTL ? (right - left) : 0); + setPivotY(0); + } else { + setPivotX((right - left) * 0.5f); + setPivotY(mSnapshotView.getTop() + mSnapshotView.getHeight() * 0.5f); + } if (Utilities.ATLEAST_Q) { SYSTEM_GESTURE_EXCLUSION_RECT.get(0).set(0, 0, getWidth(), getHeight()); setSystemGestureExclusionRects(SYSTEM_GESTURE_EXCLUSION_RECT); } } - public static float getCurveScaleForInterpolation(float linearInterpolation) { + /** + * How much to scale down pages near the edge of the screen according to linearInterpolation. + */ + public static float getCurveScaleForInterpolation(DeviceProfile deviceProfile, + float linearInterpolation) { float curveInterpolation = CURVE_INTERPOLATOR.getInterpolation(linearInterpolation); - return getCurveScaleForCurveInterpolation(curveInterpolation); + return getCurveScaleForCurveInterpolation(deviceProfile, curveInterpolation); } - private static float getCurveScaleForCurveInterpolation(float curveInterpolation) { - return 1 - curveInterpolation * EDGE_SCALE_DOWN_FACTOR; + private static float getCurveScaleForCurveInterpolation(DeviceProfile deviceProfile, + float curveInterpolation) { + return 1 - curveInterpolation * getEdgeScaleDownFactor(deviceProfile); + } + + /** + * How much to scale down pages near the edge of the screen. + */ + public static float getEdgeScaleDownFactor(DeviceProfile deviceProfile) { + if (deviceProfile.isTablet && FeatureFlags.ENABLE_OVERVIEW_GRID.get()) { + return EDGE_SCALE_DOWN_FACTOR_GRID; + } else { + return EDGE_SCALE_DOWN_FACTOR_CAROUSEL; + } } private void setCurveScale(float curveScale) { mCurveScale = curveScale; - setScaleX(mCurveScale); - setScaleY(mCurveScale); + applyScale(); + } + + private void setFullscreenScale(float fullscreenScale) { + mFullscreenScale = fullscreenScale; + applyScale(); + } + + private void applyScale() { + setScaleX(mCurveScale * mFullscreenScale); + setScaleY(mCurveScale * mFullscreenScale); } public float getCurveScale() { return mCurveScale; } - private void setFillDismissGapTranslationX(float x) { - mFillDismissGapTranslationX = x; + private void setDismissTranslationX(float x) { + mDismissTranslationX = x; applyTranslationX(); } - private void setFillDismissGapTranslationY(float y) { - mFillDismissGapTranslationY = y; + private void setDismissTranslationY(float y) { + mDismissTranslationY = y; applyTranslationY(); } @@ -834,17 +903,59 @@ public class TaskView extends FrameLayout implements PageCallbacks, Reusable { applyTranslationY(); } + private void setTaskResistanceTranslationX(float x) { + mTaskResistanceTranslationX = x; + applyTranslationX(); + } + + private void setTaskResistanceTranslationY(float y) { + mTaskResistanceTranslationY = y; + applyTranslationY(); + } + + private void setFullscreenTranslationX(float fullscreenTranslationX) { + mFullscreenTranslationX = fullscreenTranslationX; + applyTranslationX(); + } + + public float getFullscreenTranslationX() { + return mFullscreenTranslationX; + } + + public void setAccumulatedTranslationX(float accumulatedTranslationX) { + mAccumulatedTranslationX = accumulatedTranslationX; + applyTranslationX(); + } + + public float getAccumulatedTranslationX() { + return mAccumulatedTranslationX; + } + + private void setBoxTranslationY(float boxTranslationY) { + mBoxTranslationY = boxTranslationY; + applyTranslationY(); + } + private void applyTranslationX() { - setTranslationX(mFillDismissGapTranslationX + mTaskOffsetTranslationX); + setTranslationX( + mDismissTranslationX + mTaskOffsetTranslationX + mTaskResistanceTranslationX + + mFullscreenTranslationX + mAccumulatedTranslationX); } private void applyTranslationY() { - setTranslationY(mFillDismissGapTranslationY + mTaskOffsetTranslationY); + setTranslationY( + mDismissTranslationY + mTaskOffsetTranslationY + mTaskResistanceTranslationY + + mBoxTranslationY); } - public FloatProperty getPrimaryFillDismissGapTranslationProperty() { + public FloatProperty getFillDismissGapTranslationProperty() { return getPagedOrientationHandler().getPrimaryValue( - FILL_DISMISS_GAP_TRANSLATION_X, FILL_DISMISS_GAP_TRANSLATION_Y); + DISMISS_TRANSLATION_X, DISMISS_TRANSLATION_Y); + } + + public FloatProperty getDismissTaskTranslationProperty() { + return getPagedOrientationHandler().getSecondaryValue( + DISMISS_TRANSLATION_X, DISMISS_TRANSLATION_Y); } public FloatProperty getPrimaryTaskOffsetTranslationProperty() { @@ -852,6 +963,11 @@ public class TaskView extends FrameLayout implements PageCallbacks, Reusable { TASK_OFFSET_TRANSLATION_X, TASK_OFFSET_TRANSLATION_Y); } + public FloatProperty getTaskResistanceTranslationProperty() { + return getPagedOrientationHandler().getSecondaryValue( + TASK_RESISTANCE_TRANSLATION_X, TASK_RESISTANCE_TRANSLATION_Y); + } + @Override public boolean hasOverlappingRendering() { // TODO: Clip-out the icon region from the thumbnail, since they are overlapping. @@ -987,6 +1103,8 @@ public class TaskView extends FrameLayout implements PageCallbacks, Reusable { setClipChildren(!isFullscreen); setClipToPadding(!isFullscreen); + updateTaskScaling(); + TaskThumbnailView thumbnail = getThumbnail(); updateCurrentFullscreenParams(thumbnail.getPreviewPositionHelper()); @@ -1012,6 +1130,83 @@ public class TaskView extends FrameLayout implements PageCallbacks, Reusable { previewPositionHelper); } + void updateTaskSize() { + ViewGroup.LayoutParams params = getLayoutParams(); + if (mActivity.getDeviceProfile().isTablet && FeatureFlags.ENABLE_OVERVIEW_GRID.get()) { + final int thumbnailPadding = (int) getResources().getDimension( + R.dimen.task_thumbnail_top_margin); + + Rect lastComputedTaskSize = getRecentsView().getLastComputedTaskSize(); + int taskWidth = lastComputedTaskSize.width(); + int taskHeight = lastComputedTaskSize.height(); + int boxLength = Math.max(taskWidth, taskHeight); + float thumbnailRatio = mSnapshotView.getThumbnailRatio(); + + int expectedWidth; + int expectedHeight; + if (thumbnailRatio > 1) { + expectedWidth = boxLength; + expectedHeight = (int) (boxLength / thumbnailRatio) + thumbnailPadding; + } else { + expectedWidth = (int) (boxLength * thumbnailRatio); + expectedHeight = boxLength + thumbnailPadding; + } + + float heightDiff = (expectedHeight - thumbnailPadding - taskHeight) / 2.0f; + setBoxTranslationY(heightDiff); + + if (expectedWidth > taskWidth) { + // In full screen, expectedWidth should not be larger than taskWidth. + mScaleAtFullscreen = taskWidth / (float) expectedWidth; + } else if (expectedHeight - thumbnailPadding > taskHeight) { + // In full screen, expectedHeight should not be larger than taskHeight. + mScaleAtFullscreen = taskHeight / (float) (expectedHeight - thumbnailPadding); + } else { + mScaleAtFullscreen = 1f; + } + + if (params.width != expectedWidth || params.height != expectedHeight) { + params.width = expectedWidth; + params.height = expectedHeight; + setLayoutParams(params); + } + } else { + setBoxTranslationY(0); + if (params.width != ViewGroup.LayoutParams.MATCH_PARENT) { + params.width = ViewGroup.LayoutParams.MATCH_PARENT; + params.height = ViewGroup.LayoutParams.MATCH_PARENT; + setLayoutParams(params); + } + } + updateTaskScaling(); + } + + private void updateTaskScaling() { + if (mActivity.getDeviceProfile().isTablet && FeatureFlags.ENABLE_OVERVIEW_GRID.get()) { + ViewGroup.LayoutParams params = getLayoutParams(); + if (params.width == ViewGroup.LayoutParams.MATCH_PARENT + || params.height == ViewGroup.LayoutParams.MATCH_PARENT) { + // Snapshot is not loaded yet, skip. + return; + } + + float progress = EXAGGERATED_EASE.getInterpolation(mFullscreenProgress); + setFullscreenScale(Utilities.mapRange(progress, 1f, mScaleAtFullscreen)); + + float widthDiff = params.width * (1 - mFullscreenScale); + setFullscreenTranslationX(getFullscreenTrans( + getLayoutDirection() == LAYOUT_DIRECTION_RTL ? -widthDiff : widthDiff)); + } else { + setFullscreenScale(1); + setFullscreenTranslationX(0); + } + } + + private float getFullscreenTrans(float endTranslation) { + float progress = ACCEL_DEACCEL.getInterpolation(mFullscreenProgress); + return Utilities.mapRange(progress, 0, endTranslation); + } + public boolean isRunningTask() { if (getRecentsView() == null) { return false; diff --git a/src/com/android/launcher3/PagedView.java b/src/com/android/launcher3/PagedView.java index 4303dee769..ada297f340 100644 --- a/src/com/android/launcher3/PagedView.java +++ b/src/com/android/launcher3/PagedView.java @@ -745,6 +745,11 @@ public abstract class PagedView extends ViewGrou return mOrientationHandler.getChildStart(pageAtIndex); } + protected int getChildVisibleSize(int index) { + View layout = getPageAt(index); + return mOrientationHandler.getMeasuredSize(layout); + } + @Override public boolean requestChildRectangleOnScreen(View child, Rect rectangle, boolean immediate) { int page = indexToPage(indexOfChild(child)); @@ -1457,8 +1462,7 @@ public abstract class PagedView extends ViewGrou } private int getDisplacementFromScreenCenter(int childIndex, int screenCenter) { - View layout = getPageAt(childIndex); - int childSize = mOrientationHandler.getMeasuredSize(layout); + int childSize = getChildVisibleSize(childIndex); int halfChildSize = (childSize / 2); int childCenter = getChildOffset(childIndex) + halfChildSize; return childCenter - screenCenter; diff --git a/src/com/android/launcher3/config/FeatureFlags.java b/src/com/android/launcher3/config/FeatureFlags.java index ac0083c1ee..2b373a84f8 100644 --- a/src/com/android/launcher3/config/FeatureFlags.java +++ b/src/com/android/launcher3/config/FeatureFlags.java @@ -214,6 +214,10 @@ public final class FeatureFlags { public static final BooleanFlag ENABLE_TASKBAR = new DeviceFlag( "ENABLE_TASKBAR", false, "Allows a system Taskbar to be shown on larger devices."); + public static final BooleanFlag ENABLE_OVERVIEW_GRID = new DeviceFlag( + "ENABLE_OVERVIEW_GRID", false, "Uses grid overview layout. " + + "Only applicable on large screen devices."); + public static void initialize(Context context) { synchronized (sDebugFlags) { for (DebugFlag flag : sDebugFlags) {