Drive: Add BatchableRequest subclass.
[chromium-blink-merge.git] / ui / views / controls / throbber.cc
blobd1d5c1d892369a72213428a065f38d43ab2451a3
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
3 // found in the LICENSE file.
5 #include "ui/views/controls/throbber.h"
7 #include "base/time/time.h"
8 #include "ui/base/resource/resource_bundle.h"
9 #include "ui/gfx/canvas.h"
10 #include "ui/gfx/image/image.h"
11 #include "ui/gfx/image/image_skia.h"
12 #include "ui/resources/grit/ui_resources.h"
14 using base::Time;
15 using base::TimeDelta;
17 namespace views {
19 Throbber::Throbber(int frame_time_ms,
20 bool paint_while_stopped)
21 : running_(false),
22 paint_while_stopped_(paint_while_stopped),
23 frames_(NULL),
24 frame_time_(TimeDelta::FromMilliseconds(frame_time_ms)) {
25 SetFrames(ui::ResourceBundle::GetSharedInstance().GetImageNamed(
26 IDR_THROBBER).ToImageSkia());
29 Throbber::~Throbber() {
30 Stop();
33 void Throbber::Start() {
34 if (running_)
35 return;
37 start_time_ = Time::Now();
39 timer_.Start(FROM_HERE, frame_time_ - TimeDelta::FromMilliseconds(10),
40 this, &Throbber::Run);
42 running_ = true;
44 SchedulePaint(); // paint right away
47 void Throbber::Stop() {
48 if (!running_)
49 return;
51 timer_.Stop();
53 running_ = false;
54 SchedulePaint(); // Important if we're not painting while stopped
57 void Throbber::SetFrames(const gfx::ImageSkia* frames) {
58 frames_ = frames;
59 DCHECK(frames_->width() > 0 && frames_->height() > 0);
60 DCHECK(frames_->width() % frames_->height() == 0);
61 frame_count_ = frames_->width() / frames_->height();
62 PreferredSizeChanged();
65 void Throbber::Run() {
66 DCHECK(running_);
68 SchedulePaint();
71 gfx::Size Throbber::GetPreferredSize() const {
72 return gfx::Size(frames_->height(), frames_->height());
75 void Throbber::OnPaint(gfx::Canvas* canvas) {
76 if (!running_ && !paint_while_stopped_)
77 return;
79 const TimeDelta elapsed_time = Time::Now() - start_time_;
80 const int current_frame =
81 static_cast<int>(elapsed_time / frame_time_) % frame_count_;
83 int image_size = frames_->height();
84 int image_offset = current_frame * image_size;
85 canvas->DrawImageInt(*frames_,
86 image_offset, 0, image_size, image_size,
87 0, 0, image_size, image_size,
88 false);
93 // Smoothed throbber ---------------------------------------------------------
96 // Delay after work starts before starting throbber, in milliseconds.
97 static const int kStartDelay = 200;
99 // Delay after work stops before stopping, in milliseconds.
100 static const int kStopDelay = 50;
103 SmoothedThrobber::SmoothedThrobber(int frame_time_ms)
104 : Throbber(frame_time_ms, /* paint_while_stopped= */ false),
105 start_delay_ms_(kStartDelay),
106 stop_delay_ms_(kStopDelay) {
109 SmoothedThrobber::~SmoothedThrobber() {}
111 void SmoothedThrobber::Start() {
112 stop_timer_.Stop();
114 if (!running_ && !start_timer_.IsRunning()) {
115 start_timer_.Start(FROM_HERE, TimeDelta::FromMilliseconds(start_delay_ms_),
116 this, &SmoothedThrobber::StartDelayOver);
120 void SmoothedThrobber::StartDelayOver() {
121 Throbber::Start();
124 void SmoothedThrobber::Stop() {
125 if (!running_)
126 start_timer_.Stop();
128 stop_timer_.Stop();
129 stop_timer_.Start(FROM_HERE, TimeDelta::FromMilliseconds(stop_delay_ms_),
130 this, &SmoothedThrobber::StopDelayOver);
133 void SmoothedThrobber::StopDelayOver() {
134 Throbber::Stop();
137 // Checkmark throbber ---------------------------------------------------------
139 CheckmarkThrobber::CheckmarkThrobber()
140 : Throbber(kFrameTimeMs, false),
141 checked_(false),
142 checkmark_(ui::ResourceBundle::GetSharedInstance().GetImageNamed(
143 IDR_CHECKMARK).ToImageSkia()) {
146 void CheckmarkThrobber::SetChecked(bool checked) {
147 bool changed = checked != checked_;
148 if (changed) {
149 checked_ = checked;
150 SchedulePaint();
154 void CheckmarkThrobber::OnPaint(gfx::Canvas* canvas) {
155 if (running_) {
156 // Let the throbber throb...
157 Throbber::OnPaint(canvas);
158 return;
160 // Otherwise we paint our tick mark or nothing depending on our state.
161 if (checked_) {
162 int checkmark_x = (width() - checkmark_->width()) / 2;
163 int checkmark_y = (height() - checkmark_->height()) / 2;
164 canvas->DrawImageInt(*checkmark_, checkmark_x, checkmark_y);
168 } // namespace views