Move the drag thing into its own window that goes around on top of everything else.
diff --git a/src/com/android/launcher2/DragLayer.java b/src/com/android/launcher2/DragLayer.java
index fee8632..2839711 100644
--- a/src/com/android/launcher2/DragLayer.java
+++ b/src/com/android/launcher2/DragLayer.java
@@ -39,114 +39,9 @@
 /**
  * A ViewGroup that coordinated dragging across its dscendants
  */
-public class DragLayer extends FrameLayout implements DragController {
-    private static final int SCROLL_DELAY = 600;
-    private static final int SCROLL_ZONE = 20;
-    private static final int VIBRATE_DURATION = 35;
-    private static final int ANIMATION_SCALE_UP_DURATION = 110;
+public class DragLayer extends FrameLayout {
 
-    private static final boolean PROFILE_DRAWING_DURING_DRAG = false;
-
-    // Number of pixels to add to the dragged item for scaling
-    private static final float DRAG_SCALE = 24.0f;
-
-    private boolean mDragging = false;
-    private boolean mShouldDrop;
-    private float mLastMotionX;
-    private float mLastMotionY;
-
-    /**
-     * The bitmap that is currently being dragged
-     */
-    private Bitmap mDragBitmap = null;
-    private View mOriginator;
-
-    private int mBitmapOffsetX;
-    private int mBitmapOffsetY;
-
-    /**
-     * X offset from where we touched on the cell to its upper-left corner
-     */
-    private float mTouchOffsetX;
-
-    /**
-     * Y offset from where we touched on the cell to its upper-left corner
-     */
-    private float mTouchOffsetY;
-
-    /**
-     * Utility rectangle
-     */
-    private Rect mDragRect = new Rect();
-
-    /**
-     * Where the drag originated
-     */
-    private DragSource mDragSource;
-
-    /**
-     * The data associated with the object being dragged
-     */
-    private Object mDragInfo;
-
-    private final Rect mRect = new Rect();
-    private final int[] mDropCoordinates = new int[2];
-
-    private final Vibrator mVibrator = new Vibrator();
-
-    private DragListener mListener;
-
-    private DragScroller mDragScroller;
-
-    private static final int SCROLL_OUTSIDE_ZONE = 0;
-    private static final int SCROLL_WAITING_IN_ZONE = 1;
-
-    private static final int SCROLL_LEFT = 0;
-    private static final int SCROLL_RIGHT = 1;
-
-    private int mScrollState = SCROLL_OUTSIDE_ZONE;
-
-    private ScrollRunnable mScrollRunnable = new ScrollRunnable();
-    private View mIgnoredDropTarget;
-
-    private RectF mDragRegion;
-    private boolean mEnteredRegion;
-    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;
-
-    private static final int ANIMATION_TYPE_SCALE = 1;
-
-    private float mAnimationFrom;
-    private float mAnimationTo;
-    private int mAnimationDuration;
-    private long mAnimationStartTime;
-    private int mAnimationType;
-    private int mAnimationState = ANIMATION_STATE_DONE;
-
-    private InputMethodManager mInputMethodManager;
+    DragController mDragController;
 
     /**
      * Used to create a new DragLayer from XML.
@@ -156,478 +51,24 @@
      */
     public DragLayer(Context context, AttributeSet attrs) {
         super(context, attrs);
-
-        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) {
-        if (PROFILE_DRAWING_DURING_DRAG) {
-            android.os.Debug.startMethodTracing("Launcher");
-        }
-
-        // Hide soft keyboard, if visible
-        if (mInputMethodManager == null) {
-            mInputMethodManager = (InputMethodManager)
-                getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
-        }
-        mInputMethodManager.hideSoftInputFromWindow(getWindowToken(), 0);
-
-        if (mListener != null) {
-            mListener.onDragStart(v, source, dragInfo, dragAction);
-        }
-
-        Rect r = mDragRect;
-        r.set(v.getScrollX(), v.getScrollY(), 0, 0);
-
-        offsetDescendantRectToMyCoords(v, r);
-        mTouchOffsetX = mLastMotionX - r.left;
-        mTouchOffsetY = mLastMotionY - r.top;
-
-        v.clearFocus();
-        v.setPressed(false);
-
-        boolean willNotCache = v.willNotCacheDrawing();
-        v.setWillNotCacheDrawing(false);
-
-        // Reset the drawing cache background color to fully transparent
-        // for the duration of this operation
-        int color = v.getDrawingCacheBackgroundColor();
-        v.setDrawingCacheBackgroundColor(0);
-
-        if (color != 0) {
-            v.destroyDrawingCache();
-        }
-        v.buildDrawingCache();
-        Bitmap viewBitmap = v.getDrawingCache();
-        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;
-        scale.setScale(scaleFactor, scaleFactor);
-
-        mAnimationTo = 1.0f;
-        mAnimationFrom = 1.0f / scaleFactor;
-        mAnimationDuration = ANIMATION_SCALE_UP_DURATION;
-        mAnimationState = ANIMATION_STATE_STARTING;
-        mAnimationType = ANIMATION_TYPE_SCALE;
-
-        mDragBitmap = Bitmap.createBitmap(viewBitmap, 0, 0, width, height, scale, true);
-        v.destroyDrawingCache();
-        v.setWillNotCacheDrawing(willNotCache);
-        v.setDrawingCacheBackgroundColor(color);
-
-        final Bitmap dragBitmap = mDragBitmap;
-        mBitmapOffsetX = (dragBitmap.getWidth() - width) / 2;
-        mBitmapOffsetY = (dragBitmap.getHeight() - height) / 2;
-
-        if (dragAction == DRAG_ACTION_MOVE) {
-            v.setVisibility(GONE);
-        }
-
-        mDragPaint = null;
-        mDragging = true;
-        mShouldDrop = true;
-        mOriginator = v;
-        mDragSource = source;
-        mDragInfo = dragInfo;
-
-        mVibrator.vibrate(VIBRATE_DURATION);
-
-        mEnteredRegion = false;
-
-        invalidate();
+    public void setDragController(DragController controller) {
+        mDragController = controller;
     }
-
+    
     @Override
     public boolean dispatchKeyEvent(KeyEvent event) {
-        return mDragging || super.dispatchKeyEvent(event);
-    }
-
-    @Override
-    protected void dispatchDraw(Canvas canvas) {
-        super.dispatchDraw(canvas);
-
-        if (mDragging && mDragBitmap != null) {
-            if (mAnimationState == ANIMATION_STATE_STARTING) {
-                mAnimationStartTime = SystemClock.uptimeMillis();
-                mAnimationState = ANIMATION_STATE_RUNNING;
-            }
-
-            if (mAnimationState == ANIMATION_STATE_RUNNING) {
-                float normalized = (float) (SystemClock.uptimeMillis() - mAnimationStartTime) /
-                        mAnimationDuration;
-                if (normalized >= 1.0f) {
-                    mAnimationState = ANIMATION_STATE_DONE;
-                }
-                normalized = Math.min(normalized, 1.0f);
-                final float value = mAnimationFrom  + (mAnimationTo - mAnimationFrom) * normalized;
-
-                switch (mAnimationType) {
-                    case ANIMATION_TYPE_SCALE:
-                        final Bitmap dragBitmap = mDragBitmap;
-                        canvas.save();
-                        canvas.translate(mScrollX + mLastMotionX - mTouchOffsetX - mBitmapOffsetX,
-                                mScrollY + mLastMotionY - mTouchOffsetY - mBitmapOffsetY);
-                        canvas.translate((dragBitmap.getWidth() * (1.0f - value)) / 2,
-                                (dragBitmap.getHeight() * (1.0f - value)) / 2);
-                        canvas.scale(value, value);
-                        canvas.drawBitmap(dragBitmap, 0.0f, 0.0f, mDragPaint);
-                        canvas.restore();
-                        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);
-            }
-        }
-    }
-
-    private void endDrag() {
-        if (mDragging) {
-            mDragging = false;
-            if (mDragBitmap != null) {
-                mDragBitmap.recycle();
-            }
-            if (mOriginator != null) {
-                mOriginator.setVisibility(VISIBLE);
-            }
-            if (mListener != null) {
-                mListener.onDragEnd();
-            }
-        }
+        return mDragController.dispatchKeyEvent(event) || super.dispatchKeyEvent(event);
     }
 
     @Override
     public boolean onInterceptTouchEvent(MotionEvent ev) {
-        final int action = ev.getAction();
-
-        final float x = ev.getX();
-        final float y = ev.getY();
-
-        switch (action) {
-            case MotionEvent.ACTION_MOVE:
-                break;
-
-            case MotionEvent.ACTION_DOWN:
-                // Remember location of down touch
-                mLastMotionX = x;
-                mLastMotionY = y;
-                mLastDropTarget = null;
-                break;
-
-            case MotionEvent.ACTION_CANCEL:
-            case MotionEvent.ACTION_UP:
-                if (mShouldDrop && drop(x, y)) {
-                    mShouldDrop = false;
-                }
-                endDrag();
-                break;
-        }
-
-        return mDragging;
+        return mDragController.onInterceptTouchEvent(ev);
     }
 
     @Override
     public boolean onTouchEvent(MotionEvent ev) {
-        if (!mDragging) {
-            return false;
-        }
-
-        final int action = ev.getAction();
-        final float x = ev.getX();
-        final float y = ev.getY();
-
-        switch (action) {
-        case MotionEvent.ACTION_DOWN:
-
-            // Remember where the motion event started
-            mLastMotionX = x;
-            mLastMotionY = y;
-
-            if ((x < SCROLL_ZONE) || (x > getWidth() - SCROLL_ZONE)) {
-                mScrollState = SCROLL_WAITING_IN_ZONE;
-                postDelayed(mScrollRunnable, SCROLL_DELAY);
-            } else {
-                mScrollState = SCROLL_OUTSIDE_ZONE;
-            }
-
-            break;
-        case MotionEvent.ACTION_MOVE:
-            final int scrollX = mScrollX;
-            final int scrollY = mScrollY;
-
-            final float touchX = mTouchOffsetX;
-            final float touchY = mTouchOffsetY;
-
-            final int offsetX = mBitmapOffsetX;
-            final int offsetY = mBitmapOffsetY;
-
-            int left = (int) (scrollX + mLastMotionX - touchX - offsetX);
-            int top = (int) (scrollY + mLastMotionY - touchY - offsetY);
-
-            final Bitmap dragBitmap = mDragBitmap;
-            final int width = dragBitmap.getWidth();
-            final int height = dragBitmap.getHeight();
-
-            final Rect rect = mRect;
-            rect.set(left - 1, top - 1, left + width + 1, top + height + 1);
-
-            mLastMotionX = x;
-            mLastMotionY = y;
-
-            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);
-
-            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);
-            if (dropTarget != null) {
-                if (mLastDropTarget == dropTarget) {
-                    dropTarget.onDragOver(mDragSource, coordinates[0], coordinates[1],
-                        (int) mTouchOffsetX, (int) mTouchOffsetY, mDragInfo);
-                } else {
-                    if (mLastDropTarget != null) {
-                        mLastDropTarget.onDragExit(mDragSource, coordinates[0], coordinates[1],
-                            (int) mTouchOffsetX, (int) mTouchOffsetY, mDragInfo);
-                    }
-                    dropTarget.onDragEnter(mDragSource, coordinates[0], coordinates[1],
-                        (int) mTouchOffsetX, (int) mTouchOffsetY, mDragInfo);
-                }
-            } else {
-                if (mLastDropTarget != null) {
-                    mLastDropTarget.onDragExit(mDragSource, coordinates[0], coordinates[1],
-                        (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;
-            if (mDragRegion != null) {
-                final RectF region = mDragRegion;
-                final boolean inRegion = region.contains(ev.getRawX(), ev.getRawY());
-                if (!mEnteredRegion && inRegion) {
-                    mDragPaint = mTrashPaint;
-                    mEnteredRegion = true;
-                    inDragRegion = true;
-                } else if (mEnteredRegion && !inRegion) {
-                    mDragPaint = null;
-                    mEnteredRegion = false;
-                }
-            }
-
-            if (!inDragRegion && x < SCROLL_ZONE) {
-                if (mScrollState == SCROLL_OUTSIDE_ZONE) {
-                    mScrollState = SCROLL_WAITING_IN_ZONE;
-                    mScrollRunnable.setDirection(SCROLL_LEFT);
-                    postDelayed(mScrollRunnable, SCROLL_DELAY);
-                }
-            } else if (!inDragRegion && x > getWidth() - SCROLL_ZONE) {
-                if (mScrollState == SCROLL_OUTSIDE_ZONE) {
-                    mScrollState = SCROLL_WAITING_IN_ZONE;
-                    mScrollRunnable.setDirection(SCROLL_RIGHT);
-                    postDelayed(mScrollRunnable, SCROLL_DELAY);
-                }
-            } else {
-                if (mScrollState == SCROLL_WAITING_IN_ZONE) {
-                    mScrollState = SCROLL_OUTSIDE_ZONE;
-                    mScrollRunnable.setDirection(SCROLL_RIGHT);
-                    removeCallbacks(mScrollRunnable);
-                }
-            }
-
-            break;
-        case MotionEvent.ACTION_UP:
-            removeCallbacks(mScrollRunnable);
-            if (mShouldDrop) {
-                drop(x, y);
-                mShouldDrop = false;
-            }
-            endDrag();
-
-            break;
-        case MotionEvent.ACTION_CANCEL:
-            endDrag();
-        }
-
-        return true;
-    }
-
-    private boolean drop(float x, float y) {
-        invalidate();
-
-        final int[] coordinates = mDropCoordinates;
-        DropTarget dropTarget = findDropTarget((int) x, (int) y, coordinates);
-
-        if (dropTarget != null) {
-            dropTarget.onDragExit(mDragSource, coordinates[0], coordinates[1],
-                    (int) mTouchOffsetX, (int) mTouchOffsetY, mDragInfo);
-            if (dropTarget.acceptDrop(mDragSource, coordinates[0], coordinates[1],
-                    (int) mTouchOffsetX, (int) mTouchOffsetY, mDragInfo)) {
-                dropTarget.onDrop(mDragSource, coordinates[0], coordinates[1],
-                        (int) mTouchOffsetX, (int) mTouchOffsetY, mDragInfo);
-                mDragSource.onDropCompleted((View) dropTarget, true);
-                return true;
-            } else {
-                mDragSource.onDropCompleted((View) dropTarget, false);
-                return true;
-            }
-        }
-        return false;
-    }
-
-    DropTarget findDropTarget(int x, int y, int[] dropCoordinates) {
-        return findDropTarget(this, x, y, dropCoordinates);
-    }
-
-    private DropTarget findDropTarget(ViewGroup container, int x, int y, int[] dropCoordinates) {
-        final Rect r = mDragRect;
-        final int count = container.getChildCount();
-        final int scrolledX = x + container.getScrollX();
-        final int scrolledY = y + container.getScrollY();
-        final View ignoredDropTarget = mIgnoredDropTarget;
-
-        for (int i = count - 1; i >= 0; i--) {
-            final View child = container.getChildAt(i);
-            if (child.getVisibility() == VISIBLE && child != ignoredDropTarget) {
-                child.getHitRect(r);
-                if (r.contains(scrolledX, scrolledY)) {
-                    DropTarget target = null;
-                    if (child instanceof ViewGroup) {
-                        x = scrolledX - child.getLeft();
-                        y = scrolledY - child.getTop();
-                        target = findDropTarget((ViewGroup) child, x, y, dropCoordinates);
-                    }
-                    if (target == null) {
-                        if (child instanceof DropTarget) {
-                            // 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;
-                    }
-                }
-            }
-        }
-
-        return null;
-    }
-
-    public void setDragScoller(DragScroller scroller) {
-        mDragScroller = scroller;
-    }
-
-    public void setDragListener(DragListener l) {
-        mListener = l;
-    }
-
-    public void removeDragListener(DragListener l) {
-        mListener = null;
-    }
-
-    /**
-     * Specifies the view that must be ignored when looking for a drop target.
-     *
-     * @param view The view that will not be taken into account while looking
-     *        for a drop target.
-     */
-    void setIgnoredDropTarget(View view) {
-        mIgnoredDropTarget = view;
-    }
-
-    /**
-     * Specifies the delete region.
-     *
-     * @param region The rectangle in screen coordinates of the delete region.
-     */
-    void setDeleteRegion(RectF region) {
-        mDragRegion = region;
-    }
-
-    private class ScrollRunnable implements Runnable {
-        private int mDirection;
-
-        ScrollRunnable() {
-        }
-
-        public void run() {
-            if (mDragScroller != null) {
-                mDrawEstimated = false;
-                if (mDirection == SCROLL_LEFT) {
-                    mDragScroller.scrollLeft();
-                } else {
-                    mDragScroller.scrollRight();
-                }
-                mScrollState = SCROLL_OUTSIDE_ZONE;
-            }
-        }
-
-        void setDirection(int direction) {
-            mDirection = direction;
-        }
+        return mDragController.onTouchEvent(ev);
     }
 }