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 navi_it->title_visible = EINA_TRUE;
993 _sizing_eval(WIDGET(navi_it));
995 if (wd->freeze_events)
996 evas_object_freeze_events_set(VIEW(navi_it), EINA_FALSE);
999 static Elm_Naviframe_Item *
1000 _item_new(Evas_Object *obj,
1001 const char *title_label,
1002 Evas_Object *prev_btn,
1003 Evas_Object *next_btn,
1004 Evas_Object *content,
1005 const char *item_style)
1007 Widget_Data *wd = elm_widget_data_get(obj);
1010 Elm_Naviframe_Item *it = elm_widget_item_new(obj, Elm_Naviframe_Item);
1013 ERR("Failed to allocate new item! : naviframe=%p", obj);
1017 elm_widget_item_del_pre_hook_set(it, _item_del_pre_hook);
1018 elm_widget_item_text_set_hook_set(it, _item_text_set_hook);
1019 elm_widget_item_text_get_hook_set(it, _item_text_get_hook);
1020 elm_widget_item_content_set_hook_set(it, _item_content_set_hook);
1021 elm_widget_item_content_get_hook_set(it, _item_content_get_hook);
1022 elm_widget_item_content_unset_hook_set(it, _item_content_unset_hook);
1023 elm_widget_item_signal_emit_hook_set(it, _item_signal_emit_hook);
1026 VIEW(it) = elm_layout_add(obj);
1027 evas_object_smart_member_add(VIEW(it), wd->base);
1029 evas_object_event_callback_add(VIEW(it),
1030 EVAS_CALLBACK_CHANGED_SIZE_HINTS,
1031 _changed_size_hints,
1033 elm_object_signal_callback_add(VIEW(it),
1034 "elm,action,show,finished",
1036 _show_finished, it);
1037 elm_object_signal_callback_add(VIEW(it),
1038 "elm,action,pushed,finished",
1040 _pushed_finished, it);
1041 elm_object_signal_callback_add(VIEW(it),
1042 "elm,action,popped,finished",
1044 _popped_finished, it);
1045 elm_object_signal_callback_add(VIEW(it),
1046 "elm,action,title,clicked",
1048 _title_clicked, it);
1050 _item_style_set(it, item_style);
1051 _item_text_set_hook((Elm_Object_Item *) it, "elm.text.title", title_label);
1054 if ((!prev_btn) && wd->auto_pushed && eina_inlist_count(wd->stack))
1056 prev_btn = _back_btn_new(obj);
1057 _title_prev_btn_set(it, prev_btn, EINA_TRUE);
1060 _title_prev_btn_set(it, prev_btn, EINA_FALSE);
1062 _title_next_btn_set(it, next_btn);
1063 _item_content_set(it, content);
1064 it->title_visible = EINA_TRUE;
1069 _focus_next_hook(const Evas_Object *obj, Elm_Focus_Direction dir, Evas_Object **next)
1071 Widget_Data *wd = elm_widget_data_get(obj);
1072 if (!wd || !wd->stack) return EINA_FALSE;
1073 return elm_widget_focus_next_get(VIEW(elm_naviframe_top_item_get(obj)),
1079 elm_naviframe_add(Evas_Object *parent)
1085 ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL);
1086 ELM_SET_WIDTYPE(widtype, "naviframe");
1087 elm_widget_type_set(obj, "naviframe");
1088 elm_widget_sub_object_add(parent, obj);
1089 elm_widget_data_set(obj, wd);
1090 elm_widget_del_hook_set(obj, _del_hook);
1091 elm_widget_disable_hook_set(obj, _disable_hook);
1092 elm_widget_theme_hook_set(obj, _theme_hook);
1093 elm_widget_text_set_hook_set(obj, _text_set_hook);
1094 elm_widget_text_get_hook_set(obj, _text_get_hook);
1095 elm_widget_content_set_hook_set(obj, _content_set_hook);
1096 elm_widget_content_get_hook_set(obj, _content_get_hook);
1097 elm_widget_content_unset_hook_set(obj, _content_unset_hook);
1098 elm_widget_signal_emit_hook_set(obj, _emit_hook);
1099 elm_widget_can_focus_set(obj, EINA_FALSE);
1100 elm_widget_focus_next_hook_set(obj, _focus_next_hook);
1103 //FIXME: Is this base layout really needed?
1104 wd->base = elm_layout_add(parent);
1105 evas_object_event_callback_add(wd->base,
1106 EVAS_CALLBACK_CHANGED_SIZE_HINTS,
1107 _changed_size_hints,
1109 elm_widget_resize_object_set(obj, wd->base);
1110 elm_layout_theme_set(wd->base, "naviframe", "base", "default");
1112 evas_object_event_callback_add(obj, EVAS_CALLBACK_MOVE, _move, obj);
1113 evas_object_event_callback_add(obj, EVAS_CALLBACK_RESIZE, _resize, obj);
1114 evas_object_smart_callbacks_descriptions_set(obj, _signals);
1116 wd->auto_pushed = EINA_TRUE;
1117 wd->freeze_events = EINA_TRUE;
1118 wd->item_style = eina_stringshare_add("basic");
1123 EAPI Elm_Object_Item *
1124 elm_naviframe_item_push(Evas_Object *obj,
1125 const char *title_label,
1126 Evas_Object *prev_btn,
1127 Evas_Object *next_btn,
1128 Evas_Object *content,
1129 const char *item_style)
1131 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1133 Elm_Naviframe_Item *prev_it, *it;
1135 wd = elm_widget_data_get(obj);
1136 if (!wd) return NULL;
1138 it = _item_new(obj, title_label, prev_btn, next_btn, content, item_style);
1139 if (!it) return NULL;
1141 evas_object_show(VIEW(it));
1143 prev_it = (Elm_Naviframe_Item *) elm_naviframe_top_item_get(obj);
1146 if (wd->freeze_events)
1148 evas_object_freeze_events_set(VIEW(it), EINA_TRUE);
1149 evas_object_freeze_events_set(VIEW(prev_it), EINA_TRUE);
1151 elm_object_signal_emit(VIEW(prev_it), "elm,state,cur,pushed", "elm");
1152 elm_object_signal_emit(VIEW(it), "elm,state,new,pushed", "elm");
1153 edje_object_message_signal_process(elm_layout_edje_get(VIEW(prev_it)));
1154 edje_object_message_signal_process(elm_layout_edje_get(VIEW(it)));
1156 wd->stack = eina_inlist_append(wd->stack, EINA_INLIST_GET(it));
1158 return (Elm_Object_Item *) it;
1161 EAPI Elm_Object_Item *
1162 elm_naviframe_item_insert_before(Elm_Object_Item *before,
1163 const char *title_label,
1164 Evas_Object *prev_btn,
1165 Evas_Object *next_btn,
1166 Evas_Object *content,
1167 const char *item_style)
1169 ELM_OBJ_ITEM_CHECK_OR_RETURN(before, NULL);
1170 Elm_Naviframe_Item *it;
1173 wd = elm_widget_data_get(WIDGET(before));
1174 if (!wd) return NULL;
1176 it = _item_new(WIDGET(before), title_label, prev_btn, next_btn, content,
1178 if (!it) return NULL;
1181 eina_inlist_prepend_relative(wd->stack,
1182 EINA_INLIST_GET(it),
1183 EINA_INLIST_GET(((Elm_Naviframe_Item *) before)));
1184 _sizing_eval(WIDGET(before));
1185 return (Elm_Object_Item *) it;
1188 EAPI Elm_Object_Item *
1189 elm_naviframe_item_insert_after(Elm_Object_Item *after,
1190 const char *title_label,
1191 Evas_Object *prev_btn,
1192 Evas_Object *next_btn,
1193 Evas_Object *content,
1194 const char *item_style)
1196 ELM_OBJ_ITEM_CHECK_OR_RETURN(after, NULL);
1197 Elm_Naviframe_Item *it;
1200 wd = elm_widget_data_get(WIDGET(after));
1201 if (!wd) return NULL;
1203 it = _item_new(WIDGET(after), title_label, prev_btn, next_btn, content,
1205 if (!it) return NULL;
1207 if (elm_naviframe_top_item_get(WIDGET(after)) == after)
1209 evas_object_hide(VIEW(after));
1210 evas_object_show(VIEW(it));
1213 eina_inlist_append_relative(wd->stack,
1214 EINA_INLIST_GET(it),
1215 EINA_INLIST_GET(((Elm_Naviframe_Item *) after)));
1216 _sizing_eval(WIDGET(after));
1217 return (Elm_Object_Item *) it;
1221 elm_naviframe_item_pop(Evas_Object *obj)
1223 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1224 Elm_Naviframe_Item *it, *prev_it = NULL;
1226 Evas_Object *content = NULL;
1228 wd = elm_widget_data_get(obj);
1229 if (!wd) return NULL;
1231 it = (Elm_Naviframe_Item *) elm_naviframe_top_item_get(obj);
1232 if (!it) return NULL;
1233 elm_widget_tree_unfocusable_set(it->content, EINA_TRUE);
1235 content = it->content;
1237 if (wd->stack->last->prev)
1238 prev_it = EINA_INLIST_CONTAINER_GET(wd->stack->last->prev,
1239 Elm_Naviframe_Item);
1240 wd->stack = eina_inlist_remove(wd->stack, EINA_INLIST_GET(it));
1243 if (wd->freeze_events)
1245 evas_object_freeze_events_set(VIEW(it), EINA_TRUE);
1246 evas_object_freeze_events_set(VIEW(prev_it), EINA_TRUE);
1248 elm_object_signal_emit(VIEW(it), "elm,state,cur,popped", "elm");
1249 evas_object_show(VIEW(prev_it));
1250 evas_object_raise(VIEW(prev_it));
1251 elm_object_signal_emit(VIEW(prev_it),
1252 "elm,state,prev,popped",
1254 edje_object_message_signal_process(elm_layout_edje_get(VIEW(it)));
1255 edje_object_message_signal_process(elm_layout_edje_get(VIEW(prev_it)));
1256 elm_widget_item_smart_callback_call(prev_it,
1257 SIG_ITEM_SHOW_BEGIN,
1263 elm_widget_item_free(it);
1270 elm_naviframe_item_pop_to(Elm_Object_Item *it)
1272 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1273 Elm_Naviframe_Item *navi_it;
1275 Eina_Inlist *l, *prev_l;
1277 navi_it = (Elm_Naviframe_Item *) it;
1278 wd = elm_widget_data_get(WIDGET(navi_it));
1281 if (it == elm_naviframe_top_item_get(WIDGET(navi_it))) return;
1283 l = wd->stack->last->prev;
1287 if (EINA_INLIST_CONTAINER_GET(l, Elm_Naviframe_Item) ==
1288 ((Elm_Naviframe_Item *) it)) break;
1290 wd->stack = eina_inlist_remove(wd->stack, l);
1291 _item_del(EINA_INLIST_CONTAINER_GET(l, Elm_Naviframe_Item));
1292 elm_widget_item_free(EINA_INLIST_CONTAINER_GET(l,
1293 Elm_Naviframe_Item));
1296 elm_naviframe_item_pop(WIDGET(navi_it));
1300 elm_naviframe_item_promote(Elm_Object_Item *it)
1302 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1303 Elm_Naviframe_Item *navi_it;
1304 Elm_Naviframe_Item *prev_it;
1307 navi_it = (Elm_Naviframe_Item *) it;
1308 wd = elm_widget_data_get(navi_it->base.widget);
1311 if (it == elm_naviframe_top_item_get(navi_it->base.widget)) return;
1312 wd->stack = eina_inlist_demote(wd->stack, EINA_INLIST_GET(navi_it));
1313 prev_it = EINA_INLIST_CONTAINER_GET(wd->stack->last->prev,
1314 Elm_Naviframe_Item);
1315 if (wd->freeze_events)
1317 evas_object_freeze_events_set(VIEW(it), EINA_TRUE);
1318 evas_object_freeze_events_set(VIEW(prev_it), EINA_TRUE);
1320 elm_object_signal_emit(VIEW(prev_it),
1321 "elm,state,cur,pushed",
1323 evas_object_show(VIEW(navi_it));
1324 evas_object_raise(VIEW(navi_it));
1325 elm_object_signal_emit(VIEW(navi_it),
1326 "elm,state,new,pushed",
1328 edje_object_message_signal_process(elm_layout_edje_get(VIEW(prev_it)));
1329 edje_object_message_signal_process(elm_layout_edje_get(VIEW(navi_it)));
1333 elm_naviframe_item_simple_promote(Evas_Object *obj, Evas_Object *content)
1335 ELM_CHECK_WIDTYPE(obj, widtype);
1336 Widget_Data *wd = elm_widget_data_get(obj);
1338 Elm_Naviframe_Item *itr;
1339 EINA_INLIST_FOREACH(wd->stack, itr)
1341 if (elm_object_item_content_get((Elm_Object_Item *) itr) == content)
1343 elm_naviframe_item_promote((Elm_Object_Item *) itr);
1351 elm_naviframe_item_del(Elm_Object_Item *it)
1353 elm_object_item_del(it);
1357 elm_naviframe_content_preserve_on_pop_set(Evas_Object *obj, Eina_Bool preserve)
1359 ELM_CHECK_WIDTYPE(obj, widtype);
1360 Widget_Data *wd = elm_widget_data_get(obj);
1362 wd->preserve = !!preserve;
1366 elm_naviframe_content_preserve_on_pop_get(const Evas_Object *obj)
1368 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
1369 Widget_Data *wd = elm_widget_data_get(obj);
1370 if (!wd) return EINA_FALSE;
1371 return wd->preserve;
1374 EAPI Elm_Object_Item*
1375 elm_naviframe_top_item_get(const Evas_Object *obj)
1377 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1378 Widget_Data *wd = elm_widget_data_get(obj);
1379 if ((!wd) || (!wd->stack)) return NULL;
1380 return (Elm_Object_Item *) (EINA_INLIST_CONTAINER_GET(wd->stack->last,
1381 Elm_Naviframe_Item));
1384 EAPI Elm_Object_Item*
1385 elm_naviframe_bottom_item_get(const Evas_Object *obj)
1387 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1388 Widget_Data *wd = elm_widget_data_get(obj);
1389 if ((!wd) || (!wd->stack)) return NULL;
1390 return (Elm_Object_Item *) (EINA_INLIST_CONTAINER_GET(wd->stack,
1391 Elm_Naviframe_Item));
1395 elm_naviframe_item_style_set(Elm_Object_Item *it, const char *item_style)
1397 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1398 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
1400 //Return if new style is exsiting one.
1401 if ((item_style && navi_it->style) && (!strcmp(item_style, navi_it->style)))
1404 if ((!item_style) && (!navi_it->style))
1407 _item_style_set(navi_it, item_style);
1411 elm_naviframe_item_style_get(const Elm_Object_Item *it)
1413 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
1414 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
1415 return navi_it->style;
1419 elm_naviframe_item_title_visible_set(Elm_Object_Item *it, Eina_Bool visible)
1421 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1422 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
1424 visible = !!visible;
1425 if (navi_it->title_visible == visible) return;
1427 navi_it->title_visible = visible;
1428 _item_title_visible_update(navi_it);
1432 elm_naviframe_item_title_visible_get(const Elm_Object_Item *it)
1434 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
1435 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
1436 return navi_it->title_visible;
1440 elm_naviframe_prev_btn_auto_pushed_set(Evas_Object *obj, Eina_Bool auto_pushed)
1442 ELM_CHECK_WIDTYPE(obj, widtype);
1443 Widget_Data *wd = elm_widget_data_get(obj);
1445 wd->auto_pushed = !!auto_pushed;
1449 elm_naviframe_prev_btn_auto_pushed_get(const Evas_Object *obj)
1451 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
1452 Widget_Data *wd = elm_widget_data_get(obj);
1453 if (!wd) return EINA_FALSE;
1454 return wd->auto_pushed;
1458 elm_naviframe_items_get(const Evas_Object *obj)
1460 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1461 Widget_Data *wd = elm_widget_data_get(obj);
1462 if (!wd) return NULL;
1463 Eina_List *ret = NULL;
1464 Elm_Naviframe_Item *itr;
1465 EINA_INLIST_FOREACH(wd->stack, itr)
1467 ret = eina_list_append(ret, itr);
1473 elm_naviframe_event_enabled_set(Evas_Object *obj, Eina_Bool enabled)
1475 ELM_CHECK_WIDTYPE(obj, widtype);
1476 Widget_Data *wd = elm_widget_data_get(obj);
1478 enabled = !!enabled;
1479 if (wd->freeze_events == !enabled) return;
1480 wd->freeze_events = !enabled;
1484 elm_naviframe_event_enabled_get(const Evas_Object *obj)
1486 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
1487 Widget_Data *wd = elm_widget_data_get(obj);
1488 if (!wd) return EINA_FALSE;
1489 return !wd->freeze_events;
1493 elm_naviframe_item_style_default_set(Evas_Object *obj, const char *style)
1495 ELM_CHECK_WIDTYPE(obj, widtype);
1496 Widget_Data *wd = elm_widget_data_get(obj);
1498 eina_stringshare_replace(&wd->item_style, style);
1503 elm_naviframe_item_style_default_get(const Evas_Object *obj)
1505 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1506 Widget_Data *wd = elm_widget_data_get(obj);
1507 if (!wd) return NULL;
1508 return wd->item_style;