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/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 "chrome/app/chrome_command_ids.h" | 9 #include "chrome/app/chrome_command_ids.h" |
| 10 #include "chrome/browser/accessibility/browser_accessibility_state.h" | 10 #include "chrome/browser/accessibility/browser_accessibility_state.h" |
| (...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 175 app_menu_ = new views::MenuButton(NULL, std::wstring(), this, false); | 175 app_menu_ = new views::MenuButton(NULL, std::wstring(), this, false); |
| 176 app_menu_->set_border(NULL); | 176 app_menu_->set_border(NULL); |
| 177 app_menu_->EnableCanvasFlippingForRTLUI(true); | 177 app_menu_->EnableCanvasFlippingForRTLUI(true); |
| 178 app_menu_->SetAccessibleName(l10n_util::GetString(IDS_ACCNAME_APP)); | 178 app_menu_->SetAccessibleName(l10n_util::GetString(IDS_ACCNAME_APP)); |
| 179 app_menu_->SetTooltipText(l10n_util::GetStringF(IDS_APPMENU_TOOLTIP, | 179 app_menu_->SetTooltipText(l10n_util::GetStringF(IDS_APPMENU_TOOLTIP, |
| 180 l10n_util::GetString(IDS_PRODUCT_NAME))); | 180 l10n_util::GetString(IDS_PRODUCT_NAME))); |
| 181 app_menu_->SetID(VIEW_ID_APP_MENU); | 181 app_menu_->SetID(VIEW_ID_APP_MENU); |
| 182 | 182 |
| 183 // Catch the case where the window is created after we detect a new version. | 183 // Catch the case where the window is created after we detect a new version. |
| 184 if (IsUpgradeRecommended() || ShouldShowIncompatibilityWarning()) | 184 if (IsUpgradeRecommended() || ShouldShowIncompatibilityWarning()) |
| 185 ShowNotificationDot(); | 185 UpdateAppMenuBadge(); |
| 186 | 186 |
| 187 LoadImages(); | 187 LoadImages(); |
| 188 | 188 |
| 189 // Always add children in order from left to right, for accessibility. | 189 // Always add children in order from left to right, for accessibility. |
| 190 AddChildView(back_); | 190 AddChildView(back_); |
| 191 AddChildView(forward_); | 191 AddChildView(forward_); |
| 192 AddChildView(reload_); | 192 AddChildView(reload_); |
| 193 AddChildView(home_); | 193 AddChildView(home_); |
| 194 AddChildView(location_bar_); | 194 AddChildView(location_bar_); |
| 195 AddChildView(browser_actions_); | 195 AddChildView(browser_actions_); |
| (...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 315 menu_listeners_[i]->OnMenuOpened(); | 315 menu_listeners_[i]->OnMenuOpened(); |
| 316 | 316 |
| 317 wrench_menu_->RunMenu(app_menu_); | 317 wrench_menu_->RunMenu(app_menu_); |
| 318 | 318 |
| 319 #if defined(OS_CHROMEOS) | 319 #if defined(OS_CHROMEOS) |
| 320 cleanup: | 320 cleanup: |
| 321 #endif | 321 #endif |
| 322 if (destroyed_flag) | 322 if (destroyed_flag) |
| 323 return; | 323 return; |
| 324 destroyed_flag_ = NULL; | 324 destroyed_flag_ = NULL; |
| 325 | |
| 326 // Stop pulsating the notification dot on the app menu (if active). | |
| 327 notification_dot_pulse_timer_.Stop(); | |
| 328 } | 325 } |
| 329 | 326 |
| 330 //////////////////////////////////////////////////////////////////////////////// | 327 //////////////////////////////////////////////////////////////////////////////// |
| 331 // ToolbarView, LocationBarView::Delegate implementation: | 328 // ToolbarView, LocationBarView::Delegate implementation: |
| 332 | 329 |
| 333 TabContents* ToolbarView::GetTabContents() { | 330 TabContents* ToolbarView::GetTabContents() { |
| 334 return browser_->GetSelectedTabContents(); | 331 return browser_->GetSelectedTabContents(); |
| 335 } | 332 } |
| 336 | 333 |
| 337 InstantController* ToolbarView::GetInstant() { | 334 InstantController* ToolbarView::GetInstant() { |
| 338 return browser_->instant(); | 335 return browser_->instant(); |
| 339 } | 336 } |
| 340 | 337 |
| 341 void ToolbarView::OnInputInProgress(bool in_progress) { | 338 void ToolbarView::OnInputInProgress(bool in_progress) { |
| 342 // The edit should make sure we're only notified when something changes. | 339 // The edit should make sure we're only notified when something changes. |
| 343 DCHECK(model_->input_in_progress() != in_progress); | 340 DCHECK(model_->input_in_progress() != in_progress); |
| 344 | 341 |
| 345 model_->set_input_in_progress(in_progress); | 342 model_->set_input_in_progress(in_progress); |
| 346 location_bar_->Update(NULL); | 343 location_bar_->Update(NULL); |
| 347 } | 344 } |
| 348 | 345 |
| 349 //////////////////////////////////////////////////////////////////////////////// | 346 //////////////////////////////////////////////////////////////////////////////// |
| 350 // ToolbarView, AnimationDelegate implementation: | |
| 351 | |
| 352 void ToolbarView::AnimationProgressed(const Animation* animation) { | |
| 353 app_menu_->SetIcon(GetAppMenuIcon(views::CustomButton::BS_NORMAL)); | |
| 354 app_menu_->SetHoverIcon(GetAppMenuIcon(views::CustomButton::BS_HOT)); | |
| 355 app_menu_->SetPushedIcon(GetAppMenuIcon(views::CustomButton::BS_PUSHED)); | |
| 356 SchedulePaint(); | |
| 357 } | |
| 358 | |
| 359 //////////////////////////////////////////////////////////////////////////////// | |
| 360 // ToolbarView, CommandUpdater::CommandObserver implementation: | 347 // ToolbarView, CommandUpdater::CommandObserver implementation: |
| 361 | 348 |
| 362 void ToolbarView::EnabledStateChangedForCommand(int id, bool enabled) { | 349 void ToolbarView::EnabledStateChangedForCommand(int id, bool enabled) { |
| 363 views::Button* button = NULL; | 350 views::Button* button = NULL; |
| 364 switch (id) { | 351 switch (id) { |
| 365 case IDC_BACK: | 352 case IDC_BACK: |
| 366 button = back_; | 353 button = back_; |
| 367 break; | 354 break; |
| 368 case IDC_FORWARD: | 355 case IDC_FORWARD: |
| 369 button = forward_; | 356 button = forward_; |
| (...skipping 30 matching lines...) Expand all Loading... | |
| 400 void ToolbarView::Observe(NotificationType type, | 387 void ToolbarView::Observe(NotificationType type, |
| 401 const NotificationSource& source, | 388 const NotificationSource& source, |
| 402 const NotificationDetails& details) { | 389 const NotificationDetails& details) { |
| 403 if (type == NotificationType::PREF_CHANGED) { | 390 if (type == NotificationType::PREF_CHANGED) { |
| 404 std::string* pref_name = Details<std::string>(details).ptr(); | 391 std::string* pref_name = Details<std::string>(details).ptr(); |
| 405 if (*pref_name == prefs::kShowHomeButton) { | 392 if (*pref_name == prefs::kShowHomeButton) { |
| 406 Layout(); | 393 Layout(); |
| 407 SchedulePaint(); | 394 SchedulePaint(); |
| 408 } | 395 } |
| 409 } else if (type == NotificationType::UPGRADE_RECOMMENDED) { | 396 } else if (type == NotificationType::UPGRADE_RECOMMENDED) { |
| 410 ShowNotificationDot(); | 397 UpdateAppMenuBadge(); |
| 411 } else if (type == NotificationType::MODULE_INCOMPATIBILITY_DETECTED) { | 398 } else if (type == NotificationType::MODULE_INCOMPATIBILITY_DETECTED) { |
| 412 bool confirmed_bad = *Details<bool>(details).ptr(); | 399 bool confirmed_bad = *Details<bool>(details).ptr(); |
| 413 if (confirmed_bad) | 400 if (confirmed_bad) |
| 414 ShowNotificationDot(); | 401 UpdateAppMenuBadge(); |
| 415 } | 402 } |
| 416 } | 403 } |
| 417 | 404 |
| 418 //////////////////////////////////////////////////////////////////////////////// | 405 //////////////////////////////////////////////////////////////////////////////// |
| 419 // ToolbarView, menus::AcceleratorProvider implementation: | 406 // ToolbarView, menus::AcceleratorProvider implementation: |
| 420 | 407 |
| 421 bool ToolbarView::GetAcceleratorForCommandId(int command_id, | 408 bool ToolbarView::GetAcceleratorForCommandId(int command_id, |
| 422 menus::Accelerator* accelerator) { | 409 menus::Accelerator* accelerator) { |
| 423 // The standard Ctrl-X, Ctrl-V and Ctrl-C are not defined as accelerators | 410 // The standard Ctrl-X, Ctrl-V and Ctrl-C are not defined as accelerators |
| 424 // anywhere so we need to check for them explicitly here. | 411 // anywhere so we need to check for them explicitly here. |
| (...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 641 home_->SetImage(views::CustomButton::BS_NORMAL, tp->GetBitmapNamed(IDR_HOME)); | 628 home_->SetImage(views::CustomButton::BS_NORMAL, tp->GetBitmapNamed(IDR_HOME)); |
| 642 home_->SetImage(views::CustomButton::BS_HOT, tp->GetBitmapNamed(IDR_HOME_H)); | 629 home_->SetImage(views::CustomButton::BS_HOT, tp->GetBitmapNamed(IDR_HOME_H)); |
| 643 home_->SetImage(views::CustomButton::BS_PUSHED, | 630 home_->SetImage(views::CustomButton::BS_PUSHED, |
| 644 tp->GetBitmapNamed(IDR_HOME_P)); | 631 tp->GetBitmapNamed(IDR_HOME_P)); |
| 645 | 632 |
| 646 app_menu_->SetIcon(GetAppMenuIcon(views::CustomButton::BS_NORMAL)); | 633 app_menu_->SetIcon(GetAppMenuIcon(views::CustomButton::BS_NORMAL)); |
| 647 app_menu_->SetHoverIcon(GetAppMenuIcon(views::CustomButton::BS_HOT)); | 634 app_menu_->SetHoverIcon(GetAppMenuIcon(views::CustomButton::BS_HOT)); |
| 648 app_menu_->SetPushedIcon(GetAppMenuIcon(views::CustomButton::BS_PUSHED)); | 635 app_menu_->SetPushedIcon(GetAppMenuIcon(views::CustomButton::BS_PUSHED)); |
| 649 } | 636 } |
| 650 | 637 |
| 651 void ToolbarView::ShowNotificationDot() { | 638 void ToolbarView::UpdateAppMenuBadge() { |
| 652 notification_dot_animation_.reset(new SlideAnimation(this)); | 639 app_menu_->SetIcon(GetAppMenuIcon(views::CustomButton::BS_NORMAL)); |
| 653 notification_dot_animation_->SetSlideDuration(kPulseDuration); | 640 app_menu_->SetHoverIcon(GetAppMenuIcon(views::CustomButton::BS_HOT)); |
| 654 | 641 app_menu_->SetPushedIcon(GetAppMenuIcon(views::CustomButton::BS_PUSHED)); |
| 655 // Then start the recurring timer for pulsating it. | 642 SchedulePaint(); |
| 656 notification_dot_pulse_timer_.Stop(); | |
| 657 notification_dot_pulse_timer_.Start( | |
| 658 base::TimeDelta::FromMilliseconds(kPulsateEveryMs), | |
| 659 this, &ToolbarView::PulsateNotificationDot); | |
| 660 } | |
| 661 | |
| 662 void ToolbarView::PulsateNotificationDot() { | |
| 663 // Start the pulsating animation. | |
| 664 notification_dot_animation_->Reset(0.0); | |
| 665 notification_dot_animation_->Show(); | |
| 666 } | 643 } |
| 667 | 644 |
| 668 SkBitmap ToolbarView::GetAppMenuIcon(views::CustomButton::ButtonState state) { | 645 SkBitmap ToolbarView::GetAppMenuIcon(views::CustomButton::ButtonState state) { |
| 669 ThemeProvider* tp = GetThemeProvider(); | 646 ThemeProvider* tp = GetThemeProvider(); |
| 670 | 647 |
| 671 int id = 0; | 648 int id = 0; |
| 672 switch (state) { | 649 switch (state) { |
| 673 case views::CustomButton::BS_NORMAL: id = IDR_TOOLS; break; | 650 case views::CustomButton::BS_NORMAL: id = IDR_TOOLS; break; |
| 674 case views::CustomButton::BS_HOT: id = IDR_TOOLS_H; break; | 651 case views::CustomButton::BS_HOT: id = IDR_TOOLS_H; break; |
| 675 case views::CustomButton::BS_PUSHED: id = IDR_TOOLS_P; break; | 652 case views::CustomButton::BS_PUSHED: id = IDR_TOOLS_P; break; |
| 676 default: NOTREACHED(); break; | 653 default: NOTREACHED(); break; |
| 677 } | 654 } |
| 678 SkBitmap icon = *tp->GetBitmapNamed(id); | 655 SkBitmap icon = *tp->GetBitmapNamed(id); |
| 679 | 656 |
| 680 bool add_badge = IsUpgradeRecommended() || ShouldShowIncompatibilityWarning(); | 657 bool add_badge = IsUpgradeRecommended() || ShouldShowIncompatibilityWarning(); |
| 681 if (!add_badge) | 658 if (!add_badge) |
| 682 return icon; | 659 return icon; |
| 683 | 660 |
| 684 // Draw the chrome app menu icon onto the canvas. | 661 // Draw the chrome app menu icon onto the canvas. |
| 685 scoped_ptr<gfx::CanvasSkia> canvas( | 662 scoped_ptr<gfx::CanvasSkia> canvas( |
| 686 new gfx::CanvasSkia(icon.width(), icon.height(), false)); | 663 new gfx::CanvasSkia(icon.width(), icon.height(), false)); |
| 687 canvas->DrawBitmapInt(icon, 0, 0); | 664 canvas->DrawBitmapInt(icon, 0, 0); |
| 688 | 665 |
| 689 SkBitmap badge; | 666 SkBitmap* badge = NULL; |
| 690 static bool has_faded_in = false; | 667 // Only one badge can be active at any given time. The Upgrade notification |
| 691 if (!has_faded_in) { | 668 // is deemed most important, then the DLL conflict badge. |
| 692 SkBitmap* dot = NULL; | 669 if (IsUpgradeRecommended()) { |
| 693 if (ShouldShowIncompatibilityWarning()) { | 670 badge = tp->GetBitmapNamed(IDR_UPDATE_BADGE); |
| 671 } else if (ShouldShowIncompatibilityWarning()) { | |
| 694 #if defined(OS_WIN) | 672 #if defined(OS_WIN) |
| 695 dot = tp->GetBitmapNamed(IDR_INCOMPATIBILITY_DOT_INACTIVE); | 673 badge = tp->GetBitmapNamed(IDR_CONFLICT_BADGE); |
| 696 #else | 674 #else |
| 697 NOTREACHED(); | 675 NOTREACHED(); |
| 698 #endif | 676 #endif |
| 699 } else { | |
| 700 dot = tp->GetBitmapNamed(IDR_UPGRADE_DOT_INACTIVE); | |
| 701 } | |
| 702 SkBitmap transparent; | |
| 703 transparent.setConfig(dot->getConfig(), dot->width(), dot->height()); | |
| 704 transparent.allocPixels(); | |
| 705 transparent.eraseARGB(0, 0, 0, 0); | |
| 706 badge = SkBitmapOperations::CreateBlendedBitmap( | |
| 707 *dot, transparent, | |
| 708 1.0 - notification_dot_animation_->GetCurrentValue()); | |
| 709 if (notification_dot_animation_->GetCurrentValue() == 1.0) | |
| 710 has_faded_in = true; | |
| 711 } else { | 677 } else { |
| 712 // Convert animation values that start from 0.0 and incrementally go | 678 NOTREACHED(); |
| 713 // up to 1.0 into values that start in 0.0, go to 1.0 and then back | |
| 714 // to 0.0 (to create a pulsing effect). | |
| 715 double value = | |
| 716 1.0 - abs(2.0 * notification_dot_animation_->GetCurrentValue() - 1.0); | |
| 717 | |
| 718 // Add the badge to it. | |
| 719 if (ShouldShowIncompatibilityWarning()) { | |
| 720 #if defined(OS_WIN) | |
| 721 badge = SkBitmapOperations::CreateBlendedBitmap( | |
| 722 *tp->GetBitmapNamed(IDR_INCOMPATIBILITY_DOT_INACTIVE), | |
| 723 *tp->GetBitmapNamed(IDR_INCOMPATIBILITY_DOT_ACTIVE), | |
| 724 value); | |
| 725 #else | |
| 726 NOTREACHED(); | |
| 727 #endif | |
| 728 } else { | |
| 729 badge = SkBitmapOperations::CreateBlendedBitmap( | |
| 730 *tp->GetBitmapNamed(IDR_UPGRADE_DOT_INACTIVE), | |
| 731 *tp->GetBitmapNamed(IDR_UPGRADE_DOT_ACTIVE), | |
| 732 value); | |
| 733 } | |
| 734 } | 679 } |
| 735 | 680 |
| 736 static const int kBadgeLeftSpacing = 8; | 681 static const int kBadgeRightMargin = 2; |
| 737 static const int kBadgeTopSpacing = 18; | 682 static const int kBadgeTopMargin = 2; |
| 738 canvas->DrawBitmapInt(badge, kBadgeLeftSpacing, kBadgeTopSpacing); | 683 canvas->DrawBitmapInt(*badge, |
| 684 icon.width() - badge->width() - kBadgeRightMargin, | |
| 685 0 + kBadgeTopMargin); | |
|
Andrew T Wilson (Slow)
2010/11/17 03:31:32
This is a nice refactoring - the code is much clea
Finnur
2010/11/17 09:18:51
Yes, that I'm an idiot. :)
| |
| 739 | 686 |
| 740 return canvas->ExtractBitmap(); | 687 return canvas->ExtractBitmap(); |
| 741 } | 688 } |
| OLD | NEW |