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 >= min and < 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