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

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

Issue 1415873006: Revert of Paint tab-loading throbbers into a ui::Layer. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 1 month 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/browser/ui/views/tabs/tab_controller.h » ('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 324 matching lines...) Expand 10 before | Expand all | Expand 10 after
335 335
336 return MaskedTargeterDelegate::DoesIntersectRect(target, rect); 336 return MaskedTargeterDelegate::DoesIntersectRect(target, rect);
337 } 337 }
338 338
339 Tab* tab_; 339 Tab* tab_;
340 340
341 DISALLOW_COPY_AND_ASSIGN(TabCloseButton); 341 DISALLOW_COPY_AND_ASSIGN(TabCloseButton);
342 }; 342 };
343 343
344 //////////////////////////////////////////////////////////////////////////////// 344 ////////////////////////////////////////////////////////////////////////////////
345 // ThrobberView
346 //
347 // A Layer-backed view for updating a waiting or loading tab throbber.
348 class Tab::ThrobberView : public views::View {
349 public:
350 explicit ThrobberView(Tab* owner);
351
352 // Resets the times tracking when the throbber changes state.
353 void ResetStartTimes();
354
355 private:
356 // views::View:
357 bool CanProcessEventsWithinSubtree() const override;
358 void OnPaint(gfx::Canvas* canvas) override;
359
360 Tab* owner_; // Weak. Owns |this|.
361
362 // The point in time when the tab icon was first painted in the waiting state.
363 base::TimeTicks waiting_start_time_;
364
365 // The point in time when the tab icon was first painted in the loading state.
366 base::TimeTicks loading_start_time_;
367
368 // Paint state for the throbber after the most recent waiting paint.
369 gfx::ThrobberWaitingState waiting_state_;
370
371 DISALLOW_COPY_AND_ASSIGN(ThrobberView);
372 };
373
374 Tab::ThrobberView::ThrobberView(Tab* owner) : owner_(owner) {}
375
376 void Tab::ThrobberView::ResetStartTimes() {
377 waiting_start_time_ = base::TimeTicks();
378 loading_start_time_ = base::TimeTicks();
379 waiting_state_ = gfx::ThrobberWaitingState();
380 }
381
382 bool Tab::ThrobberView::CanProcessEventsWithinSubtree() const {
383 return false;
384 }
385
386 void Tab::ThrobberView::OnPaint(gfx::Canvas* canvas) {
387 const TabRendererData::NetworkState state = owner_->data().network_state;
388 if (state == TabRendererData::NETWORK_STATE_NONE)
389 return;
390
391 ui::ThemeProvider* tp = GetThemeProvider();
392 const gfx::Rect bounds = GetLocalBounds();
393 if (state == TabRendererData::NETWORK_STATE_WAITING) {
394 if (waiting_start_time_ == base::TimeTicks())
395 waiting_start_time_ = base::TimeTicks::Now();
396
397 waiting_state_.elapsed_time = base::TimeTicks::Now() - waiting_start_time_;
398 gfx::PaintThrobberWaiting(
399 canvas, bounds, tp->GetColor(ThemeProperties::COLOR_THROBBER_WAITING),
400 waiting_state_.elapsed_time);
401 } else {
402 if (loading_start_time_ == base::TimeTicks())
403 loading_start_time_ = base::TimeTicks::Now();
404
405 waiting_state_.color =
406 tp->GetColor(ThemeProperties::COLOR_THROBBER_WAITING);
407 gfx::PaintThrobberSpinningAfterWaiting(
408 canvas, bounds, tp->GetColor(ThemeProperties::COLOR_THROBBER_SPINNING),
409 base::TimeTicks::Now() - loading_start_time_, &waiting_state_);
410 }
411 }
412
413 ////////////////////////////////////////////////////////////////////////////////
414 // ImageCacheEntry 345 // ImageCacheEntry
415 346
416 Tab::ImageCacheEntry::ImageCacheEntry() 347 Tab::ImageCacheEntry::ImageCacheEntry()
417 : resource_id(-1), 348 : resource_id(-1),
418 scale_factor(ui::SCALE_FACTOR_NONE) { 349 scale_factor(ui::SCALE_FACTOR_NONE) {
419 } 350 }
420 351
421 Tab::ImageCacheEntry::~ImageCacheEntry() {} 352 Tab::ImageCacheEntry::~ImageCacheEntry() {}
422 353
423 //////////////////////////////////////////////////////////////////////////////// 354 ////////////////////////////////////////////////////////////////////////////////
(...skipping 10 matching lines...) Expand all
434 // Tab, public: 365 // Tab, public:
435 366
436 Tab::Tab(TabController* controller) 367 Tab::Tab(TabController* controller)
437 : controller_(controller), 368 : controller_(controller),
438 closing_(false), 369 closing_(false),
439 dragging_(false), 370 dragging_(false),
440 detached_(false), 371 detached_(false),
441 favicon_hiding_offset_(0), 372 favicon_hiding_offset_(0),
442 immersive_loading_step_(0), 373 immersive_loading_step_(0),
443 should_display_crashed_favicon_(false), 374 should_display_crashed_favicon_(false),
444 throbber_(nullptr),
445 media_indicator_button_(nullptr), 375 media_indicator_button_(nullptr),
446 close_button_(nullptr), 376 close_button_(nullptr),
447 title_(new views::Label()), 377 title_(new views::Label()),
448 tab_activated_with_last_tap_down_(false), 378 tab_activated_with_last_tap_down_(false),
449 hover_controller_(this), 379 hover_controller_(this),
450 showing_icon_(false), 380 showing_icon_(false),
451 showing_media_indicator_(false), 381 showing_media_indicator_(false),
452 showing_close_button_(false), 382 showing_close_button_(false),
453 button_color_(SK_ColorTRANSPARENT) { 383 button_color_(SK_ColorTRANSPARENT) {
454 DCHECK(controller); 384 DCHECK(controller);
455 InitTabResources(); 385 InitTabResources();
456 386
457 // So we get don't get enter/exit on children and don't prematurely stop the 387 // So we get don't get enter/exit on children and don't prematurely stop the
458 // hover. 388 // hover.
459 set_notify_enter_exit_on_child(true); 389 set_notify_enter_exit_on_child(true);
460 390
461 set_id(VIEW_ID_TAB); 391 set_id(VIEW_ID_TAB);
462 392
463 title_->SetHorizontalAlignment(gfx::ALIGN_TO_HEAD); 393 title_->SetHorizontalAlignment(gfx::ALIGN_TO_HEAD);
464 title_->SetElideBehavior(gfx::FADE_TAIL); 394 title_->SetElideBehavior(gfx::FADE_TAIL);
465 title_->SetHandlesTooltips(false); 395 title_->SetHandlesTooltips(false);
466 title_->SetAutoColorReadabilityEnabled(false); 396 title_->SetAutoColorReadabilityEnabled(false);
467 title_->SetText(CoreTabHelper::GetDefaultTitle()); 397 title_->SetText(CoreTabHelper::GetDefaultTitle());
468 AddChildView(title_); 398 AddChildView(title_);
469 399
470 SetEventTargeter( 400 SetEventTargeter(
471 scoped_ptr<views::ViewTargeter>(new views::ViewTargeter(this))); 401 scoped_ptr<views::ViewTargeter>(new views::ViewTargeter(this)));
472 402
473 throbber_ = new ThrobberView(this);
474 throbber_->SetVisible(false);
475 AddChildView(throbber_);
476
477 media_indicator_button_ = new MediaIndicatorButton(this); 403 media_indicator_button_ = new MediaIndicatorButton(this);
478 AddChildView(media_indicator_button_); 404 AddChildView(media_indicator_button_);
479 405
480 close_button_ = new TabCloseButton(this); 406 close_button_ = new TabCloseButton(this);
481 close_button_->SetAccessibleName( 407 close_button_->SetAccessibleName(
482 l10n_util::GetStringUTF16(IDS_ACCNAME_CLOSE)); 408 l10n_util::GetStringUTF16(IDS_ACCNAME_CLOSE));
483 // The normal image is set by OnButtonColorMaybeChanged() because it depends 409 // The normal image is set by OnButtonColorMaybeChanged() because it depends
484 // on the current theme and active state. The hovered and pressed images 410 // on the current theme and active state. The hovered and pressed images
485 // don't depend on the these, so we can set them here. 411 // don't depend on the these, so we can set them here.
486 const gfx::ImageSkia& hovered = gfx::CreateVectorIcon( 412 const gfx::ImageSkia& hovered = gfx::CreateVectorIcon(
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
521 return controller_->IsTabSelected(this); 447 return controller_->IsTabSelected(this);
522 } 448 }
523 449
524 void Tab::SetData(const TabRendererData& data) { 450 void Tab::SetData(const TabRendererData& data) {
525 DCHECK(GetWidget()); 451 DCHECK(GetWidget());
526 452
527 if (data_.Equals(data)) 453 if (data_.Equals(data))
528 return; 454 return;
529 455
530 TabRendererData old(data_); 456 TabRendererData old(data_);
531 UpdateLoadingAnimation(data.network_state);
532 data_ = data; 457 data_ = data;
533 458
534 base::string16 title = data_.title; 459 base::string16 title = data_.title;
535 if (title.empty()) { 460 if (title.empty()) {
536 title = data_.loading ? 461 title = data_.loading ?
537 l10n_util::GetStringUTF16(IDS_TAB_LOADING_TITLE) : 462 l10n_util::GetStringUTF16(IDS_TAB_LOADING_TITLE) :
538 CoreTabHelper::GetDefaultTitle(); 463 CoreTabHelper::GetDefaultTitle();
539 } else { 464 } else {
540 Browser::FormatTitleForDisplay(&title); 465 Browser::FormatTitleForDisplay(&title);
541 } 466 }
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
581 } 506 }
582 507
583 void Tab::UpdateLoadingAnimation(TabRendererData::NetworkState state) { 508 void Tab::UpdateLoadingAnimation(TabRendererData::NetworkState state) {
584 if (state == data_.network_state && 509 if (state == data_.network_state &&
585 state == TabRendererData::NETWORK_STATE_NONE) { 510 state == TabRendererData::NETWORK_STATE_NONE) {
586 // If the network state is none and hasn't changed, do nothing. Otherwise we 511 // If the network state is none and hasn't changed, do nothing. Otherwise we
587 // need to advance the animation frame. 512 // need to advance the animation frame.
588 return; 513 return;
589 } 514 }
590 515
516 TabRendererData::NetworkState old_state = data_.network_state;
591 data_.network_state = state; 517 data_.network_state = state;
592 AdvanceLoadingAnimation(); 518 AdvanceLoadingAnimation(old_state, state);
593 } 519 }
594 520
595 void Tab::StartPulse() { 521 void Tab::StartPulse() {
596 pulse_animation_.reset(new gfx::ThrobAnimation(this)); 522 pulse_animation_.reset(new gfx::ThrobAnimation(this));
597 pulse_animation_->SetSlideDuration(kPulseDurationMs); 523 pulse_animation_->SetSlideDuration(kPulseDurationMs);
598 if (animation_container_.get()) 524 if (animation_container_.get())
599 pulse_animation_->SetContainer(animation_container_.get()); 525 pulse_animation_->SetContainer(animation_container_.get());
600 pulse_animation_->StartThrobbing(std::numeric_limits<int>::max()); 526 pulse_animation_->StartThrobbing(std::numeric_limits<int>::max());
601 } 527 }
602 528
(...skipping 259 matching lines...) Expand 10 before | Expand all | Expand 10 after
862 const int extra_padding = 788 const int extra_padding =
863 (controller_->ShouldHideCloseButtonForInactiveTabs() || 789 (controller_->ShouldHideCloseButtonForInactiveTabs() ||
864 (IconCapacity() < 3)) ? 0 : kExtraLeftPaddingToBalanceCloseButtonPadding; 790 (IconCapacity() < 3)) ? 0 : kExtraLeftPaddingToBalanceCloseButtonPadding;
865 const int start = lb.x() + extra_padding; 791 const int start = lb.x() + extra_padding;
866 favicon_bounds_.SetRect(start, lb.y(), 0, 0); 792 favicon_bounds_.SetRect(start, lb.y(), 0, 0);
867 if (showing_icon_) { 793 if (showing_icon_) {
868 favicon_bounds_.set_size(gfx::Size(gfx::kFaviconSize, gfx::kFaviconSize)); 794 favicon_bounds_.set_size(gfx::Size(gfx::kFaviconSize, gfx::kFaviconSize));
869 favicon_bounds_.set_y(lb.y() + (lb.height() - gfx::kFaviconSize + 1) / 2); 795 favicon_bounds_.set_y(lb.y() + (lb.height() - gfx::kFaviconSize + 1) / 2);
870 MaybeAdjustLeftForPinnedTab(&favicon_bounds_); 796 MaybeAdjustLeftForPinnedTab(&favicon_bounds_);
871 } 797 }
872 throbber_->SetBoundsRect(favicon_bounds_);
873 798
874 showing_close_button_ = ShouldShowCloseBox(); 799 showing_close_button_ = ShouldShowCloseBox();
875 if (showing_close_button_) { 800 if (showing_close_button_) {
876 // If the ratio of the close button size to tab width exceeds the maximum. 801 // If the ratio of the close button size to tab width exceeds the maximum.
877 // The close button should be as large as possible so that there is a larger 802 // The close button should be as large as possible so that there is a larger
878 // hit-target for touch events. So the close button bounds extends to the 803 // hit-target for touch events. So the close button bounds extends to the
879 // edges of the tab. However, the larger hit-target should be active only 804 // edges of the tab. However, the larger hit-target should be active only
880 // for mouse events, and the close-image should show up in the right place. 805 // for mouse events, and the close-image should show up in the right place.
881 // So a border is added to the button with necessary padding. The close 806 // So a border is added to the button with necessary padding. The close
882 // button (BaseTab::TabCloseButton) makes sure the padding is a hit-target 807 // button (BaseTab::TabCloseButton) makes sure the padding is a hit-target
(...skipping 536 matching lines...) Expand 10 before | Expand all | Expand 10 after
1419 1344
1420 void Tab::PaintIcon(gfx::Canvas* canvas) { 1345 void Tab::PaintIcon(gfx::Canvas* canvas) {
1421 gfx::Rect bounds = favicon_bounds_; 1346 gfx::Rect bounds = favicon_bounds_;
1422 bounds.set_x(GetMirroredXForRect(bounds)); 1347 bounds.set_x(GetMirroredXForRect(bounds));
1423 bounds.Offset(0, favicon_hiding_offset_); 1348 bounds.Offset(0, favicon_hiding_offset_);
1424 bounds.Intersect(GetInteriorBounds()); 1349 bounds.Intersect(GetInteriorBounds());
1425 if (bounds.IsEmpty()) 1350 if (bounds.IsEmpty())
1426 return; 1351 return;
1427 1352
1428 if (data().network_state != TabRendererData::NETWORK_STATE_NONE) { 1353 if (data().network_state != TabRendererData::NETWORK_STATE_NONE) {
1429 // Throbber will do its own painting. 1354 // Paint network activity (aka throbber) animation frame.
1355 ui::ThemeProvider* tp = GetThemeProvider();
1356 if (data().network_state == TabRendererData::NETWORK_STATE_WAITING) {
1357 if (waiting_start_time_ == base::TimeTicks())
1358 waiting_start_time_ = base::TimeTicks::Now();
1359
1360 waiting_state_.elapsed_time =
1361 base::TimeTicks::Now() - waiting_start_time_;
1362 gfx::PaintThrobberWaiting(
1363 canvas, bounds, tp->GetColor(ThemeProperties::COLOR_THROBBER_WAITING),
1364 waiting_state_.elapsed_time);
1365 } else {
1366 if (loading_start_time_ == base::TimeTicks())
1367 loading_start_time_ = base::TimeTicks::Now();
1368
1369 waiting_state_.color =
1370 tp->GetColor(ThemeProperties::COLOR_THROBBER_WAITING);
1371 gfx::PaintThrobberSpinningAfterWaiting(
1372 canvas, bounds,
1373 tp->GetColor(ThemeProperties::COLOR_THROBBER_SPINNING),
1374 base::TimeTicks::Now() - loading_start_time_, &waiting_state_);
1375 }
1430 } else { 1376 } else {
1431 const gfx::ImageSkia& favicon = should_display_crashed_favicon_ ? 1377 const gfx::ImageSkia& favicon = should_display_crashed_favicon_ ?
1432 *ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed( 1378 *ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed(
1433 IDR_CRASH_SAD_FAVICON) : 1379 IDR_CRASH_SAD_FAVICON) :
1434 data().favicon; 1380 data().favicon;
1435 if (!favicon.isNull()) { 1381 if (!favicon.isNull()) {
1436 canvas->DrawImageInt(favicon, 0, 0, bounds.width(), bounds.height(), 1382 canvas->DrawImageInt(favicon, 0, 0, bounds.width(), bounds.height(),
1437 bounds.x(), bounds.y(), bounds.width(), 1383 bounds.x(), bounds.y(), bounds.width(),
1438 bounds.height(), false); 1384 bounds.height(), false);
1439 } 1385 }
1440 } 1386 }
1441 } 1387 }
1442 1388
1443 void Tab::AdvanceLoadingAnimation() { 1389 void Tab::AdvanceLoadingAnimation(TabRendererData::NetworkState old_state,
1444 const TabRendererData::NetworkState state = data().network_state; 1390 TabRendererData::NetworkState state) {
1391 if (state == TabRendererData::NETWORK_STATE_WAITING) {
1392 // Waiting steps backwards.
1393 immersive_loading_step_ =
1394 (immersive_loading_step_ - 1 + kImmersiveLoadingStepCount) %
1395 kImmersiveLoadingStepCount;
1396 } else if (state == TabRendererData::NETWORK_STATE_LOADING) {
1397 immersive_loading_step_ = (immersive_loading_step_ + 1) %
1398 kImmersiveLoadingStepCount;
1399 } else {
1400 waiting_start_time_ = base::TimeTicks();
1401 loading_start_time_ = base::TimeTicks();
1402 waiting_state_ = gfx::ThrobberWaitingState();
1403 immersive_loading_step_ = 0;
1404 }
1445 if (controller_->IsImmersiveStyle()) { 1405 if (controller_->IsImmersiveStyle()) {
1446 if (state == TabRendererData::NETWORK_STATE_WAITING) {
1447 // Waiting steps backwards.
1448 immersive_loading_step_ =
1449 (immersive_loading_step_ - 1 + kImmersiveLoadingStepCount) %
1450 kImmersiveLoadingStepCount;
1451 } else if (state == TabRendererData::NETWORK_STATE_LOADING) {
1452 immersive_loading_step_ =
1453 (immersive_loading_step_ + 1) % kImmersiveLoadingStepCount;
1454 } else {
1455 immersive_loading_step_ = 0;
1456 }
1457
1458 SchedulePaintInRect(GetImmersiveBarRect()); 1406 SchedulePaintInRect(GetImmersiveBarRect());
1459 return; 1407 } else {
1408 ScheduleIconPaint();
1460 } 1409 }
1461
1462 if (state == TabRendererData::NETWORK_STATE_NONE) {
1463 throbber_->ResetStartTimes();
1464 throbber_->SetVisible(false);
1465 ScheduleIconPaint();
1466 return;
1467 }
1468
1469 // Since the throbber can animate for a long time, paint to a separate layer
1470 // when possible to reduce repaint overhead.
1471 const bool paint_to_layer = controller_->CanPaintThrobberToLayer();
1472 if (paint_to_layer != !!throbber_->layer()) {
1473 throbber_->SetPaintToLayer(paint_to_layer);
1474 throbber_->SetFillsBoundsOpaquely(false);
1475 if (paint_to_layer)
1476 ScheduleIconPaint(); // Ensure the non-layered throbber goes away.
1477 }
1478 if (!throbber_->visible()) {
1479 ScheduleIconPaint(); // Repaint the icon area to hide the favicon.
1480 throbber_->SetVisible(true);
1481 }
1482 throbber_->SchedulePaint();
1483 } 1410 }
1484 1411
1485 int Tab::IconCapacity() const { 1412 int Tab::IconCapacity() const {
1486 const gfx::Size min_size(GetMinimumInactiveSize()); 1413 const gfx::Size min_size(GetMinimumInactiveSize());
1487 if (height() < min_size.height()) 1414 if (height() < min_size.height())
1488 return 0; 1415 return 0;
1489 const int available_width = std::max(0, width() - min_size.width()); 1416 const int available_width = std::max(0, width() - min_size.width());
1490 // All icons are the same size as the favicon. 1417 // All icons are the same size as the favicon.
1491 const int icon_width = gfx::kFaviconSize; 1418 const int icon_width = gfx::kFaviconSize;
1492 // We need enough space to display the icons flush against each other. 1419 // We need enough space to display the icons flush against each other.
(...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after
1684 const gfx::ImageSkia& image) { 1611 const gfx::ImageSkia& image) {
1685 DCHECK_NE(scale_factor, ui::SCALE_FACTOR_NONE); 1612 DCHECK_NE(scale_factor, ui::SCALE_FACTOR_NONE);
1686 ImageCacheEntry entry; 1613 ImageCacheEntry entry;
1687 entry.resource_id = resource_id; 1614 entry.resource_id = resource_id;
1688 entry.scale_factor = scale_factor; 1615 entry.scale_factor = scale_factor;
1689 entry.image = image; 1616 entry.image = image;
1690 image_cache_->push_front(entry); 1617 image_cache_->push_front(entry);
1691 if (image_cache_->size() > kMaxImageCacheSize) 1618 if (image_cache_->size() > kMaxImageCacheSize)
1692 image_cache_->pop_back(); 1619 image_cache_->pop_back();
1693 } 1620 }
OLDNEW
« no previous file with comments | « chrome/browser/ui/views/tabs/tab.h ('k') | chrome/browser/ui/views/tabs/tab_controller.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698