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