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