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;
46 Eina_Bool content_unfocusable : 1;
49 static const char *widtype = NULL;
52 static const char SIG_TRANSITION_FINISHED[] = "transition,finished";
53 static const char SIG_TITLE_CLICKED[] = "title,clicked";
55 static const Evas_Smart_Cb_Description _signals[] = {
56 {SIG_TRANSITION_FINISHED, ""},
57 {SIG_TITLE_CLICKED, ""},
61 static void _text_set_hook(Evas_Object *obj,
64 static const char *_text_get_hook(const Evas_Object *obj, const char *part);
65 static void _content_set_hook(Evas_Object *obj,
67 Evas_Object *content);
68 static Evas_Object *_content_get_hook(const Evas_Object *obj, const char *part);
69 static Evas_Object *_content_unset_hook(Evas_Object *obj, const char *part);
70 static void _del_hook(Evas_Object *obj);
71 static void _theme_hook(Evas_Object *obj);
72 static void _emit_hook(Evas_Object *obj,
75 static void _disable_hook(Evas_Object *obj);
76 static void _item_text_set_hook(Elm_Object_Item *it,
79 static const char *_item_text_get_hook(const Elm_Object_Item *it,
81 static void _item_content_set_hook(Elm_Object_Item *it,
83 Evas_Object *content);
84 static Evas_Object *_item_content_get_hook(const Elm_Object_Item *it,
86 static Evas_Object *_item_content_unset_hook(Elm_Object_Item *it,
88 static void _item_signal_emit_hook(Elm_Object_Item *it,
91 static void _item_title_visible_update(Elm_Naviframe_Item *navi_it);
92 static void _sizing_eval(Evas_Object *obj);
93 static void _move(void *data, Evas *e, Evas_Object *obj, void *event_info);
94 static void _resize(void *data,
98 static void _title_clicked(void *data, Evas_Object *obj,
101 static void _back_btn_clicked(void *data,
104 static Evas_Object *_back_btn_new(Evas_Object *obj);
105 static void _item_content_del(void *data,
109 static void _title_content_del(void *data,
113 static void _title_prev_btn_del(void *data,
117 static void _title_next_btn_del(void *data,
121 static void _title_icon_del(void *data,
125 static void _title_content_set(Elm_Naviframe_Item *it,
127 Evas_Object *content);
128 static void _title_prev_btn_set(Elm_Naviframe_Item *it,
131 static void _title_next_btn_set(Elm_Naviframe_Item *it, Evas_Object *btn);
132 static void _title_icon_set(Elm_Naviframe_Item *it, Evas_Object *icon);
133 static Evas_Object * _item_content_unset(Elm_Naviframe_Item *it);
134 static Evas_Object * _title_prev_btn_unset(Elm_Naviframe_Item *it);
135 static Evas_Object * _title_next_btn_unset(Elm_Naviframe_Item *it);
136 static Evas_Object * _title_icon_unset(Elm_Naviframe_Item *it);
137 static Evas_Object * _title_content_unset(Elm_Naviframe_Item *it,
139 static void _item_del(Elm_Naviframe_Item *it);
140 static Eina_Bool _item_del_pre_hook(Elm_Object_Item *it);
141 static void _pushed_finished(void *data,
143 const char *emission,
145 static void _popped_finished(void *data,
147 const char *emission,
149 static void _show_finished(void *data,
151 const char *emission,
153 static void _changed_size_hints(void *data,
157 static void _item_content_set(Elm_Naviframe_Item *navi_it,
158 Evas_Object *content);
159 static void _item_style_set(Elm_Naviframe_Item *navi_it,
160 const char *item_style);
161 static Elm_Naviframe_Item * _item_new(Evas_Object *obj,
162 const char *title_label,
163 Evas_Object *prev_btn,
164 Evas_Object *next_btn,
165 Evas_Object *content,
166 const char *item_style);
167 static Eina_Bool _focus_next_hook(const Evas_Object *obj,
168 Elm_Focus_Direction dir,
172 _del_hook(Evas_Object *obj)
175 Elm_Naviframe_Item *it;
177 wd = elm_widget_data_get(obj);
182 while (wd->stack->last)
184 it = EINA_INLIST_CONTAINER_GET(wd->stack->last,
186 wd->stack = eina_inlist_remove(wd->stack, wd->stack->last);
188 elm_widget_item_free(it);
189 if (!wd->stack) break;
196 _theme_hook(Evas_Object *obj)
199 Elm_Naviframe_Item *it;
201 wd = elm_widget_data_get(obj);
204 _elm_theme_object_set(obj,
208 elm_widget_style_get(obj));
210 EINA_INLIST_FOREACH(wd->stack, it)
212 _item_style_set(it, it->style);
213 _item_title_visible_update(it);
217 static void _emit_hook(Evas_Object *obj,
218 const char *emission,
221 Elm_Object_Item *it = elm_naviframe_top_item_get(obj);
223 return elm_object_item_signal_emit(it, emission, source);
227 _disable_hook(Evas_Object *obj __UNUSED__)
233 _item_text_set_hook(Elm_Object_Item *it,
237 Elm_Naviframe_Text_Item_Pair *pair = NULL;
238 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *)it;
241 if (!part || !strcmp(part, "default"))
242 snprintf(buf, sizeof(buf), "elm.text.title");
243 else if (!strcmp("subtitle", part))
244 snprintf(buf, sizeof(buf), "elm.text.subtitle");
246 snprintf(buf, sizeof(buf), "%s", part);
248 EINA_INLIST_FOREACH(navi_it->text_list, pair)
249 if (!strcmp(buf, pair->part)) break;
253 pair = ELM_NEW(Elm_Naviframe_Text_Item_Pair);
256 ERR("Failed to allocate new text part of the item! : naviframe=%p",
260 eina_stringshare_replace(&pair->part, buf);
261 navi_it->text_list = eina_inlist_append(navi_it->text_list,
262 EINA_INLIST_GET(pair));
264 elm_object_part_text_set(VIEW(navi_it), buf, label);
268 snprintf(buf, sizeof(buf), "elm,state,%s,show", buf);
269 elm_object_signal_emit(VIEW(navi_it), buf, "elm");
273 snprintf(buf, sizeof(buf), "elm,state,%s,hide", buf);
274 elm_object_signal_emit(VIEW(navi_it), buf, "elm");
277 _sizing_eval(WIDGET(navi_it));
281 _item_text_get_hook(const Elm_Object_Item *it, const char *part)
285 if (!part || !strcmp(part, "default"))
286 snprintf(buf, sizeof(buf), "elm.text.title");
287 else if (!strcmp("subtitle", part))
288 snprintf(buf, sizeof(buf), "elm.text.subtitle");
290 snprintf(buf, sizeof(buf), "%s", part);
292 return elm_object_part_text_get(VIEW(it), buf);
296 _item_content_set_hook(Elm_Object_Item *it,
298 Evas_Object *content)
300 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *)it;
303 if (!part || !strcmp("default", part))
305 _item_content_set(navi_it, content);
308 else if (!strcmp(part, "prev_btn"))
310 _title_prev_btn_set(navi_it, content, EINA_FALSE);
313 else if (!strcmp(part, "next_btn"))
315 _title_next_btn_set(navi_it, content);
318 else if (!strcmp(part, "icon"))
320 _title_icon_set(navi_it, content);
325 _title_content_set(navi_it, part, content);
329 _item_content_get_hook(const Elm_Object_Item *it, const char *part)
331 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *)it;
334 if (!part || !strcmp("default", part))
335 return navi_it->content;
336 else if (!strcmp(part, "prev_btn"))
337 return navi_it->title_prev_btn;
338 else if (!strcmp(part, "next_btn"))
339 return navi_it->title_next_btn;
340 else if (!strcmp(part, "icon"))
341 return navi_it->title_icon;
344 return elm_object_part_content_get(VIEW(navi_it), part);
348 _item_content_unset_hook(Elm_Object_Item *it, const char *part)
350 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *)it;
353 if (!part || !strcmp("default", part))
354 return _item_content_unset(navi_it);
355 else if (!strcmp(part, "prev_btn"))
356 return _title_prev_btn_unset(navi_it);
357 else if (!strcmp(part, "next_btn"))
358 return _title_next_btn_unset(navi_it);
359 else if (!strcmp(part, "icon"))
360 return _title_icon_unset(navi_it);
362 return _title_content_unset(navi_it, part);
366 _item_signal_emit_hook(Elm_Object_Item *it,
367 const char *emission,
370 elm_object_signal_emit(VIEW(it), emission, source);
374 _item_title_visible_update(Elm_Naviframe_Item *navi_it)
376 if (navi_it->title_visible)
377 elm_object_signal_emit(VIEW(navi_it), "elm,state,title,show", "elm");
379 elm_object_signal_emit(VIEW(navi_it), "elm,state,title,hide", "elm");
383 _sizing_eval(Evas_Object *obj)
386 Elm_Naviframe_Item *it;
387 Evas_Coord x, y, w, h;
388 Evas_Coord minw = -1, minh = -1;
390 wd = elm_widget_data_get(obj);
393 evas_object_geometry_get(obj, &x, &y, &w, &h);
395 EINA_INLIST_FOREACH(wd->stack, it)
397 evas_object_move(VIEW(it), x, y);
398 evas_object_resize(VIEW(it), w, h);
399 edje_object_size_min_calc(elm_layout_edje_get(VIEW(it)),
402 if (it->minw > minw) minw = it->minw;
403 if (it->minh > minh) minh = it->minh;
405 evas_object_size_hint_min_set(obj, minw, minh);
406 evas_object_size_hint_max_set(obj, -1, -1);
410 _move(void *data __UNUSED__,
413 void *event_info __UNUSED__)
419 _resize(void *data __UNUSED__,
422 void *event_info __UNUSED__)
428 _title_clicked(void *data,
429 Evas_Object *obj __UNUSED__,
430 const char *emission __UNUSED__,
431 const char *source __UNUSED__)
433 Elm_Naviframe_Item *it = data;
434 evas_object_smart_callback_call(WIDGET(it), SIG_TITLE_CLICKED, it);
438 _back_btn_clicked(void *data,
440 void *event_info __UNUSED__)
442 /* Since edje has the event queue, clicked event could be happend multiple times
443 on some heavy environment. This callback del will prevent those scenario and
444 guarantee only one clicked for it's own page. */
445 evas_object_smart_callback_del(obj, "clicked", _back_btn_clicked);
446 elm_naviframe_item_pop(data);
450 _back_btn_new(Evas_Object *obj)
454 btn = elm_button_add(obj);
455 if (!btn) return NULL;
456 evas_object_smart_callback_add(btn, "clicked", _back_btn_clicked, obj);
457 snprintf(buf, sizeof(buf), "naviframe/back_btn/%s",
458 elm_widget_style_get(obj));
459 elm_object_style_set(btn, buf);
463 static void _text_set_hook(Evas_Object *obj,
467 Elm_Object_Item *it = elm_naviframe_top_item_get(obj);
469 elm_object_item_part_text_set(it, part, label);
472 static const char *_text_get_hook(const Evas_Object *obj, const char *part)
474 Elm_Object_Item *it = elm_naviframe_top_item_get(obj);
475 if (!it) return NULL;
476 return elm_object_item_part_text_get(it, part);
480 _content_set_hook(Evas_Object *obj, const char *part, Evas_Object *content)
482 Elm_Object_Item *it = elm_naviframe_top_item_get(obj);
484 elm_object_item_part_content_set(it, part, content);
488 _content_unset_hook(Evas_Object *obj, const char *part)
490 Elm_Object_Item *it = elm_naviframe_top_item_get(obj);
491 if (!it) return NULL;
492 return elm_object_item_part_content_unset(it, part);
496 _content_get_hook(const Evas_Object *obj, const char *part)
498 Elm_Object_Item *it = elm_naviframe_top_item_get(obj);
499 if (!it) return NULL;
500 return elm_object_item_part_content_get(it, part);
504 _title_content_del(void *data,
506 Evas_Object *obj __UNUSED__,
507 void *event_info __UNUSED__)
510 Elm_Naviframe_Content_Item_Pair *pair = data;
511 Elm_Naviframe_Item *it = pair->it;
512 snprintf(buf, sizeof(buf), "elm,state,%s,hide", pair->part);
513 elm_object_signal_emit(VIEW(it), buf, "elm");
514 it->content_list = eina_inlist_remove(it->content_list,
515 EINA_INLIST_GET(pair));
516 eina_stringshare_del(pair->part);
521 _title_prev_btn_del(void *data,
523 Evas_Object *obj __UNUSED__,
524 void *event_info __UNUSED__)
526 Elm_Naviframe_Item *it = data;
527 it->back_btn = EINA_FALSE;
528 it->title_prev_btn = NULL;
529 elm_object_signal_emit(VIEW(it), "elm,state,prev_btn,hide", "elm");
533 _title_next_btn_del(void *data,
535 Evas_Object *obj __UNUSED__,
536 void *event_info __UNUSED__)
538 Elm_Naviframe_Item *it = data;
539 it->title_next_btn = NULL;
540 elm_object_signal_emit(VIEW(it), "elm,state,next_btn,hide", "elm");
544 _title_icon_del(void *data,
546 Evas_Object *obj __UNUSED__,
547 void *event_info __UNUSED__)
549 Elm_Naviframe_Item *it = data;
550 it->title_icon = NULL;
551 elm_object_signal_emit(VIEW(it), "elm,state,icon,hide", "elm");
555 _item_content_del(void *data,
557 Evas_Object *obj __UNUSED__,
558 void *event_info __UNUSED__)
560 Elm_Naviframe_Item *it = data;
562 elm_object_signal_emit(VIEW(it), "elm,state,content,hide", "elm");
566 _title_content_set(Elm_Naviframe_Item *it,
568 Evas_Object *content)
571 Elm_Naviframe_Content_Item_Pair *pair = NULL;
572 Evas_Object *prev_content = NULL;
574 EINA_INLIST_FOREACH(it->content_list, pair)
575 if (!strcmp(part, pair->part)) break;
579 prev_content = elm_object_part_content_get(VIEW(it), part);
580 if (prev_content != content)
584 evas_object_event_callback_del(prev_content,
587 snprintf(buf, sizeof(buf), "elm,state,%s,hide", part);
588 elm_object_signal_emit(VIEW(it), buf, "elm");
590 evas_object_del(prev_content);
591 if (!content) return;
596 if (!content) return;
597 pair = ELM_NEW(Elm_Naviframe_Content_Item_Pair);
600 ERR("Failed to allocate new content part of the item! : naviframe=%p", WIDGET(it));
604 eina_stringshare_replace(&pair->part, part);
605 it->content_list = eina_inlist_append(it->content_list,
606 EINA_INLIST_GET(pair));
608 if (prev_content != content)
610 evas_object_event_callback_add(content,
615 elm_object_part_content_set(VIEW(it), part, content);
616 snprintf(buf, sizeof(buf), "elm,state,%s,show", part);
617 elm_object_signal_emit(VIEW(it), buf, "elm");
619 _sizing_eval(WIDGET(it));
623 _title_prev_btn_set(Elm_Naviframe_Item *it,
627 if (it->title_prev_btn == btn) return;
628 if (it->title_prev_btn) evas_object_del(it->title_prev_btn);
629 it->title_prev_btn = btn;
632 evas_object_event_callback_add(btn,
636 elm_object_part_content_set(VIEW(it), "elm.swallow.prev_btn", btn);
637 elm_object_signal_emit(VIEW(it), "elm,state,prev_btn,show", "elm");
638 it->back_btn = back_btn;
640 _sizing_eval(WIDGET(it));
644 _title_next_btn_set(Elm_Naviframe_Item *it, Evas_Object *btn)
646 if (it->title_next_btn == btn) return;
647 if (it->title_next_btn) evas_object_del(it->title_next_btn);
648 it->title_next_btn = btn;
651 evas_object_event_callback_add(btn,
655 elm_object_part_content_set(VIEW(it), "elm.swallow.next_btn", btn);
656 elm_object_signal_emit(VIEW(it), "elm,state,next_btn,show", "elm");
658 _sizing_eval(WIDGET(it));
662 _title_icon_set(Elm_Naviframe_Item *it, Evas_Object *icon)
664 if (it->title_icon == icon) return;
665 if (it->title_icon) evas_object_del(it->title_icon);
666 it->title_icon = icon;
669 evas_object_event_callback_add(icon,
673 elm_object_part_content_set(VIEW(it), "elm.swallow.icon", icon);
674 elm_object_signal_emit(VIEW(it), "elm,state,icon,show", "elm");
676 _sizing_eval(WIDGET(it));
680 _item_content_unset(Elm_Naviframe_Item *it)
682 Evas_Object *content = it->content;
683 if (!content) return NULL;
685 elm_object_part_content_unset(VIEW(it), "elm.swallow.content");
686 elm_object_signal_emit(VIEW(it), "elm,state,content,hide", "elm");
687 evas_object_event_callback_del(content,
690 _sizing_eval(WIDGET(it));
697 _title_prev_btn_unset(Elm_Naviframe_Item *it)
699 Evas_Object *content = it->title_prev_btn;
700 if (!content) return NULL;
702 elm_object_part_content_unset(VIEW(it), "elm.swallow.prev_btn");
703 elm_object_signal_emit(VIEW(it), "elm,state,prev_btn,hide", "elm");
704 evas_object_event_callback_del(content,
706 _title_prev_btn_del);
707 _sizing_eval(WIDGET(it));
709 it->title_prev_btn = NULL;
714 _title_next_btn_unset(Elm_Naviframe_Item *it)
716 Evas_Object *content = it->title_next_btn;
717 if (!content) return NULL;
719 elm_object_part_content_unset(VIEW(it), "elm.swallow.next_btn");
720 elm_object_signal_emit(VIEW(it), "elm,state,next_btn,hide", "elm");
721 evas_object_event_callback_del(content,
723 _title_next_btn_del);
724 _sizing_eval(WIDGET(it));
726 it->title_next_btn = NULL;
731 _title_icon_unset(Elm_Naviframe_Item *it)
733 Evas_Object *content = it->title_icon;
734 if (!content) return NULL;
736 elm_object_part_content_unset(VIEW(it), "elm.swallow.icon");
737 elm_object_signal_emit(VIEW(it), "elm,state,icon,hide", "elm");
738 evas_object_event_callback_del(content,
741 _sizing_eval(WIDGET(it));
742 it->title_icon = NULL;
748 _title_content_unset(Elm_Naviframe_Item *it, const char *part)
750 Elm_Naviframe_Content_Item_Pair *pair = NULL;
752 Evas_Object *content = NULL;
754 EINA_INLIST_FOREACH(it->content_list, pair)
756 if (!strcmp(part, pair->part))
758 content = elm_object_part_content_get(VIEW(it), part);
759 eina_stringshare_del(pair->part);
760 it->content_list = eina_inlist_remove(it->content_list,
761 EINA_INLIST_GET(pair));
767 if (!content) return NULL;
769 elm_object_part_content_unset(VIEW(it), part);
770 snprintf(buf, sizeof(buf), "elm,state,%s,hide", part);
771 elm_object_signal_emit(VIEW(it), buf, "elm");
772 evas_object_event_callback_del(content,
775 _sizing_eval(WIDGET(it));
781 _item_del(Elm_Naviframe_Item *it)
784 Elm_Naviframe_Content_Item_Pair *content_pair;
785 Elm_Naviframe_Text_Item_Pair *text_pair;
786 Evas_Object *content;
790 wd = elm_widget_data_get(WIDGET(it));
793 while (it->content_list)
796 EINA_INLIST_CONTAINER_GET(it->content_list,
797 Elm_Naviframe_Content_Item_Pair);
798 content = elm_object_part_content_get(VIEW(it), content_pair->part);
799 evas_object_event_callback_del(content,
802 eina_stringshare_del(content_pair->part);
803 it->content_list = eina_inlist_remove(it->content_list,
808 while (it->text_list)
810 text_pair = EINA_INLIST_CONTAINER_GET(it->text_list,
811 Elm_Naviframe_Text_Item_Pair);
812 eina_stringshare_del(text_pair->part);
813 it->text_list = eina_inlist_remove(it->text_list,
818 eina_stringshare_del(it->style);
820 if (wd->preserve && it->content)
822 elm_object_part_content_unset(VIEW(it), "elm.swallow.content");
823 evas_object_event_callback_del(it->content,
830 _item_del_pre_hook(Elm_Object_Item *it)
832 Elm_Naviframe_Item *navi_it;
835 navi_it =(Elm_Naviframe_Item *)it;
836 wd = elm_widget_data_get(WIDGET(navi_it));
837 if (!wd) return EINA_FALSE;
839 if (it == elm_naviframe_top_item_get(WIDGET(navi_it)))
841 wd->stack = eina_inlist_remove(wd->stack, EINA_INLIST_GET(navi_it));
843 //If the item is only one, the stack will be empty
844 if (!wd->stack) return EINA_TRUE;
845 navi_it = EINA_INLIST_CONTAINER_GET(wd->stack->last,
847 evas_object_show(VIEW(navi_it));
848 evas_object_raise(VIEW(navi_it));
849 elm_object_signal_emit(VIEW(navi_it), "elm,state,visible", "elm");
853 wd->stack = eina_inlist_remove(wd->stack, EINA_INLIST_GET(navi_it));
861 _pushed_finished(void *data,
862 Evas_Object *obj __UNUSED__,
863 const char *emission __UNUSED__,
864 const char *source __UNUSED__)
867 Elm_Naviframe_Item *it = data;
870 wd = elm_widget_data_get(WIDGET(it));
873 evas_object_hide(VIEW(it));
876 elm_widget_tree_unfocusable_set(it->content, it->content_unfocusable);
878 if (wd->freeze_events)
879 evas_object_freeze_events_set(VIEW(it), EINA_FALSE);
883 _popped_finished(void *data,
884 Evas_Object *obj __UNUSED__,
885 const char *emission __UNUSED__,
886 const char *source __UNUSED__)
889 Elm_Naviframe_Item *it = data;
892 wd = elm_widget_data_get(WIDGET(it));
895 if (wd->preserve && it->content)
896 elm_widget_tree_unfocusable_set(it->content, it->content_unfocusable);
900 elm_widget_item_free(data);
904 _show_finished(void *data,
905 Evas_Object *obj __UNUSED__,
906 const char *emission __UNUSED__,
907 const char *source __UNUSED__)
909 Elm_Naviframe_Item *it;
914 wd = elm_widget_data_get(WIDGET(it));
917 elm_widget_tree_unfocusable_set(it->content, it->content_unfocusable);
919 evas_object_smart_callback_call(WIDGET(it),
920 SIG_TRANSITION_FINISHED,
922 if (wd->freeze_events)
923 evas_object_freeze_events_set(VIEW(it), EINA_FALSE);
927 _changed_size_hints(void *data,
929 Evas_Object *obj __UNUSED__,
930 void *event_info __UNUSED__)
936 _item_content_set(Elm_Naviframe_Item *navi_it, Evas_Object *content)
938 if (navi_it->content == content) return;
939 if (navi_it->content) evas_object_del(navi_it->content);
940 elm_object_part_content_set(VIEW(navi_it), "elm.swallow.content", content);
943 elm_object_signal_emit(VIEW(navi_it), "elm,state,content,show", "elm");
945 elm_object_signal_emit(VIEW(navi_it), "elm,state,content,hide", "elm");
947 evas_object_event_callback_add(content,
951 navi_it->content = content;
952 _sizing_eval(WIDGET(navi_it));
955 //FIXME: need to handle if this function is called while transition
957 _item_style_set(Elm_Naviframe_Item *navi_it, const char *item_style)
959 Elm_Naviframe_Content_Item_Pair *content_pair;
960 Elm_Naviframe_Text_Item_Pair *text_pair;
967 strcpy(buf, "item/basic");
968 eina_stringshare_replace(&navi_it->style, "basic");
972 snprintf(buf, sizeof(buf), "item/%s", item_style);
973 eina_stringshare_replace(&navi_it->style, item_style);
975 elm_layout_theme_set(VIEW(navi_it),
978 elm_widget_style_get(WIDGET(navi_it)));
980 EINA_INLIST_FOREACH(navi_it->text_list, text_pair)
981 _item_text_set_hook((Elm_Object_Item *) navi_it,
983 elm_object_part_text_get(VIEW(navi_it),
986 EINA_INLIST_FOREACH(navi_it->content_list, content_pair)
987 _item_content_set_hook((Elm_Object_Item *) navi_it,
989 elm_object_part_content_get(VIEW(navi_it),
990 content_pair->part));
992 if (navi_it->content)
993 elm_object_signal_emit(VIEW(navi_it), "elm,state,content,show", "elm");
996 if (navi_it->title_prev_btn)
997 elm_object_signal_emit(VIEW(navi_it), "elm,state,prev_btn,show", "elm");
1000 if (navi_it->title_next_btn)
1001 elm_object_signal_emit(VIEW(navi_it), "elm,state,next_btn,show", "elm");
1003 _sizing_eval(WIDGET(navi_it));
1005 wd = elm_widget_data_get(WIDGET(navi_it));
1008 if (wd->freeze_events)
1009 evas_object_freeze_events_set(VIEW(navi_it), EINA_FALSE);
1012 static Elm_Naviframe_Item *
1013 _item_new(Evas_Object *obj,
1014 const char *title_label,
1015 Evas_Object *prev_btn,
1016 Evas_Object *next_btn,
1017 Evas_Object *content,
1018 const char *item_style)
1020 Widget_Data *wd = elm_widget_data_get(obj);
1023 Elm_Naviframe_Item *it = elm_widget_item_new(obj, Elm_Naviframe_Item);
1026 ERR("Failed to allocate new item! : naviframe=%p", obj);
1030 elm_widget_item_del_pre_hook_set(it, _item_del_pre_hook);
1031 elm_widget_item_text_set_hook_set(it, _item_text_set_hook);
1032 elm_widget_item_text_get_hook_set(it, _item_text_get_hook);
1033 elm_widget_item_content_set_hook_set(it, _item_content_set_hook);
1034 elm_widget_item_content_get_hook_set(it, _item_content_get_hook);
1035 elm_widget_item_content_unset_hook_set(it, _item_content_unset_hook);
1036 elm_widget_item_signal_emit_hook_set(it, _item_signal_emit_hook);
1039 VIEW(it) = elm_layout_add(obj);
1040 evas_object_smart_member_add(VIEW(it), obj);
1042 evas_object_event_callback_add(VIEW(it),
1043 EVAS_CALLBACK_CHANGED_SIZE_HINTS,
1044 _changed_size_hints,
1046 elm_object_signal_callback_add(VIEW(it),
1047 "elm,action,show,finished",
1049 _show_finished, it);
1050 elm_object_signal_callback_add(VIEW(it),
1051 "elm,action,pushed,finished",
1053 _pushed_finished, it);
1054 elm_object_signal_callback_add(VIEW(it),
1055 "elm,action,popped,finished",
1057 _popped_finished, it);
1058 elm_object_signal_callback_add(VIEW(it),
1059 "elm,action,title,clicked",
1061 _title_clicked, it);
1063 _item_style_set(it, item_style);
1064 _item_text_set_hook((Elm_Object_Item *)it, "elm.text.title", title_label);
1067 if ((!prev_btn) && wd->auto_pushed && eina_inlist_count(wd->stack))
1069 prev_btn = _back_btn_new(obj);
1070 _title_prev_btn_set(it, prev_btn, EINA_TRUE);
1073 _title_prev_btn_set(it, prev_btn, EINA_FALSE);
1075 _title_next_btn_set(it, next_btn);
1076 _item_content_set(it, content);
1077 it->title_visible = EINA_TRUE;
1082 _focus_next_hook(const Evas_Object *obj, Elm_Focus_Direction dir, Evas_Object **next)
1085 Elm_Naviframe_Item *top_it;
1086 Eina_List *l = NULL;
1087 Widget_Data *wd = elm_widget_data_get(obj);
1088 void *(*list_data_get)(const Eina_List *list);
1089 if (!wd) return EINA_FALSE;
1091 top_it = (Elm_Naviframe_Item *)elm_naviframe_top_item_get(obj);
1092 if (!top_it) return EINA_FALSE;
1094 list_data_get = eina_list_data_get;
1096 //Forcus order: prev button, next button, contents
1097 if (top_it->title_prev_btn)
1098 l = eina_list_append(l, top_it->title_prev_btn);
1099 if (top_it->title_next_btn)
1100 l = eina_list_append(l, top_it->title_next_btn);
1101 l = eina_list_append(l, VIEW(top_it));
1103 ret = elm_widget_focus_list_next_get(obj, l, list_data_get, dir, next);
1109 elm_naviframe_add(Evas_Object *parent)
1115 ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL);
1116 ELM_SET_WIDTYPE(widtype, "naviframe");
1117 elm_widget_type_set(obj, "naviframe");
1118 elm_widget_sub_object_add(parent, obj);
1119 elm_widget_data_set(obj, wd);
1120 elm_widget_del_hook_set(obj, _del_hook);
1121 elm_widget_disable_hook_set(obj, _disable_hook);
1122 elm_widget_theme_hook_set(obj, _theme_hook);
1123 elm_widget_text_set_hook_set(obj, _text_set_hook);
1124 elm_widget_text_get_hook_set(obj, _text_get_hook);
1125 elm_widget_content_set_hook_set(obj, _content_set_hook);
1126 elm_widget_content_get_hook_set(obj, _content_get_hook);
1127 elm_widget_content_unset_hook_set(obj, _content_unset_hook);
1128 elm_widget_signal_emit_hook_set(obj, _emit_hook);
1129 elm_widget_can_focus_set(obj, EINA_FALSE);
1130 elm_widget_focus_next_hook_set(obj, _focus_next_hook);
1133 //FIXME: Is this base layout really needed?
1134 wd->base = elm_layout_add(obj);
1135 evas_object_event_callback_add(wd->base,
1136 EVAS_CALLBACK_CHANGED_SIZE_HINTS,
1137 _changed_size_hints,
1139 elm_widget_resize_object_set(obj, wd->base);
1140 elm_layout_theme_set(wd->base, "naviframe", "base", "default");
1142 evas_object_event_callback_add(obj, EVAS_CALLBACK_MOVE, _move, obj);
1143 evas_object_event_callback_add(obj, EVAS_CALLBACK_RESIZE, _resize, obj);
1144 evas_object_smart_callbacks_descriptions_set(obj, _signals);
1146 wd->auto_pushed = EINA_TRUE;
1147 wd->freeze_events = EINA_TRUE;
1152 EAPI Elm_Object_Item *
1153 elm_naviframe_item_push(Evas_Object *obj,
1154 const char *title_label,
1155 Evas_Object *prev_btn,
1156 Evas_Object *next_btn,
1157 Evas_Object *content,
1158 const char *item_style)
1160 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1162 Elm_Naviframe_Item *prev_it, *it;
1164 wd = elm_widget_data_get(obj);
1165 if (!wd) return NULL;
1167 it = _item_new(obj, title_label, prev_btn, next_btn, content, item_style);
1168 if (!it) return NULL;
1170 evas_object_show(VIEW(it));
1172 prev_it = (Elm_Naviframe_Item *) elm_naviframe_top_item_get(obj);
1175 if (wd->freeze_events)
1177 evas_object_freeze_events_set(VIEW(it), EINA_TRUE);
1178 evas_object_freeze_events_set(VIEW(prev_it), EINA_TRUE);
1180 elm_object_signal_emit(VIEW(prev_it), "elm,state,cur,pushed", "elm");
1181 elm_object_signal_emit(VIEW(it), "elm,state,new,pushed", "elm");
1182 edje_object_message_signal_process(elm_layout_edje_get(VIEW(prev_it)));
1183 if (prev_it->content)
1185 prev_it->content_unfocusable = elm_widget_tree_unfocusable_get(prev_it->content);
1186 elm_widget_tree_unfocusable_set(prev_it->content, EINA_TRUE);
1188 edje_object_message_signal_process(elm_layout_edje_get(VIEW(it)));
1190 wd->stack = eina_inlist_append(wd->stack, EINA_INLIST_GET(it));
1192 return (Elm_Object_Item *)it;
1195 EAPI Elm_Object_Item *
1196 elm_naviframe_item_insert_before(Evas_Object *obj,
1197 Elm_Object_Item *before,
1198 const char *title_label,
1199 Evas_Object *prev_btn,
1200 Evas_Object *next_btn,
1201 Evas_Object *content,
1202 const char *item_style)
1204 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1205 ELM_OBJ_ITEM_CHECK_OR_RETURN(before, NULL);
1206 Elm_Naviframe_Item *it;
1209 wd = elm_widget_data_get(obj);
1210 if (!wd) return NULL;
1212 it = _item_new(obj, title_label, prev_btn, next_btn, content, item_style);
1213 if (!it) return NULL;
1216 eina_inlist_prepend_relative(wd->stack,
1217 EINA_INLIST_GET(it),
1218 EINA_INLIST_GET(((Elm_Naviframe_Item *) before)));
1220 return (Elm_Object_Item *)it;
1223 EAPI Elm_Object_Item *
1224 elm_naviframe_item_insert_after(Evas_Object *obj,
1225 Elm_Object_Item *after,
1226 const char *title_label,
1227 Evas_Object *prev_btn,
1228 Evas_Object *next_btn,
1229 Evas_Object *content,
1230 const char *item_style)
1232 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1233 ELM_OBJ_ITEM_CHECK_OR_RETURN(after, NULL);
1234 Elm_Naviframe_Item *it;
1236 Eina_Bool top_inserted;
1238 wd = elm_widget_data_get(obj);
1239 if (!wd) return NULL;
1241 it = _item_new(obj, title_label, prev_btn, next_btn, content, item_style);
1242 if (!it) return NULL;
1244 if (elm_naviframe_top_item_get(obj) == after) top_inserted = EINA_TRUE;
1247 eina_inlist_append_relative(wd->stack,
1248 EINA_INLIST_GET(it),
1249 EINA_INLIST_GET(((Elm_Naviframe_Item *) after)));
1252 evas_object_show(VIEW(it));
1253 evas_object_hide(VIEW(after));
1258 return (Elm_Object_Item *)it;
1262 elm_naviframe_item_pop(Evas_Object *obj)
1264 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1265 Elm_Naviframe_Item *it, *prev_it = NULL;
1267 Evas_Object *content = NULL;
1269 wd = elm_widget_data_get(obj);
1270 if (!wd) return NULL;
1272 it = (Elm_Naviframe_Item *) elm_naviframe_top_item_get(obj);
1273 if (!it) return NULL;
1275 content = it->content;
1279 it->content_unfocusable = elm_widget_tree_unfocusable_get(it->content);
1280 elm_widget_tree_unfocusable_set(it->content, EINA_TRUE);
1283 if (wd->stack->last->prev)
1284 prev_it = EINA_INLIST_CONTAINER_GET(wd->stack->last->prev,
1285 Elm_Naviframe_Item);
1286 wd->stack = eina_inlist_remove(wd->stack, EINA_INLIST_GET(it));
1289 if (wd->freeze_events)
1291 evas_object_freeze_events_set(VIEW(it), EINA_TRUE);
1292 evas_object_freeze_events_set(VIEW(prev_it), EINA_TRUE);
1294 elm_object_signal_emit(VIEW(it), "elm,state,cur,popped", "elm");
1295 evas_object_show(VIEW(prev_it));
1296 elm_object_signal_emit(VIEW(prev_it),
1297 "elm,state,prev,popped",
1299 edje_object_message_signal_process(elm_layout_edje_get(VIEW(it)));
1300 edje_object_message_signal_process(elm_layout_edje_get(VIEW(prev_it)));
1305 elm_widget_item_free(it);
1312 elm_naviframe_item_pop_to(Elm_Object_Item *it)
1314 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1315 Elm_Naviframe_Item *navi_it;
1317 Eina_Inlist *l, *prev_l;
1319 navi_it = (Elm_Naviframe_Item *)it;
1320 wd = elm_widget_data_get(WIDGET(navi_it));
1323 if (it == elm_naviframe_top_item_get(WIDGET(navi_it))) return;
1325 l = wd->stack->last->prev;
1329 if (EINA_INLIST_CONTAINER_GET(l, Elm_Naviframe_Item) ==
1330 ((Elm_Naviframe_Item *)it)) break;
1332 wd->stack = eina_inlist_remove(wd->stack, l);
1333 _item_del(EINA_INLIST_CONTAINER_GET(l, Elm_Naviframe_Item));
1334 elm_widget_item_free(EINA_INLIST_CONTAINER_GET(l,
1335 Elm_Naviframe_Item));
1338 elm_naviframe_item_pop(WIDGET(navi_it));
1342 elm_naviframe_item_promote(Elm_Object_Item *it)
1344 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1345 Elm_Naviframe_Item *navi_it;
1346 Elm_Naviframe_Item *prev_it;
1349 navi_it = (Elm_Naviframe_Item *)it;
1350 wd = elm_widget_data_get(navi_it->base.widget);
1353 if (it == elm_naviframe_top_item_get(navi_it->base.widget)) return;
1354 wd->stack = eina_inlist_demote(wd->stack, EINA_INLIST_GET(navi_it));
1355 prev_it = EINA_INLIST_CONTAINER_GET(wd->stack->last->prev,
1356 Elm_Naviframe_Item);
1357 if (prev_it->content)
1359 prev_it->content_unfocusable = elm_widget_tree_unfocusable_get(prev_it->content);
1360 elm_widget_tree_unfocusable_set(prev_it->content, EINA_TRUE);
1363 if (wd->freeze_events)
1365 evas_object_freeze_events_set(VIEW(it), EINA_TRUE);
1366 evas_object_freeze_events_set(VIEW(prev_it), EINA_TRUE);
1368 elm_object_signal_emit(VIEW(prev_it),
1369 "elm,state,cur,pushed",
1371 evas_object_show(VIEW(navi_it));
1372 evas_object_raise(VIEW(navi_it));
1373 elm_object_signal_emit(VIEW(navi_it),
1374 "elm,state,new,pushed",
1376 edje_object_message_signal_process(elm_layout_edje_get(VIEW(prev_it)));
1377 edje_object_message_signal_process(elm_layout_edje_get(VIEW(navi_it)));
1381 elm_naviframe_item_simple_promote(Evas_Object *obj, Evas_Object *content)
1383 ELM_CHECK_WIDTYPE(obj, widtype);
1384 Widget_Data *wd = elm_widget_data_get(obj);
1386 Elm_Naviframe_Item *itr;
1387 EINA_INLIST_FOREACH(wd->stack, itr)
1389 if (elm_object_item_content_get((Elm_Object_Item *)itr) == content)
1391 elm_naviframe_item_promote((Elm_Object_Item *)itr);
1399 elm_naviframe_content_preserve_on_pop_set(Evas_Object *obj, Eina_Bool preserve)
1401 ELM_CHECK_WIDTYPE(obj, widtype);
1402 Widget_Data *wd = elm_widget_data_get(obj);
1404 wd->preserve = !!preserve;
1408 elm_naviframe_content_preserve_on_pop_get(const Evas_Object *obj)
1410 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
1411 Widget_Data *wd = elm_widget_data_get(obj);
1412 if (!wd) return EINA_FALSE;
1413 return wd->preserve;
1416 EAPI Elm_Object_Item*
1417 elm_naviframe_top_item_get(const Evas_Object *obj)
1419 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1420 Widget_Data *wd = elm_widget_data_get(obj);
1421 if ((!wd) || (!wd->stack)) return NULL;
1422 return (Elm_Object_Item *) (EINA_INLIST_CONTAINER_GET(wd->stack->last,
1423 Elm_Naviframe_Item));
1426 EAPI Elm_Object_Item*
1427 elm_naviframe_bottom_item_get(const Evas_Object *obj)
1429 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1430 Widget_Data *wd = elm_widget_data_get(obj);
1431 if ((!wd) || (!wd->stack)) return NULL;
1432 return (Elm_Object_Item *) (EINA_INLIST_CONTAINER_GET(wd->stack,
1433 Elm_Naviframe_Item));
1437 elm_naviframe_item_style_set(Elm_Object_Item *it, const char *item_style)
1439 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1440 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *)it;
1443 if (!strcmp(item_style, navi_it->style)) return;
1446 if (!strcmp("basic", navi_it->style)) return;
1448 _item_style_set(navi_it, item_style);
1449 _item_title_visible_update(navi_it);
1453 elm_naviframe_item_style_get(const Elm_Object_Item *it)
1455 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
1456 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *)it;
1457 return navi_it->style;
1461 elm_naviframe_item_title_visible_set(Elm_Object_Item *it, Eina_Bool visible)
1463 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1464 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *)it;
1466 visible = !!visible;
1467 if (navi_it->title_visible == visible) return;
1469 navi_it->title_visible = visible;
1470 _item_title_visible_update(navi_it);
1474 elm_naviframe_item_title_visible_get(const Elm_Object_Item *it)
1476 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
1477 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *)it;
1478 return navi_it->title_visible;
1482 elm_naviframe_prev_btn_auto_pushed_set(Evas_Object *obj, Eina_Bool auto_pushed)
1484 ELM_CHECK_WIDTYPE(obj, widtype);
1485 Widget_Data *wd = elm_widget_data_get(obj);
1487 wd->auto_pushed = !!auto_pushed;
1491 elm_naviframe_prev_btn_auto_pushed_get(const Evas_Object *obj)
1493 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
1494 Widget_Data *wd = elm_widget_data_get(obj);
1495 if (!wd) return EINA_FALSE;
1496 return wd->auto_pushed;
1500 elm_naviframe_items_get(const Evas_Object *obj)
1502 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1503 Widget_Data *wd = elm_widget_data_get(obj);
1504 if (!wd) return NULL;
1505 Eina_List *ret = NULL;
1506 Elm_Naviframe_Item *itr;
1507 EINA_INLIST_FOREACH(wd->stack, itr)
1508 ret = eina_list_append(ret, itr);
1513 elm_naviframe_event_enabled_set(Evas_Object *obj, Eina_Bool enabled)
1515 ELM_CHECK_WIDTYPE(obj, widtype);
1516 Widget_Data *wd = elm_widget_data_get(obj);
1518 enabled = !!enabled;
1519 if (wd->freeze_events == !enabled) return;
1520 wd->freeze_events = !enabled;
1524 elm_naviframe_event_enabled_get(const Evas_Object *obj)
1526 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
1527 Widget_Data *wd = elm_widget_data_get(obj);
1528 if (!wd) return EINA_FALSE;
1529 return !wd->freeze_events;