elementary: add the possibility to set the amount of cached items in a slideshow
[framework/uifw/elementary.git] / src / lib / elm_slideshow.c
1 #include <Elementary.h>
2 #include "elm_priv.h"
3
4 /**
5  * @defgroup Slideshow Slideshow
6  *
7  * This object display a list of object (generally a list of images) and some actions like
8  * next/previous are used to navigate. The animations are defined in the theme,
9  * consequently new animations can be added without having to update the
10  * applications.
11  *
12  * The slideshow use 2 callbacks to create and delete the objects displayed. When an item
13  * is displayed the function itc->func.get() is called. This function should create the object,
14  * for example the object can be an evas_object_image or a photocam. When a object is no more
15  * displayed the function itc->func.del() is called, the user can delete the dana associated to the item.
16  *
17  * Signals that you can add callbacks for are:
18  *
19  * "changed" - when the slideshow switch to another item
20  */
21
22 typedef struct _Widget_Data Widget_Data;
23
24 struct _Elm_Slideshow_Item
25 {
26    Elm_Widget_Item base;
27
28    Eina_List *l, *l_built;
29
30    const Elm_Slideshow_Item_Class *itc;
31 };
32
33 struct _Widget_Data
34 {
35    Evas_Object *slideshow;
36
37    // list of Elm_Slideshow_Item*
38    Eina_List *items;
39    Eina_List *items_built;
40
41    Elm_Slideshow_Item *current;
42    Elm_Slideshow_Item *previous;
43
44    Eina_List *transitions;
45    const char *transition;
46
47    int count_item_pre_before;
48    int count_item_pre_after;
49    Ecore_Timer *timer;
50    double timeout;
51    Eina_Bool loop:1;
52
53    struct {
54         const char *current;
55         Eina_List *list; //list of const char *
56    } layout;
57 };
58
59 static const char *widtype = NULL;
60 static void _del_hook(Evas_Object *obj);
61 static void _mirrored_set(Evas_Object *obj, Eina_Bool rtl);
62 static void _theme_hook(Evas_Object *obj);
63 static void _sizing_eval(Evas_Object *obj);
64 static void _changed_size_hints(void *data, Evas *e, Evas_Object *obj, void *event_info);
65 static Eina_Bool _timer_cb(void *data);
66 static void _on_focus_hook(void *data, Evas_Object *obj);
67 static Eina_Bool _event_hook(Evas_Object *obj, Evas_Object *src,
68                              Evas_Callback_Type type, void *event_info);
69
70 static const char SIG_CHANGED[] = "changed";
71
72 static const Evas_Smart_Cb_Description _signals[] = {
73    {SIG_CHANGED, ""},
74    {NULL, NULL}
75 };
76
77
78
79 static Eina_Bool
80 _event_hook(Evas_Object *obj, Evas_Object *src __UNUSED__, Evas_Callback_Type type, void *event_info)
81 {
82    if (type != EVAS_CALLBACK_KEY_DOWN) return EINA_FALSE;
83    Evas_Event_Key_Down *ev = event_info;
84    Widget_Data *wd = elm_widget_data_get(obj);
85    if (!wd) return EINA_FALSE;
86    if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return EINA_FALSE;
87    if (elm_widget_disabled_get(obj)) return EINA_FALSE;
88    if ((!strcmp(ev->keyname, "Left")) || (!strcmp(ev->keyname, "KP_Left")))
89      {
90         elm_slideshow_previous(obj);
91         ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
92         return EINA_TRUE;
93      }
94    if ((!strcmp(ev->keyname, "Right")) || (!strcmp(ev->keyname, "KP_Right")))
95      {
96         elm_slideshow_next(obj);
97         ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
98         return EINA_TRUE;
99      }
100    if ((!strcmp(ev->keyname, "Return")) ||
101        (!strcmp(ev->keyname, "KP_Enter")) ||
102        (!strcmp(ev->keyname, "space")))
103      {
104         if (wd->timeout)
105           {
106              if (wd->timer)
107                {
108                   ecore_timer_del(wd->timer);
109                   wd->timer = NULL;
110                }
111              else
112                elm_slideshow_timeout_set(obj, wd->timeout);
113           }
114         ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
115         return EINA_TRUE;
116      }
117    return EINA_FALSE;
118 }
119
120 static void
121 _del_hook(Evas_Object *obj)
122 {
123    const char *layout;
124    Widget_Data *wd = elm_widget_data_get(obj);
125    if (!wd) return;
126    elm_slideshow_clear(obj);
127    elm_widget_stringlist_free(wd->transitions);
128    if (wd->timer) ecore_timer_del(wd->timer);
129    EINA_LIST_FREE(wd->layout.list, layout)
130       eina_stringshare_del(layout);
131    free(wd);
132 }
133
134 static void
135 _on_focus_hook(void *data __UNUSED__, Evas_Object *obj)
136 {
137    Widget_Data *wd = elm_widget_data_get(obj);
138    if (!wd) return;
139    if (elm_widget_focus_get(obj))
140      {
141         edje_object_signal_emit(wd->slideshow, "elm,action,focus", "elm");
142         evas_object_focus_set(wd->slideshow, EINA_TRUE);
143      }
144    else
145      {
146         edje_object_signal_emit(wd->slideshow, "elm,action,unfocus", "elm");
147         evas_object_focus_set(wd->slideshow, EINA_FALSE);
148      }
149 }
150
151 static void
152 _mirrored_set(Evas_Object *obj, Eina_Bool rtl)
153 {
154    Widget_Data *wd = elm_widget_data_get(obj);
155    if (!wd) return;
156    edje_object_mirrored_set(wd->slideshow, rtl);
157 }
158
159 static void
160 _theme_hook(Evas_Object *obj)
161 {
162    Widget_Data *wd = elm_widget_data_get(obj);
163    if (!wd) return;
164    _elm_widget_mirrored_reload(obj);
165    _mirrored_set(obj, elm_widget_mirrored_get(obj));
166    _elm_theme_object_set(obj, wd->slideshow, "slideshow", "base", elm_widget_style_get(obj));
167    edje_object_scale_set(wd->slideshow, elm_widget_scale_get(obj) *
168                          _elm_config->scale);
169    _sizing_eval(obj);
170 }
171
172 static void
173 _sizing_eval(Evas_Object *obj)
174 {
175    Widget_Data *wd = elm_widget_data_get(obj);
176    Evas_Coord minw = -1, minh = -1;
177    if (!wd) return;
178    edje_object_size_min_calc(wd->slideshow, &minw, &minh);
179    evas_object_size_hint_min_set(obj, minw, minh);
180    evas_object_size_hint_max_set(obj, minw, minh);
181 }
182
183
184 static Elm_Slideshow_Item* _item_prev_get(Elm_Slideshow_Item* item)
185 {
186    Widget_Data *wd = elm_widget_data_get(item->base.widget);
187    Elm_Slideshow_Item* prev = eina_list_data_get(eina_list_prev(item->l));
188    if((!prev) && (wd->loop))
189      prev = eina_list_data_get(eina_list_last(item->l));
190    return prev;
191 }
192
193 static Elm_Slideshow_Item* _item_next_get(Elm_Slideshow_Item* item)
194 {
195    Widget_Data *wd = elm_widget_data_get(item->base.widget);
196    Elm_Slideshow_Item* next = eina_list_data_get(eina_list_next(item->l));
197    if((!next) && (wd->loop))
198      next = eina_list_data_get(wd->items);
199    return next;
200 }
201
202
203 static void
204 _changed_size_hints(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
205 {
206    _sizing_eval(data);
207 }
208
209 static void
210 _sub_del(void *data __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
211 {
212    ;
213 }
214
215 static void
216 _item_realize(Elm_Slideshow_Item *item)
217 {
218    Elm_Slideshow_Item *_item_prev, *_item_next;
219    Evas_Object *obj = item->base.widget;
220    Widget_Data *wd = elm_widget_data_get(obj);
221    int ac, bc, lc;
222
223    if (!wd) return;
224    if ((!item->base.view) && (item->itc->func.get))
225      {
226         item->base.view = item->itc->func.get((void*)item->base.data, obj);
227         evas_object_smart_member_add(item->base.view, obj);
228         item->l_built = eina_list_append(NULL, item);
229         wd->items_built = eina_list_merge(wd->items_built, item->l_built);
230         evas_object_hide(item->base.view);
231      }
232    else if (item->l_built)
233      wd->items_built = eina_list_demote_list(wd->items_built, item->l_built);
234
235    //pre-create previous and next item
236    ac = wd->count_item_pre_after;
237    _item_next = item;
238    bc = wd->count_item_pre_before;
239    _item_prev = item;
240    lc = eina_list_count(wd->items) - 1;
241    while (lc > 0 && ((ac > 0) || (bc > 0)))
242      {
243         if (lc > 0 && ac > 0)
244           {
245              --ac;
246              --lc;
247              _item_next = _item_next_get(_item_next);
248              if ((_item_next)
249                  && (!_item_next->base.view)
250                  && (_item_next->itc->func.get))
251                {
252                   _item_next->base.view =
253                      _item_next->itc->func.get((void*)_item_next->base.data,
254                                                obj);
255                   evas_object_smart_member_add(_item_next->base.view, obj);
256                   _item_next->l_built = eina_list_append(NULL, _item_next);
257                   wd->items_built = eina_list_merge(wd->items_built,
258                                                     _item_next->l_built);
259                   evas_object_hide(_item_next->base.view);
260                }
261              else if (_item_next && _item_next->l_built)
262                wd->items_built = eina_list_demote_list(wd->items_built,
263                                                        _item_next->l_built);
264           }
265
266         if (lc > 0 && bc > 0)
267           {
268              --bc;
269              --lc;
270              _item_prev = _item_prev_get(_item_prev);
271              if ((_item_prev)
272                  && (!_item_prev->base.view)
273                  && (_item_prev->itc->func.get))
274                {
275                   _item_prev->base.view =
276                      _item_prev->itc->func.get((void*)_item_prev->base.data,
277                                                obj);
278                   evas_object_smart_member_add(_item_prev->base.view, obj);
279                   _item_prev->l_built = eina_list_append(NULL, _item_prev);
280                   wd->items_built = eina_list_merge(wd->items_built,
281                                                     _item_prev->l_built);
282                   evas_object_hide(_item_prev->base.view);
283                }
284              else if (_item_prev && _item_prev->l_built)
285                wd->items_built = eina_list_demote_list(wd->items_built,
286                                                        _item_prev->l_built);
287           }
288      }
289
290    //delete unused items
291    lc = wd->count_item_pre_before + wd->count_item_pre_after + 1;
292    while (eina_list_count(wd->items_built) > lc)
293      {
294         item = eina_list_data_get(wd->items_built);
295         wd->items_built = eina_list_remove_list(wd->items_built,
296                                                 wd->items_built);
297         if(item->itc->func.del)
298           item->itc->func.del((void*)item->base.data, item->base.view);
299         evas_object_del(item->base.view);
300         item->base.view = NULL;
301      }
302 }
303
304 static void
305 _end(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
306 {
307    Elm_Slideshow_Item *item;
308    Widget_Data *wd = elm_widget_data_get(data);
309    if (!wd) return;
310
311    item = wd->previous;
312    if(item)
313      {
314         edje_object_part_unswallow(NULL, item->base.view);
315         evas_object_hide(item->base.view);
316         wd->previous = NULL;
317      }
318
319
320    item = wd->current;
321    if ((!item) || (!item->base.view)) return;
322
323    _item_realize(item);
324    edje_object_part_unswallow(NULL, item->base.view);
325    evas_object_show(item->base.view);
326
327    edje_object_signal_emit(wd->slideshow, "anim,end", "slideshow");
328    edje_object_part_swallow(wd->slideshow, "elm.swallow.1", item->base.view);
329 }
330
331
332 static Eina_Bool
333 _timer_cb(void *data)
334 {
335    Evas_Object *obj = data;
336    Widget_Data *wd = elm_widget_data_get(obj);
337    if (!wd) return ECORE_CALLBACK_CANCEL;
338    wd->timer = NULL;
339    elm_slideshow_next(obj);
340    return ECORE_CALLBACK_CANCEL;
341 }
342
343
344
345 /**
346  * Add a new slideshow to the parent
347  *
348  * @param parent The parent object
349  * @return The new object or NULL if it cannot be created
350  *
351  * @ingroup Slideshow
352  */
353 EAPI Evas_Object *
354 elm_slideshow_add(Evas_Object *parent)
355 {
356    Evas_Object *obj;
357    Evas *e;
358    Widget_Data *wd;
359
360    ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL);
361
362    ELM_SET_WIDTYPE(widtype, "slideshow");
363    elm_widget_type_set(obj, "slideshow");
364    elm_widget_sub_object_add(parent, obj);
365    elm_widget_on_focus_hook_set(obj, _on_focus_hook, NULL);
366    elm_widget_data_set(obj, wd);
367    elm_widget_del_hook_set(obj, _del_hook);
368    elm_widget_theme_hook_set(obj, _theme_hook);
369    elm_widget_can_focus_set(obj, EINA_TRUE);
370    elm_widget_event_hook_set(obj, _event_hook);
371
372    wd->current = NULL;
373    wd->previous = NULL;
374
375    wd->slideshow = edje_object_add(e);
376    _elm_theme_object_set(obj, wd->slideshow, "slideshow", "base", "default");
377    evas_object_smart_member_add(wd->slideshow, obj);
378    wd->count_item_pre_before = 2;
379    wd->count_item_pre_after = 2;
380    elm_widget_resize_object_set(obj, wd->slideshow);
381    evas_object_show(wd->slideshow);
382
383    wd->transitions = elm_widget_stringlist_get(edje_object_data_get(wd->slideshow, "transitions"));
384    if (eina_list_count(wd->transitions) > 0)
385      wd->transition = eina_stringshare_add(eina_list_data_get(wd->transitions));
386
387    wd->layout.list = elm_widget_stringlist_get(edje_object_data_get(wd->slideshow, "layouts"));
388    if (eina_list_count(wd->layout.list) > 0)
389      wd->layout.current = eina_list_data_get(wd->layout.list);
390
391    edje_object_signal_callback_add(wd->slideshow, "end", "slideshow", _end, obj);
392
393    evas_object_smart_callback_add(obj, "sub-object-del", _sub_del, obj);
394    evas_object_event_callback_add(obj, EVAS_CALLBACK_CHANGED_SIZE_HINTS, _changed_size_hints, obj);
395
396    evas_object_smart_callbacks_descriptions_set(obj, _signals);
397
398    _mirrored_set(obj, elm_widget_mirrored_get(obj));
399    _sizing_eval(obj);
400    return obj;
401 }
402
403 /**
404  * Add a object in the list. The object can be a evas object image or a elm photo for example.
405  *
406  * @param obj The slideshow object
407  * @aram itc Callbacks used to create the object and delete the data associated when the item is deleted.
408  * @param data Data used by the user to identified the item
409  * @return Returns The slideshow item
410  *
411  * @ingroup Slideshow
412  */
413 EAPI Elm_Slideshow_Item*
414 elm_slideshow_item_add(Evas_Object *obj, const Elm_Slideshow_Item_Class *itc, const void *data)
415 {
416    Elm_Slideshow_Item *item;
417    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
418    Widget_Data *wd = elm_widget_data_get(obj);
419
420    if (!wd) return NULL;
421    item = elm_widget_item_new(obj, Elm_Slideshow_Item);
422    item->base.data = data;
423    item->itc = itc;
424    item->l = eina_list_append(item->l, item);
425
426    wd->items = eina_list_merge(wd->items, item->l);
427
428    if (!wd->current) elm_slideshow_show(item);
429
430    return item;
431 }
432
433 /**
434  * Go to the item
435  *
436  * @param obj The slideshow object
437  * @param item The item
438  *
439  * @ingroup Slideshow
440  */
441 EAPI void
442 elm_slideshow_show(Elm_Slideshow_Item *item)
443 {
444    char buf[1024];
445    Elm_Slideshow_Item *next = NULL;
446    Widget_Data *wd;
447    ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(item);
448    wd = elm_widget_data_get(item->base.widget);
449    if (!wd)
450      return;
451    if (item == wd->current)
452      return;
453
454    next = item;
455    _end(item->base.widget, item->base.widget, NULL, NULL);
456
457    if (wd->timer) ecore_timer_del(wd->timer);
458    if (wd->timeout > 0.0)
459      wd->timer = ecore_timer_add(wd->timeout, _timer_cb, item->base.widget);
460    _item_realize(next);
461    edje_object_part_swallow(wd->slideshow, "elm.swallow.2", next->base.view);
462    evas_object_show(next->base.view);
463    snprintf(buf, sizeof(buf), "%s,next", wd->transition);
464    edje_object_signal_emit(wd->slideshow, buf, "slideshow");
465    wd->previous = wd->current;
466    wd->current = next;
467    evas_object_smart_callback_call(item->base.widget, SIG_CHANGED, wd->current);
468 }
469
470 /**
471  * Go to the next item
472  *
473  * @param obj The slideshow object
474  *
475  * @ingroup Slideshow
476  */
477 EAPI void
478 elm_slideshow_next(Evas_Object *obj)
479 {
480    char buf[1024];
481    Elm_Slideshow_Item *next = NULL;
482    ELM_CHECK_WIDTYPE(obj, widtype);
483    Widget_Data *wd = elm_widget_data_get(obj);
484
485    if (!wd) return;
486
487    if (wd->current)
488      next = _item_next_get(wd->current);
489
490    if ((!next) || (next == wd->current)) return;
491
492    _end(obj, obj, NULL, NULL);
493
494    if (wd->timer) ecore_timer_del(wd->timer);
495    if (wd->timeout > 0.0)
496      wd->timer = ecore_timer_add(wd->timeout, _timer_cb, obj);
497
498    _item_realize(next);
499
500    edje_object_part_swallow(wd->slideshow, "elm.swallow.2", next->base.view);
501    evas_object_show(next->base.view);
502
503    snprintf(buf, sizeof(buf), "%s,next", wd->transition);
504    edje_object_signal_emit(wd->slideshow, buf, "slideshow");
505
506    wd->previous = wd->current;
507    wd->current = next;
508    evas_object_smart_callback_call(obj, SIG_CHANGED, wd->current);
509 }
510
511 /**
512  * Go to the previous item
513  *
514  * @param obj The slideshow object
515  *
516  * @ingroup Slideshow
517  */
518 EAPI void
519 elm_slideshow_previous(Evas_Object *obj)
520 {
521    char buf[1024];
522    Elm_Slideshow_Item *prev = NULL;
523    ELM_CHECK_WIDTYPE(obj, widtype);
524    Widget_Data *wd = elm_widget_data_get(obj);
525
526    if (!wd) return;
527
528    if (wd->current)
529      prev = _item_prev_get(wd->current);
530
531    if ((!prev) ||  (prev == wd->current)) return;
532
533    _end(obj, obj, NULL, NULL);
534
535    if (wd->timer) ecore_timer_del(wd->timer);
536    if (wd->timeout > 0.0)
537      wd->timer = ecore_timer_add(wd->timeout, _timer_cb, obj);
538
539    _item_realize(prev);
540
541    edje_object_part_swallow(wd->slideshow, "elm.swallow.2", prev->base.view);
542    evas_object_show(prev->base.view);
543
544    snprintf(buf, 1024, "%s,previous", wd->transition);
545    edje_object_signal_emit(wd->slideshow, buf, "slideshow");
546
547    wd->previous = wd->current;
548    wd->current = prev;
549    evas_object_smart_callback_call(obj, SIG_CHANGED, wd->current);
550 }
551
552 /**
553  * Returns the list of transitions available.
554  *
555  * @param obj The slideshow object
556  * @return Returns the list of transitions (list of const char*)
557  *
558  * @ingroup Slideshow
559  */
560 EAPI const Eina_List *
561 elm_slideshow_transitions_get(const Evas_Object *obj)
562 {
563    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
564    Widget_Data *wd = elm_widget_data_get(obj);
565    if (!wd) return NULL;
566    return wd->transitions;
567 }
568
569 /**
570  * Returns the list of layouts available.
571  *
572  * @param obj The slideshow object
573  * @return Returns the list of layout (list of const char*)
574  *
575  * @ingroup Slideshow
576  */
577 EAPI const Eina_List *
578 elm_slideshow_layouts_get(const Evas_Object *obj)
579 {
580    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
581    Widget_Data *wd = elm_widget_data_get(obj);
582    if (!wd) return NULL;
583    return wd->layout.list;
584 }
585
586 /**
587  * Set the transition to use
588  *
589  * @param obj The slideshow object
590  * @param transition the new transition
591  *
592  * @ingroup Slideshow
593  */
594 EAPI void
595 elm_slideshow_transition_set(Evas_Object *obj, const char *transition)
596 {
597    ELM_CHECK_WIDTYPE(obj, widtype);
598    Widget_Data *wd = elm_widget_data_get(obj);
599    if (!wd) return;
600    eina_stringshare_replace(&wd->transition, transition);
601 }
602
603 /**
604  * Returns the transition to use
605  *
606  * @param obj The slideshow object
607  * @return the transition set
608  *
609  * @ingroup Slideshow
610  */
611 EAPI const char *
612 elm_slideshow_transition_get(const Evas_Object *obj)
613 {
614    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
615    Widget_Data *wd = elm_widget_data_get(obj);
616    if (!wd) return NULL;
617    return wd->transition;
618 }
619
620 /**
621  * The slideshow can go to the next item automatically after a few seconds.
622  * This method set the timeout to use. A timeout <=0 disable the timer.
623  *
624  * @param obj The slideshow object
625  * @param timeout The new timeout
626  *
627  * @ingroup Slideshow
628  */
629 EAPI void
630 elm_slideshow_timeout_set(Evas_Object *obj, double timeout)
631 {
632    ELM_CHECK_WIDTYPE(obj, widtype);
633    Widget_Data *wd = elm_widget_data_get(obj);
634    if (!wd) return;
635    wd->timeout = timeout;
636    if (wd->timer) ecore_timer_del(wd->timer);
637    wd->timer = NULL;
638    if (timeout > 0.0)
639      wd->timer = ecore_timer_add(timeout, _timer_cb, obj);
640 }
641
642 /**
643  * Returns the timeout value
644  *
645  * @param obj The slideshow object
646  * @return Returns the timeout
647  *
648  * @ingroup Slideshow
649  */
650 EAPI double
651 elm_slideshow_timeout_get(const Evas_Object *obj)
652 {
653    ELM_CHECK_WIDTYPE(obj, widtype) -1.0;
654    Widget_Data *wd = elm_widget_data_get(obj);
655    if (!wd) return -1.0;
656    return wd->timeout;
657 }
658
659 /**
660  * Set if the first item should follow the last and vice versa
661  *
662  * @param obj The slideshow object
663  * @param loop if EINA_TRUE, the first item will follow the last and vice versa
664  *
665  * @ingroup Slideshow
666  */
667 EAPI void
668 elm_slideshow_loop_set(Evas_Object *obj, Eina_Bool loop)
669 {
670    ELM_CHECK_WIDTYPE(obj, widtype);
671    Widget_Data *wd = elm_widget_data_get(obj);
672    if (!wd) return;
673    wd->loop = loop;
674 }
675
676 /**
677  * Returns the current layout name
678  *
679  * @param obj The slideshow object
680  * @returns Returns the layout name
681  *
682  * @ingroup Slideshow
683  */
684 EAPI const char *
685 elm_slideshow_layout_get(const Evas_Object *obj)
686 {
687    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
688    Widget_Data *wd = elm_widget_data_get(obj);
689    if (!wd) return EINA_FALSE;
690    return wd->layout.current;
691 }
692
693 /**
694  * Set the layout
695  *
696  * @param obj The slideshow object
697  * @param layout the new layout
698  *
699  * @ingroup Slideshow
700  */
701 EAPI void
702 elm_slideshow_layout_set(Evas_Object *obj, const char *layout)
703 {
704    char buf[PATH_MAX];
705    ELM_CHECK_WIDTYPE(obj, widtype);
706    Widget_Data *wd = elm_widget_data_get(obj);
707    if (!wd) return;
708
709    wd->layout.current = layout;
710    snprintf(buf, sizeof(buf), "layout,%s", layout);
711    edje_object_signal_emit(wd->slideshow, buf, "slideshow");
712 }
713
714 /**
715  * Return if the first item should follow the last and vice versa
716  *
717  * @param obj The slideshow object
718  * @returns Returns the loop flag
719  *
720  * @ingroup Slideshow
721  */
722 EAPI Eina_Bool
723 elm_slideshow_loop_get(const Evas_Object *obj)
724 {
725    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
726    Widget_Data *wd = elm_widget_data_get(obj);
727    if (!wd) return EINA_FALSE;
728    return wd->loop;
729 }
730
731 /**
732  * Delete all the items
733  *
734  * @param obj The slideshow object
735  *
736  * @ingroup Slideshow
737  */
738 EAPI void
739 elm_slideshow_clear(Evas_Object *obj)
740 {
741    Elm_Slideshow_Item *item;
742    ELM_CHECK_WIDTYPE(obj, widtype);
743    Widget_Data *wd = elm_widget_data_get(obj);
744    if (!wd) return;
745    wd->previous = NULL;
746    wd->current = NULL;
747    EINA_LIST_FREE(wd->items_built, item)
748      {
749         if (item->itc->func.del)
750           item->itc->func.del((void*)item->base.data, item->base.view);
751         evas_object_del(item->base.view);
752         item->base.view = NULL;
753      }
754
755    EINA_LIST_FREE(wd->items, item)
756      {
757         elm_widget_item_del(item);
758      }
759 }
760
761
762 /**
763  * Delete the item
764  *
765  * @param item The slideshow item
766  *
767  * @ingroup Slideshow
768  */
769 EAPI void
770 elm_slideshow_item_del(Elm_Slideshow_Item *item)
771 {
772    ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(item);
773    Widget_Data *wd = elm_widget_data_get(item->base.widget);
774    if (!wd) return;
775    if (wd->previous == item) wd->previous = NULL;
776    if (wd->current == item)
777      {
778         Eina_List *l = eina_list_data_find_list(wd->items, item);
779         Eina_List *l2 = eina_list_next(l);
780         wd->current = NULL;
781         if (!l2)
782           l2 = eina_list_nth_list(wd->items, eina_list_count(wd->items) - 1);
783         if (l2)
784           elm_slideshow_show(eina_list_data_get(l2));
785      }
786
787    wd->items = eina_list_remove_list(wd->items, item->l);
788    wd->items_built = eina_list_remove_list(wd->items_built, item->l_built);
789
790    if ((item->base.view) && (item->itc->func.del))
791      item->itc->func.del((void*)item->base.data, item->base.view);
792    if (item->base.view)
793      evas_object_del(item->base.view);
794    free(item);
795 }
796
797 /**
798  * Returns the list of items
799  * @param obj The slideshow object
800  * @return Returns the list of items (list of Elm_Slideshow_Item).
801  *
802  * @ingroup Slideshow
803  */
804 EAPI const Eina_List *
805 elm_slideshow_items_get(const Evas_Object *obj)
806 {
807    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
808    Widget_Data *wd = elm_widget_data_get(obj);
809    if (!wd) return NULL;
810    return wd->items;
811 }
812
813
814 /**
815  * Returns the current item displayed
816  *
817  * @param obj The slideshow object
818  * @return Returns the current item displayed
819  *
820  * @ingroup Slideshow
821  */
822 EAPI Elm_Slideshow_Item *
823 elm_slideshow_item_current_get(const Evas_Object *obj)
824 {
825    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
826    Widget_Data *wd = elm_widget_data_get(obj);
827    if (!wd) return NULL;
828    return wd->current;
829 }
830
831 /**
832  * Returns the evas object associated to an item
833  *
834  * @param item The slideshow item
835  * @return Returns the evas object associated to this item
836  *
837  * @ingroup Slideshow
838  */
839 EAPI Evas_Object *
840 elm_slideshow_item_object_get(const Elm_Slideshow_Item * item)
841 {
842    ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(item, NULL);
843    return item->base.view;
844 }
845
846 /**
847  * Returns the data associated to an item
848  *
849  * @param item The slideshow item
850  * @return Returns the data associated to this item
851  *
852  * @ingroup Slideshow
853  */
854 EAPI void *
855 elm_slideshow_item_data_get(const Elm_Slideshow_Item * item)
856 {
857    ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(item, NULL);
858    return elm_widget_item_data_get(item);
859 }
860
861 /**
862  * Returns max amount of cached items before current
863  *
864  * @param obj The slideshow object
865  * @return Returns max amount of cached items
866  *
867  * @ingroup Slideshow
868  */
869 EAPI int
870 elm_slideshow_cache_before_get(const Evas_Object *obj)
871 {
872    ELM_CHECK_WIDTYPE(obj, widtype) -1;
873    Widget_Data *wd = elm_widget_data_get(obj);
874    if (!wd) return -1;
875    return wd->count_item_pre_before;
876 }
877
878
879
880 /**
881  * Set max amount of cached items before current
882  *
883  * @param obj The slideshow object
884  * @param count Max amount of cached items
885  *
886  * @ingroup Slideshow
887  */
888 EAPI void
889 elm_slideshow_cache_before_set(Evas_Object *obj, int count)
890 {
891    ELM_CHECK_WIDTYPE(obj, widtype);
892    Widget_Data *wd = elm_widget_data_get(obj);
893    if (!wd) return;
894    if (count < 0) count = 0;
895    wd->count_item_pre_before = count;
896 }
897
898 /**
899  * Returns max amount of cached items after current
900  *
901  * @param obj The slideshow object
902  * @return Returns max amount of cached items
903  *
904  * @ingroup Slideshow
905  */
906 EAPI int
907 elm_slideshow_cache_after_get(const Evas_Object *obj)
908 {
909    ELM_CHECK_WIDTYPE(obj, widtype) -1;
910    Widget_Data *wd = elm_widget_data_get(obj);
911    if (!wd) return -1;
912    return wd->count_item_pre_after;
913 }
914
915
916
917 /**
918  * Set max amount of cached items after current
919  *
920  * @param obj The slideshow object
921  * @param count max amount of cached items
922  *
923  * @ingroup Slideshow
924  */
925 EAPI void
926 elm_slideshow_cache_after_set(Evas_Object *obj, int count)
927 {
928    ELM_CHECK_WIDTYPE(obj, widtype);
929    Widget_Data *wd = elm_widget_data_get(obj);
930    if (!wd) return;
931    if (count < 0) count = 0;
932    wd->count_item_pre_after = count;
933 }
934