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 //If the item is only one, the stack will be empty
890 if (!wd->stack) return EINA_TRUE;
891 navi_it = EINA_INLIST_CONTAINER_GET(wd->stack->last,
893 evas_object_show(VIEW(navi_it));
894 evas_object_raise(VIEW(navi_it));
895 elm_object_signal_emit(VIEW(navi_it), "elm,state,visible", "elm");
899 wd->stack = eina_inlist_remove(wd->stack, EINA_INLIST_GET(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;