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