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)
1063 Elm_Naviframe_Item *top_it;
1064 Eina_List *l = NULL;
1065 Widget_Data *wd = elm_widget_data_get(obj);
1066 void *(*list_data_get)(const Eina_List *list);
1067 if (!wd) return EINA_FALSE;
1069 top_it = (Elm_Naviframe_Item *)elm_naviframe_top_item_get(obj);
1070 if (!top_it) return EINA_FALSE;
1072 list_data_get = eina_list_data_get;
1074 //Forcus order: prev button, next button, contents
1075 if (top_it->title_prev_btn)
1076 l = eina_list_append(l, top_it->title_prev_btn);
1077 if (top_it->title_next_btn)
1078 l = eina_list_append(l, top_it->title_next_btn);
1079 l = eina_list_append(l, VIEW(top_it));
1081 ret = elm_widget_focus_list_next_get(obj, l, list_data_get, dir, next);
1087 elm_naviframe_add(Evas_Object *parent)
1093 ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL);
1094 ELM_SET_WIDTYPE(widtype, "naviframe");
1095 elm_widget_type_set(obj, "naviframe");
1096 elm_widget_sub_object_add(parent, obj);
1097 elm_widget_data_set(obj, wd);
1098 elm_widget_del_hook_set(obj, _del_hook);
1099 elm_widget_disable_hook_set(obj, _disable_hook);
1100 elm_widget_theme_hook_set(obj, _theme_hook);
1101 elm_widget_text_set_hook_set(obj, _text_set_hook);
1102 elm_widget_text_get_hook_set(obj, _text_get_hook);
1103 elm_widget_content_set_hook_set(obj, _content_set_hook);
1104 elm_widget_content_get_hook_set(obj, _content_get_hook);
1105 elm_widget_content_unset_hook_set(obj, _content_unset_hook);
1106 elm_widget_signal_emit_hook_set(obj, _emit_hook);
1107 elm_widget_can_focus_set(obj, EINA_FALSE);
1108 elm_widget_focus_next_hook_set(obj, _focus_next_hook);
1111 //FIXME: Is this base layout really needed?
1112 wd->base = elm_layout_add(parent);
1113 evas_object_event_callback_add(wd->base,
1114 EVAS_CALLBACK_CHANGED_SIZE_HINTS,
1115 _changed_size_hints,
1117 elm_widget_resize_object_set(obj, wd->base);
1118 elm_layout_theme_set(wd->base, "naviframe", "base", "default");
1120 evas_object_event_callback_add(obj, EVAS_CALLBACK_MOVE, _move, obj);
1121 evas_object_event_callback_add(obj, EVAS_CALLBACK_RESIZE, _resize, obj);
1122 evas_object_smart_callbacks_descriptions_set(obj, _signals);
1124 wd->auto_pushed = EINA_TRUE;
1125 wd->freeze_events = EINA_TRUE;
1130 EAPI Elm_Object_Item *
1131 elm_naviframe_item_push(Evas_Object *obj,
1132 const char *title_label,
1133 Evas_Object *prev_btn,
1134 Evas_Object *next_btn,
1135 Evas_Object *content,
1136 const char *item_style)
1138 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1140 Elm_Naviframe_Item *prev_it, *it;
1142 wd = elm_widget_data_get(obj);
1143 if (!wd) return NULL;
1145 it = _item_new(obj, title_label, prev_btn, next_btn, content, item_style);
1146 if (!it) return NULL;
1148 evas_object_show(VIEW(it));
1150 prev_it = (Elm_Naviframe_Item *) elm_naviframe_top_item_get(obj);
1153 if (wd->freeze_events)
1155 evas_object_freeze_events_set(VIEW(it), EINA_TRUE);
1156 evas_object_freeze_events_set(VIEW(prev_it), EINA_TRUE);
1158 elm_object_signal_emit(VIEW(prev_it), "elm,state,cur,pushed", "elm");
1159 elm_object_signal_emit(VIEW(it), "elm,state,new,pushed", "elm");
1160 edje_object_message_signal_process(elm_layout_edje_get(VIEW(prev_it)));
1161 elm_widget_tree_unfocusable_set(prev_it->content, EINA_TRUE);
1162 edje_object_message_signal_process(elm_layout_edje_get(VIEW(it)));
1164 wd->stack = eina_inlist_append(wd->stack, EINA_INLIST_GET(it));
1166 return (Elm_Object_Item *)it;
1169 EAPI Elm_Object_Item *
1170 elm_naviframe_item_insert_before(Evas_Object *obj,
1171 Elm_Object_Item *before,
1172 const char *title_label,
1173 Evas_Object *prev_btn,
1174 Evas_Object *next_btn,
1175 Evas_Object *content,
1176 const char *item_style)
1178 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1179 ELM_OBJ_ITEM_CHECK_OR_RETURN(before, NULL);
1180 Elm_Naviframe_Item *it;
1183 wd = elm_widget_data_get(obj);
1184 if (!wd) return NULL;
1186 it = _item_new(WIDGET(before), title_label, prev_btn, next_btn, content,
1188 if (!it) return NULL;
1191 eina_inlist_prepend_relative(wd->stack,
1192 EINA_INLIST_GET(it),
1193 EINA_INLIST_GET(((Elm_Naviframe_Item *) before)));
1194 _sizing_eval(WIDGET(before));
1195 return (Elm_Object_Item *)it;
1198 EAPI Elm_Object_Item *
1199 elm_naviframe_item_insert_after(Evas_Object *obj,
1200 Elm_Object_Item *after,
1201 const char *title_label,
1202 Evas_Object *prev_btn,
1203 Evas_Object *next_btn,
1204 Evas_Object *content,
1205 const char *item_style)
1207 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1208 ELM_OBJ_ITEM_CHECK_OR_RETURN(after, NULL);
1209 Elm_Naviframe_Item *it;
1212 wd = elm_widget_data_get(obj);
1213 if (!wd) return NULL;
1215 it = _item_new(WIDGET(after), title_label, prev_btn, next_btn, content,
1217 if (!it) return NULL;
1219 if (elm_naviframe_top_item_get(WIDGET(after)) == after)
1221 evas_object_hide(VIEW(after));
1222 evas_object_show(VIEW(it));
1225 eina_inlist_append_relative(wd->stack,
1226 EINA_INLIST_GET(it),
1227 EINA_INLIST_GET(((Elm_Naviframe_Item *) after)));
1228 _sizing_eval(WIDGET(after));
1229 return (Elm_Object_Item *)it;
1233 elm_naviframe_item_pop(Evas_Object *obj)
1235 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1236 Elm_Naviframe_Item *it, *prev_it = NULL;
1238 Evas_Object *content = NULL;
1240 wd = elm_widget_data_get(obj);
1241 if (!wd) return NULL;
1243 it = (Elm_Naviframe_Item *) elm_naviframe_top_item_get(obj);
1244 if (!it) return NULL;
1246 content = it->content;
1248 elm_widget_tree_unfocusable_set(it->content, EINA_TRUE);
1250 if (wd->stack->last->prev)
1251 prev_it = EINA_INLIST_CONTAINER_GET(wd->stack->last->prev,
1252 Elm_Naviframe_Item);
1253 wd->stack = eina_inlist_remove(wd->stack, EINA_INLIST_GET(it));
1256 if (wd->freeze_events)
1258 evas_object_freeze_events_set(VIEW(it), EINA_TRUE);
1259 evas_object_freeze_events_set(VIEW(prev_it), EINA_TRUE);
1261 elm_object_signal_emit(VIEW(it), "elm,state,cur,popped", "elm");
1262 evas_object_show(VIEW(prev_it));
1263 evas_object_raise(VIEW(prev_it));
1264 elm_object_signal_emit(VIEW(prev_it),
1265 "elm,state,prev,popped",
1267 edje_object_message_signal_process(elm_layout_edje_get(VIEW(it)));
1268 edje_object_message_signal_process(elm_layout_edje_get(VIEW(prev_it)));
1273 elm_widget_item_free(it);
1280 elm_naviframe_item_pop_to(Elm_Object_Item *it)
1282 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1283 Elm_Naviframe_Item *navi_it;
1285 Eina_Inlist *l, *prev_l;
1287 navi_it = (Elm_Naviframe_Item *)it;
1288 wd = elm_widget_data_get(WIDGET(navi_it));
1291 if (it == elm_naviframe_top_item_get(WIDGET(navi_it))) return;
1293 l = wd->stack->last->prev;
1297 if (EINA_INLIST_CONTAINER_GET(l, Elm_Naviframe_Item) ==
1298 ((Elm_Naviframe_Item *)it)) break;
1300 wd->stack = eina_inlist_remove(wd->stack, l);
1301 _item_del(EINA_INLIST_CONTAINER_GET(l, Elm_Naviframe_Item));
1302 elm_widget_item_free(EINA_INLIST_CONTAINER_GET(l,
1303 Elm_Naviframe_Item));
1306 elm_naviframe_item_pop(WIDGET(navi_it));
1310 elm_naviframe_item_promote(Elm_Object_Item *it)
1312 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1313 Elm_Naviframe_Item *navi_it;
1314 Elm_Naviframe_Item *prev_it;
1317 navi_it = (Elm_Naviframe_Item *)it;
1318 wd = elm_widget_data_get(navi_it->base.widget);
1321 if (it == elm_naviframe_top_item_get(navi_it->base.widget)) return;
1322 elm_widget_tree_unfocusable_set(navi_it->content, EINA_FALSE);
1323 wd->stack = eina_inlist_demote(wd->stack, EINA_INLIST_GET(navi_it));
1324 prev_it = EINA_INLIST_CONTAINER_GET(wd->stack->last->prev,
1325 Elm_Naviframe_Item);
1326 elm_widget_tree_unfocusable_set(prev_it->content, EINA_FALSE);
1327 if (wd->freeze_events)
1329 evas_object_freeze_events_set(VIEW(it), EINA_TRUE);
1330 evas_object_freeze_events_set(VIEW(prev_it), EINA_TRUE);
1332 elm_object_signal_emit(VIEW(prev_it),
1333 "elm,state,cur,pushed",
1335 evas_object_show(VIEW(navi_it));
1336 evas_object_raise(VIEW(navi_it));
1337 elm_object_signal_emit(VIEW(navi_it),
1338 "elm,state,new,pushed",
1340 edje_object_message_signal_process(elm_layout_edje_get(VIEW(prev_it)));
1341 edje_object_message_signal_process(elm_layout_edje_get(VIEW(navi_it)));
1345 elm_naviframe_item_simple_promote(Evas_Object *obj, Evas_Object *content)
1347 ELM_CHECK_WIDTYPE(obj, widtype);
1348 Widget_Data *wd = elm_widget_data_get(obj);
1350 Elm_Naviframe_Item *itr;
1351 EINA_INLIST_FOREACH(wd->stack, itr)
1353 if (elm_object_item_content_get((Elm_Object_Item *)itr) == content)
1355 elm_naviframe_item_promote((Elm_Object_Item *)itr);
1363 elm_naviframe_content_preserve_on_pop_set(Evas_Object *obj, Eina_Bool preserve)
1365 ELM_CHECK_WIDTYPE(obj, widtype);
1366 Widget_Data *wd = elm_widget_data_get(obj);
1368 wd->preserve = !!preserve;
1372 elm_naviframe_content_preserve_on_pop_get(const Evas_Object *obj)
1374 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
1375 Widget_Data *wd = elm_widget_data_get(obj);
1376 if (!wd) return EINA_FALSE;
1377 return wd->preserve;
1380 EAPI Elm_Object_Item*
1381 elm_naviframe_top_item_get(const Evas_Object *obj)
1383 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1384 Widget_Data *wd = elm_widget_data_get(obj);
1385 if ((!wd) || (!wd->stack)) return NULL;
1386 return (Elm_Object_Item *) (EINA_INLIST_CONTAINER_GET(wd->stack->last,
1387 Elm_Naviframe_Item));
1390 EAPI Elm_Object_Item*
1391 elm_naviframe_bottom_item_get(const Evas_Object *obj)
1393 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1394 Widget_Data *wd = elm_widget_data_get(obj);
1395 if ((!wd) || (!wd->stack)) return NULL;
1396 return (Elm_Object_Item *) (EINA_INLIST_CONTAINER_GET(wd->stack,
1397 Elm_Naviframe_Item));
1401 elm_naviframe_item_style_set(Elm_Object_Item *it, const char *item_style)
1403 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1404 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *)it;
1407 if (!strcmp(item_style, navi_it->style)) return;
1410 if (!strcmp("basic", navi_it->style)) return;
1412 _item_style_set(navi_it, item_style);
1416 elm_naviframe_item_style_get(const Elm_Object_Item *it)
1418 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
1419 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *)it;
1420 return navi_it->style;
1424 elm_naviframe_item_title_visible_set(Elm_Object_Item *it, Eina_Bool visible)
1426 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1427 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *)it;
1429 visible = !!visible;
1430 if (navi_it->title_visible == visible) return;
1432 navi_it->title_visible = visible;
1433 _item_title_visible_update(navi_it);
1437 elm_naviframe_item_title_visible_get(const Elm_Object_Item *it)
1439 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
1440 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *)it;
1441 return navi_it->title_visible;
1445 elm_naviframe_prev_btn_auto_pushed_set(Evas_Object *obj, Eina_Bool auto_pushed)
1447 ELM_CHECK_WIDTYPE(obj, widtype);
1448 Widget_Data *wd = elm_widget_data_get(obj);
1450 wd->auto_pushed = !!auto_pushed;
1454 elm_naviframe_prev_btn_auto_pushed_get(const Evas_Object *obj)
1456 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
1457 Widget_Data *wd = elm_widget_data_get(obj);
1458 if (!wd) return EINA_FALSE;
1459 return wd->auto_pushed;
1463 elm_naviframe_items_get(const Evas_Object *obj)
1465 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1466 Widget_Data *wd = elm_widget_data_get(obj);
1467 if (!wd) return NULL;
1468 Eina_List *ret = NULL;
1469 Elm_Naviframe_Item *itr;
1470 EINA_INLIST_FOREACH(wd->stack, itr)
1471 ret = eina_list_append(ret, itr);
1476 elm_naviframe_event_enabled_set(Evas_Object *obj, Eina_Bool enabled)
1478 ELM_CHECK_WIDTYPE(obj, widtype);
1479 Widget_Data *wd = elm_widget_data_get(obj);
1481 enabled = !!enabled;
1482 if (wd->freeze_events == !enabled) return;
1483 wd->freeze_events = !enabled;
1487 elm_naviframe_event_enabled_get(const Evas_Object *obj)
1489 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
1490 Widget_Data *wd = elm_widget_data_get(obj);
1491 if (!wd) return EINA_FALSE;
1492 return !wd->freeze_events;