diff options
author | Adam Cohen <adamcohen@google.com> | 2011-05-13 20:57:39 -0700 |
---|---|---|
committer | Adam Cohen <adamcohen@google.com> | 2011-05-16 17:17:27 -0700 |
commit | 2801cafe62653131fdc9da402e5c44e5ffd0bf47 (patch) | |
tree | 68c8a5fa2a77cfc1cee158f3cbc804ad4d61c7c3 /src | |
parent | b3715fe227dfaafa66479228276ef0329925085f (diff) | |
download | android_packages_apps_Trebuchet-2801cafe62653131fdc9da402e5c44e5ffd0bf47.tar.gz android_packages_apps_Trebuchet-2801cafe62653131fdc9da402e5c44e5ffd0bf47.tar.bz2 android_packages_apps_Trebuchet-2801cafe62653131fdc9da402e5c44e5ffd0bf47.zip |
Shrink-wrapped folders
Change-Id: Ida1b5d0bd4d39eabfde9f8a5bee0d4b6e9b33627
Diffstat (limited to 'src')
-rw-r--r-- | src/com/android/launcher2/CellLayout.java | 42 | ||||
-rw-r--r-- | src/com/android/launcher2/CellLayoutChildren.java | 3 | ||||
-rw-r--r-- | src/com/android/launcher2/DragLayer.java | 22 | ||||
-rw-r--r-- | src/com/android/launcher2/Folder.java | 347 | ||||
-rw-r--r-- | src/com/android/launcher2/FolderIcon.java | 66 | ||||
-rw-r--r-- | src/com/android/launcher2/Launcher.java | 33 | ||||
-rw-r--r-- | src/com/android/launcher2/Workspace.java | 9 |
7 files changed, 417 insertions, 105 deletions
diff --git a/src/com/android/launcher2/CellLayout.java b/src/com/android/launcher2/CellLayout.java index fdef18da4..5f848a8fa 100644 --- a/src/com/android/launcher2/CellLayout.java +++ b/src/com/android/launcher2/CellLayout.java @@ -321,6 +321,16 @@ public class CellLayout extends ViewGroup { return heightGap * (numCells - 1) + cellHeight * numCells + (crosshairsSize + 1) / 2; } + public void enableHardwareLayers() { + mChildren.enableHardwareLayers(); + } + + public void setGridSize(int x, int y) { + mCountX = x; + mCountY = y; + mOccupied = new boolean[mCountX][mCountY]; + } + private void invalidateBubbleTextView(BubbleTextView icon) { final int padding = icon.getPressedOrFocusedBackgroundPadding(); invalidate(icon.getLeft() + getLeftPadding() - padding, @@ -870,10 +880,10 @@ public class CellLayout extends ViewGroup { if (mWidthGap < 0 || mHeightGap < 0) { int vSpaceLeft = heightSpecSize - mTopPadding - mBottomPadding - (cellHeight * mCountY); - mHeightGap = vSpaceLeft / numHeightGaps; + mHeightGap = numHeightGaps > 0 ? vSpaceLeft / numHeightGaps : 0; int hSpaceLeft = widthSpecSize - mLeftPadding - mRightPadding - (cellWidth * mCountX); - mWidthGap = hSpaceLeft / numWidthGaps; + mWidthGap = numWidthGaps > 0 ? hSpaceLeft / numWidthGaps : 0; // center it around the min gaps int minGap = Math.min(mWidthGap, mHeightGap); @@ -894,9 +904,10 @@ public class CellLayout extends ViewGroup { int count = getChildCount(); for (int i = 0; i < count; i++) { View child = getChildAt(i); - int childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(newWidth, MeasureSpec.EXACTLY); - int childheightMeasureSpec = MeasureSpec.makeMeasureSpec(newHeight, - MeasureSpec.EXACTLY); + int childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(newWidth - mLeftPadding - + mRightPadding, MeasureSpec.EXACTLY); + int childheightMeasureSpec = MeasureSpec.makeMeasureSpec(newHeight - mTopPadding - + mBottomPadding, MeasureSpec.EXACTLY); child.measure(childWidthMeasureSpec, childheightMeasureSpec); } setMeasuredDimension(newWidth, newHeight); @@ -1027,6 +1038,13 @@ public class CellLayout extends ViewGroup { mDragCenter.set(originX, originY); } + if (dragOutline == null && v == null) { + if (mCrosshairsDrawable != null) { + invalidate(); + } + return; + } + if (nearest != null && (nearest[0] != oldDragCellX || nearest[1] != oldDragCellY)) { // Find the top left corner of the rect the object will occupy final int[] topLeft = mTmpPoint; @@ -1492,8 +1510,8 @@ public class CellLayout extends ViewGroup { static boolean findVacantCell(int[] vacant, int spanX, int spanY, int xCount, int yCount, boolean[][] occupied) { - for (int x = 0; x < xCount; x++) { - for (int y = 0; y < yCount; y++) { + for (int y = 0; y < yCount; y++) { + for (int x = 0; x < xCount; x++) { boolean available = !occupied[x][y]; out: for (int i = x; i < x + spanX - 1 && x < xCount; i++) { for (int j = y; j < y + spanY - 1 && y < yCount; j++) { @@ -1597,6 +1615,16 @@ out: for (int i = x; i < x + spanX - 1 && x < xCount; i++) { } } + public int getDesiredWidth() { + return mLeftPadding + mRightPadding + (mCountX * mCellWidth) + + (Math.max((mCountX - 1), 0) * mWidthGap); + } + + public int getDesiredHeight() { + return mTopPadding + mBottomPadding + (mCountY * mCellHeight) + + (Math.max((mCountY - 1), 0) * mHeightGap); + } + public boolean isOccupied(int x, int y) { if (x < mCountX && y < mCountY) { return mOccupied[x][y]; diff --git a/src/com/android/launcher2/CellLayoutChildren.java b/src/com/android/launcher2/CellLayoutChildren.java index f9adce0c3..59db9c9ed 100644 --- a/src/com/android/launcher2/CellLayoutChildren.java +++ b/src/com/android/launcher2/CellLayoutChildren.java @@ -40,6 +40,9 @@ public class CellLayoutChildren extends ViewGroup { public CellLayoutChildren(Context context) { super(context); mWallpaperManager = WallpaperManager.getInstance(context); + } + + public void enableHardwareLayers() { setLayerType(LAYER_TYPE_HARDWARE, null); } diff --git a/src/com/android/launcher2/DragLayer.java b/src/com/android/launcher2/DragLayer.java index c2b710ec7..7503dda72 100644 --- a/src/com/android/launcher2/DragLayer.java +++ b/src/com/android/launcher2/DragLayer.java @@ -42,6 +42,8 @@ public class DragLayer extends FrameLayout { new ArrayList<AppWidgetResizeFrame>(); private AppWidgetResizeFrame mCurrentResizeFrame; private int mXDown, mYDown; + private Folder mCurrentFolder = null; + private Launcher mLauncher; /** * Used to create a new DragLayer from XML. @@ -82,6 +84,18 @@ public class DragLayer extends FrameLayout { } } } + if (mCurrentFolder != null) { + mCurrentFolder.getHitRect(hitRect); + int[] screenPos = new int[2]; + View parent = (View) mCurrentFolder.getParent(); + if (parent != null) { + parent.getLocationOnScreen(screenPos); + hitRect.offset(screenPos[0], screenPos[1]); + if (!hitRect.contains(x, y)) { + mLauncher.closeFolder(); + } + } + } return false; } @@ -237,4 +251,12 @@ public class DragLayer extends FrameLayout { resizeFrame.snapToWidget(false); } + + public void setLauncher(Launcher l) { + mLauncher = l; + } + + public void setCurrentFolder(Folder f) { + mCurrentFolder = f; + } } diff --git a/src/com/android/launcher2/Folder.java b/src/com/android/launcher2/Folder.java index 3a8a68d56..a4aeec407 100644 --- a/src/com/android/launcher2/Folder.java +++ b/src/com/android/launcher2/Folder.java @@ -20,20 +20,21 @@ import java.util.ArrayList; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; -import android.animation.AnimatorSet; import android.animation.ObjectAnimator; import android.animation.PropertyValuesHolder; import android.animation.ValueAnimator; import android.animation.ValueAnimator.AnimatorUpdateListener; import android.content.Context; +import android.graphics.Matrix; import android.graphics.Rect; import android.util.AttributeSet; import android.view.LayoutInflater; import android.view.MotionEvent; import android.view.View; import android.view.View.OnClickListener; +import android.view.animation.AccelerateInterpolator; +import android.view.animation.DecelerateInterpolator; import android.widget.AdapterView; -import android.widget.Button; import android.widget.LinearLayout; import android.widget.TextView; import android.widget.AdapterView.OnItemClickListener; @@ -41,7 +42,6 @@ import android.widget.AdapterView.OnItemLongClickListener; import com.android.launcher.R; import com.android.launcher2.FolderInfo.FolderListener; -import com.android.launcher2.Workspace.ShrinkState; /** * Represents a set of icons chosen by the user or generated by the system. @@ -53,8 +53,6 @@ public class Folder extends LinearLayout implements DragSource, OnItemLongClickL protected Launcher mLauncher; - protected Button mCloseButton; - protected FolderInfo mInfo; /** @@ -75,6 +73,14 @@ public class Folder extends LinearLayout implements DragSource, OnItemLongClickL private final IconCache mIconCache; private int mState = STATE_NONE; private int[] mDragItemPosition = new int[2]; + private static final int FULL_GROW = 0; + private static final int PARTIAL_GROW = 1; + private int mMode = PARTIAL_GROW; + private boolean mRearrangeOnClose = false; + private FolderIcon mFolderIcon; + private int mMaxCountX; + private int mMaxCountY; + private Rect mNewSize = new Rect(); /** * Used to inflate the Workspace from XML. @@ -88,18 +94,19 @@ public class Folder extends LinearLayout implements DragSource, OnItemLongClickL mInflater = LayoutInflater.from(context); mIconCache = ((LauncherApplication)context.getApplicationContext()).getIconCache(); mExpandDuration = getResources().getInteger(R.integer.config_folderAnimDuration); + + mMaxCountX = LauncherModel.getCellCountX() - 1; + mMaxCountY = LauncherModel.getCellCountY() - 1; } @Override protected void onFinishInflate() { super.onFinishInflate(); - - mCloseButton = (Button) findViewById(R.id.folder_close); - mCloseButton.setOnClickListener(this); - mCloseButton.setOnLongClickListener(this); mContent = (CellLayout) findViewById(R.id.folder_content); + mContent.setGridSize(0, 0); + mContent.enableHardwareLayers(); } - + public void onItemClick(AdapterView parent, View v, int position, long id) { ShortcutInfo app = (ShortcutInfo) parent.getItemAtPosition(position); int[] pos = new int[2]; @@ -119,15 +126,14 @@ public class Folder extends LinearLayout implements DragSource, OnItemLongClickL item.intent.setSourceBounds(new Rect(pos[0], pos[1], pos[0] + v.getWidth(), pos[1] + v.getHeight())); mLauncher.startActivitySafely(item.intent, item); - } else { - mLauncher.closeFolder(this); } } public boolean onLongClick(View v) { Object tag = v.getTag(); if (tag instanceof ShortcutInfo) { - // refactor this code from Folder + mLauncher.closeFolder(this); + ShortcutInfo item = (ShortcutInfo) tag; if (!v.isInTouchMode()) { return false; @@ -137,7 +143,8 @@ public class Folder extends LinearLayout implements DragSource, OnItemLongClickL mDragController.startDrag(v, this, item, DragController.DRAG_ACTION_COPY); mDragItemPosition[0] = item.cellX; mDragItemPosition[1] = item.cellY; - mLauncher.closeFolder(this); + mInfo.remove(item); + mDragItem = item; } else { mLauncher.closeFolder(this); @@ -178,7 +185,11 @@ public class Folder extends LinearLayout implements DragSource, OnItemLongClickL void setLauncher(Launcher launcher) { mLauncher = launcher; } - + + void setFolderIcon(FolderIcon icon) { + mFolderIcon = icon; + } + /** * @return the FolderInfo object associated with this folder */ @@ -201,15 +212,10 @@ public class Folder extends LinearLayout implements DragSource, OnItemLongClickL void bind(FolderInfo info) { mInfo = info; - mCloseButton.setText(info.title); ArrayList<ShortcutInfo> children = info.contents; for (int i = 0; i < children.size(); i++) { ShortcutInfo child = (ShortcutInfo) children.get(i); - if ((child.cellX == -1 && child.cellY == -1) || - mContent.isOccupied(child.cellX, child.cellY)) { - findAndSetEmptyCells(child); - } - createAndAddShortcut((ShortcutInfo) children.get(i)); + onAdd(child); } mInfo.addListener(this); } @@ -232,19 +238,20 @@ public class Folder extends LinearLayout implements DragSource, OnItemLongClickL private void positionAndSizeAsIcon() { if (!(getParent() instanceof CellLayoutChildren)) return; - CellLayoutChildren clc = (CellLayoutChildren) getParent(); - CellLayout cellLayout = (CellLayout) clc.getParent(); - - FolderIcon fi = (FolderIcon) cellLayout.getChildAt(mInfo.cellX, mInfo.cellY); - CellLayout.LayoutParams iconLp = (CellLayout.LayoutParams) fi.getLayoutParams(); + CellLayout.LayoutParams iconLp = (CellLayout.LayoutParams) mFolderIcon.getLayoutParams(); CellLayout.LayoutParams lp = (CellLayout.LayoutParams) getLayoutParams(); - lp.width = iconLp.width; - lp.height = iconLp.height; - lp.x = iconLp.x; - lp.y = iconLp.y; - - mContent.setAlpha(0f); + if (mMode == PARTIAL_GROW) { + setScaleX(0.8f); + setScaleY(0.8f); + setAlpha(0f); + } else { + lp.width = iconLp.width; + lp.height = iconLp.height; + lp.x = iconLp.x; + lp.y = iconLp.y; + mContent.setAlpha(0); + } mState = STATE_SMALL; } @@ -254,41 +261,46 @@ public class Folder extends LinearLayout implements DragSource, OnItemLongClickL } if (!(getParent() instanceof CellLayoutChildren)) return; + ObjectAnimator oa; CellLayout.LayoutParams lp = (CellLayout.LayoutParams) getLayoutParams(); - CellLayoutChildren clc = (CellLayoutChildren) getParent(); - CellLayout cellLayout = (CellLayout) clc.getParent(); - Rect r = cellLayout.getContentRect(null); - - PropertyValuesHolder width = PropertyValuesHolder.ofInt("width", r.width()); - PropertyValuesHolder height = PropertyValuesHolder.ofInt("height", r.height()); - PropertyValuesHolder x = PropertyValuesHolder.ofInt("x", 0); - PropertyValuesHolder y = PropertyValuesHolder.ofInt("y", 0); - - ObjectAnimator oa = ObjectAnimator.ofPropertyValuesHolder(lp, width, height, x, y); - oa.addUpdateListener(new AnimatorUpdateListener() { - public void onAnimationUpdate(ValueAnimator animation) { - requestLayout(); - } - }); - - PropertyValuesHolder alpha = PropertyValuesHolder.ofFloat("alpha", 1.0f); - ObjectAnimator oaContentAlpha = ObjectAnimator.ofPropertyValuesHolder(mContent, alpha); + centerAboutIcon(); + if (mMode == PARTIAL_GROW) { + PropertyValuesHolder alpha = PropertyValuesHolder.ofFloat("alpha", 1); + PropertyValuesHolder scaleX = PropertyValuesHolder.ofFloat("scaleX", 1.0f); + PropertyValuesHolder scaleY = PropertyValuesHolder.ofFloat("scaleY", 1.0f); + oa = ObjectAnimator.ofPropertyValuesHolder(this, alpha, scaleX, scaleY); + } else { + PropertyValuesHolder width = PropertyValuesHolder.ofInt("width", mNewSize.width()); + PropertyValuesHolder height = PropertyValuesHolder.ofInt("height", mNewSize.height()); + PropertyValuesHolder x = PropertyValuesHolder.ofInt("x", mNewSize.left); + PropertyValuesHolder y = PropertyValuesHolder.ofInt("y", mNewSize.top); + oa = ObjectAnimator.ofPropertyValuesHolder(lp, width, height, x, y); + oa.addUpdateListener(new AnimatorUpdateListener() { + public void onAnimationUpdate(ValueAnimator animation) { + requestLayout(); + } + }); + + PropertyValuesHolder alpha = PropertyValuesHolder.ofFloat("alpha", 1.0f); + ObjectAnimator alphaOa = ObjectAnimator.ofPropertyValuesHolder(mContent, alpha); + alphaOa.setDuration(mExpandDuration); + alphaOa.setInterpolator(new AccelerateInterpolator(2.0f)); + alphaOa.start(); + } - AnimatorSet set = new AnimatorSet(); - set.playTogether(oa, oaContentAlpha); - set.setDuration(mExpandDuration); - set.addListener(new AnimatorListenerAdapter() { + oa.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationStart(Animator animation) { mState = STATE_ANIMATING; } @Override public void onAnimationEnd(Animator animation) { - mState = STATE_SMALL; + mState = STATE_OPEN; } }); - set.start(); + oa.setDuration(mExpandDuration); + oa.start(); } public void animateClosed() { @@ -296,42 +308,49 @@ public class Folder extends LinearLayout implements DragSource, OnItemLongClickL CellLayoutChildren clc = (CellLayoutChildren) getParent(); final CellLayout cellLayout = (CellLayout) clc.getParent(); + ObjectAnimator oa; - FolderIcon fi = (FolderIcon) cellLayout.getChildAt(mInfo.cellX, mInfo.cellY); - CellLayout.LayoutParams iconLp = (CellLayout.LayoutParams) fi.getLayoutParams(); - CellLayout.LayoutParams lp = (CellLayout.LayoutParams) getLayoutParams(); - - PropertyValuesHolder width = PropertyValuesHolder.ofInt("width", iconLp.width); - PropertyValuesHolder height = PropertyValuesHolder.ofInt("height", iconLp.height); - PropertyValuesHolder x = PropertyValuesHolder.ofInt("x",iconLp.x); - PropertyValuesHolder y = PropertyValuesHolder.ofInt("y", iconLp.y); - - ObjectAnimator oa = ObjectAnimator.ofPropertyValuesHolder(lp, width, height, x, y); - oa.addUpdateListener(new AnimatorUpdateListener() { - public void onAnimationUpdate(ValueAnimator animation) { - requestLayout(); - } - }); - - PropertyValuesHolder alpha = PropertyValuesHolder.ofFloat("alpha", 0f); - ObjectAnimator oaContentAlpha = ObjectAnimator.ofPropertyValuesHolder(mContent, alpha); - - AnimatorSet set = new AnimatorSet(); - set.playTogether(oa, oaContentAlpha); - set.setDuration(mExpandDuration); + if (mMode == PARTIAL_GROW) { + PropertyValuesHolder alpha = PropertyValuesHolder.ofFloat("alpha", 0); + PropertyValuesHolder scaleX = PropertyValuesHolder.ofFloat("scaleX", 0.9f); + PropertyValuesHolder scaleY = PropertyValuesHolder.ofFloat("scaleY", 0.9f); + oa = ObjectAnimator.ofPropertyValuesHolder(this, alpha, scaleX, scaleY); + } else { + CellLayout.LayoutParams iconLp = (CellLayout.LayoutParams) mFolderIcon.getLayoutParams(); + CellLayout.LayoutParams lp = (CellLayout.LayoutParams) getLayoutParams(); + + PropertyValuesHolder width = PropertyValuesHolder.ofInt("width", iconLp.width); + PropertyValuesHolder height = PropertyValuesHolder.ofInt("height", iconLp.height); + PropertyValuesHolder x = PropertyValuesHolder.ofInt("x",iconLp.x); + PropertyValuesHolder y = PropertyValuesHolder.ofInt("y", iconLp.y); + oa = ObjectAnimator.ofPropertyValuesHolder(lp, width, height, x, y); + oa.addUpdateListener(new AnimatorUpdateListener() { + public void onAnimationUpdate(ValueAnimator animation) { + requestLayout(); + } + }); + + PropertyValuesHolder alpha = PropertyValuesHolder.ofFloat("alpha", 0f); + ObjectAnimator alphaOa = ObjectAnimator.ofPropertyValuesHolder(mContent, alpha); + alphaOa.setDuration(mExpandDuration); + alphaOa.setInterpolator(new DecelerateInterpolator(2.0f)); + alphaOa.start(); + } - set.addListener(new AnimatorListenerAdapter() { + oa.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { + onCloseComplete(); cellLayout.removeViewWithoutMarkingCells(Folder.this); - mState = STATE_OPEN; + mState = STATE_SMALL; } @Override public void onAnimationStart(Animator animation) { mState = STATE_ANIMATING; } }); - set.start(); + oa.setDuration(mExpandDuration); + oa.start(); } void notifyDataSetChanged() { @@ -345,9 +364,9 @@ public class Folder extends LinearLayout implements DragSource, OnItemLongClickL 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) - && item.container != mInfo.id; + return ((itemType == LauncherSettings.Favorites.ITEM_TYPE_APPLICATION || + itemType == LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT) && + !isFull()); } public void onDrop(DragSource source, int x, int y, int xOffset, int yOffset, @@ -361,7 +380,6 @@ public class Folder extends LinearLayout implements DragSource, OnItemLongClickL } else { item = (ShortcutInfo)dragInfo; } - findAndSetEmptyCells(item); mInfo.add(item); LauncherModel.addOrMoveItemInDatabase(mLauncher, item, mInfo.id, 0, item.cellX, item.cellY); } @@ -398,20 +416,34 @@ public class Folder extends LinearLayout implements DragSource, OnItemLongClickL public void onDragEnter(DragSource source, int x, int y, int xOffset, int yOffset, DragView dragView, Object dragInfo) { + mContent.onDragEnter(); } public void onDragOver(DragSource source, int x, int y, int xOffset, int yOffset, DragView dragView, Object dragInfo) { + float[] r = mapPointFromScreenToContent(x, y, null); + mContent.visualizeDropLocation(null, null, (int) r[0], (int) r[1], 1, 1); } public void onDragExit(DragSource source, int x, int y, int xOffset, int yOffset, DragView dragView, Object dragInfo) { + mContent.onDragExit(); } - public void onDropCompleted(View target, Object dragInfo, boolean success) { - if (success) { - mInfo.remove(mDragItem); + public float[] mapPointFromScreenToContent(int x, int y, float[] r) { + if (r == null) { + r = new float[2]; } + + int[] screenLocation = new int[2]; + mContent.getLocationOnScreen(screenLocation); + + r[0] = x - screenLocation[0]; + r[1] = y - screenLocation[1]; + return r; + } + + public void onDropCompleted(View target, Object dragInfo, boolean success) { } public boolean isDropEnabled() { @@ -423,9 +455,119 @@ public class Folder extends LinearLayout implements DragSource, OnItemLongClickL return null; } + private void setupContentDimension(int count) { + ArrayList<View> list = getItemsInReadingOrder(); + + int countX = mContent.getCountX(); + int countY = mContent.getCountY(); + if (countX * countY < count) { + // Current grid is too small, expand it + if (countX <= countY && countX < mMaxCountX) { + countX++; + } else if (countY < mMaxCountY) { + countY++; + } + if (countY == 0) countY++; + + mContent.setGridSize(countX, countY); + } else if ((countX - 1) * countY >= count || (countY - 1) * countX >= count) { + // Current grid is too big, shrink it + if (countX <= countY) { + countY--; + } else { + countX--; + } + mContent.setGridSize(countX, countY); + } + arrangeChildren(list); + } + + public boolean isFull() { + return getItemCount() >= mMaxCountX * mMaxCountY; + } + + private void centerAboutIcon() { + CellLayout.LayoutParams iconLp = (CellLayout.LayoutParams) mFolderIcon.getLayoutParams(); + CellLayout.LayoutParams lp = (CellLayout.LayoutParams) getLayoutParams(); + + int width = getPaddingLeft() + getPaddingRight() + mContent.getDesiredWidth(); + int height = getPaddingTop() + getPaddingBottom() + mContent.getDesiredHeight(); + + int centerX = iconLp.x + iconLp.width / 2; + int centerY = iconLp.y + iconLp.height / 2; + int centeredLeft = centerX - width / 2; + int centeredTop = centerY - height / 2; + + CellLayoutChildren clc = (CellLayoutChildren) getParent(); + int parentWidth = 0; + int parentHeight = 0; + if (clc != null) { + parentWidth = clc.getMeasuredWidth(); + parentHeight = clc.getMeasuredHeight(); + } + + int left = Math.min(Math.max(0, centeredLeft), parentWidth - width); + int top = Math.min(Math.max(0, centeredTop), parentHeight - height); + + int folderPivotX = width / 2 + (centeredLeft - left); + int folderPivotY = height / 2 + (centeredTop - top); + setPivotX(folderPivotX); + setPivotY(folderPivotY); + int folderIconPivotX = (int) (mFolderIcon.getMeasuredWidth() * + (1.0f * folderPivotX / width)); + int folderIconPivotY = (int) (mFolderIcon.getMeasuredHeight() * + (1.0f * folderPivotY / height)); + mFolderIcon.setPivotX(folderIconPivotX); + mFolderIcon.setPivotY(folderIconPivotY); + + if (mMode == PARTIAL_GROW) { + lp.width = width; + lp.height = height; + lp.x = left; + lp.y = top; + } else { + mNewSize.set(left, top, left + width, top + height); + } + } + + private void setupContentForNumItems(int count) { + + setupContentDimension(count); + + CellLayout.LayoutParams lp = (CellLayout.LayoutParams) getLayoutParams(); + if (lp == null) { + lp = new CellLayout.LayoutParams(0, 0, -1, -1); + lp.isLockedToGrid = false; + setLayoutParams(lp); + } + centerAboutIcon(); + } + + private void arrangeChildren(ArrayList<View> list) { + int[] vacant = new int[2]; + if (list == null) { + list = getItemsInReadingOrder(); + } + mContent.removeAllViews(); + + for (int i = 0; i < list.size(); i++) { + View v = list.get(i); + mContent.getVacantCell(vacant, 1, 1); + CellLayout.LayoutParams lp = (CellLayout.LayoutParams) v.getLayoutParams(); + lp.cellX = vacant[0]; + lp.cellY = vacant[1]; + ItemInfo info = (ItemInfo) v.getTag(); + info.cellX = vacant[0]; + info.cellY = vacant[1]; + boolean insert = false; + mContent.addViewToCellLayout(v, insert ? 0 : -1, (int)info.id, lp, true); + } + } + public void onAdd(ShortcutInfo item) { - if ((item.cellX == -1 && item.cellY == -1) || - mContent.isOccupied(item.cellX, item.cellY)) { + if (!findAndSetEmptyCells(item)) { + // The current layout is full, can we expand it? + setupContentForNumItems(getItemCount() + 1); findAndSetEmptyCells(item); } createAndAddShortcut(item); @@ -439,8 +581,33 @@ public class Folder extends LinearLayout implements DragSource, OnItemLongClickL return mContent.getChildrenLayout().getChildAt(index); } + private ArrayList<View> getItemsInReadingOrder() { + ArrayList<View> list = new ArrayList<View>(); + for (int j = 0; j < mContent.getCountY(); j++) { + for (int i = 0; i < mContent.getCountX(); i++) { + View v = mContent.getChildAt(i, j); + if (v != null) { + list.add(v); + } + } + } + return list; + } + + private void onCloseComplete() { + if (mRearrangeOnClose) { + setupContentForNumItems(getItemCount()); + mRearrangeOnClose = false; + } + } + public void onRemove(ShortcutInfo item) { View v = mContent.getChildAt(mDragItemPosition[0], mDragItemPosition[1]); mContent.removeView(v); + if (mState == STATE_ANIMATING) { + mRearrangeOnClose = true; + } else { + setupContentForNumItems(getItemCount()); + } } } diff --git a/src/com/android/launcher2/FolderIcon.java b/src/com/android/launcher2/FolderIcon.java index b770cd6d1..aa7d079c0 100644 --- a/src/com/android/launcher2/FolderIcon.java +++ b/src/com/android/launcher2/FolderIcon.java @@ -16,6 +16,12 @@ 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; @@ -40,6 +46,11 @@ public class FolderIcon extends FrameLayout implements DropTarget, FolderListene 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); } @@ -61,7 +72,7 @@ public class FolderIcon extends FrameLayout implements DropTarget, FolderListene FolderIcon icon = (FolderIcon) LayoutInflater.from(launcher).inflate(resId, group, false); final Resources resources = launcher.getResources(); - Drawable d = iconCache.getFullResIcon(resources, R.drawable.folder_bg); + Drawable d = iconCache.getFullResIcon(resources, R.drawable.portal_ring_inner_holo); icon.setBackgroundDrawable(d); icon.setTag(folderInfo); icon.setOnClickListener(launcher); @@ -71,6 +82,7 @@ public class FolderIcon extends FrameLayout implements DropTarget, FolderListene Folder folder = Folder.fromXml(launcher); folder.setDragController(launcher.getDragController()); folder.setLauncher(launcher); + folder.setFolderIcon(icon); folder.bind(folderInfo); icon.mFolder = folder; @@ -83,9 +95,9 @@ public class FolderIcon extends FrameLayout implements DropTarget, FolderListene 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) - && item.container != mInfo.id; + return ((itemType == LauncherSettings.Favorites.ITEM_TYPE_APPLICATION || + itemType == LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT) && + !mFolder.isFull()); } public void addItem(ShortcutInfo item) { @@ -107,8 +119,32 @@ public class FolderIcon extends FrameLayout implements DropTarget, FolderListene 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, @@ -117,6 +153,28 @@ public class FolderIcon extends FrameLayout implements DropTarget, FolderListene 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 diff --git a/src/com/android/launcher2/Launcher.java b/src/com/android/launcher2/Launcher.java index 2fe1c7d5b..9dfed6945 100644 --- a/src/com/android/launcher2/Launcher.java +++ b/src/com/android/launcher2/Launcher.java @@ -28,6 +28,8 @@ import java.util.List; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; import android.animation.AnimatorSet; +import android.animation.ObjectAnimator; +import android.animation.PropertyValuesHolder; import android.animation.ValueAnimator; import android.animation.ValueAnimator.AnimatorUpdateListener; import android.app.Activity; @@ -266,6 +268,8 @@ public final class Launcher extends Activity private static Drawable.ConstantState sVoiceSearchIcon; private static Drawable.ConstantState sAppMarketIcon; + private DragLayer mDragLayer; + private BubbleTextView mWaitingForResume; private static ArrayList<PendingAddArguments> sPendingAddList @@ -894,6 +898,8 @@ public final class Launcher extends Activity DragLayer dragLayer = (DragLayer) findViewById(R.id.drag_layer); dragLayer.setDragController(dragController); + dragLayer.setLauncher(this); + mDragLayer = dragLayer; if (LauncherApplication.isScreenLarge()) { mAllAppsGrid = (AllAppsView) dragLayer.findViewById(R.id.all_apps_view); @@ -1917,10 +1923,11 @@ public final class Launcher extends Activity } } - private void closeFolder() { + public void closeFolder() { Folder folder = mWorkspace.getOpenFolder(); if (folder != null) { closeFolder(folder); + mDragLayer.setCurrentFolder(null); } } @@ -1930,6 +1937,8 @@ public final class Launcher extends Activity ViewGroup parent = (ViewGroup) folder.getParent().getParent(); if (parent != null) { CellLayout cl = (CellLayout) parent; + FolderIcon fi = (FolderIcon) cl.getChildAt(folder.mInfo.cellX, folder.mInfo.cellY); + shrinkAndFadeInFolderIcon(fi); mDragController.removeDropTarget((DropTarget)folder); } @@ -2128,6 +2137,26 @@ public final class Launcher extends Activity } } + private void growAndFadeOutFolderIcon(FolderIcon fi) { + PropertyValuesHolder alpha = PropertyValuesHolder.ofFloat("alpha", 0); + PropertyValuesHolder scaleX = PropertyValuesHolder.ofFloat("scaleX", 1.5f); + PropertyValuesHolder scaleY = PropertyValuesHolder.ofFloat("scaleY", 1.5f); + + ObjectAnimator oa = ObjectAnimator.ofPropertyValuesHolder(fi, alpha, scaleX, scaleY); + oa.setDuration(getResources().getInteger(R.integer.config_folderAnimDuration)); + oa.start(); + } + + private void shrinkAndFadeInFolderIcon(FolderIcon fi) { + PropertyValuesHolder alpha = PropertyValuesHolder.ofFloat("alpha", 1.0f); + PropertyValuesHolder scaleX = PropertyValuesHolder.ofFloat("scaleX", 1.0f); + PropertyValuesHolder scaleY = PropertyValuesHolder.ofFloat("scaleY", 1.0f); + + ObjectAnimator oa = ObjectAnimator.ofPropertyValuesHolder(fi, alpha, scaleX, scaleY); + oa.setDuration(getResources().getInteger(R.integer.config_folderAnimDuration)); + oa.start(); + } + /** * Opens the user folder described by the specified tag. The opening of the folder * is animated relative to the specified View. If the View is null, no animation @@ -2139,9 +2168,11 @@ public final class Launcher extends Activity Folder folder = folderIcon.mFolder; FolderInfo info = folder.mInfo; + growAndFadeOutFolderIcon(folderIcon); info.opened = true; mWorkspace.addInFullScreen(folder, info.screen); + mDragLayer.setCurrentFolder(folder); folder.animateOpen(); folder.onOpen(); } diff --git a/src/com/android/launcher2/Workspace.java b/src/com/android/launcher2/Workspace.java index 70de0a4f7..24160f056 100644 --- a/src/com/android/launcher2/Workspace.java +++ b/src/com/android/launcher2/Workspace.java @@ -389,10 +389,13 @@ public class Workspace extends SmoothPagedView if (!(child instanceof CellLayout)) { throw new IllegalArgumentException("A Workspace can only have CellLayout children."); } - ((CellLayout) child).setOnInterceptTouchListener(this); - child.setOnClickListener(this); - child.setClickable(true); + CellLayout cl = ((CellLayout) child); + cl.setOnInterceptTouchListener(this); + cl.setOnClickListener(this); + cl.setClickable(true); + cl.enableHardwareLayers(); } + @Override public void addView(View child, int index, LayoutParams params) { onAddView(child); |