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 //If the item is only one, the stack will be empty
847 if (!wd->stack) return EINA_TRUE;
848 navi_it = EINA_INLIST_CONTAINER_GET(wd->stack->last,
850 evas_object_show(VIEW(navi_it));
851 evas_object_raise(VIEW(navi_it));
852 elm_object_signal_emit(VIEW(navi_it), "elm,state,visible", "elm");
856 wd->stack = eina_inlist_remove(wd->stack, EINA_INLIST_GET(navi_it));
864 _pushed_finished(void *data,
865 Evas_Object *obj __UNUSED__,
866 const char *emission __UNUSED__,
867 const char *source __UNUSED__)
870 Elm_Naviframe_Item *it = data;
873 wd = elm_widget_data_get(WIDGET(it));
876 evas_object_hide(VIEW(it));
877 evas_object_smart_callback_call(WIDGET(it),
880 if (wd->freeze_events)
881 evas_object_freeze_events_set(VIEW(it), EINA_FALSE);
885 _popped_finished(void *data,
886 Evas_Object *obj __UNUSED__,
887 const char *emission __UNUSED__,
888 const char *source __UNUSED__)
890 Elm_Naviframe_Item *it = data;
892 evas_object_smart_callback_call(WIDGET(it),
896 elm_widget_item_free(data);
900 _show_finished(void *data,
901 Evas_Object *obj __UNUSED__,
902 const char *emission __UNUSED__,
903 const char *source __UNUSED__)
905 Elm_Naviframe_Item *it;
910 wd = elm_widget_data_get(WIDGET(it));
913 evas_object_smart_callback_call(WIDGET(it),
914 SIG_TRANSITION_FINISHED,
916 if (wd->freeze_events)
917 evas_object_freeze_events_set(VIEW(it), EINA_FALSE);
921 _changed_size_hints(void *data,
923 Evas_Object *obj __UNUSED__,
924 void *event_info __UNUSED__)
930 _item_content_set(Elm_Naviframe_Item *navi_it, Evas_Object *content)
932 if (navi_it->content == content) return;
933 if (navi_it->content) evas_object_del(navi_it->content);
934 elm_object_part_content_set(VIEW(navi_it), "elm.swallow.content", content);
937 elm_object_signal_emit(VIEW(navi_it), "elm,state,content,show", "elm");
939 elm_object_signal_emit(VIEW(navi_it), "elm,state,content,hide", "elm");
941 evas_object_event_callback_add(content,
945 navi_it->content = content;
946 _sizing_eval(WIDGET(navi_it));
949 //FIXME: need to handle if this function is called while transition
951 _item_style_set(Elm_Naviframe_Item *navi_it, const char *item_style)
953 Elm_Naviframe_Content_Item_Pair *content_pair;
954 Elm_Naviframe_Text_Item_Pair *text_pair;
956 wd = elm_widget_data_get(WIDGET(navi_it));
963 snprintf(buf, sizeof(buf), "item/%s", wd->item_style);
967 snprintf(buf, sizeof(buf), "item/%s", item_style);
968 eina_stringshare_replace(&navi_it->style, item_style);
970 elm_layout_theme_set(VIEW(navi_it),
973 elm_widget_style_get(WIDGET(navi_it)));
975 EINA_INLIST_FOREACH(navi_it->text_list, text_pair)
976 _item_text_set_hook((Elm_Object_Item *) navi_it,
978 elm_object_part_text_get(VIEW(navi_it),
981 EINA_INLIST_FOREACH(navi_it->content_list, content_pair)
982 _item_content_set_hook((Elm_Object_Item *) navi_it,
984 elm_object_part_content_get(VIEW(navi_it),
985 content_pair->part));
987 if (navi_it->content)
988 elm_object_signal_emit(VIEW(navi_it), "elm,state,content,show", "elm");
991 if (navi_it->title_prev_btn)
992 elm_object_signal_emit(VIEW(navi_it), "elm,state,prev_btn,show", "elm");
995 if (navi_it->title_next_btn)
996 elm_object_signal_emit(VIEW(navi_it), "elm,state,next_btn,show", "elm");
998 navi_it->title_visible = EINA_TRUE;
999 _sizing_eval(WIDGET(navi_it));
1001 if (wd->freeze_events)
1002 evas_object_freeze_events_set(VIEW(navi_it), EINA_FALSE);
1005 static Elm_Naviframe_Item *
1006 _item_new(Evas_Object *obj,
1007 const char *title_label,
1008 Evas_Object *prev_btn,
1009 Evas_Object *next_btn,
1010 Evas_Object *content,
1011 const char *item_style)
1013 Widget_Data *wd = elm_widget_data_get(obj);
1016 Elm_Naviframe_Item *it = elm_widget_item_new(obj, Elm_Naviframe_Item);
1019 ERR("Failed to allocate new item! : naviframe=%p", obj);
1023 elm_widget_item_del_pre_hook_set(it, _item_del_pre_hook);
1024 elm_widget_item_text_set_hook_set(it, _item_text_set_hook);
1025 elm_widget_item_text_get_hook_set(it, _item_text_get_hook);
1026 elm_widget_item_content_set_hook_set(it, _item_content_set_hook);
1027 elm_widget_item_content_get_hook_set(it, _item_content_get_hook);
1028 elm_widget_item_content_unset_hook_set(it, _item_content_unset_hook);
1029 elm_widget_item_signal_emit_hook_set(it, _item_signal_emit_hook);
1032 VIEW(it) = elm_layout_add(obj);
1033 evas_object_smart_member_add(VIEW(it), wd->base);
1035 evas_object_event_callback_add(VIEW(it),
1036 EVAS_CALLBACK_CHANGED_SIZE_HINTS,
1037 _changed_size_hints,
1039 elm_object_signal_callback_add(VIEW(it),
1040 "elm,action,show,finished",
1042 _show_finished, it);
1043 elm_object_signal_callback_add(VIEW(it),
1044 "elm,action,pushed,finished",
1046 _pushed_finished, it);
1047 elm_object_signal_callback_add(VIEW(it),
1048 "elm,action,popped,finished",
1050 _popped_finished, it);
1051 elm_object_signal_callback_add(VIEW(it),
1052 "elm,action,title,clicked",
1054 _title_clicked, it);
1056 _item_style_set(it, item_style);
1057 _item_text_set_hook((Elm_Object_Item *) it, "elm.text.title", title_label);
1060 if ((!prev_btn) && wd->auto_pushed && eina_inlist_count(wd->stack))
1062 prev_btn = _back_btn_new(obj);
1063 _title_prev_btn_set(it, prev_btn, EINA_TRUE);
1066 _title_prev_btn_set(it, prev_btn, EINA_FALSE);
1068 _title_next_btn_set(it, next_btn);
1069 _item_content_set(it, content);
1070 it->title_visible = EINA_TRUE;
1075 _focus_next_hook(const Evas_Object *obj, Elm_Focus_Direction dir, Evas_Object **next)
1077 Widget_Data *wd = elm_widget_data_get(obj);
1078 if (!wd || !wd->stack) return EINA_FALSE;
1079 return elm_widget_focus_next_get(VIEW(elm_naviframe_top_item_get(obj)),
1085 elm_naviframe_add(Evas_Object *parent)
1091 ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL);
1092 ELM_SET_WIDTYPE(widtype, "naviframe");
1093 elm_widget_type_set(obj, "naviframe");
1094 elm_widget_sub_object_add(parent, obj);
1095 elm_widget_data_set(obj, wd);
1096 elm_widget_del_hook_set(obj, _del_hook);
1097 elm_widget_disable_hook_set(obj, _disable_hook);
1098 elm_widget_theme_hook_set(obj, _theme_hook);
1099 elm_widget_text_set_hook_set(obj, _text_set_hook);
1100 elm_widget_text_get_hook_set(obj, _text_get_hook);
1101 elm_widget_content_set_hook_set(obj, _content_set_hook);
1102 elm_widget_content_get_hook_set(obj, _content_get_hook);
1103 elm_widget_content_unset_hook_set(obj, _content_unset_hook);
1104 elm_widget_signal_emit_hook_set(obj, _emit_hook);
1105 elm_widget_can_focus_set(obj, EINA_FALSE);
1106 elm_widget_focus_next_hook_set(obj, _focus_next_hook);
1109 //FIXME: Is this base layout really needed?
1110 wd->base = elm_layout_add(parent);
1111 evas_object_event_callback_add(wd->base,
1112 EVAS_CALLBACK_CHANGED_SIZE_HINTS,
1113 _changed_size_hints,
1115 elm_widget_resize_object_set(obj, wd->base);
1116 elm_layout_theme_set(wd->base, "naviframe", "base", "default");
1118 evas_object_event_callback_add(obj, EVAS_CALLBACK_MOVE, _move, obj);
1119 evas_object_event_callback_add(obj, EVAS_CALLBACK_RESIZE, _resize, obj);
1120 evas_object_smart_callbacks_descriptions_set(obj, _signals);
1122 wd->auto_pushed = EINA_TRUE;
1123 wd->freeze_events = EINA_TRUE;
1124 wd->item_style = eina_stringshare_add("basic");
1129 EAPI Elm_Object_Item *
1130 elm_naviframe_item_push(Evas_Object *obj,
1131 const char *title_label,
1132 Evas_Object *prev_btn,
1133 Evas_Object *next_btn,
1134 Evas_Object *content,
1135 const char *item_style)
1137 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1139 Elm_Naviframe_Item *prev_it, *it;
1141 wd = elm_widget_data_get(obj);
1142 if (!wd) return NULL;
1144 it = _item_new(obj, title_label, prev_btn, next_btn, content, item_style);
1145 if (!it) return NULL;
1147 evas_object_show(VIEW(it));
1149 prev_it = (Elm_Naviframe_Item *) elm_naviframe_top_item_get(obj);
1152 if (wd->freeze_events)
1154 evas_object_freeze_events_set(VIEW(it), EINA_TRUE);
1155 evas_object_freeze_events_set(VIEW(prev_it), EINA_TRUE);
1157 elm_object_signal_emit(VIEW(prev_it), "elm,state,cur,pushed", "elm");
1158 elm_object_signal_emit(VIEW(it), "elm,state,new,pushed", "elm");
1159 edje_object_message_signal_process(elm_layout_edje_get(VIEW(prev_it)));
1160 edje_object_message_signal_process(elm_layout_edje_get(VIEW(it)));
1162 wd->stack = eina_inlist_append(wd->stack, EINA_INLIST_GET(it));
1164 return (Elm_Object_Item *) it;
1167 EAPI Elm_Object_Item *
1168 elm_naviframe_item_insert_before(Elm_Object_Item *before,
1169 const char *title_label,
1170 Evas_Object *prev_btn,
1171 Evas_Object *next_btn,
1172 Evas_Object *content,
1173 const char *item_style)
1175 ELM_OBJ_ITEM_CHECK_OR_RETURN(before, NULL);
1176 Elm_Naviframe_Item *it;
1179 wd = elm_widget_data_get(WIDGET(before));
1180 if (!wd) return NULL;
1182 it = _item_new(WIDGET(before), title_label, prev_btn, next_btn, content,
1184 if (!it) return NULL;
1187 eina_inlist_prepend_relative(wd->stack, EINA_INLIST_GET(it),
1188 EINA_INLIST_GET(((Elm_Naviframe_Item *) before)));
1189 _sizing_eval(WIDGET(before));
1190 return (Elm_Object_Item *) it;
1193 EAPI Elm_Object_Item *
1194 elm_naviframe_item_insert_after(Elm_Object_Item *after,
1195 const char *title_label,
1196 Evas_Object *prev_btn,
1197 Evas_Object *next_btn,
1198 Evas_Object *content,
1199 const char *item_style)
1201 ELM_OBJ_ITEM_CHECK_OR_RETURN(after, NULL);
1202 Elm_Naviframe_Item *it;
1205 wd = elm_widget_data_get(WIDGET(after));
1206 if (!wd) return NULL;
1208 it = _item_new(WIDGET(after), title_label, prev_btn, next_btn, content,
1210 if (!it) return NULL;
1212 if (elm_naviframe_top_item_get(WIDGET(after)) == after)
1214 evas_object_hide(VIEW(after));
1215 evas_object_show(VIEW(it));
1218 eina_inlist_append_relative(wd->stack, EINA_INLIST_GET(it),
1219 EINA_INLIST_GET(((Elm_Naviframe_Item *) after)));
1220 _sizing_eval(WIDGET(after));
1221 return (Elm_Object_Item *) it;
1225 elm_naviframe_item_pop(Evas_Object *obj)
1227 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1228 Elm_Naviframe_Item *it, *prev_it = NULL;
1230 Evas_Object *content = NULL;
1232 wd = elm_widget_data_get(obj);
1233 if (!wd) return NULL;
1235 it = (Elm_Naviframe_Item *) elm_naviframe_top_item_get(obj);
1236 if (!it) return NULL;
1237 elm_widget_tree_unfocusable_set(it->content, EINA_TRUE);
1239 content = it->content;
1241 if (wd->stack->last->prev)
1242 prev_it = EINA_INLIST_CONTAINER_GET(wd->stack->last->prev,
1243 Elm_Naviframe_Item);
1244 wd->stack = eina_inlist_remove(wd->stack, EINA_INLIST_GET(it));
1247 if (wd->freeze_events)
1249 evas_object_freeze_events_set(VIEW(it), EINA_TRUE);
1250 evas_object_freeze_events_set(VIEW(prev_it), EINA_TRUE);
1252 elm_object_signal_emit(VIEW(it), "elm,state,cur,popped", "elm");
1253 evas_object_show(VIEW(prev_it));
1254 evas_object_raise(VIEW(prev_it));
1255 elm_object_signal_emit(VIEW(prev_it),
1256 "elm,state,prev,popped",
1258 edje_object_message_signal_process(elm_layout_edje_get(VIEW(it)));
1259 edje_object_message_signal_process(elm_layout_edje_get(VIEW(prev_it)));
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 wd->stack = eina_inlist_demote(wd->stack, EINA_INLIST_GET(navi_it));
1314 prev_it = EINA_INLIST_CONTAINER_GET(wd->stack->last->prev,
1315 Elm_Naviframe_Item);
1316 if (wd->freeze_events)
1318 evas_object_freeze_events_set(VIEW(it), EINA_TRUE);
1319 evas_object_freeze_events_set(VIEW(prev_it), EINA_TRUE);
1321 elm_object_signal_emit(VIEW(prev_it),
1322 "elm,state,cur,pushed",
1324 evas_object_show(VIEW(navi_it));
1325 evas_object_raise(VIEW(navi_it));
1326 elm_object_signal_emit(VIEW(navi_it),
1327 "elm,state,new,pushed",
1329 edje_object_message_signal_process(elm_layout_edje_get(VIEW(prev_it)));
1330 edje_object_message_signal_process(elm_layout_edje_get(VIEW(navi_it)));
1334 elm_naviframe_item_simple_promote(Evas_Object *obj, Evas_Object *content)
1336 ELM_CHECK_WIDTYPE(obj, widtype);
1337 Widget_Data *wd = elm_widget_data_get(obj);
1339 Elm_Naviframe_Item *itr;
1340 EINA_INLIST_FOREACH(wd->stack, itr)
1342 if (elm_object_item_content_get((Elm_Object_Item *) itr) == content)
1344 elm_naviframe_item_promote((Elm_Object_Item *) itr);
1352 elm_naviframe_item_del(Elm_Object_Item *it)
1354 elm_object_item_del(it);
1358 elm_naviframe_content_preserve_on_pop_set(Evas_Object *obj, Eina_Bool preserve)
1360 ELM_CHECK_WIDTYPE(obj, widtype);
1361 Widget_Data *wd = elm_widget_data_get(obj);
1363 wd->preserve = !!preserve;
1367 elm_naviframe_content_preserve_on_pop_get(const Evas_Object *obj)
1369 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
1370 Widget_Data *wd = elm_widget_data_get(obj);
1371 if (!wd) return EINA_FALSE;
1372 return wd->preserve;
1375 EAPI Elm_Object_Item*
1376 elm_naviframe_top_item_get(const Evas_Object *obj)
1378 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1379 Widget_Data *wd = elm_widget_data_get(obj);
1380 if ((!wd) || (!wd->stack)) return NULL;
1381 return (Elm_Object_Item *) (EINA_INLIST_CONTAINER_GET(wd->stack->last,
1382 Elm_Naviframe_Item));
1385 EAPI Elm_Object_Item*
1386 elm_naviframe_bottom_item_get(const Evas_Object *obj)
1388 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1389 Widget_Data *wd = elm_widget_data_get(obj);
1390 if ((!wd) || (!wd->stack)) return NULL;
1391 return (Elm_Object_Item *) (EINA_INLIST_CONTAINER_GET(wd->stack,
1392 Elm_Naviframe_Item));
1396 elm_naviframe_item_style_set(Elm_Object_Item *it, const char *item_style)
1398 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1399 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
1401 //Return if new style is exsiting one.
1402 if ((item_style && navi_it->style) && (!strcmp(item_style, navi_it->style)))
1405 if ((!item_style) && (!navi_it->style))
1408 _item_style_set(navi_it, item_style);
1412 elm_naviframe_item_style_get(const Elm_Object_Item *it)
1414 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
1415 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
1416 return navi_it->style;
1420 elm_naviframe_item_title_visible_set(Elm_Object_Item *it, Eina_Bool visible)
1422 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1423 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
1425 visible = !!visible;
1426 if (navi_it->title_visible == visible) return;
1428 navi_it->title_visible = visible;
1429 _item_title_visible_update(navi_it);
1433 elm_naviframe_item_title_visible_get(const Elm_Object_Item *it)
1435 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
1436 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
1437 return navi_it->title_visible;
1441 elm_naviframe_prev_btn_auto_pushed_set(Evas_Object *obj, Eina_Bool auto_pushed)
1443 ELM_CHECK_WIDTYPE(obj, widtype);
1444 Widget_Data *wd = elm_widget_data_get(obj);
1446 wd->auto_pushed = !!auto_pushed;
1450 elm_naviframe_prev_btn_auto_pushed_get(const Evas_Object *obj)
1452 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
1453 Widget_Data *wd = elm_widget_data_get(obj);
1454 if (!wd) return EINA_FALSE;
1455 return wd->auto_pushed;
1459 elm_naviframe_items_get(const Evas_Object *obj)
1461 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1462 Widget_Data *wd = elm_widget_data_get(obj);
1463 if (!wd) return NULL;
1464 Eina_List *ret = NULL;
1465 Elm_Naviframe_Item *itr;
1466 EINA_INLIST_FOREACH(wd->stack, itr)
1468 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;