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