Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(57)

Side by Side Diff: chrome/browser/ui/views/tabs/tab.cc

Issue 1381203002: An energy usage monitor for Mac, and some layer-backed throbber experiments Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix the AA thing, but it is still a bit weird Created 5 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « chrome/browser/ui/views/tabs/tab.h ('k') | chrome/chrome_tests.gypi » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 12 matching lines...) Expand all
23 #include "chrome/common/chrome_switches.h" 23 #include "chrome/common/chrome_switches.h"
24 #include "chrome/grit/generated_resources.h" 24 #include "chrome/grit/generated_resources.h"
25 #include "content/public/browser/user_metrics.h" 25 #include "content/public/browser/user_metrics.h"
26 #include "grit/theme_resources.h" 26 #include "grit/theme_resources.h"
27 #include "third_party/skia/include/effects/SkGradientShader.h" 27 #include "third_party/skia/include/effects/SkGradientShader.h"
28 #include "ui/accessibility/ax_view_state.h" 28 #include "ui/accessibility/ax_view_state.h"
29 #include "ui/base/l10n/l10n_util.h" 29 #include "ui/base/l10n/l10n_util.h"
30 #include "ui/base/models/list_selection_model.h" 30 #include "ui/base/models/list_selection_model.h"
31 #include "ui/base/resource/resource_bundle.h" 31 #include "ui/base/resource/resource_bundle.h"
32 #include "ui/base/theme_provider.h" 32 #include "ui/base/theme_provider.h"
33 #include "ui/compositor/layer_animator.h"
34 #include "ui/compositor/paint_recorder.h"
33 #include "ui/gfx/animation/animation_container.h" 35 #include "ui/gfx/animation/animation_container.h"
34 #include "ui/gfx/animation/multi_animation.h" 36 #include "ui/gfx/animation/multi_animation.h"
35 #include "ui/gfx/animation/throb_animation.h" 37 #include "ui/gfx/animation/throb_animation.h"
36 #include "ui/gfx/canvas.h" 38 #include "ui/gfx/canvas.h"
37 #include "ui/gfx/color_analysis.h" 39 #include "ui/gfx/color_analysis.h"
38 #include "ui/gfx/favicon_size.h" 40 #include "ui/gfx/favicon_size.h"
39 #include "ui/gfx/geometry/rect_conversions.h" 41 #include "ui/gfx/geometry/rect_conversions.h"
40 #include "ui/gfx/image/image_skia_operations.h" 42 #include "ui/gfx/image/image_skia_operations.h"
41 #include "ui/gfx/paint_vector_icon.h" 43 #include "ui/gfx/paint_vector_icon.h"
42 #include "ui/gfx/path.h" 44 #include "ui/gfx/path.h"
43 #include "ui/gfx/skia_util.h" 45 #include "ui/gfx/skia_util.h"
44 #include "ui/gfx/vector_icons_public.h" 46 #include "ui/gfx/vector_icons_public.h"
45 #include "ui/resources/grit/ui_resources.h" 47 #include "ui/resources/grit/ui_resources.h"
46 #include "ui/views/border.h" 48 #include "ui/views/border.h"
47 #include "ui/views/controls/button/image_button.h" 49 #include "ui/views/controls/button/image_button.h"
48 #include "ui/views/controls/label.h" 50 #include "ui/views/controls/label.h"
49 #include "ui/views/rect_based_targeting_utils.h" 51 #include "ui/views/rect_based_targeting_utils.h"
50 #include "ui/views/view_targeter.h" 52 #include "ui/views/view_targeter.h"
51 #include "ui/views/widget/tooltip_manager.h" 53 #include "ui/views/widget/tooltip_manager.h"
52 #include "ui/views/widget/widget.h" 54 #include "ui/views/widget/widget.h"
53 #include "ui/views/window/non_client_view.h" 55 #include "ui/views/window/non_client_view.h"
54 56
55 #if defined(USE_AURA) 57 #if defined(USE_AURA)
56 #include "ui/aura/env.h" 58 #include "ui/aura/env.h"
57 #endif 59 #endif
58 60
61 #include "base/debug/stack_trace.h"
62
59 using base::UserMetricsAction; 63 using base::UserMetricsAction;
60 64
61 namespace { 65 namespace {
62 66
63 // Height of the shadow at the top of the tab image assets. 67 // Height of the shadow at the top of the tab image assets.
64 const int kDropShadowHeight = 4; 68 const int kDropShadowHeight = 4;
65 69
66 // How long the pulse throb takes. 70 // How long the pulse throb takes.
67 const int kPulseDurationMs = 200; 71 const int kPulseDurationMs = 200;
68 72
(...skipping 316 matching lines...) Expand 10 before | Expand all | Expand 10 after
385 // ImageCacheEntry 389 // ImageCacheEntry
386 390
387 Tab::ImageCacheEntry::ImageCacheEntry() 391 Tab::ImageCacheEntry::ImageCacheEntry()
388 : resource_id(-1), 392 : resource_id(-1),
389 scale_factor(ui::SCALE_FACTOR_NONE) { 393 scale_factor(ui::SCALE_FACTOR_NONE) {
390 } 394 }
391 395
392 Tab::ImageCacheEntry::~ImageCacheEntry() {} 396 Tab::ImageCacheEntry::~ImageCacheEntry() {}
393 397
394 //////////////////////////////////////////////////////////////////////////////// 398 ////////////////////////////////////////////////////////////////////////////////
399 // ThrobberView
400
401 class Tab::ThrobberView : public views::View {
402 public:
403 ThrobberView(Tab* owner, const gfx::Rect& bounds)
404 : owner_(owner),
405 waiting_arc_(owner_->GetThemeProvider()->GetColor(
406 ThemeProperties::COLOR_THROBBER_WAITING),
407 180) {
408 SetPaintToLayer(true);
409 SetFillsBoundsOpaquely(false);
410 SetBoundsRect(bounds);
411 owner_->AddChildView(this);
412
413 mask_.SetFillsBoundsOpaquely(false);
414 mask_.SetMasksToBounds(true);
415 }
416
417 void SchedulePaintIfRequired() {
418 if (NeedsPaint())
419 SchedulePaint();
420 }
421
422 // views::View:
423 void OnBoundsChanged(const gfx::Rect& previous_bounds) override {
424 gfx::Rect bounds = GetLocalBounds();
425 waiting_arc_.layer()->SetBounds(
426 gfx::Rect(0, 0, bounds.width() * Arc::kAA, bounds.height() * Arc::kAA));
427
428 bounds.set_width(bounds.width() / 2);
429 mask_.SetBounds(bounds);
430 }
431
432 void OnPaint(gfx::Canvas* canvas) override {
433 state_ = owner_->data().network_state;
434 if (state_ == TabRendererData::NETWORK_STATE_NONE)
435 return;
436
437 const gfx::Rect bounds = GetLocalBounds();
438
439 // Paint network activity (aka throbber) animation frame.
440 ui::ThemeProvider* tp = owner_->GetThemeProvider();
441 if (state_ == TabRendererData::NETWORK_STATE_WAITING) {
442 // Painted by Arc.
443 } else {
444 if (loading_start_time_ == base::TimeTicks())
445 loading_start_time_ = base::TimeTicks::Now();
446
447 waiting_state_.color =
448 tp->GetColor(ThemeProperties::COLOR_THROBBER_WAITING);
449 gfx::PaintThrobberSpinningAfterWaiting(
450 canvas, bounds,
451 tp->GetColor(ThemeProperties::COLOR_THROBBER_SPINNING),
452 base::TimeTicks::Now() - loading_start_time_, &waiting_state_);
453 }
454 }
455
456 private:
457 class Arc : public ui::LayerDelegate {
458 public:
459 // Since the rotation transform mis-aligns the pixel anti-aliasing done by
460 // Skia, perform a kind of FSAA by drawing on a larger canvas and scaling
461 // down as part of the transform.
462 static const int kAA = 4;
463
464 Arc(SkColor color, SkScalar sweep)
465 : color_(color), sweep_(sweep), layer_(ui::LAYER_TEXTURED) {
466 layer_.set_delegate(this);
467 layer_.SetFillsBoundsOpaquely(false);
468 }
469
470 ui::Layer* layer() { return &layer_; }
471
472 void SetAngle(SkScalar angle) {
473 const gfx::Size size = layer()->size();
474 gfx::Transform transform;
475 transform.Translate(size.width() / 2.0 / kAA, size.height() / 2.0 / kAA);
476 transform.Rotate(-angle);
477 transform.Scale(1.0 / kAA, 1.0 / kAA);
478 transform.Translate(-size.width() / 2, -size.height() / 2);
479 layer()->SetTransform(transform);
480 }
481
482 // LayerDelegate:
483 void OnPaintLayer(const ui::PaintContext& context) override {
484 const gfx::Size size = layer()->size();
485 ui::PaintRecorder recorder(context, size);
486 gfx::PaintThrobberArc(recorder.canvas(), gfx::Rect(size), color_, -90,
487 sweep_);
488 }
489
490 void OnDelegatedFrameDamage(const gfx::Rect& damage_rect_in_dip) override {}
491 void OnDeviceScaleFactorChanged(float device_scale_factor) override {}
492 base::Closure PrepareForLayerBoundsChange() override {
493 return base::Closure();
494 }
495
496 private:
497 SkColor color_;
498 SkScalar sweep_;
499 ui::Layer layer_;
500
501 DISALLOW_COPY_AND_ASSIGN(Arc);
502 };
503
504 void ApplyWaitingRotation(const base::TimeDelta& elapsed_time) {
505 const base::TimeDelta revolution_time =
506 base::TimeDelta::FromMilliseconds(1320);
507 bool needs_mask = elapsed_time < revolution_time / 2;
508 mask_.SetMasksToBounds(needs_mask);
509 waiting_arc_.SetAngle(360 * waiting_state_.elapsed_time / revolution_time);
510 }
511
512 bool NeedsPaint() {
513 if (bounds().IsEmpty())
514 return false;
515
516 TabRendererData::NetworkState new_state = owner_->data().network_state;
517 const bool changing_state = new_state != state_;
518
519 // Waiting throbber is fully layer-backed.
520 if (new_state == TabRendererData::NETWORK_STATE_WAITING) {
521 if (waiting_start_time_ == base::TimeTicks())
522 waiting_start_time_ = base::TimeTicks::Now();
523
524 state_ = new_state;
525 waiting_state_.elapsed_time =
526 base::TimeTicks::Now() - waiting_start_time_;
527 layer()->Add(&mask_);
528 mask_.Add(waiting_arc_.layer());
529 ApplyWaitingRotation(waiting_state_.elapsed_time);
530 return changing_state;
531 }
532
533 return true;
534 }
535
536 Tab* owner_; // Weak. Owns this.
537
538 TabRendererData::NetworkState state_ = TabRendererData::NETWORK_STATE_NONE;
539
540 // The point in time when the tab icon was first painted in the waiting state.
541 base::TimeTicks waiting_start_time_;
542
543 // The point in time when the tab icon was first painted in the loading state.
544 base::TimeTicks loading_start_time_;
545
546 // Paint state for the throbber after the most recent waiting paint.
547 gfx::ThrobberWaitingState waiting_state_;
548
549 ui::Layer mask_;
550 Arc waiting_arc_;
551
552 DISALLOW_COPY_AND_ASSIGN(ThrobberView);
553 };
554
555 ////////////////////////////////////////////////////////////////////////////////
395 // Tab, statics: 556 // Tab, statics:
396 557
397 // static 558 // static
398 const char Tab::kViewClassName[] = "Tab"; 559 const char Tab::kViewClassName[] = "Tab";
399 Tab::TabImage Tab::tab_active_ = {0}; 560 Tab::TabImage Tab::tab_active_ = {0};
400 Tab::TabImage Tab::tab_inactive_ = {0}; 561 Tab::TabImage Tab::tab_inactive_ = {0};
401 Tab::TabImage Tab::tab_alpha_ = {0}; 562 Tab::TabImage Tab::tab_alpha_ = {0};
402 Tab::ImageCache* Tab::image_cache_ = NULL; 563 Tab::ImageCache* Tab::image_cache_ = NULL;
403 564
404 //////////////////////////////////////////////////////////////////////////////// 565 ////////////////////////////////////////////////////////////////////////////////
405 // Tab, public: 566 // Tab, public:
406 567
407 Tab::Tab(TabController* controller) 568 Tab::Tab(TabController* controller)
408 : controller_(controller), 569 : controller_(controller),
409 closing_(false), 570 closing_(false),
410 dragging_(false), 571 dragging_(false),
411 detached_(false), 572 detached_(false),
412 favicon_hiding_offset_(0), 573 favicon_hiding_offset_(0),
413 immersive_loading_step_(0), 574 immersive_loading_step_(0),
414 should_display_crashed_favicon_(false), 575 should_display_crashed_favicon_(false),
576 throbber_(nullptr),
415 media_indicator_button_(nullptr), 577 media_indicator_button_(nullptr),
416 close_button_(nullptr), 578 close_button_(nullptr),
417 title_(new views::Label()), 579 title_(new views::Label()),
418 tab_activated_with_last_tap_down_(false), 580 tab_activated_with_last_tap_down_(false),
419 hover_controller_(this), 581 hover_controller_(this),
420 showing_icon_(false), 582 showing_icon_(false),
421 showing_media_indicator_(false), 583 showing_media_indicator_(false),
422 showing_close_button_(false), 584 showing_close_button_(false),
423 button_color_(SK_ColorTRANSPARENT) { 585 button_color_(SK_ColorTRANSPARENT) {
424 DCHECK(controller); 586 DCHECK(controller);
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
545 } 707 }
546 708
547 void Tab::UpdateLoadingAnimation(TabRendererData::NetworkState state) { 709 void Tab::UpdateLoadingAnimation(TabRendererData::NetworkState state) {
548 if (state == data_.network_state && 710 if (state == data_.network_state &&
549 state == TabRendererData::NETWORK_STATE_NONE) { 711 state == TabRendererData::NETWORK_STATE_NONE) {
550 // If the network state is none and hasn't changed, do nothing. Otherwise we 712 // If the network state is none and hasn't changed, do nothing. Otherwise we
551 // need to advance the animation frame. 713 // need to advance the animation frame.
552 return; 714 return;
553 } 715 }
554 716
555 TabRendererData::NetworkState old_state = data_.network_state;
556 data_.network_state = state; 717 data_.network_state = state;
557 AdvanceLoadingAnimation(old_state, state); 718 AdvanceLoadingAnimation(state);
558 } 719 }
559 720
560 void Tab::StartPulse() { 721 void Tab::StartPulse() {
561 pulse_animation_.reset(new gfx::ThrobAnimation(this)); 722 pulse_animation_.reset(new gfx::ThrobAnimation(this));
562 pulse_animation_->SetSlideDuration(kPulseDurationMs); 723 pulse_animation_->SetSlideDuration(kPulseDurationMs);
563 if (animation_container_.get()) 724 if (animation_container_.get())
564 pulse_animation_->SetContainer(animation_container_.get()); 725 pulse_animation_->SetContainer(animation_container_.get());
565 pulse_animation_->StartThrobbing(std::numeric_limits<int>::max()); 726 pulse_animation_->StartThrobbing(std::numeric_limits<int>::max());
566 } 727 }
567 728
(...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after
780 const int extra_padding = 941 const int extra_padding =
781 (controller_->ShouldHideCloseButtonForInactiveTabs() || 942 (controller_->ShouldHideCloseButtonForInactiveTabs() ||
782 (IconCapacity() < 3)) ? 0 : kExtraLeftPaddingToBalanceCloseButtonPadding; 943 (IconCapacity() < 3)) ? 0 : kExtraLeftPaddingToBalanceCloseButtonPadding;
783 const int start = lb.x() + extra_padding; 944 const int start = lb.x() + extra_padding;
784 favicon_bounds_.SetRect(start, lb.y(), 0, 0); 945 favicon_bounds_.SetRect(start, lb.y(), 0, 0);
785 if (showing_icon_) { 946 if (showing_icon_) {
786 favicon_bounds_.set_size(gfx::Size(gfx::kFaviconSize, gfx::kFaviconSize)); 947 favicon_bounds_.set_size(gfx::Size(gfx::kFaviconSize, gfx::kFaviconSize));
787 favicon_bounds_.set_y(lb.y() + (lb.height() - gfx::kFaviconSize + 1) / 2); 948 favicon_bounds_.set_y(lb.y() + (lb.height() - gfx::kFaviconSize + 1) / 2);
788 MaybeAdjustLeftForPinnedTab(&favicon_bounds_); 949 MaybeAdjustLeftForPinnedTab(&favicon_bounds_);
789 } 950 }
951 if (throbber_)
952 throbber_->SetBoundsRect(favicon_bounds_);
790 953
791 showing_close_button_ = ShouldShowCloseBox(); 954 showing_close_button_ = ShouldShowCloseBox();
792 if (showing_close_button_) { 955 if (showing_close_button_) {
793 // If the ratio of the close button size to tab width exceeds the maximum. 956 // If the ratio of the close button size to tab width exceeds the maximum.
794 // The close button should be as large as possible so that there is a larger 957 // The close button should be as large as possible so that there is a larger
795 // hit-target for touch events. So the close button bounds extends to the 958 // hit-target for touch events. So the close button bounds extends to the
796 // edges of the tab. However, the larger hit-target should be active only 959 // edges of the tab. However, the larger hit-target should be active only
797 // for mouse events, and the close-image should show up in the right place. 960 // for mouse events, and the close-image should show up in the right place.
798 // So a border is added to the button with necessary padding. The close 961 // So a border is added to the button with necessary padding. The close
799 // button (BaseTab::TabCloseButton) makes sure the padding is a hit-target 962 // button (BaseTab::TabCloseButton) makes sure the padding is a hit-target
(...skipping 540 matching lines...) Expand 10 before | Expand all | Expand 10 after
1340 } 1503 }
1341 1504
1342 void Tab::PaintIcon(gfx::Canvas* canvas) { 1505 void Tab::PaintIcon(gfx::Canvas* canvas) {
1343 gfx::Rect bounds = favicon_bounds_; 1506 gfx::Rect bounds = favicon_bounds_;
1344 if (bounds.IsEmpty()) 1507 if (bounds.IsEmpty())
1345 return; 1508 return;
1346 1509
1347 bounds.set_x(GetMirroredXForRect(bounds)); 1510 bounds.set_x(GetMirroredXForRect(bounds));
1348 1511
1349 if (data().network_state != TabRendererData::NETWORK_STATE_NONE) { 1512 if (data().network_state != TabRendererData::NETWORK_STATE_NONE) {
1350 // Paint network activity (aka throbber) animation frame. 1513 // Throbber will do its own painting.
1351 ui::ThemeProvider* tp = GetThemeProvider();
1352 if (data().network_state == TabRendererData::NETWORK_STATE_WAITING) {
1353 if (waiting_start_time_ == base::TimeTicks())
1354 waiting_start_time_ = base::TimeTicks::Now();
1355
1356 waiting_state_.elapsed_time =
1357 base::TimeTicks::Now() - waiting_start_time_;
1358 gfx::PaintThrobberWaiting(
1359 canvas, bounds, tp->GetColor(ThemeProperties::COLOR_THROBBER_WAITING),
1360 waiting_state_.elapsed_time);
1361 } else {
1362 if (loading_start_time_ == base::TimeTicks())
1363 loading_start_time_ = base::TimeTicks::Now();
1364
1365 waiting_state_.color =
1366 tp->GetColor(ThemeProperties::COLOR_THROBBER_WAITING);
1367 gfx::PaintThrobberSpinningAfterWaiting(
1368 canvas, bounds,
1369 tp->GetColor(ThemeProperties::COLOR_THROBBER_SPINNING),
1370 base::TimeTicks::Now() - loading_start_time_, &waiting_state_);
1371 }
1372 } else if (should_display_crashed_favicon_) { 1514 } else if (should_display_crashed_favicon_) {
1373 // Paint crash favicon. 1515 // Paint crash favicon.
1374 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); 1516 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
1375 gfx::ImageSkia crashed_favicon(*rb.GetImageSkiaNamed(IDR_SAD_FAVICON)); 1517 gfx::ImageSkia crashed_favicon(*rb.GetImageSkiaNamed(IDR_SAD_FAVICON));
1376 bounds.set_y(bounds.y() + favicon_hiding_offset_); 1518 bounds.set_y(bounds.y() + favicon_hiding_offset_);
1377 DrawIconCenter(canvas, crashed_favicon, 0, 1519 DrawIconCenter(canvas, crashed_favicon, 0,
1378 crashed_favicon.width(), 1520 crashed_favicon.width(),
1379 crashed_favicon.height(), 1521 crashed_favicon.height(),
1380 bounds, true, SkPaint()); 1522 bounds, true, SkPaint());
1381 } else if (!data().favicon.isNull()) { 1523 } else if (!data().favicon.isNull()) {
1382 // Paint the normal favicon. 1524 // Paint the normal favicon.
1383 DrawIconCenter(canvas, data().favicon, 0, 1525 DrawIconCenter(canvas, data().favicon, 0,
1384 data().favicon.width(), 1526 data().favicon.width(),
1385 data().favicon.height(), 1527 data().favicon.height(),
1386 bounds, true, SkPaint()); 1528 bounds, true, SkPaint());
1387 } 1529 }
1388 } 1530 }
1389 1531
1390 void Tab::AdvanceLoadingAnimation(TabRendererData::NetworkState old_state, 1532 void Tab::AdvanceLoadingAnimation(TabRendererData::NetworkState state) {
1391 TabRendererData::NetworkState state) {
1392 if (state == TabRendererData::NETWORK_STATE_WAITING) { 1533 if (state == TabRendererData::NETWORK_STATE_WAITING) {
1393 // Waiting steps backwards. 1534 // Waiting steps backwards.
1394 immersive_loading_step_ = 1535 immersive_loading_step_ =
1395 (immersive_loading_step_ - 1 + kImmersiveLoadingStepCount) % 1536 (immersive_loading_step_ - 1 + kImmersiveLoadingStepCount) %
1396 kImmersiveLoadingStepCount; 1537 kImmersiveLoadingStepCount;
1397 } else if (state == TabRendererData::NETWORK_STATE_LOADING) { 1538 } else if (state == TabRendererData::NETWORK_STATE_LOADING) {
1398 immersive_loading_step_ = (immersive_loading_step_ + 1) % 1539 immersive_loading_step_ = (immersive_loading_step_ + 1) %
1399 kImmersiveLoadingStepCount; 1540 kImmersiveLoadingStepCount;
1400 } else { 1541 } else {
1401 waiting_start_time_ = base::TimeTicks();
1402 loading_start_time_ = base::TimeTicks();
1403 waiting_state_ = gfx::ThrobberWaitingState();
1404 immersive_loading_step_ = 0; 1542 immersive_loading_step_ = 0;
1405 } 1543 }
1544
1406 if (controller_->IsImmersiveStyle()) { 1545 if (controller_->IsImmersiveStyle()) {
1407 SchedulePaintInRect(GetImmersiveBarRect()); 1546 SchedulePaintInRect(GetImmersiveBarRect());
1408 } else { 1547 return;
1548 }
1549
1550 const bool needs_throbber = state != TabRendererData::NETWORK_STATE_NONE;
1551 if (needs_throbber && !throbber_) {
1552 throbber_ = new ThrobberView(this, favicon_bounds_);
1553 ScheduleIconPaint(); // Repaint the icon area to not show the icon.
1554 } else if (!needs_throbber) {
1555 delete throbber_;
1556 throbber_ = nullptr;
1409 ScheduleIconPaint(); 1557 ScheduleIconPaint();
1410 } 1558 }
1559 if (throbber_)
1560 throbber_->SchedulePaintIfRequired();
1411 } 1561 }
1412 1562
1413 int Tab::IconCapacity() const { 1563 int Tab::IconCapacity() const {
1414 const gfx::Size min_size(GetMinimumUnselectedSize()); 1564 const gfx::Size min_size(GetMinimumUnselectedSize());
1415 if (height() < min_size.height()) 1565 if (height() < min_size.height())
1416 return 0; 1566 return 0;
1417 const int available_width = std::max(0, width() - min_size.width()); 1567 const int available_width = std::max(0, width() - min_size.width());
1418 // All icons are the same size as the favicon. 1568 // All icons are the same size as the favicon.
1419 const int icon_width = gfx::kFaviconSize; 1569 const int icon_width = gfx::kFaviconSize;
1420 // We need enough space to display the icons flush against each other. 1570 // We need enough space to display the icons flush against each other.
(...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after
1679 const gfx::ImageSkia& image) { 1829 const gfx::ImageSkia& image) {
1680 DCHECK_NE(scale_factor, ui::SCALE_FACTOR_NONE); 1830 DCHECK_NE(scale_factor, ui::SCALE_FACTOR_NONE);
1681 ImageCacheEntry entry; 1831 ImageCacheEntry entry;
1682 entry.resource_id = resource_id; 1832 entry.resource_id = resource_id;
1683 entry.scale_factor = scale_factor; 1833 entry.scale_factor = scale_factor;
1684 entry.image = image; 1834 entry.image = image;
1685 image_cache_->push_front(entry); 1835 image_cache_->push_front(entry);
1686 if (image_cache_->size() > kMaxImageCacheSize) 1836 if (image_cache_->size() > kMaxImageCacheSize)
1687 image_cache_->pop_back(); 1837 image_cache_->pop_back();
1688 } 1838 }
OLDNEW
« no previous file with comments | « chrome/browser/ui/views/tabs/tab.h ('k') | chrome/chrome_tests.gypi » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698