1be7607af8875236b9cf7bdb5f5aa089c207529afWinson/* 2be7607af8875236b9cf7bdb5f5aa089c207529afWinson * Copyright (C) 2014 The Android Open Source Project 3be7607af8875236b9cf7bdb5f5aa089c207529afWinson * 4be7607af8875236b9cf7bdb5f5aa089c207529afWinson * Licensed under the Apache License, Version 2.0 (the "License"); 5be7607af8875236b9cf7bdb5f5aa089c207529afWinson * you may not use this file except in compliance with the License. 6be7607af8875236b9cf7bdb5f5aa089c207529afWinson * You may obtain a copy of the License at 7be7607af8875236b9cf7bdb5f5aa089c207529afWinson * 8be7607af8875236b9cf7bdb5f5aa089c207529afWinson * http://www.apache.org/licenses/LICENSE-2.0 9be7607af8875236b9cf7bdb5f5aa089c207529afWinson * 10be7607af8875236b9cf7bdb5f5aa089c207529afWinson * Unless required by applicable law or agreed to in writing, software 11be7607af8875236b9cf7bdb5f5aa089c207529afWinson * distributed under the License is distributed on an "AS IS" BASIS, 12be7607af8875236b9cf7bdb5f5aa089c207529afWinson * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13be7607af8875236b9cf7bdb5f5aa089c207529afWinson * See the License for the specific language governing permissions and 14be7607af8875236b9cf7bdb5f5aa089c207529afWinson * limitations under the License. 15be7607af8875236b9cf7bdb5f5aa089c207529afWinson */ 16be7607af8875236b9cf7bdb5f5aa089c207529afWinson 17be7607af8875236b9cf7bdb5f5aa089c207529afWinsonpackage com.android.systemui.recents.views; 18be7607af8875236b9cf7bdb5f5aa089c207529afWinson 19c694a509ff768b6a942616676dd8103e20d06e66Winsonimport android.app.ActivityManager; 20be7607af8875236b9cf7bdb5f5aa089c207529afWinsonimport android.graphics.Point; 2119cf2972582198484816ac15ba83a4f46946082bJorim Jaggiimport android.graphics.Rect; 22131d53a7d817560ad06b5f26dc64a2969aeed53fWinsonimport android.view.InputDevice; 23be7607af8875236b9cf7bdb5f5aa089c207529afWinsonimport android.view.MotionEvent; 24131d53a7d817560ad06b5f26dc64a2969aeed53fWinsonimport android.view.PointerIcon; 259e177f05ea9a92a23ca72d9990f8a8bd7ada5f5aMatthew Ngimport android.view.View; 263e8747414520ee348cf4b9c4a6afd9ff80b5a8f8Winsonimport android.view.ViewConfiguration; 27231bc9c54a48921f9c6a1ae187969c9bfe9d121fWinsonimport android.view.ViewDebug; 28c0d7058b14c24cd07912f5629c26b39b7b4673d5Winson 2919cf2972582198484816ac15ba83a4f46946082bJorim Jaggiimport com.android.internal.policy.DividerSnapAlgorithm; 3053ec42cb17693b2d631746e1e5d31021a3359163Winsonimport com.android.systemui.recents.Recents; 31be7607af8875236b9cf7bdb5f5aa089c207529afWinsonimport com.android.systemui.recents.events.EventBus; 3219cf2972582198484816ac15ba83a4f46946082bJorim Jaggiimport com.android.systemui.recents.events.activity.ConfigurationChangedEvent; 333975de5f8347b3ef1d64a038f3d50dd065618367Matthew Ngimport com.android.systemui.recents.events.activity.HideRecentsEvent; 349e177f05ea9a92a23ca72d9990f8a8bd7ada5f5aMatthew Ngimport com.android.systemui.recents.events.ui.DismissAllTaskViewsEvent; 359b001396c26e5b5ee95e0a54213a8a421179e365Winsonimport com.android.systemui.recents.events.ui.HideIncompatibleAppOverlayEvent; 369b001396c26e5b5ee95e0a54213a8a421179e365Winsonimport com.android.systemui.recents.events.ui.ShowIncompatibleAppOverlayEvent; 37eca4ab6e99bcb2a7b31b8b4b1c3b5474297b6b25Winsonimport com.android.systemui.recents.events.ui.dragndrop.DragDropTargetChangedEvent; 38be7607af8875236b9cf7bdb5f5aa089c207529afWinsonimport com.android.systemui.recents.events.ui.dragndrop.DragEndEvent; 39be7607af8875236b9cf7bdb5f5aa089c207529afWinsonimport com.android.systemui.recents.events.ui.dragndrop.DragStartEvent; 40eca4ab6e99bcb2a7b31b8b4b1c3b5474297b6b25Winsonimport com.android.systemui.recents.events.ui.dragndrop.DragStartInitializeDropTargetsEvent; 41d759a7123a7cacf431399b310421c59a6c818e53Winsonimport com.android.systemui.recents.misc.SystemServicesProxy; 426519c1b0fe85c5f25115539e936e4333e8537098Winson Chungimport com.android.systemui.shared.recents.model.Task; 43be7607af8875236b9cf7bdb5f5aa089c207529afWinson 44eca4ab6e99bcb2a7b31b8b4b1c3b5474297b6b25Winsonimport java.util.ArrayList; 45eca4ab6e99bcb2a7b31b8b4b1c3b5474297b6b25Winson 46be7607af8875236b9cf7bdb5f5aa089c207529afWinson/** 47be7607af8875236b9cf7bdb5f5aa089c207529afWinson * Handles touch events for a RecentsView. 48be7607af8875236b9cf7bdb5f5aa089c207529afWinson */ 49eca4ab6e99bcb2a7b31b8b4b1c3b5474297b6b25Winsonpublic class RecentsViewTouchHandler { 50eca4ab6e99bcb2a7b31b8b4b1c3b5474297b6b25Winson 51be7607af8875236b9cf7bdb5f5aa089c207529afWinson private RecentsView mRv; 52be7607af8875236b9cf7bdb5f5aa089c207529afWinson 53231bc9c54a48921f9c6a1ae187969c9bfe9d121fWinson @ViewDebug.ExportedProperty(deepExport=true, prefix="drag_task") 54be7607af8875236b9cf7bdb5f5aa089c207529afWinson private Task mDragTask; 55231bc9c54a48921f9c6a1ae187969c9bfe9d121fWinson @ViewDebug.ExportedProperty(deepExport=true, prefix="drag_task_view_") 56be7607af8875236b9cf7bdb5f5aa089c207529afWinson private TaskView mTaskView; 57be7607af8875236b9cf7bdb5f5aa089c207529afWinson 58231bc9c54a48921f9c6a1ae187969c9bfe9d121fWinson @ViewDebug.ExportedProperty(category="recents") 59479f7446cf489fb99c91b3fc2bf96b1dc184f5baWinson private Point mTaskViewOffset = new Point(); 60231bc9c54a48921f9c6a1ae187969c9bfe9d121fWinson @ViewDebug.ExportedProperty(category="recents") 61be7607af8875236b9cf7bdb5f5aa089c207529afWinson private Point mDownPos = new Point(); 62231bc9c54a48921f9c6a1ae187969c9bfe9d121fWinson @ViewDebug.ExportedProperty(category="recents") 633e8747414520ee348cf4b9c4a6afd9ff80b5a8f8Winson private boolean mDragRequested; 64231bc9c54a48921f9c6a1ae187969c9bfe9d121fWinson @ViewDebug.ExportedProperty(category="recents") 653e8747414520ee348cf4b9c4a6afd9ff80b5a8f8Winson private boolean mIsDragging; 663e8747414520ee348cf4b9c4a6afd9ff80b5a8f8Winson private float mDragSlop; 67131d53a7d817560ad06b5f26dc64a2969aeed53fWinson private int mDeviceId = -1; 68eca4ab6e99bcb2a7b31b8b4b1c3b5474297b6b25Winson 69eca4ab6e99bcb2a7b31b8b4b1c3b5474297b6b25Winson private DropTarget mLastDropTarget; 7019cf2972582198484816ac15ba83a4f46946082bJorim Jaggi private DividerSnapAlgorithm mDividerSnapAlgorithm; 71eca4ab6e99bcb2a7b31b8b4b1c3b5474297b6b25Winson private ArrayList<DropTarget> mDropTargets = new ArrayList<>(); 726519c1b0fe85c5f25115539e936e4333e8537098Winson Chung private ArrayList<DockState> mVisibleDockStates = new ArrayList<>(); 73be7607af8875236b9cf7bdb5f5aa089c207529afWinson 74be7607af8875236b9cf7bdb5f5aa089c207529afWinson public RecentsViewTouchHandler(RecentsView rv) { 75be7607af8875236b9cf7bdb5f5aa089c207529afWinson mRv = rv; 763e8747414520ee348cf4b9c4a6afd9ff80b5a8f8Winson mDragSlop = ViewConfiguration.get(rv.getContext()).getScaledTouchSlop(); 7719cf2972582198484816ac15ba83a4f46946082bJorim Jaggi updateSnapAlgorithm(); 7819cf2972582198484816ac15ba83a4f46946082bJorim Jaggi } 7919cf2972582198484816ac15ba83a4f46946082bJorim Jaggi 8019cf2972582198484816ac15ba83a4f46946082bJorim Jaggi private void updateSnapAlgorithm() { 8119cf2972582198484816ac15ba83a4f46946082bJorim Jaggi Rect insets = new Rect(); 8219cf2972582198484816ac15ba83a4f46946082bJorim Jaggi SystemServicesProxy.getInstance(mRv.getContext()).getStableInsets(insets); 8319cf2972582198484816ac15ba83a4f46946082bJorim Jaggi mDividerSnapAlgorithm = DividerSnapAlgorithm.create(mRv.getContext(), insets); 84be7607af8875236b9cf7bdb5f5aa089c207529afWinson } 85be7607af8875236b9cf7bdb5f5aa089c207529afWinson 86882072baacaee4ecd43f0209b691a9af746462f2Winson /** 87eca4ab6e99bcb2a7b31b8b4b1c3b5474297b6b25Winson * Registers a new drop target for the current drag only. 88eca4ab6e99bcb2a7b31b8b4b1c3b5474297b6b25Winson */ 89eca4ab6e99bcb2a7b31b8b4b1c3b5474297b6b25Winson public void registerDropTargetForCurrentDrag(DropTarget target) { 90eca4ab6e99bcb2a7b31b8b4b1c3b5474297b6b25Winson mDropTargets.add(target); 91eca4ab6e99bcb2a7b31b8b4b1c3b5474297b6b25Winson } 92eca4ab6e99bcb2a7b31b8b4b1c3b5474297b6b25Winson 93eca4ab6e99bcb2a7b31b8b4b1c3b5474297b6b25Winson /** 94036693cf71f8c4d2dd0dfb57ad05e8827ed6df60Winson * Returns the set of visible dock states for this current drag. 95036693cf71f8c4d2dd0dfb57ad05e8827ed6df60Winson */ 966519c1b0fe85c5f25115539e936e4333e8537098Winson Chung public ArrayList<DockState> getVisibleDockStates() { 97036693cf71f8c4d2dd0dfb57ad05e8827ed6df60Winson return mVisibleDockStates; 98036693cf71f8c4d2dd0dfb57ad05e8827ed6df60Winson } 99036693cf71f8c4d2dd0dfb57ad05e8827ed6df60Winson 100be7607af8875236b9cf7bdb5f5aa089c207529afWinson /** Touch preprocessing for handling below */ 101be7607af8875236b9cf7bdb5f5aa089c207529afWinson public boolean onInterceptTouchEvent(MotionEvent ev) { 1029e177f05ea9a92a23ca72d9990f8a8bd7ada5f5aMatthew Ng return handleTouchEvent(ev) || mDragRequested; 103be7607af8875236b9cf7bdb5f5aa089c207529afWinson } 104be7607af8875236b9cf7bdb5f5aa089c207529afWinson 105be7607af8875236b9cf7bdb5f5aa089c207529afWinson /** Handles touch events once we have intercepted them */ 106be7607af8875236b9cf7bdb5f5aa089c207529afWinson public boolean onTouchEvent(MotionEvent ev) { 1074165d336b6cd69715eda7fbdfd272a878097170eWinson handleTouchEvent(ev); 1082cf6ad832d7be4e86765a2326498b50560af07dfWinson Chung if (ev.getAction() == MotionEvent.ACTION_UP && mRv.getStack().getTaskCount() == 0) { 1093975de5f8347b3ef1d64a038f3d50dd065618367Matthew Ng EventBus.getDefault().send(new HideRecentsEvent(false, true)); 1103975de5f8347b3ef1d64a038f3d50dd065618367Matthew Ng } 1113975de5f8347b3ef1d64a038f3d50dd065618367Matthew Ng return true; 1124165d336b6cd69715eda7fbdfd272a878097170eWinson } 1134165d336b6cd69715eda7fbdfd272a878097170eWinson 1144165d336b6cd69715eda7fbdfd272a878097170eWinson /**** Events ****/ 1154165d336b6cd69715eda7fbdfd272a878097170eWinson 1164165d336b6cd69715eda7fbdfd272a878097170eWinson public final void onBusEvent(DragStartEvent event) { 117d759a7123a7cacf431399b310421c59a6c818e53Winson SystemServicesProxy ssp = Recents.getSystemServices(); 1184165d336b6cd69715eda7fbdfd272a878097170eWinson mRv.getParent().requestDisallowInterceptTouchEvent(true); 1193e8747414520ee348cf4b9c4a6afd9ff80b5a8f8Winson mDragRequested = true; 1203e8747414520ee348cf4b9c4a6afd9ff80b5a8f8Winson // We defer starting the actual drag handling until the user moves past the drag slop 1213e8747414520ee348cf4b9c4a6afd9ff80b5a8f8Winson mIsDragging = false; 1224165d336b6cd69715eda7fbdfd272a878097170eWinson mDragTask = event.task; 1234165d336b6cd69715eda7fbdfd272a878097170eWinson mTaskView = event.taskView; 124eca4ab6e99bcb2a7b31b8b4b1c3b5474297b6b25Winson mDropTargets.clear(); 1254165d336b6cd69715eda7fbdfd272a878097170eWinson 126479f7446cf489fb99c91b3fc2bf96b1dc184f5baWinson int[] recentsViewLocation = new int[2]; 127479f7446cf489fb99c91b3fc2bf96b1dc184f5baWinson mRv.getLocationInWindow(recentsViewLocation); 128479f7446cf489fb99c91b3fc2bf96b1dc184f5baWinson mTaskViewOffset.set(mTaskView.getLeft() - recentsViewLocation[0] + event.tlOffset.x, 129479f7446cf489fb99c91b3fc2bf96b1dc184f5baWinson mTaskView.getTop() - recentsViewLocation[1] + event.tlOffset.y); 130b7035f3a4738efdf40dc0ad06f19303ffcd784f7Matthew Ng 131b7035f3a4738efdf40dc0ad06f19303ffcd784f7Matthew Ng // Change space coordinates relative to the view to RecentsView when user initiates a touch 132b7035f3a4738efdf40dc0ad06f19303ffcd784f7Matthew Ng if (event.isUserTouchInitiated) { 133b7035f3a4738efdf40dc0ad06f19303ffcd784f7Matthew Ng float x = mDownPos.x - mTaskViewOffset.x; 134b7035f3a4738efdf40dc0ad06f19303ffcd784f7Matthew Ng float y = mDownPos.y - mTaskViewOffset.y; 135b7035f3a4738efdf40dc0ad06f19303ffcd784f7Matthew Ng mTaskView.setTranslationX(x); 136b7035f3a4738efdf40dc0ad06f19303ffcd784f7Matthew Ng mTaskView.setTranslationY(y); 137b7035f3a4738efdf40dc0ad06f19303ffcd784f7Matthew Ng } 138eca4ab6e99bcb2a7b31b8b4b1c3b5474297b6b25Winson 139036693cf71f8c4d2dd0dfb57ad05e8827ed6df60Winson mVisibleDockStates.clear(); 1409be3a060827154617eed9132c64431af56d98eb4Erik Wolsheimer if (ActivityManager.supportsMultiWindow(mRv.getContext()) && !ssp.hasDockedTask() 14119cf2972582198484816ac15ba83a4f46946082bJorim Jaggi && mDividerSnapAlgorithm.isSplitScreenFeasible()) { 142f21c3dace89b168f5e5e4e96532d977b8b0a1cf5Winson Recents.logDockAttempt(mRv.getContext(), event.task.getTopComponent(), 143f21c3dace89b168f5e5e4e96532d977b8b0a1cf5Winson event.task.resizeMode); 144931845fcb3823ce175fcfc7c6ce2d9751102c331Winson if (!event.task.isDockable) { 1459b001396c26e5b5ee95e0a54213a8a421179e365Winson EventBus.getDefault().send(new ShowIncompatibleAppOverlayEvent()); 146931845fcb3823ce175fcfc7c6ce2d9751102c331Winson } else { 147931845fcb3823ce175fcfc7c6ce2d9751102c331Winson // Add the dock state drop targets (these take priority) 1486519c1b0fe85c5f25115539e936e4333e8537098Winson Chung DockState[] dockStates = Recents.getConfiguration() 149b7035f3a4738efdf40dc0ad06f19303ffcd784f7Matthew Ng .getDockStatesForCurrentOrientation(); 1506519c1b0fe85c5f25115539e936e4333e8537098Winson Chung for (DockState dockState : dockStates) { 151931845fcb3823ce175fcfc7c6ce2d9751102c331Winson registerDropTargetForCurrentDrag(dockState); 15299ef458ff1b79c93a8dfdc289fb6ff80fd7aacf6Winson dockState.update(mRv.getContext()); 153931845fcb3823ce175fcfc7c6ce2d9751102c331Winson mVisibleDockStates.add(dockState); 154931845fcb3823ce175fcfc7c6ce2d9751102c331Winson } 155eca4ab6e99bcb2a7b31b8b4b1c3b5474297b6b25Winson } 156eca4ab6e99bcb2a7b31b8b4b1c3b5474297b6b25Winson } 157eca4ab6e99bcb2a7b31b8b4b1c3b5474297b6b25Winson 158eca4ab6e99bcb2a7b31b8b4b1c3b5474297b6b25Winson // Request other drop targets to register themselves 159d952961977a0eb6c1fefcb0707d1c61741515f68Winson EventBus.getDefault().send(new DragStartInitializeDropTargetsEvent(event.task, 160d952961977a0eb6c1fefcb0707d1c61741515f68Winson event.taskView, this)); 161131d53a7d817560ad06b5f26dc64a2969aeed53fWinson if (mDeviceId != -1) { 162df42455b1c1c1e0aafc090a0b89c088cbc603551Winson Chung InputDevice device = InputDevice.getDevice(mDeviceId); 163df42455b1c1c1e0aafc090a0b89c088cbc603551Winson Chung if (device != null) { 164df42455b1c1c1e0aafc090a0b89c088cbc603551Winson Chung device.setPointerType(PointerIcon.TYPE_GRABBING); 165df42455b1c1c1e0aafc090a0b89c088cbc603551Winson Chung } 166131d53a7d817560ad06b5f26dc64a2969aeed53fWinson } 1674165d336b6cd69715eda7fbdfd272a878097170eWinson } 1684165d336b6cd69715eda7fbdfd272a878097170eWinson 1694165d336b6cd69715eda7fbdfd272a878097170eWinson public final void onBusEvent(DragEndEvent event) { 1709b001396c26e5b5ee95e0a54213a8a421179e365Winson if (!mDragTask.isDockable) { 1719b001396c26e5b5ee95e0a54213a8a421179e365Winson EventBus.getDefault().send(new HideIncompatibleAppOverlayEvent()); 1729b001396c26e5b5ee95e0a54213a8a421179e365Winson } 1733e8747414520ee348cf4b9c4a6afd9ff80b5a8f8Winson mDragRequested = false; 1744165d336b6cd69715eda7fbdfd272a878097170eWinson mDragTask = null; 1754165d336b6cd69715eda7fbdfd272a878097170eWinson mTaskView = null; 176eca4ab6e99bcb2a7b31b8b4b1c3b5474297b6b25Winson mLastDropTarget = null; 1774165d336b6cd69715eda7fbdfd272a878097170eWinson } 178be7607af8875236b9cf7bdb5f5aa089c207529afWinson 17919cf2972582198484816ac15ba83a4f46946082bJorim Jaggi public final void onBusEvent(ConfigurationChangedEvent event) { 1809832f8f463a7d5448af2294bce05eac85f4dbef0Winson if (event.fromDisplayDensityChange || event.fromDeviceOrientationChange) { 18125160db73f37619a26a3d87a06625925d881b0fdJorim Jaggi updateSnapAlgorithm(); 18225160db73f37619a26a3d87a06625925d881b0fdJorim Jaggi } 18319cf2972582198484816ac15ba83a4f46946082bJorim Jaggi } 18419cf2972582198484816ac15ba83a4f46946082bJorim Jaggi 1859e177f05ea9a92a23ca72d9990f8a8bd7ada5f5aMatthew Ng void cancelStackActionButtonClick() { 1869e177f05ea9a92a23ca72d9990f8a8bd7ada5f5aMatthew Ng mRv.getStackActionButton().setPressed(false); 1879e177f05ea9a92a23ca72d9990f8a8bd7ada5f5aMatthew Ng } 1889e177f05ea9a92a23ca72d9990f8a8bd7ada5f5aMatthew Ng 1899e177f05ea9a92a23ca72d9990f8a8bd7ada5f5aMatthew Ng private boolean isWithinStackActionButton(float x, float y) { 1909e177f05ea9a92a23ca72d9990f8a8bd7ada5f5aMatthew Ng Rect rect = mRv.getStackActionButtonBoundsFromStackLayout(); 1919e177f05ea9a92a23ca72d9990f8a8bd7ada5f5aMatthew Ng return mRv.getStackActionButton().getVisibility() == View.VISIBLE && 1929e177f05ea9a92a23ca72d9990f8a8bd7ada5f5aMatthew Ng mRv.getStackActionButton().pointInView(x - rect.left, y - rect.top, 0 /* slop */); 1939e177f05ea9a92a23ca72d9990f8a8bd7ada5f5aMatthew Ng } 1949e177f05ea9a92a23ca72d9990f8a8bd7ada5f5aMatthew Ng 1959e177f05ea9a92a23ca72d9990f8a8bd7ada5f5aMatthew Ng private void changeStackActionButtonDrawableHotspot(float x, float y) { 1969e177f05ea9a92a23ca72d9990f8a8bd7ada5f5aMatthew Ng Rect rect = mRv.getStackActionButtonBoundsFromStackLayout(); 1979e177f05ea9a92a23ca72d9990f8a8bd7ada5f5aMatthew Ng mRv.getStackActionButton().drawableHotspotChanged(x - rect.left, y - rect.top); 1989e177f05ea9a92a23ca72d9990f8a8bd7ada5f5aMatthew Ng } 1999e177f05ea9a92a23ca72d9990f8a8bd7ada5f5aMatthew Ng 2004165d336b6cd69715eda7fbdfd272a878097170eWinson /** 2014165d336b6cd69715eda7fbdfd272a878097170eWinson * Handles dragging touch events 2024165d336b6cd69715eda7fbdfd272a878097170eWinson */ 2039e177f05ea9a92a23ca72d9990f8a8bd7ada5f5aMatthew Ng private boolean handleTouchEvent(MotionEvent ev) { 204a20eeda52951021da758fefba7bf956c9c9d15a2Jorim Jaggi int action = ev.getActionMasked(); 2059e177f05ea9a92a23ca72d9990f8a8bd7ada5f5aMatthew Ng boolean consumed = false; 2069e177f05ea9a92a23ca72d9990f8a8bd7ada5f5aMatthew Ng float evX = ev.getX(); 2079e177f05ea9a92a23ca72d9990f8a8bd7ada5f5aMatthew Ng float evY = ev.getY(); 208a20eeda52951021da758fefba7bf956c9c9d15a2Jorim Jaggi switch (action) { 209be7607af8875236b9cf7bdb5f5aa089c207529afWinson case MotionEvent.ACTION_DOWN: 2109e177f05ea9a92a23ca72d9990f8a8bd7ada5f5aMatthew Ng mDownPos.set((int) evX, (int) evY); 211131d53a7d817560ad06b5f26dc64a2969aeed53fWinson mDeviceId = ev.getDeviceId(); 2129e177f05ea9a92a23ca72d9990f8a8bd7ada5f5aMatthew Ng 2139e177f05ea9a92a23ca72d9990f8a8bd7ada5f5aMatthew Ng if (isWithinStackActionButton(evX, evY)) { 2149e177f05ea9a92a23ca72d9990f8a8bd7ada5f5aMatthew Ng changeStackActionButtonDrawableHotspot(evX, evY); 2159e177f05ea9a92a23ca72d9990f8a8bd7ada5f5aMatthew Ng mRv.getStackActionButton().setPressed(true); 2169e177f05ea9a92a23ca72d9990f8a8bd7ada5f5aMatthew Ng } 217be7607af8875236b9cf7bdb5f5aa089c207529afWinson break; 218be7607af8875236b9cf7bdb5f5aa089c207529afWinson case MotionEvent.ACTION_MOVE: { 2193e8747414520ee348cf4b9c4a6afd9ff80b5a8f8Winson float x = evX - mTaskViewOffset.x; 2203e8747414520ee348cf4b9c4a6afd9ff80b5a8f8Winson float y = evY - mTaskViewOffset.y; 2213e8747414520ee348cf4b9c4a6afd9ff80b5a8f8Winson 2229e177f05ea9a92a23ca72d9990f8a8bd7ada5f5aMatthew Ng if (mRv.getStackActionButton().isPressed() && isWithinStackActionButton(evX, evY)) { 2239e177f05ea9a92a23ca72d9990f8a8bd7ada5f5aMatthew Ng changeStackActionButtonDrawableHotspot(evX, evY); 2249e177f05ea9a92a23ca72d9990f8a8bd7ada5f5aMatthew Ng } 2259e177f05ea9a92a23ca72d9990f8a8bd7ada5f5aMatthew Ng 2263e8747414520ee348cf4b9c4a6afd9ff80b5a8f8Winson if (mDragRequested) { 2273e8747414520ee348cf4b9c4a6afd9ff80b5a8f8Winson if (!mIsDragging) { 2283e8747414520ee348cf4b9c4a6afd9ff80b5a8f8Winson mIsDragging = Math.hypot(evX - mDownPos.x, evY - mDownPos.y) > mDragSlop; 2294165d336b6cd69715eda7fbdfd272a878097170eWinson } 2303e8747414520ee348cf4b9c4a6afd9ff80b5a8f8Winson if (mIsDragging) { 2313e8747414520ee348cf4b9c4a6afd9ff80b5a8f8Winson int width = mRv.getMeasuredWidth(); 2323e8747414520ee348cf4b9c4a6afd9ff80b5a8f8Winson int height = mRv.getMeasuredHeight(); 2333e8747414520ee348cf4b9c4a6afd9ff80b5a8f8Winson 2343e8747414520ee348cf4b9c4a6afd9ff80b5a8f8Winson DropTarget currentDropTarget = null; 2353e8747414520ee348cf4b9c4a6afd9ff80b5a8f8Winson 2363e8747414520ee348cf4b9c4a6afd9ff80b5a8f8Winson // Give priority to the current drop target to retain the touch handling 2373e8747414520ee348cf4b9c4a6afd9ff80b5a8f8Winson if (mLastDropTarget != null) { 2383e8747414520ee348cf4b9c4a6afd9ff80b5a8f8Winson if (mLastDropTarget.acceptsDrop((int) evX, (int) evY, width, height, 23908deff0a67bd1e2d44477ed7c84c39fb3299fb7cWinson mRv.mSystemInsets, true /* isCurrentTarget */)) { 2403e8747414520ee348cf4b9c4a6afd9ff80b5a8f8Winson currentDropTarget = mLastDropTarget; 2413e8747414520ee348cf4b9c4a6afd9ff80b5a8f8Winson } 2423e8747414520ee348cf4b9c4a6afd9ff80b5a8f8Winson } 2433e8747414520ee348cf4b9c4a6afd9ff80b5a8f8Winson 2443e8747414520ee348cf4b9c4a6afd9ff80b5a8f8Winson // Otherwise, find the next target to handle this event 2453e8747414520ee348cf4b9c4a6afd9ff80b5a8f8Winson if (currentDropTarget == null) { 2463e8747414520ee348cf4b9c4a6afd9ff80b5a8f8Winson for (DropTarget target : mDropTargets) { 2473e8747414520ee348cf4b9c4a6afd9ff80b5a8f8Winson if (target.acceptsDrop((int) evX, (int) evY, width, height, 24808deff0a67bd1e2d44477ed7c84c39fb3299fb7cWinson mRv.mSystemInsets, false /* isCurrentTarget */)) { 2493e8747414520ee348cf4b9c4a6afd9ff80b5a8f8Winson currentDropTarget = target; 2503e8747414520ee348cf4b9c4a6afd9ff80b5a8f8Winson break; 2513e8747414520ee348cf4b9c4a6afd9ff80b5a8f8Winson } 2523e8747414520ee348cf4b9c4a6afd9ff80b5a8f8Winson } 2533e8747414520ee348cf4b9c4a6afd9ff80b5a8f8Winson } 2543e8747414520ee348cf4b9c4a6afd9ff80b5a8f8Winson if (mLastDropTarget != currentDropTarget) { 2553e8747414520ee348cf4b9c4a6afd9ff80b5a8f8Winson mLastDropTarget = currentDropTarget; 2563e8747414520ee348cf4b9c4a6afd9ff80b5a8f8Winson EventBus.getDefault().send(new DragDropTargetChangedEvent(mDragTask, 2573e8747414520ee348cf4b9c4a6afd9ff80b5a8f8Winson currentDropTarget)); 2583e8747414520ee348cf4b9c4a6afd9ff80b5a8f8Winson } 259be7607af8875236b9cf7bdb5f5aa089c207529afWinson } 260479f7446cf489fb99c91b3fc2bf96b1dc184f5baWinson mTaskView.setTranslationX(x); 261479f7446cf489fb99c91b3fc2bf96b1dc184f5baWinson mTaskView.setTranslationY(y); 2624165d336b6cd69715eda7fbdfd272a878097170eWinson } 263be7607af8875236b9cf7bdb5f5aa089c207529afWinson break; 264be7607af8875236b9cf7bdb5f5aa089c207529afWinson } 265be7607af8875236b9cf7bdb5f5aa089c207529afWinson case MotionEvent.ACTION_UP: 266be7607af8875236b9cf7bdb5f5aa089c207529afWinson case MotionEvent.ACTION_CANCEL: { 2679e177f05ea9a92a23ca72d9990f8a8bd7ada5f5aMatthew Ng if (mRv.getStackActionButton().isPressed() && isWithinStackActionButton(evX, evY)) { 2689e177f05ea9a92a23ca72d9990f8a8bd7ada5f5aMatthew Ng EventBus.getDefault().send(new DismissAllTaskViewsEvent()); 2699e177f05ea9a92a23ca72d9990f8a8bd7ada5f5aMatthew Ng consumed = true; 2709e177f05ea9a92a23ca72d9990f8a8bd7ada5f5aMatthew Ng } 2719e177f05ea9a92a23ca72d9990f8a8bd7ada5f5aMatthew Ng cancelStackActionButtonClick(); 2723e8747414520ee348cf4b9c4a6afd9ff80b5a8f8Winson if (mDragRequested) { 273f300badbf10505fbcb884aebb0f2c3120e018748Jorim Jaggi boolean cancelled = action == MotionEvent.ACTION_CANCEL; 274f300badbf10505fbcb884aebb0f2c3120e018748Jorim Jaggi if (cancelled) { 275f300badbf10505fbcb884aebb0f2c3120e018748Jorim Jaggi EventBus.getDefault().send(new DragDropTargetChangedEvent(mDragTask, null)); 276f300badbf10505fbcb884aebb0f2c3120e018748Jorim Jaggi } 277479f7446cf489fb99c91b3fc2bf96b1dc184f5baWinson EventBus.getDefault().send(new DragEndEvent(mDragTask, mTaskView, 278f300badbf10505fbcb884aebb0f2c3120e018748Jorim Jaggi !cancelled ? mLastDropTarget : null)); 27909d8a184c6d9d996663da1756ab4ac7d54c04b45Winson break; 28009d8a184c6d9d996663da1756ab4ac7d54c04b45Winson } 281131d53a7d817560ad06b5f26dc64a2969aeed53fWinson mDeviceId = -1; 282be7607af8875236b9cf7bdb5f5aa089c207529afWinson } 283be7607af8875236b9cf7bdb5f5aa089c207529afWinson } 2849e177f05ea9a92a23ca72d9990f8a8bd7ada5f5aMatthew Ng return consumed; 285be7607af8875236b9cf7bdb5f5aa089c207529afWinson } 286be7607af8875236b9cf7bdb5f5aa089c207529afWinson} 287