Search in sources :

Example 1 with StaggeredWorkspaceAnim

use of com.android.quickstep.util.StaggeredWorkspaceAnim in project android_packages_apps_Trebuchet by LineageOS.

the class NoButtonQuickSwitchTouchController method onDragEnd.

@Override
public void onDragEnd(PointF velocity) {
    boolean horizontalFling = mSwipeDetector.isFling(velocity.x);
    boolean verticalFling = mSwipeDetector.isFling(velocity.y);
    boolean noFling = !horizontalFling && !verticalFling;
    int logAction = noFling ? Touch.SWIPE : Touch.FLING;
    if (mMotionPauseDetector.isPaused() && noFling) {
        cancelAnimations();
        Animator overviewAnim = mLauncher.createAtomicAnimationFactory().createStateElementAnimation(INDEX_PAUSE_TO_OVERVIEW_ANIM);
        overviewAnim.addListener(new AnimatorListenerAdapter() {

            @Override
            public void onAnimationEnd(Animator animation) {
                onAnimationToStateCompleted(OVERVIEW, logAction);
            }
        });
        overviewAnim.start();
        return;
    }
    final LauncherState targetState;
    if (horizontalFling && verticalFling) {
        if (velocity.x < 0) {
            // Flinging left and up or down both go back home.
            targetState = NORMAL;
        } else {
            if (velocity.y > 0) {
                // Flinging right and down goes to quick switch.
                targetState = QUICK_SWITCH;
            } else {
                // Flinging up and right could go either home or to quick switch.
                // Determine the target based on the higher velocity.
                targetState = Math.abs(velocity.x) > Math.abs(velocity.y) ? QUICK_SWITCH : NORMAL;
            }
        }
    } else if (horizontalFling) {
        targetState = velocity.x > 0 ? QUICK_SWITCH : NORMAL;
    } else if (verticalFling) {
        targetState = velocity.y > 0 ? QUICK_SWITCH : NORMAL;
    } else {
        // If user isn't flinging, just snap to the closest state.
        boolean passedHorizontalThreshold = mXOverviewAnim.getInterpolatedProgress() > 0.5f;
        boolean passedVerticalThreshold = mYOverviewAnim.value > 1f;
        targetState = passedHorizontalThreshold && !passedVerticalThreshold ? QUICK_SWITCH : NORMAL;
    }
    // Animate the various components to the target state.
    float xProgress = mXOverviewAnim.getProgressFraction();
    float startXProgress = Utilities.boundToRange(xProgress + velocity.x * getSingleFrameMs(mLauncher) / mXRange, 0f, 1f);
    final float endXProgress = targetState == NORMAL ? 0 : 1;
    long xDuration = BaseSwipeDetector.calculateDuration(velocity.x, Math.abs(endXProgress - startXProgress));
    ValueAnimator xOverviewAnim = mXOverviewAnim.getAnimationPlayer();
    xOverviewAnim.setFloatValues(startXProgress, endXProgress);
    xOverviewAnim.setDuration(xDuration).setInterpolator(scrollInterpolatorForVelocity(velocity.x));
    mXOverviewAnim.dispatchOnStart();
    boolean flingUpToNormal = verticalFling && velocity.y < 0 && targetState == NORMAL;
    float yProgress = mYOverviewAnim.value;
    float startYProgress = Utilities.boundToRange(yProgress - velocity.y * getSingleFrameMs(mLauncher) / mYRange, 0f, mMaxYProgress);
    final float endYProgress;
    if (flingUpToNormal) {
        endYProgress = 1;
    } else if (targetState == NORMAL) {
        // Keep overview at its current scale/translationY as it slides off the screen.
        endYProgress = startYProgress;
    } else {
        endYProgress = 0;
    }
    float yDistanceToCover = Math.abs(endYProgress - startYProgress) * mYRange;
    long yDuration = (long) (yDistanceToCover / Math.max(1f, Math.abs(velocity.y)));
    ValueAnimator yOverviewAnim = mYOverviewAnim.animateToValue(startYProgress, endYProgress);
    yOverviewAnim.setDuration(yDuration);
    mYOverviewAnim.updateValue(startYProgress);
    ValueAnimator nonOverviewAnim = mNonOverviewAnim.getAnimationPlayer();
    if (flingUpToNormal && !mIsHomeScreenVisible) {
        // We are flinging to home while workspace is invisible, run the same staggered
        // animation as from an app.
        StateAnimationConfig config = new StateAnimationConfig();
        // Update mNonOverviewAnim to do nothing so it doesn't interfere.
        config.animFlags = 0;
        updateNonOverviewAnim(targetState, config);
        nonOverviewAnim = mNonOverviewAnim.getAnimationPlayer();
        new StaggeredWorkspaceAnim(mLauncher, velocity.y, false).start();
    } else {
        boolean canceled = targetState == NORMAL;
        if (canceled) {
            // Let the state manager know that the animation didn't go to the target state,
            // but don't clean up yet (we already clean up when the animation completes).
            mNonOverviewAnim.dispatchOnCancelWithoutCancelRunnable();
        }
        float startProgress = mNonOverviewAnim.getProgressFraction();
        float endProgress = canceled ? 0 : 1;
        nonOverviewAnim.setFloatValues(startProgress, endProgress);
        mNonOverviewAnim.dispatchOnStart();
    }
    nonOverviewAnim.setDuration(Math.max(xDuration, yDuration));
    mNonOverviewAnim.setEndAction(() -> onAnimationToStateCompleted(targetState, logAction));
    cancelAnimations();
    xOverviewAnim.start();
    yOverviewAnim.start();
    nonOverviewAnim.start();
}
Also used : LauncherState(com.android.launcher3.LauncherState) Animator(android.animation.Animator) ValueAnimator(android.animation.ValueAnimator) StateAnimationConfig(com.android.launcher3.states.StateAnimationConfig) AnimatorListenerAdapter(android.animation.AnimatorListenerAdapter) StaggeredWorkspaceAnim(com.android.quickstep.util.StaggeredWorkspaceAnim) ValueAnimator(android.animation.ValueAnimator)

