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(part, "elm.swallow.content")))
328 _item_content_set(navi_it, content);
331 else if (!strcmp(part, "elm.swallow.prev_btn"))
333 _title_prev_btn_set(navi_it, content, EINA_FALSE);
336 else if (!strcmp(part, "elm.swallow.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(part, "elm.swallow.content")))
360 return navi_it->content;
361 else if (!strcmp(part, "elm.swallow.prev_btn"))
362 return navi_it->title_prev_btn;
363 else if (!strcmp(part, "elm.swallow.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("elm.swallow.content", part))
385 return _item_content_unset(navi_it);
386 else if (!strcmp(part, "elm.swallow.prev_btn"))
387 return _title_prev_btn_unset(navi_it);
388 else if (!strcmp(part, "elm.swallow.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 evas_object_geometry_get(obj, &x, &y, &w, &h);
428 EINA_INLIST_FOREACH(wd->stack, it)
430 evas_object_move(VIEW(it), x, y);
431 evas_object_resize(VIEW(it), w, h);
432 edje_object_size_min_calc(VIEW(it), &it->minw, &it->minh);
433 if (it->minw > minw) minw = it->minw;
434 if (it->minh > minh) minh = it->minh;
436 evas_object_size_hint_min_set(obj, minw, minh);
437 evas_object_size_hint_max_set(obj, -1, -1);
441 _move(void *data __UNUSED__,
444 void *event_info __UNUSED__)
450 _resize(void *data __UNUSED__,
453 void *event_info __UNUSED__)
459 _title_clicked(void *data,
460 Evas_Object *obj __UNUSED__,
461 const char *emission __UNUSED__,
462 const char *source __UNUSED__)
464 Elm_Naviframe_Item *it = data;
465 evas_object_smart_callback_call(WIDGET(it), SIG_TITLE_CLICKED, it);
469 _back_btn_clicked(void *data,
471 void *event_info __UNUSED__)
473 /* Since edje has the event queue, clicked event could be happend multiple times
474 on some heavy environment. This callback del will prevent those scenario and
475 guarantee only one clicked for it's own page. */
476 evas_object_smart_callback_del(obj, "clicked", _back_btn_clicked);
477 elm_naviframe_item_pop(data);
481 _back_btn_new(Evas_Object *obj)
485 btn = elm_button_add(obj);
486 if (!btn) return NULL;
487 evas_object_smart_callback_add(btn, "clicked", _back_btn_clicked, obj);
488 snprintf(buf, sizeof(buf), "naviframe/back_btn/%s", elm_widget_style_get(obj));
489 elm_object_style_set(btn, buf);
494 _title_content_del(void *data,
496 Evas_Object *obj __UNUSED__,
497 void *event_info __UNUSED__)
500 Elm_Naviframe_Content_Item_Pair *pair = data;
501 Elm_Naviframe_Item *it = pair->it;
502 snprintf(buf, sizeof(buf), "elm,state,%s,hide", pair->part);
503 edje_object_signal_emit(VIEW(it), buf, "elm");
504 it->content_list = eina_inlist_remove(it->content_list,
505 EINA_INLIST_GET(pair));
506 eina_stringshare_del(pair->part);
511 _title_prev_btn_del(void *data,
513 Evas_Object *obj __UNUSED__,
514 void *event_info __UNUSED__)
516 Elm_Naviframe_Item *it = data;
517 it->back_btn = EINA_FALSE;
518 it->title_prev_btn = NULL;
519 edje_object_signal_emit(VIEW(it), "elm,state,prev_btn,hide", "elm");
523 _title_next_btn_del(void *data,
525 Evas_Object *obj __UNUSED__,
526 void *event_info __UNUSED__)
528 Elm_Naviframe_Item *it = data;
529 it->title_next_btn = NULL;
530 edje_object_signal_emit(VIEW(it), "elm,state,next_btn,hide", "elm");
534 _title_icon_del(void *data,
536 Evas_Object *obj __UNUSED__,
537 void *event_info __UNUSED__)
539 Elm_Naviframe_Item *it = data;
540 it->title_icon = NULL;
541 edje_object_signal_emit(VIEW(it), "elm,state,icon,hide", "elm");
545 _item_content_del(void *data,
547 Evas_Object *obj __UNUSED__,
548 void *event_info __UNUSED__)
550 Elm_Naviframe_Item *it = data;
552 edje_object_signal_emit(VIEW(it), "elm,state,content,hide", "elm");
556 _title_content_set(Elm_Naviframe_Item *it,
558 Evas_Object *content)
561 Elm_Naviframe_Content_Item_Pair *pair = NULL;
563 EINA_INLIST_FOREACH(it->content_list, pair)
564 if (!strcmp(part, pair->part)) break;
568 if (pair->content != content)
572 evas_object_event_callback_del(pair->content,
575 evas_object_event_callback_del(pair->content,
576 EVAS_CALLBACK_CHANGED_SIZE_HINTS,
577 _changed_size_hints);
578 snprintf(buf, sizeof(buf), "elm,state,%s,hide", part);
579 edje_object_signal_emit(VIEW(it), buf, "elm");
581 evas_object_del(pair->content);
582 if (!content) return;
587 if (!content) return;
588 pair = ELM_NEW(Elm_Naviframe_Content_Item_Pair);
591 ERR("Failed to allocate new content part of the item! : naviframe=%p", WIDGET(it));
595 eina_stringshare_replace(&pair->part, part);
596 it->content_list = eina_inlist_append(it->content_list,
597 EINA_INLIST_GET(pair));
599 if (pair->content != content)
601 elm_widget_sub_object_add(WIDGET(it), content);
602 evas_object_event_callback_add(content,
606 evas_object_event_callback_add(content,
607 EVAS_CALLBACK_CHANGED_SIZE_HINTS,
611 edje_object_part_swallow(VIEW(it), part, content);
612 snprintf(buf, sizeof(buf), "elm,state,%s,show", part);
613 edje_object_signal_emit(VIEW(it), buf, "elm");
614 pair->content = content;
616 _sizing_eval(WIDGET(it));
620 _title_prev_btn_set(Elm_Naviframe_Item *it,
624 if (it->title_prev_btn == btn) return;
626 if (it->title_prev_btn)
627 evas_object_del(it->title_prev_btn);
629 it->title_prev_btn = btn;
632 elm_widget_sub_object_add(WIDGET(it), btn);
633 evas_object_event_callback_add(btn,
637 evas_object_event_callback_add(btn,
638 EVAS_CALLBACK_CHANGED_SIZE_HINTS,
641 edje_object_part_swallow(VIEW(it), "elm.swallow.prev_btn", btn);
642 edje_object_signal_emit(VIEW(it), "elm,state,prev_btn,show", "elm");
643 it->back_btn = back_btn;
645 _sizing_eval(WIDGET(it));
649 _title_next_btn_set(Elm_Naviframe_Item *it, Evas_Object *btn)
651 if (it->title_next_btn == btn) return;
653 if (it->title_next_btn)
654 evas_object_del(it->title_next_btn);
656 it->title_next_btn = btn;
659 elm_widget_sub_object_add(WIDGET(it), btn);
660 evas_object_event_callback_add(btn,
664 evas_object_event_callback_add(btn,
665 EVAS_CALLBACK_CHANGED_SIZE_HINTS,
668 edje_object_part_swallow(VIEW(it), "elm.swallow.next_btn", btn);
669 edje_object_signal_emit(VIEW(it), "elm,state,next_btn,show", "elm");
671 _sizing_eval(WIDGET(it));
675 _title_icon_set(Elm_Naviframe_Item *it, Evas_Object *icon)
677 if (it->title_icon == icon) return;
680 evas_object_del(it->title_icon);
682 it->title_icon = icon;
685 elm_widget_sub_object_add(WIDGET(it), icon);
686 evas_object_event_callback_add(icon,
690 evas_object_event_callback_add(icon,
691 EVAS_CALLBACK_CHANGED_SIZE_HINTS,
694 edje_object_part_swallow(VIEW(it), "elm.swallow.icon", icon);
695 edje_object_signal_emit(VIEW(it), "elm,state,icon,show", "elm");
697 _sizing_eval(WIDGET(it));
701 _item_content_unset(Elm_Naviframe_Item *it)
703 Evas_Object *content = it->content;
704 if (!content) return NULL;
706 elm_widget_sub_object_del(WIDGET(it), content);
707 edje_object_part_unswallow(VIEW(it), content);
708 edje_object_signal_emit(VIEW(it), "elm,state,content,hide", "elm");
709 evas_object_event_callback_del(content,
712 evas_object_event_callback_del(content,
713 EVAS_CALLBACK_CHANGED_SIZE_HINTS,
714 _changed_size_hints);
715 _sizing_eval(WIDGET(it));
722 _title_prev_btn_unset(Elm_Naviframe_Item *it)
724 Evas_Object *content = it->title_prev_btn;
725 if (!content) return NULL;
727 elm_widget_sub_object_del(WIDGET(it), content);
728 edje_object_part_unswallow(VIEW(it), content);
729 edje_object_signal_emit(VIEW(it), "elm,state,prev_btn,hide", "elm");
730 evas_object_event_callback_del(content,
732 _title_prev_btn_del);
733 evas_object_event_callback_del(content,
734 EVAS_CALLBACK_CHANGED_SIZE_HINTS,
735 _changed_size_hints);
736 _sizing_eval(WIDGET(it));
738 it->title_prev_btn = NULL;
743 _title_next_btn_unset(Elm_Naviframe_Item *it)
745 Evas_Object *content = it->title_next_btn;
746 if (!content) return NULL;
748 elm_widget_sub_object_del(WIDGET(it), content);
749 edje_object_part_unswallow(VIEW(it), content);
750 edje_object_signal_emit(VIEW(it), "elm,state,next_btn,hide", "elm");
751 evas_object_event_callback_del(content,
753 _title_next_btn_del);
754 evas_object_event_callback_del(content,
755 EVAS_CALLBACK_CHANGED_SIZE_HINTS,
756 _changed_size_hints);
757 _sizing_eval(WIDGET(it));
759 it->title_next_btn = NULL;
764 _title_icon_unset(Elm_Naviframe_Item *it)
766 Evas_Object *content = it->title_icon;
767 if (!content) return NULL;
769 elm_widget_sub_object_del(WIDGET(it), content);
770 edje_object_part_unswallow(VIEW(it), content);
771 edje_object_signal_emit(VIEW(it), "elm,state,icon,hide", "elm");
772 evas_object_event_callback_del(content,
775 evas_object_event_callback_del(content,
776 EVAS_CALLBACK_CHANGED_SIZE_HINTS,
777 _changed_size_hints);
778 _sizing_eval(WIDGET(it));
779 it->title_icon = NULL;
785 _title_content_unset(Elm_Naviframe_Item *it, const char *part)
787 Elm_Naviframe_Content_Item_Pair *pair = NULL;
789 Evas_Object *content = NULL;
791 EINA_INLIST_FOREACH(it->content_list, pair)
793 if (!strcmp(part, pair->part))
795 content = pair->content;
796 eina_stringshare_del(pair->part);
797 it->content_list = eina_inlist_remove(it->content_list,
798 EINA_INLIST_GET(pair));
804 if (!content) return NULL;
806 elm_widget_sub_object_del(WIDGET(it), content);
807 edje_object_part_unswallow(VIEW(it), content);
808 snprintf(buf, sizeof(buf), "elm,state,%s,hide", part);
809 edje_object_signal_emit(VIEW(it), buf, "elm");
810 evas_object_event_callback_del(content,
813 evas_object_event_callback_del(content,
814 EVAS_CALLBACK_CHANGED_SIZE_HINTS,
815 _changed_size_hints);
816 _sizing_eval(WIDGET(it));
822 _item_del(Elm_Naviframe_Item *it)
825 Elm_Naviframe_Content_Item_Pair *content_pair;
826 Elm_Naviframe_Text_Item_Pair *text_pair;
830 wd = elm_widget_data_get(WIDGET(it));
833 if (it->title_prev_btn)
834 evas_object_del(it->title_prev_btn);
835 if (it->title_next_btn)
836 evas_object_del(it->title_next_btn);
838 evas_object_del(it->title_icon);
839 if ((it->content) && (!wd->preserve))
840 evas_object_del(it->content);
842 while (it->content_list)
844 content_pair = EINA_INLIST_CONTAINER_GET(it->content_list,
845 Elm_Naviframe_Content_Item_Pair);
846 evas_object_event_callback_del(content_pair->content,
849 evas_object_event_callback_del(content_pair->content,
850 EVAS_CALLBACK_CHANGED_SIZE_HINTS,
851 _changed_size_hints);
852 evas_object_del(content_pair->content);
853 eina_stringshare_del(content_pair->part);
854 it->content_list = eina_inlist_remove(it->content_list,
859 while (it->text_list)
861 text_pair = EINA_INLIST_CONTAINER_GET(it->text_list,
862 Elm_Naviframe_Text_Item_Pair);
863 eina_stringshare_del(text_pair->part);
864 eina_stringshare_del(text_pair->text);
865 it->text_list = eina_inlist_remove(it->text_list,
870 eina_stringshare_del(it->style);
872 elm_widget_item_del(it);
876 _pushed_finished(void *data,
877 Evas_Object *obj __UNUSED__,
878 const char *emission __UNUSED__,
879 const char *source __UNUSED__)
882 Elm_Naviframe_Item *it = data;
885 wd = elm_widget_data_get(WIDGET(it));
888 evas_object_hide(VIEW(it));
889 evas_object_smart_callback_call(WIDGET(it),
892 if (wd->freeze_events)
893 evas_object_freeze_events_set(VIEW(it), EINA_FALSE);
897 _popped_finished(void *data,
898 Evas_Object *obj __UNUSED__,
899 const char *emission __UNUSED__,
900 const char *source __UNUSED__)
902 Elm_Naviframe_Item *it = data;
904 evas_object_smart_callback_call(WIDGET(it),
911 _show_finished(void *data,
912 Evas_Object *obj __UNUSED__,
913 const char *emission __UNUSED__,
914 const char *source __UNUSED__)
916 Elm_Naviframe_Item *it;
921 wd = elm_widget_data_get(WIDGET(it));
924 evas_object_smart_callback_call(WIDGET(it),
925 SIG_TRANSITION_FINISHED,
927 if (wd->freeze_events)
928 evas_object_freeze_events_set(VIEW(it), EINA_FALSE);
932 _changed_size_hints(void *data,
934 Evas_Object *obj __UNUSED__,
935 void *event_info __UNUSED__)
941 _item_content_set(Elm_Naviframe_Item *navi_it, Evas_Object *content)
943 if (navi_it->content == content) return;
944 if (navi_it->content) evas_object_del(navi_it->content);
945 elm_widget_sub_object_add(WIDGET(navi_it), content);
946 edje_object_part_swallow(VIEW(navi_it),
947 "elm.swallow.content",
950 edje_object_signal_emit(VIEW(navi_it),
951 "elm,state,content,show",
954 edje_object_signal_emit(VIEW(navi_it),
955 "elm,state,content,hide",
957 evas_object_event_callback_add(content,
961 evas_object_event_callback_add(content,
962 EVAS_CALLBACK_CHANGED_SIZE_HINTS,
965 navi_it->content = content;
966 _sizing_eval(WIDGET(navi_it));
969 //FIXME: need to handle if this function is called while transition
971 _item_style_set(Elm_Naviframe_Item *navi_it, const char *item_style)
973 Elm_Naviframe_Content_Item_Pair *content_pair;
974 Elm_Naviframe_Text_Item_Pair *text_pair;
981 strcpy(buf, "item/basic");
982 eina_stringshare_replace(&navi_it->style, "basic");
986 snprintf(buf, sizeof(buf), "item/%s", item_style);
987 eina_stringshare_replace(&navi_it->style, item_style);
989 _elm_theme_object_set(WIDGET(navi_it),
993 elm_widget_style_get(WIDGET(navi_it)));
995 EINA_INLIST_FOREACH(navi_it->text_list, text_pair)
996 _item_text_set_hook((Elm_Object_Item *) navi_it,
1000 EINA_INLIST_FOREACH(navi_it->content_list, content_pair)
1001 _item_content_set_hook((Elm_Object_Item *) navi_it,
1003 content_pair->content);
1005 if (navi_it->content)
1007 edje_object_part_swallow(VIEW(navi_it),
1008 "elm.swallow.content",
1010 edje_object_signal_emit(VIEW(navi_it),
1011 "elm,state,content,show",
1016 if (navi_it->title_prev_btn)
1018 edje_object_part_swallow(VIEW(navi_it),
1019 "elm.swallow.prev_btn",
1020 navi_it->title_prev_btn);
1021 edje_object_signal_emit(VIEW(navi_it),
1022 "elm,state,prev_btn,show",
1027 if (navi_it->title_next_btn)
1029 edje_object_part_swallow(VIEW(navi_it),
1030 "elm.swallow.next_btn",
1031 navi_it->title_next_btn);
1032 edje_object_signal_emit(VIEW(navi_it),
1033 "elm,state,next_btn,show",
1037 navi_it->title_visible = EINA_TRUE;
1038 _sizing_eval(WIDGET(navi_it));
1040 wd = elm_widget_data_get(WIDGET(navi_it));
1043 if (wd->freeze_events)
1044 evas_object_freeze_events_set(VIEW(navi_it), EINA_FALSE);
1047 static Elm_Naviframe_Item *
1048 _item_new(Evas_Object *obj,
1049 const char *title_label,
1050 Evas_Object *prev_btn,
1051 Evas_Object *next_btn,
1052 Evas_Object *content,
1053 const char *item_style)
1055 Widget_Data *wd = elm_widget_data_get(obj);
1058 Elm_Naviframe_Item *it = elm_widget_item_new(obj, Elm_Naviframe_Item);
1061 ERR("Failed to allocate new item! : naviframe=%p", obj);
1065 elm_widget_item_text_set_hook_set(it, _item_text_set_hook);
1066 elm_widget_item_text_get_hook_set(it, _item_text_get_hook);
1067 elm_widget_item_content_set_hook_set(it, _item_content_set_hook);
1068 elm_widget_item_content_get_hook_set(it, _item_content_get_hook);
1069 elm_widget_item_content_unset_hook_set(it, _item_content_unset_hook);
1070 elm_widget_item_signal_emit_hook_set(it, _item_signal_emit_hook);
1073 VIEW(it) = edje_object_add(evas_object_evas_get(obj));
1074 edje_object_mirrored_set(VIEW(it), elm_widget_mirrored_get(obj));
1075 evas_object_smart_member_add(VIEW(it), wd->base);
1076 elm_widget_sub_object_add(obj, VIEW(it));
1077 edje_object_signal_callback_add(VIEW(it),
1078 "elm,action,show,finished",
1080 _show_finished, it);
1081 edje_object_signal_callback_add(VIEW(it),
1082 "elm,action,pushed,finished",
1084 _pushed_finished, it);
1085 edje_object_signal_callback_add(VIEW(it),
1086 "elm,action,popped,finished",
1088 _popped_finished, it);
1089 edje_object_signal_callback_add(VIEW(it),
1090 "elm,action,title,clicked",
1092 _title_clicked, it);
1094 _item_style_set(it, item_style);
1095 _item_text_set_hook((Elm_Object_Item *) it, "elm.text.title", title_label);
1098 if ((!prev_btn) && wd->auto_pushed && eina_inlist_count(wd->stack))
1100 prev_btn = _back_btn_new(obj);
1101 _title_prev_btn_set(it, prev_btn, EINA_TRUE);
1104 _title_prev_btn_set(it, prev_btn, EINA_FALSE);
1106 _title_next_btn_set(it, next_btn);
1107 _item_content_set(it, content);
1108 it->title_visible = EINA_TRUE;
1113 elm_naviframe_add(Evas_Object *parent)
1119 ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL);
1120 ELM_SET_WIDTYPE(widtype, "naviframe");
1121 elm_widget_type_set(obj, "naviframe");
1122 elm_widget_sub_object_add(parent, obj);
1123 elm_widget_data_set(obj, wd);
1124 elm_widget_del_hook_set(obj, _del_hook);
1125 elm_widget_disable_hook_set(obj, _disable_hook);
1126 elm_widget_theme_hook_set(obj, _theme_hook);
1127 elm_widget_signal_emit_hook_set(obj, _emit_hook);
1130 wd->base = edje_object_add(e);
1131 edje_object_mirrored_set(wd->base, elm_widget_mirrored_get(obj));
1132 elm_widget_resize_object_set(obj, wd->base);
1133 _elm_theme_object_set(obj, wd->base, "naviframe", "base", "default");
1135 evas_object_event_callback_add(obj, EVAS_CALLBACK_MOVE, _move, obj);
1136 evas_object_event_callback_add(obj, EVAS_CALLBACK_RESIZE, _resize, obj);
1137 evas_object_smart_callbacks_descriptions_set(obj, _signals);
1139 wd->auto_pushed = EINA_TRUE;
1140 wd->freeze_events = EINA_TRUE;
1145 EAPI Elm_Object_Item *
1146 elm_naviframe_item_push(Evas_Object *obj,
1147 const char *title_label,
1148 Evas_Object *prev_btn,
1149 Evas_Object *next_btn,
1150 Evas_Object *content,
1151 const char *item_style)
1153 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1155 Elm_Naviframe_Item *prev_it, *it;
1157 wd = elm_widget_data_get(obj);
1158 if (!wd) return NULL;
1160 it = _item_new(obj, title_label, prev_btn, next_btn, content, item_style);
1161 if (!it) return NULL;
1163 evas_object_show(VIEW(it));
1165 prev_it = (Elm_Naviframe_Item *) elm_naviframe_top_item_get(obj);
1168 if (wd->freeze_events)
1170 evas_object_freeze_events_set(VIEW(it), EINA_TRUE);
1171 evas_object_freeze_events_set(VIEW(prev_it), EINA_TRUE);
1173 edje_object_signal_emit(VIEW(prev_it),
1174 "elm,state,cur,pushed",
1176 edje_object_signal_emit(VIEW(it),
1177 "elm,state,new,pushed",
1179 edje_object_message_signal_process(VIEW(prev_it));
1180 edje_object_message_signal_process(VIEW(it));
1182 wd->stack = eina_inlist_append(wd->stack, EINA_INLIST_GET(it));
1184 return (Elm_Object_Item *) it;
1187 EAPI Elm_Object_Item *
1188 elm_naviframe_item_insert_before(Elm_Object_Item *before,
1189 const char *title_label,
1190 Evas_Object *prev_btn,
1191 Evas_Object *next_btn,
1192 Evas_Object *content,
1193 const char *item_style)
1195 ELM_OBJ_ITEM_CHECK_OR_RETURN(before, NULL);
1196 Elm_Naviframe_Item *it;
1199 wd = elm_widget_data_get(WIDGET(before));
1200 if (!wd) return NULL;
1202 it = _item_new(WIDGET(before), title_label, prev_btn, next_btn, content,
1204 if (!it) return NULL;
1207 eina_inlist_prepend_relative(wd->stack, EINA_INLIST_GET(it),
1208 EINA_INLIST_GET(((Elm_Naviframe_Item *) before)));
1209 _sizing_eval(WIDGET(before));
1210 return (Elm_Object_Item *) it;
1213 EAPI Elm_Object_Item *
1214 elm_naviframe_item_insert_after(Elm_Object_Item *after,
1215 const char *title_label,
1216 Evas_Object *prev_btn,
1217 Evas_Object *next_btn,
1218 Evas_Object *content,
1219 const char *item_style)
1221 ELM_OBJ_ITEM_CHECK_OR_RETURN(after, NULL);
1222 Elm_Naviframe_Item *it;
1225 wd = elm_widget_data_get(WIDGET(after));
1226 if (!wd) return NULL;
1228 it = _item_new(WIDGET(after), title_label, prev_btn, next_btn, content,
1230 if (!it) return NULL;
1232 if (elm_naviframe_top_item_get(WIDGET(after)) == after)
1234 evas_object_hide(VIEW(after));
1235 evas_object_show(VIEW(it));
1238 eina_inlist_append_relative(wd->stack, EINA_INLIST_GET(it),
1239 EINA_INLIST_GET(((Elm_Naviframe_Item *) after)));
1240 _sizing_eval(WIDGET(after));
1241 return (Elm_Object_Item *) it;
1245 elm_naviframe_item_pop(Evas_Object *obj)
1247 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1248 Elm_Naviframe_Item *it, *prev_it = NULL;
1250 Evas_Object *content = NULL;
1252 wd = elm_widget_data_get(obj);
1253 if (!wd) return NULL;
1255 it = (Elm_Naviframe_Item *) elm_naviframe_top_item_get(obj);
1256 if (!it) return NULL;
1257 elm_widget_tree_unfocusable_set(it->content, EINA_TRUE);
1259 content = it->content;
1261 if (wd->stack->last->prev)
1262 prev_it = EINA_INLIST_CONTAINER_GET(wd->stack->last->prev,
1263 Elm_Naviframe_Item);
1264 wd->stack = eina_inlist_remove(wd->stack, EINA_INLIST_GET(it));
1267 if (wd->freeze_events)
1269 evas_object_freeze_events_set(VIEW(it), EINA_TRUE);
1270 evas_object_freeze_events_set(VIEW(prev_it), EINA_TRUE);
1272 edje_object_signal_emit(VIEW(it), "elm,state,cur,popped", "elm");
1273 evas_object_show(VIEW(prev_it));
1274 evas_object_raise(VIEW(prev_it));
1275 edje_object_signal_emit(VIEW(prev_it),
1276 "elm,state,prev,popped",
1278 edje_object_message_signal_process(VIEW(it));
1279 edje_object_message_signal_process(VIEW(prev_it));
1288 elm_naviframe_item_pop_to(Elm_Object_Item *it)
1290 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1291 Elm_Naviframe_Item *navi_it;
1293 Eina_Inlist *l, *prev_l;
1295 navi_it = (Elm_Naviframe_Item *) it;
1296 wd = elm_widget_data_get(WIDGET(navi_it));
1299 if (it == elm_naviframe_top_item_get(WIDGET(navi_it))) return;
1301 l = wd->stack->last->prev;
1305 if (EINA_INLIST_CONTAINER_GET(l, Elm_Naviframe_Item) ==
1306 ((Elm_Naviframe_Item *) it)) break;
1308 wd->stack = eina_inlist_remove(wd->stack, l);
1309 _item_del(EINA_INLIST_CONTAINER_GET(l, Elm_Naviframe_Item));
1312 elm_naviframe_item_pop(WIDGET(navi_it));
1316 elm_naviframe_item_promote(Elm_Object_Item *it)
1318 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1319 Elm_Naviframe_Item *navi_it;
1320 Elm_Naviframe_Item *prev_it;
1323 navi_it = (Elm_Naviframe_Item *) it;
1324 wd = elm_widget_data_get(navi_it->base.widget);
1327 if (it == elm_naviframe_top_item_get(navi_it->base.widget)) return;
1328 wd->stack = eina_inlist_demote(wd->stack, EINA_INLIST_GET(navi_it));
1329 prev_it = EINA_INLIST_CONTAINER_GET(wd->stack->last->prev,
1330 Elm_Naviframe_Item);
1331 if (wd->freeze_events)
1333 evas_object_freeze_events_set(VIEW(it), EINA_TRUE);
1334 evas_object_freeze_events_set(VIEW(prev_it), EINA_TRUE);
1336 edje_object_signal_emit(VIEW(prev_it),
1337 "elm,state,cur,pushed",
1339 evas_object_show(VIEW(navi_it));
1340 evas_object_raise(VIEW(navi_it));
1341 edje_object_signal_emit(VIEW(navi_it),
1342 "elm,state,new,pushed",
1344 edje_object_message_signal_process(VIEW(prev_it));
1345 edje_object_message_signal_process(VIEW(navi_it));
1349 elm_naviframe_item_del(Elm_Object_Item *it)
1351 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1352 Elm_Naviframe_Item *navi_it;
1355 navi_it =(Elm_Naviframe_Item *) it;
1356 wd = elm_widget_data_get(WIDGET(navi_it));
1359 if (it == elm_naviframe_top_item_get(WIDGET(navi_it)))
1361 wd->stack = eina_inlist_remove(wd->stack, EINA_INLIST_GET(navi_it));
1363 //If the item is only one, the stack will be empty
1364 if (!wd->stack) return;
1365 navi_it = EINA_INLIST_CONTAINER_GET(wd->stack->last,
1366 Elm_Naviframe_Item);
1367 evas_object_show(VIEW(navi_it));
1368 evas_object_raise(VIEW(navi_it));
1369 edje_object_signal_emit(VIEW(navi_it), "elm,state,visible", "elm");
1373 wd->stack = eina_inlist_remove(wd->stack, EINA_INLIST_GET(navi_it));
1379 elm_naviframe_content_preserve_on_pop_set(Evas_Object *obj, Eina_Bool preserve)
1381 ELM_CHECK_WIDTYPE(obj, widtype);
1382 Widget_Data *wd = elm_widget_data_get(obj);
1384 wd->preserve = !!preserve;
1388 elm_naviframe_content_preserve_on_pop_get(const Evas_Object *obj)
1390 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
1391 Widget_Data *wd = elm_widget_data_get(obj);
1392 if (!wd) return EINA_FALSE;
1393 return wd->preserve;
1396 EAPI Elm_Object_Item*
1397 elm_naviframe_top_item_get(const Evas_Object *obj)
1399 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1400 Widget_Data *wd = elm_widget_data_get(obj);
1401 if ((!wd) || (!wd->stack)) return NULL;
1402 return (Elm_Object_Item *) (EINA_INLIST_CONTAINER_GET(wd->stack->last,
1403 Elm_Naviframe_Item));
1406 EAPI Elm_Object_Item*
1407 elm_naviframe_bottom_item_get(const Evas_Object *obj)
1409 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1410 Widget_Data *wd = elm_widget_data_get(obj);
1411 if ((!wd) || (!wd->stack)) return NULL;
1412 return (Elm_Object_Item *) (EINA_INLIST_CONTAINER_GET(wd->stack,
1413 Elm_Naviframe_Item));
1417 elm_naviframe_item_style_set(Elm_Object_Item *it, const char *item_style)
1419 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1420 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
1422 //Return if new style is exsiting one.
1424 if (!strcmp(item_style, navi_it->style)) return;
1427 if (!strcmp("basic", navi_it->style)) return;
1429 _item_style_set(navi_it, item_style);
1433 elm_naviframe_item_style_get(const Elm_Object_Item *it)
1435 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
1436 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
1437 return navi_it->style;
1441 elm_naviframe_item_title_visible_set(Elm_Object_Item *it, Eina_Bool visible)
1443 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1444 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
1446 visible = !!visible;
1447 if (navi_it->title_visible == visible) return;
1449 navi_it->title_visible = visible;
1450 _item_title_visible_update(navi_it);
1454 elm_naviframe_item_title_visible_get(const Elm_Object_Item *it)
1456 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
1457 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
1458 return navi_it->title_visible;
1462 elm_naviframe_prev_btn_auto_pushed_set(Evas_Object *obj, Eina_Bool auto_pushed)
1464 ELM_CHECK_WIDTYPE(obj, widtype);
1465 Widget_Data *wd = elm_widget_data_get(obj);
1467 wd->auto_pushed = !!auto_pushed;
1471 elm_naviframe_prev_btn_auto_pushed_get(const Evas_Object *obj)
1473 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
1474 Widget_Data *wd = elm_widget_data_get(obj);
1475 if (!wd) return EINA_FALSE;
1476 return wd->auto_pushed;
1480 elm_naviframe_items_get(const Evas_Object *obj)
1482 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1483 Widget_Data *wd = elm_widget_data_get(obj);
1484 if (!wd) return NULL;
1489 elm_naviframe_event_enabled_set(Evas_Object *obj, Eina_Bool enabled)
1491 ELM_CHECK_WIDTYPE(obj, widtype);
1492 Widget_Data *wd = elm_widget_data_get(obj);
1494 enabled = !!enabled;
1495 if (wd->freeze_events == !enabled) return;
1496 wd->freeze_events = !enabled;
1500 elm_naviframe_event_enabled_get(const Evas_Object *obj)
1502 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
1503 Widget_Data *wd = elm_widget_data_get(obj);
1504 if (!wd) return EINA_FALSE;
1505 return !wd->freeze_events;