1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "ui/compositor/scoped_layer_animation_settings.h"
7 #include "ui/compositor/layer.h"
8 #include "ui/compositor/layer_animation_observer.h"
9 #include "ui/compositor/layer_animation_sequence.h"
10 #include "ui/compositor/layer_animator.h"
14 const int kDefaultTransitionDurationMs
= 200;
20 // InvertingObserver -----------------------------------------------------------
21 class InvertingObserver
: public ImplicitAnimationObserver
{
27 virtual ~InvertingObserver() {}
29 void SetLayer(Layer
* base_layer
) { base_layer_
= base_layer
; }
31 Layer
* layer() { return base_layer_
; }
33 void AddInverselyAnimatedLayer(Layer
* inverse_layer
) {
34 inverse_layers_
.push_back(inverse_layer
);
37 virtual void OnImplicitAnimationsCompleted() OVERRIDE
{}
39 virtual void OnLayerAnimationScheduled(
40 LayerAnimationSequence
* sequence
) OVERRIDE
{
41 DCHECK(base_layer_
!= NULL
)
42 << "Must set base layer with ScopedLayerAnimationSettings::"
43 << "SetInverslyAnimatedBaseLayer";
44 gfx::Transform base_transform
= base_layer_
->transform();
45 scoped_ptr
<LayerAnimationElement
> inverse
= GetInverseElement(sequence
,
48 for (std::vector
<Layer
*>::const_iterator i
=
49 inverse_layers_
.begin(); i
!= inverse_layers_
.end(); ++i
) {
50 (*i
)->GetAnimator()->StartAnimation(new LayerAnimationSequence(
51 LayerAnimationElement::CloneInverseTransformElement(
56 scoped_ptr
<LayerAnimationElement
> GetInverseElement(
57 LayerAnimationSequence
* sequence
,
58 gfx::Transform base
) const {
59 const size_t expected_size
= 1;
60 DCHECK_EQ(expected_size
, sequence
->size()) <<
61 "Inverse supported only for single element sequences.";
63 LayerAnimationElement
* element
= sequence
->FirstElement();
64 DCHECK_EQ(static_cast<LayerAnimationElement::AnimatableProperties
>(
65 LayerAnimationElement::TRANSFORM
),
66 element
->properties())
67 << "Only transform animations are currently invertible.";
69 scoped_ptr
<LayerAnimationElement
> to_return(
70 LayerAnimationElement::CreateInverseTransformElement(base
, element
));
71 return to_return
.Pass();
76 std::vector
<Layer
*> inverse_layers_
;
80 // ScopedLayerAnimationSettings ------------------------------------------------
81 ScopedLayerAnimationSettings::ScopedLayerAnimationSettings(
82 scoped_refptr
<LayerAnimator
> animator
)
83 : animator_(animator
),
84 old_is_transition_duration_locked_(
85 animator
->is_transition_duration_locked_
),
86 old_transition_duration_(animator
->GetTransitionDuration()),
87 old_tween_type_(animator
->tween_type()),
88 old_preemption_strategy_(animator
->preemption_strategy()),
89 inverse_observer_(new InvertingObserver()) {
90 SetTransitionDuration(
91 base::TimeDelta::FromMilliseconds(kDefaultTransitionDurationMs
));
94 ScopedLayerAnimationSettings::~ScopedLayerAnimationSettings() {
95 animator_
->is_transition_duration_locked_
=
96 old_is_transition_duration_locked_
;
97 animator_
->SetTransitionDuration(old_transition_duration_
);
98 animator_
->set_tween_type(old_tween_type_
);
99 animator_
->set_preemption_strategy(old_preemption_strategy_
);
101 for (std::set
<ImplicitAnimationObserver
*>::const_iterator i
=
102 observers_
.begin(); i
!= observers_
.end(); ++i
) {
103 animator_
->observers_
.RemoveObserver(*i
);
104 (*i
)->SetActive(true);
107 if (inverse_observer_
->layer()) {
108 animator_
->observers_
.RemoveObserver(inverse_observer_
.get());
112 void ScopedLayerAnimationSettings::AddObserver(
113 ImplicitAnimationObserver
* observer
) {
114 observers_
.insert(observer
);
115 animator_
->AddObserver(observer
);
118 void ScopedLayerAnimationSettings::SetTransitionDuration(
119 base::TimeDelta duration
) {
120 animator_
->SetTransitionDuration(duration
);
123 void ScopedLayerAnimationSettings::LockTransitionDuration() {
124 animator_
->is_transition_duration_locked_
= true;
127 base::TimeDelta
ScopedLayerAnimationSettings::GetTransitionDuration() const {
128 return animator_
->GetTransitionDuration();
131 void ScopedLayerAnimationSettings::SetTweenType(gfx::Tween::Type tween_type
) {
132 animator_
->set_tween_type(tween_type
);
135 gfx::Tween::Type
ScopedLayerAnimationSettings::GetTweenType() const {
136 return animator_
->tween_type();
139 void ScopedLayerAnimationSettings::SetPreemptionStrategy(
140 LayerAnimator::PreemptionStrategy strategy
) {
141 animator_
->set_preemption_strategy(strategy
);
144 LayerAnimator::PreemptionStrategy
145 ScopedLayerAnimationSettings::GetPreemptionStrategy() const {
146 return animator_
->preemption_strategy();
149 void ScopedLayerAnimationSettings::SetInverselyAnimatedBaseLayer(Layer
* base
) {
150 if (inverse_observer_
->layer() && !base
) {
151 animator_
->RemoveObserver(inverse_observer_
.get());
152 } else if (base
&& !(inverse_observer_
->layer())) {
153 animator_
->AddObserver(inverse_observer_
.get());
155 inverse_observer_
->SetLayer(base
);
158 void ScopedLayerAnimationSettings::AddInverselyAnimatedLayer(
159 Layer
* inverse_layer
) {
160 inverse_observer_
->AddInverselyAnimatedLayer(inverse_layer
);