Fix bug with drag visualization and UserFolders.
When dragging an app shortcut, it was possible that we'd show a red rectangle around a cell occupied by a UserFolder. This shouldn't be possible -- as soon as that cell becomes the target drop cell, the folder should start handling the drag and drop events. Change-Id: I1b7a8b1aa9aeb7e2f1bd51ce8d947c06455e988f
This commit is contained in:
parent
6569f2c80e
commit
440c360bc3
|
@ -677,6 +677,20 @@ public class CellLayout extends ViewGroup {
|
|||
return true;
|
||||
}
|
||||
|
||||
public View getChildAt(int x, int y) {
|
||||
final int count = getChildCount();
|
||||
for (int i = 0; i < count; i++) {
|
||||
View child = getChildAt(i);
|
||||
LayoutParams lp = (LayoutParams) child.getLayoutParams();
|
||||
|
||||
if ((lp.cellX <= x) && (x < lp.cellX + lp.cellHSpan) &&
|
||||
(lp.cellY <= y) && (y < lp.cellY + lp.cellHSpan)) {
|
||||
return child;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Estimate where the top left cell of the dragged item will land if it is dropped.
|
||||
*
|
||||
|
@ -690,7 +704,7 @@ public class CellLayout extends ViewGroup {
|
|||
final int countX = getCountX();
|
||||
final int countY = getCountY();
|
||||
|
||||
pointToCellRounded(originX, originY, result);
|
||||
pointToCellRounded(originX + (mCellWidth / 2), originY + (mCellHeight / 2), result);
|
||||
|
||||
// If the item isn't fully on this screen, snap to the edges
|
||||
int rightOverhang = result[0] + spanX - countX;
|
||||
|
|
|
@ -254,4 +254,10 @@ public class DeleteZone extends ImageView implements DropTarget, DragController.
|
|||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public DropTarget getDropTargetDelegate(DragSource source, int x, int y, int xOffset, int yOffset,
|
||||
DragView dragView, Object dragInfo) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -394,6 +394,12 @@ public class DragController {
|
|||
// Drop on someone?
|
||||
final int[] coordinates = mCoordinatesTemp;
|
||||
DropTarget dropTarget = findDropTarget(screenX, screenY, coordinates);
|
||||
DropTarget delegate = dropTarget.getDropTargetDelegate(
|
||||
mDragSource, coordinates[0], coordinates[1],
|
||||
(int) mTouchOffsetX, (int) mTouchOffsetY, mDragView, mDragInfo);
|
||||
if (delegate != null) {
|
||||
dropTarget = delegate;
|
||||
}
|
||||
if (dropTarget != null) {
|
||||
if (mLastDropTarget == dropTarget) {
|
||||
dropTarget.onDragOver(mDragSource, coordinates[0], coordinates[1],
|
||||
|
@ -482,13 +488,25 @@ public class DragController {
|
|||
final ArrayList<DropTarget> dropTargets = mDropTargets;
|
||||
final int count = dropTargets.size();
|
||||
for (int i=count-1; i>=0; i--) {
|
||||
final DropTarget target = dropTargets.get(i);
|
||||
DropTarget target = dropTargets.get(i);
|
||||
target.getHitRect(r);
|
||||
|
||||
// Convert the hit rect to screen coordinates
|
||||
target.getLocationOnScreen(dropCoordinates);
|
||||
r.offset(dropCoordinates[0] - target.getLeft(), dropCoordinates[1] - target.getTop());
|
||||
|
||||
if (r.contains(x, y)) {
|
||||
DropTarget delegate = target.getDropTargetDelegate(mDragSource,
|
||||
x, y, (int)mTouchOffsetX, (int)mTouchOffsetY, mDragView, mDragInfo);
|
||||
if (delegate != null) {
|
||||
target = delegate;
|
||||
target.getLocationOnScreen(dropCoordinates);
|
||||
}
|
||||
|
||||
// Make dropCoordinates relative to the DropTarget
|
||||
dropCoordinates[0] = x - dropCoordinates[0];
|
||||
dropCoordinates[1] = y - dropCoordinates[1];
|
||||
|
||||
return target;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -50,6 +50,26 @@ public interface DropTarget {
|
|||
void onDragExit(DragSource source, int x, int y, int xOffset, int yOffset,
|
||||
DragView dragView, Object dragInfo);
|
||||
|
||||
/**
|
||||
* Allows a DropTarget to delegate drag and drop events to another object.
|
||||
*
|
||||
* Most subclasses will should just return null from this method.
|
||||
*
|
||||
* @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 dragView The DragView that's being dragged around on screen.
|
||||
* @param dragInfo Data associated with the object being dragged
|
||||
*
|
||||
* @return The DropTarget to delegate to, or null to not delegate to another object.
|
||||
*/
|
||||
DropTarget getDropTargetDelegate(DragSource source, int x, int y, int xOffset, int yOffset,
|
||||
DragView dragView, Object dragInfo);
|
||||
|
||||
/**
|
||||
* 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
|
||||
|
|
|
@ -102,4 +102,10 @@ public class FolderIcon extends BubbleTextView implements DropTarget {
|
|||
DragView dragView, Object dragInfo) {
|
||||
setCompoundDrawablesWithIntrinsicBounds(null, mCloseIcon, null, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DropTarget getDropTargetDelegate(DragSource source, int x, int y, int xOffset, int yOffset,
|
||||
DragView dragView, Object dragInfo) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -89,4 +89,10 @@ public class UserFolder extends Folder implements DropTarget {
|
|||
super.onOpen();
|
||||
requestFocus();
|
||||
}
|
||||
|
||||
@Override
|
||||
public DropTarget getDropTargetDelegate(DragSource source, int x, int y, int xOffset, int yOffset,
|
||||
DragView dragView, Object dragInfo) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1219,11 +1219,45 @@ public class Workspace extends ViewGroup implements DropTarget, DragSource, Drag
|
|||
clearVacantCache();
|
||||
}
|
||||
|
||||
public DropTarget getDropTargetDelegate(DragSource source, int x, int y, int xOffset, int yOffset,
|
||||
DragView dragView, Object dragInfo) {
|
||||
|
||||
// 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.
|
||||
|
||||
ItemInfo item = (ItemInfo)dragInfo;
|
||||
CellLayout currentLayout = getCurrentDropLayout();
|
||||
|
||||
int dragPointX, dragPointY;
|
||||
if (item.spanX == 1 && item.spanY == 1) {
|
||||
// For a 1x1, calculate the drop cell exactly as in onDragOver
|
||||
dragPointX = x - xOffset;
|
||||
dragPointY = y - yOffset;
|
||||
} else {
|
||||
// Otherwise, use the exact drag coordinates
|
||||
dragPointX = x;
|
||||
dragPointY = y;
|
||||
}
|
||||
|
||||
// If we are dragging over a cell that contains a DropTarget that will
|
||||
// accept the drop, delegate to that DropTarget.
|
||||
final int[] cellXY = mTempCell;
|
||||
currentLayout.estimateDropCell(dragPointX, dragPointY, item.spanX, item.spanY, cellXY);
|
||||
View child = currentLayout.getChildAt(cellXY[0], cellXY[1]);
|
||||
if (child instanceof DropTarget) {
|
||||
DropTarget target = (DropTarget)child;
|
||||
if (target.acceptDrop(source, x, y, xOffset, yOffset, dragView, dragInfo)) {
|
||||
return target;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void onDragOver(DragSource source, int x, int y, int xOffset, int yOffset,
|
||||
DragView dragView, Object dragInfo) {
|
||||
|
||||
ItemInfo item = (ItemInfo)dragInfo;
|
||||
|
||||
CellLayout currentLayout = getCurrentDropLayout();
|
||||
|
||||
if (dragInfo instanceof LauncherAppWidgetInfo) {
|
||||
|
|
Loading…
Reference in New Issue