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