• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
19 class DetachedPanelCollection;
20 class DockedPanelCollection;
21 class GURL;
22 class PanelDragController;
23 class PanelResizeController;
24 class PanelMouseWatcher;
25 class StackedPanelCollection;
26 
27 // This class manages a set of panels.
28 class 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 
stacks()125   const Stacks& stacks() const { return stacks_; }
num_stacks()126   int num_stacks() const { return stacks_.size(); }
127 
drag_controller()128   PanelDragController* drag_controller() const {
129     return drag_controller_.get();
130   }
131 
132 #ifdef UNIT_TEST
resize_controller()133   PanelResizeController* resize_controller() const {
134     return resize_controller_.get();
135   }
136 #endif
137 
display_settings_provider()138   DisplaySettingsProvider* display_settings_provider() const {
139     return display_settings_provider_.get();
140   }
141 
mouse_watcher()142   PanelMouseWatcher* mouse_watcher() const {
143     return panel_mouse_watcher_.get();
144   }
145 
detached_collection()146   DetachedPanelCollection* detached_collection() const {
147     return detached_collection_.get();
148   }
149 
docked_collection()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.
AdjustTimeInterval(double interval)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 
auto_sizing_enabled()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
shorten_time_intervals_for_testing()172   static void shorten_time_intervals_for_testing() {
173     shorten_time_intervals_ = true;
174   }
175 
set_display_settings_provider(DisplaySettingsProvider * display_settings_provider)176   void set_display_settings_provider(
177       DisplaySettingsProvider* display_settings_provider) {
178     display_settings_provider_.reset(display_settings_provider);
179   }
180 
enable_auto_sizing(bool enabled)181   void enable_auto_sizing(bool enabled) {
182     auto_sizing_enabled_ = enabled;
183   }
184 
SetMouseWatcherForTesting(PanelMouseWatcher * watcher)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