Merge "Adding mouse wheel support. (Bug 17323718)" into lmp-mr1-dev

This commit is contained in:
Winson Chung
2014-10-14 22:47:12 +00:00
committed by Android (Google) Code Review
7 changed files with 100 additions and 31 deletions

View File

@@ -18,7 +18,6 @@ package com.android.systemui.recents.views;
import android.app.ActivityOptions;
import android.app.TaskStackBuilder;
import android.content.ActivityNotFoundException;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
@@ -35,7 +34,6 @@ import android.view.WindowInsets;
import android.widget.FrameLayout;
import com.android.systemui.recents.Constants;
import com.android.systemui.recents.RecentsConfiguration;
import com.android.systemui.recents.misc.Console;
import com.android.systemui.recents.misc.SystemServicesProxy;
import com.android.systemui.recents.misc.Utilities;
import com.android.systemui.recents.model.RecentsPackageMonitor;
@@ -339,7 +337,7 @@ public class RecentsView extends FrameLayout implements TaskStackView.TaskStackV
View child = getChildAt(i);
if (child != mSearchBar) {
TaskStackView stackView = (TaskStackView) child;
stackView.focusNextTask(forward);
stackView.focusNextTask(forward, true);
break;
}
}

View File

@@ -414,7 +414,7 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
}
/** Focuses the task at the specified index in the stack */
void focusTask(int taskIndex, boolean scrollToNewPosition) {
void focusTask(int taskIndex, boolean scrollToNewPosition, final boolean animateFocusedState) {
// Return early if the task is already focused
if (taskIndex == mFocusedTaskIndex) return;
@@ -426,7 +426,7 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
TaskView tv = getChildViewForTask(t);
Runnable postScrollRunnable = null;
if (tv != null) {
tv.setFocusedTask();
tv.setFocusedTask(animateFocusedState);
} else {
postScrollRunnable = new Runnable() {
@Override
@@ -434,7 +434,7 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
Task t = mStack.getTasks().get(mFocusedTaskIndex);
TaskView tv = getChildViewForTask(t);
if (tv != null) {
tv.setFocusedTask();
tv.setFocusedTask(animateFocusedState);
}
}
};
@@ -454,18 +454,50 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
}
}
/** Focuses the next task in the stack */
void focusNextTask(boolean forward) {
/**
* Ensures that there is a task focused, if nothign is focused, then we will use the task
* at the center of the visible stack.
*/
public boolean ensureFocusedTask() {
if (mFocusedTaskIndex < 0) {
// If there is no task focused, then find the task that is closes to the center
// of the screen and use that as the currently focused task
int x = mLayoutAlgorithm.mStackVisibleRect.centerX();
int y = mLayoutAlgorithm.mStackVisibleRect.centerY();
int childCount = getChildCount();
for (int i = childCount - 1; i >= 0; i--) {
TaskView tv = (TaskView) getChildAt(i);
tv.getHitRect(mTmpRect);
if (mTmpRect.contains(x, y)) {
mFocusedTaskIndex = mStack.indexOfTask(tv.getTask());
break;
}
}
// If we can't find the center task, then use the front most index
if (mFocusedTaskIndex < 0 && childCount > 0) {
mFocusedTaskIndex = childCount - 1;
}
}
return mFocusedTaskIndex >= 0;
}
/**
* Focuses the next task in the stack.
* @param animateFocusedState determines whether to actually draw the highlight along with
* the change in focus, as well as whether to scroll to fit the
* task into view.
*/
public void focusNextTask(boolean forward, boolean animateFocusedState) {
// Find the next index to focus
int numTasks = mStack.getTaskCount();
if (numTasks == 0) return;
int nextFocusIndex = numTasks - 1;
if (0 <= mFocusedTaskIndex && mFocusedTaskIndex < numTasks) {
nextFocusIndex = Math.max(0, Math.min(numTasks - 1,
mFocusedTaskIndex + (forward ? -1 : 1)));
int direction = (forward ? -1 : 1);
int newIndex = mFocusedTaskIndex + direction;
if (newIndex >= 0 && newIndex <= (numTasks - 1)) {
newIndex = Math.max(0, Math.min(numTasks - 1, newIndex));
focusTask(newIndex, true, animateFocusedState);
}
focusTask(nextFocusIndex, true);
}
/** Dismisses the focused task. */
@@ -504,6 +536,11 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
return mTouchHandler.onTouchEvent(ev);
}
@Override
public boolean onGenericMotionEvent(MotionEvent ev) {
return mTouchHandler.onGenericMotionEvent(ev);
}
@Override
public void computeScroll() {
mStackScroller.computeScroll();
@@ -652,9 +689,9 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
// When Alt-Tabbing, we scroll to and focus the previous task
if (mConfig.launchedWithAltTab) {
if (mConfig.launchedFromHome) {
focusTask(Math.max(0, mStack.getTaskCount() - 1), false);
focusTask(Math.max(0, mStack.getTaskCount() - 1), false, true);
} else {
focusTask(Math.max(0, mStack.getTaskCount() - 2), false);
focusTask(Math.max(0, mStack.getTaskCount() - 2), false, true);
}
}
}
@@ -1018,14 +1055,18 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
tv.getTask().activityLabel));
// Remove the task from the view
mStack.removeTask(task);
// If the dismissed task was focused, then we should focus the next task in front
// If the dismissed task was focused, then we should focus the new task in the same index
if (taskWasFocused) {
ArrayList<Task> tasks = mStack.getTasks();
int nextTaskIndex = Math.min(tasks.size() - 1, taskIndex);
int nextTaskIndex = Math.min(tasks.size() - 1, taskIndex - 1);
if (nextTaskIndex >= 0) {
Task nextTask = tasks.get(nextTaskIndex);
TaskView nextTv = getChildViewForTask(nextTask);
nextTv.setFocusedTask();
if (nextTv != null) {
// Focus the next task, and only animate the visible state if we are launched
// from Alt-Tab
nextTv.setFocusedTask(mConfig.launchedWithAltTab);
}
}
}
}

