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;
51 static const char SIG_TRANSITION_FINISHED[] = "transition,finished";
52 static const char SIG_PUSH_FINISHED[] = "push,finished";
53 static const char SIG_POP_FINISHED[] = "pop,finished";
54 static const char SIG_TITLE_CLICKED[] = "title,clicked";
56 static const Evas_Smart_Cb_Description _signals[] = {
57 {SIG_TRANSITION_FINISHED, ""},
58 {SIG_TITLE_CLICKED, ""},
62 static void _del_hook(Evas_Object *obj);
63 static void _theme_hook(Evas_Object *obj);
64 static void _emit_hook(Evas_Object *obj,
67 static void _disable_hook(Evas_Object *obj);
68 static void _item_text_set_hook(Elm_Object_Item *it,
71 static const char *_item_text_get_hook(const Elm_Object_Item *it,
73 static void _item_content_set_hook(Elm_Object_Item *it,
75 Evas_Object *content);
76 static Evas_Object *_item_content_get_hook(const Elm_Object_Item *it,
78 static Evas_Object *_item_content_unset_hook(Elm_Object_Item *it,
80 static void _item_signal_emit_hook(Elm_Object_Item *it,
83 static void _item_title_visible_update(Elm_Naviframe_Item *navi_it);
84 static void _sizing_eval(Evas_Object *obj);
85 static void _move(void *data, Evas *e, Evas_Object *obj, void *event_info);
86 static void _resize(void *data,
90 static void _title_clicked(void *data, Evas_Object *obj,
93 static void _back_btn_clicked(void *data,
96 static Evas_Object *_back_btn_new(Evas_Object *obj);
97 static void _item_content_del(void *data,
101 static void _title_content_del(void *data,
105 static void _title_prev_btn_del(void *data,
109 static void _title_next_btn_del(void *data,
113 static void _title_icon_del(void *data,
117 static void _title_content_set(Elm_Naviframe_Item *it,
119 Evas_Object *content);
120 static void _title_prev_btn_set(Elm_Naviframe_Item *it,
123 static void _title_next_btn_set(Elm_Naviframe_Item *it, Evas_Object *btn);
124 static void _title_icon_set(Elm_Naviframe_Item *it, Evas_Object *icon);
125 static Evas_Object * _item_content_unset(Elm_Naviframe_Item *it);
126 static Evas_Object * _title_prev_btn_unset(Elm_Naviframe_Item *it);
127 static Evas_Object * _title_next_btn_unset(Elm_Naviframe_Item *it);
128 static Evas_Object * _title_icon_unset(Elm_Naviframe_Item *it);
129 static Evas_Object * _title_content_unset(Elm_Naviframe_Item *it,
131 static void _item_del(Elm_Naviframe_Item *it);
132 static Eina_Bool _item_del_pre_hook(Elm_Object_Item *it);
133 static void _pushed_finished(void *data,
135 const char *emission,
137 static void _popped_finished(void *data,
139 const char *emission,
141 static void _show_finished(void *data,
143 const char *emission,
145 static void _changed_size_hints(void *data,
149 static void _item_content_set(Elm_Naviframe_Item *navi_it,
150 Evas_Object *content);
151 static void _item_style_set(Elm_Naviframe_Item *navi_it,
152 const char *item_style);
153 static Elm_Naviframe_Item * _item_new(Evas_Object *obj,
154 const char *title_label,
155 Evas_Object *prev_btn,
156 Evas_Object *next_btn,
157 Evas_Object *content,
158 const char *item_style);
159 static Eina_Bool _focus_next_hook(const Evas_Object *obj,
160 Elm_Focus_Direction dir,
164 _del_hook(Evas_Object *obj)
167 Elm_Naviframe_Item *it;
169 wd = elm_widget_data_get(obj);
174 while (wd->stack->last)
176 it = EINA_INLIST_CONTAINER_GET(wd->stack->last,
178 wd->stack = eina_inlist_remove(wd->stack, wd->stack->last);
180 elm_widget_item_free(it);
181 if (!wd->stack) break;
184 eina_stringshare_del(wd->item_style);
189 _theme_hook(Evas_Object *obj)
192 Elm_Naviframe_Item *it;
194 wd = elm_widget_data_get(obj);
197 _elm_theme_object_set(obj,
201 elm_widget_style_get(obj));
203 EINA_INLIST_FOREACH(wd->stack, it)
205 _item_style_set(it, it->style);
206 _item_title_visible_update(it);
210 static void _emit_hook(Evas_Object *obj,
211 const char *emission,
214 ELM_CHECK_WIDTYPE(obj, widtype);
216 Widget_Data *wd = elm_widget_data_get(obj);
219 elm_object_signal_emit(wd->base, emission, source);
223 _disable_hook(Evas_Object *obj __UNUSED__)
229 _item_text_set_hook(Elm_Object_Item *it,
233 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
235 Elm_Naviframe_Text_Item_Pair *pair = NULL;
236 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
239 if (!part || !strcmp(part, "default"))
240 snprintf(buf, sizeof(buf), "elm.text.title");
241 else if(!strcmp("subtitle", part))
242 snprintf(buf, sizeof(buf), "elm.text.subtitle");
244 snprintf(buf, sizeof(buf), "%s", part);
246 EINA_INLIST_FOREACH(navi_it->text_list, pair)
247 if (!strcmp(buf, pair->part)) break;
251 pair = ELM_NEW(Elm_Naviframe_Text_Item_Pair);
254 ERR("Failed to allocate new text part of the item! : naviframe=%p",
258 eina_stringshare_replace(&pair->part, buf);
259 navi_it->text_list = eina_inlist_append(navi_it->text_list,
260 EINA_INLIST_GET(pair));
262 elm_object_part_text_set(VIEW(navi_it), buf, label);
266 snprintf(buf, sizeof(buf), "elm,state,%s,show", buf);
267 elm_object_signal_emit(VIEW(navi_it), buf, "elm");
271 snprintf(buf, sizeof(buf), "elm,state,%s,hide", buf);
272 elm_object_signal_emit(VIEW(navi_it), buf, "elm");
275 _sizing_eval(WIDGET(navi_it));
279 _item_text_get_hook(const Elm_Object_Item *it, const char *part)
281 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
284 if (!part || !strcmp(part, "default"))
285 snprintf(buf, sizeof(buf), "elm.text.title");
286 else if(!strcmp("subtitle", part))
287 snprintf(buf, sizeof(buf), "elm.text.subtitle");
289 snprintf(buf, sizeof(buf), "%s", part);
291 return elm_object_part_text_get(VIEW(it), buf);
295 _item_content_set_hook(Elm_Object_Item *it,
297 Evas_Object *content)
299 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
301 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
304 if (!part || !strcmp("default", part))
306 _item_content_set(navi_it, content);
309 else if (!strcmp(part, "prev_btn"))
311 _title_prev_btn_set(navi_it, content, EINA_FALSE);
314 else if (!strcmp(part, "next_btn"))
316 _title_next_btn_set(navi_it, content);
319 else if (!strcmp(part, "icon"))
321 _title_icon_set(navi_it, content);
326 _title_content_set(navi_it, part, content);
330 _item_content_get_hook(const Elm_Object_Item *it, const char *part)
332 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
333 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
336 if (!part || !strcmp("default", part))
337 return navi_it->content;
338 else if (!strcmp(part, "prev_btn"))
339 return navi_it->title_prev_btn;
340 else if (!strcmp(part, "next_btn"))
341 return navi_it->title_next_btn;
342 else if (!strcmp(part, "icon"))
343 return navi_it->title_icon;
346 return elm_object_part_content_get(VIEW(navi_it), part);
350 _item_content_unset_hook(Elm_Object_Item *it, const char *part)
352 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
353 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
356 if (!part || !strcmp("default", part))
357 return _item_content_unset(navi_it);
358 else if (!strcmp(part, "prev_btn"))
359 return _title_prev_btn_unset(navi_it);
360 else if (!strcmp(part, "next_btn"))
361 return _title_next_btn_unset(navi_it);
362 else if (!strcmp(part, "icon"))
363 return _title_icon_unset(navi_it);
365 return _title_content_unset(navi_it, part);
369 _item_signal_emit_hook(Elm_Object_Item *it,
370 const char *emission,
373 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
374 elm_object_signal_emit(VIEW(it), emission, source);
378 _item_title_visible_update(Elm_Naviframe_Item *navi_it)
380 if (navi_it->title_visible)
381 elm_object_signal_emit(VIEW(navi_it), "elm,state,title,show", "elm");
383 elm_object_signal_emit(VIEW(navi_it), "elm,state,title,hide", "elm");
387 _sizing_eval(Evas_Object *obj)
390 Elm_Naviframe_Item *it;
391 Evas_Coord x, y, w, h;
392 Evas_Coord minw = -1, minh = -1;
394 wd = elm_widget_data_get(obj);
397 evas_object_geometry_get(obj, &x, &y, &w, &h);
399 EINA_INLIST_FOREACH(wd->stack, it)
401 evas_object_move(VIEW(it), x, y);
402 evas_object_resize(VIEW(it), w, h);
403 edje_object_size_min_calc(elm_layout_edje_get(VIEW(it)),
406 if (it->minw > minw) minw = it->minw;
407 if (it->minh > minh) minh = it->minh;
409 evas_object_size_hint_min_set(obj, minw, minh);
410 evas_object_size_hint_max_set(obj, -1, -1);
414 _move(void *data __UNUSED__,
417 void *event_info __UNUSED__)
423 _resize(void *data __UNUSED__,
426 void *event_info __UNUSED__)
432 _title_clicked(void *data,
433 Evas_Object *obj __UNUSED__,
434 const char *emission __UNUSED__,
435 const char *source __UNUSED__)
437 Elm_Naviframe_Item *it = data;
438 evas_object_smart_callback_call(WIDGET(it), SIG_TITLE_CLICKED, it);
442 _back_btn_clicked(void *data,
444 void *event_info __UNUSED__)
446 /* Since edje has the event queue, clicked event could be happend multiple times
447 on some heavy environment. This callback del will prevent those scenario and
448 guarantee only one clicked for it's own page. */
449 evas_object_smart_callback_del(obj, "clicked", _back_btn_clicked);
450 elm_naviframe_item_pop(data);
454 _back_btn_new(Evas_Object *obj)
458 btn = elm_button_add(obj);
459 if (!btn) return NULL;
460 evas_object_smart_callback_add(btn, "clicked", _back_btn_clicked, obj);
461 snprintf(buf, sizeof(buf), "naviframe/back_btn/%s", elm_widget_style_get(obj));
462 elm_object_style_set(btn, buf);
467 _title_content_del(void *data,
469 Evas_Object *obj __UNUSED__,
470 void *event_info __UNUSED__)
473 Elm_Naviframe_Content_Item_Pair *pair = data;
474 Elm_Naviframe_Item *it = pair->it;
475 snprintf(buf, sizeof(buf), "elm,state,%s,hide", pair->part);
476 elm_object_signal_emit(VIEW(it), buf, "elm");
477 it->content_list = eina_inlist_remove(it->content_list,
478 EINA_INLIST_GET(pair));
479 eina_stringshare_del(pair->part);
484 _title_prev_btn_del(void *data,
486 Evas_Object *obj __UNUSED__,
487 void *event_info __UNUSED__)
489 Elm_Naviframe_Item *it = data;
490 it->back_btn = EINA_FALSE;
491 it->title_prev_btn = NULL;
492 elm_object_signal_emit(VIEW(it), "elm,state,prev_btn,hide", "elm");
496 _title_next_btn_del(void *data,
498 Evas_Object *obj __UNUSED__,
499 void *event_info __UNUSED__)
501 Elm_Naviframe_Item *it = data;
502 it->title_next_btn = NULL;
503 elm_object_signal_emit(VIEW(it), "elm,state,next_btn,hide", "elm");
507 _title_icon_del(void *data,
509 Evas_Object *obj __UNUSED__,
510 void *event_info __UNUSED__)
512 Elm_Naviframe_Item *it = data;
513 it->title_icon = NULL;
514 elm_object_signal_emit(VIEW(it), "elm,state,icon,hide", "elm");
518 _item_content_del(void *data,
520 Evas_Object *obj __UNUSED__,
521 void *event_info __UNUSED__)
523 Elm_Naviframe_Item *it = data;
525 elm_object_signal_emit(VIEW(it), "elm,state,content,hide", "elm");
529 _title_content_set(Elm_Naviframe_Item *it,
531 Evas_Object *content)
534 Elm_Naviframe_Content_Item_Pair *pair = NULL;
535 Evas_Object *prev_content = NULL;
537 EINA_INLIST_FOREACH(it->content_list, pair)
538 if (!strcmp(part, pair->part)) break;
542 prev_content = elm_object_part_content_get(VIEW(it), part);
543 if (prev_content != content)
547 evas_object_event_callback_del(prev_content,
550 snprintf(buf, sizeof(buf), "elm,state,%s,hide", part);
551 elm_object_signal_emit(VIEW(it), buf, "elm");
553 evas_object_del(prev_content);
554 if (!content) return;
559 if (!content) return;
560 pair = ELM_NEW(Elm_Naviframe_Content_Item_Pair);
563 ERR("Failed to allocate new content part of the item! : naviframe=%p", WIDGET(it));
567 eina_stringshare_replace(&pair->part, part);
568 it->content_list = eina_inlist_append(it->content_list,
569 EINA_INLIST_GET(pair));
571 if (prev_content != content)
573 evas_object_event_callback_add(content,
578 elm_object_part_content_set(VIEW(it), part, content);
579 snprintf(buf, sizeof(buf), "elm,state,%s,show", part);
580 elm_object_signal_emit(VIEW(it), buf, "elm");
582 _sizing_eval(WIDGET(it));
586 _title_prev_btn_set(Elm_Naviframe_Item *it,
590 if (it->title_prev_btn == btn) return;
591 if (it->title_prev_btn) evas_object_del(it->title_prev_btn);
592 it->title_prev_btn = btn;
595 evas_object_event_callback_add(btn,
599 elm_object_part_content_set(VIEW(it), "elm.swallow.prev_btn", btn);
600 elm_object_signal_emit(VIEW(it), "elm,state,prev_btn,show", "elm");
601 it->back_btn = back_btn;
603 _sizing_eval(WIDGET(it));
607 _title_next_btn_set(Elm_Naviframe_Item *it, Evas_Object *btn)
609 if (it->title_next_btn == btn) return;
610 if (it->title_next_btn) evas_object_del(it->title_next_btn);
611 it->title_next_btn = btn;
614 evas_object_event_callback_add(btn,
618 elm_object_part_content_set(VIEW(it), "elm.swallow.next_btn", btn);
619 elm_object_signal_emit(VIEW(it), "elm,state,next_btn,show", "elm");
621 _sizing_eval(WIDGET(it));
625 _title_icon_set(Elm_Naviframe_Item *it, Evas_Object *icon)
627 if (it->title_icon == icon) return;
628 if (it->title_icon) evas_object_del(it->title_icon);
629 it->title_icon = icon;
632 evas_object_event_callback_add(icon,
636 elm_object_part_content_set(VIEW(it), "elm.swallow.icon", icon);
637 elm_object_signal_emit(VIEW(it), "elm,state,icon,show", "elm");
639 _sizing_eval(WIDGET(it));
643 _item_content_unset(Elm_Naviframe_Item *it)
645 Evas_Object *content = it->content;
646 if (!content) return NULL;
648 elm_object_part_content_unset(VIEW(it), "elm.swallow.content");
649 elm_object_signal_emit(VIEW(it), "elm,state,content,hide", "elm");
650 evas_object_event_callback_del(content,
653 _sizing_eval(WIDGET(it));
660 _title_prev_btn_unset(Elm_Naviframe_Item *it)
662 Evas_Object *content = it->title_prev_btn;
663 if (!content) return NULL;
665 elm_object_part_content_unset(VIEW(it), "elm.swallow.prev_btn");
666 elm_object_signal_emit(VIEW(it), "elm,state,prev_btn,hide", "elm");
667 evas_object_event_callback_del(content,
669 _title_prev_btn_del);
670 _sizing_eval(WIDGET(it));
672 it->title_prev_btn = NULL;
677 _title_next_btn_unset(Elm_Naviframe_Item *it)
679 Evas_Object *content = it->title_next_btn;
680 if (!content) return NULL;
682 elm_object_part_content_unset(VIEW(it), "elm.swallow.next_btn");
683 elm_object_signal_emit(VIEW(it), "elm,state,next_btn,hide", "elm");
684 evas_object_event_callback_del(content,
686 _title_next_btn_del);
687 _sizing_eval(WIDGET(it));
689 it->title_next_btn = NULL;
694 _title_icon_unset(Elm_Naviframe_Item *it)
696 Evas_Object *content = it->title_icon;
697 if (!content) return NULL;
699 elm_object_part_content_unset(VIEW(it), "elm.swallow.icon");
700 elm_object_signal_emit(VIEW(it), "elm,state,icon,hide", "elm");
701 evas_object_event_callback_del(content,
704 _sizing_eval(WIDGET(it));
705 it->title_icon = NULL;
711 _title_content_unset(Elm_Naviframe_Item *it, const char *part)
713 Elm_Naviframe_Content_Item_Pair *pair = NULL;
715 Evas_Object *content = NULL;
717 EINA_INLIST_FOREACH(it->content_list, pair)
719 if (!strcmp(part, pair->part))
721 content = elm_object_part_content_get(VIEW(it), part);
722 eina_stringshare_del(pair->part);
723 it->content_list = eina_inlist_remove(it->content_list,
724 EINA_INLIST_GET(pair));
730 if (!content) return NULL;
732 elm_object_part_content_unset(VIEW(it), part);
733 snprintf(buf, sizeof(buf), "elm,state,%s,hide", part);
734 elm_object_signal_emit(VIEW(it), buf, "elm");
735 evas_object_event_callback_del(content,
738 _sizing_eval(WIDGET(it));
744 _item_del(Elm_Naviframe_Item *it)
747 Elm_Naviframe_Content_Item_Pair *content_pair;
748 Elm_Naviframe_Text_Item_Pair *text_pair;
749 Evas_Object *content;
753 wd = elm_widget_data_get(WIDGET(it));
756 while (it->content_list)
759 EINA_INLIST_CONTAINER_GET(it->content_list,
760 Elm_Naviframe_Content_Item_Pair);
761 content = elm_object_part_content_get(VIEW(it), content_pair->part);
762 evas_object_event_callback_del(content,
765 eina_stringshare_del(content_pair->part);
766 it->content_list = eina_inlist_remove(it->content_list,
771 while (it->text_list)
773 text_pair = EINA_INLIST_CONTAINER_GET(it->text_list,
774 Elm_Naviframe_Text_Item_Pair);
775 eina_stringshare_del(text_pair->part);
776 it->text_list = eina_inlist_remove(it->text_list,
781 eina_stringshare_del(it->style);
785 _item_del_pre_hook(Elm_Object_Item *it)
787 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
788 Elm_Naviframe_Item *navi_it;
791 navi_it =(Elm_Naviframe_Item *) it;
792 wd = elm_widget_data_get(WIDGET(navi_it));
793 if (!wd) return EINA_FALSE;
795 if (it == elm_naviframe_top_item_get(WIDGET(navi_it)))
797 wd->stack = eina_inlist_remove(wd->stack, EINA_INLIST_GET(navi_it));
799 elm_widget_item_free(navi_it);
800 //If the item is only one, the stack will be empty
801 if (!wd->stack) return EINA_TRUE;
802 navi_it = EINA_INLIST_CONTAINER_GET(wd->stack->last,
804 evas_object_show(VIEW(navi_it));
805 evas_object_raise(VIEW(navi_it));
806 elm_object_signal_emit(VIEW(navi_it), "elm,state,visible", "elm");
810 wd->stack = eina_inlist_remove(wd->stack, EINA_INLIST_GET(navi_it));
812 elm_widget_item_free(navi_it);
819 _pushed_finished(void *data,
820 Evas_Object *obj __UNUSED__,
821 const char *emission __UNUSED__,
822 const char *source __UNUSED__)
825 Elm_Naviframe_Item *it = data;
828 wd = elm_widget_data_get(WIDGET(it));
831 evas_object_hide(VIEW(it));
832 evas_object_smart_callback_call(WIDGET(it),
835 if (wd->freeze_events)
836 evas_object_freeze_events_set(VIEW(it), EINA_FALSE);
840 _popped_finished(void *data,
841 Evas_Object *obj __UNUSED__,
842 const char *emission __UNUSED__,
843 const char *source __UNUSED__)
845 Elm_Naviframe_Item *it = data;
847 evas_object_smart_callback_call(WIDGET(it),
851 elm_widget_item_free(data);
855 _show_finished(void *data,
856 Evas_Object *obj __UNUSED__,
857 const char *emission __UNUSED__,
858 const char *source __UNUSED__)
860 Elm_Naviframe_Item *it;
865 wd = elm_widget_data_get(WIDGET(it));
868 evas_object_smart_callback_call(WIDGET(it),
869 SIG_TRANSITION_FINISHED,
871 if (wd->freeze_events)
872 evas_object_freeze_events_set(VIEW(it), EINA_FALSE);
876 _changed_size_hints(void *data,
878 Evas_Object *obj __UNUSED__,
879 void *event_info __UNUSED__)
885 _item_content_set(Elm_Naviframe_Item *navi_it, Evas_Object *content)
887 if (navi_it->content == content) return;
888 if (navi_it->content) evas_object_del(navi_it->content);
889 elm_object_part_content_set(VIEW(navi_it), "elm.swallow.content", content);
892 elm_object_signal_emit(VIEW(navi_it), "elm,state,content,show", "elm");
894 elm_object_signal_emit(VIEW(navi_it), "elm,state,content,hide", "elm");
896 evas_object_event_callback_add(content,
900 navi_it->content = content;
901 _sizing_eval(WIDGET(navi_it));
904 //FIXME: need to handle if this function is called while transition
906 _item_style_set(Elm_Naviframe_Item *navi_it, const char *item_style)
908 Elm_Naviframe_Content_Item_Pair *content_pair;
909 Elm_Naviframe_Text_Item_Pair *text_pair;
911 wd = elm_widget_data_get(WIDGET(navi_it));
918 snprintf(buf, sizeof(buf), "item/%s", wd->item_style);
922 snprintf(buf, sizeof(buf), "item/%s", item_style);
923 eina_stringshare_replace(&navi_it->style, item_style);
925 elm_layout_theme_set(VIEW(navi_it),
928 elm_widget_style_get(WIDGET(navi_it)));
930 EINA_INLIST_FOREACH(navi_it->text_list, text_pair)
931 _item_text_set_hook((Elm_Object_Item *) navi_it,
933 elm_object_part_text_get(VIEW(navi_it),
936 EINA_INLIST_FOREACH(navi_it->content_list, content_pair)
937 _item_content_set_hook((Elm_Object_Item *) navi_it,
939 elm_object_part_content_get(VIEW(navi_it),
940 content_pair->part));
942 if (navi_it->content)
943 elm_object_signal_emit(VIEW(navi_it), "elm,state,content,show", "elm");
946 if (navi_it->title_prev_btn)
947 elm_object_signal_emit(VIEW(navi_it), "elm,state,prev_btn,show", "elm");
950 if (navi_it->title_next_btn)
951 elm_object_signal_emit(VIEW(navi_it), "elm,state,next_btn,show", "elm");
953 navi_it->title_visible = EINA_TRUE;
954 _sizing_eval(WIDGET(navi_it));
956 if (wd->freeze_events)
957 evas_object_freeze_events_set(VIEW(navi_it), EINA_FALSE);
960 static Elm_Naviframe_Item *
961 _item_new(Evas_Object *obj,
962 const char *title_label,
963 Evas_Object *prev_btn,
964 Evas_Object *next_btn,
965 Evas_Object *content,
966 const char *item_style)
968 Widget_Data *wd = elm_widget_data_get(obj);
971 Elm_Naviframe_Item *it = elm_widget_item_new(obj, Elm_Naviframe_Item);
974 ERR("Failed to allocate new item! : naviframe=%p", obj);
978 elm_widget_item_del_pre_hook_set(it, _item_del_pre_hook);
979 elm_widget_item_text_set_hook_set(it, _item_text_set_hook);
980 elm_widget_item_text_get_hook_set(it, _item_text_get_hook);
981 elm_widget_item_content_set_hook_set(it, _item_content_set_hook);
982 elm_widget_item_content_get_hook_set(it, _item_content_get_hook);
983 elm_widget_item_content_unset_hook_set(it, _item_content_unset_hook);
984 elm_widget_item_signal_emit_hook_set(it, _item_signal_emit_hook);
987 VIEW(it) = elm_layout_add(obj);
988 evas_object_smart_member_add(VIEW(it), wd->base);
990 evas_object_event_callback_add(VIEW(it),
991 EVAS_CALLBACK_CHANGED_SIZE_HINTS,
994 elm_object_signal_callback_add(VIEW(it),
995 "elm,action,show,finished",
998 elm_object_signal_callback_add(VIEW(it),
999 "elm,action,pushed,finished",
1001 _pushed_finished, it);
1002 elm_object_signal_callback_add(VIEW(it),
1003 "elm,action,popped,finished",
1005 _popped_finished, it);
1006 elm_object_signal_callback_add(VIEW(it),
1007 "elm,action,title,clicked",
1009 _title_clicked, it);
1011 _item_style_set(it, item_style);
1012 _item_text_set_hook((Elm_Object_Item *) it, "elm.text.title", title_label);
1015 if ((!prev_btn) && wd->auto_pushed && eina_inlist_count(wd->stack))
1017 prev_btn = _back_btn_new(obj);
1018 _title_prev_btn_set(it, prev_btn, EINA_TRUE);
1021 _title_prev_btn_set(it, prev_btn, EINA_FALSE);
1023 _title_next_btn_set(it, next_btn);
1024 _item_content_set(it, content);
1025 it->title_visible = EINA_TRUE;
1030 _focus_next_hook(const Evas_Object *obj, Elm_Focus_Direction dir, Evas_Object **next)
1032 Widget_Data *wd = elm_widget_data_get(obj);
1033 if (!wd || !wd->stack) return EINA_FALSE;
1034 return elm_widget_focus_next_get(VIEW(elm_naviframe_top_item_get(obj)),
1040 elm_naviframe_add(Evas_Object *parent)
1046 ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL);
1047 ELM_SET_WIDTYPE(widtype, "naviframe");
1048 elm_widget_type_set(obj, "naviframe");
1049 elm_widget_sub_object_add(parent, obj);
1050 elm_widget_data_set(obj, wd);
1051 elm_widget_del_hook_set(obj, _del_hook);
1052 elm_widget_disable_hook_set(obj, _disable_hook);
1053 elm_widget_theme_hook_set(obj, _theme_hook);
1054 elm_widget_signal_emit_hook_set(obj, _emit_hook);
1055 elm_widget_can_focus_set(obj, EINA_FALSE);
1056 elm_widget_focus_next_hook_set(obj, _focus_next_hook);
1059 wd->base = elm_layout_add(parent);
1060 evas_object_event_callback_add(wd->base,
1061 EVAS_CALLBACK_CHANGED_SIZE_HINTS,
1062 _changed_size_hints,
1064 elm_widget_resize_object_set(obj, wd->base);
1065 elm_layout_theme_set(wd->base, "naviframe", "base", "default");
1067 evas_object_event_callback_add(obj, EVAS_CALLBACK_MOVE, _move, obj);
1068 evas_object_event_callback_add(obj, EVAS_CALLBACK_RESIZE, _resize, obj);
1069 evas_object_smart_callbacks_descriptions_set(obj, _signals);
1071 wd->auto_pushed = EINA_TRUE;
1072 wd->freeze_events = EINA_TRUE;
1073 wd->item_style = eina_stringshare_add("basic");
1078 EAPI Elm_Object_Item *
1079 elm_naviframe_item_push(Evas_Object *obj,
1080 const char *title_label,
1081 Evas_Object *prev_btn,
1082 Evas_Object *next_btn,
1083 Evas_Object *content,
1084 const char *item_style)
1086 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1088 Elm_Naviframe_Item *prev_it, *it;
1090 wd = elm_widget_data_get(obj);
1091 if (!wd) return NULL;
1093 it = _item_new(obj, title_label, prev_btn, next_btn, content, item_style);
1094 if (!it) return NULL;
1096 evas_object_show(VIEW(it));
1098 prev_it = (Elm_Naviframe_Item *) elm_naviframe_top_item_get(obj);
1101 if (wd->freeze_events)
1103 evas_object_freeze_events_set(VIEW(it), EINA_TRUE);
1104 evas_object_freeze_events_set(VIEW(prev_it), EINA_TRUE);
1106 elm_object_signal_emit(VIEW(prev_it), "elm,state,cur,pushed", "elm");
1107 elm_object_signal_emit(VIEW(it), "elm,state,new,pushed", "elm");
1108 edje_object_message_signal_process(elm_layout_edje_get(VIEW(prev_it)));
1109 edje_object_message_signal_process(elm_layout_edje_get(VIEW(it)));
1111 wd->stack = eina_inlist_append(wd->stack, EINA_INLIST_GET(it));
1113 return (Elm_Object_Item *) it;
1116 EAPI Elm_Object_Item *
1117 elm_naviframe_item_insert_before(Elm_Object_Item *before,
1118 const char *title_label,
1119 Evas_Object *prev_btn,
1120 Evas_Object *next_btn,
1121 Evas_Object *content,
1122 const char *item_style)
1124 ELM_OBJ_ITEM_CHECK_OR_RETURN(before, NULL);
1125 Elm_Naviframe_Item *it;
1128 wd = elm_widget_data_get(WIDGET(before));
1129 if (!wd) return NULL;
1131 it = _item_new(WIDGET(before), title_label, prev_btn, next_btn, content,
1133 if (!it) return NULL;
1136 eina_inlist_prepend_relative(wd->stack, EINA_INLIST_GET(it),
1137 EINA_INLIST_GET(((Elm_Naviframe_Item *) before)));
1138 _sizing_eval(WIDGET(before));
1139 return (Elm_Object_Item *) it;
1142 EAPI Elm_Object_Item *
1143 elm_naviframe_item_insert_after(Elm_Object_Item *after,
1144 const char *title_label,
1145 Evas_Object *prev_btn,
1146 Evas_Object *next_btn,
1147 Evas_Object *content,
1148 const char *item_style)
1150 ELM_OBJ_ITEM_CHECK_OR_RETURN(after, NULL);
1151 Elm_Naviframe_Item *it;
1154 wd = elm_widget_data_get(WIDGET(after));
1155 if (!wd) return NULL;
1157 it = _item_new(WIDGET(after), title_label, prev_btn, next_btn, content,
1159 if (!it) return NULL;
1161 if (elm_naviframe_top_item_get(WIDGET(after)) == after)
1163 evas_object_hide(VIEW(after));
1164 evas_object_show(VIEW(it));
1167 eina_inlist_append_relative(wd->stack, EINA_INLIST_GET(it),
1168 EINA_INLIST_GET(((Elm_Naviframe_Item *) after)));
1169 _sizing_eval(WIDGET(after));
1170 return (Elm_Object_Item *) it;
1174 elm_naviframe_item_pop(Evas_Object *obj)
1176 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1177 Elm_Naviframe_Item *it, *prev_it = NULL;
1179 Evas_Object *content = NULL;
1181 wd = elm_widget_data_get(obj);
1182 if (!wd) return NULL;
1184 it = (Elm_Naviframe_Item *) elm_naviframe_top_item_get(obj);
1185 if (!it) return NULL;
1186 elm_widget_tree_unfocusable_set(it->content, EINA_TRUE);
1188 content = it->content;
1190 if (wd->stack->last->prev)
1191 prev_it = EINA_INLIST_CONTAINER_GET(wd->stack->last->prev,
1192 Elm_Naviframe_Item);
1193 wd->stack = eina_inlist_remove(wd->stack, EINA_INLIST_GET(it));
1196 if (wd->freeze_events)
1198 evas_object_freeze_events_set(VIEW(it), EINA_TRUE);
1199 evas_object_freeze_events_set(VIEW(prev_it), EINA_TRUE);
1201 elm_object_signal_emit(VIEW(it), "elm,state,cur,popped", "elm");
1202 evas_object_show(VIEW(prev_it));
1203 evas_object_raise(VIEW(prev_it));
1204 elm_object_signal_emit(VIEW(prev_it),
1205 "elm,state,prev,popped",
1207 edje_object_message_signal_process(elm_layout_edje_get(VIEW(it)));
1208 edje_object_message_signal_process(elm_layout_edje_get(VIEW(prev_it)));
1213 elm_widget_item_free(it);
1220 elm_naviframe_item_pop_to(Elm_Object_Item *it)
1222 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1223 Elm_Naviframe_Item *navi_it;
1225 Eina_Inlist *l, *prev_l;
1227 navi_it = (Elm_Naviframe_Item *) it;
1228 wd = elm_widget_data_get(WIDGET(navi_it));
1231 if (it == elm_naviframe_top_item_get(WIDGET(navi_it))) return;
1233 l = wd->stack->last->prev;
1237 if (EINA_INLIST_CONTAINER_GET(l, Elm_Naviframe_Item) ==
1238 ((Elm_Naviframe_Item *) it)) break;
1240 wd->stack = eina_inlist_remove(wd->stack, l);
1241 _item_del(EINA_INLIST_CONTAINER_GET(l, Elm_Naviframe_Item));
1242 elm_widget_item_free(EINA_INLIST_CONTAINER_GET(l,
1243 Elm_Naviframe_Item));
1246 elm_naviframe_item_pop(WIDGET(navi_it));
1250 elm_naviframe_item_promote(Elm_Object_Item *it)
1252 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1253 Elm_Naviframe_Item *navi_it;
1254 Elm_Naviframe_Item *prev_it;
1257 navi_it = (Elm_Naviframe_Item *) it;
1258 wd = elm_widget_data_get(navi_it->base.widget);
1261 if (it == elm_naviframe_top_item_get(navi_it->base.widget)) return;
1262 wd->stack = eina_inlist_demote(wd->stack, EINA_INLIST_GET(navi_it));
1263 prev_it = EINA_INLIST_CONTAINER_GET(wd->stack->last->prev,
1264 Elm_Naviframe_Item);
1265 if (wd->freeze_events)
1267 evas_object_freeze_events_set(VIEW(it), EINA_TRUE);
1268 evas_object_freeze_events_set(VIEW(prev_it), EINA_TRUE);
1270 elm_object_signal_emit(VIEW(prev_it),
1271 "elm,state,cur,pushed",
1273 evas_object_show(VIEW(navi_it));
1274 evas_object_raise(VIEW(navi_it));
1275 elm_object_signal_emit(VIEW(navi_it),
1276 "elm,state,new,pushed",
1278 edje_object_message_signal_process(elm_layout_edje_get(VIEW(prev_it)));
1279 edje_object_message_signal_process(elm_layout_edje_get(VIEW(navi_it)));
1283 elm_naviframe_item_simple_promote(Evas_Object *obj, Evas_Object *content)
1285 ELM_CHECK_WIDTYPE(obj, widtype);
1286 Widget_Data *wd = elm_widget_data_get(obj);
1288 Elm_Naviframe_Item *itr;
1289 EINA_INLIST_FOREACH(wd->stack, itr)
1291 if (elm_object_item_content_get((Elm_Object_Item *) itr) == content)
1293 elm_naviframe_item_promote((Elm_Object_Item *) itr);
1301 elm_naviframe_item_del(Elm_Object_Item *it)
1303 elm_object_item_del(it);
1307 elm_naviframe_content_preserve_on_pop_set(Evas_Object *obj, Eina_Bool preserve)
1309 ELM_CHECK_WIDTYPE(obj, widtype);
1310 Widget_Data *wd = elm_widget_data_get(obj);
1312 wd->preserve = !!preserve;
1316 elm_naviframe_content_preserve_on_pop_get(const Evas_Object *obj)
1318 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
1319 Widget_Data *wd = elm_widget_data_get(obj);
1320 if (!wd) return EINA_FALSE;
1321 return wd->preserve;
1324 EAPI Elm_Object_Item*
1325 elm_naviframe_top_item_get(const Evas_Object *obj)
1327 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1328 Widget_Data *wd = elm_widget_data_get(obj);
1329 if ((!wd) || (!wd->stack)) return NULL;
1330 return (Elm_Object_Item *) (EINA_INLIST_CONTAINER_GET(wd->stack->last,
1331 Elm_Naviframe_Item));
1334 EAPI Elm_Object_Item*
1335 elm_naviframe_bottom_item_get(const Evas_Object *obj)
1337 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1338 Widget_Data *wd = elm_widget_data_get(obj);
1339 if ((!wd) || (!wd->stack)) return NULL;
1340 return (Elm_Object_Item *) (EINA_INLIST_CONTAINER_GET(wd->stack,
1341 Elm_Naviframe_Item));
1345 elm_naviframe_item_style_set(Elm_Object_Item *it, const char *item_style)
1347 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1348 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
1350 //Return if new style is exsiting one.
1351 if ((item_style && navi_it->style) && (!strcmp(item_style, navi_it->style)))
1354 if ((!item_style) && (!navi_it->style))
1357 _item_style_set(navi_it, item_style);
1361 elm_naviframe_item_style_get(const Elm_Object_Item *it)
1363 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
1364 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
1365 return navi_it->style;
1369 elm_naviframe_item_title_visible_set(Elm_Object_Item *it, Eina_Bool visible)
1371 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1372 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
1374 visible = !!visible;
1375 if (navi_it->title_visible == visible) return;
1377 navi_it->title_visible = visible;
1378 _item_title_visible_update(navi_it);
1382 elm_naviframe_item_title_visible_get(const Elm_Object_Item *it)
1384 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
1385 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
1386 return navi_it->title_visible;
1390 elm_naviframe_prev_btn_auto_pushed_set(Evas_Object *obj, Eina_Bool auto_pushed)
1392 ELM_CHECK_WIDTYPE(obj, widtype);
1393 Widget_Data *wd = elm_widget_data_get(obj);
1395 wd->auto_pushed = !!auto_pushed;
1399 elm_naviframe_prev_btn_auto_pushed_get(const Evas_Object *obj)
1401 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
1402 Widget_Data *wd = elm_widget_data_get(obj);
1403 if (!wd) return EINA_FALSE;
1404 return wd->auto_pushed;
1408 elm_naviframe_items_get(const Evas_Object *obj)
1410 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1411 Widget_Data *wd = elm_widget_data_get(obj);
1412 if (!wd) return NULL;
1413 Eina_List *ret = NULL;
1414 Elm_Naviframe_Item *itr;
1415 EINA_INLIST_FOREACH(wd->stack, itr)
1417 ret = eina_list_append(ret, itr);
1423 elm_naviframe_event_enabled_set(Evas_Object *obj, Eina_Bool enabled)
1425 ELM_CHECK_WIDTYPE(obj, widtype);
1426 Widget_Data *wd = elm_widget_data_get(obj);
1428 enabled = !!enabled;
1429 if (wd->freeze_events == !enabled) return;
1430 wd->freeze_events = !enabled;
1434 elm_naviframe_event_enabled_get(const Evas_Object *obj)
1436 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
1437 Widget_Data *wd = elm_widget_data_get(obj);
1438 if (!wd) return EINA_FALSE;
1439 return !wd->freeze_events;
1443 elm_naviframe_item_style_default_set(Evas_Object *obj, const char *style)
1445 ELM_CHECK_WIDTYPE(obj, widtype);
1446 Widget_Data *wd = elm_widget_data_get(obj);
1448 eina_stringshare_replace(&wd->item_style, style);
1453 elm_naviframe_item_style_default_get(const Evas_Object *obj)
1455 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1456 Widget_Data *wd = elm_widget_data_get(obj);
1457 if (!wd) return NULL;
1458 return wd->item_style;