blob: 48a733663fad8cda5a42d781f8f161bcf12ed503 [file] [log] [blame]
/*
* Copyright (C) 2014 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;
import android.animation.Animator;
import android.animation.ObjectAnimator;
import android.animation.PropertyValuesHolder;
import android.graphics.Rect;
import android.graphics.RectF;
import android.util.Property;
import android.view.View;
import com.android.systemui.recents.utilities.AnimationProps;
import com.android.systemui.recents.utilities.Utilities;
import java.util.ArrayList;
/**
* The visual properties for a {@link TaskView}.
*/
public class TaskViewTransform {
public static final Property<View, Rect> LTRB =
new Property<View, Rect>(Rect.class, "leftTopRightBottom") {
private Rect mTmpRect = new Rect();
@Override
public void set(View v, Rect ltrb) {
v.setLeftTopRightBottom(ltrb.left, ltrb.top, ltrb.right, ltrb.bottom);
}
@Override
public Rect get(View v) {
mTmpRect.set(v.getLeft(), v.getTop(), v.getRight(), v.getBottom());
return mTmpRect;
}
};
public float translationZ = 0;
public float scale = 1f;
public float alpha = 1f;
public float dimAlpha = 0f;
public float viewOutlineAlpha = 0f;
public boolean visible = false;
// This is a window-space rect used for positioning the task in the stack
public RectF rect = new RectF();
/**
* Fills int this transform from the state of the given TaskView.
*/
public void fillIn(TaskView tv) {
translationZ = tv.getTranslationZ();
scale = tv.getScaleX();
alpha = tv.getAlpha();
visible = true;
dimAlpha = tv.getDimAlpha();
viewOutlineAlpha = tv.getViewBounds().getAlpha();
rect.set(tv.getLeft(), tv.getTop(), tv.getRight(), tv.getBottom());
}
/**
* Copies the transform state from another {@link TaskViewTransform}.
*/
public void copyFrom(TaskViewTransform other) {
translationZ = other.translationZ;
scale = other.scale;
alpha = other.alpha;
visible = other.visible;
dimAlpha = other.dimAlpha;
viewOutlineAlpha = other.viewOutlineAlpha;
rect.set(other.rect);
}
/**
* @return whether {@param other} is the same transform as this
*/
public boolean isSame(TaskViewTransform other) {
return translationZ == other.translationZ
&& scale == other.scale
&& other.alpha == alpha
&& dimAlpha == other.dimAlpha
&& visible == other.visible
&& rect.equals(other.rect);
}
/**
* Resets the current transform.
*/
public void reset() {
translationZ = 0;
scale = 1f;
alpha = 1f;
dimAlpha = 0f;
viewOutlineAlpha = 0f;
visible = false;
rect.setEmpty();
}
/** Convenience functions to compare against current property values */
public boolean hasAlphaChangedFrom(float v) {
return (Float.compare(alpha, v) != 0);
}
public boolean hasScaleChangedFrom(float v) {
return (Float.compare(scale, v) != 0);
}
public boolean hasTranslationZChangedFrom(float v) {
return (Float.compare(translationZ, v) != 0);
}
public boolean hasRectChangedFrom(View v) {
return ((int) rect.left != v.getLeft()) || ((int) rect.right != v.getRight()) ||
((int) rect.top != v.getTop()) || ((int) rect.bottom != v.getBottom());
}
/**
* Applies this transform to a view.
*/
public void applyToTaskView(TaskView v, ArrayList<Animator> animators,
AnimationProps animation, boolean allowShadows) {
// Return early if not visible
if (!visible) {
return;
}
if (animation.isImmediate()) {
if (allowShadows && hasTranslationZChangedFrom(v.getTranslationZ())) {
v.setTranslationZ(translationZ);
}
if (hasScaleChangedFrom(v.getScaleX())) {
v.setScaleX(scale);
v.setScaleY(scale);
}
if (hasAlphaChangedFrom(v.getAlpha())) {
v.setAlpha(alpha);
}
if (hasRectChangedFrom(v)) {
v.setLeftTopRightBottom((int) rect.left, (int) rect.top, (int) rect.right,
(int) rect.bottom);
}
} else {
if (allowShadows && hasTranslationZChangedFrom(v.getTranslationZ())) {
ObjectAnimator anim = ObjectAnimator.ofFloat(v, View.TRANSLATION_Z,
v.getTranslationZ(), translationZ);
animators.add(animation.apply(AnimationProps.TRANSLATION_Z, anim));
}
if (hasScaleChangedFrom(v.getScaleX())) {
ObjectAnimator anim = ObjectAnimator.ofPropertyValuesHolder(v,
PropertyValuesHolder.ofFloat(View.SCALE_X, v.getScaleX(), scale),
PropertyValuesHolder.ofFloat(View.SCALE_Y, v.getScaleX(), scale));
animators.add(animation.apply(AnimationProps.SCALE, anim));
}
if (hasAlphaChangedFrom(v.getAlpha())) {
ObjectAnimator anim = ObjectAnimator.ofFloat(v, View.ALPHA, v.getAlpha(), alpha);
animators.add(animation.apply(AnimationProps.ALPHA, anim));
}
if (hasRectChangedFrom(v)) {
Rect fromViewRect = new Rect(v.getLeft(), v.getTop(), v.getRight(), v.getBottom());
Rect toViewRect = new Rect();
rect.round(toViewRect);
ObjectAnimator anim = ObjectAnimator.ofPropertyValuesHolder(v,
PropertyValuesHolder.ofObject(LTRB, Utilities.RECT_EVALUATOR,
fromViewRect, toViewRect));
animators.add(animation.apply(AnimationProps.BOUNDS, anim));
}
}
}
/** Reset the transform on a view. */
public static void reset(TaskView v) {
v.setTranslationX(0f);
v.setTranslationY(0f);
v.setTranslationZ(0f);
v.setScaleX(1f);
v.setScaleY(1f);
v.setAlpha(1f);
v.getViewBounds().setClipBottom(0);
v.setLeftTopRightBottom(0, 0, 0, 0);
}
@Override
public String toString() {
return "R: " + rect + " V: " + visible;
}
}