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#ifndef ASH_DESKTOP_BACKGROUND_DESKTOP_BACKGROUND_WIDGET_CONTROLLER_H_
6#define ASH_DESKTOP_BACKGROUND_DESKTOP_BACKGROUND_WIDGET_CONTROLLER_H_
7
8#include "ash/ash_export.h"
9#include "base/memory/scoped_ptr.h"
10#include "ui/aura/window.h"
11#include "ui/compositor/layer.h"
12#include "ui/views/widget/widget.h"
13#include "ui/views/widget/widget_observer.h"
14
15namespace ash {
16class RootWindowController;
17
18// This class implements a widget-based wallpaper.
19// DesktopBackgroundWidgetController is owned by RootWindowController.
20// When the animation completes the old DesktopBackgroundWidgetController is
21// destroyed. Exported for tests.
22class ASH_EXPORT DesktopBackgroundWidgetController
23    : public views::WidgetObserver {
24 public:
25  // Create
26  explicit DesktopBackgroundWidgetController(views::Widget* widget);
27
28  virtual ~DesktopBackgroundWidgetController();
29
30  // Overridden from views::WidgetObserver.
31  virtual void OnWidgetDestroying(views::Widget* widget) OVERRIDE;
32
33  // Set bounds of component that draws background.
34  void SetBounds(gfx::Rect bounds);
35
36  // Move component from |src_container| in |root_window| to |dest_container|.
37  // It is required for lock screen, when we need to move background so that
38  // it hides user's windows. Returns true if there was something to reparent.
39  bool Reparent(aura::Window* root_window,
40                int src_container,
41                int dest_container);
42
43  // Starts wallpaper fade in animation. |root_window_controller| is
44  // the root window where the animation will happen. (This is
45  // necessary this as |layer_| doesn't have access to the root window).
46  void StartAnimating(RootWindowController* root_window_controller);
47
48  views::Widget* widget() { return widget_; }
49
50 private:
51  views::Widget* widget_;
52
53  DISALLOW_COPY_AND_ASSIGN(DesktopBackgroundWidgetController);
54};
55
56// This class wraps a DesktopBackgroundWidgetController pointer. It is owned
57// by RootWindowController. The instance of DesktopBackgroundWidgetController is
58// moved to this RootWindowController when the animation completes.
59// Exported for tests.
60class ASH_EXPORT AnimatingDesktopController {
61 public:
62  explicit AnimatingDesktopController(
63      DesktopBackgroundWidgetController* component);
64  ~AnimatingDesktopController();
65
66  // Stops animation and makes sure OnImplicitAnimationsCompleted() is called if
67  // current animation is not finished yet.
68  // Note we have to make sure this function is called before we set
69  // kAnimatingDesktopController to a new controller. If it is not called, the
70  // animating widget/layer is closed immediately and the new one is animating
71  // from the widget/layer before animation. For instance, if a user quickly
72  // switches between red, green and blue wallpapers. The green wallpaper will
73  // first fade in from red wallpaper. And in the middle of the animation, blue
74  // wallpaper also wants to fade in. If the green wallpaper animation does not
75  // finish immediately, the green wallpaper widget will be removed and the red
76  // widget will show again. As a result, the blue wallpaper fades in from red
77  // wallpaper. This is a bad user experience. See bug http://crbug.com/156542
78  // for more details.
79  void StopAnimating();
80
81  // Gets the wrapped DesktopBackgroundWidgetController pointer. Caller should
82  // take ownership of the pointer if |pass_ownership| is true.
83  DesktopBackgroundWidgetController* GetController(bool pass_ownership);
84
85 private:
86  scoped_ptr<DesktopBackgroundWidgetController> controller_;
87
88  DISALLOW_COPY_AND_ASSIGN(AnimatingDesktopController);
89};
90
91}  // namespace ash
92
93#endif  // ASH_DESKTOP_BACKGROUND_DESKTOP_BACKGROUND_WIDGET_CONTROLLER_H_
94