comparison src/ui_spinner.c @ 9:d907d608745f

Sync to GQview 1.5.9 release. ######## DO NOT BASE ENHANCEMENTS OR TRANSLATION UPDATES ON CODE IN THIS CVS! This CVS is never up to date with current development and is provided solely for reference purposes, please use the latest official release package when making any changes or translation updates. ########
author gqview
date Sat, 26 Feb 2005 00:13:35 +0000
parents
children 4b2d7f9af171
comparison
equal deleted inserted replaced
8:e0d0593d519e 9:d907d608745f
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