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 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 |