• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.
4 
5 #include "ui/compositor/scoped_layer_animation_settings.h"
6 
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"
11 
12 namespace {
13 
14 const int kDefaultTransitionDurationMs = 200;
15 
16 }  // namespace
17 
18 namespace ui {
19 
20 // InvertingObserver -----------------------------------------------------------
21 class InvertingObserver : public ImplicitAnimationObserver {
22   public:
InvertingObserver()23     InvertingObserver()
24       : base_layer_(NULL) {
25     }
26 
~InvertingObserver()27     virtual ~InvertingObserver() {}
28 
SetLayer(Layer * base_layer)29     void SetLayer(Layer* base_layer) { base_layer_ = base_layer; }
30 
layer()31     Layer* layer() { return base_layer_; }
32 
AddInverselyAnimatedLayer(Layer * inverse_layer)33     void AddInverselyAnimatedLayer(Layer* inverse_layer) {
34       inverse_layers_.push_back(inverse_layer);
35     }
36 
OnImplicitAnimationsCompleted()37     virtual void OnImplicitAnimationsCompleted() OVERRIDE {}
38 
OnLayerAnimationScheduled(LayerAnimationSequence * sequence)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,
46           base_transform);
47 
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(
52                 inverse.get())));
53       }
54     }
55   private:
GetInverseElement(LayerAnimationSequence * sequence,gfx::Transform base) const56     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.";
62 
63       LayerAnimationElement* element = sequence->FirstElement();
64       LayerAnimationElement::AnimatableProperties transform_property;
65       transform_property.insert(LayerAnimationElement::TRANSFORM);
66       DCHECK(transform_property == element->properties())
67         << "Only transform animations are currently invertible.";
68 
69       scoped_ptr<LayerAnimationElement> to_return(
70           LayerAnimationElement::CreateInverseTransformElement(base, element));
71       return to_return.Pass();
72     }
73 
74     Layer* base_layer_;
75     // child layers
76     std::vector<Layer*> inverse_layers_;
77 };
78 
79 
80 // ScoperLayerAnimationSettings ------------------------------------------------
ScopedLayerAnimationSettings(LayerAnimator * animator)81 ScopedLayerAnimationSettings::ScopedLayerAnimationSettings(
82     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));
92 }
93 
~ScopedLayerAnimationSettings()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_);
100 
101   for (std::set<ImplicitAnimationObserver*>::const_iterator i =
102        observers_.begin(); i != observers_.end(); ++i) {
103     animator_->observers_.RemoveObserver(*i);
104     (*i)->SetActive(true);
105   }
106 
107   if (inverse_observer_->layer()) {
108     animator_->observers_.RemoveObserver(inverse_observer_.get());
109   }
110 }
111 
AddObserver(ImplicitAnimationObserver * observer)112 void ScopedLayerAnimationSettings::AddObserver(
113     ImplicitAnimationObserver* observer) {
114   observers_.insert(observer);
115   animator_->AddObserver(observer);
116 }
117 
SetTransitionDuration(base::TimeDelta duration)118 void ScopedLayerAnimationSettings::SetTransitionDuration(
119     base::TimeDelta duration) {
120   animator_->SetTransitionDuration(duration);
121 }
122 
LockTransitionDuration()123 void ScopedLayerAnimationSettings::LockTransitionDuration() {
124   animator_->is_transition_duration_locked_ = true;
125 }
126 
GetTransitionDuration() const127 base::TimeDelta ScopedLayerAnimationSettings::GetTransitionDuration() const {
128   return animator_->GetTransitionDuration();
129 }
130 
SetTweenType(gfx::Tween::Type tween_type)131 void ScopedLayerAnimationSettings::SetTweenType(gfx::Tween::Type tween_type) {
132   animator_->set_tween_type(tween_type);
133 }
134 
GetTweenType() const135 gfx::Tween::Type ScopedLayerAnimationSettings::GetTweenType() const {
136   return animator_->tween_type();
137 }
138 
SetPreemptionStrategy(LayerAnimator::PreemptionStrategy strategy)139 void ScopedLayerAnimationSettings::SetPreemptionStrategy(
140     LayerAnimator::PreemptionStrategy strategy) {
141   animator_->set_preemption_strategy(strategy);
142 }
143 
144 LayerAnimator::PreemptionStrategy
GetPreemptionStrategy() const145 ScopedLayerAnimationSettings::GetPreemptionStrategy() const {
146   return animator_->preemption_strategy();
147 }
148 
SetInverselyAnimatedBaseLayer(Layer * base)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());
154   }
155   inverse_observer_->SetLayer(base);
156 }
157 
AddInverselyAnimatedLayer(Layer * inverse_layer)158 void ScopedLayerAnimationSettings::AddInverselyAnimatedLayer(
159     Layer* inverse_layer) {
160   inverse_observer_->AddInverselyAnimatedLayer(inverse_layer);
161 }
162 
163 }  // namespace ui
164