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 441cb72677e4e493cced578cc9a8298f4c5ef68e..d77fc8ae387aad9415a644d86860165f10db7e94 100644 |
--- a/chrome/browser/ui/views/tabs/tab.cc |
+++ b/chrome/browser/ui/views/tabs/tab.cc |
@@ -16,11 +16,13 @@ |
#include "chrome/browser/ui/tabs/tab_resources.h" |
#include "chrome/browser/ui/tabs/tab_utils.h" |
#include "chrome/browser/ui/view_ids.h" |
+#include "chrome/browser/ui/views/tabs/media_indicator_button.h" |
#include "chrome/browser/ui/views/tabs/tab_controller.h" |
#include "chrome/browser/ui/views/theme_image_mapper.h" |
#include "chrome/browser/ui/views/touch_uma/touch_uma.h" |
#include "chrome/common/chrome_switches.h" |
#include "chrome/grit/generated_resources.h" |
+#include "content/public/browser/user_metrics.h" |
#include "grit/theme_resources.h" |
#include "third_party/skia/include/effects/SkGradientShader.h" |
#include "ui/accessibility/ax_view_state.h" |
@@ -49,6 +51,8 @@ |
#include "ui/views/widget/widget.h" |
#include "ui/views/window/non_client_view.h" |
+using base::UserMetricsAction; |
+ |
namespace { |
// Padding around the "content" of a tab, occupied by the tab border graphics. |
@@ -409,8 +413,8 @@ Tab::Tab(TabController* controller) |
loading_animation_frame_(0), |
immersive_loading_step_(0), |
should_display_crashed_favicon_(false), |
- animating_media_state_(TAB_MEDIA_STATE_NONE), |
close_button_(NULL), |
+ media_indicator_button_(NULL), |
title_(new views::Label()), |
tab_activated_with_last_tap_down_(false), |
hover_controller_(this), |
@@ -509,11 +513,8 @@ void Tab::SetData(const TabRendererData& data) { |
ResetCrashedFavicon(); |
} |
- if (data_.media_state != old.media_state) { |
- if (data_.media_state != TAB_MEDIA_STATE_NONE) |
- animating_media_state_ = data_.media_state; |
- StartMediaIndicatorAnimation(); |
- } |
+ if (data_.media_state != old.media_state) |
+ GetMediaIndicatorButton()->TransitionToMediaState(data_.media_state); |
if (old.mini != data_.mini) { |
StopAndDeleteAnimation( |
@@ -642,14 +643,10 @@ void Tab::AnimationProgressed(const gfx::Animation* animation) { |
} |
void Tab::AnimationCanceled(const gfx::Animation* animation) { |
- if (media_indicator_animation_ == animation) |
- animating_media_state_ = data_.media_state; |
SchedulePaint(); |
} |
void Tab::AnimationEnded(const gfx::Animation* animation) { |
- if (media_indicator_animation_ == animation) |
- animating_media_state_ = data_.media_state; |
SchedulePaint(); |
} |
@@ -657,6 +654,17 @@ void Tab::AnimationEnded(const gfx::Animation* animation) { |
// Tab, views::ButtonListener overrides: |
void Tab::ButtonPressed(views::Button* sender, const ui::Event& event) { |
+ if (media_indicator_button_ && media_indicator_button_->visible()) { |
+ if (media_indicator_button_->enabled()) |
+ content::RecordAction(UserMetricsAction("CloseTab_MuteToggleAvailable")); |
+ else if (data_.media_state == TAB_MEDIA_STATE_AUDIO_PLAYING) |
+ content::RecordAction(UserMetricsAction("CloseTab_AudioIndicator")); |
+ else |
+ content::RecordAction(UserMetricsAction("CloseTab_RecordingIndicator")); |
+ } else { |
+ content::RecordAction(UserMetricsAction("CloseTab_NoMediaIndicator")); |
+ } |
+ |
const CloseTabSource source = |
(event.type() == ui::ET_MOUSE_RELEASED && |
(event.flags() & ui::EF_FROM_TOUCH) == 0) ? CLOSE_TAB_FROM_MOUSE : |
@@ -770,19 +778,21 @@ void Tab::Layout() { |
close_button_->SetVisible(showing_close_button_); |
showing_media_indicator_ = ShouldShowMediaIndicator(); |
- media_indicator_bounds_.SetRect(lb.x(), lb.y(), 0, 0); |
if (showing_media_indicator_) { |
- const gfx::Image& media_indicator_image = |
- chrome::GetTabMediaIndicatorImage(animating_media_state_); |
- media_indicator_bounds_.set_width(media_indicator_image.Width()); |
- media_indicator_bounds_.set_height(media_indicator_image.Height()); |
- media_indicator_bounds_.set_y( |
- lb.y() + (lb.height() - media_indicator_bounds_.height() + 1) / 2); |
+ views::ImageButton* const button = GetMediaIndicatorButton(); |
+ const gfx::Size image_size(button->GetPreferredSize()); |
const int right = showing_close_button_ ? |
close_button_->x() + close_button_->GetInsets().left() : lb.right(); |
- media_indicator_bounds_.set_x( |
- std::max(lb.x(), right - media_indicator_bounds_.width())); |
- MaybeAdjustLeftForMiniTab(&media_indicator_bounds_); |
+ gfx::Rect bounds( |
+ std::max(lb.x(), right - image_size.width()), |
+ lb.y() + (lb.height() - image_size.height() + 1) / 2, |
+ image_size.width(), |
+ image_size.height()); |
+ MaybeAdjustLeftForMiniTab(&bounds); |
+ button->SetBoundsRect(bounds); |
+ button->SetVisible(true); |
+ } else if (media_indicator_button_) { |
+ media_indicator_button_->SetVisible(false); |
} |
// Size the title to fill the remaining width and use all available height. |
@@ -791,7 +801,7 @@ void Tab::Layout() { |
int title_left = favicon_bounds_.right() + kFaviconTitleSpacing; |
int title_width = lb.width() - title_left; |
if (showing_media_indicator_) { |
- title_width = media_indicator_bounds_.x() - kViewSpacing - title_left; |
+ title_width = media_indicator_button_->x() - kViewSpacing - title_left; |
} else if (close_button_->visible()) { |
// Allow the title to overlay the close button's empty border padding. |
title_width = close_button_->x() + close_button_->GetInsets().left() - |
@@ -803,7 +813,6 @@ void Tab::Layout() { |
rect.set_y(lb.y() - (title_height - rect.height()) / 2); |
rect.set_height(title_height); |
} |
- rect.set_x(GetMirroredXForRect(rect)); |
title_->SetBoundsRect(rect); |
} |
title_->SetVisible(show_title); |
@@ -904,6 +913,11 @@ void Tab::OnMouseReleased(const ui::MouseEvent& event) { |
// selection. Reset it now to handle the case where multiple tabs were |
// selected. |
controller_->SelectTab(this); |
+ |
+ if (media_indicator_button_ && media_indicator_button_->visible() && |
+ media_indicator_button_->bounds().Contains(event.location())) { |
+ content::RecordAction(UserMetricsAction("TabMediaIndicator_Clicked")); |
+ } |
} |
} |
@@ -1020,9 +1034,6 @@ void Tab::PaintTab(gfx::Canvas* canvas) { |
if (show_icon) |
PaintIcon(canvas); |
- if (show_media_indicator) |
- PaintMediaIndicator(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; |
@@ -1341,28 +1352,6 @@ void Tab::PaintIcon(gfx::Canvas* canvas) { |
} |
} |
-void Tab::PaintMediaIndicator(gfx::Canvas* canvas) { |
- if (media_indicator_bounds_.IsEmpty() || !media_indicator_animation_) |
- return; |
- |
- gfx::Rect bounds = media_indicator_bounds_; |
- bounds.set_x(GetMirroredXForRect(bounds)); |
- |
- SkPaint paint; |
- paint.setAntiAlias(true); |
- double opaqueness = media_indicator_animation_->GetCurrentValue(); |
- if (data_.media_state == TAB_MEDIA_STATE_NONE) |
- opaqueness = 1.0 - opaqueness; // Fading out, not in. |
- paint.setAlpha(opaqueness * SK_AlphaOPAQUE); |
- |
- const gfx::ImageSkia& media_indicator_image = |
- *(chrome::GetTabMediaIndicatorImage(animating_media_state_). |
- ToImageSkia()); |
- DrawIconAtLocation(canvas, media_indicator_image, 0, |
- bounds.x(), bounds.y(), media_indicator_image.width(), |
- media_indicator_image.height(), true, paint); |
-} |
- |
void Tab::AdvanceLoadingAnimation(TabRendererData::NetworkState old_state, |
TabRendererData::NetworkState state) { |
static bool initialized = false; |
@@ -1439,13 +1428,15 @@ int Tab::IconCapacity() const { |
bool Tab::ShouldShowIcon() const { |
return chrome::ShouldTabShowFavicon( |
IconCapacity(), data().mini, IsActive(), data().show_icon, |
- animating_media_state_); |
+ media_indicator_button_ ? media_indicator_button_->showing_media_state() : |
+ data_.media_state); |
} |
bool Tab::ShouldShowMediaIndicator() const { |
return chrome::ShouldTabShowMediaIndicator( |
IconCapacity(), data().mini, IsActive(), data().show_icon, |
- animating_media_state_); |
+ media_indicator_button_ ? media_indicator_button_->showing_media_state() : |
+ data_.media_state); |
} |
bool Tab::ShouldShowCloseBox() const { |
@@ -1500,13 +1491,6 @@ bool Tab::IsPerformingCrashAnimation() const { |
return crash_icon_animation_.get() && data_.IsCrashed(); |
} |
-void Tab::StartMediaIndicatorAnimation() { |
- media_indicator_animation_ = |
- chrome::CreateTabMediaIndicatorFadeAnimation(data_.media_state); |
- media_indicator_animation_->set_delegate(this); |
- media_indicator_animation_->Start(); |
-} |
- |
void Tab::ScheduleIconPaint() { |
gfx::Rect bounds = favicon_bounds_; |
if (bounds.IsEmpty()) |
@@ -1546,6 +1530,14 @@ void Tab::GetTabIdAndFrameId(views::Widget* widget, |
} |
} |
+MediaIndicatorButton* Tab::GetMediaIndicatorButton() { |
+ if (!media_indicator_button_) { |
+ media_indicator_button_ = new MediaIndicatorButton(); |
+ AddChildView(media_indicator_button_); // Takes ownership. |
+ } |
+ return media_indicator_button_; |
+} |
+ |
//////////////////////////////////////////////////////////////////////////////// |
// Tab, private static: |