1 /* -*- Mode: C; tab-width: 3; indent-tabs-mode: nil; c-basic-offset: 3 -*- */
2 
3 /*
4  * GImageView
5  * Copyright (C) 2001 Takuro Ashie
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20  *
21  * $Id: gimv_slideshow.c,v 1.4 2004/09/22 14:26:22 makeinu Exp $
22  */
23 
24 #include "gimageview.h"
25 
26 #include "gimv_image_win.h"
27 #include "prefs.h"
28 #include "gimv_slideshow.h"
29 
30 
31 gint            idle_slideshow_delete (gpointer   data);
32 static GList   *next_image            (GimvImageView *iv,
33                                        gpointer   list_owner,
34                                        GList     *current,
35                                        gpointer   data);
36 static GList   *prev_image            (GimvImageView *iv,
37                                        gpointer   list_owner,
38                                        GList     *current,
39                                        gpointer   data);
40 static void     remove_list           (GimvImageView *iv,
41                                        gpointer   list_owner,
42                                        gpointer   data);
43 
44 
45 /******************************************************************************
46  *
47  *  Other private functions
48  *
49  ******************************************************************************/
50 gint
idle_slideshow_delete(gpointer data)51 idle_slideshow_delete (gpointer data)
52 {
53    GimvSlideShow *slideshow = data;
54 
55    gimv_slideshow_delete (slideshow);
56 
57    return 0;
58 }
59 
60 
61 typedef struct ChangeImageData_Tag
62 {
63    GimvSlideShow *slideshow;
64    GimvImageWin  *iw;
65    GimvImageInfo *info;
66 } ChangeImageData;
67 
68 
69 static gboolean
change_image_idle(gpointer user_data)70 change_image_idle (gpointer user_data)
71 {
72    ChangeImageData *data = user_data;
73 
74    gimv_image_win_change_image (data->iw, data->info);
75 
76    return FALSE;
77 }
78 
79 
80 static GList *
next_image(GimvImageView * iv,gpointer list_owner,GList * current,gpointer data)81 next_image (GimvImageView *iv,
82             gpointer list_owner,
83             GList *current,
84             gpointer data)
85 {
86    GimvImageWin *iw = data;
87    GList *next, *node;
88    GimvSlideShow *slideshow = list_owner;
89 
90    g_return_val_if_fail (iv, NULL);
91    g_return_val_if_fail (current, NULL);
92 
93    node = g_list_find (slideshow->filelist, current->data);
94    g_return_val_if_fail (node, NULL);
95 
96    next = g_list_next (current);
97    if (!next && slideshow->repeat)
98       next = g_list_first (current);
99    else if (!next)
100       next = current;
101    g_return_val_if_fail (next, NULL);
102 
103    if (next != current) {
104       ChangeImageData *change_data = g_new0 (ChangeImageData, 1);
105 
106       change_data->slideshow = slideshow;
107       change_data->iw = iw;
108       change_data->info = next->data;
109       gtk_idle_add_full (GTK_PRIORITY_DEFAULT,
110                          change_image_idle,
111                          NULL,
112                          change_data,
113                          (GtkDestroyNotify) g_free);
114       slideshow->current = next;
115    }
116 
117    return next;
118 }
119 
120 
121 static GList *
prev_image(GimvImageView * iv,gpointer list_owner,GList * current,gpointer data)122 prev_image (GimvImageView *iv,
123             gpointer list_owner,
124             GList *current,
125             gpointer data)
126 {
127    GimvImageWin *iw = data;
128    GList *prev, *node;
129    GimvSlideShow *slideshow = list_owner;
130 
131    g_return_val_if_fail (iv, NULL);
132    g_return_val_if_fail (current, NULL);
133 
134    node = g_list_find (slideshow->filelist, current->data);
135    g_return_val_if_fail (node, NULL);
136 
137    prev = g_list_previous (current);
138    if (!prev && slideshow->repeat)
139       prev = g_list_last (current);
140    else if (!prev)
141       prev = current;
142    g_return_val_if_fail (prev, NULL);
143 
144    if (prev != current) {
145       ChangeImageData *change_data = g_new0 (ChangeImageData, 1);
146 
147       change_data->slideshow = slideshow;
148       change_data->iw = iw;
149       change_data->info = prev->data;
150       gtk_idle_add_full (GTK_PRIORITY_DEFAULT,
151                          change_image_idle,
152                          NULL,
153                          change_data,
154                          (GtkDestroyNotify) g_free);
155       slideshow->current = prev;
156    }
157 
158    return prev;
159 }
160 
161 
162 static GList *
nth_image(GimvImageView * iv,gpointer list_owner,GList * list,guint nth,gpointer data)163 nth_image (GimvImageView *iv,
164            gpointer list_owner,
165            GList *list,
166            guint nth,
167            gpointer data)
168 {
169    GimvImageWin *iw = data;
170    GList *node;
171    GimvSlideShow *slideshow = list_owner;
172    ChangeImageData *change_data;
173 
174    g_return_val_if_fail (iv, NULL);
175 
176    node = g_list_nth (slideshow->filelist, nth);
177    g_return_val_if_fail (node, NULL);
178 
179    change_data = g_new0 (ChangeImageData, 1);
180    change_data->slideshow = slideshow;
181    change_data->iw = iw;
182    change_data->info = node->data;
183    gtk_idle_add_full (GTK_PRIORITY_DEFAULT,
184                       change_image_idle,
185                       NULL,
186                       change_data,
187                       (GtkDestroyNotify) g_free);
188    slideshow->current = node;
189 
190    return node;
191 }
192 
193 
194 static void
remove_list(GimvImageView * iv,gpointer list_owner,gpointer data)195 remove_list (GimvImageView *iv, gpointer list_owner, gpointer data)
196 {
197    GimvSlideShow *slideshow = list_owner;
198 
199    g_return_if_fail (iv);
200    g_return_if_fail (slideshow);
201 
202    /* free slide show data safely */
203    gtk_idle_add (idle_slideshow_delete, slideshow);
204 }
205 
206 
207 static void
cb_show_fullscreen(GimvImageWin * iw,GimvSlideShow * slideshow)208 cb_show_fullscreen (GimvImageWin *iw, GimvSlideShow *slideshow)
209 {
210 }
211 
212 
213 static void
cb_hide_fullscreen(GimvImageWin * iw,GimvSlideShow * slideshow)214 cb_hide_fullscreen (GimvImageWin *iw, GimvSlideShow *slideshow)
215 {
216    gtk_widget_destroy (GTK_WIDGET (iw));
217 }
218 
219 
220 
221 /******************************************************************************
222  *
223  *  Public functions
224  *
225  ******************************************************************************/
226 GimvSlideShow *
gimv_slideshow_new(void)227 gimv_slideshow_new (void)
228 {
229    GimvSlideShow *slideshow;
230 
231    slideshow = g_new0 (GimvSlideShow, 1);
232 
233    slideshow->iw               = NULL;
234    slideshow->filelist         = NULL;
235    slideshow->repeat           = conf.slideshow_repeat;
236 
237    return slideshow;
238 }
239 
240 
241 void
gimv_slideshow_delete(GimvSlideShow * slideshow)242 gimv_slideshow_delete (GimvSlideShow *slideshow)
243 {
244    GimvImageWin *iw;
245    GimvImageView *iv;
246 
247    g_return_if_fail (slideshow);
248 
249    iw = slideshow->iw;
250    iv = iw->iv;
251 
252    g_list_foreach (slideshow->filelist, (GFunc) gimv_image_info_unref, NULL);
253    g_list_free (g_list_first (slideshow->filelist));
254 
255    g_free (slideshow);
256 }
257 
258 
259 GimvSlideShow *
gimv_slideshow_new_with_filelist(GList * filelist,GList * start)260 gimv_slideshow_new_with_filelist (GList *filelist, GList *start)
261 {
262    GimvSlideShow *slideshow;
263 
264    g_return_val_if_fail (filelist, NULL);
265 
266    slideshow           = gimv_slideshow_new ();
267    slideshow->filelist = g_list_first (filelist);
268    slideshow->current  = start ? start : filelist;
269 
270    return slideshow;
271 }
272 
273 
274 GimvImageWin *
gimv_slideshow_open_window(GimvSlideShow * slideshow)275 gimv_slideshow_open_window (GimvSlideShow *slideshow)
276 {
277    GimvImageWin *iw;
278    GimvImageView *iv;
279    GList *current;
280 
281    g_return_val_if_fail (slideshow, NULL);
282    g_return_val_if_fail (slideshow->filelist, NULL);
283 
284    if (slideshow->iw)
285       return slideshow->iw;
286 
287    /* current = g_list_first (slideshow->filelist); */
288    current = slideshow->current ? slideshow->current
289                                 : slideshow->filelist;
290    g_return_val_if_fail (slideshow, NULL);
291 
292    slideshow->iw = GIMV_IMAGE_WIN (gimv_image_win_new (NULL));
293    g_return_val_if_fail (slideshow->iw, NULL);
294 
295    iw = slideshow->iw;
296    iv = iw->iv;
297 
298    /* override some parameters */
299    gtk_object_set(GTK_OBJECT(iv),
300                   "x_scale",           conf.slideshow_img_scale,
301                   "y_scale",           conf.slideshow_img_scale,
302                   "default_zoom",      conf.slideshow_zoom,
303                   "default_rotation",  conf.slideshow_rotation,
304                   "keep_aspect",       conf.slideshow_keep_aspect,
305                   NULL);
306 
307    gimv_image_win_change_image (GIMV_IMAGE_WIN (iw), current->data);
308 
309    gimv_image_win_show_menubar   (iw, conf.slideshow_menubar);
310    gimv_image_win_show_toolbar   (iw, conf.slideshow_toolbar);
311    gimv_image_win_show_player    (iw, conf.slideshow_player);
312    gimv_image_win_show_statusbar (iw, conf.slideshow_statusbar);
313    switch (conf.slideshow_screen_mode) {
314    case GimvSlideShowWinModeFullScreen:
315       gimv_image_win_set_fullscreen (iw, TRUE);
316       break;
317    case GimvSlideShowWinModeMaximize:
318       gimv_image_win_set_maximize (iw, TRUE);
319       break;
320    default:
321       break;
322    }
323    if (conf.slideshow_set_bg)
324       gimv_image_win_set_fullscreen_bg_color (iw,
325                                               conf.slideshow_bg_color[0],
326                                               conf.slideshow_bg_color[1],
327                                               conf.slideshow_bg_color[2]);
328    gimv_image_win_set_flags (iw,
329                              GimvImageWinHideFrameFlag
330                              | GimvImageWinNotSaveStateFlag);
331 
332    gimv_image_win_slideshow_set_repeat (iw, conf.slideshow_repeat);
333    gimv_image_win_slideshow_set_interval (iw, conf.slideshow_interval * 1000);
334 
335    /* set bg color */
336    if (conf.slideshow_set_bg) {
337       gimv_image_view_set_bg_color (iv,
338                                     conf.slideshow_bg_color[0],
339                                     conf.slideshow_bg_color[1],
340                                     conf.slideshow_bg_color[2]);
341    }
342 
343    gimv_image_view_set_list (iv,
344                              slideshow->filelist,
345                              current,
346                              (gpointer) slideshow,
347                              next_image,
348                              prev_image,
349                              nth_image,
350                              remove_list,
351                              iw);
352 
353    gtk_signal_connect_after (GTK_OBJECT (iw), "show_fullscreen",
354                              GTK_SIGNAL_FUNC (cb_show_fullscreen), slideshow);
355    gtk_signal_connect_after (GTK_OBJECT (iw), "hide_fullscreen",
356                              GTK_SIGNAL_FUNC (cb_hide_fullscreen), slideshow);
357 
358    gtk_widget_show (GTK_WIDGET (slideshow->iw));
359 
360    return iw;
361 }
362 
363 
364 /*
365  *  gimv_slideshow_play:
366  *     @ Execute slide show;
367  *
368  *  slideshow : Poiter to GimvSlideShow struct.
369  */
370 void
gimv_slideshow_play(GimvSlideShow * slideshow)371 gimv_slideshow_play (GimvSlideShow *slideshow)
372 {
373    GimvImageWin *iw = NULL;
374 
375    g_return_if_fail (slideshow);
376 
377    if (!slideshow->iw)
378       iw = gimv_slideshow_open_window (slideshow);
379    else
380       iw = slideshow->iw;
381 
382    g_return_if_fail (iw);
383 
384    gimv_image_win_slideshow_play (iw);
385 }
386 
387 
388 void
gimv_slideshow_stop(GimvSlideShow * slideshow)389 gimv_slideshow_stop (GimvSlideShow *slideshow)
390 {
391    GimvImageWin *iw;
392 
393    g_return_if_fail (slideshow);
394 
395    iw = slideshow->iw;
396    g_return_if_fail (iw);
397 
398    gimv_image_win_slideshow_stop (iw);
399 }
400 
401 
402 void
gimv_slideshow_set_interval(GimvSlideShow * slideshow,guint interval)403 gimv_slideshow_set_interval (GimvSlideShow *slideshow, guint interval)
404 {
405    GimvImageWin *iw;
406 
407    g_return_if_fail (slideshow);
408 
409    iw = slideshow->iw;
410    g_return_if_fail (iw);
411 
412    gimv_image_win_slideshow_set_interval (slideshow->iw, interval);
413 }
414