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.
5 #include "ash/rotator/screen_rotation.h"
7 #include "base/debug/trace_event.h"
9 #include "ui/compositor/layer_animation_delegate.h"
10 #include "ui/gfx/interpolated_transform.h"
11 #include "ui/gfx/rect.h"
12 #include "ui/gfx/transform.h"
18 const int k90DegreeTransitionDurationMs
= 350;
19 const int k180DegreeTransitionDurationMs
= 550;
20 const int k360DegreeTransitionDurationMs
= 750;
22 base::TimeDelta
GetTransitionDuration(int degrees
) {
24 return base::TimeDelta::FromMilliseconds(k360DegreeTransitionDurationMs
);
26 return base::TimeDelta::FromMilliseconds(k180DegreeTransitionDurationMs
);
28 return base::TimeDelta::FromMilliseconds(0);
29 return base::TimeDelta::FromMilliseconds(k90DegreeTransitionDurationMs
);
34 ScreenRotation::ScreenRotation(int degrees
)
35 : ui::LayerAnimationElement(GetProperties(),
36 GetTransitionDuration(degrees
)),
40 ScreenRotation::~ScreenRotation() {
43 void ScreenRotation::OnStart(ui::LayerAnimationDelegate
* delegate
) {
44 // No rotation required.
48 const ui::Transform
& current_transform
=
49 delegate
->GetTransformForAnimation();
50 const gfx::Rect
& bounds
= delegate
->GetBoundsForAnimation();
55 int width
= bounds
.width();
56 int height
= bounds
.height();
60 new_origin_
= new_pivot
= gfx::Point(width
, 0);
63 new_origin_
= new_pivot
= gfx::Point(0, height
);
67 new_pivot
= old_pivot
= gfx::Point(width
/ 2, height
/ 2);
68 new_origin_
.SetPoint(width
, height
);
72 // Convert points to world space.
73 current_transform
.TransformPoint(old_pivot
);
74 current_transform
.TransformPoint(new_pivot
);
75 current_transform
.TransformPoint(new_origin_
);
77 scoped_ptr
<ui::InterpolatedTransform
> rotation(
78 new ui::InterpolatedTransformAboutPivot(
80 new ui::InterpolatedRotation(0, degrees_
)));
82 scoped_ptr
<ui::InterpolatedTransform
> translation(
83 new ui::InterpolatedTranslation(
85 gfx::Point(new_pivot
.x() - old_pivot
.x(),
86 new_pivot
.y() - old_pivot
.y())));
88 float scale_factor
= 0.9f
;
89 scoped_ptr
<ui::InterpolatedTransform
> scale_down(
90 new ui::InterpolatedScale(1.0f
, scale_factor
, 0.0f
, 0.5f
));
92 scoped_ptr
<ui::InterpolatedTransform
> scale_up(
93 new ui::InterpolatedScale(1.0f
, 1.0f
/ scale_factor
, 0.5f
, 1.0f
));
95 interpolated_transform_
.reset(
96 new ui::InterpolatedConstantTransform(current_transform
));
98 scale_up
->SetChild(scale_down
.release());
99 translation
->SetChild(scale_up
.release());
100 rotation
->SetChild(translation
.release());
101 interpolated_transform_
->SetChild(rotation
.release());
104 bool ScreenRotation::OnProgress(double t
,
105 ui::LayerAnimationDelegate
* delegate
) {
106 delegate
->SetTransformFromAnimation(interpolated_transform_
->Interpolate(t
));
110 void ScreenRotation::OnGetTarget(TargetValue
* target
) const {
111 target
->transform
= interpolated_transform_
->Interpolate(1.0);
114 void ScreenRotation::OnAbort() {
118 const ui::LayerAnimationElement::AnimatableProperties
&
119 ScreenRotation::GetProperties() {
120 static ui::LayerAnimationElement::AnimatableProperties properties
;
121 if (properties
.empty())
122 properties
.insert(ui::LayerAnimationElement::TRANSFORM
);