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 panel::ResizingSides sides); 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