| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 |
| OLD | NEW |