Home | History | Annotate | Download | only in desktop_background
      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