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: 23 InvertingObserver() 24 : base_layer_(NULL) { 25 } 26 27 virtual ~InvertingObserver() {} 28 29 void SetLayer(Layer* base_layer) { base_layer_ = base_layer; } 30 31 Layer* layer() { return base_layer_; } 32 33 void AddInverselyAnimatedLayer(Layer* inverse_layer) { 34 inverse_layers_.push_back(inverse_layer); 35 } 36 37 virtual void OnImplicitAnimationsCompleted() OVERRIDE {} 38 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: 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."; 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 ------------------------------------------------ 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 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 112 void ScopedLayerAnimationSettings::AddObserver( 113 ImplicitAnimationObserver* observer) { 114 observers_.insert(observer); 115 animator_->AddObserver(observer); 116 } 117 118 void ScopedLayerAnimationSettings::SetTransitionDuration( 119 base::TimeDelta duration) { 120 animator_->SetTransitionDuration(duration); 121 } 122 123 void ScopedLayerAnimationSettings::LockTransitionDuration() { 124 animator_->is_transition_duration_locked_ = true; 125 } 126 127 base::TimeDelta ScopedLayerAnimationSettings::GetTransitionDuration() const { 128 return animator_->GetTransitionDuration(); 129 } 130 131 void ScopedLayerAnimationSettings::SetTweenType(gfx::Tween::Type tween_type) { 132 animator_->set_tween_type(tween_type); 133 } 134 135 gfx::Tween::Type ScopedLayerAnimationSettings::GetTweenType() const { 136 return animator_->tween_type(); 137 } 138 139 void ScopedLayerAnimationSettings::SetPreemptionStrategy( 140 LayerAnimator::PreemptionStrategy strategy) { 141 animator_->set_preemption_strategy(strategy); 142 } 143 144 LayerAnimator::PreemptionStrategy 145 ScopedLayerAnimationSettings::GetPreemptionStrategy() const { 146 return animator_->preemption_strategy(); 147 } 148 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 158 void ScopedLayerAnimationSettings::AddInverselyAnimatedLayer( 159 Layer* inverse_layer) { 160 inverse_observer_->AddInverselyAnimatedLayer(inverse_layer); 161 } 162 163 } // namespace ui 164