Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(628)

Side by Side Diff: ash/wm/session_state_animator.cc

Issue 10914016: ash: Extract animator from PowerButtonController (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Yet another attempt Created 8 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
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 "ash/wm/session_state_animator.h"
6
7 #include "ash/shell.h"
8 #include "ash/shell_window_ids.h"
9 #include "ui/aura/root_window.h"
10 #include "ui/compositor/layer_animation_sequence.h"
11
12 namespace ash {
13
14 namespace {
15
16 // Amount of time taken to scale the snapshot of the screen down to a
17 // slightly-smaller size once the user starts holding the power button. Used
18 // for both the pre-lock and pre-shutdown animations.
19 const int kSlowCloseAnimMs = 400;
20
21 // Amount of time taken to scale the snapshot of the screen back to its original
22 // size when the button is released.
23 const int kUndoSlowCloseAnimMs = 100;
24
25 // Amount of time taken to scale the snapshot down to a point in the center of
26 // the screen once the screen has been locked or we've been notified that the
27 // system is shutting down.
28 const int kFastCloseAnimMs = 150;
29
30 // Amount of time taken to make the lock window fade in when the screen is
31 // locked.
32 const int kLockFadeInAnimMs = 200;
33
34 // Slightly-smaller size that we scale the screen down to for the pre-lock and
35 // pre-shutdown states.
36 const float kSlowCloseSizeRatio = 0.95f;
37
38 // Returns the transform that should be applied to containers for the slow-close
39 // animation.
40 ui::Transform GetSlowCloseTransform() {
41 gfx::Size root_size = Shell::GetPrimaryRootWindow()->bounds().size();
42 ui::Transform transform;
43 transform.SetScale(kSlowCloseSizeRatio, kSlowCloseSizeRatio);
44 transform.ConcatTranslate(
45 floor(0.5 * (1.0 - kSlowCloseSizeRatio) * root_size.width() + 0.5),
46 floor(0.5 * (1.0 - kSlowCloseSizeRatio) * root_size.height() + 0.5));
47 return transform;
48 }
49
50 // Returns the transform that should be applied to containers for the fast-close
51 // animation.
52 ui::Transform GetFastCloseTransform() {
53 gfx::Size root_size = Shell::GetPrimaryRootWindow()->bounds().size();
54 ui::Transform transform;
55 transform.SetScale(0.0, 0.0);
56 transform.ConcatTranslate(floor(0.5 * root_size.width() + 0.5),
57 floor(0.5 * root_size.height() + 0.5));
58 return transform;
59 }
60
61 // Slowly shrinks |window| to a slightly-smaller size.
62 void StartSlowCloseAnimationForWindow(aura::Window* window) {
63 ui::LayerAnimator* animator = window->layer()->GetAnimator();
64 animator->set_preemption_strategy(
65 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
66 animator->StartAnimation(
67 new ui::LayerAnimationSequence(
68 ui::LayerAnimationElement::CreateTransformElement(
69 GetSlowCloseTransform(),
70 base::TimeDelta::FromMilliseconds(kSlowCloseAnimMs))));
71 }
72
73 // Quickly undoes the effects of the slow-close animation on |window|.
74 void StartUndoSlowCloseAnimationForWindow(aura::Window* window) {
75 ui::LayerAnimator* animator = window->layer()->GetAnimator();
76 animator->set_preemption_strategy(
77 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
78 animator->StartAnimation(
79 new ui::LayerAnimationSequence(
80 ui::LayerAnimationElement::CreateTransformElement(
81 ui::Transform(),
82 base::TimeDelta::FromMilliseconds(kUndoSlowCloseAnimMs))));
83 }
84
85 // Quickly shrinks |window| down to a point in the center of the screen and
86 // fades it out to 0 opacity.
87 void StartFastCloseAnimationForWindow(aura::Window* window) {
88 ui::LayerAnimator* animator = window->layer()->GetAnimator();
89 animator->set_preemption_strategy(
90 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
91 animator->StartAnimation(
92 new ui::LayerAnimationSequence(
93 ui::LayerAnimationElement::CreateTransformElement(
94 GetFastCloseTransform(),
95 base::TimeDelta::FromMilliseconds(kFastCloseAnimMs))));
96 animator->StartAnimation(
97 new ui::LayerAnimationSequence(
98 ui::LayerAnimationElement::CreateOpacityElement(
99 0.0, base::TimeDelta::FromMilliseconds(kFastCloseAnimMs))));
100 }
101
102 // Fades |window| in to full opacity.
103 void FadeInWindow(aura::Window* window) {
104 ui::LayerAnimator* animator = window->layer()->GetAnimator();
105 animator->set_preemption_strategy(
106 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
107 animator->StartAnimation(
108 new ui::LayerAnimationSequence(
109 ui::LayerAnimationElement::CreateOpacityElement(
110 1.0, base::TimeDelta::FromMilliseconds(kLockFadeInAnimMs))));
111 }
112
113 // Makes |window| fully transparent instantaneously.
114 void HideWindow(aura::Window* window) {
115 window->layer()->SetOpacity(0.0);
116 }
117
118 // Restores |window| to its original position and scale and full opacity
119 // instantaneously.
120 void RestoreWindow(aura::Window* window) {
121 window->layer()->SetTransform(ui::Transform());
122 window->layer()->SetOpacity(1.0);
123 }
124
125 } // namespace
126
127 void SessionStateAnimator::TestApi::TriggerHideBlackLayerTimeout() {
128 animator_->DropBlackLayer();
129 animator_->hide_black_layer_timer_.Stop();
130 }
131
132 bool SessionStateAnimator::TestApi::ContainersAreAnimated(
133 int container_mask, AnimationType type) const {
134 aura::Window::Windows containers;
135 animator_->GetContainers(container_mask, &containers);
136 for (aura::Window::Windows::const_iterator it = containers.begin();
137 it != containers.end(); ++it) {
138 aura::Window* window = *it;
139 ui::Layer* layer = window->layer();
140
141 switch (type) {
142 case ANIMATION_SLOW_CLOSE:
143 if (layer->GetTargetTransform() != GetSlowCloseTransform())
144 return false;
145 break;
146 case ANIMATION_UNDO_SLOW_CLOSE:
147 if (layer->GetTargetTransform() != ui::Transform())
148 return false;
149 break;
150 case ANIMATION_FAST_CLOSE:
151 if (layer->GetTargetTransform() != GetFastCloseTransform() ||
152 layer->GetTargetOpacity() > 0.0001)
153 return false;
154 break;
155 case ANIMATION_FADE_IN:
156 if (layer->GetTargetOpacity() < 0.9999)
157 return false;
158 break;
159 case ANIMATION_HIDE:
160 if (layer->GetTargetOpacity() > 0.0001)
161 return false;
162 break;
163 case ANIMATION_RESTORE:
164 if (layer->opacity() < 0.9999 || layer->transform() != ui::Transform())
165 return false;
166 break;
167 default:
168 NOTREACHED() << "Unhandled animation type " << type;
169 return false;
170 }
171 }
172 return true;
173 }
174
175 bool SessionStateAnimator::TestApi::BlackLayerIsVisible() const {
176 return animator_->black_layer_.get() &&
177 animator_->black_layer_->visible();
178 }
179
180 gfx::Rect SessionStateAnimator::TestApi::GetBlackLayerBounds() const {
181 ui::Layer* layer = animator_->black_layer_.get();
182 return layer ? layer->bounds() : gfx::Rect();
183 }
184
185 // static
186 int SessionStateAnimator::GetAllContainersMask() {
187 return DESKTOP_BACKGROUND |
188 NON_LOCK_SCREEN_CONTAINERS |
189 GetAllLockScreenContainersMask();
190 }
191
192 // static
193 int SessionStateAnimator::GetAllLockScreenContainersMask() {
194 return LOCK_SCREEN_BACKGROUND |
195 LOCK_SCREEN_CONTAINERS |
196 LOCK_SCREEN_RELATED_CONTAINERS;
197 }
198
199 SessionStateAnimator::SessionStateAnimator() {
200 Shell::GetPrimaryRootWindow()->AddRootWindowObserver(this);
201 }
202
203 SessionStateAnimator::~SessionStateAnimator() {
204 Shell::GetPrimaryRootWindow()->RemoveRootWindowObserver(this);
205 }
206
207 // Fills |containers| with the containers described by |container_mask|.
208 void SessionStateAnimator::GetContainers(int container_mask,
209 aura::Window::Windows* containers) {
210 aura::RootWindow* root_window = Shell::GetPrimaryRootWindow();
211 containers->clear();
212
213 if (container_mask & DESKTOP_BACKGROUND) {
214 containers->push_back(Shell::GetContainer(
215 root_window,
216 internal::kShellWindowId_DesktopBackgroundContainer));
217 }
218 if (container_mask & NON_LOCK_SCREEN_CONTAINERS) {
219 containers->push_back(Shell::GetContainer(
220 root_window,
221 internal::kShellWindowId_NonLockScreenContainersContainer));
222 }
223 if (container_mask & LOCK_SCREEN_BACKGROUND) {
224 containers->push_back(Shell::GetContainer(
225 root_window,
226 internal::kShellWindowId_LockScreenBackgroundContainer));
227 }
228 if (container_mask & LOCK_SCREEN_CONTAINERS) {
229 containers->push_back(Shell::GetContainer(
230 root_window,
231 internal::kShellWindowId_LockScreenContainersContainer));
232 }
233 if (container_mask & LOCK_SCREEN_RELATED_CONTAINERS) {
234 containers->push_back(Shell::GetContainer(
235 root_window,
236 internal::kShellWindowId_LockScreenRelatedContainersContainer));
237 }
238 }
239
240 // Apply animation |type| to all containers described by |container_mask|.
241 void SessionStateAnimator::StartAnimation(int container_mask,
242 AnimationType type) {
243 aura::Window::Windows containers;
244 GetContainers(container_mask, &containers);
245
246 for (aura::Window::Windows::const_iterator it = containers.begin();
247 it != containers.end(); ++it) {
248 aura::Window* window = *it;
249 switch (type) {
250 case ANIMATION_SLOW_CLOSE:
251 StartSlowCloseAnimationForWindow(window);
252 break;
253 case ANIMATION_UNDO_SLOW_CLOSE:
254 StartUndoSlowCloseAnimationForWindow(window);
255 break;
256 case ANIMATION_FAST_CLOSE:
257 StartFastCloseAnimationForWindow(window);
258 break;
259 case ANIMATION_FADE_IN:
260 FadeInWindow(window);
261 break;
262 case ANIMATION_HIDE:
263 HideWindow(window);
264 break;
265 case ANIMATION_RESTORE:
266 RestoreWindow(window);
267 break;
268 default:
269 NOTREACHED() << "Unhandled animation type " << type;
270 }
271 }
272 }
273
274 void SessionStateAnimator::OnRootWindowResized(const aura::RootWindow* root,
275 const gfx::Size& new_size) {
276 if (black_layer_.get())
277 black_layer_->SetBounds(gfx::Rect(root->bounds().size()));
278 }
279
280 void SessionStateAnimator::ShowBlackLayer() {
281 if (hide_black_layer_timer_.IsRunning())
282 hide_black_layer_timer_.Stop();
283
284 if (!black_layer_.get()) {
285 black_layer_.reset(new ui::Layer(ui::LAYER_SOLID_COLOR));
286 black_layer_->SetColor(SK_ColorBLACK);
287
288 ui::Layer* root_layer = Shell::GetPrimaryRootWindow()->layer();
289 black_layer_->SetBounds(root_layer->bounds());
290 root_layer->Add(black_layer_.get());
291 root_layer->StackAtBottom(black_layer_.get());
292 }
293 black_layer_->SetVisible(true);
294 }
295
296 void SessionStateAnimator::DropBlackLayer() {
297 black_layer_.reset();
298 }
299
300 void SessionStateAnimator::ScheduleDropBlackLayer() {
301 hide_black_layer_timer_.Stop();
302 hide_black_layer_timer_.Start(
303 FROM_HERE,
304 base::TimeDelta::FromMilliseconds(kUndoSlowCloseAnimMs),
305 this, &SessionStateAnimator::DropBlackLayer);
306 }
307
308 } // namespace ash
OLDNEW
« ash/wm/session_state_animator.h ('K') | « ash/wm/session_state_animator.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698