0.8.0
[geeqie.git] / src / slideshow.c
1 /*
2  * GQview image viewer
3  * (C)2000 John Ellis
4  *
5  * Author: John Ellis
6  *
7  */
8
9 #include "gqview.h"
10
11 static GList *slide_list = NULL;
12 static GList *past_slide_list = NULL;
13 static gchar *slide_img = NULL;
14 static gchar *slide_path = NULL;
15 static gint slide_count = 0;
16 static gint slide_active = FALSE;
17 static gint slide_sel_list = FALSE;
18 static gint slide_timeout_id = -1;
19
20 static void slideshow_free_all()
21 {
22         slide_active = FALSE;
23
24         g_list_free(slide_list);
25         slide_list = NULL;
26
27         g_list_free(past_slide_list);
28         past_slide_list = NULL;
29
30         g_free(slide_path);
31         slide_path = NULL;
32
33         g_free(slide_img);
34         slide_img = NULL;
35
36         slide_count = 0;
37         slide_sel_list = FALSE;
38 }
39
40 static GList *generate_list()
41 {
42         GList *list = NULL;
43
44         if (file_selection_count() < 2)
45                 {
46                 gint i;
47                 gint c = file_count();
48                 for(i = 0; i < c; i++)
49                         {
50                         list = g_list_prepend(list, GINT_TO_POINTER(i));
51                         }
52                 slide_sel_list = FALSE;
53                 }
54         else
55                 {
56                 GList *work = GTK_CLIST(file_clist)->selection;
57                 while(work)
58                         {
59                         list = g_list_prepend(list, work->data);
60                         work = work->next;
61                         }
62                 slide_sel_list = TRUE;
63                 }
64         list = g_list_reverse(list);
65
66         return list;
67 }
68
69 static GList *generate_random_list()
70 {
71         GList *src_list = NULL;
72         GList *list = NULL;
73         GList *work;
74
75         src_list = generate_list();
76
77         while(src_list)
78                 {
79                 gint p = (float)rand() / RAND_MAX * g_list_length(src_list);
80                 work = g_list_nth(src_list, p);
81                 list = g_list_prepend(list, work->data);
82                 src_list = g_list_remove(src_list, work->data);
83                 }
84
85         return list;
86 }
87
88 static void slideshow_init_list()
89 {
90         if (slide_list)
91                 {
92                 g_list_free(slide_list);
93                 }
94
95         if (past_slide_list)
96                 {
97                 g_list_free(past_slide_list);
98                 past_slide_list = NULL;
99                 }
100
101         if (slideshow_random)
102                 {
103                 slide_list = generate_random_list();
104                 }
105         else
106                 {
107                 slide_list = generate_list();
108                 }
109 }
110
111 static void slideshow_move_list(gint forward)
112 {
113         if (forward)
114                 {
115                 if (slide_list)
116                         {
117                         past_slide_list = g_list_prepend (past_slide_list, slide_list->data);
118                         slide_list = g_list_remove(slide_list, slide_list->data);
119                         }
120                 }
121         else
122                 {
123                 if (past_slide_list)
124                         {
125                         slide_list = g_list_prepend(slide_list, past_slide_list->data);
126                         past_slide_list = g_list_remove(past_slide_list, past_slide_list->data);
127                         }
128                 }
129 }
130
131 static gint slideshow_should_continue()
132 {
133         if (!slide_active || !slide_list || !slide_path ||
134             slide_count != file_count() ||
135             (slide_img && image_get_path() && strcmp(image_get_path(), slide_img) != 0) ||
136             current_path == NULL ||
137             strcmp(current_path, slide_path) != 0)
138                 {
139                 return FALSE;
140                 }
141
142         return TRUE;
143 }
144
145 static gint real_slideshow_prev()
146 {
147         gint row;
148         gchar *buf;
149
150         if (!slide_active) return FALSE;
151         if (!past_slide_list || !past_slide_list->next) return TRUE;
152
153         if (!slideshow_should_continue())
154                 {
155                 slideshow_free_all();
156                 slide_timeout_id = -1;
157                 return FALSE;
158                 }
159
160         slideshow_move_list(FALSE);
161
162         row = GPOINTER_TO_INT(past_slide_list->data);
163
164         g_free(slide_img);
165         slide_img = NULL;
166         buf = file_get_path(row);
167
168         if (slide_sel_list)
169                 {
170                 image_change_to(buf);
171                 update_status_label(NULL);
172                 }
173         else
174                 {
175                 file_image_change_to(row);
176                 }
177
178         slide_img = buf;
179
180         return TRUE;
181 }
182
183 /* the return is TRUE if slideshow should continue */
184 static gint real_slideshow_next()
185 {
186         gint row;
187         gchar *buf;
188
189         if (!slide_active) return FALSE;
190
191         if (!slideshow_should_continue())
192                 {
193                 slideshow_free_all();
194                 slide_timeout_id = -1;
195                 return FALSE;
196                 }
197
198         row = GPOINTER_TO_INT(slide_list->data);
199
200         g_free(slide_img);
201         slide_img = NULL;
202         buf = file_get_path(row);
203         slideshow_move_list(TRUE);
204
205         if (!slide_list && slideshow_repeat)
206                 {
207                 slideshow_init_list();
208                 }
209
210         if (slide_sel_list)
211                 {
212                 image_change_to(buf);
213                 update_status_label(NULL);
214                 }
215         else
216                 {
217                 file_image_change_to(row);
218                 }
219
220         slide_img = buf;
221
222         if (!slide_list)
223                 {
224                 slideshow_free_all();
225                 slide_timeout_id = -1;
226                 return FALSE;
227                 }
228
229         return TRUE;
230 }
231
232 static gint slideshow_loop_cb(gpointer data)
233 {
234         return real_slideshow_next();
235 }
236
237 void slideshow_start()
238 {
239         gint row;
240         gchar *buf;
241
242         if (slide_active) return;
243
244         if (file_count() < 2) return;
245
246         slideshow_init_list();
247         if (!slide_list) return;
248
249         row = GPOINTER_TO_INT(slide_list->data);
250
251         slide_active = TRUE;
252         slide_path = g_strdup(current_path);
253         slide_count = file_count();
254         g_free(slide_img);
255         slide_img = NULL;
256         buf = file_get_path(row);
257         slideshow_move_list(TRUE);
258
259         if (slide_sel_list)
260                 {
261                 image_change_to(buf);
262                 update_status_label(NULL);
263                 }
264         else
265                 {
266                 file_image_change_to(row);
267                 }
268
269         slide_img = buf;
270
271         slide_timeout_id = gtk_timeout_add(slideshow_delay * 1000, slideshow_loop_cb, NULL);
272 }
273
274 void slideshow_stop()
275 {
276         if (!slide_active) return;
277
278         slideshow_free_all();
279         if (slide_timeout_id != -1)
280                 {
281                 gtk_timeout_remove(slide_timeout_id);
282                 slide_timeout_id = -1;
283                 }
284         update_status_label(NULL);
285 }
286
287 static void slideshow_reset_timeout(gint reset)
288 {
289         if (reset)
290                 {
291                 if (slide_timeout_id != -1) gtk_timeout_remove(slide_timeout_id);
292                 slide_timeout_id = gtk_timeout_add(slideshow_delay * 1000, slideshow_loop_cb, NULL);
293                 }
294         else
295                 {
296                 if (slide_timeout_id != -1)
297                         {
298                         gtk_timeout_remove(slide_timeout_id);
299                         slide_timeout_id = -1;
300                         }
301                 }
302 }
303
304 void slideshow_next()
305 {
306         if (!slide_active) return;
307         slideshow_reset_timeout(real_slideshow_next());
308 }
309
310 void slideshow_prev()
311 {
312         if (!slide_active) return;
313         slideshow_reset_timeout(real_slideshow_prev());
314 }
315
316 void slideshow_toggle()
317 {
318         if (!slide_active)
319                 {
320                 slideshow_start();
321                 }
322         else
323                 {
324                 slideshow_stop();
325                 }
326 }
327
328 gint slideshow_is_running()
329 {
330         if (!slide_active) return FALSE;
331
332         if (!slideshow_should_continue())
333                 {
334                 slideshow_free_all();
335                 if (slide_timeout_id != -1)
336                         {
337                         gtk_timeout_remove(slide_timeout_id);
338                         slide_timeout_id = -1;
339                         }
340                 return FALSE;
341                 }
342
343         return TRUE;
344 }
345