Merge "Fixed the UI artifact related to image floating sometimes while animating...
[framework/uifw/elementary.git] / src / lib / elc_naviframe.c
1 #include <Elementary.h>
2 #include "elm_priv.h"
3
4 typedef struct _Widget_Data Widget_Data;
5
6 struct _Widget_Data
7 {
8    Eina_List    *stack;
9    Evas_Object  *base;
10    Eina_Bool     preserve: 1;
11    Eina_Bool     pass_events: 1;
12 };
13
14 struct _Elm_Naviframe_Item
15 {
16    Elm_Widget_Item    base;
17    Evas_Object       *title;
18    Evas_Object       *content;
19    const char        *title_label;
20    const char        *title_sublabel;
21    Evas_Object       *title_prev_btn;
22    Evas_Object       *title_next_btn;
23    Evas_Object       *title_icon;
24    Evas_Object       *extension;
25    const char        *style;
26    Eina_Bool          back_btn: 1;
27    Eina_Bool          title_visible: 1;
28 };
29
30 static const char *widtype = NULL;
31
32 static const char SIG_TRANSITION_FINISHED[] = "transition,finished";
33 static const char SIG_TITLE_CLICKED[] = "title,clicked";
34
35 static const Evas_Smart_Cb_Description _signals[] = {
36        {SIG_TRANSITION_FINISHED, ""},
37        {SIG_TITLE_CLICKED, ""},
38        {NULL, NULL}
39 };
40
41 #define ELM_NAVIFRAME_ITEM_CHECK_RETURN(it, ...) \
42    ELM_WIDGET_ITEM_CHECK_OR_RETURN((Elm_Widget_Item *) it, __VA_ARGS__); \
43    ELM_CHECK_WIDTYPE(it->base.widget, widtype) __VA_ARGS__;
44
45 static void _del_hook(Evas_Object *obj);
46 static void _theme_hook(Evas_Object *obj);
47 static void _disable_hook(Evas_Object *obj);
48 static void _sizing_eval(Evas_Object *obj);
49 static void _item_sizing_eval(Elm_Naviframe_Item *it);
50 static void _move(void *data, Evas *e, Evas_Object *obj, void *event_info);
51 static void _resize(void *data,
52                     Evas *e,
53                     Evas_Object *obj,
54                     void *event_info);
55 static void _title_clicked(void *data, Evas_Object *obj,
56                            const char *emission,
57                            const char *source);
58 static void _back_btn_clicked(void *data,
59                               Evas_Object *obj,
60                               void *event_info);
61 static Evas_Object *_back_btn_new(Evas_Object *obj);
62 static void _title_prev_btn_del(void *data,
63                                 Evas *e,
64                                 Evas_Object *obj,
65                                 void *event_info);
66 static void _title_next_btn_del(void *data,
67                                 Evas *e,
68                                 Evas_Object *obj,
69                                 void *event_info);
70 static void _title_icon_del(void *data,
71                             Evas *e,
72                             Evas_Object *obj,
73                             void *event_info);
74 static void _content_del(void *data,
75                          Evas *e,
76                          Evas_Object *obj,
77                          void *event_info);
78 static void _extension_del(void *data,
79                            Evas *e,
80                            Evas_Object *obj,
81                            void *event_info);
82 static void _title_prev_btn_set(Elm_Naviframe_Item *it,
83                                 Evas_Object *btn,
84                                 Eina_Bool back_btn);
85 static void _title_next_btn_set(Elm_Naviframe_Item *it, Evas_Object *btn);
86 static void _item_del(Elm_Naviframe_Item *it);
87 static void _pushed_finished(void *data,
88                              Evas_Object *obj,
89                              const char *emission,
90                              const char *source);
91 static void _popped_finished(void *data,
92                              Evas_Object *obj,
93                              const char *emission,
94                              const char *source);
95 static void _show_finished(void *data,
96                            Evas_Object *obj,
97                            const char *emission,
98                            const char *source);
99
100 static void
101 _del_hook(Evas_Object *obj)
102 {
103    Widget_Data *wd;
104    Eina_List *list;
105    Elm_Naviframe_Item *it;
106
107    wd = elm_widget_data_get(obj);
108    if (!wd) return;
109
110    EINA_LIST_FOREACH(wd->stack, list, it)
111      _item_del(it);
112    eina_list_free(wd->stack);
113    free(wd);
114 }
115
116 static void
117 _theme_hook(Evas_Object *obj __UNUSED__)
118 {
119    //FIXME:
120 }
121
122 static void
123 _disable_hook(Evas_Object *obj __UNUSED__)
124 {
125    //FIXME:
126 }
127
128 static void
129 _sizing_eval(Evas_Object *obj)
130 {
131    Widget_Data *wd;
132    Eina_List *list;
133    Elm_Naviframe_Item *it;
134    wd  = elm_widget_data_get(obj);
135    if (!wd) return;
136
137    list = eina_list_last(wd->stack);
138    if (!list) return;
139
140    EINA_LIST_FOREACH(wd->stack, list, it)
141      _item_sizing_eval(it);
142 }
143
144 static void
145 _item_sizing_eval(Elm_Naviframe_Item *it)
146 {
147    Widget_Data *wd;
148    Evas_Coord x, y, w, h;
149    if (!it) return;
150
151    wd = elm_widget_data_get(it->base.widget);
152    if (!wd) return;
153
154    evas_object_geometry_get(it->base.widget, &x, &y, &w, &h);
155    evas_object_move(it->base.view, x, y);
156    evas_object_resize(it->base.view, w, h);
157 }
158
159 static void
160 _move(void *data __UNUSED__,
161       Evas *e __UNUSED__,
162       Evas_Object *obj,
163       void *event_info __UNUSED__)
164 {
165    _sizing_eval(obj);
166 }
167
168 static void
169 _resize(void *data __UNUSED__,
170         Evas *e __UNUSED__,
171         Evas_Object *obj,
172         void *event_info __UNUSED__)
173 {
174    _sizing_eval(obj);
175 }
176
177 static void
178 _title_clicked(void *data,
179                Evas_Object *obj __UNUSED__,
180                const char *emission __UNUSED__,
181                const char *source __UNUSED__)
182 {
183    Elm_Naviframe_Item *it = data;
184    evas_object_smart_callback_call(it->base.widget, SIG_TITLE_CLICKED, it);
185 }
186
187 static void
188 _back_btn_clicked(void *data,
189                   Evas_Object *obj __UNUSED__,
190                   void *event_info __UNUSED__)
191 {
192    elm_naviframe_item_pop(data);
193 }
194
195 static Evas_Object *
196 _back_btn_new(Evas_Object *obj)
197 {
198    Evas_Object *btn;
199    char buf[256];   //FIXME: How to guarantee the size of style name?
200    btn = elm_button_add(obj);
201    if (!btn) return NULL;
202    evas_object_smart_callback_add(btn, "clicked", _back_btn_clicked, obj);
203    snprintf(buf, sizeof(buf), "naviframe/back_btn/%s", elm_widget_style_get(obj));
204    elm_object_style_set(btn, buf);
205    return btn;
206 }
207
208 static void
209 _title_prev_btn_del(void *data,
210                     Evas *e __UNUSED__,
211                     Evas_Object *obj __UNUSED__,
212                     void *event_info __UNUSED__)
213 {
214    Elm_Naviframe_Item *it = data;
215    it->back_btn = EINA_FALSE;
216    it->title_prev_btn = NULL;
217 }
218
219 static void
220 _title_next_btn_del(void *data,
221                     Evas *e __UNUSED__,
222                     Evas_Object *obj __UNUSED__,
223                     void *event_info __UNUSED__)
224 {
225    Elm_Naviframe_Item *it = data;
226    it->title_next_btn = NULL;
227 }
228
229 static void
230 _title_icon_del(void *data,
231                 Evas *e __UNUSED__,
232                 Evas_Object *obj __UNUSED__,
233                 void *event_info __UNUSED__)
234 {
235    Elm_Naviframe_Item *it = data;
236    it->title_icon = NULL;
237    edje_object_signal_emit(it->base.view, "elm,state,icon,hide", "elm");
238 }
239
240 static void
241 _content_del(void *data,
242              Evas *e __UNUSED__,
243              Evas_Object *obj __UNUSED__,
244              void *event_info __UNUSED__)
245 {
246    Elm_Naviframe_Item *it = data;
247    it->content = NULL;
248    edje_object_signal_emit(it->base.view, "elm,state,content,hide", "elm");
249 }
250
251 static void
252 _extension_del(void *data,
253                Evas *e,
254                Evas_Object *obj __UNUSED__,
255                void *event_info __UNUSED__)
256 {
257    Elm_Naviframe_Item *it = data;
258    it->extension = NULL;
259 }
260
261 static void
262 _title_prev_btn_set(Elm_Naviframe_Item *it, Evas_Object *btn, Eina_Bool back_btn)
263 {
264    char buf[256];   //FIXME: How to guarantee the size of style name?
265
266    if (it->title_prev_btn == btn) return;
267
268    if (it->title_prev_btn)
269      evas_object_del(it->title_prev_btn);
270
271    it->title_prev_btn = btn;
272
273    if (!btn) return;
274
275    if (!back_btn)
276      {
277         snprintf(buf,
278                  sizeof(buf),
279                  "naviframe/prev_btn/%s",
280                  elm_widget_style_get(it->base.widget));
281         elm_object_style_set(btn, buf);
282      }
283    elm_widget_sub_object_add(it->base.widget, btn);
284    evas_object_event_callback_add(btn,
285                                   EVAS_CALLBACK_DEL,
286                                   _title_prev_btn_del,
287                                   it);
288    edje_object_part_swallow(it->title, "elm.swallow.prev_btn", btn);
289    it->back_btn = back_btn;
290 }
291
292 static void
293 _title_next_btn_set(Elm_Naviframe_Item *it, Evas_Object *btn)
294 {
295    char buf[256];   //FIXME: How to guarantee the size of style name?
296
297    if (it->title_next_btn == btn) return;
298
299    if (it->title_next_btn)
300      evas_object_del(it->title_next_btn);
301
302    it->title_next_btn = btn;
303
304    if (!btn) return;
305
306    snprintf(buf,
307             sizeof(buf),
308             "naviframe/next_btn/%s",
309             elm_widget_style_get(it->base.widget));
310    elm_object_style_set(btn, buf);
311    elm_widget_sub_object_add(it->base.widget, btn);
312    evas_object_event_callback_add(btn,
313                                   EVAS_CALLBACK_DEL,
314                                   _title_next_btn_del,
315                                   it);
316    edje_object_part_swallow(it->title, "elm.swallow.next_btn", btn);
317 }
318
319 static void
320 _item_del(Elm_Naviframe_Item *it)
321 {
322    Widget_Data *wd;
323
324    if (!it) return;
325
326    wd = elm_widget_data_get(it->base.widget);
327    if (!wd) return;
328
329    if (it->title_prev_btn)
330      evas_object_del(it->title_prev_btn);
331    if (it->title_next_btn)
332      evas_object_del(it->title_next_btn);
333    if (it->title_icon)
334      evas_object_del(it->title_icon);
335    if ((it->content) && (!wd->preserve))
336      evas_object_del(it->content);
337    if (it->extension)
338      evas_object_del(it->extension);
339
340    evas_object_del(it->title);
341    evas_object_del(it->base.view);
342
343    wd->stack = eina_list_remove(wd->stack, it);
344
345    free(it);
346 }
347
348 static void
349 _pushed_finished(void *data,
350                  Evas_Object *obj __UNUSED__,
351                  const char *emission __UNUSED__,
352                  const char *source __UNUSED__)
353 {
354    Elm_Naviframe_Item *it = data;
355    if (!it) return;
356    evas_object_hide(it->base.view);
357 }
358
359 static void
360 _popped_finished(void *data,
361                  Evas_Object *obj __UNUSED__,
362                  const char *emission __UNUSED__,
363                  const char *source __UNUSED__)
364 {
365    _item_del(data);
366 }
367
368 static void
369 _show_finished(void *data,
370                Evas_Object *obj __UNUSED__,
371                const char *emission __UNUSED__,
372                const char *source __UNUSED__)
373 {
374    Elm_Naviframe_Item *it;
375    Widget_Data *wd;
376
377    it = data;
378    if (!it) return;
379    wd =  elm_widget_data_get(it->base.widget);
380    if (!wd) return;
381
382    evas_object_smart_callback_call(it->base.widget,
383                                    SIG_TRANSITION_FINISHED,
384                                    (void *) EINA_TRUE);
385    if (wd->pass_events)
386      evas_object_pass_events_set(wd->base, EINA_FALSE);
387 }
388
389 EAPI Evas_Object *
390 elm_naviframe_add(Evas_Object *parent)
391 {
392    Evas_Object *obj;
393    Evas *e;
394    Widget_Data *wd;
395
396    ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL);
397    ELM_SET_WIDTYPE(widtype, "naviframe");
398    elm_widget_type_set(obj, "naviframe");
399    elm_widget_sub_object_add(parent, obj);
400    elm_widget_data_set(obj, wd);
401    elm_widget_del_hook_set(obj, _del_hook);
402    elm_widget_disable_hook_set(obj, _disable_hook);
403    elm_widget_theme_hook_set(obj, _theme_hook);
404
405    //base
406    wd->base = edje_object_add(e);
407    elm_widget_resize_object_set(obj, wd->base);
408    _elm_theme_object_set(obj, wd->base, "naviframe", "base", "default");
409
410    evas_object_event_callback_add(obj, EVAS_CALLBACK_MOVE, _move, obj);
411    evas_object_event_callback_add(obj, EVAS_CALLBACK_RESIZE, _resize, obj);
412    evas_object_smart_callbacks_descriptions_set(obj, _signals);
413
414    wd->pass_events = EINA_TRUE;
415
416    return obj;
417 }
418
419 EAPI Elm_Naviframe_Item *
420 elm_naviframe_item_push(Evas_Object *obj, const char *title_label, Evas_Object *prev_btn, Evas_Object *next_btn, Evas_Object *content, const char *item_style)
421 {
422    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
423    Widget_Data *wd;
424    Elm_Naviframe_Item *prev_it, *it;
425
426    wd = elm_widget_data_get(obj);
427    if (!wd) return NULL;
428
429    //create item
430    it = elm_widget_item_new(obj, Elm_Naviframe_Item);
431    if (!it)
432      {
433         ERR("Failed to allocate new item! : naviframe=%p", obj);
434         return NULL;
435      }
436    //item base layout
437    it->base.view = edje_object_add(evas_object_evas_get(obj));
438    evas_object_smart_member_add(it->base.view, wd->base);
439    elm_widget_sub_object_add(obj, it->base.view);
440    edje_object_signal_callback_add(it->base.view,
441                                    "elm,action,show,finished",
442                                    "",
443                                    _show_finished, it);
444    edje_object_signal_callback_add(it->base.view,
445                                    "elm,action,pushed,finished",
446                                    "",
447                                    _pushed_finished, it);
448    edje_object_signal_callback_add(it->base.view,
449                                    "elm,action,popped,finished",
450                                    "",
451                                    _popped_finished, it);
452    elm_naviframe_item_style_set(it, item_style);
453
454    //title
455    it->title = edje_object_add(evas_object_evas_get(obj));
456    elm_widget_sub_object_add(obj, it->title);
457    _elm_theme_object_set(obj,
458                          it->title, "naviframe",
459                          "title",
460                          elm_widget_style_get(obj));
461    edje_object_signal_callback_add(it->title,
462                                    "elm,action,clicked",
463                                    "elm",
464                                    _title_clicked, it);
465
466    elm_naviframe_item_title_label_set(it, title_label);
467
468    //title buttons
469    if ((!prev_btn) && (eina_list_count(wd->stack)))
470      {
471         prev_btn = _back_btn_new(obj);
472         _title_prev_btn_set(it, prev_btn, EINA_TRUE);
473      }
474    else
475      _title_prev_btn_set(it, prev_btn, EINA_FALSE);
476
477    _title_next_btn_set(it, next_btn);
478    edje_object_part_swallow(it->base.view, "elm.swallow.title", it->title);
479
480    elm_naviframe_item_content_set(it, content);
481
482    _item_sizing_eval(it);
483    evas_object_show(it->base.view);
484
485    prev_it = elm_naviframe_top_item_get(obj);
486    if (prev_it)
487      {
488         if (wd->pass_events)
489           evas_object_pass_events_set(wd->base, EINA_TRUE);
490         edje_object_signal_emit(prev_it->base.view,
491                                 "elm,state,pushed",
492                                 "elm");
493         edje_object_signal_emit(it->base.view,
494                                 "elm,state,show",
495                                 "elm");
496      }
497    else
498      edje_object_signal_emit(it->base.view, "elm,state,visible", "elm");
499    it->title_visible = EINA_TRUE;
500    wd->stack = eina_list_append(wd->stack, it);
501    return it;
502 }
503
504 EAPI Evas_Object *
505 elm_naviframe_item_pop(Evas_Object *obj)
506 {
507    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
508    Elm_Naviframe_Item *it, *prev_it;
509    Widget_Data *wd;
510    Evas_Object *content = NULL;
511
512    wd = elm_widget_data_get(obj);
513    if (!wd) return NULL;
514
515    it = elm_naviframe_top_item_get(obj);
516    if (!it) return NULL;
517    wd->stack = eina_list_remove(wd->stack, it);
518
519    if (wd->preserve)
520      content = it->content;
521
522    prev_it = elm_naviframe_top_item_get(obj);
523    if (prev_it)
524      {
525         if (wd->pass_events)
526           evas_object_pass_events_set(wd->base, EINA_TRUE);
527         evas_object_show(prev_it->base.view);
528         evas_object_raise(prev_it->base.view);
529         edje_object_signal_emit(prev_it->base.view,
530                                 "elm,state,show",
531                                 "elm");
532         edje_object_signal_emit(it->base.view, "elm,state,popped", "elm");
533      }
534    else
535      _item_del(it);
536
537    return content;
538 }
539
540 EAPI void
541 elm_naviframe_content_preserve_on_pop_set(Evas_Object *obj, Eina_Bool preserve)
542 {
543    ELM_CHECK_WIDTYPE(obj, widtype);
544    Widget_Data *wd = elm_widget_data_get(obj);
545    if (!wd) return;
546    wd->preserve = !!preserve;
547 }
548
549 EAPI Eina_Bool
550 elm_naviframe_content_preserve_on_pop_get(const Evas_Object *obj)
551 {
552    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
553    Widget_Data *wd = elm_widget_data_get(obj);
554    if (!wd) return EINA_FALSE;
555    return wd->preserve;
556 }
557
558 EAPI void
559 elm_naviframe_item_content_set(Elm_Naviframe_Item *it, Evas_Object *content)
560 {
561    ELM_NAVIFRAME_ITEM_CHECK_RETURN(it);
562
563    if (it->content == content) return;
564    if (it->content) evas_object_del(it->content);
565    elm_widget_sub_object_add(it->base.widget, content);
566    edje_object_part_swallow(it->base.view, "elm.swallow.content", content);
567    if (content)
568      edje_object_signal_emit(it->base.view,
569                              "elm,state,content,show",
570                              "elm");
571    else
572      edje_object_signal_emit(it->base.view,
573                              "elm,state,content,hide",
574                              "elm");
575    evas_object_event_callback_add(content,
576                                   EVAS_CALLBACK_DEL,
577                                   _content_del,
578                                   it);
579    it->content = content;
580    _item_sizing_eval(it);
581 }
582
583 EAPI Evas_Object *
584 elm_naviframe_item_content_get(const Elm_Naviframe_Item *it)
585 {
586    ELM_NAVIFRAME_ITEM_CHECK_RETURN(it, NULL);
587    return it->content;
588 }
589
590 EAPI void
591 elm_naviframe_item_title_label_set(Elm_Naviframe_Item *it, const char *label)
592 {
593    ELM_NAVIFRAME_ITEM_CHECK_RETURN(it);
594
595    edje_object_part_text_set(it->title, "elm.text.title", label);
596    if (label)
597      edje_object_signal_emit(it->title, "elm,state,title,show", "elm");
598    else
599      edje_object_signal_emit(it->title, "elm,state,title,hidew", "elm");
600
601    eina_stringshare_replace(&it->title_label, label);
602    _item_sizing_eval(it);
603 }
604
605 EAPI const char *
606 elm_naviframe_item_title_label_get(const Elm_Naviframe_Item *it)
607 {
608    ELM_NAVIFRAME_ITEM_CHECK_RETURN(it, NULL);
609    return it->title_label;
610 }
611
612 EAPI void
613 elm_naviframe_item_subtitle_label_set(Elm_Naviframe_Item *it, const char *label)
614 {
615    ELM_NAVIFRAME_ITEM_CHECK_RETURN(it);
616
617    edje_object_part_text_set(it->title, "elm.text.subtitle", label);
618    if (label)
619      edje_object_signal_emit(it->title, "elm,state,subtitle,show", "elm");
620    else
621      edje_object_signal_emit(it->title, "elm,state,subtitle,hide", "elm");
622
623    eina_stringshare_replace(&it->title_sublabel, label);
624    _item_sizing_eval(it);
625 }
626
627 EAPI const char *
628 elm_naviframe_item_subtitle_label_get(const Elm_Naviframe_Item *it)
629 {
630    ELM_NAVIFRAME_ITEM_CHECK_RETURN(it, NULL);
631    return it->title_sublabel;
632 }
633
634 EAPI Elm_Naviframe_Item*
635 elm_naviframe_top_item_get(const Evas_Object *obj)
636 {
637    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
638    Widget_Data *wd = elm_widget_data_get(obj);
639    if ((!wd) || (!wd->stack)) return NULL;
640    return eina_list_last(wd->stack)->data;
641 }
642
643 EAPI Elm_Naviframe_Item*
644 elm_naviframe_bottom_item_get(const Evas_Object *obj)
645 {
646    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
647    Widget_Data *wd = elm_widget_data_get(obj);
648    if (!wd) return NULL;
649    return NULL;
650 }
651
652 EAPI void
653 elm_naviframe_item_button_set(Elm_Naviframe_Item *it, Evas_Object *btn, Elm_Naviframe_Button_Type btn_type)
654 {
655    ELM_NAVIFRAME_ITEM_CHECK_RETURN(it);
656
657    switch(btn_type)
658      {
659         case ELM_NAVIFRAME_PREV_BUTTON:
660           _title_prev_btn_set(it, btn, EINA_FALSE);
661           break;
662         case ELM_NAVIFRAME_NEXT_BUTTON:
663           _title_next_btn_set(it, btn);
664           break;
665         default:
666           WRN("Button type is invalid! : naviframe=%p", it->base.widget);
667           break;
668      }
669    _item_sizing_eval(it);
670 }
671
672 EAPI Evas_Object *
673 elm_naviframe_item_button_get(const Elm_Naviframe_Item *it, Elm_Naviframe_Button_Type btn_type)
674 {
675    ELM_NAVIFRAME_ITEM_CHECK_RETURN(it, NULL);
676
677    switch(btn_type)
678      {
679         case ELM_NAVIFRAME_PREV_BUTTON:
680            return it->title_prev_btn;
681         case ELM_NAVIFRAME_NEXT_BUTTON:
682            return it->title_next_btn;
683         default:
684            WRN("Button type is invalid! : naviframe=%p", it->base.widget);
685            break;
686      }
687    return NULL;
688 }
689
690 EAPI void
691 elm_naviframe_item_icon_set(Elm_Naviframe_Item *it, Evas_Object *icon)
692 {
693    ELM_NAVIFRAME_ITEM_CHECK_RETURN(it);
694
695    Widget_Data *wd = elm_widget_data_get(it->base.widget);
696    if (!wd) return;
697
698    if (it->title_icon == icon) return;
699    if (it->title_icon) evas_object_del(it->title_icon);
700    it->title_icon = icon;
701    if (!icon)
702      {
703         edje_object_signal_emit(it->title,
704                                 "elm,state,icon,hide",
705                                 "elm");
706         return;
707      }
708    elm_widget_sub_object_add(it->base.widget, icon);
709    edje_object_part_swallow(it->title, "elm.swallow.icon", icon);
710    edje_object_signal_emit(it->title, "elm,state,icon,show", "elm");
711
712    evas_object_event_callback_add(icon, EVAS_CALLBACK_DEL, _title_icon_del, it);
713    _item_sizing_eval(it);
714 }
715
716 EAPI Evas_Object *
717 elm_naviframe_item_icon_get(const Elm_Naviframe_Item *it)
718 {
719    ELM_NAVIFRAME_ITEM_CHECK_RETURN(it, NULL);
720    return it->title_icon;
721 }
722
723 EAPI void
724 elm_naviframe_item_style_set(Elm_Naviframe_Item *it, const char *item_style)
725 {
726    ELM_NAVIFRAME_ITEM_CHECK_RETURN(it);
727
728    char buf[256];
729
730    if (!item_style) sprintf(buf, "item/basic");
731    else
732      {
733         if (strlen(item_style) > sizeof(buf))
734           WRN("too much long style name! : naviframe=%p", it->base.widget);
735         else
736           sprintf(buf, "item/%s", item_style);
737      }
738    _elm_theme_object_set(it->base.widget,
739                          it->base.view,
740                          "naviframe",
741                          buf,
742                          elm_widget_style_get(it->base.widget));
743 }
744
745 EAPI const char *
746 elm_naviframe_item_style_get(const Elm_Naviframe_Item *it)
747 {
748    ELM_NAVIFRAME_ITEM_CHECK_RETURN(it, NULL);
749    return it->style;
750 }
751
752 EAPI void
753 elm_naviframe_item_title_visible_set(Elm_Naviframe_Item *it, Eina_Bool visible)
754 {
755    ELM_NAVIFRAME_ITEM_CHECK_RETURN(it);
756
757    visible = !!visible;
758    if (it->title_visible == visible) return;
759
760    if (visible)
761      edje_object_signal_emit(it->base.view, "elm,state,title,show", "elm");
762    else
763      edje_object_signal_emit(it->base.view, "elm,state,title,hide", "elm");
764
765    it->title_visible = visible;
766 }
767
768 EAPI Eina_Bool
769 elm_naviframe_item_title_visible_get(const Elm_Naviframe_Item *it)
770 {
771    ELM_NAVIFRAME_ITEM_CHECK_RETURN(it, EINA_FALSE);
772    return it->title_visible;
773 }
774
775 EAPI void
776 elm_naviframe_item_extension_set(Elm_Naviframe_Item *it, const char *swallow, Evas_Object *extension)
777 {
778    ELM_NAVIFRAME_ITEM_CHECK_RETURN(it);
779    Evas_Object *prev;
780    if (!swallow)
781      {
782         WRN("swallow part should not be NULL! : naviframe=%p", it->base.widget);
783         return;
784      }
785    if (it->extension) evas_object_del(it->extension);
786    it->extension = extension;
787    if (!extension) return;
788    evas_object_event_callback_add(extension, EVAS_CALLBACK_DEL, _extension_del, it);
789    if (!edje_object_part_swallow(it->base.view, swallow, extension))
790      return;
791    elm_widget_sub_object_add(it->base.widget, extension);
792    edje_object_signal_emit(it->base.view,
793                            "elm,state,extension,show",
794                            "elm");
795    _sizing_eval(it->base.view);
796 }
797
798 EAPI Evas_Object *
799 elm_naviframe_item_extension_unset(Elm_Naviframe_Item *it, const char *swallow)
800 {
801    ELM_NAVIFRAME_ITEM_CHECK_RETURN(it, NULL);
802
803    Evas_Object *extension = it->extension;
804    if (!extension) return NULL;
805    edje_object_part_unswallow(it->base.view, extension);
806    elm_widget_sub_object_del(it->base.widget, extension);
807    evas_object_event_callback_del(extension, EVAS_CALLBACK_DEL, _extension_del);
808    edje_object_signal_emit(it->base.view,
809                            "elm,state,extension,hide",
810                            "elm");
811    _sizing_eval(it->base.widget);
812    it->extension = NULL;
813    return extension;
814 }
815
816 EAPI Evas_Object *
817 elm_naviframe_item_extension_get(const Elm_Naviframe_Item *it, const char *swallow)
818 {
819    ELM_NAVIFRAME_ITEM_CHECK_RETURN(it, NULL);
820    return edje_object_part_swallow_get(it->base.view, swallow);
821 }