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 ba54c9f8529263a58a8373d7abfd567659e641e9..d64ab5fc263a3d9193fcca460325fb05e07c35c6 100644 |
--- a/chrome/browser/ui/views/tabs/tab.cc |
+++ b/chrome/browser/ui/views/tabs/tab.cc |
@@ -37,7 +37,6 @@ |
#include "ui/base/resource/resource_bundle.h" |
#include "ui/base/theme_provider.h" |
#include "ui/gfx/animation/animation_container.h" |
-#include "ui/gfx/animation/multi_animation.h" |
#include "ui/gfx/animation/throb_animation.h" |
#include "ui/gfx/canvas.h" |
#include "ui/gfx/color_analysis.h" |
@@ -89,10 +88,6 @@ const double kSelectedTabOpacity = 0.3; |
// Inactive selected tabs have their throb value scaled by this. |
const double kSelectedTabThrobScale = 0.95 - kSelectedTabOpacity; |
-// Offset from the right edge for the start of the pinned title change |
-// animation. |
-const int kPinnedTitleChangeInitialXOffset = 6; |
- |
// Max number of images to cache. This has to be at least two since rounding |
// errors may lead to tabs in the same tabstrip having different sizes. |
// 8 = normal/incognito, active/inactive, 2 sizes within tabstrip. |
@@ -566,34 +561,6 @@ Tab::Tab(TabController* controller, gfx::AnimationContainer* container) |
pulse_animation_->SetSlideDuration(kPulseDurationMs); |
pulse_animation_->SetContainer(animation_container_.get()); |
- const int kPinnedTitleChangeAnimationDuration1MS = 1600; |
- const int kPinnedTitleChangeAnimationStart1MS = 0; |
- const int kPinnedTitleChangeAnimationEnd1MS = 1900; |
- const int kPinnedTitleChangeAnimationDuration2MS = 0; |
- const int kPinnedTitleChangeAnimationDuration3MS = 550; |
- const int kPinnedTitleChangeAnimationStart3MS = 150; |
- const int kPinnedTitleChangeAnimationEnd3MS = 800; |
- const int kPinnedTitleChangeAnimationIntervalMS = 40; |
- gfx::MultiAnimation::Parts parts; |
- parts.push_back(gfx::MultiAnimation::Part( |
- kPinnedTitleChangeAnimationDuration1MS, |
- kPinnedTitleChangeAnimationStart1MS, |
- kPinnedTitleChangeAnimationEnd1MS, |
- gfx::Tween::EASE_OUT)); |
- parts.push_back(gfx::MultiAnimation::Part( |
- kPinnedTitleChangeAnimationDuration2MS, |
- gfx::Tween::ZERO)); |
- parts.push_back(gfx::MultiAnimation::Part( |
- kPinnedTitleChangeAnimationDuration3MS, |
- kPinnedTitleChangeAnimationStart3MS, |
- kPinnedTitleChangeAnimationEnd3MS, |
- gfx::Tween::EASE_IN)); |
- const base::TimeDelta timeout = |
- base::TimeDelta::FromMilliseconds(kPinnedTitleChangeAnimationIntervalMS); |
- pinned_title_change_animation_.reset(new gfx::MultiAnimation(parts, timeout)); |
- pinned_title_change_animation_->SetContainer(animation_container_.get()); |
- pinned_title_change_animation_->set_delegate(this); |
- |
hover_controller_.SetAnimationContainer(animation_container_.get()); |
} |
@@ -652,7 +619,7 @@ void Tab::SetData(const TabRendererData& data) { |
alert_indicator_button_->TransitionToAlertState(data_.alert_state); |
if (old.pinned != data_.pinned) |
- StopPinnedTabTitleAnimation(); |
+ showing_pinned_tab_title_changed_indicator_ = false; |
DataChanged(old); |
@@ -680,13 +647,14 @@ void Tab::StopPulse() { |
pulse_animation_->Stop(); |
} |
-void Tab::StartPinnedTabTitleAnimation() { |
- if (data().pinned) |
- pinned_title_change_animation_->Start(); |
-} |
+void Tab::SetPinnedTabTitleChangedIndicatorVisible(bool value) { |
+ if (value == showing_pinned_tab_title_changed_indicator_) |
+ return; |
-void Tab::StopPinnedTabTitleAnimation() { |
- pinned_title_change_animation_->Stop(); |
+ DCHECK(!value || data().pinned); |
+ |
+ showing_pinned_tab_title_changed_indicator_ = value; |
+ SchedulePaint(); |
} |
int Tab::GetWidthOfLargestSelectableRegion() const { |
@@ -1265,10 +1233,7 @@ void Tab::PaintTabBackground(gfx::Canvas* canvas) { |
PaintTabBackgroundUsingFillId(canvas, true, kActiveTabFillId, |
has_custom_image, y_offset); |
} else { |
- if (pinned_title_change_animation_->is_animating()) |
- PaintInactiveTabBackgroundWithTitleChange(canvas); |
- else |
- PaintInactiveTabBackground(canvas); |
+ PaintInactiveTabBackground(canvas); |
const double throb_value = GetThrobValue(); |
if (throb_value > 0) { |
@@ -1281,45 +1246,6 @@ void Tab::PaintTabBackground(gfx::Canvas* canvas) { |
} |
} |
-void Tab::PaintInactiveTabBackgroundWithTitleChange(gfx::Canvas* canvas) { |
- const int kPinnedTitleChangeGradientRadius = 20; |
- const float radius = kPinnedTitleChangeGradientRadius; |
- double x = radius; |
- SkColor hover_color = |
- GetThemeProvider()->GetColor(ThemeProperties::COLOR_TOOLBAR); |
- if (pinned_title_change_animation_->current_part_index() == 0) { |
- x = pinned_title_change_animation_->CurrentValueBetween( |
- width() + radius - kPinnedTitleChangeInitialXOffset, radius); |
- } else if (pinned_title_change_animation_->current_part_index() == 2) { |
- x = pinned_title_change_animation_->CurrentValueBetween(radius, -radius); |
- const int alpha = |
- pinned_title_change_animation_->CurrentValueBetween(255, 0); |
- hover_color = SkColorSetA(hover_color, static_cast<SkAlpha>(alpha)); |
- } |
- SkPoint p; |
- p.set(SkDoubleToScalar(x), 0); |
- if (ui::MaterialDesignController::IsModeMaterial()) { |
- PaintInactiveTabBackground(canvas); |
- gfx::ScopedCanvas scoped_canvas(canvas); |
- const float scale = canvas->UndoDeviceScaleFactor(); |
- SkPath fill; |
- GetFillPath(scale, &fill); |
- canvas->ClipPath(fill, true); |
- p.scale(SkFloatToScalar(scale)); |
- DrawHighlight(canvas, p, SkFloatToScalar(radius * scale), hover_color); |
- } else { |
- gfx::Canvas background_canvas(size(), canvas->image_scale(), false); |
- PaintInactiveTabBackground(&background_canvas); |
- gfx::ImageSkia background_image(background_canvas.ExtractImageRep()); |
- canvas->DrawImageInt(background_image, 0, 0); |
- gfx::Canvas hover_canvas(size(), canvas->image_scale(), false); |
- DrawHighlight(&hover_canvas, p, SkFloatToScalar(radius), hover_color); |
- gfx::ImageSkia hover_image = gfx::ImageSkiaOperations::CreateMaskedImage( |
- gfx::ImageSkia(hover_canvas.ExtractImageRep()), background_image); |
- canvas->DrawImageInt(hover_image, 0, 0); |
- } |
-} |
- |
void Tab::PaintInactiveTabBackground(gfx::Canvas* canvas) { |
bool has_custom_image; |
int fill_id = controller_->GetBackgroundResourceId(&has_custom_image); |
@@ -1492,6 +1418,50 @@ void Tab::PaintTabFill(gfx::Canvas* canvas, |
height() - tab_insets.top() - toolbar_overlap); |
} |
+void Tab::PaintPinnedTabTitleChangedIndicatorAndIcon( |
+ gfx::Canvas* canvas, |
+ const gfx::ImageSkia& favicon, |
+ const gfx::Rect& favicon_bounds) { |
+ // The pinned tab title changed indicator consists of two parts: |
+ // . a clear (totally transparent) part over the bottom right (or left in rtl) |
+ // of the favicon. This is done by drawing the favicon to a canvas, then |
+ // drawing the clear part on top of the favicon. |
+ // . a circle in the bottom right (or left in rtl) of the favicon. |
+ if (!favicon.isNull()) { |
+ const float kIndicatorCropRadius = 4.5; |
+ gfx::Canvas icon_canvas(gfx::Size(gfx::kFaviconSize, gfx::kFaviconSize), |
+ canvas->image_scale(), false); |
+ icon_canvas.DrawImageInt(favicon, 0, 0); |
+ SkPaint clear_paint; |
+ clear_paint.setAntiAlias(true); |
+ clear_paint.setStyle(SkPaint::kFill_Style); |
+ clear_paint.setXfermodeMode(SkXfermode::kClear_Mode); |
+ const int circle_x = base::i18n::IsRTL() ? 0 : gfx::kFaviconSize; |
+ icon_canvas.DrawCircle(gfx::PointF(circle_x, gfx::kFaviconSize), |
+ kIndicatorCropRadius, clear_paint); |
+ canvas->DrawImageInt(gfx::ImageSkia(icon_canvas.ExtractImageRep()), 0, 0, |
+ favicon_bounds.width(), favicon_bounds.height(), |
+ favicon_bounds.x(), favicon_bounds.y(), |
+ favicon_bounds.width(), favicon_bounds.height(), |
+ false); |
+ } |
+ |
+ // Draws the actual pinned tab title changed indicator. |
+ const int kIndicatorRadius = 3; |
+ SkPaint indicator_paint; |
+ indicator_paint.setColor(GetNativeTheme()->GetSystemColor( |
+ ui::NativeTheme::kColorId_CallToActionColor)); |
+ indicator_paint.setAntiAlias(true); |
+ indicator_paint.setStyle(SkPaint::kFill_Style); |
+ indicator_paint.setXfermodeMode(SkXfermode::kSrcOver_Mode); |
Evan Stade
2016/06/24 17:58:13
Fill and SrcOver are the defaults I believe. Did y
sky
2016/06/24 18:16:31
Mostly because knowing the defaults requires looki
|
+ const int indicator_x = GetMirroredXWithWidthInView( |
Evan Stade
2016/06/24 17:58:13
I'm unclear why this x/y calculation isn't the sam
sky
2016/06/24 18:16:31
They are centered on the same absolute point, but
Evan Stade
2016/06/24 18:32:31
ah, I missed that you're still using ExtractImageR
|
+ favicon_bounds_.right() - kIndicatorRadius, kIndicatorRadius * 2); |
Evan Stade
2016/06/24 17:58:13
confusing that favicon_bounds != favicon_bounds_
sky
2016/06/24 18:16:31
Ya, that is confusing. Renamed to favicon_draw_bou
|
+ const int indicator_y = favicon_bounds_.bottom() - kIndicatorRadius; |
+ canvas->DrawCircle(gfx::Point(indicator_x + kIndicatorRadius, |
+ indicator_y + kIndicatorRadius), |
+ kIndicatorRadius, indicator_paint); |
+} |
+ |
void Tab::PaintIcon(gfx::Canvas* canvas) { |
gfx::Rect bounds = favicon_bounds_; |
bounds.set_x(GetMirroredXForRect(bounds)); |
@@ -1502,16 +1472,21 @@ void Tab::PaintIcon(gfx::Canvas* canvas) { |
if (data().network_state != TabRendererData::NETWORK_STATE_NONE) { |
// Throbber will do its own painting. |
- } else { |
- const gfx::ImageSkia& favicon = should_display_crashed_favicon_ ? |
- *ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed( |
- IDR_CRASH_SAD_FAVICON) : |
- data().favicon; |
- if (!favicon.isNull()) { |
- canvas->DrawImageInt(favicon, 0, 0, bounds.width(), bounds.height(), |
- bounds.x(), bounds.y(), bounds.width(), |
- bounds.height(), false); |
- } |
+ return; |
+ } |
+ const gfx::ImageSkia& favicon = |
+ should_display_crashed_favicon_ |
+ ? *ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed( |
+ IDR_CRASH_SAD_FAVICON) |
+ : data().favicon; |
+ |
+ if (showing_pinned_tab_title_changed_indicator_ && |
+ !should_display_crashed_favicon_) { |
+ PaintPinnedTabTitleChangedIndicatorAndIcon(canvas, favicon, bounds); |
+ } else if (!favicon.isNull()) { |
+ canvas->DrawImageInt(favicon, 0, 0, bounds.width(), bounds.height(), |
+ bounds.x(), bounds.y(), bounds.width(), |
+ bounds.height(), false); |
} |
} |
@@ -1616,14 +1591,10 @@ double Tab::GetThrobValue() { |
const double offset = |
is_selected ? (kSelectedTabThrobScale * kHoverOpacity) : kHoverOpacity; |
- // Showing both the pulse and title change animation at the same time is too |
- // much. |
- if (pulse_animation_->is_animating() && |
- !pinned_title_change_animation_->is_animating()) { |
+ if (pulse_animation_->is_animating()) |
val += pulse_animation_->GetCurrentValue() * offset; |
- } else if (hover_controller_.ShouldDraw()) { |
+ else if (hover_controller_.ShouldDraw()) |
val += hover_controller_.GetAnimationValue() * offset; |
- } |
return val; |
} |