OLD | NEW |
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 <stddef.h> | 7 #include <stddef.h> |
8 #include <limits> | 8 #include <limits> |
9 #include <utility> | 9 #include <utility> |
10 | 10 |
(...skipping 19 matching lines...) Expand all Loading... |
30 #include "grit/theme_resources.h" | 30 #include "grit/theme_resources.h" |
31 #include "third_party/skia/include/effects/SkGradientShader.h" | 31 #include "third_party/skia/include/effects/SkGradientShader.h" |
32 #include "third_party/skia/include/pathops/SkPathOps.h" | 32 #include "third_party/skia/include/pathops/SkPathOps.h" |
33 #include "ui/accessibility/ax_view_state.h" | 33 #include "ui/accessibility/ax_view_state.h" |
34 #include "ui/base/l10n/l10n_util.h" | 34 #include "ui/base/l10n/l10n_util.h" |
35 #include "ui/base/material_design/material_design_controller.h" | 35 #include "ui/base/material_design/material_design_controller.h" |
36 #include "ui/base/models/list_selection_model.h" | 36 #include "ui/base/models/list_selection_model.h" |
37 #include "ui/base/resource/resource_bundle.h" | 37 #include "ui/base/resource/resource_bundle.h" |
38 #include "ui/base/theme_provider.h" | 38 #include "ui/base/theme_provider.h" |
39 #include "ui/gfx/animation/animation_container.h" | 39 #include "ui/gfx/animation/animation_container.h" |
40 #include "ui/gfx/animation/multi_animation.h" | |
41 #include "ui/gfx/animation/throb_animation.h" | 40 #include "ui/gfx/animation/throb_animation.h" |
42 #include "ui/gfx/canvas.h" | 41 #include "ui/gfx/canvas.h" |
43 #include "ui/gfx/color_analysis.h" | 42 #include "ui/gfx/color_analysis.h" |
44 #include "ui/gfx/favicon_size.h" | 43 #include "ui/gfx/favicon_size.h" |
45 #include "ui/gfx/geometry/rect_conversions.h" | 44 #include "ui/gfx/geometry/rect_conversions.h" |
46 #include "ui/gfx/image/image_skia_operations.h" | 45 #include "ui/gfx/image/image_skia_operations.h" |
47 #include "ui/gfx/paint_vector_icon.h" | 46 #include "ui/gfx/paint_vector_icon.h" |
48 #include "ui/gfx/path.h" | 47 #include "ui/gfx/path.h" |
49 #include "ui/gfx/scoped_canvas.h" | 48 #include "ui/gfx/scoped_canvas.h" |
50 #include "ui/gfx/skia_util.h" | 49 #include "ui/gfx/skia_util.h" |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
82 | 81 |
83 // How opaque to make the hover state (out of 1). | 82 // How opaque to make the hover state (out of 1). |
84 const double kHoverOpacity = 0.33; | 83 const double kHoverOpacity = 0.33; |
85 | 84 |
86 // Opacity of the active tab background painted over inactive selected tabs. | 85 // Opacity of the active tab background painted over inactive selected tabs. |
87 const double kSelectedTabOpacity = 0.3; | 86 const double kSelectedTabOpacity = 0.3; |
88 | 87 |
89 // Inactive selected tabs have their throb value scaled by this. | 88 // Inactive selected tabs have their throb value scaled by this. |
90 const double kSelectedTabThrobScale = 0.95 - kSelectedTabOpacity; | 89 const double kSelectedTabThrobScale = 0.95 - kSelectedTabOpacity; |
91 | 90 |
92 // Offset from the right edge for the start of the pinned title change | |
93 // animation. | |
94 const int kPinnedTitleChangeInitialXOffset = 6; | |
95 | |
96 // Max number of images to cache. This has to be at least two since rounding | 91 // Max number of images to cache. This has to be at least two since rounding |
97 // errors may lead to tabs in the same tabstrip having different sizes. | 92 // errors may lead to tabs in the same tabstrip having different sizes. |
98 // 8 = normal/incognito, active/inactive, 2 sizes within tabstrip. | 93 // 8 = normal/incognito, active/inactive, 2 sizes within tabstrip. |
99 const size_t kMaxImageCacheSize = 8; | 94 const size_t kMaxImageCacheSize = 8; |
100 | 95 |
101 // Height of the miniature tab strip in immersive mode. | 96 // Height of the miniature tab strip in immersive mode. |
102 const int kImmersiveTabHeight = 3; | 97 const int kImmersiveTabHeight = 3; |
103 | 98 |
104 // Height of the small tab indicator rectangles in immersive mode. | 99 // Height of the small tab indicator rectangles in immersive mode. |
105 const int kImmersiveBarHeight = 2; | 100 const int kImmersiveBarHeight = 2; |
(...skipping 21 matching lines...) Expand all Loading... |
127 float GetUnscaledEndcapWidth() { | 122 float GetUnscaledEndcapWidth() { |
128 return GetLayoutInsets(TAB).left() - 0.5f; | 123 return GetLayoutInsets(TAB).left() - 0.5f; |
129 } | 124 } |
130 | 125 |
131 void DrawHighlight(gfx::Canvas* canvas, | 126 void DrawHighlight(gfx::Canvas* canvas, |
132 const SkPoint& p, | 127 const SkPoint& p, |
133 SkScalar radius, | 128 SkScalar radius, |
134 SkColor color) { | 129 SkColor color) { |
135 const SkColor colors[2] = { color, SkColorSetA(color, 0) }; | 130 const SkColor colors[2] = { color, SkColorSetA(color, 0) }; |
136 SkPaint paint; | 131 SkPaint paint; |
137 paint.setStyle(SkPaint::kFill_Style); | |
138 paint.setAntiAlias(true); | 132 paint.setAntiAlias(true); |
139 paint.setShader(SkGradientShader::MakeRadial(p, radius, colors, nullptr, 2, | 133 paint.setShader(SkGradientShader::MakeRadial(p, radius, colors, nullptr, 2, |
140 SkShader::kClamp_TileMode)); | 134 SkShader::kClamp_TileMode)); |
141 canvas->sk_canvas()->drawRect( | 135 canvas->sk_canvas()->drawRect( |
142 SkRect::MakeXYWH(p.x() - radius, p.y() - radius, radius * 2, radius * 2), | 136 SkRect::MakeXYWH(p.x() - radius, p.y() - radius, radius * 2, radius * 2), |
143 paint); | 137 paint); |
144 } | 138 } |
145 | 139 |
146 } // namespace | 140 } // namespace |
147 | 141 |
(...skipping 411 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
559 // to help avoid mis-clicks. | 553 // to help avoid mis-clicks. |
560 close_button_->SetAnimationDuration(0); | 554 close_button_->SetAnimationDuration(0); |
561 AddChildView(close_button_); | 555 AddChildView(close_button_); |
562 | 556 |
563 set_context_menu_controller(this); | 557 set_context_menu_controller(this); |
564 | 558 |
565 const int kPulseDurationMs = 200; | 559 const int kPulseDurationMs = 200; |
566 pulse_animation_->SetSlideDuration(kPulseDurationMs); | 560 pulse_animation_->SetSlideDuration(kPulseDurationMs); |
567 pulse_animation_->SetContainer(animation_container_.get()); | 561 pulse_animation_->SetContainer(animation_container_.get()); |
568 | 562 |
569 const int kPinnedTitleChangeAnimationDuration1MS = 1600; | |
570 const int kPinnedTitleChangeAnimationStart1MS = 0; | |
571 const int kPinnedTitleChangeAnimationEnd1MS = 1900; | |
572 const int kPinnedTitleChangeAnimationDuration2MS = 0; | |
573 const int kPinnedTitleChangeAnimationDuration3MS = 550; | |
574 const int kPinnedTitleChangeAnimationStart3MS = 150; | |
575 const int kPinnedTitleChangeAnimationEnd3MS = 800; | |
576 const int kPinnedTitleChangeAnimationIntervalMS = 40; | |
577 gfx::MultiAnimation::Parts parts; | |
578 parts.push_back(gfx::MultiAnimation::Part( | |
579 kPinnedTitleChangeAnimationDuration1MS, | |
580 kPinnedTitleChangeAnimationStart1MS, | |
581 kPinnedTitleChangeAnimationEnd1MS, | |
582 gfx::Tween::EASE_OUT)); | |
583 parts.push_back(gfx::MultiAnimation::Part( | |
584 kPinnedTitleChangeAnimationDuration2MS, | |
585 gfx::Tween::ZERO)); | |
586 parts.push_back(gfx::MultiAnimation::Part( | |
587 kPinnedTitleChangeAnimationDuration3MS, | |
588 kPinnedTitleChangeAnimationStart3MS, | |
589 kPinnedTitleChangeAnimationEnd3MS, | |
590 gfx::Tween::EASE_IN)); | |
591 const base::TimeDelta timeout = | |
592 base::TimeDelta::FromMilliseconds(kPinnedTitleChangeAnimationIntervalMS); | |
593 pinned_title_change_animation_.reset(new gfx::MultiAnimation(parts, timeout)); | |
594 pinned_title_change_animation_->SetContainer(animation_container_.get()); | |
595 pinned_title_change_animation_->set_delegate(this); | |
596 | |
597 hover_controller_.SetAnimationContainer(animation_container_.get()); | 563 hover_controller_.SetAnimationContainer(animation_container_.get()); |
598 } | 564 } |
599 | 565 |
600 Tab::~Tab() { | 566 Tab::~Tab() { |
601 } | 567 } |
602 | 568 |
603 bool Tab::IsActive() const { | 569 bool Tab::IsActive() const { |
604 return controller_->IsActiveTab(this); | 570 return controller_->IsActiveTab(this); |
605 } | 571 } |
606 | 572 |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
645 } else if (!should_display_crashed_favicon_ && | 611 } else if (!should_display_crashed_favicon_ && |
646 !crash_icon_animation_->is_animating()) { | 612 !crash_icon_animation_->is_animating()) { |
647 data_.alert_state = TabAlertState::NONE; | 613 data_.alert_state = TabAlertState::NONE; |
648 crash_icon_animation_->Start(); | 614 crash_icon_animation_->Start(); |
649 } | 615 } |
650 | 616 |
651 if (data_.alert_state != old.alert_state) | 617 if (data_.alert_state != old.alert_state) |
652 alert_indicator_button_->TransitionToAlertState(data_.alert_state); | 618 alert_indicator_button_->TransitionToAlertState(data_.alert_state); |
653 | 619 |
654 if (old.pinned != data_.pinned) | 620 if (old.pinned != data_.pinned) |
655 StopPinnedTabTitleAnimation(); | 621 showing_pinned_tab_title_changed_indicator_ = false; |
656 | 622 |
657 DataChanged(old); | 623 DataChanged(old); |
658 | 624 |
659 Layout(); | 625 Layout(); |
660 SchedulePaint(); | 626 SchedulePaint(); |
661 } | 627 } |
662 | 628 |
663 void Tab::UpdateLoadingAnimation(TabRendererData::NetworkState state) { | 629 void Tab::UpdateLoadingAnimation(TabRendererData::NetworkState state) { |
664 if (state == data_.network_state && | 630 if (state == data_.network_state && |
665 state == TabRendererData::NETWORK_STATE_NONE) { | 631 state == TabRendererData::NETWORK_STATE_NONE) { |
666 // If the network state is none and hasn't changed, do nothing. Otherwise we | 632 // If the network state is none and hasn't changed, do nothing. Otherwise we |
667 // need to advance the animation frame. | 633 // need to advance the animation frame. |
668 return; | 634 return; |
669 } | 635 } |
670 | 636 |
671 data_.network_state = state; | 637 data_.network_state = state; |
672 AdvanceLoadingAnimation(); | 638 AdvanceLoadingAnimation(); |
673 } | 639 } |
674 | 640 |
675 void Tab::StartPulse() { | 641 void Tab::StartPulse() { |
676 pulse_animation_->StartThrobbing(std::numeric_limits<int>::max()); | 642 pulse_animation_->StartThrobbing(std::numeric_limits<int>::max()); |
677 } | 643 } |
678 | 644 |
679 void Tab::StopPulse() { | 645 void Tab::StopPulse() { |
680 pulse_animation_->Stop(); | 646 pulse_animation_->Stop(); |
681 } | 647 } |
682 | 648 |
683 void Tab::StartPinnedTabTitleAnimation() { | 649 void Tab::SetPinnedTabTitleChangedIndicatorVisible(bool value) { |
684 if (data().pinned) | 650 if (value == showing_pinned_tab_title_changed_indicator_) |
685 pinned_title_change_animation_->Start(); | 651 return; |
686 } | |
687 | 652 |
688 void Tab::StopPinnedTabTitleAnimation() { | 653 DCHECK(!value || data().pinned); |
689 pinned_title_change_animation_->Stop(); | 654 |
| 655 showing_pinned_tab_title_changed_indicator_ = value; |
| 656 SchedulePaint(); |
690 } | 657 } |
691 | 658 |
692 int Tab::GetWidthOfLargestSelectableRegion() const { | 659 int Tab::GetWidthOfLargestSelectableRegion() const { |
693 // Assume the entire region to the left of the alert indicator and/or close | 660 // Assume the entire region to the left of the alert indicator and/or close |
694 // buttons is available for click-to-select. If neither are visible, the | 661 // buttons is available for click-to-select. If neither are visible, the |
695 // entire tab region is available. | 662 // entire tab region is available. |
696 const int indicator_left = | 663 const int indicator_left = |
697 showing_alert_indicator_ ? alert_indicator_button_->x() : width(); | 664 showing_alert_indicator_ ? alert_indicator_button_->x() : width(); |
698 const int close_button_left = showing_close_button_ ? | 665 const int close_button_left = showing_close_button_ ? |
699 close_button_->x() : width(); | 666 close_button_->x() : width(); |
(...skipping 558 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1258 | 1225 |
1259 void Tab::PaintTabBackground(gfx::Canvas* canvas) { | 1226 void Tab::PaintTabBackground(gfx::Canvas* canvas) { |
1260 const int kActiveTabFillId = IDR_THEME_TOOLBAR; | 1227 const int kActiveTabFillId = IDR_THEME_TOOLBAR; |
1261 const bool has_custom_image = | 1228 const bool has_custom_image = |
1262 GetThemeProvider()->HasCustomImage(kActiveTabFillId); | 1229 GetThemeProvider()->HasCustomImage(kActiveTabFillId); |
1263 const int y_offset = -GetYInsetForActiveTabBackground(); | 1230 const int y_offset = -GetYInsetForActiveTabBackground(); |
1264 if (IsActive()) { | 1231 if (IsActive()) { |
1265 PaintTabBackgroundUsingFillId(canvas, true, kActiveTabFillId, | 1232 PaintTabBackgroundUsingFillId(canvas, true, kActiveTabFillId, |
1266 has_custom_image, y_offset); | 1233 has_custom_image, y_offset); |
1267 } else { | 1234 } else { |
1268 if (pinned_title_change_animation_->is_animating()) | 1235 PaintInactiveTabBackground(canvas); |
1269 PaintInactiveTabBackgroundWithTitleChange(canvas); | |
1270 else | |
1271 PaintInactiveTabBackground(canvas); | |
1272 | 1236 |
1273 const double throb_value = GetThrobValue(); | 1237 const double throb_value = GetThrobValue(); |
1274 if (throb_value > 0) { | 1238 if (throb_value > 0) { |
1275 canvas->SaveLayerAlpha(gfx::ToRoundedInt(throb_value * 0xff), | 1239 canvas->SaveLayerAlpha(gfx::ToRoundedInt(throb_value * 0xff), |
1276 GetLocalBounds()); | 1240 GetLocalBounds()); |
1277 PaintTabBackgroundUsingFillId(canvas, true, kActiveTabFillId, | 1241 PaintTabBackgroundUsingFillId(canvas, true, kActiveTabFillId, |
1278 has_custom_image, y_offset); | 1242 has_custom_image, y_offset); |
1279 canvas->Restore(); | 1243 canvas->Restore(); |
1280 } | 1244 } |
1281 } | 1245 } |
1282 } | 1246 } |
1283 | 1247 |
1284 void Tab::PaintInactiveTabBackgroundWithTitleChange(gfx::Canvas* canvas) { | |
1285 const int kPinnedTitleChangeGradientRadius = 20; | |
1286 const float radius = kPinnedTitleChangeGradientRadius; | |
1287 double x = radius; | |
1288 SkColor hover_color = | |
1289 GetThemeProvider()->GetColor(ThemeProperties::COLOR_TOOLBAR); | |
1290 if (pinned_title_change_animation_->current_part_index() == 0) { | |
1291 x = pinned_title_change_animation_->CurrentValueBetween( | |
1292 width() + radius - kPinnedTitleChangeInitialXOffset, radius); | |
1293 } else if (pinned_title_change_animation_->current_part_index() == 2) { | |
1294 x = pinned_title_change_animation_->CurrentValueBetween(radius, -radius); | |
1295 const int alpha = | |
1296 pinned_title_change_animation_->CurrentValueBetween(255, 0); | |
1297 hover_color = SkColorSetA(hover_color, static_cast<SkAlpha>(alpha)); | |
1298 } | |
1299 SkPoint p; | |
1300 p.set(SkDoubleToScalar(x), 0); | |
1301 if (ui::MaterialDesignController::IsModeMaterial()) { | |
1302 PaintInactiveTabBackground(canvas); | |
1303 gfx::ScopedCanvas scoped_canvas(canvas); | |
1304 const float scale = canvas->UndoDeviceScaleFactor(); | |
1305 SkPath fill; | |
1306 GetFillPath(scale, &fill); | |
1307 canvas->ClipPath(fill, true); | |
1308 p.scale(SkFloatToScalar(scale)); | |
1309 DrawHighlight(canvas, p, SkFloatToScalar(radius * scale), hover_color); | |
1310 } else { | |
1311 gfx::Canvas background_canvas(size(), canvas->image_scale(), false); | |
1312 PaintInactiveTabBackground(&background_canvas); | |
1313 gfx::ImageSkia background_image(background_canvas.ExtractImageRep()); | |
1314 canvas->DrawImageInt(background_image, 0, 0); | |
1315 gfx::Canvas hover_canvas(size(), canvas->image_scale(), false); | |
1316 DrawHighlight(&hover_canvas, p, SkFloatToScalar(radius), hover_color); | |
1317 gfx::ImageSkia hover_image = gfx::ImageSkiaOperations::CreateMaskedImage( | |
1318 gfx::ImageSkia(hover_canvas.ExtractImageRep()), background_image); | |
1319 canvas->DrawImageInt(hover_image, 0, 0); | |
1320 } | |
1321 } | |
1322 | |
1323 void Tab::PaintInactiveTabBackground(gfx::Canvas* canvas) { | 1248 void Tab::PaintInactiveTabBackground(gfx::Canvas* canvas) { |
1324 bool has_custom_image; | 1249 bool has_custom_image; |
1325 int fill_id = controller_->GetBackgroundResourceId(&has_custom_image); | 1250 int fill_id = controller_->GetBackgroundResourceId(&has_custom_image); |
1326 | 1251 |
1327 // If the theme is providing a custom background image, then its top edge | 1252 // If the theme is providing a custom background image, then its top edge |
1328 // should be at the top of the tab. Otherwise, we assume that the background | 1253 // should be at the top of the tab. Otherwise, we assume that the background |
1329 // image is a composited foreground + frame image. Note that if the theme is | 1254 // image is a composited foreground + frame image. Note that if the theme is |
1330 // only providing a custom frame image, |has_custom_image| will be true, but | 1255 // only providing a custom frame image, |has_custom_image| will be true, but |
1331 // we should use the |background_offset_| here. | 1256 // we should use the |background_offset_| here. |
1332 const ui::ThemeProvider* tp = GetThemeProvider(); | 1257 const ui::ThemeProvider* tp = GetThemeProvider(); |
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1485 | 1410 |
1486 // Draw center. Instead of masking out the top portion we simply skip over it | 1411 // Draw center. Instead of masking out the top portion we simply skip over it |
1487 // by incrementing by the top padding, since it's a simple rectangle. | 1412 // by incrementing by the top padding, since it's a simple rectangle. |
1488 canvas->TileImageInt(*fill_image, x_offset + mask_images_.l_width, | 1413 canvas->TileImageInt(*fill_image, x_offset + mask_images_.l_width, |
1489 y_offset + tab_insets.top(), mask_images_.l_width, | 1414 y_offset + tab_insets.top(), mask_images_.l_width, |
1490 tab_insets.top(), | 1415 tab_insets.top(), |
1491 width() - mask_images_.l_width - mask_images_.r_width, | 1416 width() - mask_images_.l_width - mask_images_.r_width, |
1492 height() - tab_insets.top() - toolbar_overlap); | 1417 height() - tab_insets.top() - toolbar_overlap); |
1493 } | 1418 } |
1494 | 1419 |
| 1420 void Tab::PaintPinnedTabTitleChangedIndicatorAndIcon( |
| 1421 gfx::Canvas* canvas, |
| 1422 const gfx::ImageSkia& favicon, |
| 1423 const gfx::Rect& favicon_draw_bounds) { |
| 1424 // The pinned tab title changed indicator consists of two parts: |
| 1425 // . a clear (totally transparent) part over the bottom right (or left in rtl) |
| 1426 // of the favicon. This is done by drawing the favicon to a canvas, then |
| 1427 // drawing the clear part on top of the favicon. |
| 1428 // . a circle in the bottom right (or left in rtl) of the favicon. |
| 1429 if (!favicon.isNull()) { |
| 1430 const float kIndicatorCropRadius = 4.5; |
| 1431 gfx::Canvas icon_canvas(gfx::Size(gfx::kFaviconSize, gfx::kFaviconSize), |
| 1432 canvas->image_scale(), false); |
| 1433 icon_canvas.DrawImageInt(favicon, 0, 0); |
| 1434 SkPaint clear_paint; |
| 1435 clear_paint.setAntiAlias(true); |
| 1436 clear_paint.setXfermodeMode(SkXfermode::kClear_Mode); |
| 1437 const int circle_x = base::i18n::IsRTL() ? 0 : gfx::kFaviconSize; |
| 1438 icon_canvas.DrawCircle(gfx::PointF(circle_x, gfx::kFaviconSize), |
| 1439 kIndicatorCropRadius, clear_paint); |
| 1440 canvas->DrawImageInt(gfx::ImageSkia(icon_canvas.ExtractImageRep()), 0, 0, |
| 1441 favicon_draw_bounds.width(), |
| 1442 favicon_draw_bounds.height(), favicon_draw_bounds.x(), |
| 1443 favicon_draw_bounds.y(), favicon_draw_bounds.width(), |
| 1444 favicon_draw_bounds.height(), false); |
| 1445 } |
| 1446 |
| 1447 // Draws the actual pinned tab title changed indicator. |
| 1448 const int kIndicatorRadius = 3; |
| 1449 SkPaint indicator_paint; |
| 1450 indicator_paint.setColor(GetNativeTheme()->GetSystemColor( |
| 1451 ui::NativeTheme::kColorId_CallToActionColor)); |
| 1452 indicator_paint.setAntiAlias(true); |
| 1453 const int indicator_x = GetMirroredXWithWidthInView( |
| 1454 favicon_bounds_.right() - kIndicatorRadius, kIndicatorRadius * 2); |
| 1455 const int indicator_y = favicon_bounds_.bottom() - kIndicatorRadius; |
| 1456 canvas->DrawCircle(gfx::Point(indicator_x + kIndicatorRadius, |
| 1457 indicator_y + kIndicatorRadius), |
| 1458 kIndicatorRadius, indicator_paint); |
| 1459 } |
| 1460 |
1495 void Tab::PaintIcon(gfx::Canvas* canvas) { | 1461 void Tab::PaintIcon(gfx::Canvas* canvas) { |
1496 gfx::Rect bounds = favicon_bounds_; | 1462 gfx::Rect bounds = favicon_bounds_; |
1497 bounds.set_x(GetMirroredXForRect(bounds)); | 1463 bounds.set_x(GetMirroredXForRect(bounds)); |
1498 bounds.Offset(0, favicon_hiding_offset_); | 1464 bounds.Offset(0, favicon_hiding_offset_); |
1499 bounds.Intersect(GetContentsBounds()); | 1465 bounds.Intersect(GetContentsBounds()); |
1500 if (bounds.IsEmpty()) | 1466 if (bounds.IsEmpty()) |
1501 return; | 1467 return; |
1502 | 1468 |
1503 if (data().network_state != TabRendererData::NETWORK_STATE_NONE) { | 1469 if (data().network_state != TabRendererData::NETWORK_STATE_NONE) { |
1504 // Throbber will do its own painting. | 1470 // Throbber will do its own painting. |
1505 } else { | 1471 return; |
1506 const gfx::ImageSkia& favicon = should_display_crashed_favicon_ ? | 1472 } |
1507 *ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed( | 1473 const gfx::ImageSkia& favicon = |
1508 IDR_CRASH_SAD_FAVICON) : | 1474 should_display_crashed_favicon_ |
1509 data().favicon; | 1475 ? *ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed( |
1510 if (!favicon.isNull()) { | 1476 IDR_CRASH_SAD_FAVICON) |
1511 canvas->DrawImageInt(favicon, 0, 0, bounds.width(), bounds.height(), | 1477 : data().favicon; |
1512 bounds.x(), bounds.y(), bounds.width(), | 1478 |
1513 bounds.height(), false); | 1479 if (showing_pinned_tab_title_changed_indicator_ && |
1514 } | 1480 !should_display_crashed_favicon_) { |
| 1481 PaintPinnedTabTitleChangedIndicatorAndIcon(canvas, favicon, bounds); |
| 1482 } else if (!favicon.isNull()) { |
| 1483 canvas->DrawImageInt(favicon, 0, 0, bounds.width(), bounds.height(), |
| 1484 bounds.x(), bounds.y(), bounds.width(), |
| 1485 bounds.height(), false); |
1515 } | 1486 } |
1516 } | 1487 } |
1517 | 1488 |
1518 void Tab::AdvanceLoadingAnimation() { | 1489 void Tab::AdvanceLoadingAnimation() { |
1519 const TabRendererData::NetworkState state = data().network_state; | 1490 const TabRendererData::NetworkState state = data().network_state; |
1520 if (controller_->IsImmersiveStyle()) { | 1491 if (controller_->IsImmersiveStyle()) { |
1521 throbber_->SetVisible(false); | 1492 throbber_->SetVisible(false); |
1522 if (state == TabRendererData::NETWORK_STATE_WAITING) { | 1493 if (state == TabRendererData::NETWORK_STATE_WAITING) { |
1523 // Waiting steps backwards. | 1494 // Waiting steps backwards. |
1524 immersive_loading_step_ = | 1495 immersive_loading_step_ = |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1609 return !data().pinned || | 1580 return !data().pinned || |
1610 (width() >= (GetPinnedWidth() + kPinnedTabExtraWidthToRenderAsNormal)); | 1581 (width() >= (GetPinnedWidth() + kPinnedTabExtraWidthToRenderAsNormal)); |
1611 } | 1582 } |
1612 | 1583 |
1613 double Tab::GetThrobValue() { | 1584 double Tab::GetThrobValue() { |
1614 const bool is_selected = IsSelected(); | 1585 const bool is_selected = IsSelected(); |
1615 double val = is_selected ? kSelectedTabOpacity : 0; | 1586 double val = is_selected ? kSelectedTabOpacity : 0; |
1616 const double offset = | 1587 const double offset = |
1617 is_selected ? (kSelectedTabThrobScale * kHoverOpacity) : kHoverOpacity; | 1588 is_selected ? (kSelectedTabThrobScale * kHoverOpacity) : kHoverOpacity; |
1618 | 1589 |
1619 // Showing both the pulse and title change animation at the same time is too | 1590 if (pulse_animation_->is_animating()) |
1620 // much. | |
1621 if (pulse_animation_->is_animating() && | |
1622 !pinned_title_change_animation_->is_animating()) { | |
1623 val += pulse_animation_->GetCurrentValue() * offset; | 1591 val += pulse_animation_->GetCurrentValue() * offset; |
1624 } else if (hover_controller_.ShouldDraw()) { | 1592 else if (hover_controller_.ShouldDraw()) |
1625 val += hover_controller_.GetAnimationValue() * offset; | 1593 val += hover_controller_.GetAnimationValue() * offset; |
1626 } | |
1627 return val; | 1594 return val; |
1628 } | 1595 } |
1629 | 1596 |
1630 void Tab::SetFaviconHidingOffset(int offset) { | 1597 void Tab::SetFaviconHidingOffset(int offset) { |
1631 favicon_hiding_offset_ = offset; | 1598 favicon_hiding_offset_ = offset; |
1632 ScheduleIconPaint(); | 1599 ScheduleIconPaint(); |
1633 } | 1600 } |
1634 | 1601 |
1635 void Tab::OnButtonColorMaybeChanged() { | 1602 void Tab::OnButtonColorMaybeChanged() { |
1636 // The theme provider may be null if we're not currently in a widget | 1603 // The theme provider may be null if we're not currently in a widget |
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1774 inactive_images_.image_c = rb.GetImageSkiaNamed(IDR_TAB_INACTIVE_CENTER); | 1741 inactive_images_.image_c = rb.GetImageSkiaNamed(IDR_TAB_INACTIVE_CENTER); |
1775 inactive_images_.image_r = rb.GetImageSkiaNamed(IDR_TAB_INACTIVE_RIGHT); | 1742 inactive_images_.image_r = rb.GetImageSkiaNamed(IDR_TAB_INACTIVE_RIGHT); |
1776 inactive_images_.l_width = inactive_images_.image_l->width(); | 1743 inactive_images_.l_width = inactive_images_.image_l->width(); |
1777 inactive_images_.r_width = inactive_images_.image_r->width(); | 1744 inactive_images_.r_width = inactive_images_.image_r->width(); |
1778 | 1745 |
1779 mask_images_.image_l = rb.GetImageSkiaNamed(IDR_TAB_ALPHA_LEFT); | 1746 mask_images_.image_l = rb.GetImageSkiaNamed(IDR_TAB_ALPHA_LEFT); |
1780 mask_images_.image_r = rb.GetImageSkiaNamed(IDR_TAB_ALPHA_RIGHT); | 1747 mask_images_.image_r = rb.GetImageSkiaNamed(IDR_TAB_ALPHA_RIGHT); |
1781 mask_images_.l_width = mask_images_.image_l->width(); | 1748 mask_images_.l_width = mask_images_.image_l->width(); |
1782 mask_images_.r_width = mask_images_.image_r->width(); | 1749 mask_images_.r_width = mask_images_.image_r->width(); |
1783 } | 1750 } |
OLD | NEW |