Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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_toolbar_gtk.h" | 5 #include "chrome/browser/gtk/browser_toolbar_gtk.h" |
| 6 | 6 |
| 7 #include <X11/XF86keysym.h> | 7 #include <X11/XF86keysym.h> |
| 8 #include <gdk/gdkkeysyms.h> | 8 #include <gdk/gdkkeysyms.h> |
| 9 #include <gtk/gtk.h> | 9 #include <gtk/gtk.h> |
| 10 | 10 |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 70 | 70 |
| 71 // Interior spacing between toolbar widgets. | 71 // Interior spacing between toolbar widgets. |
| 72 const int kToolbarWidgetSpacing = 1; | 72 const int kToolbarWidgetSpacing = 1; |
| 73 | 73 |
| 74 // Amount of rounding on top corners of toolbar. Only used in Gtk theme mode. | 74 // Amount of rounding on top corners of toolbar. Only used in Gtk theme mode. |
| 75 const int kToolbarCornerSize = 3; | 75 const int kToolbarCornerSize = 3; |
| 76 | 76 |
| 77 // The offset in pixels of the upgrade dot on the app menu. | 77 // The offset in pixels of the upgrade dot on the app menu. |
| 78 const int kUpgradeDotOffset = 6; | 78 const int kUpgradeDotOffset = 6; |
| 79 | 79 |
| 80 // The duration of the upgrade notification animation (actually the duration | |
| 81 // of a half-throb). | |
| 82 const int kThrobDuration = 1000; | |
| 83 | |
| 84 void SetWidgetHeightRequest(GtkWidget* widget, gpointer user_data) { | 80 void SetWidgetHeightRequest(GtkWidget* widget, gpointer user_data) { |
| 85 gtk_widget_set_size_request(widget, -1, GPOINTER_TO_INT(user_data)); | 81 gtk_widget_set_size_request(widget, -1, GPOINTER_TO_INT(user_data)); |
| 86 } | 82 } |
| 87 | 83 |
| 88 } // namespace | 84 } // namespace |
| 89 | 85 |
| 90 // BrowserToolbarGtk, public --------------------------------------------------- | 86 // BrowserToolbarGtk, public --------------------------------------------------- |
| 91 | 87 |
| 92 BrowserToolbarGtk::BrowserToolbarGtk(Browser* browser, BrowserWindowGtk* window) | 88 BrowserToolbarGtk::BrowserToolbarGtk(Browser* browser, BrowserWindowGtk* window) |
| 93 : toolbar_(NULL), | 89 : toolbar_(NULL), |
| 94 location_bar_(new LocationBarViewGtk(browser)), | 90 location_bar_(new LocationBarViewGtk(browser)), |
| 95 model_(browser->toolbar_model()), | 91 model_(browser->toolbar_model()), |
| 96 wrench_menu_model_(this, browser), | 92 wrench_menu_model_(this, browser), |
| 97 browser_(browser), | 93 browser_(browser), |
| 98 window_(window), | 94 window_(window), |
| 99 profile_(NULL), | 95 profile_(NULL) { |
| 100 upgrade_reminder_animation_(this), | |
| 101 upgrade_reminder_canceled_(false) { | |
| 102 browser_->command_updater()->AddCommandObserver(IDC_BACK, this); | 96 browser_->command_updater()->AddCommandObserver(IDC_BACK, this); |
| 103 browser_->command_updater()->AddCommandObserver(IDC_FORWARD, this); | 97 browser_->command_updater()->AddCommandObserver(IDC_FORWARD, this); |
| 104 browser_->command_updater()->AddCommandObserver(IDC_HOME, this); | 98 browser_->command_updater()->AddCommandObserver(IDC_HOME, this); |
| 105 browser_->command_updater()->AddCommandObserver(IDC_BOOKMARK_PAGE, this); | 99 browser_->command_updater()->AddCommandObserver(IDC_BOOKMARK_PAGE, this); |
| 106 | 100 |
| 107 registrar_.Add(this, | 101 registrar_.Add(this, |
| 108 NotificationType::BROWSER_THEME_CHANGED, | 102 NotificationType::BROWSER_THEME_CHANGED, |
| 109 NotificationService::AllSources()); | 103 NotificationService::AllSources()); |
| 110 registrar_.Add(this, | 104 registrar_.Add(this, |
| 111 NotificationType::UPGRADE_RECOMMENDED, | 105 NotificationType::UPGRADE_RECOMMENDED, |
| 112 NotificationService::AllSources()); | 106 NotificationService::AllSources()); |
| 113 | |
| 114 upgrade_reminder_animation_.SetThrobDuration(kThrobDuration); | |
| 115 | |
| 116 ActiveWindowWatcherX::AddObserver(this); | |
| 117 } | 107 } |
| 118 | 108 |
| 119 BrowserToolbarGtk::~BrowserToolbarGtk() { | 109 BrowserToolbarGtk::~BrowserToolbarGtk() { |
| 120 ActiveWindowWatcherX::RemoveObserver(this); | |
| 121 | |
| 122 browser_->command_updater()->RemoveCommandObserver(IDC_BACK, this); | 110 browser_->command_updater()->RemoveCommandObserver(IDC_BACK, this); |
| 123 browser_->command_updater()->RemoveCommandObserver(IDC_FORWARD, this); | 111 browser_->command_updater()->RemoveCommandObserver(IDC_FORWARD, this); |
| 124 browser_->command_updater()->RemoveCommandObserver(IDC_HOME, this); | 112 browser_->command_updater()->RemoveCommandObserver(IDC_HOME, this); |
| 125 browser_->command_updater()->RemoveCommandObserver(IDC_BOOKMARK_PAGE, this); | 113 browser_->command_updater()->RemoveCommandObserver(IDC_BOOKMARK_PAGE, this); |
| 126 | 114 |
| 127 offscreen_entry_.Destroy(); | 115 offscreen_entry_.Destroy(); |
| 128 | 116 |
| 129 wrench_menu_.reset(); | 117 wrench_menu_.reset(); |
| 130 } | 118 } |
| 131 | 119 |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 222 | 210 |
| 223 // Put the wrench button in a box so that we can paint the update notification | 211 // Put the wrench button in a box so that we can paint the update notification |
| 224 // over it. | 212 // over it. |
| 225 GtkWidget* wrench_box = gtk_alignment_new(0, 0, 1, 1); | 213 GtkWidget* wrench_box = gtk_alignment_new(0, 0, 1, 1); |
| 226 g_signal_connect_after(wrench_box, "expose-event", | 214 g_signal_connect_after(wrench_box, "expose-event", |
| 227 G_CALLBACK(OnWrenchMenuButtonExposeThunk), this); | 215 G_CALLBACK(OnWrenchMenuButtonExposeThunk), this); |
| 228 gtk_container_add(GTK_CONTAINER(wrench_box), wrench_button); | 216 gtk_container_add(GTK_CONTAINER(wrench_box), wrench_button); |
| 229 gtk_box_pack_start(GTK_BOX(toolbar_), wrench_box, FALSE, FALSE, 4); | 217 gtk_box_pack_start(GTK_BOX(toolbar_), wrench_box, FALSE, FALSE, 4); |
| 230 | 218 |
| 231 wrench_menu_.reset(new MenuGtk(this, &wrench_menu_model_)); | 219 wrench_menu_.reset(new MenuGtk(this, &wrench_menu_model_)); |
| 232 g_signal_connect(wrench_menu_->widget(), "show", | |
| 233 G_CALLBACK(OnWrenchMenuShowThunk), this); | |
| 234 registrar_.Add(this, NotificationType::ZOOM_LEVEL_CHANGED, | 220 registrar_.Add(this, NotificationType::ZOOM_LEVEL_CHANGED, |
| 235 Source<Profile>(browser_->profile())); | 221 Source<Profile>(browser_->profile())); |
| 236 | 222 |
| 237 if (ShouldOnlyShowLocation()) { | 223 if (ShouldOnlyShowLocation()) { |
| 238 gtk_widget_show(event_box_); | 224 gtk_widget_show(event_box_); |
| 239 gtk_widget_show(alignment_); | 225 gtk_widget_show(alignment_); |
| 240 gtk_widget_show(toolbar_); | 226 gtk_widget_show(toolbar_); |
| 241 gtk_widget_show_all(location_hbox_); | 227 gtk_widget_show_all(location_hbox_); |
| 242 gtk_widget_hide(reload_->widget()); | 228 gtk_widget_hide(reload_->widget()); |
| 243 } else { | 229 } else { |
| 244 gtk_widget_show_all(event_box_); | 230 gtk_widget_show_all(event_box_); |
| 245 if (actions_toolbar_->button_count() == 0) | 231 if (actions_toolbar_->button_count() == 0) |
| 246 gtk_widget_hide(actions_toolbar_->widget()); | 232 gtk_widget_hide(actions_toolbar_->widget()); |
| 247 } | 233 } |
| 248 // Initialize pref-dependent UI state. | 234 // Initialize pref-dependent UI state. |
| 249 NotifyPrefChanged(NULL); | 235 NotifyPrefChanged(NULL); |
| 250 | 236 |
| 251 // Because the above does a recursive show all on all widgets we need to | 237 // Because the above does a recursive show all on all widgets we need to |
| 252 // update the icon visibility to hide them. | 238 // update the icon visibility to hide them. |
| 253 location_bar_->UpdateContentSettingsIcons(); | 239 location_bar_->UpdateContentSettingsIcons(); |
| 254 | 240 |
| 255 SetViewIDs(); | 241 SetViewIDs(); |
| 256 theme_provider_->InitThemesFor(this); | 242 theme_provider_->InitThemesFor(this); |
| 257 | |
| 258 MaybeShowUpgradeReminder(); | |
| 259 } | 243 } |
| 260 | 244 |
| 261 void BrowserToolbarGtk::SetViewIDs() { | 245 void BrowserToolbarGtk::SetViewIDs() { |
| 262 ViewIDUtil::SetID(widget(), VIEW_ID_TOOLBAR); | 246 ViewIDUtil::SetID(widget(), VIEW_ID_TOOLBAR); |
| 263 ViewIDUtil::SetID(back_->widget(), VIEW_ID_BACK_BUTTON); | 247 ViewIDUtil::SetID(back_->widget(), VIEW_ID_BACK_BUTTON); |
| 264 ViewIDUtil::SetID(forward_->widget(), VIEW_ID_FORWARD_BUTTON); | 248 ViewIDUtil::SetID(forward_->widget(), VIEW_ID_FORWARD_BUTTON); |
| 265 ViewIDUtil::SetID(reload_->widget(), VIEW_ID_RELOAD_BUTTON); | 249 ViewIDUtil::SetID(reload_->widget(), VIEW_ID_RELOAD_BUTTON); |
| 266 ViewIDUtil::SetID(home_->widget(), VIEW_ID_HOME_BUTTON); | 250 ViewIDUtil::SetID(home_->widget(), VIEW_ID_HOME_BUTTON); |
| 267 ViewIDUtil::SetID(location_bar_->widget(), VIEW_ID_LOCATION_BAR); | 251 ViewIDUtil::SetID(location_bar_->widget(), VIEW_ID_LOCATION_BAR); |
| 268 ViewIDUtil::SetID(wrench_menu_button_->widget(), VIEW_ID_APP_MENU); | 252 ViewIDUtil::SetID(wrench_menu_button_->widget(), VIEW_ID_APP_MENU); |
| (...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 388 if (use_gtk) { | 372 if (use_gtk) { |
| 389 // We need to manually update the icon if we are in GTK mode. (Note that | 373 // We need to manually update the icon if we are in GTK mode. (Note that |
| 390 // we set the initial value in Init()). | 374 // we set the initial value in Init()). |
| 391 gtk_image_set_from_pixbuf( | 375 gtk_image_set_from_pixbuf( |
| 392 GTK_IMAGE(wrench_menu_image_), | 376 GTK_IMAGE(wrench_menu_image_), |
| 393 theme_provider_->GetRTLEnabledPixbufNamed(IDR_TOOLS)); | 377 theme_provider_->GetRTLEnabledPixbufNamed(IDR_TOOLS)); |
| 394 } | 378 } |
| 395 | 379 |
| 396 UpdateRoundedness(); | 380 UpdateRoundedness(); |
| 397 } else if (type == NotificationType::UPGRADE_RECOMMENDED) { | 381 } else if (type == NotificationType::UPGRADE_RECOMMENDED) { |
| 398 MaybeShowUpgradeReminder(); | 382 gtk_widget_queue_draw(wrench_menu_button_->widget()); |
| 399 } else if (type == NotificationType::ZOOM_LEVEL_CHANGED) { | 383 } else if (type == NotificationType::ZOOM_LEVEL_CHANGED) { |
| 400 // If our zoom level changed, we need to tell the menu to update its state, | 384 // If our zoom level changed, we need to tell the menu to update its state, |
| 401 // since the menu could still be open. | 385 // since the menu could still be open. |
| 402 wrench_menu_->UpdateMenu(); | 386 wrench_menu_->UpdateMenu(); |
| 403 } else { | 387 } else { |
| 404 NOTREACHED(); | 388 NOTREACHED(); |
| 405 } | 389 } |
| 406 } | 390 } |
| 407 | 391 |
| 408 // BrowserToolbarGtk, public --------------------------------------------------- | 392 // BrowserToolbarGtk, public --------------------------------------------------- |
| (...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 631 } | 615 } |
| 632 } | 616 } |
| 633 | 617 |
| 634 if (!pref || | 618 if (!pref || |
| 635 *pref == prefs::kHomePage || | 619 *pref == prefs::kHomePage || |
| 636 *pref == prefs::kHomePageIsNewTabPage) | 620 *pref == prefs::kHomePageIsNewTabPage) |
| 637 SetUpDragForHomeButton(!home_page_.IsManaged() && | 621 SetUpDragForHomeButton(!home_page_.IsManaged() && |
| 638 !home_page_is_new_tab_page_.IsManaged()); | 622 !home_page_is_new_tab_page_.IsManaged()); |
| 639 } | 623 } |
| 640 | 624 |
| 641 void BrowserToolbarGtk::MaybeShowUpgradeReminder() { | |
| 642 // Only show the upgrade reminder animation for the currently active window. | |
| 643 if (window_->IsActive() && | |
| 644 Singleton<UpgradeDetector>::get()->notify_upgrade() && | |
| 645 !upgrade_reminder_canceled_) { | |
| 646 upgrade_reminder_animation_.StartThrobbing(-1); | |
| 647 } else { | |
| 648 upgrade_reminder_animation_.Reset(); | |
| 649 } | |
| 650 } | |
| 651 | |
| 652 bool BrowserToolbarGtk::ShouldOnlyShowLocation() const { | 625 bool BrowserToolbarGtk::ShouldOnlyShowLocation() const { |
| 653 // If we're a popup window, only show the location bar (omnibox). | 626 // If we're a popup window, only show the location bar (omnibox). |
| 654 return browser_->type() != Browser::TYPE_NORMAL; | 627 return browser_->type() != Browser::TYPE_NORMAL; |
| 655 } | 628 } |
| 656 | 629 |
| 657 void BrowserToolbarGtk::AnimationEnded(const Animation* animation) { | |
| 658 DCHECK_EQ(animation, &upgrade_reminder_animation_); | |
| 659 gtk_widget_queue_draw(wrench_menu_button_->widget()->parent); | |
| 660 } | |
| 661 | |
| 662 void BrowserToolbarGtk::AnimationProgressed(const Animation* animation) { | |
| 663 DCHECK_EQ(animation, &upgrade_reminder_animation_); | |
| 664 if (UpgradeAnimationIsFaded()) | |
| 665 gtk_widget_queue_draw(wrench_menu_button_->widget()->parent); | |
| 666 } | |
| 667 | |
| 668 void BrowserToolbarGtk::AnimationCanceled(const Animation* animation) { | |
| 669 AnimationEnded(animation); | |
| 670 } | |
| 671 | |
| 672 void BrowserToolbarGtk::ActiveWindowChanged(GdkWindow* active_window) { | |
| 673 MaybeShowUpgradeReminder(); | |
| 674 } | |
| 675 | |
| 676 void BrowserToolbarGtk::OnWrenchMenuShow(GtkWidget* sender) { | |
| 677 if (upgrade_reminder_animation_.is_animating()) { | |
| 678 upgrade_reminder_canceled_ = true; | |
| 679 MaybeShowUpgradeReminder(); | |
| 680 } | |
| 681 } | |
| 682 | |
| 683 gboolean BrowserToolbarGtk::OnWrenchMenuButtonExpose(GtkWidget* sender, | 630 gboolean BrowserToolbarGtk::OnWrenchMenuButtonExpose(GtkWidget* sender, |
| 684 GdkEventExpose* expose) { | 631 GdkEventExpose* expose) { |
| 685 if (!Singleton<UpgradeDetector>::get()->notify_upgrade()) | 632 if (!Singleton<UpgradeDetector>::get()->notify_upgrade()) |
| 686 return FALSE; | 633 return FALSE; |
| 687 | 634 |
| 688 SkBitmap badge; | 635 const SkBitmap& badge = |
| 689 if (UpgradeAnimationIsFaded()) { | 636 *theme_provider_->GetBitmapNamed(IDR_UPDATE_BADGE); |
| 690 badge = SkBitmapOperations::CreateBlendedBitmap( | |
| 691 *theme_provider_->GetBitmapNamed(IDR_UPGRADE_DOT_ACTIVE), | |
| 692 *theme_provider_->GetBitmapNamed(IDR_UPGRADE_DOT_INACTIVE), | |
| 693 upgrade_reminder_animation_.GetCurrentValue()); | |
| 694 } else { | |
| 695 badge = *theme_provider_->GetBitmapNamed(IDR_UPGRADE_DOT_INACTIVE); | |
| 696 } | |
| 697 | 637 |
| 698 // Draw the chrome app menu icon onto the canvas. | 638 // Draw the chrome app menu icon onto the canvas. |
| 699 gfx::CanvasSkiaPaint canvas(expose, false); | 639 gfx::CanvasSkiaPaint canvas(expose, false); |
| 700 int x_offset = base::i18n::IsRTL() ? | 640 int x_offset = base::i18n::IsRTL() ? |
| 701 sender->allocation.width - kUpgradeDotOffset - badge.width() : | 641 sender->allocation.width - kUpgradeDotOffset - badge.width() : |
| 702 kUpgradeDotOffset; | 642 kUpgradeDotOffset; |
| 703 int y_offset = sender->allocation.height / 2 + badge.height(); | 643 int y_offset = sender->allocation.height / 2; |
| 704 canvas.DrawBitmapInt( | 644 canvas.DrawBitmapInt( |
| 705 badge, | 645 badge, |
| 706 sender->allocation.x + x_offset, | 646 sender->allocation.x + x_offset, |
| 707 sender->allocation.y + y_offset); | 647 sender->allocation.y + y_offset); |
|
Finnur
2010/11/18 10:12:57
Actually:
The badge needs to be in the top right
| |
| 708 | 648 |
| 709 return FALSE; | 649 return FALSE; |
| 710 } | 650 } |
| 711 | |
| 712 bool BrowserToolbarGtk::UpgradeAnimationIsFaded() { | |
| 713 return upgrade_reminder_animation_.cycles_remaining() > 0 && | |
| 714 // This funky looking math makes the badge throb for 2 seconds once | |
| 715 // every 8 seconds. | |
| 716 ((upgrade_reminder_animation_.cycles_remaining() - 1) / 2) % 4 == 0; | |
| 717 } | |
| OLD | NEW |