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);
222 _item_title_visible_update(it);
225 static void _emit_hook(Evas_Object *obj,
226 const char *emission,
229 Elm_Object_Item *it = elm_naviframe_top_item_get(obj);
231 return elm_object_item_signal_emit(it, emission, source);
235 _disable_hook(Evas_Object *obj __UNUSED__)
241 _item_text_set_hook(Elm_Object_Item *it,
245 Elm_Naviframe_Text_Item_Pair *pair = NULL;
246 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
249 if (!part || !strcmp(part, "default"))
250 snprintf(buf, sizeof(buf), "elm.text.title");
251 else if(!strcmp("subtitle", part))
252 snprintf(buf, sizeof(buf), "elm.text.subtitle");
254 snprintf(buf, sizeof(buf), "%s", part);
256 EINA_INLIST_FOREACH(navi_it->text_list, pair)
257 if (!strcmp(buf, pair->part)) break;
261 pair = ELM_NEW(Elm_Naviframe_Text_Item_Pair);
264 ERR("Failed to allocate new text part of the item! : naviframe=%p",
268 eina_stringshare_replace(&pair->part, buf);
269 navi_it->text_list = eina_inlist_append(navi_it->text_list,
270 EINA_INLIST_GET(pair));
272 elm_object_part_text_set(VIEW(navi_it), buf, label);
276 snprintf(buf, sizeof(buf), "elm,state,%s,show", buf);
277 elm_object_signal_emit(VIEW(navi_it), buf, "elm");
281 snprintf(buf, sizeof(buf), "elm,state,%s,hide", buf);
282 elm_object_signal_emit(VIEW(navi_it), buf, "elm");
285 _sizing_eval(WIDGET(navi_it));
289 _item_text_get_hook(const Elm_Object_Item *it, const char *part)
293 if (!part || !strcmp(part, "default"))
294 snprintf(buf, sizeof(buf), "elm.text.title");
295 else if(!strcmp("subtitle", part))
296 snprintf(buf, sizeof(buf), "elm.text.subtitle");
298 snprintf(buf, sizeof(buf), "%s", part);
300 return elm_object_part_text_get(VIEW(it), buf);
304 _item_content_set_hook(Elm_Object_Item *it,
306 Evas_Object *content)
308 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
311 if (!part || !strcmp("default", part))
313 _item_content_set(navi_it, content);
316 else if (!strcmp(part, "prev_btn"))
318 _title_prev_btn_set(navi_it, content, EINA_FALSE);
321 else if (!strcmp(part, "next_btn"))
323 _title_next_btn_set(navi_it, content);
326 else if (!strcmp(part, "icon"))
328 _title_icon_set(navi_it, content);
333 _title_content_set(navi_it, part, content);
337 _item_content_get_hook(const Elm_Object_Item *it, const char *part)
339 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
342 if (!part || !strcmp("default", part))
343 return navi_it->content;
344 else if (!strcmp(part, "prev_btn"))
345 return navi_it->title_prev_btn;
346 else if (!strcmp(part, "next_btn"))
347 return navi_it->title_next_btn;
348 else if (!strcmp(part, "icon"))
349 return navi_it->title_icon;
352 return elm_object_part_content_get(VIEW(navi_it), part);
356 _item_content_unset_hook(Elm_Object_Item *it, const char *part)
358 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
361 if (!part || !strcmp("default", part))
362 return _item_content_unset(navi_it);
363 else if (!strcmp(part, "prev_btn"))
364 return _title_prev_btn_unset(navi_it);
365 else if (!strcmp(part, "next_btn"))
366 return _title_next_btn_unset(navi_it);
367 else if (!strcmp(part, "icon"))
368 return _title_icon_unset(navi_it);
370 return _title_content_unset(navi_it, part);
374 _item_signal_emit_hook(Elm_Object_Item *it,
375 const char *emission,
378 elm_object_signal_emit(VIEW(it), emission, source);
382 _item_title_visible_update(Elm_Naviframe_Item *navi_it)
384 if (navi_it->title_visible)
385 elm_object_signal_emit(VIEW(navi_it), "elm,state,title,show", "elm");
387 elm_object_signal_emit(VIEW(navi_it), "elm,state,title,hide", "elm");
391 _sizing_eval(Evas_Object *obj)
394 Elm_Naviframe_Item *it;
395 Evas_Coord x, y, w, h;
396 Evas_Coord minw = -1, minh = -1;
398 wd = elm_widget_data_get(obj);
401 evas_object_geometry_get(obj, &x, &y, &w, &h);
403 EINA_INLIST_FOREACH(wd->stack, it)
405 evas_object_move(VIEW(it), x, y);
406 evas_object_resize(VIEW(it), w, h);
407 edje_object_size_min_calc(elm_layout_edje_get(VIEW(it)),
410 if (it->minw > minw) minw = it->minw;
411 if (it->minh > minh) minh = it->minh;
413 evas_object_size_hint_min_set(obj, minw, minh);
414 evas_object_size_hint_max_set(obj, -1, -1);
418 _move(void *data __UNUSED__,
421 void *event_info __UNUSED__)
427 _resize(void *data __UNUSED__,
430 void *event_info __UNUSED__)
436 _title_clicked(void *data,
437 Evas_Object *obj __UNUSED__,
438 const char *emission __UNUSED__,
439 const char *source __UNUSED__)
441 Elm_Naviframe_Item *it = data;
442 evas_object_smart_callback_call(WIDGET(it), SIG_TITLE_CLICKED, it);
446 _back_btn_clicked(void *data,
448 void *event_info __UNUSED__)
450 /* Since edje has the event queue, clicked event could be happend multiple times
451 on some heavy environment. This callback del will prevent those scenario and
452 guarantee only one clicked for it's own page. */
453 evas_object_smart_callback_del(obj, "clicked", _back_btn_clicked);
454 elm_naviframe_item_pop(data);
458 _back_btn_new(Evas_Object *obj)
462 btn = elm_button_add(obj);
463 if (!btn) return NULL;
464 evas_object_smart_callback_add(btn, "clicked", _back_btn_clicked, obj);
465 snprintf(buf, sizeof(buf), "naviframe/back_btn/%s",
466 elm_widget_style_get(obj));
467 elm_object_style_set(btn, buf);
471 static void _text_set_hook(Evas_Object *obj,
475 Elm_Object_Item *it = elm_naviframe_top_item_get(obj);
477 elm_object_item_part_text_set(it, part, label);
480 static const char *_text_get_hook(const Evas_Object *obj, const char *part)
482 Elm_Object_Item *it = elm_naviframe_top_item_get(obj);
483 if (!it) return NULL;
484 return elm_object_item_part_text_get(it, part);
488 _content_set_hook(Evas_Object *obj, const char *part, Evas_Object *content)
490 Elm_Object_Item *it = elm_naviframe_top_item_get(obj);
492 elm_object_item_part_content_set(it, part, content);
496 _content_unset_hook(Evas_Object *obj, const char *part)
498 Elm_Object_Item *it = elm_naviframe_top_item_get(obj);
499 if (!it) return NULL;
500 return elm_object_item_part_content_unset(it, part);
504 _content_get_hook(const Evas_Object *obj, const char *part)
506 Elm_Object_Item *it = elm_naviframe_top_item_get(obj);
507 if (!it) return NULL;
508 return elm_object_item_part_content_get(it, part);
512 _title_content_del(void *data,
514 Evas_Object *obj __UNUSED__,
515 void *event_info __UNUSED__)
518 Elm_Naviframe_Content_Item_Pair *pair = data;
519 Elm_Naviframe_Item *it = pair->it;
520 snprintf(buf, sizeof(buf), "elm,state,%s,hide", pair->part);
521 elm_object_signal_emit(VIEW(it), buf, "elm");
522 it->content_list = eina_inlist_remove(it->content_list,
523 EINA_INLIST_GET(pair));
524 eina_stringshare_del(pair->part);
529 _title_prev_btn_del(void *data,
531 Evas_Object *obj __UNUSED__,
532 void *event_info __UNUSED__)
534 Elm_Naviframe_Item *it = data;
535 it->back_btn = EINA_FALSE;
536 it->title_prev_btn = NULL;
537 elm_object_signal_emit(VIEW(it), "elm,state,prev_btn,hide", "elm");
541 _title_next_btn_del(void *data,
543 Evas_Object *obj __UNUSED__,
544 void *event_info __UNUSED__)
546 Elm_Naviframe_Item *it = data;
547 it->title_next_btn = NULL;
548 elm_object_signal_emit(VIEW(it), "elm,state,next_btn,hide", "elm");
552 _title_icon_del(void *data,
554 Evas_Object *obj __UNUSED__,
555 void *event_info __UNUSED__)
557 Elm_Naviframe_Item *it = data;
558 it->title_icon = NULL;
559 elm_object_signal_emit(VIEW(it), "elm,state,icon,hide", "elm");
563 _item_content_del(void *data,
565 Evas_Object *obj __UNUSED__,
566 void *event_info __UNUSED__)
568 Elm_Naviframe_Item *it = data;
570 elm_object_signal_emit(VIEW(it), "elm,state,content,hide", "elm");
574 _title_content_set(Elm_Naviframe_Item *it,
576 Evas_Object *content)
579 Elm_Naviframe_Content_Item_Pair *pair = NULL;
580 Evas_Object *prev_content = NULL;
582 EINA_INLIST_FOREACH(it->content_list, pair)
583 if (!strcmp(part, pair->part)) break;
587 prev_content = elm_object_part_content_get(VIEW(it), part);
588 if (prev_content != content)
592 evas_object_event_callback_del(prev_content,
595 snprintf(buf, sizeof(buf), "elm,state,%s,hide", part);
596 elm_object_signal_emit(VIEW(it), buf, "elm");
598 evas_object_del(prev_content);
599 if (!content) return;
604 if (!content) return;
605 pair = ELM_NEW(Elm_Naviframe_Content_Item_Pair);
608 ERR("Failed to allocate new content part of the item! : naviframe=%p", WIDGET(it));
612 eina_stringshare_replace(&pair->part, part);
613 it->content_list = eina_inlist_append(it->content_list,
614 EINA_INLIST_GET(pair));
616 if (prev_content != content)
618 evas_object_event_callback_add(content,
623 elm_object_part_content_set(VIEW(it), part, content);
624 snprintf(buf, sizeof(buf), "elm,state,%s,show", part);
625 elm_object_signal_emit(VIEW(it), buf, "elm");
627 _sizing_eval(WIDGET(it));
631 _title_prev_btn_set(Elm_Naviframe_Item *it,
635 if (it->title_prev_btn == btn) return;
636 if (it->title_prev_btn) evas_object_del(it->title_prev_btn);
637 it->title_prev_btn = btn;
640 evas_object_event_callback_add(btn,
644 elm_object_part_content_set(VIEW(it), "elm.swallow.prev_btn", btn);
645 elm_object_signal_emit(VIEW(it), "elm,state,prev_btn,show", "elm");
646 it->back_btn = back_btn;
648 _sizing_eval(WIDGET(it));
652 _title_next_btn_set(Elm_Naviframe_Item *it, Evas_Object *btn)
654 if (it->title_next_btn == btn) return;
655 if (it->title_next_btn) evas_object_del(it->title_next_btn);
656 it->title_next_btn = btn;
659 evas_object_event_callback_add(btn,
663 elm_object_part_content_set(VIEW(it), "elm.swallow.next_btn", btn);
664 elm_object_signal_emit(VIEW(it), "elm,state,next_btn,show", "elm");
666 _sizing_eval(WIDGET(it));
670 _title_icon_set(Elm_Naviframe_Item *it, Evas_Object *icon)
672 if (it->title_icon == icon) return;
673 if (it->title_icon) evas_object_del(it->title_icon);
674 it->title_icon = icon;
677 evas_object_event_callback_add(icon,
681 elm_object_part_content_set(VIEW(it), "elm.swallow.icon", icon);
682 elm_object_signal_emit(VIEW(it), "elm,state,icon,show", "elm");
684 _sizing_eval(WIDGET(it));
688 _item_content_unset(Elm_Naviframe_Item *it)
690 Evas_Object *content = it->content;
691 if (!content) return NULL;
693 elm_object_part_content_unset(VIEW(it), "elm.swallow.content");
694 elm_object_signal_emit(VIEW(it), "elm,state,content,hide", "elm");
695 evas_object_event_callback_del(content,
698 _sizing_eval(WIDGET(it));
705 _title_prev_btn_unset(Elm_Naviframe_Item *it)
707 Evas_Object *content = it->title_prev_btn;
708 if (!content) return NULL;
710 elm_object_part_content_unset(VIEW(it), "elm.swallow.prev_btn");
711 elm_object_signal_emit(VIEW(it), "elm,state,prev_btn,hide", "elm");
712 evas_object_event_callback_del(content,
714 _title_prev_btn_del);
715 _sizing_eval(WIDGET(it));
717 it->title_prev_btn = NULL;
722 _title_next_btn_unset(Elm_Naviframe_Item *it)
724 Evas_Object *content = it->title_next_btn;
725 if (!content) return NULL;
727 elm_object_part_content_unset(VIEW(it), "elm.swallow.next_btn");
728 elm_object_signal_emit(VIEW(it), "elm,state,next_btn,hide", "elm");
729 evas_object_event_callback_del(content,
731 _title_next_btn_del);
732 _sizing_eval(WIDGET(it));
734 it->title_next_btn = NULL;
739 _title_icon_unset(Elm_Naviframe_Item *it)
741 Evas_Object *content = it->title_icon;
742 if (!content) return NULL;
744 elm_object_part_content_unset(VIEW(it), "elm.swallow.icon");
745 elm_object_signal_emit(VIEW(it), "elm,state,icon,hide", "elm");
746 evas_object_event_callback_del(content,
749 _sizing_eval(WIDGET(it));
750 it->title_icon = NULL;
756 _title_content_unset(Elm_Naviframe_Item *it, const char *part)
758 Elm_Naviframe_Content_Item_Pair *pair = NULL;
760 Evas_Object *content = NULL;
762 EINA_INLIST_FOREACH(it->content_list, pair)
764 if (!strcmp(part, pair->part))
766 content = elm_object_part_content_get(VIEW(it), part);
767 eina_stringshare_del(pair->part);
768 it->content_list = eina_inlist_remove(it->content_list,
769 EINA_INLIST_GET(pair));
775 if (!content) return NULL;
777 elm_object_part_content_unset(VIEW(it), part);
778 snprintf(buf, sizeof(buf), "elm,state,%s,hide", part);
779 elm_object_signal_emit(VIEW(it), buf, "elm");
780 evas_object_event_callback_del(content,
783 _sizing_eval(WIDGET(it));
789 _item_del(Elm_Naviframe_Item *it)
792 Elm_Naviframe_Content_Item_Pair *content_pair;
793 Elm_Naviframe_Text_Item_Pair *text_pair;
794 Evas_Object *content;
798 wd = elm_widget_data_get(WIDGET(it));
801 while (it->content_list)
804 EINA_INLIST_CONTAINER_GET(it->content_list,
805 Elm_Naviframe_Content_Item_Pair);
806 content = elm_object_part_content_get(VIEW(it), content_pair->part);
807 evas_object_event_callback_del(content,
810 eina_stringshare_del(content_pair->part);
811 it->content_list = eina_inlist_remove(it->content_list,
816 while (it->text_list)
818 text_pair = EINA_INLIST_CONTAINER_GET(it->text_list,
819 Elm_Naviframe_Text_Item_Pair);
820 eina_stringshare_del(text_pair->part);
821 it->text_list = eina_inlist_remove(it->text_list,
826 eina_stringshare_del(it->style);
830 _item_del_pre_hook(Elm_Object_Item *it)
832 Elm_Naviframe_Item *navi_it;
835 navi_it =(Elm_Naviframe_Item *) it;
836 wd = elm_widget_data_get(WIDGET(navi_it));
837 if (!wd) return EINA_FALSE;
839 if (it == elm_naviframe_top_item_get(WIDGET(navi_it)))
841 wd->stack = eina_inlist_remove(wd->stack, EINA_INLIST_GET(navi_it));
843 //If the item is only one, the stack will be empty
844 if (!wd->stack) return EINA_TRUE;
845 navi_it = EINA_INLIST_CONTAINER_GET(wd->stack->last,
847 evas_object_show(VIEW(navi_it));
848 evas_object_raise(VIEW(navi_it));
849 elm_object_signal_emit(VIEW(navi_it), "elm,state,visible", "elm");
853 wd->stack = eina_inlist_remove(wd->stack, EINA_INLIST_GET(navi_it));
861 _pushed_finished(void *data,
862 Evas_Object *obj __UNUSED__,
863 const char *emission __UNUSED__,
864 const char *source __UNUSED__)
867 Elm_Naviframe_Item *it = data;
870 wd = elm_widget_data_get(WIDGET(it));
873 evas_object_hide(VIEW(it));
874 if (wd->freeze_events)
875 evas_object_freeze_events_set(VIEW(it), EINA_FALSE);
877 elm_widget_item_smart_callback_call(it,
878 SIG_ITEM_HIDE_FINISHED,
883 _popped_finished(void *data,
884 Evas_Object *obj __UNUSED__,
885 const char *emission __UNUSED__,
886 const char *source __UNUSED__)
888 Elm_Naviframe_Item *it = data;
891 elm_widget_item_free(data);
895 _show_finished(void *data,
896 Evas_Object *obj __UNUSED__,
897 const char *emission __UNUSED__,
898 const char *source __UNUSED__)
900 Elm_Naviframe_Item *it;
905 wd = elm_widget_data_get(WIDGET(it));
908 evas_object_smart_callback_call(WIDGET(it),
909 SIG_TRANSITION_FINISHED,
911 if (wd->freeze_events)
912 evas_object_freeze_events_set(VIEW(it), EINA_FALSE);
916 _changed_size_hints(void *data,
918 Evas_Object *obj __UNUSED__,
919 void *event_info __UNUSED__)
925 _item_content_set(Elm_Naviframe_Item *navi_it, Evas_Object *content)
927 if (navi_it->content == content) return;
928 if (navi_it->content) evas_object_del(navi_it->content);
929 elm_object_part_content_set(VIEW(navi_it), "elm.swallow.content", content);
932 elm_object_signal_emit(VIEW(navi_it), "elm,state,content,show", "elm");
934 elm_object_signal_emit(VIEW(navi_it), "elm,state,content,hide", "elm");
936 evas_object_event_callback_add(content,
940 navi_it->content = content;
941 _sizing_eval(WIDGET(navi_it));
944 //FIXME: need to handle if this function is called while transition
946 _item_style_set(Elm_Naviframe_Item *navi_it, const char *item_style)
948 Elm_Naviframe_Content_Item_Pair *content_pair;
949 Elm_Naviframe_Text_Item_Pair *text_pair;
951 wd = elm_widget_data_get(WIDGET(navi_it));
958 snprintf(buf, sizeof(buf), "item/%s", wd->item_style);
962 snprintf(buf, sizeof(buf), "item/%s", item_style);
963 eina_stringshare_replace(&navi_it->style, item_style);
965 elm_layout_theme_set(VIEW(navi_it),
968 elm_widget_style_get(WIDGET(navi_it)));
970 EINA_INLIST_FOREACH(navi_it->text_list, text_pair)
971 _item_text_set_hook((Elm_Object_Item *) navi_it,
973 elm_object_part_text_get(VIEW(navi_it),
976 EINA_INLIST_FOREACH(navi_it->content_list, content_pair)
977 _item_content_set_hook((Elm_Object_Item *) navi_it,
979 elm_object_part_content_get(VIEW(navi_it),
980 content_pair->part));
982 if (navi_it->content)
983 elm_object_signal_emit(VIEW(navi_it), "elm,state,content,show", "elm");
986 if (navi_it->title_prev_btn)
987 elm_object_signal_emit(VIEW(navi_it), "elm,state,prev_btn,show", "elm");
990 if (navi_it->title_next_btn)
991 elm_object_signal_emit(VIEW(navi_it), "elm,state,next_btn,show", "elm");
993 navi_it->title_visible = EINA_TRUE;
994 _sizing_eval(WIDGET(navi_it));
996 if (wd->freeze_events)
997 evas_object_freeze_events_set(VIEW(navi_it), EINA_FALSE);
1000 static Elm_Naviframe_Item *
1001 _item_new(Evas_Object *obj,
1002 const char *title_label,
1003 Evas_Object *prev_btn,
1004 Evas_Object *next_btn,
1005 Evas_Object *content,
1006 const char *item_style)
1008 Widget_Data *wd = elm_widget_data_get(obj);
1011 Elm_Naviframe_Item *it = elm_widget_item_new(obj, Elm_Naviframe_Item);
1014 ERR("Failed to allocate new item! : naviframe=%p", obj);
1018 elm_widget_item_del_pre_hook_set(it, _item_del_pre_hook);
1019 elm_widget_item_text_set_hook_set(it, _item_text_set_hook);
1020 elm_widget_item_text_get_hook_set(it, _item_text_get_hook);
1021 elm_widget_item_content_set_hook_set(it, _item_content_set_hook);
1022 elm_widget_item_content_get_hook_set(it, _item_content_get_hook);
1023 elm_widget_item_content_unset_hook_set(it, _item_content_unset_hook);
1024 elm_widget_item_signal_emit_hook_set(it, _item_signal_emit_hook);
1027 VIEW(it) = elm_layout_add(obj);
1028 evas_object_smart_member_add(VIEW(it), wd->base);
1030 evas_object_event_callback_add(VIEW(it),
1031 EVAS_CALLBACK_CHANGED_SIZE_HINTS,
1032 _changed_size_hints,
1034 elm_object_signal_callback_add(VIEW(it),
1035 "elm,action,show,finished",
1037 _show_finished, it);
1038 elm_object_signal_callback_add(VIEW(it),
1039 "elm,action,pushed,finished",
1041 _pushed_finished, it);
1042 elm_object_signal_callback_add(VIEW(it),
1043 "elm,action,popped,finished",
1045 _popped_finished, it);
1046 elm_object_signal_callback_add(VIEW(it),
1047 "elm,action,title,clicked",
1049 _title_clicked, it);
1051 _item_style_set(it, item_style);
1052 _item_text_set_hook((Elm_Object_Item *) it, "elm.text.title", title_label);
1055 if ((!prev_btn) && wd->auto_pushed && eina_inlist_count(wd->stack))
1057 prev_btn = _back_btn_new(obj);
1058 _title_prev_btn_set(it, prev_btn, EINA_TRUE);
1061 _title_prev_btn_set(it, prev_btn, EINA_FALSE);
1063 _title_next_btn_set(it, next_btn);
1064 _item_content_set(it, content);
1065 it->title_visible = EINA_TRUE;
1070 _focus_next_hook(const Evas_Object *obj, Elm_Focus_Direction dir, Evas_Object **next)
1072 Widget_Data *wd = elm_widget_data_get(obj);
1073 if (!wd || !wd->stack) return EINA_FALSE;
1074 return elm_widget_focus_next_get(VIEW(elm_naviframe_top_item_get(obj)),
1080 elm_naviframe_add(Evas_Object *parent)
1086 ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL);
1087 ELM_SET_WIDTYPE(widtype, "naviframe");
1088 elm_widget_type_set(obj, "naviframe");
1089 elm_widget_sub_object_add(parent, obj);
1090 elm_widget_data_set(obj, wd);
1091 elm_widget_del_hook_set(obj, _del_hook);
1092 elm_widget_disable_hook_set(obj, _disable_hook);
1093 elm_widget_theme_hook_set(obj, _theme_hook);
1094 elm_widget_text_set_hook_set(obj, _text_set_hook);
1095 elm_widget_text_get_hook_set(obj, _text_get_hook);
1096 elm_widget_content_set_hook_set(obj, _content_set_hook);
1097 elm_widget_content_get_hook_set(obj, _content_get_hook);
1098 elm_widget_content_unset_hook_set(obj, _content_unset_hook);
1099 elm_widget_signal_emit_hook_set(obj, _emit_hook);
1100 elm_widget_can_focus_set(obj, EINA_FALSE);
1101 elm_widget_focus_next_hook_set(obj, _focus_next_hook);
1104 //FIXME: Is this base layout really needed?
1105 wd->base = elm_layout_add(parent);
1106 evas_object_event_callback_add(wd->base,
1107 EVAS_CALLBACK_CHANGED_SIZE_HINTS,
1108 _changed_size_hints,
1110 elm_widget_resize_object_set(obj, wd->base);
1111 elm_layout_theme_set(wd->base, "naviframe", "base", "default");
1113 evas_object_event_callback_add(obj, EVAS_CALLBACK_MOVE, _move, obj);
1114 evas_object_event_callback_add(obj, EVAS_CALLBACK_RESIZE, _resize, obj);
1115 evas_object_smart_callbacks_descriptions_set(obj, _signals);
1117 wd->auto_pushed = EINA_TRUE;
1118 wd->freeze_events = EINA_TRUE;
1119 wd->item_style = eina_stringshare_add("basic");
1124 EAPI Elm_Object_Item *
1125 elm_naviframe_item_push(Evas_Object *obj,
1126 const char *title_label,
1127 Evas_Object *prev_btn,
1128 Evas_Object *next_btn,
1129 Evas_Object *content,
1130 const char *item_style)
1132 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1134 Elm_Naviframe_Item *prev_it, *it;
1136 wd = elm_widget_data_get(obj);
1137 if (!wd) return NULL;
1139 it = _item_new(obj, title_label, prev_btn, next_btn, content, item_style);
1140 if (!it) return NULL;
1142 evas_object_show(VIEW(it));
1144 prev_it = (Elm_Naviframe_Item *) elm_naviframe_top_item_get(obj);
1147 if (wd->freeze_events)
1149 evas_object_freeze_events_set(VIEW(it), EINA_TRUE);
1150 evas_object_freeze_events_set(VIEW(prev_it), EINA_TRUE);
1152 elm_object_signal_emit(VIEW(prev_it), "elm,state,cur,pushed", "elm");
1153 elm_object_signal_emit(VIEW(it), "elm,state,new,pushed", "elm");
1154 edje_object_message_signal_process(elm_layout_edje_get(VIEW(prev_it)));
1155 edje_object_message_signal_process(elm_layout_edje_get(VIEW(it)));
1157 wd->stack = eina_inlist_append(wd->stack, EINA_INLIST_GET(it));
1159 return (Elm_Object_Item *) it;
1162 EAPI Elm_Object_Item *
1163 elm_naviframe_item_insert_before(Elm_Object_Item *before,
1164 const char *title_label,
1165 Evas_Object *prev_btn,
1166 Evas_Object *next_btn,
1167 Evas_Object *content,
1168 const char *item_style)
1170 ELM_OBJ_ITEM_CHECK_OR_RETURN(before, NULL);
1171 Elm_Naviframe_Item *it;
1174 wd = elm_widget_data_get(WIDGET(before));
1175 if (!wd) return NULL;
1177 it = _item_new(WIDGET(before), title_label, prev_btn, next_btn, content,
1179 if (!it) return NULL;
1182 eina_inlist_prepend_relative(wd->stack,
1183 EINA_INLIST_GET(it),
1184 EINA_INLIST_GET(((Elm_Naviframe_Item *) before)));
1185 _sizing_eval(WIDGET(before));
1186 return (Elm_Object_Item *) it;
1189 EAPI Elm_Object_Item *
1190 elm_naviframe_item_insert_after(Elm_Object_Item *after,
1191 const char *title_label,
1192 Evas_Object *prev_btn,
1193 Evas_Object *next_btn,
1194 Evas_Object *content,
1195 const char *item_style)
1197 ELM_OBJ_ITEM_CHECK_OR_RETURN(after, NULL);
1198 Elm_Naviframe_Item *it;
1201 wd = elm_widget_data_get(WIDGET(after));
1202 if (!wd) return NULL;
1204 it = _item_new(WIDGET(after), title_label, prev_btn, next_btn, content,
1206 if (!it) return NULL;
1208 if (elm_naviframe_top_item_get(WIDGET(after)) == after)
1210 evas_object_hide(VIEW(after));
1211 evas_object_show(VIEW(it));
1214 eina_inlist_append_relative(wd->stack,
1215 EINA_INLIST_GET(it),
1216 EINA_INLIST_GET(((Elm_Naviframe_Item *) after)));
1217 _sizing_eval(WIDGET(after));
1218 return (Elm_Object_Item *) it;
1222 elm_naviframe_item_pop(Evas_Object *obj)
1224 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1225 Elm_Naviframe_Item *it, *prev_it = NULL;
1227 Evas_Object *content = NULL;
1229 wd = elm_widget_data_get(obj);
1230 if (!wd) return NULL;
1232 it = (Elm_Naviframe_Item *) elm_naviframe_top_item_get(obj);
1233 if (!it) return NULL;
1234 elm_widget_tree_unfocusable_set(it->content, EINA_TRUE);
1236 content = it->content;
1238 if (wd->stack->last->prev)
1239 prev_it = EINA_INLIST_CONTAINER_GET(wd->stack->last->prev,
1240 Elm_Naviframe_Item);
1241 wd->stack = eina_inlist_remove(wd->stack, EINA_INLIST_GET(it));
1244 if (wd->freeze_events)
1246 evas_object_freeze_events_set(VIEW(it), EINA_TRUE);
1247 evas_object_freeze_events_set(VIEW(prev_it), EINA_TRUE);
1249 elm_object_signal_emit(VIEW(it), "elm,state,cur,popped", "elm");
1250 evas_object_show(VIEW(prev_it));
1251 evas_object_raise(VIEW(prev_it));
1252 elm_object_signal_emit(VIEW(prev_it),
1253 "elm,state,prev,popped",
1255 edje_object_message_signal_process(elm_layout_edje_get(VIEW(it)));
1256 edje_object_message_signal_process(elm_layout_edje_get(VIEW(prev_it)));
1257 elm_widget_item_smart_callback_call(prev_it,
1258 SIG_ITEM_SHOW_BEGIN,
1264 elm_widget_item_free(it);
1271 elm_naviframe_item_pop_to(Elm_Object_Item *it)
1273 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1274 Elm_Naviframe_Item *navi_it;
1276 Eina_Inlist *l, *prev_l;
1278 navi_it = (Elm_Naviframe_Item *) it;
1279 wd = elm_widget_data_get(WIDGET(navi_it));
1282 if (it == elm_naviframe_top_item_get(WIDGET(navi_it))) return;
1284 l = wd->stack->last->prev;
1288 if (EINA_INLIST_CONTAINER_GET(l, Elm_Naviframe_Item) ==
1289 ((Elm_Naviframe_Item *) it)) break;
1291 wd->stack = eina_inlist_remove(wd->stack, l);
1292 _item_del(EINA_INLIST_CONTAINER_GET(l, Elm_Naviframe_Item));
1293 elm_widget_item_free(EINA_INLIST_CONTAINER_GET(l,
1294 Elm_Naviframe_Item));
1297 elm_naviframe_item_pop(WIDGET(navi_it));
1301 elm_naviframe_item_promote(Elm_Object_Item *it)
1303 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1304 Elm_Naviframe_Item *navi_it;
1305 Elm_Naviframe_Item *prev_it;
1308 navi_it = (Elm_Naviframe_Item *) it;
1309 wd = elm_widget_data_get(navi_it->base.widget);
1312 if (it == elm_naviframe_top_item_get(navi_it->base.widget)) return;
1313 wd->stack = eina_inlist_demote(wd->stack, EINA_INLIST_GET(navi_it));
1314 prev_it = EINA_INLIST_CONTAINER_GET(wd->stack->last->prev,
1315 Elm_Naviframe_Item);
1316 if (wd->freeze_events)
1318 evas_object_freeze_events_set(VIEW(it), EINA_TRUE);
1319 evas_object_freeze_events_set(VIEW(prev_it), EINA_TRUE);
1321 elm_object_signal_emit(VIEW(prev_it),
1322 "elm,state,cur,pushed",
1324 evas_object_show(VIEW(navi_it));
1325 evas_object_raise(VIEW(navi_it));
1326 elm_object_signal_emit(VIEW(navi_it),
1327 "elm,state,new,pushed",
1329 edje_object_message_signal_process(elm_layout_edje_get(VIEW(prev_it)));
1330 edje_object_message_signal_process(elm_layout_edje_get(VIEW(navi_it)));
1334 elm_naviframe_item_simple_promote(Evas_Object *obj, Evas_Object *content)
1336 ELM_CHECK_WIDTYPE(obj, widtype);
1337 Widget_Data *wd = elm_widget_data_get(obj);
1339 Elm_Naviframe_Item *itr;
1340 EINA_INLIST_FOREACH(wd->stack, itr)
1342 if (elm_object_item_content_get((Elm_Object_Item *) itr) == content)
1344 elm_naviframe_item_promote((Elm_Object_Item *) itr);
1352 elm_naviframe_item_del(Elm_Object_Item *it)
1354 elm_object_item_del(it);
1358 elm_naviframe_content_preserve_on_pop_set(Evas_Object *obj, Eina_Bool preserve)
1360 ELM_CHECK_WIDTYPE(obj, widtype);
1361 Widget_Data *wd = elm_widget_data_get(obj);
1363 wd->preserve = !!preserve;
1367 elm_naviframe_content_preserve_on_pop_get(const Evas_Object *obj)
1369 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
1370 Widget_Data *wd = elm_widget_data_get(obj);
1371 if (!wd) return EINA_FALSE;
1372 return wd->preserve;
1375 EAPI Elm_Object_Item*
1376 elm_naviframe_top_item_get(const Evas_Object *obj)
1378 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1379 Widget_Data *wd = elm_widget_data_get(obj);
1380 if ((!wd) || (!wd->stack)) return NULL;
1381 return (Elm_Object_Item *) (EINA_INLIST_CONTAINER_GET(wd->stack->last,
1382 Elm_Naviframe_Item));
1385 EAPI Elm_Object_Item*
1386 elm_naviframe_bottom_item_get(const Evas_Object *obj)
1388 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1389 Widget_Data *wd = elm_widget_data_get(obj);
1390 if ((!wd) || (!wd->stack)) return NULL;
1391 return (Elm_Object_Item *) (EINA_INLIST_CONTAINER_GET(wd->stack,
1392 Elm_Naviframe_Item));
1396 elm_naviframe_item_style_set(Elm_Object_Item *it, const char *item_style)
1398 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1399 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
1401 //Return if new style is exsiting one.
1402 if ((item_style && navi_it->style) && (!strcmp(item_style, navi_it->style)))
1405 if ((!item_style) && (!navi_it->style))
1408 _item_style_set(navi_it, item_style);
1412 elm_naviframe_item_style_get(const Elm_Object_Item *it)
1414 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
1415 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
1416 return navi_it->style;
1420 elm_naviframe_item_title_visible_set(Elm_Object_Item *it, Eina_Bool visible)
1422 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1423 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
1425 visible = !!visible;
1426 if (navi_it->title_visible == visible) return;
1428 navi_it->title_visible = visible;
1429 _item_title_visible_update(navi_it);
1433 elm_naviframe_item_title_visible_get(const Elm_Object_Item *it)
1435 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
1436 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
1437 return navi_it->title_visible;
1441 elm_naviframe_prev_btn_auto_pushed_set(Evas_Object *obj, Eina_Bool auto_pushed)
1443 ELM_CHECK_WIDTYPE(obj, widtype);
1444 Widget_Data *wd = elm_widget_data_get(obj);
1446 wd->auto_pushed = !!auto_pushed;
1450 elm_naviframe_prev_btn_auto_pushed_get(const Evas_Object *obj)
1452 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
1453 Widget_Data *wd = elm_widget_data_get(obj);
1454 if (!wd) return EINA_FALSE;
1455 return wd->auto_pushed;
1459 elm_naviframe_items_get(const Evas_Object *obj)
1461 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1462 Widget_Data *wd = elm_widget_data_get(obj);
1463 if (!wd) return NULL;
1464 Eina_List *ret = NULL;
1465 Elm_Naviframe_Item *itr;
1466 EINA_INLIST_FOREACH(wd->stack, itr)
1468 ret = eina_list_append(ret, itr);
1474 elm_naviframe_event_enabled_set(Evas_Object *obj, Eina_Bool enabled)
1476 ELM_CHECK_WIDTYPE(obj, widtype);
1477 Widget_Data *wd = elm_widget_data_get(obj);
1479 enabled = !!enabled;
1480 if (wd->freeze_events == !enabled) return;
1481 wd->freeze_events = !enabled;
1485 elm_naviframe_event_enabled_get(const Evas_Object *obj)
1487 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
1488 Widget_Data *wd = elm_widget_data_get(obj);
1489 if (!wd) return EINA_FALSE;
1490 return !wd->freeze_events;
1494 elm_naviframe_item_style_default_set(Evas_Object *obj, const char *style)
1496 ELM_CHECK_WIDTYPE(obj, widtype);
1497 Widget_Data *wd = elm_widget_data_get(obj);
1499 eina_stringshare_replace(&wd->item_style, style);
1504 elm_naviframe_item_style_default_get(const Evas_Object *obj)
1506 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1507 Widget_Data *wd = elm_widget_data_get(obj);
1508 if (!wd) return NULL;
1509 return wd->item_style;