Mercurial > geeqie.yaz
annotate src/slideshow.c @ 94:50dc5a14d37b
Thu Nov 2 17:51:31 2006 John Ellis <johne@verizon.net>
* collect.c, img-view.c: Make [Shift]+P printing shortcut work for
collections and view windows.
* layout_util.c: Fix shortcuts [Control]+N and [Shift]+P, broken
by the previous keypress handler code cleanup. Add [Control]+V to
view current image in a new image window.
author | gqview |
---|---|
date | Thu, 02 Nov 2006 23:27:03 +0000 |
parents | b3149a34d0dd |
children | 197b8d2e52ce |
rev | line source |
---|---|
1 | 1 /* |
9 | 2 * GQview |
3 * (C) 2004 John Ellis | |
1 | 4 * |
5 * Author: John Ellis | |
6 * | |
9 | 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! | |
1 | 10 */ |
11 | |
9 | 12 |
1 | 13 #include "gqview.h" |
9 | 14 #include "collect.h" |
15 #include "image.h" | |
16 #include "slideshow.h" | |
1 | 17 |
9 | 18 #include "layout.h" |
19 #include "layout_image.h" | |
20 #include "ui_fileops.h" | |
1 | 21 |
9 | 22 |
23 static void slideshow_timer_reset(SlideShowData *ss, gint reset); | |
24 | |
1 | 25 |
9 | 26 void slideshow_free(SlideShowData *ss) |
27 { | |
89
b3149a34d0dd
Sat Oct 28 14:41:10 2006 John Ellis <johne@verizon.net>
gqview
parents:
9
diff
changeset
|
28 if (!ss) return; |
b3149a34d0dd
Sat Oct 28 14:41:10 2006 John Ellis <johne@verizon.net>
gqview
parents:
9
diff
changeset
|
29 |
9 | 30 slideshow_timer_reset(ss, FALSE); |
1 | 31 |
9 | 32 if (ss->stop_func) ss->stop_func(ss, ss->stop_data); |
3 | 33 |
9 | 34 if (ss->path_list) path_list_free(ss->path_list); |
35 if (ss->cd) collection_unref(ss->cd); | |
36 g_free(ss->layout_path); | |
1 | 37 |
9 | 38 g_list_free(ss->list); |
39 g_list_free(ss->list_done); | |
1 | 40 |
9 | 41 g_free(ss->slide_path); |
42 | |
43 g_free(ss); | |
1 | 44 } |
45 | |
9 | 46 static GList *generate_list(SlideShowData *ss) |
1 | 47 { |
48 GList *list = NULL; | |
49 | |
9 | 50 if (ss->from_selection) |
51 { | |
52 list = layout_selection_list_by_index(ss->layout); | |
53 } | |
54 else | |
1 | 55 { |
56 gint i; | |
9 | 57 for(i = 0; i < ss->slide_count; i++) |
1 | 58 { |
59 list = g_list_prepend(list, GINT_TO_POINTER(i)); | |
60 } | |
9 | 61 list = g_list_reverse(list); |
1 | 62 } |
63 | |
64 return list; | |
65 } | |
66 | |
9 | 67 static GList *generate_random_list(SlideShowData *ss) |
1 | 68 { |
69 GList *src_list = NULL; | |
70 GList *list = NULL; | |
71 GList *work; | |
72 | |
9 | 73 src_list = generate_list(ss); |
1 | 74 |
75 while(src_list) | |
76 { | |
9 | 77 gint p = (double)rand() / ((double)RAND_MAX + 1.0) * g_list_length(src_list); |
1 | 78 work = g_list_nth(src_list, p); |
79 list = g_list_prepend(list, work->data); | |
80 src_list = g_list_remove(src_list, work->data); | |
81 } | |
82 | |
83 return list; | |
84 } | |
85 | |
9 | 86 static void slideshow_list_init(SlideShowData *ss, gint start_index) |
1 | 87 { |
9 | 88 if (ss->list_done) |
1 | 89 { |
9 | 90 g_list_free(ss->list_done); |
91 ss->list_done = NULL; | |
1 | 92 } |
93 | |
9 | 94 if (ss->list) g_list_free(ss->list); |
3 | 95 |
1 | 96 if (slideshow_random) |
97 { | |
9 | 98 ss->list = generate_random_list(ss); |
1 | 99 } |
100 else | |
101 { | |
9 | 102 ss->list = generate_list(ss); |
103 if (start_index >= 0) | |
3 | 104 { |
9 | 105 /* start with specified image by skipping to it */ |
106 gint i = 0; | |
107 | |
108 while(ss->list && i < start_index) | |
109 { | |
110 ss->list_done = g_list_prepend (ss->list_done, ss->list->data); | |
111 ss->list = g_list_remove(ss->list, ss->list->data); | |
112 i++; | |
113 } | |
3 | 114 } |
115 } | |
116 } | |
117 | |
9 | 118 gint slideshow_should_continue(SlideShowData *ss) |
1 | 119 { |
9 | 120 const gchar *imd_path; |
121 const gchar *path; | |
122 | |
89
b3149a34d0dd
Sat Oct 28 14:41:10 2006 John Ellis <johne@verizon.net>
gqview
parents:
9
diff
changeset
|
123 if (!ss) return FALSE; |
b3149a34d0dd
Sat Oct 28 14:41:10 2006 John Ellis <johne@verizon.net>
gqview
parents:
9
diff
changeset
|
124 |
9 | 125 imd_path = image_get_path(ss->imd); |
126 | |
127 if ( ((imd_path == NULL) != (ss->slide_path == NULL)) || | |
128 (imd_path && ss->slide_path && strcmp(imd_path, ss->slide_path) != 0) ) return FALSE; | |
129 | |
130 if (ss->path_list) return TRUE; | |
131 | |
132 if (ss->cd) | |
133 { | |
134 if (g_list_length(ss->cd->list) == ss->slide_count) | |
135 return TRUE; | |
136 else | |
137 return FALSE; | |
138 } | |
139 | |
140 if (!ss->layout) return FALSE; | |
141 path = layout_get_path(ss->layout); | |
142 | |
143 if (path && ss->layout_path && | |
144 strcmp(path, ss->layout_path) == 0) | |
145 { | |
146 if (ss->from_selection && ss->slide_count == layout_selection_count(ss->layout, NULL)) return TRUE; | |
147 if (!ss->from_selection && ss->slide_count == layout_list_count(ss->layout, NULL)) return TRUE; | |
148 } | |
149 | |
150 return FALSE; | |
151 } | |
152 | |
153 static gint slideshow_step(SlideShowData *ss, gint forward) | |
154 { | |
155 gint row; | |
156 | |
157 if (!slideshow_should_continue(ss)) | |
1 | 158 { |
159 return FALSE; | |
160 } | |
161 | |
9 | 162 if (forward) |
163 { | |
164 if (!ss->list) return TRUE; | |
1 | 165 |
9 | 166 row = GPOINTER_TO_INT(ss->list->data); |
167 ss->list_done = g_list_prepend (ss->list_done, ss->list->data); | |
168 ss->list = g_list_remove(ss->list, ss->list->data); | |
169 } | |
170 else | |
171 { | |
172 if (!ss->list_done || !ss->list_done->next) return TRUE; | |
3 | 173 |
9 | 174 ss->list = g_list_prepend(ss->list, ss->list_done->data); |
175 ss->list_done = g_list_remove(ss->list_done, ss->list_done->data); | |
176 row = GPOINTER_TO_INT(ss->list_done->data); | |
3 | 177 } |
178 | |
9 | 179 g_free(ss->slide_path); |
180 ss->slide_path = NULL; | |
3 | 181 |
9 | 182 if (ss->path_list) |
183 { | |
184 ss->slide_path = g_strdup(g_list_nth_data(ss->path_list, row)); | |
185 image_change_path(ss->imd, ss->slide_path, image_zoom_get_default(ss->imd, zoom_mode)); | |
186 } | |
187 else if (ss->cd) | |
188 { | |
189 CollectInfo *info; | |
3 | 190 |
9 | 191 info = g_list_nth_data(ss->cd->list, row); |
192 ss->slide_path = g_strdup(info->path); | |
193 | |
194 image_change_from_collection(ss->imd, ss->cd, info, image_zoom_get_default(ss->imd, zoom_mode)); | |
3 | 195 } |
196 else | |
197 { | |
9 | 198 ss->slide_path = g_strdup(layout_list_get_path(ss->layout, row)); |
199 | |
200 if (ss->from_selection) | |
201 { | |
202 image_change_path(ss->imd, ss->slide_path, image_zoom_get_default(ss->imd, zoom_mode)); | |
203 layout_status_update_info(ss->layout, NULL); | |
204 } | |
205 else | |
206 { | |
207 layout_image_set_index(ss->layout, row); | |
208 } | |
3 | 209 } |
210 | |
9 | 211 if (!ss->list && slideshow_repeat) |
212 { | |
213 slideshow_list_init(ss, -1); | |
214 } | |
3 | 215 |
9 | 216 if (!ss->list) |
1 | 217 { |
218 return FALSE; | |
219 } | |
220 | |
9 | 221 /* read ahead */ |
1 | 222 |
9 | 223 if (enable_read_ahead) |
1 | 224 { |
9 | 225 gint r; |
226 if (forward) | |
227 { | |
228 if (!ss->list) return TRUE; | |
229 r = GPOINTER_TO_INT(ss->list->data); | |
230 } | |
231 else | |
232 { | |
233 if (!ss->list_done || !ss->list_done->next) return TRUE; | |
234 r = GPOINTER_TO_INT(ss->list_done->next->data); | |
235 } | |
1 | 236 |
9 | 237 if (ss->path_list) |
238 { | |
239 image_prebuffer_set(ss->imd, g_list_nth_data(ss->path_list, r)); | |
240 } | |
241 else if (ss->cd) | |
242 { | |
243 CollectInfo *info; | |
244 info = g_list_nth_data(ss->cd->list, r); | |
245 if (info) image_prebuffer_set(ss->imd, info->path); | |
246 } | |
247 else if (ss->from_selection) | |
248 { | |
249 image_prebuffer_set(ss->imd, layout_list_get_path(ss->layout, r)); | |
250 } | |
1 | 251 } |
252 | |
253 return TRUE; | |
254 } | |
255 | |
3 | 256 static gint slideshow_loop_cb(gpointer data) |
257 { | |
9 | 258 SlideShowData *ss = data; |
1 | 259 |
9 | 260 if (ss->paused) return TRUE; |
1 | 261 |
9 | 262 if (!slideshow_step(ss, TRUE)) |
3 | 263 { |
9 | 264 ss->timeout_id = -1; |
265 slideshow_free(ss); | |
1 | 266 return FALSE; |
267 } | |
268 | |
269 return TRUE; | |
270 } | |
271 | |
9 | 272 static void slideshow_timer_reset(SlideShowData *ss, gint reset) |
273 { | |
274 if (reset) | |
275 { | |
276 if (slideshow_delay < 1) slideshow_delay = 1; | |
277 | |
278 if (ss->timeout_id != -1) g_source_remove(ss->timeout_id); | |
279 ss->timeout_id = g_timeout_add(slideshow_delay * 1000 / SLIDESHOW_SUBSECOND_PRECISION, | |
280 slideshow_loop_cb, ss); | |
281 } | |
282 else if (ss->timeout_id != -1) | |
283 { | |
284 g_source_remove(ss->timeout_id); | |
285 ss->timeout_id = -1; | |
286 } | |
287 } | |
288 | |
289 void slideshow_next(SlideShowData *ss) | |
290 { | |
89
b3149a34d0dd
Sat Oct 28 14:41:10 2006 John Ellis <johne@verizon.net>
gqview
parents:
9
diff
changeset
|
291 if (!ss) return; |
b3149a34d0dd
Sat Oct 28 14:41:10 2006 John Ellis <johne@verizon.net>
gqview
parents:
9
diff
changeset
|
292 |
9 | 293 if (!slideshow_step(ss, TRUE)) |
294 { | |
295 slideshow_free(ss); | |
296 return; | |
297 } | |
298 | |
299 slideshow_timer_reset(ss, TRUE); | |
300 } | |
301 | |
302 void slideshow_prev(SlideShowData *ss) | |
303 { | |
89
b3149a34d0dd
Sat Oct 28 14:41:10 2006 John Ellis <johne@verizon.net>
gqview
parents:
9
diff
changeset
|
304 if (!ss) return; |
b3149a34d0dd
Sat Oct 28 14:41:10 2006 John Ellis <johne@verizon.net>
gqview
parents:
9
diff
changeset
|
305 |
9 | 306 if (!slideshow_step(ss, FALSE)) |
307 { | |
308 slideshow_free(ss); | |
309 return; | |
310 } | |
311 | |
312 slideshow_timer_reset(ss, TRUE); | |
313 } | |
314 | |
315 static SlideShowData *real_slideshow_start(ImageWindow *imd, LayoutWindow *lw, | |
316 GList *path_list, gint start_point, | |
317 CollectionData *cd, CollectInfo *start_info, | |
318 void (*stop_func)(SlideShowData *, gpointer), gpointer stop_data) | |
319 { | |
320 SlideShowData *ss; | |
321 gint start_index = -1; | |
322 | |
323 if (!path_list && !cd && layout_list_count(lw, NULL) < 1) return NULL; | |
324 | |
325 ss = g_new0(SlideShowData, 1); | |
326 | |
327 ss->imd = imd; | |
328 | |
329 ss->path_list = path_list; | |
330 ss->cd = cd; | |
331 ss->layout = lw; | |
332 ss->layout_path = NULL; | |
333 | |
334 ss->list = NULL; | |
335 ss->list_done = NULL; | |
336 | |
337 ss->from_selection = FALSE; | |
338 | |
339 ss->stop_func = stop_func; | |
340 ss->stop_data = stop_data; | |
341 | |
342 ss->timeout_id = -1; | |
343 | |
344 ss->paused = FALSE; | |
345 | |
346 if (ss->path_list) | |
347 { | |
348 ss->slide_count = g_list_length(ss->path_list); | |
349 } | |
350 else if (ss->cd) | |
351 { | |
352 collection_ref(ss->cd); | |
353 ss->slide_count = g_list_length(ss->cd->list); | |
354 if (!slideshow_random && start_info) | |
355 { | |
356 start_index = g_list_index(ss->cd->list, start_info); | |
357 } | |
358 } | |
359 else | |
360 { | |
361 /* layout method */ | |
362 | |
363 ss->slide_count = layout_selection_count(ss->layout, NULL); | |
364 ss->layout_path = g_strdup(layout_get_path(ss->layout)); | |
365 if (ss->slide_count < 2) | |
366 { | |
367 ss->slide_count = layout_list_count(ss->layout, NULL); | |
368 if (!slideshow_random && start_point >= 0 && start_point < ss->slide_count) | |
369 { | |
370 start_index = start_point; | |
371 } | |
372 } | |
373 else | |
374 { | |
375 ss->from_selection = TRUE; | |
376 } | |
377 } | |
378 | |
379 slideshow_list_init(ss, start_index); | |
380 | |
381 ss->slide_path = g_strdup(image_get_path(ss->imd)); | |
382 if (slideshow_step(ss, TRUE)) | |
383 { | |
384 slideshow_timer_reset(ss, TRUE); | |
385 } | |
386 else | |
387 { | |
388 ss = NULL; | |
389 } | |
390 | |
391 return ss; | |
392 } | |
393 | |
394 SlideShowData *slideshow_start_from_path_list(ImageWindow *imd, GList *list, | |
395 void (*stop_func)(SlideShowData *, gpointer), gpointer stop_data) | |
396 { | |
397 return real_slideshow_start(imd, NULL, list, -1, NULL, NULL, stop_func, stop_data); | |
398 } | |
399 | |
400 SlideShowData *slideshow_start_from_collection(ImageWindow *imd, CollectionData *cd, | |
401 void (*stop_func)(SlideShowData *, gpointer), gpointer stop_data, | |
402 CollectInfo *start_info) | |
403 { | |
404 return real_slideshow_start(imd, NULL, NULL, -1, cd, start_info, stop_func, stop_data); | |
405 } | |
406 | |
407 SlideShowData *slideshow_start(ImageWindow *imd, LayoutWindow *lw, gint start_point, | |
408 void (*stop_func)(SlideShowData *, gpointer), gpointer stop_data) | |
409 { | |
410 return real_slideshow_start(imd, lw, NULL, start_point, NULL, NULL, stop_func, stop_data); | |
411 } | |
412 | |
413 gint slideshow_paused(SlideShowData *ss) | |
414 { | |
415 if (!ss) return FALSE; | |
416 | |
417 return ss->paused; | |
418 } | |
419 | |
420 void slideshow_pause_set(SlideShowData *ss, gint paused) | |
421 { | |
422 if (!ss) return; | |
423 | |
424 ss->paused = paused; | |
425 } | |
426 | |
427 gint slideshow_pause_toggle(SlideShowData *ss) | |
428 { | |
429 slideshow_pause_set(ss, !slideshow_paused(ss)); | |
430 return slideshow_paused(ss); | |
431 } | |
432 | |
433 |