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

Commit 4dd024b9 authored by Jon Miranda's avatar Jon Miranda
Browse files

Add new motion for when Folder preview changes due to onDrop.

Instead of changing the display order of the Folder to preserve
the upper left quadrant, we are opting to change the Folder Icon
preview to always show the upper left quadrant.

This means that when adding items to a Folder, the preview items
may change. (They will change when the column size increases).

Bug: 27944225
Bug: 63140071
Change-Id: I863c2479469d68559cab2878030c2087d48217d6
parent 5dcd5027
Loading
Loading
Loading
Loading
+58 −11
Original line number Diff line number Diff line
package com.android.launcher3.folder;


public class ClippedFolderIconLayoutRule implements FolderIcon.PreviewLayoutRule {

    static final int MAX_NUM_ITEMS_IN_PREVIEW = 4;
    private static final int MIN_NUM_ITEMS_IN_PREVIEW = 2;
    private static final int MAX_NUM_ITEMS_PER_ROW = 2;

    final float MIN_SCALE = 0.48f;
    final float MAX_SCALE = 0.58f;
    final float MAX_RADIUS_DILATION = 0.15f;
    final float ITEM_RADIUS_SCALE_FACTOR = 1.33f;
    private static final float MIN_SCALE = 0.48f;
    private static final float MAX_SCALE = 0.58f;
    private static final float MAX_RADIUS_DILATION = 0.15f;
    private static final float ITEM_RADIUS_SCALE_FACTOR = 1.33f;

    private static final int EXIT_INDEX = -2;
    private static final int ENTER_INDEX = -3;

