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#ifndef UI_VIEWS_CONTROLS_THROBBER_H_
6#define UI_VIEWS_CONTROLS_THROBBER_H_
7
8#include "base/basictypes.h"
9#include "base/compiler_specific.h"
10#include "base/time/time.h"
11#include "base/timer/timer.h"
12#include "ui/views/view.h"
13
14namespace gfx {
15class ImageSkia;
16}
17
18namespace views {
19
20// Throbbers display an animation, usually used as a status indicator.
21
22class VIEWS_EXPORT Throbber : public View {
23 public:
24  // |frame_time_ms| is the amount of time that should elapse between frames
25  //                 (in milliseconds)
26  // If |paint_while_stopped| is false, this view will be invisible when not
27  // running.
28  Throbber(int frame_time_ms, bool paint_while_stopped);
29  Throbber(int frame_time_ms, bool paint_while_stopped, gfx::ImageSkia* frames);
30  virtual ~Throbber();
31
32  // Start and stop the throbber animation
33  virtual void Start();
34  virtual void Stop();
35
36  // Set custom throbber frames. Otherwise IDR_THROBBER is loaded.
37  void SetFrames(const gfx::ImageSkia* frames);
38
39  // Overridden from View:
40  virtual gfx::Size GetPreferredSize() const OVERRIDE;
41  virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE;
42
43 protected:
44  // Specifies whether the throbber is currently animating or not
45  bool running_;
46
47 private:
48  void Run();
49
50  bool paint_while_stopped_;
51  int frame_count_;  // How many frames we have.
52  base::Time start_time_;  // Time when Start was called.
53  const gfx::ImageSkia* frames_;  // Frames images.
54  base::TimeDelta frame_time_;  // How long one frame is displayed.
55  base::RepeatingTimer<Throbber> timer_;  // Used to schedule Run calls.
56
57  DISALLOW_COPY_AND_ASSIGN(Throbber);
58};
59
60// A SmoothedThrobber is a throbber that is representing potentially short
61// and nonoverlapping bursts of work.  SmoothedThrobber ignores small
62// pauses in the work stops and starts, and only starts its throbber after
63// a small amount of work time has passed.
64class VIEWS_EXPORT SmoothedThrobber : public Throbber {
65 public:
66  explicit SmoothedThrobber(int frame_delay_ms);
67  SmoothedThrobber(int frame_delay_ms, gfx::ImageSkia* frames);
68  virtual ~SmoothedThrobber();
69
70  virtual void Start() OVERRIDE;
71  virtual void Stop() OVERRIDE;
72
73  void set_start_delay_ms(int value) { start_delay_ms_ = value; }
74  void set_stop_delay_ms(int value) { stop_delay_ms_ = value; }
75
76 private:
77  // Called when the startup-delay timer fires
78  // This function starts the actual throbbing.
79  void StartDelayOver();
80
81  // Called when the shutdown-delay timer fires.
82  // This function stops the actual throbbing.
83  void StopDelayOver();
84
85  // Delay after work starts before starting throbber, in milliseconds.
86  int start_delay_ms_;
87
88  // Delay after work stops before stopping, in milliseconds.
89  int stop_delay_ms_;
90
91  base::OneShotTimer<SmoothedThrobber> start_timer_;
92  base::OneShotTimer<SmoothedThrobber> stop_timer_;
93
94  DISALLOW_COPY_AND_ASSIGN(SmoothedThrobber);
95};
96
97// A CheckmarkThrobber is a special variant of throbber that has three states:
98//   1. not yet completed (which paints nothing)
99//   2. working (which paints the throbber animation)
100//   3. completed (which paints a checkmark)
101//
102class VIEWS_EXPORT CheckmarkThrobber : public Throbber {
103 public:
104  CheckmarkThrobber();
105
106  // If checked is true, the throbber stops spinning and displays a checkmark.
107  // If checked is false, the throbber stops spinning and displays nothing.
108  void SetChecked(bool checked);
109
110  // Overridden from Throbber:
111  virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE;
112
113 private:
114  static const int kFrameTimeMs = 30;
115
116  // Whether or not we should display a checkmark.
117  bool checked_;
118
119  // The checkmark image.
120  const gfx::ImageSkia* checkmark_;
121
122  DISALLOW_COPY_AND_ASSIGN(CheckmarkThrobber);
123};
124
125}  // namespace views
126
127#endif  // UI_VIEWS_CONTROLS_THROBBER_H_
128