• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
app_name()80   const std::string& app_name() const { return app_name_; }
app_icon()81   const gfx::Image& app_icon() const { return app_icon_; }
session_id()82   const SessionID& session_id() const { return session_id_; }
extension_window_controller()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   virtual void SetAlwaysOnTop(bool on_top) OVERRIDE;
137 
138   // Overridden from CommandUpdaterDelegate:
139   virtual void ExecuteCommandWithDisposition(
140       int id,
141       WindowOpenDisposition disposition) OVERRIDE;
142 
143   // content::NotificationObserver overrides.
144   virtual void Observe(int type,
145                        const content::NotificationSource& source,
146                        const content::NotificationDetails& details) OVERRIDE;
147 
148   // Construct a native panel implementation.
149   static NativePanel* CreateNativePanel(Panel* panel,
150                                         const gfx::Rect& bounds,
151                                         bool always_on_top);
152 
native_panel()153   NativePanel* native_panel() const { return native_panel_; }
154 
155   // Invoked when the native panel has detected a mouse click on the
156   // panel's titlebar, minimize or restore buttons. Behavior of the
157   // click may be modified as indicated by |modifier|.
158   void OnTitlebarClicked(panel::ClickModifier modifier);
159   void OnMinimizeButtonClicked(panel::ClickModifier modifier);
160   void OnRestoreButtonClicked(panel::ClickModifier modifier);
161 
162   // Used on platforms where the panel cannot determine its window size
163   // until the window has been created. (e.g. GTK)
164   void OnWindowSizeAvailable();
165 
166   // Asynchronous completion of panel close request.
167   void OnNativePanelClosed();
168 
169   // May be NULL if:
170   // * panel is newly created and has not been positioned yet.
171   // * panel is being closed asynchronously.
172   // Please use it with caution.
collection()173   PanelCollection* collection() const { return collection_; }
174 
175   // Sets the current panel collection that contains this panel.
set_collection(PanelCollection * new_collection)176   void set_collection(PanelCollection* new_collection) {
177     collection_ = new_collection;
178   }
179 
180   StackedPanelCollection* stack() const;
181 
expansion_state()182   ExpansionState expansion_state() const { return expansion_state_; }
min_size()183   const gfx::Size& min_size() const { return min_size_; }
max_size()184   const gfx::Size& max_size() const { return max_size_; }
auto_resizable()185   bool auto_resizable() const { return auto_resizable_; }
186 
in_preview_mode()187   bool in_preview_mode() const { return in_preview_mode_; }
188 
189   panel::Resizability CanResizeByMouse() const;
190 
attention_mode()191   AttentionMode attention_mode() const { return attention_mode_; }
set_attention_mode(AttentionMode attention_mode)192   void set_attention_mode(AttentionMode attention_mode) {
193     attention_mode_ = attention_mode;
194   }
195 
196   // The full size is the size of the panel when it is detached or expanded
197   // in the docked collection and squeezing mode is not on.
full_size()198   gfx::Size full_size() const { return full_size_; }
set_full_size(const gfx::Size & size)199   void set_full_size(const gfx::Size& size) { full_size_ = size; }
200 
201   // Panel must be initialized to be "fully created" and ready for use.
202   // Only called by PanelManager.
initialized()203   bool initialized() const { return initialized_; }
204   void Initialize(const GURL& url, const gfx::Rect& bounds, bool always_on_top);
205 
206   // This is different from BaseWindow::SetBounds():
207   // * SetPanelBounds() is only called by PanelManager to manage its position.
208   // * SetBounds() is called by the API to try to change the bounds, which may
209   //   only change the size for Panel.
210   void SetPanelBounds(const gfx::Rect& bounds);
211 
212   // Updates the panel bounds instantly without any animation.
213   void SetPanelBoundsInstantly(const gfx::Rect& bounds);
214 
215   // Ensures that the panel's size does not exceed the work area by updating
216   // maximum and full size of the panel. This is called each time when display
217   // settings are changed. Note that bounds are not updated here and the call
218   // of setting bounds or refreshing layout should be called after this.
219   void LimitSizeToWorkArea(const gfx::Rect& work_area);
220 
221   // Sets whether the panel will auto resize according to its content.
222   void SetAutoResizable(bool resizable);
223 
224   // Configures the web contents for auto resize, including configurations
225   // on the renderer and detecting renderer changes.
226   void EnableWebContentsAutoResize(content::WebContents* web_contents);
227 
228   // Invoked when the preferred window size of the given panel might need to
229   // get changed due to the contents being auto-resized.
230   void OnContentsAutoResized(const gfx::Size& new_content_size);
231 
232   // Resizes the panel and sets the origin. Invoked when the panel is resized
233   // via the mouse.
234   void OnWindowResizedByMouse(const gfx::Rect& new_bounds);
235 
236   // Sets minimum and maximum size for the panel.
237   void SetSizeRange(const gfx::Size& min_size, const gfx::Size& max_size);
238 
239   // Updates the maximum size of the panel so that it's never smaller than the
240   // panel's desired size. Note that even if the user resizes the panel smaller
241   // later, the increased maximum size will still be in effect. Since it's not
242   // possible currently to switch the panel back to autosizing from
243   // user-resizable, it should not be a problem.
244   void IncreaseMaxSize(const gfx::Size& desired_panel_size);
245 
246   // Handles keyboard events coming back from the renderer.
247   void HandleKeyboardEvent(const content::NativeWebKeyboardEvent& event);
248 
249   // Sets whether the panel is shown in preview mode. When the panel is
250   // being dragged, it is in preview mode.
251   void SetPreviewMode(bool in_preview_mode);
252 
253   // Sets whether the minimize or restore button, if any, are visible.
254   void UpdateMinimizeRestoreButtonVisibility();
255 
256   // Changes the preferred size to acceptable based on min_size() and max_size()
257   gfx::Size ClampSize(const gfx::Size& size) const;
258 
259   // Called when the panel's active state changes.
260   // |active| is true if panel became active.
261   void OnActiveStateChanged(bool active);
262 
263   // Called when the panel starts/ends the user resizing.
264   void OnPanelStartUserResizing();
265   void OnPanelEndUserResizing();
266 
267   // Gives beforeunload handlers the chance to cancel the close.
268   bool ShouldCloseWindow();
269 
270   // Invoked when the window containing us is closing. Performs the necessary
271   // cleanup.
272   void OnWindowClosing();
273 
274   // Executes a command if it's enabled.
275   // Returns true if the command is executed.
276   bool ExecuteCommandIfEnabled(int id);
277 
278   // Gets the title of the window from the web contents.
279   base::string16 GetWindowTitle() const;
280 
281   // Gets the Favicon of the web contents.
282   gfx::Image GetCurrentPageIcon() const;
283 
284   // Updates the title bar to display the current title and icon.
285   void UpdateTitleBar();
286 
287   // Updates UI to reflect change in loading state.
288   void LoadingStateChanged(bool is_loading);
289 
290   // Updates UI to reflect that the web cotents receives the focus.
291   void WebContentsFocused(content::WebContents* contents);
292 
293   // Moves the panel by delta instantly.
294   void MoveByInstantly(const gfx::Vector2d& delta_origin);
295 
296   // Applies |corner_style| to the panel window.
297   void SetWindowCornerStyle(panel::CornerStyle corner_style);
298 
299   // Performs the system minimize for the panel, i.e. becoming iconic.
300   void MinimizeBySystem();
301 
302   bool IsMinimizedBySystem() const;
303 
304   // Returns true if the panel is shown in the active desktop. The user could
305   // create or use multiple desktops or workspaces.
306   bool IsShownOnActiveDesktop() const;
307 
308   // Turns on/off the shadow effect around the window shape.
309   void ShowShadow(bool show);
310 
311  protected:
312   // Panel can only be created using PanelManager::CreatePanel() or subclass.
313   // |app_name| is the default title for Panels when the page content does not
314   // provide a title. For extensions, this is usually the application name
315   // generated from the extension id.
316   Panel(Profile* profile, const std::string& app_name,
317         const gfx::Size& min_size, const gfx::Size& max_size);
318 
319  private:
320   friend class PanelManager;
321   friend class PanelBrowserTest;
322 
323   enum MaxSizePolicy {
324     // Default maximum size is proportional to the work area.
325     DEFAULT_MAX_SIZE,
326     // Custom maximum size is used when the panel is resized by the user.
327     CUSTOM_MAX_SIZE
328   };
329 
330   void OnImageLoaded(const gfx::Image& image);
331 
332   // Initialize state for all supported commands.
333   void InitCommandState();
334 
335   // Configures the renderer for auto resize (if auto resize is enabled).
336   void ConfigureAutoResize(content::WebContents* web_contents);
337 
338   // Load the app's image, firing a load state change when loaded.
339   void UpdateAppIcon();
340 
341   // Prepares a title string for display (removes embedded newlines, etc).
342   static void FormatTitleForDisplay(base::string16* title);
343 
344   // The application name that is also the name of the window when the
345   // page content does not provide a title.
346   // This name should be set when the panel is created.
347   const std::string app_name_;
348 
349   Profile* profile_;
350 
351   // Current collection of panels to which this panel belongs. This determines
352   // the panel's screen layout.
353   PanelCollection* collection_;  // Owned by PanelManager.
354 
355   bool initialized_;
356 
357   // Stores the full size of the panel so we can restore it after it's
358   // been minimized or squeezed due to lack of space in the collection.
359   gfx::Size full_size_;
360 
361   // This is the minimum size that the panel can shrink to.
362   gfx::Size min_size_;
363 
364   // This is the size beyond which the panel is not going to grow to accomodate
365   // the growing content and WebKit would add the scrollbars in such case.
366   gfx::Size max_size_;
367 
368   MaxSizePolicy max_size_policy_;
369 
370   // True if this panel auto resizes based on content.
371   bool auto_resizable_;
372 
373   // True if this panel is in preview mode. When in preview mode, panel bounds
374   // should not be affected by layout refresh. This is currently used by drag
375   // controller to add a panel to the collection without causing its bounds to
376   // change.
377   bool in_preview_mode_;
378 
379   // Platform specifc implementation for panels.  It'd be one of
380   // PanelGtk/PanelView/PanelCocoa.
381   NativePanel* native_panel_;  // Weak, owns us.
382 
383   AttentionMode attention_mode_;
384 
385   ExpansionState expansion_state_;
386 
387   // The CommandUpdater manages the window commands.
388   CommandUpdater command_updater_;
389 
390   content::NotificationRegistrar registrar_;
391   const SessionID session_id_;
392   scoped_ptr<extensions::WindowController> extension_window_controller_;
393   scoped_ptr<PanelHost> panel_host_;
394 
395   // Icon showed in the task bar.
396   gfx::Image app_icon_;
397 
398   base::WeakPtrFactory<Panel> image_loader_ptr_factory_;
399 
400   DISALLOW_COPY_AND_ASSIGN(Panel);
401 };
402 
403 #endif  // CHROME_BROWSER_UI_PANELS_PANEL_H_
404