1 #include <Elementary.h>
5 * @defgroup NavigationBar NavigationBar
8 * The Navigationbar is an object that allows flipping (with animation) between 1 or
9 * more of objects, much like a stack of windows within the window. It also displays title
10 * area above all the pages consisting of title,function buttons.
12 * Objects can be pushed or popped from the stack.
13 * Pushes and pops will animate (and a pop will delete the object once the
14 * animation is finished). Objects are pushed to the top with
15 * elm_navigationbar_push() and when the top item is no longer
16 * wanted, simply pop it with elm_navigationbar_pop() and it will also be
17 * deleted. You can query which objects are the top and bottom with
18 * elm_navigationbar_content_bottom_get() and elm_navigationbar_content_top_get().
21 #define _ELM_NAVIBAR_PREV_BTN_DEFAULT_LABEL "Previous"
23 typedef struct _Widget_Data Widget_Data;
24 typedef struct _Elm_Navigationbar_Item Elm_Navigationbar_Item;
25 typedef struct _Transit_Cb_Data Transit_Cb_Data;
27 static const char _navigationbar_key[] = "_elm_navigationbar";
32 ELM_NAVIGATIONBAR_PREV_BUTTON = ELM_NAVIGATIONBAR_FUNCTION_BUTTON1,
33 ELM_NAVIGATIONBAR_NEXT_BUTTON = ELM_NAVIGATIONBAR_FUNCTION_BUTTON2,
34 ELM_NAVIGATIONBAR_TITLE_BTN_CNT = 2
35 } Elm_Navigationbar_Button_Type;
42 Eina_Bool title_visible : 1;
46 struct _Elm_Navigationbar_Item
51 Eina_List *title_obj_list; //TODO: Remove!
52 Evas_Object *title_obj;
53 Evas_Object *title_btns[ELM_NAVIGATIONBAR_TITLE_BTN_CNT];
56 Eina_Bool titleobj_visible :1;
57 Eina_Bool back_btn :1;
61 struct _Transit_Cb_Data
63 Elm_Navigationbar_Item* prev_it;
64 Elm_Navigationbar_Item* it;
67 Eina_Bool first_page : 1;
70 static const char *widtype = NULL;
72 static void _del_hook(Evas_Object *obj);
73 static void _theme_hook(Evas_Object *obj);
74 static void _sizing_eval(Evas_Object *obj);
75 static void _resize(void *data, Evas *e, Evas_Object *obj, void *event_info);
76 static void _item_sizing_eval(Elm_Navigationbar_Item *it);
77 static void _item_del(Elm_Navigationbar_Item *it);
78 static void _back_button_clicked(void *data, Evas_Object *obj, void *event_info);
79 static void _button_size_set(Evas_Object *obj);
80 static Eina_Bool _button_set(Evas_Object *obj, Evas_Object *prev_btn, Evas_Object *new_btn, Eina_Bool back_btn);
81 static void _transition_complete_cb(void *data);
82 static void _elm_navigationbar_prev_btn_set(Evas_Object *obj,
85 Elm_Navigationbar_Item *it);
86 static void _elm_navigationbar_next_btn_set(Evas_Object *obj,
89 Elm_Navigationbar_Item *it);
90 static void _title_clicked(void *data, Evas_Object *obj, const char *emission, const char *source);
91 static void _titleobj_switching(Evas_Object *obj, Elm_Navigationbar_Item *it);
93 static const char SIG_HIDE_FINISHED[] = "hide,finished";
94 static const char SIG_TITLE_OBJ_VISIBLE_CHANGED[] = "titleobj,visible,changed";
95 static const char SIG_TITLE_CLICKED[] = "title,clicked";
97 static const Evas_Smart_Cb_Description _signals[] = {
98 {SIG_HIDE_FINISHED, ""},
99 {SIG_TITLE_OBJ_VISIBLE_CHANGED, ""},
100 {SIG_TITLE_CLICKED, ""},
105 _content_del(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
107 Elm_Navigationbar_Item *it = data;
108 evas_object_data_del(obj, _navigationbar_key);
110 //TODO: it will be better remove this page?
114 _title_obj_del(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
116 Elm_Navigationbar_Item *it = data;
118 elm_navigationbar_title_object_list_unset(it->base.widget, it->content, &l);
120 evas_object_del(eina_list_data_get(l));
125 _title_icon_del(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
127 Elm_Navigationbar_Item *it = data;
132 _title_btn_del(void *data, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
134 Elm_Navigationbar_Item *it = data;
136 if (it->title_btns[ELM_NAVIGATIONBAR_PREV_BUTTON] == obj)
137 it->title_btns[ELM_NAVIGATIONBAR_PREV_BUTTON] = NULL;
138 else if (it->title_btns[ELM_NAVIGATIONBAR_NEXT_BUTTON] == obj)
139 it->title_btns[ELM_NAVIGATIONBAR_NEXT_BUTTON] = NULL;
143 _title_btn_set(Elm_Navigationbar_Item *it, Evas_Object *btn, int title_btn_idx, Eina_Bool back_btn)
147 if(it->title_btns[title_btn_idx] == btn) return EINA_FALSE;
149 changed = _button_set(it->base.widget, it->title_btns[title_btn_idx], btn, back_btn);
150 it->title_btns[title_btn_idx] = btn;
152 if ((!changed) || (!btn)) return EINA_FALSE;
154 it->back_btn = back_btn;
156 evas_object_event_callback_add(btn, EVAS_CALLBACK_DEL, _title_btn_del, it);
162 _create_back_btn(Evas_Object *parent, const char *title, void *data)
164 Evas_Object *btn = elm_button_add(parent);
165 if (!btn) return NULL;
166 elm_object_text_set(btn, title);
167 evas_object_smart_callback_add(btn, "clicked", _back_button_clicked, data);
168 elm_object_focus_allow_set(btn, EINA_FALSE);
173 _del_hook(Evas_Object *obj)
175 Widget_Data *wd = elm_widget_data_get(obj);
177 Elm_Navigationbar_Item *it;
179 EINA_LIST_FOREACH(wd->stack, list, it)
181 eina_list_free(wd->stack);
186 _theme_hook(Evas_Object *obj)
188 Widget_Data *wd = elm_widget_data_get(obj);
189 Eina_List *list = NULL;
190 Elm_Navigationbar_Item *it = NULL;
194 _elm_theme_object_set(obj, wd->base, "navigationbar", "base", elm_widget_style_get(obj));
196 list = eina_list_last(wd->stack);
199 it = eina_list_data_get(list);
203 if (it->title_btns[ELM_NAVIGATIONBAR_PREV_BUTTON])
204 edje_object_part_swallow(wd->base, "elm.swallow.prev_btn", it->title_btns[ELM_NAVIGATIONBAR_PREV_BUTTON]);
205 if (it->title_btns[ELM_NAVIGATIONBAR_NEXT_BUTTON])
206 edje_object_part_swallow(wd->base, "elm.swallow.next_btn", it->title_btns[ELM_NAVIGATIONBAR_NEXT_BUTTON]);
211 edje_object_part_swallow(wd->base, "elm.swallow.icon", it->icon);
212 edje_object_signal_emit(wd->base, "elm,state,icon,visible", "elm");
217 edje_object_part_text_set(wd->base, "elm.text", it->title);
222 edje_object_part_swallow(wd->base, "elm.swallow.title", it->title_obj);
224 if (it->titleobj_visible)
225 edje_object_signal_emit(wd->base, "elm,state,show,noanimate,title", "elm");
227 edje_object_signal_emit(wd->base, "elm,state,hide,noanimate,title", "elm"); //elm,state,title,hide
230 edje_object_signal_emit(wd->base, "elm,state,show,extended", "elm");
235 if (!wd->title_visible)
236 edje_object_signal_emit(wd->base, "elm,state,item,moveup", "elm");
238 edje_object_message_signal_process(wd->base);
243 _item_del(Elm_Navigationbar_Item *it)
245 //TODO: So hard to manage.
246 //TODO: Just prepare one layout for title objects.
247 //TODO: then remove the layout only.
253 wd = elm_widget_data_get(it->base.widget);
256 //Remove Function Buttons
257 for (idx = 0; idx < ELM_NAVIGATIONBAR_TITLE_BTN_CNT; idx++)
259 if (!it->title_btns[idx]) continue;
260 if (!it->back_btn) elm_object_unfocus(it->title_btns[idx]);
261 evas_object_event_callback_del(it->title_btns[idx], EVAS_CALLBACK_DEL, _title_btn_del);
262 evas_object_del(it->title_btns[idx]);
266 evas_object_event_callback_del(it->icon, EVAS_CALLBACK_DEL, _title_icon_del);
267 evas_object_del(it->icon);
271 evas_object_event_callback_del(it->title_obj, EVAS_CALLBACK_DEL, _title_obj_del);
272 evas_object_del(it->title_obj);
273 eina_list_free(it->title_obj_list);
275 if (it->title) eina_stringshare_del(it->title);
276 if (it->subtitle) eina_stringshare_del(it->subtitle);
280 evas_object_data_del(it->content, _navigationbar_key);
281 evas_object_event_callback_del(it->content, EVAS_CALLBACK_DEL, _content_del);
288 _sizing_eval(Evas_Object *obj)
293 wd = elm_widget_data_get(obj);
296 list = eina_list_last(wd->stack);
299 _item_sizing_eval(list->data);
303 _item_sizing_eval(Elm_Navigationbar_Item *it)
306 Widget_Data *wd = elm_widget_data_get(it->base.widget);
311 edje_object_size_min_calc(wd->base, &minw, NULL);
313 //TODO: Even the below code for size calculation is redundant and should be removed.
314 //TODO: Item_sizing_eval function has to be totally refactored/removed.
315 _button_size_set(it->title_btns[ELM_NAVIGATIONBAR_PREV_BUTTON]);
316 _button_size_set(it->title_btns[ELM_NAVIGATIONBAR_NEXT_BUTTON]);
320 _resize(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
326 _titleobj_switching(Evas_Object *obj, Elm_Navigationbar_Item *it)
328 Widget_Data *wd = elm_widget_data_get(obj);
331 if (!it->title_obj) return;
333 if (elm_navigationbar_content_top_get(it->base.widget) != it->content)
336 if (it->titleobj_visible)
337 edje_object_signal_emit(wd->base, "elm,state,show,title", "elm"); //elm,state,title,show
339 edje_object_signal_emit(wd->base, "elm,state,hide,title", "elm"); //elm,state,title,hide
341 _item_sizing_eval(it);
345 _title_clicked(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
347 Evas_Object *navibar = data;
350 Elm_Navigationbar_Item *it;
352 wd = elm_widget_data_get(navibar);
355 last = eina_list_last(wd->stack);
358 it = eina_list_data_get(last);
359 if ((!it) || (!it->title_obj)) return;
361 if (!it->titleobj_visible)
363 it->titleobj_visible = EINA_TRUE;
364 evas_object_smart_callback_call(it->base.widget, SIG_TITLE_OBJ_VISIBLE_CHANGED, (void *) EINA_TRUE);
368 it->titleobj_visible = EINA_FALSE;
369 evas_object_smart_callback_call(it->base.widget, SIG_TITLE_OBJ_VISIBLE_CHANGED, (void *) EINA_FALSE);
372 evas_object_smart_callback_call(navibar, SIG_TITLE_CLICKED, NULL);
374 _titleobj_switching(navibar, it);
377 //TODO: should be renamed.
379 _transition_complete_cb(void *data)
381 Evas_Object *navi_bar;
383 Elm_Navigationbar_Item *prev_it;
384 Elm_Navigationbar_Item *it;
387 Transit_Cb_Data *cb = data;
390 navi_bar = cb->navibar;
391 if (!navi_bar) return;
393 wd = elm_widget_data_get(navi_bar);
396 prev_it = cb->prev_it;
399 if (cb->pop && prev_it)
401 ll = eina_list_last(wd->stack);
402 if (ll->data == prev_it)
405 wd->stack = eina_list_remove_list(wd->stack, ll);
410 if (prev_it->title_btns[ELM_NAVIGATIONBAR_PREV_BUTTON])
411 evas_object_hide(prev_it->title_btns[ELM_NAVIGATIONBAR_PREV_BUTTON]);
412 if (prev_it->title_btns[ELM_NAVIGATIONBAR_NEXT_BUTTON])
413 evas_object_hide(prev_it->title_btns[ELM_NAVIGATIONBAR_NEXT_BUTTON]);
414 if (prev_it->title_obj)
415 evas_object_hide(prev_it->title_obj);
417 evas_object_hide(prev_it->icon);
419 if ((it) && (wd->title_visible))
421 edje_object_part_text_set(wd->base, "elm.text", it->title);
426 edje_object_signal_emit(wd->base, "elm,action,pop", "elm");
428 edje_object_signal_emit(wd->base, "elm,action,push", "elm");
429 evas_object_pass_events_set(wd->base, EINA_TRUE);
433 edje_object_part_swallow(wd->base, "elm.swallow.title", it->title_obj);
436 edje_object_part_text_set(wd->base, "elm.text.sub", it->subtitle);
438 edje_object_part_text_set(wd->base, "elm.text.sub", NULL);
440 if (it->title_btns[ELM_NAVIGATIONBAR_PREV_BUTTON])
441 edje_object_part_swallow(wd->base, "elm.swallow.prev_btn", it->title_btns[ELM_NAVIGATIONBAR_PREV_BUTTON]);
442 if (it->title_btns[ELM_NAVIGATIONBAR_NEXT_BUTTON])
443 edje_object_part_swallow(wd->base, "elm.swallow.next_btn", it->title_btns[ELM_NAVIGATIONBAR_NEXT_BUTTON]);
447 edje_object_part_swallow(wd->base, "elm.swallow.icon", it->icon);
448 edje_object_signal_emit(wd->base, "elm,state,icon,visible", "elm");
451 edje_object_signal_emit(wd->base, "elm,state,icon,hidden", "elm");
453 if ((it->title_obj) && (it->title))
455 edje_object_signal_emit(wd->base, "elm,state,show,extended", "elm");
456 if(it->titleobj_visible)
458 //TODO: remove the dependency on these signals as related to nbeat, try to make it totally theme dependent
459 edje_object_signal_emit(wd->base, "elm,state,show,noanimate,title", "elm");
462 //TODO: remove the dependency on these signals as related to nbeat, try to make it totally theme dependent
463 edje_object_signal_emit(wd->base, "elm,state,hide,noanimate,title", "elm");
467 edje_object_signal_emit(wd->base, "elm,state,hide,extended", "elm");
468 //TODO: remove the dependency on these signals as related to nbeat, try to make it totally theme dependent
469 edje_object_signal_emit(wd->base, "elm,state,hide,noanimate,title", "elm");
470 it->titleobj_visible = EINA_FALSE;
476 _back_button_clicked(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
478 Elm_Navigationbar_Item *it = data;
479 elm_navigationbar_pop(it->base.widget);
483 _hide_finished(void *data, Evas_Object *obj __UNUSED__, void *event_info)
485 Evas_Object *navi_bar = data;
486 Widget_Data *wd = elm_widget_data_get(navi_bar);
487 wd->popping = EINA_FALSE;
488 evas_object_smart_callback_call(navi_bar, SIG_HIDE_FINISHED, event_info);
489 evas_object_pass_events_set(wd->base, EINA_FALSE);
493 _button_size_set(Evas_Object *obj)
496 Evas_Coord minw = -1, minh = -1, maxw= -1, maxh = -1;
497 Evas_Coord w = 0, h = 0;
499 evas_object_size_hint_min_get(obj, &minw, &minh);
500 evas_object_size_hint_max_get(obj, &maxw, &maxh);
501 evas_object_geometry_get(obj, NULL, NULL, &w, &h);
502 if (w < minw) w = minw;
503 if (h < minh) h = minh;
504 if ((maxw >= 0) && (w > maxw)) w = maxw;
505 if ((maxh >= 0) && (h > maxh)) h = maxh;
506 evas_object_resize(obj, w, h);
510 _elm_navigationbar_prev_btn_set(Evas_Object *obj, Evas_Object *content, Evas_Object *new_btn, Elm_Navigationbar_Item *it)
513 Evas_Object *prev_btn;
515 wd = elm_widget_data_get(obj);
518 if (!_title_btn_set(it, new_btn, ELM_NAVIGATIONBAR_PREV_BUTTON, EINA_FALSE))
521 //update if the content is the top item
522 if (elm_navigationbar_content_top_get(obj) != content)
525 prev_btn = edje_object_part_swallow_get(wd->base, "elm.swallow.prev_btn");
526 if (prev_btn) evas_object_del(prev_btn);
527 edje_object_part_swallow(wd->base, "elm.swallow.prev_btn", new_btn);
530 //TODO: looks make this _elm_navigationbar_function_button1_set same.
532 _elm_navigationbar_next_btn_set(Evas_Object *obj, Evas_Object *content, Evas_Object *new_btn, Elm_Navigationbar_Item *it)
535 Evas_Object *prev_btn;
537 wd = elm_widget_data_get(obj);
540 if (!_title_btn_set(it, new_btn, ELM_NAVIGATIONBAR_NEXT_BUTTON, EINA_FALSE))
543 //update if the content is the top item
544 if (elm_navigationbar_content_top_get(obj) != content)
547 prev_btn = edje_object_part_swallow_get(wd->base, "elm.swallow.next_btn");
548 if (prev_btn) evas_object_del(prev_btn);
549 edje_object_part_swallow(wd->base, "elm.swallow.next_btn", new_btn);
553 _button_set(Evas_Object *obj, Evas_Object *prev_btn, Evas_Object *new_btn, Eina_Bool back_btn)
555 char buf[4096]; //TODO: How to guarantee this buffer size?
556 Eina_Bool changed = EINA_FALSE;
561 evas_object_del(prev_btn);
563 if (!new_btn) return changed;
567 snprintf(buf, sizeof(buf), "navigationbar_prev_btn/%s", elm_widget_style_get(obj));
568 elm_object_style_set(new_btn, buf);
572 if (!strcmp("default", elm_object_style_get(new_btn)))
574 snprintf(buf, sizeof(buf), "navigationbar_next_btn/%s", elm_widget_style_get(obj));
575 elm_object_style_set(new_btn, buf);
579 elm_widget_sub_object_add(obj, new_btn);
586 * Add a new navigationbar to the parent
588 * @param[in] parent The parent object
589 * @return The new object or NULL if it cannot be created
591 * @ingroup NavigationBar
594 elm_navigationbar_add(Evas_Object *parent)
600 EINA_SAFETY_ON_NULL_RETURN_VAL(parent, NULL);
602 wd = ELM_NEW(Widget_Data);
603 e = evas_object_evas_get(parent);
604 obj = elm_widget_add(e);
605 ELM_SET_WIDTYPE(widtype, "navigationbar");
606 elm_widget_type_set(obj, "navigationbar");
607 elm_widget_sub_object_add(parent, obj);
608 elm_widget_data_set(obj, wd);
609 elm_widget_del_hook_set(obj, _del_hook);
610 elm_widget_theme_hook_set(obj, _theme_hook);
612 wd->base = edje_object_add(e);
613 _elm_theme_object_set(obj, wd->base, "navigationbar", "base", "default");
614 elm_widget_resize_object_set(obj, wd->base);
615 //TODO: elm,action,title,clicked
616 edje_object_signal_callback_add(wd->base, "elm,action,clicked", "elm",
617 _title_clicked, obj);
619 //TODO: How about making the pager as a base?
620 //TODO: Swallow title and content as one content into the pager.
621 wd->pager = elm_pager_add(obj);
622 elm_object_style_set(wd->pager, "navigationbar");
623 elm_widget_sub_object_add(obj, wd->pager);
624 edje_object_part_swallow(wd->base, "elm.swallow.content", wd->pager);
625 evas_object_smart_callback_add(wd->pager, "hide,finished", _hide_finished, obj);
626 evas_object_event_callback_add(obj, EVAS_CALLBACK_RESIZE, _resize, NULL);
628 wd->title_visible = EINA_TRUE;
630 evas_object_smart_callbacks_descriptions_set(obj, _signals);
632 //TODO: apply elm_object_disabled_set
638 * Push an object to the top of the NavigationBar stack (and show it)
639 * The object pushed becomes a child of the navigationbar and will be controlled
640 * it is deleted when the navigationbar is deleted or when the content is popped.
642 * @param[in] obj The NavigationBar object
643 * @param[in] title The title string
644 * @param[in] prev_btn The previous button
645 * @param[in] next_btn The next button
646 * @param[in] unused Unused.
647 * @param[in] content The object to push
649 * @ingroup NavigationBar
652 elm_navigationbar_push(Evas_Object *obj, const char *title, Evas_Object *prev_btn, Evas_Object *next_btn, Evas_Object *unused __UNUSED__, Evas_Object *content)
654 ELM_CHECK_WIDTYPE(obj, widtype);
657 Elm_Navigationbar_Item *it;
658 Elm_Navigationbar_Item *top_it;
660 if (!content) return;
662 wd = elm_widget_data_get(obj);
665 if (evas_object_data_get(content, _navigationbar_key)) return;
667 it = elm_widget_item_new(obj, Elm_Navigationbar_Item);
670 top_it = eina_list_data_get(eina_list_last(wd->stack));
672 _title_btn_set(it, prev_btn, ELM_NAVIGATIONBAR_PREV_BUTTON, EINA_FALSE);
673 _title_btn_set(it, next_btn, ELM_NAVIGATIONBAR_NEXT_BUTTON, EINA_FALSE);
675 it->content = content;
676 evas_object_event_callback_add(content, EVAS_CALLBACK_DEL, _content_del, it);
677 evas_object_data_set(content, _navigationbar_key, it);
679 //Add a prev-button automatically.
680 if ((!prev_btn) && (top_it))
683 _title_btn_set(it, _create_back_btn(obj, top_it->title, it), ELM_NAVIGATIONBAR_PREV_BUTTON, EINA_TRUE);
685 _title_btn_set(it, _create_back_btn(obj, _ELM_NAVIBAR_PREV_BTN_DEFAULT_LABEL, it), ELM_NAVIGATIONBAR_PREV_BUTTON, EINA_TRUE);
688 eina_stringshare_replace(&it->title, title);
689 edje_object_part_text_set(wd->base, "elm.text", title);
690 _item_sizing_eval(it);
692 Transit_Cb_Data *cb = ELM_NEW(Transit_Cb_Data);
693 // unswallow items and start transition
694 // TODO: For what? why does it need to unswallow?
697 cb->prev_it = top_it;
698 cb->first_page = EINA_FALSE;
699 if (top_it->title_obj) edje_object_part_unswallow(wd->base, top_it->title_obj);
700 if (top_it->title_btns[ELM_NAVIGATIONBAR_PREV_BUTTON])
701 edje_object_part_unswallow(wd->base, top_it->title_btns[ELM_NAVIGATIONBAR_PREV_BUTTON]);
702 if (top_it->title_btns[ELM_NAVIGATIONBAR_NEXT_BUTTON])
703 edje_object_part_unswallow(wd->base, top_it->title_btns[ELM_NAVIGATIONBAR_NEXT_BUTTON]);
705 edje_object_part_unswallow(wd->base, top_it->icon);
707 //If page is the first, then do not run the transition... but if user want.. ?
711 cb->first_page = EINA_TRUE;
715 cb->pop = EINA_FALSE;
717 _transition_complete_cb(cb);
719 elm_pager_content_push(wd->pager, it->content);
721 wd->stack = eina_list_append(wd->stack, it);
726 * This pops the object that is on top (visible) in the navigationbar, makes it disappear, then deletes the object.
727 * The object that was underneath it, on the stack will become visible.
729 * @param[in] obj The NavigationBar object
731 * @ingroup NavigationBar
734 elm_navigationbar_pop(Evas_Object *obj)
736 ELM_CHECK_WIDTYPE(obj, widtype);
737 Widget_Data *wd = elm_widget_data_get(obj);
740 Elm_Navigationbar_Item *it = NULL;
741 Elm_Navigationbar_Item *prev_it = NULL;
743 //TODO: It's impossible to pop while popping?
744 if (wd->popping) return;
745 if (!wd->stack) return;
747 //find item to be popped and to be shown
748 //TODO: hmm.. i think it's hard to manager separated list from elm_pager internal list. but how about use evas_object_data_set to each content??
749 ll = eina_list_last(wd->stack);
757 //unswallow items and start trasition
758 cb = ELM_NEW(Transit_Cb_Data);
760 //Previous page is exist.
763 cb->prev_it = prev_it;
766 if (prev_it->title_obj)
767 edje_object_part_unswallow(wd->base, prev_it->title_obj);
768 if (prev_it->title_btns[ELM_NAVIGATIONBAR_PREV_BUTTON])
769 edje_object_part_unswallow(wd->base, prev_it->title_btns[ELM_NAVIGATIONBAR_PREV_BUTTON]);
770 if (prev_it->title_btns[ELM_NAVIGATIONBAR_NEXT_BUTTON])
771 edje_object_part_unswallow(wd->base, prev_it->title_btns[ELM_NAVIGATIONBAR_NEXT_BUTTON]);
773 edje_object_part_unswallow(wd->base, prev_it->icon);
774 _item_sizing_eval(it);
776 //This case, it's the last page.
779 cb->prev_it = prev_it;
782 //TODO: seems that flag is inverted.
783 cb->first_page = EINA_FALSE;
786 _transition_complete_cb(cb);
787 wd->popping = EINA_TRUE;
789 elm_pager_content_pop(wd->pager);
791 if ((prev_it) && (!it))
792 edje_object_part_text_set(wd->base, "elm.text", NULL);
798 * This Pops to the given content object (and update it) by deleting rest of the objects in between.
800 * @param[in] obj The NavigationBar object
801 * @param[in] content the object to show
803 * @ingroup NavigationBar
806 elm_navigationbar_to_content_pop(Evas_Object *obj, Evas_Object *content)
808 ELM_CHECK_WIDTYPE(obj, widtype);
812 Elm_Navigationbar_Item *it;
813 Elm_Navigationbar_Item *prev_it;
816 wd = elm_widget_data_get(obj);
817 if ((!wd) || (!content) || (!wd->stack)) return;
819 //find item to be popped and to be shown
821 ll = eina_list_last(wd->stack);
830 if ((it->base.widget) && (it->content != content))
833 wd->stack = eina_list_remove_list(wd->stack, ll);
842 //unswallow items and start trasition
843 cb = ELM_NEW(Transit_Cb_Data);
844 cb->prev_it = prev_it;
847 cb->first_page = EINA_FALSE;
850 //TODO: make one call.
851 if (prev_it->title_obj)
852 edje_object_part_unswallow(wd->base, prev_it->title_obj);
853 if (prev_it->title_btns[ELM_NAVIGATIONBAR_PREV_BUTTON])
854 edje_object_part_unswallow(wd->base, prev_it->title_btns[ELM_NAVIGATIONBAR_PREV_BUTTON]);
855 if (prev_it->title_btns[ELM_NAVIGATIONBAR_NEXT_BUTTON])
856 edje_object_part_unswallow(wd->base, prev_it->title_btns[ELM_NAVIGATIONBAR_NEXT_BUTTON]);
858 _item_sizing_eval(it);
859 _transition_complete_cb(cb);
861 elm_pager_to_content_pop(wd->pager, content);
866 * Set the title string for the pushed content
868 * @param[in] obj The NavigationBar object
869 * @param[in] content The object to push or pushed
870 * @param[in] title The title string
872 * @ingroup NavigationBar
875 elm_navigationbar_title_label_set(Evas_Object *obj, Evas_Object *content, const char *title)
877 ELM_CHECK_WIDTYPE(obj, widtype);
879 Elm_Navigationbar_Item *it;
881 if (!content) return;
883 wd = elm_widget_data_get(obj);
886 it = evas_object_data_get(content, _navigationbar_key);
889 eina_stringshare_replace(&it->title, title);
890 edje_object_part_text_set(wd->base, "elm.text", title);
891 _item_sizing_eval(it);
895 * Return the title string of the pushed content
897 * @param[in] obj The NavigationBar object
898 * @param[in] content The object to push or pushed
899 * @return The title string or NULL if none
901 * @ingroup NavigationBar
904 elm_navigationbar_title_label_get(Evas_Object *obj, Evas_Object *content)
906 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
908 Elm_Navigationbar_Item *it;
910 if (!content) return NULL;
912 wd = elm_widget_data_get(obj);
913 if (!wd) return NULL;
915 it = evas_object_data_get(content, _navigationbar_key);
916 if (!it) return NULL;
921 * Set the title icon for the pushed content
923 * @param[in] obj The NavigationBar object
924 * @param[in] content The object to push or pushed
925 * @param[in] icon The icon object
927 * @ingroup NavigationBar
930 elm_navigationbar_title_icon_set(Evas_Object *obj, Evas_Object *content, Evas_Object *icon)
932 ELM_CHECK_WIDTYPE(obj, widtype);
934 Elm_Navigationbar_Item *it;
935 Evas_Object *swallow;
937 if (!content) return;
939 wd = elm_widget_data_get(obj);
942 it = evas_object_data_get(content, _navigationbar_key);
945 if (it->icon == icon) return;
946 if (it->icon) evas_object_del(it->icon);
951 elm_widget_sub_object_add(obj, icon);
952 evas_object_event_callback_add(icon, EVAS_CALLBACK_DEL, _title_icon_del, it);
953 _item_sizing_eval(it);
954 //update if the content is the top item
955 if (elm_navigationbar_content_top_get(obj) != content)
958 swallow = edje_object_part_swallow_get(wd->base, "elm.swallow.icon");
961 edje_object_signal_emit(wd->base, "elm,state,icon,hidden", "elm");
962 edje_object_part_unswallow(wd->base, swallow);
963 evas_object_hide(swallow);
965 if (wd->title_visible)
967 edje_object_part_swallow(wd->base, "elm.swallow.icon", icon);
968 edje_object_signal_emit(wd->base, "elm,state,icon,visible", "elm");
969 edje_object_message_signal_process(wd->base);
972 edje_object_signal_emit(wd->base, "elm,state,icon,hidden", "elm");
976 * Get the title icon for the pushed content
978 * @param[in] obj The NavigationBar object
979 * @param[in] content The object to push or pushed
980 * @return The icon object or NULL if none
982 * @ingroup NavigationBar
985 elm_navigationbar_title_icon_get(Evas_Object *obj, Evas_Object *content)
987 ELM_CHECK_WIDTYPE(obj, widtype)NULL;
989 Elm_Navigationbar_Item *it;
991 if (!content) return NULL;
993 wd = elm_widget_data_get(obj);
994 if (!wd) return NULL;
996 it = evas_object_data_get(content, _navigationbar_key);
997 if (!it) return NULL;
1003 * Add a title object for the content.
1005 * @param[in] obj The NavigationBar object
1006 * @param[in] content The object pushed
1007 * @param[in] title_obj a title object (normally button or segment_control)
1009 * @ingroup NavigationBar
1011 //TODO: elm_navigationbar_title_object_set ( .... )
1013 elm_navigationbar_title_object_add(Evas_Object *obj, Evas_Object *content, Evas_Object *title_obj)
1015 ELM_CHECK_WIDTYPE(obj, widtype);
1017 Elm_Navigationbar_Item *it;
1019 if ((!title_obj) || (!content)) return;
1021 wd = elm_widget_data_get(obj);
1024 it = evas_object_data_get(content, _navigationbar_key);
1029 evas_object_event_callback_del(it->title_obj, EVAS_CALLBACK_DEL, _title_obj_del);
1030 evas_object_del(it->title_obj);
1033 it->title_obj = title_obj;
1034 elm_widget_sub_object_add(obj, title_obj);
1035 evas_object_event_callback_add(title_obj, EVAS_CALLBACK_DEL, _title_obj_del, it);
1037 //TODO: Conserve this line for a while the object list get API is alive.
1038 eina_list_free(it->title_obj_list);
1039 it->title_obj_list = eina_list_append(NULL, title_obj);
1041 if (elm_navigationbar_content_top_get(obj) != content)
1044 edje_object_part_swallow(wd->base, "elm.swallow.title", title_obj);
1046 //TODO: Looks something incorrect.
1047 if (wd->title_visible)
1051 edje_object_signal_emit(wd->base, "elm,state,show,extended", "elm");
1052 //TODO: for before nbeat?
1053 edje_object_signal_emit(wd->base, "elm,state,show,noanimate,title", "elm");
1054 it->titleobj_visible = EINA_TRUE;
1057 _item_sizing_eval(it);
1061 * Unset the list of title objects corresponding to given content and returns it to
1063 * @param[in] obj The NavigationBar object
1064 * @param[in] content The content object pushed
1065 * @param[out] list updates the list with title objects list, this list has to be freed and the
1066 * objects have to be deleted by application.
1067 * @ingroup NavigationBar
1071 elm_navigationbar_title_object_list_unset(Evas_Object *obj, Evas_Object *content, Eina_List **list)
1073 ELM_CHECK_WIDTYPE(obj, widtype);
1075 Elm_Navigationbar_Item *it;
1076 Evas_Object *swallow;
1078 if ((!list) || (!content)) return;
1080 wd = elm_widget_data_get(obj);
1083 it = evas_object_data_get(content, _navigationbar_key);
1086 *list = eina_list_append(*list, it->title_obj);
1087 it->title_obj = NULL;
1089 if (elm_navigationbar_content_top_get(obj) != content)
1092 //In this case, the content is in the last of the stack
1093 swallow = edje_object_part_swallow_get(wd->base, "elm.swallow.title");
1094 if (!swallow) return;
1096 if (wd->title_visible)
1098 if(it->titleobj_visible)
1100 //TODO: remove the dependency on these signals as related to nbeat?
1101 edje_object_signal_emit(wd->base, "elm,state,hide,noanimate,title", "elm");
1102 it->titleobj_visible = EINA_FALSE;
1104 edje_object_signal_emit(wd->base, "elm,state,hide,extended", "elm");
1106 _item_sizing_eval(it);
1110 elm_navigationbar_title_object_get(Evas_Object *obj, Evas_Object *content)
1112 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1114 Elm_Navigationbar_Item *it;
1116 if (!content) return NULL;
1118 wd = elm_widget_data_get(obj);
1119 if (!wd) return NULL;
1121 it = evas_object_data_get(content, _navigationbar_key);
1122 if (!it) return NULL;
1124 return it->title_obj;
1128 * Return the list of title objects of the pushed content.
1130 * @param[in] obj The NavigationBar object
1131 * @param[in] content The object to push or pushed
1132 * @return The list of title objects
1134 * @ingroup NavigationBar
1138 elm_navigationbar_title_object_list_get(Evas_Object *obj, Evas_Object *content)
1140 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1142 Elm_Navigationbar_Item *it;
1144 if (!content) return NULL;
1146 wd = elm_widget_data_get(obj);
1147 if (!wd) return NULL;
1149 it = evas_object_data_get(content, _navigationbar_key);
1150 if (!it) return NULL;
1152 return it->title_obj_list;
1156 * Return the content object at the top of the NavigationBar stack
1158 * @param[in] obj The NavigationBar object
1159 * @return The top content object or NULL if none
1161 * @ingroup NavigationBar
1164 elm_navigationbar_content_top_get(Evas_Object *obj)
1166 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1167 Widget_Data *wd = elm_widget_data_get(obj);
1168 if (!wd) return NULL;
1169 return elm_pager_content_top_get(wd->pager);
1173 * Return the content object at the bottom of the NavigationBar stack
1175 * @param[in] obj The NavigationBar object
1176 * @return The bottom content object or NULL if none
1178 * @ingroup NavigationBar
1181 elm_navigationbar_content_bottom_get(Evas_Object *obj)
1183 ELM_CHECK_WIDTYPE(obj, widtype)NULL;
1184 Widget_Data *wd = elm_widget_data_get(obj);
1185 if (!wd) return NULL;
1186 return elm_pager_content_bottom_get(wd->pager);
1190 * This hides the title area of navigationbar.
1192 * @param[in] obj The NavigationBar object
1193 * @param[in] hidden if EINA_TRUE the title area is hidden.
1195 * @ingroup NavigationBar
1197 //TODO: does not provide hidden get ?
1199 elm_navigationbar_hidden_set(Evas_Object *obj,
1202 ELM_CHECK_WIDTYPE(obj, widtype);
1203 Widget_Data *wd = elm_widget_data_get(obj);
1207 edje_object_signal_emit(wd->base, "elm,state,item,moveup", "elm");
1209 edje_object_signal_emit(wd->base, "elm,state,item,movedown", "elm");
1211 wd->title_visible = !hidden;
1215 * Set the button object of the pushed content.
1217 * @param[in] obj The NavigationBar object
1218 * @param[in] content The object to push or pushed
1219 * @param[in] button The button
1220 * @param[in] button_type Indicates the position
1222 * @ingroup NavigationBar
1225 elm_navigationbar_title_button_set(Evas_Object *obj, Evas_Object *content, Evas_Object *button, Elm_Navi_Button_Type button_type)
1227 ELM_CHECK_WIDTYPE(obj, widtype);
1230 Elm_Navigationbar_Item *it;
1232 if (!content) return;
1234 wd = elm_widget_data_get(obj);
1237 it = evas_object_data_get(content, _navigationbar_key);
1242 case ELM_NAVIGATIONBAR_PREV_BUTTON:
1243 _elm_navigationbar_prev_btn_set(obj, content, button, it);
1245 case ELM_NAVIGATIONBAR_NEXT_BUTTON:
1246 _elm_navigationbar_next_btn_set(obj, content, button, it);
1249 _elm_navigationbar_prev_btn_set(obj, content, button, it);
1256 * Return the button object of the pushed content
1258 * @param[in] obj The NavigationBar object
1259 * @param[in] content The object to push or pushed
1260 * @param[in] button_type Indicates the position
1261 * @return The button object or NULL if none
1263 * @ingroup NavigationBar
1266 elm_navigationbar_title_button_get(Evas_Object *obj, Evas_Object *content, Elm_Navi_Button_Type button_type)
1268 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1270 Elm_Navigationbar_Item *it;
1272 if (!content) return NULL;
1274 wd = elm_widget_data_get(obj);
1275 if (!wd) return NULL;
1277 it = evas_object_data_get(content, _navigationbar_key);
1278 if (!it) return NULL;
1282 case ELM_NAVIGATIONBAR_PREV_BUTTON:
1283 return it->title_btns[ELM_NAVIGATIONBAR_PREV_BUTTON];
1284 case ELM_NAVIGATIONBAR_NEXT_BUTTON:
1285 return it->title_btns[ELM_NAVIGATIONBAR_NEXT_BUTTON];
1287 return it->title_btns[ELM_NAVIGATIONBAR_PREV_BUTTON];
1293 * Set the sub title string for the pushed content.
1295 * @param[in] obj The NavigationBar object
1296 * @param[in] content The object to push or pushed
1297 * @param[in] subtitle The subtitle string
1299 * @ingroup NavigationBar
1302 elm_navigationbar_subtitle_label_set(Evas_Object *obj, Evas_Object *content, const char *subtitle)
1304 ELM_CHECK_WIDTYPE(obj, widtype);
1306 Elm_Navigationbar_Item *it;
1308 wd = elm_widget_data_get(obj);
1311 it = evas_object_data_get(content, _navigationbar_key);
1314 eina_stringshare_replace(&it->subtitle, subtitle);
1315 edje_object_part_text_set(wd->base, "elm.text.sub", subtitle);
1316 _item_sizing_eval(it);
1320 * Return the subtitle string of the pushed content.
1322 * @param[in] obj The NavigationBar object
1323 * @param[in] content The object to push or pushed
1324 * @return The subtitle string or NULL if none
1326 * @ingroup NavigationBar
1329 elm_navigationbar_subtitle_label_get(Evas_Object *obj, Evas_Object *content)
1331 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1333 Elm_Navigationbar_Item *it;
1335 wd = elm_widget_data_get(obj);
1336 if (!wd) return NULL;
1338 it = evas_object_data_get(content, _navigationbar_key);
1339 if (!it) return NULL;
1340 return it->subtitle;
1344 * This disables content area animation on push/pop.
1346 * @param[in] obj The NavigationBar object
1347 * @param[in] disable if EINA_TRUE animation is disabled.
1349 * @ingroup NavigationBar
1351 //TODO: Let's check to remove this API.
1353 elm_navigationbar_animation_disabled_set(Evas_Object *obj, Eina_Bool disable)
1355 ELM_CHECK_WIDTYPE(obj, widtype);
1356 Widget_Data *wd = elm_widget_data_get(obj);
1358 elm_pager_animation_disabled_set(wd->pager, disable);
1362 * This shows/hides title object area.
1364 * @param[in] obj The NavigationBar object
1365 * @param[in] show if EINA_TRUE title object is shown else its hidden.
1366 * @param[in] content The content object packed in navigationbar.
1367 * @ingroup NavigationBar
1370 elm_navigationbar_title_object_visible_set(Evas_Object *obj, Evas_Object *content, Eina_Bool visible)
1372 ELM_CHECK_WIDTYPE(obj, widtype);
1373 Elm_Navigationbar_Item *it;
1376 if (!content) return;
1378 wd = elm_widget_data_get(obj);
1381 it = evas_object_data_get(content, _navigationbar_key);
1383 if (it->titleobj_visible == visible) return;
1384 it->titleobj_visible = visible;
1385 _titleobj_switching(obj, it);
1389 * This gets the status whether title object is shown/hidden.
1391 * @param[in] obj The NavigationBar object
1392 * @param[in] content The content object packed in navigationbar.
1393 * @return The status whether title object is shown/hidden.
1394 * @ingroup NavigationBar
1397 elm_navigationbar_title_object_visible_get(Evas_Object *obj, Evas_Object *content)
1399 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
1400 Elm_Navigationbar_Item *it;
1403 if (!content) return EINA_FALSE;
1405 wd = elm_widget_data_get(obj);
1406 if (!wd) return EINA_FALSE;
1408 it = evas_object_data_get(content, _navigationbar_key);
1409 if (!it) return EINA_FALSE;
1411 return it->titleobj_visible;