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