mirror of
https://github.com/LawnchairLauncher/lawnchair.git
synced 2026-03-03 09:26:51 +00:00
Compute window offset when quick scrub starts
Instead of setting the window center to match the task center on every update, compute the final offset when quick scrub starts and interpolate alongside other factors such as window scale. Bug: 78027888 Change-Id: I33b115764d46ecd6907ecb82b1ba12aeefc583c5
This commit is contained in:
@@ -43,6 +43,7 @@ import com.android.quickstep.util.LayoutUtils;
|
||||
import com.android.quickstep.util.RemoteAnimationProvider;
|
||||
import com.android.quickstep.util.RemoteAnimationTargetSet;
|
||||
import com.android.quickstep.views.LauncherLayoutListener;
|
||||
import com.android.quickstep.views.LauncherRecentsView;
|
||||
import com.android.quickstep.views.RecentsView;
|
||||
import com.android.quickstep.views.RecentsViewContainer;
|
||||
import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
|
||||
@@ -65,6 +66,8 @@ public interface ActivityControlHelper<T extends BaseDraggingActivity> {
|
||||
*/
|
||||
boolean onQuickInteractionStart(T activity, boolean activityVisible);
|
||||
|
||||
float getTranslationYForQuickScrub(T activity);
|
||||
|
||||
void executeOnWindowAvailable(T activity, Runnable action);
|
||||
|
||||
void onTransitionCancelled(T activity, boolean activityVisible);
|
||||
@@ -117,6 +120,13 @@ public interface ActivityControlHelper<T extends BaseDraggingActivity> {
|
||||
return !fromState.overviewUi;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getTranslationYForQuickScrub(Launcher activity) {
|
||||
LauncherRecentsView recentsView = activity.getOverviewPanel();
|
||||
float transYFactor = FAST_OVERVIEW.getOverviewScaleAndTranslationYFactor(activity)[1];
|
||||
return recentsView.computeTranslationYForFactor(transYFactor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void executeOnWindowAvailable(Launcher activity, Runnable action) {
|
||||
if (activity.getWorkspace().runOnOverlayHidden(action)) {
|
||||
@@ -275,6 +285,11 @@ public interface ActivityControlHelper<T extends BaseDraggingActivity> {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getTranslationYForQuickScrub(RecentsActivity activity) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void executeOnWindowAvailable(RecentsActivity activity, Runnable action) {
|
||||
action.run();
|
||||
|
||||
@@ -458,17 +458,6 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity> {
|
||||
}
|
||||
mLauncherTransitionController.setPlayFraction(shift);
|
||||
|
||||
// Make sure the window follows the first task if it moves, e.g. during quick scrub.
|
||||
View firstTask = mRecentsView.getPageAt(0);
|
||||
// The first task may be null if we are swiping up from a task that does not
|
||||
// appear in the list (ie. the assistant)
|
||||
if (firstTask != null) {
|
||||
int scrollForFirstTask = mRecentsView.getScrollForPage(0);
|
||||
int offsetFromFirstTask = (scrollForFirstTask - mRecentsView.getScrollX());
|
||||
mClipAnimationHelper.offsetTarget(firstTask.getScaleX(),
|
||||
offsetFromFirstTask + firstTask.getTranslationX(),
|
||||
mRecentsView.getTranslationY());
|
||||
}
|
||||
if (mRecentsAnimationWrapper.controller != null) {
|
||||
// TODO: This logic is spartanic!
|
||||
boolean passedThreshold = shift > 0.12f;
|
||||
@@ -714,11 +703,31 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity> {
|
||||
}
|
||||
|
||||
private void onQuickScrubStart() {
|
||||
mActivityControlHelper.onQuickInteractionStart(mActivity, mWasLauncherAlreadyVisible);
|
||||
if (mLauncherTransitionController != null) {
|
||||
mLauncherTransitionController.getAnimationPlayer().end();
|
||||
mLauncherTransitionController = null;
|
||||
}
|
||||
|
||||
mActivityControlHelper.onQuickInteractionStart(mActivity, false);
|
||||
mQuickScrubController.onQuickScrubStart(false);
|
||||
|
||||
// Inform the last progress in case we skipped before.
|
||||
mQuickScrubController.onQuickScrubProgress(mCurrentQuickScrubProgress);
|
||||
|
||||
// Make sure the window follows the first task if it moves, e.g. during quick scrub.
|
||||
TaskView firstTask = mRecentsView.getPageAt(0);
|
||||
// The first task may be null if we are swiping up from a task that does not
|
||||
// appear in the list (i.e. the assistant)
|
||||
if (firstTask != null) {
|
||||
int scrollForFirstTask = mRecentsView.getScrollForPage(0);
|
||||
int scrollForSecondTask = mRecentsView.getChildCount() > 1
|
||||
? mRecentsView.getScrollForPage(1) : scrollForFirstTask;
|
||||
int offsetFromFirstTask = scrollForFirstTask - scrollForSecondTask;
|
||||
float interpolation = offsetFromFirstTask / (mRecentsView.getWidth() / 2);
|
||||
mClipAnimationHelper.offsetTarget(
|
||||
firstTask.getCurveScaleForInterpolation(interpolation), offsetFromFirstTask,
|
||||
mActivityControlHelper.getTranslationYForQuickScrub(mActivity));
|
||||
}
|
||||
}
|
||||
|
||||
private void onFinishedTransitionToQuickScrub() {
|
||||
|
||||
@@ -15,9 +15,13 @@
|
||||
*/
|
||||
package com.android.quickstep.util;
|
||||
|
||||
import static com.android.launcher3.anim.Interpolators.LINEAR;
|
||||
import static com.android.launcher3.anim.Interpolators.SCROLL;
|
||||
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Matrix;
|
||||
import android.graphics.Matrix.ScaleToFit;
|
||||
import android.graphics.PointF;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.RectF;
|
||||
|
||||
@@ -46,8 +50,10 @@ public class ClipAnimationHelper {
|
||||
private final RectF mSourceRect = new RectF();
|
||||
// The bounds of the task view in launcher window coordinates
|
||||
private final RectF mTargetRect = new RectF();
|
||||
// Doesn't change after initialized, used as an anchor when changing mTargetRect
|
||||
private final RectF mInitialTargetRect = new RectF();
|
||||
// Doesn't change after initialized, used as an anchor when changing mTargetOffset
|
||||
private final PointF mInitialTargetOffset = new PointF();
|
||||
// Set when the final window destination is changed, such as offsetting for quick scrub
|
||||
private final PointF mTargetOffset = new PointF();
|
||||
// The insets to be used for clipping the app window, which can be larger than mSourceInsets
|
||||
// if the aspect ratio of the target is smaller than the aspect ratio of the source rect. In
|
||||
// app window coordinates.
|
||||
@@ -60,6 +66,9 @@ public class ClipAnimationHelper {
|
||||
private final Rect mClipRect = new Rect();
|
||||
private final RectFEvaluator mRectFEvaluator = new RectFEvaluator();
|
||||
private final Matrix mTmpMatrix = new Matrix();
|
||||
private final RectF mTmpRectF = new RectF();
|
||||
|
||||
private float mTargetScale = 1f;
|
||||
|
||||
public void updateSource(Rect homeStackBounds, RemoteAnimationTargetCompat target) {
|
||||
mHomeStackBounds.set(homeStackBounds);
|
||||
@@ -75,10 +84,9 @@ public class ClipAnimationHelper {
|
||||
mSourceStackBounds.width() - mSourceInsets.right,
|
||||
mSourceStackBounds.height() - mSourceInsets.bottom);
|
||||
mTargetRect.set(targetRect);
|
||||
mTargetRect.offset(mHomeStackBounds.left - mSourceStackBounds.left,
|
||||
mInitialTargetOffset.set(mHomeStackBounds.left - mSourceStackBounds.left,
|
||||
mHomeStackBounds.top - mSourceStackBounds.top);
|
||||
|
||||
mInitialTargetRect.set(mTargetRect);
|
||||
mTargetOffset.set(mInitialTargetOffset);
|
||||
|
||||
// Calculate the clip based on the target rect (since the content insets and the
|
||||
// launcher insets may differ, so the aspect ratio of the target rect can differ
|
||||
@@ -98,10 +106,13 @@ public class ClipAnimationHelper {
|
||||
|
||||
public void applyTransform(RemoteAnimationTargetSet targetSet, float progress) {
|
||||
RectF currentRect;
|
||||
synchronized (mTargetRect) {
|
||||
currentRect = mRectFEvaluator.evaluate(progress, mSourceRect, mTargetRect);
|
||||
mTmpRectF.set(mTargetRect);
|
||||
Utilities.scaleRectFAboutCenter(mTmpRectF, mTargetScale);
|
||||
currentRect = mRectFEvaluator.evaluate(progress, mSourceRect, mTmpRectF);
|
||||
synchronized (mTargetOffset) {
|
||||
// Stay lined up with the center of the target, since it moves for quick scrub.
|
||||
currentRect.offset(mTargetRect.centerX() - currentRect.centerX(), 0);
|
||||
currentRect.offset(mTargetOffset.x * SCROLL.getInterpolation(progress),
|
||||
mTargetOffset.y * LINEAR.getInterpolation(progress));
|
||||
}
|
||||
|
||||
mClipRect.left = (int) (mSourceWindowClipInsets.left * progress);
|
||||
@@ -131,10 +142,10 @@ public class ClipAnimationHelper {
|
||||
}
|
||||
|
||||
public void offsetTarget(float scale, float offsetX, float offsetY) {
|
||||
synchronized (mTargetRect) {
|
||||
mTargetRect.set(mInitialTargetRect);
|
||||
Utilities.scaleRectFAboutCenter(mTargetRect, scale);
|
||||
mTargetRect.offset(offsetX, offsetY);
|
||||
synchronized (mTargetOffset) {
|
||||
mTargetScale = scale;
|
||||
mTargetOffset.set(mInitialTargetOffset);
|
||||
mTargetOffset.offset(offsetX, offsetY);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -187,13 +198,11 @@ public class ClipAnimationHelper {
|
||||
}
|
||||
|
||||
public void drawForProgress(TaskThumbnailView ttv, Canvas canvas, float progress) {
|
||||
RectF currentRect;
|
||||
synchronized (mTargetRect) {
|
||||
currentRect = mRectFEvaluator.evaluate(progress, mSourceRect, mTargetRect);
|
||||
}
|
||||
RectF currentRect = mRectFEvaluator.evaluate(progress, mSourceRect, mTargetRect);
|
||||
|
||||
canvas.translate(mSourceStackBounds.left - mHomeStackBounds.left,
|
||||
mSourceStackBounds.top - mHomeStackBounds.top);
|
||||
synchronized (mTargetOffset) {
|
||||
canvas.translate(-mTargetOffset.x, -mTargetOffset.y);
|
||||
}
|
||||
mTmpMatrix.setRectToRect(mTargetRect, currentRect, ScaleToFit.FILL);
|
||||
canvas.concat(mTmpMatrix);
|
||||
canvas.translate(mTargetRect.left, mTargetRect.top);
|
||||
|
||||
@@ -86,7 +86,11 @@ public class LauncherRecentsView extends RecentsView<Launcher> {
|
||||
|
||||
public void setTranslationYFactor(float translationFactor) {
|
||||
mTranslationYFactor = translationFactor;
|
||||
setTranslationY(mTranslationYFactor * (getPaddingBottom() - getPaddingTop()));
|
||||
setTranslationY(computeTranslationYForFactor(mTranslationYFactor));
|
||||
}
|
||||
|
||||
public float computeTranslationYForFactor(float translationYFactor) {
|
||||
return translationYFactor * (getPaddingBottom() - getPaddingTop());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -219,11 +219,20 @@ public class TaskView extends FrameLayout implements TaskCallbacks, PageCallback
|
||||
mSnapshotView.setDimAlpha(mCurveDimAlpha);
|
||||
}
|
||||
|
||||
mCurveScale = 1 - curveInterpolation * EDGE_SCALE_DOWN_FACTOR;
|
||||
mCurveScale = getCurveScaleForCurveInterpolation(curveInterpolation);
|
||||
setScaleX(mCurveScale);
|
||||
setScaleY(mCurveScale);
|
||||
}
|
||||
|
||||
public float getCurveScaleForInterpolation(float linearInterpolation) {
|
||||
float curveInterpolation = CURVE_INTERPOLATOR.getInterpolation(linearInterpolation);
|
||||
return getCurveScaleForCurveInterpolation(curveInterpolation);
|
||||
}
|
||||
|
||||
private float getCurveScaleForCurveInterpolation(float curveInterpolation) {
|
||||
return 1 - curveInterpolation * EDGE_SCALE_DOWN_FACTOR;
|
||||
}
|
||||
|
||||
public float getCurveScale() {
|
||||
return mCurveScale;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user