use of com.android.systemui.recents.model.Task in project android_frameworks_base by DirtyUnicorns.
the class FreeformWorkspaceLayoutAlgorithm method update.
/**
* Updates the layout for each of the freeform workspace tasks. This is called after the stack
* layout is updated.
*/
public void update(List<Task> freeformTasks, TaskStackLayoutAlgorithm stackLayout) {
Collections.reverse(freeformTasks);
mTaskRectMap.clear();
int numFreeformTasks = stackLayout.mNumFreeformTasks;
if (!freeformTasks.isEmpty()) {
// Normalize the widths so that we can calculate the best layout below
int workspaceWidth = stackLayout.mFreeformRect.width();
int workspaceHeight = stackLayout.mFreeformRect.height();
float normalizedWorkspaceWidth = (float) workspaceWidth / workspaceHeight;
float normalizedWorkspaceHeight = 1f;
float[] normalizedTaskWidths = new float[numFreeformTasks];
for (int i = 0; i < numFreeformTasks; i++) {
Task task = freeformTasks.get(i);
float rowTaskWidth;
if (task.bounds != null) {
rowTaskWidth = (float) task.bounds.width() / task.bounds.height();
} else {
// If this is a stack task that was dragged into the freeform workspace, then
// the task will not yet have an associated bounds, so assume the full workspace
// width for the time being
rowTaskWidth = normalizedWorkspaceWidth;
}
// Bound the task width to the workspace width so that at the worst case, it will
// fit its own row
normalizedTaskWidths[i] = Math.min(rowTaskWidth, normalizedWorkspaceWidth);
}
// Determine the scale to best fit each of the tasks in the workspace
float rowScale = 0.85f;
float rowWidth = 0f;
float maxRowWidth = 0f;
int rowCount = 1;
for (int i = 0; i < numFreeformTasks; ) {
float width = normalizedTaskWidths[i] * rowScale;
if (rowWidth + width > normalizedWorkspaceWidth) {
// That is too long for this row, create new row
if ((rowCount + 1) * rowScale > normalizedWorkspaceHeight) {
// The new row is too high, so we need to try fitting again. Update the
// scale to be the smaller of the scale needed to fit the task in the
// previous row, or the scale needed to fit the new row
rowScale = Math.min(normalizedWorkspaceWidth / (rowWidth + width), normalizedWorkspaceHeight / (rowCount + 1));
rowCount = 1;
rowWidth = 0;
i = 0;
} else {
// The new row fits, so continue
rowWidth = width;
rowCount++;
i++;
}
} else {
// Task is OK in this row
rowWidth += width;
i++;
}
maxRowWidth = Math.max(rowWidth, maxRowWidth);
}
// Normalize each of the actual rects to that scale
float defaultRowLeft = ((1f - (maxRowWidth / normalizedWorkspaceWidth)) * workspaceWidth) / 2f;
float rowLeft = defaultRowLeft;
float rowTop = ((1f - (rowScale * rowCount)) * workspaceHeight) / 2f;
float rowHeight = rowScale * workspaceHeight;
for (int i = 0; i < numFreeformTasks; i++) {
Task task = freeformTasks.get(i);
float width = rowHeight * normalizedTaskWidths[i];
if (rowLeft + width > workspaceWidth) {
// This goes on the next line
rowTop += rowHeight;
rowLeft = defaultRowLeft;
}
RectF rect = new RectF(rowLeft, rowTop, rowLeft + width, rowTop + rowHeight);
rect.inset(mTaskPadding, mTaskPadding);
rowLeft += width;
mTaskRectMap.put(task.key, rect);
}
}
}
use of com.android.systemui.recents.model.Task in project android_frameworks_base by DirtyUnicorns.
the class RecentsTransitionHelper method composeDockAnimationSpec.
/**
* Composes the transition spec when docking a task, which includes a full task bitmap.
*/
public List<AppTransitionAnimationSpec> composeDockAnimationSpec(TaskView taskView, Rect bounds) {
mTmpTransform.fillIn(taskView);
Task task = taskView.getTask();
Bitmap thumbnail = RecentsTransitionHelper.composeTaskBitmap(taskView, mTmpTransform);
return Collections.singletonList(new AppTransitionAnimationSpec(task.key.id, thumbnail, bounds));
}
use of com.android.systemui.recents.model.Task in project android_frameworks_base by DirtyUnicorns.
the class RecentsView method launchPreviousTask.
/** Launches the task that recents was launched from if possible */
public boolean launchPreviousTask() {
if (mTaskStackView != null) {
Task task = getStack().getLaunchTarget();
if (task != null) {
TaskView taskView = mTaskStackView.getChildViewForTask(task);
EventBus.getDefault().send(new LaunchTaskEvent(taskView, task, null, INVALID_STACK_ID, false));
return true;
}
}
return false;
}
use of com.android.systemui.recents.model.Task in project android_frameworks_base by DirtyUnicorns.
the class TaskStackLayoutAlgorithm method update.
/**
* Computes the minimum and maximum scroll progress values and the progress values for each task
* in the stack.
*/
void update(TaskStack stack, ArraySet<Task.TaskKey> ignoreTasksSet) {
SystemServicesProxy ssp = Recents.getSystemServices();
RecentsActivityLaunchState launchState = Recents.getConfiguration().getLaunchState();
// Clear the progress map
mTaskIndexMap.clear();
// Return early if we have no tasks
ArrayList<Task> tasks = stack.getStackTasks();
if (tasks.isEmpty()) {
mFrontMostTaskP = 0;
mMinScrollP = mMaxScrollP = mInitialScrollP = 0;
mNumStackTasks = mNumFreeformTasks = 0;
return;
}
// Filter the set of freeform and stack tasks
ArrayList<Task> freeformTasks = new ArrayList<>();
ArrayList<Task> stackTasks = new ArrayList<>();
for (int i = 0; i < tasks.size(); i++) {
Task task = tasks.get(i);
if (ignoreTasksSet.contains(task.key)) {
continue;
}
if (task.isFreeformTask()) {
freeformTasks.add(task);
} else {
stackTasks.add(task);
}
}
mNumStackTasks = stackTasks.size();
mNumFreeformTasks = freeformTasks.size();
// Put each of the tasks in the progress map at a fixed index (does not need to actually
// map to a scroll position, just by index)
int taskCount = stackTasks.size();
for (int i = 0; i < taskCount; i++) {
Task task = stackTasks.get(i);
mTaskIndexMap.put(task.key.id, i);
}
// Update the freeform tasks
if (!freeformTasks.isEmpty()) {
mFreeformLayoutAlgorithm.update(freeformTasks, this);
}
// Calculate the min/max/initial scroll
Task launchTask = stack.getLaunchTarget();
int launchTaskIndex = launchTask != null ? stack.indexOfStackTask(launchTask) : mNumStackTasks - 1;
if (getInitialFocusState() == STATE_FOCUSED) {
int maxBottomOffset = mStackBottomOffset + mTaskRect.height();
float maxBottomNormX = getNormalizedXFromFocusedY(maxBottomOffset, FROM_BOTTOM);
mFocusedRange.offset(0f);
mMinScrollP = 0;
mMaxScrollP = Math.max(mMinScrollP, (mNumStackTasks - 1) - Math.max(0, mFocusedRange.getAbsoluteX(maxBottomNormX)));
if (launchState.launchedFromHome) {
mInitialScrollP = Utilities.clamp(launchTaskIndex, mMinScrollP, mMaxScrollP);
} else {
mInitialScrollP = Utilities.clamp(launchTaskIndex - 1, mMinScrollP, mMaxScrollP);
}
} else if (!ssp.hasFreeformWorkspaceSupport() && mNumStackTasks == 1) {
// If there is one stack task, ignore the min/max/initial scroll positions
mMinScrollP = 0;
mMaxScrollP = 0;
mInitialScrollP = 0;
} else {
// Set the max scroll to be the point where the front most task is visible with the
// stack bottom offset
int maxBottomOffset = mStackBottomOffset + mTaskRect.height();
float maxBottomNormX = getNormalizedXFromUnfocusedY(maxBottomOffset, FROM_BOTTOM);
mUnfocusedRange.offset(0f);
mMinScrollP = 0;
mMaxScrollP = Math.max(mMinScrollP, (mNumStackTasks - 1) - Math.max(0, mUnfocusedRange.getAbsoluteX(maxBottomNormX)));
boolean scrollToFront = launchState.launchedFromHome || launchState.launchedViaDockGesture;
if (launchState.launchedFromBlacklistedApp) {
mInitialScrollP = mMaxScrollP;
} else if (launchState.launchedWithAltTab) {
mInitialScrollP = Utilities.clamp(launchTaskIndex, mMinScrollP, mMaxScrollP);
} else if (scrollToFront) {
mInitialScrollP = Utilities.clamp(launchTaskIndex, mMinScrollP, mMaxScrollP);
} else {
// We are overriding the initial two task positions, so set the initial scroll
// position to match the second task (aka focused task) position
float initialTopNormX = getNormalizedXFromUnfocusedY(mInitialTopOffset, FROM_TOP);
mInitialScrollP = Math.max(mMinScrollP, Math.min(mMaxScrollP, (mNumStackTasks - 2)) - Math.max(0, mUnfocusedRange.getAbsoluteX(initialTopNormX)));
}
}
}
use of com.android.systemui.recents.model.Task in project android_frameworks_base by DirtyUnicorns.
the class TaskStackLayoutAlgorithm method setTaskOverridesForInitialState.
/**
* Creates task overrides to ensure the initial stack layout if necessary.
*/
public void setTaskOverridesForInitialState(TaskStack stack, boolean ignoreScrollToFront) {
RecentsActivityLaunchState launchState = Recents.getConfiguration().getLaunchState();
mTaskIndexOverrideMap.clear();
boolean scrollToFront = launchState.launchedFromHome || launchState.launchedFromBlacklistedApp || launchState.launchedViaDockGesture;
if (getInitialFocusState() == STATE_UNFOCUSED && mNumStackTasks > 1) {
if (ignoreScrollToFront || (!launchState.launchedWithAltTab && !scrollToFront)) {
// Set the initial scroll to the predefined state (which differs from the stack)
float[] initialNormX = null;
float minBottomTaskNormX = getNormalizedXFromUnfocusedY(mSystemInsets.bottom + mInitialBottomOffset, FROM_BOTTOM);
float maxBottomTaskNormX = getNormalizedXFromUnfocusedY(mFocusedTopPeekHeight + mTaskRect.height() - mMinMargin, FROM_TOP);
if (mNumStackTasks <= 2) {
// For small stacks, position the tasks so that they are top aligned to under
// the action button, but ensure that it is at least a certain offset from the
// bottom of the stack
initialNormX = new float[] { Math.min(maxBottomTaskNormX, minBottomTaskNormX), getNormalizedXFromUnfocusedY(mFocusedTopPeekHeight, FROM_TOP) };
} else {
initialNormX = new float[] { minBottomTaskNormX, getNormalizedXFromUnfocusedY(mInitialTopOffset, FROM_TOP) };
}
mUnfocusedRange.offset(0f);
List<Task> tasks = stack.getStackTasks();
int taskCount = tasks.size();
for (int i = taskCount - 1; i >= 0; i--) {
int indexFromFront = taskCount - i - 1;
if (indexFromFront >= initialNormX.length) {
break;
}
float newTaskProgress = mInitialScrollP + mUnfocusedRange.getAbsoluteX(initialNormX[indexFromFront]);
mTaskIndexOverrideMap.put(tasks.get(i).key.id, newTaskProgress);
}
}
}
}
Aggregations