scoped_layer_animation_settings.cc revision a1401311d1ab56c4ed0a474bd38c108f75cb0cd9
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 DCHECK_EQ(static_cast<LayerAnimationElement::AnimatableProperties>( 65 LayerAnimationElement::TRANSFORM), 66 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// ScopedLayerAnimationSettings ------------------------------------------------ 81ScopedLayerAnimationSettings::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)); 92} 93 94ScopedLayerAnimationSettings::~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 112void ScopedLayerAnimationSettings::AddObserver( 113 ImplicitAnimationObserver* observer) { 114 observers_.insert(observer); 115 animator_->AddObserver(observer); 116} 117 118void ScopedLayerAnimationSettings::SetTransitionDuration( 119 base::TimeDelta duration) { 120 animator_->SetTransitionDuration(duration); 121} 122 123void ScopedLayerAnimationSettings::LockTransitionDuration() { 124 animator_->is_transition_duration_locked_ = true; 125} 126 127base::TimeDelta ScopedLayerAnimationSettings::GetTransitionDuration() const { 128 return animator_->GetTransitionDuration(); 129} 130 131void ScopedLayerAnimationSettings::SetTweenType(gfx::Tween::Type tween_type) { 132 animator_->set_tween_type(tween_type); 133} 134 135gfx::Tween::Type ScopedLayerAnimationSettings::GetTweenType() const { 136 return animator_->tween_type(); 137} 138 139void ScopedLayerAnimationSettings::SetPreemptionStrategy( 140 LayerAnimator::PreemptionStrategy strategy) { 141 animator_->set_preemption_strategy(strategy); 142} 143 144LayerAnimator::PreemptionStrategy 145ScopedLayerAnimationSettings::GetPreemptionStrategy() const { 146 return animator_->preemption_strategy(); 147} 148 149void 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 158void ScopedLayerAnimationSettings::AddInverselyAnimatedLayer( 159 Layer* inverse_layer) { 160 inverse_observer_->AddInverselyAnimatedLayer(inverse_layer); 161} 162 163} // namespace ui 164