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;
46 Eina_Bool back_btn: 1;
47 Eina_Bool title_visible: 1;
50 static const char *widtype = NULL;
52 static const char SIG_TRANSITION_FINISHED[] = "transition,finished";
53 static const char SIG_PUSH_FINISHED[] = "push,finished";
54 static const char SIG_POP_FINISHED[] = "pop,finished";
55 static const char SIG_TITLE_CLICKED[] = "title,clicked";
57 static const Evas_Smart_Cb_Description _signals[] = {
58 {SIG_TRANSITION_FINISHED, ""},
59 {SIG_TITLE_CLICKED, ""},
63 static void _del_hook(Evas_Object *obj);
64 static void _theme_hook(Evas_Object *obj);
65 static void _emit_hook(Evas_Object *obj,
68 static void _disable_hook(Evas_Object *obj);
69 static void _mirrored_set(Evas_Object *obj, Eina_Bool rtl);
70 static void _item_text_set_hook(Elm_Object_Item *it,
73 static const char *_item_text_get_hook(const Elm_Object_Item *it,
75 static void _item_content_set_hook(Elm_Object_Item *it,
77 Evas_Object *content);
78 static Evas_Object *_item_content_get_hook(const Elm_Object_Item *it,
80 static Evas_Object *_item_content_unset_hook(Elm_Object_Item *it,
82 static void _item_signal_emit_hook(Elm_Object_Item *it,
85 static void _item_title_visible_update(Elm_Naviframe_Item *navi_it);
86 static void _sizing_eval(Evas_Object *obj);
87 static void _move(void *data, Evas *e, Evas_Object *obj, void *event_info);
88 static void _resize(void *data,
92 static void _title_clicked(void *data, Evas_Object *obj,
95 static void _back_btn_clicked(void *data,
98 static Evas_Object *_back_btn_new(Evas_Object *obj);
99 static void _item_content_del(void *data,
103 static void _title_content_del(void *data,
107 static void _title_prev_btn_del(void *data,
111 static void _title_next_btn_del(void *data,
115 static void _title_icon_del(void *data,
119 static void _title_content_set(Elm_Naviframe_Item *it,
121 Evas_Object *content);
122 static void _title_prev_btn_set(Elm_Naviframe_Item *it,
125 static void _title_next_btn_set(Elm_Naviframe_Item *it, Evas_Object *btn);
126 static void _title_icon_set(Elm_Naviframe_Item *it, Evas_Object *icon);
127 static Evas_Object * _item_content_unset(Elm_Naviframe_Item *it);
128 static Evas_Object * _title_prev_btn_unset(Elm_Naviframe_Item *it);
129 static Evas_Object * _title_next_btn_unset(Elm_Naviframe_Item *it);
130 static Evas_Object * _title_icon_unset(Elm_Naviframe_Item *it);
131 static Evas_Object * _title_content_unset(Elm_Naviframe_Item *it,
133 static void _item_del(Elm_Naviframe_Item *it);
134 static void _pushed_finished(void *data,
136 const char *emission,
138 static void _popped_finished(void *data,
140 const char *emission,
142 static void _show_finished(void *data,
144 const char *emission,
146 static void _changed_size_hints(void *data,
150 static void _item_content_set(Elm_Naviframe_Item *navi_it,
151 Evas_Object *content);
152 static void _item_style_set(Elm_Naviframe_Item *navi_it,
153 const char *item_style);
154 static Elm_Naviframe_Item * _item_new(Evas_Object *obj,
155 const char *title_label,
156 Evas_Object *prev_btn,
157 Evas_Object *next_btn,
158 Evas_Object *content,
159 const char *item_style);
162 _del_hook(Evas_Object *obj)
165 Elm_Naviframe_Item *it;
167 wd = elm_widget_data_get(obj);
172 while (wd->stack->last)
174 it = EINA_INLIST_CONTAINER_GET(wd->stack->last,
176 wd->stack = eina_inlist_remove(wd->stack, wd->stack->last);
178 if (!wd->stack) break;
185 _theme_hook(Evas_Object *obj)
188 Elm_Naviframe_Item *it;
190 wd = elm_widget_data_get(obj);
193 _elm_theme_object_set(obj,
197 elm_widget_style_get(obj));
199 EINA_INLIST_FOREACH(wd->stack, it)
201 _item_style_set(it, it->style);
202 _item_title_visible_update(it);
205 _elm_widget_mirrored_reload(obj);
206 _mirrored_set(obj, elm_widget_mirrored_get(obj));
209 static void _emit_hook(Evas_Object *obj,
210 const char *emission,
213 ELM_CHECK_WIDTYPE(obj, widtype);
215 Widget_Data *wd = elm_widget_data_get(obj);
218 edje_object_signal_emit(wd->base, emission, source);
222 _disable_hook(Evas_Object *obj __UNUSED__)
228 _mirrored_set(Evas_Object *obj, Eina_Bool rtl)
231 Elm_Naviframe_Item *it;
233 wd = elm_widget_data_get(obj);
236 EINA_INLIST_FOREACH(wd->stack, it)
237 edje_object_mirrored_set(VIEW(it), rtl);
238 edje_object_mirrored_set(wd->base, rtl);
242 _item_text_set_hook(Elm_Object_Item *it,
246 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
248 Elm_Naviframe_Text_Item_Pair *pair = NULL;
249 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
252 if (!part || !strcmp(part, "default"))
253 snprintf(buf, sizeof(buf), "elm.text.title");
254 else if(!strcmp("subtitle", part))
255 snprintf(buf, sizeof(buf), "elm.text.subtitle");
257 snprintf(buf, sizeof(buf), "%s", part);
259 EINA_INLIST_FOREACH(navi_it->text_list, pair)
260 if (!strcmp(buf, pair->part)) break;
264 pair = ELM_NEW(Elm_Naviframe_Text_Item_Pair);
267 ERR("Failed to allocate new text part of the item! : naviframe=%p",
271 eina_stringshare_replace(&pair->part, buf);
272 navi_it->text_list = eina_inlist_append(navi_it->text_list,
273 EINA_INLIST_GET(pair));
276 eina_stringshare_replace(&pair->text, label);
277 edje_object_part_text_set(VIEW(navi_it), buf, label);
281 snprintf(buf, sizeof(buf), "elm,state,%s,show", buf);
282 edje_object_signal_emit(VIEW(navi_it), buf, "elm");
286 snprintf(buf, sizeof(buf), "elm,state,%s,hide", buf);
287 edje_object_signal_emit(VIEW(navi_it), buf, "elm");
290 _sizing_eval(WIDGET(navi_it));
294 _item_text_get_hook(const Elm_Object_Item *it, const char *part)
296 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
297 Elm_Naviframe_Text_Item_Pair *pair = NULL;
298 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
301 if (!part || !strcmp(part, "default"))
302 snprintf(buf, sizeof(buf), "elm.text.title");
303 else if(!strcmp("subtitle", part))
304 snprintf(buf, sizeof(buf), "elm.text.subtitle");
306 snprintf(buf, sizeof(buf), "%s", part);
308 EINA_INLIST_FOREACH(navi_it->text_list, pair)
310 if (!strcmp(buf, pair->part))
317 _item_content_set_hook(Elm_Object_Item *it,
319 Evas_Object *content)
321 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
323 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
326 if (!part || !strcmp("default", part))
328 _item_content_set(navi_it, content);
331 else if (!strcmp(part, "prev_btn"))
333 _title_prev_btn_set(navi_it, content, EINA_FALSE);
336 else if (!strcmp(part, "next_btn"))
338 _title_next_btn_set(navi_it, content);
341 else if (!strcmp(part, "icon"))
343 _title_icon_set(navi_it, content);
348 _title_content_set(navi_it, part, content);
352 _item_content_get_hook(const Elm_Object_Item *it, const char *part)
354 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
355 Elm_Naviframe_Content_Item_Pair *pair = NULL;
356 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
359 if (!part || !strcmp("default", part))
360 return navi_it->content;
361 else if (!strcmp(part, "prev_btn"))
362 return navi_it->title_prev_btn;
363 else if (!strcmp(part, "next_btn"))
364 return navi_it->title_next_btn;
365 else if (!strcmp(part, "icon"))
366 return navi_it->title_icon;
369 EINA_INLIST_FOREACH(navi_it->content_list, pair)
371 if (!strcmp(part, pair->part))
372 return pair->content;
378 _item_content_unset_hook(Elm_Object_Item *it, const char *part)
380 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
381 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
384 if (!part || !strcmp("default", part))
385 return _item_content_unset(navi_it);
386 else if (!strcmp(part, "prev_btn"))
387 return _title_prev_btn_unset(navi_it);
388 else if (!strcmp(part, "next_btn"))
389 return _title_next_btn_unset(navi_it);
390 else if (!strcmp(part, "icon"))
391 return _title_icon_unset(navi_it);
393 return _title_content_unset(navi_it, part);
397 _item_signal_emit_hook(Elm_Object_Item *it,
398 const char *emission,
401 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
402 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
403 edje_object_signal_emit(VIEW(navi_it), emission, source);
407 _item_title_visible_update(Elm_Naviframe_Item *navi_it)
409 if (navi_it->title_visible)
410 edje_object_signal_emit(VIEW(navi_it), "elm,state,title,show", "elm");
412 edje_object_signal_emit(VIEW(navi_it), "elm,state,title,hide", "elm");
416 _sizing_eval(Evas_Object *obj)
419 Elm_Naviframe_Item *it;
420 Evas_Coord x, y, w, h;
421 Evas_Coord minw = -1, minh = -1;
423 wd = elm_widget_data_get(obj);
426 EINA_INLIST_FOREACH(wd->stack, it)
428 evas_object_geometry_get(WIDGET(it), &x, &y, &w, &h);
429 evas_object_move(VIEW(it), x, y);
430 evas_object_resize(VIEW(it), w, h);
431 edje_object_size_min_calc(VIEW(it), &it->minw, &it->minh);
432 if (it->minw > minw) minw = it->minw;
433 if (it->minh > minh) minh = it->minh;
435 evas_object_size_hint_min_set(obj, minw, minh);
436 evas_object_size_hint_max_set(obj, -1, -1);
440 _move(void *data __UNUSED__,
443 void *event_info __UNUSED__)
449 _resize(void *data __UNUSED__,
452 void *event_info __UNUSED__)
458 _title_clicked(void *data,
459 Evas_Object *obj __UNUSED__,
460 const char *emission __UNUSED__,
461 const char *source __UNUSED__)
463 Elm_Naviframe_Item *it = data;
464 evas_object_smart_callback_call(WIDGET(it), SIG_TITLE_CLICKED, it);
468 _back_btn_clicked(void *data,
470 void *event_info __UNUSED__)
472 /* Since edje has the event queue, clicked event could be happend multiple times
473 on some heavy environment. This callback del will prevent those scenario and
474 guarantee only one clicked for it's own page. */
475 evas_object_smart_callback_del(obj, "clicked", _back_btn_clicked);
476 elm_naviframe_item_pop(data);
480 _back_btn_new(Evas_Object *obj)
484 btn = elm_button_add(obj);
485 if (!btn) return NULL;
486 evas_object_smart_callback_add(btn, "clicked", _back_btn_clicked, obj);
487 snprintf(buf, sizeof(buf), "naviframe/back_btn/%s", elm_widget_style_get(obj));
488 elm_object_style_set(btn, buf);
493 _title_content_del(void *data,
495 Evas_Object *obj __UNUSED__,
496 void *event_info __UNUSED__)
499 Elm_Naviframe_Content_Item_Pair *pair = data;
500 Elm_Naviframe_Item *it = pair->it;
501 snprintf(buf, sizeof(buf), "elm,state,%s,hide", pair->part);
502 edje_object_signal_emit(VIEW(it), buf, "elm");
503 it->content_list = eina_inlist_remove(it->content_list,
504 EINA_INLIST_GET(pair));
505 eina_stringshare_del(pair->part);
510 _title_prev_btn_del(void *data,
512 Evas_Object *obj __UNUSED__,
513 void *event_info __UNUSED__)
515 Elm_Naviframe_Item *it = data;
516 it->back_btn = EINA_FALSE;
517 it->title_prev_btn = NULL;
518 edje_object_signal_emit(VIEW(it), "elm,state,prev_btn,hide", "elm");
522 _title_next_btn_del(void *data,
524 Evas_Object *obj __UNUSED__,
525 void *event_info __UNUSED__)
527 Elm_Naviframe_Item *it = data;
528 it->title_next_btn = NULL;
529 edje_object_signal_emit(VIEW(it), "elm,state,next_btn,hide", "elm");
533 _title_icon_del(void *data,
535 Evas_Object *obj __UNUSED__,
536 void *event_info __UNUSED__)
538 Elm_Naviframe_Item *it = data;
539 it->title_icon = NULL;
540 edje_object_signal_emit(VIEW(it), "elm,state,icon,hide", "elm");
544 _item_content_del(void *data,
546 Evas_Object *obj __UNUSED__,
547 void *event_info __UNUSED__)
549 Elm_Naviframe_Item *it = data;
551 edje_object_signal_emit(VIEW(it), "elm,state,content,hide", "elm");
555 _title_content_set(Elm_Naviframe_Item *it,
557 Evas_Object *content)
560 Elm_Naviframe_Content_Item_Pair *pair = NULL;
562 EINA_INLIST_FOREACH(it->content_list, pair)
563 if (!strcmp(part, pair->part)) break;
567 if (pair->content && (pair->content != content))
571 evas_object_event_callback_del(pair->content,
574 evas_object_event_callback_del(pair->content,
575 EVAS_CALLBACK_CHANGED_SIZE_HINTS,
576 _changed_size_hints);
577 snprintf(buf, sizeof(buf), "elm,state,%s,hide", part);
578 edje_object_signal_emit(VIEW(it), buf, "elm");
580 evas_object_del(pair->content);
581 if (!content) return;
586 if (!content) return;
587 pair = ELM_NEW(Elm_Naviframe_Content_Item_Pair);
590 ERR("Failed to allocate new content part of the item! : naviframe=%p", WIDGET(it));
594 eina_stringshare_replace(&pair->part, part);
595 it->content_list = eina_inlist_append(it->content_list,
596 EINA_INLIST_GET(pair));
597 elm_widget_sub_object_add(WIDGET(it), content);
598 evas_object_event_callback_add(content,
602 evas_object_event_callback_add(content,
603 EVAS_CALLBACK_CHANGED_SIZE_HINTS,
607 edje_object_part_swallow(VIEW(it), part, content);
608 snprintf(buf, sizeof(buf), "elm,state,%s,show", part);
609 edje_object_signal_emit(VIEW(it), buf, "elm");
610 pair->content = content;
612 _sizing_eval(WIDGET(it));
616 _title_prev_btn_set(Elm_Naviframe_Item *it,
620 if (it->title_prev_btn == btn) return;
622 if (it->title_prev_btn)
623 evas_object_del(it->title_prev_btn);
625 it->title_prev_btn = btn;
628 elm_widget_sub_object_add(WIDGET(it), btn);
629 evas_object_event_callback_add(btn,
633 evas_object_event_callback_add(btn,
634 EVAS_CALLBACK_CHANGED_SIZE_HINTS,
637 edje_object_part_swallow(VIEW(it), "elm.swallow.prev_btn", btn);
638 edje_object_signal_emit(VIEW(it), "elm,state,prev_btn,show", "elm");
639 it->back_btn = back_btn;
641 _sizing_eval(WIDGET(it));
645 _title_next_btn_set(Elm_Naviframe_Item *it, Evas_Object *btn)
647 if (it->title_next_btn == btn) return;
649 if (it->title_next_btn)
650 evas_object_del(it->title_next_btn);
652 it->title_next_btn = btn;
655 elm_widget_sub_object_add(WIDGET(it), btn);
656 evas_object_event_callback_add(btn,
660 evas_object_event_callback_add(btn,
661 EVAS_CALLBACK_CHANGED_SIZE_HINTS,
664 edje_object_part_swallow(VIEW(it), "elm.swallow.next_btn", btn);
665 edje_object_signal_emit(VIEW(it), "elm,state,next_btn,show", "elm");
667 _sizing_eval(WIDGET(it));
671 _title_icon_set(Elm_Naviframe_Item *it, Evas_Object *icon)
673 if (it->title_icon == icon) return;
676 evas_object_del(it->title_icon);
678 it->title_icon = icon;
681 elm_widget_sub_object_add(WIDGET(it), icon);
682 evas_object_event_callback_add(icon,
686 evas_object_event_callback_add(icon,
687 EVAS_CALLBACK_CHANGED_SIZE_HINTS,
690 edje_object_part_swallow(VIEW(it), "elm.swallow.icon", icon);
691 edje_object_signal_emit(VIEW(it), "elm,state,icon,show", "elm");
693 _sizing_eval(WIDGET(it));
697 _item_content_unset(Elm_Naviframe_Item *it)
699 Evas_Object *content = it->content;
700 if (!content) return NULL;
702 elm_widget_sub_object_del(WIDGET(it), content);
703 edje_object_part_unswallow(VIEW(it), content);
704 edje_object_signal_emit(VIEW(it), "elm,state,content,hide", "elm");
705 evas_object_event_callback_del(content,
708 evas_object_event_callback_del(content,
709 EVAS_CALLBACK_CHANGED_SIZE_HINTS,
710 _changed_size_hints);
711 _sizing_eval(WIDGET(it));
718 _title_prev_btn_unset(Elm_Naviframe_Item *it)
720 Evas_Object *content = it->title_prev_btn;
721 if (!content) return NULL;
723 elm_widget_sub_object_del(WIDGET(it), content);
724 edje_object_part_unswallow(VIEW(it), content);
725 edje_object_signal_emit(VIEW(it), "elm,state,prev_btn,hide", "elm");
726 evas_object_event_callback_del(content,
728 _title_prev_btn_del);
729 evas_object_event_callback_del(content,
730 EVAS_CALLBACK_CHANGED_SIZE_HINTS,
731 _changed_size_hints);
732 _sizing_eval(WIDGET(it));
734 it->title_prev_btn = NULL;
739 _title_next_btn_unset(Elm_Naviframe_Item *it)
741 Evas_Object *content = it->title_next_btn;
742 if (!content) return NULL;
744 elm_widget_sub_object_del(WIDGET(it), content);
745 edje_object_part_unswallow(VIEW(it), content);
746 edje_object_signal_emit(VIEW(it), "elm,state,next_btn,hide", "elm");
747 evas_object_event_callback_del(content,
749 _title_next_btn_del);
750 evas_object_event_callback_del(content,
751 EVAS_CALLBACK_CHANGED_SIZE_HINTS,
752 _changed_size_hints);
753 _sizing_eval(WIDGET(it));
755 it->title_next_btn = NULL;
760 _title_icon_unset(Elm_Naviframe_Item *it)
762 Evas_Object *content = it->title_icon;
763 if (!content) return NULL;
765 elm_widget_sub_object_del(WIDGET(it), content);
766 edje_object_part_unswallow(VIEW(it), content);
767 edje_object_signal_emit(VIEW(it), "elm,state,icon,hide", "elm");
768 evas_object_event_callback_del(content,
771 evas_object_event_callback_del(content,
772 EVAS_CALLBACK_CHANGED_SIZE_HINTS,
773 _changed_size_hints);
774 _sizing_eval(WIDGET(it));
775 it->title_icon = NULL;
781 _title_content_unset(Elm_Naviframe_Item *it, const char *part)
783 Elm_Naviframe_Content_Item_Pair *pair = NULL;
785 Evas_Object *content = NULL;
787 EINA_INLIST_FOREACH(it->content_list, pair)
789 if (!strcmp(part, pair->part))
791 content = pair->content;
792 eina_stringshare_del(pair->part);
793 it->content_list = eina_inlist_remove(it->content_list,
794 EINA_INLIST_GET(pair));
800 if (!content) return NULL;
802 elm_widget_sub_object_del(WIDGET(it), content);
803 edje_object_part_unswallow(VIEW(it), content);
804 snprintf(buf, sizeof(buf), "elm,state,%s,hide", part);
805 edje_object_signal_emit(VIEW(it), buf, "elm");
806 evas_object_event_callback_del(content,
809 evas_object_event_callback_del(content,
810 EVAS_CALLBACK_CHANGED_SIZE_HINTS,
811 _changed_size_hints);
812 _sizing_eval(WIDGET(it));
819 _item_del(Elm_Naviframe_Item *it)
822 Elm_Naviframe_Content_Item_Pair *content_pair;
823 Elm_Naviframe_Text_Item_Pair *text_pair;
827 wd = elm_widget_data_get(WIDGET(it));
830 if (it->title_prev_btn)
831 evas_object_del(it->title_prev_btn);
832 if (it->title_next_btn)
833 evas_object_del(it->title_next_btn);
835 evas_object_del(it->title_icon);
836 if ((it->content) && (!wd->preserve))
837 evas_object_del(it->content);
839 while (it->content_list)
841 content_pair = EINA_INLIST_CONTAINER_GET(it->content_list,
842 Elm_Naviframe_Content_Item_Pair);
843 evas_object_event_callback_del(content_pair->content,
846 evas_object_event_callback_del(content_pair->content,
847 EVAS_CALLBACK_CHANGED_SIZE_HINTS,
848 _changed_size_hints);
849 evas_object_del(content_pair->content);
850 eina_stringshare_del(content_pair->part);
851 it->content_list = eina_inlist_remove(it->content_list,
856 while (it->text_list)
858 text_pair = EINA_INLIST_CONTAINER_GET(it->text_list,
859 Elm_Naviframe_Text_Item_Pair);
860 eina_stringshare_del(text_pair->part);
861 eina_stringshare_del(text_pair->text);
862 it->text_list = eina_inlist_remove(it->text_list,
867 eina_stringshare_del(it->style);
869 elm_widget_item_del(it);
873 _pushed_finished(void *data,
874 Evas_Object *obj __UNUSED__,
875 const char *emission __UNUSED__,
876 const char *source __UNUSED__)
879 Elm_Naviframe_Item *it = data;
882 wd = elm_widget_data_get(WIDGET(it));
885 evas_object_hide(VIEW(it));
886 evas_object_smart_callback_call(WIDGET(it),
889 if (wd->freeze_events)
890 evas_object_freeze_events_set(VIEW(it), EINA_FALSE);
894 _popped_finished(void *data,
895 Evas_Object *obj __UNUSED__,
896 const char *emission __UNUSED__,
897 const char *source __UNUSED__)
899 Elm_Naviframe_Item *it = data;
901 evas_object_smart_callback_call(WIDGET(it),
908 _show_finished(void *data,
909 Evas_Object *obj __UNUSED__,
910 const char *emission __UNUSED__,
911 const char *source __UNUSED__)
913 Elm_Naviframe_Item *it;
918 wd = elm_widget_data_get(WIDGET(it));
921 evas_object_smart_callback_call(WIDGET(it),
922 SIG_TRANSITION_FINISHED,
924 if (wd->freeze_events)
925 evas_object_freeze_events_set(VIEW(it), EINA_FALSE);
929 _changed_size_hints(void *data,
931 Evas_Object *obj __UNUSED__,
932 void *event_info __UNUSED__)
938 _item_content_set(Elm_Naviframe_Item *navi_it, Evas_Object *content)
940 if (navi_it->content == content) return;
941 if (navi_it->content) evas_object_del(navi_it->content);
942 elm_widget_sub_object_add(WIDGET(navi_it), content);
943 edje_object_part_swallow(VIEW(navi_it),
944 "elm.swallow.content",
947 edje_object_signal_emit(VIEW(navi_it),
948 "elm,state,content,show",
951 edje_object_signal_emit(VIEW(navi_it),
952 "elm,state,content,hide",
954 evas_object_event_callback_add(content,
958 evas_object_event_callback_add(content,
959 EVAS_CALLBACK_CHANGED_SIZE_HINTS,
962 navi_it->content = content;
963 _sizing_eval(WIDGET(navi_it));
966 //FIXME: need to handle if this function is called while transition
968 _item_style_set(Elm_Naviframe_Item *navi_it, const char *item_style)
970 Elm_Naviframe_Content_Item_Pair *content_pair;
971 Elm_Naviframe_Text_Item_Pair *text_pair;
978 sprintf(buf, "item/basic");
979 eina_stringshare_replace(&navi_it->style, "basic");
983 if (strlen(item_style) > sizeof(buf))
984 WRN("too much long style name! : naviframe=%p", WIDGET(navi_it));
985 sprintf(buf, "item/%s", item_style);
986 eina_stringshare_replace(&navi_it->style, item_style);
988 _elm_theme_object_set(WIDGET(navi_it),
992 elm_widget_style_get(WIDGET(navi_it)));
994 EINA_INLIST_FOREACH(navi_it->text_list, text_pair)
995 _item_text_set_hook((Elm_Object_Item *) navi_it,
999 EINA_INLIST_FOREACH(navi_it->content_list, content_pair)
1000 _item_content_set_hook((Elm_Object_Item *) navi_it,
1002 content_pair->content);
1004 if (navi_it->content)
1006 edje_object_part_swallow(VIEW(navi_it),
1007 "elm.swallow.content",
1009 edje_object_signal_emit(VIEW(navi_it),
1010 "elm,state,content,show",
1015 if (navi_it->title_prev_btn)
1017 edje_object_part_swallow(VIEW(navi_it),
1018 "elm.swallow.prev_btn",
1019 navi_it->title_prev_btn);
1020 edje_object_signal_emit(VIEW(navi_it),
1021 "elm,state,prev_btn,show",
1026 if (navi_it->title_next_btn)
1028 edje_object_part_swallow(VIEW(navi_it),
1029 "elm.swallow.next_btn",
1030 navi_it->title_next_btn);
1031 edje_object_signal_emit(VIEW(navi_it),
1032 "elm,state,next_btn,show",
1036 navi_it->title_visible = EINA_TRUE;
1037 _sizing_eval(WIDGET(navi_it));
1039 wd = elm_widget_data_get(WIDGET(navi_it));
1042 if (wd->freeze_events)
1043 evas_object_freeze_events_set(VIEW(navi_it), EINA_FALSE);
1046 static Elm_Naviframe_Item *
1047 _item_new(Evas_Object *obj,
1048 const char *title_label,
1049 Evas_Object *prev_btn,
1050 Evas_Object *next_btn,
1051 Evas_Object *content,
1052 const char *item_style)
1054 Widget_Data *wd = elm_widget_data_get(obj);
1057 Elm_Naviframe_Item *it = elm_widget_item_new(obj, Elm_Naviframe_Item);
1060 ERR("Failed to allocate new item! : naviframe=%p", obj);
1064 elm_widget_item_text_set_hook_set(it, _item_text_set_hook);
1065 elm_widget_item_text_get_hook_set(it, _item_text_get_hook);
1066 elm_widget_item_content_set_hook_set(it, _item_content_set_hook);
1067 elm_widget_item_content_get_hook_set(it, _item_content_get_hook);
1068 elm_widget_item_content_unset_hook_set(it, _item_content_unset_hook);
1069 elm_widget_item_signal_emit_hook_set(it, _item_signal_emit_hook);
1072 VIEW(it) = edje_object_add(evas_object_evas_get(obj));
1073 edje_object_mirrored_set(VIEW(it), elm_widget_mirrored_get(obj));
1074 evas_object_smart_member_add(VIEW(it), wd->base);
1075 elm_widget_sub_object_add(obj, VIEW(it));
1076 edje_object_signal_callback_add(VIEW(it),
1077 "elm,action,show,finished",
1079 _show_finished, it);
1080 edje_object_signal_callback_add(VIEW(it),
1081 "elm,action,pushed,finished",
1083 _pushed_finished, it);
1084 edje_object_signal_callback_add(VIEW(it),
1085 "elm,action,popped,finished",
1087 _popped_finished, it);
1088 edje_object_signal_callback_add(VIEW(it),
1089 "elm,action,title,clicked",
1091 _title_clicked, it);
1093 _item_style_set(it, item_style);
1094 _item_text_set_hook((Elm_Object_Item *) it, "elm.text.title", title_label);
1097 if ((!prev_btn) && wd->auto_pushed && eina_inlist_count(wd->stack))
1099 prev_btn = _back_btn_new(obj);
1100 _title_prev_btn_set(it, prev_btn, EINA_TRUE);
1103 _title_prev_btn_set(it, prev_btn, EINA_FALSE);
1105 _title_next_btn_set(it, next_btn);
1106 _item_content_set(it, content);
1107 it->title_visible = EINA_TRUE;
1112 elm_naviframe_add(Evas_Object *parent)
1118 ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL);
1119 ELM_SET_WIDTYPE(widtype, "naviframe");
1120 elm_widget_type_set(obj, "naviframe");
1121 elm_widget_sub_object_add(parent, obj);
1122 elm_widget_data_set(obj, wd);
1123 elm_widget_del_hook_set(obj, _del_hook);
1124 elm_widget_disable_hook_set(obj, _disable_hook);
1125 elm_widget_theme_hook_set(obj, _theme_hook);
1126 elm_widget_signal_emit_hook_set(obj, _emit_hook);
1129 wd->base = edje_object_add(e);
1130 edje_object_mirrored_set(wd->base, elm_widget_mirrored_get(obj));
1131 elm_widget_resize_object_set(obj, wd->base);
1132 _elm_theme_object_set(obj, wd->base, "naviframe", "base", "default");
1134 evas_object_event_callback_add(obj, EVAS_CALLBACK_MOVE, _move, obj);
1135 evas_object_event_callback_add(obj, EVAS_CALLBACK_RESIZE, _resize, obj);
1136 evas_object_smart_callbacks_descriptions_set(obj, _signals);
1138 wd->auto_pushed = EINA_TRUE;
1139 wd->freeze_events = EINA_TRUE;
1144 EAPI Elm_Object_Item *
1145 elm_naviframe_item_push(Evas_Object *obj,
1146 const char *title_label,
1147 Evas_Object *prev_btn,
1148 Evas_Object *next_btn,
1149 Evas_Object *content,
1150 const char *item_style)
1152 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1154 Elm_Naviframe_Item *prev_it, *it;
1156 wd = elm_widget_data_get(obj);
1157 if (!wd) return NULL;
1159 it = _item_new(obj, title_label, prev_btn, next_btn, content, item_style);
1160 if (!it) return NULL;
1162 evas_object_show(VIEW(it));
1164 prev_it = (Elm_Naviframe_Item *) elm_naviframe_top_item_get(obj);
1167 if (wd->freeze_events)
1169 evas_object_freeze_events_set(VIEW(it), EINA_TRUE);
1170 evas_object_freeze_events_set(VIEW(prev_it), EINA_TRUE);
1172 edje_object_signal_emit(VIEW(prev_it),
1173 "elm,state,cur,pushed",
1175 edje_object_signal_emit(VIEW(it),
1176 "elm,state,new,pushed",
1178 edje_object_message_signal_process(VIEW(prev_it));
1179 edje_object_message_signal_process(VIEW(it));
1181 wd->stack = eina_inlist_append(wd->stack, EINA_INLIST_GET(it));
1183 return (Elm_Object_Item *) it;
1186 EAPI Elm_Object_Item *
1187 elm_naviframe_item_insert_before(Elm_Object_Item *before,
1188 const char *title_label,
1189 Evas_Object *prev_btn,
1190 Evas_Object *next_btn,
1191 Evas_Object *content,
1192 const char *item_style)
1194 ELM_OBJ_ITEM_CHECK_OR_RETURN(before, NULL);
1195 Elm_Naviframe_Item *it;
1198 wd = elm_widget_data_get(WIDGET(before));
1199 if (!wd) return NULL;
1201 it = _item_new(WIDGET(before), title_label, prev_btn, next_btn, content,
1203 if (!it) return NULL;
1206 eina_inlist_prepend_relative(wd->stack, EINA_INLIST_GET(it),
1207 EINA_INLIST_GET(((Elm_Naviframe_Item *) before)));
1208 _sizing_eval(WIDGET(before));
1209 return (Elm_Object_Item *) it;
1212 EAPI Elm_Object_Item *
1213 elm_naviframe_item_insert_after(Elm_Object_Item *after,
1214 const char *title_label,
1215 Evas_Object *prev_btn,
1216 Evas_Object *next_btn,
1217 Evas_Object *content,
1218 const char *item_style)
1220 ELM_OBJ_ITEM_CHECK_OR_RETURN(after, NULL);
1221 Elm_Naviframe_Item *it;
1224 wd = elm_widget_data_get(WIDGET(after));
1225 if (!wd) return NULL;
1227 it = _item_new(WIDGET(after), title_label, prev_btn, next_btn, content,
1229 if (!it) return NULL;
1231 if (elm_naviframe_top_item_get(WIDGET(after)) == after)
1233 evas_object_hide(VIEW(after));
1234 evas_object_show(VIEW(it));
1237 eina_inlist_append_relative(wd->stack, EINA_INLIST_GET(it),
1238 EINA_INLIST_GET(((Elm_Naviframe_Item *) after)));
1239 _sizing_eval(WIDGET(after));
1240 return (Elm_Object_Item *) it;
1244 elm_naviframe_item_pop(Evas_Object *obj)
1246 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1247 Elm_Naviframe_Item *it, *prev_it = NULL;
1249 Evas_Object *content = NULL;
1251 wd = elm_widget_data_get(obj);
1252 if (!wd) return NULL;
1254 it = (Elm_Naviframe_Item *) elm_naviframe_top_item_get(obj);
1255 if (!it) return NULL;
1256 elm_widget_tree_unfocusable_set(it->content, EINA_TRUE);
1258 content = it->content;
1260 if (wd->stack->last->prev)
1261 prev_it = EINA_INLIST_CONTAINER_GET(wd->stack->last->prev,
1262 Elm_Naviframe_Item);
1263 wd->stack = eina_inlist_remove(wd->stack, EINA_INLIST_GET(it));
1266 if (wd->freeze_events)
1268 evas_object_freeze_events_set(VIEW(it), EINA_TRUE);
1269 evas_object_freeze_events_set(VIEW(prev_it), EINA_TRUE);
1271 edje_object_signal_emit(VIEW(it), "elm,state,cur,popped", "elm");
1272 evas_object_show(VIEW(prev_it));
1273 evas_object_raise(VIEW(prev_it));
1274 edje_object_signal_emit(VIEW(prev_it),
1275 "elm,state,prev,popped",
1277 edje_object_message_signal_process(VIEW(it));
1278 edje_object_message_signal_process(VIEW(prev_it));
1287 elm_naviframe_item_pop_to(Elm_Object_Item *it)
1289 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1290 Elm_Naviframe_Item *navi_it;
1292 Eina_Inlist *l, *prev_l;
1294 navi_it = (Elm_Naviframe_Item *) it;
1295 wd = elm_widget_data_get(WIDGET(navi_it));
1298 if (it == elm_naviframe_top_item_get(WIDGET(navi_it))) return;
1300 l = wd->stack->last->prev;
1304 if (EINA_INLIST_CONTAINER_GET(l, Elm_Naviframe_Item) ==
1305 ((Elm_Naviframe_Item *) it)) break;
1307 wd->stack = eina_inlist_remove(wd->stack, l);
1308 _item_del(EINA_INLIST_CONTAINER_GET(l, Elm_Naviframe_Item));
1311 elm_naviframe_item_pop(WIDGET(navi_it));
1315 elm_naviframe_item_promote(Elm_Object_Item *it)
1317 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1318 Elm_Naviframe_Item *navi_it;
1319 Elm_Naviframe_Item *prev_it;
1322 navi_it = (Elm_Naviframe_Item *) it;
1323 wd = elm_widget_data_get(navi_it->base.widget);
1326 if (it == elm_naviframe_top_item_get(navi_it->base.widget)) return;
1327 wd->stack = eina_inlist_demote(wd->stack, EINA_INLIST_GET(navi_it));
1328 prev_it = EINA_INLIST_CONTAINER_GET(wd->stack->last->prev,
1329 Elm_Naviframe_Item);
1330 if (wd->freeze_events)
1332 evas_object_freeze_events_set(VIEW(it), EINA_TRUE);
1333 evas_object_freeze_events_set(VIEW(prev_it), EINA_TRUE);
1335 edje_object_signal_emit(VIEW(prev_it),
1336 "elm,state,cur,pushed",
1338 evas_object_show(VIEW(navi_it));
1339 evas_object_raise(VIEW(navi_it));
1340 edje_object_signal_emit(VIEW(navi_it),
1341 "elm,state,new,pushed",
1343 edje_object_message_signal_process(VIEW(prev_it));
1344 edje_object_message_signal_process(VIEW(navi_it));
1348 elm_naviframe_item_del(Elm_Object_Item *it)
1350 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1351 Elm_Naviframe_Item *navi_it;
1354 navi_it =(Elm_Naviframe_Item *) it;
1355 wd = elm_widget_data_get(WIDGET(navi_it));
1358 if (it == elm_naviframe_top_item_get(WIDGET(navi_it)))
1360 wd->stack = eina_inlist_remove(wd->stack, EINA_INLIST_GET(navi_it));
1362 navi_it = EINA_INLIST_CONTAINER_GET(wd->stack->last,
1363 Elm_Naviframe_Item);
1364 evas_object_show(VIEW(navi_it));
1365 evas_object_raise(VIEW(navi_it));
1366 edje_object_signal_emit(VIEW(navi_it), "elm,state,visible", "elm");
1370 wd->stack = eina_inlist_remove(wd->stack, EINA_INLIST_GET(navi_it));
1376 elm_naviframe_content_preserve_on_pop_set(Evas_Object *obj, Eina_Bool preserve)
1378 ELM_CHECK_WIDTYPE(obj, widtype);
1379 Widget_Data *wd = elm_widget_data_get(obj);
1381 wd->preserve = !!preserve;
1385 elm_naviframe_content_preserve_on_pop_get(const Evas_Object *obj)
1387 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
1388 Widget_Data *wd = elm_widget_data_get(obj);
1389 if (!wd) return EINA_FALSE;
1390 return wd->preserve;
1393 EAPI Elm_Object_Item*
1394 elm_naviframe_top_item_get(const Evas_Object *obj)
1396 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1397 Widget_Data *wd = elm_widget_data_get(obj);
1398 if ((!wd) || (!wd->stack)) return NULL;
1399 return (Elm_Object_Item *) (EINA_INLIST_CONTAINER_GET(wd->stack->last,
1400 Elm_Naviframe_Item));
1403 EAPI Elm_Object_Item*
1404 elm_naviframe_bottom_item_get(const Evas_Object *obj)
1406 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1407 Widget_Data *wd = elm_widget_data_get(obj);
1408 if ((!wd) || (!wd->stack)) return NULL;
1409 return (Elm_Object_Item *) (EINA_INLIST_CONTAINER_GET(wd->stack,
1410 Elm_Naviframe_Item));
1414 elm_naviframe_item_style_set(Elm_Object_Item *it, const char *item_style)
1416 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1417 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
1419 //Return if new style is exsiting one.
1421 if (!strcmp(item_style, navi_it->style)) return;
1424 if (!strcmp("basic", navi_it->style)) return;
1426 _item_style_set(navi_it, item_style);
1430 elm_naviframe_item_style_get(const Elm_Object_Item *it)
1432 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
1433 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
1434 return navi_it->style;
1438 elm_naviframe_item_title_visible_set(Elm_Object_Item *it, Eina_Bool visible)
1440 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1441 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
1443 visible = !!visible;
1444 if (navi_it->title_visible == visible) return;
1446 navi_it->title_visible = visible;
1447 _item_title_visible_update(navi_it);
1451 elm_naviframe_item_title_visible_get(const Elm_Object_Item *it)
1453 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
1454 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
1455 return navi_it->title_visible;
1459 elm_naviframe_prev_btn_auto_pushed_set(Evas_Object *obj, Eina_Bool auto_pushed)
1461 ELM_CHECK_WIDTYPE(obj, widtype);
1462 Widget_Data *wd = elm_widget_data_get(obj);
1464 wd->auto_pushed = !!auto_pushed;
1468 elm_naviframe_prev_btn_auto_pushed_get(const Evas_Object *obj)
1470 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
1471 Widget_Data *wd = elm_widget_data_get(obj);
1472 if (!wd) return EINA_FALSE;
1473 return wd->auto_pushed;
1477 elm_naviframe_items_get(const Evas_Object *obj)
1479 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1480 Widget_Data *wd = elm_widget_data_get(obj);
1481 if (!wd) return NULL;
1486 elm_naviframe_event_enabled_set(Evas_Object *obj, Eina_Bool enabled)
1488 ELM_CHECK_WIDTYPE(obj, widtype);
1489 Widget_Data *wd = elm_widget_data_get(obj);
1491 enabled = !!enabled;
1492 if (wd->freeze_events == !enabled) return;
1493 wd->freeze_events = !enabled;
1497 elm_naviframe_event_enabled_get(const Evas_Object *obj)
1499 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
1500 Widget_Data *wd = elm_widget_data_get(obj);
1501 if (!wd) return EINA_FALSE;
1502 return !wd->freeze_events;