diff options
author | Michael Jurka <mikejurka@google.com> | 2010-08-19 13:52:27 -0700 |
---|---|---|
committer | Michael Jurka <mikejurka@google.com> | 2010-08-23 15:49:58 -0700 |
commit | a63c452f5bd491ba9b28c332ccedc6c6c7e2f3cc (patch) | |
tree | e2b3859a545fb54e91dc98b26f90697af032b6e4 /src/com/android/launcher2/Workspace.java | |
parent | 01f0ed4126be412c8c4352026dad3b2a49832267 (diff) | |
download | android_packages_apps_Trebuchet-a63c452f5bd491ba9b28c332ccedc6c6c7e2f3cc.tar.gz android_packages_apps_Trebuchet-a63c452f5bd491ba9b28c332ccedc6c6c7e2f3cc.tar.bz2 android_packages_apps_Trebuchet-a63c452f5bd491ba9b28c332ccedc6c6c7e2f3cc.zip |
added support for dragging widgets and app icons to mini screens
- gave mini screens a rounded rect background
- mini screens change color when dragged over
- added a way to specify the active region of dragged items, to allow for clipping of whitespace at borders
- fixed: feedback while dragging was often one cell off
- fixed: bug when adding to almost-full screen
- removed unused classes
Change-Id: I2fbd2aaaee6831b288cca8dec75e7b446068e8d1
Diffstat (limited to 'src/com/android/launcher2/Workspace.java')
-rw-r--r-- | src/com/android/launcher2/Workspace.java | 174 |
1 files changed, 152 insertions, 22 deletions
diff --git a/src/com/android/launcher2/Workspace.java b/src/com/android/launcher2/Workspace.java index 73eaeab9e..fc505c71b 100644 --- a/src/com/android/launcher2/Workspace.java +++ b/src/com/android/launcher2/Workspace.java @@ -34,6 +34,7 @@ import android.content.pm.ProviderInfo; import android.content.res.Resources; import android.content.res.TypedArray; import android.graphics.Canvas; +import android.graphics.Matrix; import android.graphics.Paint; import android.graphics.Rect; import android.graphics.drawable.Drawable; @@ -124,6 +125,8 @@ public class Workspace extends ViewGroup private int[] mTempCell = new int[2]; private int[] mTempEstimate = new int[2]; + private float[] mTempDragCoordinates = new float[2]; + private float[] mTempDragBottomRightCoordinates = new float[2]; private boolean mAllowLongPress = true; @@ -459,7 +462,7 @@ public class Workspace extends ViewGroup } } - CellLayout.CellInfo updateOccupiedCells(boolean[] occupied) { + CellLayout.CellInfo updateOccupiedCellsForCurrentScreen(boolean[] occupied) { CellLayout group = (CellLayout) getChildAt(mCurrentScreen); if (group != null) { return group.updateOccupiedCells(occupied, null); @@ -1309,9 +1312,31 @@ public class Workspace extends ViewGroup public void onDrop(DragSource source, int x, int y, int xOffset, int yOffset, DragView dragView, Object dragInfo) { - final CellLayout cellLayout = getCurrentDropLayout(); + CellLayout cellLayout = getCurrentDropLayout(); + 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 = findMatchingScreenForDragOver(localXY, localBottomRightXY); + 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]; + } if (source != this) { - onDropExternal(x - xOffset, y - yOffset, dragInfo, cellLayout); + onDropExternal(originX, originY, dragInfo, cellLayout); } else { // Move internally if (mDragInfo != null) { @@ -1323,7 +1348,8 @@ public class Workspace extends ViewGroup addInScreen(cell, index, mDragInfo.cellX, mDragInfo.cellY, mDragInfo.spanX, mDragInfo.spanY); } - mTargetCell = estimateDropCell(x - xOffset, y - yOffset, + + mTargetCell = estimateDropCell(originX, originY, mDragInfo.spanX, mDragInfo.spanY, cell, cellLayout, mTargetCell); cellLayout.onDropChild(cell); @@ -1381,11 +1407,87 @@ public class Workspace extends ViewGroup return null; } + // 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 findMatchingScreenForDragOver(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(); + + // 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; + 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 + float left = cl.getLeft(); + 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); + + float dragRegionX = xy[0]; + float dragRegionY = xy[1]; + float dragRegionRight = bottomRightXy[0]; + float dragRegionBottom = bottomRightXy[1]; + + // 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 + float overlap = (overlapRight - overlapLeft) * (overlapBottom - overlapTop); + if (overlap > bestOverlapSoFar) { + bestOverlapSoFar = overlap; + bestMatchingScreen = cl; + bestX = xy[0]; + bestY = xy[1]; + bestRight = bottomRightXy[0]; + bestBottom = bottomRightXy[1]; + } + } + } + if (bestMatchingScreen != null && bestMatchingScreen != mDragTargetLayout) { + if (mDragTargetLayout != null) { + mDragTargetLayout.onDragComplete(); + } + 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) { final ItemInfo item = (ItemInfo)dragInfo; - final CellLayout currentLayout = getCurrentDropLayout(); + CellLayout currentLayout = getCurrentDropLayout(); if (dragInfo instanceof LauncherAppWidgetInfo) { LauncherAppWidgetInfo widgetInfo = (LauncherAppWidgetInfo)dragInfo; @@ -1397,6 +1499,39 @@ public class Workspace extends ViewGroup 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 = findMatchingScreenForDragOver(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 + // apps screen is over + if (item != null && item.spanX == 1 && currentLayout != null) { + int dragRegionLeft = (dragView.getWidth() - currentLayout.getCellWidth()) / 2; + + originX += dragRegionLeft - dragView.getDragRegionLeft(); + if (dragView.getDragRegionWidth() != currentLayout.getCellWidth()) { + dragView.setDragRegion(dragView.getDragRegionLeft(), dragView.getDragRegionTop(), + currentLayout.getCellWidth(), dragView.getDragRegionHeight()); + } + } + } if (currentLayout != mDragTargetLayout) { if (mDragTargetLayout != null) { mDragTargetLayout.onDragComplete(); @@ -1404,23 +1539,14 @@ public class Workspace extends ViewGroup mDragTargetLayout = currentLayout; } - // Find the top left corner of the item - int originX = x - xOffset; - int originY = y - yOffset; - - // If not dragging from the Workspace, the size of dragView might not match the cell size - if (!source.equals(this)) { - // Break the drag view up into evenly sized chunks based on its spans - int chunkWidth = dragView.getWidth() / item.spanX; - int chunkHeight = dragView.getHeight() / item.spanY; - - // Adjust the origin for a cell centered at the top left chunk - originX += (chunkWidth - currentLayout.getCellWidth()) / 2; - originY += (chunkHeight - currentLayout.getCellHeight()) / 2; + // only visualize the drop locations for moving icons within the home screen on tablet + // on phone, we also visualize icons dragged in from All Apps + if ((!LauncherApplication.isScreenXLarge() || source == this) + && mDragTargetLayout != null) { + final View child = (mDragInfo == null) ? null : mDragInfo.cell; + mDragTargetLayout.visualizeDropLocation( + child, originX, originY, item.spanX, item.spanY); } - - final View child = (mDragInfo == null) ? null : mDragInfo.cell; - currentLayout.visualizeDropLocation(child, originX, originY, item.spanX, item.spanY); } public void onDragExit(DragSource source, int x, int y, int xOffset, @@ -1460,7 +1586,11 @@ public class Workspace extends ViewGroup break; case LauncherSettings.Favorites.ITEM_TYPE_APPWIDGET: cellLayout.setTagToCellInfoForPoint(x, y); - mLauncher.addAppWidgetFromDrop(((LauncherAppWidgetInfo)dragInfo).providerName, cellLayout.getTag()); + int[] position = new int[2]; + position[0] = x; + position[1] = y; + mLauncher.addAppWidgetFromDrop(((LauncherAppWidgetInfo)dragInfo).providerName, + cellLayout.getTag(), position); break; default: throw new IllegalStateException("Unknown item type: " |