Home | History | Annotate | Download | only in panels
      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_H_
      6 #define CHROME_BROWSER_UI_PANELS_PANEL_H_
      7 
      8 #include <string>
      9 
     10 #include "base/gtest_prod_util.h"
     11 #include "base/memory/scoped_ptr.h"
     12 #include "base/memory/weak_ptr.h"
     13 #include "base/strings/string16.h"
     14 #include "chrome/browser/command_updater.h"
     15 #include "chrome/browser/command_updater_delegate.h"
     16 #include "chrome/browser/sessions/session_id.h"
     17 #include "chrome/browser/ui/panels/panel_constants.h"
     18 #include "content/public/browser/notification_observer.h"
     19 #include "content/public/browser/notification_registrar.h"
     20 #include "ui/base/base_window.h"
     21 #include "ui/gfx/image/image.h"
     22 #include "ui/gfx/rect.h"
     23 
     24 class GURL;
     25 class NativePanel;
     26 class PanelCollection;
     27 class PanelHost;
     28 class PanelManager;
     29 class Profile;
     30 class StackedPanelCollection;
     31 
     32 namespace content {
     33 class WebContents;
     34 struct NativeWebKeyboardEvent;
     35 }
     36 
     37 namespace extensions {
     38 class Extension;
     39 class WindowController;
     40 }
     41 
     42 // A platform independent implementation of ui::BaseWindow for Panels.
     43 // This class gets the first crack at all the ui::BaseWindow calls for Panels
     44 // and does one or more of the following:
     45 // - Do nothing.  The function is not relevant to Panels.
     46 // - Do Panel specific platform independent processing and then invoke the
     47 //   function on the platform specific member. For example, restrict panel
     48 //   size to certain limits.
     49 // - Invoke an appropriate PanelManager function to do stuff that might affect
     50 //   other Panels. For example deleting a panel would rearrange other panels.
     51 class Panel : public ui::BaseWindow,
     52               public CommandUpdaterDelegate,
     53               public content::NotificationObserver {
     54  public:
     55   enum ExpansionState {
     56     // The panel is fully expanded with both title-bar and the client-area.
     57     EXPANDED,
     58     // The panel is shown with the title-bar only.
     59     TITLE_ONLY,
     60     // The panel is shown with 3-pixel line.
     61     MINIMIZED
     62   };
     63 
     64   // Controls how the attention should be drawn.
     65   enum AttentionMode {
     66     // Uses the panel attention. The panel's titlebar would be painted
     67     // differently to attract the user's attention. This is the default mode.
     68     USE_PANEL_ATTENTION = 0x01,
     69     // Uses the system attention. On Windows or Linux (depending on Window
     70     // Manager), the app icon on taskbar will be flashed. On MacOS, the dock
     71     // icon will jump once.
     72     USE_SYSTEM_ATTENTION = 0x02
     73   };
     74 
     75   virtual ~Panel();
     76 
     77   // Returns the PanelManager associated with this panel.
     78   PanelManager* manager() const;
     79 
     80   const std::string& app_name() const { return app_name_; }
     81   const gfx::Image& app_icon() const { return app_icon_; }
     82   const SessionID& session_id() const { return session_id_; }
     83   extensions::WindowController* extension_window_controller() const {
     84     return extension_window_controller_.get();
     85   }
     86   const std::string extension_id() const;
     87 
     88   CommandUpdater* command_updater();
     89   Profile* profile() const;
     90 
     91   const extensions::Extension* GetExtension() const;
     92 
     93   // Returns web contents of the panel, if any. There may be none if web
     94   // contents have not been added to the panel yet.
     95   content::WebContents* GetWebContents() const;
     96 
     97   void SetExpansionState(ExpansionState new_expansion_state);
     98 
     99   bool IsDrawingAttention() const;
    100 
    101   // This function will only get called by PanelManager when full screen mode
    102   // changes i.e it gets called when an app goes into full screen mode or when
    103   // an app exits full screen mode. Panel should respond by making sure
    104   // a) it does not go on top when some app enters full screen mode.
    105   // b) it remains on top when an app exits full screen mode.
    106   void FullScreenModeChanged(bool is_full_screen);
    107 
    108   int TitleOnlyHeight() const;
    109 
    110   // Returns true if the panel can show minimize or restore button in its
    111   // titlebar, depending on its state.
    112   bool CanShowMinimizeButton() const;
    113   bool CanShowRestoreButton() const;
    114 
    115   // ui::BaseWindow overrides.
    116   virtual bool IsActive() const OVERRIDE;
    117   virtual bool IsMaximized() const OVERRIDE;
    118   virtual bool IsMinimized() const OVERRIDE;
    119   virtual bool IsFullscreen() const OVERRIDE;
    120   virtual gfx::NativeWindow GetNativeWindow() OVERRIDE;
    121   virtual gfx::Rect GetRestoredBounds() const OVERRIDE;
    122   virtual ui::WindowShowState GetRestoredState() const OVERRIDE;
    123   virtual gfx::Rect GetBounds() const OVERRIDE;
    124   virtual void Show() OVERRIDE;
    125   virtual void Hide() OVERRIDE;
    126   virtual void ShowInactive() OVERRIDE;
    127   virtual void Close() OVERRIDE;
    128   virtual void Activate() OVERRIDE;
    129   virtual void Deactivate() OVERRIDE;
    130   virtual void Maximize() OVERRIDE;
    131   virtual void Minimize() OVERRIDE;
    132   virtual void Restore() OVERRIDE;
    133   virtual void SetBounds(const gfx::Rect& bounds) OVERRIDE;
    134   virtual void FlashFrame(bool flash) OVERRIDE;
    135   virtual bool IsAlwaysOnTop() const OVERRIDE;
    136 
    137   // Overridden from CommandUpdaterDelegate:
    138   virtual void ExecuteCommandWithDisposition(
    139       int id,
    140       WindowOpenDisposition disposition) OVERRIDE;
    141 
    142   // content::NotificationObserver overrides.
    143   virtual void Observe(int type,
    144                        const content::NotificationSource& source,
    145                        const content::NotificationDetails& details) OVERRIDE;
    146 
    147   // Construct a native panel implementation.
    148   static NativePanel* CreateNativePanel(Panel* panel,
    149                                         const gfx::Rect& bounds,
    150                                         bool always_on_top);
    151 
    152   NativePanel* native_panel() const { return native_panel_; }
    153 
    154   // Invoked when the native panel has detected a mouse click on the
    155   // panel's titlebar, minimize or restore buttons. Behavior of the
    156   // click may be modified as indicated by |modifier|.
    157   void OnTitlebarClicked(panel::ClickModifier modifier);
    158   void OnMinimizeButtonClicked(panel::ClickModifier modifier);
    159   void OnRestoreButtonClicked(panel::ClickModifier modifier);
    160 
    161   // Used on platforms where the panel cannot determine its window size
    162   // until the window has been created. (e.g. GTK)
    163   void OnWindowSizeAvailable();
    164 
    165   // Asynchronous completion of panel close request.
    166   void OnNativePanelClosed();
    167 
    168   // May be NULL if:
    169   // * panel is newly created and has not been positioned yet.
    170   // * panel is being closed asynchronously.
    171   // Please use it with caution.
    172   PanelCollection* collection() const { return collection_; }
    173 
    174   // Sets the current panel collection that contains this panel.
    175   void set_collection(PanelCollection* new_collection) {
    176     collection_ = new_collection;
    177   }
    178 
    179   StackedPanelCollection* stack() const;
    180 
    181   ExpansionState expansion_state() const { return expansion_state_; }
    182   const gfx::Size& min_size() const { return min_size_; }
    183   const gfx::Size& max_size() const { return max_size_; }
    184   bool auto_resizable() const { return auto_resizable_; }
    185 
    186   bool in_preview_mode() const { return in_preview_mode_; }
    187 
    188   panel::Resizability CanResizeByMouse() const;
    189 
    190   AttentionMode attention_mode() const { return attention_mode_; }
    191   void set_attention_mode(AttentionMode attention_mode) {
    192     attention_mode_ = attention_mode;
    193   }
    194 
    195   // The full size is the size of the panel when it is detached or expanded
    196   // in the docked collection and squeezing mode is not on.
    197   gfx::Size full_size() const { return full_size_; }
    198   void set_full_size(const gfx::Size& size) { full_size_ = size; }
    199 
    200   // Panel must be initialized to be "fully created" and ready for use.
    201   // Only called by PanelManager.
    202   bool initialized() const { return initialized_; }
    203   void Initialize(const GURL& url, const gfx::Rect& bounds, bool always_on_top);
    204 
    205   // This is different from BaseWindow::SetBounds():
    206   // * SetPanelBounds() is only called by PanelManager to manage its position.
    207   // * SetBounds() is called by the API to try to change the bounds, which may
    208   //   only change the size for Panel.
    209   void SetPanelBounds(const gfx::Rect& bounds);
    210 
    211   // Updates the panel bounds instantly without any animation.
    212   void SetPanelBoundsInstantly(const gfx::Rect& bounds);
    213 
    214   // Ensures that the panel's size does not exceed the work area by updating
    215   // maximum and full size of the panel. This is called each time when display
    216   // settings are changed. Note that bounds are not updated here and the call
    217   // of setting bounds or refreshing layout should be called after this.
    218   void LimitSizeToWorkArea(const gfx::Rect& work_area);
    219 
    220   // Sets whether the panel will auto resize according to its content.
    221   void SetAutoResizable(bool resizable);
    222 
    223   // Configures the web contents for auto resize, including configurations
    224   // on the renderer and detecting renderer changes.
    225   void EnableWebContentsAutoResize(content::WebContents* web_contents);
    226 
    227   // Invoked when the preferred window size of the given panel might need to
    228   // get changed due to the contents being auto-resized.
    229   void OnContentsAutoResized(const gfx::Size& new_content_size);
    230 
    231   // Resizes the panel and sets the origin. Invoked when the panel is resized
    232   // via the mouse.
    233   void OnWindowResizedByMouse(const gfx::Rect& new_bounds);
    234 
    235   // Sets minimum and maximum size for the panel.
    236   void SetSizeRange(const gfx::Size& min_size, const gfx::Size& max_size);
    237 
    238   // Updates the maximum size of the panel so that it's never smaller than the
    239   // panel's desired size. Note that even if the user resizes the panel smaller
    240   // later, the increased maximum size will still be in effect. Since it's not
    241   // possible currently to switch the panel back to autosizing from
    242   // user-resizable, it should not be a problem.
    243   void IncreaseMaxSize(const gfx::Size& desired_panel_size);
    244 
    245   // Handles keyboard events coming back from the renderer.
    246   void HandleKeyboardEvent(const content::NativeWebKeyboardEvent& event);
    247 
    248   // Whether the panel window is always on top.
    249   void SetAlwaysOnTop(bool on_top);
    250 
    251   // Sets whether the panel is shown in preview mode. When the panel is
    252   // being dragged, it is in preview mode.
    253   void SetPreviewMode(bool in_preview_mode);
    254 
    255   // Sets up the panel for being resizable by the user - for example,
    256   // enables the resize mouse cursors when mouse is hovering over the edges.
    257   void EnableResizeByMouse(bool enable);
    258 
    259   // Sets whether the minimize or restore button, if any, are visible.
    260   void UpdateMinimizeRestoreButtonVisibility();
    261 
    262   // Changes the preferred size to acceptable based on min_size() and max_size()
    263   gfx::Size ClampSize(const gfx::Size& size) const;
    264 
    265   // Called when the panel's active state changes.
    266   // |active| is true if panel became active.
    267   void OnActiveStateChanged(bool active);
    268 
    269   // Called when the panel starts/ends the user resizing.
    270   void OnPanelStartUserResizing();
    271   void OnPanelEndUserResizing();
    272 
    273   // Gives beforeunload handlers the chance to cancel the close.
    274   bool ShouldCloseWindow();
    275 
    276   // Invoked when the window containing us is closing. Performs the necessary
    277   // cleanup.
    278   void OnWindowClosing();
    279 
    280   // Executes a command if it's enabled.
    281   // Returns true if the command is executed.
    282   bool ExecuteCommandIfEnabled(int id);
    283 
    284   // Gets the title of the window from the web contents.
    285   string16 GetWindowTitle() const;
    286 
    287   // Gets the Favicon of the web contents.
    288   gfx::Image GetCurrentPageIcon() const;
    289 
    290   // Updates the title bar to display the current title and icon.
    291   void UpdateTitleBar();
    292 
    293   // Updates UI to reflect change in loading state.
    294   void LoadingStateChanged(bool is_loading);
    295 
    296   // Updates UI to reflect that the web cotents receives the focus.
    297   void WebContentsFocused(content::WebContents* contents);
    298 
    299   // Moves the panel by delta instantly.
    300   void MoveByInstantly(const gfx::Vector2d& delta_origin);
    301 
    302   // Applies |corner_style| to the panel window.
    303   void SetWindowCornerStyle(panel::CornerStyle corner_style);
    304 
    305   // Performs the system minimize for the panel, i.e. becoming iconic.
    306   void MinimizeBySystem();
    307 
    308   bool IsMinimizedBySystem() const;
    309 
    310   // Returns true if the panel is shown in the active desktop. The user could
    311   // create or use multiple desktops or workspaces.
    312   bool IsShownOnActiveDesktop() const;
    313 
    314   // Turns on/off the shadow effect around the window shape.
    315   void ShowShadow(bool show);
    316 
    317  protected:
    318   // Panel can only be created using PanelManager::CreatePanel() or subclass.
    319   // |app_name| is the default title for Panels when the page content does not
    320   // provide a title. For extensions, this is usually the application name
    321   // generated from the extension id.
    322   Panel(Profile* profile, const std::string& app_name,
    323         const gfx::Size& min_size, const gfx::Size& max_size);
    324 
    325  private:
    326   friend class PanelManager;
    327   friend class PanelBrowserTest;
    328 
    329   enum MaxSizePolicy {
    330     // Default maximum size is proportional to the work area.
    331     DEFAULT_MAX_SIZE,
    332     // Custom maximum size is used when the panel is resized by the user.
    333     CUSTOM_MAX_SIZE
    334   };
    335 
    336   void OnImageLoaded(const gfx::Image& image);
    337 
    338   // Initialize state for all supported commands.
    339   void InitCommandState();
    340 
    341   // Configures the renderer for auto resize (if auto resize is enabled).
    342   void ConfigureAutoResize(content::WebContents* web_contents);
    343 
    344   // Load the app's image, firing a load state change when loaded.
    345   void UpdateAppIcon();
    346 
    347   // Prepares a title string for display (removes embedded newlines, etc).
    348   static void FormatTitleForDisplay(string16* title);
    349 
    350   // The application name that is also the name of the window when the
    351   // page content does not provide a title.
    352   // This name should be set when the panel is created.
    353   const std::string app_name_;
    354 
    355   Profile* profile_;
    356 
    357   // Current collection of panels to which this panel belongs. This determines
    358   // the panel's screen layout.
    359   PanelCollection* collection_;  // Owned by PanelManager.
    360 
    361   bool initialized_;
    362 
    363   // Stores the full size of the panel so we can restore it after it's
    364   // been minimized or squeezed due to lack of space in the collection.
    365   gfx::Size full_size_;
    366 
    367   // This is the minimum size that the panel can shrink to.
    368   gfx::Size min_size_;
    369 
    370   // This is the size beyond which the panel is not going to grow to accomodate
    371   // the growing content and WebKit would add the scrollbars in such case.
    372   gfx::Size max_size_;
    373 
    374   MaxSizePolicy max_size_policy_;
    375 
    376   // True if this panel auto resizes based on content.
    377   bool auto_resizable_;
    378 
    379   // True if this panel is in preview mode. When in preview mode, panel bounds
    380   // should not be affected by layout refresh. This is currently used by drag
    381   // controller to add a panel to the collection without causing its bounds to
    382   // change.
    383   bool in_preview_mode_;
    384 
    385   // Platform specifc implementation for panels.  It'd be one of
    386   // PanelGtk/PanelView/PanelCocoa.
    387   NativePanel* native_panel_;  // Weak, owns us.
    388 
    389   AttentionMode attention_mode_;
    390 
    391   ExpansionState expansion_state_;
    392 
    393   // The CommandUpdater manages the window commands.
    394   CommandUpdater command_updater_;
    395 
    396   content::NotificationRegistrar registrar_;
    397   const SessionID session_id_;
    398   scoped_ptr<extensions::WindowController> extension_window_controller_;
    399   scoped_ptr<PanelHost> panel_host_;
    400 
    401   // Icon showed in the task bar.
    402   gfx::Image app_icon_;
    403 
    404   base::WeakPtrFactory<Panel> image_loader_ptr_factory_;
    405 
    406   DISALLOW_COPY_AND_ASSIGN(Panel);
    407 };
    408 
    409 #endif  // CHROME_BROWSER_UI_PANELS_PANEL_H_
    410