RecentsViewTouchHandler.java revision 09d8a184c6d9d996663da1756ab4ac7d54c04b45
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 17package com.android.systemui.recents.views; 18 19import android.content.res.Configuration; 20import android.graphics.Point; 21import android.view.MotionEvent; 22import com.android.systemui.recents.events.EventBus; 23import com.android.systemui.recents.events.ui.dragndrop.DragDockStateChangedEvent; 24import com.android.systemui.recents.events.ui.dragndrop.DragEndEvent; 25import com.android.systemui.recents.events.ui.dragndrop.DragStartEvent; 26import com.android.systemui.recents.misc.ReferenceCountedTrigger; 27import com.android.systemui.recents.model.Task; 28import com.android.systemui.recents.model.TaskStack; 29 30 31/** 32 * Represents the dock regions for each orientation. 33 */ 34class DockRegion { 35 public static TaskStack.DockState[] LANDSCAPE = { 36 TaskStack.DockState.LEFT, TaskStack.DockState.RIGHT 37 }; 38 public static TaskStack.DockState[] PORTRAIT = { 39 // We only allow docking to the top for now 40 TaskStack.DockState.TOP 41 }; 42} 43 44/** 45 * Handles touch events for a RecentsView. 46 */ 47class RecentsViewTouchHandler { 48 49 private RecentsView mRv; 50 51 private Task mDragTask; 52 private TaskView mTaskView; 53 private DragView mDragView; 54 55 private Point mDownPos = new Point(); 56 private boolean mDragging; 57 private TaskStack.DockState mLastDockState = TaskStack.DockState.NONE; 58 59 public RecentsViewTouchHandler(RecentsView rv) { 60 mRv = rv; 61 } 62 63 public TaskStack.DockState getPreferredDockStateForCurrentOrientation() { 64 boolean isLandscape = mRv.getResources().getConfiguration().orientation == 65 Configuration.ORIENTATION_LANDSCAPE; 66 TaskStack.DockState[] dockStates = isLandscape ? 67 DockRegion.LANDSCAPE : DockRegion.PORTRAIT; 68 return dockStates[0]; 69 } 70 71 /** Touch preprocessing for handling below */ 72 public boolean onInterceptTouchEvent(MotionEvent ev) { 73 handleTouchEvent(ev); 74 return mDragging; 75 } 76 77 /** Handles touch events once we have intercepted them */ 78 public boolean onTouchEvent(MotionEvent ev) { 79 handleTouchEvent(ev); 80 return mDragging; 81 } 82 83 /**** Events ****/ 84 85 public final void onBusEvent(DragStartEvent event) { 86 mRv.getParent().requestDisallowInterceptTouchEvent(true); 87 mDragging = true; 88 mDragTask = event.task; 89 mTaskView = event.taskView; 90 mDragView = event.dragView; 91 92 float x = mDownPos.x - mDragView.getTopLeftOffset().x; 93 float y = mDownPos.y - mDragView.getTopLeftOffset().y; 94 mDragView.setTranslationX(x); 95 mDragView.setTranslationY(y); 96 } 97 98 public final void onBusEvent(DragEndEvent event) { 99 mDragging = false; 100 mDragTask = null; 101 mTaskView = null; 102 mDragView = null; 103 mLastDockState = TaskStack.DockState.NONE; 104 } 105 106 /** 107 * Handles dragging touch events 108 * @param ev 109 */ 110 private void handleTouchEvent(MotionEvent ev) { 111 boolean isLandscape = mRv.getResources().getConfiguration().orientation == 112 Configuration.ORIENTATION_LANDSCAPE; 113 int action = ev.getAction(); 114 switch (action & MotionEvent.ACTION_MASK) { 115 case MotionEvent.ACTION_DOWN: 116 mDownPos.set((int) ev.getX(), (int) ev.getY()); 117 break; 118 case MotionEvent.ACTION_MOVE: { 119 if (mDragging) { 120 int width = mRv.getMeasuredWidth(); 121 int height = mRv.getMeasuredHeight(); 122 float evX = ev.getX(); 123 float evY = ev.getY(); 124 float x = evX - mDragView.getTopLeftOffset().x; 125 float y = evY - mDragView.getTopLeftOffset().y; 126 127 // Update the dock state 128 TaskStack.DockState[] dockStates = isLandscape ? 129 DockRegion.LANDSCAPE : DockRegion.PORTRAIT; 130 TaskStack.DockState foundDockState = TaskStack.DockState.NONE; 131 for (int i = 0; i < dockStates.length; i++) { 132 TaskStack.DockState state = dockStates[i]; 133 if (state.touchAreaContainsPoint(width, height, evX, evY)) { 134 foundDockState = state; 135 break; 136 } 137 } 138 if (mLastDockState != foundDockState) { 139 mLastDockState = foundDockState; 140 EventBus.getDefault().send(new DragDockStateChangedEvent(mDragTask, 141 foundDockState)); 142 } 143 144 mDragView.setTranslationX(x); 145 mDragView.setTranslationY(y); 146 } 147 break; 148 } 149 case MotionEvent.ACTION_UP: 150 case MotionEvent.ACTION_CANCEL: { 151 if (mDragging) { 152 ReferenceCountedTrigger postAnimationTrigger = new ReferenceCountedTrigger( 153 mRv.getContext(), null, null, null); 154 postAnimationTrigger.increment(); 155 EventBus.getDefault().send(new DragEndEvent(mDragTask, mTaskView, mDragView, 156 mLastDockState, postAnimationTrigger)); 157 postAnimationTrigger.decrement(); 158 break; 159 } 160 } 161 } 162 } 163} 164