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 // A helper class that contains the gtk widgets that make up the titlebar. The 6 // titlebar consists of the tabstrip and if the custom chrome frame is turned 7 // on, it includes the taller titlebar and minimize, restore, maximize, and 8 // close buttons. 9 10 #ifndef CHROME_BROWSER_UI_GTK_BROWSER_TITLEBAR_H_ 11 #define CHROME_BROWSER_UI_GTK_BROWSER_TITLEBAR_H_ 12 13 #include <gtk/gtk.h> 14 15 #include "base/compiler_specific.h" 16 #include "base/memory/scoped_ptr.h" 17 #include "base/prefs/pref_member.h" 18 #include "chrome/browser/ui/gtk/titlebar_throb_animation.h" 19 #include "content/public/browser/notification_observer.h" 20 #include "content/public/browser/notification_registrar.h" 21 #include "ui/base/gtk/gtk_signal.h" 22 #include "ui/base/models/simple_menu_model.h" 23 #include "ui/base/x/active_window_watcher_x_observer.h" 24 25 class AvatarMenuButtonGtk; 26 class BrowserWindowGtk; 27 class CustomDrawButton; 28 class GtkThemeService; 29 class MenuGtk; 30 class PopupPageMenuModel; 31 32 namespace content { 33 class WebContents; 34 } 35 36 class BrowserTitlebar : public content::NotificationObserver, 37 public ui::ActiveWindowWatcherXObserver, 38 public ui::SimpleMenuModel::Delegate { 39 public: 40 // A default button order string for when we aren't asking gconf for the 41 // metacity configuration. 42 static const char kDefaultButtonString[]; 43 44 BrowserTitlebar(BrowserWindowGtk* browser_window, GtkWindow* window); 45 virtual ~BrowserTitlebar(); 46 47 // Updates the title and icon when in app or popup mode (no tabstrip). 48 void UpdateTitleAndIcon(); 49 widget()50 GtkWidget* widget() { 51 return container_; 52 } 53 set_window(GtkWindow * window)54 void set_window(GtkWindow* window) { window_ = window; } 55 56 // Build the titlebar, the space above the tab strip, and (maybe) the min, 57 // max, close buttons. |container_| is the gtk container that we put the 58 // widget into. 59 void Init(); 60 61 // Builds the buttons based on the metacity |button_string|. 62 void BuildButtons(const std::string& button_string); 63 64 // Update the appearance of the title bar based on whether we're showing a 65 // custom frame or not. If |use_custom_frame| is true, we show an extra 66 // tall titlebar and the min/max/close buttons. 67 void UpdateCustomFrame(bool use_custom_frame); 68 69 // Called by the browser asking us to update the loading throbber. 70 // |web_contents| is the tab that is associated with the window throbber. 71 // |web_contents| can be null. 72 void UpdateThrobber(content::WebContents* web_contents); 73 74 // On Windows, right clicking in the titlebar background brings up the system 75 // menu. There's no such thing on linux, so we just show the menu items we 76 // add to the menu. 77 void ShowContextMenu(GdkEventButton* event); 78 avatar_button()79 AvatarMenuButtonGtk* avatar_button() { return avatar_button_.get(); } 80 81 private: 82 class ContextMenuModel : public ui::SimpleMenuModel { 83 public: 84 explicit ContextMenuModel(ui::SimpleMenuModel::Delegate* delegate); 85 }; 86 87 // Builds the button as denoted by |button_token|. Returns true if the button 88 // is created successfully. 89 bool BuildButton(const std::string& button_token, bool left_side); 90 91 // Retrieves the 3 image ids (IDR_) and a tooltip id (IDS) for the purpose of 92 // painting a CustomDraw button. 93 void GetButtonResources(const std::string& button_name, 94 int* normal_image_id, 95 int* pressed_image_id, 96 int* hover_image_id, 97 int* tooltip_id) const; 98 99 // Constructs a CustomDraw button given button name and left or right side of 100 // the titlebar where the button is placed. 101 CustomDrawButton* CreateTitlebarButton(const std::string& button_name, 102 bool left_side); 103 104 // Lazily builds and returns |titlebar_{left,right}_buttons_vbox_| and their 105 // subtrees. We do this lazily because in most situations, only one of them 106 // is allocated (though the user can (and do) manually mess with their gconf 107 // settings to get absolutely horrid combinations of buttons on both sides. 108 GtkWidget* GetButtonHBox(bool left_side); 109 110 // Updates the theme supplied background color and image. 111 void UpdateButtonBackground(CustomDrawButton* button); 112 113 // Updates the color of the title bar. Called whenever we have a state 114 // change in the window. 115 void UpdateTextColor(); 116 117 // Updates the color of the avatar label text and background. 118 void UpdateAvatarLabel(); 119 120 // Update the titlebar spacing based on the custom frame and maximized state. 121 void UpdateTitlebarAlignment(); 122 123 // Updates the avatar image displayed, either a multi-profile avatar or the 124 // incognito spy guy. 125 void UpdateAvatar(); 126 127 // The maximize button was clicked, take an action depending on which mouse 128 // button the user pressed. 129 void MaximizeButtonClicked(); 130 131 // Updates the visibility of the maximize and restore buttons; only one can 132 // be visible at a time. 133 void UpdateMaximizeRestoreVisibility(); 134 135 // Callback for changes to window state. This includes 136 // maximizing/restoring/minimizing the window. 137 CHROMEG_CALLBACK_1(BrowserTitlebar, gboolean, OnWindowStateChanged, 138 GtkWindow*, GdkEventWindowState*); 139 140 // Callback for mousewheel events. 141 CHROMEGTK_CALLBACK_1(BrowserTitlebar, gboolean, OnScroll, 142 GdkEventScroll*); 143 144 // Callback for min/max/close buttons. 145 CHROMEGTK_CALLBACK_0(BrowserTitlebar, void, OnButtonClicked); 146 147 // Callback for favicon/settings buttons. 148 CHROMEGTK_CALLBACK_1(BrowserTitlebar, gboolean, 149 OnFaviconMenuButtonPressed, GdkEventButton*); 150 151 // Callback for avatar menu label. 152 CHROMEGTK_CALLBACK_1(BrowserTitlebar, gboolean, 153 OnAvatarLabelButtonPressed, GdkEventButton*); 154 155 // -- Context Menu ----------------------------------------------------------- 156 157 // SimpleMenuModel::Delegate implementation: 158 virtual bool IsCommandIdEnabled(int command_id) const OVERRIDE; 159 virtual bool IsCommandIdChecked(int command_id) const OVERRIDE; 160 virtual void ExecuteCommand(int command_id, int event_flags) OVERRIDE; 161 virtual bool GetAcceleratorForCommandId( 162 int command_id, 163 ui::Accelerator* accelerator) OVERRIDE; 164 165 // Overridden from content::NotificationObserver: 166 virtual void Observe(int type, 167 const content::NotificationSource& source, 168 const content::NotificationDetails& details) OVERRIDE; 169 170 // Overriden from ActiveWindowWatcherXObserver. 171 virtual void ActiveWindowChanged(GdkWindow* active_window) OVERRIDE; 172 173 // Whether to display the avatar image. 174 bool ShouldDisplayAvatar(); 175 176 // Returns true if the profile associated with this BrowserWindow is off the 177 // record. 178 bool IsOffTheRecord(); 179 180 // Pointers to the browser window that owns us and its GtkWindow. 181 BrowserWindowGtk* browser_window_; 182 GtkWindow* window_; 183 184 // The container widget the holds the hbox which contains the whole titlebar. 185 GtkWidget* container_; 186 187 // The hbox that contains the whole titlebar. 188 GtkWidget* container_hbox_; 189 190 // VBoxes that holds the min/max/close buttons box and an optional padding 191 // that defines the skyline if the user turns off window manager decorations. 192 // There is a left and right version of this box since we try to integrate 193 // with the recent Ubuntu theme changes which put the buttons on the left. 194 GtkWidget* titlebar_left_buttons_vbox_; 195 GtkWidget* titlebar_right_buttons_vbox_; 196 197 // HBoxes that contains the actual min/max/close buttons. 198 GtkWidget* titlebar_left_buttons_hbox_; 199 GtkWidget* titlebar_right_buttons_hbox_; 200 201 // Avatar frame. One of these frames holds either the spy guy in incognito 202 // mode, or the avatar image when using multiple-profiles. It's the side with 203 // the least window control buttons (close, maximize, minimize). 204 // These pointers are never NULL. 205 GtkWidget* titlebar_left_avatar_frame_; 206 GtkWidget* titlebar_right_avatar_frame_; 207 208 // Avatar label. Used if the active profile is managed. The label is either 209 // displayed on the right side of the avatar image if the image is displayed 210 // on the left, or on the left side of the avatar image if the image is 211 // displayed on the right. 212 GtkWidget* titlebar_left_label_frame_; 213 GtkWidget* titlebar_right_label_frame_; 214 215 // The avatar image widget. It will be NULL if there is no avatar displayed. 216 GtkWidget* avatar_; 217 218 // The avatar label of a managed user. It will be NULL if no avatar label is 219 // displayed. 220 GtkWidget* avatar_label_; 221 GtkWidget* avatar_label_bg_; 222 223 // Padding between the titlebar buttons and the top of the screen. Only show 224 // when not maximized. 225 GtkWidget* top_padding_left_; 226 GtkWidget* top_padding_right_; 227 228 // Gtk alignment that contains the tab strip. If the user turns off window 229 // manager decorations, we draw this taller. 230 GtkWidget* titlebar_alignment_; 231 232 // The favicon and page title used when in app mode or popup mode. 233 GtkWidget* app_mode_favicon_; 234 GtkWidget* app_mode_title_; 235 236 // Whether we are using a custom frame. 237 bool using_custom_frame_; 238 239 // Whether we have focus (gtk_window_is_active() sometimes returns the wrong 240 // value, so manually track the focus-in and focus-out events.) 241 bool window_has_focus_; 242 243 // Whether to display the avatar image on the left or right of the titlebar. 244 bool display_avatar_on_left_; 245 246 // We change the size of these three buttons when the window is maximized, so 247 // we use these structs to keep track of their original size. 248 GtkRequisition close_button_req_; 249 GtkRequisition minimize_button_req_; 250 GtkRequisition restore_button_req_; 251 252 // Maximize and restore widgets in the titlebar. 253 scoped_ptr<CustomDrawButton> minimize_button_; 254 scoped_ptr<CustomDrawButton> maximize_button_; 255 scoped_ptr<CustomDrawButton> restore_button_; 256 scoped_ptr<CustomDrawButton> close_button_; 257 258 // The context menu view and model. 259 scoped_ptr<MenuGtk> context_menu_; 260 scoped_ptr<ContextMenuModel> context_menu_model_; 261 262 // The favicon menu view and model. 263 scoped_ptr<MenuGtk> favicon_menu_; 264 scoped_ptr<PopupPageMenuModel> favicon_menu_model_; 265 266 // The throbber used when the window is in app mode or popup window mode. 267 TitlebarThrobAnimation throbber_; 268 269 // The avatar button. 270 scoped_ptr<AvatarMenuButtonGtk> avatar_button_; 271 272 // Theme provider for building buttons. 273 GtkThemeService* theme_service_; 274 275 content::NotificationRegistrar registrar_; 276 }; 277 278 #endif // CHROME_BROWSER_UI_GTK_BROWSER_TITLEBAR_H_ 279