[elm_popup/TC]: Icon directory and image changed as per review comment.
[framework/uifw/elementary.git] / src / lib / elm_navigationbar_ex.c
1 #include <Elementary.h>\r
2 #include "elm_priv.h"\r
3 \r
4 /**\r
5  * @defgroup Navigationbar_ex Navigationbar_ex\r
6  * @ingroup Elementary\r
7  *\r
8  * The NavigationBar_ex is an object that allows flipping (with animation) between 1 or\r
9  * more pages of objects, much like a stack of windows within the window as well display\r
10  * the title area for the page consisting of buttons, title, titleobjects etc:-.\r
11  *\r
12  * Objects can be pushed or popped from the stack or deleted as normal.\r
13  * Pushes and pops will animate and a pop will delete the object once the\r
14  * animation is finished if delete_on_pop is set else the content is unset and the\r
15  * content pointer is sent as event information in the hide,finished signal.\r
16  * Any object in the Navigationbar_ex can be promoted to the top\r
17  * (from its current stacking position) as well. Objects are pushed to the\r
18  * top with elm_navigationbar_ex_item_push() and when the top item is no longer\r
19  * wanted, simply pop it with elm_navigationbar_ex_item_pop() and it will also be\r
20  * deleted/unset depending on delete_on_pop variable.\r
21  * Any object you wish to promote to the top that is already in the\r
22  * navigationbar, simply use elm_navigationbar_ex_item_promote(). If an object is no longer\r
23  * needed and is not the top item, just delete it as normal. You can query\r
24  * which objects are the top and bottom with elm_navigationbar_ex_item_bottom_get()\r
25  * and elm_navigationbar_ex_item_top_get().\r
26  */\r
27 \r
28 typedef struct _Widget_Data Widget_Data;\r
29 typedef struct _function_button fn_button;\r
30 \r
31 struct _Widget_Data\r
32 {\r
33    Eina_List *stack, *to_delete;\r
34    Elm_Navigationbar_ex_Item *top, *oldtop;\r
35    Evas_Object *rect, *clip;\r
36    Eina_Bool del_on_pop : 1;\r
37    Eina_Bool disable_animation: 1;\r
38 };\r
39 \r
40 struct _Elm_Navigationbar_ex_Item\r
41 {\r
42    Evas_Object *obj, *base, *content;\r
43    Evas_Object *ct_base;\r
44    Evas_Coord minw, minh;\r
45    const char *title;\r
46    const char *subtitle;\r
47    const char *item_style;\r
48    Eina_List *fnbtn_list;\r
49    Evas_Object *title_obj;\r
50    Evas_Object *icon;\r
51    Eina_Bool popme : 1;\r
52    Eina_Bool titleobj_visible:1;\r
53 };\r
54 \r
55 struct _function_button\r
56 {\r
57    Evas_Object *btn;\r
58    int btn_id;\r
59 };\r
60 \r
61 static const char *widtype = NULL;\r
62 static void _del_hook(Evas_Object *obj);\r
63 static void _theme_hook(Evas_Object *obj);\r
64 static void _sizing_eval(Evas_Object *obj);\r
65 static void _changed_size_hints(void *data, Evas *e, Evas_Object *obj, void *event_info);\r
66 static void _sub_del(void *data, Evas_Object *obj, void *event_info);\r
67 \r
68 static void\r
69 _del_hook(Evas_Object *obj)\r
70 {\r
71    Widget_Data *wd = elm_widget_data_get(obj);\r
72    if (!wd) return;\r
73    free(wd);\r
74 }\r
75 \r
76 static Evas_Object*\r
77 _content_unset(Elm_Navigationbar_ex_Item* item)\r
78 {\r
79    if (!item) return NULL;\r
80    Evas_Object *content = NULL;\r
81    if (!item->content) return NULL;\r
82    content = item->content;\r
83    elm_widget_sub_object_del(item->obj,item->content);\r
84    edje_object_part_unswallow(item->ct_base,item->content);\r
85    item->content = NULL;\r
86    evas_object_hide(content);\r
87    return content;\r
88 }\r
89 \r
90 static void\r
91 _theme_hook(Evas_Object *obj)\r
92 {\r
93    Widget_Data *wd = elm_widget_data_get(obj);\r
94    Eina_List *l;\r
95    char buf_fn[1024];\r
96    char buf[1024];\r
97    Elm_Navigationbar_ex_Item *it;\r
98    if (!wd) return;\r
99    EINA_LIST_FOREACH(wd->stack, l, it)\r
100      {\r
101         Eina_List *bl;\r
102         fn_button *btn;\r
103         edje_object_scale_set(it->base, elm_widget_scale_get(obj) *\r
104                               _elm_config->scale);\r
105         strncpy(buf, "item/", sizeof(buf));\r
106         strncat(buf, it->item_style, sizeof(buf) - strlen(buf));\r
107         _elm_theme_object_set(obj, it->base,  "navigationbar_ex", buf, elm_widget_style_get(obj));\r
108         _elm_theme_object_set(obj, it->ct_base,  "navigationbar_ex", "content", elm_widget_style_get(obj));\r
109         EINA_LIST_FOREACH(it->fnbtn_list, bl, btn)\r
110           {\r
111              if (btn->btn_id == ELM_NAVIGATIONBAR_EX_BACK_BUTTON)\r
112                {\r
113                   snprintf(buf_fn, sizeof(buf_fn), "navigationbar_backbutton/%s", elm_widget_style_get(obj));\r
114                   elm_object_style_set(btn->btn, buf_fn);\r
115                }\r
116              else\r
117                {\r
118                   snprintf(buf_fn, sizeof(buf_fn), "navigationbar_functionbutton/%s", elm_widget_style_get(obj));\r
119                   elm_object_style_set(btn->btn, buf_fn);\r
120                }\r
121           }\r
122      }\r
123    _sizing_eval(obj);\r
124 }\r
125 \r
126 static void\r
127 _sizing_eval(Evas_Object *obj)\r
128 {\r
129    Widget_Data *wd = elm_widget_data_get(obj);\r
130    Evas_Coord minw = -1, minh = -1;\r
131    Eina_List *l;\r
132    Elm_Navigationbar_ex_Item *it;\r
133    if (!wd) return;\r
134    EINA_LIST_FOREACH(wd->stack, l, it)\r
135      {\r
136         if (it->minw > minw) minw = it->minw;\r
137         if (it->minh > minh) minh = it->minh;\r
138      }\r
139    evas_object_size_hint_min_set(obj, minw, minh);\r
140    evas_object_size_hint_max_set(obj, -1, -1);\r
141 }\r
142 \r
143 static void\r
144 _changed_size_hints(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)\r
145 {\r
146    Elm_Navigationbar_ex_Item *it = data;\r
147    Evas_Coord minw = -1, minh = -1;\r
148    evas_object_size_hint_min_get(it->content, &minw, &minh);\r
149    // FIXME: why is this needed? how does edje get this unswallowed or\r
150    // lose its callbacks to edje\r
151    edje_object_part_swallow(it->ct_base, "elm.swallow.content", it->content);\r
152    edje_object_size_min_calc(it->base, &it->minw, &it->minh);\r
153    _sizing_eval(it->obj);\r
154 }\r
155 \r
156 static void\r
157 _eval_top(Evas_Object *obj)\r
158 {\r
159    Widget_Data *wd = elm_widget_data_get(obj);\r
160    Eina_Bool animate = EINA_TRUE;\r
161    Elm_Navigationbar_ex_Item *ittop = NULL;\r
162    if (!wd) return;\r
163    if (!wd->stack) return;\r
164    ittop = eina_list_last(wd->stack)->data;\r
165    if (ittop != wd->top)\r
166      {\r
167         Evas_Object *o1, *o2;\r
168         const char *onshow, *onhide;\r
169 \r
170         if (wd->top)\r
171           {\r
172              o1 = wd->top->ct_base;\r
173              o2 = wd->top->base;/*make use of the signals sent for animation*/\r
174 \r
175              /*issue to fix, hide signal does not come for t_base, increasing time helps\r
176               in getting correct events in pop*/\r
177              if (wd->disable_animation)\r
178                {\r
179                   edje_object_signal_emit(o2, "elm,action,hide,noanimate", "elm");\r
180                   edje_object_signal_emit(o1, "elm,action,hide,noanimate", "elm");\r
181                }\r
182              else if (wd->top->popme)\r
183                {\r
184                   edje_object_signal_emit(o2, "elm,action,pop", "elm");\r
185                   edje_object_signal_emit(o1, "elm,action,pop", "elm");\r
186                }\r
187              else\r
188                {\r
189                   edje_object_signal_emit(o2, "elm,action,hide", "elm");\r
190                   edje_object_signal_emit(o1, "elm,action,hide", "elm");\r
191                }\r
192              onhide = edje_object_data_get(o1, "onhide");\r
193              if (onhide)\r
194                {\r
195                   if (!strcmp(onhide, "raise")) {\r
196                      evas_object_raise(o2);\r
197                      evas_object_raise(o1);\r
198                   }\r
199                   else if (!strcmp(onhide, "lower")) {\r
200                        evas_object_lower(o2);\r
201                        evas_object_lower(o1);\r
202                   }\r
203                }\r
204           }\r
205         else\r
206           {\r
207              animate = EINA_FALSE;\r
208           }\r
209         wd->oldtop = wd->top;\r
210         wd->top = ittop;\r
211         o1 = wd->top->ct_base;\r
212         o2 = wd->top->base;\r
213         evas_object_show(o2);\r
214         evas_object_show(o1);\r
215 \r
216         if ((!animate)||(wd->disable_animation))\r
217           {\r
218              edje_object_signal_emit(o2, "elm,action,show,noanimate", "elm");\r
219              edje_object_signal_emit(o1, "elm,action,show,noanimate", "elm");\r
220           }\r
221         else if (wd->oldtop)\r
222           {\r
223              if (elm_object_focus_get(wd->oldtop->content))\r
224                elm_object_focus(wd->top->content);\r
225              if (wd->oldtop->popme)\r
226                {\r
227                   edje_object_signal_emit(o2, "elm,action,show", "elm");\r
228                   edje_object_signal_emit(o1, "elm,action,show", "elm");\r
229                }\r
230              else\r
231                {\r
232                   edje_object_signal_emit(o2, "elm,action,push", "elm");\r
233                   edje_object_signal_emit(o1, "elm,action,push", "elm");\r
234                }\r
235           }\r
236         else\r
237           {\r
238              edje_object_signal_emit(o2, "elm,action,push", "elm");\r
239              edje_object_signal_emit(o1, "elm,action,push", "elm");\r
240           }\r
241         onshow = edje_object_data_get(o1, "onshow");\r
242         if (onshow)\r
243           {\r
244              if (!strcmp(onshow, "raise")) {\r
245                 evas_object_raise(o2);\r
246                 evas_object_raise(o1);\r
247              }\r
248              else if (!strcmp(onshow, "lower")) {\r
249                 evas_object_lower(o2);\r
250                 evas_object_lower(o1);\r
251              }\r
252           }\r
253      }\r
254 }\r
255 \r
256 static void\r
257 _move(void *data, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)\r
258 {\r
259    Widget_Data *wd = elm_widget_data_get(data);\r
260    Evas_Coord x, y;\r
261    Eina_List *l;\r
262    Elm_Navigationbar_ex_Item *it;\r
263    if (!wd) return;\r
264    evas_object_geometry_get(obj, &x, &y, NULL, NULL);\r
265    EINA_LIST_FOREACH(wd->stack, l, it)\r
266      evas_object_move(it->base, x, y);\r
267 }\r
268 \r
269 static void\r
270 _sub_del(void *data, Evas_Object *obj __UNUSED__, void *event_info)\r
271 {\r
272    Widget_Data *wd = elm_widget_data_get(data);\r
273    Evas_Object *sub = event_info;\r
274    Eina_List *l,*list;\r
275    fn_button *btn_data;\r
276    Elm_Navigationbar_ex_Item *it;\r
277    if (!wd) return;\r
278    EINA_LIST_FOREACH(wd->stack, l, it)\r
279      {\r
280         if (it->content == sub)\r
281           {\r
282              wd->stack = eina_list_remove_list(wd->stack, l);\r
283              evas_object_event_callback_del_full\r
284                (sub, EVAS_CALLBACK_CHANGED_SIZE_HINTS, _changed_size_hints, it);\r
285              if (it->title) eina_stringshare_del(it->title);\r
286              if (it->subtitle) eina_stringshare_del(it->subtitle);\r
287              EINA_LIST_FOREACH(it->fnbtn_list, list, btn_data)\r
288                {\r
289                   evas_object_del(btn_data->btn);\r
290                   free(btn_data);\r
291                   btn_data = NULL;\r
292                }\r
293              if (it->item_style) eina_stringshare_del(it->item_style);\r
294              if (it->title_obj) evas_object_del(it->title_obj);\r
295              if (it->icon) evas_object_del(it->icon);\r
296              evas_object_del(it->ct_base);\r
297              evas_object_del(it->base);\r
298              _eval_top(it->obj);\r
299              free(it);\r
300              return;\r
301           }\r
302      }\r
303 }\r
304 \r
305 static void\r
306 _resize(void *data, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)\r
307 {\r
308    Widget_Data *wd = elm_widget_data_get(data);\r
309    Evas_Coord w, h;\r
310    Eina_List *l;\r
311    Elm_Navigationbar_ex_Item *it;\r
312    if (!wd) return;\r
313    evas_object_geometry_get(obj, NULL, NULL, &w, &h);\r
314    EINA_LIST_FOREACH(wd->stack, l, it) evas_object_resize(it->base, w, h);\r
315 }\r
316 \r
317 static void\r
318 _signal_hide_finished(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)\r
319 {\r
320    Elm_Navigationbar_ex_Item *it = data;\r
321    Evas_Object *obj2 = it->obj;\r
322    Widget_Data *wd = elm_widget_data_get(it->obj);\r
323    evas_object_hide(it->ct_base);\r
324    evas_object_hide(it->base);\r
325    edje_object_signal_emit(it->base, "elm,action,reset", "elm");\r
326    edje_object_signal_emit(it->ct_base, "elm,action,reset", "elm");\r
327    evas_object_smart_callback_call(obj2, "hide,finished", it->content);\r
328    edje_object_message_signal_process(it->base);\r
329    edje_object_message_signal_process(it->ct_base);\r
330    if (it->popme)\r
331      {\r
332         if (wd->del_on_pop)\r
333           {\r
334              evas_object_del(it->content);\r
335           }\r
336         else\r
337           {\r
338              _content_unset(it);\r
339           }\r
340      }\r
341    _sizing_eval(obj2);\r
342 }\r
343 \r
344 static void\r
345 _item_promote(Elm_Navigationbar_ex_Item* item)\r
346 {\r
347    if (!item) return;\r
348    Widget_Data *wd = elm_widget_data_get(item->obj);\r
349    Eina_List *l;\r
350    Elm_Navigationbar_ex_Item *it;\r
351    if (!wd) return;\r
352    EINA_LIST_FOREACH(wd->stack, l, it)\r
353      {\r
354         if (it == item)\r
355           {\r
356              wd->stack = eina_list_remove_list(wd->stack, l);\r
357              wd->stack = eina_list_append(wd->stack, it);\r
358              _eval_top(it->obj);\r
359              return;\r
360           }\r
361      }\r
362 }\r
363 \r
364 static void\r
365 _process_deletions(Widget_Data *wd)\r
366 {\r
367    if (!wd) return;\r
368    Elm_Navigationbar_ex_Item *it;\r
369    fn_button *btn_data;\r
370    Eina_List *list;\r
371    EINA_LIST_FREE(wd->to_delete, it)\r
372      {\r
373         evas_object_event_callback_del_full\r
374           (it->content, EVAS_CALLBACK_CHANGED_SIZE_HINTS, _changed_size_hints, it);\r
375         if (it->title) eina_stringshare_del(it->title);\r
376         if (it->subtitle) eina_stringshare_del(it->subtitle);\r
377         if (it->item_style) eina_stringshare_del(it->item_style);\r
378         EINA_LIST_FOREACH(it->fnbtn_list, list, btn_data)\r
379           {\r
380              evas_object_del(btn_data->btn);\r
381              free(btn_data);\r
382              btn_data = NULL;\r
383           }\r
384         if (it->title_obj) evas_object_del(it->title_obj);\r
385         if (it->content)  evas_object_del(it->content);\r
386         if (it->icon) evas_object_del(it->icon);\r
387         evas_object_del(it->ct_base);\r
388         evas_object_del(it->base);\r
389         _eval_top(it->obj);\r
390         free(it);\r
391         it = NULL;\r
392      }\r
393 }\r
394 \r
395 static void\r
396 _show_hide_titleobj(void *data, Evas_Object *obj , const char *emission, const char *source)\r
397 {\r
398    Elm_Navigationbar_ex_Item *item = (Elm_Navigationbar_ex_Item *)data;\r
399    if(!item) return;\r
400    if(!item->title_obj) return;\r
401    if(!item->titleobj_visible)\r
402      {\r
403        edje_object_signal_emit(item->base, "elm,state,show,title", "elm");\r
404        item->titleobj_visible = EINA_TRUE;\r
405      }\r
406    else\r
407      {\r
408        edje_object_signal_emit(item->base, "elm,state,hide,title", "elm");\r
409        item->titleobj_visible = EINA_FALSE;\r
410      }\r
411 }\r
412 \r
413 /**\r
414  * Add a new navigationbar_ex to the parent\r
415  *\r
416  * @param[in] parent The parent object\r
417  * @return The new object or NULL if it cannot be created\r
418  *\r
419  * @ingroup Navigationbar_ex\r
420  */\r
421 EAPI Evas_Object *\r
422 elm_navigationbar_ex_add(Evas_Object *parent)\r
423 {\r
424    Evas_Object *obj;\r
425    Evas *e;\r
426    Widget_Data *wd;\r
427 \r
428    EINA_SAFETY_ON_NULL_RETURN_VAL(parent, NULL);\r
429 \r
430    wd = ELM_NEW(Widget_Data);\r
431    e = evas_object_evas_get(parent);\r
432    obj = elm_widget_add(e);\r
433    ELM_SET_WIDTYPE(widtype, "navigationbar_ex");\r
434    elm_widget_type_set(obj, "navigationbar_ex");\r
435    elm_widget_sub_object_add(parent, obj);\r
436    elm_widget_data_set(obj, wd);\r
437    elm_widget_del_hook_set(obj, _del_hook);\r
438    elm_widget_theme_hook_set(obj, _theme_hook);\r
439    elm_widget_can_focus_set(obj, EINA_FALSE);\r
440    wd->clip = evas_object_rectangle_add(e);\r
441    elm_widget_resize_object_set(obj, wd->clip);\r
442    elm_widget_sub_object_add(obj, wd->clip);\r
443 \r
444    wd->rect = evas_object_rectangle_add(e);\r
445    elm_widget_sub_object_add(obj, wd->rect);\r
446    evas_object_color_set(wd->rect, 255, 255, 255, 0);\r
447    evas_object_clip_set(wd->rect, wd->clip);\r
448 \r
449    evas_object_event_callback_add(obj, EVAS_CALLBACK_MOVE, _move, obj);\r
450    evas_object_event_callback_add(obj, EVAS_CALLBACK_RESIZE, _resize, obj);\r
451 \r
452    evas_object_smart_callback_add(obj, "sub-object-del", _sub_del, obj);\r
453    wd->del_on_pop = EINA_TRUE;\r
454    _sizing_eval(obj);\r
455    return obj;\r
456 }\r
457 \r
458 /**\r
459  * Push an object along with its style to the top of the Navigationbar_ex stack (and show it)\r
460  *\r
461  * The object pushed becomes a child of the Navigationbar_ex and will be controlled\r
462  * it will be deleted when the Navigationbar_ex is deleted or when content is popped(depending on del_\r
463  * on_pop variable).\r
464  *\r
465  * @param[in] obj The Navigationbar_ex object\r
466  * @param[in] content The object to push\r
467  * @param[in] item_style The style of the page\r
468  * @return The Navigationbar_ex Item or NULL\r
469  * @ingroup Navigationbar_ex\r
470  */\r
471 EAPI Elm_Navigationbar_ex_Item*\r
472 elm_navigationbar_ex_item_push(Evas_Object *obj, Evas_Object *content, const char* item_style)\r
473 {\r
474    ELM_CHECK_WIDTYPE(obj, widtype)NULL;\r
475    Widget_Data *wd = elm_widget_data_get(obj);\r
476    Elm_Navigationbar_ex_Item *it = ELM_NEW(Elm_Navigationbar_ex_Item);\r
477    Evas_Coord x, y, w, h;\r
478    char buf[1024];\r
479    if (!wd) return NULL;\r
480    if (!content) return NULL;\r
481    if (!item_style) return NULL;\r
482    if (!it) return NULL;\r
483    it->obj = obj;\r
484    it->content = content;\r
485    it->base = edje_object_add(evas_object_evas_get(obj));\r
486    it->ct_base = edje_object_add(evas_object_evas_get(obj));\r
487 \r
488    evas_object_smart_member_add(it->base, obj);\r
489    evas_object_smart_member_add(it->ct_base, obj);\r
490 \r
491    evas_object_geometry_get(obj, &x, &y, &w, &h);\r
492    evas_object_move(it->base, x, y);\r
493    evas_object_resize(it->base, w, h);\r
494    evas_object_clip_set(it->base, wd->clip);\r
495 \r
496    elm_widget_sub_object_add(obj, it->base);\r
497    elm_widget_sub_object_add(obj, it->ct_base);\r
498 \r
499    elm_widget_sub_object_add(obj, it->content);\r
500 \r
501    _elm_theme_object_set(obj, it->ct_base,  "navigationbar_ex", "content", elm_widget_style_get(obj));\r
502 \r
503    strncpy(buf, "item/", sizeof(buf));\r
504    strncat(buf, item_style, sizeof(buf) - strlen(buf));\r
505    if (!eina_stringshare_replace(&it->item_style, item_style)) return NULL;\r
506    _elm_theme_object_set(obj, it->base,  "navigationbar_ex", buf, elm_widget_style_get(obj));\r
507 \r
508 \r
509    edje_object_part_swallow(it->base, "elm.swallow.content", it->ct_base);\r
510 \r
511    edje_object_signal_callback_add(it->ct_base, "elm,action,hide,finished", "",\r
512                                    _signal_hide_finished, it);\r
513    evas_object_event_callback_add(it->content,\r
514                                   EVAS_CALLBACK_CHANGED_SIZE_HINTS,\r
515                                   _changed_size_hints, it);\r
516    edje_object_part_swallow(it->ct_base, "elm.swallow.content", it->content);\r
517    edje_object_size_min_calc(it->base, &it->minw, &it->minh);\r
518    evas_object_data_set(it->base, "_elm_leaveme", obj);\r
519    evas_object_show(it->content);\r
520    wd->stack = eina_list_append(wd->stack, it);\r
521    _eval_top(obj);\r
522    _sizing_eval(obj);\r
523    return it;\r
524 }\r
525 \r
526 /**\r
527  * Set the title string for the pushed Item.\r
528  * @param[in] item The Navigationbar_ex Item\r
529  * @param[in] title The title string\r
530  *\r
531  * @ingroup Navigationbar_ex\r
532  */\r
533 EAPI void\r
534 elm_navigationbar_ex_item_title_label_set( Elm_Navigationbar_ex_Item* item, const char *title)\r
535 {\r
536    if (!item) return;\r
537    if (!eina_stringshare_replace(&item->title, title)) return;\r
538    if (item->base)\r
539      {\r
540         edje_object_part_text_set(item->base, "elm.text", item->title);\r
541      }\r
542 }\r
543 \r
544 /**\r
545  * Return the title string of the pushed item.\r
546  *\r
547  * @param[in]  item The Navigationbar_ex Item\r
548  * @return The title string or NULL if none\r
549  *\r
550  * @ingroup Navigationbar_ex\r
551  */\r
552 EAPI const char *\r
553 elm_navigationbar_ex_item_title_label_get(Elm_Navigationbar_ex_Item* item)\r
554 {\r
555    if(!item) return NULL;\r
556    return item->title;\r
557 }\r
558 \r
559 /**\r
560  * Set the sub title string for the pushed content\r
561  *\r
562  * @param[in] item The Navigationbar_ex Item\r
563  * @param[in] subtitle The subtitle string\r
564  *\r
565  * @ingroup Navigationbar_ex\r
566  */\r
567 EAPI void\r
568 elm_navigationbar_ex_item_subtitle_label_set( Elm_Navigationbar_ex_Item* item, const char *subtitle)\r
569 {\r
570    if (!item) return;\r
571    if (!eina_stringshare_replace(&item->subtitle, subtitle)) return;\r
572    if (item->base)\r
573      edje_object_part_text_set(item->base, "elm.text.sub", item->subtitle);\r
574 }\r
575 \r
576 /**\r
577  * Return the subtitle string of the pushed content\r
578  *\r
579  * @param[in] item The Navigationbar_ex Item\r
580  * @return The subtitle string or NULL if none\r
581  *\r
582  * @ingroup Navigationbar_ex\r
583  */\r
584 EAPI const char *\r
585 elm_navigationbar_ex_item_subtitle_label_get(Elm_Navigationbar_ex_Item* item)\r
586 {\r
587    if (!item) return NULL;\r
588    return item->subtitle;\r
589 }\r
590 \r
591 /**\r
592  * Set's the icon object of the pushed content\r
593  *\r
594  * @param[in] item The Navigationbar_ex Item\r
595  * @param[in] The icon object or NULL if none\r
596  *\r
597  *@ingroup Navigationbar_ex\r
598  */\r
599 EAPI void\r
600 elm_navigationbar_ex_item_icon_set(Elm_Navigationbar_ex_Item* item, Evas_Object *icon)\r
601 {\r
602    if (!item) return;\r
603    if (item->icon == icon) return;\r
604    if (item->icon) evas_object_del(item->icon);\r
605    item->icon = icon;\r
606    if(icon)\r
607      {\r
608         edje_object_part_swallow(item->base, "elm.swallow.icon", icon);\r
609         elm_widget_sub_object_add(item->obj, icon);\r
610         edje_object_signal_emit(item->base, "elm,state,icon,visible", "elm");\r
611         edje_object_message_signal_process(item->base);\r
612      }\r
613    else\r
614      edje_object_signal_emit(item->base, "elm,state,icon,hidden", "elm");\r
615 }\r
616 \r
617 /**\r
618  * Return the icon object of the pushed content\r
619  *\r
620  * @param[in] item The Navigationbar_ex Item\r
621  * @return The icon object or NULL if none\r
622  *\r
623  * @ingroup Navigationbar_ex\r
624  */\r
625 EAPI Evas_Object *\r
626 elm_navigationbar_ex_item_icon_get(Elm_Navigationbar_ex_Item* item)\r
627 {\r
628    if (!item) return NULL;\r
629    return item->icon;\r
630 }\r
631 \r
632 \r
633 /**\r
634  * Set the button object of the pushed content\r
635  *\r
636  * @param[in] item The Navigationbar_ex Item\r
637  * @param[in] btn_label The button label\r
638  * @param[in] icon The button icon\r
639  * @param[in] button_type Indicates the position[use macros of type Elm_Navi_ex_Button_Type\r
640  * if more function buttons are required you can use values ELM_NAVIGATIONBAR_EX_MAX and more]\r
641  * @param[in] func Callback function called when button is clicked.\r
642  * @param[in] data Callback data that would be sent when button is clicked.\r
643  * @ingroup Navigationbar_ex\r
644  */\r
645 EAPI void\r
646 elm_navigationbar_ex_item_title_button_set(Elm_Navigationbar_ex_Item* item, char *btn_label, Evas_Object *icon, int button_type, Evas_Smart_Cb func, const void *data)\r
647 {\r
648    if (!item) return;\r
649    Eina_List *bl;\r
650    Evas_Object *btn;\r
651    char buf[1024],theme[1024];\r
652    fn_button *btn_det = NULL;\r
653    EINA_LIST_FOREACH(item->fnbtn_list, bl, btn_det)\r
654      {\r
655         if (btn_det->btn_id == button_type)\r
656           {\r
657              evas_object_del(btn_det->btn);\r
658              free(btn_det);\r
659              btn_det = NULL;\r
660              item->fnbtn_list = eina_list_remove_list(item->fnbtn_list, bl);\r
661           }\r
662      }\r
663    btn = elm_button_add(item->obj);\r
664    btn_det = ELM_NEW(btn_det);\r
665    if (!btn_det) return;\r
666    if (button_type == ELM_NAVIGATIONBAR_EX_BACK_BUTTON)\r
667      {\r
668         snprintf(theme, sizeof(theme), "navigationbar_backbutton/%s", elm_widget_style_get(item->obj));\r
669         elm_object_style_set(btn, theme);\r
670         snprintf(buf, sizeof(buf), "elm.swallow.back");\r
671      }\r
672    else\r
673      {\r
674         snprintf(theme, sizeof(theme), "navigationbar_functionbutton/%s", elm_widget_style_get(item->obj));\r
675         elm_object_style_set(btn, theme);\r
676         snprintf(buf, sizeof(buf), "elm.swallow.btn%d", button_type);\r
677      }\r
678    if (btn_label)\r
679      elm_button_label_set(btn, btn_label);\r
680    if (icon)\r
681      elm_button_icon_set(btn, icon);\r
682    elm_object_focus_allow_set(btn, EINA_FALSE);\r
683    evas_object_smart_callback_add(btn, "clicked", func, data);\r
684    edje_object_part_swallow(item->base, buf, btn);\r
685    elm_widget_sub_object_add(item->obj, btn);\r
686    btn_det->btn = btn;\r
687    btn_det->btn_id = button_type;\r
688    item->fnbtn_list = eina_list_append(item->fnbtn_list, btn_det);\r
689 }\r
690 \r
691 /**\r
692  * Return the button object of the pushed content\r
693  *\r
694  * @param[in] item The Navigationbar_ex Item\r
695  * @param[in] button_type Indicates the position\r
696  * @return The button object or NULL if none\r
697  *\r
698  * @ingroup Navigationbar_ex\r
699  */\r
700 EAPI Evas_Object *\r
701 elm_navigationbar_ex_item_title_button_get(Elm_Navigationbar_ex_Item* item, int button_type)\r
702 {\r
703    if (!item) return NULL;\r
704    fn_button *btn_det;\r
705    Eina_List *bl;\r
706    EINA_LIST_FOREACH(item->fnbtn_list, bl, btn_det)\r
707      {\r
708         if (btn_det->btn_id == button_type)\r
709           return btn_det->btn;\r
710      }\r
711    return NULL;\r
712 }\r
713 \r
714 /**\r
715  * Unset the button object of the pushed content\r
716  *\r
717  * @param[in] item The Navigationbar_ex Item\r
718  * @param[in] button_type Indicates the position\r
719  * @return The button object or NULL if none\r
720  *\r
721  * @ingroup Navigationbar_ex\r
722  */\r
723 EAPI Evas_Object *\r
724 elm_navigationbar_ex_item_title_button_unset(Elm_Navigationbar_ex_Item* item, int button_type)\r
725 {\r
726    if (!item) return NULL;\r
727    fn_button *btn_det;\r
728    Eina_List *bl;\r
729    Evas_Object *btn_ret;\r
730    EINA_LIST_FOREACH(item->fnbtn_list, bl, btn_det)\r
731      {\r
732         if (btn_det->btn_id == button_type)\r
733           {\r
734              btn_ret = btn_det->btn;\r
735              elm_widget_sub_object_del(item->obj,btn_det->btn);\r
736              edje_object_part_unswallow(item->base,btn_det->btn);\r
737              item->fnbtn_list = eina_list_remove_list(item->fnbtn_list, bl);\r
738              btn_det->btn = NULL;\r
739              return btn_ret;\r
740           }\r
741      }\r
742    return NULL;\r
743 }\r
744 \r
745 /**\r
746  * Sets a title object for the Item\r
747  * @param[in] item The Navigationbar_ex Item\r
748  * @param[in] title_obj Title object (normally segment_control/searchbar)\r
749  *\r
750  * @ingroup Navigationbar_ex\r
751  */\r
752 EAPI void\r
753 elm_navigationbar_ex_item_title_object_set(Elm_Navigationbar_ex_Item* item, Evas_Object *title_obj)\r
754 {\r
755    if (!item) return;\r
756    if (item->title_obj) evas_object_del(item->title_obj);\r
757    item->title_obj = title_obj;\r
758    if (title_obj)\r
759      {\r
760         elm_widget_sub_object_add(item->obj,title_obj);\r
761         edje_object_part_swallow(item->base, "elm.swallow.title", title_obj);\r
762         edje_object_signal_callback_add(item->base, "elm,action,clicked", "elm",\r
763                                         _show_hide_titleobj, item);\r
764      }\r
765    _sizing_eval(item->obj);\r
766 }\r
767 \r
768 /**\r
769  * Hides the title area of the item.\r
770  * @param[in] item The Navigationbar_ex Item\r
771  * @param[in] hidden if EINA_TRUE the title area is hidden else its shown.\r
772  *\r
773  * @ingroup Navigationbar_ex\r
774  */\r
775 \r
776 EAPI void\r
777 elm_navigationbar_ex_item_title_hidden_set(Elm_Navigationbar_ex_Item* item, Eina_Bool hidden)\r
778 {\r
779    if (!item) return;\r
780    if (hidden) edje_object_signal_emit(item->base, "elm,state,item,moveup", "elm");\r
781    else edje_object_signal_emit(item->base, "elm,state,item,movedown", "elm");\r
782    _sizing_eval(item->obj);\r
783 }\r
784 \r
785 /**\r
786  * Unsets a title object for the item, the return object has to be deleted\r
787  * by application if not added again in to navigationbar.\r
788  *\r
789  * @param[in] item The Navigationbar_ex Item\r
790  * @return The title object or NULL if none is set\r
791  *\r
792  * @ingroup Navigationbar_ex\r
793  */\r
794 EAPI Evas_Object*\r
795 elm_navigationbar_ex_item_title_object_unset(Elm_Navigationbar_ex_Item* item)\r
796 {\r
797    if (!item) return NULL;\r
798    Evas_Object *title_obj=NULL;\r
799    if (!item->title_obj) return NULL;\r
800    title_obj = item->title_obj;\r
801    elm_widget_sub_object_del(item->obj,item->title_obj);\r
802    edje_object_part_unswallow(item->base,item->title_obj);\r
803    item->title_obj = NULL;\r
804    return title_obj;\r
805 }\r
806 \r
807 /**\r
808  * Returns the title object of the pushed content.\r
809  *\r
810  * @param[in] item The Navigationbar_ex Item\r
811  * @return The title object or NULL if none is set\r
812  *\r
813  * @ingroup Navigationbar_ex\r
814  */\r
815 EAPI Evas_Object*\r
816 elm_navigationbar_ex_item_title_object_get(Elm_Navigationbar_ex_Item* item)\r
817 {\r
818    if (!item) return NULL;\r
819    return item->title_obj;\r
820 }\r
821 \r
822 \r
823 /**\r
824  * Unsets the content of the item, the return object has to be deleted\r
825  * by application if not added again in to navigationbar, when the content\r
826  * is unset the corresponding item would be deleted, when this content is pushed again\r
827  * a new item would be created again.\r
828  *\r
829  * @param[in] item The Navigationbar_ex Item\r
830  * @return The content object or NULL if none is set\r
831  *\r
832  * @ingroup Navigationbar_ex\r
833  */\r
834 EAPI Evas_Object *\r
835 elm_navigationbar_ex_item_content_unset(Elm_Navigationbar_ex_Item* item)\r
836 {\r
837  if (!item) return NULL;\r
838    Evas_Object *content = _content_unset(item);\r
839    return content;\r
840 }\r
841 \r
842 /**\r
843  * Returns the content of the item.\r
844  *\r
845  * @param[in] item The Navigationbar_ex Item\r
846  * @return The content object or NULL if none is set\r
847  *\r
848  * @ingroup Navigationbar_ex\r
849  */\r
850 EAPI Evas_Object *\r
851 elm_navigationbar_ex_item_content_get(Elm_Navigationbar_ex_Item* item)\r
852 {\r
853    if (!item) return NULL;\r
854    return item->content;\r
855 }\r
856 \r
857 /**\r
858  * Set whether the content pushed has to be deleted on pop.\r
859  * if false the item is not deleted but only removed from the stack\r
860  * the pointer of the content is sent along with hide,finished signal.\r
861  *\r
862  * @param[in] obj The Navigationbar_ex object.\r
863  * @param[in] del_on_pop if set the content is deleted on pop else unset, by default the value is EINA_TRUE.\r
864  *\r
865  * @ingroup Navigationbar_ex\r
866  */\r
867 EAPI void\r
868 elm_navigationbar_ex_delete_on_pop_set(Evas_Object *obj, Eina_Bool del_on_pop)\r
869 {\r
870    ELM_CHECK_WIDTYPE(obj, widtype);\r
871    Widget_Data *wd = elm_widget_data_get(obj);\r
872    if (!wd) return;\r
873    wd->del_on_pop = del_on_pop;\r
874 }\r
875 \r
876 /**\r
877  * Sets the style of the navigationbar item.\r
878  * @param[in] item The Navigationbar_ex Item\r
879  * @param[in] item_style Navigationbar Item style, this can be used when the style of the item has to be dynamically set.\r
880  *\r
881  * @ingroup Navigationbar_ex\r
882  */\r
883 EAPI void\r
884 elm_navigationbar_ex_item_style_set(Elm_Navigationbar_ex_Item* item, const char* item_style)\r
885 {\r
886    if (!item) return;\r
887    if(!item_style) return;\r
888    char buf[1024];\r
889    char buf_fn[1024];\r
890    Eina_List *bl;\r
891    fn_button *btn_det;\r
892    strncpy(buf, "item/", sizeof(buf));\r
893    strncat(buf, item_style, sizeof(buf) - strlen(buf));\r
894    if (!eina_stringshare_replace(&item->item_style, item_style)) return;\r
895    _elm_theme_object_set(item->obj, item->base,  "navigationbar_ex", buf, elm_widget_style_get(item->obj));\r
896    if (item->title)\r
897      edje_object_part_text_set(item->base, "elm.text", item->title);\r
898    if (item->subtitle)\r
899      edje_object_part_text_set(item->base, "elm.text.sub", item->subtitle);\r
900    if (item->fnbtn_list)\r
901      {\r
902         EINA_LIST_FOREACH(item->fnbtn_list, bl, btn_det)\r
903           {\r
904              if (btn_det->btn_id == ELM_NAVIGATIONBAR_EX_BACK_BUTTON)\r
905                {\r
906                   snprintf(buf_fn, sizeof(buf_fn), "navigationbar_backbutton/%s", elm_widget_style_get(item->obj));\r
907                   elm_object_style_set(btn_det->btn, buf_fn);\r
908                }\r
909              else\r
910                {\r
911                   snprintf(buf_fn, sizeof(buf_fn), "navigationbar_functionbutton/%s", elm_widget_style_get(item->obj));\r
912                   elm_object_style_set(btn_det->btn, buf_fn);\r
913                }\r
914           }\r
915      }\r
916 }\r
917 \r
918 /**\r
919  * Returns the style of the item.\r
920  *\r
921  * @param[in] item The Navigationbar_ex Item\r
922  * @return The item style.\r
923  *\r
924  * @ingroup Navigationbar_ex\r
925  */\r
926 EAPI const char*\r
927 elm_navigationbar_ex_item_style_get(Elm_Navigationbar_ex_Item* item)\r
928 {\r
929    if (!item) return NULL;\r
930    return item->item_style;\r
931 }\r
932 \r
933 \r
934 /**\r
935  * Promote an object already in the stack to the top of the stack\r
936  *\r
937  * This will take the indicated object and promote it to the top of the stack\r
938  * as if it had been pushed there. The object must already be inside the\r
939  * Navigationbar_ex stack to work.\r
940  *\r
941  * @param[in] item The Navigationbar_ex item to promote.\r
942  * @ingroup Navigationbar_ex\r
943  */\r
944 EAPI void\r
945 elm_navigationbar_ex_item_promote(Elm_Navigationbar_ex_Item* item)\r
946 {\r
947    if (!item) return;\r
948    _item_promote(item);\r
949 }\r
950 \r
951 /**\r
952  * Pop to the inputted Navigationbar_ex item\r
953  * the rest of the items are deleted.\r
954  *\r
955  * @param[in] item The Navigationbar_ex item\r
956  *\r
957  * @ingroup Navigationbar_ex\r
958  */\r
959 EAPI void\r
960 elm_navigationbar_ex_to_item_pop(Elm_Navigationbar_ex_Item* item)\r
961 {\r
962    if (!item) return;\r
963    Widget_Data *wd = elm_widget_data_get(item->obj);\r
964    Elm_Navigationbar_ex_Item *it = NULL;\r
965    Eina_List *list;\r
966    if (!wd) return;\r
967    if (!wd->stack) return;\r
968    it = eina_list_last(wd->stack)->data;\r
969    it->popme = EINA_TRUE;\r
970    list = eina_list_last(wd->stack);\r
971    if (list)\r
972      {\r
973         while (list)\r
974           {\r
975              it = list->data;\r
976              if (it != item)\r
977                {\r
978                   wd->to_delete = eina_list_append(wd->to_delete, it);\r
979                   wd->stack = eina_list_remove_list(wd->stack, list);\r
980                }\r
981              else\r
982                break;\r
983 \r
984              list = list->prev;\r
985           }\r
986      }\r
987    _eval_top(it->obj);\r
988    if (wd->to_delete)\r
989      _process_deletions(wd);\r
990 }\r
991 \r
992 /**\r
993  * Pop the object that is on top of the Navigationbar_ex stack\r
994  * This pops the object that is on top (visible) in the navigationbar, makes it disappear, then deletes/unsets the object\r
995  * based on del_on_pop variable.\r
996  * The object that was underneath it on the stack will become visible.\r
997  *\r
998  * @param[in] obj The Navigationbar_ex object\r
999  *\r
1000  * @ingroup Navigationbar_ex\r
1001  */\r
1002 EAPI void\r
1003 elm_navigationbar_ex_item_pop(Evas_Object *obj)\r
1004 {\r
1005    ELM_CHECK_WIDTYPE(obj, widtype);\r
1006    Widget_Data *wd = elm_widget_data_get(obj);\r
1007    Eina_List *ll;\r
1008    Elm_Navigationbar_ex_Item *it;\r
1009    if (!wd) return;\r
1010    if (!wd->stack) return;\r
1011    it = eina_list_last(wd->stack)->data;\r
1012    it->popme = EINA_TRUE;\r
1013    ll = eina_list_last(wd->stack);\r
1014    if (ll)\r
1015      {\r
1016         ll = ll->prev;\r
1017         if (!ll)\r
1018           {\r
1019 \r
1020              Evas_Object *o, *o2;\r
1021              const char *onhide;\r
1022 \r
1023              wd->top = it;\r
1024              o = wd->top->ct_base;\r
1025              o2 = wd->top->base;\r
1026 \r
1027              edje_object_signal_emit(o2, "elm,action,pop", "elm");\r
1028              edje_object_signal_emit(o, "elm,action,pop", "elm");\r
1029              onhide = edje_object_data_get(o, "onhide");\r
1030              if (onhide)\r
1031                {\r
1032                   if (!strcmp(onhide, "raise"))\r
1033                     {\r
1034                        evas_object_raise(o2);\r
1035                        evas_object_raise(o);\r
1036                     }\r
1037                   else if (!strcmp(onhide, "lower"))\r
1038                     {\r
1039                        evas_object_lower(o2);\r
1040                        evas_object_lower(o);\r
1041                     }\r
1042                }\r
1043              wd->top = NULL;\r
1044           }\r
1045         else\r
1046           {\r
1047              it = ll->data;\r
1048              _item_promote(it);\r
1049           }\r
1050      }\r
1051 }\r
1052 \r
1053 \r
1054 /**\r
1055  * Return the item at the bottom of the Navigationbar_ex stack\r
1056  *\r
1057  * @param[in] obj The Navigationbar_ex object\r
1058  * @return The bottom item or NULL if none\r
1059  *\r
1060  * @ingroup Navigationbar_ex\r
1061  */\r
1062 EAPI Elm_Navigationbar_ex_Item*\r
1063 elm_navigationbar_ex_item_bottom_get(const Evas_Object *obj)\r
1064 {\r
1065    ELM_CHECK_WIDTYPE(obj, widtype) NULL;\r
1066    Widget_Data *wd = elm_widget_data_get(obj);\r
1067    Elm_Navigationbar_ex_Item *it;\r
1068    if (!wd) return NULL;\r
1069    if (!wd->stack) return NULL;\r
1070    it = wd->stack->data;\r
1071    return it;\r
1072 }\r
1073 \r
1074 /**\r
1075  * Return the item at the top of the Navigationbar_ex stack\r
1076  *\r
1077  * @param[in] obj The Navigationbar_ex object\r
1078  * @return The top object or NULL if none\r
1079  *\r
1080  * @ingroup Navigationbar_ex\r
1081  */\r
1082 EAPI Elm_Navigationbar_ex_Item*\r
1083 elm_navigationbar_ex_item_top_get(const Evas_Object *obj)\r
1084 {\r
1085    ELM_CHECK_WIDTYPE(obj, widtype) NULL;\r
1086    Widget_Data *wd = elm_widget_data_get(obj);\r
1087    Elm_Navigationbar_ex_Item *it;\r
1088    if (!wd) return NULL;\r
1089    if (!wd->stack) return NULL;\r
1090    it = eina_list_last(wd->stack)->data;\r
1091    return it;\r
1092 }\r
1093 \r
1094 /**\r
1095  * This disables content animation on push/pop.\r
1096  *\r
1097  * @param obj The navigationbar_ex object\r
1098  * @param disable  if EINA_TRUE animation is disabled.\r
1099  *\r
1100  * @ingroup Navigationbar_ex\r
1101  */\r
1102 EAPI void\r
1103 elm_navigationbar_ex_animation_disable_set(Evas_Object *obj, Eina_Bool disable)\r
1104 {\r
1105    ELM_CHECK_WIDTYPE(obj, widtype);\r
1106    Widget_Data *wd = elm_widget_data_get(obj);\r
1107    wd->disable_animation = disable;\r
1108 }\r
1109 \r
1110 \r
1111 \r