| Index: chrome/browser/ui/views/tabs/tab.cc
|
| diff --git a/chrome/browser/ui/views/tabs/tab.cc b/chrome/browser/ui/views/tabs/tab.cc
|
| index b7871eb591b2508780431457ce9aa04408b20ebd..2492f4ebdff81f02c01645b8c17e45e0b66413f5 100644
|
| --- a/chrome/browser/ui/views/tabs/tab.cc
|
| +++ b/chrome/browser/ui/views/tabs/tab.cc
|
| @@ -465,6 +465,7 @@ Tab::Tab(TabController* controller)
|
| tab_activated_with_last_gesture_begin_(false),
|
| hover_controller_(this),
|
| showing_icon_(false),
|
| + showing_audio_indicator_(false),
|
| showing_close_button_(false),
|
| close_button_color_(0) {
|
| InitTabResources();
|
| @@ -492,8 +493,6 @@ Tab::Tab(TabController* controller)
|
| AddChildView(close_button_);
|
|
|
| set_context_menu_controller(this);
|
| -
|
| - tab_audio_indicator_.reset(new TabAudioIndicator(this));
|
| }
|
|
|
| Tab::~Tab() {
|
| @@ -502,7 +501,6 @@ Tab::~Tab() {
|
| void Tab::set_animation_container(gfx::AnimationContainer* container) {
|
| animation_container_ = container;
|
| hover_controller_.SetAnimationContainer(container);
|
| - tab_audio_indicator_->SetAnimationContainer(container);
|
| }
|
|
|
| bool Tab::IsActive() const {
|
| @@ -556,8 +554,6 @@ void Tab::SetData(const TabRendererData& data) {
|
| }
|
| }
|
|
|
| - tab_audio_indicator_->SetIsPlayingAudio(data_.AudioActive());
|
| -
|
| DataChanged(old);
|
|
|
| Layout();
|
| @@ -679,16 +675,6 @@ int Tab::GetImmersiveHeight() {
|
| }
|
|
|
| ////////////////////////////////////////////////////////////////////////////////
|
| -// Tab, TabAudioIndicator::Delegate overrides:
|
| -
|
| -void Tab::ScheduleAudioIndicatorPaint() {
|
| - // No need to schedule a paint if another animation is active. The other
|
| - // animation will do its own scheduling.
|
| - if (!icon_animation_)
|
| - ScheduleIconPaint();
|
| -}
|
| -
|
| -////////////////////////////////////////////////////////////////////////////////
|
| // Tab, AnimationDelegate overrides:
|
|
|
| void Tab::AnimationProgressed(const gfx::Animation* animation) {
|
| @@ -781,20 +767,7 @@ void Tab::Layout() {
|
| int favicon_left = lb.x();
|
| favicon_bounds_.SetRect(favicon_left, favicon_top,
|
| tab_icon_size(), tab_icon_size());
|
| - if (data().mini && width() < kMiniTabRendererAsNormalTabWidth) {
|
| - // Adjust the location of the favicon when transitioning from a normal
|
| - // tab to a mini-tab.
|
| - int mini_delta = kMiniTabRendererAsNormalTabWidth - GetMiniWidth();
|
| - int ideal_delta = width() - GetMiniWidth();
|
| - if (ideal_delta < mini_delta) {
|
| - int ideal_x = (GetMiniWidth() - tab_icon_size()) / 2;
|
| - int x = favicon_bounds_.x() + static_cast<int>(
|
| - (1 - static_cast<float>(ideal_delta) /
|
| - static_cast<float>(mini_delta)) *
|
| - (ideal_x - favicon_bounds_.x()));
|
| - favicon_bounds_.set_x(x);
|
| - }
|
| - }
|
| + MaybeAdjustLeftForMiniTab(&favicon_bounds_);
|
| } else {
|
| favicon_bounds_.SetRect(lb.x(), lb.y(), 0, 0);
|
| }
|
| @@ -831,6 +804,23 @@ void Tab::Layout() {
|
| close_button_->SetVisible(false);
|
| }
|
|
|
| + showing_audio_indicator_ = ShouldShowAudioIndicator();
|
| + if (showing_audio_indicator_) {
|
| + ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
|
| + gfx::ImageSkia audio_indicator_image(
|
| + *rb.GetImageSkiaNamed(IDR_TAB_AUDIO_INDICATOR));
|
| + const int top =
|
| + top_padding() + (content_height - audio_indicator_image.height()) / 2;
|
| + const int right = showing_close_button_ ?
|
| + close_button_->x() + close_button_->GetInsets().left() : lb.right();
|
| + const int left = std::max(lb.x(), right - audio_indicator_image.width());
|
| + audio_indicator_bounds_.SetRect(left, top,
|
| + tab_icon_size(), tab_icon_size());
|
| + MaybeAdjustLeftForMiniTab(&audio_indicator_bounds_);
|
| + } else {
|
| + audio_indicator_bounds_.SetRect(lb.x(), lb.y(), 0, 0);
|
| + }
|
| +
|
| const int title_text_offset = is_host_desktop_type_ash ?
|
| kTitleTextOffsetYAsh : kTitleTextOffsetY;
|
| int title_left = favicon_bounds_.right() + kFaviconTitleSpacing;
|
| @@ -847,16 +837,19 @@ void Tab::Layout() {
|
| title_top -= (text_height - minimum_size.height()) / 2;
|
|
|
| int title_width;
|
| - if (close_button_->visible()) {
|
| + if (showing_audio_indicator_) {
|
| + title_width = audio_indicator_bounds_.x() - kTitleCloseButtonSpacing -
|
| + title_left;
|
| + } else if (close_button_->visible()) {
|
| // The close button has an empty border with some padding (see details
|
| // above where the close-button's bounds is set). Allow the title to
|
| // overlap the empty padding.
|
| - title_width = std::max(close_button_->x() +
|
| - close_button_->GetInsets().left() -
|
| - kTitleCloseButtonSpacing - title_left, 0);
|
| + title_width = close_button_->x() + close_button_->GetInsets().left() -
|
| + kTitleCloseButtonSpacing - title_left;
|
| } else {
|
| - title_width = std::max(lb.width() - title_left, 0);
|
| + title_width = lb.width() - title_left;
|
| }
|
| + title_width = std::max(title_width, 0);
|
| title_bounds_.SetRect(title_left, title_top, title_width, font_height_);
|
| } else {
|
| title_bounds_.SetRect(title_left, title_top, 0, 0);
|
| @@ -1077,6 +1070,17 @@ const gfx::Rect& Tab::GetIconBounds() const {
|
| return favicon_bounds_;
|
| }
|
|
|
| +void Tab::MaybeAdjustLeftForMiniTab(gfx::Rect* bounds) const {
|
| + if (!data().mini || width() >= kMiniTabRendererAsNormalTabWidth)
|
| + return;
|
| + const int mini_delta = kMiniTabRendererAsNormalTabWidth - GetMiniWidth();
|
| + const int ideal_delta = width() - GetMiniWidth();
|
| + const int ideal_x = (GetMiniWidth() - bounds->width()) / 2;
|
| + bounds->set_x(bounds->x() + static_cast<int>(
|
| + (1 - static_cast<float>(ideal_delta) / static_cast<float>(mini_delta)) *
|
| + (ideal_x - bounds->x())));
|
| +}
|
| +
|
| void Tab::DataChanged(const TabRendererData& old) {
|
| if (data().blocked == old.blocked)
|
| return;
|
| @@ -1090,9 +1094,13 @@ void Tab::DataChanged(const TabRendererData& old) {
|
| void Tab::PaintTab(gfx::Canvas* canvas) {
|
| // See if the model changes whether the icons should be painted.
|
| const bool show_icon = ShouldShowIcon();
|
| + const bool show_audio_indicator = ShouldShowAudioIndicator();
|
| const bool show_close_button = ShouldShowCloseBox();
|
| - if (show_icon != showing_icon_ || show_close_button != showing_close_button_)
|
| + if (show_icon != showing_icon_ ||
|
| + show_audio_indicator != showing_audio_indicator_ ||
|
| + show_close_button != showing_close_button_) {
|
| Layout();
|
| + }
|
|
|
| PaintTabBackground(canvas);
|
|
|
| @@ -1107,6 +1115,9 @@ void Tab::PaintTab(gfx::Canvas* canvas) {
|
| if (show_icon)
|
| PaintIcon(canvas);
|
|
|
| + if (show_audio_indicator)
|
| + PaintAudioIndicator(canvas);
|
| +
|
| // If the close button color has changed, generate a new one.
|
| if (!close_button_color_ || title_color != close_button_color_) {
|
| close_button_color_ = title_color;
|
| @@ -1457,13 +1468,6 @@ void Tab::PaintIcon(gfx::Canvas* canvas) {
|
| data().favicon.width(),
|
| data().favicon.height(),
|
| bounds, true, SkPaint());
|
| - } else if (!icon_animation_ && tab_audio_indicator_->IsAnimating()) {
|
| - // Draw the audio indicator UI only if no other icon animation is
|
| - // active.
|
| - if (!icon_animation_ && tab_audio_indicator_->IsAnimating()) {
|
| - tab_audio_indicator_->set_favicon(data().favicon);
|
| - tab_audio_indicator_->Paint(canvas, bounds);
|
| - }
|
| } else {
|
| DrawIconCenter(canvas, data().favicon, 0,
|
| data().favicon.width(),
|
| @@ -1573,6 +1577,21 @@ void Tab::PaintCaptureState(gfx::Canvas* canvas, gfx::Rect bounds) {
|
| }
|
| }
|
|
|
| +void Tab::PaintAudioIndicator(gfx::Canvas* canvas) {
|
| + if (audio_indicator_bounds_.IsEmpty())
|
| + return;
|
| +
|
| + gfx::Rect bounds = audio_indicator_bounds_;
|
| + bounds.set_x(GetMirroredXForRect(bounds));
|
| +
|
| + ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
|
| + const gfx::ImageSkia audio_indicator_image(
|
| + *rb.GetImageSkiaNamed(IDR_TAB_AUDIO_INDICATOR));
|
| + DrawIconAtLocation(canvas, audio_indicator_image, 0,
|
| + bounds.x(), bounds.y(), audio_indicator_image.width(),
|
| + audio_indicator_image.height(), true, SkPaint());
|
| +}
|
| +
|
| void Tab::PaintTitle(gfx::Canvas* canvas, SkColor title_color) {
|
| // Paint the Title.
|
| const gfx::Rect& title_bounds = GetTitleBounds();
|
| @@ -1652,19 +1671,44 @@ void Tab::AdvanceLoadingAnimation(TabRendererData::NetworkState old_state,
|
| int Tab::IconCapacity() const {
|
| if (height() < GetMinimumUnselectedSize().height())
|
| return 0;
|
| - return (width() - left_padding() - right_padding()) / tab_icon_size();
|
| + const int kPaddingBetweenIcons = 2;
|
| + return (width() - left_padding() - right_padding()) /
|
| + (tab_icon_size() + kPaddingBetweenIcons);
|
| }
|
|
|
| bool Tab::ShouldShowIcon() const {
|
| + if (!data().show_icon)
|
| + return false;
|
| + const bool should_show_audio_indicator = ShouldShowAudioIndicator();
|
| + if (data().mini && height() >= GetMinimumUnselectedSize().height()) {
|
| + // Audio indicator always takes precendence over the favicon for mini tabs.
|
| + return !should_show_audio_indicator;
|
| + }
|
| + int required_capacity = should_show_audio_indicator ? 2 : 1;
|
| + if (IsActive()) {
|
| + // Active tabs give priority to the close button, then the audio indicator,
|
| + // then the favicon.
|
| + ++required_capacity;
|
| + } else {
|
| + // Non-active tabs give priority to the audio indicator, then the favicon,
|
| + // and finally the close button.
|
| + }
|
| + return IconCapacity() >= required_capacity;
|
| +}
|
| +
|
| +bool Tab::ShouldShowAudioIndicator() const {
|
| + // Note: If the capture indicator is active, then do not show the audio
|
| + // indicator. This allows the favicon "throbber" animation to be shown in
|
| + // small-width situations.
|
| + if (!data().AudioActive() || data().CaptureActive())
|
| + return false;
|
| if (data().mini && height() >= GetMinimumUnselectedSize().height())
|
| return true;
|
| - if (!data().show_icon) {
|
| - return false;
|
| - } else if (IsActive()) {
|
| - // The active tab clips favicon before close button.
|
| + if (IsActive()) {
|
| + // The active tab clips the audio indicator before the close button.
|
| return IconCapacity() >= 2;
|
| }
|
| - // Non-selected tabs clip close button before favicon.
|
| + // Non-active tabs clip close button before the audio indicator.
|
| return IconCapacity() >= 1;
|
| }
|
|
|
|
|