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

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

Issue 10169019: Add PanelBrowserTitlebarGtk for panels on GTK. (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Move IsTypePanel() logic out of BrowserTitlebar Created 8 years, 8 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
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 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/ui/gtk/browser_titlebar.h" 5 #include "chrome/browser/ui/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>
(...skipping 416 matching lines...) Expand 10 before | Expand all | Expand 10 after
427 StringTokenizer tokenizer(button_string, ":,"); 427 StringTokenizer tokenizer(button_string, ":,");
428 tokenizer.set_options(StringTokenizer::RETURN_DELIMS); 428 tokenizer.set_options(StringTokenizer::RETURN_DELIMS);
429 int left_count = 0; 429 int left_count = 0;
430 int right_count = 0; 430 int right_count = 0;
431 while (tokenizer.GetNext()) { 431 while (tokenizer.GetNext()) {
432 if (tokenizer.token_is_delim()) { 432 if (tokenizer.token_is_delim()) {
433 if (*tokenizer.token_begin() == ':') 433 if (*tokenizer.token_begin() == ':')
434 left_side = false; 434 left_side = false;
435 } else { 435 } else {
436 base::StringPiece token = tokenizer.token_piece(); 436 base::StringPiece token = tokenizer.token_piece();
437 if (token == "minimize" && !IsTypePanel()) { 437 if (BuildButton(token.as_string(), left_side))
438 (left_side ? left_count : right_count)++; 438 (left_side ? left_count : right_count)++;
439 GtkWidget* parent_box = GetButtonHBox(left_side);
440 minimize_button_.reset(
441 BuildTitlebarButton(IDR_MINIMIZE, IDR_MINIMIZE_P,
442 IDR_MINIMIZE_H, parent_box, true,
443 IDS_XPFRAME_MINIMIZE_TOOLTIP));
444
445 gtk_widget_size_request(minimize_button_->widget(),
446 &minimize_button_req_);
447 } else if (token == "maximize" && !IsTypePanel()) {
448 (left_side ? left_count : right_count)++;
449 GtkWidget* parent_box = GetButtonHBox(left_side);
450 restore_button_.reset(
451 BuildTitlebarButton(IDR_RESTORE, IDR_RESTORE_P,
452 IDR_RESTORE_H, parent_box, true,
453 IDS_XPFRAME_RESTORE_TOOLTIP));
454 maximize_button_.reset(
455 BuildTitlebarButton(IDR_MAXIMIZE, IDR_MAXIMIZE_P,
456 IDR_MAXIMIZE_H, parent_box, true,
457 IDS_XPFRAME_MAXIMIZE_TOOLTIP));
458
459 gtk_util::SetButtonClickableByMouseButtons(maximize_button_->widget(),
460 true, true, true);
461 gtk_widget_size_request(restore_button_->widget(),
462 &restore_button_req_);
463 } else if (token == "close") {
464 (left_side ? left_count : right_count)++;
465 GtkWidget* parent_box = GetButtonHBox(left_side);
466 close_button_.reset(
467 BuildTitlebarButton(IDR_CLOSE, IDR_CLOSE_P,
468 IDR_CLOSE_H, parent_box, true,
469 IDS_XPFRAME_CLOSE_TOOLTIP));
470 close_button_->set_flipped(left_side);
471
472 gtk_widget_size_request(close_button_->widget(), &close_button_req_);
473 }
474 // Ignore any other values like "pin" since we don't have images for
475 // those.
476 } 439 }
477 } 440 }
478 441
479 // If we are in incognito mode, add the spy guy to either the end of the left 442 // If we are in incognito mode, add the spy guy to either the end of the left
480 // or the beginning of the right depending on which side has fewer buttons. 443 // or the beginning of the right depending on which side has fewer buttons.
481 display_avatar_on_left_ = right_count > left_count; 444 display_avatar_on_left_ = right_count > left_count;
482 445
483 // Now show the correct widgets in the two hierarchies. 446 // Now show the correct widgets in the two hierarchies.
484 if (using_custom_frame_) { 447 if (using_custom_frame_) {
485 gtk_widget_show_all(titlebar_left_buttons_vbox_); 448 gtk_widget_show_all(titlebar_left_buttons_vbox_);
486 gtk_widget_show_all(titlebar_right_buttons_vbox_); 449 gtk_widget_show_all(titlebar_right_buttons_vbox_);
487 } 450 }
488 UpdateMaximizeRestoreVisibility(); 451 UpdateMaximizeRestoreVisibility();
489 } 452 }
490 453
454 bool BrowserTitlebar::BuildButton(const std::string& button_token,
455 bool left_side) {
456 if (button_token == "minimize") {
457 GtkWidget* parent_box = GetButtonHBox(left_side);
458 minimize_button_.reset(
459 CreateTitlebarButton(IDR_MINIMIZE, IDR_MINIMIZE_P,
460 IDR_MINIMIZE_H, parent_box,
461 IDS_XPFRAME_MINIMIZE_TOOLTIP));
462
463 gtk_widget_size_request(minimize_button_->widget(),
464 &minimize_button_req_);
465 return true;
466 } else if (button_token == "maximize") {
jennb 2012/04/20 22:26:32 Should we add a "restore" token and separate the b
jianli 2012/04/20 23:00:29 We can't do that because the passing string to Bui
jennb 2012/04/21 01:04:49 You could modify the passed in string, kDefaultBut
467 GtkWidget* parent_box = GetButtonHBox(left_side);
468 restore_button_.reset(
469 CreateTitlebarButton(IDR_RESTORE, IDR_RESTORE_P,
470 IDR_RESTORE_H, parent_box,
471 IDS_XPFRAME_RESTORE_TOOLTIP));
472 maximize_button_.reset(
473 CreateTitlebarButton(IDR_MAXIMIZE, IDR_MAXIMIZE_P,
474 IDR_MAXIMIZE_H, parent_box,
475 IDS_XPFRAME_MAXIMIZE_TOOLTIP));
476
477 gtk_util::SetButtonClickableByMouseButtons(maximize_button_->widget(),
478 true, true, true);
479 gtk_widget_size_request(restore_button_->widget(),
480 &restore_button_req_);
481 return true;
482 } else if (button_token == "close") {
483 GtkWidget* parent_box = GetButtonHBox(left_side);
484 close_button_.reset(
485 CreateTitlebarButton(IDR_CLOSE, IDR_CLOSE_P,
486 IDR_CLOSE_H, parent_box,
487 IDS_XPFRAME_CLOSE_TOOLTIP));
488 close_button_->set_flipped(left_side);
489
490 gtk_widget_size_request(close_button_->widget(), &close_button_req_);
491 return true;
492 }
493 // Ignore any other values like "pin" since we don't have images for
494 // those.
495 return false;
496 }
497
491 GtkWidget* BrowserTitlebar::GetButtonHBox(bool left_side) { 498 GtkWidget* BrowserTitlebar::GetButtonHBox(bool left_side) {
492 if (left_side && titlebar_left_buttons_hbox_) 499 if (left_side && titlebar_left_buttons_hbox_)
493 return titlebar_left_buttons_hbox_; 500 return titlebar_left_buttons_hbox_;
494 else if (!left_side && titlebar_right_buttons_hbox_) 501 else if (!left_side && titlebar_right_buttons_hbox_)
495 return titlebar_right_buttons_hbox_; 502 return titlebar_right_buttons_hbox_;
496 503
497 // We put the min/max/restore/close buttons in a vbox so they are top aligned 504 // We put the min/max/restore/close buttons in a vbox so they are top aligned
498 // (up to padding) and don't vertically stretch. 505 // (up to padding) and don't vertically stretch.
499 GtkWidget* vbox = left_side ? titlebar_left_buttons_vbox_ : 506 GtkWidget* vbox = left_side ? titlebar_left_buttons_vbox_ :
500 titlebar_right_buttons_vbox_; 507 titlebar_right_buttons_vbox_;
501 508
502 GtkWidget* top_padding = gtk_fixed_new(); 509 GtkWidget* top_padding = gtk_fixed_new();
503 gtk_widget_set_size_request(top_padding, -1, kButtonOuterPadding); 510 gtk_widget_set_size_request(top_padding, -1, kButtonOuterPadding);
504 gtk_box_pack_start(GTK_BOX(vbox), top_padding, FALSE, FALSE, 0); 511 gtk_box_pack_start(GTK_BOX(vbox), top_padding, FALSE, FALSE, 0);
505 512
506 GtkWidget* buttons_hbox = gtk_hbox_new(FALSE, kButtonSpacing); 513 GtkWidget* buttons_hbox = gtk_hbox_new(FALSE, kButtonSpacing);
507 gtk_box_pack_start(GTK_BOX(vbox), buttons_hbox, FALSE, FALSE, 0); 514 gtk_box_pack_start(GTK_BOX(vbox), buttons_hbox, FALSE, FALSE, 0);
508 515
509 if (left_side) { 516 if (left_side) {
510 titlebar_left_buttons_hbox_ = buttons_hbox; 517 titlebar_left_buttons_hbox_ = buttons_hbox;
511 top_padding_left_ = top_padding; 518 top_padding_left_ = top_padding;
512 } else { 519 } else {
513 titlebar_right_buttons_hbox_ = buttons_hbox; 520 titlebar_right_buttons_hbox_ = buttons_hbox;
514 top_padding_right_ = top_padding; 521 top_padding_right_ = top_padding;
515 } 522 }
516 523
517 return buttons_hbox; 524 return buttons_hbox;
518 } 525 }
519 526
520 CustomDrawButton* BrowserTitlebar::BuildTitlebarButton(int image, 527 CustomDrawButton* BrowserTitlebar::CreateTitlebarButton(int image,
521 int image_pressed, int image_hot, GtkWidget* box, bool start, 528 int image_pressed, int image_hot, GtkWidget* box, int tooltip) {
522 int tooltip) {
523 CustomDrawButton* button = new CustomDrawButton(image, image_pressed, 529 CustomDrawButton* button = new CustomDrawButton(image, image_pressed,
524 image_hot, 0); 530 image_hot, 0);
525 gtk_widget_add_events(GTK_WIDGET(button->widget()), GDK_POINTER_MOTION_MASK); 531 gtk_widget_add_events(GTK_WIDGET(button->widget()), GDK_POINTER_MOTION_MASK);
526 g_signal_connect(button->widget(), "clicked", 532 g_signal_connect(button->widget(), "clicked",
527 G_CALLBACK(OnButtonClickedThunk), this); 533 G_CALLBACK(OnButtonClickedThunk), this);
528 g_signal_connect(button->widget(), "motion-notify-event", 534 g_signal_connect(button->widget(), "motion-notify-event",
529 G_CALLBACK(OnMouseMoveEvent), browser_window_); 535 G_CALLBACK(OnMouseMoveEvent), browser_window_);
530 std::string localized_tooltip = l10n_util::GetStringUTF8(tooltip); 536 std::string localized_tooltip = l10n_util::GetStringUTF8(tooltip);
531 gtk_widget_set_tooltip_text(button->widget(), 537 gtk_widget_set_tooltip_text(button->widget(),
532 localized_tooltip.c_str()); 538 localized_tooltip.c_str());
533 if (start) 539 gtk_box_pack_start(GTK_BOX(box), button->widget(), FALSE, FALSE, 0);
534 gtk_box_pack_start(GTK_BOX(box), button->widget(), FALSE, FALSE, 0);
535 else
536 gtk_box_pack_end(GTK_BOX(box), button->widget(), FALSE, FALSE, 0);
537 return button; 540 return button;
538 } 541 }
539 542
540 void BrowserTitlebar::UpdateButtonBackground(CustomDrawButton* button) { 543 void BrowserTitlebar::UpdateButtonBackground(CustomDrawButton* button) {
541 SkColor color = theme_service_->GetColor( 544 SkColor color = theme_service_->GetColor(
542 ThemeService::COLOR_BUTTON_BACKGROUND); 545 ThemeService::COLOR_BUTTON_BACKGROUND);
543 SkBitmap* background = 546 SkBitmap* background =
544 theme_service_->GetBitmapNamed(IDR_THEME_WINDOW_CONTROL_BACKGROUND); 547 theme_service_->GetBitmapNamed(IDR_THEME_WINDOW_CONTROL_BACKGROUND);
545 548
546 // TODO(erg): For now, we just use a completely black mask and we can get 549 // TODO(erg): For now, we just use a completely black mask and we can get
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
622 void BrowserTitlebar::UpdateThrobber(WebContents* web_contents) { 625 void BrowserTitlebar::UpdateThrobber(WebContents* web_contents) {
623 DCHECK(app_mode_favicon_); 626 DCHECK(app_mode_favicon_);
624 627
625 if (web_contents && web_contents->IsLoading()) { 628 if (web_contents && web_contents->IsLoading()) {
626 GdkPixbuf* icon_pixbuf = 629 GdkPixbuf* icon_pixbuf =
627 throbber_.GetNextFrame(web_contents->IsWaitingForResponse()); 630 throbber_.GetNextFrame(web_contents->IsWaitingForResponse());
628 gtk_image_set_from_pixbuf(GTK_IMAGE(app_mode_favicon_), icon_pixbuf); 631 gtk_image_set_from_pixbuf(GTK_IMAGE(app_mode_favicon_), icon_pixbuf);
629 } else { 632 } else {
630 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); 633 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
631 634
632 // Note: we want to exclude the application popup window. 635 // Note: we want to exclude the application popup/panel window.
633 if ((browser_window_->browser()->is_app() && 636 if ((browser_window_->browser()->is_app() &&
634 browser_window_->browser()->is_type_popup()) || 637 !browser_window_->browser()->is_type_tabbed())) {
635 IsTypePanel()) {
636 SkBitmap icon = browser_window_->browser()->GetCurrentPageIcon(); 638 SkBitmap icon = browser_window_->browser()->GetCurrentPageIcon();
637 if (icon.empty()) { 639 if (icon.empty()) {
638 // Fallback to the Chromium icon if the page has no icon. 640 // Fallback to the Chromium icon if the page has no icon.
639 gtk_image_set_from_pixbuf(GTK_IMAGE(app_mode_favicon_), 641 gtk_image_set_from_pixbuf(GTK_IMAGE(app_mode_favicon_),
640 rb.GetNativeImageNamed(IDR_PRODUCT_LOGO_16).ToGdkPixbuf()); 642 rb.GetNativeImageNamed(IDR_PRODUCT_LOGO_16).ToGdkPixbuf());
641 } else { 643 } else {
642 GdkPixbuf* icon_pixbuf = gfx::GdkPixbufFromSkBitmap(&icon); 644 GdkPixbuf* icon_pixbuf = gfx::GdkPixbufFromSkBitmap(&icon);
643 gtk_image_set_from_pixbuf(GTK_IMAGE(app_mode_favicon_), icon_pixbuf); 645 gtk_image_set_from_pixbuf(GTK_IMAGE(app_mode_favicon_), icon_pixbuf);
644 g_object_unref(icon_pixbuf); 646 g_object_unref(icon_pixbuf);
645 } 647 }
(...skipping 251 matching lines...) Expand 10 before | Expand all | Expand 10 after
897 browser_window_->UnMaximize(); 899 browser_window_->UnMaximize();
898 } else if (maximize_button_.get() && maximize_button_->widget() == button) { 900 } else if (maximize_button_.get() && maximize_button_->widget() == button) {
899 MaximizeButtonClicked(); 901 MaximizeButtonClicked();
900 } else if (minimize_button_.get() && minimize_button_->widget() == button) { 902 } else if (minimize_button_.get() && minimize_button_->widget() == button) {
901 gtk_window_iconify(window_); 903 gtk_window_iconify(window_);
902 } 904 }
903 } 905 }
904 906
905 gboolean BrowserTitlebar::OnFaviconMenuButtonPressed(GtkWidget* widget, 907 gboolean BrowserTitlebar::OnFaviconMenuButtonPressed(GtkWidget* widget,
906 GdkEventButton* event) { 908 GdkEventButton* event) {
907 if (event->button != 1 || IsTypePanel()) 909 if (event->button != 1)
908 return FALSE; 910 return FALSE;
909 911
910 ShowFaviconMenu(event); 912 ShowFaviconMenu(event);
911 return TRUE; 913 return TRUE;
912 } 914 }
913 915
914 void BrowserTitlebar::ShowContextMenu(GdkEventButton* event) { 916 void BrowserTitlebar::ShowContextMenu(GdkEventButton* event) {
915 if (!context_menu_.get()) { 917 if (!context_menu_.get()) {
916 context_menu_model_.reset(new ContextMenuModel(this)); 918 context_menu_model_.reset(new ContextMenuModel(this));
917 context_menu_.reset(new MenuGtk(NULL, context_menu_model_.get())); 919 context_menu_.reset(new MenuGtk(NULL, context_menu_model_.get()));
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after
1048 // Can be called during shutdown; BrowserWindowGtk will set our |window_| 1050 // Can be called during shutdown; BrowserWindowGtk will set our |window_|
1049 // to NULL during that time. 1051 // to NULL during that time.
1050 if (!window_) 1052 if (!window_)
1051 return; 1053 return;
1052 1054
1053 window_has_focus_ = 1055 window_has_focus_ =
1054 gtk_widget_get_window(GTK_WIDGET(window_)) == active_window; 1056 gtk_widget_get_window(GTK_WIDGET(window_)) == active_window;
1055 UpdateTextColor(); 1057 UpdateTextColor();
1056 } 1058 }
1057 1059
1058 bool BrowserTitlebar::IsTypePanel() {
1059 return browser_window_->browser()->is_type_panel();
1060 }
1061
1062 bool BrowserTitlebar::ShouldDisplayAvatar() { 1060 bool BrowserTitlebar::ShouldDisplayAvatar() {
1063 return (IsOffTheRecord() || HasMultipleProfiles()) && 1061 return (IsOffTheRecord() || HasMultipleProfiles()) &&
1064 browser_window_->browser()->is_type_tabbed(); 1062 browser_window_->browser()->is_type_tabbed();
1065 } 1063 }
1066 1064
1067 bool BrowserTitlebar::IsOffTheRecord() { 1065 bool BrowserTitlebar::IsOffTheRecord() {
1068 return browser_window_->browser()->profile()->IsOffTheRecord(); 1066 return browser_window_->browser()->profile()->IsOffTheRecord();
1069 } 1067 }
1070 1068
1071 /////////////////////////////////////////////////////////////////////////////// 1069 ///////////////////////////////////////////////////////////////////////////////
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
1128 ui::SimpleMenuModel::Delegate* delegate) 1126 ui::SimpleMenuModel::Delegate* delegate)
1129 : SimpleMenuModel(delegate) { 1127 : SimpleMenuModel(delegate) {
1130 AddItemWithStringId(IDC_NEW_TAB, IDS_TAB_CXMENU_NEWTAB); 1128 AddItemWithStringId(IDC_NEW_TAB, IDS_TAB_CXMENU_NEWTAB);
1131 AddItemWithStringId(IDC_RESTORE_TAB, IDS_RESTORE_TAB); 1129 AddItemWithStringId(IDC_RESTORE_TAB, IDS_RESTORE_TAB);
1132 AddSeparator(); 1130 AddSeparator();
1133 AddItemWithStringId(IDC_TASK_MANAGER, IDS_TASK_MANAGER); 1131 AddItemWithStringId(IDC_TASK_MANAGER, IDS_TASK_MANAGER);
1134 AddSeparator(); 1132 AddSeparator();
1135 AddCheckItemWithStringId(kShowWindowDecorationsCommand, 1133 AddCheckItemWithStringId(kShowWindowDecorationsCommand,
1136 IDS_SHOW_WINDOW_DECORATIONS_MENU); 1134 IDS_SHOW_WINDOW_DECORATIONS_MENU);
1137 } 1135 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698