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

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

Powered by Google App Engine
This is Rietveld 408576698