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)
219 _item_style_set(it, it->style);
220 _item_title_visible_update(it);
224 static void _emit_hook(Evas_Object *obj,
225 const char *emission,
228 Elm_Object_Item *it = elm_naviframe_top_item_get(obj);
230 return elm_object_item_signal_emit(it, emission, source);
234 _disable_hook(Evas_Object *obj __UNUSED__)
240 _item_text_set_hook(Elm_Object_Item *it,
244 Elm_Naviframe_Text_Item_Pair *pair = NULL;
245 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *)it;
248 if (!part || !strcmp(part, "default"))
249 snprintf(buf, sizeof(buf), "elm.text.title");
250 else if(!strcmp("subtitle", part))
251 snprintf(buf, sizeof(buf), "elm.text.subtitle");
253 snprintf(buf, sizeof(buf), "%s", part);
255 EINA_INLIST_FOREACH(navi_it->text_list, pair)
256 if (!strcmp(buf, pair->part)) break;
260 pair = ELM_NEW(Elm_Naviframe_Text_Item_Pair);
263 ERR("Failed to allocate new text part of the item! : naviframe=%p",
267 eina_stringshare_replace(&pair->part, buf);
268 navi_it->text_list = eina_inlist_append(navi_it->text_list,
269 EINA_INLIST_GET(pair));
271 elm_object_part_text_set(VIEW(navi_it), buf, label);
275 snprintf(buf, sizeof(buf), "elm,state,%s,show", buf);
276 elm_object_signal_emit(VIEW(navi_it), buf, "elm");
280 snprintf(buf, sizeof(buf), "elm,state,%s,hide", buf);
281 elm_object_signal_emit(VIEW(navi_it), buf, "elm");
284 _sizing_eval(WIDGET(navi_it));
288 _item_text_get_hook(const Elm_Object_Item *it, const char *part)
292 if (!part || !strcmp(part, "default"))
293 snprintf(buf, sizeof(buf), "elm.text.title");
294 else if(!strcmp("subtitle", part))
295 snprintf(buf, sizeof(buf), "elm.text.subtitle");
297 snprintf(buf, sizeof(buf), "%s", part);
299 return elm_object_part_text_get(VIEW(it), buf);
303 _item_content_set_hook(Elm_Object_Item *it,
305 Evas_Object *content)
307 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *)it;
310 if (!part || !strcmp("default", part))
312 _item_content_set(navi_it, content);
315 else if (!strcmp(part, "prev_btn"))
317 _title_prev_btn_set(navi_it, content, EINA_FALSE);
320 else if (!strcmp(part, "next_btn"))
322 _title_next_btn_set(navi_it, content);
325 else if (!strcmp(part, "icon"))
327 _title_icon_set(navi_it, content);
332 _title_content_set(navi_it, part, content);
336 _item_content_get_hook(const Elm_Object_Item *it, const char *part)
338 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *)it;
341 if (!part || !strcmp("default", part))
342 return navi_it->content;
343 else if (!strcmp(part, "prev_btn"))
344 return navi_it->title_prev_btn;
345 else if (!strcmp(part, "next_btn"))
346 return navi_it->title_next_btn;
347 else if (!strcmp(part, "icon"))
348 return navi_it->title_icon;
351 return elm_object_part_content_get(VIEW(navi_it), part);
355 _item_content_unset_hook(Elm_Object_Item *it, const char *part)
357 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *)it;
360 if (!part || !strcmp("default", part))
361 return _item_content_unset(navi_it);
362 else if (!strcmp(part, "prev_btn"))
363 return _title_prev_btn_unset(navi_it);
364 else if (!strcmp(part, "next_btn"))
365 return _title_next_btn_unset(navi_it);
366 else if (!strcmp(part, "icon"))
367 return _title_icon_unset(navi_it);
369 return _title_content_unset(navi_it, part);
373 _item_signal_emit_hook(Elm_Object_Item *it,
374 const char *emission,
377 elm_object_signal_emit(VIEW(it), emission, source);
381 _item_title_visible_update(Elm_Naviframe_Item *navi_it)
383 if (navi_it->title_visible)
384 elm_object_signal_emit(VIEW(navi_it), "elm,state,title,show", "elm");
386 elm_object_signal_emit(VIEW(navi_it), "elm,state,title,hide", "elm");
390 _sizing_eval(Evas_Object *obj)
393 Elm_Naviframe_Item *it;
394 Evas_Coord x, y, w, h;
395 Evas_Coord minw = -1, minh = -1;
397 wd = elm_widget_data_get(obj);
400 evas_object_geometry_get(obj, &x, &y, &w, &h);
402 EINA_INLIST_FOREACH(wd->stack, it)
404 evas_object_move(VIEW(it), x, y);
405 evas_object_resize(VIEW(it), w, h);
406 edje_object_size_min_calc(elm_layout_edje_get(VIEW(it)),
409 if (it->minw > minw) minw = it->minw;
410 if (it->minh > minh) minh = it->minh;
412 evas_object_size_hint_min_set(obj, minw, minh);
413 evas_object_size_hint_max_set(obj, -1, -1);
417 _move(void *data __UNUSED__,
420 void *event_info __UNUSED__)
426 _resize(void *data __UNUSED__,
429 void *event_info __UNUSED__)
435 _title_clicked(void *data,
436 Evas_Object *obj __UNUSED__,
437 const char *emission __UNUSED__,
438 const char *source __UNUSED__)
440 Elm_Naviframe_Item *it = data;
441 evas_object_smart_callback_call(WIDGET(it), SIG_TITLE_CLICKED, it);
445 _back_btn_clicked(void *data,
447 void *event_info __UNUSED__)
449 /* Since edje has the event queue, clicked event could be happend multiple times
450 on some heavy environment. This callback del will prevent those scenario and
451 guarantee only one clicked for it's own page. */
452 evas_object_smart_callback_del(obj, "clicked", _back_btn_clicked);
453 elm_naviframe_item_pop(data);
457 _back_btn_new(Evas_Object *obj)
461 btn = elm_button_add(obj);
462 if (!btn) return NULL;
463 evas_object_smart_callback_add(btn, "clicked", _back_btn_clicked, obj);
464 snprintf(buf, sizeof(buf), "naviframe/back_btn/%s",
465 elm_widget_style_get(obj));
466 elm_object_style_set(btn, buf);
470 static void _text_set_hook(Evas_Object *obj,
474 Elm_Object_Item *it = elm_naviframe_top_item_get(obj);
476 elm_object_item_part_text_set(it, part, label);
479 static const char *_text_get_hook(const Evas_Object *obj, const char *part)
481 Elm_Object_Item *it = elm_naviframe_top_item_get(obj);
482 if (!it) return NULL;
483 return elm_object_item_part_text_get(it, part);
487 _content_set_hook(Evas_Object *obj, const char *part, Evas_Object *content)
489 Elm_Object_Item *it = elm_naviframe_top_item_get(obj);
491 elm_object_item_part_content_set(it, part, content);
495 _content_unset_hook(Evas_Object *obj, const char *part)
497 Elm_Object_Item *it = elm_naviframe_top_item_get(obj);
498 if (!it) return NULL;
499 return elm_object_item_part_content_unset(it, part);
503 _content_get_hook(const Evas_Object *obj, const char *part)
505 Elm_Object_Item *it = elm_naviframe_top_item_get(obj);
506 if (!it) return NULL;
507 return elm_object_item_part_content_get(it, part);
511 _title_content_del(void *data,
513 Evas_Object *obj __UNUSED__,
514 void *event_info __UNUSED__)
517 Elm_Naviframe_Content_Item_Pair *pair = data;
518 Elm_Naviframe_Item *it = pair->it;
519 snprintf(buf, sizeof(buf), "elm,state,%s,hide", pair->part);
520 elm_object_signal_emit(VIEW(it), buf, "elm");
521 it->content_list = eina_inlist_remove(it->content_list,
522 EINA_INLIST_GET(pair));
523 eina_stringshare_del(pair->part);
528 _title_prev_btn_del(void *data,
530 Evas_Object *obj __UNUSED__,
531 void *event_info __UNUSED__)
533 Elm_Naviframe_Item *it = data;
534 it->back_btn = EINA_FALSE;
535 it->title_prev_btn = NULL;
536 elm_object_signal_emit(VIEW(it), "elm,state,prev_btn,hide", "elm");
540 _title_next_btn_del(void *data,
542 Evas_Object *obj __UNUSED__,
543 void *event_info __UNUSED__)
545 Elm_Naviframe_Item *it = data;
546 it->title_next_btn = NULL;
547 elm_object_signal_emit(VIEW(it), "elm,state,next_btn,hide", "elm");
551 _title_icon_del(void *data,
553 Evas_Object *obj __UNUSED__,
554 void *event_info __UNUSED__)
556 Elm_Naviframe_Item *it = data;
557 it->title_icon = NULL;
558 elm_object_signal_emit(VIEW(it), "elm,state,icon,hide", "elm");
562 _item_content_del(void *data,
564 Evas_Object *obj __UNUSED__,
565 void *event_info __UNUSED__)
567 Elm_Naviframe_Item *it = data;
569 elm_object_signal_emit(VIEW(it), "elm,state,content,hide", "elm");
573 _title_content_set(Elm_Naviframe_Item *it,
575 Evas_Object *content)
578 Elm_Naviframe_Content_Item_Pair *pair = NULL;
579 Evas_Object *prev_content = NULL;
581 EINA_INLIST_FOREACH(it->content_list, pair)
582 if (!strcmp(part, pair->part)) break;
586 prev_content = elm_object_part_content_get(VIEW(it), part);
587 if (prev_content != content)
591 evas_object_event_callback_del(prev_content,
594 snprintf(buf, sizeof(buf), "elm,state,%s,hide", part);
595 elm_object_signal_emit(VIEW(it), buf, "elm");
597 evas_object_del(prev_content);
598 if (!content) return;
603 if (!content) return;
604 pair = ELM_NEW(Elm_Naviframe_Content_Item_Pair);
607 ERR("Failed to allocate new content part of the item! : naviframe=%p", WIDGET(it));
611 eina_stringshare_replace(&pair->part, part);
612 it->content_list = eina_inlist_append(it->content_list,
613 EINA_INLIST_GET(pair));
615 if (prev_content != content)
617 evas_object_event_callback_add(content,
622 elm_object_part_content_set(VIEW(it), part, content);
623 snprintf(buf, sizeof(buf), "elm,state,%s,show", part);
624 elm_object_signal_emit(VIEW(it), buf, "elm");
626 _sizing_eval(WIDGET(it));
630 _title_prev_btn_set(Elm_Naviframe_Item *it,
634 if (it->title_prev_btn == btn) return;
635 if (it->title_prev_btn) evas_object_del(it->title_prev_btn);
636 it->title_prev_btn = btn;
639 evas_object_event_callback_add(btn,
643 elm_object_part_content_set(VIEW(it), "elm.swallow.prev_btn", btn);
644 elm_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;
654 if (it->title_next_btn) evas_object_del(it->title_next_btn);
655 it->title_next_btn = btn;
658 evas_object_event_callback_add(btn,
662 elm_object_part_content_set(VIEW(it), "elm.swallow.next_btn", btn);
663 elm_object_signal_emit(VIEW(it), "elm,state,next_btn,show", "elm");
665 _sizing_eval(WIDGET(it));
669 _title_icon_set(Elm_Naviframe_Item *it, Evas_Object *icon)
671 if (it->title_icon == icon) return;
672 if (it->title_icon) evas_object_del(it->title_icon);
673 it->title_icon = icon;
676 evas_object_event_callback_add(icon,
680 elm_object_part_content_set(VIEW(it), "elm.swallow.icon", icon);
681 elm_object_signal_emit(VIEW(it), "elm,state,icon,show", "elm");
683 _sizing_eval(WIDGET(it));
687 _item_content_unset(Elm_Naviframe_Item *it)
689 Evas_Object *content = it->content;
690 if (!content) return NULL;
692 elm_object_part_content_unset(VIEW(it), "elm.swallow.content");
693 elm_object_signal_emit(VIEW(it), "elm,state,content,hide", "elm");
694 evas_object_event_callback_del(content,
697 _sizing_eval(WIDGET(it));
704 _title_prev_btn_unset(Elm_Naviframe_Item *it)
706 Evas_Object *content = it->title_prev_btn;
707 if (!content) return NULL;
709 elm_object_part_content_unset(VIEW(it), "elm.swallow.prev_btn");
710 elm_object_signal_emit(VIEW(it), "elm,state,prev_btn,hide", "elm");
711 evas_object_event_callback_del(content,
713 _title_prev_btn_del);
714 _sizing_eval(WIDGET(it));
716 it->title_prev_btn = NULL;
721 _title_next_btn_unset(Elm_Naviframe_Item *it)
723 Evas_Object *content = it->title_next_btn;
724 if (!content) return NULL;
726 elm_object_part_content_unset(VIEW(it), "elm.swallow.next_btn");
727 elm_object_signal_emit(VIEW(it), "elm,state,next_btn,hide", "elm");
728 evas_object_event_callback_del(content,
730 _title_next_btn_del);
731 _sizing_eval(WIDGET(it));
733 it->title_next_btn = NULL;
738 _title_icon_unset(Elm_Naviframe_Item *it)
740 Evas_Object *content = it->title_icon;
741 if (!content) return NULL;
743 elm_object_part_content_unset(VIEW(it), "elm.swallow.icon");
744 elm_object_signal_emit(VIEW(it), "elm,state,icon,hide", "elm");
745 evas_object_event_callback_del(content,
748 _sizing_eval(WIDGET(it));
749 it->title_icon = NULL;
755 _title_content_unset(Elm_Naviframe_Item *it, const char *part)
757 Elm_Naviframe_Content_Item_Pair *pair = NULL;
759 Evas_Object *content = NULL;
761 EINA_INLIST_FOREACH(it->content_list, pair)
763 if (!strcmp(part, pair->part))
765 content = elm_object_part_content_get(VIEW(it), part);
766 eina_stringshare_del(pair->part);
767 it->content_list = eina_inlist_remove(it->content_list,
768 EINA_INLIST_GET(pair));
774 if (!content) return NULL;
776 elm_object_part_content_unset(VIEW(it), part);
777 snprintf(buf, sizeof(buf), "elm,state,%s,hide", part);
778 elm_object_signal_emit(VIEW(it), buf, "elm");
779 evas_object_event_callback_del(content,
782 _sizing_eval(WIDGET(it));
788 _item_del(Elm_Naviframe_Item *it)
791 Elm_Naviframe_Content_Item_Pair *content_pair;
792 Elm_Naviframe_Text_Item_Pair *text_pair;
793 Evas_Object *content;
797 wd = elm_widget_data_get(WIDGET(it));
800 while (it->content_list)
803 EINA_INLIST_CONTAINER_GET(it->content_list,
804 Elm_Naviframe_Content_Item_Pair);
805 content = elm_object_part_content_get(VIEW(it), content_pair->part);
806 evas_object_event_callback_del(content,
809 eina_stringshare_del(content_pair->part);
810 it->content_list = eina_inlist_remove(it->content_list,
815 while (it->text_list)
817 text_pair = EINA_INLIST_CONTAINER_GET(it->text_list,
818 Elm_Naviframe_Text_Item_Pair);
819 eina_stringshare_del(text_pair->part);
820 it->text_list = eina_inlist_remove(it->text_list,
825 eina_stringshare_del(it->style);
829 _item_del_pre_hook(Elm_Object_Item *it)
831 Elm_Naviframe_Item *navi_it;
834 navi_it =(Elm_Naviframe_Item *)it;
835 wd = elm_widget_data_get(WIDGET(navi_it));
836 if (!wd) return EINA_FALSE;
838 if (it == elm_naviframe_top_item_get(WIDGET(navi_it)))
840 wd->stack = eina_inlist_remove(wd->stack, EINA_INLIST_GET(navi_it));
842 //If the item is only one, the stack will be empty
843 if (!wd->stack) return EINA_TRUE;
844 navi_it = EINA_INLIST_CONTAINER_GET(wd->stack->last,
846 evas_object_show(VIEW(navi_it));
847 evas_object_raise(VIEW(navi_it));
848 elm_object_signal_emit(VIEW(navi_it), "elm,state,visible", "elm");
852 wd->stack = eina_inlist_remove(wd->stack, EINA_INLIST_GET(navi_it));
860 _pushed_finished(void *data,
861 Evas_Object *obj __UNUSED__,
862 const char *emission __UNUSED__,
863 const char *source __UNUSED__)
866 Elm_Naviframe_Item *it = data;
869 wd = elm_widget_data_get(WIDGET(it));
872 evas_object_hide(VIEW(it));
873 if (wd->freeze_events)
874 evas_object_freeze_events_set(VIEW(it), EINA_FALSE);
876 elm_widget_item_smart_callback_call(it,
877 SIG_ITEM_HIDE_FINISHED,
882 _popped_finished(void *data,
883 Evas_Object *obj __UNUSED__,
884 const char *emission __UNUSED__,
885 const char *source __UNUSED__)
887 Elm_Naviframe_Item *it = data;
890 elm_widget_item_free(data);
894 _show_finished(void *data,
895 Evas_Object *obj __UNUSED__,
896 const char *emission __UNUSED__,
897 const char *source __UNUSED__)
899 Elm_Naviframe_Item *it;
904 wd = elm_widget_data_get(WIDGET(it));
907 evas_object_smart_callback_call(WIDGET(it),
908 SIG_TRANSITION_FINISHED,
910 if (wd->freeze_events)
911 evas_object_freeze_events_set(VIEW(it), EINA_FALSE);
915 _changed_size_hints(void *data,
917 Evas_Object *obj __UNUSED__,
918 void *event_info __UNUSED__)
924 _item_content_set(Elm_Naviframe_Item *navi_it, Evas_Object *content)
926 if (navi_it->content == content) return;
927 if (navi_it->content) evas_object_del(navi_it->content);
928 elm_object_part_content_set(VIEW(navi_it), "elm.swallow.content", content);
931 elm_object_signal_emit(VIEW(navi_it), "elm,state,content,show", "elm");
933 elm_object_signal_emit(VIEW(navi_it), "elm,state,content,hide", "elm");
935 evas_object_event_callback_add(content,
939 navi_it->content = content;
940 _sizing_eval(WIDGET(navi_it));
943 //FIXME: need to handle if this function is called while transition
945 _item_style_set(Elm_Naviframe_Item *navi_it, const char *item_style)
947 Elm_Naviframe_Content_Item_Pair *content_pair;
948 Elm_Naviframe_Text_Item_Pair *text_pair;
950 wd = elm_widget_data_get(WIDGET(navi_it));
957 snprintf(buf, sizeof(buf), "item/%s", wd->item_style);
961 snprintf(buf, sizeof(buf), "item/%s", item_style);
962 eina_stringshare_replace(&navi_it->style, item_style);
964 elm_layout_theme_set(VIEW(navi_it),
967 elm_widget_style_get(WIDGET(navi_it)));
969 EINA_INLIST_FOREACH(navi_it->text_list, text_pair)
970 _item_text_set_hook((Elm_Object_Item *) navi_it,
972 elm_object_part_text_get(VIEW(navi_it),
975 EINA_INLIST_FOREACH(navi_it->content_list, content_pair)
976 _item_content_set_hook((Elm_Object_Item *) navi_it,
978 elm_object_part_content_get(VIEW(navi_it),
979 content_pair->part));
981 if (navi_it->content)
982 elm_object_signal_emit(VIEW(navi_it), "elm,state,content,show", "elm");
985 if (navi_it->title_prev_btn)
986 elm_object_signal_emit(VIEW(navi_it), "elm,state,prev_btn,show", "elm");
989 if (navi_it->title_next_btn)
990 elm_object_signal_emit(VIEW(navi_it), "elm,state,next_btn,show", "elm");
992 // why does this forcibly enable title? isnt that separate to style?
993 // navi_it->title_visible = EINA_TRUE;
994 _sizing_eval(WIDGET(navi_it));
996 if (wd->freeze_events)
997 evas_object_freeze_events_set(VIEW(navi_it), EINA_FALSE);
1000 static Elm_Naviframe_Item *
1001 _item_new(Evas_Object *obj,
1002 const char *title_label,
1003 Evas_Object *prev_btn,
1004 Evas_Object *next_btn,
1005 Evas_Object *content,
1006 const char *item_style)
1008 Widget_Data *wd = elm_widget_data_get(obj);
1011 Elm_Naviframe_Item *it = elm_widget_item_new(obj, Elm_Naviframe_Item);
1014 ERR("Failed to allocate new item! : naviframe=%p", obj);
1018 elm_widget_item_del_pre_hook_set(it, _item_del_pre_hook);
1019 elm_widget_item_text_set_hook_set(it, _item_text_set_hook);
1020 elm_widget_item_text_get_hook_set(it, _item_text_get_hook);
1021 elm_widget_item_content_set_hook_set(it, _item_content_set_hook);
1022 elm_widget_item_content_get_hook_set(it, _item_content_get_hook);
1023 elm_widget_item_content_unset_hook_set(it, _item_content_unset_hook);
1024 elm_widget_item_signal_emit_hook_set(it, _item_signal_emit_hook);
1027 VIEW(it) = elm_layout_add(obj);
1028 evas_object_smart_member_add(VIEW(it), wd->base);
1030 evas_object_event_callback_add(VIEW(it),
1031 EVAS_CALLBACK_CHANGED_SIZE_HINTS,
1032 _changed_size_hints,
1034 elm_object_signal_callback_add(VIEW(it),
1035 "elm,action,show,finished",
1037 _show_finished, it);
1038 elm_object_signal_callback_add(VIEW(it),
1039 "elm,action,pushed,finished",
1041 _pushed_finished, it);
1042 elm_object_signal_callback_add(VIEW(it),
1043 "elm,action,popped,finished",
1045 _popped_finished, it);
1046 elm_object_signal_callback_add(VIEW(it),
1047 "elm,action,title,clicked",
1049 _title_clicked, it);
1051 _item_style_set(it, item_style);
1052 _item_text_set_hook((Elm_Object_Item *)it, "elm.text.title", title_label);
1055 if ((!prev_btn) && wd->auto_pushed && eina_inlist_count(wd->stack))
1057 prev_btn = _back_btn_new(obj);
1058 _title_prev_btn_set(it, prev_btn, EINA_TRUE);
1061 _title_prev_btn_set(it, prev_btn, EINA_FALSE);
1063 _title_next_btn_set(it, next_btn);
1064 _item_content_set(it, content);
1065 it->title_visible = EINA_TRUE;
1070 _focus_next_hook(const Evas_Object *obj, Elm_Focus_Direction dir, Evas_Object **next)
1072 Widget_Data *wd = elm_widget_data_get(obj);
1073 if (!wd || !wd->stack) return EINA_FALSE;
1074 return elm_widget_focus_next_get(VIEW(elm_naviframe_top_item_get(obj)),
1080 elm_naviframe_add(Evas_Object *parent)
1086 ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL);
1087 ELM_SET_WIDTYPE(widtype, "naviframe");
1088 elm_widget_type_set(obj, "naviframe");
1089 elm_widget_sub_object_add(parent, obj);
1090 elm_widget_data_set(obj, wd);
1091 elm_widget_del_hook_set(obj, _del_hook);
1092 elm_widget_disable_hook_set(obj, _disable_hook);
1093 elm_widget_theme_hook_set(obj, _theme_hook);
1094 elm_widget_text_set_hook_set(obj, _text_set_hook);
1095 elm_widget_text_get_hook_set(obj, _text_get_hook);
1096 elm_widget_content_set_hook_set(obj, _content_set_hook);
1097 elm_widget_content_get_hook_set(obj, _content_get_hook);
1098 elm_widget_content_unset_hook_set(obj, _content_unset_hook);
1099 elm_widget_signal_emit_hook_set(obj, _emit_hook);
1100 elm_widget_can_focus_set(obj, EINA_FALSE);
1101 elm_widget_focus_next_hook_set(obj, _focus_next_hook);
1104 //FIXME: Is this base layout really needed?
1105 wd->base = elm_layout_add(parent);
1106 evas_object_event_callback_add(wd->base,
1107 EVAS_CALLBACK_CHANGED_SIZE_HINTS,
1108 _changed_size_hints,
1110 elm_widget_resize_object_set(obj, wd->base);
1111 elm_layout_theme_set(wd->base, "naviframe", "base", "default");
1113 evas_object_event_callback_add(obj, EVAS_CALLBACK_MOVE, _move, obj);
1114 evas_object_event_callback_add(obj, EVAS_CALLBACK_RESIZE, _resize, obj);
1115 evas_object_smart_callbacks_descriptions_set(obj, _signals);
1117 wd->auto_pushed = EINA_TRUE;
1118 wd->freeze_events = EINA_TRUE;
1119 wd->item_style = eina_stringshare_add("basic");
1124 EAPI Elm_Object_Item *
1125 elm_naviframe_item_push(Evas_Object *obj,
1126 const char *title_label,
1127 Evas_Object *prev_btn,
1128 Evas_Object *next_btn,
1129 Evas_Object *content,
1130 const char *item_style)
1132 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1134 Elm_Naviframe_Item *prev_it, *it;
1136 wd = elm_widget_data_get(obj);
1137 if (!wd) return NULL;
1139 it = _item_new(obj, title_label, prev_btn, next_btn, content, item_style);
1140 if (!it) return NULL;
1142 evas_object_show(VIEW(it));
1144 prev_it = (Elm_Naviframe_Item *) elm_naviframe_top_item_get(obj);
1147 if (wd->freeze_events)
1149 evas_object_freeze_events_set(VIEW(it), EINA_TRUE);
1150 evas_object_freeze_events_set(VIEW(prev_it), EINA_TRUE);
1152 elm_object_signal_emit(VIEW(prev_it), "elm,state,cur,pushed", "elm");
1153 elm_object_signal_emit(VIEW(it), "elm,state,new,pushed", "elm");
1154 edje_object_message_signal_process(elm_layout_edje_get(VIEW(prev_it)));
1155 elm_widget_tree_unfocusable_set(it->content, EINA_TRUE);
1156 edje_object_message_signal_process(elm_layout_edje_get(VIEW(it)));
1158 wd->stack = eina_inlist_append(wd->stack, EINA_INLIST_GET(it));
1160 return (Elm_Object_Item *)it;
1163 EAPI Elm_Object_Item *
1164 elm_naviframe_item_insert_before(Elm_Object_Item *before,
1165 const char *title_label,
1166 Evas_Object *prev_btn,
1167 Evas_Object *next_btn,
1168 Evas_Object *content,
1169 const char *item_style)
1171 ELM_OBJ_ITEM_CHECK_OR_RETURN(before, NULL);
1172 Elm_Naviframe_Item *it;
1175 wd = elm_widget_data_get(WIDGET(before));
1176 if (!wd) return NULL;
1178 it = _item_new(WIDGET(before), title_label, prev_btn, next_btn, content,
1180 if (!it) return NULL;
1183 eina_inlist_prepend_relative(wd->stack,
1184 EINA_INLIST_GET(it),
1185 EINA_INLIST_GET(((Elm_Naviframe_Item *) before)));
1186 _sizing_eval(WIDGET(before));
1187 return (Elm_Object_Item *)it;
1190 EAPI Elm_Object_Item *
1191 elm_naviframe_item_insert_after(Elm_Object_Item *after,
1192 const char *title_label,
1193 Evas_Object *prev_btn,
1194 Evas_Object *next_btn,
1195 Evas_Object *content,
1196 const char *item_style)
1198 ELM_OBJ_ITEM_CHECK_OR_RETURN(after, NULL);
1199 Elm_Naviframe_Item *it;
1202 wd = elm_widget_data_get(WIDGET(after));
1203 if (!wd) return NULL;
1205 it = _item_new(WIDGET(after), title_label, prev_btn, next_btn, content,
1207 if (!it) return NULL;
1209 if (elm_naviframe_top_item_get(WIDGET(after)) == after)
1211 evas_object_hide(VIEW(after));
1212 evas_object_show(VIEW(it));
1215 eina_inlist_append_relative(wd->stack,
1216 EINA_INLIST_GET(it),
1217 EINA_INLIST_GET(((Elm_Naviframe_Item *) after)));
1218 _sizing_eval(WIDGET(after));
1219 return (Elm_Object_Item *)it;
1223 elm_naviframe_item_pop(Evas_Object *obj)
1225 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1226 Elm_Naviframe_Item *it, *prev_it = NULL;
1228 Evas_Object *content = NULL;
1230 wd = elm_widget_data_get(obj);
1231 if (!wd) return NULL;
1233 it = (Elm_Naviframe_Item *) elm_naviframe_top_item_get(obj);
1234 if (!it) return NULL;
1236 content = it->content;
1238 if (wd->stack->last->prev)
1239 prev_it = EINA_INLIST_CONTAINER_GET(wd->stack->last->prev,
1240 Elm_Naviframe_Item);
1241 wd->stack = eina_inlist_remove(wd->stack, EINA_INLIST_GET(it));
1244 if (wd->freeze_events)
1246 evas_object_freeze_events_set(VIEW(it), EINA_TRUE);
1247 evas_object_freeze_events_set(VIEW(prev_it), EINA_TRUE);
1249 elm_object_signal_emit(VIEW(it), "elm,state,cur,popped", "elm");
1250 evas_object_show(VIEW(prev_it));
1251 evas_object_raise(VIEW(prev_it));
1252 elm_object_signal_emit(VIEW(prev_it),
1253 "elm,state,prev,popped",
1255 edje_object_message_signal_process(elm_layout_edje_get(VIEW(it)));
1256 edje_object_message_signal_process(elm_layout_edje_get(VIEW(prev_it)));
1257 elm_widget_item_smart_callback_call(prev_it,
1258 SIG_ITEM_SHOW_BEGIN,
1264 elm_widget_item_free(it);
1271 elm_naviframe_item_pop_to(Elm_Object_Item *it)
1273 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1274 Elm_Naviframe_Item *navi_it;
1276 Eina_Inlist *l, *prev_l;
1278 navi_it = (Elm_Naviframe_Item *)it;
1279 wd = elm_widget_data_get(WIDGET(navi_it));
1282 if (it == elm_naviframe_top_item_get(WIDGET(navi_it))) return;
1284 l = wd->stack->last->prev;
1288 if (EINA_INLIST_CONTAINER_GET(l, Elm_Naviframe_Item) ==
1289 ((Elm_Naviframe_Item *)it)) break;
1291 wd->stack = eina_inlist_remove(wd->stack, l);
1292 _item_del(EINA_INLIST_CONTAINER_GET(l, Elm_Naviframe_Item));
1293 elm_widget_item_free(EINA_INLIST_CONTAINER_GET(l,
1294 Elm_Naviframe_Item));
1297 elm_naviframe_item_pop(WIDGET(navi_it));
1301 elm_naviframe_item_promote(Elm_Object_Item *it)
1303 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1304 Elm_Naviframe_Item *navi_it;
1305 Elm_Naviframe_Item *prev_it;
1308 navi_it = (Elm_Naviframe_Item *)it;
1309 wd = elm_widget_data_get(navi_it->base.widget);
1312 if (it == elm_naviframe_top_item_get(navi_it->base.widget)) return;
1313 elm_widget_tree_unfocusable_set(navi_it->content, EINA_FALSE);
1314 wd->stack = eina_inlist_demote(wd->stack, EINA_INLIST_GET(navi_it));
1315 prev_it = EINA_INLIST_CONTAINER_GET(wd->stack->last->prev,
1316 Elm_Naviframe_Item);
1317 elm_widget_tree_unfocusable_set(prev_it->content, EINA_FALSE);
1318 if (wd->freeze_events)
1320 evas_object_freeze_events_set(VIEW(it), EINA_TRUE);
1321 evas_object_freeze_events_set(VIEW(prev_it), EINA_TRUE);
1323 elm_object_signal_emit(VIEW(prev_it),
1324 "elm,state,cur,pushed",
1326 evas_object_show(VIEW(navi_it));
1327 evas_object_raise(VIEW(navi_it));
1328 elm_object_signal_emit(VIEW(navi_it),
1329 "elm,state,new,pushed",
1331 edje_object_message_signal_process(elm_layout_edje_get(VIEW(prev_it)));
1332 edje_object_message_signal_process(elm_layout_edje_get(VIEW(navi_it)));
1336 elm_naviframe_item_simple_promote(Evas_Object *obj, Evas_Object *content)
1338 ELM_CHECK_WIDTYPE(obj, widtype);
1339 Widget_Data *wd = elm_widget_data_get(obj);
1341 Elm_Naviframe_Item *itr;
1342 EINA_INLIST_FOREACH(wd->stack, itr)
1344 if (elm_object_item_content_get((Elm_Object_Item *)itr) == content)
1346 elm_naviframe_item_promote((Elm_Object_Item *)itr);
1354 elm_naviframe_item_del(Elm_Object_Item *it)
1356 elm_object_item_del(it);
1360 elm_naviframe_content_preserve_on_pop_set(Evas_Object *obj, Eina_Bool preserve)
1362 ELM_CHECK_WIDTYPE(obj, widtype);
1363 Widget_Data *wd = elm_widget_data_get(obj);
1365 wd->preserve = !!preserve;
1369 elm_naviframe_content_preserve_on_pop_get(const Evas_Object *obj)
1371 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
1372 Widget_Data *wd = elm_widget_data_get(obj);
1373 if (!wd) return EINA_FALSE;
1374 return wd->preserve;
1377 EAPI Elm_Object_Item*
1378 elm_naviframe_top_item_get(const Evas_Object *obj)
1380 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1381 Widget_Data *wd = elm_widget_data_get(obj);
1382 if ((!wd) || (!wd->stack)) return NULL;
1383 return (Elm_Object_Item *) (EINA_INLIST_CONTAINER_GET(wd->stack->last,
1384 Elm_Naviframe_Item));
1387 EAPI Elm_Object_Item*
1388 elm_naviframe_bottom_item_get(const Evas_Object *obj)
1390 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1391 Widget_Data *wd = elm_widget_data_get(obj);
1392 if ((!wd) || (!wd->stack)) return NULL;
1393 return (Elm_Object_Item *) (EINA_INLIST_CONTAINER_GET(wd->stack,
1394 Elm_Naviframe_Item));
1398 elm_naviframe_item_style_set(Elm_Object_Item *it, const char *item_style)
1400 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1401 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *)it;
1403 //Return if new style is exsiting one.
1404 if ((item_style && navi_it->style) && (!strcmp(item_style, navi_it->style)))
1407 if ((!item_style) && (!navi_it->style))
1410 _item_style_set(navi_it, item_style);
1414 elm_naviframe_item_style_get(const Elm_Object_Item *it)
1416 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
1417 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *)it;
1418 return navi_it->style;
1422 elm_naviframe_item_title_visible_set(Elm_Object_Item *it, Eina_Bool visible)
1424 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1425 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *)it;
1427 visible = !!visible;
1428 if (navi_it->title_visible == visible) return;
1430 navi_it->title_visible = visible;
1431 _item_title_visible_update(navi_it);
1435 elm_naviframe_item_title_visible_get(const Elm_Object_Item *it)
1437 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
1438 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *)it;
1439 return navi_it->title_visible;
1443 elm_naviframe_prev_btn_auto_pushed_set(Evas_Object *obj, Eina_Bool auto_pushed)
1445 ELM_CHECK_WIDTYPE(obj, widtype);
1446 Widget_Data *wd = elm_widget_data_get(obj);
1448 wd->auto_pushed = !!auto_pushed;
1452 elm_naviframe_prev_btn_auto_pushed_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->auto_pushed;
1461 elm_naviframe_items_get(const Evas_Object *obj)
1463 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1464 Widget_Data *wd = elm_widget_data_get(obj);
1465 if (!wd) return NULL;
1466 Eina_List *ret = NULL;
1467 Elm_Naviframe_Item *itr;
1468 EINA_INLIST_FOREACH(wd->stack, itr)
1469 ret = eina_list_append(ret, itr);
1474 elm_naviframe_event_enabled_set(Evas_Object *obj, Eina_Bool enabled)
1476 ELM_CHECK_WIDTYPE(obj, widtype);
1477 Widget_Data *wd = elm_widget_data_get(obj);
1479 enabled = !!enabled;
1480 if (wd->freeze_events == !enabled) return;
1481 wd->freeze_events = !enabled;
1485 elm_naviframe_event_enabled_get(const Evas_Object *obj)
1487 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
1488 Widget_Data *wd = elm_widget_data_get(obj);
1489 if (!wd) return EINA_FALSE;
1490 return !wd->freeze_events;
1494 elm_naviframe_item_style_default_set(Evas_Object *obj, const char *style)
1496 ELM_CHECK_WIDTYPE(obj, widtype);
1497 Widget_Data *wd = elm_widget_data_get(obj);
1499 eina_stringshare_replace(&wd->item_style, style);
1504 elm_naviframe_item_style_default_get(const Evas_Object *obj)
1506 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1507 Widget_Data *wd = elm_widget_data_get(obj);
1508 if (!wd) return NULL;
1509 return wd->item_style;