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);
819 if (wd->preserve && it->content)
821 elm_object_part_content_unset(VIEW(it), "elm.swallow.content");
822 evas_object_event_callback_del(it->content,
829 _item_del_pre_hook(Elm_Object_Item *it)
831 Elm_Naviframe_Item *navi_it;
834 navi_it =(Elm_Naviframe_Item *)it;
835 wd = elm_widget_data_get(WIDGET(navi_it));
836 if (!wd) return EINA_FALSE;
838 if (it == elm_naviframe_top_item_get(WIDGET(navi_it)))
840 wd->stack = eina_inlist_remove(wd->stack, EINA_INLIST_GET(navi_it));
842 //If the item is only one, the stack will be empty
843 if (!wd->stack) return EINA_TRUE;
844 navi_it = EINA_INLIST_CONTAINER_GET(wd->stack->last,
846 evas_object_show(VIEW(navi_it));
847 evas_object_raise(VIEW(navi_it));
848 elm_object_signal_emit(VIEW(navi_it), "elm,state,visible", "elm");
852 wd->stack = eina_inlist_remove(wd->stack, EINA_INLIST_GET(navi_it));
860 _pushed_finished(void *data,
861 Evas_Object *obj __UNUSED__,
862 const char *emission __UNUSED__,
863 const char *source __UNUSED__)
866 Elm_Naviframe_Item *it = data;
869 wd = elm_widget_data_get(WIDGET(it));
872 evas_object_hide(VIEW(it));
873 if (wd->freeze_events)
874 evas_object_freeze_events_set(VIEW(it), EINA_FALSE);
878 _popped_finished(void *data,
879 Evas_Object *obj __UNUSED__,
880 const char *emission __UNUSED__,
881 const char *source __UNUSED__)
883 Elm_Naviframe_Item *it = data;
886 elm_widget_item_free(data);
890 _show_finished(void *data,
891 Evas_Object *obj __UNUSED__,
892 const char *emission __UNUSED__,
893 const char *source __UNUSED__)
895 Elm_Naviframe_Item *it;
900 wd = elm_widget_data_get(WIDGET(it));
903 evas_object_smart_callback_call(WIDGET(it),
904 SIG_TRANSITION_FINISHED,
906 if (wd->freeze_events)
907 evas_object_freeze_events_set(VIEW(it), EINA_FALSE);
911 _changed_size_hints(void *data,
913 Evas_Object *obj __UNUSED__,
914 void *event_info __UNUSED__)
920 _item_content_set(Elm_Naviframe_Item *navi_it, Evas_Object *content)
922 if (navi_it->content == content) return;
923 if (navi_it->content) evas_object_del(navi_it->content);
924 elm_object_part_content_set(VIEW(navi_it), "elm.swallow.content", content);
927 elm_object_signal_emit(VIEW(navi_it), "elm,state,content,show", "elm");
929 elm_object_signal_emit(VIEW(navi_it), "elm,state,content,hide", "elm");
931 evas_object_event_callback_add(content,
935 navi_it->content = content;
936 _sizing_eval(WIDGET(navi_it));
939 //FIXME: need to handle if this function is called while transition
941 _item_style_set(Elm_Naviframe_Item *navi_it, const char *item_style)
943 Elm_Naviframe_Content_Item_Pair *content_pair;
944 Elm_Naviframe_Text_Item_Pair *text_pair;
951 strcpy(buf, "item/basic");
952 eina_stringshare_replace(&navi_it->style, "basic");
956 snprintf(buf, sizeof(buf), "item/%s", item_style);
957 eina_stringshare_replace(&navi_it->style, item_style);
959 elm_layout_theme_set(VIEW(navi_it),
962 elm_widget_style_get(WIDGET(navi_it)));
964 EINA_INLIST_FOREACH(navi_it->text_list, text_pair)
965 _item_text_set_hook((Elm_Object_Item *) navi_it,
967 elm_object_part_text_get(VIEW(navi_it),
970 EINA_INLIST_FOREACH(navi_it->content_list, content_pair)
971 _item_content_set_hook((Elm_Object_Item *) navi_it,
973 elm_object_part_content_get(VIEW(navi_it),
974 content_pair->part));
976 if (navi_it->content)
977 elm_object_signal_emit(VIEW(navi_it), "elm,state,content,show", "elm");
980 if (navi_it->title_prev_btn)
981 elm_object_signal_emit(VIEW(navi_it), "elm,state,prev_btn,show", "elm");
984 if (navi_it->title_next_btn)
985 elm_object_signal_emit(VIEW(navi_it), "elm,state,next_btn,show", "elm");
987 // why does this forcibly enable title? isnt that separate to style?
988 // navi_it->title_visible = EINA_TRUE;
989 _sizing_eval(WIDGET(navi_it));
991 wd = elm_widget_data_get(WIDGET(navi_it));
994 if (wd->freeze_events)
995 evas_object_freeze_events_set(VIEW(navi_it), EINA_FALSE);
998 static Elm_Naviframe_Item *
999 _item_new(Evas_Object *obj,
1000 const char *title_label,
1001 Evas_Object *prev_btn,
1002 Evas_Object *next_btn,
1003 Evas_Object *content,
1004 const char *item_style)
1006 Widget_Data *wd = elm_widget_data_get(obj);
1009 Elm_Naviframe_Item *it = elm_widget_item_new(obj, Elm_Naviframe_Item);
1012 ERR("Failed to allocate new item! : naviframe=%p", obj);
1016 elm_widget_item_del_pre_hook_set(it, _item_del_pre_hook);
1017 elm_widget_item_text_set_hook_set(it, _item_text_set_hook);
1018 elm_widget_item_text_get_hook_set(it, _item_text_get_hook);
1019 elm_widget_item_content_set_hook_set(it, _item_content_set_hook);
1020 elm_widget_item_content_get_hook_set(it, _item_content_get_hook);
1021 elm_widget_item_content_unset_hook_set(it, _item_content_unset_hook);
1022 elm_widget_item_signal_emit_hook_set(it, _item_signal_emit_hook);
1025 VIEW(it) = elm_layout_add(obj);
1026 evas_object_smart_member_add(VIEW(it), wd->base);
1028 evas_object_event_callback_add(VIEW(it),
1029 EVAS_CALLBACK_CHANGED_SIZE_HINTS,
1030 _changed_size_hints,
1032 elm_object_signal_callback_add(VIEW(it),
1033 "elm,action,show,finished",
1035 _show_finished, it);
1036 elm_object_signal_callback_add(VIEW(it),
1037 "elm,action,pushed,finished",
1039 _pushed_finished, it);
1040 elm_object_signal_callback_add(VIEW(it),
1041 "elm,action,popped,finished",
1043 _popped_finished, it);
1044 elm_object_signal_callback_add(VIEW(it),
1045 "elm,action,title,clicked",
1047 _title_clicked, it);
1049 _item_style_set(it, item_style);
1050 _item_text_set_hook((Elm_Object_Item *)it, "elm.text.title", title_label);
1053 if ((!prev_btn) && wd->auto_pushed && eina_inlist_count(wd->stack))
1055 prev_btn = _back_btn_new(obj);
1056 _title_prev_btn_set(it, prev_btn, EINA_TRUE);
1059 _title_prev_btn_set(it, prev_btn, EINA_FALSE);
1061 _title_next_btn_set(it, next_btn);
1062 _item_content_set(it, content);
1063 it->title_visible = EINA_TRUE;
1068 _focus_next_hook(const Evas_Object *obj, Elm_Focus_Direction dir, Evas_Object **next)
1071 Elm_Naviframe_Item *top_it;
1072 Eina_List *l = NULL;
1073 Widget_Data *wd = elm_widget_data_get(obj);
1074 void *(*list_data_get)(const Eina_List *list);
1075 if (!wd) return EINA_FALSE;
1077 top_it = (Elm_Naviframe_Item *)elm_naviframe_top_item_get(obj);
1078 if (!top_it) return EINA_FALSE;
1080 list_data_get = eina_list_data_get;
1082 //Forcus order: prev button, next button, contents
1083 if (top_it->title_prev_btn)
1084 l = eina_list_append(l, top_it->title_prev_btn);
1085 if (top_it->title_next_btn)
1086 l = eina_list_append(l, top_it->title_next_btn);
1087 l = eina_list_append(l, VIEW(top_it));
1089 ret = elm_widget_focus_list_next_get(obj, l, list_data_get, dir, next);
1095 elm_naviframe_add(Evas_Object *parent)
1101 ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL);
1102 ELM_SET_WIDTYPE(widtype, "naviframe");
1103 elm_widget_type_set(obj, "naviframe");
1104 elm_widget_sub_object_add(parent, obj);
1105 elm_widget_data_set(obj, wd);
1106 elm_widget_del_hook_set(obj, _del_hook);
1107 elm_widget_disable_hook_set(obj, _disable_hook);
1108 elm_widget_theme_hook_set(obj, _theme_hook);
1109 elm_widget_text_set_hook_set(obj, _text_set_hook);
1110 elm_widget_text_get_hook_set(obj, _text_get_hook);
1111 elm_widget_content_set_hook_set(obj, _content_set_hook);
1112 elm_widget_content_get_hook_set(obj, _content_get_hook);
1113 elm_widget_content_unset_hook_set(obj, _content_unset_hook);
1114 elm_widget_signal_emit_hook_set(obj, _emit_hook);
1115 elm_widget_can_focus_set(obj, EINA_FALSE);
1116 elm_widget_focus_next_hook_set(obj, _focus_next_hook);
1119 //FIXME: Is this base layout really needed?
1120 wd->base = elm_layout_add(parent);
1121 evas_object_event_callback_add(wd->base,
1122 EVAS_CALLBACK_CHANGED_SIZE_HINTS,
1123 _changed_size_hints,
1125 elm_widget_resize_object_set(obj, wd->base);
1126 elm_layout_theme_set(wd->base, "naviframe", "base", "default");
1128 evas_object_event_callback_add(obj, EVAS_CALLBACK_MOVE, _move, obj);
1129 evas_object_event_callback_add(obj, EVAS_CALLBACK_RESIZE, _resize, obj);
1130 evas_object_smart_callbacks_descriptions_set(obj, _signals);
1132 wd->auto_pushed = EINA_TRUE;
1133 wd->freeze_events = EINA_TRUE;
1138 EAPI Elm_Object_Item *
1139 elm_naviframe_item_push(Evas_Object *obj,
1140 const char *title_label,
1141 Evas_Object *prev_btn,
1142 Evas_Object *next_btn,
1143 Evas_Object *content,
1144 const char *item_style)
1146 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1148 Elm_Naviframe_Item *prev_it, *it;
1150 wd = elm_widget_data_get(obj);
1151 if (!wd) return NULL;
1153 it = _item_new(obj, title_label, prev_btn, next_btn, content, item_style);
1154 if (!it) return NULL;
1156 evas_object_show(VIEW(it));
1158 prev_it = (Elm_Naviframe_Item *) elm_naviframe_top_item_get(obj);
1161 if (wd->freeze_events)
1163 evas_object_freeze_events_set(VIEW(it), EINA_TRUE);
1164 evas_object_freeze_events_set(VIEW(prev_it), EINA_TRUE);
1166 elm_object_signal_emit(VIEW(prev_it), "elm,state,cur,pushed", "elm");
1167 elm_object_signal_emit(VIEW(it), "elm,state,new,pushed", "elm");
1168 edje_object_message_signal_process(elm_layout_edje_get(VIEW(prev_it)));
1169 elm_widget_tree_unfocusable_set(prev_it->content, EINA_TRUE);
1170 edje_object_message_signal_process(elm_layout_edje_get(VIEW(it)));
1172 wd->stack = eina_inlist_append(wd->stack, EINA_INLIST_GET(it));
1174 return (Elm_Object_Item *)it;
1177 EAPI Elm_Object_Item *
1178 elm_naviframe_item_insert_before(Evas_Object *obj,
1179 Elm_Object_Item *before,
1180 const char *title_label,
1181 Evas_Object *prev_btn,
1182 Evas_Object *next_btn,
1183 Evas_Object *content,
1184 const char *item_style)
1186 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1187 ELM_OBJ_ITEM_CHECK_OR_RETURN(before, NULL);
1188 Elm_Naviframe_Item *it;
1191 wd = elm_widget_data_get(obj);
1192 if (!wd) return NULL;
1194 it = _item_new(WIDGET(before), title_label, prev_btn, next_btn, content,
1196 if (!it) return NULL;
1199 eina_inlist_prepend_relative(wd->stack,
1200 EINA_INLIST_GET(it),
1201 EINA_INLIST_GET(((Elm_Naviframe_Item *) before)));
1202 _sizing_eval(WIDGET(before));
1203 return (Elm_Object_Item *)it;
1206 EAPI Elm_Object_Item *
1207 elm_naviframe_item_insert_after(Evas_Object *obj,
1208 Elm_Object_Item *after,
1209 const char *title_label,
1210 Evas_Object *prev_btn,
1211 Evas_Object *next_btn,
1212 Evas_Object *content,
1213 const char *item_style)
1215 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1216 ELM_OBJ_ITEM_CHECK_OR_RETURN(after, NULL);
1217 Elm_Naviframe_Item *it;
1220 wd = elm_widget_data_get(obj);
1221 if (!wd) return NULL;
1223 it = _item_new(WIDGET(after), title_label, prev_btn, next_btn, content,
1225 if (!it) return NULL;
1227 if (elm_naviframe_top_item_get(WIDGET(after)) == after)
1229 evas_object_hide(VIEW(after));
1230 evas_object_show(VIEW(it));
1233 eina_inlist_append_relative(wd->stack,
1234 EINA_INLIST_GET(it),
1235 EINA_INLIST_GET(((Elm_Naviframe_Item *) after)));
1236 _sizing_eval(WIDGET(after));
1237 return (Elm_Object_Item *)it;
1241 elm_naviframe_item_pop(Evas_Object *obj)
1243 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1244 Elm_Naviframe_Item *it, *prev_it = NULL;
1246 Evas_Object *content = NULL;
1248 wd = elm_widget_data_get(obj);
1249 if (!wd) return NULL;
1251 it = (Elm_Naviframe_Item *) elm_naviframe_top_item_get(obj);
1252 if (!it) return NULL;
1254 content = it->content;
1256 elm_widget_tree_unfocusable_set(it->content, EINA_TRUE);
1258 if (wd->stack->last->prev)
1259 prev_it = EINA_INLIST_CONTAINER_GET(wd->stack->last->prev,
1260 Elm_Naviframe_Item);
1261 wd->stack = eina_inlist_remove(wd->stack, EINA_INLIST_GET(it));
1264 if (wd->freeze_events)
1266 evas_object_freeze_events_set(VIEW(it), EINA_TRUE);
1267 evas_object_freeze_events_set(VIEW(prev_it), EINA_TRUE);
1269 elm_object_signal_emit(VIEW(it), "elm,state,cur,popped", "elm");
1270 evas_object_show(VIEW(prev_it));
1271 evas_object_raise(VIEW(prev_it));
1272 elm_object_signal_emit(VIEW(prev_it),
1273 "elm,state,prev,popped",
1275 edje_object_message_signal_process(elm_layout_edje_get(VIEW(it)));
1276 edje_object_message_signal_process(elm_layout_edje_get(VIEW(prev_it)));
1281 elm_widget_item_free(it);
1288 elm_naviframe_item_pop_to(Elm_Object_Item *it)
1290 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1291 Elm_Naviframe_Item *navi_it;
1293 Eina_Inlist *l, *prev_l;
1295 navi_it = (Elm_Naviframe_Item *)it;
1296 wd = elm_widget_data_get(WIDGET(navi_it));
1299 if (it == elm_naviframe_top_item_get(WIDGET(navi_it))) return;
1301 l = wd->stack->last->prev;
1305 if (EINA_INLIST_CONTAINER_GET(l, Elm_Naviframe_Item) ==
1306 ((Elm_Naviframe_Item *)it)) break;
1308 wd->stack = eina_inlist_remove(wd->stack, l);
1309 _item_del(EINA_INLIST_CONTAINER_GET(l, Elm_Naviframe_Item));
1310 elm_widget_item_free(EINA_INLIST_CONTAINER_GET(l,
1311 Elm_Naviframe_Item));
1314 elm_naviframe_item_pop(WIDGET(navi_it));
1318 elm_naviframe_item_promote(Elm_Object_Item *it)
1320 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1321 Elm_Naviframe_Item *navi_it;
1322 Elm_Naviframe_Item *prev_it;
1325 navi_it = (Elm_Naviframe_Item *)it;
1326 wd = elm_widget_data_get(navi_it->base.widget);
1329 if (it == elm_naviframe_top_item_get(navi_it->base.widget)) return;
1330 elm_widget_tree_unfocusable_set(navi_it->content, EINA_FALSE);
1331 wd->stack = eina_inlist_demote(wd->stack, EINA_INLIST_GET(navi_it));
1332 prev_it = EINA_INLIST_CONTAINER_GET(wd->stack->last->prev,
1333 Elm_Naviframe_Item);
1334 elm_widget_tree_unfocusable_set(prev_it->content, EINA_FALSE);
1335 if (wd->freeze_events)
1337 evas_object_freeze_events_set(VIEW(it), EINA_TRUE);
1338 evas_object_freeze_events_set(VIEW(prev_it), EINA_TRUE);
1340 elm_object_signal_emit(VIEW(prev_it),
1341 "elm,state,cur,pushed",
1343 evas_object_show(VIEW(navi_it));
1344 evas_object_raise(VIEW(navi_it));
1345 elm_object_signal_emit(VIEW(navi_it),
1346 "elm,state,new,pushed",
1348 edje_object_message_signal_process(elm_layout_edje_get(VIEW(prev_it)));
1349 edje_object_message_signal_process(elm_layout_edje_get(VIEW(navi_it)));
1353 elm_naviframe_item_simple_promote(Evas_Object *obj, Evas_Object *content)
1355 ELM_CHECK_WIDTYPE(obj, widtype);
1356 Widget_Data *wd = elm_widget_data_get(obj);
1358 Elm_Naviframe_Item *itr;
1359 EINA_INLIST_FOREACH(wd->stack, itr)
1361 if (elm_object_item_content_get((Elm_Object_Item *)itr) == content)
1363 elm_naviframe_item_promote((Elm_Object_Item *)itr);
1371 elm_naviframe_content_preserve_on_pop_set(Evas_Object *obj, Eina_Bool preserve)
1373 ELM_CHECK_WIDTYPE(obj, widtype);
1374 Widget_Data *wd = elm_widget_data_get(obj);
1376 wd->preserve = !!preserve;
1380 elm_naviframe_content_preserve_on_pop_get(const Evas_Object *obj)
1382 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
1383 Widget_Data *wd = elm_widget_data_get(obj);
1384 if (!wd) return EINA_FALSE;
1385 return wd->preserve;
1388 EAPI Elm_Object_Item*
1389 elm_naviframe_top_item_get(const Evas_Object *obj)
1391 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1392 Widget_Data *wd = elm_widget_data_get(obj);
1393 if ((!wd) || (!wd->stack)) return NULL;
1394 return (Elm_Object_Item *) (EINA_INLIST_CONTAINER_GET(wd->stack->last,
1395 Elm_Naviframe_Item));
1398 EAPI Elm_Object_Item*
1399 elm_naviframe_bottom_item_get(const Evas_Object *obj)
1401 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1402 Widget_Data *wd = elm_widget_data_get(obj);
1403 if ((!wd) || (!wd->stack)) return NULL;
1404 return (Elm_Object_Item *) (EINA_INLIST_CONTAINER_GET(wd->stack,
1405 Elm_Naviframe_Item));
1409 elm_naviframe_item_style_set(Elm_Object_Item *it, const char *item_style)
1411 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1412 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *)it;
1415 if (!strcmp(item_style, navi_it->style)) return;
1418 if (!strcmp("basic", navi_it->style)) return;
1420 _item_style_set(navi_it, item_style);
1424 elm_naviframe_item_style_get(const Elm_Object_Item *it)
1426 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
1427 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *)it;
1428 return navi_it->style;
1432 elm_naviframe_item_title_visible_set(Elm_Object_Item *it, Eina_Bool visible)
1434 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1435 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *)it;
1437 visible = !!visible;
1438 if (navi_it->title_visible == visible) return;
1440 navi_it->title_visible = visible;
1441 _item_title_visible_update(navi_it);
1445 elm_naviframe_item_title_visible_get(const Elm_Object_Item *it)
1447 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
1448 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *)it;
1449 return navi_it->title_visible;
1453 elm_naviframe_prev_btn_auto_pushed_set(Evas_Object *obj, Eina_Bool auto_pushed)
1455 ELM_CHECK_WIDTYPE(obj, widtype);
1456 Widget_Data *wd = elm_widget_data_get(obj);
1458 wd->auto_pushed = !!auto_pushed;
1462 elm_naviframe_prev_btn_auto_pushed_get(const Evas_Object *obj)
1464 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
1465 Widget_Data *wd = elm_widget_data_get(obj);
1466 if (!wd) return EINA_FALSE;
1467 return wd->auto_pushed;
1471 elm_naviframe_items_get(const Evas_Object *obj)
1473 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1474 Widget_Data *wd = elm_widget_data_get(obj);
1475 if (!wd) return NULL;
1476 Eina_List *ret = NULL;
1477 Elm_Naviframe_Item *itr;
1478 EINA_INLIST_FOREACH(wd->stack, itr)
1479 ret = eina_list_append(ret, itr);
1484 elm_naviframe_event_enabled_set(Evas_Object *obj, Eina_Bool enabled)
1486 ELM_CHECK_WIDTYPE(obj, widtype);
1487 Widget_Data *wd = elm_widget_data_get(obj);
1489 enabled = !!enabled;
1490 if (wd->freeze_events == !enabled) return;
1491 wd->freeze_events = !enabled;
1495 elm_naviframe_event_enabled_get(const Evas_Object *obj)
1497 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
1498 Widget_Data *wd = elm_widget_data_get(obj);
1499 if (!wd) return EINA_FALSE;
1500 return !wd->freeze_events;