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;
16 Eina_Stringshare *item_style;
19 struct _Elm_Naviframe_Content_Item_Pair
23 Elm_Naviframe_Item *it;
26 struct _Elm_Naviframe_Text_Item_Pair
32 struct _Elm_Naviframe_Item
36 Eina_Inlist *content_list;
37 Eina_Inlist *text_list;
39 Evas_Object *title_prev_btn;
40 Evas_Object *title_next_btn;
41 Evas_Object *title_icon;
45 Eina_Bool back_btn: 1;
46 Eina_Bool title_visible: 1;
49 static const char *widtype = NULL;
51 static const char SIG_TRANSITION_FINISHED[] = "transition,finished";
52 static const char SIG_PUSH_FINISHED[] = "push,finished";
53 static const char SIG_POP_FINISHED[] = "pop,finished";
54 static const char SIG_TITLE_CLICKED[] = "title,clicked";
56 static const Evas_Smart_Cb_Description _signals[] = {
57 {SIG_TRANSITION_FINISHED, ""},
58 {SIG_TITLE_CLICKED, ""},
62 static Evas_Object *_content_get_hook(const Evas_Object *obj,
64 static void _del_hook(Evas_Object *obj);
65 static void _theme_hook(Evas_Object *obj);
66 static void _emit_hook(Evas_Object *obj,
69 static void _disable_hook(Evas_Object *obj);
70 static void _item_text_set_hook(Elm_Object_Item *it,
73 static const char *_item_text_get_hook(const Elm_Object_Item *it,
75 static void _item_content_set_hook(Elm_Object_Item *it,
77 Evas_Object *content);
78 static Evas_Object *_item_content_get_hook(const Elm_Object_Item *it,
80 static Evas_Object *_item_content_unset_hook(Elm_Object_Item *it,
82 static void _item_signal_emit_hook(Elm_Object_Item *it,
85 static void _item_title_visible_update(Elm_Naviframe_Item *navi_it);
86 static void _sizing_eval(Evas_Object *obj);
87 static void _move(void *data, Evas *e, Evas_Object *obj, void *event_info);
88 static void _resize(void *data,
92 static void _title_clicked(void *data, Evas_Object *obj,
95 static void _back_btn_clicked(void *data,
98 static Evas_Object *_back_btn_new(Evas_Object *obj);
99 static void _item_content_del(void *data,
103 static void _title_content_del(void *data,
107 static void _title_prev_btn_del(void *data,
111 static void _title_next_btn_del(void *data,
115 static void _title_icon_del(void *data,
119 static void _title_content_set(Elm_Naviframe_Item *it,
121 Evas_Object *content);
122 static void _title_prev_btn_set(Elm_Naviframe_Item *it,
125 static void _title_next_btn_set(Elm_Naviframe_Item *it, Evas_Object *btn);
126 static void _title_icon_set(Elm_Naviframe_Item *it, Evas_Object *icon);
127 static Evas_Object * _item_content_unset(Elm_Naviframe_Item *it);
128 static Evas_Object * _title_prev_btn_unset(Elm_Naviframe_Item *it);
129 static Evas_Object * _title_next_btn_unset(Elm_Naviframe_Item *it);
130 static Evas_Object * _title_icon_unset(Elm_Naviframe_Item *it);
131 static Evas_Object * _title_content_unset(Elm_Naviframe_Item *it,
133 static void _item_del(Elm_Naviframe_Item *it);
134 static Eina_Bool _item_del_pre_hook(Elm_Object_Item *it);
135 static void _pushed_finished(void *data,
137 const char *emission,
139 static void _popped_finished(void *data,
141 const char *emission,
143 static void _show_finished(void *data,
145 const char *emission,
147 static void _changed_size_hints(void *data,
151 static void _item_content_set(Elm_Naviframe_Item *navi_it,
152 Evas_Object *content);
153 static void _item_style_set(Elm_Naviframe_Item *navi_it,
154 const char *item_style);
155 static Elm_Naviframe_Item * _item_new(Evas_Object *obj,
156 const char *title_label,
157 Evas_Object *prev_btn,
158 Evas_Object *next_btn,
159 Evas_Object *content,
160 const char *item_style);
161 static Eina_Bool _focus_next_hook(const Evas_Object *obj,
162 Elm_Focus_Direction dir,
166 _del_hook(Evas_Object *obj)
169 Elm_Naviframe_Item *it;
171 wd = elm_widget_data_get(obj);
176 while (wd->stack->last)
178 it = EINA_INLIST_CONTAINER_GET(wd->stack->last,
180 wd->stack = eina_inlist_remove(wd->stack, wd->stack->last);
182 elm_widget_item_free(it);
183 if (!wd->stack) break;
186 eina_stringshare_del(wd->item_style);
191 _theme_hook(Evas_Object *obj)
194 Elm_Naviframe_Item *it;
196 wd = elm_widget_data_get(obj);
199 _elm_theme_object_set(obj,
203 elm_widget_style_get(obj));
205 EINA_INLIST_FOREACH(wd->stack, it)
207 _item_style_set(it, it->style);
208 _item_title_visible_update(it);
212 static void _emit_hook(Evas_Object *obj,
213 const char *emission,
216 ELM_CHECK_WIDTYPE(obj, widtype);
218 Widget_Data *wd = elm_widget_data_get(obj);
221 elm_object_signal_emit(wd->base, emission, source);
225 _disable_hook(Evas_Object *obj __UNUSED__)
231 _item_text_set_hook(Elm_Object_Item *it,
235 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
237 Elm_Naviframe_Text_Item_Pair *pair = NULL;
238 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
241 if (!part || !strcmp(part, "default"))
242 snprintf(buf, sizeof(buf), "elm.text.title");
243 else if(!strcmp("subtitle", part))
244 snprintf(buf, sizeof(buf), "elm.text.subtitle");
246 snprintf(buf, sizeof(buf), "%s", part);
248 EINA_INLIST_FOREACH(navi_it->text_list, pair)
249 if (!strcmp(buf, pair->part)) break;
253 pair = ELM_NEW(Elm_Naviframe_Text_Item_Pair);
256 ERR("Failed to allocate new text part of the item! : naviframe=%p",
260 eina_stringshare_replace(&pair->part, buf);
261 navi_it->text_list = eina_inlist_append(navi_it->text_list,
262 EINA_INLIST_GET(pair));
264 elm_object_part_text_set(VIEW(navi_it), buf, label);
268 snprintf(buf, sizeof(buf), "elm,state,%s,show", buf);
269 elm_object_signal_emit(VIEW(navi_it), buf, "elm");
273 snprintf(buf, sizeof(buf), "elm,state,%s,hide", buf);
274 elm_object_signal_emit(VIEW(navi_it), buf, "elm");
277 _sizing_eval(WIDGET(navi_it));
281 _item_text_get_hook(const Elm_Object_Item *it, const char *part)
283 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
286 if (!part || !strcmp(part, "default"))
287 snprintf(buf, sizeof(buf), "elm.text.title");
288 else if(!strcmp("subtitle", part))
289 snprintf(buf, sizeof(buf), "elm.text.subtitle");
291 snprintf(buf, sizeof(buf), "%s", part);
293 return elm_object_part_text_get(VIEW(it), buf);
297 _item_content_set_hook(Elm_Object_Item *it,
299 Evas_Object *content)
301 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
303 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
306 if (!part || !strcmp("default", part))
308 _item_content_set(navi_it, content);
311 else if (!strcmp(part, "prev_btn"))
313 _title_prev_btn_set(navi_it, content, EINA_FALSE);
316 else if (!strcmp(part, "next_btn"))
318 _title_next_btn_set(navi_it, content);
321 else if (!strcmp(part, "icon"))
323 _title_icon_set(navi_it, content);
328 _title_content_set(navi_it, part, content);
332 _item_content_get_hook(const Elm_Object_Item *it, const char *part)
334 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
335 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
338 if (!part || !strcmp("default", part))
339 return navi_it->content;
340 else if (!strcmp(part, "prev_btn"))
341 return navi_it->title_prev_btn;
342 else if (!strcmp(part, "next_btn"))
343 return navi_it->title_next_btn;
344 else if (!strcmp(part, "icon"))
345 return navi_it->title_icon;
348 return elm_object_part_content_get(VIEW(navi_it), part);
352 _item_content_unset_hook(Elm_Object_Item *it, const char *part)
354 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
355 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
358 if (!part || !strcmp("default", part))
359 return _item_content_unset(navi_it);
360 else if (!strcmp(part, "prev_btn"))
361 return _title_prev_btn_unset(navi_it);
362 else if (!strcmp(part, "next_btn"))
363 return _title_next_btn_unset(navi_it);
364 else if (!strcmp(part, "icon"))
365 return _title_icon_unset(navi_it);
367 return _title_content_unset(navi_it, part);
371 _item_signal_emit_hook(Elm_Object_Item *it,
372 const char *emission,
375 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
376 elm_object_signal_emit(VIEW(it), emission, source);
380 _item_title_visible_update(Elm_Naviframe_Item *navi_it)
382 if (navi_it->title_visible)
383 elm_object_signal_emit(VIEW(navi_it), "elm,state,title,show", "elm");
385 elm_object_signal_emit(VIEW(navi_it), "elm,state,title,hide", "elm");
389 _sizing_eval(Evas_Object *obj)
392 Elm_Naviframe_Item *it;
393 Evas_Coord x, y, w, h;
394 Evas_Coord minw = -1, minh = -1;
396 wd = elm_widget_data_get(obj);
399 evas_object_geometry_get(obj, &x, &y, &w, &h);
401 EINA_INLIST_FOREACH(wd->stack, it)
403 evas_object_move(VIEW(it), x, y);
404 evas_object_resize(VIEW(it), w, h);
405 edje_object_size_min_calc(elm_layout_edje_get(VIEW(it)),
408 if (it->minw > minw) minw = it->minw;
409 if (it->minh > minh) minh = it->minh;
411 evas_object_size_hint_min_set(obj, minw, minh);
412 evas_object_size_hint_max_set(obj, -1, -1);
416 _move(void *data __UNUSED__,
419 void *event_info __UNUSED__)
425 _resize(void *data __UNUSED__,
428 void *event_info __UNUSED__)
434 _title_clicked(void *data,
435 Evas_Object *obj __UNUSED__,
436 const char *emission __UNUSED__,
437 const char *source __UNUSED__)
439 Elm_Naviframe_Item *it = data;
440 evas_object_smart_callback_call(WIDGET(it), SIG_TITLE_CLICKED, it);
444 _back_btn_clicked(void *data,
446 void *event_info __UNUSED__)
448 /* Since edje has the event queue, clicked event could be happend multiple times
449 on some heavy environment. This callback del will prevent those scenario and
450 guarantee only one clicked for it's own page. */
451 evas_object_smart_callback_del(obj, "clicked", _back_btn_clicked);
452 elm_naviframe_item_pop(data);
456 _back_btn_new(Evas_Object *obj)
460 btn = elm_button_add(obj);
461 if (!btn) return NULL;
462 evas_object_smart_callback_add(btn, "clicked", _back_btn_clicked, obj);
463 snprintf(buf, sizeof(buf), "naviframe/back_btn/%s", elm_widget_style_get(obj));
464 elm_object_style_set(btn, buf);
469 _content_get_hook(const Evas_Object *obj, const char *part)
471 Elm_Object_Item *it = elm_naviframe_top_item_get(obj);
472 if (!it) return NULL;
473 return elm_object_item_part_content_get(it, part);
477 _title_content_del(void *data,
479 Evas_Object *obj __UNUSED__,
480 void *event_info __UNUSED__)
483 Elm_Naviframe_Content_Item_Pair *pair = data;
484 Elm_Naviframe_Item *it = pair->it;
485 snprintf(buf, sizeof(buf), "elm,state,%s,hide", pair->part);
486 elm_object_signal_emit(VIEW(it), buf, "elm");
487 it->content_list = eina_inlist_remove(it->content_list,
488 EINA_INLIST_GET(pair));
489 eina_stringshare_del(pair->part);
494 _title_prev_btn_del(void *data,
496 Evas_Object *obj __UNUSED__,
497 void *event_info __UNUSED__)
499 Elm_Naviframe_Item *it = data;
500 it->back_btn = EINA_FALSE;
501 it->title_prev_btn = NULL;
502 elm_object_signal_emit(VIEW(it), "elm,state,prev_btn,hide", "elm");
506 _title_next_btn_del(void *data,
508 Evas_Object *obj __UNUSED__,
509 void *event_info __UNUSED__)
511 Elm_Naviframe_Item *it = data;
512 it->title_next_btn = NULL;
513 elm_object_signal_emit(VIEW(it), "elm,state,next_btn,hide", "elm");
517 _title_icon_del(void *data,
519 Evas_Object *obj __UNUSED__,
520 void *event_info __UNUSED__)
522 Elm_Naviframe_Item *it = data;
523 it->title_icon = NULL;
524 elm_object_signal_emit(VIEW(it), "elm,state,icon,hide", "elm");
528 _item_content_del(void *data,
530 Evas_Object *obj __UNUSED__,
531 void *event_info __UNUSED__)
533 Elm_Naviframe_Item *it = data;
535 elm_object_signal_emit(VIEW(it), "elm,state,content,hide", "elm");
539 _title_content_set(Elm_Naviframe_Item *it,
541 Evas_Object *content)
544 Elm_Naviframe_Content_Item_Pair *pair = NULL;
545 Evas_Object *prev_content = NULL;
547 EINA_INLIST_FOREACH(it->content_list, pair)
548 if (!strcmp(part, pair->part)) break;
552 prev_content = elm_object_part_content_get(VIEW(it), part);
553 if (prev_content != content)
557 evas_object_event_callback_del(prev_content,
560 snprintf(buf, sizeof(buf), "elm,state,%s,hide", part);
561 elm_object_signal_emit(VIEW(it), buf, "elm");
563 evas_object_del(prev_content);
564 if (!content) return;
569 if (!content) return;
570 pair = ELM_NEW(Elm_Naviframe_Content_Item_Pair);
573 ERR("Failed to allocate new content part of the item! : naviframe=%p", WIDGET(it));
577 eina_stringshare_replace(&pair->part, part);
578 it->content_list = eina_inlist_append(it->content_list,
579 EINA_INLIST_GET(pair));
581 if (prev_content != content)
583 evas_object_event_callback_add(content,
588 elm_object_part_content_set(VIEW(it), part, content);
589 snprintf(buf, sizeof(buf), "elm,state,%s,show", part);
590 elm_object_signal_emit(VIEW(it), buf, "elm");
592 _sizing_eval(WIDGET(it));
596 _title_prev_btn_set(Elm_Naviframe_Item *it,
600 if (it->title_prev_btn == btn) return;
601 if (it->title_prev_btn) evas_object_del(it->title_prev_btn);
602 it->title_prev_btn = btn;
605 evas_object_event_callback_add(btn,
609 elm_object_part_content_set(VIEW(it), "elm.swallow.prev_btn", btn);
610 elm_object_signal_emit(VIEW(it), "elm,state,prev_btn,show", "elm");
611 it->back_btn = back_btn;
613 _sizing_eval(WIDGET(it));
617 _title_next_btn_set(Elm_Naviframe_Item *it, Evas_Object *btn)
619 if (it->title_next_btn == btn) return;
620 if (it->title_next_btn) evas_object_del(it->title_next_btn);
621 it->title_next_btn = btn;
624 evas_object_event_callback_add(btn,
628 elm_object_part_content_set(VIEW(it), "elm.swallow.next_btn", btn);
629 elm_object_signal_emit(VIEW(it), "elm,state,next_btn,show", "elm");
631 _sizing_eval(WIDGET(it));
635 _title_icon_set(Elm_Naviframe_Item *it, Evas_Object *icon)
637 if (it->title_icon == icon) return;
638 if (it->title_icon) evas_object_del(it->title_icon);
639 it->title_icon = icon;
642 evas_object_event_callback_add(icon,
646 elm_object_part_content_set(VIEW(it), "elm.swallow.icon", icon);
647 elm_object_signal_emit(VIEW(it), "elm,state,icon,show", "elm");
649 _sizing_eval(WIDGET(it));
653 _item_content_unset(Elm_Naviframe_Item *it)
655 Evas_Object *content = it->content;
656 if (!content) return NULL;
658 elm_object_part_content_unset(VIEW(it), "elm.swallow.content");
659 elm_object_signal_emit(VIEW(it), "elm,state,content,hide", "elm");
660 evas_object_event_callback_del(content,
663 _sizing_eval(WIDGET(it));
670 _title_prev_btn_unset(Elm_Naviframe_Item *it)
672 Evas_Object *content = it->title_prev_btn;
673 if (!content) return NULL;
675 elm_object_part_content_unset(VIEW(it), "elm.swallow.prev_btn");
676 elm_object_signal_emit(VIEW(it), "elm,state,prev_btn,hide", "elm");
677 evas_object_event_callback_del(content,
679 _title_prev_btn_del);
680 _sizing_eval(WIDGET(it));
682 it->title_prev_btn = NULL;
687 _title_next_btn_unset(Elm_Naviframe_Item *it)
689 Evas_Object *content = it->title_next_btn;
690 if (!content) return NULL;
692 elm_object_part_content_unset(VIEW(it), "elm.swallow.next_btn");
693 elm_object_signal_emit(VIEW(it), "elm,state,next_btn,hide", "elm");
694 evas_object_event_callback_del(content,
696 _title_next_btn_del);
697 _sizing_eval(WIDGET(it));
699 it->title_next_btn = NULL;
704 _title_icon_unset(Elm_Naviframe_Item *it)
706 Evas_Object *content = it->title_icon;
707 if (!content) return NULL;
709 elm_object_part_content_unset(VIEW(it), "elm.swallow.icon");
710 elm_object_signal_emit(VIEW(it), "elm,state,icon,hide", "elm");
711 evas_object_event_callback_del(content,
714 _sizing_eval(WIDGET(it));
715 it->title_icon = NULL;
721 _title_content_unset(Elm_Naviframe_Item *it, const char *part)
723 Elm_Naviframe_Content_Item_Pair *pair = NULL;
725 Evas_Object *content = NULL;
727 EINA_INLIST_FOREACH(it->content_list, pair)
729 if (!strcmp(part, pair->part))
731 content = elm_object_part_content_get(VIEW(it), part);
732 eina_stringshare_del(pair->part);
733 it->content_list = eina_inlist_remove(it->content_list,
734 EINA_INLIST_GET(pair));
740 if (!content) return NULL;
742 elm_object_part_content_unset(VIEW(it), part);
743 snprintf(buf, sizeof(buf), "elm,state,%s,hide", part);
744 elm_object_signal_emit(VIEW(it), buf, "elm");
745 evas_object_event_callback_del(content,
748 _sizing_eval(WIDGET(it));
754 _item_del(Elm_Naviframe_Item *it)
757 Elm_Naviframe_Content_Item_Pair *content_pair;
758 Elm_Naviframe_Text_Item_Pair *text_pair;
759 Evas_Object *content;
763 wd = elm_widget_data_get(WIDGET(it));
766 while (it->content_list)
769 EINA_INLIST_CONTAINER_GET(it->content_list,
770 Elm_Naviframe_Content_Item_Pair);
771 content = elm_object_part_content_get(VIEW(it), content_pair->part);
772 evas_object_event_callback_del(content,
775 eina_stringshare_del(content_pair->part);
776 it->content_list = eina_inlist_remove(it->content_list,
781 while (it->text_list)
783 text_pair = EINA_INLIST_CONTAINER_GET(it->text_list,
784 Elm_Naviframe_Text_Item_Pair);
785 eina_stringshare_del(text_pair->part);
786 it->text_list = eina_inlist_remove(it->text_list,
791 eina_stringshare_del(it->style);
795 _item_del_pre_hook(Elm_Object_Item *it)
797 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
798 Elm_Naviframe_Item *navi_it;
801 navi_it =(Elm_Naviframe_Item *) it;
802 wd = elm_widget_data_get(WIDGET(navi_it));
803 if (!wd) return EINA_FALSE;
805 if (it == elm_naviframe_top_item_get(WIDGET(navi_it)))
807 wd->stack = eina_inlist_remove(wd->stack, EINA_INLIST_GET(navi_it));
809 elm_widget_item_free(navi_it);
810 //If the item is only one, the stack will be empty
811 if (!wd->stack) return EINA_TRUE;
812 navi_it = EINA_INLIST_CONTAINER_GET(wd->stack->last,
814 evas_object_show(VIEW(navi_it));
815 evas_object_raise(VIEW(navi_it));
816 elm_object_signal_emit(VIEW(navi_it), "elm,state,visible", "elm");
820 wd->stack = eina_inlist_remove(wd->stack, EINA_INLIST_GET(navi_it));
822 elm_widget_item_free(navi_it);
829 _pushed_finished(void *data,
830 Evas_Object *obj __UNUSED__,
831 const char *emission __UNUSED__,
832 const char *source __UNUSED__)
835 Elm_Naviframe_Item *it = data;
838 wd = elm_widget_data_get(WIDGET(it));
841 evas_object_hide(VIEW(it));
842 evas_object_smart_callback_call(WIDGET(it),
845 if (wd->freeze_events)
846 evas_object_freeze_events_set(VIEW(it), EINA_FALSE);
850 _popped_finished(void *data,
851 Evas_Object *obj __UNUSED__,
852 const char *emission __UNUSED__,
853 const char *source __UNUSED__)
855 Elm_Naviframe_Item *it = data;
857 evas_object_smart_callback_call(WIDGET(it),
861 elm_widget_item_free(data);
865 _show_finished(void *data,
866 Evas_Object *obj __UNUSED__,
867 const char *emission __UNUSED__,
868 const char *source __UNUSED__)
870 Elm_Naviframe_Item *it;
875 wd = elm_widget_data_get(WIDGET(it));
878 evas_object_smart_callback_call(WIDGET(it),
879 SIG_TRANSITION_FINISHED,
881 if (wd->freeze_events)
882 evas_object_freeze_events_set(VIEW(it), EINA_FALSE);
886 _changed_size_hints(void *data,
888 Evas_Object *obj __UNUSED__,
889 void *event_info __UNUSED__)
895 _item_content_set(Elm_Naviframe_Item *navi_it, Evas_Object *content)
897 if (navi_it->content == content) return;
898 if (navi_it->content) evas_object_del(navi_it->content);
899 elm_object_part_content_set(VIEW(navi_it), "elm.swallow.content", content);
902 elm_object_signal_emit(VIEW(navi_it), "elm,state,content,show", "elm");
904 elm_object_signal_emit(VIEW(navi_it), "elm,state,content,hide", "elm");
906 evas_object_event_callback_add(content,
910 navi_it->content = content;
911 _sizing_eval(WIDGET(navi_it));
914 //FIXME: need to handle if this function is called while transition
916 _item_style_set(Elm_Naviframe_Item *navi_it, const char *item_style)
918 Elm_Naviframe_Content_Item_Pair *content_pair;
919 Elm_Naviframe_Text_Item_Pair *text_pair;
921 wd = elm_widget_data_get(WIDGET(navi_it));
928 snprintf(buf, sizeof(buf), "item/%s", wd->item_style);
932 snprintf(buf, sizeof(buf), "item/%s", item_style);
933 eina_stringshare_replace(&navi_it->style, item_style);
935 elm_layout_theme_set(VIEW(navi_it),
938 elm_widget_style_get(WIDGET(navi_it)));
940 EINA_INLIST_FOREACH(navi_it->text_list, text_pair)
941 _item_text_set_hook((Elm_Object_Item *) navi_it,
943 elm_object_part_text_get(VIEW(navi_it),
946 EINA_INLIST_FOREACH(navi_it->content_list, content_pair)
947 _item_content_set_hook((Elm_Object_Item *) navi_it,
949 elm_object_part_content_get(VIEW(navi_it),
950 content_pair->part));
952 if (navi_it->content)
953 elm_object_signal_emit(VIEW(navi_it), "elm,state,content,show", "elm");
956 if (navi_it->title_prev_btn)
957 elm_object_signal_emit(VIEW(navi_it), "elm,state,prev_btn,show", "elm");
960 if (navi_it->title_next_btn)
961 elm_object_signal_emit(VIEW(navi_it), "elm,state,next_btn,show", "elm");
963 navi_it->title_visible = EINA_TRUE;
964 _sizing_eval(WIDGET(navi_it));
966 if (wd->freeze_events)
967 evas_object_freeze_events_set(VIEW(navi_it), EINA_FALSE);
970 static Elm_Naviframe_Item *
971 _item_new(Evas_Object *obj,
972 const char *title_label,
973 Evas_Object *prev_btn,
974 Evas_Object *next_btn,
975 Evas_Object *content,
976 const char *item_style)
978 Widget_Data *wd = elm_widget_data_get(obj);
981 Elm_Naviframe_Item *it = elm_widget_item_new(obj, Elm_Naviframe_Item);
984 ERR("Failed to allocate new item! : naviframe=%p", obj);
988 elm_widget_item_del_pre_hook_set(it, _item_del_pre_hook);
989 elm_widget_item_text_set_hook_set(it, _item_text_set_hook);
990 elm_widget_item_text_get_hook_set(it, _item_text_get_hook);
991 elm_widget_item_content_set_hook_set(it, _item_content_set_hook);
992 elm_widget_item_content_get_hook_set(it, _item_content_get_hook);
993 elm_widget_item_content_unset_hook_set(it, _item_content_unset_hook);
994 elm_widget_item_signal_emit_hook_set(it, _item_signal_emit_hook);
997 VIEW(it) = elm_layout_add(obj);
998 evas_object_smart_member_add(VIEW(it), wd->base);
1000 evas_object_event_callback_add(VIEW(it),
1001 EVAS_CALLBACK_CHANGED_SIZE_HINTS,
1002 _changed_size_hints,
1004 elm_object_signal_callback_add(VIEW(it),
1005 "elm,action,show,finished",
1007 _show_finished, it);
1008 elm_object_signal_callback_add(VIEW(it),
1009 "elm,action,pushed,finished",
1011 _pushed_finished, it);
1012 elm_object_signal_callback_add(VIEW(it),
1013 "elm,action,popped,finished",
1015 _popped_finished, it);
1016 elm_object_signal_callback_add(VIEW(it),
1017 "elm,action,title,clicked",
1019 _title_clicked, it);
1021 _item_style_set(it, item_style);
1022 _item_text_set_hook((Elm_Object_Item *) it, "elm.text.title", title_label);
1025 if ((!prev_btn) && wd->auto_pushed && eina_inlist_count(wd->stack))
1027 prev_btn = _back_btn_new(obj);
1028 _title_prev_btn_set(it, prev_btn, EINA_TRUE);
1031 _title_prev_btn_set(it, prev_btn, EINA_FALSE);
1033 _title_next_btn_set(it, next_btn);
1034 _item_content_set(it, content);
1035 it->title_visible = EINA_TRUE;
1040 _focus_next_hook(const Evas_Object *obj, Elm_Focus_Direction dir, Evas_Object **next)
1042 Widget_Data *wd = elm_widget_data_get(obj);
1043 if (!wd || !wd->stack) return EINA_FALSE;
1044 return elm_widget_focus_next_get(VIEW(elm_naviframe_top_item_get(obj)),
1050 elm_naviframe_add(Evas_Object *parent)
1056 ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL);
1057 ELM_SET_WIDTYPE(widtype, "naviframe");
1058 elm_widget_type_set(obj, "naviframe");
1059 elm_widget_sub_object_add(parent, obj);
1060 elm_widget_data_set(obj, wd);
1061 elm_widget_del_hook_set(obj, _del_hook);
1062 elm_widget_disable_hook_set(obj, _disable_hook);
1063 elm_widget_theme_hook_set(obj, _theme_hook);
1064 elm_widget_content_get_hook_set(obj, _content_get_hook);
1065 elm_widget_signal_emit_hook_set(obj, _emit_hook);
1066 elm_widget_can_focus_set(obj, EINA_FALSE);
1067 elm_widget_focus_next_hook_set(obj, _focus_next_hook);
1070 wd->base = elm_layout_add(parent);
1071 evas_object_event_callback_add(wd->base,
1072 EVAS_CALLBACK_CHANGED_SIZE_HINTS,
1073 _changed_size_hints,
1075 elm_widget_resize_object_set(obj, wd->base);
1076 elm_layout_theme_set(wd->base, "naviframe", "base", "default");
1078 evas_object_event_callback_add(obj, EVAS_CALLBACK_MOVE, _move, obj);
1079 evas_object_event_callback_add(obj, EVAS_CALLBACK_RESIZE, _resize, obj);
1080 evas_object_smart_callbacks_descriptions_set(obj, _signals);
1082 wd->auto_pushed = EINA_TRUE;
1083 wd->freeze_events = EINA_TRUE;
1084 wd->item_style = eina_stringshare_add("basic");
1089 EAPI Elm_Object_Item *
1090 elm_naviframe_item_push(Evas_Object *obj,
1091 const char *title_label,
1092 Evas_Object *prev_btn,
1093 Evas_Object *next_btn,
1094 Evas_Object *content,
1095 const char *item_style)
1097 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1099 Elm_Naviframe_Item *prev_it, *it;
1101 wd = elm_widget_data_get(obj);
1102 if (!wd) return NULL;
1104 it = _item_new(obj, title_label, prev_btn, next_btn, content, item_style);
1105 if (!it) return NULL;
1107 evas_object_show(VIEW(it));
1109 prev_it = (Elm_Naviframe_Item *) elm_naviframe_top_item_get(obj);
1112 if (wd->freeze_events)
1114 evas_object_freeze_events_set(VIEW(it), EINA_TRUE);
1115 evas_object_freeze_events_set(VIEW(prev_it), EINA_TRUE);
1117 elm_object_signal_emit(VIEW(prev_it), "elm,state,cur,pushed", "elm");
1118 elm_object_signal_emit(VIEW(it), "elm,state,new,pushed", "elm");
1119 edje_object_message_signal_process(elm_layout_edje_get(VIEW(prev_it)));
1120 edje_object_message_signal_process(elm_layout_edje_get(VIEW(it)));
1122 wd->stack = eina_inlist_append(wd->stack, EINA_INLIST_GET(it));
1124 return (Elm_Object_Item *) it;
1127 EAPI Elm_Object_Item *
1128 elm_naviframe_item_insert_before(Elm_Object_Item *before,
1129 const char *title_label,
1130 Evas_Object *prev_btn,
1131 Evas_Object *next_btn,
1132 Evas_Object *content,
1133 const char *item_style)
1135 ELM_OBJ_ITEM_CHECK_OR_RETURN(before, NULL);
1136 Elm_Naviframe_Item *it;
1139 wd = elm_widget_data_get(WIDGET(before));
1140 if (!wd) return NULL;
1142 it = _item_new(WIDGET(before), title_label, prev_btn, next_btn, content,
1144 if (!it) return NULL;
1147 eina_inlist_prepend_relative(wd->stack, EINA_INLIST_GET(it),
1148 EINA_INLIST_GET(((Elm_Naviframe_Item *) before)));
1149 _sizing_eval(WIDGET(before));
1150 return (Elm_Object_Item *) it;
1153 EAPI Elm_Object_Item *
1154 elm_naviframe_item_insert_after(Elm_Object_Item *after,
1155 const char *title_label,
1156 Evas_Object *prev_btn,
1157 Evas_Object *next_btn,
1158 Evas_Object *content,
1159 const char *item_style)
1161 ELM_OBJ_ITEM_CHECK_OR_RETURN(after, NULL);
1162 Elm_Naviframe_Item *it;
1165 wd = elm_widget_data_get(WIDGET(after));
1166 if (!wd) return NULL;
1168 it = _item_new(WIDGET(after), title_label, prev_btn, next_btn, content,
1170 if (!it) return NULL;
1172 if (elm_naviframe_top_item_get(WIDGET(after)) == after)
1174 evas_object_hide(VIEW(after));
1175 evas_object_show(VIEW(it));
1178 eina_inlist_append_relative(wd->stack, EINA_INLIST_GET(it),
1179 EINA_INLIST_GET(((Elm_Naviframe_Item *) after)));
1180 _sizing_eval(WIDGET(after));
1181 return (Elm_Object_Item *) it;
1185 elm_naviframe_item_pop(Evas_Object *obj)
1187 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1188 Elm_Naviframe_Item *it, *prev_it = NULL;
1190 Evas_Object *content = NULL;
1192 wd = elm_widget_data_get(obj);
1193 if (!wd) return NULL;
1195 it = (Elm_Naviframe_Item *) elm_naviframe_top_item_get(obj);
1196 if (!it) return NULL;
1197 elm_widget_tree_unfocusable_set(it->content, EINA_TRUE);
1199 content = it->content;
1201 if (wd->stack->last->prev)
1202 prev_it = EINA_INLIST_CONTAINER_GET(wd->stack->last->prev,
1203 Elm_Naviframe_Item);
1204 wd->stack = eina_inlist_remove(wd->stack, EINA_INLIST_GET(it));
1207 if (wd->freeze_events)
1209 evas_object_freeze_events_set(VIEW(it), EINA_TRUE);
1210 evas_object_freeze_events_set(VIEW(prev_it), EINA_TRUE);
1212 elm_object_signal_emit(VIEW(it), "elm,state,cur,popped", "elm");
1213 evas_object_show(VIEW(prev_it));
1214 evas_object_raise(VIEW(prev_it));
1215 elm_object_signal_emit(VIEW(prev_it),
1216 "elm,state,prev,popped",
1218 edje_object_message_signal_process(elm_layout_edje_get(VIEW(it)));
1219 edje_object_message_signal_process(elm_layout_edje_get(VIEW(prev_it)));
1224 elm_widget_item_free(it);
1231 elm_naviframe_item_pop_to(Elm_Object_Item *it)
1233 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1234 Elm_Naviframe_Item *navi_it;
1236 Eina_Inlist *l, *prev_l;
1238 navi_it = (Elm_Naviframe_Item *) it;
1239 wd = elm_widget_data_get(WIDGET(navi_it));
1242 if (it == elm_naviframe_top_item_get(WIDGET(navi_it))) return;
1244 l = wd->stack->last->prev;
1248 if (EINA_INLIST_CONTAINER_GET(l, Elm_Naviframe_Item) ==
1249 ((Elm_Naviframe_Item *) it)) break;
1251 wd->stack = eina_inlist_remove(wd->stack, l);
1252 _item_del(EINA_INLIST_CONTAINER_GET(l, Elm_Naviframe_Item));
1253 elm_widget_item_free(EINA_INLIST_CONTAINER_GET(l,
1254 Elm_Naviframe_Item));
1257 elm_naviframe_item_pop(WIDGET(navi_it));
1261 elm_naviframe_item_promote(Elm_Object_Item *it)
1263 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1264 Elm_Naviframe_Item *navi_it;
1265 Elm_Naviframe_Item *prev_it;
1268 navi_it = (Elm_Naviframe_Item *) it;
1269 wd = elm_widget_data_get(navi_it->base.widget);
1272 if (it == elm_naviframe_top_item_get(navi_it->base.widget)) return;
1273 wd->stack = eina_inlist_demote(wd->stack, EINA_INLIST_GET(navi_it));
1274 prev_it = EINA_INLIST_CONTAINER_GET(wd->stack->last->prev,
1275 Elm_Naviframe_Item);
1276 if (wd->freeze_events)
1278 evas_object_freeze_events_set(VIEW(it), EINA_TRUE);
1279 evas_object_freeze_events_set(VIEW(prev_it), EINA_TRUE);
1281 elm_object_signal_emit(VIEW(prev_it),
1282 "elm,state,cur,pushed",
1284 evas_object_show(VIEW(navi_it));
1285 evas_object_raise(VIEW(navi_it));
1286 elm_object_signal_emit(VIEW(navi_it),
1287 "elm,state,new,pushed",
1289 edje_object_message_signal_process(elm_layout_edje_get(VIEW(prev_it)));
1290 edje_object_message_signal_process(elm_layout_edje_get(VIEW(navi_it)));
1294 elm_naviframe_item_simple_promote(Evas_Object *obj, Evas_Object *content)
1296 ELM_CHECK_WIDTYPE(obj, widtype);
1297 Widget_Data *wd = elm_widget_data_get(obj);
1299 Elm_Naviframe_Item *itr;
1300 EINA_INLIST_FOREACH(wd->stack, itr)
1302 if (elm_object_item_content_get((Elm_Object_Item *) itr) == content)
1304 elm_naviframe_item_promote((Elm_Object_Item *) itr);
1312 elm_naviframe_item_del(Elm_Object_Item *it)
1314 elm_object_item_del(it);
1318 elm_naviframe_content_preserve_on_pop_set(Evas_Object *obj, Eina_Bool preserve)
1320 ELM_CHECK_WIDTYPE(obj, widtype);
1321 Widget_Data *wd = elm_widget_data_get(obj);
1323 wd->preserve = !!preserve;
1327 elm_naviframe_content_preserve_on_pop_get(const Evas_Object *obj)
1329 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
1330 Widget_Data *wd = elm_widget_data_get(obj);
1331 if (!wd) return EINA_FALSE;
1332 return wd->preserve;
1335 EAPI Elm_Object_Item*
1336 elm_naviframe_top_item_get(const Evas_Object *obj)
1338 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1339 Widget_Data *wd = elm_widget_data_get(obj);
1340 if ((!wd) || (!wd->stack)) return NULL;
1341 return (Elm_Object_Item *) (EINA_INLIST_CONTAINER_GET(wd->stack->last,
1342 Elm_Naviframe_Item));
1345 EAPI Elm_Object_Item*
1346 elm_naviframe_bottom_item_get(const Evas_Object *obj)
1348 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1349 Widget_Data *wd = elm_widget_data_get(obj);
1350 if ((!wd) || (!wd->stack)) return NULL;
1351 return (Elm_Object_Item *) (EINA_INLIST_CONTAINER_GET(wd->stack,
1352 Elm_Naviframe_Item));
1356 elm_naviframe_item_style_set(Elm_Object_Item *it, const char *item_style)
1358 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1359 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
1361 //Return if new style is exsiting one.
1362 if ((item_style && navi_it->style) && (!strcmp(item_style, navi_it->style)))
1365 if ((!item_style) && (!navi_it->style))
1368 _item_style_set(navi_it, item_style);
1372 elm_naviframe_item_style_get(const Elm_Object_Item *it)
1374 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
1375 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
1376 return navi_it->style;
1380 elm_naviframe_item_title_visible_set(Elm_Object_Item *it, Eina_Bool visible)
1382 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1383 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
1385 visible = !!visible;
1386 if (navi_it->title_visible == visible) return;
1388 navi_it->title_visible = visible;
1389 _item_title_visible_update(navi_it);
1393 elm_naviframe_item_title_visible_get(const Elm_Object_Item *it)
1395 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
1396 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
1397 return navi_it->title_visible;
1401 elm_naviframe_prev_btn_auto_pushed_set(Evas_Object *obj, Eina_Bool auto_pushed)
1403 ELM_CHECK_WIDTYPE(obj, widtype);
1404 Widget_Data *wd = elm_widget_data_get(obj);
1406 wd->auto_pushed = !!auto_pushed;
1410 elm_naviframe_prev_btn_auto_pushed_get(const Evas_Object *obj)
1412 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
1413 Widget_Data *wd = elm_widget_data_get(obj);
1414 if (!wd) return EINA_FALSE;
1415 return wd->auto_pushed;
1419 elm_naviframe_items_get(const Evas_Object *obj)
1421 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1422 Widget_Data *wd = elm_widget_data_get(obj);
1423 if (!wd) return NULL;
1424 Eina_List *ret = NULL;
1425 Elm_Naviframe_Item *itr;
1426 EINA_INLIST_FOREACH(wd->stack, itr)
1428 ret = eina_list_append(ret, itr);
1434 elm_naviframe_event_enabled_set(Evas_Object *obj, Eina_Bool enabled)
1436 ELM_CHECK_WIDTYPE(obj, widtype);
1437 Widget_Data *wd = elm_widget_data_get(obj);
1439 enabled = !!enabled;
1440 if (wd->freeze_events == !enabled) return;
1441 wd->freeze_events = !enabled;
1445 elm_naviframe_event_enabled_get(const Evas_Object *obj)
1447 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
1448 Widget_Data *wd = elm_widget_data_get(obj);
1449 if (!wd) return EINA_FALSE;
1450 return !wd->freeze_events;
1454 elm_naviframe_item_style_default_set(Evas_Object *obj, const char *style)
1456 ELM_CHECK_WIDTYPE(obj, widtype);
1457 Widget_Data *wd = elm_widget_data_get(obj);
1459 eina_stringshare_replace(&wd->item_style, style);
1464 elm_naviframe_item_style_default_get(const Evas_Object *obj)
1466 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1467 Widget_Data *wd = elm_widget_data_get(obj);
1468 if (!wd) return NULL;
1469 return wd->item_style;