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 void _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 elm_widget_item_free(it);
180 if (!wd->stack) break;
187 _theme_hook(Evas_Object *obj)
190 Elm_Naviframe_Item *it;
192 wd = elm_widget_data_get(obj);
195 _elm_theme_object_set(obj,
199 elm_widget_style_get(obj));
201 EINA_INLIST_FOREACH(wd->stack, it)
203 _item_style_set(it, it->style);
204 _item_title_visible_update(it);
207 _elm_widget_mirrored_reload(obj);
208 _mirrored_set(obj, elm_widget_mirrored_get(obj));
211 static void _emit_hook(Evas_Object *obj,
212 const char *emission,
215 ELM_CHECK_WIDTYPE(obj, widtype);
217 Widget_Data *wd = elm_widget_data_get(obj);
220 edje_object_signal_emit(wd->base, emission, source);
224 _disable_hook(Evas_Object *obj __UNUSED__)
230 _mirrored_set(Evas_Object *obj, Eina_Bool rtl)
233 Elm_Naviframe_Item *it;
235 wd = elm_widget_data_get(obj);
238 EINA_INLIST_FOREACH(wd->stack, it)
239 edje_object_mirrored_set(VIEW(it), rtl);
240 edje_object_mirrored_set(wd->base, rtl);
244 _item_text_set_hook(Elm_Object_Item *it,
248 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
250 Elm_Naviframe_Text_Item_Pair *pair = NULL;
251 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
254 if (!part || !strcmp(part, "default"))
255 snprintf(buf, sizeof(buf), "elm.text.title");
256 else if(!strcmp("subtitle", part))
257 snprintf(buf, sizeof(buf), "elm.text.subtitle");
259 snprintf(buf, sizeof(buf), "%s", part);
261 EINA_INLIST_FOREACH(navi_it->text_list, pair)
262 if (!strcmp(buf, pair->part)) break;
266 pair = ELM_NEW(Elm_Naviframe_Text_Item_Pair);
269 ERR("Failed to allocate new text part of the item! : naviframe=%p",
273 eina_stringshare_replace(&pair->part, buf);
274 navi_it->text_list = eina_inlist_append(navi_it->text_list,
275 EINA_INLIST_GET(pair));
278 eina_stringshare_replace(&pair->text, label);
279 edje_object_part_text_set(VIEW(navi_it), buf, label);
283 snprintf(buf, sizeof(buf), "elm,state,%s,show", buf);
284 edje_object_signal_emit(VIEW(navi_it), buf, "elm");
288 snprintf(buf, sizeof(buf), "elm,state,%s,hide", buf);
289 edje_object_signal_emit(VIEW(navi_it), buf, "elm");
292 _sizing_eval(WIDGET(navi_it));
296 _item_text_get_hook(const Elm_Object_Item *it, const char *part)
298 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
299 Elm_Naviframe_Text_Item_Pair *pair = NULL;
300 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
303 if (!part || !strcmp(part, "default"))
304 snprintf(buf, sizeof(buf), "elm.text.title");
305 else if(!strcmp("subtitle", part))
306 snprintf(buf, sizeof(buf), "elm.text.subtitle");
308 snprintf(buf, sizeof(buf), "%s", part);
310 EINA_INLIST_FOREACH(navi_it->text_list, pair)
312 if (!strcmp(buf, pair->part))
319 _item_content_set_hook(Elm_Object_Item *it,
321 Evas_Object *content)
323 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
325 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
328 if (!part || !strcmp("default", part))
330 _item_content_set(navi_it, content);
333 else if (!strcmp(part, "prev_btn"))
335 _title_prev_btn_set(navi_it, content, EINA_FALSE);
338 else if (!strcmp(part, "next_btn"))
340 _title_next_btn_set(navi_it, content);
343 else if (!strcmp(part, "icon"))
345 _title_icon_set(navi_it, content);
350 _title_content_set(navi_it, part, content);
354 _item_content_get_hook(const Elm_Object_Item *it, const char *part)
356 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
357 Elm_Naviframe_Content_Item_Pair *pair = NULL;
358 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
361 if (!part || !strcmp("default", part))
362 return navi_it->content;
363 else if (!strcmp(part, "prev_btn"))
364 return navi_it->title_prev_btn;
365 else if (!strcmp(part, "next_btn"))
366 return navi_it->title_next_btn;
367 else if (!strcmp(part, "icon"))
368 return navi_it->title_icon;
371 EINA_INLIST_FOREACH(navi_it->content_list, pair)
373 if (!strcmp(part, pair->part))
374 return pair->content;
380 _item_content_unset_hook(Elm_Object_Item *it, const char *part)
382 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
383 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
386 if (!part || !strcmp("default", part))
387 return _item_content_unset(navi_it);
388 else if (!strcmp(part, "prev_btn"))
389 return _title_prev_btn_unset(navi_it);
390 else if (!strcmp(part, "next_btn"))
391 return _title_next_btn_unset(navi_it);
392 else if (!strcmp(part, "icon"))
393 return _title_icon_unset(navi_it);
395 return _title_content_unset(navi_it, part);
399 _item_signal_emit_hook(Elm_Object_Item *it,
400 const char *emission,
403 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
404 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
405 edje_object_signal_emit(VIEW(navi_it), emission, source);
409 _item_title_visible_update(Elm_Naviframe_Item *navi_it)
411 if (navi_it->title_visible)
412 edje_object_signal_emit(VIEW(navi_it), "elm,state,title,show", "elm");
414 edje_object_signal_emit(VIEW(navi_it), "elm,state,title,hide", "elm");
418 _sizing_eval(Evas_Object *obj)
421 Elm_Naviframe_Item *it;
422 Evas_Coord x, y, w, h;
423 Evas_Coord minw = -1, minh = -1;
425 wd = elm_widget_data_get(obj);
428 EINA_INLIST_FOREACH(wd->stack, it)
430 evas_object_geometry_get(WIDGET(it), &x, &y, &w, &h);
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);
878 Elm_Naviframe_Item *navi_it;
881 navi_it =(Elm_Naviframe_Item *) it;
882 wd = elm_widget_data_get(WIDGET(navi_it));
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;
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 edje_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);
907 _pushed_finished(void *data,
908 Evas_Object *obj __UNUSED__,
909 const char *emission __UNUSED__,
910 const char *source __UNUSED__)
913 Elm_Naviframe_Item *it = data;
916 wd = elm_widget_data_get(WIDGET(it));
919 evas_object_hide(VIEW(it));
920 evas_object_smart_callback_call(WIDGET(it),
923 if (wd->freeze_events)
924 evas_object_freeze_events_set(VIEW(it), EINA_FALSE);
928 _popped_finished(void *data,
929 Evas_Object *obj __UNUSED__,
930 const char *emission __UNUSED__,
931 const char *source __UNUSED__)
933 Elm_Naviframe_Item *it = data;
935 evas_object_smart_callback_call(WIDGET(it),
939 elm_widget_item_free(data);
943 _show_finished(void *data,
944 Evas_Object *obj __UNUSED__,
945 const char *emission __UNUSED__,
946 const char *source __UNUSED__)
948 Elm_Naviframe_Item *it;
953 wd = elm_widget_data_get(WIDGET(it));
956 evas_object_smart_callback_call(WIDGET(it),
957 SIG_TRANSITION_FINISHED,
959 if (wd->freeze_events)
960 evas_object_freeze_events_set(VIEW(it), EINA_FALSE);
964 _changed_size_hints(void *data,
966 Evas_Object *obj __UNUSED__,
967 void *event_info __UNUSED__)
973 _item_content_set(Elm_Naviframe_Item *navi_it, Evas_Object *content)
975 if (navi_it->content == content) return;
976 if (navi_it->content) evas_object_del(navi_it->content);
977 elm_widget_sub_object_add(WIDGET(navi_it), content);
978 edje_object_part_swallow(VIEW(navi_it),
979 "elm.swallow.content",
982 edje_object_signal_emit(VIEW(navi_it),
983 "elm,state,content,show",
986 edje_object_signal_emit(VIEW(navi_it),
987 "elm,state,content,hide",
989 evas_object_event_callback_add(content,
993 evas_object_event_callback_add(content,
994 EVAS_CALLBACK_CHANGED_SIZE_HINTS,
997 navi_it->content = content;
998 _sizing_eval(WIDGET(navi_it));
1001 //FIXME: need to handle if this function is called while transition
1003 _item_style_set(Elm_Naviframe_Item *navi_it, const char *item_style)
1005 Elm_Naviframe_Content_Item_Pair *content_pair;
1006 Elm_Naviframe_Text_Item_Pair *text_pair;
1013 strcpy(buf, "item/basic");
1014 eina_stringshare_replace(&navi_it->style, "basic");
1018 snprintf(buf, sizeof(buf), "item/%s", item_style);
1019 eina_stringshare_replace(&navi_it->style, item_style);
1021 _elm_theme_object_set(WIDGET(navi_it),
1025 elm_widget_style_get(WIDGET(navi_it)));
1027 EINA_INLIST_FOREACH(navi_it->text_list, text_pair)
1028 _item_text_set_hook((Elm_Object_Item *) navi_it,
1032 EINA_INLIST_FOREACH(navi_it->content_list, content_pair)
1033 _item_content_set_hook((Elm_Object_Item *) navi_it,
1035 content_pair->content);
1037 if (navi_it->content)
1039 edje_object_part_swallow(VIEW(navi_it),
1040 "elm.swallow.content",
1042 edje_object_signal_emit(VIEW(navi_it),
1043 "elm,state,content,show",
1048 if (navi_it->title_prev_btn)
1050 edje_object_part_swallow(VIEW(navi_it),
1051 "elm.swallow.prev_btn",
1052 navi_it->title_prev_btn);
1053 edje_object_signal_emit(VIEW(navi_it),
1054 "elm,state,prev_btn,show",
1059 if (navi_it->title_next_btn)
1061 edje_object_part_swallow(VIEW(navi_it),
1062 "elm.swallow.next_btn",
1063 navi_it->title_next_btn);
1064 edje_object_signal_emit(VIEW(navi_it),
1065 "elm,state,next_btn,show",
1069 navi_it->title_visible = EINA_TRUE;
1070 _sizing_eval(WIDGET(navi_it));
1072 wd = elm_widget_data_get(WIDGET(navi_it));
1075 if (wd->freeze_events)
1076 evas_object_freeze_events_set(VIEW(navi_it), EINA_FALSE);
1079 static Elm_Naviframe_Item *
1080 _item_new(Evas_Object *obj,
1081 const char *title_label,
1082 Evas_Object *prev_btn,
1083 Evas_Object *next_btn,
1084 Evas_Object *content,
1085 const char *item_style)
1087 Widget_Data *wd = elm_widget_data_get(obj);
1090 Elm_Naviframe_Item *it = elm_widget_item_new(obj, Elm_Naviframe_Item);
1093 ERR("Failed to allocate new item! : naviframe=%p", obj);
1097 elm_widget_item_del_pre_hook_set(it, _item_del_pre_hook);
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));
1317 elm_widget_item_free(it);
1324 elm_naviframe_item_pop_to(Elm_Object_Item *it)
1326 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1327 Elm_Naviframe_Item *navi_it;
1329 Eina_Inlist *l, *prev_l;
1331 navi_it = (Elm_Naviframe_Item *) it;
1332 wd = elm_widget_data_get(WIDGET(navi_it));
1335 if (it == elm_naviframe_top_item_get(WIDGET(navi_it))) return;
1337 l = wd->stack->last->prev;
1341 if (EINA_INLIST_CONTAINER_GET(l, Elm_Naviframe_Item) ==
1342 ((Elm_Naviframe_Item *) it)) break;
1344 wd->stack = eina_inlist_remove(wd->stack, l);
1345 _item_del(EINA_INLIST_CONTAINER_GET(l, Elm_Naviframe_Item));
1346 elm_widget_item_free(EINA_INLIST_CONTAINER_GET(l,
1347 Elm_Naviframe_Item));
1350 elm_naviframe_item_pop(WIDGET(navi_it));
1354 elm_naviframe_item_promote(Elm_Object_Item *it)
1356 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1357 Elm_Naviframe_Item *navi_it;
1358 Elm_Naviframe_Item *prev_it;
1361 navi_it = (Elm_Naviframe_Item *) it;
1362 wd = elm_widget_data_get(navi_it->base.widget);
1365 if (it == elm_naviframe_top_item_get(navi_it->base.widget)) return;
1366 wd->stack = eina_inlist_demote(wd->stack, EINA_INLIST_GET(navi_it));
1367 prev_it = EINA_INLIST_CONTAINER_GET(wd->stack->last->prev,
1368 Elm_Naviframe_Item);
1369 if (wd->freeze_events)
1371 evas_object_freeze_events_set(VIEW(it), EINA_TRUE);
1372 evas_object_freeze_events_set(VIEW(prev_it), EINA_TRUE);
1374 edje_object_signal_emit(VIEW(prev_it),
1375 "elm,state,cur,pushed",
1377 evas_object_show(VIEW(navi_it));
1378 evas_object_raise(VIEW(navi_it));
1379 edje_object_signal_emit(VIEW(navi_it),
1380 "elm,state,new,pushed",
1382 edje_object_message_signal_process(VIEW(prev_it));
1383 edje_object_message_signal_process(VIEW(navi_it));
1387 elm_naviframe_item_del(Elm_Object_Item *it)
1389 elm_object_item_del(it);
1393 elm_naviframe_content_preserve_on_pop_set(Evas_Object *obj, Eina_Bool preserve)
1395 ELM_CHECK_WIDTYPE(obj, widtype);
1396 Widget_Data *wd = elm_widget_data_get(obj);
1398 wd->preserve = !!preserve;
1402 elm_naviframe_content_preserve_on_pop_get(const Evas_Object *obj)
1404 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
1405 Widget_Data *wd = elm_widget_data_get(obj);
1406 if (!wd) return EINA_FALSE;
1407 return wd->preserve;
1410 EAPI Elm_Object_Item*
1411 elm_naviframe_top_item_get(const Evas_Object *obj)
1413 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1414 Widget_Data *wd = elm_widget_data_get(obj);
1415 if ((!wd) || (!wd->stack)) return NULL;
1416 return (Elm_Object_Item *) (EINA_INLIST_CONTAINER_GET(wd->stack->last,
1417 Elm_Naviframe_Item));
1420 EAPI Elm_Object_Item*
1421 elm_naviframe_bottom_item_get(const Evas_Object *obj)
1423 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1424 Widget_Data *wd = elm_widget_data_get(obj);
1425 if ((!wd) || (!wd->stack)) return NULL;
1426 return (Elm_Object_Item *) (EINA_INLIST_CONTAINER_GET(wd->stack,
1427 Elm_Naviframe_Item));
1431 elm_naviframe_item_style_set(Elm_Object_Item *it, const char *item_style)
1433 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1434 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
1436 //Return if new style is exsiting one.
1438 if (!strcmp(item_style, navi_it->style)) return;
1441 if (!strcmp("basic", navi_it->style)) return;
1443 _item_style_set(navi_it, item_style);
1447 elm_naviframe_item_style_get(const Elm_Object_Item *it)
1449 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
1450 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
1451 return navi_it->style;
1455 elm_naviframe_item_title_visible_set(Elm_Object_Item *it, Eina_Bool visible)
1457 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1458 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
1460 visible = !!visible;
1461 if (navi_it->title_visible == visible) return;
1463 navi_it->title_visible = visible;
1464 _item_title_visible_update(navi_it);
1468 elm_naviframe_item_title_visible_get(const Elm_Object_Item *it)
1470 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
1471 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
1472 return navi_it->title_visible;
1476 elm_naviframe_prev_btn_auto_pushed_set(Evas_Object *obj, Eina_Bool auto_pushed)
1478 ELM_CHECK_WIDTYPE(obj, widtype);
1479 Widget_Data *wd = elm_widget_data_get(obj);
1481 wd->auto_pushed = !!auto_pushed;
1485 elm_naviframe_prev_btn_auto_pushed_get(const Evas_Object *obj)
1487 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
1488 Widget_Data *wd = elm_widget_data_get(obj);
1489 if (!wd) return EINA_FALSE;
1490 return wd->auto_pushed;
1494 elm_naviframe_items_get(const Evas_Object *obj)
1496 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1497 Widget_Data *wd = elm_widget_data_get(obj);
1498 if (!wd) return NULL;
1503 elm_naviframe_event_enabled_set(Evas_Object *obj, Eina_Bool enabled)
1505 ELM_CHECK_WIDTYPE(obj, widtype);
1506 Widget_Data *wd = elm_widget_data_get(obj);
1508 enabled = !!enabled;
1509 if (wd->freeze_events == !enabled) return;
1510 wd->freeze_events = !enabled;
1514 elm_naviframe_event_enabled_get(const Evas_Object *obj)
1516 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
1517 Widget_Data *wd = elm_widget_data_get(obj);
1518 if (!wd) return EINA_FALSE;
1519 return !wd->freeze_events;