131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project/* 231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * Copyright (C) 2008 The Android Open Source Project 331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * 431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * you may not use this file except in compliance with the License. 631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * You may obtain a copy of the License at 731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * 831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * 1031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 1131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 1231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * See the License for the specific language governing permissions and 1431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * limitations under the License. 1531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project */ 1631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 17261194387beebaa7927ec4e310274218b651494dSunny Goyalpackage com.android.launcher3.folder; 1831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 192801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohenimport android.animation.Animator; 202801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohenimport android.animation.AnimatorListenerAdapter; 212801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohenimport android.animation.ValueAnimator; 222801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohenimport android.animation.ValueAnimator.AnimatorUpdateListener; 2331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.content.Context; 24a9cf38f533d1e86269868f1e6a806ccffd4a78fcAdam Cohenimport android.graphics.Canvas; 25f4b08913677e18a8412930972237b91d5a946d95Adam Cohenimport android.graphics.Color; 26efca0279eb927faebffc38c8382818df67fcd159Adam Cohenimport android.graphics.Paint; 27119e8982ab6a0cf00e31e8744f27b72ba8bf7b20Adam Cohenimport android.graphics.Path; 28badf71e11fba2d6efa1d1bcca9542001f90a3777Adam Cohenimport android.graphics.PorterDuff; 293e8f811f31a2275e778244427271f77f4116c08bAdam Cohenimport android.graphics.Rect; 30efca0279eb927faebffc38c8382818df67fcd159Adam Cohenimport android.graphics.Region; 3131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.graphics.drawable.Drawable; 32099f60d51f6310e1290687e83958e665b3324504Adam Cohenimport android.os.Parcelable; 3331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.util.AttributeSet; 34efca0279eb927faebffc38c8382818df67fcd159Adam Cohenimport android.util.DisplayMetrics; 3531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.view.LayoutInflater; 3688f334571fe41df620ba903ced9b2c69b0170d5cWinson Chungimport android.view.MotionEvent; 377c6932140dcbd2db88d7a809ba72ee04abb5bf26Adam Cohenimport android.view.View; 3802dd7aea3d8ac94126a8f8069e6762592ea60326Jason Monkimport android.view.ViewConfiguration; 3931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.view.ViewGroup; 403e8f811f31a2275e778244427271f77f4116c08bAdam Cohenimport android.view.animation.AccelerateInterpolator; 413e8f811f31a2275e778244427271f77f4116c08bAdam Cohenimport android.view.animation.DecelerateInterpolator; 426e1c0d34bb31cacc24c57c89ab01deaa8985814fWinson Chungimport android.widget.FrameLayout; 43a9cf38f533d1e86269868f1e6a806ccffd4a78fcAdam Cohenimport android.widget.TextView; 4431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 45261194387beebaa7927ec4e310274218b651494dSunny Goyalimport com.android.launcher3.Alarm; 46261194387beebaa7927ec4e310274218b651494dSunny Goyalimport com.android.launcher3.AppInfo; 47261194387beebaa7927ec4e310274218b651494dSunny Goyalimport com.android.launcher3.BubbleTextView; 48261194387beebaa7927ec4e310274218b651494dSunny Goyalimport com.android.launcher3.CellLayout; 49261194387beebaa7927ec4e310274218b651494dSunny Goyalimport com.android.launcher3.CheckLongPressHelper; 50261194387beebaa7927ec4e310274218b651494dSunny Goyalimport com.android.launcher3.DeviceProfile; 51325dc23624160689e59fbac708cf6f222b20d025Daniel Sandlerimport com.android.launcher3.DropTarget.DragObject; 52261194387beebaa7927ec4e310274218b651494dSunny Goyalimport com.android.launcher3.FastBitmapDrawable; 53261194387beebaa7927ec4e310274218b651494dSunny Goyalimport com.android.launcher3.FolderInfo; 54325dc23624160689e59fbac708cf6f222b20d025Daniel Sandlerimport com.android.launcher3.FolderInfo.FolderListener; 55261194387beebaa7927ec4e310274218b651494dSunny Goyalimport com.android.launcher3.IconCache; 56261194387beebaa7927ec4e310274218b651494dSunny Goyalimport com.android.launcher3.ItemInfo; 57261194387beebaa7927ec4e310274218b651494dSunny Goyalimport com.android.launcher3.Launcher; 58261194387beebaa7927ec4e310274218b651494dSunny Goyalimport com.android.launcher3.LauncherAnimUtils; 59261194387beebaa7927ec4e310274218b651494dSunny Goyalimport com.android.launcher3.LauncherAppState; 60261194387beebaa7927ec4e310274218b651494dSunny Goyalimport com.android.launcher3.LauncherSettings; 61261194387beebaa7927ec4e310274218b651494dSunny Goyalimport com.android.launcher3.OnAlarmListener; 62261194387beebaa7927ec4e310274218b651494dSunny Goyalimport com.android.launcher3.PreloadIconDrawable; 63261194387beebaa7927ec4e310274218b651494dSunny Goyalimport com.android.launcher3.R; 64261194387beebaa7927ec4e310274218b651494dSunny Goyalimport com.android.launcher3.ShortcutInfo; 65261194387beebaa7927ec4e310274218b651494dSunny Goyalimport com.android.launcher3.SimpleOnStylusPressListener; 66261194387beebaa7927ec4e310274218b651494dSunny Goyalimport com.android.launcher3.StylusEventHelper; 67261194387beebaa7927ec4e310274218b651494dSunny Goyalimport com.android.launcher3.Utilities; 68261194387beebaa7927ec4e310274218b651494dSunny Goyalimport com.android.launcher3.Workspace; 69119e8982ab6a0cf00e31e8744f27b72ba8bf7b20Adam Cohenimport com.android.launcher3.config.FeatureFlags; 70fedca43d396d6fd7c46fbb2f37dfa7cfe3b31834Vadim Tryshevimport com.android.launcher3.dragndrop.DragLayer; 71fedca43d396d6fd7c46fbb2f37dfa7cfe3b31834Vadim Tryshevimport com.android.launcher3.dragndrop.DragView; 72091440a9cb9d4f42406631004aa484cbb79214caAdam Cohenimport com.android.launcher3.util.Thunk; 73edcce099c98a6c40d10109ac092ab50f9d2668f3Romain Guy 74c0dcf597084d00e4c23a7fea5fd0738f6c095a6bAdam Cohenimport java.util.ArrayList; 75c0dcf597084d00e4c23a7fea5fd0738f6c095a6bAdam Cohen 7631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project/** 77f9c184a619e4e4b82cf9e0bf318ca6d8deaaaee7Adam Cohen * An icon that can appear on in the workspace representing an {@link Folder}. 7831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project */ 796e1c0d34bb31cacc24c57c89ab01deaa8985814fWinson Chungpublic class FolderIcon extends FrameLayout implements FolderListener { 80efca0279eb927faebffc38c8382818df67fcd159Adam Cohen @Thunk Launcher mLauncher; 81091440a9cb9d4f42406631004aa484cbb79214caAdam Cohen @Thunk Folder mFolder; 82fb91f303f5e672f9b4c4f9f8a03486b224d60cd6Adam Cohen private FolderInfo mInfo; 83091440a9cb9d4f42406631004aa484cbb79214caAdam Cohen @Thunk static boolean sStaticValuesDirty = true; 84a9cf38f533d1e86269868f1e6a806ccffd4a78fcAdam Cohen 85efca0279eb927faebffc38c8382818df67fcd159Adam Cohen public static final int NUM_ITEMS_IN_PREVIEW = FeatureFlags.LAUNCHER3_LEGACY_FOLDER_ICON ? 86efca0279eb927faebffc38c8382818df67fcd159Adam Cohen StackFolderIconLayoutRule.MAX_NUM_ITEMS_IN_PREVIEW : 87efca0279eb927faebffc38c8382818df67fcd159Adam Cohen ClippedFolderIconLayoutRule.MAX_NUM_ITEMS_IN_PREVIEW; 88f9c184a619e4e4b82cf9e0bf318ca6d8deaaaee7Adam Cohen 8988f334571fe41df620ba903ced9b2c69b0170d5cWinson Chung private CheckLongPressHelper mLongPressHelper; 90ef044dd380ac3abf354027750efdc16d5d48ac70Mady Mellor private StylusEventHelper mStylusEventHelper; 9188f334571fe41df620ba903ced9b2c69b0170d5cWinson Chung 92badf71e11fba2d6efa1d1bcca9542001f90a3777Adam Cohen // The number of icons to display in the 93f4b08913677e18a8412930972237b91d5a946d95Adam Cohen private static final int CONSUMPTION_ANIMATION_DURATION = 100; 94d044526d82e7938cf35b296978d9d5302f98b4afAdam Cohen private static final int DROP_IN_ANIMATION_DURATION = 400; 958dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen private static final int INITIAL_ITEM_ANIMATION_DURATION = 350; 96fb91f303f5e672f9b4c4f9f8a03486b224d60cd6Adam Cohen private static final int FINAL_ITEM_ANIMATION_DURATION = 200; 97badf71e11fba2d6efa1d1bcca9542001f90a3777Adam Cohen 9855bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi // Flag whether the folder should open itself when an item is dragged over is enabled. 9955bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi public static final boolean SPRING_LOADING_ENABLED = true; 10055bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi 10155bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi // Delay when drag enters until the folder opens, in miliseconds. 10255bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi private static final int ON_OPEN_DELAY = 800; 10355bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi 104efca0279eb927faebffc38c8382818df67fcd159Adam Cohen @Thunk BubbleTextView mFolderName; 1052801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen 106d044526d82e7938cf35b296978d9d5302f98b4afAdam Cohen // These variables are all associated with the drawing of the preview; they are stored 107d044526d82e7938cf35b296978d9d5302f98b4afAdam Cohen // as member variables for shared usage and to avoid computation on each frame 108aa2542a461072a57058ce45946ff6f5552ecce8aAdam Cohen private int mIntrinsicIconSize = -1; 109aa2542a461072a57058ce45946ff6f5552ecce8aAdam Cohen private int mTotalWidth = -1; 110aa2542a461072a57058ce45946ff6f5552ecce8aAdam Cohen private int mPrevTopPadding = -1; 111aa2542a461072a57058ce45946ff6f5552ecce8aAdam Cohen 112efca0279eb927faebffc38c8382818df67fcd159Adam Cohen PreviewBackground mBackground = new PreviewBackground(); 113f9c184a619e4e4b82cf9e0bf318ca6d8deaaaee7Adam Cohen 114f9c184a619e4e4b82cf9e0bf318ca6d8deaaaee7Adam Cohen private PreviewLayoutRule mPreviewLayoutRule; 115f9c184a619e4e4b82cf9e0bf318ca6d8deaaaee7Adam Cohen 116d044526d82e7938cf35b296978d9d5302f98b4afAdam Cohen boolean mAnimating = false; 117d4e53c882494f8cd7e4c0d44dbfc300d3610afcfWinson Chung private Rect mOldBounds = new Rect(); 118fb91f303f5e672f9b4c4f9f8a03486b224d60cd6Adam Cohen 11902dd7aea3d8ac94126a8f8069e6762592ea60326Jason Monk private float mSlop; 12002dd7aea3d8ac94126a8f8069e6762592ea60326Jason Monk 1214f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen private PreviewItemDrawingParams mTmpParams = new PreviewItemDrawingParams(0, 0, 0, 0); 1224f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen private ArrayList<PreviewItemDrawingParams> mDrawingParams = new ArrayList<PreviewItemDrawingParams>(); 1234f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen private Drawable mReferenceDrawable = null; 124d044526d82e7938cf35b296978d9d5302f98b4afAdam Cohen 125efca0279eb927faebffc38c8382818df67fcd159Adam Cohen Paint mBgPaint = new Paint(); 126efca0279eb927faebffc38c8382818df67fcd159Adam Cohen 12755bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi private Alarm mOpenAlarm = new Alarm(); 12855bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi 12931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project public FolderIcon(Context context, AttributeSet attrs) { 13031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project super(context, attrs); 13188f334571fe41df620ba903ced9b2c69b0170d5cWinson Chung init(); 13231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 13331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 13431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project public FolderIcon(Context context) { 13531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project super(context); 13688f334571fe41df620ba903ced9b2c69b0170d5cWinson Chung init(); 13788f334571fe41df620ba903ced9b2c69b0170d5cWinson Chung } 13888f334571fe41df620ba903ced9b2c69b0170d5cWinson Chung 13988f334571fe41df620ba903ced9b2c69b0170d5cWinson Chung private void init() { 14088f334571fe41df620ba903ced9b2c69b0170d5cWinson Chung mLongPressHelper = new CheckLongPressHelper(this); 141bb83520a620919a8f19472ba4426585d007d1abaMady Mellor mStylusEventHelper = new StylusEventHelper(new SimpleOnStylusPressListener(this), this); 142efca0279eb927faebffc38c8382818df67fcd159Adam Cohen mPreviewLayoutRule = FeatureFlags.LAUNCHER3_LEGACY_FOLDER_ICON ? 143efca0279eb927faebffc38c8382818df67fcd159Adam Cohen new StackFolderIconLayoutRule() : 144efca0279eb927faebffc38c8382818df67fcd159Adam Cohen new ClippedFolderIconLayoutRule(); 1450280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka } 1460280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka 147f9c184a619e4e4b82cf9e0bf318ca6d8deaaaee7Adam Cohen public static FolderIcon fromXml(int resId, Launcher launcher, ViewGroup group, 148df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen FolderInfo folderInfo, IconCache iconCache) { 1493a9fcedbcd235372cd2ab64f825a0b5b3937f59eMichael Jurka @SuppressWarnings("all") // suppress dead code warning 1503a9fcedbcd235372cd2ab64f825a0b5b3937f59eMichael Jurka final boolean error = INITIAL_ITEM_ANIMATION_DURATION >= DROP_IN_ANIMATION_DURATION; 1513a9fcedbcd235372cd2ab64f825a0b5b3937f59eMichael Jurka if (error) { 152d044526d82e7938cf35b296978d9d5302f98b4afAdam Cohen throw new IllegalStateException("DROP_IN_ANIMATION_DURATION must be greater than " + 153d044526d82e7938cf35b296978d9d5302f98b4afAdam Cohen "INITIAL_ITEM_ANIMATION_DURATION, as sequencing of adding first two items " + 154d044526d82e7938cf35b296978d9d5302f98b4afAdam Cohen "is dependent on this"); 155d044526d82e7938cf35b296978d9d5302f98b4afAdam Cohen } 1562e6da1539bc7286336b3c24d96ab76434939ce4dAdam Cohen 1572e6da1539bc7286336b3c24d96ab76434939ce4dAdam Cohen DeviceProfile grid = launcher.getDeviceProfile(); 15831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project FolderIcon icon = (FolderIcon) LayoutInflater.from(launcher).inflate(resId, group, false); 159efca0279eb927faebffc38c8382818df67fcd159Adam Cohen 160efca0279eb927faebffc38c8382818df67fcd159Adam Cohen // For performance and compatibility reasons we render the preview using a software layer. 161efca0279eb927faebffc38c8382818df67fcd159Adam Cohen // In particular, hardware path clipping has spotty ecosystem support and bad performance. 162efca0279eb927faebffc38c8382818df67fcd159Adam Cohen // Software rendering also allows us to use shadow layers. 163efca0279eb927faebffc38c8382818df67fcd159Adam Cohen icon.setLayerType(LAYER_TYPE_SOFTWARE, new Paint(Paint.FILTER_BITMAP_FLAG)); 164efca0279eb927faebffc38c8382818df67fcd159Adam Cohen 1655f8afe6280eae34620067696173e71943e1a30a3Winson Chung icon.setClipToPadding(false); 166d2eca6b66e654e71fb46ae718910af3ec6c2cf9cAdam Cohen icon.mFolderName = (BubbleTextView) icon.findViewById(R.id.folder_icon_name); 16776fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen icon.mFolderName.setText(folderInfo.title); 1686e1c0d34bb31cacc24c57c89ab01deaa8985814fWinson Chung icon.mFolderName.setCompoundDrawablePadding(0); 1696e1c0d34bb31cacc24c57c89ab01deaa8985814fWinson Chung FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) icon.mFolderName.getLayoutParams(); 1706e1c0d34bb31cacc24c57c89ab01deaa8985814fWinson Chung lp.topMargin = grid.iconSizePx + grid.iconDrawablePaddingPx; 1716e1c0d34bb31cacc24c57c89ab01deaa8985814fWinson Chung 17231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project icon.setTag(folderInfo); 17331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project icon.setOnClickListener(launcher); 17431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project icon.mInfo = folderInfo; 17531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project icon.mLauncher = launcher; 176f4f89ef608245d39bbddda05f291361d2ae06667Sunny Goyal icon.setContentDescription(launcher.getString(R.string.folder_name_format, folderInfo.title)); 177a9cf38f533d1e86269868f1e6a806ccffd4a78fcAdam Cohen Folder folder = Folder.fromXml(launcher); 178a9cf38f533d1e86269868f1e6a806ccffd4a78fcAdam Cohen folder.setDragController(launcher.getDragController()); 1792801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen folder.setFolderIcon(icon); 180a9cf38f533d1e86269868f1e6a806ccffd4a78fcAdam Cohen folder.bind(folderInfo); 1814f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen icon.setFolder(folder); 182ae50284e0a838139c67caf0064a0977c871497faSunny Goyal icon.setAccessibilityDelegate(launcher.getAccessibilityDelegate()); 183e48644a6cc3024399ee2c9509d42ef6c2770ef61Sunny Goyal 18490cb3e51af988d526912aed7a532745d729a844cSunny Goyal folderInfo.addListener(icon); 18590cb3e51af988d526912aed7a532745d729a844cSunny Goyal 18690cb3e51af988d526912aed7a532745d729a844cSunny Goyal icon.setOnFocusChangeListener(launcher.mFocusHandler); 18719072da7441e07d5e90026d9e9e1b38f11245e44Adam Cohen return icon; 18819072da7441e07d5e90026d9e9e1b38f11245e44Adam Cohen } 18919072da7441e07d5e90026d9e9e1b38f11245e44Adam Cohen 190099f60d51f6310e1290687e83958e665b3324504Adam Cohen @Override 191099f60d51f6310e1290687e83958e665b3324504Adam Cohen protected Parcelable onSaveInstanceState() { 192099f60d51f6310e1290687e83958e665b3324504Adam Cohen sStaticValuesDirty = true; 193099f60d51f6310e1290687e83958e665b3324504Adam Cohen return super.onSaveInstanceState(); 194099f60d51f6310e1290687e83958e665b3324504Adam Cohen } 195099f60d51f6310e1290687e83958e665b3324504Adam Cohen 196f05545fcc2df05518731f8d7ff048d797fe776d5Anjali Koppal public Folder getFolder() { 197fb91f303f5e672f9b4c4f9f8a03486b224d60cd6Adam Cohen return mFolder; 198fb91f303f5e672f9b4c4f9f8a03486b224d60cd6Adam Cohen } 199fb91f303f5e672f9b4c4f9f8a03486b224d60cd6Adam Cohen 2004f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen private void setFolder(Folder folder) { 2014f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen mFolder = folder; 2024f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen updateItemDrawingParams(false); 2034f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen } 2044f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen 205f9c184a619e4e4b82cf9e0bf318ca6d8deaaaee7Adam Cohen public FolderInfo getFolderInfo() { 206fb91f303f5e672f9b4c4f9f8a03486b224d60cd6Adam Cohen return mInfo; 207fb91f303f5e672f9b4c4f9f8a03486b224d60cd6Adam Cohen } 208fb91f303f5e672f9b4c4f9f8a03486b224d60cd6Adam Cohen 209073a46ff635d089cbcb15d939d1de42dd2b86c97Adam Cohen private boolean willAcceptItem(ItemInfo item) { 21031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project final int itemType = item.itemType; 2112801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen return ((itemType == LauncherSettings.Favorites.ITEM_TYPE_APPLICATION || 212bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham itemType == LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT || 213bfbf7f9f4a0b300613f0ff27a4eb592d88c08325Tony Wickham itemType == LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT) && 214c51934bfdfed6a5011c6d6c5b7b70f2d75613d41Adam Cohen !mFolder.isFull() && item != mInfo && !mInfo.opened); 215073a46ff635d089cbcb15d939d1de42dd2b86c97Adam Cohen } 216073a46ff635d089cbcb15d939d1de42dd2b86c97Adam Cohen 217aa8ef119f18864f4ab41c12f9c2ad6d7f643a0a9Sunny Goyal public boolean acceptDrop(ItemInfo dragInfo) { 218aa8ef119f18864f4ab41c12f9c2ad6d7f643a0a9Sunny Goyal final ItemInfo item = dragInfo; 219fb91f303f5e672f9b4c4f9f8a03486b224d60cd6Adam Cohen return !mFolder.isDestroyed() && willAcceptItem(item); 22031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 22131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 222df0353815c629fc678824b07a234b89a1ff94208Adam Cohen public void addItem(ShortcutInfo item) { 223c52ba710053e4c6927937dd1a26d1abe06b6fa99Sunny Goyal mInfo.add(item, true); 224df0353815c629fc678824b07a234b89a1ff94208Adam Cohen } 225df0353815c629fc678824b07a234b89a1ff94208Adam Cohen 226aa8ef119f18864f4ab41c12f9c2ad6d7f643a0a9Sunny Goyal public void onDragEnter(ItemInfo dragInfo) { 227aa8ef119f18864f4ab41c12f9c2ad6d7f643a0a9Sunny Goyal if (mFolder.isDestroyed() || !willAcceptItem(dragInfo)) return; 22869ce2e5beaa1a57c7b8fa14a2d6ff0b3abeb93c0Adam Cohen CellLayout.LayoutParams lp = (CellLayout.LayoutParams) getLayoutParams(); 229efca0279eb927faebffc38c8382818df67fcd159Adam Cohen CellLayout cl = (CellLayout) getParent().getParent(); 230efca0279eb927faebffc38c8382818df67fcd159Adam Cohen 231efca0279eb927faebffc38c8382818df67fcd159Adam Cohen mBackground.animateToAccept(cl, lp.cellX, lp.cellY); 23255bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi mOpenAlarm.setOnAlarmListener(mOnOpenListener); 233dedfca2aef7573624bdb421b1805ef5e04bee502Adam Cohen if (SPRING_LOADING_ENABLED && 234dedfca2aef7573624bdb421b1805ef5e04bee502Adam Cohen ((dragInfo instanceof AppInfo) || (dragInfo instanceof ShortcutInfo))) { 235dedfca2aef7573624bdb421b1805ef5e04bee502Adam Cohen // TODO: we currently don't support spring-loading for PendingAddShortcutInfos even 236dedfca2aef7573624bdb421b1805ef5e04bee502Adam Cohen // though widget-style shortcuts can be added to folders. The issue is that we need 237dedfca2aef7573624bdb421b1805ef5e04bee502Adam Cohen // to deal with configuration activities which are currently handled in 238dedfca2aef7573624bdb421b1805ef5e04bee502Adam Cohen // Workspace#onDropExternal. 23955bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi mOpenAlarm.setAlarm(ON_OPEN_DELAY); 24055bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi } 241073a46ff635d089cbcb15d939d1de42dd2b86c97Adam Cohen } 242073a46ff635d089cbcb15d939d1de42dd2b86c97Adam Cohen 24355bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi OnAlarmListener mOnOpenListener = new OnAlarmListener() { 24455bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi public void onAlarm(Alarm alarm) { 245e393d3af369c452f3b5f5d9c0a23a83aa3aa736bSunny Goyal mFolder.beginExternalDrag(); 24637b2a496ebd6a985c210abaa6ca745a860f5f9d2Adam Cohen mLauncher.openFolder(FolderIcon.this); 24755bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi } 24855bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi }; 24955bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi 2508f288aac99a11d52fd9747f360a8ce3bb521b17aWinson public Drawable prepareCreate(final View destView) { 2518f288aac99a11d52fd9747f360a8ce3bb521b17aWinson Drawable animateDrawable = getTopDrawable((TextView) destView); 2528f288aac99a11d52fd9747f360a8ce3bb521b17aWinson computePreviewDrawingParams(animateDrawable.getIntrinsicWidth(), 2538f288aac99a11d52fd9747f360a8ce3bb521b17aWinson destView.getMeasuredWidth()); 2548f288aac99a11d52fd9747f360a8ce3bb521b17aWinson return animateDrawable; 2558f288aac99a11d52fd9747f360a8ce3bb521b17aWinson } 2568f288aac99a11d52fd9747f360a8ce3bb521b17aWinson 257d044526d82e7938cf35b296978d9d5302f98b4afAdam Cohen public void performCreateAnimation(final ShortcutInfo destInfo, final View destView, 2587bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung final ShortcutInfo srcInfo, final DragView srcView, Rect dstRect, 259ac8c87687b8e063c981f28cb31bab2cc110f26ccAdam Cohen float scaleRelativeToDragLayer, Runnable postAnimationRunnable) { 260d044526d82e7938cf35b296978d9d5302f98b4afAdam Cohen 261fb91f303f5e672f9b4c4f9f8a03486b224d60cd6Adam Cohen // These correspond two the drawable and view that the icon was dropped _onto_ 2628f288aac99a11d52fd9747f360a8ce3bb521b17aWinson Drawable animateDrawable = prepareCreate(destView); 263fb91f303f5e672f9b4c4f9f8a03486b224d60cd6Adam Cohen 2644f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen mReferenceDrawable = animateDrawable; 2654f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen 2664f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen addItem(destInfo); 267fb91f303f5e672f9b4c4f9f8a03486b224d60cd6Adam Cohen // This will animate the first item from it's position as an icon into its 268fb91f303f5e672f9b4c4f9f8a03486b224d60cd6Adam Cohen // position as the first item in the preview 269fb91f303f5e672f9b4c4f9f8a03486b224d60cd6Adam Cohen animateFirstItem(animateDrawable, INITIAL_ITEM_ANIMATION_DURATION, false, null); 270ac8c87687b8e063c981f28cb31bab2cc110f26ccAdam Cohen 271d044526d82e7938cf35b296978d9d5302f98b4afAdam Cohen // This will animate the dragView (srcView) into the new folder 272e393d3af369c452f3b5f5d9c0a23a83aa3aa736bSunny Goyal onDrop(srcInfo, srcView, dstRect, scaleRelativeToDragLayer, 1, postAnimationRunnable); 273fb91f303f5e672f9b4c4f9f8a03486b224d60cd6Adam Cohen } 274fb91f303f5e672f9b4c4f9f8a03486b224d60cd6Adam Cohen 275fb91f303f5e672f9b4c4f9f8a03486b224d60cd6Adam Cohen public void performDestroyAnimation(final View finalView, Runnable onCompleteRunnable) { 27695abbb330ce9bbaf23594245f0f8a795c8118038Sunny Goyal Drawable animateDrawable = getTopDrawable((TextView) finalView); 27702dd7aea3d8ac94126a8f8069e6762592ea60326Jason Monk computePreviewDrawingParams(animateDrawable.getIntrinsicWidth(), 278fb91f303f5e672f9b4c4f9f8a03486b224d60cd6Adam Cohen finalView.getMeasuredWidth()); 279d044526d82e7938cf35b296978d9d5302f98b4afAdam Cohen 280d044526d82e7938cf35b296978d9d5302f98b4afAdam Cohen // This will animate the first item from it's position as an icon into its 281d044526d82e7938cf35b296978d9d5302f98b4afAdam Cohen // position as the first item in the preview 282fb91f303f5e672f9b4c4f9f8a03486b224d60cd6Adam Cohen animateFirstItem(animateDrawable, FINAL_ITEM_ANIMATION_DURATION, true, 283fb91f303f5e672f9b4c4f9f8a03486b224d60cd6Adam Cohen onCompleteRunnable); 284d044526d82e7938cf35b296978d9d5302f98b4afAdam Cohen } 285d044526d82e7938cf35b296978d9d5302f98b4afAdam Cohen 286c6cc61d45836e4081920883cc4d448ccb0bb8417Adam Cohen public void onDragExit() { 287efca0279eb927faebffc38c8382818df67fcd159Adam Cohen mBackground.animateToRest(); 28855bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi mOpenAlarm.cancelAlarm(); 289073a46ff635d089cbcb15d939d1de42dd2b86c97Adam Cohen } 290073a46ff635d089cbcb15d939d1de42dd2b86c97Adam Cohen 2917bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung private void onDrop(final ShortcutInfo item, DragView animateView, Rect finalRect, 292e393d3af369c452f3b5f5d9c0a23a83aa3aa736bSunny Goyal float scaleRelativeToDragLayer, int index, Runnable postAnimationRunnable) { 293d044526d82e7938cf35b296978d9d5302f98b4afAdam Cohen item.cellX = -1; 294d044526d82e7938cf35b296978d9d5302f98b4afAdam Cohen item.cellY = -1; 295d044526d82e7938cf35b296978d9d5302f98b4afAdam Cohen 296558baaf0a0b1c6a9062a6771088098533a35222bAdam Cohen // Typically, the animateView corresponds to the DragView; however, if this is being done 297558baaf0a0b1c6a9062a6771088098533a35222bAdam Cohen // after a configuration activity (ie. for a Shortcut being dragged from AllApps) we 298558baaf0a0b1c6a9062a6771088098533a35222bAdam Cohen // will not have a view to animate 299558baaf0a0b1c6a9062a6771088098533a35222bAdam Cohen if (animateView != null) { 300558baaf0a0b1c6a9062a6771088098533a35222bAdam Cohen DragLayer dragLayer = mLauncher.getDragLayer(); 301558baaf0a0b1c6a9062a6771088098533a35222bAdam Cohen Rect from = new Rect(); 302558baaf0a0b1c6a9062a6771088098533a35222bAdam Cohen dragLayer.getViewRectRelativeToSelf(animateView, from); 303558baaf0a0b1c6a9062a6771088098533a35222bAdam Cohen Rect to = finalRect; 304558baaf0a0b1c6a9062a6771088098533a35222bAdam Cohen if (to == null) { 305558baaf0a0b1c6a9062a6771088098533a35222bAdam Cohen to = new Rect(); 306558baaf0a0b1c6a9062a6771088098533a35222bAdam Cohen Workspace workspace = mLauncher.getWorkspace(); 307558baaf0a0b1c6a9062a6771088098533a35222bAdam Cohen // Set cellLayout and this to it's final state to compute final animation locations 308558baaf0a0b1c6a9062a6771088098533a35222bAdam Cohen workspace.setFinalTransitionTransform((CellLayout) getParent().getParent()); 309558baaf0a0b1c6a9062a6771088098533a35222bAdam Cohen float scaleX = getScaleX(); 310558baaf0a0b1c6a9062a6771088098533a35222bAdam Cohen float scaleY = getScaleY(); 311558baaf0a0b1c6a9062a6771088098533a35222bAdam Cohen setScaleX(1.0f); 312558baaf0a0b1c6a9062a6771088098533a35222bAdam Cohen setScaleY(1.0f); 313558baaf0a0b1c6a9062a6771088098533a35222bAdam Cohen scaleRelativeToDragLayer = dragLayer.getDescendantRectRelativeToSelf(this, to); 314558baaf0a0b1c6a9062a6771088098533a35222bAdam Cohen // Finished computing final animation locations, restore current state 315558baaf0a0b1c6a9062a6771088098533a35222bAdam Cohen setScaleX(scaleX); 316558baaf0a0b1c6a9062a6771088098533a35222bAdam Cohen setScaleY(scaleY); 317558baaf0a0b1c6a9062a6771088098533a35222bAdam Cohen workspace.resetTransitionTransform((CellLayout) getParent().getParent()); 318558baaf0a0b1c6a9062a6771088098533a35222bAdam Cohen } 319ac8c87687b8e063c981f28cb31bab2cc110f26ccAdam Cohen 320558baaf0a0b1c6a9062a6771088098533a35222bAdam Cohen int[] center = new int[2]; 321119e8982ab6a0cf00e31e8744f27b72ba8bf7b20Adam Cohen float scale = getLocalCenterForIndex(index, index + 1, center); 322558baaf0a0b1c6a9062a6771088098533a35222bAdam Cohen center[0] = (int) Math.round(scaleRelativeToDragLayer * center[0]); 323558baaf0a0b1c6a9062a6771088098533a35222bAdam Cohen center[1] = (int) Math.round(scaleRelativeToDragLayer * center[1]); 324d044526d82e7938cf35b296978d9d5302f98b4afAdam Cohen 325558baaf0a0b1c6a9062a6771088098533a35222bAdam Cohen to.offset(center[0] - animateView.getMeasuredWidth() / 2, 3265f8afe6280eae34620067696173e71943e1a30a3Winson Chung center[1] - animateView.getMeasuredHeight() / 2); 327d044526d82e7938cf35b296978d9d5302f98b4afAdam Cohen 328f9c184a619e4e4b82cf9e0bf318ca6d8deaaaee7Adam Cohen float finalAlpha = index < mPreviewLayoutRule.numItems() ? 0.5f : 0f; 329558baaf0a0b1c6a9062a6771088098533a35222bAdam Cohen 330ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen float finalScale = scale * scaleRelativeToDragLayer; 331558baaf0a0b1c6a9062a6771088098533a35222bAdam Cohen dragLayer.animateView(animateView, from, to, finalAlpha, 332ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen 1, 1, finalScale, finalScale, DROP_IN_ANIMATION_DURATION, 333558baaf0a0b1c6a9062a6771088098533a35222bAdam Cohen new DecelerateInterpolator(2), new AccelerateInterpolator(2), 334ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen postAnimationRunnable, DragLayer.ANIMATION_END_DISAPPEAR, null); 335fb91f303f5e672f9b4c4f9f8a03486b224d60cd6Adam Cohen addItem(item); 3367a8b82b5926e6a520df28e7f591b9a94ec605581Adam Cohen mFolder.hideItem(item); 3374f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen 3384f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen final PreviewItemDrawingParams params = index < mDrawingParams.size() ? 3394f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen mDrawingParams.get(index) : null; 3404f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen if (params != null) params.hidden = true; 341558baaf0a0b1c6a9062a6771088098533a35222bAdam Cohen postDelayed(new Runnable() { 342558baaf0a0b1c6a9062a6771088098533a35222bAdam Cohen public void run() { 3434f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen if (params != null) params.hidden = false; 3447a8b82b5926e6a520df28e7f591b9a94ec605581Adam Cohen mFolder.showItem(item); 345fb91f303f5e672f9b4c4f9f8a03486b224d60cd6Adam Cohen invalidate(); 346558baaf0a0b1c6a9062a6771088098533a35222bAdam Cohen } 347558baaf0a0b1c6a9062a6771088098533a35222bAdam Cohen }, DROP_IN_ANIMATION_DURATION); 348558baaf0a0b1c6a9062a6771088098533a35222bAdam Cohen } else { 349558baaf0a0b1c6a9062a6771088098533a35222bAdam Cohen addItem(item); 350558baaf0a0b1c6a9062a6771088098533a35222bAdam Cohen } 351d044526d82e7938cf35b296978d9d5302f98b4afAdam Cohen } 352d044526d82e7938cf35b296978d9d5302f98b4afAdam Cohen 3533e8f811f31a2275e778244427271f77f4116c08bAdam Cohen public void onDrop(DragObject d) { 354c0dcf597084d00e4c23a7fea5fd0738f6c095a6bAdam Cohen ShortcutInfo item; 355eadbfc564d84aaf1d800da3d0d6edf6312f89648Michael Jurka if (d.dragInfo instanceof AppInfo) { 356c0dcf597084d00e4c23a7fea5fd0738f6c095a6bAdam Cohen // Came from all apps -- make a copy 357eadbfc564d84aaf1d800da3d0d6edf6312f89648Michael Jurka item = ((AppInfo) d.dragInfo).makeShortcut(); 358c0dcf597084d00e4c23a7fea5fd0738f6c095a6bAdam Cohen } else { 3593e8f811f31a2275e778244427271f77f4116c08bAdam Cohen item = (ShortcutInfo) d.dragInfo; 360c0dcf597084d00e4c23a7fea5fd0738f6c095a6bAdam Cohen } 36167bd9ccf856840856944815a382e4bbb0e71e949Adam Cohen mFolder.notifyDrop(); 362e393d3af369c452f3b5f5d9c0a23a83aa3aa736bSunny Goyal onDrop(item, d.dragView, null, 1.0f, mInfo.contents.size(), d.postAnimationRunnable); 363c0dcf597084d00e4c23a7fea5fd0738f6c095a6bAdam Cohen } 364c0dcf597084d00e4c23a7fea5fd0738f6c095a6bAdam Cohen 365d044526d82e7938cf35b296978d9d5302f98b4afAdam Cohen private void computePreviewDrawingParams(int drawableSize, int totalSize) { 366aa2542a461072a57058ce45946ff6f5552ecce8aAdam Cohen if (mIntrinsicIconSize != drawableSize || mTotalWidth != totalSize || 367aa2542a461072a57058ce45946ff6f5552ecce8aAdam Cohen mPrevTopPadding != getPaddingTop()) { 3682e6da1539bc7286336b3c24d96ab76434939ce4dAdam Cohen DeviceProfile grid = mLauncher.getDeviceProfile(); 3695f8afe6280eae34620067696173e71943e1a30a3Winson Chung 370d044526d82e7938cf35b296978d9d5302f98b4afAdam Cohen mIntrinsicIconSize = drawableSize; 371d044526d82e7938cf35b296978d9d5302f98b4afAdam Cohen mTotalWidth = totalSize; 372aa2542a461072a57058ce45946ff6f5552ecce8aAdam Cohen mPrevTopPadding = getPaddingTop(); 37376fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen 374efca0279eb927faebffc38c8382818df67fcd159Adam Cohen mBackground.setup(getResources().getDisplayMetrics(), grid, this, mTotalWidth, 375efca0279eb927faebffc38c8382818df67fcd159Adam Cohen getPaddingTop()); 376efca0279eb927faebffc38c8382818df67fcd159Adam Cohen mPreviewLayoutRule.init(mBackground.previewSize, mIntrinsicIconSize, 377119e8982ab6a0cf00e31e8744f27b72ba8bf7b20Adam Cohen Utilities.isRtl(getResources())); 378efca0279eb927faebffc38c8382818df67fcd159Adam Cohen 3794f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen updateItemDrawingParams(false); 380073a46ff635d089cbcb15d939d1de42dd2b86c97Adam Cohen } 381d044526d82e7938cf35b296978d9d5302f98b4afAdam Cohen } 38276fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen 383d044526d82e7938cf35b296978d9d5302f98b4afAdam Cohen private void computePreviewDrawingParams(Drawable d) { 384d044526d82e7938cf35b296978d9d5302f98b4afAdam Cohen computePreviewDrawingParams(d.getIntrinsicWidth(), getMeasuredWidth()); 385d044526d82e7938cf35b296978d9d5302f98b4afAdam Cohen } 386073a46ff635d089cbcb15d939d1de42dd2b86c97Adam Cohen 387261194387beebaa7927ec4e310274218b651494dSunny Goyal static class PreviewItemDrawingParams { 388261194387beebaa7927ec4e310274218b651494dSunny Goyal PreviewItemDrawingParams(float transX, float transY, float scale, float overlayAlpha) { 389d044526d82e7938cf35b296978d9d5302f98b4afAdam Cohen this.transX = transX; 390d044526d82e7938cf35b296978d9d5302f98b4afAdam Cohen this.transY = transY; 391d044526d82e7938cf35b296978d9d5302f98b4afAdam Cohen this.scale = scale; 392d044526d82e7938cf35b296978d9d5302f98b4afAdam Cohen this.overlayAlpha = overlayAlpha; 393d044526d82e7938cf35b296978d9d5302f98b4afAdam Cohen } 3944f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen 3954f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen public void update(float transX, float transY, float scale) { 3964f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen // We ensure the update will not interfere with an animation on the layout params 3974f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen // If the final values differ, we cancel the animation. 3984f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen if (anim != null) { 3994f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen if (anim.finalTransX == transX || anim.finalTransY == transY 4004f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen || anim.finalScale == scale) { 4014f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen return; 4024f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen } 4034f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen anim.cancel(); 4044f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen } 4054f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen 4064f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen this.transX = transX; 4074f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen this.transY = transY; 4084f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen this.scale = scale; 4094f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen } 4104f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen 411261194387beebaa7927ec4e310274218b651494dSunny Goyal float transX; 412261194387beebaa7927ec4e310274218b651494dSunny Goyal float transY; 413261194387beebaa7927ec4e310274218b651494dSunny Goyal float scale; 4144f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen public float overlayAlpha; 4154f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen boolean hidden; 4164f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen FolderPreviewItemAnim anim; 417261194387beebaa7927ec4e310274218b651494dSunny Goyal Drawable drawable; 418d044526d82e7938cf35b296978d9d5302f98b4afAdam Cohen } 419badf71e11fba2d6efa1d1bcca9542001f90a3777Adam Cohen 420119e8982ab6a0cf00e31e8744f27b72ba8bf7b20Adam Cohen private float getLocalCenterForIndex(int index, int curNumItems, int[] center) { 4214f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen mTmpParams = computePreviewItemDrawingParams(Math.min(mPreviewLayoutRule.numItems(), index), 4224f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen curNumItems, mTmpParams); 423a9cf38f533d1e86269868f1e6a806ccffd4a78fcAdam Cohen 424efca0279eb927faebffc38c8382818df67fcd159Adam Cohen mTmpParams.transX += mBackground.basePreviewOffsetX; 425efca0279eb927faebffc38c8382818df67fcd159Adam Cohen mTmpParams.transY += mBackground.basePreviewOffsetY; 4264f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen float offsetX = mTmpParams.transX + (mTmpParams.scale * mIntrinsicIconSize) / 2; 4274f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen float offsetY = mTmpParams.transY + (mTmpParams.scale * mIntrinsicIconSize) / 2; 428badf71e11fba2d6efa1d1bcca9542001f90a3777Adam Cohen 429ac8c87687b8e063c981f28cb31bab2cc110f26ccAdam Cohen center[0] = (int) Math.round(offsetX); 430ac8c87687b8e063c981f28cb31bab2cc110f26ccAdam Cohen center[1] = (int) Math.round(offsetY); 4314f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen return mTmpParams.scale; 432d044526d82e7938cf35b296978d9d5302f98b4afAdam Cohen } 433badf71e11fba2d6efa1d1bcca9542001f90a3777Adam Cohen 434119e8982ab6a0cf00e31e8744f27b72ba8bf7b20Adam Cohen private PreviewItemDrawingParams computePreviewItemDrawingParams(int index, int curNumItems, 435d044526d82e7938cf35b296978d9d5302f98b4afAdam Cohen PreviewItemDrawingParams params) { 4364f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen // We use an index of -1 to represent an icon on the workspace for the destroy and 4374f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen // create animations 4384f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen if (index == -1) { 4394f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen return getFinalIconParams(params); 4404f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen } 441119e8982ab6a0cf00e31e8744f27b72ba8bf7b20Adam Cohen return mPreviewLayoutRule.computePreviewItemDrawingParams(index, curNumItems, params); 442d044526d82e7938cf35b296978d9d5302f98b4afAdam Cohen } 443badf71e11fba2d6efa1d1bcca9542001f90a3777Adam Cohen 4444f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen private PreviewItemDrawingParams getFinalIconParams(PreviewItemDrawingParams params) { 4454f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen float iconSize = mLauncher.getDeviceProfile().iconSizePx; 4464f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen 4474f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen final float scale = iconSize / mReferenceDrawable.getIntrinsicWidth(); 448efca0279eb927faebffc38c8382818df67fcd159Adam Cohen final float trans = (mBackground.previewSize - iconSize) / 2; 4494f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen 4504f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen params.update(trans, trans, scale); 4514f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen return params; 4524f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen } 4534f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen 454d044526d82e7938cf35b296978d9d5302f98b4afAdam Cohen private void drawPreviewItem(Canvas canvas, PreviewItemDrawingParams params) { 455d044526d82e7938cf35b296978d9d5302f98b4afAdam Cohen canvas.save(); 456119e8982ab6a0cf00e31e8744f27b72ba8bf7b20Adam Cohen canvas.translate(params.transX, params.transY); 457d044526d82e7938cf35b296978d9d5302f98b4afAdam Cohen canvas.scale(params.scale, params.scale); 458d044526d82e7938cf35b296978d9d5302f98b4afAdam Cohen Drawable d = params.drawable; 459d044526d82e7938cf35b296978d9d5302f98b4afAdam Cohen 460d044526d82e7938cf35b296978d9d5302f98b4afAdam Cohen if (d != null) { 461d4e53c882494f8cd7e4c0d44dbfc300d3610afcfWinson Chung mOldBounds.set(d.getBounds()); 462d044526d82e7938cf35b296978d9d5302f98b4afAdam Cohen d.setBounds(0, 0, mIntrinsicIconSize, mIntrinsicIconSize); 463c5c60ad3592f53549c9ffaa58e9a87b0480080e8Sunny Goyal if (d instanceof FastBitmapDrawable) { 464c5c60ad3592f53549c9ffaa58e9a87b0480080e8Sunny Goyal FastBitmapDrawable fd = (FastBitmapDrawable) d; 465c088049113c261331b5685e64050d14a31cd72dfWinson float oldBrightness = fd.getBrightness(); 466508da15509224b46fcccabbe78f3e92fe69a67d8Sunny Goyal fd.setBrightness(params.overlayAlpha); 467c5c60ad3592f53549c9ffaa58e9a87b0480080e8Sunny Goyal d.draw(canvas); 468508da15509224b46fcccabbe78f3e92fe69a67d8Sunny Goyal fd.setBrightness(oldBrightness); 469c5c60ad3592f53549c9ffaa58e9a87b0480080e8Sunny Goyal } else { 470c088049113c261331b5685e64050d14a31cd72dfWinson d.setColorFilter(Color.argb((int) (params.overlayAlpha * 255), 255, 255, 255), 471c5c60ad3592f53549c9ffaa58e9a87b0480080e8Sunny Goyal PorterDuff.Mode.SRC_ATOP); 472c5c60ad3592f53549c9ffaa58e9a87b0480080e8Sunny Goyal d.draw(canvas); 473c5c60ad3592f53549c9ffaa58e9a87b0480080e8Sunny Goyal d.clearColorFilter(); 474c5c60ad3592f53549c9ffaa58e9a87b0480080e8Sunny Goyal } 475d4e53c882494f8cd7e4c0d44dbfc300d3610afcfWinson Chung d.setBounds(mOldBounds); 476d044526d82e7938cf35b296978d9d5302f98b4afAdam Cohen } 477d044526d82e7938cf35b296978d9d5302f98b4afAdam Cohen canvas.restore(); 478d044526d82e7938cf35b296978d9d5302f98b4afAdam Cohen } 47976fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen 480f172b747c24f28e29baaaf58f08bab48847b7a40Adam Cohen /** 481f172b747c24f28e29baaaf58f08bab48847b7a40Adam Cohen * This object represents a FolderIcon preview background. It stores drawing / measurement 482f172b747c24f28e29baaaf58f08bab48847b7a40Adam Cohen * information, handles drawing, and animation (accept state <--> rest state). 483f172b747c24f28e29baaaf58f08bab48847b7a40Adam Cohen */ 484efca0279eb927faebffc38c8382818df67fcd159Adam Cohen public static class PreviewBackground { 485efca0279eb927faebffc38c8382818df67fcd159Adam Cohen private float mScale = 1f; 486efca0279eb927faebffc38c8382818df67fcd159Adam Cohen private float mColorMultiplier = 1f; 487efca0279eb927faebffc38c8382818df67fcd159Adam Cohen private Path mClipPath = new Path(); 488efca0279eb927faebffc38c8382818df67fcd159Adam Cohen private int mStrokeWidth; 489f172b747c24f28e29baaaf58f08bab48847b7a40Adam Cohen private View mInvalidateDelegate; 490efca0279eb927faebffc38c8382818df67fcd159Adam Cohen 491efca0279eb927faebffc38c8382818df67fcd159Adam Cohen public int previewSize; 492efca0279eb927faebffc38c8382818df67fcd159Adam Cohen private int basePreviewOffsetX; 493efca0279eb927faebffc38c8382818df67fcd159Adam Cohen private int basePreviewOffsetY; 494efca0279eb927faebffc38c8382818df67fcd159Adam Cohen 495efca0279eb927faebffc38c8382818df67fcd159Adam Cohen private CellLayout mDrawingDelegate; 496efca0279eb927faebffc38c8382818df67fcd159Adam Cohen public int delegateCellX; 497efca0279eb927faebffc38c8382818df67fcd159Adam Cohen public int delegateCellY; 498efca0279eb927faebffc38c8382818df67fcd159Adam Cohen 499f172b747c24f28e29baaaf58f08bab48847b7a40Adam Cohen // When the PreviewBackground is drawn under an icon (for creating a folder) the border 500f172b747c24f28e29baaaf58f08bab48847b7a40Adam Cohen // should not occlude the icon 501f172b747c24f28e29baaaf58f08bab48847b7a40Adam Cohen public boolean isClipping = true; 502f172b747c24f28e29baaaf58f08bab48847b7a40Adam Cohen 503efca0279eb927faebffc38c8382818df67fcd159Adam Cohen // Drawing / animation configurations 504efca0279eb927faebffc38c8382818df67fcd159Adam Cohen private static final float ACCEPT_SCALE_FACTOR = 1.25f; 505efca0279eb927faebffc38c8382818df67fcd159Adam Cohen private static final float ACCEPT_COLOR_MULTIPLIER = 1.5f; 506efca0279eb927faebffc38c8382818df67fcd159Adam Cohen 507efca0279eb927faebffc38c8382818df67fcd159Adam Cohen // Expressed on a scale from 0 to 255. 508efca0279eb927faebffc38c8382818df67fcd159Adam Cohen private static final int BG_OPACITY = 160; 509efca0279eb927faebffc38c8382818df67fcd159Adam Cohen private static final int MAX_BG_OPACITY = 225; 510efca0279eb927faebffc38c8382818df67fcd159Adam Cohen private static final int BG_INTENSITY = 245; 511efca0279eb927faebffc38c8382818df67fcd159Adam Cohen private static final int SHADOW_OPACITY = 80; 512efca0279eb927faebffc38c8382818df67fcd159Adam Cohen 513efca0279eb927faebffc38c8382818df67fcd159Adam Cohen ValueAnimator mScaleAnimator; 514efca0279eb927faebffc38c8382818df67fcd159Adam Cohen 515f172b747c24f28e29baaaf58f08bab48847b7a40Adam Cohen public void setup(DisplayMetrics dm, DeviceProfile grid, View invalidateDelegate, 516efca0279eb927faebffc38c8382818df67fcd159Adam Cohen int availableSpace, int topPadding) { 517f172b747c24f28e29baaaf58f08bab48847b7a40Adam Cohen mInvalidateDelegate = invalidateDelegate; 518efca0279eb927faebffc38c8382818df67fcd159Adam Cohen 519efca0279eb927faebffc38c8382818df67fcd159Adam Cohen final int previewSize = grid.folderIconSizePx; 520efca0279eb927faebffc38c8382818df67fcd159Adam Cohen final int previewPadding = grid.folderIconPreviewPadding; 521efca0279eb927faebffc38c8382818df67fcd159Adam Cohen 522efca0279eb927faebffc38c8382818df67fcd159Adam Cohen this.previewSize = (previewSize - 2 * previewPadding); 523efca0279eb927faebffc38c8382818df67fcd159Adam Cohen 524efca0279eb927faebffc38c8382818df67fcd159Adam Cohen basePreviewOffsetX = (availableSpace - this.previewSize) / 2; 525efca0279eb927faebffc38c8382818df67fcd159Adam Cohen basePreviewOffsetY = previewPadding + grid.folderBackgroundOffset + topPadding; 526efca0279eb927faebffc38c8382818df67fcd159Adam Cohen 527efca0279eb927faebffc38c8382818df67fcd159Adam Cohen mStrokeWidth = Utilities.pxFromDp(1, dm); 528efca0279eb927faebffc38c8382818df67fcd159Adam Cohen 529efca0279eb927faebffc38c8382818df67fcd159Adam Cohen invalidate(); 530efca0279eb927faebffc38c8382818df67fcd159Adam Cohen } 531efca0279eb927faebffc38c8382818df67fcd159Adam Cohen 532efca0279eb927faebffc38c8382818df67fcd159Adam Cohen int getRadius() { 533efca0279eb927faebffc38c8382818df67fcd159Adam Cohen return previewSize / 2; 534efca0279eb927faebffc38c8382818df67fcd159Adam Cohen } 535efca0279eb927faebffc38c8382818df67fcd159Adam Cohen 536efca0279eb927faebffc38c8382818df67fcd159Adam Cohen int getScaledRadius() { 537efca0279eb927faebffc38c8382818df67fcd159Adam Cohen return (int) (mScale * getRadius()); 538efca0279eb927faebffc38c8382818df67fcd159Adam Cohen } 539efca0279eb927faebffc38c8382818df67fcd159Adam Cohen 540efca0279eb927faebffc38c8382818df67fcd159Adam Cohen int getOffsetX() { 541efca0279eb927faebffc38c8382818df67fcd159Adam Cohen return basePreviewOffsetX - (getScaledRadius() - getRadius()); 542efca0279eb927faebffc38c8382818df67fcd159Adam Cohen } 543efca0279eb927faebffc38c8382818df67fcd159Adam Cohen 544efca0279eb927faebffc38c8382818df67fcd159Adam Cohen int getOffsetY() { 545efca0279eb927faebffc38c8382818df67fcd159Adam Cohen return basePreviewOffsetY - (getScaledRadius() - getRadius()); 546efca0279eb927faebffc38c8382818df67fcd159Adam Cohen } 547efca0279eb927faebffc38c8382818df67fcd159Adam Cohen 548efca0279eb927faebffc38c8382818df67fcd159Adam Cohen void invalidate() { 549efca0279eb927faebffc38c8382818df67fcd159Adam Cohen int radius = getScaledRadius(); 550efca0279eb927faebffc38c8382818df67fcd159Adam Cohen mClipPath.reset(); 551efca0279eb927faebffc38c8382818df67fcd159Adam Cohen mClipPath.addCircle(radius, radius, radius, Path.Direction.CW); 552efca0279eb927faebffc38c8382818df67fcd159Adam Cohen 553f172b747c24f28e29baaaf58f08bab48847b7a40Adam Cohen if (mInvalidateDelegate != null) { 554f172b747c24f28e29baaaf58f08bab48847b7a40Adam Cohen mInvalidateDelegate.invalidate(); 555efca0279eb927faebffc38c8382818df67fcd159Adam Cohen } 556efca0279eb927faebffc38c8382818df67fcd159Adam Cohen 557efca0279eb927faebffc38c8382818df67fcd159Adam Cohen if (mDrawingDelegate != null) { 558efca0279eb927faebffc38c8382818df67fcd159Adam Cohen mDrawingDelegate.invalidate(); 559efca0279eb927faebffc38c8382818df67fcd159Adam Cohen } 560efca0279eb927faebffc38c8382818df67fcd159Adam Cohen } 561efca0279eb927faebffc38c8382818df67fcd159Adam Cohen 562f172b747c24f28e29baaaf58f08bab48847b7a40Adam Cohen void setInvalidateDelegate(View invalidateDelegate) { 563f172b747c24f28e29baaaf58f08bab48847b7a40Adam Cohen mInvalidateDelegate = invalidateDelegate; 564efca0279eb927faebffc38c8382818df67fcd159Adam Cohen invalidate(); 565efca0279eb927faebffc38c8382818df67fcd159Adam Cohen } 566efca0279eb927faebffc38c8382818df67fcd159Adam Cohen 567efca0279eb927faebffc38c8382818df67fcd159Adam Cohen public void drawBackground(Canvas canvas, Paint paint) { 568efca0279eb927faebffc38c8382818df67fcd159Adam Cohen canvas.save(); 569efca0279eb927faebffc38c8382818df67fcd159Adam Cohen canvas.translate(getOffsetX(), getOffsetY()); 570efca0279eb927faebffc38c8382818df67fcd159Adam Cohen 571efca0279eb927faebffc38c8382818df67fcd159Adam Cohen paint.reset(); 572efca0279eb927faebffc38c8382818df67fcd159Adam Cohen paint.setStyle(Paint.Style.FILL); 573efca0279eb927faebffc38c8382818df67fcd159Adam Cohen paint.setXfermode(null); 574efca0279eb927faebffc38c8382818df67fcd159Adam Cohen paint.setAntiAlias(true); 575efca0279eb927faebffc38c8382818df67fcd159Adam Cohen 576efca0279eb927faebffc38c8382818df67fcd159Adam Cohen int alpha = (int) Math.min(MAX_BG_OPACITY, BG_OPACITY * mColorMultiplier); 577efca0279eb927faebffc38c8382818df67fcd159Adam Cohen paint.setColor(Color.argb(alpha, BG_INTENSITY, BG_INTENSITY, BG_INTENSITY)); 578efca0279eb927faebffc38c8382818df67fcd159Adam Cohen 579efca0279eb927faebffc38c8382818df67fcd159Adam Cohen float radius = getScaledRadius(); 580efca0279eb927faebffc38c8382818df67fcd159Adam Cohen 581efca0279eb927faebffc38c8382818df67fcd159Adam Cohen canvas.drawCircle(radius, radius, radius, paint); 582efca0279eb927faebffc38c8382818df67fcd159Adam Cohen canvas.clipPath(mClipPath, Region.Op.DIFFERENCE); 583efca0279eb927faebffc38c8382818df67fcd159Adam Cohen 584efca0279eb927faebffc38c8382818df67fcd159Adam Cohen paint.setStyle(Paint.Style.STROKE); 585efca0279eb927faebffc38c8382818df67fcd159Adam Cohen paint.setColor(Color.TRANSPARENT); 586efca0279eb927faebffc38c8382818df67fcd159Adam Cohen paint.setShadowLayer(mStrokeWidth, 0, mStrokeWidth, Color.argb(SHADOW_OPACITY, 0, 0, 0)); 587efca0279eb927faebffc38c8382818df67fcd159Adam Cohen canvas.drawCircle(radius, radius, radius, paint); 588efca0279eb927faebffc38c8382818df67fcd159Adam Cohen 589efca0279eb927faebffc38c8382818df67fcd159Adam Cohen canvas.restore(); 590efca0279eb927faebffc38c8382818df67fcd159Adam Cohen } 591efca0279eb927faebffc38c8382818df67fcd159Adam Cohen 592efca0279eb927faebffc38c8382818df67fcd159Adam Cohen public void drawBackgroundStroke(Canvas canvas, Paint paint) { 593efca0279eb927faebffc38c8382818df67fcd159Adam Cohen canvas.save(); 594efca0279eb927faebffc38c8382818df67fcd159Adam Cohen canvas.translate(getOffsetX(), getOffsetY()); 595efca0279eb927faebffc38c8382818df67fcd159Adam Cohen 596efca0279eb927faebffc38c8382818df67fcd159Adam Cohen paint.reset(); 597efca0279eb927faebffc38c8382818df67fcd159Adam Cohen paint.setAntiAlias(true); 598efca0279eb927faebffc38c8382818df67fcd159Adam Cohen paint.setColor(Color.argb(255, BG_INTENSITY, BG_INTENSITY, BG_INTENSITY)); 599efca0279eb927faebffc38c8382818df67fcd159Adam Cohen paint.setStyle(Paint.Style.STROKE); 600efca0279eb927faebffc38c8382818df67fcd159Adam Cohen paint.setStrokeWidth(mStrokeWidth); 601efca0279eb927faebffc38c8382818df67fcd159Adam Cohen 602efca0279eb927faebffc38c8382818df67fcd159Adam Cohen float radius = getScaledRadius(); 603efca0279eb927faebffc38c8382818df67fcd159Adam Cohen canvas.drawCircle(radius, radius, radius - 1, paint); 604efca0279eb927faebffc38c8382818df67fcd159Adam Cohen 605efca0279eb927faebffc38c8382818df67fcd159Adam Cohen canvas.restore(); 606efca0279eb927faebffc38c8382818df67fcd159Adam Cohen } 607efca0279eb927faebffc38c8382818df67fcd159Adam Cohen 608efca0279eb927faebffc38c8382818df67fcd159Adam Cohen public void drawLeaveBehind(Canvas canvas, Paint paint) { 609efca0279eb927faebffc38c8382818df67fcd159Adam Cohen float originalScale = mScale; 610efca0279eb927faebffc38c8382818df67fcd159Adam Cohen mScale = 0.5f; 611efca0279eb927faebffc38c8382818df67fcd159Adam Cohen 612efca0279eb927faebffc38c8382818df67fcd159Adam Cohen canvas.save(); 613efca0279eb927faebffc38c8382818df67fcd159Adam Cohen canvas.translate(getOffsetX(), getOffsetY()); 614efca0279eb927faebffc38c8382818df67fcd159Adam Cohen 615efca0279eb927faebffc38c8382818df67fcd159Adam Cohen paint.reset(); 616efca0279eb927faebffc38c8382818df67fcd159Adam Cohen paint.setAntiAlias(true); 617efca0279eb927faebffc38c8382818df67fcd159Adam Cohen paint.setColor(Color.argb(160, 245, 245, 245)); 618efca0279eb927faebffc38c8382818df67fcd159Adam Cohen 619efca0279eb927faebffc38c8382818df67fcd159Adam Cohen float radius = getScaledRadius(); 620efca0279eb927faebffc38c8382818df67fcd159Adam Cohen canvas.drawCircle(radius, radius, radius, paint); 621efca0279eb927faebffc38c8382818df67fcd159Adam Cohen 622efca0279eb927faebffc38c8382818df67fcd159Adam Cohen canvas.restore(); 623efca0279eb927faebffc38c8382818df67fcd159Adam Cohen mScale = originalScale; 624efca0279eb927faebffc38c8382818df67fcd159Adam Cohen } 625efca0279eb927faebffc38c8382818df67fcd159Adam Cohen 626efca0279eb927faebffc38c8382818df67fcd159Adam Cohen // It is the callers responsibility to save and restore the canvas. 627efca0279eb927faebffc38c8382818df67fcd159Adam Cohen private void clipCanvas(Canvas canvas) { 628efca0279eb927faebffc38c8382818df67fcd159Adam Cohen canvas.translate(getOffsetX(), getOffsetY()); 629efca0279eb927faebffc38c8382818df67fcd159Adam Cohen canvas.clipPath(mClipPath); 630efca0279eb927faebffc38c8382818df67fcd159Adam Cohen canvas.translate(-getOffsetX(), -getOffsetY()); 631efca0279eb927faebffc38c8382818df67fcd159Adam Cohen } 632efca0279eb927faebffc38c8382818df67fcd159Adam Cohen 633efca0279eb927faebffc38c8382818df67fcd159Adam Cohen private void delegateDrawing(CellLayout delegate, int cellX, int cellY) { 634efca0279eb927faebffc38c8382818df67fcd159Adam Cohen if (mDrawingDelegate != delegate) { 635efca0279eb927faebffc38c8382818df67fcd159Adam Cohen delegate.addFolderBackground(this); 636efca0279eb927faebffc38c8382818df67fcd159Adam Cohen } 637efca0279eb927faebffc38c8382818df67fcd159Adam Cohen 638efca0279eb927faebffc38c8382818df67fcd159Adam Cohen mDrawingDelegate = delegate; 639efca0279eb927faebffc38c8382818df67fcd159Adam Cohen delegateCellX = cellX; 640efca0279eb927faebffc38c8382818df67fcd159Adam Cohen delegateCellY = cellY; 641efca0279eb927faebffc38c8382818df67fcd159Adam Cohen 642efca0279eb927faebffc38c8382818df67fcd159Adam Cohen invalidate(); 643efca0279eb927faebffc38c8382818df67fcd159Adam Cohen } 644efca0279eb927faebffc38c8382818df67fcd159Adam Cohen 645efca0279eb927faebffc38c8382818df67fcd159Adam Cohen private void clearDrawingDelegate() { 646efca0279eb927faebffc38c8382818df67fcd159Adam Cohen if (mDrawingDelegate != null) { 647efca0279eb927faebffc38c8382818df67fcd159Adam Cohen mDrawingDelegate.removeFolderBackground(this); 648efca0279eb927faebffc38c8382818df67fcd159Adam Cohen } 649efca0279eb927faebffc38c8382818df67fcd159Adam Cohen 650efca0279eb927faebffc38c8382818df67fcd159Adam Cohen mDrawingDelegate = null; 651efca0279eb927faebffc38c8382818df67fcd159Adam Cohen invalidate(); 652efca0279eb927faebffc38c8382818df67fcd159Adam Cohen } 653efca0279eb927faebffc38c8382818df67fcd159Adam Cohen 654efca0279eb927faebffc38c8382818df67fcd159Adam Cohen private boolean drawingDelegated() { 655efca0279eb927faebffc38c8382818df67fcd159Adam Cohen return mDrawingDelegate != null; 656efca0279eb927faebffc38c8382818df67fcd159Adam Cohen } 657efca0279eb927faebffc38c8382818df67fcd159Adam Cohen 658efca0279eb927faebffc38c8382818df67fcd159Adam Cohen private void animateScale(float finalScale, float finalMultiplier, 659efca0279eb927faebffc38c8382818df67fcd159Adam Cohen final Runnable onStart, final Runnable onEnd) { 660efca0279eb927faebffc38c8382818df67fcd159Adam Cohen final float scale0 = mScale; 661efca0279eb927faebffc38c8382818df67fcd159Adam Cohen final float scale1 = finalScale; 662efca0279eb927faebffc38c8382818df67fcd159Adam Cohen 663efca0279eb927faebffc38c8382818df67fcd159Adam Cohen final float bgMultiplier0 = mColorMultiplier; 664efca0279eb927faebffc38c8382818df67fcd159Adam Cohen final float bgMultiplier1 = finalMultiplier; 665efca0279eb927faebffc38c8382818df67fcd159Adam Cohen 666efca0279eb927faebffc38c8382818df67fcd159Adam Cohen if (mScaleAnimator != null) { 667efca0279eb927faebffc38c8382818df67fcd159Adam Cohen mScaleAnimator.cancel(); 668efca0279eb927faebffc38c8382818df67fcd159Adam Cohen } 669efca0279eb927faebffc38c8382818df67fcd159Adam Cohen 670efca0279eb927faebffc38c8382818df67fcd159Adam Cohen mScaleAnimator = LauncherAnimUtils.ofFloat(null, 0f, 1.0f); 671efca0279eb927faebffc38c8382818df67fcd159Adam Cohen 672efca0279eb927faebffc38c8382818df67fcd159Adam Cohen mScaleAnimator.addUpdateListener(new AnimatorUpdateListener() { 673efca0279eb927faebffc38c8382818df67fcd159Adam Cohen @Override 674efca0279eb927faebffc38c8382818df67fcd159Adam Cohen public void onAnimationUpdate(ValueAnimator animation) { 675efca0279eb927faebffc38c8382818df67fcd159Adam Cohen float prog = animation.getAnimatedFraction(); 676efca0279eb927faebffc38c8382818df67fcd159Adam Cohen mScale = prog * scale1 + (1 - prog) * scale0; 677efca0279eb927faebffc38c8382818df67fcd159Adam Cohen mColorMultiplier = prog * bgMultiplier1 + (1 - prog) * bgMultiplier0; 678efca0279eb927faebffc38c8382818df67fcd159Adam Cohen invalidate(); 679efca0279eb927faebffc38c8382818df67fcd159Adam Cohen } 680efca0279eb927faebffc38c8382818df67fcd159Adam Cohen }); 681efca0279eb927faebffc38c8382818df67fcd159Adam Cohen mScaleAnimator.addListener(new AnimatorListenerAdapter() { 682efca0279eb927faebffc38c8382818df67fcd159Adam Cohen @Override 683efca0279eb927faebffc38c8382818df67fcd159Adam Cohen public void onAnimationStart(Animator animation) { 684efca0279eb927faebffc38c8382818df67fcd159Adam Cohen if (onStart != null) { 685efca0279eb927faebffc38c8382818df67fcd159Adam Cohen onStart.run(); 686efca0279eb927faebffc38c8382818df67fcd159Adam Cohen } 687efca0279eb927faebffc38c8382818df67fcd159Adam Cohen } 688efca0279eb927faebffc38c8382818df67fcd159Adam Cohen 689efca0279eb927faebffc38c8382818df67fcd159Adam Cohen @Override 690efca0279eb927faebffc38c8382818df67fcd159Adam Cohen public void onAnimationEnd(Animator animation) { 691efca0279eb927faebffc38c8382818df67fcd159Adam Cohen if (onEnd != null) { 692efca0279eb927faebffc38c8382818df67fcd159Adam Cohen onEnd.run(); 693efca0279eb927faebffc38c8382818df67fcd159Adam Cohen } 694efca0279eb927faebffc38c8382818df67fcd159Adam Cohen mScaleAnimator = null; 695efca0279eb927faebffc38c8382818df67fcd159Adam Cohen } 696efca0279eb927faebffc38c8382818df67fcd159Adam Cohen }); 697efca0279eb927faebffc38c8382818df67fcd159Adam Cohen 698efca0279eb927faebffc38c8382818df67fcd159Adam Cohen mScaleAnimator.setDuration(CONSUMPTION_ANIMATION_DURATION); 699efca0279eb927faebffc38c8382818df67fcd159Adam Cohen mScaleAnimator.start(); 700efca0279eb927faebffc38c8382818df67fcd159Adam Cohen } 701efca0279eb927faebffc38c8382818df67fcd159Adam Cohen 702efca0279eb927faebffc38c8382818df67fcd159Adam Cohen public void animateToAccept(final CellLayout cl, final int cellX, final int cellY) { 703efca0279eb927faebffc38c8382818df67fcd159Adam Cohen Runnable onStart = new Runnable() { 704efca0279eb927faebffc38c8382818df67fcd159Adam Cohen @Override 705efca0279eb927faebffc38c8382818df67fcd159Adam Cohen public void run() { 706efca0279eb927faebffc38c8382818df67fcd159Adam Cohen delegateDrawing(cl, cellX, cellY); 707efca0279eb927faebffc38c8382818df67fcd159Adam Cohen } 708efca0279eb927faebffc38c8382818df67fcd159Adam Cohen }; 709efca0279eb927faebffc38c8382818df67fcd159Adam Cohen animateScale(ACCEPT_SCALE_FACTOR, ACCEPT_COLOR_MULTIPLIER, onStart, null); 710efca0279eb927faebffc38c8382818df67fcd159Adam Cohen } 711efca0279eb927faebffc38c8382818df67fcd159Adam Cohen 712efca0279eb927faebffc38c8382818df67fcd159Adam Cohen public void animateToRest() { 713efca0279eb927faebffc38c8382818df67fcd159Adam Cohen // This can be called multiple times -- we need to make sure the drawing delegate 714efca0279eb927faebffc38c8382818df67fcd159Adam Cohen // is saved and restored at the beginning of the animation, since cancelling the 715efca0279eb927faebffc38c8382818df67fcd159Adam Cohen // existing animation can clear the delgate. 716efca0279eb927faebffc38c8382818df67fcd159Adam Cohen final CellLayout cl = mDrawingDelegate; 717efca0279eb927faebffc38c8382818df67fcd159Adam Cohen final int cellX = delegateCellX; 718efca0279eb927faebffc38c8382818df67fcd159Adam Cohen final int cellY = delegateCellY; 719efca0279eb927faebffc38c8382818df67fcd159Adam Cohen 720efca0279eb927faebffc38c8382818df67fcd159Adam Cohen Runnable onStart = new Runnable() { 721efca0279eb927faebffc38c8382818df67fcd159Adam Cohen @Override 722efca0279eb927faebffc38c8382818df67fcd159Adam Cohen public void run() { 723efca0279eb927faebffc38c8382818df67fcd159Adam Cohen delegateDrawing(cl, cellX, cellY); 724efca0279eb927faebffc38c8382818df67fcd159Adam Cohen } 725efca0279eb927faebffc38c8382818df67fcd159Adam Cohen }; 726efca0279eb927faebffc38c8382818df67fcd159Adam Cohen Runnable onEnd = new Runnable() { 727efca0279eb927faebffc38c8382818df67fcd159Adam Cohen @Override 728efca0279eb927faebffc38c8382818df67fcd159Adam Cohen public void run() { 729efca0279eb927faebffc38c8382818df67fcd159Adam Cohen clearDrawingDelegate(); 730efca0279eb927faebffc38c8382818df67fcd159Adam Cohen } 731efca0279eb927faebffc38c8382818df67fcd159Adam Cohen }; 732efca0279eb927faebffc38c8382818df67fcd159Adam Cohen animateScale(1f, 1f, onStart, onEnd); 733efca0279eb927faebffc38c8382818df67fcd159Adam Cohen } 734efca0279eb927faebffc38c8382818df67fcd159Adam Cohen } 735efca0279eb927faebffc38c8382818df67fcd159Adam Cohen 736efca0279eb927faebffc38c8382818df67fcd159Adam Cohen public void setFolderBackground(PreviewBackground bg) { 737efca0279eb927faebffc38c8382818df67fcd159Adam Cohen mBackground = bg; 738f172b747c24f28e29baaaf58f08bab48847b7a40Adam Cohen mBackground.setInvalidateDelegate(this); 739efca0279eb927faebffc38c8382818df67fcd159Adam Cohen } 740efca0279eb927faebffc38c8382818df67fcd159Adam Cohen 741d044526d82e7938cf35b296978d9d5302f98b4afAdam Cohen @Override 742d044526d82e7938cf35b296978d9d5302f98b4afAdam Cohen protected void dispatchDraw(Canvas canvas) { 743d044526d82e7938cf35b296978d9d5302f98b4afAdam Cohen super.dispatchDraw(canvas); 744badf71e11fba2d6efa1d1bcca9542001f90a3777Adam Cohen 7454f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen if (mReferenceDrawable != null) { 7464f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen computePreviewDrawingParams(mReferenceDrawable); 747d044526d82e7938cf35b296978d9d5302f98b4afAdam Cohen } 748a9cf38f533d1e86269868f1e6a806ccffd4a78fcAdam Cohen 749efca0279eb927faebffc38c8382818df67fcd159Adam Cohen if (!mBackground.drawingDelegated()) { 750efca0279eb927faebffc38c8382818df67fcd159Adam Cohen mBackground.drawBackground(canvas, mBgPaint); 751efca0279eb927faebffc38c8382818df67fcd159Adam Cohen } 752efca0279eb927faebffc38c8382818df67fcd159Adam Cohen 753efca0279eb927faebffc38c8382818df67fcd159Adam Cohen if (mFolder == null) return; 754efca0279eb927faebffc38c8382818df67fcd159Adam Cohen if (mFolder.getItemCount() == 0 && !mAnimating) return; 755efca0279eb927faebffc38c8382818df67fcd159Adam Cohen 756119e8982ab6a0cf00e31e8744f27b72ba8bf7b20Adam Cohen canvas.save(); 757efca0279eb927faebffc38c8382818df67fcd159Adam Cohen 758efca0279eb927faebffc38c8382818df67fcd159Adam Cohen 759efca0279eb927faebffc38c8382818df67fcd159Adam Cohen if (mPreviewLayoutRule.clipToBackground()) { 760efca0279eb927faebffc38c8382818df67fcd159Adam Cohen mBackground.clipCanvas(canvas); 761119e8982ab6a0cf00e31e8744f27b72ba8bf7b20Adam Cohen } 762119e8982ab6a0cf00e31e8744f27b72ba8bf7b20Adam Cohen 763efca0279eb927faebffc38c8382818df67fcd159Adam Cohen // The items are drawn in coordinates relative to the preview offset 764efca0279eb927faebffc38c8382818df67fcd159Adam Cohen canvas.translate(mBackground.basePreviewOffsetX, mBackground.basePreviewOffsetY); 765efca0279eb927faebffc38c8382818df67fcd159Adam Cohen 7664f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen // The first item should be drawn last (ie. on top of later items) 7674f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen for (int i = mDrawingParams.size() - 1; i >= 0; i--) { 7684f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen PreviewItemDrawingParams p = mDrawingParams.get(i); 7694f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen if (!p.hidden) { 7704f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen drawPreviewItem(canvas, p); 771a9cf38f533d1e86269868f1e6a806ccffd4a78fcAdam Cohen } 772a9cf38f533d1e86269868f1e6a806ccffd4a78fcAdam Cohen } 773119e8982ab6a0cf00e31e8744f27b72ba8bf7b20Adam Cohen canvas.restore(); 774efca0279eb927faebffc38c8382818df67fcd159Adam Cohen 775efca0279eb927faebffc38c8382818df67fcd159Adam Cohen if (mPreviewLayoutRule.clipToBackground() && !mBackground.drawingDelegated()) { 776efca0279eb927faebffc38c8382818df67fcd159Adam Cohen mBackground.drawBackgroundStroke(canvas, mBgPaint); 777efca0279eb927faebffc38c8382818df67fcd159Adam Cohen } 778d044526d82e7938cf35b296978d9d5302f98b4afAdam Cohen } 779d044526d82e7938cf35b296978d9d5302f98b4afAdam Cohen 7803484638cad97e255a412b0489a63873fb3ca4218Sunny Goyal private Drawable getTopDrawable(TextView v) { 7813484638cad97e255a412b0489a63873fb3ca4218Sunny Goyal Drawable d = v.getCompoundDrawables()[1]; 7823484638cad97e255a412b0489a63873fb3ca4218Sunny Goyal return (d instanceof PreloadIconDrawable) ? ((PreloadIconDrawable) d).mIcon : d; 7833484638cad97e255a412b0489a63873fb3ca4218Sunny Goyal } 7843484638cad97e255a412b0489a63873fb3ca4218Sunny Goyal 7854f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen class FolderPreviewItemAnim { 7864f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen ValueAnimator mValueAnimator; 7874f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen float finalScale; 7884f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen float finalTransX; 7894f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen float finalTransY; 7904f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen 7914f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen /** 7924f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen * 7934f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen * @param params layout params to animate 7944f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen * @param index0 original index of the item to be animated 7954f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen * @param nItems0 original number of items in the preview 7964f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen * @param index1 new index of the item to be animated 7974f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen * @param nItems1 new number of items in the preview 7984f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen * @param duration duration in ms of the animation 7994f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen * @param onCompleteRunnable runnable to execute upon animation completion 8004f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen */ 8014f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen public FolderPreviewItemAnim(final PreviewItemDrawingParams params, int index0, int nItems0, 8024f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen int index1, int nItems1, int duration, final Runnable onCompleteRunnable) { 8034f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen 8044f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen computePreviewItemDrawingParams(index1, nItems1, mTmpParams); 8054f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen 8064f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen finalScale = mTmpParams.scale; 8074f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen finalTransX = mTmpParams.transX; 8084f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen finalTransY = mTmpParams.transY; 8094f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen 8104f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen computePreviewItemDrawingParams(index0, nItems0, mTmpParams); 8114f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen 8124f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen final float scale0 = mTmpParams.scale; 8134f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen final float transX0 = mTmpParams.transX; 8144f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen final float transY0 = mTmpParams.transY; 8154f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen 8164f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen mValueAnimator = LauncherAnimUtils.ofFloat(FolderIcon.this, 0f, 1.0f); 8174f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen mValueAnimator.addUpdateListener(new AnimatorUpdateListener(){ 8184f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen public void onAnimationUpdate(ValueAnimator animation) { 8194f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen float progress = animation.getAnimatedFraction(); 820119e8982ab6a0cf00e31e8744f27b72ba8bf7b20Adam Cohen 8214f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen params.transX = transX0 + progress * (finalTransX - transX0); 8224f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen params.transY = transY0 + progress * (finalTransY - transY0); 8234f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen params.scale = scale0 + progress * (finalScale - scale0); 8244f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen invalidate(); 8254f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen } 8264f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen }); 827d044526d82e7938cf35b296978d9d5302f98b4afAdam Cohen 8284f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen mValueAnimator.addListener(new AnimatorListenerAdapter() { 8294f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen @Override 8304f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen public void onAnimationStart(Animator animation) { 831fb91f303f5e672f9b4c4f9f8a03486b224d60cd6Adam Cohen } 832d044526d82e7938cf35b296978d9d5302f98b4afAdam Cohen 8334f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen @Override 8344f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen public void onAnimationEnd(Animator animation) { 8354f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen if (onCompleteRunnable != null) { 8364f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen onCompleteRunnable.run(); 8374f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen } 8384f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen params.anim = null; 839fb91f303f5e672f9b4c4f9f8a03486b224d60cd6Adam Cohen } 8404f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen }); 8414f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen mValueAnimator.setDuration(duration); 8424f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen } 8434f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen 8444f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen public void start() { 8454f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen mValueAnimator.start(); 8464f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen } 8474f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen 8484f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen public void cancel() { 8494f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen mValueAnimator.cancel(); 8504f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen } 8514f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen 8524f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen public boolean hasEqualFinalState(FolderPreviewItemAnim anim) { 8534f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen return finalTransY == anim.finalTransY && finalTransX == anim.finalTransX && 8544f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen finalScale == anim.finalScale; 8554f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen 8564f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen } 8574f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen } 8584f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen 8594f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen private void animateFirstItem(final Drawable d, int duration, final boolean reverse, 8604f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen final Runnable onCompleteRunnable) { 8614f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen 8624f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen FolderPreviewItemAnim anim; 8634f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen if (!reverse) { 8644f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen anim = new FolderPreviewItemAnim(mDrawingParams.get(0), -1, -1, 0, 2, duration, 8654f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen onCompleteRunnable); 8664f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen } else { 8674f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen anim = new FolderPreviewItemAnim(mDrawingParams.get(0), 0, 2, -1, -1, duration, 8684f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen onCompleteRunnable); 8694f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen } 8704f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen anim.start(); 871a9cf38f533d1e86269868f1e6a806ccffd4a78fcAdam Cohen } 872a9cf38f533d1e86269868f1e6a806ccffd4a78fcAdam Cohen 873099f60d51f6310e1290687e83958e665b3324504Adam Cohen public void setTextVisible(boolean visible) { 874099f60d51f6310e1290687e83958e665b3324504Adam Cohen if (visible) { 875099f60d51f6310e1290687e83958e665b3324504Adam Cohen mFolderName.setVisibility(VISIBLE); 876099f60d51f6310e1290687e83958e665b3324504Adam Cohen } else { 877099f60d51f6310e1290687e83958e665b3324504Adam Cohen mFolderName.setVisibility(INVISIBLE); 878099f60d51f6310e1290687e83958e665b3324504Adam Cohen } 879099f60d51f6310e1290687e83958e665b3324504Adam Cohen } 880099f60d51f6310e1290687e83958e665b3324504Adam Cohen 881099f60d51f6310e1290687e83958e665b3324504Adam Cohen public boolean getTextVisible() { 882099f60d51f6310e1290687e83958e665b3324504Adam Cohen return mFolderName.getVisibility() == VISIBLE; 883099f60d51f6310e1290687e83958e665b3324504Adam Cohen } 884099f60d51f6310e1290687e83958e665b3324504Adam Cohen 8854f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen private void updateItemDrawingParams(boolean animate) { 8864f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen ArrayList<View> items = mFolder.getItemsInReadingOrder(); 8874f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen int nItemsInPreview = Math.min(items.size(), mPreviewLayoutRule.numItems()); 8884f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen 8894f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen int prevNumItems = mDrawingParams.size(); 8904f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen 8914f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen // We adjust the size of the list to match the number of items in the preview 8924f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen while (nItemsInPreview < mDrawingParams.size()) { 8934f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen mDrawingParams.remove(mDrawingParams.size() - 1); 8944f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen } 8954f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen while (nItemsInPreview > mDrawingParams.size()) { 8964f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen mDrawingParams.add(new PreviewItemDrawingParams(0, 0, 0, 0)); 8974f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen } 8984f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen 8994f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen for (int i = 0; i < mDrawingParams.size(); i++) { 9004f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen PreviewItemDrawingParams p = mDrawingParams.get(i); 9014f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen p.drawable = getTopDrawable((TextView) items.get(i)); 9024f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen 903efca0279eb927faebffc38c8382818df67fcd159Adam Cohen if (!animate || FeatureFlags.LAUNCHER3_LEGACY_FOLDER_ICON) { 9044f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen computePreviewItemDrawingParams(i, nItemsInPreview, p); 9054f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen if (mReferenceDrawable == null) { 9064f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen mReferenceDrawable = p.drawable; 9074f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen } 9084f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen } else { 9094f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen FolderPreviewItemAnim anim = new FolderPreviewItemAnim(p, i, prevNumItems, i, 9104f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen nItemsInPreview, DROP_IN_ANIMATION_DURATION, null); 9114f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen 9124f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen if (p.anim != null) { 9134f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen if (p.anim.hasEqualFinalState(anim)) { 9144f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen // do nothing, let the current animation finish 9154f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen continue; 9164f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen } 9174f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen p.anim.cancel(); 9184f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen } 9194f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen p.anim = anim; 9204f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen p.anim.start(); 9214f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen } 9224f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen } 9234f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen } 9244f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen 925c52ba710053e4c6927937dd1a26d1abe06b6fa99Sunny Goyal @Override 926c52ba710053e4c6927937dd1a26d1abe06b6fa99Sunny Goyal public void onItemsChanged(boolean animate) { 927c52ba710053e4c6927937dd1a26d1abe06b6fa99Sunny Goyal updateItemDrawingParams(animate); 92876078c4ef35b6e95fb6d8129a32cf52a36625e28Adam Cohen invalidate(); 92976078c4ef35b6e95fb6d8129a32cf52a36625e28Adam Cohen requestLayout(); 93076078c4ef35b6e95fb6d8129a32cf52a36625e28Adam Cohen } 93176078c4ef35b6e95fb6d8129a32cf52a36625e28Adam Cohen 932a9cf38f533d1e86269868f1e6a806ccffd4a78fcAdam Cohen public void onAdd(ShortcutInfo item) { 933a9cf38f533d1e86269868f1e6a806ccffd4a78fcAdam Cohen invalidate(); 934a9cf38f533d1e86269868f1e6a806ccffd4a78fcAdam Cohen requestLayout(); 935a9cf38f533d1e86269868f1e6a806ccffd4a78fcAdam Cohen } 936a9cf38f533d1e86269868f1e6a806ccffd4a78fcAdam Cohen 937a9cf38f533d1e86269868f1e6a806ccffd4a78fcAdam Cohen public void onRemove(ShortcutInfo item) { 938a9cf38f533d1e86269868f1e6a806ccffd4a78fcAdam Cohen invalidate(); 939a9cf38f533d1e86269868f1e6a806ccffd4a78fcAdam Cohen requestLayout(); 940a9cf38f533d1e86269868f1e6a806ccffd4a78fcAdam Cohen } 94176fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen 94276fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen public void onTitleChanged(CharSequence title) { 94382b016cb56540fe26213e817dd0dd668099c8e20Winson Chung mFolderName.setText(title); 944f4f89ef608245d39bbddda05f291361d2ae06667Sunny Goyal setContentDescription(getContext().getString(R.string.folder_name_format, title)); 94576fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen } 94688f334571fe41df620ba903ced9b2c69b0170d5cWinson Chung 94788f334571fe41df620ba903ced9b2c69b0170d5cWinson Chung @Override 94888f334571fe41df620ba903ced9b2c69b0170d5cWinson Chung public boolean onTouchEvent(MotionEvent event) { 94988f334571fe41df620ba903ced9b2c69b0170d5cWinson Chung // Call the superclass onTouchEvent first, because sometimes it changes the state to 95088f334571fe41df620ba903ced9b2c69b0170d5cWinson Chung // isPressed() on an ACTION_UP 95188f334571fe41df620ba903ced9b2c69b0170d5cWinson Chung boolean result = super.onTouchEvent(event); 95288f334571fe41df620ba903ced9b2c69b0170d5cWinson Chung 953ef044dd380ac3abf354027750efdc16d5d48ac70Mady Mellor // Check for a stylus button press, if it occurs cancel any long press checks. 954bb83520a620919a8f19472ba4426585d007d1abaMady Mellor if (mStylusEventHelper.onMotionEvent(event)) { 955ef044dd380ac3abf354027750efdc16d5d48ac70Mady Mellor mLongPressHelper.cancelLongPress(); 956ef044dd380ac3abf354027750efdc16d5d48ac70Mady Mellor return true; 957ef044dd380ac3abf354027750efdc16d5d48ac70Mady Mellor } 958ef044dd380ac3abf354027750efdc16d5d48ac70Mady Mellor 95988f334571fe41df620ba903ced9b2c69b0170d5cWinson Chung switch (event.getAction()) { 96088f334571fe41df620ba903ced9b2c69b0170d5cWinson Chung case MotionEvent.ACTION_DOWN: 96188f334571fe41df620ba903ced9b2c69b0170d5cWinson Chung mLongPressHelper.postCheckForLongPress(); 96288f334571fe41df620ba903ced9b2c69b0170d5cWinson Chung break; 96388f334571fe41df620ba903ced9b2c69b0170d5cWinson Chung case MotionEvent.ACTION_CANCEL: 96488f334571fe41df620ba903ced9b2c69b0170d5cWinson Chung case MotionEvent.ACTION_UP: 96588f334571fe41df620ba903ced9b2c69b0170d5cWinson Chung mLongPressHelper.cancelLongPress(); 96688f334571fe41df620ba903ced9b2c69b0170d5cWinson Chung break; 96702dd7aea3d8ac94126a8f8069e6762592ea60326Jason Monk case MotionEvent.ACTION_MOVE: 96802dd7aea3d8ac94126a8f8069e6762592ea60326Jason Monk if (!Utilities.pointInView(this, event.getX(), event.getY(), mSlop)) { 96902dd7aea3d8ac94126a8f8069e6762592ea60326Jason Monk mLongPressHelper.cancelLongPress(); 97002dd7aea3d8ac94126a8f8069e6762592ea60326Jason Monk } 97102dd7aea3d8ac94126a8f8069e6762592ea60326Jason Monk break; 97288f334571fe41df620ba903ced9b2c69b0170d5cWinson Chung } 97388f334571fe41df620ba903ced9b2c69b0170d5cWinson Chung return result; 97488f334571fe41df620ba903ced9b2c69b0170d5cWinson Chung } 97588f334571fe41df620ba903ced9b2c69b0170d5cWinson Chung 97688f334571fe41df620ba903ced9b2c69b0170d5cWinson Chung @Override 97702dd7aea3d8ac94126a8f8069e6762592ea60326Jason Monk protected void onAttachedToWindow() { 97802dd7aea3d8ac94126a8f8069e6762592ea60326Jason Monk super.onAttachedToWindow(); 97902dd7aea3d8ac94126a8f8069e6762592ea60326Jason Monk mSlop = ViewConfiguration.get(getContext()).getScaledTouchSlop(); 98002dd7aea3d8ac94126a8f8069e6762592ea60326Jason Monk } 98102dd7aea3d8ac94126a8f8069e6762592ea60326Jason Monk 98202dd7aea3d8ac94126a8f8069e6762592ea60326Jason Monk @Override 98388f334571fe41df620ba903ced9b2c69b0170d5cWinson Chung public void cancelLongPress() { 98488f334571fe41df620ba903ced9b2c69b0170d5cWinson Chung super.cancelLongPress(); 98588f334571fe41df620ba903ced9b2c69b0170d5cWinson Chung mLongPressHelper.cancelLongPress(); 98688f334571fe41df620ba903ced9b2c69b0170d5cWinson Chung } 987f9c184a619e4e4b82cf9e0bf318ca6d8deaaaee7Adam Cohen 988aaf7d1d13bd88bdeac5c56a9ab1d293fdaea3c11Sunny Goyal public void removeListeners() { 989aaf7d1d13bd88bdeac5c56a9ab1d293fdaea3c11Sunny Goyal mInfo.removeListener(this); 990aaf7d1d13bd88bdeac5c56a9ab1d293fdaea3c11Sunny Goyal mInfo.removeListener(mFolder); 991aaf7d1d13bd88bdeac5c56a9ab1d293fdaea3c11Sunny Goyal } 992aaf7d1d13bd88bdeac5c56a9ab1d293fdaea3c11Sunny Goyal 993f9c184a619e4e4b82cf9e0bf318ca6d8deaaaee7Adam Cohen public interface PreviewLayoutRule { 994119e8982ab6a0cf00e31e8744f27b72ba8bf7b20Adam Cohen public PreviewItemDrawingParams computePreviewItemDrawingParams(int index, int curNumItems, 995f9c184a619e4e4b82cf9e0bf318ca6d8deaaaee7Adam Cohen PreviewItemDrawingParams params); 996f9c184a619e4e4b82cf9e0bf318ca6d8deaaaee7Adam Cohen 997119e8982ab6a0cf00e31e8744f27b72ba8bf7b20Adam Cohen public void init(int availableSpace, int intrinsicIconSize, boolean rtl); 998f9c184a619e4e4b82cf9e0bf318ca6d8deaaaee7Adam Cohen 999f9c184a619e4e4b82cf9e0bf318ca6d8deaaaee7Adam Cohen public int numItems(); 1000efca0279eb927faebffc38c8382818df67fcd159Adam Cohen public boolean clipToBackground(); 1001f9c184a619e4e4b82cf9e0bf318ca6d8deaaaee7Adam Cohen } 100231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project} 1003