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 Elm_Navigationbar_Item *_check_item_is_added(Evas_Object *obj, Evas_Object *content);
82 static void _transition_complete_cb(void *data);
83 static void _elm_navigationbar_prev_btn_set(Evas_Object *obj,
86 Elm_Navigationbar_Item *it);
87 static void _elm_navigationbar_next_btn_set(Evas_Object *obj,
90 Elm_Navigationbar_Item *it);
91 static void _title_clicked(void *data, Evas_Object *obj, const char *emission, const char *source);
92 static void _titleobj_switching(Evas_Object *obj, Elm_Navigationbar_Item *it);
94 static const char SIG_HIDE_FINISHED[] = "hide,finished";
95 static const char SIG_TITLE_OBJ_VISIBLE_CHANGED[] = "titleobj,visible,changed";
96 static const char SIG_TITLE_CLICKED[] = "title,clicked";
98 static const Evas_Smart_Cb_Description _signals[] = {
99 {SIG_HIDE_FINISHED, ""},
100 {SIG_TITLE_OBJ_VISIBLE_CHANGED, ""},
101 {SIG_TITLE_CLICKED, ""},
106 _content_del(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
108 Elm_Navigationbar_Item *it = data;
109 evas_object_data_del(obj, _navigationbar_key);
111 //TODO: it will be better remove this page?
115 _title_obj_del(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
117 Elm_Navigationbar_Item *it = data;
119 elm_navigationbar_title_object_list_unset(it->base.widget, it->content, &l);
121 evas_object_del(eina_list_data_get(l));
126 _title_icon_del(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
128 Elm_Navigationbar_Item *it = data;
133 _title_btn_del(void *data, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
135 Elm_Navigationbar_Item *it = data;
137 if (it->title_btns[ELM_NAVIGATIONBAR_PREV_BUTTON] == obj)
138 it->title_btns[ELM_NAVIGATIONBAR_PREV_BUTTON] = NULL;
139 else if (it->title_btns[ELM_NAVIGATIONBAR_NEXT_BUTTON] == obj)
140 it->title_btns[ELM_NAVIGATIONBAR_NEXT_BUTTON] = NULL;
144 _title_btn_set(Elm_Navigationbar_Item *it, Evas_Object *btn, int title_btn_idx, Eina_Bool back_btn)
148 if(it->title_btns[title_btn_idx] == btn) return EINA_FALSE;
150 changed = _button_set(it->base.widget, it->title_btns[title_btn_idx], btn, back_btn);
151 it->title_btns[title_btn_idx] = btn;
153 if ((!changed) || (!btn)) return EINA_FALSE;
155 it->back_btn = back_btn;
157 evas_object_event_callback_add(btn, EVAS_CALLBACK_DEL, _title_btn_del, it);
163 _create_back_btn(Evas_Object *parent, const char *title, void *data)
165 Evas_Object *btn = elm_button_add(parent);
166 if (!btn) return NULL;
167 elm_button_label_set(btn, title);
168 evas_object_smart_callback_add(btn, "clicked", _back_button_clicked, data);
169 elm_object_focus_allow_set(btn, EINA_FALSE);
174 _del_hook(Evas_Object *obj)
176 Widget_Data *wd = elm_widget_data_get(obj);
178 Elm_Navigationbar_Item *it;
180 EINA_LIST_FOREACH(wd->stack, list, it)
182 eina_list_free(wd->stack);
187 _theme_hook(Evas_Object *obj)
189 Widget_Data *wd = elm_widget_data_get(obj);
190 Eina_List *list = NULL;
191 Elm_Navigationbar_Item *it = NULL;
195 _elm_theme_object_set(obj, wd->base, "navigationbar", "base", elm_widget_style_get(obj));
196 EINA_LIST_FOREACH(wd->stack, list, it)
198 if (it->title_btns[ELM_NAVIGATIONBAR_PREV_BUTTON])
201 snprintf(buf_fn, sizeof(buf_fn), "navigationbar_prev_btn/%s", elm_widget_style_get(obj));
203 snprintf(buf_fn, sizeof(buf_fn), "navigationbar_next_btn/%s", elm_widget_style_get(obj));
204 elm_object_style_set(it->title_btns[ELM_NAVIGATIONBAR_PREV_BUTTON], buf_fn);
206 if (it->title_btns[ELM_NAVIGATIONBAR_NEXT_BUTTON])
208 snprintf(buf_fn, sizeof(buf_fn), "navigationbar_next_btn/%s", elm_widget_style_get(obj));
209 elm_object_style_set(it->title_btns[ELM_NAVIGATIONBAR_NEXT_BUTTON], buf_fn);
212 edje_object_message_signal_process(wd->base);
217 _item_del(Elm_Navigationbar_Item *it)
219 //TODO: So hard to manage.
220 //TODO: Just prepare one layout for title objects.
221 //TODO: then remove the layout only.
227 wd = elm_widget_data_get(it->base.widget);
230 //Remove Function Buttons
231 for (idx = 0; idx < ELM_NAVIGATIONBAR_TITLE_BTN_CNT; idx++)
233 if (!it->title_btns[idx]) continue;
234 if (!it->back_btn) elm_object_unfocus(it->title_btns[idx]);
235 evas_object_event_callback_del(it->title_btns[idx], EVAS_CALLBACK_DEL, _title_btn_del);
236 evas_object_del(it->title_btns[idx]);
240 evas_object_event_callback_del(it->icon, EVAS_CALLBACK_DEL, _title_icon_del);
241 evas_object_del(it->icon);
245 evas_object_event_callback_del(it->title_obj, EVAS_CALLBACK_DEL, _title_obj_del);
246 evas_object_del(it->title_obj);
247 eina_list_free(it->title_obj_list);
249 if (it->title) eina_stringshare_del(it->title);
250 if (it->subtitle) eina_stringshare_del(it->subtitle);
254 evas_object_data_del(it->content, _navigationbar_key);
255 evas_object_event_callback_del(it->content, EVAS_CALLBACK_DEL, _content_del);
262 _sizing_eval(Evas_Object *obj)
267 wd = elm_widget_data_get(obj);
270 list = eina_list_last(wd->stack);
273 _item_sizing_eval(list->data);
277 _item_sizing_eval(Elm_Navigationbar_Item *it)
280 Widget_Data *wd = elm_widget_data_get(it->base.widget);
285 edje_object_size_min_calc(wd->base, &minw, NULL);
287 //TODO: Even the below code for size calculation is redundant and should be removed.
288 //TODO: Item_sizing_eval function has to be totally refactored/removed.
289 _button_size_set(it->title_btns[ELM_NAVIGATIONBAR_PREV_BUTTON]);
290 _button_size_set(it->title_btns[ELM_NAVIGATIONBAR_NEXT_BUTTON]);
294 _resize(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
300 _titleobj_switching(Evas_Object *obj, Elm_Navigationbar_Item *it)
302 Widget_Data *wd = elm_widget_data_get(obj);
305 if (!it->title_obj) return;
307 if (elm_navigationbar_content_top_get(it->base.widget) != it->content)
310 if (it->titleobj_visible)
311 edje_object_signal_emit(wd->base, "elm,state,show,title", "elm"); //elm,state,title,show
313 edje_object_signal_emit(wd->base, "elm,state,hide,title", "elm"); //elm,state,title,hide
315 _item_sizing_eval(it);
319 _title_clicked(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
321 Evas_Object *navibar = data;
324 Elm_Navigationbar_Item *it;
326 wd = elm_widget_data_get(navibar);
329 last = eina_list_last(wd->stack);
332 it = eina_list_data_get(last);
333 if ((!it) || (!it->title_obj)) return;
335 if (!it->titleobj_visible)
337 it->titleobj_visible = EINA_TRUE;
338 evas_object_smart_callback_call(it->base.widget, SIG_TITLE_OBJ_VISIBLE_CHANGED, (void *) EINA_TRUE);
342 it->titleobj_visible = EINA_FALSE;
343 evas_object_smart_callback_call(it->base.widget, SIG_TITLE_OBJ_VISIBLE_CHANGED, (void *) EINA_FALSE);
346 evas_object_smart_callback_call(navibar, SIG_TITLE_CLICKED, NULL);
348 _titleobj_switching(navibar, it);
351 //TODO: should be renamed.
353 _transition_complete_cb(void *data)
355 Evas_Object *navi_bar;
357 Elm_Navigationbar_Item *prev_it;
358 Elm_Navigationbar_Item *it;
361 Transit_Cb_Data *cb = data;
364 navi_bar = cb->navibar;
365 if (!navi_bar) return;
367 wd = elm_widget_data_get(navi_bar);
370 prev_it = cb->prev_it;
373 if (cb->pop && prev_it)
375 ll = eina_list_last(wd->stack);
376 if (ll->data == prev_it)
379 wd->stack = eina_list_remove_list(wd->stack, ll);
384 if (prev_it->title_btns[ELM_NAVIGATIONBAR_PREV_BUTTON])
385 evas_object_hide(prev_it->title_btns[ELM_NAVIGATIONBAR_PREV_BUTTON]);
386 if (prev_it->title_btns[ELM_NAVIGATIONBAR_NEXT_BUTTON])
387 evas_object_hide(prev_it->title_btns[ELM_NAVIGATIONBAR_NEXT_BUTTON]);
388 if (prev_it->title_obj)
389 evas_object_hide(prev_it->title_obj);
391 evas_object_hide(prev_it->icon);
393 if ((it) && (wd->title_visible))
395 edje_object_part_text_set(wd->base, "elm.text", it->title);
400 edje_object_signal_emit(wd->base, "elm,action,pop", "elm");
402 edje_object_signal_emit(wd->base, "elm,action,push", "elm");
403 evas_object_pass_events_set(wd->base, EINA_TRUE);
407 edje_object_part_swallow(wd->base, "elm.swallow.title", it->title_obj);
410 edje_object_part_text_set(wd->base, "elm.text.sub", it->subtitle);
412 edje_object_part_text_set(wd->base, "elm.text.sub", NULL);
414 if (it->title_btns[ELM_NAVIGATIONBAR_PREV_BUTTON])
415 edje_object_part_swallow(wd->base, "elm.swallow.prev_btn", it->title_btns[ELM_NAVIGATIONBAR_PREV_BUTTON]);
416 if (it->title_btns[ELM_NAVIGATIONBAR_NEXT_BUTTON])
417 edje_object_part_swallow(wd->base, "elm.swallow.next_btn", it->title_btns[ELM_NAVIGATIONBAR_NEXT_BUTTON]);
421 edje_object_part_swallow(wd->base, "elm.swallow.icon", it->icon);
422 edje_object_signal_emit(wd->base, "elm,state,icon,visible", "elm");
425 edje_object_signal_emit(wd->base, "elm,state,icon,hidden", "elm");
427 if ((it->title_obj) && (it->title))
429 edje_object_signal_emit(wd->base, "elm,state,show,extended", "elm");
430 if(it->titleobj_visible)
432 //TODO: remove the dependency on these signals as related to nbeat, try to make it totally theme dependent
433 edje_object_signal_emit(wd->base, "elm,state,show,noanimate,title", "elm");
436 //TODO: remove the dependency on these signals as related to nbeat, try to make it totally theme dependent
437 edje_object_signal_emit(wd->base, "elm,state,hide,noanimate,title", "elm");
441 edje_object_signal_emit(wd->base, "elm,state,hide,extended", "elm");
442 //TODO: remove the dependency on these signals as related to nbeat, try to make it totally theme dependent
443 edje_object_signal_emit(wd->base, "elm,state,hide,noanimate,title", "elm");
444 it->titleobj_visible = EINA_FALSE;
450 _back_button_clicked(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
452 Elm_Navigationbar_Item *it = data;
453 elm_navigationbar_pop(it->base.widget);
457 _hide_finished(void *data, Evas_Object *obj __UNUSED__, void *event_info)
459 Evas_Object *navi_bar = data;
460 Widget_Data *wd = elm_widget_data_get(navi_bar);
461 wd->popping = EINA_FALSE;
462 evas_object_smart_callback_call(navi_bar, SIG_HIDE_FINISHED, event_info);
463 evas_object_pass_events_set(wd->base, EINA_FALSE);
467 _button_size_set(Evas_Object *obj)
470 Evas_Coord minw = -1, minh = -1, maxw= -1, maxh = -1;
471 Evas_Coord w = 0, h = 0;
473 evas_object_size_hint_min_get(obj, &minw, &minh);
474 evas_object_size_hint_max_get(obj, &maxw, &maxh);
475 evas_object_geometry_get(obj, NULL, NULL, &w, &h);
476 if (w < minw) w = minw;
477 if (h < minh) h = minh;
478 if ((maxw >= 0) && (w > maxw)) w = maxw;
479 if ((maxh >= 0) && (h > maxh)) h = maxh;
480 evas_object_resize(obj, w, h);
484 _elm_navigationbar_prev_btn_set(Evas_Object *obj, Evas_Object *content, Evas_Object *new_btn, Elm_Navigationbar_Item *it)
487 Evas_Object *prev_btn;
489 wd = elm_widget_data_get(obj);
492 if (!_title_btn_set(it, new_btn, ELM_NAVIGATIONBAR_PREV_BUTTON, EINA_FALSE))
495 //update if the content is the top item
496 if (elm_navigationbar_content_top_get(obj) != content)
499 prev_btn = edje_object_part_swallow_get(wd->base, "elm.swallow.prev_btn");
500 if (prev_btn) evas_object_del(prev_btn);
501 edje_object_part_swallow(wd->base, "elm.swallow.prev_btn", new_btn);
504 //TODO: looks make this _elm_navigationbar_function_button1_set same.
506 _elm_navigationbar_next_btn_set(Evas_Object *obj, Evas_Object *content, Evas_Object *new_btn, Elm_Navigationbar_Item *it)
509 Evas_Object *prev_btn;
511 wd = elm_widget_data_get(obj);
514 if (!_title_btn_set(it, new_btn, ELM_NAVIGATIONBAR_NEXT_BUTTON, EINA_FALSE))
517 //update if the content is the top item
518 if (elm_navigationbar_content_top_get(obj) != content)
521 prev_btn = edje_object_part_swallow_get(wd->base, "elm.swallow.next_btn");
522 if (prev_btn) evas_object_del(prev_btn);
523 edje_object_part_swallow(wd->base, "elm.swallow.next_btn", new_btn);
527 _button_set(Evas_Object *obj, Evas_Object *prev_btn, Evas_Object *new_btn, Eina_Bool back_btn)
529 char buf[4096]; //TODO: How to guarantee this buffer size?
530 Eina_Bool changed = EINA_FALSE;
535 evas_object_del(prev_btn);
537 if (!new_btn) return changed;
541 snprintf(buf, sizeof(buf), "navigationbar_prev_btn/%s", elm_widget_style_get(obj));
542 elm_object_style_set(new_btn, buf);
546 snprintf(buf, sizeof(buf), "navigationbar_next_btn/%s", elm_widget_style_get(obj));
547 elm_object_style_set(new_btn, buf);
550 elm_widget_sub_object_add(obj, new_btn);
557 * Add a new navigationbar to the parent
559 * @param[in] parent The parent object
560 * @return The new object or NULL if it cannot be created
562 * @ingroup NavigationBar
565 elm_navigationbar_add(Evas_Object *parent)
571 EINA_SAFETY_ON_NULL_RETURN_VAL(parent, NULL);
573 wd = ELM_NEW(Widget_Data);
574 e = evas_object_evas_get(parent);
575 obj = elm_widget_add(e);
576 ELM_SET_WIDTYPE(widtype, "navigationbar");
577 elm_widget_type_set(obj, "navigationbar");
578 elm_widget_sub_object_add(parent, obj);
579 elm_widget_data_set(obj, wd);
580 elm_widget_del_hook_set(obj, _del_hook);
581 elm_widget_theme_hook_set(obj, _theme_hook);
583 wd->base = edje_object_add(e);
584 _elm_theme_object_set(obj, wd->base, "navigationbar", "base", "default");
585 elm_widget_resize_object_set(obj, wd->base);
586 //TODO: elm,action,title,clicked
587 edje_object_signal_callback_add(wd->base, "elm,action,clicked", "elm",
588 _title_clicked, obj);
590 //TODO: How about making the pager as a base?
591 //TODO: Swallow title and content as one content into the pager.
592 wd->pager = elm_pager_add(obj);
593 elm_object_style_set(wd->pager, "navigationbar");
594 elm_widget_sub_object_add(obj, wd->pager);
595 edje_object_part_swallow(wd->base, "elm.swallow.content", wd->pager);
596 evas_object_smart_callback_add(wd->pager, "hide,finished", _hide_finished, obj);
597 evas_object_event_callback_add(obj, EVAS_CALLBACK_RESIZE, _resize, NULL);
599 wd->title_visible = EINA_TRUE;
601 evas_object_smart_callbacks_descriptions_set(obj, _signals);
603 //TODO: apply elm_object_disabled_set
609 * Push an object to the top of the NavigationBar stack (and show it)
610 * The object pushed becomes a child of the navigationbar and will be controlled
611 * it is deleted when the navigationbar is deleted or when the content is popped.
613 * @param[in] obj The NavigationBar object
614 * @param[in] title The title string
615 * @param[in] prev_btn The previous button
616 * @param[in] next_btn The next button
617 * @param[in] unused Unused.
618 * @param[in] content The object to push
620 * @ingroup NavigationBar
623 elm_navigationbar_push(Evas_Object *obj, const char *title, Evas_Object *prev_btn, Evas_Object *next_btn, Evas_Object *unused __UNUSED__, Evas_Object *content)
625 ELM_CHECK_WIDTYPE(obj, widtype);
628 Elm_Navigationbar_Item *it;
629 Elm_Navigationbar_Item *top_it;
631 if (!content) return;
633 wd = elm_widget_data_get(obj);
636 if (evas_object_data_get(content, _navigationbar_key)) return;
638 it = elm_widget_item_new(obj, Elm_Navigationbar_Item);
641 top_it = eina_list_data_get(eina_list_last(wd->stack));
643 _title_btn_set(it, prev_btn, ELM_NAVIGATIONBAR_PREV_BUTTON, EINA_FALSE);
644 _title_btn_set(it, next_btn, ELM_NAVIGATIONBAR_NEXT_BUTTON, EINA_FALSE);
646 it->content = content;
647 evas_object_event_callback_add(content, EVAS_CALLBACK_DEL, _content_del, it);
648 evas_object_data_set(content, _navigationbar_key, it);
650 //Add a prev-button automatically.
651 if ((!prev_btn) && (top_it))
654 _title_btn_set(it, _create_back_btn(obj, top_it->title, it), ELM_NAVIGATIONBAR_PREV_BUTTON, EINA_TRUE);
656 _title_btn_set(it, _create_back_btn(obj, _ELM_NAVIBAR_PREV_BTN_DEFAULT_LABEL, it), ELM_NAVIGATIONBAR_PREV_BUTTON, EINA_TRUE);
659 eina_stringshare_replace(&it->title, title);
660 edje_object_part_text_set(wd->base, "elm.text", title);
661 _item_sizing_eval(it);
663 Transit_Cb_Data *cb = ELM_NEW(Transit_Cb_Data);
664 // unswallow items and start transition
665 // TODO: For what? why does it need to unswallow?
668 cb->prev_it = top_it;
669 cb->first_page = EINA_FALSE;
670 if (top_it->title_obj) edje_object_part_unswallow(wd->base, top_it->title_obj);
671 if (top_it->title_btns[ELM_NAVIGATIONBAR_PREV_BUTTON])
672 edje_object_part_unswallow(wd->base, top_it->title_btns[ELM_NAVIGATIONBAR_PREV_BUTTON]);
673 if (top_it->title_btns[ELM_NAVIGATIONBAR_NEXT_BUTTON])
674 edje_object_part_unswallow(wd->base, top_it->title_btns[ELM_NAVIGATIONBAR_NEXT_BUTTON]);
676 edje_object_part_unswallow(wd->base, top_it->icon);
678 //If page is the first, then do not run the transition... but if user want.. ?
682 cb->first_page = EINA_TRUE;
686 cb->pop = EINA_FALSE;
688 _transition_complete_cb(cb);
690 elm_pager_content_push(wd->pager, it->content);
692 wd->stack = eina_list_append(wd->stack, it);
697 * This pops the object that is on top (visible) in the navigationbar, makes it disappear, then deletes the object.
698 * The object that was underneath it, on the stack will become visible.
700 * @param[in] obj The NavigationBar object
702 * @ingroup NavigationBar
705 elm_navigationbar_pop(Evas_Object *obj)
707 ELM_CHECK_WIDTYPE(obj, widtype);
708 Widget_Data *wd = elm_widget_data_get(obj);
711 Elm_Navigationbar_Item *it = NULL;
712 Elm_Navigationbar_Item *prev_it = NULL;
714 //TODO: It's impossible to pop while popping?
715 if (wd->popping) return;
716 if (!wd->stack) return;
718 //find item to be popped and to be shown
719 //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??
720 ll = eina_list_last(wd->stack);
728 //unswallow items and start trasition
729 cb = ELM_NEW(Transit_Cb_Data);
731 //Previous page is exist.
734 cb->prev_it = prev_it;
737 if (prev_it->title_obj)
738 edje_object_part_unswallow(wd->base, prev_it->title_obj);
739 if (prev_it->title_btns[ELM_NAVIGATIONBAR_PREV_BUTTON])
740 edje_object_part_unswallow(wd->base, prev_it->title_btns[ELM_NAVIGATIONBAR_PREV_BUTTON]);
741 if (prev_it->title_btns[ELM_NAVIGATIONBAR_NEXT_BUTTON])
742 edje_object_part_unswallow(wd->base, prev_it->title_btns[ELM_NAVIGATIONBAR_NEXT_BUTTON]);
744 edje_object_part_unswallow(wd->base, prev_it->icon);
745 _item_sizing_eval(it);
747 //This case, it's the last page.
750 cb->prev_it = prev_it;
753 //TODO: seems that flag is inverted.
754 cb->first_page = EINA_FALSE;
757 _transition_complete_cb(cb);
758 wd->popping = EINA_TRUE;
760 elm_pager_content_pop(wd->pager);
762 if ((prev_it) && (!it))
763 edje_object_part_text_set(wd->base, "elm.text", NULL);
769 * This Pops to the given content object (and update it) by deleting rest of the objects in between.
771 * @param[in] obj The NavigationBar object
772 * @param[in] content the object to show
774 * @ingroup NavigationBar
777 elm_navigationbar_to_content_pop(Evas_Object *obj, Evas_Object *content)
779 ELM_CHECK_WIDTYPE(obj, widtype);
783 Elm_Navigationbar_Item *it;
784 Elm_Navigationbar_Item *prev_it;
787 wd = elm_widget_data_get(obj);
788 if ((!wd) || (!content) || (!wd->stack)) return;
790 //find item to be popped and to be shown
792 ll = eina_list_last(wd->stack);
801 if ((it->base.widget) && (it->content != content))
804 wd->stack = eina_list_remove_list(wd->stack, ll);
813 //unswallow items and start trasition
814 cb = ELM_NEW(Transit_Cb_Data);
815 cb->prev_it = prev_it;
818 cb->first_page = EINA_FALSE;
821 //TODO: make one call.
822 if (prev_it->title_obj)
823 edje_object_part_unswallow(wd->base, prev_it->title_obj);
824 if (prev_it->title_btns[ELM_NAVIGATIONBAR_PREV_BUTTON])
825 edje_object_part_unswallow(wd->base, prev_it->title_btns[ELM_NAVIGATIONBAR_PREV_BUTTON]);
826 if (prev_it->title_btns[ELM_NAVIGATIONBAR_NEXT_BUTTON])
827 edje_object_part_unswallow(wd->base, prev_it->title_btns[ELM_NAVIGATIONBAR_NEXT_BUTTON]);
829 _item_sizing_eval(it);
830 _transition_complete_cb(cb);
832 elm_pager_to_content_pop(wd->pager, content);
837 * Set the title string for the pushed content
839 * @param[in] obj The NavigationBar object
840 * @param[in] content The object to push or pushed
841 * @param[in] title The title string
843 * @ingroup NavigationBar
846 elm_navigationbar_title_label_set(Evas_Object *obj, Evas_Object *content, const char *title)
848 ELM_CHECK_WIDTYPE(obj, widtype);
850 Elm_Navigationbar_Item *it;
852 if (!content) return;
854 wd = elm_widget_data_get(obj);
857 it = evas_object_data_get(content, _navigationbar_key);
860 eina_stringshare_replace(&it->title, title);
861 edje_object_part_text_set(wd->base, "elm.text", title);
862 _item_sizing_eval(it);
866 * Return the title string of the pushed content
868 * @param[in] obj The NavigationBar object
869 * @param[in] content The object to push or pushed
870 * @return The title string or NULL if none
872 * @ingroup NavigationBar
875 elm_navigationbar_title_label_get(Evas_Object *obj, Evas_Object *content)
877 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
879 Elm_Navigationbar_Item *it;
881 if (!content) return NULL;
883 wd = elm_widget_data_get(obj);
884 if (!wd) return NULL;
886 it = evas_object_data_get(content, _navigationbar_key);
887 if (!it) return NULL;
892 * Set the title icon for the pushed content
894 * @param[in] obj The NavigationBar object
895 * @param[in] content The object to push or pushed
896 * @param[in] icon The icon object
898 * @ingroup NavigationBar
901 elm_navigationbar_title_icon_set(Evas_Object *obj, Evas_Object *content, Evas_Object *icon)
903 ELM_CHECK_WIDTYPE(obj, widtype);
905 Elm_Navigationbar_Item *it;
906 Evas_Object *swallow;
908 if (!content) return;
910 wd = elm_widget_data_get(obj);
913 it = evas_object_data_get(content, _navigationbar_key);
916 if (it->icon == icon) return;
917 if (it->icon) evas_object_del(it->icon);
922 elm_widget_sub_object_add(obj, icon);
923 evas_object_event_callback_add(icon, EVAS_CALLBACK_DEL, _title_icon_del, it);
924 _item_sizing_eval(it);
925 //update if the content is the top item
926 if (elm_navigationbar_content_top_get(obj) != content)
929 swallow = edje_object_part_swallow_get(wd->base, "elm.swallow.icon");
932 edje_object_signal_emit(wd->base, "elm,state,icon,hidden", "elm");
933 edje_object_part_unswallow(wd->base, swallow);
934 evas_object_hide(swallow);
936 if (wd->title_visible)
938 edje_object_part_swallow(wd->base, "elm.swallow.icon", icon);
939 edje_object_signal_emit(wd->base, "elm,state,icon,visible", "elm");
940 edje_object_message_signal_process(wd->base);
943 edje_object_signal_emit(wd->base, "elm,state,icon,hidden", "elm");
947 * Get the title icon for the pushed content
949 * @param[in] obj The NavigationBar object
950 * @param[in] content The object to push or pushed
951 * @return The icon object or NULL if none
953 * @ingroup NavigationBar
956 elm_navigationbar_title_icon_get(Evas_Object *obj, Evas_Object *content)
958 ELM_CHECK_WIDTYPE(obj, widtype)NULL;
960 Elm_Navigationbar_Item *it;
962 if (!content) return NULL;
964 wd = elm_widget_data_get(obj);
965 if (!wd) return NULL;
967 it = evas_object_data_get(content, _navigationbar_key);
968 if (!it) return NULL;
974 * Add a title object for the content.
976 * @param[in] obj The NavigationBar object
977 * @param[in] content The object pushed
978 * @param[in] title_obj a title object (normally button or segment_control)
980 * @ingroup NavigationBar
982 //TODO: elm_navigationbar_title_object_set ( .... )
984 elm_navigationbar_title_object_add(Evas_Object *obj, Evas_Object *content, Evas_Object *title_obj)
986 ELM_CHECK_WIDTYPE(obj, widtype);
988 Elm_Navigationbar_Item *it;
990 if ((!title_obj) || (!content)) return;
992 wd = elm_widget_data_get(obj);
995 it = evas_object_data_get(content, _navigationbar_key);
1000 evas_object_event_callback_del(it->title_obj, EVAS_CALLBACK_DEL, _title_obj_del);
1001 evas_object_del(it->title_obj);
1004 it->title_obj = title_obj;
1005 elm_widget_sub_object_add(obj, title_obj);
1006 evas_object_event_callback_add(title_obj, EVAS_CALLBACK_DEL, _title_obj_del, it);
1008 //TODO: Conserve this line for a while the object list get API is alive.
1009 eina_list_free(it->title_obj_list);
1010 it->title_obj_list = eina_list_append(NULL, title_obj);
1012 if (elm_navigationbar_content_top_get(obj) != content)
1015 edje_object_part_swallow(wd->base, "elm.swallow.title", title_obj);
1017 //TODO: Looks something incorrect.
1018 if (wd->title_visible)
1022 edje_object_signal_emit(wd->base, "elm,state,show,extended", "elm");
1023 //TODO: for before nbeat?
1024 edje_object_signal_emit(wd->base, "elm,state,show,noanimate,title", "elm");
1025 it->titleobj_visible = EINA_TRUE;
1028 _item_sizing_eval(it);
1032 * Unset the list of title objects corresponding to given content and returns it to
1034 * @param[in] obj The NavigationBar object
1035 * @param[in] content The content object pushed
1036 * @param[out] list updates the list with title objects list, this list has to be freed and the
1037 * objects have to be deleted by application.
1038 * @ingroup NavigationBar
1042 elm_navigationbar_title_object_list_unset(Evas_Object *obj, Evas_Object *content, Eina_List **list)
1044 ELM_CHECK_WIDTYPE(obj, widtype);
1046 Elm_Navigationbar_Item *it;
1047 Evas_Object *swallow;
1049 if ((!list) || (!content)) return;
1051 wd = elm_widget_data_get(obj);
1054 it = evas_object_data_get(content, _navigationbar_key);
1057 *list = eina_list_append(*list, it->title_obj);
1058 it->title_obj = NULL;
1060 if (elm_navigationbar_content_top_get(obj) != content)
1063 //In this case, the content is in the last of the stack
1064 swallow = edje_object_part_swallow_get(wd->base, "elm.swallow.title");
1065 if (!swallow) return;
1067 if (wd->title_visible)
1069 if(it->titleobj_visible)
1071 //TODO: remove the dependency on these signals as related to nbeat?
1072 edje_object_signal_emit(wd->base, "elm,state,hide,noanimate,title", "elm");
1073 it->titleobj_visible = EINA_FALSE;
1075 edje_object_signal_emit(wd->base, "elm,state,hide,extended", "elm");
1077 _item_sizing_eval(it);
1081 elm_navigationbar_title_object_get(Evas_Object *obj, Evas_Object *content)
1083 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1085 Elm_Navigationbar_Item *it;
1087 if (!content) return NULL;
1089 wd = elm_widget_data_get(obj);
1090 if (!wd) return NULL;
1092 it = evas_object_data_get(content, _navigationbar_key);
1093 if (!it) return NULL;
1095 return it->title_obj;
1099 * Return the list of title objects of the pushed content.
1101 * @param[in] obj The NavigationBar object
1102 * @param[in] content The object to push or pushed
1103 * @return The list of title objects
1105 * @ingroup NavigationBar
1109 elm_navigationbar_title_object_list_get(Evas_Object *obj, Evas_Object *content)
1111 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1113 Elm_Navigationbar_Item *it;
1115 if (!content) return NULL;
1117 wd = elm_widget_data_get(obj);
1118 if (!wd) return NULL;
1120 it = evas_object_data_get(content, _navigationbar_key);
1121 if (!it) return NULL;
1123 return it->title_obj_list;
1127 * Return the content object at the top of the NavigationBar stack
1129 * @param[in] obj The NavigationBar object
1130 * @return The top content object or NULL if none
1132 * @ingroup NavigationBar
1135 elm_navigationbar_content_top_get(Evas_Object *obj)
1137 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1138 Widget_Data *wd = elm_widget_data_get(obj);
1139 if (!wd) return NULL;
1140 return elm_pager_content_top_get(wd->pager);
1144 * Return the content object at the bottom of the NavigationBar stack
1146 * @param[in] obj The NavigationBar object
1147 * @return The bottom content object or NULL if none
1149 * @ingroup NavigationBar
1152 elm_navigationbar_content_bottom_get(Evas_Object *obj)
1154 ELM_CHECK_WIDTYPE(obj, widtype)NULL;
1155 Widget_Data *wd = elm_widget_data_get(obj);
1156 if (!wd) return NULL;
1157 return elm_pager_content_bottom_get(wd->pager);
1161 * This hides the title area of navigationbar.
1163 * @param[in] obj The NavigationBar object
1164 * @param[in] hidden if EINA_TRUE the title area is hidden.
1166 * @ingroup NavigationBar
1168 //TODO: does not provide hidden get ?
1170 elm_navigationbar_hidden_set(Evas_Object *obj,
1173 ELM_CHECK_WIDTYPE(obj, widtype);
1174 Widget_Data *wd = elm_widget_data_get(obj);
1178 edje_object_signal_emit(wd->base, "elm,state,item,moveup", "elm");
1180 edje_object_signal_emit(wd->base, "elm,state,item,movedown", "elm");
1182 wd->title_visible = !hidden;
1186 * Set the button object of the pushed content.
1188 * @param[in] obj The NavigationBar object
1189 * @param[in] content The object to push or pushed
1190 * @param[in] button The button
1191 * @param[in] button_type Indicates the position
1193 * @ingroup NavigationBar
1196 elm_navigationbar_title_button_set(Evas_Object *obj, Evas_Object *content, Evas_Object *button, Elm_Navi_Button_Type button_type)
1198 ELM_CHECK_WIDTYPE(obj, widtype);
1201 Elm_Navigationbar_Item *it;
1203 if (!content) return;
1205 wd = elm_widget_data_get(obj);
1208 it = evas_object_data_get(content, _navigationbar_key);
1213 case ELM_NAVIGATIONBAR_PREV_BUTTON:
1214 _elm_navigationbar_prev_btn_set(obj, content, button, it);
1216 case ELM_NAVIGATIONBAR_NEXT_BUTTON:
1217 _elm_navigationbar_next_btn_set(obj, content, button, it);
1220 _elm_navigationbar_prev_btn_set(obj, content, button, it);
1227 * Return the button object of the pushed content
1229 * @param[in] obj The NavigationBar object
1230 * @param[in] content The object to push or pushed
1231 * @param[in] button_type Indicates the position
1232 * @return The button object or NULL if none
1234 * @ingroup NavigationBar
1237 elm_navigationbar_title_button_get(Evas_Object *obj, Evas_Object *content, Elm_Navi_Button_Type button_type)
1239 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1241 Elm_Navigationbar_Item *it;
1243 if (!content) return NULL;
1245 wd = elm_widget_data_get(obj);
1246 if (!wd) return NULL;
1248 it = evas_object_data_get(content, _navigationbar_key);
1249 if (!it) return NULL;
1253 case ELM_NAVIGATIONBAR_PREV_BUTTON:
1254 return it->title_btns[ELM_NAVIGATIONBAR_PREV_BUTTON];
1255 case ELM_NAVIGATIONBAR_NEXT_BUTTON:
1256 return it->title_btns[ELM_NAVIGATIONBAR_NEXT_BUTTON];
1258 return it->title_btns[ELM_NAVIGATIONBAR_PREV_BUTTON];
1264 * Set the sub title string for the pushed content.
1266 * @param[in] obj The NavigationBar object
1267 * @param[in] content The object to push or pushed
1268 * @param[in] subtitle The subtitle string
1270 * @ingroup NavigationBar
1273 elm_navigationbar_subtitle_label_set(Evas_Object *obj, Evas_Object *content, const char *subtitle)
1275 ELM_CHECK_WIDTYPE(obj, widtype);
1277 Elm_Navigationbar_Item *it;
1279 wd = elm_widget_data_get(obj);
1282 it = evas_object_data_get(content, _navigationbar_key);
1285 eina_stringshare_replace(&it->subtitle, subtitle);
1286 edje_object_part_text_set(wd->base, "elm.text.sub", subtitle);
1287 _item_sizing_eval(it);
1291 * Return the subtitle string of the pushed content.
1293 * @param[in] obj The NavigationBar object
1294 * @param[in] content The object to push or pushed
1295 * @return The subtitle string or NULL if none
1297 * @ingroup NavigationBar
1300 elm_navigationbar_subtitle_label_get(Evas_Object *obj, Evas_Object *content)
1302 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1304 Elm_Navigationbar_Item *it;
1306 wd = elm_widget_data_get(obj);
1307 if (!wd) return NULL;
1309 it = evas_object_data_get(content, _navigationbar_key);
1310 if (!it) return NULL;
1311 return it->subtitle;
1315 * This disables content area animation on push/pop.
1317 * @param[in] obj The NavigationBar object
1318 * @param[in] disable if EINA_TRUE animation is disabled.
1320 * @ingroup NavigationBar
1322 //TODO: Let's check to remove this API.
1324 elm_navigationbar_animation_disabled_set(Evas_Object *obj, Eina_Bool disable)
1326 ELM_CHECK_WIDTYPE(obj, widtype);
1327 Widget_Data *wd = elm_widget_data_get(obj);
1329 elm_pager_animation_disabled_set(wd->pager, disable);
1333 * This shows/hides title object area.
1335 * @param[in] obj The NavigationBar object
1336 * @param[in] show if EINA_TRUE title object is shown else its hidden.
1337 * @param[in] content The content object packed in navigationbar.
1338 * @ingroup NavigationBar
1341 elm_navigationbar_title_object_visible_set(Evas_Object *obj, Evas_Object *content, Eina_Bool visible)
1343 ELM_CHECK_WIDTYPE(obj, widtype);
1344 Elm_Navigationbar_Item *it;
1347 if (!content) return;
1349 wd = elm_widget_data_get(obj);
1352 it = evas_object_data_get(content, _navigationbar_key);
1354 if (it->titleobj_visible == visible) return;
1355 it->titleobj_visible = visible;
1356 _titleobj_switching(obj, it);
1360 * This gets the status whether title object is shown/hidden.
1362 * @param[in] obj The NavigationBar object
1363 * @param[in] content The content object packed in navigationbar.
1364 * @return The status whether title object is shown/hidden.
1365 * @ingroup NavigationBar
1368 elm_navigationbar_title_object_visible_get(Evas_Object *obj, Evas_Object *content)
1370 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
1371 Elm_Navigationbar_Item *it;
1374 if (!content) return EINA_FALSE;
1376 wd = elm_widget_data_get(obj);
1377 if (!wd) return EINA_FALSE;
1379 it = evas_object_data_get(content, _navigationbar_key);
1380 if (!it) return EINA_FALSE;
1382 return it->titleobj_visible;