FolderIcon.java revision badf71e11fba2d6efa1d1bcca9542001f90a3777
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 17a5902524d4403885eb4c50360bf3465c6be796efJoe Onoratopackage com.android.launcher2; 1831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 197c6932140dcbd2db88d7a809ba72ee04abb5bf26Adam Cohenimport java.util.ArrayList; 207c6932140dcbd2db88d7a809ba72ee04abb5bf26Adam Cohen 212801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohenimport android.animation.Animator; 222801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohenimport android.animation.AnimatorListenerAdapter; 232801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohenimport android.animation.ValueAnimator; 242801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohenimport android.animation.ValueAnimator.AnimatorUpdateListener; 2531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.content.Context; 2631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.content.res.Resources; 27a9cf38f533d1e86269868f1e6a806ccffd4a78fcAdam Cohenimport android.graphics.Canvas; 28f4b08913677e18a8412930972237b91d5a946d95Adam Cohenimport android.graphics.Color; 29badf71e11fba2d6efa1d1bcca9542001f90a3777Adam Cohenimport android.graphics.PorterDuff; 3031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.graphics.drawable.Drawable; 3131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.util.AttributeSet; 3231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.view.LayoutInflater; 337c6932140dcbd2db88d7a809ba72ee04abb5bf26Adam Cohenimport android.view.View; 3431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.view.ViewGroup; 35a9cf38f533d1e86269868f1e6a806ccffd4a78fcAdam Cohenimport android.widget.FrameLayout; 36a9cf38f533d1e86269868f1e6a806ccffd4a78fcAdam Cohenimport android.widget.TextView; 3731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 38edcce099c98a6c40d10109ac092ab50f9d2668f3Romain Guyimport com.android.launcher.R; 39a9cf38f533d1e86269868f1e6a806ccffd4a78fcAdam Cohenimport com.android.launcher2.FolderInfo.FolderListener; 40edcce099c98a6c40d10109ac092ab50f9d2668f3Romain Guy 4131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project/** 4231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * An icon that can appear on in the workspace representing an {@link UserFolder}. 4331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project */ 44a9cf38f533d1e86269868f1e6a806ccffd4a78fcAdam Cohenpublic class FolderIcon extends FrameLayout implements DropTarget, FolderListener { 4531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project private Launcher mLauncher; 46a9cf38f533d1e86269868f1e6a806ccffd4a78fcAdam Cohen Folder mFolder; 47a9cf38f533d1e86269868f1e6a806ccffd4a78fcAdam Cohen FolderInfo mInfo; 48a9cf38f533d1e86269868f1e6a806ccffd4a78fcAdam Cohen 49badf71e11fba2d6efa1d1bcca9542001f90a3777Adam Cohen // The number of icons to display in the 50a9cf38f533d1e86269868f1e6a806ccffd4a78fcAdam Cohen private static final int NUM_ITEMS_IN_PREVIEW = 4; 51f4b08913677e18a8412930972237b91d5a946d95Adam Cohen private static final int CONSUMPTION_ANIMATION_DURATION = 100; 52badf71e11fba2d6efa1d1bcca9542001f90a3777Adam Cohen 53badf71e11fba2d6efa1d1bcca9542001f90a3777Adam Cohen // The degree to which the inner ring grows when accepting drop 54073a46ff635d089cbcb15d939d1de42dd2b86c97Adam Cohen private static final float INNER_RING_GROWTH_FACTOR = 0.1f; 55badf71e11fba2d6efa1d1bcca9542001f90a3777Adam Cohen 56badf71e11fba2d6efa1d1bcca9542001f90a3777Adam Cohen // The degree to which the inner ring is scaled in its natural state 57badf71e11fba2d6efa1d1bcca9542001f90a3777Adam Cohen private static final float INNER_RING_BASELINE_SCALE = 1.0f; 58badf71e11fba2d6efa1d1bcca9542001f90a3777Adam Cohen 59badf71e11fba2d6efa1d1bcca9542001f90a3777Adam Cohen // The degree to which the outer ring grows when accepting drop 60073a46ff635d089cbcb15d939d1de42dd2b86c97Adam Cohen private static final float OUTER_RING_BASELINE_SCALE = 0.7f; 61badf71e11fba2d6efa1d1bcca9542001f90a3777Adam Cohen 62badf71e11fba2d6efa1d1bcca9542001f90a3777Adam Cohen // The degree to which the outer ring is scaled in its natural state 63073a46ff635d089cbcb15d939d1de42dd2b86c97Adam Cohen private static final float OUTER_RING_GROWTH_FACTOR = 0.3f; 64badf71e11fba2d6efa1d1bcca9542001f90a3777Adam Cohen 65badf71e11fba2d6efa1d1bcca9542001f90a3777Adam Cohen // The amount of vertical spread between items in the stack [0...1] 66badf71e11fba2d6efa1d1bcca9542001f90a3777Adam Cohen private static final float PERSPECTIVE_SHIFT_FACTOR = 0.18f; 67badf71e11fba2d6efa1d1bcca9542001f90a3777Adam Cohen 68badf71e11fba2d6efa1d1bcca9542001f90a3777Adam Cohen // The degree to which the item in the back of the stack is scaled [0...1] 69badf71e11fba2d6efa1d1bcca9542001f90a3777Adam Cohen // (0 means it's not scaled at all, 1 means it's scaled to nothing) 70badf71e11fba2d6efa1d1bcca9542001f90a3777Adam Cohen private static final float PERSPECTIVE_SCALE_FACTOR = 0.3f; 71badf71e11fba2d6efa1d1bcca9542001f90a3777Adam Cohen 72badf71e11fba2d6efa1d1bcca9542001f90a3777Adam Cohen // The percentage of the FolderIcons view that will be dedicated to the items preview 73badf71e11fba2d6efa1d1bcca9542001f90a3777Adam Cohen private static final float SPACE_PERCENTAGE_FOR_ICONS = 0.8f; 7431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 75073a46ff635d089cbcb15d939d1de42dd2b86c97Adam Cohen public static Drawable sFolderOuterRingDrawable = null; 76f4b08913677e18a8412930972237b91d5a946d95Adam Cohen public static Drawable sFolderInnerRingDrawable = null; 77073a46ff635d089cbcb15d939d1de42dd2b86c97Adam Cohen 78073a46ff635d089cbcb15d939d1de42dd2b86c97Adam Cohen private int mOriginalWidth = -1; 79073a46ff635d089cbcb15d939d1de42dd2b86c97Adam Cohen private int mOriginalHeight = -1; 80073a46ff635d089cbcb15d939d1de42dd2b86c97Adam Cohen 81073a46ff635d089cbcb15d939d1de42dd2b86c97Adam Cohen private int mFolderLocX; 82073a46ff635d089cbcb15d939d1de42dd2b86c97Adam Cohen private int mFolderLocY; 83073a46ff635d089cbcb15d939d1de42dd2b86c97Adam Cohen private float mOuterRingScale; 84f4b08913677e18a8412930972237b91d5a946d95Adam Cohen private float mInnerRingScale; 852801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen 8631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project public FolderIcon(Context context, AttributeSet attrs) { 8731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project super(context, attrs); 8831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 8931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 9031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project public FolderIcon(Context context) { 9131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project super(context); 9231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 9331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 940280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka public boolean isDropEnabled() { 957a1d16555d80135e61b90158ff3c1e3f963bd8b8Winson Chung final ViewGroup cellLayoutChildren = (ViewGroup) getParent(); 967a1d16555d80135e61b90158ff3c1e3f963bd8b8Winson Chung final ViewGroup cellLayout = (ViewGroup) cellLayoutChildren.getParent(); 977a1d16555d80135e61b90158ff3c1e3f963bd8b8Winson Chung final Workspace workspace = (Workspace) cellLayout.getParent(); 987a1d16555d80135e61b90158ff3c1e3f963bd8b8Winson Chung return !workspace.isSmall(); 990280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka } 1000280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka 10131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project static FolderIcon fromXml(int resId, Launcher launcher, ViewGroup group, 102df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen FolderInfo folderInfo, IconCache iconCache) { 10331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 10431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project FolderIcon icon = (FolderIcon) LayoutInflater.from(launcher).inflate(resId, group, false); 10531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 10631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project final Resources resources = launcher.getResources(); 1072801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen Drawable d = iconCache.getFullResIcon(resources, R.drawable.portal_ring_inner_holo); 108a9cf38f533d1e86269868f1e6a806ccffd4a78fcAdam Cohen icon.setBackgroundDrawable(d); 10931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project icon.setTag(folderInfo); 11031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project icon.setOnClickListener(launcher); 11131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project icon.mInfo = folderInfo; 11231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project icon.mLauncher = launcher; 113a9cf38f533d1e86269868f1e6a806ccffd4a78fcAdam Cohen 114a9cf38f533d1e86269868f1e6a806ccffd4a78fcAdam Cohen Folder folder = Folder.fromXml(launcher); 115a9cf38f533d1e86269868f1e6a806ccffd4a78fcAdam Cohen folder.setDragController(launcher.getDragController()); 116a9cf38f533d1e86269868f1e6a806ccffd4a78fcAdam Cohen folder.setLauncher(launcher); 1172801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen folder.setFolderIcon(icon); 118a9cf38f533d1e86269868f1e6a806ccffd4a78fcAdam Cohen folder.bind(folderInfo); 119a9cf38f533d1e86269868f1e6a806ccffd4a78fcAdam Cohen icon.mFolder = folder; 120a9cf38f533d1e86269868f1e6a806ccffd4a78fcAdam Cohen 121a9cf38f533d1e86269868f1e6a806ccffd4a78fcAdam Cohen folderInfo.addListener(icon); 122073a46ff635d089cbcb15d939d1de42dd2b86c97Adam Cohen if (sFolderOuterRingDrawable == null) { 123073a46ff635d089cbcb15d939d1de42dd2b86c97Adam Cohen sFolderOuterRingDrawable = 124073a46ff635d089cbcb15d939d1de42dd2b86c97Adam Cohen launcher.getResources().getDrawable(R.drawable.portal_ring_outer_holo); 125073a46ff635d089cbcb15d939d1de42dd2b86c97Adam Cohen } 126a9cf38f533d1e86269868f1e6a806ccffd4a78fcAdam Cohen 127f4b08913677e18a8412930972237b91d5a946d95Adam Cohen if (sFolderInnerRingDrawable == null) { 128f4b08913677e18a8412930972237b91d5a946d95Adam Cohen sFolderInnerRingDrawable = 129f4b08913677e18a8412930972237b91d5a946d95Adam Cohen launcher.getResources().getDrawable(R.drawable.portal_ring_inner_holo); 130f4b08913677e18a8412930972237b91d5a946d95Adam Cohen } 13131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project return icon; 13231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 13331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 134073a46ff635d089cbcb15d939d1de42dd2b86c97Adam Cohen private boolean willAcceptItem(ItemInfo item) { 13531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project final int itemType = item.itemType; 1362801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen return ((itemType == LauncherSettings.Favorites.ITEM_TYPE_APPLICATION || 1372801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen itemType == LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT) && 138073a46ff635d089cbcb15d939d1de42dd2b86c97Adam Cohen !mFolder.isFull() && item != mInfo); 139073a46ff635d089cbcb15d939d1de42dd2b86c97Adam Cohen } 140073a46ff635d089cbcb15d939d1de42dd2b86c97Adam Cohen 141cb3382b1bfe1a534b1b44f5c4def9b2db605ac90Adam Cohen public boolean acceptDrop(DragObject d) { 142cb3382b1bfe1a534b1b44f5c4def9b2db605ac90Adam Cohen final ItemInfo item = (ItemInfo) d.dragInfo; 143073a46ff635d089cbcb15d939d1de42dd2b86c97Adam Cohen return willAcceptItem(item); 14431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 14531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 146df0353815c629fc678824b07a234b89a1ff94208Adam Cohen public void addItem(ShortcutInfo item) { 147df0353815c629fc678824b07a234b89a1ff94208Adam Cohen mInfo.add(item); 148a9cf38f533d1e86269868f1e6a806ccffd4a78fcAdam Cohen LauncherModel.addOrMoveItemInDatabase(mLauncher, item, mInfo.id, 0, item.cellX, item.cellY); 149df0353815c629fc678824b07a234b89a1ff94208Adam Cohen } 150df0353815c629fc678824b07a234b89a1ff94208Adam Cohen 151cb3382b1bfe1a534b1b44f5c4def9b2db605ac90Adam Cohen public void onDrop(DragObject d) { 1520589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato ShortcutInfo item; 153cb3382b1bfe1a534b1b44f5c4def9b2db605ac90Adam Cohen if (d.dragInfo instanceof ApplicationInfo) { 1540589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato // Came from all apps -- make a copy 155cb3382b1bfe1a534b1b44f5c4def9b2db605ac90Adam Cohen item = ((ApplicationInfo) d.dragInfo).makeShortcut(); 1560589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato } else { 157cb3382b1bfe1a534b1b44f5c4def9b2db605ac90Adam Cohen item = (ShortcutInfo) d.dragInfo; 1580589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato } 15966d72178af91d455700875635473be942bc90e54Michael Jurka item.cellX = -1; 16066d72178af91d455700875635473be942bc90e54Michael Jurka item.cellY = -1; 161df0353815c629fc678824b07a234b89a1ff94208Adam Cohen addItem(item); 16231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 16331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 1642801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen void saveState(CellLayout.LayoutParams lp) { 1652801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen mOriginalWidth = lp.width; 1662801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen mOriginalHeight = lp.height; 1672801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen } 1682801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen 169073a46ff635d089cbcb15d939d1de42dd2b86c97Adam Cohen private void animateToAcceptState() { 170f4b08913677e18a8412930972237b91d5a946d95Adam Cohen ValueAnimator va = ValueAnimator.ofFloat(0f, 1f); 171f4b08913677e18a8412930972237b91d5a946d95Adam Cohen va.setDuration(CONSUMPTION_ANIMATION_DURATION); 172f4b08913677e18a8412930972237b91d5a946d95Adam Cohen va.addUpdateListener(new AnimatorUpdateListener() { 173073a46ff635d089cbcb15d939d1de42dd2b86c97Adam Cohen public void onAnimationUpdate(ValueAnimator animation) { 174073a46ff635d089cbcb15d939d1de42dd2b86c97Adam Cohen final float percent = (Float) animation.getAnimatedValue(); 175073a46ff635d089cbcb15d939d1de42dd2b86c97Adam Cohen mOuterRingScale = OUTER_RING_BASELINE_SCALE + percent * OUTER_RING_GROWTH_FACTOR; 176f4b08913677e18a8412930972237b91d5a946d95Adam Cohen mInnerRingScale = INNER_RING_BASELINE_SCALE + percent * INNER_RING_GROWTH_FACTOR; 177073a46ff635d089cbcb15d939d1de42dd2b86c97Adam Cohen mLauncher.getWorkspace().invalidate(); 178073a46ff635d089cbcb15d939d1de42dd2b86c97Adam Cohen invalidate(); 1792801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen } 1802801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen }); 181f4b08913677e18a8412930972237b91d5a946d95Adam Cohen va.addListener(new AnimatorListenerAdapter() { 1822801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen @Override 1832801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen public void onAnimationEnd(Animator animation) { 184f4b08913677e18a8412930972237b91d5a946d95Adam Cohen // Instead of setting the background drawable to null, we set the color to 185f4b08913677e18a8412930972237b91d5a946d95Adam Cohen // transparent. Setting the background drawable to null results in onDraw 186f4b08913677e18a8412930972237b91d5a946d95Adam Cohen // not getting called. 187f4b08913677e18a8412930972237b91d5a946d95Adam Cohen setBackgroundColor(Color.TRANSPARENT); 188f4b08913677e18a8412930972237b91d5a946d95Adam Cohen requestLayout(); 189073a46ff635d089cbcb15d939d1de42dd2b86c97Adam Cohen } 190073a46ff635d089cbcb15d939d1de42dd2b86c97Adam Cohen }); 191f4b08913677e18a8412930972237b91d5a946d95Adam Cohen va.start(); 192f4b08913677e18a8412930972237b91d5a946d95Adam Cohen } 193073a46ff635d089cbcb15d939d1de42dd2b86c97Adam Cohen 194f4b08913677e18a8412930972237b91d5a946d95Adam Cohen private void animateToNaturalState() { 195f4b08913677e18a8412930972237b91d5a946d95Adam Cohen ValueAnimator va = ValueAnimator.ofFloat(0f, 1f); 196f4b08913677e18a8412930972237b91d5a946d95Adam Cohen va.setDuration(CONSUMPTION_ANIMATION_DURATION); 197f4b08913677e18a8412930972237b91d5a946d95Adam Cohen va.addUpdateListener(new AnimatorUpdateListener() { 198073a46ff635d089cbcb15d939d1de42dd2b86c97Adam Cohen public void onAnimationUpdate(ValueAnimator animation) { 199073a46ff635d089cbcb15d939d1de42dd2b86c97Adam Cohen final float percent = (Float) animation.getAnimatedValue(); 200073a46ff635d089cbcb15d939d1de42dd2b86c97Adam Cohen mOuterRingScale = OUTER_RING_BASELINE_SCALE + OUTER_RING_GROWTH_FACTOR 201073a46ff635d089cbcb15d939d1de42dd2b86c97Adam Cohen - percent * OUTER_RING_GROWTH_FACTOR; 202f4b08913677e18a8412930972237b91d5a946d95Adam Cohen mInnerRingScale = INNER_RING_BASELINE_SCALE + INNER_RING_GROWTH_FACTOR 203f4b08913677e18a8412930972237b91d5a946d95Adam Cohen - percent * INNER_RING_GROWTH_FACTOR; 204073a46ff635d089cbcb15d939d1de42dd2b86c97Adam Cohen mLauncher.getWorkspace().invalidate(); 205f4b08913677e18a8412930972237b91d5a946d95Adam Cohen invalidate(); 2062801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen } 2072801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen }); 208f4b08913677e18a8412930972237b91d5a946d95Adam Cohen va.addListener(new AnimatorListenerAdapter() { 209f4b08913677e18a8412930972237b91d5a946d95Adam Cohen @Override 210f4b08913677e18a8412930972237b91d5a946d95Adam Cohen public void onAnimationEnd(Animator animation) { 211f4b08913677e18a8412930972237b91d5a946d95Adam Cohen setBackgroundDrawable(sFolderInnerRingDrawable); 212f4b08913677e18a8412930972237b91d5a946d95Adam Cohen mLauncher.getWorkspace().hideFolderAccept(FolderIcon.this); 213f4b08913677e18a8412930972237b91d5a946d95Adam Cohen } 214f4b08913677e18a8412930972237b91d5a946d95Adam Cohen }); 215f4b08913677e18a8412930972237b91d5a946d95Adam Cohen va.start(); 21631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 217440c360bc395c43683fa9ca226e59f9e35f9e926Patrick Dubroy 218073a46ff635d089cbcb15d939d1de42dd2b86c97Adam Cohen private void determineFolderLocationInWorkspace() { 219073a46ff635d089cbcb15d939d1de42dd2b86c97Adam Cohen int tvLocation[] = new int[2]; 220073a46ff635d089cbcb15d939d1de42dd2b86c97Adam Cohen int wsLocation[] = new int[2]; 221073a46ff635d089cbcb15d939d1de42dd2b86c97Adam Cohen getLocationOnScreen(tvLocation); 222073a46ff635d089cbcb15d939d1de42dd2b86c97Adam Cohen mLauncher.getWorkspace().getLocationOnScreen(wsLocation); 223073a46ff635d089cbcb15d939d1de42dd2b86c97Adam Cohen mFolderLocX = tvLocation[0] - wsLocation[0] + getMeasuredWidth() / 2; 224073a46ff635d089cbcb15d939d1de42dd2b86c97Adam Cohen mFolderLocY = tvLocation[1] - wsLocation[1] + getMeasuredHeight() / 2; 225073a46ff635d089cbcb15d939d1de42dd2b86c97Adam Cohen } 226073a46ff635d089cbcb15d939d1de42dd2b86c97Adam Cohen 227cb3382b1bfe1a534b1b44f5c4def9b2db605ac90Adam Cohen public void onDragEnter(DragObject d) { 228cb3382b1bfe1a534b1b44f5c4def9b2db605ac90Adam Cohen if (!willAcceptItem((ItemInfo) d.dragInfo)) return; 229073a46ff635d089cbcb15d939d1de42dd2b86c97Adam Cohen determineFolderLocationInWorkspace(); 230073a46ff635d089cbcb15d939d1de42dd2b86c97Adam Cohen mLauncher.getWorkspace().showFolderAccept(this); 231073a46ff635d089cbcb15d939d1de42dd2b86c97Adam Cohen animateToAcceptState(); 232073a46ff635d089cbcb15d939d1de42dd2b86c97Adam Cohen } 233073a46ff635d089cbcb15d939d1de42dd2b86c97Adam Cohen 234cb3382b1bfe1a534b1b44f5c4def9b2db605ac90Adam Cohen public void onDragOver(DragObject d) { 235073a46ff635d089cbcb15d939d1de42dd2b86c97Adam Cohen } 236073a46ff635d089cbcb15d939d1de42dd2b86c97Adam Cohen 237cb3382b1bfe1a534b1b44f5c4def9b2db605ac90Adam Cohen public void onDragExit(DragObject d) { 238cb3382b1bfe1a534b1b44f5c4def9b2db605ac90Adam Cohen if (!willAcceptItem((ItemInfo) d.dragInfo)) return; 239073a46ff635d089cbcb15d939d1de42dd2b86c97Adam Cohen animateToNaturalState(); 240073a46ff635d089cbcb15d939d1de42dd2b86c97Adam Cohen } 241073a46ff635d089cbcb15d939d1de42dd2b86c97Adam Cohen 242cb3382b1bfe1a534b1b44f5c4def9b2db605ac90Adam Cohen public DropTarget getDropTargetDelegate(DragObject d) { 243440c360bc395c43683fa9ca226e59f9e35f9e926Patrick Dubroy return null; 244440c360bc395c43683fa9ca226e59f9e35f9e926Patrick Dubroy } 245a9cf38f533d1e86269868f1e6a806ccffd4a78fcAdam Cohen 246073a46ff635d089cbcb15d939d1de42dd2b86c97Adam Cohen public void getFolderLocation(int[] loc) { 247073a46ff635d089cbcb15d939d1de42dd2b86c97Adam Cohen loc[0] = mFolderLocX; 248073a46ff635d089cbcb15d939d1de42dd2b86c97Adam Cohen loc[1] = mFolderLocY; 249073a46ff635d089cbcb15d939d1de42dd2b86c97Adam Cohen } 250073a46ff635d089cbcb15d939d1de42dd2b86c97Adam Cohen 251073a46ff635d089cbcb15d939d1de42dd2b86c97Adam Cohen public float getOuterRingScale() { 252073a46ff635d089cbcb15d939d1de42dd2b86c97Adam Cohen return mOuterRingScale; 253073a46ff635d089cbcb15d939d1de42dd2b86c97Adam Cohen } 254073a46ff635d089cbcb15d939d1de42dd2b86c97Adam Cohen 255f4b08913677e18a8412930972237b91d5a946d95Adam Cohen public float getInnerRingScale() { 256f4b08913677e18a8412930972237b91d5a946d95Adam Cohen return mInnerRingScale; 257f4b08913677e18a8412930972237b91d5a946d95Adam Cohen } 258f4b08913677e18a8412930972237b91d5a946d95Adam Cohen 259a9cf38f533d1e86269868f1e6a806ccffd4a78fcAdam Cohen @Override 260a9cf38f533d1e86269868f1e6a806ccffd4a78fcAdam Cohen protected void onDraw(Canvas canvas) { 261a9cf38f533d1e86269868f1e6a806ccffd4a78fcAdam Cohen if (mFolder == null) return; 262a9cf38f533d1e86269868f1e6a806ccffd4a78fcAdam Cohen if (mFolder.getItemCount() == 0) return; 263a9cf38f533d1e86269868f1e6a806ccffd4a78fcAdam Cohen 264a9cf38f533d1e86269868f1e6a806ccffd4a78fcAdam Cohen canvas.save(); 265a9cf38f533d1e86269868f1e6a806ccffd4a78fcAdam Cohen TextView v = (TextView) mFolder.getItemAt(0); 266a9cf38f533d1e86269868f1e6a806ccffd4a78fcAdam Cohen Drawable d = v.getCompoundDrawables()[1]; 267a9cf38f533d1e86269868f1e6a806ccffd4a78fcAdam Cohen 268073a46ff635d089cbcb15d939d1de42dd2b86c97Adam Cohen if (mOriginalWidth < 0 || mOriginalHeight < 0) { 269073a46ff635d089cbcb15d939d1de42dd2b86c97Adam Cohen mOriginalWidth = getMeasuredWidth(); 270073a46ff635d089cbcb15d939d1de42dd2b86c97Adam Cohen mOriginalHeight = getMeasuredHeight(); 271073a46ff635d089cbcb15d939d1de42dd2b86c97Adam Cohen } 272073a46ff635d089cbcb15d939d1de42dd2b86c97Adam Cohen 273badf71e11fba2d6efa1d1bcca9542001f90a3777Adam Cohen int unscaledHeight = (int) (d.getIntrinsicHeight() * (1 + PERSPECTIVE_SHIFT_FACTOR)); 274badf71e11fba2d6efa1d1bcca9542001f90a3777Adam Cohen float baselineIconScale = SPACE_PERCENTAGE_FOR_ICONS / (unscaledHeight / (mOriginalHeight * 1.0f)); 275badf71e11fba2d6efa1d1bcca9542001f90a3777Adam Cohen 276badf71e11fba2d6efa1d1bcca9542001f90a3777Adam Cohen int baselineHeight = (int) (d.getIntrinsicHeight() * baselineIconScale); 277badf71e11fba2d6efa1d1bcca9542001f90a3777Adam Cohen int totalStackHeight = (int) (baselineHeight * (1 + PERSPECTIVE_SHIFT_FACTOR)); 278badf71e11fba2d6efa1d1bcca9542001f90a3777Adam Cohen int baselineWidth = (int) (d.getIntrinsicWidth() * baselineIconScale); 279badf71e11fba2d6efa1d1bcca9542001f90a3777Adam Cohen float maxPerpectiveShift = baselineHeight * PERSPECTIVE_SHIFT_FACTOR; 280a9cf38f533d1e86269868f1e6a806ccffd4a78fcAdam Cohen 2817c6932140dcbd2db88d7a809ba72ee04abb5bf26Adam Cohen ArrayList<View> items = mFolder.getItemsInReadingOrder(); 2827c6932140dcbd2db88d7a809ba72ee04abb5bf26Adam Cohen int firstItemIndex = Math.max(0, items.size() - NUM_ITEMS_IN_PREVIEW); 283badf71e11fba2d6efa1d1bcca9542001f90a3777Adam Cohen 284badf71e11fba2d6efa1d1bcca9542001f90a3777Adam Cohen int xShift = (int) (mOriginalWidth - baselineWidth) / 2; 285badf71e11fba2d6efa1d1bcca9542001f90a3777Adam Cohen int yShift = (int) (mOriginalHeight - totalStackHeight) / 2; 286badf71e11fba2d6efa1d1bcca9542001f90a3777Adam Cohen canvas.translate(xShift, yShift); 2874dbe6d993485a702505ee4895db94aaa89655f2cAdam Cohen for (int i = firstItemIndex; i < items.size(); i++) { 288badf71e11fba2d6efa1d1bcca9542001f90a3777Adam Cohen int index = i - firstItemIndex; 289badf71e11fba2d6efa1d1bcca9542001f90a3777Adam Cohen index += Math.max(0, NUM_ITEMS_IN_PREVIEW - items.size()); 290badf71e11fba2d6efa1d1bcca9542001f90a3777Adam Cohen 291badf71e11fba2d6efa1d1bcca9542001f90a3777Adam Cohen float r = (index * 1.0f) / (NUM_ITEMS_IN_PREVIEW - 1); 292badf71e11fba2d6efa1d1bcca9542001f90a3777Adam Cohen float scale = (1 - PERSPECTIVE_SCALE_FACTOR * (1 - r)); 293badf71e11fba2d6efa1d1bcca9542001f90a3777Adam Cohen r = (float) Math.pow(r, 2); 294badf71e11fba2d6efa1d1bcca9542001f90a3777Adam Cohen 295badf71e11fba2d6efa1d1bcca9542001f90a3777Adam Cohen float transY = r * maxPerpectiveShift; 296badf71e11fba2d6efa1d1bcca9542001f90a3777Adam Cohen float transX = (1 - scale) * baselineWidth / 2.0f; 297badf71e11fba2d6efa1d1bcca9542001f90a3777Adam Cohen 2987c6932140dcbd2db88d7a809ba72ee04abb5bf26Adam Cohen v = (TextView) items.get(i); 299a9cf38f533d1e86269868f1e6a806ccffd4a78fcAdam Cohen d = v.getCompoundDrawables()[1]; 300a9cf38f533d1e86269868f1e6a806ccffd4a78fcAdam Cohen 301badf71e11fba2d6efa1d1bcca9542001f90a3777Adam Cohen canvas.save(); 302badf71e11fba2d6efa1d1bcca9542001f90a3777Adam Cohen canvas.translate(transX, transY); 303badf71e11fba2d6efa1d1bcca9542001f90a3777Adam Cohen canvas.scale(baselineIconScale * scale, baselineIconScale * scale); 304f4b08913677e18a8412930972237b91d5a946d95Adam Cohen 305badf71e11fba2d6efa1d1bcca9542001f90a3777Adam Cohen int overlayAlpha = (int) (80 * (1 - r)); 306a9cf38f533d1e86269868f1e6a806ccffd4a78fcAdam Cohen if (d != null) { 307a9cf38f533d1e86269868f1e6a806ccffd4a78fcAdam Cohen d.setBounds(0, 0, d.getIntrinsicWidth(), d.getIntrinsicHeight()); 308badf71e11fba2d6efa1d1bcca9542001f90a3777Adam Cohen d.setColorFilter(Color.argb(overlayAlpha, 0, 0, 0), PorterDuff.Mode.SRC_ATOP); 309a9cf38f533d1e86269868f1e6a806ccffd4a78fcAdam Cohen d.draw(canvas); 310badf71e11fba2d6efa1d1bcca9542001f90a3777Adam Cohen d.clearColorFilter(); 311a9cf38f533d1e86269868f1e6a806ccffd4a78fcAdam Cohen } 312badf71e11fba2d6efa1d1bcca9542001f90a3777Adam Cohen canvas.restore(); 313a9cf38f533d1e86269868f1e6a806ccffd4a78fcAdam Cohen } 314a9cf38f533d1e86269868f1e6a806ccffd4a78fcAdam Cohen 315a9cf38f533d1e86269868f1e6a806ccffd4a78fcAdam Cohen canvas.restore(); 316a9cf38f533d1e86269868f1e6a806ccffd4a78fcAdam Cohen } 317a9cf38f533d1e86269868f1e6a806ccffd4a78fcAdam Cohen 318a9cf38f533d1e86269868f1e6a806ccffd4a78fcAdam Cohen public void onAdd(ShortcutInfo item) { 319a9cf38f533d1e86269868f1e6a806ccffd4a78fcAdam Cohen invalidate(); 320a9cf38f533d1e86269868f1e6a806ccffd4a78fcAdam Cohen requestLayout(); 321a9cf38f533d1e86269868f1e6a806ccffd4a78fcAdam Cohen } 322a9cf38f533d1e86269868f1e6a806ccffd4a78fcAdam Cohen 323a9cf38f533d1e86269868f1e6a806ccffd4a78fcAdam Cohen public void onRemove(ShortcutInfo item) { 324a9cf38f533d1e86269868f1e6a806ccffd4a78fcAdam Cohen invalidate(); 325a9cf38f533d1e86269868f1e6a806ccffd4a78fcAdam Cohen requestLayout(); 326a9cf38f533d1e86269868f1e6a806ccffd4a78fcAdam Cohen } 32731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project} 328