| 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/views/corewm/window_animations.h" | 5 #include "ui/views/corewm/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> |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 102 int type = window->GetProperty(kWindowVisibilityAnimationTypeKey); | 102 int type = window->GetProperty(kWindowVisibilityAnimationTypeKey); |
| 103 if (type == WINDOW_VISIBILITY_ANIMATION_TYPE_DEFAULT) { | 103 if (type == WINDOW_VISIBILITY_ANIMATION_TYPE_DEFAULT) { |
| 104 return (window->type() == ui::wm::WINDOW_TYPE_MENU || | 104 return (window->type() == ui::wm::WINDOW_TYPE_MENU || |
| 105 window->type() == ui::wm::WINDOW_TYPE_TOOLTIP) | 105 window->type() == ui::wm::WINDOW_TYPE_TOOLTIP) |
| 106 ? WINDOW_VISIBILITY_ANIMATION_TYPE_FADE | 106 ? WINDOW_VISIBILITY_ANIMATION_TYPE_FADE |
| 107 : WINDOW_VISIBILITY_ANIMATION_TYPE_DROP; | 107 : WINDOW_VISIBILITY_ANIMATION_TYPE_DROP; |
| 108 } | 108 } |
| 109 return type; | 109 return type; |
| 110 } | 110 } |
| 111 | 111 |
| 112 class HidingWindowAnimationObserver; |
| 113 DEFINE_WINDOW_PROPERTY_KEY(HidingWindowAnimationObserver*, |
| 114 kHidingWindowAnimationObserverKey, |
| 115 NULL); |
| 116 |
| 112 // Observes a hide animation. | 117 // Observes a hide animation. |
| 113 // A window can be hidden for a variety of reasons. Sometimes, Hide() will be | 118 // A window can be hidden for a variety of reasons. Sometimes, Hide() will be |
| 114 // called and life is simple. Sometimes, the window is actually bound to a | 119 // called and life is simple. Sometimes, the window is actually bound to a |
| 115 // views::Widget and that Widget is closed, and life is a little more | 120 // views::Widget and that Widget is closed, and life is a little more |
| 116 // complicated. When a Widget is closed the aura::Window* is actually not | 121 // complicated. When a Widget is closed the aura::Window* is actually not |
| 117 // destroyed immediately - it is actually just immediately hidden and then | 122 // destroyed immediately - it is actually just immediately hidden and then |
| 118 // destroyed when the stack unwinds. To handle this case, we start the hide | 123 // destroyed when the stack unwinds. To handle this case, we start the hide |
| 119 // animation immediately when the window is hidden, then when the window is | 124 // animation immediately when the window is hidden, then when the window is |
| 120 // subsequently destroyed this object acquires ownership of the window's layer, | 125 // subsequently destroyed this object acquires ownership of the window's layer, |
| 121 // so that it can continue animating it until the animation completes. | 126 // so that it can continue animating it until the animation completes. |
| 122 // Regardless of whether or not the window is destroyed, this object deletes | 127 // Regardless of whether or not the window is destroyed, this object deletes |
| 123 // itself when the animation completes. | 128 // itself when the animation completes. |
| 124 class HidingWindowAnimationObserver : public ui::ImplicitAnimationObserver, | 129 class HidingWindowAnimationObserver : public ui::ImplicitAnimationObserver, |
| 125 public aura::WindowObserver { | 130 public aura::WindowObserver { |
| 126 public: | 131 public: |
| 127 explicit HidingWindowAnimationObserver(aura::Window* window) | 132 explicit HidingWindowAnimationObserver(aura::Window* window) |
| 128 : window_(window) { | 133 : window_(window), |
| 134 layers_detached_(false) { |
| 129 window_->AddObserver(this); | 135 window_->AddObserver(this); |
| 136 window->SetProperty(kHidingWindowAnimationObserverKey, this); |
| 130 } | 137 } |
| 131 virtual ~HidingWindowAnimationObserver() { | 138 virtual ~HidingWindowAnimationObserver() { |
| 132 STLDeleteElements(&layers_); | 139 STLDeleteElements(&layers_); |
| 133 } | 140 } |
| 134 | 141 |
| 142 ui::Layer* DetachAndRecreateLayers() { |
| 143 ui::Layer* old_layer = views::corewm::RecreateWindowLayers(window_, true); |
| 144 // Make the new layer unvisible immediately. |
| 145 window_->layer()->SetVisible(false); |
| 146 layers_.push_back(old_layer); |
| 147 layers_detached_ = true; |
| 148 return old_layer; |
| 149 } |
| 150 |
| 135 private: | 151 private: |
| 136 // Overridden from ui::ImplicitAnimationObserver: | 152 // Overridden from ui::ImplicitAnimationObserver: |
| 137 virtual void OnImplicitAnimationsCompleted() OVERRIDE { | 153 virtual void OnImplicitAnimationsCompleted() OVERRIDE { |
| 138 // Window may have been destroyed by this point. | 154 // Window may have been destroyed by this point. |
| 139 if (window_) { | 155 if (window_) { |
| 140 aura::client::AnimationHost* animation_host = | 156 aura::client::AnimationHost* animation_host = |
| 141 aura::client::GetAnimationHost(window_); | 157 aura::client::GetAnimationHost(window_); |
| 142 if (animation_host) | 158 if (animation_host) |
| 143 animation_host->OnWindowHidingAnimationCompleted(); | 159 animation_host->OnWindowHidingAnimationCompleted(); |
| 144 window_->RemoveObserver(this); | 160 window_->RemoveObserver(this); |
| 161 window_->ClearProperty(kHidingWindowAnimationObserverKey); |
| 145 } | 162 } |
| 146 delete this; | 163 delete this; |
| 147 } | 164 } |
| 148 | 165 |
| 149 // Overridden from aura::WindowObserver: | 166 // Overridden from aura::WindowObserver: |
| 150 virtual void OnWindowDestroying(aura::Window* window) OVERRIDE { | 167 virtual void OnWindowDestroying(aura::Window* window) OVERRIDE { |
| 151 DCHECK_EQ(window, window_); | 168 DCHECK_EQ(window, window_); |
| 152 DCHECK(layers_.empty()); | 169 DCHECK(layers_.empty() || layers_detached_); |
| 153 AcquireAllLayers(window_); | 170 if (!layers_detached_) { |
| 154 | 171 AcquireAllLayers(window_); |
| 155 // If the Widget has views with layers, then it is necessary to take | 172 // If the Widget has views with layers, then it is necessary to take |
| 156 // ownership of those layers too. | 173 // ownership of those layers too. |
| 157 views::Widget* widget = views::Widget::GetWidgetForNativeWindow(window_); | 174 views::Widget* widget = views::Widget::GetWidgetForNativeWindow(window_); |
| 158 const views::Widget* const_widget = widget; | 175 const views::Widget* const_widget = widget; |
| 159 if (widget && const_widget->GetRootView() && widget->GetContentsView()) | 176 if (widget && const_widget->GetRootView() && widget->GetContentsView()) |
| 160 AcquireAllViewLayers(widget->GetContentsView()); | 177 AcquireAllViewLayers(widget->GetContentsView()); |
| 178 } |
| 161 window_->RemoveObserver(this); | 179 window_->RemoveObserver(this); |
| 162 window_ = NULL; | 180 window_ = NULL; |
| 163 } | 181 } |
| 164 | 182 |
| 165 void AcquireAllLayers(aura::Window* window) { | 183 void AcquireAllLayers(aura::Window* window) { |
| 166 ui::Layer* layer = window->AcquireLayer(); | 184 ui::Layer* layer = window->AcquireLayer(); |
| 167 DCHECK(layer); | 185 DCHECK(layer); |
| 168 layers_.push_back(layer); | 186 layers_.push_back(layer); |
| 169 for (aura::Window::Windows::const_iterator it = window->children().begin(); | 187 for (aura::Window::Windows::const_iterator it = window->children().begin(); |
| 170 it != window->children().end(); | 188 it != window->children().end(); |
| 171 ++it) | 189 ++it) |
| 172 AcquireAllLayers(*it); | 190 AcquireAllLayers(*it); |
| 173 } | 191 } |
| 174 | 192 |
| 175 void AcquireAllViewLayers(views::View* view) { | 193 void AcquireAllViewLayers(views::View* view) { |
| 176 for (int i = 0; i < view->child_count(); ++i) | 194 for (int i = 0; i < view->child_count(); ++i) |
| 177 AcquireAllViewLayers(view->child_at(i)); | 195 AcquireAllViewLayers(view->child_at(i)); |
| 178 if (view->layer()) { | 196 if (view->layer()) { |
| 179 ui::Layer* layer = view->RecreateLayer(); | 197 ui::Layer* layer = view->RecreateLayer(); |
| 180 if (layer) { | 198 if (layer) { |
| 181 layer->SuppressPaint(); | 199 layer->SuppressPaint(); |
| 182 layers_.push_back(layer); | 200 layers_.push_back(layer); |
| 183 } | 201 } |
| 184 } | 202 } |
| 185 } | 203 } |
| 186 | 204 |
| 187 aura::Window* window_; | 205 aura::Window* window_; |
| 188 std::vector<ui::Layer*> layers_; | 206 std::vector<ui::Layer*> layers_; |
| 207 bool layers_detached_; |
| 189 | 208 |
| 190 DISALLOW_COPY_AND_ASSIGN(HidingWindowAnimationObserver); | 209 DISALLOW_COPY_AND_ASSIGN(HidingWindowAnimationObserver); |
| 191 }; | 210 }; |
| 192 | 211 |
| 193 void GetTransformRelativeToRoot(ui::Layer* layer, gfx::Transform* transform) { | 212 void GetTransformRelativeToRoot(ui::Layer* layer, gfx::Transform* transform) { |
| 194 const Layer* root = layer; | 213 const Layer* root = layer; |
| 195 while (root->parent()) | 214 while (root->parent()) |
| 196 root = root->parent(); | 215 root = root->parent(); |
| 197 layer->GetTargetTransformRelativeTo(root, transform); | 216 layer->GetTargetTransformRelativeTo(root, transform); |
| 198 } | 217 } |
| (...skipping 340 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 539 void SetWindowVisibilityAnimationVerticalPosition(aura::Window* window, | 558 void SetWindowVisibilityAnimationVerticalPosition(aura::Window* window, |
| 540 float position) { | 559 float position) { |
| 541 window->SetProperty(kWindowVisibilityAnimationVerticalPositionKey, position); | 560 window->SetProperty(kWindowVisibilityAnimationVerticalPositionKey, position); |
| 542 } | 561 } |
| 543 | 562 |
| 544 ui::ImplicitAnimationObserver* CreateHidingWindowAnimationObserver( | 563 ui::ImplicitAnimationObserver* CreateHidingWindowAnimationObserver( |
| 545 aura::Window* window) { | 564 aura::Window* window) { |
| 546 return new HidingWindowAnimationObserver(window); | 565 return new HidingWindowAnimationObserver(window); |
| 547 } | 566 } |
| 548 | 567 |
| 568 ui::Layer* DetachHidingAnimationLayer(aura::Window* window) { |
| 569 HidingWindowAnimationObserver* observer = |
| 570 window->GetProperty(kHidingWindowAnimationObserverKey); |
| 571 return observer ? observer->DetachAndRecreateLayers() : NULL; |
| 572 } |
| 573 |
| 549 bool AnimateOnChildWindowVisibilityChanged(aura::Window* window, bool visible) { | 574 bool AnimateOnChildWindowVisibilityChanged(aura::Window* window, bool visible) { |
| 550 if (WindowAnimationsDisabled(window)) | 575 if (WindowAnimationsDisabled(window)) |
| 551 return false; | 576 return false; |
| 552 if (visible) | 577 if (visible) |
| 553 return AnimateShowWindow(window); | 578 return AnimateShowWindow(window); |
| 554 // Don't start hiding the window again if it's already being hidden. | 579 // Don't start hiding the window again if it's already being hidden. |
| 555 return window->layer()->GetTargetOpacity() != 0.0f && | 580 return window->layer()->GetTargetOpacity() != 0.0f && |
| 556 AnimateHideWindow(window); | 581 AnimateHideWindow(window); |
| 557 } | 582 } |
| 558 | 583 |
| (...skipping 10 matching lines...) Expand all Loading... |
| 569 | 594 |
| 570 bool WindowAnimationsDisabled(aura::Window* window) { | 595 bool WindowAnimationsDisabled(aura::Window* window) { |
| 571 return (!gfx::Animation::ShouldRenderRichAnimation() || (window && | 596 return (!gfx::Animation::ShouldRenderRichAnimation() || (window && |
| 572 window->GetProperty(aura::client::kAnimationsDisabledKey)) || | 597 window->GetProperty(aura::client::kAnimationsDisabledKey)) || |
| 573 CommandLine::ForCurrentProcess()->HasSwitch( | 598 CommandLine::ForCurrentProcess()->HasSwitch( |
| 574 switches::kWindowAnimationsDisabled)); | 599 switches::kWindowAnimationsDisabled)); |
| 575 } | 600 } |
| 576 | 601 |
| 577 } // namespace corewm | 602 } // namespace corewm |
| 578 } // namespace views | 603 } // namespace views |
| OLD | NEW |