RecentsViewTouchHandler.java revision be7607af8875236b9cf7bdb5f5aa089c207529af
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 TaskStack.DockState.TOP, TaskStack.DockState.BOTTOM 40 }; 41} 42 43/** 44 * Handles touch events for a RecentsView. 45 */ 46class RecentsViewTouchHandler { 47 48 private RecentsView mRv; 49 50 private Task mDragTask; 51 private TaskView mTaskView; 52 private DragView mDragView; 53 54 private Point mDownPos = new Point(); 55 private boolean mDragging; 56 private TaskStack.DockState mLastDockState; 57 58 public RecentsViewTouchHandler(RecentsView rv) { 59 mRv = rv; 60 } 61 62 /** Touch preprocessing for handling below */ 63 public boolean onInterceptTouchEvent(MotionEvent ev) { 64 int action = ev.getAction(); 65 switch (action & MotionEvent.ACTION_MASK) { 66 case MotionEvent.ACTION_DOWN: 67 mDownPos.set((int) ev.getX(), (int) ev.getY()); 68 break; 69 } 70 return mDragging; 71 } 72 73 /** Handles touch events once we have intercepted them */ 74 public boolean onTouchEvent(MotionEvent ev) { 75 if (!mDragging) return false; 76 77 boolean isLandscape = mRv.getResources().getConfiguration().orientation == 78 Configuration.ORIENTATION_LANDSCAPE; 79 int action = ev.getAction(); 80 switch (action & MotionEvent.ACTION_MASK) { 81 case MotionEvent.ACTION_DOWN: 82 mDownPos.set((int) ev.getX(), (int) ev.getY()); 83 break; 84 case MotionEvent.ACTION_MOVE: { 85 int width = mRv.getMeasuredWidth(); 86 int height = mRv.getMeasuredHeight(); 87 float evX = ev.getX(); 88 float evY = ev.getY(); 89 float x = evX - mDragView.getTopLeftOffset().x; 90 float y = evY - mDragView.getTopLeftOffset().y; 91 92 // Update the dock state 93 TaskStack.DockState[] dockStates = isLandscape ? 94 DockRegion.LANDSCAPE : DockRegion.PORTRAIT; 95 TaskStack.DockState foundDockState = null; 96 for (int i = 0; i < dockStates.length; i++) { 97 TaskStack.DockState state = dockStates[i]; 98 if (state.touchAreaContainsPoint(width, height, evX, evY)) { 99 foundDockState = state; 100 break; 101 } 102 } 103 if (mLastDockState != foundDockState) { 104 mLastDockState = foundDockState; 105 EventBus.getDefault().send(new DragDockStateChangedEvent(mDragTask, 106 foundDockState)); 107 } 108 109 mDragView.setTranslationX(x); 110 mDragView.setTranslationY(y); 111 break; 112 } 113 case MotionEvent.ACTION_UP: 114 case MotionEvent.ACTION_CANCEL: { 115 ReferenceCountedTrigger postAnimationTrigger = new ReferenceCountedTrigger( 116 mRv.getContext(), null, null, null); 117 postAnimationTrigger.increment(); 118 EventBus.getDefault().send(new DragEndEvent(mDragTask, mTaskView, mDragView, 119 mLastDockState, postAnimationTrigger)); 120 postAnimationTrigger.decrement(); 121 break; 122 } 123 } 124 return true; 125 } 126 127 /**** Events ****/ 128 129 public final void onBusEvent(DragStartEvent event) { 130 mRv.getParent().requestDisallowInterceptTouchEvent(true); 131 mDragging = true; 132 mDragTask = event.task; 133 mTaskView = event.taskView; 134 mDragView = event.dragView; 135 136 float x = mDownPos.x - mDragView.getTopLeftOffset().x; 137 float y = mDownPos.y - mDragView.getTopLeftOffset().y; 138 mDragView.setTranslationX(x); 139 mDragView.setTranslationY(y); 140 } 141 142 public final void onBusEvent(DragEndEvent event) { 143 mDragging = false; 144 mDragTask = null; 145 mTaskView = null; 146 mDragView = null; 147 mLastDockState = null; 148 } 149} 150