Home | History | Annotate | Download | only in compositor
      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