blob: 5fd39e3f041350b21176606f0b032f57a49cc84c [file] [log] [blame]
/*
* Copyright (C) 2013 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.server.wm;
import android.graphics.Rect;
public class StackBox {
/** For use with {@link WindowManagerService#createStack} */
public static final int TASK_STACK_GOES_BEFORE = 0;
public static final int TASK_STACK_GOES_AFTER = 1;
public static final int TASK_STACK_GOES_ABOVE = 2;
public static final int TASK_STACK_GOES_BELOW = 3;
public static final int TASK_STACK_GOES_OVER = 4;
public static final int TASK_STACK_GOES_UNDER = 5;
final DisplayContent mDisplayContent;
StackBox mParent;
boolean mVertical;
StackBox mFirst;
StackBox mSecond;
float mWeight;
TaskStack mStack;
Rect mBounds;
boolean layoutNeeded;
StackBox(DisplayContent displayContent, Rect bounds) {
mDisplayContent = displayContent;
mBounds = bounds;
}
/** Propagate #layoutNeeded bottom up. */
void makeDirty() {
layoutNeeded = true;
if (mParent != null) {
mParent.makeDirty();
}
}
/** Propagate #layoutNeeded top down. */
void makeClean() {
layoutNeeded = false;
if (mFirst != null) {
mFirst.makeClean();
mSecond.makeClean();
}
}
TaskStack split(int stackId, int relativeStackId, int position, float weight) {
if (mStack != null) {
if (mStack.mStackId == relativeStackId) {
// Found it!
TaskStack stack = new TaskStack(stackId, this);
TaskStack firstStack;
TaskStack secondStack;
int width, height, split;
switch (position) {
default:
case TASK_STACK_GOES_BEFORE:
case TASK_STACK_GOES_AFTER:
mVertical = false;
width = (int)(weight * mBounds.width());
height = mBounds.height();
if (position == TASK_STACK_GOES_BEFORE) {
firstStack = stack;
secondStack = mStack;
split = mBounds.left + width;
} else {
firstStack = mStack;
secondStack = stack;
split = mBounds.right - width;
}
break;
case TASK_STACK_GOES_ABOVE:
case TASK_STACK_GOES_BELOW:
mVertical = true;
width = mBounds.width();
height = (int)(weight * mBounds.height());
if (position == TASK_STACK_GOES_ABOVE) {
firstStack = stack;
secondStack = mStack;
split = mBounds.top + height;
} else {
firstStack = mStack;
secondStack = stack;
split = mBounds.bottom - height;
}
break;
}
mFirst = new StackBox(mDisplayContent, new Rect(mBounds.left, mBounds.top,
mVertical ? mBounds.right : split, mVertical ? split : mBounds.bottom));
mFirst.mStack = firstStack;
mSecond = new StackBox(mDisplayContent, new Rect(mVertical ? mBounds.left : split,
mVertical ? split : mBounds.top, mBounds.right, mBounds.bottom));
mSecond.mStack = secondStack;
mStack = null;
return stack;
}
return null;
}
// Propagate the split to see if the target task stack is in either sub box.
TaskStack stack = mFirst.split(stackId, relativeStackId, position, weight);
if (stack != null) {
return stack;
}
return mSecond.split(stackId, relativeStackId, position, weight);
}
TaskStack merge(int position) {
TaskStack stack = null;
if (mFirst != null) {
switch (position) {
default:
case TASK_STACK_GOES_BEFORE:
case TASK_STACK_GOES_ABOVE:
stack = mFirst.merge(position);
stack.merge(mSecond.merge(position));
break;
case TASK_STACK_GOES_AFTER:
case TASK_STACK_GOES_BELOW:
stack = mSecond.merge(position);
stack.merge(mFirst.merge(position));
break;
}
return stack;
}
return mStack;
}
boolean merge(int stackId, int position, StackBox primary, StackBox secondary) {
TaskStack stack = primary.mStack;
if (stack != null && stack.mStackId == stackId) {
stack.merge(secondary.merge(position));
mStack = stack;
mFirst = null;
mSecond = null;
return true;
}
return false;
}
boolean merge(int stackId, int position) {
if (mFirst != null) {
if (merge(stackId, position, mFirst, mSecond)
|| merge(stackId, position, mSecond, mFirst)
|| mFirst.merge(stackId, position)
|| mSecond.merge(stackId, position)) {
return true;
}
}
return false;
}
void absorb(StackBox box) {
mFirst = box.mFirst;
mSecond = box.mSecond;
mStack = box.mStack;
layoutNeeded = true;
}
void removeStack() {
if (mParent != null) {
if (mParent.mFirst == this) {
mParent.absorb(mParent.mSecond);
} else {
mParent.absorb(mParent.mFirst);
}
mParent.makeDirty();
}
}
boolean addTaskToStack(Task task, int stackId, boolean toTop) {
if (mStack != null) {
if (mStack.mStackId == stackId) {
mStack.addTask(task, toTop);
return true;
}
return false;
}
return mFirst.addTaskToStack(task, stackId, toTop)
|| mSecond.addTaskToStack(task, stackId, toTop);
}
boolean resize(int stackId, float weight) {
return false;
}
}