| /* |
| * 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. |
| */ |
| |
| package com.android.launcher2; |
| |
| import android.animation.Animator; |
| import android.animation.AnimatorListenerAdapter; |
| import android.animation.ObjectAnimator; |
| import android.animation.PropertyValuesHolder; |
| import android.animation.ValueAnimator; |
| import android.animation.ValueAnimator.AnimatorUpdateListener; |
| import android.content.Context; |
| import android.content.res.Resources; |
| import android.graphics.Canvas; |
| import android.graphics.drawable.Drawable; |
| import android.util.AttributeSet; |
| import android.view.LayoutInflater; |
| import android.view.ViewGroup; |
| import android.widget.FrameLayout; |
| import android.widget.TextView; |
| |
| import com.android.launcher.R; |
| import com.android.launcher2.FolderInfo.FolderListener; |
| |
| /** |
| * An icon that can appear on in the workspace representing an {@link UserFolder}. |
| */ |
| public class FolderIcon extends FrameLayout implements DropTarget, FolderListener { |
| private Launcher mLauncher; |
| Folder mFolder; |
| FolderInfo mInfo; |
| |
| private static final int NUM_ITEMS_IN_PREVIEW = 4; |
| private static final float ICON_ANGLE = 15f; |
| |
| int mOriginalWidth; |
| int mOriginalHeight; |
| int mOriginalX; |
| int mOriginalY; |
| |
| public FolderIcon(Context context, AttributeSet attrs) { |
| super(context, attrs); |
| } |
| |
| public FolderIcon(Context context) { |
| super(context); |
| } |
| |
| public boolean isDropEnabled() { |
| final ViewGroup cellLayoutChildren = (ViewGroup) getParent(); |
| final ViewGroup cellLayout = (ViewGroup) cellLayoutChildren.getParent(); |
| final Workspace workspace = (Workspace) cellLayout.getParent(); |
| return !workspace.isSmall(); |
| } |
| |
| static FolderIcon fromXml(int resId, Launcher launcher, ViewGroup group, |
| FolderInfo folderInfo, IconCache iconCache) { |
| |
| FolderIcon icon = (FolderIcon) LayoutInflater.from(launcher).inflate(resId, group, false); |
| |
| final Resources resources = launcher.getResources(); |
| Drawable d = iconCache.getFullResIcon(resources, R.drawable.portal_ring_inner_holo); |
| icon.setBackgroundDrawable(d); |
| icon.setTag(folderInfo); |
| icon.setOnClickListener(launcher); |
| icon.mInfo = folderInfo; |
| icon.mLauncher = launcher; |
| |
| Folder folder = Folder.fromXml(launcher); |
| folder.setDragController(launcher.getDragController()); |
| folder.setLauncher(launcher); |
| folder.setFolderIcon(icon); |
| folder.bind(folderInfo); |
| icon.mFolder = folder; |
| |
| folderInfo.addListener(icon); |
| |
| return icon; |
| } |
| |
| public boolean acceptDrop(DragSource source, int x, int y, int xOffset, int yOffset, |
| DragView dragView, Object dragInfo) { |
| final ItemInfo item = (ItemInfo) dragInfo; |
| final int itemType = item.itemType; |
| return ((itemType == LauncherSettings.Favorites.ITEM_TYPE_APPLICATION || |
| itemType == LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT) && |
| !mFolder.isFull()); |
| } |
| |
| public void addItem(ShortcutInfo item) { |
| mInfo.add(item); |
| LauncherModel.addOrMoveItemInDatabase(mLauncher, item, mInfo.id, 0, item.cellX, item.cellY); |
| } |
| |
| public void onDrop(DragSource source, int x, int y, int xOffset, int yOffset, |
| DragView dragView, 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); |
| } |
| |
| void saveState(CellLayout.LayoutParams lp) { |
| mOriginalWidth = lp.width; |
| mOriginalHeight = lp.height; |
| mOriginalX = lp.x; |
| mOriginalY = lp.y; |
| } |
| |
| public void onDragEnter(DragSource source, int x, int y, int xOffset, int yOffset, |
| DragView dragView, Object dragInfo) { |
| CellLayout.LayoutParams lp = (CellLayout.LayoutParams) getLayoutParams(); |
| lp.isLockedToGrid = false; |
| saveState(lp); |
| |
| PropertyValuesHolder width = PropertyValuesHolder.ofInt("width", (int) (1.1 * lp.width)); |
| PropertyValuesHolder height = PropertyValuesHolder.ofInt("height", (int) (1.1 * lp.height)); |
| PropertyValuesHolder newX = PropertyValuesHolder.ofInt("x", lp.x - (int) (0.05 * lp.width)); |
| PropertyValuesHolder newY = PropertyValuesHolder.ofInt("y", lp.y - (int) (0.05 * lp.height)); |
| ObjectAnimator oa = ObjectAnimator.ofPropertyValuesHolder(lp, width, height, newX, newY); |
| oa.addUpdateListener(new AnimatorUpdateListener() { |
| public void onAnimationUpdate(ValueAnimator animation) { |
| invalidate(); |
| requestLayout(); |
| } |
| }); |
| oa.setDuration(50); |
| oa.start(); |
| } |
| |
| public void onDragOver(DragSource source, int x, int y, int xOffset, int yOffset, |
| DragView dragView, Object dragInfo) { |
| } |
| |
| public void onDragExit(DragSource source, int x, int y, int xOffset, int yOffset, |
| DragView dragView, Object dragInfo) { |
| final CellLayout.LayoutParams lp = (CellLayout.LayoutParams) getLayoutParams(); |
| lp.isLockedToGrid = false; |
| |
| PropertyValuesHolder width = PropertyValuesHolder.ofInt("width", mOriginalWidth); |
| PropertyValuesHolder height = PropertyValuesHolder.ofInt("height", mOriginalHeight); |
| PropertyValuesHolder newX = PropertyValuesHolder.ofInt("x", mOriginalX); |
| PropertyValuesHolder newY = PropertyValuesHolder.ofInt("y", mOriginalY); |
| ObjectAnimator oa = ObjectAnimator.ofPropertyValuesHolder(lp, width, height, newX, newY); |
| oa.addUpdateListener(new AnimatorUpdateListener() { |
| public void onAnimationUpdate(ValueAnimator animation) { |
| invalidate(); |
| requestLayout(); |
| } |
| }); |
| oa.addListener(new AnimatorListenerAdapter() { |
| @Override |
| public void onAnimationEnd(Animator animation) { |
| lp.isLockedToGrid = true; |
| } |
| }); |
| oa.setDuration(50); |
| oa.start(); |
| } |
| |
| @Override |
| public DropTarget getDropTargetDelegate(DragSource source, int x, int y, int xOffset, int yOffset, |
| DragView dragView, Object dragInfo) { |
| return null; |
| } |
| |
| @Override |
| protected void onDraw(Canvas canvas) { |
| if (mFolder == null) return; |
| if (mFolder.getItemCount() == 0) return; |
| |
| canvas.save(); |
| TextView v = (TextView) mFolder.getItemAt(0); |
| Drawable d = v.getCompoundDrawables()[1]; |
| |
| canvas.translate( (getMeasuredWidth() - d.getIntrinsicWidth()) / 2, |
| (getMeasuredHeight() - d.getIntrinsicHeight()) / 2); |
| |
| canvas.translate(d.getIntrinsicWidth() / 2, d.getIntrinsicHeight() / 2); |
| canvas.rotate(ICON_ANGLE); |
| |
| canvas.translate(-d.getIntrinsicWidth() / 2, -d.getIntrinsicHeight() / 2); |
| |
| for (int i = Math.max(0, mFolder.getItemCount() - NUM_ITEMS_IN_PREVIEW); |
| i < mFolder.getItemCount(); i++) { |
| v = (TextView) mFolder.getItemAt(i); |
| d = v.getCompoundDrawables()[1]; |
| |
| if (d != null) { |
| d.setBounds(0, 0, d.getIntrinsicWidth(), d.getIntrinsicHeight()); |
| d.draw(canvas); |
| } |
| |
| canvas.translate(d.getIntrinsicWidth() / 2, d.getIntrinsicHeight() / 2); |
| canvas.rotate(-ICON_ANGLE); |
| canvas.translate(-d.getIntrinsicWidth() / 2, -d.getIntrinsicHeight() / 2); |
| } |
| |
| canvas.restore(); |
| } |
| |
| public void onAdd(ShortcutInfo item) { |
| invalidate(); |
| requestLayout(); |
| } |
| |
| public void onRemove(ShortcutInfo item) { |
| invalidate(); |
| requestLayout(); |
| } |
| } |