Example 2 with StaggeredWorkspaceAnim

use of com.android.quickstep.util.StaggeredWorkspaceAnim in project Neo-Launcher by NeoApplications.

the class LauncherActivityControllerHelper method prepareHomeUI.

@NonNull
@Override
public HomeAnimationFactory prepareHomeUI(Launcher activity) {
    final DeviceProfile dp = activity.getDeviceProfile();
    final RecentsView recentsView = activity.getOverviewPanel();
    final TaskView runningTaskView = recentsView.getRunningTaskView();
    final View workspaceView;
    if (runningTaskView != null && runningTaskView.getTask().key.getComponent() != null) {
        workspaceView = activity.getWorkspace().getFirstMatchForAppClose(runningTaskView.getTask().key.getComponent().getPackageName(), UserHandle.of(runningTaskView.getTask().key.userId));
    } else {
        workspaceView = null;
    }
    final RectF iconLocation = new RectF();
    boolean canUseWorkspaceView = workspaceView != null && workspaceView.isAttachedToWindow();
    FloatingIconView floatingIconView = canUseWorkspaceView ? FloatingIconView.getFloatingIconView(activity, workspaceView, true, /* hideOriginal */
    iconLocation, false) : null;
    return new HomeAnimationFactory() {

        @Nullable
        @Override
        public View getFloatingView() {
            return floatingIconView;
        }

        @NonNull
        @Override
        public RectF getWindowTargetRect() {
            if (canUseWorkspaceView) {
                return iconLocation;
            } else {
                return HomeAnimationFactory.getDefaultWindowTargetRect(dp);
            }
        }

        @NonNull
        @Override
        public AnimatorPlaybackController createActivityAnimationToHome() {
            // Return an empty APC here since we have an non-user controlled animation to home.
            long accuracy = 2 * Math.max(dp.widthPx, dp.heightPx);
            return activity.getStateManager().createAnimationToNewWorkspace(NORMAL, accuracy, 0);
        }

        @Override
        public void playAtomicAnimation(float velocity) {
            new StaggeredWorkspaceAnim(activity, velocity, true).start();
        }
    };
}
Also used : RectF(android.graphics.RectF) DeviceProfile(com.android.launcher3.DeviceProfile) TaskView(com.android.quickstep.views.TaskView) FloatingIconView(com.android.launcher3.views.FloatingIconView) StaggeredWorkspaceAnim(com.android.quickstep.util.StaggeredWorkspaceAnim) LauncherRecentsView(com.android.quickstep.views.LauncherRecentsView) RecentsView(com.android.quickstep.views.RecentsView) View(android.view.View) FloatingIconView(com.android.launcher3.views.FloatingIconView) TaskView(com.android.quickstep.views.TaskView) LauncherRecentsView(com.android.quickstep.views.LauncherRecentsView) RecentsView(com.android.quickstep.views.RecentsView) NonNull(androidx.annotation.NonNull)

