Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / ui / views / controls / throbber.cc
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.
4
5 #include "ui/views/controls/throbber.h"
6
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"
13
14 using base::Time;
15 using base::TimeDelta;
16
17 namespace views {
18
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());
27 }
28
29 Throbber::~Throbber() {
30   Stop();
31 }
32
33 void Throbber::Start() {
34   if (running_)
35     return;
36
37   start_time_ = Time::Now();
38
39   timer_.Start(FROM_HERE, frame_time_ - TimeDelta::FromMilliseconds(10),
40                this, &Throbber::Run);
41
42   running_ = true;
43
44   SchedulePaint();  // paint right away
45 }
46
47 void Throbber::Stop() {
48   if (!running_)
49     return;
50
51   timer_.Stop();
52
53   running_ = false;
54   SchedulePaint();  // Important if we're not painting while stopped
55 }
56
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();
63 }
64
65 void Throbber::Run() {
66   DCHECK(running_);
67
68   SchedulePaint();
69 }
70
71 gfx::Size Throbber::GetPreferredSize() const {
72   return gfx::Size(frames_->height(), frames_->height());
73 }
74
75 void Throbber::OnPaint(gfx::Canvas* canvas) {
76   if (!running_ && !paint_while_stopped_)
77     return;
78
79   const TimeDelta elapsed_time = Time::Now() - start_time_;
80   const int current_frame =
81       static_cast<int>(elapsed_time / frame_time_) % frame_count_;
82
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);
89 }
90
91
92
93 // Smoothed throbber ---------------------------------------------------------
94
95
96 // Delay after work starts before starting throbber, in milliseconds.
97 static const int kStartDelay = 200;
98
99 // Delay after work stops before stopping, in milliseconds.
100 static const int kStopDelay = 50;
101
102
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) {
107 }
108
109 SmoothedThrobber::~SmoothedThrobber() {}
110
111 void SmoothedThrobber::Start() {
112   stop_timer_.Stop();
113
114   if (!running_ && !start_timer_.IsRunning()) {
115     start_timer_.Start(FROM_HERE, TimeDelta::FromMilliseconds(start_delay_ms_),
116                        this, &SmoothedThrobber::StartDelayOver);
117   }
118 }
119
120 void SmoothedThrobber::StartDelayOver() {
121   Throbber::Start();
122 }
123
124 void SmoothedThrobber::Stop() {
125   if (!running_)
126     start_timer_.Stop();
127
128   stop_timer_.Stop();
129   stop_timer_.Start(FROM_HERE, TimeDelta::FromMilliseconds(stop_delay_ms_),
130                     this, &SmoothedThrobber::StopDelayOver);
131 }
132
133 void SmoothedThrobber::StopDelayOver() {
134   Throbber::Stop();
135 }
136
137 // Checkmark throbber ---------------------------------------------------------
138
139 CheckmarkThrobber::CheckmarkThrobber()
140     : Throbber(kFrameTimeMs, false),
141       checked_(false),
142       checkmark_(ui::ResourceBundle::GetSharedInstance().GetImageNamed(
143           IDR_CHECKMARK).ToImageSkia()) {
144 }
145
146 void CheckmarkThrobber::SetChecked(bool checked) {
147   bool changed = checked != checked_;
148   if (changed) {
149     checked_ = checked;
150     SchedulePaint();
151   }
152 }
153
154 void CheckmarkThrobber::OnPaint(gfx::Canvas* canvas) {
155   if (running_) {
156     // Let the throbber throb...
157     Throbber::OnPaint(canvas);
158     return;
159   }
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);
165   }
166 }
167
168 }  // namespace views