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
22 Elm_Naviframe_Item *it;
25 struct _Elm_Naviframe_Text_Item_Pair
31 struct _Elm_Naviframe_Item
35 Eina_Inlist *content_list;
36 Eina_Inlist *text_list;
38 Evas_Object *title_prev_btn;
39 Evas_Object *title_next_btn;
40 Evas_Object *title_icon;
44 Eina_Bool back_btn: 1;
45 Eina_Bool title_visible: 1;
48 static const char *widtype = NULL;
51 static const char SIG_TRANSITION_FINISHED[] = "transition,finished";
52 static const char SIG_TITLE_CLICKED[] = "title,clicked";
55 static const char SIG_ITEM_SHOW_BEGIN[] = "show,begin";
56 static const char SIG_ITEM_HIDE_FINISHED[] = "hide,finished";
58 static const Evas_Smart_Cb_Description _signals[] = {
59 {SIG_TRANSITION_FINISHED, ""},
60 {SIG_TITLE_CLICKED, ""},
61 {SIG_ITEM_SHOW_BEGIN, ""},
62 {SIG_ITEM_HIDE_FINISHED, ""},
66 static void _text_set_hook(Evas_Object *obj,
69 static const char *_text_get_hook(const Evas_Object *obj, const char *part);
70 static void _content_set_hook(Evas_Object *obj,
72 Evas_Object *content);
73 static Evas_Object *_content_get_hook(const Evas_Object *obj, const char *part);
74 static Evas_Object *_content_unset_hook(Evas_Object *obj, const char *part);
75 static void _del_hook(Evas_Object *obj);
76 static void _theme_hook(Evas_Object *obj);
77 static void _emit_hook(Evas_Object *obj,
80 static void _disable_hook(Evas_Object *obj);
81 static void _item_text_set_hook(Elm_Object_Item *it,
84 static const char *_item_text_get_hook(const Elm_Object_Item *it,
86 static void _item_content_set_hook(Elm_Object_Item *it,
88 Evas_Object *content);
89 static Evas_Object *_item_content_get_hook(const Elm_Object_Item *it,
91 static Evas_Object *_item_content_unset_hook(Elm_Object_Item *it,
93 static void _item_signal_emit_hook(Elm_Object_Item *it,
96 static void _item_title_visible_update(Elm_Naviframe_Item *navi_it);
97 static void _sizing_eval(Evas_Object *obj);
98 static void _move(void *data, Evas *e, Evas_Object *obj, void *event_info);
99 static void _resize(void *data,
103 static void _title_clicked(void *data, Evas_Object *obj,
104 const char *emission,
106 static void _back_btn_clicked(void *data,
109 static Evas_Object *_back_btn_new(Evas_Object *obj);
110 static void _item_content_del(void *data,
114 static void _title_content_del(void *data,
118 static void _title_prev_btn_del(void *data,
122 static void _title_next_btn_del(void *data,
126 static void _title_icon_del(void *data,
130 static void _title_content_set(Elm_Naviframe_Item *it,
132 Evas_Object *content);
133 static void _title_prev_btn_set(Elm_Naviframe_Item *it,
136 static void _title_next_btn_set(Elm_Naviframe_Item *it, Evas_Object *btn);
137 static void _title_icon_set(Elm_Naviframe_Item *it, Evas_Object *icon);
138 static Evas_Object * _item_content_unset(Elm_Naviframe_Item *it);
139 static Evas_Object * _title_prev_btn_unset(Elm_Naviframe_Item *it);
140 static Evas_Object * _title_next_btn_unset(Elm_Naviframe_Item *it);
141 static Evas_Object * _title_icon_unset(Elm_Naviframe_Item *it);
142 static Evas_Object * _title_content_unset(Elm_Naviframe_Item *it,
144 static void _item_del(Elm_Naviframe_Item *it);
145 static Eina_Bool _item_del_pre_hook(Elm_Object_Item *it);
146 static void _pushed_finished(void *data,
148 const char *emission,
150 static void _popped_finished(void *data,
152 const char *emission,
154 static void _show_finished(void *data,
156 const char *emission,
158 static void _changed_size_hints(void *data,
162 static void _item_content_set(Elm_Naviframe_Item *navi_it,
163 Evas_Object *content);
164 static void _item_style_set(Elm_Naviframe_Item *navi_it,
165 const char *item_style);
166 static Elm_Naviframe_Item * _item_new(Evas_Object *obj,
167 const char *title_label,
168 Evas_Object *prev_btn,
169 Evas_Object *next_btn,
170 Evas_Object *content,
171 const char *item_style);
172 static Eina_Bool _focus_next_hook(const Evas_Object *obj,
173 Elm_Focus_Direction dir,
177 _del_hook(Evas_Object *obj)
180 Elm_Naviframe_Item *it;
182 wd = elm_widget_data_get(obj);
187 while (wd->stack->last)
189 it = EINA_INLIST_CONTAINER_GET(wd->stack->last,
191 wd->stack = eina_inlist_remove(wd->stack, wd->stack->last);
193 elm_widget_item_free(it);
194 if (!wd->stack) break;
201 _theme_hook(Evas_Object *obj)
204 Elm_Naviframe_Item *it;
206 wd = elm_widget_data_get(obj);
209 _elm_theme_object_set(obj,
213 elm_widget_style_get(obj));
215 EINA_INLIST_FOREACH(wd->stack, it)
217 _item_style_set(it, it->style);
218 _item_title_visible_update(it);
222 static void _emit_hook(Evas_Object *obj,
223 const char *emission,
226 Elm_Object_Item *it = elm_naviframe_top_item_get(obj);
228 return elm_object_item_signal_emit(it, emission, source);
232 _disable_hook(Evas_Object *obj __UNUSED__)
238 _item_text_set_hook(Elm_Object_Item *it,
242 Elm_Naviframe_Text_Item_Pair *pair = NULL;
243 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *)it;
246 if (!part || !strcmp(part, "default"))
247 snprintf(buf, sizeof(buf), "elm.text.title");
248 else if(!strcmp("subtitle", part))
249 snprintf(buf, sizeof(buf), "elm.text.subtitle");
251 snprintf(buf, sizeof(buf), "%s", part);
253 EINA_INLIST_FOREACH(navi_it->text_list, pair)
254 if (!strcmp(buf, pair->part)) break;
258 pair = ELM_NEW(Elm_Naviframe_Text_Item_Pair);
261 ERR("Failed to allocate new text part of the item! : naviframe=%p",
265 eina_stringshare_replace(&pair->part, buf);
266 navi_it->text_list = eina_inlist_append(navi_it->text_list,
267 EINA_INLIST_GET(pair));
269 elm_object_part_text_set(VIEW(navi_it), buf, label);
273 snprintf(buf, sizeof(buf), "elm,state,%s,show", buf);
274 elm_object_signal_emit(VIEW(navi_it), buf, "elm");
278 snprintf(buf, sizeof(buf), "elm,state,%s,hide", buf);
279 elm_object_signal_emit(VIEW(navi_it), buf, "elm");
282 _sizing_eval(WIDGET(navi_it));
286 _item_text_get_hook(const Elm_Object_Item *it, const char *part)
290 if (!part || !strcmp(part, "default"))
291 snprintf(buf, sizeof(buf), "elm.text.title");
292 else if(!strcmp("subtitle", part))
293 snprintf(buf, sizeof(buf), "elm.text.subtitle");
295 snprintf(buf, sizeof(buf), "%s", part);
297 return elm_object_part_text_get(VIEW(it), buf);
301 _item_content_set_hook(Elm_Object_Item *it,
303 Evas_Object *content)
305 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *)it;
308 if (!part || !strcmp("default", part))
310 _item_content_set(navi_it, content);
313 else if (!strcmp(part, "prev_btn"))
315 _title_prev_btn_set(navi_it, content, EINA_FALSE);
318 else if (!strcmp(part, "next_btn"))
320 _title_next_btn_set(navi_it, content);
323 else if (!strcmp(part, "icon"))
325 _title_icon_set(navi_it, content);
330 _title_content_set(navi_it, part, content);
334 _item_content_get_hook(const Elm_Object_Item *it, const char *part)
336 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *)it;
339 if (!part || !strcmp("default", part))
340 return navi_it->content;
341 else if (!strcmp(part, "prev_btn"))
342 return navi_it->title_prev_btn;
343 else if (!strcmp(part, "next_btn"))
344 return navi_it->title_next_btn;
345 else if (!strcmp(part, "icon"))
346 return navi_it->title_icon;
349 return elm_object_part_content_get(VIEW(navi_it), part);
353 _item_content_unset_hook(Elm_Object_Item *it, const char *part)
355 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *)it;
358 if (!part || !strcmp("default", part))
359 return _item_content_unset(navi_it);
360 else if (!strcmp(part, "prev_btn"))
361 return _title_prev_btn_unset(navi_it);
362 else if (!strcmp(part, "next_btn"))
363 return _title_next_btn_unset(navi_it);
364 else if (!strcmp(part, "icon"))
365 return _title_icon_unset(navi_it);
367 return _title_content_unset(navi_it, part);
371 _item_signal_emit_hook(Elm_Object_Item *it,
372 const char *emission,
375 elm_object_signal_emit(VIEW(it), emission, source);
379 _item_title_visible_update(Elm_Naviframe_Item *navi_it)
381 if (navi_it->title_visible)
382 elm_object_signal_emit(VIEW(navi_it), "elm,state,title,show", "elm");
384 elm_object_signal_emit(VIEW(navi_it), "elm,state,title,hide", "elm");
388 _sizing_eval(Evas_Object *obj)
391 Elm_Naviframe_Item *it;
392 Evas_Coord x, y, w, h;
393 Evas_Coord minw = -1, minh = -1;
395 wd = elm_widget_data_get(obj);
398 evas_object_geometry_get(obj, &x, &y, &w, &h);
400 EINA_INLIST_FOREACH(wd->stack, it)
402 evas_object_move(VIEW(it), x, y);
403 evas_object_resize(VIEW(it), w, h);
404 edje_object_size_min_calc(elm_layout_edje_get(VIEW(it)),
407 if (it->minw > minw) minw = it->minw;
408 if (it->minh > minh) minh = it->minh;
410 evas_object_size_hint_min_set(obj, minw, minh);
411 evas_object_size_hint_max_set(obj, -1, -1);
415 _move(void *data __UNUSED__,
418 void *event_info __UNUSED__)
424 _resize(void *data __UNUSED__,
427 void *event_info __UNUSED__)
433 _title_clicked(void *data,
434 Evas_Object *obj __UNUSED__,
435 const char *emission __UNUSED__,
436 const char *source __UNUSED__)
438 Elm_Naviframe_Item *it = data;
439 evas_object_smart_callback_call(WIDGET(it), SIG_TITLE_CLICKED, it);
443 _back_btn_clicked(void *data,
445 void *event_info __UNUSED__)
447 /* Since edje has the event queue, clicked event could be happend multiple times
448 on some heavy environment. This callback del will prevent those scenario and
449 guarantee only one clicked for it's own page. */
450 evas_object_smart_callback_del(obj, "clicked", _back_btn_clicked);
451 elm_naviframe_item_pop(data);
455 _back_btn_new(Evas_Object *obj)
459 btn = elm_button_add(obj);
460 if (!btn) return NULL;
461 evas_object_smart_callback_add(btn, "clicked", _back_btn_clicked, obj);
462 snprintf(buf, sizeof(buf), "naviframe/back_btn/%s",
463 elm_widget_style_get(obj));
464 elm_object_style_set(btn, buf);
468 static void _text_set_hook(Evas_Object *obj,
472 Elm_Object_Item *it = elm_naviframe_top_item_get(obj);
474 elm_object_item_part_text_set(it, part, label);
477 static const char *_text_get_hook(const Evas_Object *obj, const char *part)
479 Elm_Object_Item *it = elm_naviframe_top_item_get(obj);
480 if (!it) return NULL;
481 return elm_object_item_part_text_get(it, part);
485 _content_set_hook(Evas_Object *obj, const char *part, Evas_Object *content)
487 Elm_Object_Item *it = elm_naviframe_top_item_get(obj);
489 elm_object_item_part_content_set(it, part, content);
493 _content_unset_hook(Evas_Object *obj, const char *part)
495 Elm_Object_Item *it = elm_naviframe_top_item_get(obj);
496 if (!it) return NULL;
497 return elm_object_item_part_content_unset(it, part);
501 _content_get_hook(const Evas_Object *obj, const char *part)
503 Elm_Object_Item *it = elm_naviframe_top_item_get(obj);
504 if (!it) return NULL;
505 return elm_object_item_part_content_get(it, part);
509 _title_content_del(void *data,
511 Evas_Object *obj __UNUSED__,
512 void *event_info __UNUSED__)
515 Elm_Naviframe_Content_Item_Pair *pair = data;
516 Elm_Naviframe_Item *it = pair->it;
517 snprintf(buf, sizeof(buf), "elm,state,%s,hide", pair->part);
518 elm_object_signal_emit(VIEW(it), buf, "elm");
519 it->content_list = eina_inlist_remove(it->content_list,
520 EINA_INLIST_GET(pair));
521 eina_stringshare_del(pair->part);
526 _title_prev_btn_del(void *data,
528 Evas_Object *obj __UNUSED__,
529 void *event_info __UNUSED__)
531 Elm_Naviframe_Item *it = data;
532 it->back_btn = EINA_FALSE;
533 it->title_prev_btn = NULL;
534 elm_object_signal_emit(VIEW(it), "elm,state,prev_btn,hide", "elm");
538 _title_next_btn_del(void *data,
540 Evas_Object *obj __UNUSED__,
541 void *event_info __UNUSED__)
543 Elm_Naviframe_Item *it = data;
544 it->title_next_btn = NULL;
545 elm_object_signal_emit(VIEW(it), "elm,state,next_btn,hide", "elm");
549 _title_icon_del(void *data,
551 Evas_Object *obj __UNUSED__,
552 void *event_info __UNUSED__)
554 Elm_Naviframe_Item *it = data;
555 it->title_icon = NULL;
556 elm_object_signal_emit(VIEW(it), "elm,state,icon,hide", "elm");
560 _item_content_del(void *data,
562 Evas_Object *obj __UNUSED__,
563 void *event_info __UNUSED__)
565 Elm_Naviframe_Item *it = data;
567 elm_object_signal_emit(VIEW(it), "elm,state,content,hide", "elm");
571 _title_content_set(Elm_Naviframe_Item *it,
573 Evas_Object *content)
576 Elm_Naviframe_Content_Item_Pair *pair = NULL;
577 Evas_Object *prev_content = NULL;
579 EINA_INLIST_FOREACH(it->content_list, pair)
580 if (!strcmp(part, pair->part)) break;
584 prev_content = elm_object_part_content_get(VIEW(it), part);
585 if (prev_content != content)
589 evas_object_event_callback_del(prev_content,
592 snprintf(buf, sizeof(buf), "elm,state,%s,hide", part);
593 elm_object_signal_emit(VIEW(it), buf, "elm");
595 evas_object_del(prev_content);
596 if (!content) return;
601 if (!content) return;
602 pair = ELM_NEW(Elm_Naviframe_Content_Item_Pair);
605 ERR("Failed to allocate new content part of the item! : naviframe=%p", WIDGET(it));
609 eina_stringshare_replace(&pair->part, part);
610 it->content_list = eina_inlist_append(it->content_list,
611 EINA_INLIST_GET(pair));
613 if (prev_content != content)
615 evas_object_event_callback_add(content,
620 elm_object_part_content_set(VIEW(it), part, content);
621 snprintf(buf, sizeof(buf), "elm,state,%s,show", part);
622 elm_object_signal_emit(VIEW(it), buf, "elm");
624 _sizing_eval(WIDGET(it));
628 _title_prev_btn_set(Elm_Naviframe_Item *it,
632 if (it->title_prev_btn == btn) return;
633 if (it->title_prev_btn) evas_object_del(it->title_prev_btn);
634 it->title_prev_btn = btn;
637 evas_object_event_callback_add(btn,
641 elm_object_part_content_set(VIEW(it), "elm.swallow.prev_btn", btn);
642 elm_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;
652 if (it->title_next_btn) evas_object_del(it->title_next_btn);
653 it->title_next_btn = btn;
656 evas_object_event_callback_add(btn,
660 elm_object_part_content_set(VIEW(it), "elm.swallow.next_btn", btn);
661 elm_object_signal_emit(VIEW(it), "elm,state,next_btn,show", "elm");
663 _sizing_eval(WIDGET(it));
667 _title_icon_set(Elm_Naviframe_Item *it, Evas_Object *icon)
669 if (it->title_icon == icon) return;
670 if (it->title_icon) evas_object_del(it->title_icon);
671 it->title_icon = icon;
674 evas_object_event_callback_add(icon,
678 elm_object_part_content_set(VIEW(it), "elm.swallow.icon", icon);
679 elm_object_signal_emit(VIEW(it), "elm,state,icon,show", "elm");
681 _sizing_eval(WIDGET(it));
685 _item_content_unset(Elm_Naviframe_Item *it)
687 Evas_Object *content = it->content;
688 if (!content) return NULL;
690 elm_object_part_content_unset(VIEW(it), "elm.swallow.content");
691 elm_object_signal_emit(VIEW(it), "elm,state,content,hide", "elm");
692 evas_object_event_callback_del(content,
695 _sizing_eval(WIDGET(it));
702 _title_prev_btn_unset(Elm_Naviframe_Item *it)
704 Evas_Object *content = it->title_prev_btn;
705 if (!content) return NULL;
707 elm_object_part_content_unset(VIEW(it), "elm.swallow.prev_btn");
708 elm_object_signal_emit(VIEW(it), "elm,state,prev_btn,hide", "elm");
709 evas_object_event_callback_del(content,
711 _title_prev_btn_del);
712 _sizing_eval(WIDGET(it));
714 it->title_prev_btn = NULL;
719 _title_next_btn_unset(Elm_Naviframe_Item *it)
721 Evas_Object *content = it->title_next_btn;
722 if (!content) return NULL;
724 elm_object_part_content_unset(VIEW(it), "elm.swallow.next_btn");
725 elm_object_signal_emit(VIEW(it), "elm,state,next_btn,hide", "elm");
726 evas_object_event_callback_del(content,
728 _title_next_btn_del);
729 _sizing_eval(WIDGET(it));
731 it->title_next_btn = NULL;
736 _title_icon_unset(Elm_Naviframe_Item *it)
738 Evas_Object *content = it->title_icon;
739 if (!content) return NULL;
741 elm_object_part_content_unset(VIEW(it), "elm.swallow.icon");
742 elm_object_signal_emit(VIEW(it), "elm,state,icon,hide", "elm");
743 evas_object_event_callback_del(content,
746 _sizing_eval(WIDGET(it));
747 it->title_icon = NULL;
753 _title_content_unset(Elm_Naviframe_Item *it, const char *part)
755 Elm_Naviframe_Content_Item_Pair *pair = NULL;
757 Evas_Object *content = NULL;
759 EINA_INLIST_FOREACH(it->content_list, pair)
761 if (!strcmp(part, pair->part))
763 content = elm_object_part_content_get(VIEW(it), part);
764 eina_stringshare_del(pair->part);
765 it->content_list = eina_inlist_remove(it->content_list,
766 EINA_INLIST_GET(pair));
772 if (!content) return NULL;
774 elm_object_part_content_unset(VIEW(it), part);
775 snprintf(buf, sizeof(buf), "elm,state,%s,hide", part);
776 elm_object_signal_emit(VIEW(it), buf, "elm");
777 evas_object_event_callback_del(content,
780 _sizing_eval(WIDGET(it));
786 _item_del(Elm_Naviframe_Item *it)
789 Elm_Naviframe_Content_Item_Pair *content_pair;
790 Elm_Naviframe_Text_Item_Pair *text_pair;
791 Evas_Object *content;
795 wd = elm_widget_data_get(WIDGET(it));
798 while (it->content_list)
801 EINA_INLIST_CONTAINER_GET(it->content_list,
802 Elm_Naviframe_Content_Item_Pair);
803 content = elm_object_part_content_get(VIEW(it), content_pair->part);
804 evas_object_event_callback_del(content,
807 eina_stringshare_del(content_pair->part);
808 it->content_list = eina_inlist_remove(it->content_list,
813 while (it->text_list)
815 text_pair = EINA_INLIST_CONTAINER_GET(it->text_list,
816 Elm_Naviframe_Text_Item_Pair);
817 eina_stringshare_del(text_pair->part);
818 it->text_list = eina_inlist_remove(it->text_list,
823 eina_stringshare_del(it->style);
827 _item_del_pre_hook(Elm_Object_Item *it)
829 Elm_Naviframe_Item *navi_it;
832 navi_it =(Elm_Naviframe_Item *)it;
833 wd = elm_widget_data_get(WIDGET(navi_it));
834 if (!wd) return EINA_FALSE;
836 if (it == elm_naviframe_top_item_get(WIDGET(navi_it)))
838 wd->stack = eina_inlist_remove(wd->stack, EINA_INLIST_GET(navi_it));
840 //If the item is only one, the stack will be empty
841 if (!wd->stack) return EINA_TRUE;
842 navi_it = EINA_INLIST_CONTAINER_GET(wd->stack->last,
844 evas_object_show(VIEW(navi_it));
845 evas_object_raise(VIEW(navi_it));
846 elm_object_signal_emit(VIEW(navi_it), "elm,state,visible", "elm");
850 wd->stack = eina_inlist_remove(wd->stack, EINA_INLIST_GET(navi_it));
858 _pushed_finished(void *data,
859 Evas_Object *obj __UNUSED__,
860 const char *emission __UNUSED__,
861 const char *source __UNUSED__)
864 Elm_Naviframe_Item *it = data;
867 wd = elm_widget_data_get(WIDGET(it));
870 evas_object_hide(VIEW(it));
871 if (wd->freeze_events)
872 evas_object_freeze_events_set(VIEW(it), EINA_FALSE);
874 elm_widget_item_smart_callback_call(it,
875 SIG_ITEM_HIDE_FINISHED,
880 _popped_finished(void *data,
881 Evas_Object *obj __UNUSED__,
882 const char *emission __UNUSED__,
883 const char *source __UNUSED__)
885 Elm_Naviframe_Item *it = data;
888 elm_widget_item_free(data);
892 _show_finished(void *data,
893 Evas_Object *obj __UNUSED__,
894 const char *emission __UNUSED__,
895 const char *source __UNUSED__)
897 Elm_Naviframe_Item *it;
902 wd = elm_widget_data_get(WIDGET(it));
905 evas_object_smart_callback_call(WIDGET(it),
906 SIG_TRANSITION_FINISHED,
908 if (wd->freeze_events)
909 evas_object_freeze_events_set(VIEW(it), EINA_FALSE);
913 _changed_size_hints(void *data,
915 Evas_Object *obj __UNUSED__,
916 void *event_info __UNUSED__)
922 _item_content_set(Elm_Naviframe_Item *navi_it, Evas_Object *content)
924 if (navi_it->content == content) return;
925 if (navi_it->content) evas_object_del(navi_it->content);
926 elm_object_part_content_set(VIEW(navi_it), "elm.swallow.content", content);
929 elm_object_signal_emit(VIEW(navi_it), "elm,state,content,show", "elm");
931 elm_object_signal_emit(VIEW(navi_it), "elm,state,content,hide", "elm");
933 evas_object_event_callback_add(content,
937 navi_it->content = content;
938 _sizing_eval(WIDGET(navi_it));
941 //FIXME: need to handle if this function is called while transition
943 _item_style_set(Elm_Naviframe_Item *navi_it, const char *item_style)
945 Elm_Naviframe_Content_Item_Pair *content_pair;
946 Elm_Naviframe_Text_Item_Pair *text_pair;
953 strcpy(buf, "item/basic");
954 eina_stringshare_replace(&navi_it->style, "basic");
958 snprintf(buf, sizeof(buf), "item/%s", item_style);
959 eina_stringshare_replace(&navi_it->style, item_style);
961 elm_layout_theme_set(VIEW(navi_it),
964 elm_widget_style_get(WIDGET(navi_it)));
966 EINA_INLIST_FOREACH(navi_it->text_list, text_pair)
967 _item_text_set_hook((Elm_Object_Item *) navi_it,
969 elm_object_part_text_get(VIEW(navi_it),
972 EINA_INLIST_FOREACH(navi_it->content_list, content_pair)
973 _item_content_set_hook((Elm_Object_Item *) navi_it,
975 elm_object_part_content_get(VIEW(navi_it),
976 content_pair->part));
978 if (navi_it->content)
979 elm_object_signal_emit(VIEW(navi_it), "elm,state,content,show", "elm");
982 if (navi_it->title_prev_btn)
983 elm_object_signal_emit(VIEW(navi_it), "elm,state,prev_btn,show", "elm");
986 if (navi_it->title_next_btn)
987 elm_object_signal_emit(VIEW(navi_it), "elm,state,next_btn,show", "elm");
989 // why does this forcibly enable title? isnt that separate to style?
990 // navi_it->title_visible = EINA_TRUE;
991 _sizing_eval(WIDGET(navi_it));
993 wd = elm_widget_data_get(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;
1123 EAPI Elm_Object_Item *
1124 elm_naviframe_item_push(Evas_Object *obj,
1125 const char *title_label,
1126 Evas_Object *prev_btn,
1127 Evas_Object *next_btn,
1128 Evas_Object *content,
1129 const char *item_style)
1131 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1133 Elm_Naviframe_Item *prev_it, *it;
1135 wd = elm_widget_data_get(obj);
1136 if (!wd) return NULL;
1138 it = _item_new(obj, title_label, prev_btn, next_btn, content, item_style);
1139 if (!it) return NULL;
1141 evas_object_show(VIEW(it));
1143 prev_it = (Elm_Naviframe_Item *) elm_naviframe_top_item_get(obj);
1146 if (wd->freeze_events)
1148 evas_object_freeze_events_set(VIEW(it), EINA_TRUE);
1149 evas_object_freeze_events_set(VIEW(prev_it), EINA_TRUE);
1151 elm_object_signal_emit(VIEW(prev_it), "elm,state,cur,pushed", "elm");
1152 elm_object_signal_emit(VIEW(it), "elm,state,new,pushed", "elm");
1153 edje_object_message_signal_process(elm_layout_edje_get(VIEW(prev_it)));
1154 elm_widget_tree_unfocusable_set(it->content, EINA_TRUE);
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(Evas_Object *obj,
1164 Elm_Object_Item *before,
1165 const char *title_label,
1166 Evas_Object *prev_btn,
1167 Evas_Object *next_btn,
1168 Evas_Object *content,
1169 const char *item_style)
1171 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1172 ELM_OBJ_ITEM_CHECK_OR_RETURN(before, NULL);
1173 Elm_Naviframe_Item *it;
1176 wd = elm_widget_data_get(obj);
1177 if (!wd) return NULL;
1179 it = _item_new(WIDGET(before), title_label, prev_btn, next_btn, content,
1181 if (!it) return NULL;
1184 eina_inlist_prepend_relative(wd->stack,
1185 EINA_INLIST_GET(it),
1186 EINA_INLIST_GET(((Elm_Naviframe_Item *) before)));
1187 _sizing_eval(WIDGET(before));
1188 return (Elm_Object_Item *)it;
1191 EAPI Elm_Object_Item *
1192 elm_naviframe_item_insert_after(Evas_Object *obj,
1193 Elm_Object_Item *after,
1194 const char *title_label,
1195 Evas_Object *prev_btn,
1196 Evas_Object *next_btn,
1197 Evas_Object *content,
1198 const char *item_style)
1200 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1201 ELM_OBJ_ITEM_CHECK_OR_RETURN(after, NULL);
1202 Elm_Naviframe_Item *it;
1205 wd = elm_widget_data_get(obj);
1206 if (!wd) return NULL;
1208 it = _item_new(WIDGET(after), title_label, prev_btn, next_btn, content,
1210 if (!it) return NULL;
1212 if (elm_naviframe_top_item_get(WIDGET(after)) == after)
1214 evas_object_hide(VIEW(after));
1215 evas_object_show(VIEW(it));
1218 eina_inlist_append_relative(wd->stack,
1219 EINA_INLIST_GET(it),
1220 EINA_INLIST_GET(((Elm_Naviframe_Item *) after)));
1221 _sizing_eval(WIDGET(after));
1222 return (Elm_Object_Item *)it;
1226 elm_naviframe_item_pop(Evas_Object *obj)
1228 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1229 Elm_Naviframe_Item *it, *prev_it = NULL;
1231 Evas_Object *content = NULL;
1233 wd = elm_widget_data_get(obj);
1234 if (!wd) return NULL;
1236 it = (Elm_Naviframe_Item *) elm_naviframe_top_item_get(obj);
1237 if (!it) return NULL;
1239 content = it->content;
1241 if (wd->stack->last->prev)
1242 prev_it = EINA_INLIST_CONTAINER_GET(wd->stack->last->prev,
1243 Elm_Naviframe_Item);
1244 wd->stack = eina_inlist_remove(wd->stack, EINA_INLIST_GET(it));
1247 if (wd->freeze_events)
1249 evas_object_freeze_events_set(VIEW(it), EINA_TRUE);
1250 evas_object_freeze_events_set(VIEW(prev_it), EINA_TRUE);
1252 elm_object_signal_emit(VIEW(it), "elm,state,cur,popped", "elm");
1253 evas_object_show(VIEW(prev_it));
1254 evas_object_raise(VIEW(prev_it));
1255 elm_object_signal_emit(VIEW(prev_it),
1256 "elm,state,prev,popped",
1258 edje_object_message_signal_process(elm_layout_edje_get(VIEW(it)));
1259 edje_object_message_signal_process(elm_layout_edje_get(VIEW(prev_it)));
1260 elm_widget_item_smart_callback_call(prev_it,
1261 SIG_ITEM_SHOW_BEGIN,
1267 elm_widget_item_free(it);
1274 elm_naviframe_item_pop_to(Elm_Object_Item *it)
1276 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1277 Elm_Naviframe_Item *navi_it;
1279 Eina_Inlist *l, *prev_l;
1281 navi_it = (Elm_Naviframe_Item *)it;
1282 wd = elm_widget_data_get(WIDGET(navi_it));
1285 if (it == elm_naviframe_top_item_get(WIDGET(navi_it))) return;
1287 l = wd->stack->last->prev;
1291 if (EINA_INLIST_CONTAINER_GET(l, Elm_Naviframe_Item) ==
1292 ((Elm_Naviframe_Item *)it)) break;
1294 wd->stack = eina_inlist_remove(wd->stack, l);
1295 _item_del(EINA_INLIST_CONTAINER_GET(l, Elm_Naviframe_Item));
1296 elm_widget_item_free(EINA_INLIST_CONTAINER_GET(l,
1297 Elm_Naviframe_Item));
1300 elm_naviframe_item_pop(WIDGET(navi_it));
1304 elm_naviframe_item_promote(Elm_Object_Item *it)
1306 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1307 Elm_Naviframe_Item *navi_it;
1308 Elm_Naviframe_Item *prev_it;
1311 navi_it = (Elm_Naviframe_Item *)it;
1312 wd = elm_widget_data_get(navi_it->base.widget);
1315 if (it == elm_naviframe_top_item_get(navi_it->base.widget)) return;
1316 elm_widget_tree_unfocusable_set(navi_it->content, EINA_FALSE);
1317 wd->stack = eina_inlist_demote(wd->stack, EINA_INLIST_GET(navi_it));
1318 prev_it = EINA_INLIST_CONTAINER_GET(wd->stack->last->prev,
1319 Elm_Naviframe_Item);
1320 elm_widget_tree_unfocusable_set(prev_it->content, EINA_FALSE);
1321 if (wd->freeze_events)
1323 evas_object_freeze_events_set(VIEW(it), EINA_TRUE);
1324 evas_object_freeze_events_set(VIEW(prev_it), EINA_TRUE);
1326 elm_object_signal_emit(VIEW(prev_it),
1327 "elm,state,cur,pushed",
1329 evas_object_show(VIEW(navi_it));
1330 evas_object_raise(VIEW(navi_it));
1331 elm_object_signal_emit(VIEW(navi_it),
1332 "elm,state,new,pushed",
1334 edje_object_message_signal_process(elm_layout_edje_get(VIEW(prev_it)));
1335 edje_object_message_signal_process(elm_layout_edje_get(VIEW(navi_it)));
1339 elm_naviframe_item_simple_promote(Evas_Object *obj, Evas_Object *content)
1341 ELM_CHECK_WIDTYPE(obj, widtype);
1342 Widget_Data *wd = elm_widget_data_get(obj);
1344 Elm_Naviframe_Item *itr;
1345 EINA_INLIST_FOREACH(wd->stack, itr)
1347 if (elm_object_item_content_get((Elm_Object_Item *)itr) == content)
1349 elm_naviframe_item_promote((Elm_Object_Item *)itr);
1357 elm_naviframe_content_preserve_on_pop_set(Evas_Object *obj, Eina_Bool preserve)
1359 ELM_CHECK_WIDTYPE(obj, widtype);
1360 Widget_Data *wd = elm_widget_data_get(obj);
1362 wd->preserve = !!preserve;
1366 elm_naviframe_content_preserve_on_pop_get(const Evas_Object *obj)
1368 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
1369 Widget_Data *wd = elm_widget_data_get(obj);
1370 if (!wd) return EINA_FALSE;
1371 return wd->preserve;
1374 EAPI Elm_Object_Item*
1375 elm_naviframe_top_item_get(const Evas_Object *obj)
1377 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1378 Widget_Data *wd = elm_widget_data_get(obj);
1379 if ((!wd) || (!wd->stack)) return NULL;
1380 return (Elm_Object_Item *) (EINA_INLIST_CONTAINER_GET(wd->stack->last,
1381 Elm_Naviframe_Item));
1384 EAPI Elm_Object_Item*
1385 elm_naviframe_bottom_item_get(const Evas_Object *obj)
1387 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1388 Widget_Data *wd = elm_widget_data_get(obj);
1389 if ((!wd) || (!wd->stack)) return NULL;
1390 return (Elm_Object_Item *) (EINA_INLIST_CONTAINER_GET(wd->stack,
1391 Elm_Naviframe_Item));
1395 elm_naviframe_item_style_set(Elm_Object_Item *it, const char *item_style)
1397 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1398 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *)it;
1401 if (!strcmp(item_style, navi_it->style)) return;
1404 if (!strcmp("basic", navi_it->style)) return;
1406 _item_style_set(navi_it, item_style);
1410 elm_naviframe_item_style_get(const Elm_Object_Item *it)
1412 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
1413 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *)it;
1414 return navi_it->style;
1418 elm_naviframe_item_title_visible_set(Elm_Object_Item *it, Eina_Bool visible)
1420 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1421 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *)it;
1423 visible = !!visible;
1424 if (navi_it->title_visible == visible) return;
1426 navi_it->title_visible = visible;
1427 _item_title_visible_update(navi_it);
1431 elm_naviframe_item_title_visible_get(const Elm_Object_Item *it)
1433 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
1434 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *)it;
1435 return navi_it->title_visible;
1439 elm_naviframe_prev_btn_auto_pushed_set(Evas_Object *obj, Eina_Bool auto_pushed)
1441 ELM_CHECK_WIDTYPE(obj, widtype);
1442 Widget_Data *wd = elm_widget_data_get(obj);
1444 wd->auto_pushed = !!auto_pushed;
1448 elm_naviframe_prev_btn_auto_pushed_get(const Evas_Object *obj)
1450 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
1451 Widget_Data *wd = elm_widget_data_get(obj);
1452 if (!wd) return EINA_FALSE;
1453 return wd->auto_pushed;
1457 elm_naviframe_items_get(const Evas_Object *obj)
1459 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1460 Widget_Data *wd = elm_widget_data_get(obj);
1461 if (!wd) return NULL;
1462 Eina_List *ret = NULL;
1463 Elm_Naviframe_Item *itr;
1464 EINA_INLIST_FOREACH(wd->stack, itr)
1465 ret = eina_list_append(ret, itr);
1470 elm_naviframe_event_enabled_set(Evas_Object *obj, Eina_Bool enabled)
1472 ELM_CHECK_WIDTYPE(obj, widtype);
1473 Widget_Data *wd = elm_widget_data_get(obj);
1475 enabled = !!enabled;
1476 if (wd->freeze_events == !enabled) return;
1477 wd->freeze_events = !enabled;
1481 elm_naviframe_event_enabled_get(const Evas_Object *obj)
1483 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
1484 Widget_Data *wd = elm_widget_data_get(obj);
1485 if (!wd) return EINA_FALSE;
1486 return !wd->freeze_events;