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 elm_naviframe_add(Evas_Object *parent)
1031 ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL);
1032 ELM_SET_WIDTYPE(widtype, "naviframe");
1033 elm_widget_type_set(obj, "naviframe");
1034 elm_widget_sub_object_add(parent, obj);
1035 elm_widget_data_set(obj, wd);
1036 elm_widget_del_hook_set(obj, _del_hook);
1037 elm_widget_disable_hook_set(obj, _disable_hook);
1038 elm_widget_theme_hook_set(obj, _theme_hook);
1039 elm_widget_signal_emit_hook_set(obj, _emit_hook);
1042 wd->base = elm_layout_add(parent);
1043 evas_object_event_callback_add(wd->base,
1044 EVAS_CALLBACK_CHANGED_SIZE_HINTS,
1045 _changed_size_hints,
1047 elm_widget_resize_object_set(obj, wd->base);
1048 elm_layout_theme_set(wd->base, "naviframe", "base", "default");
1050 evas_object_event_callback_add(obj, EVAS_CALLBACK_MOVE, _move, obj);
1051 evas_object_event_callback_add(obj, EVAS_CALLBACK_RESIZE, _resize, obj);
1052 evas_object_smart_callbacks_descriptions_set(obj, _signals);
1054 wd->auto_pushed = EINA_TRUE;
1055 wd->freeze_events = EINA_TRUE;
1060 EAPI Elm_Object_Item *
1061 elm_naviframe_item_push(Evas_Object *obj,
1062 const char *title_label,
1063 Evas_Object *prev_btn,
1064 Evas_Object *next_btn,
1065 Evas_Object *content,
1066 const char *item_style)
1068 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1070 Elm_Naviframe_Item *prev_it, *it;
1072 wd = elm_widget_data_get(obj);
1073 if (!wd) return NULL;
1075 it = _item_new(obj, title_label, prev_btn, next_btn, content, item_style);
1076 if (!it) return NULL;
1078 evas_object_show(VIEW(it));
1080 prev_it = (Elm_Naviframe_Item *) elm_naviframe_top_item_get(obj);
1083 if (wd->freeze_events)
1085 evas_object_freeze_events_set(VIEW(it), EINA_TRUE);
1086 evas_object_freeze_events_set(VIEW(prev_it), EINA_TRUE);
1088 elm_object_signal_emit(VIEW(prev_it), "elm,state,cur,pushed", "elm");
1089 elm_object_signal_emit(VIEW(it), "elm,state,new,pushed", "elm");
1090 edje_object_message_signal_process(elm_layout_edje_get(VIEW(prev_it)));
1091 edje_object_message_signal_process(elm_layout_edje_get(VIEW(it)));
1093 wd->stack = eina_inlist_append(wd->stack, EINA_INLIST_GET(it));
1095 return (Elm_Object_Item *) it;
1098 EAPI Elm_Object_Item *
1099 elm_naviframe_item_insert_before(Elm_Object_Item *before,
1100 const char *title_label,
1101 Evas_Object *prev_btn,
1102 Evas_Object *next_btn,
1103 Evas_Object *content,
1104 const char *item_style)
1106 ELM_OBJ_ITEM_CHECK_OR_RETURN(before, NULL);
1107 Elm_Naviframe_Item *it;
1110 wd = elm_widget_data_get(WIDGET(before));
1111 if (!wd) return NULL;
1113 it = _item_new(WIDGET(before), title_label, prev_btn, next_btn, content,
1115 if (!it) return NULL;
1118 eina_inlist_prepend_relative(wd->stack, EINA_INLIST_GET(it),
1119 EINA_INLIST_GET(((Elm_Naviframe_Item *) before)));
1120 _sizing_eval(WIDGET(before));
1121 return (Elm_Object_Item *) it;
1124 EAPI Elm_Object_Item *
1125 elm_naviframe_item_insert_after(Elm_Object_Item *after,
1126 const char *title_label,
1127 Evas_Object *prev_btn,
1128 Evas_Object *next_btn,
1129 Evas_Object *content,
1130 const char *item_style)
1132 ELM_OBJ_ITEM_CHECK_OR_RETURN(after, NULL);
1133 Elm_Naviframe_Item *it;
1136 wd = elm_widget_data_get(WIDGET(after));
1137 if (!wd) return NULL;
1139 it = _item_new(WIDGET(after), title_label, prev_btn, next_btn, content,
1141 if (!it) return NULL;
1143 if (elm_naviframe_top_item_get(WIDGET(after)) == after)
1145 evas_object_hide(VIEW(after));
1146 evas_object_show(VIEW(it));
1149 eina_inlist_append_relative(wd->stack, EINA_INLIST_GET(it),
1150 EINA_INLIST_GET(((Elm_Naviframe_Item *) after)));
1151 _sizing_eval(WIDGET(after));
1152 return (Elm_Object_Item *) it;
1156 elm_naviframe_item_pop(Evas_Object *obj)
1158 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1159 Elm_Naviframe_Item *it, *prev_it = NULL;
1161 Evas_Object *content = NULL;
1163 wd = elm_widget_data_get(obj);
1164 if (!wd) return NULL;
1166 it = (Elm_Naviframe_Item *) elm_naviframe_top_item_get(obj);
1167 if (!it) return NULL;
1168 elm_widget_tree_unfocusable_set(it->content, EINA_TRUE);
1170 content = it->content;
1172 if (wd->stack->last->prev)
1173 prev_it = EINA_INLIST_CONTAINER_GET(wd->stack->last->prev,
1174 Elm_Naviframe_Item);
1175 wd->stack = eina_inlist_remove(wd->stack, EINA_INLIST_GET(it));
1178 if (wd->freeze_events)
1180 evas_object_freeze_events_set(VIEW(it), EINA_TRUE);
1181 evas_object_freeze_events_set(VIEW(prev_it), EINA_TRUE);
1183 elm_object_signal_emit(VIEW(it), "elm,state,cur,popped", "elm");
1184 evas_object_show(VIEW(prev_it));
1185 evas_object_raise(VIEW(prev_it));
1186 elm_object_signal_emit(VIEW(prev_it),
1187 "elm,state,prev,popped",
1189 edje_object_message_signal_process(elm_layout_edje_get(VIEW(it)));
1190 edje_object_message_signal_process(elm_layout_edje_get(VIEW(prev_it)));
1195 elm_widget_item_free(it);
1202 elm_naviframe_item_pop_to(Elm_Object_Item *it)
1204 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1205 Elm_Naviframe_Item *navi_it;
1207 Eina_Inlist *l, *prev_l;
1209 navi_it = (Elm_Naviframe_Item *) it;
1210 wd = elm_widget_data_get(WIDGET(navi_it));
1213 if (it == elm_naviframe_top_item_get(WIDGET(navi_it))) return;
1215 l = wd->stack->last->prev;
1219 if (EINA_INLIST_CONTAINER_GET(l, Elm_Naviframe_Item) ==
1220 ((Elm_Naviframe_Item *) it)) break;
1222 wd->stack = eina_inlist_remove(wd->stack, l);
1223 _item_del(EINA_INLIST_CONTAINER_GET(l, Elm_Naviframe_Item));
1224 elm_widget_item_free(EINA_INLIST_CONTAINER_GET(l,
1225 Elm_Naviframe_Item));
1228 elm_naviframe_item_pop(WIDGET(navi_it));
1232 elm_naviframe_item_promote(Elm_Object_Item *it)
1234 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1235 Elm_Naviframe_Item *navi_it;
1236 Elm_Naviframe_Item *prev_it;
1239 navi_it = (Elm_Naviframe_Item *) it;
1240 wd = elm_widget_data_get(navi_it->base.widget);
1243 if (it == elm_naviframe_top_item_get(navi_it->base.widget)) return;
1244 wd->stack = eina_inlist_demote(wd->stack, EINA_INLIST_GET(navi_it));
1245 prev_it = EINA_INLIST_CONTAINER_GET(wd->stack->last->prev,
1246 Elm_Naviframe_Item);
1247 if (wd->freeze_events)
1249 evas_object_freeze_events_set(VIEW(it), EINA_TRUE);
1250 evas_object_freeze_events_set(VIEW(prev_it), EINA_TRUE);
1252 elm_object_signal_emit(VIEW(prev_it),
1253 "elm,state,cur,pushed",
1255 evas_object_show(VIEW(navi_it));
1256 evas_object_raise(VIEW(navi_it));
1257 elm_object_signal_emit(VIEW(navi_it),
1258 "elm,state,new,pushed",
1260 edje_object_message_signal_process(elm_layout_edje_get(VIEW(prev_it)));
1261 edje_object_message_signal_process(elm_layout_edje_get(VIEW(navi_it)));
1265 elm_naviframe_item_del(Elm_Object_Item *it)
1267 elm_object_item_del(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;