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 453 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
559 // to help avoid mis-clicks. | 554 // to help avoid mis-clicks. |
560 close_button_->SetAnimationDuration(0); | 555 close_button_->SetAnimationDuration(0); |
561 AddChildView(close_button_); | 556 AddChildView(close_button_); |
562 | 557 |
563 set_context_menu_controller(this); | 558 set_context_menu_controller(this); |
564 | 559 |
565 const int kPulseDurationMs = 200; | 560 const int kPulseDurationMs = 200; |
566 pulse_animation_->SetSlideDuration(kPulseDurationMs); | 561 pulse_animation_->SetSlideDuration(kPulseDurationMs); |
567 pulse_animation_->SetContainer(animation_container_.get()); | 562 pulse_animation_->SetContainer(animation_container_.get()); |
568 | 563 |
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()); | 564 hover_controller_.SetAnimationContainer(animation_container_.get()); |
598 } | 565 } |
599 | 566 |
600 Tab::~Tab() { | 567 Tab::~Tab() { |
601 } | 568 } |
602 | 569 |
603 bool Tab::IsActive() const { | 570 bool Tab::IsActive() const { |
604 return controller_->IsActiveTab(this); | 571 return controller_->IsActiveTab(this); |
605 } | 572 } |
606 | 573 |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
645 } else if (!should_display_crashed_favicon_ && | 612 } else if (!should_display_crashed_favicon_ && |
646 !crash_icon_animation_->is_animating()) { | 613 !crash_icon_animation_->is_animating()) { |
647 data_.alert_state = TabAlertState::NONE; | 614 data_.alert_state = TabAlertState::NONE; |
648 crash_icon_animation_->Start(); | 615 crash_icon_animation_->Start(); |
649 } | 616 } |
650 | 617 |
651 if (data_.alert_state != old.alert_state) | 618 if (data_.alert_state != old.alert_state) |
652 alert_indicator_button_->TransitionToAlertState(data_.alert_state); | 619 alert_indicator_button_->TransitionToAlertState(data_.alert_state); |
653 | 620 |
654 if (old.pinned != data_.pinned) | 621 if (old.pinned != data_.pinned) |
655 StopPinnedTabTitleAnimation(); | 622 showing_pinned_tab_title_changed_indicator_ = false; |
656 | 623 |
657 DataChanged(old); | 624 DataChanged(old); |
658 | 625 |
659 Layout(); | 626 Layout(); |
660 SchedulePaint(); | 627 SchedulePaint(); |
661 } | 628 } |
662 | 629 |
663 void Tab::UpdateLoadingAnimation(TabRendererData::NetworkState state) { | 630 void Tab::UpdateLoadingAnimation(TabRendererData::NetworkState state) { |
664 if (state == data_.network_state && | 631 if (state == data_.network_state && |
665 state == TabRendererData::NETWORK_STATE_NONE) { | 632 state == TabRendererData::NETWORK_STATE_NONE) { |
666 // If the network state is none and hasn't changed, do nothing. Otherwise we | 633 // If the network state is none and hasn't changed, do nothing. Otherwise we |
667 // need to advance the animation frame. | 634 // need to advance the animation frame. |
668 return; | 635 return; |
669 } | 636 } |
670 | 637 |
671 data_.network_state = state; | 638 data_.network_state = state; |
672 AdvanceLoadingAnimation(); | 639 AdvanceLoadingAnimation(); |
673 } | 640 } |
674 | 641 |
675 void Tab::StartPulse() { | 642 void Tab::StartPulse() { |
676 pulse_animation_->StartThrobbing(std::numeric_limits<int>::max()); | 643 pulse_animation_->StartThrobbing(std::numeric_limits<int>::max()); |
677 } | 644 } |
678 | 645 |
679 void Tab::StopPulse() { | 646 void Tab::StopPulse() { |
680 pulse_animation_->Stop(); | 647 pulse_animation_->Stop(); |
681 } | 648 } |
682 | 649 |
683 void Tab::StartPinnedTabTitleAnimation() { | 650 void Tab::SetPinnedTabTitleChangedIndicatorVisible(bool value) { |
684 if (data().pinned) | 651 if (value == showing_pinned_tab_title_changed_indicator_) |
685 pinned_title_change_animation_->Start(); | 652 return; |
686 } | |
687 | 653 |
688 void Tab::StopPinnedTabTitleAnimation() { | 654 DCHECK(!value || data().pinned); |
689 pinned_title_change_animation_->Stop(); | 655 |
656 showing_pinned_tab_title_changed_indicator_ = value; | |
657 SchedulePaint(); | |
690 } | 658 } |
691 | 659 |
692 int Tab::GetWidthOfLargestSelectableRegion() const { | 660 int Tab::GetWidthOfLargestSelectableRegion() const { |
693 // Assume the entire region to the left of the alert indicator and/or close | 661 // 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 | 662 // buttons is available for click-to-select. If neither are visible, the |
695 // entire tab region is available. | 663 // entire tab region is available. |
696 const int indicator_left = | 664 const int indicator_left = |
697 showing_alert_indicator_ ? alert_indicator_button_->x() : width(); | 665 showing_alert_indicator_ ? alert_indicator_button_->x() : width(); |
698 const int close_button_left = showing_close_button_ ? | 666 const int close_button_left = showing_close_button_ ? |
699 close_button_->x() : width(); | 667 close_button_->x() : width(); |
(...skipping 558 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1258 | 1226 |
1259 void Tab::PaintTabBackground(gfx::Canvas* canvas) { | 1227 void Tab::PaintTabBackground(gfx::Canvas* canvas) { |
1260 const int kActiveTabFillId = IDR_THEME_TOOLBAR; | 1228 const int kActiveTabFillId = IDR_THEME_TOOLBAR; |
1261 const bool has_custom_image = | 1229 const bool has_custom_image = |
1262 GetThemeProvider()->HasCustomImage(kActiveTabFillId); | 1230 GetThemeProvider()->HasCustomImage(kActiveTabFillId); |
1263 const int y_offset = -GetYInsetForActiveTabBackground(); | 1231 const int y_offset = -GetYInsetForActiveTabBackground(); |
1264 if (IsActive()) { | 1232 if (IsActive()) { |
1265 PaintTabBackgroundUsingFillId(canvas, true, kActiveTabFillId, | 1233 PaintTabBackgroundUsingFillId(canvas, true, kActiveTabFillId, |
1266 has_custom_image, y_offset); | 1234 has_custom_image, y_offset); |
1267 } else { | 1235 } else { |
1268 if (pinned_title_change_animation_->is_animating()) | 1236 PaintInactiveTabBackground(canvas); |
1269 PaintInactiveTabBackgroundWithTitleChange(canvas); | |
1270 else | |
1271 PaintInactiveTabBackground(canvas); | |
1272 | 1237 |
1273 const double throb_value = GetThrobValue(); | 1238 const double throb_value = GetThrobValue(); |
1274 if (throb_value > 0) { | 1239 if (throb_value > 0) { |
1275 canvas->SaveLayerAlpha(gfx::ToRoundedInt(throb_value * 0xff), | 1240 canvas->SaveLayerAlpha(gfx::ToRoundedInt(throb_value * 0xff), |
1276 GetLocalBounds()); | 1241 GetLocalBounds()); |
1277 PaintTabBackgroundUsingFillId(canvas, true, kActiveTabFillId, | 1242 PaintTabBackgroundUsingFillId(canvas, true, kActiveTabFillId, |
1278 has_custom_image, y_offset); | 1243 has_custom_image, y_offset); |
1279 canvas->Restore(); | 1244 canvas->Restore(); |
1280 } | 1245 } |
1281 } | 1246 } |
1282 } | 1247 } |
1283 | 1248 |
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) { | 1249 void Tab::PaintInactiveTabBackground(gfx::Canvas* canvas) { |
1324 bool has_custom_image; | 1250 bool has_custom_image; |
1325 int fill_id = controller_->GetBackgroundResourceId(&has_custom_image); | 1251 int fill_id = controller_->GetBackgroundResourceId(&has_custom_image); |
1326 | 1252 |
1327 // If the theme is providing a custom background image, then its top edge | 1253 // 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 | 1254 // 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 | 1255 // 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 | 1256 // only providing a custom frame image, |has_custom_image| will be true, but |
1331 // we should use the |background_offset_| here. | 1257 // we should use the |background_offset_| here. |
1332 const ui::ThemeProvider* tp = GetThemeProvider(); | 1258 const ui::ThemeProvider* tp = GetThemeProvider(); |
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1485 | 1411 |
1486 // Draw center. Instead of masking out the top portion we simply skip over it | 1412 // 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. | 1413 // by incrementing by the top padding, since it's a simple rectangle. |
1488 canvas->TileImageInt(*fill_image, x_offset + mask_images_.l_width, | 1414 canvas->TileImageInt(*fill_image, x_offset + mask_images_.l_width, |
1489 y_offset + tab_insets.top(), mask_images_.l_width, | 1415 y_offset + tab_insets.top(), mask_images_.l_width, |
1490 tab_insets.top(), | 1416 tab_insets.top(), |
1491 width() - mask_images_.l_width - mask_images_.r_width, | 1417 width() - mask_images_.l_width - mask_images_.r_width, |
1492 height() - tab_insets.top() - toolbar_overlap); | 1418 height() - tab_insets.top() - toolbar_overlap); |
1493 } | 1419 } |
1494 | 1420 |
1421 void Tab::PaintPinnedTabTitleChangedIndicatorAndIcon( | |
1422 gfx::Canvas* canvas, | |
1423 const gfx::ImageSkia& favicon, | |
1424 const gfx::Rect& favicon_bounds) { | |
1425 // The pinned tab title changed indicator consists of two parts: | |
1426 // . a clear (totally transparent) part over the bottom right (or left in rtl) | |
1427 // of the favicon. This is done by drawing the favicon to a canvas, then | |
1428 // drawing the clear part on top of the favicon. | |
1429 // . a circle in the bottom right (or left in rtl) of the favicon. | |
1430 if (!favicon.isNull()) { | |
1431 const float kIndicatorCropRadius = 4.5; | |
1432 gfx::Canvas icon_canvas(gfx::Size(gfx::kFaviconSize, gfx::kFaviconSize), | |
1433 canvas->image_scale(), false); | |
1434 icon_canvas.DrawImageInt(favicon, 0, 0); | |
1435 SkPaint clear_paint; | |
1436 clear_paint.setAntiAlias(true); | |
1437 clear_paint.setStyle(SkPaint::kFill_Style); | |
1438 clear_paint.setXfermodeMode(SkXfermode::kClear_Mode); | |
1439 const int circle_x = base::i18n::IsRTL() ? 0 : gfx::kFaviconSize; | |
1440 icon_canvas.DrawCircle(gfx::PointF(circle_x, gfx::kFaviconSize), | |
1441 kIndicatorCropRadius, clear_paint); | |
1442 canvas->DrawImageInt(gfx::ImageSkia(icon_canvas.ExtractImageRep()), 0, 0, | |
1443 favicon_bounds.width(), favicon_bounds.height(), | |
1444 favicon_bounds.x(), favicon_bounds.y(), | |
1445 favicon_bounds.width(), favicon_bounds.height(), | |
1446 false); | |
1447 } | |
1448 | |
1449 // Draws the actual pinned tab title changed indicator. | |
1450 const int kIndicatorRadius = 3; | |
1451 SkPaint indicator_paint; | |
1452 indicator_paint.setColor(GetNativeTheme()->GetSystemColor( | |
1453 ui::NativeTheme::kColorId_CallToActionColor)); | |
1454 indicator_paint.setAntiAlias(true); | |
1455 indicator_paint.setStyle(SkPaint::kFill_Style); | |
1456 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
| |
1457 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
| |
1458 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
| |
1459 const int indicator_y = favicon_bounds_.bottom() - kIndicatorRadius; | |
1460 canvas->DrawCircle(gfx::Point(indicator_x + kIndicatorRadius, | |
1461 indicator_y + kIndicatorRadius), | |
1462 kIndicatorRadius, indicator_paint); | |
1463 } | |
1464 | |
1495 void Tab::PaintIcon(gfx::Canvas* canvas) { | 1465 void Tab::PaintIcon(gfx::Canvas* canvas) { |
1496 gfx::Rect bounds = favicon_bounds_; | 1466 gfx::Rect bounds = favicon_bounds_; |
1497 bounds.set_x(GetMirroredXForRect(bounds)); | 1467 bounds.set_x(GetMirroredXForRect(bounds)); |
1498 bounds.Offset(0, favicon_hiding_offset_); | 1468 bounds.Offset(0, favicon_hiding_offset_); |
1499 bounds.Intersect(GetContentsBounds()); | 1469 bounds.Intersect(GetContentsBounds()); |
1500 if (bounds.IsEmpty()) | 1470 if (bounds.IsEmpty()) |
1501 return; | 1471 return; |
1502 | 1472 |
1503 if (data().network_state != TabRendererData::NETWORK_STATE_NONE) { | 1473 if (data().network_state != TabRendererData::NETWORK_STATE_NONE) { |
1504 // Throbber will do its own painting. | 1474 // Throbber will do its own painting. |
1505 } else { | 1475 return; |
1506 const gfx::ImageSkia& favicon = should_display_crashed_favicon_ ? | 1476 } |
1507 *ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed( | 1477 const gfx::ImageSkia& favicon = |
1508 IDR_CRASH_SAD_FAVICON) : | 1478 should_display_crashed_favicon_ |
1509 data().favicon; | 1479 ? *ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed( |
1510 if (!favicon.isNull()) { | 1480 IDR_CRASH_SAD_FAVICON) |
1511 canvas->DrawImageInt(favicon, 0, 0, bounds.width(), bounds.height(), | 1481 : data().favicon; |
1512 bounds.x(), bounds.y(), bounds.width(), | 1482 |
1513 bounds.height(), false); | 1483 if (showing_pinned_tab_title_changed_indicator_ && |
1514 } | 1484 !should_display_crashed_favicon_) { |
1485 PaintPinnedTabTitleChangedIndicatorAndIcon(canvas, favicon, bounds); | |
1486 } else if (!favicon.isNull()) { | |
1487 canvas->DrawImageInt(favicon, 0, 0, bounds.width(), bounds.height(), | |
1488 bounds.x(), bounds.y(), bounds.width(), | |
1489 bounds.height(), false); | |
1515 } | 1490 } |
1516 } | 1491 } |
1517 | 1492 |
1518 void Tab::AdvanceLoadingAnimation() { | 1493 void Tab::AdvanceLoadingAnimation() { |
1519 const TabRendererData::NetworkState state = data().network_state; | 1494 const TabRendererData::NetworkState state = data().network_state; |
1520 if (controller_->IsImmersiveStyle()) { | 1495 if (controller_->IsImmersiveStyle()) { |
1521 throbber_->SetVisible(false); | 1496 throbber_->SetVisible(false); |
1522 if (state == TabRendererData::NETWORK_STATE_WAITING) { | 1497 if (state == TabRendererData::NETWORK_STATE_WAITING) { |
1523 // Waiting steps backwards. | 1498 // Waiting steps backwards. |
1524 immersive_loading_step_ = | 1499 immersive_loading_step_ = |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1609 return !data().pinned || | 1584 return !data().pinned || |
1610 (width() >= (GetPinnedWidth() + kPinnedTabExtraWidthToRenderAsNormal)); | 1585 (width() >= (GetPinnedWidth() + kPinnedTabExtraWidthToRenderAsNormal)); |
1611 } | 1586 } |
1612 | 1587 |
1613 double Tab::GetThrobValue() { | 1588 double Tab::GetThrobValue() { |
1614 const bool is_selected = IsSelected(); | 1589 const bool is_selected = IsSelected(); |
1615 double val = is_selected ? kSelectedTabOpacity : 0; | 1590 double val = is_selected ? kSelectedTabOpacity : 0; |
1616 const double offset = | 1591 const double offset = |
1617 is_selected ? (kSelectedTabThrobScale * kHoverOpacity) : kHoverOpacity; | 1592 is_selected ? (kSelectedTabThrobScale * kHoverOpacity) : kHoverOpacity; |
1618 | 1593 |
1619 // Showing both the pulse and title change animation at the same time is too | 1594 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; | 1595 val += pulse_animation_->GetCurrentValue() * offset; |
1624 } else if (hover_controller_.ShouldDraw()) { | 1596 else if (hover_controller_.ShouldDraw()) |
1625 val += hover_controller_.GetAnimationValue() * offset; | 1597 val += hover_controller_.GetAnimationValue() * offset; |
1626 } | |
1627 return val; | 1598 return val; |
1628 } | 1599 } |
1629 | 1600 |
1630 void Tab::SetFaviconHidingOffset(int offset) { | 1601 void Tab::SetFaviconHidingOffset(int offset) { |
1631 favicon_hiding_offset_ = offset; | 1602 favicon_hiding_offset_ = offset; |
1632 ScheduleIconPaint(); | 1603 ScheduleIconPaint(); |
1633 } | 1604 } |
1634 | 1605 |
1635 void Tab::OnButtonColorMaybeChanged() { | 1606 void Tab::OnButtonColorMaybeChanged() { |
1636 // The theme provider may be null if we're not currently in a widget | 1607 // 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); | 1745 inactive_images_.image_c = rb.GetImageSkiaNamed(IDR_TAB_INACTIVE_CENTER); |
1775 inactive_images_.image_r = rb.GetImageSkiaNamed(IDR_TAB_INACTIVE_RIGHT); | 1746 inactive_images_.image_r = rb.GetImageSkiaNamed(IDR_TAB_INACTIVE_RIGHT); |
1776 inactive_images_.l_width = inactive_images_.image_l->width(); | 1747 inactive_images_.l_width = inactive_images_.image_l->width(); |
1777 inactive_images_.r_width = inactive_images_.image_r->width(); | 1748 inactive_images_.r_width = inactive_images_.image_r->width(); |
1778 | 1749 |
1779 mask_images_.image_l = rb.GetImageSkiaNamed(IDR_TAB_ALPHA_LEFT); | 1750 mask_images_.image_l = rb.GetImageSkiaNamed(IDR_TAB_ALPHA_LEFT); |
1780 mask_images_.image_r = rb.GetImageSkiaNamed(IDR_TAB_ALPHA_RIGHT); | 1751 mask_images_.image_r = rb.GetImageSkiaNamed(IDR_TAB_ALPHA_RIGHT); |
1781 mask_images_.l_width = mask_images_.image_l->width(); | 1752 mask_images_.l_width = mask_images_.image_l->width(); |
1782 mask_images_.r_width = mask_images_.image_r->width(); | 1753 mask_images_.r_width = mask_images_.image_r->width(); |
1783 } | 1754 } |
OLD | NEW |