• 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_GTK_PANELS_PANEL_GTK_H_
6 #define CHROME_BROWSER_UI_GTK_PANELS_PANEL_GTK_H_
7 
8 #include <gtk/gtk.h>
9 #include <map>
10 
11 #include "base/basictypes.h"
12 #include "base/memory/scoped_ptr.h"
13 #include "base/timer/timer.h"
14 #include "chrome/browser/ui/panels/native_panel.h"
15 #include "chrome/browser/ui/panels/panel_constants.h"
16 #include "ui/base/gtk/gtk_signal.h"
17 #include "ui/base/x/active_window_watcher_x_observer.h"
18 #include "ui/gfx/rect.h"
19 
20 class Panel;
21 class PanelTitlebarGtk;
22 class PanelDragGtk;
23 class GtkNativePanelTesting;
24 
25 namespace gfx {
26 class Image;
27 }
28 
29 // An implementation of the native panel in GTK.
30 class PanelGtk : public NativePanel,
31                  public ui::ActiveWindowWatcherXObserver {
32  public:
33   enum PaintState {
34     PAINT_AS_ACTIVE,
35     PAINT_AS_INACTIVE,
36     PAINT_AS_MINIMIZED,
37     PAINT_FOR_ATTENTION
38   };
39 
40   PanelGtk(Panel* panel, const gfx::Rect& bounds, bool always_on_top);
41   virtual ~PanelGtk();
42 
43   void Init();
44 
45   // Overridden from NativePanel.
46   virtual void ShowPanel() OVERRIDE;
47   virtual void ShowPanelInactive() OVERRIDE;
48   virtual gfx::Rect GetPanelBounds() const OVERRIDE;
49   virtual void SetPanelBounds(const gfx::Rect& bounds) OVERRIDE;
50   virtual void SetPanelBoundsInstantly(const gfx::Rect& bounds) OVERRIDE;
51   virtual void ClosePanel() OVERRIDE;
52   virtual void ActivatePanel() OVERRIDE;
53   virtual void DeactivatePanel() OVERRIDE;
54   virtual bool IsPanelActive() const OVERRIDE;
55   virtual void PreventActivationByOS(bool prevent_activation) OVERRIDE;
56   virtual gfx::NativeWindow GetNativePanelWindow() OVERRIDE;
57   virtual void UpdatePanelTitleBar() OVERRIDE;
58   virtual void UpdatePanelLoadingAnimations(bool should_animate) OVERRIDE;
59   virtual void PanelWebContentsFocused(content::WebContents* contents) OVERRIDE;
60   virtual void PanelCut() OVERRIDE;
61   virtual void PanelCopy() OVERRIDE;
62   virtual void PanelPaste() OVERRIDE;
63   virtual void DrawAttention(bool draw_attention) OVERRIDE;
64   virtual bool IsDrawingAttention() const OVERRIDE;
65   virtual void HandlePanelKeyboardEvent(
66       const content::NativeWebKeyboardEvent& event) OVERRIDE;
67   virtual void FullScreenModeChanged(bool is_full_screen) OVERRIDE;
68   virtual void PanelExpansionStateChanging(
69       Panel::ExpansionState old_state,
70       Panel::ExpansionState new_state) OVERRIDE;
71   virtual void AttachWebContents(content::WebContents* contents) OVERRIDE;
72   virtual void DetachWebContents(content::WebContents* contents) OVERRIDE;
73   // These sizes are in screen coordinates.
74   virtual gfx::Size WindowSizeFromContentSize(
75       const gfx::Size& content_size) const OVERRIDE;
76   virtual gfx::Size ContentSizeFromWindowSize(
77       const gfx::Size& window_size) const OVERRIDE;
78   virtual int TitleOnlyHeight() const OVERRIDE;
79   virtual bool IsPanelAlwaysOnTop() const OVERRIDE;
80   virtual void SetPanelAlwaysOnTop(bool on_top) OVERRIDE;
81   virtual void UpdatePanelMinimizeRestoreButtonVisibility() OVERRIDE;
82   virtual void SetWindowCornerStyle(panel::CornerStyle corner_style) OVERRIDE;
83   virtual void MinimizePanelBySystem() OVERRIDE;
84   virtual bool IsPanelMinimizedBySystem() const OVERRIDE;
85   virtual bool IsPanelShownOnActiveDesktop() const OVERRIDE;
86   virtual void ShowShadow(bool show) OVERRIDE;
87 
88   virtual NativePanelTesting* CreateNativePanelTesting() OVERRIDE;
89 
90   // Overridden from ActiveWindowWatcherXObserver.
91   virtual void ActiveWindowChanged(GdkWindow* active_window) OVERRIDE;
92 
panel()93   Panel* panel() const { return panel_.get(); }
paint_state()94   PaintState paint_state() const { return paint_state_; }
titlebar()95   PanelTitlebarGtk* titlebar() const { return titlebar_.get(); }
96 
97  private:
98   friend class GtkNativePanelTesting;
99 
100   // Applies our custom window shape with rounded or non-rounded corners.
101   void UpdateWindowShape();
102 
103   // Checks to see if the mouse pointer at |x|, |y| is over the border of the
104   // custom frame (a spot that should trigger a window resize). Returns true if
105   // it should and sets |edge|.
106   bool GetWindowEdge(int x, int y, GdkWindowEdge* edge) const;
107 
108   // Connect/disconnect accelerators for keyboard shortcut support.
109   void ConnectAccelerators();
110   void DisconnectAccelerators();
111 
112   // Returns the image to paint the frame.
113   gfx::Image GetFrameBackground() const;
114 
115   // Animation when panel is first shown.
116   void RevealPanel();
117 
118   // Creates helper for handling drags if not already created.
119   void EnsureDragHelperCreated();
120 
121   void SetBoundsInternal(const gfx::Rect& bounds);
122 
123   void LoadingAnimationCallback();
124 
125   // Returns the size of the window frame around the client content area.
126   gfx::Size GetNonClientFrameSize() const;
127 
128   // Invalidate window to force repaint.
129   void InvalidateWindow();
130 
131   // Callback for accelerator activation. |user_data| stores the command id
132   // of the matched accelerator.
133   static gboolean OnGtkAccelerator(GtkAccelGroup* accel_group,
134                                    GObject* acceleratable,
135                                    guint keyval,
136                                    GdkModifierType modifier,
137                                    void* user_data);
138 
139   CHROMEGTK_CALLBACK_1(PanelGtk, gboolean, OnMainWindowDeleteEvent,
140                        GdkEvent*);
141   CHROMEGTK_CALLBACK_0(PanelGtk, void, OnMainWindowDestroy);
142   CHROMEGTK_CALLBACK_1(PanelGtk, gboolean, OnConfigure, GdkEventConfigure*);
143   CHROMEGTK_CALLBACK_1(PanelGtk, gboolean, OnWindowState, GdkEventWindowState*);
144   // Callback for when the custom frame alignment needs to be redrawn.
145   CHROMEGTK_CALLBACK_1(PanelGtk, gboolean, OnCustomFrameExpose,
146                        GdkEventExpose*);
147   // Key press event callback.
148   CHROMEGTK_CALLBACK_1(PanelGtk, gboolean, OnKeyPress, GdkEventKey*);
149   // Mouse move and button press callbacks. If mouse hits titlebar,
150   // the titlebar gets the event, else the window gets the button press.
151   CHROMEGTK_CALLBACK_1(PanelGtk, gboolean, OnMouseMoveEvent,
152                        GdkEventMotion*);
153   CHROMEGTK_CALLBACK_1(PanelGtk, gboolean, OnButtonPressEvent,
154                        GdkEventButton*);
155   CHROMEGTK_CALLBACK_1(PanelGtk, gboolean,
156                        OnTitlebarButtonPressEvent, GdkEventButton*);
157   CHROMEGTK_CALLBACK_1(PanelGtk, gboolean,
158                        OnTitlebarButtonReleaseEvent, GdkEventButton*);
159 
160   scoped_ptr<Panel> panel_;
161   gfx::Rect bounds_;
162 
163   // True if the panel should always stay on top of other windows.
164   bool always_on_top_;
165 
166   // True after panel has been shown.
167   bool is_shown_;
168 
169   scoped_ptr<PanelDragGtk> drag_helper_;
170 
171   // The configure size of the current window, used to figure out whether to
172   // ignore later configure events. See OnConfigure() for more information.
173   gfx::Size configure_size_;
174 
175   // Indicates different painting state, active, drawing attention or else.
176   PaintState paint_state_;
177 
178   // Indicates that the panel is currently drawing attention.
179   bool is_drawing_attention_;
180 
181   // The timer used to update frames for the Loading Animation.
182   base::RepeatingTimer<PanelGtk> loading_animation_timer_;
183 
184   // The current window cursor.  We set it to a resize cursor when over the
185   // custom frame border.  We set it to NULL if we want the default cursor.
186   GdkCursor* frame_cursor_;
187 
188   // True if the window manager thinks the window is active.  Not all window
189   // managers keep track of this state (_NET_ACTIVE_WINDOW), in which case
190   // this will always be true.
191   bool is_active_;
192 
193   // True if the window manager thinks the window is minimized (iconified).
194   // Not all window managers support this, in which case this will always be
195   // false.
196   bool is_minimized_;
197 
198   // Top level window.
199   GtkWindow* window_;
200   // GtkAlignment that holds the interior components of the chromium window.
201   // This is used to draw the custom frame border and content shadow.
202   GtkWidget* window_container_;
203   // VBox that holds everything (titlebar, web contents).
204   GtkWidget* window_vbox_;
205   // EventBox that holds web contents.
206   GtkWidget* render_area_event_box_;
207   // We insert and remove WebContents GtkWidgets into this expanded.
208   GtkWidget* contents_expanded_;
209 
210   // The accelerator group used to handle accelerators, owned by this object.
211   GtkAccelGroup* accel_group_;
212 
213   // The container for the titlebar.
214   scoped_ptr<PanelTitlebarGtk> titlebar_;
215 
216   // Indicates how the window corner should be rendered, rounded or not.
217   panel::CornerStyle corner_style_;
218 
219   DISALLOW_COPY_AND_ASSIGN(PanelGtk);
220 };
221 
222 #endif  // CHROME_BROWSER_UI_GTK_PANELS_PANEL_GTK_H_
223