    private float[] mTmpPoint = new float[2];

@@ -31,20 +34,28 @@ public class ClippedFolderIconLayoutRule implements FolderIcon.PreviewLayoutRule
    @Override
    public PreviewItemDrawingParams computePreviewItemDrawingParams(int index, int curNumItems,
            PreviewItemDrawingParams params) {

        float totalScale = scaleForItem(index, curNumItems);
        float transX;
        float transY;
        float overlayAlpha = 0;

        if (index == getExitIndex()) {
            // 0 1 * <-- Exit position (row 0, col 2)
            // 2 3
            getGridPosition(0, 2, mTmpPoint);
        } else if (index == getEnterIndex()) {
            // 0 1
            // 2 3 * <-- Enter position (row 1, col 2)
            getGridPosition(1, 2, mTmpPoint);
        } else if (index >= MAX_NUM_ITEMS_IN_PREVIEW) {
            // Items beyond those displayed in the preview are animated to the center
        if (index >= MAX_NUM_ITEMS_IN_PREVIEW) {
            transX = transY = mAvailableSpace / 2 - (mIconSize * totalScale) / 2;
            mTmpPoint[0] = mTmpPoint[1] = mAvailableSpace / 2 - (mIconSize * totalScale) / 2;
        } else {
            getPosition(index, curNumItems, mTmpPoint);
        }

        transX = mTmpPoint[0];
        transY = mTmpPoint[1];
        }

        if (params == null) {
            params = new PreviewItemDrawingParams(transX, transY, totalScale, overlayAlpha);
@@ -55,6 +66,27 @@ public class ClippedFolderIconLayoutRule implements FolderIcon.PreviewLayoutRule
        return params;
    }

    /**
     * Builds a grid based on the positioning of the items when there are
     * {@link #MAX_NUM_ITEMS_IN_PREVIEW} in the preview.
     *
     * Positions in the grid: 0 1  // 0 is row 0, col 1
     *                        2 3  // 3 is row 1, col 1
     */
    private void getGridPosition(int row, int col, float[] result) {
        // We use position 0 and 3 to calculate the x and y distances between items.
        getPosition(0, 4, result);
        float left = result[0];
        float top = result[1];

        getPosition(3, 4, result);
        float dx = result[0] - left;
        float dy = result[1] - top;

        result[0] = left + (col * dx);
        result[1] = top + (row * dy);
    }

    private void getPosition(int index, int curNumItems, float[] result) {
        // The case of two items is homomorphic to the case of one.
        curNumItems = Math.max(curNumItems, 2);
@@ -127,4 +159,19 @@ public class ClippedFolderIconLayoutRule implements FolderIcon.PreviewLayoutRule
    public boolean clipToBackground() {
        return true;
    }

    @Override
    public boolean hasEnterExitIndices() {
        return true;
    }

    @Override
    public int getExitIndex() {
        return EXIT_INDEX;
    }

    @Override
    public int getEnterIndex() {
        return ENTER_INDEX;
    }
}
+47 −7
Original line number Diff line number Diff line
@@ -221,7 +221,15 @@ public class FolderIcon extends FrameLayout implements FolderListener {
    }

    public void addItem(ShortcutInfo item) {
        mInfo.add(item, true);
        addItem(item, true);
    }

    public void addItem(ShortcutInfo item, boolean animate) {
        mInfo.add(item, animate);
    }

    public void removeItem(ShortcutInfo item, boolean animate) {
        mInfo.remove(item, animate);
    }

    public void onDragEnter(ItemInfo dragInfo) {
@@ -276,7 +284,7 @@ public class FolderIcon extends FrameLayout implements FolderListener {
    }

    private void onDrop(final ShortcutInfo item, DragView animateView, Rect finalRect,
            float scaleRelativeToDragLayer, final int index, Runnable postAnimationRunnable) {
            float scaleRelativeToDragLayer, int index, Runnable postAnimationRunnable) {
        item.cellX = -1;
        item.cellY = -1;

@@ -304,6 +312,32 @@ public class FolderIcon extends FrameLayout implements FolderListener {
                workspace.resetTransitionTransform((CellLayout) getParent().getParent());
            }

            boolean itemAdded = false;
            if (index >= mPreviewLayoutRule.maxNumItems()
                    && mPreviewLayoutRule.hasEnterExitIndices()) {
                List<BubbleTextView> oldPreviewItems = getPreviewItemsOnPage(0);
                addItem(item, false);
                List<BubbleTextView> newPreviewItems = getPreviewItemsOnPage(0);

                if (!oldPreviewItems.containsAll(newPreviewItems)) {
                    for (int i = 0; i < newPreviewItems.size(); ++i) {
                        if (newPreviewItems.get(i).getTag().equals(item)) {
                            // If the item dropped is going to be in the preview, we update the
                            // index here to reflect its position in the preview.
                            index = i;
                        }
                    }
                    mPreviewItemManager.onDrop(oldPreviewItems, newPreviewItems, item);
                    itemAdded = true;
                } else {
                    removeItem(item, false);
                }
            }

            if (!itemAdded) {
                addItem(item);
            }

            int[] center = new int[2];
            float scale = getLocalCenterForIndex(index, index + 1, center);
            center[0] = (int) Math.round(scaleRelativeToDragLayer * center[0]);
@@ -319,13 +353,14 @@ public class FolderIcon extends FrameLayout implements FolderListener {
                    1, 1, finalScale, finalScale, DROP_IN_ANIMATION_DURATION,
                    new DecelerateInterpolator(2), new AccelerateInterpolator(2),
                    postAnimationRunnable, DragLayer.ANIMATION_END_DISAPPEAR, null);
            addItem(item);

            mFolder.hideItem(item);

            mPreviewItemManager.hidePreviewItem(index, true);
            if (!itemAdded) mPreviewItemManager.hidePreviewItem(index, true);
            final int finalIndex = index;
            postDelayed(new Runnable() {
                public void run() {
                    mPreviewItemManager.hidePreviewItem(index, false);
                    mPreviewItemManager.hidePreviewItem(finalIndex, false);
                    mFolder.showItem(item);
                    invalidate();
                }
@@ -661,5 +696,10 @@ public class FolderIcon extends FrameLayout implements FolderListener {
        float getIconSize();
        int maxNumItems();
        boolean clipToBackground();

        boolean hasEnterExitIndices();
        int getExitIndex();
        int getEnterIndex();

    }
}
+3 −8
Original line number Diff line number Diff line
@@ -40,19 +40,14 @@ public class FolderIconPreviewVerifier {
    }

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

        mDisplayingUpperLeftQuadrant = FeatureFlags.LAUNCHER3_NEW_FOLDER_ANIMATION
                && !FeatureFlags.LAUNCHER3_LEGACY_FOLDER_ICON
                && numItemsInFolder > FolderIcon.NUM_ITEMS_IN_PREVIEW;

        if (mDisplayingUpperLeftQuadrant) {
            FolderPagedView.calculateGridSize(info.contents.size(), 0, 0, mMaxGridCountX,
                    mMaxGridCountY, mMaxItemsPerPage, mGridSize);
            mGridCountX = mGridSize[0];
        }
    }

    /**
+77 −0
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@ import android.view.View;
import android.widget.TextView;

import com.android.launcher3.BubbleTextView;
import com.android.launcher3.ShortcutInfo;
import com.android.launcher3.Utilities;
import com.android.launcher3.config.FeatureFlags;

@@ -273,4 +274,80 @@ public class PreviewItemManager {
    float getIntrinsicIconSize() {
        return mIntrinsicIconSize;
    }

    /**
     * Handles the case where items in the preview are either:
     *  - Moving into the preview
     *  - Moving into a new position
     *  - Moving out of the preview
     *
     * @param oldParams The list of items in the old preview.
     * @param newParams The list of items in the new preview.
     * @param dropped The item that was dropped onto the FolderIcon.
     */
    public void onDrop(List<BubbleTextView> oldParams, List<BubbleTextView> newParams,
            ShortcutInfo dropped) {
        int numItems = newParams.size();
        final ArrayList<PreviewItemDrawingParams> params = mFirstPageParams;
        buildParamsForPage(0, params, false);

        // New preview items for items that are moving in (except for the dropped item).
        List<BubbleTextView> moveIn = new ArrayList<>();
        for (BubbleTextView btv : newParams) {
            if (!oldParams.contains(btv) && !btv.getTag().equals(dropped)) {
                moveIn.add(btv);
            }
        }
        for (int i = 0; i < moveIn.size(); ++i) {
            int prevIndex = newParams.indexOf(moveIn.get(i));
            PreviewItemDrawingParams p = params.get(prevIndex);
            computePreviewItemDrawingParams(prevIndex, numItems, p);
            updateTransitionParam(p, moveIn.get(i), mIcon.mPreviewLayoutRule.getEnterIndex(),
                    newParams.indexOf(moveIn.get(i)));
        }

        // Items that are moving into new positions within the preview.
        for (int newIndex = 0; newIndex < newParams.size(); ++newIndex) {
            int oldIndex = oldParams.indexOf(newParams.get(newIndex));
            if (oldIndex >= 0 && newIndex != oldIndex) {
                PreviewItemDrawingParams p = params.get(newIndex);
                updateTransitionParam(p, newParams.get(newIndex), oldIndex, newIndex);
            }
        }

        // Old preview items that need to be moved out.
        List<BubbleTextView> moveOut = new ArrayList<>(oldParams);
        moveOut.removeAll(newParams);
        for (int i = 0; i < moveOut.size(); ++i) {
            BubbleTextView item = moveOut.get(i);
            int oldIndex = oldParams.indexOf(item);
            PreviewItemDrawingParams p = computePreviewItemDrawingParams(oldIndex, numItems, null);
            updateTransitionParam(p, item, oldIndex, mIcon.mPreviewLayoutRule.getExitIndex());
            params.add(0, p); // We want these items first so that they are on drawn last.
        }

        for (int i = 0; i < params.size(); ++i) {
            if (params.get(i).anim != null) {
                params.get(i).anim.start();
            }
        }
    }

    private void updateTransitionParam(final PreviewItemDrawingParams p, BubbleTextView btv,
            int prevIndex, int newIndex) {
        p.drawable = btv.getCompoundDrawables()[1];
        if (!mIcon.mFolder.isOpen()) {
            // Set the callback to FolderIcon as it is responsible to drawing the icon. The
            // callback will be released when the folder is opened.
            p.drawable.setCallback(mIcon);
        }

        FolderPreviewItemAnim anim = new FolderPreviewItemAnim(this, p, prevIndex,
                FolderIcon.NUM_ITEMS_IN_PREVIEW, newIndex, FolderIcon.NUM_ITEMS_IN_PREVIEW,
                DROP_IN_ANIMATION_DURATION, null);
        if (p.anim != null && !p.anim.hasEqualFinalState(anim)) {
            p.anim.cancel();
        }
        p.anim = anim;
    }
}
+15 −0
Original line number Diff line number Diff line
@@ -97,4 +97,19 @@ public class StackFolderIconLayoutRule implements FolderIcon.PreviewLayoutRule {
    public boolean clipToBackground() {
        return false;
    }

    @Override
    public boolean hasEnterExitIndices() {
        return false;
    }

    @Override
    public int getExitIndex() {
        throw new RuntimeException("hasEnterExitIndices not supported");
    }

    @Override
    public int getEnterIndex() {
        throw new RuntimeException("hasEnterExitIndices not supported");
    }
}