blob: aff8761fd7752ccfa5ee73a0dd0da13fd23a7b2b [file] [log] [blame]
The Android Open Source Project31dd5032009-03-03 19:32:27 -08001/*
2 * Copyright (C) 2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Joe Onoratoa5902522009-07-30 13:37:37 -070017package com.android.launcher2;
The Android Open Source Project31dd5032009-03-03 19:32:27 -080018
Adam Cohen2801caf2011-05-13 20:57:39 -070019import android.animation.Animator;
20import android.animation.AnimatorListenerAdapter;
Adam Cohen2801caf2011-05-13 20:57:39 -070021import android.animation.ValueAnimator;
22import android.animation.ValueAnimator.AnimatorUpdateListener;
The Android Open Source Project31dd5032009-03-03 19:32:27 -080023import android.content.Context;
24import android.content.res.Resources;
Adam Cohena9cf38f2011-05-02 15:36:58 -070025import android.graphics.Canvas;
Adam Cohenf4b08912011-05-17 18:45:47 -070026import android.graphics.Color;
Adam Cohenbadf71e2011-05-26 19:08:29 -070027import android.graphics.PorterDuff;
Adam Cohen3e8f8112011-07-02 18:03:00 -070028import android.graphics.Rect;
The Android Open Source Project31dd5032009-03-03 19:32:27 -080029import android.graphics.drawable.Drawable;
30import android.util.AttributeSet;
31import android.view.LayoutInflater;
Adam Cohen7c693212011-05-18 15:26:57 -070032import android.view.View;
The Android Open Source Project31dd5032009-03-03 19:32:27 -080033import android.view.ViewGroup;
Adam Cohen3e8f8112011-07-02 18:03:00 -070034import android.view.animation.AccelerateInterpolator;
35import android.view.animation.DecelerateInterpolator;
Adam Cohen76fc0852011-06-17 13:26:23 -070036import android.widget.ImageView;
37import android.widget.LinearLayout;
Adam Cohena9cf38f2011-05-02 15:36:58 -070038import android.widget.TextView;
The Android Open Source Project31dd5032009-03-03 19:32:27 -080039
Romain Guyedcce092010-03-04 13:03:17 -080040import com.android.launcher.R;
Adam Cohenc0dcf592011-06-01 15:30:43 -070041import com.android.launcher2.DropTarget.DragObject;
Adam Cohena9cf38f2011-05-02 15:36:58 -070042import com.android.launcher2.FolderInfo.FolderListener;
Romain Guyedcce092010-03-04 13:03:17 -080043
Adam Cohenc0dcf592011-06-01 15:30:43 -070044import java.util.ArrayList;
45
The Android Open Source Project31dd5032009-03-03 19:32:27 -080046/**
47 * An icon that can appear on in the workspace representing an {@link UserFolder}.
48 */
Adam Cohen76fc0852011-06-17 13:26:23 -070049public class FolderIcon extends LinearLayout implements FolderListener {
The Android Open Source Project31dd5032009-03-03 19:32:27 -080050 private Launcher mLauncher;
Adam Cohena9cf38f2011-05-02 15:36:58 -070051 Folder mFolder;
52 FolderInfo mInfo;
53
Adam Cohenbadf71e2011-05-26 19:08:29 -070054 // The number of icons to display in the
Adam Cohen76fc0852011-06-17 13:26:23 -070055 private static final int NUM_ITEMS_IN_PREVIEW = 3;
Adam Cohenf4b08912011-05-17 18:45:47 -070056 private static final int CONSUMPTION_ANIMATION_DURATION = 100;
Adam Cohenbadf71e2011-05-26 19:08:29 -070057
58 // The degree to which the inner ring grows when accepting drop
Adam Cohen073a46f2011-05-17 16:28:09 -070059 private static final float INNER_RING_GROWTH_FACTOR = 0.1f;
Adam Cohenbadf71e2011-05-26 19:08:29 -070060
Adam Cohenbadf71e2011-05-26 19:08:29 -070061 // The degree to which the outer ring is scaled in its natural state
Adam Cohen76fc0852011-06-17 13:26:23 -070062 private static final float OUTER_RING_GROWTH_FACTOR = 0.4f;
Adam Cohenbadf71e2011-05-26 19:08:29 -070063
64 // The amount of vertical spread between items in the stack [0...1]
Adam Cohen76fc0852011-06-17 13:26:23 -070065 private static final float PERSPECTIVE_SHIFT_FACTOR = 0.24f;
Adam Cohenbadf71e2011-05-26 19:08:29 -070066
67 // The degree to which the item in the back of the stack is scaled [0...1]
68 // (0 means it's not scaled at all, 1 means it's scaled to nothing)
Adam Cohen76fc0852011-06-17 13:26:23 -070069 private static final float PERSPECTIVE_SCALE_FACTOR = 0.35f;
Adam Cohenbadf71e2011-05-26 19:08:29 -070070
Adam Cohen073a46f2011-05-17 16:28:09 -070071 private int mOriginalWidth = -1;
72 private int mOriginalHeight = -1;
Adam Cohen76fc0852011-06-17 13:26:23 -070073 private ImageView mPreviewBackground;
74 private BubbleTextView mFolderName;
Adam Cohen073a46f2011-05-17 16:28:09 -070075
Adam Cohen19072da2011-05-31 14:30:45 -070076 FolderRingAnimator mFolderRingAnimator = null;
Adam Cohen2801caf2011-05-13 20:57:39 -070077
The Android Open Source Project31dd5032009-03-03 19:32:27 -080078 public FolderIcon(Context context, AttributeSet attrs) {
79 super(context, attrs);
80 }
81
82 public FolderIcon(Context context) {
83 super(context);
84 }
85
Michael Jurka0280c3b2010-09-17 15:00:07 -070086 public boolean isDropEnabled() {
Winson Chung7a1d1652011-03-18 15:56:01 -070087 final ViewGroup cellLayoutChildren = (ViewGroup) getParent();
88 final ViewGroup cellLayout = (ViewGroup) cellLayoutChildren.getParent();
89 final Workspace workspace = (Workspace) cellLayout.getParent();
90 return !workspace.isSmall();
Michael Jurka0280c3b2010-09-17 15:00:07 -070091 }
92
The Android Open Source Project31dd5032009-03-03 19:32:27 -080093 static FolderIcon fromXml(int resId, Launcher launcher, ViewGroup group,
Adam Cohendf2cc412011-04-27 16:56:57 -070094 FolderInfo folderInfo, IconCache iconCache) {
The Android Open Source Project31dd5032009-03-03 19:32:27 -080095
96 FolderIcon icon = (FolderIcon) LayoutInflater.from(launcher).inflate(resId, group, false);
97
Adam Cohen76fc0852011-06-17 13:26:23 -070098 icon.mFolderName = (BubbleTextView) icon.findViewById(R.id.folder_name);
99 icon.mFolderName.setText(folderInfo.title);
100 icon.mPreviewBackground = (ImageView) icon.findViewById(R.id.preview_background);
Winson Chung6a0f57d2011-06-29 20:10:49 -0700101 icon.mPreviewBackground.setContentDescription(folderInfo.title);
Adam Cohen76fc0852011-06-17 13:26:23 -0700102
The Android Open Source Project31dd5032009-03-03 19:32:27 -0800103 icon.setTag(folderInfo);
104 icon.setOnClickListener(launcher);
105 icon.mInfo = folderInfo;
106 icon.mLauncher = launcher;
Adam Cohena9cf38f2011-05-02 15:36:58 -0700107
108 Folder folder = Folder.fromXml(launcher);
109 folder.setDragController(launcher.getDragController());
110 folder.setLauncher(launcher);
Adam Cohen2801caf2011-05-13 20:57:39 -0700111 folder.setFolderIcon(icon);
Adam Cohena9cf38f2011-05-02 15:36:58 -0700112 folder.bind(folderInfo);
113 icon.mFolder = folder;
Adam Cohen19072da2011-05-31 14:30:45 -0700114 icon.mFolderRingAnimator = new FolderRingAnimator(launcher, icon);
Adam Cohena9cf38f2011-05-02 15:36:58 -0700115 folderInfo.addListener(icon);
Adam Cohen19072da2011-05-31 14:30:45 -0700116
117 return icon;
118 }
119
120 public static class FolderRingAnimator {
121 public int mFolderLocX;
122 public int mFolderLocY;
Adam Cohen76fc0852011-06-17 13:26:23 -0700123 public float mOuterRingSize;
124 public float mInnerRingSize;
Adam Cohen19072da2011-05-31 14:30:45 -0700125 public FolderIcon mFolderIcon = null;
126 private Launcher mLauncher;
Adam Cohenc0dcf592011-06-01 15:30:43 -0700127 public Drawable mOuterRingDrawable = null;
128 public Drawable mInnerRingDrawable = null;
129 public static Drawable sSharedOuterRingDrawable = null;
130 public static Drawable sSharedInnerRingDrawable = null;
Adam Cohen76fc0852011-06-17 13:26:23 -0700131 public static int sPreviewSize = -1;
132 public static int sPreviewPadding = -1;
133
Adam Cohenc0dcf592011-06-01 15:30:43 -0700134 private ValueAnimator mAcceptAnimator;
135 private ValueAnimator mNeutralAnimator;
Adam Cohen19072da2011-05-31 14:30:45 -0700136
137 public FolderRingAnimator(Launcher launcher, FolderIcon folderIcon) {
138 mLauncher = launcher;
139 mFolderIcon = folderIcon;
Adam Cohen76fc0852011-06-17 13:26:23 -0700140 Resources res = launcher.getResources();
141 mOuterRingDrawable = res.getDrawable(R.drawable.portal_ring_outer_holo);
142 mInnerRingDrawable = res.getDrawable(R.drawable.portal_ring_inner_holo);
143
144 if (sPreviewSize < 0 || sPreviewPadding < 0) {
145 sPreviewSize = res.getDimensionPixelSize(R.dimen.folder_preview_size);
146 sPreviewPadding = res.getDimensionPixelSize(R.dimen.folder_preview_padding);
147 }
Adam Cohenc0dcf592011-06-01 15:30:43 -0700148 if (sSharedOuterRingDrawable == null) {
Adam Cohen76fc0852011-06-17 13:26:23 -0700149 sSharedOuterRingDrawable = res.getDrawable(R.drawable.portal_ring_outer_holo);
Adam Cohen19072da2011-05-31 14:30:45 -0700150 }
Adam Cohenc0dcf592011-06-01 15:30:43 -0700151 if (sSharedInnerRingDrawable == null) {
Adam Cohen76fc0852011-06-17 13:26:23 -0700152 sSharedInnerRingDrawable = res.getDrawable(R.drawable.portal_ring_inner_holo);
Adam Cohen19072da2011-05-31 14:30:45 -0700153 }
Adam Cohen073a46f2011-05-17 16:28:09 -0700154 }
Adam Cohena9cf38f2011-05-02 15:36:58 -0700155
Adam Cohenc0dcf592011-06-01 15:30:43 -0700156 // Location is expressed in window coordinates
Adam Cohen19072da2011-05-31 14:30:45 -0700157 public void setLocation(int x, int y) {
158 mFolderLocX = x;
159 mFolderLocY = y;
Adam Cohenf4b08912011-05-17 18:45:47 -0700160 }
Adam Cohen19072da2011-05-31 14:30:45 -0700161
162 public void animateToAcceptState() {
Adam Cohenc0dcf592011-06-01 15:30:43 -0700163 if (mNeutralAnimator != null) {
164 mNeutralAnimator.cancel();
165 }
166 mAcceptAnimator = ValueAnimator.ofFloat(0f, 1f);
167 mAcceptAnimator.setDuration(CONSUMPTION_ANIMATION_DURATION);
168 mAcceptAnimator.addUpdateListener(new AnimatorUpdateListener() {
Adam Cohen19072da2011-05-31 14:30:45 -0700169 public void onAnimationUpdate(ValueAnimator animation) {
170 final float percent = (Float) animation.getAnimatedValue();
Adam Cohen76fc0852011-06-17 13:26:23 -0700171 mOuterRingSize = (1 + percent * OUTER_RING_GROWTH_FACTOR) * sPreviewSize;
172 mInnerRingSize = (1 + percent * INNER_RING_GROWTH_FACTOR) * sPreviewSize;
Adam Cohen19072da2011-05-31 14:30:45 -0700173 mLauncher.getWorkspace().invalidate();
174 if (mFolderIcon != null) {
175 mFolderIcon.invalidate();
176 }
177 }
178 });
Adam Cohenc0dcf592011-06-01 15:30:43 -0700179 mAcceptAnimator.addListener(new AnimatorListenerAdapter() {
Adam Cohen19072da2011-05-31 14:30:45 -0700180 @Override
Adam Cohenc0dcf592011-06-01 15:30:43 -0700181 public void onAnimationStart(Animator animation) {
Adam Cohen19072da2011-05-31 14:30:45 -0700182 if (mFolderIcon != null) {
Adam Cohen76fc0852011-06-17 13:26:23 -0700183 mFolderIcon.mPreviewBackground.setVisibility(INVISIBLE);
Adam Cohen19072da2011-05-31 14:30:45 -0700184 }
185 }
186 });
Adam Cohenc0dcf592011-06-01 15:30:43 -0700187 mAcceptAnimator.start();
Adam Cohen19072da2011-05-31 14:30:45 -0700188 }
189
190 public void animateToNaturalState() {
Adam Cohenc0dcf592011-06-01 15:30:43 -0700191 if (mAcceptAnimator != null) {
192 mAcceptAnimator.cancel();
193 }
194 mNeutralAnimator = ValueAnimator.ofFloat(0f, 1f);
195 mNeutralAnimator.setDuration(CONSUMPTION_ANIMATION_DURATION);
196 mNeutralAnimator.addUpdateListener(new AnimatorUpdateListener() {
Adam Cohen19072da2011-05-31 14:30:45 -0700197 public void onAnimationUpdate(ValueAnimator animation) {
198 final float percent = (Float) animation.getAnimatedValue();
Adam Cohen76fc0852011-06-17 13:26:23 -0700199 mOuterRingSize = (1 + (1 - percent) * OUTER_RING_GROWTH_FACTOR) * sPreviewSize;
200 mInnerRingSize = (1 + (1 - percent) * INNER_RING_GROWTH_FACTOR) * sPreviewSize;
Adam Cohen19072da2011-05-31 14:30:45 -0700201 mLauncher.getWorkspace().invalidate();
202 if (mFolderIcon != null) {
203 mFolderIcon.invalidate();
204 }
205 }
206 });
Adam Cohenc0dcf592011-06-01 15:30:43 -0700207 mNeutralAnimator.addListener(new AnimatorListenerAdapter() {
Adam Cohen19072da2011-05-31 14:30:45 -0700208 @Override
209 public void onAnimationEnd(Animator animation) {
210 if (mFolderIcon != null) {
Adam Cohen76fc0852011-06-17 13:26:23 -0700211 mFolderIcon.mPreviewBackground.setVisibility(VISIBLE);
Adam Cohen19072da2011-05-31 14:30:45 -0700212 }
213 mLauncher.getWorkspace().hideFolderAccept(FolderRingAnimator.this);
214 }
215 });
Adam Cohenc0dcf592011-06-01 15:30:43 -0700216 mNeutralAnimator.start();
Adam Cohen19072da2011-05-31 14:30:45 -0700217 }
218
Adam Cohenc0dcf592011-06-01 15:30:43 -0700219 // Location is expressed in window coordinates
Adam Cohen19072da2011-05-31 14:30:45 -0700220 public void getLocation(int[] loc) {
221 loc[0] = mFolderLocX;
222 loc[1] = mFolderLocY;
223 }
224
Adam Cohen76fc0852011-06-17 13:26:23 -0700225 public float getOuterRingSize() {
226 return mOuterRingSize;
Adam Cohen19072da2011-05-31 14:30:45 -0700227 }
228
Adam Cohen76fc0852011-06-17 13:26:23 -0700229 public float getInnerRingSize() {
230 return mInnerRingSize;
Adam Cohen19072da2011-05-31 14:30:45 -0700231 }
The Android Open Source Project31dd5032009-03-03 19:32:27 -0800232 }
233
Adam Cohen073a46f2011-05-17 16:28:09 -0700234 private boolean willAcceptItem(ItemInfo item) {
235 final int itemType = item.itemType;
236 return ((itemType == LauncherSettings.Favorites.ITEM_TYPE_APPLICATION ||
237 itemType == LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT) &&
238 !mFolder.isFull() && item != mInfo);
239 }
240
Adam Cohenc0dcf592011-06-01 15:30:43 -0700241 public boolean acceptDrop(Object dragInfo) {
242 final ItemInfo item = (ItemInfo) dragInfo;
Adam Cohen073a46f2011-05-17 16:28:09 -0700243 return willAcceptItem(item);
The Android Open Source Project31dd5032009-03-03 19:32:27 -0800244 }
245
Adam Cohendf035382011-04-11 17:22:04 -0700246 public void addItem(ShortcutInfo item) {
247 mInfo.add(item);
Adam Cohena9cf38f2011-05-02 15:36:58 -0700248 LauncherModel.addOrMoveItemInDatabase(mLauncher, item, mInfo.id, 0, item.cellX, item.cellY);
Adam Cohendf035382011-04-11 17:22:04 -0700249 }
250
Adam Cohen2801caf2011-05-13 20:57:39 -0700251 void saveState(CellLayout.LayoutParams lp) {
252 mOriginalWidth = lp.width;
253 mOriginalHeight = lp.height;
Adam Cohen2801caf2011-05-13 20:57:39 -0700254 }
255
Adam Cohen073a46f2011-05-17 16:28:09 -0700256 private void determineFolderLocationInWorkspace() {
257 int tvLocation[] = new int[2];
258 int wsLocation[] = new int[2];
Adam Cohenc0dcf592011-06-01 15:30:43 -0700259 getLocationInWindow(tvLocation);
260 mLauncher.getWorkspace().getLocationInWindow(wsLocation);
Adam Cohen19072da2011-05-31 14:30:45 -0700261
262 int x = tvLocation[0] - wsLocation[0] + getMeasuredWidth() / 2;
Adam Cohen76fc0852011-06-17 13:26:23 -0700263 int y = tvLocation[1] - wsLocation[1] + FolderRingAnimator.sPreviewSize / 2;
Adam Cohen19072da2011-05-31 14:30:45 -0700264 mFolderRingAnimator.setLocation(x, y);
Adam Cohen073a46f2011-05-17 16:28:09 -0700265 }
266
Adam Cohenc0dcf592011-06-01 15:30:43 -0700267 public void onDragEnter(Object dragInfo) {
268 if (!willAcceptItem((ItemInfo) dragInfo)) return;
Adam Cohen073a46f2011-05-17 16:28:09 -0700269 determineFolderLocationInWorkspace();
Adam Cohen19072da2011-05-31 14:30:45 -0700270 mLauncher.getWorkspace().showFolderAccept(mFolderRingAnimator);
271 mFolderRingAnimator.animateToAcceptState();
Adam Cohen073a46f2011-05-17 16:28:09 -0700272 }
273
Adam Cohenc0dcf592011-06-01 15:30:43 -0700274 public void onDragOver(Object dragInfo) {
The Android Open Source Project31dd5032009-03-03 19:32:27 -0800275 }
276
Adam Cohenc0dcf592011-06-01 15:30:43 -0700277 public void onDragExit(Object dragInfo) {
278 if (!willAcceptItem((ItemInfo) dragInfo)) return;
Adam Cohen19072da2011-05-31 14:30:45 -0700279 mFolderRingAnimator.animateToNaturalState();
The Android Open Source Project31dd5032009-03-03 19:32:27 -0800280 }
Patrick Dubroy440c3602010-07-13 17:50:32 -0700281
Adam Cohen3e8f8112011-07-02 18:03:00 -0700282 public void onDrop(DragObject d) {
Adam Cohenc0dcf592011-06-01 15:30:43 -0700283 ShortcutInfo item;
Adam Cohen3e8f8112011-07-02 18:03:00 -0700284 if (d.dragInfo instanceof ApplicationInfo) {
Adam Cohenc0dcf592011-06-01 15:30:43 -0700285 // Came from all apps -- make a copy
Adam Cohen3e8f8112011-07-02 18:03:00 -0700286 item = ((ApplicationInfo) d.dragInfo).makeShortcut();
Adam Cohenc0dcf592011-06-01 15:30:43 -0700287 } else {
Adam Cohen3e8f8112011-07-02 18:03:00 -0700288 item = (ShortcutInfo) d.dragInfo;
Adam Cohenc0dcf592011-06-01 15:30:43 -0700289 }
290 item.cellX = -1;
291 item.cellY = -1;
292 addItem(item);
Adam Cohen3e8f8112011-07-02 18:03:00 -0700293 DragLayer dragLayer = mLauncher.getDragLayer();
294 Rect from = new Rect();
295 dragLayer.getViewRectRelativeToSelf(d.dragView, from);
296 Rect to = new Rect();
297 dragLayer.getDescendantRectRelativeToSelf(this, to);
298
299 int previewSize = FolderRingAnimator.sPreviewSize;
300 int vanishingPointX = (int) (previewSize * 0.7);
301 int vanishingPointY = (int) (previewSize * (1 - 0.88f));
302 to.offset(vanishingPointX - previewSize / 2 , vanishingPointY - previewSize / 2);
303
304 dragLayer.animateView(d.dragView, from, to, 0f, 0.2f, 400, new DecelerateInterpolator(2),
305 new AccelerateInterpolator(2));
Adam Cohenc0dcf592011-06-01 15:30:43 -0700306 }
307
Adam Cohencb3382b2011-05-24 14:07:08 -0700308 public DropTarget getDropTargetDelegate(DragObject d) {
Patrick Dubroy440c3602010-07-13 17:50:32 -0700309 return null;
310 }
Adam Cohena9cf38f2011-05-02 15:36:58 -0700311
312 @Override
Adam Cohenc0dcf592011-06-01 15:30:43 -0700313 protected void dispatchDraw(Canvas canvas) {
Adam Cohen76fc0852011-06-17 13:26:23 -0700314 super.dispatchDraw(canvas);
315
Adam Cohena9cf38f2011-05-02 15:36:58 -0700316 if (mFolder == null) return;
317 if (mFolder.getItemCount() == 0) return;
318
319 canvas.save();
320 TextView v = (TextView) mFolder.getItemAt(0);
321 Drawable d = v.getCompoundDrawables()[1];
Adam Cohen76fc0852011-06-17 13:26:23 -0700322 int intrinsicIconSize = d.getIntrinsicHeight();
Adam Cohena9cf38f2011-05-02 15:36:58 -0700323
Adam Cohen073a46f2011-05-17 16:28:09 -0700324 if (mOriginalWidth < 0 || mOriginalHeight < 0) {
325 mOriginalWidth = getMeasuredWidth();
326 mOriginalHeight = getMeasuredHeight();
327 }
Adam Cohen76fc0852011-06-17 13:26:23 -0700328 final int previewSize = FolderRingAnimator.sPreviewSize;
329 final int previewPadding = FolderRingAnimator.sPreviewPadding;
Adam Cohena9cf38f2011-05-02 15:36:58 -0700330
Adam Cohen76fc0852011-06-17 13:26:23 -0700331 int halfAvailableSpace = (previewSize - 2 * previewPadding) / 2;
332 // cos(45) = 0.707 + ~= 0.1)
333 int availableSpace = (int) (halfAvailableSpace * (1 + 0.8f));
Adam Cohenbadf71e2011-05-26 19:08:29 -0700334
Adam Cohen76fc0852011-06-17 13:26:23 -0700335 int unscaledHeight = (int) (intrinsicIconSize * (1 + PERSPECTIVE_SHIFT_FACTOR));
336 float baselineIconScale = (1.0f * availableSpace / unscaledHeight);
337
338 int baselineSize = (int) (intrinsicIconSize * baselineIconScale);
339 float maxPerspectiveShift = baselineSize * PERSPECTIVE_SHIFT_FACTOR;
Adam Cohena9cf38f2011-05-02 15:36:58 -0700340
Adam Cohen76078c42011-06-09 15:06:52 -0700341 ArrayList<View> items = mFolder.getItemsInReadingOrder(false);
Adam Cohenbadf71e2011-05-26 19:08:29 -0700342
Adam Cohen76fc0852011-06-17 13:26:23 -0700343 int xShift = (mOriginalWidth - 2 * halfAvailableSpace) / 2;
344 int yShift = previewPadding;
Adam Cohenbadf71e2011-05-26 19:08:29 -0700345 canvas.translate(xShift, yShift);
Adam Cohen3e8f8112011-07-02 18:03:00 -0700346 int nItemsInPreview = Math.min(items.size(), NUM_ITEMS_IN_PREVIEW);
347 for (int i = nItemsInPreview - 1; i >= 0; i--) {
348 int index = NUM_ITEMS_IN_PREVIEW - i - 1;
Adam Cohenbadf71e2011-05-26 19:08:29 -0700349
350 float r = (index * 1.0f) / (NUM_ITEMS_IN_PREVIEW - 1);
351 float scale = (1 - PERSPECTIVE_SCALE_FACTOR * (1 - r));
Adam Cohenbadf71e2011-05-26 19:08:29 -0700352
Adam Cohen76fc0852011-06-17 13:26:23 -0700353 float offset = (1 - r) * maxPerspectiveShift;
354 float scaledSize = scale * baselineSize;
355 float scaleOffsetCorrection = (1 - scale) * baselineSize;
356
357 // We want to imagine our coordinates from the bottom left, growing up and to the
358 // right. This is natural for the x-axis, but for the y-axis, we have to invert things.
359 float transY = 2 * halfAvailableSpace - (offset + scaledSize + scaleOffsetCorrection);
360 float transX = offset + scaleOffsetCorrection;
Adam Cohenbadf71e2011-05-26 19:08:29 -0700361
Adam Cohen7c693212011-05-18 15:26:57 -0700362 v = (TextView) items.get(i);
Adam Cohena9cf38f2011-05-02 15:36:58 -0700363 d = v.getCompoundDrawables()[1];
364
Adam Cohenbadf71e2011-05-26 19:08:29 -0700365 canvas.save();
366 canvas.translate(transX, transY);
367 canvas.scale(baselineIconScale * scale, baselineIconScale * scale);
Adam Cohenf4b08912011-05-17 18:45:47 -0700368
Adam Cohenbadf71e2011-05-26 19:08:29 -0700369 int overlayAlpha = (int) (80 * (1 - r));
Adam Cohena9cf38f2011-05-02 15:36:58 -0700370 if (d != null) {
Adam Cohen76fc0852011-06-17 13:26:23 -0700371 d.setBounds(0, 0, intrinsicIconSize, intrinsicIconSize);
372 d.setFilterBitmap(true);
Adam Cohenbadf71e2011-05-26 19:08:29 -0700373 d.setColorFilter(Color.argb(overlayAlpha, 0, 0, 0), PorterDuff.Mode.SRC_ATOP);
Adam Cohena9cf38f2011-05-02 15:36:58 -0700374 d.draw(canvas);
Adam Cohenbadf71e2011-05-26 19:08:29 -0700375 d.clearColorFilter();
Adam Cohen76fc0852011-06-17 13:26:23 -0700376 d.setFilterBitmap(false);
Adam Cohena9cf38f2011-05-02 15:36:58 -0700377 }
Adam Cohenbadf71e2011-05-26 19:08:29 -0700378 canvas.restore();
Adam Cohena9cf38f2011-05-02 15:36:58 -0700379 }
Adam Cohena9cf38f2011-05-02 15:36:58 -0700380 canvas.restore();
381 }
382
Adam Cohen76078c42011-06-09 15:06:52 -0700383 public void onItemsChanged() {
384 invalidate();
385 requestLayout();
386 }
387
Adam Cohena9cf38f2011-05-02 15:36:58 -0700388 public void onAdd(ShortcutInfo item) {
389 invalidate();
390 requestLayout();
391 }
392
393 public void onRemove(ShortcutInfo item) {
394 invalidate();
395 requestLayout();
396 }
Adam Cohen76fc0852011-06-17 13:26:23 -0700397
398 public void onTitleChanged(CharSequence title) {
Adam Cohend63cfa92011-06-24 14:17:17 -0700399 mFolderName.setText(title.toString());
Winson Chung6a0f57d2011-06-29 20:10:49 -0700400 mPreviewBackground.setContentDescription(title.toString());
Adam Cohen76fc0852011-06-17 13:26:23 -0700401 }
The Android Open Source Project31dd5032009-03-03 19:32:27 -0800402}