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 17325dc23624160689e59fbac708cf6f222b20d025Daniel Sandlerpackage com.android.launcher3; 1831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 19df95eb12a4d288ffa143a0c3db60e7e98f3e03b9Winson Chungimport android.content.ComponentName; 2000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onoratoimport android.content.Context; 216e1bdaf4198f9eb7b4124550d3ad07da2a0226e4Winson Chungimport android.content.res.Resources; 2200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onoratoimport android.graphics.Bitmap; 23b8c69f3c17a40adc2d85e8e996f754c383c293dcWinson Chungimport android.graphics.Point; 24043f2af567178b82b0b41f12d379e7dd12da2936Winson Chungimport android.graphics.PointF; 2500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onoratoimport android.graphics.Rect; 2600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onoratoimport android.os.Handler; 270280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurkaimport android.os.IBinder; 2800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onoratoimport android.util.Log; 294390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyalimport android.view.HapticFeedbackConstants; 304390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyalimport android.view.KeyEvent; 314390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyalimport android.view.MotionEvent; 324390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyalimport android.view.VelocityTracker; 334390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyalimport android.view.View; 344390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyalimport android.view.ViewConfiguration; 3500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onoratoimport android.view.inputmethod.InputMethodManager; 36c0dcf597084d00e4c23a7fea5fd0738f6c095a6bAdam Cohen 37091440a9cb9d4f42406631004aa484cbb79214caAdam Cohenimport com.android.launcher3.util.Thunk; 38091440a9cb9d4f42406631004aa484cbb79214caAdam Cohen 39c0dcf597084d00e4c23a7fea5fd0738f6c095a6bAdam Cohenimport java.util.ArrayList; 404390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyalimport java.util.HashSet; 4131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 4231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project/** 4300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato * Class for initiating a drag within a view or across multiple views. 4431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project */ 4500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onoratopublic class DragController { 462e5c432a0aa7e83031575df73bed43a297e2eed3Joe Onorato private static final String TAG = "Launcher.DragController"; 472e5c432a0aa7e83031575df73bed43a297e2eed3Joe Onorato 4800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato /** Indicates the drag is a move. */ 4900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato public static int DRAG_ACTION_MOVE = 0; 5000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato 5100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato /** Indicates the drag is a copy. */ 5200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato public static int DRAG_ACTION_COPY = 1; 5300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato 544846193300245c8c0a1f9bde3175f273df044309Sunny Goyal public static final int SCROLL_DELAY = 500; 554846193300245c8c0a1f9bde3175f273df044309Sunny Goyal public static final int RESCROLL_DELAY = PagedView.PAGE_SNAP_ANIMATION_DURATION + 150; 5600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato 5700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato private static final boolean PROFILE_DRAWING_DURING_DRAG = false; 5800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato 5900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato private static final int SCROLL_OUTSIDE_ZONE = 0; 6000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato private static final int SCROLL_WAITING_IN_ZONE = 1; 6100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato 6254fa3b95557c283976e8c1aa8a157b460b0b4513Patrick Dubroy static final int SCROLL_NONE = -1; 631262e369484ce7f2565655ed80e6299232c70bd7Patrick Dubroy static final int SCROLL_LEFT = 0; 641262e369484ce7f2565655ed80e6299232c70bd7Patrick Dubroy static final int SCROLL_RIGHT = 1; 6500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato 66043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung private static final float MAX_FLING_DEGREES = 35f; 67043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung 68091440a9cb9d4f42406631004aa484cbb79214caAdam Cohen @Thunk Launcher mLauncher; 6900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato private Handler mHandler; 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]; 747066003b2032a49ae5e59dab9b706259bdeb7e6eSunny Goyal private final boolean mIsRtl; 7500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato 7600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato /** Whether or not we're dragging. */ 7700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato private boolean mDragging; 7800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato 79c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen /** Whether or not this is an accessible drag operation */ 80c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen private boolean mIsAccessibleDrag; 81c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen 8200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato /** X coordinate of the down event. */ 83e3e27a854f3eca363d3c5ce353d19de475272d87Adam Cohen private int mMotionDownX; 8400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato 8500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato /** Y coordinate of the down event. */ 86e3e27a854f3eca363d3c5ce353d19de475272d87Adam Cohen private int mMotionDownY; 8700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato 88658db74c24817892f1a379b16620744f38f60e40Joe Onorato /** the area at the edge of the screen that makes the workspace go left 89658db74c24817892f1a379b16620744f38f60e40Joe Onorato * or right while you're dragging. 90658db74c24817892f1a379b16620744f38f60e40Joe Onorato */ 91658db74c24817892f1a379b16620744f38f60e40Joe Onorato private int mScrollZone; 92658db74c24817892f1a379b16620744f38f60e40Joe Onorato 939932a9b1e66fed4b5f38ce50f13d56331bbdcd7eAdam Cohen private DropTarget.DragObject mDragObject; 9400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato 9500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato /** Who can receive drop events */ 9600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato private ArrayList<DropTarget> mDropTargets = new ArrayList<DropTarget>(); 974ed6278e518cc6894cb150b606382e8e6a012599Patrick Dubroy private ArrayList<DragListener> mListeners = new ArrayList<DragListener>(); 98043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung private DropTarget mFlingToDeleteDropTarget; 9900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato 10000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato /** The window token used as the parent for the DragView. */ 10100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato private IBinder mWindowToken; 10200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato 10300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato /** The view that will be scrolled when dragging to the left and right edges of the screen. */ 10400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato private View mScrollView; 10500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato 106ea3763c2672f77539538af8cdd395ad97058eaabRomain Guy private View mMoveTarget; 107ea3763c2672f77539538af8cdd395ad97058eaabRomain Guy 108091440a9cb9d4f42406631004aa484cbb79214caAdam Cohen @Thunk DragScroller mDragScroller; 109091440a9cb9d4f42406631004aa484cbb79214caAdam Cohen @Thunk int mScrollState = SCROLL_OUTSIDE_ZONE; 11000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato private ScrollRunnable mScrollRunnable = new ScrollRunnable(); 11100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato 11200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato private DropTarget mLastDropTarget; 11300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato 11400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato private InputMethodManager mInputMethodManager; 11500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato 116091440a9cb9d4f42406631004aa484cbb79214caAdam Cohen @Thunk int mLastTouch[] = new int[2]; 117091440a9cb9d4f42406631004aa484cbb79214caAdam Cohen @Thunk long mLastTouchUpTime = -1; 118091440a9cb9d4f42406631004aa484cbb79214caAdam Cohen @Thunk int mDistanceSinceScroll = 0; 119a16fd5a6bd5371d40a5679261d416f06f8efa022Patrick Dubroy 120273c1022405bcc5e0840450b9195622e7476c9ddWinson Chung private int mTmpPoint[] = new int[2]; 121273c1022405bcc5e0840450b9195622e7476c9ddWinson Chung private Rect mDragLayerRect = new Rect(); 122273c1022405bcc5e0840450b9195622e7476c9ddWinson Chung 123043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung protected int mFlingToDeleteThresholdVelocity; 124043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung private VelocityTracker mVelocityTracker; 125043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung 12631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project /** 12731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * Interface to receive notifications when a drag starts or stops 12831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project */ 129fa401a10e7e9341daf6f3c5949bf9331902c26d0Sunny Goyal public interface DragListener { 13031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project /** 13131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * A drag has begun 13253b8d071ce63b2b55fa8bdc71488c44308bfcf2fMindy DelliCarpini * 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); 13953b8d071ce63b2b55fa8bdc71488c44308bfcf2fMindy DelliCarpini 14031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project /** 141e3193b93ad7bf33e2e45319084a99b9fc986622bWinson Chung * The drag has ended 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. 15031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project */ 1518dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen public DragController(Launcher launcher) { 1526e1bdaf4198f9eb7b4124550d3ad07da2a0226e4Winson Chung Resources r = launcher.getResources(); 1538dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen mLauncher = launcher; 15400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato mHandler = new Handler(); 1556e1bdaf4198f9eb7b4124550d3ad07da2a0226e4Winson Chung mScrollZone = r.getDimensionPixelSize(R.dimen.scroll_zone); 156043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung mVelocityTracker = VelocityTracker.obtain(); 157043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung 1586e1bdaf4198f9eb7b4124550d3ad07da2a0226e4Winson Chung float density = r.getDisplayMetrics().density; 1596e1bdaf4198f9eb7b4124550d3ad07da2a0226e4Winson Chung mFlingToDeleteThresholdVelocity = 1606e1bdaf4198f9eb7b4124550d3ad07da2a0226e4Winson Chung (int) (r.getInteger(R.integer.config_flingToDeleteMinVelocity) * density); 1617066003b2032a49ae5e59dab9b706259bdeb7e6eSunny Goyal mIsRtl = Utilities.isRtl(r); 16200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato } 16331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 1641262e369484ce7f2565655ed80e6299232c70bd7Patrick Dubroy public boolean dragging() { 1651262e369484ce7f2565655ed80e6299232c70bd7Patrick Dubroy return mDragging; 1661262e369484ce7f2565655ed80e6299232c70bd7Patrick Dubroy } 1671262e369484ce7f2565655ed80e6299232c70bd7Patrick Dubroy 16831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project /** 1695162ea9b1f41dbebe00fd9ec4d1e15a697971439Joe Onorato * Starts a drag. 170a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka * 17131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * @param v The view that is being dragged 172e3193b93ad7bf33e2e45319084a99b9fc986622bWinson Chung * @param bmp The bitmap that represents the view being dragged 173e3193b93ad7bf33e2e45319084a99b9fc986622bWinson Chung * @param source An object representing where the drag originated 174e3193b93ad7bf33e2e45319084a99b9fc986622bWinson Chung * @param dragInfo The data associated with the object that is being dragged 175e3193b93ad7bf33e2e45319084a99b9fc986622bWinson Chung * @param dragAction The drag action: either {@link #DRAG_ACTION_MOVE} or 176e3193b93ad7bf33e2e45319084a99b9fc986622bWinson Chung * {@link #DRAG_ACTION_COPY} 177f52abd7758b8f245522936e941336e574debabf5Sunny Goyal * @param viewImageBounds the position of the image inside the view 178e3193b93ad7bf33e2e45319084a99b9fc986622bWinson Chung * @param dragRegion Coordinates within the bitmap b for the position of item being dragged. 179e3193b93ad7bf33e2e45319084a99b9fc986622bWinson Chung * Makes dragging feel more precise, e.g. you can clip out a transparent border 180e3193b93ad7bf33e2e45319084a99b9fc986622bWinson Chung */ 181f52abd7758b8f245522936e941336e574debabf5Sunny Goyal public void startDrag(View v, Bitmap bmp, DragSource source, Object dragInfo, 182f52abd7758b8f245522936e941336e574debabf5Sunny Goyal Rect viewImageBounds, int dragAction, float initialDragViewScale) { 183e3193b93ad7bf33e2e45319084a99b9fc986622bWinson Chung int[] loc = mCoordinatesTemp; 1848dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen mLauncher.getDragLayer().getLocationInDragLayer(v, loc); 185f52abd7758b8f245522936e941336e574debabf5Sunny Goyal int dragLayerX = loc[0] + viewImageBounds.left 186f52abd7758b8f245522936e941336e574debabf5Sunny Goyal + (int) ((initialDragViewScale * bmp.getWidth() - bmp.getWidth()) / 2); 187f52abd7758b8f245522936e941336e574debabf5Sunny Goyal int dragLayerY = loc[1] + viewImageBounds.top 188f52abd7758b8f245522936e941336e574debabf5Sunny Goyal + (int) ((initialDragViewScale * bmp.getHeight() - bmp.getHeight()) / 2); 189e3193b93ad7bf33e2e45319084a99b9fc986622bWinson Chung 19005713af127d765cc28a8b2fd548a90347c90d6cbMichael Jurka startDrag(bmp, dragLayerX, dragLayerY, source, dragInfo, dragAction, null, 191c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen null, initialDragViewScale, false); 192e3193b93ad7bf33e2e45319084a99b9fc986622bWinson Chung 193e3193b93ad7bf33e2e45319084a99b9fc986622bWinson Chung if (dragAction == DRAG_ACTION_MOVE) { 194e3193b93ad7bf33e2e45319084a99b9fc986622bWinson Chung v.setVisibility(View.GONE); 195e3193b93ad7bf33e2e45319084a99b9fc986622bWinson Chung } 196e3193b93ad7bf33e2e45319084a99b9fc986622bWinson Chung } 197e3193b93ad7bf33e2e45319084a99b9fc986622bWinson Chung 198e3193b93ad7bf33e2e45319084a99b9fc986622bWinson Chung /** 199e3193b93ad7bf33e2e45319084a99b9fc986622bWinson Chung * Starts a drag. 200e3193b93ad7bf33e2e45319084a99b9fc986622bWinson Chung * 2015162ea9b1f41dbebe00fd9ec4d1e15a697971439Joe Onorato * @param b The bitmap to display as the drag image. It will be re-scaled to the 2025162ea9b1f41dbebe00fd9ec4d1e15a697971439Joe Onorato * enlarged size. 2038dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen * @param dragLayerX The x position in the DragLayer of the left-top of the bitmap. 2048dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen * @param dragLayerY The y position in the DragLayer of the left-top of the bitmap. 2055162ea9b1f41dbebe00fd9ec4d1e15a697971439Joe Onorato * @param source An object representing where the drag originated 206ea3763c2672f77539538af8cdd395ad97058eaabRomain Guy * @param dragInfo The data associated with the object that is being dragged 2075162ea9b1f41dbebe00fd9ec4d1e15a697971439Joe Onorato * @param dragAction The drag action: either {@link #DRAG_ACTION_MOVE} or 2085162ea9b1f41dbebe00fd9ec4d1e15a697971439Joe Onorato * {@link #DRAG_ACTION_COPY} 209a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka * @param dragRegion Coordinates within the bitmap b for the position of item being dragged. 210a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka * Makes dragging feel more precise, e.g. you can clip out a transparent border 211c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen * @param accessible whether this drag should occur in accessibility mode 212a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka */ 213eeb5bbc9409978cc2ae52d48380399fcde3d9f85Winson Chung public DragView startDrag(Bitmap b, int dragLayerX, int dragLayerY, 21472d598400da7cef9c7fc4f99bb1fcd7ff0710011Winson Chung DragSource source, Object dragInfo, int dragAction, Point dragOffset, Rect dragRegion, 215c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen float initialDragViewScale, boolean accessible) { 21600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato if (PROFILE_DRAWING_DURING_DRAG) { 21700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato android.os.Debug.startMethodTracing("Launcher"); 21800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato } 21900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato 22000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato // Hide soft keyboard, if visible 22100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato if (mInputMethodManager == null) { 22200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato mInputMethodManager = (InputMethodManager) 2238dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen mLauncher.getSystemService(Context.INPUT_METHOD_SERVICE); 22400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato } 22500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato mInputMethodManager.hideSoftInputFromWindow(mWindowToken, 0); 22600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato 2274ed6278e518cc6894cb150b606382e8e6a012599Patrick Dubroy for (DragListener listener : mListeners) { 2284ed6278e518cc6894cb150b606382e8e6a012599Patrick Dubroy listener.onDragStart(source, dragInfo, dragAction); 22900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato } 23000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato 2318dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen final int registrationX = mMotionDownX - dragLayerX; 2328dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen final int registrationY = mMotionDownY - dragLayerY; 23300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato 234a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka final int dragRegionLeft = dragRegion == null ? 0 : dragRegion.left; 235a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka final int dragRegionTop = dragRegion == null ? 0 : dragRegion.top; 236e3e27a854f3eca363d3c5ce353d19de475272d87Adam Cohen 23700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato mDragging = true; 238c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen mIsAccessibleDrag = accessible; 239cb3382b1bfe1a534b1b44f5c4def9b2db605ac90Adam Cohen 2409932a9b1e66fed4b5f38ce50f13d56331bbdcd7eAdam Cohen mDragObject = new DropTarget.DragObject(); 2419932a9b1e66fed4b5f38ce50f13d56331bbdcd7eAdam Cohen 242bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen mDragObject.dragComplete = false; 243c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen if (mIsAccessibleDrag) { 244c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen // For an accessible drag, we assume the view is being dragged from the center. 245c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen mDragObject.xOffset = b.getWidth() / 2; 246c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen mDragObject.yOffset = b.getHeight() / 2; 247c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen mDragObject.accessibleDrag = true; 248c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen } else { 249c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen mDragObject.xOffset = mMotionDownX - (dragLayerX + dragRegionLeft); 250c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen mDragObject.yOffset = mMotionDownY - (dragLayerY + dragRegionTop); 251c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen } 252c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen 253cb3382b1bfe1a534b1b44f5c4def9b2db605ac90Adam Cohen mDragObject.dragSource = source; 254cb3382b1bfe1a534b1b44f5c4def9b2db605ac90Adam Cohen mDragObject.dragInfo = dragInfo; 25500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato 2568dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen final DragView dragView = mDragObject.dragView = new DragView(mLauncher, b, registrationX, 25772d598400da7cef9c7fc4f99bb1fcd7ff0710011Winson Chung registrationY, 0, 0, b.getWidth(), b.getHeight(), initialDragViewScale); 258a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka 259b8c69f3c17a40adc2d85e8e996f754c383c293dcWinson Chung if (dragOffset != null) { 260b8c69f3c17a40adc2d85e8e996f754c383c293dcWinson Chung dragView.setDragVisualizeOffset(new Point(dragOffset)); 261b8c69f3c17a40adc2d85e8e996f754c383c293dcWinson Chung } 262a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka if (dragRegion != null) { 263e3e27a854f3eca363d3c5ce353d19de475272d87Adam Cohen dragView.setDragRegion(new Rect(dragRegion)); 264a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka } 265a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka 266780fe59a7af8b12fbdcd7f6841edaa7f2c2e019dWinson Chung mLauncher.getDragLayer().performHapticFeedback(HapticFeedbackConstants.LONG_PRESS); 2678dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen dragView.show(mMotionDownX, mMotionDownY); 2688dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen handleMoveEvent(mMotionDownX, mMotionDownY); 269eeb5bbc9409978cc2ae52d48380399fcde3d9f85Winson Chung return dragView; 27000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato } 27100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato 27200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato /** 27300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato * Draw the view into a bitmap. 27400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato */ 275120980bd00f5eecec5717f49a3d7db96571025a9Adam Cohen Bitmap getViewBitmap(View v) { 27600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato v.clearFocus(); 27700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato v.setPressed(false); 27800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato 27900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato boolean willNotCache = v.willNotCacheDrawing(); 28000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato v.setWillNotCacheDrawing(false); 28100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato 28200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato // Reset the drawing cache background color to fully transparent 28300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato // for the duration of this operation 28400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato int color = v.getDrawingCacheBackgroundColor(); 28500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato v.setDrawingCacheBackgroundColor(0); 286120980bd00f5eecec5717f49a3d7db96571025a9Adam Cohen float alpha = v.getAlpha(); 287120980bd00f5eecec5717f49a3d7db96571025a9Adam Cohen v.setAlpha(1.0f); 28800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato 28900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato if (color != 0) { 29000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato v.destroyDrawingCache(); 29100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato } 29200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato v.buildDrawingCache(); 29300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato Bitmap cacheBitmap = v.getDrawingCache(); 2943f8175a86e24b3568d1f5b12e1d3d5efcc57d691Daniel Sandler if (cacheBitmap == null) { 2953f8175a86e24b3568d1f5b12e1d3d5efcc57d691Daniel Sandler Log.e(TAG, "failed getViewBitmap(" + v + ")", new RuntimeException()); 2963f8175a86e24b3568d1f5b12e1d3d5efcc57d691Daniel Sandler return null; 2973f8175a86e24b3568d1f5b12e1d3d5efcc57d691Daniel Sandler } 29800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato 29900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato Bitmap bitmap = Bitmap.createBitmap(cacheBitmap); 30000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato 30100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato // Restore the view 30200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato v.destroyDrawingCache(); 303120980bd00f5eecec5717f49a3d7db96571025a9Adam Cohen v.setAlpha(alpha); 30400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato v.setWillNotCacheDrawing(willNotCache); 30500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato v.setDrawingCacheBackgroundColor(color); 30600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato 30700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato return bitmap; 30800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato } 30900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato 31000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato /** 31100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato * Call this from a drag source view like this: 31200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato * 31300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato * <pre> 31400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato * @Override 31500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato * public boolean dispatchKeyEvent(KeyEvent event) { 31600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato * return mDragController.dispatchKeyEvent(this, event) 31700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato * || super.dispatchKeyEvent(event); 31800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato * </pre> 31900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato */ 32000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato public boolean dispatchKeyEvent(KeyEvent event) { 32100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato return mDragging; 32200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato } 32300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato 324304dcde0e301c2f1a0b2bdc80ea8617930691b6eWinson Chung public boolean isDragging() { 325304dcde0e301c2f1a0b2bdc80ea8617930691b6eWinson Chung return mDragging; 326304dcde0e301c2f1a0b2bdc80ea8617930691b6eWinson Chung } 327304dcde0e301c2f1a0b2bdc80ea8617930691b6eWinson Chung 32824b6fd854f75f21700a330c2f0d11938e5dfeab6Joe Onorato /** 32924b6fd854f75f21700a330c2f0d11938e5dfeab6Joe Onorato * Stop dragging without dropping. 33024b6fd854f75f21700a330c2f0d11938e5dfeab6Joe Onorato */ 33124b6fd854f75f21700a330c2f0d11938e5dfeab6Joe Onorato public void cancelDrag() { 332621e6406fadba27d6cff1c38b31d5cdf99c0f97aWinson Chung if (mDragging) { 333c07918d0053fc7d2a19d7b013565a5d2e7d4af51Winson Chung if (mLastDropTarget != null) { 334c07918d0053fc7d2a19d7b013565a5d2e7d4af51Winson Chung mLastDropTarget.onDragExit(mDragObject); 335c07918d0053fc7d2a19d7b013565a5d2e7d4af51Winson Chung } 33641bb19d2775836e30ebf42f681b4617bc71600aaWinson Chung mDragObject.deferDragViewCleanupPostAnimation = false; 33736cc09b07b19198f4ea886583cef462ade27192cAdam Cohen mDragObject.cancelled = true; 338bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen mDragObject.dragComplete = true; 339a48487a814c07a9f1f45eb3ffe3d873b3dc31b3bWinson Chung mDragObject.dragSource.onDropCompleted(null, mDragObject, false, false); 340621e6406fadba27d6cff1c38b31d5cdf99c0f97aWinson Chung } 34124b6fd854f75f21700a330c2f0d11938e5dfeab6Joe Onorato endDrag(); 34224b6fd854f75f21700a330c2f0d11938e5dfeab6Joe Onorato } 3434390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal public void onAppsRemoved(final ArrayList<String> packageNames, HashSet<ComponentName> cns) { 344a182096cb20e0580dfca6661b2e5871c8886c834Winson Chung // Cancel the current drag if we are removing an app that we are dragging 345a182096cb20e0580dfca6661b2e5871c8886c834Winson Chung if (mDragObject != null) { 346a182096cb20e0580dfca6661b2e5871c8886c834Winson Chung Object rawDragInfo = mDragObject.dragInfo; 347a182096cb20e0580dfca6661b2e5871c8886c834Winson Chung if (rawDragInfo instanceof ShortcutInfo) { 348a182096cb20e0580dfca6661b2e5871c8886c834Winson Chung ShortcutInfo dragInfo = (ShortcutInfo) rawDragInfo; 3494390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal for (ComponentName componentName : cns) { 3507bcadad93f97e79d95ae879fe165de2e2371f613Michael Jurka // Added null checks to prevent NPE we've seen in the wild 3514390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal if (dragInfo != null && dragInfo.intent != null) { 352df95eb12a4d288ffa143a0c3db60e7e98f3e03b9Winson Chung ComponentName cn = dragInfo.intent.getComponent(); 3534390acea35aefae52bd3fe38f5fdbb7ea322afb0Sunny Goyal boolean isSameComponent = cn != null && (cn.equals(componentName) || 35460e1efe032821235c04376088494b44dfde4b62eAdam Cohen packageNames.contains(cn.getPackageName())); 35583892cc0768bd6d7f0827886e9e7a2eb3eed2b01Winson Chung if (isSameComponent) { 35611a4937fbff0dbc50fb022513dc3b6c643154445Winson Chung cancelDrag(); 35711a4937fbff0dbc50fb022513dc3b6c643154445Winson Chung return; 35811a4937fbff0dbc50fb022513dc3b6c643154445Winson Chung } 359a182096cb20e0580dfca6661b2e5871c8886c834Winson Chung } 360a182096cb20e0580dfca6661b2e5871c8886c834Winson Chung } 361a182096cb20e0580dfca6661b2e5871c8886c834Winson Chung } 362a182096cb20e0580dfca6661b2e5871c8886c834Winson Chung } 363a182096cb20e0580dfca6661b2e5871c8886c834Winson Chung } 36424b6fd854f75f21700a330c2f0d11938e5dfeab6Joe Onorato 36500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato private void endDrag() { 36600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato if (mDragging) { 36700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato mDragging = false; 368c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen mIsAccessibleDrag = false; 369aa15ffe60e28b923ebf3e3162ce427ca6feae803Winson Chung clearScrollRunnable(); 370043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung boolean isDeferred = false; 371cb3382b1bfe1a534b1b44f5c4def9b2db605ac90Adam Cohen if (mDragObject.dragView != null) { 372043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung isDeferred = mDragObject.deferDragViewCleanupPostAnimation; 373043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung if (!isDeferred) { 3747bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung mDragObject.dragView.remove(); 3757bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung } 376cb3382b1bfe1a534b1b44f5c4def9b2db605ac90Adam Cohen mDragObject.dragView = null; 37700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato } 378043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung 379043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung // Only end the drag if we are not deferred 380043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung if (!isDeferred) { 381f406615354a92367481a60966b6b873cae37fe4cSunny Goyal for (DragListener listener : new ArrayList<>(mListeners)) { 382043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung listener.onDragEnd(); 383043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung } 384043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung } 385043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung } 386043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung 387043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung releaseVelocityTracker(); 388043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung } 389043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung 390043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung /** 391043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung * This only gets called as a result of drag view cleanup being deferred in endDrag(); 392043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung */ 393043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung void onDeferredEndDrag(DragView dragView) { 394043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung dragView.remove(); 395043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung 3961e2f465f46ded990ea30516cdb7f0fcf3280411fMichael Jurka if (mDragObject.deferDragViewCleanupPostAnimation) { 3971e2f465f46ded990ea30516cdb7f0fcf3280411fMichael Jurka // If we skipped calling onDragEnd() before, do it now 398f406615354a92367481a60966b6b873cae37fe4cSunny Goyal for (DragListener listener : new ArrayList<>(mListeners)) { 3991e2f465f46ded990ea30516cdb7f0fcf3280411fMichael Jurka listener.onDragEnd(); 4001e2f465f46ded990ea30516cdb7f0fcf3280411fMichael Jurka } 40100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato } 40200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato } 40300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato 404fa401a10e7e9341daf6f3c5949bf9331902c26d0Sunny Goyal public void onDeferredEndFling(DropTarget.DragObject d) { 405a48487a814c07a9f1f45eb3ffe3d873b3dc31b3bWinson Chung d.dragSource.onFlingToDeleteCompleted(); 406a48487a814c07a9f1f45eb3ffe3d873b3dc31b3bWinson Chung } 407a48487a814c07a9f1f45eb3ffe3d873b3dc31b3bWinson Chung 40800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato /** 409273c1022405bcc5e0840450b9195622e7476c9ddWinson Chung * Clamps the position to the drag layer bounds. 410273c1022405bcc5e0840450b9195622e7476c9ddWinson Chung */ 411273c1022405bcc5e0840450b9195622e7476c9ddWinson Chung private int[] getClampedDragLayerPos(float x, float y) { 412273c1022405bcc5e0840450b9195622e7476c9ddWinson Chung mLauncher.getDragLayer().getLocalVisibleRect(mDragLayerRect); 413273c1022405bcc5e0840450b9195622e7476c9ddWinson Chung mTmpPoint[0] = (int) Math.max(mDragLayerRect.left, Math.min(x, mDragLayerRect.right - 1)); 414273c1022405bcc5e0840450b9195622e7476c9ddWinson Chung mTmpPoint[1] = (int) Math.max(mDragLayerRect.top, Math.min(y, mDragLayerRect.bottom - 1)); 415273c1022405bcc5e0840450b9195622e7476c9ddWinson Chung return mTmpPoint; 416273c1022405bcc5e0840450b9195622e7476c9ddWinson Chung } 417273c1022405bcc5e0840450b9195622e7476c9ddWinson Chung 418a2413751e3a698aef9c87411a639637883856939Winson Chung long getLastGestureUpTime() { 419a2413751e3a698aef9c87411a639637883856939Winson Chung if (mDragging) { 420a2413751e3a698aef9c87411a639637883856939Winson Chung return System.currentTimeMillis(); 421a2413751e3a698aef9c87411a639637883856939Winson Chung } else { 422a2413751e3a698aef9c87411a639637883856939Winson Chung return mLastTouchUpTime; 423a2413751e3a698aef9c87411a639637883856939Winson Chung } 424a2413751e3a698aef9c87411a639637883856939Winson Chung } 425a2413751e3a698aef9c87411a639637883856939Winson Chung 426a2413751e3a698aef9c87411a639637883856939Winson Chung void resetLastGestureUpTime() { 427a2413751e3a698aef9c87411a639637883856939Winson Chung mLastTouchUpTime = -1; 428a2413751e3a698aef9c87411a639637883856939Winson Chung } 429a2413751e3a698aef9c87411a639637883856939Winson Chung 430273c1022405bcc5e0840450b9195622e7476c9ddWinson Chung /** 43100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato * Call this from a drag source view. 43200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato */ 43300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato public boolean onInterceptTouchEvent(MotionEvent ev) { 4343a9fcedbcd235372cd2ab64f825a0b5b3937f59eMichael Jurka @SuppressWarnings("all") // suppress dead code warning 4353a9fcedbcd235372cd2ab64f825a0b5b3937f59eMichael Jurka final boolean debug = false; 4363a9fcedbcd235372cd2ab64f825a0b5b3937f59eMichael Jurka if (debug) { 437a30ce8e6b25e41f392a41fd4d0d3e0a424a84dadJoe Onorato Log.d(Launcher.TAG, "DragController.onInterceptTouchEvent " + ev + " mDragging=" 4389c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato + mDragging); 4399c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato } 44000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato 441c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen if (mIsAccessibleDrag) { 442c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen return false; 443c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen } 444c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen 445043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung // Update the velocity tracker 446043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung acquireVelocityTrackerAndAddMovement(ev); 447043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung 448043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung final int action = ev.getAction(); 449273c1022405bcc5e0840450b9195622e7476c9ddWinson Chung final int[] dragLayerPos = getClampedDragLayerPos(ev.getX(), ev.getY()); 450273c1022405bcc5e0840450b9195622e7476c9ddWinson Chung final int dragLayerX = dragLayerPos[0]; 451273c1022405bcc5e0840450b9195622e7476c9ddWinson Chung final int dragLayerY = dragLayerPos[1]; 45200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato 45300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato switch (action) { 45400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato case MotionEvent.ACTION_MOVE: 45500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato break; 45600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato case MotionEvent.ACTION_DOWN: 45700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato // Remember location of down touch 4588dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen mMotionDownX = dragLayerX; 4598dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen mMotionDownY = dragLayerY; 46000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato mLastDropTarget = null; 46100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato break; 46200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato case MotionEvent.ACTION_UP: 463a2413751e3a698aef9c87411a639637883856939Winson Chung mLastTouchUpTime = System.currentTimeMillis(); 46400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato if (mDragging) { 465043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung PointF vec = isFlingingToDelete(mDragObject.dragSource); 4661a70cef9884270f2f0a760f079a10fdfb1544c98Sunny Goyal if (!DeleteDropTarget.supportsDrop(mDragObject.dragInfo)) { 4677c4c5108295db764ba091cc0ffd7af335a166449Adam Cohen vec = null; 4687c4c5108295db764ba091cc0ffd7af335a166449Adam Cohen } 469043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung if (vec != null) { 470043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung dropOnFlingToDeleteTarget(dragLayerX, dragLayerY, vec); 471043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung } else { 472043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung drop(dragLayerX, dragLayerY); 473043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung } 47400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato } 47500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato endDrag(); 47600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato break; 477621e6406fadba27d6cff1c38b31d5cdf99c0f97aWinson Chung case MotionEvent.ACTION_CANCEL: 478621e6406fadba27d6cff1c38b31d5cdf99c0f97aWinson Chung cancelDrag(); 479621e6406fadba27d6cff1c38b31d5cdf99c0f97aWinson Chung break; 48000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato } 48100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato 48200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato return mDragging; 48300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato } 48400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato 48500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato /** 486ea3763c2672f77539538af8cdd395ad97058eaabRomain Guy * Sets the view that should handle move events. 487ea3763c2672f77539538af8cdd395ad97058eaabRomain Guy */ 488ea3763c2672f77539538af8cdd395ad97058eaabRomain Guy void setMoveTarget(View view) { 489ea3763c2672f77539538af8cdd395ad97058eaabRomain Guy mMoveTarget = view; 490ea3763c2672f77539538af8cdd395ad97058eaabRomain Guy } 491ea3763c2672f77539538af8cdd395ad97058eaabRomain Guy 492ea3763c2672f77539538af8cdd395ad97058eaabRomain Guy public boolean dispatchUnhandledMove(View focused, int direction) { 493ea3763c2672f77539538af8cdd395ad97058eaabRomain Guy return mMoveTarget != null && mMoveTarget.dispatchUnhandledMove(focused, direction); 494ea3763c2672f77539538af8cdd395ad97058eaabRomain Guy } 495ea3763c2672f77539538af8cdd395ad97058eaabRomain Guy 496aa15ffe60e28b923ebf3e3162ce427ca6feae803Winson Chung private void clearScrollRunnable() { 497aa15ffe60e28b923ebf3e3162ce427ca6feae803Winson Chung mHandler.removeCallbacks(mScrollRunnable); 498aa15ffe60e28b923ebf3e3162ce427ca6feae803Winson Chung if (mScrollState == SCROLL_WAITING_IN_ZONE) { 499aa15ffe60e28b923ebf3e3162ce427ca6feae803Winson Chung mScrollState = SCROLL_OUTSIDE_ZONE; 500aa15ffe60e28b923ebf3e3162ce427ca6feae803Winson Chung mScrollRunnable.setDirection(SCROLL_RIGHT); 501aa15ffe60e28b923ebf3e3162ce427ca6feae803Winson Chung mDragScroller.onExitScrollArea(); 502360e63fd3e77247002b86da2a77bd8dfe8c8a807Winson Chung mLauncher.getDragLayer().onExitScrollArea(); 503aa15ffe60e28b923ebf3e3162ce427ca6feae803Winson Chung } 504aa15ffe60e28b923ebf3e3162ce427ca6feae803Winson Chung } 505aa15ffe60e28b923ebf3e3162ce427ca6feae803Winson Chung 506de7658b5e02ae10010e44fcf8d9c5814f54d9eb0Patrick Dubroy private void handleMoveEvent(int x, int y) { 507cb3382b1bfe1a534b1b44f5c4def9b2db605ac90Adam Cohen mDragObject.dragView.move(x, y); 508de7658b5e02ae10010e44fcf8d9c5814f54d9eb0Patrick Dubroy 509de7658b5e02ae10010e44fcf8d9c5814f54d9eb0Patrick Dubroy // Drop on someone? 510de7658b5e02ae10010e44fcf8d9c5814f54d9eb0Patrick Dubroy final int[] coordinates = mCoordinatesTemp; 511de7658b5e02ae10010e44fcf8d9c5814f54d9eb0Patrick Dubroy DropTarget dropTarget = findDropTarget(x, y, coordinates); 512cb3382b1bfe1a534b1b44f5c4def9b2db605ac90Adam Cohen mDragObject.x = coordinates[0]; 513cb3382b1bfe1a534b1b44f5c4def9b2db605ac90Adam Cohen mDragObject.y = coordinates[1]; 51425460a1d5cb473033408c9e76898bb77e785c66fWinson Chung checkTouchMove(dropTarget); 51525460a1d5cb473033408c9e76898bb77e785c66fWinson Chung 51625460a1d5cb473033408c9e76898bb77e785c66fWinson Chung // Check if we are hovering over the scroll areas 517f7a29e83f06909b378dba39c83a522375682710aSunny Goyal mDistanceSinceScroll += Math.hypot(mLastTouch[0] - x, mLastTouch[1] - y); 51825460a1d5cb473033408c9e76898bb77e785c66fWinson Chung mLastTouch[0] = x; 51925460a1d5cb473033408c9e76898bb77e785c66fWinson Chung mLastTouch[1] = y; 52025460a1d5cb473033408c9e76898bb77e785c66fWinson Chung checkScrollState(x, y); 52125460a1d5cb473033408c9e76898bb77e785c66fWinson Chung } 52225460a1d5cb473033408c9e76898bb77e785c66fWinson Chung 52325460a1d5cb473033408c9e76898bb77e785c66fWinson Chung public void forceTouchMove() { 52425460a1d5cb473033408c9e76898bb77e785c66fWinson Chung int[] dummyCoordinates = mCoordinatesTemp; 52525460a1d5cb473033408c9e76898bb77e785c66fWinson Chung DropTarget dropTarget = findDropTarget(mLastTouch[0], mLastTouch[1], dummyCoordinates); 5264ef75f523c5b2bfed37bf1ed4bd2bcf8bda8b502Adam Cohen mDragObject.x = dummyCoordinates[0]; 5274ef75f523c5b2bfed37bf1ed4bd2bcf8bda8b502Adam Cohen mDragObject.y = dummyCoordinates[1]; 52825460a1d5cb473033408c9e76898bb77e785c66fWinson Chung checkTouchMove(dropTarget); 52925460a1d5cb473033408c9e76898bb77e785c66fWinson Chung } 53025460a1d5cb473033408c9e76898bb77e785c66fWinson Chung 53125460a1d5cb473033408c9e76898bb77e785c66fWinson Chung private void checkTouchMove(DropTarget dropTarget) { 532de7658b5e02ae10010e44fcf8d9c5814f54d9eb0Patrick Dubroy if (dropTarget != null) { 533de7658b5e02ae10010e44fcf8d9c5814f54d9eb0Patrick Dubroy if (mLastDropTarget != dropTarget) { 534de7658b5e02ae10010e44fcf8d9c5814f54d9eb0Patrick Dubroy if (mLastDropTarget != null) { 535cb3382b1bfe1a534b1b44f5c4def9b2db605ac90Adam Cohen mLastDropTarget.onDragExit(mDragObject); 536de7658b5e02ae10010e44fcf8d9c5814f54d9eb0Patrick Dubroy } 537cb3382b1bfe1a534b1b44f5c4def9b2db605ac90Adam Cohen dropTarget.onDragEnter(mDragObject); 538de7658b5e02ae10010e44fcf8d9c5814f54d9eb0Patrick Dubroy } 539cb3382b1bfe1a534b1b44f5c4def9b2db605ac90Adam Cohen dropTarget.onDragOver(mDragObject); 540de7658b5e02ae10010e44fcf8d9c5814f54d9eb0Patrick Dubroy } else { 541de7658b5e02ae10010e44fcf8d9c5814f54d9eb0Patrick Dubroy if (mLastDropTarget != null) { 542cb3382b1bfe1a534b1b44f5c4def9b2db605ac90Adam Cohen mLastDropTarget.onDragExit(mDragObject); 543de7658b5e02ae10010e44fcf8d9c5814f54d9eb0Patrick Dubroy } 544de7658b5e02ae10010e44fcf8d9c5814f54d9eb0Patrick Dubroy } 545de7658b5e02ae10010e44fcf8d9c5814f54d9eb0Patrick Dubroy mLastDropTarget = dropTarget; 54625460a1d5cb473033408c9e76898bb77e785c66fWinson Chung } 547de7658b5e02ae10010e44fcf8d9c5814f54d9eb0Patrick Dubroy 548091440a9cb9d4f42406631004aa484cbb79214caAdam Cohen @Thunk void checkScrollState(int x, int y) { 5498dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen final int slop = ViewConfiguration.get(mLauncher).getScaledWindowTouchSlop(); 550aa15ffe60e28b923ebf3e3162ce427ca6feae803Winson Chung final int delay = mDistanceSinceScroll < slop ? RESCROLL_DELAY : SCROLL_DELAY; 551fe1fe268b6d9ffd99218117795b3524a87e5110bWinson Chung final DragLayer dragLayer = mLauncher.getDragLayer(); 5527066003b2032a49ae5e59dab9b706259bdeb7e6eSunny Goyal final int forwardDirection = mIsRtl ? SCROLL_RIGHT : SCROLL_LEFT; 5537066003b2032a49ae5e59dab9b706259bdeb7e6eSunny Goyal final int backwardsDirection = mIsRtl ? SCROLL_LEFT : SCROLL_RIGHT; 554a16fd5a6bd5371d40a5679261d416f06f8efa022Patrick Dubroy 5553f4e1423804d64a38cb69e4511d7b80783564827Winson Chung if (x < mScrollZone) { 556aa15ffe60e28b923ebf3e3162ce427ca6feae803Winson Chung if (mScrollState == SCROLL_OUTSIDE_ZONE) { 557de7658b5e02ae10010e44fcf8d9c5814f54d9eb0Patrick Dubroy mScrollState = SCROLL_WAITING_IN_ZONE; 558fe1fe268b6d9ffd99218117795b3524a87e5110bWinson Chung if (mDragScroller.onEnterScrollArea(x, y, forwardDirection)) { 559fe1fe268b6d9ffd99218117795b3524a87e5110bWinson Chung dragLayer.onEnterScrollArea(forwardDirection); 560fe1fe268b6d9ffd99218117795b3524a87e5110bWinson Chung mScrollRunnable.setDirection(forwardDirection); 561aa15ffe60e28b923ebf3e3162ce427ca6feae803Winson Chung mHandler.postDelayed(mScrollRunnable, delay); 5623e0839e5f830ab7e64223ebe186d97729eda3e22Winson Chung } 563de7658b5e02ae10010e44fcf8d9c5814f54d9eb0Patrick Dubroy } 5643f4e1423804d64a38cb69e4511d7b80783564827Winson Chung } else if (x > mScrollView.getWidth() - mScrollZone) { 565aa15ffe60e28b923ebf3e3162ce427ca6feae803Winson Chung if (mScrollState == SCROLL_OUTSIDE_ZONE) { 566de7658b5e02ae10010e44fcf8d9c5814f54d9eb0Patrick Dubroy mScrollState = SCROLL_WAITING_IN_ZONE; 567fe1fe268b6d9ffd99218117795b3524a87e5110bWinson Chung if (mDragScroller.onEnterScrollArea(x, y, backwardsDirection)) { 568fe1fe268b6d9ffd99218117795b3524a87e5110bWinson Chung dragLayer.onEnterScrollArea(backwardsDirection); 569fe1fe268b6d9ffd99218117795b3524a87e5110bWinson Chung mScrollRunnable.setDirection(backwardsDirection); 570aa15ffe60e28b923ebf3e3162ce427ca6feae803Winson Chung mHandler.postDelayed(mScrollRunnable, delay); 5713e0839e5f830ab7e64223ebe186d97729eda3e22Winson Chung } 572de7658b5e02ae10010e44fcf8d9c5814f54d9eb0Patrick Dubroy } 573de7658b5e02ae10010e44fcf8d9c5814f54d9eb0Patrick Dubroy } else { 574aa15ffe60e28b923ebf3e3162ce427ca6feae803Winson Chung clearScrollRunnable(); 575de7658b5e02ae10010e44fcf8d9c5814f54d9eb0Patrick Dubroy } 576de7658b5e02ae10010e44fcf8d9c5814f54d9eb0Patrick Dubroy } 577de7658b5e02ae10010e44fcf8d9c5814f54d9eb0Patrick Dubroy 578ea3763c2672f77539538af8cdd395ad97058eaabRomain Guy /** 57900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato * Call this from a drag source view. 58000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato */ 58100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato public boolean onTouchEvent(MotionEvent ev) { 582c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen if (!mDragging || mIsAccessibleDrag) { 58300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato return false; 58400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato } 58500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato 586043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung // Update the velocity tracker 587043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung acquireVelocityTrackerAndAddMovement(ev); 588043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung 58900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato final int action = ev.getAction(); 590273c1022405bcc5e0840450b9195622e7476c9ddWinson Chung final int[] dragLayerPos = getClampedDragLayerPos(ev.getX(), ev.getY()); 591273c1022405bcc5e0840450b9195622e7476c9ddWinson Chung final int dragLayerX = dragLayerPos[0]; 592273c1022405bcc5e0840450b9195622e7476c9ddWinson Chung final int dragLayerY = dragLayerPos[1]; 59300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato 59400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato switch (action) { 59500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato case MotionEvent.ACTION_DOWN: 59600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato // Remember where the motion event started 5978dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen mMotionDownX = dragLayerX; 5988dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen mMotionDownY = dragLayerY; 59900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato 6008dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen if ((dragLayerX < mScrollZone) || (dragLayerX > mScrollView.getWidth() - mScrollZone)) { 60100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato mScrollState = SCROLL_WAITING_IN_ZONE; 60200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato mHandler.postDelayed(mScrollRunnable, SCROLL_DELAY); 60300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato } else { 60400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato mScrollState = SCROLL_OUTSIDE_ZONE; 60500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato } 60653b8d071ce63b2b55fa8bdc71488c44308bfcf2fMindy DelliCarpini handleMoveEvent(dragLayerX, dragLayerY); 60700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato break; 60800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato case MotionEvent.ACTION_MOVE: 6098dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen handleMoveEvent(dragLayerX, dragLayerY); 61000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato break; 61100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato case MotionEvent.ACTION_UP: 612b0a6bbeeab0960419dcd1f695c209ca0ec36ab8aPatrick Dubroy // Ensure that we've processed a move event at the current pointer location. 6138dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen handleMoveEvent(dragLayerX, dragLayerY); 6143bc21c35fa167ac233e19df0c9a01b0a07173ed8Winson Chung mHandler.removeCallbacks(mScrollRunnable); 615043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung 61600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato if (mDragging) { 617043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung PointF vec = isFlingingToDelete(mDragObject.dragSource); 6181a70cef9884270f2f0a760f079a10fdfb1544c98Sunny Goyal if (!DeleteDropTarget.supportsDrop(mDragObject.dragInfo)) { 619947dc5431981e40ffc8d687604f7777d35915034Adam Cohen vec = null; 620947dc5431981e40ffc8d687604f7777d35915034Adam Cohen } 621043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung if (vec != null) { 622043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung dropOnFlingToDeleteTarget(dragLayerX, dragLayerY, vec); 623043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung } else { 624043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung drop(dragLayerX, dragLayerY); 625043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung } 62600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato } 62700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato endDrag(); 62800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato break; 62900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato case MotionEvent.ACTION_CANCEL: 6303bc21c35fa167ac233e19df0c9a01b0a07173ed8Winson Chung mHandler.removeCallbacks(mScrollRunnable); 63124b6fd854f75f21700a330c2f0d11938e5dfeab6Joe Onorato cancelDrag(); 632621e6406fadba27d6cff1c38b31d5cdf99c0f97aWinson Chung break; 63300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato } 63400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato 63500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato return true; 63600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato } 63700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato 638043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung /** 639c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen * Since accessible drag and drop won't cause the same sequence of touch events, we manually 640c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen * inject the appropriate state. 641c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen */ 642c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen public void prepareAccessibleDrag(int x, int y) { 643c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen mMotionDownX = x; 644c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen mMotionDownY = y; 645c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen mLastDropTarget = null; 646c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen } 647c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen 648c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen /** 649c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen * As above, since accessible drag and drop won't cause the same sequence of touch events, 650c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen * we manually ensure appropriate drag and drop events get emulated for accessible drag. 651c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen */ 652c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen public void completeAccessibleDrag(int[] location) { 653c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen final int[] coordinates = mCoordinatesTemp; 654c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen 655c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen // We make sure that we prime the target for drop. 656c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen DropTarget dropTarget = findDropTarget(location[0], location[1], coordinates); 657c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen mDragObject.x = coordinates[0]; 658c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen mDragObject.y = coordinates[1]; 659c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen checkTouchMove(dropTarget); 660c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen 661e9b651eef1b9f3647eba94f833bff3fc52f5956bSunny Goyal dropTarget.prepareAccessibilityDrop(); 662c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen // Perform the drop 663c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen drop(location[0], location[1]); 664c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen endDrag(); 665c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen } 666c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen 667c9735cff2e558aa3f3810e49c15ef13049b9429cAdam Cohen /** 668043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung * Determines whether the user flung the current item to delete it. 669043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung * 670043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung * @return the vector at which the item was flung, or null if no fling was detected. 671043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung */ 672043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung private PointF isFlingingToDelete(DragSource source) { 673043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung if (mFlingToDeleteDropTarget == null) return null; 674043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung if (!source.supportsFlingToDelete()) return null; 675043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung 676043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung ViewConfiguration config = ViewConfiguration.get(mLauncher); 677043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung mVelocityTracker.computeCurrentVelocity(1000, config.getScaledMaximumFlingVelocity()); 678043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung 679043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung if (mVelocityTracker.getYVelocity() < mFlingToDeleteThresholdVelocity) { 680043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung // Do a quick dot product test to ensure that we are flinging upwards 681043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung PointF vel = new PointF(mVelocityTracker.getXVelocity(), 682043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung mVelocityTracker.getYVelocity()); 683043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung PointF upVec = new PointF(0f, -1f); 684043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung float theta = (float) Math.acos(((vel.x * upVec.x) + (vel.y * upVec.y)) / 685043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung (vel.length() * upVec.length())); 686043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung if (theta <= Math.toRadians(MAX_FLING_DEGREES)) { 687043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung return vel; 688043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung } 689043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung } 690043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung return null; 691043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung } 692043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung 693043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung private void dropOnFlingToDeleteTarget(float x, float y, PointF vel) { 694043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung final int[] coordinates = mCoordinatesTemp; 695043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung 696043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung mDragObject.x = coordinates[0]; 697043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung mDragObject.y = coordinates[1]; 698043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung 699043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung // Clean up dragging on the target if it's not the current fling delete target otherwise, 700043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung // start dragging to it. 701043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung if (mLastDropTarget != null && mFlingToDeleteDropTarget != mLastDropTarget) { 702043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung mLastDropTarget.onDragExit(mDragObject); 703043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung } 704043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung 705043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung // Drop onto the fling-to-delete target 706043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung boolean accepted = false; 707043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung mFlingToDeleteDropTarget.onDragEnter(mDragObject); 708232decb008661d82ed2ca6d5f3080ee5a50d3be1Winson Chung // We must set dragComplete to true _only_ after we "enter" the fling-to-delete target for 709232decb008661d82ed2ca6d5f3080ee5a50d3be1Winson Chung // "drop" 710232decb008661d82ed2ca6d5f3080ee5a50d3be1Winson Chung mDragObject.dragComplete = true; 711043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung mFlingToDeleteDropTarget.onDragExit(mDragObject); 712043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung if (mFlingToDeleteDropTarget.acceptDrop(mDragObject)) { 713ddec73471eb6cc1f15eb9421a205bb2362509075Sunny Goyal mFlingToDeleteDropTarget.onFlingToDelete(mDragObject, vel); 714043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung accepted = true; 715043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung } 716a48487a814c07a9f1f45eb3ffe3d873b3dc31b3bWinson Chung mDragObject.dragSource.onDropCompleted((View) mFlingToDeleteDropTarget, mDragObject, true, 717043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung accepted); 718043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung } 719043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung 720b0a6bbeeab0960419dcd1f695c209ca0ec36ab8aPatrick Dubroy private void drop(float x, float y) { 72100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato final int[] coordinates = mCoordinatesTemp; 722b0a6bbeeab0960419dcd1f695c209ca0ec36ab8aPatrick Dubroy final DropTarget dropTarget = findDropTarget((int) x, (int) y, coordinates); 72300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato 724cb3382b1bfe1a534b1b44f5c4def9b2db605ac90Adam Cohen mDragObject.x = coordinates[0]; 725cb3382b1bfe1a534b1b44f5c4def9b2db605ac90Adam Cohen mDragObject.y = coordinates[1]; 726b0a6bbeeab0960419dcd1f695c209ca0ec36ab8aPatrick Dubroy boolean accepted = false; 72700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato if (dropTarget != null) { 728bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen mDragObject.dragComplete = true; 729cb3382b1bfe1a534b1b44f5c4def9b2db605ac90Adam Cohen dropTarget.onDragExit(mDragObject); 730cb3382b1bfe1a534b1b44f5c4def9b2db605ac90Adam Cohen if (dropTarget.acceptDrop(mDragObject)) { 731cb3382b1bfe1a534b1b44f5c4def9b2db605ac90Adam Cohen dropTarget.onDrop(mDragObject); 732b0a6bbeeab0960419dcd1f695c209ca0ec36ab8aPatrick Dubroy accepted = true; 73300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato } 73400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato } 735a48487a814c07a9f1f45eb3ffe3d873b3dc31b3bWinson Chung mDragObject.dragSource.onDropCompleted((View) dropTarget, mDragObject, false, accepted); 73600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato } 73700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato 73800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato private DropTarget findDropTarget(int x, int y, int[] dropCoordinates) { 73900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato final Rect r = mRectTemp; 74000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato 74100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato final ArrayList<DropTarget> dropTargets = mDropTargets; 74200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato final int count = dropTargets.size(); 74300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato for (int i=count-1; i>=0; i--) { 744440c360bc395c43683fa9ca226e59f9e35f9e926Patrick Dubroy DropTarget target = dropTargets.get(i); 7450280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka if (!target.isDropEnabled()) 7460280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka continue; 7470280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka 7487d30a37007bac318db1c9af47a9af12d348042a5Adam Cohen target.getHitRectRelativeToDragLayer(r); 749440c360bc395c43683fa9ca226e59f9e35f9e926Patrick Dubroy 750cb3382b1bfe1a534b1b44f5c4def9b2db605ac90Adam Cohen mDragObject.x = x; 751cb3382b1bfe1a534b1b44f5c4def9b2db605ac90Adam Cohen mDragObject.y = y; 75200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato if (r.contains(x, y)) { 753440c360bc395c43683fa9ca226e59f9e35f9e926Patrick Dubroy 7547d30a37007bac318db1c9af47a9af12d348042a5Adam Cohen dropCoordinates[0] = x; 7557d30a37007bac318db1c9af47a9af12d348042a5Adam Cohen dropCoordinates[1] = y; 7567d30a37007bac318db1c9af47a9af12d348042a5Adam Cohen mLauncher.getDragLayer().mapCoordInSelfToDescendent((View) target, dropCoordinates); 757440c360bc395c43683fa9ca226e59f9e35f9e926Patrick Dubroy 75800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato return target; 75900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato } 76000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato } 76100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato return null; 76200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato } 76300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato 76400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato public void setDragScoller(DragScroller scroller) { 76500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato mDragScroller = scroller; 76600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato } 76700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato 76800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato public void setWindowToken(IBinder token) { 76900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato mWindowToken = token; 77000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato } 77100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato 77231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project /** 77331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * Sets the drag listner which will be notified when a drag starts or ends. 77431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project */ 7754ed6278e518cc6894cb150b606382e8e6a012599Patrick Dubroy public void addDragListener(DragListener l) { 7764ed6278e518cc6894cb150b606382e8e6a012599Patrick Dubroy mListeners.add(l); 77700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato } 77800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato 77931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project /** 78031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * Remove a previously installed drag listener. 78131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project */ 78200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato public void removeDragListener(DragListener l) { 7834ed6278e518cc6894cb150b606382e8e6a012599Patrick Dubroy mListeners.remove(l); 78400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato } 78500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato 78600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato /** 78700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato * Add a DropTarget to the list of potential places to receive drop events. 78800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato */ 78900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato public void addDropTarget(DropTarget target) { 79000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato mDropTargets.add(target); 79100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato } 79200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato 79300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato /** 79400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato * Don't send drop events to <em>target</em> any more. 79500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato */ 79600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato public void removeDropTarget(DropTarget target) { 79700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato mDropTargets.remove(target); 79800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato } 79900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato 80000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato /** 801043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung * Sets the current fling-to-delete drop target. 802043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung */ 803043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung public void setFlingToDeleteDropTarget(DropTarget target) { 804043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung mFlingToDeleteDropTarget = target; 805043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung } 806043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung 807043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung private void acquireVelocityTrackerAndAddMovement(MotionEvent ev) { 808043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung if (mVelocityTracker == null) { 809043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung mVelocityTracker = VelocityTracker.obtain(); 810043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung } 811043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung mVelocityTracker.addMovement(ev); 812043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung } 813043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung 814043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung private void releaseVelocityTracker() { 815043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung if (mVelocityTracker != null) { 816043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung mVelocityTracker.recycle(); 817043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung mVelocityTracker = null; 818043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung } 819043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung } 820043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung 821043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung /** 82200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato * Set which view scrolls for touch events near the edge of the screen. 82300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato */ 82400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato public void setScrollView(View v) { 82500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato mScrollView = v; 82600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato } 82700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato 8285f445425606b2c27276a79e9e871cf7f67b1b719Patrick Dubroy DragView getDragView() { 829cb3382b1bfe1a534b1b44f5c4def9b2db605ac90Adam Cohen return mDragObject.dragView; 8305f445425606b2c27276a79e9e871cf7f67b1b719Patrick Dubroy } 8315f445425606b2c27276a79e9e871cf7f67b1b719Patrick Dubroy 83200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato private class ScrollRunnable implements Runnable { 83300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato private int mDirection; 83400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato 83500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato ScrollRunnable() { 83600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato } 83700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato 83800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato public void run() { 83900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato if (mDragScroller != null) { 84000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato if (mDirection == SCROLL_LEFT) { 84100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato mDragScroller.scrollLeft(); 84200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato } else { 84300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato mDragScroller.scrollRight(); 84400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato } 84500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato mScrollState = SCROLL_OUTSIDE_ZONE; 846a16fd5a6bd5371d40a5679261d416f06f8efa022Patrick Dubroy mDistanceSinceScroll = 0; 847a16fd5a6bd5371d40a5679261d416f06f8efa022Patrick Dubroy mDragScroller.onExitScrollArea(); 848360e63fd3e77247002b86da2a77bd8dfe8c8a807Winson Chung mLauncher.getDragLayer().onExitScrollArea(); 849aa15ffe60e28b923ebf3e3162ce427ca6feae803Winson Chung 850aa15ffe60e28b923ebf3e3162ce427ca6feae803Winson Chung if (isDragging()) { 85125460a1d5cb473033408c9e76898bb77e785c66fWinson Chung // Check the scroll again so that we can requeue the scroller if necessary 85225460a1d5cb473033408c9e76898bb77e785c66fWinson Chung checkScrollState(mLastTouch[0], mLastTouch[1]); 853aa15ffe60e28b923ebf3e3162ce427ca6feae803Winson Chung } 85400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato } 85500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato } 85600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato 85700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato void setDirection(int direction) { 85800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato mDirection = direction; 85900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato } 86000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato } 86131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project} 862