Chromium Code Reviews| OLD | NEW |
|---|---|
| 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/views/tabs/tab.h" | 5 #include "chrome/browser/ui/views/tabs/tab.h" |
| 6 | 6 |
| 7 #include <limits> | 7 #include <limits> |
| 8 | 8 |
| 9 #include "base/command_line.h" | 9 #include "base/command_line.h" |
| 10 #include "base/debug/alias.h" | 10 #include "base/debug/alias.h" |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 31 #include "ui/base/resource/resource_bundle.h" | 31 #include "ui/base/resource/resource_bundle.h" |
| 32 #include "ui/base/theme_provider.h" | 32 #include "ui/base/theme_provider.h" |
| 33 #include "ui/gfx/animation/animation_container.h" | 33 #include "ui/gfx/animation/animation_container.h" |
| 34 #include "ui/gfx/animation/multi_animation.h" | 34 #include "ui/gfx/animation/multi_animation.h" |
| 35 #include "ui/gfx/animation/throb_animation.h" | 35 #include "ui/gfx/animation/throb_animation.h" |
| 36 #include "ui/gfx/canvas.h" | 36 #include "ui/gfx/canvas.h" |
| 37 #include "ui/gfx/color_analysis.h" | 37 #include "ui/gfx/color_analysis.h" |
| 38 #include "ui/gfx/favicon_size.h" | 38 #include "ui/gfx/favicon_size.h" |
| 39 #include "ui/gfx/geometry/rect_conversions.h" | 39 #include "ui/gfx/geometry/rect_conversions.h" |
| 40 #include "ui/gfx/image/image_skia_operations.h" | 40 #include "ui/gfx/image/image_skia_operations.h" |
| 41 #include "ui/gfx/paint_vector_icon.h" | |
| 41 #include "ui/gfx/path.h" | 42 #include "ui/gfx/path.h" |
| 42 #include "ui/gfx/skia_util.h" | 43 #include "ui/gfx/skia_util.h" |
| 44 #include "ui/gfx/vector_icons_public.h" | |
| 43 #include "ui/resources/grit/ui_resources.h" | 45 #include "ui/resources/grit/ui_resources.h" |
| 44 #include "ui/views/border.h" | 46 #include "ui/views/border.h" |
| 45 #include "ui/views/controls/button/image_button.h" | 47 #include "ui/views/controls/button/image_button.h" |
| 46 #include "ui/views/controls/label.h" | 48 #include "ui/views/controls/label.h" |
| 47 #include "ui/views/rect_based_targeting_utils.h" | 49 #include "ui/views/rect_based_targeting_utils.h" |
| 48 #include "ui/views/view_targeter.h" | 50 #include "ui/views/view_targeter.h" |
| 49 #include "ui/views/widget/tooltip_manager.h" | 51 #include "ui/views/widget/tooltip_manager.h" |
| 50 #include "ui/views/widget/widget.h" | 52 #include "ui/views/widget/widget.h" |
| 51 #include "ui/views/window/non_client_view.h" | 53 #include "ui/views/window/non_client_view.h" |
| 52 | 54 |
| 53 #if defined(USE_AURA) | 55 #if defined(USE_AURA) |
| 54 #include "ui/aura/env.h" | 56 #include "ui/aura/env.h" |
| 55 #endif | 57 #endif |
| 56 | 58 |
| 57 using base::UserMetricsAction; | 59 using base::UserMetricsAction; |
| 58 | 60 |
| 59 namespace { | 61 namespace { |
| 60 | 62 |
| 61 // Height of the shadow at the top of the tab image assets. | 63 // Height of the shadow at the top of the tab image assets. |
| 62 const int kDropShadowHeight = 4; | 64 const int kDropShadowHeight = 4; |
| 63 | 65 |
| 64 // How long the pulse throb takes. | 66 // How long the pulse throb takes. |
| 65 const int kPulseDurationMs = 200; | 67 const int kPulseDurationMs = 200; |
| 66 | 68 |
| 67 // Width of touch tabs. | 69 // Width of touch tabs. |
| 68 const int kTouchWidth = 120; | 70 const int kTouchWidth = 120; |
| 69 | 71 |
| 70 const int kToolbarOverlap = 1; | 72 const int kToolbarOverlap = 1; |
| 71 const int kExtraLeftPaddingToBalanceCloseButtonPadding = 2; | 73 const int kExtraLeftPaddingToBalanceCloseButtonPadding = 2; |
| 72 const int kAfterTitleSpacing = 3; | 74 const int kAfterTitleSpacing = 4; |
| 73 | 75 |
| 74 // When a non-pinned tab becomes a pinned tab the width of the tab animates. If | 76 // When a non-pinned tab becomes a pinned tab the width of the tab animates. If |
| 75 // the width of a pinned tab is at least kPinnedTabExtraWidthToRenderAsNormal | 77 // the width of a pinned tab is at least kPinnedTabExtraWidthToRenderAsNormal |
| 76 // larger than the desired pinned tab width then the tab is rendered as a normal | 78 // larger than the desired pinned tab width then the tab is rendered as a normal |
| 77 // tab. This is done to avoid having the title immediately disappear when | 79 // tab. This is done to avoid having the title immediately disappear when |
| 78 // transitioning a tab from normal to pinned tab. | 80 // transitioning a tab from normal to pinned tab. |
| 79 const int kPinnedTabExtraWidthToRenderAsNormal = 30; | 81 const int kPinnedTabExtraWidthToRenderAsNormal = 30; |
| 80 | 82 |
| 81 // How opaque to make the hover state (out of 1). | 83 // How opaque to make the hover state (out of 1). |
| 82 const double kHoverOpacity = 0.33; | 84 const double kHoverOpacity = 0.33; |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 126 const SkColor kImmersiveInactiveTabColor = SkColorSetRGB(190, 190, 190); | 128 const SkColor kImmersiveInactiveTabColor = SkColorSetRGB(190, 190, 190); |
| 127 | 129 |
| 128 // The minimum opacity (out of 1) when a tab (either active or inactive) is | 130 // The minimum opacity (out of 1) when a tab (either active or inactive) is |
| 129 // throbbing in the immersive mode light strip. | 131 // throbbing in the immersive mode light strip. |
| 130 const double kImmersiveTabMinThrobOpacity = 0.66; | 132 const double kImmersiveTabMinThrobOpacity = 0.66; |
| 131 | 133 |
| 132 // Number of steps in the immersive mode loading animation. | 134 // Number of steps in the immersive mode loading animation. |
| 133 const int kImmersiveLoadingStepCount = 32; | 135 const int kImmersiveLoadingStepCount = 32; |
| 134 | 136 |
| 135 const char kTabCloseButtonName[] = "TabCloseButton"; | 137 const char kTabCloseButtonName[] = "TabCloseButton"; |
| 138 const int kTabCloseButtonSize = 16; | |
| 136 | 139 |
| 137 void DrawIconAtLocation(gfx::Canvas* canvas, | 140 void DrawIconAtLocation(gfx::Canvas* canvas, |
| 138 const gfx::ImageSkia& image, | 141 const gfx::ImageSkia& image, |
| 139 int image_offset, | 142 int image_offset, |
| 140 int dst_x, | 143 int dst_x, |
| 141 int dst_y, | 144 int dst_y, |
| 142 int icon_width, | 145 int icon_width, |
| 143 int icon_height, | 146 int icon_height, |
| 144 bool filter, | 147 bool filter, |
| 145 const SkPaint& paint) { | 148 const SkPaint& paint) { |
| (...skipping 256 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 402 // Tab, public: | 405 // Tab, public: |
| 403 | 406 |
| 404 Tab::Tab(TabController* controller) | 407 Tab::Tab(TabController* controller) |
| 405 : controller_(controller), | 408 : controller_(controller), |
| 406 closing_(false), | 409 closing_(false), |
| 407 dragging_(false), | 410 dragging_(false), |
| 408 detached_(false), | 411 detached_(false), |
| 409 favicon_hiding_offset_(0), | 412 favicon_hiding_offset_(0), |
| 410 immersive_loading_step_(0), | 413 immersive_loading_step_(0), |
| 411 should_display_crashed_favicon_(false), | 414 should_display_crashed_favicon_(false), |
| 412 close_button_(NULL), | 415 media_indicator_button_(nullptr), |
| 413 media_indicator_button_(NULL), | 416 close_button_(nullptr), |
| 414 title_(new views::Label()), | 417 title_(new views::Label()), |
| 415 tab_activated_with_last_tap_down_(false), | 418 tab_activated_with_last_tap_down_(false), |
| 416 hover_controller_(this), | 419 hover_controller_(this), |
| 417 showing_icon_(false), | 420 showing_icon_(false), |
| 418 showing_media_indicator_(false), | 421 showing_media_indicator_(false), |
| 419 showing_close_button_(false), | 422 showing_close_button_(false), |
| 420 close_button_color_(0) { | 423 button_color_(SK_ColorTRANSPARENT) { |
| 421 DCHECK(controller); | 424 DCHECK(controller); |
| 422 InitTabResources(); | 425 InitTabResources(); |
| 423 | 426 |
| 424 // So we get don't get enter/exit on children and don't prematurely stop the | 427 // So we get don't get enter/exit on children and don't prematurely stop the |
| 425 // hover. | 428 // hover. |
| 426 set_notify_enter_exit_on_child(true); | 429 set_notify_enter_exit_on_child(true); |
| 427 | 430 |
| 428 set_id(VIEW_ID_TAB); | 431 set_id(VIEW_ID_TAB); |
| 429 | 432 |
| 430 title_->SetHorizontalAlignment(gfx::ALIGN_TO_HEAD); | 433 title_->SetHorizontalAlignment(gfx::ALIGN_TO_HEAD); |
| 431 title_->SetElideBehavior(gfx::FADE_TAIL); | 434 title_->SetElideBehavior(gfx::FADE_TAIL); |
| 432 title_->SetHandlesTooltips(false); | 435 title_->SetHandlesTooltips(false); |
| 433 title_->SetAutoColorReadabilityEnabled(false); | 436 title_->SetAutoColorReadabilityEnabled(false); |
| 434 title_->SetText(CoreTabHelper::GetDefaultTitle()); | 437 title_->SetText(CoreTabHelper::GetDefaultTitle()); |
| 435 AddChildView(title_); | 438 AddChildView(title_); |
| 436 | 439 |
| 437 SetEventTargeter( | 440 SetEventTargeter( |
| 438 scoped_ptr<views::ViewTargeter>(new views::ViewTargeter(this))); | 441 scoped_ptr<views::ViewTargeter>(new views::ViewTargeter(this))); |
| 439 | 442 |
| 440 // Add the Close Button. | 443 media_indicator_button_ = new MediaIndicatorButton(this); |
| 444 AddChildView(media_indicator_button_); | |
| 445 | |
| 441 close_button_ = new TabCloseButton(this); | 446 close_button_ = new TabCloseButton(this); |
| 442 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); | |
| 443 close_button_->SetImage(views::CustomButton::STATE_NORMAL, | |
| 444 rb.GetImageSkiaNamed(IDR_CLOSE_1)); | |
| 445 close_button_->SetImage(views::CustomButton::STATE_HOVERED, | |
| 446 rb.GetImageSkiaNamed(IDR_CLOSE_1_H)); | |
| 447 close_button_->SetImage(views::CustomButton::STATE_PRESSED, | |
| 448 rb.GetImageSkiaNamed(IDR_CLOSE_1_P)); | |
| 449 close_button_->SetAccessibleName( | 447 close_button_->SetAccessibleName( |
| 450 l10n_util::GetStringUTF16(IDS_ACCNAME_CLOSE)); | 448 l10n_util::GetStringUTF16(IDS_ACCNAME_CLOSE)); |
| 449 // The normal image is set by OnButtonColorMaybeChanged() because it depends | |
| 450 // on the current theme and active state. The hovered and pressed images | |
| 451 // don't depend on the these, so we can set them here. | |
| 452 const gfx::ImageSkia& hovered = gfx::CreateVectorIcon( | |
| 453 gfx::VectorIconId::TAB_CLOSE_HOVERED_PRESSED, kTabCloseButtonSize, | |
| 454 SkColorSetARGB(0xFF, 0xDB, 0x44, 0x37)); | |
| 455 const gfx::ImageSkia& pressed = gfx::CreateVectorIcon( | |
| 456 gfx::VectorIconId::TAB_CLOSE_HOVERED_PRESSED, kTabCloseButtonSize, | |
| 457 SkColorSetARGB(0xFF, 0xA8, 0x35, 0x2A)); | |
| 458 close_button_->SetImage(views::CustomButton::STATE_HOVERED, &hovered); | |
| 459 close_button_->SetImage(views::CustomButton::STATE_PRESSED, &pressed); | |
| 460 | |
| 451 // Disable animation so that the red danger sign shows up immediately | 461 // Disable animation so that the red danger sign shows up immediately |
| 452 // to help avoid mis-clicks. | 462 // to help avoid mis-clicks. |
| 453 close_button_->SetAnimationDuration(0); | 463 close_button_->SetAnimationDuration(0); |
| 454 AddChildView(close_button_); | 464 AddChildView(close_button_); |
| 455 | 465 |
| 456 set_context_menu_controller(this); | 466 set_context_menu_controller(this); |
| 457 } | 467 } |
| 458 | 468 |
| 459 Tab::~Tab() { | 469 Tab::~Tab() { |
| 460 } | 470 } |
| 461 | 471 |
| 462 void Tab::set_animation_container(gfx::AnimationContainer* container) { | 472 void Tab::SetAnimationContainer(gfx::AnimationContainer* container) { |
| 463 animation_container_ = container; | 473 animation_container_ = container; |
| 464 hover_controller_.SetAnimationContainer(container); | 474 hover_controller_.SetAnimationContainer(container); |
| 465 } | 475 } |
| 466 | 476 |
| 467 bool Tab::IsActive() const { | 477 bool Tab::IsActive() const { |
| 468 return controller_->IsActiveTab(this); | 478 return controller_->IsActiveTab(this); |
| 469 } | 479 } |
| 470 | 480 |
| 471 void Tab::ActiveStateChanged() { | 481 void Tab::ActiveStateChanged() { |
| 472 GetMediaIndicatorButton()->UpdateEnabledForMuteToggle(); | 482 OnButtonColorMaybeChanged(); |
| 483 media_indicator_button_->UpdateEnabledForMuteToggle(); | |
| 473 } | 484 } |
| 474 | 485 |
| 475 bool Tab::IsSelected() const { | 486 bool Tab::IsSelected() const { |
| 476 return controller_->IsTabSelected(this); | 487 return controller_->IsTabSelected(this); |
| 477 } | 488 } |
| 478 | 489 |
| 479 void Tab::SetData(const TabRendererData& data) { | 490 void Tab::SetData(const TabRendererData& data) { |
| 480 DCHECK(GetWidget()); | 491 DCHECK(GetWidget()); |
| 481 | 492 |
| 482 if (data_.Equals(data)) | 493 if (data_.Equals(data)) |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 514 StartCrashAnimation(); | 525 StartCrashAnimation(); |
| 515 #endif | 526 #endif |
| 516 } | 527 } |
| 517 } else { | 528 } else { |
| 518 if (IsPerformingCrashAnimation()) | 529 if (IsPerformingCrashAnimation()) |
| 519 StopCrashAnimation(); | 530 StopCrashAnimation(); |
| 520 ResetCrashedFavicon(); | 531 ResetCrashedFavicon(); |
| 521 } | 532 } |
| 522 | 533 |
| 523 if (data_.media_state != old.media_state) | 534 if (data_.media_state != old.media_state) |
| 524 GetMediaIndicatorButton()->TransitionToMediaState(data_.media_state); | 535 media_indicator_button_->TransitionToMediaState(data_.media_state); |
| 525 | 536 |
| 526 if (old.pinned != data_.pinned) { | 537 if (old.pinned != data_.pinned) { |
| 527 StopAndDeleteAnimation(pinned_title_change_animation_.Pass()); | 538 StopAndDeleteAnimation(pinned_title_change_animation_.Pass()); |
| 528 } | 539 } |
| 529 | 540 |
| 530 DataChanged(old); | 541 DataChanged(old); |
| 531 | 542 |
| 532 Layout(); | 543 Layout(); |
| 533 SchedulePaint(); | 544 SchedulePaint(); |
| 534 } | 545 } |
| (...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 720 if (!intersection.intersect(RectToSkRect(clip))) | 731 if (!intersection.intersect(RectToSkRect(clip))) |
| 721 return false; | 732 return false; |
| 722 mask->addRect(intersection); | 733 mask->addRect(intersection); |
| 723 } | 734 } |
| 724 return true; | 735 return true; |
| 725 } | 736 } |
| 726 | 737 |
| 727 //////////////////////////////////////////////////////////////////////////////// | 738 //////////////////////////////////////////////////////////////////////////////// |
| 728 // Tab, views::View overrides: | 739 // Tab, views::View overrides: |
| 729 | 740 |
| 741 void Tab::ViewHierarchyChanged(const ViewHierarchyChangedDetails& details) { | |
| 742 // If this hierarchy changed has resulted in us being part of a widget | |
| 743 // hierarchy for the first time, we can now get at the theme provider, and | |
| 744 // should recalculate the button color. | |
| 745 if (details.is_add) | |
| 746 OnButtonColorMaybeChanged(); | |
| 747 } | |
| 748 | |
| 730 void Tab::OnPaint(gfx::Canvas* canvas) { | 749 void Tab::OnPaint(gfx::Canvas* canvas) { |
| 731 // Don't paint if we're narrower than we can render correctly. (This should | 750 // Don't paint if we're narrower than we can render correctly. (This should |
| 732 // only happen during animations). | 751 // only happen during animations). |
| 733 if (width() < GetMinimumUnselectedSize().width() && !data().pinned) | 752 if (width() < GetMinimumUnselectedSize().width() && !data().pinned) |
| 734 return; | 753 return; |
| 735 | 754 |
| 736 gfx::Rect clip; | 755 gfx::Rect clip; |
| 737 if (!controller_->ShouldPaintTab(this, &clip)) | 756 if (!controller_->ShouldPaintTab(this, &clip)) |
| 738 return; | 757 return; |
| 739 if (!clip.IsEmpty()) { | 758 if (!clip.IsEmpty()) { |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 790 const int bottom = height() - close_button_size.height() - top; | 809 const int bottom = height() - close_button_size.height() - top; |
| 791 const int right = width() - close_button_end; | 810 const int right = width() - close_button_end; |
| 792 close_button_->SetBorder( | 811 close_button_->SetBorder( |
| 793 views::Border::CreateEmptyBorder(top, left, bottom, right)); | 812 views::Border::CreateEmptyBorder(top, left, bottom, right)); |
| 794 close_button_->SizeToPreferredSize(); | 813 close_button_->SizeToPreferredSize(); |
| 795 } | 814 } |
| 796 close_button_->SetVisible(showing_close_button_); | 815 close_button_->SetVisible(showing_close_button_); |
| 797 | 816 |
| 798 showing_media_indicator_ = ShouldShowMediaIndicator(); | 817 showing_media_indicator_ = ShouldShowMediaIndicator(); |
| 799 if (showing_media_indicator_) { | 818 if (showing_media_indicator_) { |
| 800 views::ImageButton* const button = GetMediaIndicatorButton(); | 819 const gfx::Size image_size(media_indicator_button_->GetPreferredSize()); |
| 801 const gfx::Size image_size(button->GetPreferredSize()); | |
| 802 const int right = showing_close_button_ ? | 820 const int right = showing_close_button_ ? |
| 803 close_button_->x() + close_button_->GetInsets().left() : lb.right(); | 821 close_button_->x() + close_button_->GetInsets().left() : lb.right(); |
| 804 gfx::Rect bounds( | 822 gfx::Rect bounds( |
| 805 std::max(lb.x(), right - image_size.width()), | 823 std::max(lb.x(), right - image_size.width()), |
| 806 lb.y() + (lb.height() - image_size.height() + 1) / 2, | 824 lb.y() + (lb.height() - image_size.height() + 1) / 2, |
| 807 image_size.width(), | 825 image_size.width(), |
| 808 image_size.height()); | 826 image_size.height()); |
| 809 MaybeAdjustLeftForPinnedTab(&bounds); | 827 MaybeAdjustLeftForPinnedTab(&bounds); |
| 810 button->SetBoundsRect(bounds); | 828 media_indicator_button_->SetBoundsRect(bounds); |
| 811 button->SetVisible(true); | |
| 812 } else if (media_indicator_button_) { | |
| 813 media_indicator_button_->SetVisible(false); | |
| 814 } | 829 } |
| 830 media_indicator_button_->SetVisible(showing_media_indicator_); | |
| 815 | 831 |
| 816 // Size the title to fill the remaining width and use all available height. | 832 // Size the title to fill the remaining width and use all available height. |
| 817 const bool show_title = ShouldRenderAsNormalTab(); | 833 const bool show_title = ShouldRenderAsNormalTab(); |
| 818 if (show_title) { | 834 if (show_title) { |
| 819 const int title_spacing = GetLayoutConstant(TAB_FAVICON_TITLE_SPACING); | 835 const int title_spacing = GetLayoutConstant(TAB_FAVICON_TITLE_SPACING); |
| 820 int title_left = showing_icon_ ? | 836 int title_left = showing_icon_ ? |
| 821 (favicon_bounds_.right() + title_spacing) : start; | 837 (favicon_bounds_.right() + title_spacing) : start; |
| 822 int title_width = lb.right() - title_left; | 838 int title_width = lb.right() - title_left; |
| 823 if (showing_media_indicator_) { | 839 if (showing_media_indicator_) { |
| 824 title_width = | 840 title_width = |
| 825 media_indicator_button_->x() - kAfterTitleSpacing - title_left; | 841 media_indicator_button_->x() - kAfterTitleSpacing - title_left; |
| 826 } else if (close_button_->visible()) { | 842 } else if (close_button_->visible()) { |
| 827 // Allow the title to overlay the close button's empty border padding. | 843 // Allow the title to overlay the close button's empty border padding. |
| 828 title_width = close_button_->x() + close_button_->GetInsets().left() - | 844 title_width = close_button_->x() + close_button_->GetInsets().left() - |
| 829 kAfterTitleSpacing - title_left; | 845 kAfterTitleSpacing - title_left; |
| 830 } | 846 } |
| 831 gfx::Rect rect(title_left, lb.y(), std::max(title_width, 0), lb.height()); | 847 gfx::Rect rect(title_left, lb.y(), std::max(title_width, 0), lb.height()); |
| 832 const int title_height = title_->GetPreferredSize().height(); | 848 const int title_height = title_->GetPreferredSize().height(); |
| 833 if (title_height > rect.height()) { | 849 if (title_height > rect.height()) { |
| 834 rect.set_y(lb.y() - (title_height - rect.height()) / 2); | 850 rect.set_y(lb.y() - (title_height - rect.height()) / 2); |
| 835 rect.set_height(title_height); | 851 rect.set_height(title_height); |
| 836 } | 852 } |
| 837 title_->SetBoundsRect(rect); | 853 title_->SetBoundsRect(rect); |
| 838 } | 854 } |
| 839 title_->SetVisible(show_title); | 855 title_->SetVisible(show_title); |
| 840 } | 856 } |
| 841 | 857 |
| 842 void Tab::OnThemeChanged() { | 858 void Tab::OnThemeChanged() { |
| 843 LoadTabImages(); | 859 LoadTabImages(); |
| 860 OnButtonColorMaybeChanged(); | |
| 844 } | 861 } |
| 845 | 862 |
| 846 const char* Tab::GetClassName() const { | 863 const char* Tab::GetClassName() const { |
| 847 return kViewClassName; | 864 return kViewClassName; |
| 848 } | 865 } |
| 849 | 866 |
| 850 bool Tab::GetTooltipText(const gfx::Point& p, base::string16* tooltip) const { | 867 bool Tab::GetTooltipText(const gfx::Point& p, base::string16* tooltip) const { |
| 851 // Note: Anything that affects the tooltip text should be accounted for when | 868 // Note: Anything that affects the tooltip text should be accounted for when |
| 852 // calling TooltipTextChanged() from Tab::DataChanged(). | 869 // calling TooltipTextChanged() from Tab::DataChanged(). |
| 853 *tooltip = chrome::AssembleTabTooltipText(data_.title, data_.media_state); | 870 *tooltip = chrome::AssembleTabTooltipText(data_.title, data_.media_state); |
| (...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1035 StopPulse(); | 1052 StopPulse(); |
| 1036 } | 1053 } |
| 1037 | 1054 |
| 1038 void Tab::PaintTab(gfx::Canvas* canvas) { | 1055 void Tab::PaintTab(gfx::Canvas* canvas) { |
| 1039 // See if the model changes whether the icons should be painted. | 1056 // See if the model changes whether the icons should be painted. |
| 1040 const bool show_icon = ShouldShowIcon(); | 1057 const bool show_icon = ShouldShowIcon(); |
| 1041 const bool show_media_indicator = ShouldShowMediaIndicator(); | 1058 const bool show_media_indicator = ShouldShowMediaIndicator(); |
| 1042 const bool show_close_button = ShouldShowCloseBox(); | 1059 const bool show_close_button = ShouldShowCloseBox(); |
| 1043 if (show_icon != showing_icon_ || | 1060 if (show_icon != showing_icon_ || |
| 1044 show_media_indicator != showing_media_indicator_ || | 1061 show_media_indicator != showing_media_indicator_ || |
| 1045 show_close_button != showing_close_button_) { | 1062 show_close_button != showing_close_button_) |
| 1046 Layout(); | 1063 Layout(); |
| 1047 } | |
| 1048 | 1064 |
| 1049 PaintTabBackground(canvas); | 1065 PaintTabBackground(canvas); |
| 1050 | 1066 |
| 1051 const SkColor title_color = GetThemeProvider()->GetColor(IsSelected() ? | |
| 1052 ThemeProperties::COLOR_TAB_TEXT : | |
| 1053 ThemeProperties::COLOR_BACKGROUND_TAB_TEXT); | |
| 1054 title_->SetVisible(ShouldRenderAsNormalTab()); | |
| 1055 title_->SetEnabledColor(title_color); | |
| 1056 | |
| 1057 if (show_icon) | 1067 if (show_icon) |
| 1058 PaintIcon(canvas); | 1068 PaintIcon(canvas); |
| 1059 | |
| 1060 // If the close button color has changed, generate a new one. | |
| 1061 if (!close_button_color_ || title_color != close_button_color_) { | |
| 1062 close_button_color_ = title_color; | |
| 1063 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); | |
| 1064 close_button_->SetBackground(close_button_color_, | |
| 1065 rb.GetImageSkiaNamed(IDR_CLOSE_1), | |
| 1066 rb.GetImageSkiaNamed(IDR_CLOSE_1_MASK)); | |
| 1067 } | |
| 1068 } | 1069 } |
| 1069 | 1070 |
| 1070 void Tab::PaintImmersiveTab(gfx::Canvas* canvas) { | 1071 void Tab::PaintImmersiveTab(gfx::Canvas* canvas) { |
| 1071 // Use transparency for the draw-attention animation. | 1072 // Use transparency for the draw-attention animation. |
| 1072 int alpha = 255; | 1073 int alpha = 255; |
| 1073 if (pulse_animation_ && pulse_animation_->is_animating() && !data().pinned) { | 1074 if (pulse_animation_ && pulse_animation_->is_animating() && !data().pinned) { |
| 1074 alpha = pulse_animation_->CurrentValueBetween( | 1075 alpha = pulse_animation_->CurrentValueBetween( |
| 1075 255, static_cast<int>(255 * kImmersiveTabMinThrobOpacity)); | 1076 255, static_cast<int>(255 * kImmersiveTabMinThrobOpacity)); |
| 1076 } | 1077 } |
| 1077 | 1078 |
| (...skipping 422 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1500 | 1501 |
| 1501 void Tab::StartCrashAnimation() { | 1502 void Tab::StartCrashAnimation() { |
| 1502 crash_icon_animation_.reset(new FaviconCrashAnimation(this)); | 1503 crash_icon_animation_.reset(new FaviconCrashAnimation(this)); |
| 1503 crash_icon_animation_->Start(); | 1504 crash_icon_animation_->Start(); |
| 1504 } | 1505 } |
| 1505 | 1506 |
| 1506 bool Tab::IsPerformingCrashAnimation() const { | 1507 bool Tab::IsPerformingCrashAnimation() const { |
| 1507 return crash_icon_animation_.get() && data_.IsCrashed(); | 1508 return crash_icon_animation_.get() && data_.IsCrashed(); |
| 1508 } | 1509 } |
| 1509 | 1510 |
| 1511 void Tab::OnButtonColorMaybeChanged() { | |
| 1512 // The theme provider may be null if we're not currently in a widget | |
| 1513 // hierarchy. | |
| 1514 ui::ThemeProvider* theme_provider = GetThemeProvider(); | |
| 1515 if (!theme_provider) | |
| 1516 return; | |
| 1517 | |
| 1518 const SkColor title_color = theme_provider->GetColor(IsActive() ? | |
| 1519 ThemeProperties::COLOR_TAB_TEXT : | |
| 1520 ThemeProperties::COLOR_BACKGROUND_TAB_TEXT); | |
| 1521 const SkColor new_button_color = SkColorSetA(title_color, 0xA0); | |
| 1522 if (button_color_ != new_button_color) { | |
| 1523 button_color_ = new_button_color; | |
| 1524 title_->SetEnabledColor(title_color); | |
| 1525 media_indicator_button_->OnParentTabButtonColorChanged(); | |
| 1526 const gfx::ImageSkia& close_button_normal_image = gfx::CreateVectorIcon( | |
| 1527 gfx::VectorIconId::TAB_CLOSE_NORMAL, kTabCloseButtonSize, | |
| 1528 button_color_); | |
| 1529 close_button_->SetImage(views::CustomButton::STATE_NORMAL, | |
| 1530 &close_button_normal_image); | |
| 1531 } | |
| 1532 } | |
| 1533 | |
| 1510 void Tab::ScheduleIconPaint() { | 1534 void Tab::ScheduleIconPaint() { |
| 1511 gfx::Rect bounds = favicon_bounds_; | 1535 gfx::Rect bounds = favicon_bounds_; |
| 1512 if (bounds.IsEmpty()) | 1536 if (bounds.IsEmpty()) |
| 1513 return; | 1537 return; |
| 1514 | 1538 |
| 1515 // Extends the area to the bottom when sad_favicon is animating. | 1539 // Extends the area to the bottom when sad_favicon is animating. |
| 1516 if (IsPerformingCrashAnimation()) | 1540 if (IsPerformingCrashAnimation()) |
| 1517 bounds.set_height(height() - bounds.y()); | 1541 bounds.set_height(height() - bounds.y()); |
| 1518 bounds.set_x(GetMirroredXForRect(bounds)); | 1542 bounds.set_x(GetMirroredXForRect(bounds)); |
| 1519 SchedulePaintInRect(bounds); | 1543 SchedulePaintInRect(bounds); |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1591 *frame_id = 0; | 1615 *frame_id = 0; |
| 1592 } else if (data().incognito) { | 1616 } else if (data().incognito) { |
| 1593 *tab_id = IDR_THEME_TAB_BACKGROUND_INCOGNITO; | 1617 *tab_id = IDR_THEME_TAB_BACKGROUND_INCOGNITO; |
| 1594 *frame_id = IDR_THEME_FRAME_INCOGNITO; | 1618 *frame_id = IDR_THEME_FRAME_INCOGNITO; |
| 1595 } else { | 1619 } else { |
| 1596 *tab_id = IDR_THEME_TAB_BACKGROUND; | 1620 *tab_id = IDR_THEME_TAB_BACKGROUND; |
| 1597 *frame_id = IDR_THEME_FRAME; | 1621 *frame_id = IDR_THEME_FRAME; |
| 1598 } | 1622 } |
| 1599 } | 1623 } |
| 1600 | 1624 |
| 1601 MediaIndicatorButton* Tab::GetMediaIndicatorButton() { | |
| 1602 if (!media_indicator_button_) { | |
|
Evan Stade
2015/09/23 18:16:35
guess I don't really mind either way, but why this
Peter Kasting
2015/09/23 20:44:13
I wrote a comment on this removal in https://coder
| |
| 1603 media_indicator_button_ = new MediaIndicatorButton(this); | |
| 1604 AddChildView(media_indicator_button_); // Takes ownership. | |
| 1605 } | |
| 1606 return media_indicator_button_; | |
| 1607 } | |
| 1608 | |
| 1609 //////////////////////////////////////////////////////////////////////////////// | 1625 //////////////////////////////////////////////////////////////////////////////// |
| 1610 // Tab, private static: | 1626 // Tab, private static: |
| 1611 | 1627 |
| 1612 // static | 1628 // static |
| 1613 void Tab::InitTabResources() { | 1629 void Tab::InitTabResources() { |
| 1614 static bool initialized = false; | 1630 static bool initialized = false; |
| 1615 if (initialized) | 1631 if (initialized) |
| 1616 return; | 1632 return; |
| 1617 | 1633 |
| 1618 initialized = true; | 1634 initialized = true; |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1663 const gfx::ImageSkia& image) { | 1679 const gfx::ImageSkia& image) { |
| 1664 DCHECK_NE(scale_factor, ui::SCALE_FACTOR_NONE); | 1680 DCHECK_NE(scale_factor, ui::SCALE_FACTOR_NONE); |
| 1665 ImageCacheEntry entry; | 1681 ImageCacheEntry entry; |
| 1666 entry.resource_id = resource_id; | 1682 entry.resource_id = resource_id; |
| 1667 entry.scale_factor = scale_factor; | 1683 entry.scale_factor = scale_factor; |
| 1668 entry.image = image; | 1684 entry.image = image; |
| 1669 image_cache_->push_front(entry); | 1685 image_cache_->push_front(entry); |
| 1670 if (image_cache_->size() > kMaxImageCacheSize) | 1686 if (image_cache_->size() > kMaxImageCacheSize) |
| 1671 image_cache_->pop_back(); | 1687 image_cache_->pop_back(); |
| 1672 } | 1688 } |
| OLD | NEW |