| OLD | NEW |
| 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/gtk/browser_titlebar.h" | 5 #include "chrome/browser/gtk/browser_titlebar.h" |
| 6 | 6 |
| 7 #include <gtk/gtk.h> | 7 #include <gtk/gtk.h> |
| 8 | 8 |
| 9 #include "app/l10n_util.h" | 9 #include "app/l10n_util.h" |
| 10 #include "chrome/app/chrome_dll_resource.h" | 10 #include "chrome/app/chrome_dll_resource.h" |
| (...skipping 10 matching lines...) Expand all Loading... |
| 21 #include "grit/theme_resources.h" | 21 #include "grit/theme_resources.h" |
| 22 | 22 |
| 23 namespace { | 23 namespace { |
| 24 | 24 |
| 25 // The space above the titlebars. | 25 // The space above the titlebars. |
| 26 const int kTitlebarHeight = 14; | 26 const int kTitlebarHeight = 14; |
| 27 | 27 |
| 28 // A linux specific menu item for toggling window decorations. | 28 // A linux specific menu item for toggling window decorations. |
| 29 const int kShowWindowDecorationsCommand = 200; | 29 const int kShowWindowDecorationsCommand = 200; |
| 30 | 30 |
| 31 gboolean OnMouseMoveEvent(GtkWidget* widget, GdkEventMotion* event, |
| 32 BrowserWindowGtk* browser_window) { |
| 33 // Reset to the default mouse cursor. |
| 34 browser_window->ResetCustomFrameCursor(); |
| 35 return TRUE; |
| 31 } | 36 } |
| 32 | 37 |
| 38 } // namespace |
| 39 |
| 33 BrowserTitlebar::BrowserTitlebar(BrowserWindowGtk* browser_window, | 40 BrowserTitlebar::BrowserTitlebar(BrowserWindowGtk* browser_window, |
| 34 GtkWindow* window) | 41 GtkWindow* window) |
| 35 : browser_window_(browser_window), window_(window) { | 42 : browser_window_(browser_window), window_(window) { |
| 36 Init(); | 43 Init(); |
| 37 } | 44 } |
| 38 | 45 |
| 39 void BrowserTitlebar::Init() { | 46 void BrowserTitlebar::Init() { |
| 40 titlebar_background_.reset(new NineBox( | 47 titlebar_background_.reset(new NineBox( |
| 41 browser_window_->browser()->profile()->GetThemeProvider(), | 48 browser_window_->browser()->profile()->GetThemeProvider(), |
| 42 0, IDR_THEME_FRAME, 0, 0, 0, 0, 0, 0, 0)); | 49 0, IDR_THEME_FRAME, 0, 0, 0, 0, 0, 0, 0)); |
| 43 titlebar_background_otr_.reset(new NineBox( | 50 titlebar_background_otr_.reset(new NineBox( |
| 44 browser_window_->browser()->profile()->GetThemeProvider(), | 51 browser_window_->browser()->profile()->GetThemeProvider(), |
| 45 0, IDR_THEME_FRAME_INCOGNITO, 0, 0, 0, 0, 0, 0, 0)); | 52 0, IDR_THEME_FRAME_INCOGNITO, 0, 0, 0, 0, 0, 0, 0)); |
| 46 | 53 |
| 47 // The widget hierarchy is shown below. In addition to the diagram, there is | 54 // The widget hierarchy is shown below. |
| 48 // a gtk event box surrounding the titlebar_hbox which catches mouse events | |
| 49 // in the titlebar. | |
| 50 // | 55 // |
| 51 // +- HBox (titlebar_hbox) -----------------------------------------------+ | 56 // +- HBox (container_) --------------------------------------------------+ |
| 52 // |+- Alignment (titlebar_alignment_)-++- VBox (titlebar_buttons_box_) -+| | 57 // |+- Alignment (titlebar_alignment_)-++- VBox (titlebar_buttons_box_) -+| |
| 53 // || ||+- HBox -----------------------+|| | 58 // || ||+- HBox -----------------------+|| |
| 54 // || |||+- button -++- button -+ ||| | 59 // || |||+- button -++- button -+ ||| |
| 55 // ||+- TabStripGtk ------------------+|||| minimize || restore | ... ||| | 60 // ||+- TabStripGtk ------------------+|||| minimize || restore | ... ||| |
| 56 // ||| tab tab tab tabclose +|||+----------++----------+ ||| | 61 // ||| tab tab tab tabclose +|||+----------++----------+ ||| |
| 57 // ||+--------------------------------+||+------------------------------+|| | 62 // ||+--------------------------------+||+------------------------------+|| |
| 58 // |+----------------------------------++--------------------------------+| | 63 // |+----------------------------------++--------------------------------+| |
| 59 // +----------------------------------------------------------------------+ | 64 // +----------------------------------------------------------------------+ |
| 60 container_ = gtk_event_box_new(); | 65 container_ = gtk_hbox_new(FALSE, 0); |
| 61 GtkWidget* titlebar_hbox = gtk_hbox_new(FALSE, 0); | |
| 62 gtk_container_add(GTK_CONTAINER(container_), titlebar_hbox); | |
| 63 | 66 |
| 64 g_signal_connect(G_OBJECT(container_), "button-press-event", | 67 g_signal_connect(G_OBJECT(container_), "expose-event", |
| 65 G_CALLBACK(OnMouseButtonPress), this); | |
| 66 g_signal_connect(G_OBJECT(titlebar_hbox), "expose-event", | |
| 67 G_CALLBACK(OnExpose), this); | 68 G_CALLBACK(OnExpose), this); |
| 68 g_signal_connect(window_, "window-state-event", | 69 g_signal_connect(window_, "window-state-event", |
| 69 G_CALLBACK(OnWindowStateChanged), this); | 70 G_CALLBACK(OnWindowStateChanged), this); |
| 70 | 71 |
| 71 // We use an alignment to control the titlebar height. | 72 // We use an alignment to control the titlebar height. |
| 72 titlebar_alignment_ = gtk_alignment_new(0.0, 0.0, 1.0, 1.0); | 73 titlebar_alignment_ = gtk_alignment_new(0.0, 0.0, 1.0, 1.0); |
| 73 gtk_box_pack_start(GTK_BOX(titlebar_hbox), titlebar_alignment_, TRUE, | 74 gtk_box_pack_start(GTK_BOX(container_), titlebar_alignment_, TRUE, |
| 74 TRUE, 0); | 75 TRUE, 0); |
| 75 | 76 |
| 76 // Put the tab strip in the titlebar. | 77 // Put the tab strip in the titlebar. |
| 77 gtk_container_add(GTK_CONTAINER(titlebar_alignment_), | 78 gtk_container_add(GTK_CONTAINER(titlebar_alignment_), |
| 78 browser_window_->tabstrip()->widget()); | 79 browser_window_->tabstrip()->widget()); |
| 79 | 80 |
| 80 // We put the min/max/restore/close buttons in a vbox so they are top aligned | 81 // We put the min/max/restore/close buttons in a vbox so they are top aligned |
| 81 // and don't vertically stretch. | 82 // and don't vertically stretch. |
| 82 titlebar_buttons_box_ = gtk_vbox_new(FALSE, 0); | 83 titlebar_buttons_box_ = gtk_vbox_new(FALSE, 0); |
| 83 GtkWidget* buttons_hbox = gtk_hbox_new(FALSE, 0); | 84 GtkWidget* buttons_hbox = gtk_hbox_new(FALSE, 0); |
| 84 gtk_box_pack_start(GTK_BOX(titlebar_buttons_box_), buttons_hbox, FALSE, | 85 gtk_box_pack_start(GTK_BOX(titlebar_buttons_box_), buttons_hbox, FALSE, |
| 85 FALSE, 0); | 86 FALSE, 0); |
| 86 | 87 |
| 87 close_button_.reset(BuildTitlebarButton(IDR_CLOSE, IDR_CLOSE_P, IDR_CLOSE_H, | 88 close_button_.reset(BuildTitlebarButton(IDR_CLOSE, IDR_CLOSE_P, IDR_CLOSE_H, |
| 88 buttons_hbox, IDS_XPFRAME_CLOSE_TOOLTIP)); | 89 buttons_hbox, IDS_XPFRAME_CLOSE_TOOLTIP)); |
| 89 restore_button_.reset(BuildTitlebarButton(IDR_RESTORE, IDR_RESTORE_P, | 90 restore_button_.reset(BuildTitlebarButton(IDR_RESTORE, IDR_RESTORE_P, |
| 90 IDR_RESTORE_H, buttons_hbox, | 91 IDR_RESTORE_H, buttons_hbox, |
| 91 IDS_XPFRAME_RESTORE_TOOLTIP)); | 92 IDS_XPFRAME_RESTORE_TOOLTIP)); |
| 92 maximize_button_.reset(BuildTitlebarButton(IDR_MAXIMIZE, IDR_MAXIMIZE_P, | 93 maximize_button_.reset(BuildTitlebarButton(IDR_MAXIMIZE, IDR_MAXIMIZE_P, |
| 93 IDR_MAXIMIZE_H, buttons_hbox, | 94 IDR_MAXIMIZE_H, buttons_hbox, |
| 94 IDS_XPFRAME_MAXIMIZE_TOOLTIP)); | 95 IDS_XPFRAME_MAXIMIZE_TOOLTIP)); |
| 95 minimize_button_.reset(BuildTitlebarButton(IDR_MINIMIZE, IDR_MINIMIZE_P, | 96 minimize_button_.reset(BuildTitlebarButton(IDR_MINIMIZE, IDR_MINIMIZE_P, |
| 96 IDR_MINIMIZE_H, buttons_hbox, | 97 IDR_MINIMIZE_H, buttons_hbox, |
| 97 IDS_XPFRAME_MINIMIZE_TOOLTIP)); | 98 IDS_XPFRAME_MINIMIZE_TOOLTIP)); |
| 98 | 99 |
| 99 gtk_box_pack_end(GTK_BOX(titlebar_hbox), titlebar_buttons_box_, FALSE, | 100 gtk_box_pack_end(GTK_BOX(container_), titlebar_buttons_box_, FALSE, |
| 100 FALSE, 0); | 101 FALSE, 0); |
| 101 | 102 |
| 102 gtk_widget_show_all(container_); | 103 gtk_widget_show_all(container_); |
| 103 } | 104 } |
| 104 | 105 |
| 105 CustomDrawButton* BrowserTitlebar::BuildTitlebarButton(int image, | 106 CustomDrawButton* BrowserTitlebar::BuildTitlebarButton(int image, |
| 106 int image_pressed, int image_hot, GtkWidget* box, int tooltip) { | 107 int image_pressed, int image_hot, GtkWidget* box, int tooltip) { |
| 107 CustomDrawButton* button = new CustomDrawButton(image, image_pressed, | 108 CustomDrawButton* button = new CustomDrawButton(image, image_pressed, |
| 108 image_hot, 0); | 109 image_hot, 0); |
| 110 gtk_widget_add_events(GTK_WIDGET(button->widget()), GDK_POINTER_MOTION_MASK); |
| 109 g_signal_connect(button->widget(), "clicked", G_CALLBACK(OnButtonClicked), | 111 g_signal_connect(button->widget(), "clicked", G_CALLBACK(OnButtonClicked), |
| 110 this); | 112 this); |
| 113 g_signal_connect(button->widget(), "motion-notify-event", |
| 114 G_CALLBACK(OnMouseMoveEvent), browser_window_); |
| 111 std::string localized_tooltip = l10n_util::GetStringUTF8(tooltip); | 115 std::string localized_tooltip = l10n_util::GetStringUTF8(tooltip); |
| 112 gtk_widget_set_tooltip_text(button->widget(), | 116 gtk_widget_set_tooltip_text(button->widget(), |
| 113 localized_tooltip.c_str()); | 117 localized_tooltip.c_str()); |
| 114 gtk_box_pack_end(GTK_BOX(box), button->widget(), FALSE, FALSE, 0); | 118 gtk_box_pack_end(GTK_BOX(box), button->widget(), FALSE, FALSE, 0); |
| 115 return button; | 119 return button; |
| 116 } | 120 } |
| 117 | 121 |
| 118 void BrowserTitlebar::UpdateCustomFrame(bool use_custom_frame) { | 122 void BrowserTitlebar::UpdateCustomFrame(bool use_custom_frame) { |
| 119 if (use_custom_frame) { | 123 if (use_custom_frame) { |
| 120 gtk_alignment_set_padding(GTK_ALIGNMENT(titlebar_alignment_), | 124 gtk_alignment_set_padding(GTK_ALIGNMENT(titlebar_alignment_), |
| (...skipping 13 matching lines...) Expand all Loading... |
| 134 Profile* profile = titlebar->browser_window_->browser()->profile(); | 138 Profile* profile = titlebar->browser_window_->browser()->profile(); |
| 135 NineBox* image = profile->IsOffTheRecord() | 139 NineBox* image = profile->IsOffTheRecord() |
| 136 ? titlebar->titlebar_background_otr_.get() | 140 ? titlebar->titlebar_background_otr_.get() |
| 137 : titlebar->titlebar_background_.get(); | 141 : titlebar->titlebar_background_.get(); |
| 138 image->RenderTopCenterStrip(cr, e->area.x, 0, e->area.width); | 142 image->RenderTopCenterStrip(cr, e->area.x, 0, e->area.width); |
| 139 cairo_destroy(cr); | 143 cairo_destroy(cr); |
| 140 | 144 |
| 141 return FALSE; // Allow subwidgets to paint. | 145 return FALSE; // Allow subwidgets to paint. |
| 142 } | 146 } |
| 143 | 147 |
| 144 gboolean BrowserTitlebar::OnMouseButtonPress(GtkWidget* widget, | |
| 145 GdkEventButton* event, BrowserTitlebar* titlebar) { | |
| 146 if (1 == event->button) { | |
| 147 if (GDK_BUTTON_PRESS == event->type) { | |
| 148 gtk_window_begin_move_drag(GTK_WINDOW(titlebar->window_), | |
| 149 event->button, event->x_root, event->y_root, event->time); | |
| 150 return TRUE; | |
| 151 } else if (GDK_2BUTTON_PRESS == event->type) { | |
| 152 // Maximize/restore on double click. | |
| 153 if (titlebar->browser_window_->IsMaximized()) { | |
| 154 gtk_window_unmaximize(titlebar->window_); | |
| 155 } else { | |
| 156 gtk_window_maximize(titlebar->window_); | |
| 157 } | |
| 158 return TRUE; | |
| 159 } | |
| 160 } else if (3 == event->button) { | |
| 161 titlebar->ShowContextMenu(); | |
| 162 return TRUE; | |
| 163 } | |
| 164 | |
| 165 return FALSE; // Continue to propagate the event. | |
| 166 } | |
| 167 | |
| 168 gboolean BrowserTitlebar::OnWindowStateChanged(GtkWindow* window, | 148 gboolean BrowserTitlebar::OnWindowStateChanged(GtkWindow* window, |
| 169 GdkEventWindowState* event, BrowserTitlebar* titlebar) { | 149 GdkEventWindowState* event, BrowserTitlebar* titlebar) { |
| 170 // Update the maximize/restore button. | 150 // Update the maximize/restore button. |
| 171 if (titlebar->browser_window_->IsMaximized()) { | 151 if (titlebar->browser_window_->IsMaximized()) { |
| 172 gtk_widget_hide(titlebar->maximize_button_->widget()); | 152 gtk_widget_hide(titlebar->maximize_button_->widget()); |
| 173 gtk_widget_show(titlebar->restore_button_->widget()); | 153 gtk_widget_show(titlebar->restore_button_->widget()); |
| 174 } else { | 154 } else { |
| 175 gtk_widget_hide(titlebar->restore_button_->widget()); | 155 gtk_widget_hide(titlebar->restore_button_->widget()); |
| 176 gtk_widget_show(titlebar->maximize_button_->widget()); | 156 gtk_widget_show(titlebar->maximize_button_->widget()); |
| 177 } | 157 } |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 255 PrefService* prefs = browser_window_->browser()->profile()->GetPrefs(); | 235 PrefService* prefs = browser_window_->browser()->profile()->GetPrefs(); |
| 256 prefs->SetBoolean(prefs::kUseCustomChromeFrame, | 236 prefs->SetBoolean(prefs::kUseCustomChromeFrame, |
| 257 !prefs->GetBoolean(prefs::kUseCustomChromeFrame)); | 237 !prefs->GetBoolean(prefs::kUseCustomChromeFrame)); |
| 258 break; | 238 break; |
| 259 } | 239 } |
| 260 | 240 |
| 261 default: | 241 default: |
| 262 NOTREACHED(); | 242 NOTREACHED(); |
| 263 } | 243 } |
| 264 } | 244 } |
| OLD | NEW |