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