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/views/toolbar_view.h" | 5 #include "chrome/browser/views/toolbar_view.h" |
6 | 6 |
7 #include "app/l10n_util.h" | 7 #include "app/l10n_util.h" |
8 #include "app/resource_bundle.h" | 8 #include "app/resource_bundle.h" |
9 #include "base/command_line.h" | 9 #include "base/command_line.h" |
10 #include "chrome/app/chrome_dll_resource.h" | 10 #include "chrome/app/chrome_dll_resource.h" |
11 #include "chrome/browser/browser.h" | 11 #include "chrome/browser/browser.h" |
12 #include "chrome/browser/browser_theme_provider.h" | 12 #include "chrome/browser/browser_theme_provider.h" |
13 #include "chrome/browser/browser_window.h" | 13 #include "chrome/browser/browser_window.h" |
14 #include "chrome/browser/pref_service.h" | 14 #include "chrome/browser/pref_service.h" |
15 #include "chrome/browser/profile.h" | 15 #include "chrome/browser/profile.h" |
| 16 #include "chrome/browser/upgrade_detector.h" |
16 #include "chrome/browser/view_ids.h" | 17 #include "chrome/browser/view_ids.h" |
17 #include "chrome/browser/views/bookmark_menu_button.h" | 18 #include "chrome/browser/views/bookmark_menu_button.h" |
18 #include "chrome/browser/views/browser_actions_container.h" | 19 #include "chrome/browser/views/browser_actions_container.h" |
19 #include "chrome/browser/views/event_utils.h" | 20 #include "chrome/browser/views/event_utils.h" |
20 #include "chrome/browser/views/frame/browser_view.h" | 21 #include "chrome/browser/views/frame/browser_view.h" |
21 #include "chrome/common/chrome_switches.h" | 22 #include "chrome/common/chrome_switches.h" |
22 #include "chrome/common/notification_service.h" | 23 #include "chrome/common/notification_service.h" |
23 #include "chrome/common/pref_names.h" | 24 #include "chrome/common/pref_names.h" |
24 #include "gfx/canvas.h" | 25 #include "gfx/canvas.h" |
25 #include "grit/chromium_strings.h" | 26 #include "grit/chromium_strings.h" |
26 #include "grit/generated_resources.h" | 27 #include "grit/generated_resources.h" |
| 28 #include "gfx/skbitmap_operations.h" |
27 #include "grit/theme_resources.h" | 29 #include "grit/theme_resources.h" |
28 #include "views/controls/button/button_dropdown.h" | 30 #include "views/controls/button/button_dropdown.h" |
29 #include "views/focus/view_storage.h" | 31 #include "views/focus/view_storage.h" |
30 #include "views/widget/tooltip_manager.h" | 32 #include "views/widget/tooltip_manager.h" |
31 #include "views/window/non_client_view.h" | 33 #include "views/window/non_client_view.h" |
32 #include "views/window/window.h" | 34 #include "views/window/window.h" |
33 | 35 |
34 static const int kControlHorizOffset = 4; | 36 static const int kControlHorizOffset = 4; |
35 static const int kControlVertOffset = 6; | 37 static const int kControlVertOffset = 6; |
36 static const int kControlIndent = 3; | 38 static const int kControlIndent = 3; |
37 static const int kStatusBubbleWidth = 480; | 39 static const int kStatusBubbleWidth = 480; |
38 | 40 |
| 41 // The length of time to run the upgrade notification animation (the time it |
| 42 // takes one pulse to run its course and go back to its original brightness). |
| 43 static const int kPulseDuration = 2000; |
| 44 |
| 45 // How long to wait between pulsating the upgrade notifier. |
| 46 static const int kPulsateEveryMs = 8000; |
| 47 |
| 48 // The offset in pixels of the upgrade dot on the app menu. |
| 49 static const int kUpgradeDotOffset = 11; |
| 50 |
39 // Separation between the location bar and the menus. | 51 // Separation between the location bar and the menus. |
40 static const int kMenuButtonOffset = 3; | 52 static const int kMenuButtonOffset = 3; |
41 | 53 |
42 // Padding to the right of the location bar | 54 // Padding to the right of the location bar |
43 static const int kPaddingRight = 2; | 55 static const int kPaddingRight = 2; |
44 | 56 |
45 static const int kPopupTopSpacingNonGlass = 3; | 57 static const int kPopupTopSpacingNonGlass = 3; |
46 static const int kPopupBottomSpacingNonGlass = 2; | 58 static const int kPopupBottomSpacingNonGlass = 2; |
47 static const int kPopupBottomSpacingGlass = 1; | 59 static const int kPopupBottomSpacingGlass = 1; |
48 | 60 |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
82 | 94 |
83 if (browser->SupportsWindowFeature(Browser::FEATURE_TABSTRIP)) | 95 if (browser->SupportsWindowFeature(Browser::FEATURE_TABSTRIP)) |
84 display_mode_ = DISPLAYMODE_NORMAL; | 96 display_mode_ = DISPLAYMODE_NORMAL; |
85 else | 97 else |
86 display_mode_ = DISPLAYMODE_LOCATION; | 98 display_mode_ = DISPLAYMODE_LOCATION; |
87 | 99 |
88 if (!kPopupBackgroundEdge) { | 100 if (!kPopupBackgroundEdge) { |
89 kPopupBackgroundEdge = ResourceBundle::GetSharedInstance().GetBitmapNamed( | 101 kPopupBackgroundEdge = ResourceBundle::GetSharedInstance().GetBitmapNamed( |
90 IDR_LOCATIONBG_POPUPMODE_EDGE); | 102 IDR_LOCATIONBG_POPUPMODE_EDGE); |
91 } | 103 } |
| 104 |
| 105 if (!Singleton<UpgradeDetector>::get()->notify_upgrade()) { |
| 106 registrar_.Add(this, |
| 107 NotificationType::UPGRADE_RECOMMENDED, |
| 108 NotificationService::AllSources()); |
| 109 } |
92 } | 110 } |
93 | 111 |
94 ToolbarView::~ToolbarView() { | 112 ToolbarView::~ToolbarView() { |
95 if (destroyed_flag_) | 113 if (destroyed_flag_) |
96 *destroyed_flag_ = true; | 114 *destroyed_flag_ = true; |
97 if (menu_bar_emulation_mode_) { | 115 if (menu_bar_emulation_mode_) { |
98 focus_manager_->UnregisterAccelerators(this); | 116 focus_manager_->UnregisterAccelerators(this); |
99 focus_manager_->RemoveFocusChangeListener(this); | 117 focus_manager_->RemoveFocusChangeListener(this); |
100 } | 118 } |
101 } | 119 } |
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
273 | 291 |
274 void ToolbarView::OnInputInProgress(bool in_progress) { | 292 void ToolbarView::OnInputInProgress(bool in_progress) { |
275 // The edit should make sure we're only notified when something changes. | 293 // The edit should make sure we're only notified when something changes. |
276 DCHECK(model_->input_in_progress() != in_progress); | 294 DCHECK(model_->input_in_progress() != in_progress); |
277 | 295 |
278 model_->set_input_in_progress(in_progress); | 296 model_->set_input_in_progress(in_progress); |
279 location_bar_->Update(NULL); | 297 location_bar_->Update(NULL); |
280 } | 298 } |
281 | 299 |
282 //////////////////////////////////////////////////////////////////////////////// | 300 //////////////////////////////////////////////////////////////////////////////// |
| 301 // ToolbarView, AnimationDelegate implementation: |
| 302 |
| 303 void ToolbarView::AnimationProgressed(const Animation* animation) { |
| 304 app_menu_->SetIcon(GetAppMenuIcon()); |
| 305 SchedulePaint(); |
| 306 } |
| 307 |
| 308 //////////////////////////////////////////////////////////////////////////////// |
283 // ToolbarView, CommandUpdater::CommandObserver implementation: | 309 // ToolbarView, CommandUpdater::CommandObserver implementation: |
284 | 310 |
285 void ToolbarView::EnabledStateChangedForCommand(int id, bool enabled) { | 311 void ToolbarView::EnabledStateChangedForCommand(int id, bool enabled) { |
286 views::Button* button = NULL; | 312 views::Button* button = NULL; |
287 switch (id) { | 313 switch (id) { |
288 case IDC_BACK: | 314 case IDC_BACK: |
289 button = back_; | 315 button = back_; |
290 break; | 316 break; |
291 case IDC_FORWARD: | 317 case IDC_FORWARD: |
292 button = forward_; | 318 button = forward_; |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
333 | 359 |
334 void ToolbarView::Observe(NotificationType type, | 360 void ToolbarView::Observe(NotificationType type, |
335 const NotificationSource& source, | 361 const NotificationSource& source, |
336 const NotificationDetails& details) { | 362 const NotificationDetails& details) { |
337 if (type == NotificationType::PREF_CHANGED) { | 363 if (type == NotificationType::PREF_CHANGED) { |
338 std::wstring* pref_name = Details<std::wstring>(details).ptr(); | 364 std::wstring* pref_name = Details<std::wstring>(details).ptr(); |
339 if (*pref_name == prefs::kShowHomeButton) { | 365 if (*pref_name == prefs::kShowHomeButton) { |
340 Layout(); | 366 Layout(); |
341 SchedulePaint(); | 367 SchedulePaint(); |
342 } | 368 } |
| 369 } else if (type == NotificationType::UPGRADE_RECOMMENDED) { |
| 370 ShowUpgradeReminder(); |
343 } | 371 } |
344 } | 372 } |
345 | 373 |
346 //////////////////////////////////////////////////////////////////////////////// | 374 //////////////////////////////////////////////////////////////////////////////// |
347 // ToolbarView, menus::SimpleMenuModel::Delegate implementation: | 375 // ToolbarView, menus::SimpleMenuModel::Delegate implementation: |
348 | 376 |
349 bool ToolbarView::IsCommandIdChecked(int command_id) const { | 377 bool ToolbarView::IsCommandIdChecked(int command_id) const { |
350 if (command_id == IDC_SHOW_BOOKMARK_BAR) | 378 if (command_id == IDC_SHOW_BOOKMARK_BAR) |
351 return profile_->GetPrefs()->GetBoolean(prefs::kShowBookmarkBar); | 379 return profile_->GetPrefs()->GetBoolean(prefs::kShowBookmarkBar); |
352 return false; | 380 return false; |
(...skipping 305 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
658 l10n_util::GetString(IDS_PRODUCT_NAME))); | 686 l10n_util::GetString(IDS_PRODUCT_NAME))); |
659 app_menu_->SetID(VIEW_ID_APP_MENU); | 687 app_menu_->SetID(VIEW_ID_APP_MENU); |
660 | 688 |
661 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kBookmarkMenu)) { | 689 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kBookmarkMenu)) { |
662 bookmark_menu_ = new BookmarkMenuButton(browser_); | 690 bookmark_menu_ = new BookmarkMenuButton(browser_); |
663 AddChildView(bookmark_menu_); | 691 AddChildView(bookmark_menu_); |
664 } else { | 692 } else { |
665 bookmark_menu_ = NULL; | 693 bookmark_menu_ = NULL; |
666 } | 694 } |
667 | 695 |
| 696 // Catch the case where the window is created after we detect a new version. |
| 697 if (Singleton<UpgradeDetector>::get()->notify_upgrade()) |
| 698 ShowUpgradeReminder(); |
| 699 |
668 LoadRightSideControlsImages(); | 700 LoadRightSideControlsImages(); |
669 | 701 |
670 AddChildView(browser_actions_); | 702 AddChildView(browser_actions_); |
671 AddChildView(page_menu_); | 703 AddChildView(page_menu_); |
672 AddChildView(app_menu_); | 704 AddChildView(app_menu_); |
673 } | 705 } |
674 | 706 |
675 void ToolbarView::LoadLeftSideControlsImages() { | 707 void ToolbarView::LoadLeftSideControlsImages() { |
676 ThemeProvider* tp = GetThemeProvider(); | 708 ThemeProvider* tp = GetThemeProvider(); |
677 | 709 |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
727 go_->SetToggledImage(views::CustomButton::BS_NORMAL, | 759 go_->SetToggledImage(views::CustomButton::BS_NORMAL, |
728 tp->GetBitmapNamed(IDR_STOP)); | 760 tp->GetBitmapNamed(IDR_STOP)); |
729 go_->SetToggledImage(views::CustomButton::BS_HOT, | 761 go_->SetToggledImage(views::CustomButton::BS_HOT, |
730 tp->GetBitmapNamed(IDR_STOP_H)); | 762 tp->GetBitmapNamed(IDR_STOP_H)); |
731 go_->SetToggledImage(views::CustomButton::BS_PUSHED, | 763 go_->SetToggledImage(views::CustomButton::BS_PUSHED, |
732 tp->GetBitmapNamed(IDR_STOP_P)); | 764 tp->GetBitmapNamed(IDR_STOP_P)); |
733 go_->SetBackground(color, background, | 765 go_->SetBackground(color, background, |
734 tp->GetBitmapNamed(IDR_GO_MASK)); | 766 tp->GetBitmapNamed(IDR_GO_MASK)); |
735 } | 767 } |
736 | 768 |
| 769 void ToolbarView::ShowUpgradeReminder() { |
| 770 update_reminder_animation_.reset(new SlideAnimation(this)); |
| 771 update_reminder_animation_->SetSlideDuration(kPulseDuration); |
| 772 |
| 773 // Then start the recurring timer for pulsating it. |
| 774 upgrade_reminder_pulse_timer_.Start( |
| 775 base::TimeDelta::FromMilliseconds(kPulsateEveryMs), |
| 776 this, &ToolbarView::PulsateUpgradeNotifier); |
| 777 } |
| 778 |
| 779 void ToolbarView::PulsateUpgradeNotifier() { |
| 780 // Start the pulsating animation. |
| 781 update_reminder_animation_->Reset(0.0); |
| 782 update_reminder_animation_->Show(); |
| 783 } |
| 784 |
| 785 SkBitmap ToolbarView::GetAppMenuIcon() { |
| 786 ThemeProvider* tp = GetThemeProvider(); |
| 787 |
| 788 SkBitmap icon; |
| 789 |
| 790 // We use different menu button images if the locale is right-to-left. |
| 791 if (base::i18n::IsRTL()) |
| 792 icon = *tp->GetBitmapNamed(IDR_MENU_CHROME_RTL); |
| 793 else |
| 794 icon = *tp->GetBitmapNamed(IDR_MENU_CHROME); |
| 795 |
| 796 if (!Singleton<UpgradeDetector>::get()->notify_upgrade()) |
| 797 return icon; |
| 798 |
| 799 // Draw the chrome app menu icon onto the canvas. |
| 800 scoped_ptr<gfx::Canvas> canvas( |
| 801 new gfx::Canvas(icon.width(), icon.height(), false)); |
| 802 canvas->DrawBitmapInt(icon, 0, 0); |
| 803 |
| 804 SkBitmap badge; |
| 805 |
| 806 static bool has_faded_in = false; |
| 807 if (!has_faded_in) { |
| 808 SkBitmap* dot = tp->GetBitmapNamed(IDR_UPGRADE_DOT_INACTIVE); |
| 809 SkBitmap transparent; |
| 810 transparent.setConfig(dot->getConfig(), dot->width(), dot->height()); |
| 811 transparent.allocPixels(); |
| 812 transparent.eraseARGB(0, 0, 0, 0); |
| 813 badge = SkBitmapOperations::CreateBlendedBitmap( |
| 814 *dot, transparent, 1.0 - update_reminder_animation_->GetCurrentValue()); |
| 815 if (update_reminder_animation_->GetCurrentValue() == 1.0) |
| 816 has_faded_in = true; |
| 817 } else { |
| 818 // Convert animation values that start from 0.0 and incrementally go |
| 819 // up to 1.0 into values that start in 0.0, go to 1.0 and then back |
| 820 // to 0.0 (to create a pulsing effect). |
| 821 double value = 1.0 - |
| 822 abs(2.0 * update_reminder_animation_->GetCurrentValue() - |
| 823 1.0); |
| 824 |
| 825 // Add the badge to it. |
| 826 badge = SkBitmapOperations::CreateBlendedBitmap( |
| 827 *tp->GetBitmapNamed(IDR_UPGRADE_DOT_INACTIVE), |
| 828 *tp->GetBitmapNamed(IDR_UPGRADE_DOT_ACTIVE), |
| 829 value); |
| 830 } |
| 831 |
| 832 int x_pos = kUpgradeDotOffset; |
| 833 if (base::i18n::IsRTL()) |
| 834 x_pos = icon.width() - badge.width(); |
| 835 canvas->DrawBitmapInt(badge, x_pos, icon.height() - badge.height()); |
| 836 |
| 837 return canvas->ExtractBitmap(); |
| 838 } |
| 839 |
737 void ToolbarView::LoadRightSideControlsImages() { | 840 void ToolbarView::LoadRightSideControlsImages() { |
738 ThemeProvider* tp = GetThemeProvider(); | 841 ThemeProvider* tp = GetThemeProvider(); |
739 | 842 |
740 // We use different menu button images if the locale is right-to-left. | 843 // We use different menu button images if the locale is right-to-left. |
741 if (base::i18n::IsRTL()) | 844 if (base::i18n::IsRTL()) |
742 page_menu_->SetIcon(*tp->GetBitmapNamed(IDR_MENU_PAGE_RTL)); | 845 page_menu_->SetIcon(*tp->GetBitmapNamed(IDR_MENU_PAGE_RTL)); |
743 else | 846 else |
744 page_menu_->SetIcon(*tp->GetBitmapNamed(IDR_MENU_PAGE)); | 847 page_menu_->SetIcon(*tp->GetBitmapNamed(IDR_MENU_PAGE)); |
745 if (base::i18n::IsRTL()) | 848 |
746 app_menu_->SetIcon(*tp->GetBitmapNamed(IDR_MENU_CHROME_RTL)); | 849 app_menu_->SetIcon(GetAppMenuIcon()); |
747 else | |
748 app_menu_->SetIcon(*tp->GetBitmapNamed(IDR_MENU_CHROME)); | |
749 | 850 |
750 if (bookmark_menu_ != NULL) | 851 if (bookmark_menu_ != NULL) |
751 bookmark_menu_->SetIcon(*tp->GetBitmapNamed(IDR_MENU_BOOKMARK)); | 852 bookmark_menu_->SetIcon(*tp->GetBitmapNamed(IDR_MENU_BOOKMARK)); |
752 } | 853 } |
753 | 854 |
754 void ToolbarView::RunPageMenu(const gfx::Point& pt) { | 855 void ToolbarView::RunPageMenu(const gfx::Point& pt) { |
755 bool destroyed_flag = false; | 856 bool destroyed_flag = false; |
756 destroyed_flag_ = &destroyed_flag; | 857 destroyed_flag_ = &destroyed_flag; |
757 | 858 |
758 page_menu_model_.reset(new PageMenuModel(this, browser_)); | 859 page_menu_model_.reset(new PageMenuModel(this, browser_)); |
(...skipping 23 matching lines...) Expand all Loading... |
782 for (unsigned int i = 0; i < menu_listeners_.size(); i++) { | 883 for (unsigned int i = 0; i < menu_listeners_.size(); i++) { |
783 app_menu_menu_->AddMenuListener(menu_listeners_[i]); | 884 app_menu_menu_->AddMenuListener(menu_listeners_[i]); |
784 } | 885 } |
785 app_menu_menu_->RunMenuAt(pt, views::Menu2::ALIGN_TOPRIGHT); | 886 app_menu_menu_->RunMenuAt(pt, views::Menu2::ALIGN_TOPRIGHT); |
786 | 887 |
787 if (destroyed_flag) | 888 if (destroyed_flag) |
788 return; | 889 return; |
789 | 890 |
790 destroyed_flag_ = NULL; | 891 destroyed_flag_ = NULL; |
791 | 892 |
| 893 // Stop pulsating the upgrade reminder on the app menu, if active. |
| 894 upgrade_reminder_pulse_timer_.Stop(); |
| 895 |
792 for (unsigned int i = 0; i < menu_listeners_.size(); i++) { | 896 for (unsigned int i = 0; i < menu_listeners_.size(); i++) { |
793 app_menu_menu_->RemoveMenuListener(menu_listeners_[i]); | 897 app_menu_menu_->RemoveMenuListener(menu_listeners_[i]); |
794 } | 898 } |
795 SwitchToOtherMenuIfNeeded(app_menu_menu_.get(), page_menu_); | 899 SwitchToOtherMenuIfNeeded(app_menu_menu_.get(), page_menu_); |
796 } | 900 } |
797 | 901 |
798 void ToolbarView::SwitchToOtherMenuIfNeeded( | 902 void ToolbarView::SwitchToOtherMenuIfNeeded( |
799 views::Menu2* previous_menu, views::MenuButton* next_menu_button) { | 903 views::Menu2* previous_menu, views::MenuButton* next_menu_button) { |
800 // If the user tried to move to the right or left, switch from the | 904 // If the user tried to move to the right or left, switch from the |
801 // app menu to the page menu. Switching to the next menu is delayed | 905 // app menu to the page menu. Switching to the next menu is delayed |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
861 last_focused_view->RequestFocus(); | 965 last_focused_view->RequestFocus(); |
862 } else { | 966 } else { |
863 // Focus the location bar | 967 // Focus the location bar |
864 views::View* view = GetAncestorWithClassName(BrowserView::kViewClassName); | 968 views::View* view = GetAncestorWithClassName(BrowserView::kViewClassName); |
865 if (view) { | 969 if (view) { |
866 BrowserView* browser_view = static_cast<BrowserView*>(view); | 970 BrowserView* browser_view = static_cast<BrowserView*>(view); |
867 browser_view->SetFocusToLocationBar(false); | 971 browser_view->SetFocusToLocationBar(false); |
868 } | 972 } |
869 } | 973 } |
870 } | 974 } |
OLD | NEW |