// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef CHROME_BROWSER_UI_PANELS_PANEL_MANAGER_H_ #define CHROME_BROWSER_UI_PANELS_PANEL_MANAGER_H_ #include <list> #include <vector> #include "base/basictypes.h" #include "base/lazy_instance.h" #include "base/memory/scoped_ptr.h" #include "chrome/browser/ui/panels/display_settings_provider.h" #include "chrome/browser/ui/panels/panel.h" #include "chrome/browser/ui/panels/panel_collection.h" #include "chrome/browser/ui/panels/panel_constants.h" #include "ui/gfx/rect.h" class DetachedPanelCollection; class DockedPanelCollection; class GURL; class PanelDragController; class PanelResizeController; class PanelMouseWatcher; class StackedPanelCollection; // This class manages a set of panels. class PanelManager : public DisplaySettingsProvider::DisplayObserver, public DisplaySettingsProvider::FullScreenObserver { public: typedef std::list<StackedPanelCollection*> Stacks; enum CreateMode { CREATE_AS_DOCKED, // Creates a docked panel. The default. CREATE_AS_DETACHED // Creates a detached panel. }; // Returns a single instance. static PanelManager* GetInstance(); // Tells PanelManager to use |provider| for testing purpose. This has to be // called before GetInstance. static void SetDisplaySettingsProviderForTesting( DisplaySettingsProvider* provider); // Returns true if panels should be used for the extension. static bool ShouldUsePanels(const std::string& extension_id); // Returns true if panel stacking support is enabled. static bool IsPanelStackingEnabled(); // Returns true if a panel can be system-minimized by the desktop // environment. Some desktop environment, like Unity, does not trigger the // "window-state-event" which prevents the minimize and unminimize from // working. static bool CanUseSystemMinimize(); // Returns the default top-left position for a detached panel. gfx::Point GetDefaultDetachedPanelOrigin(); // Creates a panel and returns it. The panel might be queued for display // later. // |app_name| is the default title for Panels when the page content does not // provide a title. For extensions, this is usually the application name // generated from the extension id. // |requested_bounds| is the desired bounds for the panel, but actual // bounds may differ after panel layout depending on create |mode|. // |mode| indicates whether panel should be created as docked or detached. Panel* CreatePanel(const std::string& app_name, Profile* profile, const GURL& url, const gfx::Rect& requested_bounds, CreateMode mode); // Close all panels (asynchronous). Panels will be removed after closing. void CloseAll(); // Asynchronous confirmation of panel having been closed. void OnPanelClosed(Panel* panel); // Creates a StackedPanelCollection and returns it. StackedPanelCollection* CreateStack(); // Deletes |stack|. The stack must be empty at the time of deletion. void RemoveStack(StackedPanelCollection* stack); // Returns the maximum size that panel can be auto-resized or resized by the // API. int GetMaxPanelWidth(const gfx::Rect& work_area) const; int GetMaxPanelHeight(const gfx::Rect& work_area) const; // Drags the given panel. // |mouse_location| is in screen coordinate system. void StartDragging(Panel* panel, const gfx::Point& mouse_location); void Drag(const gfx::Point& mouse_location); void EndDragging(bool cancelled); // Resizes the given panel. // |mouse_location| is in screen coordinate system. void StartResizingByMouse(Panel* panel, const gfx::Point& mouse_location, panel::ResizingSides sides); void ResizeByMouse(const gfx::Point& mouse_location); void EndResizingByMouse(bool cancelled); // Invoked when a panel's expansion state changes. void OnPanelExpansionStateChanged(Panel* panel); // Moves the |panel| to a different collection. void MovePanelToCollection(Panel* panel, PanelCollection* target_collection, PanelCollection::PositioningMask positioning_mask); // Returns true if we should bring up the titlebars, given the current mouse // point. bool ShouldBringUpTitlebars(int mouse_x, int mouse_y) const; // Brings up or down the titlebars for all minimized panels. void BringUpOrDownTitlebars(bool bring_up); std::vector<Panel*> GetDetachedAndStackedPanels() const; int num_panels() const; std::vector<Panel*> panels() const; const Stacks& stacks() const { return stacks_; } int num_stacks() const { return stacks_.size(); } PanelDragController* drag_controller() const { return drag_controller_.get(); } #ifdef UNIT_TEST PanelResizeController* resize_controller() const { return resize_controller_.get(); } #endif DisplaySettingsProvider* display_settings_provider() const { return display_settings_provider_.get(); } PanelMouseWatcher* mouse_watcher() const { return panel_mouse_watcher_.get(); } DetachedPanelCollection* detached_collection() const { return detached_collection_.get(); } DockedPanelCollection* docked_collection() const { return docked_collection_.get(); } // Reduces time interval in tests to shorten test run time. // Wrapper should be used around all time intervals in panels code. static inline double AdjustTimeInterval(double interval) { if (shorten_time_intervals_) return interval / 500.0; else return interval; } bool auto_sizing_enabled() const { return auto_sizing_enabled_; } // Called from native level when panel animation ends. void OnPanelAnimationEnded(Panel* panel); #ifdef UNIT_TEST static void shorten_time_intervals_for_testing() { shorten_time_intervals_ = true; } void set_display_settings_provider( DisplaySettingsProvider* display_settings_provider) { display_settings_provider_.reset(display_settings_provider); } void enable_auto_sizing(bool enabled) { auto_sizing_enabled_ = enabled; } void SetMouseWatcherForTesting(PanelMouseWatcher* watcher) { SetMouseWatcher(watcher); } #endif private: friend struct base::DefaultLazyInstanceTraits<PanelManager>; PanelManager(); virtual ~PanelManager(); void Initialize(DisplaySettingsProvider* provider); // Overridden from DisplaySettingsProvider::DisplayObserver: virtual void OnDisplayChanged() OVERRIDE; // Overridden from DisplaySettingsProvider::FullScreenObserver: virtual void OnFullScreenModeChanged(bool is_full_screen) OVERRIDE; // Returns the collection to which a new panel should add. The new panel // is expected to be created with |bounds| and |mode|. The size of |bounds| // could be used to determine which collection is more appropriate to have // the new panel. Upon return, |positioning_mask| contains the required mask // to be applied when the new panel is being added to the collection. PanelCollection* GetCollectionForNewPanel( Panel* new_panel, const gfx::Rect& bounds, CreateMode mode, PanelCollection::PositioningMask* positioning_mask); // Tests may want to use a mock panel mouse watcher. void SetMouseWatcher(PanelMouseWatcher* watcher); // Tests may want to shorten time intervals to reduce running time. static bool shorten_time_intervals_; scoped_ptr<DetachedPanelCollection> detached_collection_; scoped_ptr<DockedPanelCollection> docked_collection_; Stacks stacks_; scoped_ptr<PanelDragController> drag_controller_; scoped_ptr<PanelResizeController> resize_controller_; // Use a mouse watcher to know when to bring up titlebars to "peek" at // minimized panels. Mouse movement is only tracked when there is a minimized // panel. scoped_ptr<PanelMouseWatcher> panel_mouse_watcher_; scoped_ptr<DisplaySettingsProvider> display_settings_provider_; // Whether or not bounds will be updated when the preferred content size is // changed. The testing code could set this flag to false so that other tests // will not be affected. bool auto_sizing_enabled_; DISALLOW_COPY_AND_ASSIGN(PanelManager); }; #endif // CHROME_BROWSER_UI_PANELS_PANEL_MANAGER_H_