Winson | be7607a | 2015-10-01 17:24:51 -0700 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (C) 2014 The Android Open Source Project |
| 3 | * |
| 4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
| 5 | * you may not use this file except in compliance with the License. |
| 6 | * You may obtain a copy of the License at |
| 7 | * |
| 8 | * http://www.apache.org/licenses/LICENSE-2.0 |
| 9 | * |
| 10 | * Unless required by applicable law or agreed to in writing, software |
| 11 | * distributed under the License is distributed on an "AS IS" BASIS, |
| 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 13 | * See the License for the specific language governing permissions and |
| 14 | * limitations under the License. |
| 15 | */ |
| 16 | |
| 17 | package com.android.systemui.recents.views; |
| 18 | |
| 19 | import android.content.res.Configuration; |
| 20 | import android.graphics.Point; |
| 21 | import android.view.MotionEvent; |
Winson | 53ec42c | 2015-10-28 15:55:35 -0700 | [diff] [blame] | 22 | import com.android.systemui.recents.Recents; |
Winson | 882072b | 2015-10-12 11:26:33 -0700 | [diff] [blame] | 23 | import com.android.systemui.recents.RecentsConfiguration; |
Winson | be7607a | 2015-10-01 17:24:51 -0700 | [diff] [blame] | 24 | import com.android.systemui.recents.events.EventBus; |
Winson | eca4ab6 | 2015-11-04 10:50:28 -0800 | [diff] [blame] | 25 | import com.android.systemui.recents.events.ui.dragndrop.DragDropTargetChangedEvent; |
Winson | be7607a | 2015-10-01 17:24:51 -0700 | [diff] [blame] | 26 | import com.android.systemui.recents.events.ui.dragndrop.DragEndEvent; |
| 27 | import com.android.systemui.recents.events.ui.dragndrop.DragStartEvent; |
Winson | eca4ab6 | 2015-11-04 10:50:28 -0800 | [diff] [blame] | 28 | import com.android.systemui.recents.events.ui.dragndrop.DragStartInitializeDropTargetsEvent; |
Winson | d759a71 | 2015-11-30 18:43:43 -0800 | [diff] [blame] | 29 | import com.android.systemui.recents.misc.SystemServicesProxy; |
Winson | be7607a | 2015-10-01 17:24:51 -0700 | [diff] [blame] | 30 | import com.android.systemui.recents.model.Task; |
| 31 | import com.android.systemui.recents.model.TaskStack; |
| 32 | |
Winson | eca4ab6 | 2015-11-04 10:50:28 -0800 | [diff] [blame] | 33 | import java.util.ArrayList; |
| 34 | |
Winson | be7607a | 2015-10-01 17:24:51 -0700 | [diff] [blame] | 35 | |
| 36 | /** |
| 37 | * Represents the dock regions for each orientation. |
| 38 | */ |
| 39 | class DockRegion { |
Winson | 882072b | 2015-10-12 11:26:33 -0700 | [diff] [blame] | 40 | public static TaskStack.DockState[] PHONE_LANDSCAPE = { |
Winson | e92440e | 2015-10-28 09:48:47 -0700 | [diff] [blame] | 41 | // We only allow docking to the left for now on small devices |
Winson | 2364f26 | 2015-10-26 10:56:59 -0700 | [diff] [blame] | 42 | TaskStack.DockState.LEFT |
Winson | be7607a | 2015-10-01 17:24:51 -0700 | [diff] [blame] | 43 | }; |
Winson | 882072b | 2015-10-12 11:26:33 -0700 | [diff] [blame] | 44 | public static TaskStack.DockState[] PHONE_PORTRAIT = { |
Winson | e92440e | 2015-10-28 09:48:47 -0700 | [diff] [blame] | 45 | // We only allow docking to the top for now on small devices |
Winson | 4165d336 | 2015-10-10 14:40:35 -0700 | [diff] [blame] | 46 | TaskStack.DockState.TOP |
Winson | be7607a | 2015-10-01 17:24:51 -0700 | [diff] [blame] | 47 | }; |
Winson | 882072b | 2015-10-12 11:26:33 -0700 | [diff] [blame] | 48 | public static TaskStack.DockState[] TABLET_LANDSCAPE = { |
Winson | e92440e | 2015-10-28 09:48:47 -0700 | [diff] [blame] | 49 | TaskStack.DockState.LEFT, |
| 50 | TaskStack.DockState.RIGHT |
Winson | 882072b | 2015-10-12 11:26:33 -0700 | [diff] [blame] | 51 | }; |
| 52 | public static TaskStack.DockState[] TABLET_PORTRAIT = PHONE_PORTRAIT; |
Winson | be7607a | 2015-10-01 17:24:51 -0700 | [diff] [blame] | 53 | } |
| 54 | |
| 55 | /** |
| 56 | * Handles touch events for a RecentsView. |
| 57 | */ |
Winson | eca4ab6 | 2015-11-04 10:50:28 -0800 | [diff] [blame] | 58 | public class RecentsViewTouchHandler { |
| 59 | |
Winson | be7607a | 2015-10-01 17:24:51 -0700 | [diff] [blame] | 60 | private RecentsView mRv; |
| 61 | |
| 62 | private Task mDragTask; |
| 63 | private TaskView mTaskView; |
Winson | be7607a | 2015-10-01 17:24:51 -0700 | [diff] [blame] | 64 | |
Winson | 479f744 | 2015-11-25 15:16:27 -0800 | [diff] [blame] | 65 | private Point mTaskViewOffset = new Point(); |
Winson | be7607a | 2015-10-01 17:24:51 -0700 | [diff] [blame] | 66 | private Point mDownPos = new Point(); |
| 67 | private boolean mDragging; |
Winson | eca4ab6 | 2015-11-04 10:50:28 -0800 | [diff] [blame] | 68 | |
| 69 | private DropTarget mLastDropTarget; |
| 70 | private ArrayList<DropTarget> mDropTargets = new ArrayList<>(); |
Winson | be7607a | 2015-10-01 17:24:51 -0700 | [diff] [blame] | 71 | |
| 72 | public RecentsViewTouchHandler(RecentsView rv) { |
| 73 | mRv = rv; |
| 74 | } |
| 75 | |
Winson | 882072b | 2015-10-12 11:26:33 -0700 | [diff] [blame] | 76 | /** |
Winson | eca4ab6 | 2015-11-04 10:50:28 -0800 | [diff] [blame] | 77 | * Registers a new drop target for the current drag only. |
| 78 | */ |
| 79 | public void registerDropTargetForCurrentDrag(DropTarget target) { |
| 80 | mDropTargets.add(target); |
| 81 | } |
| 82 | |
| 83 | /** |
Winson | 882072b | 2015-10-12 11:26:33 -0700 | [diff] [blame] | 84 | * Returns the preferred dock states for the current orientation. |
| 85 | */ |
| 86 | public TaskStack.DockState[] getDockStatesForCurrentOrientation() { |
Winson | 4165d336 | 2015-10-10 14:40:35 -0700 | [diff] [blame] | 87 | boolean isLandscape = mRv.getResources().getConfiguration().orientation == |
| 88 | Configuration.ORIENTATION_LANDSCAPE; |
Winson | 53ec42c | 2015-10-28 15:55:35 -0700 | [diff] [blame] | 89 | RecentsConfiguration config = Recents.getConfiguration(); |
Winson | 4165d336 | 2015-10-10 14:40:35 -0700 | [diff] [blame] | 90 | TaskStack.DockState[] dockStates = isLandscape ? |
Winson | 882072b | 2015-10-12 11:26:33 -0700 | [diff] [blame] | 91 | (config.isLargeScreen ? DockRegion.TABLET_LANDSCAPE : DockRegion.PHONE_LANDSCAPE) : |
| 92 | (config.isLargeScreen ? DockRegion.TABLET_PORTRAIT : DockRegion.PHONE_PORTRAIT); |
| 93 | return dockStates; |
Winson | 4165d336 | 2015-10-10 14:40:35 -0700 | [diff] [blame] | 94 | } |
| 95 | |
Winson | be7607a | 2015-10-01 17:24:51 -0700 | [diff] [blame] | 96 | /** Touch preprocessing for handling below */ |
| 97 | public boolean onInterceptTouchEvent(MotionEvent ev) { |
Winson | 4165d336 | 2015-10-10 14:40:35 -0700 | [diff] [blame] | 98 | handleTouchEvent(ev); |
Winson | be7607a | 2015-10-01 17:24:51 -0700 | [diff] [blame] | 99 | return mDragging; |
| 100 | } |
| 101 | |
| 102 | /** Handles touch events once we have intercepted them */ |
| 103 | public boolean onTouchEvent(MotionEvent ev) { |
Winson | 4165d336 | 2015-10-10 14:40:35 -0700 | [diff] [blame] | 104 | handleTouchEvent(ev); |
| 105 | return mDragging; |
Winson | be7607a | 2015-10-01 17:24:51 -0700 | [diff] [blame] | 106 | } |
| 107 | |
| 108 | /**** Events ****/ |
| 109 | |
| 110 | public final void onBusEvent(DragStartEvent event) { |
Winson | d759a71 | 2015-11-30 18:43:43 -0800 | [diff] [blame] | 111 | SystemServicesProxy ssp = Recents.getSystemServices(); |
Winson | be7607a | 2015-10-01 17:24:51 -0700 | [diff] [blame] | 112 | mRv.getParent().requestDisallowInterceptTouchEvent(true); |
| 113 | mDragging = true; |
| 114 | mDragTask = event.task; |
| 115 | mTaskView = event.taskView; |
Winson | eca4ab6 | 2015-11-04 10:50:28 -0800 | [diff] [blame] | 116 | mDropTargets.clear(); |
Winson | be7607a | 2015-10-01 17:24:51 -0700 | [diff] [blame] | 117 | |
Winson | 479f744 | 2015-11-25 15:16:27 -0800 | [diff] [blame] | 118 | int[] recentsViewLocation = new int[2]; |
| 119 | mRv.getLocationInWindow(recentsViewLocation); |
| 120 | mTaskViewOffset.set(mTaskView.getLeft() - recentsViewLocation[0] + event.tlOffset.x, |
| 121 | mTaskView.getTop() - recentsViewLocation[1] + event.tlOffset.y); |
| 122 | float x = mDownPos.x - mTaskViewOffset.x; |
| 123 | float y = mDownPos.y - mTaskViewOffset.y; |
| 124 | mTaskView.setTranslationX(x); |
| 125 | mTaskView.setTranslationY(y); |
Winson | eca4ab6 | 2015-11-04 10:50:28 -0800 | [diff] [blame] | 126 | |
Winson | d759a71 | 2015-11-30 18:43:43 -0800 | [diff] [blame] | 127 | if (!ssp.hasDockedTask()) { |
Winson | eca4ab6 | 2015-11-04 10:50:28 -0800 | [diff] [blame] | 128 | // Add the dock state drop targets (these take priority) |
| 129 | TaskStack.DockState[] dockStates = getDockStatesForCurrentOrientation(); |
| 130 | for (TaskStack.DockState dockState : dockStates) { |
| 131 | registerDropTargetForCurrentDrag(dockState); |
| 132 | } |
| 133 | } |
| 134 | |
| 135 | // Request other drop targets to register themselves |
| 136 | EventBus.getDefault().send(new DragStartInitializeDropTargetsEvent(event.task, this)); |
Winson | be7607a | 2015-10-01 17:24:51 -0700 | [diff] [blame] | 137 | } |
| 138 | |
| 139 | public final void onBusEvent(DragEndEvent event) { |
| 140 | mDragging = false; |
| 141 | mDragTask = null; |
| 142 | mTaskView = null; |
Winson | eca4ab6 | 2015-11-04 10:50:28 -0800 | [diff] [blame] | 143 | mLastDropTarget = null; |
Winson | 4165d336 | 2015-10-10 14:40:35 -0700 | [diff] [blame] | 144 | } |
| 145 | |
| 146 | /** |
| 147 | * Handles dragging touch events |
Winson | 4165d336 | 2015-10-10 14:40:35 -0700 | [diff] [blame] | 148 | */ |
| 149 | private void handleTouchEvent(MotionEvent ev) { |
Winson | 4165d336 | 2015-10-10 14:40:35 -0700 | [diff] [blame] | 150 | int action = ev.getAction(); |
| 151 | switch (action & MotionEvent.ACTION_MASK) { |
| 152 | case MotionEvent.ACTION_DOWN: |
| 153 | mDownPos.set((int) ev.getX(), (int) ev.getY()); |
| 154 | break; |
| 155 | case MotionEvent.ACTION_MOVE: { |
| 156 | if (mDragging) { |
| 157 | int width = mRv.getMeasuredWidth(); |
| 158 | int height = mRv.getMeasuredHeight(); |
| 159 | float evX = ev.getX(); |
| 160 | float evY = ev.getY(); |
Winson | 479f744 | 2015-11-25 15:16:27 -0800 | [diff] [blame] | 161 | float x = evX - mTaskViewOffset.x; |
| 162 | float y = evY - mTaskViewOffset.y; |
Winson | 4165d336 | 2015-10-10 14:40:35 -0700 | [diff] [blame] | 163 | |
Winson | eca4ab6 | 2015-11-04 10:50:28 -0800 | [diff] [blame] | 164 | DropTarget currentDropTarget = null; |
| 165 | for (DropTarget target : mDropTargets) { |
| 166 | if (target.acceptsDrop((int) evX, (int) evY, width, height)) { |
| 167 | currentDropTarget = target; |
Winson | 4165d336 | 2015-10-10 14:40:35 -0700 | [diff] [blame] | 168 | break; |
| 169 | } |
| 170 | } |
Winson | eca4ab6 | 2015-11-04 10:50:28 -0800 | [diff] [blame] | 171 | if (mLastDropTarget != currentDropTarget) { |
| 172 | mLastDropTarget = currentDropTarget; |
| 173 | EventBus.getDefault().send(new DragDropTargetChangedEvent(mDragTask, |
| 174 | currentDropTarget)); |
Winson | 4165d336 | 2015-10-10 14:40:35 -0700 | [diff] [blame] | 175 | } |
| 176 | |
Winson | 479f744 | 2015-11-25 15:16:27 -0800 | [diff] [blame] | 177 | mTaskView.setTranslationX(x); |
| 178 | mTaskView.setTranslationY(y); |
Winson | 4165d336 | 2015-10-10 14:40:35 -0700 | [diff] [blame] | 179 | } |
| 180 | break; |
| 181 | } |
| 182 | case MotionEvent.ACTION_UP: |
| 183 | case MotionEvent.ACTION_CANCEL: { |
Winson | 09d8a18 | 2015-10-10 14:50:23 -0700 | [diff] [blame] | 184 | if (mDragging) { |
Winson | 479f744 | 2015-11-25 15:16:27 -0800 | [diff] [blame] | 185 | EventBus.getDefault().send(new DragEndEvent(mDragTask, mTaskView, |
Winson Chung | aaeaac1 | 2015-12-16 16:49:36 -0500 | [diff] [blame] | 186 | mLastDropTarget)); |
Winson | 09d8a18 | 2015-10-10 14:50:23 -0700 | [diff] [blame] | 187 | break; |
| 188 | } |
Winson | 4165d336 | 2015-10-10 14:40:35 -0700 | [diff] [blame] | 189 | } |
| 190 | } |
Winson | be7607a | 2015-10-01 17:24:51 -0700 | [diff] [blame] | 191 | } |
| 192 | } |