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),
942 _show_finished(void *data,
943 Evas_Object *obj __UNUSED__,
944 const char *emission __UNUSED__,
945 const char *source __UNUSED__)
947 Elm_Naviframe_Item *it;
952 wd = elm_widget_data_get(WIDGET(it));
955 evas_object_smart_callback_call(WIDGET(it),
956 SIG_TRANSITION_FINISHED,
958 if (wd->freeze_events)
959 evas_object_freeze_events_set(VIEW(it), EINA_FALSE);
963 _changed_size_hints(void *data,
965 Evas_Object *obj __UNUSED__,
966 void *event_info __UNUSED__)
972 _item_content_set(Elm_Naviframe_Item *navi_it, Evas_Object *content)
974 if (navi_it->content == content) return;
975 if (navi_it->content) evas_object_del(navi_it->content);
976 elm_widget_sub_object_add(WIDGET(navi_it), content);
977 edje_object_part_swallow(VIEW(navi_it),
978 "elm.swallow.content",
981 edje_object_signal_emit(VIEW(navi_it),
982 "elm,state,content,show",
985 edje_object_signal_emit(VIEW(navi_it),
986 "elm,state,content,hide",
988 evas_object_event_callback_add(content,
992 evas_object_event_callback_add(content,
993 EVAS_CALLBACK_CHANGED_SIZE_HINTS,
996 navi_it->content = content;
997 _sizing_eval(WIDGET(navi_it));
1000 //FIXME: need to handle if this function is called while transition
1002 _item_style_set(Elm_Naviframe_Item *navi_it, const char *item_style)
1004 Elm_Naviframe_Content_Item_Pair *content_pair;
1005 Elm_Naviframe_Text_Item_Pair *text_pair;
1012 strcpy(buf, "item/basic");
1013 eina_stringshare_replace(&navi_it->style, "basic");
1017 snprintf(buf, sizeof(buf), "item/%s", item_style);
1018 eina_stringshare_replace(&navi_it->style, item_style);
1020 _elm_theme_object_set(WIDGET(navi_it),
1024 elm_widget_style_get(WIDGET(navi_it)));
1026 EINA_INLIST_FOREACH(navi_it->text_list, text_pair)
1027 _item_text_set_hook((Elm_Object_Item *) navi_it,
1031 EINA_INLIST_FOREACH(navi_it->content_list, content_pair)
1032 _item_content_set_hook((Elm_Object_Item *) navi_it,
1034 content_pair->content);
1036 if (navi_it->content)
1038 edje_object_part_swallow(VIEW(navi_it),
1039 "elm.swallow.content",
1041 edje_object_signal_emit(VIEW(navi_it),
1042 "elm,state,content,show",
1047 if (navi_it->title_prev_btn)
1049 edje_object_part_swallow(VIEW(navi_it),
1050 "elm.swallow.prev_btn",
1051 navi_it->title_prev_btn);
1052 edje_object_signal_emit(VIEW(navi_it),
1053 "elm,state,prev_btn,show",
1058 if (navi_it->title_next_btn)
1060 edje_object_part_swallow(VIEW(navi_it),
1061 "elm.swallow.next_btn",
1062 navi_it->title_next_btn);
1063 edje_object_signal_emit(VIEW(navi_it),
1064 "elm,state,next_btn,show",
1068 navi_it->title_visible = EINA_TRUE;
1069 _sizing_eval(WIDGET(navi_it));
1071 wd = elm_widget_data_get(WIDGET(navi_it));
1074 if (wd->freeze_events)
1075 evas_object_freeze_events_set(VIEW(navi_it), EINA_FALSE);
1078 static Elm_Naviframe_Item *
1079 _item_new(Evas_Object *obj,
1080 const char *title_label,
1081 Evas_Object *prev_btn,
1082 Evas_Object *next_btn,
1083 Evas_Object *content,
1084 const char *item_style)
1086 Widget_Data *wd = elm_widget_data_get(obj);
1089 Elm_Naviframe_Item *it = elm_widget_item_new(obj, Elm_Naviframe_Item);
1092 ERR("Failed to allocate new item! : naviframe=%p", obj);
1096 elm_widget_item_text_set_hook_set(it, _item_text_set_hook);
1097 elm_widget_item_text_get_hook_set(it, _item_text_get_hook);
1098 elm_widget_item_content_set_hook_set(it, _item_content_set_hook);
1099 elm_widget_item_content_get_hook_set(it, _item_content_get_hook);
1100 elm_widget_item_content_unset_hook_set(it, _item_content_unset_hook);
1101 elm_widget_item_signal_emit_hook_set(it, _item_signal_emit_hook);
1104 VIEW(it) = edje_object_add(evas_object_evas_get(obj));
1105 edje_object_mirrored_set(VIEW(it), elm_widget_mirrored_get(obj));
1106 evas_object_smart_member_add(VIEW(it), wd->base);
1107 elm_widget_sub_object_add(obj, VIEW(it));
1108 edje_object_signal_callback_add(VIEW(it),
1109 "elm,action,show,finished",
1111 _show_finished, it);
1112 edje_object_signal_callback_add(VIEW(it),
1113 "elm,action,pushed,finished",
1115 _pushed_finished, it);
1116 edje_object_signal_callback_add(VIEW(it),
1117 "elm,action,popped,finished",
1119 _popped_finished, it);
1120 edje_object_signal_callback_add(VIEW(it),
1121 "elm,action,title,clicked",
1123 _title_clicked, it);
1125 _item_style_set(it, item_style);
1126 _item_text_set_hook((Elm_Object_Item *) it, "elm.text.title", title_label);
1129 if ((!prev_btn) && wd->auto_pushed && eina_inlist_count(wd->stack))
1131 prev_btn = _back_btn_new(obj);
1132 _title_prev_btn_set(it, prev_btn, EINA_TRUE);
1135 _title_prev_btn_set(it, prev_btn, EINA_FALSE);
1137 _title_next_btn_set(it, next_btn);
1138 _item_content_set(it, content);
1139 it->title_visible = EINA_TRUE;
1144 elm_naviframe_add(Evas_Object *parent)
1150 ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL);
1151 ELM_SET_WIDTYPE(widtype, "naviframe");
1152 elm_widget_type_set(obj, "naviframe");
1153 elm_widget_sub_object_add(parent, obj);
1154 elm_widget_data_set(obj, wd);
1155 elm_widget_del_hook_set(obj, _del_hook);
1156 elm_widget_disable_hook_set(obj, _disable_hook);
1157 elm_widget_theme_hook_set(obj, _theme_hook);
1158 elm_widget_signal_emit_hook_set(obj, _emit_hook);
1161 wd->base = edje_object_add(e);
1162 edje_object_mirrored_set(wd->base, elm_widget_mirrored_get(obj));
1163 elm_widget_resize_object_set(obj, wd->base);
1164 _elm_theme_object_set(obj, wd->base, "naviframe", "base", "default");
1166 evas_object_event_callback_add(obj, EVAS_CALLBACK_MOVE, _move, obj);
1167 evas_object_event_callback_add(obj, EVAS_CALLBACK_RESIZE, _resize, obj);
1168 evas_object_smart_callbacks_descriptions_set(obj, _signals);
1170 wd->auto_pushed = EINA_TRUE;
1171 wd->freeze_events = EINA_TRUE;
1176 EAPI Elm_Object_Item *
1177 elm_naviframe_item_push(Evas_Object *obj,
1178 const char *title_label,
1179 Evas_Object *prev_btn,
1180 Evas_Object *next_btn,
1181 Evas_Object *content,
1182 const char *item_style)
1184 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1186 Elm_Naviframe_Item *prev_it, *it;
1188 wd = elm_widget_data_get(obj);
1189 if (!wd) return NULL;
1191 it = _item_new(obj, title_label, prev_btn, next_btn, content, item_style);
1192 if (!it) return NULL;
1194 evas_object_show(VIEW(it));
1196 prev_it = (Elm_Naviframe_Item *) elm_naviframe_top_item_get(obj);
1199 if (wd->freeze_events)
1201 evas_object_freeze_events_set(VIEW(it), EINA_TRUE);
1202 evas_object_freeze_events_set(VIEW(prev_it), EINA_TRUE);
1204 edje_object_signal_emit(VIEW(prev_it),
1205 "elm,state,cur,pushed",
1207 edje_object_signal_emit(VIEW(it),
1208 "elm,state,new,pushed",
1210 edje_object_message_signal_process(VIEW(prev_it));
1211 edje_object_message_signal_process(VIEW(it));
1213 wd->stack = eina_inlist_append(wd->stack, EINA_INLIST_GET(it));
1215 return (Elm_Object_Item *) it;
1218 EAPI Elm_Object_Item *
1219 elm_naviframe_item_insert_before(Elm_Object_Item *before,
1220 const char *title_label,
1221 Evas_Object *prev_btn,
1222 Evas_Object *next_btn,
1223 Evas_Object *content,
1224 const char *item_style)
1226 ELM_OBJ_ITEM_CHECK_OR_RETURN(before, NULL);
1227 Elm_Naviframe_Item *it;
1230 wd = elm_widget_data_get(WIDGET(before));
1231 if (!wd) return NULL;
1233 it = _item_new(WIDGET(before), title_label, prev_btn, next_btn, content,
1235 if (!it) return NULL;
1238 eina_inlist_prepend_relative(wd->stack, EINA_INLIST_GET(it),
1239 EINA_INLIST_GET(((Elm_Naviframe_Item *) before)));
1240 _sizing_eval(WIDGET(before));
1241 return (Elm_Object_Item *) it;
1244 EAPI Elm_Object_Item *
1245 elm_naviframe_item_insert_after(Elm_Object_Item *after,
1246 const char *title_label,
1247 Evas_Object *prev_btn,
1248 Evas_Object *next_btn,
1249 Evas_Object *content,
1250 const char *item_style)
1252 ELM_OBJ_ITEM_CHECK_OR_RETURN(after, NULL);
1253 Elm_Naviframe_Item *it;
1256 wd = elm_widget_data_get(WIDGET(after));
1257 if (!wd) return NULL;
1259 it = _item_new(WIDGET(after), title_label, prev_btn, next_btn, content,
1261 if (!it) return NULL;
1263 if (elm_naviframe_top_item_get(WIDGET(after)) == after)
1265 evas_object_hide(VIEW(after));
1266 evas_object_show(VIEW(it));
1269 eina_inlist_append_relative(wd->stack, EINA_INLIST_GET(it),
1270 EINA_INLIST_GET(((Elm_Naviframe_Item *) after)));
1271 _sizing_eval(WIDGET(after));
1272 return (Elm_Object_Item *) it;
1276 elm_naviframe_item_pop(Evas_Object *obj)
1278 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1279 Elm_Naviframe_Item *it, *prev_it = NULL;
1281 Evas_Object *content = NULL;
1283 wd = elm_widget_data_get(obj);
1284 if (!wd) return NULL;
1286 it = (Elm_Naviframe_Item *) elm_naviframe_top_item_get(obj);
1287 if (!it) return NULL;
1288 elm_widget_tree_unfocusable_set(it->content, EINA_TRUE);
1290 content = it->content;
1292 if (wd->stack->last->prev)
1293 prev_it = EINA_INLIST_CONTAINER_GET(wd->stack->last->prev,
1294 Elm_Naviframe_Item);
1295 wd->stack = eina_inlist_remove(wd->stack, EINA_INLIST_GET(it));
1298 if (wd->freeze_events)
1300 evas_object_freeze_events_set(VIEW(it), EINA_TRUE);
1301 evas_object_freeze_events_set(VIEW(prev_it), EINA_TRUE);
1303 edje_object_signal_emit(VIEW(it), "elm,state,cur,popped", "elm");
1304 evas_object_show(VIEW(prev_it));
1305 evas_object_raise(VIEW(prev_it));
1306 edje_object_signal_emit(VIEW(prev_it),
1307 "elm,state,prev,popped",
1309 edje_object_message_signal_process(VIEW(it));
1310 edje_object_message_signal_process(VIEW(prev_it));
1319 elm_naviframe_item_pop_to(Elm_Object_Item *it)
1321 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1322 Elm_Naviframe_Item *navi_it;
1324 Eina_Inlist *l, *prev_l;
1326 navi_it = (Elm_Naviframe_Item *) it;
1327 wd = elm_widget_data_get(WIDGET(navi_it));
1330 if (it == elm_naviframe_top_item_get(WIDGET(navi_it))) return;
1332 l = wd->stack->last->prev;
1336 if (EINA_INLIST_CONTAINER_GET(l, Elm_Naviframe_Item) ==
1337 ((Elm_Naviframe_Item *) it)) break;
1339 wd->stack = eina_inlist_remove(wd->stack, l);
1340 _item_del(EINA_INLIST_CONTAINER_GET(l, Elm_Naviframe_Item));
1343 elm_naviframe_item_pop(WIDGET(navi_it));
1347 elm_naviframe_item_promote(Elm_Object_Item *it)
1349 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1350 Elm_Naviframe_Item *navi_it;
1351 Elm_Naviframe_Item *prev_it;
1354 navi_it = (Elm_Naviframe_Item *) it;
1355 wd = elm_widget_data_get(navi_it->base.widget);
1358 if (it == elm_naviframe_top_item_get(navi_it->base.widget)) return;
1359 wd->stack = eina_inlist_demote(wd->stack, EINA_INLIST_GET(navi_it));
1360 prev_it = EINA_INLIST_CONTAINER_GET(wd->stack->last->prev,
1361 Elm_Naviframe_Item);
1362 if (wd->freeze_events)
1364 evas_object_freeze_events_set(VIEW(it), EINA_TRUE);
1365 evas_object_freeze_events_set(VIEW(prev_it), EINA_TRUE);
1367 edje_object_signal_emit(VIEW(prev_it),
1368 "elm,state,cur,pushed",
1370 evas_object_show(VIEW(navi_it));
1371 evas_object_raise(VIEW(navi_it));
1372 edje_object_signal_emit(VIEW(navi_it),
1373 "elm,state,new,pushed",
1375 edje_object_message_signal_process(VIEW(prev_it));
1376 edje_object_message_signal_process(VIEW(navi_it));
1380 elm_naviframe_item_del(Elm_Object_Item *it)
1382 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1383 Elm_Naviframe_Item *navi_it;
1386 navi_it =(Elm_Naviframe_Item *) it;
1387 wd = elm_widget_data_get(WIDGET(navi_it));
1390 if (it == elm_naviframe_top_item_get(WIDGET(navi_it)))
1392 wd->stack = eina_inlist_remove(wd->stack, EINA_INLIST_GET(navi_it));
1394 //If the item is only one, the stack will be empty
1395 if (!wd->stack) return;
1396 navi_it = EINA_INLIST_CONTAINER_GET(wd->stack->last,
1397 Elm_Naviframe_Item);
1398 evas_object_show(VIEW(navi_it));
1399 evas_object_raise(VIEW(navi_it));
1400 edje_object_signal_emit(VIEW(navi_it), "elm,state,visible", "elm");
1404 wd->stack = eina_inlist_remove(wd->stack, EINA_INLIST_GET(navi_it));
1410 elm_naviframe_content_preserve_on_pop_set(Evas_Object *obj, Eina_Bool preserve)
1412 ELM_CHECK_WIDTYPE(obj, widtype);
1413 Widget_Data *wd = elm_widget_data_get(obj);
1415 wd->preserve = !!preserve;
1419 elm_naviframe_content_preserve_on_pop_get(const Evas_Object *obj)
1421 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
1422 Widget_Data *wd = elm_widget_data_get(obj);
1423 if (!wd) return EINA_FALSE;
1424 return wd->preserve;
1427 EAPI Elm_Object_Item*
1428 elm_naviframe_top_item_get(const Evas_Object *obj)
1430 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1431 Widget_Data *wd = elm_widget_data_get(obj);
1432 if ((!wd) || (!wd->stack)) return NULL;
1433 return (Elm_Object_Item *) (EINA_INLIST_CONTAINER_GET(wd->stack->last,
1434 Elm_Naviframe_Item));
1437 EAPI Elm_Object_Item*
1438 elm_naviframe_bottom_item_get(const Evas_Object *obj)
1440 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1441 Widget_Data *wd = elm_widget_data_get(obj);
1442 if ((!wd) || (!wd->stack)) return NULL;
1443 return (Elm_Object_Item *) (EINA_INLIST_CONTAINER_GET(wd->stack,
1444 Elm_Naviframe_Item));
1448 elm_naviframe_item_style_set(Elm_Object_Item *it, const char *item_style)
1450 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1451 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
1453 //Return if new style is exsiting one.
1455 if (!strcmp(item_style, navi_it->style)) return;
1458 if (!strcmp("basic", navi_it->style)) return;
1460 _item_style_set(navi_it, item_style);
1464 elm_naviframe_item_style_get(const Elm_Object_Item *it)
1466 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
1467 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
1468 return navi_it->style;
1472 elm_naviframe_item_title_visible_set(Elm_Object_Item *it, Eina_Bool visible)
1474 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1475 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
1477 visible = !!visible;
1478 if (navi_it->title_visible == visible) return;
1480 navi_it->title_visible = visible;
1481 _item_title_visible_update(navi_it);
1485 elm_naviframe_item_title_visible_get(const Elm_Object_Item *it)
1487 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
1488 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
1489 return navi_it->title_visible;
1493 elm_naviframe_prev_btn_auto_pushed_set(Evas_Object *obj, Eina_Bool auto_pushed)
1495 ELM_CHECK_WIDTYPE(obj, widtype);
1496 Widget_Data *wd = elm_widget_data_get(obj);
1498 wd->auto_pushed = !!auto_pushed;
1502 elm_naviframe_prev_btn_auto_pushed_get(const Evas_Object *obj)
1504 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
1505 Widget_Data *wd = elm_widget_data_get(obj);
1506 if (!wd) return EINA_FALSE;
1507 return wd->auto_pushed;
1511 elm_naviframe_items_get(const Evas_Object *obj)
1513 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1514 Widget_Data *wd = elm_widget_data_get(obj);
1515 if (!wd) return NULL;
1520 elm_naviframe_event_enabled_set(Evas_Object *obj, Eina_Bool enabled)
1522 ELM_CHECK_WIDTYPE(obj, widtype);
1523 Widget_Data *wd = elm_widget_data_get(obj);
1525 enabled = !!enabled;
1526 if (wd->freeze_events == !enabled) return;
1527 wd->freeze_events = !enabled;
1531 elm_naviframe_event_enabled_get(const Evas_Object *obj)
1533 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
1534 Widget_Data *wd = elm_widget_data_get(obj);
1535 if (!wd) return EINA_FALSE;
1536 return !wd->freeze_events;