elm: Use appropriate add/del_full for evas event callbacks.
[framework/uifw/elementary.git] / src / lib / elm_slideshow.c
1 #include <Elementary.h>
2 #include "elm_priv.h"
3
4 typedef struct _Widget_Data Widget_Data;
5
6 struct _Elm_Slideshow_Item
7 {
8    ELM_WIDGET_ITEM;
9
10    Eina_List *l, *l_built;
11
12    const Elm_Slideshow_Item_Class *itc;
13 };
14
15 struct _Widget_Data
16 {
17    Evas_Object *slideshow;
18
19    // list of Elm_Slideshow_Item*
20    Eina_List *items;
21    Eina_List *items_built;
22
23    Elm_Slideshow_Item *current;
24    Elm_Slideshow_Item *previous;
25
26    Eina_List *transitions;
27    const char *transition;
28
29    int count_item_pre_before;
30    int count_item_pre_after;
31    Ecore_Timer *timer;
32    double timeout;
33    Eina_Bool loop:1;
34
35    struct {
36         const char *current;
37         Eina_List *list; //list of const char *
38    } layout;
39 };
40
41 static const char *widtype = NULL;
42 static void _del_pre_hook(Evas_Object *obj);
43 static void _del_hook(Evas_Object *obj);
44 static void _mirrored_set(Evas_Object *obj, Eina_Bool rtl);
45 static void _theme_hook(Evas_Object *obj);
46 static void _sizing_eval(Evas_Object *obj);
47 static void _changed_size_hints(void *data, Evas *e, Evas_Object *obj, void *event_info);
48 static Eina_Bool _timer_cb(void *data);
49 static void _on_focus_hook(void *data, Evas_Object *obj);
50 static Eina_Bool _event_hook(Evas_Object *obj, Evas_Object *src,
51                              Evas_Callback_Type type, void *event_info);
52
53 static const char SIG_CHANGED[] = "changed";
54
55 static const Evas_Smart_Cb_Description _signals[] = {
56    {SIG_CHANGED, ""},
57    {NULL, NULL}
58 };
59
60 static Eina_Bool
61 _event_hook(Evas_Object *obj, Evas_Object *src __UNUSED__, Evas_Callback_Type type, void *event_info)
62 {
63    if (type != EVAS_CALLBACK_KEY_DOWN) return EINA_FALSE;
64    Evas_Event_Key_Down *ev = event_info;
65    Widget_Data *wd = elm_widget_data_get(obj);
66    if (!wd) return EINA_FALSE;
67    if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return EINA_FALSE;
68    if (elm_widget_disabled_get(obj)) return EINA_FALSE;
69    if ((!strcmp(ev->keyname, "Left")) || (!strcmp(ev->keyname, "KP_Left")))
70      {
71         elm_slideshow_previous(obj);
72         ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
73         return EINA_TRUE;
74      }
75    if ((!strcmp(ev->keyname, "Right")) || (!strcmp(ev->keyname, "KP_Right")))
76      {
77         elm_slideshow_next(obj);
78         ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
79         return EINA_TRUE;
80      }
81    if ((!strcmp(ev->keyname, "Return")) ||
82        (!strcmp(ev->keyname, "KP_Enter")) ||
83        (!strcmp(ev->keyname, "space")))
84      {
85         if (wd->timeout)
86           {
87              if (wd->timer)
88                {
89                   ecore_timer_del(wd->timer);
90                   wd->timer = NULL;
91                }
92              else
93                elm_slideshow_timeout_set(obj, wd->timeout);
94           }
95         ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
96         return EINA_TRUE;
97      }
98    return EINA_FALSE;
99 }
100
101 static void
102 _del_pre_hook(Evas_Object *obj)
103 {
104    Widget_Data *wd = elm_widget_data_get(obj);
105    if (!wd) return;
106    evas_object_event_callback_del_full(obj, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
107                                        _changed_size_hints, obj);
108 }
109
110 static void
111 _del_hook(Evas_Object *obj)
112 {
113    const char *layout;
114    Widget_Data *wd = elm_widget_data_get(obj);
115    if (!wd) return;
116    elm_slideshow_clear(obj);
117    elm_widget_stringlist_free(wd->transitions);
118    if (wd->timer) ecore_timer_del(wd->timer);
119    EINA_LIST_FREE(wd->layout.list, layout)
120       eina_stringshare_del(layout);
121    free(wd);
122 }
123
124 static void
125 _on_focus_hook(void *data __UNUSED__, Evas_Object *obj)
126 {
127    Widget_Data *wd = elm_widget_data_get(obj);
128    if (!wd) return;
129    if (elm_widget_focus_get(obj))
130      {
131         edje_object_signal_emit(wd->slideshow, "elm,action,focus", "elm");
132         evas_object_focus_set(wd->slideshow, EINA_TRUE);
133      }
134    else
135      {
136         edje_object_signal_emit(wd->slideshow, "elm,action,unfocus", "elm");
137         evas_object_focus_set(wd->slideshow, EINA_FALSE);
138      }
139 }
140
141 static void
142 _mirrored_set(Evas_Object *obj, Eina_Bool rtl)
143 {
144    Widget_Data *wd = elm_widget_data_get(obj);
145    if (!wd) return;
146    edje_object_mirrored_set(wd->slideshow, rtl);
147 }
148
149 static void
150 _theme_hook(Evas_Object *obj)
151 {
152    Widget_Data *wd = elm_widget_data_get(obj);
153    if (!wd) return;
154    _elm_widget_mirrored_reload(obj);
155    _mirrored_set(obj, elm_widget_mirrored_get(obj));
156    _elm_theme_object_set(obj, wd->slideshow, "slideshow", "base", elm_widget_style_get(obj));
157    edje_object_scale_set(wd->slideshow, elm_widget_scale_get(obj) *
158                          _elm_config->scale);
159    _sizing_eval(obj);
160 }
161
162 static void
163 _sizing_eval(Evas_Object *obj)
164 {
165    Widget_Data *wd = elm_widget_data_get(obj);
166    Evas_Coord minw = -1, minh = -1;
167    if (!wd) return;
168    edje_object_size_min_calc(wd->slideshow, &minw, &minh);
169    evas_object_size_hint_min_set(obj, minw, minh);
170    evas_object_size_hint_max_set(obj, minw, minh);
171 }
172
173
174 static Elm_Slideshow_Item* _item_prev_get(Elm_Slideshow_Item* item)
175 {
176    Widget_Data *wd = elm_widget_data_get(WIDGET(item));
177    Elm_Slideshow_Item* prev = eina_list_data_get(eina_list_prev(item->l));
178    if ((!prev) && (wd->loop))
179      prev = eina_list_data_get(eina_list_last(item->l));
180    return prev;
181 }
182
183 static Elm_Slideshow_Item* _item_next_get(Elm_Slideshow_Item* item)
184 {
185    Widget_Data *wd = elm_widget_data_get(WIDGET(item));
186    Elm_Slideshow_Item* next = eina_list_data_get(eina_list_next(item->l));
187    if ((!next) && (wd->loop))
188      next = eina_list_data_get(wd->items);
189    return next;
190 }
191
192 static void
193 _changed_size_hints(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
194 {
195    _sizing_eval(data);
196 }
197
198 static void
199 _sub_del(void *data __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
200 {
201    ;
202 }
203
204 static void
205 _item_realize(Elm_Slideshow_Item *item)
206 {
207    Elm_Slideshow_Item *_item_prev, *_item_next;
208    Evas_Object *obj = WIDGET(item);
209    Widget_Data *wd = elm_widget_data_get(obj);
210    int ac, bc, lc;
211
212    if (!wd) return;
213    if ((!VIEW(item)) && (item->itc->func.get))
214      {
215         VIEW(item) = item->itc->func.get((void*)item->base.data, obj);
216         evas_object_smart_member_add(VIEW(item), obj);
217         item->l_built = eina_list_append(NULL, item);
218         wd->items_built = eina_list_merge(wd->items_built, item->l_built);
219         evas_object_hide(VIEW(item));
220      }
221    else if (item->l_built)
222      wd->items_built = eina_list_demote_list(wd->items_built, item->l_built);
223
224    //pre-create previous and next item
225    ac = wd->count_item_pre_after;
226    _item_next = item;
227    bc = wd->count_item_pre_before;
228    _item_prev = item;
229    lc = eina_list_count(wd->items) - 1;
230    while (lc > 0 && ((ac > 0) || (bc > 0)))
231      {
232         if (lc > 0 && ac > 0)
233           {
234              --ac;
235              --lc;
236              if (_item_next)
237                {
238                   _item_next = _item_next_get(_item_next);
239                   if ((_item_next)
240                       && (!VIEW(_item_next))
241                       && (_item_next->itc->func.get))
242                     {
243                        VIEW(_item_next) =
244                           _item_next->itc->func.get(
245                              (void*)_item_next->base.data, obj);
246                        evas_object_smart_member_add(VIEW(_item_next), obj);
247                        _item_next->l_built = eina_list_append(NULL, _item_next);
248                        wd->items_built = eina_list_merge(wd->items_built,
249                                                          _item_next->l_built);
250                        evas_object_hide(VIEW(_item_next));
251                     }
252                   else if (_item_next && _item_next->l_built)
253                     wd->items_built =
254                        eina_list_demote_list(wd->items_built,
255                                              _item_next->l_built);
256                }
257           }
258
259         if (lc > 0 && bc > 0)
260           {
261              --bc;
262              --lc;
263              if (_item_prev)
264                {
265                   _item_prev = _item_prev_get(_item_prev);
266                   if ((_item_prev)
267                       && (!VIEW(_item_prev))
268                       && (_item_prev->itc->func.get))
269                     {
270                        VIEW(_item_prev) =
271                           _item_prev->itc->func.get(
272                              (void*)_item_prev->base.data, obj);
273                        evas_object_smart_member_add(VIEW(_item_prev), obj);
274                        _item_prev->l_built = eina_list_append(NULL, _item_prev);
275                        wd->items_built = eina_list_merge(wd->items_built,
276                                                          _item_prev->l_built);
277                        evas_object_hide(VIEW(_item_prev));
278                     }
279                   else if (_item_prev && _item_prev->l_built)
280                     wd->items_built =
281                        eina_list_demote_list(wd->items_built,
282                                              _item_prev->l_built);
283                }
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, VIEW(item));
296         evas_object_del(VIEW(item));
297         VIEW(item) = 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, VIEW(item));
312         evas_object_hide(VIEW(item));
313         wd->previous = NULL;
314      }
315
316
317    item = wd->current;
318    if ((!item) || (!VIEW(item))) return;
319
320    _item_realize(item);
321    edje_object_part_unswallow(NULL, VIEW(item));
322    evas_object_show(VIEW(item));
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 EAPI Evas_Object *
340 elm_slideshow_add(Evas_Object *parent)
341 {
342    Evas_Object *obj;
343    Evas *e;
344    Widget_Data *wd;
345
346    ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL);
347
348    ELM_SET_WIDTYPE(widtype, "slideshow");
349    elm_widget_type_set(obj, "slideshow");
350    elm_widget_sub_object_add(parent, obj);
351    elm_widget_on_focus_hook_set(obj, _on_focus_hook, NULL);
352    elm_widget_data_set(obj, wd);
353    elm_widget_del_pre_hook_set(obj, _del_pre_hook);
354    elm_widget_del_hook_set(obj, _del_hook);
355    elm_widget_theme_hook_set(obj, _theme_hook);
356    elm_widget_can_focus_set(obj, EINA_TRUE);
357    elm_widget_event_hook_set(obj, _event_hook);
358
359    wd->current = NULL;
360    wd->previous = NULL;
361
362    wd->slideshow = edje_object_add(e);
363    _elm_theme_object_set(obj, wd->slideshow, "slideshow", "base", "default");
364    evas_object_smart_member_add(wd->slideshow, obj);
365    wd->count_item_pre_before = 2;
366    wd->count_item_pre_after = 2;
367    elm_widget_resize_object_set(obj, wd->slideshow);
368    evas_object_show(wd->slideshow);
369
370    wd->transitions = elm_widget_stringlist_get(edje_object_data_get(wd->slideshow, "transitions"));
371    if (eina_list_count(wd->transitions) > 0)
372      wd->transition = eina_stringshare_add(eina_list_data_get(wd->transitions));
373
374    wd->layout.list = elm_widget_stringlist_get(edje_object_data_get(wd->slideshow, "layouts"));
375    if (eina_list_count(wd->layout.list) > 0)
376      wd->layout.current = eina_list_data_get(wd->layout.list);
377
378    edje_object_signal_callback_add(wd->slideshow, "end", "slideshow", _end, obj);
379
380    evas_object_smart_callback_add(obj, "sub-object-del", _sub_del, obj);
381    evas_object_event_callback_add(obj, EVAS_CALLBACK_CHANGED_SIZE_HINTS, _changed_size_hints, obj);
382
383    evas_object_smart_callbacks_descriptions_set(obj, _signals);
384
385    _mirrored_set(obj, elm_widget_mirrored_get(obj));
386    _sizing_eval(obj);
387    return obj;
388 }
389
390 EAPI Elm_Slideshow_Item*
391 elm_slideshow_item_add(Evas_Object *obj, const Elm_Slideshow_Item_Class *itc, const void *data)
392 {
393    Elm_Slideshow_Item *item;
394    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
395    Widget_Data *wd = elm_widget_data_get(obj);
396
397    if (!wd) return NULL;
398    item = elm_widget_item_new(obj, Elm_Slideshow_Item);
399    item->base.data = data;
400    item->itc = itc;
401    item->l = eina_list_append(item->l, item);
402
403    wd->items = eina_list_merge(wd->items, item->l);
404
405    if (!wd->current) elm_slideshow_show(item);
406
407    return item;
408 }
409
410 EAPI Elm_Slideshow_Item*
411 elm_slideshow_item_sorted_insert(Evas_Object *obj, const Elm_Slideshow_Item_Class *itc, const void *data, Eina_Compare_Cb func)
412 {
413    Elm_Slideshow_Item *item;
414    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
415    Widget_Data *wd = elm_widget_data_get(obj);
416
417    if (!wd) return NULL;
418    item = elm_widget_item_new(obj, Elm_Slideshow_Item);
419    item->base.data = data;
420    item->itc = itc;
421    item->l = eina_list_append(item->l, item);
422
423    wd->items = eina_list_sorted_merge(wd->items, item->l, func);
424
425    if (!wd->current) elm_slideshow_show(item);
426
427    return item;
428 }
429
430 EAPI void
431 elm_slideshow_show(Elm_Slideshow_Item *item)
432 {
433    char buf[1024];
434    Elm_Slideshow_Item *next = NULL;
435    Widget_Data *wd;
436    ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(item);
437    wd = elm_widget_data_get(WIDGET(item));
438    if (!wd)
439      return;
440    if (item == wd->current)
441      return;
442
443    next = item;
444    _end(WIDGET(item), WIDGET(item), NULL, NULL);
445
446    if (wd->timer) ecore_timer_del(wd->timer);
447    if (wd->timeout > 0.0)
448      wd->timer = ecore_timer_add(wd->timeout, _timer_cb, WIDGET(item));
449    _item_realize(next);
450    edje_object_part_swallow(wd->slideshow, "elm.swallow.2", VIEW(next));
451    evas_object_show(VIEW(next));
452    snprintf(buf, sizeof(buf), "%s,next", wd->transition);
453    edje_object_signal_emit(wd->slideshow, buf, "slideshow");
454    wd->previous = wd->current;
455    wd->current = next;
456    evas_object_smart_callback_call(WIDGET(item), SIG_CHANGED, wd->current);
457 }
458
459 EAPI void
460 elm_slideshow_next(Evas_Object *obj)
461 {
462    char buf[1024];
463    Elm_Slideshow_Item *next = NULL;
464    ELM_CHECK_WIDTYPE(obj, widtype);
465    Widget_Data *wd = elm_widget_data_get(obj);
466
467    if (!wd) return;
468
469    if (wd->current)
470      next = _item_next_get(wd->current);
471
472    if ((!next) || (next == wd->current)) return;
473
474    _end(obj, obj, NULL, NULL);
475
476    if (wd->timer) ecore_timer_del(wd->timer);
477    if (wd->timeout > 0.0)
478      wd->timer = ecore_timer_add(wd->timeout, _timer_cb, obj);
479
480    _item_realize(next);
481
482    edje_object_part_swallow(wd->slideshow, "elm.swallow.2", VIEW(next));
483    evas_object_show(VIEW(next));
484
485    snprintf(buf, sizeof(buf), "%s,next", wd->transition);
486    edje_object_signal_emit(wd->slideshow, buf, "slideshow");
487
488    wd->previous = wd->current;
489    wd->current = next;
490    evas_object_smart_callback_call(obj, SIG_CHANGED, wd->current);
491 }
492
493 EAPI void
494 elm_slideshow_previous(Evas_Object *obj)
495 {
496    char buf[1024];
497    Elm_Slideshow_Item *prev = NULL;
498    ELM_CHECK_WIDTYPE(obj, widtype);
499    Widget_Data *wd = elm_widget_data_get(obj);
500
501    if (!wd) return;
502
503    if (wd->current)
504      prev = _item_prev_get(wd->current);
505
506    if ((!prev) ||  (prev == wd->current)) return;
507
508    _end(obj, obj, NULL, NULL);
509
510    if (wd->timer) ecore_timer_del(wd->timer);
511    if (wd->timeout > 0.0)
512      wd->timer = ecore_timer_add(wd->timeout, _timer_cb, obj);
513
514    _item_realize(prev);
515
516    edje_object_part_swallow(wd->slideshow, "elm.swallow.2", VIEW(prev));
517    evas_object_show(VIEW(prev));
518
519    snprintf(buf, 1024, "%s,previous", wd->transition);
520    edje_object_signal_emit(wd->slideshow, buf, "slideshow");
521
522    wd->previous = wd->current;
523    wd->current = prev;
524    evas_object_smart_callback_call(obj, SIG_CHANGED, wd->current);
525 }
526
527 EAPI const Eina_List *
528 elm_slideshow_transitions_get(const Evas_Object *obj)
529 {
530    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
531    Widget_Data *wd = elm_widget_data_get(obj);
532    if (!wd) return NULL;
533    return wd->transitions;
534 }
535
536 EAPI const Eina_List *
537 elm_slideshow_layouts_get(const Evas_Object *obj)
538 {
539    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
540    Widget_Data *wd = elm_widget_data_get(obj);
541    if (!wd) return NULL;
542    return wd->layout.list;
543 }
544
545 EAPI void
546 elm_slideshow_transition_set(Evas_Object *obj, const char *transition)
547 {
548    ELM_CHECK_WIDTYPE(obj, widtype);
549    Widget_Data *wd = elm_widget_data_get(obj);
550    if (!wd) return;
551    eina_stringshare_replace(&wd->transition, transition);
552 }
553
554 EAPI const char *
555 elm_slideshow_transition_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->transition;
561 }
562
563 EAPI void
564 elm_slideshow_timeout_set(Evas_Object *obj, double 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.0)
573      wd->timer = ecore_timer_add(timeout, _timer_cb, obj);
574 }
575
576 EAPI double
577 elm_slideshow_timeout_get(const Evas_Object *obj)
578 {
579    ELM_CHECK_WIDTYPE(obj, widtype) -1.0;
580    Widget_Data *wd = elm_widget_data_get(obj);
581    if (!wd) return -1.0;
582    return wd->timeout;
583 }
584
585 EAPI void
586 elm_slideshow_loop_set(Evas_Object *obj, Eina_Bool loop)
587 {
588    ELM_CHECK_WIDTYPE(obj, widtype);
589    Widget_Data *wd = elm_widget_data_get(obj);
590    if (!wd) return;
591    wd->loop = loop;
592 }
593
594 EAPI const char *
595 elm_slideshow_layout_get(const Evas_Object *obj)
596 {
597    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
598    Widget_Data *wd = elm_widget_data_get(obj);
599    if (!wd) return EINA_FALSE;
600    return wd->layout.current;
601 }
602
603 EAPI void
604 elm_slideshow_layout_set(Evas_Object *obj, const char *layout)
605 {
606    char buf[PATH_MAX];
607    ELM_CHECK_WIDTYPE(obj, widtype);
608    Widget_Data *wd = elm_widget_data_get(obj);
609    if (!wd) return;
610
611    wd->layout.current = layout;
612    snprintf(buf, sizeof(buf), "layout,%s", layout);
613    edje_object_signal_emit(wd->slideshow, buf, "slideshow");
614 }
615
616 EAPI Eina_Bool
617 elm_slideshow_loop_get(const Evas_Object *obj)
618 {
619    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
620    Widget_Data *wd = elm_widget_data_get(obj);
621    if (!wd) return EINA_FALSE;
622    return wd->loop;
623 }
624
625 EAPI void
626 elm_slideshow_clear(Evas_Object *obj)
627 {
628    Elm_Slideshow_Item *item;
629    ELM_CHECK_WIDTYPE(obj, widtype);
630    Widget_Data *wd = elm_widget_data_get(obj);
631    if (!wd) return;
632    wd->previous = NULL;
633    wd->current = NULL;
634    EINA_LIST_FREE(wd->items_built, item)
635      {
636         if (item->itc->func.del)
637           item->itc->func.del((void*)item->base.data, VIEW(item));
638         evas_object_del(VIEW(item));
639         VIEW(item) = NULL;
640      }
641
642    EINA_LIST_FREE(wd->items, item)
643      {
644         elm_widget_item_del(item);
645      }
646 }
647
648 EAPI void
649 elm_slideshow_item_del(Elm_Slideshow_Item *item)
650 {
651    ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(item);
652    Widget_Data *wd = elm_widget_data_get(WIDGET(item));
653    if (!wd) return;
654    if (wd->previous == item) wd->previous = NULL;
655    if (wd->current == item)
656      {
657         Eina_List *l = eina_list_data_find_list(wd->items, item);
658         Eina_List *l2 = eina_list_next(l);
659         wd->current = NULL;
660         if (!l2)
661           l2 = eina_list_nth_list(wd->items, eina_list_count(wd->items) - 1);
662         if (l2)
663           elm_slideshow_show(eina_list_data_get(l2));
664      }
665
666    wd->items = eina_list_remove_list(wd->items, item->l);
667    wd->items_built = eina_list_remove_list(wd->items_built, item->l_built);
668
669    if ((VIEW(item)) && (item->itc->func.del))
670      item->itc->func.del((void*)item->base.data, VIEW(item));
671    if (VIEW(item))
672      evas_object_del(VIEW(item));
673    free(item);
674 }
675
676 EAPI const Eina_List *
677 elm_slideshow_items_get(const Evas_Object *obj)
678 {
679    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
680    Widget_Data *wd = elm_widget_data_get(obj);
681    if (!wd) return NULL;
682    return wd->items;
683 }
684
685 EAPI Elm_Slideshow_Item *
686 elm_slideshow_item_current_get(const Evas_Object *obj)
687 {
688    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
689    Widget_Data *wd = elm_widget_data_get(obj);
690    if (!wd) return NULL;
691    return wd->current;
692 }
693
694 EAPI Evas_Object *
695 elm_slideshow_item_object_get(const Elm_Slideshow_Item * item)
696 {
697    ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(item, NULL);
698    return VIEW(item);
699 }
700
701 EAPI void *
702 elm_slideshow_item_data_get(const Elm_Slideshow_Item * item)
703 {
704    ELM_WIDGET_ITEM_WIDTYPE_CHECK_OR_RETURN(item, NULL);
705    return elm_widget_item_data_get(item);
706 }
707
708 EAPI int
709 elm_slideshow_cache_before_get(const Evas_Object *obj)
710 {
711    ELM_CHECK_WIDTYPE(obj, widtype) -1;
712    Widget_Data *wd = elm_widget_data_get(obj);
713    if (!wd) return -1;
714    return wd->count_item_pre_before;
715 }
716
717 EAPI void
718 elm_slideshow_cache_before_set(Evas_Object *obj, int count)
719 {
720    ELM_CHECK_WIDTYPE(obj, widtype);
721    Widget_Data *wd = elm_widget_data_get(obj);
722    if (!wd) return;
723    if (count < 0) count = 0;
724    wd->count_item_pre_before = count;
725 }
726
727 EAPI int
728 elm_slideshow_cache_after_get(const Evas_Object *obj)
729 {
730    ELM_CHECK_WIDTYPE(obj, widtype) -1;
731    Widget_Data *wd = elm_widget_data_get(obj);
732    if (!wd) return -1;
733    return wd->count_item_pre_after;
734 }
735
736 EAPI void
737 elm_slideshow_cache_after_set(Evas_Object *obj, int count)
738 {
739    ELM_CHECK_WIDTYPE(obj, widtype);
740    Widget_Data *wd = elm_widget_data_get(obj);
741    if (!wd) return;
742    if (count < 0) count = 0;
743    wd->count_item_pre_after = count;
744 }
745
746 EAPI Elm_Slideshow_Item *
747 elm_slideshow_item_nth_get(const Evas_Object *obj, unsigned int nth)
748 {
749    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
750    Widget_Data *wd = elm_widget_data_get(obj);
751    if (!wd) return NULL;
752    return eina_list_nth(wd->items, nth);
753 }
754
755 EAPI unsigned int
756 elm_slideshow_count_get(const Evas_Object *obj)
757 {
758    ELM_CHECK_WIDTYPE(obj, widtype) 0;
759    Widget_Data *wd = elm_widget_data_get(obj);
760    if (!wd) return 0;
761    return eina_list_count(wd->items);
762 }