FolderIcon.java revision f172b747c24f28e29baaaf58f08bab48847b7a40
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(); 128f9c184a619e4e4b82cf9e0bf318ca6d8deaaaee7Adam Cohen @Thunk 129f9c184a619e4e4b82cf9e0bf318ca6d8deaaaee7Adam Cohen ItemInfo mDragInfo; 13055bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi 13131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project public FolderIcon(Context context, AttributeSet attrs) { 13231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project super(context, attrs); 13388f334571fe41df620ba903ced9b2c69b0170d5cWinson Chung init(); 13431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 13531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 13631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project public FolderIcon(Context context) { 13731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project super(context); 13888f334571fe41df620ba903ced9b2c69b0170d5cWinson Chung init(); 13988f334571fe41df620ba903ced9b2c69b0170d5cWinson Chung } 14088f334571fe41df620ba903ced9b2c69b0170d5cWinson Chung 14188f334571fe41df620ba903ced9b2c69b0170d5cWinson Chung private void init() { 14288f334571fe41df620ba903ced9b2c69b0170d5cWinson Chung mLongPressHelper = new CheckLongPressHelper(this); 143bb83520a620919a8f19472ba4426585d007d1abaMady Mellor mStylusEventHelper = new StylusEventHelper(new SimpleOnStylusPressListener(this), this); 144efca0279eb927faebffc38c8382818df67fcd159Adam Cohen mPreviewLayoutRule = FeatureFlags.LAUNCHER3_LEGACY_FOLDER_ICON ? 145efca0279eb927faebffc38c8382818df67fcd159Adam Cohen new StackFolderIconLayoutRule() : 146efca0279eb927faebffc38c8382818df67fcd159Adam Cohen new ClippedFolderIconLayoutRule(); 14731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 148efca0279eb927faebffc38c8382818df67fcd159Adam Cohen setAccessibilityDelegate(LauncherAppState.getInstance().getAccessibilityDelegate()); 1490280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka } 1500280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka 151f9c184a619e4e4b82cf9e0bf318ca6d8deaaaee7Adam Cohen public static FolderIcon fromXml(int resId, Launcher launcher, ViewGroup group, 152df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen FolderInfo folderInfo, IconCache iconCache) { 1533a9fcedbcd235372cd2ab64f825a0b5b3937f59eMichael Jurka @SuppressWarnings("all") // suppress dead code warning 1543a9fcedbcd235372cd2ab64f825a0b5b3937f59eMichael Jurka final boolean error = INITIAL_ITEM_ANIMATION_DURATION >= DROP_IN_ANIMATION_DURATION; 1553a9fcedbcd235372cd2ab64f825a0b5b3937f59eMichael Jurka if (error) { 156d044526d82e7938cf35b296978d9d5302f98b4afAdam Cohen throw new IllegalStateException("DROP_IN_ANIMATION_DURATION must be greater than " + 157d044526d82e7938cf35b296978d9d5302f98b4afAdam Cohen "INITIAL_ITEM_ANIMATION_DURATION, as sequencing of adding first two items " + 158d044526d82e7938cf35b296978d9d5302f98b4afAdam Cohen "is dependent on this"); 159d044526d82e7938cf35b296978d9d5302f98b4afAdam Cohen } 1602e6da1539bc7286336b3c24d96ab76434939ce4dAdam Cohen 1612e6da1539bc7286336b3c24d96ab76434939ce4dAdam Cohen DeviceProfile grid = launcher.getDeviceProfile(); 16231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project FolderIcon icon = (FolderIcon) LayoutInflater.from(launcher).inflate(resId, group, false); 163efca0279eb927faebffc38c8382818df67fcd159Adam Cohen 164efca0279eb927faebffc38c8382818df67fcd159Adam Cohen // For performance and compatibility reasons we render the preview using a software layer. 165efca0279eb927faebffc38c8382818df67fcd159Adam Cohen // In particular, hardware path clipping has spotty ecosystem support and bad performance. 166efca0279eb927faebffc38c8382818df67fcd159Adam Cohen // Software rendering also allows us to use shadow layers. 167efca0279eb927faebffc38c8382818df67fcd159Adam Cohen icon.setLayerType(LAYER_TYPE_SOFTWARE, new Paint(Paint.FILTER_BITMAP_FLAG)); 168efca0279eb927faebffc38c8382818df67fcd159Adam Cohen 1695f8afe6280eae34620067696173e71943e1a30a3Winson Chung icon.setClipToPadding(false); 170d2eca6b66e654e71fb46ae718910af3ec6c2cf9cAdam Cohen icon.mFolderName = (BubbleTextView) icon.findViewById(R.id.folder_icon_name); 17176fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen icon.mFolderName.setText(folderInfo.title); 1726e1c0d34bb31cacc24c57c89ab01deaa8985814fWinson Chung icon.mFolderName.setCompoundDrawablePadding(0); 1736e1c0d34bb31cacc24c57c89ab01deaa8985814fWinson Chung FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) icon.mFolderName.getLayoutParams(); 1746e1c0d34bb31cacc24c57c89ab01deaa8985814fWinson Chung lp.topMargin = grid.iconSizePx + grid.iconDrawablePaddingPx; 1756e1c0d34bb31cacc24c57c89ab01deaa8985814fWinson Chung 17631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project icon.setTag(folderInfo); 17731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project icon.setOnClickListener(launcher); 17831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project icon.mInfo = folderInfo; 17931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project icon.mLauncher = launcher; 180f4f89ef608245d39bbddda05f291361d2ae06667Sunny Goyal icon.setContentDescription(launcher.getString(R.string.folder_name_format, folderInfo.title)); 181a9cf38f533d1e86269868f1e6a806ccffd4a78fcAdam Cohen Folder folder = Folder.fromXml(launcher); 182a9cf38f533d1e86269868f1e6a806ccffd4a78fcAdam Cohen folder.setDragController(launcher.getDragController()); 1832801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen folder.setFolderIcon(icon); 184a9cf38f533d1e86269868f1e6a806ccffd4a78fcAdam Cohen folder.bind(folderInfo); 1854f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen icon.setFolder(folder); 186099f60d51f6310e1290687e83958e665b3324504Adam Cohen 187099f60d51f6310e1290687e83958e665b3324504Adam Cohen folderInfo.addListener(icon); 188099f60d51f6310e1290687e83958e665b3324504Adam Cohen 189dcbcc86353e9ed52daac87f292aece667cd0ac71Sunny Goyal icon.setOnFocusChangeListener(launcher.mFocusHandler); 19019072da7441e07d5e90026d9e9e1b38f11245e44Adam Cohen return icon; 19119072da7441e07d5e90026d9e9e1b38f11245e44Adam Cohen } 19219072da7441e07d5e90026d9e9e1b38f11245e44Adam Cohen 193099f60d51f6310e1290687e83958e665b3324504Adam Cohen @Override 194099f60d51f6310e1290687e83958e665b3324504Adam Cohen protected Parcelable onSaveInstanceState() { 195099f60d51f6310e1290687e83958e665b3324504Adam Cohen sStaticValuesDirty = true; 196099f60d51f6310e1290687e83958e665b3324504Adam Cohen return super.onSaveInstanceState(); 197099f60d51f6310e1290687e83958e665b3324504Adam Cohen } 198099f60d51f6310e1290687e83958e665b3324504Adam Cohen 19969ce2e5beaa1a57c7b8fa14a2d6ff0b3abeb93c0Adam Cohen 20031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 201f05545fcc2df05518731f8d7ff048d797fe776d5Anjali Koppal public Folder getFolder() { 202fb91f303f5e672f9b4c4f9f8a03486b224d60cd6Adam Cohen return mFolder; 203fb91f303f5e672f9b4c4f9f8a03486b224d60cd6Adam Cohen } 204fb91f303f5e672f9b4c4f9f8a03486b224d60cd6Adam Cohen 2054f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen private void setFolder(Folder folder) { 2064f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen mFolder = folder; 2074f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen updateItemDrawingParams(false); 2084f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen } 2094f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen 210f9c184a619e4e4b82cf9e0bf318ca6d8deaaaee7Adam Cohen public FolderInfo getFolderInfo() { 211fb91f303f5e672f9b4c4f9f8a03486b224d60cd6Adam Cohen return mInfo; 212fb91f303f5e672f9b4c4f9f8a03486b224d60cd6Adam Cohen } 213fb91f303f5e672f9b4c4f9f8a03486b224d60cd6Adam Cohen 214073a46ff635d089cbcb15d939d1de42dd2b86c97Adam Cohen private boolean willAcceptItem(ItemInfo item) { 21531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project final int itemType = item.itemType; 2162801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen return ((itemType == LauncherSettings.Favorites.ITEM_TYPE_APPLICATION || 2172801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen itemType == LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT) && 218c51934bfdfed6a5011c6d6c5b7b70f2d75613d41Adam Cohen !mFolder.isFull() && item != mInfo && !mInfo.opened); 219073a46ff635d089cbcb15d939d1de42dd2b86c97Adam Cohen } 220073a46ff635d089cbcb15d939d1de42dd2b86c97Adam Cohen 221aa8ef119f18864f4ab41c12f9c2ad6d7f643a0a9Sunny Goyal public boolean acceptDrop(ItemInfo dragInfo) { 222aa8ef119f18864f4ab41c12f9c2ad6d7f643a0a9Sunny Goyal final ItemInfo item = dragInfo; 223fb91f303f5e672f9b4c4f9f8a03486b224d60cd6Adam Cohen return !mFolder.isDestroyed() && willAcceptItem(item); 22431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 22531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 226df0353815c629fc678824b07a234b89a1ff94208Adam Cohen public void addItem(ShortcutInfo item) { 227df0353815c629fc678824b07a234b89a1ff94208Adam Cohen mInfo.add(item); 228df0353815c629fc678824b07a234b89a1ff94208Adam Cohen } 229df0353815c629fc678824b07a234b89a1ff94208Adam Cohen 230aa8ef119f18864f4ab41c12f9c2ad6d7f643a0a9Sunny Goyal public void onDragEnter(ItemInfo dragInfo) { 231aa8ef119f18864f4ab41c12f9c2ad6d7f643a0a9Sunny Goyal if (mFolder.isDestroyed() || !willAcceptItem(dragInfo)) return; 23269ce2e5beaa1a57c7b8fa14a2d6ff0b3abeb93c0Adam Cohen CellLayout.LayoutParams lp = (CellLayout.LayoutParams) getLayoutParams(); 233efca0279eb927faebffc38c8382818df67fcd159Adam Cohen CellLayout cl = (CellLayout) getParent().getParent(); 234efca0279eb927faebffc38c8382818df67fcd159Adam Cohen 235efca0279eb927faebffc38c8382818df67fcd159Adam Cohen mBackground.animateToAccept(cl, lp.cellX, lp.cellY); 23655bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi mOpenAlarm.setOnAlarmListener(mOnOpenListener); 237dedfca2aef7573624bdb421b1805ef5e04bee502Adam Cohen if (SPRING_LOADING_ENABLED && 238dedfca2aef7573624bdb421b1805ef5e04bee502Adam Cohen ((dragInfo instanceof AppInfo) || (dragInfo instanceof ShortcutInfo))) { 239dedfca2aef7573624bdb421b1805ef5e04bee502Adam Cohen // TODO: we currently don't support spring-loading for PendingAddShortcutInfos even 240dedfca2aef7573624bdb421b1805ef5e04bee502Adam Cohen // though widget-style shortcuts can be added to folders. The issue is that we need 241dedfca2aef7573624bdb421b1805ef5e04bee502Adam Cohen // to deal with configuration activities which are currently handled in 242dedfca2aef7573624bdb421b1805ef5e04bee502Adam Cohen // Workspace#onDropExternal. 24355bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi mOpenAlarm.setAlarm(ON_OPEN_DELAY); 24455bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi } 245aa8ef119f18864f4ab41c12f9c2ad6d7f643a0a9Sunny Goyal mDragInfo = dragInfo; 246073a46ff635d089cbcb15d939d1de42dd2b86c97Adam Cohen } 247073a46ff635d089cbcb15d939d1de42dd2b86c97Adam Cohen 24855bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi OnAlarmListener mOnOpenListener = new OnAlarmListener() { 24955bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi public void onAlarm(Alarm alarm) { 25055bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi ShortcutInfo item; 25155bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi if (mDragInfo instanceof AppInfo) { 25255bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi // Came from all apps -- make a copy. 25355bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi item = ((AppInfo) mDragInfo).makeShortcut(); 25455bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi item.spanX = 1; 25555bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi item.spanY = 1; 25655bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi } else { 257dedfca2aef7573624bdb421b1805ef5e04bee502Adam Cohen // ShortcutInfo 25855bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi item = (ShortcutInfo) mDragInfo; 25955bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi } 26055bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi mFolder.beginExternalDrag(item); 26108442b84a25a22f3f21aad89ed5a6adccaa2166dSunny Goyal mLauncher.openFolder(FolderIcon.this, true); 26255bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi } 26355bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi }; 26455bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi 265d044526d82e7938cf35b296978d9d5302f98b4afAdam Cohen public void performCreateAnimation(final ShortcutInfo destInfo, final View destView, 2667bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung final ShortcutInfo srcInfo, final DragView srcView, Rect dstRect, 267ac8c87687b8e063c981f28cb31bab2cc110f26ccAdam Cohen float scaleRelativeToDragLayer, Runnable postAnimationRunnable) { 268d044526d82e7938cf35b296978d9d5302f98b4afAdam Cohen 269fb91f303f5e672f9b4c4f9f8a03486b224d60cd6Adam Cohen // These correspond two the drawable and view that the icon was dropped _onto_ 27095abbb330ce9bbaf23594245f0f8a795c8118038Sunny Goyal Drawable animateDrawable = getTopDrawable((TextView) destView); 271fb91f303f5e672f9b4c4f9f8a03486b224d60cd6Adam Cohen computePreviewDrawingParams(animateDrawable.getIntrinsicWidth(), 272fb91f303f5e672f9b4c4f9f8a03486b224d60cd6Adam Cohen destView.getMeasuredWidth()); 273fb91f303f5e672f9b4c4f9f8a03486b224d60cd6Adam Cohen 2744f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen mReferenceDrawable = animateDrawable; 2754f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen 2764f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen addItem(destInfo); 277fb91f303f5e672f9b4c4f9f8a03486b224d60cd6Adam Cohen // This will animate the first item from it's position as an icon into its 278fb91f303f5e672f9b4c4f9f8a03486b224d60cd6Adam Cohen // position as the first item in the preview 279fb91f303f5e672f9b4c4f9f8a03486b224d60cd6Adam Cohen animateFirstItem(animateDrawable, INITIAL_ITEM_ANIMATION_DURATION, false, null); 280ac8c87687b8e063c981f28cb31bab2cc110f26ccAdam Cohen 281d044526d82e7938cf35b296978d9d5302f98b4afAdam Cohen // This will animate the dragView (srcView) into the new folder 2827bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung onDrop(srcInfo, srcView, dstRect, scaleRelativeToDragLayer, 1, postAnimationRunnable, null); 283fb91f303f5e672f9b4c4f9f8a03486b224d60cd6Adam Cohen } 284fb91f303f5e672f9b4c4f9f8a03486b224d60cd6Adam Cohen 285fb91f303f5e672f9b4c4f9f8a03486b224d60cd6Adam Cohen public void performDestroyAnimation(final View finalView, Runnable onCompleteRunnable) { 28695abbb330ce9bbaf23594245f0f8a795c8118038Sunny Goyal Drawable animateDrawable = getTopDrawable((TextView) finalView); 28702dd7aea3d8ac94126a8f8069e6762592ea60326Jason Monk computePreviewDrawingParams(animateDrawable.getIntrinsicWidth(), 288fb91f303f5e672f9b4c4f9f8a03486b224d60cd6Adam Cohen finalView.getMeasuredWidth()); 289d044526d82e7938cf35b296978d9d5302f98b4afAdam Cohen 290d044526d82e7938cf35b296978d9d5302f98b4afAdam Cohen // This will animate the first item from it's position as an icon into its 291d044526d82e7938cf35b296978d9d5302f98b4afAdam Cohen // position as the first item in the preview 292fb91f303f5e672f9b4c4f9f8a03486b224d60cd6Adam Cohen animateFirstItem(animateDrawable, FINAL_ITEM_ANIMATION_DURATION, true, 293fb91f303f5e672f9b4c4f9f8a03486b224d60cd6Adam Cohen onCompleteRunnable); 294d044526d82e7938cf35b296978d9d5302f98b4afAdam Cohen } 295d044526d82e7938cf35b296978d9d5302f98b4afAdam Cohen 296c0dcf597084d00e4c23a7fea5fd0738f6c095a6bAdam Cohen public void onDragExit(Object dragInfo) { 297c6cc61d45836e4081920883cc4d448ccb0bb8417Adam Cohen onDragExit(); 298c6cc61d45836e4081920883cc4d448ccb0bb8417Adam Cohen } 299c6cc61d45836e4081920883cc4d448ccb0bb8417Adam Cohen 300c6cc61d45836e4081920883cc4d448ccb0bb8417Adam Cohen public void onDragExit() { 301efca0279eb927faebffc38c8382818df67fcd159Adam Cohen mBackground.animateToRest(); 30255bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi mOpenAlarm.cancelAlarm(); 303073a46ff635d089cbcb15d939d1de42dd2b86c97Adam Cohen } 304073a46ff635d089cbcb15d939d1de42dd2b86c97Adam Cohen 3057bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung private void onDrop(final ShortcutInfo item, DragView animateView, Rect finalRect, 3067bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung float scaleRelativeToDragLayer, int index, Runnable postAnimationRunnable, 3077bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung DragObject d) { 308d044526d82e7938cf35b296978d9d5302f98b4afAdam Cohen item.cellX = -1; 309d044526d82e7938cf35b296978d9d5302f98b4afAdam Cohen item.cellY = -1; 310d044526d82e7938cf35b296978d9d5302f98b4afAdam Cohen 311558baaf0a0b1c6a9062a6771088098533a35222bAdam Cohen // Typically, the animateView corresponds to the DragView; however, if this is being done 312558baaf0a0b1c6a9062a6771088098533a35222bAdam Cohen // after a configuration activity (ie. for a Shortcut being dragged from AllApps) we 313558baaf0a0b1c6a9062a6771088098533a35222bAdam Cohen // will not have a view to animate 314558baaf0a0b1c6a9062a6771088098533a35222bAdam Cohen if (animateView != null) { 315558baaf0a0b1c6a9062a6771088098533a35222bAdam Cohen DragLayer dragLayer = mLauncher.getDragLayer(); 316558baaf0a0b1c6a9062a6771088098533a35222bAdam Cohen Rect from = new Rect(); 317558baaf0a0b1c6a9062a6771088098533a35222bAdam Cohen dragLayer.getViewRectRelativeToSelf(animateView, from); 318558baaf0a0b1c6a9062a6771088098533a35222bAdam Cohen Rect to = finalRect; 319558baaf0a0b1c6a9062a6771088098533a35222bAdam Cohen if (to == null) { 320558baaf0a0b1c6a9062a6771088098533a35222bAdam Cohen to = new Rect(); 321558baaf0a0b1c6a9062a6771088098533a35222bAdam Cohen Workspace workspace = mLauncher.getWorkspace(); 322558baaf0a0b1c6a9062a6771088098533a35222bAdam Cohen // Set cellLayout and this to it's final state to compute final animation locations 323558baaf0a0b1c6a9062a6771088098533a35222bAdam Cohen workspace.setFinalTransitionTransform((CellLayout) getParent().getParent()); 324558baaf0a0b1c6a9062a6771088098533a35222bAdam Cohen float scaleX = getScaleX(); 325558baaf0a0b1c6a9062a6771088098533a35222bAdam Cohen float scaleY = getScaleY(); 326558baaf0a0b1c6a9062a6771088098533a35222bAdam Cohen setScaleX(1.0f); 327558baaf0a0b1c6a9062a6771088098533a35222bAdam Cohen setScaleY(1.0f); 328558baaf0a0b1c6a9062a6771088098533a35222bAdam Cohen scaleRelativeToDragLayer = dragLayer.getDescendantRectRelativeToSelf(this, to); 329558baaf0a0b1c6a9062a6771088098533a35222bAdam Cohen // Finished computing final animation locations, restore current state 330558baaf0a0b1c6a9062a6771088098533a35222bAdam Cohen setScaleX(scaleX); 331558baaf0a0b1c6a9062a6771088098533a35222bAdam Cohen setScaleY(scaleY); 332558baaf0a0b1c6a9062a6771088098533a35222bAdam Cohen workspace.resetTransitionTransform((CellLayout) getParent().getParent()); 333558baaf0a0b1c6a9062a6771088098533a35222bAdam Cohen } 334ac8c87687b8e063c981f28cb31bab2cc110f26ccAdam Cohen 335558baaf0a0b1c6a9062a6771088098533a35222bAdam Cohen int[] center = new int[2]; 336119e8982ab6a0cf00e31e8744f27b72ba8bf7b20Adam Cohen float scale = getLocalCenterForIndex(index, index + 1, center); 337558baaf0a0b1c6a9062a6771088098533a35222bAdam Cohen center[0] = (int) Math.round(scaleRelativeToDragLayer * center[0]); 338558baaf0a0b1c6a9062a6771088098533a35222bAdam Cohen center[1] = (int) Math.round(scaleRelativeToDragLayer * center[1]); 339d044526d82e7938cf35b296978d9d5302f98b4afAdam Cohen 340558baaf0a0b1c6a9062a6771088098533a35222bAdam Cohen to.offset(center[0] - animateView.getMeasuredWidth() / 2, 3415f8afe6280eae34620067696173e71943e1a30a3Winson Chung center[1] - animateView.getMeasuredHeight() / 2); 342d044526d82e7938cf35b296978d9d5302f98b4afAdam Cohen 343f9c184a619e4e4b82cf9e0bf318ca6d8deaaaee7Adam Cohen float finalAlpha = index < mPreviewLayoutRule.numItems() ? 0.5f : 0f; 344558baaf0a0b1c6a9062a6771088098533a35222bAdam Cohen 345ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen float finalScale = scale * scaleRelativeToDragLayer; 346558baaf0a0b1c6a9062a6771088098533a35222bAdam Cohen dragLayer.animateView(animateView, from, to, finalAlpha, 347ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen 1, 1, finalScale, finalScale, DROP_IN_ANIMATION_DURATION, 348558baaf0a0b1c6a9062a6771088098533a35222bAdam Cohen new DecelerateInterpolator(2), new AccelerateInterpolator(2), 349ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen postAnimationRunnable, DragLayer.ANIMATION_END_DISAPPEAR, null); 350fb91f303f5e672f9b4c4f9f8a03486b224d60cd6Adam Cohen addItem(item); 3517a8b82b5926e6a520df28e7f591b9a94ec605581Adam Cohen mFolder.hideItem(item); 3524f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen 3534f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen final PreviewItemDrawingParams params = index < mDrawingParams.size() ? 3544f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen mDrawingParams.get(index) : null; 3554f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen if (params != null) params.hidden = true; 356558baaf0a0b1c6a9062a6771088098533a35222bAdam Cohen postDelayed(new Runnable() { 357558baaf0a0b1c6a9062a6771088098533a35222bAdam Cohen public void run() { 3584f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen if (params != null) params.hidden = false; 3597a8b82b5926e6a520df28e7f591b9a94ec605581Adam Cohen mFolder.showItem(item); 360fb91f303f5e672f9b4c4f9f8a03486b224d60cd6Adam Cohen invalidate(); 361558baaf0a0b1c6a9062a6771088098533a35222bAdam Cohen } 362558baaf0a0b1c6a9062a6771088098533a35222bAdam Cohen }, DROP_IN_ANIMATION_DURATION); 363558baaf0a0b1c6a9062a6771088098533a35222bAdam Cohen } else { 364558baaf0a0b1c6a9062a6771088098533a35222bAdam Cohen addItem(item); 365558baaf0a0b1c6a9062a6771088098533a35222bAdam Cohen } 366d044526d82e7938cf35b296978d9d5302f98b4afAdam Cohen } 367d044526d82e7938cf35b296978d9d5302f98b4afAdam Cohen 3683e8f811f31a2275e778244427271f77f4116c08bAdam Cohen public void onDrop(DragObject d) { 369c0dcf597084d00e4c23a7fea5fd0738f6c095a6bAdam Cohen ShortcutInfo item; 370eadbfc564d84aaf1d800da3d0d6edf6312f89648Michael Jurka if (d.dragInfo instanceof AppInfo) { 371c0dcf597084d00e4c23a7fea5fd0738f6c095a6bAdam Cohen // Came from all apps -- make a copy 372eadbfc564d84aaf1d800da3d0d6edf6312f89648Michael Jurka item = ((AppInfo) d.dragInfo).makeShortcut(); 373c0dcf597084d00e4c23a7fea5fd0738f6c095a6bAdam Cohen } else { 3743e8f811f31a2275e778244427271f77f4116c08bAdam Cohen item = (ShortcutInfo) d.dragInfo; 375c0dcf597084d00e4c23a7fea5fd0738f6c095a6bAdam Cohen } 37667bd9ccf856840856944815a382e4bbb0e71e949Adam Cohen mFolder.notifyDrop(); 3777bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung onDrop(item, d.dragView, null, 1.0f, mInfo.contents.size(), d.postAnimationRunnable, d); 378c0dcf597084d00e4c23a7fea5fd0738f6c095a6bAdam Cohen } 379c0dcf597084d00e4c23a7fea5fd0738f6c095a6bAdam Cohen 380d044526d82e7938cf35b296978d9d5302f98b4afAdam Cohen private void computePreviewDrawingParams(int drawableSize, int totalSize) { 381aa2542a461072a57058ce45946ff6f5552ecce8aAdam Cohen if (mIntrinsicIconSize != drawableSize || mTotalWidth != totalSize || 382aa2542a461072a57058ce45946ff6f5552ecce8aAdam Cohen mPrevTopPadding != getPaddingTop()) { 3832e6da1539bc7286336b3c24d96ab76434939ce4dAdam Cohen DeviceProfile grid = mLauncher.getDeviceProfile(); 3845f8afe6280eae34620067696173e71943e1a30a3Winson Chung 385d044526d82e7938cf35b296978d9d5302f98b4afAdam Cohen mIntrinsicIconSize = drawableSize; 386d044526d82e7938cf35b296978d9d5302f98b4afAdam Cohen mTotalWidth = totalSize; 387aa2542a461072a57058ce45946ff6f5552ecce8aAdam Cohen mPrevTopPadding = getPaddingTop(); 38876fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen 389efca0279eb927faebffc38c8382818df67fcd159Adam Cohen mBackground.setup(getResources().getDisplayMetrics(), grid, this, mTotalWidth, 390efca0279eb927faebffc38c8382818df67fcd159Adam Cohen getPaddingTop()); 391efca0279eb927faebffc38c8382818df67fcd159Adam Cohen mPreviewLayoutRule.init(mBackground.previewSize, mIntrinsicIconSize, 392119e8982ab6a0cf00e31e8744f27b72ba8bf7b20Adam Cohen Utilities.isRtl(getResources())); 393efca0279eb927faebffc38c8382818df67fcd159Adam Cohen 3944f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen updateItemDrawingParams(false); 395073a46ff635d089cbcb15d939d1de42dd2b86c97Adam Cohen } 396d044526d82e7938cf35b296978d9d5302f98b4afAdam Cohen } 39776fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen 398d044526d82e7938cf35b296978d9d5302f98b4afAdam Cohen private void computePreviewDrawingParams(Drawable d) { 399d044526d82e7938cf35b296978d9d5302f98b4afAdam Cohen computePreviewDrawingParams(d.getIntrinsicWidth(), getMeasuredWidth()); 400d044526d82e7938cf35b296978d9d5302f98b4afAdam Cohen } 401073a46ff635d089cbcb15d939d1de42dd2b86c97Adam Cohen 402261194387beebaa7927ec4e310274218b651494dSunny Goyal static class PreviewItemDrawingParams { 403261194387beebaa7927ec4e310274218b651494dSunny Goyal PreviewItemDrawingParams(float transX, float transY, float scale, float overlayAlpha) { 404d044526d82e7938cf35b296978d9d5302f98b4afAdam Cohen this.transX = transX; 405d044526d82e7938cf35b296978d9d5302f98b4afAdam Cohen this.transY = transY; 406d044526d82e7938cf35b296978d9d5302f98b4afAdam Cohen this.scale = scale; 407d044526d82e7938cf35b296978d9d5302f98b4afAdam Cohen this.overlayAlpha = overlayAlpha; 408d044526d82e7938cf35b296978d9d5302f98b4afAdam Cohen } 4094f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen 4104f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen public void update(float transX, float transY, float scale) { 4114f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen // We ensure the update will not interfere with an animation on the layout params 4124f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen // If the final values differ, we cancel the animation. 4134f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen if (anim != null) { 4144f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen if (anim.finalTransX == transX || anim.finalTransY == transY 4154f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen || anim.finalScale == scale) { 4164f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen return; 4174f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen } 4184f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen anim.cancel(); 4194f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen } 4204f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen 4214f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen this.transX = transX; 4224f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen this.transY = transY; 4234f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen this.scale = scale; 4244f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen } 4254f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen 426261194387beebaa7927ec4e310274218b651494dSunny Goyal float transX; 427261194387beebaa7927ec4e310274218b651494dSunny Goyal float transY; 428261194387beebaa7927ec4e310274218b651494dSunny Goyal float scale; 4294f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen public float overlayAlpha; 4304f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen boolean hidden; 4314f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen FolderPreviewItemAnim anim; 432261194387beebaa7927ec4e310274218b651494dSunny Goyal Drawable drawable; 433d044526d82e7938cf35b296978d9d5302f98b4afAdam Cohen } 434badf71e11fba2d6efa1d1bcca9542001f90a3777Adam Cohen 435119e8982ab6a0cf00e31e8744f27b72ba8bf7b20Adam Cohen private float getLocalCenterForIndex(int index, int curNumItems, int[] center) { 4364f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen mTmpParams = computePreviewItemDrawingParams(Math.min(mPreviewLayoutRule.numItems(), index), 4374f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen curNumItems, mTmpParams); 438a9cf38f533d1e86269868f1e6a806ccffd4a78fcAdam Cohen 439efca0279eb927faebffc38c8382818df67fcd159Adam Cohen mTmpParams.transX += mBackground.basePreviewOffsetX; 440efca0279eb927faebffc38c8382818df67fcd159Adam Cohen mTmpParams.transY += mBackground.basePreviewOffsetY; 4414f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen float offsetX = mTmpParams.transX + (mTmpParams.scale * mIntrinsicIconSize) / 2; 4424f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen float offsetY = mTmpParams.transY + (mTmpParams.scale * mIntrinsicIconSize) / 2; 443badf71e11fba2d6efa1d1bcca9542001f90a3777Adam Cohen 444ac8c87687b8e063c981f28cb31bab2cc110f26ccAdam Cohen center[0] = (int) Math.round(offsetX); 445ac8c87687b8e063c981f28cb31bab2cc110f26ccAdam Cohen center[1] = (int) Math.round(offsetY); 4464f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen return mTmpParams.scale; 447d044526d82e7938cf35b296978d9d5302f98b4afAdam Cohen } 448badf71e11fba2d6efa1d1bcca9542001f90a3777Adam Cohen 449119e8982ab6a0cf00e31e8744f27b72ba8bf7b20Adam Cohen private PreviewItemDrawingParams computePreviewItemDrawingParams(int index, int curNumItems, 450d044526d82e7938cf35b296978d9d5302f98b4afAdam Cohen PreviewItemDrawingParams params) { 4514f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen // We use an index of -1 to represent an icon on the workspace for the destroy and 4524f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen // create animations 4534f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen if (index == -1) { 4544f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen return getFinalIconParams(params); 4554f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen } 456119e8982ab6a0cf00e31e8744f27b72ba8bf7b20Adam Cohen return mPreviewLayoutRule.computePreviewItemDrawingParams(index, curNumItems, params); 457d044526d82e7938cf35b296978d9d5302f98b4afAdam Cohen } 458badf71e11fba2d6efa1d1bcca9542001f90a3777Adam Cohen 4594f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen private PreviewItemDrawingParams getFinalIconParams(PreviewItemDrawingParams params) { 4604f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen float iconSize = mLauncher.getDeviceProfile().iconSizePx; 4614f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen 4624f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen final float scale = iconSize / mReferenceDrawable.getIntrinsicWidth(); 463efca0279eb927faebffc38c8382818df67fcd159Adam Cohen final float trans = (mBackground.previewSize - iconSize) / 2; 4644f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen 4654f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen params.update(trans, trans, scale); 4664f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen return params; 4674f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen } 4684f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen 469d044526d82e7938cf35b296978d9d5302f98b4afAdam Cohen private void drawPreviewItem(Canvas canvas, PreviewItemDrawingParams params) { 470d044526d82e7938cf35b296978d9d5302f98b4afAdam Cohen canvas.save(); 471119e8982ab6a0cf00e31e8744f27b72ba8bf7b20Adam Cohen canvas.translate(params.transX, params.transY); 472d044526d82e7938cf35b296978d9d5302f98b4afAdam Cohen canvas.scale(params.scale, params.scale); 473d044526d82e7938cf35b296978d9d5302f98b4afAdam Cohen Drawable d = params.drawable; 474d044526d82e7938cf35b296978d9d5302f98b4afAdam Cohen 475d044526d82e7938cf35b296978d9d5302f98b4afAdam Cohen if (d != null) { 476d4e53c882494f8cd7e4c0d44dbfc300d3610afcfWinson Chung mOldBounds.set(d.getBounds()); 477d044526d82e7938cf35b296978d9d5302f98b4afAdam Cohen d.setBounds(0, 0, mIntrinsicIconSize, mIntrinsicIconSize); 478c5c60ad3592f53549c9ffaa58e9a87b0480080e8Sunny Goyal if (d instanceof FastBitmapDrawable) { 479c5c60ad3592f53549c9ffaa58e9a87b0480080e8Sunny Goyal FastBitmapDrawable fd = (FastBitmapDrawable) d; 480c088049113c261331b5685e64050d14a31cd72dfWinson float oldBrightness = fd.getBrightness(); 481508da15509224b46fcccabbe78f3e92fe69a67d8Sunny Goyal fd.setBrightness(params.overlayAlpha); 482c5c60ad3592f53549c9ffaa58e9a87b0480080e8Sunny Goyal d.draw(canvas); 483508da15509224b46fcccabbe78f3e92fe69a67d8Sunny Goyal fd.setBrightness(oldBrightness); 484c5c60ad3592f53549c9ffaa58e9a87b0480080e8Sunny Goyal } else { 485c088049113c261331b5685e64050d14a31cd72dfWinson d.setColorFilter(Color.argb((int) (params.overlayAlpha * 255), 255, 255, 255), 486c5c60ad3592f53549c9ffaa58e9a87b0480080e8Sunny Goyal PorterDuff.Mode.SRC_ATOP); 487c5c60ad3592f53549c9ffaa58e9a87b0480080e8Sunny Goyal d.draw(canvas); 488c5c60ad3592f53549c9ffaa58e9a87b0480080e8Sunny Goyal d.clearColorFilter(); 489c5c60ad3592f53549c9ffaa58e9a87b0480080e8Sunny Goyal } 490d4e53c882494f8cd7e4c0d44dbfc300d3610afcfWinson Chung d.setBounds(mOldBounds); 491d044526d82e7938cf35b296978d9d5302f98b4afAdam Cohen } 492d044526d82e7938cf35b296978d9d5302f98b4afAdam Cohen canvas.restore(); 493d044526d82e7938cf35b296978d9d5302f98b4afAdam Cohen } 49476fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen 495f172b747c24f28e29baaaf58f08bab48847b7a40Adam Cohen /** 496f172b747c24f28e29baaaf58f08bab48847b7a40Adam Cohen * This object represents a FolderIcon preview background. It stores drawing / measurement 497f172b747c24f28e29baaaf58f08bab48847b7a40Adam Cohen * information, handles drawing, and animation (accept state <--> rest state). 498f172b747c24f28e29baaaf58f08bab48847b7a40Adam Cohen */ 499efca0279eb927faebffc38c8382818df67fcd159Adam Cohen public static class PreviewBackground { 500efca0279eb927faebffc38c8382818df67fcd159Adam Cohen private float mScale = 1f; 501efca0279eb927faebffc38c8382818df67fcd159Adam Cohen private float mColorMultiplier = 1f; 502efca0279eb927faebffc38c8382818df67fcd159Adam Cohen private Path mClipPath = new Path(); 503efca0279eb927faebffc38c8382818df67fcd159Adam Cohen private int mStrokeWidth; 504f172b747c24f28e29baaaf58f08bab48847b7a40Adam Cohen private View mInvalidateDelegate; 505efca0279eb927faebffc38c8382818df67fcd159Adam Cohen 506efca0279eb927faebffc38c8382818df67fcd159Adam Cohen public int previewSize; 507efca0279eb927faebffc38c8382818df67fcd159Adam Cohen private int basePreviewOffsetX; 508efca0279eb927faebffc38c8382818df67fcd159Adam Cohen private int basePreviewOffsetY; 509efca0279eb927faebffc38c8382818df67fcd159Adam Cohen 510efca0279eb927faebffc38c8382818df67fcd159Adam Cohen private CellLayout mDrawingDelegate; 511efca0279eb927faebffc38c8382818df67fcd159Adam Cohen public int delegateCellX; 512efca0279eb927faebffc38c8382818df67fcd159Adam Cohen public int delegateCellY; 513efca0279eb927faebffc38c8382818df67fcd159Adam Cohen 514f172b747c24f28e29baaaf58f08bab48847b7a40Adam Cohen // When the PreviewBackground is drawn under an icon (for creating a folder) the border 515f172b747c24f28e29baaaf58f08bab48847b7a40Adam Cohen // should not occlude the icon 516f172b747c24f28e29baaaf58f08bab48847b7a40Adam Cohen public boolean isClipping = true; 517f172b747c24f28e29baaaf58f08bab48847b7a40Adam Cohen 518efca0279eb927faebffc38c8382818df67fcd159Adam Cohen // Drawing / animation configurations 519efca0279eb927faebffc38c8382818df67fcd159Adam Cohen private static final float ACCEPT_SCALE_FACTOR = 1.25f; 520efca0279eb927faebffc38c8382818df67fcd159Adam Cohen private static final float ACCEPT_COLOR_MULTIPLIER = 1.5f; 521efca0279eb927faebffc38c8382818df67fcd159Adam Cohen 522efca0279eb927faebffc38c8382818df67fcd159Adam Cohen // Expressed on a scale from 0 to 255. 523efca0279eb927faebffc38c8382818df67fcd159Adam Cohen private static final int BG_OPACITY = 160; 524efca0279eb927faebffc38c8382818df67fcd159Adam Cohen private static final int MAX_BG_OPACITY = 225; 525efca0279eb927faebffc38c8382818df67fcd159Adam Cohen private static final int BG_INTENSITY = 245; 526efca0279eb927faebffc38c8382818df67fcd159Adam Cohen private static final int SHADOW_OPACITY = 80; 527efca0279eb927faebffc38c8382818df67fcd159Adam Cohen 528efca0279eb927faebffc38c8382818df67fcd159Adam Cohen ValueAnimator mScaleAnimator; 529efca0279eb927faebffc38c8382818df67fcd159Adam Cohen 530f172b747c24f28e29baaaf58f08bab48847b7a40Adam Cohen public void setup(DisplayMetrics dm, DeviceProfile grid, View invalidateDelegate, 531efca0279eb927faebffc38c8382818df67fcd159Adam Cohen int availableSpace, int topPadding) { 532f172b747c24f28e29baaaf58f08bab48847b7a40Adam Cohen mInvalidateDelegate = invalidateDelegate; 533efca0279eb927faebffc38c8382818df67fcd159Adam Cohen 534efca0279eb927faebffc38c8382818df67fcd159Adam Cohen final int previewSize = grid.folderIconSizePx; 535efca0279eb927faebffc38c8382818df67fcd159Adam Cohen final int previewPadding = grid.folderIconPreviewPadding; 536efca0279eb927faebffc38c8382818df67fcd159Adam Cohen 537efca0279eb927faebffc38c8382818df67fcd159Adam Cohen this.previewSize = (previewSize - 2 * previewPadding); 538efca0279eb927faebffc38c8382818df67fcd159Adam Cohen 539efca0279eb927faebffc38c8382818df67fcd159Adam Cohen basePreviewOffsetX = (availableSpace - this.previewSize) / 2; 540efca0279eb927faebffc38c8382818df67fcd159Adam Cohen basePreviewOffsetY = previewPadding + grid.folderBackgroundOffset + topPadding; 541efca0279eb927faebffc38c8382818df67fcd159Adam Cohen 542efca0279eb927faebffc38c8382818df67fcd159Adam Cohen mStrokeWidth = Utilities.pxFromDp(1, dm); 543efca0279eb927faebffc38c8382818df67fcd159Adam Cohen 544efca0279eb927faebffc38c8382818df67fcd159Adam Cohen invalidate(); 545efca0279eb927faebffc38c8382818df67fcd159Adam Cohen } 546efca0279eb927faebffc38c8382818df67fcd159Adam Cohen 547efca0279eb927faebffc38c8382818df67fcd159Adam Cohen int getRadius() { 548efca0279eb927faebffc38c8382818df67fcd159Adam Cohen return previewSize / 2; 549efca0279eb927faebffc38c8382818df67fcd159Adam Cohen } 550efca0279eb927faebffc38c8382818df67fcd159Adam Cohen 551efca0279eb927faebffc38c8382818df67fcd159Adam Cohen int getScaledRadius() { 552efca0279eb927faebffc38c8382818df67fcd159Adam Cohen return (int) (mScale * getRadius()); 553efca0279eb927faebffc38c8382818df67fcd159Adam Cohen } 554efca0279eb927faebffc38c8382818df67fcd159Adam Cohen 555efca0279eb927faebffc38c8382818df67fcd159Adam Cohen int getOffsetX() { 556efca0279eb927faebffc38c8382818df67fcd159Adam Cohen return basePreviewOffsetX - (getScaledRadius() - getRadius()); 557efca0279eb927faebffc38c8382818df67fcd159Adam Cohen } 558efca0279eb927faebffc38c8382818df67fcd159Adam Cohen 559efca0279eb927faebffc38c8382818df67fcd159Adam Cohen int getOffsetY() { 560efca0279eb927faebffc38c8382818df67fcd159Adam Cohen return basePreviewOffsetY - (getScaledRadius() - getRadius()); 561efca0279eb927faebffc38c8382818df67fcd159Adam Cohen } 562efca0279eb927faebffc38c8382818df67fcd159Adam Cohen 563efca0279eb927faebffc38c8382818df67fcd159Adam Cohen void invalidate() { 564efca0279eb927faebffc38c8382818df67fcd159Adam Cohen int radius = getScaledRadius(); 565efca0279eb927faebffc38c8382818df67fcd159Adam Cohen mClipPath.reset(); 566efca0279eb927faebffc38c8382818df67fcd159Adam Cohen mClipPath.addCircle(radius, radius, radius, Path.Direction.CW); 567efca0279eb927faebffc38c8382818df67fcd159Adam Cohen 568f172b747c24f28e29baaaf58f08bab48847b7a40Adam Cohen if (mInvalidateDelegate != null) { 569f172b747c24f28e29baaaf58f08bab48847b7a40Adam Cohen mInvalidateDelegate.invalidate(); 570efca0279eb927faebffc38c8382818df67fcd159Adam Cohen } 571efca0279eb927faebffc38c8382818df67fcd159Adam Cohen 572efca0279eb927faebffc38c8382818df67fcd159Adam Cohen if (mDrawingDelegate != null) { 573efca0279eb927faebffc38c8382818df67fcd159Adam Cohen mDrawingDelegate.invalidate(); 574efca0279eb927faebffc38c8382818df67fcd159Adam Cohen } 575efca0279eb927faebffc38c8382818df67fcd159Adam Cohen } 576efca0279eb927faebffc38c8382818df67fcd159Adam Cohen 577f172b747c24f28e29baaaf58f08bab48847b7a40Adam Cohen void setInvalidateDelegate(View invalidateDelegate) { 578f172b747c24f28e29baaaf58f08bab48847b7a40Adam Cohen mInvalidateDelegate = invalidateDelegate; 579efca0279eb927faebffc38c8382818df67fcd159Adam Cohen invalidate(); 580efca0279eb927faebffc38c8382818df67fcd159Adam Cohen } 581efca0279eb927faebffc38c8382818df67fcd159Adam Cohen 582efca0279eb927faebffc38c8382818df67fcd159Adam Cohen public void drawBackground(Canvas canvas, Paint paint) { 583efca0279eb927faebffc38c8382818df67fcd159Adam Cohen canvas.save(); 584efca0279eb927faebffc38c8382818df67fcd159Adam Cohen canvas.translate(getOffsetX(), getOffsetY()); 585efca0279eb927faebffc38c8382818df67fcd159Adam Cohen 586efca0279eb927faebffc38c8382818df67fcd159Adam Cohen paint.reset(); 587efca0279eb927faebffc38c8382818df67fcd159Adam Cohen paint.setStyle(Paint.Style.FILL); 588efca0279eb927faebffc38c8382818df67fcd159Adam Cohen paint.setXfermode(null); 589efca0279eb927faebffc38c8382818df67fcd159Adam Cohen paint.setAntiAlias(true); 590efca0279eb927faebffc38c8382818df67fcd159Adam Cohen 591efca0279eb927faebffc38c8382818df67fcd159Adam Cohen int alpha = (int) Math.min(MAX_BG_OPACITY, BG_OPACITY * mColorMultiplier); 592efca0279eb927faebffc38c8382818df67fcd159Adam Cohen paint.setColor(Color.argb(alpha, BG_INTENSITY, BG_INTENSITY, BG_INTENSITY)); 593efca0279eb927faebffc38c8382818df67fcd159Adam Cohen 594efca0279eb927faebffc38c8382818df67fcd159Adam Cohen float radius = getScaledRadius(); 595efca0279eb927faebffc38c8382818df67fcd159Adam Cohen 596efca0279eb927faebffc38c8382818df67fcd159Adam Cohen canvas.drawCircle(radius, radius, radius, paint); 597efca0279eb927faebffc38c8382818df67fcd159Adam Cohen canvas.clipPath(mClipPath, Region.Op.DIFFERENCE); 598efca0279eb927faebffc38c8382818df67fcd159Adam Cohen 599efca0279eb927faebffc38c8382818df67fcd159Adam Cohen paint.setStyle(Paint.Style.STROKE); 600efca0279eb927faebffc38c8382818df67fcd159Adam Cohen paint.setColor(Color.TRANSPARENT); 601efca0279eb927faebffc38c8382818df67fcd159Adam Cohen paint.setShadowLayer(mStrokeWidth, 0, mStrokeWidth, Color.argb(SHADOW_OPACITY, 0, 0, 0)); 602efca0279eb927faebffc38c8382818df67fcd159Adam Cohen canvas.drawCircle(radius, radius, radius, paint); 603efca0279eb927faebffc38c8382818df67fcd159Adam Cohen 604efca0279eb927faebffc38c8382818df67fcd159Adam Cohen canvas.restore(); 605efca0279eb927faebffc38c8382818df67fcd159Adam Cohen } 606efca0279eb927faebffc38c8382818df67fcd159Adam Cohen 607efca0279eb927faebffc38c8382818df67fcd159Adam Cohen public void drawBackgroundStroke(Canvas canvas, Paint paint) { 608efca0279eb927faebffc38c8382818df67fcd159Adam Cohen canvas.save(); 609efca0279eb927faebffc38c8382818df67fcd159Adam Cohen canvas.translate(getOffsetX(), getOffsetY()); 610efca0279eb927faebffc38c8382818df67fcd159Adam Cohen 611efca0279eb927faebffc38c8382818df67fcd159Adam Cohen paint.reset(); 612efca0279eb927faebffc38c8382818df67fcd159Adam Cohen paint.setAntiAlias(true); 613efca0279eb927faebffc38c8382818df67fcd159Adam Cohen paint.setColor(Color.argb(255, BG_INTENSITY, BG_INTENSITY, BG_INTENSITY)); 614efca0279eb927faebffc38c8382818df67fcd159Adam Cohen paint.setStyle(Paint.Style.STROKE); 615efca0279eb927faebffc38c8382818df67fcd159Adam Cohen paint.setStrokeWidth(mStrokeWidth); 616efca0279eb927faebffc38c8382818df67fcd159Adam Cohen 617efca0279eb927faebffc38c8382818df67fcd159Adam Cohen float radius = getScaledRadius(); 618efca0279eb927faebffc38c8382818df67fcd159Adam Cohen canvas.drawCircle(radius, radius, radius - 1, paint); 619efca0279eb927faebffc38c8382818df67fcd159Adam Cohen 620efca0279eb927faebffc38c8382818df67fcd159Adam Cohen canvas.restore(); 621efca0279eb927faebffc38c8382818df67fcd159Adam Cohen } 622efca0279eb927faebffc38c8382818df67fcd159Adam Cohen 623efca0279eb927faebffc38c8382818df67fcd159Adam Cohen public void drawLeaveBehind(Canvas canvas, Paint paint) { 624efca0279eb927faebffc38c8382818df67fcd159Adam Cohen float originalScale = mScale; 625efca0279eb927faebffc38c8382818df67fcd159Adam Cohen mScale = 0.5f; 626efca0279eb927faebffc38c8382818df67fcd159Adam Cohen 627efca0279eb927faebffc38c8382818df67fcd159Adam Cohen canvas.save(); 628efca0279eb927faebffc38c8382818df67fcd159Adam Cohen canvas.translate(getOffsetX(), getOffsetY()); 629efca0279eb927faebffc38c8382818df67fcd159Adam Cohen 630efca0279eb927faebffc38c8382818df67fcd159Adam Cohen paint.reset(); 631efca0279eb927faebffc38c8382818df67fcd159Adam Cohen paint.setAntiAlias(true); 632efca0279eb927faebffc38c8382818df67fcd159Adam Cohen paint.setColor(Color.argb(160, 245, 245, 245)); 633efca0279eb927faebffc38c8382818df67fcd159Adam Cohen 634efca0279eb927faebffc38c8382818df67fcd159Adam Cohen float radius = getScaledRadius(); 635efca0279eb927faebffc38c8382818df67fcd159Adam Cohen canvas.drawCircle(radius, radius, radius, paint); 636efca0279eb927faebffc38c8382818df67fcd159Adam Cohen 637efca0279eb927faebffc38c8382818df67fcd159Adam Cohen canvas.restore(); 638efca0279eb927faebffc38c8382818df67fcd159Adam Cohen mScale = originalScale; 639efca0279eb927faebffc38c8382818df67fcd159Adam Cohen } 640efca0279eb927faebffc38c8382818df67fcd159Adam Cohen 641efca0279eb927faebffc38c8382818df67fcd159Adam Cohen // It is the callers responsibility to save and restore the canvas. 642efca0279eb927faebffc38c8382818df67fcd159Adam Cohen private void clipCanvas(Canvas canvas) { 643efca0279eb927faebffc38c8382818df67fcd159Adam Cohen canvas.translate(getOffsetX(), getOffsetY()); 644efca0279eb927faebffc38c8382818df67fcd159Adam Cohen canvas.clipPath(mClipPath); 645efca0279eb927faebffc38c8382818df67fcd159Adam Cohen canvas.translate(-getOffsetX(), -getOffsetY()); 646efca0279eb927faebffc38c8382818df67fcd159Adam Cohen } 647efca0279eb927faebffc38c8382818df67fcd159Adam Cohen 648efca0279eb927faebffc38c8382818df67fcd159Adam Cohen private void delegateDrawing(CellLayout delegate, int cellX, int cellY) { 649efca0279eb927faebffc38c8382818df67fcd159Adam Cohen if (mDrawingDelegate != delegate) { 650efca0279eb927faebffc38c8382818df67fcd159Adam Cohen delegate.addFolderBackground(this); 651efca0279eb927faebffc38c8382818df67fcd159Adam Cohen } 652efca0279eb927faebffc38c8382818df67fcd159Adam Cohen 653efca0279eb927faebffc38c8382818df67fcd159Adam Cohen mDrawingDelegate = delegate; 654efca0279eb927faebffc38c8382818df67fcd159Adam Cohen delegateCellX = cellX; 655efca0279eb927faebffc38c8382818df67fcd159Adam Cohen delegateCellY = cellY; 656efca0279eb927faebffc38c8382818df67fcd159Adam Cohen 657efca0279eb927faebffc38c8382818df67fcd159Adam Cohen invalidate(); 658efca0279eb927faebffc38c8382818df67fcd159Adam Cohen } 659efca0279eb927faebffc38c8382818df67fcd159Adam Cohen 660efca0279eb927faebffc38c8382818df67fcd159Adam Cohen private void clearDrawingDelegate() { 661efca0279eb927faebffc38c8382818df67fcd159Adam Cohen if (mDrawingDelegate != null) { 662efca0279eb927faebffc38c8382818df67fcd159Adam Cohen mDrawingDelegate.removeFolderBackground(this); 663efca0279eb927faebffc38c8382818df67fcd159Adam Cohen } 664efca0279eb927faebffc38c8382818df67fcd159Adam Cohen 665efca0279eb927faebffc38c8382818df67fcd159Adam Cohen mDrawingDelegate = null; 666efca0279eb927faebffc38c8382818df67fcd159Adam Cohen invalidate(); 667efca0279eb927faebffc38c8382818df67fcd159Adam Cohen } 668efca0279eb927faebffc38c8382818df67fcd159Adam Cohen 669efca0279eb927faebffc38c8382818df67fcd159Adam Cohen private boolean drawingDelegated() { 670efca0279eb927faebffc38c8382818df67fcd159Adam Cohen return mDrawingDelegate != null; 671efca0279eb927faebffc38c8382818df67fcd159Adam Cohen } 672efca0279eb927faebffc38c8382818df67fcd159Adam Cohen 673efca0279eb927faebffc38c8382818df67fcd159Adam Cohen private void animateScale(float finalScale, float finalMultiplier, 674efca0279eb927faebffc38c8382818df67fcd159Adam Cohen final Runnable onStart, final Runnable onEnd) { 675efca0279eb927faebffc38c8382818df67fcd159Adam Cohen final float scale0 = mScale; 676efca0279eb927faebffc38c8382818df67fcd159Adam Cohen final float scale1 = finalScale; 677efca0279eb927faebffc38c8382818df67fcd159Adam Cohen 678efca0279eb927faebffc38c8382818df67fcd159Adam Cohen final float bgMultiplier0 = mColorMultiplier; 679efca0279eb927faebffc38c8382818df67fcd159Adam Cohen final float bgMultiplier1 = finalMultiplier; 680efca0279eb927faebffc38c8382818df67fcd159Adam Cohen 681efca0279eb927faebffc38c8382818df67fcd159Adam Cohen if (mScaleAnimator != null) { 682efca0279eb927faebffc38c8382818df67fcd159Adam Cohen mScaleAnimator.cancel(); 683efca0279eb927faebffc38c8382818df67fcd159Adam Cohen } 684efca0279eb927faebffc38c8382818df67fcd159Adam Cohen 685efca0279eb927faebffc38c8382818df67fcd159Adam Cohen mScaleAnimator = LauncherAnimUtils.ofFloat(null, 0f, 1.0f); 686efca0279eb927faebffc38c8382818df67fcd159Adam Cohen 687efca0279eb927faebffc38c8382818df67fcd159Adam Cohen mScaleAnimator.addUpdateListener(new AnimatorUpdateListener() { 688efca0279eb927faebffc38c8382818df67fcd159Adam Cohen @Override 689efca0279eb927faebffc38c8382818df67fcd159Adam Cohen public void onAnimationUpdate(ValueAnimator animation) { 690efca0279eb927faebffc38c8382818df67fcd159Adam Cohen float prog = animation.getAnimatedFraction(); 691efca0279eb927faebffc38c8382818df67fcd159Adam Cohen mScale = prog * scale1 + (1 - prog) * scale0; 692efca0279eb927faebffc38c8382818df67fcd159Adam Cohen mColorMultiplier = prog * bgMultiplier1 + (1 - prog) * bgMultiplier0; 693efca0279eb927faebffc38c8382818df67fcd159Adam Cohen invalidate(); 694efca0279eb927faebffc38c8382818df67fcd159Adam Cohen } 695efca0279eb927faebffc38c8382818df67fcd159Adam Cohen }); 696efca0279eb927faebffc38c8382818df67fcd159Adam Cohen mScaleAnimator.addListener(new AnimatorListenerAdapter() { 697efca0279eb927faebffc38c8382818df67fcd159Adam Cohen @Override 698efca0279eb927faebffc38c8382818df67fcd159Adam Cohen public void onAnimationStart(Animator animation) { 699efca0279eb927faebffc38c8382818df67fcd159Adam Cohen if (onStart != null) { 700efca0279eb927faebffc38c8382818df67fcd159Adam Cohen onStart.run(); 701efca0279eb927faebffc38c8382818df67fcd159Adam Cohen } 702efca0279eb927faebffc38c8382818df67fcd159Adam Cohen } 703efca0279eb927faebffc38c8382818df67fcd159Adam Cohen 704efca0279eb927faebffc38c8382818df67fcd159Adam Cohen @Override 705efca0279eb927faebffc38c8382818df67fcd159Adam Cohen public void onAnimationEnd(Animator animation) { 706efca0279eb927faebffc38c8382818df67fcd159Adam Cohen if (onEnd != null) { 707efca0279eb927faebffc38c8382818df67fcd159Adam Cohen onEnd.run(); 708efca0279eb927faebffc38c8382818df67fcd159Adam Cohen } 709efca0279eb927faebffc38c8382818df67fcd159Adam Cohen mScaleAnimator = null; 710efca0279eb927faebffc38c8382818df67fcd159Adam Cohen } 711efca0279eb927faebffc38c8382818df67fcd159Adam Cohen }); 712efca0279eb927faebffc38c8382818df67fcd159Adam Cohen 713efca0279eb927faebffc38c8382818df67fcd159Adam Cohen mScaleAnimator.setDuration(CONSUMPTION_ANIMATION_DURATION); 714efca0279eb927faebffc38c8382818df67fcd159Adam Cohen mScaleAnimator.start(); 715efca0279eb927faebffc38c8382818df67fcd159Adam Cohen } 716efca0279eb927faebffc38c8382818df67fcd159Adam Cohen 717efca0279eb927faebffc38c8382818df67fcd159Adam Cohen public void animateToAccept(final CellLayout cl, final int cellX, final int cellY) { 718efca0279eb927faebffc38c8382818df67fcd159Adam Cohen Runnable onStart = new Runnable() { 719efca0279eb927faebffc38c8382818df67fcd159Adam Cohen @Override 720efca0279eb927faebffc38c8382818df67fcd159Adam Cohen public void run() { 721efca0279eb927faebffc38c8382818df67fcd159Adam Cohen delegateDrawing(cl, cellX, cellY); 722efca0279eb927faebffc38c8382818df67fcd159Adam Cohen } 723efca0279eb927faebffc38c8382818df67fcd159Adam Cohen }; 724efca0279eb927faebffc38c8382818df67fcd159Adam Cohen animateScale(ACCEPT_SCALE_FACTOR, ACCEPT_COLOR_MULTIPLIER, onStart, null); 725efca0279eb927faebffc38c8382818df67fcd159Adam Cohen } 726efca0279eb927faebffc38c8382818df67fcd159Adam Cohen 727efca0279eb927faebffc38c8382818df67fcd159Adam Cohen public void animateToRest() { 728efca0279eb927faebffc38c8382818df67fcd159Adam Cohen // This can be called multiple times -- we need to make sure the drawing delegate 729efca0279eb927faebffc38c8382818df67fcd159Adam Cohen // is saved and restored at the beginning of the animation, since cancelling the 730efca0279eb927faebffc38c8382818df67fcd159Adam Cohen // existing animation can clear the delgate. 731efca0279eb927faebffc38c8382818df67fcd159Adam Cohen final CellLayout cl = mDrawingDelegate; 732efca0279eb927faebffc38c8382818df67fcd159Adam Cohen final int cellX = delegateCellX; 733efca0279eb927faebffc38c8382818df67fcd159Adam Cohen final int cellY = delegateCellY; 734efca0279eb927faebffc38c8382818df67fcd159Adam Cohen 735efca0279eb927faebffc38c8382818df67fcd159Adam Cohen Runnable onStart = new Runnable() { 736efca0279eb927faebffc38c8382818df67fcd159Adam Cohen @Override 737efca0279eb927faebffc38c8382818df67fcd159Adam Cohen public void run() { 738efca0279eb927faebffc38c8382818df67fcd159Adam Cohen delegateDrawing(cl, cellX, cellY); 739efca0279eb927faebffc38c8382818df67fcd159Adam Cohen } 740efca0279eb927faebffc38c8382818df67fcd159Adam Cohen }; 741efca0279eb927faebffc38c8382818df67fcd159Adam Cohen Runnable onEnd = new Runnable() { 742efca0279eb927faebffc38c8382818df67fcd159Adam Cohen @Override 743efca0279eb927faebffc38c8382818df67fcd159Adam Cohen public void run() { 744efca0279eb927faebffc38c8382818df67fcd159Adam Cohen clearDrawingDelegate(); 745efca0279eb927faebffc38c8382818df67fcd159Adam Cohen } 746efca0279eb927faebffc38c8382818df67fcd159Adam Cohen }; 747efca0279eb927faebffc38c8382818df67fcd159Adam Cohen animateScale(1f, 1f, onStart, onEnd); 748efca0279eb927faebffc38c8382818df67fcd159Adam Cohen } 749efca0279eb927faebffc38c8382818df67fcd159Adam Cohen } 750efca0279eb927faebffc38c8382818df67fcd159Adam Cohen 751efca0279eb927faebffc38c8382818df67fcd159Adam Cohen public void setFolderBackground(PreviewBackground bg) { 752efca0279eb927faebffc38c8382818df67fcd159Adam Cohen mBackground = bg; 753f172b747c24f28e29baaaf58f08bab48847b7a40Adam Cohen mBackground.setInvalidateDelegate(this); 754efca0279eb927faebffc38c8382818df67fcd159Adam Cohen } 755efca0279eb927faebffc38c8382818df67fcd159Adam Cohen 756d044526d82e7938cf35b296978d9d5302f98b4afAdam Cohen @Override 757d044526d82e7938cf35b296978d9d5302f98b4afAdam Cohen protected void dispatchDraw(Canvas canvas) { 758d044526d82e7938cf35b296978d9d5302f98b4afAdam Cohen super.dispatchDraw(canvas); 759badf71e11fba2d6efa1d1bcca9542001f90a3777Adam Cohen 7604f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen if (mReferenceDrawable != null) { 7614f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen computePreviewDrawingParams(mReferenceDrawable); 762d044526d82e7938cf35b296978d9d5302f98b4afAdam Cohen } 763a9cf38f533d1e86269868f1e6a806ccffd4a78fcAdam Cohen 764efca0279eb927faebffc38c8382818df67fcd159Adam Cohen if (!mBackground.drawingDelegated()) { 765efca0279eb927faebffc38c8382818df67fcd159Adam Cohen mBackground.drawBackground(canvas, mBgPaint); 766efca0279eb927faebffc38c8382818df67fcd159Adam Cohen } 767efca0279eb927faebffc38c8382818df67fcd159Adam Cohen 768efca0279eb927faebffc38c8382818df67fcd159Adam Cohen if (mFolder == null) return; 769efca0279eb927faebffc38c8382818df67fcd159Adam Cohen if (mFolder.getItemCount() == 0 && !mAnimating) return; 770efca0279eb927faebffc38c8382818df67fcd159Adam Cohen 771119e8982ab6a0cf00e31e8744f27b72ba8bf7b20Adam Cohen canvas.save(); 772efca0279eb927faebffc38c8382818df67fcd159Adam Cohen 773efca0279eb927faebffc38c8382818df67fcd159Adam Cohen 774efca0279eb927faebffc38c8382818df67fcd159Adam Cohen if (mPreviewLayoutRule.clipToBackground()) { 775efca0279eb927faebffc38c8382818df67fcd159Adam Cohen mBackground.clipCanvas(canvas); 776119e8982ab6a0cf00e31e8744f27b72ba8bf7b20Adam Cohen } 777119e8982ab6a0cf00e31e8744f27b72ba8bf7b20Adam Cohen 778efca0279eb927faebffc38c8382818df67fcd159Adam Cohen // The items are drawn in coordinates relative to the preview offset 779efca0279eb927faebffc38c8382818df67fcd159Adam Cohen canvas.translate(mBackground.basePreviewOffsetX, mBackground.basePreviewOffsetY); 780efca0279eb927faebffc38c8382818df67fcd159Adam Cohen 7814f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen // The first item should be drawn last (ie. on top of later items) 7824f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen for (int i = mDrawingParams.size() - 1; i >= 0; i--) { 7834f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen PreviewItemDrawingParams p = mDrawingParams.get(i); 7844f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen if (!p.hidden) { 7854f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen drawPreviewItem(canvas, p); 786a9cf38f533d1e86269868f1e6a806ccffd4a78fcAdam Cohen } 787a9cf38f533d1e86269868f1e6a806ccffd4a78fcAdam Cohen } 788119e8982ab6a0cf00e31e8744f27b72ba8bf7b20Adam Cohen canvas.restore(); 789efca0279eb927faebffc38c8382818df67fcd159Adam Cohen 790efca0279eb927faebffc38c8382818df67fcd159Adam Cohen if (mPreviewLayoutRule.clipToBackground() && !mBackground.drawingDelegated()) { 791efca0279eb927faebffc38c8382818df67fcd159Adam Cohen mBackground.drawBackgroundStroke(canvas, mBgPaint); 792efca0279eb927faebffc38c8382818df67fcd159Adam Cohen } 793d044526d82e7938cf35b296978d9d5302f98b4afAdam Cohen } 794d044526d82e7938cf35b296978d9d5302f98b4afAdam Cohen 7953484638cad97e255a412b0489a63873fb3ca4218Sunny Goyal private Drawable getTopDrawable(TextView v) { 7963484638cad97e255a412b0489a63873fb3ca4218Sunny Goyal Drawable d = v.getCompoundDrawables()[1]; 7973484638cad97e255a412b0489a63873fb3ca4218Sunny Goyal return (d instanceof PreloadIconDrawable) ? ((PreloadIconDrawable) d).mIcon : d; 7983484638cad97e255a412b0489a63873fb3ca4218Sunny Goyal } 7993484638cad97e255a412b0489a63873fb3ca4218Sunny Goyal 8004f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen class FolderPreviewItemAnim { 8014f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen ValueAnimator mValueAnimator; 8024f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen float finalScale; 8034f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen float finalTransX; 8044f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen float finalTransY; 8054f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen 8064f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen /** 8074f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen * 8084f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen * @param params layout params to animate 8094f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen * @param index0 original index of the item to be animated 8104f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen * @param nItems0 original number of items in the preview 8114f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen * @param index1 new index of the item to be animated 8124f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen * @param nItems1 new number of items in the preview 8134f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen * @param duration duration in ms of the animation 8144f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen * @param onCompleteRunnable runnable to execute upon animation completion 8154f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen */ 8164f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen public FolderPreviewItemAnim(final PreviewItemDrawingParams params, int index0, int nItems0, 8174f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen int index1, int nItems1, int duration, final Runnable onCompleteRunnable) { 8184f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen 8194f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen computePreviewItemDrawingParams(index1, nItems1, mTmpParams); 8204f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen 8214f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen finalScale = mTmpParams.scale; 8224f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen finalTransX = mTmpParams.transX; 8234f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen finalTransY = mTmpParams.transY; 8244f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen 8254f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen computePreviewItemDrawingParams(index0, nItems0, mTmpParams); 8264f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen 8274f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen final float scale0 = mTmpParams.scale; 8284f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen final float transX0 = mTmpParams.transX; 8294f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen final float transY0 = mTmpParams.transY; 8304f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen 8314f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen mValueAnimator = LauncherAnimUtils.ofFloat(FolderIcon.this, 0f, 1.0f); 8324f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen mValueAnimator.addUpdateListener(new AnimatorUpdateListener(){ 8334f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen public void onAnimationUpdate(ValueAnimator animation) { 8344f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen float progress = animation.getAnimatedFraction(); 835119e8982ab6a0cf00e31e8744f27b72ba8bf7b20Adam Cohen 8364f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen params.transX = transX0 + progress * (finalTransX - transX0); 8374f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen params.transY = transY0 + progress * (finalTransY - transY0); 8384f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen params.scale = scale0 + progress * (finalScale - scale0); 8394f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen invalidate(); 8404f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen } 8414f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen }); 842d044526d82e7938cf35b296978d9d5302f98b4afAdam Cohen 8434f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen mValueAnimator.addListener(new AnimatorListenerAdapter() { 8444f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen @Override 8454f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen public void onAnimationStart(Animator animation) { 846fb91f303f5e672f9b4c4f9f8a03486b224d60cd6Adam Cohen } 847d044526d82e7938cf35b296978d9d5302f98b4afAdam Cohen 8484f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen @Override 8494f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen public void onAnimationEnd(Animator animation) { 8504f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen if (onCompleteRunnable != null) { 8514f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen onCompleteRunnable.run(); 8524f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen } 8534f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen params.anim = null; 854fb91f303f5e672f9b4c4f9f8a03486b224d60cd6Adam Cohen } 8554f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen }); 8564f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen mValueAnimator.setDuration(duration); 8574f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen } 8584f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen 8594f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen public void start() { 8604f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen mValueAnimator.start(); 8614f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen } 8624f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen 8634f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen public void cancel() { 8644f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen mValueAnimator.cancel(); 8654f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen } 8664f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen 8674f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen public boolean hasEqualFinalState(FolderPreviewItemAnim anim) { 8684f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen return finalTransY == anim.finalTransY && finalTransX == anim.finalTransX && 8694f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen finalScale == anim.finalScale; 8704f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen 8714f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen } 8724f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen } 8734f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen 8744f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen private void animateFirstItem(final Drawable d, int duration, final boolean reverse, 8754f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen final Runnable onCompleteRunnable) { 8764f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen 8774f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen FolderPreviewItemAnim anim; 8784f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen if (!reverse) { 8794f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen anim = new FolderPreviewItemAnim(mDrawingParams.get(0), -1, -1, 0, 2, duration, 8804f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen onCompleteRunnable); 8814f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen } else { 8824f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen anim = new FolderPreviewItemAnim(mDrawingParams.get(0), 0, 2, -1, -1, duration, 8834f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen onCompleteRunnable); 8844f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen } 8854f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen anim.start(); 886a9cf38f533d1e86269868f1e6a806ccffd4a78fcAdam Cohen } 887a9cf38f533d1e86269868f1e6a806ccffd4a78fcAdam Cohen 888099f60d51f6310e1290687e83958e665b3324504Adam Cohen public void setTextVisible(boolean visible) { 889099f60d51f6310e1290687e83958e665b3324504Adam Cohen if (visible) { 890099f60d51f6310e1290687e83958e665b3324504Adam Cohen mFolderName.setVisibility(VISIBLE); 891099f60d51f6310e1290687e83958e665b3324504Adam Cohen } else { 892099f60d51f6310e1290687e83958e665b3324504Adam Cohen mFolderName.setVisibility(INVISIBLE); 893099f60d51f6310e1290687e83958e665b3324504Adam Cohen } 894099f60d51f6310e1290687e83958e665b3324504Adam Cohen } 895099f60d51f6310e1290687e83958e665b3324504Adam Cohen 896099f60d51f6310e1290687e83958e665b3324504Adam Cohen public boolean getTextVisible() { 897099f60d51f6310e1290687e83958e665b3324504Adam Cohen return mFolderName.getVisibility() == VISIBLE; 898099f60d51f6310e1290687e83958e665b3324504Adam Cohen } 899099f60d51f6310e1290687e83958e665b3324504Adam Cohen 9004f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen private void updateItemDrawingParams(boolean animate) { 9014f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen ArrayList<View> items = mFolder.getItemsInReadingOrder(); 9024f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen int nItemsInPreview = Math.min(items.size(), mPreviewLayoutRule.numItems()); 9034f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen 9044f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen int prevNumItems = mDrawingParams.size(); 9054f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen 9064f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen // We adjust the size of the list to match the number of items in the preview 9074f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen while (nItemsInPreview < mDrawingParams.size()) { 9084f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen mDrawingParams.remove(mDrawingParams.size() - 1); 9094f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen } 9104f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen while (nItemsInPreview > mDrawingParams.size()) { 9114f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen mDrawingParams.add(new PreviewItemDrawingParams(0, 0, 0, 0)); 9124f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen } 9134f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen 9144f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen for (int i = 0; i < mDrawingParams.size(); i++) { 9154f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen PreviewItemDrawingParams p = mDrawingParams.get(i); 9164f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen p.drawable = getTopDrawable((TextView) items.get(i)); 9174f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen 918efca0279eb927faebffc38c8382818df67fcd159Adam Cohen if (!animate || FeatureFlags.LAUNCHER3_LEGACY_FOLDER_ICON) { 9194f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen computePreviewItemDrawingParams(i, nItemsInPreview, p); 9204f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen if (mReferenceDrawable == null) { 9214f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen mReferenceDrawable = p.drawable; 9224f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen } 9234f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen } else { 9244f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen FolderPreviewItemAnim anim = new FolderPreviewItemAnim(p, i, prevNumItems, i, 9254f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen nItemsInPreview, DROP_IN_ANIMATION_DURATION, null); 9264f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen 9274f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen if (p.anim != null) { 9284f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen if (p.anim.hasEqualFinalState(anim)) { 9294f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen // do nothing, let the current animation finish 9304f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen continue; 9314f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen } 9324f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen p.anim.cancel(); 9334f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen } 9344f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen p.anim = anim; 9354f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen p.anim.start(); 9364f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen } 9374f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen } 9384f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen } 9394f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen 94076078c4ef35b6e95fb6d8129a32cf52a36625e28Adam Cohen public void onItemsChanged() { 9414f8071b759fd54bc6d271ea450af00fe0730baeaAdam Cohen updateItemDrawingParams(true); 94276078c4ef35b6e95fb6d8129a32cf52a36625e28Adam Cohen invalidate(); 94376078c4ef35b6e95fb6d8129a32cf52a36625e28Adam Cohen requestLayout(); 94476078c4ef35b6e95fb6d8129a32cf52a36625e28Adam Cohen } 94576078c4ef35b6e95fb6d8129a32cf52a36625e28Adam Cohen 946a9cf38f533d1e86269868f1e6a806ccffd4a78fcAdam Cohen public void onAdd(ShortcutInfo item) { 947a9cf38f533d1e86269868f1e6a806ccffd4a78fcAdam Cohen invalidate(); 948a9cf38f533d1e86269868f1e6a806ccffd4a78fcAdam Cohen requestLayout(); 949a9cf38f533d1e86269868f1e6a806ccffd4a78fcAdam Cohen } 950a9cf38f533d1e86269868f1e6a806ccffd4a78fcAdam Cohen 951a9cf38f533d1e86269868f1e6a806ccffd4a78fcAdam Cohen public void onRemove(ShortcutInfo item) { 952a9cf38f533d1e86269868f1e6a806ccffd4a78fcAdam Cohen invalidate(); 953a9cf38f533d1e86269868f1e6a806ccffd4a78fcAdam Cohen requestLayout(); 954a9cf38f533d1e86269868f1e6a806ccffd4a78fcAdam Cohen } 95576fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen 95676fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen public void onTitleChanged(CharSequence title) { 95782b016cb56540fe26213e817dd0dd668099c8e20Winson Chung mFolderName.setText(title); 958f4f89ef608245d39bbddda05f291361d2ae06667Sunny Goyal setContentDescription(getContext().getString(R.string.folder_name_format, title)); 95976fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen } 96088f334571fe41df620ba903ced9b2c69b0170d5cWinson Chung 96188f334571fe41df620ba903ced9b2c69b0170d5cWinson Chung @Override 96288f334571fe41df620ba903ced9b2c69b0170d5cWinson Chung public boolean onTouchEvent(MotionEvent event) { 96388f334571fe41df620ba903ced9b2c69b0170d5cWinson Chung // Call the superclass onTouchEvent first, because sometimes it changes the state to 96488f334571fe41df620ba903ced9b2c69b0170d5cWinson Chung // isPressed() on an ACTION_UP 96588f334571fe41df620ba903ced9b2c69b0170d5cWinson Chung boolean result = super.onTouchEvent(event); 96688f334571fe41df620ba903ced9b2c69b0170d5cWinson Chung 967ef044dd380ac3abf354027750efdc16d5d48ac70Mady Mellor // Check for a stylus button press, if it occurs cancel any long press checks. 968bb83520a620919a8f19472ba4426585d007d1abaMady Mellor if (mStylusEventHelper.onMotionEvent(event)) { 969ef044dd380ac3abf354027750efdc16d5d48ac70Mady Mellor mLongPressHelper.cancelLongPress(); 970ef044dd380ac3abf354027750efdc16d5d48ac70Mady Mellor return true; 971ef044dd380ac3abf354027750efdc16d5d48ac70Mady Mellor } 972ef044dd380ac3abf354027750efdc16d5d48ac70Mady Mellor 97388f334571fe41df620ba903ced9b2c69b0170d5cWinson Chung switch (event.getAction()) { 97488f334571fe41df620ba903ced9b2c69b0170d5cWinson Chung case MotionEvent.ACTION_DOWN: 97588f334571fe41df620ba903ced9b2c69b0170d5cWinson Chung mLongPressHelper.postCheckForLongPress(); 97688f334571fe41df620ba903ced9b2c69b0170d5cWinson Chung break; 97788f334571fe41df620ba903ced9b2c69b0170d5cWinson Chung case MotionEvent.ACTION_CANCEL: 97888f334571fe41df620ba903ced9b2c69b0170d5cWinson Chung case MotionEvent.ACTION_UP: 97988f334571fe41df620ba903ced9b2c69b0170d5cWinson Chung mLongPressHelper.cancelLongPress(); 98088f334571fe41df620ba903ced9b2c69b0170d5cWinson Chung break; 98102dd7aea3d8ac94126a8f8069e6762592ea60326Jason Monk case MotionEvent.ACTION_MOVE: 98202dd7aea3d8ac94126a8f8069e6762592ea60326Jason Monk if (!Utilities.pointInView(this, event.getX(), event.getY(), mSlop)) { 98302dd7aea3d8ac94126a8f8069e6762592ea60326Jason Monk mLongPressHelper.cancelLongPress(); 98402dd7aea3d8ac94126a8f8069e6762592ea60326Jason Monk } 98502dd7aea3d8ac94126a8f8069e6762592ea60326Jason Monk break; 98688f334571fe41df620ba903ced9b2c69b0170d5cWinson Chung } 98788f334571fe41df620ba903ced9b2c69b0170d5cWinson Chung return result; 98888f334571fe41df620ba903ced9b2c69b0170d5cWinson Chung } 98988f334571fe41df620ba903ced9b2c69b0170d5cWinson Chung 99088f334571fe41df620ba903ced9b2c69b0170d5cWinson Chung @Override 99102dd7aea3d8ac94126a8f8069e6762592ea60326Jason Monk protected void onAttachedToWindow() { 99202dd7aea3d8ac94126a8f8069e6762592ea60326Jason Monk super.onAttachedToWindow(); 99302dd7aea3d8ac94126a8f8069e6762592ea60326Jason Monk mSlop = ViewConfiguration.get(getContext()).getScaledTouchSlop(); 99402dd7aea3d8ac94126a8f8069e6762592ea60326Jason Monk } 99502dd7aea3d8ac94126a8f8069e6762592ea60326Jason Monk 99602dd7aea3d8ac94126a8f8069e6762592ea60326Jason Monk @Override 99788f334571fe41df620ba903ced9b2c69b0170d5cWinson Chung public void cancelLongPress() { 99888f334571fe41df620ba903ced9b2c69b0170d5cWinson Chung super.cancelLongPress(); 99988f334571fe41df620ba903ced9b2c69b0170d5cWinson Chung mLongPressHelper.cancelLongPress(); 100088f334571fe41df620ba903ced9b2c69b0170d5cWinson Chung } 1001f9c184a619e4e4b82cf9e0bf318ca6d8deaaaee7Adam Cohen 1002f9c184a619e4e4b82cf9e0bf318ca6d8deaaaee7Adam Cohen public interface PreviewLayoutRule { 1003119e8982ab6a0cf00e31e8744f27b72ba8bf7b20Adam Cohen public PreviewItemDrawingParams computePreviewItemDrawingParams(int index, int curNumItems, 1004f9c184a619e4e4b82cf9e0bf318ca6d8deaaaee7Adam Cohen PreviewItemDrawingParams params); 1005f9c184a619e4e4b82cf9e0bf318ca6d8deaaaee7Adam Cohen 1006119e8982ab6a0cf00e31e8744f27b72ba8bf7b20Adam Cohen public void init(int availableSpace, int intrinsicIconSize, boolean rtl); 1007f9c184a619e4e4b82cf9e0bf318ca6d8deaaaee7Adam Cohen 1008f9c184a619e4e4b82cf9e0bf318ca6d8deaaaee7Adam Cohen public int numItems(); 1009efca0279eb927faebffc38c8382818df67fcd159Adam Cohen public boolean clipToBackground(); 1010f9c184a619e4e4b82cf9e0bf318ca6d8deaaaee7Adam Cohen } 101131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project} 1012