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/desktop_background/desktop_background_widget_controller.h" 6 7 #include "ash/ash_export.h" 8 #include "ash/desktop_background/user_wallpaper_delegate.h" 9 #include "ash/root_window_controller.h" 10 #include "ash/shell.h" 11 #include "ui/aura/root_window.h" 12 #include "ui/compositor/layer_animation_observer.h" 13 #include "ui/compositor/scoped_layer_animation_settings.h" 14 #include "ui/views/widget/widget.h" 15 #include "ui/views/widget/widget_observer.h" 16 17 namespace ash { 18 namespace internal { 19 namespace { 20 21 class ShowWallpaperAnimationObserver : public ui::ImplicitAnimationObserver, 22 public views::WidgetObserver { 23 public: 24 ShowWallpaperAnimationObserver(RootWindowController* root_window_controller, 25 views::Widget* desktop_widget, 26 bool is_initial_animation) 27 : root_window_controller_(root_window_controller), 28 desktop_widget_(desktop_widget), 29 is_initial_animation_(is_initial_animation) { 30 DCHECK(desktop_widget_); 31 desktop_widget_->AddObserver(this); 32 } 33 34 virtual ~ShowWallpaperAnimationObserver() { 35 StopObservingImplicitAnimations(); 36 if (desktop_widget_) 37 desktop_widget_->RemoveObserver(this); 38 } 39 40 private: 41 // Overridden from ui::ImplicitAnimationObserver: 42 virtual void OnImplicitAnimationsScheduled() OVERRIDE { 43 if (is_initial_animation_) { 44 root_window_controller_-> 45 HandleInitialDesktopBackgroundAnimationStarted(); 46 } 47 } 48 49 virtual void OnImplicitAnimationsCompleted() OVERRIDE { 50 root_window_controller_->OnWallpaperAnimationFinished(desktop_widget_); 51 delete this; 52 } 53 54 // Overridden from views::WidgetObserver. 55 virtual void OnWidgetDestroying(views::Widget* widget) OVERRIDE { 56 delete this; 57 } 58 59 RootWindowController* root_window_controller_; 60 views::Widget* desktop_widget_; 61 62 // Is this object observing the initial brightness/grayscale animation? 63 const bool is_initial_animation_; 64 65 DISALLOW_COPY_AND_ASSIGN(ShowWallpaperAnimationObserver); 66 }; 67 68 } // namespace 69 70 DesktopBackgroundWidgetController::DesktopBackgroundWidgetController( 71 views::Widget* widget) : widget_(widget) { 72 DCHECK(widget_); 73 widget_->AddObserver(this); 74 } 75 76 DesktopBackgroundWidgetController::DesktopBackgroundWidgetController( 77 ui::Layer* layer) : widget_(NULL) { 78 layer_.reset(layer); 79 } 80 81 DesktopBackgroundWidgetController::~DesktopBackgroundWidgetController() { 82 if (widget_) { 83 widget_->RemoveObserver(this); 84 widget_->CloseNow(); 85 widget_ = NULL; 86 } else if (layer_) 87 layer_.reset(NULL); 88 } 89 90 void DesktopBackgroundWidgetController::OnWidgetDestroying( 91 views::Widget* widget) { 92 widget_->RemoveObserver(this); 93 widget_ = NULL; 94 } 95 96 void DesktopBackgroundWidgetController::SetBounds(gfx::Rect bounds) { 97 if (widget_) 98 widget_->SetBounds(bounds); 99 else if (layer_) 100 layer_->SetBounds(bounds); 101 } 102 103 bool DesktopBackgroundWidgetController::Reparent(aura::RootWindow* root_window, 104 int src_container, 105 int dest_container) { 106 if (widget_) { 107 views::Widget::ReparentNativeView(widget_->GetNativeView(), 108 root_window->GetChildById(dest_container)); 109 return true; 110 } else if (layer_) { 111 ui::Layer* layer = layer_.get(); 112 root_window->GetChildById(src_container)->layer()->Remove(layer); 113 root_window->GetChildById(dest_container)->layer()->Add(layer); 114 return true; 115 } 116 // Nothing to reparent. 117 return false; 118 } 119 120 void DesktopBackgroundWidgetController::StartAnimating( 121 RootWindowController* root_window_controller) { 122 if (widget_) { 123 ui::ScopedLayerAnimationSettings settings( 124 widget_->GetNativeView()->layer()->GetAnimator()); 125 settings.SetPreemptionStrategy(ui::LayerAnimator::ENQUEUE_NEW_ANIMATION); 126 settings.AddObserver(new ShowWallpaperAnimationObserver( 127 root_window_controller, widget_, 128 Shell::GetInstance()->user_wallpaper_delegate()-> 129 ShouldShowInitialAnimation())); 130 widget_->Show(); 131 widget_->GetNativeView()->SetName("DesktopBackgroundView"); 132 } else if (layer_) 133 root_window_controller->OnWallpaperAnimationFinished(NULL); 134 } 135 136 AnimatingDesktopController::AnimatingDesktopController( 137 DesktopBackgroundWidgetController* component) { 138 controller_.reset(component); 139 } 140 141 AnimatingDesktopController::~AnimatingDesktopController() { 142 } 143 144 void AnimatingDesktopController::StopAnimating() { 145 if (controller_) { 146 ui::Layer* layer = controller_->layer() ? controller_->layer() : 147 controller_->widget()->GetNativeView()->layer(); 148 layer->GetAnimator()->StopAnimating(); 149 } 150 } 151 152 DesktopBackgroundWidgetController* AnimatingDesktopController::GetController( 153 bool pass_ownership) { 154 if (pass_ownership) 155 return controller_.release(); 156 return controller_.get(); 157 } 158 159 } // namespace internal 160 } // namespace ash 161