1 #include <Elementary.h>
4 typedef struct _Widget_Data Widget_Data;
5 typedef struct _Elm_Naviframe_Item Elm_Naviframe_Item;
6 typedef struct _Elm_Naviframe_Content_Item_Pair Elm_Naviframe_Content_Item_Pair;
7 typedef struct _Elm_Naviframe_Text_Item_Pair Elm_Naviframe_Text_Item_Pair;
13 Eina_Bool preserve: 1;
14 Eina_Bool auto_pushed: 1;
15 Eina_Bool freeze_events: 1;
18 struct _Elm_Naviframe_Content_Item_Pair
23 Elm_Naviframe_Item *it;
26 struct _Elm_Naviframe_Text_Item_Pair
33 struct _Elm_Naviframe_Item
37 Eina_Inlist *content_list;
38 Eina_Inlist *text_list;
40 Evas_Object *title_prev_btn;
41 Evas_Object *title_next_btn;
42 Evas_Object *title_icon;
46 Eina_Bool back_btn: 1;
47 Eina_Bool title_visible: 1;
50 static const char *widtype = NULL;
52 static const char SIG_TRANSITION_FINISHED[] = "transition,finished";
53 static const char SIG_PUSH_FINISHED[] = "push,finished";
54 static const char SIG_POP_FINISHED[] = "pop,finished";
55 static const char SIG_TITLE_CLICKED[] = "title,clicked";
57 static const Evas_Smart_Cb_Description _signals[] = {
58 {SIG_TRANSITION_FINISHED, ""},
59 {SIG_TITLE_CLICKED, ""},
63 static void _del_hook(Evas_Object *obj);
64 static void _theme_hook(Evas_Object *obj);
65 static void _emit_hook(Evas_Object *obj,
68 static void _disable_hook(Evas_Object *obj);
69 static void _mirrored_set(Evas_Object *obj, Eina_Bool rtl);
70 static void _item_text_set_hook(Elm_Object_Item *it,
73 static const char *_item_text_get_hook(const Elm_Object_Item *it,
75 static void _item_content_set_hook(Elm_Object_Item *it,
77 Evas_Object *content);
78 static Evas_Object *_item_content_get_hook(const Elm_Object_Item *it,
80 static Evas_Object *_item_content_unset_hook(Elm_Object_Item *it,
82 static void _item_signal_emit_hook(Elm_Object_Item *it,
85 static void _item_title_visible_update(Elm_Naviframe_Item *navi_it);
86 static void _sizing_eval(Evas_Object *obj);
87 static void _move(void *data, Evas *e, Evas_Object *obj, void *event_info);
88 static void _resize(void *data,
92 static void _title_clicked(void *data, Evas_Object *obj,
95 static void _back_btn_clicked(void *data,
98 static Evas_Object *_back_btn_new(Evas_Object *obj);
99 static void _item_content_del(void *data,
103 static void _title_content_del(void *data,
107 static void _title_prev_btn_del(void *data,
111 static void _title_next_btn_del(void *data,
115 static void _title_icon_del(void *data,
119 static void _title_content_set(Elm_Naviframe_Item *it,
121 Evas_Object *content);
122 static void _title_prev_btn_set(Elm_Naviframe_Item *it,
125 static void _title_next_btn_set(Elm_Naviframe_Item *it, Evas_Object *btn);
126 static void _title_icon_set(Elm_Naviframe_Item *it, Evas_Object *icon);
127 static Evas_Object * _item_content_unset(Elm_Naviframe_Item *it);
128 static Evas_Object * _title_prev_btn_unset(Elm_Naviframe_Item *it);
129 static Evas_Object * _title_next_btn_unset(Elm_Naviframe_Item *it);
130 static Evas_Object * _title_icon_unset(Elm_Naviframe_Item *it);
131 static Evas_Object * _title_content_unset(Elm_Naviframe_Item *it,
133 static void _item_del(Elm_Naviframe_Item *it);
134 static Eina_Bool _item_del_pre_hook(Elm_Object_Item *it);
135 static void _pushed_finished(void *data,
137 const char *emission,
139 static void _popped_finished(void *data,
141 const char *emission,
143 static void _show_finished(void *data,
145 const char *emission,
147 static void _changed_size_hints(void *data,
151 static void _item_content_set(Elm_Naviframe_Item *navi_it,
152 Evas_Object *content);
153 static void _item_style_set(Elm_Naviframe_Item *navi_it,
154 const char *item_style);
155 static Elm_Naviframe_Item * _item_new(Evas_Object *obj,
156 const char *title_label,
157 Evas_Object *prev_btn,
158 Evas_Object *next_btn,
159 Evas_Object *content,
160 const char *item_style);
163 _del_hook(Evas_Object *obj)
166 Elm_Naviframe_Item *it;
168 wd = elm_widget_data_get(obj);
173 while (wd->stack->last)
175 it = EINA_INLIST_CONTAINER_GET(wd->stack->last,
177 wd->stack = eina_inlist_remove(wd->stack, wd->stack->last);
179 if (!wd->stack) break;
186 _theme_hook(Evas_Object *obj)
189 Elm_Naviframe_Item *it;
191 wd = elm_widget_data_get(obj);
194 _elm_theme_object_set(obj,
198 elm_widget_style_get(obj));
200 EINA_INLIST_FOREACH(wd->stack, it)
202 _item_style_set(it, it->style);
203 _item_title_visible_update(it);
206 _elm_widget_mirrored_reload(obj);
207 _mirrored_set(obj, elm_widget_mirrored_get(obj));
210 static void _emit_hook(Evas_Object *obj,
211 const char *emission,
214 ELM_CHECK_WIDTYPE(obj, widtype);
216 Widget_Data *wd = elm_widget_data_get(obj);
219 edje_object_signal_emit(wd->base, emission, source);
223 _disable_hook(Evas_Object *obj __UNUSED__)
229 _mirrored_set(Evas_Object *obj, Eina_Bool rtl)
232 Elm_Naviframe_Item *it;
234 wd = elm_widget_data_get(obj);
237 EINA_INLIST_FOREACH(wd->stack, it)
238 edje_object_mirrored_set(VIEW(it), rtl);
239 edje_object_mirrored_set(wd->base, rtl);
243 _item_text_set_hook(Elm_Object_Item *it,
247 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
249 Elm_Naviframe_Text_Item_Pair *pair = NULL;
250 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
253 if (!part || !strcmp(part, "default"))
254 snprintf(buf, sizeof(buf), "elm.text.title");
255 else if(!strcmp("subtitle", part))
256 snprintf(buf, sizeof(buf), "elm.text.subtitle");
258 snprintf(buf, sizeof(buf), "%s", part);
260 EINA_INLIST_FOREACH(navi_it->text_list, pair)
261 if (!strcmp(buf, pair->part)) break;
265 pair = ELM_NEW(Elm_Naviframe_Text_Item_Pair);
268 ERR("Failed to allocate new text part of the item! : naviframe=%p",
272 eina_stringshare_replace(&pair->part, buf);
273 navi_it->text_list = eina_inlist_append(navi_it->text_list,
274 EINA_INLIST_GET(pair));
277 eina_stringshare_replace(&pair->text, label);
278 edje_object_part_text_set(VIEW(navi_it), buf, label);
282 snprintf(buf, sizeof(buf), "elm,state,%s,show", buf);
283 edje_object_signal_emit(VIEW(navi_it), buf, "elm");
287 snprintf(buf, sizeof(buf), "elm,state,%s,hide", buf);
288 edje_object_signal_emit(VIEW(navi_it), buf, "elm");
291 _sizing_eval(WIDGET(navi_it));
295 _item_text_get_hook(const Elm_Object_Item *it, const char *part)
297 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
298 Elm_Naviframe_Text_Item_Pair *pair = NULL;
299 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
302 if (!part || !strcmp(part, "default"))
303 snprintf(buf, sizeof(buf), "elm.text.title");
304 else if(!strcmp("subtitle", part))
305 snprintf(buf, sizeof(buf), "elm.text.subtitle");
307 snprintf(buf, sizeof(buf), "%s", part);
309 EINA_INLIST_FOREACH(navi_it->text_list, pair)
311 if (!strcmp(buf, pair->part))
318 _item_content_set_hook(Elm_Object_Item *it,
320 Evas_Object *content)
322 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
324 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
327 if ((!part) || (!strcmp(part, "elm.swallow.content")))
329 _item_content_set(navi_it, content);
332 else if (!strcmp(part, "elm.swallow.prev_btn"))
334 _title_prev_btn_set(navi_it, content, EINA_FALSE);
337 else if (!strcmp(part, "elm.swallow.next_btn"))
339 _title_next_btn_set(navi_it, content);
342 else if (!strcmp(part, "icon"))
344 _title_icon_set(navi_it, content);
349 _title_content_set(navi_it, part, content);
353 _item_content_get_hook(const Elm_Object_Item *it, const char *part)
355 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
356 Elm_Naviframe_Content_Item_Pair *pair = NULL;
357 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
360 if ((!part) || (!strcmp(part, "elm.swallow.content")))
361 return navi_it->content;
362 else if (!strcmp(part, "elm.swallow.prev_btn"))
363 return navi_it->title_prev_btn;
364 else if (!strcmp(part, "elm.swallow.next_btn"))
365 return navi_it->title_next_btn;
366 else if (!strcmp(part, "icon"))
367 return navi_it->title_icon;
370 EINA_INLIST_FOREACH(navi_it->content_list, pair)
372 if (!strcmp(part, pair->part))
373 return pair->content;
379 _item_content_unset_hook(Elm_Object_Item *it, const char *part)
381 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
382 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
385 if (!part || !strcmp("elm.swallow.content", part))
386 return _item_content_unset(navi_it);
387 else if (!strcmp(part, "elm.swallow.prev_btn"))
388 return _title_prev_btn_unset(navi_it);
389 else if (!strcmp(part, "elm.swallow.next_btn"))
390 return _title_next_btn_unset(navi_it);
391 else if (!strcmp(part, "icon"))
392 return _title_icon_unset(navi_it);
394 return _title_content_unset(navi_it, part);
398 _item_signal_emit_hook(Elm_Object_Item *it,
399 const char *emission,
402 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
403 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
404 edje_object_signal_emit(VIEW(navi_it), emission, source);
408 _item_title_visible_update(Elm_Naviframe_Item *navi_it)
410 if (navi_it->title_visible)
411 edje_object_signal_emit(VIEW(navi_it), "elm,state,title,show", "elm");
413 edje_object_signal_emit(VIEW(navi_it), "elm,state,title,hide", "elm");
417 _sizing_eval(Evas_Object *obj)
420 Elm_Naviframe_Item *it;
421 Evas_Coord x, y, w, h;
422 Evas_Coord minw = -1, minh = -1;
424 wd = elm_widget_data_get(obj);
427 evas_object_geometry_get(obj, &x, &y, &w, &h);
429 EINA_INLIST_FOREACH(wd->stack, it)
431 evas_object_move(VIEW(it), x, y);
432 evas_object_resize(VIEW(it), w, h);
433 edje_object_size_min_calc(VIEW(it), &it->minw, &it->minh);
434 if (it->minw > minw) minw = it->minw;
435 if (it->minh > minh) minh = it->minh;
437 evas_object_size_hint_min_set(obj, minw, minh);
438 evas_object_size_hint_max_set(obj, -1, -1);
442 _move(void *data __UNUSED__,
445 void *event_info __UNUSED__)
451 _resize(void *data __UNUSED__,
454 void *event_info __UNUSED__)
460 _title_clicked(void *data,
461 Evas_Object *obj __UNUSED__,
462 const char *emission __UNUSED__,
463 const char *source __UNUSED__)
465 Elm_Naviframe_Item *it = data;
466 evas_object_smart_callback_call(WIDGET(it), SIG_TITLE_CLICKED, it);
470 _back_btn_clicked(void *data,
472 void *event_info __UNUSED__)
474 /* Since edje has the event queue, clicked event could be happend multiple times
475 on some heavy environment. This callback del will prevent those scenario and
476 guarantee only one clicked for it's own page. */
477 evas_object_smart_callback_del(obj, "clicked", _back_btn_clicked);
478 elm_naviframe_item_pop(data);
482 _back_btn_new(Evas_Object *obj)
486 btn = elm_button_add(obj);
487 if (!btn) return NULL;
488 evas_object_smart_callback_add(btn, "clicked", _back_btn_clicked, obj);
489 snprintf(buf, sizeof(buf), "naviframe/back_btn/%s", elm_widget_style_get(obj));
490 elm_object_style_set(btn, buf);
495 _title_content_del(void *data,
497 Evas_Object *obj __UNUSED__,
498 void *event_info __UNUSED__)
501 Elm_Naviframe_Content_Item_Pair *pair = data;
502 Elm_Naviframe_Item *it = pair->it;
503 snprintf(buf, sizeof(buf), "elm,state,%s,hide", pair->part);
504 edje_object_signal_emit(VIEW(it), buf, "elm");
505 it->content_list = eina_inlist_remove(it->content_list,
506 EINA_INLIST_GET(pair));
507 eina_stringshare_del(pair->part);
512 _title_prev_btn_del(void *data,
514 Evas_Object *obj __UNUSED__,
515 void *event_info __UNUSED__)
517 Elm_Naviframe_Item *it = data;
518 it->back_btn = EINA_FALSE;
519 it->title_prev_btn = NULL;
520 edje_object_signal_emit(VIEW(it), "elm,state,prev_btn,hide", "elm");
524 _title_next_btn_del(void *data,
526 Evas_Object *obj __UNUSED__,
527 void *event_info __UNUSED__)
529 Elm_Naviframe_Item *it = data;
530 it->title_next_btn = NULL;
531 edje_object_signal_emit(VIEW(it), "elm,state,next_btn,hide", "elm");
535 _title_icon_del(void *data,
537 Evas_Object *obj __UNUSED__,
538 void *event_info __UNUSED__)
540 Elm_Naviframe_Item *it = data;
541 it->title_icon = NULL;
542 edje_object_signal_emit(VIEW(it), "elm,state,icon,hide", "elm");
546 _item_content_del(void *data,
548 Evas_Object *obj __UNUSED__,
549 void *event_info __UNUSED__)
551 Elm_Naviframe_Item *it = data;
553 edje_object_signal_emit(VIEW(it), "elm,state,content,hide", "elm");
557 _title_content_set(Elm_Naviframe_Item *it,
559 Evas_Object *content)
562 Elm_Naviframe_Content_Item_Pair *pair = NULL;
564 EINA_INLIST_FOREACH(it->content_list, pair)
565 if (!strcmp(part, pair->part)) break;
569 if (pair->content != content)
573 evas_object_event_callback_del(pair->content,
576 evas_object_event_callback_del(pair->content,
577 EVAS_CALLBACK_CHANGED_SIZE_HINTS,
578 _changed_size_hints);
579 snprintf(buf, sizeof(buf), "elm,state,%s,hide", part);
580 edje_object_signal_emit(VIEW(it), buf, "elm");
582 evas_object_del(pair->content);
583 if (!content) return;
588 if (!content) return;
589 pair = ELM_NEW(Elm_Naviframe_Content_Item_Pair);
592 ERR("Failed to allocate new content part of the item! : naviframe=%p", WIDGET(it));
596 eina_stringshare_replace(&pair->part, part);
597 it->content_list = eina_inlist_append(it->content_list,
598 EINA_INLIST_GET(pair));
600 if (pair->content != content)
602 elm_widget_sub_object_add(WIDGET(it), content);
603 evas_object_event_callback_add(content,
607 evas_object_event_callback_add(content,
608 EVAS_CALLBACK_CHANGED_SIZE_HINTS,
612 edje_object_part_swallow(VIEW(it), part, content);
613 snprintf(buf, sizeof(buf), "elm,state,%s,show", part);
614 edje_object_signal_emit(VIEW(it), buf, "elm");
615 pair->content = content;
617 _sizing_eval(WIDGET(it));
621 _title_prev_btn_set(Elm_Naviframe_Item *it,
625 if (it->title_prev_btn == btn) return;
627 if (it->title_prev_btn)
628 evas_object_del(it->title_prev_btn);
630 it->title_prev_btn = btn;
633 elm_widget_sub_object_add(WIDGET(it), btn);
634 evas_object_event_callback_add(btn,
638 evas_object_event_callback_add(btn,
639 EVAS_CALLBACK_CHANGED_SIZE_HINTS,
642 edje_object_part_swallow(VIEW(it), "elm.swallow.prev_btn", btn);
643 edje_object_signal_emit(VIEW(it), "elm,state,prev_btn,show", "elm");
644 it->back_btn = back_btn;
646 _sizing_eval(WIDGET(it));
650 _title_next_btn_set(Elm_Naviframe_Item *it, Evas_Object *btn)
652 if (it->title_next_btn == btn) return;
654 if (it->title_next_btn)
655 evas_object_del(it->title_next_btn);
657 it->title_next_btn = btn;
660 elm_widget_sub_object_add(WIDGET(it), btn);
661 evas_object_event_callback_add(btn,
665 evas_object_event_callback_add(btn,
666 EVAS_CALLBACK_CHANGED_SIZE_HINTS,
669 edje_object_part_swallow(VIEW(it), "elm.swallow.next_btn", btn);
670 edje_object_signal_emit(VIEW(it), "elm,state,next_btn,show", "elm");
672 _sizing_eval(WIDGET(it));
676 _title_icon_set(Elm_Naviframe_Item *it, Evas_Object *icon)
678 if (it->title_icon == icon) return;
681 evas_object_del(it->title_icon);
683 it->title_icon = icon;
686 elm_widget_sub_object_add(WIDGET(it), icon);
687 evas_object_event_callback_add(icon,
691 evas_object_event_callback_add(icon,
692 EVAS_CALLBACK_CHANGED_SIZE_HINTS,
695 edje_object_part_swallow(VIEW(it), "elm.swallow.icon", icon);
696 edje_object_signal_emit(VIEW(it), "elm,state,icon,show", "elm");
698 _sizing_eval(WIDGET(it));
702 _item_content_unset(Elm_Naviframe_Item *it)
704 Evas_Object *content = it->content;
705 if (!content) return NULL;
707 elm_widget_sub_object_del(WIDGET(it), content);
708 edje_object_part_unswallow(VIEW(it), content);
709 edje_object_signal_emit(VIEW(it), "elm,state,content,hide", "elm");
710 evas_object_event_callback_del(content,
713 evas_object_event_callback_del(content,
714 EVAS_CALLBACK_CHANGED_SIZE_HINTS,
715 _changed_size_hints);
716 _sizing_eval(WIDGET(it));
723 _title_prev_btn_unset(Elm_Naviframe_Item *it)
725 Evas_Object *content = it->title_prev_btn;
726 if (!content) return NULL;
728 elm_widget_sub_object_del(WIDGET(it), content);
729 edje_object_part_unswallow(VIEW(it), content);
730 edje_object_signal_emit(VIEW(it), "elm,state,prev_btn,hide", "elm");
731 evas_object_event_callback_del(content,
733 _title_prev_btn_del);
734 evas_object_event_callback_del(content,
735 EVAS_CALLBACK_CHANGED_SIZE_HINTS,
736 _changed_size_hints);
737 _sizing_eval(WIDGET(it));
739 it->title_prev_btn = NULL;
744 _title_next_btn_unset(Elm_Naviframe_Item *it)
746 Evas_Object *content = it->title_next_btn;
747 if (!content) return NULL;
749 elm_widget_sub_object_del(WIDGET(it), content);
750 edje_object_part_unswallow(VIEW(it), content);
751 edje_object_signal_emit(VIEW(it), "elm,state,next_btn,hide", "elm");
752 evas_object_event_callback_del(content,
754 _title_next_btn_del);
755 evas_object_event_callback_del(content,
756 EVAS_CALLBACK_CHANGED_SIZE_HINTS,
757 _changed_size_hints);
758 _sizing_eval(WIDGET(it));
760 it->title_next_btn = NULL;
765 _title_icon_unset(Elm_Naviframe_Item *it)
767 Evas_Object *content = it->title_icon;
768 if (!content) return NULL;
770 elm_widget_sub_object_del(WIDGET(it), content);
771 edje_object_part_unswallow(VIEW(it), content);
772 edje_object_signal_emit(VIEW(it), "elm,state,icon,hide", "elm");
773 evas_object_event_callback_del(content,
776 evas_object_event_callback_del(content,
777 EVAS_CALLBACK_CHANGED_SIZE_HINTS,
778 _changed_size_hints);
779 _sizing_eval(WIDGET(it));
780 it->title_icon = NULL;
786 _title_content_unset(Elm_Naviframe_Item *it, const char *part)
788 Elm_Naviframe_Content_Item_Pair *pair = NULL;
790 Evas_Object *content = NULL;
792 EINA_INLIST_FOREACH(it->content_list, pair)
794 if (!strcmp(part, pair->part))
796 content = pair->content;
797 eina_stringshare_del(pair->part);
798 it->content_list = eina_inlist_remove(it->content_list,
799 EINA_INLIST_GET(pair));
805 if (!content) return NULL;
807 elm_widget_sub_object_del(WIDGET(it), content);
808 edje_object_part_unswallow(VIEW(it), content);
809 snprintf(buf, sizeof(buf), "elm,state,%s,hide", part);
810 edje_object_signal_emit(VIEW(it), buf, "elm");
811 evas_object_event_callback_del(content,
814 evas_object_event_callback_del(content,
815 EVAS_CALLBACK_CHANGED_SIZE_HINTS,
816 _changed_size_hints);
817 _sizing_eval(WIDGET(it));
823 _item_del(Elm_Naviframe_Item *it)
826 Elm_Naviframe_Content_Item_Pair *content_pair;
827 Elm_Naviframe_Text_Item_Pair *text_pair;
831 wd = elm_widget_data_get(WIDGET(it));
834 if (it->title_prev_btn)
835 evas_object_del(it->title_prev_btn);
836 if (it->title_next_btn)
837 evas_object_del(it->title_next_btn);
839 evas_object_del(it->title_icon);
840 if ((it->content) && (!wd->preserve))
841 evas_object_del(it->content);
843 while (it->content_list)
845 content_pair = EINA_INLIST_CONTAINER_GET(it->content_list,
846 Elm_Naviframe_Content_Item_Pair);
847 evas_object_event_callback_del(content_pair->content,
850 evas_object_event_callback_del(content_pair->content,
851 EVAS_CALLBACK_CHANGED_SIZE_HINTS,
852 _changed_size_hints);
853 evas_object_del(content_pair->content);
854 eina_stringshare_del(content_pair->part);
855 it->content_list = eina_inlist_remove(it->content_list,
860 while (it->text_list)
862 text_pair = EINA_INLIST_CONTAINER_GET(it->text_list,
863 Elm_Naviframe_Text_Item_Pair);
864 eina_stringshare_del(text_pair->part);
865 eina_stringshare_del(text_pair->text);
866 it->text_list = eina_inlist_remove(it->text_list,
871 eina_stringshare_del(it->style);
875 _item_del_pre_hook(Elm_Object_Item *it)
877 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
878 Elm_Naviframe_Item *navi_it;
881 navi_it =(Elm_Naviframe_Item *) it;
882 wd = elm_widget_data_get(WIDGET(navi_it));
883 if (!wd) return EINA_FALSE;
885 if (it == elm_naviframe_top_item_get(WIDGET(navi_it)))
887 wd->stack = eina_inlist_remove(wd->stack, EINA_INLIST_GET(navi_it));
889 elm_widget_item_free(navi_it);
890 //If the item is only one, the stack will be empty
891 if (!wd->stack) return EINA_TRUE;
892 navi_it = EINA_INLIST_CONTAINER_GET(wd->stack->last,
894 evas_object_show(VIEW(navi_it));
895 evas_object_raise(VIEW(navi_it));
896 elm_object_signal_emit(VIEW(navi_it), "elm,state,visible", "elm");
900 wd->stack = eina_inlist_remove(wd->stack, EINA_INLIST_GET(navi_it));
902 elm_widget_item_free(navi_it);
909 _pushed_finished(void *data,
910 Evas_Object *obj __UNUSED__,
911 const char *emission __UNUSED__,
912 const char *source __UNUSED__)
915 Elm_Naviframe_Item *it = data;
918 wd = elm_widget_data_get(WIDGET(it));
921 evas_object_hide(VIEW(it));
922 evas_object_smart_callback_call(WIDGET(it),
925 if (wd->freeze_events)
926 evas_object_freeze_events_set(VIEW(it), EINA_FALSE);
930 _popped_finished(void *data,
931 Evas_Object *obj __UNUSED__,
932 const char *emission __UNUSED__,
933 const char *source __UNUSED__)
935 Elm_Naviframe_Item *it = data;
937 evas_object_smart_callback_call(WIDGET(it),
944 _show_finished(void *data,
945 Evas_Object *obj __UNUSED__,
946 const char *emission __UNUSED__,
947 const char *source __UNUSED__)
949 Elm_Naviframe_Item *it;
954 wd = elm_widget_data_get(WIDGET(it));
957 evas_object_smart_callback_call(WIDGET(it),
958 SIG_TRANSITION_FINISHED,
960 if (wd->freeze_events)
961 evas_object_freeze_events_set(VIEW(it), EINA_FALSE);
965 _changed_size_hints(void *data,
967 Evas_Object *obj __UNUSED__,
968 void *event_info __UNUSED__)
974 _item_content_set(Elm_Naviframe_Item *navi_it, Evas_Object *content)
976 if (navi_it->content == content) return;
977 if (navi_it->content) evas_object_del(navi_it->content);
978 elm_widget_sub_object_add(WIDGET(navi_it), content);
979 edje_object_part_swallow(VIEW(navi_it),
980 "elm.swallow.content",
983 edje_object_signal_emit(VIEW(navi_it),
984 "elm,state,content,show",
987 edje_object_signal_emit(VIEW(navi_it),
988 "elm,state,content,hide",
990 evas_object_event_callback_add(content,
994 evas_object_event_callback_add(content,
995 EVAS_CALLBACK_CHANGED_SIZE_HINTS,
998 navi_it->content = content;
999 _sizing_eval(WIDGET(navi_it));
1002 //FIXME: need to handle if this function is called while transition
1004 _item_style_set(Elm_Naviframe_Item *navi_it, const char *item_style)
1006 Elm_Naviframe_Content_Item_Pair *content_pair;
1007 Elm_Naviframe_Text_Item_Pair *text_pair;
1014 strcpy(buf, "item/basic");
1015 eina_stringshare_replace(&navi_it->style, "basic");
1019 snprintf(buf, sizeof(buf), "item/%s", item_style);
1020 eina_stringshare_replace(&navi_it->style, item_style);
1022 _elm_theme_object_set(WIDGET(navi_it),
1026 elm_widget_style_get(WIDGET(navi_it)));
1028 EINA_INLIST_FOREACH(navi_it->text_list, text_pair)
1029 _item_text_set_hook((Elm_Object_Item *) navi_it,
1033 EINA_INLIST_FOREACH(navi_it->content_list, content_pair)
1034 _item_content_set_hook((Elm_Object_Item *) navi_it,
1036 content_pair->content);
1038 if (navi_it->content)
1040 edje_object_part_swallow(VIEW(navi_it),
1041 "elm.swallow.content",
1043 edje_object_signal_emit(VIEW(navi_it),
1044 "elm,state,content,show",
1049 if (navi_it->title_prev_btn)
1051 edje_object_part_swallow(VIEW(navi_it),
1052 "elm.swallow.prev_btn",
1053 navi_it->title_prev_btn);
1054 edje_object_signal_emit(VIEW(navi_it),
1055 "elm,state,prev_btn,show",
1060 if (navi_it->title_next_btn)
1062 edje_object_part_swallow(VIEW(navi_it),
1063 "elm.swallow.next_btn",
1064 navi_it->title_next_btn);
1065 edje_object_signal_emit(VIEW(navi_it),
1066 "elm,state,next_btn,show",
1070 navi_it->title_visible = EINA_TRUE;
1071 _sizing_eval(WIDGET(navi_it));
1073 wd = elm_widget_data_get(WIDGET(navi_it));
1076 if (wd->freeze_events)
1077 evas_object_freeze_events_set(VIEW(navi_it), EINA_FALSE);
1080 static Elm_Naviframe_Item *
1081 _item_new(Evas_Object *obj,
1082 const char *title_label,
1083 Evas_Object *prev_btn,
1084 Evas_Object *next_btn,
1085 Evas_Object *content,
1086 const char *item_style)
1088 Widget_Data *wd = elm_widget_data_get(obj);
1091 Elm_Naviframe_Item *it = elm_widget_item_new(obj, Elm_Naviframe_Item);
1094 ERR("Failed to allocate new item! : naviframe=%p", obj);
1098 elm_widget_item_text_set_hook_set(it, _item_text_set_hook);
1099 elm_widget_item_text_get_hook_set(it, _item_text_get_hook);
1100 elm_widget_item_content_set_hook_set(it, _item_content_set_hook);
1101 elm_widget_item_content_get_hook_set(it, _item_content_get_hook);
1102 elm_widget_item_content_unset_hook_set(it, _item_content_unset_hook);
1103 elm_widget_item_signal_emit_hook_set(it, _item_signal_emit_hook);
1106 VIEW(it) = edje_object_add(evas_object_evas_get(obj));
1107 edje_object_mirrored_set(VIEW(it), elm_widget_mirrored_get(obj));
1108 evas_object_smart_member_add(VIEW(it), wd->base);
1109 elm_widget_sub_object_add(obj, VIEW(it));
1110 edje_object_signal_callback_add(VIEW(it),
1111 "elm,action,show,finished",
1113 _show_finished, it);
1114 edje_object_signal_callback_add(VIEW(it),
1115 "elm,action,pushed,finished",
1117 _pushed_finished, it);
1118 edje_object_signal_callback_add(VIEW(it),
1119 "elm,action,popped,finished",
1121 _popped_finished, it);
1122 edje_object_signal_callback_add(VIEW(it),
1123 "elm,action,title,clicked",
1125 _title_clicked, it);
1127 _item_style_set(it, item_style);
1128 _item_text_set_hook((Elm_Object_Item *) it, "elm.text.title", title_label);
1131 if ((!prev_btn) && wd->auto_pushed && eina_inlist_count(wd->stack))
1133 prev_btn = _back_btn_new(obj);
1134 _title_prev_btn_set(it, prev_btn, EINA_TRUE);
1137 _title_prev_btn_set(it, prev_btn, EINA_FALSE);
1139 _title_next_btn_set(it, next_btn);
1140 _item_content_set(it, content);
1141 it->title_visible = EINA_TRUE;
1146 elm_naviframe_add(Evas_Object *parent)
1152 ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL);
1153 ELM_SET_WIDTYPE(widtype, "naviframe");
1154 elm_widget_type_set(obj, "naviframe");
1155 elm_widget_sub_object_add(parent, obj);
1156 elm_widget_data_set(obj, wd);
1157 elm_widget_del_hook_set(obj, _del_hook);
1158 elm_widget_disable_hook_set(obj, _disable_hook);
1159 elm_widget_theme_hook_set(obj, _theme_hook);
1160 elm_widget_signal_emit_hook_set(obj, _emit_hook);
1163 wd->base = edje_object_add(e);
1164 edje_object_mirrored_set(wd->base, elm_widget_mirrored_get(obj));
1165 elm_widget_resize_object_set(obj, wd->base);
1166 _elm_theme_object_set(obj, wd->base, "naviframe", "base", "default");
1168 evas_object_event_callback_add(obj, EVAS_CALLBACK_MOVE, _move, obj);
1169 evas_object_event_callback_add(obj, EVAS_CALLBACK_RESIZE, _resize, obj);
1170 evas_object_smart_callbacks_descriptions_set(obj, _signals);
1172 wd->auto_pushed = EINA_TRUE;
1173 wd->freeze_events = EINA_TRUE;
1178 EAPI Elm_Object_Item *
1179 elm_naviframe_item_push(Evas_Object *obj,
1180 const char *title_label,
1181 Evas_Object *prev_btn,
1182 Evas_Object *next_btn,
1183 Evas_Object *content,
1184 const char *item_style)
1186 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1188 Elm_Naviframe_Item *prev_it, *it;
1190 wd = elm_widget_data_get(obj);
1191 if (!wd) return NULL;
1193 it = _item_new(obj, title_label, prev_btn, next_btn, content, item_style);
1194 if (!it) return NULL;
1196 evas_object_show(VIEW(it));
1198 prev_it = (Elm_Naviframe_Item *) elm_naviframe_top_item_get(obj);
1201 if (wd->freeze_events)
1203 evas_object_freeze_events_set(VIEW(it), EINA_TRUE);
1204 evas_object_freeze_events_set(VIEW(prev_it), EINA_TRUE);
1206 edje_object_signal_emit(VIEW(prev_it),
1207 "elm,state,cur,pushed",
1209 edje_object_signal_emit(VIEW(it),
1210 "elm,state,new,pushed",
1212 edje_object_message_signal_process(VIEW(prev_it));
1213 edje_object_message_signal_process(VIEW(it));
1215 wd->stack = eina_inlist_append(wd->stack, EINA_INLIST_GET(it));
1217 return (Elm_Object_Item *) it;
1220 EAPI Elm_Object_Item *
1221 elm_naviframe_item_insert_before(Elm_Object_Item *before,
1222 const char *title_label,
1223 Evas_Object *prev_btn,
1224 Evas_Object *next_btn,
1225 Evas_Object *content,
1226 const char *item_style)
1228 ELM_OBJ_ITEM_CHECK_OR_RETURN(before, NULL);
1229 Elm_Naviframe_Item *it;
1232 wd = elm_widget_data_get(WIDGET(before));
1233 if (!wd) return NULL;
1235 it = _item_new(WIDGET(before), title_label, prev_btn, next_btn, content,
1237 if (!it) return NULL;
1240 eina_inlist_prepend_relative(wd->stack, EINA_INLIST_GET(it),
1241 EINA_INLIST_GET(((Elm_Naviframe_Item *) before)));
1242 _sizing_eval(WIDGET(before));
1243 return (Elm_Object_Item *) it;
1246 EAPI Elm_Object_Item *
1247 elm_naviframe_item_insert_after(Elm_Object_Item *after,
1248 const char *title_label,
1249 Evas_Object *prev_btn,
1250 Evas_Object *next_btn,
1251 Evas_Object *content,
1252 const char *item_style)
1254 ELM_OBJ_ITEM_CHECK_OR_RETURN(after, NULL);
1255 Elm_Naviframe_Item *it;
1258 wd = elm_widget_data_get(WIDGET(after));
1259 if (!wd) return NULL;
1261 it = _item_new(WIDGET(after), title_label, prev_btn, next_btn, content,
1263 if (!it) return NULL;
1265 if (elm_naviframe_top_item_get(WIDGET(after)) == after)
1267 evas_object_hide(VIEW(after));
1268 evas_object_show(VIEW(it));
1271 eina_inlist_append_relative(wd->stack, EINA_INLIST_GET(it),
1272 EINA_INLIST_GET(((Elm_Naviframe_Item *) after)));
1273 _sizing_eval(WIDGET(after));
1274 return (Elm_Object_Item *) it;
1278 elm_naviframe_item_pop(Evas_Object *obj)
1280 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1281 Elm_Naviframe_Item *it, *prev_it = NULL;
1283 Evas_Object *content = NULL;
1285 wd = elm_widget_data_get(obj);
1286 if (!wd) return NULL;
1288 it = (Elm_Naviframe_Item *) elm_naviframe_top_item_get(obj);
1289 if (!it) return NULL;
1290 elm_widget_tree_unfocusable_set(it->content, EINA_TRUE);
1292 content = it->content;
1294 if (wd->stack->last->prev)
1295 prev_it = EINA_INLIST_CONTAINER_GET(wd->stack->last->prev,
1296 Elm_Naviframe_Item);
1297 wd->stack = eina_inlist_remove(wd->stack, EINA_INLIST_GET(it));
1300 if (wd->freeze_events)
1302 evas_object_freeze_events_set(VIEW(it), EINA_TRUE);
1303 evas_object_freeze_events_set(VIEW(prev_it), EINA_TRUE);
1305 edje_object_signal_emit(VIEW(it), "elm,state,cur,popped", "elm");
1306 evas_object_show(VIEW(prev_it));
1307 evas_object_raise(VIEW(prev_it));
1308 edje_object_signal_emit(VIEW(prev_it),
1309 "elm,state,prev,popped",
1311 edje_object_message_signal_process(VIEW(it));
1312 edje_object_message_signal_process(VIEW(prev_it));
1321 elm_naviframe_item_pop_to(Elm_Object_Item *it)
1323 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1324 Elm_Naviframe_Item *navi_it;
1326 Eina_Inlist *l, *prev_l;
1328 navi_it = (Elm_Naviframe_Item *) it;
1329 wd = elm_widget_data_get(WIDGET(navi_it));
1332 if (it == elm_naviframe_top_item_get(WIDGET(navi_it))) return;
1334 l = wd->stack->last->prev;
1338 if (EINA_INLIST_CONTAINER_GET(l, Elm_Naviframe_Item) ==
1339 ((Elm_Naviframe_Item *) it)) break;
1341 wd->stack = eina_inlist_remove(wd->stack, l);
1342 _item_del(EINA_INLIST_CONTAINER_GET(l, Elm_Naviframe_Item));
1345 elm_naviframe_item_pop(WIDGET(navi_it));
1349 elm_naviframe_item_promote(Elm_Object_Item *it)
1351 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1352 Elm_Naviframe_Item *navi_it;
1353 Elm_Naviframe_Item *prev_it;
1356 navi_it = (Elm_Naviframe_Item *) it;
1357 wd = elm_widget_data_get(navi_it->base.widget);
1360 if (it == elm_naviframe_top_item_get(navi_it->base.widget)) return;
1361 wd->stack = eina_inlist_demote(wd->stack, EINA_INLIST_GET(navi_it));
1362 prev_it = EINA_INLIST_CONTAINER_GET(wd->stack->last->prev,
1363 Elm_Naviframe_Item);
1364 if (wd->freeze_events)
1366 evas_object_freeze_events_set(VIEW(it), EINA_TRUE);
1367 evas_object_freeze_events_set(VIEW(prev_it), EINA_TRUE);
1369 edje_object_signal_emit(VIEW(prev_it),
1370 "elm,state,cur,pushed",
1372 evas_object_show(VIEW(navi_it));
1373 evas_object_raise(VIEW(navi_it));
1374 edje_object_signal_emit(VIEW(navi_it),
1375 "elm,state,new,pushed",
1377 edje_object_message_signal_process(VIEW(prev_it));
1378 edje_object_message_signal_process(VIEW(navi_it));
1382 elm_naviframe_item_del(Elm_Object_Item *it)
1384 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1385 Elm_Naviframe_Item *navi_it;
1388 navi_it =(Elm_Naviframe_Item *) it;
1389 wd = elm_widget_data_get(WIDGET(navi_it));
1392 if (it == elm_naviframe_top_item_get(WIDGET(navi_it)))
1394 wd->stack = eina_inlist_remove(wd->stack, EINA_INLIST_GET(navi_it));
1396 //If the item is only one, the stack will be empty
1397 if (!wd->stack) return;
1398 navi_it = EINA_INLIST_CONTAINER_GET(wd->stack->last,
1399 Elm_Naviframe_Item);
1400 evas_object_show(VIEW(navi_it));
1401 evas_object_raise(VIEW(navi_it));
1402 edje_object_signal_emit(VIEW(navi_it), "elm,state,visible", "elm");
1406 wd->stack = eina_inlist_remove(wd->stack, EINA_INLIST_GET(navi_it));
1412 elm_naviframe_content_preserve_on_pop_set(Evas_Object *obj, Eina_Bool preserve)
1414 ELM_CHECK_WIDTYPE(obj, widtype);
1415 Widget_Data *wd = elm_widget_data_get(obj);
1417 wd->preserve = !!preserve;
1421 elm_naviframe_content_preserve_on_pop_get(const Evas_Object *obj)
1423 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
1424 Widget_Data *wd = elm_widget_data_get(obj);
1425 if (!wd) return EINA_FALSE;
1426 return wd->preserve;
1429 EAPI Elm_Object_Item*
1430 elm_naviframe_top_item_get(const Evas_Object *obj)
1432 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1433 Widget_Data *wd = elm_widget_data_get(obj);
1434 if ((!wd) || (!wd->stack)) return NULL;
1435 return (Elm_Object_Item *) (EINA_INLIST_CONTAINER_GET(wd->stack->last,
1436 Elm_Naviframe_Item));
1439 EAPI Elm_Object_Item*
1440 elm_naviframe_bottom_item_get(const Evas_Object *obj)
1442 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1443 Widget_Data *wd = elm_widget_data_get(obj);
1444 if ((!wd) || (!wd->stack)) return NULL;
1445 return (Elm_Object_Item *) (EINA_INLIST_CONTAINER_GET(wd->stack,
1446 Elm_Naviframe_Item));
1450 elm_naviframe_item_style_set(Elm_Object_Item *it, const char *item_style)
1452 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1453 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
1455 //Return if new style is exsiting one.
1457 if (!strcmp(item_style, navi_it->style)) return;
1460 if (!strcmp("basic", navi_it->style)) return;
1462 _item_style_set(navi_it, item_style);
1466 elm_naviframe_item_style_get(const Elm_Object_Item *it)
1468 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
1469 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
1470 return navi_it->style;
1474 elm_naviframe_item_title_visible_set(Elm_Object_Item *it, Eina_Bool visible)
1476 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1477 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
1479 visible = !!visible;
1480 if (navi_it->title_visible == visible) return;
1482 navi_it->title_visible = visible;
1483 _item_title_visible_update(navi_it);
1487 elm_naviframe_item_title_visible_get(const Elm_Object_Item *it)
1489 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
1490 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
1491 return navi_it->title_visible;
1495 elm_naviframe_prev_btn_auto_pushed_set(Evas_Object *obj, Eina_Bool auto_pushed)
1497 ELM_CHECK_WIDTYPE(obj, widtype);
1498 Widget_Data *wd = elm_widget_data_get(obj);
1500 wd->auto_pushed = !!auto_pushed;
1504 elm_naviframe_prev_btn_auto_pushed_get(const Evas_Object *obj)
1506 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
1507 Widget_Data *wd = elm_widget_data_get(obj);
1508 if (!wd) return EINA_FALSE;
1509 return wd->auto_pushed;
1513 elm_naviframe_items_get(const Evas_Object *obj)
1515 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1516 Widget_Data *wd = elm_widget_data_get(obj);
1517 if (!wd) return NULL;
1522 elm_naviframe_event_enabled_set(Evas_Object *obj, Eina_Bool enabled)
1524 ELM_CHECK_WIDTYPE(obj, widtype);
1525 Widget_Data *wd = elm_widget_data_get(obj);
1527 enabled = !!enabled;
1528 if (wd->freeze_events == !enabled) return;
1529 wd->freeze_events = !enabled;
1533 elm_naviframe_event_enabled_get(const Evas_Object *obj)
1535 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
1536 Widget_Data *wd = elm_widget_data_get(obj);
1537 if (!wd) return EINA_FALSE;
1538 return !wd->freeze_events;