DragController.java revision 24b6fd854f75f21700a330c2f0d11938e5dfeab6
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.Canvas;
2200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onoratoimport android.graphics.Matrix;
2300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onoratoimport android.graphics.Rect;
2400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onoratoimport android.graphics.RectF;
2500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onoratoimport android.os.IBinder;
2600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onoratoimport android.os.Handler;
2700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onoratoimport android.os.Vibrator;
2800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onoratoimport android.os.SystemClock;
2900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onoratoimport android.util.AttributeSet;
30e048e8a8eff51e8c2c271d16c864367dac438ca2Joe Onoratoimport android.util.DisplayMetrics;
3100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onoratoimport android.util.Log;
3231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.view.View;
3300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onoratoimport android.view.ViewGroup;
3400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onoratoimport android.view.KeyEvent;
3500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onoratoimport android.view.MotionEvent;
36e048e8a8eff51e8c2c271d16c864367dac438ca2Joe Onoratoimport android.view.WindowManager;
3700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onoratoimport android.view.inputmethod.InputMethodManager;
3800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onoratoimport android.widget.FrameLayout;
3900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onoratoimport android.widget.ImageView;
4000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
4100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onoratoimport java.util.ArrayList;
4231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
4331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project/**
4400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato * Class for initiating a drag within a view or across multiple views.
4531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project */
4600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onoratopublic class DragController {
472e5c432a0aa7e83031575df73bed43a297e2eed3Joe Onorato    private static final String TAG = "Launcher.DragController";
482e5c432a0aa7e83031575df73bed43a297e2eed3Joe Onorato
4900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    /** Indicates the drag is a move.  */
5000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    public static int DRAG_ACTION_MOVE = 0;
5100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
5200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    /** Indicates the drag is a copy.  */
5300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    public static int DRAG_ACTION_COPY = 1;
5400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
5500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    private static final int SCROLL_DELAY = 600;
5600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    private static final int SCROLL_ZONE = 20;
5700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    private static final int VIBRATE_DURATION = 35;
5800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
5900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    private static final boolean PROFILE_DRAWING_DURING_DRAG = false;
6000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
6100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    private static final int SCROLL_OUTSIDE_ZONE = 0;
6200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    private static final int SCROLL_WAITING_IN_ZONE = 1;
6300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
6400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    private static final int SCROLL_LEFT = 0;
6500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    private static final int SCROLL_RIGHT = 1;
6600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
6700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    private Context mContext;
6800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    private Handler mHandler;
6900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    private final Vibrator mVibrator = new Vibrator();
7000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
7100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    // temporaries to avoid gc thrash
7200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    private Rect mRectTemp = new Rect();
7300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    private final int[] mCoordinatesTemp = new int[2];
7400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
7500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    /** Whether or not we're dragging. */
7600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    private boolean mDragging;
7700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
7800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    /** X coordinate of the down event. */
7900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    private float mMotionDownX;
8000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
8100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    /** Y coordinate of the down event. */
8200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    private float mMotionDownY;
8300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
84e048e8a8eff51e8c2c271d16c864367dac438ca2Joe Onorato    /** Info about the screen for clamping. */
85e048e8a8eff51e8c2c271d16c864367dac438ca2Joe Onorato    private DisplayMetrics mDisplayMetrics = new DisplayMetrics();
86e048e8a8eff51e8c2c271d16c864367dac438ca2Joe Onorato
8700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    /** Original view that is being dragged.  */
8800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    private View mOriginator;
8900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
9000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    /** X offset from the upper-left corner of the cell to where we touched.  */
9100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    private float mTouchOffsetX;
9200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
9300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    /** Y offset from the upper-left corner of the cell to where we touched.  */
9400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    private float mTouchOffsetY;
9500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
9600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    /** Where the drag originated */
9700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    private DragSource mDragSource;
9800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
9900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    /** The data associated with the object being dragged */
10000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    private Object mDragInfo;
10100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
10200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    /** The view that moves around while you drag.  */
10300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    private DragView mDragView;
10400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
10500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    /** Who can receive drop events */
10600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    private ArrayList<DropTarget> mDropTargets = new ArrayList<DropTarget>();
10700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
10800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    private DragListener mListener;
10900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
11000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    /** The window token used as the parent for the DragView. */
11100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    private IBinder mWindowToken;
11200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
11300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    /** The view that will be scrolled when dragging to the left and right edges of the screen. */
11400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    private View mScrollView;
11500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
11600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    private DragScroller mDragScroller;
11700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    private int mScrollState = SCROLL_OUTSIDE_ZONE;
11800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    private ScrollRunnable mScrollRunnable = new ScrollRunnable();
11900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
12000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    private RectF mDeleteRegion;
12100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    private DropTarget mLastDropTarget;
12200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
12300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    private InputMethodManager mInputMethodManager;
12400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
12531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    /**
12631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     * Interface to receive notifications when a drag starts or stops
12731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     */
12831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    interface DragListener {
12931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
13031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        /**
13131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project         * A drag has begun
13231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project         *
13331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project         * @param source An object representing where the drag originated
13431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project         * @param info The data associated with the object that is being dragged
13531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project         * @param dragAction The drag action: either {@link DragController#DRAG_ACTION_MOVE}
13631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project         *        or {@link DragController#DRAG_ACTION_COPY}
13731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project         */
1385162ea9b1f41dbebe00fd9ec4d1e15a697971439Joe Onorato        void onDragStart(DragSource source, Object info, int dragAction);
13931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
14031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        /**
14131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project         * The drag has eneded
14231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project         */
14331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        void onDragEnd();
14431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    }
14531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
14631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    /**
14700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato     * Used to create a new DragLayer from XML.
14800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato     *
14900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato     * @param context The application's context.
15000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato     * @param attrs The attribtues set containing the Workspace's customization values.
15131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     */
15200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    public DragController(Context context) {
15300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        mContext = context;
15400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        mHandler = new Handler();
15500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    }
15631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
15731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    /**
1585162ea9b1f41dbebe00fd9ec4d1e15a697971439Joe Onorato     * Starts a drag.
15931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     *
16031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     * @param v The view that is being dragged
16131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     * @param source An object representing where the drag originated
16231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     * @param info The data associated with the object that is being dragged
16331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     * @param dragAction The drag action: either {@link #DRAG_ACTION_MOVE} or
16431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     *        {@link #DRAG_ACTION_COPY}
16531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     */
16600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    public void startDrag(View v, DragSource source, Object dragInfo, int dragAction) {
1675162ea9b1f41dbebe00fd9ec4d1e15a697971439Joe Onorato        mOriginator = v;
1685162ea9b1f41dbebe00fd9ec4d1e15a697971439Joe Onorato
1695162ea9b1f41dbebe00fd9ec4d1e15a697971439Joe Onorato        Bitmap b = getViewBitmap(v);
1705162ea9b1f41dbebe00fd9ec4d1e15a697971439Joe Onorato
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
1985162ea9b1f41dbebe00fd9ec4d1e15a697971439Joe Onorato     * @param info 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();
25700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
25800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        Bitmap bitmap = Bitmap.createBitmap(cacheBitmap);
25900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
26000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        // Restore the view
26100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        v.destroyDrawingCache();
26200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        v.setWillNotCacheDrawing(willNotCache);
26300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        v.setDrawingCacheBackgroundColor(color);
26400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
26500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        return bitmap;
26600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    }
26700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
26800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    /**
26900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato     * Call this from a drag source view like this:
27000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato     *
27100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato     * <pre>
27200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato     *  @Override
27300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato     *  public boolean dispatchKeyEvent(KeyEvent event) {
27400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato     *      return mDragController.dispatchKeyEvent(this, event)
27500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato     *              || super.dispatchKeyEvent(event);
27600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato     * </pre>
27700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato     */
27800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    public boolean dispatchKeyEvent(KeyEvent event) {
27900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        return mDragging;
28000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    }
28100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
28224b6fd854f75f21700a330c2f0d11938e5dfeab6Joe Onorato    /**
28324b6fd854f75f21700a330c2f0d11938e5dfeab6Joe Onorato     * Stop dragging without dropping.
28424b6fd854f75f21700a330c2f0d11938e5dfeab6Joe Onorato     */
28524b6fd854f75f21700a330c2f0d11938e5dfeab6Joe Onorato    public void cancelDrag() {
28624b6fd854f75f21700a330c2f0d11938e5dfeab6Joe Onorato        endDrag();
28724b6fd854f75f21700a330c2f0d11938e5dfeab6Joe Onorato    }
28824b6fd854f75f21700a330c2f0d11938e5dfeab6Joe Onorato
28900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    private void endDrag() {
29000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        if (mDragging) {
29100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato            mDragging = false;
29200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato            if (mOriginator != null) {
29300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato                mOriginator.setVisibility(View.VISIBLE);
29400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato            }
29500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato            if (mListener != null) {
29600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato                mListener.onDragEnd();
29700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato            }
29800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato            if (mDragView != null) {
29900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato                mDragView.remove();
30000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato                mDragView = null;
30100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato            }
30200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        }
30300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    }
30400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
30500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    /**
30600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato     * Call this from a drag source view.
30700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato     */
30800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    public boolean onInterceptTouchEvent(MotionEvent ev) {
3099c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        if (false) {
310a30ce8e6b25e41f392a41fd4d0d3e0a424a84dadJoe Onorato            Log.d(Launcher.TAG, "DragController.onInterceptTouchEvent " + ev + " mDragging="
3119c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato                    + mDragging);
3129c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato        }
31300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        final int action = ev.getAction();
31400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
31587467d3a2168180e8d6437d07d22b4dd0ef59845Joe Onorato        if (action == MotionEvent.ACTION_DOWN) {
31687467d3a2168180e8d6437d07d22b4dd0ef59845Joe Onorato            recordScreenSize();
31787467d3a2168180e8d6437d07d22b4dd0ef59845Joe Onorato        }
31887467d3a2168180e8d6437d07d22b4dd0ef59845Joe Onorato
319e048e8a8eff51e8c2c271d16c864367dac438ca2Joe Onorato        final int screenX = clamp((int)ev.getRawX(), 0, mDisplayMetrics.widthPixels);
320e048e8a8eff51e8c2c271d16c864367dac438ca2Joe Onorato        final int screenY = clamp((int)ev.getRawY(), 0, mDisplayMetrics.heightPixels);
32100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
32200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        switch (action) {
32300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato            case MotionEvent.ACTION_MOVE:
32400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato                break;
32500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
32600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato            case MotionEvent.ACTION_DOWN:
32700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato                // Remember location of down touch
32800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato                mMotionDownX = screenX;
32900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato                mMotionDownY = screenY;
33000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato                mLastDropTarget = null;
33100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato                break;
33200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
33300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato            case MotionEvent.ACTION_CANCEL:
33400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato            case MotionEvent.ACTION_UP:
33500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato                if (mDragging) {
33600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato                    drop(screenX, screenY);
33700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato                }
33800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato                endDrag();
33900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato                break;
34000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        }
34100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
34200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        return mDragging;
34300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    }
34400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
34500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    /**
34600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato     * Call this from a drag source view.
34700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato     */
34800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    public boolean onTouchEvent(MotionEvent ev) {
34900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        View scrollView = mScrollView;
35000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
35100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        if (!mDragging) {
35200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato            return false;
35300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        }
35400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
35500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        final int action = ev.getAction();
356e048e8a8eff51e8c2c271d16c864367dac438ca2Joe Onorato        final int screenX = clamp((int)ev.getRawX(), 0, mDisplayMetrics.widthPixels);
357e048e8a8eff51e8c2c271d16c864367dac438ca2Joe Onorato        final int screenY = clamp((int)ev.getRawY(), 0, mDisplayMetrics.heightPixels);
35800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
35900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        switch (action) {
36000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        case MotionEvent.ACTION_DOWN:
36100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato            // Remember where the motion event started
362e048e8a8eff51e8c2c271d16c864367dac438ca2Joe Onorato            mMotionDownX = screenX;
363e048e8a8eff51e8c2c271d16c864367dac438ca2Joe Onorato            mMotionDownY = screenY;
36400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
365e048e8a8eff51e8c2c271d16c864367dac438ca2Joe Onorato            if ((screenX < SCROLL_ZONE) || (screenX > scrollView.getWidth() - SCROLL_ZONE)) {
36600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato                mScrollState = SCROLL_WAITING_IN_ZONE;
36700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato                mHandler.postDelayed(mScrollRunnable, SCROLL_DELAY);
36800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato            } else {
36900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato                mScrollState = SCROLL_OUTSIDE_ZONE;
37000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato            }
37100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
37200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato            break;
37300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        case MotionEvent.ACTION_MOVE:
374e048e8a8eff51e8c2c271d16c864367dac438ca2Joe Onorato            // Update the drag view.  Don't use the clamped pos here so the dragging looks
375e048e8a8eff51e8c2c271d16c864367dac438ca2Joe Onorato            // like it goes off screen a little, intead of bumping up against the edge.
37600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato            mDragView.move((int)ev.getRawX(), (int)ev.getRawY());
37700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
37800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato            // Drop on someone?
37900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato            final int[] coordinates = mCoordinatesTemp;
380e048e8a8eff51e8c2c271d16c864367dac438ca2Joe Onorato            DropTarget dropTarget = findDropTarget((int) screenX, (int) screenY, coordinates);
38100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato            if (dropTarget != null) {
38200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato                if (mLastDropTarget == dropTarget) {
38300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato                    dropTarget.onDragOver(mDragSource, coordinates[0], coordinates[1],
38400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato                        (int) mTouchOffsetX, (int) mTouchOffsetY, mDragView, mDragInfo);
38500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato                } else {
38600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato                    if (mLastDropTarget != null) {
38700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato                        mLastDropTarget.onDragExit(mDragSource, coordinates[0], coordinates[1],
38800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato                            (int) mTouchOffsetX, (int) mTouchOffsetY, mDragView, mDragInfo);
38900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato                    }
39000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato                    dropTarget.onDragEnter(mDragSource, coordinates[0], coordinates[1],
39100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato                        (int) mTouchOffsetX, (int) mTouchOffsetY, mDragView, mDragInfo);
39200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato                }
39300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato            } else {
39400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato                if (mLastDropTarget != null) {
39500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato                    mLastDropTarget.onDragExit(mDragSource, coordinates[0], coordinates[1],
39600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato                        (int) mTouchOffsetX, (int) mTouchOffsetY, mDragView, mDragInfo);
39700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato                }
39800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato            }
39900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato            mLastDropTarget = dropTarget;
40000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
40100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato            // Scroll, maybe, but not if we're in the delete region.
40200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato            boolean inDeleteRegion = false;
40300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato            if (mDeleteRegion != null) {
404e048e8a8eff51e8c2c271d16c864367dac438ca2Joe Onorato                inDeleteRegion = mDeleteRegion.contains(screenX, screenY);
40500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato            }
406e048e8a8eff51e8c2c271d16c864367dac438ca2Joe Onorato            if (!inDeleteRegion && screenX < SCROLL_ZONE) {
40700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato                if (mScrollState == SCROLL_OUTSIDE_ZONE) {
40800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato                    mScrollState = SCROLL_WAITING_IN_ZONE;
40900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato                    mScrollRunnable.setDirection(SCROLL_LEFT);
41000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato                    mHandler.postDelayed(mScrollRunnable, SCROLL_DELAY);
41100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato                }
412e048e8a8eff51e8c2c271d16c864367dac438ca2Joe Onorato            } else if (!inDeleteRegion && screenX > scrollView.getWidth() - SCROLL_ZONE) {
41300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato                if (mScrollState == SCROLL_OUTSIDE_ZONE) {
41400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato                    mScrollState = SCROLL_WAITING_IN_ZONE;
41500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato                    mScrollRunnable.setDirection(SCROLL_RIGHT);
41600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato                    mHandler.postDelayed(mScrollRunnable, SCROLL_DELAY);
41700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato                }
41800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato            } else {
41900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato                if (mScrollState == SCROLL_WAITING_IN_ZONE) {
42000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato                    mScrollState = SCROLL_OUTSIDE_ZONE;
42100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato                    mScrollRunnable.setDirection(SCROLL_RIGHT);
42200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato                    mHandler.removeCallbacks(mScrollRunnable);
42300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato                }
42400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato            }
42500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
42600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato            break;
42700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        case MotionEvent.ACTION_UP:
42800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato            mHandler.removeCallbacks(mScrollRunnable);
42900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato            if (mDragging) {
430e048e8a8eff51e8c2c271d16c864367dac438ca2Joe Onorato                drop(screenX, screenY);
43100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato            }
43200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato            endDrag();
43300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
43400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato            break;
43500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        case MotionEvent.ACTION_CANCEL:
43624b6fd854f75f21700a330c2f0d11938e5dfeab6Joe Onorato            cancelDrag();
43700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        }
43800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
43900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        return true;
44000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    }
44100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
44200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    private boolean drop(float x, float y) {
44300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        final int[] coordinates = mCoordinatesTemp;
44400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        DropTarget dropTarget = findDropTarget((int) x, (int) y, coordinates);
44500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
44600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        if (dropTarget != null) {
44700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato            dropTarget.onDragExit(mDragSource, coordinates[0], coordinates[1],
44800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato                    (int) mTouchOffsetX, (int) mTouchOffsetY, mDragView, mDragInfo);
44900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato            if (dropTarget.acceptDrop(mDragSource, coordinates[0], coordinates[1],
45000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato                    (int) mTouchOffsetX, (int) mTouchOffsetY, mDragView, mDragInfo)) {
45100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato                dropTarget.onDrop(mDragSource, coordinates[0], coordinates[1],
45200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato                        (int) mTouchOffsetX, (int) mTouchOffsetY, mDragView, mDragInfo);
45300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato                mDragSource.onDropCompleted((View) dropTarget, true);
45400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato                return true;
45500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato            } else {
45600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato                mDragSource.onDropCompleted((View) dropTarget, false);
45700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato                return true;
45800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato            }
45900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        }
46000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        return false;
46100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    }
46200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
46300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    private DropTarget findDropTarget(int x, int y, int[] dropCoordinates) {
46400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        final Rect r = mRectTemp;
46500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
46600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        final ArrayList<DropTarget> dropTargets = mDropTargets;
46700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        final int count = dropTargets.size();
46800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        for (int i=count-1; i>=0; i--) {
46900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato            final DropTarget target = dropTargets.get(i);
47000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato            target.getHitRect(r);
47100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato            target.getLocationOnScreen(dropCoordinates);
47200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato            r.offset(dropCoordinates[0] - target.getLeft(), dropCoordinates[1] - target.getTop());
47300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato            if (r.contains(x, y)) {
47400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato                dropCoordinates[0] = x - dropCoordinates[0];
47500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato                dropCoordinates[1] = y - dropCoordinates[1];
47600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato                return target;
47700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato            }
47800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        }
47900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        return null;
48000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    }
48100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
482e048e8a8eff51e8c2c271d16c864367dac438ca2Joe Onorato    /**
483e048e8a8eff51e8c2c271d16c864367dac438ca2Joe Onorato     * Get the screen size so we can clamp events to the screen size so even if
484e048e8a8eff51e8c2c271d16c864367dac438ca2Joe Onorato     * you drag off the edge of the screen, we find something.
485e048e8a8eff51e8c2c271d16c864367dac438ca2Joe Onorato     */
486e048e8a8eff51e8c2c271d16c864367dac438ca2Joe Onorato    private void recordScreenSize() {
487e048e8a8eff51e8c2c271d16c864367dac438ca2Joe Onorato        ((WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE))
488e048e8a8eff51e8c2c271d16c864367dac438ca2Joe Onorato                .getDefaultDisplay().getMetrics(mDisplayMetrics);
489e048e8a8eff51e8c2c271d16c864367dac438ca2Joe Onorato    }
490e048e8a8eff51e8c2c271d16c864367dac438ca2Joe Onorato
491e048e8a8eff51e8c2c271d16c864367dac438ca2Joe Onorato    /**
492e048e8a8eff51e8c2c271d16c864367dac438ca2Joe Onorato     * Clamp val to be &gt;= min and &lt; max.
493e048e8a8eff51e8c2c271d16c864367dac438ca2Joe Onorato     */
494e048e8a8eff51e8c2c271d16c864367dac438ca2Joe Onorato    private static int clamp(int val, int min, int max) {
495e048e8a8eff51e8c2c271d16c864367dac438ca2Joe Onorato        if (val < min) {
496e048e8a8eff51e8c2c271d16c864367dac438ca2Joe Onorato            return min;
497e048e8a8eff51e8c2c271d16c864367dac438ca2Joe Onorato        } else if (val >= max) {
498e048e8a8eff51e8c2c271d16c864367dac438ca2Joe Onorato            return max - 1;
499e048e8a8eff51e8c2c271d16c864367dac438ca2Joe Onorato        } else {
500e048e8a8eff51e8c2c271d16c864367dac438ca2Joe Onorato            return val;
501e048e8a8eff51e8c2c271d16c864367dac438ca2Joe Onorato        }
502e048e8a8eff51e8c2c271d16c864367dac438ca2Joe Onorato    }
503e048e8a8eff51e8c2c271d16c864367dac438ca2Joe Onorato
50400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    public void setDragScoller(DragScroller scroller) {
50500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        mDragScroller = scroller;
50600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    }
50700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
50800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    public void setWindowToken(IBinder token) {
50900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        mWindowToken = token;
51000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    }
51100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
51231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    /**
51331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     * Sets the drag listner which will be notified when a drag starts or ends.
51431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     */
51500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    public void setDragListener(DragListener l) {
51600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        mListener = l;
51700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    }
51800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
51931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    /**
52031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     * Remove a previously installed drag listener.
52131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     */
52200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    public void removeDragListener(DragListener l) {
52300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        mListener = null;
52400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    }
52500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
52600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    /**
52700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato     * Add a DropTarget to the list of potential places to receive drop events.
52800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato     */
52900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    public void addDropTarget(DropTarget target) {
53000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        mDropTargets.add(target);
53100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    }
53200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
53300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    /**
53400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato     * Don't send drop events to <em>target</em> any more.
53500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato     */
53600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    public void removeDropTarget(DropTarget target) {
53700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        mDropTargets.remove(target);
53800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    }
53900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
54000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    /**
54100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato     * Set which view scrolls for touch events near the edge of the screen.
54200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato     */
54300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    public void setScrollView(View v) {
54400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        mScrollView = v;
54500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    }
54600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
54700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    /**
54800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato     * Specifies the delete region.  We won't scroll on touch events over the delete region.
54900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato     *
55000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato     * @param region The rectangle in screen coordinates of the delete region.
55100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato     */
55200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    void setDeleteRegion(RectF region) {
55300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        mDeleteRegion = region;
55400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    }
55500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
55600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    private class ScrollRunnable implements Runnable {
55700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        private int mDirection;
55800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
55900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        ScrollRunnable() {
56000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        }
56100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
56200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        public void run() {
56300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato            if (mDragScroller != null) {
56400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato                if (mDirection == SCROLL_LEFT) {
56500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato                    mDragScroller.scrollLeft();
56600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato                } else {
56700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato                    mDragScroller.scrollRight();
56800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato                }
56900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato                mScrollState = SCROLL_OUTSIDE_ZONE;
57000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato            }
57100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        }
57200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
57300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        void setDirection(int direction) {
57400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato            mDirection = direction;
57500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        }
57600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    }
57731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project}
578