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)
472 Elm_Naviframe_Item *it;
473 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
475 if (part && strcmp(part, "default")) return NULL;
476 wd = elm_widget_data_get(obj);
477 if ((!wd) || (!wd->stack)) return NULL;
478 it = (Elm_Naviframe_Item *) (EINA_INLIST_CONTAINER_GET(wd->stack->last,
479 Elm_Naviframe_Item));
484 _title_content_del(void *data,
486 Evas_Object *obj __UNUSED__,
487 void *event_info __UNUSED__)
490 Elm_Naviframe_Content_Item_Pair *pair = data;
491 Elm_Naviframe_Item *it = pair->it;
492 snprintf(buf, sizeof(buf), "elm,state,%s,hide", pair->part);
493 elm_object_signal_emit(VIEW(it), buf, "elm");
494 it->content_list = eina_inlist_remove(it->content_list,
495 EINA_INLIST_GET(pair));
496 eina_stringshare_del(pair->part);
501 _title_prev_btn_del(void *data,
503 Evas_Object *obj __UNUSED__,
504 void *event_info __UNUSED__)
506 Elm_Naviframe_Item *it = data;
507 it->back_btn = EINA_FALSE;
508 it->title_prev_btn = NULL;
509 elm_object_signal_emit(VIEW(it), "elm,state,prev_btn,hide", "elm");
513 _title_next_btn_del(void *data,
515 Evas_Object *obj __UNUSED__,
516 void *event_info __UNUSED__)
518 Elm_Naviframe_Item *it = data;
519 it->title_next_btn = NULL;
520 elm_object_signal_emit(VIEW(it), "elm,state,next_btn,hide", "elm");
524 _title_icon_del(void *data,
526 Evas_Object *obj __UNUSED__,
527 void *event_info __UNUSED__)
529 Elm_Naviframe_Item *it = data;
530 it->title_icon = NULL;
531 elm_object_signal_emit(VIEW(it), "elm,state,icon,hide", "elm");
535 _item_content_del(void *data,
537 Evas_Object *obj __UNUSED__,
538 void *event_info __UNUSED__)
540 Elm_Naviframe_Item *it = data;
542 elm_object_signal_emit(VIEW(it), "elm,state,content,hide", "elm");
546 _title_content_set(Elm_Naviframe_Item *it,
548 Evas_Object *content)
551 Elm_Naviframe_Content_Item_Pair *pair = NULL;
552 Evas_Object *prev_content = NULL;
554 EINA_INLIST_FOREACH(it->content_list, pair)
555 if (!strcmp(part, pair->part)) break;
559 prev_content = elm_object_part_content_get(VIEW(it), part);
560 if (prev_content != content)
564 evas_object_event_callback_del(prev_content,
567 snprintf(buf, sizeof(buf), "elm,state,%s,hide", part);
568 elm_object_signal_emit(VIEW(it), buf, "elm");
570 evas_object_del(prev_content);
571 if (!content) return;
576 if (!content) return;
577 pair = ELM_NEW(Elm_Naviframe_Content_Item_Pair);
580 ERR("Failed to allocate new content part of the item! : naviframe=%p", WIDGET(it));
584 eina_stringshare_replace(&pair->part, part);
585 it->content_list = eina_inlist_append(it->content_list,
586 EINA_INLIST_GET(pair));
588 if (prev_content != content)
590 evas_object_event_callback_add(content,
595 elm_object_part_content_set(VIEW(it), part, content);
596 snprintf(buf, sizeof(buf), "elm,state,%s,show", part);
597 elm_object_signal_emit(VIEW(it), buf, "elm");
599 _sizing_eval(WIDGET(it));
603 _title_prev_btn_set(Elm_Naviframe_Item *it,
607 if (it->title_prev_btn == btn) return;
608 if (it->title_prev_btn) evas_object_del(it->title_prev_btn);
609 it->title_prev_btn = btn;
612 evas_object_event_callback_add(btn,
616 elm_object_part_content_set(VIEW(it), "elm.swallow.prev_btn", btn);
617 elm_object_signal_emit(VIEW(it), "elm,state,prev_btn,show", "elm");
618 it->back_btn = back_btn;
620 _sizing_eval(WIDGET(it));
624 _title_next_btn_set(Elm_Naviframe_Item *it, Evas_Object *btn)
626 if (it->title_next_btn == btn) return;
627 if (it->title_next_btn) evas_object_del(it->title_next_btn);
628 it->title_next_btn = btn;
631 evas_object_event_callback_add(btn,
635 elm_object_part_content_set(VIEW(it), "elm.swallow.next_btn", btn);
636 elm_object_signal_emit(VIEW(it), "elm,state,next_btn,show", "elm");
638 _sizing_eval(WIDGET(it));
642 _title_icon_set(Elm_Naviframe_Item *it, Evas_Object *icon)
644 if (it->title_icon == icon) return;
645 if (it->title_icon) evas_object_del(it->title_icon);
646 it->title_icon = icon;
649 evas_object_event_callback_add(icon,
653 elm_object_part_content_set(VIEW(it), "elm.swallow.icon", icon);
654 elm_object_signal_emit(VIEW(it), "elm,state,icon,show", "elm");
656 _sizing_eval(WIDGET(it));
660 _item_content_unset(Elm_Naviframe_Item *it)
662 Evas_Object *content = it->content;
663 if (!content) return NULL;
665 elm_object_part_content_unset(VIEW(it), "elm.swallow.content");
666 elm_object_signal_emit(VIEW(it), "elm,state,content,hide", "elm");
667 evas_object_event_callback_del(content,
670 _sizing_eval(WIDGET(it));
677 _title_prev_btn_unset(Elm_Naviframe_Item *it)
679 Evas_Object *content = it->title_prev_btn;
680 if (!content) return NULL;
682 elm_object_part_content_unset(VIEW(it), "elm.swallow.prev_btn");
683 elm_object_signal_emit(VIEW(it), "elm,state,prev_btn,hide", "elm");
684 evas_object_event_callback_del(content,
686 _title_prev_btn_del);
687 _sizing_eval(WIDGET(it));
689 it->title_prev_btn = NULL;
694 _title_next_btn_unset(Elm_Naviframe_Item *it)
696 Evas_Object *content = it->title_next_btn;
697 if (!content) return NULL;
699 elm_object_part_content_unset(VIEW(it), "elm.swallow.next_btn");
700 elm_object_signal_emit(VIEW(it), "elm,state,next_btn,hide", "elm");
701 evas_object_event_callback_del(content,
703 _title_next_btn_del);
704 _sizing_eval(WIDGET(it));
706 it->title_next_btn = NULL;
711 _title_icon_unset(Elm_Naviframe_Item *it)
713 Evas_Object *content = it->title_icon;
714 if (!content) return NULL;
716 elm_object_part_content_unset(VIEW(it), "elm.swallow.icon");
717 elm_object_signal_emit(VIEW(it), "elm,state,icon,hide", "elm");
718 evas_object_event_callback_del(content,
721 _sizing_eval(WIDGET(it));
722 it->title_icon = NULL;
728 _title_content_unset(Elm_Naviframe_Item *it, const char *part)
730 Elm_Naviframe_Content_Item_Pair *pair = NULL;
732 Evas_Object *content = NULL;
734 EINA_INLIST_FOREACH(it->content_list, pair)
736 if (!strcmp(part, pair->part))
738 content = elm_object_part_content_get(VIEW(it), part);
739 eina_stringshare_del(pair->part);
740 it->content_list = eina_inlist_remove(it->content_list,
741 EINA_INLIST_GET(pair));
747 if (!content) return NULL;
749 elm_object_part_content_unset(VIEW(it), part);
750 snprintf(buf, sizeof(buf), "elm,state,%s,hide", part);
751 elm_object_signal_emit(VIEW(it), buf, "elm");
752 evas_object_event_callback_del(content,
755 _sizing_eval(WIDGET(it));
761 _item_del(Elm_Naviframe_Item *it)
764 Elm_Naviframe_Content_Item_Pair *content_pair;
765 Elm_Naviframe_Text_Item_Pair *text_pair;
766 Evas_Object *content;
770 wd = elm_widget_data_get(WIDGET(it));
773 while (it->content_list)
776 EINA_INLIST_CONTAINER_GET(it->content_list,
777 Elm_Naviframe_Content_Item_Pair);
778 content = elm_object_part_content_get(VIEW(it), content_pair->part);
779 evas_object_event_callback_del(content,
782 eina_stringshare_del(content_pair->part);
783 it->content_list = eina_inlist_remove(it->content_list,
788 while (it->text_list)
790 text_pair = EINA_INLIST_CONTAINER_GET(it->text_list,
791 Elm_Naviframe_Text_Item_Pair);
792 eina_stringshare_del(text_pair->part);
793 it->text_list = eina_inlist_remove(it->text_list,
798 eina_stringshare_del(it->style);
802 _item_del_pre_hook(Elm_Object_Item *it)
804 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
805 Elm_Naviframe_Item *navi_it;
808 navi_it =(Elm_Naviframe_Item *) it;
809 wd = elm_widget_data_get(WIDGET(navi_it));
810 if (!wd) return EINA_FALSE;
812 if (it == elm_naviframe_top_item_get(WIDGET(navi_it)))
814 wd->stack = eina_inlist_remove(wd->stack, EINA_INLIST_GET(navi_it));
816 elm_widget_item_free(navi_it);
817 //If the item is only one, the stack will be empty
818 if (!wd->stack) return EINA_TRUE;
819 navi_it = EINA_INLIST_CONTAINER_GET(wd->stack->last,
821 evas_object_show(VIEW(navi_it));
822 evas_object_raise(VIEW(navi_it));
823 elm_object_signal_emit(VIEW(navi_it), "elm,state,visible", "elm");
827 wd->stack = eina_inlist_remove(wd->stack, EINA_INLIST_GET(navi_it));
829 elm_widget_item_free(navi_it);
836 _pushed_finished(void *data,
837 Evas_Object *obj __UNUSED__,
838 const char *emission __UNUSED__,
839 const char *source __UNUSED__)
842 Elm_Naviframe_Item *it = data;
845 wd = elm_widget_data_get(WIDGET(it));
848 evas_object_hide(VIEW(it));
849 evas_object_smart_callback_call(WIDGET(it),
852 if (wd->freeze_events)
853 evas_object_freeze_events_set(VIEW(it), EINA_FALSE);
857 _popped_finished(void *data,
858 Evas_Object *obj __UNUSED__,
859 const char *emission __UNUSED__,
860 const char *source __UNUSED__)
862 Elm_Naviframe_Item *it = data;
864 evas_object_smart_callback_call(WIDGET(it),
868 elm_widget_item_free(data);
872 _show_finished(void *data,
873 Evas_Object *obj __UNUSED__,
874 const char *emission __UNUSED__,
875 const char *source __UNUSED__)
877 Elm_Naviframe_Item *it;
882 wd = elm_widget_data_get(WIDGET(it));
885 evas_object_smart_callback_call(WIDGET(it),
886 SIG_TRANSITION_FINISHED,
888 if (wd->freeze_events)
889 evas_object_freeze_events_set(VIEW(it), EINA_FALSE);
893 _changed_size_hints(void *data,
895 Evas_Object *obj __UNUSED__,
896 void *event_info __UNUSED__)
902 _item_content_set(Elm_Naviframe_Item *navi_it, Evas_Object *content)
904 if (navi_it->content == content) return;
905 if (navi_it->content) evas_object_del(navi_it->content);
906 elm_object_part_content_set(VIEW(navi_it), "elm.swallow.content", content);
909 elm_object_signal_emit(VIEW(navi_it), "elm,state,content,show", "elm");
911 elm_object_signal_emit(VIEW(navi_it), "elm,state,content,hide", "elm");
913 evas_object_event_callback_add(content,
917 navi_it->content = content;
918 _sizing_eval(WIDGET(navi_it));
921 //FIXME: need to handle if this function is called while transition
923 _item_style_set(Elm_Naviframe_Item *navi_it, const char *item_style)
925 Elm_Naviframe_Content_Item_Pair *content_pair;
926 Elm_Naviframe_Text_Item_Pair *text_pair;
928 wd = elm_widget_data_get(WIDGET(navi_it));
935 snprintf(buf, sizeof(buf), "item/%s", wd->item_style);
939 snprintf(buf, sizeof(buf), "item/%s", item_style);
940 eina_stringshare_replace(&navi_it->style, item_style);
942 elm_layout_theme_set(VIEW(navi_it),
945 elm_widget_style_get(WIDGET(navi_it)));
947 EINA_INLIST_FOREACH(navi_it->text_list, text_pair)
948 _item_text_set_hook((Elm_Object_Item *) navi_it,
950 elm_object_part_text_get(VIEW(navi_it),
953 EINA_INLIST_FOREACH(navi_it->content_list, content_pair)
954 _item_content_set_hook((Elm_Object_Item *) navi_it,
956 elm_object_part_content_get(VIEW(navi_it),
957 content_pair->part));
959 if (navi_it->content)
960 elm_object_signal_emit(VIEW(navi_it), "elm,state,content,show", "elm");
963 if (navi_it->title_prev_btn)
964 elm_object_signal_emit(VIEW(navi_it), "elm,state,prev_btn,show", "elm");
967 if (navi_it->title_next_btn)
968 elm_object_signal_emit(VIEW(navi_it), "elm,state,next_btn,show", "elm");
970 navi_it->title_visible = EINA_TRUE;
971 _sizing_eval(WIDGET(navi_it));
973 if (wd->freeze_events)
974 evas_object_freeze_events_set(VIEW(navi_it), EINA_FALSE);
977 static Elm_Naviframe_Item *
978 _item_new(Evas_Object *obj,
979 const char *title_label,
980 Evas_Object *prev_btn,
981 Evas_Object *next_btn,
982 Evas_Object *content,
983 const char *item_style)
985 Widget_Data *wd = elm_widget_data_get(obj);
988 Elm_Naviframe_Item *it = elm_widget_item_new(obj, Elm_Naviframe_Item);
991 ERR("Failed to allocate new item! : naviframe=%p", obj);
995 elm_widget_item_del_pre_hook_set(it, _item_del_pre_hook);
996 elm_widget_item_text_set_hook_set(it, _item_text_set_hook);
997 elm_widget_item_text_get_hook_set(it, _item_text_get_hook);
998 elm_widget_item_content_set_hook_set(it, _item_content_set_hook);
999 elm_widget_item_content_get_hook_set(it, _item_content_get_hook);
1000 elm_widget_item_content_unset_hook_set(it, _item_content_unset_hook);
1001 elm_widget_item_signal_emit_hook_set(it, _item_signal_emit_hook);
1004 VIEW(it) = elm_layout_add(obj);
1005 evas_object_smart_member_add(VIEW(it), wd->base);
1007 evas_object_event_callback_add(VIEW(it),
1008 EVAS_CALLBACK_CHANGED_SIZE_HINTS,
1009 _changed_size_hints,
1011 elm_object_signal_callback_add(VIEW(it),
1012 "elm,action,show,finished",
1014 _show_finished, it);
1015 elm_object_signal_callback_add(VIEW(it),
1016 "elm,action,pushed,finished",
1018 _pushed_finished, it);
1019 elm_object_signal_callback_add(VIEW(it),
1020 "elm,action,popped,finished",
1022 _popped_finished, it);
1023 elm_object_signal_callback_add(VIEW(it),
1024 "elm,action,title,clicked",
1026 _title_clicked, it);
1028 _item_style_set(it, item_style);
1029 _item_text_set_hook((Elm_Object_Item *) it, "elm.text.title", title_label);
1032 if ((!prev_btn) && wd->auto_pushed && eina_inlist_count(wd->stack))
1034 prev_btn = _back_btn_new(obj);
1035 _title_prev_btn_set(it, prev_btn, EINA_TRUE);
1038 _title_prev_btn_set(it, prev_btn, EINA_FALSE);
1040 _title_next_btn_set(it, next_btn);
1041 _item_content_set(it, content);
1042 it->title_visible = EINA_TRUE;
1047 _focus_next_hook(const Evas_Object *obj, Elm_Focus_Direction dir, Evas_Object **next)
1049 Widget_Data *wd = elm_widget_data_get(obj);
1050 if (!wd || !wd->stack) return EINA_FALSE;
1051 return elm_widget_focus_next_get(VIEW(elm_naviframe_top_item_get(obj)),
1057 elm_naviframe_add(Evas_Object *parent)
1063 ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL);
1064 ELM_SET_WIDTYPE(widtype, "naviframe");
1065 elm_widget_type_set(obj, "naviframe");
1066 elm_widget_sub_object_add(parent, obj);
1067 elm_widget_data_set(obj, wd);
1068 elm_widget_del_hook_set(obj, _del_hook);
1069 elm_widget_disable_hook_set(obj, _disable_hook);
1070 elm_widget_theme_hook_set(obj, _theme_hook);
1071 elm_widget_content_get_hook_set(obj, _content_get_hook);
1072 elm_widget_signal_emit_hook_set(obj, _emit_hook);
1073 elm_widget_can_focus_set(obj, EINA_FALSE);
1074 elm_widget_focus_next_hook_set(obj, _focus_next_hook);
1077 wd->base = elm_layout_add(parent);
1078 evas_object_event_callback_add(wd->base,
1079 EVAS_CALLBACK_CHANGED_SIZE_HINTS,
1080 _changed_size_hints,
1082 elm_widget_resize_object_set(obj, wd->base);
1083 elm_layout_theme_set(wd->base, "naviframe", "base", "default");
1085 evas_object_event_callback_add(obj, EVAS_CALLBACK_MOVE, _move, obj);
1086 evas_object_event_callback_add(obj, EVAS_CALLBACK_RESIZE, _resize, obj);
1087 evas_object_smart_callbacks_descriptions_set(obj, _signals);
1089 wd->auto_pushed = EINA_TRUE;
1090 wd->freeze_events = EINA_TRUE;
1091 wd->item_style = eina_stringshare_add("basic");
1096 EAPI Elm_Object_Item *
1097 elm_naviframe_item_push(Evas_Object *obj,
1098 const char *title_label,
1099 Evas_Object *prev_btn,
1100 Evas_Object *next_btn,
1101 Evas_Object *content,
1102 const char *item_style)
1104 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1106 Elm_Naviframe_Item *prev_it, *it;
1108 wd = elm_widget_data_get(obj);
1109 if (!wd) return NULL;
1111 it = _item_new(obj, title_label, prev_btn, next_btn, content, item_style);
1112 if (!it) return NULL;
1114 evas_object_show(VIEW(it));
1116 prev_it = (Elm_Naviframe_Item *) elm_naviframe_top_item_get(obj);
1119 if (wd->freeze_events)
1121 evas_object_freeze_events_set(VIEW(it), EINA_TRUE);
1122 evas_object_freeze_events_set(VIEW(prev_it), EINA_TRUE);
1124 elm_object_signal_emit(VIEW(prev_it), "elm,state,cur,pushed", "elm");
1125 elm_object_signal_emit(VIEW(it), "elm,state,new,pushed", "elm");
1126 edje_object_message_signal_process(elm_layout_edje_get(VIEW(prev_it)));
1127 edje_object_message_signal_process(elm_layout_edje_get(VIEW(it)));
1129 wd->stack = eina_inlist_append(wd->stack, EINA_INLIST_GET(it));
1131 return (Elm_Object_Item *) it;
1134 EAPI Elm_Object_Item *
1135 elm_naviframe_item_insert_before(Elm_Object_Item *before,
1136 const char *title_label,
1137 Evas_Object *prev_btn,
1138 Evas_Object *next_btn,
1139 Evas_Object *content,
1140 const char *item_style)
1142 ELM_OBJ_ITEM_CHECK_OR_RETURN(before, NULL);
1143 Elm_Naviframe_Item *it;
1146 wd = elm_widget_data_get(WIDGET(before));
1147 if (!wd) return NULL;
1149 it = _item_new(WIDGET(before), title_label, prev_btn, next_btn, content,
1151 if (!it) return NULL;
1154 eina_inlist_prepend_relative(wd->stack, EINA_INLIST_GET(it),
1155 EINA_INLIST_GET(((Elm_Naviframe_Item *) before)));
1156 _sizing_eval(WIDGET(before));
1157 return (Elm_Object_Item *) it;
1160 EAPI Elm_Object_Item *
1161 elm_naviframe_item_insert_after(Elm_Object_Item *after,
1162 const char *title_label,
1163 Evas_Object *prev_btn,
1164 Evas_Object *next_btn,
1165 Evas_Object *content,
1166 const char *item_style)
1168 ELM_OBJ_ITEM_CHECK_OR_RETURN(after, NULL);
1169 Elm_Naviframe_Item *it;
1172 wd = elm_widget_data_get(WIDGET(after));
1173 if (!wd) return NULL;
1175 it = _item_new(WIDGET(after), title_label, prev_btn, next_btn, content,
1177 if (!it) return NULL;
1179 if (elm_naviframe_top_item_get(WIDGET(after)) == after)
1181 evas_object_hide(VIEW(after));
1182 evas_object_show(VIEW(it));
1185 eina_inlist_append_relative(wd->stack, EINA_INLIST_GET(it),
1186 EINA_INLIST_GET(((Elm_Naviframe_Item *) after)));
1187 _sizing_eval(WIDGET(after));
1188 return (Elm_Object_Item *) it;
1192 elm_naviframe_item_pop(Evas_Object *obj)
1194 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1195 Elm_Naviframe_Item *it, *prev_it = NULL;
1197 Evas_Object *content = NULL;
1199 wd = elm_widget_data_get(obj);
1200 if (!wd) return NULL;
1202 it = (Elm_Naviframe_Item *) elm_naviframe_top_item_get(obj);
1203 if (!it) return NULL;
1204 elm_widget_tree_unfocusable_set(it->content, EINA_TRUE);
1206 content = it->content;
1208 if (wd->stack->last->prev)
1209 prev_it = EINA_INLIST_CONTAINER_GET(wd->stack->last->prev,
1210 Elm_Naviframe_Item);
1211 wd->stack = eina_inlist_remove(wd->stack, EINA_INLIST_GET(it));
1214 if (wd->freeze_events)
1216 evas_object_freeze_events_set(VIEW(it), EINA_TRUE);
1217 evas_object_freeze_events_set(VIEW(prev_it), EINA_TRUE);
1219 elm_object_signal_emit(VIEW(it), "elm,state,cur,popped", "elm");
1220 evas_object_show(VIEW(prev_it));
1221 evas_object_raise(VIEW(prev_it));
1222 elm_object_signal_emit(VIEW(prev_it),
1223 "elm,state,prev,popped",
1225 edje_object_message_signal_process(elm_layout_edje_get(VIEW(it)));
1226 edje_object_message_signal_process(elm_layout_edje_get(VIEW(prev_it)));
1231 elm_widget_item_free(it);
1238 elm_naviframe_item_pop_to(Elm_Object_Item *it)
1240 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1241 Elm_Naviframe_Item *navi_it;
1243 Eina_Inlist *l, *prev_l;
1245 navi_it = (Elm_Naviframe_Item *) it;
1246 wd = elm_widget_data_get(WIDGET(navi_it));
1249 if (it == elm_naviframe_top_item_get(WIDGET(navi_it))) return;
1251 l = wd->stack->last->prev;
1255 if (EINA_INLIST_CONTAINER_GET(l, Elm_Naviframe_Item) ==
1256 ((Elm_Naviframe_Item *) it)) break;
1258 wd->stack = eina_inlist_remove(wd->stack, l);
1259 _item_del(EINA_INLIST_CONTAINER_GET(l, Elm_Naviframe_Item));
1260 elm_widget_item_free(EINA_INLIST_CONTAINER_GET(l,
1261 Elm_Naviframe_Item));
1264 elm_naviframe_item_pop(WIDGET(navi_it));
1268 elm_naviframe_item_promote(Elm_Object_Item *it)
1270 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1271 Elm_Naviframe_Item *navi_it;
1272 Elm_Naviframe_Item *prev_it;
1275 navi_it = (Elm_Naviframe_Item *) it;
1276 wd = elm_widget_data_get(navi_it->base.widget);
1279 if (it == elm_naviframe_top_item_get(navi_it->base.widget)) return;
1280 wd->stack = eina_inlist_demote(wd->stack, EINA_INLIST_GET(navi_it));
1281 prev_it = EINA_INLIST_CONTAINER_GET(wd->stack->last->prev,
1282 Elm_Naviframe_Item);
1283 if (wd->freeze_events)
1285 evas_object_freeze_events_set(VIEW(it), EINA_TRUE);
1286 evas_object_freeze_events_set(VIEW(prev_it), EINA_TRUE);
1288 elm_object_signal_emit(VIEW(prev_it),
1289 "elm,state,cur,pushed",
1291 evas_object_show(VIEW(navi_it));
1292 evas_object_raise(VIEW(navi_it));
1293 elm_object_signal_emit(VIEW(navi_it),
1294 "elm,state,new,pushed",
1296 edje_object_message_signal_process(elm_layout_edje_get(VIEW(prev_it)));
1297 edje_object_message_signal_process(elm_layout_edje_get(VIEW(navi_it)));
1301 elm_naviframe_item_simple_promote(Evas_Object *obj, Evas_Object *content)
1303 ELM_CHECK_WIDTYPE(obj, widtype);
1304 Widget_Data *wd = elm_widget_data_get(obj);
1306 Elm_Naviframe_Item *itr;
1307 EINA_INLIST_FOREACH(wd->stack, itr)
1309 if (elm_object_item_content_get((Elm_Object_Item *) itr) == content)
1311 elm_naviframe_item_promote((Elm_Object_Item *) itr);
1319 elm_naviframe_item_del(Elm_Object_Item *it)
1321 elm_object_item_del(it);
1325 elm_naviframe_content_preserve_on_pop_set(Evas_Object *obj, Eina_Bool preserve)
1327 ELM_CHECK_WIDTYPE(obj, widtype);
1328 Widget_Data *wd = elm_widget_data_get(obj);
1330 wd->preserve = !!preserve;
1334 elm_naviframe_content_preserve_on_pop_get(const Evas_Object *obj)
1336 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
1337 Widget_Data *wd = elm_widget_data_get(obj);
1338 if (!wd) return EINA_FALSE;
1339 return wd->preserve;
1342 EAPI Elm_Object_Item*
1343 elm_naviframe_top_item_get(const Evas_Object *obj)
1345 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1346 Widget_Data *wd = elm_widget_data_get(obj);
1347 if ((!wd) || (!wd->stack)) return NULL;
1348 return (Elm_Object_Item *) (EINA_INLIST_CONTAINER_GET(wd->stack->last,
1349 Elm_Naviframe_Item));
1352 EAPI Elm_Object_Item*
1353 elm_naviframe_bottom_item_get(const Evas_Object *obj)
1355 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1356 Widget_Data *wd = elm_widget_data_get(obj);
1357 if ((!wd) || (!wd->stack)) return NULL;
1358 return (Elm_Object_Item *) (EINA_INLIST_CONTAINER_GET(wd->stack,
1359 Elm_Naviframe_Item));
1363 elm_naviframe_item_style_set(Elm_Object_Item *it, const char *item_style)
1365 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1366 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
1368 //Return if new style is exsiting one.
1369 if ((item_style && navi_it->style) && (!strcmp(item_style, navi_it->style)))
1372 if ((!item_style) && (!navi_it->style))
1375 _item_style_set(navi_it, item_style);
1379 elm_naviframe_item_style_get(const Elm_Object_Item *it)
1381 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
1382 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
1383 return navi_it->style;
1387 elm_naviframe_item_title_visible_set(Elm_Object_Item *it, Eina_Bool visible)
1389 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1390 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
1392 visible = !!visible;
1393 if (navi_it->title_visible == visible) return;
1395 navi_it->title_visible = visible;
1396 _item_title_visible_update(navi_it);
1400 elm_naviframe_item_title_visible_get(const Elm_Object_Item *it)
1402 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
1403 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
1404 return navi_it->title_visible;
1408 elm_naviframe_prev_btn_auto_pushed_set(Evas_Object *obj, Eina_Bool auto_pushed)
1410 ELM_CHECK_WIDTYPE(obj, widtype);
1411 Widget_Data *wd = elm_widget_data_get(obj);
1413 wd->auto_pushed = !!auto_pushed;
1417 elm_naviframe_prev_btn_auto_pushed_get(const Evas_Object *obj)
1419 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
1420 Widget_Data *wd = elm_widget_data_get(obj);
1421 if (!wd) return EINA_FALSE;
1422 return wd->auto_pushed;
1426 elm_naviframe_items_get(const Evas_Object *obj)
1428 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1429 Widget_Data *wd = elm_widget_data_get(obj);
1430 if (!wd) return NULL;
1431 Eina_List *ret = NULL;
1432 Elm_Naviframe_Item *itr;
1433 EINA_INLIST_FOREACH(wd->stack, itr)
1435 ret = eina_list_append(ret, itr);
1441 elm_naviframe_event_enabled_set(Evas_Object *obj, Eina_Bool enabled)
1443 ELM_CHECK_WIDTYPE(obj, widtype);
1444 Widget_Data *wd = elm_widget_data_get(obj);
1446 enabled = !!enabled;
1447 if (wd->freeze_events == !enabled) return;
1448 wd->freeze_events = !enabled;
1452 elm_naviframe_event_enabled_get(const Evas_Object *obj)
1454 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
1455 Widget_Data *wd = elm_widget_data_get(obj);
1456 if (!wd) return EINA_FALSE;
1457 return !wd->freeze_events;
1461 elm_naviframe_item_style_default_set(Evas_Object *obj, const char *style)
1463 ELM_CHECK_WIDTYPE(obj, widtype);
1464 Widget_Data *wd = elm_widget_data_get(obj);
1466 eina_stringshare_replace(&wd->item_style, style);
1471 elm_naviframe_item_style_default_get(const Evas_Object *obj)
1473 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1474 Widget_Data *wd = elm_widget_data_get(obj);
1475 if (!wd) return NULL;
1476 return wd->item_style;