Merge branch 'master' into svn_merge
[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 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,
84                                             Evas_Object *content,
85                                             Evas_Object *new_btn,
86                                             Elm_Navigationbar_Item *it);
87 static void _elm_navigationbar_next_btn_set(Evas_Object *obj,
88                                             Evas_Object *content,
89                                             Evas_Object *new_btn,
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);
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_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);
170    return btn;
171 }
172
173 static void
174 _del_hook(Evas_Object *obj)
175 {
176    Widget_Data *wd = elm_widget_data_get(obj);
177    Eina_List *list;
178    Elm_Navigationbar_Item *it;
179
180    EINA_LIST_FOREACH(wd->stack, list, it)
181      _item_del(it);
182    eina_list_free(wd->stack);
183    free(wd);
184 }
185
186 static void
187 _theme_hook(Evas_Object *obj)
188 {
189    Widget_Data *wd = elm_widget_data_get(obj);
190    Eina_List *list = NULL;
191    Elm_Navigationbar_Item *it = NULL;
192    char buf_fn[4096];
193
194    if (!wd) return;
195    _elm_theme_object_set(obj, wd->base, "navigationbar", "base", elm_widget_style_get(obj));
196    EINA_LIST_FOREACH(wd->stack, list, it)
197      {
198         if (it->title_btns[ELM_NAVIGATIONBAR_PREV_BUTTON])
199          {
200             if (it->back_btn)
201               snprintf(buf_fn, sizeof(buf_fn), "navigationbar_prev_btn/%s", elm_widget_style_get(obj));
202             else
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);
205          }
206         if (it->title_btns[ELM_NAVIGATIONBAR_NEXT_BUTTON])
207          {
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);
210          }
211      }
212    edje_object_message_signal_process(wd->base);
213    _sizing_eval(obj);
214 }
215
216 static void
217 _item_del(Elm_Navigationbar_Item *it)
218 {
219    //TODO: So hard to manage.
220    //TODO: Just prepare one layout for title objects.
221    //TODO: then remove the layout only.
222    Widget_Data *wd;
223    int idx;
224
225    if (!it) return;
226
227    wd = elm_widget_data_get(it->base.widget);
228    if (!wd) return;
229
230    //Remove Function Buttons
231    for (idx = 0; idx < ELM_NAVIGATIONBAR_TITLE_BTN_CNT; idx++)
232      {
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]);
237      }
238    if (it->icon)
239      {
240         evas_object_event_callback_del(it->icon, EVAS_CALLBACK_DEL, _title_icon_del);
241         evas_object_del(it->icon);
242      }
243    if (it->title_obj)
244      {
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);
248      }
249    if (it->title) eina_stringshare_del(it->title);
250    if (it->subtitle) eina_stringshare_del(it->subtitle);
251
252    if (it->content)
253      {
254         evas_object_data_del(it->content, _navigationbar_key);
255         evas_object_event_callback_del(it->content, EVAS_CALLBACK_DEL, _content_del);
256      }
257
258    free(it);
259 }
260
261 static void
262 _sizing_eval(Evas_Object *obj)
263 {
264    Widget_Data *wd;
265    Eina_List *list;
266
267    wd  = elm_widget_data_get(obj);
268    if (!wd) return;
269
270    list = eina_list_last(wd->stack);
271    if (!list) return;
272
273    _item_sizing_eval(list->data);
274 }
275
276 static void
277 _item_sizing_eval(Elm_Navigationbar_Item *it)
278 {
279    if (!it) return;
280    Widget_Data *wd = elm_widget_data_get(it->base.widget);
281    Evas_Coord minw;
282
283    if (!wd) return;
284
285    edje_object_size_min_calc(wd->base, &minw, NULL);
286
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]);
291 }
292
293 static void
294 _resize(void *data __UNUSED__, Evas *e  __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
295 {
296    _sizing_eval(obj);
297 }
298
299 static void
300 _titleobj_switching(Evas_Object *obj, Elm_Navigationbar_Item *it)
301 {
302    Widget_Data *wd = elm_widget_data_get(obj);
303    if (!wd) return;
304
305    if (!it->title_obj) return;
306
307    if (elm_navigationbar_content_top_get(it->base.widget) != it->content)
308      return;
309
310    if (it->titleobj_visible)
311      edje_object_signal_emit(wd->base, "elm,state,show,title", "elm"); //elm,state,title,show
312    else
313      edje_object_signal_emit(wd->base, "elm,state,hide,title", "elm"); //elm,state,title,hide
314
315    _item_sizing_eval(it);
316 }
317
318 static void
319 _title_clicked(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
320 {
321    Evas_Object *navibar = data;
322    Widget_Data *wd;
323    Eina_List *last;
324    Elm_Navigationbar_Item *it;
325
326    wd = elm_widget_data_get(navibar);
327    if (!wd) return;
328
329    last = eina_list_last(wd->stack);
330    if (!last) return;
331
332    it = eina_list_data_get(last);
333    if ((!it) || (!it->title_obj)) return;
334
335    if (!it->titleobj_visible)
336      {
337         it->titleobj_visible = EINA_TRUE;
338         evas_object_smart_callback_call(it->base.widget, SIG_TITLE_OBJ_VISIBLE_CHANGED, (void *) EINA_TRUE);
339      }
340    else
341      {
342         it->titleobj_visible = EINA_FALSE;
343         evas_object_smart_callback_call(it->base.widget, SIG_TITLE_OBJ_VISIBLE_CHANGED, (void *) EINA_FALSE);
344      }
345
346    evas_object_smart_callback_call(navibar, SIG_TITLE_CLICKED, NULL);
347
348    _titleobj_switching(navibar, it);
349 }
350
351 //TODO: should be renamed.
352 static void
353 _transition_complete_cb(void *data)
354 {
355    Evas_Object *navi_bar;
356    Widget_Data *wd;
357    Elm_Navigationbar_Item *prev_it;
358    Elm_Navigationbar_Item *it;
359    Eina_List *ll;
360
361    Transit_Cb_Data *cb = data;
362    if (!cb) return;
363
364    navi_bar = cb->navibar;
365    if (!navi_bar) return;
366
367    wd = elm_widget_data_get(navi_bar);
368    if (!wd) return;
369
370    prev_it = cb->prev_it;
371    it = cb->it;
372
373    if (cb->pop && prev_it)
374      {
375         ll = eina_list_last(wd->stack);
376         if (ll->data == prev_it)
377           {
378              _item_del(prev_it);
379              wd->stack = eina_list_remove_list(wd->stack, ll);
380           }
381      }
382    else if (prev_it)
383      {
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);
390         if (prev_it->icon)
391           evas_object_hide(prev_it->icon);
392      }
393    if ((it) && (wd->title_visible))
394      {
395         edje_object_part_text_set(wd->base, "elm.text", it->title);
396
397         if (!cb->first_page)
398           {
399              if (cb->pop)
400                edje_object_signal_emit(wd->base, "elm,action,pop", "elm");
401              else
402                edje_object_signal_emit(wd->base, "elm,action,push", "elm");
403              evas_object_pass_events_set(wd->base, EINA_TRUE);
404           }
405         if (it->title_obj)
406           {
407              edje_object_part_swallow(wd->base, "elm.swallow.title", it->title_obj);
408           }
409         if (it->subtitle)
410           edje_object_part_text_set(wd->base, "elm.text.sub", it->subtitle);
411         else
412           edje_object_part_text_set(wd->base, "elm.text.sub", NULL);
413
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]);
418
419         if(it->icon)
420           {
421              edje_object_part_swallow(wd->base, "elm.swallow.icon", it->icon);
422              edje_object_signal_emit(wd->base, "elm,state,icon,visible", "elm");
423           }
424         else
425           edje_object_signal_emit(wd->base, "elm,state,icon,hidden", "elm");
426
427         if ((it->title_obj) && (it->title))
428           {
429              edje_object_signal_emit(wd->base, "elm,state,show,extended", "elm");
430              if(it->titleobj_visible)
431                {
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");
434                }
435              else
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");
438           }
439         else
440           {
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;
445           }
446      }
447 }
448
449 static void
450 _back_button_clicked(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
451 {
452    Elm_Navigationbar_Item *it = data;
453    elm_navigationbar_pop(it->base.widget);
454 }
455
456 static void
457 _hide_finished(void *data, Evas_Object *obj __UNUSED__, void *event_info)
458 {
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);
464 }
465
466 static void
467 _button_size_set(Evas_Object *obj)
468 {
469    if (!obj) return;
470    Evas_Coord minw = -1, minh = -1, maxw= -1, maxh = -1;
471    Evas_Coord w = 0, h = 0;
472
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);
481 }
482
483 static void
484 _elm_navigationbar_prev_btn_set(Evas_Object *obj, Evas_Object *content, Evas_Object *new_btn, Elm_Navigationbar_Item *it)
485 {
486    Widget_Data *wd;
487    Evas_Object *prev_btn;
488
489    wd = elm_widget_data_get(obj);
490    if (!wd) return;
491
492    if (!_title_btn_set(it, new_btn, ELM_NAVIGATIONBAR_PREV_BUTTON, EINA_FALSE))
493      return;
494
495    //update if the content is the top item
496    if (elm_navigationbar_content_top_get(obj) != content)
497      return;
498
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);
502 }
503
504 //TODO: looks make this  _elm_navigationbar_function_button1_set  same.
505 static void
506 _elm_navigationbar_next_btn_set(Evas_Object *obj, Evas_Object *content, Evas_Object *new_btn, Elm_Navigationbar_Item *it)
507 {
508    Widget_Data *wd;
509    Evas_Object *prev_btn;
510
511    wd = elm_widget_data_get(obj);
512    if (!wd) return;
513
514    if (!_title_btn_set(it, new_btn, ELM_NAVIGATIONBAR_NEXT_BUTTON, EINA_FALSE))
515      return;
516
517    //update if the content is the top item
518    if (elm_navigationbar_content_top_get(obj) != content)
519      return;
520
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);
524 }
525
526 static Eina_Bool
527 _button_set(Evas_Object *obj, Evas_Object *prev_btn, Evas_Object *new_btn, Eina_Bool back_btn)
528 {
529    char buf[4096];   //TODO: How to guarantee this buffer size?
530    Eina_Bool changed = EINA_FALSE;
531
532    if (prev_btn)
533      {
534         changed = EINA_TRUE;
535         evas_object_del(prev_btn);
536      }
537    if (!new_btn) return changed;
538
539    if (back_btn)
540      {
541         snprintf(buf, sizeof(buf), "navigationbar_prev_btn/%s", elm_widget_style_get(obj));
542         elm_object_style_set(new_btn, buf);
543      }
544    else
545      {
546         snprintf(buf, sizeof(buf), "navigationbar_next_btn/%s", elm_widget_style_get(obj));
547         elm_object_style_set(new_btn, buf);
548      }
549
550    elm_widget_sub_object_add(obj, new_btn);
551    changed = EINA_TRUE;
552
553    return changed;
554 }
555
556 /**
557  * Add a new navigationbar to the parent
558  *
559  * @param[in] parent The parent object
560  * @return The new object or NULL if it cannot be created
561  *
562  * @ingroup NavigationBar
563  */
564 EAPI Evas_Object *
565 elm_navigationbar_add(Evas_Object *parent)
566 {
567    Evas_Object *obj;
568    Evas *e;
569    Widget_Data *wd;
570
571    EINA_SAFETY_ON_NULL_RETURN_VAL(parent, NULL);
572
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);
582
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);
589
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);
598
599    wd->title_visible = EINA_TRUE;
600
601    evas_object_smart_callbacks_descriptions_set(obj, _signals);
602
603    //TODO: apply elm_object_disabled_set
604
605    return obj;
606 }
607
608 /**
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.
612  *
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
619  *
620  * @ingroup NavigationBar
621  */
622 EAPI void
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)
624 {
625    ELM_CHECK_WIDTYPE(obj, widtype);
626
627    Widget_Data *wd;
628    Elm_Navigationbar_Item *it;
629    Elm_Navigationbar_Item *top_it;
630
631    if (!content) return;
632
633    wd = elm_widget_data_get(obj);
634    if (!wd) return;
635
636    if (evas_object_data_get(content, _navigationbar_key)) return;
637
638    it = elm_widget_item_new(obj, Elm_Navigationbar_Item);
639    if (!it) return;
640
641    top_it = eina_list_data_get(eina_list_last(wd->stack));
642
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);
645
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);
649
650    //Add a prev-button automatically.
651    if ((!prev_btn) && (top_it))
652    {
653       if (top_it->title)
654         _title_btn_set(it, _create_back_btn(obj, top_it->title, it), ELM_NAVIGATIONBAR_PREV_BUTTON, EINA_TRUE);
655       else
656         _title_btn_set(it, _create_back_btn(obj, _ELM_NAVIBAR_PREV_BTN_DEFAULT_LABEL, it), ELM_NAVIGATIONBAR_PREV_BUTTON, EINA_TRUE);
657    }
658
659    eina_stringshare_replace(&it->title, title);
660    edje_object_part_text_set(wd->base, "elm.text", title);
661    _item_sizing_eval(it);
662
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?
666    if (top_it)
667      {
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]);
675         if (top_it->icon)
676           edje_object_part_unswallow(wd->base, top_it->icon);
677      }
678    //If page is the first, then do not run the transition... but if user want.. ?
679    else
680      {
681         cb->prev_it = NULL;
682         cb->first_page = EINA_TRUE;
683      }
684    cb->navibar = obj;
685    cb->it = it;
686    cb->pop = EINA_FALSE;
687
688    _transition_complete_cb(cb);
689    free(cb);
690    elm_pager_content_push(wd->pager, it->content);
691
692    wd->stack = eina_list_append(wd->stack, it);
693    _sizing_eval(obj);
694 }
695
696 /**
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.
699  *
700  * @param[in] obj The NavigationBar object
701  *
702  * @ingroup NavigationBar
703  */
704 EAPI void
705 elm_navigationbar_pop(Evas_Object *obj)
706 {
707    ELM_CHECK_WIDTYPE(obj, widtype);
708    Widget_Data *wd = elm_widget_data_get(obj);
709    Eina_List *ll;
710    Transit_Cb_Data *cb;
711    Elm_Navigationbar_Item *it = NULL;
712    Elm_Navigationbar_Item *prev_it = NULL;
713
714    //TODO: It's impossible to pop while popping?
715    if (wd->popping) return;
716    if (!wd->stack) return;
717
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);
721    if (ll)
722      {
723         prev_it = ll->data;
724         ll = ll->prev;
725         if (ll)
726           it = ll->data;
727      }
728    //unswallow items and start trasition
729    cb = ELM_NEW(Transit_Cb_Data);
730
731    //Previous page is exist.
732    if (prev_it && it)
733      {
734         cb->prev_it = prev_it;
735         cb->it = it;
736         cb->pop = EINA_TRUE;
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]);
743         if (prev_it->icon)
744           edje_object_part_unswallow(wd->base, prev_it->icon);
745         _item_sizing_eval(it);
746      }
747    //This case, it's the last page.
748    else if (prev_it)
749      {
750         cb->prev_it = prev_it;
751         cb->it = NULL;
752         cb->pop = EINA_TRUE;
753         //TODO: seems that flag is inverted.
754         cb->first_page = EINA_FALSE;
755      }
756    cb->navibar = obj;
757    _transition_complete_cb(cb);
758    wd->popping = EINA_TRUE;
759
760    elm_pager_content_pop(wd->pager);
761
762    if ((prev_it) && (!it))
763      edje_object_part_text_set(wd->base, "elm.text", NULL);
764
765    free(cb);
766 }
767
768 /**
769  * This Pops to the given content object (and update it) by deleting rest of the objects in between.
770  *
771  * @param[in] obj The NavigationBar object
772  * @param[in] content the object to show
773  *
774  * @ingroup NavigationBar
775  */
776 EAPI void
777 elm_navigationbar_to_content_pop(Evas_Object *obj, Evas_Object *content)
778 {
779    ELM_CHECK_WIDTYPE(obj, widtype);
780
781    Widget_Data *wd;
782    Eina_List *ll;
783    Elm_Navigationbar_Item *it;
784    Elm_Navigationbar_Item *prev_it;
785    Transit_Cb_Data *cb;
786
787    wd = elm_widget_data_get(obj);
788    if ((!wd) || (!content) || (!wd->stack)) return;
789
790    //find item to be popped and to be shown
791    it = prev_it = NULL;
792    ll = eina_list_last(wd->stack);
793    if (ll)
794      {
795         prev_it = ll->data;
796         ll =  ll->prev;
797      }
798    while (ll)
799      {
800         it = ll->data;
801         if ((it->base.widget) && (it->content != content))
802           {
803              _item_del(ll->data);
804              wd->stack = eina_list_remove_list(wd->stack, ll);
805              it = NULL;
806            }
807          else
808            break;
809          ll =  ll->prev;
810       }
811    if (prev_it && it)
812      {
813         //unswallow items and start trasition
814         cb = ELM_NEW(Transit_Cb_Data);
815         cb->prev_it = prev_it;
816         cb->it = it;
817         cb->pop = EINA_TRUE;
818         cb->first_page = EINA_FALSE;
819         cb->navibar = obj;
820
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]);
828
829         _item_sizing_eval(it);
830         _transition_complete_cb(cb);
831
832         elm_pager_to_content_pop(wd->pager, content);
833      }
834 }
835
836 /**
837  * Set the title string for the pushed content
838  *
839  * @param[in] obj The NavigationBar object
840  * @param[in] content The object to push or pushed
841  * @param[in] title The title string
842  *
843  * @ingroup NavigationBar
844  */
845 EAPI void
846 elm_navigationbar_title_label_set(Evas_Object *obj, Evas_Object *content, const char *title)
847 {
848    ELM_CHECK_WIDTYPE(obj, widtype);
849    Widget_Data *wd;
850    Elm_Navigationbar_Item *it;
851
852    if (!content) return;
853
854    wd = elm_widget_data_get(obj);
855    if (!wd) return;
856
857    it = evas_object_data_get(content, _navigationbar_key);
858    if (!it) return;
859
860    eina_stringshare_replace(&it->title, title);
861    edje_object_part_text_set(wd->base, "elm.text", title);
862    _item_sizing_eval(it);
863 }
864
865 /**
866  * Return the title string of the pushed content
867  *
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
871  *
872  * @ingroup NavigationBar
873  */
874 EAPI const char *
875 elm_navigationbar_title_label_get(Evas_Object *obj, Evas_Object *content)
876 {
877    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
878    Widget_Data *wd;
879    Elm_Navigationbar_Item *it;
880
881    if (!content) return NULL;
882
883    wd = elm_widget_data_get(obj);
884    if (!wd) return NULL;
885
886    it = evas_object_data_get(content, _navigationbar_key);
887    if (!it) return NULL;
888    return it->title;
889 }
890
891 /**
892  * Set the title icon for the pushed content
893  *
894  * @param[in] obj The NavigationBar object
895  * @param[in] content The object to push or pushed
896  * @param[in] icon The icon object
897  *
898  * @ingroup NavigationBar
899  */
900 EAPI void
901 elm_navigationbar_title_icon_set(Evas_Object *obj, Evas_Object *content, Evas_Object *icon)
902 {
903    ELM_CHECK_WIDTYPE(obj, widtype);
904    Widget_Data *wd;
905    Elm_Navigationbar_Item *it;
906    Evas_Object *swallow;
907
908    if (!content) return;
909
910     wd = elm_widget_data_get(obj);
911     if (!wd) return;
912
913    it = evas_object_data_get(content, _navigationbar_key);
914    if (!it) return;
915
916    if (it->icon == icon) return;
917    if (it->icon) evas_object_del(it->icon);
918    it->icon = icon;
919
920    if (!icon) return;
921
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)
927      return;
928
929    swallow = edje_object_part_swallow_get(wd->base, "elm.swallow.icon");
930    if (swallow)
931      {
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);
935      }
936    if (wd->title_visible)
937      {
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);
941      }
942    else
943       edje_object_signal_emit(wd->base, "elm,state,icon,hidden", "elm");
944 }
945
946 /**
947  * Get the title icon for the pushed content
948  *
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
952  *
953  * @ingroup NavigationBar
954  */
955 EAPI Evas_Object *
956 elm_navigationbar_title_icon_get(Evas_Object *obj, Evas_Object *content)
957 {
958    ELM_CHECK_WIDTYPE(obj, widtype)NULL;
959    Widget_Data *wd;
960    Elm_Navigationbar_Item *it;
961
962    if (!content) return NULL;
963
964    wd = elm_widget_data_get(obj);
965    if (!wd) return NULL;
966
967    it = evas_object_data_get(content, _navigationbar_key);
968    if (!it) return NULL;
969
970    return it->icon;
971 }
972
973 /**
974  * Add a title object for the content.
975  *
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)
979  *
980  * @ingroup NavigationBar
981  */
982 //TODO: elm_navigationbar_title_object_set ( .... )
983 EAPI void
984 elm_navigationbar_title_object_add(Evas_Object *obj, Evas_Object *content, Evas_Object *title_obj)
985 {
986    ELM_CHECK_WIDTYPE(obj, widtype);
987    Widget_Data *wd;
988    Elm_Navigationbar_Item *it;
989
990    if ((!title_obj) || (!content)) return;
991
992    wd = elm_widget_data_get(obj);
993    if (!wd) return;
994
995    it = evas_object_data_get(content, _navigationbar_key);
996    if (!it) return;
997
998    if (it->title_obj)
999      {
1000        evas_object_event_callback_del(it->title_obj, EVAS_CALLBACK_DEL, _title_obj_del);
1001        evas_object_del(it->title_obj);
1002      }
1003
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);
1007
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);
1011
1012    if (elm_navigationbar_content_top_get(obj) != content)
1013      return;
1014
1015    edje_object_part_swallow(wd->base, "elm.swallow.title", title_obj);
1016
1017    //TODO: Looks something incorrect. 
1018    if (wd->title_visible)
1019      {
1020        if (it->title)
1021          {
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;
1026          }
1027      }
1028    _item_sizing_eval(it);
1029 }
1030
1031 /**
1032  * Unset the list of title objects corresponding to given content and returns it to
1033  * the application.
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
1039  */
1040 //TODO: remove!
1041 EAPI void
1042 elm_navigationbar_title_object_list_unset(Evas_Object *obj, Evas_Object *content, Eina_List **list)
1043 {
1044    ELM_CHECK_WIDTYPE(obj, widtype);
1045    Widget_Data *wd;
1046    Elm_Navigationbar_Item *it;
1047    Evas_Object *swallow;
1048
1049    if ((!list) || (!content)) return;
1050
1051    wd = elm_widget_data_get(obj);
1052    if (!wd) return;
1053
1054    it = evas_object_data_get(content, _navigationbar_key);
1055    if (!it) return;
1056
1057    *list = eina_list_append(*list, it->title_obj);
1058    it->title_obj = NULL;
1059
1060    if (elm_navigationbar_content_top_get(obj) != content)
1061      return;
1062
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;
1066
1067    if (wd->title_visible)
1068     {
1069       if(it->titleobj_visible)
1070         {
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;
1074         }
1075        edje_object_signal_emit(wd->base, "elm,state,hide,extended", "elm");
1076    }
1077    _item_sizing_eval(it);
1078 }
1079
1080 EAPI Evas_Object *
1081 elm_navigationbar_title_object_get(Evas_Object *obj, Evas_Object *content)
1082 {
1083    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1084    Widget_Data *wd;
1085    Elm_Navigationbar_Item *it;
1086
1087    if (!content) return NULL;
1088
1089    wd = elm_widget_data_get(obj);
1090    if (!wd) return NULL;
1091
1092    it = evas_object_data_get(content, _navigationbar_key);
1093    if (!it) return NULL;
1094
1095    return it->title_obj;
1096 }
1097
1098 /**
1099  * Return the list of title objects of the pushed content.
1100  *
1101  * @param[in] obj The NavigationBar object
1102  * @param[in] content The object to push or pushed
1103  * @return The list of title objects
1104  *
1105  * @ingroup NavigationBar
1106  */
1107 //TODO: Remove!!
1108 EAPI Eina_List *
1109 elm_navigationbar_title_object_list_get(Evas_Object *obj, Evas_Object *content)
1110 {
1111    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1112    Widget_Data *wd;
1113    Elm_Navigationbar_Item *it;
1114
1115    if (!content) return NULL;
1116
1117    wd = elm_widget_data_get(obj);
1118    if (!wd) return NULL;
1119
1120    it = evas_object_data_get(content, _navigationbar_key);
1121    if (!it) return NULL;
1122
1123    return it->title_obj_list;
1124 }
1125
1126 /**
1127  * Return the content object at the top of the NavigationBar stack
1128  *
1129  * @param[in] obj The NavigationBar object
1130  * @return The top content object or NULL if none
1131  *
1132  * @ingroup NavigationBar
1133  */
1134 EAPI Evas_Object *
1135 elm_navigationbar_content_top_get(Evas_Object *obj)
1136 {
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);
1141 }
1142
1143 /**
1144  * Return the content object at the bottom of the NavigationBar stack
1145  *
1146  * @param[in] obj The NavigationBar object
1147  * @return The bottom content object or NULL if none
1148  *
1149  * @ingroup NavigationBar
1150  */
1151 EAPI Evas_Object *
1152 elm_navigationbar_content_bottom_get(Evas_Object *obj)
1153 {
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);
1158 }
1159
1160 /**
1161  * This hides the title area of navigationbar.
1162  *
1163  * @param[in] obj The NavigationBar object
1164  * @param[in] hidden if EINA_TRUE the title area is hidden.
1165  *
1166  * @ingroup NavigationBar
1167  */
1168 //TODO: does not provide hidden get ?
1169 EAPI void
1170 elm_navigationbar_hidden_set(Evas_Object *obj,
1171                         Eina_Bool hidden)
1172 {
1173    ELM_CHECK_WIDTYPE(obj, widtype);
1174    Widget_Data *wd = elm_widget_data_get(obj);
1175    if (!wd) return;
1176
1177    if (hidden)
1178      edje_object_signal_emit(wd->base, "elm,state,item,moveup", "elm");
1179    else
1180      edje_object_signal_emit(wd->base, "elm,state,item,movedown", "elm");
1181
1182    wd->title_visible = !hidden;
1183 }
1184
1185 /**
1186  * Set the button object of the pushed content.
1187  *
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
1192  *
1193  * @ingroup NavigationBar
1194  */
1195 EAPI void
1196 elm_navigationbar_title_button_set(Evas_Object *obj, Evas_Object *content, Evas_Object *button, Elm_Navi_Button_Type button_type)
1197 {
1198    ELM_CHECK_WIDTYPE(obj, widtype);
1199
1200    Widget_Data *wd;
1201    Elm_Navigationbar_Item *it;
1202
1203    if (!content) return;
1204
1205    wd = elm_widget_data_get(obj);
1206    if (!wd) return;
1207
1208    it = evas_object_data_get(content, _navigationbar_key);
1209    if (!it) return;
1210
1211    switch(button_type)
1212      {
1213       case ELM_NAVIGATIONBAR_PREV_BUTTON:
1214         _elm_navigationbar_prev_btn_set(obj, content, button, it);
1215         break;
1216       case ELM_NAVIGATIONBAR_NEXT_BUTTON:
1217         _elm_navigationbar_next_btn_set(obj, content, button, it);
1218         break;
1219       default:
1220         _elm_navigationbar_prev_btn_set(obj, content, button, it);
1221         break;
1222      }
1223    _sizing_eval(obj);
1224 }
1225
1226 /**
1227  * Return the button object of the pushed content
1228  *
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
1233  *
1234  * @ingroup NavigationBar
1235  */
1236 EAPI Evas_Object *
1237 elm_navigationbar_title_button_get(Evas_Object *obj, Evas_Object *content, Elm_Navi_Button_Type button_type)
1238 {
1239    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1240    Widget_Data *wd;
1241    Elm_Navigationbar_Item *it;
1242
1243    if (!content) return NULL;
1244
1245    wd = elm_widget_data_get(obj);
1246    if (!wd) return NULL;
1247
1248    it = evas_object_data_get(content, _navigationbar_key);
1249    if (!it) return NULL;
1250
1251    switch(button_type)
1252      {
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];
1257         default:
1258            return it->title_btns[ELM_NAVIGATIONBAR_PREV_BUTTON];
1259      }
1260    return NULL;
1261 }
1262
1263 /**
1264  * Set the sub title string for the pushed content.
1265  *
1266  * @param[in] obj The NavigationBar object
1267  * @param[in] content The object to push or pushed
1268  * @param[in] subtitle The subtitle string
1269  *
1270  * @ingroup NavigationBar
1271  */
1272 EAPI void
1273 elm_navigationbar_subtitle_label_set(Evas_Object *obj, Evas_Object *content, const char *subtitle)
1274 {
1275    ELM_CHECK_WIDTYPE(obj, widtype);
1276    Widget_Data *wd;
1277    Elm_Navigationbar_Item *it;
1278
1279    wd = elm_widget_data_get(obj);
1280    if (!wd) return;
1281
1282    it = evas_object_data_get(content, _navigationbar_key);
1283    if (!it) return;
1284
1285    eina_stringshare_replace(&it->subtitle, subtitle);
1286    edje_object_part_text_set(wd->base, "elm.text.sub", subtitle);
1287    _item_sizing_eval(it);
1288 }
1289
1290 /**
1291  * Return the subtitle string of the pushed content.
1292  *
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
1296  *
1297  * @ingroup NavigationBar
1298  */
1299 EAPI const char *
1300 elm_navigationbar_subtitle_label_get(Evas_Object *obj, Evas_Object *content)
1301 {
1302    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1303    Widget_Data *wd;
1304    Elm_Navigationbar_Item *it;
1305
1306    wd = elm_widget_data_get(obj);
1307    if (!wd) return NULL;
1308
1309    it = evas_object_data_get(content, _navigationbar_key);
1310    if (!it) return NULL;
1311    return it->subtitle;
1312 }
1313
1314 /**
1315  * This disables content area animation on push/pop.
1316  *
1317  * @param[in] obj The NavigationBar object
1318  * @param[in] disable  if EINA_TRUE animation is disabled.
1319  *
1320  * @ingroup NavigationBar
1321  */
1322 //TODO: Let's check to remove this API.
1323 EAPI void
1324 elm_navigationbar_animation_disabled_set(Evas_Object *obj, Eina_Bool disable)
1325 {
1326    ELM_CHECK_WIDTYPE(obj, widtype);
1327    Widget_Data *wd = elm_widget_data_get(obj);
1328    if (!wd) return;
1329    elm_pager_animation_disabled_set(wd->pager, disable);
1330 }
1331
1332 /**
1333  * This shows/hides title object area.
1334  *
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
1339  */
1340 EAPI void
1341 elm_navigationbar_title_object_visible_set(Evas_Object *obj, Evas_Object *content, Eina_Bool visible)
1342 {
1343     ELM_CHECK_WIDTYPE(obj, widtype);
1344     Elm_Navigationbar_Item *it;
1345     Widget_Data *wd;
1346
1347     if (!content) return;
1348
1349     wd = elm_widget_data_get(obj);
1350     if (!wd) return;
1351
1352     it = evas_object_data_get(content, _navigationbar_key);
1353     if (!it) return;
1354     if (it->titleobj_visible == visible) return;
1355     it->titleobj_visible = visible;
1356     _titleobj_switching(obj, it);
1357 }
1358
1359 /**
1360  * This gets the status whether title object is shown/hidden.
1361  *
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
1366  */
1367 Eina_Bool
1368 elm_navigationbar_title_object_visible_get(Evas_Object *obj, Evas_Object *content)
1369 {
1370    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
1371    Elm_Navigationbar_Item *it;
1372    Widget_Data *wd;
1373
1374    if (!content) return EINA_FALSE;
1375
1376    wd = elm_widget_data_get(obj);
1377    if (!wd) return EINA_FALSE;
1378
1379    it = evas_object_data_get(content, _navigationbar_key);
1380    if (!it) return EINA_FALSE;
1381
1382    return it->titleobj_visible;
1383 }