// 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_H_ #define CHROME_BROWSER_UI_PANELS_PANEL_H_ #include #include "base/gtest_prod_util.h" #include "base/memory/scoped_ptr.h" #include "base/memory/weak_ptr.h" #include "base/strings/string16.h" #include "chrome/browser/command_updater.h" #include "chrome/browser/command_updater_delegate.h" #include "chrome/browser/ui/panels/panel_constants.h" #include "components/sessions/session_id.h" #include "content/public/browser/notification_observer.h" #include "content/public/browser/notification_registrar.h" #include "extensions/browser/extension_registry_observer.h" #include "ui/base/base_window.h" #include "ui/gfx/image/image.h" #include "ui/gfx/rect.h" class GURL; class NativePanel; class PanelCollection; class PanelHost; class PanelManager; class Profile; class StackedPanelCollection; namespace content { class WebContents; struct NativeWebKeyboardEvent; } namespace extensions { class Extension; class ExtensionRegistry; class WindowController; } // A platform independent implementation of ui::BaseWindow for Panels. // This class gets the first crack at all the ui::BaseWindow calls for Panels // and does one or more of the following: // - Do nothing. The function is not relevant to Panels. // - Do Panel specific platform independent processing and then invoke the // function on the platform specific member. For example, restrict panel // size to certain limits. // - Invoke an appropriate PanelManager function to do stuff that might affect // other Panels. For example deleting a panel would rearrange other panels. class Panel : public ui::BaseWindow, public CommandUpdaterDelegate, public content::NotificationObserver, public extensions::ExtensionRegistryObserver { public: enum ExpansionState { // The panel is fully expanded with both title-bar and the client-area. EXPANDED, // The panel is shown with the title-bar only. TITLE_ONLY, // The panel is shown with 3-pixel line. MINIMIZED }; // Controls how the attention should be drawn. enum AttentionMode { // Uses the panel attention. The panel's titlebar would be painted // differently to attract the user's attention. This is the default mode. USE_PANEL_ATTENTION = 0x01, // Uses the system attention. On Windows or Linux (depending on Window // Manager), the app icon on taskbar will be flashed. On MacOS, the dock // icon will jump once. USE_SYSTEM_ATTENTION = 0x02 }; virtual ~Panel(); // Returns the PanelManager associated with this panel. PanelManager* manager() const; const std::string& app_name() const { return app_name_; } const gfx::Image& app_icon() const { return app_icon_; } const SessionID& session_id() const { return session_id_; } extensions::WindowController* extension_window_controller() const { return extension_window_controller_.get(); } const std::string extension_id() const; CommandUpdater* command_updater(); Profile* profile() const; const extensions::Extension* GetExtension() const; // Returns web contents of the panel, if any. There may be none if web // contents have not been added to the panel yet. content::WebContents* GetWebContents() const; void SetExpansionState(ExpansionState new_expansion_state); bool IsDrawingAttention() const; // This function will only get called by PanelManager when full screen mode // changes i.e it gets called when an app goes into full screen mode or when // an app exits full screen mode. Panel should respond by making sure // a) it does not go on top when some app enters full screen mode. // b) it remains on top when an app exits full screen mode. void FullScreenModeChanged(bool is_full_screen); int TitleOnlyHeight() const; // Returns true if the panel can show minimize or restore button in its // titlebar, depending on its state. bool CanShowMinimizeButton() const; bool CanShowRestoreButton() const; // ui::BaseWindow overrides. virtual bool IsActive() const OVERRIDE; virtual bool IsMaximized() const OVERRIDE; virtual bool IsMinimized() const OVERRIDE; virtual bool IsFullscreen() const OVERRIDE; virtual gfx::NativeWindow GetNativeWindow() OVERRIDE; virtual gfx::Rect GetRestoredBounds() const OVERRIDE; virtual ui::WindowShowState GetRestoredState() const OVERRIDE; virtual gfx::Rect GetBounds() const OVERRIDE; virtual void Show() OVERRIDE; virtual void Hide() OVERRIDE; virtual void ShowInactive() OVERRIDE; virtual void Close() OVERRIDE; virtual void Activate() OVERRIDE; virtual void Deactivate() OVERRIDE; virtual void Maximize() OVERRIDE; virtual void Minimize() OVERRIDE; virtual void Restore() OVERRIDE; virtual void SetBounds(const gfx::Rect& bounds) OVERRIDE; virtual void FlashFrame(bool flash) OVERRIDE; virtual bool IsAlwaysOnTop() const OVERRIDE; virtual void SetAlwaysOnTop(bool on_top) OVERRIDE; // Overridden from CommandUpdaterDelegate: virtual void ExecuteCommandWithDisposition( int id, WindowOpenDisposition disposition) OVERRIDE; // content::NotificationObserver overrides. virtual void Observe(int type, const content::NotificationSource& source, const content::NotificationDetails& details) OVERRIDE; // extensions::ExtensionRegistryObserver. virtual void OnExtensionUnloaded( content::BrowserContext* browser_context, const extensions::Extension* extension, extensions::UnloadedExtensionInfo::Reason reason) OVERRIDE; // Construct a native panel implementation. static NativePanel* CreateNativePanel(Panel* panel, const gfx::Rect& bounds, bool always_on_top); NativePanel* native_panel() const { return native_panel_; } // Invoked when the native panel has detected a mouse click on the // panel's titlebar, minimize or restore buttons. Behavior of the // click may be modified as indicated by |modifier|. void OnTitlebarClicked(panel::ClickModifier modifier); void OnMinimizeButtonClicked(panel::ClickModifier modifier); void OnRestoreButtonClicked(panel::ClickModifier modifier); // Used on platforms where the panel cannot determine its window size // until the window has been created. (e.g. GTK) void OnWindowSizeAvailable(); // Asynchronous completion of panel close request. void OnNativePanelClosed(); // May be NULL if: // * panel is newly created and has not been positioned yet. // * panel is being closed asynchronously. // Please use it with caution. PanelCollection* collection() const { return collection_; } // Sets the current panel collection that contains this panel. void set_collection(PanelCollection* new_collection) { collection_ = new_collection; } StackedPanelCollection* stack() const; ExpansionState expansion_state() const { return expansion_state_; } const gfx::Size& min_size() const { return min_size_; } const gfx::Size& max_size() const { return max_size_; } bool auto_resizable() const { return auto_resizable_; } bool in_preview_mode() const { return in_preview_mode_; } panel::Resizability CanResizeByMouse() const; AttentionMode attention_mode() const { return attention_mode_; } void set_attention_mode(AttentionMode attention_mode) { attention_mode_ = attention_mode; } // The full size is the size of the panel when it is detached or expanded // in the docked collection and squeezing mode is not on. gfx::Size full_size() const { return full_size_; } void set_full_size(const gfx::Size& size) { full_size_ = size; } // Panel must be initialized to be "fully created" and ready for use. // Only called by PanelManager. bool initialized() const { return initialized_; } void Initialize(const GURL& url, const gfx::Rect& bounds, bool always_on_top); // This is different from BaseWindow::SetBounds(): // * SetPanelBounds() is only called by PanelManager to manage its position. // * SetBounds() is called by the API to try to change the bounds, which may // only change the size for Panel. void SetPanelBounds(const gfx::Rect& bounds); // Updates the panel bounds instantly without any animation. void SetPanelBoundsInstantly(const gfx::Rect& bounds); // Ensures that the panel's size does not exceed the work area by updating // maximum and full size of the panel. This is called each time when display // settings are changed. Note that bounds are not updated here and the call // of setting bounds or refreshing layout should be called after this. void LimitSizeToWorkArea(const gfx::Rect& work_area); // Sets whether the panel will auto resize according to its content. void SetAutoResizable(bool resizable); // Configures the web contents for auto resize, including configurations // on the renderer and detecting renderer changes. void EnableWebContentsAutoResize(content::WebContents* web_contents); // Invoked when the preferred window size of the given panel might need to // get changed due to the contents being auto-resized. void OnContentsAutoResized(const gfx::Size& new_content_size); // Resizes the panel and sets the origin. Invoked when the panel is resized // via the mouse. void OnWindowResizedByMouse(const gfx::Rect& new_bounds); // Sets minimum and maximum size for the panel. void SetSizeRange(const gfx::Size& min_size, const gfx::Size& max_size); // Updates the maximum size of the panel so that it's never smaller than the // panel's desired size. Note that even if the user resizes the panel smaller // later, the increased maximum size will still be in effect. Since it's not // possible currently to switch the panel back to autosizing from // user-resizable, it should not be a problem. void IncreaseMaxSize(const gfx::Size& desired_panel_size); // Handles keyboard events coming back from the renderer. void HandleKeyboardEvent(const content::NativeWebKeyboardEvent& event); // Sets whether the panel is shown in preview mode. When the panel is // being dragged, it is in preview mode. void SetPreviewMode(bool in_preview_mode); // Sets whether the minimize or restore button, if any, are visible. void UpdateMinimizeRestoreButtonVisibility(); // Changes the preferred size to acceptable based on min_size() and max_size() gfx::Size ClampSize(const gfx::Size& size) const; // Called when the panel's active state changes. // |active| is true if panel became active. void OnActiveStateChanged(bool active); // Called when the panel starts/ends the user resizing. void OnPanelStartUserResizing(); void OnPanelEndUserResizing(); // Gives beforeunload handlers the chance to cancel the close. bool ShouldCloseWindow(); // Invoked when the window containing us is closing. Performs the necessary // cleanup. void OnWindowClosing(); // Executes a command if it's enabled. // Returns true if the command is executed. bool ExecuteCommandIfEnabled(int id); // Gets the title of the window from the web contents. base::string16 GetWindowTitle() const; // Gets the Favicon of the web contents. gfx::Image GetCurrentPageIcon() const; // Updates the title bar to display the current title and icon. void UpdateTitleBar(); // Updates UI to reflect change in loading state. void LoadingStateChanged(bool is_loading); // Updates UI to reflect that the web cotents receives the focus. void WebContentsFocused(content::WebContents* contents); // Moves the panel by delta instantly. void MoveByInstantly(const gfx::Vector2d& delta_origin); // Applies |corner_style| to the panel window. void SetWindowCornerStyle(panel::CornerStyle corner_style); // Performs the system minimize for the panel, i.e. becoming iconic. void MinimizeBySystem(); bool IsMinimizedBySystem() const; // Returns true if the panel is shown in the active desktop. The user could // create or use multiple desktops or workspaces. bool IsShownOnActiveDesktop() const; // Turns on/off the shadow effect around the window shape. void ShowShadow(bool show); protected: // Panel can only be created using PanelManager::CreatePanel() or subclass. // |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. Panel(Profile* profile, const std::string& app_name, const gfx::Size& min_size, const gfx::Size& max_size); private: friend class PanelManager; friend class PanelBrowserTest; enum MaxSizePolicy { // Default maximum size is proportional to the work area. DEFAULT_MAX_SIZE, // Custom maximum size is used when the panel is resized by the user. CUSTOM_MAX_SIZE }; void OnImageLoaded(const gfx::Image& image); // Initialize state for all supported commands. void InitCommandState(); // Configures the renderer for auto resize (if auto resize is enabled). void ConfigureAutoResize(content::WebContents* web_contents); // Load the app's image, firing a load state change when loaded. void UpdateAppIcon(); // Prepares a title string for display (removes embedded newlines, etc). static void FormatTitleForDisplay(base::string16* title); // The application name that is also the name of the window when the // page content does not provide a title. // This name should be set when the panel is created. const std::string app_name_; Profile* profile_; // Current collection of panels to which this panel belongs. This determines // the panel's screen layout. PanelCollection* collection_; // Owned by PanelManager. bool initialized_; // Stores the full size of the panel so we can restore it after it's // been minimized or squeezed due to lack of space in the collection. gfx::Size full_size_; // This is the minimum size that the panel can shrink to. gfx::Size min_size_; // This is the size beyond which the panel is not going to grow to accomodate // the growing content and WebKit would add the scrollbars in such case. gfx::Size max_size_; MaxSizePolicy max_size_policy_; // True if this panel auto resizes based on content. bool auto_resizable_; // True if this panel is in preview mode. When in preview mode, panel bounds // should not be affected by layout refresh. This is currently used by drag // controller to add a panel to the collection without causing its bounds to // change. bool in_preview_mode_; // Platform specifc implementation for panels. It'd be one of // PanelGtk/PanelView/PanelCocoa. NativePanel* native_panel_; // Weak, owns us. AttentionMode attention_mode_; ExpansionState expansion_state_; // The CommandUpdater manages the window commands. CommandUpdater command_updater_; content::NotificationRegistrar registrar_; extensions::ExtensionRegistry* extension_registry_; const SessionID session_id_; scoped_ptr extension_window_controller_; scoped_ptr panel_host_; // Icon showed in the task bar. gfx::Image app_icon_; base::WeakPtrFactory image_loader_ptr_factory_; DISALLOW_COPY_AND_ASSIGN(Panel); }; #endif // CHROME_BROWSER_UI_PANELS_PANEL_H_