DragController.java revision 3f8175a86e24b3568d1f5b12e1d3d5efcc57d691
131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project/*
231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * Copyright (C) 2008 The Android Open Source Project
331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project *
431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * you may not use this file except in compliance with the License.
631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * You may obtain a copy of the License at
731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project *
831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project *
1031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
1131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
1231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * See the License for the specific language governing permissions and
1431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * limitations under the License.
1531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project */
1631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
17a5902524d4403885eb4c50360bf3465c6be796efJoe Onoratopackage com.android.launcher2;
1831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
1900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onoratoimport android.content.Context;
2000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onoratoimport android.graphics.Bitmap;
2100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onoratoimport android.graphics.Rect;
2200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onoratoimport android.graphics.RectF;
2300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onoratoimport android.os.IBinder;
2400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onoratoimport android.os.Handler;
2500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onoratoimport android.os.Vibrator;
26e048e8a8eff51e8c2c271d16c864367dac438ca2Joe Onoratoimport android.util.DisplayMetrics;
2700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onoratoimport android.util.Log;
2831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.view.View;
2900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onoratoimport android.view.KeyEvent;
3000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onoratoimport android.view.MotionEvent;
31e048e8a8eff51e8c2c271d16c864367dac438ca2Joe Onoratoimport android.view.WindowManager;
3200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onoratoimport android.view.inputmethod.InputMethodManager;
3300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
3400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onoratoimport java.util.ArrayList;
3531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
3631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project/**
3700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato * Class for initiating a drag within a view or across multiple views.
3831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project */
3900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onoratopublic class DragController {
40ea3763c2672f77539538af8cdd395ad97058eaabRomain Guy    @SuppressWarnings({"UnusedDeclaration"})
412e5c432a0aa7e83031575df73bed43a297e2eed3Joe Onorato    private static final String TAG = "Launcher.DragController";
422e5c432a0aa7e83031575df73bed43a297e2eed3Joe Onorato
4300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    /** Indicates the drag is a move.  */
4400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    public static int DRAG_ACTION_MOVE = 0;
4500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
4600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    /** Indicates the drag is a copy.  */
4700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    public static int DRAG_ACTION_COPY = 1;
4800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
4900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    private static final int SCROLL_DELAY = 600;
5000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    private static final int SCROLL_ZONE = 20;
5100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    private static final int VIBRATE_DURATION = 35;
5200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
5300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    private static final boolean PROFILE_DRAWING_DURING_DRAG = false;
5400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
5500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    private static final int SCROLL_OUTSIDE_ZONE = 0;
5600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    private static final int SCROLL_WAITING_IN_ZONE = 1;
5700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
5800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    private static final int SCROLL_LEFT = 0;
5900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    private static final int SCROLL_RIGHT = 1;
6000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
6100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    private Context mContext;
6200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    private Handler mHandler;
6300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    private final Vibrator mVibrator = new Vibrator();
6400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
6500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    // temporaries to avoid gc thrash
6600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    private Rect mRectTemp = new Rect();
6700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    private final int[] mCoordinatesTemp = new int[2];
6800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
6900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    /** Whether or not we're dragging. */
7000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    private boolean mDragging;
7100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
7200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    /** X coordinate of the down event. */
7300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    private float mMotionDownX;
7400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
7500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    /** Y coordinate of the down event. */
7600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    private float mMotionDownY;
7700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
78e048e8a8eff51e8c2c271d16c864367dac438ca2Joe Onorato    /** Info about the screen for clamping. */
79e048e8a8eff51e8c2c271d16c864367dac438ca2Joe Onorato    private DisplayMetrics mDisplayMetrics = new DisplayMetrics();
80e048e8a8eff51e8c2c271d16c864367dac438ca2Joe Onorato
8100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    /** Original view that is being dragged.  */
8200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    private View mOriginator;
8300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
8400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    /** X offset from the upper-left corner of the cell to where we touched.  */
8500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    private float mTouchOffsetX;
8600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
8700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    /** Y offset from the upper-left corner of the cell to where we touched.  */
8800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    private float mTouchOffsetY;
8900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
9000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    /** Where the drag originated */
9100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    private DragSource mDragSource;
9200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
9300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    /** The data associated with the object being dragged */
9400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    private Object mDragInfo;
9500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
9600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    /** The view that moves around while you drag.  */
9700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    private DragView mDragView;
9800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
9900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    /** Who can receive drop events */
10000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    private ArrayList<DropTarget> mDropTargets = new ArrayList<DropTarget>();
10100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
10200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    private DragListener mListener;
10300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
10400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    /** The window token used as the parent for the DragView. */
10500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    private IBinder mWindowToken;
10600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
10700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    /** The view that will be scrolled when dragging to the left and right edges of the screen. */
10800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    private View mScrollView;
10900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
110ea3763c2672f77539538af8cdd395ad97058eaabRomain Guy    private View mMoveTarget;
111ea3763c2672f77539538af8cdd395ad97058eaabRomain Guy
11200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    private DragScroller mDragScroller;
11300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    private int mScrollState = SCROLL_OUTSIDE_ZONE;
11400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    private ScrollRunnable mScrollRunnable = new ScrollRunnable();
11500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
11600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    private RectF mDeleteRegion;
11700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    private DropTarget mLastDropTarget;
11800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
11900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    private InputMethodManager mInputMethodManager;
12000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
12131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    /**
12231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     * Interface to receive notifications when a drag starts or stops
12331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     */
12431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    interface DragListener {
12531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
12631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        /**
12731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project         * A drag has begun
12831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project         *
12931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project         * @param source An object representing where the drag originated
13031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project         * @param info The data associated with the object that is being dragged
13131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project         * @param dragAction The drag action: either {@link DragController#DRAG_ACTION_MOVE}
13231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project         *        or {@link DragController#DRAG_ACTION_COPY}
13331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project         */
1345162ea9b1f41dbebe00fd9ec4d1e15a697971439Joe Onorato        void onDragStart(DragSource source, Object info, int dragAction);
13531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
13631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        /**
13731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project         * The drag has eneded
13831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project         */
13931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        void onDragEnd();
14031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    }
14131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
14231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    /**
14300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato     * Used to create a new DragLayer from XML.
14400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato     *
14500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato     * @param context The application's context.
14631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     */
14700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    public DragController(Context context) {
14800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        mContext = context;
14900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        mHandler = new Handler();
15000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    }
15131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
15231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    /**
1535162ea9b1f41dbebe00fd9ec4d1e15a697971439Joe Onorato     * Starts a drag.
15431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     *
15531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     * @param v The view that is being dragged
15631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     * @param source An object representing where the drag originated
157ea3763c2672f77539538af8cdd395ad97058eaabRomain Guy     * @param dragInfo The data associated with the object that is being dragged
15831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     * @param dragAction The drag action: either {@link #DRAG_ACTION_MOVE} or
15931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     *        {@link #DRAG_ACTION_COPY}
16031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     */
16100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    public void startDrag(View v, DragSource source, Object dragInfo, int dragAction) {
1625162ea9b1f41dbebe00fd9ec4d1e15a697971439Joe Onorato        mOriginator = v;
1635162ea9b1f41dbebe00fd9ec4d1e15a697971439Joe Onorato
1645162ea9b1f41dbebe00fd9ec4d1e15a697971439Joe Onorato        Bitmap b = getViewBitmap(v);
1655162ea9b1f41dbebe00fd9ec4d1e15a697971439Joe Onorato
1663f8175a86e24b3568d1f5b12e1d3d5efcc57d691Daniel Sandler        if (b == null) {
1673f8175a86e24b3568d1f5b12e1d3d5efcc57d691Daniel Sandler            // out of memory?
1683f8175a86e24b3568d1f5b12e1d3d5efcc57d691Daniel Sandler            return;
1693f8175a86e24b3568d1f5b12e1d3d5efcc57d691Daniel Sandler        }
1703f8175a86e24b3568d1f5b12e1d3d5efcc57d691Daniel Sandler
1715162ea9b1f41dbebe00fd9ec4d1e15a697971439Joe Onorato        int[] loc = mCoordinatesTemp;
1725162ea9b1f41dbebe00fd9ec4d1e15a697971439Joe Onorato        v.getLocationOnScreen(loc);
1735162ea9b1f41dbebe00fd9ec4d1e15a697971439Joe Onorato        int screenX = loc[0];
1745162ea9b1f41dbebe00fd9ec4d1e15a697971439Joe Onorato        int screenY = loc[1];
1755162ea9b1f41dbebe00fd9ec4d1e15a697971439Joe Onorato
1765162ea9b1f41dbebe00fd9ec4d1e15a697971439Joe Onorato        startDrag(b, screenX, screenY, 0, 0, b.getWidth(), b.getHeight(),
1775162ea9b1f41dbebe00fd9ec4d1e15a697971439Joe Onorato                source, dragInfo, dragAction);
1785162ea9b1f41dbebe00fd9ec4d1e15a697971439Joe Onorato
1795162ea9b1f41dbebe00fd9ec4d1e15a697971439Joe Onorato        b.recycle();
1805162ea9b1f41dbebe00fd9ec4d1e15a697971439Joe Onorato
1815162ea9b1f41dbebe00fd9ec4d1e15a697971439Joe Onorato        if (dragAction == DRAG_ACTION_MOVE) {
1825162ea9b1f41dbebe00fd9ec4d1e15a697971439Joe Onorato            v.setVisibility(View.GONE);
1835162ea9b1f41dbebe00fd9ec4d1e15a697971439Joe Onorato        }
1845162ea9b1f41dbebe00fd9ec4d1e15a697971439Joe Onorato    }
1855162ea9b1f41dbebe00fd9ec4d1e15a697971439Joe Onorato
1865162ea9b1f41dbebe00fd9ec4d1e15a697971439Joe Onorato    /**
1875162ea9b1f41dbebe00fd9ec4d1e15a697971439Joe Onorato     * Starts a drag.
1885162ea9b1f41dbebe00fd9ec4d1e15a697971439Joe Onorato     *
1895162ea9b1f41dbebe00fd9ec4d1e15a697971439Joe Onorato     * @param b The bitmap to display as the drag image.  It will be re-scaled to the
1905162ea9b1f41dbebe00fd9ec4d1e15a697971439Joe Onorato     *          enlarged size.
1915162ea9b1f41dbebe00fd9ec4d1e15a697971439Joe Onorato     * @param screenX The x position on screen of the left-top of the bitmap.
1925162ea9b1f41dbebe00fd9ec4d1e15a697971439Joe Onorato     * @param screenY The y position on screen of the left-top of the bitmap.
1935162ea9b1f41dbebe00fd9ec4d1e15a697971439Joe Onorato     * @param textureLeft The left edge of the region inside b to use.
1945162ea9b1f41dbebe00fd9ec4d1e15a697971439Joe Onorato     * @param textureTop The top edge of the region inside b to use.
1955162ea9b1f41dbebe00fd9ec4d1e15a697971439Joe Onorato     * @param textureWidth The width of the region inside b to use.
1965162ea9b1f41dbebe00fd9ec4d1e15a697971439Joe Onorato     * @param textureHeight The height of the region inside b to use.
1975162ea9b1f41dbebe00fd9ec4d1e15a697971439Joe Onorato     * @param source An object representing where the drag originated
198ea3763c2672f77539538af8cdd395ad97058eaabRomain Guy     * @param dragInfo The data associated with the object that is being dragged
1995162ea9b1f41dbebe00fd9ec4d1e15a697971439Joe Onorato     * @param dragAction The drag action: either {@link #DRAG_ACTION_MOVE} or
2005162ea9b1f41dbebe00fd9ec4d1e15a697971439Joe Onorato     *        {@link #DRAG_ACTION_COPY}
2015162ea9b1f41dbebe00fd9ec4d1e15a697971439Joe Onorato     */
2025162ea9b1f41dbebe00fd9ec4d1e15a697971439Joe Onorato    public void startDrag(Bitmap b, int screenX, int screenY,
2035162ea9b1f41dbebe00fd9ec4d1e15a697971439Joe Onorato            int textureLeft, int textureTop, int textureWidth, int textureHeight,
2045162ea9b1f41dbebe00fd9ec4d1e15a697971439Joe Onorato            DragSource source, Object dragInfo, int dragAction) {
20500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        if (PROFILE_DRAWING_DURING_DRAG) {
20600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato            android.os.Debug.startMethodTracing("Launcher");
20700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        }
20800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
20900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        // Hide soft keyboard, if visible
21000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        if (mInputMethodManager == null) {
21100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato            mInputMethodManager = (InputMethodManager)
21200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato                    mContext.getSystemService(Context.INPUT_METHOD_SERVICE);
21300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        }
21400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        mInputMethodManager.hideSoftInputFromWindow(mWindowToken, 0);
21500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
21600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        if (mListener != null) {
2175162ea9b1f41dbebe00fd9ec4d1e15a697971439Joe Onorato            mListener.onDragStart(source, dragInfo, dragAction);
21800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        }
21900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
22000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        int registrationX = ((int)mMotionDownX) - screenX;
22100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        int registrationY = ((int)mMotionDownY) - screenY;
22200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
22300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        mTouchOffsetX = mMotionDownX - screenX;
22400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        mTouchOffsetY = mMotionDownY - screenY;
22500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
22600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        mDragging = true;
22700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        mDragSource = source;
22800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        mDragInfo = dragInfo;
22900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
23000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        mVibrator.vibrate(VIBRATE_DURATION);
23100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
2325162ea9b1f41dbebe00fd9ec4d1e15a697971439Joe Onorato        DragView dragView = mDragView = new DragView(mContext, b, registrationX, registrationY,
2335162ea9b1f41dbebe00fd9ec4d1e15a697971439Joe Onorato                textureLeft, textureTop, textureWidth, textureHeight);
23400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        dragView.show(mWindowToken, (int)mMotionDownX, (int)mMotionDownY);
23500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    }
23600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
23700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    /**
23800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato     * Draw the view into a bitmap.
23900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato     */
24000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    private Bitmap getViewBitmap(View v) {
24100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        v.clearFocus();
24200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        v.setPressed(false);
24300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
24400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        boolean willNotCache = v.willNotCacheDrawing();
24500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        v.setWillNotCacheDrawing(false);
24600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
24700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        // Reset the drawing cache background color to fully transparent
24800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        // for the duration of this operation
24900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        int color = v.getDrawingCacheBackgroundColor();
25000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        v.setDrawingCacheBackgroundColor(0);
25100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
25200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        if (color != 0) {
25300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato            v.destroyDrawingCache();
25400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        }
25500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        v.buildDrawingCache();
25600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        Bitmap cacheBitmap = v.getDrawingCache();
2573f8175a86e24b3568d1f5b12e1d3d5efcc57d691Daniel Sandler        if (cacheBitmap == null) {
2583f8175a86e24b3568d1f5b12e1d3d5efcc57d691Daniel Sandler            Log.e(TAG, "failed getViewBitmap(" + v + ")", new RuntimeException());
2593f8175a86e24b3568d1f5b12e1d3d5efcc57d691Daniel Sandler            return null;
2603f8175a86e24b3568d1f5b12e1d3d5efcc57d691Daniel Sandler        }
26100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
26200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        Bitmap bitmap = Bitmap.createBitmap(cacheBitmap);
26300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
26400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        // Restore the view
26500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        v.destroyDrawingCache();
26600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        v.setWillNotCacheDrawing(willNotCache);
26700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        v.setDrawingCacheBackgroundColor(color);
26800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
26900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        return bitmap;
27000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    }
27100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
27200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    /**
27300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato     * Call this from a drag source view like this:
27400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato     *
27500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato     * <pre>
27600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato     *  @Override
27700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato     *  public boolean dispatchKeyEvent(KeyEvent event) {
27800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato     *      return mDragController.dispatchKeyEvent(this, event)
27900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato     *              || super.dispatchKeyEvent(event);
28000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato     * </pre>
28100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato     */
282ea3763c2672f77539538af8cdd395ad97058eaabRomain Guy    @SuppressWarnings({"UnusedDeclaration"})
28300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    public boolean dispatchKeyEvent(KeyEvent event) {
28400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        return mDragging;
28500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    }
28600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
28724b6fd854f75f21700a330c2f0d11938e5dfeab6Joe Onorato    /**
28824b6fd854f75f21700a330c2f0d11938e5dfeab6Joe Onorato     * Stop dragging without dropping.
28924b6fd854f75f21700a330c2f0d11938e5dfeab6Joe Onorato     */
29024b6fd854f75f21700a330c2f0d11938e5dfeab6Joe Onorato    public void cancelDrag() {
29124b6fd854f75f21700a330c2f0d11938e5dfeab6Joe Onorato        endDrag();
29224b6fd854f75f21700a330c2f0d11938e5dfeab6Joe Onorato    }
29324b6fd854f75f21700a330c2f0d11938e5dfeab6Joe Onorato
29400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    private void endDrag() {
29500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        if (mDragging) {
29600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato            mDragging = false;
29700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato            if (mOriginator != null) {
29800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato                mOriginator.setVisibility(View.VISIBLE);
29900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato            }
30000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato            if (mListener != null) {
30100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato                mListener.onDragEnd();
30200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato            }
30300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato            if (mDragView != null) {
30400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato                mDragView.remove();
30500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato                mDragView = null;
30600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato            }
30700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        }
30800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    }
30900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
31000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    /**
31100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato     * Call this from a drag source view.
31200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato     */
31300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    public boolean onInterceptTouchEvent(MotionEvent ev) {
3149c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        if (false) {
315a30ce8e6b25e41f392a41fd4d0d3e0a424a84dadJoe Onorato            Log.d(Launcher.TAG, "DragController.onInterceptTouchEvent " + ev + " mDragging="
3169c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    + mDragging);
3179c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        }
31800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        final int action = ev.getAction();
31900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
32087467d3a2168180e8d6437d07d22b4dd0ef59845Joe Onorato        if (action == MotionEvent.ACTION_DOWN) {
32187467d3a2168180e8d6437d07d22b4dd0ef59845Joe Onorato            recordScreenSize();
32287467d3a2168180e8d6437d07d22b4dd0ef59845Joe Onorato        }
32387467d3a2168180e8d6437d07d22b4dd0ef59845Joe Onorato
324e048e8a8eff51e8c2c271d16c864367dac438ca2Joe Onorato        final int screenX = clamp((int)ev.getRawX(), 0, mDisplayMetrics.widthPixels);
325e048e8a8eff51e8c2c271d16c864367dac438ca2Joe Onorato        final int screenY = clamp((int)ev.getRawY(), 0, mDisplayMetrics.heightPixels);
32600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
32700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        switch (action) {
32800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato            case MotionEvent.ACTION_MOVE:
32900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato                break;
33000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
33100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato            case MotionEvent.ACTION_DOWN:
33200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato                // Remember location of down touch
33300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato                mMotionDownX = screenX;
33400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato                mMotionDownY = screenY;
33500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato                mLastDropTarget = null;
33600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato                break;
33700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
33800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato            case MotionEvent.ACTION_CANCEL:
33900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato            case MotionEvent.ACTION_UP:
34000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato                if (mDragging) {
34100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato                    drop(screenX, screenY);
34200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato                }
34300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato                endDrag();
34400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato                break;
34500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        }
34600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
34700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        return mDragging;
34800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    }
34900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
35000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    /**
351ea3763c2672f77539538af8cdd395ad97058eaabRomain Guy     * Sets the view that should handle move events.
352ea3763c2672f77539538af8cdd395ad97058eaabRomain Guy     */
353ea3763c2672f77539538af8cdd395ad97058eaabRomain Guy    void setMoveTarget(View view) {
354ea3763c2672f77539538af8cdd395ad97058eaabRomain Guy        mMoveTarget = view;
355ea3763c2672f77539538af8cdd395ad97058eaabRomain Guy    }
356ea3763c2672f77539538af8cdd395ad97058eaabRomain Guy
357ea3763c2672f77539538af8cdd395ad97058eaabRomain Guy    public boolean dispatchUnhandledMove(View focused, int direction) {
358ea3763c2672f77539538af8cdd395ad97058eaabRomain Guy        return mMoveTarget != null && mMoveTarget.dispatchUnhandledMove(focused, direction);
359ea3763c2672f77539538af8cdd395ad97058eaabRomain Guy    }
360ea3763c2672f77539538af8cdd395ad97058eaabRomain Guy
361ea3763c2672f77539538af8cdd395ad97058eaabRomain Guy    /**
36200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato     * Call this from a drag source view.
36300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato     */
36400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    public boolean onTouchEvent(MotionEvent ev) {
36500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        View scrollView = mScrollView;
36600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
36700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        if (!mDragging) {
36800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato            return false;
36900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        }
37000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
37100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        final int action = ev.getAction();
372e048e8a8eff51e8c2c271d16c864367dac438ca2Joe Onorato        final int screenX = clamp((int)ev.getRawX(), 0, mDisplayMetrics.widthPixels);
373e048e8a8eff51e8c2c271d16c864367dac438ca2Joe Onorato        final int screenY = clamp((int)ev.getRawY(), 0, mDisplayMetrics.heightPixels);
37400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
37500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        switch (action) {
37600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        case MotionEvent.ACTION_DOWN:
37700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato            // Remember where the motion event started
378e048e8a8eff51e8c2c271d16c864367dac438ca2Joe Onorato            mMotionDownX = screenX;
379e048e8a8eff51e8c2c271d16c864367dac438ca2Joe Onorato            mMotionDownY = screenY;
38000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
381e048e8a8eff51e8c2c271d16c864367dac438ca2Joe Onorato            if ((screenX < SCROLL_ZONE) || (screenX > scrollView.getWidth() - SCROLL_ZONE)) {
38200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato                mScrollState = SCROLL_WAITING_IN_ZONE;
38300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato                mHandler.postDelayed(mScrollRunnable, SCROLL_DELAY);
38400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato            } else {
38500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato                mScrollState = SCROLL_OUTSIDE_ZONE;
38600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato            }
38700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
38800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato            break;
38900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        case MotionEvent.ACTION_MOVE:
390e048e8a8eff51e8c2c271d16c864367dac438ca2Joe Onorato            // Update the drag view.  Don't use the clamped pos here so the dragging looks
391e048e8a8eff51e8c2c271d16c864367dac438ca2Joe Onorato            // like it goes off screen a little, intead of bumping up against the edge.
39200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato            mDragView.move((int)ev.getRawX(), (int)ev.getRawY());
39300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
39400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato            // Drop on someone?
39500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato            final int[] coordinates = mCoordinatesTemp;
396ea3763c2672f77539538af8cdd395ad97058eaabRomain Guy            DropTarget dropTarget = findDropTarget(screenX, screenY, coordinates);
39700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato            if (dropTarget != null) {
39800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato                if (mLastDropTarget == dropTarget) {
39900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato                    dropTarget.onDragOver(mDragSource, coordinates[0], coordinates[1],
40000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato                        (int) mTouchOffsetX, (int) mTouchOffsetY, mDragView, mDragInfo);
40100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato                } else {
40200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato                    if (mLastDropTarget != null) {
40300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato                        mLastDropTarget.onDragExit(mDragSource, coordinates[0], coordinates[1],
40400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato                            (int) mTouchOffsetX, (int) mTouchOffsetY, mDragView, mDragInfo);
40500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato                    }
40600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato                    dropTarget.onDragEnter(mDragSource, coordinates[0], coordinates[1],
40700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato                        (int) mTouchOffsetX, (int) mTouchOffsetY, mDragView, mDragInfo);
40800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato                }
40900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato            } else {
41000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato                if (mLastDropTarget != null) {
41100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato                    mLastDropTarget.onDragExit(mDragSource, coordinates[0], coordinates[1],
41200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato                        (int) mTouchOffsetX, (int) mTouchOffsetY, mDragView, mDragInfo);
41300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato                }
41400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato            }
41500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato            mLastDropTarget = dropTarget;
41600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
41700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato            // Scroll, maybe, but not if we're in the delete region.
41800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato            boolean inDeleteRegion = false;
41900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato            if (mDeleteRegion != null) {
420e048e8a8eff51e8c2c271d16c864367dac438ca2Joe Onorato                inDeleteRegion = mDeleteRegion.contains(screenX, screenY);
42100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato            }
422e048e8a8eff51e8c2c271d16c864367dac438ca2Joe Onorato            if (!inDeleteRegion && screenX < SCROLL_ZONE) {
42300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato                if (mScrollState == SCROLL_OUTSIDE_ZONE) {
42400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato                    mScrollState = SCROLL_WAITING_IN_ZONE;
42500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato                    mScrollRunnable.setDirection(SCROLL_LEFT);
42600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato                    mHandler.postDelayed(mScrollRunnable, SCROLL_DELAY);
42700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato                }
428e048e8a8eff51e8c2c271d16c864367dac438ca2Joe Onorato            } else if (!inDeleteRegion && screenX > scrollView.getWidth() - SCROLL_ZONE) {
42900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato                if (mScrollState == SCROLL_OUTSIDE_ZONE) {
43000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato                    mScrollState = SCROLL_WAITING_IN_ZONE;
43100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato                    mScrollRunnable.setDirection(SCROLL_RIGHT);
43200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato                    mHandler.postDelayed(mScrollRunnable, SCROLL_DELAY);
43300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato                }
43400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato            } else {
43500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato                if (mScrollState == SCROLL_WAITING_IN_ZONE) {
43600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato                    mScrollState = SCROLL_OUTSIDE_ZONE;
43700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato                    mScrollRunnable.setDirection(SCROLL_RIGHT);
43800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato                    mHandler.removeCallbacks(mScrollRunnable);
43900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato                }
44000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato            }
44100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
44200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato            break;
44300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        case MotionEvent.ACTION_UP:
44400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato            mHandler.removeCallbacks(mScrollRunnable);
44500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato            if (mDragging) {
446e048e8a8eff51e8c2c271d16c864367dac438ca2Joe Onorato                drop(screenX, screenY);
44700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato            }
44800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato            endDrag();
44900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
45000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato            break;
45100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        case MotionEvent.ACTION_CANCEL:
45224b6fd854f75f21700a330c2f0d11938e5dfeab6Joe Onorato            cancelDrag();
45300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        }
45400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
45500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        return true;
45600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    }
45700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
45800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    private boolean drop(float x, float y) {
45900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        final int[] coordinates = mCoordinatesTemp;
46000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        DropTarget dropTarget = findDropTarget((int) x, (int) y, coordinates);
46100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
46200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        if (dropTarget != null) {
46300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato            dropTarget.onDragExit(mDragSource, coordinates[0], coordinates[1],
46400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato                    (int) mTouchOffsetX, (int) mTouchOffsetY, mDragView, mDragInfo);
46500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato            if (dropTarget.acceptDrop(mDragSource, coordinates[0], coordinates[1],
46600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato                    (int) mTouchOffsetX, (int) mTouchOffsetY, mDragView, mDragInfo)) {
46700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato                dropTarget.onDrop(mDragSource, coordinates[0], coordinates[1],
46800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato                        (int) mTouchOffsetX, (int) mTouchOffsetY, mDragView, mDragInfo);
46900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato                mDragSource.onDropCompleted((View) dropTarget, true);
47000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato                return true;
47100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato            } else {
47200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato                mDragSource.onDropCompleted((View) dropTarget, false);
47300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato                return true;
47400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato            }
47500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        }
47600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        return false;
47700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    }
47800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
47900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    private DropTarget findDropTarget(int x, int y, int[] dropCoordinates) {
48000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        final Rect r = mRectTemp;
48100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
48200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        final ArrayList<DropTarget> dropTargets = mDropTargets;
48300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        final int count = dropTargets.size();
48400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        for (int i=count-1; i>=0; i--) {
48500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato            final DropTarget target = dropTargets.get(i);
48600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato            target.getHitRect(r);
48700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato            target.getLocationOnScreen(dropCoordinates);
48800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato            r.offset(dropCoordinates[0] - target.getLeft(), dropCoordinates[1] - target.getTop());
48900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato            if (r.contains(x, y)) {
49000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato                dropCoordinates[0] = x - dropCoordinates[0];
49100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato                dropCoordinates[1] = y - dropCoordinates[1];
49200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato                return target;
49300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato            }
49400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        }
49500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        return null;
49600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    }
49700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
498e048e8a8eff51e8c2c271d16c864367dac438ca2Joe Onorato    /**
499e048e8a8eff51e8c2c271d16c864367dac438ca2Joe Onorato     * Get the screen size so we can clamp events to the screen size so even if
500e048e8a8eff51e8c2c271d16c864367dac438ca2Joe Onorato     * you drag off the edge of the screen, we find something.
501e048e8a8eff51e8c2c271d16c864367dac438ca2Joe Onorato     */
502e048e8a8eff51e8c2c271d16c864367dac438ca2Joe Onorato    private void recordScreenSize() {
503e048e8a8eff51e8c2c271d16c864367dac438ca2Joe Onorato        ((WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE))
504e048e8a8eff51e8c2c271d16c864367dac438ca2Joe Onorato                .getDefaultDisplay().getMetrics(mDisplayMetrics);
505e048e8a8eff51e8c2c271d16c864367dac438ca2Joe Onorato    }
506e048e8a8eff51e8c2c271d16c864367dac438ca2Joe Onorato
507e048e8a8eff51e8c2c271d16c864367dac438ca2Joe Onorato    /**
508e048e8a8eff51e8c2c271d16c864367dac438ca2Joe Onorato     * Clamp val to be &gt;= min and &lt; max.
509e048e8a8eff51e8c2c271d16c864367dac438ca2Joe Onorato     */
510e048e8a8eff51e8c2c271d16c864367dac438ca2Joe Onorato    private static int clamp(int val, int min, int max) {
511e048e8a8eff51e8c2c271d16c864367dac438ca2Joe Onorato        if (val < min) {
512e048e8a8eff51e8c2c271d16c864367dac438ca2Joe Onorato            return min;
513e048e8a8eff51e8c2c271d16c864367dac438ca2Joe Onorato        } else if (val >= max) {
514e048e8a8eff51e8c2c271d16c864367dac438ca2Joe Onorato            return max - 1;
515e048e8a8eff51e8c2c271d16c864367dac438ca2Joe Onorato        } else {
516e048e8a8eff51e8c2c271d16c864367dac438ca2Joe Onorato            return val;
517e048e8a8eff51e8c2c271d16c864367dac438ca2Joe Onorato        }
518e048e8a8eff51e8c2c271d16c864367dac438ca2Joe Onorato    }
519e048e8a8eff51e8c2c271d16c864367dac438ca2Joe Onorato
52000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    public void setDragScoller(DragScroller scroller) {
52100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        mDragScroller = scroller;
52200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    }
52300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
52400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    public void setWindowToken(IBinder token) {
52500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        mWindowToken = token;
52600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    }
52700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
52831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    /**
52931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     * Sets the drag listner which will be notified when a drag starts or ends.
53031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     */
53100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    public void setDragListener(DragListener l) {
53200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        mListener = l;
53300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    }
53400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
53531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    /**
53631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     * Remove a previously installed drag listener.
53731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     */
53800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    public void removeDragListener(DragListener l) {
53900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        mListener = null;
54000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    }
54100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
54200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    /**
54300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato     * Add a DropTarget to the list of potential places to receive drop events.
54400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato     */
54500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    public void addDropTarget(DropTarget target) {
54600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        mDropTargets.add(target);
54700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    }
54800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
54900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    /**
55000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato     * Don't send drop events to <em>target</em> any more.
55100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato     */
55200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    public void removeDropTarget(DropTarget target) {
55300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        mDropTargets.remove(target);
55400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    }
55500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
55600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    /**
55700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato     * Set which view scrolls for touch events near the edge of the screen.
55800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato     */
55900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    public void setScrollView(View v) {
56000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        mScrollView = v;
56100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    }
56200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
56300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    /**
56400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato     * Specifies the delete region.  We won't scroll on touch events over the delete region.
56500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato     *
56600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato     * @param region The rectangle in screen coordinates of the delete region.
56700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato     */
56800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    void setDeleteRegion(RectF region) {
56900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        mDeleteRegion = region;
57000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    }
57100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
57200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    private class ScrollRunnable implements Runnable {
57300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        private int mDirection;
57400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
57500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        ScrollRunnable() {
57600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        }
57700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
57800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        public void run() {
57900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato            if (mDragScroller != null) {
58000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato                if (mDirection == SCROLL_LEFT) {
58100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato                    mDragScroller.scrollLeft();
58200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato                } else {
58300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato                    mDragScroller.scrollRight();
58400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato                }
58500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato                mScrollState = SCROLL_OUTSIDE_ZONE;
58600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato            }
58700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        }
58800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
58900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        void setDirection(int direction) {
59000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato            mDirection = direction;
59100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        }
59200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    }
59331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project}
594