diff options
-rw-r--r-- | chrome/browser/gtk/browser_titlebar.cc | 264 | ||||
-rw-r--r-- | chrome/browser/gtk/browser_titlebar.h | 106 | ||||
-rw-r--r-- | chrome/browser/gtk/browser_window_gtk.cc | 134 | ||||
-rw-r--r-- | chrome/browser/gtk/browser_window_gtk.h | 44 | ||||
-rw-r--r-- | chrome/browser/gtk/tabs/tab_strip_gtk.cc | 97 | ||||
-rw-r--r-- | chrome/browser/gtk/tabs/tab_strip_gtk.h | 20 | ||||
-rw-r--r-- | chrome/browser/tabs/tab_strip_model.h | 1 | ||||
-rw-r--r-- | chrome/chrome.gyp | 2 |
8 files changed, 389 insertions, 279 deletions
diff --git a/chrome/browser/gtk/browser_titlebar.cc b/chrome/browser/gtk/browser_titlebar.cc new file mode 100644 index 0000000..4540c5d --- /dev/null +++ b/chrome/browser/gtk/browser_titlebar.cc @@ -0,0 +1,264 @@ +// Copyright (c) 2009 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. + +#include "chrome/browser/gtk/browser_titlebar.h" + +#include <gtk/gtk.h> + +#include "app/l10n_util.h" +#include "chrome/app/chrome_dll_resource.h" +#include "chrome/browser/browser.h" +#include "chrome/browser/gtk/browser_window_gtk.h" +#include "chrome/browser/gtk/custom_button.h" +#include "chrome/browser/gtk/nine_box.h" +#include "chrome/browser/gtk/tabs/tab_strip_gtk.h" +#include "chrome/browser/profile.h" +#include "chrome/common/pref_names.h" +#include "chrome/common/pref_service.h" +#include "grit/app_resources.h" +#include "grit/generated_resources.h" +#include "grit/theme_resources.h" + +namespace { + +// The space above the titlebars. +const int kTitlebarHeight = 14; + +// A linux specific menu item for toggling window decorations. +const int kShowWindowDecorationsCommand = 200; + +} + +BrowserTitlebar::BrowserTitlebar(BrowserWindowGtk* browser_window, + GtkWindow* window) + : browser_window_(browser_window), window_(window) { + Init(); +} + +void BrowserTitlebar::Init() { + titlebar_background_.reset(new NineBox( + browser_window_->browser()->profile()->GetThemeProvider(), + 0, IDR_THEME_FRAME, 0, 0, 0, 0, 0, 0, 0)); + titlebar_background_otr_.reset(new NineBox( + browser_window_->browser()->profile()->GetThemeProvider(), + 0, IDR_THEME_FRAME_INCOGNITO, 0, 0, 0, 0, 0, 0, 0)); + + // The widget hierarchy is shown below. In addition to the diagram, there is + // a gtk event box surrounding the titlebar_hbox which catches mouse events + // in the titlebar. + // + // +- HBox (titlebar_hbox) -----------------------------------------------+ + // |+- Alignment (titlebar_alignment_)-++- VBox (titlebar_buttons_box_) -+| + // || ||+- HBox -----------------------+|| + // || |||+- button -++- button -+ ||| + // ||+- TabStripGtk ------------------+|||| minimize || restore | ... ||| + // ||| tab tab tab tabclose +|||+----------++----------+ ||| + // ||+--------------------------------+||+------------------------------+|| + // |+----------------------------------++--------------------------------+| + // +----------------------------------------------------------------------+ + container_ = gtk_event_box_new(); + GtkWidget* titlebar_hbox = gtk_hbox_new(FALSE, 0); + gtk_container_add(GTK_CONTAINER(container_), titlebar_hbox); + + g_signal_connect(G_OBJECT(container_), "button-press-event", + G_CALLBACK(OnMouseButtonPress), this); + g_signal_connect(G_OBJECT(titlebar_hbox), "expose-event", + G_CALLBACK(OnExpose), this); + g_signal_connect(window_, "window-state-event", + G_CALLBACK(OnWindowStateChanged), this); + + // We use an alignment to control the titlebar height. + titlebar_alignment_ = gtk_alignment_new(0.0, 0.0, 1.0, 1.0); + gtk_box_pack_start(GTK_BOX(titlebar_hbox), titlebar_alignment_, TRUE, + TRUE, 0); + + // Put the tab strip in the titlebar. + gtk_container_add(GTK_CONTAINER(titlebar_alignment_), + browser_window_->tabstrip()->widget()); + + // We put the min/max/restore/close buttons in a vbox so they are top aligned + // and don't vertically stretch. + titlebar_buttons_box_ = gtk_vbox_new(FALSE, 0); + GtkWidget* buttons_hbox = gtk_hbox_new(FALSE, 0); + gtk_box_pack_start(GTK_BOX(titlebar_buttons_box_), buttons_hbox, FALSE, + FALSE, 0); + + close_button_.reset(BuildTitlebarButton(IDR_CLOSE, IDR_CLOSE_P, IDR_CLOSE_H, + buttons_hbox, IDS_XPFRAME_CLOSE_TOOLTIP)); + restore_button_.reset(BuildTitlebarButton(IDR_RESTORE, IDR_RESTORE_P, + IDR_RESTORE_H, buttons_hbox, + IDS_XPFRAME_RESTORE_TOOLTIP)); + maximize_button_.reset(BuildTitlebarButton(IDR_MAXIMIZE, IDR_MAXIMIZE_P, + IDR_MAXIMIZE_H, buttons_hbox, + IDS_XPFRAME_MAXIMIZE_TOOLTIP)); + minimize_button_.reset(BuildTitlebarButton(IDR_MINIMIZE, IDR_MINIMIZE_P, + IDR_MINIMIZE_H, buttons_hbox, + IDS_XPFRAME_MINIMIZE_TOOLTIP)); + + gtk_box_pack_end(GTK_BOX(titlebar_hbox), titlebar_buttons_box_, FALSE, + FALSE, 0); + + gtk_widget_show_all(container_); +} + +CustomDrawButton* BrowserTitlebar::BuildTitlebarButton(int image, + int image_pressed, int image_hot, GtkWidget* box, int tooltip) { + CustomDrawButton* button = new CustomDrawButton(image, image_pressed, + image_hot, 0); + g_signal_connect(button->widget(), "clicked", G_CALLBACK(OnButtonClicked), + this); + std::string localized_tooltip = l10n_util::GetStringUTF8(tooltip); + gtk_widget_set_tooltip_text(button->widget(), + localized_tooltip.c_str()); + gtk_box_pack_end(GTK_BOX(box), button->widget(), FALSE, FALSE, 0); + return button; +} + +void BrowserTitlebar::UpdateCustomFrame(bool use_custom_frame) { + if (use_custom_frame) { + gtk_alignment_set_padding(GTK_ALIGNMENT(titlebar_alignment_), + kTitlebarHeight, 0, 0, 0); + gtk_widget_show_all(titlebar_buttons_box_); + } else { + gtk_alignment_set_padding(GTK_ALIGNMENT(titlebar_alignment_), 0, 0, 0, 0); + gtk_widget_hide(titlebar_buttons_box_); + } +} + +gboolean BrowserTitlebar::OnExpose(GtkWidget* widget, GdkEventExpose* e, + BrowserTitlebar* titlebar) { + cairo_t* cr = gdk_cairo_create(GDK_DRAWABLE(widget->window)); + cairo_rectangle(cr, e->area.x, e->area.y, e->area.width, e->area.height); + cairo_clip(cr); + Profile* profile = titlebar->browser_window_->browser()->profile(); + NineBox* image = profile->IsOffTheRecord() + ? titlebar->titlebar_background_otr_.get() + : titlebar->titlebar_background_.get(); + image->RenderTopCenterStrip(cr, e->area.x, 0, e->area.width); + cairo_destroy(cr); + + return FALSE; // Allow subwidgets to paint. +} + +gboolean BrowserTitlebar::OnMouseButtonPress(GtkWidget* widget, + GdkEventButton* event, BrowserTitlebar* titlebar) { + if (1 == event->button) { + if (GDK_BUTTON_PRESS == event->type) { + gtk_window_begin_move_drag(GTK_WINDOW(titlebar->window_), + event->button, event->x_root, event->y_root, event->time); + return TRUE; + } else if (GDK_2BUTTON_PRESS == event->type) { + // Maximize/restore on double click. + if (titlebar->browser_window_->IsMaximized()) { + gtk_window_unmaximize(titlebar->window_); + } else { + gtk_window_maximize(titlebar->window_); + } + return TRUE; + } + } else if (3 == event->button) { + titlebar->ShowContextMenu(); + return TRUE; + } + + return FALSE; // Continue to propagate the event. +} + +gboolean BrowserTitlebar::OnWindowStateChanged(GtkWindow* window, + GdkEventWindowState* event, BrowserTitlebar* titlebar) { + // Update the maximize/restore button. + if (titlebar->browser_window_->IsMaximized()) { + gtk_widget_hide(titlebar->maximize_button_->widget()); + gtk_widget_show(titlebar->restore_button_->widget()); + } else { + gtk_widget_hide(titlebar->restore_button_->widget()); + gtk_widget_show(titlebar->maximize_button_->widget()); + } + return FALSE; +} + +void BrowserTitlebar::OnButtonClicked(GtkWidget* button, + BrowserTitlebar* titlebar) { + if (titlebar->close_button_->widget() == button) { + titlebar->browser_window_->Close(); + } else if (titlebar->restore_button_->widget() == button) { + gtk_window_unmaximize(titlebar->window_); + } else if (titlebar->maximize_button_->widget() == button) { + gtk_window_maximize(titlebar->window_); + } else if (titlebar->minimize_button_->widget() == button) { + gtk_window_iconify(titlebar->window_); + } +} + +void BrowserTitlebar::ShowContextMenu() { + if (!context_menu_.get()) { + context_menu_.reset(new MenuGtk(this, false)); + context_menu_->AppendMenuItemWithLabel( + IDC_NEW_TAB, + l10n_util::GetStringUTF8(IDS_TAB_CXMENU_NEWTAB)); + context_menu_->AppendMenuItemWithLabel( + IDC_RESTORE_TAB, + l10n_util::GetStringUTF8(IDS_RESTORE_TAB)); + + context_menu_->AppendSeparator(); + + context_menu_->AppendMenuItemWithLabel( + IDC_TASK_MANAGER, + l10n_util::GetStringUTF8(IDS_TASK_MANAGER)); + + context_menu_->AppendSeparator(); + + context_menu_->AppendCheckMenuItemWithLabel( + kShowWindowDecorationsCommand, + l10n_util::GetStringUTF8(IDS_SHOW_WINDOW_DECORATIONS)); + } + + context_menu_->PopupAsContext(gtk_get_current_event_time()); +} + +bool BrowserTitlebar::IsCommandEnabled(int command_id) const { + switch (command_id) { + case IDC_NEW_TAB: + case kShowWindowDecorationsCommand: + return true; + + case IDC_RESTORE_TAB: + return browser_window_->browser()->CanRestoreTab(); + + case IDC_TASK_MANAGER: + // TODO(tc): Task manager needs to be implemented. + return false; + + default: + NOTREACHED(); + } + return false; +} + +bool BrowserTitlebar::IsItemChecked(int command_id) const { + DCHECK(command_id == kShowWindowDecorationsCommand); + PrefService* prefs = browser_window_->browser()->profile()->GetPrefs(); + return !prefs->GetBoolean(prefs::kUseCustomChromeFrame); +} + +void BrowserTitlebar::ExecuteCommand(int command_id) { + switch (command_id) { + case IDC_NEW_TAB: + case IDC_RESTORE_TAB: + case IDC_TASK_MANAGER: + browser_window_->browser()->ExecuteCommand(command_id); + break; + + case kShowWindowDecorationsCommand: + { + PrefService* prefs = browser_window_->browser()->profile()->GetPrefs(); + prefs->SetBoolean(prefs::kUseCustomChromeFrame, + !prefs->GetBoolean(prefs::kUseCustomChromeFrame)); + break; + } + + default: + NOTREACHED(); + } +} diff --git a/chrome/browser/gtk/browser_titlebar.h b/chrome/browser/gtk/browser_titlebar.h new file mode 100644 index 0000000..c937f85 --- /dev/null +++ b/chrome/browser/gtk/browser_titlebar.h @@ -0,0 +1,106 @@ +// Copyright (c) 2009 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_GTK_BROWSER_TITLEBAR_H_ +#define CHROME_BROWSER_GTK_BROWSER_TITLEBAR_H_ + +#include <gtk/gtk.h> + +#include "base/scoped_ptr.h" +#include "chrome/browser/gtk/menu_gtk.h" +#include "chrome/browser/gtk/nine_box.h" + +class BrowserWindowGtk; +class CustomDrawButton; +class TabStripGtk; + +class BrowserTitlebar : public MenuGtk::Delegate { + public: + BrowserTitlebar(BrowserWindowGtk* browser_window, GtkWindow* window); + virtual ~BrowserTitlebar() { } + + GtkWidget* widget() { + return container_; + } + + // 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); + + private: + // Build the titlebar, the space above the tab + // strip, and (maybe) the min, max, close buttons. |container| is the gtk + // continer that we put the widget into. + void Init(); + + // Constructs a CustomDraw button given 3 image ids (IDR_), the box to place + // the button into, and a tooltip id (IDS_). + CustomDrawButton* BuildTitlebarButton(int image, int image_pressed, + int image_hot, GtkWidget* box, + int tooltip); + + // Callback for when the titlebar (include the background of the tab strip) + // needs to be redrawn. + static gboolean OnExpose(GtkWidget* widget, GdkEventExpose* e, + BrowserTitlebar* window); + + // Callback for when the titlebar (include the background of the tab strip) + // needs to be redrawn. + static gboolean OnMouseButtonPress(GtkWidget* widget, GdkEventButton* e, + BrowserTitlebar* window); + + // Callback for changes to window state. This includes + // maximizing/restoring/minimizing the window. + static gboolean OnWindowStateChanged(GtkWindow* window, + GdkEventWindowState* event, + BrowserTitlebar* titlebar); + + // Callback for min/max/close buttons. + static void OnButtonClicked(GtkWidget* button, BrowserTitlebar* window); + + // -- Context Menu ----------------------------------------------------------- + + // 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(); + // MenuGtk::Delegate implementation: + virtual bool IsCommandEnabled(int command_id) const; + virtual bool IsItemChecked(int command_id) const; + virtual void ExecuteCommand(int command_id); + + // Pointers to the browser window that owns us and it's GtkWindow. + BrowserWindowGtk* browser_window_; + GtkWindow* window_; + + // The container widget the holds the whole titlebar. + GtkWidget* container_; + // Box that holds the min/max/close buttons if the user turns off window + // manager decorations. + GtkWidget* titlebar_buttons_box_; + // Gtk alignment that contains the tab strip. If the user turns off window + // manager decorations, we draw this taller. + GtkWidget* titlebar_alignment_; + + // 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 background of the title bar and tab strip. + scoped_ptr<NineBox> titlebar_background_; + scoped_ptr<NineBox> titlebar_background_otr_; + + // The context menu. + scoped_ptr<MenuGtk> context_menu_; +}; + +#endif // CHROME_BROWSER_GTK_BROWSER_TITLEBAR_H_ diff --git a/chrome/browser/gtk/browser_window_gtk.cc b/chrome/browser/gtk/browser_window_gtk.cc index e43327f..d62c7a1 100644 --- a/chrome/browser/gtk/browser_window_gtk.cc +++ b/chrome/browser/gtk/browser_window_gtk.cc @@ -7,7 +7,6 @@ #include <gdk/gdkkeysyms.h> #include "app/resource_bundle.h" -#include "app/l10n_util.h" #include "base/base_paths_linux.h" #include "base/gfx/gtk_util.h" #include "base/logging.h" @@ -23,15 +22,14 @@ #include "chrome/browser/download/download_manager.h" #include "chrome/browser/gtk/about_chrome_dialog.h" #include "chrome/browser/gtk/bookmark_bar_gtk.h" +#include "chrome/browser/gtk/browser_titlebar.h" #include "chrome/browser/gtk/browser_toolbar_gtk.h" #include "chrome/browser/gtk/clear_browsing_data_dialog_gtk.h" -#include "chrome/browser/gtk/custom_button.h" #include "chrome/browser/gtk/download_shelf_gtk.h" #include "chrome/browser/gtk/go_button_gtk.h" #include "chrome/browser/gtk/import_dialog_gtk.h" #include "chrome/browser/gtk/infobar_container_gtk.h" #include "chrome/browser/gtk/find_bar_gtk.h" -#include "chrome/browser/gtk/nine_box.h" #include "chrome/browser/gtk/status_bubble_gtk.h" #include "chrome/browser/gtk/tab_contents_container_gtk.h" #include "chrome/browser/gtk/tabs/tab_strip_gtk.h" @@ -43,8 +41,6 @@ #include "chrome/common/notification_service.h" #include "chrome/common/pref_names.h" #include "chrome/common/pref_service.h" -#include "grit/app_resources.h" -#include "grit/generated_resources.h" #include "grit/theme_resources.h" namespace { @@ -59,9 +55,6 @@ const char* kBrowserWindowKey = "__BROWSER_WINDOW_GTK__"; // The width of the custom frame. const int kCustomFrameWidth = 3; -// The space above the titlebars. -const int kTitlebarHeight = 14; - gboolean MainWindowConfigured(GtkWindow* window, GdkEventConfigure* event, BrowserWindowGtk* browser_win) { gfx::Rect bounds = gfx::Rect(event->x, event->y, event->width, event->height); @@ -323,13 +316,6 @@ BrowserWindowGtk::BrowserWindowGtk(Browser* browser) ConnectAccelerators(); bounds_ = GetInitialWindowBounds(window_); - titlebar_background_.reset(new NineBox( - browser_->profile()->GetThemeProvider(), - 0, IDR_THEME_FRAME, 0, 0, 0, 0, 0, 0, 0)); - titlebar_background_otr_.reset(new NineBox( - browser_->profile()->GetThemeProvider(), - 0, IDR_THEME_FRAME_INCOGNITO, 0, 0, 0, 0, 0, 0, 0)); - // This vbox encompasses all of the widgets within the browser, including the // tabstrip and the content vbox. The vbox is put in a floating container // (see gtk_floating_container.h) so we can position the @@ -342,8 +328,13 @@ BrowserWindowGtk::BrowserWindowGtk(Browser* browser) window_container_ = gtk_alignment_new(0.0, 0.0, 1.0, 1.0); gtk_container_add(GTK_CONTAINER(window_container_), window_vbox); + tabstrip_.reset(new TabStripGtk(browser_->tabstrip_model())); + tabstrip_->Init(browser_->profile()); + // Build the titlebar (tabstrip + header space + min/max/close buttons). - BuildTitlebar(window_vbox); + titlebar_.reset(new BrowserTitlebar(this, window_)); + gtk_box_pack_start(GTK_BOX(window_vbox), titlebar_->widget(), FALSE, FALSE, + 0); // The content_vbox_ surrounds the "content": toolbar+bookmarks bar+page. content_vbox_ = gtk_vbox_new(FALSE, 0); @@ -420,34 +411,6 @@ gboolean BrowserWindowGtk::OnContentAreaExpose(GtkWidget* widget, return FALSE; // Allow subwidgets to paint. } -gboolean BrowserWindowGtk::OnTitlebarExpose(GtkWidget* widget, - GdkEventExpose* e, - BrowserWindowGtk* window) { - cairo_t* cr = gdk_cairo_create(GDK_DRAWABLE(widget->window)); - cairo_rectangle(cr, e->area.x, e->area.y, e->area.width, e->area.height); - cairo_clip(cr); - NineBox* image = window->browser_->profile()->IsOffTheRecord() - ? window->titlebar_background_otr_.get() - : window->titlebar_background_.get(); - image->RenderTopCenterStrip(cr, e->area.x, e->area.y, e->area.width); - cairo_destroy(cr); - - return FALSE; // Allow subwidgets to paint. -} - -void BrowserWindowGtk::OnButtonClicked(GtkWidget* button, - BrowserWindowGtk* window) { - if (window->close_button_->widget() == button) { - window->Close(); - } else if (window->restore_button_->widget() == button) { - gtk_window_unmaximize(window->window_); - } else if (window->maximize_button_->widget() == button) { - gtk_window_maximize(window->window_); - } else if (window->minimize_button_->widget() == button) { - gtk_window_iconify(window->window_); - } -} - void BrowserWindowGtk::Show() { gtk_widget_show(GTK_WIDGET(window_)); } @@ -794,15 +757,6 @@ void BrowserWindowGtk::OnBoundsChanged(const gfx::Rect& bounds) { void BrowserWindowGtk::OnStateChanged(GdkWindowState state) { state_ = state; - // Update the maximize/restore button. - if (IsMaximized()) { - gtk_widget_hide(maximize_button_->widget()); - gtk_widget_show(restore_button_->widget()); - } else { - gtk_widget_hide(restore_button_->widget()); - gtk_widget_show(maximize_button_->widget()); - } - SaveWindowPosition(); } @@ -908,88 +862,16 @@ void BrowserWindowGtk::ConnectAccelerators() { } } -void BrowserWindowGtk::BuildTitlebar(GtkWidget* container) { - // +- HBox (titlebar_hbox) -----------------------------------------------+ - // |+- Alignment (titlebar_alignment_)-++- VBox (titlebar_buttons_box_) -+| - // || ||+- HBox -----------------------+|| - // || |||+- button -++- button -+ ||| - // ||+- TabStripGtk ------------------+|||| minimize || restore | ... ||| - // ||| tab tab tab tabclose +|||+----------++----------+ ||| - // ||+--------------------------------+||+------------------------------+|| - // |+----------------------------------++--------------------------------+| - // +----------------------------------------------------------------------+ - // - GtkWidget* titlebar_hbox = gtk_hbox_new(FALSE, 0); - g_signal_connect(G_OBJECT(titlebar_hbox), "expose-event", - G_CALLBACK(&OnTitlebarExpose), this); - - // We use an alignment to control the titlebar height. - titlebar_alignment_ = gtk_alignment_new(0.0, 0.0, 1.0, 1.0); - gtk_box_pack_start(GTK_BOX(titlebar_hbox), titlebar_alignment_, TRUE, - TRUE, 0); - - tabstrip_.reset(new TabStripGtk(browser_->tabstrip_model())); - tabstrip_->Init(browser_->profile()); - gtk_container_add(GTK_CONTAINER(titlebar_alignment_), tabstrip_->widget()); - - // We put the min/max/restore/close buttons in a vbox so they are top aligned - // and don't vertically stretch. - titlebar_buttons_box_ = gtk_vbox_new(FALSE, 0); - GtkWidget* buttons_hbox = gtk_hbox_new(FALSE, 0); - gtk_box_pack_start(GTK_BOX(titlebar_buttons_box_), buttons_hbox, FALSE, - FALSE, 0); - - close_button_.reset(BuildTitlebarButton(IDR_CLOSE, IDR_CLOSE_P, IDR_CLOSE_H, - buttons_hbox, IDS_XPFRAME_CLOSE_TOOLTIP)); - restore_button_.reset(BuildTitlebarButton(IDR_RESTORE, IDR_RESTORE_P, - IDR_RESTORE_H, buttons_hbox, - IDS_XPFRAME_RESTORE_TOOLTIP)); - maximize_button_.reset(BuildTitlebarButton(IDR_MAXIMIZE, IDR_MAXIMIZE_P, - IDR_MAXIMIZE_H, buttons_hbox, - IDS_XPFRAME_MAXIMIZE_TOOLTIP)); - minimize_button_.reset(BuildTitlebarButton(IDR_MINIMIZE, IDR_MINIMIZE_P, - IDR_MINIMIZE_H, buttons_hbox, - IDS_XPFRAME_MINIMIZE_TOOLTIP)); - - gtk_box_pack_end(GTK_BOX(titlebar_hbox), titlebar_buttons_box_, FALSE, - FALSE, 0); - - gtk_widget_show_all(titlebar_hbox); - if (IsMaximized()) { - gtk_widget_hide(maximize_button_->widget()); - } else { - gtk_widget_hide(restore_button_->widget()); - } - - gtk_box_pack_start(GTK_BOX(container), titlebar_hbox, FALSE, FALSE, 0); -} - -CustomDrawButton* BrowserWindowGtk::BuildTitlebarButton(int image, - int image_pressed, int image_hot, GtkWidget* box, int tooltip) { - CustomDrawButton* button = new CustomDrawButton(image, image_pressed, - image_hot, 0); - g_signal_connect(button->widget(), "clicked", G_CALLBACK(OnButtonClicked), - this); - std::string localized_tooltip = l10n_util::GetStringUTF8(tooltip); - gtk_widget_set_tooltip_text(button->widget(), - localized_tooltip.c_str()); - gtk_box_pack_end(GTK_BOX(box), button->widget(), FALSE, FALSE, 0); - return button; -} void BrowserWindowGtk::UpdateCustomFrame() { gtk_window_set_decorated(window_, !use_custom_frame_.GetValue()); + titlebar_->UpdateCustomFrame(use_custom_frame_.GetValue()); if (use_custom_frame_.GetValue()) { gtk_alignment_set_padding(GTK_ALIGNMENT(window_container_), 0, kCustomFrameWidth, kCustomFrameWidth, kCustomFrameWidth); - gtk_alignment_set_padding(GTK_ALIGNMENT(titlebar_alignment_), - kTitlebarHeight, 0, 0, 0); - gtk_widget_show_all(titlebar_buttons_box_); } else { gtk_alignment_set_padding(GTK_ALIGNMENT(window_container_), 0, 0, 0, 0); - gtk_alignment_set_padding(GTK_ALIGNMENT(titlebar_alignment_), 0, 0, 0, 0); - gtk_widget_hide(titlebar_buttons_box_); } } diff --git a/chrome/browser/gtk/browser_window_gtk.h b/chrome/browser/gtk/browser_window_gtk.h index ee43808..850431d 100644 --- a/chrome/browser/gtk/browser_window_gtk.h +++ b/chrome/browser/gtk/browser_window_gtk.h @@ -19,6 +19,8 @@ #include "chrome/common/x11_util.h" class BookmarkBarGtk; +class Browser; +class BrowserTitlebar; class BrowserToolbarGtk; class CustomDrawButton; class DownloadShelfGtk; @@ -133,18 +135,16 @@ class BrowserWindowGtk : public BrowserWindow, // ID of the top-level X window of this object. static GtkWindow* GetBrowserWindowForXID(XID xid); + Browser* browser() { + return browser_.get(); + } + protected: virtual void DestroyBrowser(); // Top level window. GtkWindow* window_; // GtkAlignment that holds the interior components of the chromium window. GtkWidget* window_container_; - // Box that holds the min/max/close buttons if the user turns off window - // manager decorations. - GtkWidget* titlebar_buttons_box_; - // Gtk alignment that contains the tab strip. If the user turns off window - // manager decorations, we draw this taller. - GtkWidget* titlebar_alignment_; // VBox that holds everything below the tabs. GtkWidget* content_vbox_; // VBox that holds everything below the toolbar. @@ -167,17 +167,6 @@ class BrowserWindowGtk : public BrowserWindow, // ctrl-l, etc.). void ConnectAccelerators(); - // Build the titlebar which includes the tab strip, the space above the tab - // strip, and (maybe) the min, max, close buttons. |container| is the gtk - // continer that we put the widget into. - void BuildTitlebar(GtkWidget* container); - - // Constructs a CustomDraw button given 3 image ids (IDR_), the box to place - // the button into, and a tooltip id (IDS_). - CustomDrawButton* BuildTitlebarButton(int image, int image_pressed, - int image_hot, GtkWidget* box, - int tooltip); - // Change whether we're showing the custom blue frame. // Must be called once at startup. // Triggers relayout of the content. @@ -191,14 +180,6 @@ class BrowserWindowGtk : public BrowserWindow, static gboolean OnContentAreaExpose(GtkWidget* widget, GdkEventExpose* e, BrowserWindowGtk* window); - // Callback for when the titlebar (include the background of the tab strip) - // needs to be redrawn. - static gboolean OnTitlebarExpose(GtkWidget* widget, GdkEventExpose* e, - BrowserWindowGtk* window); - - // Callback for min/max/close buttons. - static void OnButtonClicked(GtkWidget* button, BrowserWindowGtk* window); - static gboolean OnGtkAccelerator(GtkAccelGroup* accel_group, GObject* acceleratable, guint keyval, @@ -234,6 +215,9 @@ class BrowserWindowGtk : public BrowserWindow, // OnStateChanged(), we can't rely on |state_| & GDK_WINDOW_STATE_FULLSCREEN. bool full_screen_; + // The container for the titlebar + tab strip. + scoped_ptr<BrowserTitlebar> titlebar_; + // The object that manages all of the widgets in the toolbar. scoped_ptr<BrowserToolbarGtk> toolbar_; @@ -254,16 +238,6 @@ class BrowserWindowGtk : public BrowserWindow, // The container for info bars. Always non-NULL. scoped_ptr<InfoBarContainerGtk> infobar_container_; - // 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 background of the title bar and tab strip. - scoped_ptr<NineBox> titlebar_background_; - scoped_ptr<NineBox> titlebar_background_otr_; - // The timer used to update frames for the Loading Animation. base::RepeatingTimer<BrowserWindowGtk> loading_animation_timer_; diff --git a/chrome/browser/gtk/tabs/tab_strip_gtk.cc b/chrome/browser/gtk/tabs/tab_strip_gtk.cc index d460c59..2b95e74 100644 --- a/chrome/browser/gtk/tabs/tab_strip_gtk.cc +++ b/chrome/browser/gtk/tabs/tab_strip_gtk.cc @@ -18,10 +18,7 @@ #include "chrome/browser/profile.h" #include "chrome/browser/tab_contents/tab_contents.h" #include "chrome/common/gtk_util.h" -#include "chrome/common/pref_names.h" -#include "chrome/common/pref_service.h" #include "grit/app_resources.h" -#include "grit/generated_resources.h" #include "grit/theme_resources.h" namespace { @@ -488,8 +485,6 @@ void TabStripGtk::Init(Profile* profile) { G_CALLBACK(OnExpose), this); g_signal_connect(G_OBJECT(tabstrip_.get()), "size-allocate", G_CALLBACK(OnSizeAllocate), this); - g_signal_connect(G_OBJECT(tabstrip_.get()), "button-press-event", - G_CALLBACK(OnButtonPress), this); g_signal_connect(G_OBJECT(tabstrip_.get()), "drag-motion", G_CALLBACK(OnDragMotion), this); g_signal_connect(G_OBJECT(tabstrip_.get()), "drag-drop", @@ -1482,19 +1477,6 @@ void TabStripGtk::OnSizeAllocate(GtkWidget* widget, GtkAllocation* allocation, } // static -gboolean TabStripGtk::OnButtonPress(GtkWidget* widget, GdkEventButton* event, - TabStripGtk* tabstrip) { - if (1 == event->button) { - gtk_window_begin_move_drag(GTK_WINDOW(gtk_widget_get_toplevel(widget)), - event->button, event->x_root, event->y_root, event->time); - } else if (3 == event->button) { - tabstrip->ShowContextMenu(); - } - - return TRUE; -} - -// static gboolean TabStripGtk::OnDragMotion(GtkWidget* widget, GdkDragContext* context, gint x, gint y, guint time, TabStripGtk* tabstrip) { @@ -1570,82 +1552,3 @@ CustomDrawButton* TabStripGtk::MakeNewTabButton() { return button; } - -void TabStripGtk::ShowContextMenu() { - if (!context_menu_.get()) { - context_menu_.reset(new MenuGtk(this, false)); - context_menu_->AppendMenuItemWithLabel( - TabStripModel::CommandNewTab, - l10n_util::GetStringUTF8(IDS_TAB_CXMENU_NEWTAB)); - context_menu_->AppendMenuItemWithLabel( - TabStripModel::CommandRestoreTab, - l10n_util::GetStringUTF8(IDS_RESTORE_TAB)); - - context_menu_->AppendSeparator(); - - context_menu_->AppendMenuItemWithLabel( - TabStripModel::CommandTaskManager, - l10n_util::GetStringUTF8(IDS_TASK_MANAGER)); - - context_menu_->AppendSeparator(); - - context_menu_->AppendCheckMenuItemWithLabel( - kShowWindowDecorationsCommand, - l10n_util::GetStringUTF8(IDS_SHOW_WINDOW_DECORATIONS)); - } - - context_menu_->PopupAsContext(gtk_get_current_event_time()); -} - -bool TabStripGtk::IsCommandEnabled(int command_id) const { - switch (command_id) { - case TabStripModel::CommandNewTab: - case kShowWindowDecorationsCommand: - return true; - - case TabStripModel::CommandRestoreTab: - return model_->delegate()->CanRestoreTab(); - - case TabStripModel::CommandTaskManager: - // TODO(tc): This needs to be implemented in the TabStripModelDelegate. - return false; - - default: - NOTREACHED(); - } - return false; -} - -bool TabStripGtk::IsItemChecked(int command_id) const { - DCHECK(command_id == kShowWindowDecorationsCommand); - PrefService* prefs = model_->profile()->GetPrefs(); - return !prefs->GetBoolean(prefs::kUseCustomChromeFrame); -} - -void TabStripGtk::ExecuteCommand(int command_id) { - switch (command_id) { - case TabStripModel::CommandNewTab: - model_->delegate()->AddBlankTab(true); - break; - - case TabStripModel::CommandRestoreTab: - model_->delegate()->RestoreTab(); - break; - - case TabStripModel::CommandTaskManager: - // TODO(tc): This needs to be implemented in the TabStripModelDelegate. - NOTIMPLEMENTED(); - break; - - case kShowWindowDecorationsCommand: - { - PrefService* prefs = model_->profile()->GetPrefs(); - prefs->SetBoolean(prefs::kUseCustomChromeFrame, - !prefs->GetBoolean(prefs::kUseCustomChromeFrame)); - break; - } - - default: - NOTREACHED(); - } -} diff --git a/chrome/browser/gtk/tabs/tab_strip_gtk.h b/chrome/browser/gtk/tabs/tab_strip_gtk.h index 93b953f..4e85403 100644 --- a/chrome/browser/gtk/tabs/tab_strip_gtk.h +++ b/chrome/browser/gtk/tabs/tab_strip_gtk.h @@ -12,7 +12,6 @@ #include "base/gfx/rect.h" #include "base/task.h" #include "base/message_loop.h" -#include "chrome/browser/gtk/menu_gtk.h" #include "chrome/browser/gtk/tabs/tab_gtk.h" #include "chrome/browser/tabs/tab_strip_model.h" #include "chrome/common/owned_widget_gtk.h" @@ -22,7 +21,6 @@ class DraggedTabControllerGtk; class TabStripGtk : public TabStripModelObserver, public TabGtk::TabDelegate, - public MenuGtk::Delegate, public MessageLoopForUI::Observer { public: class TabAnimation; @@ -189,10 +187,6 @@ class TabStripGtk : public TabStripModelObserver, static void OnSizeAllocate(GtkWidget* widget, GtkAllocation* allocation, TabStripGtk* tabstrip); - // Event handler for context menu popups. - static gboolean OnButtonPress(GtkWidget* widget, GdkEventButton* event, - TabStripGtk* tabstrip); - // drag-motion handler that is signaled when the user performs a drag in the // tabstrip bounds. static gboolean OnDragMotion(GtkWidget* widget, GdkDragContext* context, @@ -282,17 +276,6 @@ class TabStripGtk : public TabStripModelObserver, // during animations, so we can't use current_unselected_width_. void LayoutNewTabButton(double last_tab_right, double unselected_width); - // -- Context Menu ----------------------------------------------------------- - - // On Windows, right clicking in the tab strip 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(); - // MenuGtk::Delegate implementation: - virtual bool IsCommandEnabled(int command_id) const; - virtual bool IsItemChecked(int command_id) const; - virtual void ExecuteCommand(int command_id); - // -- Link Drag & Drop ------------------------------------------------------ // Returns the bounds to render the drop at, in screen coordinates. Sets @@ -385,9 +368,6 @@ class TabStripGtk : public TabStripModelObserver, // the drag session. scoped_ptr<DraggedTabControllerGtk> drag_controller_; - // The context menu. - scoped_ptr<MenuGtk> context_menu_; - // A factory that is used to construct a delayed callback to the // ResizeLayoutTabsNow method. ScopedRunnableMethodFactory<TabStripGtk> resize_layout_factory_; diff --git a/chrome/browser/tabs/tab_strip_model.h b/chrome/browser/tabs/tab_strip_model.h index f56f984..2431883 100644 --- a/chrome/browser/tabs/tab_strip_model.h +++ b/chrome/browser/tabs/tab_strip_model.h @@ -420,7 +420,6 @@ class TabStripModel : public NotificationObserver { CommandCloseTabsToRight, CommandCloseTabsOpenedBy, CommandRestoreTab, - CommandTaskManager, CommandLast }; diff --git a/chrome/chrome.gyp b/chrome/chrome.gyp index 487c007..b474a99d 100644 --- a/chrome/chrome.gyp +++ b/chrome/chrome.gyp @@ -926,6 +926,8 @@ 'browser/gtk/bookmark_utils_gtk.h', 'browser/gtk/bookmark_tree_model.cc', 'browser/gtk/bookmark_tree_model.h', + 'browser/gtk/browser_titlebar.cc', + 'browser/gtk/browser_titlebar.h', 'browser/gtk/browser_toolbar_gtk.cc', 'browser/gtk/browser_toolbar_gtk.h', 'browser/gtk/browser_window_factory_gtk.cc', |