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;
14 Eina_Bool preserve: 1;
15 Eina_Bool auto_pushed: 1;
16 Eina_Bool freeze_events: 1;
19 struct _Elm_Naviframe_Content_Item_Pair
24 Elm_Naviframe_Item *it;
27 struct _Elm_Naviframe_Text_Item_Pair
34 struct _Elm_Naviframe_Item
38 Eina_Inlist *content_list;
39 Eina_Inlist *text_list;
41 Evas_Object *title_prev_btn;
42 Evas_Object *title_next_btn;
43 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 _mirrored_set(Evas_Object *obj, Eina_Bool rtl);
69 static void _item_text_set_hook(Elm_Object_Item *it,
72 static const char *_item_text_get_hook(const Elm_Object_Item *it,
74 static void _item_content_set_hook(Elm_Object_Item *it,
76 Evas_Object *content);
77 static Evas_Object *_item_content_get_hook(const Elm_Object_Item *it,
79 static Evas_Object *_item_content_unset_hook(Elm_Object_Item *it,
81 static void _item_signal_emit_hook(Elm_Object_Item *it,
84 static void _item_title_visible_update(Elm_Naviframe_Item *navi_it);
85 static void _sizing_eval(Evas_Object *obj);
86 static void _item_sizing_eval(Elm_Naviframe_Item *it);
87 static void _move(void *data, Evas *e, Evas_Object *obj, void *event_info);
88 static void _resize(void *data,
92 static void _hide(void *data, Evas *e, Evas_Object *obj, void *event_info);
93 static void _title_clicked(void *data, Evas_Object *obj,
96 static void _back_btn_clicked(void *data,
99 static Evas_Object *_back_btn_new(Evas_Object *obj);
100 static void _item_content_del(void *data,
104 static void _title_content_del(void *data,
108 static void _title_prev_btn_del(void *data,
112 static void _title_next_btn_del(void *data,
116 static void _title_icon_del(void *data,
120 static void _title_content_set(Elm_Naviframe_Item *it,
122 Evas_Object *content);
123 static void _title_prev_btn_set(Elm_Naviframe_Item *it,
126 static void _title_next_btn_set(Elm_Naviframe_Item *it, Evas_Object *btn);
127 static void _title_icon_set(Elm_Naviframe_Item *it, Evas_Object *icon);
128 static Evas_Object * _item_content_unset(Elm_Naviframe_Item *it);
129 static Evas_Object * _title_prev_btn_unset(Elm_Naviframe_Item *it);
130 static Evas_Object * _title_next_btn_unset(Elm_Naviframe_Item *it);
131 static Evas_Object * _title_icon_unset(Elm_Naviframe_Item *it);
132 static Evas_Object * _title_content_unset(Elm_Naviframe_Item *it,
134 static void _item_del(Elm_Naviframe_Item *it);
135 static void _pushed_finished(void *data,
137 const char *emission,
139 static void _popped_finished(void *data,
141 const char *emission,
143 static void _show_finished(void *data,
145 const char *emission,
147 static void _changed_size_hints(void *data,
151 static void _item_content_set(Elm_Naviframe_Item *navi_it,
152 Evas_Object *content);
153 static void _item_style_set(Elm_Naviframe_Item *navi_it,
154 const char *item_style);
155 static Elm_Naviframe_Item * _item_new(Evas_Object *obj,
156 const char *title_label,
157 Evas_Object *prev_btn,
158 Evas_Object *next_btn,
159 Evas_Object *content,
160 const char *item_style);
163 _del_hook(Evas_Object *obj)
166 Elm_Naviframe_Item *it;
168 wd = elm_widget_data_get(obj);
173 while (wd->stack->last)
175 it = EINA_INLIST_CONTAINER_GET(wd->stack->last,
177 wd->stack = eina_inlist_remove(wd->stack, wd->stack->last);
179 if (!wd->stack) break;
186 _theme_hook(Evas_Object *obj)
189 Elm_Naviframe_Item *it;
191 wd = elm_widget_data_get(obj);
194 _elm_theme_object_set(obj,
198 elm_widget_style_get(obj));
200 EINA_INLIST_FOREACH(wd->stack, it)
202 _item_style_set(it, it->style);
203 _item_title_visible_update(it);
206 _elm_widget_mirrored_reload(obj);
207 _mirrored_set(obj, elm_widget_mirrored_get(obj));
209 evas_object_hide(wd->rect);
212 static void _emit_hook(Evas_Object *obj,
213 const char *emission,
216 ELM_CHECK_WIDTYPE(obj, widtype);
218 Widget_Data *wd = elm_widget_data_get(obj);
221 edje_object_signal_emit(wd->base, emission, source);
225 _disable_hook(Evas_Object *obj __UNUSED__)
231 _mirrored_set(Evas_Object *obj, Eina_Bool rtl)
234 Elm_Naviframe_Item *it;
236 wd = elm_widget_data_get(obj);
239 EINA_INLIST_FOREACH(wd->stack, it)
240 edje_object_mirrored_set(VIEW(it), rtl);
241 edje_object_mirrored_set(wd->base, rtl);
245 _item_text_set_hook(Elm_Object_Item *it,
249 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
251 Elm_Naviframe_Text_Item_Pair *pair = NULL;
252 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
255 if (!part || !strcmp(part, "default"))
256 snprintf(buf, sizeof(buf), "elm.text.title");
257 else if(!strcmp("subtitle", part))
258 snprintf(buf, sizeof(buf), "elm.text.subtitle");
260 snprintf(buf, sizeof(buf), "%s", part);
262 EINA_INLIST_FOREACH(navi_it->text_list, pair)
263 if (!strcmp(buf, pair->part)) break;
267 pair = ELM_NEW(Elm_Naviframe_Text_Item_Pair);
270 ERR("Failed to allocate new text part of the item! : naviframe=%p",
274 eina_stringshare_replace(&pair->part, buf);
275 navi_it->text_list = eina_inlist_append(navi_it->text_list,
276 EINA_INLIST_GET(pair));
279 eina_stringshare_replace(&pair->text, label);
280 edje_object_part_text_set(VIEW(navi_it), buf, label);
284 snprintf(buf, sizeof(buf), "elm,state,%s,show", buf);
285 edje_object_signal_emit(VIEW(navi_it), buf, "elm");
289 snprintf(buf, sizeof(buf), "elm,state,%s,hide", buf);
290 edje_object_signal_emit(VIEW(navi_it), buf, "elm");
293 _sizing_eval(WIDGET(navi_it));
297 _item_text_get_hook(const Elm_Object_Item *it, const char *part)
299 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
300 Elm_Naviframe_Text_Item_Pair *pair = NULL;
301 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
304 if (!part || !strcmp(part, "default"))
305 snprintf(buf, sizeof(buf), "elm.text.title");
306 else if(!strcmp("subtitle", part))
307 snprintf(buf, sizeof(buf), "elm.text.subtitle");
309 snprintf(buf, sizeof(buf), "%s", part);
311 EINA_INLIST_FOREACH(navi_it->text_list, pair)
313 if (!strcmp(buf, pair->part))
320 _item_content_set_hook(Elm_Object_Item *it,
322 Evas_Object *content)
324 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
326 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
329 if ((!part) || (!strcmp(part, "elm.swallow.content")))
331 _item_content_set(navi_it, content);
334 else if (!strcmp(part, "elm.swallow.prev_btn"))
336 _title_prev_btn_set(navi_it, content, EINA_FALSE);
339 else if (!strcmp(part, "elm.swallow.next_btn"))
341 _title_next_btn_set(navi_it, content);
344 else if (!strcmp(part, "icon"))
346 _title_icon_set(navi_it, content);
351 _title_content_set(navi_it, part, content);
355 _item_content_get_hook(const Elm_Object_Item *it, const char *part)
357 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
358 Elm_Naviframe_Content_Item_Pair *pair = NULL;
359 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
362 if ((!part) || (!strcmp(part, "elm.swallow.content")))
363 return navi_it->content;
364 else if (!strcmp(part, "elm.swallow.prev_btn"))
365 return navi_it->title_prev_btn;
366 else if (!strcmp(part, "elm.swallow.next_btn"))
367 return navi_it->title_next_btn;
368 else if (!strcmp(part, "icon"))
369 return navi_it->title_icon;
372 EINA_INLIST_FOREACH(navi_it->content_list, pair)
374 if (!strcmp(part, pair->part))
375 return pair->content;
381 _item_content_unset_hook(Elm_Object_Item *it, const char *part)
383 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
384 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
387 if (!part || !strcmp("elm.swallow.content", part))
388 return _item_content_unset(navi_it);
389 else if (!strcmp(part, "elm.swallow.prev_btn"))
390 return _title_prev_btn_unset(navi_it);
391 else if (!strcmp(part, "elm.swallow.next_btn"))
392 return _title_next_btn_unset(navi_it);
393 else if (!strcmp(part, "icon"))
394 return _title_icon_unset(navi_it);
396 return _title_content_unset(navi_it, part);
400 _item_signal_emit_hook(Elm_Object_Item *it,
401 const char *emission,
404 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
405 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
406 edje_object_signal_emit(VIEW(navi_it), emission, source);
410 _item_title_visible_update(Elm_Naviframe_Item *navi_it)
412 if (navi_it->title_visible)
413 edje_object_signal_emit(VIEW(navi_it), "elm,state,title,show", "elm");
415 edje_object_signal_emit(VIEW(navi_it), "elm,state,title,hide", "elm");
419 _sizing_eval(Evas_Object *obj)
422 Elm_Naviframe_Item *it;
423 wd = elm_widget_data_get(obj);
426 EINA_INLIST_FOREACH(wd->stack, it)
427 _item_sizing_eval(it);
431 _item_sizing_eval(Elm_Naviframe_Item *it)
434 Evas_Coord x, y, w, h;
437 wd = elm_widget_data_get(WIDGET(it));
440 evas_object_geometry_get(WIDGET(it), &x, &y, &w, &h);
441 evas_object_move(VIEW(it), x, y);
442 evas_object_resize(VIEW(it), w, h);
446 _move(void *data __UNUSED__,
449 void *event_info __UNUSED__)
452 Widget_Data *wd = elm_widget_data_get(obj);
455 evas_object_geometry_get(obj, &x, &y, NULL, NULL);
456 evas_object_move(wd->rect, x, y);
462 _resize(void *data __UNUSED__,
465 void *event_info __UNUSED__)
468 Widget_Data *wd = elm_widget_data_get(obj);
471 evas_object_geometry_get(obj, NULL, NULL, &w, &h);
472 evas_object_resize(wd->rect, w, h);
478 _hide(void *data __UNUSED__,
481 void *event_info __UNUSED__)
483 Widget_Data *wd = elm_widget_data_get(obj);
485 if (wd->freeze_events)
486 evas_object_hide(wd->rect);
490 _title_clicked(void *data,
491 Evas_Object *obj __UNUSED__,
492 const char *emission __UNUSED__,
493 const char *source __UNUSED__)
495 Elm_Naviframe_Item *it = data;
496 evas_object_smart_callback_call(WIDGET(it), SIG_TITLE_CLICKED, it);
500 _back_btn_clicked(void *data,
502 void *event_info __UNUSED__)
504 /* Since edje has the event queue, clicked event could be happend multiple times
505 on some heavy environment. This callback del will prevent those scenario and
506 guarantee only one clicked for it's own page. */
507 evas_object_smart_callback_del(obj, "clicked", _back_btn_clicked);
508 elm_naviframe_item_pop(data);
512 _back_btn_new(Evas_Object *obj)
516 btn = elm_button_add(obj);
517 if (!btn) return NULL;
518 evas_object_smart_callback_add(btn, "clicked", _back_btn_clicked, obj);
519 snprintf(buf, sizeof(buf), "naviframe/back_btn/%s", elm_widget_style_get(obj));
520 elm_object_style_set(btn, buf);
525 _title_content_del(void *data,
527 Evas_Object *obj __UNUSED__,
528 void *event_info __UNUSED__)
531 Elm_Naviframe_Content_Item_Pair *pair = data;
532 Elm_Naviframe_Item *it = pair->it;
533 snprintf(buf, sizeof(buf), "elm,state,%s,hide", pair->part);
534 edje_object_signal_emit(VIEW(it), buf, "elm");
535 it->content_list = eina_inlist_remove(it->content_list,
536 EINA_INLIST_GET(pair));
537 eina_stringshare_del(pair->part);
542 _title_prev_btn_del(void *data,
544 Evas_Object *obj __UNUSED__,
545 void *event_info __UNUSED__)
547 Elm_Naviframe_Item *it = data;
548 it->back_btn = EINA_FALSE;
549 it->title_prev_btn = NULL;
550 edje_object_signal_emit(VIEW(it), "elm,state,prev_btn,hide", "elm");
554 _title_next_btn_del(void *data,
556 Evas_Object *obj __UNUSED__,
557 void *event_info __UNUSED__)
559 Elm_Naviframe_Item *it = data;
560 it->title_next_btn = NULL;
561 edje_object_signal_emit(VIEW(it), "elm,state,next_btn,hide", "elm");
565 _title_icon_del(void *data,
567 Evas_Object *obj __UNUSED__,
568 void *event_info __UNUSED__)
570 Elm_Naviframe_Item *it = data;
571 it->title_icon = NULL;
572 edje_object_signal_emit(VIEW(it), "elm,state,icon,hide", "elm");
576 _item_content_del(void *data,
578 Evas_Object *obj __UNUSED__,
579 void *event_info __UNUSED__)
581 Elm_Naviframe_Item *it = data;
583 edje_object_signal_emit(VIEW(it), "elm,state,content,hide", "elm");
587 _title_content_set(Elm_Naviframe_Item *it,
589 Evas_Object *content)
592 Elm_Naviframe_Content_Item_Pair *pair = NULL;
594 EINA_INLIST_FOREACH(it->content_list, pair)
595 if (!strcmp(part, pair->part)) break;
597 if ((pair) && (pair->content))
601 evas_object_del(pair->content);
602 pair->content = NULL;
605 if (pair->content == content) return;
606 evas_object_event_callback_del(pair->content,
609 evas_object_event_callback_del(pair->content,
610 EVAS_CALLBACK_CHANGED_SIZE_HINTS,
611 _changed_size_hints);
612 evas_object_del(pair->content);
613 snprintf(buf, sizeof(buf), "elm,state,%s,hide", part);
614 edje_object_signal_emit(VIEW(it), buf, "elm");
618 pair = ELM_NEW(Elm_Naviframe_Content_Item_Pair);
621 ERR("Failed to allocate new content part of the item! : naviframe=%p", WIDGET(it));
625 eina_stringshare_replace(&pair->part, part);
626 it->content_list = eina_inlist_append(it->content_list,
627 EINA_INLIST_GET(pair));
630 elm_widget_sub_object_add(WIDGET(it), content);
631 evas_object_event_callback_add(content,
635 evas_object_event_callback_add(content,
636 EVAS_CALLBACK_CHANGED_SIZE_HINTS,
639 edje_object_part_swallow(VIEW(it), part, content);
640 snprintf(buf, sizeof(buf), "elm,state,%s,show", part);
641 edje_object_signal_emit(VIEW(it), buf, "elm");
642 pair->content = content;
643 _sizing_eval(WIDGET(it));
647 _title_prev_btn_set(Elm_Naviframe_Item *it,
651 if (it->title_prev_btn == btn) return;
653 if (it->title_prev_btn)
654 evas_object_del(it->title_prev_btn);
656 it->title_prev_btn = btn;
659 elm_widget_sub_object_add(WIDGET(it), btn);
660 evas_object_event_callback_add(btn,
664 evas_object_event_callback_add(btn,
665 EVAS_CALLBACK_CHANGED_SIZE_HINTS,
668 edje_object_part_swallow(VIEW(it), "elm.swallow.prev_btn", btn);
669 edje_object_signal_emit(VIEW(it), "elm,state,prev_btn,show", "elm");
670 it->back_btn = back_btn;
672 _sizing_eval(WIDGET(it));
676 _title_next_btn_set(Elm_Naviframe_Item *it, Evas_Object *btn)
678 if (it->title_next_btn == btn) return;
680 if (it->title_next_btn)
681 evas_object_del(it->title_next_btn);
683 it->title_next_btn = btn;
686 elm_widget_sub_object_add(WIDGET(it), btn);
687 evas_object_event_callback_add(btn,
691 evas_object_event_callback_add(btn,
692 EVAS_CALLBACK_CHANGED_SIZE_HINTS,
695 edje_object_part_swallow(VIEW(it), "elm.swallow.next_btn", btn);
696 edje_object_signal_emit(VIEW(it), "elm,state,next_btn,show", "elm");
698 _sizing_eval(WIDGET(it));
702 _title_icon_set(Elm_Naviframe_Item *it, Evas_Object *icon)
704 if (it->title_icon == icon) return;
707 evas_object_del(it->title_icon);
709 it->title_icon = icon;
712 elm_widget_sub_object_add(WIDGET(it), icon);
713 evas_object_event_callback_add(icon,
717 evas_object_event_callback_add(icon,
718 EVAS_CALLBACK_CHANGED_SIZE_HINTS,
721 edje_object_part_swallow(VIEW(it), "elm.swallow.icon", icon);
722 edje_object_signal_emit(VIEW(it), "elm,state,icon,show", "elm");
724 _sizing_eval(WIDGET(it));
728 _item_content_unset(Elm_Naviframe_Item *it)
730 Evas_Object *content = it->content;
731 if (!content) return NULL;
733 elm_widget_sub_object_del(WIDGET(it), content);
734 edje_object_part_unswallow(VIEW(it), content);
735 edje_object_signal_emit(VIEW(it), "elm,state,content,hide", "elm");
736 evas_object_event_callback_del(content,
739 evas_object_event_callback_del(content,
740 EVAS_CALLBACK_CHANGED_SIZE_HINTS,
741 _changed_size_hints);
742 _sizing_eval(WIDGET(it));
749 _title_prev_btn_unset(Elm_Naviframe_Item *it)
751 Evas_Object *content = it->title_prev_btn;
752 if (!content) return NULL;
754 elm_widget_sub_object_del(WIDGET(it), content);
755 edje_object_part_unswallow(VIEW(it), content);
756 edje_object_signal_emit(VIEW(it), "elm,state,prev_btn,hide", "elm");
757 evas_object_event_callback_del(content,
759 _title_prev_btn_del);
760 evas_object_event_callback_del(content,
761 EVAS_CALLBACK_CHANGED_SIZE_HINTS,
762 _changed_size_hints);
763 _sizing_eval(WIDGET(it));
765 it->title_prev_btn = NULL;
770 _title_next_btn_unset(Elm_Naviframe_Item *it)
772 Evas_Object *content = it->title_next_btn;
773 if (!content) return NULL;
775 elm_widget_sub_object_del(WIDGET(it), content);
776 edje_object_part_unswallow(VIEW(it), content);
777 edje_object_signal_emit(VIEW(it), "elm,state,next_btn,hide", "elm");
778 evas_object_event_callback_del(content,
780 _title_next_btn_del);
781 evas_object_event_callback_del(content,
782 EVAS_CALLBACK_CHANGED_SIZE_HINTS,
783 _changed_size_hints);
784 _sizing_eval(WIDGET(it));
786 it->title_next_btn = NULL;
791 _title_icon_unset(Elm_Naviframe_Item *it)
793 Evas_Object *content = it->title_icon;
794 if (!content) return NULL;
796 elm_widget_sub_object_del(WIDGET(it), content);
797 edje_object_part_unswallow(VIEW(it), content);
798 edje_object_signal_emit(VIEW(it), "elm,state,icon,hide", "elm");
799 evas_object_event_callback_del(content,
802 evas_object_event_callback_del(content,
803 EVAS_CALLBACK_CHANGED_SIZE_HINTS,
804 _changed_size_hints);
805 _sizing_eval(WIDGET(it));
807 it->title_icon = NULL;
812 _title_content_unset(Elm_Naviframe_Item *it, const char *part)
814 Elm_Naviframe_Content_Item_Pair *pair = NULL;
816 Evas_Object *content = NULL;
818 EINA_INLIST_FOREACH(it->content_list, pair)
820 if (!strcmp(part, pair->part))
822 content = pair->content;
823 eina_stringshare_del(pair->part);
824 it->content_list = eina_inlist_remove(it->content_list,
825 EINA_INLIST_GET(pair));
831 if (!content) return NULL;
833 elm_widget_sub_object_del(WIDGET(it), content);
834 edje_object_part_unswallow(VIEW(it), content);
835 snprintf(buf, sizeof(buf), "elm,state,%s,hide", part);
836 edje_object_signal_emit(VIEW(it), buf, "elm");
837 evas_object_event_callback_del(content,
840 evas_object_event_callback_del(content,
841 EVAS_CALLBACK_CHANGED_SIZE_HINTS,
842 _changed_size_hints);
843 _sizing_eval(WIDGET(it));
850 _item_del(Elm_Naviframe_Item *it)
853 Elm_Naviframe_Content_Item_Pair *content_pair;
854 Elm_Naviframe_Text_Item_Pair *text_pair;
858 wd = elm_widget_data_get(WIDGET(it));
861 if (it->title_prev_btn)
862 evas_object_del(it->title_prev_btn);
863 if (it->title_next_btn)
864 evas_object_del(it->title_next_btn);
866 evas_object_del(it->title_icon);
867 if ((it->content) && (!wd->preserve))
868 evas_object_del(it->content);
870 while (it->content_list)
872 content_pair = EINA_INLIST_CONTAINER_GET(it->content_list,
873 Elm_Naviframe_Content_Item_Pair);
874 evas_object_event_callback_del(content_pair->content,
877 evas_object_event_callback_del(content_pair->content,
878 EVAS_CALLBACK_CHANGED_SIZE_HINTS,
879 _changed_size_hints);
880 evas_object_del(content_pair->content);
881 eina_stringshare_del(content_pair->part);
882 it->content_list = eina_inlist_remove(it->content_list,
887 while (it->text_list)
889 text_pair = EINA_INLIST_CONTAINER_GET(it->text_list,
890 Elm_Naviframe_Text_Item_Pair);
891 eina_stringshare_del(text_pair->part);
892 eina_stringshare_del(text_pair->text);
893 it->text_list = eina_inlist_remove(it->text_list,
898 eina_stringshare_del(it->style);
900 elm_widget_item_del(it);
904 _pushed_finished(void *data,
905 Evas_Object *obj __UNUSED__,
906 const char *emission __UNUSED__,
907 const char *source __UNUSED__)
910 Elm_Naviframe_Item *it = data;
913 wd = elm_widget_data_get(WIDGET(it));
916 evas_object_hide(VIEW(it));
917 evas_object_smart_callback_call(WIDGET(it),
923 _popped_finished(void *data,
924 Evas_Object *obj __UNUSED__,
925 const char *emission __UNUSED__,
926 const char *source __UNUSED__)
928 Elm_Naviframe_Item *it = data;
930 evas_object_smart_callback_call(WIDGET(it),
937 _show_finished(void *data,
938 Evas_Object *obj __UNUSED__,
939 const char *emission __UNUSED__,
940 const char *source __UNUSED__)
942 Elm_Naviframe_Item *it;
947 wd = elm_widget_data_get(WIDGET(it));
950 evas_object_smart_callback_call(WIDGET(it),
951 SIG_TRANSITION_FINISHED,
953 if (wd->freeze_events)
954 evas_object_hide(wd->rect);
958 _changed_size_hints(void *data,
960 Evas_Object *obj __UNUSED__,
961 void *event_info __UNUSED__)
967 _item_content_set(Elm_Naviframe_Item *navi_it, Evas_Object *content)
969 if (navi_it->content == content) return;
970 if (navi_it->content) evas_object_del(navi_it->content);
971 elm_widget_sub_object_add(WIDGET(navi_it), content);
972 edje_object_part_swallow(VIEW(navi_it),
973 "elm.swallow.content",
976 edje_object_signal_emit(VIEW(navi_it),
977 "elm,state,content,show",
980 edje_object_signal_emit(VIEW(navi_it),
981 "elm,state,content,hide",
983 evas_object_event_callback_add(content,
987 evas_object_event_callback_add(content,
988 EVAS_CALLBACK_CHANGED_SIZE_HINTS,
991 navi_it->content = content;
992 _sizing_eval(WIDGET(navi_it));
995 //FIXME: need to handle if this function is called while transition
997 _item_style_set(Elm_Naviframe_Item *navi_it, const char *item_style)
999 Elm_Naviframe_Content_Item_Pair *content_pair;
1000 Elm_Naviframe_Text_Item_Pair *text_pair;
1007 sprintf(buf, "item/basic");
1008 eina_stringshare_replace(&navi_it->style, "basic");
1012 if (strlen(item_style) > sizeof(buf))
1013 WRN("too much long style name! : naviframe=%p", WIDGET(navi_it));
1014 sprintf(buf, "item/%s", item_style);
1015 eina_stringshare_replace(&navi_it->style, item_style);
1017 _elm_theme_object_set(WIDGET(navi_it),
1021 elm_widget_style_get(WIDGET(navi_it)));
1023 EINA_INLIST_FOREACH(navi_it->text_list, text_pair)
1024 _item_text_set_hook((Elm_Object_Item *) navi_it,
1028 EINA_INLIST_FOREACH(navi_it->content_list, content_pair)
1029 _item_content_set_hook((Elm_Object_Item *) navi_it,
1031 content_pair->content);
1033 if (navi_it->content)
1035 edje_object_part_swallow(VIEW(navi_it),
1036 "elm.swallow.content",
1038 edje_object_signal_emit(VIEW(navi_it),
1039 "elm,state,content,show",
1044 if (navi_it->title_prev_btn)
1046 edje_object_part_swallow(VIEW(navi_it),
1047 "elm.swallow.prev_btn",
1048 navi_it->title_prev_btn);
1049 edje_object_signal_emit(VIEW(navi_it),
1050 "elm,state,prev_btn,show",
1055 if (navi_it->title_next_btn)
1057 edje_object_part_swallow(VIEW(navi_it),
1058 "elm.swallow.next_btn",
1059 navi_it->title_next_btn);
1060 edje_object_signal_emit(VIEW(navi_it),
1061 "elm,state,next_btn,show",
1065 navi_it->title_visible = EINA_TRUE;
1066 _sizing_eval(WIDGET(navi_it));
1068 wd = elm_widget_data_get(WIDGET(navi_it));
1071 if (wd->freeze_events)
1072 evas_object_hide(wd->rect);
1075 static Elm_Naviframe_Item *
1076 _item_new(Evas_Object *obj,
1077 const char *title_label,
1078 Evas_Object *prev_btn,
1079 Evas_Object *next_btn,
1080 Evas_Object *content,
1081 const char *item_style)
1083 Widget_Data *wd = elm_widget_data_get(obj);
1086 Elm_Naviframe_Item *it = elm_widget_item_new(obj, Elm_Naviframe_Item);
1089 ERR("Failed to allocate new item! : naviframe=%p", obj);
1093 elm_widget_item_text_set_hook_set(it, _item_text_set_hook);
1094 elm_widget_item_text_get_hook_set(it, _item_text_get_hook);
1095 elm_widget_item_content_set_hook_set(it, _item_content_set_hook);
1096 elm_widget_item_content_get_hook_set(it, _item_content_get_hook);
1097 elm_widget_item_content_unset_hook_set(it, _item_content_unset_hook);
1098 elm_widget_item_signal_emit_hook_set(it, _item_signal_emit_hook);
1101 VIEW(it) = edje_object_add(evas_object_evas_get(obj));
1102 edje_object_mirrored_set(VIEW(it), elm_widget_mirrored_get(obj));
1103 evas_object_smart_member_add(VIEW(it), wd->base);
1104 elm_widget_sub_object_add(obj, VIEW(it));
1105 edje_object_signal_callback_add(VIEW(it),
1106 "elm,action,show,finished",
1108 _show_finished, it);
1109 edje_object_signal_callback_add(VIEW(it),
1110 "elm,action,pushed,finished",
1112 _pushed_finished, it);
1113 edje_object_signal_callback_add(VIEW(it),
1114 "elm,action,popped,finished",
1116 _popped_finished, it);
1117 edje_object_signal_callback_add(VIEW(it),
1118 "elm,action,title,clicked",
1120 _title_clicked, it);
1122 _item_style_set(it, item_style);
1123 _item_text_set_hook((Elm_Object_Item *) it, "elm.text.title", title_label);
1126 if ((!prev_btn) && wd->auto_pushed && eina_inlist_count(wd->stack))
1128 prev_btn = _back_btn_new(obj);
1129 _title_prev_btn_set(it, prev_btn, EINA_TRUE);
1132 _title_prev_btn_set(it, prev_btn, EINA_FALSE);
1134 _title_next_btn_set(it, next_btn);
1135 _item_content_set(it, content);
1136 it->title_visible = EINA_TRUE;
1141 elm_naviframe_add(Evas_Object *parent)
1147 ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL);
1148 ELM_SET_WIDTYPE(widtype, "naviframe");
1149 elm_widget_type_set(obj, "naviframe");
1150 elm_widget_sub_object_add(parent, obj);
1151 elm_widget_data_set(obj, wd);
1152 elm_widget_del_hook_set(obj, _del_hook);
1153 elm_widget_disable_hook_set(obj, _disable_hook);
1154 elm_widget_theme_hook_set(obj, _theme_hook);
1155 elm_widget_signal_emit_hook_set(obj, _emit_hook);
1158 wd->base = edje_object_add(e);
1159 edje_object_mirrored_set(wd->base, elm_widget_mirrored_get(obj));
1160 elm_widget_resize_object_set(obj, wd->base);
1161 _elm_theme_object_set(obj, wd->base, "naviframe", "base", "default");
1164 wd->rect = evas_object_rectangle_add(e);
1165 evas_object_color_set(wd->rect, 0, 0, 0, 0);
1166 elm_widget_sub_object_add(obj, wd->rect);
1168 evas_object_event_callback_add(obj, EVAS_CALLBACK_MOVE, _move, obj);
1169 evas_object_event_callback_add(obj, EVAS_CALLBACK_RESIZE, _resize, obj);
1170 evas_object_event_callback_add(obj, EVAS_CALLBACK_HIDE, _hide, obj);
1171 evas_object_smart_callbacks_descriptions_set(obj, _signals);
1173 wd->auto_pushed = EINA_TRUE;
1174 wd->freeze_events = EINA_TRUE;
1179 EAPI Elm_Object_Item *
1180 elm_naviframe_item_push(Evas_Object *obj,
1181 const char *title_label,
1182 Evas_Object *prev_btn,
1183 Evas_Object *next_btn,
1184 Evas_Object *content,
1185 const char *item_style)
1187 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1189 Elm_Naviframe_Item *prev_it, *it;
1191 wd = elm_widget_data_get(obj);
1192 if (!wd) return NULL;
1194 it = _item_new(obj, title_label, prev_btn, next_btn, content, item_style);
1195 if (!it) return NULL;
1197 evas_object_show(VIEW(it));
1199 prev_it = (Elm_Naviframe_Item *) elm_naviframe_top_item_get(obj);
1202 if (wd->freeze_events)
1204 evas_object_raise(wd->rect);
1205 evas_object_show(wd->rect);
1207 edje_object_signal_emit(VIEW(prev_it),
1208 "elm,state,cur,pushed",
1210 edje_object_signal_emit(VIEW(it),
1211 "elm,state,new,pushed",
1213 edje_object_message_signal_process(VIEW(prev_it));
1214 edje_object_message_signal_process(VIEW(it));
1216 wd->stack = eina_inlist_append(wd->stack, EINA_INLIST_GET(it));
1218 return (Elm_Object_Item *) it;
1221 EAPI Elm_Object_Item *
1222 elm_naviframe_item_insert_before(Elm_Object_Item *before,
1223 const char *title_label,
1224 Evas_Object *prev_btn,
1225 Evas_Object *next_btn,
1226 Evas_Object *content,
1227 const char *item_style)
1229 ELM_OBJ_ITEM_CHECK_OR_RETURN(before, NULL);
1230 Elm_Naviframe_Item *it;
1233 wd = elm_widget_data_get(WIDGET(before));
1234 if (!wd) return NULL;
1236 it = _item_new(WIDGET(before), title_label, prev_btn, next_btn, content,
1238 if (!it) return NULL;
1241 eina_inlist_prepend_relative(wd->stack, EINA_INLIST_GET(it),
1242 EINA_INLIST_GET(((Elm_Naviframe_Item *) before)));
1243 _sizing_eval(WIDGET(before));
1244 return (Elm_Object_Item *) it;
1247 EAPI Elm_Object_Item *
1248 elm_naviframe_item_insert_after(Elm_Object_Item *after,
1249 const char *title_label,
1250 Evas_Object *prev_btn,
1251 Evas_Object *next_btn,
1252 Evas_Object *content,
1253 const char *item_style)
1255 ELM_OBJ_ITEM_CHECK_OR_RETURN(after, NULL);
1256 Elm_Naviframe_Item *it;
1259 wd = elm_widget_data_get(WIDGET(after));
1260 if (!wd) return NULL;
1262 it = _item_new(WIDGET(after), title_label, prev_btn, next_btn, content,
1264 if (!it) return NULL;
1266 if (elm_naviframe_top_item_get(WIDGET(after)) == after)
1268 evas_object_hide(VIEW(after));
1269 evas_object_show(VIEW(it));
1272 eina_inlist_append_relative(wd->stack, EINA_INLIST_GET(it),
1273 EINA_INLIST_GET(((Elm_Naviframe_Item *) after)));
1274 _sizing_eval(WIDGET(after));
1275 return (Elm_Object_Item *) it;
1279 elm_naviframe_item_pop(Evas_Object *obj)
1281 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1282 Elm_Naviframe_Item *it, *prev_it = NULL;
1284 Evas_Object *content = NULL;
1286 wd = elm_widget_data_get(obj);
1287 if (!wd) return NULL;
1289 it = (Elm_Naviframe_Item *) elm_naviframe_top_item_get(obj);
1290 if (!it) return NULL;
1291 elm_widget_tree_unfocusable_set(it->content, EINA_TRUE);
1293 content = it->content;
1295 if (wd->stack->last->prev)
1296 prev_it = EINA_INLIST_CONTAINER_GET(wd->stack->last->prev,
1297 Elm_Naviframe_Item);
1298 wd->stack = eina_inlist_remove(wd->stack, EINA_INLIST_GET(it));
1301 if (wd->freeze_events)
1303 evas_object_raise(wd->rect);
1304 evas_object_show(wd->rect);
1306 edje_object_signal_emit(VIEW(it), "elm,state,cur,popped", "elm");
1307 evas_object_show(VIEW(prev_it));
1308 evas_object_raise(VIEW(prev_it));
1309 edje_object_signal_emit(VIEW(prev_it),
1310 "elm,state,prev,popped",
1312 edje_object_message_signal_process(VIEW(it));
1313 edje_object_message_signal_process(VIEW(prev_it));
1322 elm_naviframe_item_pop_to(Elm_Object_Item *it)
1324 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1325 Elm_Naviframe_Item *navi_it;
1327 Eina_Inlist *l, *prev_l;
1329 navi_it = (Elm_Naviframe_Item *) it;
1330 wd = elm_widget_data_get(WIDGET(navi_it));
1333 if (it == elm_naviframe_top_item_get(WIDGET(navi_it))) return;
1335 l = wd->stack->last->prev;
1339 if (EINA_INLIST_CONTAINER_GET(l, Elm_Naviframe_Item) ==
1340 ((Elm_Naviframe_Item *) it)) break;
1342 wd->stack = eina_inlist_remove(wd->stack, l);
1343 _item_del(EINA_INLIST_CONTAINER_GET(l, Elm_Naviframe_Item));
1346 elm_naviframe_item_pop(WIDGET(navi_it));
1350 elm_naviframe_item_promote(Elm_Object_Item *it)
1352 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1353 Elm_Naviframe_Item *navi_it;
1354 Elm_Naviframe_Item *prev_it;
1357 navi_it = (Elm_Naviframe_Item *) it;
1358 wd = elm_widget_data_get(navi_it->base.widget);
1361 if (it == elm_naviframe_top_item_get(navi_it->base.widget)) return;
1362 wd->stack = eina_inlist_demote(wd->stack, EINA_INLIST_GET(navi_it));
1363 prev_it = EINA_INLIST_CONTAINER_GET(wd->stack->last->prev,
1364 Elm_Naviframe_Item);
1365 if (wd->freeze_events)
1367 evas_object_raise(wd->rect);
1368 evas_object_show(wd->rect);
1370 edje_object_signal_emit(VIEW(prev_it),
1371 "elm,state,cur,pushed",
1373 evas_object_show(VIEW(navi_it));
1374 evas_object_raise(VIEW(navi_it));
1375 edje_object_signal_emit(VIEW(navi_it),
1376 "elm,state,new,pushed",
1378 edje_object_message_signal_process(VIEW(prev_it));
1379 edje_object_message_signal_process(VIEW(navi_it));
1383 elm_naviframe_item_del(Elm_Object_Item *it)
1385 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1386 Elm_Naviframe_Item *navi_it;
1389 navi_it =(Elm_Naviframe_Item *) it;
1390 wd = elm_widget_data_get(WIDGET(navi_it));
1393 if (it == elm_naviframe_top_item_get(WIDGET(navi_it)))
1395 wd->stack = eina_inlist_remove(wd->stack, EINA_INLIST_GET(navi_it));
1397 navi_it = EINA_INLIST_CONTAINER_GET(wd->stack->last,
1398 Elm_Naviframe_Item);
1399 evas_object_show(VIEW(navi_it));
1400 evas_object_raise(VIEW(navi_it));
1401 edje_object_signal_emit(VIEW(navi_it), "elm,state,visible", "elm");
1405 wd->stack = eina_inlist_remove(wd->stack, EINA_INLIST_GET(navi_it));
1411 elm_naviframe_content_preserve_on_pop_set(Evas_Object *obj, Eina_Bool preserve)
1413 ELM_CHECK_WIDTYPE(obj, widtype);
1414 Widget_Data *wd = elm_widget_data_get(obj);
1416 wd->preserve = !!preserve;
1420 elm_naviframe_content_preserve_on_pop_get(const Evas_Object *obj)
1422 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
1423 Widget_Data *wd = elm_widget_data_get(obj);
1424 if (!wd) return EINA_FALSE;
1425 return wd->preserve;
1428 EAPI Elm_Object_Item*
1429 elm_naviframe_top_item_get(const Evas_Object *obj)
1431 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1432 Widget_Data *wd = elm_widget_data_get(obj);
1433 if ((!wd) || (!wd->stack)) return NULL;
1434 return (Elm_Object_Item *) (EINA_INLIST_CONTAINER_GET(wd->stack->last,
1435 Elm_Naviframe_Item));
1438 EAPI Elm_Object_Item*
1439 elm_naviframe_bottom_item_get(const Evas_Object *obj)
1441 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1442 Widget_Data *wd = elm_widget_data_get(obj);
1443 if ((!wd) || (!wd->stack)) return NULL;
1444 return (Elm_Object_Item *) (EINA_INLIST_CONTAINER_GET(wd->stack,
1445 Elm_Naviframe_Item));
1449 elm_naviframe_item_style_set(Elm_Object_Item *it, const char *item_style)
1451 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1452 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
1454 //Return if new style is exsiting one.
1456 if (!strcmp(item_style, navi_it->style)) return;
1459 if (!strcmp("basic", navi_it->style)) return;
1461 _item_style_set(navi_it, item_style);
1465 elm_naviframe_item_style_get(const Elm_Object_Item *it)
1467 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
1468 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
1469 return navi_it->style;
1473 elm_naviframe_item_title_visible_set(Elm_Object_Item *it, Eina_Bool visible)
1475 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1476 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
1478 visible = !!visible;
1479 if (navi_it->title_visible == visible) return;
1481 navi_it->title_visible = visible;
1482 _item_title_visible_update(navi_it);
1486 elm_naviframe_item_title_visible_get(const Elm_Object_Item *it)
1488 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
1489 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
1490 return navi_it->title_visible;
1494 elm_naviframe_prev_btn_auto_pushed_set(Evas_Object *obj, Eina_Bool auto_pushed)
1496 ELM_CHECK_WIDTYPE(obj, widtype);
1497 Widget_Data *wd = elm_widget_data_get(obj);
1499 wd->auto_pushed = !!auto_pushed;
1503 elm_naviframe_prev_btn_auto_pushed_get(const Evas_Object *obj)
1505 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
1506 Widget_Data *wd = elm_widget_data_get(obj);
1507 if (!wd) return EINA_FALSE;
1508 return wd->auto_pushed;
1512 elm_naviframe_items_get(const Evas_Object *obj)
1514 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1515 Widget_Data *wd = elm_widget_data_get(obj);
1516 if (!wd) return NULL;