| Index: chrome/browser/ui/views/tabs/tab.cc
|
| diff --git a/chrome/browser/ui/views/tabs/tab.cc b/chrome/browser/ui/views/tabs/tab.cc
|
| index 6d0d78ae342129de7cfe6e2eb8a11b18c20d701b..b991cf321bc262e48e617e4bfeeded4104bfc133 100644
|
| --- a/chrome/browser/ui/views/tabs/tab.cc
|
| +++ b/chrome/browser/ui/views/tabs/tab.cc
|
| @@ -137,6 +137,62 @@ const int kImmersiveLoadingStepCount = 32;
|
| const char kTabCloseButtonName[] = "TabCloseButton";
|
| const int kTabCloseButtonSize = 16;
|
|
|
| +class ThrobberView : public views::View {
|
| + public:
|
| + ThrobberView(Tab* owner, const gfx::Rect& bounds) : owner_(owner) {
|
| + SetPaintToLayer(true);
|
| + SetFillsBoundsOpaquely(false);
|
| + SetBoundsRect(bounds);
|
| + owner_->AddChildView(this);
|
| + }
|
| +
|
| + // views::View:
|
| + void OnPaint(gfx::Canvas* canvas) override {
|
| + const TabRendererData::NetworkState state = owner_->data().network_state;
|
| + if (state == TabRendererData::NETWORK_STATE_NONE)
|
| + return;
|
| +
|
| + const gfx::Rect bounds = GetLocalBounds(); // Adjust for RTL?
|
| +
|
| + // Paint network activity (aka throbber) animation frame.
|
| + ui::ThemeProvider* tp = owner_->GetThemeProvider();
|
| + if (state == TabRendererData::NETWORK_STATE_WAITING) {
|
| + if (waiting_start_time_ == base::TimeTicks())
|
| + waiting_start_time_ = base::TimeTicks::Now();
|
| +
|
| + waiting_state_.elapsed_time =
|
| + base::TimeTicks::Now() - waiting_start_time_;
|
| + gfx::PaintThrobberWaiting(
|
| + canvas, bounds, tp->GetColor(ThemeProperties::COLOR_THROBBER_WAITING),
|
| + waiting_state_.elapsed_time);
|
| + } else {
|
| + if (loading_start_time_ == base::TimeTicks())
|
| + loading_start_time_ = base::TimeTicks::Now();
|
| +
|
| + waiting_state_.color =
|
| + tp->GetColor(ThemeProperties::COLOR_THROBBER_WAITING);
|
| + gfx::PaintThrobberSpinningAfterWaiting(
|
| + canvas, bounds,
|
| + tp->GetColor(ThemeProperties::COLOR_THROBBER_SPINNING),
|
| + base::TimeTicks::Now() - loading_start_time_, &waiting_state_);
|
| + }
|
| + }
|
| +
|
| + private:
|
| + Tab* owner_; // Weak. Owns this.
|
| +
|
| + // The point in time when the tab icon was first painted in the waiting state.
|
| + base::TimeTicks waiting_start_time_;
|
| +
|
| + // The point in time when the tab icon was first painted in the loading state.
|
| + base::TimeTicks loading_start_time_;
|
| +
|
| + // Paint state for the throbber after the most recent waiting paint.
|
| + gfx::ThrobberWaitingState waiting_state_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(ThrobberView);
|
| +};
|
| +
|
| void DrawIconAtLocation(gfx::Canvas* canvas,
|
| const gfx::ImageSkia& image,
|
| int image_offset,
|
| @@ -412,6 +468,7 @@ Tab::Tab(TabController* controller)
|
| favicon_hiding_offset_(0),
|
| immersive_loading_step_(0),
|
| should_display_crashed_favicon_(false),
|
| + throbber_(nullptr),
|
| media_indicator_button_(nullptr),
|
| close_button_(nullptr),
|
| title_(new views::Label()),
|
| @@ -552,9 +609,8 @@ void Tab::UpdateLoadingAnimation(TabRendererData::NetworkState state) {
|
| return;
|
| }
|
|
|
| - TabRendererData::NetworkState old_state = data_.network_state;
|
| data_.network_state = state;
|
| - AdvanceLoadingAnimation(old_state, state);
|
| + AdvanceLoadingAnimation(state);
|
| }
|
|
|
| void Tab::StartPulse() {
|
| @@ -787,6 +843,8 @@ void Tab::Layout() {
|
| favicon_bounds_.set_y(lb.y() + (lb.height() - gfx::kFaviconSize + 1) / 2);
|
| MaybeAdjustLeftForPinnedTab(&favicon_bounds_);
|
| }
|
| + if (throbber_)
|
| + throbber_->SetBoundsRect(favicon_bounds_);
|
|
|
| showing_close_button_ = ShouldShowCloseBox();
|
| if (showing_close_button_) {
|
| @@ -1347,28 +1405,7 @@ void Tab::PaintIcon(gfx::Canvas* canvas) {
|
| bounds.set_x(GetMirroredXForRect(bounds));
|
|
|
| if (data().network_state != TabRendererData::NETWORK_STATE_NONE) {
|
| - // Paint network activity (aka throbber) animation frame.
|
| - ui::ThemeProvider* tp = GetThemeProvider();
|
| - if (data().network_state == TabRendererData::NETWORK_STATE_WAITING) {
|
| - if (waiting_start_time_ == base::TimeTicks())
|
| - waiting_start_time_ = base::TimeTicks::Now();
|
| -
|
| - waiting_state_.elapsed_time =
|
| - base::TimeTicks::Now() - waiting_start_time_;
|
| - gfx::PaintThrobberWaiting(
|
| - canvas, bounds, tp->GetColor(ThemeProperties::COLOR_THROBBER_WAITING),
|
| - waiting_state_.elapsed_time);
|
| - } else {
|
| - if (loading_start_time_ == base::TimeTicks())
|
| - loading_start_time_ = base::TimeTicks::Now();
|
| -
|
| - waiting_state_.color =
|
| - tp->GetColor(ThemeProperties::COLOR_THROBBER_WAITING);
|
| - gfx::PaintThrobberSpinningAfterWaiting(
|
| - canvas, bounds,
|
| - tp->GetColor(ThemeProperties::COLOR_THROBBER_SPINNING),
|
| - base::TimeTicks::Now() - loading_start_time_, &waiting_state_);
|
| - }
|
| + // Throbber will do its own painting.
|
| } else if (should_display_crashed_favicon_) {
|
| // Paint crash favicon.
|
| ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
|
| @@ -1387,8 +1424,7 @@ void Tab::PaintIcon(gfx::Canvas* canvas) {
|
| }
|
| }
|
|
|
| -void Tab::AdvanceLoadingAnimation(TabRendererData::NetworkState old_state,
|
| - TabRendererData::NetworkState state) {
|
| +void Tab::AdvanceLoadingAnimation(TabRendererData::NetworkState state) {
|
| if (state == TabRendererData::NETWORK_STATE_WAITING) {
|
| // Waiting steps backwards.
|
| immersive_loading_step_ =
|
| @@ -1398,16 +1434,25 @@ void Tab::AdvanceLoadingAnimation(TabRendererData::NetworkState old_state,
|
| immersive_loading_step_ = (immersive_loading_step_ + 1) %
|
| kImmersiveLoadingStepCount;
|
| } else {
|
| - waiting_start_time_ = base::TimeTicks();
|
| - loading_start_time_ = base::TimeTicks();
|
| - waiting_state_ = gfx::ThrobberWaitingState();
|
| immersive_loading_step_ = 0;
|
| }
|
| +
|
| if (controller_->IsImmersiveStyle()) {
|
| SchedulePaintInRect(GetImmersiveBarRect());
|
| - } else {
|
| + return;
|
| + }
|
| +
|
| + const bool needs_throbber = state != TabRendererData::NETWORK_STATE_NONE;
|
| + if (needs_throbber && !throbber_) {
|
| + throbber_ = new ThrobberView(this, favicon_bounds_);
|
| + ScheduleIconPaint(); // Repaint the icon area to not show the icon.
|
| + } else if (!needs_throbber) {
|
| + delete throbber_;
|
| + throbber_ = nullptr;
|
| ScheduleIconPaint();
|
| }
|
| + if (throbber_)
|
| + throbber_->SchedulePaint();
|
| }
|
|
|
| int Tab::IconCapacity() const {
|
|
|