1 #include <Elementary.h>
4 typedef struct _Widget_Data Widget_Data;
5 typedef struct _Elm_Naviframe_Item Elm_Naviframe_Item;
6 typedef struct _Elm_Naviframe_Content_Item_Pair Elm_Naviframe_Content_Item_Pair;
7 typedef struct _Elm_Naviframe_Text_Item_Pair Elm_Naviframe_Text_Item_Pair;
13 Eina_Bool preserve: 1;
14 Eina_Bool auto_pushed: 1;
15 Eina_Bool freeze_events: 1;
18 struct _Elm_Naviframe_Content_Item_Pair
22 Elm_Naviframe_Item *it;
25 struct _Elm_Naviframe_Text_Item_Pair
31 struct _Elm_Naviframe_Item
35 Eina_Inlist *content_list;
36 Eina_Inlist *text_list;
38 Evas_Object *title_prev_btn;
39 Evas_Object *title_next_btn;
40 Evas_Object *title_icon;
44 Eina_Bool back_btn: 1;
45 Eina_Bool title_visible: 1;
46 Eina_Bool content_unfocusable : 1;
49 static const char *widtype = NULL;
52 static const char SIG_TRANSITION_FINISHED[] = "transition,finished";
53 static const char SIG_TITLE_CLICKED[] = "title,clicked";
55 static const Evas_Smart_Cb_Description _signals[] = {
56 {SIG_TRANSITION_FINISHED, ""},
57 {SIG_TITLE_CLICKED, ""},
61 static void _text_set_hook(Evas_Object *obj,
64 static const char *_text_get_hook(const Evas_Object *obj, const char *part);
65 static void _content_set_hook(Evas_Object *obj,
67 Evas_Object *content);
68 static Evas_Object *_content_get_hook(const Evas_Object *obj, const char *part);
69 static Evas_Object *_content_unset_hook(Evas_Object *obj, const char *part);
70 static void _del_hook(Evas_Object *obj);
71 static void _theme_hook(Evas_Object *obj);
72 static void _emit_hook(Evas_Object *obj,
75 static void _disable_hook(Evas_Object *obj);
76 static void _item_text_set_hook(Elm_Object_Item *it,
79 static const char *_item_text_get_hook(const Elm_Object_Item *it,
81 static void _item_content_set_hook(Elm_Object_Item *it,
83 Evas_Object *content);
84 static Evas_Object *_item_content_get_hook(const Elm_Object_Item *it,
86 static Evas_Object *_item_content_unset_hook(Elm_Object_Item *it,
88 static void _item_signal_emit_hook(Elm_Object_Item *it,
91 static void _item_title_visible_update(Elm_Naviframe_Item *navi_it);
92 static void _sizing_eval(Evas_Object *obj);
93 static void _move(void *data, Evas *e, Evas_Object *obj, void *event_info);
94 static void _resize(void *data,
98 static void _title_clicked(void *data, Evas_Object *obj,
101 static void _back_btn_clicked(void *data,
104 static Evas_Object *_back_btn_new(Evas_Object *obj);
105 static void _item_content_del(void *data,
109 static void _title_content_del(void *data,
113 static void _title_prev_btn_del(void *data,
117 static void _title_next_btn_del(void *data,
121 static void _title_icon_del(void *data,
125 static void _title_content_set(Elm_Naviframe_Item *it,
127 Evas_Object *content);
128 static void _title_prev_btn_set(Elm_Naviframe_Item *it,
131 static void _title_next_btn_set(Elm_Naviframe_Item *it, Evas_Object *btn);
132 static void _title_icon_set(Elm_Naviframe_Item *it, Evas_Object *icon);
133 static Evas_Object * _item_content_unset(Elm_Naviframe_Item *it);
134 static Evas_Object * _title_prev_btn_unset(Elm_Naviframe_Item *it);
135 static Evas_Object * _title_next_btn_unset(Elm_Naviframe_Item *it);
136 static Evas_Object * _title_icon_unset(Elm_Naviframe_Item *it);
137 static Evas_Object * _title_content_unset(Elm_Naviframe_Item *it,
139 static void _item_del(Elm_Naviframe_Item *it);
140 static Eina_Bool _item_del_pre_hook(Elm_Object_Item *it);
141 static void _pushed_finished(void *data,
143 const char *emission,
145 static void _popped_finished(void *data,
147 const char *emission,
149 static void _show_finished(void *data,
151 const char *emission,
153 static void _changed_size_hints(void *data,
157 static void _item_content_set(Elm_Naviframe_Item *navi_it,
158 Evas_Object *content);
159 static void _item_style_set(Elm_Naviframe_Item *navi_it,
160 const char *item_style);
161 static Elm_Naviframe_Item * _item_new(Evas_Object *obj,
162 const char *title_label,
163 Evas_Object *prev_btn,
164 Evas_Object *next_btn,
165 Evas_Object *content,
166 const char *item_style);
167 static Eina_Bool _focus_next_hook(const Evas_Object *obj,
168 Elm_Focus_Direction dir,
172 _del_hook(Evas_Object *obj)
175 Elm_Naviframe_Item *it;
177 wd = elm_widget_data_get(obj);
182 while (wd->stack->last)
184 it = EINA_INLIST_CONTAINER_GET(wd->stack->last,
186 wd->stack = eina_inlist_remove(wd->stack, wd->stack->last);
188 elm_widget_item_free(it);
189 if (!wd->stack) break;
196 _theme_hook(Evas_Object *obj)
199 Elm_Naviframe_Item *it;
201 wd = elm_widget_data_get(obj);
204 _elm_theme_object_set(obj,
208 elm_widget_style_get(obj));
210 EINA_INLIST_FOREACH(wd->stack, it)
212 _item_style_set(it, it->style);
213 _item_title_visible_update(it);
217 static void _emit_hook(Evas_Object *obj,
218 const char *emission,
221 Elm_Object_Item *it = elm_naviframe_top_item_get(obj);
223 return elm_object_item_signal_emit(it, emission, source);
227 _disable_hook(Evas_Object *obj __UNUSED__)
233 _item_text_set_hook(Elm_Object_Item *it,
237 Elm_Naviframe_Text_Item_Pair *pair = NULL;
238 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *)it;
241 if (!part || !strcmp(part, "default"))
242 snprintf(buf, sizeof(buf), "elm.text.title");
243 else if(!strcmp("subtitle", part))
244 snprintf(buf, sizeof(buf), "elm.text.subtitle");
246 snprintf(buf, sizeof(buf), "%s", part);
248 EINA_INLIST_FOREACH(navi_it->text_list, pair)
249 if (!strcmp(buf, pair->part)) break;
253 pair = ELM_NEW(Elm_Naviframe_Text_Item_Pair);
256 ERR("Failed to allocate new text part of the item! : naviframe=%p",
260 eina_stringshare_replace(&pair->part, buf);
261 navi_it->text_list = eina_inlist_append(navi_it->text_list,
262 EINA_INLIST_GET(pair));
264 elm_object_part_text_set(VIEW(navi_it), buf, label);
268 snprintf(buf, sizeof(buf), "elm,state,%s,show", buf);
269 elm_object_signal_emit(VIEW(navi_it), buf, "elm");
273 snprintf(buf, sizeof(buf), "elm,state,%s,hide", buf);
274 elm_object_signal_emit(VIEW(navi_it), buf, "elm");
277 _sizing_eval(WIDGET(navi_it));
281 _item_text_get_hook(const Elm_Object_Item *it, const char *part)
285 if (!part || !strcmp(part, "default"))
286 snprintf(buf, sizeof(buf), "elm.text.title");
287 else if(!strcmp("subtitle", part))
288 snprintf(buf, sizeof(buf), "elm.text.subtitle");
290 snprintf(buf, sizeof(buf), "%s", part);
292 return elm_object_part_text_get(VIEW(it), buf);
296 _item_content_set_hook(Elm_Object_Item *it,
298 Evas_Object *content)
300 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *)it;
303 if (!part || !strcmp("default", part))
305 _item_content_set(navi_it, content);
308 else if (!strcmp(part, "prev_btn"))
310 _title_prev_btn_set(navi_it, content, EINA_FALSE);
313 else if (!strcmp(part, "next_btn"))
315 _title_next_btn_set(navi_it, content);
318 else if (!strcmp(part, "icon"))
320 _title_icon_set(navi_it, content);
325 _title_content_set(navi_it, part, content);
329 _item_content_get_hook(const Elm_Object_Item *it, const char *part)
331 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *)it;
334 if (!part || !strcmp("default", part))
335 return navi_it->content;
336 else if (!strcmp(part, "prev_btn"))
337 return navi_it->title_prev_btn;
338 else if (!strcmp(part, "next_btn"))
339 return navi_it->title_next_btn;
340 else if (!strcmp(part, "icon"))
341 return navi_it->title_icon;
344 return elm_object_part_content_get(VIEW(navi_it), part);
348 _item_content_unset_hook(Elm_Object_Item *it, const char *part)
350 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *)it;
353 if (!part || !strcmp("default", part))
354 return _item_content_unset(navi_it);
355 else if (!strcmp(part, "prev_btn"))
356 return _title_prev_btn_unset(navi_it);
357 else if (!strcmp(part, "next_btn"))
358 return _title_next_btn_unset(navi_it);
359 else if (!strcmp(part, "icon"))
360 return _title_icon_unset(navi_it);
362 return _title_content_unset(navi_it, part);
366 _item_signal_emit_hook(Elm_Object_Item *it,
367 const char *emission,
370 elm_object_signal_emit(VIEW(it), emission, source);
374 _item_title_visible_update(Elm_Naviframe_Item *navi_it)
376 if (navi_it->title_visible)
377 elm_object_signal_emit(VIEW(navi_it), "elm,state,title,show", "elm");
379 elm_object_signal_emit(VIEW(navi_it), "elm,state,title,hide", "elm");
383 _sizing_eval(Evas_Object *obj)
386 Elm_Naviframe_Item *it;
387 Evas_Coord x, y, w, h;
388 Evas_Coord minw = -1, minh = -1;
390 wd = elm_widget_data_get(obj);
393 evas_object_geometry_get(obj, &x, &y, &w, &h);
395 EINA_INLIST_FOREACH(wd->stack, it)
397 evas_object_move(VIEW(it), x, y);
398 evas_object_resize(VIEW(it), w, h);
399 edje_object_size_min_calc(elm_layout_edje_get(VIEW(it)),
402 if (it->minw > minw) minw = it->minw;
403 if (it->minh > minh) minh = it->minh;
405 evas_object_size_hint_min_set(obj, minw, minh);
406 evas_object_size_hint_max_set(obj, -1, -1);
410 _move(void *data __UNUSED__,
413 void *event_info __UNUSED__)
419 _resize(void *data __UNUSED__,
422 void *event_info __UNUSED__)
428 _title_clicked(void *data,
429 Evas_Object *obj __UNUSED__,
430 const char *emission __UNUSED__,
431 const char *source __UNUSED__)
433 Elm_Naviframe_Item *it = data;
434 evas_object_smart_callback_call(WIDGET(it), SIG_TITLE_CLICKED, it);
438 _back_btn_clicked(void *data,
440 void *event_info __UNUSED__)
442 /* Since edje has the event queue, clicked event could be happend multiple times
443 on some heavy environment. This callback del will prevent those scenario and
444 guarantee only one clicked for it's own page. */
445 evas_object_smart_callback_del(obj, "clicked", _back_btn_clicked);
446 elm_naviframe_item_pop(data);
450 _back_btn_new(Evas_Object *obj)
454 btn = elm_button_add(obj);
455 if (!btn) return NULL;
456 evas_object_smart_callback_add(btn, "clicked", _back_btn_clicked, obj);
457 snprintf(buf, sizeof(buf), "naviframe/back_btn/%s",
458 elm_widget_style_get(obj));
459 elm_object_style_set(btn, buf);
463 static void _text_set_hook(Evas_Object *obj,
467 Elm_Object_Item *it = elm_naviframe_top_item_get(obj);
469 elm_object_item_part_text_set(it, part, label);
472 static const char *_text_get_hook(const Evas_Object *obj, const char *part)
474 Elm_Object_Item *it = elm_naviframe_top_item_get(obj);
475 if (!it) return NULL;
476 return elm_object_item_part_text_get(it, part);
480 _content_set_hook(Evas_Object *obj, const char *part, Evas_Object *content)
482 Elm_Object_Item *it = elm_naviframe_top_item_get(obj);
484 elm_object_item_part_content_set(it, part, content);
488 _content_unset_hook(Evas_Object *obj, const char *part)
490 Elm_Object_Item *it = elm_naviframe_top_item_get(obj);
491 if (!it) return NULL;
492 return elm_object_item_part_content_unset(it, part);
496 _content_get_hook(const Evas_Object *obj, const char *part)
498 Elm_Object_Item *it = elm_naviframe_top_item_get(obj);
499 if (!it) return NULL;
500 return elm_object_item_part_content_get(it, part);
504 _title_content_del(void *data,
506 Evas_Object *obj __UNUSED__,
507 void *event_info __UNUSED__)
510 Elm_Naviframe_Content_Item_Pair *pair = data;
511 Elm_Naviframe_Item *it = pair->it;
512 snprintf(buf, sizeof(buf), "elm,state,%s,hide", pair->part);
513 elm_object_signal_emit(VIEW(it), buf, "elm");
514 it->content_list = eina_inlist_remove(it->content_list,
515 EINA_INLIST_GET(pair));
516 eina_stringshare_del(pair->part);
521 _title_prev_btn_del(void *data,
523 Evas_Object *obj __UNUSED__,
524 void *event_info __UNUSED__)
526 Elm_Naviframe_Item *it = data;
527 it->back_btn = EINA_FALSE;
528 it->title_prev_btn = NULL;
529 elm_object_signal_emit(VIEW(it), "elm,state,prev_btn,hide", "elm");
533 _title_next_btn_del(void *data,
535 Evas_Object *obj __UNUSED__,
536 void *event_info __UNUSED__)
538 Elm_Naviframe_Item *it = data;
539 it->title_next_btn = NULL;
540 elm_object_signal_emit(VIEW(it), "elm,state,next_btn,hide", "elm");
544 _title_icon_del(void *data,
546 Evas_Object *obj __UNUSED__,
547 void *event_info __UNUSED__)
549 Elm_Naviframe_Item *it = data;
550 it->title_icon = NULL;
551 elm_object_signal_emit(VIEW(it), "elm,state,icon,hide", "elm");
555 _item_content_del(void *data,
557 Evas_Object *obj __UNUSED__,
558 void *event_info __UNUSED__)
560 Elm_Naviframe_Item *it = data;
562 elm_object_signal_emit(VIEW(it), "elm,state,content,hide", "elm");
566 _title_content_set(Elm_Naviframe_Item *it,
568 Evas_Object *content)
571 Elm_Naviframe_Content_Item_Pair *pair = NULL;
572 Evas_Object *prev_content = NULL;
574 EINA_INLIST_FOREACH(it->content_list, pair)
575 if (!strcmp(part, pair->part)) break;
579 prev_content = elm_object_part_content_get(VIEW(it), part);
580 if (prev_content != content)
584 evas_object_event_callback_del(prev_content,
587 snprintf(buf, sizeof(buf), "elm,state,%s,hide", part);
588 elm_object_signal_emit(VIEW(it), buf, "elm");
590 evas_object_del(prev_content);
591 if (!content) return;
596 if (!content) return;
597 pair = ELM_NEW(Elm_Naviframe_Content_Item_Pair);
600 ERR("Failed to allocate new content part of the item! : naviframe=%p", WIDGET(it));
604 eina_stringshare_replace(&pair->part, part);
605 it->content_list = eina_inlist_append(it->content_list,
606 EINA_INLIST_GET(pair));
608 if (prev_content != content)
610 evas_object_event_callback_add(content,
615 elm_object_part_content_set(VIEW(it), part, content);
616 snprintf(buf, sizeof(buf), "elm,state,%s,show", part);
617 elm_object_signal_emit(VIEW(it), buf, "elm");
619 _sizing_eval(WIDGET(it));
623 _title_prev_btn_set(Elm_Naviframe_Item *it,
627 if (it->title_prev_btn == btn) return;
628 if (it->title_prev_btn) evas_object_del(it->title_prev_btn);
629 it->title_prev_btn = btn;
632 evas_object_event_callback_add(btn,
636 elm_object_part_content_set(VIEW(it), "elm.swallow.prev_btn", btn);
637 elm_object_signal_emit(VIEW(it), "elm,state,prev_btn,show", "elm");
638 it->back_btn = back_btn;
640 _sizing_eval(WIDGET(it));
644 _title_next_btn_set(Elm_Naviframe_Item *it, Evas_Object *btn)
646 if (it->title_next_btn == btn) return;
647 if (it->title_next_btn) evas_object_del(it->title_next_btn);
648 it->title_next_btn = btn;
651 evas_object_event_callback_add(btn,
655 elm_object_part_content_set(VIEW(it), "elm.swallow.next_btn", btn);
656 elm_object_signal_emit(VIEW(it), "elm,state,next_btn,show", "elm");
658 _sizing_eval(WIDGET(it));
662 _title_icon_set(Elm_Naviframe_Item *it, Evas_Object *icon)
664 if (it->title_icon == icon) return;
665 if (it->title_icon) evas_object_del(it->title_icon);
666 it->title_icon = icon;
669 evas_object_event_callback_add(icon,
673 elm_object_part_content_set(VIEW(it), "elm.swallow.icon", icon);
674 elm_object_signal_emit(VIEW(it), "elm,state,icon,show", "elm");
676 _sizing_eval(WIDGET(it));
680 _item_content_unset(Elm_Naviframe_Item *it)
682 Evas_Object *content = it->content;
683 if (!content) return NULL;
685 elm_object_part_content_unset(VIEW(it), "elm.swallow.content");
686 elm_object_signal_emit(VIEW(it), "elm,state,content,hide", "elm");
687 evas_object_event_callback_del(content,
690 _sizing_eval(WIDGET(it));
697 _title_prev_btn_unset(Elm_Naviframe_Item *it)
699 Evas_Object *content = it->title_prev_btn;
700 if (!content) return NULL;
702 elm_object_part_content_unset(VIEW(it), "elm.swallow.prev_btn");
703 elm_object_signal_emit(VIEW(it), "elm,state,prev_btn,hide", "elm");
704 evas_object_event_callback_del(content,
706 _title_prev_btn_del);
707 _sizing_eval(WIDGET(it));
709 it->title_prev_btn = NULL;
714 _title_next_btn_unset(Elm_Naviframe_Item *it)
716 Evas_Object *content = it->title_next_btn;
717 if (!content) return NULL;
719 elm_object_part_content_unset(VIEW(it), "elm.swallow.next_btn");
720 elm_object_signal_emit(VIEW(it), "elm,state,next_btn,hide", "elm");
721 evas_object_event_callback_del(content,
723 _title_next_btn_del);
724 _sizing_eval(WIDGET(it));
726 it->title_next_btn = NULL;
731 _title_icon_unset(Elm_Naviframe_Item *it)
733 Evas_Object *content = it->title_icon;
734 if (!content) return NULL;
736 elm_object_part_content_unset(VIEW(it), "elm.swallow.icon");
737 elm_object_signal_emit(VIEW(it), "elm,state,icon,hide", "elm");
738 evas_object_event_callback_del(content,
741 _sizing_eval(WIDGET(it));
742 it->title_icon = NULL;
748 _title_content_unset(Elm_Naviframe_Item *it, const char *part)
750 Elm_Naviframe_Content_Item_Pair *pair = NULL;
752 Evas_Object *content = NULL;
754 EINA_INLIST_FOREACH(it->content_list, pair)
756 if (!strcmp(part, pair->part))
758 content = elm_object_part_content_get(VIEW(it), part);
759 eina_stringshare_del(pair->part);
760 it->content_list = eina_inlist_remove(it->content_list,
761 EINA_INLIST_GET(pair));
767 if (!content) return NULL;
769 elm_object_part_content_unset(VIEW(it), part);
770 snprintf(buf, sizeof(buf), "elm,state,%s,hide", part);
771 elm_object_signal_emit(VIEW(it), buf, "elm");
772 evas_object_event_callback_del(content,
775 _sizing_eval(WIDGET(it));
781 _item_del(Elm_Naviframe_Item *it)
784 Elm_Naviframe_Content_Item_Pair *content_pair;
785 Elm_Naviframe_Text_Item_Pair *text_pair;
786 Evas_Object *content;
790 wd = elm_widget_data_get(WIDGET(it));
793 while (it->content_list)
796 EINA_INLIST_CONTAINER_GET(it->content_list,
797 Elm_Naviframe_Content_Item_Pair);
798 content = elm_object_part_content_get(VIEW(it), content_pair->part);
799 evas_object_event_callback_del(content,
802 eina_stringshare_del(content_pair->part);
803 it->content_list = eina_inlist_remove(it->content_list,
808 while (it->text_list)
810 text_pair = EINA_INLIST_CONTAINER_GET(it->text_list,
811 Elm_Naviframe_Text_Item_Pair);
812 eina_stringshare_del(text_pair->part);
813 it->text_list = eina_inlist_remove(it->text_list,
818 eina_stringshare_del(it->style);
820 if (wd->preserve && it->content)
822 elm_object_part_content_unset(VIEW(it), "elm.swallow.content");
823 evas_object_event_callback_del(it->content,
830 _item_del_pre_hook(Elm_Object_Item *it)
832 Elm_Naviframe_Item *navi_it;
835 navi_it =(Elm_Naviframe_Item *)it;
836 wd = elm_widget_data_get(WIDGET(navi_it));
837 if (!wd) return EINA_FALSE;
839 if (it == elm_naviframe_top_item_get(WIDGET(navi_it)))
841 wd->stack = eina_inlist_remove(wd->stack, EINA_INLIST_GET(navi_it));
843 //If the item is only one, the stack will be empty
844 if (!wd->stack) return EINA_TRUE;
845 navi_it = EINA_INLIST_CONTAINER_GET(wd->stack->last,
847 evas_object_show(VIEW(navi_it));
848 evas_object_raise(VIEW(navi_it));
849 elm_object_signal_emit(VIEW(navi_it), "elm,state,visible", "elm");
853 wd->stack = eina_inlist_remove(wd->stack, EINA_INLIST_GET(navi_it));
861 _pushed_finished(void *data,
862 Evas_Object *obj __UNUSED__,
863 const char *emission __UNUSED__,
864 const char *source __UNUSED__)
867 Elm_Naviframe_Item *it = data;
870 wd = elm_widget_data_get(WIDGET(it));
873 evas_object_hide(VIEW(it));
876 elm_widget_tree_unfocusable_set(it->content, it->content_unfocusable);
878 if (wd->freeze_events)
879 evas_object_freeze_events_set(VIEW(it), EINA_FALSE);
883 _popped_finished(void *data,
884 Evas_Object *obj __UNUSED__,
885 const char *emission __UNUSED__,
886 const char *source __UNUSED__)
889 Elm_Naviframe_Item *it = data;
892 wd = elm_widget_data_get(WIDGET(it));
895 if (wd->preserve && it->content)
896 elm_widget_tree_unfocusable_set(it->content, it->content_unfocusable);
900 elm_widget_item_free(data);
904 _show_finished(void *data,
905 Evas_Object *obj __UNUSED__,
906 const char *emission __UNUSED__,
907 const char *source __UNUSED__)
909 Elm_Naviframe_Item *it;
914 wd = elm_widget_data_get(WIDGET(it));
917 elm_widget_tree_unfocusable_set(it->content, it->content_unfocusable);
919 evas_object_smart_callback_call(WIDGET(it),
920 SIG_TRANSITION_FINISHED,
922 if (wd->freeze_events)
923 evas_object_freeze_events_set(VIEW(it), EINA_FALSE);
927 _changed_size_hints(void *data,
929 Evas_Object *obj __UNUSED__,
930 void *event_info __UNUSED__)
936 _item_content_set(Elm_Naviframe_Item *navi_it, Evas_Object *content)
938 if (navi_it->content == content) return;
939 if (navi_it->content) evas_object_del(navi_it->content);
940 elm_object_part_content_set(VIEW(navi_it), "elm.swallow.content", content);
943 elm_object_signal_emit(VIEW(navi_it), "elm,state,content,show", "elm");
945 elm_object_signal_emit(VIEW(navi_it), "elm,state,content,hide", "elm");
947 evas_object_event_callback_add(content,
951 navi_it->content = content;
952 _sizing_eval(WIDGET(navi_it));
955 //FIXME: need to handle if this function is called while transition
957 _item_style_set(Elm_Naviframe_Item *navi_it, const char *item_style)
959 Elm_Naviframe_Content_Item_Pair *content_pair;
960 Elm_Naviframe_Text_Item_Pair *text_pair;
967 strcpy(buf, "item/basic");
968 eina_stringshare_replace(&navi_it->style, "basic");
972 snprintf(buf, sizeof(buf), "item/%s", item_style);
973 eina_stringshare_replace(&navi_it->style, item_style);
975 elm_layout_theme_set(VIEW(navi_it),
978 elm_widget_style_get(WIDGET(navi_it)));
980 EINA_INLIST_FOREACH(navi_it->text_list, text_pair)
981 _item_text_set_hook((Elm_Object_Item *) navi_it,
983 elm_object_part_text_get(VIEW(navi_it),
986 EINA_INLIST_FOREACH(navi_it->content_list, content_pair)
987 _item_content_set_hook((Elm_Object_Item *) navi_it,
989 elm_object_part_content_get(VIEW(navi_it),
990 content_pair->part));
992 if (navi_it->content)
993 elm_object_signal_emit(VIEW(navi_it), "elm,state,content,show", "elm");
996 if (navi_it->title_prev_btn)
997 elm_object_signal_emit(VIEW(navi_it), "elm,state,prev_btn,show", "elm");
1000 if (navi_it->title_next_btn)
1001 elm_object_signal_emit(VIEW(navi_it), "elm,state,next_btn,show", "elm");
1003 // why does this forcibly enable title? isnt that separate to style?
1004 // navi_it->title_visible = EINA_TRUE;
1005 _sizing_eval(WIDGET(navi_it));
1007 wd = elm_widget_data_get(WIDGET(navi_it));
1010 if (wd->freeze_events)
1011 evas_object_freeze_events_set(VIEW(navi_it), EINA_FALSE);
1014 static Elm_Naviframe_Item *
1015 _item_new(Evas_Object *obj,
1016 const char *title_label,
1017 Evas_Object *prev_btn,
1018 Evas_Object *next_btn,
1019 Evas_Object *content,
1020 const char *item_style)
1022 Widget_Data *wd = elm_widget_data_get(obj);
1025 Elm_Naviframe_Item *it = elm_widget_item_new(obj, Elm_Naviframe_Item);
1028 ERR("Failed to allocate new item! : naviframe=%p", obj);
1032 elm_widget_item_del_pre_hook_set(it, _item_del_pre_hook);
1033 elm_widget_item_text_set_hook_set(it, _item_text_set_hook);
1034 elm_widget_item_text_get_hook_set(it, _item_text_get_hook);
1035 elm_widget_item_content_set_hook_set(it, _item_content_set_hook);
1036 elm_widget_item_content_get_hook_set(it, _item_content_get_hook);
1037 elm_widget_item_content_unset_hook_set(it, _item_content_unset_hook);
1038 elm_widget_item_signal_emit_hook_set(it, _item_signal_emit_hook);
1041 VIEW(it) = elm_layout_add(obj);
1042 evas_object_smart_member_add(VIEW(it), wd->base);
1044 evas_object_event_callback_add(VIEW(it),
1045 EVAS_CALLBACK_CHANGED_SIZE_HINTS,
1046 _changed_size_hints,
1048 elm_object_signal_callback_add(VIEW(it),
1049 "elm,action,show,finished",
1051 _show_finished, it);
1052 elm_object_signal_callback_add(VIEW(it),
1053 "elm,action,pushed,finished",
1055 _pushed_finished, it);
1056 elm_object_signal_callback_add(VIEW(it),
1057 "elm,action,popped,finished",
1059 _popped_finished, it);
1060 elm_object_signal_callback_add(VIEW(it),
1061 "elm,action,title,clicked",
1063 _title_clicked, it);
1065 _item_style_set(it, item_style);
1066 _item_text_set_hook((Elm_Object_Item *)it, "elm.text.title", title_label);
1069 if ((!prev_btn) && wd->auto_pushed && eina_inlist_count(wd->stack))
1071 prev_btn = _back_btn_new(obj);
1072 _title_prev_btn_set(it, prev_btn, EINA_TRUE);
1075 _title_prev_btn_set(it, prev_btn, EINA_FALSE);
1077 _title_next_btn_set(it, next_btn);
1078 _item_content_set(it, content);
1079 it->title_visible = EINA_TRUE;
1084 _focus_next_hook(const Evas_Object *obj, Elm_Focus_Direction dir, Evas_Object **next)
1087 Elm_Naviframe_Item *top_it;
1088 Eina_List *l = NULL;
1089 Widget_Data *wd = elm_widget_data_get(obj);
1090 void *(*list_data_get)(const Eina_List *list);
1091 if (!wd) return EINA_FALSE;
1093 top_it = (Elm_Naviframe_Item *)elm_naviframe_top_item_get(obj);
1094 if (!top_it) return EINA_FALSE;
1096 list_data_get = eina_list_data_get;
1098 //Forcus order: prev button, next button, contents
1099 if (top_it->title_prev_btn)
1100 l = eina_list_append(l, top_it->title_prev_btn);
1101 if (top_it->title_next_btn)
1102 l = eina_list_append(l, top_it->title_next_btn);
1103 l = eina_list_append(l, VIEW(top_it));
1105 ret = elm_widget_focus_list_next_get(obj, l, list_data_get, dir, next);
1111 elm_naviframe_add(Evas_Object *parent)
1117 ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL);
1118 ELM_SET_WIDTYPE(widtype, "naviframe");
1119 elm_widget_type_set(obj, "naviframe");
1120 elm_widget_sub_object_add(parent, obj);
1121 elm_widget_data_set(obj, wd);
1122 elm_widget_del_hook_set(obj, _del_hook);
1123 elm_widget_disable_hook_set(obj, _disable_hook);
1124 elm_widget_theme_hook_set(obj, _theme_hook);
1125 elm_widget_text_set_hook_set(obj, _text_set_hook);
1126 elm_widget_text_get_hook_set(obj, _text_get_hook);
1127 elm_widget_content_set_hook_set(obj, _content_set_hook);
1128 elm_widget_content_get_hook_set(obj, _content_get_hook);
1129 elm_widget_content_unset_hook_set(obj, _content_unset_hook);
1130 elm_widget_signal_emit_hook_set(obj, _emit_hook);
1131 elm_widget_can_focus_set(obj, EINA_FALSE);
1132 elm_widget_focus_next_hook_set(obj, _focus_next_hook);
1135 //FIXME: Is this base layout really needed?
1136 wd->base = elm_layout_add(parent);
1137 evas_object_event_callback_add(wd->base,
1138 EVAS_CALLBACK_CHANGED_SIZE_HINTS,
1139 _changed_size_hints,
1141 elm_widget_resize_object_set(obj, wd->base);
1142 elm_layout_theme_set(wd->base, "naviframe", "base", "default");
1144 evas_object_event_callback_add(obj, EVAS_CALLBACK_MOVE, _move, obj);
1145 evas_object_event_callback_add(obj, EVAS_CALLBACK_RESIZE, _resize, obj);
1146 evas_object_smart_callbacks_descriptions_set(obj, _signals);
1148 wd->auto_pushed = EINA_TRUE;
1149 wd->freeze_events = EINA_TRUE;
1154 EAPI Elm_Object_Item *
1155 elm_naviframe_item_push(Evas_Object *obj,
1156 const char *title_label,
1157 Evas_Object *prev_btn,
1158 Evas_Object *next_btn,
1159 Evas_Object *content,
1160 const char *item_style)
1162 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1164 Elm_Naviframe_Item *prev_it, *it;
1166 wd = elm_widget_data_get(obj);
1167 if (!wd) return NULL;
1169 it = _item_new(obj, title_label, prev_btn, next_btn, content, item_style);
1170 if (!it) return NULL;
1172 evas_object_show(VIEW(it));
1174 prev_it = (Elm_Naviframe_Item *) elm_naviframe_top_item_get(obj);
1177 if (wd->freeze_events)
1179 evas_object_freeze_events_set(VIEW(it), EINA_TRUE);
1180 evas_object_freeze_events_set(VIEW(prev_it), EINA_TRUE);
1182 elm_object_signal_emit(VIEW(prev_it), "elm,state,cur,pushed", "elm");
1183 elm_object_signal_emit(VIEW(it), "elm,state,new,pushed", "elm");
1184 edje_object_message_signal_process(elm_layout_edje_get(VIEW(prev_it)));
1185 if (prev_it->content)
1187 prev_it->content_unfocusable = elm_widget_tree_unfocusable_get(prev_it->content);
1188 elm_widget_tree_unfocusable_set(prev_it->content, EINA_TRUE);
1190 edje_object_message_signal_process(elm_layout_edje_get(VIEW(it)));
1192 wd->stack = eina_inlist_append(wd->stack, EINA_INLIST_GET(it));
1194 return (Elm_Object_Item *)it;
1197 EAPI Elm_Object_Item *
1198 elm_naviframe_item_insert_before(Evas_Object *obj,
1199 Elm_Object_Item *before,
1200 const char *title_label,
1201 Evas_Object *prev_btn,
1202 Evas_Object *next_btn,
1203 Evas_Object *content,
1204 const char *item_style)
1206 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1207 ELM_OBJ_ITEM_CHECK_OR_RETURN(before, NULL);
1208 Elm_Naviframe_Item *it;
1211 wd = elm_widget_data_get(obj);
1212 if (!wd) return NULL;
1214 it = _item_new(obj, title_label, prev_btn, next_btn, content, item_style);
1215 if (!it) return NULL;
1218 eina_inlist_prepend_relative(wd->stack,
1219 EINA_INLIST_GET(it),
1220 EINA_INLIST_GET(((Elm_Naviframe_Item *) before)));
1222 return (Elm_Object_Item *)it;
1225 EAPI Elm_Object_Item *
1226 elm_naviframe_item_insert_after(Evas_Object *obj,
1227 Elm_Object_Item *after,
1228 const char *title_label,
1229 Evas_Object *prev_btn,
1230 Evas_Object *next_btn,
1231 Evas_Object *content,
1232 const char *item_style)
1234 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1235 ELM_OBJ_ITEM_CHECK_OR_RETURN(after, NULL);
1236 Elm_Naviframe_Item *it;
1238 Eina_Bool top_inserted;
1240 wd = elm_widget_data_get(obj);
1241 if (!wd) return NULL;
1243 it = _item_new(obj, title_label, prev_btn, next_btn, content, item_style);
1244 if (!it) return NULL;
1246 if (elm_naviframe_top_item_get(obj) == after) top_inserted = EINA_TRUE;
1249 eina_inlist_append_relative(wd->stack,
1250 EINA_INLIST_GET(it),
1251 EINA_INLIST_GET(((Elm_Naviframe_Item *) after)));
1254 evas_object_show(VIEW(it));
1255 evas_object_hide(VIEW(after));
1260 return (Elm_Object_Item *)it;
1264 elm_naviframe_item_pop(Evas_Object *obj)
1266 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1267 Elm_Naviframe_Item *it, *prev_it = NULL;
1269 Evas_Object *content = NULL;
1271 wd = elm_widget_data_get(obj);
1272 if (!wd) return NULL;
1274 it = (Elm_Naviframe_Item *) elm_naviframe_top_item_get(obj);
1275 if (!it) return NULL;
1277 content = it->content;
1281 it->content_unfocusable = elm_widget_tree_unfocusable_get(it->content);
1282 elm_widget_tree_unfocusable_set(it->content, EINA_TRUE);
1285 if (wd->stack->last->prev)
1286 prev_it = EINA_INLIST_CONTAINER_GET(wd->stack->last->prev,
1287 Elm_Naviframe_Item);
1288 wd->stack = eina_inlist_remove(wd->stack, EINA_INLIST_GET(it));
1291 if (wd->freeze_events)
1293 evas_object_freeze_events_set(VIEW(it), EINA_TRUE);
1294 evas_object_freeze_events_set(VIEW(prev_it), EINA_TRUE);
1296 elm_object_signal_emit(VIEW(it), "elm,state,cur,popped", "elm");
1297 evas_object_show(VIEW(prev_it));
1298 elm_object_signal_emit(VIEW(prev_it),
1299 "elm,state,prev,popped",
1301 edje_object_message_signal_process(elm_layout_edje_get(VIEW(it)));
1302 edje_object_message_signal_process(elm_layout_edje_get(VIEW(prev_it)));
1307 elm_widget_item_free(it);
1314 elm_naviframe_item_pop_to(Elm_Object_Item *it)
1316 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1317 Elm_Naviframe_Item *navi_it;
1319 Eina_Inlist *l, *prev_l;
1321 navi_it = (Elm_Naviframe_Item *)it;
1322 wd = elm_widget_data_get(WIDGET(navi_it));
1325 if (it == elm_naviframe_top_item_get(WIDGET(navi_it))) return;
1327 l = wd->stack->last->prev;
1331 if (EINA_INLIST_CONTAINER_GET(l, Elm_Naviframe_Item) ==
1332 ((Elm_Naviframe_Item *)it)) break;
1334 wd->stack = eina_inlist_remove(wd->stack, l);
1335 _item_del(EINA_INLIST_CONTAINER_GET(l, Elm_Naviframe_Item));
1336 elm_widget_item_free(EINA_INLIST_CONTAINER_GET(l,
1337 Elm_Naviframe_Item));
1340 elm_naviframe_item_pop(WIDGET(navi_it));
1344 elm_naviframe_item_promote(Elm_Object_Item *it)
1346 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1347 Elm_Naviframe_Item *navi_it;
1348 Elm_Naviframe_Item *prev_it;
1351 navi_it = (Elm_Naviframe_Item *)it;
1352 wd = elm_widget_data_get(navi_it->base.widget);
1355 if (it == elm_naviframe_top_item_get(navi_it->base.widget)) return;
1356 wd->stack = eina_inlist_demote(wd->stack, EINA_INLIST_GET(navi_it));
1357 prev_it = EINA_INLIST_CONTAINER_GET(wd->stack->last->prev,
1358 Elm_Naviframe_Item);
1359 if (prev_it->content)
1361 prev_it->content_unfocusable = elm_widget_tree_unfocusable_get(prev_it->content);
1362 elm_widget_tree_unfocusable_set(prev_it->content, EINA_TRUE);
1365 if (wd->freeze_events)
1367 evas_object_freeze_events_set(VIEW(it), EINA_TRUE);
1368 evas_object_freeze_events_set(VIEW(prev_it), EINA_TRUE);
1370 elm_object_signal_emit(VIEW(prev_it),
1371 "elm,state,cur,pushed",
1373 evas_object_show(VIEW(navi_it));
1374 evas_object_raise(VIEW(navi_it));
1375 elm_object_signal_emit(VIEW(navi_it),
1376 "elm,state,new,pushed",
1378 edje_object_message_signal_process(elm_layout_edje_get(VIEW(prev_it)));
1379 edje_object_message_signal_process(elm_layout_edje_get(VIEW(navi_it)));
1383 elm_naviframe_item_simple_promote(Evas_Object *obj, Evas_Object *content)
1385 ELM_CHECK_WIDTYPE(obj, widtype);
1386 Widget_Data *wd = elm_widget_data_get(obj);
1388 Elm_Naviframe_Item *itr;
1389 EINA_INLIST_FOREACH(wd->stack, itr)
1391 if (elm_object_item_content_get((Elm_Object_Item *)itr) == content)
1393 elm_naviframe_item_promote((Elm_Object_Item *)itr);
1401 elm_naviframe_content_preserve_on_pop_set(Evas_Object *obj, Eina_Bool preserve)
1403 ELM_CHECK_WIDTYPE(obj, widtype);
1404 Widget_Data *wd = elm_widget_data_get(obj);
1406 wd->preserve = !!preserve;
1410 elm_naviframe_content_preserve_on_pop_get(const Evas_Object *obj)
1412 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
1413 Widget_Data *wd = elm_widget_data_get(obj);
1414 if (!wd) return EINA_FALSE;
1415 return wd->preserve;
1418 EAPI Elm_Object_Item*
1419 elm_naviframe_top_item_get(const Evas_Object *obj)
1421 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1422 Widget_Data *wd = elm_widget_data_get(obj);
1423 if ((!wd) || (!wd->stack)) return NULL;
1424 return (Elm_Object_Item *) (EINA_INLIST_CONTAINER_GET(wd->stack->last,
1425 Elm_Naviframe_Item));
1428 EAPI Elm_Object_Item*
1429 elm_naviframe_bottom_item_get(const Evas_Object *obj)
1431 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1432 Widget_Data *wd = elm_widget_data_get(obj);
1433 if ((!wd) || (!wd->stack)) return NULL;
1434 return (Elm_Object_Item *) (EINA_INLIST_CONTAINER_GET(wd->stack,
1435 Elm_Naviframe_Item));
1439 elm_naviframe_item_style_set(Elm_Object_Item *it, const char *item_style)
1441 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1442 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *)it;
1445 if (!strcmp(item_style, navi_it->style)) return;
1448 if (!strcmp("basic", navi_it->style)) return;
1450 _item_style_set(navi_it, item_style);
1454 elm_naviframe_item_style_get(const Elm_Object_Item *it)
1456 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
1457 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *)it;
1458 return navi_it->style;
1462 elm_naviframe_item_title_visible_set(Elm_Object_Item *it, Eina_Bool visible)
1464 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1465 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *)it;
1467 visible = !!visible;
1468 if (navi_it->title_visible == visible) return;
1470 navi_it->title_visible = visible;
1471 _item_title_visible_update(navi_it);
1475 elm_naviframe_item_title_visible_get(const Elm_Object_Item *it)
1477 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
1478 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *)it;
1479 return navi_it->title_visible;
1483 elm_naviframe_prev_btn_auto_pushed_set(Evas_Object *obj, Eina_Bool auto_pushed)
1485 ELM_CHECK_WIDTYPE(obj, widtype);
1486 Widget_Data *wd = elm_widget_data_get(obj);
1488 wd->auto_pushed = !!auto_pushed;
1492 elm_naviframe_prev_btn_auto_pushed_get(const Evas_Object *obj)
1494 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
1495 Widget_Data *wd = elm_widget_data_get(obj);
1496 if (!wd) return EINA_FALSE;
1497 return wd->auto_pushed;
1501 elm_naviframe_items_get(const Evas_Object *obj)
1503 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1504 Widget_Data *wd = elm_widget_data_get(obj);
1505 if (!wd) return NULL;
1506 Eina_List *ret = NULL;
1507 Elm_Naviframe_Item *itr;
1508 EINA_INLIST_FOREACH(wd->stack, itr)
1509 ret = eina_list_append(ret, itr);
1514 elm_naviframe_event_enabled_set(Evas_Object *obj, Eina_Bool enabled)
1516 ELM_CHECK_WIDTYPE(obj, widtype);
1517 Widget_Data *wd = elm_widget_data_get(obj);
1519 enabled = !!enabled;
1520 if (wd->freeze_events == !enabled) return;
1521 wd->freeze_events = !enabled;
1525 elm_naviframe_event_enabled_get(const Evas_Object *obj)
1527 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
1528 Widget_Data *wd = elm_widget_data_get(obj);
1529 if (!wd) return EINA_FALSE;
1530 return !wd->freeze_events;