1 #include <Elementary.h>
3 #include "elm_widget_slideshow.h"
5 EAPI const char ELM_SLIDESHOW_SMART_NAME[] = "elm_slideshow";
7 static const char SIG_CHANGED[] = "changed";
8 static const char SIG_TRANSITION_END[] = "transition,end";
10 static const Evas_Smart_Cb_Description _smart_callbacks[] = {
12 {SIG_TRANSITION_END, ""},
16 EVAS_SMART_SUBCLASS_NEW
17 (ELM_SLIDESHOW_SMART_NAME, _elm_slideshow, Elm_Slideshow_Smart_Class,
18 Elm_Layout_Smart_Class, elm_layout_smart_class_get, _smart_callbacks);
21 _elm_slideshow_smart_event(Evas_Object *obj,
22 Evas_Object *src __UNUSED__,
23 Evas_Callback_Type type,
26 Evas_Event_Key_Down *ev = event_info;
28 // TIZEN ONLY(20131221) : When access mode, focused ui is disabled.
29 if (_elm_config->access_mode) return EINA_FALSE;
31 if (elm_widget_disabled_get(obj)) return EINA_FALSE;
33 if (type != EVAS_CALLBACK_KEY_DOWN) return EINA_FALSE;
34 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return EINA_FALSE;
36 ELM_SLIDESHOW_DATA_GET(obj, sd);
38 if ((!strcmp(ev->keyname, "Left")) ||
39 ((!strcmp(ev->keyname, "KP_Left")) && (!ev->string)))
41 elm_slideshow_previous(obj);
42 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
47 if ((!strcmp(ev->keyname, "Right")) ||
48 ((!strcmp(ev->keyname, "KP_Right")) && (!ev->string)))
50 elm_slideshow_next(obj);
51 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
56 if ((!strcmp(ev->keyname, "Return")) ||
57 (!strcmp(ev->keyname, "KP_Enter")))
63 ecore_timer_del(sd->timer);
67 elm_slideshow_timeout_set(obj, sd->timeout);
69 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
78 _elm_slideshow_smart_sizing_eval(Evas_Object *obj)
80 ELM_SLIDESHOW_DATA_GET(obj, sd);
81 Evas_Coord minw = -1, minh = -1;
83 edje_object_size_min_calc(ELM_WIDGET_DATA(sd)->resize_obj, &minw, &minh);
84 evas_object_size_hint_min_set(obj, minw, minh);
85 evas_object_size_hint_max_set(obj, minw, minh);
88 static Elm_Slideshow_Item *
89 _item_prev_get(Elm_Slideshow_Item *item)
91 ELM_SLIDESHOW_DATA_GET(WIDGET(item), sd);
92 Elm_Slideshow_Item *prev = eina_list_data_get(eina_list_prev(item->l));
94 if ((!prev) && (sd->loop))
95 prev = eina_list_data_get(eina_list_last(item->l));
100 static Elm_Slideshow_Item *
101 _item_next_get(Elm_Slideshow_Item *item)
103 ELM_SLIDESHOW_DATA_GET(WIDGET(item), sd);
104 Elm_Slideshow_Item *next = eina_list_data_get(eina_list_next(item->l));
106 if ((!next) && (sd->loop))
107 next = eina_list_data_get(sd->items);
113 _on_size_hints_changed(void *data,
115 Evas_Object *obj __UNUSED__,
116 void *event_info __UNUSED__)
118 elm_layout_sizing_eval(data);
122 _item_realize(Elm_Slideshow_Item *item)
124 Elm_Slideshow_Item *_item_prev, *_item_next;
125 Evas_Object *obj = WIDGET(item);
126 int ac, bc, lc, ic = 0;
128 ELM_SLIDESHOW_DATA_GET_OR_RETURN(obj, sd);
130 if ((!VIEW(item)) && (item->itc->func.get))
132 VIEW(item) = item->itc->func.get(elm_widget_item_data_get(item), obj);
133 item->l_built = eina_list_append(NULL, item);
134 sd->items_built = eina_list_merge(sd->items_built, item->l_built);
135 //FIXME: item could be shown by obj
136 evas_object_hide(VIEW(item));
138 else if (item->l_built)
139 sd->items_built = eina_list_demote_list(sd->items_built, item->l_built);
141 //pre-create previous and next item
142 ac = sd->count_item_pre_after;
144 bc = sd->count_item_pre_before;
146 lc = eina_list_count(sd->items) - 1;
148 while (lc > 0 && ((ac > 0) || (bc > 0)))
150 if (lc > 0 && ac > 0)
156 _item_next = _item_next_get(_item_next);
158 && (!VIEW(_item_next))
159 && (_item_next->itc->func.get))
163 _item_next->itc->func.get(
164 elm_widget_item_data_get(_item_next), obj);
165 _item_next->l_built =
166 eina_list_append(NULL, _item_next);
167 sd->items_built = eina_list_merge
168 (sd->items_built, _item_next->l_built);
169 //FIXME: _item_next could be shown by obj later
170 evas_object_hide(VIEW(_item_next));
172 else if (_item_next && _item_next->l_built)
176 eina_list_demote_list
177 (sd->items_built, _item_next->l_built);
182 if (lc > 0 && bc > 0)
188 _item_prev = _item_prev_get(_item_prev);
190 && (!VIEW(_item_prev))
191 && (_item_prev->itc->func.get))
195 _item_prev->itc->func.get(
196 elm_widget_item_data_get(_item_prev), obj);
197 _item_prev->l_built =
198 eina_list_append(NULL, _item_prev);
199 sd->items_built = eina_list_merge
200 (sd->items_built, _item_prev->l_built);
201 //FIXME: _item_prev could be shown by obj later
202 evas_object_hide(VIEW(_item_prev));
204 else if (_item_prev && _item_prev->l_built)
208 eina_list_demote_list
209 (sd->items_built, _item_prev->l_built);
215 //delete unused items
218 while ((int)eina_list_count(sd->items_built) > lc)
220 item = eina_list_data_get(sd->items_built);
221 sd->items_built = eina_list_remove_list
222 (sd->items_built, sd->items_built);
223 if (item->itc->func.del)
224 item->itc->func.del(elm_widget_item_data_get(item), VIEW(item));
225 evas_object_del(VIEW(item));
231 _on_slideshow_end(void *data,
232 Evas_Object *obj __UNUSED__,
233 const char *emission,
234 const char *source __UNUSED__)
236 Elm_Slideshow_Item *item;
237 ELM_SLIDESHOW_DATA_GET(data, sd);
242 elm_layout_content_unset(data, "elm.swallow.1");
243 evas_object_hide(VIEW(item));
248 if ((!item) || (!VIEW(item))) return;
251 elm_layout_content_unset(data, "elm.swallow.2");
253 elm_layout_content_set(data, "elm.swallow.1", VIEW(item));
254 elm_layout_signal_emit(data, "anim,end", "slideshow");
256 if (emission != NULL)
257 evas_object_smart_callback_call(data, SIG_TRANSITION_END, sd->current);
261 _timer_cb(void *data)
263 Evas_Object *obj = data;
264 ELM_SLIDESHOW_DATA_GET(obj, sd);
267 elm_slideshow_next(obj);
269 return ECORE_CALLBACK_CANCEL;
273 _item_del_pre_hook(Elm_Object_Item *it)
275 Elm_Slideshow_Item *item = (Elm_Slideshow_Item *)it;
276 ELM_SLIDESHOW_DATA_GET_OR_RETURN_VAL(WIDGET(item), sd, EINA_FALSE);
278 if (sd->previous == item) sd->previous = NULL;
279 if (sd->current == item)
281 Eina_List *l = eina_list_data_find_list(sd->items, item);
282 Eina_List *l2 = eina_list_next(l);
286 l2 = eina_list_prev(l);
288 elm_slideshow_item_show(eina_list_data_get(l2));
291 elm_slideshow_item_show(eina_list_data_get(l2));
294 sd->items = eina_list_remove_list(sd->items, item->l);
295 sd->items_built = eina_list_remove_list(sd->items_built, item->l_built);
297 if ((VIEW(item)) && (item->itc->func.del))
298 item->itc->func.del(elm_widget_item_data_get(item), VIEW(item));
304 _elm_slideshow_smart_add(Evas_Object *obj)
306 EVAS_SMART_DATA_ALLOC(obj, Elm_Slideshow_Smart_Data);
308 ELM_WIDGET_CLASS(_elm_slideshow_parent_sc)->base.add(obj);
312 _elm_slideshow_smart_del(Evas_Object *obj)
314 ELM_SLIDESHOW_DATA_GET(obj, sd);
317 elm_slideshow_clear(obj);
318 elm_widget_stringlist_free(sd->transitions);
319 if (sd->timer) ecore_timer_del(sd->timer);
321 EINA_LIST_FREE (sd->layout.list, layout)
322 eina_stringshare_del(layout);
324 ELM_WIDGET_CLASS(_elm_slideshow_parent_sc)->base.del(obj);
328 _elm_slideshow_smart_set_user(Elm_Slideshow_Smart_Class *sc)
330 ELM_WIDGET_CLASS(sc)->base.add = _elm_slideshow_smart_add;
331 ELM_WIDGET_CLASS(sc)->base.del = _elm_slideshow_smart_del;
333 ELM_WIDGET_CLASS(sc)->event = _elm_slideshow_smart_event;
335 /* not a 'focus chain manager' */
336 ELM_WIDGET_CLASS(sc)->focus_next = NULL;
337 ELM_WIDGET_CLASS(sc)->focus_direction_manager_is = NULL;
338 ELM_WIDGET_CLASS(sc)->focus_direction = NULL;
340 ELM_LAYOUT_CLASS(sc)->sizing_eval = _elm_slideshow_smart_sizing_eval;
343 EAPI const Elm_Slideshow_Smart_Class *
344 elm_slideshow_smart_class_get(void)
346 static Elm_Slideshow_Smart_Class _sc =
347 ELM_SLIDESHOW_SMART_CLASS_INIT_NAME_VERSION(ELM_SLIDESHOW_SMART_NAME);
348 static const Elm_Slideshow_Smart_Class *class = NULL;
349 Evas_Smart_Class *esc = (Evas_Smart_Class *)&_sc;
354 _elm_slideshow_smart_set(&_sc);
355 esc->callbacks = _smart_callbacks;
362 elm_slideshow_add(Evas_Object *parent)
366 EINA_SAFETY_ON_NULL_RETURN_VAL(parent, NULL);
368 obj = elm_widget_add(_elm_slideshow_smart_class_new(), parent);
369 if (!obj) return NULL;
371 if (!elm_widget_sub_object_add(parent, obj))
372 ERR("could not add %p as sub object of %p", obj, parent);
374 ELM_SLIDESHOW_DATA_GET(obj, sd);
379 sd->count_item_pre_before = 2;
380 sd->count_item_pre_after = 2;
382 elm_layout_theme_set(obj, "slideshow", "base", elm_widget_style_get(obj));
384 sd->transitions = elm_widget_stringlist_get
385 (edje_object_data_get(ELM_WIDGET_DATA(sd)->resize_obj,
387 if (eina_list_count(sd->transitions) > 0)
389 eina_stringshare_add(eina_list_data_get(sd->transitions));
391 sd->layout.list = elm_widget_stringlist_get
392 (edje_object_data_get(ELM_WIDGET_DATA(sd)->resize_obj, "layouts"));
394 if (eina_list_count(sd->layout.list) > 0)
395 sd->layout.current = eina_list_data_get(sd->layout.list);
397 edje_object_signal_callback_add
398 (ELM_WIDGET_DATA(sd)->resize_obj, "end", "slideshow", _on_slideshow_end,
401 evas_object_event_callback_add
402 (obj, EVAS_CALLBACK_CHANGED_SIZE_HINTS, _on_size_hints_changed, obj);
404 elm_widget_can_focus_set(obj, EINA_TRUE);
406 elm_layout_sizing_eval(obj);
408 //Tizen Only: This should be removed when eo is applied.
409 ELM_WIDGET_DATA_GET(obj, wsd);
410 wsd->on_create = EINA_FALSE;
415 EAPI Elm_Object_Item *
416 elm_slideshow_item_add(Evas_Object *obj,
417 const Elm_Slideshow_Item_Class *itc,
420 Elm_Slideshow_Item *item;
422 ELM_SLIDESHOW_CHECK(obj) NULL;
423 ELM_SLIDESHOW_DATA_GET(obj, sd);
425 item = elm_widget_item_new(obj, Elm_Slideshow_Item);
426 if (!item) return NULL;
428 elm_widget_item_del_pre_hook_set(item, _item_del_pre_hook);
430 item->l = eina_list_append(item->l, item);
431 elm_widget_item_data_set(item, data);
433 sd->items = eina_list_merge(sd->items, item->l);
435 if (!sd->current) elm_slideshow_item_show((Elm_Object_Item *)item);
437 return (Elm_Object_Item *)item;
440 EAPI Elm_Object_Item *
441 elm_slideshow_item_sorted_insert(Evas_Object *obj,
442 const Elm_Slideshow_Item_Class *itc,
444 Eina_Compare_Cb func)
446 Elm_Slideshow_Item *item;
448 ELM_SLIDESHOW_CHECK(obj) NULL;
449 ELM_SLIDESHOW_DATA_GET(obj, sd);
451 item = elm_widget_item_new(obj, Elm_Slideshow_Item);
452 if (!item) return NULL;
454 elm_widget_item_del_pre_hook_set(item, _item_del_pre_hook);
456 item->l = eina_list_append(item->l, item);
457 elm_widget_item_data_set(item, data);
459 sd->items = eina_list_sorted_merge(sd->items, item->l, func);
461 if (!sd->current) elm_slideshow_item_show((Elm_Object_Item *)item);
463 return (Elm_Object_Item *)item;
467 elm_slideshow_item_show(Elm_Object_Item *it)
470 Elm_Slideshow_Item *item, *next = NULL;
472 ELM_SLIDESHOW_ITEM_CHECK(it);
474 item = (Elm_Slideshow_Item *)it;
475 ELM_SLIDESHOW_DATA_GET(WIDGET(item), sd);
477 if (item == sd->current) return;
480 _on_slideshow_end(WIDGET(item), WIDGET(item), NULL, NULL);
482 if (sd->timer) ecore_timer_del(sd->timer);
484 if (sd->timeout > 0.0)
485 sd->timer = ecore_timer_add(sd->timeout, _timer_cb, WIDGET(item));
488 elm_layout_content_set(WIDGET(item), "elm.swallow.2", VIEW(next));
491 sprintf(buf,"none,next");
493 snprintf(buf, sizeof(buf), "%s,next", sd->transition);
494 elm_layout_signal_emit(WIDGET(item), buf, "slideshow");
496 sd->previous = sd->current;
498 evas_object_smart_callback_call(WIDGET(item), SIG_CHANGED, sd->current);
502 elm_slideshow_next(Evas_Object *obj)
505 Elm_Slideshow_Item *next = NULL;
507 ELM_SLIDESHOW_CHECK(obj);
508 ELM_SLIDESHOW_DATA_GET(obj, sd);
510 if (sd->current) next = _item_next_get(sd->current);
512 if ((!next) || (next == sd->current)) return;
514 _on_slideshow_end(obj, obj, NULL, NULL);
516 if (sd->timer) ecore_timer_del(sd->timer);
518 if (sd->timeout > 0.0)
519 sd->timer = ecore_timer_add(sd->timeout, _timer_cb, obj);
523 elm_layout_content_set(obj, "elm.swallow.2", VIEW(next));
526 sprintf(buf,"none,next");
528 snprintf(buf, sizeof(buf), "%s,next", sd->transition);
529 elm_layout_signal_emit(obj, buf, "slideshow");
531 sd->previous = sd->current;
533 evas_object_smart_callback_call(obj, SIG_CHANGED, sd->current);
537 elm_slideshow_previous(Evas_Object *obj)
540 Elm_Slideshow_Item *prev = NULL;
542 ELM_SLIDESHOW_CHECK(obj);
543 ELM_SLIDESHOW_DATA_GET(obj, sd);
545 if (sd->current) prev = _item_prev_get(sd->current);
547 if ((!prev) || (prev == sd->current)) return;
549 _on_slideshow_end(obj, obj, NULL, NULL);
551 if (sd->timer) ecore_timer_del(sd->timer);
553 if (sd->timeout > 0.0)
554 sd->timer = ecore_timer_add(sd->timeout, _timer_cb, obj);
558 elm_layout_content_set(obj, "elm.swallow.2", VIEW(prev));
561 sprintf(buf,"none,previous");
563 snprintf(buf, 1024, "%s,previous", sd->transition);
564 elm_layout_signal_emit(obj, buf, "slideshow");
566 sd->previous = sd->current;
568 evas_object_smart_callback_call(obj, SIG_CHANGED, sd->current);
571 EAPI const Eina_List *
572 elm_slideshow_transitions_get(const Evas_Object *obj)
574 ELM_SLIDESHOW_CHECK(obj) NULL;
575 ELM_SLIDESHOW_DATA_GET(obj, sd);
577 return sd->transitions;
580 EAPI const Eina_List *
581 elm_slideshow_layouts_get(const Evas_Object *obj)
583 ELM_SLIDESHOW_CHECK(obj) NULL;
584 ELM_SLIDESHOW_DATA_GET(obj, sd);
586 return sd->layout.list;
590 elm_slideshow_transition_set(Evas_Object *obj,
591 const char *transition)
593 ELM_SLIDESHOW_CHECK(obj);
594 ELM_SLIDESHOW_DATA_GET(obj, sd);
596 eina_stringshare_replace(&sd->transition, transition);
600 elm_slideshow_transition_get(const Evas_Object *obj)
602 ELM_SLIDESHOW_CHECK(obj) NULL;
603 ELM_SLIDESHOW_DATA_GET(obj, sd);
605 return sd->transition;
609 elm_slideshow_timeout_set(Evas_Object *obj,
612 ELM_SLIDESHOW_CHECK(obj);
613 ELM_SLIDESHOW_DATA_GET(obj, sd);
615 sd->timeout = timeout;
617 if (sd->timer) ecore_timer_del(sd->timer);
621 sd->timer = ecore_timer_add(timeout, _timer_cb, obj);
625 elm_slideshow_timeout_get(const Evas_Object *obj)
627 ELM_SLIDESHOW_CHECK(obj) - 1.0;
628 ELM_SLIDESHOW_DATA_GET(obj, sd);
634 elm_slideshow_loop_set(Evas_Object *obj,
637 ELM_SLIDESHOW_CHECK(obj);
638 ELM_SLIDESHOW_DATA_GET(obj, sd);
644 elm_slideshow_layout_get(const Evas_Object *obj)
646 ELM_SLIDESHOW_CHECK(obj) EINA_FALSE;
647 ELM_SLIDESHOW_DATA_GET(obj, sd);
649 return sd->layout.current;
653 elm_slideshow_layout_set(Evas_Object *obj,
658 ELM_SLIDESHOW_CHECK(obj);
659 ELM_SLIDESHOW_DATA_GET(obj, sd);
661 sd->layout.current = layout;
662 snprintf(buf, sizeof(buf), "layout,%s", layout);
663 elm_layout_signal_emit(obj, buf, "slideshow");
667 elm_slideshow_loop_get(const Evas_Object *obj)
669 ELM_SLIDESHOW_CHECK(obj) EINA_FALSE;
670 ELM_SLIDESHOW_DATA_GET(obj, sd);
676 elm_slideshow_clear(Evas_Object *obj)
678 Elm_Slideshow_Item *item;
680 ELM_SLIDESHOW_CHECK(obj);
681 ELM_SLIDESHOW_DATA_GET(obj, sd);
685 EINA_LIST_FREE (sd->items_built, item)
687 if (item->itc->func.del)
688 item->itc->func.del(elm_widget_item_data_get(item), VIEW(item));
691 EINA_LIST_FREE (sd->items, item)
692 elm_widget_item_free(item);
695 EAPI const Eina_List *
696 elm_slideshow_items_get(const Evas_Object *obj)
698 ELM_SLIDESHOW_CHECK(obj) NULL;
699 ELM_SLIDESHOW_DATA_GET(obj, sd);
704 EAPI Elm_Object_Item *
705 elm_slideshow_item_current_get(const Evas_Object *obj)
707 ELM_SLIDESHOW_CHECK(obj) NULL;
708 ELM_SLIDESHOW_DATA_GET(obj, sd);
710 return (Elm_Object_Item *)sd->current;
714 elm_slideshow_item_object_get(const Elm_Object_Item *it)
716 ELM_SLIDESHOW_ITEM_CHECK_OR_RETURN(it, NULL);
721 elm_slideshow_cache_before_get(const Evas_Object *obj)
723 ELM_SLIDESHOW_CHECK(obj) - 1;
724 ELM_SLIDESHOW_DATA_GET(obj, sd);
726 return sd->count_item_pre_before;
730 elm_slideshow_cache_before_set(Evas_Object *obj, int count)
732 ELM_SLIDESHOW_CHECK(obj);
733 ELM_SLIDESHOW_DATA_GET(obj, sd);
735 if (count < 0) count = 0;
736 sd->count_item_pre_before = count;
740 elm_slideshow_cache_after_get(const Evas_Object *obj)
742 ELM_SLIDESHOW_CHECK(obj) - 1;
743 ELM_SLIDESHOW_DATA_GET(obj, sd);
745 return sd->count_item_pre_after;
749 elm_slideshow_cache_after_set(Evas_Object *obj,
752 ELM_SLIDESHOW_CHECK(obj);
753 ELM_SLIDESHOW_DATA_GET(obj, sd);
755 if (count < 0) count = 0;
756 sd->count_item_pre_after = count;
759 EAPI Elm_Object_Item *
760 elm_slideshow_item_nth_get(const Evas_Object *obj,
763 ELM_SLIDESHOW_CHECK(obj) NULL;
764 ELM_SLIDESHOW_DATA_GET(obj, sd);
766 return eina_list_nth(sd->items, nth);
770 elm_slideshow_count_get(const Evas_Object *obj)
772 ELM_SLIDESHOW_CHECK(obj) 0;
773 ELM_SLIDESHOW_DATA_GET(obj, sd);
775 return eina_list_count(sd->items);