9
|
1 /*
|
|
2 * (SLIK) SimpLIstic sKin functions
|
|
3 * (C) 2004 John Ellis
|
|
4 *
|
|
5 * Author: John Ellis
|
|
6 *
|
|
7 * This software is released under the GNU General Public License (GNU GPL).
|
|
8 * Please read the included file COPYING for more information.
|
|
9 * This software comes with no warranty of any kind, use at your own risk!
|
|
10 */
|
|
11
|
|
12 #ifdef HAVE_CONFIG_H
|
|
13 # include "config.h"
|
|
14 #endif
|
|
15 #include "intl.h"
|
|
16
|
|
17 #include <stdio.h>
|
|
18 #include <stdlib.h>
|
|
19 #include <string.h>
|
|
20
|
|
21 #include <gtk/gtk.h>
|
|
22
|
|
23 #include "ui_spinner.h"
|
|
24
|
|
25 #include "ui_icons.h"
|
|
26 #include "ui_fileops.h"
|
|
27
|
|
28
|
|
29 #define SPINNER_FRAMES 19
|
|
30
|
|
31
|
|
32 /*
|
|
33 *-----------------------------------------------------------------------------
|
|
34 * spinner utility
|
|
35 *-----------------------------------------------------------------------------
|
|
36 */
|
|
37
|
|
38 typedef struct _SpinnerData SpinnerData;
|
|
39 struct _SpinnerData {
|
|
40 GtkWidget *image;
|
|
41 GList *list; /* list of pixbufs */
|
|
42 gint frame;
|
|
43 gint timer_id;
|
|
44 };
|
|
45
|
|
46 static void spinner_set_frame(SpinnerData *sp, gint frame)
|
|
47 {
|
|
48 GdkPixbuf *pb;
|
|
49
|
|
50 pb = g_list_nth_data(sp->list, frame);
|
|
51 if (pb) gtk_image_set_from_pixbuf(GTK_IMAGE(sp->image), pb);
|
|
52
|
|
53 sp->frame = frame;
|
|
54 }
|
|
55
|
|
56 static void spinner_increment_frame(SpinnerData *sp)
|
|
57 {
|
|
58 sp->frame++;
|
|
59 if (sp->frame >= g_list_length(sp->list)) sp->frame = 1;
|
|
60 spinner_set_frame(sp, sp->frame);
|
|
61 }
|
|
62
|
|
63 static gboolean spinner_loop_cb(gpointer data)
|
|
64 {
|
|
65 SpinnerData *sp = data;
|
|
66
|
|
67 if (sp->list) spinner_increment_frame(sp);
|
|
68
|
|
69 return TRUE;
|
|
70 }
|
|
71
|
|
72 static void spinner_set_timeout(SpinnerData *sp, gint interval)
|
|
73 {
|
|
74 if (!sp) return;
|
|
75
|
|
76 if (sp->timer_id != -1)
|
|
77 {
|
|
78 g_source_remove(sp->timer_id);
|
|
79 sp->timer_id = -1;
|
|
80 }
|
|
81
|
|
82 if (interval > 0)
|
|
83 {
|
|
84 sp->timer_id = g_timeout_add(interval, spinner_loop_cb, sp);
|
|
85 }
|
|
86 else if (interval < 0)
|
|
87 {
|
|
88 spinner_set_frame(sp, 0);
|
|
89 }
|
|
90
|
|
91 gtk_widget_set_sensitive(sp->image, (interval >= 0));
|
|
92 }
|
|
93
|
|
94 static void spinner_destroy_cb(GtkWidget *widget, gpointer data)
|
|
95 {
|
|
96 SpinnerData *sp = data;
|
|
97 GList *work;
|
|
98
|
|
99 spinner_set_timeout(sp, 0);
|
|
100
|
|
101 work = sp->list;
|
|
102 while (work)
|
|
103 {
|
|
104 GdkPixbuf *pb = work->data;
|
|
105 work = work->next;
|
|
106
|
|
107 g_object_unref(pb);
|
|
108 }
|
|
109 g_list_free(sp->list);
|
|
110 g_free(sp);
|
|
111 }
|
|
112
|
|
113 GtkWidget *spinner_new(const gchar *path, gint interval)
|
|
114 {
|
|
115 SpinnerData *sp;
|
|
116
|
|
117 sp = g_new0(SpinnerData, 1);
|
|
118 sp->list = NULL;
|
|
119 sp->timer_id = -1;
|
|
120
|
|
121 if (path)
|
|
122 {
|
|
123 gchar *pathl;
|
|
124 GdkPixbuf *pb;
|
|
125 gint n;
|
|
126 gchar *buf;
|
|
127
|
|
128 pathl = path_from_utf8(path);
|
|
129
|
|
130 n = 0;
|
|
131 buf = g_strdup_printf("%s%02d.png", pathl, n);
|
|
132 while ((pb = gdk_pixbuf_new_from_file(buf, NULL)))
|
|
133 {
|
|
134 sp->list = g_list_append(sp->list, pb);
|
|
135
|
|
136 n++;
|
|
137 g_free(buf);
|
|
138 buf = g_strdup_printf("%s%02d.png", pathl, n);
|
|
139 }
|
|
140 g_free(buf);
|
|
141
|
|
142 g_free(pathl);
|
|
143 }
|
|
144
|
|
145 if (!sp->list)
|
|
146 {
|
|
147 GdkPixbuf *pb;
|
|
148 gint n;
|
|
149 gint w, h;
|
|
150
|
|
151 pb = gdk_pixbuf_new_from_inline (-1, icon_spinner, FALSE, NULL);
|
|
152 w = gdk_pixbuf_get_width(pb);
|
|
153 h = gdk_pixbuf_get_height(pb) / SPINNER_FRAMES;
|
|
154 for (n = 0; n < SPINNER_FRAMES; n++)
|
|
155 {
|
|
156 sp->list = g_list_append(sp->list,
|
|
157 gdk_pixbuf_new_subpixbuf(pb, 0, n * h, w, h));
|
|
158 }
|
|
159 /* pb pixels is inline static, so the subpixbufs in sp->list will be ok */
|
|
160 g_object_unref(pb);
|
|
161 }
|
|
162
|
|
163 if (sp->list)
|
|
164 {
|
|
165 GdkPixbuf *pb;
|
|
166
|
|
167 pb = sp->list->data;
|
|
168 sp->image = gtk_image_new_from_pixbuf(pb);
|
|
169 }
|
|
170 else
|
|
171 {
|
|
172 sp->image = gtk_image_new_from_stock(GTK_STOCK_MISSING_IMAGE, GTK_ICON_SIZE_DIALOG);
|
|
173 }
|
|
174
|
|
175 g_object_set_data(G_OBJECT(sp->image), "spinner", sp);
|
|
176
|
|
177 g_signal_connect(G_OBJECT(sp->image), "destroy",
|
|
178 G_CALLBACK(spinner_destroy_cb), sp);
|
|
179
|
|
180 spinner_set_timeout(sp, interval);
|
|
181
|
|
182 return sp->image;
|
|
183 }
|
|
184
|
|
185 void spinner_set_interval(GtkWidget *spinner, gint interval)
|
|
186 {
|
|
187 SpinnerData *sp;
|
|
188
|
|
189 sp = g_object_get_data(G_OBJECT(spinner), "spinner");
|
|
190
|
|
191 spinner_set_timeout(sp, interval);
|
|
192 }
|
|
193
|
|
194 void spinner_step(GtkWidget *spinner, gint reset)
|
|
195 {
|
|
196 SpinnerData *sp;
|
|
197
|
|
198 sp = g_object_get_data(G_OBJECT(spinner), "spinner");
|
|
199 if (sp->timer_id != -1)
|
|
200 {
|
|
201 printf("spinner warning: attempt to step with timer set\n");
|
|
202 return;
|
|
203 }
|
|
204
|
|
205 if (reset)
|
|
206 {
|
|
207 spinner_set_frame(sp, 0);
|
|
208 }
|
|
209 else
|
|
210 {
|
|
211 spinner_increment_frame(sp);
|
|
212 }
|
|
213 }
|
|
214
|