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