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

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

Issue 23513039: Replace animated tab audio indicator with static tab audio indicator. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Addressed review comments from sail@. Created 7 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 | Annotate | Revision Log
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 447 matching lines...) Expand 10 before | Expand all | Expand 10 after
458 closing_(false), 458 closing_(false),
459 dragging_(false), 459 dragging_(false),
460 favicon_hiding_offset_(0), 460 favicon_hiding_offset_(0),
461 loading_animation_frame_(0), 461 loading_animation_frame_(0),
462 immersive_loading_step_(0), 462 immersive_loading_step_(0),
463 should_display_crashed_favicon_(false), 463 should_display_crashed_favicon_(false),
464 theme_provider_(NULL), 464 theme_provider_(NULL),
465 tab_activated_with_last_gesture_begin_(false), 465 tab_activated_with_last_gesture_begin_(false),
466 hover_controller_(this), 466 hover_controller_(this),
467 showing_icon_(false), 467 showing_icon_(false),
468 showing_audio_indicator_(false),
468 showing_close_button_(false), 469 showing_close_button_(false),
469 close_button_color_(0) { 470 close_button_color_(0) {
470 InitTabResources(); 471 InitTabResources();
471 472
472 // So we get don't get enter/exit on children and don't prematurely stop the 473 // So we get don't get enter/exit on children and don't prematurely stop the
473 // hover. 474 // hover.
474 set_notify_enter_exit_on_child(true); 475 set_notify_enter_exit_on_child(true);
475 476
476 set_id(VIEW_ID_TAB); 477 set_id(VIEW_ID_TAB);
477 478
478 // Add the Close Button. 479 // Add the Close Button.
479 close_button_ = new TabCloseButton(this); 480 close_button_ = new TabCloseButton(this);
480 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); 481 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
481 close_button_->SetImage(views::CustomButton::STATE_NORMAL, 482 close_button_->SetImage(views::CustomButton::STATE_NORMAL,
482 rb.GetImageSkiaNamed(IDR_CLOSE_1)); 483 rb.GetImageSkiaNamed(IDR_CLOSE_1));
483 close_button_->SetImage(views::CustomButton::STATE_HOVERED, 484 close_button_->SetImage(views::CustomButton::STATE_HOVERED,
484 rb.GetImageSkiaNamed(IDR_CLOSE_1_H)); 485 rb.GetImageSkiaNamed(IDR_CLOSE_1_H));
485 close_button_->SetImage(views::CustomButton::STATE_PRESSED, 486 close_button_->SetImage(views::CustomButton::STATE_PRESSED,
486 rb.GetImageSkiaNamed(IDR_CLOSE_1_P)); 487 rb.GetImageSkiaNamed(IDR_CLOSE_1_P));
487 close_button_->SetAccessibleName( 488 close_button_->SetAccessibleName(
488 l10n_util::GetStringUTF16(IDS_ACCNAME_CLOSE)); 489 l10n_util::GetStringUTF16(IDS_ACCNAME_CLOSE));
489 // Disable animation so that the red danger sign shows up immediately 490 // Disable animation so that the red danger sign shows up immediately
490 // to help avoid mis-clicks. 491 // to help avoid mis-clicks.
491 close_button_->SetAnimationDuration(0); 492 close_button_->SetAnimationDuration(0);
492 AddChildView(close_button_); 493 AddChildView(close_button_);
493 494
494 set_context_menu_controller(this); 495 set_context_menu_controller(this);
495
496 tab_audio_indicator_.reset(new TabAudioIndicator(this));
497 } 496 }
498 497
499 Tab::~Tab() { 498 Tab::~Tab() {
500 } 499 }
501 500
502 void Tab::set_animation_container(ui::AnimationContainer* container) { 501 void Tab::set_animation_container(ui::AnimationContainer* container) {
503 animation_container_ = container; 502 animation_container_ = container;
504 hover_controller_.SetAnimationContainer(container); 503 hover_controller_.SetAnimationContainer(container);
505 tab_audio_indicator_->SetAnimationContainer(container);
506 } 504 }
507 505
508 bool Tab::IsActive() const { 506 bool Tab::IsActive() const {
509 return controller() ? controller()->IsActiveTab(this) : true; 507 return controller() ? controller()->IsActiveTab(this) : true;
510 } 508 }
511 509
512 bool Tab::IsSelected() const { 510 bool Tab::IsSelected() const {
513 return controller() ? controller()->IsTabSelected(this) : true; 511 return controller() ? controller()->IsTabSelected(this) : true;
514 } 512 }
515 513
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
549 ResetCrashedFavicon(); 547 ResetCrashedFavicon();
550 } 548 }
551 549
552 if (old.mini != data_.mini) { 550 if (old.mini != data_.mini) {
553 if (tab_animation_.get() && tab_animation_->is_animating()) { 551 if (tab_animation_.get() && tab_animation_->is_animating()) {
554 tab_animation_->Stop(); 552 tab_animation_->Stop();
555 tab_animation_.reset(NULL); 553 tab_animation_.reset(NULL);
556 } 554 }
557 } 555 }
558 556
559 tab_audio_indicator_->SetIsPlayingAudio(data_.AudioActive());
560
561 DataChanged(old); 557 DataChanged(old);
562 558
563 Layout(); 559 Layout();
564 SchedulePaint(); 560 SchedulePaint();
565 } 561 }
566 562
567 void Tab::UpdateLoadingAnimation(TabRendererData::NetworkState state) { 563 void Tab::UpdateLoadingAnimation(TabRendererData::NetworkState state) {
568 if (state == data_.network_state && 564 if (state == data_.network_state &&
569 state == TabRendererData::NETWORK_STATE_NONE) { 565 state == TabRendererData::NETWORK_STATE_NONE) {
570 // If the network state is none and hasn't changed, do nothing. Otherwise we 566 // If the network state is none and hasn't changed, do nothing. Otherwise we
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
672 int Tab::GetMiniWidth() { 668 int Tab::GetMiniWidth() {
673 return browser_defaults::kMiniTabWidth; 669 return browser_defaults::kMiniTabWidth;
674 } 670 }
675 671
676 // static 672 // static
677 int Tab::GetImmersiveHeight() { 673 int Tab::GetImmersiveHeight() {
678 return kImmersiveTabHeight; 674 return kImmersiveTabHeight;
679 } 675 }
680 676
681 //////////////////////////////////////////////////////////////////////////////// 677 ////////////////////////////////////////////////////////////////////////////////
682 // Tab, TabAudioIndicator::Delegate overrides:
683
684 void Tab::ScheduleAudioIndicatorPaint() {
685 // No need to schedule a paint if another animation is active. The other
686 // animation will do its own scheduling.
687 if (!icon_animation_)
688 ScheduleIconPaint();
689 }
690
691 ////////////////////////////////////////////////////////////////////////////////
692 // Tab, AnimationDelegate overrides: 678 // Tab, AnimationDelegate overrides:
693 679
694 void Tab::AnimationProgressed(const ui::Animation* animation) { 680 void Tab::AnimationProgressed(const ui::Animation* animation) {
695 // Ignore if the pulse animation is being performed on active tab because 681 // Ignore if the pulse animation is being performed on active tab because
696 // it repaints the same image. See |Tab::PaintTabBackground()|. 682 // it repaints the same image. See |Tab::PaintTabBackground()|.
697 if (animation == tab_animation_.get() && IsActive()) 683 if (animation == tab_animation_.get() && IsActive())
698 return; 684 return;
699 SchedulePaint(); 685 SchedulePaint();
700 } 686 }
701 687
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
774 content_height = std::max(content_height, close_button_size.height()); 760 content_height = std::max(content_height, close_button_size.height());
775 761
776 // Size the Favicon. 762 // Size the Favicon.
777 showing_icon_ = ShouldShowIcon(); 763 showing_icon_ = ShouldShowIcon();
778 if (showing_icon_) { 764 if (showing_icon_) {
779 // Use the size of the favicon as apps use a bigger favicon size. 765 // Use the size of the favicon as apps use a bigger favicon size.
780 int favicon_top = top_padding() + content_height / 2 - tab_icon_size() / 2; 766 int favicon_top = top_padding() + content_height / 2 - tab_icon_size() / 2;
781 int favicon_left = lb.x(); 767 int favicon_left = lb.x();
782 favicon_bounds_.SetRect(favicon_left, favicon_top, 768 favicon_bounds_.SetRect(favicon_left, favicon_top,
783 tab_icon_size(), tab_icon_size()); 769 tab_icon_size(), tab_icon_size());
784 if (data().mini && width() < kMiniTabRendererAsNormalTabWidth) { 770 MaybeAdjustLeftForMiniTab(&favicon_bounds_);
785 // Adjust the location of the favicon when transitioning from a normal
786 // tab to a mini-tab.
787 int mini_delta = kMiniTabRendererAsNormalTabWidth - GetMiniWidth();
788 int ideal_delta = width() - GetMiniWidth();
789 if (ideal_delta < mini_delta) {
790 int ideal_x = (GetMiniWidth() - tab_icon_size()) / 2;
791 int x = favicon_bounds_.x() + static_cast<int>(
792 (1 - static_cast<float>(ideal_delta) /
793 static_cast<float>(mini_delta)) *
794 (ideal_x - favicon_bounds_.x()));
795 favicon_bounds_.set_x(x);
796 }
797 }
798 } else { 771 } else {
799 favicon_bounds_.SetRect(lb.x(), lb.y(), 0, 0); 772 favicon_bounds_.SetRect(lb.x(), lb.y(), 0, 0);
800 } 773 }
801 774
802 // Size the Close button. 775 // Size the Close button.
803 showing_close_button_ = ShouldShowCloseBox(); 776 showing_close_button_ = ShouldShowCloseBox();
804 const bool is_host_desktop_type_ash = 777 const bool is_host_desktop_type_ash =
805 GetHostDesktopType(this) == chrome::HOST_DESKTOP_TYPE_ASH; 778 GetHostDesktopType(this) == chrome::HOST_DESKTOP_TYPE_ASH;
806 if (showing_close_button_) { 779 if (showing_close_button_) {
807 const int close_button_vert_fuzz = is_host_desktop_type_ash ? 780 const int close_button_vert_fuzz = is_host_desktop_type_ash ?
(...skipping 16 matching lines...) Expand all
824 close_button_->set_border(views::Border::CreateEmptyBorder(top_border, 797 close_button_->set_border(views::Border::CreateEmptyBorder(top_border,
825 left_border, bottom_border, right_border)); 798 left_border, bottom_border, right_border));
826 close_button_->SetPosition(gfx::Point(lb.width(), 0)); 799 close_button_->SetPosition(gfx::Point(lb.width(), 0));
827 close_button_->SizeToPreferredSize(); 800 close_button_->SizeToPreferredSize();
828 close_button_->SetVisible(true); 801 close_button_->SetVisible(true);
829 } else { 802 } else {
830 close_button_->SetBounds(0, 0, 0, 0); 803 close_button_->SetBounds(0, 0, 0, 0);
831 close_button_->SetVisible(false); 804 close_button_->SetVisible(false);
832 } 805 }
833 806
807 showing_audio_indicator_ = ShouldShowAudioIndicator();
808 if (showing_audio_indicator_) {
809 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
810 gfx::ImageSkia audio_indicator_image(
811 *rb.GetImageSkiaNamed(IDR_TAB_AUDIO_INDICATOR));
812 const int top =
813 top_padding() + (content_height - audio_indicator_image.height()) / 2;
814 const int right = showing_close_button_ ?
sky 2013/09/16 23:47:19 Does this work when RTL?
miu 2013/09/19 02:37:11 Yes. All the layout code sets its bounds under th
815 close_button_->x() + close_button_->GetInsets().left() : lb.right();
816 const int left = std::max(lb.x(), right - audio_indicator_image.width());
817 audio_indicator_bounds_.SetRect(left, top,
818 tab_icon_size(), tab_icon_size());
819 MaybeAdjustLeftForMiniTab(&audio_indicator_bounds_);
820 } else {
821 audio_indicator_bounds_.SetRect(lb.x(), lb.y(), 0, 0);
822 }
823
834 const int title_text_offset = is_host_desktop_type_ash ? 824 const int title_text_offset = is_host_desktop_type_ash ?
835 kTitleTextOffsetYAsh : kTitleTextOffsetY; 825 kTitleTextOffsetYAsh : kTitleTextOffsetY;
836 int title_left = favicon_bounds_.right() + kFaviconTitleSpacing; 826 int title_left = favicon_bounds_.right() + kFaviconTitleSpacing;
837 int title_top = top_padding() + title_text_offset + 827 int title_top = top_padding() + title_text_offset +
838 (content_height - font_height_) / 2; 828 (content_height - font_height_) / 2;
839 // Size the Title text to fill the remaining space. 829 // Size the Title text to fill the remaining space.
840 if (!data().mini || width() >= kMiniTabRendererAsNormalTabWidth) { 830 if (!data().mini || width() >= kMiniTabRendererAsNormalTabWidth) {
841 // If the user has big fonts, the title will appear rendered too far down 831 // If the user has big fonts, the title will appear rendered too far down
842 // on the y-axis if we use the regular top padding, so we need to adjust it 832 // on the y-axis if we use the regular top padding, so we need to adjust it
843 // so that the text appears centered. 833 // so that the text appears centered.
844 gfx::Size minimum_size = GetMinimumUnselectedSize(); 834 gfx::Size minimum_size = GetMinimumUnselectedSize();
845 int text_height = title_top + font_height_ + bottom_padding(); 835 int text_height = title_top + font_height_ + bottom_padding();
846 if (text_height > minimum_size.height()) 836 if (text_height > minimum_size.height())
847 title_top -= (text_height - minimum_size.height()) / 2; 837 title_top -= (text_height - minimum_size.height()) / 2;
848 838
849 int title_width; 839 int title_width;
850 if (close_button_->visible()) { 840 if (showing_audio_indicator_) {
841 title_width = audio_indicator_bounds_.x() - kTitleCloseButtonSpacing -
842 title_left;
843 } else if (close_button_->visible()) {
851 // The close button has an empty border with some padding (see details 844 // The close button has an empty border with some padding (see details
852 // above where the close-button's bounds is set). Allow the title to 845 // above where the close-button's bounds is set). Allow the title to
853 // overlap the empty padding. 846 // overlap the empty padding.
854 title_width = std::max(close_button_->x() + 847 title_width = close_button_->x() + close_button_->GetInsets().left() -
855 close_button_->GetInsets().left() - 848 kTitleCloseButtonSpacing - title_left;
856 kTitleCloseButtonSpacing - title_left, 0);
857 } else { 849 } else {
858 title_width = std::max(lb.width() - title_left, 0); 850 title_width = lb.width() - title_left;
859 } 851 }
852 title_width = std::max(title_width, 0);
860 title_bounds_.SetRect(title_left, title_top, title_width, font_height_); 853 title_bounds_.SetRect(title_left, title_top, title_width, font_height_);
861 } else { 854 } else {
862 title_bounds_.SetRect(title_left, title_top, 0, 0); 855 title_bounds_.SetRect(title_left, title_top, 0, 0);
863 } 856 }
864 857
865 // Certain UI elements within the Tab (the favicon, etc.) are not represented 858 // Certain UI elements within the Tab (the favicon, etc.) are not represented
866 // as child Views (which is the preferred method). Instead, these UI elements 859 // as child Views (which is the preferred method). Instead, these UI elements
867 // are drawn directly on the canvas from within Tab::OnPaint(). The Tab's 860 // are drawn directly on the canvas from within Tab::OnPaint(). The Tab's
868 // child Views (for example, the Tab's close button which is a views::Button 861 // child Views (for example, the Tab's close button which is a views::Button
869 // instance) are automatically mirrored by the mirroring infrastructure in 862 // instance) are automatically mirrored by the mirroring infrastructure in
(...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after
1070 // Tab, private 1063 // Tab, private
1071 1064
1072 const gfx::Rect& Tab::GetTitleBounds() const { 1065 const gfx::Rect& Tab::GetTitleBounds() const {
1073 return title_bounds_; 1066 return title_bounds_;
1074 } 1067 }
1075 1068
1076 const gfx::Rect& Tab::GetIconBounds() const { 1069 const gfx::Rect& Tab::GetIconBounds() const {
1077 return favicon_bounds_; 1070 return favicon_bounds_;
1078 } 1071 }
1079 1072
1073 void Tab::MaybeAdjustLeftForMiniTab(gfx::Rect* bounds) const {
1074 if (!data().mini || width() >= kMiniTabRendererAsNormalTabWidth)
1075 return;
1076 const int mini_delta = kMiniTabRendererAsNormalTabWidth - GetMiniWidth();
1077 const int ideal_delta = width() - GetMiniWidth();
1078 const int ideal_x = (GetMiniWidth() - bounds->width()) / 2;
1079 bounds->set_x(bounds->x() + static_cast<int>(
sky 2013/09/16 23:47:19 Wasn't the old code conditionally doing this? (789
miu 2013/09/19 02:37:11 Sort of. Yes, there was an "if (ideal_delta < min
1080 (1 - static_cast<float>(ideal_delta) / static_cast<float>(mini_delta)) *
1081 (ideal_x - bounds->x())));
1082 }
1083
1080 void Tab::DataChanged(const TabRendererData& old) { 1084 void Tab::DataChanged(const TabRendererData& old) {
1081 if (data().blocked == old.blocked) 1085 if (data().blocked == old.blocked)
1082 return; 1086 return;
1083 1087
1084 if (data().blocked) 1088 if (data().blocked)
1085 StartPulse(); 1089 StartPulse();
1086 else 1090 else
1087 StopPulse(); 1091 StopPulse();
1088 } 1092 }
1089 1093
1090 void Tab::PaintTab(gfx::Canvas* canvas) { 1094 void Tab::PaintTab(gfx::Canvas* canvas) {
1091 // See if the model changes whether the icons should be painted. 1095 // See if the model changes whether the icons should be painted.
1092 const bool show_icon = ShouldShowIcon(); 1096 const bool show_icon = ShouldShowIcon();
1097 const bool show_audio_indicator = ShouldShowAudioIndicator();
1093 const bool show_close_button = ShouldShowCloseBox(); 1098 const bool show_close_button = ShouldShowCloseBox();
1094 if (show_icon != showing_icon_ || show_close_button != showing_close_button_) 1099 if (show_icon != showing_icon_ ||
1100 show_audio_indicator != showing_audio_indicator_ ||
1101 show_close_button != showing_close_button_) {
1095 Layout(); 1102 Layout();
1103 }
1096 1104
1097 PaintTabBackground(canvas); 1105 PaintTabBackground(canvas);
1098 1106
1099 SkColor title_color = GetThemeProvider()-> 1107 SkColor title_color = GetThemeProvider()->
1100 GetColor(IsSelected() ? 1108 GetColor(IsSelected() ?
1101 ThemeProperties::COLOR_TAB_TEXT : 1109 ThemeProperties::COLOR_TAB_TEXT :
1102 ThemeProperties::COLOR_BACKGROUND_TAB_TEXT); 1110 ThemeProperties::COLOR_BACKGROUND_TAB_TEXT);
1103 1111
1104 if (!data().mini || width() > kMiniTabRendererAsNormalTabWidth) 1112 if (!data().mini || width() > kMiniTabRendererAsNormalTabWidth)
1105 PaintTitle(canvas, title_color); 1113 PaintTitle(canvas, title_color);
1106 1114
1107 if (show_icon) 1115 if (show_icon)
1108 PaintIcon(canvas); 1116 PaintIcon(canvas);
1109 1117
1118 if (show_audio_indicator)
1119 PaintAudioIndicator(canvas);
1120
1110 // If the close button color has changed, generate a new one. 1121 // If the close button color has changed, generate a new one.
1111 if (!close_button_color_ || title_color != close_button_color_) { 1122 if (!close_button_color_ || title_color != close_button_color_) {
1112 close_button_color_ = title_color; 1123 close_button_color_ = title_color;
1113 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); 1124 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
1114 close_button_->SetBackground(close_button_color_, 1125 close_button_->SetBackground(close_button_color_,
1115 rb.GetImageSkiaNamed(IDR_CLOSE_1), 1126 rb.GetImageSkiaNamed(IDR_CLOSE_1),
1116 rb.GetImageSkiaNamed(IDR_CLOSE_1_MASK)); 1127 rb.GetImageSkiaNamed(IDR_CLOSE_1_MASK));
1117 } 1128 }
1118 } 1129 }
1119 1130
(...skipping 330 matching lines...) Expand 10 before | Expand all | Expand 10 after
1450 resized_icon.height(), 1461 resized_icon.height(),
1451 resized_bounds, true, SkPaint()); 1462 resized_bounds, true, SkPaint());
1452 1463
1453 ui::ThemeProvider* tp = GetThemeProvider(); 1464 ui::ThemeProvider* tp = GetThemeProvider();
1454 gfx::ImageSkia projection_screen( 1465 gfx::ImageSkia projection_screen(
1455 *tp->GetImageSkiaNamed(IDR_TAB_CAPTURE)); 1466 *tp->GetImageSkiaNamed(IDR_TAB_CAPTURE));
1456 DrawIconCenter(canvas, projection_screen, 0, 1467 DrawIconCenter(canvas, projection_screen, 0,
1457 data().favicon.width(), 1468 data().favicon.width(),
1458 data().favicon.height(), 1469 data().favicon.height(),
1459 bounds, true, SkPaint()); 1470 bounds, true, SkPaint());
1460 } else if (!icon_animation_ && tab_audio_indicator_->IsAnimating()) {
1461 // Draw the audio indicator UI only if no other icon animation is
1462 // active.
1463 if (!icon_animation_ && tab_audio_indicator_->IsAnimating()) {
1464 tab_audio_indicator_->set_favicon(data().favicon);
1465 tab_audio_indicator_->Paint(canvas, bounds);
1466 }
1467 } else { 1471 } else {
1468 DrawIconCenter(canvas, data().favicon, 0, 1472 DrawIconCenter(canvas, data().favicon, 0,
1469 data().favicon.width(), 1473 data().favicon.width(),
1470 data().favicon.height(), 1474 data().favicon.height(),
1471 bounds, true, SkPaint()); 1475 bounds, true, SkPaint());
1472 } 1476 }
1473 } 1477 }
1474 } 1478 }
1475 canvas->Restore(); 1479 canvas->Restore();
1476 1480
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
1566 1570
1567 // Draw the recording icon. 1571 // Draw the recording icon.
1568 DrawIconBottomRight(canvas, recording_dot, 0, 1572 DrawIconBottomRight(canvas, recording_dot, 0,
1569 recording_dot.width(), recording_dot.height(), 1573 recording_dot.width(), recording_dot.height(),
1570 bounds, false, paint); 1574 bounds, false, paint);
1571 } else { 1575 } else {
1572 NOTREACHED(); 1576 NOTREACHED();
1573 } 1577 }
1574 } 1578 }
1575 1579
1580 void Tab::PaintAudioIndicator(gfx::Canvas* canvas) {
1581 gfx::Rect bounds = audio_indicator_bounds_;
1582 if (bounds.IsEmpty())
sky 2013/09/16 23:47:19 nit: do the test on audio_indicator_bounds_ and mo
miu 2013/09/19 02:37:11 Done.
1583 return;
1584
1585 bounds.set_x(GetMirroredXForRect(bounds));
1586
1587 canvas->Save();
sky 2013/09/16 23:47:19 DrawIconAtLocation?
miu 2013/09/19 02:37:11 Oh, duh. Yeah, that's much cleaner. :)
1588 canvas->ClipRect(GetLocalBounds());
1589 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
1590 gfx::ImageSkia audio_indicator_image(
1591 *rb.GetImageSkiaNamed(IDR_TAB_AUDIO_INDICATOR));
1592 DrawIconCenter(canvas, audio_indicator_image, 0,
1593 audio_indicator_image.width(),
1594 audio_indicator_image.height(),
1595 bounds, true, SkPaint());
1596 canvas->Restore();
1597 }
1598
1576 void Tab::PaintTitle(gfx::Canvas* canvas, SkColor title_color) { 1599 void Tab::PaintTitle(gfx::Canvas* canvas, SkColor title_color) {
1577 // Paint the Title. 1600 // Paint the Title.
1578 const gfx::Rect& title_bounds = GetTitleBounds(); 1601 const gfx::Rect& title_bounds = GetTitleBounds();
1579 string16 title = data().title; 1602 string16 title = data().title;
1580 1603
1581 if (title.empty()) { 1604 if (title.empty()) {
1582 title = data().loading ? 1605 title = data().loading ?
1583 l10n_util::GetStringUTF16(IDS_TAB_LOADING_TITLE) : 1606 l10n_util::GetStringUTF16(IDS_TAB_LOADING_TITLE) :
1584 CoreTabHelper::GetDefaultTitle(); 1607 CoreTabHelper::GetDefaultTitle();
1585 } else { 1608 } else {
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
1645 } 1668 }
1646 if (controller() && controller()->IsImmersiveStyle()) 1669 if (controller() && controller()->IsImmersiveStyle())
1647 SchedulePaintInRect(GetImmersiveBarRect()); 1670 SchedulePaintInRect(GetImmersiveBarRect());
1648 else 1671 else
1649 ScheduleIconPaint(); 1672 ScheduleIconPaint();
1650 } 1673 }
1651 1674
1652 int Tab::IconCapacity() const { 1675 int Tab::IconCapacity() const {
1653 if (height() < GetMinimumUnselectedSize().height()) 1676 if (height() < GetMinimumUnselectedSize().height())
1654 return 0; 1677 return 0;
1655 return (width() - left_padding() - right_padding()) / tab_icon_size(); 1678 const int kPaddingBetweenIcons = 2;
1679 return (width() - left_padding() - right_padding()) /
1680 (tab_icon_size() + kPaddingBetweenIcons);
1656 } 1681 }
1657 1682
1658 bool Tab::ShouldShowIcon() const { 1683 bool Tab::ShouldShowIcon() const {
1684 if (!data().show_icon)
1685 return false;
1686 const bool should_show_audio_indicator = ShouldShowAudioIndicator();
1687 if (data().mini && height() >= GetMinimumUnselectedSize().height()) {
1688 // Audio indicator always takes precendence over the favicon for mini tabs.
1689 return !should_show_audio_indicator;
1690 }
1691 int required_capacity = should_show_audio_indicator ? 2 : 1;
1692 if (IsActive()) {
1693 // Active tabs give priority to the close button, then the audio indicator,
1694 // then the favicon.
1695 ++required_capacity;
1696 } else {
1697 // Non-active tabs give priority to the audio indicator, then the favicon,
1698 // and finally the close button.
1699 }
1700 return IconCapacity() >= required_capacity;
1701 }
1702
1703 bool Tab::ShouldShowAudioIndicator() const {
1704 // Note: If the capture indicator is active, then do not show the audio
1705 // indicator. This allows the favicon "throbber" animation to be shown in
1706 // small-width situations.
1707 if (!data().AudioActive() || data().CaptureActive())
1708 return false;
1659 if (data().mini && height() >= GetMinimumUnselectedSize().height()) 1709 if (data().mini && height() >= GetMinimumUnselectedSize().height())
1660 return true; 1710 return true;
1661 if (!data().show_icon) { 1711 if (IsActive()) {
1662 return false; 1712 // The active tab clips the audio indicator before the close button.
1663 } else if (IsActive()) {
1664 // The active tab clips favicon before close button.
1665 return IconCapacity() >= 2; 1713 return IconCapacity() >= 2;
1666 } 1714 }
1667 // Non-selected tabs clip close button before favicon. 1715 // Non-active tabs clip close button before the audio indicator.
1668 return IconCapacity() >= 1; 1716 return IconCapacity() >= 1;
1669 } 1717 }
1670 1718
1671 bool Tab::ShouldShowCloseBox() const { 1719 bool Tab::ShouldShowCloseBox() const {
1672 // The active tab never clips close button. 1720 // The active tab never clips close button.
1673 return !data().mini && (IsActive() || IconCapacity() >= 3); 1721 return !data().mini && (IsActive() || IconCapacity() >= 3);
1674 } 1722 }
1675 1723
1676 double Tab::GetThrobValue() { 1724 double Tab::GetThrobValue() {
1677 bool is_selected = IsSelected(); 1725 bool is_selected = IsSelected();
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after
1834 const gfx::ImageSkia& image) { 1882 const gfx::ImageSkia& image) {
1835 DCHECK_NE(scale_factor, ui::SCALE_FACTOR_NONE); 1883 DCHECK_NE(scale_factor, ui::SCALE_FACTOR_NONE);
1836 ImageCacheEntry entry; 1884 ImageCacheEntry entry;
1837 entry.resource_id = resource_id; 1885 entry.resource_id = resource_id;
1838 entry.scale_factor = scale_factor; 1886 entry.scale_factor = scale_factor;
1839 entry.image = image; 1887 entry.image = image;
1840 image_cache_->push_front(entry); 1888 image_cache_->push_front(entry);
1841 if (image_cache_->size() > kMaxImageCacheSize) 1889 if (image_cache_->size() > kMaxImageCacheSize)
1842 image_cache_->pop_back(); 1890 image_cache_->pop_back();
1843 } 1891 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698