Home | History | Annotate | Download | only in window_sizer
      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_WINDOW_SIZER_WINDOW_SIZER_H_
      6 #define CHROME_BROWSER_UI_WINDOW_SIZER_WINDOW_SIZER_H_
      7 
      8 #include "base/basictypes.h"
      9 #include "base/memory/scoped_ptr.h"
     10 #include "chrome/browser/ui/host_desktop.h"
     11 #include "ui/base/ui_base_types.h"
     12 #include "ui/gfx/rect.h"
     13 
     14 class Browser;
     15 
     16 namespace gfx {
     17 class Display;
     18 class Screen;
     19 }
     20 
     21 ///////////////////////////////////////////////////////////////////////////////
     22 // WindowSizer
     23 //
     24 //  A class that determines the best new size and position for a window to be
     25 //  shown at based several factors, including the position and size of the last
     26 //  window of the same type, the last saved bounds of the window from the
     27 //  previous session, and default system metrics if neither of the above two
     28 //  conditions exist. The system has built-in providers for monitor metrics
     29 //  and persistent storage (using preferences) but can be overrided with mocks
     30 //  for testing.
     31 //
     32 class WindowSizer {
     33  public:
     34   class StateProvider;
     35   class TargetDisplayProvider;
     36 
     37   // WindowSizer owns |state_provider| and |target_display_provider|,
     38   // and will use the platforms's gfx::Screen.
     39   WindowSizer(scoped_ptr<StateProvider> state_provider,
     40               scoped_ptr<TargetDisplayProvider> target_display_provider,
     41               const Browser* browser);
     42 
     43   // WindowSizer owns |state_provider| and |target_display_provider|,
     44   // and will use the supplied |screen|. Used only for testing.
     45   WindowSizer(scoped_ptr<StateProvider> state_provider,
     46               scoped_ptr<TargetDisplayProvider> target_display_provider,
     47               gfx::Screen* screen,
     48               const Browser* browser);
     49 
     50   virtual ~WindowSizer();
     51 
     52   // An interface implemented by an object that can retrieve state from either a
     53   // persistent store or an existing window.
     54   class StateProvider {
     55    public:
     56     virtual ~StateProvider() {}
     57 
     58     // Retrieve the persisted bounds of the window. Returns true if there was
     59     // persisted data to retrieve state information, false otherwise.
     60     // The |show_state| variable will only be touched if there was persisted
     61     // data and the |show_state| variable is SHOW_STATE_DEFAULT.
     62     virtual bool GetPersistentState(gfx::Rect* bounds,
     63                                     gfx::Rect* work_area,
     64                                     ui::WindowShowState* show_state) const = 0;
     65 
     66     // Retrieve the bounds of the most recent window of the matching type.
     67     // Returns true if there was a last active window to retrieve state
     68     // information from, false otherwise.
     69     // The |show_state| variable will only be touched if we have found a
     70     // suitable window and the |show_state| variable is SHOW_STATE_DEFAULT.
     71     virtual bool GetLastActiveWindowState(
     72         gfx::Rect* bounds,
     73         ui::WindowShowState* show_state) const = 0;
     74   };
     75 
     76   // An interface implemented by an object to identify on which
     77   // display a new window should be located.
     78   class TargetDisplayProvider {
     79     public:
     80       virtual ~TargetDisplayProvider() {}
     81       virtual gfx::Display GetTargetDisplay(const gfx::Screen* screen,
     82                                             const gfx::Rect& bounds) const = 0;
     83   };
     84 
     85   // Determines the position and size for a window as it is created as well
     86   // as the initial state. This function uses several strategies to figure out
     87   // optimal size and placement, first looking for an existing active window,
     88   // then falling back to persisted data from a previous session, finally
     89   // utilizing a default algorithm. If |specified_bounds| are non-empty, this
     90   // value is returned instead. For use only in testing.
     91   // |show_state| will be overwritten and return the initial visual state of
     92   // the window to use.
     93   void DetermineWindowBoundsAndShowState(
     94       const gfx::Rect& specified_bounds,
     95       gfx::Rect* bounds,
     96       ui::WindowShowState* show_state) const;
     97 
     98   // Determines the size, position and maximized state for the browser window.
     99   // See documentation for DetermineWindowBounds above. Normally,
    100   // |window_bounds| is calculated by calling GetLastActiveWindowState(). To
    101   // explicitly specify a particular window to base the bounds on, pass in a
    102   // non-NULL value for |browser|.
    103   static void GetBrowserWindowBoundsAndShowState(
    104       const std::string& app_name,
    105       const gfx::Rect& specified_bounds,
    106       const Browser* browser,
    107       gfx::Rect* window_bounds,
    108       ui::WindowShowState* show_state);
    109 
    110   // Returns the default origin for popups of the given size.
    111   static gfx::Point GetDefaultPopupOrigin(const gfx::Size& size,
    112                                           chrome::HostDesktopType type);
    113 
    114   // How much horizontal and vertical offset there is between newly
    115   // opened windows.  This value may be different on each platform.
    116   static const int kWindowTilePixels;
    117 
    118  private:
    119   // The edge of the screen to check for out-of-bounds.
    120   enum Edge { TOP, LEFT, BOTTOM, RIGHT };
    121 
    122   // Gets the size and placement of the last active window. Returns true if this
    123   // data is valid, false if there is no last window and the application should
    124   // restore saved state from preferences using RestoreWindowPosition.
    125   // |show_state| will only be changed if it was set to SHOW_STATE_DEFAULT.
    126   bool GetLastActiveWindowBounds(gfx::Rect* bounds,
    127                                  ui::WindowShowState* show_state) const;
    128 
    129   // Gets the size and placement of the last window in the last session, saved
    130   // in local state preferences. Returns true if local state exists containing
    131   // this information, false if this information does not exist and a default
    132   // size should be used.
    133   // |show_state| will only be changed if it was set to SHOW_STATE_DEFAULT.
    134   bool GetSavedWindowBounds(gfx::Rect* bounds,
    135                             ui::WindowShowState* show_state) const;
    136 
    137   // Gets the default window position and size to be shown on
    138   // |display| if there is no last window and no saved window
    139   // placement in prefs. This function determines the default size
    140   // based on monitor size, etc.
    141   void GetDefaultWindowBounds(const gfx::Display& display,
    142                               gfx::Rect* default_bounds) const;
    143 
    144   // Adjusts |bounds| to be visible on-screen, biased toward the work area of
    145   // the |display|.  Despite the name, this doesn't
    146   // guarantee the bounds are fully contained within this display's work rect;
    147   // it just tried to ensure the edges are visible on _some_ work rect.
    148   // If |saved_work_area| is non-empty, it is used to determine whether the
    149   // monitor configuration has changed. If it has, bounds are repositioned and
    150   // resized if necessary to make them completely contained in the current work
    151   // area.
    152   void AdjustBoundsToBeVisibleOnDisplay(
    153       const gfx::Display& display,
    154       const gfx::Rect& saved_work_area,
    155       gfx::Rect* bounds) const;
    156 
    157   // Determine the target display for a new window based on
    158   // |bounds|. On ash environment, this returns the display containing
    159   // ash's the target root window.
    160   gfx::Display GetTargetDisplay(const gfx::Rect& bounds) const;
    161 
    162 #if defined(USE_ASH)
    163   // Ash specific logic for window placement. Returns true if |bounds| and
    164   // |show_state| have been fully determined, otherwise returns false (but
    165   // may still affect |show_state|).
    166   // If the window is too big to fit in the display work area then the |bounds|
    167   // are adjusted to default bounds and the |show_state| is adjusted to
    168   // SHOW_STATE_MAXIMIZED.
    169   bool GetBrowserBoundsAsh(gfx::Rect* bounds,
    170                            ui::WindowShowState* show_state) const;
    171 
    172   // Determines the position and size for a tabbed browser window in
    173   // ash as it gets created. This will be called before other standard
    174   // placement logic. |show_state| will only be changed
    175   // if it was set to SHOW_STATE_DEFAULT.
    176   void GetTabbedBrowserBoundsAsh(gfx::Rect* bounds,
    177                                  ui::WindowShowState* show_state) const;
    178 #endif
    179 
    180   // Determine the default show state for the window - not looking at other
    181   // windows or at persistent information.
    182   ui::WindowShowState GetWindowDefaultShowState() const;
    183 
    184   // Providers for persistent storage and monitor metrics.
    185   scoped_ptr<StateProvider> state_provider_;
    186   scoped_ptr<TargetDisplayProvider> target_display_provider_;
    187   gfx::Screen* screen_;  // not owned.
    188 
    189   // Note that this browser handle might be NULL.
    190   const Browser* browser_;
    191 
    192   DISALLOW_COPY_AND_ASSIGN(WindowSizer);
    193 };
    194 
    195 #endif  // CHROME_BROWSER_UI_WINDOW_SIZER_WINDOW_SIZER_H_
    196