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