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
22 Elm_Naviframe_Item *it;
25 struct _Elm_Naviframe_Text_Item_Pair
31 struct _Elm_Naviframe_Item
35 Eina_Inlist *content_list;
36 Eina_Inlist *text_list;
38 Evas_Object *title_prev_btn;
39 Evas_Object *title_next_btn;
40 Evas_Object *title_icon;
44 Eina_Bool back_btn: 1;
45 Eina_Bool title_visible: 1;
48 static const char *widtype = NULL;
50 static const char SIG_TRANSITION_FINISHED[] = "transition,finished";
51 static const char SIG_PUSH_FINISHED[] = "push,finished";
52 static const char SIG_POP_FINISHED[] = "pop,finished";
53 static const char SIG_TITLE_CLICKED[] = "title,clicked";
55 static const Evas_Smart_Cb_Description _signals[] = {
56 {SIG_TRANSITION_FINISHED, ""},
57 {SIG_TITLE_CLICKED, ""},
61 static void _del_hook(Evas_Object *obj);
62 static void _theme_hook(Evas_Object *obj);
63 static void _emit_hook(Evas_Object *obj,
66 static void _disable_hook(Evas_Object *obj);
67 static void _item_text_set_hook(Elm_Object_Item *it,
70 static const char *_item_text_get_hook(const Elm_Object_Item *it,
72 static void _item_content_set_hook(Elm_Object_Item *it,
74 Evas_Object *content);
75 static Evas_Object *_item_content_get_hook(const Elm_Object_Item *it,
77 static Evas_Object *_item_content_unset_hook(Elm_Object_Item *it,
79 static void _item_signal_emit_hook(Elm_Object_Item *it,
82 static void _item_title_visible_update(Elm_Naviframe_Item *navi_it);
83 static void _sizing_eval(Evas_Object *obj);
84 static void _move(void *data, Evas *e, Evas_Object *obj, void *event_info);
85 static void _resize(void *data,
89 static void _title_clicked(void *data, Evas_Object *obj,
92 static void _back_btn_clicked(void *data,
95 static Evas_Object *_back_btn_new(Evas_Object *obj);
96 static void _item_content_del(void *data,
100 static void _title_content_del(void *data,
104 static void _title_prev_btn_del(void *data,
108 static void _title_next_btn_del(void *data,
112 static void _title_icon_del(void *data,
116 static void _title_content_set(Elm_Naviframe_Item *it,
118 Evas_Object *content);
119 static void _title_prev_btn_set(Elm_Naviframe_Item *it,
122 static void _title_next_btn_set(Elm_Naviframe_Item *it, Evas_Object *btn);
123 static void _title_icon_set(Elm_Naviframe_Item *it, Evas_Object *icon);
124 static Evas_Object * _item_content_unset(Elm_Naviframe_Item *it);
125 static Evas_Object * _title_prev_btn_unset(Elm_Naviframe_Item *it);
126 static Evas_Object * _title_next_btn_unset(Elm_Naviframe_Item *it);
127 static Evas_Object * _title_icon_unset(Elm_Naviframe_Item *it);
128 static Evas_Object * _title_content_unset(Elm_Naviframe_Item *it,
130 static void _item_del(Elm_Naviframe_Item *it);
131 static void _item_del_pre_hook(Elm_Object_Item *it);
132 static void _pushed_finished(void *data,
134 const char *emission,
136 static void _popped_finished(void *data,
138 const char *emission,
140 static void _show_finished(void *data,
142 const char *emission,
144 static void _changed_size_hints(void *data,
148 static void _item_content_set(Elm_Naviframe_Item *navi_it,
149 Evas_Object *content);
150 static void _item_style_set(Elm_Naviframe_Item *navi_it,
151 const char *item_style);
152 static Elm_Naviframe_Item * _item_new(Evas_Object *obj,
153 const char *title_label,
154 Evas_Object *prev_btn,
155 Evas_Object *next_btn,
156 Evas_Object *content,
157 const char *item_style);
158 static Eina_Bool _focus_next_hook(const Evas_Object *obj,
159 Elm_Focus_Direction dir,
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);
208 static void _emit_hook(Evas_Object *obj,
209 const char *emission,
212 ELM_CHECK_WIDTYPE(obj, widtype);
214 Widget_Data *wd = elm_widget_data_get(obj);
217 elm_object_signal_emit(wd->base, emission, source);
221 _disable_hook(Evas_Object *obj __UNUSED__)
227 _item_text_set_hook(Elm_Object_Item *it,
231 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
233 Elm_Naviframe_Text_Item_Pair *pair = NULL;
234 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
237 if (!part || !strcmp(part, "default"))
238 snprintf(buf, sizeof(buf), "elm.text.title");
239 else if(!strcmp("subtitle", part))
240 snprintf(buf, sizeof(buf), "elm.text.subtitle");
242 snprintf(buf, sizeof(buf), "%s", part);
244 EINA_INLIST_FOREACH(navi_it->text_list, pair)
245 if (!strcmp(buf, pair->part)) break;
249 pair = ELM_NEW(Elm_Naviframe_Text_Item_Pair);
252 ERR("Failed to allocate new text part of the item! : naviframe=%p",
256 eina_stringshare_replace(&pair->part, buf);
257 navi_it->text_list = eina_inlist_append(navi_it->text_list,
258 EINA_INLIST_GET(pair));
260 elm_object_part_text_set(VIEW(navi_it), buf, label);
264 snprintf(buf, sizeof(buf), "elm,state,%s,show", buf);
265 elm_object_signal_emit(VIEW(navi_it), buf, "elm");
269 snprintf(buf, sizeof(buf), "elm,state,%s,hide", buf);
270 elm_object_signal_emit(VIEW(navi_it), buf, "elm");
273 _sizing_eval(WIDGET(navi_it));
277 _item_text_get_hook(const Elm_Object_Item *it, const char *part)
279 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
282 if (!part || !strcmp(part, "default"))
283 snprintf(buf, sizeof(buf), "elm.text.title");
284 else if(!strcmp("subtitle", part))
285 snprintf(buf, sizeof(buf), "elm.text.subtitle");
287 snprintf(buf, sizeof(buf), "%s", part);
289 return elm_object_part_text_get(VIEW(it), buf);
293 _item_content_set_hook(Elm_Object_Item *it,
295 Evas_Object *content)
297 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
299 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
302 if (!part || !strcmp("default", part))
304 _item_content_set(navi_it, content);
307 else if (!strcmp(part, "prev_btn"))
309 _title_prev_btn_set(navi_it, content, EINA_FALSE);
312 else if (!strcmp(part, "next_btn"))
314 _title_next_btn_set(navi_it, content);
317 else if (!strcmp(part, "icon"))
319 _title_icon_set(navi_it, content);
324 _title_content_set(navi_it, part, content);
328 _item_content_get_hook(const Elm_Object_Item *it, const char *part)
330 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
331 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
334 if (!part || !strcmp("default", part))
335 return navi_it->content;
336 else if (!strcmp(part, "prev_btn"))
337 return navi_it->title_prev_btn;
338 else if (!strcmp(part, "next_btn"))
339 return navi_it->title_next_btn;
340 else if (!strcmp(part, "icon"))
341 return navi_it->title_icon;
344 return elm_object_part_content_get(VIEW(navi_it), part);
348 _item_content_unset_hook(Elm_Object_Item *it, const char *part)
350 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
351 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
354 if (!part || !strcmp("default", part))
355 return _item_content_unset(navi_it);
356 else if (!strcmp(part, "prev_btn"))
357 return _title_prev_btn_unset(navi_it);
358 else if (!strcmp(part, "next_btn"))
359 return _title_next_btn_unset(navi_it);
360 else if (!strcmp(part, "icon"))
361 return _title_icon_unset(navi_it);
363 return _title_content_unset(navi_it, part);
367 _item_signal_emit_hook(Elm_Object_Item *it,
368 const char *emission,
371 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
372 elm_object_signal_emit(VIEW(it), emission, source);
376 _item_title_visible_update(Elm_Naviframe_Item *navi_it)
378 if (navi_it->title_visible)
379 elm_object_signal_emit(VIEW(navi_it), "elm,state,title,show", "elm");
381 elm_object_signal_emit(VIEW(navi_it), "elm,state,title,hide", "elm");
385 _sizing_eval(Evas_Object *obj)
388 Elm_Naviframe_Item *it;
389 Evas_Coord x, y, w, h;
390 Evas_Coord minw = -1, minh = -1;
392 wd = elm_widget_data_get(obj);
395 evas_object_geometry_get(obj, &x, &y, &w, &h);
397 EINA_INLIST_FOREACH(wd->stack, it)
399 evas_object_move(VIEW(it), x, y);
400 evas_object_resize(VIEW(it), w, h);
401 edje_object_size_min_calc(elm_layout_edje_get(VIEW(it)),
404 if (it->minw > minw) minw = it->minw;
405 if (it->minh > minh) minh = it->minh;
407 evas_object_size_hint_min_set(obj, minw, minh);
408 evas_object_size_hint_max_set(obj, -1, -1);
412 _move(void *data __UNUSED__,
415 void *event_info __UNUSED__)
421 _resize(void *data __UNUSED__,
424 void *event_info __UNUSED__)
430 _title_clicked(void *data,
431 Evas_Object *obj __UNUSED__,
432 const char *emission __UNUSED__,
433 const char *source __UNUSED__)
435 Elm_Naviframe_Item *it = data;
436 evas_object_smart_callback_call(WIDGET(it), SIG_TITLE_CLICKED, it);
440 _back_btn_clicked(void *data,
442 void *event_info __UNUSED__)
444 /* Since edje has the event queue, clicked event could be happend multiple times
445 on some heavy environment. This callback del will prevent those scenario and
446 guarantee only one clicked for it's own page. */
447 evas_object_smart_callback_del(obj, "clicked", _back_btn_clicked);
448 elm_naviframe_item_pop(data);
452 _back_btn_new(Evas_Object *obj)
456 btn = elm_button_add(obj);
457 if (!btn) return NULL;
458 evas_object_smart_callback_add(btn, "clicked", _back_btn_clicked, obj);
459 snprintf(buf, sizeof(buf), "naviframe/back_btn/%s", elm_widget_style_get(obj));
460 elm_object_style_set(btn, buf);
465 _title_content_del(void *data,
467 Evas_Object *obj __UNUSED__,
468 void *event_info __UNUSED__)
471 Elm_Naviframe_Content_Item_Pair *pair = data;
472 Elm_Naviframe_Item *it = pair->it;
473 snprintf(buf, sizeof(buf), "elm,state,%s,hide", pair->part);
474 elm_object_signal_emit(VIEW(it), buf, "elm");
475 it->content_list = eina_inlist_remove(it->content_list,
476 EINA_INLIST_GET(pair));
477 eina_stringshare_del(pair->part);
482 _title_prev_btn_del(void *data,
484 Evas_Object *obj __UNUSED__,
485 void *event_info __UNUSED__)
487 Elm_Naviframe_Item *it = data;
488 it->back_btn = EINA_FALSE;
489 it->title_prev_btn = NULL;
490 elm_object_signal_emit(VIEW(it), "elm,state,prev_btn,hide", "elm");
494 _title_next_btn_del(void *data,
496 Evas_Object *obj __UNUSED__,
497 void *event_info __UNUSED__)
499 Elm_Naviframe_Item *it = data;
500 it->title_next_btn = NULL;
501 elm_object_signal_emit(VIEW(it), "elm,state,next_btn,hide", "elm");
505 _title_icon_del(void *data,
507 Evas_Object *obj __UNUSED__,
508 void *event_info __UNUSED__)
510 Elm_Naviframe_Item *it = data;
511 it->title_icon = NULL;
512 elm_object_signal_emit(VIEW(it), "elm,state,icon,hide", "elm");
516 _item_content_del(void *data,
518 Evas_Object *obj __UNUSED__,
519 void *event_info __UNUSED__)
521 Elm_Naviframe_Item *it = data;
523 elm_object_signal_emit(VIEW(it), "elm,state,content,hide", "elm");
527 _title_content_set(Elm_Naviframe_Item *it,
529 Evas_Object *content)
532 Elm_Naviframe_Content_Item_Pair *pair = NULL;
533 Evas_Object *prev_content = NULL;
535 EINA_INLIST_FOREACH(it->content_list, pair)
536 if (!strcmp(part, pair->part)) break;
540 prev_content = elm_object_part_content_get(VIEW(it), part);
541 if (prev_content != content)
545 evas_object_event_callback_del(prev_content,
548 snprintf(buf, sizeof(buf), "elm,state,%s,hide", part);
549 elm_object_signal_emit(VIEW(it), buf, "elm");
551 evas_object_del(prev_content);
552 if (!content) return;
557 if (!content) return;
558 pair = ELM_NEW(Elm_Naviframe_Content_Item_Pair);
561 ERR("Failed to allocate new content part of the item! : naviframe=%p", WIDGET(it));
565 eina_stringshare_replace(&pair->part, part);
566 it->content_list = eina_inlist_append(it->content_list,
567 EINA_INLIST_GET(pair));
569 if (prev_content != content)
571 evas_object_event_callback_add(content,
576 elm_object_part_content_set(VIEW(it), part, content);
577 snprintf(buf, sizeof(buf), "elm,state,%s,show", part);
578 elm_object_signal_emit(VIEW(it), buf, "elm");
580 _sizing_eval(WIDGET(it));
584 _title_prev_btn_set(Elm_Naviframe_Item *it,
588 if (it->title_prev_btn == btn) return;
589 if (it->title_prev_btn) evas_object_del(it->title_prev_btn);
590 it->title_prev_btn = btn;
593 evas_object_event_callback_add(btn,
597 elm_object_part_content_set(VIEW(it), "elm.swallow.prev_btn", btn);
598 elm_object_signal_emit(VIEW(it), "elm,state,prev_btn,show", "elm");
599 it->back_btn = back_btn;
601 _sizing_eval(WIDGET(it));
605 _title_next_btn_set(Elm_Naviframe_Item *it, Evas_Object *btn)
607 if (it->title_next_btn == btn) return;
608 if (it->title_next_btn) evas_object_del(it->title_next_btn);
609 it->title_next_btn = btn;
612 evas_object_event_callback_add(btn,
616 elm_object_part_content_set(VIEW(it), "elm.swallow.next_btn", btn);
617 elm_object_signal_emit(VIEW(it), "elm,state,next_btn,show", "elm");
619 _sizing_eval(WIDGET(it));
623 _title_icon_set(Elm_Naviframe_Item *it, Evas_Object *icon)
625 if (it->title_icon == icon) return;
626 if (it->title_icon) evas_object_del(it->title_icon);
627 it->title_icon = icon;
630 evas_object_event_callback_add(icon,
634 elm_object_part_content_set(VIEW(it), "elm.swallow.icon", icon);
635 elm_object_signal_emit(VIEW(it), "elm,state,icon,show", "elm");
637 _sizing_eval(WIDGET(it));
641 _item_content_unset(Elm_Naviframe_Item *it)
643 Evas_Object *content = it->content;
644 if (!content) return NULL;
646 elm_object_part_content_unset(VIEW(it), "elm.swallow.content");
647 elm_object_signal_emit(VIEW(it), "elm,state,content,hide", "elm");
648 evas_object_event_callback_del(content,
651 _sizing_eval(WIDGET(it));
658 _title_prev_btn_unset(Elm_Naviframe_Item *it)
660 Evas_Object *content = it->title_prev_btn;
661 if (!content) return NULL;
663 elm_object_part_content_unset(VIEW(it), "elm.swallow.prev_btn");
664 elm_object_signal_emit(VIEW(it), "elm,state,prev_btn,hide", "elm");
665 evas_object_event_callback_del(content,
667 _title_prev_btn_del);
668 _sizing_eval(WIDGET(it));
670 it->title_prev_btn = NULL;
675 _title_next_btn_unset(Elm_Naviframe_Item *it)
677 Evas_Object *content = it->title_next_btn;
678 if (!content) return NULL;
680 elm_object_part_content_unset(VIEW(it), "elm.swallow.next_btn");
681 elm_object_signal_emit(VIEW(it), "elm,state,next_btn,hide", "elm");
682 evas_object_event_callback_del(content,
684 _title_next_btn_del);
685 _sizing_eval(WIDGET(it));
687 it->title_next_btn = NULL;
692 _title_icon_unset(Elm_Naviframe_Item *it)
694 Evas_Object *content = it->title_icon;
695 if (!content) return NULL;
697 elm_object_part_content_unset(VIEW(it), "elm.swallow.icon");
698 elm_object_signal_emit(VIEW(it), "elm,state,icon,hide", "elm");
699 evas_object_event_callback_del(content,
702 _sizing_eval(WIDGET(it));
703 it->title_icon = NULL;
709 _title_content_unset(Elm_Naviframe_Item *it, const char *part)
711 Elm_Naviframe_Content_Item_Pair *pair = NULL;
713 Evas_Object *content = NULL;
715 EINA_INLIST_FOREACH(it->content_list, pair)
717 if (!strcmp(part, pair->part))
719 content = elm_object_part_content_get(VIEW(it), part);
720 eina_stringshare_del(pair->part);
721 it->content_list = eina_inlist_remove(it->content_list,
722 EINA_INLIST_GET(pair));
728 if (!content) return NULL;
730 elm_object_part_content_unset(VIEW(it), part);
731 snprintf(buf, sizeof(buf), "elm,state,%s,hide", part);
732 elm_object_signal_emit(VIEW(it), buf, "elm");
733 evas_object_event_callback_del(content,
736 _sizing_eval(WIDGET(it));
742 _item_del(Elm_Naviframe_Item *it)
745 Elm_Naviframe_Content_Item_Pair *content_pair;
746 Elm_Naviframe_Text_Item_Pair *text_pair;
747 Evas_Object *content;
751 wd = elm_widget_data_get(WIDGET(it));
754 while (it->content_list)
757 EINA_INLIST_CONTAINER_GET(it->content_list,
758 Elm_Naviframe_Content_Item_Pair);
759 content = elm_object_part_content_get(VIEW(it), content_pair->part);
760 evas_object_event_callback_del(content,
763 eina_stringshare_del(content_pair->part);
764 it->content_list = eina_inlist_remove(it->content_list,
769 while (it->text_list)
771 text_pair = EINA_INLIST_CONTAINER_GET(it->text_list,
772 Elm_Naviframe_Text_Item_Pair);
773 eina_stringshare_del(text_pair->part);
774 it->text_list = eina_inlist_remove(it->text_list,
779 eina_stringshare_del(it->style);
783 _item_del_pre_hook(Elm_Object_Item *it)
785 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
786 Elm_Naviframe_Item *navi_it;
789 navi_it =(Elm_Naviframe_Item *) it;
790 wd = elm_widget_data_get(WIDGET(navi_it));
793 if (it == elm_naviframe_top_item_get(WIDGET(navi_it)))
795 wd->stack = eina_inlist_remove(wd->stack, EINA_INLIST_GET(navi_it));
797 elm_widget_item_free(navi_it);
798 //If the item is only one, the stack will be empty
799 if (!wd->stack) return;
800 navi_it = EINA_INLIST_CONTAINER_GET(wd->stack->last,
802 evas_object_show(VIEW(navi_it));
803 evas_object_raise(VIEW(navi_it));
804 elm_object_signal_emit(VIEW(navi_it), "elm,state,visible", "elm");
808 wd->stack = eina_inlist_remove(wd->stack, EINA_INLIST_GET(navi_it));
810 elm_widget_item_free(navi_it);
815 _pushed_finished(void *data,
816 Evas_Object *obj __UNUSED__,
817 const char *emission __UNUSED__,
818 const char *source __UNUSED__)
821 Elm_Naviframe_Item *it = data;
824 wd = elm_widget_data_get(WIDGET(it));
827 evas_object_hide(VIEW(it));
828 evas_object_smart_callback_call(WIDGET(it),
831 if (wd->freeze_events)
832 evas_object_freeze_events_set(VIEW(it), EINA_FALSE);
836 _popped_finished(void *data,
837 Evas_Object *obj __UNUSED__,
838 const char *emission __UNUSED__,
839 const char *source __UNUSED__)
841 Elm_Naviframe_Item *it = data;
843 evas_object_smart_callback_call(WIDGET(it),
847 elm_widget_item_free(data);
851 _show_finished(void *data,
852 Evas_Object *obj __UNUSED__,
853 const char *emission __UNUSED__,
854 const char *source __UNUSED__)
856 Elm_Naviframe_Item *it;
861 wd = elm_widget_data_get(WIDGET(it));
864 evas_object_smart_callback_call(WIDGET(it),
865 SIG_TRANSITION_FINISHED,
867 if (wd->freeze_events)
868 evas_object_freeze_events_set(VIEW(it), EINA_FALSE);
872 _changed_size_hints(void *data,
874 Evas_Object *obj __UNUSED__,
875 void *event_info __UNUSED__)
881 _item_content_set(Elm_Naviframe_Item *navi_it, Evas_Object *content)
883 if (navi_it->content == content) return;
884 if (navi_it->content) evas_object_del(navi_it->content);
885 elm_object_part_content_set(VIEW(navi_it), "elm.swallow.content", content);
888 elm_object_signal_emit(VIEW(navi_it), "elm,state,content,show", "elm");
890 elm_object_signal_emit(VIEW(navi_it), "elm,state,content,hide", "elm");
892 evas_object_event_callback_add(content,
896 navi_it->content = content;
897 _sizing_eval(WIDGET(navi_it));
900 //FIXME: need to handle if this function is called while transition
902 _item_style_set(Elm_Naviframe_Item *navi_it, const char *item_style)
904 Elm_Naviframe_Content_Item_Pair *content_pair;
905 Elm_Naviframe_Text_Item_Pair *text_pair;
912 strcpy(buf, "item/basic");
913 eina_stringshare_replace(&navi_it->style, "basic");
917 snprintf(buf, sizeof(buf), "item/%s", item_style);
918 eina_stringshare_replace(&navi_it->style, item_style);
920 elm_layout_theme_set(VIEW(navi_it),
923 elm_widget_style_get(WIDGET(navi_it)));
925 EINA_INLIST_FOREACH(navi_it->text_list, text_pair)
926 _item_text_set_hook((Elm_Object_Item *) navi_it,
928 elm_object_part_text_get(VIEW(navi_it),
931 EINA_INLIST_FOREACH(navi_it->content_list, content_pair)
932 _item_content_set_hook((Elm_Object_Item *) navi_it,
934 elm_object_part_content_get(VIEW(navi_it),
935 content_pair->part));
937 if (navi_it->content)
938 elm_object_signal_emit(VIEW(navi_it), "elm,state,content,show", "elm");
941 if (navi_it->title_prev_btn)
942 elm_object_signal_emit(VIEW(navi_it), "elm,state,prev_btn,show", "elm");
945 if (navi_it->title_next_btn)
946 elm_object_signal_emit(VIEW(navi_it), "elm,state,next_btn,show", "elm");
948 navi_it->title_visible = EINA_TRUE;
949 _sizing_eval(WIDGET(navi_it));
951 wd = elm_widget_data_get(WIDGET(navi_it));
954 if (wd->freeze_events)
955 evas_object_freeze_events_set(VIEW(navi_it), EINA_FALSE);
958 static Elm_Naviframe_Item *
959 _item_new(Evas_Object *obj,
960 const char *title_label,
961 Evas_Object *prev_btn,
962 Evas_Object *next_btn,
963 Evas_Object *content,
964 const char *item_style)
966 Widget_Data *wd = elm_widget_data_get(obj);
969 Elm_Naviframe_Item *it = elm_widget_item_new(obj, Elm_Naviframe_Item);
972 ERR("Failed to allocate new item! : naviframe=%p", obj);
976 elm_widget_item_del_pre_hook_set(it, _item_del_pre_hook);
977 elm_widget_item_text_set_hook_set(it, _item_text_set_hook);
978 elm_widget_item_text_get_hook_set(it, _item_text_get_hook);
979 elm_widget_item_content_set_hook_set(it, _item_content_set_hook);
980 elm_widget_item_content_get_hook_set(it, _item_content_get_hook);
981 elm_widget_item_content_unset_hook_set(it, _item_content_unset_hook);
982 elm_widget_item_signal_emit_hook_set(it, _item_signal_emit_hook);
985 VIEW(it) = elm_layout_add(obj);
986 evas_object_smart_member_add(VIEW(it), wd->base);
988 evas_object_event_callback_add(VIEW(it),
989 EVAS_CALLBACK_CHANGED_SIZE_HINTS,
992 elm_object_signal_callback_add(VIEW(it),
993 "elm,action,show,finished",
996 elm_object_signal_callback_add(VIEW(it),
997 "elm,action,pushed,finished",
999 _pushed_finished, it);
1000 elm_object_signal_callback_add(VIEW(it),
1001 "elm,action,popped,finished",
1003 _popped_finished, it);
1004 elm_object_signal_callback_add(VIEW(it),
1005 "elm,action,title,clicked",
1007 _title_clicked, it);
1009 _item_style_set(it, item_style);
1010 _item_text_set_hook((Elm_Object_Item *) it, "elm.text.title", title_label);
1013 if ((!prev_btn) && wd->auto_pushed && eina_inlist_count(wd->stack))
1015 prev_btn = _back_btn_new(obj);
1016 _title_prev_btn_set(it, prev_btn, EINA_TRUE);
1019 _title_prev_btn_set(it, prev_btn, EINA_FALSE);
1021 _title_next_btn_set(it, next_btn);
1022 _item_content_set(it, content);
1023 it->title_visible = EINA_TRUE;
1028 _focus_next_hook(const Evas_Object *obj, Elm_Focus_Direction dir, Evas_Object **next)
1030 Widget_Data *wd = elm_widget_data_get(obj);
1031 if (!wd || !wd->stack) return EINA_FALSE;
1032 return elm_widget_focus_next_get(VIEW(elm_naviframe_top_item_get(obj)),
1038 elm_naviframe_add(Evas_Object *parent)
1044 ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL);
1045 ELM_SET_WIDTYPE(widtype, "naviframe");
1046 elm_widget_type_set(obj, "naviframe");
1047 elm_widget_sub_object_add(parent, obj);
1048 elm_widget_data_set(obj, wd);
1049 elm_widget_del_hook_set(obj, _del_hook);
1050 elm_widget_disable_hook_set(obj, _disable_hook);
1051 elm_widget_theme_hook_set(obj, _theme_hook);
1052 elm_widget_signal_emit_hook_set(obj, _emit_hook);
1053 elm_widget_can_focus_set(obj, EINA_FALSE);
1054 elm_widget_focus_next_hook_set(obj, _focus_next_hook);
1057 wd->base = elm_layout_add(parent);
1058 evas_object_event_callback_add(wd->base,
1059 EVAS_CALLBACK_CHANGED_SIZE_HINTS,
1060 _changed_size_hints,
1062 elm_widget_resize_object_set(obj, wd->base);
1063 elm_layout_theme_set(wd->base, "naviframe", "base", "default");
1065 evas_object_event_callback_add(obj, EVAS_CALLBACK_MOVE, _move, obj);
1066 evas_object_event_callback_add(obj, EVAS_CALLBACK_RESIZE, _resize, obj);
1067 evas_object_smart_callbacks_descriptions_set(obj, _signals);
1069 wd->auto_pushed = EINA_TRUE;
1070 wd->freeze_events = EINA_TRUE;
1075 EAPI Elm_Object_Item *
1076 elm_naviframe_item_push(Evas_Object *obj,
1077 const char *title_label,
1078 Evas_Object *prev_btn,
1079 Evas_Object *next_btn,
1080 Evas_Object *content,
1081 const char *item_style)
1083 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1085 Elm_Naviframe_Item *prev_it, *it;
1087 wd = elm_widget_data_get(obj);
1088 if (!wd) return NULL;
1090 it = _item_new(obj, title_label, prev_btn, next_btn, content, item_style);
1091 if (!it) return NULL;
1093 evas_object_show(VIEW(it));
1095 prev_it = (Elm_Naviframe_Item *) elm_naviframe_top_item_get(obj);
1098 if (wd->freeze_events)
1100 evas_object_freeze_events_set(VIEW(it), EINA_TRUE);
1101 evas_object_freeze_events_set(VIEW(prev_it), EINA_TRUE);
1103 elm_object_signal_emit(VIEW(prev_it), "elm,state,cur,pushed", "elm");
1104 elm_object_signal_emit(VIEW(it), "elm,state,new,pushed", "elm");
1105 edje_object_message_signal_process(elm_layout_edje_get(VIEW(prev_it)));
1106 edje_object_message_signal_process(elm_layout_edje_get(VIEW(it)));
1108 wd->stack = eina_inlist_append(wd->stack, EINA_INLIST_GET(it));
1110 return (Elm_Object_Item *) it;
1113 EAPI Elm_Object_Item *
1114 elm_naviframe_item_insert_before(Elm_Object_Item *before,
1115 const char *title_label,
1116 Evas_Object *prev_btn,
1117 Evas_Object *next_btn,
1118 Evas_Object *content,
1119 const char *item_style)
1121 ELM_OBJ_ITEM_CHECK_OR_RETURN(before, NULL);
1122 Elm_Naviframe_Item *it;
1125 wd = elm_widget_data_get(WIDGET(before));
1126 if (!wd) return NULL;
1128 it = _item_new(WIDGET(before), title_label, prev_btn, next_btn, content,
1130 if (!it) return NULL;
1133 eina_inlist_prepend_relative(wd->stack, EINA_INLIST_GET(it),
1134 EINA_INLIST_GET(((Elm_Naviframe_Item *) before)));
1135 _sizing_eval(WIDGET(before));
1136 return (Elm_Object_Item *) it;
1139 EAPI Elm_Object_Item *
1140 elm_naviframe_item_insert_after(Elm_Object_Item *after,
1141 const char *title_label,
1142 Evas_Object *prev_btn,
1143 Evas_Object *next_btn,
1144 Evas_Object *content,
1145 const char *item_style)
1147 ELM_OBJ_ITEM_CHECK_OR_RETURN(after, NULL);
1148 Elm_Naviframe_Item *it;
1151 wd = elm_widget_data_get(WIDGET(after));
1152 if (!wd) return NULL;
1154 it = _item_new(WIDGET(after), title_label, prev_btn, next_btn, content,
1156 if (!it) return NULL;
1158 if (elm_naviframe_top_item_get(WIDGET(after)) == after)
1160 evas_object_hide(VIEW(after));
1161 evas_object_show(VIEW(it));
1164 eina_inlist_append_relative(wd->stack, EINA_INLIST_GET(it),
1165 EINA_INLIST_GET(((Elm_Naviframe_Item *) after)));
1166 _sizing_eval(WIDGET(after));
1167 return (Elm_Object_Item *) it;
1171 elm_naviframe_item_pop(Evas_Object *obj)
1173 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1174 Elm_Naviframe_Item *it, *prev_it = NULL;
1176 Evas_Object *content = NULL;
1178 wd = elm_widget_data_get(obj);
1179 if (!wd) return NULL;
1181 it = (Elm_Naviframe_Item *) elm_naviframe_top_item_get(obj);
1182 if (!it) return NULL;
1183 elm_widget_tree_unfocusable_set(it->content, EINA_TRUE);
1185 content = it->content;
1187 if (wd->stack->last->prev)
1188 prev_it = EINA_INLIST_CONTAINER_GET(wd->stack->last->prev,
1189 Elm_Naviframe_Item);
1190 wd->stack = eina_inlist_remove(wd->stack, EINA_INLIST_GET(it));
1193 if (wd->freeze_events)
1195 evas_object_freeze_events_set(VIEW(it), EINA_TRUE);
1196 evas_object_freeze_events_set(VIEW(prev_it), EINA_TRUE);
1198 elm_object_signal_emit(VIEW(it), "elm,state,cur,popped", "elm");
1199 evas_object_show(VIEW(prev_it));
1200 evas_object_raise(VIEW(prev_it));
1201 elm_object_signal_emit(VIEW(prev_it),
1202 "elm,state,prev,popped",
1204 edje_object_message_signal_process(elm_layout_edje_get(VIEW(it)));
1205 edje_object_message_signal_process(elm_layout_edje_get(VIEW(prev_it)));
1210 elm_widget_item_free(it);
1217 elm_naviframe_item_pop_to(Elm_Object_Item *it)
1219 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1220 Elm_Naviframe_Item *navi_it;
1222 Eina_Inlist *l, *prev_l;
1224 navi_it = (Elm_Naviframe_Item *) it;
1225 wd = elm_widget_data_get(WIDGET(navi_it));
1228 if (it == elm_naviframe_top_item_get(WIDGET(navi_it))) return;
1230 l = wd->stack->last->prev;
1234 if (EINA_INLIST_CONTAINER_GET(l, Elm_Naviframe_Item) ==
1235 ((Elm_Naviframe_Item *) it)) break;
1237 wd->stack = eina_inlist_remove(wd->stack, l);
1238 _item_del(EINA_INLIST_CONTAINER_GET(l, Elm_Naviframe_Item));
1239 elm_widget_item_free(EINA_INLIST_CONTAINER_GET(l,
1240 Elm_Naviframe_Item));
1243 elm_naviframe_item_pop(WIDGET(navi_it));
1247 elm_naviframe_item_promote(Elm_Object_Item *it)
1249 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1250 Elm_Naviframe_Item *navi_it;
1251 Elm_Naviframe_Item *prev_it;
1254 navi_it = (Elm_Naviframe_Item *) it;
1255 wd = elm_widget_data_get(navi_it->base.widget);
1258 if (it == elm_naviframe_top_item_get(navi_it->base.widget)) return;
1259 wd->stack = eina_inlist_demote(wd->stack, EINA_INLIST_GET(navi_it));
1260 prev_it = EINA_INLIST_CONTAINER_GET(wd->stack->last->prev,
1261 Elm_Naviframe_Item);
1262 if (wd->freeze_events)
1264 evas_object_freeze_events_set(VIEW(it), EINA_TRUE);
1265 evas_object_freeze_events_set(VIEW(prev_it), EINA_TRUE);
1267 elm_object_signal_emit(VIEW(prev_it),
1268 "elm,state,cur,pushed",
1270 evas_object_show(VIEW(navi_it));
1271 evas_object_raise(VIEW(navi_it));
1272 elm_object_signal_emit(VIEW(navi_it),
1273 "elm,state,new,pushed",
1275 edje_object_message_signal_process(elm_layout_edje_get(VIEW(prev_it)));
1276 edje_object_message_signal_process(elm_layout_edje_get(VIEW(navi_it)));
1280 elm_naviframe_item_del(Elm_Object_Item *it)
1282 elm_object_item_del(it);
1286 elm_naviframe_content_preserve_on_pop_set(Evas_Object *obj, Eina_Bool preserve)
1288 ELM_CHECK_WIDTYPE(obj, widtype);
1289 Widget_Data *wd = elm_widget_data_get(obj);
1291 wd->preserve = !!preserve;
1295 elm_naviframe_content_preserve_on_pop_get(const Evas_Object *obj)
1297 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
1298 Widget_Data *wd = elm_widget_data_get(obj);
1299 if (!wd) return EINA_FALSE;
1300 return wd->preserve;
1303 EAPI Elm_Object_Item*
1304 elm_naviframe_top_item_get(const Evas_Object *obj)
1306 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1307 Widget_Data *wd = elm_widget_data_get(obj);
1308 if ((!wd) || (!wd->stack)) return NULL;
1309 return (Elm_Object_Item *) (EINA_INLIST_CONTAINER_GET(wd->stack->last,
1310 Elm_Naviframe_Item));
1313 EAPI Elm_Object_Item*
1314 elm_naviframe_bottom_item_get(const Evas_Object *obj)
1316 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1317 Widget_Data *wd = elm_widget_data_get(obj);
1318 if ((!wd) || (!wd->stack)) return NULL;
1319 return (Elm_Object_Item *) (EINA_INLIST_CONTAINER_GET(wd->stack,
1320 Elm_Naviframe_Item));
1324 elm_naviframe_item_style_set(Elm_Object_Item *it, const char *item_style)
1326 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1327 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
1329 //Return if new style is exsiting one.
1331 if (!strcmp(item_style, navi_it->style)) return;
1334 if (!strcmp("basic", navi_it->style)) return;
1336 _item_style_set(navi_it, item_style);
1340 elm_naviframe_item_style_get(const Elm_Object_Item *it)
1342 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
1343 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
1344 return navi_it->style;
1348 elm_naviframe_item_title_visible_set(Elm_Object_Item *it, Eina_Bool visible)
1350 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1351 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
1353 visible = !!visible;
1354 if (navi_it->title_visible == visible) return;
1356 navi_it->title_visible = visible;
1357 _item_title_visible_update(navi_it);
1361 elm_naviframe_item_title_visible_get(const Elm_Object_Item *it)
1363 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
1364 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
1365 return navi_it->title_visible;
1369 elm_naviframe_prev_btn_auto_pushed_set(Evas_Object *obj, Eina_Bool auto_pushed)
1371 ELM_CHECK_WIDTYPE(obj, widtype);
1372 Widget_Data *wd = elm_widget_data_get(obj);
1374 wd->auto_pushed = !!auto_pushed;
1378 elm_naviframe_prev_btn_auto_pushed_get(const Evas_Object *obj)
1380 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
1381 Widget_Data *wd = elm_widget_data_get(obj);
1382 if (!wd) return EINA_FALSE;
1383 return wd->auto_pushed;
1387 elm_naviframe_items_get(const Evas_Object *obj)
1389 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1390 Widget_Data *wd = elm_widget_data_get(obj);
1391 if (!wd) return NULL;
1396 elm_naviframe_event_enabled_set(Evas_Object *obj, Eina_Bool enabled)
1398 ELM_CHECK_WIDTYPE(obj, widtype);
1399 Widget_Data *wd = elm_widget_data_get(obj);
1401 enabled = !!enabled;
1402 if (wd->freeze_events == !enabled) return;
1403 wd->freeze_events = !enabled;
1407 elm_naviframe_event_enabled_get(const Evas_Object *obj)
1409 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
1410 Widget_Data *wd = elm_widget_data_get(obj);
1411 if (!wd) return EINA_FALSE;
1412 return !wd->freeze_events;