blob: 0ed05f004277a53d1e6542d4f6e25e9fb257a873 [file] [log] [blame]
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// A helper class that contains the gtk widgets that make up the titlebar. The
// titlebar consists of the tabstrip and if the custom chrome frame is turned
// on, it includes the taller titlebar and minimize, restore, maximize, and
// close buttons.
#ifndef CHROME_BROWSER_UI_GTK_BROWSER_TITLEBAR_H_
#define CHROME_BROWSER_UI_GTK_BROWSER_TITLEBAR_H_
#pragma once
#include <gtk/gtk.h>
#include "base/compiler_specific.h"
#include "base/memory/scoped_ptr.h"
#include "chrome/browser/prefs/pref_member.h"
#include "content/public/browser/notification_observer.h"
#include "content/public/browser/notification_registrar.h"
#include "ui/base/gtk/gtk_signal.h"
#include "ui/base/models/simple_menu_model.h"
#include "ui/base/x/active_window_watcher_x_observer.h"
class AvatarMenuButtonGtk;
class BrowserWindowGtk;
class CustomDrawButton;
class GtkThemeService;
class MenuGtk;
class PopupPageMenuModel;
namespace content {
class WebContents;
}
class BrowserTitlebar : public content::NotificationObserver,
public ui::ActiveWindowWatcherXObserver,
public ui::SimpleMenuModel::Delegate {
public:
// A default button order string for when we aren't asking gconf for the
// metacity configuration.
static const char kDefaultButtonString[];
BrowserTitlebar(BrowserWindowGtk* browser_window, GtkWindow* window);
virtual ~BrowserTitlebar();
// Updates the theme supplied background color and image.
virtual void UpdateButtonBackground(CustomDrawButton* button);
// Updates the title and icon when in app or popup/panel mode (no tabstrip).
virtual void UpdateTitleAndIcon();
GtkWidget* widget() {
return container_;
}
void set_window(GtkWindow* window) { window_ = window; }
// Build the titlebar, the space above the tab strip, and (maybe) the min,
// max, close buttons. |container_| is the gtk container that we put the
// widget into.
void Init();
// Builds the buttons based on the metacity |button_string|.
void BuildButtons(const std::string& button_string);
// Update the appearance of the title bar based on whether we're showing a
// custom frame or not. If |use_custom_frame| is true, we show an extra
// tall titlebar and the min/max/close buttons.
void UpdateCustomFrame(bool use_custom_frame);
// Called by the browser asking us to update the loading throbber.
// |web_contents| is the tab that is associated with the window throbber.
// |web_contents| can be null.
void UpdateThrobber(content::WebContents* web_contents);
// On Windows, right clicking in the titlebar background brings up the system
// menu. There's no such thing on linux, so we just show the menu items we
// add to the menu.
void ShowContextMenu(GdkEventButton* event);
AvatarMenuButtonGtk* avatar_button() { return avatar_button_.get(); }
protected:
// Builds the button as denoted by |button_token|. Returns true if the button
// is created successfully.
virtual bool BuildButton(const std::string& button_token, bool left_side);
// Retrieves the 3 image ids (IDR_) and a tooltip id (IDS) for the purpose of
// painting a CustomDraw button.
virtual void GetButtonResources(const std::string& button_name,
int* normal_image_id,
int* pressed_image_id,
int* hover_image_id,
int* tooltip_id) const;
// Returns the spacing around outside of titlebar buttons.
virtual int GetButtonOuterPadding() const;
// Returns the spacing between buttons of the titlebar.
virtual int GetButtonSpacing() const;
// Called when a button is clicked.
virtual void HandleButtonClick(GtkWidget* button);
// Show the menu that the user gets from left-clicking the favicon.
virtual void ShowFaviconMenu(GdkEventButton* event);
// Updates the color of the title bar. Called whenever we have a state
// change in the window.
virtual void UpdateTextColor();
// Constructs a CustomDraw button given button name and left or right side of
// the titlebar where the button is placed.
CustomDrawButton* CreateTitlebarButton(const std::string& button_name,
bool left_side);
// Lazily builds and returns |titlebar_{left,right}_buttons_vbox_| and their
// subtrees. We do this lazily because in most situations, only one of them
// is allocated (though the user can (and do) manually mess with their gconf
// settings to get absolutely horrid combinations of buttons on both sides.
GtkWidget* GetButtonHBox(bool left_side);
CustomDrawButton* minimize_button() const { return minimize_button_.get(); }
CustomDrawButton* maximize_button() const { return maximize_button_.get(); }
CustomDrawButton* restore_button() const { return restore_button_.get(); }
CustomDrawButton* close_button() const { return close_button_.get(); }
GtkWidget* app_mode_title() const { return app_mode_title_; }
GtkThemeService* theme_service() const { return theme_service_; }
private:
// A helper class to keep track of which frame of the throbber animation
// we're showing.
class Throbber {
public:
Throbber() : current_frame_(0), current_waiting_frame_(0) {}
// Get the next frame in the animation. The image is owned by the throbber
// so the caller doesn't need to unref. |is_waiting| is true if we're
// still waiting for a response.
GdkPixbuf* GetNextFrame(bool is_waiting);
// Reset back to the first frame.
void Reset();
private:
// Make sure the frames are loaded.
static void InitFrames();
int current_frame_;
int current_waiting_frame_;
};
class ContextMenuModel : public ui::SimpleMenuModel {
public:
explicit ContextMenuModel(ui::SimpleMenuModel::Delegate* delegate);
};
// Update the titlebar spacing based on the custom frame and maximized state.
void UpdateTitlebarAlignment();
// Updates the avatar image displayed, either a multi-profile avatar or the
// incognito spy guy.
void UpdateAvatar();
// The maximize button was clicked, take an action depending on which mouse
// button the user pressed.
void MaximizeButtonClicked();
// Updates the visibility of the maximize and restore buttons; only one can
// be visible at a time.
void UpdateMaximizeRestoreVisibility();
// Callback for changes to window state. This includes
// maximizing/restoring/minimizing the window.
CHROMEG_CALLBACK_1(BrowserTitlebar, gboolean, OnWindowStateChanged,
GtkWindow*, GdkEventWindowState*);
// Callback for mousewheel events.
CHROMEGTK_CALLBACK_1(BrowserTitlebar, gboolean, OnScroll,
GdkEventScroll*);
// Callback for min/max/close buttons.
CHROMEGTK_CALLBACK_0(BrowserTitlebar, void, OnButtonClicked);
// Callback for favicon/settings buttons.
CHROMEGTK_CALLBACK_1(BrowserTitlebar, gboolean,
OnFaviconMenuButtonPressed, GdkEventButton*);
// -- Context Menu -----------------------------------------------------------
// SimpleMenuModel::Delegate implementation:
virtual bool IsCommandIdEnabled(int command_id) const OVERRIDE;
virtual bool IsCommandIdChecked(int command_id) const OVERRIDE;
virtual void ExecuteCommand(int command_id) OVERRIDE;
virtual bool GetAcceleratorForCommandId(
int command_id,
ui::Accelerator* accelerator) OVERRIDE;
// Overridden from content::NotificationObserver:
virtual void Observe(int type,
const content::NotificationSource& source,
const content::NotificationDetails& details) OVERRIDE;
// Overriden from ActiveWindowWatcherXObserver.
virtual void ActiveWindowChanged(GdkWindow* active_window) OVERRIDE;
// Whether to display the avatar image.
bool ShouldDisplayAvatar();
// Returns true if the profile associated with this BrowserWindow is off the
// record.
bool IsOffTheRecord();
// Pointers to the browser window that owns us and its GtkWindow.
BrowserWindowGtk* browser_window_;
GtkWindow* window_;
// The container widget the holds the hbox which contains the whole titlebar.
GtkWidget* container_;
// The hbox that contains the whole titlebar.
GtkWidget* container_hbox_;
// VBoxes that holds the min/max/close buttons box and an optional padding
// that defines the skyline if the user turns off window manager decorations.
// There is a left and right version of this box since we try to integrate
// with the recent Ubuntu theme changes which put the buttons on the left.
GtkWidget* titlebar_left_buttons_vbox_;
GtkWidget* titlebar_right_buttons_vbox_;
// HBoxes that contains the actual min/max/close buttons.
GtkWidget* titlebar_left_buttons_hbox_;
GtkWidget* titlebar_right_buttons_hbox_;
// Avatar frame. One of these frames holds either the spy guy in incognito
// mode, or the avatar image when using multiple-profiles. It's the side with
// the least window control buttons (close, maximize, minimize).
// These pointers are never NULL.
GtkWidget* titlebar_left_avatar_frame_;
GtkWidget* titlebar_right_avatar_frame_;
// The avatar image widget. It will be NULL if there is no avatar displayed.
GtkWidget* avatar_;
// Padding between the titlebar buttons and the top of the screen. Only show
// when not maximized.
GtkWidget* top_padding_left_;
GtkWidget* top_padding_right_;
// Gtk alignment that contains the tab strip. If the user turns off window
// manager decorations, we draw this taller.
GtkWidget* titlebar_alignment_;
// The favicon and page title used when in app mode or popup mode.
GtkWidget* app_mode_favicon_;
GtkWidget* app_mode_title_;
// Whether we are using a custom frame.
bool using_custom_frame_;
// Whether we have focus (gtk_window_is_active() sometimes returns the wrong
// value, so manually track the focus-in and focus-out events.)
bool window_has_focus_;
// Whether to display the avatar image on the left or right of the titlebar.
bool display_avatar_on_left_;
// We change the size of these three buttons when the window is maximized, so
// we use these structs to keep track of their original size.
GtkRequisition close_button_req_;
GtkRequisition minimize_button_req_;
GtkRequisition restore_button_req_;
// Maximize and restore widgets in the titlebar.
scoped_ptr<CustomDrawButton> minimize_button_;
scoped_ptr<CustomDrawButton> maximize_button_;
scoped_ptr<CustomDrawButton> restore_button_;
scoped_ptr<CustomDrawButton> close_button_;
// The context menu view and model.
scoped_ptr<MenuGtk> context_menu_;
scoped_ptr<ContextMenuModel> context_menu_model_;
// The favicon menu view and model.
scoped_ptr<MenuGtk> favicon_menu_;
scoped_ptr<PopupPageMenuModel> favicon_menu_model_;
// The throbber used when the window is in app mode or popup window mode.
Throbber throbber_;
// The avatar button.
scoped_ptr<AvatarMenuButtonGtk> avatar_button_;
// Theme provider for building buttons.
GtkThemeService* theme_service_;
content::NotificationRegistrar registrar_;
};
#endif // CHROME_BROWSER_UI_GTK_BROWSER_TITLEBAR_H_