Example 3 with StaggeredWorkspaceAnim

use of com.android.quickstep.util.StaggeredWorkspaceAnim in project Neo-Launcher by NeoApplications.

the class NoButtonQuickSwitchTouchController method onDragEnd.

@Override
public void onDragEnd(PointF velocity) {
    boolean horizontalFling = mSwipeDetector.isFling(velocity.x);
    boolean verticalFling = mSwipeDetector.isFling(velocity.y);
    boolean noFling = !horizontalFling && !verticalFling;
    int logAction = noFling ? Touch.SWIPE : Touch.FLING;
    if (mMotionPauseDetector.isPaused() && noFling) {
        cancelAnimations();
        Animator overviewAnim = mLauncher.getAppTransitionManager().createStateElementAnimation(INDEX_PAUSE_TO_OVERVIEW_ANIM);
        overviewAnim.addListener(new AnimatorListenerAdapter() {

            @Override
            public void onAnimationEnd(Animator animation) {
                onAnimationToStateCompleted(OVERVIEW, logAction);
            }
        });
        overviewAnim.start();
        return;
    }
    final LauncherState targetState;
    if (horizontalFling && verticalFling) {
        if (velocity.x < 0) {
            // Flinging left and up or down both go back home.
            targetState = NORMAL;
        } else {
            if (velocity.y > 0) {
                // Flinging right and down goes to quick switch.
                targetState = QUICK_SWITCH;
            } else {
                // Flinging up and right could go either home or to quick switch.
                // Determine the target based on the higher velocity.
                targetState = Math.abs(velocity.x) > Math.abs(velocity.y) ? QUICK_SWITCH : NORMAL;
            }
        }
    } else if (horizontalFling) {
        targetState = velocity.x > 0 ? QUICK_SWITCH : NORMAL;
    } else if (verticalFling) {
        targetState = velocity.y > 0 ? QUICK_SWITCH : NORMAL;
    } else {
        // If user isn't flinging, just snap to the closest state based on x progress.
        boolean passedHorizontalThreshold = mXOverviewAnim.getInterpolatedProgress() > 0.5f;
        targetState = passedHorizontalThreshold ? QUICK_SWITCH : NORMAL;
    }
    // Animate the various components to the target state.
    float xProgress = mXOverviewAnim.getProgressFraction();
    float startXProgress = Utilities.boundToRange(xProgress + velocity.x * getSingleFrameMs(mLauncher) / mXRange, 0f, 1f);
    final float endXProgress = targetState == NORMAL ? 0 : 1;
    long xDuration = BaseSwipeDetector.calculateDuration(velocity.x, Math.abs(endXProgress - startXProgress));
    ValueAnimator xOverviewAnim = mXOverviewAnim.getAnimationPlayer();
    xOverviewAnim.setFloatValues(startXProgress, endXProgress);
    xOverviewAnim.setDuration(xDuration).setInterpolator(scrollInterpolatorForVelocity(velocity.x));
    mXOverviewAnim.dispatchOnStartWithVelocity(endXProgress, velocity.x);
    boolean flingUpToNormal = verticalFling && velocity.y < 0 && targetState == NORMAL;
    float yProgress = mYOverviewAnim.getProgressFraction();
    float startYProgress = Utilities.boundToRange(yProgress - velocity.y * getSingleFrameMs(mLauncher) / mYRange, 0f, 1f);
    final float endYProgress;
    if (flingUpToNormal) {
        endYProgress = 1;
    } else if (targetState == NORMAL) {
        // Keep overview at its current scale/translationY as it slides off the screen.
        endYProgress = startYProgress;
    } else {
        endYProgress = 0;
    }
    long yDuration = BaseSwipeDetector.calculateDuration(velocity.y, Math.abs(endYProgress - startYProgress));
    ValueAnimator yOverviewAnim = mYOverviewAnim.getAnimationPlayer();
    yOverviewAnim.setFloatValues(startYProgress, endYProgress);
    yOverviewAnim.setDuration(yDuration);
    mYOverviewAnim.dispatchOnStartWithVelocity(endYProgress, velocity.y);
    ValueAnimator nonOverviewAnim = mNonOverviewAnim.getAnimationPlayer();
    if (flingUpToNormal && !mIsHomeScreenVisible) {
        // We are flinging to home while workspace is invisible, run the same staggered
        // animation as from an app.
        // Update mNonOverviewAnim to do nothing so it doesn't interfere.
        updateNonOverviewAnim(targetState, new AnimatorSetBuilder(), 0);
        nonOverviewAnim = mNonOverviewAnim.getAnimationPlayer();
        new StaggeredWorkspaceAnim(mLauncher, velocity.y, false).start();
    } else {
        boolean canceled = targetState == NORMAL;
        if (canceled) {
            // Let the state manager know that the animation didn't go to the target state,
            // but don't clean up yet (we already clean up when the animation completes).
            mNonOverviewAnim.dispatchOnCancelWithoutCancelRunnable();
        }
        float startProgress = mNonOverviewAnim.getProgressFraction();
        float endProgress = canceled ? 0 : 1;
        nonOverviewAnim.setFloatValues(startProgress, endProgress);
        mNonOverviewAnim.dispatchOnStartWithVelocity(endProgress, horizontalFling ? velocity.x : velocity.y);
    }
    nonOverviewAnim.setDuration(Math.max(xDuration, yDuration));
    mNonOverviewAnim.setEndAction(() -> onAnimationToStateCompleted(targetState, logAction));
    cancelAnimations();
    xOverviewAnim.start();
    yOverviewAnim.start();
    nonOverviewAnim.start();
}
Also used : LauncherState(com.android.launcher3.LauncherState) Animator(android.animation.Animator) ObjectAnimator(android.animation.ObjectAnimator) ValueAnimator(android.animation.ValueAnimator) AnimatorSetBuilder(com.android.launcher3.anim.AnimatorSetBuilder) AnimatorListenerAdapter(android.animation.AnimatorListenerAdapter) StaggeredWorkspaceAnim(com.android.quickstep.util.StaggeredWorkspaceAnim) ValueAnimator(android.animation.ValueAnimator)

Aggregations

StaggeredWorkspaceAnim (com.android.quickstep.util.StaggeredWorkspaceAnim)3 Animator (android.animation.Animator)2 AnimatorListenerAdapter (android.animation.AnimatorListenerAdapter)2 ValueAnimator (android.animation.ValueAnimator)2 LauncherState (com.android.launcher3.LauncherState)2 ObjectAnimator (android.animation.ObjectAnimator)1 RectF (android.graphics.RectF)1 View (android.view.View)1 NonNull (androidx.annotation.NonNull)1 DeviceProfile (com.android.launcher3.DeviceProfile)1 AnimatorSetBuilder (com.android.launcher3.anim.AnimatorSetBuilder)1 StateAnimationConfig (com.android.launcher3.states.StateAnimationConfig)1 FloatingIconView (com.android.launcher3.views.FloatingIconView)1 LauncherRecentsView (com.android.quickstep.views.LauncherRecentsView)1 RecentsView (com.android.quickstep.views.RecentsView)1 TaskView (com.android.quickstep.views.TaskView)1