Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(486)

Side by Side Diff: chrome/browser/ui/views/tabs/tab.cc

Issue 1354823002: Render the tab close button as a vector-based icon. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 19 matching lines...) Expand all
30 #include "ui/base/resource/resource_bundle.h" 30 #include "ui/base/resource/resource_bundle.h"
31 #include "ui/base/theme_provider.h" 31 #include "ui/base/theme_provider.h"
32 #include "ui/gfx/animation/animation_container.h" 32 #include "ui/gfx/animation/animation_container.h"
33 #include "ui/gfx/animation/multi_animation.h" 33 #include "ui/gfx/animation/multi_animation.h"
34 #include "ui/gfx/animation/throb_animation.h" 34 #include "ui/gfx/animation/throb_animation.h"
35 #include "ui/gfx/canvas.h" 35 #include "ui/gfx/canvas.h"
36 #include "ui/gfx/color_analysis.h" 36 #include "ui/gfx/color_analysis.h"
37 #include "ui/gfx/favicon_size.h" 37 #include "ui/gfx/favicon_size.h"
38 #include "ui/gfx/geometry/rect_conversions.h" 38 #include "ui/gfx/geometry/rect_conversions.h"
39 #include "ui/gfx/image/image_skia_operations.h" 39 #include "ui/gfx/image/image_skia_operations.h"
40 #include "ui/gfx/paint_vector_icon.h"
40 #include "ui/gfx/path.h" 41 #include "ui/gfx/path.h"
41 #include "ui/gfx/skia_util.h" 42 #include "ui/gfx/skia_util.h"
43 #include "ui/gfx/vector_icons_public.h"
44 #include "ui/native_theme/common_theme.h"
45 #include "ui/native_theme/native_theme.h"
42 #include "ui/resources/grit/ui_resources.h" 46 #include "ui/resources/grit/ui_resources.h"
43 #include "ui/views/border.h" 47 #include "ui/views/border.h"
44 #include "ui/views/controls/button/image_button.h" 48 #include "ui/views/controls/button/image_button.h"
45 #include "ui/views/controls/label.h" 49 #include "ui/views/controls/label.h"
46 #include "ui/views/rect_based_targeting_utils.h" 50 #include "ui/views/rect_based_targeting_utils.h"
47 #include "ui/views/view_targeter.h" 51 #include "ui/views/view_targeter.h"
48 #include "ui/views/widget/tooltip_manager.h" 52 #include "ui/views/widget/tooltip_manager.h"
49 #include "ui/views/widget/widget.h" 53 #include "ui/views/widget/widget.h"
50 #include "ui/views/window/non_client_view.h" 54 #include "ui/views/window/non_client_view.h"
51 55
(...skipping 16 matching lines...) Expand all
68 72
69 // How long the pulse throb takes. 73 // How long the pulse throb takes.
70 const int kPulseDurationMs = 200; 74 const int kPulseDurationMs = 200;
71 75
72 // Width of touch tabs. 76 // Width of touch tabs.
73 const int kTouchWidth = 120; 77 const int kTouchWidth = 120;
74 78
75 const int kToolbarOverlap = 1; 79 const int kToolbarOverlap = 1;
76 const int kExtraLeftPaddingToBalanceCloseButtonPadding = 2; 80 const int kExtraLeftPaddingToBalanceCloseButtonPadding = 2;
77 const int kFaviconTitleSpacing = 4; 81 const int kFaviconTitleSpacing = 4;
78 const int kAfterTitleSpacing = 3; 82 const int kAfterTitleSpacing = 4;
79 const int kCloseButtonRightPaddingOverlap = 3; 83 const int kCloseButtonRightPaddingOverlap = 2;
80 const int kStandardTitleWidth = 175; 84 const int kStandardTitleWidth = 175;
81 85
82 // Width of the content inside a pinned tab. 86 // Width of the content inside a pinned tab.
83 int kPinnedTabContentWidth = 25; 87 int kPinnedTabContentWidth = 25;
84 88
85 // When a non-pinned tab becomes a pinned tab the width of the tab animates. If 89 // When a non-pinned tab becomes a pinned tab the width of the tab animates. If
86 // the width of a pinned tab is at least kPinnedTabExtraWidthToRenderAsNormal 90 // the width of a pinned tab is at least kPinnedTabExtraWidthToRenderAsNormal
87 // larger than the desired pinned tab width then the tab is rendered as a normal 91 // larger than the desired pinned tab width then the tab is rendered as a normal
88 // tab. This is done to avoid having the title immediately disappear when 92 // tab. This is done to avoid having the title immediately disappear when
89 // transitioning a tab from normal to pinned tab. 93 // transitioning a tab from normal to pinned tab.
(...skipping 331 matching lines...) Expand 10 before | Expand all | Expand 10 after
421 immersive_loading_step_(0), 425 immersive_loading_step_(0),
422 should_display_crashed_favicon_(false), 426 should_display_crashed_favicon_(false),
423 close_button_(NULL), 427 close_button_(NULL),
424 media_indicator_button_(NULL), 428 media_indicator_button_(NULL),
425 title_(new views::Label()), 429 title_(new views::Label()),
426 tab_activated_with_last_tap_down_(false), 430 tab_activated_with_last_tap_down_(false),
427 hover_controller_(this), 431 hover_controller_(this),
428 showing_icon_(false), 432 showing_icon_(false),
429 showing_media_indicator_(false), 433 showing_media_indicator_(false),
430 showing_close_button_(false), 434 showing_close_button_(false),
431 close_button_color_(0) { 435 close_button_color_(SK_ColorTRANSPARENT) {
432 DCHECK(controller); 436 DCHECK(controller);
433 InitTabResources(); 437 InitTabResources();
434 438
435 // So we get don't get enter/exit on children and don't prematurely stop the 439 // So we get don't get enter/exit on children and don't prematurely stop the
436 // hover. 440 // hover.
437 set_notify_enter_exit_on_child(true); 441 set_notify_enter_exit_on_child(true);
438 442
439 set_id(VIEW_ID_TAB); 443 set_id(VIEW_ID_TAB);
440 444
441 title_->SetHorizontalAlignment(gfx::ALIGN_TO_HEAD); 445 title_->SetHorizontalAlignment(gfx::ALIGN_TO_HEAD);
442 title_->SetElideBehavior(gfx::FADE_TAIL); 446 title_->SetElideBehavior(gfx::FADE_TAIL);
443 title_->SetHandlesTooltips(false); 447 title_->SetHandlesTooltips(false);
444 title_->SetAutoColorReadabilityEnabled(false); 448 title_->SetAutoColorReadabilityEnabled(false);
445 title_->SetText(CoreTabHelper::GetDefaultTitle()); 449 title_->SetText(CoreTabHelper::GetDefaultTitle());
446 AddChildView(title_); 450 AddChildView(title_);
447 451
448 SetEventTargeter( 452 SetEventTargeter(
449 scoped_ptr<views::ViewTargeter>(new views::ViewTargeter(this))); 453 scoped_ptr<views::ViewTargeter>(new views::ViewTargeter(this)));
450 454
451 // Add the Close Button.
452 close_button_ = new TabCloseButton(this); 455 close_button_ = new TabCloseButton(this);
453 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
454 close_button_->SetImage(views::CustomButton::STATE_NORMAL,
455 rb.GetImageSkiaNamed(IDR_CLOSE_1));
456 close_button_->SetImage(views::CustomButton::STATE_HOVERED,
457 rb.GetImageSkiaNamed(IDR_CLOSE_1_H));
458 close_button_->SetImage(views::CustomButton::STATE_PRESSED,
459 rb.GetImageSkiaNamed(IDR_CLOSE_1_P));
460 close_button_->SetAccessibleName( 456 close_button_->SetAccessibleName(
461 l10n_util::GetStringUTF16(IDS_ACCNAME_CLOSE)); 457 l10n_util::GetStringUTF16(IDS_ACCNAME_CLOSE));
458
459 // We need to set the close button's normal image now, even though it will
460 // have the wrong color, so that the close button gets sized and laid out
461 // correctly. (We can't get the correct color without a ThemeProvider, which
462 // we won't have until we're part of a Widget hierarchy.) We'll reset the
463 // image to the right color the first time through OnPaint(), when we're
464 // guaranteed to have the ThemeProvider available.
465 SetCloseButtonNormalImage();
466
467 // The hovered andpressed images won't be changing later, so we can set them
468 // correctly here.
469 const gfx::ImageSkia& hovered = gfx::CreateVectorIcon(
470 gfx::VectorIconId::TAB_CLOSE_HOVERED_PRESSED, 16,
471 SkColorSetARGB(0xFF, 0xDB, 0x44, 0x37));
472 const gfx::ImageSkia& pressed = gfx::CreateVectorIcon(
473 gfx::VectorIconId::TAB_CLOSE_HOVERED_PRESSED, 16,
474 SkColorSetARGB(0xFF, 0xA8, 0x35, 0x2A));
475 close_button_->SetImage(views::CustomButton::STATE_HOVERED, &hovered);
476 close_button_->SetImage(views::CustomButton::STATE_PRESSED, &pressed);
477
462 // Disable animation so that the red danger sign shows up immediately 478 // Disable animation so that the red danger sign shows up immediately
463 // to help avoid mis-clicks. 479 // to help avoid mis-clicks.
464 close_button_->SetAnimationDuration(0); 480 close_button_->SetAnimationDuration(0);
481
465 AddChildView(close_button_); 482 AddChildView(close_button_);
466 483
467 set_context_menu_controller(this); 484 set_context_menu_controller(this);
468 } 485 }
469 486
470 Tab::~Tab() { 487 Tab::~Tab() {
471 } 488 }
472 489
473 void Tab::set_animation_container(gfx::AnimationContainer* container) { 490 void Tab::set_animation_container(gfx::AnimationContainer* container) {
474 animation_container_ = container; 491 animation_container_ = container;
(...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after
737 754
738 void Tab::OnPaint(gfx::Canvas* canvas) { 755 void Tab::OnPaint(gfx::Canvas* canvas) {
739 // Don't paint if we're narrower than we can render correctly. (This should 756 // Don't paint if we're narrower than we can render correctly. (This should
740 // only happen during animations). 757 // only happen during animations).
741 if (width() < GetMinimumUnselectedSize().width() && !data().pinned) 758 if (width() < GetMinimumUnselectedSize().width() && !data().pinned)
742 return; 759 return;
743 760
744 gfx::Rect clip; 761 gfx::Rect clip;
745 if (!controller_->ShouldPaintTab(this, &clip)) 762 if (!controller_->ShouldPaintTab(this, &clip))
746 return; 763 return;
764
765 // If we haven't set the correct close button normal image, we can do so now.
766 if (close_button_color_ == SK_ColorTRANSPARENT)
767 OnThemeChanged();
768
747 if (!clip.IsEmpty()) { 769 if (!clip.IsEmpty()) {
748 canvas->Save(); 770 canvas->Save();
749 canvas->ClipRect(clip); 771 canvas->ClipRect(clip);
750 } 772 }
751 773
752 if (controller_->IsImmersiveStyle()) 774 if (controller_->IsImmersiveStyle())
753 PaintImmersiveTab(canvas); 775 PaintImmersiveTab(canvas);
754 else 776 else
755 PaintTab(canvas); 777 PaintTab(canvas);
756 778
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
840 rect.set_y(lb.y() - (title_height - rect.height()) / 2); 862 rect.set_y(lb.y() - (title_height - rect.height()) / 2);
841 rect.set_height(title_height); 863 rect.set_height(title_height);
842 } 864 }
843 title_->SetBoundsRect(rect); 865 title_->SetBoundsRect(rect);
844 } 866 }
845 title_->SetVisible(show_title); 867 title_->SetVisible(show_title);
846 } 868 }
847 869
848 void Tab::OnThemeChanged() { 870 void Tab::OnThemeChanged() {
849 LoadTabImages(); 871 LoadTabImages();
872
873 const SkColor text_color = GetThemeProvider()->GetColor(
874 IsActive() ? ThemeProperties::COLOR_TAB_TEXT
875 : ThemeProperties::COLOR_BACKGROUND_TAB_TEXT);
876 close_button_color_ = SkColorSetA(text_color, 0x70);
877 SetCloseButtonNormalImage();
850 } 878 }
851 879
852 const char* Tab::GetClassName() const { 880 const char* Tab::GetClassName() const {
853 return kViewClassName; 881 return kViewClassName;
854 } 882 }
855 883
856 bool Tab::GetTooltipText(const gfx::Point& p, base::string16* tooltip) const { 884 bool Tab::GetTooltipText(const gfx::Point& p, base::string16* tooltip) const {
857 // Note: Anything that affects the tooltip text should be accounted for when 885 // Note: Anything that affects the tooltip text should be accounted for when
858 // calling TooltipTextChanged() from Tab::DataChanged(). 886 // calling TooltipTextChanged() from Tab::DataChanged().
859 *tooltip = chrome::AssembleTabTooltipText(data_.title, data_.media_state); 887 *tooltip = chrome::AssembleTabTooltipText(data_.title, data_.media_state);
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after
1041 StopPulse(); 1069 StopPulse();
1042 } 1070 }
1043 1071
1044 void Tab::PaintTab(gfx::Canvas* canvas) { 1072 void Tab::PaintTab(gfx::Canvas* canvas) {
1045 // See if the model changes whether the icons should be painted. 1073 // See if the model changes whether the icons should be painted.
1046 const bool show_icon = ShouldShowIcon(); 1074 const bool show_icon = ShouldShowIcon();
1047 const bool show_media_indicator = ShouldShowMediaIndicator(); 1075 const bool show_media_indicator = ShouldShowMediaIndicator();
1048 const bool show_close_button = ShouldShowCloseBox(); 1076 const bool show_close_button = ShouldShowCloseBox();
1049 if (show_icon != showing_icon_ || 1077 if (show_icon != showing_icon_ ||
1050 show_media_indicator != showing_media_indicator_ || 1078 show_media_indicator != showing_media_indicator_ ||
1051 show_close_button != showing_close_button_) { 1079 show_close_button != showing_close_button_)
1052 Layout(); 1080 Layout();
1053 }
1054 1081
1055 PaintTabBackground(canvas); 1082 PaintTabBackground(canvas);
1056 1083
1057 const SkColor title_color = GetThemeProvider()->GetColor(IsSelected() ? 1084 const SkColor title_color = GetThemeProvider()->GetColor(IsSelected() ?
1058 ThemeProperties::COLOR_TAB_TEXT : 1085 ThemeProperties::COLOR_TAB_TEXT :
1059 ThemeProperties::COLOR_BACKGROUND_TAB_TEXT); 1086 ThemeProperties::COLOR_BACKGROUND_TAB_TEXT);
1060 title_->SetVisible(ShouldRenderAsNormalTab());
Peter Kasting 2015/09/18 01:00:46 This was already done in Layout().
1061 title_->SetEnabledColor(title_color); 1087 title_->SetEnabledColor(title_color);
1062 1088
1063 if (show_icon) 1089 if (show_icon)
1064 PaintIcon(canvas); 1090 PaintIcon(canvas);
1065
1066 // If the close button color has changed, generate a new one.
1067 if (!close_button_color_ || title_color != close_button_color_) {
1068 close_button_color_ = title_color;
1069 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
1070 close_button_->SetBackground(close_button_color_,
1071 rb.GetImageSkiaNamed(IDR_CLOSE_1),
1072 rb.GetImageSkiaNamed(IDR_CLOSE_1_MASK));
1073 }
1074 } 1091 }
1075 1092
1076 void Tab::PaintImmersiveTab(gfx::Canvas* canvas) { 1093 void Tab::PaintImmersiveTab(gfx::Canvas* canvas) {
1077 // Use transparency for the draw-attention animation. 1094 // Use transparency for the draw-attention animation.
1078 int alpha = 255; 1095 int alpha = 255;
1079 if (pulse_animation_ && pulse_animation_->is_animating() && !data().pinned) { 1096 if (pulse_animation_ && pulse_animation_->is_animating() && !data().pinned) {
1080 alpha = pulse_animation_->CurrentValueBetween( 1097 alpha = pulse_animation_->CurrentValueBetween(
1081 255, static_cast<int>(255 * kImmersiveTabMinThrobOpacity)); 1098 255, static_cast<int>(255 * kImmersiveTabMinThrobOpacity));
1082 } 1099 }
1083 1100
(...skipping 422 matching lines...) Expand 10 before | Expand all | Expand 10 after
1506 1523
1507 void Tab::StartCrashAnimation() { 1524 void Tab::StartCrashAnimation() {
1508 crash_icon_animation_.reset(new FaviconCrashAnimation(this)); 1525 crash_icon_animation_.reset(new FaviconCrashAnimation(this));
1509 crash_icon_animation_->Start(); 1526 crash_icon_animation_->Start();
1510 } 1527 }
1511 1528
1512 bool Tab::IsPerformingCrashAnimation() const { 1529 bool Tab::IsPerformingCrashAnimation() const {
1513 return crash_icon_animation_.get() && data_.IsCrashed(); 1530 return crash_icon_animation_.get() && data_.IsCrashed();
1514 } 1531 }
1515 1532
1533 void Tab::SetCloseButtonNormalImage() {
1534 const gfx::ImageSkia& normal = gfx::CreateVectorIcon(
1535 gfx::VectorIconId::TAB_CLOSE_NORMAL, 16, close_button_color_);
1536 close_button_->SetImage(views::CustomButton::STATE_NORMAL, &normal);
1537 }
1538
1516 void Tab::ScheduleIconPaint() { 1539 void Tab::ScheduleIconPaint() {
1517 gfx::Rect bounds = favicon_bounds_; 1540 gfx::Rect bounds = favicon_bounds_;
1518 if (bounds.IsEmpty()) 1541 if (bounds.IsEmpty())
1519 return; 1542 return;
1520 1543
1521 // Extends the area to the bottom when sad_favicon is animating. 1544 // Extends the area to the bottom when sad_favicon is animating.
1522 if (IsPerformingCrashAnimation()) 1545 if (IsPerformingCrashAnimation())
1523 bounds.set_height(height() - bounds.y()); 1546 bounds.set_height(height() - bounds.y());
1524 bounds.set_x(GetMirroredXForRect(bounds)); 1547 bounds.set_x(GetMirroredXForRect(bounds));
1525 SchedulePaintInRect(bounds); 1548 SchedulePaintInRect(bounds);
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after
1669 const gfx::ImageSkia& image) { 1692 const gfx::ImageSkia& image) {
1670 DCHECK_NE(scale_factor, ui::SCALE_FACTOR_NONE); 1693 DCHECK_NE(scale_factor, ui::SCALE_FACTOR_NONE);
1671 ImageCacheEntry entry; 1694 ImageCacheEntry entry;
1672 entry.resource_id = resource_id; 1695 entry.resource_id = resource_id;
1673 entry.scale_factor = scale_factor; 1696 entry.scale_factor = scale_factor;
1674 entry.image = image; 1697 entry.image = image;
1675 image_cache_->push_front(entry); 1698 image_cache_->push_front(entry);
1676 if (image_cache_->size() > kMaxImageCacheSize) 1699 if (image_cache_->size() > kMaxImageCacheSize)
1677 image_cache_->pop_back(); 1700 image_cache_->pop_back();
1678 } 1701 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698