diff options
author | Adam Cohen <adamcohen@google.com> | 2011-04-11 17:22:04 -0700 |
---|---|---|
committer | Adam Cohen <adamcohen@google.com> | 2011-04-15 12:04:25 -0700 |
commit | df0353815c629fc678824b07a234b89a1ff94208 (patch) | |
tree | 1afe36bae8433612563c648dff5b3ca175c1aba0 | |
parent | 3f272c6665090a006859892f441b058deb3d6fab (diff) | |
download | android_packages_apps_Trebuchet-df0353815c629fc678824b07a234b89a1ff94208.tar.gz android_packages_apps_Trebuchet-df0353815c629fc678824b07a234b89a1ff94208.tar.bz2 android_packages_apps_Trebuchet-df0353815c629fc678824b07a234b89a1ff94208.zip |
Enabling user folder creation by dropping shortcut onto shortcut
Change-Id: Ib8de001f5003cd44f1524cb7763fc928fa24aaba
-rw-r--r-- | src/com/android/launcher2/CellLayout.java | 63 | ||||
-rw-r--r-- | src/com/android/launcher2/FolderIcon.java | 8 | ||||
-rw-r--r-- | src/com/android/launcher2/Launcher.java | 9 | ||||
-rw-r--r-- | src/com/android/launcher2/Workspace.java | 59 |
4 files changed, 119 insertions, 20 deletions
diff --git a/src/com/android/launcher2/CellLayout.java b/src/com/android/launcher2/CellLayout.java index 97518a5c5..ac9d54d65 100644 --- a/src/com/android/launcher2/CellLayout.java +++ b/src/com/android/launcher2/CellLayout.java @@ -95,7 +95,7 @@ public class CellLayout extends ViewGroup { private float mGlowBackgroundScale; private float mGlowBackgroundAlpha; - private boolean mAcceptsDrops = false; + private boolean mAcceptsDrops = true; // If we're actively dragging something over this screen, mIsDragOverlapping is true private boolean mIsDragOverlapping = false; private boolean mIsDragOccuring = false; @@ -1010,13 +1010,14 @@ public class CellLayout extends ViewGroup { * @param pixelY The Y location at which you want to search for a vacant area. * @param spanX Horizontal span of the object. * @param spanY Vertical span of the object. - * @param ignoreView Considers space occupied by this view as unoccupied - * @param result Previously returned value to possibly recycle. + * @param ignoreOccupied If true, the result can be an occupied cell + * @param result Array in which to place the result, or null (in which case a new array will + * be allocated) * @return The X, Y cell of a vacant area that can contain this object, * nearest the requested location. */ - int[] findNearestVacantArea( - int pixelX, int pixelY, int spanX, int spanY, View ignoreView, int[] result) { + int[] findNearestArea(int pixelX, int pixelY, int spanX, int spanY, View ignoreView, + boolean ignoreOccupied, int[] result) { // mark space take by ignoreView as available (method checks if ignoreView is null) markCellsAsUnoccupiedForView(ignoreView); @@ -1031,13 +1032,15 @@ public class CellLayout extends ViewGroup { for (int y = 0; y < countY - (spanY - 1); y++) { inner: for (int x = 0; x < countX - (spanX - 1); x++) { - for (int i = 0; i < spanX; i++) { - for (int j = 0; j < spanY; j++) { - if (occupied[x + i][y + j]) { - // small optimization: we can skip to after the column we just found - // an occupied cell - x += i; - continue inner; + if (ignoreOccupied) { + for (int i = 0; i < spanX; i++) { + for (int j = 0; j < spanY; j++) { + if (occupied[x + i][y + j]) { + // small optimization: we can skip to after the column we + // just found an occupied cell + x += i; + continue inner; + } } } } @@ -1064,6 +1067,42 @@ public class CellLayout extends ViewGroup { } } + /** + * Find a vacant area that will fit the given bounds nearest the requested + * cell location. Uses Euclidean distance to score multiple vacant areas. + * + * @param pixelX The X location at which you want to search for a vacant area. + * @param pixelY The Y location at which you want to search for a vacant area. + * @param spanX Horizontal span of the object. + * @param spanY Vertical span of the object. + * @param ignoreView Considers space occupied by this view as unoccupied + * @param result Previously returned value to possibly recycle. + * @return The X, Y cell of a vacant area that can contain this object, + * nearest the requested location. + */ + int[] findNearestVacantArea( + int pixelX, int pixelY, int spanX, int spanY, View ignoreView, int[] result) { + return findNearestArea(pixelX, pixelY, spanX, spanY, ignoreView, true, result); + } + + /** + * Find a starting cell position that will fit the given bounds nearest the requested + * cell location. Uses Euclidean distance to score multiple vacant areas. + * + * @param pixelX The X location at which you want to search for a vacant area. + * @param pixelY The Y location at which you want to search for a vacant area. + * @param spanX Horizontal span of the object. + * @param spanY Vertical span of the object. + * @param ignoreView Considers space occupied by this view as unoccupied + * @param result Previously returned value to possibly recycle. + * @return The X, Y cell of a vacant area that can contain this object, + * nearest the requested location. + */ + int[] findNearestArea( + int pixelX, int pixelY, int spanX, int spanY, int[] result) { + return findNearestArea(pixelX, pixelY, spanX, spanY, null, false, result); + } + boolean existsEmptyCell() { return findCellForSpan(null, 1, 1); } diff --git a/src/com/android/launcher2/FolderIcon.java b/src/com/android/launcher2/FolderIcon.java index bbc3409af..a64b550e1 100644 --- a/src/com/android/launcher2/FolderIcon.java +++ b/src/com/android/launcher2/FolderIcon.java @@ -77,6 +77,11 @@ public class FolderIcon extends BubbleTextView implements DropTarget { && item.container != mInfo.id; } + public void addItem(ShortcutInfo item) { + mInfo.add(item); + LauncherModel.addOrMoveItemInDatabase(mLauncher, item, mInfo.id, 0, 0, 0); + } + public void onDrop(DragSource source, int x, int y, int xOffset, int yOffset, DragView dragView, Object dragInfo) { ShortcutInfo item; @@ -86,8 +91,7 @@ public class FolderIcon extends BubbleTextView implements DropTarget { } else { item = (ShortcutInfo)dragInfo; } - mInfo.add(item); - LauncherModel.addOrMoveItemInDatabase(mLauncher, item, mInfo.id, 0, 0, 0); + addItem(item); } public void onDragEnter(DragSource source, int x, int y, int xOffset, int yOffset, diff --git a/src/com/android/launcher2/Launcher.java b/src/com/android/launcher2/Launcher.java index a68bd9b74..bb58081ce 100644 --- a/src/com/android/launcher2/Launcher.java +++ b/src/com/android/launcher2/Launcher.java @@ -107,7 +107,6 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.List; - /** * Default launcher application. */ @@ -315,7 +314,6 @@ public final class Launcher extends Activity // share the same customization workspace across all the tabs mCustomizePagedView = (CustomizePagedView) findViewById( R.id.customization_drawer_tab_contents); - } setupViews(); @@ -1803,7 +1801,7 @@ public final class Launcher extends Activity } } - void addFolder(int screen, int intersectCellX, int intersectCellY) { + FolderIcon addFolder(int screen, int intersectCellX, int intersectCellY) { UserFolderInfo folderInfo = new UserFolderInfo(); folderInfo.title = getText(R.string.folder_name); @@ -1811,7 +1809,7 @@ public final class Launcher extends Activity final int[] cellXY = mTmpAddItemCellCoordinates; if (!layout.findCellForSpanThatIntersects(cellXY, 1, 1, intersectCellX, intersectCellY)) { showOutOfSpaceMessage(); - return; + return null; } // Update the model @@ -1825,6 +1823,7 @@ public final class Launcher extends Activity (ViewGroup) mWorkspace.getChildAt(mWorkspace.getCurrentPage()), folderInfo, mIconCache); mWorkspace.addInScreen(newFolder, screen, cellXY[0], cellXY[1], 1, 1, isWorkspaceLocked()); + return newFolder; } void removeFolder(FolderInfo folder) { @@ -3377,6 +3376,8 @@ public final class Launcher extends Activity */ public void startBinding() { final Workspace workspace = mWorkspace; + + mWorkspace.clearDropTargets(); int count = workspace.getChildCount(); for (int i = 0; i < count; i++) { // Use removeAllViewsInLayout() to avoid an extra requestLayout() and invalidate(). diff --git a/src/com/android/launcher2/Workspace.java b/src/com/android/launcher2/Workspace.java index 7e17a54f3..a156d0d82 100644 --- a/src/com/android/launcher2/Workspace.java +++ b/src/com/android/launcher2/Workspace.java @@ -2333,13 +2333,39 @@ public class Workspace extends SmoothPagedView if (dropTargetLayout != null) { // Move internally - mTargetCell = findNearestVacantArea(originX, originY, - mDragInfo.spanX, mDragInfo.spanY, cell, dropTargetLayout, + + // First we find the cell nearest to point at which the item is dropped, without + // any consideration to whether there is an item there. + mTargetCell = findNearestArea(originX, originY, + mDragInfo.spanX, mDragInfo.spanY, dropTargetLayout, mTargetCell); final int screen = (mTargetCell == null) ? mDragInfo.screen : indexOfChild(dropTargetLayout); + View v = dropTargetLayout.getChildAt(mTargetCell[0], mTargetCell[1]); + boolean hasMoved = !(mDragInfo.cellX == mTargetCell[0] && + mDragInfo.cellY == mTargetCell[1]); + + // If the item being dropped is a shortcut and the nearest drop cell also contains + // a shortcut, then create a folder with the two shortcuts. + if (v != null && (v.getTag() instanceof ShortcutInfo) && + dragInfo instanceof ShortcutInfo && hasMoved) { + ShortcutInfo info1 = (ShortcutInfo) v.getTag(); + ShortcutInfo info2 = (ShortcutInfo) dragInfo; + dropTargetLayout.removeView(v); + FolderIcon fi = mLauncher.addFolder(screen, mTargetCell[0], mTargetCell[1]); + fi.addItem(info1); + fi.addItem(info2); + return; + } + + // Aside from the special case where we're dropping a shortcut onto a shortcut, + // we need to find the nearest cell location that is vacant + mTargetCell = findNearestVacantArea(originX, originY, + mDragInfo.spanX, mDragInfo.spanY, cell, dropTargetLayout, + mTargetCell); + if (screen != mCurrentPage) { snapToPage(screen); } @@ -2984,6 +3010,20 @@ public class Workspace extends SmoothPagedView localPixelX, localPixelY, spanX, spanY, ignoreView, recycle); } + /** + * Calculate the nearest cell where the given object would be dropped. + */ + private int[] findNearestArea(int pixelX, int pixelY, + int spanX, int spanY,CellLayout layout, int[] recycle) { + + int localPixelX = pixelX - (layout.getLeft() - mScrollX); + int localPixelY = pixelY - (layout.getTop() - mScrollY); + + // Find the best target drop location + return layout.findNearestArea( + localPixelX, localPixelY, spanX, spanY, recycle); + } + void setLauncher(Launcher launcher) { mLauncher = launcher; mSpringLoadedDragController = new SpringLoadedDragController(mLauncher); @@ -3134,6 +3174,21 @@ public class Workspace extends SmoothPagedView return null; } + void clearDropTargets() { + final int screenCount = getChildCount(); + + for (int i = 0; i < screenCount; i++) { + final CellLayout layoutParent = (CellLayout) getChildAt(i); + final ViewGroup layout = layoutParent.getChildrenLayout(); + int childCount = layout.getChildCount(); + for (int j = 0; j < childCount; j++) { + View v = layout.getChildAt(j); + if (v instanceof DropTarget) { + mDragController.removeDropTarget((DropTarget) v); + } + } + } + } void removeItems(final ArrayList<ApplicationInfo> apps) { final int screenCount = getChildCount(); |