// 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