blob: be3af040c7485c36b1d18a01a7a2d29a3aeb4159 [file] [log] [blame]
/*
* Copyright (C) 2016 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.views.grid;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Point;
import android.graphics.Rect;
import android.view.WindowManager;
import com.android.systemui.R;
import com.android.systemui.recents.misc.Utilities;
import com.android.systemui.recents.views.TaskStackLayoutAlgorithm;
import com.android.systemui.recents.views.TaskViewTransform;
public class TaskGridLayoutAlgorithm {
private final String TAG = "TaskGridLayoutAlgorithm";
private final int MAX_LAYOUT_TASK_COUNT = 8;
/** The horizontal padding around the whole recents view. */
private int mPaddingLeftRight;
/** The vertical padding around the whole recents view. */
private int mPaddingTopBottom;
/** The padding between task views. */
private int mPaddingTaskView;
private Rect mDisplayRect;
private Rect mWindowRect;
private Point mScreenSize = new Point();
private Rect mTaskGridRect;
/** The height, in pixels, of each task view's title bar. */
private int mTitleBarHeight;
/** The aspect ratio of each task thumbnail, without the title bar. */
private float mAppAspectRatio;
private Rect mSystemInsets = new Rect();
/**
* When the amount of tasks is determined, the size and position of every task view can be
* decided. Each instance of TaskGridRectInfo store the task view information for a certain
* amount of tasks.
*/
class TaskGridRectInfo {
Rect size;
int[] xOffsets;
int[] yOffsets;
public TaskGridRectInfo(int taskCount) {
size = new Rect();
xOffsets = new int[taskCount];
yOffsets = new int[taskCount];
int layoutTaskCount = Math.min(MAX_LAYOUT_TASK_COUNT, taskCount);
int tasksPerLine = layoutTaskCount < 2 ? 1 : (
layoutTaskCount < 5 ? 2 : (
layoutTaskCount < 7 ? 3 : 4));
int lines = layoutTaskCount < 3 ? 1 : 2;
int taskWidth, taskHeight;
int maxTaskWidth = (mDisplayRect.width() - 2 * mPaddingLeftRight
- (tasksPerLine - 1) * mPaddingTaskView) / tasksPerLine;
int maxTaskHeight = (mDisplayRect.height() - 2 * mPaddingTopBottom
- (lines - 1) * mPaddingTaskView) / lines;
if (maxTaskHeight >= maxTaskWidth / mAppAspectRatio + mTitleBarHeight) {
// Width bound.
taskWidth = maxTaskWidth;
taskHeight = (int) (maxTaskWidth / mAppAspectRatio + mTitleBarHeight);
} else {
// Height bound.
taskHeight = maxTaskHeight;
taskWidth = (int) ((taskHeight - mTitleBarHeight) * mAppAspectRatio);
}
size.set(0, 0, taskWidth, taskHeight);
int emptySpaceX = mDisplayRect.width() - 2 * mPaddingLeftRight
- (tasksPerLine * taskWidth) - (tasksPerLine - 1) * mPaddingTaskView;
int emptySpaceY = mDisplayRect.height() - 2 * mPaddingTopBottom
- (lines * taskHeight) - (lines - 1) * mPaddingTaskView;
for (int taskIndex = 0; taskIndex < taskCount; taskIndex++) {
// We also need to invert the index in order to display the most recent tasks first.
int taskLayoutIndex = taskCount - taskIndex - 1;
int xIndex = taskLayoutIndex % tasksPerLine;
int yIndex = taskLayoutIndex / tasksPerLine;
xOffsets[taskIndex] =
emptySpaceX / 2 + mPaddingLeftRight + (taskWidth + mPaddingTaskView) * xIndex;
yOffsets[taskIndex] =
emptySpaceY / 2 + mPaddingTopBottom + (taskHeight + mPaddingTaskView) * yIndex;
}
}
}
/**
* We can find task view sizes and positions from mTaskGridRectInfoList[k - 1] when there
* are k tasks.
*/
TaskGridRectInfo[] mTaskGridRectInfoList;
public TaskGridLayoutAlgorithm(Context context) {
reloadOnConfigurationChange(context);
}
public void reloadOnConfigurationChange(Context context) {
Resources res = context.getResources();
mPaddingLeftRight = res.getDimensionPixelSize(R.dimen.recents_grid_padding_left_right);
mPaddingTopBottom = res.getDimensionPixelSize(R.dimen.recents_grid_padding_top_bottom);
mPaddingTaskView = res.getDimensionPixelSize(R.dimen.recents_grid_padding_task_view);
mTaskGridRect = new Rect();
mTitleBarHeight = res.getDimensionPixelSize(R.dimen.recents_grid_task_view_header_height);
WindowManager windowManager = (WindowManager) context
.getSystemService(Context.WINDOW_SERVICE);
windowManager.getDefaultDisplay().getRealSize(mScreenSize);
updateAppAspectRatio();
}
public TaskViewTransform getTransform(int taskIndex, int taskCount,
TaskViewTransform transformOut, TaskStackLayoutAlgorithm stackLayout) {
TaskGridRectInfo gridInfo = mTaskGridRectInfoList[taskCount - 1];
mTaskGridRect.set(gridInfo.size);
int x = gridInfo.xOffsets[taskIndex];
int y = gridInfo.yOffsets[taskIndex];
float z = stackLayout.mMaxTranslationZ;
float dimAlpha = 0f;
float viewOutlineAlpha = 0f;
// We also need to invert the index in order to display the most recent tasks first.
int taskLayoutIndex = taskCount - taskIndex - 1;
boolean isTaskViewVisible = (taskLayoutIndex < MAX_LAYOUT_TASK_COUNT);
// Fill out the transform
transformOut.scale = 1f;
transformOut.alpha = isTaskViewVisible ? 1f : 0f;
transformOut.translationZ = z;
transformOut.dimAlpha = dimAlpha;
transformOut.viewOutlineAlpha = viewOutlineAlpha;
transformOut.rect.set(mTaskGridRect);
transformOut.rect.offset(x, y);
Utilities.scaleRectAboutCenter(transformOut.rect, transformOut.scale);
// We only show the 8 most recent tasks.
transformOut.visible = isTaskViewVisible;
return transformOut;
}
public void initialize(Rect displayRect, Rect windowRect) {
mDisplayRect = displayRect;
mWindowRect = windowRect;
// Pre-calculate the positions and offsets of task views so that we can reuse them directly
// in the future.
mTaskGridRectInfoList = new TaskGridRectInfo[MAX_LAYOUT_TASK_COUNT];
for (int i = 0; i < MAX_LAYOUT_TASK_COUNT; i++) {
mTaskGridRectInfoList[i] = new TaskGridRectInfo(i + 1);
}
}
public void setSystemInsets(Rect systemInsets) {
mSystemInsets = systemInsets;
updateAppAspectRatio();
}
private void updateAppAspectRatio() {
int usableWidth = mScreenSize.x - mSystemInsets.left - mSystemInsets.right;
int usableHeight = mScreenSize.y - mSystemInsets.top - mSystemInsets.bottom;
mAppAspectRatio = (float) usableWidth / (float) usableHeight;
}
public Rect getStackActionButtonRect() {
Rect buttonRect = new Rect(mDisplayRect);
buttonRect.right -= mPaddingLeftRight;
buttonRect.left += mPaddingLeftRight;
buttonRect.bottom = buttonRect.top + mPaddingTopBottom;
return buttonRect;
}
public Rect getTaskGridRect() {
return mTaskGridRect;
}
}