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);
160 _del_hook(Evas_Object *obj)
163 Elm_Naviframe_Item *it;
165 wd = elm_widget_data_get(obj);
170 while (wd->stack->last)
172 it = EINA_INLIST_CONTAINER_GET(wd->stack->last,
174 wd->stack = eina_inlist_remove(wd->stack, wd->stack->last);
176 elm_widget_item_free(it);
177 if (!wd->stack) break;
184 _theme_hook(Evas_Object *obj)
187 Elm_Naviframe_Item *it;
189 wd = elm_widget_data_get(obj);
192 _elm_theme_object_set(obj,
196 elm_widget_style_get(obj));
198 EINA_INLIST_FOREACH(wd->stack, it)
200 _item_style_set(it, it->style);
201 _item_title_visible_update(it);
205 static void _emit_hook(Evas_Object *obj,
206 const char *emission,
209 ELM_CHECK_WIDTYPE(obj, widtype);
211 Widget_Data *wd = elm_widget_data_get(obj);
214 elm_object_signal_emit(wd->base, emission, source);
218 _disable_hook(Evas_Object *obj __UNUSED__)
224 _item_text_set_hook(Elm_Object_Item *it,
228 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
230 Elm_Naviframe_Text_Item_Pair *pair = NULL;
231 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
234 if (!part || !strcmp(part, "default"))
235 snprintf(buf, sizeof(buf), "elm.text.title");
236 else if(!strcmp("subtitle", part))
237 snprintf(buf, sizeof(buf), "elm.text.subtitle");
239 snprintf(buf, sizeof(buf), "%s", part);
241 EINA_INLIST_FOREACH(navi_it->text_list, pair)
242 if (!strcmp(buf, pair->part)) break;
246 pair = ELM_NEW(Elm_Naviframe_Text_Item_Pair);
249 ERR("Failed to allocate new text part of the item! : naviframe=%p",
253 eina_stringshare_replace(&pair->part, buf);
254 navi_it->text_list = eina_inlist_append(navi_it->text_list,
255 EINA_INLIST_GET(pair));
257 elm_object_part_text_set(VIEW(navi_it), buf, label);
261 snprintf(buf, sizeof(buf), "elm,state,%s,show", buf);
262 elm_object_signal_emit(VIEW(navi_it), buf, "elm");
266 snprintf(buf, sizeof(buf), "elm,state,%s,hide", buf);
267 elm_object_signal_emit(VIEW(navi_it), buf, "elm");
270 _sizing_eval(WIDGET(navi_it));
274 _item_text_get_hook(const Elm_Object_Item *it, const char *part)
276 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
279 if (!part || !strcmp(part, "default"))
280 snprintf(buf, sizeof(buf), "elm.text.title");
281 else if(!strcmp("subtitle", part))
282 snprintf(buf, sizeof(buf), "elm.text.subtitle");
284 snprintf(buf, sizeof(buf), "%s", part);
286 return elm_object_part_text_get(VIEW(it), buf);
290 _item_content_set_hook(Elm_Object_Item *it,
292 Evas_Object *content)
294 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
296 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
299 if (!part || !strcmp("default", part))
301 _item_content_set(navi_it, content);
304 else if (!strcmp(part, "prev_btn"))
306 _title_prev_btn_set(navi_it, content, EINA_FALSE);
309 else if (!strcmp(part, "next_btn"))
311 _title_next_btn_set(navi_it, content);
314 else if (!strcmp(part, "icon"))
316 _title_icon_set(navi_it, content);
321 _title_content_set(navi_it, part, content);
325 _item_content_get_hook(const Elm_Object_Item *it, const char *part)
327 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
328 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
331 if (!part || !strcmp("default", part))
332 return navi_it->content;
333 else if (!strcmp(part, "prev_btn"))
334 return navi_it->title_prev_btn;
335 else if (!strcmp(part, "next_btn"))
336 return navi_it->title_next_btn;
337 else if (!strcmp(part, "icon"))
338 return navi_it->title_icon;
341 return elm_object_part_content_get(VIEW(navi_it), part);
345 _item_content_unset_hook(Elm_Object_Item *it, const char *part)
347 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
348 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
351 if (!part || !strcmp("default", part))
352 return _item_content_unset(navi_it);
353 else if (!strcmp(part, "prev_btn"))
354 return _title_prev_btn_unset(navi_it);
355 else if (!strcmp(part, "next_btn"))
356 return _title_next_btn_unset(navi_it);
357 else if (!strcmp(part, "icon"))
358 return _title_icon_unset(navi_it);
360 return _title_content_unset(navi_it, part);
364 _item_signal_emit_hook(Elm_Object_Item *it,
365 const char *emission,
368 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
369 elm_object_signal_emit(VIEW(it), emission, source);
373 _item_title_visible_update(Elm_Naviframe_Item *navi_it)
375 if (navi_it->title_visible)
376 elm_object_signal_emit(VIEW(navi_it), "elm,state,title,show", "elm");
378 elm_object_signal_emit(VIEW(navi_it), "elm,state,title,hide", "elm");
382 _sizing_eval(Evas_Object *obj)
385 Elm_Naviframe_Item *it;
386 Evas_Coord x, y, w, h;
387 Evas_Coord minw = -1, minh = -1;
389 wd = elm_widget_data_get(obj);
392 evas_object_geometry_get(obj, &x, &y, &w, &h);
394 EINA_INLIST_FOREACH(wd->stack, it)
396 evas_object_move(VIEW(it), x, y);
397 evas_object_resize(VIEW(it), w, h);
398 edje_object_size_min_calc(elm_layout_edje_get(VIEW(it)),
401 if (it->minw > minw) minw = it->minw;
402 if (it->minh > minh) minh = it->minh;
404 evas_object_size_hint_min_set(obj, minw, minh);
405 evas_object_size_hint_max_set(obj, -1, -1);
409 _move(void *data __UNUSED__,
412 void *event_info __UNUSED__)
418 _resize(void *data __UNUSED__,
421 void *event_info __UNUSED__)
427 _title_clicked(void *data,
428 Evas_Object *obj __UNUSED__,
429 const char *emission __UNUSED__,
430 const char *source __UNUSED__)
432 Elm_Naviframe_Item *it = data;
433 evas_object_smart_callback_call(WIDGET(it), SIG_TITLE_CLICKED, it);
437 _back_btn_clicked(void *data,
439 void *event_info __UNUSED__)
441 /* Since edje has the event queue, clicked event could be happend multiple times
442 on some heavy environment. This callback del will prevent those scenario and
443 guarantee only one clicked for it's own page. */
444 evas_object_smart_callback_del(obj, "clicked", _back_btn_clicked);
445 elm_naviframe_item_pop(data);
449 _back_btn_new(Evas_Object *obj)
453 btn = elm_button_add(obj);
454 if (!btn) return NULL;
455 evas_object_smart_callback_add(btn, "clicked", _back_btn_clicked, obj);
456 snprintf(buf, sizeof(buf), "naviframe/back_btn/%s", elm_widget_style_get(obj));
457 elm_object_style_set(btn, buf);
462 _title_content_del(void *data,
464 Evas_Object *obj __UNUSED__,
465 void *event_info __UNUSED__)
468 Elm_Naviframe_Content_Item_Pair *pair = data;
469 Elm_Naviframe_Item *it = pair->it;
470 snprintf(buf, sizeof(buf), "elm,state,%s,hide", pair->part);
471 elm_object_signal_emit(VIEW(it), buf, "elm");
472 it->content_list = eina_inlist_remove(it->content_list,
473 EINA_INLIST_GET(pair));
474 eina_stringshare_del(pair->part);
479 _title_prev_btn_del(void *data,
481 Evas_Object *obj __UNUSED__,
482 void *event_info __UNUSED__)
484 Elm_Naviframe_Item *it = data;
485 it->back_btn = EINA_FALSE;
486 it->title_prev_btn = NULL;
487 elm_object_signal_emit(VIEW(it), "elm,state,prev_btn,hide", "elm");
491 _title_next_btn_del(void *data,
493 Evas_Object *obj __UNUSED__,
494 void *event_info __UNUSED__)
496 Elm_Naviframe_Item *it = data;
497 it->title_next_btn = NULL;
498 elm_object_signal_emit(VIEW(it), "elm,state,next_btn,hide", "elm");
502 _title_icon_del(void *data,
504 Evas_Object *obj __UNUSED__,
505 void *event_info __UNUSED__)
507 Elm_Naviframe_Item *it = data;
508 it->title_icon = NULL;
509 elm_object_signal_emit(VIEW(it), "elm,state,icon,hide", "elm");
513 _item_content_del(void *data,
515 Evas_Object *obj __UNUSED__,
516 void *event_info __UNUSED__)
518 Elm_Naviframe_Item *it = data;
520 elm_object_signal_emit(VIEW(it), "elm,state,content,hide", "elm");
524 _title_content_set(Elm_Naviframe_Item *it,
526 Evas_Object *content)
529 Elm_Naviframe_Content_Item_Pair *pair = NULL;
530 Evas_Object *prev_content = NULL;
532 EINA_INLIST_FOREACH(it->content_list, pair)
533 if (!strcmp(part, pair->part)) break;
537 prev_content = elm_object_part_content_get(VIEW(it), part);
538 if (prev_content != content)
542 evas_object_event_callback_del(prev_content,
545 snprintf(buf, sizeof(buf), "elm,state,%s,hide", part);
546 elm_object_signal_emit(VIEW(it), buf, "elm");
548 evas_object_del(prev_content);
549 if (!content) return;
554 if (!content) return;
555 pair = ELM_NEW(Elm_Naviframe_Content_Item_Pair);
558 ERR("Failed to allocate new content part of the item! : naviframe=%p", WIDGET(it));
562 eina_stringshare_replace(&pair->part, part);
563 it->content_list = eina_inlist_append(it->content_list,
564 EINA_INLIST_GET(pair));
566 if (prev_content != content)
568 evas_object_event_callback_add(content,
573 elm_object_part_content_set(VIEW(it), part, content);
574 snprintf(buf, sizeof(buf), "elm,state,%s,show", part);
575 elm_object_signal_emit(VIEW(it), buf, "elm");
577 _sizing_eval(WIDGET(it));
581 _title_prev_btn_set(Elm_Naviframe_Item *it,
585 if (it->title_prev_btn == btn) return;
586 if (it->title_prev_btn) evas_object_del(it->title_prev_btn);
587 it->title_prev_btn = btn;
590 evas_object_event_callback_add(btn,
594 elm_object_part_content_set(VIEW(it), "elm.swallow.prev_btn", btn);
595 elm_object_signal_emit(VIEW(it), "elm,state,prev_btn,show", "elm");
596 it->back_btn = back_btn;
598 _sizing_eval(WIDGET(it));
602 _title_next_btn_set(Elm_Naviframe_Item *it, Evas_Object *btn)
604 if (it->title_next_btn == btn) return;
605 if (it->title_next_btn) evas_object_del(it->title_next_btn);
606 it->title_next_btn = btn;
609 evas_object_event_callback_add(btn,
613 elm_object_part_content_set(VIEW(it), "elm.swallow.next_btn", btn);
614 elm_object_signal_emit(VIEW(it), "elm,state,next_btn,show", "elm");
616 _sizing_eval(WIDGET(it));
620 _title_icon_set(Elm_Naviframe_Item *it, Evas_Object *icon)
622 if (it->title_icon == icon) return;
623 if (it->title_icon) evas_object_del(it->title_icon);
624 it->title_icon = icon;
627 evas_object_event_callback_add(icon,
631 elm_object_part_content_set(VIEW(it), "elm.swallow.icon", icon);
632 elm_object_signal_emit(VIEW(it), "elm,state,icon,show", "elm");
634 _sizing_eval(WIDGET(it));
638 _item_content_unset(Elm_Naviframe_Item *it)
640 Evas_Object *content = it->content;
641 if (!content) return NULL;
643 elm_object_part_content_unset(VIEW(it), "elm.swallow.content");
644 elm_object_signal_emit(VIEW(it), "elm,state,content,hide", "elm");
645 evas_object_event_callback_del(content,
648 _sizing_eval(WIDGET(it));
655 _title_prev_btn_unset(Elm_Naviframe_Item *it)
657 Evas_Object *content = it->title_prev_btn;
658 if (!content) return NULL;
660 elm_object_part_content_unset(VIEW(it), "elm.swallow.prev_btn");
661 elm_object_signal_emit(VIEW(it), "elm,state,prev_btn,hide", "elm");
662 evas_object_event_callback_del(content,
664 _title_prev_btn_del);
665 _sizing_eval(WIDGET(it));
667 it->title_prev_btn = NULL;
672 _title_next_btn_unset(Elm_Naviframe_Item *it)
674 Evas_Object *content = it->title_next_btn;
675 if (!content) return NULL;
677 elm_object_part_content_unset(VIEW(it), "elm.swallow.next_btn");
678 elm_object_signal_emit(VIEW(it), "elm,state,next_btn,hide", "elm");
679 evas_object_event_callback_del(content,
681 _title_next_btn_del);
682 _sizing_eval(WIDGET(it));
684 it->title_next_btn = NULL;
689 _title_icon_unset(Elm_Naviframe_Item *it)
691 Evas_Object *content = it->title_icon;
692 if (!content) return NULL;
694 elm_object_part_content_unset(VIEW(it), "elm.swallow.icon");
695 elm_object_signal_emit(VIEW(it), "elm,state,icon,hide", "elm");
696 evas_object_event_callback_del(content,
699 _sizing_eval(WIDGET(it));
700 it->title_icon = NULL;
706 _title_content_unset(Elm_Naviframe_Item *it, const char *part)
708 Elm_Naviframe_Content_Item_Pair *pair = NULL;
710 Evas_Object *content = NULL;
712 EINA_INLIST_FOREACH(it->content_list, pair)
714 if (!strcmp(part, pair->part))
716 content = elm_object_part_content_get(VIEW(it), part);
717 eina_stringshare_del(pair->part);
718 it->content_list = eina_inlist_remove(it->content_list,
719 EINA_INLIST_GET(pair));
725 if (!content) return NULL;
727 elm_object_part_content_unset(VIEW(it), part);
728 snprintf(buf, sizeof(buf), "elm,state,%s,hide", part);
729 elm_object_signal_emit(VIEW(it), buf, "elm");
730 evas_object_event_callback_del(content,
733 _sizing_eval(WIDGET(it));
739 _item_del(Elm_Naviframe_Item *it)
742 Elm_Naviframe_Content_Item_Pair *content_pair;
743 Elm_Naviframe_Text_Item_Pair *text_pair;
744 Evas_Object *content;
748 wd = elm_widget_data_get(WIDGET(it));
751 while (it->content_list)
754 EINA_INLIST_CONTAINER_GET(it->content_list,
755 Elm_Naviframe_Content_Item_Pair);
756 content = elm_object_part_content_get(VIEW(it), content_pair->part);
757 evas_object_event_callback_del(content,
760 eina_stringshare_del(content_pair->part);
761 it->content_list = eina_inlist_remove(it->content_list,
766 while (it->text_list)
768 text_pair = EINA_INLIST_CONTAINER_GET(it->text_list,
769 Elm_Naviframe_Text_Item_Pair);
770 eina_stringshare_del(text_pair->part);
771 it->text_list = eina_inlist_remove(it->text_list,
776 eina_stringshare_del(it->style);
780 _item_del_pre_hook(Elm_Object_Item *it)
782 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
783 Elm_Naviframe_Item *navi_it;
786 navi_it =(Elm_Naviframe_Item *) it;
787 wd = elm_widget_data_get(WIDGET(navi_it));
790 if (it == elm_naviframe_top_item_get(WIDGET(navi_it)))
792 wd->stack = eina_inlist_remove(wd->stack, EINA_INLIST_GET(navi_it));
794 elm_widget_item_free(navi_it);
795 //If the item is only one, the stack will be empty
796 if (!wd->stack) return;
797 navi_it = EINA_INLIST_CONTAINER_GET(wd->stack->last,
799 evas_object_show(VIEW(navi_it));
800 evas_object_raise(VIEW(navi_it));
801 elm_object_signal_emit(VIEW(navi_it), "elm,state,visible", "elm");
805 wd->stack = eina_inlist_remove(wd->stack, EINA_INLIST_GET(navi_it));
807 elm_widget_item_free(navi_it);
812 _pushed_finished(void *data,
813 Evas_Object *obj __UNUSED__,
814 const char *emission __UNUSED__,
815 const char *source __UNUSED__)
818 Elm_Naviframe_Item *it = data;
821 wd = elm_widget_data_get(WIDGET(it));
824 evas_object_hide(VIEW(it));
825 evas_object_smart_callback_call(WIDGET(it),
828 if (wd->freeze_events)
829 evas_object_freeze_events_set(VIEW(it), EINA_FALSE);
833 _popped_finished(void *data,
834 Evas_Object *obj __UNUSED__,
835 const char *emission __UNUSED__,
836 const char *source __UNUSED__)
838 Elm_Naviframe_Item *it = data;
840 evas_object_smart_callback_call(WIDGET(it),
844 elm_widget_item_free(data);
848 _show_finished(void *data,
849 Evas_Object *obj __UNUSED__,
850 const char *emission __UNUSED__,
851 const char *source __UNUSED__)
853 Elm_Naviframe_Item *it;
858 wd = elm_widget_data_get(WIDGET(it));
861 evas_object_smart_callback_call(WIDGET(it),
862 SIG_TRANSITION_FINISHED,
864 if (wd->freeze_events)
865 evas_object_freeze_events_set(VIEW(it), EINA_FALSE);
869 _changed_size_hints(void *data,
871 Evas_Object *obj __UNUSED__,
872 void *event_info __UNUSED__)
878 _item_content_set(Elm_Naviframe_Item *navi_it, Evas_Object *content)
880 if (navi_it->content == content) return;
881 if (navi_it->content) evas_object_del(navi_it->content);
882 elm_object_part_content_set(VIEW(navi_it), "elm.swallow.content", content);
885 elm_object_signal_emit(VIEW(navi_it), "elm,state,content,show", "elm");
887 elm_object_signal_emit(VIEW(navi_it), "elm,state,content,hide", "elm");
889 evas_object_event_callback_add(content,
893 navi_it->content = content;
894 _sizing_eval(WIDGET(navi_it));
897 //FIXME: need to handle if this function is called while transition
899 _item_style_set(Elm_Naviframe_Item *navi_it, const char *item_style)
901 Elm_Naviframe_Content_Item_Pair *content_pair;
902 Elm_Naviframe_Text_Item_Pair *text_pair;
909 strcpy(buf, "item/basic");
910 eina_stringshare_replace(&navi_it->style, "basic");
914 snprintf(buf, sizeof(buf), "item/%s", item_style);
915 eina_stringshare_replace(&navi_it->style, item_style);
917 elm_layout_theme_set(VIEW(navi_it),
920 elm_widget_style_get(WIDGET(navi_it)));
922 EINA_INLIST_FOREACH(navi_it->text_list, text_pair)
923 _item_text_set_hook((Elm_Object_Item *) navi_it,
925 elm_object_part_text_get(VIEW(navi_it),
928 EINA_INLIST_FOREACH(navi_it->content_list, content_pair)
929 _item_content_set_hook((Elm_Object_Item *) navi_it,
931 elm_object_part_content_get(VIEW(navi_it),
932 content_pair->part));
934 if (navi_it->content)
935 elm_object_signal_emit(VIEW(navi_it), "elm,state,content,show", "elm");
938 if (navi_it->title_prev_btn)
939 elm_object_signal_emit(VIEW(navi_it), "elm,state,prev_btn,show", "elm");
942 if (navi_it->title_next_btn)
943 elm_object_signal_emit(VIEW(navi_it), "elm,state,next_btn,show", "elm");
945 navi_it->title_visible = EINA_TRUE;
946 _sizing_eval(WIDGET(navi_it));
948 wd = elm_widget_data_get(WIDGET(navi_it));
951 if (wd->freeze_events)
952 evas_object_freeze_events_set(VIEW(navi_it), EINA_FALSE);
955 static Elm_Naviframe_Item *
956 _item_new(Evas_Object *obj,
957 const char *title_label,
958 Evas_Object *prev_btn,
959 Evas_Object *next_btn,
960 Evas_Object *content,
961 const char *item_style)
963 Widget_Data *wd = elm_widget_data_get(obj);
966 Elm_Naviframe_Item *it = elm_widget_item_new(obj, Elm_Naviframe_Item);
969 ERR("Failed to allocate new item! : naviframe=%p", obj);
973 elm_widget_item_del_pre_hook_set(it, _item_del_pre_hook);
974 elm_widget_item_text_set_hook_set(it, _item_text_set_hook);
975 elm_widget_item_text_get_hook_set(it, _item_text_get_hook);
976 elm_widget_item_content_set_hook_set(it, _item_content_set_hook);
977 elm_widget_item_content_get_hook_set(it, _item_content_get_hook);
978 elm_widget_item_content_unset_hook_set(it, _item_content_unset_hook);
979 elm_widget_item_signal_emit_hook_set(it, _item_signal_emit_hook);
982 VIEW(it) = elm_layout_add(obj);
983 evas_object_smart_member_add(VIEW(it), wd->base);
985 evas_object_event_callback_add(VIEW(it),
986 EVAS_CALLBACK_CHANGED_SIZE_HINTS,
989 elm_object_signal_callback_add(VIEW(it),
990 "elm,action,show,finished",
993 elm_object_signal_callback_add(VIEW(it),
994 "elm,action,pushed,finished",
996 _pushed_finished, it);
997 elm_object_signal_callback_add(VIEW(it),
998 "elm,action,popped,finished",
1000 _popped_finished, it);
1001 elm_object_signal_callback_add(VIEW(it),
1002 "elm,action,title,clicked",
1004 _title_clicked, it);
1006 _item_style_set(it, item_style);
1007 _item_text_set_hook((Elm_Object_Item *) it, "elm.text.title", title_label);
1010 if ((!prev_btn) && wd->auto_pushed && eina_inlist_count(wd->stack))
1012 prev_btn = _back_btn_new(obj);
1013 _title_prev_btn_set(it, prev_btn, EINA_TRUE);
1016 _title_prev_btn_set(it, prev_btn, EINA_FALSE);
1018 _title_next_btn_set(it, next_btn);
1019 _item_content_set(it, content);
1020 it->title_visible = EINA_TRUE;
1025 _focus_next_hook(const Evas_Object *obj, Elm_Focus_Direction dir, Evas_Object **next)
1027 Widget_Data *wd = elm_widget_data_get(obj);
1028 if (!wd || !wd->stack) return EINA_FALSE;
1029 return elm_widget_focus_next_get(VIEW(elm_naviframe_top_item_get(obj)),
1035 elm_naviframe_add(Evas_Object *parent)
1041 ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL);
1042 ELM_SET_WIDTYPE(widtype, "naviframe");
1043 elm_widget_type_set(obj, "naviframe");
1044 elm_widget_sub_object_add(parent, obj);
1045 elm_widget_data_set(obj, wd);
1046 elm_widget_del_hook_set(obj, _del_hook);
1047 elm_widget_disable_hook_set(obj, _disable_hook);
1048 elm_widget_theme_hook_set(obj, _theme_hook);
1049 elm_widget_signal_emit_hook_set(obj, _emit_hook);
1050 elm_widget_can_focus_set(obj, EINA_FALSE);
1051 elm_widget_focus_next_hook_set(obj, _focus_next_hook);
1054 wd->base = elm_layout_add(parent);
1055 evas_object_event_callback_add(wd->base,
1056 EVAS_CALLBACK_CHANGED_SIZE_HINTS,
1057 _changed_size_hints,
1059 elm_widget_resize_object_set(obj, wd->base);
1060 elm_layout_theme_set(wd->base, "naviframe", "base", "default");
1062 evas_object_event_callback_add(obj, EVAS_CALLBACK_MOVE, _move, obj);
1063 evas_object_event_callback_add(obj, EVAS_CALLBACK_RESIZE, _resize, obj);
1064 evas_object_smart_callbacks_descriptions_set(obj, _signals);
1066 wd->auto_pushed = EINA_TRUE;
1067 wd->freeze_events = EINA_TRUE;
1072 EAPI Elm_Object_Item *
1073 elm_naviframe_item_push(Evas_Object *obj,
1074 const char *title_label,
1075 Evas_Object *prev_btn,
1076 Evas_Object *next_btn,
1077 Evas_Object *content,
1078 const char *item_style)
1080 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1082 Elm_Naviframe_Item *prev_it, *it;
1084 wd = elm_widget_data_get(obj);
1085 if (!wd) return NULL;
1087 it = _item_new(obj, title_label, prev_btn, next_btn, content, item_style);
1088 if (!it) return NULL;
1090 evas_object_show(VIEW(it));
1092 prev_it = (Elm_Naviframe_Item *) elm_naviframe_top_item_get(obj);
1095 if (wd->freeze_events)
1097 evas_object_freeze_events_set(VIEW(it), EINA_TRUE);
1098 evas_object_freeze_events_set(VIEW(prev_it), EINA_TRUE);
1100 elm_object_signal_emit(VIEW(prev_it), "elm,state,cur,pushed", "elm");
1101 elm_object_signal_emit(VIEW(it), "elm,state,new,pushed", "elm");
1102 edje_object_message_signal_process(elm_layout_edje_get(VIEW(prev_it)));
1103 edje_object_message_signal_process(elm_layout_edje_get(VIEW(it)));
1105 wd->stack = eina_inlist_append(wd->stack, EINA_INLIST_GET(it));
1107 return (Elm_Object_Item *) it;
1110 EAPI Elm_Object_Item *
1111 elm_naviframe_item_insert_before(Elm_Object_Item *before,
1112 const char *title_label,
1113 Evas_Object *prev_btn,
1114 Evas_Object *next_btn,
1115 Evas_Object *content,
1116 const char *item_style)
1118 ELM_OBJ_ITEM_CHECK_OR_RETURN(before, NULL);
1119 Elm_Naviframe_Item *it;
1122 wd = elm_widget_data_get(WIDGET(before));
1123 if (!wd) return NULL;
1125 it = _item_new(WIDGET(before), title_label, prev_btn, next_btn, content,
1127 if (!it) return NULL;
1130 eina_inlist_prepend_relative(wd->stack, EINA_INLIST_GET(it),
1131 EINA_INLIST_GET(((Elm_Naviframe_Item *) before)));
1132 _sizing_eval(WIDGET(before));
1133 return (Elm_Object_Item *) it;
1136 EAPI Elm_Object_Item *
1137 elm_naviframe_item_insert_after(Elm_Object_Item *after,
1138 const char *title_label,
1139 Evas_Object *prev_btn,
1140 Evas_Object *next_btn,
1141 Evas_Object *content,
1142 const char *item_style)
1144 ELM_OBJ_ITEM_CHECK_OR_RETURN(after, NULL);
1145 Elm_Naviframe_Item *it;
1148 wd = elm_widget_data_get(WIDGET(after));
1149 if (!wd) return NULL;
1151 it = _item_new(WIDGET(after), title_label, prev_btn, next_btn, content,
1153 if (!it) return NULL;
1155 if (elm_naviframe_top_item_get(WIDGET(after)) == after)
1157 evas_object_hide(VIEW(after));
1158 evas_object_show(VIEW(it));
1161 eina_inlist_append_relative(wd->stack, EINA_INLIST_GET(it),
1162 EINA_INLIST_GET(((Elm_Naviframe_Item *) after)));
1163 _sizing_eval(WIDGET(after));
1164 return (Elm_Object_Item *) it;
1168 elm_naviframe_item_pop(Evas_Object *obj)
1170 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1171 Elm_Naviframe_Item *it, *prev_it = NULL;
1173 Evas_Object *content = NULL;
1175 wd = elm_widget_data_get(obj);
1176 if (!wd) return NULL;
1178 it = (Elm_Naviframe_Item *) elm_naviframe_top_item_get(obj);
1179 if (!it) return NULL;
1180 elm_widget_tree_unfocusable_set(it->content, EINA_TRUE);
1182 content = it->content;
1184 if (wd->stack->last->prev)
1185 prev_it = EINA_INLIST_CONTAINER_GET(wd->stack->last->prev,
1186 Elm_Naviframe_Item);
1187 wd->stack = eina_inlist_remove(wd->stack, EINA_INLIST_GET(it));
1190 if (wd->freeze_events)
1192 evas_object_freeze_events_set(VIEW(it), EINA_TRUE);
1193 evas_object_freeze_events_set(VIEW(prev_it), EINA_TRUE);
1195 elm_object_signal_emit(VIEW(it), "elm,state,cur,popped", "elm");
1196 evas_object_show(VIEW(prev_it));
1197 evas_object_raise(VIEW(prev_it));
1198 elm_object_signal_emit(VIEW(prev_it),
1199 "elm,state,prev,popped",
1201 edje_object_message_signal_process(elm_layout_edje_get(VIEW(it)));
1202 edje_object_message_signal_process(elm_layout_edje_get(VIEW(prev_it)));
1207 elm_widget_item_free(it);
1214 elm_naviframe_item_pop_to(Elm_Object_Item *it)
1216 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1217 Elm_Naviframe_Item *navi_it;
1219 Eina_Inlist *l, *prev_l;
1221 navi_it = (Elm_Naviframe_Item *) it;
1222 wd = elm_widget_data_get(WIDGET(navi_it));
1225 if (it == elm_naviframe_top_item_get(WIDGET(navi_it))) return;
1227 l = wd->stack->last->prev;
1231 if (EINA_INLIST_CONTAINER_GET(l, Elm_Naviframe_Item) ==
1232 ((Elm_Naviframe_Item *) it)) break;
1234 wd->stack = eina_inlist_remove(wd->stack, l);
1235 _item_del(EINA_INLIST_CONTAINER_GET(l, Elm_Naviframe_Item));
1236 elm_widget_item_free(EINA_INLIST_CONTAINER_GET(l,
1237 Elm_Naviframe_Item));
1240 elm_naviframe_item_pop(WIDGET(navi_it));
1244 elm_naviframe_item_promote(Elm_Object_Item *it)
1246 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1247 Elm_Naviframe_Item *navi_it;
1248 Elm_Naviframe_Item *prev_it;
1251 navi_it = (Elm_Naviframe_Item *) it;
1252 wd = elm_widget_data_get(navi_it->base.widget);
1255 if (it == elm_naviframe_top_item_get(navi_it->base.widget)) return;
1256 wd->stack = eina_inlist_demote(wd->stack, EINA_INLIST_GET(navi_it));
1257 prev_it = EINA_INLIST_CONTAINER_GET(wd->stack->last->prev,
1258 Elm_Naviframe_Item);
1259 if (wd->freeze_events)
1261 evas_object_freeze_events_set(VIEW(it), EINA_TRUE);
1262 evas_object_freeze_events_set(VIEW(prev_it), EINA_TRUE);
1264 elm_object_signal_emit(VIEW(prev_it),
1265 "elm,state,cur,pushed",
1267 evas_object_show(VIEW(navi_it));
1268 evas_object_raise(VIEW(navi_it));
1269 elm_object_signal_emit(VIEW(navi_it),
1270 "elm,state,new,pushed",
1272 edje_object_message_signal_process(elm_layout_edje_get(VIEW(prev_it)));
1273 edje_object_message_signal_process(elm_layout_edje_get(VIEW(navi_it)));
1277 elm_naviframe_item_del(Elm_Object_Item *it)
1279 elm_object_item_del(it);
1283 elm_naviframe_content_preserve_on_pop_set(Evas_Object *obj, Eina_Bool preserve)
1285 ELM_CHECK_WIDTYPE(obj, widtype);
1286 Widget_Data *wd = elm_widget_data_get(obj);
1288 wd->preserve = !!preserve;
1292 elm_naviframe_content_preserve_on_pop_get(const Evas_Object *obj)
1294 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
1295 Widget_Data *wd = elm_widget_data_get(obj);
1296 if (!wd) return EINA_FALSE;
1297 return wd->preserve;
1300 EAPI Elm_Object_Item*
1301 elm_naviframe_top_item_get(const Evas_Object *obj)
1303 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1304 Widget_Data *wd = elm_widget_data_get(obj);
1305 if ((!wd) || (!wd->stack)) return NULL;
1306 return (Elm_Object_Item *) (EINA_INLIST_CONTAINER_GET(wd->stack->last,
1307 Elm_Naviframe_Item));
1310 EAPI Elm_Object_Item*
1311 elm_naviframe_bottom_item_get(const Evas_Object *obj)
1313 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1314 Widget_Data *wd = elm_widget_data_get(obj);
1315 if ((!wd) || (!wd->stack)) return NULL;
1316 return (Elm_Object_Item *) (EINA_INLIST_CONTAINER_GET(wd->stack,
1317 Elm_Naviframe_Item));
1321 elm_naviframe_item_style_set(Elm_Object_Item *it, const char *item_style)
1323 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1324 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
1326 //Return if new style is exsiting one.
1328 if (!strcmp(item_style, navi_it->style)) return;
1331 if (!strcmp("basic", navi_it->style)) return;
1333 _item_style_set(navi_it, item_style);
1337 elm_naviframe_item_style_get(const Elm_Object_Item *it)
1339 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
1340 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
1341 return navi_it->style;
1345 elm_naviframe_item_title_visible_set(Elm_Object_Item *it, Eina_Bool visible)
1347 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1348 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
1350 visible = !!visible;
1351 if (navi_it->title_visible == visible) return;
1353 navi_it->title_visible = visible;
1354 _item_title_visible_update(navi_it);
1358 elm_naviframe_item_title_visible_get(const Elm_Object_Item *it)
1360 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
1361 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
1362 return navi_it->title_visible;
1366 elm_naviframe_prev_btn_auto_pushed_set(Evas_Object *obj, Eina_Bool auto_pushed)
1368 ELM_CHECK_WIDTYPE(obj, widtype);
1369 Widget_Data *wd = elm_widget_data_get(obj);
1371 wd->auto_pushed = !!auto_pushed;
1375 elm_naviframe_prev_btn_auto_pushed_get(const Evas_Object *obj)
1377 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
1378 Widget_Data *wd = elm_widget_data_get(obj);
1379 if (!wd) return EINA_FALSE;
1380 return wd->auto_pushed;
1384 elm_naviframe_items_get(const Evas_Object *obj)
1386 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1387 Widget_Data *wd = elm_widget_data_get(obj);
1388 if (!wd) return NULL;
1393 elm_naviframe_event_enabled_set(Evas_Object *obj, Eina_Bool enabled)
1395 ELM_CHECK_WIDTYPE(obj, widtype);
1396 Widget_Data *wd = elm_widget_data_get(obj);
1398 enabled = !!enabled;
1399 if (wd->freeze_events == !enabled) return;
1400 wd->freeze_events = !enabled;
1404 elm_naviframe_event_enabled_get(const Evas_Object *obj)
1406 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
1407 Widget_Data *wd = elm_widget_data_get(obj);
1408 if (!wd) return EINA_FALSE;
1409 return !wd->freeze_events;