View File

@@ -199,18 +199,14 @@ public class TaskStackViewLayoutAlgorithm {
return transformOut;
}
/**
* Returns the untransformed task view size.
*/
/** Returns the untransformed task view size. */
public Rect getUntransformedTaskViewSize() {
Rect tvSize = new Rect(mTaskRect);
tvSize.offsetTo(0, 0);
return tvSize;
}
/**
* Returns the scroll to such task top = 1f;
*/
/** Returns the scroll to such task top = 1f; */
float getStackScrollForTask(Task t) {
return mTaskProgressMap.get(t.key);
}

View File

@@ -38,6 +38,7 @@ public class TaskStackViewScroller {
OverScroller mScroller;
ObjectAnimator mScrollAnimator;
float mFinalAnimatedScroll;
public TaskStackViewScroller(Context context, RecentsConfiguration config, TaskStackViewLayoutAlgorithm layoutAlgorithm) {
mConfig = config;
@@ -128,10 +129,15 @@ public class TaskStackViewScroller {
/** Animates the stack scroll */
void animateScroll(float curScroll, float newScroll, final Runnable postRunnable) {
// Abort any current animations
// Finish any current scrolling animations
if (mScrollAnimator != null && mScrollAnimator.isRunning()) {
setStackScroll(mFinalAnimatedScroll);
mScroller.startScroll(0, progressToScrollRange(mFinalAnimatedScroll), 0, 0, 0);
}
stopScroller();
stopBoundScrollAnimation();
mFinalAnimatedScroll = newScroll;
mScrollAnimator = ObjectAnimator.ofFloat(this, "stackScroll", curScroll, newScroll);
mScrollAnimator.setDuration(mConfig.taskStackScrollDuration);
mScrollAnimator.setInterpolator(mConfig.linearOutSlowInInterpolator);

View File

@@ -17,6 +17,7 @@
package com.android.systemui.recents.views;
import android.content.Context;
import android.view.InputDevice;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.View;
@@ -189,7 +190,6 @@ class TaskStackViewTouchHandler implements SwipeHelper.Callback {
/** Handles touch events once we have intercepted them */
public boolean onTouchEvent(MotionEvent ev) {
// Short circuit if we have no children
boolean hasChildren = (mSv.getChildCount() > 0);
if (!hasChildren) {
@@ -336,6 +336,30 @@ class TaskStackViewTouchHandler implements SwipeHelper.Callback {
return true;
}
/** Handles generic motion events */
public boolean onGenericMotionEvent(MotionEvent ev) {
if ((ev.getSource() & InputDevice.SOURCE_CLASS_POINTER) ==
InputDevice.SOURCE_CLASS_POINTER) {
int action = ev.getAction();
switch (action & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_SCROLL:
// Find the front most task and scroll the next task to the front
float vScroll = ev.getAxisValue(MotionEvent.AXIS_VSCROLL);
if (vScroll > 0) {
if (mSv.ensureFocusedTask()) {
mSv.focusNextTask(true, false);
}
} else {
if (mSv.ensureFocusedTask()) {
mSv.focusNextTask(false, false);
}
}
return true;
}
}
return false;
}
/**** SwipeHelper Implementation ****/
@Override

View File

@@ -716,11 +716,11 @@ public class TaskView extends FrameLayout implements Task.TaskCallbacks,
* if the view is not currently visible, or we are in touch state (where we still want to keep
* track of focus).
*/
public void setFocusedTask() {
public void setFocusedTask(boolean animateFocusedState) {
mIsFocused = true;
if (mFocusAnimationsEnabled) {
// Focus the header bar
mHeaderView.onTaskViewFocusChanged(true);
mHeaderView.onTaskViewFocusChanged(true, animateFocusedState);
}
// Update the thumbnail alpha with the focus
mThumbnailView.onFocusChanged(true);
@@ -742,7 +742,7 @@ public class TaskView extends FrameLayout implements Task.TaskCallbacks,
mIsFocused = false;
if (mFocusAnimationsEnabled) {
// Un-focus the header bar
mHeaderView.onTaskViewFocusChanged(false);
mHeaderView.onTaskViewFocusChanged(false, true);
}
// Update the thumbnail alpha with the focus
@@ -776,7 +776,7 @@ public class TaskView extends FrameLayout implements Task.TaskCallbacks,
mFocusAnimationsEnabled = true;
if (mIsFocused && !wasFocusAnimationsEnabled) {
// Re-notify the header if we were focused and animations were not previously enabled
mHeaderView.onTaskViewFocusChanged(true);
mHeaderView.onTaskViewFocusChanged(true, true);
}
}

View File

@@ -268,13 +268,17 @@ public class TaskViewHeader extends FrameLayout {
}
/** Notifies the associated TaskView has been focused. */
void onTaskViewFocusChanged(boolean focused) {
void onTaskViewFocusChanged(boolean focused, boolean animateFocusedState) {
// If we are not animating the visible state, just return
if (!animateFocusedState) return;
boolean isRunning = false;
if (mFocusAnimator != null) {
isRunning = mFocusAnimator.isRunning();
mFocusAnimator.removeAllListeners();
mFocusAnimator.cancel();
}
if (focused) {
int secondaryColor = getSecondaryColor(mCurrentPrimaryColor, mCurrentPrimaryColorIsDark);
int[][] states = new int[][] {