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

Side by Side Diff: ui/wm/core/window_animations.cc

Issue 180273025: Keep dedicated layers for hiding animation (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 9 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 | Annotate | Revision Log
« no previous file with comments | « ui/wm/core/window_animations.h ('k') | ui/wm/core/window_animations_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 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 "ui/wm/core/window_animations.h" 5 #include "ui/wm/core/window_animations.h"
6 6
7 #include <math.h> 7 #include <math.h>
8 8
9 #include <algorithm> 9 #include <algorithm>
10 #include <vector> 10 #include <vector>
11 11
12 #include "base/command_line.h" 12 #include "base/command_line.h"
13 #include "base/compiler_specific.h" 13 #include "base/compiler_specific.h"
14 #include "base/logging.h" 14 #include "base/logging.h"
15 #include "base/message_loop/message_loop.h" 15 #include "base/message_loop/message_loop.h"
16 #include "base/stl_util.h" 16 #include "base/stl_util.h"
17 #include "base/time/time.h" 17 #include "base/time/time.h"
18 #include "ui/aura/client/animation_host.h" 18 #include "ui/aura/client/animation_host.h"
19 #include "ui/aura/client/aura_constants.h" 19 #include "ui/aura/client/aura_constants.h"
20 #include "ui/aura/window.h" 20 #include "ui/aura/window.h"
21 #include "ui/aura/window_delegate.h" 21 #include "ui/aura/window_delegate.h"
22 #include "ui/aura/window_observer.h" 22 #include "ui/aura/window_observer.h"
23 #include "ui/aura/window_property.h" 23 #include "ui/aura/window_property.h"
24 #include "ui/compositor/compositor_observer.h" 24 #include "ui/compositor/compositor_observer.h"
25 #include "ui/compositor/layer.h" 25 #include "ui/compositor/layer.h"
26 #include "ui/compositor/layer_animation_observer.h" 26 #include "ui/compositor/layer_animation_observer.h"
27 #include "ui/compositor/layer_animation_sequence.h" 27 #include "ui/compositor/layer_animation_sequence.h"
28 #include "ui/compositor/layer_animator.h" 28 #include "ui/compositor/layer_animator.h"
29 #include "ui/compositor/layer_tree_owner.h"
29 #include "ui/compositor/scoped_layer_animation_settings.h" 30 #include "ui/compositor/scoped_layer_animation_settings.h"
30 #include "ui/gfx/animation/animation.h" 31 #include "ui/gfx/animation/animation.h"
31 #include "ui/gfx/interpolated_transform.h" 32 #include "ui/gfx/interpolated_transform.h"
32 #include "ui/gfx/rect_conversions.h" 33 #include "ui/gfx/rect_conversions.h"
33 #include "ui/gfx/screen.h" 34 #include "ui/gfx/screen.h"
34 #include "ui/gfx/vector2d.h" 35 #include "ui/gfx/vector2d.h"
35 #include "ui/gfx/vector3d_f.h" 36 #include "ui/gfx/vector3d_f.h"
36 #include "ui/wm/core/window_util.h" 37 #include "ui/wm/core/window_util.h"
37 #include "ui/wm/core/wm_core_switches.h" 38 #include "ui/wm/core/wm_core_switches.h"
38 39
39 DECLARE_WINDOW_PROPERTY_TYPE(int) 40 DECLARE_WINDOW_PROPERTY_TYPE(int)
40 DECLARE_WINDOW_PROPERTY_TYPE(wm::WindowVisibilityAnimationType) 41 DECLARE_WINDOW_PROPERTY_TYPE(wm::WindowVisibilityAnimationType)
41 DECLARE_WINDOW_PROPERTY_TYPE(wm::WindowVisibilityAnimationTransition) 42 DECLARE_WINDOW_PROPERTY_TYPE(wm::WindowVisibilityAnimationTransition)
42 DECLARE_WINDOW_PROPERTY_TYPE(float) 43 DECLARE_WINDOW_PROPERTY_TYPE(float)
43 DECLARE_EXPORTED_WINDOW_PROPERTY_TYPE(WM_CORE_EXPORT, bool) 44 DECLARE_EXPORTED_WINDOW_PROPERTY_TYPE(WM_CORE_EXPORT, bool)
44 45
45 using aura::Window;
46 using base::TimeDelta;
47 using ui::Layer;
48
49 namespace wm { 46 namespace wm {
50 namespace { 47 namespace {
51 const float kWindowAnimation_Vertical_TranslateY = 15.f; 48 const float kWindowAnimation_Vertical_TranslateY = 15.f;
52 } // namespace 49 } // namespace
53 50
54 DEFINE_WINDOW_PROPERTY_KEY(int, 51 DEFINE_WINDOW_PROPERTY_KEY(int,
55 kWindowVisibilityAnimationTypeKey, 52 kWindowVisibilityAnimationTypeKey,
56 WINDOW_VISIBILITY_ANIMATION_TYPE_DEFAULT); 53 WINDOW_VISIBILITY_ANIMATION_TYPE_DEFAULT);
57 DEFINE_WINDOW_PROPERTY_KEY(int, kWindowVisibilityAnimationDurationKey, 0); 54 DEFINE_WINDOW_PROPERTY_KEY(int, kWindowVisibilityAnimationDurationKey, 0);
58 DEFINE_WINDOW_PROPERTY_KEY(WindowVisibilityAnimationTransition, 55 DEFINE_WINDOW_PROPERTY_KEY(WindowVisibilityAnimationTransition,
59 kWindowVisibilityAnimationTransitionKey, 56 kWindowVisibilityAnimationTransitionKey,
60 ANIMATE_BOTH); 57 ANIMATE_BOTH);
61 DEFINE_WINDOW_PROPERTY_KEY(float, 58 DEFINE_WINDOW_PROPERTY_KEY(float,
62 kWindowVisibilityAnimationVerticalPositionKey, 59 kWindowVisibilityAnimationVerticalPositionKey,
63 kWindowAnimation_Vertical_TranslateY); 60 kWindowAnimation_Vertical_TranslateY);
64 61
62 // An AnimationObserer which has two roles:
63 // 1) Notifies AnimationHost at the end of hiding animation.
64 // 2) Detaches the window's layers for hiding animation and deletes
65 // them upon completion of the animation. This is necessary to a)
66 // ensure that the animation continues in the event of the window being
67 // deleted, and b) to ensure that the animation is visible even if the
68 // window gets restacked below other windows when focus or activation
69 // changes.
70 class HidingWindowAnimationObserver : public ui::ImplicitAnimationObserver,
71 public aura::WindowObserver {
72 public:
73 HidingWindowAnimationObserver(aura::Window* window,
74 ui::ScopedLayerAnimationSettings* settings);
75 virtual ~HidingWindowAnimationObserver() {}
76
77 // ui::ImplicitAnimationObserver:
78 virtual void OnImplicitAnimationsCompleted() OVERRIDE;
79
80 // aura::WindowObserver:
81 virtual void OnWindowDestroying(aura::Window* window) OVERRIDE;
82
83 // Detach the current layers and create new layers for |window_|.
84 // Stack the original layers above |window_| and its transient
85 // children. If the window has transient children, the original
86 // layers will be moved above the top most transient child so that
87 // activation change does not put the window above the animating
88 // layer.
89 void DetachAndRecreateLayers();
90
91 private:
92 aura::Window* window_;
93
94 // The owner of detached layers.
95 scoped_ptr<ui::LayerTreeOwner> layer_owner_;
96
97 DISALLOW_COPY_AND_ASSIGN(HidingWindowAnimationObserver);
98 };
99
65 namespace { 100 namespace {
66 101
67 const int kDefaultAnimationDurationForMenuMS = 150; 102 const int kDefaultAnimationDurationForMenuMS = 150;
68 103
69 const float kWindowAnimation_HideOpacity = 0.f; 104 const float kWindowAnimation_HideOpacity = 0.f;
70 const float kWindowAnimation_ShowOpacity = 1.f; 105 const float kWindowAnimation_ShowOpacity = 1.f;
71 const float kWindowAnimation_TranslateFactor = 0.5f; 106 const float kWindowAnimation_TranslateFactor = 0.5f;
72 const float kWindowAnimation_ScaleFactor = .95f; 107 const float kWindowAnimation_ScaleFactor = .95f;
73 108
74 const int kWindowAnimation_Rotate_DurationMS = 180; 109 const int kWindowAnimation_Rotate_DurationMS = 180;
75 const int kWindowAnimation_Rotate_OpacityDurationPercent = 90; 110 const int kWindowAnimation_Rotate_OpacityDurationPercent = 90;
76 const float kWindowAnimation_Rotate_TranslateY = -20.f; 111 const float kWindowAnimation_Rotate_TranslateY = -20.f;
77 const float kWindowAnimation_Rotate_PerspectiveDepth = 500.f; 112 const float kWindowAnimation_Rotate_PerspectiveDepth = 500.f;
78 const float kWindowAnimation_Rotate_DegreesX = 5.f; 113 const float kWindowAnimation_Rotate_DegreesX = 5.f;
79 const float kWindowAnimation_Rotate_ScaleFactor = .99f; 114 const float kWindowAnimation_Rotate_ScaleFactor = .99f;
80 115
81 const float kWindowAnimation_Bounce_Scale = 1.02f; 116 const float kWindowAnimation_Bounce_Scale = 1.02f;
82 const int kWindowAnimation_Bounce_DurationMS = 180; 117 const int kWindowAnimation_Bounce_DurationMS = 180;
83 const int kWindowAnimation_Bounce_GrowShrinkDurationPercent = 40; 118 const int kWindowAnimation_Bounce_GrowShrinkDurationPercent = 40;
84 119
85 base::TimeDelta GetWindowVisibilityAnimationDuration( 120 base::TimeDelta GetWindowVisibilityAnimationDuration(
86 const aura::Window& window) { 121 const aura::Window& window) {
87 int duration = 122 int duration =
88 window.GetProperty(kWindowVisibilityAnimationDurationKey); 123 window.GetProperty(kWindowVisibilityAnimationDurationKey);
89 if (duration == 0 && window.type() == ui::wm::WINDOW_TYPE_MENU) { 124 if (duration == 0 && window.type() == ui::wm::WINDOW_TYPE_MENU) {
90 return base::TimeDelta::FromMilliseconds( 125 return base::TimeDelta::FromMilliseconds(
91 kDefaultAnimationDurationForMenuMS); 126 kDefaultAnimationDurationForMenuMS);
92 } 127 }
93 return TimeDelta::FromInternalValue(duration); 128 return base::TimeDelta::FromInternalValue(duration);
94 } 129 }
95 130
96 // Gets/sets the WindowVisibilityAnimationType associated with a window. 131 // Gets/sets the WindowVisibilityAnimationType associated with a window.
97 // TODO(beng): redundant/fold into method on public api? 132 // TODO(beng): redundant/fold into method on public api?
98 int GetWindowVisibilityAnimationType(aura::Window* window) { 133 int GetWindowVisibilityAnimationType(aura::Window* window) {
99 int type = window->GetProperty(kWindowVisibilityAnimationTypeKey); 134 int type = window->GetProperty(kWindowVisibilityAnimationTypeKey);
100 if (type == WINDOW_VISIBILITY_ANIMATION_TYPE_DEFAULT) { 135 if (type == WINDOW_VISIBILITY_ANIMATION_TYPE_DEFAULT) {
101 return (window->type() == ui::wm::WINDOW_TYPE_MENU || 136 return (window->type() == ui::wm::WINDOW_TYPE_MENU ||
102 window->type() == ui::wm::WINDOW_TYPE_TOOLTIP) 137 window->type() == ui::wm::WINDOW_TYPE_TOOLTIP)
103 ? WINDOW_VISIBILITY_ANIMATION_TYPE_FADE 138 ? WINDOW_VISIBILITY_ANIMATION_TYPE_FADE
104 : WINDOW_VISIBILITY_ANIMATION_TYPE_DROP; 139 : WINDOW_VISIBILITY_ANIMATION_TYPE_DROP;
105 } 140 }
106 return type; 141 return type;
107 } 142 }
108 143
109 // Observes a hide animation.
110 // A window can be hidden for a variety of reasons. Sometimes, Hide() will be
111 // called and life is simple. Sometimes, the window is actually bound to a
112 // views::Widget and that Widget is closed, and life is a little more
113 // complicated. When a Widget is closed the aura::Window* is actually not
114 // destroyed immediately - it is actually just immediately hidden and then
115 // destroyed when the stack unwinds. To handle this case, we start the hide
116 // animation immediately when the window is hidden, then when the window is
117 // subsequently destroyed this object acquires ownership of the window's layer,
118 // so that it can continue animating it until the animation completes.
119 // Regardless of whether or not the window is destroyed, this object deletes
120 // itself when the animation completes.
121 class HidingWindowAnimationObserver : public ui::ImplicitAnimationObserver,
122 public aura::WindowObserver {
123 public:
124 explicit HidingWindowAnimationObserver(aura::Window* window)
125 : window_(window) {
126 window_->AddObserver(this);
127 }
128 virtual ~HidingWindowAnimationObserver() {
129 STLDeleteElements(&layers_);
130 }
131
132 private:
133 // Overridden from ui::ImplicitAnimationObserver:
134 virtual void OnImplicitAnimationsCompleted() OVERRIDE {
135 // Window may have been destroyed by this point.
136 if (window_) {
137 aura::client::AnimationHost* animation_host =
138 aura::client::GetAnimationHost(window_);
139 if (animation_host)
140 animation_host->OnWindowHidingAnimationCompleted();
141 window_->RemoveObserver(this);
142 }
143 delete this;
144 }
145
146 // Overridden from aura::WindowObserver:
147 virtual void OnWindowDestroying(aura::Window* window) OVERRIDE {
148 DCHECK_EQ(window, window_);
149 DCHECK(layers_.empty());
150 AcquireAllLayers(window_->layer());
151 window_->RemoveObserver(this);
152 window_ = NULL;
153 }
154
155 void AcquireAllLayers(ui::Layer* layer) {
156 if (layer->owner()) {
157 ui::Layer* released = layer->owner()->AcquireLayer();
158 DCHECK_EQ(layer, released);
159 layers_.push_back(released);
160 }
161 std::vector<Layer*>::const_iterator it = layer->children().begin();
162 for (; it != layer->children().end(); ++it)
163 AcquireAllLayers(*it);
164 }
165
166 aura::Window* window_;
167 std::vector<ui::Layer*> layers_;
168
169 DISALLOW_COPY_AND_ASSIGN(HidingWindowAnimationObserver);
170 };
171
172 void GetTransformRelativeToRoot(ui::Layer* layer, gfx::Transform* transform) { 144 void GetTransformRelativeToRoot(ui::Layer* layer, gfx::Transform* transform) {
173 const Layer* root = layer; 145 const ui::Layer* root = layer;
174 while (root->parent()) 146 while (root->parent())
175 root = root->parent(); 147 root = root->parent();
176 layer->GetTargetTransformRelativeTo(root, transform); 148 layer->GetTargetTransformRelativeTo(root, transform);
177 } 149 }
178 150
179 gfx::Rect GetLayerWorldBoundsAfterTransform(ui::Layer* layer, 151 gfx::Rect GetLayerWorldBoundsAfterTransform(ui::Layer* layer,
180 const gfx::Transform& transform) { 152 const gfx::Transform& transform) {
181 gfx::Transform in_world = transform; 153 gfx::Transform in_world = transform;
182 GetTransformRelativeToRoot(layer, &in_world); 154 GetTransformRelativeToRoot(layer, &in_world);
183 155
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
218 190
219 animation_host->SetHostTransitionOffsets(top_left_delta, bottom_right_delta); 191 animation_host->SetHostTransitionOffsets(top_left_delta, bottom_right_delta);
220 } 192 }
221 193
222 // Shows a window using an animation, animating its opacity from 0.f to 1.f, 194 // Shows a window using an animation, animating its opacity from 0.f to 1.f,
223 // its visibility to true, and its transform from |start_transform| to 195 // its visibility to true, and its transform from |start_transform| to
224 // |end_transform|. 196 // |end_transform|.
225 void AnimateShowWindowCommon(aura::Window* window, 197 void AnimateShowWindowCommon(aura::Window* window,
226 const gfx::Transform& start_transform, 198 const gfx::Transform& start_transform,
227 const gfx::Transform& end_transform) { 199 const gfx::Transform& end_transform) {
228 window->layer()->set_delegate(window);
229
230 AugmentWindowSize(window, end_transform); 200 AugmentWindowSize(window, end_transform);
231 201
232 window->layer()->SetOpacity(kWindowAnimation_HideOpacity); 202 window->layer()->SetOpacity(kWindowAnimation_HideOpacity);
233 window->layer()->SetTransform(start_transform); 203 window->layer()->SetTransform(start_transform);
234 window->layer()->SetVisible(true); 204 window->layer()->SetVisible(true);
235 205
236 { 206 {
237 // Property sets within this scope will be implicitly animated. 207 // Property sets within this scope will be implicitly animated.
238 ui::ScopedLayerAnimationSettings settings(window->layer()->GetAnimator()); 208 ui::ScopedLayerAnimationSettings settings(window->layer()->GetAnimator());
239 base::TimeDelta duration = GetWindowVisibilityAnimationDuration(*window); 209 base::TimeDelta duration = GetWindowVisibilityAnimationDuration(*window);
240 if (duration.ToInternalValue() > 0) 210 if (duration.ToInternalValue() > 0)
241 settings.SetTransitionDuration(duration); 211 settings.SetTransitionDuration(duration);
242 212
243 window->layer()->SetTransform(end_transform); 213 window->layer()->SetTransform(end_transform);
244 window->layer()->SetOpacity(kWindowAnimation_ShowOpacity); 214 window->layer()->SetOpacity(kWindowAnimation_ShowOpacity);
245 } 215 }
246 } 216 }
247 217
248 // Hides a window using an animation, animating its opacity from 1.f to 0.f, 218 // Hides a window using an animation, animating its opacity from 1.f to 0.f,
249 // its visibility to false, and its transform to |end_transform|. 219 // its visibility to false, and its transform to |end_transform|.
250 void AnimateHideWindowCommon(aura::Window* window, 220 void AnimateHideWindowCommon(aura::Window* window,
251 const gfx::Transform& end_transform) { 221 const gfx::Transform& end_transform) {
252 AugmentWindowSize(window, end_transform); 222 AugmentWindowSize(window, end_transform);
253 window->layer()->set_delegate(NULL);
254 223
255 // Property sets within this scope will be implicitly animated. 224 // Property sets within this scope will be implicitly animated.
256 ui::ScopedLayerAnimationSettings settings(window->layer()->GetAnimator()); 225 ScopedHidingAnimationSettings hiding_settings(window);
257 settings.AddObserver(new HidingWindowAnimationObserver(window));
258
259 base::TimeDelta duration = GetWindowVisibilityAnimationDuration(*window); 226 base::TimeDelta duration = GetWindowVisibilityAnimationDuration(*window);
260 if (duration.ToInternalValue() > 0) 227 if (duration.ToInternalValue() > 0)
261 settings.SetTransitionDuration(duration); 228 hiding_settings.layer_animation_settings()->SetTransitionDuration(duration);
262 229
263 window->layer()->SetOpacity(kWindowAnimation_HideOpacity); 230 window->layer()->SetOpacity(kWindowAnimation_HideOpacity);
264 window->layer()->SetTransform(end_transform); 231 window->layer()->SetTransform(end_transform);
265 window->layer()->SetVisible(false); 232 window->layer()->SetVisible(false);
266 } 233 }
267 234
268 static gfx::Transform GetScaleForWindow(aura::Window* window) { 235 static gfx::Transform GetScaleForWindow(aura::Window* window) {
269 gfx::Rect bounds = window->bounds(); 236 gfx::Rect bounds = window->bounds();
270 gfx::Transform scale = gfx::GetScaleTransform( 237 gfx::Transform scale = gfx::GetScaleTransform(
271 gfx::Point(kWindowAnimation_TranslateFactor * bounds.width(), 238 gfx::Point(kWindowAnimation_TranslateFactor * bounds.width(),
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
328 kWindowAnimation_Bounce_GrowShrinkDurationPercent / 100))); 295 kWindowAnimation_Bounce_GrowShrinkDurationPercent / 100)));
329 transition->set_tween_type(grow ? gfx::Tween::EASE_OUT : gfx::Tween::EASE_IN); 296 transition->set_tween_type(grow ? gfx::Tween::EASE_OUT : gfx::Tween::EASE_IN);
330 return transition.release(); 297 return transition.release();
331 } 298 }
332 299
333 void AnimateBounce(aura::Window* window) { 300 void AnimateBounce(aura::Window* window) {
334 ui::ScopedLayerAnimationSettings scoped_settings( 301 ui::ScopedLayerAnimationSettings scoped_settings(
335 window->layer()->GetAnimator()); 302 window->layer()->GetAnimator());
336 scoped_settings.SetPreemptionStrategy( 303 scoped_settings.SetPreemptionStrategy(
337 ui::LayerAnimator::REPLACE_QUEUED_ANIMATIONS); 304 ui::LayerAnimator::REPLACE_QUEUED_ANIMATIONS);
338 window->layer()->set_delegate(window);
339 scoped_ptr<ui::LayerAnimationSequence> sequence( 305 scoped_ptr<ui::LayerAnimationSequence> sequence(
340 new ui::LayerAnimationSequence); 306 new ui::LayerAnimationSequence);
341 sequence->AddElement(CreateGrowShrinkElement(window, true)); 307 sequence->AddElement(CreateGrowShrinkElement(window, true));
342 sequence->AddElement(ui::LayerAnimationElement::CreatePauseElement( 308 sequence->AddElement(ui::LayerAnimationElement::CreatePauseElement(
343 ui::LayerAnimationElement::BOUNDS, 309 ui::LayerAnimationElement::BOUNDS,
344 base::TimeDelta::FromMilliseconds( 310 base::TimeDelta::FromMilliseconds(
345 kWindowAnimation_Bounce_DurationMS * 311 kWindowAnimation_Bounce_DurationMS *
346 (100 - 2 * kWindowAnimation_Bounce_GrowShrinkDurationPercent) / 312 (100 - 2 * kWindowAnimation_Bounce_GrowShrinkDurationPercent) /
347 100))); 313 100)));
348 sequence->AddElement(CreateGrowShrinkElement(window, false)); 314 sequence->AddElement(CreateGrowShrinkElement(window, false));
349 window->layer()->GetAnimator()->StartAnimation(sequence.release()); 315 window->layer()->GetAnimator()->StartAnimation(sequence.release());
350 } 316 }
351 317
352 void AddLayerAnimationsForRotate(aura::Window* window, bool show) { 318 void AddLayerAnimationsForRotate(aura::Window* window, bool show) {
353 window->layer()->set_delegate(window);
354 if (show) 319 if (show)
355 window->layer()->SetOpacity(kWindowAnimation_HideOpacity); 320 window->layer()->SetOpacity(kWindowAnimation_HideOpacity);
356 321
357 base::TimeDelta duration = base::TimeDelta::FromMilliseconds( 322 base::TimeDelta duration = base::TimeDelta::FromMilliseconds(
358 kWindowAnimation_Rotate_DurationMS); 323 kWindowAnimation_Rotate_DurationMS);
359 324
325 HidingWindowAnimationObserver* observer = NULL;
326
360 if (!show) { 327 if (!show) {
361 new HidingWindowAnimationObserver(window); 328 // TODO(oshima): Fix observer leak.
329 observer = new HidingWindowAnimationObserver(window, NULL);
362 window->layer()->GetAnimator()->SchedulePauseForProperties( 330 window->layer()->GetAnimator()->SchedulePauseForProperties(
363 duration * (100 - kWindowAnimation_Rotate_OpacityDurationPercent) / 100, 331 duration * (100 - kWindowAnimation_Rotate_OpacityDurationPercent) / 100,
364 ui::LayerAnimationElement::OPACITY); 332 ui::LayerAnimationElement::OPACITY);
365 } 333 }
366 scoped_ptr<ui::LayerAnimationElement> opacity( 334 scoped_ptr<ui::LayerAnimationElement> opacity(
367 ui::LayerAnimationElement::CreateOpacityElement( 335 ui::LayerAnimationElement::CreateOpacityElement(
368 show ? kWindowAnimation_ShowOpacity : kWindowAnimation_HideOpacity, 336 show ? kWindowAnimation_ShowOpacity : kWindowAnimation_HideOpacity,
369 duration * kWindowAnimation_Rotate_OpacityDurationPercent / 100)); 337 duration * kWindowAnimation_Rotate_OpacityDurationPercent / 100));
370 opacity->set_tween_type(gfx::Tween::EASE_IN_OUT); 338 opacity->set_tween_type(gfx::Tween::EASE_IN_OUT);
371 window->layer()->GetAnimator()->ScheduleAnimation( 339 window->layer()->GetAnimator()->ScheduleAnimation(
(...skipping 27 matching lines...) Expand all
399 translation->SetChild(scale_about_pivot.release()); 367 translation->SetChild(scale_about_pivot.release());
400 rotation->SetChild(translation.release()); 368 rotation->SetChild(translation.release());
401 rotation->SetReversed(show); 369 rotation->SetReversed(show);
402 370
403 scoped_ptr<ui::LayerAnimationElement> transition( 371 scoped_ptr<ui::LayerAnimationElement> transition(
404 ui::LayerAnimationElement::CreateInterpolatedTransformElement( 372 ui::LayerAnimationElement::CreateInterpolatedTransformElement(
405 rotation.release(), duration)); 373 rotation.release(), duration));
406 374
407 window->layer()->GetAnimator()->ScheduleAnimation( 375 window->layer()->GetAnimator()->ScheduleAnimation(
408 new ui::LayerAnimationSequence(transition.release())); 376 new ui::LayerAnimationSequence(transition.release()));
377 if (observer)
378 observer->DetachAndRecreateLayers();
409 } 379 }
410 380
411 void AnimateShowWindow_Rotate(aura::Window* window) { 381 void AnimateShowWindow_Rotate(aura::Window* window) {
412 AddLayerAnimationsForRotate(window, true); 382 AddLayerAnimationsForRotate(window, true);
413 } 383 }
414 384
415 void AnimateHideWindow_Rotate(aura::Window* window) { 385 void AnimateHideWindow_Rotate(aura::Window* window) {
416 AddLayerAnimationsForRotate(window, false); 386 AddLayerAnimationsForRotate(window, false);
417 } 387 }
418 388
419 bool AnimateShowWindow(aura::Window* window) { 389 bool AnimateShowWindow(aura::Window* window) {
420 if (!HasWindowVisibilityAnimationTransition(window, ANIMATE_SHOW)) { 390 if (!HasWindowVisibilityAnimationTransition(window, ANIMATE_SHOW)) {
421 if (HasWindowVisibilityAnimationTransition(window, ANIMATE_HIDE)) { 391 if (HasWindowVisibilityAnimationTransition(window, ANIMATE_HIDE)) {
422 // Since hide animation may have changed opacity and transform, 392 // Since hide animation may have changed opacity and transform,
423 // reset them to show the window. 393 // reset them to show the window.
424 window->layer()->set_delegate(window);
425 window->layer()->SetOpacity(kWindowAnimation_ShowOpacity); 394 window->layer()->SetOpacity(kWindowAnimation_ShowOpacity);
426 window->layer()->SetTransform(gfx::Transform()); 395 window->layer()->SetTransform(gfx::Transform());
427 } 396 }
428 return false; 397 return false;
429 } 398 }
430 399
431 switch (GetWindowVisibilityAnimationType(window)) { 400 switch (GetWindowVisibilityAnimationType(window)) {
432 case WINDOW_VISIBILITY_ANIMATION_TYPE_DROP: 401 case WINDOW_VISIBILITY_ANIMATION_TYPE_DROP:
433 AnimateShowWindow_Drop(window); 402 AnimateShowWindow_Drop(window);
434 return true; 403 return true;
435 case WINDOW_VISIBILITY_ANIMATION_TYPE_VERTICAL: 404 case WINDOW_VISIBILITY_ANIMATION_TYPE_VERTICAL:
436 AnimateShowWindow_Vertical(window); 405 AnimateShowWindow_Vertical(window);
437 return true; 406 return true;
438 case WINDOW_VISIBILITY_ANIMATION_TYPE_FADE: 407 case WINDOW_VISIBILITY_ANIMATION_TYPE_FADE:
439 AnimateShowWindow_Fade(window); 408 AnimateShowWindow_Fade(window);
440 return true; 409 return true;
441 case WINDOW_VISIBILITY_ANIMATION_TYPE_ROTATE: 410 case WINDOW_VISIBILITY_ANIMATION_TYPE_ROTATE:
442 AnimateShowWindow_Rotate(window); 411 AnimateShowWindow_Rotate(window);
443 return true; 412 return true;
444 default: 413 default:
445 return false; 414 return false;
446 } 415 }
447 } 416 }
448 417
449 bool AnimateHideWindow(aura::Window* window) { 418 bool AnimateHideWindow(aura::Window* window) {
450 if (!HasWindowVisibilityAnimationTransition(window, ANIMATE_HIDE)) { 419 if (!HasWindowVisibilityAnimationTransition(window, ANIMATE_HIDE)) {
451 if (HasWindowVisibilityAnimationTransition(window, ANIMATE_SHOW)) { 420 if (HasWindowVisibilityAnimationTransition(window, ANIMATE_SHOW)) {
452 // Since show animation may have changed opacity and transform, 421 // Since show animation may have changed opacity and transform,
453 // reset them, though the change should be hidden. 422 // reset them, though the change should be hidden.
454 window->layer()->set_delegate(NULL);
455 window->layer()->SetOpacity(kWindowAnimation_HideOpacity); 423 window->layer()->SetOpacity(kWindowAnimation_HideOpacity);
456 window->layer()->SetTransform(gfx::Transform()); 424 window->layer()->SetTransform(gfx::Transform());
457 } 425 }
458 return false; 426 return false;
459 } 427 }
460 428
461 switch (GetWindowVisibilityAnimationType(window)) { 429 switch (GetWindowVisibilityAnimationType(window)) {
462 case WINDOW_VISIBILITY_ANIMATION_TYPE_DROP: 430 case WINDOW_VISIBILITY_ANIMATION_TYPE_DROP:
463 AnimateHideWindow_Drop(window); 431 AnimateHideWindow_Drop(window);
464 return true; 432 return true;
465 case WINDOW_VISIBILITY_ANIMATION_TYPE_VERTICAL: 433 case WINDOW_VISIBILITY_ANIMATION_TYPE_VERTICAL:
466 AnimateHideWindow_Vertical(window); 434 AnimateHideWindow_Vertical(window);
467 return true; 435 return true;
468 case WINDOW_VISIBILITY_ANIMATION_TYPE_FADE: 436 case WINDOW_VISIBILITY_ANIMATION_TYPE_FADE:
469 AnimateHideWindow_Fade(window); 437 AnimateHideWindow_Fade(window);
470 return true; 438 return true;
471 case WINDOW_VISIBILITY_ANIMATION_TYPE_ROTATE: 439 case WINDOW_VISIBILITY_ANIMATION_TYPE_ROTATE:
472 AnimateHideWindow_Rotate(window); 440 AnimateHideWindow_Rotate(window);
473 return true; 441 return true;
474 default: 442 default:
475 return false; 443 return false;
476 } 444 }
477 } 445 }
478 446
479 } // namespace 447 } // namespace
480 448
481 //////////////////////////////////////////////////////////////////////////////// 449 ////////////////////////////////////////////////////////////////////////////////
450 // HidingWindowAnimationObserver
451
452 HidingWindowAnimationObserver::HidingWindowAnimationObserver(
453 aura::Window* window,
454 ui::ScopedLayerAnimationSettings* settings)
455 : window_(window) {
456 window->AddObserver(this);
457 if (settings)
458 settings->AddObserver(this);
459 }
460
461 void HidingWindowAnimationObserver::OnImplicitAnimationsCompleted() {
462 // Window may have been destroyed by this point.
463 if (window_) {
464 aura::client::AnimationHost* animation_host =
465 aura::client::GetAnimationHost(window_);
466 if (animation_host)
467 animation_host->OnWindowHidingAnimationCompleted();
468 window_->RemoveObserver(this);
469 }
470 delete this;
471 }
472
473 void HidingWindowAnimationObserver::OnWindowDestroying(aura::Window* window) {
474 DCHECK_EQ(window, window_);
475 window_->RemoveObserver(this);
476 window_ = NULL;
477 }
478
479 void HidingWindowAnimationObserver::DetachAndRecreateLayers() {
480 layer_owner_ = RecreateLayers(window_);
481 if (window_->parent()) {
482 const aura::Window::Windows& transient_children =
483 GetTransientChildren(window_);
484 aura::Window::Windows::const_iterator iter =
485 std::find(window_->parent()->children().begin(),
486 window_->parent()->children().end(),
487 window_);
488 DCHECK(iter != window_->parent()->children().end());
489 aura::Window* topmost_transient_child = NULL;
490 for (++iter; iter != window_->parent()->children().end(); ++iter) {
491 if (std::find(transient_children.begin(),
492 transient_children.end(),
493 *iter) !=
494 transient_children.end()) {
495 topmost_transient_child = *iter;
496 }
497 }
498 if (topmost_transient_child) {
499 window_->parent()->layer()->StackAbove(
500 layer_owner_->root(), topmost_transient_child->layer());
501 }
502 }
503
504 // TODO(sky): The recreated layer should have the target visibility of
505 // the original layer.
506 // Make the new layer invisible immediately.
507 window_->layer()->SetVisible(false);
508 window_->layer()->SetOpacity(0);
509 }
510
511 ////////////////////////////////////////////////////////////////////////////////
512 // ScopedHidingAnimationSettings
513
514 ScopedHidingAnimationSettings::ScopedHidingAnimationSettings(
515 aura::Window* window)
516 : layer_animation_settings_(window->layer()->GetAnimator()),
517 observer_(new HidingWindowAnimationObserver(
518 window, &layer_animation_settings_)) {
519 }
520
521 ScopedHidingAnimationSettings::~ScopedHidingAnimationSettings() {
522 observer_->DetachAndRecreateLayers();
523 }
524
525 ////////////////////////////////////////////////////////////////////////////////
482 // External interface 526 // External interface
483 527
484 void SetWindowVisibilityAnimationType(aura::Window* window, int type) { 528 void SetWindowVisibilityAnimationType(aura::Window* window, int type) {
485 window->SetProperty(kWindowVisibilityAnimationTypeKey, type); 529 window->SetProperty(kWindowVisibilityAnimationTypeKey, type);
486 } 530 }
487 531
488 int GetWindowVisibilityAnimationType(aura::Window* window) { 532 int GetWindowVisibilityAnimationType(aura::Window* window) {
489 return window->GetProperty(kWindowVisibilityAnimationTypeKey); 533 return window->GetProperty(kWindowVisibilityAnimationTypeKey);
490 } 534 }
491 535
492 void SetWindowVisibilityAnimationTransition( 536 void SetWindowVisibilityAnimationTransition(
493 aura::Window* window, 537 aura::Window* window,
494 WindowVisibilityAnimationTransition transition) { 538 WindowVisibilityAnimationTransition transition) {
495 window->SetProperty(kWindowVisibilityAnimationTransitionKey, transition); 539 window->SetProperty(kWindowVisibilityAnimationTransitionKey, transition);
496 } 540 }
497 541
498 bool HasWindowVisibilityAnimationTransition( 542 bool HasWindowVisibilityAnimationTransition(
499 aura::Window* window, 543 aura::Window* window,
500 WindowVisibilityAnimationTransition transition) { 544 WindowVisibilityAnimationTransition transition) {
501 WindowVisibilityAnimationTransition prop = window->GetProperty( 545 WindowVisibilityAnimationTransition prop = window->GetProperty(
502 kWindowVisibilityAnimationTransitionKey); 546 kWindowVisibilityAnimationTransitionKey);
503 return (prop & transition) != 0; 547 return (prop & transition) != 0;
504 } 548 }
505 549
506 void SetWindowVisibilityAnimationDuration(aura::Window* window, 550 void SetWindowVisibilityAnimationDuration(aura::Window* window,
507 const TimeDelta& duration) { 551 const base::TimeDelta& duration) {
508 window->SetProperty(kWindowVisibilityAnimationDurationKey, 552 window->SetProperty(kWindowVisibilityAnimationDurationKey,
509 static_cast<int>(duration.ToInternalValue())); 553 static_cast<int>(duration.ToInternalValue()));
510 } 554 }
511 555
512 base::TimeDelta GetWindowVisibilityAnimationDuration( 556 base::TimeDelta GetWindowVisibilityAnimationDuration(
513 const aura::Window& window) { 557 const aura::Window& window) {
514 return base::TimeDelta::FromInternalValue( 558 return base::TimeDelta::FromInternalValue(
515 window.GetProperty(kWindowVisibilityAnimationDurationKey)); 559 window.GetProperty(kWindowVisibilityAnimationDurationKey));
516 } 560 }
517 561
518 void SetWindowVisibilityAnimationVerticalPosition(aura::Window* window, 562 void SetWindowVisibilityAnimationVerticalPosition(aura::Window* window,
519 float position) { 563 float position) {
520 window->SetProperty(kWindowVisibilityAnimationVerticalPositionKey, position); 564 window->SetProperty(kWindowVisibilityAnimationVerticalPositionKey, position);
521 } 565 }
522 566
523 ui::ImplicitAnimationObserver* CreateHidingWindowAnimationObserver(
524 aura::Window* window) {
525 return new HidingWindowAnimationObserver(window);
526 }
527
528 bool AnimateOnChildWindowVisibilityChanged(aura::Window* window, bool visible) { 567 bool AnimateOnChildWindowVisibilityChanged(aura::Window* window, bool visible) {
529 if (WindowAnimationsDisabled(window)) 568 if (WindowAnimationsDisabled(window))
530 return false; 569 return false;
531 if (visible) 570 if (visible)
532 return AnimateShowWindow(window); 571 return AnimateShowWindow(window);
533 // Don't start hiding the window again if it's already being hidden. 572 // Don't start hiding the window again if it's already being hidden.
534 return window->layer()->GetTargetOpacity() != 0.0f && 573 return window->layer()->GetTargetOpacity() != 0.0f &&
535 AnimateHideWindow(window); 574 AnimateHideWindow(window);
536 } 575 }
537 576
538 bool AnimateWindow(aura::Window* window, WindowAnimationType type) { 577 bool AnimateWindow(aura::Window* window, WindowAnimationType type) {
539 switch (type) { 578 switch (type) {
540 case WINDOW_ANIMATION_TYPE_BOUNCE: 579 case WINDOW_ANIMATION_TYPE_BOUNCE:
541 AnimateBounce(window); 580 AnimateBounce(window);
542 return true; 581 return true;
543 default: 582 default:
544 NOTREACHED(); 583 NOTREACHED();
545 return false; 584 return false;
546 } 585 }
547 } 586 }
548 587
549 bool WindowAnimationsDisabled(aura::Window* window) { 588 bool WindowAnimationsDisabled(aura::Window* window) {
550 return (!gfx::Animation::ShouldRenderRichAnimation() || (window && 589 return (!gfx::Animation::ShouldRenderRichAnimation() || (window &&
551 window->GetProperty(aura::client::kAnimationsDisabledKey)) || 590 window->GetProperty(aura::client::kAnimationsDisabledKey)) ||
552 CommandLine::ForCurrentProcess()->HasSwitch( 591 CommandLine::ForCurrentProcess()->HasSwitch(
553 switches::kWindowAnimationsDisabled)); 592 switches::kWindowAnimationsDisabled));
554 } 593 }
555 594
556 } // namespace wm 595 } // namespace wm
OLDNEW
« no previous file with comments | « ui/wm/core/window_animations.h ('k') | ui/wm/core/window_animations_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698