summaryrefslogtreecommitdiffstats
path: root/src/com/android/launcher2/Workspace.java
diff options
context:
space:
mode:
authorMichael Jurka <mikejurka@google.com>2010-08-19 13:52:27 -0700
committerMichael Jurka <mikejurka@google.com>2010-08-23 15:49:58 -0700
commita63c452f5bd491ba9b28c332ccedc6c6c7e2f3cc (patch)
treee2b3859a545fb54e91dc98b26f90697af032b6e4 /src/com/android/launcher2/Workspace.java
parent01f0ed4126be412c8c4352026dad3b2a49832267 (diff)
downloadandroid_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.java174
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: "