2009-03-03 19:32:27 -08:00
|
|
|
/*
|
|
|
|
|
* Copyright (C) 2008 The Android Open Source Project
|
|
|
|
|
*
|
|
|
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
|
* you may not use this file except in compliance with the License.
|
|
|
|
|
* You may obtain a copy of the License at
|
|
|
|
|
*
|
|
|
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
|
*
|
|
|
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
|
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
|
* See the License for the specific language governing permissions and
|
|
|
|
|
* limitations under the License.
|
|
|
|
|
*/
|
|
|
|
|
|
2009-07-30 13:37:37 -07:00
|
|
|
package com.android.launcher2;
|
2009-03-03 19:32:27 -08:00
|
|
|
|
2011-05-13 20:57:39 -07:00
|
|
|
import android.animation.Animator;
|
|
|
|
|
import android.animation.AnimatorListenerAdapter;
|
|
|
|
|
import android.animation.ValueAnimator;
|
|
|
|
|
import android.animation.ValueAnimator.AnimatorUpdateListener;
|
2009-03-03 19:32:27 -08:00
|
|
|
import android.content.Context;
|
|
|
|
|
import android.content.res.Resources;
|
2011-05-02 15:36:58 -07:00
|
|
|
import android.graphics.Canvas;
|
2011-05-17 18:45:47 -07:00
|
|
|
import android.graphics.Color;
|
2011-05-26 19:08:29 -07:00
|
|
|
import android.graphics.PorterDuff;
|
2009-03-03 19:32:27 -08:00
|
|
|
import android.graphics.drawable.Drawable;
|
|
|
|
|
import android.util.AttributeSet;
|
|
|
|
|
import android.view.LayoutInflater;
|
2011-05-18 15:26:57 -07:00
|
|
|
import android.view.View;
|
2009-03-03 19:32:27 -08:00
|
|
|
import android.view.ViewGroup;
|
2011-06-17 13:26:23 -07:00
|
|
|
import android.widget.ImageView;
|
|
|
|
|
import android.widget.LinearLayout;
|
2011-05-02 15:36:58 -07:00
|
|
|
import android.widget.TextView;
|
2009-03-03 19:32:27 -08:00
|
|
|
|
2010-03-04 13:03:17 -08:00
|
|
|
import com.android.launcher.R;
|
2011-06-01 15:30:43 -07:00
|
|
|
import com.android.launcher2.DropTarget.DragObject;
|
2011-05-02 15:36:58 -07:00
|
|
|
import com.android.launcher2.FolderInfo.FolderListener;
|
2010-03-04 13:03:17 -08:00
|
|
|
|
2011-06-01 15:30:43 -07:00
|
|
|
import java.util.ArrayList;
|
|
|
|
|
|
2009-03-03 19:32:27 -08:00
|
|
|
/**
|
|
|
|
|
* An icon that can appear on in the workspace representing an {@link UserFolder}.
|
|
|
|
|
*/
|
2011-06-17 13:26:23 -07:00
|
|
|
public class FolderIcon extends LinearLayout implements FolderListener {
|
2009-03-03 19:32:27 -08:00
|
|
|
private Launcher mLauncher;
|
2011-05-02 15:36:58 -07:00
|
|
|
Folder mFolder;
|
|
|
|
|
FolderInfo mInfo;
|
|
|
|
|
|
2011-05-26 19:08:29 -07:00
|
|
|
// The number of icons to display in the
|
2011-06-17 13:26:23 -07:00
|
|
|
private static final int NUM_ITEMS_IN_PREVIEW = 3;
|
2011-05-17 18:45:47 -07:00
|
|
|
private static final int CONSUMPTION_ANIMATION_DURATION = 100;
|
2011-05-26 19:08:29 -07:00
|
|
|
|
|
|
|
|
// The degree to which the inner ring grows when accepting drop
|
2011-05-17 16:28:09 -07:00
|
|
|
private static final float INNER_RING_GROWTH_FACTOR = 0.1f;
|
2011-05-26 19:08:29 -07:00
|
|
|
|
|
|
|
|
// The degree to which the outer ring is scaled in its natural state
|
2011-06-17 13:26:23 -07:00
|
|
|
private static final float OUTER_RING_GROWTH_FACTOR = 0.4f;
|
2011-05-26 19:08:29 -07:00
|
|
|
|
|
|
|
|
// The amount of vertical spread between items in the stack [0...1]
|
2011-06-17 13:26:23 -07:00
|
|
|
private static final float PERSPECTIVE_SHIFT_FACTOR = 0.24f;
|
2011-05-26 19:08:29 -07:00
|
|
|
|
|
|
|
|
// The degree to which the item in the back of the stack is scaled [0...1]
|
|
|
|
|
// (0 means it's not scaled at all, 1 means it's scaled to nothing)
|
2011-06-17 13:26:23 -07:00
|
|
|
private static final float PERSPECTIVE_SCALE_FACTOR = 0.35f;
|
2009-03-03 19:32:27 -08:00
|
|
|
|
2011-05-17 16:28:09 -07:00
|
|
|
private int mOriginalWidth = -1;
|
|
|
|
|
private int mOriginalHeight = -1;
|
2011-06-17 13:26:23 -07:00
|
|
|
private ImageView mPreviewBackground;
|
|
|
|
|
private BubbleTextView mFolderName;
|
2011-05-17 16:28:09 -07:00
|
|
|
|
2011-05-31 14:30:45 -07:00
|
|
|
FolderRingAnimator mFolderRingAnimator = null;
|
2011-05-13 20:57:39 -07:00
|
|
|
|
2009-03-03 19:32:27 -08:00
|
|
|
public FolderIcon(Context context, AttributeSet attrs) {
|
|
|
|
|
super(context, attrs);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public FolderIcon(Context context) {
|
|
|
|
|
super(context);
|
|
|
|
|
}
|
|
|
|
|
|
2010-09-17 15:00:07 -07:00
|
|
|
public boolean isDropEnabled() {
|
2011-03-18 15:56:01 -07:00
|
|
|
final ViewGroup cellLayoutChildren = (ViewGroup) getParent();
|
|
|
|
|
final ViewGroup cellLayout = (ViewGroup) cellLayoutChildren.getParent();
|
|
|
|
|
final Workspace workspace = (Workspace) cellLayout.getParent();
|
|
|
|
|
return !workspace.isSmall();
|
2010-09-17 15:00:07 -07:00
|
|
|
}
|
|
|
|
|
|
2009-03-03 19:32:27 -08:00
|
|
|
static FolderIcon fromXml(int resId, Launcher launcher, ViewGroup group,
|
2011-04-27 16:56:57 -07:00
|
|
|
FolderInfo folderInfo, IconCache iconCache) {
|
2009-03-03 19:32:27 -08:00
|
|
|
|
|
|
|
|
FolderIcon icon = (FolderIcon) LayoutInflater.from(launcher).inflate(resId, group, false);
|
|
|
|
|
|
2011-06-17 13:26:23 -07:00
|
|
|
icon.mFolderName = (BubbleTextView) icon.findViewById(R.id.folder_name);
|
|
|
|
|
icon.mFolderName.setText(folderInfo.title);
|
|
|
|
|
icon.mPreviewBackground = (ImageView) icon.findViewById(R.id.preview_background);
|
|
|
|
|
|
2009-03-03 19:32:27 -08:00
|
|
|
icon.setTag(folderInfo);
|
|
|
|
|
icon.setOnClickListener(launcher);
|
|
|
|
|
icon.mInfo = folderInfo;
|
|
|
|
|
icon.mLauncher = launcher;
|
2011-05-02 15:36:58 -07:00
|
|
|
|
|
|
|
|
Folder folder = Folder.fromXml(launcher);
|
|
|
|
|
folder.setDragController(launcher.getDragController());
|
|
|
|
|
folder.setLauncher(launcher);
|
2011-05-13 20:57:39 -07:00
|
|
|
folder.setFolderIcon(icon);
|
2011-05-02 15:36:58 -07:00
|
|
|
folder.bind(folderInfo);
|
|
|
|
|
icon.mFolder = folder;
|
2011-05-31 14:30:45 -07:00
|
|
|
icon.mFolderRingAnimator = new FolderRingAnimator(launcher, icon);
|
2011-05-02 15:36:58 -07:00
|
|
|
folderInfo.addListener(icon);
|
2011-05-31 14:30:45 -07:00
|
|
|
|
|
|
|
|
return icon;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static class FolderRingAnimator {
|
|
|
|
|
public int mFolderLocX;
|
|
|
|
|
public int mFolderLocY;
|
2011-06-17 13:26:23 -07:00
|
|
|
public float mOuterRingSize;
|
|
|
|
|
public float mInnerRingSize;
|
2011-05-31 14:30:45 -07:00
|
|
|
public FolderIcon mFolderIcon = null;
|
|
|
|
|
private Launcher mLauncher;
|
2011-06-01 15:30:43 -07:00
|
|
|
public Drawable mOuterRingDrawable = null;
|
|
|
|
|
public Drawable mInnerRingDrawable = null;
|
|
|
|
|
public static Drawable sSharedOuterRingDrawable = null;
|
|
|
|
|
public static Drawable sSharedInnerRingDrawable = null;
|
2011-06-17 13:26:23 -07:00
|
|
|
public static int sPreviewSize = -1;
|
|
|
|
|
public static int sPreviewPadding = -1;
|
|
|
|
|
|
2011-06-01 15:30:43 -07:00
|
|
|
private ValueAnimator mAcceptAnimator;
|
|
|
|
|
private ValueAnimator mNeutralAnimator;
|
2011-05-31 14:30:45 -07:00
|
|
|
|
|
|
|
|
public FolderRingAnimator(Launcher launcher, FolderIcon folderIcon) {
|
|
|
|
|
mLauncher = launcher;
|
|
|
|
|
mFolderIcon = folderIcon;
|
2011-06-17 13:26:23 -07:00
|
|
|
Resources res = launcher.getResources();
|
|
|
|
|
mOuterRingDrawable = res.getDrawable(R.drawable.portal_ring_outer_holo);
|
|
|
|
|
mInnerRingDrawable = res.getDrawable(R.drawable.portal_ring_inner_holo);
|
|
|
|
|
|
|
|
|
|
if (sPreviewSize < 0 || sPreviewPadding < 0) {
|
|
|
|
|
sPreviewSize = res.getDimensionPixelSize(R.dimen.folder_preview_size);
|
|
|
|
|
sPreviewPadding = res.getDimensionPixelSize(R.dimen.folder_preview_padding);
|
|
|
|
|
}
|
2011-06-01 15:30:43 -07:00
|
|
|
if (sSharedOuterRingDrawable == null) {
|
2011-06-17 13:26:23 -07:00
|
|
|
sSharedOuterRingDrawable = res.getDrawable(R.drawable.portal_ring_outer_holo);
|
2011-05-31 14:30:45 -07:00
|
|
|
}
|
2011-06-01 15:30:43 -07:00
|
|
|
if (sSharedInnerRingDrawable == null) {
|
2011-06-17 13:26:23 -07:00
|
|
|
sSharedInnerRingDrawable = res.getDrawable(R.drawable.portal_ring_inner_holo);
|
2011-05-31 14:30:45 -07:00
|
|
|
}
|
2011-05-17 16:28:09 -07:00
|
|
|
}
|
2011-05-02 15:36:58 -07:00
|
|
|
|
2011-06-01 15:30:43 -07:00
|
|
|
// Location is expressed in window coordinates
|
2011-05-31 14:30:45 -07:00
|
|
|
public void setLocation(int x, int y) {
|
|
|
|
|
mFolderLocX = x;
|
|
|
|
|
mFolderLocY = y;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void animateToAcceptState() {
|
2011-06-01 15:30:43 -07:00
|
|
|
if (mNeutralAnimator != null) {
|
|
|
|
|
mNeutralAnimator.cancel();
|
|
|
|
|
}
|
|
|
|
|
mAcceptAnimator = ValueAnimator.ofFloat(0f, 1f);
|
|
|
|
|
mAcceptAnimator.setDuration(CONSUMPTION_ANIMATION_DURATION);
|
|
|
|
|
mAcceptAnimator.addUpdateListener(new AnimatorUpdateListener() {
|
2011-05-31 14:30:45 -07:00
|
|
|
public void onAnimationUpdate(ValueAnimator animation) {
|
|
|
|
|
final float percent = (Float) animation.getAnimatedValue();
|
2011-06-17 13:26:23 -07:00
|
|
|
mOuterRingSize = (1 + percent * OUTER_RING_GROWTH_FACTOR) * sPreviewSize;
|
|
|
|
|
mInnerRingSize = (1 + percent * INNER_RING_GROWTH_FACTOR) * sPreviewSize;
|
2011-05-31 14:30:45 -07:00
|
|
|
mLauncher.getWorkspace().invalidate();
|
|
|
|
|
if (mFolderIcon != null) {
|
|
|
|
|
mFolderIcon.invalidate();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
});
|
2011-06-01 15:30:43 -07:00
|
|
|
mAcceptAnimator.addListener(new AnimatorListenerAdapter() {
|
2011-05-31 14:30:45 -07:00
|
|
|
@Override
|
2011-06-01 15:30:43 -07:00
|
|
|
public void onAnimationStart(Animator animation) {
|
2011-05-31 14:30:45 -07:00
|
|
|
if (mFolderIcon != null) {
|
2011-06-17 13:26:23 -07:00
|
|
|
mFolderIcon.mPreviewBackground.setVisibility(INVISIBLE);
|
2011-05-31 14:30:45 -07:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
});
|
2011-06-01 15:30:43 -07:00
|
|
|
mAcceptAnimator.start();
|
2011-05-31 14:30:45 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void animateToNaturalState() {
|
2011-06-01 15:30:43 -07:00
|
|
|
if (mAcceptAnimator != null) {
|
|
|
|
|
mAcceptAnimator.cancel();
|
|
|
|
|
}
|
|
|
|
|
mNeutralAnimator = ValueAnimator.ofFloat(0f, 1f);
|
|
|
|
|
mNeutralAnimator.setDuration(CONSUMPTION_ANIMATION_DURATION);
|
|
|
|
|
mNeutralAnimator.addUpdateListener(new AnimatorUpdateListener() {
|
2011-05-31 14:30:45 -07:00
|
|
|
public void onAnimationUpdate(ValueAnimator animation) {
|
|
|
|
|
final float percent = (Float) animation.getAnimatedValue();
|
2011-06-17 13:26:23 -07:00
|
|
|
mOuterRingSize = (1 + (1 - percent) * OUTER_RING_GROWTH_FACTOR) * sPreviewSize;
|
|
|
|
|
mInnerRingSize = (1 + (1 - percent) * INNER_RING_GROWTH_FACTOR) * sPreviewSize;
|
2011-05-31 14:30:45 -07:00
|
|
|
mLauncher.getWorkspace().invalidate();
|
|
|
|
|
if (mFolderIcon != null) {
|
|
|
|
|
mFolderIcon.invalidate();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
});
|
2011-06-01 15:30:43 -07:00
|
|
|
mNeutralAnimator.addListener(new AnimatorListenerAdapter() {
|
2011-05-31 14:30:45 -07:00
|
|
|
@Override
|
|
|
|
|
public void onAnimationEnd(Animator animation) {
|
|
|
|
|
if (mFolderIcon != null) {
|
2011-06-17 13:26:23 -07:00
|
|
|
mFolderIcon.mPreviewBackground.setVisibility(VISIBLE);
|
2011-05-31 14:30:45 -07:00
|
|
|
}
|
|
|
|
|
mLauncher.getWorkspace().hideFolderAccept(FolderRingAnimator.this);
|
|
|
|
|
}
|
|
|
|
|
});
|
2011-06-01 15:30:43 -07:00
|
|
|
mNeutralAnimator.start();
|
2011-05-31 14:30:45 -07:00
|
|
|
}
|
|
|
|
|
|
2011-06-01 15:30:43 -07:00
|
|
|
// Location is expressed in window coordinates
|
2011-05-31 14:30:45 -07:00
|
|
|
public void getLocation(int[] loc) {
|
|
|
|
|
loc[0] = mFolderLocX;
|
|
|
|
|
loc[1] = mFolderLocY;
|
|
|
|
|
}
|
|
|
|
|
|
2011-06-17 13:26:23 -07:00
|
|
|
public float getOuterRingSize() {
|
|
|
|
|
return mOuterRingSize;
|
2011-05-31 14:30:45 -07:00
|
|
|
}
|
|
|
|
|
|
2011-06-17 13:26:23 -07:00
|
|
|
public float getInnerRingSize() {
|
|
|
|
|
return mInnerRingSize;
|
2011-05-17 18:45:47 -07:00
|
|
|
}
|
2009-03-03 19:32:27 -08:00
|
|
|
}
|
|
|
|
|
|
2011-05-17 16:28:09 -07:00
|
|
|
private boolean willAcceptItem(ItemInfo item) {
|
2009-03-03 19:32:27 -08:00
|
|
|
final int itemType = item.itemType;
|
2011-05-13 20:57:39 -07:00
|
|
|
return ((itemType == LauncherSettings.Favorites.ITEM_TYPE_APPLICATION ||
|
|
|
|
|
itemType == LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT) &&
|
2011-05-17 16:28:09 -07:00
|
|
|
!mFolder.isFull() && item != mInfo);
|
|
|
|
|
}
|
|
|
|
|
|
2011-06-01 15:30:43 -07:00
|
|
|
public boolean acceptDrop(Object dragInfo) {
|
|
|
|
|
final ItemInfo item = (ItemInfo) dragInfo;
|
2011-05-17 16:28:09 -07:00
|
|
|
return willAcceptItem(item);
|
2009-03-03 19:32:27 -08:00
|
|
|
}
|
|
|
|
|
|
2011-04-11 17:22:04 -07:00
|
|
|
public void addItem(ShortcutInfo item) {
|
|
|
|
|
mInfo.add(item);
|
2011-05-02 15:36:58 -07:00
|
|
|
LauncherModel.addOrMoveItemInDatabase(mLauncher, item, mInfo.id, 0, item.cellX, item.cellY);
|
2011-04-11 17:22:04 -07:00
|
|
|
}
|
|
|
|
|
|
2011-05-13 20:57:39 -07:00
|
|
|
void saveState(CellLayout.LayoutParams lp) {
|
|
|
|
|
mOriginalWidth = lp.width;
|
|
|
|
|
mOriginalHeight = lp.height;
|
|
|
|
|
}
|
|
|
|
|
|
2011-05-17 16:28:09 -07:00
|
|
|
private void determineFolderLocationInWorkspace() {
|
|
|
|
|
int tvLocation[] = new int[2];
|
|
|
|
|
int wsLocation[] = new int[2];
|
2011-06-01 15:30:43 -07:00
|
|
|
getLocationInWindow(tvLocation);
|
|
|
|
|
mLauncher.getWorkspace().getLocationInWindow(wsLocation);
|
2011-05-31 14:30:45 -07:00
|
|
|
|
|
|
|
|
int x = tvLocation[0] - wsLocation[0] + getMeasuredWidth() / 2;
|
2011-06-17 13:26:23 -07:00
|
|
|
int y = tvLocation[1] - wsLocation[1] + FolderRingAnimator.sPreviewSize / 2;
|
2011-05-31 14:30:45 -07:00
|
|
|
mFolderRingAnimator.setLocation(x, y);
|
2011-05-17 16:28:09 -07:00
|
|
|
}
|
|
|
|
|
|
2011-06-01 15:30:43 -07:00
|
|
|
public void onDragEnter(Object dragInfo) {
|
|
|
|
|
if (!willAcceptItem((ItemInfo) dragInfo)) return;
|
2011-05-17 16:28:09 -07:00
|
|
|
determineFolderLocationInWorkspace();
|
2011-05-31 14:30:45 -07:00
|
|
|
mLauncher.getWorkspace().showFolderAccept(mFolderRingAnimator);
|
|
|
|
|
mFolderRingAnimator.animateToAcceptState();
|
2011-05-17 16:28:09 -07:00
|
|
|
}
|
|
|
|
|
|
2011-06-01 15:30:43 -07:00
|
|
|
public void onDragOver(Object dragInfo) {
|
2011-05-17 16:28:09 -07:00
|
|
|
}
|
|
|
|
|
|
2011-06-01 15:30:43 -07:00
|
|
|
public void onDragExit(Object dragInfo) {
|
|
|
|
|
if (!willAcceptItem((ItemInfo) dragInfo)) return;
|
2011-05-31 14:30:45 -07:00
|
|
|
mFolderRingAnimator.animateToNaturalState();
|
2011-05-17 16:28:09 -07:00
|
|
|
}
|
|
|
|
|
|
2011-06-01 15:30:43 -07:00
|
|
|
public void onDrop(Object dragInfo) {
|
|
|
|
|
ShortcutInfo item;
|
|
|
|
|
if (dragInfo instanceof ApplicationInfo) {
|
|
|
|
|
// Came from all apps -- make a copy
|
|
|
|
|
item = ((ApplicationInfo) dragInfo).makeShortcut();
|
|
|
|
|
} else {
|
|
|
|
|
item = (ShortcutInfo) dragInfo;
|
|
|
|
|
}
|
|
|
|
|
item.cellX = -1;
|
|
|
|
|
item.cellY = -1;
|
|
|
|
|
addItem(item);
|
|
|
|
|
}
|
|
|
|
|
|
2011-05-24 14:07:08 -07:00
|
|
|
public DropTarget getDropTargetDelegate(DragObject d) {
|
2010-07-13 17:50:32 -07:00
|
|
|
return null;
|
|
|
|
|
}
|
2011-05-02 15:36:58 -07:00
|
|
|
|
|
|
|
|
@Override
|
2011-06-01 15:30:43 -07:00
|
|
|
protected void dispatchDraw(Canvas canvas) {
|
2011-06-17 13:26:23 -07:00
|
|
|
super.dispatchDraw(canvas);
|
|
|
|
|
|
2011-05-02 15:36:58 -07:00
|
|
|
if (mFolder == null) return;
|
|
|
|
|
if (mFolder.getItemCount() == 0) return;
|
|
|
|
|
|
|
|
|
|
canvas.save();
|
|
|
|
|
TextView v = (TextView) mFolder.getItemAt(0);
|
|
|
|
|
Drawable d = v.getCompoundDrawables()[1];
|
2011-06-17 13:26:23 -07:00
|
|
|
int intrinsicIconSize = d.getIntrinsicHeight();
|
2011-05-02 15:36:58 -07:00
|
|
|
|
2011-05-17 16:28:09 -07:00
|
|
|
if (mOriginalWidth < 0 || mOriginalHeight < 0) {
|
|
|
|
|
mOriginalWidth = getMeasuredWidth();
|
|
|
|
|
mOriginalHeight = getMeasuredHeight();
|
|
|
|
|
}
|
2011-06-17 13:26:23 -07:00
|
|
|
final int previewSize = FolderRingAnimator.sPreviewSize;
|
|
|
|
|
final int previewPadding = FolderRingAnimator.sPreviewPadding;
|
|
|
|
|
|
|
|
|
|
int halfAvailableSpace = (previewSize - 2 * previewPadding) / 2;
|
|
|
|
|
// cos(45) = 0.707 + ~= 0.1)
|
|
|
|
|
int availableSpace = (int) (halfAvailableSpace * (1 + 0.8f));
|
2011-05-17 16:28:09 -07:00
|
|
|
|
2011-06-17 13:26:23 -07:00
|
|
|
int unscaledHeight = (int) (intrinsicIconSize * (1 + PERSPECTIVE_SHIFT_FACTOR));
|
|
|
|
|
float baselineIconScale = (1.0f * availableSpace / unscaledHeight);
|
2011-05-26 19:08:29 -07:00
|
|
|
|
2011-06-17 13:26:23 -07:00
|
|
|
int baselineSize = (int) (intrinsicIconSize * baselineIconScale);
|
|
|
|
|
float maxPerspectiveShift = baselineSize * PERSPECTIVE_SHIFT_FACTOR;
|
2011-05-02 15:36:58 -07:00
|
|
|
|
2011-06-09 15:06:52 -07:00
|
|
|
ArrayList<View> items = mFolder.getItemsInReadingOrder(false);
|
2011-05-18 15:26:57 -07:00
|
|
|
int firstItemIndex = Math.max(0, items.size() - NUM_ITEMS_IN_PREVIEW);
|
2011-05-26 19:08:29 -07:00
|
|
|
|
2011-06-17 13:26:23 -07:00
|
|
|
int xShift = (mOriginalWidth - 2 * halfAvailableSpace) / 2;
|
|
|
|
|
int yShift = previewPadding;
|
2011-05-26 19:08:29 -07:00
|
|
|
canvas.translate(xShift, yShift);
|
2011-05-18 17:14:15 -07:00
|
|
|
for (int i = firstItemIndex; i < items.size(); i++) {
|
2011-05-26 19:08:29 -07:00
|
|
|
int index = i - firstItemIndex;
|
|
|
|
|
index += Math.max(0, NUM_ITEMS_IN_PREVIEW - items.size());
|
|
|
|
|
|
|
|
|
|
float r = (index * 1.0f) / (NUM_ITEMS_IN_PREVIEW - 1);
|
|
|
|
|
float scale = (1 - PERSPECTIVE_SCALE_FACTOR * (1 - r));
|
|
|
|
|
|
2011-06-17 13:26:23 -07:00
|
|
|
//r = (float) Math.pow(r, 2);
|
|
|
|
|
|
|
|
|
|
float offset = (1 - r) * maxPerspectiveShift;
|
|
|
|
|
float scaledSize = scale * baselineSize;
|
|
|
|
|
float scaleOffsetCorrection = (1 - scale) * baselineSize;
|
|
|
|
|
|
|
|
|
|
// We want to imagine our coordinates from the bottom left, growing up and to the
|
|
|
|
|
// right. This is natural for the x-axis, but for the y-axis, we have to invert things.
|
|
|
|
|
float transY = 2 * halfAvailableSpace - (offset + scaledSize + scaleOffsetCorrection);
|
|
|
|
|
float transX = offset + scaleOffsetCorrection;
|
2011-05-26 19:08:29 -07:00
|
|
|
|
2011-05-18 15:26:57 -07:00
|
|
|
v = (TextView) items.get(i);
|
2011-05-02 15:36:58 -07:00
|
|
|
d = v.getCompoundDrawables()[1];
|
|
|
|
|
|
2011-05-26 19:08:29 -07:00
|
|
|
canvas.save();
|
|
|
|
|
canvas.translate(transX, transY);
|
|
|
|
|
canvas.scale(baselineIconScale * scale, baselineIconScale * scale);
|
2011-05-17 18:45:47 -07:00
|
|
|
|
2011-05-26 19:08:29 -07:00
|
|
|
int overlayAlpha = (int) (80 * (1 - r));
|
2011-05-02 15:36:58 -07:00
|
|
|
if (d != null) {
|
2011-06-17 13:26:23 -07:00
|
|
|
d.setBounds(0, 0, intrinsicIconSize, intrinsicIconSize);
|
|
|
|
|
d.setFilterBitmap(true);
|
2011-05-26 19:08:29 -07:00
|
|
|
d.setColorFilter(Color.argb(overlayAlpha, 0, 0, 0), PorterDuff.Mode.SRC_ATOP);
|
2011-05-02 15:36:58 -07:00
|
|
|
d.draw(canvas);
|
2011-05-26 19:08:29 -07:00
|
|
|
d.clearColorFilter();
|
2011-06-17 13:26:23 -07:00
|
|
|
d.setFilterBitmap(false);
|
2011-05-02 15:36:58 -07:00
|
|
|
}
|
2011-05-26 19:08:29 -07:00
|
|
|
canvas.restore();
|
2011-05-02 15:36:58 -07:00
|
|
|
}
|
|
|
|
|
canvas.restore();
|
|
|
|
|
}
|
|
|
|
|
|
2011-06-09 15:06:52 -07:00
|
|
|
public void onItemsChanged() {
|
|
|
|
|
invalidate();
|
|
|
|
|
requestLayout();
|
|
|
|
|
}
|
|
|
|
|
|
2011-05-02 15:36:58 -07:00
|
|
|
public void onAdd(ShortcutInfo item) {
|
|
|
|
|
invalidate();
|
|
|
|
|
requestLayout();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void onRemove(ShortcutInfo item) {
|
|
|
|
|
invalidate();
|
|
|
|
|
requestLayout();
|
|
|
|
|
}
|
2011-06-17 13:26:23 -07:00
|
|
|
|
|
|
|
|
public void onTitleChanged(CharSequence title) {
|
|
|
|
|
mFolderName.setText(title);
|
|
|
|
|
mFolderName.invalidate();
|
|
|
|
|
mFolderName.requestLayout();
|
|
|
|
|
}
|
2009-03-03 19:32:27 -08:00
|
|
|
}
|