[Navigation_bar] focus will not be passed to the content which will be deleted soon
[framework/uifw/elementary.git] / src / lib / elc_navigationbar.c
1 #include <Elementary.h>
2 #include "elm_priv.h"
3
4 /**
5  * @defgroup NavigationBar NavigationBar
6  * @ingroup Elementary
7  *
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.
11  *
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().
19  */
20
21 #define _ELM_NAVIBAR_PREV_BTN_DEFAULT_LABEL "Previous"
22
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;
26
27 static const char _navigationbar_key[] = "_elm_navigationbar";
28
29 //TODO: Remove!
30 typedef enum
31   {
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;
36
37 struct _Widget_Data
38 {
39    Eina_List *stack;
40    Evas_Object *base;
41    Evas_Object *pager;
42    Eina_Bool title_visible : 1;
43    Eina_Bool popping: 1;
44  };
45
46 struct _Elm_Navigationbar_Item
47 {
48    Elm_Widget_Item base;
49    const char *title;
50    const char *subtitle;
51    Eina_List *title_obj_list;   //TODO: Remove!
52    Evas_Object *title_obj;
53    Evas_Object *title_btns[ELM_NAVIGATIONBAR_TITLE_BTN_CNT];
54    Evas_Object *content;
55    Evas_Object *icon;
56    Eina_Bool titleobj_visible :1;
57    Eina_Bool back_btn :1;
58 };
59
60 //TODO: Remove!
61 struct _Transit_Cb_Data
62 {
63    Elm_Navigationbar_Item* prev_it;
64    Elm_Navigationbar_Item* it;
65    Evas_Object *navibar;
66    Eina_Bool pop : 1;
67    Eina_Bool first_page : 1;
68 };
69
70 static const char *widtype = NULL;
71
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,
83                                             Evas_Object *content,
84                                             Evas_Object *new_btn,
85                                             Elm_Navigationbar_Item *it);
86 static void _elm_navigationbar_next_btn_set(Evas_Object *obj,
87                                             Evas_Object *content,
88                                             Evas_Object *new_btn,
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);
92 static void _emit_hook(Evas_Object *obj, const char *emission, const char *source);
93
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";
97
98 static const Evas_Smart_Cb_Description _signals[] = {
99        {SIG_HIDE_FINISHED, ""},
100        {SIG_TITLE_OBJ_VISIBLE_CHANGED, ""},
101        {SIG_TITLE_CLICKED, ""},
102        {NULL, NULL}
103 };
104
105 static void
106 _content_del(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
107 {
108    Elm_Navigationbar_Item *it = data;
109    evas_object_data_del(obj, _navigationbar_key);
110    it->content = NULL;
111    //TODO: it will be better remove this page?
112 }
113
114 static void
115 _title_obj_del(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
116 {
117    Elm_Navigationbar_Item *it = data;
118    Eina_List *l = NULL;
119    elm_navigationbar_title_object_list_unset(it->base.widget, it->content, &l);
120    if (!l) return;
121    evas_object_del(eina_list_data_get(l));
122    eina_list_free(l);
123 }
124
125 static void
126 _title_icon_del(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
127 {
128    Elm_Navigationbar_Item *it = data;
129    it->icon = NULL;
130 }
131
132 static void
133 _title_btn_del(void *data, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
134 {
135    Elm_Navigationbar_Item *it = data;
136
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;
141 }
142
143 static Eina_Bool
144 _title_btn_set(Elm_Navigationbar_Item *it, Evas_Object *btn, int title_btn_idx, Eina_Bool back_btn)
145 {
146    Eina_Bool changed;
147
148    if(it->title_btns[title_btn_idx] == btn) return EINA_FALSE;
149
150    changed = _button_set(it->base.widget, it->title_btns[title_btn_idx], btn, back_btn);
151    it->title_btns[title_btn_idx] = btn;
152
153    if ((!changed) || (!btn)) return EINA_FALSE;
154
155    it->back_btn = back_btn;
156
157    evas_object_event_callback_add(btn, EVAS_CALLBACK_DEL, _title_btn_del, it);
158
159    return EINA_TRUE;
160 }
161
162 static Evas_Object *
163 _create_back_btn(Evas_Object *parent, const char *title, void *data)
164 {
165    Evas_Object *btn = elm_button_add(parent);
166    if (!btn) return NULL;
167    elm_object_text_set(btn, title);
168    evas_object_smart_callback_add(btn, "clicked", _back_button_clicked, data);
169    return btn;
170 }
171
172 static void
173 _del_hook(Evas_Object *obj)
174 {
175    Widget_Data *wd = elm_widget_data_get(obj);
176    Eina_List *list;
177    Elm_Navigationbar_Item *it;
178
179    EINA_LIST_FOREACH(wd->stack, list, it)
180      _item_del(it);
181    eina_list_free(wd->stack);
182    free(wd);
183 }
184
185 void
186 _emit_hook(Evas_Object *obj, const char *emission, const char *source)
187 {
188    ELM_CHECK_WIDTYPE(obj, widtype);
189
190    Widget_Data *wd;
191    Eina_List *last;
192    Elm_Navigationbar_Item *it;
193
194    wd = elm_widget_data_get(obj);
195    if (!wd) return;
196
197    last = eina_list_last(wd->stack);
198    if (!last) return;
199
200    it = eina_list_data_get(last);
201    if ((!it) || (!it->title_obj)) return;
202
203    //FIXME: I know this is really bullshit.
204    //We don't need to keep the titleobj_visible but return the status in edc.
205    if (!strcmp(source, "elm"))
206      {
207         if (!strcmp(emission, "elm,state,hide,noanimate,title"))
208           it->titleobj_visible = EINA_FALSE;
209         else if (!strcmp(emission, "elm,state,show,noanimate,title"))
210           it->titleobj_visible = EINA_TRUE;
211      }
212
213    edje_object_signal_emit(wd->base, emission, source);
214 }
215
216 static void
217 _theme_hook(Evas_Object *obj)
218 {
219    Widget_Data *wd = elm_widget_data_get(obj);
220    Eina_List *list = NULL;
221    Elm_Navigationbar_Item *it = NULL;
222
223    if (!wd) return;
224    _elm_theme_object_set(obj, wd->base, "navigationbar", "base", elm_widget_style_get(obj));
225
226    list = eina_list_last(wd->stack);
227    if (list)
228      {
229         it = eina_list_data_get(list);
230         if (it)
231           {
232              //buttons
233              if (it->title_btns[ELM_NAVIGATIONBAR_PREV_BUTTON])
234                edje_object_part_swallow(wd->base, "elm.swallow.prev_btn", it->title_btns[ELM_NAVIGATIONBAR_PREV_BUTTON]);
235              if (it->title_btns[ELM_NAVIGATIONBAR_NEXT_BUTTON])
236                edje_object_part_swallow(wd->base, "elm.swallow.next_btn", it->title_btns[ELM_NAVIGATIONBAR_NEXT_BUTTON]);
237
238              //icon
239              if (it->icon)
240                {
241                   edje_object_part_swallow(wd->base, "elm.swallow.icon", it->icon);
242                   edje_object_signal_emit(wd->base, "elm,state,icon,visible", "elm");
243                }
244
245              //title text
246              if (it->title)
247                edje_object_part_text_set(wd->base, "elm.text", it->title);
248
249              //title object
250              if (it->title_obj)
251                {
252                   edje_object_part_swallow(wd->base, "elm.swallow.title", it->title_obj);
253
254                   if (it->titleobj_visible)
255                     edje_object_signal_emit(wd->base, "elm,state,show,noanimate,title", "elm");
256                   else
257                     edje_object_signal_emit(wd->base, "elm,state,hide,noanimate,title", "elm"); //elm,state,title,hide
258
259                   if (it->title)
260                     edje_object_signal_emit(wd->base, "elm,state,show,extended", "elm");
261                }
262             }
263      }
264
265    if (!wd->title_visible)
266      edje_object_signal_emit(wd->base, "elm,state,item,moveup", "elm");
267
268    edje_object_message_signal_process(wd->base);
269    _sizing_eval(obj);
270 }
271
272 static void
273 _item_del(Elm_Navigationbar_Item *it)
274 {
275    //TODO: So hard to manage.
276    //TODO: Just prepare one layout for title objects.
277    //TODO: then remove the layout only.
278    Widget_Data *wd;
279    int idx;
280
281    if (!it) return;
282
283    wd = elm_widget_data_get(it->base.widget);
284    if (!wd) return;
285
286    //Remove Function Buttons
287    for (idx = 0; idx < ELM_NAVIGATIONBAR_TITLE_BTN_CNT; idx++)
288      {
289         if (!it->title_btns[idx]) continue;
290         if (!it->back_btn) elm_object_unfocus(it->title_btns[idx]);
291         evas_object_event_callback_del(it->title_btns[idx], EVAS_CALLBACK_DEL, _title_btn_del);
292         evas_object_del(it->title_btns[idx]);
293      }
294    if (it->icon)
295      {
296         evas_object_event_callback_del(it->icon, EVAS_CALLBACK_DEL, _title_icon_del);
297         evas_object_del(it->icon);
298      }
299    if (it->title_obj)
300      {
301         evas_object_event_callback_del(it->title_obj, EVAS_CALLBACK_DEL, _title_obj_del);
302         evas_object_del(it->title_obj);
303         eina_list_free(it->title_obj_list);
304      }
305    if (it->title) eina_stringshare_del(it->title);
306    if (it->subtitle) eina_stringshare_del(it->subtitle);
307
308    if (it->content)
309      {
310         evas_object_data_del(it->content, _navigationbar_key);
311         evas_object_event_callback_del(it->content, EVAS_CALLBACK_DEL, _content_del);
312      }
313
314    free(it);
315 }
316
317 static void
318 _sizing_eval(Evas_Object *obj)
319 {
320    Widget_Data *wd;
321    Eina_List *list;
322
323    wd  = elm_widget_data_get(obj);
324    if (!wd) return;
325
326    list = eina_list_last(wd->stack);
327    if (!list) return;
328
329    _item_sizing_eval(list->data);
330 }
331
332 static void
333 _item_sizing_eval(Elm_Navigationbar_Item *it)
334 {
335    if (!it) return;
336    Widget_Data *wd = elm_widget_data_get(it->base.widget);
337    Evas_Coord minw;
338
339    if (!wd) return;
340
341    edje_object_size_min_calc(wd->base, &minw, NULL);
342
343    //TODO: Even the below code for size calculation is redundant and should be removed.
344    //TODO: Item_sizing_eval function has to be totally refactored/removed.
345    _button_size_set(it->title_btns[ELM_NAVIGATIONBAR_PREV_BUTTON]);
346    _button_size_set(it->title_btns[ELM_NAVIGATIONBAR_NEXT_BUTTON]);
347 }
348
349 static void
350 _resize(void *data __UNUSED__, Evas *e  __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
351 {
352    _sizing_eval(obj);
353 }
354
355 static void
356 _titleobj_switching(Evas_Object *obj, Elm_Navigationbar_Item *it)
357 {
358    Widget_Data *wd = elm_widget_data_get(obj);
359    if (!wd) return;
360
361    if (!it->title_obj) return;
362
363    if (elm_navigationbar_content_top_get(it->base.widget) != it->content)
364      return;
365
366    if (it->titleobj_visible)
367      edje_object_signal_emit(wd->base, "elm,state,show,title", "elm"); //elm,state,title,show
368    else
369      edje_object_signal_emit(wd->base, "elm,state,hide,title", "elm"); //elm,state,title,hide
370
371    _item_sizing_eval(it);
372 }
373
374 static void
375 _title_clicked(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
376 {
377    Evas_Object *navibar = data;
378    Widget_Data *wd;
379    Eina_List *last;
380    Elm_Navigationbar_Item *it;
381
382    wd = elm_widget_data_get(navibar);
383    if (!wd) return;
384
385    last = eina_list_last(wd->stack);
386    if (!last) return;
387
388    it = eina_list_data_get(last);
389    if ((!it) || (!it->title_obj)) return;
390
391    if (!it->titleobj_visible)
392      {
393         it->titleobj_visible = EINA_TRUE;
394         evas_object_smart_callback_call(it->base.widget, SIG_TITLE_OBJ_VISIBLE_CHANGED, (void *) EINA_TRUE);
395      }
396    else
397      {
398         it->titleobj_visible = EINA_FALSE;
399         evas_object_smart_callback_call(it->base.widget, SIG_TITLE_OBJ_VISIBLE_CHANGED, (void *) EINA_FALSE);
400      }
401
402    evas_object_smart_callback_call(navibar, SIG_TITLE_CLICKED, NULL);
403
404    _titleobj_switching(navibar, it);
405 }
406
407 //TODO: should be renamed.
408 static void
409 _transition_complete_cb(void *data)
410 {
411    Evas_Object *navi_bar;
412    Widget_Data *wd;
413    Elm_Navigationbar_Item *prev_it;
414    Elm_Navigationbar_Item *it;
415    Eina_List *ll;
416
417    Transit_Cb_Data *cb = data;
418    if (!cb) return;
419
420    navi_bar = cb->navibar;
421    if (!navi_bar) return;
422
423    wd = elm_widget_data_get(navi_bar);
424    if (!wd) return;
425
426    prev_it = cb->prev_it;
427    it = cb->it;
428
429    if (cb->pop && prev_it)
430      {
431         ll = eina_list_last(wd->stack);
432         if (ll->data == prev_it)
433           {
434              _item_del(prev_it);
435              wd->stack = eina_list_remove_list(wd->stack, ll);
436           }
437      }
438    else if (prev_it)
439      {
440         if (prev_it->title_btns[ELM_NAVIGATIONBAR_PREV_BUTTON])
441            evas_object_hide(prev_it->title_btns[ELM_NAVIGATIONBAR_PREV_BUTTON]);
442         if (prev_it->title_btns[ELM_NAVIGATIONBAR_NEXT_BUTTON])
443           evas_object_hide(prev_it->title_btns[ELM_NAVIGATIONBAR_NEXT_BUTTON]);
444         if (prev_it->title_obj)
445           evas_object_hide(prev_it->title_obj);
446         if (prev_it->icon)
447           evas_object_hide(prev_it->icon);
448      }
449    if ((it) && (wd->title_visible))
450      {
451         edje_object_part_text_set(wd->base, "elm.text", it->title);
452
453         if (!cb->first_page)
454           {
455              if (cb->pop)
456                edje_object_signal_emit(wd->base, "elm,action,pop", "elm");
457              else
458                edje_object_signal_emit(wd->base, "elm,action,push", "elm");
459              evas_object_pass_events_set(wd->base, EINA_TRUE);
460           }
461         if (it->title_obj)
462           {
463              edje_object_part_swallow(wd->base, "elm.swallow.title", it->title_obj);
464           }
465         if (it->subtitle)
466           edje_object_part_text_set(wd->base, "elm.text.sub", it->subtitle);
467         else
468           edje_object_part_text_set(wd->base, "elm.text.sub", NULL);
469
470         if (it->title_btns[ELM_NAVIGATIONBAR_PREV_BUTTON])
471           edje_object_part_swallow(wd->base, "elm.swallow.prev_btn", it->title_btns[ELM_NAVIGATIONBAR_PREV_BUTTON]);
472         if (it->title_btns[ELM_NAVIGATIONBAR_NEXT_BUTTON])
473           edje_object_part_swallow(wd->base, "elm.swallow.next_btn", it->title_btns[ELM_NAVIGATIONBAR_NEXT_BUTTON]);
474
475         if(it->icon)
476           {
477              edje_object_part_swallow(wd->base, "elm.swallow.icon", it->icon);
478              edje_object_signal_emit(wd->base, "elm,state,icon,visible", "elm");
479           }
480         else
481           edje_object_signal_emit(wd->base, "elm,state,icon,hidden", "elm");
482
483         if ((it->title_obj) && (it->title))
484           {
485              edje_object_signal_emit(wd->base, "elm,state,show,extended", "elm");
486              if(it->titleobj_visible)
487                {
488                  //TODO: remove the dependency on these signals as related to nbeat, try to make it totally theme dependent
489                  edje_object_signal_emit(wd->base, "elm,state,show,noanimate,title", "elm");
490                }
491              else
492                //TODO: remove the dependency on these signals as related to nbeat, try to make it totally theme dependent
493                edje_object_signal_emit(wd->base, "elm,state,hide,noanimate,title", "elm");
494           }
495         else
496           {
497              edje_object_signal_emit(wd->base, "elm,state,hide,extended", "elm");
498              //TODO: remove the dependency on these signals as related to nbeat, try to make it totally theme dependent
499              edje_object_signal_emit(wd->base, "elm,state,hide,noanimate,title", "elm");
500              it->titleobj_visible = EINA_FALSE;
501           }
502      }
503 }
504
505 static void
506 _back_button_clicked(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
507 {
508    Elm_Navigationbar_Item *it = data;
509    elm_navigationbar_pop(it->base.widget);
510 }
511
512 static void
513 _hide_finished(void *data, Evas_Object *obj __UNUSED__, void *event_info)
514 {
515    Evas_Object *navi_bar = data;
516    Widget_Data *wd =  elm_widget_data_get(navi_bar);
517    wd->popping = EINA_FALSE;
518    evas_object_smart_callback_call(navi_bar, SIG_HIDE_FINISHED, event_info);
519    evas_object_pass_events_set(wd->base, EINA_FALSE);
520 }
521
522 static void
523 _button_size_set(Evas_Object *obj)
524 {
525    if (!obj) return;
526    Evas_Coord minw = -1, minh = -1, maxw= -1, maxh = -1;
527    Evas_Coord w = 0, h = 0;
528
529    evas_object_size_hint_min_get(obj, &minw, &minh);
530    evas_object_size_hint_max_get(obj, &maxw, &maxh);
531    evas_object_geometry_get(obj, NULL, NULL, &w, &h);
532    if (w < minw) w = minw;
533    if (h < minh) h = minh;
534    if ((maxw >= 0) && (w > maxw)) w = maxw;
535    if ((maxh >= 0) && (h > maxh)) h = maxh;
536    evas_object_resize(obj, w, h);
537 }
538
539 static void
540 _elm_navigationbar_prev_btn_set(Evas_Object *obj, Evas_Object *content, Evas_Object *new_btn, Elm_Navigationbar_Item *it)
541 {
542    Widget_Data *wd;
543    Evas_Object *prev_btn;
544
545    wd = elm_widget_data_get(obj);
546    if (!wd) return;
547
548    if (!_title_btn_set(it, new_btn, ELM_NAVIGATIONBAR_PREV_BUTTON, EINA_FALSE))
549      return;
550
551    //update if the content is the top item
552    if (elm_navigationbar_content_top_get(obj) != content)
553      return;
554
555    prev_btn = edje_object_part_swallow_get(wd->base, "elm.swallow.prev_btn");
556    if (prev_btn) evas_object_del(prev_btn);
557    edje_object_part_swallow(wd->base, "elm.swallow.prev_btn", new_btn);
558 }
559
560 //TODO: looks make this  _elm_navigationbar_function_button1_set  same.
561 static void
562 _elm_navigationbar_next_btn_set(Evas_Object *obj, Evas_Object *content, Evas_Object *new_btn, Elm_Navigationbar_Item *it)
563 {
564    Widget_Data *wd;
565    Evas_Object *prev_btn;
566
567    wd = elm_widget_data_get(obj);
568    if (!wd) return;
569
570    if (!_title_btn_set(it, new_btn, ELM_NAVIGATIONBAR_NEXT_BUTTON, EINA_FALSE))
571      return;
572
573    //update if the content is the top item
574    if (elm_navigationbar_content_top_get(obj) != content)
575      return;
576
577    prev_btn = edje_object_part_swallow_get(wd->base, "elm.swallow.next_btn");
578    if (prev_btn) evas_object_del(prev_btn);
579    edje_object_part_swallow(wd->base, "elm.swallow.next_btn", new_btn);
580 }
581
582 static Eina_Bool
583 _button_set(Evas_Object *obj, Evas_Object *prev_btn, Evas_Object *new_btn, Eina_Bool back_btn)
584 {
585    char buf[4096];   //TODO: How to guarantee this buffer size?
586    Eina_Bool changed = EINA_FALSE;
587
588    if (prev_btn)
589      {
590         changed = EINA_TRUE;
591         evas_object_del(prev_btn);
592      }
593    if (!new_btn) return changed;
594
595    if (back_btn)
596      {
597         snprintf(buf, sizeof(buf), "navigationbar_prev_btn/%s", elm_widget_style_get(obj));
598         elm_object_style_set(new_btn, buf);
599      }
600    else
601      {
602         if (!strcmp("default", elm_object_style_get(new_btn)))
603           {
604              snprintf(buf, sizeof(buf), "navigationbar_next_btn/%s", elm_widget_style_get(obj));
605              elm_object_style_set(new_btn, buf);
606           }
607      }
608
609    elm_widget_sub_object_add(obj, new_btn);
610    changed = EINA_TRUE;
611
612    return changed;
613 }
614
615 /**
616  * Add a new navigationbar to the parent
617  *
618  * @param[in] parent The parent object
619  * @return The new object or NULL if it cannot be created
620  *
621  * @ingroup NavigationBar
622  */
623 EAPI Evas_Object *
624 elm_navigationbar_add(Evas_Object *parent)
625 {
626    Evas_Object *obj;
627    Evas *e;
628    Widget_Data *wd;
629
630    EINA_SAFETY_ON_NULL_RETURN_VAL(parent, NULL);
631
632    wd = ELM_NEW(Widget_Data);
633    e = evas_object_evas_get(parent);
634    obj = elm_widget_add(e);
635    ELM_SET_WIDTYPE(widtype, "navigationbar");
636    elm_widget_type_set(obj, "navigationbar");
637    elm_widget_sub_object_add(parent, obj);
638    elm_widget_data_set(obj, wd);
639    elm_widget_del_hook_set(obj, _del_hook);
640    elm_widget_theme_hook_set(obj, _theme_hook);
641    elm_widget_signal_emit_hook_set(obj, _emit_hook);
642
643    wd->base = edje_object_add(e);
644    _elm_theme_object_set(obj, wd->base, "navigationbar", "base", "default");
645    elm_widget_resize_object_set(obj, wd->base);
646    //TODO: elm,action,title,clicked
647    edje_object_signal_callback_add(wd->base, "elm,action,clicked", "elm",
648                                             _title_clicked, obj);
649
650    //TODO: How about making the pager as a base?
651    //TODO: Swallow title and content as one content into the pager.
652    wd->pager = elm_pager_add(obj);
653    elm_object_style_set(wd->pager, "navigationbar");
654    elm_widget_sub_object_add(obj, wd->pager);
655    edje_object_part_swallow(wd->base, "elm.swallow.content", wd->pager);
656    evas_object_smart_callback_add(wd->pager, "hide,finished", _hide_finished, obj);
657    evas_object_event_callback_add(obj, EVAS_CALLBACK_RESIZE, _resize, NULL);
658
659    wd->title_visible = EINA_TRUE;
660
661    evas_object_smart_callbacks_descriptions_set(obj, _signals);
662
663    //TODO: apply elm_object_disabled_set
664
665    return obj;
666 }
667
668 /**
669  * Push an object to the top of the NavigationBar stack (and show it)
670  * The object pushed becomes a child of the navigationbar and will be controlled
671  * it is deleted when the navigationbar is deleted or when the content is popped.
672  *
673  * @param[in] obj The NavigationBar object
674  * @param[in] title The title string
675  * @param[in] prev_btn The previous button
676  * @param[in] next_btn The next button
677  * @param[in] unused Unused.
678  * @param[in] content The object to push
679  *
680  * @ingroup NavigationBar
681  */
682 EAPI void
683 elm_navigationbar_push(Evas_Object *obj, const char *title, Evas_Object *prev_btn, Evas_Object *next_btn, Evas_Object *unused __UNUSED__, Evas_Object *content)
684 {
685    ELM_CHECK_WIDTYPE(obj, widtype);
686
687    Widget_Data *wd;
688    Elm_Navigationbar_Item *it;
689    Elm_Navigationbar_Item *top_it;
690
691    if (!content) return;
692
693    wd = elm_widget_data_get(obj);
694    if (!wd) return;
695
696    if (evas_object_data_get(content, _navigationbar_key)) return;
697
698    it = elm_widget_item_new(obj, Elm_Navigationbar_Item);
699    if (!it) return;
700
701    top_it = eina_list_data_get(eina_list_last(wd->stack));
702
703    _title_btn_set(it, prev_btn, ELM_NAVIGATIONBAR_PREV_BUTTON, EINA_FALSE);
704    _title_btn_set(it, next_btn, ELM_NAVIGATIONBAR_NEXT_BUTTON, EINA_FALSE);
705
706    it->content = content;
707    evas_object_event_callback_add(content, EVAS_CALLBACK_DEL, _content_del, it);
708    evas_object_data_set(content, _navigationbar_key, it);
709
710    //Add a prev-button automatically.
711    if ((!prev_btn) && (top_it))
712    {
713       if (top_it->title)
714         _title_btn_set(it, _create_back_btn(obj, top_it->title, it), ELM_NAVIGATIONBAR_PREV_BUTTON, EINA_TRUE);
715       else
716         _title_btn_set(it, _create_back_btn(obj, _ELM_NAVIBAR_PREV_BTN_DEFAULT_LABEL, it), ELM_NAVIGATIONBAR_PREV_BUTTON, EINA_TRUE);
717    }
718
719    eina_stringshare_replace(&it->title, title);
720    edje_object_part_text_set(wd->base, "elm.text", title);
721    _item_sizing_eval(it);
722
723    Transit_Cb_Data *cb = ELM_NEW(Transit_Cb_Data);
724    // unswallow items and start transition
725    // TODO: For what? why does it need to unswallow?
726    if (top_it)
727      {
728         cb->prev_it = top_it;
729         cb->first_page = EINA_FALSE;
730         if (top_it->title_obj) edje_object_part_unswallow(wd->base, top_it->title_obj);
731         if (top_it->title_btns[ELM_NAVIGATIONBAR_PREV_BUTTON])
732           edje_object_part_unswallow(wd->base, top_it->title_btns[ELM_NAVIGATIONBAR_PREV_BUTTON]);
733         if (top_it->title_btns[ELM_NAVIGATIONBAR_NEXT_BUTTON])
734           edje_object_part_unswallow(wd->base, top_it->title_btns[ELM_NAVIGATIONBAR_NEXT_BUTTON]);
735         if (top_it->icon)
736           edje_object_part_unswallow(wd->base, top_it->icon);
737      }
738    //If page is the first, then do not run the transition... but if user want.. ?
739    else
740      {
741         cb->prev_it = NULL;
742         cb->first_page = EINA_TRUE;
743      }
744    cb->navibar = obj;
745    cb->it = it;
746    cb->pop = EINA_FALSE;
747
748    _transition_complete_cb(cb);
749    free(cb);
750    elm_pager_content_push(wd->pager, it->content);
751
752    wd->stack = eina_list_append(wd->stack, it);
753    _sizing_eval(obj);
754 }
755
756 /**
757  * This pops the object that is on top (visible) in the navigationbar, makes it disappear, then deletes the object.
758  * The object that was underneath it, on the stack will become visible.
759  *
760  * @param[in] obj The NavigationBar object
761  *
762  * @ingroup NavigationBar
763  */
764 EAPI void
765 elm_navigationbar_pop(Evas_Object *obj)
766 {
767    ELM_CHECK_WIDTYPE(obj, widtype);
768    Widget_Data *wd = elm_widget_data_get(obj);
769    Eina_List *ll;
770    Transit_Cb_Data *cb;
771    Elm_Navigationbar_Item *it = NULL;
772    Elm_Navigationbar_Item *prev_it = NULL;
773
774    //TODO: It's impossible to pop while popping?
775    if (wd->popping) return;
776    if (!wd->stack) return;
777
778    //find item to be popped and to be shown
779    //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??
780    ll = eina_list_last(wd->stack);
781    if (ll)
782      {
783         prev_it = ll->data;
784         ll = ll->prev;
785         if (ll)
786           it = ll->data;
787      }
788    //unswallow items and start trasition
789    cb = ELM_NEW(Transit_Cb_Data);
790
791    //Previous page is exist.
792    if (prev_it && it)
793      {
794         cb->prev_it = prev_it;
795         cb->it = it;
796         cb->pop = EINA_TRUE;
797         if (prev_it->title_obj)
798           edje_object_part_unswallow(wd->base, prev_it->title_obj);
799         if (prev_it->title_btns[ELM_NAVIGATIONBAR_PREV_BUTTON])
800           edje_object_part_unswallow(wd->base, prev_it->title_btns[ELM_NAVIGATIONBAR_PREV_BUTTON]);
801         if (prev_it->title_btns[ELM_NAVIGATIONBAR_NEXT_BUTTON])
802           edje_object_part_unswallow(wd->base, prev_it->title_btns[ELM_NAVIGATIONBAR_NEXT_BUTTON]);
803         if (prev_it->icon)
804           edje_object_part_unswallow(wd->base, prev_it->icon);
805         _item_sizing_eval(it);
806      }
807    //This case, it's the last page.
808    else if (prev_it)
809      {
810         cb->prev_it = prev_it;
811         cb->it = NULL;
812         cb->pop = EINA_TRUE;
813         //TODO: seems that flag is inverted.
814         cb->first_page = EINA_FALSE;
815      }
816    if (prev_it->content)
817      elm_object_tree_unfocusable_set(prev_it->content, EINA_TRUE);
818    cb->navibar = obj;
819    _transition_complete_cb(cb);
820    wd->popping = EINA_TRUE;
821
822    elm_pager_content_pop(wd->pager);
823
824    if ((prev_it) && (!it))
825      edje_object_part_text_set(wd->base, "elm.text", NULL);
826
827    free(cb);
828 }
829
830 /**
831  * This Pops to the given content object (and update it) by deleting rest of the objects in between.
832  *
833  * @param[in] obj The NavigationBar object
834  * @param[in] content the object to show
835  *
836  * @ingroup NavigationBar
837  */
838 EAPI void
839 elm_navigationbar_to_content_pop(Evas_Object *obj, Evas_Object *content)
840 {
841    ELM_CHECK_WIDTYPE(obj, widtype);
842
843    Widget_Data *wd;
844    Eina_List *ll;
845    Elm_Navigationbar_Item *it;
846    Elm_Navigationbar_Item *prev_it;
847    Transit_Cb_Data *cb;
848
849    wd = elm_widget_data_get(obj);
850    if ((!wd) || (!content) || (!wd->stack)) return;
851
852    //find item to be popped and to be shown
853    it = prev_it = NULL;
854    ll = eina_list_last(wd->stack);
855    if (ll)
856      {
857         prev_it = ll->data;
858         ll =  ll->prev;
859      }
860    while (ll)
861      {
862         it = ll->data;
863         if ((it->base.widget) && (it->content != content))
864           {
865              _item_del(ll->data);
866              wd->stack = eina_list_remove_list(wd->stack, ll);
867              it = NULL;
868            }
869          else
870            break;
871          ll =  ll->prev;
872       }
873    if (prev_it && it)
874      {
875         //unswallow items and start trasition
876         cb = ELM_NEW(Transit_Cb_Data);
877         cb->prev_it = prev_it;
878         cb->it = it;
879         cb->pop = EINA_TRUE;
880         cb->first_page = EINA_FALSE;
881         cb->navibar = obj;
882
883         //TODO: make one call.
884         if (prev_it->title_obj)
885           edje_object_part_unswallow(wd->base, prev_it->title_obj);
886         if (prev_it->title_btns[ELM_NAVIGATIONBAR_PREV_BUTTON])
887           edje_object_part_unswallow(wd->base, prev_it->title_btns[ELM_NAVIGATIONBAR_PREV_BUTTON]);
888         if (prev_it->title_btns[ELM_NAVIGATIONBAR_NEXT_BUTTON])
889           edje_object_part_unswallow(wd->base, prev_it->title_btns[ELM_NAVIGATIONBAR_NEXT_BUTTON]);
890
891         _item_sizing_eval(it);
892         _transition_complete_cb(cb);
893
894         elm_pager_to_content_pop(wd->pager, content);
895      }
896 }
897
898 /**
899  * Set the title string for the pushed content
900  *
901  * @param[in] obj The NavigationBar object
902  * @param[in] content The object to push or pushed
903  * @param[in] title The title string
904  *
905  * @ingroup NavigationBar
906  */
907 EAPI void
908 elm_navigationbar_title_label_set(Evas_Object *obj, Evas_Object *content, const char *title)
909 {
910    ELM_CHECK_WIDTYPE(obj, widtype);
911    Widget_Data *wd;
912    Elm_Navigationbar_Item *it;
913
914    if (!content) return;
915
916    wd = elm_widget_data_get(obj);
917    if (!wd) return;
918
919    it = evas_object_data_get(content, _navigationbar_key);
920    if (!it) return;
921
922    eina_stringshare_replace(&it->title, title);
923    edje_object_part_text_set(wd->base, "elm.text", title);
924    _item_sizing_eval(it);
925 }
926
927 /**
928  * Return the title string of the pushed content
929  *
930  * @param[in] obj The NavigationBar object
931  * @param[in] content The object to push or pushed
932  * @return The title string or NULL if none
933  *
934  * @ingroup NavigationBar
935  */
936 EAPI const char *
937 elm_navigationbar_title_label_get(Evas_Object *obj, Evas_Object *content)
938 {
939    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
940    Widget_Data *wd;
941    Elm_Navigationbar_Item *it;
942
943    if (!content) return NULL;
944
945    wd = elm_widget_data_get(obj);
946    if (!wd) return NULL;
947
948    it = evas_object_data_get(content, _navigationbar_key);
949    if (!it) return NULL;
950    return it->title;
951 }
952
953 /**
954  * Set the title icon for the pushed content
955  *
956  * @param[in] obj The NavigationBar object
957  * @param[in] content The object to push or pushed
958  * @param[in] icon The icon object
959  *
960  * @ingroup NavigationBar
961  */
962 EAPI void
963 elm_navigationbar_title_icon_set(Evas_Object *obj, Evas_Object *content, Evas_Object *icon)
964 {
965    ELM_CHECK_WIDTYPE(obj, widtype);
966    Widget_Data *wd;
967    Elm_Navigationbar_Item *it;
968    Evas_Object *swallow;
969
970    if (!content) return;
971
972     wd = elm_widget_data_get(obj);
973     if (!wd) return;
974
975    it = evas_object_data_get(content, _navigationbar_key);
976    if (!it) return;
977
978    if (it->icon == icon) return;
979    if (it->icon) evas_object_del(it->icon);
980    it->icon = icon;
981
982    if (!icon) return;
983
984    elm_widget_sub_object_add(obj, icon);
985    evas_object_event_callback_add(icon, EVAS_CALLBACK_DEL, _title_icon_del, it);
986    _item_sizing_eval(it);
987    //update if the content is the top item
988    if (elm_navigationbar_content_top_get(obj) != content)
989      return;
990
991    swallow = edje_object_part_swallow_get(wd->base, "elm.swallow.icon");
992    if (swallow)
993      {
994         edje_object_signal_emit(wd->base, "elm,state,icon,hidden", "elm");
995         edje_object_part_unswallow(wd->base, swallow);
996         evas_object_hide(swallow);
997      }
998    if (wd->title_visible)
999      {
1000         edje_object_part_swallow(wd->base, "elm.swallow.icon", icon);
1001         edje_object_signal_emit(wd->base, "elm,state,icon,visible", "elm");
1002         edje_object_message_signal_process(wd->base);
1003      }
1004    else
1005       edje_object_signal_emit(wd->base, "elm,state,icon,hidden", "elm");
1006 }
1007
1008 /**
1009  * Get the title icon for the pushed content
1010  *
1011  * @param[in] obj The NavigationBar object
1012  * @param[in] content The object to push or pushed
1013  * @return The icon object or NULL if none
1014  *
1015  * @ingroup NavigationBar
1016  */
1017 EAPI Evas_Object *
1018 elm_navigationbar_title_icon_get(Evas_Object *obj, Evas_Object *content)
1019 {
1020    ELM_CHECK_WIDTYPE(obj, widtype)NULL;
1021    Widget_Data *wd;
1022    Elm_Navigationbar_Item *it;
1023
1024    if (!content) return NULL;
1025
1026    wd = elm_widget_data_get(obj);
1027    if (!wd) return NULL;
1028
1029    it = evas_object_data_get(content, _navigationbar_key);
1030    if (!it) return NULL;
1031
1032    return it->icon;
1033 }
1034
1035 /**
1036  * Add a title object for the content.
1037  *
1038  * @param[in] obj The NavigationBar object
1039  * @param[in] content The object pushed
1040  * @param[in] title_obj a title object (normally button or segment_control)
1041  *
1042  * @ingroup NavigationBar
1043  */
1044 //TODO: elm_navigationbar_title_object_set ( .... )
1045 EAPI void
1046 elm_navigationbar_title_object_add(Evas_Object *obj, Evas_Object *content, Evas_Object *title_obj)
1047 {
1048    ELM_CHECK_WIDTYPE(obj, widtype);
1049    Widget_Data *wd;
1050    Elm_Navigationbar_Item *it;
1051
1052    if ((!title_obj) || (!content)) return;
1053
1054    wd = elm_widget_data_get(obj);
1055    if (!wd) return;
1056
1057    it = evas_object_data_get(content, _navigationbar_key);
1058    if (!it) return;
1059
1060    if (it->title_obj)
1061      {
1062        evas_object_event_callback_del(it->title_obj, EVAS_CALLBACK_DEL, _title_obj_del);
1063        evas_object_del(it->title_obj);
1064      }
1065
1066    it->title_obj = title_obj;
1067    elm_widget_sub_object_add(obj, title_obj);
1068    evas_object_event_callback_add(title_obj, EVAS_CALLBACK_DEL, _title_obj_del, it);
1069
1070    //TODO: Conserve this line for a while the object list get API is alive.
1071    eina_list_free(it->title_obj_list);
1072    it->title_obj_list = eina_list_append(NULL, title_obj);
1073
1074    if (elm_navigationbar_content_top_get(obj) != content)
1075      return;
1076
1077    edje_object_part_swallow(wd->base, "elm.swallow.title", title_obj);
1078
1079    //TODO: Looks something incorrect.
1080    if (wd->title_visible)
1081      {
1082        if (it->title)
1083          {
1084             edje_object_signal_emit(wd->base, "elm,state,show,extended", "elm");
1085             //TODO: for before nbeat?
1086             edje_object_signal_emit(wd->base, "elm,state,show,noanimate,title", "elm");
1087             it->titleobj_visible = EINA_TRUE;
1088          }
1089      }
1090    _item_sizing_eval(it);
1091 }
1092
1093 /**
1094  * Unset the list of title objects corresponding to given content and returns it to
1095  * the application.
1096  * @param[in] obj The NavigationBar object
1097  * @param[in] content The content object pushed
1098  * @param[out] list updates the list with title objects list, this list has to be freed and the
1099  * objects have to be deleted by application.
1100  * @ingroup NavigationBar
1101  */
1102 //TODO: remove!
1103 EAPI void
1104 elm_navigationbar_title_object_list_unset(Evas_Object *obj, Evas_Object *content, Eina_List **list)
1105 {
1106    ELM_CHECK_WIDTYPE(obj, widtype);
1107    Widget_Data *wd;
1108    Elm_Navigationbar_Item *it;
1109    Evas_Object *swallow;
1110
1111    if ((!list) || (!content)) return;
1112
1113    wd = elm_widget_data_get(obj);
1114    if (!wd) return;
1115
1116    it = evas_object_data_get(content, _navigationbar_key);
1117    if (!it) return;
1118
1119    *list = eina_list_append(*list, it->title_obj);
1120    it->title_obj = NULL;
1121
1122    if (elm_navigationbar_content_top_get(obj) != content)
1123      return;
1124
1125    //In this case, the content is in the last of the stack
1126    swallow = edje_object_part_swallow_get(wd->base, "elm.swallow.title");
1127    if (!swallow) return;
1128
1129    if (wd->title_visible)
1130     {
1131       if(it->titleobj_visible)
1132         {
1133           //TODO: remove the dependency on these signals as related to nbeat?
1134           edje_object_signal_emit(wd->base, "elm,state,hide,noanimate,title", "elm");
1135           it->titleobj_visible = EINA_FALSE;
1136         }
1137        edje_object_signal_emit(wd->base, "elm,state,hide,extended", "elm");
1138    }
1139    _item_sizing_eval(it);
1140 }
1141
1142 EAPI Evas_Object *
1143 elm_navigationbar_title_object_get(Evas_Object *obj, Evas_Object *content)
1144 {
1145    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1146    Widget_Data *wd;
1147    Elm_Navigationbar_Item *it;
1148
1149    if (!content) return NULL;
1150
1151    wd = elm_widget_data_get(obj);
1152    if (!wd) return NULL;
1153
1154    it = evas_object_data_get(content, _navigationbar_key);
1155    if (!it) return NULL;
1156
1157    return it->title_obj;
1158 }
1159
1160 /**
1161  * Return the list of title objects of the pushed content.
1162  *
1163  * @param[in] obj The NavigationBar object
1164  * @param[in] content The object to push or pushed
1165  * @return The list of title objects
1166  *
1167  * @ingroup NavigationBar
1168  */
1169 //TODO: Remove!!
1170 EAPI Eina_List *
1171 elm_navigationbar_title_object_list_get(Evas_Object *obj, Evas_Object *content)
1172 {
1173    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1174    Widget_Data *wd;
1175    Elm_Navigationbar_Item *it;
1176
1177    if (!content) return NULL;
1178
1179    wd = elm_widget_data_get(obj);
1180    if (!wd) return NULL;
1181
1182    it = evas_object_data_get(content, _navigationbar_key);
1183    if (!it) return NULL;
1184
1185    return it->title_obj_list;
1186 }
1187
1188 /**
1189  * Return the content object at the top of the NavigationBar stack
1190  *
1191  * @param[in] obj The NavigationBar object
1192  * @return The top content object or NULL if none
1193  *
1194  * @ingroup NavigationBar
1195  */
1196 EAPI Evas_Object *
1197 elm_navigationbar_content_top_get(Evas_Object *obj)
1198 {
1199    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1200    Widget_Data *wd = elm_widget_data_get(obj);
1201    if (!wd) return NULL;
1202    return elm_pager_content_top_get(wd->pager);
1203 }
1204
1205 /**
1206  * Return the content object at the bottom of the NavigationBar stack
1207  *
1208  * @param[in] obj The NavigationBar object
1209  * @return The bottom content object or NULL if none
1210  *
1211  * @ingroup NavigationBar
1212  */
1213 EAPI Evas_Object *
1214 elm_navigationbar_content_bottom_get(Evas_Object *obj)
1215 {
1216    ELM_CHECK_WIDTYPE(obj, widtype)NULL;
1217    Widget_Data *wd = elm_widget_data_get(obj);
1218    if (!wd) return NULL;
1219    return elm_pager_content_bottom_get(wd->pager);
1220 }
1221
1222 /**
1223  * This hides the title area of navigationbar.
1224  *
1225  * @param[in] obj The NavigationBar object
1226  * @param[in] hidden if EINA_TRUE the title area is hidden.
1227  *
1228  * @ingroup NavigationBar
1229  */
1230 //TODO: does not provide hidden get ?
1231 EAPI void
1232 elm_navigationbar_hidden_set(Evas_Object *obj,
1233                         Eina_Bool hidden)
1234 {
1235    ELM_CHECK_WIDTYPE(obj, widtype);
1236    Widget_Data *wd = elm_widget_data_get(obj);
1237    if (!wd) return;
1238
1239    if (hidden)
1240      edje_object_signal_emit(wd->base, "elm,state,item,moveup", "elm");
1241    else
1242      edje_object_signal_emit(wd->base, "elm,state,item,movedown", "elm");
1243
1244    wd->title_visible = !hidden;
1245 }
1246
1247 /**
1248  * Set the button object of the pushed content.
1249  *
1250  * @param[in] obj The NavigationBar object
1251  * @param[in] content The object to push or pushed
1252  * @param[in] button The button
1253  * @param[in] button_type Indicates the position
1254  *
1255  * @ingroup NavigationBar
1256  */
1257 EAPI void
1258 elm_navigationbar_title_button_set(Evas_Object *obj, Evas_Object *content, Evas_Object *button, Elm_Navi_Button_Type button_type)
1259 {
1260    ELM_CHECK_WIDTYPE(obj, widtype);
1261
1262    Widget_Data *wd;
1263    Elm_Navigationbar_Item *it;
1264
1265    if (!content) return;
1266
1267    wd = elm_widget_data_get(obj);
1268    if (!wd) return;
1269
1270    it = evas_object_data_get(content, _navigationbar_key);
1271    if (!it) return;
1272
1273    switch(button_type)
1274      {
1275       case ELM_NAVIGATIONBAR_PREV_BUTTON:
1276         _elm_navigationbar_prev_btn_set(obj, content, button, it);
1277         break;
1278       case ELM_NAVIGATIONBAR_NEXT_BUTTON:
1279         _elm_navigationbar_next_btn_set(obj, content, button, it);
1280         break;
1281       default:
1282         _elm_navigationbar_prev_btn_set(obj, content, button, it);
1283         break;
1284      }
1285    _sizing_eval(obj);
1286 }
1287
1288 /**
1289  * Return the button object of the pushed content
1290  *
1291  * @param[in] obj The NavigationBar object
1292  * @param[in] content The object to push or pushed
1293  * @param[in] button_type Indicates the position
1294  * @return The button object or NULL if none
1295  *
1296  * @ingroup NavigationBar
1297  */
1298 EAPI Evas_Object *
1299 elm_navigationbar_title_button_get(Evas_Object *obj, Evas_Object *content, Elm_Navi_Button_Type button_type)
1300 {
1301    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1302    Widget_Data *wd;
1303    Elm_Navigationbar_Item *it;
1304
1305    if (!content) return NULL;
1306
1307    wd = elm_widget_data_get(obj);
1308    if (!wd) return NULL;
1309
1310    it = evas_object_data_get(content, _navigationbar_key);
1311    if (!it) return NULL;
1312
1313    switch(button_type)
1314      {
1315         case ELM_NAVIGATIONBAR_PREV_BUTTON:
1316            return it->title_btns[ELM_NAVIGATIONBAR_PREV_BUTTON];
1317         case ELM_NAVIGATIONBAR_NEXT_BUTTON:
1318            return it->title_btns[ELM_NAVIGATIONBAR_NEXT_BUTTON];
1319         default:
1320            return it->title_btns[ELM_NAVIGATIONBAR_PREV_BUTTON];
1321      }
1322    return NULL;
1323 }
1324
1325 /**
1326  * Set the sub title string for the pushed content.
1327  *
1328  * @param[in] obj The NavigationBar object
1329  * @param[in] content The object to push or pushed
1330  * @param[in] subtitle The subtitle string
1331  *
1332  * @ingroup NavigationBar
1333  */
1334 EAPI void
1335 elm_navigationbar_subtitle_label_set(Evas_Object *obj, Evas_Object *content, const char *subtitle)
1336 {
1337    ELM_CHECK_WIDTYPE(obj, widtype);
1338    Widget_Data *wd;
1339    Elm_Navigationbar_Item *it;
1340
1341    wd = elm_widget_data_get(obj);
1342    if (!wd) return;
1343
1344    it = evas_object_data_get(content, _navigationbar_key);
1345    if (!it) return;
1346
1347    eina_stringshare_replace(&it->subtitle, subtitle);
1348    edje_object_part_text_set(wd->base, "elm.text.sub", subtitle);
1349    _item_sizing_eval(it);
1350 }
1351
1352 /**
1353  * Return the subtitle string of the pushed content.
1354  *
1355  * @param[in] obj The NavigationBar object
1356  * @param[in] content The object to push or pushed
1357  * @return The subtitle string or NULL if none
1358  *
1359  * @ingroup NavigationBar
1360  */
1361 EAPI const char *
1362 elm_navigationbar_subtitle_label_get(Evas_Object *obj, Evas_Object *content)
1363 {
1364    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1365    Widget_Data *wd;
1366    Elm_Navigationbar_Item *it;
1367
1368    wd = elm_widget_data_get(obj);
1369    if (!wd) return NULL;
1370
1371    it = evas_object_data_get(content, _navigationbar_key);
1372    if (!it) return NULL;
1373    return it->subtitle;
1374 }
1375
1376 /**
1377  * This disables content area animation on push/pop.
1378  *
1379  * @param[in] obj The NavigationBar object
1380  * @param[in] disable  if EINA_TRUE animation is disabled.
1381  *
1382  * @ingroup NavigationBar
1383  */
1384 //TODO: Let's check to remove this API.
1385 EAPI void
1386 elm_navigationbar_animation_disabled_set(Evas_Object *obj, Eina_Bool disable)
1387 {
1388    ELM_CHECK_WIDTYPE(obj, widtype);
1389    Widget_Data *wd = elm_widget_data_get(obj);
1390    if (!wd) return;
1391    elm_pager_animation_disabled_set(wd->pager, disable);
1392 }
1393
1394 /**
1395  * This shows/hides title object area.
1396  *
1397  * @param[in] obj The NavigationBar object
1398  * @param[in] show  if EINA_TRUE title object is shown else its hidden.
1399  * @param[in] content  The content object packed in navigationbar.
1400  * @ingroup NavigationBar
1401  */
1402 EAPI void
1403 elm_navigationbar_title_object_visible_set(Evas_Object *obj, Evas_Object *content, Eina_Bool visible)
1404 {
1405     ELM_CHECK_WIDTYPE(obj, widtype);
1406     Elm_Navigationbar_Item *it;
1407     Widget_Data *wd;
1408
1409     if (!content) return;
1410
1411     wd = elm_widget_data_get(obj);
1412     if (!wd) return;
1413
1414     it = evas_object_data_get(content, _navigationbar_key);
1415     if (!it) return;
1416     if (it->titleobj_visible == visible) return;
1417     it->titleobj_visible = visible;
1418     _titleobj_switching(obj, it);
1419 }
1420
1421 /**
1422  * This gets the status whether title object is shown/hidden.
1423  *
1424  * @param[in] obj The NavigationBar object
1425  * @param[in] content  The content object packed in navigationbar.
1426  * @return The status whether title object is shown/hidden.
1427  * @ingroup NavigationBar
1428  */
1429 Eina_Bool
1430 elm_navigationbar_title_object_visible_get(Evas_Object *obj, Evas_Object *content)
1431 {
1432    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
1433    Elm_Navigationbar_Item *it;
1434    Widget_Data *wd;
1435
1436    if (!content) return EINA_FALSE;
1437
1438    wd = elm_widget_data_get(obj);
1439    if (!wd) return EINA_FALSE;
1440
1441    it = evas_object_data_get(content, _navigationbar_key);
1442    if (!it) return EINA_FALSE;
1443
1444    return it->titleobj_visible;
1445 }