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 <limits> | 7 #include <limits> |
8 | 8 |
9 #include "base/command_line.h" | 9 #include "base/command_line.h" |
10 #include "base/debug/alias.h" | 10 #include "base/debug/alias.h" |
(...skipping 399 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
410 //////////////////////////////////////////////////////////////////////////////// | 410 //////////////////////////////////////////////////////////////////////////////// |
411 // Tab, public: | 411 // Tab, public: |
412 | 412 |
413 Tab::Tab(TabController* controller) | 413 Tab::Tab(TabController* controller) |
414 : controller_(controller), | 414 : controller_(controller), |
415 closing_(false), | 415 closing_(false), |
416 dragging_(false), | 416 dragging_(false), |
417 favicon_hiding_offset_(0), | 417 favicon_hiding_offset_(0), |
418 loading_animation_frame_(0), | 418 loading_animation_frame_(0), |
419 should_display_crashed_favicon_(false), | 419 should_display_crashed_favicon_(false), |
420 throbber_disabled_(false), | |
421 theme_provider_(NULL), | 420 theme_provider_(NULL), |
422 ALLOW_THIS_IN_INITIALIZER_LIST(hover_controller_(this)), | 421 ALLOW_THIS_IN_INITIALIZER_LIST(hover_controller_(this)), |
423 showing_icon_(false), | 422 showing_icon_(false), |
424 showing_close_button_(false), | 423 showing_close_button_(false), |
425 close_button_color_(0), | 424 close_button_color_(0), |
426 icon_dominant_color_(SK_ColorWHITE) { | 425 icon_dominant_color_(SK_ColorWHITE) { |
427 InitTabResources(); | 426 InitTabResources(); |
428 | 427 |
429 // So we get don't get enter/exit on children and don't prematurely stop the | 428 // So we get don't get enter/exit on children and don't prematurely stop the |
430 // hover. | 429 // hover. |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
489 #endif | 488 #endif |
490 } | 489 } |
491 | 490 |
492 } else if ((data_.capture_state == TabRendererData::CAPTURE_STATE_NONE) && | 491 } else if ((data_.capture_state == TabRendererData::CAPTURE_STATE_NONE) && |
493 (old.capture_state != TabRendererData::CAPTURE_STATE_NONE)) { | 492 (old.capture_state != TabRendererData::CAPTURE_STATE_NONE)) { |
494 StopRecordingAnimation(); | 493 StopRecordingAnimation(); |
495 | 494 |
496 } else if ((data_.capture_state != TabRendererData::CAPTURE_STATE_NONE) && | 495 } else if ((data_.capture_state != TabRendererData::CAPTURE_STATE_NONE) && |
497 (old.capture_state == TabRendererData::CAPTURE_STATE_NONE)) { | 496 (old.capture_state == TabRendererData::CAPTURE_STATE_NONE)) { |
498 StartRecordingAnimation(); | 497 StartRecordingAnimation(); |
498 | |
sky
2013/01/23 16:10:02
nuke this, in fact nuke 494 and 490 as well.
| |
499 } else { | 499 } else { |
500 if (IsPerformingCrashAnimation()) | 500 if (IsPerformingCrashAnimation()) |
501 StopCrashAnimation(); | 501 StopCrashAnimation(); |
502 ResetCrashedFavicon(); | 502 ResetCrashedFavicon(); |
503 } | 503 } |
504 | 504 |
505 // If the favicon changed, re-compute its dominant color. | 505 // If the favicon changed, re-compute its dominant color. |
506 if (controller() && | 506 if (controller() && |
507 controller()->IsImmersiveStyle() && | 507 controller()->IsImmersiveStyle() && |
508 !data_.favicon.isNull() && | 508 !data_.favicon.isNull() && |
509 !data_.favicon.BackedBySameObjectAs(old.favicon)) | 509 !data_.favicon.BackedBySameObjectAs(old.favicon)) |
510 UpdateIconDominantColor(); | 510 UpdateIconDominantColor(); |
511 | 511 |
512 DataChanged(old); | 512 DataChanged(old); |
513 | 513 |
514 Layout(); | 514 Layout(); |
515 SchedulePaint(); | 515 SchedulePaint(); |
516 } | 516 } |
517 | 517 |
518 void Tab::UpdateLoadingAnimation(TabRendererData::NetworkState state) { | 518 void Tab::UpdateLoadingAnimation(TabRendererData::NetworkState state) { |
519 // If this is an extension app and a command line flag is set, | |
520 // then disable the throbber. | |
521 throbber_disabled_ = data().app && | |
522 CommandLine::ForCurrentProcess()->HasSwitch(switches::kAppsNoThrob); | |
523 | |
524 if (throbber_disabled_) | |
525 return; | |
526 | |
527 if (state == data_.network_state && | 519 if (state == data_.network_state && |
528 state == TabRendererData::NETWORK_STATE_NONE) { | 520 state == TabRendererData::NETWORK_STATE_NONE) { |
529 // If the network state is none and hasn't changed, do nothing. Otherwise we | 521 // If the network state is none and hasn't changed, do nothing. Otherwise we |
530 // need to advance the animation frame. | 522 // need to advance the animation frame. |
531 return; | 523 return; |
532 } | 524 } |
533 | 525 |
534 TabRendererData::NetworkState old_state = data_.network_state; | 526 TabRendererData::NetworkState old_state = data_.network_state; |
535 data_.network_state = state; | 527 data_.network_state = state; |
536 AdvanceLoadingAnimation(old_state, state); | 528 AdvanceLoadingAnimation(old_state, state); |
537 } | 529 } |
538 | 530 |
539 void Tab::StartPulse() { | 531 void Tab::StartPulse() { |
540 if (!tab_animation_.get()) { | 532 ui::ThrobAnimation* animation = new ui::ThrobAnimation(this); |
541 tab_animation_.reset(new ui::ThrobAnimation(this)); | 533 animation->SetSlideDuration(kPulseDurationMs); |
542 tab_animation_->SetSlideDuration(kPulseDurationMs); | 534 if (animation_container_.get()) |
543 if (animation_container_.get()) | 535 animation->SetContainer(animation_container_.get()); |
544 tab_animation_->SetContainer(animation_container_.get()); | 536 animation->StartThrobbing(std::numeric_limits<int>::max()); |
545 } | 537 tab_animation_.reset(animation); |
546 tab_animation_->Reset(); | |
547 tab_animation_->StartThrobbing(std::numeric_limits<int>::max()); | |
548 } | 538 } |
549 | 539 |
550 void Tab::StopPulse() { | 540 void Tab::StopPulse() { |
551 if (!tab_animation_.get()) | 541 if (!tab_animation_.get()) |
552 return; | 542 return; |
553 | 543 tab_animation_->Stop(); |
554 tab_animation_->Stop(); // Do stop so we get notified. | |
555 tab_animation_.reset(NULL); | 544 tab_animation_.reset(NULL); |
556 } | 545 } |
557 | 546 |
558 void Tab::StartMiniTabTitleAnimation() { | 547 void Tab::StartMiniTabTitleAnimation() { |
559 if (!mini_title_animation_.get()) { | 548 // We can only do this animation if the tab is mini because we will |
549 // upcast tab_animation back to MultiAnimation when we draw. | |
550 if (!data().mini) | |
551 return; | |
552 if (!tab_animation_.get()) { | |
560 ui::MultiAnimation::Parts parts; | 553 ui::MultiAnimation::Parts parts; |
561 parts.push_back( | 554 parts.push_back( |
562 ui::MultiAnimation::Part(kMiniTitleChangeAnimationDuration1MS, | 555 ui::MultiAnimation::Part(kMiniTitleChangeAnimationDuration1MS, |
563 ui::Tween::EASE_OUT)); | 556 ui::Tween::EASE_OUT)); |
564 parts.push_back( | 557 parts.push_back( |
565 ui::MultiAnimation::Part(kMiniTitleChangeAnimationDuration2MS, | 558 ui::MultiAnimation::Part(kMiniTitleChangeAnimationDuration2MS, |
566 ui::Tween::ZERO)); | 559 ui::Tween::ZERO)); |
567 parts.push_back( | 560 parts.push_back( |
568 ui::MultiAnimation::Part(kMiniTitleChangeAnimationDuration3MS, | 561 ui::MultiAnimation::Part(kMiniTitleChangeAnimationDuration3MS, |
569 ui::Tween::EASE_IN)); | 562 ui::Tween::EASE_IN)); |
570 parts[0].start_time_ms = kMiniTitleChangeAnimationStart1MS; | 563 parts[0].start_time_ms = kMiniTitleChangeAnimationStart1MS; |
571 parts[0].end_time_ms = kMiniTitleChangeAnimationEnd1MS; | 564 parts[0].end_time_ms = kMiniTitleChangeAnimationEnd1MS; |
572 parts[2].start_time_ms = kMiniTitleChangeAnimationStart3MS; | 565 parts[2].start_time_ms = kMiniTitleChangeAnimationStart3MS; |
573 parts[2].end_time_ms = kMiniTitleChangeAnimationEnd3MS; | 566 parts[2].end_time_ms = kMiniTitleChangeAnimationEnd3MS; |
574 mini_title_animation_.reset(new ui::MultiAnimation( | 567 base::TimeDelta timeout = |
575 parts, | 568 base::TimeDelta::FromMilliseconds(kMiniTitleChangeAnimationIntervalMS); |
576 base::TimeDelta::FromMilliseconds( | 569 ui::MultiAnimation* animation = new ui::MultiAnimation(parts, timeout); |
577 kMiniTitleChangeAnimationIntervalMS))); | 570 if (animation_container_.get()) |
578 mini_title_animation_->SetContainer(animation_container()); | 571 animation->SetContainer(animation_container_.get()); |
579 mini_title_animation_->set_delegate(this); | 572 animation->set_delegate(this); |
573 tab_animation_.reset(animation); | |
580 } | 574 } |
581 mini_title_animation_->Start(); | 575 tab_animation_->Start(); |
582 } | 576 } |
583 | 577 |
584 void Tab::StopMiniTabTitleAnimation() { | 578 void Tab::StopMiniTabTitleAnimation() { |
585 if (mini_title_animation_.get()) | 579 if (!tab_animation_.get()) |
586 mini_title_animation_->Stop(); | 580 return; |
581 tab_animation_->Stop(); | |
582 tab_animation_.reset(NULL); | |
587 } | 583 } |
588 | 584 |
589 void Tab::UpdateIconDominantColor() { | 585 void Tab::UpdateIconDominantColor() { |
590 icon_dominant_color_ = | 586 icon_dominant_color_ = |
591 color_utils::CalculateKMeanColorOfBitmap(*data_.favicon.bitmap()); | 587 color_utils::CalculateKMeanColorOfBitmap(*data_.favicon.bitmap()); |
592 } | 588 } |
593 | 589 |
594 // static | 590 // static |
595 gfx::Size Tab::GetBasicMinimumUnselectedSize() { | 591 gfx::Size Tab::GetBasicMinimumUnselectedSize() { |
596 InitTabResources(); | 592 InitTabResources(); |
(...skipping 472 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1069 IsActive() ? kImmersiveActiveTabColor : kImmersiveInactiveTabColor; | 1065 IsActive() ? kImmersiveActiveTabColor : kImmersiveInactiveTabColor; |
1070 gfx::Rect main_bar_rect( | 1066 gfx::Rect main_bar_rect( |
1071 main_bar_left, 0, main_bar_right - main_bar_left, kImmersiveBarHeight); | 1067 main_bar_left, 0, main_bar_right - main_bar_left, kImmersiveBarHeight); |
1072 canvas->FillRect(main_bar_rect, color); | 1068 canvas->FillRect(main_bar_rect, color); |
1073 } | 1069 } |
1074 | 1070 |
1075 void Tab::PaintTabBackground(gfx::Canvas* canvas) { | 1071 void Tab::PaintTabBackground(gfx::Canvas* canvas) { |
1076 if (IsActive()) { | 1072 if (IsActive()) { |
1077 PaintActiveTabBackground(canvas); | 1073 PaintActiveTabBackground(canvas); |
1078 } else { | 1074 } else { |
1079 if (mini_title_animation_.get() && mini_title_animation_->is_animating()) | 1075 if (tab_animation_.get() && |
1080 PaintInactiveTabBackgroundWithTitleChange(canvas); | 1076 tab_animation_->is_animating() && |
1081 else | 1077 data().mini) { |
sky
2013/01/23 16:10:02
What happens if we start animating while not mini,
cpu_(ooo_6.6-7.5)
2013/01/23 18:31:40
Visually, nothing bad. The behavior is though a bi
sky
2013/01/23 19:33:02
Doesn't this mean you could do the wrong cast thou
cpu_(ooo_6.6-7.5)
2013/01/23 20:35:07
Ah, I see what you mean. I have the check of line
sky
2013/01/23 21:07:22
What happens if we StartPulse() and the tab is min
| |
1078 ui::MultiAnimation* animation = | |
1079 static_cast<ui::MultiAnimation*>(tab_animation_.get()); | |
1080 PaintInactiveTabBackgroundWithTitleChange(canvas, animation); | |
1081 } else { | |
1082 PaintInactiveTabBackground(canvas); | 1082 PaintInactiveTabBackground(canvas); |
1083 } | |
1083 | 1084 |
1084 double throb_value = GetThrobValue(); | 1085 double throb_value = GetThrobValue(); |
1085 if (throb_value > 0) { | 1086 if (throb_value > 0) { |
1086 canvas->SaveLayerAlpha(static_cast<int>(throb_value * 0xff), | 1087 canvas->SaveLayerAlpha(static_cast<int>(throb_value * 0xff), |
1087 GetLocalBounds()); | 1088 GetLocalBounds()); |
1088 PaintActiveTabBackground(canvas); | 1089 PaintActiveTabBackground(canvas); |
1089 canvas->Restore(); | 1090 canvas->Restore(); |
1090 } | 1091 } |
1091 } | 1092 } |
1092 } | 1093 } |
1093 | 1094 |
1094 void Tab::PaintInactiveTabBackgroundWithTitleChange(gfx::Canvas* canvas) { | 1095 void Tab::PaintInactiveTabBackgroundWithTitleChange( |
1096 gfx::Canvas* canvas, ui::MultiAnimation* animation) { | |
1095 // Render the inactive tab background. We'll use this for clipping. | 1097 // Render the inactive tab background. We'll use this for clipping. |
1096 gfx::Canvas background_canvas(size(), canvas->scale_factor(), false); | 1098 gfx::Canvas background_canvas(size(), canvas->scale_factor(), false); |
1097 PaintInactiveTabBackground(&background_canvas); | 1099 PaintInactiveTabBackground(&background_canvas); |
1098 | 1100 |
1099 gfx::ImageSkia background_image(background_canvas.ExtractImageRep()); | 1101 gfx::ImageSkia background_image(background_canvas.ExtractImageRep()); |
1100 | 1102 |
1101 // Draw a radial gradient to hover_canvas. | 1103 // Draw a radial gradient to hover_canvas. |
1102 gfx::Canvas hover_canvas(size(), canvas->scale_factor(), false); | 1104 gfx::Canvas hover_canvas(size(), canvas->scale_factor(), false); |
1103 int radius = kMiniTitleChangeGradientRadius; | 1105 int radius = kMiniTitleChangeGradientRadius; |
1104 int x0 = width() + radius - kMiniTitleChangeInitialXOffset; | 1106 int x0 = width() + radius - kMiniTitleChangeInitialXOffset; |
1105 int x1 = radius; | 1107 int x1 = radius; |
1106 int x2 = -radius; | 1108 int x2 = -radius; |
1107 int x; | 1109 int x; |
1108 if (mini_title_animation_->current_part_index() == 0) { | 1110 if (animation->current_part_index() == 0) { |
1109 x = mini_title_animation_->CurrentValueBetween(x0, x1); | 1111 x = animation->CurrentValueBetween(x0, x1); |
1110 } else if (mini_title_animation_->current_part_index() == 1) { | 1112 } else if (animation->current_part_index() == 1) { |
1111 x = x1; | 1113 x = x1; |
1112 } else { | 1114 } else { |
1113 x = mini_title_animation_->CurrentValueBetween(x1, x2); | 1115 x = animation->CurrentValueBetween(x1, x2); |
1114 } | 1116 } |
1115 SkPoint center_point; | 1117 SkPoint center_point; |
1116 center_point.iset(x, 0); | 1118 center_point.iset(x, 0); |
1117 SkColor colors[2] = { kMiniTitleChangeGradientColor1, | 1119 SkColor colors[2] = { kMiniTitleChangeGradientColor1, |
1118 kMiniTitleChangeGradientColor2 }; | 1120 kMiniTitleChangeGradientColor2 }; |
1119 skia::RefPtr<SkShader> shader = skia::AdoptRef( | 1121 skia::RefPtr<SkShader> shader = skia::AdoptRef( |
1120 SkGradientShader::CreateRadial( | 1122 SkGradientShader::CreateRadial( |
1121 center_point, SkIntToScalar(radius), colors, NULL, 2, | 1123 center_point, SkIntToScalar(radius), colors, NULL, 2, |
1122 SkShader::kClamp_TileMode)); | 1124 SkShader::kClamp_TileMode)); |
1123 SkPaint paint; | 1125 SkPaint paint; |
1124 paint.setShader(shader.get()); | 1126 paint.setShader(shader.get()); |
1125 hover_canvas.DrawRect(gfx::Rect(x - radius, -radius, radius * 2, radius * 2), | 1127 hover_canvas.DrawRect(gfx::Rect(x - radius, -radius, radius * 2, radius * 2), |
1126 paint); | 1128 paint); |
1127 | 1129 |
1128 // Draw the radial gradient clipped to the background into hover_image. | 1130 // Draw the radial gradient clipped to the background into hover_image. |
1129 gfx::ImageSkia hover_image = gfx::ImageSkiaOperations::CreateMaskedImage( | 1131 gfx::ImageSkia hover_image = gfx::ImageSkiaOperations::CreateMaskedImage( |
1130 gfx::ImageSkia(hover_canvas.ExtractImageRep()), background_image); | 1132 gfx::ImageSkia(hover_canvas.ExtractImageRep()), background_image); |
1131 | 1133 |
1132 // Draw the tab background to the canvas. | 1134 // Draw the tab background to the canvas. |
1133 canvas->DrawImageInt(background_image, 0, 0); | 1135 canvas->DrawImageInt(background_image, 0, 0); |
1134 | 1136 |
1135 // And then the gradient on top of that. | 1137 // And then the gradient on top of that. |
1136 if (mini_title_animation_->current_part_index() == 2) { | 1138 if (animation->current_part_index() == 2) { |
1137 uint8 alpha = mini_title_animation_->CurrentValueBetween(255, 0); | 1139 uint8 alpha = animation->CurrentValueBetween(255, 0); |
1138 canvas->DrawImageInt(hover_image, 0, 0, alpha); | 1140 canvas->DrawImageInt(hover_image, 0, 0, alpha); |
1139 } else { | 1141 } else { |
1140 canvas->DrawImageInt(hover_image, 0, 0); | 1142 canvas->DrawImageInt(hover_image, 0, 0); |
1141 } | 1143 } |
1142 } | 1144 } |
1143 | 1145 |
1144 void Tab::PaintInactiveTabBackground(gfx::Canvas* canvas) { | 1146 void Tab::PaintInactiveTabBackground(gfx::Canvas* canvas) { |
1145 int tab_id; | 1147 int tab_id; |
1146 if (GetWidget() && GetWidget()->GetTopLevelWidget()->ShouldUseNativeFrame()) { | 1148 if (GetWidget() && GetWidget()->GetTopLevelWidget()->ShouldUseNativeFrame()) { |
1147 tab_id = IDR_THEME_TAB_BACKGROUND_V; | 1149 tab_id = IDR_THEME_TAB_BACKGROUND_V; |
(...skipping 341 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1489 bool Tab::ShouldShowCloseBox() const { | 1491 bool Tab::ShouldShowCloseBox() const { |
1490 // The active tab never clips close button. | 1492 // The active tab never clips close button. |
1491 return !data().mini && (IsActive() || IconCapacity() >= 3); | 1493 return !data().mini && (IsActive() || IconCapacity() >= 3); |
1492 } | 1494 } |
1493 | 1495 |
1494 double Tab::GetThrobValue() { | 1496 double Tab::GetThrobValue() { |
1495 bool is_selected = IsSelected(); | 1497 bool is_selected = IsSelected(); |
1496 double min = is_selected ? kSelectedTabOpacity : 0; | 1498 double min = is_selected ? kSelectedTabOpacity : 0; |
1497 double scale = is_selected ? kSelectedTabThrobScale : 1; | 1499 double scale = is_selected ? kSelectedTabThrobScale : 1; |
1498 | 1500 |
1499 if (tab_animation_.get() && tab_animation_->is_animating()) | 1501 if (!data().mini) { |
1500 return tab_animation_->GetCurrentValue() * kHoverOpacity * scale + min; | 1502 if (tab_animation_.get() && tab_animation_->is_animating()) |
1503 return tab_animation_->GetCurrentValue() * kHoverOpacity * scale + min; | |
1504 } | |
1501 | 1505 |
1502 if (hover_controller_.ShouldDraw()) { | 1506 if (hover_controller_.ShouldDraw()) { |
1503 return kHoverOpacity * hover_controller_.GetAnimationValue() * scale + | 1507 return kHoverOpacity * hover_controller_.GetAnimationValue() * scale + |
1504 min; | 1508 min; |
1505 } | 1509 } |
1506 | 1510 |
1507 return is_selected ? kSelectedTabOpacity : 0; | 1511 return is_selected ? kSelectedTabOpacity : 0; |
1508 } | 1512 } |
1509 | 1513 |
1510 void Tab::SetFaviconHidingOffset(int offset) { | 1514 void Tab::SetFaviconHidingOffset(int offset) { |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1625 const gfx::ImageSkia& image) { | 1629 const gfx::ImageSkia& image) { |
1626 DCHECK_NE(scale_factor, ui::SCALE_FACTOR_NONE); | 1630 DCHECK_NE(scale_factor, ui::SCALE_FACTOR_NONE); |
1627 ImageCacheEntry entry; | 1631 ImageCacheEntry entry; |
1628 entry.resource_id = resource_id; | 1632 entry.resource_id = resource_id; |
1629 entry.scale_factor = scale_factor; | 1633 entry.scale_factor = scale_factor; |
1630 entry.image = image; | 1634 entry.image = image; |
1631 image_cache_->push_front(entry); | 1635 image_cache_->push_front(entry); |
1632 if (image_cache_->size() > kMaxImageCacheSize) | 1636 if (image_cache_->size() > kMaxImageCacheSize) |
1633 image_cache_->pop_back(); | 1637 image_cache_->pop_back(); |
1634 } | 1638 } |
OLD | NEW |