blob: 98326d2fb25f83a37a850933d20ea9c8f40a32ce [file] [log] [blame]
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "ui/compositor/layer_animation_element.h"
#include "base/compiler_specific.h"
#include "ui/base/animation/tween.h"
#include "ui/compositor/layer_animation_delegate.h"
#include "ui/compositor/layer_animator.h"
#include "ui/gfx/interpolated_transform.h"
namespace ui {
namespace {
// Pause -----------------------------------------------------------------------
class Pause : public LayerAnimationElement {
public:
Pause(const AnimatableProperties& properties, base::TimeDelta duration)
: LayerAnimationElement(properties, duration) {
}
virtual ~Pause() {}
private:
virtual void OnStart(LayerAnimationDelegate* delegate) OVERRIDE {}
virtual bool OnProgress(double t,
LayerAnimationDelegate* delegate) OVERRIDE {
return false;
}
virtual void OnGetTarget(TargetValue* target) const OVERRIDE {}
virtual void OnAbort() OVERRIDE {}
DISALLOW_COPY_AND_ASSIGN(Pause);
};
// TransformTransition ---------------------------------------------------------
class TransformTransition : public LayerAnimationElement {
public:
TransformTransition(const Transform& target, base::TimeDelta duration)
: LayerAnimationElement(GetProperties(), duration),
target_(target) {
}
virtual ~TransformTransition() {}
protected:
virtual void OnStart(LayerAnimationDelegate* delegate) OVERRIDE {
start_ = delegate->GetTransformForAnimation();
}
virtual bool OnProgress(double t, LayerAnimationDelegate* delegate) OVERRIDE {
delegate->SetTransformFromAnimation(
Tween::ValueBetween(t, start_, target_));
return true;
}
virtual void OnGetTarget(TargetValue* target) const OVERRIDE {
target->transform = target_;
}
virtual void OnAbort() OVERRIDE {}
private:
static AnimatableProperties GetProperties() {
AnimatableProperties properties;
properties.insert(LayerAnimationElement::TRANSFORM);
return properties;
}
Transform start_;
const Transform target_;
DISALLOW_COPY_AND_ASSIGN(TransformTransition);
};
// InterpolatedTransformTransition ---------------------------------------------
class InterpolatedTransformTransition : public LayerAnimationElement {
public:
InterpolatedTransformTransition(InterpolatedTransform* interpolated_transform,
base::TimeDelta duration)
: LayerAnimationElement(GetProperties(), duration),
interpolated_transform_(interpolated_transform) {
}
virtual ~InterpolatedTransformTransition() {}
protected:
virtual void OnStart(LayerAnimationDelegate* delegate) OVERRIDE {
}
virtual bool OnProgress(double t, LayerAnimationDelegate* delegate) OVERRIDE {
delegate->SetTransformFromAnimation(
interpolated_transform_->Interpolate(static_cast<float>(t)));
return true;
}
virtual void OnGetTarget(TargetValue* target) const OVERRIDE {
target->transform = interpolated_transform_->Interpolate(1.0f);
}
virtual void OnAbort() OVERRIDE {}
private:
static AnimatableProperties GetProperties() {
AnimatableProperties properties;
properties.insert(LayerAnimationElement::TRANSFORM);
return properties;
}
scoped_ptr<InterpolatedTransform> interpolated_transform_;
DISALLOW_COPY_AND_ASSIGN(InterpolatedTransformTransition);
};
// BoundsTransition ------------------------------------------------------------
class BoundsTransition : public LayerAnimationElement {
public:
BoundsTransition(const gfx::Rect& target, base::TimeDelta duration)
: LayerAnimationElement(GetProperties(), duration),
target_(target) {
}
virtual ~BoundsTransition() {}
protected:
virtual void OnStart(LayerAnimationDelegate* delegate) OVERRIDE {
start_ = delegate->GetBoundsForAnimation();
}
virtual bool OnProgress(double t, LayerAnimationDelegate* delegate) OVERRIDE {
delegate->SetBoundsFromAnimation(Tween::ValueBetween(t, start_, target_));
return true;
}
virtual void OnGetTarget(TargetValue* target) const OVERRIDE {
target->bounds = target_;
}
virtual void OnAbort() OVERRIDE {}
private:
static AnimatableProperties GetProperties() {
AnimatableProperties properties;
properties.insert(LayerAnimationElement::BOUNDS);
return properties;
}
gfx::Rect start_;
const gfx::Rect target_;
DISALLOW_COPY_AND_ASSIGN(BoundsTransition);
};
// OpacityTransition -----------------------------------------------------------
class OpacityTransition : public LayerAnimationElement {
public:
OpacityTransition(float target, base::TimeDelta duration)
: LayerAnimationElement(GetProperties(), duration),
start_(0.0f),
target_(target) {
}
virtual ~OpacityTransition() {}
protected:
virtual void OnStart(LayerAnimationDelegate* delegate) OVERRIDE {
start_ = delegate->GetOpacityForAnimation();
}
virtual bool OnProgress(double t, LayerAnimationDelegate* delegate) OVERRIDE {
delegate->SetOpacityFromAnimation(Tween::ValueBetween(t, start_, target_));
return true;
}
virtual void OnGetTarget(TargetValue* target) const OVERRIDE {
target->opacity = target_;
}
virtual void OnAbort() OVERRIDE {}
private:
static AnimatableProperties GetProperties() {
AnimatableProperties properties;
properties.insert(LayerAnimationElement::OPACITY);
return properties;
}
float start_;
const float target_;
DISALLOW_COPY_AND_ASSIGN(OpacityTransition);
};
// VisibilityTransition --------------------------------------------------------
class VisibilityTransition : public LayerAnimationElement {
public:
VisibilityTransition(bool target, base::TimeDelta duration)
: LayerAnimationElement(GetProperties(), duration),
start_(false),
target_(target) {
}
virtual ~VisibilityTransition() {}
protected:
virtual void OnStart(LayerAnimationDelegate* delegate) OVERRIDE {
start_ = delegate->GetVisibilityForAnimation();
}
virtual bool OnProgress(double t, LayerAnimationDelegate* delegate) OVERRIDE {
delegate->SetVisibilityFromAnimation(t == 1.0 ? target_ : start_);
return t == 1.0;
}
virtual void OnGetTarget(TargetValue* target) const OVERRIDE {
target->visibility = target_;
}
virtual void OnAbort() OVERRIDE {}
private:
static AnimatableProperties GetProperties() {
AnimatableProperties properties;
properties.insert(LayerAnimationElement::VISIBILITY);
return properties;
}
bool start_;
const bool target_;
DISALLOW_COPY_AND_ASSIGN(VisibilityTransition);
};
// BrightnessTransition --------------------------------------------------------
class BrightnessTransition : public LayerAnimationElement {
public:
BrightnessTransition(float target, base::TimeDelta duration)
: LayerAnimationElement(GetProperties(), duration),
start_(0.0f),
target_(target) {
}
virtual ~BrightnessTransition() {}
protected:
virtual void OnStart(LayerAnimationDelegate* delegate) OVERRIDE {
start_ = delegate->GetBrightnessForAnimation();
}
virtual bool OnProgress(double t, LayerAnimationDelegate* delegate) OVERRIDE {
delegate->SetBrightnessFromAnimation(
Tween::ValueBetween(t, start_, target_));
return true;
}
virtual void OnGetTarget(TargetValue* target) const OVERRIDE {
target->brightness = target_;
}
virtual void OnAbort() OVERRIDE {}
private:
static AnimatableProperties GetProperties() {
AnimatableProperties properties;
properties.insert(LayerAnimationElement::BRIGHTNESS);
return properties;
}
float start_;
const float target_;
DISALLOW_COPY_AND_ASSIGN(BrightnessTransition);
};
// GrayscaleTransition ---------------------------------------------------------
class GrayscaleTransition : public LayerAnimationElement {
public:
GrayscaleTransition(float target, base::TimeDelta duration)
: LayerAnimationElement(GetProperties(), duration),
start_(0.0f),
target_(target) {
}
virtual ~GrayscaleTransition() {}
protected:
virtual void OnStart(LayerAnimationDelegate* delegate) OVERRIDE {
start_ = delegate->GetGrayscaleForAnimation();
}
virtual bool OnProgress(double t, LayerAnimationDelegate* delegate) OVERRIDE {
delegate->SetGrayscaleFromAnimation(
Tween::ValueBetween(t, start_, target_));
return true;
}
virtual void OnGetTarget(TargetValue* target) const OVERRIDE {
target->grayscale = target_;
}
virtual void OnAbort() OVERRIDE {}
private:
static AnimatableProperties GetProperties() {
AnimatableProperties properties;
properties.insert(LayerAnimationElement::GRAYSCALE);
return properties;
}
float start_;
const float target_;
DISALLOW_COPY_AND_ASSIGN(GrayscaleTransition);
};
} // namespace
// LayerAnimationElement::TargetValue ------------------------------------------
LayerAnimationElement::TargetValue::TargetValue()
: opacity(0.0f),
visibility(false),
brightness(0.0f),
grayscale(0.0f) {
}
LayerAnimationElement::TargetValue::TargetValue(
const LayerAnimationDelegate* delegate)
: bounds(delegate ? delegate->GetBoundsForAnimation() : gfx::Rect()),
transform(delegate ? delegate->GetTransformForAnimation() : Transform()),
opacity(delegate ? delegate->GetOpacityForAnimation() : 0.0f),
visibility(delegate ? delegate->GetVisibilityForAnimation() : false),
brightness(delegate ? delegate->GetBrightnessForAnimation() : 0.0f),
grayscale(delegate ? delegate->GetGrayscaleForAnimation() : 0.0f) {
}
// LayerAnimationElement -------------------------------------------------------
LayerAnimationElement::LayerAnimationElement(
const AnimatableProperties& properties,
base::TimeDelta duration)
: first_frame_(true),
properties_(properties),
duration_(GetEffectiveDuration(duration)),
tween_type_(Tween::LINEAR) {
}
LayerAnimationElement::~LayerAnimationElement() {
}
bool LayerAnimationElement::Progress(double t,
LayerAnimationDelegate* delegate) {
if (first_frame_)
OnStart(delegate);
bool need_draw = OnProgress(Tween::CalculateValue(tween_type_, t), delegate);
first_frame_ = t == 1.0;
return need_draw;
}
void LayerAnimationElement::GetTargetValue(TargetValue* target) const {
OnGetTarget(target);
}
void LayerAnimationElement::Abort() {
first_frame_ = true;
OnAbort();
}
// static
base::TimeDelta LayerAnimationElement::GetEffectiveDuration(
const base::TimeDelta& duration) {
if (LayerAnimator::disable_animations_for_test())
return base::TimeDelta();
if (LayerAnimator::slow_animation_mode())
return duration * LayerAnimator::slow_animation_scale_factor();
return duration;
}
// static
LayerAnimationElement* LayerAnimationElement::CreateTransformElement(
const Transform& transform, base::TimeDelta duration) {
return new TransformTransition(transform, duration);
}
// static
LayerAnimationElement*
LayerAnimationElement::CreateInterpolatedTransformElement(
InterpolatedTransform* interpolated_transform, base::TimeDelta duration) {
return new InterpolatedTransformTransition(interpolated_transform, duration);
}
// static
LayerAnimationElement* LayerAnimationElement::CreateBoundsElement(
const gfx::Rect& bounds, base::TimeDelta duration) {
return new BoundsTransition(bounds, duration);
}
// static
LayerAnimationElement* LayerAnimationElement::CreateOpacityElement(
float opacity, base::TimeDelta duration) {
return new OpacityTransition(opacity, duration);
}
// static
LayerAnimationElement* LayerAnimationElement::CreateVisibilityElement(
bool visibility, base::TimeDelta duration) {
return new VisibilityTransition(visibility, duration);
}
// static
LayerAnimationElement* LayerAnimationElement::CreateBrightnessElement(
float brightness, base::TimeDelta duration) {
return new BrightnessTransition(brightness, duration);
}
// static
LayerAnimationElement* LayerAnimationElement::CreateGrayscaleElement(
float grayscale, base::TimeDelta duration) {
return new GrayscaleTransition(grayscale, duration);
}
// static
LayerAnimationElement* LayerAnimationElement::CreatePauseElement(
const AnimatableProperties& properties, base::TimeDelta duration) {
return new Pause(properties, duration);
}
} // namespace ui