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 if (elm_widget_disabled_get(obj)) return EINA_FALSE;
30 if (type != EVAS_CALLBACK_KEY_DOWN) return EINA_FALSE;
31 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return EINA_FALSE;
33 ELM_SLIDESHOW_DATA_GET(obj, sd);
35 if ((!strcmp(ev->keyname, "Left")) ||
36 ((!strcmp(ev->keyname, "KP_Left")) && (!ev->string)))
38 elm_slideshow_previous(obj);
39 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
44 if ((!strcmp(ev->keyname, "Right")) ||
45 ((!strcmp(ev->keyname, "KP_Right")) && (!ev->string)))
47 elm_slideshow_next(obj);
48 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
53 if ((!strcmp(ev->keyname, "Return")) ||
54 (!strcmp(ev->keyname, "KP_Enter")) ||
55 (!strcmp(ev->keyname, "space")))
61 ecore_timer_del(sd->timer);
65 elm_slideshow_timeout_set(obj, sd->timeout);
67 ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
76 _elm_slideshow_smart_sizing_eval(Evas_Object *obj)
78 ELM_SLIDESHOW_DATA_GET(obj, sd);
79 Evas_Coord minw = -1, minh = -1;
81 edje_object_size_min_calc(ELM_WIDGET_DATA(sd)->resize_obj, &minw, &minh);
82 evas_object_size_hint_min_set(obj, minw, minh);
83 evas_object_size_hint_max_set(obj, minw, minh);
86 static Elm_Slideshow_Item *
87 _item_prev_get(Elm_Slideshow_Item *item)
89 ELM_SLIDESHOW_DATA_GET(WIDGET(item), sd);
90 Elm_Slideshow_Item *prev = eina_list_data_get(eina_list_prev(item->l));
92 if ((!prev) && (sd->loop))
93 prev = eina_list_data_get(eina_list_last(item->l));
98 static Elm_Slideshow_Item *
99 _item_next_get(Elm_Slideshow_Item *item)
101 ELM_SLIDESHOW_DATA_GET(WIDGET(item), sd);
102 Elm_Slideshow_Item *next = eina_list_data_get(eina_list_next(item->l));
104 if ((!next) && (sd->loop))
105 next = eina_list_data_get(sd->items);
111 _on_size_hints_changed(void *data,
113 Evas_Object *obj __UNUSED__,
114 void *event_info __UNUSED__)
116 elm_layout_sizing_eval(data);
120 _item_realize(Elm_Slideshow_Item *item)
122 Elm_Slideshow_Item *_item_prev, *_item_next;
123 Evas_Object *obj = WIDGET(item);
124 int ac, bc, lc, ic = 0;
126 ELM_SLIDESHOW_DATA_GET_OR_RETURN(obj, sd);
128 if ((!VIEW(item)) && (item->itc->func.get))
130 VIEW(item) = item->itc->func.get(elm_widget_item_data_get(item), obj);
131 item->l_built = eina_list_append(NULL, item);
132 sd->items_built = eina_list_merge(sd->items_built, item->l_built);
133 //FIXME: item could be shown by obj
134 evas_object_hide(VIEW(item));
136 else if (item->l_built)
137 sd->items_built = eina_list_demote_list(sd->items_built, item->l_built);
139 //pre-create previous and next item
140 ac = sd->count_item_pre_after;
142 bc = sd->count_item_pre_before;
144 lc = eina_list_count(sd->items) - 1;
146 while (lc > 0 && ((ac > 0) || (bc > 0)))
148 if (lc > 0 && ac > 0)
154 _item_next = _item_next_get(_item_next);
156 && (!VIEW(_item_next))
157 && (_item_next->itc->func.get))
161 _item_next->itc->func.get(
162 elm_widget_item_data_get(_item_next), obj);
163 _item_next->l_built =
164 eina_list_append(NULL, _item_next);
165 sd->items_built = eina_list_merge
166 (sd->items_built, _item_next->l_built);
167 //FIXME: _item_next could be shown by obj later
168 evas_object_hide(VIEW(_item_next));
170 else if (_item_next && _item_next->l_built)
174 eina_list_demote_list
175 (sd->items_built, _item_next->l_built);
180 if (lc > 0 && bc > 0)
186 _item_prev = _item_prev_get(_item_prev);
188 && (!VIEW(_item_prev))
189 && (_item_prev->itc->func.get))
193 _item_prev->itc->func.get(
194 elm_widget_item_data_get(_item_prev), obj);
195 _item_prev->l_built =
196 eina_list_append(NULL, _item_prev);
197 sd->items_built = eina_list_merge
198 (sd->items_built, _item_prev->l_built);
199 //FIXME: _item_prev could be shown by obj later
200 evas_object_hide(VIEW(_item_prev));
202 else if (_item_prev && _item_prev->l_built)
206 eina_list_demote_list
207 (sd->items_built, _item_prev->l_built);
213 //delete unused items
216 while ((int)eina_list_count(sd->items_built) > lc)
218 item = eina_list_data_get(sd->items_built);
219 sd->items_built = eina_list_remove_list
220 (sd->items_built, sd->items_built);
221 if (item->itc->func.del)
222 item->itc->func.del(elm_widget_item_data_get(item), VIEW(item));
223 evas_object_del(VIEW(item));
229 _on_slideshow_end(void *data,
230 Evas_Object *obj __UNUSED__,
231 const char *emission,
232 const char *source __UNUSED__)
234 Elm_Slideshow_Item *item;
235 ELM_SLIDESHOW_DATA_GET(data, sd);
240 elm_layout_content_unset(data, "elm.swallow.1");
241 evas_object_hide(VIEW(item));
246 if ((!item) || (!VIEW(item))) return;
249 elm_layout_content_unset(data, "elm.swallow.2");
251 elm_layout_content_set(data, "elm.swallow.1", VIEW(item));
252 elm_layout_signal_emit(data, "anim,end", "slideshow");
254 if (emission != NULL)
255 evas_object_smart_callback_call(data, SIG_TRANSITION_END, sd->current);
259 _timer_cb(void *data)
261 Evas_Object *obj = data;
262 ELM_SLIDESHOW_DATA_GET(obj, sd);
265 elm_slideshow_next(obj);
267 return ECORE_CALLBACK_CANCEL;
271 _item_del_pre_hook(Elm_Object_Item *it)
273 Elm_Slideshow_Item *item = (Elm_Slideshow_Item *)it;
274 ELM_SLIDESHOW_DATA_GET_OR_RETURN_VAL(WIDGET(item), sd, EINA_FALSE);
276 if (sd->previous == item) sd->previous = NULL;
277 if (sd->current == item)
279 Eina_List *l = eina_list_data_find_list(sd->items, item);
280 Eina_List *l2 = eina_list_next(l);
284 l2 = eina_list_prev(l);
286 elm_slideshow_item_show(eina_list_data_get(l2));
289 elm_slideshow_item_show(eina_list_data_get(l2));
292 sd->items = eina_list_remove_list(sd->items, item->l);
293 sd->items_built = eina_list_remove_list(sd->items_built, item->l_built);
295 if ((VIEW(item)) && (item->itc->func.del))
296 item->itc->func.del(elm_widget_item_data_get(item), VIEW(item));
302 _elm_slideshow_smart_add(Evas_Object *obj)
304 EVAS_SMART_DATA_ALLOC(obj, Elm_Slideshow_Smart_Data);
306 ELM_WIDGET_CLASS(_elm_slideshow_parent_sc)->base.add(obj);
308 priv->current = NULL;
309 priv->previous = NULL;
311 priv->count_item_pre_before = 2;
312 priv->count_item_pre_after = 2;
314 elm_layout_theme_set(obj, "slideshow", "base", elm_widget_style_get(obj));
316 priv->transitions = elm_widget_stringlist_get
317 (edje_object_data_get(ELM_WIDGET_DATA(priv)->resize_obj,
319 if (eina_list_count(priv->transitions) > 0)
321 eina_stringshare_add(eina_list_data_get(priv->transitions));
323 priv->layout.list = elm_widget_stringlist_get
324 (edje_object_data_get(ELM_WIDGET_DATA(priv)->resize_obj, "layouts"));
326 if (eina_list_count(priv->layout.list) > 0)
327 priv->layout.current = eina_list_data_get(priv->layout.list);
329 edje_object_signal_callback_add
330 (ELM_WIDGET_DATA(priv)->resize_obj, "end", "slideshow", _on_slideshow_end,
333 evas_object_event_callback_add
334 (obj, EVAS_CALLBACK_CHANGED_SIZE_HINTS, _on_size_hints_changed, obj);
336 elm_widget_can_focus_set(obj, EINA_TRUE);
338 elm_layout_sizing_eval(obj);
342 _elm_slideshow_smart_del(Evas_Object *obj)
344 ELM_SLIDESHOW_DATA_GET(obj, sd);
347 elm_slideshow_clear(obj);
348 elm_widget_stringlist_free(sd->transitions);
349 if (sd->timer) ecore_timer_del(sd->timer);
351 EINA_LIST_FREE (sd->layout.list, layout)
352 eina_stringshare_del(layout);
354 ELM_WIDGET_CLASS(_elm_slideshow_parent_sc)->base.del(obj);
358 _elm_slideshow_smart_set_user(Elm_Slideshow_Smart_Class *sc)
360 ELM_WIDGET_CLASS(sc)->base.add = _elm_slideshow_smart_add;
361 ELM_WIDGET_CLASS(sc)->base.del = _elm_slideshow_smart_del;
363 ELM_WIDGET_CLASS(sc)->event = _elm_slideshow_smart_event;
365 /* not a 'focus chain manager' */
366 ELM_WIDGET_CLASS(sc)->focus_next = NULL;
367 ELM_WIDGET_CLASS(sc)->focus_direction = NULL;
369 ELM_LAYOUT_CLASS(sc)->sizing_eval = _elm_slideshow_smart_sizing_eval;
372 EAPI const Elm_Slideshow_Smart_Class *
373 elm_slideshow_smart_class_get(void)
375 static Elm_Slideshow_Smart_Class _sc =
376 ELM_SLIDESHOW_SMART_CLASS_INIT_NAME_VERSION(ELM_SLIDESHOW_SMART_NAME);
377 static const Elm_Slideshow_Smart_Class *class = NULL;
378 Evas_Smart_Class *esc = (Evas_Smart_Class *)&_sc;
383 _elm_slideshow_smart_set(&_sc);
384 esc->callbacks = _smart_callbacks;
391 elm_slideshow_add(Evas_Object *parent)
395 EINA_SAFETY_ON_NULL_RETURN_VAL(parent, NULL);
397 obj = elm_widget_add(_elm_slideshow_smart_class_new(), parent);
398 if (!obj) return NULL;
400 if (!elm_widget_sub_object_add(parent, obj))
401 ERR("could not add %p as sub object of %p", obj, parent);
406 EAPI Elm_Object_Item *
407 elm_slideshow_item_add(Evas_Object *obj,
408 const Elm_Slideshow_Item_Class *itc,
411 Elm_Slideshow_Item *item;
413 ELM_SLIDESHOW_CHECK(obj) NULL;
414 ELM_SLIDESHOW_DATA_GET(obj, sd);
416 item = elm_widget_item_new(obj, Elm_Slideshow_Item);
417 if (!item) return NULL;
419 elm_widget_item_del_pre_hook_set(item, _item_del_pre_hook);
421 item->l = eina_list_append(item->l, item);
422 elm_widget_item_data_set(item, data);
424 sd->items = eina_list_merge(sd->items, item->l);
426 if (!sd->current) elm_slideshow_item_show((Elm_Object_Item *)item);
428 return (Elm_Object_Item *)item;
431 EAPI Elm_Object_Item *
432 elm_slideshow_item_sorted_insert(Evas_Object *obj,
433 const Elm_Slideshow_Item_Class *itc,
435 Eina_Compare_Cb func)
437 Elm_Slideshow_Item *item;
439 ELM_SLIDESHOW_CHECK(obj) NULL;
440 ELM_SLIDESHOW_DATA_GET(obj, sd);
442 item = elm_widget_item_new(obj, Elm_Slideshow_Item);
443 if (!item) return NULL;
445 elm_widget_item_del_pre_hook_set(item, _item_del_pre_hook);
447 item->l = eina_list_append(item->l, item);
448 elm_widget_item_data_set(item, data);
450 sd->items = eina_list_sorted_merge(sd->items, item->l, func);
452 if (!sd->current) elm_slideshow_item_show((Elm_Object_Item *)item);
454 return (Elm_Object_Item *)item;
458 elm_slideshow_item_show(Elm_Object_Item *it)
461 Elm_Slideshow_Item *item, *next = NULL;
463 ELM_SLIDESHOW_ITEM_CHECK(it);
465 item = (Elm_Slideshow_Item *)it;
466 ELM_SLIDESHOW_DATA_GET(WIDGET(item), sd);
468 if (item == sd->current) return;
471 _on_slideshow_end(WIDGET(item), WIDGET(item), NULL, NULL);
473 if (sd->timer) ecore_timer_del(sd->timer);
475 if (sd->timeout > 0.0)
476 sd->timer = ecore_timer_add(sd->timeout, _timer_cb, WIDGET(item));
479 elm_layout_content_set(WIDGET(item), "elm.swallow.2", VIEW(next));
482 sprintf(buf,"none,next");
484 snprintf(buf, sizeof(buf), "%s,next", sd->transition);
485 elm_layout_signal_emit(WIDGET(item), buf, "slideshow");
487 sd->previous = sd->current;
489 evas_object_smart_callback_call(WIDGET(item), SIG_CHANGED, sd->current);
493 elm_slideshow_next(Evas_Object *obj)
496 Elm_Slideshow_Item *next = NULL;
498 ELM_SLIDESHOW_CHECK(obj);
499 ELM_SLIDESHOW_DATA_GET(obj, sd);
501 if (sd->current) next = _item_next_get(sd->current);
503 if ((!next) || (next == sd->current)) return;
505 _on_slideshow_end(obj, obj, NULL, NULL);
507 if (sd->timer) ecore_timer_del(sd->timer);
509 if (sd->timeout > 0.0)
510 sd->timer = ecore_timer_add(sd->timeout, _timer_cb, obj);
514 elm_layout_content_set(obj, "elm.swallow.2", VIEW(next));
517 sprintf(buf,"none,next");
519 snprintf(buf, sizeof(buf), "%s,next", sd->transition);
520 elm_layout_signal_emit(obj, buf, "slideshow");
522 sd->previous = sd->current;
524 evas_object_smart_callback_call(obj, SIG_CHANGED, sd->current);
528 elm_slideshow_previous(Evas_Object *obj)
531 Elm_Slideshow_Item *prev = NULL;
533 ELM_SLIDESHOW_CHECK(obj);
534 ELM_SLIDESHOW_DATA_GET(obj, sd);
536 if (sd->current) prev = _item_prev_get(sd->current);
538 if ((!prev) || (prev == sd->current)) return;
540 _on_slideshow_end(obj, obj, NULL, NULL);
542 if (sd->timer) ecore_timer_del(sd->timer);
544 if (sd->timeout > 0.0)
545 sd->timer = ecore_timer_add(sd->timeout, _timer_cb, obj);
549 elm_layout_content_set(obj, "elm.swallow.2", VIEW(prev));
552 sprintf(buf,"none,previous");
554 snprintf(buf, 1024, "%s,previous", sd->transition);
555 elm_layout_signal_emit(obj, buf, "slideshow");
557 sd->previous = sd->current;
559 evas_object_smart_callback_call(obj, SIG_CHANGED, sd->current);
562 EAPI const Eina_List *
563 elm_slideshow_transitions_get(const Evas_Object *obj)
565 ELM_SLIDESHOW_CHECK(obj) NULL;
566 ELM_SLIDESHOW_DATA_GET(obj, sd);
568 return sd->transitions;
571 EAPI const Eina_List *
572 elm_slideshow_layouts_get(const Evas_Object *obj)
574 ELM_SLIDESHOW_CHECK(obj) NULL;
575 ELM_SLIDESHOW_DATA_GET(obj, sd);
577 return sd->layout.list;
581 elm_slideshow_transition_set(Evas_Object *obj,
582 const char *transition)
584 ELM_SLIDESHOW_CHECK(obj);
585 ELM_SLIDESHOW_DATA_GET(obj, sd);
587 eina_stringshare_replace(&sd->transition, transition);
591 elm_slideshow_transition_get(const Evas_Object *obj)
593 ELM_SLIDESHOW_CHECK(obj) NULL;
594 ELM_SLIDESHOW_DATA_GET(obj, sd);
596 return sd->transition;
600 elm_slideshow_timeout_set(Evas_Object *obj,
603 ELM_SLIDESHOW_CHECK(obj);
604 ELM_SLIDESHOW_DATA_GET(obj, sd);
606 sd->timeout = timeout;
608 if (sd->timer) ecore_timer_del(sd->timer);
612 sd->timer = ecore_timer_add(timeout, _timer_cb, obj);
616 elm_slideshow_timeout_get(const Evas_Object *obj)
618 ELM_SLIDESHOW_CHECK(obj) - 1.0;
619 ELM_SLIDESHOW_DATA_GET(obj, sd);
625 elm_slideshow_loop_set(Evas_Object *obj,
628 ELM_SLIDESHOW_CHECK(obj);
629 ELM_SLIDESHOW_DATA_GET(obj, sd);
635 elm_slideshow_layout_get(const Evas_Object *obj)
637 ELM_SLIDESHOW_CHECK(obj) EINA_FALSE;
638 ELM_SLIDESHOW_DATA_GET(obj, sd);
640 return sd->layout.current;
644 elm_slideshow_layout_set(Evas_Object *obj,
649 ELM_SLIDESHOW_CHECK(obj);
650 ELM_SLIDESHOW_DATA_GET(obj, sd);
652 sd->layout.current = layout;
653 snprintf(buf, sizeof(buf), "layout,%s", layout);
654 elm_layout_signal_emit(obj, buf, "slideshow");
658 elm_slideshow_loop_get(const Evas_Object *obj)
660 ELM_SLIDESHOW_CHECK(obj) EINA_FALSE;
661 ELM_SLIDESHOW_DATA_GET(obj, sd);
667 elm_slideshow_clear(Evas_Object *obj)
669 Elm_Slideshow_Item *item;
671 ELM_SLIDESHOW_CHECK(obj);
672 ELM_SLIDESHOW_DATA_GET(obj, sd);
676 EINA_LIST_FREE (sd->items_built, item)
678 if (item->itc->func.del)
679 item->itc->func.del(elm_widget_item_data_get(item), VIEW(item));
682 EINA_LIST_FREE (sd->items, item)
683 elm_widget_item_free(item);
686 EAPI const Eina_List *
687 elm_slideshow_items_get(const Evas_Object *obj)
689 ELM_SLIDESHOW_CHECK(obj) NULL;
690 ELM_SLIDESHOW_DATA_GET(obj, sd);
695 EAPI Elm_Object_Item *
696 elm_slideshow_item_current_get(const Evas_Object *obj)
698 ELM_SLIDESHOW_CHECK(obj) NULL;
699 ELM_SLIDESHOW_DATA_GET(obj, sd);
701 return (Elm_Object_Item *)sd->current;
705 elm_slideshow_item_object_get(const Elm_Object_Item *it)
707 ELM_SLIDESHOW_ITEM_CHECK_OR_RETURN(it, NULL);
712 elm_slideshow_cache_before_get(const Evas_Object *obj)
714 ELM_SLIDESHOW_CHECK(obj) - 1;
715 ELM_SLIDESHOW_DATA_GET(obj, sd);
717 return sd->count_item_pre_before;
721 elm_slideshow_cache_before_set(Evas_Object *obj, int count)
723 ELM_SLIDESHOW_CHECK(obj);
724 ELM_SLIDESHOW_DATA_GET(obj, sd);
726 if (count < 0) count = 0;
727 sd->count_item_pre_before = count;
731 elm_slideshow_cache_after_get(const Evas_Object *obj)
733 ELM_SLIDESHOW_CHECK(obj) - 1;
734 ELM_SLIDESHOW_DATA_GET(obj, sd);
736 return sd->count_item_pre_after;
740 elm_slideshow_cache_after_set(Evas_Object *obj,
743 ELM_SLIDESHOW_CHECK(obj);
744 ELM_SLIDESHOW_DATA_GET(obj, sd);
746 if (count < 0) count = 0;
747 sd->count_item_pre_after = count;
750 EAPI Elm_Object_Item *
751 elm_slideshow_item_nth_get(const Evas_Object *obj,
754 ELM_SLIDESHOW_CHECK(obj) NULL;
755 ELM_SLIDESHOW_DATA_GET(obj, sd);
757 return eina_list_nth(sd->items, nth);
761 elm_slideshow_count_get(const Evas_Object *obj)
763 ELM_SLIDESHOW_CHECK(obj) 0;
764 ELM_SLIDESHOW_DATA_GET(obj, sd);
766 return eina_list_count(sd->items);