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