panel_manager.h revision f8ee788a64d60abd8f2d742a5fdedde054ecd910
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 CHROME_BROWSER_UI_PANELS_PANEL_MANAGER_H_
6#define CHROME_BROWSER_UI_PANELS_PANEL_MANAGER_H_
7
8#include <list>
9#include <vector>
10#include "base/basictypes.h"
11#include "base/lazy_instance.h"
12#include "base/memory/scoped_ptr.h"
13#include "chrome/browser/ui/panels/display_settings_provider.h"
14#include "chrome/browser/ui/panels/panel.h"
15#include "chrome/browser/ui/panels/panel_collection.h"
16#include "chrome/browser/ui/panels/panel_constants.h"
17#include "ui/gfx/rect.h"
18
19class DetachedPanelCollection;
20class DockedPanelCollection;
21class GURL;
22class PanelDragController;
23class PanelResizeController;
24class PanelMouseWatcher;
25class StackedPanelCollection;
26
27// This class manages a set of panels.
28class PanelManager : public DisplaySettingsProvider::DisplayObserver,
29                     public DisplaySettingsProvider::FullScreenObserver {
30 public:
31  typedef std::list<StackedPanelCollection*> Stacks;
32
33  enum CreateMode {
34    CREATE_AS_DOCKED,  // Creates a docked panel. The default.
35    CREATE_AS_DETACHED  // Creates a detached panel.
36  };
37
38  // Returns a single instance.
39  static PanelManager* GetInstance();
40
41  // Tells PanelManager to use |provider| for testing purpose. This has to be
42  // called before GetInstance.
43  static void SetDisplaySettingsProviderForTesting(
44      DisplaySettingsProvider* provider);
45
46  // Returns true if panels should be used for the extension.
47  static bool ShouldUsePanels(const std::string& extension_id);
48
49  // Returns true if panel stacking support is enabled.
50  static bool IsPanelStackingEnabled();
51
52  // Returns true if a panel can be system-minimized by the desktop
53  // environment. Some desktop environment, like Unity, does not trigger the
54  // "window-state-event" which prevents the minimize and unminimize from
55  // working.
56  static bool CanUseSystemMinimize();
57
58  // Returns the default top-left position for a detached panel.
59  gfx::Point GetDefaultDetachedPanelOrigin();
60
61  // Creates a panel and returns it. The panel might be queued for display
62  // later.
63  // |app_name| is the default title for Panels when the page content does not
64  // provide a title. For extensions, this is usually the application name
65  // generated from the extension id.
66  // |requested_bounds| is the desired bounds for the panel, but actual
67  // bounds may differ after panel layout depending on create |mode|.
68  // |mode| indicates whether panel should be created as docked or detached.
69  Panel* CreatePanel(const std::string& app_name,
70                     Profile* profile,
71                     const GURL& url,
72                     const gfx::Rect& requested_bounds,
73                     CreateMode mode);
74
75  // Close all panels (asynchronous). Panels will be removed after closing.
76  void CloseAll();
77
78  // Asynchronous confirmation of panel having been closed.
79  void OnPanelClosed(Panel* panel);
80
81  // Creates a StackedPanelCollection and returns it.
82  StackedPanelCollection* CreateStack();
83
84  // Deletes |stack|. The stack must be empty at the time of deletion.
85  void RemoveStack(StackedPanelCollection* stack);
86
87  // Returns the maximum size that panel can be auto-resized or resized by the
88  // API.
89  int GetMaxPanelWidth(const gfx::Rect& work_area) const;
90  int GetMaxPanelHeight(const gfx::Rect& work_area) const;
91
92  // Drags the given panel.
93  // |mouse_location| is in screen coordinate system.
94  void StartDragging(Panel* panel, const gfx::Point& mouse_location);
95  void Drag(const gfx::Point& mouse_location);
96  void EndDragging(bool cancelled);
97
98  // Resizes the given panel.
99  // |mouse_location| is in screen coordinate system.
100  void StartResizingByMouse(Panel* panel, const gfx::Point& mouse_location,
101                            int component);
102  void ResizeByMouse(const gfx::Point& mouse_location);
103  void EndResizingByMouse(bool cancelled);
104
105  // Invoked when a panel's expansion state changes.
106  void OnPanelExpansionStateChanged(Panel* panel);
107
108  // Moves the |panel| to a different collection.
109  void MovePanelToCollection(Panel* panel,
110                             PanelCollection* target_collection,
111                             PanelCollection::PositioningMask positioning_mask);
112
113  // Returns true if we should bring up the titlebars, given the current mouse
114  // point.
115  bool ShouldBringUpTitlebars(int mouse_x, int mouse_y) const;
116
117  // Brings up or down the titlebars for all minimized panels.
118  void BringUpOrDownTitlebars(bool bring_up);
119
120  std::vector<Panel*> GetDetachedAndStackedPanels() const;
121
122  int num_panels() const;
123  std::vector<Panel*> panels() const;
124
125  const Stacks& stacks() const { return stacks_; }
126  int num_stacks() const { return stacks_.size(); }
127
128  PanelDragController* drag_controller() const {
129    return drag_controller_.get();
130  }
131
132#ifdef UNIT_TEST
133  PanelResizeController* resize_controller() const {
134    return resize_controller_.get();
135  }
136#endif
137
138  DisplaySettingsProvider* display_settings_provider() const {
139    return display_settings_provider_.get();
140  }
141
142  PanelMouseWatcher* mouse_watcher() const {
143    return panel_mouse_watcher_.get();
144  }
145
146  DetachedPanelCollection* detached_collection() const {
147    return detached_collection_.get();
148  }
149
150  DockedPanelCollection* docked_collection() const {
151    return docked_collection_.get();
152  }
153
154  // Reduces time interval in tests to shorten test run time.
155  // Wrapper should be used around all time intervals in panels code.
156  static inline double AdjustTimeInterval(double interval) {
157    if (shorten_time_intervals_)
158      return interval / 500.0;
159    else
160      return interval;
161  }
162
163
164  bool auto_sizing_enabled() const {
165    return auto_sizing_enabled_;
166  }
167
168  // Called from native level when panel animation ends.
169  void OnPanelAnimationEnded(Panel* panel);
170
171#ifdef UNIT_TEST
172  static void shorten_time_intervals_for_testing() {
173    shorten_time_intervals_ = true;
174  }
175
176  void set_display_settings_provider(
177      DisplaySettingsProvider* display_settings_provider) {
178    display_settings_provider_.reset(display_settings_provider);
179  }
180
181  void enable_auto_sizing(bool enabled) {
182    auto_sizing_enabled_ = enabled;
183  }
184
185  void SetMouseWatcherForTesting(PanelMouseWatcher* watcher) {
186    SetMouseWatcher(watcher);
187  }
188#endif
189
190 private:
191  friend struct base::DefaultLazyInstanceTraits<PanelManager>;
192
193  PanelManager();
194  virtual ~PanelManager();
195
196  void Initialize(DisplaySettingsProvider* provider);
197
198  // Overridden from DisplaySettingsProvider::DisplayObserver:
199  virtual void OnDisplayChanged() OVERRIDE;
200
201  // Overridden from DisplaySettingsProvider::FullScreenObserver:
202  virtual void OnFullScreenModeChanged(bool is_full_screen) OVERRIDE;
203
204  // Returns the collection to which a new panel should add. The new panel
205  // is expected to be created with |bounds| and |mode|. The size of |bounds|
206  // could be used to determine which collection is more appropriate to have
207  // the new panel. Upon return, |positioning_mask| contains the required mask
208  // to be applied when the new panel is being added to the collection.
209  PanelCollection* GetCollectionForNewPanel(
210      Panel* new_panel,
211      const gfx::Rect& bounds,
212      CreateMode mode,
213      PanelCollection::PositioningMask* positioning_mask);
214
215  // Tests may want to use a mock panel mouse watcher.
216  void SetMouseWatcher(PanelMouseWatcher* watcher);
217
218  // Tests may want to shorten time intervals to reduce running time.
219  static bool shorten_time_intervals_;
220
221  scoped_ptr<DetachedPanelCollection> detached_collection_;
222  scoped_ptr<DockedPanelCollection> docked_collection_;
223  Stacks stacks_;
224
225  scoped_ptr<PanelDragController> drag_controller_;
226  scoped_ptr<PanelResizeController> resize_controller_;
227
228  // Use a mouse watcher to know when to bring up titlebars to "peek" at
229  // minimized panels. Mouse movement is only tracked when there is a minimized
230  // panel.
231  scoped_ptr<PanelMouseWatcher> panel_mouse_watcher_;
232
233  scoped_ptr<DisplaySettingsProvider> display_settings_provider_;
234
235  // Whether or not bounds will be updated when the preferred content size is
236  // changed. The testing code could set this flag to false so that other tests
237  // will not be affected.
238  bool auto_sizing_enabled_;
239
240  DISALLOW_COPY_AND_ASSIGN(PanelManager);
241};
242
243#endif  // CHROME_BROWSER_UI_PANELS_PANEL_MANAGER_H_
244