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/window_event_dispatcher.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
17namespace ash {
18namespace {
19
20class ShowWallpaperAnimationObserver : public ui::ImplicitAnimationObserver,
21                                       public views::WidgetObserver {
22 public:
23  ShowWallpaperAnimationObserver(RootWindowController* root_window_controller,
24                                 views::Widget* desktop_widget,
25                                 bool is_initial_animation)
26      : root_window_controller_(root_window_controller),
27        desktop_widget_(desktop_widget),
28        is_initial_animation_(is_initial_animation) {
29    DCHECK(desktop_widget_);
30    desktop_widget_->AddObserver(this);
31  }
32
33  virtual ~ShowWallpaperAnimationObserver() {
34    StopObservingImplicitAnimations();
35    if (desktop_widget_)
36      desktop_widget_->RemoveObserver(this);
37  }
38
39 private:
40  // Overridden from ui::ImplicitAnimationObserver:
41  virtual void OnImplicitAnimationsScheduled() OVERRIDE {
42    if (is_initial_animation_) {
43      root_window_controller_->
44          HandleInitialDesktopBackgroundAnimationStarted();
45    }
46  }
47
48  virtual void OnImplicitAnimationsCompleted() OVERRIDE {
49    root_window_controller_->OnWallpaperAnimationFinished(desktop_widget_);
50    delete this;
51  }
52
53  // Overridden from views::WidgetObserver.
54  virtual void OnWidgetDestroying(views::Widget* widget) OVERRIDE {
55    delete this;
56  }
57
58  RootWindowController* root_window_controller_;
59  views::Widget* desktop_widget_;
60
61  // Is this object observing the initial brightness/grayscale animation?
62  const bool is_initial_animation_;
63
64  DISALLOW_COPY_AND_ASSIGN(ShowWallpaperAnimationObserver);
65};
66
67}  // namespace
68
69DesktopBackgroundWidgetController::DesktopBackgroundWidgetController(
70    views::Widget* widget) : widget_(widget) {
71  DCHECK(widget_);
72  widget_->AddObserver(this);
73}
74
75DesktopBackgroundWidgetController::~DesktopBackgroundWidgetController() {
76  if (widget_) {
77    widget_->RemoveObserver(this);
78    widget_->CloseNow();
79    widget_ = NULL;
80  }
81}
82
83void DesktopBackgroundWidgetController::OnWidgetDestroying(
84    views::Widget* widget) {
85  widget_->RemoveObserver(this);
86  widget_ = NULL;
87}
88
89void DesktopBackgroundWidgetController::SetBounds(gfx::Rect bounds) {
90  if (widget_)
91    widget_->SetBounds(bounds);
92}
93
94bool DesktopBackgroundWidgetController::Reparent(aura::Window* root_window,
95                                                 int src_container,
96                                                 int dest_container) {
97  if (widget_) {
98    views::Widget::ReparentNativeView(widget_->GetNativeView(),
99        root_window->GetChildById(dest_container));
100    return true;
101  }
102  // Nothing to reparent.
103  return false;
104}
105
106void DesktopBackgroundWidgetController::StartAnimating(
107    RootWindowController* root_window_controller) {
108  if (widget_) {
109    ui::ScopedLayerAnimationSettings settings(
110        widget_->GetNativeView()->layer()->GetAnimator());
111    settings.AddObserver(new ShowWallpaperAnimationObserver(
112        root_window_controller, widget_,
113        Shell::GetInstance()->user_wallpaper_delegate()->
114            ShouldShowInitialAnimation()));
115    // When |widget_| shows, AnimateShowWindowCommon() is called to do the
116    // animation. Sets transition duration to 0 to avoid animating to the
117    // show animation's initial values.
118    settings.SetTransitionDuration(base::TimeDelta());
119    widget_->Show();
120    widget_->GetNativeView()->SetName("DesktopBackgroundView");
121  }
122}
123
124AnimatingDesktopController::AnimatingDesktopController(
125    DesktopBackgroundWidgetController* component) {
126  controller_.reset(component);
127}
128
129AnimatingDesktopController::~AnimatingDesktopController() {
130}
131
132void AnimatingDesktopController::StopAnimating() {
133  if (controller_) {
134    ui::Layer* layer = controller_->widget()->GetNativeView()->layer();
135    layer->GetAnimator()->StopAnimating();
136  }
137}
138
139DesktopBackgroundWidgetController* AnimatingDesktopController::GetController(
140    bool pass_ownership) {
141  if (pass_ownership)
142    return controller_.release();
143  return controller_.get();
144}
145
146}  // namespace ash
147