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.ActivityOptions;
import android.app.TaskStackBuilder; import android.app.TaskStackBuilder;
import android.content.ActivityNotFoundException;
import android.content.ComponentName; import android.content.ComponentName;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
@@ -35,7 +34,6 @@ import android.view.WindowInsets;
import android.widget.FrameLayout; import android.widget.FrameLayout;
import com.android.systemui.recents.Constants; import com.android.systemui.recents.Constants;
import com.android.systemui.recents.RecentsConfiguration; 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.SystemServicesProxy;
import com.android.systemui.recents.misc.Utilities; import com.android.systemui.recents.misc.Utilities;
import com.android.systemui.recents.model.RecentsPackageMonitor; import com.android.systemui.recents.model.RecentsPackageMonitor;
@@ -339,7 +337,7 @@ public class RecentsView extends FrameLayout implements TaskStackView.TaskStackV
View child = getChildAt(i); View child = getChildAt(i);
if (child != mSearchBar) { if (child != mSearchBar) {
TaskStackView stackView = (TaskStackView) child; TaskStackView stackView = (TaskStackView) child;
stackView.focusNextTask(forward); stackView.focusNextTask(forward, true);
break; 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 */ /** 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 // Return early if the task is already focused
if (taskIndex == mFocusedTaskIndex) return; if (taskIndex == mFocusedTaskIndex) return;
@@ -426,7 +426,7 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
TaskView tv = getChildViewForTask(t); TaskView tv = getChildViewForTask(t);
Runnable postScrollRunnable = null; Runnable postScrollRunnable = null;
if (tv != null) { if (tv != null) {
tv.setFocusedTask(); tv.setFocusedTask(animateFocusedState);
} else { } else {
postScrollRunnable = new Runnable() { postScrollRunnable = new Runnable() {
@Override @Override
@@ -434,7 +434,7 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
Task t = mStack.getTasks().get(mFocusedTaskIndex); Task t = mStack.getTasks().get(mFocusedTaskIndex);
TaskView tv = getChildViewForTask(t); TaskView tv = getChildViewForTask(t);
if (tv != null) { 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 // Find the next index to focus
int numTasks = mStack.getTaskCount(); int numTasks = mStack.getTaskCount();
if (numTasks == 0) return; if (numTasks == 0) return;
int nextFocusIndex = numTasks - 1; int direction = (forward ? -1 : 1);
if (0 <= mFocusedTaskIndex && mFocusedTaskIndex < numTasks) { int newIndex = mFocusedTaskIndex + direction;
nextFocusIndex = Math.max(0, Math.min(numTasks - 1, if (newIndex >= 0 && newIndex <= (numTasks - 1)) {
mFocusedTaskIndex + (forward ? -1 : 1))); newIndex = Math.max(0, Math.min(numTasks - 1, newIndex));
focusTask(newIndex, true, animateFocusedState);
} }
focusTask(nextFocusIndex, true);
} }
/** Dismisses the focused task. */ /** Dismisses the focused task. */
@@ -504,6 +536,11 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
return mTouchHandler.onTouchEvent(ev); return mTouchHandler.onTouchEvent(ev);
} }
@Override
public boolean onGenericMotionEvent(MotionEvent ev) {
return mTouchHandler.onGenericMotionEvent(ev);
}
@Override @Override
public void computeScroll() { public void computeScroll() {
mStackScroller.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 // When Alt-Tabbing, we scroll to and focus the previous task
if (mConfig.launchedWithAltTab) { if (mConfig.launchedWithAltTab) {
if (mConfig.launchedFromHome) { if (mConfig.launchedFromHome) {
focusTask(Math.max(0, mStack.getTaskCount() - 1), false); focusTask(Math.max(0, mStack.getTaskCount() - 1), false, true);
} else { } 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)); tv.getTask().activityLabel));
// Remove the task from the view // Remove the task from the view
mStack.removeTask(task); 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) { if (taskWasFocused) {
ArrayList<Task> tasks = mStack.getTasks(); 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) { if (nextTaskIndex >= 0) {
Task nextTask = tasks.get(nextTaskIndex); Task nextTask = tasks.get(nextTaskIndex);
TaskView nextTv = getChildViewForTask(nextTask); 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; return transformOut;
} }
/** /** Returns the untransformed task view size. */
* Returns the untransformed task view size.
*/
public Rect getUntransformedTaskViewSize() { public Rect getUntransformedTaskViewSize() {
Rect tvSize = new Rect(mTaskRect); Rect tvSize = new Rect(mTaskRect);
tvSize.offsetTo(0, 0); tvSize.offsetTo(0, 0);
return tvSize; return tvSize;
} }
/** /** Returns the scroll to such task top = 1f; */
* Returns the scroll to such task top = 1f;
*/
float getStackScrollForTask(Task t) { float getStackScrollForTask(Task t) {
return mTaskProgressMap.get(t.key); return mTaskProgressMap.get(t.key);
} }

View File

@@ -38,6 +38,7 @@ public class TaskStackViewScroller {
OverScroller mScroller; OverScroller mScroller;
ObjectAnimator mScrollAnimator; ObjectAnimator mScrollAnimator;
float mFinalAnimatedScroll;
public TaskStackViewScroller(Context context, RecentsConfiguration config, TaskStackViewLayoutAlgorithm layoutAlgorithm) { public TaskStackViewScroller(Context context, RecentsConfiguration config, TaskStackViewLayoutAlgorithm layoutAlgorithm) {
mConfig = config; mConfig = config;
@@ -128,10 +129,15 @@ public class TaskStackViewScroller {
/** Animates the stack scroll */ /** Animates the stack scroll */
void animateScroll(float curScroll, float newScroll, final Runnable postRunnable) { 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(); stopScroller();
stopBoundScrollAnimation(); stopBoundScrollAnimation();
mFinalAnimatedScroll = newScroll;
mScrollAnimator = ObjectAnimator.ofFloat(this, "stackScroll", curScroll, newScroll); mScrollAnimator = ObjectAnimator.ofFloat(this, "stackScroll", curScroll, newScroll);
mScrollAnimator.setDuration(mConfig.taskStackScrollDuration); mScrollAnimator.setDuration(mConfig.taskStackScrollDuration);
mScrollAnimator.setInterpolator(mConfig.linearOutSlowInInterpolator); mScrollAnimator.setInterpolator(mConfig.linearOutSlowInInterpolator);

View File

@@ -17,6 +17,7 @@
package com.android.systemui.recents.views; package com.android.systemui.recents.views;
import android.content.Context; import android.content.Context;
import android.view.InputDevice;
import android.view.MotionEvent; import android.view.MotionEvent;
import android.view.VelocityTracker; import android.view.VelocityTracker;
import android.view.View; import android.view.View;
@@ -189,7 +190,6 @@ class TaskStackViewTouchHandler implements SwipeHelper.Callback {
/** Handles touch events once we have intercepted them */ /** Handles touch events once we have intercepted them */
public boolean onTouchEvent(MotionEvent ev) { public boolean onTouchEvent(MotionEvent ev) {
// Short circuit if we have no children // Short circuit if we have no children
boolean hasChildren = (mSv.getChildCount() > 0); boolean hasChildren = (mSv.getChildCount() > 0);
if (!hasChildren) { if (!hasChildren) {
@@ -336,6 +336,30 @@ class TaskStackViewTouchHandler implements SwipeHelper.Callback {
return true; 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 ****/ /**** SwipeHelper Implementation ****/
@Override @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 * if the view is not currently visible, or we are in touch state (where we still want to keep
* track of focus). * track of focus).
*/ */
public void setFocusedTask() { public void setFocusedTask(boolean animateFocusedState) {
mIsFocused = true; mIsFocused = true;
if (mFocusAnimationsEnabled) { if (mFocusAnimationsEnabled) {
// Focus the header bar // Focus the header bar
mHeaderView.onTaskViewFocusChanged(true); mHeaderView.onTaskViewFocusChanged(true, animateFocusedState);
} }
// Update the thumbnail alpha with the focus // Update the thumbnail alpha with the focus
mThumbnailView.onFocusChanged(true); mThumbnailView.onFocusChanged(true);
@@ -742,7 +742,7 @@ public class TaskView extends FrameLayout implements Task.TaskCallbacks,
mIsFocused = false; mIsFocused = false;
if (mFocusAnimationsEnabled) { if (mFocusAnimationsEnabled) {
// Un-focus the header bar // Un-focus the header bar
mHeaderView.onTaskViewFocusChanged(false); mHeaderView.onTaskViewFocusChanged(false, true);
} }
// Update the thumbnail alpha with the focus // Update the thumbnail alpha with the focus
@@ -776,7 +776,7 @@ public class TaskView extends FrameLayout implements Task.TaskCallbacks,
mFocusAnimationsEnabled = true; mFocusAnimationsEnabled = true;
if (mIsFocused && !wasFocusAnimationsEnabled) { if (mIsFocused && !wasFocusAnimationsEnabled) {
// Re-notify the header if we were focused and animations were not previously enabled // 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. */ /** 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; boolean isRunning = false;
if (mFocusAnimator != null) { if (mFocusAnimator != null) {
isRunning = mFocusAnimator.isRunning(); isRunning = mFocusAnimator.isRunning();
mFocusAnimator.removeAllListeners(); mFocusAnimator.removeAllListeners();
mFocusAnimator.cancel(); mFocusAnimator.cancel();
} }
if (focused) { if (focused) {
int secondaryColor = getSecondaryColor(mCurrentPrimaryColor, mCurrentPrimaryColorIsDark); int secondaryColor = getSecondaryColor(mCurrentPrimaryColor, mCurrentPrimaryColorIsDark);
int[][] states = new int[][] { int[][] states = new int[][] {