music.c: cosmetix
[k8lowj.git] / src / throbber.c
blob2948aa502ce918789a0461610a38bb5f23dc64c3
1 /* logjam - a GTK client for LiveJournal.
2 * Copyright (C) 2000-2003 Evan Martin <evan@livejournal.com>
4 * vim: tabstop=4 shiftwidth=4 noexpandtab :
5 */
7 #include "gtk-all.h"
9 #include <string.h>
11 #ifdef HAVE_LIBRSVG
12 #include <librsvg/rsvg.h>
13 #include "logo-svg.h"
14 #else
15 #include "icons.h"
16 #endif
18 #include "throbber.h"
19 #include "util.h"
21 struct _Throbber {
22 GtkImage parent;
23 guint tag;
25 #ifdef HAVE_LIBRSVG
26 int angle;
27 #else
28 int state;
29 GdkPixbuf *pb[THROBBER_COUNT];
30 #endif
34 #ifdef HAVE_LIBRSVG
35 /* delay in ms between frames of the throbber */
36 #define THROBBER_FRAME_DELAY 20
37 static void update_svg(Throbber *t);
39 void
40 throbber_reset(Throbber *t) {
41 t->angle = 0;
42 update_svg(t);
45 static void
46 throbber_finalize(GObject *object) {
47 GObjectClass *parent_class;
49 throbber_stop(THROBBER(object));
51 parent_class = g_type_class_peek_parent(G_OBJECT_GET_CLASS(object));
52 parent_class->finalize(object);
55 static void
56 size_cb(gint *width, gint *height, gpointer data) {
57 *width = *height = 48;
60 static void
61 update_svg(Throbber *t) {
62 RsvgHandle *handle;
63 GdkPixbuf *pb;
64 char *transform;
65 GError *err = NULL;
67 handle = rsvg_handle_new();
68 rsvg_handle_set_size_callback(handle, size_cb, NULL, NULL);
70 if (!rsvg_handle_write(handle,
71 (unsigned char*)logo_svg_data_1, sizeof(logo_svg_data_1)-1,
72 &err)) {
73 g_print("error: %s\n", err->message);
74 g_error_free(err);
75 return;
78 transform = g_strdup_printf(
79 "transform=\"translate(%d, %d) rotate(%d) translate(%d, %d)\"\n",
80 logo_svg_translate2_x, logo_svg_translate2_y,
81 t->angle,
82 logo_svg_translate1_x, logo_svg_translate1_y);
83 rsvg_handle_write(handle, (unsigned char*)transform, strlen(transform), NULL);
84 g_free(transform);
86 if (!rsvg_handle_write(handle,
87 (unsigned char*)logo_svg_data_2, sizeof(logo_svg_data_2)-1,
88 &err)) {
89 g_print("error: %s\n", err->message);
90 g_error_free(err);
91 return;
93 if (!rsvg_handle_close(handle, &err)) {
94 g_print("error: %s\n", err->message);
95 g_error_free(err);
96 return;
99 pb = rsvg_handle_get_pixbuf(handle);
101 gtk_image_set_from_pixbuf(GTK_IMAGE(t), pb);
102 g_object_unref(G_OBJECT(pb));
103 rsvg_handle_free(handle);
106 static gboolean
107 throbber_cb(Throbber *t) {
108 t->angle += 3;
109 update_svg(t);
110 return TRUE;
113 #else
114 /* we're doing the image-based throbber. */
116 /* delay in ms between frames of the throbber */
117 #define THROBBER_FRAME_DELAY 400
119 void
120 throbber_reset(Throbber *t) {
121 icons_load_throbber(t->pb);
122 gtk_image_set_from_pixbuf(GTK_IMAGE(t), t->pb[0]);
125 static gboolean
126 throbber_cb(Throbber *t) {
127 t->state = (t->state + 1) % THROBBER_COUNT;
128 gtk_image_set_from_pixbuf(GTK_IMAGE(t), t->pb[t->state]);
129 return TRUE;
132 static void
133 throbber_finalize(GObject *object) {
134 GObjectClass *parent_class;
135 int i;
137 throbber_stop(THROBBER(object));
138 for (i = 0; i < THROBBER_COUNT; i++)
139 g_object_unref(G_OBJECT(THROBBER(object)->pb[i]));
141 parent_class = g_type_class_peek_parent(G_OBJECT_GET_CLASS(object));
142 parent_class->finalize(object);
146 #endif
148 static void
149 throbber_init(Throbber *t) {
150 throbber_reset(t);
153 void
154 throbber_start(Throbber *t) {
155 if (t->tag)
156 return;
157 t->tag = gtk_timeout_add(THROBBER_FRAME_DELAY,
158 (GSourceFunc)throbber_cb, t);
160 void
161 throbber_stop(Throbber *t) {
162 if (!t->tag)
163 return;
164 gtk_timeout_remove(t->tag);
165 t->tag = 0;
168 static void
169 throbber_class_init(gpointer klass, gpointer class_data) {
170 GObjectClass *gclass = G_OBJECT_CLASS(klass);
172 gclass->finalize = throbber_finalize;
175 GType
176 throbber_get_type(void) {
177 static GType throbber_type = 0;
178 if (!throbber_type) {
179 static const GTypeInfo throbber_info = {
180 sizeof (GtkImageClass),
181 NULL,
182 NULL,
183 (GClassInitFunc) throbber_class_init,
184 NULL,
185 NULL,
186 sizeof (Throbber),
188 (GInstanceInitFunc) throbber_init,
190 throbber_type = g_type_register_static(GTK_TYPE_IMAGE, "Throbber",
191 &throbber_info, 0);
193 return throbber_type;
196 GtkWidget*
197 throbber_new(void) {
198 Throbber *throbber =
199 THROBBER(g_object_new(throbber_get_type(), NULL));
200 return GTK_WIDGET(throbber);