diff options
author | finnur@chromium.org <finnur@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-05-26 20:11:54 +0000 |
---|---|---|
committer | finnur@chromium.org <finnur@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-05-26 20:11:54 +0000 |
commit | b1b7394fa3880dab9f9bd0cfc40ea8c614f0b49e (patch) | |
tree | d6e9f57d10714b67c4c7fbed0e874d4e337f406e /chrome/browser/views/toolbar_view.cc | |
parent | a8e4a8fa39604cd309e1e3d62cf9c552dcfe541d (diff) | |
download | chromium_src-b1b7394fa3880dab9f9bd0cfc40ea8c614f0b49e.zip chromium_src-b1b7394fa3880dab9f9bd0cfc40ea8c614f0b49e.tar.gz chromium_src-b1b7394fa3880dab9f9bd0cfc40ea8c614f0b49e.tar.bz2 |
Implement upgrade notifications.
When we detect that the installed version is newer than the version you are
running we show a little throbbing orange dot over the wrench menu.
If you open the wrench menu and close it again, the throbbing will stop.
However, if you look at the contents of the wrench menu you'll notice that
the About box menu item has been removed and in its place is a menu item
"Update Chrome Now" with a bright orange icon to draw your attention to it.
Clicking on the icon shows a dialog box asking whether you want to restart
Chrome. If you do, the browser restarts with your session restored
(even if you have Session Restore turned off).
Known issues:
- Currently this is Windows only. We'll have to port this to Linux and do
something differnet for Mac (which doesn't have the wrench menu).
- Showing an icon in front of Update Chrome causes the checkbox for the
bookmark bar menu to go away. Given that we will soon redesign the menus I'm
not going to spend much time trying to fix it.
BUG=27941
TEST=Wait for Chrome to be upgraded in the background, an orange dot should
appear over the wrench menu and if you select Update Chrome your session should
be retained.
Review URL: http://codereview.chromium.org/2225003
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@48318 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/views/toolbar_view.cc')
-rw-r--r-- | chrome/browser/views/toolbar_view.cc | 112 |
1 files changed, 108 insertions, 4 deletions
diff --git a/chrome/browser/views/toolbar_view.cc b/chrome/browser/views/toolbar_view.cc index cc00ba5..4d15f5c 100644 --- a/chrome/browser/views/toolbar_view.cc +++ b/chrome/browser/views/toolbar_view.cc @@ -13,6 +13,7 @@ #include "chrome/browser/browser_window.h" #include "chrome/browser/pref_service.h" #include "chrome/browser/profile.h" +#include "chrome/browser/upgrade_detector.h" #include "chrome/browser/view_ids.h" #include "chrome/browser/views/bookmark_menu_button.h" #include "chrome/browser/views/browser_actions_container.h" @@ -24,6 +25,7 @@ #include "gfx/canvas.h" #include "grit/chromium_strings.h" #include "grit/generated_resources.h" +#include "gfx/skbitmap_operations.h" #include "grit/theme_resources.h" #include "views/controls/button/button_dropdown.h" #include "views/focus/view_storage.h" @@ -36,6 +38,16 @@ static const int kControlVertOffset = 6; static const int kControlIndent = 3; static const int kStatusBubbleWidth = 480; +// The length of time to run the upgrade notification animation (the time it +// takes one pulse to run its course and go back to its original brightness). +static const int kPulseDuration = 2000; + +// How long to wait between pulsating the upgrade notifier. +static const int kPulsateEveryMs = 8000; + +// The offset in pixels of the upgrade dot on the app menu. +static const int kUpgradeDotOffset = 11; + // Separation between the location bar and the menus. static const int kMenuButtonOffset = 3; @@ -89,6 +101,12 @@ ToolbarView::ToolbarView(Browser* browser) kPopupBackgroundEdge = ResourceBundle::GetSharedInstance().GetBitmapNamed( IDR_LOCATIONBG_POPUPMODE_EDGE); } + + if (!Singleton<UpgradeDetector>::get()->notify_upgrade()) { + registrar_.Add(this, + NotificationType::UPGRADE_RECOMMENDED, + NotificationService::AllSources()); + } } ToolbarView::~ToolbarView() { @@ -280,6 +298,14 @@ void ToolbarView::OnInputInProgress(bool in_progress) { } //////////////////////////////////////////////////////////////////////////////// +// ToolbarView, AnimationDelegate implementation: + +void ToolbarView::AnimationProgressed(const Animation* animation) { + app_menu_->SetIcon(GetAppMenuIcon()); + SchedulePaint(); +} + +//////////////////////////////////////////////////////////////////////////////// // ToolbarView, CommandUpdater::CommandObserver implementation: void ToolbarView::EnabledStateChangedForCommand(int id, bool enabled) { @@ -340,6 +366,8 @@ void ToolbarView::Observe(NotificationType type, Layout(); SchedulePaint(); } + } else if (type == NotificationType::UPGRADE_RECOMMENDED) { + ShowUpgradeReminder(); } } @@ -665,6 +693,10 @@ void ToolbarView::CreateRightSideControls(Profile* profile) { bookmark_menu_ = NULL; } + // Catch the case where the window is created after we detect a new version. + if (Singleton<UpgradeDetector>::get()->notify_upgrade()) + ShowUpgradeReminder(); + LoadRightSideControlsImages(); AddChildView(browser_actions_); @@ -734,6 +766,77 @@ void ToolbarView::LoadCenterStackImages() { tp->GetBitmapNamed(IDR_GO_MASK)); } +void ToolbarView::ShowUpgradeReminder() { + update_reminder_animation_.reset(new SlideAnimation(this)); + update_reminder_animation_->SetSlideDuration(kPulseDuration); + + // Then start the recurring timer for pulsating it. + upgrade_reminder_pulse_timer_.Start( + base::TimeDelta::FromMilliseconds(kPulsateEveryMs), + this, &ToolbarView::PulsateUpgradeNotifier); +} + +void ToolbarView::PulsateUpgradeNotifier() { + // Start the pulsating animation. + update_reminder_animation_->Reset(0.0); + update_reminder_animation_->Show(); +} + +SkBitmap ToolbarView::GetAppMenuIcon() { + ThemeProvider* tp = GetThemeProvider(); + + SkBitmap icon; + + // We use different menu button images if the locale is right-to-left. + if (base::i18n::IsRTL()) + icon = *tp->GetBitmapNamed(IDR_MENU_CHROME_RTL); + else + icon = *tp->GetBitmapNamed(IDR_MENU_CHROME); + + if (!Singleton<UpgradeDetector>::get()->notify_upgrade()) + return icon; + + // Draw the chrome app menu icon onto the canvas. + scoped_ptr<gfx::Canvas> canvas( + new gfx::Canvas(icon.width(), icon.height(), false)); + canvas->DrawBitmapInt(icon, 0, 0); + + SkBitmap badge; + + static bool has_faded_in = false; + if (!has_faded_in) { + SkBitmap* dot = tp->GetBitmapNamed(IDR_UPGRADE_DOT_INACTIVE); + SkBitmap transparent; + transparent.setConfig(dot->getConfig(), dot->width(), dot->height()); + transparent.allocPixels(); + transparent.eraseARGB(0, 0, 0, 0); + badge = SkBitmapOperations::CreateBlendedBitmap( + *dot, transparent, 1.0 - update_reminder_animation_->GetCurrentValue()); + if (update_reminder_animation_->GetCurrentValue() == 1.0) + has_faded_in = true; + } else { + // Convert animation values that start from 0.0 and incrementally go + // up to 1.0 into values that start in 0.0, go to 1.0 and then back + // to 0.0 (to create a pulsing effect). + double value = 1.0 - + abs(2.0 * update_reminder_animation_->GetCurrentValue() - + 1.0); + + // Add the badge to it. + badge = SkBitmapOperations::CreateBlendedBitmap( + *tp->GetBitmapNamed(IDR_UPGRADE_DOT_INACTIVE), + *tp->GetBitmapNamed(IDR_UPGRADE_DOT_ACTIVE), + value); + } + + int x_pos = kUpgradeDotOffset; + if (base::i18n::IsRTL()) + x_pos = icon.width() - badge.width(); + canvas->DrawBitmapInt(badge, x_pos, icon.height() - badge.height()); + + return canvas->ExtractBitmap(); +} + void ToolbarView::LoadRightSideControlsImages() { ThemeProvider* tp = GetThemeProvider(); @@ -742,10 +845,8 @@ void ToolbarView::LoadRightSideControlsImages() { page_menu_->SetIcon(*tp->GetBitmapNamed(IDR_MENU_PAGE_RTL)); else page_menu_->SetIcon(*tp->GetBitmapNamed(IDR_MENU_PAGE)); - if (base::i18n::IsRTL()) - app_menu_->SetIcon(*tp->GetBitmapNamed(IDR_MENU_CHROME_RTL)); - else - app_menu_->SetIcon(*tp->GetBitmapNamed(IDR_MENU_CHROME)); + + app_menu_->SetIcon(GetAppMenuIcon()); if (bookmark_menu_ != NULL) bookmark_menu_->SetIcon(*tp->GetBitmapNamed(IDR_MENU_BOOKMARK)); @@ -789,6 +890,9 @@ void ToolbarView::RunAppMenu(const gfx::Point& pt) { destroyed_flag_ = NULL; + // Stop pulsating the upgrade reminder on the app menu, if active. + upgrade_reminder_pulse_timer_.Stop(); + for (unsigned int i = 0; i < menu_listeners_.size(); i++) { app_menu_menu_->RemoveMenuListener(menu_listeners_[i]); } |