scoped_layer_animation_settings.cc revision d0247b1b59f9c528cb6df88b4f2b9afaf80d181e
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 12namespace { 13 14const int kDefaultTransitionDurationMs = 200; 15 16} // namespace 17 18namespace ui { 19 20// InvertingObserver ----------------------------------------------------------- 21class 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 ------------------------------------------------ 81ScopedLayerAnimationSettings::ScopedLayerAnimationSettings( 82 LayerAnimator* animator) 83 : animator_(animator), 84 old_transition_duration_(animator->transition_duration_), 85 old_tween_type_(animator->tween_type()), 86 old_preemption_strategy_(animator->preemption_strategy()), 87 inverse_observer_(new InvertingObserver()) { 88 SetTransitionDuration( 89 base::TimeDelta::FromMilliseconds(kDefaultTransitionDurationMs)); 90} 91 92ScopedLayerAnimationSettings::~ScopedLayerAnimationSettings() { 93 animator_->transition_duration_ = old_transition_duration_; 94 animator_->set_tween_type(old_tween_type_); 95 animator_->set_preemption_strategy(old_preemption_strategy_); 96 97 for (std::set<ImplicitAnimationObserver*>::const_iterator i = 98 observers_.begin(); i != observers_.end(); ++i) { 99 animator_->observers_.RemoveObserver(*i); 100 (*i)->SetActive(true); 101 } 102 103 if (inverse_observer_->layer()) { 104 animator_->observers_.RemoveObserver(inverse_observer_.get()); 105 } 106} 107 108void ScopedLayerAnimationSettings::AddObserver( 109 ImplicitAnimationObserver* observer) { 110 observers_.insert(observer); 111 animator_->AddObserver(observer); 112} 113 114void ScopedLayerAnimationSettings::SetTransitionDuration( 115 base::TimeDelta duration) { 116 animator_->transition_duration_ = duration; 117} 118 119base::TimeDelta ScopedLayerAnimationSettings::GetTransitionDuration() const { 120 return animator_->transition_duration_; 121} 122 123void ScopedLayerAnimationSettings::SetTweenType(gfx::Tween::Type tween_type) { 124 animator_->set_tween_type(tween_type); 125} 126 127gfx::Tween::Type ScopedLayerAnimationSettings::GetTweenType() const { 128 return animator_->tween_type(); 129} 130 131void ScopedLayerAnimationSettings::SetPreemptionStrategy( 132 LayerAnimator::PreemptionStrategy strategy) { 133 animator_->set_preemption_strategy(strategy); 134} 135 136LayerAnimator::PreemptionStrategy 137ScopedLayerAnimationSettings::GetPreemptionStrategy() const { 138 return animator_->preemption_strategy(); 139} 140 141void ScopedLayerAnimationSettings::SetInverselyAnimatedBaseLayer(Layer* base) { 142 if (inverse_observer_->layer() && !base) { 143 animator_->RemoveObserver(inverse_observer_.get()); 144 } else if (base && !(inverse_observer_->layer())) { 145 animator_->AddObserver(inverse_observer_.get()); 146 } 147 inverse_observer_->SetLayer(base); 148} 149 150void ScopedLayerAnimationSettings::AddInverselyAnimatedLayer( 151 Layer* inverse_layer) { 152 inverse_observer_->AddInverselyAnimatedLayer(inverse_layer); 153} 154 155} // namespace ui 156