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