15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/compositor/scoped_layer_animation_settings.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "ui/compositor/layer.h" 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/compositor/layer_animation_observer.h" 9d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "ui/compositor/layer_animation_sequence.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/compositor/layer_animator.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const int kDefaultTransitionDurationMs = 200; 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace ui { 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// InvertingObserver ----------------------------------------------------------- 21d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)class InvertingObserver : public ImplicitAnimationObserver { 22d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) public: 23d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) InvertingObserver() 24d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) : base_layer_(NULL) { 25d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 26d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 27d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) virtual ~InvertingObserver() {} 28d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 29d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) void SetLayer(Layer* base_layer) { base_layer_ = base_layer; } 30d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 31d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) Layer* layer() { return base_layer_; } 32d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 33d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) void AddInverselyAnimatedLayer(Layer* inverse_layer) { 34d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) inverse_layers_.push_back(inverse_layer); 35d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 36d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 37d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) virtual void OnImplicitAnimationsCompleted() OVERRIDE {} 38d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 39d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) virtual void OnLayerAnimationScheduled( 40d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) LayerAnimationSequence* sequence) OVERRIDE { 41d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) DCHECK(base_layer_ != NULL) 42d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) << "Must set base layer with ScopedLayerAnimationSettings::" 43d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) << "SetInverslyAnimatedBaseLayer"; 44d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) gfx::Transform base_transform = base_layer_->transform(); 45d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) scoped_ptr<LayerAnimationElement> inverse = GetInverseElement(sequence, 46d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) base_transform); 47d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 48d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) for (std::vector<Layer*>::const_iterator i = 49d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) inverse_layers_.begin(); i != inverse_layers_.end(); ++i) { 50d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) (*i)->GetAnimator()->StartAnimation(new LayerAnimationSequence( 51d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) LayerAnimationElement::CloneInverseTransformElement( 52d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) inverse.get()))); 53d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 54d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 55d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) private: 56d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) scoped_ptr<LayerAnimationElement> GetInverseElement( 57d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) LayerAnimationSequence* sequence, 58d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) gfx::Transform base) const { 59d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) const size_t expected_size = 1; 60d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) DCHECK_EQ(expected_size, sequence->size()) << 61d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) "Inverse supported only for single element sequences."; 62d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 63d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) LayerAnimationElement* element = sequence->FirstElement(); 645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK_EQ(static_cast<LayerAnimationElement::AnimatableProperties>( 655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) LayerAnimationElement::TRANSFORM), 665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) element->properties()) 675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) << "Only transform animations are currently invertible."; 68d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 69d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) scoped_ptr<LayerAnimationElement> to_return( 70d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) LayerAnimationElement::CreateInverseTransformElement(base, element)); 71d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return to_return.Pass(); 72d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 73d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 74d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) Layer* base_layer_; 75d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // child layers 76d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) std::vector<Layer*> inverse_layers_; 77d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)}; 78d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 79d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 80a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// ScopedLayerAnimationSettings ------------------------------------------------ 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ScopedLayerAnimationSettings::ScopedLayerAnimationSettings( 82a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) scoped_refptr<LayerAnimator> animator) 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : animator_(animator), 84a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) old_is_transition_duration_locked_( 85a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) animator->is_transition_duration_locked_), 86a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) old_transition_duration_(animator->GetTransitionDuration()), 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) old_tween_type_(animator->tween_type()), 88d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) old_preemption_strategy_(animator->preemption_strategy()), 89d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) inverse_observer_(new InvertingObserver()) { 902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SetTransitionDuration( 912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::TimeDelta::FromMilliseconds(kDefaultTransitionDurationMs)); 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ScopedLayerAnimationSettings::~ScopedLayerAnimationSettings() { 95a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) animator_->is_transition_duration_locked_ = 96a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) old_is_transition_duration_locked_; 97a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) animator_->SetTransitionDuration(old_transition_duration_); 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) animator_->set_tween_type(old_tween_type_); 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) animator_->set_preemption_strategy(old_preemption_strategy_); 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (std::set<ImplicitAnimationObserver*>::const_iterator i = 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) observers_.begin(); i != observers_.end(); ++i) { 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) animator_->observers_.RemoveObserver(*i); 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (*i)->SetActive(true); 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 106d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 107d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (inverse_observer_->layer()) { 108d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) animator_->observers_.RemoveObserver(inverse_observer_.get()); 109d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ScopedLayerAnimationSettings::AddObserver( 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ImplicitAnimationObserver* observer) { 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) observers_.insert(observer); 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) animator_->AddObserver(observer); 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ScopedLayerAnimationSettings::SetTransitionDuration( 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeDelta duration) { 120a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) animator_->SetTransitionDuration(duration); 121a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 122a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 123a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void ScopedLayerAnimationSettings::LockTransitionDuration() { 124a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) animator_->is_transition_duration_locked_ = true; 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)base::TimeDelta ScopedLayerAnimationSettings::GetTransitionDuration() const { 128a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return animator_->GetTransitionDuration(); 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 131d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)void ScopedLayerAnimationSettings::SetTweenType(gfx::Tween::Type tween_type) { 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) animator_->set_tween_type(tween_type); 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 135d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)gfx::Tween::Type ScopedLayerAnimationSettings::GetTweenType() const { 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return animator_->tween_type(); 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ScopedLayerAnimationSettings::SetPreemptionStrategy( 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LayerAnimator::PreemptionStrategy strategy) { 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) animator_->set_preemption_strategy(strategy); 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)LayerAnimator::PreemptionStrategy 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ScopedLayerAnimationSettings::GetPreemptionStrategy() const { 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return animator_->preemption_strategy(); 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 149d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)void ScopedLayerAnimationSettings::SetInverselyAnimatedBaseLayer(Layer* base) { 150d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (inverse_observer_->layer() && !base) { 151d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) animator_->RemoveObserver(inverse_observer_.get()); 152d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } else if (base && !(inverse_observer_->layer())) { 153d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) animator_->AddObserver(inverse_observer_.get()); 154d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 155d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) inverse_observer_->SetLayer(base); 156d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)} 157d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 158d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)void ScopedLayerAnimationSettings::AddInverselyAnimatedLayer( 159d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) Layer* inverse_layer) { 160d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) inverse_observer_->AddInverselyAnimatedLayer(inverse_layer); 161d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)} 162d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace ui 164