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;
18 struct _Elm_Naviframe_Content_Item_Pair
23 Elm_Naviframe_Item *it;
26 struct _Elm_Naviframe_Text_Item_Pair
33 struct _Elm_Naviframe_Item
37 Eina_Inlist *content_list;
38 Eina_Inlist *text_list;
40 Evas_Object *title_prev_btn;
41 Evas_Object *title_next_btn;
42 Evas_Object *title_icon;
44 Eina_Bool back_btn: 1;
45 Eina_Bool title_visible: 1;
48 static const char *widtype = NULL;
50 static const char SIG_TRANSITION_FINISHED[] = "transition,finished";
51 static const char SIG_PUSH_FINISHED[] = "push,finished";
52 static const char SIG_POP_FINISHED[] = "pop,finished";
53 static const char SIG_TITLE_CLICKED[] = "title,clicked";
55 static const Evas_Smart_Cb_Description _signals[] = {
56 {SIG_TRANSITION_FINISHED, ""},
57 {SIG_TITLE_CLICKED, ""},
61 static void _del_hook(Evas_Object *obj);
62 static void _theme_hook(Evas_Object *obj);
63 static void _emit_hook(Evas_Object *obj,
66 static void _disable_hook(Evas_Object *obj);
67 static void _mirrored_set(Evas_Object *obj, Eina_Bool rtl);
68 static void _item_text_set_hook(Elm_Object_Item *it,
71 static const char *_item_text_get_hook(const Elm_Object_Item *it,
73 static void _item_content_set_hook(Elm_Object_Item *it,
75 Evas_Object *content);
76 static Evas_Object *_item_content_get_hook(const Elm_Object_Item *it,
78 static Evas_Object *_item_content_unset_hook(Elm_Object_Item *it,
80 static void _item_signal_emit_hook(Elm_Object_Item *it,
83 static void _item_title_visible_update(Elm_Naviframe_Item *navi_it);
84 static void _sizing_eval(Evas_Object *obj);
85 static void _item_sizing_eval(Elm_Naviframe_Item *it);
86 static void _move(void *data, Evas *e, Evas_Object *obj, void *event_info);
87 static void _resize(void *data,
91 static void _title_clicked(void *data, Evas_Object *obj,
94 static void _back_btn_clicked(void *data,
97 static Evas_Object *_back_btn_new(Evas_Object *obj);
98 static void _item_content_del(void *data,
102 static void _title_content_del(void *data,
106 static void _title_prev_btn_del(void *data,
110 static void _title_next_btn_del(void *data,
114 static void _title_icon_del(void *data,
118 static void _title_content_set(Elm_Naviframe_Item *it,
120 Evas_Object *content);
121 static void _title_prev_btn_set(Elm_Naviframe_Item *it,
124 static void _title_next_btn_set(Elm_Naviframe_Item *it, Evas_Object *btn);
125 static void _title_icon_set(Elm_Naviframe_Item *it, Evas_Object *icon);
126 static Evas_Object * _item_content_unset(Elm_Naviframe_Item *it);
127 static Evas_Object * _title_prev_btn_unset(Elm_Naviframe_Item *it);
128 static Evas_Object * _title_next_btn_unset(Elm_Naviframe_Item *it);
129 static Evas_Object * _title_icon_unset(Elm_Naviframe_Item *it);
130 static Evas_Object * _title_content_unset(Elm_Naviframe_Item *it,
132 static void _item_del(Elm_Naviframe_Item *it);
133 static void _pushed_finished(void *data,
135 const char *emission,
137 static void _popped_finished(void *data,
139 const char *emission,
141 static void _show_finished(void *data,
143 const char *emission,
145 static void _changed_size_hints(void *data,
149 static void _item_content_set(Elm_Naviframe_Item *navi_it,
150 Evas_Object *content);
151 static void _item_style_set(Elm_Naviframe_Item *navi_it,
152 const char *item_style);
153 static Elm_Naviframe_Item * _item_new(Evas_Object *obj,
154 const char *title_label,
155 Evas_Object *prev_btn,
156 Evas_Object *next_btn,
157 Evas_Object *content,
158 const char *item_style);
161 _del_hook(Evas_Object *obj)
164 Elm_Naviframe_Item *it;
166 wd = elm_widget_data_get(obj);
171 while (wd->stack->last)
173 it = EINA_INLIST_CONTAINER_GET(wd->stack->last,
175 wd->stack = eina_inlist_remove(wd->stack, wd->stack->last);
177 if (!wd->stack) break;
184 _theme_hook(Evas_Object *obj)
187 Elm_Naviframe_Item *it;
189 wd = elm_widget_data_get(obj);
192 _elm_theme_object_set(obj,
196 elm_widget_style_get(obj));
198 EINA_INLIST_FOREACH(wd->stack, it)
200 _item_style_set(it, it->style);
201 _item_title_visible_update(it);
204 _elm_widget_mirrored_reload(obj);
205 _mirrored_set(obj, elm_widget_mirrored_get(obj));
208 static void _emit_hook(Evas_Object *obj,
209 const char *emission,
212 ELM_CHECK_WIDTYPE(obj, widtype);
214 Widget_Data *wd = elm_widget_data_get(obj);
217 edje_object_signal_emit(wd->base, emission, source);
221 _disable_hook(Evas_Object *obj __UNUSED__)
227 _mirrored_set(Evas_Object *obj, Eina_Bool rtl)
230 Elm_Naviframe_Item *it;
232 wd = elm_widget_data_get(obj);
235 EINA_INLIST_FOREACH(wd->stack, it)
236 edje_object_mirrored_set(VIEW(it), rtl);
237 edje_object_mirrored_set(wd->base, rtl);
241 _item_text_set_hook(Elm_Object_Item *it,
245 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
247 Elm_Naviframe_Text_Item_Pair *pair = NULL;
248 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
251 if (!part || !strcmp(part, "default"))
252 snprintf(buf, sizeof(buf), "elm.text.title");
253 else if(!strcmp("subtitle", part))
254 snprintf(buf, sizeof(buf), "elm.text.subtitle");
256 snprintf(buf, sizeof(buf), "%s", part);
258 EINA_INLIST_FOREACH(navi_it->text_list, pair)
259 if (!strcmp(buf, pair->part)) break;
263 pair = ELM_NEW(Elm_Naviframe_Text_Item_Pair);
266 ERR("Failed to allocate new text part of the item! : naviframe=%p",
270 eina_stringshare_replace(&pair->part, buf);
271 navi_it->text_list = eina_inlist_append(navi_it->text_list,
272 EINA_INLIST_GET(pair));
275 eina_stringshare_replace(&pair->text, label);
276 edje_object_part_text_set(VIEW(navi_it), buf, label);
280 snprintf(buf, sizeof(buf), "elm,state,%s,show", buf);
281 edje_object_signal_emit(VIEW(navi_it), buf, "elm");
285 snprintf(buf, sizeof(buf), "elm,state,%s,hide", buf);
286 edje_object_signal_emit(VIEW(navi_it), buf, "elm");
289 _sizing_eval(WIDGET(navi_it));
293 _item_text_get_hook(const Elm_Object_Item *it, const char *part)
295 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
296 Elm_Naviframe_Text_Item_Pair *pair = NULL;
297 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
300 if (!part || !strcmp(part, "default"))
301 snprintf(buf, sizeof(buf), "elm.text.title");
302 else if(!strcmp("subtitle", part))
303 snprintf(buf, sizeof(buf), "elm.text.subtitle");
305 snprintf(buf, sizeof(buf), "%s", part);
307 EINA_INLIST_FOREACH(navi_it->text_list, pair)
309 if (!strcmp(buf, pair->part))
316 _item_content_set_hook(Elm_Object_Item *it,
318 Evas_Object *content)
320 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
322 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
325 if ((!part) || (!strcmp(part, "elm.swallow.content")))
327 _item_content_set(navi_it, content);
330 else if (!strcmp(part, "elm.swallow.prev_btn"))
332 _title_prev_btn_set(navi_it, content, EINA_FALSE);
335 else if (!strcmp(part, "elm.swallow.next_btn"))
337 _title_next_btn_set(navi_it, content);
340 else if (!strcmp(part, "icon"))
342 _title_icon_set(navi_it, content);
347 _title_content_set(navi_it, part, content);
351 _item_content_get_hook(const Elm_Object_Item *it, const char *part)
353 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
354 Elm_Naviframe_Content_Item_Pair *pair = NULL;
355 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
358 if ((!part) || (!strcmp(part, "elm.swallow.content")))
359 return navi_it->content;
360 else if (!strcmp(part, "elm.swallow.prev_btn"))
361 return navi_it->title_prev_btn;
362 else if (!strcmp(part, "elm.swallow.next_btn"))
363 return navi_it->title_next_btn;
364 else if (!strcmp(part, "icon"))
365 return navi_it->title_icon;
368 EINA_INLIST_FOREACH(navi_it->content_list, pair)
370 if (!strcmp(part, pair->part))
371 return pair->content;
377 _item_content_unset_hook(Elm_Object_Item *it, const char *part)
379 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
380 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
383 if (!part || !strcmp("elm.swallow.content", part))
384 return _item_content_unset(navi_it);
385 else if (!strcmp(part, "elm.swallow.prev_btn"))
386 return _title_prev_btn_unset(navi_it);
387 else if (!strcmp(part, "elm.swallow.next_btn"))
388 return _title_next_btn_unset(navi_it);
389 else if (!strcmp(part, "icon"))
390 return _title_icon_unset(navi_it);
392 return _title_content_unset(navi_it, part);
396 _item_signal_emit_hook(Elm_Object_Item *it,
397 const char *emission,
400 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
401 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
402 edje_object_signal_emit(VIEW(navi_it), emission, source);
406 _item_title_visible_update(Elm_Naviframe_Item *navi_it)
408 if (navi_it->title_visible)
409 edje_object_signal_emit(VIEW(navi_it), "elm,state,title,show", "elm");
411 edje_object_signal_emit(VIEW(navi_it), "elm,state,title,hide", "elm");
415 _sizing_eval(Evas_Object *obj)
418 Elm_Naviframe_Item *it;
419 wd = elm_widget_data_get(obj);
422 EINA_INLIST_FOREACH(wd->stack, it)
423 _item_sizing_eval(it);
427 _item_sizing_eval(Elm_Naviframe_Item *it)
430 Evas_Coord x, y, w, h;
433 wd = elm_widget_data_get(WIDGET(it));
436 evas_object_geometry_get(WIDGET(it), &x, &y, &w, &h);
437 evas_object_move(VIEW(it), x, y);
438 evas_object_resize(VIEW(it), w, h);
442 _move(void *data __UNUSED__,
445 void *event_info __UNUSED__)
451 _resize(void *data __UNUSED__,
454 void *event_info __UNUSED__)
460 _title_clicked(void *data,
461 Evas_Object *obj __UNUSED__,
462 const char *emission __UNUSED__,
463 const char *source __UNUSED__)
465 Elm_Naviframe_Item *it = data;
466 evas_object_smart_callback_call(WIDGET(it), SIG_TITLE_CLICKED, it);
470 _back_btn_clicked(void *data,
472 void *event_info __UNUSED__)
474 /* Since edje has the event queue, clicked event could be happend multiple times
475 on some heavy environment. This callback del will prevent those scenario and
476 guarantee only one clicked for it's own page. */
477 evas_object_smart_callback_del(obj, "clicked", _back_btn_clicked);
478 elm_naviframe_item_pop(data);
482 _back_btn_new(Evas_Object *obj)
486 btn = elm_button_add(obj);
487 if (!btn) return NULL;
488 evas_object_smart_callback_add(btn, "clicked", _back_btn_clicked, obj);
489 snprintf(buf, sizeof(buf), "naviframe/back_btn/%s", elm_widget_style_get(obj));
490 elm_object_style_set(btn, buf);
495 _title_content_del(void *data,
497 Evas_Object *obj __UNUSED__,
498 void *event_info __UNUSED__)
501 Elm_Naviframe_Content_Item_Pair *pair = data;
502 Elm_Naviframe_Item *it = pair->it;
503 snprintf(buf, sizeof(buf), "elm,state,%s,hide", pair->part);
504 edje_object_signal_emit(VIEW(it), buf, "elm");
505 it->content_list = eina_inlist_remove(it->content_list,
506 EINA_INLIST_GET(pair));
507 eina_stringshare_del(pair->part);
512 _title_prev_btn_del(void *data,
514 Evas_Object *obj __UNUSED__,
515 void *event_info __UNUSED__)
517 Elm_Naviframe_Item *it = data;
518 it->back_btn = EINA_FALSE;
519 it->title_prev_btn = NULL;
520 edje_object_signal_emit(VIEW(it), "elm,state,prev_btn,hide", "elm");
524 _title_next_btn_del(void *data,
526 Evas_Object *obj __UNUSED__,
527 void *event_info __UNUSED__)
529 Elm_Naviframe_Item *it = data;
530 it->title_next_btn = NULL;
531 edje_object_signal_emit(VIEW(it), "elm,state,next_btn,hide", "elm");
535 _title_icon_del(void *data,
537 Evas_Object *obj __UNUSED__,
538 void *event_info __UNUSED__)
540 Elm_Naviframe_Item *it = data;
541 it->title_icon = NULL;
542 edje_object_signal_emit(VIEW(it), "elm,state,icon,hide", "elm");
546 _item_content_del(void *data,
548 Evas_Object *obj __UNUSED__,
549 void *event_info __UNUSED__)
551 Elm_Naviframe_Item *it = data;
553 edje_object_signal_emit(VIEW(it), "elm,state,content,hide", "elm");
557 _title_content_set(Elm_Naviframe_Item *it,
559 Evas_Object *content)
562 Elm_Naviframe_Content_Item_Pair *pair = NULL;
564 EINA_INLIST_FOREACH(it->content_list, pair)
565 if (!strcmp(part, pair->part)) break;
569 if (pair->content != content)
573 evas_object_event_callback_del(pair->content,
576 evas_object_event_callback_del(pair->content,
577 EVAS_CALLBACK_CHANGED_SIZE_HINTS,
578 _changed_size_hints);
579 snprintf(buf, sizeof(buf), "elm,state,%s,hide", part);
580 edje_object_signal_emit(VIEW(it), buf, "elm");
582 evas_object_del(pair->content);
583 if (!content) return;
588 if (!content) return;
589 pair = ELM_NEW(Elm_Naviframe_Content_Item_Pair);
592 ERR("Failed to allocate new content part of the item! : naviframe=%p", WIDGET(it));
596 eina_stringshare_replace(&pair->part, part);
597 it->content_list = eina_inlist_append(it->content_list,
598 EINA_INLIST_GET(pair));
600 if (pair->content != content)
602 elm_widget_sub_object_add(WIDGET(it), content);
603 evas_object_event_callback_add(content,
607 evas_object_event_callback_add(content,
608 EVAS_CALLBACK_CHANGED_SIZE_HINTS,
612 edje_object_part_swallow(VIEW(it), part, content);
613 snprintf(buf, sizeof(buf), "elm,state,%s,show", part);
614 edje_object_signal_emit(VIEW(it), buf, "elm");
615 pair->content = content;
617 _sizing_eval(WIDGET(it));
621 _title_prev_btn_set(Elm_Naviframe_Item *it,
625 if (it->title_prev_btn == btn) return;
627 if (it->title_prev_btn)
628 evas_object_del(it->title_prev_btn);
630 it->title_prev_btn = btn;
633 elm_widget_sub_object_add(WIDGET(it), btn);
634 evas_object_event_callback_add(btn,
638 evas_object_event_callback_add(btn,
639 EVAS_CALLBACK_CHANGED_SIZE_HINTS,
642 edje_object_part_swallow(VIEW(it), "elm.swallow.prev_btn", btn);
643 edje_object_signal_emit(VIEW(it), "elm,state,prev_btn,show", "elm");
644 it->back_btn = back_btn;
646 _sizing_eval(WIDGET(it));
650 _title_next_btn_set(Elm_Naviframe_Item *it, Evas_Object *btn)
652 if (it->title_next_btn == btn) return;
654 if (it->title_next_btn)
655 evas_object_del(it->title_next_btn);
657 it->title_next_btn = btn;
660 elm_widget_sub_object_add(WIDGET(it), btn);
661 evas_object_event_callback_add(btn,
665 evas_object_event_callback_add(btn,
666 EVAS_CALLBACK_CHANGED_SIZE_HINTS,
669 edje_object_part_swallow(VIEW(it), "elm.swallow.next_btn", btn);
670 edje_object_signal_emit(VIEW(it), "elm,state,next_btn,show", "elm");
672 _sizing_eval(WIDGET(it));
676 _title_icon_set(Elm_Naviframe_Item *it, Evas_Object *icon)
678 if (it->title_icon == icon) return;
681 evas_object_del(it->title_icon);
683 it->title_icon = icon;
686 elm_widget_sub_object_add(WIDGET(it), icon);
687 evas_object_event_callback_add(icon,
691 evas_object_event_callback_add(icon,
692 EVAS_CALLBACK_CHANGED_SIZE_HINTS,
695 edje_object_part_swallow(VIEW(it), "elm.swallow.icon", icon);
696 edje_object_signal_emit(VIEW(it), "elm,state,icon,show", "elm");
698 _sizing_eval(WIDGET(it));
702 _item_content_unset(Elm_Naviframe_Item *it)
704 Evas_Object *content = it->content;
705 if (!content) return NULL;
707 elm_widget_sub_object_del(WIDGET(it), content);
708 edje_object_part_unswallow(VIEW(it), content);
709 edje_object_signal_emit(VIEW(it), "elm,state,content,hide", "elm");
710 evas_object_event_callback_del(content,
713 evas_object_event_callback_del(content,
714 EVAS_CALLBACK_CHANGED_SIZE_HINTS,
715 _changed_size_hints);
716 _sizing_eval(WIDGET(it));
723 _title_prev_btn_unset(Elm_Naviframe_Item *it)
725 Evas_Object *content = it->title_prev_btn;
726 if (!content) return NULL;
728 elm_widget_sub_object_del(WIDGET(it), content);
729 edje_object_part_unswallow(VIEW(it), content);
730 edje_object_signal_emit(VIEW(it), "elm,state,prev_btn,hide", "elm");
731 evas_object_event_callback_del(content,
733 _title_prev_btn_del);
734 evas_object_event_callback_del(content,
735 EVAS_CALLBACK_CHANGED_SIZE_HINTS,
736 _changed_size_hints);
737 _sizing_eval(WIDGET(it));
739 it->title_prev_btn = NULL;
744 _title_next_btn_unset(Elm_Naviframe_Item *it)
746 Evas_Object *content = it->title_next_btn;
747 if (!content) return NULL;
749 elm_widget_sub_object_del(WIDGET(it), content);
750 edje_object_part_unswallow(VIEW(it), content);
751 edje_object_signal_emit(VIEW(it), "elm,state,next_btn,hide", "elm");
752 evas_object_event_callback_del(content,
754 _title_next_btn_del);
755 evas_object_event_callback_del(content,
756 EVAS_CALLBACK_CHANGED_SIZE_HINTS,
757 _changed_size_hints);
758 _sizing_eval(WIDGET(it));
760 it->title_next_btn = NULL;
765 _title_icon_unset(Elm_Naviframe_Item *it)
767 Evas_Object *content = it->title_icon;
768 if (!content) return NULL;
770 elm_widget_sub_object_del(WIDGET(it), content);
771 edje_object_part_unswallow(VIEW(it), content);
772 edje_object_signal_emit(VIEW(it), "elm,state,icon,hide", "elm");
773 evas_object_event_callback_del(content,
776 evas_object_event_callback_del(content,
777 EVAS_CALLBACK_CHANGED_SIZE_HINTS,
778 _changed_size_hints);
779 _sizing_eval(WIDGET(it));
780 it->title_icon = NULL;
786 _title_content_unset(Elm_Naviframe_Item *it, const char *part)
788 Elm_Naviframe_Content_Item_Pair *pair = NULL;
790 Evas_Object *content = NULL;
792 EINA_INLIST_FOREACH(it->content_list, pair)
794 if (!strcmp(part, pair->part))
796 content = pair->content;
797 eina_stringshare_del(pair->part);
798 it->content_list = eina_inlist_remove(it->content_list,
799 EINA_INLIST_GET(pair));
805 if (!content) return NULL;
807 elm_widget_sub_object_del(WIDGET(it), content);
808 edje_object_part_unswallow(VIEW(it), content);
809 snprintf(buf, sizeof(buf), "elm,state,%s,hide", part);
810 edje_object_signal_emit(VIEW(it), buf, "elm");
811 evas_object_event_callback_del(content,
814 evas_object_event_callback_del(content,
815 EVAS_CALLBACK_CHANGED_SIZE_HINTS,
816 _changed_size_hints);
817 _sizing_eval(WIDGET(it));
823 _item_del(Elm_Naviframe_Item *it)
826 Elm_Naviframe_Content_Item_Pair *content_pair;
827 Elm_Naviframe_Text_Item_Pair *text_pair;
831 wd = elm_widget_data_get(WIDGET(it));
834 if (it->title_prev_btn)
835 evas_object_del(it->title_prev_btn);
836 if (it->title_next_btn)
837 evas_object_del(it->title_next_btn);
839 evas_object_del(it->title_icon);
840 if ((it->content) && (!wd->preserve))
841 evas_object_del(it->content);
843 while (it->content_list)
845 content_pair = EINA_INLIST_CONTAINER_GET(it->content_list,
846 Elm_Naviframe_Content_Item_Pair);
847 evas_object_event_callback_del(content_pair->content,
850 evas_object_event_callback_del(content_pair->content,
851 EVAS_CALLBACK_CHANGED_SIZE_HINTS,
852 _changed_size_hints);
853 evas_object_del(content_pair->content);
854 eina_stringshare_del(content_pair->part);
855 it->content_list = eina_inlist_remove(it->content_list,
860 while (it->text_list)
862 text_pair = EINA_INLIST_CONTAINER_GET(it->text_list,
863 Elm_Naviframe_Text_Item_Pair);
864 eina_stringshare_del(text_pair->part);
865 eina_stringshare_del(text_pair->text);
866 it->text_list = eina_inlist_remove(it->text_list,
871 eina_stringshare_del(it->style);
873 elm_widget_item_del(it);
877 _pushed_finished(void *data,
878 Evas_Object *obj __UNUSED__,
879 const char *emission __UNUSED__,
880 const char *source __UNUSED__)
883 Elm_Naviframe_Item *it = data;
886 wd = elm_widget_data_get(WIDGET(it));
889 evas_object_hide(VIEW(it));
890 evas_object_smart_callback_call(WIDGET(it),
893 if (wd->freeze_events)
894 evas_object_freeze_events_set(VIEW(it), EINA_FALSE);
898 _popped_finished(void *data,
899 Evas_Object *obj __UNUSED__,
900 const char *emission __UNUSED__,
901 const char *source __UNUSED__)
903 Elm_Naviframe_Item *it = data;
905 evas_object_smart_callback_call(WIDGET(it),
912 _show_finished(void *data,
913 Evas_Object *obj __UNUSED__,
914 const char *emission __UNUSED__,
915 const char *source __UNUSED__)
917 Elm_Naviframe_Item *it;
922 wd = elm_widget_data_get(WIDGET(it));
925 evas_object_smart_callback_call(WIDGET(it),
926 SIG_TRANSITION_FINISHED,
928 if (wd->freeze_events)
929 evas_object_freeze_events_set(VIEW(it), EINA_FALSE);
933 _changed_size_hints(void *data,
935 Evas_Object *obj __UNUSED__,
936 void *event_info __UNUSED__)
942 _item_content_set(Elm_Naviframe_Item *navi_it, Evas_Object *content)
944 if (navi_it->content == content) return;
945 if (navi_it->content) evas_object_del(navi_it->content);
946 elm_widget_sub_object_add(WIDGET(navi_it), content);
947 edje_object_part_swallow(VIEW(navi_it),
948 "elm.swallow.content",
951 edje_object_signal_emit(VIEW(navi_it),
952 "elm,state,content,show",
955 edje_object_signal_emit(VIEW(navi_it),
956 "elm,state,content,hide",
958 evas_object_event_callback_add(content,
962 evas_object_event_callback_add(content,
963 EVAS_CALLBACK_CHANGED_SIZE_HINTS,
966 navi_it->content = content;
967 _sizing_eval(WIDGET(navi_it));
970 //FIXME: need to handle if this function is called while transition
972 _item_style_set(Elm_Naviframe_Item *navi_it, const char *item_style)
974 Elm_Naviframe_Content_Item_Pair *content_pair;
975 Elm_Naviframe_Text_Item_Pair *text_pair;
982 sprintf(buf, "item/basic");
983 eina_stringshare_replace(&navi_it->style, "basic");
987 if (strlen(item_style) > sizeof(buf))
988 WRN("too much long style name! : naviframe=%p", WIDGET(navi_it));
989 sprintf(buf, "item/%s", item_style);
990 eina_stringshare_replace(&navi_it->style, item_style);
992 _elm_theme_object_set(WIDGET(navi_it),
996 elm_widget_style_get(WIDGET(navi_it)));
998 EINA_INLIST_FOREACH(navi_it->text_list, text_pair)
999 _item_text_set_hook((Elm_Object_Item *) navi_it,
1003 EINA_INLIST_FOREACH(navi_it->content_list, content_pair)
1004 _item_content_set_hook((Elm_Object_Item *) navi_it,
1006 content_pair->content);
1008 if (navi_it->content)
1010 edje_object_part_swallow(VIEW(navi_it),
1011 "elm.swallow.content",
1013 edje_object_signal_emit(VIEW(navi_it),
1014 "elm,state,content,show",
1019 if (navi_it->title_prev_btn)
1021 edje_object_part_swallow(VIEW(navi_it),
1022 "elm.swallow.prev_btn",
1023 navi_it->title_prev_btn);
1024 edje_object_signal_emit(VIEW(navi_it),
1025 "elm,state,prev_btn,show",
1030 if (navi_it->title_next_btn)
1032 edje_object_part_swallow(VIEW(navi_it),
1033 "elm.swallow.next_btn",
1034 navi_it->title_next_btn);
1035 edje_object_signal_emit(VIEW(navi_it),
1036 "elm,state,next_btn,show",
1040 navi_it->title_visible = EINA_TRUE;
1041 _sizing_eval(WIDGET(navi_it));
1043 wd = elm_widget_data_get(WIDGET(navi_it));
1046 if (wd->freeze_events)
1047 evas_object_freeze_events_set(VIEW(navi_it), EINA_FALSE);
1050 static Elm_Naviframe_Item *
1051 _item_new(Evas_Object *obj,
1052 const char *title_label,
1053 Evas_Object *prev_btn,
1054 Evas_Object *next_btn,
1055 Evas_Object *content,
1056 const char *item_style)
1058 Widget_Data *wd = elm_widget_data_get(obj);
1061 Elm_Naviframe_Item *it = elm_widget_item_new(obj, Elm_Naviframe_Item);
1064 ERR("Failed to allocate new item! : naviframe=%p", obj);
1068 elm_widget_item_text_set_hook_set(it, _item_text_set_hook);
1069 elm_widget_item_text_get_hook_set(it, _item_text_get_hook);
1070 elm_widget_item_content_set_hook_set(it, _item_content_set_hook);
1071 elm_widget_item_content_get_hook_set(it, _item_content_get_hook);
1072 elm_widget_item_content_unset_hook_set(it, _item_content_unset_hook);
1073 elm_widget_item_signal_emit_hook_set(it, _item_signal_emit_hook);
1076 VIEW(it) = edje_object_add(evas_object_evas_get(obj));
1077 edje_object_mirrored_set(VIEW(it), elm_widget_mirrored_get(obj));
1078 evas_object_smart_member_add(VIEW(it), wd->base);
1079 elm_widget_sub_object_add(obj, VIEW(it));
1080 edje_object_signal_callback_add(VIEW(it),
1081 "elm,action,show,finished",
1083 _show_finished, it);
1084 edje_object_signal_callback_add(VIEW(it),
1085 "elm,action,pushed,finished",
1087 _pushed_finished, it);
1088 edje_object_signal_callback_add(VIEW(it),
1089 "elm,action,popped,finished",
1091 _popped_finished, it);
1092 edje_object_signal_callback_add(VIEW(it),
1093 "elm,action,title,clicked",
1095 _title_clicked, it);
1097 _item_style_set(it, item_style);
1098 _item_text_set_hook((Elm_Object_Item *) it, "elm.text.title", title_label);
1101 if ((!prev_btn) && wd->auto_pushed && eina_inlist_count(wd->stack))
1103 prev_btn = _back_btn_new(obj);
1104 _title_prev_btn_set(it, prev_btn, EINA_TRUE);
1107 _title_prev_btn_set(it, prev_btn, EINA_FALSE);
1109 _title_next_btn_set(it, next_btn);
1110 _item_content_set(it, content);
1111 it->title_visible = EINA_TRUE;
1116 elm_naviframe_add(Evas_Object *parent)
1122 ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL);
1123 ELM_SET_WIDTYPE(widtype, "naviframe");
1124 elm_widget_type_set(obj, "naviframe");
1125 elm_widget_sub_object_add(parent, obj);
1126 elm_widget_data_set(obj, wd);
1127 elm_widget_del_hook_set(obj, _del_hook);
1128 elm_widget_disable_hook_set(obj, _disable_hook);
1129 elm_widget_theme_hook_set(obj, _theme_hook);
1130 elm_widget_signal_emit_hook_set(obj, _emit_hook);
1133 wd->base = edje_object_add(e);
1134 edje_object_mirrored_set(wd->base, elm_widget_mirrored_get(obj));
1135 elm_widget_resize_object_set(obj, wd->base);
1136 _elm_theme_object_set(obj, wd->base, "naviframe", "base", "default");
1138 evas_object_event_callback_add(obj, EVAS_CALLBACK_MOVE, _move, obj);
1139 evas_object_event_callback_add(obj, EVAS_CALLBACK_RESIZE, _resize, obj);
1140 evas_object_smart_callbacks_descriptions_set(obj, _signals);
1142 wd->auto_pushed = EINA_TRUE;
1143 wd->freeze_events = EINA_TRUE;
1148 EAPI Elm_Object_Item *
1149 elm_naviframe_item_push(Evas_Object *obj,
1150 const char *title_label,
1151 Evas_Object *prev_btn,
1152 Evas_Object *next_btn,
1153 Evas_Object *content,
1154 const char *item_style)
1156 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1158 Elm_Naviframe_Item *prev_it, *it;
1160 wd = elm_widget_data_get(obj);
1161 if (!wd) return NULL;
1163 it = _item_new(obj, title_label, prev_btn, next_btn, content, item_style);
1164 if (!it) return NULL;
1166 evas_object_show(VIEW(it));
1168 prev_it = (Elm_Naviframe_Item *) elm_naviframe_top_item_get(obj);
1171 if (wd->freeze_events)
1173 evas_object_freeze_events_set(VIEW(it), EINA_TRUE);
1174 evas_object_freeze_events_set(VIEW(prev_it), EINA_TRUE);
1176 edje_object_signal_emit(VIEW(prev_it),
1177 "elm,state,cur,pushed",
1179 edje_object_signal_emit(VIEW(it),
1180 "elm,state,new,pushed",
1182 edje_object_message_signal_process(VIEW(prev_it));
1183 edje_object_message_signal_process(VIEW(it));
1185 wd->stack = eina_inlist_append(wd->stack, EINA_INLIST_GET(it));
1187 return (Elm_Object_Item *) it;
1190 EAPI Elm_Object_Item *
1191 elm_naviframe_item_insert_before(Elm_Object_Item *before,
1192 const char *title_label,
1193 Evas_Object *prev_btn,
1194 Evas_Object *next_btn,
1195 Evas_Object *content,
1196 const char *item_style)
1198 ELM_OBJ_ITEM_CHECK_OR_RETURN(before, NULL);
1199 Elm_Naviframe_Item *it;
1202 wd = elm_widget_data_get(WIDGET(before));
1203 if (!wd) return NULL;
1205 it = _item_new(WIDGET(before), title_label, prev_btn, next_btn, content,
1207 if (!it) return NULL;
1210 eina_inlist_prepend_relative(wd->stack, EINA_INLIST_GET(it),
1211 EINA_INLIST_GET(((Elm_Naviframe_Item *) before)));
1212 _sizing_eval(WIDGET(before));
1213 return (Elm_Object_Item *) it;
1216 EAPI Elm_Object_Item *
1217 elm_naviframe_item_insert_after(Elm_Object_Item *after,
1218 const char *title_label,
1219 Evas_Object *prev_btn,
1220 Evas_Object *next_btn,
1221 Evas_Object *content,
1222 const char *item_style)
1224 ELM_OBJ_ITEM_CHECK_OR_RETURN(after, NULL);
1225 Elm_Naviframe_Item *it;
1228 wd = elm_widget_data_get(WIDGET(after));
1229 if (!wd) return NULL;
1231 it = _item_new(WIDGET(after), title_label, prev_btn, next_btn, content,
1233 if (!it) return NULL;
1235 if (elm_naviframe_top_item_get(WIDGET(after)) == after)
1237 evas_object_hide(VIEW(after));
1238 evas_object_show(VIEW(it));
1241 eina_inlist_append_relative(wd->stack, EINA_INLIST_GET(it),
1242 EINA_INLIST_GET(((Elm_Naviframe_Item *) after)));
1243 _sizing_eval(WIDGET(after));
1244 return (Elm_Object_Item *) it;
1248 elm_naviframe_item_pop(Evas_Object *obj)
1250 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1251 Elm_Naviframe_Item *it, *prev_it = NULL;
1253 Evas_Object *content = NULL;
1255 wd = elm_widget_data_get(obj);
1256 if (!wd) return NULL;
1258 it = (Elm_Naviframe_Item *) elm_naviframe_top_item_get(obj);
1259 if (!it) return NULL;
1260 elm_widget_tree_unfocusable_set(it->content, EINA_TRUE);
1262 content = it->content;
1264 if (wd->stack->last->prev)
1265 prev_it = EINA_INLIST_CONTAINER_GET(wd->stack->last->prev,
1266 Elm_Naviframe_Item);
1267 wd->stack = eina_inlist_remove(wd->stack, EINA_INLIST_GET(it));
1270 if (wd->freeze_events)
1272 evas_object_freeze_events_set(VIEW(it), EINA_TRUE);
1273 evas_object_freeze_events_set(VIEW(prev_it), EINA_TRUE);
1275 edje_object_signal_emit(VIEW(it), "elm,state,cur,popped", "elm");
1276 evas_object_show(VIEW(prev_it));
1277 evas_object_raise(VIEW(prev_it));
1278 edje_object_signal_emit(VIEW(prev_it),
1279 "elm,state,prev,popped",
1281 edje_object_message_signal_process(VIEW(it));
1282 edje_object_message_signal_process(VIEW(prev_it));
1291 elm_naviframe_item_pop_to(Elm_Object_Item *it)
1293 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1294 Elm_Naviframe_Item *navi_it;
1296 Eina_Inlist *l, *prev_l;
1298 navi_it = (Elm_Naviframe_Item *) it;
1299 wd = elm_widget_data_get(WIDGET(navi_it));
1302 if (it == elm_naviframe_top_item_get(WIDGET(navi_it))) return;
1304 l = wd->stack->last->prev;
1308 if (EINA_INLIST_CONTAINER_GET(l, Elm_Naviframe_Item) ==
1309 ((Elm_Naviframe_Item *) it)) break;
1311 wd->stack = eina_inlist_remove(wd->stack, l);
1312 _item_del(EINA_INLIST_CONTAINER_GET(l, Elm_Naviframe_Item));
1315 elm_naviframe_item_pop(WIDGET(navi_it));
1319 elm_naviframe_item_promote(Elm_Object_Item *it)
1321 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1322 Elm_Naviframe_Item *navi_it;
1323 Elm_Naviframe_Item *prev_it;
1326 navi_it = (Elm_Naviframe_Item *) it;
1327 wd = elm_widget_data_get(navi_it->base.widget);
1330 if (it == elm_naviframe_top_item_get(navi_it->base.widget)) return;
1331 wd->stack = eina_inlist_demote(wd->stack, EINA_INLIST_GET(navi_it));
1332 prev_it = EINA_INLIST_CONTAINER_GET(wd->stack->last->prev,
1333 Elm_Naviframe_Item);
1334 if (wd->freeze_events)
1336 evas_object_freeze_events_set(VIEW(it), EINA_TRUE);
1337 evas_object_freeze_events_set(VIEW(prev_it), EINA_TRUE);
1339 edje_object_signal_emit(VIEW(prev_it),
1340 "elm,state,cur,pushed",
1342 evas_object_show(VIEW(navi_it));
1343 evas_object_raise(VIEW(navi_it));
1344 edje_object_signal_emit(VIEW(navi_it),
1345 "elm,state,new,pushed",
1347 edje_object_message_signal_process(VIEW(prev_it));
1348 edje_object_message_signal_process(VIEW(navi_it));
1352 elm_naviframe_item_del(Elm_Object_Item *it)
1354 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1355 Elm_Naviframe_Item *navi_it;
1358 navi_it =(Elm_Naviframe_Item *) it;
1359 wd = elm_widget_data_get(WIDGET(navi_it));
1362 if (it == elm_naviframe_top_item_get(WIDGET(navi_it)))
1364 wd->stack = eina_inlist_remove(wd->stack, EINA_INLIST_GET(navi_it));
1366 //If the item is only one, the stack will be empty
1367 if (!wd->stack) return;
1368 navi_it = EINA_INLIST_CONTAINER_GET(wd->stack->last,
1369 Elm_Naviframe_Item);
1370 evas_object_show(VIEW(navi_it));
1371 evas_object_raise(VIEW(navi_it));
1372 edje_object_signal_emit(VIEW(navi_it), "elm,state,visible", "elm");
1376 wd->stack = eina_inlist_remove(wd->stack, EINA_INLIST_GET(navi_it));
1382 elm_naviframe_content_preserve_on_pop_set(Evas_Object *obj, Eina_Bool preserve)
1384 ELM_CHECK_WIDTYPE(obj, widtype);
1385 Widget_Data *wd = elm_widget_data_get(obj);
1387 wd->preserve = !!preserve;
1391 elm_naviframe_content_preserve_on_pop_get(const Evas_Object *obj)
1393 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
1394 Widget_Data *wd = elm_widget_data_get(obj);
1395 if (!wd) return EINA_FALSE;
1396 return wd->preserve;
1399 EAPI Elm_Object_Item*
1400 elm_naviframe_top_item_get(const Evas_Object *obj)
1402 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1403 Widget_Data *wd = elm_widget_data_get(obj);
1404 if ((!wd) || (!wd->stack)) return NULL;
1405 return (Elm_Object_Item *) (EINA_INLIST_CONTAINER_GET(wd->stack->last,
1406 Elm_Naviframe_Item));
1409 EAPI Elm_Object_Item*
1410 elm_naviframe_bottom_item_get(const Evas_Object *obj)
1412 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1413 Widget_Data *wd = elm_widget_data_get(obj);
1414 if ((!wd) || (!wd->stack)) return NULL;
1415 return (Elm_Object_Item *) (EINA_INLIST_CONTAINER_GET(wd->stack,
1416 Elm_Naviframe_Item));
1420 elm_naviframe_item_style_set(Elm_Object_Item *it, const char *item_style)
1422 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1423 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
1425 //Return if new style is exsiting one.
1427 if (!strcmp(item_style, navi_it->style)) return;
1430 if (!strcmp("basic", navi_it->style)) return;
1432 _item_style_set(navi_it, item_style);
1436 elm_naviframe_item_style_get(const Elm_Object_Item *it)
1438 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
1439 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
1440 return navi_it->style;
1444 elm_naviframe_item_title_visible_set(Elm_Object_Item *it, Eina_Bool visible)
1446 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1447 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
1449 visible = !!visible;
1450 if (navi_it->title_visible == visible) return;
1452 navi_it->title_visible = visible;
1453 _item_title_visible_update(navi_it);
1457 elm_naviframe_item_title_visible_get(const Elm_Object_Item *it)
1459 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
1460 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
1461 return navi_it->title_visible;
1465 elm_naviframe_prev_btn_auto_pushed_set(Evas_Object *obj, Eina_Bool auto_pushed)
1467 ELM_CHECK_WIDTYPE(obj, widtype);
1468 Widget_Data *wd = elm_widget_data_get(obj);
1470 wd->auto_pushed = !!auto_pushed;
1474 elm_naviframe_prev_btn_auto_pushed_get(const Evas_Object *obj)
1476 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
1477 Widget_Data *wd = elm_widget_data_get(obj);
1478 if (!wd) return EINA_FALSE;
1479 return wd->auto_pushed;
1483 elm_naviframe_items_get(const Evas_Object *obj)
1485 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1486 Widget_Data *wd = elm_widget_data_get(obj);
1487 if (!wd) return NULL;
1492 elm_naviframe_event_enabled_set(Evas_Object *obj, Eina_Bool enabled)
1494 ELM_CHECK_WIDTYPE(obj, widtype);
1495 Widget_Data *wd = elm_widget_data_get(obj);
1497 enabled = !!enabled;
1498 if (wd->freeze_events == !enabled) return;
1499 wd->freeze_events = !enabled;
1503 elm_naviframe_event_enabled_get(const Evas_Object *obj)
1505 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
1506 Widget_Data *wd = elm_widget_data_get(obj);
1507 if (!wd) return EINA_FALSE;
1508 return !wd->freeze_events;