Chromium Code Reviews| 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 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 158 public gfx::AnimationDelegate { | 158 public gfx::AnimationDelegate { |
| 159 public: | 159 public: |
| 160 explicit FaviconCrashAnimation(Tab* target) | 160 explicit FaviconCrashAnimation(Tab* target) |
| 161 : gfx::LinearAnimation(1000, 25, this), | 161 : gfx::LinearAnimation(1000, 25, this), |
| 162 target_(target) { | 162 target_(target) { |
| 163 } | 163 } |
| 164 ~FaviconCrashAnimation() override {} | 164 ~FaviconCrashAnimation() override {} |
| 165 | 165 |
| 166 // gfx::Animation overrides: | 166 // gfx::Animation overrides: |
| 167 void AnimateToState(double state) override { | 167 void AnimateToState(double state) override { |
| 168 const double kHidingOffset = 27; | 168 const double kHidingOffset = |
| 169 Tab::GetMinimumInactiveSize().height() - GetLayoutInsets(TAB).height(); | |
| 169 | 170 |
| 170 if (state < .5) { | 171 if (state < .5) { |
| 171 // Animate the normal icon down. | 172 // Animate the normal icon down. |
| 172 target_->SetFaviconHidingOffset( | 173 target_->SetFaviconHidingOffset( |
| 173 static_cast<int>(floor(kHidingOffset * 2.0 * state))); | 174 static_cast<int>(floor(kHidingOffset * 2.0 * state))); |
| 174 } else { | 175 } else { |
| 175 // Animate the crashed icon up. | 176 // Animate the crashed icon up. |
| 176 target_->DisplayCrashedFavicon(); | 177 target_->set_should_display_crashed_favicon(); |
| 177 target_->SetFaviconHidingOffset( | 178 target_->SetFaviconHidingOffset( |
| 178 static_cast<int>( | 179 static_cast<int>( |
| 179 floor(kHidingOffset - ((state - .5) * 2.0 * kHidingOffset)))); | 180 floor(kHidingOffset - ((state - .5) * 2.0 * kHidingOffset)))); |
| 180 } | 181 } |
| 181 } | 182 } |
| 182 | 183 |
| 183 // gfx::AnimationDelegate overrides: | |
| 184 void AnimationCanceled(const gfx::Animation* animation) override { | |
| 185 target_->SetFaviconHidingOffset(0); | |
| 186 } | |
| 187 | |
| 188 private: | 184 private: |
| 189 Tab* target_; | 185 Tab* target_; |
| 190 | 186 |
| 191 DISALLOW_COPY_AND_ASSIGN(FaviconCrashAnimation); | 187 DISALLOW_COPY_AND_ASSIGN(FaviconCrashAnimation); |
| 192 }; | 188 }; |
| 193 | 189 |
| 194 //////////////////////////////////////////////////////////////////////////////// | 190 //////////////////////////////////////////////////////////////////////////////// |
| 195 // TabCloseButton | 191 // TabCloseButton |
| 196 // | 192 // |
| 197 // This is a Button subclass that causes middle clicks to be forwarded to the | 193 // This is a Button subclass that causes middle clicks to be forwarded to the |
| (...skipping 266 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 464 if (title.empty()) { | 460 if (title.empty()) { |
| 465 title = data_.loading ? | 461 title = data_.loading ? |
| 466 l10n_util::GetStringUTF16(IDS_TAB_LOADING_TITLE) : | 462 l10n_util::GetStringUTF16(IDS_TAB_LOADING_TITLE) : |
| 467 CoreTabHelper::GetDefaultTitle(); | 463 CoreTabHelper::GetDefaultTitle(); |
| 468 } else { | 464 } else { |
| 469 Browser::FormatTitleForDisplay(&title); | 465 Browser::FormatTitleForDisplay(&title); |
| 470 } | 466 } |
| 471 title_->SetText(title); | 467 title_->SetText(title); |
| 472 | 468 |
| 473 if (data_.IsCrashed()) { | 469 if (data_.IsCrashed()) { |
| 474 if (!should_display_crashed_favicon_ && !IsPerformingCrashAnimation()) { | 470 if (!should_display_crashed_favicon_ && !crash_icon_animation_) { |
| 475 data_.media_state = TAB_MEDIA_STATE_NONE; | 471 data_.media_state = TAB_MEDIA_STATE_NONE; |
| 472 bool start_crash_animation = true; | |
| 476 #if defined(OS_CHROMEOS) | 473 #if defined(OS_CHROMEOS) |
| 477 // On Chrome OS, we reload killed tabs automatically when the user | 474 // On Chrome OS, we reload killed tabs automatically when the user |
| 478 // switches to them. Don't display animations for these unless they're | 475 // switches to them. Don't display animations for these unless they're |
| 479 // selected (i.e. in the foreground) -- we won't reload these | 476 // selected (i.e. in the foreground) -- we won't reload these |
| 480 // automatically since we don't want to get into a crash loop. | 477 // automatically since we don't want to get into a crash loop. |
| 481 if (IsSelected() || | 478 start_crash_animation = IsSelected() || |
| 482 (data_.crashed_status | 479 (data_.crashed_status != |
| 483 != base::TERMINATION_STATUS_PROCESS_WAS_KILLED && | 480 base::TERMINATION_STATUS_PROCESS_WAS_KILLED && |
| 484 data_.crashed_status | 481 data_.crashed_status != |
| 485 != base::TERMINATION_STATUS_PROCESS_WAS_KILLED_BY_OOM)) { | 482 base::TERMINATION_STATUS_PROCESS_WAS_KILLED_BY_OOM)); |
| 486 StartCrashAnimation(); | 483 #endif |
| 484 if (start_crash_animation) { | |
| 485 crash_icon_animation_.reset(new FaviconCrashAnimation(this)); | |
| 486 crash_icon_animation_->Start(); | |
| 487 } | 487 } |
| 488 #else | |
| 489 StartCrashAnimation(); | |
| 490 #endif | |
| 491 } | 488 } |
| 492 } else { | 489 } else { |
| 493 if (IsPerformingCrashAnimation()) | 490 if (crash_icon_animation_) |
| 494 StopCrashAnimation(); | 491 crash_icon_animation_.reset(); |
| 495 ResetCrashedFavicon(); | 492 should_display_crashed_favicon_ = false; |
| 493 favicon_hiding_offset_ = 0; | |
| 496 } | 494 } |
| 497 | 495 |
| 498 if (data_.media_state != old.media_state) | 496 if (data_.media_state != old.media_state) |
| 499 media_indicator_button_->TransitionToMediaState(data_.media_state); | 497 media_indicator_button_->TransitionToMediaState(data_.media_state); |
| 500 | 498 |
| 501 if (old.pinned != data_.pinned) { | 499 if (old.pinned != data_.pinned) |
| 502 StopAndDeleteAnimation(pinned_title_change_animation_.Pass()); | 500 StopPinnedTabTitleAnimation(); |
| 503 } | |
| 504 | 501 |
| 505 DataChanged(old); | 502 DataChanged(old); |
| 506 | 503 |
| 507 Layout(); | 504 Layout(); |
| 508 SchedulePaint(); | 505 SchedulePaint(); |
| 509 } | 506 } |
| 510 | 507 |
| 511 void Tab::UpdateLoadingAnimation(TabRendererData::NetworkState state) { | 508 void Tab::UpdateLoadingAnimation(TabRendererData::NetworkState state) { |
| 512 if (state == data_.network_state && | 509 if (state == data_.network_state && |
| 513 state == TabRendererData::NETWORK_STATE_NONE) { | 510 state == TabRendererData::NETWORK_STATE_NONE) { |
| (...skipping 826 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1340 | 1337 |
| 1341 // Now draw the highlights/shadows around the tab edge. | 1338 // Now draw the highlights/shadows around the tab edge. |
| 1342 canvas->DrawImageInt(*tab_image->image_l, 0, 0); | 1339 canvas->DrawImageInt(*tab_image->image_l, 0, 0); |
| 1343 canvas->TileImageInt(*tab_image->image_c, tab_image->l_width, 0, | 1340 canvas->TileImageInt(*tab_image->image_c, tab_image->l_width, 0, |
| 1344 width() - tab_image->l_width - tab_image->r_width, height()); | 1341 width() - tab_image->l_width - tab_image->r_width, height()); |
| 1345 canvas->DrawImageInt(*tab_image->image_r, width() - tab_image->r_width, 0); | 1342 canvas->DrawImageInt(*tab_image->image_r, width() - tab_image->r_width, 0); |
| 1346 } | 1343 } |
| 1347 | 1344 |
| 1348 void Tab::PaintIcon(gfx::Canvas* canvas) { | 1345 void Tab::PaintIcon(gfx::Canvas* canvas) { |
| 1349 gfx::Rect bounds = favicon_bounds_; | 1346 gfx::Rect bounds = favicon_bounds_; |
| 1347 bounds.set_x(GetMirroredXForRect(bounds)); | |
| 1348 bounds.Offset(0, favicon_hiding_offset_); | |
| 1349 bounds.Intersect(GetInteriorBounds()); | |
| 1350 if (bounds.IsEmpty()) | 1350 if (bounds.IsEmpty()) |
| 1351 return; | 1351 return; |
| 1352 | 1352 |
| 1353 bounds.set_x(GetMirroredXForRect(bounds)); | 1353 if (!should_display_crashed_favicon_ && |
|
Peter Kasting
2015/10/09 09:37:29
Not sure I should add this; see CL description.
| |
| 1354 | 1354 data().network_state != TabRendererData::NETWORK_STATE_NONE) { |
| 1355 if (data().network_state != TabRendererData::NETWORK_STATE_NONE) { | |
| 1356 // Paint network activity (aka throbber) animation frame. | 1355 // Paint network activity (aka throbber) animation frame. |
| 1357 ui::ThemeProvider* tp = GetThemeProvider(); | 1356 ui::ThemeProvider* tp = GetThemeProvider(); |
| 1358 if (data().network_state == TabRendererData::NETWORK_STATE_WAITING) { | 1357 if (data().network_state == TabRendererData::NETWORK_STATE_WAITING) { |
| 1359 if (waiting_start_time_ == base::TimeTicks()) | 1358 if (waiting_start_time_ == base::TimeTicks()) |
| 1360 waiting_start_time_ = base::TimeTicks::Now(); | 1359 waiting_start_time_ = base::TimeTicks::Now(); |
| 1361 | 1360 |
| 1362 waiting_state_.elapsed_time = | 1361 waiting_state_.elapsed_time = |
| 1363 base::TimeTicks::Now() - waiting_start_time_; | 1362 base::TimeTicks::Now() - waiting_start_time_; |
| 1364 gfx::PaintThrobberWaiting( | 1363 gfx::PaintThrobberWaiting( |
| 1365 canvas, bounds, tp->GetColor(ThemeProperties::COLOR_THROBBER_WAITING), | 1364 canvas, bounds, tp->GetColor(ThemeProperties::COLOR_THROBBER_WAITING), |
| (...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1481 } | 1480 } |
| 1482 | 1481 |
| 1483 return is_selected ? kSelectedTabOpacity : 0; | 1482 return is_selected ? kSelectedTabOpacity : 0; |
| 1484 } | 1483 } |
| 1485 | 1484 |
| 1486 void Tab::SetFaviconHidingOffset(int offset) { | 1485 void Tab::SetFaviconHidingOffset(int offset) { |
| 1487 favicon_hiding_offset_ = offset; | 1486 favicon_hiding_offset_ = offset; |
| 1488 ScheduleIconPaint(); | 1487 ScheduleIconPaint(); |
| 1489 } | 1488 } |
| 1490 | 1489 |
| 1491 void Tab::DisplayCrashedFavicon() { | |
| 1492 should_display_crashed_favicon_ = true; | |
| 1493 } | |
| 1494 | |
| 1495 void Tab::ResetCrashedFavicon() { | |
| 1496 should_display_crashed_favicon_ = false; | |
| 1497 } | |
| 1498 | |
| 1499 void Tab::StopCrashAnimation() { | |
| 1500 crash_icon_animation_.reset(); | |
| 1501 } | |
| 1502 | |
| 1503 void Tab::StartCrashAnimation() { | |
| 1504 crash_icon_animation_.reset(new FaviconCrashAnimation(this)); | |
| 1505 crash_icon_animation_->Start(); | |
| 1506 } | |
| 1507 | |
| 1508 bool Tab::IsPerformingCrashAnimation() const { | |
| 1509 return crash_icon_animation_.get() && data_.IsCrashed(); | |
| 1510 } | |
| 1511 | |
| 1512 void Tab::OnButtonColorMaybeChanged() { | 1490 void Tab::OnButtonColorMaybeChanged() { |
| 1513 // The theme provider may be null if we're not currently in a widget | 1491 // The theme provider may be null if we're not currently in a widget |
| 1514 // hierarchy. | 1492 // hierarchy. |
| 1515 ui::ThemeProvider* theme_provider = GetThemeProvider(); | 1493 ui::ThemeProvider* theme_provider = GetThemeProvider(); |
| 1516 if (!theme_provider) | 1494 if (!theme_provider) |
| 1517 return; | 1495 return; |
| 1518 | 1496 |
| 1519 const SkColor title_color = theme_provider->GetColor(IsActive() ? | 1497 const SkColor title_color = theme_provider->GetColor(IsActive() ? |
| 1520 ThemeProperties::COLOR_TAB_TEXT : | 1498 ThemeProperties::COLOR_TAB_TEXT : |
| 1521 ThemeProperties::COLOR_BACKGROUND_TAB_TEXT); | 1499 ThemeProperties::COLOR_BACKGROUND_TAB_TEXT); |
| 1522 const SkColor new_button_color = SkColorSetA(title_color, 0xA0); | 1500 const SkColor new_button_color = SkColorSetA(title_color, 0xA0); |
| 1523 if (button_color_ != new_button_color) { | 1501 if (button_color_ != new_button_color) { |
| 1524 button_color_ = new_button_color; | 1502 button_color_ = new_button_color; |
| 1525 title_->SetEnabledColor(title_color); | 1503 title_->SetEnabledColor(title_color); |
| 1526 media_indicator_button_->OnParentTabButtonColorChanged(); | 1504 media_indicator_button_->OnParentTabButtonColorChanged(); |
| 1527 const gfx::ImageSkia& close_button_normal_image = gfx::CreateVectorIcon( | 1505 const gfx::ImageSkia& close_button_normal_image = gfx::CreateVectorIcon( |
| 1528 gfx::VectorIconId::TAB_CLOSE_NORMAL, kTabCloseButtonSize, | 1506 gfx::VectorIconId::TAB_CLOSE_NORMAL, kTabCloseButtonSize, |
| 1529 button_color_); | 1507 button_color_); |
| 1530 close_button_->SetImage(views::CustomButton::STATE_NORMAL, | 1508 close_button_->SetImage(views::CustomButton::STATE_NORMAL, |
| 1531 &close_button_normal_image); | 1509 &close_button_normal_image); |
| 1532 } | 1510 } |
| 1533 } | 1511 } |
| 1534 | 1512 |
| 1535 void Tab::ScheduleIconPaint() { | 1513 void Tab::ScheduleIconPaint() { |
| 1536 gfx::Rect bounds = favicon_bounds_; | 1514 gfx::Rect bounds = favicon_bounds_; |
| 1537 if (bounds.IsEmpty()) | 1515 if (bounds.IsEmpty()) |
| 1538 return; | 1516 return; |
| 1539 | 1517 |
| 1540 // Extends the area to the bottom when sad_favicon is animating. | 1518 // Extends the area to the bottom when the crash animation is in progress. |
| 1541 if (IsPerformingCrashAnimation()) | 1519 if (crash_icon_animation_) |
| 1542 bounds.set_height(height() - bounds.y()); | 1520 bounds.set_height(height() - bounds.y()); |
| 1543 bounds.set_x(GetMirroredXForRect(bounds)); | 1521 bounds.set_x(GetMirroredXForRect(bounds)); |
| 1544 SchedulePaintInRect(bounds); | 1522 SchedulePaintInRect(bounds); |
| 1545 } | 1523 } |
| 1546 | 1524 |
| 1547 gfx::Rect Tab::GetInteriorBounds() const { | 1525 gfx::Rect Tab::GetInteriorBounds() const { |
| 1548 gfx::Rect bounds(GetContentsBounds()); | 1526 gfx::Rect bounds(GetContentsBounds()); |
| 1549 bounds.Inset(GetLayoutInsets(TAB)); | 1527 bounds.Inset(GetLayoutInsets(TAB)); |
| 1550 return bounds; | 1528 return bounds; |
| 1551 } | 1529 } |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1634 const gfx::ImageSkia& image) { | 1612 const gfx::ImageSkia& image) { |
| 1635 DCHECK_NE(scale_factor, ui::SCALE_FACTOR_NONE); | 1613 DCHECK_NE(scale_factor, ui::SCALE_FACTOR_NONE); |
| 1636 ImageCacheEntry entry; | 1614 ImageCacheEntry entry; |
| 1637 entry.resource_id = resource_id; | 1615 entry.resource_id = resource_id; |
| 1638 entry.scale_factor = scale_factor; | 1616 entry.scale_factor = scale_factor; |
| 1639 entry.image = image; | 1617 entry.image = image; |
| 1640 image_cache_->push_front(entry); | 1618 image_cache_->push_front(entry); |
| 1641 if (image_cache_->size() > kMaxImageCacheSize) | 1619 if (image_cache_->size() > kMaxImageCacheSize) |
| 1642 image_cache_->pop_back(); | 1620 image_cache_->pop_back(); |
| 1643 } | 1621 } |
| OLD | NEW |