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;
52 static const char SIG_TRANSITION_FINISHED[] = "transition,finished";
53 static const char SIG_TITLE_CLICKED[] = "title,clicked";
56 static const char SIG_ITEM_SHOW_BEGIN[] = "show,begin";
57 static const char SIG_ITEM_HIDE_FINISHED[] = "hide,finished";
59 static const Evas_Smart_Cb_Description _signals[] = {
60 {SIG_TRANSITION_FINISHED, ""},
61 {SIG_TITLE_CLICKED, ""},
62 {SIG_ITEM_SHOW_BEGIN, ""},
63 {SIG_ITEM_HIDE_FINISHED, ""},
67 static void _text_set_hook(Evas_Object *obj,
70 static const char *_text_get_hook(const Evas_Object *obj, const char *part);
71 static void _content_set_hook(Evas_Object *obj,
73 Evas_Object *content);
74 static Evas_Object *_content_get_hook(const Evas_Object *obj, const char *part);
75 static Evas_Object *_content_unset_hook(Evas_Object *obj, const char *part);
76 static void _del_hook(Evas_Object *obj);
77 static void _theme_hook(Evas_Object *obj);
78 static void _emit_hook(Evas_Object *obj,
81 static void _disable_hook(Evas_Object *obj);
82 static void _item_text_set_hook(Elm_Object_Item *it,
85 static const char *_item_text_get_hook(const Elm_Object_Item *it,
87 static void _item_content_set_hook(Elm_Object_Item *it,
89 Evas_Object *content);
90 static Evas_Object *_item_content_get_hook(const Elm_Object_Item *it,
92 static Evas_Object *_item_content_unset_hook(Elm_Object_Item *it,
94 static void _item_signal_emit_hook(Elm_Object_Item *it,
97 static void _item_title_visible_update(Elm_Naviframe_Item *navi_it);
98 static void _sizing_eval(Evas_Object *obj);
99 static void _move(void *data, Evas *e, Evas_Object *obj, void *event_info);
100 static void _resize(void *data,
104 static void _title_clicked(void *data, Evas_Object *obj,
105 const char *emission,
107 static void _back_btn_clicked(void *data,
110 static Evas_Object *_back_btn_new(Evas_Object *obj);
111 static void _item_content_del(void *data,
115 static void _title_content_del(void *data,
119 static void _title_prev_btn_del(void *data,
123 static void _title_next_btn_del(void *data,
127 static void _title_icon_del(void *data,
131 static void _title_content_set(Elm_Naviframe_Item *it,
133 Evas_Object *content);
134 static void _title_prev_btn_set(Elm_Naviframe_Item *it,
137 static void _title_next_btn_set(Elm_Naviframe_Item *it, Evas_Object *btn);
138 static void _title_icon_set(Elm_Naviframe_Item *it, Evas_Object *icon);
139 static Evas_Object * _item_content_unset(Elm_Naviframe_Item *it);
140 static Evas_Object * _title_prev_btn_unset(Elm_Naviframe_Item *it);
141 static Evas_Object * _title_next_btn_unset(Elm_Naviframe_Item *it);
142 static Evas_Object * _title_icon_unset(Elm_Naviframe_Item *it);
143 static Evas_Object * _title_content_unset(Elm_Naviframe_Item *it,
145 static void _item_del(Elm_Naviframe_Item *it);
146 static Eina_Bool _item_del_pre_hook(Elm_Object_Item *it);
147 static void _pushed_finished(void *data,
149 const char *emission,
151 static void _popped_finished(void *data,
153 const char *emission,
155 static void _show_finished(void *data,
157 const char *emission,
159 static void _changed_size_hints(void *data,
163 static void _item_content_set(Elm_Naviframe_Item *navi_it,
164 Evas_Object *content);
165 static void _item_style_set(Elm_Naviframe_Item *navi_it,
166 const char *item_style);
167 static Elm_Naviframe_Item * _item_new(Evas_Object *obj,
168 const char *title_label,
169 Evas_Object *prev_btn,
170 Evas_Object *next_btn,
171 Evas_Object *content,
172 const char *item_style);
173 static Eina_Bool _focus_next_hook(const Evas_Object *obj,
174 Elm_Focus_Direction dir,
178 _del_hook(Evas_Object *obj)
181 Elm_Naviframe_Item *it;
183 wd = elm_widget_data_get(obj);
188 while (wd->stack->last)
190 it = EINA_INLIST_CONTAINER_GET(wd->stack->last,
192 wd->stack = eina_inlist_remove(wd->stack, wd->stack->last);
194 elm_widget_item_free(it);
195 if (!wd->stack) break;
198 eina_stringshare_del(wd->item_style);
203 _theme_hook(Evas_Object *obj)
206 Elm_Naviframe_Item *it;
208 wd = elm_widget_data_get(obj);
211 _elm_theme_object_set(obj,
215 elm_widget_style_get(obj));
217 EINA_INLIST_FOREACH(wd->stack, it)
218 _item_style_set(it, it->style);
220 _item_title_visible_update(it);
223 static void _emit_hook(Evas_Object *obj,
224 const char *emission,
227 Elm_Object_Item *it = elm_naviframe_top_item_get(obj);
229 return elm_object_item_signal_emit(it, emission, source);
233 _disable_hook(Evas_Object *obj __UNUSED__)
239 _item_text_set_hook(Elm_Object_Item *it,
243 Elm_Naviframe_Text_Item_Pair *pair = NULL;
244 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
247 if (!part || !strcmp(part, "default"))
248 snprintf(buf, sizeof(buf), "elm.text.title");
249 else if(!strcmp("subtitle", part))
250 snprintf(buf, sizeof(buf), "elm.text.subtitle");
252 snprintf(buf, sizeof(buf), "%s", part);
254 EINA_INLIST_FOREACH(navi_it->text_list, pair)
255 if (!strcmp(buf, pair->part)) break;
259 pair = ELM_NEW(Elm_Naviframe_Text_Item_Pair);
262 ERR("Failed to allocate new text part of the item! : naviframe=%p",
266 eina_stringshare_replace(&pair->part, buf);
267 navi_it->text_list = eina_inlist_append(navi_it->text_list,
268 EINA_INLIST_GET(pair));
270 elm_object_part_text_set(VIEW(navi_it), buf, label);
274 snprintf(buf, sizeof(buf), "elm,state,%s,show", buf);
275 elm_object_signal_emit(VIEW(navi_it), buf, "elm");
279 snprintf(buf, sizeof(buf), "elm,state,%s,hide", buf);
280 elm_object_signal_emit(VIEW(navi_it), buf, "elm");
283 _sizing_eval(WIDGET(navi_it));
287 _item_text_get_hook(const Elm_Object_Item *it, const char *part)
291 if (!part || !strcmp(part, "default"))
292 snprintf(buf, sizeof(buf), "elm.text.title");
293 else if(!strcmp("subtitle", part))
294 snprintf(buf, sizeof(buf), "elm.text.subtitle");
296 snprintf(buf, sizeof(buf), "%s", part);
298 return elm_object_part_text_get(VIEW(it), buf);
302 _item_content_set_hook(Elm_Object_Item *it,
304 Evas_Object *content)
306 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
309 if (!part || !strcmp("default", part))
311 _item_content_set(navi_it, content);
314 else if (!strcmp(part, "prev_btn"))
316 _title_prev_btn_set(navi_it, content, EINA_FALSE);
319 else if (!strcmp(part, "next_btn"))
321 _title_next_btn_set(navi_it, content);
324 else if (!strcmp(part, "icon"))
326 _title_icon_set(navi_it, content);
331 _title_content_set(navi_it, part, content);
335 _item_content_get_hook(const Elm_Object_Item *it, const char *part)
337 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
340 if (!part || !strcmp("default", part))
341 return navi_it->content;
342 else if (!strcmp(part, "prev_btn"))
343 return navi_it->title_prev_btn;
344 else if (!strcmp(part, "next_btn"))
345 return navi_it->title_next_btn;
346 else if (!strcmp(part, "icon"))
347 return navi_it->title_icon;
350 return elm_object_part_content_get(VIEW(navi_it), part);
354 _item_content_unset_hook(Elm_Object_Item *it, const char *part)
356 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
359 if (!part || !strcmp("default", part))
360 return _item_content_unset(navi_it);
361 else if (!strcmp(part, "prev_btn"))
362 return _title_prev_btn_unset(navi_it);
363 else if (!strcmp(part, "next_btn"))
364 return _title_next_btn_unset(navi_it);
365 else if (!strcmp(part, "icon"))
366 return _title_icon_unset(navi_it);
368 return _title_content_unset(navi_it, part);
372 _item_signal_emit_hook(Elm_Object_Item *it,
373 const char *emission,
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",
464 elm_widget_style_get(obj));
465 elm_object_style_set(btn, buf);
469 static void _text_set_hook(Evas_Object *obj,
473 Elm_Object_Item *it = elm_naviframe_top_item_get(obj);
475 elm_object_item_part_text_set(it, part, label);
478 static const char *_text_get_hook(const Evas_Object *obj, const char *part)
480 Elm_Object_Item *it = elm_naviframe_top_item_get(obj);
481 if (!it) return NULL;
482 return elm_object_item_part_text_get(it, part);
486 _content_set_hook(Evas_Object *obj, const char *part, Evas_Object *content)
488 Elm_Object_Item *it = elm_naviframe_top_item_get(obj);
490 elm_object_item_part_content_set(it, part, content);
494 _content_unset_hook(Evas_Object *obj, const char *part)
496 Elm_Object_Item *it = elm_naviframe_top_item_get(obj);
497 if (!it) return NULL;
498 return elm_object_item_part_content_unset(it, part);
502 _content_get_hook(const Evas_Object *obj, const char *part)
504 Elm_Object_Item *it = elm_naviframe_top_item_get(obj);
505 if (!it) return NULL;
506 return elm_object_item_part_content_get(it, part);
510 _title_content_del(void *data,
512 Evas_Object *obj __UNUSED__,
513 void *event_info __UNUSED__)
516 Elm_Naviframe_Content_Item_Pair *pair = data;
517 Elm_Naviframe_Item *it = pair->it;
518 snprintf(buf, sizeof(buf), "elm,state,%s,hide", pair->part);
519 elm_object_signal_emit(VIEW(it), buf, "elm");
520 it->content_list = eina_inlist_remove(it->content_list,
521 EINA_INLIST_GET(pair));
522 eina_stringshare_del(pair->part);
527 _title_prev_btn_del(void *data,
529 Evas_Object *obj __UNUSED__,
530 void *event_info __UNUSED__)
532 Elm_Naviframe_Item *it = data;
533 it->back_btn = EINA_FALSE;
534 it->title_prev_btn = NULL;
535 elm_object_signal_emit(VIEW(it), "elm,state,prev_btn,hide", "elm");
539 _title_next_btn_del(void *data,
541 Evas_Object *obj __UNUSED__,
542 void *event_info __UNUSED__)
544 Elm_Naviframe_Item *it = data;
545 it->title_next_btn = NULL;
546 elm_object_signal_emit(VIEW(it), "elm,state,next_btn,hide", "elm");
550 _title_icon_del(void *data,
552 Evas_Object *obj __UNUSED__,
553 void *event_info __UNUSED__)
555 Elm_Naviframe_Item *it = data;
556 it->title_icon = NULL;
557 elm_object_signal_emit(VIEW(it), "elm,state,icon,hide", "elm");
561 _item_content_del(void *data,
563 Evas_Object *obj __UNUSED__,
564 void *event_info __UNUSED__)
566 Elm_Naviframe_Item *it = data;
568 elm_object_signal_emit(VIEW(it), "elm,state,content,hide", "elm");
572 _title_content_set(Elm_Naviframe_Item *it,
574 Evas_Object *content)
577 Elm_Naviframe_Content_Item_Pair *pair = NULL;
578 Evas_Object *prev_content = NULL;
580 EINA_INLIST_FOREACH(it->content_list, pair)
581 if (!strcmp(part, pair->part)) break;
585 prev_content = elm_object_part_content_get(VIEW(it), part);
586 if (prev_content != content)
590 evas_object_event_callback_del(prev_content,
593 snprintf(buf, sizeof(buf), "elm,state,%s,hide", part);
594 elm_object_signal_emit(VIEW(it), buf, "elm");
596 evas_object_del(prev_content);
597 if (!content) return;
602 if (!content) return;
603 pair = ELM_NEW(Elm_Naviframe_Content_Item_Pair);
606 ERR("Failed to allocate new content part of the item! : naviframe=%p", WIDGET(it));
610 eina_stringshare_replace(&pair->part, part);
611 it->content_list = eina_inlist_append(it->content_list,
612 EINA_INLIST_GET(pair));
614 if (prev_content != content)
616 evas_object_event_callback_add(content,
621 elm_object_part_content_set(VIEW(it), part, content);
622 snprintf(buf, sizeof(buf), "elm,state,%s,show", part);
623 elm_object_signal_emit(VIEW(it), buf, "elm");
625 _sizing_eval(WIDGET(it));
629 _title_prev_btn_set(Elm_Naviframe_Item *it,
633 if (it->title_prev_btn == btn) return;
634 if (it->title_prev_btn) evas_object_del(it->title_prev_btn);
635 it->title_prev_btn = btn;
638 evas_object_event_callback_add(btn,
642 elm_object_part_content_set(VIEW(it), "elm.swallow.prev_btn", btn);
643 elm_object_signal_emit(VIEW(it), "elm,state,prev_btn,show", "elm");
644 it->back_btn = back_btn;
646 _sizing_eval(WIDGET(it));
650 _title_next_btn_set(Elm_Naviframe_Item *it, Evas_Object *btn)
652 if (it->title_next_btn == btn) return;
653 if (it->title_next_btn) evas_object_del(it->title_next_btn);
654 it->title_next_btn = btn;
657 evas_object_event_callback_add(btn,
661 elm_object_part_content_set(VIEW(it), "elm.swallow.next_btn", btn);
662 elm_object_signal_emit(VIEW(it), "elm,state,next_btn,show", "elm");
664 _sizing_eval(WIDGET(it));
668 _title_icon_set(Elm_Naviframe_Item *it, Evas_Object *icon)
670 if (it->title_icon == icon) return;
671 if (it->title_icon) evas_object_del(it->title_icon);
672 it->title_icon = icon;
675 evas_object_event_callback_add(icon,
679 elm_object_part_content_set(VIEW(it), "elm.swallow.icon", icon);
680 elm_object_signal_emit(VIEW(it), "elm,state,icon,show", "elm");
682 _sizing_eval(WIDGET(it));
686 _item_content_unset(Elm_Naviframe_Item *it)
688 Evas_Object *content = it->content;
689 if (!content) return NULL;
691 elm_object_part_content_unset(VIEW(it), "elm.swallow.content");
692 elm_object_signal_emit(VIEW(it), "elm,state,content,hide", "elm");
693 evas_object_event_callback_del(content,
696 _sizing_eval(WIDGET(it));
703 _title_prev_btn_unset(Elm_Naviframe_Item *it)
705 Evas_Object *content = it->title_prev_btn;
706 if (!content) return NULL;
708 elm_object_part_content_unset(VIEW(it), "elm.swallow.prev_btn");
709 elm_object_signal_emit(VIEW(it), "elm,state,prev_btn,hide", "elm");
710 evas_object_event_callback_del(content,
712 _title_prev_btn_del);
713 _sizing_eval(WIDGET(it));
715 it->title_prev_btn = NULL;
720 _title_next_btn_unset(Elm_Naviframe_Item *it)
722 Evas_Object *content = it->title_next_btn;
723 if (!content) return NULL;
725 elm_object_part_content_unset(VIEW(it), "elm.swallow.next_btn");
726 elm_object_signal_emit(VIEW(it), "elm,state,next_btn,hide", "elm");
727 evas_object_event_callback_del(content,
729 _title_next_btn_del);
730 _sizing_eval(WIDGET(it));
732 it->title_next_btn = NULL;
737 _title_icon_unset(Elm_Naviframe_Item *it)
739 Evas_Object *content = it->title_icon;
740 if (!content) return NULL;
742 elm_object_part_content_unset(VIEW(it), "elm.swallow.icon");
743 elm_object_signal_emit(VIEW(it), "elm,state,icon,hide", "elm");
744 evas_object_event_callback_del(content,
747 _sizing_eval(WIDGET(it));
748 it->title_icon = NULL;
754 _title_content_unset(Elm_Naviframe_Item *it, const char *part)
756 Elm_Naviframe_Content_Item_Pair *pair = NULL;
758 Evas_Object *content = NULL;
760 EINA_INLIST_FOREACH(it->content_list, pair)
762 if (!strcmp(part, pair->part))
764 content = elm_object_part_content_get(VIEW(it), part);
765 eina_stringshare_del(pair->part);
766 it->content_list = eina_inlist_remove(it->content_list,
767 EINA_INLIST_GET(pair));
773 if (!content) return NULL;
775 elm_object_part_content_unset(VIEW(it), part);
776 snprintf(buf, sizeof(buf), "elm,state,%s,hide", part);
777 elm_object_signal_emit(VIEW(it), buf, "elm");
778 evas_object_event_callback_del(content,
781 _sizing_eval(WIDGET(it));
787 _item_del(Elm_Naviframe_Item *it)
790 Elm_Naviframe_Content_Item_Pair *content_pair;
791 Elm_Naviframe_Text_Item_Pair *text_pair;
792 Evas_Object *content;
796 wd = elm_widget_data_get(WIDGET(it));
799 while (it->content_list)
802 EINA_INLIST_CONTAINER_GET(it->content_list,
803 Elm_Naviframe_Content_Item_Pair);
804 content = elm_object_part_content_get(VIEW(it), content_pair->part);
805 evas_object_event_callback_del(content,
808 eina_stringshare_del(content_pair->part);
809 it->content_list = eina_inlist_remove(it->content_list,
814 while (it->text_list)
816 text_pair = EINA_INLIST_CONTAINER_GET(it->text_list,
817 Elm_Naviframe_Text_Item_Pair);
818 eina_stringshare_del(text_pair->part);
819 it->text_list = eina_inlist_remove(it->text_list,
824 eina_stringshare_del(it->style);
828 _item_del_pre_hook(Elm_Object_Item *it)
830 Elm_Naviframe_Item *navi_it;
833 navi_it =(Elm_Naviframe_Item *) it;
834 wd = elm_widget_data_get(WIDGET(navi_it));
835 if (!wd) return EINA_FALSE;
837 if (it == elm_naviframe_top_item_get(WIDGET(navi_it)))
839 wd->stack = eina_inlist_remove(wd->stack, EINA_INLIST_GET(navi_it));
841 //If the item is only one, the stack will be empty
842 if (!wd->stack) return EINA_TRUE;
843 navi_it = EINA_INLIST_CONTAINER_GET(wd->stack->last,
845 evas_object_show(VIEW(navi_it));
846 evas_object_raise(VIEW(navi_it));
847 elm_object_signal_emit(VIEW(navi_it), "elm,state,visible", "elm");
851 wd->stack = eina_inlist_remove(wd->stack, EINA_INLIST_GET(navi_it));
859 _pushed_finished(void *data,
860 Evas_Object *obj __UNUSED__,
861 const char *emission __UNUSED__,
862 const char *source __UNUSED__)
865 Elm_Naviframe_Item *it = data;
868 wd = elm_widget_data_get(WIDGET(it));
871 evas_object_hide(VIEW(it));
872 if (wd->freeze_events)
873 evas_object_freeze_events_set(VIEW(it), EINA_FALSE);
875 elm_widget_item_smart_callback_call(it,
876 SIG_ITEM_HIDE_FINISHED,
881 _popped_finished(void *data,
882 Evas_Object *obj __UNUSED__,
883 const char *emission __UNUSED__,
884 const char *source __UNUSED__)
886 Elm_Naviframe_Item *it = data;
889 elm_widget_item_free(data);
893 _show_finished(void *data,
894 Evas_Object *obj __UNUSED__,
895 const char *emission __UNUSED__,
896 const char *source __UNUSED__)
898 Elm_Naviframe_Item *it;
903 wd = elm_widget_data_get(WIDGET(it));
906 evas_object_smart_callback_call(WIDGET(it),
907 SIG_TRANSITION_FINISHED,
909 if (wd->freeze_events)
910 evas_object_freeze_events_set(VIEW(it), EINA_FALSE);
914 _changed_size_hints(void *data,
916 Evas_Object *obj __UNUSED__,
917 void *event_info __UNUSED__)
923 _item_content_set(Elm_Naviframe_Item *navi_it, Evas_Object *content)
925 if (navi_it->content == content) return;
926 if (navi_it->content) evas_object_del(navi_it->content);
927 elm_object_part_content_set(VIEW(navi_it), "elm.swallow.content", content);
930 elm_object_signal_emit(VIEW(navi_it), "elm,state,content,show", "elm");
932 elm_object_signal_emit(VIEW(navi_it), "elm,state,content,hide", "elm");
934 evas_object_event_callback_add(content,
938 navi_it->content = content;
939 _sizing_eval(WIDGET(navi_it));
942 //FIXME: need to handle if this function is called while transition
944 _item_style_set(Elm_Naviframe_Item *navi_it, const char *item_style)
946 Elm_Naviframe_Content_Item_Pair *content_pair;
947 Elm_Naviframe_Text_Item_Pair *text_pair;
949 wd = elm_widget_data_get(WIDGET(navi_it));
956 snprintf(buf, sizeof(buf), "item/%s", wd->item_style);
960 snprintf(buf, sizeof(buf), "item/%s", item_style);
961 eina_stringshare_replace(&navi_it->style, item_style);
963 elm_layout_theme_set(VIEW(navi_it),
966 elm_widget_style_get(WIDGET(navi_it)));
968 EINA_INLIST_FOREACH(navi_it->text_list, text_pair)
969 _item_text_set_hook((Elm_Object_Item *) navi_it,
971 elm_object_part_text_get(VIEW(navi_it),
974 EINA_INLIST_FOREACH(navi_it->content_list, content_pair)
975 _item_content_set_hook((Elm_Object_Item *) navi_it,
977 elm_object_part_content_get(VIEW(navi_it),
978 content_pair->part));
980 if (navi_it->content)
981 elm_object_signal_emit(VIEW(navi_it), "elm,state,content,show", "elm");
984 if (navi_it->title_prev_btn)
985 elm_object_signal_emit(VIEW(navi_it), "elm,state,prev_btn,show", "elm");
988 if (navi_it->title_next_btn)
989 elm_object_signal_emit(VIEW(navi_it), "elm,state,next_btn,show", "elm");
991 navi_it->title_visible = EINA_TRUE;
992 _sizing_eval(WIDGET(navi_it));
994 if (wd->freeze_events)
995 evas_object_freeze_events_set(VIEW(navi_it), EINA_FALSE);
998 static Elm_Naviframe_Item *
999 _item_new(Evas_Object *obj,
1000 const char *title_label,
1001 Evas_Object *prev_btn,
1002 Evas_Object *next_btn,
1003 Evas_Object *content,
1004 const char *item_style)
1006 Widget_Data *wd = elm_widget_data_get(obj);
1009 Elm_Naviframe_Item *it = elm_widget_item_new(obj, Elm_Naviframe_Item);
1012 ERR("Failed to allocate new item! : naviframe=%p", obj);
1016 elm_widget_item_del_pre_hook_set(it, _item_del_pre_hook);
1017 elm_widget_item_text_set_hook_set(it, _item_text_set_hook);
1018 elm_widget_item_text_get_hook_set(it, _item_text_get_hook);
1019 elm_widget_item_content_set_hook_set(it, _item_content_set_hook);
1020 elm_widget_item_content_get_hook_set(it, _item_content_get_hook);
1021 elm_widget_item_content_unset_hook_set(it, _item_content_unset_hook);
1022 elm_widget_item_signal_emit_hook_set(it, _item_signal_emit_hook);
1025 VIEW(it) = elm_layout_add(obj);
1026 evas_object_smart_member_add(VIEW(it), wd->base);
1028 evas_object_event_callback_add(VIEW(it),
1029 EVAS_CALLBACK_CHANGED_SIZE_HINTS,
1030 _changed_size_hints,
1032 elm_object_signal_callback_add(VIEW(it),
1033 "elm,action,show,finished",
1035 _show_finished, it);
1036 elm_object_signal_callback_add(VIEW(it),
1037 "elm,action,pushed,finished",
1039 _pushed_finished, it);
1040 elm_object_signal_callback_add(VIEW(it),
1041 "elm,action,popped,finished",
1043 _popped_finished, it);
1044 elm_object_signal_callback_add(VIEW(it),
1045 "elm,action,title,clicked",
1047 _title_clicked, it);
1049 _item_style_set(it, item_style);
1050 _item_text_set_hook((Elm_Object_Item *) it, "elm.text.title", title_label);
1053 if ((!prev_btn) && wd->auto_pushed && eina_inlist_count(wd->stack))
1055 prev_btn = _back_btn_new(obj);
1056 _title_prev_btn_set(it, prev_btn, EINA_TRUE);
1059 _title_prev_btn_set(it, prev_btn, EINA_FALSE);
1061 _title_next_btn_set(it, next_btn);
1062 _item_content_set(it, content);
1063 it->title_visible = EINA_TRUE;
1068 _focus_next_hook(const Evas_Object *obj, Elm_Focus_Direction dir, Evas_Object **next)
1070 Widget_Data *wd = elm_widget_data_get(obj);
1071 if (!wd || !wd->stack) return EINA_FALSE;
1072 return elm_widget_focus_next_get(VIEW(elm_naviframe_top_item_get(obj)),
1078 elm_naviframe_add(Evas_Object *parent)
1084 ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL);
1085 ELM_SET_WIDTYPE(widtype, "naviframe");
1086 elm_widget_type_set(obj, "naviframe");
1087 elm_widget_sub_object_add(parent, obj);
1088 elm_widget_data_set(obj, wd);
1089 elm_widget_del_hook_set(obj, _del_hook);
1090 elm_widget_disable_hook_set(obj, _disable_hook);
1091 elm_widget_theme_hook_set(obj, _theme_hook);
1092 elm_widget_text_set_hook_set(obj, _text_set_hook);
1093 elm_widget_text_get_hook_set(obj, _text_get_hook);
1094 elm_widget_content_set_hook_set(obj, _content_set_hook);
1095 elm_widget_content_get_hook_set(obj, _content_get_hook);
1096 elm_widget_content_unset_hook_set(obj, _content_unset_hook);
1097 elm_widget_signal_emit_hook_set(obj, _emit_hook);
1098 elm_widget_can_focus_set(obj, EINA_FALSE);
1099 elm_widget_focus_next_hook_set(obj, _focus_next_hook);
1102 //FIXME: Is this base layout really needed?
1103 wd->base = elm_layout_add(parent);
1104 evas_object_event_callback_add(wd->base,
1105 EVAS_CALLBACK_CHANGED_SIZE_HINTS,
1106 _changed_size_hints,
1108 elm_widget_resize_object_set(obj, wd->base);
1109 elm_layout_theme_set(wd->base, "naviframe", "base", "default");
1111 evas_object_event_callback_add(obj, EVAS_CALLBACK_MOVE, _move, obj);
1112 evas_object_event_callback_add(obj, EVAS_CALLBACK_RESIZE, _resize, obj);
1113 evas_object_smart_callbacks_descriptions_set(obj, _signals);
1115 wd->auto_pushed = EINA_TRUE;
1116 wd->freeze_events = EINA_TRUE;
1117 wd->item_style = eina_stringshare_add("basic");
1122 EAPI Elm_Object_Item *
1123 elm_naviframe_item_push(Evas_Object *obj,
1124 const char *title_label,
1125 Evas_Object *prev_btn,
1126 Evas_Object *next_btn,
1127 Evas_Object *content,
1128 const char *item_style)
1130 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1132 Elm_Naviframe_Item *prev_it, *it;
1134 wd = elm_widget_data_get(obj);
1135 if (!wd) return NULL;
1137 it = _item_new(obj, title_label, prev_btn, next_btn, content, item_style);
1138 if (!it) return NULL;
1140 evas_object_show(VIEW(it));
1142 prev_it = (Elm_Naviframe_Item *) elm_naviframe_top_item_get(obj);
1145 if (wd->freeze_events)
1147 evas_object_freeze_events_set(VIEW(it), EINA_TRUE);
1148 evas_object_freeze_events_set(VIEW(prev_it), EINA_TRUE);
1150 elm_object_signal_emit(VIEW(prev_it), "elm,state,cur,pushed", "elm");
1151 elm_object_signal_emit(VIEW(it), "elm,state,new,pushed", "elm");
1152 edje_object_message_signal_process(elm_layout_edje_get(VIEW(prev_it)));
1153 edje_object_message_signal_process(elm_layout_edje_get(VIEW(it)));
1155 wd->stack = eina_inlist_append(wd->stack, EINA_INLIST_GET(it));
1157 return (Elm_Object_Item *) it;
1160 EAPI Elm_Object_Item *
1161 elm_naviframe_item_insert_before(Elm_Object_Item *before,
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(before, NULL);
1169 Elm_Naviframe_Item *it;
1172 wd = elm_widget_data_get(WIDGET(before));
1173 if (!wd) return NULL;
1175 it = _item_new(WIDGET(before), title_label, prev_btn, next_btn, content,
1177 if (!it) return NULL;
1180 eina_inlist_prepend_relative(wd->stack,
1181 EINA_INLIST_GET(it),
1182 EINA_INLIST_GET(((Elm_Naviframe_Item *) before)));
1183 _sizing_eval(WIDGET(before));
1184 return (Elm_Object_Item *) it;
1187 EAPI Elm_Object_Item *
1188 elm_naviframe_item_insert_after(Elm_Object_Item *after,
1189 const char *title_label,
1190 Evas_Object *prev_btn,
1191 Evas_Object *next_btn,
1192 Evas_Object *content,
1193 const char *item_style)
1195 ELM_OBJ_ITEM_CHECK_OR_RETURN(after, NULL);
1196 Elm_Naviframe_Item *it;
1199 wd = elm_widget_data_get(WIDGET(after));
1200 if (!wd) return NULL;
1202 it = _item_new(WIDGET(after), title_label, prev_btn, next_btn, content,
1204 if (!it) return NULL;
1206 if (elm_naviframe_top_item_get(WIDGET(after)) == after)
1208 evas_object_hide(VIEW(after));
1209 evas_object_show(VIEW(it));
1212 eina_inlist_append_relative(wd->stack,
1213 EINA_INLIST_GET(it),
1214 EINA_INLIST_GET(((Elm_Naviframe_Item *) after)));
1215 _sizing_eval(WIDGET(after));
1216 return (Elm_Object_Item *) it;
1220 elm_naviframe_item_pop(Evas_Object *obj)
1222 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1223 Elm_Naviframe_Item *it, *prev_it = NULL;
1225 Evas_Object *content = NULL;
1227 wd = elm_widget_data_get(obj);
1228 if (!wd) return NULL;
1230 it = (Elm_Naviframe_Item *) elm_naviframe_top_item_get(obj);
1231 if (!it) return NULL;
1232 elm_widget_tree_unfocusable_set(it->content, EINA_TRUE);
1234 content = it->content;
1236 if (wd->stack->last->prev)
1237 prev_it = EINA_INLIST_CONTAINER_GET(wd->stack->last->prev,
1238 Elm_Naviframe_Item);
1239 wd->stack = eina_inlist_remove(wd->stack, EINA_INLIST_GET(it));
1242 if (wd->freeze_events)
1244 evas_object_freeze_events_set(VIEW(it), EINA_TRUE);
1245 evas_object_freeze_events_set(VIEW(prev_it), EINA_TRUE);
1247 elm_object_signal_emit(VIEW(it), "elm,state,cur,popped", "elm");
1248 evas_object_show(VIEW(prev_it));
1249 evas_object_raise(VIEW(prev_it));
1250 elm_object_signal_emit(VIEW(prev_it),
1251 "elm,state,prev,popped",
1253 edje_object_message_signal_process(elm_layout_edje_get(VIEW(it)));
1254 edje_object_message_signal_process(elm_layout_edje_get(VIEW(prev_it)));
1255 elm_widget_item_smart_callback_call(prev_it,
1256 SIG_ITEM_SHOW_BEGIN,
1262 elm_widget_item_free(it);
1269 elm_naviframe_item_pop_to(Elm_Object_Item *it)
1271 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1272 Elm_Naviframe_Item *navi_it;
1274 Eina_Inlist *l, *prev_l;
1276 navi_it = (Elm_Naviframe_Item *) it;
1277 wd = elm_widget_data_get(WIDGET(navi_it));
1280 if (it == elm_naviframe_top_item_get(WIDGET(navi_it))) return;
1282 l = wd->stack->last->prev;
1286 if (EINA_INLIST_CONTAINER_GET(l, Elm_Naviframe_Item) ==
1287 ((Elm_Naviframe_Item *) it)) break;
1289 wd->stack = eina_inlist_remove(wd->stack, l);
1290 _item_del(EINA_INLIST_CONTAINER_GET(l, Elm_Naviframe_Item));
1291 elm_widget_item_free(EINA_INLIST_CONTAINER_GET(l,
1292 Elm_Naviframe_Item));
1295 elm_naviframe_item_pop(WIDGET(navi_it));
1299 elm_naviframe_item_promote(Elm_Object_Item *it)
1301 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1302 Elm_Naviframe_Item *navi_it;
1303 Elm_Naviframe_Item *prev_it;
1306 navi_it = (Elm_Naviframe_Item *) it;
1307 wd = elm_widget_data_get(navi_it->base.widget);
1310 if (it == elm_naviframe_top_item_get(navi_it->base.widget)) return;
1311 wd->stack = eina_inlist_demote(wd->stack, EINA_INLIST_GET(navi_it));
1312 prev_it = EINA_INLIST_CONTAINER_GET(wd->stack->last->prev,
1313 Elm_Naviframe_Item);
1314 if (wd->freeze_events)
1316 evas_object_freeze_events_set(VIEW(it), EINA_TRUE);
1317 evas_object_freeze_events_set(VIEW(prev_it), EINA_TRUE);
1319 elm_object_signal_emit(VIEW(prev_it),
1320 "elm,state,cur,pushed",
1322 evas_object_show(VIEW(navi_it));
1323 evas_object_raise(VIEW(navi_it));
1324 elm_object_signal_emit(VIEW(navi_it),
1325 "elm,state,new,pushed",
1327 edje_object_message_signal_process(elm_layout_edje_get(VIEW(prev_it)));
1328 edje_object_message_signal_process(elm_layout_edje_get(VIEW(navi_it)));
1332 elm_naviframe_item_simple_promote(Evas_Object *obj, Evas_Object *content)
1334 ELM_CHECK_WIDTYPE(obj, widtype);
1335 Widget_Data *wd = elm_widget_data_get(obj);
1337 Elm_Naviframe_Item *itr;
1338 EINA_INLIST_FOREACH(wd->stack, itr)
1340 if (elm_object_item_content_get((Elm_Object_Item *) itr) == content)
1342 elm_naviframe_item_promote((Elm_Object_Item *) itr);
1350 elm_naviframe_item_del(Elm_Object_Item *it)
1352 elm_object_item_del(it);
1356 elm_naviframe_content_preserve_on_pop_set(Evas_Object *obj, Eina_Bool preserve)
1358 ELM_CHECK_WIDTYPE(obj, widtype);
1359 Widget_Data *wd = elm_widget_data_get(obj);
1361 wd->preserve = !!preserve;
1365 elm_naviframe_content_preserve_on_pop_get(const Evas_Object *obj)
1367 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
1368 Widget_Data *wd = elm_widget_data_get(obj);
1369 if (!wd) return EINA_FALSE;
1370 return wd->preserve;
1373 EAPI Elm_Object_Item*
1374 elm_naviframe_top_item_get(const Evas_Object *obj)
1376 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1377 Widget_Data *wd = elm_widget_data_get(obj);
1378 if ((!wd) || (!wd->stack)) return NULL;
1379 return (Elm_Object_Item *) (EINA_INLIST_CONTAINER_GET(wd->stack->last,
1380 Elm_Naviframe_Item));
1383 EAPI Elm_Object_Item*
1384 elm_naviframe_bottom_item_get(const Evas_Object *obj)
1386 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1387 Widget_Data *wd = elm_widget_data_get(obj);
1388 if ((!wd) || (!wd->stack)) return NULL;
1389 return (Elm_Object_Item *) (EINA_INLIST_CONTAINER_GET(wd->stack,
1390 Elm_Naviframe_Item));
1394 elm_naviframe_item_style_set(Elm_Object_Item *it, const char *item_style)
1396 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1397 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
1399 //Return if new style is exsiting one.
1400 if ((item_style && navi_it->style) && (!strcmp(item_style, navi_it->style)))
1403 if ((!item_style) && (!navi_it->style))
1406 _item_style_set(navi_it, item_style);
1410 elm_naviframe_item_style_get(const Elm_Object_Item *it)
1412 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
1413 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
1414 return navi_it->style;
1418 elm_naviframe_item_title_visible_set(Elm_Object_Item *it, Eina_Bool visible)
1420 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1421 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
1423 visible = !!visible;
1424 if (navi_it->title_visible == visible) return;
1426 navi_it->title_visible = visible;
1427 _item_title_visible_update(navi_it);
1431 elm_naviframe_item_title_visible_get(const Elm_Object_Item *it)
1433 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
1434 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
1435 return navi_it->title_visible;
1439 elm_naviframe_prev_btn_auto_pushed_set(Evas_Object *obj, Eina_Bool auto_pushed)
1441 ELM_CHECK_WIDTYPE(obj, widtype);
1442 Widget_Data *wd = elm_widget_data_get(obj);
1444 wd->auto_pushed = !!auto_pushed;
1448 elm_naviframe_prev_btn_auto_pushed_get(const Evas_Object *obj)
1450 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
1451 Widget_Data *wd = elm_widget_data_get(obj);
1452 if (!wd) return EINA_FALSE;
1453 return wd->auto_pushed;
1457 elm_naviframe_items_get(const Evas_Object *obj)
1459 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1460 Widget_Data *wd = elm_widget_data_get(obj);
1461 if (!wd) return NULL;
1462 Eina_List *ret = NULL;
1463 Elm_Naviframe_Item *itr;
1464 EINA_INLIST_FOREACH(wd->stack, itr)
1465 ret = eina_list_append(ret, itr);
1470 elm_naviframe_event_enabled_set(Evas_Object *obj, Eina_Bool enabled)
1472 ELM_CHECK_WIDTYPE(obj, widtype);
1473 Widget_Data *wd = elm_widget_data_get(obj);
1475 enabled = !!enabled;
1476 if (wd->freeze_events == !enabled) return;
1477 wd->freeze_events = !enabled;
1481 elm_naviframe_event_enabled_get(const Evas_Object *obj)
1483 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
1484 Widget_Data *wd = elm_widget_data_get(obj);
1485 if (!wd) return EINA_FALSE;
1486 return !wd->freeze_events;
1490 elm_naviframe_item_style_default_set(Evas_Object *obj, const char *style)
1492 ELM_CHECK_WIDTYPE(obj, widtype);
1493 Widget_Data *wd = elm_widget_data_get(obj);
1495 eina_stringshare_replace(&wd->item_style, style);
1500 elm_naviframe_item_style_default_get(const Evas_Object *obj)
1502 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1503 Widget_Data *wd = elm_widget_data_get(obj);
1504 if (!wd) return NULL;
1505 return wd->item_style;