Elementary slideshow: Fixed doxygen typo.
[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 an 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 an 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  * Insert an object in the list. The object can be a evas object image or a elm photo for example.
429  *
430  * @param obj The slideshow object
431  * @aram itc Callbacks used to create the object and delete the data associated when the item is deleted.
432  * @param data Data used by the user to identified the item
433  * @param func The function to compare data
434  * @return Returns The slideshow item
435  *
436  * @ingroup Slideshow
437  */
438 EAPI Elm_Slideshow_Item*
439 elm_slideshow_item_sorted_insert(Evas_Object *obj, const Elm_Slideshow_Item_Class *itc, const void *data, Eina_Compare_Cb func)
440 {
441    Elm_Slideshow_Item *item;
442    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
443    Widget_Data *wd = elm_widget_data_get(obj);
444
445    if (!wd) return NULL;
446    item = elm_widget_item_new(obj, Elm_Slideshow_Item);
447    item->base.data = data;
448    item->itc = itc;
449    item->l = eina_list_append(item->l, item);
450
451    wd->items = eina_list_sorted_merge(wd->items, item->l, func);
452
453    if (!wd->current) elm_slideshow_show(item);
454
455    return item;
456 }
457
458 /**
459  * Go to the item
460  *
461  * @param obj The slideshow object
462  * @param item The item
463  *
464  * @ingroup Slideshow
465  */
466 EAPI void
467 elm_slideshow_show(Elm_Slideshow_Item *item)
468 {
469    char buf[1024];
470    Elm_Slideshow_Item *next = NULL;
471    Widget_Data *wd;
472    ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(item);
473    wd = elm_widget_data_get(item->base.widget);
474    if (!wd)
475      return;
476    if (item == wd->current)
477      return;
478
479    next = item;
480    _end(item->base.widget, item->base.widget, NULL, NULL);
481
482    if (wd->timer) ecore_timer_del(wd->timer);
483    if (wd->timeout > 0.0)
484      wd->timer = ecore_timer_add(wd->timeout, _timer_cb, item->base.widget);
485    _item_realize(next);
486    edje_object_part_swallow(wd->slideshow, "elm.swallow.2", next->base.view);
487    evas_object_show(next->base.view);
488    snprintf(buf, sizeof(buf), "%s,next", wd->transition);
489    edje_object_signal_emit(wd->slideshow, buf, "slideshow");
490    wd->previous = wd->current;
491    wd->current = next;
492    evas_object_smart_callback_call(item->base.widget, SIG_CHANGED, wd->current);
493 }
494
495 /**
496  * Go to the next item
497  *
498  * @param obj The slideshow object
499  *
500  * @ingroup Slideshow
501  */
502 EAPI void
503 elm_slideshow_next(Evas_Object *obj)
504 {
505    char buf[1024];
506    Elm_Slideshow_Item *next = NULL;
507    ELM_CHECK_WIDTYPE(obj, widtype);
508    Widget_Data *wd = elm_widget_data_get(obj);
509
510    if (!wd) return;
511
512    if (wd->current)
513      next = _item_next_get(wd->current);
514
515    if ((!next) || (next == wd->current)) return;
516
517    _end(obj, obj, NULL, NULL);
518
519    if (wd->timer) ecore_timer_del(wd->timer);
520    if (wd->timeout > 0.0)
521      wd->timer = ecore_timer_add(wd->timeout, _timer_cb, obj);
522
523    _item_realize(next);
524
525    edje_object_part_swallow(wd->slideshow, "elm.swallow.2", next->base.view);
526    evas_object_show(next->base.view);
527
528    snprintf(buf, sizeof(buf), "%s,next", wd->transition);
529    edje_object_signal_emit(wd->slideshow, buf, "slideshow");
530
531    wd->previous = wd->current;
532    wd->current = next;
533    evas_object_smart_callback_call(obj, SIG_CHANGED, wd->current);
534 }
535
536 /**
537  * Go to the previous item
538  *
539  * @param obj The slideshow object
540  *
541  * @ingroup Slideshow
542  */
543 EAPI void
544 elm_slideshow_previous(Evas_Object *obj)
545 {
546    char buf[1024];
547    Elm_Slideshow_Item *prev = NULL;
548    ELM_CHECK_WIDTYPE(obj, widtype);
549    Widget_Data *wd = elm_widget_data_get(obj);
550
551    if (!wd) return;
552
553    if (wd->current)
554      prev = _item_prev_get(wd->current);
555
556    if ((!prev) ||  (prev == wd->current)) return;
557
558    _end(obj, obj, NULL, NULL);
559
560    if (wd->timer) ecore_timer_del(wd->timer);
561    if (wd->timeout > 0.0)
562      wd->timer = ecore_timer_add(wd->timeout, _timer_cb, obj);
563
564    _item_realize(prev);
565
566    edje_object_part_swallow(wd->slideshow, "elm.swallow.2", prev->base.view);
567    evas_object_show(prev->base.view);
568
569    snprintf(buf, 1024, "%s,previous", wd->transition);
570    edje_object_signal_emit(wd->slideshow, buf, "slideshow");
571
572    wd->previous = wd->current;
573    wd->current = prev;
574    evas_object_smart_callback_call(obj, SIG_CHANGED, wd->current);
575 }
576
577 /**
578  * Returns the list of transitions available.
579  *
580  * @param obj The slideshow object
581  * @return Returns the list of transitions (list of const char*)
582  *
583  * @ingroup Slideshow
584  */
585 EAPI const Eina_List *
586 elm_slideshow_transitions_get(const Evas_Object *obj)
587 {
588    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
589    Widget_Data *wd = elm_widget_data_get(obj);
590    if (!wd) return NULL;
591    return wd->transitions;
592 }
593
594 /**
595  * Returns the list of layouts available.
596  *
597  * @param obj The slideshow object
598  * @return Returns the list of layout (list of const char*)
599  *
600  * @ingroup Slideshow
601  */
602 EAPI const Eina_List *
603 elm_slideshow_layouts_get(const Evas_Object *obj)
604 {
605    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
606    Widget_Data *wd = elm_widget_data_get(obj);
607    if (!wd) return NULL;
608    return wd->layout.list;
609 }
610
611 /**
612  * Set the transition to use
613  *
614  * @param obj The slideshow object
615  * @param transition the new transition
616  *
617  * @ingroup Slideshow
618  */
619 EAPI void
620 elm_slideshow_transition_set(Evas_Object *obj, const char *transition)
621 {
622    ELM_CHECK_WIDTYPE(obj, widtype);
623    Widget_Data *wd = elm_widget_data_get(obj);
624    if (!wd) return;
625    eina_stringshare_replace(&wd->transition, transition);
626 }
627
628 /**
629  * Returns the transition to use
630  *
631  * @param obj The slideshow object
632  * @return the transition set
633  *
634  * @ingroup Slideshow
635  */
636 EAPI const char *
637 elm_slideshow_transition_get(const Evas_Object *obj)
638 {
639    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
640    Widget_Data *wd = elm_widget_data_get(obj);
641    if (!wd) return NULL;
642    return wd->transition;
643 }
644
645 /**
646  * The slideshow can go to the next item automatically after a few seconds.
647  * This method set the timeout to use. A timeout <=0 disable the timer.
648  *
649  * @param obj The slideshow object
650  * @param timeout The new timeout
651  *
652  * @ingroup Slideshow
653  */
654 EAPI void
655 elm_slideshow_timeout_set(Evas_Object *obj, double timeout)
656 {
657    ELM_CHECK_WIDTYPE(obj, widtype);
658    Widget_Data *wd = elm_widget_data_get(obj);
659    if (!wd) return;
660    wd->timeout = timeout;
661    if (wd->timer) ecore_timer_del(wd->timer);
662    wd->timer = NULL;
663    if (timeout > 0.0)
664      wd->timer = ecore_timer_add(timeout, _timer_cb, obj);
665 }
666
667 /**
668  * Returns the timeout value
669  *
670  * @param obj The slideshow object
671  * @return Returns the timeout
672  *
673  * @ingroup Slideshow
674  */
675 EAPI double
676 elm_slideshow_timeout_get(const Evas_Object *obj)
677 {
678    ELM_CHECK_WIDTYPE(obj, widtype) -1.0;
679    Widget_Data *wd = elm_widget_data_get(obj);
680    if (!wd) return -1.0;
681    return wd->timeout;
682 }
683
684 /**
685  * Set if the first item should follow the last and vice versa
686  *
687  * @param obj The slideshow object
688  * @param loop if EINA_TRUE, the first item will follow the last and vice versa
689  *
690  * @ingroup Slideshow
691  */
692 EAPI void
693 elm_slideshow_loop_set(Evas_Object *obj, Eina_Bool loop)
694 {
695    ELM_CHECK_WIDTYPE(obj, widtype);
696    Widget_Data *wd = elm_widget_data_get(obj);
697    if (!wd) return;
698    wd->loop = loop;
699 }
700
701 /**
702  * Returns the current layout name
703  *
704  * @param obj The slideshow object
705  * @returns Returns the layout name
706  *
707  * @ingroup Slideshow
708  */
709 EAPI const char *
710 elm_slideshow_layout_get(const Evas_Object *obj)
711 {
712    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
713    Widget_Data *wd = elm_widget_data_get(obj);
714    if (!wd) return EINA_FALSE;
715    return wd->layout.current;
716 }
717
718 /**
719  * Set the layout
720  *
721  * @param obj The slideshow object
722  * @param layout the new layout
723  *
724  * @ingroup Slideshow
725  */
726 EAPI void
727 elm_slideshow_layout_set(Evas_Object *obj, const char *layout)
728 {
729    char buf[PATH_MAX];
730    ELM_CHECK_WIDTYPE(obj, widtype);
731    Widget_Data *wd = elm_widget_data_get(obj);
732    if (!wd) return;
733
734    wd->layout.current = layout;
735    snprintf(buf, sizeof(buf), "layout,%s", layout);
736    edje_object_signal_emit(wd->slideshow, buf, "slideshow");
737 }
738
739 /**
740  * Return if the first item should follow the last and vice versa
741  *
742  * @param obj The slideshow object
743  * @returns Returns the loop flag
744  *
745  * @ingroup Slideshow
746  */
747 EAPI Eina_Bool
748 elm_slideshow_loop_get(const Evas_Object *obj)
749 {
750    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
751    Widget_Data *wd = elm_widget_data_get(obj);
752    if (!wd) return EINA_FALSE;
753    return wd->loop;
754 }
755
756 /**
757  * Delete all the items
758  *
759  * @param obj The slideshow object
760  *
761  * @ingroup Slideshow
762  */
763 EAPI void
764 elm_slideshow_clear(Evas_Object *obj)
765 {
766    Elm_Slideshow_Item *item;
767    ELM_CHECK_WIDTYPE(obj, widtype);
768    Widget_Data *wd = elm_widget_data_get(obj);
769    if (!wd) return;
770    wd->previous = NULL;
771    wd->current = NULL;
772    EINA_LIST_FREE(wd->items_built, item)
773      {
774         if (item->itc->func.del)
775           item->itc->func.del((void*)item->base.data, item->base.view);
776         evas_object_del(item->base.view);
777         item->base.view = NULL;
778      }
779
780    EINA_LIST_FREE(wd->items, item)
781      {
782         elm_widget_item_del(item);
783      }
784 }
785
786 /**
787  * Delete the item
788  *
789  * @param item The slideshow item
790  *
791  * @ingroup Slideshow
792  */
793 EAPI void
794 elm_slideshow_item_del(Elm_Slideshow_Item *item)
795 {
796    ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(item);
797    Widget_Data *wd = elm_widget_data_get(item->base.widget);
798    if (!wd) return;
799    if (wd->previous == item) wd->previous = NULL;
800    if (wd->current == item)
801      {
802         Eina_List *l = eina_list_data_find_list(wd->items, item);
803         Eina_List *l2 = eina_list_next(l);
804         wd->current = NULL;
805         if (!l2)
806           l2 = eina_list_nth_list(wd->items, eina_list_count(wd->items) - 1);
807         if (l2)
808           elm_slideshow_show(eina_list_data_get(l2));
809      }
810
811    wd->items = eina_list_remove_list(wd->items, item->l);
812    wd->items_built = eina_list_remove_list(wd->items_built, item->l_built);
813
814    if ((item->base.view) && (item->itc->func.del))
815      item->itc->func.del((void*)item->base.data, item->base.view);
816    if (item->base.view)
817      evas_object_del(item->base.view);
818    free(item);
819 }
820
821 /**
822  * Returns the list of items
823  * @param obj The slideshow object
824  * @return Returns the list of items (list of Elm_Slideshow_Item).
825  *
826  * @ingroup Slideshow
827  */
828 EAPI const Eina_List *
829 elm_slideshow_items_get(const Evas_Object *obj)
830 {
831    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
832    Widget_Data *wd = elm_widget_data_get(obj);
833    if (!wd) return NULL;
834    return wd->items;
835 }
836
837 /**
838  * Returns the current item displayed
839  *
840  * @param obj The slideshow object
841  * @return Returns the current item displayed
842  *
843  * @ingroup Slideshow
844  */
845 EAPI Elm_Slideshow_Item *
846 elm_slideshow_item_current_get(const Evas_Object *obj)
847 {
848    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
849    Widget_Data *wd = elm_widget_data_get(obj);
850    if (!wd) return NULL;
851    return wd->current;
852 }
853
854 /**
855  * Returns the evas object associated to an item
856  *
857  * @param item The slideshow item
858  * @return Returns the evas object associated to this item
859  *
860  * @ingroup Slideshow
861  */
862 EAPI Evas_Object *
863 elm_slideshow_item_object_get(const Elm_Slideshow_Item * item)
864 {
865    ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(item, NULL);
866    return item->base.view;
867 }
868
869 /**
870  * Returns the data associated to an item
871  *
872  * @param item The slideshow item
873  * @return Returns the data associated to this item
874  *
875  * @ingroup Slideshow
876  */
877 EAPI void *
878 elm_slideshow_item_data_get(const Elm_Slideshow_Item * item)
879 {
880    ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(item, NULL);
881    return elm_widget_item_data_get(item);
882 }
883
884 /**
885  * Returns max amount of cached items before current
886  *
887  * @param obj The slideshow object
888  * @return Returns max amount of cached items
889  *
890  * @ingroup Slideshow
891  */
892 EAPI int
893 elm_slideshow_cache_before_get(const Evas_Object *obj)
894 {
895    ELM_CHECK_WIDTYPE(obj, widtype) -1;
896    Widget_Data *wd = elm_widget_data_get(obj);
897    if (!wd) return -1;
898    return wd->count_item_pre_before;
899 }
900
901 /**
902  * Set max amount of cached items before current
903  *
904  * @param obj The slideshow object
905  * @param count Max amount of cached items
906  *
907  * @ingroup Slideshow
908  */
909 EAPI void
910 elm_slideshow_cache_before_set(Evas_Object *obj, int count)
911 {
912    ELM_CHECK_WIDTYPE(obj, widtype);
913    Widget_Data *wd = elm_widget_data_get(obj);
914    if (!wd) return;
915    if (count < 0) count = 0;
916    wd->count_item_pre_before = count;
917 }
918
919 /**
920  * Returns max amount of cached items after current
921  *
922  * @param obj The slideshow object
923  * @return Returns max amount of cached items
924  *
925  * @ingroup Slideshow
926  */
927 EAPI int
928 elm_slideshow_cache_after_get(const Evas_Object *obj)
929 {
930    ELM_CHECK_WIDTYPE(obj, widtype) -1;
931    Widget_Data *wd = elm_widget_data_get(obj);
932    if (!wd) return -1;
933    return wd->count_item_pre_after;
934 }
935
936 /**
937  * Set max amount of cached items after current
938  *
939  * @param obj The slideshow object
940  * @param count max amount of cached items
941  *
942  * @ingroup Slideshow
943  */
944 EAPI void
945 elm_slideshow_cache_after_set(Evas_Object *obj, int count)
946 {
947    ELM_CHECK_WIDTYPE(obj, widtype);
948    Widget_Data *wd = elm_widget_data_get(obj);
949    if (!wd) return;
950    if (count < 0) count = 0;
951    wd->count_item_pre_after = count;
952 }