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));
218 EINA_INLIST_FOREACH(wd->stack, it)
220 _item_style_set(it, it->style);
221 _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 printf("%p: vis: %i\n", navi_it, navi_it->title_visible);
385 if (navi_it->title_visible)
386 elm_object_signal_emit(VIEW(navi_it), "elm,state,title,show", "elm");
388 elm_object_signal_emit(VIEW(navi_it), "elm,state,title,hide", "elm");
392 _sizing_eval(Evas_Object *obj)
395 Elm_Naviframe_Item *it;
396 Evas_Coord x, y, w, h;
397 Evas_Coord minw = -1, minh = -1;
399 wd = elm_widget_data_get(obj);
402 evas_object_geometry_get(obj, &x, &y, &w, &h);
404 EINA_INLIST_FOREACH(wd->stack, it)
406 evas_object_move(VIEW(it), x, y);
407 evas_object_resize(VIEW(it), w, h);
408 edje_object_size_min_calc(elm_layout_edje_get(VIEW(it)),
411 if (it->minw > minw) minw = it->minw;
412 if (it->minh > minh) minh = it->minh;
414 evas_object_size_hint_min_set(obj, minw, minh);
415 evas_object_size_hint_max_set(obj, -1, -1);
419 _move(void *data __UNUSED__,
422 void *event_info __UNUSED__)
428 _resize(void *data __UNUSED__,
431 void *event_info __UNUSED__)
437 _title_clicked(void *data,
438 Evas_Object *obj __UNUSED__,
439 const char *emission __UNUSED__,
440 const char *source __UNUSED__)
442 Elm_Naviframe_Item *it = data;
443 evas_object_smart_callback_call(WIDGET(it), SIG_TITLE_CLICKED, it);
447 _back_btn_clicked(void *data,
449 void *event_info __UNUSED__)
451 /* Since edje has the event queue, clicked event could be happend multiple times
452 on some heavy environment. This callback del will prevent those scenario and
453 guarantee only one clicked for it's own page. */
454 evas_object_smart_callback_del(obj, "clicked", _back_btn_clicked);
455 elm_naviframe_item_pop(data);
459 _back_btn_new(Evas_Object *obj)
463 btn = elm_button_add(obj);
464 if (!btn) return NULL;
465 evas_object_smart_callback_add(btn, "clicked", _back_btn_clicked, obj);
466 snprintf(buf, sizeof(buf), "naviframe/back_btn/%s",
467 elm_widget_style_get(obj));
468 elm_object_style_set(btn, buf);
472 static void _text_set_hook(Evas_Object *obj,
476 Elm_Object_Item *it = elm_naviframe_top_item_get(obj);
478 elm_object_item_part_text_set(it, part, label);
481 static const char *_text_get_hook(const Evas_Object *obj, const char *part)
483 Elm_Object_Item *it = elm_naviframe_top_item_get(obj);
484 if (!it) return NULL;
485 return elm_object_item_part_text_get(it, part);
489 _content_set_hook(Evas_Object *obj, const char *part, Evas_Object *content)
491 Elm_Object_Item *it = elm_naviframe_top_item_get(obj);
493 elm_object_item_part_content_set(it, part, content);
497 _content_unset_hook(Evas_Object *obj, const char *part)
499 Elm_Object_Item *it = elm_naviframe_top_item_get(obj);
500 if (!it) return NULL;
501 return elm_object_item_part_content_unset(it, part);
505 _content_get_hook(const Evas_Object *obj, const char *part)
507 Elm_Object_Item *it = elm_naviframe_top_item_get(obj);
508 if (!it) return NULL;
509 return elm_object_item_part_content_get(it, part);
513 _title_content_del(void *data,
515 Evas_Object *obj __UNUSED__,
516 void *event_info __UNUSED__)
519 Elm_Naviframe_Content_Item_Pair *pair = data;
520 Elm_Naviframe_Item *it = pair->it;
521 snprintf(buf, sizeof(buf), "elm,state,%s,hide", pair->part);
522 elm_object_signal_emit(VIEW(it), buf, "elm");
523 it->content_list = eina_inlist_remove(it->content_list,
524 EINA_INLIST_GET(pair));
525 eina_stringshare_del(pair->part);
530 _title_prev_btn_del(void *data,
532 Evas_Object *obj __UNUSED__,
533 void *event_info __UNUSED__)
535 Elm_Naviframe_Item *it = data;
536 it->back_btn = EINA_FALSE;
537 it->title_prev_btn = NULL;
538 elm_object_signal_emit(VIEW(it), "elm,state,prev_btn,hide", "elm");
542 _title_next_btn_del(void *data,
544 Evas_Object *obj __UNUSED__,
545 void *event_info __UNUSED__)
547 Elm_Naviframe_Item *it = data;
548 it->title_next_btn = NULL;
549 elm_object_signal_emit(VIEW(it), "elm,state,next_btn,hide", "elm");
553 _title_icon_del(void *data,
555 Evas_Object *obj __UNUSED__,
556 void *event_info __UNUSED__)
558 Elm_Naviframe_Item *it = data;
559 it->title_icon = NULL;
560 elm_object_signal_emit(VIEW(it), "elm,state,icon,hide", "elm");
564 _item_content_del(void *data,
566 Evas_Object *obj __UNUSED__,
567 void *event_info __UNUSED__)
569 Elm_Naviframe_Item *it = data;
571 elm_object_signal_emit(VIEW(it), "elm,state,content,hide", "elm");
575 _title_content_set(Elm_Naviframe_Item *it,
577 Evas_Object *content)
580 Elm_Naviframe_Content_Item_Pair *pair = NULL;
581 Evas_Object *prev_content = NULL;
583 EINA_INLIST_FOREACH(it->content_list, pair)
584 if (!strcmp(part, pair->part)) break;
588 prev_content = elm_object_part_content_get(VIEW(it), part);
589 if (prev_content != content)
593 evas_object_event_callback_del(prev_content,
596 snprintf(buf, sizeof(buf), "elm,state,%s,hide", part);
597 elm_object_signal_emit(VIEW(it), buf, "elm");
599 evas_object_del(prev_content);
600 if (!content) return;
605 if (!content) return;
606 pair = ELM_NEW(Elm_Naviframe_Content_Item_Pair);
609 ERR("Failed to allocate new content part of the item! : naviframe=%p", WIDGET(it));
613 eina_stringshare_replace(&pair->part, part);
614 it->content_list = eina_inlist_append(it->content_list,
615 EINA_INLIST_GET(pair));
617 if (prev_content != content)
619 evas_object_event_callback_add(content,
624 elm_object_part_content_set(VIEW(it), part, content);
625 snprintf(buf, sizeof(buf), "elm,state,%s,show", part);
626 elm_object_signal_emit(VIEW(it), buf, "elm");
628 _sizing_eval(WIDGET(it));
632 _title_prev_btn_set(Elm_Naviframe_Item *it,
636 if (it->title_prev_btn == btn) return;
637 if (it->title_prev_btn) evas_object_del(it->title_prev_btn);
638 it->title_prev_btn = btn;
641 evas_object_event_callback_add(btn,
645 elm_object_part_content_set(VIEW(it), "elm.swallow.prev_btn", btn);
646 elm_object_signal_emit(VIEW(it), "elm,state,prev_btn,show", "elm");
647 it->back_btn = back_btn;
649 _sizing_eval(WIDGET(it));
653 _title_next_btn_set(Elm_Naviframe_Item *it, Evas_Object *btn)
655 if (it->title_next_btn == btn) return;
656 if (it->title_next_btn) evas_object_del(it->title_next_btn);
657 it->title_next_btn = btn;
660 evas_object_event_callback_add(btn,
664 elm_object_part_content_set(VIEW(it), "elm.swallow.next_btn", btn);
665 elm_object_signal_emit(VIEW(it), "elm,state,next_btn,show", "elm");
667 _sizing_eval(WIDGET(it));
671 _title_icon_set(Elm_Naviframe_Item *it, Evas_Object *icon)
673 if (it->title_icon == icon) return;
674 if (it->title_icon) evas_object_del(it->title_icon);
675 it->title_icon = icon;
678 evas_object_event_callback_add(icon,
682 elm_object_part_content_set(VIEW(it), "elm.swallow.icon", icon);
683 elm_object_signal_emit(VIEW(it), "elm,state,icon,show", "elm");
685 _sizing_eval(WIDGET(it));
689 _item_content_unset(Elm_Naviframe_Item *it)
691 Evas_Object *content = it->content;
692 if (!content) return NULL;
694 elm_object_part_content_unset(VIEW(it), "elm.swallow.content");
695 elm_object_signal_emit(VIEW(it), "elm,state,content,hide", "elm");
696 evas_object_event_callback_del(content,
699 _sizing_eval(WIDGET(it));
706 _title_prev_btn_unset(Elm_Naviframe_Item *it)
708 Evas_Object *content = it->title_prev_btn;
709 if (!content) return NULL;
711 elm_object_part_content_unset(VIEW(it), "elm.swallow.prev_btn");
712 elm_object_signal_emit(VIEW(it), "elm,state,prev_btn,hide", "elm");
713 evas_object_event_callback_del(content,
715 _title_prev_btn_del);
716 _sizing_eval(WIDGET(it));
718 it->title_prev_btn = NULL;
723 _title_next_btn_unset(Elm_Naviframe_Item *it)
725 Evas_Object *content = it->title_next_btn;
726 if (!content) return NULL;
728 elm_object_part_content_unset(VIEW(it), "elm.swallow.next_btn");
729 elm_object_signal_emit(VIEW(it), "elm,state,next_btn,hide", "elm");
730 evas_object_event_callback_del(content,
732 _title_next_btn_del);
733 _sizing_eval(WIDGET(it));
735 it->title_next_btn = NULL;
740 _title_icon_unset(Elm_Naviframe_Item *it)
742 Evas_Object *content = it->title_icon;
743 if (!content) return NULL;
745 elm_object_part_content_unset(VIEW(it), "elm.swallow.icon");
746 elm_object_signal_emit(VIEW(it), "elm,state,icon,hide", "elm");
747 evas_object_event_callback_del(content,
750 _sizing_eval(WIDGET(it));
751 it->title_icon = NULL;
757 _title_content_unset(Elm_Naviframe_Item *it, const char *part)
759 Elm_Naviframe_Content_Item_Pair *pair = NULL;
761 Evas_Object *content = NULL;
763 EINA_INLIST_FOREACH(it->content_list, pair)
765 if (!strcmp(part, pair->part))
767 content = elm_object_part_content_get(VIEW(it), part);
768 eina_stringshare_del(pair->part);
769 it->content_list = eina_inlist_remove(it->content_list,
770 EINA_INLIST_GET(pair));
776 if (!content) return NULL;
778 elm_object_part_content_unset(VIEW(it), part);
779 snprintf(buf, sizeof(buf), "elm,state,%s,hide", part);
780 elm_object_signal_emit(VIEW(it), buf, "elm");
781 evas_object_event_callback_del(content,
784 _sizing_eval(WIDGET(it));
790 _item_del(Elm_Naviframe_Item *it)
793 Elm_Naviframe_Content_Item_Pair *content_pair;
794 Elm_Naviframe_Text_Item_Pair *text_pair;
795 Evas_Object *content;
799 wd = elm_widget_data_get(WIDGET(it));
802 while (it->content_list)
805 EINA_INLIST_CONTAINER_GET(it->content_list,
806 Elm_Naviframe_Content_Item_Pair);
807 content = elm_object_part_content_get(VIEW(it), content_pair->part);
808 evas_object_event_callback_del(content,
811 eina_stringshare_del(content_pair->part);
812 it->content_list = eina_inlist_remove(it->content_list,
817 while (it->text_list)
819 text_pair = EINA_INLIST_CONTAINER_GET(it->text_list,
820 Elm_Naviframe_Text_Item_Pair);
821 eina_stringshare_del(text_pair->part);
822 it->text_list = eina_inlist_remove(it->text_list,
827 eina_stringshare_del(it->style);
831 _item_del_pre_hook(Elm_Object_Item *it)
833 Elm_Naviframe_Item *navi_it;
836 navi_it =(Elm_Naviframe_Item *) it;
837 wd = elm_widget_data_get(WIDGET(navi_it));
838 if (!wd) return EINA_FALSE;
840 if (it == elm_naviframe_top_item_get(WIDGET(navi_it)))
842 wd->stack = eina_inlist_remove(wd->stack, EINA_INLIST_GET(navi_it));
844 //If the item is only one, the stack will be empty
845 if (!wd->stack) return EINA_TRUE;
846 navi_it = EINA_INLIST_CONTAINER_GET(wd->stack->last,
848 evas_object_show(VIEW(navi_it));
849 evas_object_raise(VIEW(navi_it));
850 elm_object_signal_emit(VIEW(navi_it), "elm,state,visible", "elm");
854 wd->stack = eina_inlist_remove(wd->stack, EINA_INLIST_GET(navi_it));
862 _pushed_finished(void *data,
863 Evas_Object *obj __UNUSED__,
864 const char *emission __UNUSED__,
865 const char *source __UNUSED__)
868 Elm_Naviframe_Item *it = data;
871 wd = elm_widget_data_get(WIDGET(it));
874 evas_object_hide(VIEW(it));
875 if (wd->freeze_events)
876 evas_object_freeze_events_set(VIEW(it), EINA_FALSE);
878 elm_widget_item_smart_callback_call(it,
879 SIG_ITEM_HIDE_FINISHED,
884 _popped_finished(void *data,
885 Evas_Object *obj __UNUSED__,
886 const char *emission __UNUSED__,
887 const char *source __UNUSED__)
889 Elm_Naviframe_Item *it = data;
892 elm_widget_item_free(data);
896 _show_finished(void *data,
897 Evas_Object *obj __UNUSED__,
898 const char *emission __UNUSED__,
899 const char *source __UNUSED__)
901 Elm_Naviframe_Item *it;
906 wd = elm_widget_data_get(WIDGET(it));
909 evas_object_smart_callback_call(WIDGET(it),
910 SIG_TRANSITION_FINISHED,
912 if (wd->freeze_events)
913 evas_object_freeze_events_set(VIEW(it), EINA_FALSE);
917 _changed_size_hints(void *data,
919 Evas_Object *obj __UNUSED__,
920 void *event_info __UNUSED__)
926 _item_content_set(Elm_Naviframe_Item *navi_it, Evas_Object *content)
928 if (navi_it->content == content) return;
929 if (navi_it->content) evas_object_del(navi_it->content);
930 elm_object_part_content_set(VIEW(navi_it), "elm.swallow.content", content);
933 elm_object_signal_emit(VIEW(navi_it), "elm,state,content,show", "elm");
935 elm_object_signal_emit(VIEW(navi_it), "elm,state,content,hide", "elm");
937 evas_object_event_callback_add(content,
941 navi_it->content = content;
942 _sizing_eval(WIDGET(navi_it));
945 //FIXME: need to handle if this function is called while transition
947 _item_style_set(Elm_Naviframe_Item *navi_it, const char *item_style)
949 Elm_Naviframe_Content_Item_Pair *content_pair;
950 Elm_Naviframe_Text_Item_Pair *text_pair;
952 wd = elm_widget_data_get(WIDGET(navi_it));
959 snprintf(buf, sizeof(buf), "item/%s", wd->item_style);
963 snprintf(buf, sizeof(buf), "item/%s", item_style);
964 eina_stringshare_replace(&navi_it->style, item_style);
966 elm_layout_theme_set(VIEW(navi_it),
969 elm_widget_style_get(WIDGET(navi_it)));
971 EINA_INLIST_FOREACH(navi_it->text_list, text_pair)
972 _item_text_set_hook((Elm_Object_Item *) navi_it,
974 elm_object_part_text_get(VIEW(navi_it),
977 EINA_INLIST_FOREACH(navi_it->content_list, content_pair)
978 _item_content_set_hook((Elm_Object_Item *) navi_it,
980 elm_object_part_content_get(VIEW(navi_it),
981 content_pair->part));
983 if (navi_it->content)
984 elm_object_signal_emit(VIEW(navi_it), "elm,state,content,show", "elm");
987 if (navi_it->title_prev_btn)
988 elm_object_signal_emit(VIEW(navi_it), "elm,state,prev_btn,show", "elm");
991 if (navi_it->title_next_btn)
992 elm_object_signal_emit(VIEW(navi_it), "elm,state,next_btn,show", "elm");
994 // why does this forcibly enable title? isnt that separate to style?
995 // navi_it->title_visible = EINA_TRUE;
996 _sizing_eval(WIDGET(navi_it));
998 if (wd->freeze_events)
999 evas_object_freeze_events_set(VIEW(navi_it), EINA_FALSE);
1002 static Elm_Naviframe_Item *
1003 _item_new(Evas_Object *obj,
1004 const char *title_label,
1005 Evas_Object *prev_btn,
1006 Evas_Object *next_btn,
1007 Evas_Object *content,
1008 const char *item_style)
1010 Widget_Data *wd = elm_widget_data_get(obj);
1013 Elm_Naviframe_Item *it = elm_widget_item_new(obj, Elm_Naviframe_Item);
1016 ERR("Failed to allocate new item! : naviframe=%p", obj);
1020 elm_widget_item_del_pre_hook_set(it, _item_del_pre_hook);
1021 elm_widget_item_text_set_hook_set(it, _item_text_set_hook);
1022 elm_widget_item_text_get_hook_set(it, _item_text_get_hook);
1023 elm_widget_item_content_set_hook_set(it, _item_content_set_hook);
1024 elm_widget_item_content_get_hook_set(it, _item_content_get_hook);
1025 elm_widget_item_content_unset_hook_set(it, _item_content_unset_hook);
1026 elm_widget_item_signal_emit_hook_set(it, _item_signal_emit_hook);
1029 VIEW(it) = elm_layout_add(obj);
1030 evas_object_smart_member_add(VIEW(it), wd->base);
1032 evas_object_event_callback_add(VIEW(it),
1033 EVAS_CALLBACK_CHANGED_SIZE_HINTS,
1034 _changed_size_hints,
1036 elm_object_signal_callback_add(VIEW(it),
1037 "elm,action,show,finished",
1039 _show_finished, it);
1040 elm_object_signal_callback_add(VIEW(it),
1041 "elm,action,pushed,finished",
1043 _pushed_finished, it);
1044 elm_object_signal_callback_add(VIEW(it),
1045 "elm,action,popped,finished",
1047 _popped_finished, it);
1048 elm_object_signal_callback_add(VIEW(it),
1049 "elm,action,title,clicked",
1051 _title_clicked, it);
1053 _item_style_set(it, item_style);
1054 _item_text_set_hook((Elm_Object_Item *) it, "elm.text.title", title_label);
1057 if ((!prev_btn) && wd->auto_pushed && eina_inlist_count(wd->stack))
1059 prev_btn = _back_btn_new(obj);
1060 _title_prev_btn_set(it, prev_btn, EINA_TRUE);
1063 _title_prev_btn_set(it, prev_btn, EINA_FALSE);
1065 _title_next_btn_set(it, next_btn);
1066 _item_content_set(it, content);
1067 it->title_visible = EINA_TRUE;
1072 _focus_next_hook(const Evas_Object *obj, Elm_Focus_Direction dir, Evas_Object **next)
1074 Widget_Data *wd = elm_widget_data_get(obj);
1075 if (!wd || !wd->stack) return EINA_FALSE;
1076 return elm_widget_focus_next_get(VIEW(elm_naviframe_top_item_get(obj)),
1082 elm_naviframe_add(Evas_Object *parent)
1088 ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL);
1089 ELM_SET_WIDTYPE(widtype, "naviframe");
1090 elm_widget_type_set(obj, "naviframe");
1091 elm_widget_sub_object_add(parent, obj);
1092 elm_widget_data_set(obj, wd);
1093 elm_widget_del_hook_set(obj, _del_hook);
1094 elm_widget_disable_hook_set(obj, _disable_hook);
1095 elm_widget_theme_hook_set(obj, _theme_hook);
1096 elm_widget_text_set_hook_set(obj, _text_set_hook);
1097 elm_widget_text_get_hook_set(obj, _text_get_hook);
1098 elm_widget_content_set_hook_set(obj, _content_set_hook);
1099 elm_widget_content_get_hook_set(obj, _content_get_hook);
1100 elm_widget_content_unset_hook_set(obj, _content_unset_hook);
1101 elm_widget_signal_emit_hook_set(obj, _emit_hook);
1102 elm_widget_can_focus_set(obj, EINA_FALSE);
1103 elm_widget_focus_next_hook_set(obj, _focus_next_hook);
1106 //FIXME: Is this base layout really needed?
1107 wd->base = elm_layout_add(parent);
1108 evas_object_event_callback_add(wd->base,
1109 EVAS_CALLBACK_CHANGED_SIZE_HINTS,
1110 _changed_size_hints,
1112 elm_widget_resize_object_set(obj, wd->base);
1113 elm_layout_theme_set(wd->base, "naviframe", "base", "default");
1115 evas_object_event_callback_add(obj, EVAS_CALLBACK_MOVE, _move, obj);
1116 evas_object_event_callback_add(obj, EVAS_CALLBACK_RESIZE, _resize, obj);
1117 evas_object_smart_callbacks_descriptions_set(obj, _signals);
1119 wd->auto_pushed = EINA_TRUE;
1120 wd->freeze_events = EINA_TRUE;
1121 wd->item_style = eina_stringshare_add("basic");
1126 EAPI Elm_Object_Item *
1127 elm_naviframe_item_push(Evas_Object *obj,
1128 const char *title_label,
1129 Evas_Object *prev_btn,
1130 Evas_Object *next_btn,
1131 Evas_Object *content,
1132 const char *item_style)
1134 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1136 Elm_Naviframe_Item *prev_it, *it;
1138 wd = elm_widget_data_get(obj);
1139 if (!wd) return NULL;
1141 it = _item_new(obj, title_label, prev_btn, next_btn, content, item_style);
1142 if (!it) return NULL;
1144 evas_object_show(VIEW(it));
1146 prev_it = (Elm_Naviframe_Item *) elm_naviframe_top_item_get(obj);
1149 if (wd->freeze_events)
1151 evas_object_freeze_events_set(VIEW(it), EINA_TRUE);
1152 evas_object_freeze_events_set(VIEW(prev_it), EINA_TRUE);
1154 elm_object_signal_emit(VIEW(prev_it), "elm,state,cur,pushed", "elm");
1155 elm_object_signal_emit(VIEW(it), "elm,state,new,pushed", "elm");
1156 edje_object_message_signal_process(elm_layout_edje_get(VIEW(prev_it)));
1157 elm_widget_tree_unfocusable_set(it->content, EINA_TRUE);
1158 edje_object_message_signal_process(elm_layout_edje_get(VIEW(it)));
1160 wd->stack = eina_inlist_append(wd->stack, EINA_INLIST_GET(it));
1162 return (Elm_Object_Item *) it;
1165 EAPI Elm_Object_Item *
1166 elm_naviframe_item_insert_before(Elm_Object_Item *before,
1167 const char *title_label,
1168 Evas_Object *prev_btn,
1169 Evas_Object *next_btn,
1170 Evas_Object *content,
1171 const char *item_style)
1173 ELM_OBJ_ITEM_CHECK_OR_RETURN(before, NULL);
1174 Elm_Naviframe_Item *it;
1177 wd = elm_widget_data_get(WIDGET(before));
1178 if (!wd) return NULL;
1180 it = _item_new(WIDGET(before), title_label, prev_btn, next_btn, content,
1182 if (!it) return NULL;
1185 eina_inlist_prepend_relative(wd->stack,
1186 EINA_INLIST_GET(it),
1187 EINA_INLIST_GET(((Elm_Naviframe_Item *) before)));
1188 _sizing_eval(WIDGET(before));
1189 return (Elm_Object_Item *) it;
1192 EAPI Elm_Object_Item *
1193 elm_naviframe_item_insert_after(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_OBJ_ITEM_CHECK_OR_RETURN(after, NULL);
1201 Elm_Naviframe_Item *it;
1204 wd = elm_widget_data_get(WIDGET(after));
1205 if (!wd) return NULL;
1207 it = _item_new(WIDGET(after), title_label, prev_btn, next_btn, content,
1209 if (!it) return NULL;
1211 if (elm_naviframe_top_item_get(WIDGET(after)) == after)
1213 evas_object_hide(VIEW(after));
1214 evas_object_show(VIEW(it));
1217 eina_inlist_append_relative(wd->stack,
1218 EINA_INLIST_GET(it),
1219 EINA_INLIST_GET(((Elm_Naviframe_Item *) after)));
1220 _sizing_eval(WIDGET(after));
1221 return (Elm_Object_Item *) it;
1225 elm_naviframe_item_pop(Evas_Object *obj)
1227 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1228 Elm_Naviframe_Item *it, *prev_it = NULL;
1230 Evas_Object *content = NULL;
1232 wd = elm_widget_data_get(obj);
1233 if (!wd) return NULL;
1235 it = (Elm_Naviframe_Item *) elm_naviframe_top_item_get(obj);
1236 if (!it) return NULL;
1238 content = it->content;
1240 if (wd->stack->last->prev)
1241 prev_it = EINA_INLIST_CONTAINER_GET(wd->stack->last->prev,
1242 Elm_Naviframe_Item);
1243 wd->stack = eina_inlist_remove(wd->stack, EINA_INLIST_GET(it));
1246 if (wd->freeze_events)
1248 evas_object_freeze_events_set(VIEW(it), EINA_TRUE);
1249 evas_object_freeze_events_set(VIEW(prev_it), EINA_TRUE);
1251 elm_object_signal_emit(VIEW(it), "elm,state,cur,popped", "elm");
1252 evas_object_show(VIEW(prev_it));
1253 evas_object_raise(VIEW(prev_it));
1254 elm_object_signal_emit(VIEW(prev_it),
1255 "elm,state,prev,popped",
1257 edje_object_message_signal_process(elm_layout_edje_get(VIEW(it)));
1258 edje_object_message_signal_process(elm_layout_edje_get(VIEW(prev_it)));
1259 elm_widget_item_smart_callback_call(prev_it,
1260 SIG_ITEM_SHOW_BEGIN,
1266 elm_widget_item_free(it);
1273 elm_naviframe_item_pop_to(Elm_Object_Item *it)
1275 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1276 Elm_Naviframe_Item *navi_it;
1278 Eina_Inlist *l, *prev_l;
1280 navi_it = (Elm_Naviframe_Item *) it;
1281 wd = elm_widget_data_get(WIDGET(navi_it));
1284 if (it == elm_naviframe_top_item_get(WIDGET(navi_it))) return;
1286 l = wd->stack->last->prev;
1290 if (EINA_INLIST_CONTAINER_GET(l, Elm_Naviframe_Item) ==
1291 ((Elm_Naviframe_Item *) it)) break;
1293 wd->stack = eina_inlist_remove(wd->stack, l);
1294 _item_del(EINA_INLIST_CONTAINER_GET(l, Elm_Naviframe_Item));
1295 elm_widget_item_free(EINA_INLIST_CONTAINER_GET(l,
1296 Elm_Naviframe_Item));
1299 elm_naviframe_item_pop(WIDGET(navi_it));
1303 elm_naviframe_item_promote(Elm_Object_Item *it)
1305 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1306 Elm_Naviframe_Item *navi_it;
1307 Elm_Naviframe_Item *prev_it;
1310 navi_it = (Elm_Naviframe_Item *) it;
1311 wd = elm_widget_data_get(navi_it->base.widget);
1314 if (it == elm_naviframe_top_item_get(navi_it->base.widget)) return;
1315 elm_widget_tree_unfocusable_set(navi_it->content, EINA_FALSE);
1316 wd->stack = eina_inlist_demote(wd->stack, EINA_INLIST_GET(navi_it));
1317 prev_it = EINA_INLIST_CONTAINER_GET(wd->stack->last->prev,
1318 Elm_Naviframe_Item);
1319 elm_widget_tree_unfocusable_set(prev_it->content, EINA_FALSE);
1320 if (wd->freeze_events)
1322 evas_object_freeze_events_set(VIEW(it), EINA_TRUE);
1323 evas_object_freeze_events_set(VIEW(prev_it), EINA_TRUE);
1325 elm_object_signal_emit(VIEW(prev_it),
1326 "elm,state,cur,pushed",
1328 evas_object_show(VIEW(navi_it));
1329 evas_object_raise(VIEW(navi_it));
1330 elm_object_signal_emit(VIEW(navi_it),
1331 "elm,state,new,pushed",
1333 edje_object_message_signal_process(elm_layout_edje_get(VIEW(prev_it)));
1334 edje_object_message_signal_process(elm_layout_edje_get(VIEW(navi_it)));
1338 elm_naviframe_item_simple_promote(Evas_Object *obj, Evas_Object *content)
1340 ELM_CHECK_WIDTYPE(obj, widtype);
1341 Widget_Data *wd = elm_widget_data_get(obj);
1343 Elm_Naviframe_Item *itr;
1344 EINA_INLIST_FOREACH(wd->stack, itr)
1346 if (elm_object_item_content_get((Elm_Object_Item *) itr) == content)
1348 elm_naviframe_item_promote((Elm_Object_Item *) itr);
1356 elm_naviframe_item_del(Elm_Object_Item *it)
1358 elm_object_item_del(it);
1362 elm_naviframe_content_preserve_on_pop_set(Evas_Object *obj, Eina_Bool preserve)
1364 ELM_CHECK_WIDTYPE(obj, widtype);
1365 Widget_Data *wd = elm_widget_data_get(obj);
1367 wd->preserve = !!preserve;
1371 elm_naviframe_content_preserve_on_pop_get(const Evas_Object *obj)
1373 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
1374 Widget_Data *wd = elm_widget_data_get(obj);
1375 if (!wd) return EINA_FALSE;
1376 return wd->preserve;
1379 EAPI Elm_Object_Item*
1380 elm_naviframe_top_item_get(const Evas_Object *obj)
1382 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1383 Widget_Data *wd = elm_widget_data_get(obj);
1384 if ((!wd) || (!wd->stack)) return NULL;
1385 return (Elm_Object_Item *) (EINA_INLIST_CONTAINER_GET(wd->stack->last,
1386 Elm_Naviframe_Item));
1389 EAPI Elm_Object_Item*
1390 elm_naviframe_bottom_item_get(const Evas_Object *obj)
1392 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1393 Widget_Data *wd = elm_widget_data_get(obj);
1394 if ((!wd) || (!wd->stack)) return NULL;
1395 return (Elm_Object_Item *) (EINA_INLIST_CONTAINER_GET(wd->stack,
1396 Elm_Naviframe_Item));
1400 elm_naviframe_item_style_set(Elm_Object_Item *it, const char *item_style)
1402 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1403 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
1405 //Return if new style is exsiting one.
1406 if ((item_style && navi_it->style) && (!strcmp(item_style, navi_it->style)))
1409 if ((!item_style) && (!navi_it->style))
1412 _item_style_set(navi_it, item_style);
1416 elm_naviframe_item_style_get(const Elm_Object_Item *it)
1418 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
1419 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
1420 return navi_it->style;
1424 elm_naviframe_item_title_visible_set(Elm_Object_Item *it, Eina_Bool visible)
1426 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1427 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
1429 visible = !!visible;
1430 if (navi_it->title_visible == visible) return;
1432 navi_it->title_visible = visible;
1433 _item_title_visible_update(navi_it);
1437 elm_naviframe_item_title_visible_get(const Elm_Object_Item *it)
1439 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
1440 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
1441 return navi_it->title_visible;
1445 elm_naviframe_prev_btn_auto_pushed_set(Evas_Object *obj, Eina_Bool auto_pushed)
1447 ELM_CHECK_WIDTYPE(obj, widtype);
1448 Widget_Data *wd = elm_widget_data_get(obj);
1450 wd->auto_pushed = !!auto_pushed;
1454 elm_naviframe_prev_btn_auto_pushed_get(const Evas_Object *obj)
1456 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
1457 Widget_Data *wd = elm_widget_data_get(obj);
1458 if (!wd) return EINA_FALSE;
1459 return wd->auto_pushed;
1463 elm_naviframe_items_get(const Evas_Object *obj)
1465 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1466 Widget_Data *wd = elm_widget_data_get(obj);
1467 if (!wd) return NULL;
1468 Eina_List *ret = NULL;
1469 Elm_Naviframe_Item *itr;
1470 EINA_INLIST_FOREACH(wd->stack, itr)
1471 ret = eina_list_append(ret, itr);
1476 elm_naviframe_event_enabled_set(Evas_Object *obj, Eina_Bool enabled)
1478 ELM_CHECK_WIDTYPE(obj, widtype);
1479 Widget_Data *wd = elm_widget_data_get(obj);
1481 enabled = !!enabled;
1482 if (wd->freeze_events == !enabled) return;
1483 wd->freeze_events = !enabled;
1487 elm_naviframe_event_enabled_get(const Evas_Object *obj)
1489 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
1490 Widget_Data *wd = elm_widget_data_get(obj);
1491 if (!wd) return EINA_FALSE;
1492 return !wd->freeze_events;
1496 elm_naviframe_item_style_default_set(Evas_Object *obj, const char *style)
1498 ELM_CHECK_WIDTYPE(obj, widtype);
1499 Widget_Data *wd = elm_widget_data_get(obj);
1501 eina_stringshare_replace(&wd->item_style, style);
1506 elm_naviframe_item_style_default_get(const Evas_Object *obj)
1508 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1509 Widget_Data *wd = elm_widget_data_get(obj);
1510 if (!wd) return NULL;
1511 return wd->item_style;