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 // FIXME : If current top's content is unfocusable, it should be restored as focusable.
904 // Similar cases are should be checked and should call following function.
905 if (elm_widget_tree_unfocusable_get(it->content))
906 elm_widget_tree_unfocusable_set(it->content, EINA_FALSE);
908 evas_object_smart_callback_call(WIDGET(it),
909 SIG_TRANSITION_FINISHED,
911 if (wd->freeze_events)
912 evas_object_freeze_events_set(VIEW(it), EINA_FALSE);
916 _changed_size_hints(void *data,
918 Evas_Object *obj __UNUSED__,
919 void *event_info __UNUSED__)
925 _item_content_set(Elm_Naviframe_Item *navi_it, Evas_Object *content)
927 if (navi_it->content == content) return;
928 if (navi_it->content) evas_object_del(navi_it->content);
929 elm_object_part_content_set(VIEW(navi_it), "elm.swallow.content", content);
932 elm_object_signal_emit(VIEW(navi_it), "elm,state,content,show", "elm");
934 elm_object_signal_emit(VIEW(navi_it), "elm,state,content,hide", "elm");
936 evas_object_event_callback_add(content,
940 navi_it->content = content;
941 _sizing_eval(WIDGET(navi_it));
944 //FIXME: need to handle if this function is called while transition
946 _item_style_set(Elm_Naviframe_Item *navi_it, const char *item_style)
948 Elm_Naviframe_Content_Item_Pair *content_pair;
949 Elm_Naviframe_Text_Item_Pair *text_pair;
956 strcpy(buf, "item/basic");
957 eina_stringshare_replace(&navi_it->style, "basic");
961 snprintf(buf, sizeof(buf), "item/%s", item_style);
962 eina_stringshare_replace(&navi_it->style, item_style);
964 elm_layout_theme_set(VIEW(navi_it),
967 elm_widget_style_get(WIDGET(navi_it)));
969 EINA_INLIST_FOREACH(navi_it->text_list, text_pair)
970 _item_text_set_hook((Elm_Object_Item *) navi_it,
972 elm_object_part_text_get(VIEW(navi_it),
975 EINA_INLIST_FOREACH(navi_it->content_list, content_pair)
976 _item_content_set_hook((Elm_Object_Item *) navi_it,
978 elm_object_part_content_get(VIEW(navi_it),
979 content_pair->part));
981 if (navi_it->content)
982 elm_object_signal_emit(VIEW(navi_it), "elm,state,content,show", "elm");
985 if (navi_it->title_prev_btn)
986 elm_object_signal_emit(VIEW(navi_it), "elm,state,prev_btn,show", "elm");
989 if (navi_it->title_next_btn)
990 elm_object_signal_emit(VIEW(navi_it), "elm,state,next_btn,show", "elm");
992 // why does this forcibly enable title? isnt that separate to style?
993 // navi_it->title_visible = EINA_TRUE;
994 _sizing_eval(WIDGET(navi_it));
996 wd = elm_widget_data_get(WIDGET(navi_it));
999 if (wd->freeze_events)
1000 evas_object_freeze_events_set(VIEW(navi_it), EINA_FALSE);
1003 static Elm_Naviframe_Item *
1004 _item_new(Evas_Object *obj,
1005 const char *title_label,
1006 Evas_Object *prev_btn,
1007 Evas_Object *next_btn,
1008 Evas_Object *content,
1009 const char *item_style)
1011 Widget_Data *wd = elm_widget_data_get(obj);
1014 Elm_Naviframe_Item *it = elm_widget_item_new(obj, Elm_Naviframe_Item);
1017 ERR("Failed to allocate new item! : naviframe=%p", obj);
1021 elm_widget_item_del_pre_hook_set(it, _item_del_pre_hook);
1022 elm_widget_item_text_set_hook_set(it, _item_text_set_hook);
1023 elm_widget_item_text_get_hook_set(it, _item_text_get_hook);
1024 elm_widget_item_content_set_hook_set(it, _item_content_set_hook);
1025 elm_widget_item_content_get_hook_set(it, _item_content_get_hook);
1026 elm_widget_item_content_unset_hook_set(it, _item_content_unset_hook);
1027 elm_widget_item_signal_emit_hook_set(it, _item_signal_emit_hook);
1030 VIEW(it) = elm_layout_add(obj);
1031 evas_object_smart_member_add(VIEW(it), wd->base);
1033 evas_object_event_callback_add(VIEW(it),
1034 EVAS_CALLBACK_CHANGED_SIZE_HINTS,
1035 _changed_size_hints,
1037 elm_object_signal_callback_add(VIEW(it),
1038 "elm,action,show,finished",
1040 _show_finished, it);
1041 elm_object_signal_callback_add(VIEW(it),
1042 "elm,action,pushed,finished",
1044 _pushed_finished, it);
1045 elm_object_signal_callback_add(VIEW(it),
1046 "elm,action,popped,finished",
1048 _popped_finished, it);
1049 elm_object_signal_callback_add(VIEW(it),
1050 "elm,action,title,clicked",
1052 _title_clicked, it);
1054 _item_style_set(it, item_style);
1055 _item_text_set_hook((Elm_Object_Item *)it, "elm.text.title", title_label);
1058 if ((!prev_btn) && wd->auto_pushed && eina_inlist_count(wd->stack))
1060 prev_btn = _back_btn_new(obj);
1061 _title_prev_btn_set(it, prev_btn, EINA_TRUE);
1064 _title_prev_btn_set(it, prev_btn, EINA_FALSE);
1066 _title_next_btn_set(it, next_btn);
1067 _item_content_set(it, content);
1068 it->title_visible = EINA_TRUE;
1073 _focus_next_hook(const Evas_Object *obj, Elm_Focus_Direction dir, Evas_Object **next)
1076 Elm_Naviframe_Item *top_it;
1077 Eina_List *l = NULL;
1078 Widget_Data *wd = elm_widget_data_get(obj);
1079 void *(*list_data_get)(const Eina_List *list);
1080 if (!wd) return EINA_FALSE;
1082 top_it = (Elm_Naviframe_Item *)elm_naviframe_top_item_get(obj);
1083 if (!top_it) return EINA_FALSE;
1085 list_data_get = eina_list_data_get;
1087 //Forcus order: prev button, next button, contents
1088 if (top_it->title_prev_btn)
1089 l = eina_list_append(l, top_it->title_prev_btn);
1090 if (top_it->title_next_btn)
1091 l = eina_list_append(l, top_it->title_next_btn);
1092 l = eina_list_append(l, VIEW(top_it));
1094 ret = elm_widget_focus_list_next_get(obj, l, list_data_get, dir, next);
1100 elm_naviframe_add(Evas_Object *parent)
1106 ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL);
1107 ELM_SET_WIDTYPE(widtype, "naviframe");
1108 elm_widget_type_set(obj, "naviframe");
1109 elm_widget_sub_object_add(parent, obj);
1110 elm_widget_data_set(obj, wd);
1111 elm_widget_del_hook_set(obj, _del_hook);
1112 elm_widget_disable_hook_set(obj, _disable_hook);
1113 elm_widget_theme_hook_set(obj, _theme_hook);
1114 elm_widget_text_set_hook_set(obj, _text_set_hook);
1115 elm_widget_text_get_hook_set(obj, _text_get_hook);
1116 elm_widget_content_set_hook_set(obj, _content_set_hook);
1117 elm_widget_content_get_hook_set(obj, _content_get_hook);
1118 elm_widget_content_unset_hook_set(obj, _content_unset_hook);
1119 elm_widget_signal_emit_hook_set(obj, _emit_hook);
1120 elm_widget_can_focus_set(obj, EINA_FALSE);
1121 elm_widget_focus_next_hook_set(obj, _focus_next_hook);
1124 //FIXME: Is this base layout really needed?
1125 wd->base = elm_layout_add(parent);
1126 evas_object_event_callback_add(wd->base,
1127 EVAS_CALLBACK_CHANGED_SIZE_HINTS,
1128 _changed_size_hints,
1130 elm_widget_resize_object_set(obj, wd->base);
1131 elm_layout_theme_set(wd->base, "naviframe", "base", "default");
1133 evas_object_event_callback_add(obj, EVAS_CALLBACK_MOVE, _move, obj);
1134 evas_object_event_callback_add(obj, EVAS_CALLBACK_RESIZE, _resize, obj);
1135 evas_object_smart_callbacks_descriptions_set(obj, _signals);
1137 wd->auto_pushed = EINA_TRUE;
1138 wd->freeze_events = EINA_TRUE;
1143 EAPI Elm_Object_Item *
1144 elm_naviframe_item_push(Evas_Object *obj,
1145 const char *title_label,
1146 Evas_Object *prev_btn,
1147 Evas_Object *next_btn,
1148 Evas_Object *content,
1149 const char *item_style)
1151 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1153 Elm_Naviframe_Item *prev_it, *it;
1155 wd = elm_widget_data_get(obj);
1156 if (!wd) return NULL;
1158 it = _item_new(obj, title_label, prev_btn, next_btn, content, item_style);
1159 if (!it) return NULL;
1161 evas_object_show(VIEW(it));
1163 prev_it = (Elm_Naviframe_Item *) elm_naviframe_top_item_get(obj);
1166 if (wd->freeze_events)
1168 evas_object_freeze_events_set(VIEW(it), EINA_TRUE);
1169 evas_object_freeze_events_set(VIEW(prev_it), EINA_TRUE);
1171 elm_object_signal_emit(VIEW(prev_it), "elm,state,cur,pushed", "elm");
1172 elm_object_signal_emit(VIEW(it), "elm,state,new,pushed", "elm");
1173 edje_object_message_signal_process(elm_layout_edje_get(VIEW(prev_it)));
1174 elm_widget_tree_unfocusable_set(prev_it->content, EINA_TRUE);
1175 edje_object_message_signal_process(elm_layout_edje_get(VIEW(it)));
1177 wd->stack = eina_inlist_append(wd->stack, EINA_INLIST_GET(it));
1179 return (Elm_Object_Item *)it;
1182 EAPI Elm_Object_Item *
1183 elm_naviframe_item_insert_before(Evas_Object *obj,
1184 Elm_Object_Item *before,
1185 const char *title_label,
1186 Evas_Object *prev_btn,
1187 Evas_Object *next_btn,
1188 Evas_Object *content,
1189 const char *item_style)
1191 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1192 ELM_OBJ_ITEM_CHECK_OR_RETURN(before, NULL);
1193 Elm_Naviframe_Item *it;
1196 wd = elm_widget_data_get(obj);
1197 if (!wd) return NULL;
1199 it = _item_new(WIDGET(before), title_label, prev_btn, next_btn, content,
1201 if (!it) return NULL;
1204 eina_inlist_prepend_relative(wd->stack,
1205 EINA_INLIST_GET(it),
1206 EINA_INLIST_GET(((Elm_Naviframe_Item *) before)));
1207 _sizing_eval(WIDGET(before));
1208 return (Elm_Object_Item *)it;
1211 EAPI Elm_Object_Item *
1212 elm_naviframe_item_insert_after(Evas_Object *obj,
1213 Elm_Object_Item *after,
1214 const char *title_label,
1215 Evas_Object *prev_btn,
1216 Evas_Object *next_btn,
1217 Evas_Object *content,
1218 const char *item_style)
1220 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1221 ELM_OBJ_ITEM_CHECK_OR_RETURN(after, NULL);
1222 Elm_Naviframe_Item *it;
1225 wd = elm_widget_data_get(obj);
1226 if (!wd) return NULL;
1228 it = _item_new(WIDGET(after), title_label, prev_btn, next_btn, content,
1230 if (!it) return NULL;
1232 if (elm_naviframe_top_item_get(WIDGET(after)) == after)
1234 evas_object_hide(VIEW(after));
1235 evas_object_show(VIEW(it));
1238 eina_inlist_append_relative(wd->stack,
1239 EINA_INLIST_GET(it),
1240 EINA_INLIST_GET(((Elm_Naviframe_Item *) after)));
1241 _sizing_eval(WIDGET(after));
1242 return (Elm_Object_Item *)it;
1246 elm_naviframe_item_pop(Evas_Object *obj)
1248 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1249 Elm_Naviframe_Item *it, *prev_it = NULL;
1251 Evas_Object *content = NULL;
1253 wd = elm_widget_data_get(obj);
1254 if (!wd) return NULL;
1256 it = (Elm_Naviframe_Item *) elm_naviframe_top_item_get(obj);
1257 if (!it) return NULL;
1259 content = it->content;
1261 elm_widget_tree_unfocusable_set(it->content, EINA_TRUE);
1263 if (wd->stack->last->prev)
1264 prev_it = EINA_INLIST_CONTAINER_GET(wd->stack->last->prev,
1265 Elm_Naviframe_Item);
1266 wd->stack = eina_inlist_remove(wd->stack, EINA_INLIST_GET(it));
1269 if (wd->freeze_events)
1271 evas_object_freeze_events_set(VIEW(it), EINA_TRUE);
1272 evas_object_freeze_events_set(VIEW(prev_it), EINA_TRUE);
1274 elm_object_signal_emit(VIEW(it), "elm,state,cur,popped", "elm");
1275 evas_object_show(VIEW(prev_it));
1276 evas_object_raise(VIEW(prev_it));
1277 elm_object_signal_emit(VIEW(prev_it),
1278 "elm,state,prev,popped",
1280 edje_object_message_signal_process(elm_layout_edje_get(VIEW(it)));
1281 edje_object_message_signal_process(elm_layout_edje_get(VIEW(prev_it)));
1286 elm_widget_item_free(it);
1293 elm_naviframe_item_pop_to(Elm_Object_Item *it)
1295 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1296 Elm_Naviframe_Item *navi_it;
1298 Eina_Inlist *l, *prev_l;
1300 navi_it = (Elm_Naviframe_Item *)it;
1301 wd = elm_widget_data_get(WIDGET(navi_it));
1304 if (it == elm_naviframe_top_item_get(WIDGET(navi_it))) return;
1306 l = wd->stack->last->prev;
1310 if (EINA_INLIST_CONTAINER_GET(l, Elm_Naviframe_Item) ==
1311 ((Elm_Naviframe_Item *)it)) break;
1313 wd->stack = eina_inlist_remove(wd->stack, l);
1314 _item_del(EINA_INLIST_CONTAINER_GET(l, Elm_Naviframe_Item));
1315 elm_widget_item_free(EINA_INLIST_CONTAINER_GET(l,
1316 Elm_Naviframe_Item));
1319 elm_naviframe_item_pop(WIDGET(navi_it));
1323 elm_naviframe_item_promote(Elm_Object_Item *it)
1325 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1326 Elm_Naviframe_Item *navi_it;
1327 Elm_Naviframe_Item *prev_it;
1330 navi_it = (Elm_Naviframe_Item *)it;
1331 wd = elm_widget_data_get(navi_it->base.widget);
1334 if (it == elm_naviframe_top_item_get(navi_it->base.widget)) return;
1335 elm_widget_tree_unfocusable_set(navi_it->content, EINA_FALSE);
1336 wd->stack = eina_inlist_demote(wd->stack, EINA_INLIST_GET(navi_it));
1337 prev_it = EINA_INLIST_CONTAINER_GET(wd->stack->last->prev,
1338 Elm_Naviframe_Item);
1339 elm_widget_tree_unfocusable_set(prev_it->content, EINA_FALSE);
1340 if (wd->freeze_events)
1342 evas_object_freeze_events_set(VIEW(it), EINA_TRUE);
1343 evas_object_freeze_events_set(VIEW(prev_it), EINA_TRUE);
1345 elm_object_signal_emit(VIEW(prev_it),
1346 "elm,state,cur,pushed",
1348 evas_object_show(VIEW(navi_it));
1349 evas_object_raise(VIEW(navi_it));
1350 elm_object_signal_emit(VIEW(navi_it),
1351 "elm,state,new,pushed",
1353 edje_object_message_signal_process(elm_layout_edje_get(VIEW(prev_it)));
1354 edje_object_message_signal_process(elm_layout_edje_get(VIEW(navi_it)));
1358 elm_naviframe_item_simple_promote(Evas_Object *obj, Evas_Object *content)
1360 ELM_CHECK_WIDTYPE(obj, widtype);
1361 Widget_Data *wd = elm_widget_data_get(obj);
1363 Elm_Naviframe_Item *itr;
1364 EINA_INLIST_FOREACH(wd->stack, itr)
1366 if (elm_object_item_content_get((Elm_Object_Item *)itr) == content)
1368 elm_naviframe_item_promote((Elm_Object_Item *)itr);
1376 elm_naviframe_content_preserve_on_pop_set(Evas_Object *obj, Eina_Bool preserve)
1378 ELM_CHECK_WIDTYPE(obj, widtype);
1379 Widget_Data *wd = elm_widget_data_get(obj);
1381 wd->preserve = !!preserve;
1385 elm_naviframe_content_preserve_on_pop_get(const Evas_Object *obj)
1387 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
1388 Widget_Data *wd = elm_widget_data_get(obj);
1389 if (!wd) return EINA_FALSE;
1390 return wd->preserve;
1393 EAPI Elm_Object_Item*
1394 elm_naviframe_top_item_get(const Evas_Object *obj)
1396 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1397 Widget_Data *wd = elm_widget_data_get(obj);
1398 if ((!wd) || (!wd->stack)) return NULL;
1399 return (Elm_Object_Item *) (EINA_INLIST_CONTAINER_GET(wd->stack->last,
1400 Elm_Naviframe_Item));
1403 EAPI Elm_Object_Item*
1404 elm_naviframe_bottom_item_get(const Evas_Object *obj)
1406 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1407 Widget_Data *wd = elm_widget_data_get(obj);
1408 if ((!wd) || (!wd->stack)) return NULL;
1409 return (Elm_Object_Item *) (EINA_INLIST_CONTAINER_GET(wd->stack,
1410 Elm_Naviframe_Item));
1414 elm_naviframe_item_style_set(Elm_Object_Item *it, const char *item_style)
1416 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1417 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *)it;
1420 if (!strcmp(item_style, navi_it->style)) return;
1423 if (!strcmp("basic", navi_it->style)) return;
1425 _item_style_set(navi_it, item_style);
1429 elm_naviframe_item_style_get(const Elm_Object_Item *it)
1431 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
1432 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *)it;
1433 return navi_it->style;
1437 elm_naviframe_item_title_visible_set(Elm_Object_Item *it, Eina_Bool visible)
1439 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1440 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *)it;
1442 visible = !!visible;
1443 if (navi_it->title_visible == visible) return;
1445 navi_it->title_visible = visible;
1446 _item_title_visible_update(navi_it);
1450 elm_naviframe_item_title_visible_get(const Elm_Object_Item *it)
1452 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
1453 Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *)it;
1454 return navi_it->title_visible;
1458 elm_naviframe_prev_btn_auto_pushed_set(Evas_Object *obj, Eina_Bool auto_pushed)
1460 ELM_CHECK_WIDTYPE(obj, widtype);
1461 Widget_Data *wd = elm_widget_data_get(obj);
1463 wd->auto_pushed = !!auto_pushed;
1467 elm_naviframe_prev_btn_auto_pushed_get(const Evas_Object *obj)
1469 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
1470 Widget_Data *wd = elm_widget_data_get(obj);
1471 if (!wd) return EINA_FALSE;
1472 return wd->auto_pushed;
1476 elm_naviframe_items_get(const Evas_Object *obj)
1478 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1479 Widget_Data *wd = elm_widget_data_get(obj);
1480 if (!wd) return NULL;
1481 Eina_List *ret = NULL;
1482 Elm_Naviframe_Item *itr;
1483 EINA_INLIST_FOREACH(wd->stack, itr)
1484 ret = eina_list_append(ret, itr);
1489 elm_naviframe_event_enabled_set(Evas_Object *obj, Eina_Bool enabled)
1491 ELM_CHECK_WIDTYPE(obj, widtype);
1492 Widget_Data *wd = elm_widget_data_get(obj);
1494 enabled = !!enabled;
1495 if (wd->freeze_events == !enabled) return;
1496 wd->freeze_events = !enabled;
1500 elm_naviframe_event_enabled_get(const Evas_Object *obj)
1502 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
1503 Widget_Data *wd = elm_widget_data_get(obj);
1504 if (!wd) return EINA_FALSE;
1505 return !wd->freeze_events;