Merge change 40 into donut
* changes: Make Launcher more forgiving when dragging desktop items.
This commit is contained in:
@@ -24,4 +24,5 @@
|
||||
<color name="delete_color_filter">#A5FF0000</color>
|
||||
|
||||
<color name="appwidget_error_color">#fccc</color>
|
||||
<color name="snag_callout_color">#f444</color>
|
||||
</resources>
|
||||
|
||||
@@ -174,7 +174,7 @@ public class CellLayout extends ViewGroup {
|
||||
final int yCount = portrait ? mLongAxisCells : mShortAxisCells;
|
||||
|
||||
final boolean[][] occupied = mOccupied;
|
||||
findOccupiedCells(xCount, yCount, occupied);
|
||||
findOccupiedCells(xCount, yCount, occupied, null);
|
||||
|
||||
cellInfo.cell = null;
|
||||
cellInfo.cellX = cellXY[0];
|
||||
@@ -215,7 +215,7 @@ public class CellLayout extends ViewGroup {
|
||||
final int yCount = portrait ? mLongAxisCells : mShortAxisCells;
|
||||
|
||||
final boolean[][] occupied = mOccupied;
|
||||
findOccupiedCells(xCount, yCount, occupied);
|
||||
findOccupiedCells(xCount, yCount, occupied, null);
|
||||
|
||||
findIntersectingVacantCells(info, info.cellX, info.cellY, xCount, yCount, occupied);
|
||||
|
||||
@@ -315,7 +315,7 @@ public class CellLayout extends ViewGroup {
|
||||
return true;
|
||||
}
|
||||
|
||||
CellInfo findAllVacantCells(boolean[] occupiedCells) {
|
||||
CellInfo findAllVacantCells(boolean[] occupiedCells, View ignoreView) {
|
||||
final boolean portrait = mPortrait;
|
||||
final int xCount = portrait ? mShortAxisCells : mLongAxisCells;
|
||||
final int yCount = portrait ? mLongAxisCells : mShortAxisCells;
|
||||
@@ -329,7 +329,7 @@ public class CellLayout extends ViewGroup {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
findOccupiedCells(xCount, yCount, occupied);
|
||||
findOccupiedCells(xCount, yCount, occupied, ignoreView);
|
||||
}
|
||||
|
||||
CellInfo cellInfo = new CellInfo();
|
||||
@@ -527,64 +527,72 @@ public class CellLayout extends ViewGroup {
|
||||
super.setChildrenDrawnWithCacheEnabled(enabled);
|
||||
}
|
||||
|
||||
boolean acceptChildDrop(int x, int y, int cellHSpan, int cellVSpan, View cell) {
|
||||
int[] cellXY = mCellXY;
|
||||
pointToCellRounded(x, y, cellXY);
|
||||
int cellX = cellXY[0];
|
||||
int cellY = cellXY[1];
|
||||
|
||||
return findCell(cellX, cellY, cellHSpan, cellVSpan, cell) == null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the first View intersecting with the specified cell. If the cell is outside
|
||||
* of the layout, this is returned.
|
||||
*
|
||||
* @param cellX The X location of the cell to test.
|
||||
* @param cellY The Y location of the cell to test.
|
||||
* @param cellHSpan The horizontal span of the cell to test.
|
||||
* @param cellVSpan The vertical span of the cell to test.
|
||||
* @param ignoreCell View to ignore during the test.
|
||||
*
|
||||
* @return Returns the first View intersecting with the specified cell, this if the cell
|
||||
* lies outside of this layout's grid or null if no View was found.
|
||||
* Find a vacant area that will fit the given bounds nearest the requested
|
||||
* cell location. Uses Euclidean distance to score multiple vacant areas.
|
||||
*
|
||||
* @param cellX The X location of the desired location.
|
||||
* @param cellY The Y location of the desired location.
|
||||
* @param spanX Horizontal span of the object.
|
||||
* @param spanY Vertical span of the object.
|
||||
* @param vacantCells Pre-computed set of vacant cells to search.
|
||||
* @param recycle Previously returned value to possibly recycle.
|
||||
* @return The X, Y cell of a vacant area that can contain this object,
|
||||
* nearest the requested location.
|
||||
*/
|
||||
View findCell(int cellX, int cellY, int cellHSpan, int cellVSpan, View ignoreCell) {
|
||||
if (cellX < 0 || cellX + cellHSpan > (mPortrait ? mShortAxisCells : mLongAxisCells) ||
|
||||
cellY < 0 || cellY + cellVSpan > (mPortrait ? mLongAxisCells : mShortAxisCells)) {
|
||||
return this;
|
||||
int[] findNearestVacantArea(int pixelX, int pixelY, int spanX, int spanY,
|
||||
CellInfo vacantCells, int[] recycle) {
|
||||
|
||||
// Keep track of best-scoring drop area
|
||||
final int[] bestXY = recycle != null ? recycle : new int[2];
|
||||
final int[] cellXY = mCellXY;
|
||||
double bestDistance = Double.MAX_VALUE;
|
||||
|
||||
// Bail early if vacant cells aren't valid
|
||||
if (!vacantCells.valid) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final int count = getChildCount();
|
||||
for (int i = 0; i < count; i++) {
|
||||
final View view = getChildAt(i);
|
||||
if (view == ignoreCell) {
|
||||
// Look across all vacant cells for best fit
|
||||
final int size = vacantCells.vacantCells.size();
|
||||
for (int i = 0; i < size; i++) {
|
||||
final CellInfo.VacantCell cell = vacantCells.vacantCells.get(i);
|
||||
|
||||
// Reject if vacant cell isn't our exact size
|
||||
if (cell.spanX != spanX || cell.spanY != spanY) {
|
||||
continue;
|
||||
}
|
||||
|
||||
final LayoutParams lp = (LayoutParams) view.getLayoutParams();
|
||||
if (cellX < lp.cellX + lp.cellHSpan && lp.cellX < cellX + cellHSpan &&
|
||||
cellY < lp.cellY + lp.cellVSpan && lp.cellY < cellY + cellVSpan) {
|
||||
return view;
|
||||
|
||||
// Score is center distance from requested pixel
|
||||
cellToPoint(cell.cellX, cell.cellY, cellXY);
|
||||
|
||||
double distance = Math.sqrt(Math.pow(cellXY[0] - pixelX, 2) +
|
||||
Math.pow(cellXY[1] - pixelY, 2));
|
||||
if (distance <= bestDistance) {
|
||||
bestDistance = distance;
|
||||
bestXY[0] = cell.cellX;
|
||||
bestXY[1] = cell.cellY;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
// Return null if no suitable location found
|
||||
if (bestDistance < Double.MAX_VALUE) {
|
||||
return bestXY;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Drop a child at the specified position
|
||||
*
|
||||
* @param child The child that is being dropped
|
||||
* @param cellX The child's new x location
|
||||
* @param cellY The child's new y location
|
||||
* @param targetXY Destination area to move to
|
||||
*/
|
||||
void onDropChild(View child, int cellX, int cellY) {
|
||||
int[] cellXY = mCellXY;
|
||||
pointToCellRounded(cellX, cellY, cellXY);
|
||||
void onDropChild(View child, int[] targetXY) {
|
||||
LayoutParams lp = (LayoutParams) child.getLayoutParams();
|
||||
lp.cellX = cellXY[0];
|
||||
lp.cellY = cellXY[1];
|
||||
lp.cellX = targetXY[0];
|
||||
lp.cellY = targetXY[1];
|
||||
lp.isDragging = false;
|
||||
mDragRect.setEmpty();
|
||||
child.requestLayout();
|
||||
@@ -688,7 +696,7 @@ public class CellLayout extends ViewGroup {
|
||||
final int yCount = portrait ? mLongAxisCells : mShortAxisCells;
|
||||
final boolean[][] occupied = mOccupied;
|
||||
|
||||
findOccupiedCells(xCount, yCount, occupied);
|
||||
findOccupiedCells(xCount, yCount, occupied, null);
|
||||
|
||||
return findVacantCell(vacant, spanX, spanY, xCount, yCount, occupied);
|
||||
}
|
||||
@@ -723,7 +731,7 @@ out: for (int i = x; i < x + spanX - 1 && x < xCount; i++) {
|
||||
final int yCount = portrait ? mLongAxisCells : mShortAxisCells;
|
||||
final boolean[][] occupied = mOccupied;
|
||||
|
||||
findOccupiedCells(xCount, yCount, occupied);
|
||||
findOccupiedCells(xCount, yCount, occupied, null);
|
||||
|
||||
final boolean[] flat = new boolean[xCount * yCount];
|
||||
for (int y = 0; y < yCount; y++) {
|
||||
@@ -735,7 +743,7 @@ out: for (int i = x; i < x + spanX - 1 && x < xCount; i++) {
|
||||
return flat;
|
||||
}
|
||||
|
||||
private void findOccupiedCells(int xCount, int yCount, boolean[][] occupied) {
|
||||
private void findOccupiedCells(int xCount, int yCount, boolean[][] occupied, View ignoreView) {
|
||||
for (int x = 0; x < xCount; x++) {
|
||||
for (int y = 0; y < yCount; y++) {
|
||||
occupied[x][y] = false;
|
||||
@@ -745,7 +753,7 @@ out: for (int i = x; i < x + spanX - 1 && x < xCount; i++) {
|
||||
int count = getChildCount();
|
||||
for (int i = 0; i < count; i++) {
|
||||
View child = getChildAt(i);
|
||||
if (child instanceof Folder) {
|
||||
if (child instanceof Folder || child.equals(ignoreView)) {
|
||||
continue;
|
||||
}
|
||||
LayoutParams lp = (LayoutParams) child.getLayoutParams();
|
||||
|
||||
@@ -19,6 +19,7 @@ package com.android.launcher;
|
||||
import android.widget.ImageView;
|
||||
import android.content.Context;
|
||||
import android.content.res.TypedArray;
|
||||
import android.graphics.Rect;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.View;
|
||||
import android.view.animation.TranslateAnimation;
|
||||
@@ -77,6 +78,10 @@ public class DeleteZone extends ImageView implements DropTarget, DragController.
|
||||
Object dragInfo) {
|
||||
return true;
|
||||
}
|
||||
|
||||
public Rect estimateDropLocation(DragSource source, int x, int y, int xOffset, int yOffset, Object dragInfo, Rect recycle) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public void onDrop(DragSource source, int x, int y, int xOffset, int yOffset, Object dragInfo) {
|
||||
final ItemInfo item = (ItemInfo) dragInfo;
|
||||
|
||||
@@ -113,8 +113,25 @@ public class DragLayer extends FrameLayout implements DragController {
|
||||
private DropTarget mLastDropTarget;
|
||||
|
||||
private final Paint mTrashPaint = new Paint();
|
||||
private final Paint mEstimatedPaint = new Paint();
|
||||
private Paint mDragPaint;
|
||||
|
||||
/**
|
||||
* If true, draw a "snag" showing where the object currently being dragged
|
||||
* would end up if dropped from current location.
|
||||
*/
|
||||
private static final boolean DRAW_TARGET_SNAG = false;
|
||||
|
||||
private Rect mEstimatedRect = new Rect();
|
||||
private float[] mDragCenter = new float[2];
|
||||
private float[] mEstimatedCenter = new float[2];
|
||||
private boolean mDrawEstimated = false;
|
||||
|
||||
private int mTriggerWidth = -1;
|
||||
private int mTriggerHeight = -1;
|
||||
|
||||
private static final int DISTANCE_DRAW_SNAG = 20;
|
||||
|
||||
private static final int ANIMATION_STATE_STARTING = 1;
|
||||
private static final int ANIMATION_STATE_RUNNING = 2;
|
||||
private static final int ANIMATION_STATE_DONE = 3;
|
||||
@@ -141,6 +158,13 @@ public class DragLayer extends FrameLayout implements DragController {
|
||||
|
||||
final int srcColor = context.getResources().getColor(R.color.delete_color_filter);
|
||||
mTrashPaint.setColorFilter(new PorterDuffColorFilter(srcColor, PorterDuff.Mode.SRC_ATOP));
|
||||
|
||||
// Make estimated paint area in gray
|
||||
int snagColor = context.getResources().getColor(R.color.snag_callout_color);
|
||||
mEstimatedPaint.setColor(snagColor);
|
||||
mEstimatedPaint.setStrokeWidth(3);
|
||||
mEstimatedPaint.setAntiAlias(true);
|
||||
|
||||
}
|
||||
|
||||
public void startDrag(View v, DragSource source, Object dragInfo, int dragAction) {
|
||||
@@ -177,6 +201,9 @@ public class DragLayer extends FrameLayout implements DragController {
|
||||
int width = viewBitmap.getWidth();
|
||||
int height = viewBitmap.getHeight();
|
||||
|
||||
mTriggerWidth = width * 2 / 3;
|
||||
mTriggerHeight = height * 2 / 3;
|
||||
|
||||
Matrix scale = new Matrix();
|
||||
float scaleFactor = v.getWidth();
|
||||
scaleFactor = (scaleFactor + DRAG_SCALE) /scaleFactor;
|
||||
@@ -252,6 +279,13 @@ public class DragLayer extends FrameLayout implements DragController {
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
// Only draw estimate drop "snag" when requested
|
||||
if (DRAW_TARGET_SNAG && mDrawEstimated) {
|
||||
canvas.drawLine(mDragCenter[0], mDragCenter[1], mEstimatedCenter[0], mEstimatedCenter[1], mEstimatedPaint);
|
||||
canvas.drawCircle(mEstimatedCenter[0], mEstimatedCenter[1], 8, mEstimatedPaint);
|
||||
}
|
||||
|
||||
// Draw actual icon being dragged
|
||||
canvas.drawBitmap(mDragBitmap,
|
||||
mScrollX + mLastMotionX - mTouchOffsetX - mBitmapOffsetX,
|
||||
mScrollY + mLastMotionY - mTouchOffsetY - mBitmapOffsetY, mDragPaint);
|
||||
@@ -355,8 +389,16 @@ public class DragLayer extends FrameLayout implements DragController {
|
||||
left = (int) (scrollX + x - touchX - offsetX);
|
||||
top = (int) (scrollY + y - touchY - offsetY);
|
||||
|
||||
// Invalidate current icon position
|
||||
rect.union(left - 1, top - 1, left + width + 1, top + height + 1);
|
||||
invalidate(rect);
|
||||
|
||||
mDragCenter[0] = rect.centerX();
|
||||
mDragCenter[1] = rect.centerY();
|
||||
|
||||
// Invalidate any old estimated location
|
||||
if (DRAW_TARGET_SNAG && mDrawEstimated) {
|
||||
rect.union(mEstimatedRect);
|
||||
}
|
||||
|
||||
final int[] coordinates = mDropCoordinates;
|
||||
DropTarget dropTarget = findDropTarget((int) x, (int) y, coordinates);
|
||||
@@ -378,6 +420,33 @@ public class DragLayer extends FrameLayout implements DragController {
|
||||
(int) mTouchOffsetX, (int) mTouchOffsetY, mDragInfo);
|
||||
}
|
||||
}
|
||||
|
||||
// Render estimated drop "snag" only outside of width
|
||||
mDrawEstimated = false;
|
||||
if (DRAW_TARGET_SNAG && dropTarget != null) {
|
||||
Rect foundEstimate = dropTarget.estimateDropLocation(mDragSource,
|
||||
(int) (scrollX + mLastMotionX), (int) (scrollY + mLastMotionY),
|
||||
(int) mTouchOffsetX, (int) mTouchOffsetY, mDragInfo, mEstimatedRect);
|
||||
|
||||
if (foundEstimate != null) {
|
||||
mEstimatedCenter[0] = foundEstimate.centerX();
|
||||
mEstimatedCenter[1] = foundEstimate.centerY();
|
||||
|
||||
int deltaX = (int) Math.abs(mEstimatedCenter[0] - mDragCenter[0]);
|
||||
int deltaY = (int) Math.abs(mEstimatedCenter[1] - mDragCenter[1]);
|
||||
|
||||
if (deltaX > mTriggerWidth || deltaY > mTriggerHeight) {
|
||||
mDrawEstimated = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Include new estimated area in invalidated rectangle
|
||||
if (DRAW_TARGET_SNAG && mDrawEstimated) {
|
||||
rect.union(mEstimatedRect);
|
||||
}
|
||||
invalidate(rect);
|
||||
|
||||
mLastDropTarget = dropTarget;
|
||||
|
||||
boolean inDragRegion = false;
|
||||
@@ -478,9 +547,15 @@ public class DragLayer extends FrameLayout implements DragController {
|
||||
}
|
||||
if (target == null) {
|
||||
if (child instanceof DropTarget) {
|
||||
dropCoordinates[0] = x;
|
||||
dropCoordinates[1] = y;
|
||||
return (DropTarget) child;
|
||||
// Only consider this child if they will accept
|
||||
DropTarget childTarget = (DropTarget) child;
|
||||
if (childTarget.acceptDrop(mDragSource, x, y, 0, 0, mDragInfo)) {
|
||||
dropCoordinates[0] = x;
|
||||
dropCoordinates[1] = y;
|
||||
return (DropTarget) child;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return target;
|
||||
@@ -531,6 +606,7 @@ public class DragLayer extends FrameLayout implements DragController {
|
||||
|
||||
public void run() {
|
||||
if (mDragScroller != null) {
|
||||
mDrawEstimated = false;
|
||||
if (mDirection == SCROLL_LEFT) {
|
||||
mDragScroller.scrollLeft();
|
||||
} else {
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
|
||||
package com.android.launcher;
|
||||
|
||||
import android.graphics.Rect;
|
||||
|
||||
/**
|
||||
* Interface defining an object that can receive a drag.
|
||||
*
|
||||
@@ -42,18 +44,38 @@ public interface DropTarget {
|
||||
void onDragExit(DragSource source, int x, int y, int xOffset, int yOffset, Object dragInfo);
|
||||
|
||||
/**
|
||||
* Indicates whether a drop action can occur at the specified location. The method
|
||||
* {@link #onDrop(DragSource, int, int, int, int, Object)} will be invoked on this
|
||||
* drop target only if this method returns true.
|
||||
*
|
||||
* Check if a drop action can occur at, or near, the requested location.
|
||||
* This may be called repeatedly during a drag, so any calls should return
|
||||
* quickly.
|
||||
*
|
||||
* @param source DragSource where the drag started
|
||||
* @param x X coordinate of the drop location
|
||||
* @param y Y coordinate of the drop location
|
||||
* @param xOffset Horizontal offset with the object being dragged where the original touch happened
|
||||
* @param yOffset Vertical offset with the object being dragged where the original touch happened
|
||||
* @param xOffset Horizontal offset with the object being dragged where the
|
||||
* original touch happened
|
||||
* @param yOffset Vertical offset with the object being dragged where the
|
||||
* original touch happened
|
||||
* @param dragInfo Data associated with the object being dragged
|
||||
*
|
||||
* return True if the drop is accepted, false otherwise.
|
||||
* @return True if the drop will be accepted, false otherwise.
|
||||
*/
|
||||
boolean acceptDrop(DragSource source, int x, int y, int xOffset, int yOffset, Object dragInfo);
|
||||
|
||||
/**
|
||||
* Estimate the surface area where this object would land if dropped at the
|
||||
* given location.
|
||||
*
|
||||
* @param source DragSource where the drag started
|
||||
* @param x X coordinate of the drop location
|
||||
* @param y Y coordinate of the drop location
|
||||
* @param xOffset Horizontal offset with the object being dragged where the
|
||||
* original touch happened
|
||||
* @param yOffset Vertical offset with the object being dragged where the
|
||||
* original touch happened
|
||||
* @param dragInfo Data associated with the object being dragged
|
||||
* @param recycle {@link Rect} object to be possibly recycled.
|
||||
* @return Estimated area that would be occupied if object was dropped at
|
||||
* the given location. Should return null if no estimate is found,
|
||||
* or if this target doesn't provide estimations.
|
||||
*/
|
||||
Rect estimateDropLocation(DragSource source, int x, int y, int xOffset, int yOffset, Object dragInfo, Rect recycle);
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ package com.android.launcher;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.LayoutInflater;
|
||||
@@ -69,6 +70,10 @@ public class FolderIcon extends BubbleTextView implements DropTarget {
|
||||
&& item.container != mInfo.id;
|
||||
}
|
||||
|
||||
public Rect estimateDropLocation(DragSource source, int x, int y, int xOffset, int yOffset, Object dragInfo, Rect recycle) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public void onDrop(DragSource source, int x, int y, int xOffset, int yOffset, Object dragInfo) {
|
||||
final ApplicationInfo item = (ApplicationInfo) dragInfo;
|
||||
// TODO: update open folder that is looking at this data
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.android.launcher;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Rect;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
@@ -33,6 +34,10 @@ public class UserFolder extends Folder implements DropTarget {
|
||||
return (itemType == LauncherSettings.Favorites.ITEM_TYPE_APPLICATION ||
|
||||
itemType == LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT) && item.container != mInfo.id;
|
||||
}
|
||||
|
||||
public Rect estimateDropLocation(DragSource source, int x, int y, int xOffset, int yOffset, Object dragInfo, Rect recycle) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public void onDrop(DragSource source, int x, int y, int xOffset, int yOffset, Object dragInfo) {
|
||||
final ApplicationInfo item = (ApplicationInfo) dragInfo;
|
||||
|
||||
@@ -48,7 +48,7 @@ import java.util.ArrayList;
|
||||
*/
|
||||
public class Workspace extends ViewGroup implements DropTarget, DragSource, DragScroller {
|
||||
private static final int INVALID_SCREEN = -1;
|
||||
|
||||
|
||||
/**
|
||||
* The velocity at which a fling gesture will cause us to snap to the next screen
|
||||
*/
|
||||
@@ -75,6 +75,11 @@ public class Workspace extends ViewGroup implements DropTarget, DragSource, Drag
|
||||
* CellInfo for the cell that is currently being dragged
|
||||
*/
|
||||
private CellLayout.CellInfo mDragInfo;
|
||||
|
||||
/**
|
||||
* Target drop area calculated during last acceptDrop call.
|
||||
*/
|
||||
private int[] mTargetCell = null;
|
||||
|
||||
private float mLastMotionX;
|
||||
private float mLastMotionY;
|
||||
@@ -88,8 +93,14 @@ public class Workspace extends ViewGroup implements DropTarget, DragSource, Drag
|
||||
|
||||
private Launcher mLauncher;
|
||||
private DragController mDragger;
|
||||
|
||||
|
||||
/**
|
||||
* Cache of vacant cells, used during drag events and invalidated as needed.
|
||||
*/
|
||||
private CellLayout.CellInfo mVacantCache = null;
|
||||
|
||||
private int[] mTempCell = new int[2];
|
||||
private int[] mTempEstimate = new int[2];
|
||||
|
||||
private boolean mAllowLongPress;
|
||||
private boolean mLocked;
|
||||
@@ -363,7 +374,7 @@ public class Workspace extends ViewGroup implements DropTarget, DragSource, Drag
|
||||
CellLayout.CellInfo findAllVacantCells(boolean[] occupied) {
|
||||
CellLayout group = (CellLayout) getChildAt(mCurrentScreen);
|
||||
if (group != null) {
|
||||
return group.findAllVacantCells(occupied);
|
||||
return group.findAllVacantCells(occupied, null);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@@ -890,7 +901,7 @@ public class Workspace extends ViewGroup implements DropTarget, DragSource, Drag
|
||||
}
|
||||
|
||||
public void onDrop(DragSource source, int x, int y, int xOffset, int yOffset, Object dragInfo) {
|
||||
final CellLayout cellLayout = (CellLayout) getChildAt(mCurrentScreen);
|
||||
final CellLayout cellLayout = getCurrentDropLayout();
|
||||
if (source != this) {
|
||||
onDropExternal(x - xOffset, y - yOffset, dragInfo, cellLayout);
|
||||
} else {
|
||||
@@ -902,7 +913,9 @@ public class Workspace extends ViewGroup implements DropTarget, DragSource, Drag
|
||||
originalCellLayout.removeView(cell);
|
||||
cellLayout.addView(cell);
|
||||
}
|
||||
cellLayout.onDropChild(cell, x - xOffset, y - yOffset);
|
||||
mTargetCell = estimateDropCell(source, x - xOffset, y - yOffset,
|
||||
mDragInfo.spanX, mDragInfo.spanY, cell, cellLayout, mTargetCell);
|
||||
cellLayout.onDropChild(cell, mTargetCell);
|
||||
|
||||
final ItemInfo info = (ItemInfo)cell.getTag();
|
||||
CellLayout.LayoutParams lp = (CellLayout.LayoutParams) cell.getLayoutParams();
|
||||
@@ -914,6 +927,7 @@ public class Workspace extends ViewGroup implements DropTarget, DragSource, Drag
|
||||
|
||||
public void onDragEnter(DragSource source, int x, int y, int xOffset, int yOffset,
|
||||
Object dragInfo) {
|
||||
mVacantCache = null;
|
||||
}
|
||||
|
||||
public void onDragOver(DragSource source, int x, int y, int xOffset, int yOffset,
|
||||
@@ -922,6 +936,7 @@ public class Workspace extends ViewGroup implements DropTarget, DragSource, Drag
|
||||
|
||||
public void onDragExit(DragSource source, int x, int y, int xOffset, int yOffset,
|
||||
Object dragInfo) {
|
||||
mVacantCache = null;
|
||||
}
|
||||
|
||||
private void onDropExternal(int x, int y, Object dragInfo, CellLayout cellLayout) {
|
||||
@@ -955,7 +970,8 @@ public class Workspace extends ViewGroup implements DropTarget, DragSource, Drag
|
||||
|
||||
cellLayout.addView(view, insertAtFirst ? 0 : -1);
|
||||
view.setOnLongClickListener(mLongClickListener);
|
||||
cellLayout.onDropChild(view, x, y);
|
||||
mTargetCell = estimateDropCell(null, x, y, 1, 1, view, cellLayout, mTargetCell);
|
||||
cellLayout.onDropChild(view, mTargetCell);
|
||||
CellLayout.LayoutParams lp = (CellLayout.LayoutParams) view.getLayoutParams();
|
||||
|
||||
final LauncherModel model = Launcher.getModel();
|
||||
@@ -963,18 +979,73 @@ public class Workspace extends ViewGroup implements DropTarget, DragSource, Drag
|
||||
LauncherModel.addOrMoveItemInDatabase(mLauncher, info,
|
||||
LauncherSettings.Favorites.CONTAINER_DESKTOP, mCurrentScreen, lp.cellX, lp.cellY);
|
||||
}
|
||||
|
||||
public boolean acceptDrop(DragSource source, int x, int y, int xOffset, int yOffset,
|
||||
Object dragInfo) {
|
||||
|
||||
final CellLayout.CellInfo cellInfo = mDragInfo;
|
||||
int cellHSpan = cellInfo == null ? 1 : cellInfo.spanX;
|
||||
int cellVSpan = cellInfo == null ? 1 : cellInfo.spanY;
|
||||
|
||||
return ((CellLayout) getChildAt(mCurrentScreen)).acceptChildDrop(x - xOffset, y - yOffset,
|
||||
cellHSpan, cellVSpan, cellInfo == null ? null : cellInfo.cell);
|
||||
|
||||
/**
|
||||
* Return the current {@link CellLayout}, correctly picking the destination
|
||||
* screen while a scroll is in progress.
|
||||
*/
|
||||
private CellLayout getCurrentDropLayout() {
|
||||
int index = mScroller.isFinished() ? mCurrentScreen : mNextScreen;
|
||||
return (CellLayout) getChildAt(index);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public boolean acceptDrop(DragSource source, int x, int y,
|
||||
int xOffset, int yOffset, Object dragInfo) {
|
||||
// Workspaces accept everything
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public Rect estimateDropLocation(DragSource source, int x, int y,
|
||||
int xOffset, int yOffset, Object dragInfo, Rect recycle) {
|
||||
final CellLayout layout = getCurrentDropLayout();
|
||||
|
||||
final CellLayout.CellInfo cellInfo = mDragInfo;
|
||||
final int spanX = cellInfo == null ? 1 : cellInfo.spanX;
|
||||
final int spanY = cellInfo == null ? 1 : cellInfo.spanY;
|
||||
final View ignoreView = cellInfo == null ? null : cellInfo.cell;
|
||||
|
||||
final Rect location = recycle != null ? recycle : new Rect();
|
||||
|
||||
// Find drop cell and convert into rectangle
|
||||
int[] dropCell = estimateDropCell(source, x - xOffset, y - yOffset,
|
||||
spanX, spanY, ignoreView, layout, mTempCell);
|
||||
|
||||
if (dropCell == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
layout.cellToPoint(dropCell[0], dropCell[1], mTempEstimate);
|
||||
location.left = mTempEstimate[0];
|
||||
location.top = mTempEstimate[1];
|
||||
|
||||
layout.cellToPoint(dropCell[0] + spanX, dropCell[1] + spanY, mTempEstimate);
|
||||
location.right = mTempEstimate[0];
|
||||
location.bottom = mTempEstimate[1];
|
||||
|
||||
return location;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate the nearest cell where the given object would be dropped.
|
||||
*/
|
||||
private int[] estimateDropCell(DragSource source, int pixelX, int pixelY,
|
||||
int spanX, int spanY, View ignoreView, CellLayout layout, int[] recycle) {
|
||||
// Create vacant cell cache if none exists
|
||||
if (mVacantCache == null) {
|
||||
mVacantCache = layout.findAllVacantCells(null, ignoreView);
|
||||
}
|
||||
|
||||
// Find the best target drop location
|
||||
return layout.findNearestVacantArea(pixelX, pixelY,
|
||||
spanX, spanY, mVacantCache, recycle);
|
||||
}
|
||||
|
||||
void setLauncher(Launcher launcher) {
|
||||
mLauncher = launcher;
|
||||
}
|
||||
@@ -1002,12 +1073,14 @@ public class Workspace extends ViewGroup implements DropTarget, DragSource, Drag
|
||||
}
|
||||
|
||||
public void scrollLeft() {
|
||||
mVacantCache = null;
|
||||
if (mNextScreen == INVALID_SCREEN && mCurrentScreen > 0 && mScroller.isFinished()) {
|
||||
snapToScreen(mCurrentScreen - 1);
|
||||
}
|
||||
}
|
||||
|
||||
public void scrollRight() {
|
||||
mVacantCache = null;
|
||||
if (mNextScreen == INVALID_SCREEN && mCurrentScreen < getChildCount() -1 &&
|
||||
mScroller.isFinished()) {
|
||||
snapToScreen(mCurrentScreen + 1);
|
||||
|
||||
Reference in New Issue
Block a user