Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 67d4b0ed authored by Jon Miranda's avatar Jon Miranda
Browse files

Polish taskbar un/stash animation.

- When QSB is inline, we add it to the reveal animation
  so that it moves in coordination with the rest of the
  taskbar icons
- Hide All Apps button when transitioning from Home -> App
  to match spec
- Shorten duration icons move in x duration so that they
  stay within the taskbar background bounds.

Bug: 267806083
Bug: 246635237
Bug: 246660243
Test: transient taskbar
      with isQsbInline = true and false

Change-Id: Ie6b866311cc2ceba88cdf01652b30fee457d0359
Merged-In: Ie6b866311cc2ceba88cdf01652b30fee457d0359
parent 90ff89e2
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -722,8 +722,8 @@ public class TaskbarStashController implements TaskbarControllers.LoggableTaskba
                skipInterpolator = FINAL_FRAME;
            }
        }
        play(as, mControllers.taskbarViewController
                .createRevealAnimToIsStashed(isStashed), 0, duration, EMPHASIZED);
        mControllers.taskbarViewController.addRevealAnimToIsStashed(as, isStashed, duration,
                EMPHASIZED);

        if (skipInterpolator != null) {
            as.setInterpolator(skipInterpolator);
+7 −0
Original line number Diff line number Diff line
@@ -163,6 +163,13 @@ public class TaskbarView extends FrameLayout implements FolderIcon.FolderIconPar
        return ColorUtils.HSLToColor(colorHSL);
    }

    /**
     * Returns the icon touch size.
     */
    public int getIconTouchSize() {
        return mIconTouchSize;
    }

    private int calculateThemeIconsBackground() {
        int color = ThemedIconDrawable.getColors(mContext)[0];
        if (Utilities.isDarkTheme(mContext)) {
+82 −57
Original line number Diff line number Diff line
@@ -63,7 +63,6 @@ import com.android.launcher3.icons.ThemedIconDrawable;
import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.touch.SingleAxisSwipeDetector;
import com.android.launcher3.util.DisplayController;
import com.android.launcher3.util.HorizontalInsettableView;
import com.android.launcher3.util.ItemInfoMatcher;
import com.android.launcher3.util.LauncherBindableItemsContainer;
import com.android.launcher3.util.MultiPropertyFactory;
@@ -91,6 +90,9 @@ public class TaskbarViewController implements TaskbarControllers.LoggableTaskbar
    public static final int ALPHA_INDEX_SMALL_SCREEN = 6;
    private static final int NUM_ALPHA_CHANNELS = 7;

    // This allows the icons on the edge to stay within the taskbar background bounds.
    private static final float ICON_REVEAL_X_DURATION_MULTIPLIER = 0.8f;

    private final TaskbarActivityContext mActivity;
    private final TaskbarView mTaskbarView;
    private final MultiValueAlpha mTaskbarIconAlpha;
@@ -304,73 +306,87 @@ public class TaskbarViewController implements TaskbarControllers.LoggableTaskbar
    /**
     * Creates and returns a {@link RevealOutlineAnimation} Animator that updates the icon shape
     * and size.
     * @param as The AnimatorSet to add all animations to.
     * @param isStashed When true, the icon crops vertically to the size of the stashed handle.
     *                  When false, the reverse happens.
     * @param duration The duration of the animation.
     * @param interpolator The interpolator to use for all animations.
     */
    public AnimatorSet createRevealAnimToIsStashed(boolean isStashed) {
        AnimatorSet as = new AnimatorSet();
    public void addRevealAnimToIsStashed(AnimatorSet as, boolean isStashed, long duration,
            Interpolator interpolator) {
        AnimatorSet reveal = new AnimatorSet();

        Rect stashedBounds = new Rect();
        mControllers.stashedHandleViewController.getStashedHandleBounds(stashedBounds);

        int numChildren = mTaskbarView.getChildCount();
        boolean isQsbInline = mActivity.getDeviceProfile().isQsbInline;
        int numIcons = mTaskbarView.getChildCount() - (isQsbInline ? 1 : 0);
        // We do not actually modify the width of the icons, but we will use this width to position
        // the children to overlay the nav handle.
        float virtualChildWidth = stashedBounds.width() / (float) numChildren;
        float virtualChildWidth = stashedBounds.width() / (float) numIcons;

        for (int i = numChildren - 1; i >= 0; i--) {
            View child = mTaskbarView.getChildAt(i);
        // All children move the same y-amount since they will be cropped to the same centerY.
        float croppedTransY = mTaskbarView.getIconTouchSize() - stashedBounds.height();

            if (child == mTaskbarView.getQsb()) {
                continue;
            }
        boolean isRtl = Utilities.isRtl(mTaskbarView.getResources());
        for (int i = mTaskbarView.getChildCount() - 1; i >= 0; i--) {
            View child = mTaskbarView.getChildAt(i);
            boolean isQsb = child == mTaskbarView.getQsb();

            // Crop the icons to/from the nav handle shape.
            as.play(createRevealAnimForView(child, isStashed));
            reveal.play(createRevealAnimForView(child, isStashed).setDuration(duration));

            // Translate the icons to/from their locations as the "nav handle."
            // We look at 'left' and 'right' values to ensure that the children stay within the
            // bounds of the stashed handle.
            float iconLeft = child.getLeft();
            float newLeft = stashedBounds.left + (virtualChildWidth * i);

            // All of the taskbar icons will overlap the entirety of the stashed handle
            // And the QSB, if inline, will overlap part of stashed handle as well.
            int positionInHandle = (isQsbInline && !isQsb)
                    ? i + (isRtl ? 1 : -1)
                    : i;
            float currentPosition = isQsb ? child.getX() : child.getLeft();
            float newPosition = stashedBounds.left + (virtualChildWidth * positionInHandle);
            final float croppedTransX;
            if (iconLeft > newLeft) {
                float newRight = stashedBounds.right - (virtualChildWidth * (numChildren - 1 - i));
                croppedTransX = -(child.getLeft() + child.getWidth() - newRight);
            if (currentPosition > newPosition) {
                float newRight = stashedBounds.right - (virtualChildWidth
                        * (numIcons - 1 - positionInHandle));
                croppedTransX = -(currentPosition + child.getWidth() - newRight);
            } else {
                croppedTransX = newLeft - iconLeft;
                croppedTransX = newPosition - currentPosition;
            }

            float croppedTransY = child.getHeight() - stashedBounds.height();
            long transXDuration = (long) (duration * ICON_REVEAL_X_DURATION_MULTIPLIER);
            float[] transX = isStashed
                    ? new float[] {croppedTransX}
                    : new float[] {croppedTransX, 0};
            float[] transY = isStashed
                    ? new float[] {croppedTransY}
                    : new float[] {croppedTransY, 0};

            if (child instanceof Reorderable) {
                MultiTranslateDelegate mtd = ((Reorderable) child).getTranslateDelegate();

                as.play(ObjectAnimator.ofFloat(mtd.getTranslationX(INDEX_TASKBAR_REVEAL_ANIM),
                        MULTI_PROPERTY_VALUE, isStashed
                                ? new float[] {croppedTransX}
                                : new float[] {croppedTransX, 0}));
                as.play(ObjectAnimator.ofFloat(mtd.getTranslationY(INDEX_TASKBAR_REVEAL_ANIM),
                        MULTI_PROPERTY_VALUE, isStashed
                                ? new float[] {croppedTransY}
                                : new float[] {croppedTransY, 0}));
                reveal.play(ObjectAnimator.ofFloat(mtd.getTranslationX(INDEX_TASKBAR_REVEAL_ANIM),
                        MULTI_PROPERTY_VALUE, transX)
                        .setDuration(transXDuration));
                reveal.play(ObjectAnimator.ofFloat(mtd.getTranslationY(INDEX_TASKBAR_REVEAL_ANIM),
                        MULTI_PROPERTY_VALUE, transY));
                as.addListener(forEndCallback(() ->
                        mtd.setTranslation(INDEX_TASKBAR_REVEAL_ANIM, 0, 0)));
            } else {
                as.play(ObjectAnimator.ofFloat(child,
                        VIEW_TRANSLATE_X, isStashed
                                ? new float[] {croppedTransX}
                                : new float[] {croppedTransX, 0}));
                as.play(ObjectAnimator.ofFloat(child,
                        VIEW_TRANSLATE_Y, isStashed
                                ? new float[] {croppedTransY}
                                : new float[] {croppedTransY, 0}));
                reveal.play(ObjectAnimator.ofFloat(child, VIEW_TRANSLATE_X, transX)
                        .setDuration(transXDuration));
                reveal.play(ObjectAnimator.ofFloat(child, VIEW_TRANSLATE_Y, transY));
                as.addListener(forEndCallback(() -> {
                    child.setTranslationX(0);
                    child.setTranslationY(0);
                }));
            }
        }
        return as;

        reveal.setInterpolator(interpolator);
        as.play(reveal);
    }

    /**
@@ -431,7 +447,6 @@ public class TaskbarViewController implements TaskbarControllers.LoggableTaskbar

        for (int i = 0; i < mTaskbarView.getChildCount(); i++) {
            View child = mTaskbarView.getChildAt(i);
            int positionInHotseat;
            boolean isAllAppsButton = child == mTaskbarView.getAllAppsButtonView();
            if (!mIsHotseatIconOnTopWhenAligned) {
                // When going to home, the EMPHASIZED interpolator in TaskbarLauncherStateController
@@ -439,11 +454,18 @@ public class TaskbarViewController implements TaskbarControllers.LoggableTaskbar
                // to avoid icons disappearing rather than fading out visually.
                setter.setViewAlpha(child, 0, Interpolators.clampToProgress(LINEAR, 0.8f, 1f));
            } else if ((isAllAppsButton && !FeatureFlags.ENABLE_ALL_APPS_BUTTON_IN_HOTSEAT.get())) {
                if (!isToHome
                        && mIsHotseatIconOnTopWhenAligned
                        && mControllers.taskbarStashController.isStashed()) {
                    // Prevent All Apps icon from appearing when going from hotseat to nav handle.
                    setter.setViewAlpha(child, 0, Interpolators.clampToProgress(LINEAR, 0f, 0f));
                } else {
                    setter.setViewAlpha(child, 0,
                            isToHome
                                    ? Interpolators.clampToProgress(LINEAR, 0f, 0.17f)
                                    : Interpolators.clampToProgress(LINEAR, 0.72f, 0.84f));
                }
            }

            if (child == mTaskbarView.getQsb()) {
                boolean isRtl = Utilities.isRtl(child.getResources());
@@ -454,32 +476,36 @@ public class TaskbarViewController implements TaskbarControllers.LoggableTaskbar
                float childCenter = (child.getLeft() + child.getRight()) / 2f;
                float halfQsbIconWidthDiff =
                        (launcherDp.hotseatQsbWidth - taskbarDp.iconSizePx) / 2f;
                setter.addFloat(child, VIEW_TRANSLATE_X,
                        isRtl ? -halfQsbIconWidthDiff : halfQsbIconWidthDiff,
                        hotseatIconCenter - childCenter, interpolator);

                float scale = ((float) taskbarDp.iconSizePx) / launcherDp.hotseatQsbVisualHeight;
                setter.addFloat(child, SCALE_PROPERTY, scale, 1f, interpolator);

                float fromX = isRtl ? -halfQsbIconWidthDiff : halfQsbIconWidthDiff;
                float toX = hotseatIconCenter - childCenter;
                if (child instanceof Reorderable) {
                    MultiTranslateDelegate mtd = ((Reorderable) child).getTranslateDelegate();

                    setter.addFloat(mtd.getTranslationX(INDEX_TASKBAR_ALIGNMENT_ANIM),
                            MULTI_PROPERTY_VALUE, fromX, toX, interpolator);
                    setter.setFloat(mtd.getTranslationY(INDEX_TASKBAR_ALIGNMENT_ANIM),
                            MULTI_PROPERTY_VALUE, mTaskbarBottomMargin, interpolator);
                } else {
                    setter.addFloat(child, VIEW_TRANSLATE_X, fromX, toX, interpolator);
                    setter.setFloat(child, VIEW_TRANSLATE_Y, mTaskbarBottomMargin, interpolator);
                }

                if (mIsHotseatIconOnTopWhenAligned) {
                    setter.addFloat(child, VIEW_ALPHA, 0f, 1f,
                            isToHome
                                    ? Interpolators.clampToProgress(LINEAR, 0f, 0.35f)
                                    : mActivity.getDeviceProfile().isQsbInline
                                            ? Interpolators.clampToProgress(LINEAR, 0f, 1f)
                                            : Interpolators.clampToProgress(LINEAR, 0.84f, 1f));
                }
                setter.addOnFrameListener(animator -> AlphaUpdateListener.updateVisibility(child));

                float qsbInsetFraction = halfQsbIconWidthDiff / launcherDp.hotseatQsbWidth;
                if (child instanceof HorizontalInsettableView) {
                    setter.addFloat((HorizontalInsettableView) child,
                            HorizontalInsettableView.HORIZONTAL_INSETS, qsbInsetFraction, 0,
                            interpolator);
                }
                continue;
            }

            int positionInHotseat;
            if (isAllAppsButton) {
                // Note that there is no All Apps button in the hotseat, this position is only used
                // as its convenient for animation purposes.
@@ -496,18 +522,17 @@ public class TaskbarViewController implements TaskbarControllers.LoggableTaskbar
            float hotseatIconCenter = hotseatPadding.left
                    + (hotseatCellSize + borderSpacing) * positionInHotseat
                    + hotseatCellSize / 2f;

            float childCenter = (child.getLeft() + child.getRight()) / 2f;
            float toX = hotseatIconCenter - childCenter;
            if (child instanceof Reorderable) {
                MultiTranslateDelegate mtd = ((Reorderable) child).getTranslateDelegate();

                setter.setFloat(mtd.getTranslationX(INDEX_TASKBAR_ALIGNMENT_ANIM),
                        MULTI_PROPERTY_VALUE, hotseatIconCenter - childCenter, interpolator);
                        MULTI_PROPERTY_VALUE, toX, interpolator);
                setter.setFloat(mtd.getTranslationY(INDEX_TASKBAR_ALIGNMENT_ANIM),
                        MULTI_PROPERTY_VALUE, mTaskbarBottomMargin, interpolator);
            } else {
                setter.setFloat(child, VIEW_TRANSLATE_X,
                        hotseatIconCenter - childCenter, interpolator);
                setter.setFloat(child, VIEW_TRANSLATE_X, toX, interpolator);
                setter.setFloat(child, VIEW_TRANSLATE_Y, mTaskbarBottomMargin, interpolator);
            }
            setter.setFloat(child, SCALE_PROPERTY, scaleUp, interpolator);
+1 −1
Original line number Diff line number Diff line
@@ -33,7 +33,7 @@ public class MultiTranslateDelegate {
    public static final int INDEX_REORDER_PREVIEW_OFFSET = 1;
    public static final int INDEX_MOVE_FROM_CENTER_ANIM = 2;

    // Specific for icons and folders
    // Specific for items in taskbar (icons, folders, qsb)
    public static final int INDEX_TASKBAR_ALIGNMENT_ANIM = 3;
    public static final int INDEX_TASKBAR_REVEAL_ANIM = 4;