elementary/naviframe - my fault. it shouldn't be committed.
[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 typedef struct _Elm_Naviframe_Item Elm_Naviframe_Item;
6 typedef struct _Elm_Naviframe_Content_Item_Pair Elm_Naviframe_Content_Item_Pair;
7 typedef struct _Elm_Naviframe_Text_Item_Pair Elm_Naviframe_Text_Item_Pair;
8
9 struct _Widget_Data
10 {
11    Eina_Inlist  *stack;
12    Evas_Object  *base;
13    Eina_Bool     preserve: 1;
14    Eina_Bool     auto_pushed: 1;
15    Eina_Bool     freeze_events: 1;
16 };
17
18 struct _Elm_Naviframe_Content_Item_Pair
19 {
20    EINA_INLIST;
21    const char *part;
22    Elm_Naviframe_Item *it;
23 };
24
25 struct _Elm_Naviframe_Text_Item_Pair
26 {
27    EINA_INLIST;
28    const char *part;
29 };
30
31 struct _Elm_Naviframe_Item
32 {
33    ELM_WIDGET_ITEM;
34    EINA_INLIST;
35    Eina_Inlist       *content_list;
36    Eina_Inlist       *text_list;
37    Evas_Object       *content;
38    Evas_Object       *title_prev_btn;
39    Evas_Object       *title_next_btn;
40    Evas_Object       *title_icon;
41    const char        *style;
42    Evas_Coord         minw;
43    Evas_Coord         minh;
44    Eina_Bool          back_btn: 1;
45    Eina_Bool          title_visible: 1;
46 };
47
48 static const char *widtype = NULL;
49
50 static const char SIG_TRANSITION_FINISHED[] = "transition,finished";
51 static const char SIG_PUSH_FINISHED[] = "push,finished";
52 static const char SIG_POP_FINISHED[] = "pop,finished";
53 static const char SIG_TITLE_CLICKED[] = "title,clicked";
54
55 static const Evas_Smart_Cb_Description _signals[] = {
56        {SIG_TRANSITION_FINISHED, ""},
57        {SIG_TITLE_CLICKED, ""},
58        {NULL, NULL}
59 };
60
61 static void _del_hook(Evas_Object *obj);
62 static void _theme_hook(Evas_Object *obj);
63 static void _emit_hook(Evas_Object *obj,
64                        const char *emission,
65                        const char *source);
66 static void _disable_hook(Evas_Object *obj);
67 static void _item_text_set_hook(Elm_Object_Item *it,
68                                 const char *part,
69                                 const char *label);
70 static const char *_item_text_get_hook(const Elm_Object_Item *it,
71                                        const char *part);
72 static void _item_content_set_hook(Elm_Object_Item *it,
73                                    const char *part,
74                                    Evas_Object *content);
75 static Evas_Object *_item_content_get_hook(const Elm_Object_Item *it,
76                                            const char *part);
77 static Evas_Object *_item_content_unset_hook(Elm_Object_Item *it,
78                                              const char *part);
79 static void _item_signal_emit_hook(Elm_Object_Item *it,
80                                    const char *emission,
81                                    const char *source);
82 static void _item_title_visible_update(Elm_Naviframe_Item *navi_it);
83 static void _sizing_eval(Evas_Object *obj);
84 static void _move(void *data, Evas *e, Evas_Object *obj, void *event_info);
85 static void _resize(void *data,
86                     Evas *e,
87                     Evas_Object *obj,
88                     void *event_info);
89 static void _title_clicked(void *data, Evas_Object *obj,
90                            const char *emission,
91                            const char *source);
92 static void _back_btn_clicked(void *data,
93                               Evas_Object *obj,
94                               void *event_info);
95 static Evas_Object *_back_btn_new(Evas_Object *obj);
96 static void _item_content_del(void *data,
97                               Evas *e,
98                               Evas_Object *obj,
99                               void *event_info);
100 static void _title_content_del(void *data,
101                                Evas *e,
102                                Evas_Object *obj,
103                                void *event_info);
104 static void _title_prev_btn_del(void *data,
105                                 Evas *e,
106                                 Evas_Object *obj,
107                                 void *event_info);
108 static void _title_next_btn_del(void *data,
109                                 Evas *e,
110                                 Evas_Object *obj,
111                                 void *event_info);
112 static void _title_icon_del(void *data,
113                             Evas *e,
114                             Evas_Object *obj,
115                             void *event_info);
116 static void _title_content_set(Elm_Naviframe_Item *it,
117                                const char *part,
118                                Evas_Object *content);
119 static void _title_prev_btn_set(Elm_Naviframe_Item *it,
120                                 Evas_Object *btn,
121                                 Eina_Bool back_btn);
122 static void _title_next_btn_set(Elm_Naviframe_Item *it, Evas_Object *btn);
123 static void _title_icon_set(Elm_Naviframe_Item *it, Evas_Object *icon);
124 static Evas_Object * _item_content_unset(Elm_Naviframe_Item *it);
125 static Evas_Object * _title_prev_btn_unset(Elm_Naviframe_Item *it);
126 static Evas_Object * _title_next_btn_unset(Elm_Naviframe_Item *it);
127 static Evas_Object * _title_icon_unset(Elm_Naviframe_Item *it);
128 static Evas_Object * _title_content_unset(Elm_Naviframe_Item *it,
129                                           const char *part);
130 static void _item_del(Elm_Naviframe_Item *it);
131 static void _item_del_pre_hook(Elm_Object_Item *it);
132 static void _pushed_finished(void *data,
133                              Evas_Object *obj,
134                              const char *emission,
135                              const char *source);
136 static void _popped_finished(void *data,
137                              Evas_Object *obj,
138                              const char *emission,
139                              const char *source);
140 static void _show_finished(void *data,
141                            Evas_Object *obj,
142                            const char *emission,
143                            const char *source);
144 static void _changed_size_hints(void *data,
145                                 Evas *e,
146                                 Evas_Object *obj,
147                                 void *event_info);
148 static void _item_content_set(Elm_Naviframe_Item *navi_it,
149                               Evas_Object *content);
150 static void _item_style_set(Elm_Naviframe_Item *navi_it,
151                             const char *item_style);
152 static Elm_Naviframe_Item * _item_new(Evas_Object *obj,
153                                       const char *title_label,
154                                       Evas_Object *prev_btn,
155                                       Evas_Object *next_btn,
156                                       Evas_Object *content,
157                                       const char *item_style);
158
159 static void
160 _del_hook(Evas_Object *obj)
161 {
162    Widget_Data *wd;
163    Elm_Naviframe_Item *it;
164
165    wd = elm_widget_data_get(obj);
166    if (!wd) return;
167
168    if (wd->stack)
169      {
170         while (wd->stack->last)
171           {
172              it = EINA_INLIST_CONTAINER_GET(wd->stack->last,
173                                             Elm_Naviframe_Item);
174              wd->stack = eina_inlist_remove(wd->stack, wd->stack->last);
175              _item_del(it);
176              elm_widget_item_free(it);
177              if (!wd->stack) break;
178           }
179      }
180    free(wd);
181 }
182
183 static void
184 _theme_hook(Evas_Object *obj)
185 {
186    Widget_Data *wd;
187    Elm_Naviframe_Item *it;
188
189    wd  = elm_widget_data_get(obj);
190    if (!wd) return;
191
192    _elm_theme_object_set(obj,
193                          wd->base,
194                          "naviframe",
195                          "base",
196                          elm_widget_style_get(obj));
197
198    EINA_INLIST_FOREACH(wd->stack, it)
199      {
200         _item_style_set(it, it->style);
201         _item_title_visible_update(it);
202      }
203 }
204
205 static void _emit_hook(Evas_Object *obj,
206                        const char *emission,
207                        const char *source)
208 {
209    ELM_CHECK_WIDTYPE(obj, widtype);
210
211    Widget_Data *wd = elm_widget_data_get(obj);
212    if (!wd) return;
213
214    elm_object_signal_emit(wd->base, emission, source);
215 }
216
217 static void
218 _disable_hook(Evas_Object *obj __UNUSED__)
219 {
220    //FIXME:
221 }
222
223 static void
224 _item_text_set_hook(Elm_Object_Item *it,
225                     const char *part,
226                     const char *label)
227 {
228    ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
229
230    Elm_Naviframe_Text_Item_Pair *pair = NULL;
231    Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
232    char buf[1024];
233
234    if (!part || !strcmp(part, "default"))
235      snprintf(buf, sizeof(buf), "elm.text.title");
236    else if(!strcmp("subtitle", part))
237      snprintf(buf, sizeof(buf), "elm.text.subtitle");
238    else
239      snprintf(buf, sizeof(buf), "%s", part);
240
241    EINA_INLIST_FOREACH(navi_it->text_list, pair)
242      if (!strcmp(buf, pair->part)) break;
243
244    if (!pair)
245      {
246         pair = ELM_NEW(Elm_Naviframe_Text_Item_Pair);
247         if (!pair)
248           {
249              ERR("Failed to allocate new text part of the item! : naviframe=%p",
250              WIDGET(navi_it));
251              return;
252           }
253         eina_stringshare_replace(&pair->part, buf);
254         navi_it->text_list = eina_inlist_append(navi_it->text_list,
255                                                 EINA_INLIST_GET(pair));
256      }
257    elm_object_part_text_set(VIEW(navi_it), buf, label);
258
259    if (label)
260      {
261         snprintf(buf, sizeof(buf), "elm,state,%s,show", buf);
262         elm_object_signal_emit(VIEW(navi_it), buf, "elm");
263      }
264    else
265      {
266         snprintf(buf, sizeof(buf), "elm,state,%s,hide", buf);
267         elm_object_signal_emit(VIEW(navi_it), buf, "elm");
268      }
269
270    _sizing_eval(WIDGET(navi_it));
271 }
272
273 static const char *
274 _item_text_get_hook(const Elm_Object_Item *it, const char *part)
275 {
276    ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
277    char buf[1024];
278
279    if (!part || !strcmp(part, "default"))
280      snprintf(buf, sizeof(buf), "elm.text.title");
281    else if(!strcmp("subtitle", part))
282      snprintf(buf, sizeof(buf), "elm.text.subtitle");
283    else
284      snprintf(buf, sizeof(buf), "%s", part);
285
286    return elm_object_part_text_get(VIEW(it), buf);
287 }
288
289 static void
290 _item_content_set_hook(Elm_Object_Item *it,
291                        const char *part,
292                        Evas_Object *content)
293 {
294    ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
295
296    Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
297
298    //specified parts
299    if (!part || !strcmp("default", part))
300      {
301         _item_content_set(navi_it, content);
302         return;
303      }
304    else if (!strcmp(part, "prev_btn"))
305      {
306         _title_prev_btn_set(navi_it, content, EINA_FALSE);
307         return;
308      }
309    else if (!strcmp(part, "next_btn"))
310      {
311         _title_next_btn_set(navi_it, content);
312         return;
313      }
314    else if (!strcmp(part, "icon"))
315      {
316         _title_icon_set(navi_it, content);
317         return;
318      }
319
320    //common part
321    _title_content_set(navi_it, part, content);
322 }
323
324 static Evas_Object *
325 _item_content_get_hook(const Elm_Object_Item *it, const char *part)
326 {
327    ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
328    Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
329
330    //specified parts
331    if (!part || !strcmp("default", part))
332      return navi_it->content;
333    else if (!strcmp(part, "prev_btn"))
334      return navi_it->title_prev_btn;
335    else if (!strcmp(part, "next_btn"))
336      return navi_it->title_next_btn;
337    else if (!strcmp(part, "icon"))
338      return navi_it->title_icon;
339
340    //common parts
341    return elm_object_part_content_get(VIEW(navi_it), part);
342 }
343
344 static Evas_Object *
345 _item_content_unset_hook(Elm_Object_Item *it, const char *part)
346 {
347    ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
348    Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
349
350    //specified parts
351    if (!part || !strcmp("default", part))
352      return _item_content_unset(navi_it);
353    else if (!strcmp(part, "prev_btn"))
354      return _title_prev_btn_unset(navi_it);
355    else if (!strcmp(part, "next_btn"))
356      return _title_next_btn_unset(navi_it);
357    else if (!strcmp(part, "icon"))
358      return _title_icon_unset(navi_it);
359
360    return _title_content_unset(navi_it, part);
361 }
362
363 static void
364 _item_signal_emit_hook(Elm_Object_Item *it,
365                        const char *emission,
366                        const char *source)
367 {
368    ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
369    elm_object_signal_emit(VIEW(it), emission, source);
370 }
371
372 static void
373 _item_title_visible_update(Elm_Naviframe_Item *navi_it)
374 {
375    if (navi_it->title_visible)
376      elm_object_signal_emit(VIEW(navi_it), "elm,state,title,show", "elm");
377    else
378      elm_object_signal_emit(VIEW(navi_it), "elm,state,title,hide", "elm");
379 }
380
381 static void
382 _sizing_eval(Evas_Object *obj)
383 {
384    Widget_Data *wd;
385    Elm_Naviframe_Item *it;
386    Evas_Coord x, y, w, h;
387    Evas_Coord minw = -1, minh = -1;
388
389    wd = elm_widget_data_get(obj);
390    if (!wd) return;
391
392    evas_object_geometry_get(obj, &x, &y, &w, &h);
393
394    EINA_INLIST_FOREACH(wd->stack, it)
395      {
396         evas_object_move(VIEW(it), x, y);
397         evas_object_resize(VIEW(it), w, h);
398         edje_object_size_min_calc(elm_layout_edje_get(VIEW(it)),
399                                   &it->minw,
400                                   &it->minh);
401         if (it->minw > minw) minw = it->minw;
402         if (it->minh > minh) minh = it->minh;
403      }
404    evas_object_size_hint_min_set(obj, minw, minh);
405    evas_object_size_hint_max_set(obj, -1, -1);
406 }
407
408 static void
409 _move(void *data __UNUSED__,
410       Evas *e __UNUSED__,
411       Evas_Object *obj,
412       void *event_info __UNUSED__)
413 {
414    _sizing_eval(obj);
415 }
416
417 static void
418 _resize(void *data __UNUSED__,
419         Evas *e __UNUSED__,
420         Evas_Object *obj,
421         void *event_info __UNUSED__)
422 {
423    _sizing_eval(obj);
424 }
425
426 static void
427 _title_clicked(void *data,
428                Evas_Object *obj __UNUSED__,
429                const char *emission __UNUSED__,
430                const char *source __UNUSED__)
431 {
432    Elm_Naviframe_Item *it = data;
433    evas_object_smart_callback_call(WIDGET(it), SIG_TITLE_CLICKED, it);
434 }
435
436 static void
437 _back_btn_clicked(void *data,
438                   Evas_Object *obj,
439                   void *event_info __UNUSED__)
440 {
441 /* Since edje has the event queue, clicked event could be happend multiple times
442    on some heavy environment. This callback del will prevent those  scenario and
443    guarantee only one clicked for it's own page. */
444    evas_object_smart_callback_del(obj, "clicked", _back_btn_clicked);
445    elm_naviframe_item_pop(data);
446 }
447
448 static Evas_Object *
449 _back_btn_new(Evas_Object *obj)
450 {
451    Evas_Object *btn;
452    char buf[1024];
453    btn = elm_button_add(obj);
454    if (!btn) return NULL;
455    evas_object_smart_callback_add(btn, "clicked", _back_btn_clicked, obj);
456    snprintf(buf, sizeof(buf), "naviframe/back_btn/%s", elm_widget_style_get(obj));
457    elm_object_style_set(btn, buf);
458    return btn;
459 }
460
461 static void
462 _title_content_del(void *data,
463                    Evas *e __UNUSED__,
464                    Evas_Object *obj __UNUSED__,
465                    void *event_info __UNUSED__)
466 {
467    char buf[1024];
468    Elm_Naviframe_Content_Item_Pair *pair = data;
469    Elm_Naviframe_Item *it = pair->it;
470    snprintf(buf, sizeof(buf), "elm,state,%s,hide", pair->part);
471    elm_object_signal_emit(VIEW(it), buf, "elm");
472    it->content_list = eina_inlist_remove(it->content_list,
473                                          EINA_INLIST_GET(pair));
474    eina_stringshare_del(pair->part);
475    free(pair);
476 }
477
478 static void
479 _title_prev_btn_del(void *data,
480                     Evas *e __UNUSED__,
481                     Evas_Object *obj __UNUSED__,
482                     void *event_info __UNUSED__)
483 {
484    Elm_Naviframe_Item *it = data;
485    it->back_btn = EINA_FALSE;
486    it->title_prev_btn = NULL;
487    elm_object_signal_emit(VIEW(it), "elm,state,prev_btn,hide", "elm");
488 }
489
490 static void
491 _title_next_btn_del(void *data,
492                     Evas *e __UNUSED__,
493                     Evas_Object *obj __UNUSED__,
494                     void *event_info __UNUSED__)
495 {
496    Elm_Naviframe_Item *it = data;
497    it->title_next_btn = NULL;
498    elm_object_signal_emit(VIEW(it), "elm,state,next_btn,hide", "elm");
499 }
500
501 static void
502 _title_icon_del(void *data,
503                 Evas *e __UNUSED__,
504                 Evas_Object *obj __UNUSED__,
505                 void *event_info __UNUSED__)
506 {
507    Elm_Naviframe_Item *it = data;
508    it->title_icon = NULL;
509    elm_object_signal_emit(VIEW(it), "elm,state,icon,hide", "elm");
510 }
511
512 static void
513 _item_content_del(void *data,
514                   Evas *e __UNUSED__,
515                   Evas_Object *obj __UNUSED__,
516                   void *event_info __UNUSED__)
517 {
518    Elm_Naviframe_Item *it = data;
519    it->content = NULL;
520    elm_object_signal_emit(VIEW(it), "elm,state,content,hide", "elm");
521 }
522
523 static void
524 _title_content_set(Elm_Naviframe_Item *it,
525                    const char *part,
526                    Evas_Object *content)
527 {
528    char buf[1024];
529    Elm_Naviframe_Content_Item_Pair *pair = NULL;
530    Evas_Object *prev_content = NULL;
531
532    EINA_INLIST_FOREACH(it->content_list, pair)
533      if (!strcmp(part, pair->part)) break;
534
535    if (pair)
536      {
537         prev_content = elm_object_part_content_get(VIEW(it), part);
538         if (prev_content != content)
539           {
540              if (content)
541                {
542                   evas_object_event_callback_del(prev_content,
543                                                  EVAS_CALLBACK_DEL,
544                                                  _title_content_del);
545                   snprintf(buf, sizeof(buf), "elm,state,%s,hide", part);
546                   elm_object_signal_emit(VIEW(it), buf, "elm");
547                }
548              evas_object_del(prev_content);
549              if (!content) return;
550           }
551      }
552    else
553      {
554         if (!content) return;
555         pair = ELM_NEW(Elm_Naviframe_Content_Item_Pair);
556         if (!pair)
557           {
558              ERR("Failed to allocate new content part of the item! : naviframe=%p", WIDGET(it));
559              return;
560           }
561         pair->it = it;
562         eina_stringshare_replace(&pair->part, part);
563         it->content_list = eina_inlist_append(it->content_list,
564                                               EINA_INLIST_GET(pair));
565      }
566    if (prev_content != content)
567      {
568         evas_object_event_callback_add(content,
569                                        EVAS_CALLBACK_DEL,
570                                        _title_content_del,
571                                        pair);
572      }
573    elm_object_part_content_set(VIEW(it), part, content);
574    snprintf(buf, sizeof(buf), "elm,state,%s,show", part);
575    elm_object_signal_emit(VIEW(it), buf, "elm");
576
577    _sizing_eval(WIDGET(it));
578 }
579
580 static void
581 _title_prev_btn_set(Elm_Naviframe_Item *it,
582                     Evas_Object *btn,
583                     Eina_Bool back_btn)
584 {
585    if (it->title_prev_btn == btn) return;
586    if (it->title_prev_btn) evas_object_del(it->title_prev_btn);
587    it->title_prev_btn = btn;
588    if (!btn) return;
589
590    evas_object_event_callback_add(btn,
591                                   EVAS_CALLBACK_DEL,
592                                   _title_prev_btn_del,
593                                   it);
594    elm_object_part_content_set(VIEW(it), "elm.swallow.prev_btn", btn);
595    elm_object_signal_emit(VIEW(it), "elm,state,prev_btn,show", "elm");
596    it->back_btn = back_btn;
597
598    _sizing_eval(WIDGET(it));
599 }
600
601 static void
602 _title_next_btn_set(Elm_Naviframe_Item *it, Evas_Object *btn)
603 {
604    if (it->title_next_btn == btn) return;
605    if (it->title_next_btn) evas_object_del(it->title_next_btn);
606    it->title_next_btn = btn;
607    if (!btn) return;
608
609    evas_object_event_callback_add(btn,
610                                   EVAS_CALLBACK_DEL,
611                                   _title_next_btn_del,
612                                   it);
613    elm_object_part_content_set(VIEW(it), "elm.swallow.next_btn", btn);
614    elm_object_signal_emit(VIEW(it), "elm,state,next_btn,show", "elm");
615
616    _sizing_eval(WIDGET(it));
617 }
618
619 static void
620 _title_icon_set(Elm_Naviframe_Item *it, Evas_Object *icon)
621 {
622    if (it->title_icon == icon) return;
623    if (it->title_icon) evas_object_del(it->title_icon);
624    it->title_icon = icon;
625    if (!icon) return;
626
627    evas_object_event_callback_add(icon,
628                                   EVAS_CALLBACK_DEL,
629                                   _title_icon_del,
630                                   it);
631    elm_object_part_content_set(VIEW(it), "elm.swallow.icon", icon);
632    elm_object_signal_emit(VIEW(it), "elm,state,icon,show", "elm");
633
634    _sizing_eval(WIDGET(it));
635 }
636
637 static Evas_Object *
638 _item_content_unset(Elm_Naviframe_Item *it)
639 {
640    Evas_Object *content = it->content;
641    if (!content) return NULL;
642
643    elm_object_part_content_unset(VIEW(it), "elm.swallow.content");
644    elm_object_signal_emit(VIEW(it), "elm,state,content,hide", "elm");
645    evas_object_event_callback_del(content,
646                                   EVAS_CALLBACK_DEL,
647                                   _item_content_del);
648    _sizing_eval(WIDGET(it));
649
650    it->content = NULL;
651    return content;
652 }
653
654 static Evas_Object *
655 _title_prev_btn_unset(Elm_Naviframe_Item *it)
656 {
657    Evas_Object *content = it->title_prev_btn;
658    if (!content) return NULL;
659
660    elm_object_part_content_unset(VIEW(it), "elm.swallow.prev_btn");
661    elm_object_signal_emit(VIEW(it), "elm,state,prev_btn,hide", "elm");
662    evas_object_event_callback_del(content,
663                                   EVAS_CALLBACK_DEL,
664                                   _title_prev_btn_del);
665    _sizing_eval(WIDGET(it));
666
667    it->title_prev_btn = NULL;
668    return content;
669 }
670
671 static Evas_Object *
672 _title_next_btn_unset(Elm_Naviframe_Item *it)
673 {
674    Evas_Object *content = it->title_next_btn;
675    if (!content) return NULL;
676
677    elm_object_part_content_unset(VIEW(it), "elm.swallow.next_btn");
678    elm_object_signal_emit(VIEW(it), "elm,state,next_btn,hide", "elm");
679    evas_object_event_callback_del(content,
680                                   EVAS_CALLBACK_DEL,
681                                   _title_next_btn_del);
682    _sizing_eval(WIDGET(it));
683
684    it->title_next_btn = NULL;
685    return content;
686 }
687
688 static Evas_Object *
689 _title_icon_unset(Elm_Naviframe_Item *it)
690 {
691    Evas_Object *content = it->title_icon;
692    if (!content) return NULL;
693
694    elm_object_part_content_unset(VIEW(it), "elm.swallow.icon");
695    elm_object_signal_emit(VIEW(it), "elm,state,icon,hide", "elm");
696    evas_object_event_callback_del(content,
697                                   EVAS_CALLBACK_DEL,
698                                   _title_icon_del);
699    _sizing_eval(WIDGET(it));
700    it->title_icon = NULL;
701
702    return content;
703 }
704
705 static Evas_Object *
706 _title_content_unset(Elm_Naviframe_Item *it, const char *part)
707 {
708    Elm_Naviframe_Content_Item_Pair *pair = NULL;
709    char buf[1028];
710    Evas_Object *content = NULL;
711
712    EINA_INLIST_FOREACH(it->content_list, pair)
713      {
714         if (!strcmp(part, pair->part))
715           {
716              content = elm_object_part_content_get(VIEW(it), part);
717              eina_stringshare_del(pair->part);
718              it->content_list = eina_inlist_remove(it->content_list,
719                                                    EINA_INLIST_GET(pair));
720              free(pair);
721              break;
722           }
723      }
724
725    if (!content) return NULL;
726
727    elm_object_part_content_unset(VIEW(it), part);
728    snprintf(buf, sizeof(buf), "elm,state,%s,hide", part);
729    elm_object_signal_emit(VIEW(it), buf, "elm");
730    evas_object_event_callback_del(content,
731                                   EVAS_CALLBACK_DEL,
732                                   _title_content_del);
733    _sizing_eval(WIDGET(it));
734
735    return content;
736 }
737
738 static void
739 _item_del(Elm_Naviframe_Item *it)
740 {
741    Widget_Data *wd;
742    Elm_Naviframe_Content_Item_Pair *content_pair;
743    Elm_Naviframe_Text_Item_Pair *text_pair;
744    Evas_Object *content;
745
746    if (!it) return;
747
748    wd = elm_widget_data_get(WIDGET(it));
749    if (!wd) return;
750
751    while (it->content_list)
752      {
753         content_pair =
754            EINA_INLIST_CONTAINER_GET(it->content_list,
755                                      Elm_Naviframe_Content_Item_Pair);
756         content = elm_object_part_content_get(VIEW(it), content_pair->part);
757         evas_object_event_callback_del(content,
758                                        EVAS_CALLBACK_DEL,
759                                        _title_content_del);
760         eina_stringshare_del(content_pair->part);
761         it->content_list = eina_inlist_remove(it->content_list,
762                                               it->content_list);
763         free(content_pair);
764      }
765
766    while (it->text_list)
767      {
768         text_pair = EINA_INLIST_CONTAINER_GET(it->text_list,
769                                               Elm_Naviframe_Text_Item_Pair);
770         eina_stringshare_del(text_pair->part);
771         it->text_list = eina_inlist_remove(it->text_list,
772                                            it->text_list);
773         free(text_pair);
774      }
775
776    eina_stringshare_del(it->style);
777 }
778
779 static void
780 _item_del_pre_hook(Elm_Object_Item *it)
781 {
782    ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
783    Elm_Naviframe_Item *navi_it;
784    Widget_Data *wd;
785
786    navi_it =(Elm_Naviframe_Item *) it;
787    wd = elm_widget_data_get(WIDGET(navi_it));
788    if (!wd) return;
789
790    if (it == elm_naviframe_top_item_get(WIDGET(navi_it)))
791      {
792         wd->stack = eina_inlist_remove(wd->stack, EINA_INLIST_GET(navi_it));
793         _item_del(navi_it);
794         elm_widget_item_free(navi_it);
795         //If the item is only one, the stack will be empty
796         if (!wd->stack) return;
797         navi_it = EINA_INLIST_CONTAINER_GET(wd->stack->last,
798                                             Elm_Naviframe_Item);
799         evas_object_show(VIEW(navi_it));
800         evas_object_raise(VIEW(navi_it));
801         elm_object_signal_emit(VIEW(navi_it), "elm,state,visible", "elm");
802      }
803    else
804      {
805         wd->stack = eina_inlist_remove(wd->stack, EINA_INLIST_GET(navi_it));
806         _item_del(navi_it);
807         elm_widget_item_free(navi_it);
808      }
809 }
810
811 static void
812 _pushed_finished(void *data,
813                  Evas_Object *obj __UNUSED__,
814                  const char *emission __UNUSED__,
815                  const char *source __UNUSED__)
816 {
817    Widget_Data *wd;
818    Elm_Naviframe_Item *it = data;
819    if (!it) return;
820
821    wd = elm_widget_data_get(WIDGET(it));
822    if (!wd) return;
823
824    evas_object_hide(VIEW(it));
825    evas_object_smart_callback_call(WIDGET(it),
826                                    SIG_PUSH_FINISHED,
827                                    data);
828    if (wd->freeze_events)
829      evas_object_freeze_events_set(VIEW(it), EINA_FALSE);
830 }
831
832 static void
833 _popped_finished(void *data,
834                  Evas_Object *obj __UNUSED__,
835                  const char *emission __UNUSED__,
836                  const char *source __UNUSED__)
837 {
838    Elm_Naviframe_Item *it = data;
839    if (!it) return;
840    evas_object_smart_callback_call(WIDGET(it),
841                                    SIG_POP_FINISHED,
842                                    data);
843    _item_del(data);
844    elm_widget_item_free(data);
845 }
846
847 static void
848 _show_finished(void *data,
849                Evas_Object *obj __UNUSED__,
850                const char *emission __UNUSED__,
851                const char *source __UNUSED__)
852 {
853    Elm_Naviframe_Item *it;
854    Widget_Data *wd;
855
856    it = data;
857    if (!it) return;
858    wd =  elm_widget_data_get(WIDGET(it));
859    if (!wd) return;
860
861    evas_object_smart_callback_call(WIDGET(it),
862                                    SIG_TRANSITION_FINISHED,
863                                    data);
864    if (wd->freeze_events)
865      evas_object_freeze_events_set(VIEW(it), EINA_FALSE);
866 }
867
868 static void
869 _changed_size_hints(void *data,
870                     Evas *e __UNUSED__,
871                     Evas_Object *obj __UNUSED__,
872                     void *event_info __UNUSED__)
873 {
874    _sizing_eval(data);
875 }
876
877 static void
878 _item_content_set(Elm_Naviframe_Item *navi_it, Evas_Object *content)
879 {
880    if (navi_it->content == content) return;
881    if (navi_it->content) evas_object_del(navi_it->content);
882    elm_object_part_content_set(VIEW(navi_it), "elm.swallow.content", content);
883
884    if (content)
885      elm_object_signal_emit(VIEW(navi_it), "elm,state,content,show", "elm");
886    else
887      elm_object_signal_emit(VIEW(navi_it), "elm,state,content,hide", "elm");
888
889    evas_object_event_callback_add(content,
890                                   EVAS_CALLBACK_DEL,
891                                   _item_content_del,
892                                   navi_it);
893    navi_it->content = content;
894    _sizing_eval(WIDGET(navi_it));
895 }
896
897 //FIXME: need to handle if this function is called while transition
898 static void
899 _item_style_set(Elm_Naviframe_Item *navi_it, const char *item_style)
900 {
901    Elm_Naviframe_Content_Item_Pair *content_pair;
902    Elm_Naviframe_Text_Item_Pair *text_pair;
903    Widget_Data *wd;
904
905    char buf[256];
906
907    if (!item_style)
908      {
909         strcpy(buf, "item/basic");
910         eina_stringshare_replace(&navi_it->style, "basic");
911      }
912    else
913      {
914         snprintf(buf, sizeof(buf), "item/%s", item_style);
915         eina_stringshare_replace(&navi_it->style, item_style);
916      }
917    elm_layout_theme_set(VIEW(navi_it),
918                         "naviframe",
919                         buf,
920                         elm_widget_style_get(WIDGET(navi_it)));
921    //recover item
922    EINA_INLIST_FOREACH(navi_it->text_list, text_pair)
923      _item_text_set_hook((Elm_Object_Item *) navi_it,
924                          text_pair->part,
925                          elm_object_part_text_get(VIEW(navi_it),
926                                                   text_pair->part));
927
928    EINA_INLIST_FOREACH(navi_it->content_list, content_pair)
929      _item_content_set_hook((Elm_Object_Item *) navi_it,
930                             content_pair->part,
931                             elm_object_part_content_get(VIEW(navi_it),
932                                                         content_pair->part));
933    //content
934    if (navi_it->content)
935      elm_object_signal_emit(VIEW(navi_it), "elm,state,content,show", "elm");
936
937    //prev button
938    if (navi_it->title_prev_btn)
939      elm_object_signal_emit(VIEW(navi_it), "elm,state,prev_btn,show", "elm");
940
941    //next button
942    if (navi_it->title_next_btn)
943      elm_object_signal_emit(VIEW(navi_it), "elm,state,next_btn,show", "elm");
944
945    navi_it->title_visible = EINA_TRUE;
946    _sizing_eval(WIDGET(navi_it));
947
948    wd = elm_widget_data_get(WIDGET(navi_it));
949    if (!wd) return;
950
951    if (wd->freeze_events)
952      evas_object_freeze_events_set(VIEW(navi_it), EINA_FALSE);
953 }
954
955 static Elm_Naviframe_Item *
956 _item_new(Evas_Object *obj,
957           const char *title_label,
958           Evas_Object *prev_btn,
959           Evas_Object *next_btn,
960           Evas_Object *content,
961           const char *item_style)
962 {
963    Widget_Data *wd = elm_widget_data_get(obj);
964
965    //create item
966    Elm_Naviframe_Item *it = elm_widget_item_new(obj, Elm_Naviframe_Item);
967    if (!it)
968      {
969         ERR("Failed to allocate new item! : naviframe=%p", obj);
970         return NULL;
971      }
972
973    elm_widget_item_del_pre_hook_set(it, _item_del_pre_hook);
974    elm_widget_item_text_set_hook_set(it, _item_text_set_hook);
975    elm_widget_item_text_get_hook_set(it, _item_text_get_hook);
976    elm_widget_item_content_set_hook_set(it, _item_content_set_hook);
977    elm_widget_item_content_get_hook_set(it, _item_content_get_hook);
978    elm_widget_item_content_unset_hook_set(it, _item_content_unset_hook);
979    elm_widget_item_signal_emit_hook_set(it, _item_signal_emit_hook);
980
981    //item base layout
982    VIEW(it) = elm_layout_add(obj);
983    evas_object_smart_member_add(VIEW(it), wd->base);
984
985    evas_object_event_callback_add(VIEW(it),
986                                   EVAS_CALLBACK_CHANGED_SIZE_HINTS,
987                                   _changed_size_hints,
988                                   obj);
989    elm_object_signal_callback_add(VIEW(it),
990                                    "elm,action,show,finished",
991                                    "",
992                                    _show_finished, it);
993    elm_object_signal_callback_add(VIEW(it),
994                                    "elm,action,pushed,finished",
995                                    "",
996                                    _pushed_finished, it);
997    elm_object_signal_callback_add(VIEW(it),
998                                    "elm,action,popped,finished",
999                                    "",
1000                                    _popped_finished, it);
1001    elm_object_signal_callback_add(VIEW(it),
1002                                    "elm,action,title,clicked",
1003                                    "",
1004                                    _title_clicked, it);
1005
1006    _item_style_set(it, item_style);
1007    _item_text_set_hook((Elm_Object_Item *) it, "elm.text.title", title_label);
1008
1009    //title buttons
1010    if ((!prev_btn) && wd->auto_pushed && eina_inlist_count(wd->stack))
1011      {
1012         prev_btn = _back_btn_new(obj);
1013         _title_prev_btn_set(it, prev_btn, EINA_TRUE);
1014      }
1015    else
1016      _title_prev_btn_set(it, prev_btn, EINA_FALSE);
1017
1018    _title_next_btn_set(it, next_btn);
1019    _item_content_set(it, content);
1020    it->title_visible = EINA_TRUE;
1021    return it;
1022 }
1023
1024 static Eina_Bool
1025 _focus_next_hook(const Evas_Object *obj, Elm_Focus_Direction dir, Evas_Object **next)
1026 {
1027    Widget_Data *wd = elm_widget_data_get(obj);
1028    if (!wd || !wd->stack) return EINA_FALSE;
1029    return elm_widget_focus_next_get(VIEW(elm_naviframe_top_item_get(obj)),
1030                                     dir,
1031                                     next);
1032 }
1033
1034 EAPI Evas_Object *
1035 elm_naviframe_add(Evas_Object *parent)
1036 {
1037    Evas_Object *obj;
1038    Evas *e;
1039    Widget_Data *wd;
1040
1041    ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL);
1042    ELM_SET_WIDTYPE(widtype, "naviframe");
1043    elm_widget_type_set(obj, "naviframe");
1044    elm_widget_sub_object_add(parent, obj);
1045    elm_widget_data_set(obj, wd);
1046    elm_widget_del_hook_set(obj, _del_hook);
1047    elm_widget_disable_hook_set(obj, _disable_hook);
1048    elm_widget_theme_hook_set(obj, _theme_hook);
1049    elm_widget_signal_emit_hook_set(obj, _emit_hook);
1050    elm_widget_can_focus_set(obj, EINA_FALSE);
1051    elm_widget_focus_next_hook_set(obj, _focus_next_hook);
1052
1053    //base
1054    wd->base = elm_layout_add(parent);
1055    evas_object_event_callback_add(wd->base,
1056                                   EVAS_CALLBACK_CHANGED_SIZE_HINTS,
1057                                   _changed_size_hints,
1058                                   obj);
1059    elm_widget_resize_object_set(obj, wd->base);
1060    elm_layout_theme_set(wd->base, "naviframe", "base", "default");
1061
1062    evas_object_event_callback_add(obj, EVAS_CALLBACK_MOVE, _move, obj);
1063    evas_object_event_callback_add(obj, EVAS_CALLBACK_RESIZE, _resize, obj);
1064    evas_object_smart_callbacks_descriptions_set(obj, _signals);
1065
1066    wd->auto_pushed = EINA_TRUE;
1067    wd->freeze_events = EINA_TRUE;
1068
1069    return obj;
1070 }
1071
1072 EAPI Elm_Object_Item *
1073 elm_naviframe_item_push(Evas_Object *obj,
1074                         const char *title_label,
1075                         Evas_Object *prev_btn,
1076                         Evas_Object *next_btn,
1077                         Evas_Object *content,
1078                         const char *item_style)
1079 {
1080    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1081    Widget_Data *wd;
1082    Elm_Naviframe_Item *prev_it, *it;
1083
1084    wd = elm_widget_data_get(obj);
1085    if (!wd) return NULL;
1086
1087    it = _item_new(obj, title_label, prev_btn, next_btn, content, item_style);
1088    if (!it) return NULL;
1089
1090    evas_object_show(VIEW(it));
1091
1092    prev_it = (Elm_Naviframe_Item *) elm_naviframe_top_item_get(obj);
1093    if (prev_it)
1094      {
1095         if (wd->freeze_events)
1096           {
1097              evas_object_freeze_events_set(VIEW(it), EINA_TRUE);
1098              evas_object_freeze_events_set(VIEW(prev_it), EINA_TRUE);
1099           }
1100         elm_object_signal_emit(VIEW(prev_it), "elm,state,cur,pushed", "elm");
1101         elm_object_signal_emit(VIEW(it), "elm,state,new,pushed", "elm");
1102         edje_object_message_signal_process(elm_layout_edje_get(VIEW(prev_it)));
1103         edje_object_message_signal_process(elm_layout_edje_get(VIEW(it)));
1104      }
1105    wd->stack = eina_inlist_append(wd->stack, EINA_INLIST_GET(it));
1106    _sizing_eval(obj);
1107    return (Elm_Object_Item *) it;
1108 }
1109
1110 EAPI Elm_Object_Item *
1111 elm_naviframe_item_insert_before(Elm_Object_Item *before,
1112                                  const char *title_label,
1113                                  Evas_Object *prev_btn,
1114                                  Evas_Object *next_btn,
1115                                  Evas_Object *content,
1116                                  const char *item_style)
1117 {
1118    ELM_OBJ_ITEM_CHECK_OR_RETURN(before, NULL);
1119    Elm_Naviframe_Item *it;
1120    Widget_Data *wd;
1121
1122    wd = elm_widget_data_get(WIDGET(before));
1123    if (!wd) return NULL;
1124
1125    it = _item_new(WIDGET(before), title_label, prev_btn, next_btn, content,
1126                   item_style);
1127    if (!it) return NULL;
1128
1129    wd->stack =
1130       eina_inlist_prepend_relative(wd->stack, EINA_INLIST_GET(it),
1131                                    EINA_INLIST_GET(((Elm_Naviframe_Item *) before)));
1132    _sizing_eval(WIDGET(before));
1133    return (Elm_Object_Item *) it;
1134 }
1135
1136 EAPI Elm_Object_Item *
1137 elm_naviframe_item_insert_after(Elm_Object_Item *after,
1138                                 const char *title_label,
1139                                 Evas_Object *prev_btn,
1140                                 Evas_Object *next_btn,
1141                                 Evas_Object *content,
1142                                 const char *item_style)
1143 {
1144    ELM_OBJ_ITEM_CHECK_OR_RETURN(after, NULL);
1145    Elm_Naviframe_Item *it;
1146    Widget_Data *wd;
1147
1148    wd = elm_widget_data_get(WIDGET(after));
1149    if (!wd) return NULL;
1150
1151    it = _item_new(WIDGET(after), title_label, prev_btn, next_btn, content,
1152                   item_style);
1153    if (!it) return NULL;
1154
1155    if (elm_naviframe_top_item_get(WIDGET(after)) == after)
1156      {
1157         evas_object_hide(VIEW(after));
1158         evas_object_show(VIEW(it));
1159      }
1160    wd->stack =
1161       eina_inlist_append_relative(wd->stack, EINA_INLIST_GET(it),
1162                                   EINA_INLIST_GET(((Elm_Naviframe_Item *) after)));
1163    _sizing_eval(WIDGET(after));
1164    return (Elm_Object_Item *) it;
1165 }
1166
1167 EAPI Evas_Object *
1168 elm_naviframe_item_pop(Evas_Object *obj)
1169 {
1170    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1171    Elm_Naviframe_Item *it, *prev_it = NULL;
1172    Widget_Data *wd;
1173    Evas_Object *content = NULL;
1174
1175    wd = elm_widget_data_get(obj);
1176    if (!wd) return NULL;
1177
1178    it = (Elm_Naviframe_Item *) elm_naviframe_top_item_get(obj);
1179    if (!it) return NULL;
1180    elm_widget_tree_unfocusable_set(it->content, EINA_TRUE);
1181    if (wd->preserve)
1182      content = it->content;
1183
1184    if (wd->stack->last->prev)
1185      prev_it = EINA_INLIST_CONTAINER_GET(wd->stack->last->prev,
1186                                          Elm_Naviframe_Item);
1187    wd->stack = eina_inlist_remove(wd->stack, EINA_INLIST_GET(it));
1188    if (prev_it)
1189      {
1190         if (wd->freeze_events)
1191           {
1192              evas_object_freeze_events_set(VIEW(it), EINA_TRUE);
1193              evas_object_freeze_events_set(VIEW(prev_it), EINA_TRUE);
1194           }
1195         elm_object_signal_emit(VIEW(it), "elm,state,cur,popped", "elm");
1196         evas_object_show(VIEW(prev_it));
1197         evas_object_raise(VIEW(prev_it));
1198         elm_object_signal_emit(VIEW(prev_it),
1199                                "elm,state,prev,popped",
1200                                "elm");
1201         edje_object_message_signal_process(elm_layout_edje_get(VIEW(it)));
1202         edje_object_message_signal_process(elm_layout_edje_get(VIEW(prev_it)));
1203      }
1204    else
1205      {
1206         _item_del(it);
1207         elm_widget_item_free(it);
1208      }
1209
1210    return content;
1211 }
1212
1213 EAPI void
1214 elm_naviframe_item_pop_to(Elm_Object_Item *it)
1215 {
1216    ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1217    Elm_Naviframe_Item *navi_it;
1218    Widget_Data *wd;
1219    Eina_Inlist *l, *prev_l;
1220
1221    navi_it = (Elm_Naviframe_Item *) it;
1222    wd = elm_widget_data_get(WIDGET(navi_it));
1223    if (!wd) return;
1224
1225    if (it == elm_naviframe_top_item_get(WIDGET(navi_it))) return;
1226
1227    l = wd->stack->last->prev;
1228
1229    while(l)
1230      {
1231         if (EINA_INLIST_CONTAINER_GET(l, Elm_Naviframe_Item) ==
1232             ((Elm_Naviframe_Item *) it)) break;
1233         prev_l = l->prev;
1234         wd->stack = eina_inlist_remove(wd->stack, l);
1235         _item_del(EINA_INLIST_CONTAINER_GET(l, Elm_Naviframe_Item));
1236         elm_widget_item_free(EINA_INLIST_CONTAINER_GET(l,
1237                                                        Elm_Naviframe_Item));
1238         l = prev_l;
1239      }
1240    elm_naviframe_item_pop(WIDGET(navi_it));
1241 }
1242
1243 EAPI void
1244 elm_naviframe_item_promote(Elm_Object_Item *it)
1245 {
1246    ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1247    Elm_Naviframe_Item *navi_it;
1248    Elm_Naviframe_Item *prev_it;
1249    Widget_Data *wd;
1250
1251    navi_it = (Elm_Naviframe_Item *) it;
1252    wd = elm_widget_data_get(navi_it->base.widget);
1253    if (!wd) return;
1254
1255    if (it == elm_naviframe_top_item_get(navi_it->base.widget)) return;
1256    wd->stack = eina_inlist_demote(wd->stack, EINA_INLIST_GET(navi_it));
1257    prev_it = EINA_INLIST_CONTAINER_GET(wd->stack->last->prev,
1258                                          Elm_Naviframe_Item);
1259    if (wd->freeze_events)
1260      {
1261         evas_object_freeze_events_set(VIEW(it), EINA_TRUE);
1262         evas_object_freeze_events_set(VIEW(prev_it), EINA_TRUE);
1263      }
1264    elm_object_signal_emit(VIEW(prev_it),
1265                           "elm,state,cur,pushed",
1266                           "elm");
1267    evas_object_show(VIEW(navi_it));
1268    evas_object_raise(VIEW(navi_it));
1269    elm_object_signal_emit(VIEW(navi_it),
1270                           "elm,state,new,pushed",
1271                           "elm");
1272    edje_object_message_signal_process(elm_layout_edje_get(VIEW(prev_it)));
1273    edje_object_message_signal_process(elm_layout_edje_get(VIEW(navi_it)));
1274 }
1275
1276 EAPI void
1277 elm_naviframe_item_del(Elm_Object_Item *it)
1278 {
1279    elm_object_item_del(it);
1280 }
1281
1282 EAPI void
1283 elm_naviframe_content_preserve_on_pop_set(Evas_Object *obj, Eina_Bool preserve)
1284 {
1285    ELM_CHECK_WIDTYPE(obj, widtype);
1286    Widget_Data *wd = elm_widget_data_get(obj);
1287    if (!wd) return;
1288    wd->preserve = !!preserve;
1289 }
1290
1291 EAPI Eina_Bool
1292 elm_naviframe_content_preserve_on_pop_get(const Evas_Object *obj)
1293 {
1294    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
1295    Widget_Data *wd = elm_widget_data_get(obj);
1296    if (!wd) return EINA_FALSE;
1297    return wd->preserve;
1298 }
1299
1300 EAPI Elm_Object_Item*
1301 elm_naviframe_top_item_get(const Evas_Object *obj)
1302 {
1303    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1304    Widget_Data *wd = elm_widget_data_get(obj);
1305    if ((!wd) || (!wd->stack)) return NULL;
1306    return (Elm_Object_Item *) (EINA_INLIST_CONTAINER_GET(wd->stack->last,
1307                                                          Elm_Naviframe_Item));
1308 }
1309
1310 EAPI Elm_Object_Item*
1311 elm_naviframe_bottom_item_get(const Evas_Object *obj)
1312 {
1313    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1314    Widget_Data *wd = elm_widget_data_get(obj);
1315    if ((!wd) || (!wd->stack)) return NULL;
1316    return (Elm_Object_Item *) (EINA_INLIST_CONTAINER_GET(wd->stack,
1317                                                          Elm_Naviframe_Item));
1318 }
1319
1320 EAPI void
1321 elm_naviframe_item_style_set(Elm_Object_Item *it, const char *item_style)
1322 {
1323    ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1324    Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
1325
1326    //Return if new style is exsiting one.
1327    if (item_style)
1328      if (!strcmp(item_style, navi_it->style)) return;
1329
1330    if (!item_style)
1331      if (!strcmp("basic", navi_it->style)) return;
1332
1333    _item_style_set(navi_it, item_style);
1334 }
1335
1336 EAPI const char *
1337 elm_naviframe_item_style_get(const Elm_Object_Item *it)
1338 {
1339    ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
1340    Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
1341    return navi_it->style;
1342 }
1343
1344 EAPI void
1345 elm_naviframe_item_title_visible_set(Elm_Object_Item *it, Eina_Bool visible)
1346 {
1347    ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1348    Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
1349
1350    visible = !!visible;
1351    if (navi_it->title_visible == visible) return;
1352
1353    navi_it->title_visible = visible;
1354    _item_title_visible_update(navi_it);
1355 }
1356
1357 EAPI Eina_Bool
1358 elm_naviframe_item_title_visible_get(const Elm_Object_Item *it)
1359 {
1360    ELM_OBJ_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
1361    Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
1362    return navi_it->title_visible;
1363 }
1364
1365 EAPI void
1366 elm_naviframe_prev_btn_auto_pushed_set(Evas_Object *obj, Eina_Bool auto_pushed)
1367 {
1368    ELM_CHECK_WIDTYPE(obj, widtype);
1369    Widget_Data *wd = elm_widget_data_get(obj);
1370    if (!wd) return;
1371    wd->auto_pushed = !!auto_pushed;
1372 }
1373
1374 EAPI Eina_Bool
1375 elm_naviframe_prev_btn_auto_pushed_get(const Evas_Object *obj)
1376 {
1377    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
1378    Widget_Data *wd = elm_widget_data_get(obj);
1379    if (!wd) return EINA_FALSE;
1380    return wd->auto_pushed;
1381 }
1382
1383 EAPI Eina_Inlist *
1384 elm_naviframe_items_get(const Evas_Object *obj)
1385 {
1386    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1387    Widget_Data *wd = elm_widget_data_get(obj);
1388    if (!wd) return NULL;
1389    return wd->stack;
1390 }
1391
1392 EAPI void
1393 elm_naviframe_event_enabled_set(Evas_Object *obj, Eina_Bool enabled)
1394 {
1395    ELM_CHECK_WIDTYPE(obj, widtype);
1396    Widget_Data *wd = elm_widget_data_get(obj);
1397    if (!wd) return;
1398    enabled = !!enabled;
1399    if (wd->freeze_events == !enabled) return;
1400    wd->freeze_events = !enabled;
1401 }
1402
1403 EAPI Eina_Bool
1404 elm_naviframe_event_enabled_get(const Evas_Object *obj)
1405 {
1406    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
1407    Widget_Data *wd = elm_widget_data_get(obj);
1408    if (!wd) return EINA_FALSE;
1409    return !wd->freeze_events;
1410 }