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
23 Elm_Naviframe_Item *it;
26 struct _Elm_Naviframe_Text_Item_Pair
33 struct _Elm_Naviframe_Item
37 Eina_Inlist *content_list;
38 Eina_Inlist *text_list;
40 Evas_Object *title_prev_btn;
41 Evas_Object *title_next_btn;
42 Evas_Object *title_icon;
46 Eina_Bool back_btn: 1;
47 Eina_Bool title_visible: 1;
50 static const char *widtype = NULL;
52 static const char SIG_TRANSITION_FINISHED[] = "transition,finished";
53 static const char SIG_PUSH_FINISHED[] = "push,finished";
54 static const char SIG_POP_FINISHED[] = "pop,finished";
55 static const char SIG_TITLE_CLICKED[] = "title,clicked";
57 static const Evas_Smart_Cb_Description _signals[] = {
58 {SIG_TRANSITION_FINISHED, ""},
59 {SIG_TITLE_CLICKED, ""},
63 static void _del_hook(Evas_Object *obj);
64 static void _theme_hook(Evas_Object *obj);
65 static void _emit_hook(Evas_Object *obj,
68 static void _disable_hook(Evas_Object *obj);
69 static void _mirrored_set(Evas_Object *obj, Eina_Bool rtl);
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 void _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);
163 _del_hook(Evas_Object *obj)
166 Elm_Naviframe_Item *it;
168 wd = elm_widget_data_get(obj);
173 while (wd->stack->last)
175 it = EINA_INLIST_CONTAINER_GET(wd->stack->last,
177 wd->stack = eina_inlist_remove(wd->stack, wd->stack->last);
179 elm_widget_item_free(it);
180 if (!wd->stack) break;
187 _theme_hook(Evas_Object *obj)
190 Elm_Naviframe_Item *it;
192 wd = elm_widget_data_get(obj);
195 _elm_theme_object_set(obj,
199 elm_widget_style_get(obj));
201 EINA_INLIST_FOREACH(wd->stack, it)
203 _item_style_set(it, it->style);
204 _item_title_visible_update(it);
207 _elm_widget_mirrored_reload(obj);
208 _mirrored_set(obj, elm_widget_mirrored_get(obj));
211 static void _emit_hook(Evas_Object *obj,
212 const char *emission,
215 ELM_CHECK_WIDTYPE(obj, widtype);
217 Widget_Data *wd = elm_widget_data_get(obj);
220 edje_object_signal_emit(wd->base, emission, source);
224 _disable_hook(Evas_Object *obj __UNUSED__)
230 _mirrored_set(Evas_Object *obj, Eina_Bool rtl)
233 Elm_Naviframe_Item *it;
235 wd = elm_widget_data_get(obj);
238 EINA_INLIST_FOREACH(wd->stack, it)
239 edje_object_mirrored_set(VIEW(it), rtl);
240 edje_object_mirrored_set(wd->base, rtl);
244 _item_text_set_hook(Elm_Object_Item *it,
248 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
250 Elm_Naviframe_Text_Item_Pair *pair = NULL;
251 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
254 if (!part || !strcmp(part, "default"))
255 snprintf(buf, sizeof(buf), "elm.text.title");
256 else if(!strcmp("subtitle", part))
257 snprintf(buf, sizeof(buf), "elm.text.subtitle");
259 snprintf(buf, sizeof(buf), "%s", part);
261 EINA_INLIST_FOREACH(navi_it->text_list, pair)
262 if (!strcmp(buf, pair->part)) break;
266 pair = ELM_NEW(Elm_Naviframe_Text_Item_Pair);
269 ERR("Failed to allocate new text part of the item! : naviframe=%p",
273 eina_stringshare_replace(&pair->part, buf);
274 navi_it->text_list = eina_inlist_append(navi_it->text_list,
275 EINA_INLIST_GET(pair));
278 eina_stringshare_replace(&pair->text, label);
279 edje_object_part_text_set(VIEW(navi_it), buf, label);
283 snprintf(buf, sizeof(buf), "elm,state,%s,show", buf);
284 edje_object_signal_emit(VIEW(navi_it), buf, "elm");
288 snprintf(buf, sizeof(buf), "elm,state,%s,hide", buf);
289 edje_object_signal_emit(VIEW(navi_it), buf, "elm");
292 _sizing_eval(WIDGET(navi_it));
296 _item_text_get_hook(const Elm_Object_Item *it, const char *part)
298 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
299 Elm_Naviframe_Text_Item_Pair *pair = NULL;
300 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
303 if (!part || !strcmp(part, "default"))
304 snprintf(buf, sizeof(buf), "elm.text.title");
305 else if(!strcmp("subtitle", part))
306 snprintf(buf, sizeof(buf), "elm.text.subtitle");
308 snprintf(buf, sizeof(buf), "%s", part);
310 EINA_INLIST_FOREACH(navi_it->text_list, pair)
312 if (!strcmp(buf, pair->part))
319 _item_content_set_hook(Elm_Object_Item *it,
321 Evas_Object *content)
323 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
325 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
328 if (!part || !strcmp("default", part))
330 _item_content_set(navi_it, content);
333 else if (!strcmp(part, "prev_btn"))
335 _title_prev_btn_set(navi_it, content, EINA_FALSE);
338 else if (!strcmp(part, "next_btn"))
340 _title_next_btn_set(navi_it, content);
343 else if (!strcmp(part, "icon"))
345 _title_icon_set(navi_it, content);
350 _title_content_set(navi_it, part, content);
354 _item_content_get_hook(const Elm_Object_Item *it, const char *part)
356 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
357 Elm_Naviframe_Content_Item_Pair *pair = NULL;
358 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
361 if (!part || !strcmp("default", part))
362 return navi_it->content;
363 else if (!strcmp(part, "prev_btn"))
364 return navi_it->title_prev_btn;
365 else if (!strcmp(part, "next_btn"))
366 return navi_it->title_next_btn;
367 else if (!strcmp(part, "icon"))
368 return navi_it->title_icon;
371 EINA_INLIST_FOREACH(navi_it->content_list, pair)
373 if (!strcmp(part, pair->part))
374 return pair->content;
380 _item_content_unset_hook(Elm_Object_Item *it, const char *part)
382 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
383 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
386 if (!part || !strcmp("default", part))
387 return _item_content_unset(navi_it);
388 else if (!strcmp(part, "prev_btn"))
389 return _title_prev_btn_unset(navi_it);
390 else if (!strcmp(part, "next_btn"))
391 return _title_next_btn_unset(navi_it);
392 else if (!strcmp(part, "icon"))
393 return _title_icon_unset(navi_it);
395 return _title_content_unset(navi_it, part);
399 _item_signal_emit_hook(Elm_Object_Item *it,
400 const char *emission,
403 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
404 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
405 edje_object_signal_emit(VIEW(navi_it), emission, source);
409 _item_title_visible_update(Elm_Naviframe_Item *navi_it)
411 if (navi_it->title_visible)
412 edje_object_signal_emit(VIEW(navi_it), "elm,state,title,show", "elm");
414 edje_object_signal_emit(VIEW(navi_it), "elm,state,title,hide", "elm");
418 _sizing_eval(Evas_Object *obj)
421 Elm_Naviframe_Item *it;
422 Evas_Coord x, y, w, h;
423 Evas_Coord minw = -1, minh = -1;
425 wd = elm_widget_data_get(obj);
428 evas_object_geometry_get(obj, &x, &y, &w, &h);
430 EINA_INLIST_FOREACH(wd->stack, it)
432 evas_object_move(VIEW(it), x, y);
433 evas_object_resize(VIEW(it), w, h);
434 edje_object_size_min_calc(VIEW(it), &it->minw, &it->minh);
435 if (it->minw > minw) minw = it->minw;
436 if (it->minh > minh) minh = it->minh;
438 evas_object_size_hint_min_set(obj, minw, minh);
439 evas_object_size_hint_max_set(obj, -1, -1);
443 _move(void *data __UNUSED__,
446 void *event_info __UNUSED__)
452 _resize(void *data __UNUSED__,
455 void *event_info __UNUSED__)
461 _title_clicked(void *data,
462 Evas_Object *obj __UNUSED__,
463 const char *emission __UNUSED__,
464 const char *source __UNUSED__)
466 Elm_Naviframe_Item *it = data;
467 evas_object_smart_callback_call(WIDGET(it), SIG_TITLE_CLICKED, it);
471 _back_btn_clicked(void *data,
473 void *event_info __UNUSED__)
475 /* Since edje has the event queue, clicked event could be happend multiple times
476 on some heavy environment. This callback del will prevent those scenario and
477 guarantee only one clicked for it's own page. */
478 evas_object_smart_callback_del(obj, "clicked", _back_btn_clicked);
479 elm_naviframe_item_pop(data);
483 _back_btn_new(Evas_Object *obj)
487 btn = elm_button_add(obj);
488 if (!btn) return NULL;
489 evas_object_smart_callback_add(btn, "clicked", _back_btn_clicked, obj);
490 snprintf(buf, sizeof(buf), "naviframe/back_btn/%s", elm_widget_style_get(obj));
491 elm_object_style_set(btn, buf);
496 _title_content_del(void *data,
498 Evas_Object *obj __UNUSED__,
499 void *event_info __UNUSED__)
502 Elm_Naviframe_Content_Item_Pair *pair = data;
503 Elm_Naviframe_Item *it = pair->it;
504 snprintf(buf, sizeof(buf), "elm,state,%s,hide", pair->part);
505 edje_object_signal_emit(VIEW(it), buf, "elm");
506 it->content_list = eina_inlist_remove(it->content_list,
507 EINA_INLIST_GET(pair));
508 eina_stringshare_del(pair->part);
513 _title_prev_btn_del(void *data,
515 Evas_Object *obj __UNUSED__,
516 void *event_info __UNUSED__)
518 Elm_Naviframe_Item *it = data;
519 it->back_btn = EINA_FALSE;
520 it->title_prev_btn = NULL;
521 edje_object_signal_emit(VIEW(it), "elm,state,prev_btn,hide", "elm");
525 _title_next_btn_del(void *data,
527 Evas_Object *obj __UNUSED__,
528 void *event_info __UNUSED__)
530 Elm_Naviframe_Item *it = data;
531 it->title_next_btn = NULL;
532 edje_object_signal_emit(VIEW(it), "elm,state,next_btn,hide", "elm");
536 _title_icon_del(void *data,
538 Evas_Object *obj __UNUSED__,
539 void *event_info __UNUSED__)
541 Elm_Naviframe_Item *it = data;
542 it->title_icon = NULL;
543 edje_object_signal_emit(VIEW(it), "elm,state,icon,hide", "elm");
547 _item_content_del(void *data,
549 Evas_Object *obj __UNUSED__,
550 void *event_info __UNUSED__)
552 Elm_Naviframe_Item *it = data;
554 edje_object_signal_emit(VIEW(it), "elm,state,content,hide", "elm");
558 _title_content_set(Elm_Naviframe_Item *it,
560 Evas_Object *content)
563 Elm_Naviframe_Content_Item_Pair *pair = NULL;
565 EINA_INLIST_FOREACH(it->content_list, pair)
566 if (!strcmp(part, pair->part)) break;
570 if (pair->content != content)
574 evas_object_event_callback_del(pair->content,
577 evas_object_event_callback_del(pair->content,
578 EVAS_CALLBACK_CHANGED_SIZE_HINTS,
579 _changed_size_hints);
580 snprintf(buf, sizeof(buf), "elm,state,%s,hide", part);
581 edje_object_signal_emit(VIEW(it), buf, "elm");
583 evas_object_del(pair->content);
584 if (!content) return;
589 if (!content) return;
590 pair = ELM_NEW(Elm_Naviframe_Content_Item_Pair);
593 ERR("Failed to allocate new content part of the item! : naviframe=%p", WIDGET(it));
597 eina_stringshare_replace(&pair->part, part);
598 it->content_list = eina_inlist_append(it->content_list,
599 EINA_INLIST_GET(pair));
601 if (pair->content != content)
603 elm_widget_sub_object_add(WIDGET(it), content);
604 evas_object_event_callback_add(content,
608 evas_object_event_callback_add(content,
609 EVAS_CALLBACK_CHANGED_SIZE_HINTS,
613 edje_object_part_swallow(VIEW(it), part, content);
614 snprintf(buf, sizeof(buf), "elm,state,%s,show", part);
615 edje_object_signal_emit(VIEW(it), buf, "elm");
616 pair->content = content;
618 _sizing_eval(WIDGET(it));
622 _title_prev_btn_set(Elm_Naviframe_Item *it,
626 if (it->title_prev_btn == btn) return;
628 if (it->title_prev_btn)
629 evas_object_del(it->title_prev_btn);
631 it->title_prev_btn = btn;
634 elm_widget_sub_object_add(WIDGET(it), btn);
635 evas_object_event_callback_add(btn,
639 evas_object_event_callback_add(btn,
640 EVAS_CALLBACK_CHANGED_SIZE_HINTS,
643 edje_object_part_swallow(VIEW(it), "elm.swallow.prev_btn", btn);
644 edje_object_signal_emit(VIEW(it), "elm,state,prev_btn,show", "elm");
645 it->back_btn = back_btn;
647 _sizing_eval(WIDGET(it));
651 _title_next_btn_set(Elm_Naviframe_Item *it, Evas_Object *btn)
653 if (it->title_next_btn == btn) return;
655 if (it->title_next_btn)
656 evas_object_del(it->title_next_btn);
658 it->title_next_btn = btn;
661 elm_widget_sub_object_add(WIDGET(it), btn);
662 evas_object_event_callback_add(btn,
666 evas_object_event_callback_add(btn,
667 EVAS_CALLBACK_CHANGED_SIZE_HINTS,
670 edje_object_part_swallow(VIEW(it), "elm.swallow.next_btn", btn);
671 edje_object_signal_emit(VIEW(it), "elm,state,next_btn,show", "elm");
673 _sizing_eval(WIDGET(it));
677 _title_icon_set(Elm_Naviframe_Item *it, Evas_Object *icon)
679 if (it->title_icon == icon) return;
682 evas_object_del(it->title_icon);
684 it->title_icon = icon;
687 elm_widget_sub_object_add(WIDGET(it), icon);
688 evas_object_event_callback_add(icon,
692 evas_object_event_callback_add(icon,
693 EVAS_CALLBACK_CHANGED_SIZE_HINTS,
696 edje_object_part_swallow(VIEW(it), "elm.swallow.icon", icon);
697 edje_object_signal_emit(VIEW(it), "elm,state,icon,show", "elm");
699 _sizing_eval(WIDGET(it));
703 _item_content_unset(Elm_Naviframe_Item *it)
705 Evas_Object *content = it->content;
706 if (!content) return NULL;
708 elm_widget_sub_object_del(WIDGET(it), content);
709 edje_object_part_unswallow(VIEW(it), content);
710 edje_object_signal_emit(VIEW(it), "elm,state,content,hide", "elm");
711 evas_object_event_callback_del(content,
714 evas_object_event_callback_del(content,
715 EVAS_CALLBACK_CHANGED_SIZE_HINTS,
716 _changed_size_hints);
717 _sizing_eval(WIDGET(it));
724 _title_prev_btn_unset(Elm_Naviframe_Item *it)
726 Evas_Object *content = it->title_prev_btn;
727 if (!content) return NULL;
729 elm_widget_sub_object_del(WIDGET(it), content);
730 edje_object_part_unswallow(VIEW(it), content);
731 edje_object_signal_emit(VIEW(it), "elm,state,prev_btn,hide", "elm");
732 evas_object_event_callback_del(content,
734 _title_prev_btn_del);
735 evas_object_event_callback_del(content,
736 EVAS_CALLBACK_CHANGED_SIZE_HINTS,
737 _changed_size_hints);
738 _sizing_eval(WIDGET(it));
740 it->title_prev_btn = NULL;
745 _title_next_btn_unset(Elm_Naviframe_Item *it)
747 Evas_Object *content = it->title_next_btn;
748 if (!content) return NULL;
750 elm_widget_sub_object_del(WIDGET(it), content);
751 edje_object_part_unswallow(VIEW(it), content);
752 edje_object_signal_emit(VIEW(it), "elm,state,next_btn,hide", "elm");
753 evas_object_event_callback_del(content,
755 _title_next_btn_del);
756 evas_object_event_callback_del(content,
757 EVAS_CALLBACK_CHANGED_SIZE_HINTS,
758 _changed_size_hints);
759 _sizing_eval(WIDGET(it));
761 it->title_next_btn = NULL;
766 _title_icon_unset(Elm_Naviframe_Item *it)
768 Evas_Object *content = it->title_icon;
769 if (!content) return NULL;
771 elm_widget_sub_object_del(WIDGET(it), content);
772 edje_object_part_unswallow(VIEW(it), content);
773 edje_object_signal_emit(VIEW(it), "elm,state,icon,hide", "elm");
774 evas_object_event_callback_del(content,
777 evas_object_event_callback_del(content,
778 EVAS_CALLBACK_CHANGED_SIZE_HINTS,
779 _changed_size_hints);
780 _sizing_eval(WIDGET(it));
781 it->title_icon = NULL;
787 _title_content_unset(Elm_Naviframe_Item *it, const char *part)
789 Elm_Naviframe_Content_Item_Pair *pair = NULL;
791 Evas_Object *content = NULL;
793 EINA_INLIST_FOREACH(it->content_list, pair)
795 if (!strcmp(part, pair->part))
797 content = pair->content;
798 eina_stringshare_del(pair->part);
799 it->content_list = eina_inlist_remove(it->content_list,
800 EINA_INLIST_GET(pair));
806 if (!content) return NULL;
808 elm_widget_sub_object_del(WIDGET(it), content);
809 edje_object_part_unswallow(VIEW(it), content);
810 snprintf(buf, sizeof(buf), "elm,state,%s,hide", part);
811 edje_object_signal_emit(VIEW(it), buf, "elm");
812 evas_object_event_callback_del(content,
815 evas_object_event_callback_del(content,
816 EVAS_CALLBACK_CHANGED_SIZE_HINTS,
817 _changed_size_hints);
818 _sizing_eval(WIDGET(it));
824 _item_del(Elm_Naviframe_Item *it)
827 Elm_Naviframe_Content_Item_Pair *content_pair;
828 Elm_Naviframe_Text_Item_Pair *text_pair;
832 wd = elm_widget_data_get(WIDGET(it));
835 if (it->title_prev_btn)
836 evas_object_del(it->title_prev_btn);
837 if (it->title_next_btn)
838 evas_object_del(it->title_next_btn);
840 evas_object_del(it->title_icon);
841 if ((it->content) && (!wd->preserve))
842 evas_object_del(it->content);
844 while (it->content_list)
846 content_pair = EINA_INLIST_CONTAINER_GET(it->content_list,
847 Elm_Naviframe_Content_Item_Pair);
848 evas_object_event_callback_del(content_pair->content,
851 evas_object_event_callback_del(content_pair->content,
852 EVAS_CALLBACK_CHANGED_SIZE_HINTS,
853 _changed_size_hints);
854 evas_object_del(content_pair->content);
855 eina_stringshare_del(content_pair->part);
856 it->content_list = eina_inlist_remove(it->content_list,
861 while (it->text_list)
863 text_pair = EINA_INLIST_CONTAINER_GET(it->text_list,
864 Elm_Naviframe_Text_Item_Pair);
865 eina_stringshare_del(text_pair->part);
866 eina_stringshare_del(text_pair->text);
867 it->text_list = eina_inlist_remove(it->text_list,
872 eina_stringshare_del(it->style);
876 _item_del_pre_hook(Elm_Object_Item *it)
878 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
879 Elm_Naviframe_Item *navi_it;
882 navi_it =(Elm_Naviframe_Item *) it;
883 wd = elm_widget_data_get(WIDGET(navi_it));
886 if (it == elm_naviframe_top_item_get(WIDGET(navi_it)))
888 wd->stack = eina_inlist_remove(wd->stack, EINA_INLIST_GET(navi_it));
890 elm_widget_item_free(navi_it);
891 //If the item is only one, the stack will be empty
892 if (!wd->stack) return;
893 navi_it = EINA_INLIST_CONTAINER_GET(wd->stack->last,
895 evas_object_show(VIEW(navi_it));
896 evas_object_raise(VIEW(navi_it));
897 edje_object_signal_emit(VIEW(navi_it), "elm,state,visible", "elm");
901 wd->stack = eina_inlist_remove(wd->stack, EINA_INLIST_GET(navi_it));
903 elm_widget_item_free(navi_it);
908 _pushed_finished(void *data,
909 Evas_Object *obj __UNUSED__,
910 const char *emission __UNUSED__,
911 const char *source __UNUSED__)
914 Elm_Naviframe_Item *it = data;
917 wd = elm_widget_data_get(WIDGET(it));
920 evas_object_hide(VIEW(it));
921 evas_object_smart_callback_call(WIDGET(it),
924 if (wd->freeze_events)
925 evas_object_freeze_events_set(VIEW(it), EINA_FALSE);
929 _popped_finished(void *data,
930 Evas_Object *obj __UNUSED__,
931 const char *emission __UNUSED__,
932 const char *source __UNUSED__)
934 Elm_Naviframe_Item *it = data;
936 evas_object_smart_callback_call(WIDGET(it),
940 elm_widget_item_free(data);
944 _show_finished(void *data,
945 Evas_Object *obj __UNUSED__,
946 const char *emission __UNUSED__,
947 const char *source __UNUSED__)
949 Elm_Naviframe_Item *it;
954 wd = elm_widget_data_get(WIDGET(it));
957 evas_object_smart_callback_call(WIDGET(it),
958 SIG_TRANSITION_FINISHED,
960 if (wd->freeze_events)
961 evas_object_freeze_events_set(VIEW(it), EINA_FALSE);
965 _changed_size_hints(void *data,
967 Evas_Object *obj __UNUSED__,
968 void *event_info __UNUSED__)
974 _item_content_set(Elm_Naviframe_Item *navi_it, Evas_Object *content)
976 if (navi_it->content == content) return;
977 if (navi_it->content) evas_object_del(navi_it->content);
978 elm_widget_sub_object_add(WIDGET(navi_it), content);
979 edje_object_part_swallow(VIEW(navi_it),
980 "elm.swallow.content",
983 edje_object_signal_emit(VIEW(navi_it),
984 "elm,state,content,show",
987 edje_object_signal_emit(VIEW(navi_it),
988 "elm,state,content,hide",
990 evas_object_event_callback_add(content,
994 evas_object_event_callback_add(content,
995 EVAS_CALLBACK_CHANGED_SIZE_HINTS,
998 navi_it->content = content;
999 _sizing_eval(WIDGET(navi_it));
1002 //FIXME: need to handle if this function is called while transition
1004 _item_style_set(Elm_Naviframe_Item *navi_it, const char *item_style)
1006 Elm_Naviframe_Content_Item_Pair *content_pair;
1007 Elm_Naviframe_Text_Item_Pair *text_pair;
1014 strcpy(buf, "item/basic");
1015 eina_stringshare_replace(&navi_it->style, "basic");
1019 snprintf(buf, sizeof(buf), "item/%s", item_style);
1020 eina_stringshare_replace(&navi_it->style, item_style);
1022 _elm_theme_object_set(WIDGET(navi_it),
1026 elm_widget_style_get(WIDGET(navi_it)));
1028 EINA_INLIST_FOREACH(navi_it->text_list, text_pair)
1029 _item_text_set_hook((Elm_Object_Item *) navi_it,
1033 EINA_INLIST_FOREACH(navi_it->content_list, content_pair)
1034 _item_content_set_hook((Elm_Object_Item *) navi_it,
1036 content_pair->content);
1038 if (navi_it->content)
1040 edje_object_part_swallow(VIEW(navi_it),
1041 "elm.swallow.content",
1043 edje_object_signal_emit(VIEW(navi_it),
1044 "elm,state,content,show",
1049 if (navi_it->title_prev_btn)
1051 edje_object_part_swallow(VIEW(navi_it),
1052 "elm.swallow.prev_btn",
1053 navi_it->title_prev_btn);
1054 edje_object_signal_emit(VIEW(navi_it),
1055 "elm,state,prev_btn,show",
1060 if (navi_it->title_next_btn)
1062 edje_object_part_swallow(VIEW(navi_it),
1063 "elm.swallow.next_btn",
1064 navi_it->title_next_btn);
1065 edje_object_signal_emit(VIEW(navi_it),
1066 "elm,state,next_btn,show",
1070 navi_it->title_visible = EINA_TRUE;
1071 _sizing_eval(WIDGET(navi_it));
1073 wd = elm_widget_data_get(WIDGET(navi_it));
1076 if (wd->freeze_events)
1077 evas_object_freeze_events_set(VIEW(navi_it), EINA_FALSE);
1080 static Elm_Naviframe_Item *
1081 _item_new(Evas_Object *obj,
1082 const char *title_label,
1083 Evas_Object *prev_btn,
1084 Evas_Object *next_btn,
1085 Evas_Object *content,
1086 const char *item_style)
1088 Widget_Data *wd = elm_widget_data_get(obj);
1091 Elm_Naviframe_Item *it = elm_widget_item_new(obj, Elm_Naviframe_Item);
1094 ERR("Failed to allocate new item! : naviframe=%p", obj);
1098 elm_widget_item_del_pre_hook_set(it, _item_del_pre_hook);
1099 elm_widget_item_text_set_hook_set(it, _item_text_set_hook);
1100 elm_widget_item_text_get_hook_set(it, _item_text_get_hook);
1101 elm_widget_item_content_set_hook_set(it, _item_content_set_hook);
1102 elm_widget_item_content_get_hook_set(it, _item_content_get_hook);
1103 elm_widget_item_content_unset_hook_set(it, _item_content_unset_hook);
1104 elm_widget_item_signal_emit_hook_set(it, _item_signal_emit_hook);
1107 VIEW(it) = edje_object_add(evas_object_evas_get(obj));
1108 edje_object_mirrored_set(VIEW(it), elm_widget_mirrored_get(obj));
1109 evas_object_smart_member_add(VIEW(it), wd->base);
1110 elm_widget_sub_object_add(obj, VIEW(it));
1111 edje_object_signal_callback_add(VIEW(it),
1112 "elm,action,show,finished",
1114 _show_finished, it);
1115 edje_object_signal_callback_add(VIEW(it),
1116 "elm,action,pushed,finished",
1118 _pushed_finished, it);
1119 edje_object_signal_callback_add(VIEW(it),
1120 "elm,action,popped,finished",
1122 _popped_finished, it);
1123 edje_object_signal_callback_add(VIEW(it),
1124 "elm,action,title,clicked",
1126 _title_clicked, it);
1128 _item_style_set(it, item_style);
1129 _item_text_set_hook((Elm_Object_Item *) it, "elm.text.title", title_label);
1132 if ((!prev_btn) && wd->auto_pushed && eina_inlist_count(wd->stack))
1134 prev_btn = _back_btn_new(obj);
1135 _title_prev_btn_set(it, prev_btn, EINA_TRUE);
1138 _title_prev_btn_set(it, prev_btn, EINA_FALSE);
1140 _title_next_btn_set(it, next_btn);
1141 _item_content_set(it, content);
1142 it->title_visible = EINA_TRUE;
1147 elm_naviframe_add(Evas_Object *parent)
1153 ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL);
1154 ELM_SET_WIDTYPE(widtype, "naviframe");
1155 elm_widget_type_set(obj, "naviframe");
1156 elm_widget_sub_object_add(parent, obj);
1157 elm_widget_data_set(obj, wd);
1158 elm_widget_del_hook_set(obj, _del_hook);
1159 elm_widget_disable_hook_set(obj, _disable_hook);
1160 elm_widget_theme_hook_set(obj, _theme_hook);
1161 elm_widget_signal_emit_hook_set(obj, _emit_hook);
1164 wd->base = edje_object_add(e);
1165 edje_object_mirrored_set(wd->base, elm_widget_mirrored_get(obj));
1166 elm_widget_resize_object_set(obj, wd->base);
1167 _elm_theme_object_set(obj, wd->base, "naviframe", "base", "default");
1169 evas_object_event_callback_add(obj, EVAS_CALLBACK_MOVE, _move, obj);
1170 evas_object_event_callback_add(obj, EVAS_CALLBACK_RESIZE, _resize, obj);
1171 evas_object_smart_callbacks_descriptions_set(obj, _signals);
1173 wd->auto_pushed = EINA_TRUE;
1174 wd->freeze_events = EINA_TRUE;
1179 EAPI Elm_Object_Item *
1180 elm_naviframe_item_push(Evas_Object *obj,
1181 const char *title_label,
1182 Evas_Object *prev_btn,
1183 Evas_Object *next_btn,
1184 Evas_Object *content,
1185 const char *item_style)
1187 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1189 Elm_Naviframe_Item *prev_it, *it;
1191 wd = elm_widget_data_get(obj);
1192 if (!wd) return NULL;
1194 it = _item_new(obj, title_label, prev_btn, next_btn, content, item_style);
1195 if (!it) return NULL;
1197 evas_object_show(VIEW(it));
1199 prev_it = (Elm_Naviframe_Item *) elm_naviframe_top_item_get(obj);
1202 if (wd->freeze_events)
1204 evas_object_freeze_events_set(VIEW(it), EINA_TRUE);
1205 evas_object_freeze_events_set(VIEW(prev_it), EINA_TRUE);
1207 edje_object_signal_emit(VIEW(prev_it),
1208 "elm,state,cur,pushed",
1210 edje_object_signal_emit(VIEW(it),
1211 "elm,state,new,pushed",
1213 edje_object_message_signal_process(VIEW(prev_it));
1214 edje_object_message_signal_process(VIEW(it));
1216 wd->stack = eina_inlist_append(wd->stack, EINA_INLIST_GET(it));
1218 return (Elm_Object_Item *) it;
1221 EAPI Elm_Object_Item *
1222 elm_naviframe_item_insert_before(Elm_Object_Item *before,
1223 const char *title_label,
1224 Evas_Object *prev_btn,
1225 Evas_Object *next_btn,
1226 Evas_Object *content,
1227 const char *item_style)
1229 ELM_OBJ_ITEM_CHECK_OR_RETURN(before, NULL);
1230 Elm_Naviframe_Item *it;
1233 wd = elm_widget_data_get(WIDGET(before));
1234 if (!wd) return NULL;
1236 it = _item_new(WIDGET(before), title_label, prev_btn, next_btn, content,
1238 if (!it) return NULL;
1241 eina_inlist_prepend_relative(wd->stack, EINA_INLIST_GET(it),
1242 EINA_INLIST_GET(((Elm_Naviframe_Item *) before)));
1243 _sizing_eval(WIDGET(before));
1244 return (Elm_Object_Item *) it;
1247 EAPI Elm_Object_Item *
1248 elm_naviframe_item_insert_after(Elm_Object_Item *after,
1249 const char *title_label,
1250 Evas_Object *prev_btn,
1251 Evas_Object *next_btn,
1252 Evas_Object *content,
1253 const char *item_style)
1255 ELM_OBJ_ITEM_CHECK_OR_RETURN(after, NULL);
1256 Elm_Naviframe_Item *it;
1259 wd = elm_widget_data_get(WIDGET(after));
1260 if (!wd) return NULL;
1262 it = _item_new(WIDGET(after), title_label, prev_btn, next_btn, content,
1264 if (!it) return NULL;
1266 if (elm_naviframe_top_item_get(WIDGET(after)) == after)
1268 evas_object_hide(VIEW(after));
1269 evas_object_show(VIEW(it));
1272 eina_inlist_append_relative(wd->stack, EINA_INLIST_GET(it),
1273 EINA_INLIST_GET(((Elm_Naviframe_Item *) after)));
1274 _sizing_eval(WIDGET(after));
1275 return (Elm_Object_Item *) it;
1279 elm_naviframe_item_pop(Evas_Object *obj)
1281 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1282 Elm_Naviframe_Item *it, *prev_it = NULL;
1284 Evas_Object *content = NULL;
1286 wd = elm_widget_data_get(obj);
1287 if (!wd) return NULL;
1289 it = (Elm_Naviframe_Item *) elm_naviframe_top_item_get(obj);
1290 if (!it) return NULL;
1291 elm_widget_tree_unfocusable_set(it->content, EINA_TRUE);
1293 content = it->content;
1295 if (wd->stack->last->prev)
1296 prev_it = EINA_INLIST_CONTAINER_GET(wd->stack->last->prev,
1297 Elm_Naviframe_Item);
1298 wd->stack = eina_inlist_remove(wd->stack, EINA_INLIST_GET(it));
1301 if (wd->freeze_events)
1303 evas_object_freeze_events_set(VIEW(it), EINA_TRUE);
1304 evas_object_freeze_events_set(VIEW(prev_it), EINA_TRUE);
1306 edje_object_signal_emit(VIEW(it), "elm,state,cur,popped", "elm");
1307 evas_object_show(VIEW(prev_it));
1308 evas_object_raise(VIEW(prev_it));
1309 edje_object_signal_emit(VIEW(prev_it),
1310 "elm,state,prev,popped",
1312 edje_object_message_signal_process(VIEW(it));
1313 edje_object_message_signal_process(VIEW(prev_it));
1318 elm_widget_item_free(it);
1325 elm_naviframe_item_pop_to(Elm_Object_Item *it)
1327 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1328 Elm_Naviframe_Item *navi_it;
1330 Eina_Inlist *l, *prev_l;
1332 navi_it = (Elm_Naviframe_Item *) it;
1333 wd = elm_widget_data_get(WIDGET(navi_it));
1336 if (it == elm_naviframe_top_item_get(WIDGET(navi_it))) return;
1338 l = wd->stack->last->prev;
1342 if (EINA_INLIST_CONTAINER_GET(l, Elm_Naviframe_Item) ==
1343 ((Elm_Naviframe_Item *) it)) break;
1345 wd->stack = eina_inlist_remove(wd->stack, l);
1346 _item_del(EINA_INLIST_CONTAINER_GET(l, Elm_Naviframe_Item));
1347 elm_widget_item_free(EINA_INLIST_CONTAINER_GET(l,
1348 Elm_Naviframe_Item));
1351 elm_naviframe_item_pop(WIDGET(navi_it));
1355 elm_naviframe_item_promote(Elm_Object_Item *it)
1357 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1358 Elm_Naviframe_Item *navi_it;
1359 Elm_Naviframe_Item *prev_it;
1362 navi_it = (Elm_Naviframe_Item *) it;
1363 wd = elm_widget_data_get(navi_it->base.widget);
1366 if (it == elm_naviframe_top_item_get(navi_it->base.widget)) return;
1367 wd->stack = eina_inlist_demote(wd->stack, EINA_INLIST_GET(navi_it));
1368 prev_it = EINA_INLIST_CONTAINER_GET(wd->stack->last->prev,
1369 Elm_Naviframe_Item);
1370 if (wd->freeze_events)
1372 evas_object_freeze_events_set(VIEW(it), EINA_TRUE);
1373 evas_object_freeze_events_set(VIEW(prev_it), EINA_TRUE);
1375 edje_object_signal_emit(VIEW(prev_it),
1376 "elm,state,cur,pushed",
1378 evas_object_show(VIEW(navi_it));
1379 evas_object_raise(VIEW(navi_it));
1380 edje_object_signal_emit(VIEW(navi_it),
1381 "elm,state,new,pushed",
1383 edje_object_message_signal_process(VIEW(prev_it));
1384 edje_object_message_signal_process(VIEW(navi_it));
1388 elm_naviframe_item_del(Elm_Object_Item *it)
1390 elm_object_item_del(it);
1394 elm_naviframe_content_preserve_on_pop_set(Evas_Object *obj, Eina_Bool preserve)
1396 ELM_CHECK_WIDTYPE(obj, widtype);
1397 Widget_Data *wd = elm_widget_data_get(obj);
1399 wd->preserve = !!preserve;
1403 elm_naviframe_content_preserve_on_pop_get(const Evas_Object *obj)
1405 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
1406 Widget_Data *wd = elm_widget_data_get(obj);
1407 if (!wd) return EINA_FALSE;
1408 return wd->preserve;
1411 EAPI Elm_Object_Item*
1412 elm_naviframe_top_item_get(const Evas_Object *obj)
1414 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1415 Widget_Data *wd = elm_widget_data_get(obj);
1416 if ((!wd) || (!wd->stack)) return NULL;
1417 return (Elm_Object_Item *) (EINA_INLIST_CONTAINER_GET(wd->stack->last,
1418 Elm_Naviframe_Item));
1421 EAPI Elm_Object_Item*
1422 elm_naviframe_bottom_item_get(const Evas_Object *obj)
1424 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1425 Widget_Data *wd = elm_widget_data_get(obj);
1426 if ((!wd) || (!wd->stack)) return NULL;
1427 return (Elm_Object_Item *) (EINA_INLIST_CONTAINER_GET(wd->stack,
1428 Elm_Naviframe_Item));
1432 elm_naviframe_item_style_set(Elm_Object_Item *it, const char *item_style)
1434 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1435 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
1437 //Return if new style is exsiting one.
1439 if (!strcmp(item_style, navi_it->style)) return;
1442 if (!strcmp("basic", navi_it->style)) return;
1444 _item_style_set(navi_it, item_style);
1448 elm_naviframe_item_style_get(const Elm_Object_Item *it)
1450 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
1451 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
1452 return navi_it->style;
1456 elm_naviframe_item_title_visible_set(Elm_Object_Item *it, Eina_Bool visible)
1458 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1459 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
1461 visible = !!visible;
1462 if (navi_it->title_visible == visible) return;
1464 navi_it->title_visible = visible;
1465 _item_title_visible_update(navi_it);
1469 elm_naviframe_item_title_visible_get(const Elm_Object_Item *it)
1471 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
1472 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
1473 return navi_it->title_visible;
1477 elm_naviframe_prev_btn_auto_pushed_set(Evas_Object *obj, Eina_Bool auto_pushed)
1479 ELM_CHECK_WIDTYPE(obj, widtype);
1480 Widget_Data *wd = elm_widget_data_get(obj);
1482 wd->auto_pushed = !!auto_pushed;
1486 elm_naviframe_prev_btn_auto_pushed_get(const Evas_Object *obj)
1488 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
1489 Widget_Data *wd = elm_widget_data_get(obj);
1490 if (!wd) return EINA_FALSE;
1491 return wd->auto_pushed;
1495 elm_naviframe_items_get(const Evas_Object *obj)
1497 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1498 Widget_Data *wd = elm_widget_data_get(obj);
1499 if (!wd) return NULL;
1504 elm_naviframe_event_enabled_set(Evas_Object *obj, Eina_Bool enabled)
1506 ELM_CHECK_WIDTYPE(obj, widtype);
1507 Widget_Data *wd = elm_widget_data_get(obj);
1509 enabled = !!enabled;
1510 if (wd->freeze_events == !enabled) return;
1511 wd->freeze_events = !enabled;
1515 elm_naviframe_event_enabled_get(const Evas_Object *obj)
1517 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
1518 Widget_Data *wd = elm_widget_data_get(obj);
1519 if (!wd) return EINA_FALSE;
1520 return !wd->freeze_events;