Add arrow key navigation support to Grid-based Recents.
am: c0e1813944
Change-Id: I36781f21274e5c07f2e1e0d2f5d30a20982c4f24
This commit is contained in:
@@ -74,6 +74,8 @@ import com.android.systemui.recents.events.ui.UserInteractionEvent;
|
|||||||
import com.android.systemui.recents.events.ui.focus.DismissFocusedTaskViewEvent;
|
import com.android.systemui.recents.events.ui.focus.DismissFocusedTaskViewEvent;
|
||||||
import com.android.systemui.recents.events.ui.focus.FocusNextTaskViewEvent;
|
import com.android.systemui.recents.events.ui.focus.FocusNextTaskViewEvent;
|
||||||
import com.android.systemui.recents.events.ui.focus.FocusPreviousTaskViewEvent;
|
import com.android.systemui.recents.events.ui.focus.FocusPreviousTaskViewEvent;
|
||||||
|
import com.android.systemui.recents.events.ui.focus.NavigateTaskViewEvent;
|
||||||
|
import com.android.systemui.recents.events.ui.focus.NavigateTaskViewEvent.Direction;
|
||||||
import com.android.systemui.recents.misc.DozeTrigger;
|
import com.android.systemui.recents.misc.DozeTrigger;
|
||||||
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;
|
||||||
@@ -592,13 +594,12 @@ public class RecentsActivity extends Activity implements ViewTreeObserver.OnPreD
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
case KeyEvent.KEYCODE_DPAD_UP: {
|
case KeyEvent.KEYCODE_DPAD_UP:
|
||||||
EventBus.getDefault().send(
|
case KeyEvent.KEYCODE_DPAD_DOWN:
|
||||||
new FocusNextTaskViewEvent(0 /* timerIndicatorDuration */));
|
case KeyEvent.KEYCODE_DPAD_LEFT:
|
||||||
return true;
|
case KeyEvent.KEYCODE_DPAD_RIGHT: {
|
||||||
}
|
final Direction direction = NavigateTaskViewEvent.getDirectionFromKeyCode(keyCode);
|
||||||
case KeyEvent.KEYCODE_DPAD_DOWN: {
|
EventBus.getDefault().send(new NavigateTaskViewEvent(direction));
|
||||||
EventBus.getDefault().send(new FocusPreviousTaskViewEvent());
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
case KeyEvent.KEYCODE_DEL:
|
case KeyEvent.KEYCODE_DEL:
|
||||||
|
|||||||
@@ -0,0 +1,49 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2017 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.android.systemui.recents.events.ui.focus;
|
||||||
|
|
||||||
|
import android.view.KeyEvent;
|
||||||
|
import com.android.systemui.recents.events.EventBus;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Navigates the task view by arrow keys.
|
||||||
|
*/
|
||||||
|
public class NavigateTaskViewEvent extends EventBus.Event {
|
||||||
|
public enum Direction {
|
||||||
|
UNDEFINED, UP, DOWN, LEFT, RIGHT;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Direction direction;
|
||||||
|
public NavigateTaskViewEvent(Direction direction) {
|
||||||
|
this.direction = direction;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Direction getDirectionFromKeyCode(int keyCode) {
|
||||||
|
switch (keyCode) {
|
||||||
|
case KeyEvent.KEYCODE_DPAD_UP:
|
||||||
|
return Direction.UP;
|
||||||
|
case KeyEvent.KEYCODE_DPAD_DOWN:
|
||||||
|
return Direction.DOWN;
|
||||||
|
case KeyEvent.KEYCODE_DPAD_LEFT:
|
||||||
|
return Direction.LEFT;
|
||||||
|
case KeyEvent.KEYCODE_DPAD_RIGHT:
|
||||||
|
return Direction.RIGHT;
|
||||||
|
default:
|
||||||
|
return Direction.UNDEFINED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -87,6 +87,7 @@ import com.android.systemui.recents.events.ui.dragndrop.DragStartInitializeDropT
|
|||||||
import com.android.systemui.recents.events.ui.focus.DismissFocusedTaskViewEvent;
|
import com.android.systemui.recents.events.ui.focus.DismissFocusedTaskViewEvent;
|
||||||
import com.android.systemui.recents.events.ui.focus.FocusNextTaskViewEvent;
|
import com.android.systemui.recents.events.ui.focus.FocusNextTaskViewEvent;
|
||||||
import com.android.systemui.recents.events.ui.focus.FocusPreviousTaskViewEvent;
|
import com.android.systemui.recents.events.ui.focus.FocusPreviousTaskViewEvent;
|
||||||
|
import com.android.systemui.recents.events.ui.focus.NavigateTaskViewEvent;
|
||||||
import com.android.systemui.recents.misc.DozeTrigger;
|
import com.android.systemui.recents.misc.DozeTrigger;
|
||||||
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;
|
||||||
@@ -1869,6 +1870,26 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
|
|||||||
setRelativeFocusedTask(false, false /* stackTasksOnly */, true /* animated */);
|
setRelativeFocusedTask(false, false /* stackTasksOnly */, true /* animated */);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public final void onBusEvent(NavigateTaskViewEvent event) {
|
||||||
|
if (useGridLayout()) {
|
||||||
|
final int taskCount = mStack.getTaskCount();
|
||||||
|
final int currentIndex = mStack.indexOfStackTask(getFocusedTask());
|
||||||
|
final int nextIndex = mLayoutAlgorithm.mTaskGridLayoutAlgorithm.navigateFocus(taskCount,
|
||||||
|
currentIndex, event.direction);
|
||||||
|
setFocusedTask(nextIndex, false, true);
|
||||||
|
} else {
|
||||||
|
switch (event.direction) {
|
||||||
|
case UP:
|
||||||
|
EventBus.getDefault().send(new FocusPreviousTaskViewEvent());
|
||||||
|
break;
|
||||||
|
case DOWN:
|
||||||
|
EventBus.getDefault().send(
|
||||||
|
new FocusNextTaskViewEvent(0 /* timerIndicatorDuration */));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public final void onBusEvent(UserInteractionEvent event) {
|
public final void onBusEvent(UserInteractionEvent event) {
|
||||||
// Poke the doze trigger on user interaction
|
// Poke the doze trigger on user interaction
|
||||||
mUIDozeTrigger.poke();
|
mUIDozeTrigger.poke();
|
||||||
|
|||||||
@@ -23,6 +23,8 @@ import android.graphics.Rect;
|
|||||||
import android.view.WindowManager;
|
import android.view.WindowManager;
|
||||||
|
|
||||||
import com.android.systemui.R;
|
import com.android.systemui.R;
|
||||||
|
import com.android.systemui.recents.events.ui.focus.NavigateTaskViewEvent;
|
||||||
|
import com.android.systemui.recents.events.ui.focus.NavigateTaskViewEvent.Direction;
|
||||||
import com.android.systemui.recents.misc.Utilities;
|
import com.android.systemui.recents.misc.Utilities;
|
||||||
import com.android.systemui.recents.views.TaskStackLayoutAlgorithm;
|
import com.android.systemui.recents.views.TaskStackLayoutAlgorithm;
|
||||||
import com.android.systemui.recents.views.TaskViewTransform;
|
import com.android.systemui.recents.views.TaskViewTransform;
|
||||||
@@ -63,6 +65,8 @@ public class TaskGridLayoutAlgorithm {
|
|||||||
Rect size;
|
Rect size;
|
||||||
int[] xOffsets;
|
int[] xOffsets;
|
||||||
int[] yOffsets;
|
int[] yOffsets;
|
||||||
|
int tasksPerLine;
|
||||||
|
int lines;
|
||||||
|
|
||||||
TaskGridRectInfo(int taskCount) {
|
TaskGridRectInfo(int taskCount) {
|
||||||
size = new Rect();
|
size = new Rect();
|
||||||
@@ -71,10 +75,10 @@ public class TaskGridLayoutAlgorithm {
|
|||||||
|
|
||||||
int layoutTaskCount = Math.min(MAX_LAYOUT_TASK_COUNT, taskCount);
|
int layoutTaskCount = Math.min(MAX_LAYOUT_TASK_COUNT, taskCount);
|
||||||
|
|
||||||
int tasksPerLine = layoutTaskCount < 2 ? 1 : (
|
tasksPerLine = layoutTaskCount < 2 ? 1 : (
|
||||||
layoutTaskCount < 5 ? 2 : (
|
layoutTaskCount < 5 ? 2 : (
|
||||||
layoutTaskCount < 7 ? 3 : 4));
|
layoutTaskCount < 7 ? 3 : 4));
|
||||||
int lines = layoutTaskCount < 3 ? 1 : 2;
|
lines = layoutTaskCount < 3 ? 1 : 2;
|
||||||
|
|
||||||
// A couple of special cases.
|
// A couple of special cases.
|
||||||
boolean landscapeWindow = mWindowRect.width() > mWindowRect.height();
|
boolean landscapeWindow = mWindowRect.width() > mWindowRect.height();
|
||||||
@@ -200,6 +204,48 @@ public class TaskGridLayoutAlgorithm {
|
|||||||
return transformOut;
|
return transformOut;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the proper task index to focus for arrow key navigation.
|
||||||
|
* @param taskCount The amount of tasks.
|
||||||
|
* @param currentFocusedIndex The index of the currently focused task.
|
||||||
|
* @param direction The direction we're navigating.
|
||||||
|
* @return The index of the task that should get the focus.
|
||||||
|
*/
|
||||||
|
public int navigateFocus(int taskCount, int currentFocusedIndex, Direction direction) {
|
||||||
|
if (taskCount < 1 || taskCount > MAX_LAYOUT_TASK_COUNT) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (currentFocusedIndex == -1) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
int newIndex = currentFocusedIndex;
|
||||||
|
final TaskGridRectInfo gridInfo = mTaskGridRectInfoList[taskCount - 1];
|
||||||
|
final int currentLine = (taskCount - 1 - currentFocusedIndex) / gridInfo.tasksPerLine;
|
||||||
|
switch (direction) {
|
||||||
|
case UP:
|
||||||
|
newIndex += gridInfo.tasksPerLine;
|
||||||
|
newIndex = newIndex >= taskCount ? currentFocusedIndex : newIndex;
|
||||||
|
break;
|
||||||
|
case DOWN:
|
||||||
|
newIndex -= gridInfo.tasksPerLine;
|
||||||
|
newIndex = newIndex < 0 ? currentFocusedIndex : newIndex;
|
||||||
|
break;
|
||||||
|
case LEFT:
|
||||||
|
newIndex++;
|
||||||
|
final int leftMostIndex = (taskCount - 1) - currentLine * gridInfo.tasksPerLine;
|
||||||
|
newIndex = newIndex > leftMostIndex ? currentFocusedIndex : newIndex;
|
||||||
|
break;
|
||||||
|
case RIGHT:
|
||||||
|
newIndex--;
|
||||||
|
int rightMostIndex =
|
||||||
|
(taskCount - 1) - (currentLine + 1) * gridInfo.tasksPerLine + 1;
|
||||||
|
rightMostIndex = rightMostIndex < 0 ? 0 : rightMostIndex;
|
||||||
|
newIndex = newIndex < rightMostIndex ? currentFocusedIndex : newIndex;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return newIndex;
|
||||||
|
}
|
||||||
|
|
||||||
public void initialize(Rect windowRect) {
|
public void initialize(Rect windowRect) {
|
||||||
mWindowRect = windowRect;
|
mWindowRect = windowRect;
|
||||||
// Define paddings in terms of percentage of the total area.
|
// Define paddings in terms of percentage of the total area.
|
||||||
|
|||||||
Reference in New Issue
Block a user