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 _pushed_finished(void *data,
133 const char *emission,
135 static void _popped_finished(void *data,
137 const char *emission,
139 static void _show_finished(void *data,
141 const char *emission,
143 static void _changed_size_hints(void *data,
147 static void _item_content_set(Elm_Naviframe_Item *navi_it,
148 Evas_Object *content);
149 static void _item_style_set(Elm_Naviframe_Item *navi_it,
150 const char *item_style);
151 static Elm_Naviframe_Item * _item_new(Evas_Object *obj,
152 const char *title_label,
153 Evas_Object *prev_btn,
154 Evas_Object *next_btn,
155 Evas_Object *content,
156 const char *item_style);
157 static Eina_Bool _focus_next_hook(const Evas_Object *obj,
158 Elm_Focus_Direction dir,
162 _del_hook(Evas_Object *obj)
165 Elm_Naviframe_Item *it;
167 wd = elm_widget_data_get(obj);
172 while (wd->stack->last)
174 it = EINA_INLIST_CONTAINER_GET(wd->stack->last,
176 wd->stack = eina_inlist_remove(wd->stack, wd->stack->last);
178 if (!wd->stack) break;
185 _theme_hook(Evas_Object *obj)
188 Elm_Naviframe_Item *it;
190 wd = elm_widget_data_get(obj);
193 _elm_theme_object_set(obj,
197 elm_widget_style_get(obj));
199 EINA_INLIST_FOREACH(wd->stack, it)
201 _item_style_set(it, it->style);
202 _item_title_visible_update(it);
206 static void _emit_hook(Evas_Object *obj,
207 const char *emission,
210 ELM_CHECK_WIDTYPE(obj, widtype);
212 Widget_Data *wd = elm_widget_data_get(obj);
215 elm_object_signal_emit(wd->base, emission, source);
219 _disable_hook(Evas_Object *obj __UNUSED__)
225 _item_text_set_hook(Elm_Object_Item *it,
229 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
231 Elm_Naviframe_Text_Item_Pair *pair = NULL;
232 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
235 if (!part || !strcmp(part, "default"))
236 snprintf(buf, sizeof(buf), "elm.text.title");
237 else if(!strcmp("subtitle", part))
238 snprintf(buf, sizeof(buf), "elm.text.subtitle");
240 snprintf(buf, sizeof(buf), "%s", part);
242 EINA_INLIST_FOREACH(navi_it->text_list, pair)
243 if (!strcmp(buf, pair->part)) break;
247 pair = ELM_NEW(Elm_Naviframe_Text_Item_Pair);
250 ERR("Failed to allocate new text part of the item! : naviframe=%p",
254 eina_stringshare_replace(&pair->part, buf);
255 navi_it->text_list = eina_inlist_append(navi_it->text_list,
256 EINA_INLIST_GET(pair));
258 elm_object_part_text_set(VIEW(navi_it), buf, label);
262 snprintf(buf, sizeof(buf), "elm,state,%s,show", buf);
263 elm_object_signal_emit(VIEW(navi_it), buf, "elm");
267 snprintf(buf, sizeof(buf), "elm,state,%s,hide", buf);
268 elm_object_signal_emit(VIEW(navi_it), buf, "elm");
271 _sizing_eval(WIDGET(navi_it));
275 _item_text_get_hook(const Elm_Object_Item *it, const char *part)
277 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
280 if (!part || !strcmp(part, "default"))
281 snprintf(buf, sizeof(buf), "elm.text.title");
282 else if(!strcmp("subtitle", part))
283 snprintf(buf, sizeof(buf), "elm.text.subtitle");
285 snprintf(buf, sizeof(buf), "%s", part);
287 return elm_object_part_text_get(VIEW(it), buf);
291 _item_content_set_hook(Elm_Object_Item *it,
293 Evas_Object *content)
295 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
297 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
300 if ((!part) || (!strcmp(part, "elm.swallow.content")))
302 _item_content_set(navi_it, content);
305 else if (!strcmp(part, "elm.swallow.prev_btn"))
307 _title_prev_btn_set(navi_it, content, EINA_FALSE);
310 else if (!strcmp(part, "elm.swallow.next_btn"))
312 _title_next_btn_set(navi_it, content);
315 else if (!strcmp(part, "icon"))
317 _title_icon_set(navi_it, content);
322 _title_content_set(navi_it, part, content);
326 _item_content_get_hook(const Elm_Object_Item *it, const char *part)
328 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
329 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
332 if ((!part) || (!strcmp(part, "elm.swallow.content")))
333 return navi_it->content;
334 else if (!strcmp(part, "elm.swallow.prev_btn"))
335 return navi_it->title_prev_btn;
336 else if (!strcmp(part, "elm.swallow.next_btn"))
337 return navi_it->title_next_btn;
338 else if (!strcmp(part, "icon"))
339 return navi_it->title_icon;
342 return elm_object_part_content_get(VIEW(navi_it), part);
346 _item_content_unset_hook(Elm_Object_Item *it, const char *part)
348 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
349 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
352 if (!part || !strcmp("elm.swallow.content", part))
353 return _item_content_unset(navi_it);
354 else if (!strcmp(part, "elm.swallow.prev_btn"))
355 return _title_prev_btn_unset(navi_it);
356 else if (!strcmp(part, "elm.swallow.next_btn"))
357 return _title_next_btn_unset(navi_it);
358 else if (!strcmp(part, "icon"))
359 return _title_icon_unset(navi_it);
361 return _title_content_unset(navi_it, part);
365 _item_signal_emit_hook(Elm_Object_Item *it,
366 const char *emission,
369 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
370 elm_object_signal_emit(VIEW(it), emission, source);
374 _item_title_visible_update(Elm_Naviframe_Item *navi_it)
376 if (navi_it->title_visible)
377 elm_object_signal_emit(VIEW(navi_it), "elm,state,title,show", "elm");
379 elm_object_signal_emit(VIEW(navi_it), "elm,state,title,hide", "elm");
383 _sizing_eval(Evas_Object *obj)
386 Elm_Naviframe_Item *it;
387 Evas_Coord x, y, w, h;
388 Evas_Coord minw = -1, minh = -1;
390 wd = elm_widget_data_get(obj);
393 evas_object_geometry_get(obj, &x, &y, &w, &h);
395 EINA_INLIST_FOREACH(wd->stack, it)
397 evas_object_move(VIEW(it), x, y);
398 evas_object_resize(VIEW(it), w, h);
399 edje_object_size_min_calc(elm_layout_edje_get(VIEW(it)),
402 if (it->minw > minw) minw = it->minw;
403 if (it->minh > minh) minh = it->minh;
405 evas_object_size_hint_min_set(obj, minw, minh);
406 evas_object_size_hint_max_set(obj, -1, -1);
410 _move(void *data __UNUSED__,
413 void *event_info __UNUSED__)
419 _resize(void *data __UNUSED__,
422 void *event_info __UNUSED__)
428 _title_clicked(void *data,
429 Evas_Object *obj __UNUSED__,
430 const char *emission __UNUSED__,
431 const char *source __UNUSED__)
433 Elm_Naviframe_Item *it = data;
434 evas_object_smart_callback_call(WIDGET(it), SIG_TITLE_CLICKED, it);
438 _back_btn_clicked(void *data,
440 void *event_info __UNUSED__)
442 /* Since edje has the event queue, clicked event could be happend multiple times
443 on some heavy environment. This callback del will prevent those scenario and
444 guarantee only one clicked for it's own page. */
445 evas_object_smart_callback_del(obj, "clicked", _back_btn_clicked);
446 elm_naviframe_item_pop(data);
450 _back_btn_new(Evas_Object *obj)
454 btn = elm_button_add(obj);
455 if (!btn) return NULL;
456 evas_object_smart_callback_add(btn, "clicked", _back_btn_clicked, obj);
457 snprintf(buf, sizeof(buf), "naviframe/back_btn/%s", elm_widget_style_get(obj));
458 elm_object_style_set(btn, buf);
463 _title_content_del(void *data,
465 Evas_Object *obj __UNUSED__,
466 void *event_info __UNUSED__)
469 Elm_Naviframe_Content_Item_Pair *pair = data;
470 Elm_Naviframe_Item *it = pair->it;
471 snprintf(buf, sizeof(buf), "elm,state,%s,hide", pair->part);
472 elm_object_signal_emit(VIEW(it), buf, "elm");
473 it->content_list = eina_inlist_remove(it->content_list,
474 EINA_INLIST_GET(pair));
475 eina_stringshare_del(pair->part);
480 _title_prev_btn_del(void *data,
482 Evas_Object *obj __UNUSED__,
483 void *event_info __UNUSED__)
485 Elm_Naviframe_Item *it = data;
486 it->back_btn = EINA_FALSE;
487 it->title_prev_btn = NULL;
488 elm_object_signal_emit(VIEW(it), "elm,state,prev_btn,hide", "elm");
492 _title_next_btn_del(void *data,
494 Evas_Object *obj __UNUSED__,
495 void *event_info __UNUSED__)
497 Elm_Naviframe_Item *it = data;
498 it->title_next_btn = NULL;
499 elm_object_signal_emit(VIEW(it), "elm,state,next_btn,hide", "elm");
503 _title_icon_del(void *data,
505 Evas_Object *obj __UNUSED__,
506 void *event_info __UNUSED__)
508 Elm_Naviframe_Item *it = data;
509 it->title_icon = NULL;
510 elm_object_signal_emit(VIEW(it), "elm,state,icon,hide", "elm");
514 _item_content_del(void *data,
516 Evas_Object *obj __UNUSED__,
517 void *event_info __UNUSED__)
519 Elm_Naviframe_Item *it = data;
521 elm_object_signal_emit(VIEW(it), "elm,state,content,hide", "elm");
525 _title_content_set(Elm_Naviframe_Item *it,
527 Evas_Object *content)
530 Elm_Naviframe_Content_Item_Pair *pair = NULL;
531 Evas_Object *prev_content = NULL;
533 EINA_INLIST_FOREACH(it->content_list, pair)
534 if (!strcmp(part, pair->part)) break;
538 prev_content = elm_object_part_content_get(VIEW(it), part);
539 if (prev_content != content)
543 evas_object_event_callback_del(prev_content,
546 snprintf(buf, sizeof(buf), "elm,state,%s,hide", part);
547 elm_object_signal_emit(VIEW(it), buf, "elm");
549 evas_object_del(prev_content);
550 if (!content) return;
555 if (!content) return;
556 pair = ELM_NEW(Elm_Naviframe_Content_Item_Pair);
559 ERR("Failed to allocate new content part of the item! : naviframe=%p", WIDGET(it));
563 eina_stringshare_replace(&pair->part, part);
564 it->content_list = eina_inlist_append(it->content_list,
565 EINA_INLIST_GET(pair));
567 if (prev_content != content)
569 evas_object_event_callback_add(content,
574 elm_object_part_content_set(VIEW(it), part, content);
575 snprintf(buf, sizeof(buf), "elm,state,%s,show", part);
576 elm_object_signal_emit(VIEW(it), buf, "elm");
578 _sizing_eval(WIDGET(it));
582 _title_prev_btn_set(Elm_Naviframe_Item *it,
586 if (it->title_prev_btn == btn) return;
587 if (it->title_prev_btn) evas_object_del(it->title_prev_btn);
588 it->title_prev_btn = btn;
591 evas_object_event_callback_add(btn,
595 elm_object_part_content_set(VIEW(it), "elm.swallow.prev_btn", btn);
596 elm_object_signal_emit(VIEW(it), "elm,state,prev_btn,show", "elm");
597 it->back_btn = back_btn;
599 _sizing_eval(WIDGET(it));
603 _title_next_btn_set(Elm_Naviframe_Item *it, Evas_Object *btn)
605 if (it->title_next_btn == btn) return;
606 if (it->title_next_btn) evas_object_del(it->title_next_btn);
607 it->title_next_btn = btn;
610 evas_object_event_callback_add(btn,
614 elm_object_part_content_set(VIEW(it), "elm.swallow.next_btn", btn);
615 elm_object_signal_emit(VIEW(it), "elm,state,next_btn,show", "elm");
617 _sizing_eval(WIDGET(it));
621 _title_icon_set(Elm_Naviframe_Item *it, Evas_Object *icon)
623 if (it->title_icon == icon) return;
624 if (it->title_icon) evas_object_del(it->title_icon);
625 it->title_icon = icon;
628 evas_object_event_callback_add(icon,
632 elm_object_part_content_set(VIEW(it), "elm.swallow.icon", icon);
633 elm_object_signal_emit(VIEW(it), "elm,state,icon,show", "elm");
635 _sizing_eval(WIDGET(it));
639 _item_content_unset(Elm_Naviframe_Item *it)
641 Evas_Object *content = it->content;
642 if (!content) return NULL;
644 elm_object_part_content_unset(VIEW(it), "elm.swallow.content");
645 elm_object_signal_emit(VIEW(it), "elm,state,content,hide", "elm");
646 evas_object_event_callback_del(content,
649 _sizing_eval(WIDGET(it));
656 _title_prev_btn_unset(Elm_Naviframe_Item *it)
658 Evas_Object *content = it->title_prev_btn;
659 if (!content) return NULL;
661 elm_object_part_content_unset(VIEW(it), "elm.swallow.prev_btn");
662 elm_object_signal_emit(VIEW(it), "elm,state,prev_btn,hide", "elm");
663 evas_object_event_callback_del(content,
665 _title_prev_btn_del);
666 _sizing_eval(WIDGET(it));
668 it->title_prev_btn = NULL;
673 _title_next_btn_unset(Elm_Naviframe_Item *it)
675 Evas_Object *content = it->title_next_btn;
676 if (!content) return NULL;
678 elm_object_part_content_unset(VIEW(it), "elm.swallow.next_btn");
679 elm_object_signal_emit(VIEW(it), "elm,state,next_btn,hide", "elm");
680 evas_object_event_callback_del(content,
682 _title_next_btn_del);
683 _sizing_eval(WIDGET(it));
685 it->title_next_btn = NULL;
690 _title_icon_unset(Elm_Naviframe_Item *it)
692 Evas_Object *content = it->title_icon;
693 if (!content) return NULL;
695 elm_object_part_content_unset(VIEW(it), "elm.swallow.icon");
696 elm_object_signal_emit(VIEW(it), "elm,state,icon,hide", "elm");
697 evas_object_event_callback_del(content,
700 _sizing_eval(WIDGET(it));
701 it->title_icon = NULL;
707 _title_content_unset(Elm_Naviframe_Item *it, const char *part)
709 Elm_Naviframe_Content_Item_Pair *pair = NULL;
711 Evas_Object *content = NULL;
713 EINA_INLIST_FOREACH(it->content_list, pair)
715 if (!strcmp(part, pair->part))
717 content = elm_object_part_content_get(VIEW(it), part);
718 eina_stringshare_del(pair->part);
719 it->content_list = eina_inlist_remove(it->content_list,
720 EINA_INLIST_GET(pair));
726 if (!content) return NULL;
728 elm_object_part_content_unset(VIEW(it), part);
729 snprintf(buf, sizeof(buf), "elm,state,%s,hide", part);
730 elm_object_signal_emit(VIEW(it), buf, "elm");
731 evas_object_event_callback_del(content,
734 _sizing_eval(WIDGET(it));
740 _item_del(Elm_Naviframe_Item *it)
743 Elm_Naviframe_Content_Item_Pair *content_pair;
744 Elm_Naviframe_Text_Item_Pair *text_pair;
745 Evas_Object *content;
749 wd = elm_widget_data_get(WIDGET(it));
752 while (it->content_list)
755 EINA_INLIST_CONTAINER_GET(it->content_list,
756 Elm_Naviframe_Content_Item_Pair);
757 content = elm_object_part_content_get(VIEW(it), content_pair->part);
758 evas_object_event_callback_del(content,
761 eina_stringshare_del(content_pair->part);
762 it->content_list = eina_inlist_remove(it->content_list,
767 while (it->text_list)
769 text_pair = EINA_INLIST_CONTAINER_GET(it->text_list,
770 Elm_Naviframe_Text_Item_Pair);
771 eina_stringshare_del(text_pair->part);
772 it->text_list = eina_inlist_remove(it->text_list,
777 eina_stringshare_del(it->style);
779 elm_widget_item_del(it);
783 _pushed_finished(void *data,
784 Evas_Object *obj __UNUSED__,
785 const char *emission __UNUSED__,
786 const char *source __UNUSED__)
789 Elm_Naviframe_Item *it = data;
792 wd = elm_widget_data_get(WIDGET(it));
795 evas_object_hide(VIEW(it));
796 evas_object_smart_callback_call(WIDGET(it),
799 if (wd->freeze_events)
800 evas_object_freeze_events_set(VIEW(it), EINA_FALSE);
804 _popped_finished(void *data,
805 Evas_Object *obj __UNUSED__,
806 const char *emission __UNUSED__,
807 const char *source __UNUSED__)
809 Elm_Naviframe_Item *it = data;
811 evas_object_smart_callback_call(WIDGET(it),
818 _show_finished(void *data,
819 Evas_Object *obj __UNUSED__,
820 const char *emission __UNUSED__,
821 const char *source __UNUSED__)
823 Elm_Naviframe_Item *it;
828 wd = elm_widget_data_get(WIDGET(it));
831 evas_object_smart_callback_call(WIDGET(it),
832 SIG_TRANSITION_FINISHED,
834 if (wd->freeze_events)
835 evas_object_freeze_events_set(VIEW(it), EINA_FALSE);
839 _changed_size_hints(void *data,
841 Evas_Object *obj __UNUSED__,
842 void *event_info __UNUSED__)
848 _item_content_set(Elm_Naviframe_Item *navi_it, Evas_Object *content)
850 if (navi_it->content == content) return;
851 if (navi_it->content) evas_object_del(navi_it->content);
852 elm_object_part_content_set(VIEW(navi_it), "elm.swallow.content", content);
855 elm_object_signal_emit(VIEW(navi_it), "elm,state,content,show", "elm");
857 elm_object_signal_emit(VIEW(navi_it), "elm,state,content,hide", "elm");
859 evas_object_event_callback_add(content,
863 navi_it->content = content;
864 _sizing_eval(WIDGET(navi_it));
867 //FIXME: need to handle if this function is called while transition
869 _item_style_set(Elm_Naviframe_Item *navi_it, const char *item_style)
871 Elm_Naviframe_Content_Item_Pair *content_pair;
872 Elm_Naviframe_Text_Item_Pair *text_pair;
879 strcpy(buf, "item/basic");
880 eina_stringshare_replace(&navi_it->style, "basic");
884 snprintf(buf, sizeof(buf), "item/%s", item_style);
885 eina_stringshare_replace(&navi_it->style, item_style);
887 elm_layout_theme_set(VIEW(navi_it),
890 elm_widget_style_get(WIDGET(navi_it)));
892 EINA_INLIST_FOREACH(navi_it->text_list, text_pair)
893 _item_text_set_hook((Elm_Object_Item *) navi_it,
895 elm_object_part_text_get(VIEW(navi_it),
898 EINA_INLIST_FOREACH(navi_it->content_list, content_pair)
899 _item_content_set_hook((Elm_Object_Item *) navi_it,
901 elm_object_part_content_get(VIEW(navi_it),
902 content_pair->part));
904 if (navi_it->content)
905 elm_object_signal_emit(VIEW(navi_it), "elm,state,content,show", "elm");
908 if (navi_it->title_prev_btn)
909 elm_object_signal_emit(VIEW(navi_it), "elm,state,prev_btn,show", "elm");
912 if (navi_it->title_next_btn)
913 elm_object_signal_emit(VIEW(navi_it), "elm,state,next_btn,show", "elm");
915 navi_it->title_visible = EINA_TRUE;
916 _sizing_eval(WIDGET(navi_it));
918 wd = elm_widget_data_get(WIDGET(navi_it));
921 if (wd->freeze_events)
922 evas_object_freeze_events_set(VIEW(navi_it), EINA_FALSE);
925 static Elm_Naviframe_Item *
926 _item_new(Evas_Object *obj,
927 const char *title_label,
928 Evas_Object *prev_btn,
929 Evas_Object *next_btn,
930 Evas_Object *content,
931 const char *item_style)
933 Widget_Data *wd = elm_widget_data_get(obj);
936 Elm_Naviframe_Item *it = elm_widget_item_new(obj, Elm_Naviframe_Item);
939 ERR("Failed to allocate new item! : naviframe=%p", obj);
943 elm_widget_item_text_set_hook_set(it, _item_text_set_hook);
944 elm_widget_item_text_get_hook_set(it, _item_text_get_hook);
945 elm_widget_item_content_set_hook_set(it, _item_content_set_hook);
946 elm_widget_item_content_get_hook_set(it, _item_content_get_hook);
947 elm_widget_item_content_unset_hook_set(it, _item_content_unset_hook);
948 elm_widget_item_signal_emit_hook_set(it, _item_signal_emit_hook);
951 VIEW(it) = elm_layout_add(obj);
952 evas_object_smart_member_add(VIEW(it), wd->base);
954 evas_object_event_callback_add(VIEW(it),
955 EVAS_CALLBACK_CHANGED_SIZE_HINTS,
958 elm_object_signal_callback_add(VIEW(it),
959 "elm,action,show,finished",
962 elm_object_signal_callback_add(VIEW(it),
963 "elm,action,pushed,finished",
965 _pushed_finished, it);
966 elm_object_signal_callback_add(VIEW(it),
967 "elm,action,popped,finished",
969 _popped_finished, it);
970 elm_object_signal_callback_add(VIEW(it),
971 "elm,action,title,clicked",
975 _item_style_set(it, item_style);
976 _item_text_set_hook((Elm_Object_Item *) it, "elm.text.title", title_label);
979 if ((!prev_btn) && wd->auto_pushed && eina_inlist_count(wd->stack))
981 prev_btn = _back_btn_new(obj);
982 _title_prev_btn_set(it, prev_btn, EINA_TRUE);
985 _title_prev_btn_set(it, prev_btn, EINA_FALSE);
987 _title_next_btn_set(it, next_btn);
988 _item_content_set(it, content);
989 it->title_visible = EINA_TRUE;
994 _focus_next_hook(const Evas_Object *obj, Elm_Focus_Direction dir, Evas_Object **next)
996 Widget_Data *wd = elm_widget_data_get(obj);
997 if (!wd || !wd->stack) return EINA_FALSE;
998 return elm_widget_focus_next_get(VIEW(elm_naviframe_top_item_get(obj)),
1004 elm_naviframe_add(Evas_Object *parent)
1010 ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL);
1011 ELM_SET_WIDTYPE(widtype, "naviframe");
1012 elm_widget_type_set(obj, "naviframe");
1013 elm_widget_sub_object_add(parent, obj);
1014 elm_widget_data_set(obj, wd);
1015 elm_widget_del_hook_set(obj, _del_hook);
1016 elm_widget_disable_hook_set(obj, _disable_hook);
1017 elm_widget_theme_hook_set(obj, _theme_hook);
1018 elm_widget_signal_emit_hook_set(obj, _emit_hook);
1019 elm_widget_can_focus_set(obj, EINA_FALSE);
1020 elm_widget_focus_next_hook_set(obj, _focus_next_hook);
1023 wd->base = elm_layout_add(parent);
1024 evas_object_event_callback_add(wd->base,
1025 EVAS_CALLBACK_CHANGED_SIZE_HINTS,
1026 _changed_size_hints,
1028 elm_widget_resize_object_set(obj, wd->base);
1029 elm_layout_theme_set(wd->base, "naviframe", "base", "default");
1031 evas_object_event_callback_add(obj, EVAS_CALLBACK_MOVE, _move, obj);
1032 evas_object_event_callback_add(obj, EVAS_CALLBACK_RESIZE, _resize, obj);
1033 evas_object_smart_callbacks_descriptions_set(obj, _signals);
1035 wd->auto_pushed = EINA_TRUE;
1036 wd->freeze_events = EINA_TRUE;
1041 EAPI Elm_Object_Item *
1042 elm_naviframe_item_push(Evas_Object *obj,
1043 const char *title_label,
1044 Evas_Object *prev_btn,
1045 Evas_Object *next_btn,
1046 Evas_Object *content,
1047 const char *item_style)
1049 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1051 Elm_Naviframe_Item *prev_it, *it;
1053 wd = elm_widget_data_get(obj);
1054 if (!wd) return NULL;
1056 it = _item_new(obj, title_label, prev_btn, next_btn, content, item_style);
1057 if (!it) return NULL;
1059 evas_object_show(VIEW(it));
1061 prev_it = (Elm_Naviframe_Item *) elm_naviframe_top_item_get(obj);
1064 if (wd->freeze_events)
1066 evas_object_freeze_events_set(VIEW(it), EINA_TRUE);
1067 evas_object_freeze_events_set(VIEW(prev_it), EINA_TRUE);
1069 elm_object_signal_emit(VIEW(prev_it), "elm,state,cur,pushed", "elm");
1070 elm_object_signal_emit(VIEW(it), "elm,state,new,pushed", "elm");
1071 edje_object_message_signal_process(elm_layout_edje_get(VIEW(prev_it)));
1072 edje_object_message_signal_process(elm_layout_edje_get(VIEW(it)));
1074 wd->stack = eina_inlist_append(wd->stack, EINA_INLIST_GET(it));
1076 return (Elm_Object_Item *) it;
1079 EAPI Elm_Object_Item *
1080 elm_naviframe_item_insert_before(Elm_Object_Item *before,
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 ELM_OBJ_ITEM_CHECK_OR_RETURN(before, NULL);
1088 Elm_Naviframe_Item *it;
1091 wd = elm_widget_data_get(WIDGET(before));
1092 if (!wd) return NULL;
1094 it = _item_new(WIDGET(before), title_label, prev_btn, next_btn, content,
1096 if (!it) return NULL;
1099 eina_inlist_prepend_relative(wd->stack, EINA_INLIST_GET(it),
1100 EINA_INLIST_GET(((Elm_Naviframe_Item *) before)));
1101 _sizing_eval(WIDGET(before));
1102 return (Elm_Object_Item *) it;
1105 EAPI Elm_Object_Item *
1106 elm_naviframe_item_insert_after(Elm_Object_Item *after,
1107 const char *title_label,
1108 Evas_Object *prev_btn,
1109 Evas_Object *next_btn,
1110 Evas_Object *content,
1111 const char *item_style)
1113 ELM_OBJ_ITEM_CHECK_OR_RETURN(after, NULL);
1114 Elm_Naviframe_Item *it;
1117 wd = elm_widget_data_get(WIDGET(after));
1118 if (!wd) return NULL;
1120 it = _item_new(WIDGET(after), title_label, prev_btn, next_btn, content,
1122 if (!it) return NULL;
1124 if (elm_naviframe_top_item_get(WIDGET(after)) == after)
1126 evas_object_hide(VIEW(after));
1127 evas_object_show(VIEW(it));
1130 eina_inlist_append_relative(wd->stack, EINA_INLIST_GET(it),
1131 EINA_INLIST_GET(((Elm_Naviframe_Item *) after)));
1132 _sizing_eval(WIDGET(after));
1133 return (Elm_Object_Item *) it;
1137 elm_naviframe_item_pop(Evas_Object *obj)
1139 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1140 Elm_Naviframe_Item *it, *prev_it = NULL;
1142 Evas_Object *content = NULL;
1144 wd = elm_widget_data_get(obj);
1145 if (!wd) return NULL;
1147 it = (Elm_Naviframe_Item *) elm_naviframe_top_item_get(obj);
1148 if (!it) return NULL;
1149 elm_widget_tree_unfocusable_set(it->content, EINA_TRUE);
1151 content = it->content;
1153 if (wd->stack->last->prev)
1154 prev_it = EINA_INLIST_CONTAINER_GET(wd->stack->last->prev,
1155 Elm_Naviframe_Item);
1156 wd->stack = eina_inlist_remove(wd->stack, EINA_INLIST_GET(it));
1159 if (wd->freeze_events)
1161 evas_object_freeze_events_set(VIEW(it), EINA_TRUE);
1162 evas_object_freeze_events_set(VIEW(prev_it), EINA_TRUE);
1164 elm_object_signal_emit(VIEW(it), "elm,state,cur,popped", "elm");
1165 evas_object_show(VIEW(prev_it));
1166 evas_object_raise(VIEW(prev_it));
1167 elm_object_signal_emit(VIEW(prev_it),
1168 "elm,state,prev,popped",
1170 edje_object_message_signal_process(elm_layout_edje_get(VIEW(it)));
1171 edje_object_message_signal_process(elm_layout_edje_get(VIEW(prev_it)));
1180 elm_naviframe_item_pop_to(Elm_Object_Item *it)
1182 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1183 Elm_Naviframe_Item *navi_it;
1185 Eina_Inlist *l, *prev_l;
1187 navi_it = (Elm_Naviframe_Item *) it;
1188 wd = elm_widget_data_get(WIDGET(navi_it));
1191 if (it == elm_naviframe_top_item_get(WIDGET(navi_it))) return;
1193 l = wd->stack->last->prev;
1197 if (EINA_INLIST_CONTAINER_GET(l, Elm_Naviframe_Item) ==
1198 ((Elm_Naviframe_Item *) it)) break;
1200 wd->stack = eina_inlist_remove(wd->stack, l);
1201 _item_del(EINA_INLIST_CONTAINER_GET(l, Elm_Naviframe_Item));
1204 elm_naviframe_item_pop(WIDGET(navi_it));
1208 elm_naviframe_item_promote(Elm_Object_Item *it)
1210 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1211 Elm_Naviframe_Item *navi_it;
1212 Elm_Naviframe_Item *prev_it;
1215 navi_it = (Elm_Naviframe_Item *) it;
1216 wd = elm_widget_data_get(navi_it->base.widget);
1219 if (it == elm_naviframe_top_item_get(navi_it->base.widget)) return;
1220 wd->stack = eina_inlist_demote(wd->stack, EINA_INLIST_GET(navi_it));
1221 prev_it = EINA_INLIST_CONTAINER_GET(wd->stack->last->prev,
1222 Elm_Naviframe_Item);
1223 if (wd->freeze_events)
1225 evas_object_freeze_events_set(VIEW(it), EINA_TRUE);
1226 evas_object_freeze_events_set(VIEW(prev_it), EINA_TRUE);
1228 elm_object_signal_emit(VIEW(prev_it),
1229 "elm,state,cur,pushed",
1231 evas_object_show(VIEW(navi_it));
1232 evas_object_raise(VIEW(navi_it));
1233 elm_object_signal_emit(VIEW(navi_it),
1234 "elm,state,new,pushed",
1236 edje_object_message_signal_process(elm_layout_edje_get(VIEW(prev_it)));
1237 edje_object_message_signal_process(elm_layout_edje_get(VIEW(navi_it)));
1241 elm_naviframe_item_del(Elm_Object_Item *it)
1243 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1244 Elm_Naviframe_Item *navi_it;
1247 navi_it =(Elm_Naviframe_Item *) it;
1248 wd = elm_widget_data_get(WIDGET(navi_it));
1251 if (it == elm_naviframe_top_item_get(WIDGET(navi_it)))
1253 wd->stack = eina_inlist_remove(wd->stack, EINA_INLIST_GET(navi_it));
1255 //If the item is only one, the stack will be empty
1256 if (!wd->stack) return;
1257 navi_it = EINA_INLIST_CONTAINER_GET(wd->stack->last,
1258 Elm_Naviframe_Item);
1259 evas_object_show(VIEW(navi_it));
1260 evas_object_raise(VIEW(navi_it));
1261 elm_object_signal_emit(VIEW(navi_it), "elm,state,visible", "elm");
1265 wd->stack = eina_inlist_remove(wd->stack, EINA_INLIST_GET(navi_it));
1271 elm_naviframe_content_preserve_on_pop_set(Evas_Object *obj, Eina_Bool preserve)
1273 ELM_CHECK_WIDTYPE(obj, widtype);
1274 Widget_Data *wd = elm_widget_data_get(obj);
1276 wd->preserve = !!preserve;
1280 elm_naviframe_content_preserve_on_pop_get(const Evas_Object *obj)
1282 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
1283 Widget_Data *wd = elm_widget_data_get(obj);
1284 if (!wd) return EINA_FALSE;
1285 return wd->preserve;
1288 EAPI Elm_Object_Item*
1289 elm_naviframe_top_item_get(const Evas_Object *obj)
1291 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1292 Widget_Data *wd = elm_widget_data_get(obj);
1293 if ((!wd) || (!wd->stack)) return NULL;
1294 return (Elm_Object_Item *) (EINA_INLIST_CONTAINER_GET(wd->stack->last,
1295 Elm_Naviframe_Item));
1298 EAPI Elm_Object_Item*
1299 elm_naviframe_bottom_item_get(const Evas_Object *obj)
1301 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1302 Widget_Data *wd = elm_widget_data_get(obj);
1303 if ((!wd) || (!wd->stack)) return NULL;
1304 return (Elm_Object_Item *) (EINA_INLIST_CONTAINER_GET(wd->stack,
1305 Elm_Naviframe_Item));
1309 elm_naviframe_item_style_set(Elm_Object_Item *it, const char *item_style)
1311 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1312 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
1314 //Return if new style is exsiting one.
1316 if (!strcmp(item_style, navi_it->style)) return;
1319 if (!strcmp("basic", navi_it->style)) return;
1321 _item_style_set(navi_it, item_style);
1325 elm_naviframe_item_style_get(const Elm_Object_Item *it)
1327 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
1328 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
1329 return navi_it->style;
1333 elm_naviframe_item_title_visible_set(Elm_Object_Item *it, Eina_Bool visible)
1335 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1336 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
1338 visible = !!visible;
1339 if (navi_it->title_visible == visible) return;
1341 navi_it->title_visible = visible;
1342 _item_title_visible_update(navi_it);
1346 elm_naviframe_item_title_visible_get(const Elm_Object_Item *it)
1348 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
1349 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
1350 return navi_it->title_visible;
1354 elm_naviframe_prev_btn_auto_pushed_set(Evas_Object *obj, Eina_Bool auto_pushed)
1356 ELM_CHECK_WIDTYPE(obj, widtype);
1357 Widget_Data *wd = elm_widget_data_get(obj);
1359 wd->auto_pushed = !!auto_pushed;
1363 elm_naviframe_prev_btn_auto_pushed_get(const Evas_Object *obj)
1365 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
1366 Widget_Data *wd = elm_widget_data_get(obj);
1367 if (!wd) return EINA_FALSE;
1368 return wd->auto_pushed;
1372 elm_naviframe_items_get(const Evas_Object *obj)
1374 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1375 Widget_Data *wd = elm_widget_data_get(obj);
1376 if (!wd) return NULL;
1381 elm_naviframe_event_enabled_set(Evas_Object *obj, Eina_Bool enabled)
1383 ELM_CHECK_WIDTYPE(obj, widtype);
1384 Widget_Data *wd = elm_widget_data_get(obj);
1386 enabled = !!enabled;
1387 if (wd->freeze_events == !enabled) return;
1388 wd->freeze_events = !enabled;
1392 elm_naviframe_event_enabled_get(const Evas_Object *obj)
1394 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
1395 Widget_Data *wd = elm_widget_data_get(obj);
1396 if (!wd) return EINA_FALSE;
1397 return !wd->freeze_events;