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;
50 static const char SIG_TRANSITION_FINISHED[] = "transition,finished";
51 static const char SIG_PUSH_FINISHED[] = "push,finished";
52 static const char SIG_POP_FINISHED[] = "pop,finished";
53 static const char SIG_TITLE_CLICKED[] = "title,clicked";
55 static const Evas_Smart_Cb_Description _signals[] = {
56 {SIG_TRANSITION_FINISHED, ""},
57 {SIG_TITLE_CLICKED, ""},
61 static void _del_hook(Evas_Object *obj);
62 static void _theme_hook(Evas_Object *obj);
63 static void _emit_hook(Evas_Object *obj,
66 static void _disable_hook(Evas_Object *obj);
67 static void _item_text_set_hook(Elm_Object_Item *it,
70 static const char *_item_text_get_hook(const Elm_Object_Item *it,
72 static void _item_content_set_hook(Elm_Object_Item *it,
74 Evas_Object *content);
75 static Evas_Object *_item_content_get_hook(const Elm_Object_Item *it,
77 static Evas_Object *_item_content_unset_hook(Elm_Object_Item *it,
79 static void _item_signal_emit_hook(Elm_Object_Item *it,
82 static void _item_title_visible_update(Elm_Naviframe_Item *navi_it);
83 static void _sizing_eval(Evas_Object *obj);
84 static void _move(void *data, Evas *e, Evas_Object *obj, void *event_info);
85 static void _resize(void *data,
89 static void _title_clicked(void *data, Evas_Object *obj,
92 static void _back_btn_clicked(void *data,
95 static Evas_Object *_back_btn_new(Evas_Object *obj);
96 static void _item_content_del(void *data,
100 static void _title_content_del(void *data,
104 static void _title_prev_btn_del(void *data,
108 static void _title_next_btn_del(void *data,
112 static void _title_icon_del(void *data,
116 static void _title_content_set(Elm_Naviframe_Item *it,
118 Evas_Object *content);
119 static void _title_prev_btn_set(Elm_Naviframe_Item *it,
122 static void _title_next_btn_set(Elm_Naviframe_Item *it, Evas_Object *btn);
123 static void _title_icon_set(Elm_Naviframe_Item *it, Evas_Object *icon);
124 static Evas_Object * _item_content_unset(Elm_Naviframe_Item *it);
125 static Evas_Object * _title_prev_btn_unset(Elm_Naviframe_Item *it);
126 static Evas_Object * _title_next_btn_unset(Elm_Naviframe_Item *it);
127 static Evas_Object * _title_icon_unset(Elm_Naviframe_Item *it);
128 static Evas_Object * _title_content_unset(Elm_Naviframe_Item *it,
130 static void _item_del(Elm_Naviframe_Item *it);
131 static void _pushed_finished(void *data,
133 const char *emission,
135 static void _popped_finished(void *data,
137 const char *emission,
139 static void _show_finished(void *data,
141 const char *emission,
143 static void _changed_size_hints(void *data,
147 static void _item_content_set(Elm_Naviframe_Item *navi_it,
148 Evas_Object *content);
149 static void _item_style_set(Elm_Naviframe_Item *navi_it,
150 const char *item_style);
151 static Elm_Naviframe_Item * _item_new(Evas_Object *obj,
152 const char *title_label,
153 Evas_Object *prev_btn,
154 Evas_Object *next_btn,
155 Evas_Object *content,
156 const char *item_style);
159 _del_hook(Evas_Object *obj)
162 Elm_Naviframe_Item *it;
164 wd = elm_widget_data_get(obj);
169 while (wd->stack->last)
171 it = EINA_INLIST_CONTAINER_GET(wd->stack->last,
173 wd->stack = eina_inlist_remove(wd->stack, wd->stack->last);
175 if (!wd->stack) break;
182 _theme_hook(Evas_Object *obj)
185 Elm_Naviframe_Item *it;
187 wd = elm_widget_data_get(obj);
190 _elm_theme_object_set(obj,
194 elm_widget_style_get(obj));
196 EINA_INLIST_FOREACH(wd->stack, it)
198 _item_style_set(it, it->style);
199 _item_title_visible_update(it);
203 static void _emit_hook(Evas_Object *obj,
204 const char *emission,
207 ELM_CHECK_WIDTYPE(obj, widtype);
209 Widget_Data *wd = elm_widget_data_get(obj);
212 elm_object_signal_emit(wd->base, emission, source);
216 _disable_hook(Evas_Object *obj __UNUSED__)
222 _item_text_set_hook(Elm_Object_Item *it,
226 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
228 Elm_Naviframe_Text_Item_Pair *pair = NULL;
229 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
232 if (!part || !strcmp(part, "default"))
233 snprintf(buf, sizeof(buf), "elm.text.title");
234 else if(!strcmp("subtitle", part))
235 snprintf(buf, sizeof(buf), "elm.text.subtitle");
237 snprintf(buf, sizeof(buf), "%s", part);
239 EINA_INLIST_FOREACH(navi_it->text_list, pair)
240 if (!strcmp(buf, pair->part)) break;
244 pair = ELM_NEW(Elm_Naviframe_Text_Item_Pair);
247 ERR("Failed to allocate new text part of the item! : naviframe=%p",
251 eina_stringshare_replace(&pair->part, buf);
252 navi_it->text_list = eina_inlist_append(navi_it->text_list,
253 EINA_INLIST_GET(pair));
255 elm_object_part_text_set(VIEW(navi_it), buf, label);
259 snprintf(buf, sizeof(buf), "elm,state,%s,show", buf);
260 elm_object_signal_emit(VIEW(navi_it), buf, "elm");
264 snprintf(buf, sizeof(buf), "elm,state,%s,hide", buf);
265 elm_object_signal_emit(VIEW(navi_it), buf, "elm");
268 _sizing_eval(WIDGET(navi_it));
272 _item_text_get_hook(const Elm_Object_Item *it, const char *part)
274 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
277 if (!part || !strcmp(part, "default"))
278 snprintf(buf, sizeof(buf), "elm.text.title");
279 else if(!strcmp("subtitle", part))
280 snprintf(buf, sizeof(buf), "elm.text.subtitle");
282 snprintf(buf, sizeof(buf), "%s", part);
284 return elm_object_part_text_get(VIEW(it), buf);
288 _item_content_set_hook(Elm_Object_Item *it,
290 Evas_Object *content)
292 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
294 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
297 if ((!part) || (!strcmp(part, "elm.swallow.content")))
299 _item_content_set(navi_it, content);
302 else if (!strcmp(part, "elm.swallow.prev_btn"))
304 _title_prev_btn_set(navi_it, content, EINA_FALSE);
307 else if (!strcmp(part, "elm.swallow.next_btn"))
309 _title_next_btn_set(navi_it, content);
312 else if (!strcmp(part, "icon"))
314 _title_icon_set(navi_it, content);
319 _title_content_set(navi_it, part, content);
323 _item_content_get_hook(const Elm_Object_Item *it, const char *part)
325 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
326 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
329 if ((!part) || (!strcmp(part, "elm.swallow.content")))
330 return navi_it->content;
331 else if (!strcmp(part, "elm.swallow.prev_btn"))
332 return navi_it->title_prev_btn;
333 else if (!strcmp(part, "elm.swallow.next_btn"))
334 return navi_it->title_next_btn;
335 else if (!strcmp(part, "icon"))
336 return navi_it->title_icon;
339 return elm_object_part_content_get(VIEW(navi_it), part);
343 _item_content_unset_hook(Elm_Object_Item *it, const char *part)
345 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
346 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
349 if (!part || !strcmp("elm.swallow.content", part))
350 return _item_content_unset(navi_it);
351 else if (!strcmp(part, "elm.swallow.prev_btn"))
352 return _title_prev_btn_unset(navi_it);
353 else if (!strcmp(part, "elm.swallow.next_btn"))
354 return _title_next_btn_unset(navi_it);
355 else if (!strcmp(part, "icon"))
356 return _title_icon_unset(navi_it);
358 return _title_content_unset(navi_it, part);
362 _item_signal_emit_hook(Elm_Object_Item *it,
363 const char *emission,
366 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
367 elm_object_signal_emit(VIEW(it), emission, source);
371 _item_title_visible_update(Elm_Naviframe_Item *navi_it)
373 if (navi_it->title_visible)
374 elm_object_signal_emit(VIEW(navi_it), "elm,state,title,show", "elm");
376 elm_object_signal_emit(VIEW(navi_it), "elm,state,title,hide", "elm");
380 _sizing_eval(Evas_Object *obj)
383 Elm_Naviframe_Item *it;
384 Evas_Coord x, y, w, h;
385 Evas_Coord minw = -1, minh = -1;
387 wd = elm_widget_data_get(obj);
390 evas_object_geometry_get(obj, &x, &y, &w, &h);
392 EINA_INLIST_FOREACH(wd->stack, it)
394 evas_object_move(VIEW(it), x, y);
395 evas_object_resize(VIEW(it), w, h);
396 edje_object_size_min_calc(elm_layout_edje_get(VIEW(it)),
399 if (it->minw > minw) minw = it->minw;
400 if (it->minh > minh) minh = it->minh;
402 evas_object_size_hint_min_set(obj, minw, minh);
403 evas_object_size_hint_max_set(obj, -1, -1);
407 _move(void *data __UNUSED__,
410 void *event_info __UNUSED__)
416 _resize(void *data __UNUSED__,
419 void *event_info __UNUSED__)
425 _title_clicked(void *data,
426 Evas_Object *obj __UNUSED__,
427 const char *emission __UNUSED__,
428 const char *source __UNUSED__)
430 Elm_Naviframe_Item *it = data;
431 evas_object_smart_callback_call(WIDGET(it), SIG_TITLE_CLICKED, it);
435 _back_btn_clicked(void *data,
437 void *event_info __UNUSED__)
439 /* Since edje has the event queue, clicked event could be happend multiple times
440 on some heavy environment. This callback del will prevent those scenario and
441 guarantee only one clicked for it's own page. */
442 evas_object_smart_callback_del(obj, "clicked", _back_btn_clicked);
443 elm_naviframe_item_pop(data);
447 _back_btn_new(Evas_Object *obj)
451 btn = elm_button_add(obj);
452 if (!btn) return NULL;
453 evas_object_smart_callback_add(btn, "clicked", _back_btn_clicked, obj);
454 snprintf(buf, sizeof(buf), "naviframe/back_btn/%s", elm_widget_style_get(obj));
455 elm_object_style_set(btn, buf);
460 _title_content_del(void *data,
462 Evas_Object *obj __UNUSED__,
463 void *event_info __UNUSED__)
466 Elm_Naviframe_Content_Item_Pair *pair = data;
467 Elm_Naviframe_Item *it = pair->it;
468 snprintf(buf, sizeof(buf), "elm,state,%s,hide", pair->part);
469 elm_object_signal_emit(VIEW(it), buf, "elm");
470 it->content_list = eina_inlist_remove(it->content_list,
471 EINA_INLIST_GET(pair));
472 eina_stringshare_del(pair->part);
477 _title_prev_btn_del(void *data,
479 Evas_Object *obj __UNUSED__,
480 void *event_info __UNUSED__)
482 Elm_Naviframe_Item *it = data;
483 it->back_btn = EINA_FALSE;
484 it->title_prev_btn = NULL;
485 elm_object_signal_emit(VIEW(it), "elm,state,prev_btn,hide", "elm");
489 _title_next_btn_del(void *data,
491 Evas_Object *obj __UNUSED__,
492 void *event_info __UNUSED__)
494 Elm_Naviframe_Item *it = data;
495 it->title_next_btn = NULL;
496 elm_object_signal_emit(VIEW(it), "elm,state,next_btn,hide", "elm");
500 _title_icon_del(void *data,
502 Evas_Object *obj __UNUSED__,
503 void *event_info __UNUSED__)
505 Elm_Naviframe_Item *it = data;
506 it->title_icon = NULL;
507 elm_object_signal_emit(VIEW(it), "elm,state,icon,hide", "elm");
511 _item_content_del(void *data,
513 Evas_Object *obj __UNUSED__,
514 void *event_info __UNUSED__)
516 Elm_Naviframe_Item *it = data;
518 elm_object_signal_emit(VIEW(it), "elm,state,content,hide", "elm");
522 _title_content_set(Elm_Naviframe_Item *it,
524 Evas_Object *content)
527 Elm_Naviframe_Content_Item_Pair *pair = NULL;
528 Evas_Object *prev_content = NULL;
530 EINA_INLIST_FOREACH(it->content_list, pair)
531 if (!strcmp(part, pair->part)) break;
535 prev_content = elm_object_part_content_get(VIEW(it), part);
536 if (prev_content != content)
540 evas_object_event_callback_del(prev_content,
543 snprintf(buf, sizeof(buf), "elm,state,%s,hide", part);
544 elm_object_signal_emit(VIEW(it), buf, "elm");
546 evas_object_del(prev_content);
547 if (!content) return;
552 if (!content) return;
553 pair = ELM_NEW(Elm_Naviframe_Content_Item_Pair);
556 ERR("Failed to allocate new content part of the item! : naviframe=%p", WIDGET(it));
560 eina_stringshare_replace(&pair->part, part);
561 it->content_list = eina_inlist_append(it->content_list,
562 EINA_INLIST_GET(pair));
564 if (prev_content != content)
566 evas_object_event_callback_add(content,
571 elm_object_part_content_set(VIEW(it), part, content);
572 snprintf(buf, sizeof(buf), "elm,state,%s,show", part);
573 elm_object_signal_emit(VIEW(it), buf, "elm");
575 _sizing_eval(WIDGET(it));
579 _title_prev_btn_set(Elm_Naviframe_Item *it,
583 if (it->title_prev_btn == btn) return;
584 if (it->title_prev_btn) evas_object_del(it->title_prev_btn);
585 it->title_prev_btn = btn;
588 evas_object_event_callback_add(btn,
592 elm_object_part_content_set(VIEW(it), "elm.swallow.prev_btn", btn);
593 elm_object_signal_emit(VIEW(it), "elm,state,prev_btn,show", "elm");
594 it->back_btn = back_btn;
596 _sizing_eval(WIDGET(it));
600 _title_next_btn_set(Elm_Naviframe_Item *it, Evas_Object *btn)
602 if (it->title_next_btn == btn) return;
603 if (it->title_next_btn) evas_object_del(it->title_next_btn);
604 it->title_next_btn = btn;
607 evas_object_event_callback_add(btn,
611 elm_object_part_content_set(VIEW(it), "elm.swallow.next_btn", btn);
612 elm_object_signal_emit(VIEW(it), "elm,state,next_btn,show", "elm");
614 _sizing_eval(WIDGET(it));
618 _title_icon_set(Elm_Naviframe_Item *it, Evas_Object *icon)
620 if (it->title_icon == icon) return;
621 if (it->title_icon) evas_object_del(it->title_icon);
622 it->title_icon = icon;
625 evas_object_event_callback_add(icon,
629 elm_object_part_content_set(VIEW(it), "elm.swallow.icon", icon);
630 elm_object_signal_emit(VIEW(it), "elm,state,icon,show", "elm");
632 _sizing_eval(WIDGET(it));
636 _item_content_unset(Elm_Naviframe_Item *it)
638 Evas_Object *content = it->content;
639 if (!content) return NULL;
641 elm_object_part_content_unset(VIEW(it), "elm.swallow.content");
642 elm_object_signal_emit(VIEW(it), "elm,state,content,hide", "elm");
643 evas_object_event_callback_del(content,
646 _sizing_eval(WIDGET(it));
653 _title_prev_btn_unset(Elm_Naviframe_Item *it)
655 Evas_Object *content = it->title_prev_btn;
656 if (!content) return NULL;
658 elm_object_part_content_unset(VIEW(it), "elm.swallow.prev_btn");
659 elm_object_signal_emit(VIEW(it), "elm,state,prev_btn,hide", "elm");
660 evas_object_event_callback_del(content,
662 _title_prev_btn_del);
663 _sizing_eval(WIDGET(it));
665 it->title_prev_btn = NULL;
670 _title_next_btn_unset(Elm_Naviframe_Item *it)
672 Evas_Object *content = it->title_next_btn;
673 if (!content) return NULL;
675 elm_object_part_content_unset(VIEW(it), "elm.swallow.next_btn");
676 elm_object_signal_emit(VIEW(it), "elm,state,next_btn,hide", "elm");
677 evas_object_event_callback_del(content,
679 _title_next_btn_del);
680 _sizing_eval(WIDGET(it));
682 it->title_next_btn = NULL;
687 _title_icon_unset(Elm_Naviframe_Item *it)
689 Evas_Object *content = it->title_icon;
690 if (!content) return NULL;
692 elm_object_part_content_unset(VIEW(it), "elm.swallow.icon");
693 elm_object_signal_emit(VIEW(it), "elm,state,icon,hide", "elm");
694 evas_object_event_callback_del(content,
697 _sizing_eval(WIDGET(it));
698 it->title_icon = NULL;
704 _title_content_unset(Elm_Naviframe_Item *it, const char *part)
706 Elm_Naviframe_Content_Item_Pair *pair = NULL;
708 Evas_Object *content = NULL;
710 EINA_INLIST_FOREACH(it->content_list, pair)
712 if (!strcmp(part, pair->part))
714 content = elm_object_part_content_get(VIEW(it), part);
715 eina_stringshare_del(pair->part);
716 it->content_list = eina_inlist_remove(it->content_list,
717 EINA_INLIST_GET(pair));
723 if (!content) return NULL;
725 elm_object_part_content_unset(VIEW(it), part);
726 snprintf(buf, sizeof(buf), "elm,state,%s,hide", part);
727 elm_object_signal_emit(VIEW(it), buf, "elm");
728 evas_object_event_callback_del(content,
731 _sizing_eval(WIDGET(it));
737 _item_del(Elm_Naviframe_Item *it)
740 Elm_Naviframe_Content_Item_Pair *content_pair;
741 Elm_Naviframe_Text_Item_Pair *text_pair;
742 Evas_Object *content;
746 wd = elm_widget_data_get(WIDGET(it));
749 while (it->content_list)
752 EINA_INLIST_CONTAINER_GET(it->content_list,
753 Elm_Naviframe_Content_Item_Pair);
754 content = elm_object_part_content_get(VIEW(it), content_pair->part);
755 evas_object_event_callback_del(content,
758 eina_stringshare_del(content_pair->part);
759 it->content_list = eina_inlist_remove(it->content_list,
764 while (it->text_list)
766 text_pair = EINA_INLIST_CONTAINER_GET(it->text_list,
767 Elm_Naviframe_Text_Item_Pair);
768 eina_stringshare_del(text_pair->part);
769 it->text_list = eina_inlist_remove(it->text_list,
774 eina_stringshare_del(it->style);
776 elm_widget_item_del(it);
780 _pushed_finished(void *data,
781 Evas_Object *obj __UNUSED__,
782 const char *emission __UNUSED__,
783 const char *source __UNUSED__)
786 Elm_Naviframe_Item *it = data;
789 wd = elm_widget_data_get(WIDGET(it));
792 evas_object_hide(VIEW(it));
793 evas_object_smart_callback_call(WIDGET(it),
796 if (wd->freeze_events)
797 evas_object_freeze_events_set(VIEW(it), EINA_FALSE);
801 _popped_finished(void *data,
802 Evas_Object *obj __UNUSED__,
803 const char *emission __UNUSED__,
804 const char *source __UNUSED__)
806 Elm_Naviframe_Item *it = data;
808 evas_object_smart_callback_call(WIDGET(it),
815 _show_finished(void *data,
816 Evas_Object *obj __UNUSED__,
817 const char *emission __UNUSED__,
818 const char *source __UNUSED__)
820 Elm_Naviframe_Item *it;
825 wd = elm_widget_data_get(WIDGET(it));
828 evas_object_smart_callback_call(WIDGET(it),
829 SIG_TRANSITION_FINISHED,
831 if (wd->freeze_events)
832 evas_object_freeze_events_set(VIEW(it), EINA_FALSE);
836 _changed_size_hints(void *data,
838 Evas_Object *obj __UNUSED__,
839 void *event_info __UNUSED__)
845 _item_content_set(Elm_Naviframe_Item *navi_it, Evas_Object *content)
847 if (navi_it->content == content) return;
848 if (navi_it->content) evas_object_del(navi_it->content);
849 elm_object_part_content_set(VIEW(navi_it), "elm.swallow.content", content);
852 elm_object_signal_emit(VIEW(navi_it), "elm,state,content,show", "elm");
854 elm_object_signal_emit(VIEW(navi_it), "elm,state,content,hide", "elm");
856 evas_object_event_callback_add(content,
860 navi_it->content = content;
861 _sizing_eval(WIDGET(navi_it));
864 //FIXME: need to handle if this function is called while transition
866 _item_style_set(Elm_Naviframe_Item *navi_it, const char *item_style)
868 Elm_Naviframe_Content_Item_Pair *content_pair;
869 Elm_Naviframe_Text_Item_Pair *text_pair;
876 strcpy(buf, "item/basic");
877 eina_stringshare_replace(&navi_it->style, "basic");
881 snprintf(buf, sizeof(buf), "item/%s", item_style);
882 eina_stringshare_replace(&navi_it->style, item_style);
884 elm_layout_theme_set(VIEW(navi_it),
887 elm_widget_style_get(WIDGET(navi_it)));
889 EINA_INLIST_FOREACH(navi_it->text_list, text_pair)
890 _item_text_set_hook((Elm_Object_Item *) navi_it,
892 elm_object_part_text_get(VIEW(navi_it),
895 EINA_INLIST_FOREACH(navi_it->content_list, content_pair)
896 _item_content_set_hook((Elm_Object_Item *) navi_it,
898 elm_object_part_content_get(VIEW(navi_it),
899 content_pair->part));
901 if (navi_it->content)
902 elm_object_signal_emit(VIEW(navi_it), "elm,state,content,show", "elm");
905 if (navi_it->title_prev_btn)
906 elm_object_signal_emit(VIEW(navi_it), "elm,state,prev_btn,show", "elm");
909 if (navi_it->title_next_btn)
910 elm_object_signal_emit(VIEW(navi_it), "elm,state,next_btn,show", "elm");
912 navi_it->title_visible = EINA_TRUE;
913 _sizing_eval(WIDGET(navi_it));
915 wd = elm_widget_data_get(WIDGET(navi_it));
918 if (wd->freeze_events)
919 evas_object_freeze_events_set(VIEW(navi_it), EINA_FALSE);
922 static Elm_Naviframe_Item *
923 _item_new(Evas_Object *obj,
924 const char *title_label,
925 Evas_Object *prev_btn,
926 Evas_Object *next_btn,
927 Evas_Object *content,
928 const char *item_style)
930 Widget_Data *wd = elm_widget_data_get(obj);
933 Elm_Naviframe_Item *it = elm_widget_item_new(obj, Elm_Naviframe_Item);
936 ERR("Failed to allocate new item! : naviframe=%p", obj);
940 elm_widget_item_text_set_hook_set(it, _item_text_set_hook);
941 elm_widget_item_text_get_hook_set(it, _item_text_get_hook);
942 elm_widget_item_content_set_hook_set(it, _item_content_set_hook);
943 elm_widget_item_content_get_hook_set(it, _item_content_get_hook);
944 elm_widget_item_content_unset_hook_set(it, _item_content_unset_hook);
945 elm_widget_item_signal_emit_hook_set(it, _item_signal_emit_hook);
948 VIEW(it) = elm_layout_add(obj);
949 evas_object_smart_member_add(VIEW(it), wd->base);
951 evas_object_event_callback_add(VIEW(it),
952 EVAS_CALLBACK_CHANGED_SIZE_HINTS,
955 elm_object_signal_callback_add(VIEW(it),
956 "elm,action,show,finished",
959 elm_object_signal_callback_add(VIEW(it),
960 "elm,action,pushed,finished",
962 _pushed_finished, it);
963 elm_object_signal_callback_add(VIEW(it),
964 "elm,action,popped,finished",
966 _popped_finished, it);
967 elm_object_signal_callback_add(VIEW(it),
968 "elm,action,title,clicked",
972 _item_style_set(it, item_style);
973 _item_text_set_hook((Elm_Object_Item *) it, "elm.text.title", title_label);
976 if ((!prev_btn) && wd->auto_pushed && eina_inlist_count(wd->stack))
978 prev_btn = _back_btn_new(obj);
979 _title_prev_btn_set(it, prev_btn, EINA_TRUE);
982 _title_prev_btn_set(it, prev_btn, EINA_FALSE);
984 _title_next_btn_set(it, next_btn);
985 _item_content_set(it, content);
986 it->title_visible = EINA_TRUE;
991 elm_naviframe_add(Evas_Object *parent)
997 ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL);
998 ELM_SET_WIDTYPE(widtype, "naviframe");
999 elm_widget_type_set(obj, "naviframe");
1000 elm_widget_sub_object_add(parent, obj);
1001 elm_widget_data_set(obj, wd);
1002 elm_widget_del_hook_set(obj, _del_hook);
1003 elm_widget_disable_hook_set(obj, _disable_hook);
1004 elm_widget_theme_hook_set(obj, _theme_hook);
1005 elm_widget_signal_emit_hook_set(obj, _emit_hook);
1008 wd->base = elm_layout_add(parent);
1009 evas_object_event_callback_add(wd->base,
1010 EVAS_CALLBACK_CHANGED_SIZE_HINTS,
1011 _changed_size_hints,
1013 elm_widget_resize_object_set(obj, wd->base);
1014 elm_layout_theme_set(wd->base, "naviframe", "base", "default");
1016 evas_object_event_callback_add(obj, EVAS_CALLBACK_MOVE, _move, obj);
1017 evas_object_event_callback_add(obj, EVAS_CALLBACK_RESIZE, _resize, obj);
1018 evas_object_smart_callbacks_descriptions_set(obj, _signals);
1020 wd->auto_pushed = EINA_TRUE;
1021 wd->freeze_events = EINA_TRUE;
1026 EAPI Elm_Object_Item *
1027 elm_naviframe_item_push(Evas_Object *obj,
1028 const char *title_label,
1029 Evas_Object *prev_btn,
1030 Evas_Object *next_btn,
1031 Evas_Object *content,
1032 const char *item_style)
1034 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1036 Elm_Naviframe_Item *prev_it, *it;
1038 wd = elm_widget_data_get(obj);
1039 if (!wd) return NULL;
1041 it = _item_new(obj, title_label, prev_btn, next_btn, content, item_style);
1042 if (!it) return NULL;
1044 evas_object_show(VIEW(it));
1046 prev_it = (Elm_Naviframe_Item *) elm_naviframe_top_item_get(obj);
1049 if (wd->freeze_events)
1051 evas_object_freeze_events_set(VIEW(it), EINA_TRUE);
1052 evas_object_freeze_events_set(VIEW(prev_it), EINA_TRUE);
1054 elm_object_signal_emit(VIEW(prev_it), "elm,state,cur,pushed", "elm");
1055 elm_object_signal_emit(VIEW(it), "elm,state,new,pushed", "elm");
1056 edje_object_message_signal_process(elm_layout_edje_get(VIEW(prev_it)));
1057 edje_object_message_signal_process(elm_layout_edje_get(VIEW(it)));
1059 wd->stack = eina_inlist_append(wd->stack, EINA_INLIST_GET(it));
1061 return (Elm_Object_Item *) it;
1064 EAPI Elm_Object_Item *
1065 elm_naviframe_item_insert_before(Elm_Object_Item *before,
1066 const char *title_label,
1067 Evas_Object *prev_btn,
1068 Evas_Object *next_btn,
1069 Evas_Object *content,
1070 const char *item_style)
1072 ELM_OBJ_ITEM_CHECK_OR_RETURN(before, NULL);
1073 Elm_Naviframe_Item *it;
1076 wd = elm_widget_data_get(WIDGET(before));
1077 if (!wd) return NULL;
1079 it = _item_new(WIDGET(before), title_label, prev_btn, next_btn, content,
1081 if (!it) return NULL;
1084 eina_inlist_prepend_relative(wd->stack, EINA_INLIST_GET(it),
1085 EINA_INLIST_GET(((Elm_Naviframe_Item *) before)));
1086 _sizing_eval(WIDGET(before));
1087 return (Elm_Object_Item *) it;
1090 EAPI Elm_Object_Item *
1091 elm_naviframe_item_insert_after(Elm_Object_Item *after,
1092 const char *title_label,
1093 Evas_Object *prev_btn,
1094 Evas_Object *next_btn,
1095 Evas_Object *content,
1096 const char *item_style)
1098 ELM_OBJ_ITEM_CHECK_OR_RETURN(after, NULL);
1099 Elm_Naviframe_Item *it;
1102 wd = elm_widget_data_get(WIDGET(after));
1103 if (!wd) return NULL;
1105 it = _item_new(WIDGET(after), title_label, prev_btn, next_btn, content,
1107 if (!it) return NULL;
1109 if (elm_naviframe_top_item_get(WIDGET(after)) == after)
1111 evas_object_hide(VIEW(after));
1112 evas_object_show(VIEW(it));
1115 eina_inlist_append_relative(wd->stack, EINA_INLIST_GET(it),
1116 EINA_INLIST_GET(((Elm_Naviframe_Item *) after)));
1117 _sizing_eval(WIDGET(after));
1118 return (Elm_Object_Item *) it;
1122 elm_naviframe_item_pop(Evas_Object *obj)
1124 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1125 Elm_Naviframe_Item *it, *prev_it = NULL;
1127 Evas_Object *content = NULL;
1129 wd = elm_widget_data_get(obj);
1130 if (!wd) return NULL;
1132 it = (Elm_Naviframe_Item *) elm_naviframe_top_item_get(obj);
1133 if (!it) return NULL;
1134 elm_widget_tree_unfocusable_set(it->content, EINA_TRUE);
1136 content = it->content;
1138 if (wd->stack->last->prev)
1139 prev_it = EINA_INLIST_CONTAINER_GET(wd->stack->last->prev,
1140 Elm_Naviframe_Item);
1141 wd->stack = eina_inlist_remove(wd->stack, EINA_INLIST_GET(it));
1144 if (wd->freeze_events)
1146 evas_object_freeze_events_set(VIEW(it), EINA_TRUE);
1147 evas_object_freeze_events_set(VIEW(prev_it), EINA_TRUE);
1149 elm_object_signal_emit(VIEW(it), "elm,state,cur,popped", "elm");
1150 evas_object_show(VIEW(prev_it));
1151 evas_object_raise(VIEW(prev_it));
1152 elm_object_signal_emit(VIEW(prev_it),
1153 "elm,state,prev,popped",
1155 edje_object_message_signal_process(elm_layout_edje_get(VIEW(it)));
1156 edje_object_message_signal_process(elm_layout_edje_get(VIEW(prev_it)));
1165 elm_naviframe_item_pop_to(Elm_Object_Item *it)
1167 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1168 Elm_Naviframe_Item *navi_it;
1170 Eina_Inlist *l, *prev_l;
1172 navi_it = (Elm_Naviframe_Item *) it;
1173 wd = elm_widget_data_get(WIDGET(navi_it));
1176 if (it == elm_naviframe_top_item_get(WIDGET(navi_it))) return;
1178 l = wd->stack->last->prev;
1182 if (EINA_INLIST_CONTAINER_GET(l, Elm_Naviframe_Item) ==
1183 ((Elm_Naviframe_Item *) it)) break;
1185 wd->stack = eina_inlist_remove(wd->stack, l);
1186 _item_del(EINA_INLIST_CONTAINER_GET(l, Elm_Naviframe_Item));
1189 elm_naviframe_item_pop(WIDGET(navi_it));
1193 elm_naviframe_item_promote(Elm_Object_Item *it)
1195 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1196 Elm_Naviframe_Item *navi_it;
1197 Elm_Naviframe_Item *prev_it;
1200 navi_it = (Elm_Naviframe_Item *) it;
1201 wd = elm_widget_data_get(navi_it->base.widget);
1204 if (it == elm_naviframe_top_item_get(navi_it->base.widget)) return;
1205 wd->stack = eina_inlist_demote(wd->stack, EINA_INLIST_GET(navi_it));
1206 prev_it = EINA_INLIST_CONTAINER_GET(wd->stack->last->prev,
1207 Elm_Naviframe_Item);
1208 if (wd->freeze_events)
1210 evas_object_freeze_events_set(VIEW(it), EINA_TRUE);
1211 evas_object_freeze_events_set(VIEW(prev_it), EINA_TRUE);
1213 elm_object_signal_emit(VIEW(prev_it),
1214 "elm,state,cur,pushed",
1216 evas_object_show(VIEW(navi_it));
1217 evas_object_raise(VIEW(navi_it));
1218 elm_object_signal_emit(VIEW(navi_it),
1219 "elm,state,new,pushed",
1221 edje_object_message_signal_process(elm_layout_edje_get(VIEW(prev_it)));
1222 edje_object_message_signal_process(elm_layout_edje_get(VIEW(navi_it)));
1226 elm_naviframe_item_del(Elm_Object_Item *it)
1228 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1229 Elm_Naviframe_Item *navi_it;
1232 navi_it =(Elm_Naviframe_Item *) it;
1233 wd = elm_widget_data_get(WIDGET(navi_it));
1236 if (it == elm_naviframe_top_item_get(WIDGET(navi_it)))
1238 wd->stack = eina_inlist_remove(wd->stack, EINA_INLIST_GET(navi_it));
1240 //If the item is only one, the stack will be empty
1241 if (!wd->stack) return;
1242 navi_it = EINA_INLIST_CONTAINER_GET(wd->stack->last,
1243 Elm_Naviframe_Item);
1244 evas_object_show(VIEW(navi_it));
1245 evas_object_raise(VIEW(navi_it));
1246 elm_object_signal_emit(VIEW(navi_it), "elm,state,visible", "elm");
1250 wd->stack = eina_inlist_remove(wd->stack, EINA_INLIST_GET(navi_it));
1256 elm_naviframe_content_preserve_on_pop_set(Evas_Object *obj, Eina_Bool preserve)
1258 ELM_CHECK_WIDTYPE(obj, widtype);
1259 Widget_Data *wd = elm_widget_data_get(obj);
1261 wd->preserve = !!preserve;
1265 elm_naviframe_content_preserve_on_pop_get(const Evas_Object *obj)
1267 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
1268 Widget_Data *wd = elm_widget_data_get(obj);
1269 if (!wd) return EINA_FALSE;
1270 return wd->preserve;
1273 EAPI Elm_Object_Item*
1274 elm_naviframe_top_item_get(const Evas_Object *obj)
1276 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1277 Widget_Data *wd = elm_widget_data_get(obj);
1278 if ((!wd) || (!wd->stack)) return NULL;
1279 return (Elm_Object_Item *) (EINA_INLIST_CONTAINER_GET(wd->stack->last,
1280 Elm_Naviframe_Item));
1283 EAPI Elm_Object_Item*
1284 elm_naviframe_bottom_item_get(const Evas_Object *obj)
1286 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1287 Widget_Data *wd = elm_widget_data_get(obj);
1288 if ((!wd) || (!wd->stack)) return NULL;
1289 return (Elm_Object_Item *) (EINA_INLIST_CONTAINER_GET(wd->stack,
1290 Elm_Naviframe_Item));
1294 elm_naviframe_item_style_set(Elm_Object_Item *it, const char *item_style)
1296 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1297 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
1299 //Return if new style is exsiting one.
1301 if (!strcmp(item_style, navi_it->style)) return;
1304 if (!strcmp("basic", navi_it->style)) return;
1306 _item_style_set(navi_it, item_style);
1310 elm_naviframe_item_style_get(const Elm_Object_Item *it)
1312 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
1313 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
1314 return navi_it->style;
1318 elm_naviframe_item_title_visible_set(Elm_Object_Item *it, Eina_Bool visible)
1320 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1321 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
1323 visible = !!visible;
1324 if (navi_it->title_visible == visible) return;
1326 navi_it->title_visible = visible;
1327 _item_title_visible_update(navi_it);
1331 elm_naviframe_item_title_visible_get(const Elm_Object_Item *it)
1333 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
1334 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
1335 return navi_it->title_visible;
1339 elm_naviframe_prev_btn_auto_pushed_set(Evas_Object *obj, Eina_Bool auto_pushed)
1341 ELM_CHECK_WIDTYPE(obj, widtype);
1342 Widget_Data *wd = elm_widget_data_get(obj);
1344 wd->auto_pushed = !!auto_pushed;
1348 elm_naviframe_prev_btn_auto_pushed_get(const Evas_Object *obj)
1350 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
1351 Widget_Data *wd = elm_widget_data_get(obj);
1352 if (!wd) return EINA_FALSE;
1353 return wd->auto_pushed;
1357 elm_naviframe_items_get(const Evas_Object *obj)
1359 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1360 Widget_Data *wd = elm_widget_data_get(obj);
1361 if (!wd) return NULL;
1366 elm_naviframe_event_enabled_set(Evas_Object *obj, Eina_Bool enabled)
1368 ELM_CHECK_WIDTYPE(obj, widtype);
1369 Widget_Data *wd = elm_widget_data_get(obj);
1371 enabled = !!enabled;
1372 if (wd->freeze_events == !enabled) return;
1373 wd->freeze_events = !enabled;
1377 elm_naviframe_event_enabled_get(const Evas_Object *obj)
1379 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
1380 Widget_Data *wd = elm_widget_data_get(obj);
1381 if (!wd) return EINA_FALSE;
1382 return !wd->freeze_events;