diff options
Diffstat (limited to 'quickstep/src/com/android/launcher3/uioverrides/PortraitStatesTouchController.java')
-rw-r--r-- | quickstep/src/com/android/launcher3/uioverrides/PortraitStatesTouchController.java | 159 |
1 files changed, 40 insertions, 119 deletions
diff --git a/quickstep/src/com/android/launcher3/uioverrides/PortraitStatesTouchController.java b/quickstep/src/com/android/launcher3/uioverrides/PortraitStatesTouchController.java index 012b54521..987f952ba 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/PortraitStatesTouchController.java +++ b/quickstep/src/com/android/launcher3/uioverrides/PortraitStatesTouchController.java @@ -18,20 +18,20 @@ package com.android.launcher3.uioverrides; import static com.android.launcher3.LauncherState.ALL_APPS; import static com.android.launcher3.LauncherState.NORMAL; import static com.android.launcher3.LauncherState.OVERVIEW; -import static com.android.launcher3.anim.AnimatorSetBuilder.ANIM_OVERVIEW_TRANSLATION; import static com.android.launcher3.anim.AnimatorSetBuilder.ANIM_VERTICAL_PROGRESS; -import static com.android.launcher3.anim.Interpolators.FAST_OUT_SLOW_IN; import static com.android.launcher3.anim.Interpolators.LINEAR; import android.animation.TimeInterpolator; import android.animation.ValueAnimator; import android.view.MotionEvent; import android.view.animation.Interpolator; +import android.view.animation.OvershootInterpolator; import com.android.launcher3.AbstractFloatingView; import com.android.launcher3.DeviceProfile; import com.android.launcher3.Launcher; import com.android.launcher3.LauncherState; +import com.android.launcher3.LauncherStateManager.AnimationComponents; import com.android.launcher3.anim.AnimatorPlaybackController; import com.android.launcher3.anim.AnimatorSetBuilder; import com.android.launcher3.anim.Interpolators; @@ -39,8 +39,8 @@ import com.android.launcher3.touch.AbstractStateChangeTouchController; import com.android.launcher3.touch.SwipeDetector; import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Touch; import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType; +import com.android.quickstep.RecentsModel; import com.android.quickstep.TouchInteractionService; -import com.android.quickstep.util.SysuiEventLogger; import com.android.quickstep.views.RecentsView; import com.android.quickstep.views.TaskView; @@ -49,43 +49,13 @@ import com.android.quickstep.views.TaskView; */ public class PortraitStatesTouchController extends AbstractStateChangeTouchController { - private static final float TOTAL_DISTANCE_MULTIPLIER = 3f; - private static final float LINEAR_SCALE_LIMIT = 1 / TOTAL_DISTANCE_MULTIPLIER; - - // Must be greater than LINEAR_SCALE_LIMIT; - private static final float MAXIMUM_DISTANCE_FACTOR = 0.9f; - - // Maximum amount to overshoot. - private static final float MAX_OVERSHOOT = 0.3f; - - private static final double PI_BY_2 = Math.PI / 2; + private static final String TAG = "PortraitStatesTouchCtrl"; private InterpolatorWrapper mAllAppsInterpolatorWrapper = new InterpolatorWrapper(); // If true, we will finish the current animation instantly on second touch. private boolean mFinishFastOnSecondTouch; - private final Interpolator mAllAppsDampedInterpolator = new Interpolator() { - - private final double mAngleMultiplier = Math.PI / - (2 * (MAXIMUM_DISTANCE_FACTOR - LINEAR_SCALE_LIMIT)); - - @Override - public float getInterpolation(float v) { - if (v <= LINEAR_SCALE_LIMIT) { - return v * TOTAL_DISTANCE_MULTIPLIER; - } - float overshoot = (v - LINEAR_SCALE_LIMIT); - return (float) (1 + MAX_OVERSHOOT * Math.sin(overshoot * mAngleMultiplier)); - } - }; - - private final Interpolator mOverviewBoundInterpolator = (v) -> { - if (v >= MAXIMUM_DISTANCE_FACTOR) { - return 1; - } - return FAST_OUT_SLOW_IN.getInterpolation(v / MAXIMUM_DISTANCE_FACTOR); - }; public PortraitStatesTouchController(Launcher l) { super(l, SwipeDetector.VERTICAL); @@ -122,24 +92,6 @@ public class PortraitStatesTouchController extends AbstractStateChangeTouchContr } @Override - protected int getSwipeDirection(MotionEvent ev) { - final int directionsToDetectScroll; - if (mLauncher.isInState(ALL_APPS)) { - directionsToDetectScroll = SwipeDetector.DIRECTION_NEGATIVE; - mStartContainerType = ContainerType.ALLAPPS; - } else if (mLauncher.isInState(NORMAL)) { - directionsToDetectScroll = SwipeDetector.DIRECTION_POSITIVE; - mStartContainerType = ContainerType.HOTSEAT; - } else if (mLauncher.isInState(OVERVIEW)) { - directionsToDetectScroll = SwipeDetector.DIRECTION_BOTH; - mStartContainerType = ContainerType.TASKSWITCHER; - } else { - return 0; - } - return directionsToDetectScroll; - } - - @Override protected LauncherState getTargetState(LauncherState fromState, boolean isDragTowardPositive) { if (fromState == ALL_APPS && !isDragTowardPositive) { // Should swipe down go to OVERVIEW instead? @@ -147,24 +99,28 @@ public class PortraitStatesTouchController extends AbstractStateChangeTouchContr mLauncher.getStateManager().getLastState() : NORMAL; } else if (fromState == OVERVIEW) { return isDragTowardPositive ? ALL_APPS : NORMAL; - } else if (isDragTowardPositive) { + } else if (fromState == NORMAL && isDragTowardPositive) { return TouchInteractionService.isConnected() ? OVERVIEW : ALL_APPS; } return fromState; } + @Override + protected int getLogContainerTypeForNormalState() { + return ContainerType.HOTSEAT; + } + private AnimatorSetBuilder getNormalToOverviewAnimation() { - mAllAppsInterpolatorWrapper.baseInterpolator = mAllAppsDampedInterpolator; + mAllAppsInterpolatorWrapper.baseInterpolator = LINEAR; AnimatorSetBuilder builder = new AnimatorSetBuilder(); builder.setInterpolator(ANIM_VERTICAL_PROGRESS, mAllAppsInterpolatorWrapper); - builder.setInterpolator(ANIM_OVERVIEW_TRANSLATION, mOverviewBoundInterpolator); return builder; } @Override - protected float initCurrentAnimation() { + protected float initCurrentAnimation(@AnimationComponents int animComponents) { float range = getShiftRange(); long maxAccuracy = (long) (2 * range); @@ -177,15 +133,11 @@ public class PortraitStatesTouchController extends AbstractStateChangeTouchContr if (mFromState == NORMAL && mToState == OVERVIEW && totalShift != 0) { builder = getNormalToOverviewAnimation(); - totalShift = totalShift * TOTAL_DISTANCE_MULTIPLIER; } else { builder = new AnimatorSetBuilder(); } - if (mPendingAnimation != null) { - mPendingAnimation.finish(false, Touch.SWIPE); - mPendingAnimation = null; - } + cancelPendingAnim(); RecentsView recentsView = mLauncher.getOverviewPanel(); TaskView taskView = (TaskView) recentsView.getChildAt(recentsView.getNextPage()); @@ -194,10 +146,17 @@ public class PortraitStatesTouchController extends AbstractStateChangeTouchContr mPendingAnimation = recentsView.createTaskLauncherAnimation(taskView, maxAccuracy); mPendingAnimation.anim.setInterpolator(Interpolators.ZOOM_IN); - mCurrentAnimation = AnimatorPlaybackController.wrap(mPendingAnimation.anim, maxAccuracy); + Runnable onCancelRunnable = () -> { + cancelPendingAnim(); + clearState(); + }; + mCurrentAnimation = AnimatorPlaybackController.wrap(mPendingAnimation.anim, maxAccuracy, + onCancelRunnable); + mLauncher.getStateManager().setCurrentUserControlledAnimation(mCurrentAnimation); } else { mCurrentAnimation = mLauncher.getStateManager() - .createAnimationToNewWorkspace(mToState, builder, maxAccuracy); + .createAnimationToNewWorkspace(mToState, builder, maxAccuracy, this::clearState, + animComponents); } if (totalShift == 0) { @@ -207,12 +166,19 @@ public class PortraitStatesTouchController extends AbstractStateChangeTouchContr return 1 / totalShift; } + private void cancelPendingAnim() { + if (mPendingAnimation != null) { + mPendingAnimation.finish(false, Touch.SWIPE); + mPendingAnimation = null; + } + } + @Override protected void updateSwipeCompleteAnimation(ValueAnimator animator, long expectedDuration, LauncherState targetState, float velocity, boolean isFling) { - handleFirstSwipeToOverview(animator, expectedDuration, targetState, velocity, isFling); super.updateSwipeCompleteAnimation(animator, expectedDuration, targetState, velocity, isFling); + handleFirstSwipeToOverview(animator, expectedDuration, targetState, velocity, isFling); } private void handleFirstSwipeToOverview(final ValueAnimator animator, @@ -220,69 +186,24 @@ public class PortraitStatesTouchController extends AbstractStateChangeTouchContr final boolean isFling) { if (mFromState == NORMAL && mToState == OVERVIEW && targetState == OVERVIEW) { mFinishFastOnSecondTouch = true; - - // Update all apps interpolator - float currentFraction = mCurrentAnimation.getProgressFraction(); - float absVelocity = Math.abs(velocity); - float currentValue = mAllAppsDampedInterpolator.getInterpolation(currentFraction); - - if (isFling && absVelocity > 1 && currentFraction < LINEAR_SCALE_LIMIT) { - - // TODO: Clean up these magic calculations - // Linearly interpolate the max value based on the velocity. - float maxValue = Math.max(absVelocity > 4 ? 1 + MAX_OVERSHOOT : - 1 + (absVelocity - 1) * MAX_OVERSHOOT / 3, - currentValue); - double angleToPeak = PI_BY_2 - Math.asin(currentValue / maxValue); - - if (expectedDuration != 0 && angleToPeak != 0) { - - float distanceLeft = 1 - currentFraction; - mAllAppsInterpolatorWrapper.baseInterpolator = (f) -> { - float scaledF = (f - currentFraction) / distanceLeft; - - if (scaledF < 0.5f) { - double angle = PI_BY_2 - angleToPeak + scaledF * angleToPeak / 0.5f; - return (float) (maxValue * Math.sin(angle)); - } - - scaledF = ((scaledF - .5f) / .5f); - double angle = PI_BY_2 + 3 * scaledF * PI_BY_2; - float amplitude = (1 - scaledF) * (1 - scaledF) * (maxValue - 1); - return 1 + (float) (amplitude * Math.sin(angle)); - }; - - animator.setDuration(expectedDuration).setInterpolator(LINEAR); - return; - } + if (isFling && expectedDuration != 0) { + // Update all apps interpolator to add a bit of overshoot starting from currFraction + final float currFraction = mCurrentAnimation.getProgressFraction(); + mAllAppsInterpolatorWrapper.baseInterpolator = Interpolators.clampToProgress( + new OvershootInterpolator(Math.min(Math.abs(velocity), 3f)), currFraction, 1); + animator.setDuration(Math.min(expectedDuration, ATOMIC_DURATION)) + .setInterpolator(LINEAR); } - - if (currentFraction < LINEAR_SCALE_LIMIT) { - mAllAppsInterpolatorWrapper.baseInterpolator = LINEAR; - return; - } - float extraValue = mAllAppsDampedInterpolator.getInterpolation(currentFraction) - 1; - float distanceLeft = 1 - currentFraction; - - animator.setFloatValues(currentFraction, 1); - mAllAppsInterpolatorWrapper.baseInterpolator = (f) -> { - float scaledF = (f - currentFraction) / distanceLeft; - - double angle = scaledF * 1.5 * Math.PI; - float amplitude = (1 - scaledF) * (1 - scaledF) * extraValue; - return 1 + (float) (amplitude * Math.sin(angle)); - }; - animator.setDuration(200).setInterpolator(LINEAR); - return; + } else { + mFinishFastOnSecondTouch = false; } - mFinishFastOnSecondTouch = false; } @Override protected void onSwipeInteractionCompleted(LauncherState targetState, int logAction) { super.onSwipeInteractionCompleted(targetState, logAction); if (mFromState == NORMAL && targetState == OVERVIEW) { - SysuiEventLogger.writeDummyRecentsTransition(0); + RecentsModel.getInstance(mLauncher).onOverviewShown(true, TAG); } } |