diff options
Diffstat (limited to 'src')
5 files changed, 200 insertions, 26 deletions
diff --git a/src/com/android/launcher3/folder/ClippedFolderIconLayoutRule.java b/src/com/android/launcher3/folder/ClippedFolderIconLayoutRule.java index ff357c0bc..f25345ee8 100644 --- a/src/com/android/launcher3/folder/ClippedFolderIconLayoutRule.java +++ b/src/com/android/launcher3/folder/ClippedFolderIconLayoutRule.java @@ -1,15 +1,18 @@ 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,21 +34,29 @@ 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; - // 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; + 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 + mTmpPoint[0] = mTmpPoint[1] = mAvailableSpace / 2 - (mIconSize * totalScale) / 2; } else { getPosition(index, curNumItems, mTmpPoint); - transX = mTmpPoint[0]; - transY = mTmpPoint[1]; } + transX = mTmpPoint[0]; + transY = mTmpPoint[1]; + if (params == null) { params = new PreviewItemDrawingParams(transX, transY, totalScale, overlayAlpha); } else { @@ -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; + } } diff --git a/src/com/android/launcher3/folder/FolderIcon.java b/src/com/android/launcher3/folder/FolderIcon.java index ae6a0e86d..c63eeb345 100644 --- a/src/com/android/launcher3/folder/FolderIcon.java +++ b/src/com/android/launcher3/folder/FolderIcon.java @@ -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,13 +312,39 @@ 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]); center[1] = (int) Math.round(scaleRelativeToDragLayer * center[1]); to.offset(center[0] - animateView.getMeasuredWidth() / 2, - center[1] - animateView.getMeasuredHeight() / 2); + center[1] - animateView.getMeasuredHeight() / 2); float finalAlpha = index < mPreviewLayoutRule.maxNumItems() ? 0.5f : 0f; @@ -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(); } @@ -655,11 +690,16 @@ public class FolderIcon extends FrameLayout implements FolderListener { interface PreviewLayoutRule { PreviewItemDrawingParams computePreviewItemDrawingParams(int index, int curNumItems, - PreviewItemDrawingParams params); + PreviewItemDrawingParams params); void init(int availableSpace, float intrinsicIconSize, boolean rtl); float scaleForItem(int index, int totalNumItems); float getIconSize(); int maxNumItems(); boolean clipToBackground(); + + boolean hasEnterExitIndices(); + int getExitIndex(); + int getEnterIndex(); + } } diff --git a/src/com/android/launcher3/folder/FolderIconPreviewVerifier.java b/src/com/android/launcher3/folder/FolderIconPreviewVerifier.java index 11c10783c..d054a5d42 100644 --- a/src/com/android/launcher3/folder/FolderIconPreviewVerifier.java +++ b/src/com/android/launcher3/folder/FolderIconPreviewVerifier.java @@ -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]; - } } /** diff --git a/src/com/android/launcher3/folder/PreviewItemManager.java b/src/com/android/launcher3/folder/PreviewItemManager.java index 74c210254..7a05f67e0 100644 --- a/src/com/android/launcher3/folder/PreviewItemManager.java +++ b/src/com/android/launcher3/folder/PreviewItemManager.java @@ -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; + } } diff --git a/src/com/android/launcher3/folder/StackFolderIconLayoutRule.java b/src/com/android/launcher3/folder/StackFolderIconLayoutRule.java index 138dc1c55..7d10556d0 100644 --- a/src/com/android/launcher3/folder/StackFolderIconLayoutRule.java +++ b/src/com/android/launcher3/folder/StackFolderIconLayoutRule.java @@ -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"); + } } |