1 #include <Elementary.h>
5 * @defgroup NavigationBar NavigationBar
8 * The Navigationbar is an object that allows flipping (with animation) between 1 or
9 * more of objects, much like a stack of windows within the window. It also displays title
10 * area above all the pages consisting of title,function buttons.
12 * Objects can be pushed or popped from the stack.
13 * Pushes and pops will animate (and a pop will delete the object once the
14 * animation is finished). Objects are pushed to the top with
15 * elm_navigationbar_push() and when the top item is no longer
16 * wanted, simply pop it with elm_navigationbar_pop() and it will also be
17 * deleted. You can query which objects are the top and bottom with
18 * elm_navigationbar_content_bottom_get() and elm_navigationbar_content_top_get().
21 typedef struct _Widget_Data Widget_Data;
22 typedef struct _Elm_Navigationbar_Item Elm_Navigationbar_Item;
23 typedef struct _Transit_Cb_Data Transit_Cb_Data;
30 Eina_Bool title_visible : 1;
34 struct _Elm_Navigationbar_Item
39 Evas_Object *title_obj;
40 Eina_List *title_list;
44 Evas_Object *back_btn;
50 Eina_Bool titleobj_visible :1;
53 struct _Transit_Cb_Data
55 Elm_Navigationbar_Item* prev_it;
56 Elm_Navigationbar_Item* it;
59 Eina_Bool first_page : 1;
62 static const char *widtype = NULL;
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);
86 #define PREV_BUTTON_DEFAULT_LABEL "Previous"
89 _del_hook(Evas_Object *obj)
91 Widget_Data *wd = elm_widget_data_get(obj);
93 Elm_Navigationbar_Item *it;
95 EINA_LIST_FOREACH(wd->stack, list, it)
97 eina_list_free(wd->stack);
102 _theme_hook(Evas_Object *obj)
104 Widget_Data *wd = elm_widget_data_get(obj);
105 Eina_List *list = NULL;
106 Elm_Navigationbar_Item *it = NULL;
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)
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);
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);
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);
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);
135 edje_object_message_signal_process(wd->base);
140 _delete_item(Elm_Navigationbar_Item *it)
142 //TODO: So hard to manange.
143 //TODO: Just prepare one layout for title objects.
144 //TODO: then remove the layout only.
146 Evas_Object *list_obj;
151 wd = elm_widget_data_get(it->obj);
156 elm_widget_sub_object_del(it->obj, it->back_btn);
157 evas_object_del(it->back_btn);
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);
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);
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);
178 eina_stringshare_del(it->title);
180 eina_stringshare_del(it->subtitle);
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);
193 _sizing_eval(Evas_Object *obj)
195 Widget_Data *wd = elm_widget_data_get(obj);
196 Evas_Coord minw = -1, minh = -1;
197 Evas_Coord w = -1, h = -1;
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;
205 evas_object_size_hint_min_set(obj, minw, minh);
206 evas_object_size_hint_max_set(obj, -1, -1);
208 list = eina_list_last(wd->stack);
211 Elm_Navigationbar_Item *it = list->data;
212 _item_sizing_eval(it);
217 _item_sizing_eval(Elm_Navigationbar_Item *it)
220 Widget_Data *wd = elm_widget_data_get(it->obj);
221 Evas_Coord pad, height, minw, w;
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;
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);
236 it->fn_btn1_w = _button_size_set(it->fn_btn1);
239 else if (it->back_btn)
241 it->fn_btn1_w = _button_size_set(it->back_btn);
246 it->fn_btn2_w = _button_size_set(it->fn_btn2);
251 it->fn_btn3_w = _button_size_set(it->fn_btn3);
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);
264 _resize(void *data, Evas *e, Evas_Object *obj, void *event_info)
270 _switch_titleobj_visibility(void *data, Evas_Object *obj , const char *emission, const char *source)
272 Elm_Navigationbar_Item *it = data;
274 Widget_Data *wd = elm_widget_data_get(it->obj);
275 Evas_Object *top = elm_navigationbar_content_top_get(it->obj);
277 if(it->content != top) return;
278 if(!it->title_obj) return;
279 if(it->titleobj_visible)
281 edje_object_signal_emit(wd->base, "elm,state,show,title", "elm");
282 it->titleobj_visible = EINA_FALSE;
286 edje_object_signal_emit(wd->base, "elm,state,hide,title", "elm");
287 it->titleobj_visible = EINA_TRUE;
289 _item_sizing_eval(it);
292 //TODO: should be renamed.
294 _transition_complete_cb(void *data)
296 Evas_Object *navi_bar;
297 Evas_Object *content = NULL;
299 Elm_Navigationbar_Item *prev_it;
300 Elm_Navigationbar_Item *it;
303 Transit_Cb_Data *cb = data;
306 navi_bar = cb->navibar;
307 if (!navi_bar) return;
309 wd = elm_widget_data_get(navi_bar);
312 prev_it = cb->prev_it;
315 if (cb->pop && prev_it)
317 ll = eina_list_last(wd->stack);
318 if (ll->data == prev_it)
320 _delete_item(prev_it);
321 wd->stack = eina_list_remove_list(wd->stack, ll);
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);
332 if (it && wd->title_visible)
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);
342 edje_object_signal_emit(wd->base, "elm,action,pop", "elm");
344 edje_object_signal_emit(wd->base, "elm,action,push", "elm");
345 edje_object_signal_emit(wd->base, "elm,state,rect,enabled", "elm");
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");
354 edje_object_signal_emit(wd->base, "elm,state,retract,title", "elm");
356 edje_object_part_text_set(wd->base, "elm.text.sub", it->subtitle);
358 edje_object_part_text_set(wd->base, "elm.text.sub", NULL);
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);
365 else if (it->back_btn)
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);
371 edje_object_signal_emit(wd->base, "elm,state,item,reset,leftpad", "elm");
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);
379 edje_object_signal_emit(wd->base, "elm,state,item,reset,rightpad", "elm");
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);
388 edje_object_signal_emit(wd->base, "elm,state,item,reset,rightpad2", "elm");
390 if ((it->title_obj) && (it->title))
391 edje_object_signal_emit(wd->base, "elm,state,show,extended", "elm");
393 edje_object_signal_emit(wd->base, "elm,state,hide,extended", "elm");
395 content = it->content;
400 _back_button_clicked(void *data, Evas_Object *obj, void *event_info)
402 Elm_Navigationbar_Item *it = data;
404 elm_navigationbar_pop(it->obj);
408 _hide_finished(void *data, Evas_Object *obj, void *event_info)
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");
418 _button_size_set(Evas_Object *obj)
421 Evas_Coord minw = -1, minh = -1, maxw= -1, maxh = -1;
422 Evas_Coord w = 0, h = 0;
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);
436 _button_set(Evas_Object *obj, Evas_Object *prev_btn, Evas_Object *new_btn, Eina_Bool back_btn)
438 char buf[4096]; //TODO: How to guarantee this buffer size?
439 Eina_Bool changed = EINA_FALSE;
441 if (prev_btn) evas_object_del(prev_btn);
442 if (!new_btn) return changed;
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);
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);
457 elm_widget_sub_object_add(obj, new_btn);
460 //TODO: Need to set EVAS_CALLBACK_DEL
465 static void _content_del(void *data, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
467 Elm_Navigationbar_Item *it = data;
469 //TODO: it will be better remove this page?
472 static Elm_Navigationbar_Item *
473 _check_item_is_added(Evas_Object *obj, Evas_Object *content)
475 Widget_Data *wd = elm_widget_data_get(obj);
477 Elm_Navigationbar_Item *it;
479 EINA_LIST_FOREACH(wd->stack, ll, it)
480 if (it->content == content)
486 _multiple_object_set(Evas_Object *obj, Evas_Object *sub_obj, Eina_List *list, int width)
490 Evas_Object *new_obj, *list_obj;
491 Evas_Coord pad, height;
496 wd = elm_widget_data_get(obj);
497 if (!wd) return NULL;
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);
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));
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)
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);
528 _multiple_object_unset(Elm_Navigationbar_Item *it, Eina_List **list)
530 Evas_Object *list_obj = NULL;
532 Evas_Object *temp_obj;
537 EINA_LIST_FOREACH (it->title_list, l, list_obj)
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);
545 eina_list_free(it->title_list);
546 it->title_list = NULL;
552 * Add a new navigationbar to the parent
554 * @param[in] parent The parent object
555 * @return The new object or NULL if it cannot be created
557 * @ingroup NavigationBar
560 elm_navigationbar_add(Evas_Object *parent)
566 EINA_SAFETY_ON_NULL_RETURN_VAL(parent, NULL);
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);
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);
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);
591 wd->title_visible = EINA_TRUE;
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.
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
608 * @ingroup NavigationBar
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)
613 ELM_CHECK_WIDTYPE(obj, widtype);
617 Elm_Navigationbar_Item *it;
618 Elm_Navigationbar_Item *prev_it;
620 if (!content) return;
622 wd = elm_widget_data_get(obj);
625 it = _check_item_is_added(obj, content);
628 if (!it) it = ELM_NEW(Elm_Navigationbar_Item);
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);
635 ll = eina_list_last(wd->stack);
636 if (ll) prev_it = ll->data;
640 it->fn_btn1 = fn_btn1;
641 it->fn_btn2 = fn_btn2;
642 it->fn_btn3 = fn_btn3;
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);
648 //Add a prev-button automatically.
649 if ((!fn_btn1) && (prev_it))
651 it->back_btn = elm_button_add(obj);
654 elm_button_label_set(it->back_btn, prev_it->title);
656 elm_button_label_set(it->back_btn, PREV_BUTTON_DEFAULT_LABEL);
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);
663 eina_stringshare_replace(&it->title, title);
664 edje_object_part_text_set(wd->base, "elm.text", title);
665 _item_sizing_eval(it);
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?
672 cb->prev_it = prev_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);
682 //If page is the first, then do not run the transition... but if user want.. ?
687 cb->pop = EINA_FALSE;
688 cb->first_page = EINA_TRUE;
691 _transition_complete_cb(cb);
693 elm_pager_content_push(wd->pager, it->content);
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);
703 EINA_LIST_FOREACH(wd->stack, ll, it)
705 if (it->content == content)
707 wd->stack = eina_list_demote_list(wd->stack, ll);
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.
720 * @param[in] obj The NavigationBar object
722 * @ingroup NavigationBar
725 elm_navigationbar_pop(Evas_Object *obj)
727 ELM_CHECK_WIDTYPE(obj, widtype);
728 Widget_Data *wd = elm_widget_data_get(obj);
731 Elm_Navigationbar_Item *it = NULL;
732 Elm_Navigationbar_Item *prev_it = NULL;
734 //TODO: It's impossible to pop while popping?
735 if (wd->popping) return;
736 if (!wd->stack) return;
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);
750 //unswallow items and start trasition
751 cb = ELM_NEW(Transit_Cb_Data);
753 //Previous page is exist.
756 cb->prev_it = prev_it;
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);
766 //This case, it's the last page.
769 cb->prev_it = prev_it;
772 //TODO: seems that flag is inverted.
773 cb->first_page = EINA_FALSE;
776 _transition_complete_cb(cb);
777 wd->popping = EINA_TRUE;
779 elm_pager_content_pop(wd->pager);
781 if ((prev_it) && (!it))
782 edje_object_part_text_set(wd->base, "elm.text", NULL);
788 * This Pops to the given content object (and update it) by deleting rest of the objects in between.
790 * @param[in] obj The NavigationBar object
791 * @param[in] content the object to show
793 * @ingroup NavigationBar
796 elm_navigationbar_to_content_pop(Evas_Object *obj, Evas_Object *content)
798 ELM_CHECK_WIDTYPE(obj, widtype);
802 Elm_Navigationbar_Item *it;
803 Elm_Navigationbar_Item *prev_it;
806 wd = elm_widget_data_get(obj);
807 if ((!wd) || (!content) || (!wd->stack)) return;
809 //find item to be popped and to be shown
811 ll = eina_list_last(wd->stack);
820 if ((it->obj) && (it->content != content))
822 _delete_item(ll->data);
823 wd->stack = eina_list_remove_list(wd->stack, ll);
832 //unswallow items and start trasition
833 cb = ELM_NEW(Transit_Cb_Data);
834 cb->prev_it = prev_it;
837 cb->first_page = EINA_FALSE;
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);
847 _item_sizing_eval(it);
848 _transition_complete_cb(cb);
850 elm_pager_to_content_pop(wd->pager, content);
855 * Set the title string for the pushed content
857 * @param[in] obj The NavigationBar object
858 * @param[in] content The object to push or pushed
859 * @param[in] title The title string
861 * @ingroup NavigationBar
864 elm_navigationbar_title_label_set(Evas_Object *obj, Evas_Object *content, const char *title)
866 ELM_CHECK_WIDTYPE(obj, widtype);
869 Elm_Navigationbar_Item *it;
871 if (!content) return;
873 wd = elm_widget_data_get(obj);
876 EINA_LIST_FOREACH(wd->stack, ll, it)
878 if (it->content == content)
880 eina_stringshare_replace(&it->title, title);
881 edje_object_part_text_set(wd->base, "elm.text", title);
882 if (wd->title_visible)
884 if ((it->title_obj) && (it->title))
885 edje_object_signal_emit(wd->base, "elm,state,extend,title", "elm");
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");
892 edje_object_signal_emit(wd->base, "elm,state,retract,title", "elm");
894 _item_sizing_eval(it);
901 * Return the title string of the pushed content
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
907 * @ingroup NavigationBar
910 elm_navigationbar_title_label_get(Evas_Object *obj, Evas_Object *content)
912 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
915 Elm_Navigationbar_Item *it;
917 if (!content) return;
919 wd = elm_widget_data_get(obj);
920 if (!wd) return NULL;
922 EINA_LIST_FOREACH(wd->stack, ll, it)
924 if (it->content == content)
931 * Add a title object for the content.
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)
937 * @ingroup NavigationBar
939 //TODO: elm_navigationbar_title_object_set ( .... )
941 elm_navigationbar_title_object_add(Evas_Object *obj, Evas_Object *content, Evas_Object *title_obj)
943 ELM_CHECK_WIDTYPE(obj, widtype);
946 Elm_Navigationbar_Item *it;
947 Elm_Navigationbar_Item *last_it;
948 Evas_Object *swallow;
950 if ((!title_obj) || (!content)) return;
952 wd = elm_widget_data_get(obj);
955 it = _check_item_is_added(obj, content);
958 ERR("[ERROR]Push the Elm_Navigationbar_Item first, later add the title object");
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);
968 if (last_it->content == content)
970 swallow = edje_object_part_swallow_get(wd->base, "elm.swallow.title");
972 //TODO: WHO REMOVE THIS?
973 edje_object_part_unswallow(wd->base, swallow);
974 evas_object_hide(swallow);
976 edje_object_part_swallow(wd->base, "elm.swallow.title", it->title_obj);
977 if (wd->title_visible)
979 //TODO: Will be removed.
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");
985 if ((it->title_obj) && (it->title))
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");
994 _item_sizing_eval(it);
1000 * Unset the list of title objects corresponding to given content and returns it to
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
1008 //TODO: double pointer ? ...
1009 //TODO: why did not return the list ?
1010 //TODO: title_object_unset
1012 elm_navigationbar_title_object_list_unset(Evas_Object *obj, Evas_Object *content, Eina_List **list)
1014 ELM_CHECK_WIDTYPE(obj, widtype);
1017 Elm_Navigationbar_Item *it;
1018 Elm_Navigationbar_Item *last_it;
1019 Evas_Object *swallow;
1021 if ((!list) || (!content)) return;
1023 wd = elm_widget_data_get(obj);
1026 ll = eina_list_last(wd->stack);
1031 EINA_LIST_FOREACH(wd->stack, ll, it)
1033 if (it->content != content) continue;
1035 if (last_it->content == it->content)
1037 swallow = edje_object_part_swallow_get(wd->base, "elm.swallow.title");
1040 //TODO: WHO DELETE THIS?
1041 edje_object_part_unswallow(wd->base, swallow);
1042 evas_object_hide(swallow);
1044 _multiple_object_unset(it, list);
1047 evas_object_del(it->title_obj);
1048 it->title_obj = NULL;
1050 if (wd->title_visible)
1052 if(it->titleobj_visible)
1054 edje_object_signal_emit(wd->base, "elm,state,hide,noanimate,title", "elm");
1055 it->titleobj_visible = EINA_FALSE;
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");
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");
1066 _item_sizing_eval(it);
1073 * Return the list of title objects of the pushed content.
1075 * @param[in] obj The NavigationBar object
1076 * @param[in] content The object to push or pushed
1077 * @return The list of title objects
1079 * @ingroup NavigationBar
1083 elm_navigationbar_title_object_list_get(Evas_Object *obj, Evas_Object *content)
1085 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1088 Elm_Navigationbar_Item *it;
1090 if (!content) return NULL;
1092 wd = elm_widget_data_get(obj);
1093 if (!wd) return NULL;
1095 EINA_LIST_FOREACH(wd->stack, ll, it)
1097 if (it->content == content)
1098 return it->title_list;
1104 _elm_navigationbar_back_button_set(Evas_Object *obj, Evas_Object *content, Evas_Object *button)
1106 Widget_Data *wd = elm_widget_data_get(obj);
1108 Elm_Navigationbar_Item *it;
1112 EINA_LIST_FOREACH(wd->stack, ll, it)
1114 if (it->content == content)
1116 if(it->back_btn == button)
1118 changed = _button_set(obj, it->back_btn, button, EINA_TRUE);
1119 it->back_btn = button;
1120 _item_sizing_eval(it);
1125 //update if the content is the top item
1126 ll = eina_list_last(wd->stack);
1130 if (it->back_btn && changed && (it->content == content) && (!it->fn_btn1))
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);
1138 static Evas_Object *
1139 _elm_navigationbar_back_button_get(Evas_Object *obj, Evas_Object *content)
1141 Widget_Data *wd = elm_widget_data_get(obj);
1143 Elm_Navigationbar_Item *it;
1145 if (!wd) return NULL;
1146 EINA_LIST_FOREACH(wd->stack, ll, it)
1148 if (it->content == content)
1149 return it->back_btn;
1155 _elm_navigationbar_function_button1_set(Evas_Object *obj, Evas_Object *content, Evas_Object *button)
1159 Elm_Navigationbar_Item *it;
1162 wd = elm_widget_data_get(obj);
1165 EINA_LIST_FOREACH(wd->stack, ll, it)
1167 if (it->content == content)
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);
1177 //update if the content is the top item
1178 if ((!it) || (!it->fn_btn1) || (!changed)) return;
1180 ll = eina_list_last(wd->stack);
1184 if (it->content == content)
1186 if (edje_object_part_swallow_get(wd->base, "elm.swallow.btn1") == it->back_btn)
1188 edje_object_part_unswallow(wd->base, it->back_btn);
1189 //TODO: WHO REMOVE THIS?
1190 evas_object_hide(it->back_btn);
1192 //TODO: IS THERE NO POSSIBLILITY TO SET FUNCTIONBTN1 MULTIPLE?
1193 edje_object_part_swallow(wd->base, "elm.swallow.btn1", it->fn_btn1);
1197 static Evas_Object *
1198 _elm_navigationbar_function_button1_get(Evas_Object *obj, Evas_Object *content)
1202 Elm_Navigationbar_Item *it;
1204 wd = elm_widget_data_get(obj);
1205 if (!wd) return NULL;
1207 EINA_LIST_FOREACH(wd->stack, ll, it)
1209 if (it->content == content)
1215 //TODO: looks make this _elm_navigationbar_function_button1_set same.
1217 _elm_navigationbar_function_button2_set(Evas_Object *obj, Evas_Object *content, Evas_Object *button)
1221 Elm_Navigationbar_Item *it;
1224 wd = elm_widget_data_get(obj);
1227 EINA_LIST_FOREACH(wd->stack, ll, it)
1229 if (it->content == content)
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);
1239 //update if the content is the top item
1240 if ((!it) || (!it->fn_btn2) || (!changed)) return;
1242 ll = eina_list_last(wd->stack);
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);
1252 static Evas_Object *
1253 _elm_navigationbar_function_button2_get(Evas_Object *obj,
1254 Evas_Object *content)
1258 Elm_Navigationbar_Item *it;
1260 wd = elm_widget_data_get(obj);
1261 if (!wd) return NULL;
1263 EINA_LIST_FOREACH(wd->stack, ll, it)
1265 if (it->content == content)
1271 //TODO: looks make this _elm_navigationbar_function_button1_set same.
1273 _elm_navigationbar_function_button3_set(Evas_Object *obj, Evas_Object *content, Evas_Object *button)
1277 Elm_Navigationbar_Item *it;
1280 wd = elm_widget_data_get(obj);
1283 EINA_LIST_FOREACH(wd->stack, ll, it)
1285 if (it->content == content)
1287 if(it->fn_btn3 == button)
1289 changed = _button_set(obj, it->fn_btn3, button, EINA_FALSE);
1290 it->fn_btn3 = button;
1291 _item_sizing_eval(it);
1296 //update if the content is the top item
1297 if ((!it) || (!it->fn_btn3) || (!changed)) return;
1299 ll = eina_list_last(wd->stack);
1304 if (it->content == content)
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);
1311 edje_object_signal_emit(wd->base, "elm,state,retract,title", "elm");
1314 static Evas_Object *
1315 _elm_navigationbar_function_button3_get(Evas_Object *obj,
1316 Evas_Object *content)
1320 Elm_Navigationbar_Item *it;
1322 wd = elm_widget_data_get(obj);
1323 if (!wd) return NULL;
1325 EINA_LIST_FOREACH(wd->stack, ll, it)
1327 if (it->content == content)
1335 * Return the content object at the top of the NavigationBar stack
1337 * @param[in] obj The NavigationBar object
1338 * @return The top content object or NULL if none
1340 * @ingroup NavigationBar
1343 elm_navigationbar_content_top_get(Evas_Object *obj)
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);
1352 * Return the content object at the bottom of the NavigationBar stack
1354 * @param[in] obj The NavigationBar object
1355 * @return The bottom content object or NULL if none
1357 * @ingroup NavigationBar
1360 elm_navigationbar_content_bottom_get(Evas_Object *obj)
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);
1369 * This hides the title area of navigationbar.
1371 * @param[in] obj The NavigationBar object
1372 * @param[in] hidden if EINA_TRUE the title area is hidden.
1374 * @ingroup NavigationBar
1376 //TODO: does not provide hidden get ?
1378 elm_navigationbar_hidden_set(Evas_Object *obj,
1381 ELM_CHECK_WIDTYPE(obj, widtype);
1382 Widget_Data *wd = elm_widget_data_get(obj);
1386 edje_object_signal_emit(wd->base, "elm,state,item,moveup", "elm");
1388 edje_object_signal_emit(wd->base, "elm,state,item,movedown", "elm");
1390 wd->title_visible = !hidden;
1394 * Set the button object of the pushed content.
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
1401 * @ingroup NavigationBar
1404 elm_navigationbar_title_button_set(Evas_Object *obj, Evas_Object *content, Evas_Object *button, Elm_Navi_Button_Type button_type)
1406 ELM_CHECK_WIDTYPE(obj, widtype);
1407 if (!content) return;
1411 case ELM_NAVIGATIONBAR_FUNCTION_BUTTON1:
1412 _elm_navigationbar_function_button1_set(obj, content, button);
1414 case ELM_NAVIGATIONBAR_FUNCTION_BUTTON2:
1415 _elm_navigationbar_function_button2_set(obj, content, button);
1417 case ELM_NAVIGATIONBAR_FUNCTION_BUTTON3:
1418 _elm_navigationbar_function_button3_set(obj, content, button);
1420 case ELM_NAVIGATIONBAR_BACK_BUTTON:
1421 _elm_navigationbar_back_button_set(obj, content, button);
1430 * Return the button object of the pushed content
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
1437 * @ingroup NavigationBar
1440 elm_navigationbar_title_button_get(Evas_Object *obj, Evas_Object *content, Elm_Navi_Button_Type button_type)
1442 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1443 Evas_Object *button;
1445 if ((!content) || (!obj))
1452 case ELM_NAVIGATIONBAR_FUNCTION_BUTTON1:
1453 button = _elm_navigationbar_function_button1_get(obj, content);
1455 case ELM_NAVIGATIONBAR_FUNCTION_BUTTON2:
1456 button = _elm_navigationbar_function_button2_get(obj, content);
1458 case ELM_NAVIGATIONBAR_FUNCTION_BUTTON3:
1459 button = _elm_navigationbar_function_button3_get(obj, content);
1461 case ELM_NAVIGATIONBAR_BACK_BUTTON:
1462 button = _elm_navigationbar_back_button_get(obj, content);
1471 * Set the sub title string for the pushed content.
1473 * @param[in] obj The NavigationBar object
1474 * @param[in] content The object to push or pushed
1475 * @param[in] subtitle The subtitle string
1477 * @ingroup NavigationBar
1480 elm_navigationbar_subtitle_label_set(Evas_Object *obj, Evas_Object *content, const char *subtitle)
1482 ELM_CHECK_WIDTYPE(obj, widtype);
1485 Elm_Navigationbar_Item *it;
1487 wd = elm_widget_data_get(obj);
1490 EINA_LIST_FOREACH(wd->stack, ll, it)
1492 if (it->content == content)
1494 eina_stringshare_replace(&it->subtitle, subtitle);
1495 edje_object_part_text_set(wd->base, "elm.text.sub", subtitle);
1496 _item_sizing_eval(it);
1503 * Return the subtitle string of the pushed content.
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
1509 * @ingroup NavigationBar
1512 elm_navigationbar_subtitle_label_get(Evas_Object *obj, Evas_Object *content)
1514 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1517 Elm_Navigationbar_Item *it;
1519 wd = elm_widget_data_get(obj);
1520 if (!wd) return NULL;
1522 EINA_LIST_FOREACH(wd->stack, ll, it)
1524 if (it->content == content)
1525 return it->subtitle;
1532 * This disables content area animation on push/pop.
1534 * @param[in] obj The NavigationBar object
1535 * @param[in] disable if EINA_TRUE animation is disabled.
1537 * @ingroup NavigationBar
1539 //TODO: Let's check to remove this API.
1541 elm_navigationbar_animation_disabled_set(Evas_Object *obj, Eina_Bool disable)
1543 ELM_CHECK_WIDTYPE(obj, widtype);
1544 Widget_Data *wd = elm_widget_data_get(obj);
1546 elm_pager_animation_disabled_set(wd->pager, disable);