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;
51 static const char SIG_TRANSITION_FINISHED[] = "transition,finished";
52 static const char SIG_TITLE_CLICKED[] = "title,clicked";
54 static const Evas_Smart_Cb_Description _signals[] = {
55 {SIG_TRANSITION_FINISHED, ""},
56 {SIG_TITLE_CLICKED, ""},
60 static void _text_set_hook(Evas_Object *obj,
63 static const char *_text_get_hook(const Evas_Object *obj, const char *part);
64 static void _content_set_hook(Evas_Object *obj,
66 Evas_Object *content);
67 static Evas_Object *_content_get_hook(const Evas_Object *obj, const char *part);
68 static Evas_Object *_content_unset_hook(Evas_Object *obj, const char *part);
69 static void _del_hook(Evas_Object *obj);
70 static void _theme_hook(Evas_Object *obj);
71 static void _emit_hook(Evas_Object *obj,
74 static void _disable_hook(Evas_Object *obj);
75 static void _item_text_set_hook(Elm_Object_Item *it,
78 static const char *_item_text_get_hook(const Elm_Object_Item *it,
80 static void _item_content_set_hook(Elm_Object_Item *it,
82 Evas_Object *content);
83 static Evas_Object *_item_content_get_hook(const Elm_Object_Item *it,
85 static Evas_Object *_item_content_unset_hook(Elm_Object_Item *it,
87 static void _item_signal_emit_hook(Elm_Object_Item *it,
90 static void _item_title_visible_update(Elm_Naviframe_Item *navi_it);
91 static void _sizing_eval(Evas_Object *obj);
92 static void _move(void *data, Evas *e, Evas_Object *obj, void *event_info);
93 static void _resize(void *data,
97 static void _title_clicked(void *data, Evas_Object *obj,
100 static void _back_btn_clicked(void *data,
103 static Evas_Object *_back_btn_new(Evas_Object *obj);
104 static void _item_content_del(void *data,
108 static void _title_content_del(void *data,
112 static void _title_prev_btn_del(void *data,
116 static void _title_next_btn_del(void *data,
120 static void _title_icon_del(void *data,
124 static void _title_content_set(Elm_Naviframe_Item *it,
126 Evas_Object *content);
127 static void _title_prev_btn_set(Elm_Naviframe_Item *it,
130 static void _title_next_btn_set(Elm_Naviframe_Item *it, Evas_Object *btn);
131 static void _title_icon_set(Elm_Naviframe_Item *it, Evas_Object *icon);
132 static Evas_Object * _item_content_unset(Elm_Naviframe_Item *it);
133 static Evas_Object * _title_prev_btn_unset(Elm_Naviframe_Item *it);
134 static Evas_Object * _title_next_btn_unset(Elm_Naviframe_Item *it);
135 static Evas_Object * _title_icon_unset(Elm_Naviframe_Item *it);
136 static Evas_Object * _title_content_unset(Elm_Naviframe_Item *it,
138 static void _item_del(Elm_Naviframe_Item *it);
139 static Eina_Bool _item_del_pre_hook(Elm_Object_Item *it);
140 static void _pushed_finished(void *data,
142 const char *emission,
144 static void _popped_finished(void *data,
146 const char *emission,
148 static void _show_finished(void *data,
150 const char *emission,
152 static void _changed_size_hints(void *data,
156 static void _item_content_set(Elm_Naviframe_Item *navi_it,
157 Evas_Object *content);
158 static void _item_style_set(Elm_Naviframe_Item *navi_it,
159 const char *item_style);
160 static Elm_Naviframe_Item * _item_new(Evas_Object *obj,
161 const char *title_label,
162 Evas_Object *prev_btn,
163 Evas_Object *next_btn,
164 Evas_Object *content,
165 const char *item_style);
166 static Eina_Bool _focus_next_hook(const Evas_Object *obj,
167 Elm_Focus_Direction dir,
171 _del_hook(Evas_Object *obj)
174 Elm_Naviframe_Item *it;
176 wd = elm_widget_data_get(obj);
181 while (wd->stack->last)
183 it = EINA_INLIST_CONTAINER_GET(wd->stack->last,
185 wd->stack = eina_inlist_remove(wd->stack, wd->stack->last);
187 elm_widget_item_free(it);
188 if (!wd->stack) break;
195 _theme_hook(Evas_Object *obj)
198 Elm_Naviframe_Item *it;
200 wd = elm_widget_data_get(obj);
203 _elm_theme_object_set(obj,
207 elm_widget_style_get(obj));
209 EINA_INLIST_FOREACH(wd->stack, it)
211 _item_style_set(it, it->style);
212 _item_title_visible_update(it);
216 static void _emit_hook(Evas_Object *obj,
217 const char *emission,
220 Elm_Object_Item *it = elm_naviframe_top_item_get(obj);
222 return elm_object_item_signal_emit(it, emission, source);
226 _disable_hook(Evas_Object *obj __UNUSED__)
232 _item_text_set_hook(Elm_Object_Item *it,
236 Elm_Naviframe_Text_Item_Pair *pair = NULL;
237 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *)it;
240 if (!part || !strcmp(part, "default"))
241 snprintf(buf, sizeof(buf), "elm.text.title");
242 else if(!strcmp("subtitle", part))
243 snprintf(buf, sizeof(buf), "elm.text.subtitle");
245 snprintf(buf, sizeof(buf), "%s", part);
247 EINA_INLIST_FOREACH(navi_it->text_list, pair)
248 if (!strcmp(buf, pair->part)) break;
252 pair = ELM_NEW(Elm_Naviframe_Text_Item_Pair);
255 ERR("Failed to allocate new text part of the item! : naviframe=%p",
259 eina_stringshare_replace(&pair->part, buf);
260 navi_it->text_list = eina_inlist_append(navi_it->text_list,
261 EINA_INLIST_GET(pair));
263 elm_object_part_text_set(VIEW(navi_it), buf, label);
267 snprintf(buf, sizeof(buf), "elm,state,%s,show", buf);
268 elm_object_signal_emit(VIEW(navi_it), buf, "elm");
272 snprintf(buf, sizeof(buf), "elm,state,%s,hide", buf);
273 elm_object_signal_emit(VIEW(navi_it), buf, "elm");
276 _sizing_eval(WIDGET(navi_it));
280 _item_text_get_hook(const Elm_Object_Item *it, const char *part)
284 if (!part || !strcmp(part, "default"))
285 snprintf(buf, sizeof(buf), "elm.text.title");
286 else if(!strcmp("subtitle", part))
287 snprintf(buf, sizeof(buf), "elm.text.subtitle");
289 snprintf(buf, sizeof(buf), "%s", part);
291 return elm_object_part_text_get(VIEW(it), buf);
295 _item_content_set_hook(Elm_Object_Item *it,
297 Evas_Object *content)
299 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *)it;
302 if (!part || !strcmp("default", part))
304 _item_content_set(navi_it, content);
307 else if (!strcmp(part, "prev_btn"))
309 _title_prev_btn_set(navi_it, content, EINA_FALSE);
312 else if (!strcmp(part, "next_btn"))
314 _title_next_btn_set(navi_it, content);
317 else if (!strcmp(part, "icon"))
319 _title_icon_set(navi_it, content);
324 _title_content_set(navi_it, part, content);
328 _item_content_get_hook(const Elm_Object_Item *it, const char *part)
330 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *)it;
333 if (!part || !strcmp("default", part))
334 return navi_it->content;
335 else if (!strcmp(part, "prev_btn"))
336 return navi_it->title_prev_btn;
337 else if (!strcmp(part, "next_btn"))
338 return navi_it->title_next_btn;
339 else if (!strcmp(part, "icon"))
340 return navi_it->title_icon;
343 return elm_object_part_content_get(VIEW(navi_it), part);
347 _item_content_unset_hook(Elm_Object_Item *it, const char *part)
349 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *)it;
352 if (!part || !strcmp("default", part))
353 return _item_content_unset(navi_it);
354 else if (!strcmp(part, "prev_btn"))
355 return _title_prev_btn_unset(navi_it);
356 else if (!strcmp(part, "next_btn"))
357 return _title_next_btn_unset(navi_it);
358 else if (!strcmp(part, "icon"))
359 return _title_icon_unset(navi_it);
361 return _title_content_unset(navi_it, part);
365 _item_signal_emit_hook(Elm_Object_Item *it,
366 const char *emission,
369 elm_object_signal_emit(VIEW(it), emission, source);
373 _item_title_visible_update(Elm_Naviframe_Item *navi_it)
375 if (navi_it->title_visible)
376 elm_object_signal_emit(VIEW(navi_it), "elm,state,title,show", "elm");
378 elm_object_signal_emit(VIEW(navi_it), "elm,state,title,hide", "elm");
382 _sizing_eval(Evas_Object *obj)
385 Elm_Naviframe_Item *it;
386 Evas_Coord x, y, w, h;
387 Evas_Coord minw = -1, minh = -1;
389 wd = elm_widget_data_get(obj);
392 evas_object_geometry_get(obj, &x, &y, &w, &h);
394 EINA_INLIST_FOREACH(wd->stack, it)
396 evas_object_move(VIEW(it), x, y);
397 evas_object_resize(VIEW(it), w, h);
398 edje_object_size_min_calc(elm_layout_edje_get(VIEW(it)),
401 if (it->minw > minw) minw = it->minw;
402 if (it->minh > minh) minh = it->minh;
404 evas_object_size_hint_min_set(obj, minw, minh);
405 evas_object_size_hint_max_set(obj, -1, -1);
409 _move(void *data __UNUSED__,
412 void *event_info __UNUSED__)
418 _resize(void *data __UNUSED__,
421 void *event_info __UNUSED__)
427 _title_clicked(void *data,
428 Evas_Object *obj __UNUSED__,
429 const char *emission __UNUSED__,
430 const char *source __UNUSED__)
432 Elm_Naviframe_Item *it = data;
433 evas_object_smart_callback_call(WIDGET(it), SIG_TITLE_CLICKED, it);
437 _back_btn_clicked(void *data,
439 void *event_info __UNUSED__)
441 /* Since edje has the event queue, clicked event could be happend multiple times
442 on some heavy environment. This callback del will prevent those scenario and
443 guarantee only one clicked for it's own page. */
444 evas_object_smart_callback_del(obj, "clicked", _back_btn_clicked);
445 elm_naviframe_item_pop(data);
449 _back_btn_new(Evas_Object *obj)
453 btn = elm_button_add(obj);
454 if (!btn) return NULL;
455 evas_object_smart_callback_add(btn, "clicked", _back_btn_clicked, obj);
456 snprintf(buf, sizeof(buf), "naviframe/back_btn/%s",
457 elm_widget_style_get(obj));
458 elm_object_style_set(btn, buf);
462 static void _text_set_hook(Evas_Object *obj,
466 Elm_Object_Item *it = elm_naviframe_top_item_get(obj);
468 elm_object_item_part_text_set(it, part, label);
471 static const char *_text_get_hook(const Evas_Object *obj, const char *part)
473 Elm_Object_Item *it = elm_naviframe_top_item_get(obj);
474 if (!it) return NULL;
475 return elm_object_item_part_text_get(it, part);
479 _content_set_hook(Evas_Object *obj, const char *part, Evas_Object *content)
481 Elm_Object_Item *it = elm_naviframe_top_item_get(obj);
483 elm_object_item_part_content_set(it, part, content);
487 _content_unset_hook(Evas_Object *obj, const char *part)
489 Elm_Object_Item *it = elm_naviframe_top_item_get(obj);
490 if (!it) return NULL;
491 return elm_object_item_part_content_unset(it, part);
495 _content_get_hook(const Evas_Object *obj, const char *part)
497 Elm_Object_Item *it = elm_naviframe_top_item_get(obj);
498 if (!it) return NULL;
499 return elm_object_item_part_content_get(it, part);
503 _title_content_del(void *data,
505 Evas_Object *obj __UNUSED__,
506 void *event_info __UNUSED__)
509 Elm_Naviframe_Content_Item_Pair *pair = data;
510 Elm_Naviframe_Item *it = pair->it;
511 snprintf(buf, sizeof(buf), "elm,state,%s,hide", pair->part);
512 elm_object_signal_emit(VIEW(it), buf, "elm");
513 it->content_list = eina_inlist_remove(it->content_list,
514 EINA_INLIST_GET(pair));
515 eina_stringshare_del(pair->part);
520 _title_prev_btn_del(void *data,
522 Evas_Object *obj __UNUSED__,
523 void *event_info __UNUSED__)
525 Elm_Naviframe_Item *it = data;
526 it->back_btn = EINA_FALSE;
527 it->title_prev_btn = NULL;
528 elm_object_signal_emit(VIEW(it), "elm,state,prev_btn,hide", "elm");
532 _title_next_btn_del(void *data,
534 Evas_Object *obj __UNUSED__,
535 void *event_info __UNUSED__)
537 Elm_Naviframe_Item *it = data;
538 it->title_next_btn = NULL;
539 elm_object_signal_emit(VIEW(it), "elm,state,next_btn,hide", "elm");
543 _title_icon_del(void *data,
545 Evas_Object *obj __UNUSED__,
546 void *event_info __UNUSED__)
548 Elm_Naviframe_Item *it = data;
549 it->title_icon = NULL;
550 elm_object_signal_emit(VIEW(it), "elm,state,icon,hide", "elm");
554 _item_content_del(void *data,
556 Evas_Object *obj __UNUSED__,
557 void *event_info __UNUSED__)
559 Elm_Naviframe_Item *it = data;
561 elm_object_signal_emit(VIEW(it), "elm,state,content,hide", "elm");
565 _title_content_set(Elm_Naviframe_Item *it,
567 Evas_Object *content)
570 Elm_Naviframe_Content_Item_Pair *pair = NULL;
571 Evas_Object *prev_content = NULL;
573 EINA_INLIST_FOREACH(it->content_list, pair)
574 if (!strcmp(part, pair->part)) break;
578 prev_content = elm_object_part_content_get(VIEW(it), part);
579 if (prev_content != content)
583 evas_object_event_callback_del(prev_content,
586 snprintf(buf, sizeof(buf), "elm,state,%s,hide", part);
587 elm_object_signal_emit(VIEW(it), buf, "elm");
589 evas_object_del(prev_content);
590 if (!content) return;
595 if (!content) return;
596 pair = ELM_NEW(Elm_Naviframe_Content_Item_Pair);
599 ERR("Failed to allocate new content part of the item! : naviframe=%p", WIDGET(it));
603 eina_stringshare_replace(&pair->part, part);
604 it->content_list = eina_inlist_append(it->content_list,
605 EINA_INLIST_GET(pair));
607 if (prev_content != content)
609 evas_object_event_callback_add(content,
614 elm_object_part_content_set(VIEW(it), part, content);
615 snprintf(buf, sizeof(buf), "elm,state,%s,show", part);
616 elm_object_signal_emit(VIEW(it), buf, "elm");
618 _sizing_eval(WIDGET(it));
622 _title_prev_btn_set(Elm_Naviframe_Item *it,
626 if (it->title_prev_btn == btn) return;
627 if (it->title_prev_btn) evas_object_del(it->title_prev_btn);
628 it->title_prev_btn = btn;
631 evas_object_event_callback_add(btn,
635 elm_object_part_content_set(VIEW(it), "elm.swallow.prev_btn", btn);
636 elm_object_signal_emit(VIEW(it), "elm,state,prev_btn,show", "elm");
637 it->back_btn = back_btn;
639 _sizing_eval(WIDGET(it));
643 _title_next_btn_set(Elm_Naviframe_Item *it, Evas_Object *btn)
645 if (it->title_next_btn == btn) return;
646 if (it->title_next_btn) evas_object_del(it->title_next_btn);
647 it->title_next_btn = btn;
650 evas_object_event_callback_add(btn,
654 elm_object_part_content_set(VIEW(it), "elm.swallow.next_btn", btn);
655 elm_object_signal_emit(VIEW(it), "elm,state,next_btn,show", "elm");
657 _sizing_eval(WIDGET(it));
661 _title_icon_set(Elm_Naviframe_Item *it, Evas_Object *icon)
663 if (it->title_icon == icon) return;
664 if (it->title_icon) evas_object_del(it->title_icon);
665 it->title_icon = icon;
668 evas_object_event_callback_add(icon,
672 elm_object_part_content_set(VIEW(it), "elm.swallow.icon", icon);
673 elm_object_signal_emit(VIEW(it), "elm,state,icon,show", "elm");
675 _sizing_eval(WIDGET(it));
679 _item_content_unset(Elm_Naviframe_Item *it)
681 Evas_Object *content = it->content;
682 if (!content) return NULL;
684 elm_object_part_content_unset(VIEW(it), "elm.swallow.content");
685 elm_object_signal_emit(VIEW(it), "elm,state,content,hide", "elm");
686 evas_object_event_callback_del(content,
689 _sizing_eval(WIDGET(it));
696 _title_prev_btn_unset(Elm_Naviframe_Item *it)
698 Evas_Object *content = it->title_prev_btn;
699 if (!content) return NULL;
701 elm_object_part_content_unset(VIEW(it), "elm.swallow.prev_btn");
702 elm_object_signal_emit(VIEW(it), "elm,state,prev_btn,hide", "elm");
703 evas_object_event_callback_del(content,
705 _title_prev_btn_del);
706 _sizing_eval(WIDGET(it));
708 it->title_prev_btn = NULL;
713 _title_next_btn_unset(Elm_Naviframe_Item *it)
715 Evas_Object *content = it->title_next_btn;
716 if (!content) return NULL;
718 elm_object_part_content_unset(VIEW(it), "elm.swallow.next_btn");
719 elm_object_signal_emit(VIEW(it), "elm,state,next_btn,hide", "elm");
720 evas_object_event_callback_del(content,
722 _title_next_btn_del);
723 _sizing_eval(WIDGET(it));
725 it->title_next_btn = NULL;
730 _title_icon_unset(Elm_Naviframe_Item *it)
732 Evas_Object *content = it->title_icon;
733 if (!content) return NULL;
735 elm_object_part_content_unset(VIEW(it), "elm.swallow.icon");
736 elm_object_signal_emit(VIEW(it), "elm,state,icon,hide", "elm");
737 evas_object_event_callback_del(content,
740 _sizing_eval(WIDGET(it));
741 it->title_icon = NULL;
747 _title_content_unset(Elm_Naviframe_Item *it, const char *part)
749 Elm_Naviframe_Content_Item_Pair *pair = NULL;
751 Evas_Object *content = NULL;
753 EINA_INLIST_FOREACH(it->content_list, pair)
755 if (!strcmp(part, pair->part))
757 content = elm_object_part_content_get(VIEW(it), part);
758 eina_stringshare_del(pair->part);
759 it->content_list = eina_inlist_remove(it->content_list,
760 EINA_INLIST_GET(pair));
766 if (!content) return NULL;
768 elm_object_part_content_unset(VIEW(it), part);
769 snprintf(buf, sizeof(buf), "elm,state,%s,hide", part);
770 elm_object_signal_emit(VIEW(it), buf, "elm");
771 evas_object_event_callback_del(content,
774 _sizing_eval(WIDGET(it));
780 _item_del(Elm_Naviframe_Item *it)
783 Elm_Naviframe_Content_Item_Pair *content_pair;
784 Elm_Naviframe_Text_Item_Pair *text_pair;
785 Evas_Object *content;
789 wd = elm_widget_data_get(WIDGET(it));
792 while (it->content_list)
795 EINA_INLIST_CONTAINER_GET(it->content_list,
796 Elm_Naviframe_Content_Item_Pair);
797 content = elm_object_part_content_get(VIEW(it), content_pair->part);
798 evas_object_event_callback_del(content,
801 eina_stringshare_del(content_pair->part);
802 it->content_list = eina_inlist_remove(it->content_list,
807 while (it->text_list)
809 text_pair = EINA_INLIST_CONTAINER_GET(it->text_list,
810 Elm_Naviframe_Text_Item_Pair);
811 eina_stringshare_del(text_pair->part);
812 it->text_list = eina_inlist_remove(it->text_list,
817 eina_stringshare_del(it->style);
821 _item_del_pre_hook(Elm_Object_Item *it)
823 Elm_Naviframe_Item *navi_it;
826 navi_it =(Elm_Naviframe_Item *)it;
827 wd = elm_widget_data_get(WIDGET(navi_it));
828 if (!wd) return EINA_FALSE;
830 if (it == elm_naviframe_top_item_get(WIDGET(navi_it)))
832 wd->stack = eina_inlist_remove(wd->stack, EINA_INLIST_GET(navi_it));
834 //If the item is only one, the stack will be empty
835 if (!wd->stack) return EINA_TRUE;
836 navi_it = EINA_INLIST_CONTAINER_GET(wd->stack->last,
838 evas_object_show(VIEW(navi_it));
839 evas_object_raise(VIEW(navi_it));
840 elm_object_signal_emit(VIEW(navi_it), "elm,state,visible", "elm");
844 wd->stack = eina_inlist_remove(wd->stack, EINA_INLIST_GET(navi_it));
852 _pushed_finished(void *data,
853 Evas_Object *obj __UNUSED__,
854 const char *emission __UNUSED__,
855 const char *source __UNUSED__)
858 Elm_Naviframe_Item *it = data;
861 wd = elm_widget_data_get(WIDGET(it));
864 evas_object_hide(VIEW(it));
865 if (wd->freeze_events)
866 evas_object_freeze_events_set(VIEW(it), EINA_FALSE);
870 _popped_finished(void *data,
871 Evas_Object *obj __UNUSED__,
872 const char *emission __UNUSED__,
873 const char *source __UNUSED__)
875 Elm_Naviframe_Item *it = data;
878 elm_widget_item_free(data);
882 _show_finished(void *data,
883 Evas_Object *obj __UNUSED__,
884 const char *emission __UNUSED__,
885 const char *source __UNUSED__)
887 Elm_Naviframe_Item *it;
892 wd = elm_widget_data_get(WIDGET(it));
895 evas_object_smart_callback_call(WIDGET(it),
896 SIG_TRANSITION_FINISHED,
898 if (wd->freeze_events)
899 evas_object_freeze_events_set(VIEW(it), EINA_FALSE);
903 _changed_size_hints(void *data,
905 Evas_Object *obj __UNUSED__,
906 void *event_info __UNUSED__)
912 _item_content_set(Elm_Naviframe_Item *navi_it, Evas_Object *content)
914 if (navi_it->content == content) return;
915 if (navi_it->content) evas_object_del(navi_it->content);
916 elm_object_part_content_set(VIEW(navi_it), "elm.swallow.content", content);
919 elm_object_signal_emit(VIEW(navi_it), "elm,state,content,show", "elm");
921 elm_object_signal_emit(VIEW(navi_it), "elm,state,content,hide", "elm");
923 evas_object_event_callback_add(content,
927 navi_it->content = content;
928 _sizing_eval(WIDGET(navi_it));
931 //FIXME: need to handle if this function is called while transition
933 _item_style_set(Elm_Naviframe_Item *navi_it, const char *item_style)
935 Elm_Naviframe_Content_Item_Pair *content_pair;
936 Elm_Naviframe_Text_Item_Pair *text_pair;
943 strcpy(buf, "item/basic");
944 eina_stringshare_replace(&navi_it->style, "basic");
948 snprintf(buf, sizeof(buf), "item/%s", item_style);
949 eina_stringshare_replace(&navi_it->style, item_style);
951 elm_layout_theme_set(VIEW(navi_it),
954 elm_widget_style_get(WIDGET(navi_it)));
956 EINA_INLIST_FOREACH(navi_it->text_list, text_pair)
957 _item_text_set_hook((Elm_Object_Item *) navi_it,
959 elm_object_part_text_get(VIEW(navi_it),
962 EINA_INLIST_FOREACH(navi_it->content_list, content_pair)
963 _item_content_set_hook((Elm_Object_Item *) navi_it,
965 elm_object_part_content_get(VIEW(navi_it),
966 content_pair->part));
968 if (navi_it->content)
969 elm_object_signal_emit(VIEW(navi_it), "elm,state,content,show", "elm");
972 if (navi_it->title_prev_btn)
973 elm_object_signal_emit(VIEW(navi_it), "elm,state,prev_btn,show", "elm");
976 if (navi_it->title_next_btn)
977 elm_object_signal_emit(VIEW(navi_it), "elm,state,next_btn,show", "elm");
979 // why does this forcibly enable title? isnt that separate to style?
980 // navi_it->title_visible = EINA_TRUE;
981 _sizing_eval(WIDGET(navi_it));
983 wd = elm_widget_data_get(WIDGET(navi_it));
986 if (wd->freeze_events)
987 evas_object_freeze_events_set(VIEW(navi_it), EINA_FALSE);
990 static Elm_Naviframe_Item *
991 _item_new(Evas_Object *obj,
992 const char *title_label,
993 Evas_Object *prev_btn,
994 Evas_Object *next_btn,
995 Evas_Object *content,
996 const char *item_style)
998 Widget_Data *wd = elm_widget_data_get(obj);
1001 Elm_Naviframe_Item *it = elm_widget_item_new(obj, Elm_Naviframe_Item);
1004 ERR("Failed to allocate new item! : naviframe=%p", obj);
1008 elm_widget_item_del_pre_hook_set(it, _item_del_pre_hook);
1009 elm_widget_item_text_set_hook_set(it, _item_text_set_hook);
1010 elm_widget_item_text_get_hook_set(it, _item_text_get_hook);
1011 elm_widget_item_content_set_hook_set(it, _item_content_set_hook);
1012 elm_widget_item_content_get_hook_set(it, _item_content_get_hook);
1013 elm_widget_item_content_unset_hook_set(it, _item_content_unset_hook);
1014 elm_widget_item_signal_emit_hook_set(it, _item_signal_emit_hook);
1017 VIEW(it) = elm_layout_add(obj);
1018 evas_object_smart_member_add(VIEW(it), wd->base);
1020 evas_object_event_callback_add(VIEW(it),
1021 EVAS_CALLBACK_CHANGED_SIZE_HINTS,
1022 _changed_size_hints,
1024 elm_object_signal_callback_add(VIEW(it),
1025 "elm,action,show,finished",
1027 _show_finished, it);
1028 elm_object_signal_callback_add(VIEW(it),
1029 "elm,action,pushed,finished",
1031 _pushed_finished, it);
1032 elm_object_signal_callback_add(VIEW(it),
1033 "elm,action,popped,finished",
1035 _popped_finished, it);
1036 elm_object_signal_callback_add(VIEW(it),
1037 "elm,action,title,clicked",
1039 _title_clicked, it);
1041 _item_style_set(it, item_style);
1042 _item_text_set_hook((Elm_Object_Item *)it, "elm.text.title", title_label);
1045 if ((!prev_btn) && wd->auto_pushed && eina_inlist_count(wd->stack))
1047 prev_btn = _back_btn_new(obj);
1048 _title_prev_btn_set(it, prev_btn, EINA_TRUE);
1051 _title_prev_btn_set(it, prev_btn, EINA_FALSE);
1053 _title_next_btn_set(it, next_btn);
1054 _item_content_set(it, content);
1055 it->title_visible = EINA_TRUE;
1060 _focus_next_hook(const Evas_Object *obj, Elm_Focus_Direction dir, Evas_Object **next)
1062 Widget_Data *wd = elm_widget_data_get(obj);
1063 if (!wd || !wd->stack) return EINA_FALSE;
1064 return elm_widget_focus_next_get(VIEW(elm_naviframe_top_item_get(obj)),
1070 elm_naviframe_add(Evas_Object *parent)
1076 ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL);
1077 ELM_SET_WIDTYPE(widtype, "naviframe");
1078 elm_widget_type_set(obj, "naviframe");
1079 elm_widget_sub_object_add(parent, obj);
1080 elm_widget_data_set(obj, wd);
1081 elm_widget_del_hook_set(obj, _del_hook);
1082 elm_widget_disable_hook_set(obj, _disable_hook);
1083 elm_widget_theme_hook_set(obj, _theme_hook);
1084 elm_widget_text_set_hook_set(obj, _text_set_hook);
1085 elm_widget_text_get_hook_set(obj, _text_get_hook);
1086 elm_widget_content_set_hook_set(obj, _content_set_hook);
1087 elm_widget_content_get_hook_set(obj, _content_get_hook);
1088 elm_widget_content_unset_hook_set(obj, _content_unset_hook);
1089 elm_widget_signal_emit_hook_set(obj, _emit_hook);
1090 elm_widget_can_focus_set(obj, EINA_FALSE);
1091 elm_widget_focus_next_hook_set(obj, _focus_next_hook);
1094 //FIXME: Is this base layout really needed?
1095 wd->base = elm_layout_add(parent);
1096 evas_object_event_callback_add(wd->base,
1097 EVAS_CALLBACK_CHANGED_SIZE_HINTS,
1098 _changed_size_hints,
1100 elm_widget_resize_object_set(obj, wd->base);
1101 elm_layout_theme_set(wd->base, "naviframe", "base", "default");
1103 evas_object_event_callback_add(obj, EVAS_CALLBACK_MOVE, _move, obj);
1104 evas_object_event_callback_add(obj, EVAS_CALLBACK_RESIZE, _resize, obj);
1105 evas_object_smart_callbacks_descriptions_set(obj, _signals);
1107 wd->auto_pushed = EINA_TRUE;
1108 wd->freeze_events = EINA_TRUE;
1113 EAPI Elm_Object_Item *
1114 elm_naviframe_item_push(Evas_Object *obj,
1115 const char *title_label,
1116 Evas_Object *prev_btn,
1117 Evas_Object *next_btn,
1118 Evas_Object *content,
1119 const char *item_style)
1121 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1123 Elm_Naviframe_Item *prev_it, *it;
1125 wd = elm_widget_data_get(obj);
1126 if (!wd) return NULL;
1128 it = _item_new(obj, title_label, prev_btn, next_btn, content, item_style);
1129 if (!it) return NULL;
1131 evas_object_show(VIEW(it));
1133 prev_it = (Elm_Naviframe_Item *) elm_naviframe_top_item_get(obj);
1136 if (wd->freeze_events)
1138 evas_object_freeze_events_set(VIEW(it), EINA_TRUE);
1139 evas_object_freeze_events_set(VIEW(prev_it), EINA_TRUE);
1141 elm_object_signal_emit(VIEW(prev_it), "elm,state,cur,pushed", "elm");
1142 elm_object_signal_emit(VIEW(it), "elm,state,new,pushed", "elm");
1143 edje_object_message_signal_process(elm_layout_edje_get(VIEW(prev_it)));
1144 elm_widget_tree_unfocusable_set(it->content, EINA_TRUE);
1145 edje_object_message_signal_process(elm_layout_edje_get(VIEW(it)));
1147 wd->stack = eina_inlist_append(wd->stack, EINA_INLIST_GET(it));
1149 return (Elm_Object_Item *)it;
1152 EAPI Elm_Object_Item *
1153 elm_naviframe_item_insert_before(Evas_Object *obj,
1154 Elm_Object_Item *before,
1155 const char *title_label,
1156 Evas_Object *prev_btn,
1157 Evas_Object *next_btn,
1158 Evas_Object *content,
1159 const char *item_style)
1161 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1162 ELM_OBJ_ITEM_CHECK_OR_RETURN(before, NULL);
1163 Elm_Naviframe_Item *it;
1166 wd = elm_widget_data_get(obj);
1167 if (!wd) return NULL;
1169 it = _item_new(WIDGET(before), title_label, prev_btn, next_btn, content,
1171 if (!it) return NULL;
1174 eina_inlist_prepend_relative(wd->stack,
1175 EINA_INLIST_GET(it),
1176 EINA_INLIST_GET(((Elm_Naviframe_Item *) before)));
1177 _sizing_eval(WIDGET(before));
1178 return (Elm_Object_Item *)it;
1181 EAPI Elm_Object_Item *
1182 elm_naviframe_item_insert_after(Evas_Object *obj,
1183 Elm_Object_Item *after,
1184 const char *title_label,
1185 Evas_Object *prev_btn,
1186 Evas_Object *next_btn,
1187 Evas_Object *content,
1188 const char *item_style)
1190 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1191 ELM_OBJ_ITEM_CHECK_OR_RETURN(after, NULL);
1192 Elm_Naviframe_Item *it;
1195 wd = elm_widget_data_get(obj);
1196 if (!wd) return NULL;
1198 it = _item_new(WIDGET(after), title_label, prev_btn, next_btn, content,
1200 if (!it) return NULL;
1202 if (elm_naviframe_top_item_get(WIDGET(after)) == after)
1204 evas_object_hide(VIEW(after));
1205 evas_object_show(VIEW(it));
1208 eina_inlist_append_relative(wd->stack,
1209 EINA_INLIST_GET(it),
1210 EINA_INLIST_GET(((Elm_Naviframe_Item *) after)));
1211 _sizing_eval(WIDGET(after));
1212 return (Elm_Object_Item *)it;
1216 elm_naviframe_item_pop(Evas_Object *obj)
1218 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1219 Elm_Naviframe_Item *it, *prev_it = NULL;
1221 Evas_Object *content = NULL;
1223 wd = elm_widget_data_get(obj);
1224 if (!wd) return NULL;
1226 it = (Elm_Naviframe_Item *) elm_naviframe_top_item_get(obj);
1227 if (!it) return NULL;
1229 content = it->content;
1231 if (wd->stack->last->prev)
1232 prev_it = EINA_INLIST_CONTAINER_GET(wd->stack->last->prev,
1233 Elm_Naviframe_Item);
1234 wd->stack = eina_inlist_remove(wd->stack, EINA_INLIST_GET(it));
1237 if (wd->freeze_events)
1239 evas_object_freeze_events_set(VIEW(it), EINA_TRUE);
1240 evas_object_freeze_events_set(VIEW(prev_it), EINA_TRUE);
1242 elm_object_signal_emit(VIEW(it), "elm,state,cur,popped", "elm");
1243 evas_object_show(VIEW(prev_it));
1244 evas_object_raise(VIEW(prev_it));
1245 elm_object_signal_emit(VIEW(prev_it),
1246 "elm,state,prev,popped",
1248 edje_object_message_signal_process(elm_layout_edje_get(VIEW(it)));
1249 edje_object_message_signal_process(elm_layout_edje_get(VIEW(prev_it)));
1254 elm_widget_item_free(it);
1261 elm_naviframe_item_pop_to(Elm_Object_Item *it)
1263 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1264 Elm_Naviframe_Item *navi_it;
1266 Eina_Inlist *l, *prev_l;
1268 navi_it = (Elm_Naviframe_Item *)it;
1269 wd = elm_widget_data_get(WIDGET(navi_it));
1272 if (it == elm_naviframe_top_item_get(WIDGET(navi_it))) return;
1274 l = wd->stack->last->prev;
1278 if (EINA_INLIST_CONTAINER_GET(l, Elm_Naviframe_Item) ==
1279 ((Elm_Naviframe_Item *)it)) break;
1281 wd->stack = eina_inlist_remove(wd->stack, l);
1282 _item_del(EINA_INLIST_CONTAINER_GET(l, Elm_Naviframe_Item));
1283 elm_widget_item_free(EINA_INLIST_CONTAINER_GET(l,
1284 Elm_Naviframe_Item));
1287 elm_naviframe_item_pop(WIDGET(navi_it));
1291 elm_naviframe_item_promote(Elm_Object_Item *it)
1293 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1294 Elm_Naviframe_Item *navi_it;
1295 Elm_Naviframe_Item *prev_it;
1298 navi_it = (Elm_Naviframe_Item *)it;
1299 wd = elm_widget_data_get(navi_it->base.widget);
1302 if (it == elm_naviframe_top_item_get(navi_it->base.widget)) return;
1303 elm_widget_tree_unfocusable_set(navi_it->content, EINA_FALSE);
1304 wd->stack = eina_inlist_demote(wd->stack, EINA_INLIST_GET(navi_it));
1305 prev_it = EINA_INLIST_CONTAINER_GET(wd->stack->last->prev,
1306 Elm_Naviframe_Item);
1307 elm_widget_tree_unfocusable_set(prev_it->content, EINA_FALSE);
1308 if (wd->freeze_events)
1310 evas_object_freeze_events_set(VIEW(it), EINA_TRUE);
1311 evas_object_freeze_events_set(VIEW(prev_it), EINA_TRUE);
1313 elm_object_signal_emit(VIEW(prev_it),
1314 "elm,state,cur,pushed",
1316 evas_object_show(VIEW(navi_it));
1317 evas_object_raise(VIEW(navi_it));
1318 elm_object_signal_emit(VIEW(navi_it),
1319 "elm,state,new,pushed",
1321 edje_object_message_signal_process(elm_layout_edje_get(VIEW(prev_it)));
1322 edje_object_message_signal_process(elm_layout_edje_get(VIEW(navi_it)));
1326 elm_naviframe_item_simple_promote(Evas_Object *obj, Evas_Object *content)
1328 ELM_CHECK_WIDTYPE(obj, widtype);
1329 Widget_Data *wd = elm_widget_data_get(obj);
1331 Elm_Naviframe_Item *itr;
1332 EINA_INLIST_FOREACH(wd->stack, itr)
1334 if (elm_object_item_content_get((Elm_Object_Item *)itr) == content)
1336 elm_naviframe_item_promote((Elm_Object_Item *)itr);
1344 elm_naviframe_item_del(Elm_Object_Item *it)
1346 elm_object_item_del(it);
1350 elm_naviframe_content_preserve_on_pop_set(Evas_Object *obj, Eina_Bool preserve)
1352 ELM_CHECK_WIDTYPE(obj, widtype);
1353 Widget_Data *wd = elm_widget_data_get(obj);
1355 wd->preserve = !!preserve;
1359 elm_naviframe_content_preserve_on_pop_get(const Evas_Object *obj)
1361 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
1362 Widget_Data *wd = elm_widget_data_get(obj);
1363 if (!wd) return EINA_FALSE;
1364 return wd->preserve;
1367 EAPI Elm_Object_Item*
1368 elm_naviframe_top_item_get(const Evas_Object *obj)
1370 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1371 Widget_Data *wd = elm_widget_data_get(obj);
1372 if ((!wd) || (!wd->stack)) return NULL;
1373 return (Elm_Object_Item *) (EINA_INLIST_CONTAINER_GET(wd->stack->last,
1374 Elm_Naviframe_Item));
1377 EAPI Elm_Object_Item*
1378 elm_naviframe_bottom_item_get(const Evas_Object *obj)
1380 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1381 Widget_Data *wd = elm_widget_data_get(obj);
1382 if ((!wd) || (!wd->stack)) return NULL;
1383 return (Elm_Object_Item *) (EINA_INLIST_CONTAINER_GET(wd->stack,
1384 Elm_Naviframe_Item));
1388 elm_naviframe_item_style_set(Elm_Object_Item *it, const char *item_style)
1390 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1391 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *)it;
1394 if (!strcmp(item_style, navi_it->style)) return;
1397 if (!strcmp("basic", navi_it->style)) return;
1399 _item_style_set(navi_it, item_style);
1403 elm_naviframe_item_style_get(const Elm_Object_Item *it)
1405 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
1406 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *)it;
1407 return navi_it->style;
1411 elm_naviframe_item_title_visible_set(Elm_Object_Item *it, Eina_Bool visible)
1413 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1414 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *)it;
1416 visible = !!visible;
1417 if (navi_it->title_visible == visible) return;
1419 navi_it->title_visible = visible;
1420 _item_title_visible_update(navi_it);
1424 elm_naviframe_item_title_visible_get(const Elm_Object_Item *it)
1426 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
1427 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *)it;
1428 return navi_it->title_visible;
1432 elm_naviframe_prev_btn_auto_pushed_set(Evas_Object *obj, Eina_Bool auto_pushed)
1434 ELM_CHECK_WIDTYPE(obj, widtype);
1435 Widget_Data *wd = elm_widget_data_get(obj);
1437 wd->auto_pushed = !!auto_pushed;
1441 elm_naviframe_prev_btn_auto_pushed_get(const Evas_Object *obj)
1443 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
1444 Widget_Data *wd = elm_widget_data_get(obj);
1445 if (!wd) return EINA_FALSE;
1446 return wd->auto_pushed;
1450 elm_naviframe_items_get(const Evas_Object *obj)
1452 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1453 Widget_Data *wd = elm_widget_data_get(obj);
1454 if (!wd) return NULL;
1455 Eina_List *ret = NULL;
1456 Elm_Naviframe_Item *itr;
1457 EINA_INLIST_FOREACH(wd->stack, itr)
1458 ret = eina_list_append(ret, itr);
1463 elm_naviframe_event_enabled_set(Evas_Object *obj, Eina_Bool enabled)
1465 ELM_CHECK_WIDTYPE(obj, widtype);
1466 Widget_Data *wd = elm_widget_data_get(obj);
1468 enabled = !!enabled;
1469 if (wd->freeze_events == !enabled) return;
1470 wd->freeze_events = !enabled;
1474 elm_naviframe_event_enabled_get(const Evas_Object *obj)
1476 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
1477 Widget_Data *wd = elm_widget_data_get(obj);
1478 if (!wd) return EINA_FALSE;
1479 return !wd->freeze_events;