| // Copyright 2015 The Chromium Authors | 
 | // Use of this source code is governed by a BSD-style license that can be | 
 | // found in the LICENSE file. | 
 |  | 
 | #include "ash/rotator/screen_rotation_animation.h" | 
 |  | 
 | #include <memory> | 
 |  | 
 | #include "base/time/time.h" | 
 | #include "ui/compositor/layer.h" | 
 | #include "ui/compositor/layer_animation_delegate.h" | 
 | #include "ui/gfx/animation/tween.h" | 
 | #include "ui/gfx/geometry/point.h" | 
 | #include "ui/gfx/geometry/transform.h" | 
 | #include "ui/gfx/interpolated_transform.h" | 
 |  | 
 | namespace ash { | 
 |  | 
 | ScreenRotationAnimation::ScreenRotationAnimation(ui::Layer* layer, | 
 |                                                  int start_degrees, | 
 |                                                  int end_degrees, | 
 |                                                  float initial_opacity, | 
 |                                                  float target_opacity, | 
 |                                                  gfx::Point pivot, | 
 |                                                  base::TimeDelta duration, | 
 |                                                  gfx::Tween::Type tween_type) | 
 |     : ui::LayerAnimationElement( | 
 |           LayerAnimationElement::TRANSFORM | LayerAnimationElement::OPACITY, | 
 |           duration), | 
 |       tween_type_(tween_type), | 
 |       initial_opacity_(initial_opacity), | 
 |       target_opacity_(target_opacity) { | 
 |   std::unique_ptr<ui::InterpolatedTransform> rotation = | 
 |       std::make_unique<ui::InterpolatedTransformAboutPivot>( | 
 |           pivot, std::make_unique<ui::InterpolatedRotation>(start_degrees, | 
 |                                                             end_degrees)); | 
 |  | 
 |   // Use the target transform/bounds in case the layer is already animating. | 
 |   gfx::Transform current_transform = layer->GetTargetTransform(); | 
 |   interpolated_transform_ = | 
 |       std::make_unique<ui::InterpolatedConstantTransform>(current_transform); | 
 |   interpolated_transform_->SetChild(std::move(rotation)); | 
 | } | 
 |  | 
 | ScreenRotationAnimation::~ScreenRotationAnimation() = default; | 
 |  | 
 | void ScreenRotationAnimation::OnStart(ui::LayerAnimationDelegate* delegate) {} | 
 |  | 
 | bool ScreenRotationAnimation::OnProgress(double current, | 
 |                                          ui::LayerAnimationDelegate* delegate) { | 
 |   const double tweened = gfx::Tween::CalculateValue(tween_type_, current); | 
 |   delegate->SetTransformFromAnimation( | 
 |       interpolated_transform_->Interpolate(tweened), | 
 |       ui::PropertyChangeReason::FROM_ANIMATION); | 
 |   delegate->SetOpacityFromAnimation( | 
 |       gfx::Tween::FloatValueBetween(tweened, initial_opacity_, target_opacity_), | 
 |       ui::PropertyChangeReason::FROM_ANIMATION); | 
 |   return true; | 
 | } | 
 |  | 
 | void ScreenRotationAnimation::OnGetTarget(TargetValue* target) const { | 
 |   target->transform = interpolated_transform_->Interpolate(1.0); | 
 | } | 
 |  | 
 | void ScreenRotationAnimation::OnAbort(ui::LayerAnimationDelegate* delegate) { | 
 |   // ui::Layer's d'tor passes its ui::LayerAnimator a null delegate before | 
 |   // deleting it. This is then passed here: http://crbug.com/661313 | 
 |   if (!delegate) | 
 |     return; | 
 |  | 
 |   TargetValue target_value; | 
 |   OnGetTarget(&target_value); | 
 |   delegate->SetTransformFromAnimation(target_value.transform, | 
 |                                       ui::PropertyChangeReason::FROM_ANIMATION); | 
 | } | 
 |  | 
 | }  // namespace ash |