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 ~InvertingObserver() override
{}
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 void OnImplicitAnimationsCompleted() override
{}
39 void OnLayerAnimationScheduled(LayerAnimationSequence
* sequence
) override
{
40 DCHECK(base_layer_
!= NULL
)
41 << "Must set base layer with ScopedLayerAnimationSettings::"
42 << "SetInverslyAnimatedBaseLayer";
43 gfx::Transform base_transform
= base_layer_
->transform();
44 scoped_ptr
<LayerAnimationElement
> inverse
= GetInverseElement(sequence
,
47 for (std::vector
<Layer
*>::const_iterator i
=
48 inverse_layers_
.begin(); i
!= inverse_layers_
.end(); ++i
) {
49 (*i
)->GetAnimator()->StartAnimation(new LayerAnimationSequence(
50 LayerAnimationElement::CloneInverseTransformElement(
55 scoped_ptr
<LayerAnimationElement
> GetInverseElement(
56 LayerAnimationSequence
* sequence
,
57 gfx::Transform base
) const {
58 const size_t expected_size
= 1;
59 DCHECK_EQ(expected_size
, sequence
->size()) <<
60 "Inverse supported only for single element sequences.";
62 LayerAnimationElement
* element
= sequence
->FirstElement();
63 DCHECK_EQ(static_cast<LayerAnimationElement::AnimatableProperties
>(
64 LayerAnimationElement::TRANSFORM
),
65 element
->properties())
66 << "Only transform animations are currently invertible.";
68 scoped_ptr
<LayerAnimationElement
> to_return(
69 LayerAnimationElement::CreateInverseTransformElement(base
, element
));
70 return to_return
.Pass();
75 std::vector
<Layer
*> inverse_layers_
;
79 // ScopedLayerAnimationSettings ------------------------------------------------
80 ScopedLayerAnimationSettings::ScopedLayerAnimationSettings(
81 scoped_refptr
<LayerAnimator
> animator
)
82 : animator_(animator
),
83 old_is_transition_duration_locked_(
84 animator
->is_transition_duration_locked_
),
85 old_transition_duration_(animator
->GetTransitionDuration()),
86 old_tween_type_(animator
->tween_type()),
87 old_preemption_strategy_(animator
->preemption_strategy()),
88 inverse_observer_(new InvertingObserver()) {
89 SetTransitionDuration(
90 base::TimeDelta::FromMilliseconds(kDefaultTransitionDurationMs
));
93 ScopedLayerAnimationSettings::~ScopedLayerAnimationSettings() {
94 animator_
->is_transition_duration_locked_
=
95 old_is_transition_duration_locked_
;
96 animator_
->SetTransitionDuration(old_transition_duration_
);
97 animator_
->set_tween_type(old_tween_type_
);
98 animator_
->set_preemption_strategy(old_preemption_strategy_
);
100 for (std::set
<ImplicitAnimationObserver
*>::const_iterator i
=
101 observers_
.begin(); i
!= observers_
.end(); ++i
) {
102 animator_
->observers_
.RemoveObserver(*i
);
103 (*i
)->SetActive(true);
106 if (inverse_observer_
->layer()) {
107 animator_
->observers_
.RemoveObserver(inverse_observer_
.get());
111 void ScopedLayerAnimationSettings::AddObserver(
112 ImplicitAnimationObserver
* observer
) {
113 observers_
.insert(observer
);
114 animator_
->AddObserver(observer
);
117 void ScopedLayerAnimationSettings::SetTransitionDuration(
118 base::TimeDelta duration
) {
119 animator_
->SetTransitionDuration(duration
);
122 void ScopedLayerAnimationSettings::LockTransitionDuration() {
123 animator_
->is_transition_duration_locked_
= true;
126 base::TimeDelta
ScopedLayerAnimationSettings::GetTransitionDuration() const {
127 return animator_
->GetTransitionDuration();
130 void ScopedLayerAnimationSettings::SetTweenType(gfx::Tween::Type tween_type
) {
131 animator_
->set_tween_type(tween_type
);
134 gfx::Tween::Type
ScopedLayerAnimationSettings::GetTweenType() const {
135 return animator_
->tween_type();
138 void ScopedLayerAnimationSettings::SetPreemptionStrategy(
139 LayerAnimator::PreemptionStrategy strategy
) {
140 animator_
->set_preemption_strategy(strategy
);
143 LayerAnimator::PreemptionStrategy
144 ScopedLayerAnimationSettings::GetPreemptionStrategy() const {
145 return animator_
->preemption_strategy();
148 void ScopedLayerAnimationSettings::SetInverselyAnimatedBaseLayer(Layer
* base
) {
149 if (inverse_observer_
->layer() && !base
) {
150 animator_
->RemoveObserver(inverse_observer_
.get());
151 } else if (base
&& !(inverse_observer_
->layer())) {
152 animator_
->AddObserver(inverse_observer_
.get());
154 inverse_observer_
->SetLayer(base
);
157 void ScopedLayerAnimationSettings::AddInverselyAnimatedLayer(
158 Layer
* inverse_layer
) {
159 inverse_observer_
->AddInverselyAnimatedLayer(inverse_layer
);