1 #include <Elementary.h>
4 typedef struct _Widget_Data Widget_Data;
5 typedef struct _Elm_Naviframe_Item Elm_Naviframe_Item;
6 typedef struct _Elm_Naviframe_Content_Item_Pair Elm_Naviframe_Content_Item_Pair;
7 typedef struct _Elm_Naviframe_Text_Item_Pair Elm_Naviframe_Text_Item_Pair;
13 Eina_Bool preserve: 1;
14 Eina_Bool auto_pushed: 1;
15 Eina_Bool freeze_events: 1;
16 Eina_Stringshare *item_style;
19 struct _Elm_Naviframe_Content_Item_Pair
23 Elm_Naviframe_Item *it;
26 struct _Elm_Naviframe_Text_Item_Pair
32 struct _Elm_Naviframe_Item
36 Eina_Inlist *content_list;
37 Eina_Inlist *text_list;
39 Evas_Object *title_prev_btn;
40 Evas_Object *title_next_btn;
41 Evas_Object *title_icon;
45 Eina_Bool back_btn: 1;
46 Eina_Bool title_visible: 1;
49 static const char *widtype = NULL;
51 static const char SIG_TRANSITION_FINISHED[] = "transition,finished";
52 static const char SIG_PUSH_FINISHED[] = "push,finished";
53 static const char SIG_POP_FINISHED[] = "pop,finished";
54 static const char SIG_TITLE_CLICKED[] = "title,clicked";
56 static const Evas_Smart_Cb_Description _signals[] = {
57 {SIG_TRANSITION_FINISHED, ""},
58 {SIG_TITLE_CLICKED, ""},
62 static void _text_set_hook(Evas_Object *obj,
65 static const char *_text_get_hook(const Evas_Object *obj, const char *part);
66 static void _content_set_hook(Evas_Object *obj,
68 Evas_Object *content);
69 static Evas_Object *_content_get_hook(const Evas_Object *obj, const char *part);
70 static Evas_Object *_content_unset_hook(Evas_Object *obj, const char *part);
71 static void _del_hook(Evas_Object *obj);
72 static void _theme_hook(Evas_Object *obj);
73 static void _emit_hook(Evas_Object *obj,
76 static void _disable_hook(Evas_Object *obj);
77 static void _item_text_set_hook(Elm_Object_Item *it,
80 static const char *_item_text_get_hook(const Elm_Object_Item *it,
82 static void _item_content_set_hook(Elm_Object_Item *it,
84 Evas_Object *content);
85 static Evas_Object *_item_content_get_hook(const Elm_Object_Item *it,
87 static Evas_Object *_item_content_unset_hook(Elm_Object_Item *it,
89 static void _item_signal_emit_hook(Elm_Object_Item *it,
92 static void _item_title_visible_update(Elm_Naviframe_Item *navi_it);
93 static void _sizing_eval(Evas_Object *obj);
94 static void _move(void *data, Evas *e, Evas_Object *obj, void *event_info);
95 static void _resize(void *data,
99 static void _title_clicked(void *data, Evas_Object *obj,
100 const char *emission,
102 static void _back_btn_clicked(void *data,
105 static Evas_Object *_back_btn_new(Evas_Object *obj);
106 static void _item_content_del(void *data,
110 static void _title_content_del(void *data,
114 static void _title_prev_btn_del(void *data,
118 static void _title_next_btn_del(void *data,
122 static void _title_icon_del(void *data,
126 static void _title_content_set(Elm_Naviframe_Item *it,
128 Evas_Object *content);
129 static void _title_prev_btn_set(Elm_Naviframe_Item *it,
132 static void _title_next_btn_set(Elm_Naviframe_Item *it, Evas_Object *btn);
133 static void _title_icon_set(Elm_Naviframe_Item *it, Evas_Object *icon);
134 static Evas_Object * _item_content_unset(Elm_Naviframe_Item *it);
135 static Evas_Object * _title_prev_btn_unset(Elm_Naviframe_Item *it);
136 static Evas_Object * _title_next_btn_unset(Elm_Naviframe_Item *it);
137 static Evas_Object * _title_icon_unset(Elm_Naviframe_Item *it);
138 static Evas_Object * _title_content_unset(Elm_Naviframe_Item *it,
140 static void _item_del(Elm_Naviframe_Item *it);
141 static Eina_Bool _item_del_pre_hook(Elm_Object_Item *it);
142 static void _pushed_finished(void *data,
144 const char *emission,
146 static void _popped_finished(void *data,
148 const char *emission,
150 static void _show_finished(void *data,
152 const char *emission,
154 static void _changed_size_hints(void *data,
158 static void _item_content_set(Elm_Naviframe_Item *navi_it,
159 Evas_Object *content);
160 static void _item_style_set(Elm_Naviframe_Item *navi_it,
161 const char *item_style);
162 static Elm_Naviframe_Item * _item_new(Evas_Object *obj,
163 const char *title_label,
164 Evas_Object *prev_btn,
165 Evas_Object *next_btn,
166 Evas_Object *content,
167 const char *item_style);
168 static Eina_Bool _focus_next_hook(const Evas_Object *obj,
169 Elm_Focus_Direction dir,
173 _del_hook(Evas_Object *obj)
176 Elm_Naviframe_Item *it;
178 wd = elm_widget_data_get(obj);
183 while (wd->stack->last)
185 it = EINA_INLIST_CONTAINER_GET(wd->stack->last,
187 wd->stack = eina_inlist_remove(wd->stack, wd->stack->last);
189 elm_widget_item_free(it);
190 if (!wd->stack) break;
193 eina_stringshare_del(wd->item_style);
198 _theme_hook(Evas_Object *obj)
201 Elm_Naviframe_Item *it;
203 wd = elm_widget_data_get(obj);
206 _elm_theme_object_set(obj,
210 elm_widget_style_get(obj));
212 EINA_INLIST_FOREACH(wd->stack, it)
214 _item_style_set(it, it->style);
215 _item_title_visible_update(it);
219 static void _emit_hook(Evas_Object *obj,
220 const char *emission,
223 Elm_Object_Item *it = elm_naviframe_top_item_get(obj);
225 return elm_object_item_signal_emit(it, emission, source);
229 _disable_hook(Evas_Object *obj __UNUSED__)
235 _item_text_set_hook(Elm_Object_Item *it,
239 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
241 Elm_Naviframe_Text_Item_Pair *pair = NULL;
242 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
245 if (!part || !strcmp(part, "default"))
246 snprintf(buf, sizeof(buf), "elm.text.title");
247 else if(!strcmp("subtitle", part))
248 snprintf(buf, sizeof(buf), "elm.text.subtitle");
250 snprintf(buf, sizeof(buf), "%s", part);
252 EINA_INLIST_FOREACH(navi_it->text_list, pair)
253 if (!strcmp(buf, pair->part)) break;
257 pair = ELM_NEW(Elm_Naviframe_Text_Item_Pair);
260 ERR("Failed to allocate new text part of the item! : naviframe=%p",
264 eina_stringshare_replace(&pair->part, buf);
265 navi_it->text_list = eina_inlist_append(navi_it->text_list,
266 EINA_INLIST_GET(pair));
268 elm_object_part_text_set(VIEW(navi_it), buf, label);
272 snprintf(buf, sizeof(buf), "elm,state,%s,show", buf);
273 elm_object_signal_emit(VIEW(navi_it), buf, "elm");
277 snprintf(buf, sizeof(buf), "elm,state,%s,hide", buf);
278 elm_object_signal_emit(VIEW(navi_it), buf, "elm");
281 _sizing_eval(WIDGET(navi_it));
285 _item_text_get_hook(const Elm_Object_Item *it, const char *part)
287 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
290 if (!part || !strcmp(part, "default"))
291 snprintf(buf, sizeof(buf), "elm.text.title");
292 else if(!strcmp("subtitle", part))
293 snprintf(buf, sizeof(buf), "elm.text.subtitle");
295 snprintf(buf, sizeof(buf), "%s", part);
297 return elm_object_part_text_get(VIEW(it), buf);
301 _item_content_set_hook(Elm_Object_Item *it,
303 Evas_Object *content)
305 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
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_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
339 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
342 if (!part || !strcmp("default", part))
343 return navi_it->content;
344 else if (!strcmp(part, "prev_btn"))
345 return navi_it->title_prev_btn;
346 else if (!strcmp(part, "next_btn"))
347 return navi_it->title_next_btn;
348 else if (!strcmp(part, "icon"))
349 return navi_it->title_icon;
352 return elm_object_part_content_get(VIEW(navi_it), part);
356 _item_content_unset_hook(Elm_Object_Item *it, const char *part)
358 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
359 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
362 if (!part || !strcmp("default", part))
363 return _item_content_unset(navi_it);
364 else if (!strcmp(part, "prev_btn"))
365 return _title_prev_btn_unset(navi_it);
366 else if (!strcmp(part, "next_btn"))
367 return _title_next_btn_unset(navi_it);
368 else if (!strcmp(part, "icon"))
369 return _title_icon_unset(navi_it);
371 return _title_content_unset(navi_it, part);
375 _item_signal_emit_hook(Elm_Object_Item *it,
376 const char *emission,
379 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
380 elm_object_signal_emit(VIEW(it), emission, source);
384 _item_title_visible_update(Elm_Naviframe_Item *navi_it)
386 if (navi_it->title_visible)
387 elm_object_signal_emit(VIEW(navi_it), "elm,state,title,show", "elm");
389 elm_object_signal_emit(VIEW(navi_it), "elm,state,title,hide", "elm");
393 _sizing_eval(Evas_Object *obj)
396 Elm_Naviframe_Item *it;
397 Evas_Coord x, y, w, h;
398 Evas_Coord minw = -1, minh = -1;
400 wd = elm_widget_data_get(obj);
403 evas_object_geometry_get(obj, &x, &y, &w, &h);
405 EINA_INLIST_FOREACH(wd->stack, it)
407 evas_object_move(VIEW(it), x, y);
408 evas_object_resize(VIEW(it), w, h);
409 edje_object_size_min_calc(elm_layout_edje_get(VIEW(it)),
412 if (it->minw > minw) minw = it->minw;
413 if (it->minh > minh) minh = it->minh;
415 evas_object_size_hint_min_set(obj, minw, minh);
416 evas_object_size_hint_max_set(obj, -1, -1);
420 _move(void *data __UNUSED__,
423 void *event_info __UNUSED__)
429 _resize(void *data __UNUSED__,
432 void *event_info __UNUSED__)
438 _title_clicked(void *data,
439 Evas_Object *obj __UNUSED__,
440 const char *emission __UNUSED__,
441 const char *source __UNUSED__)
443 Elm_Naviframe_Item *it = data;
444 evas_object_smart_callback_call(WIDGET(it), SIG_TITLE_CLICKED, it);
448 _back_btn_clicked(void *data,
450 void *event_info __UNUSED__)
452 /* Since edje has the event queue, clicked event could be happend multiple times
453 on some heavy environment. This callback del will prevent those scenario and
454 guarantee only one clicked for it's own page. */
455 evas_object_smart_callback_del(obj, "clicked", _back_btn_clicked);
456 elm_naviframe_item_pop(data);
460 _back_btn_new(Evas_Object *obj)
464 btn = elm_button_add(obj);
465 if (!btn) return NULL;
466 evas_object_smart_callback_add(btn, "clicked", _back_btn_clicked, obj);
467 snprintf(buf, sizeof(buf), "naviframe/back_btn/%s",
468 elm_widget_style_get(obj));
469 elm_object_style_set(btn, buf);
473 static void _text_set_hook(Evas_Object *obj,
477 Elm_Object_Item *it = elm_naviframe_top_item_get(obj);
479 elm_object_item_part_text_set(it, part, label);
482 static const char *_text_get_hook(const Evas_Object *obj, const char *part)
484 Elm_Object_Item *it = elm_naviframe_top_item_get(obj);
485 if (!it) return NULL;
486 return elm_object_item_part_text_get(it, part);
490 _content_set_hook(Evas_Object *obj, const char *part, Evas_Object *content)
492 Elm_Object_Item *it = elm_naviframe_top_item_get(obj);
494 elm_object_item_part_content_set(it, part, content);
498 _content_unset_hook(Evas_Object *obj, const char *part)
500 Elm_Object_Item *it = elm_naviframe_top_item_get(obj);
501 if (!it) return NULL;
502 return elm_object_item_part_content_unset(it, part);
506 _content_get_hook(const Evas_Object *obj, const char *part)
508 Elm_Object_Item *it = elm_naviframe_top_item_get(obj);
509 if (!it) return NULL;
510 return elm_object_item_part_content_get(it, part);
514 _title_content_del(void *data,
516 Evas_Object *obj __UNUSED__,
517 void *event_info __UNUSED__)
520 Elm_Naviframe_Content_Item_Pair *pair = data;
521 Elm_Naviframe_Item *it = pair->it;
522 snprintf(buf, sizeof(buf), "elm,state,%s,hide", pair->part);
523 elm_object_signal_emit(VIEW(it), buf, "elm");
524 it->content_list = eina_inlist_remove(it->content_list,
525 EINA_INLIST_GET(pair));
526 eina_stringshare_del(pair->part);
531 _title_prev_btn_del(void *data,
533 Evas_Object *obj __UNUSED__,
534 void *event_info __UNUSED__)
536 Elm_Naviframe_Item *it = data;
537 it->back_btn = EINA_FALSE;
538 it->title_prev_btn = NULL;
539 elm_object_signal_emit(VIEW(it), "elm,state,prev_btn,hide", "elm");
543 _title_next_btn_del(void *data,
545 Evas_Object *obj __UNUSED__,
546 void *event_info __UNUSED__)
548 Elm_Naviframe_Item *it = data;
549 it->title_next_btn = NULL;
550 elm_object_signal_emit(VIEW(it), "elm,state,next_btn,hide", "elm");
554 _title_icon_del(void *data,
556 Evas_Object *obj __UNUSED__,
557 void *event_info __UNUSED__)
559 Elm_Naviframe_Item *it = data;
560 it->title_icon = NULL;
561 elm_object_signal_emit(VIEW(it), "elm,state,icon,hide", "elm");
565 _item_content_del(void *data,
567 Evas_Object *obj __UNUSED__,
568 void *event_info __UNUSED__)
570 Elm_Naviframe_Item *it = data;
572 elm_object_signal_emit(VIEW(it), "elm,state,content,hide", "elm");
576 _title_content_set(Elm_Naviframe_Item *it,
578 Evas_Object *content)
581 Elm_Naviframe_Content_Item_Pair *pair = NULL;
582 Evas_Object *prev_content = NULL;
584 EINA_INLIST_FOREACH(it->content_list, pair)
585 if (!strcmp(part, pair->part)) break;
589 prev_content = elm_object_part_content_get(VIEW(it), part);
590 if (prev_content != content)
594 evas_object_event_callback_del(prev_content,
597 snprintf(buf, sizeof(buf), "elm,state,%s,hide", part);
598 elm_object_signal_emit(VIEW(it), buf, "elm");
600 evas_object_del(prev_content);
601 if (!content) return;
606 if (!content) return;
607 pair = ELM_NEW(Elm_Naviframe_Content_Item_Pair);
610 ERR("Failed to allocate new content part of the item! : naviframe=%p", WIDGET(it));
614 eina_stringshare_replace(&pair->part, part);
615 it->content_list = eina_inlist_append(it->content_list,
616 EINA_INLIST_GET(pair));
618 if (prev_content != content)
620 evas_object_event_callback_add(content,
625 elm_object_part_content_set(VIEW(it), part, content);
626 snprintf(buf, sizeof(buf), "elm,state,%s,show", part);
627 elm_object_signal_emit(VIEW(it), buf, "elm");
629 _sizing_eval(WIDGET(it));
633 _title_prev_btn_set(Elm_Naviframe_Item *it,
637 if (it->title_prev_btn == btn) return;
638 if (it->title_prev_btn) evas_object_del(it->title_prev_btn);
639 it->title_prev_btn = btn;
642 evas_object_event_callback_add(btn,
646 elm_object_part_content_set(VIEW(it), "elm.swallow.prev_btn", btn);
647 elm_object_signal_emit(VIEW(it), "elm,state,prev_btn,show", "elm");
648 it->back_btn = back_btn;
650 _sizing_eval(WIDGET(it));
654 _title_next_btn_set(Elm_Naviframe_Item *it, Evas_Object *btn)
656 if (it->title_next_btn == btn) return;
657 if (it->title_next_btn) evas_object_del(it->title_next_btn);
658 it->title_next_btn = btn;
661 evas_object_event_callback_add(btn,
665 elm_object_part_content_set(VIEW(it), "elm.swallow.next_btn", btn);
666 elm_object_signal_emit(VIEW(it), "elm,state,next_btn,show", "elm");
668 _sizing_eval(WIDGET(it));
672 _title_icon_set(Elm_Naviframe_Item *it, Evas_Object *icon)
674 if (it->title_icon == icon) return;
675 if (it->title_icon) evas_object_del(it->title_icon);
676 it->title_icon = icon;
679 evas_object_event_callback_add(icon,
683 elm_object_part_content_set(VIEW(it), "elm.swallow.icon", icon);
684 elm_object_signal_emit(VIEW(it), "elm,state,icon,show", "elm");
686 _sizing_eval(WIDGET(it));
690 _item_content_unset(Elm_Naviframe_Item *it)
692 Evas_Object *content = it->content;
693 if (!content) return NULL;
695 elm_object_part_content_unset(VIEW(it), "elm.swallow.content");
696 elm_object_signal_emit(VIEW(it), "elm,state,content,hide", "elm");
697 evas_object_event_callback_del(content,
700 _sizing_eval(WIDGET(it));
707 _title_prev_btn_unset(Elm_Naviframe_Item *it)
709 Evas_Object *content = it->title_prev_btn;
710 if (!content) return NULL;
712 elm_object_part_content_unset(VIEW(it), "elm.swallow.prev_btn");
713 elm_object_signal_emit(VIEW(it), "elm,state,prev_btn,hide", "elm");
714 evas_object_event_callback_del(content,
716 _title_prev_btn_del);
717 _sizing_eval(WIDGET(it));
719 it->title_prev_btn = NULL;
724 _title_next_btn_unset(Elm_Naviframe_Item *it)
726 Evas_Object *content = it->title_next_btn;
727 if (!content) return NULL;
729 elm_object_part_content_unset(VIEW(it), "elm.swallow.next_btn");
730 elm_object_signal_emit(VIEW(it), "elm,state,next_btn,hide", "elm");
731 evas_object_event_callback_del(content,
733 _title_next_btn_del);
734 _sizing_eval(WIDGET(it));
736 it->title_next_btn = NULL;
741 _title_icon_unset(Elm_Naviframe_Item *it)
743 Evas_Object *content = it->title_icon;
744 if (!content) return NULL;
746 elm_object_part_content_unset(VIEW(it), "elm.swallow.icon");
747 elm_object_signal_emit(VIEW(it), "elm,state,icon,hide", "elm");
748 evas_object_event_callback_del(content,
751 _sizing_eval(WIDGET(it));
752 it->title_icon = NULL;
758 _title_content_unset(Elm_Naviframe_Item *it, const char *part)
760 Elm_Naviframe_Content_Item_Pair *pair = NULL;
762 Evas_Object *content = NULL;
764 EINA_INLIST_FOREACH(it->content_list, pair)
766 if (!strcmp(part, pair->part))
768 content = elm_object_part_content_get(VIEW(it), part);
769 eina_stringshare_del(pair->part);
770 it->content_list = eina_inlist_remove(it->content_list,
771 EINA_INLIST_GET(pair));
777 if (!content) return NULL;
779 elm_object_part_content_unset(VIEW(it), part);
780 snprintf(buf, sizeof(buf), "elm,state,%s,hide", part);
781 elm_object_signal_emit(VIEW(it), buf, "elm");
782 evas_object_event_callback_del(content,
785 _sizing_eval(WIDGET(it));
791 _item_del(Elm_Naviframe_Item *it)
794 Elm_Naviframe_Content_Item_Pair *content_pair;
795 Elm_Naviframe_Text_Item_Pair *text_pair;
796 Evas_Object *content;
800 wd = elm_widget_data_get(WIDGET(it));
803 while (it->content_list)
806 EINA_INLIST_CONTAINER_GET(it->content_list,
807 Elm_Naviframe_Content_Item_Pair);
808 content = elm_object_part_content_get(VIEW(it), content_pair->part);
809 evas_object_event_callback_del(content,
812 eina_stringshare_del(content_pair->part);
813 it->content_list = eina_inlist_remove(it->content_list,
818 while (it->text_list)
820 text_pair = EINA_INLIST_CONTAINER_GET(it->text_list,
821 Elm_Naviframe_Text_Item_Pair);
822 eina_stringshare_del(text_pair->part);
823 it->text_list = eina_inlist_remove(it->text_list,
828 eina_stringshare_del(it->style);
832 _item_del_pre_hook(Elm_Object_Item *it)
834 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
835 Elm_Naviframe_Item *navi_it;
838 navi_it =(Elm_Naviframe_Item *) it;
839 wd = elm_widget_data_get(WIDGET(navi_it));
840 if (!wd) return EINA_FALSE;
842 if (it == elm_naviframe_top_item_get(WIDGET(navi_it)))
844 wd->stack = eina_inlist_remove(wd->stack, EINA_INLIST_GET(navi_it));
846 elm_widget_item_free(navi_it);
847 //If the item is only one, the stack will be empty
848 if (!wd->stack) return EINA_TRUE;
849 navi_it = EINA_INLIST_CONTAINER_GET(wd->stack->last,
851 evas_object_show(VIEW(navi_it));
852 evas_object_raise(VIEW(navi_it));
853 elm_object_signal_emit(VIEW(navi_it), "elm,state,visible", "elm");
857 wd->stack = eina_inlist_remove(wd->stack, EINA_INLIST_GET(navi_it));
859 elm_widget_item_free(navi_it);
866 _pushed_finished(void *data,
867 Evas_Object *obj __UNUSED__,
868 const char *emission __UNUSED__,
869 const char *source __UNUSED__)
872 Elm_Naviframe_Item *it = data;
875 wd = elm_widget_data_get(WIDGET(it));
878 evas_object_hide(VIEW(it));
879 evas_object_smart_callback_call(WIDGET(it),
882 if (wd->freeze_events)
883 evas_object_freeze_events_set(VIEW(it), EINA_FALSE);
887 _popped_finished(void *data,
888 Evas_Object *obj __UNUSED__,
889 const char *emission __UNUSED__,
890 const char *source __UNUSED__)
892 Elm_Naviframe_Item *it = data;
894 evas_object_smart_callback_call(WIDGET(it),
898 elm_widget_item_free(data);
902 _show_finished(void *data,
903 Evas_Object *obj __UNUSED__,
904 const char *emission __UNUSED__,
905 const char *source __UNUSED__)
907 Elm_Naviframe_Item *it;
912 wd = elm_widget_data_get(WIDGET(it));
915 evas_object_smart_callback_call(WIDGET(it),
916 SIG_TRANSITION_FINISHED,
918 if (wd->freeze_events)
919 evas_object_freeze_events_set(VIEW(it), EINA_FALSE);
923 _changed_size_hints(void *data,
925 Evas_Object *obj __UNUSED__,
926 void *event_info __UNUSED__)
932 _item_content_set(Elm_Naviframe_Item *navi_it, Evas_Object *content)
934 if (navi_it->content == content) return;
935 if (navi_it->content) evas_object_del(navi_it->content);
936 elm_object_part_content_set(VIEW(navi_it), "elm.swallow.content", content);
939 elm_object_signal_emit(VIEW(navi_it), "elm,state,content,show", "elm");
941 elm_object_signal_emit(VIEW(navi_it), "elm,state,content,hide", "elm");
943 evas_object_event_callback_add(content,
947 navi_it->content = content;
948 _sizing_eval(WIDGET(navi_it));
951 //FIXME: need to handle if this function is called while transition
953 _item_style_set(Elm_Naviframe_Item *navi_it, const char *item_style)
955 Elm_Naviframe_Content_Item_Pair *content_pair;
956 Elm_Naviframe_Text_Item_Pair *text_pair;
958 wd = elm_widget_data_get(WIDGET(navi_it));
965 snprintf(buf, sizeof(buf), "item/%s", wd->item_style);
969 snprintf(buf, sizeof(buf), "item/%s", item_style);
970 eina_stringshare_replace(&navi_it->style, item_style);
972 elm_layout_theme_set(VIEW(navi_it),
975 elm_widget_style_get(WIDGET(navi_it)));
977 EINA_INLIST_FOREACH(navi_it->text_list, text_pair)
978 _item_text_set_hook((Elm_Object_Item *) navi_it,
980 elm_object_part_text_get(VIEW(navi_it),
983 EINA_INLIST_FOREACH(navi_it->content_list, content_pair)
984 _item_content_set_hook((Elm_Object_Item *) navi_it,
986 elm_object_part_content_get(VIEW(navi_it),
987 content_pair->part));
989 if (navi_it->content)
990 elm_object_signal_emit(VIEW(navi_it), "elm,state,content,show", "elm");
993 if (navi_it->title_prev_btn)
994 elm_object_signal_emit(VIEW(navi_it), "elm,state,prev_btn,show", "elm");
997 if (navi_it->title_next_btn)
998 elm_object_signal_emit(VIEW(navi_it), "elm,state,next_btn,show", "elm");
1000 navi_it->title_visible = EINA_TRUE;
1001 _sizing_eval(WIDGET(navi_it));
1003 if (wd->freeze_events)
1004 evas_object_freeze_events_set(VIEW(navi_it), EINA_FALSE);
1007 static Elm_Naviframe_Item *
1008 _item_new(Evas_Object *obj,
1009 const char *title_label,
1010 Evas_Object *prev_btn,
1011 Evas_Object *next_btn,
1012 Evas_Object *content,
1013 const char *item_style)
1015 Widget_Data *wd = elm_widget_data_get(obj);
1018 Elm_Naviframe_Item *it = elm_widget_item_new(obj, Elm_Naviframe_Item);
1021 ERR("Failed to allocate new item! : naviframe=%p", obj);
1025 elm_widget_item_del_pre_hook_set(it, _item_del_pre_hook);
1026 elm_widget_item_text_set_hook_set(it, _item_text_set_hook);
1027 elm_widget_item_text_get_hook_set(it, _item_text_get_hook);
1028 elm_widget_item_content_set_hook_set(it, _item_content_set_hook);
1029 elm_widget_item_content_get_hook_set(it, _item_content_get_hook);
1030 elm_widget_item_content_unset_hook_set(it, _item_content_unset_hook);
1031 elm_widget_item_signal_emit_hook_set(it, _item_signal_emit_hook);
1034 VIEW(it) = elm_layout_add(obj);
1035 evas_object_smart_member_add(VIEW(it), wd->base);
1037 evas_object_event_callback_add(VIEW(it),
1038 EVAS_CALLBACK_CHANGED_SIZE_HINTS,
1039 _changed_size_hints,
1041 elm_object_signal_callback_add(VIEW(it),
1042 "elm,action,show,finished",
1044 _show_finished, it);
1045 elm_object_signal_callback_add(VIEW(it),
1046 "elm,action,pushed,finished",
1048 _pushed_finished, it);
1049 elm_object_signal_callback_add(VIEW(it),
1050 "elm,action,popped,finished",
1052 _popped_finished, it);
1053 elm_object_signal_callback_add(VIEW(it),
1054 "elm,action,title,clicked",
1056 _title_clicked, it);
1058 _item_style_set(it, item_style);
1059 _item_text_set_hook((Elm_Object_Item *) it, "elm.text.title", title_label);
1062 if ((!prev_btn) && wd->auto_pushed && eina_inlist_count(wd->stack))
1064 prev_btn = _back_btn_new(obj);
1065 _title_prev_btn_set(it, prev_btn, EINA_TRUE);
1068 _title_prev_btn_set(it, prev_btn, EINA_FALSE);
1070 _title_next_btn_set(it, next_btn);
1071 _item_content_set(it, content);
1072 it->title_visible = EINA_TRUE;
1077 _focus_next_hook(const Evas_Object *obj, Elm_Focus_Direction dir, Evas_Object **next)
1079 Widget_Data *wd = elm_widget_data_get(obj);
1080 if (!wd || !wd->stack) return EINA_FALSE;
1081 return elm_widget_focus_next_get(VIEW(elm_naviframe_top_item_get(obj)),
1087 elm_naviframe_add(Evas_Object *parent)
1093 ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL);
1094 ELM_SET_WIDTYPE(widtype, "naviframe");
1095 elm_widget_type_set(obj, "naviframe");
1096 elm_widget_sub_object_add(parent, obj);
1097 elm_widget_data_set(obj, wd);
1098 elm_widget_del_hook_set(obj, _del_hook);
1099 elm_widget_disable_hook_set(obj, _disable_hook);
1100 elm_widget_theme_hook_set(obj, _theme_hook);
1101 elm_widget_text_set_hook_set(obj, _text_set_hook);
1102 elm_widget_text_get_hook_set(obj, _text_get_hook);
1103 elm_widget_content_set_hook_set(obj, _content_set_hook);
1104 elm_widget_content_get_hook_set(obj, _content_get_hook);
1105 elm_widget_content_unset_hook_set(obj, _content_unset_hook);
1106 elm_widget_signal_emit_hook_set(obj, _emit_hook);
1107 elm_widget_can_focus_set(obj, EINA_FALSE);
1108 elm_widget_focus_next_hook_set(obj, _focus_next_hook);
1111 //FIXME: Is this base layout really needed?
1112 wd->base = elm_layout_add(parent);
1113 evas_object_event_callback_add(wd->base,
1114 EVAS_CALLBACK_CHANGED_SIZE_HINTS,
1115 _changed_size_hints,
1117 elm_widget_resize_object_set(obj, wd->base);
1118 elm_layout_theme_set(wd->base, "naviframe", "base", "default");
1120 evas_object_event_callback_add(obj, EVAS_CALLBACK_MOVE, _move, obj);
1121 evas_object_event_callback_add(obj, EVAS_CALLBACK_RESIZE, _resize, obj);
1122 evas_object_smart_callbacks_descriptions_set(obj, _signals);
1124 wd->auto_pushed = EINA_TRUE;
1125 wd->freeze_events = EINA_TRUE;
1126 wd->item_style = eina_stringshare_add("basic");
1131 EAPI Elm_Object_Item *
1132 elm_naviframe_item_push(Evas_Object *obj,
1133 const char *title_label,
1134 Evas_Object *prev_btn,
1135 Evas_Object *next_btn,
1136 Evas_Object *content,
1137 const char *item_style)
1139 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1141 Elm_Naviframe_Item *prev_it, *it;
1143 wd = elm_widget_data_get(obj);
1144 if (!wd) return NULL;
1146 it = _item_new(obj, title_label, prev_btn, next_btn, content, item_style);
1147 if (!it) return NULL;
1149 evas_object_show(VIEW(it));
1151 prev_it = (Elm_Naviframe_Item *) elm_naviframe_top_item_get(obj);
1154 if (wd->freeze_events)
1156 evas_object_freeze_events_set(VIEW(it), EINA_TRUE);
1157 evas_object_freeze_events_set(VIEW(prev_it), EINA_TRUE);
1159 elm_object_signal_emit(VIEW(prev_it), "elm,state,cur,pushed", "elm");
1160 elm_object_signal_emit(VIEW(it), "elm,state,new,pushed", "elm");
1161 edje_object_message_signal_process(elm_layout_edje_get(VIEW(prev_it)));
1162 edje_object_message_signal_process(elm_layout_edje_get(VIEW(it)));
1164 wd->stack = eina_inlist_append(wd->stack, EINA_INLIST_GET(it));
1166 return (Elm_Object_Item *) it;
1169 EAPI Elm_Object_Item *
1170 elm_naviframe_item_insert_before(Elm_Object_Item *before,
1171 const char *title_label,
1172 Evas_Object *prev_btn,
1173 Evas_Object *next_btn,
1174 Evas_Object *content,
1175 const char *item_style)
1177 ELM_OBJ_ITEM_CHECK_OR_RETURN(before, NULL);
1178 Elm_Naviframe_Item *it;
1181 wd = elm_widget_data_get(WIDGET(before));
1182 if (!wd) return NULL;
1184 it = _item_new(WIDGET(before), title_label, prev_btn, next_btn, content,
1186 if (!it) return NULL;
1189 eina_inlist_prepend_relative(wd->stack, EINA_INLIST_GET(it),
1190 EINA_INLIST_GET(((Elm_Naviframe_Item *) before)));
1191 _sizing_eval(WIDGET(before));
1192 return (Elm_Object_Item *) it;
1195 EAPI Elm_Object_Item *
1196 elm_naviframe_item_insert_after(Elm_Object_Item *after,
1197 const char *title_label,
1198 Evas_Object *prev_btn,
1199 Evas_Object *next_btn,
1200 Evas_Object *content,
1201 const char *item_style)
1203 ELM_OBJ_ITEM_CHECK_OR_RETURN(after, NULL);
1204 Elm_Naviframe_Item *it;
1207 wd = elm_widget_data_get(WIDGET(after));
1208 if (!wd) return NULL;
1210 it = _item_new(WIDGET(after), title_label, prev_btn, next_btn, content,
1212 if (!it) return NULL;
1214 if (elm_naviframe_top_item_get(WIDGET(after)) == after)
1216 evas_object_hide(VIEW(after));
1217 evas_object_show(VIEW(it));
1220 eina_inlist_append_relative(wd->stack, EINA_INLIST_GET(it),
1221 EINA_INLIST_GET(((Elm_Naviframe_Item *) after)));
1222 _sizing_eval(WIDGET(after));
1223 return (Elm_Object_Item *) it;
1227 elm_naviframe_item_pop(Evas_Object *obj)
1229 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1230 Elm_Naviframe_Item *it, *prev_it = NULL;
1232 Evas_Object *content = NULL;
1234 wd = elm_widget_data_get(obj);
1235 if (!wd) return NULL;
1237 it = (Elm_Naviframe_Item *) elm_naviframe_top_item_get(obj);
1238 if (!it) return NULL;
1239 elm_widget_tree_unfocusable_set(it->content, EINA_TRUE);
1241 content = it->content;
1243 if (wd->stack->last->prev)
1244 prev_it = EINA_INLIST_CONTAINER_GET(wd->stack->last->prev,
1245 Elm_Naviframe_Item);
1246 wd->stack = eina_inlist_remove(wd->stack, EINA_INLIST_GET(it));
1249 if (wd->freeze_events)
1251 evas_object_freeze_events_set(VIEW(it), EINA_TRUE);
1252 evas_object_freeze_events_set(VIEW(prev_it), EINA_TRUE);
1254 elm_object_signal_emit(VIEW(it), "elm,state,cur,popped", "elm");
1255 evas_object_show(VIEW(prev_it));
1256 evas_object_raise(VIEW(prev_it));
1257 elm_object_signal_emit(VIEW(prev_it),
1258 "elm,state,prev,popped",
1260 edje_object_message_signal_process(elm_layout_edje_get(VIEW(it)));
1261 edje_object_message_signal_process(elm_layout_edje_get(VIEW(prev_it)));
1266 elm_widget_item_free(it);
1273 elm_naviframe_item_pop_to(Elm_Object_Item *it)
1275 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1276 Elm_Naviframe_Item *navi_it;
1278 Eina_Inlist *l, *prev_l;
1280 navi_it = (Elm_Naviframe_Item *) it;
1281 wd = elm_widget_data_get(WIDGET(navi_it));
1284 if (it == elm_naviframe_top_item_get(WIDGET(navi_it))) return;
1286 l = wd->stack->last->prev;
1290 if (EINA_INLIST_CONTAINER_GET(l, Elm_Naviframe_Item) ==
1291 ((Elm_Naviframe_Item *) it)) break;
1293 wd->stack = eina_inlist_remove(wd->stack, l);
1294 _item_del(EINA_INLIST_CONTAINER_GET(l, Elm_Naviframe_Item));
1295 elm_widget_item_free(EINA_INLIST_CONTAINER_GET(l,
1296 Elm_Naviframe_Item));
1299 elm_naviframe_item_pop(WIDGET(navi_it));
1303 elm_naviframe_item_promote(Elm_Object_Item *it)
1305 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1306 Elm_Naviframe_Item *navi_it;
1307 Elm_Naviframe_Item *prev_it;
1310 navi_it = (Elm_Naviframe_Item *) it;
1311 wd = elm_widget_data_get(navi_it->base.widget);
1314 if (it == elm_naviframe_top_item_get(navi_it->base.widget)) return;
1315 wd->stack = eina_inlist_demote(wd->stack, EINA_INLIST_GET(navi_it));
1316 prev_it = EINA_INLIST_CONTAINER_GET(wd->stack->last->prev,
1317 Elm_Naviframe_Item);
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)
1470 ret = eina_list_append(ret, itr);
1476 elm_naviframe_event_enabled_set(Evas_Object *obj, Eina_Bool enabled)
1478 ELM_CHECK_WIDTYPE(obj, widtype);
1479 Widget_Data *wd = elm_widget_data_get(obj);
1481 enabled = !!enabled;
1482 if (wd->freeze_events == !enabled) return;
1483 wd->freeze_events = !enabled;
1487 elm_naviframe_event_enabled_get(const Evas_Object *obj)
1489 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
1490 Widget_Data *wd = elm_widget_data_get(obj);
1491 if (!wd) return EINA_FALSE;
1492 return !wd->freeze_events;
1496 elm_naviframe_item_style_default_set(Evas_Object *obj, const char *style)
1498 ELM_CHECK_WIDTYPE(obj, widtype);
1499 Widget_Data *wd = elm_widget_data_get(obj);
1501 eina_stringshare_replace(&wd->item_style, style);
1506 elm_naviframe_item_style_default_get(const Evas_Object *obj)
1508 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1509 Widget_Data *wd = elm_widget_data_get(obj);
1510 if (!wd) return NULL;
1511 return wd->item_style;