7 public class Spinner
: Gtk
.Image
{
9 private Pixbuf idlePixbuf
;
10 private Pixbuf
[] frames
;
11 private int currentFrame
;
12 private uint timeoutId
;
14 private const int targetSize
= 24;
15 private const int refreshRate
= 125;
24 protected override void OnRealized ()
28 theme
= Gtk
.IconTheme
.GetForScreen (Screen
);
29 theme
.Changed
+= ThemeChanged
;
33 private void ThemeChanged (object obj
, EventArgs args
)
38 private void LoadImages ()
40 int iconSize
= targetSize
;
43 // This code requires gtk-sharp 2.6, which we don't (yet) require
44 foreach (int size
in theme
.GetIconSizes ("gnome-spinner-rest")) {
45 if (size
>= targetSize
) {
53 idlePixbuf
= theme
.LoadIcon ("gnome-spinner-rest", iconSize
, 0);
55 Console
.Error
.WriteLine ("Could not load spinner image");
61 Gdk
.Pixbuf framesPixbuf
;
63 framesPixbuf
= theme
.LoadIcon ("gnome-spinner", iconSize
, 0);
65 Console
.Error
.WriteLine ("Could not load spinner image");
71 int frameWidth
= idlePixbuf
.Width
, frameHeight
= idlePixbuf
.Height
;
72 int width
= framesPixbuf
.Width
, height
= framesPixbuf
.Height
;
73 if (width
% frameWidth
!= 0 || height
% frameHeight
!= 0) {
74 Console
.Error
.WriteLine ("Spinner image is wrong size");
80 int rows
= height
/ frameHeight
, cols
= width
/ frameWidth
;
82 frames
= new Pixbuf
[rows
* cols
];
84 for (int y
= 0, n
= 0; y
< rows
; y
++) {
85 for (int x
= 0; x
< cols
; x
++, n
++) {
86 frames
[n
] = new Pixbuf (framesPixbuf
,
96 Pixbuf
= frames
[currentFrame
];
105 if (frames
== null || frames
.Length
== 0)
110 timeoutId
= GLib
.Timeout
.Add (refreshRate
, TimeoutHandler
);
118 GLib
.Source
.Remove (timeoutId
);
123 private bool TimeoutHandler ()
125 Pixbuf
= frames
[currentFrame
];
126 currentFrame
= (currentFrame
+ 1) % frames
.Length
;