diff options
Diffstat (limited to 'src/com/android/launcher2/Workspace.java')
-rw-r--r-- | src/com/android/launcher2/Workspace.java | 303 |
1 files changed, 153 insertions, 150 deletions
diff --git a/src/com/android/launcher2/Workspace.java b/src/com/android/launcher2/Workspace.java index 599fbdabe..8f1630076 100644 --- a/src/com/android/launcher2/Workspace.java +++ b/src/com/android/launcher2/Workspace.java @@ -16,12 +16,12 @@ package com.android.launcher2; -import android.animation.Animator; -import android.animation.ObjectAnimator; import com.android.launcher.R; -import android.animation.PropertyValuesHolder; +import android.animation.Animator; import android.animation.AnimatorSet; +import android.animation.ObjectAnimator; +import android.animation.PropertyValuesHolder; import android.animation.Animator.AnimatorListener; import android.app.WallpaperManager; import android.appwidget.AppWidgetManager; @@ -46,7 +46,6 @@ import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; import android.widget.TextView; -import android.widget.Toast; import java.util.ArrayList; import java.util.HashSet; @@ -103,8 +102,10 @@ public class Workspace extends SmoothPagedView private int[] mTempCell = new int[2]; private int[] mTempEstimate = new int[2]; + private float[] mTempOriginXY = new float[2]; private float[] mTempDragCoordinates = new float[2]; private float[] mTempDragBottomRightCoordinates = new float[2]; + private Matrix mTempInverseMatrix = new Matrix(); private static final int DEFAULT_CELL_COUNT_X = 4; private static final int DEFAULT_CELL_COUNT_Y = 4; @@ -117,7 +118,6 @@ public class Workspace extends SmoothPagedView private boolean mIsSmall; private AnimatorListener mUnshrinkAnimationListener; - /** * Used to inflate the Workspace from XML. * @@ -274,35 +274,6 @@ public class Workspace extends SmoothPagedView } /** - * Adds the specified child in the current screen. The position and dimension of - * the child are defined by x, y, spanX and spanY. - * - * @param child The child to add in one of the workspace's screens. - * @param x The X position of the child in the screen's grid. - * @param y The Y position of the child in the screen's grid. - * @param spanX The number of cells spanned horizontally by the child. - * @param spanY The number of cells spanned vertically by the child. - */ - void addInCurrentScreen(View child, int x, int y, int spanX, int spanY) { - addInScreen(child, mCurrentPage, x, y, spanX, spanY, false); - } - - /** - * Adds the specified child in the current screen. The position and dimension of - * the child are defined by x, y, spanX and spanY. - * - * @param child The child to add in one of the workspace's screens. - * @param x The X position of the child in the screen's grid. - * @param y The Y position of the child in the screen's grid. - * @param spanX The number of cells spanned horizontally by the child. - * @param spanY The number of cells spanned vertically by the child. - * @param insert When true, the child is inserted at the beginning of the children list. - */ - void addInCurrentScreen(View child, int x, int y, int spanX, int spanY, boolean insert) { - addInScreen(child, mCurrentPage, x, y, spanX, spanY, insert); - } - - /** * Adds the specified child in the specified screen. The position and dimension of * the child are defined by x, y, spanX and spanY. * @@ -369,14 +340,6 @@ public class Workspace extends SmoothPagedView } } - CellLayout.CellInfo updateOccupiedCellsForCurrentScreen(boolean[] occupied) { - CellLayout group = (CellLayout) getChildAt(mCurrentPage); - if (group != null) { - return group.updateOccupiedCells(occupied, null); - } - return null; - } - public boolean onTouch(View v, MotionEvent event) { // this is an intercepted event being forwarded from a cell layout if (mIsSmall) { @@ -469,7 +432,7 @@ public class Workspace extends SmoothPagedView } @Override - protected void onLayout(boolean changed, int left, int top, int right, int bottom) { + public void onLayout(boolean changed, int left, int top, int right, int bottom) { super.onLayout(changed, left, top, right, bottom); // if shrinkToBottom() is called on initialization, it has to be deferred @@ -776,43 +739,40 @@ public class Workspace extends SmoothPagedView invalidate(); } - void addApplicationShortcut(ShortcutInfo info, CellLayout.CellInfo cellInfo) { - addApplicationShortcut(info, cellInfo, false); - } - - void addApplicationShortcut(ShortcutInfo info, CellLayout.CellInfo cellInfo, - boolean insertAtFirst) { - final CellLayout layout = (CellLayout) getChildAt(cellInfo.screen); - final int[] result = new int[2]; + void addApplicationShortcut(ShortcutInfo info, int screen, int cellX, int cellY, + boolean insertAtFirst, int intersectX, int intersectY) { + final CellLayout cellLayout = (CellLayout) getChildAt(screen); + View view = mLauncher.createShortcut(R.layout.application, cellLayout, (ShortcutInfo) info); - layout.cellToPoint(cellInfo.cellX, cellInfo.cellY, result); - onDropExternal(result[0], result[1], info, layout, insertAtFirst); + final int[] cellXY = new int[2]; + cellLayout.findCellForSpanThatIntersects(cellXY, 1, 1, intersectX, intersectY); + addInScreen(view, screen, cellXY[0], cellXY[1], 1, 1, insertAtFirst); + LauncherModel.addOrMoveItemInDatabase(mLauncher, info, + LauncherSettings.Favorites.CONTAINER_DESKTOP, screen, + cellXY[0], cellXY[1]); } + public void onDrop(DragSource source, int x, int y, int xOffset, int yOffset, DragView dragView, Object dragInfo) { - CellLayout cellLayout = getCurrentDropLayout(); + CellLayout cellLayout; int originX = x - xOffset; int originY = y - yOffset; if (mIsSmall) { - // find out which target layout is over - final float[] localXY = mTempDragCoordinates; - localXY[0] = originX; - localXY[1] = originY; - final float[] localBottomRightXY = mTempDragBottomRightCoordinates; - // we need to subtract left/top here because DragController already adds - // dragRegionLeft/Top to xOffset and yOffset - localBottomRightXY[0] = originX + dragView.getDragRegionWidth(); - localBottomRightXY[1] = originY + dragView.getDragRegionHeight(); - cellLayout = findMatchingPageForDragOver(localXY, localBottomRightXY); + cellLayout = findMatchingPageForDragOver(dragView, originX, originY); if (cellLayout == null) { // cancel the drag if we're not over a mini-screen at time of drop // TODO: maybe add a nice fade here? return; } - // localXY will be transformed into the local screen's coordinate space; save that info - originX = (int)localXY[0]; - originY = (int)localXY[1]; + // get originX and originY in the local coordinate system of the screen + mTempOriginXY[0] = originX; + mTempOriginXY[1] = originY; + mapPointGlobalToLocal(cellLayout, mTempOriginXY); + originX = (int)mTempOriginXY[0]; + originY = (int)mTempOriginXY[1]; + } else { + cellLayout = getCurrentDropLayout(); } if (source != this) { onDropExternal(originX, originY, dragInfo, cellLayout); @@ -835,8 +795,8 @@ public class Workspace extends SmoothPagedView // update the item's position after drop final ItemInfo info = (ItemInfo) cell.getTag(); - CellLayout.LayoutParams lp = (CellLayout.LayoutParams) cell - .getLayoutParams(); + CellLayout.LayoutParams lp = (CellLayout.LayoutParams) cell.getLayoutParams(); + cellLayout.onMove(cell, mTargetCell[0], mTargetCell[1]); lp.cellX = mTargetCell[0]; lp.cellY = mTargetCell[1]; @@ -854,6 +814,10 @@ public class Workspace extends SmoothPagedView public DropTarget getDropTargetDelegate(DragSource source, int x, int y, int xOffset, int yOffset, DragView dragView, Object dragInfo) { + if (mIsSmall) { + // If we're shrunken, don't let anyone drag on folders/etc that are on the mini-screens + return null; + } // We may need to delegate the drag to a child view. If a 1x1 item // would land in a cell occupied by a DragTarget (e.g. a Folder), // then drag events should be handled by that child. @@ -871,12 +835,12 @@ public class Workspace extends SmoothPagedView dragPointX = x; dragPointY = y; } + dragPointX += mScrollX - currentLayout.getLeft(); + dragPointY += mScrollY - currentLayout.getTop(); // If we are dragging over a cell that contains a DropTarget that will // accept the drop, delegate to that DropTarget. final int[] cellXY = mTempCell; - int localDragPointX = dragPointX - (currentLayout.getLeft() - mScrollX); - int localDragPointY = dragPointY - (currentLayout.getTop() - mScrollY); currentLayout.estimateDropCell(dragPointX, dragPointY, item.spanX, item.spanY, cellXY); View child = currentLayout.getChildAt(cellXY[0], cellXY[1]); if (child instanceof DropTarget) { @@ -888,29 +852,32 @@ public class Workspace extends SmoothPagedView return null; } + + private void mapPointGlobalToLocal(View v, float[] xy) { + xy[0] = xy[0] + mScrollX - v.getLeft(); + xy[1] = xy[1] + mScrollY - v.getTop(); + v.getMatrix().invert(mTempInverseMatrix); + mTempInverseMatrix.mapPoints(xy); + } + // xy = upper left corner of item being dragged // bottomRightXy = lower right corner of item being dragged // This method will see which mini-screen is most overlapped by the item being dragged, and // return it. It will also transform the parameters xy and bottomRightXy into the local // coordinate space of the returned screen - private CellLayout findMatchingPageForDragOver(float[] xy, float[] bottomRightXy) { - float x = xy[0]; - float y = xy[1]; - float right = bottomRightXy[0]; - float bottom = bottomRightXy[1]; - - float bestX = 0; - float bestY = 0; - float bestRight = 0; - float bestBottom = 0; - - Matrix inverseMatrix = new Matrix(); + private CellLayout findMatchingPageForDragOver(DragView dragView, int originX, int originY) { + float x = originX + dragView.getScaledDragRegionXOffset(); + float y = originY + dragView.getScaledDragRegionYOffset(); + float right = x + dragView.getScaledDragRegionWidth(); + float bottom = y + dragView.getScaledDragRegionHeight(); // We loop through all the screens (ie CellLayouts) and see which one overlaps the most // with the item being dragged. final int screenCount = getChildCount(); CellLayout bestMatchingScreen = null; - float bestOverlapSoFar = 0; + float smallestDistSoFar = Float.MAX_VALUE; + final float[] xy = mTempDragCoordinates; + final float[] bottomRightXy = mTempDragBottomRightCoordinates; for (int i = 0; i < screenCount; i++) { CellLayout cl = (CellLayout)getChildAt(i); // Transform the coordinates of the item being dragged to the CellLayout's coordinates @@ -918,57 +885,76 @@ public class Workspace extends SmoothPagedView float top = cl.getTop(); xy[0] = x + mScrollX - left; xy[1] = y + mScrollY - top; - cl.getMatrix().invert(inverseMatrix); bottomRightXy[0] = right + mScrollX - left; bottomRightXy[1] = bottom + mScrollY - top; - inverseMatrix.mapPoints(xy); - inverseMatrix.mapPoints(bottomRightXy); + cl.getMatrix().invert(mTempInverseMatrix); + mTempInverseMatrix.mapPoints(xy); + mTempInverseMatrix.mapPoints(bottomRightXy); float dragRegionX = xy[0]; float dragRegionY = xy[1]; float dragRegionRight = bottomRightXy[0]; float dragRegionBottom = bottomRightXy[1]; + float dragRegionCenterX = (dragRegionX + dragRegionRight) / 2.0f; + float dragRegionCenterY = (dragRegionY + dragRegionBottom) / 2.0f; // Find the overlapping region float overlapLeft = Math.max(0f, dragRegionX); float overlapTop = Math.max(0f, dragRegionY); float overlapBottom = Math.min(cl.getHeight(), dragRegionBottom); float overlapRight = Math.min(cl.getWidth(), dragRegionRight); - if (overlapRight >= 0 && overlapLeft <= cl.getWidth() && - overlapTop >= 0 && overlapBottom <= cl.getHeight()) { - // Calculate the size of the overlapping region + (overlapTop >= 0 && overlapBottom <= cl.getHeight())) { + // Calculate the distance between the two centers + float distX = dragRegionCenterX - cl.getWidth()/2; + float distY = dragRegionCenterY - cl.getHeight()/2; + float dist = distX * distX + distY * distY; + float overlap = (overlapRight - overlapLeft) * (overlapBottom - overlapTop); - if (overlap > bestOverlapSoFar) { - bestOverlapSoFar = overlap; + + // Calculate the closest overlapping region + if (overlap > 0 && dist < smallestDistSoFar) { + smallestDistSoFar = dist; bestMatchingScreen = cl; - bestX = xy[0]; - bestY = xy[1]; - bestRight = bottomRightXy[0]; - bestBottom = bottomRightXy[1]; } } } - if (bestMatchingScreen != null && bestMatchingScreen != mDragTargetLayout) { + + if (bestMatchingScreen != mDragTargetLayout) { if (mDragTargetLayout != null) { - mDragTargetLayout.onDragComplete(); + mDragTargetLayout.onDragExit(); } mDragTargetLayout = bestMatchingScreen; } - xy[0] = bestX; - xy[1] = bestY; - bottomRightXy[0] = bestRight; - bottomRightXy[1] = bestBottom; return bestMatchingScreen; } public void onDragOver(DragSource source, int x, int y, int xOffset, int yOffset, DragView dragView, Object dragInfo) { + CellLayout currentLayout; + int originX = x - xOffset; + int originY = y - yOffset; + if (mIsSmall) { + currentLayout = findMatchingPageForDragOver(dragView, originX, originY); + + if (currentLayout == null) { + return; + } + + currentLayout.setHover(true); + // get originX and originY in the local coordinate system of the screen + mTempOriginXY[0] = originX; + mTempOriginXY[1] = originY; + mapPointGlobalToLocal(currentLayout, mTempOriginXY); + originX = (int)mTempOriginXY[0]; + originY = (int)mTempOriginXY[1]; + } else { + currentLayout = getCurrentDropLayout(); + } final ItemInfo item = (ItemInfo)dragInfo; - CellLayout currentLayout = getCurrentDropLayout(); if (dragInfo instanceof LauncherAppWidgetInfo) { LauncherAppWidgetInfo widgetInfo = (LauncherAppWidgetInfo)dragInfo; @@ -980,25 +966,6 @@ public class Workspace extends SmoothPagedView item.spanY = spans[1]; } } - int originX = x - xOffset; - int originY = y - yOffset; - if (mIsSmall) { - // find out which mini screen the dragged item is over - final float[] localXY = mTempDragCoordinates; - localXY[0] = originX; - localXY[1] = originY; - final float[] localBottomRightXY = mTempDragBottomRightCoordinates; - - localBottomRightXY[0] = originX + dragView.getDragRegionWidth(); - localBottomRightXY[1] = originY + dragView.getDragRegionHeight(); - currentLayout = findMatchingPageForDragOver(localXY, localBottomRightXY); - if (currentLayout != null) { - currentLayout.setHover(true); - } - - originX = (int)localXY[0]; - originY = (int)localXY[1]; - } if (source != this) { // This is a hack to fix the point used to determine which cell an icon from the all @@ -1015,7 +982,7 @@ public class Workspace extends SmoothPagedView } if (currentLayout != mDragTargetLayout) { if (mDragTargetLayout != null) { - mDragTargetLayout.onDragComplete(); + mDragTargetLayout.onDragExit(); } mDragTargetLayout = currentLayout; } @@ -1028,14 +995,14 @@ public class Workspace extends SmoothPagedView int localOriginX = originX - (mDragTargetLayout.getLeft() - mScrollX); int localOriginY = originY - (mDragTargetLayout.getTop() - mScrollY); mDragTargetLayout.visualizeDropLocation( - child, localOriginX, localOriginY, item.spanX, item.spanY); + child, localOriginX, localOriginY, item.spanX, item.spanY, child); } } public void onDragExit(DragSource source, int x, int y, int xOffset, int yOffset, DragView dragView, Object dragInfo) { if (mDragTargetLayout != null) { - mDragTargetLayout.onDragComplete(); + mDragTargetLayout.onDragExit(); mDragTargetLayout = null; } } @@ -1055,17 +1022,43 @@ public class Workspace extends SmoothPagedView CellLayout cl = (CellLayout) layout; ItemInfo info = (ItemInfo) dragInfo; - final CellLayout.CellInfo cellInfo = cl.updateOccupiedCells(null, null); - if (cellInfo.findCellForSpan(mTempEstimate, info.spanX, info.spanY)) { + if (cl.findCellForSpan(mTempEstimate, info.spanX, info.spanY)) { onDropExternal(0, 0, dragInfo, cl, false); return true; } + mLauncher.showOutOfSpaceMessage(); return false; } + // Drag from somewhere else private void onDropExternal(int x, int y, Object dragInfo, CellLayout cellLayout, boolean insertAtFirst) { - // Drag from somewhere else + int screen = indexOfChild(cellLayout); + if (dragInfo instanceof PendingAddItemInfo) { + PendingAddItemInfo info = (PendingAddItemInfo) dragInfo; + // When dragging and dropping from customization tray, we deal with creating + // widgets/shortcuts/folders in a slightly different way + int[] touchXY = new int[2]; + touchXY[0] = x; + touchXY[1] = y; + switch (info.itemType) { + case LauncherSettings.Favorites.ITEM_TYPE_APPWIDGET: + mLauncher.addAppWidgetFromDrop(info.componentName, screen, touchXY); + break; + case LauncherSettings.Favorites.ITEM_TYPE_LIVE_FOLDER: + mLauncher.addLiveFolderFromDrop(info.componentName, screen, touchXY); + break; + case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT: + mLauncher.processShortcutFromDrop(info.componentName, screen, touchXY); + break; + default: + throw new IllegalStateException("Unknown item type: " + info.itemType); + } + cellLayout.onDragExit(); + return; + } + + // This is for other drag/drop cases, like dragging from All Apps ItemInfo info = (ItemInfo) dragInfo; View view = null; @@ -1082,25 +1075,15 @@ public class Workspace extends SmoothPagedView break; case LauncherSettings.Favorites.ITEM_TYPE_USER_FOLDER: view = FolderIcon.fromXml(R.layout.folder_icon, mLauncher, - (ViewGroup) getChildAt(mCurrentPage), - ((UserFolderInfo) info)); - break; - case LauncherSettings.Favorites.ITEM_TYPE_APPWIDGET: - cellLayout.setTagToCellInfoForPoint(x, y); - int[] position = new int[2]; - position[0] = x; - position[1] = y; - mLauncher.addAppWidgetFromDrop(((LauncherAppWidgetInfo)dragInfo).providerName, - cellLayout.getTag(), position); + cellLayout, ((UserFolderInfo) info)); break; default: - throw new IllegalStateException("Unknown item type: " - + info.itemType); + throw new IllegalStateException("Unknown item type: " + info.itemType); } // If the view is null, it has already been added. if (view == null) { - cellLayout.onDragComplete(); + cellLayout.onDragExit(); } else { mTargetCell = estimateDropCell(x, y, 1, 1, view, cellLayout, mTargetCell); addInScreen(view, indexOfChild(cellLayout), mTargetCell[0], @@ -1109,7 +1092,7 @@ public class Workspace extends SmoothPagedView CellLayout.LayoutParams lp = (CellLayout.LayoutParams) view.getLayoutParams(); LauncherModel.addOrMoveItemInDatabase(mLauncher, info, - LauncherSettings.Favorites.CONTAINER_DESKTOP, mCurrentPage, + LauncherSettings.Favorites.CONTAINER_DESKTOP, screen, lp.cellX, lp.cellY); } } @@ -1124,22 +1107,40 @@ public class Workspace extends SmoothPagedView } /** + * Return the current CellInfo describing our current drag; this method exists + * so that Launcher can sync this object with the correct info when the activity is created/ + * destroyed + * + */ + public CellLayout.CellInfo getDragInfo() { + return mDragInfo; + } + + /** * {@inheritDoc} */ public boolean acceptDrop(DragSource source, int x, int y, int xOffset, int yOffset, DragView dragView, Object dragInfo) { - final CellLayout layout = getCurrentDropLayout(); + CellLayout layout; + if (mIsSmall) { + layout = findMatchingPageForDragOver(dragView, x - xOffset, y - yOffset); + if (layout == null) { + // cancel the drag if we're not over a mini-screen at time of drop + return false; + } + } else { + layout = getCurrentDropLayout(); + } final CellLayout.CellInfo dragCellInfo = mDragInfo; final int spanX = dragCellInfo == null ? 1 : dragCellInfo.spanX; final int spanY = dragCellInfo == null ? 1 : dragCellInfo.spanY; final View ignoreView = dragCellInfo == null ? null : dragCellInfo.cell; - final CellLayout.CellInfo cellInfo = layout.updateOccupiedCells(null, ignoreView); - if (cellInfo.findCellForSpan(mTempEstimate, spanX, spanY)) { + if (layout.findCellForSpanIgnoring(null, spanX, spanY, ignoreView)) { return true; } else { - Toast.makeText(getContext(), getContext().getString(R.string.out_of_space), Toast.LENGTH_SHORT).show(); + mLauncher.showOutOfSpaceMessage(); return false; } } @@ -1156,9 +1157,9 @@ public class Workspace extends SmoothPagedView layout.estimateDropCell(localPixelX, localPixelY, spanX, spanY, cellXY); layout.cellToPoint(cellXY[0], cellXY[1], mTempEstimate); - final CellLayout.CellInfo cellInfo = layout.updateOccupiedCells(null, ignoreView); // Find the best target drop location - return layout.findNearestVacantArea(mTempEstimate[0], mTempEstimate[1], spanX, spanY, cellInfo, recycle); + return layout.findNearestVacantArea( + mTempEstimate[0], mTempEstimate[1], spanX, spanY, recycle); } /** @@ -1196,6 +1197,10 @@ public class Workspace extends SmoothPagedView mDragInfo = null; } + public boolean isDropEnabled() { + return true; + } + @Override protected void onRestoreInstanceState(Parcelable state) { super.onRestoreInstanceState(state); @@ -1366,8 +1371,6 @@ public class Workspace extends SmoothPagedView } void updateShortcuts(ArrayList<ApplicationInfo> apps) { - final PackageManager pm = mLauncher.getPackageManager(); - final int screenCount = getChildCount(); for (int i = 0; i < screenCount; i++) { final CellLayout layout = (CellLayout) getChildAt(i); |