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/com/android/launcher2/Folder.java | |
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/com/android/launcher2/Folder.java')
-rw-r--r-- | src/com/android/launcher2/Folder.java | 347 |
1 files changed, 257 insertions, 90 deletions
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()); + } } } |