Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(103)

Side by Side Diff: chrome/browser/gtk/browser_titlebar.cc

Issue 244029: GTK: Implement popup favicon menu. (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 11 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « chrome/browser/gtk/browser_titlebar.h ('k') | chrome/browser/gtk/browser_toolbar_gtk.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 <gdk/gdkkeysyms.h> 7 #include <gdk/gdkkeysyms.h>
8 #include <gtk/gtk.h> 8 #include <gtk/gtk.h>
9 9
10 #include <string> 10 #include <string>
11 #include <vector> 11 #include <vector>
12 12
13 #include "app/gfx/skbitmap_operations.h" 13 #include "app/gfx/skbitmap_operations.h"
14 #include "app/l10n_util.h" 14 #include "app/l10n_util.h"
15 #include "app/resource_bundle.h" 15 #include "app/resource_bundle.h"
16 #include "base/gfx/gtk_util.h" 16 #include "base/gfx/gtk_util.h"
17 #include "chrome/app/chrome_dll_resource.h" 17 #include "chrome/app/chrome_dll_resource.h"
18 #include "chrome/browser/browser.h" 18 #include "chrome/browser/browser.h"
19 #include "chrome/browser/encoding_menu_controller.h"
19 #include "chrome/browser/gtk/browser_window_gtk.h" 20 #include "chrome/browser/gtk/browser_window_gtk.h"
20 #include "chrome/browser/gtk/custom_button.h" 21 #include "chrome/browser/gtk/custom_button.h"
21 #include "chrome/browser/gtk/gtk_theme_provider.h" 22 #include "chrome/browser/gtk/gtk_theme_provider.h"
22 #include "chrome/browser/gtk/menu_gtk.h" 23 #include "chrome/browser/gtk/menu_gtk.h"
23 #include "chrome/browser/gtk/nine_box.h" 24 #include "chrome/browser/gtk/nine_box.h"
24 #include "chrome/browser/gtk/standard_menus.h" 25 #include "chrome/browser/gtk/standard_menus.h"
25 #include "chrome/browser/gtk/tabs/tab_strip_gtk.h" 26 #include "chrome/browser/gtk/tabs/tab_strip_gtk.h"
26 #include "chrome/browser/profile.h" 27 #include "chrome/browser/profile.h"
27 #include "chrome/browser/tab_contents/tab_contents.h" 28 #include "chrome/browser/tab_contents/tab_contents.h"
28 #include "chrome/common/gtk_util.h" 29 #include "chrome/common/gtk_util.h"
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
114 double one_difference = fabs(baseHSL.l - oneHSL.l); 115 double one_difference = fabs(baseHSL.l - oneHSL.l);
115 double two_difference = fabs(baseHSL.l - twoHSL.l); 116 double two_difference = fabs(baseHSL.l - twoHSL.l);
116 117
117 // Be biased towards the first color presented. 118 // Be biased towards the first color presented.
118 if (two_difference > one_difference + 0.1) 119 if (two_difference > one_difference + 0.1)
119 return *two; 120 return *two;
120 else 121 else
121 return *one; 122 return *one;
122 } 123 }
123 124
125 MenuCreateMaterial g_favicon_menu[] = {
126 { MENU_NORMAL, IDC_BACK, IDS_CONTENT_CONTEXT_BACK, 0, NULL,
127 GDK_Left, GDK_MOD1_MASK, true },
128 { MENU_NORMAL, IDC_FORWARD, IDS_CONTENT_CONTEXT_FORWARD, 0, NULL,
129 GDK_Right, GDK_MOD1_MASK, true },
130 { MENU_NORMAL, IDC_RELOAD, IDS_APP_MENU_RELOAD, 0, NULL,
131 GDK_R, GDK_CONTROL_MASK, true },
132 { MENU_SEPARATOR },
133 { MENU_NORMAL, IDC_RESTORE_TAB, IDS_APP_MENU_RELOAD, 0, NULL,
134 GDK_T, GDK_CONTROL_MASK | GDK_SHIFT_MASK, true },
135 { MENU_NORMAL, IDC_DUPLICATE_TAB, IDS_APP_MENU_DUPLICATE_APP_WINDOW },
136 { MENU_NORMAL, IDC_COPY_URL, IDS_APP_MENU_COPY_URL },
137 { MENU_NORMAL, IDC_SHOW_AS_TAB, IDS_SHOW_AS_TAB },
138 { MENU_NORMAL, IDC_NEW_TAB, IDS_APP_MENU_NEW_WEB_PAGE, 0, NULL,
139 GDK_T, GDK_CONTROL_MASK },
140 };
141
142 const MenuCreateMaterial* GetFaviconMenu(Profile* profile,
143 MenuGtk::Delegate* delegate) {
144 static bool favicon_menu_built = false;
145 static MenuCreateMaterial* favicon_menu;
146 if (!favicon_menu_built) {
147 const MenuCreateMaterial* standard_page =
148 GetStandardPageMenu(profile, delegate);
149 int standard_page_menu_length = 1;
150 // Don't include the Create App Shortcut menu item.
151 int start_offset = 0;
152 for (int i = 0; standard_page[i].type != MENU_END; ++i) {
153 if (standard_page[i].id == IDC_CREATE_SHORTCUTS) {
154 // Pass the separator as well.
155 start_offset = i + 2;
156 ++i;
157 continue;
158 } else if (start_offset == 0) {
159 // The Create App Shortcut menu item is the first menu item, and if that
160 // ever changes we'll probably have to re-evaluate this code.
161 NOTREACHED();
162 continue;
163 }
164
165 standard_page_menu_length++;
166 }
167 favicon_menu = new MenuCreateMaterial[arraysize(g_favicon_menu) +
168 standard_page_menu_length];
169 memcpy(favicon_menu, g_favicon_menu,
170 arraysize(g_favicon_menu) * sizeof(MenuCreateMaterial));
171 memcpy(favicon_menu + arraysize(g_favicon_menu),
172 standard_page + start_offset,
173 (standard_page_menu_length) * sizeof(MenuCreateMaterial));
174 }
175 return favicon_menu;
176 }
177
124 } // namespace 178 } // namespace
125 179
126 BrowserTitlebar::BrowserTitlebar(BrowserWindowGtk* browser_window, 180 BrowserTitlebar::BrowserTitlebar(BrowserWindowGtk* browser_window,
127 GtkWindow* window) 181 GtkWindow* window)
128 : browser_window_(browser_window), window_(window), 182 : browser_window_(browser_window), window_(window),
129 app_mode_favicon_(NULL), 183 app_mode_favicon_(NULL),
130 app_mode_title_(NULL), 184 app_mode_title_(NULL),
131 using_custom_frame_(false), 185 using_custom_frame_(false),
132 window_has_focus_(false), 186 window_has_focus_(false),
133 theme_provider_(NULL) { 187 theme_provider_(NULL) {
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
202 TRUE, 0); 256 TRUE, 0);
203 GtkWidget* app_mode_hbox = gtk_hbox_new(FALSE, kIconTitleSpacing); 257 GtkWidget* app_mode_hbox = gtk_hbox_new(FALSE, kIconTitleSpacing);
204 gtk_container_add(GTK_CONTAINER(titlebar_alignment_), app_mode_hbox); 258 gtk_container_add(GTK_CONTAINER(titlebar_alignment_), app_mode_hbox);
205 259
206 // Put the tab strip in the hbox even though we don't show it. Sometimes 260 // Put the tab strip in the hbox even though we don't show it. Sometimes
207 // we need the position of the tab strip so make sure it's in our widget 261 // we need the position of the tab strip so make sure it's in our widget
208 // hierarchy. 262 // hierarchy.
209 gtk_box_pack_start(GTK_BOX(app_mode_hbox), 263 gtk_box_pack_start(GTK_BOX(app_mode_hbox),
210 browser_window_->tabstrip()->widget(), FALSE, FALSE, 0); 264 browser_window_->tabstrip()->widget(), FALSE, FALSE, 0);
211 265
266 GtkWidget* favicon_event_box = gtk_event_box_new();
267 gtk_event_box_set_visible_window(GTK_EVENT_BOX(favicon_event_box), FALSE);
268 g_signal_connect(favicon_event_box, "button-press-event",
269 G_CALLBACK(OnButtonPressed), this);
270 gtk_box_pack_start(GTK_BOX(app_mode_hbox), favicon_event_box, FALSE,
271 FALSE, 0);
212 // We use the app logo as a placeholder image so the title doesn't jump 272 // We use the app logo as a placeholder image so the title doesn't jump
213 // around. 273 // around.
214 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); 274 ResourceBundle& rb = ResourceBundle::GetSharedInstance();
215 // TODO(tc): Add a left click menu to this icon.
216 app_mode_favicon_ = gtk_image_new_from_pixbuf( 275 app_mode_favicon_ = gtk_image_new_from_pixbuf(
217 rb.GetRTLEnabledPixbufNamed(IDR_PRODUCT_LOGO_16)); 276 rb.GetRTLEnabledPixbufNamed(IDR_PRODUCT_LOGO_16));
218 gtk_box_pack_start(GTK_BOX(app_mode_hbox), app_mode_favicon_, FALSE, 277 g_object_set_data(G_OBJECT(app_mode_favicon_), "left-align-popup",
219 FALSE, 0); 278 reinterpret_cast<void*>(true));
279 gtk_container_add(GTK_CONTAINER(favicon_event_box), app_mode_favicon_);
220 280
221 app_mode_title_ = gtk_label_new(NULL); 281 app_mode_title_ = gtk_label_new(NULL);
222 gtk_label_set_ellipsize(GTK_LABEL(app_mode_title_), PANGO_ELLIPSIZE_END); 282 gtk_label_set_ellipsize(GTK_LABEL(app_mode_title_), PANGO_ELLIPSIZE_END);
223 gtk_misc_set_alignment(GTK_MISC(app_mode_title_), 0.0, 0.5); 283 gtk_misc_set_alignment(GTK_MISC(app_mode_title_), 0.0, 0.5);
224 gtk_box_pack_start(GTK_BOX(app_mode_hbox), app_mode_title_, TRUE, TRUE, 284 gtk_box_pack_start(GTK_BOX(app_mode_hbox), app_mode_title_, TRUE, TRUE,
225 0); 285 0);
226 286
227 // Register with the theme provider to set the |app_mode_title_| label 287 // Register with the theme provider to set the |app_mode_title_| label
228 // color. 288 // color.
229 theme_provider_ = GtkThemeProvider::GetFrom( 289 theme_provider_ = GtkThemeProvider::GetFrom(
(...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after
427 &frame_color, &gfx::kGdkWhite, &gfx::kGdkBlack); 487 &frame_color, &gfx::kGdkWhite, &gfx::kGdkBlack);
428 gtk_util::SetLabelColor(app_mode_title_, &text_color); 488 gtk_util::SetLabelColor(app_mode_title_, &text_color);
429 } else { 489 } else {
430 // TODO(tc): Seems like this color should be themable, but it's hardcoded 490 // TODO(tc): Seems like this color should be themable, but it's hardcoded
431 // to white on Windows. http://crbug.com/18093 491 // to white on Windows. http://crbug.com/18093
432 gtk_util::SetLabelColor(app_mode_title_, &gfx::kGdkWhite); 492 gtk_util::SetLabelColor(app_mode_title_, &gfx::kGdkWhite);
433 } 493 }
434 } 494 }
435 } 495 }
436 496
497 void BrowserTitlebar::ShowFaviconMenu(GdkEventButton* event) {
498 if (!favicon_menu_.get()) {
499 favicon_menu_.reset(new MenuGtk(this,
500 GetFaviconMenu(browser_window_->browser()->profile(), this), NULL));
501 }
502
503 favicon_menu_->Popup(app_mode_favicon_, reinterpret_cast<GdkEvent*>(event));
504 }
505
437 // static 506 // static
438 gboolean BrowserTitlebar::OnWindowStateChanged(GtkWindow* window, 507 gboolean BrowserTitlebar::OnWindowStateChanged(GtkWindow* window,
439 GdkEventWindowState* event, BrowserTitlebar* titlebar) { 508 GdkEventWindowState* event, BrowserTitlebar* titlebar) {
440 // Update the maximize/restore button. 509 // Update the maximize/restore button.
441 if (titlebar->browser_window_->IsMaximized()) { 510 if (titlebar->browser_window_->IsMaximized()) {
442 gtk_widget_hide(titlebar->maximize_button_->widget()); 511 gtk_widget_hide(titlebar->maximize_button_->widget());
443 gtk_widget_show(titlebar->restore_button_->widget()); 512 gtk_widget_show(titlebar->restore_button_->widget());
444 } else { 513 } else {
445 gtk_widget_hide(titlebar->restore_button_->widget()); 514 gtk_widget_hide(titlebar->restore_button_->widget());
446 gtk_widget_show(titlebar->maximize_button_->widget()); 515 gtk_widget_show(titlebar->maximize_button_->widget());
(...skipping 26 matching lines...) Expand all
473 titlebar->browser_window_->Close(); 542 titlebar->browser_window_->Close();
474 } else if (titlebar->restore_button_->widget() == button) { 543 } else if (titlebar->restore_button_->widget() == button) {
475 titlebar->browser_window_->UnMaximize(); 544 titlebar->browser_window_->UnMaximize();
476 } else if (titlebar->maximize_button_->widget() == button) { 545 } else if (titlebar->maximize_button_->widget() == button) {
477 gtk_window_maximize(titlebar->window_); 546 gtk_window_maximize(titlebar->window_);
478 } else if (titlebar->minimize_button_->widget() == button) { 547 } else if (titlebar->minimize_button_->widget() == button) {
479 gtk_window_iconify(titlebar->window_); 548 gtk_window_iconify(titlebar->window_);
480 } 549 }
481 } 550 }
482 551
552 // static
553 gboolean BrowserTitlebar::OnButtonPressed(GtkWidget* widget,
554 GdkEventButton* event,
555 BrowserTitlebar* titlebar) {
556 if (event->button != 1)
557 return FALSE;
558
559 titlebar->ShowFaviconMenu(event);
560 return TRUE;
561 }
562
483 void BrowserTitlebar::ShowContextMenu() { 563 void BrowserTitlebar::ShowContextMenu() {
484 if (!context_menu_.get()) { 564 if (!context_menu_.get()) {
485 static const MenuCreateMaterial context_menu_blueprint[] = { 565 static const MenuCreateMaterial context_menu_blueprint[] = {
486 { MENU_NORMAL, IDC_NEW_TAB, IDS_TAB_CXMENU_NEWTAB, 0, NULL, 566 { MENU_NORMAL, IDC_NEW_TAB, IDS_TAB_CXMENU_NEWTAB, 0, NULL,
487 GDK_t, GDK_CONTROL_MASK, true }, 567 GDK_t, GDK_CONTROL_MASK, true },
488 { MENU_NORMAL, IDC_RESTORE_TAB, IDS_RESTORE_TAB, 0, NULL, 568 { MENU_NORMAL, IDC_RESTORE_TAB, IDS_RESTORE_TAB, 0, NULL,
489 GDK_t, GDK_CONTROL_MASK | GDK_SHIFT_MASK, true }, 569 GDK_t, GDK_CONTROL_MASK | GDK_SHIFT_MASK, true },
490 { MENU_SEPARATOR }, 570 { MENU_SEPARATOR },
491 { MENU_NORMAL, IDC_TASK_MANAGER, IDS_TASK_MANAGER, 0, NULL, 571 { MENU_NORMAL, IDC_TASK_MANAGER, IDS_TASK_MANAGER, 0, NULL,
492 GDK_Escape, GDK_SHIFT_MASK, true }, 572 GDK_Escape, GDK_SHIFT_MASK, true },
493 #if !defined(OS_CHROMEOS) 573 #if !defined(OS_CHROMEOS)
494 { MENU_SEPARATOR }, 574 { MENU_SEPARATOR },
495 { MENU_CHECKBOX, kShowWindowDecorationsCommand, 575 { MENU_CHECKBOX, kShowWindowDecorationsCommand,
496 IDS_SHOW_WINDOW_DECORATIONS }, 576 IDS_SHOW_WINDOW_DECORATIONS },
497 #endif 577 #endif
498 { MENU_END }, 578 { MENU_END },
499 }; 579 };
500 580
501 context_menu_.reset(new MenuGtk(this, context_menu_blueprint, NULL)); 581 context_menu_.reset(new MenuGtk(this, context_menu_blueprint, NULL));
502 } 582 }
503 583
504 context_menu_->PopupAsContext(gtk_get_current_event_time()); 584 context_menu_->PopupAsContext(gtk_get_current_event_time());
505 } 585 }
506 586
507 bool BrowserTitlebar::IsCommandEnabled(int command_id) const { 587 bool BrowserTitlebar::IsCommandEnabled(int command_id) const {
508 switch (command_id) { 588 if (command_id == kShowWindowDecorationsCommand)
509 case IDC_NEW_TAB: 589 return true;
510 case kShowWindowDecorationsCommand:
511 return true;
512 590
513 case IDC_RESTORE_TAB: 591 return browser_window_->browser()->command_updater()->
514 return browser_window_->browser()->CanRestoreTab(); 592 IsCommandEnabled(command_id);
593 }
515 594
516 case IDC_TASK_MANAGER: 595 bool BrowserTitlebar::IsItemChecked(int command_id) const {
517 return true; 596 if (command_id == kShowWindowDecorationsCommand) {
597 PrefService* prefs = browser_window_->browser()->profile()->GetPrefs();
598 return !prefs->GetBoolean(prefs::kUseCustomChromeFrame);
599 }
518 600
519 default: 601 EncodingMenuController controller;
520 NOTREACHED(); 602 if (controller.DoesCommandBelongToEncodingMenu(command_id)) {
603 TabContents* tab_contents =
604 browser_window_->browser()->GetSelectedTabContents();
605 if (tab_contents) {
606 return controller.IsItemChecked(browser_window_->browser()->profile(),
607 tab_contents->encoding(),
608 command_id);
609 }
610 return false;
521 } 611 }
612
613 NOTREACHED();
522 return false; 614 return false;
523 } 615 }
524 616
525 bool BrowserTitlebar::IsItemChecked(int command_id) const { 617 void BrowserTitlebar::ExecuteCommand(int command_id) {
526 DCHECK(command_id == kShowWindowDecorationsCommand); 618 if (command_id == kShowWindowDecorationsCommand) {
527 PrefService* prefs = browser_window_->browser()->profile()->GetPrefs(); 619 PrefService* prefs = browser_window_->browser()->profile()->GetPrefs();
528 return !prefs->GetBoolean(prefs::kUseCustomChromeFrame); 620 prefs->SetBoolean(prefs::kUseCustomChromeFrame,
529 } 621 !prefs->GetBoolean(prefs::kUseCustomChromeFrame));
622 return;
623 }
530 624
531 void BrowserTitlebar::ExecuteCommand(int command_id) { 625 browser_window_->browser()->ExecuteCommand(command_id);
532 switch (command_id) {
533 case IDC_NEW_TAB:
534 case IDC_RESTORE_TAB:
535 case IDC_TASK_MANAGER:
536 browser_window_->browser()->ExecuteCommand(command_id);
537 break;
538
539 case kShowWindowDecorationsCommand:
540 {
541 PrefService* prefs = browser_window_->browser()->profile()->GetPrefs();
542 prefs->SetBoolean(prefs::kUseCustomChromeFrame,
543 !prefs->GetBoolean(prefs::kUseCustomChromeFrame));
544 break;
545 }
546
547 default:
548 NOTREACHED();
549 }
550 } 626 }
551 627
552 void BrowserTitlebar::Observe(NotificationType type, 628 void BrowserTitlebar::Observe(NotificationType type,
553 const NotificationSource& source, 629 const NotificationSource& source,
554 const NotificationDetails& details) { 630 const NotificationDetails& details) {
555 switch (type.value) { 631 switch (type.value) {
556 case NotificationType::BROWSER_THEME_CHANGED: 632 case NotificationType::BROWSER_THEME_CHANGED:
557 UpdateTextColor(); 633 UpdateTextColor();
558 break; 634 break;
559 635
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
620 if (g_throbber_frames) 696 if (g_throbber_frames)
621 return; 697 return;
622 698
623 // We load the light version of the throbber since it'll be in the titlebar. 699 // We load the light version of the throbber since it'll be in the titlebar.
624 g_throbber_frames = new std::vector<GdkPixbuf*>; 700 g_throbber_frames = new std::vector<GdkPixbuf*>;
625 MakeThrobberFrames(IDR_THROBBER_LIGHT, g_throbber_frames); 701 MakeThrobberFrames(IDR_THROBBER_LIGHT, g_throbber_frames);
626 702
627 g_throbber_waiting_frames = new std::vector<GdkPixbuf*>; 703 g_throbber_waiting_frames = new std::vector<GdkPixbuf*>;
628 MakeThrobberFrames(IDR_THROBBER_WAITING_LIGHT, g_throbber_waiting_frames); 704 MakeThrobberFrames(IDR_THROBBER_WAITING_LIGHT, g_throbber_waiting_frames);
629 } 705 }
OLDNEW
« no previous file with comments | « chrome/browser/gtk/browser_titlebar.h ('k') | chrome/browser/gtk/browser_toolbar_gtk.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698