1 #include <Elementary.h>
4 typedef struct _Widget_Data Widget_Data;
5 typedef struct _Elm_Naviframe_Item Elm_Naviframe_Item;
6 typedef struct _Elm_Naviframe_Content_Item_Pair Elm_Naviframe_Content_Item_Pair;
7 typedef struct _Elm_Naviframe_Text_Item_Pair Elm_Naviframe_Text_Item_Pair;
13 Eina_Bool preserve: 1;
14 Eina_Bool auto_pushed: 1;
15 Eina_Bool freeze_events: 1;
16 Eina_Stringshare *item_style;
19 struct _Elm_Naviframe_Content_Item_Pair
23 Elm_Naviframe_Item *it;
26 struct _Elm_Naviframe_Text_Item_Pair
32 struct _Elm_Naviframe_Item
36 Eina_Inlist *content_list;
37 Eina_Inlist *text_list;
39 Evas_Object *title_prev_btn;
40 Evas_Object *title_next_btn;
41 Evas_Object *title_icon;
45 Eina_Bool back_btn: 1;
46 Eina_Bool title_visible: 1;
49 static const char *widtype = NULL;
52 static const char SIG_TRANSITION_FINISHED[] = "transition,finished";
53 static const char SIG_TITLE_CLICKED[] = "title,clicked";
56 static const char SIG_ITEM_SHOW_BEGIN[] = "show,begin";
57 static const char SIG_ITEM_HIDE_FINISHED[] = "hide,finished";
59 static const Evas_Smart_Cb_Description _signals[] = {
60 {SIG_TRANSITION_FINISHED, ""},
61 {SIG_TITLE_CLICKED, ""},
62 {SIG_ITEM_SHOW_BEGIN, ""},
63 {SIG_ITEM_HIDE_FINISHED, ""},
67 static void _text_set_hook(Evas_Object *obj,
70 static const char *_text_get_hook(const Evas_Object *obj, const char *part);
71 static void _content_set_hook(Evas_Object *obj,
73 Evas_Object *content);
74 static Evas_Object *_content_get_hook(const Evas_Object *obj, const char *part);
75 static Evas_Object *_content_unset_hook(Evas_Object *obj, const char *part);
76 static void _del_hook(Evas_Object *obj);
77 static void _theme_hook(Evas_Object *obj);
78 static void _emit_hook(Evas_Object *obj,
81 static void _disable_hook(Evas_Object *obj);
82 static void _item_text_set_hook(Elm_Object_Item *it,
85 static const char *_item_text_get_hook(const Elm_Object_Item *it,
87 static void _item_content_set_hook(Elm_Object_Item *it,
89 Evas_Object *content);
90 static Evas_Object *_item_content_get_hook(const Elm_Object_Item *it,
92 static Evas_Object *_item_content_unset_hook(Elm_Object_Item *it,
94 static void _item_signal_emit_hook(Elm_Object_Item *it,
97 static void _item_title_visible_update(Elm_Naviframe_Item *navi_it);
98 static void _sizing_eval(Evas_Object *obj);
99 static void _move(void *data, Evas *e, Evas_Object *obj, void *event_info);
100 static void _resize(void *data,
104 static void _title_clicked(void *data, Evas_Object *obj,
105 const char *emission,
107 static void _back_btn_clicked(void *data,
110 static Evas_Object *_back_btn_new(Evas_Object *obj);
111 static void _item_content_del(void *data,
115 static void _title_content_del(void *data,
119 static void _title_prev_btn_del(void *data,
123 static void _title_next_btn_del(void *data,
127 static void _title_icon_del(void *data,
131 static void _title_content_set(Elm_Naviframe_Item *it,
133 Evas_Object *content);
134 static void _title_prev_btn_set(Elm_Naviframe_Item *it,
137 static void _title_next_btn_set(Elm_Naviframe_Item *it, Evas_Object *btn);
138 static void _title_icon_set(Elm_Naviframe_Item *it, Evas_Object *icon);
139 static Evas_Object * _item_content_unset(Elm_Naviframe_Item *it);
140 static Evas_Object * _title_prev_btn_unset(Elm_Naviframe_Item *it);
141 static Evas_Object * _title_next_btn_unset(Elm_Naviframe_Item *it);
142 static Evas_Object * _title_icon_unset(Elm_Naviframe_Item *it);
143 static Evas_Object * _title_content_unset(Elm_Naviframe_Item *it,
145 static void _item_del(Elm_Naviframe_Item *it);
146 static Eina_Bool _item_del_pre_hook(Elm_Object_Item *it);
147 static void _pushed_finished(void *data,
149 const char *emission,
151 static void _popped_finished(void *data,
153 const char *emission,
155 static void _show_finished(void *data,
157 const char *emission,
159 static void _changed_size_hints(void *data,
163 static void _item_content_set(Elm_Naviframe_Item *navi_it,
164 Evas_Object *content);
165 static void _item_style_set(Elm_Naviframe_Item *navi_it,
166 const char *item_style);
167 static Elm_Naviframe_Item * _item_new(Evas_Object *obj,
168 const char *title_label,
169 Evas_Object *prev_btn,
170 Evas_Object *next_btn,
171 Evas_Object *content,
172 const char *item_style);
173 static Eina_Bool _focus_next_hook(const Evas_Object *obj,
174 Elm_Focus_Direction dir,
178 _del_hook(Evas_Object *obj)
181 Elm_Naviframe_Item *it;
183 wd = elm_widget_data_get(obj);
188 while (wd->stack->last)
190 it = EINA_INLIST_CONTAINER_GET(wd->stack->last,
192 wd->stack = eina_inlist_remove(wd->stack, wd->stack->last);
194 elm_widget_item_free(it);
195 if (!wd->stack) break;
198 eina_stringshare_del(wd->item_style);
203 _theme_hook(Evas_Object *obj)
206 Elm_Naviframe_Item *it;
208 wd = elm_widget_data_get(obj);
211 _elm_theme_object_set(obj,
215 elm_widget_style_get(obj));
217 EINA_INLIST_FOREACH(wd->stack, it)
219 _item_style_set(it, it->style);
220 _item_title_visible_update(it);
224 static void _emit_hook(Evas_Object *obj,
225 const char *emission,
228 Elm_Object_Item *it = elm_naviframe_top_item_get(obj);
230 return elm_object_item_signal_emit(it, emission, source);
234 _disable_hook(Evas_Object *obj __UNUSED__)
240 _item_text_set_hook(Elm_Object_Item *it,
244 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
246 Elm_Naviframe_Text_Item_Pair *pair = NULL;
247 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
250 if (!part || !strcmp(part, "default"))
251 snprintf(buf, sizeof(buf), "elm.text.title");
252 else if(!strcmp("subtitle", part))
253 snprintf(buf, sizeof(buf), "elm.text.subtitle");
255 snprintf(buf, sizeof(buf), "%s", part);
257 EINA_INLIST_FOREACH(navi_it->text_list, pair)
258 if (!strcmp(buf, pair->part)) break;
262 pair = ELM_NEW(Elm_Naviframe_Text_Item_Pair);
265 ERR("Failed to allocate new text part of the item! : naviframe=%p",
269 eina_stringshare_replace(&pair->part, buf);
270 navi_it->text_list = eina_inlist_append(navi_it->text_list,
271 EINA_INLIST_GET(pair));
273 elm_object_part_text_set(VIEW(navi_it), buf, label);
277 snprintf(buf, sizeof(buf), "elm,state,%s,show", buf);
278 elm_object_signal_emit(VIEW(navi_it), buf, "elm");
282 snprintf(buf, sizeof(buf), "elm,state,%s,hide", buf);
283 elm_object_signal_emit(VIEW(navi_it), buf, "elm");
286 _sizing_eval(WIDGET(navi_it));
290 _item_text_get_hook(const Elm_Object_Item *it, const char *part)
292 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
295 if (!part || !strcmp(part, "default"))
296 snprintf(buf, sizeof(buf), "elm.text.title");
297 else if(!strcmp("subtitle", part))
298 snprintf(buf, sizeof(buf), "elm.text.subtitle");
300 snprintf(buf, sizeof(buf), "%s", part);
302 return elm_object_part_text_get(VIEW(it), buf);
306 _item_content_set_hook(Elm_Object_Item *it,
308 Evas_Object *content)
310 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
312 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
315 if (!part || !strcmp("default", part))
317 _item_content_set(navi_it, content);
320 else if (!strcmp(part, "prev_btn"))
322 _title_prev_btn_set(navi_it, content, EINA_FALSE);
325 else if (!strcmp(part, "next_btn"))
327 _title_next_btn_set(navi_it, content);
330 else if (!strcmp(part, "icon"))
332 _title_icon_set(navi_it, content);
337 _title_content_set(navi_it, part, content);
341 _item_content_get_hook(const Elm_Object_Item *it, const char *part)
343 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
344 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
347 if (!part || !strcmp("default", part))
348 return navi_it->content;
349 else if (!strcmp(part, "prev_btn"))
350 return navi_it->title_prev_btn;
351 else if (!strcmp(part, "next_btn"))
352 return navi_it->title_next_btn;
353 else if (!strcmp(part, "icon"))
354 return navi_it->title_icon;
357 return elm_object_part_content_get(VIEW(navi_it), part);
361 _item_content_unset_hook(Elm_Object_Item *it, const char *part)
363 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
364 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
367 if (!part || !strcmp("default", part))
368 return _item_content_unset(navi_it);
369 else if (!strcmp(part, "prev_btn"))
370 return _title_prev_btn_unset(navi_it);
371 else if (!strcmp(part, "next_btn"))
372 return _title_next_btn_unset(navi_it);
373 else if (!strcmp(part, "icon"))
374 return _title_icon_unset(navi_it);
376 return _title_content_unset(navi_it, part);
380 _item_signal_emit_hook(Elm_Object_Item *it,
381 const char *emission,
384 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
385 elm_object_signal_emit(VIEW(it), emission, source);
389 _item_title_visible_update(Elm_Naviframe_Item *navi_it)
391 if (navi_it->title_visible)
392 elm_object_signal_emit(VIEW(navi_it), "elm,state,title,show", "elm");
394 elm_object_signal_emit(VIEW(navi_it), "elm,state,title,hide", "elm");
398 _sizing_eval(Evas_Object *obj)
401 Elm_Naviframe_Item *it;
402 Evas_Coord x, y, w, h;
403 Evas_Coord minw = -1, minh = -1;
405 wd = elm_widget_data_get(obj);
408 evas_object_geometry_get(obj, &x, &y, &w, &h);
410 EINA_INLIST_FOREACH(wd->stack, it)
412 evas_object_move(VIEW(it), x, y);
413 evas_object_resize(VIEW(it), w, h);
414 edje_object_size_min_calc(elm_layout_edje_get(VIEW(it)),
417 if (it->minw > minw) minw = it->minw;
418 if (it->minh > minh) minh = it->minh;
420 evas_object_size_hint_min_set(obj, minw, minh);
421 evas_object_size_hint_max_set(obj, -1, -1);
425 _move(void *data __UNUSED__,
428 void *event_info __UNUSED__)
434 _resize(void *data __UNUSED__,
437 void *event_info __UNUSED__)
443 _title_clicked(void *data,
444 Evas_Object *obj __UNUSED__,
445 const char *emission __UNUSED__,
446 const char *source __UNUSED__)
448 Elm_Naviframe_Item *it = data;
449 evas_object_smart_callback_call(WIDGET(it), SIG_TITLE_CLICKED, it);
453 _back_btn_clicked(void *data,
455 void *event_info __UNUSED__)
457 /* Since edje has the event queue, clicked event could be happend multiple times
458 on some heavy environment. This callback del will prevent those scenario and
459 guarantee only one clicked for it's own page. */
460 evas_object_smart_callback_del(obj, "clicked", _back_btn_clicked);
461 elm_naviframe_item_pop(data);
465 _back_btn_new(Evas_Object *obj)
469 btn = elm_button_add(obj);
470 if (!btn) return NULL;
471 evas_object_smart_callback_add(btn, "clicked", _back_btn_clicked, obj);
472 snprintf(buf, sizeof(buf), "naviframe/back_btn/%s",
473 elm_widget_style_get(obj));
474 elm_object_style_set(btn, buf);
478 static void _text_set_hook(Evas_Object *obj,
482 Elm_Object_Item *it = elm_naviframe_top_item_get(obj);
484 elm_object_item_part_text_set(it, part, label);
487 static const char *_text_get_hook(const Evas_Object *obj, const char *part)
489 Elm_Object_Item *it = elm_naviframe_top_item_get(obj);
490 if (!it) return NULL;
491 return elm_object_item_part_text_get(it, part);
495 _content_set_hook(Evas_Object *obj, const char *part, Evas_Object *content)
497 Elm_Object_Item *it = elm_naviframe_top_item_get(obj);
499 elm_object_item_part_content_set(it, part, content);
503 _content_unset_hook(Evas_Object *obj, const char *part)
505 Elm_Object_Item *it = elm_naviframe_top_item_get(obj);
506 if (!it) return NULL;
507 return elm_object_item_part_content_unset(it, part);
511 _content_get_hook(const Evas_Object *obj, const char *part)
513 Elm_Object_Item *it = elm_naviframe_top_item_get(obj);
514 if (!it) return NULL;
515 return elm_object_item_part_content_get(it, part);
519 _title_content_del(void *data,
521 Evas_Object *obj __UNUSED__,
522 void *event_info __UNUSED__)
525 Elm_Naviframe_Content_Item_Pair *pair = data;
526 Elm_Naviframe_Item *it = pair->it;
527 snprintf(buf, sizeof(buf), "elm,state,%s,hide", pair->part);
528 elm_object_signal_emit(VIEW(it), buf, "elm");
529 it->content_list = eina_inlist_remove(it->content_list,
530 EINA_INLIST_GET(pair));
531 eina_stringshare_del(pair->part);
536 _title_prev_btn_del(void *data,
538 Evas_Object *obj __UNUSED__,
539 void *event_info __UNUSED__)
541 Elm_Naviframe_Item *it = data;
542 it->back_btn = EINA_FALSE;
543 it->title_prev_btn = NULL;
544 elm_object_signal_emit(VIEW(it), "elm,state,prev_btn,hide", "elm");
548 _title_next_btn_del(void *data,
550 Evas_Object *obj __UNUSED__,
551 void *event_info __UNUSED__)
553 Elm_Naviframe_Item *it = data;
554 it->title_next_btn = NULL;
555 elm_object_signal_emit(VIEW(it), "elm,state,next_btn,hide", "elm");
559 _title_icon_del(void *data,
561 Evas_Object *obj __UNUSED__,
562 void *event_info __UNUSED__)
564 Elm_Naviframe_Item *it = data;
565 it->title_icon = NULL;
566 elm_object_signal_emit(VIEW(it), "elm,state,icon,hide", "elm");
570 _item_content_del(void *data,
572 Evas_Object *obj __UNUSED__,
573 void *event_info __UNUSED__)
575 Elm_Naviframe_Item *it = data;
577 elm_object_signal_emit(VIEW(it), "elm,state,content,hide", "elm");
581 _title_content_set(Elm_Naviframe_Item *it,
583 Evas_Object *content)
586 Elm_Naviframe_Content_Item_Pair *pair = NULL;
587 Evas_Object *prev_content = NULL;
589 EINA_INLIST_FOREACH(it->content_list, pair)
590 if (!strcmp(part, pair->part)) break;
594 prev_content = elm_object_part_content_get(VIEW(it), part);
595 if (prev_content != content)
599 evas_object_event_callback_del(prev_content,
602 snprintf(buf, sizeof(buf), "elm,state,%s,hide", part);
603 elm_object_signal_emit(VIEW(it), buf, "elm");
605 evas_object_del(prev_content);
606 if (!content) return;
611 if (!content) return;
612 pair = ELM_NEW(Elm_Naviframe_Content_Item_Pair);
615 ERR("Failed to allocate new content part of the item! : naviframe=%p", WIDGET(it));
619 eina_stringshare_replace(&pair->part, part);
620 it->content_list = eina_inlist_append(it->content_list,
621 EINA_INLIST_GET(pair));
623 if (prev_content != content)
625 evas_object_event_callback_add(content,
630 elm_object_part_content_set(VIEW(it), part, content);
631 snprintf(buf, sizeof(buf), "elm,state,%s,show", part);
632 elm_object_signal_emit(VIEW(it), buf, "elm");
634 _sizing_eval(WIDGET(it));
638 _title_prev_btn_set(Elm_Naviframe_Item *it,
642 if (it->title_prev_btn == btn) return;
643 if (it->title_prev_btn) evas_object_del(it->title_prev_btn);
644 it->title_prev_btn = btn;
647 evas_object_event_callback_add(btn,
651 elm_object_part_content_set(VIEW(it), "elm.swallow.prev_btn", btn);
652 elm_object_signal_emit(VIEW(it), "elm,state,prev_btn,show", "elm");
653 it->back_btn = back_btn;
655 _sizing_eval(WIDGET(it));
659 _title_next_btn_set(Elm_Naviframe_Item *it, Evas_Object *btn)
661 if (it->title_next_btn == btn) return;
662 if (it->title_next_btn) evas_object_del(it->title_next_btn);
663 it->title_next_btn = btn;
666 evas_object_event_callback_add(btn,
670 elm_object_part_content_set(VIEW(it), "elm.swallow.next_btn", btn);
671 elm_object_signal_emit(VIEW(it), "elm,state,next_btn,show", "elm");
673 _sizing_eval(WIDGET(it));
677 _title_icon_set(Elm_Naviframe_Item *it, Evas_Object *icon)
679 if (it->title_icon == icon) return;
680 if (it->title_icon) evas_object_del(it->title_icon);
681 it->title_icon = icon;
684 evas_object_event_callback_add(icon,
688 elm_object_part_content_set(VIEW(it), "elm.swallow.icon", icon);
689 elm_object_signal_emit(VIEW(it), "elm,state,icon,show", "elm");
691 _sizing_eval(WIDGET(it));
695 _item_content_unset(Elm_Naviframe_Item *it)
697 Evas_Object *content = it->content;
698 if (!content) return NULL;
700 elm_object_part_content_unset(VIEW(it), "elm.swallow.content");
701 elm_object_signal_emit(VIEW(it), "elm,state,content,hide", "elm");
702 evas_object_event_callback_del(content,
705 _sizing_eval(WIDGET(it));
712 _title_prev_btn_unset(Elm_Naviframe_Item *it)
714 Evas_Object *content = it->title_prev_btn;
715 if (!content) return NULL;
717 elm_object_part_content_unset(VIEW(it), "elm.swallow.prev_btn");
718 elm_object_signal_emit(VIEW(it), "elm,state,prev_btn,hide", "elm");
719 evas_object_event_callback_del(content,
721 _title_prev_btn_del);
722 _sizing_eval(WIDGET(it));
724 it->title_prev_btn = NULL;
729 _title_next_btn_unset(Elm_Naviframe_Item *it)
731 Evas_Object *content = it->title_next_btn;
732 if (!content) return NULL;
734 elm_object_part_content_unset(VIEW(it), "elm.swallow.next_btn");
735 elm_object_signal_emit(VIEW(it), "elm,state,next_btn,hide", "elm");
736 evas_object_event_callback_del(content,
738 _title_next_btn_del);
739 _sizing_eval(WIDGET(it));
741 it->title_next_btn = NULL;
746 _title_icon_unset(Elm_Naviframe_Item *it)
748 Evas_Object *content = it->title_icon;
749 if (!content) return NULL;
751 elm_object_part_content_unset(VIEW(it), "elm.swallow.icon");
752 elm_object_signal_emit(VIEW(it), "elm,state,icon,hide", "elm");
753 evas_object_event_callback_del(content,
756 _sizing_eval(WIDGET(it));
757 it->title_icon = NULL;
763 _title_content_unset(Elm_Naviframe_Item *it, const char *part)
765 Elm_Naviframe_Content_Item_Pair *pair = NULL;
767 Evas_Object *content = NULL;
769 EINA_INLIST_FOREACH(it->content_list, pair)
771 if (!strcmp(part, pair->part))
773 content = elm_object_part_content_get(VIEW(it), part);
774 eina_stringshare_del(pair->part);
775 it->content_list = eina_inlist_remove(it->content_list,
776 EINA_INLIST_GET(pair));
782 if (!content) return NULL;
784 elm_object_part_content_unset(VIEW(it), part);
785 snprintf(buf, sizeof(buf), "elm,state,%s,hide", part);
786 elm_object_signal_emit(VIEW(it), buf, "elm");
787 evas_object_event_callback_del(content,
790 _sizing_eval(WIDGET(it));
796 _item_del(Elm_Naviframe_Item *it)
799 Elm_Naviframe_Content_Item_Pair *content_pair;
800 Elm_Naviframe_Text_Item_Pair *text_pair;
801 Evas_Object *content;
805 wd = elm_widget_data_get(WIDGET(it));
808 while (it->content_list)
811 EINA_INLIST_CONTAINER_GET(it->content_list,
812 Elm_Naviframe_Content_Item_Pair);
813 content = elm_object_part_content_get(VIEW(it), content_pair->part);
814 evas_object_event_callback_del(content,
817 eina_stringshare_del(content_pair->part);
818 it->content_list = eina_inlist_remove(it->content_list,
823 while (it->text_list)
825 text_pair = EINA_INLIST_CONTAINER_GET(it->text_list,
826 Elm_Naviframe_Text_Item_Pair);
827 eina_stringshare_del(text_pair->part);
828 it->text_list = eina_inlist_remove(it->text_list,
833 eina_stringshare_del(it->style);
837 _item_del_pre_hook(Elm_Object_Item *it)
839 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
840 Elm_Naviframe_Item *navi_it;
843 navi_it =(Elm_Naviframe_Item *) it;
844 wd = elm_widget_data_get(WIDGET(navi_it));
845 if (!wd) return EINA_FALSE;
847 if (it == elm_naviframe_top_item_get(WIDGET(navi_it)))
849 wd->stack = eina_inlist_remove(wd->stack, EINA_INLIST_GET(navi_it));
851 //If the item is only one, the stack will be empty
852 if (!wd->stack) return EINA_TRUE;
853 navi_it = EINA_INLIST_CONTAINER_GET(wd->stack->last,
855 evas_object_show(VIEW(navi_it));
856 evas_object_raise(VIEW(navi_it));
857 elm_object_signal_emit(VIEW(navi_it), "elm,state,visible", "elm");
861 wd->stack = eina_inlist_remove(wd->stack, EINA_INLIST_GET(navi_it));
869 _pushed_finished(void *data,
870 Evas_Object *obj __UNUSED__,
871 const char *emission __UNUSED__,
872 const char *source __UNUSED__)
875 Elm_Naviframe_Item *it = data;
878 wd = elm_widget_data_get(WIDGET(it));
881 evas_object_hide(VIEW(it));
882 if (wd->freeze_events)
883 evas_object_freeze_events_set(VIEW(it), EINA_FALSE);
885 elm_widget_item_smart_callback_call(it,
886 SIG_ITEM_HIDE_FINISHED,
891 _popped_finished(void *data,
892 Evas_Object *obj __UNUSED__,
893 const char *emission __UNUSED__,
894 const char *source __UNUSED__)
896 Elm_Naviframe_Item *it = data;
899 elm_widget_item_free(data);
903 _show_finished(void *data,
904 Evas_Object *obj __UNUSED__,
905 const char *emission __UNUSED__,
906 const char *source __UNUSED__)
908 Elm_Naviframe_Item *it;
913 wd = elm_widget_data_get(WIDGET(it));
916 evas_object_smart_callback_call(WIDGET(it),
917 SIG_TRANSITION_FINISHED,
919 if (wd->freeze_events)
920 evas_object_freeze_events_set(VIEW(it), EINA_FALSE);
924 _changed_size_hints(void *data,
926 Evas_Object *obj __UNUSED__,
927 void *event_info __UNUSED__)
933 _item_content_set(Elm_Naviframe_Item *navi_it, Evas_Object *content)
935 if (navi_it->content == content) return;
936 if (navi_it->content) evas_object_del(navi_it->content);
937 elm_object_part_content_set(VIEW(navi_it), "elm.swallow.content", content);
940 elm_object_signal_emit(VIEW(navi_it), "elm,state,content,show", "elm");
942 elm_object_signal_emit(VIEW(navi_it), "elm,state,content,hide", "elm");
944 evas_object_event_callback_add(content,
948 navi_it->content = content;
949 _sizing_eval(WIDGET(navi_it));
952 //FIXME: need to handle if this function is called while transition
954 _item_style_set(Elm_Naviframe_Item *navi_it, const char *item_style)
956 Elm_Naviframe_Content_Item_Pair *content_pair;
957 Elm_Naviframe_Text_Item_Pair *text_pair;
959 wd = elm_widget_data_get(WIDGET(navi_it));
966 snprintf(buf, sizeof(buf), "item/%s", wd->item_style);
970 snprintf(buf, sizeof(buf), "item/%s", item_style);
971 eina_stringshare_replace(&navi_it->style, item_style);
973 elm_layout_theme_set(VIEW(navi_it),
976 elm_widget_style_get(WIDGET(navi_it)));
978 EINA_INLIST_FOREACH(navi_it->text_list, text_pair)
979 _item_text_set_hook((Elm_Object_Item *) navi_it,
981 elm_object_part_text_get(VIEW(navi_it),
984 EINA_INLIST_FOREACH(navi_it->content_list, content_pair)
985 _item_content_set_hook((Elm_Object_Item *) navi_it,
987 elm_object_part_content_get(VIEW(navi_it),
988 content_pair->part));
990 if (navi_it->content)
991 elm_object_signal_emit(VIEW(navi_it), "elm,state,content,show", "elm");
994 if (navi_it->title_prev_btn)
995 elm_object_signal_emit(VIEW(navi_it), "elm,state,prev_btn,show", "elm");
998 if (navi_it->title_next_btn)
999 elm_object_signal_emit(VIEW(navi_it), "elm,state,next_btn,show", "elm");
1001 navi_it->title_visible = EINA_TRUE;
1002 _sizing_eval(WIDGET(navi_it));
1004 if (wd->freeze_events)
1005 evas_object_freeze_events_set(VIEW(navi_it), EINA_FALSE);
1008 static Elm_Naviframe_Item *
1009 _item_new(Evas_Object *obj,
1010 const char *title_label,
1011 Evas_Object *prev_btn,
1012 Evas_Object *next_btn,
1013 Evas_Object *content,
1014 const char *item_style)
1016 Widget_Data *wd = elm_widget_data_get(obj);
1019 Elm_Naviframe_Item *it = elm_widget_item_new(obj, Elm_Naviframe_Item);
1022 ERR("Failed to allocate new item! : naviframe=%p", obj);
1026 elm_widget_item_del_pre_hook_set(it, _item_del_pre_hook);
1027 elm_widget_item_text_set_hook_set(it, _item_text_set_hook);
1028 elm_widget_item_text_get_hook_set(it, _item_text_get_hook);
1029 elm_widget_item_content_set_hook_set(it, _item_content_set_hook);
1030 elm_widget_item_content_get_hook_set(it, _item_content_get_hook);
1031 elm_widget_item_content_unset_hook_set(it, _item_content_unset_hook);
1032 elm_widget_item_signal_emit_hook_set(it, _item_signal_emit_hook);
1035 VIEW(it) = elm_layout_add(obj);
1036 evas_object_smart_member_add(VIEW(it), wd->base);
1038 evas_object_event_callback_add(VIEW(it),
1039 EVAS_CALLBACK_CHANGED_SIZE_HINTS,
1040 _changed_size_hints,
1042 elm_object_signal_callback_add(VIEW(it),
1043 "elm,action,show,finished",
1045 _show_finished, it);
1046 elm_object_signal_callback_add(VIEW(it),
1047 "elm,action,pushed,finished",
1049 _pushed_finished, it);
1050 elm_object_signal_callback_add(VIEW(it),
1051 "elm,action,popped,finished",
1053 _popped_finished, it);
1054 elm_object_signal_callback_add(VIEW(it),
1055 "elm,action,title,clicked",
1057 _title_clicked, it);
1059 _item_style_set(it, item_style);
1060 _item_text_set_hook((Elm_Object_Item *) it, "elm.text.title", title_label);
1063 if ((!prev_btn) && wd->auto_pushed && eina_inlist_count(wd->stack))
1065 prev_btn = _back_btn_new(obj);
1066 _title_prev_btn_set(it, prev_btn, EINA_TRUE);
1069 _title_prev_btn_set(it, prev_btn, EINA_FALSE);
1071 _title_next_btn_set(it, next_btn);
1072 _item_content_set(it, content);
1073 it->title_visible = EINA_TRUE;
1078 _focus_next_hook(const Evas_Object *obj, Elm_Focus_Direction dir, Evas_Object **next)
1080 Widget_Data *wd = elm_widget_data_get(obj);
1081 if (!wd || !wd->stack) return EINA_FALSE;
1082 return elm_widget_focus_next_get(VIEW(elm_naviframe_top_item_get(obj)),
1088 elm_naviframe_add(Evas_Object *parent)
1094 ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL);
1095 ELM_SET_WIDTYPE(widtype, "naviframe");
1096 elm_widget_type_set(obj, "naviframe");
1097 elm_widget_sub_object_add(parent, obj);
1098 elm_widget_data_set(obj, wd);
1099 elm_widget_del_hook_set(obj, _del_hook);
1100 elm_widget_disable_hook_set(obj, _disable_hook);
1101 elm_widget_theme_hook_set(obj, _theme_hook);
1102 elm_widget_text_set_hook_set(obj, _text_set_hook);
1103 elm_widget_text_get_hook_set(obj, _text_get_hook);
1104 elm_widget_content_set_hook_set(obj, _content_set_hook);
1105 elm_widget_content_get_hook_set(obj, _content_get_hook);
1106 elm_widget_content_unset_hook_set(obj, _content_unset_hook);
1107 elm_widget_signal_emit_hook_set(obj, _emit_hook);
1108 elm_widget_can_focus_set(obj, EINA_FALSE);
1109 elm_widget_focus_next_hook_set(obj, _focus_next_hook);
1112 //FIXME: Is this base layout really needed?
1113 wd->base = elm_layout_add(parent);
1114 evas_object_event_callback_add(wd->base,
1115 EVAS_CALLBACK_CHANGED_SIZE_HINTS,
1116 _changed_size_hints,
1118 elm_widget_resize_object_set(obj, wd->base);
1119 elm_layout_theme_set(wd->base, "naviframe", "base", "default");
1121 evas_object_event_callback_add(obj, EVAS_CALLBACK_MOVE, _move, obj);
1122 evas_object_event_callback_add(obj, EVAS_CALLBACK_RESIZE, _resize, obj);
1123 evas_object_smart_callbacks_descriptions_set(obj, _signals);
1125 wd->auto_pushed = EINA_TRUE;
1126 wd->freeze_events = EINA_TRUE;
1127 wd->item_style = eina_stringshare_add("basic");
1132 EAPI Elm_Object_Item *
1133 elm_naviframe_item_push(Evas_Object *obj,
1134 const char *title_label,
1135 Evas_Object *prev_btn,
1136 Evas_Object *next_btn,
1137 Evas_Object *content,
1138 const char *item_style)
1140 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1142 Elm_Naviframe_Item *prev_it, *it;
1144 wd = elm_widget_data_get(obj);
1145 if (!wd) return NULL;
1147 it = _item_new(obj, title_label, prev_btn, next_btn, content, item_style);
1148 if (!it) return NULL;
1150 evas_object_show(VIEW(it));
1152 prev_it = (Elm_Naviframe_Item *) elm_naviframe_top_item_get(obj);
1155 if (wd->freeze_events)
1157 evas_object_freeze_events_set(VIEW(it), EINA_TRUE);
1158 evas_object_freeze_events_set(VIEW(prev_it), EINA_TRUE);
1160 elm_object_signal_emit(VIEW(prev_it), "elm,state,cur,pushed", "elm");
1161 elm_object_signal_emit(VIEW(it), "elm,state,new,pushed", "elm");
1162 edje_object_message_signal_process(elm_layout_edje_get(VIEW(prev_it)));
1163 edje_object_message_signal_process(elm_layout_edje_get(VIEW(it)));
1165 wd->stack = eina_inlist_append(wd->stack, EINA_INLIST_GET(it));
1167 return (Elm_Object_Item *) it;
1170 EAPI Elm_Object_Item *
1171 elm_naviframe_item_insert_before(Elm_Object_Item *before,
1172 const char *title_label,
1173 Evas_Object *prev_btn,
1174 Evas_Object *next_btn,
1175 Evas_Object *content,
1176 const char *item_style)
1178 ELM_OBJ_ITEM_CHECK_OR_RETURN(before, NULL);
1179 Elm_Naviframe_Item *it;
1182 wd = elm_widget_data_get(WIDGET(before));
1183 if (!wd) return NULL;
1185 it = _item_new(WIDGET(before), title_label, prev_btn, next_btn, content,
1187 if (!it) return NULL;
1190 eina_inlist_prepend_relative(wd->stack,
1191 EINA_INLIST_GET(it),
1192 EINA_INLIST_GET(((Elm_Naviframe_Item *) before)));
1193 _sizing_eval(WIDGET(before));
1194 return (Elm_Object_Item *) it;
1197 EAPI Elm_Object_Item *
1198 elm_naviframe_item_insert_after(Elm_Object_Item *after,
1199 const char *title_label,
1200 Evas_Object *prev_btn,
1201 Evas_Object *next_btn,
1202 Evas_Object *content,
1203 const char *item_style)
1205 ELM_OBJ_ITEM_CHECK_OR_RETURN(after, NULL);
1206 Elm_Naviframe_Item *it;
1209 wd = elm_widget_data_get(WIDGET(after));
1210 if (!wd) return NULL;
1212 it = _item_new(WIDGET(after), title_label, prev_btn, next_btn, content,
1214 if (!it) return NULL;
1216 if (elm_naviframe_top_item_get(WIDGET(after)) == after)
1218 evas_object_hide(VIEW(after));
1219 evas_object_show(VIEW(it));
1222 eina_inlist_append_relative(wd->stack,
1223 EINA_INLIST_GET(it),
1224 EINA_INLIST_GET(((Elm_Naviframe_Item *) after)));
1225 _sizing_eval(WIDGET(after));
1226 return (Elm_Object_Item *) it;
1230 elm_naviframe_item_pop(Evas_Object *obj)
1232 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1233 Elm_Naviframe_Item *it, *prev_it = NULL;
1235 Evas_Object *content = NULL;
1237 wd = elm_widget_data_get(obj);
1238 if (!wd) return NULL;
1240 it = (Elm_Naviframe_Item *) elm_naviframe_top_item_get(obj);
1241 if (!it) return NULL;
1242 elm_widget_tree_unfocusable_set(it->content, EINA_TRUE);
1244 content = it->content;
1246 if (wd->stack->last->prev)
1247 prev_it = EINA_INLIST_CONTAINER_GET(wd->stack->last->prev,
1248 Elm_Naviframe_Item);
1249 wd->stack = eina_inlist_remove(wd->stack, EINA_INLIST_GET(it));
1252 if (wd->freeze_events)
1254 evas_object_freeze_events_set(VIEW(it), EINA_TRUE);
1255 evas_object_freeze_events_set(VIEW(prev_it), EINA_TRUE);
1257 elm_object_signal_emit(VIEW(it), "elm,state,cur,popped", "elm");
1258 evas_object_show(VIEW(prev_it));
1259 evas_object_raise(VIEW(prev_it));
1260 elm_object_signal_emit(VIEW(prev_it),
1261 "elm,state,prev,popped",
1263 edje_object_message_signal_process(elm_layout_edje_get(VIEW(it)));
1264 edje_object_message_signal_process(elm_layout_edje_get(VIEW(prev_it)));
1265 elm_widget_item_smart_callback_call(prev_it,
1266 SIG_ITEM_SHOW_BEGIN,
1272 elm_widget_item_free(it);
1279 elm_naviframe_item_pop_to(Elm_Object_Item *it)
1281 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1282 Elm_Naviframe_Item *navi_it;
1284 Eina_Inlist *l, *prev_l;
1286 navi_it = (Elm_Naviframe_Item *) it;
1287 wd = elm_widget_data_get(WIDGET(navi_it));
1290 if (it == elm_naviframe_top_item_get(WIDGET(navi_it))) return;
1292 l = wd->stack->last->prev;
1296 if (EINA_INLIST_CONTAINER_GET(l, Elm_Naviframe_Item) ==
1297 ((Elm_Naviframe_Item *) it)) break;
1299 wd->stack = eina_inlist_remove(wd->stack, l);
1300 _item_del(EINA_INLIST_CONTAINER_GET(l, Elm_Naviframe_Item));
1301 elm_widget_item_free(EINA_INLIST_CONTAINER_GET(l,
1302 Elm_Naviframe_Item));
1305 elm_naviframe_item_pop(WIDGET(navi_it));
1309 elm_naviframe_item_promote(Elm_Object_Item *it)
1311 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1312 Elm_Naviframe_Item *navi_it;
1313 Elm_Naviframe_Item *prev_it;
1316 navi_it = (Elm_Naviframe_Item *) it;
1317 wd = elm_widget_data_get(navi_it->base.widget);
1320 if (it == elm_naviframe_top_item_get(navi_it->base.widget)) return;
1321 wd->stack = eina_inlist_demote(wd->stack, EINA_INLIST_GET(navi_it));
1322 prev_it = EINA_INLIST_CONTAINER_GET(wd->stack->last->prev,
1323 Elm_Naviframe_Item);
1324 if (wd->freeze_events)
1326 evas_object_freeze_events_set(VIEW(it), EINA_TRUE);
1327 evas_object_freeze_events_set(VIEW(prev_it), EINA_TRUE);
1329 elm_object_signal_emit(VIEW(prev_it),
1330 "elm,state,cur,pushed",
1332 evas_object_show(VIEW(navi_it));
1333 evas_object_raise(VIEW(navi_it));
1334 elm_object_signal_emit(VIEW(navi_it),
1335 "elm,state,new,pushed",
1337 edje_object_message_signal_process(elm_layout_edje_get(VIEW(prev_it)));
1338 edje_object_message_signal_process(elm_layout_edje_get(VIEW(navi_it)));
1342 elm_naviframe_item_simple_promote(Evas_Object *obj, Evas_Object *content)
1344 ELM_CHECK_WIDTYPE(obj, widtype);
1345 Widget_Data *wd = elm_widget_data_get(obj);
1347 Elm_Naviframe_Item *itr;
1348 EINA_INLIST_FOREACH(wd->stack, itr)
1350 if (elm_object_item_content_get((Elm_Object_Item *) itr) == content)
1352 elm_naviframe_item_promote((Elm_Object_Item *) itr);
1360 elm_naviframe_item_del(Elm_Object_Item *it)
1362 elm_object_item_del(it);
1366 elm_naviframe_content_preserve_on_pop_set(Evas_Object *obj, Eina_Bool preserve)
1368 ELM_CHECK_WIDTYPE(obj, widtype);
1369 Widget_Data *wd = elm_widget_data_get(obj);
1371 wd->preserve = !!preserve;
1375 elm_naviframe_content_preserve_on_pop_get(const Evas_Object *obj)
1377 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
1378 Widget_Data *wd = elm_widget_data_get(obj);
1379 if (!wd) return EINA_FALSE;
1380 return wd->preserve;
1383 EAPI Elm_Object_Item*
1384 elm_naviframe_top_item_get(const Evas_Object *obj)
1386 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1387 Widget_Data *wd = elm_widget_data_get(obj);
1388 if ((!wd) || (!wd->stack)) return NULL;
1389 return (Elm_Object_Item *) (EINA_INLIST_CONTAINER_GET(wd->stack->last,
1390 Elm_Naviframe_Item));
1393 EAPI Elm_Object_Item*
1394 elm_naviframe_bottom_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,
1400 Elm_Naviframe_Item));
1404 elm_naviframe_item_style_set(Elm_Object_Item *it, const char *item_style)
1406 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1407 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
1409 //Return if new style is exsiting one.
1410 if ((item_style && navi_it->style) && (!strcmp(item_style, navi_it->style)))
1413 if ((!item_style) && (!navi_it->style))
1416 _item_style_set(navi_it, item_style);
1420 elm_naviframe_item_style_get(const Elm_Object_Item *it)
1422 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
1423 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
1424 return navi_it->style;
1428 elm_naviframe_item_title_visible_set(Elm_Object_Item *it, Eina_Bool visible)
1430 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1431 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
1433 visible = !!visible;
1434 if (navi_it->title_visible == visible) return;
1436 navi_it->title_visible = visible;
1437 _item_title_visible_update(navi_it);
1441 elm_naviframe_item_title_visible_get(const Elm_Object_Item *it)
1443 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
1444 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
1445 return navi_it->title_visible;
1449 elm_naviframe_prev_btn_auto_pushed_set(Evas_Object *obj, Eina_Bool auto_pushed)
1451 ELM_CHECK_WIDTYPE(obj, widtype);
1452 Widget_Data *wd = elm_widget_data_get(obj);
1454 wd->auto_pushed = !!auto_pushed;
1458 elm_naviframe_prev_btn_auto_pushed_get(const Evas_Object *obj)
1460 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
1461 Widget_Data *wd = elm_widget_data_get(obj);
1462 if (!wd) return EINA_FALSE;
1463 return wd->auto_pushed;
1467 elm_naviframe_items_get(const Evas_Object *obj)
1469 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1470 Widget_Data *wd = elm_widget_data_get(obj);
1471 if (!wd) return NULL;
1472 Eina_List *ret = NULL;
1473 Elm_Naviframe_Item *itr;
1474 EINA_INLIST_FOREACH(wd->stack, itr)
1476 ret = eina_list_append(ret, itr);
1482 elm_naviframe_event_enabled_set(Evas_Object *obj, Eina_Bool enabled)
1484 ELM_CHECK_WIDTYPE(obj, widtype);
1485 Widget_Data *wd = elm_widget_data_get(obj);
1487 enabled = !!enabled;
1488 if (wd->freeze_events == !enabled) return;
1489 wd->freeze_events = !enabled;
1493 elm_naviframe_event_enabled_get(const Evas_Object *obj)
1495 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
1496 Widget_Data *wd = elm_widget_data_get(obj);
1497 if (!wd) return EINA_FALSE;
1498 return !wd->freeze_events;
1502 elm_naviframe_item_style_default_set(Evas_Object *obj, const char *style)
1504 ELM_CHECK_WIDTYPE(obj, widtype);
1505 Widget_Data *wd = elm_widget_data_get(obj);
1507 eina_stringshare_replace(&wd->item_style, style);
1512 elm_naviframe_item_style_default_get(const Evas_Object *obj)
1514 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1515 Widget_Data *wd = elm_widget_data_get(obj);
1516 if (!wd) return NULL;
1517 return wd->item_style;