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

Commit cebce95b authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Slide in first page preview items in FolderIcon after Folder closes."...

Merge "Slide in first page preview items in FolderIcon after Folder closes." into ub-launcher3-dorval-polish
parents 848cad56 27bdbcae
Loading
Loading
Loading
Loading
+11 −9
Original line number Diff line number Diff line
@@ -791,12 +791,14 @@ public class Folder extends AbstractFloatingView implements DragSource, View.OnC
        if (mFolderIcon != null) {
            mFolderIcon.setVisibility(View.VISIBLE);
            if (FeatureFlags.LAUNCHER3_NEW_FOLDER_ANIMATION) {
                mFolderIcon.mFolderName.setTextVisibility(true);
                mFolderIcon.setBackgroundVisible(true);
                mFolderIcon.mBackground.fadeInBackgroundShadow();
            }
            if (wasAnimated) {
                if (FeatureFlags.LAUNCHER3_NEW_FOLDER_ANIMATION) {
                    mFolderIcon.mBackground.fadeInBackgroundShadow();
                    mFolderIcon.mBackground.animateBackgroundStroke();
                    mFolderIcon.onFolderClose(mContent.getCurrentPage());
                }
                if (mFolderIcon.hasBadge()) {
                    mFolderIcon.createBadgeScaleAnimator(0f, 1f).start();
                }
@@ -818,6 +820,7 @@ public class Folder extends AbstractFloatingView implements DragSource, View.OnC
        mSuppressFolderDeletion = false;
        clearDragInfo();
        mState = STATE_SMALL;
        mContent.setCurrentPage(0);
    }

    public boolean acceptDrop(DragObject d) {
@@ -1516,18 +1519,17 @@ public class Folder extends AbstractFloatingView implements DragSource, View.OnC
        return itemsInReadingOrder;
    }

    public List<BubbleTextView> getItemsOnCurrentPage() {
    public List<BubbleTextView> getItemsOnPage(int page) {
        ArrayList<View> allItems = getItemsInRankOrder();
        int currentPage = mContent.getCurrentPage();
        int lastPage = mContent.getPageCount() - 1;
        int totalItemsInFolder = allItems.size();
        int itemsPerPage = mContent.itemsPerPage();
        int numItemsOnCurrentPage = currentPage == lastPage
                ? totalItemsInFolder - (itemsPerPage * currentPage)
        int numItemsOnCurrentPage = page == lastPage
                ? totalItemsInFolder - (itemsPerPage * page)
                : itemsPerPage;

        int startIndex = currentPage * itemsPerPage;
        int endIndex = startIndex + numItemsOnCurrentPage;
        int startIndex = page * itemsPerPage;
        int endIndex = Math.min(startIndex + numItemsOnCurrentPage, allItems.size());

        List<BubbleTextView> itemsOnCurrentPage = new ArrayList<>(numItemsOnCurrentPage);
        for (int i = startIndex; i < endIndex; ++i) {
+13 −7
Original line number Diff line number Diff line
@@ -119,7 +119,7 @@ public class FolderAnimationManager {
    public AnimatorSet getAnimator() {
        final DragLayer.LayoutParams lp = (DragLayer.LayoutParams) mFolder.getLayoutParams();
        FolderIcon.PreviewLayoutRule rule = mFolderIcon.getLayoutRule();
        final List<BubbleTextView> itemsInPreview = mFolderIcon.getItemsToDisplay();
        final List<BubbleTextView> itemsInPreview = mFolderIcon.getPreviewItems();

        // Match position of the FolderIcon
        final Rect folderIconPos = new Rect();
@@ -186,7 +186,7 @@ public class FolderAnimationManager {
        PropertyResetListener colorResetListener = new PropertyResetListener<>(
                BubbleTextView.TEXT_ALPHA_PROPERTY,
                Color.alpha(Themes.getAttrColor(mContext, android.R.attr.textColorSecondary)));
        for (BubbleTextView icon : mFolder.getItemsOnCurrentPage()) {
        for (BubbleTextView icon : mFolder.getItemsOnPage(mFolder.mContent.getCurrentPage())) {
            if (mIsOpening) {
                icon.setTextVisibility(false);
            }
@@ -237,13 +237,19 @@ public class FolderAnimationManager {
    }

    /**
     * Animate the items that are displayed in the preview.
     * Animate the items on the current page.
     */
    private void addPreviewItemAnimators(AnimatorSet animatorSet, final float folderScale,
            int previewItemOffsetX) {
        FolderIcon.PreviewLayoutRule rule = mFolderIcon.getLayoutRule();
        final List<BubbleTextView> itemsInPreview = mFolderIcon.getItemsToDisplay();
        boolean isOnFirstPage = mFolder.mContent.getCurrentPage() == 0;
        final List<BubbleTextView> itemsInPreview = isOnFirstPage
                ? mFolderIcon.getPreviewItems()
                : mFolderIcon.getPreviewItemsOnPage(mFolder.mContent.getCurrentPage());
        final int numItemsInPreview = itemsInPreview.size();
        final int numItemsInFirstPagePreview = isOnFirstPage
                ? numItemsInPreview
                : FolderIcon.NUM_ITEMS_IN_PREVIEW;

        TimeInterpolator previewItemInterpolator = getPreviewItemInterpolator();

@@ -256,8 +262,8 @@ public class FolderAnimationManager {
            btvLp.isLockedToGrid = true;
            cwc.setupLp(btv);

            // Match scale of icons in the preview.
            float previewScale = rule.scaleForItem(i, numItemsInPreview);
            // Match scale of icons in the preview of the items on the first page.
            float previewScale = rule.scaleForItem(i, numItemsInFirstPagePreview);
            float previewSize = rule.getIconSize() * previewScale;
            float iconScale = previewSize / itemsInPreview.get(i).getIconSize();

@@ -268,7 +274,7 @@ public class FolderAnimationManager {
            btv.setScaleY(scale);

            // Match positions of the icons in the folder with their positions in the preview
            rule.computePreviewItemDrawingParams(i, numItemsInPreview, mTmpParams);
            rule.computePreviewItemDrawingParams(i, numItemsInFirstPagePreview, mTmpParams);
            // The PreviewLayoutRule assumes that the icon size takes up the entire width so we
            // offset by the actual size.
            int iconOffsetX = (int) ((btvLp.width - btv.getIconSize()) * iconScale) / 2;
+19 −5
Original line number Diff line number Diff line
@@ -471,15 +471,25 @@ public class FolderIcon extends FrameLayout implements FolderListener {
        return mFolderName.getVisibility() == VISIBLE;
    }

    public List<BubbleTextView> getItemsToDisplay() {
    /**
     * Returns the list of preview items displayed in the icon.
     */
    public List<BubbleTextView> getPreviewItems() {
        return getPreviewItemsOnPage(0);
    }

    /**
     * Returns the list of "preview items" on {@param page}.
     */
    public List<BubbleTextView> getPreviewItemsOnPage(int page) {
        mPreviewVerifier.setFolderInfo(mFolder.getInfo());

        List<BubbleTextView> itemsToDisplay = new ArrayList<>();
        List<View> allItems = mFolder.getItemsInRankOrder();
        int numItems = allItems.size();
        List<BubbleTextView> itemsOnPage = mFolder.getItemsOnPage(page);
        int numItems = itemsOnPage.size();
        for (int rank = 0; rank < numItems; ++rank) {
            if (mPreviewVerifier.isItemInPreview(rank)) {
                itemsToDisplay.add((BubbleTextView) allItems.get(rank));
            if (mPreviewVerifier.isItemInPreview(page, rank)) {
                itemsToDisplay.add(itemsOnPage.get(rank));
            }

            if (itemsToDisplay.size() == FolderIcon.NUM_ITEMS_IN_PREVIEW) {
@@ -639,6 +649,10 @@ public class FolderIcon extends FrameLayout implements FolderListener {
        }
    }

    public void onFolderClose(int currentPage) {
        mPreviewItemManager.onFolderClose(currentPage);
    }

    interface PreviewLayoutRule {
        PreviewItemDrawingParams computePreviewItemDrawingParams(int index, int curNumItems,
            PreviewItemDrawingParams params);
+32 −2
Original line number Diff line number Diff line
@@ -25,15 +25,45 @@ import com.android.launcher3.config.FeatureFlags;
 */
public class FolderIconPreviewVerifier {

    private final int mMaxGridCountX;
    private final int mMaxGridCountY;
    private final int mMaxItemsPerPage;
    private final int[] mGridSize = new int[2];

    private int mGridCountX;

    public FolderIconPreviewVerifier(InvariantDeviceProfile profile) {
        // b/37570804
        mMaxGridCountX = profile.numFolderColumns;
        mMaxGridCountY = profile.numFolderRows;
        mMaxItemsPerPage = mMaxGridCountX * mMaxGridCountY;
    }

    public void setFolderInfo(FolderInfo info) {
        // b/37570804
        FolderPagedView.calculateGridSize(info.contents.size(), 0, 0, mMaxGridCountX,
                mMaxGridCountY, mMaxItemsPerPage, mGridSize);
        mGridCountX = mGridSize[0];
    }

    /**
     * Returns whether the item with {@param rank} is in the default Folder icon preview.
     */
    public boolean isItemInPreview(int rank) {
        return isItemInPreview(0, rank);
    }

    /**
     * @param page The page the item is on.
     * @param rank The rank of the item.
     * @return True iff the icon is in the 2x2 upper left quadrant of the Folder.
     */
    public boolean isItemInPreview(int page, int rank) {
        if (page > 0) {
            // First page items are laid out such that the first 4 items are always in the upper
            // left quadrant. For all other pages, we need to check the row and col.
            int col = rank % mGridCountX;
            int row = rank / mGridCountX;
            return col < 2 && row < 2;
        }
        return rank < FolderIcon.NUM_ITEMS_IN_PREVIEW;
    }
}
+77 −17
Original line number Diff line number Diff line
@@ -16,6 +16,9 @@

package com.android.launcher3.folder;

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ValueAnimator;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
@@ -48,10 +51,19 @@ public class PreviewItemManager {

    // These hold the first page preview items
    private ArrayList<PreviewItemDrawingParams> mFirstPageParams = new ArrayList<>();
    // These hold the current page preview items. It is empty if the current page is the first page.
    private ArrayList<PreviewItemDrawingParams> mCurrentPageParams = new ArrayList<>();

    private float mCurrentPageItemsTransX = 0;
    private boolean mShouldSlideInFirstPage;

    static final int INITIAL_ITEM_ANIMATION_DURATION = 350;
    private static final int FINAL_ITEM_ANIMATION_DURATION = 200;

    private static final int SLIDE_IN_FIRST_PAGE_ANIMATION_DURATION_DELAY = 200;
    private static final int SLIDE_IN_FIRST_PAGE_ANIMATION_DURATION = 300;
    private static final int ITEM_SLIDE_IN_OUT_DISTANCE_PX = 200;

    public PreviewItemManager(FolderIcon icon) {
        mIcon = icon;
    }
@@ -116,15 +128,30 @@ public class PreviewItemManager {
        return params;
    }

    public void draw(Canvas canvas) {
        computePreviewDrawingParams(mReferenceDrawable);
    public void drawParams(Canvas canvas, ArrayList<PreviewItemDrawingParams> params,
            float transX) {
        canvas.translate(transX, 0);
        // The first item should be drawn last (ie. on top of later items)
        for (int i = mFirstPageParams.size() - 1; i >= 0; i--) {
            PreviewItemDrawingParams p = mFirstPageParams.get(i);
        for (int i = params.size() - 1; i >= 0; i--) {
            PreviewItemDrawingParams p = params.get(i);
            if (!p.hidden) {
                drawPreviewItem(canvas, p);
            }
        }
        canvas.translate(-transX, 0);
    }

    public void draw(Canvas canvas) {
        computePreviewDrawingParams(mReferenceDrawable);

        float firstPageItemsTransX = 0;
        if (mShouldSlideInFirstPage) {
            drawParams(canvas, mCurrentPageParams, mCurrentPageItemsTransX);

            firstPageItemsTransX = -ITEM_SLIDE_IN_OUT_DISTANCE_PX + mCurrentPageItemsTransX;
        }

        drawParams(canvas, mFirstPageParams, firstPageItemsTransX);
    }

    public void onParamsChanged() {
@@ -156,21 +183,21 @@ public class PreviewItemManager {
        }
    }

    void updateItemDrawingParams(boolean animate) {
        List<BubbleTextView> items = mIcon.getItemsToDisplay();
        int numItemsInPreview = items.size();
        int prevNumItems = mFirstPageParams.size();
    void buildParamsForPage(int page, ArrayList<PreviewItemDrawingParams> params, boolean animate) {
        List<BubbleTextView> items = mIcon.getPreviewItemsOnPage(page);
        int prevNumItems = params.size();

        // We adjust the size of the list to match the number of items in the preview
        while (numItemsInPreview < mFirstPageParams.size()) {
            mFirstPageParams.remove(mFirstPageParams.size() - 1);
        // We adjust the size of the list to match the number of items in the preview.
        while (items.size() < params.size()) {
            params.remove(params.size() - 1);
        }
        while (numItemsInPreview > mFirstPageParams.size()) {
            mFirstPageParams.add(new PreviewItemDrawingParams(0, 0, 0, 0));
        while (items.size() > params.size()) {
            params.add(new PreviewItemDrawingParams(0, 0, 0, 0));
        }

        for (int i = 0; i < mFirstPageParams.size(); i++) {
            PreviewItemDrawingParams p = mFirstPageParams.get(i);
        int numItemsInFirstPagePreview = page == 0 ? items.size() : FolderIcon.NUM_ITEMS_IN_PREVIEW;
        for (int i = 0; i < params.size(); i++) {
            PreviewItemDrawingParams p = params.get(i);
            p.drawable = items.get(i).getCompoundDrawables()[1];

            if (p.drawable != null && !mIcon.mFolder.isOpen()) {
@@ -180,13 +207,13 @@ public class PreviewItemManager {
            }

            if (!animate || FeatureFlags.LAUNCHER3_LEGACY_FOLDER_ICON) {
                computePreviewItemDrawingParams(i, numItemsInPreview, p);
                computePreviewItemDrawingParams(i, numItemsInFirstPagePreview, p);
                if (mReferenceDrawable == null) {
                    mReferenceDrawable = p.drawable;
                }
            } else {
                FolderPreviewItemAnim anim = new FolderPreviewItemAnim(this, p, i, prevNumItems, i,
                        numItemsInPreview, DROP_IN_ANIMATION_DURATION, null);
                        numItemsInFirstPagePreview, DROP_IN_ANIMATION_DURATION, null);

                if (p.anim != null) {
                    if (p.anim.hasEqualFinalState(anim)) {
@@ -201,6 +228,39 @@ public class PreviewItemManager {
        }
    }

    void onFolderClose(int currentPage) {
        // If we are not closing on the first page, we animate the current page preview items
        // out, and animate the first page preview items in.
        mShouldSlideInFirstPage = currentPage != 0;
        if (mShouldSlideInFirstPage) {
            mCurrentPageItemsTransX = 0;
            buildParamsForPage(currentPage, mCurrentPageParams, false);
            onParamsChanged();

            ValueAnimator slideAnimator = ValueAnimator.ofFloat(0, ITEM_SLIDE_IN_OUT_DISTANCE_PX);
            slideAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                @Override
                public void onAnimationUpdate(ValueAnimator valueAnimator) {
                    mCurrentPageItemsTransX = (float) valueAnimator.getAnimatedValue();
                    onParamsChanged();
                }
            });
            slideAnimator.addListener(new AnimatorListenerAdapter() {
                @Override
                public void onAnimationEnd(Animator animation) {
                    mCurrentPageParams.clear();
                }
            });
            slideAnimator.setStartDelay(SLIDE_IN_FIRST_PAGE_ANIMATION_DURATION_DELAY);
            slideAnimator.setDuration(SLIDE_IN_FIRST_PAGE_ANIMATION_DURATION);
            slideAnimator.start();
        }
    }

    void updateItemDrawingParams(boolean animate) {
        buildParamsForPage(0, mFirstPageParams, animate);
    }

    boolean verifyDrawable(@NonNull Drawable who) {
        for (int i = 0; i < mFirstPageParams.size(); i++) {
            if (mFirstPageParams.get(i).drawable == who) {