diff options
author | Jon Miranda <jonmiranda@google.com> | 2017-07-06 09:55:50 -0700 |
---|---|---|
committer | Jon Miranda <jonmiranda@google.com> | 2017-07-06 12:20:56 -0700 |
commit | 6c5d10261eceaf1b57bce82e4e31d272bad2c349 (patch) | |
tree | f6ecd49c9d9f3feb2f336a020e5f4c841df5e7d4 /src/com/android/launcher3/folder | |
parent | e393c809e637b16bd9af8a2fc7cd30f0ffed020e (diff) | |
download | android_packages_apps_Trebuchet-6c5d10261eceaf1b57bce82e4e31d272bad2c349.tar.gz android_packages_apps_Trebuchet-6c5d10261eceaf1b57bce82e4e31d272bad2c349.tar.bz2 android_packages_apps_Trebuchet-6c5d10261eceaf1b57bce82e4e31d272bad2c349.zip |
Move the PreviewItem drawing/animation logic to PreviewItemManager.
We want this refactor in O-DR since we will be adding more animations:
- closing from a non-first page (ag/2455887 b/36022592)
- new on-drop animations *if we end up removing the permutation logic.
Bug: 36022592
Change-Id: I82b8f5f5033d4fd9bd50fbe414b0fb721891d043
Diffstat (limited to 'src/com/android/launcher3/folder')
-rw-r--r-- | src/com/android/launcher3/folder/Folder.java | 2 | ||||
-rw-r--r-- | src/com/android/launcher3/folder/FolderIcon.java | 209 | ||||
-rw-r--r-- | src/com/android/launcher3/folder/FolderPreviewItemAnim.java | 30 | ||||
-rw-r--r-- | src/com/android/launcher3/folder/PreviewItemManager.java | 216 |
4 files changed, 261 insertions, 196 deletions
diff --git a/src/com/android/launcher3/folder/Folder.java b/src/com/android/launcher3/folder/Folder.java index f68b394c1..afbf9f2a2 100644 --- a/src/com/android/launcher3/folder/Folder.java +++ b/src/com/android/launcher3/folder/Folder.java @@ -1280,7 +1280,7 @@ public class Folder extends AbstractFloatingView implements DragSource, View.OnC }; View finalChild = mContent.getLastItem(); if (finalChild != null) { - mFolderIcon.performDestroyAnimation(finalChild, onCompleteRunnable); + mFolderIcon.performDestroyAnimation(onCompleteRunnable); } else { onCompleteRunnable.run(); } diff --git a/src/com/android/launcher3/folder/FolderIcon.java b/src/com/android/launcher3/folder/FolderIcon.java index 3a0e71fa5..7fdacc094 100644 --- a/src/com/android/launcher3/folder/FolderIcon.java +++ b/src/com/android/launcher3/folder/FolderIcon.java @@ -37,7 +37,6 @@ import android.view.ViewGroup; import android.view.animation.AccelerateInterpolator; import android.view.animation.DecelerateInterpolator; import android.widget.FrameLayout; -import android.widget.TextView; import com.android.launcher3.Alarm; import com.android.launcher3.AppInfo; @@ -71,6 +70,8 @@ import com.android.launcher3.widget.PendingAddShortcutInfo; import java.util.ArrayList; import java.util.List; +import static com.android.launcher3.folder.PreviewItemManager.INITIAL_ITEM_ANIMATION_DURATION; + /** * An icon that can appear on in the workspace representing an {@link Folder}. */ @@ -87,9 +88,7 @@ public class FolderIcon extends FrameLayout implements FolderListener { private CheckLongPressHelper mLongPressHelper; private StylusEventHelper mStylusEventHelper; - private static final int DROP_IN_ANIMATION_DURATION = 400; - private static final int INITIAL_ITEM_ANIMATION_DURATION = 350; - private static final int FINAL_ITEM_ANIMATION_DURATION = 200; + static final int DROP_IN_ANIMATION_DURATION = 400; // Flag whether the folder should open itself when an item is dragged over is enabled. public static final boolean SPRING_LOADING_ENABLED = true; @@ -99,27 +98,19 @@ public class FolderIcon extends FrameLayout implements FolderListener { @Thunk BubbleTextView mFolderName; - // These variables are all associated with the drawing of the preview; they are stored - // as member variables for shared usage and to avoid computation on each frame - private float mIntrinsicIconSize = -1; - private int mTotalWidth = -1; - private int mPrevTopPadding = -1; - PreviewBackground mBackground = new PreviewBackground(); private boolean mBackgroundIsVisible = true; - private PreviewLayoutRule mPreviewLayoutRule; + FolderIconPreviewVerifier mPreviewVerifier; + PreviewLayoutRule mPreviewLayoutRule; + private PreviewItemManager mPreviewItemManager; + private PreviewItemDrawingParams mTmpParams = new PreviewItemDrawingParams(0, 0, 0, 0); boolean mAnimating = false; private Rect mTempBounds = new Rect(); private float mSlop; - FolderIconPreviewVerifier mPreviewVerifier; - private PreviewItemDrawingParams mTmpParams = new PreviewItemDrawingParams(0, 0, 0, 0); - private ArrayList<PreviewItemDrawingParams> mDrawingParams = new ArrayList<>(); - private Drawable mReferenceDrawable = null; - private Alarm mOpenAlarm = new Alarm(); private FolderBadgeInfo mBadgeInfo = new FolderBadgeInfo(); @@ -158,6 +149,7 @@ public class FolderIcon extends FrameLayout implements FolderListener { new StackFolderIconLayoutRule() : new ClippedFolderIconLayoutRule(); mSlop = ViewConfiguration.get(getContext()).getScaledTouchSlop(); + mPreviewItemManager = new PreviewItemManager(this); } public static FolderIcon fromXml(int resId, Launcher launcher, ViewGroup group, @@ -213,7 +205,7 @@ public class FolderIcon extends FrameLayout implements FolderListener { private void setFolder(Folder folder) { mFolder = folder; mPreviewVerifier = new FolderIconPreviewVerifier(mLauncher.getDeviceProfile().inv); - updateItemDrawingParams(false); + mPreviewItemManager.updateItemDrawingParams(false); } private boolean willAcceptItem(ItemInfo item) { @@ -254,40 +246,28 @@ public class FolderIcon extends FrameLayout implements FolderListener { } }; - public Drawable prepareCreate(final View destView) { - Drawable animateDrawable = ((TextView) destView).getCompoundDrawables()[1]; - computePreviewDrawingParams(animateDrawable.getIntrinsicWidth(), - destView.getMeasuredWidth()); - return animateDrawable; + public Drawable prepareCreateAnimation(final View destView) { + return mPreviewItemManager.prepareCreateAnimation(destView); } public void performCreateAnimation(final ShortcutInfo destInfo, final View destView, final ShortcutInfo srcInfo, final DragView srcView, Rect dstRect, float scaleRelativeToDragLayer, Runnable postAnimationRunnable) { - - // These correspond two the drawable and view that the icon was dropped _onto_ - Drawable animateDrawable = prepareCreate(destView); - - mReferenceDrawable = animateDrawable; - + prepareCreateAnimation(destView); addItem(destInfo); // This will animate the first item from it's position as an icon into its // position as the first item in the preview - animateFirstItem(animateDrawable, INITIAL_ITEM_ANIMATION_DURATION, false, null); + mPreviewItemManager.createFirstItemAnimation(false /* reverse */, null) + .start(); // This will animate the dragView (srcView) into the new folder onDrop(srcInfo, srcView, dstRect, scaleRelativeToDragLayer, 1, postAnimationRunnable); } - public void performDestroyAnimation(final View finalView, Runnable onCompleteRunnable) { - Drawable animateDrawable = ((TextView) finalView).getCompoundDrawables()[1]; - computePreviewDrawingParams(animateDrawable.getIntrinsicWidth(), - finalView.getMeasuredWidth()); - - // This will animate the first item from it's position as an icon into its - // position as the first item in the preview - animateFirstItem(animateDrawable, FINAL_ITEM_ANIMATION_DURATION, true, - onCompleteRunnable); + public void performDestroyAnimation(Runnable onCompleteRunnable) { + // This will animate the final item in the preview to be full size. + mPreviewItemManager.createFirstItemAnimation(true /* reverse */, onCompleteRunnable) + .start(); } public void onDragExit() { @@ -296,7 +276,7 @@ public class FolderIcon extends FrameLayout implements FolderListener { } private void onDrop(final ShortcutInfo item, DragView animateView, Rect finalRect, - float scaleRelativeToDragLayer, int index, Runnable postAnimationRunnable) { + float scaleRelativeToDragLayer, final int index, Runnable postAnimationRunnable) { item.cellX = -1; item.cellY = -1; @@ -342,12 +322,10 @@ public class FolderIcon extends FrameLayout implements FolderListener { addItem(item); mFolder.hideItem(item); - final PreviewItemDrawingParams params = index < mDrawingParams.size() ? - mDrawingParams.get(index) : null; - if (params != null) params.hidden = true; + mPreviewItemManager.hidePreviewItem(index, true); postDelayed(new Runnable() { public void run() { - if (params != null) params.hidden = false; + mPreviewItemManager.hidePreviewItem(index, false); mFolder.showItem(item); invalidate(); } @@ -369,25 +347,6 @@ public class FolderIcon extends FrameLayout implements FolderListener { onDrop(item, d.dragView, null, 1.0f, mInfo.contents.size(), d.postAnimationRunnable); } - private void computePreviewDrawingParams(int drawableSize, int totalSize) { - if (mIntrinsicIconSize != drawableSize || mTotalWidth != totalSize || - mPrevTopPadding != getPaddingTop()) { - mIntrinsicIconSize = drawableSize; - mTotalWidth = totalSize; - mPrevTopPadding = getPaddingTop(); - - mBackground.setup(mLauncher, this, mTotalWidth, getPaddingTop()); - mPreviewLayoutRule.init(mBackground.previewSize, mIntrinsicIconSize, - Utilities.isRtl(getResources())); - - updateItemDrawingParams(false); - } - } - - private void computePreviewDrawingParams(Drawable d) { - computePreviewDrawingParams(d.getIntrinsicWidth(), getMeasuredWidth()); - } - public void setBadgeInfo(FolderBadgeInfo badgeInfo) { updateBadgeScale(mBadgeInfo.hasBadge(), badgeInfo.hasBadge()); mBadgeInfo = badgeInfo; @@ -421,56 +380,21 @@ public class FolderIcon extends FrameLayout implements FolderListener { } private float getLocalCenterForIndex(int index, int curNumItems, int[] center) { - mTmpParams = computePreviewItemDrawingParams( + mTmpParams = mPreviewItemManager.computePreviewItemDrawingParams( Math.min(mPreviewLayoutRule.maxNumItems(), index), curNumItems, mTmpParams); mTmpParams.transX += mBackground.basePreviewOffsetX; mTmpParams.transY += mBackground.basePreviewOffsetY; - float offsetX = mTmpParams.transX + (mTmpParams.scale * mIntrinsicIconSize) / 2; - float offsetY = mTmpParams.transY + (mTmpParams.scale * mIntrinsicIconSize) / 2; + + float intrinsicIconSize = mPreviewItemManager.getIntrinsicIconSize(); + float offsetX = mTmpParams.transX + (mTmpParams.scale * intrinsicIconSize) / 2; + float offsetY = mTmpParams.transY + (mTmpParams.scale * intrinsicIconSize) / 2; center[0] = Math.round(offsetX); center[1] = Math.round(offsetY); return mTmpParams.scale; } - PreviewItemDrawingParams computePreviewItemDrawingParams(int index, int curNumItems, - PreviewItemDrawingParams params) { - // We use an index of -1 to represent an icon on the workspace for the destroy and - // create animations - if (index == -1) { - return getFinalIconParams(params); - } - return mPreviewLayoutRule.computePreviewItemDrawingParams(index, curNumItems, params); - } - - private PreviewItemDrawingParams getFinalIconParams(PreviewItemDrawingParams params) { - float iconSize = mLauncher.getDeviceProfile().iconSizePx; - - final float scale = iconSize / mReferenceDrawable.getIntrinsicWidth(); - final float trans = (mBackground.previewSize - iconSize) / 2; - - params.update(trans, trans, scale); - return params; - } - - private void drawPreviewItem(Canvas canvas, PreviewItemDrawingParams params) { - canvas.save(Canvas.MATRIX_SAVE_FLAG); - canvas.translate(params.transX, params.transY); - canvas.scale(params.scale, params.scale); - Drawable d = params.drawable; - - if (d != null) { - Rect bounds = d.getBounds(); - canvas.save(); - canvas.translate(-bounds.left, -bounds.top); - canvas.scale(mIntrinsicIconSize / bounds.width(), mIntrinsicIconSize / bounds.height()); - d.draw(canvas); - canvas.restore(); - } - canvas.restore(); - } - public void setFolderBackground(PreviewBackground bg) { mBackground = bg; mBackground.setInvalidateDelegate(this); @@ -487,10 +411,6 @@ public class FolderIcon extends FrameLayout implements FolderListener { if (!mBackgroundIsVisible) return; - if (mReferenceDrawable != null) { - computePreviewDrawingParams(mReferenceDrawable); - } - if (!mBackground.drawingDelegated()) { mBackground.drawBackground(canvas); } @@ -512,14 +432,7 @@ public class FolderIcon extends FrameLayout implements FolderListener { // The items are drawn in coordinates relative to the preview offset canvas.translate(mBackground.basePreviewOffsetX, mBackground.basePreviewOffsetY); - - // The first item should be drawn last (ie. on top of later items) - for (int i = mDrawingParams.size() - 1; i >= 0; i--) { - PreviewItemDrawingParams p = mDrawingParams.get(i); - if (!p.hidden) { - drawPreviewItem(canvas, p); - } - } + mPreviewItemManager.draw(canvas); canvas.translate(-mBackground.basePreviewOffsetX, -mBackground.basePreviewOffsetY); if (mPreviewLayoutRule.clipToBackground() && canvas.isHardwareAccelerated()) { @@ -546,19 +459,6 @@ public class FolderIcon extends FrameLayout implements FolderListener { } } - private void animateFirstItem(final Drawable d, int duration, final boolean reverse, - final Runnable onCompleteRunnable) { - FolderPreviewItemAnim anim; - if (!reverse) { - anim = new FolderPreviewItemAnim(this, mDrawingParams.get(0), -1, -1, 0, 2, duration, - onCompleteRunnable); - } else { - anim = new FolderPreviewItemAnim(this, mDrawingParams.get(0), 0, 2, -1, -1, duration, - onCompleteRunnable); - } - anim.start(); - } - public void setTextVisible(boolean visible) { if (visible) { mFolderName.setVisibility(VISIBLE); @@ -591,63 +491,12 @@ public class FolderIcon extends FrameLayout implements FolderListener { @Override protected boolean verifyDrawable(@NonNull Drawable who) { - for (int i = 0; i < mDrawingParams.size(); i++) { - if (mDrawingParams.get(i).drawable == who) { - return true; - } - } - return super.verifyDrawable(who); - } - - private void updateItemDrawingParams(boolean animate) { - List<BubbleTextView> items = getItemsToDisplay(); - int nItemsInPreview = items.size(); - - int prevNumItems = mDrawingParams.size(); - - // We adjust the size of the list to match the number of items in the preview - while (nItemsInPreview < mDrawingParams.size()) { - mDrawingParams.remove(mDrawingParams.size() - 1); - } - while (nItemsInPreview > mDrawingParams.size()) { - mDrawingParams.add(new PreviewItemDrawingParams(0, 0, 0, 0)); - } - - for (int i = 0; i < mDrawingParams.size(); i++) { - PreviewItemDrawingParams p = mDrawingParams.get(i); - p.drawable = items.get(i).getCompoundDrawables()[1]; - - if (p.drawable != null && !mFolder.isOpen()) { - // Set the callback to FolderIcon as it is responsible to drawing the icon. The - // callback will be release when the folder is opened. - p.drawable.setCallback(this); - } - - if (!animate || FeatureFlags.LAUNCHER3_LEGACY_FOLDER_ICON) { - computePreviewItemDrawingParams(i, nItemsInPreview, p); - if (mReferenceDrawable == null) { - mReferenceDrawable = p.drawable; - } - } else { - FolderPreviewItemAnim anim = new FolderPreviewItemAnim(this, p, i, prevNumItems, i, - nItemsInPreview, DROP_IN_ANIMATION_DURATION, null); - - if (p.anim != null) { - if (p.anim.hasEqualFinalState(anim)) { - // do nothing, let the current animation finish - continue; - } - p.anim.cancel(); - } - p.anim = anim; - p.anim.start(); - } - } + return mPreviewItemManager.verifyDrawable(who) || super.verifyDrawable(who); } @Override public void onItemsChanged(boolean animate) { - updateItemDrawingParams(animate); + mPreviewItemManager.updateItemDrawingParams(animate); invalidate(); requestLayout(); } diff --git a/src/com/android/launcher3/folder/FolderPreviewItemAnim.java b/src/com/android/launcher3/folder/FolderPreviewItemAnim.java index 0da7c5cb1..be075bc9a 100644 --- a/src/com/android/launcher3/folder/FolderPreviewItemAnim.java +++ b/src/com/android/launcher3/folder/FolderPreviewItemAnim.java @@ -25,16 +25,16 @@ import com.android.launcher3.LauncherAnimUtils; * Animates a Folder preview item. */ class FolderPreviewItemAnim { + + private static PreviewItemDrawingParams sTmpParams = new PreviewItemDrawingParams(0, 0, 0, 0); + private ValueAnimator mValueAnimator; float finalScale; float finalTransX; float finalTransY; - private PreviewItemDrawingParams mTmpParams = new PreviewItemDrawingParams(0, 0, 0, 0); - /** - * @param folderIcon The FolderIcon this preview will be drawn in. * @param params layout params to animate * @param index0 original index of the item to be animated * @param items0 original number of items in the preview @@ -43,20 +43,20 @@ class FolderPreviewItemAnim { * @param duration duration in ms of the animation * @param onCompleteRunnable runnable to execute upon animation completion */ - FolderPreviewItemAnim(final FolderIcon folderIcon, final PreviewItemDrawingParams params, - int index0, int items0, int index1, int items1, int duration, - final Runnable onCompleteRunnable) { - folderIcon.computePreviewItemDrawingParams(index1, items1, mTmpParams); + FolderPreviewItemAnim(final PreviewItemManager previewItemManager, + final PreviewItemDrawingParams params, int index0, int items0, int index1, int items1, + int duration, final Runnable onCompleteRunnable) { + previewItemManager.computePreviewItemDrawingParams(index1, items1, sTmpParams); - finalScale = mTmpParams.scale; - finalTransX = mTmpParams.transX; - finalTransY = mTmpParams.transY; + finalScale = sTmpParams.scale; + finalTransX = sTmpParams.transX; + finalTransY = sTmpParams.transY; - folderIcon.computePreviewItemDrawingParams(index0, items0, mTmpParams); + previewItemManager.computePreviewItemDrawingParams(index0, items0, sTmpParams); - final float scale0 = mTmpParams.scale; - final float transX0 = mTmpParams.transX; - final float transY0 = mTmpParams.transY; + final float scale0 = sTmpParams.scale; + final float transX0 = sTmpParams.transX; + final float transY0 = sTmpParams.transY; mValueAnimator = LauncherAnimUtils.ofFloat(0f, 1.0f); mValueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener(){ @@ -66,7 +66,7 @@ class FolderPreviewItemAnim { params.transX = transX0 + progress * (finalTransX - transX0); params.transY = transY0 + progress * (finalTransY - transY0); params.scale = scale0 + progress * (finalScale - scale0); - folderIcon.invalidate(); + previewItemManager.onParamsChanged(); } }); mValueAnimator.addListener(new AnimatorListenerAdapter() { diff --git a/src/com/android/launcher3/folder/PreviewItemManager.java b/src/com/android/launcher3/folder/PreviewItemManager.java new file mode 100644 index 000000000..2524a6d82 --- /dev/null +++ b/src/com/android/launcher3/folder/PreviewItemManager.java @@ -0,0 +1,216 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.launcher3.folder; + +import android.graphics.Canvas; +import android.graphics.Rect; +import android.graphics.drawable.Drawable; +import android.support.annotation.NonNull; +import android.view.View; +import android.widget.TextView; + +import com.android.launcher3.BubbleTextView; +import com.android.launcher3.Utilities; +import com.android.launcher3.config.FeatureFlags; + +import java.util.ArrayList; +import java.util.List; + +import static com.android.launcher3.folder.FolderIcon.DROP_IN_ANIMATION_DURATION; + +/** + * Manages the drawing and animations of {@link PreviewItemDrawingParams} for a {@link FolderIcon}. + */ +public class PreviewItemManager { + + private FolderIcon mIcon; + + // These variables are all associated with the drawing of the preview; they are stored + // as member variables for shared usage and to avoid computation on each frame + private float mIntrinsicIconSize = -1; + private int mTotalWidth = -1; + private int mPrevTopPadding = -1; + private Drawable mReferenceDrawable = null; + + // These hold the first page preview items + private ArrayList<PreviewItemDrawingParams> mFirstPageParams = new ArrayList<>(); + + static final int INITIAL_ITEM_ANIMATION_DURATION = 350; + private static final int FINAL_ITEM_ANIMATION_DURATION = 200; + + public PreviewItemManager(FolderIcon icon) { + mIcon = icon; + } + + /** + * @param reverse If true, animates the final item in the preview to be full size. If false, + * animates the first item to its position in the preview. + */ + public FolderPreviewItemAnim createFirstItemAnimation(final boolean reverse, + final Runnable onCompleteRunnable) { + return reverse + ? new FolderPreviewItemAnim(this, mFirstPageParams.get(0), 0, 2, -1, -1, + FINAL_ITEM_ANIMATION_DURATION, onCompleteRunnable) + : new FolderPreviewItemAnim(this, mFirstPageParams.get(0), -1, -1, 0, 2, + INITIAL_ITEM_ANIMATION_DURATION, onCompleteRunnable); + } + + Drawable prepareCreateAnimation(final View destView) { + Drawable animateDrawable = ((TextView) destView).getCompoundDrawables()[1]; + computePreviewDrawingParams(animateDrawable.getIntrinsicWidth(), + destView.getMeasuredWidth()); + mReferenceDrawable = animateDrawable; + return animateDrawable; + } + + private void computePreviewDrawingParams(Drawable d) { + computePreviewDrawingParams(d.getIntrinsicWidth(), mIcon.getMeasuredWidth()); + } + + private void computePreviewDrawingParams(int drawableSize, int totalSize) { + if (mIntrinsicIconSize != drawableSize || mTotalWidth != totalSize || + mPrevTopPadding != mIcon.getPaddingTop()) { + mIntrinsicIconSize = drawableSize; + mTotalWidth = totalSize; + mPrevTopPadding = mIcon.getPaddingTop(); + + mIcon.mBackground.setup(mIcon.mLauncher, mIcon, mTotalWidth, mIcon.getPaddingTop()); + mIcon.mPreviewLayoutRule.init(mIcon.mBackground.previewSize, mIntrinsicIconSize, + Utilities.isRtl(mIcon.getResources())); + + updateItemDrawingParams(false); + } + } + + PreviewItemDrawingParams computePreviewItemDrawingParams(int index, int curNumItems, + PreviewItemDrawingParams params) { + // We use an index of -1 to represent an icon on the workspace for the destroy and + // create animations + if (index == -1) { + return getFinalIconParams(params); + } + return mIcon.mPreviewLayoutRule.computePreviewItemDrawingParams(index, curNumItems, params); + } + + private PreviewItemDrawingParams getFinalIconParams(PreviewItemDrawingParams params) { + float iconSize = mIcon.mLauncher.getDeviceProfile().iconSizePx; + + final float scale = iconSize / mReferenceDrawable.getIntrinsicWidth(); + final float trans = (mIcon.mBackground.previewSize - iconSize) / 2; + + params.update(trans, trans, scale); + return params; + } + + public void draw(Canvas canvas) { + computePreviewDrawingParams(mReferenceDrawable); + // 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); + if (!p.hidden) { + drawPreviewItem(canvas, p); + } + } + } + + public void onParamsChanged() { + mIcon.invalidate(); + } + + private void drawPreviewItem(Canvas canvas, PreviewItemDrawingParams params) { + canvas.save(Canvas.MATRIX_SAVE_FLAG); + canvas.translate(params.transX, params.transY); + canvas.scale(params.scale, params.scale); + Drawable d = params.drawable; + + if (d != null) { + Rect bounds = d.getBounds(); + canvas.save(); + canvas.translate(-bounds.left, -bounds.top); + canvas.scale(mIntrinsicIconSize / bounds.width(), mIntrinsicIconSize / bounds.height()); + d.draw(canvas); + canvas.restore(); + } + canvas.restore(); + } + + public void hidePreviewItem(int index, boolean hidden) { + PreviewItemDrawingParams params = index < mFirstPageParams.size() ? + mFirstPageParams.get(index) : null; + if (params != null) { + params.hidden = hidden; + } + } + + void updateItemDrawingParams(boolean animate) { + List<BubbleTextView> items = mIcon.getItemsToDisplay(); + int numItemsInPreview = items.size(); + int prevNumItems = mFirstPageParams.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); + } + while (numItemsInPreview > mFirstPageParams.size()) { + mFirstPageParams.add(new PreviewItemDrawingParams(0, 0, 0, 0)); + } + + for (int i = 0; i < mFirstPageParams.size(); i++) { + PreviewItemDrawingParams p = mFirstPageParams.get(i); + p.drawable = items.get(i).getCompoundDrawables()[1]; + + if (p.drawable != null && !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); + } + + if (!animate || FeatureFlags.LAUNCHER3_LEGACY_FOLDER_ICON) { + computePreviewItemDrawingParams(i, numItemsInPreview, p); + if (mReferenceDrawable == null) { + mReferenceDrawable = p.drawable; + } + } else { + FolderPreviewItemAnim anim = new FolderPreviewItemAnim(this, p, i, prevNumItems, i, + numItemsInPreview, DROP_IN_ANIMATION_DURATION, null); + + if (p.anim != null) { + if (p.anim.hasEqualFinalState(anim)) { + // do nothing, let the current animation finish + continue; + } + p.anim.cancel(); + } + p.anim = anim; + p.anim.start(); + } + } + } + + boolean verifyDrawable(@NonNull Drawable who) { + for (int i = 0; i < mFirstPageParams.size(); i++) { + if (mFirstPageParams.get(i).drawable == who) { + return true; + } + } + return false; + } + + float getIntrinsicIconSize() { + return mIntrinsicIconSize; + } +} |