OLD | NEW |
---|---|
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/ui/touch/animation/screen_rotation.h" | 5 #include "chrome/browser/ui/touch/animation/screen_rotation.h" |
6 | 6 |
7 #include "base/debug/trace_event.h" | 7 #include "base/debug/trace_event.h" |
8 #include "base/message_loop.h" | 8 #include "base/message_loop.h" |
9 #include "base/task.h" | 9 #include "base/task.h" |
10 #include "ui/base/animation/slide_animation.h" | 10 #include "ui/base/animation/slide_animation.h" |
11 #include "ui/gfx/compositor/layer.h" | 11 #include "ui/gfx/compositor/layer.h" |
12 #include "ui/gfx/compositor/layer_animation_delegate.h" | |
12 #include "ui/gfx/interpolated_transform.h" | 13 #include "ui/gfx/interpolated_transform.h" |
13 #include "ui/gfx/rect.h" | 14 #include "ui/gfx/rect.h" |
14 #include "ui/gfx/transform.h" | 15 #include "ui/gfx/transform.h" |
15 #include "views/paint_lock.h" | 16 #include "views/paint_lock.h" |
16 #include "views/view.h" | 17 #include "views/view.h" |
17 #include "views/widget/widget.h" | 18 #include "views/widget/widget.h" |
18 | 19 |
19 namespace { | 20 namespace { |
20 const int kDefaultTransitionDurationMs = 350; | 21 const int kDefaultTransitionDurationMs = 350; |
21 | |
22 } // namespace | 22 } // namespace |
23 | 23 |
24 //////////////////////////////////////////////////////////////////////////////// | 24 //////////////////////////////////////////////////////////////////////////////// |
25 // ScreenRotationListener public: | 25 // ScreenRotationListener public: |
26 // | 26 // |
27 | 27 |
28 ScreenRotationListener::~ScreenRotationListener() { | 28 ScreenRotationListener::~ScreenRotationListener() { |
29 } | 29 } |
30 | 30 |
31 //////////////////////////////////////////////////////////////////////////////// | 31 //////////////////////////////////////////////////////////////////////////////// |
32 // ScreenRotation public: | 32 // ScreenRotation public: |
33 // | 33 // |
34 | 34 |
35 ScreenRotation::ScreenRotation(views::View* view, | 35 ScreenRotation::ScreenRotation(views::View* view, |
36 ui::LayerAnimationDelegate* delegate, | |
36 ScreenRotationListener* listener, | 37 ScreenRotationListener* listener, |
37 float old_degrees, | 38 float old_degrees, |
38 float new_degrees) | 39 float new_degrees) |
39 : view_(view), | 40 : view_(view), |
41 delegate_(delegate), | |
40 widget_(view->GetWidget()), | 42 widget_(view->GetWidget()), |
41 listener_(listener), | 43 listener_(listener), |
42 old_degrees_(old_degrees), | 44 old_degrees_(old_degrees), |
43 new_degrees_(new_degrees), | 45 new_degrees_(new_degrees), |
44 duration_(kDefaultTransitionDurationMs), | 46 duration_(kDefaultTransitionDurationMs), |
45 animation_started_(false), | 47 animation_started_(false), |
46 animation_stopped_(false) { | 48 animation_stopped_(false) { |
47 DCHECK(view); | 49 DCHECK(view); |
48 DCHECK(listener); | 50 DCHECK(listener); |
49 | 51 |
50 if (!view->layer() || !widget_) { | 52 if (!view->layer() || !widget_) { |
51 Finalize(); | 53 Finalize(); |
52 } else { | 54 } else { |
53 // Screen rotations are trigged as a result of a call to SetTransform which | 55 // Screen rotations are trigged as a result of a call to SetTransform which |
54 // causes a paint to be scheduled to occur. At this point, the paint has | 56 // causes a paint to be scheduled to occur. At this point, the paint has |
55 // been scheduled, but has not yet been started. We will listen for this | 57 // been scheduled, but has not yet been started. We will listen for this |
56 // paint to be completed before we start animating. | 58 // paint to be completed before we start animating. |
57 view->layer()->GetCompositor()->AddObserver(this); | 59 view->layer()->GetCompositor()->AddObserver(this); |
58 } | 60 } |
59 } | 61 } |
60 | 62 |
61 ScreenRotation::~ScreenRotation() { | 63 ScreenRotation::~ScreenRotation() { |
62 if (view_->layer()) | 64 if (view_->layer()) |
63 view_->layer()->GetCompositor()->RemoveObserver(this); | 65 view_->layer()->GetCompositor()->RemoveObserver(this); |
64 } | 66 } |
65 | 67 |
66 void ScreenRotation::Stop() { | 68 void ScreenRotation::Stop() { |
67 animation_.reset(); | 69 animation_.reset(); |
68 if (view_->layer()) { | 70 if (delegate_) { |
69 if (!interpolated_transform_.get()) { | 71 if (!interpolated_transform_.get()) { |
70 // attempt to initialize. | 72 // attempt to initialize. |
71 Init(); | 73 Init(); |
72 } | 74 } |
73 if (interpolated_transform_.get()) { | 75 if (interpolated_transform_.get()) { |
74 view_->layer()->SetTransform(interpolated_transform_->Interpolate(1.0)); | 76 delegate_->SetTransformFromAnimation( |
75 view_->GetWidget()->SchedulePaintInRect( | 77 interpolated_transform_->Interpolate(1.0)); |
76 view_->GetWidget()->GetClientAreaScreenBounds()); | 78 delegate_->ScheduleDrawForAnimation(); |
77 } | 79 } |
78 } | 80 } |
79 Finalize(); | 81 Finalize(); |
80 } | 82 } |
81 | 83 |
82 //////////////////////////////////////////////////////////////////////////////// | 84 //////////////////////////////////////////////////////////////////////////////// |
83 // ScreenRotation private: | 85 // ScreenRotation private: |
84 // | 86 // |
85 | 87 |
86 void ScreenRotation::AnimationProgressed(const ui::Animation* anim) { | 88 void ScreenRotation::AnimationProgressed(const ui::Animation* anim) { |
87 TRACE_EVENT0("ScreenRotation", "step"); | 89 TRACE_EVENT0("ScreenRotation", "step"); |
88 view_->layer()->SetTransform(interpolated_transform_->Interpolate( | 90 delegate_->SetTransformFromAnimation( |
89 anim->GetCurrentValue())); | 91 interpolated_transform_->Interpolate(anim->GetCurrentValue())); |
90 widget_->SchedulePaintInRect(widget_->GetClientAreaScreenBounds()); | 92 delegate_->ScheduleDrawForAnimation(); |
91 } | 93 } |
92 | 94 |
93 void ScreenRotation::AnimationEnded(const ui::Animation* anim) { | 95 void ScreenRotation::AnimationEnded(const ui::Animation* anim) { |
94 TRACE_EVENT_END0("ScreenRotation", "ScreenRotation"); | 96 TRACE_EVENT_END0("ScreenRotation", "ScreenRotation"); |
95 // TODO(vollick) massage matrix so that entries sufficiently close | 97 // TODO(vollick) massage matrix so that entries sufficiently close |
96 // to 0, 1, or -1 are clamped to these values. The idea is to fight | 98 // to 0, 1, or -1 are clamped to these values. The idea is to fight |
97 // accumulated numeric error due to successive rotations. | 99 // accumulated numeric error due to successive rotations. |
98 ui::Transform xform = view_->layer()->transform(); | 100 ui::Transform xform = view_->layer()->transform(); |
99 gfx::Point origin; | 101 gfx::Point origin; |
100 xform.TransformPoint(origin); | 102 xform.TransformPoint(origin); |
101 ui::Transform translation; | 103 ui::Transform translation; |
102 translation.SetTranslate(new_origin_.x() - origin.x(), | 104 translation.SetTranslate(new_origin_.x() - origin.x(), |
103 new_origin_.y() - origin.y()); | 105 new_origin_.y() - origin.y()); |
104 xform.ConcatTransform(translation); | 106 xform.ConcatTransform(translation); |
105 view_->layer()->SetTransform(xform); | 107 delegate_->SetTransformFromAnimation(xform); |
106 widget_->SchedulePaintInRect(widget_->GetClientAreaScreenBounds()); | 108 delegate_->ScheduleDrawForAnimation(); |
107 animation_stopped_ = true; | 109 animation_stopped_ = true; |
108 } | 110 } |
109 | 111 |
110 void ScreenRotation::OnCompositingEnded(ui::Compositor* compositor) { | 112 void ScreenRotation::OnCompositingEnded(ui::Compositor* compositor) { |
111 DoPendingWork(); | 113 DoPendingWork(); |
112 } | 114 } |
113 | 115 |
114 void ScreenRotation::Init() { | 116 void ScreenRotation::Init() { |
115 TRACE_EVENT0("ScreenRotation", "init"); | 117 TRACE_EVENT0("ScreenRotation", "init"); |
116 | 118 |
117 ui::Transform current_transform = view_->layer()->transform(); | 119 ui::Transform current_transform = view_->layer()->transform(); |
118 int degrees = new_degrees_ - old_degrees_; | 120 int degrees = new_degrees_ - old_degrees_; |
119 degrees = NormalizeAngle(degrees); | 121 degrees = NormalizeAngle(degrees); |
120 | 122 |
121 // No rotation required. | 123 // No rotation required. |
122 if (degrees == 0) | 124 if (degrees == 0) |
123 return; | 125 return; |
124 | 126 |
125 gfx::Point old_pivot; | 127 gfx::Point old_pivot; |
126 gfx::Point new_pivot; | 128 gfx::Point new_pivot; |
127 int width = view_->layer()->bounds().width(); | 129 const gfx::Rect bounds = delegate_->GetBoundsForAnimation(); |
sky
2011/10/20 20:30:30
const gfx::Rect&
| |
128 int height = view_->layer()->bounds().height(); | 130 int width = bounds.width(); |
131 int height = bounds.height(); | |
129 | 132 |
130 switch (degrees) { | 133 switch (degrees) { |
131 case 90: | 134 case 90: |
132 new_origin_ = new_pivot = gfx::Point(width, 0); | 135 new_origin_ = new_pivot = gfx::Point(width, 0); |
133 new_size_.SetSize(height, width); | 136 new_size_.SetSize(height, width); |
134 break; | 137 break; |
135 case -90: | 138 case -90: |
136 new_origin_ = new_pivot = gfx::Point(0, height); | 139 new_origin_ = new_pivot = gfx::Point(0, height); |
137 new_size_.SetSize(height, width); | 140 new_size_.SetSize(height, width); |
138 break; | 141 break; |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
204 } | 207 } |
205 | 208 |
206 void ScreenRotation::DoPendingWork() { | 209 void ScreenRotation::DoPendingWork() { |
207 if (!animation_started_) | 210 if (!animation_started_) |
208 Start(); | 211 Start(); |
209 else if (animation_stopped_) { | 212 else if (animation_stopped_) { |
210 view_->layer()->GetCompositor()->RemoveObserver(this); | 213 view_->layer()->GetCompositor()->RemoveObserver(this); |
211 Finalize(); | 214 Finalize(); |
212 } | 215 } |
213 } | 216 } |
OLD | NEW |