elementary/naviframe - updated doc & more contents & text hooks
[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         elm_widget_item_free(navi_it);
847         //If the item is only one, the stack will be empty
848         if (!wd->stack) return EINA_TRUE;
849         navi_it = EINA_INLIST_CONTAINER_GET(wd->stack->last,
850                                             Elm_Naviframe_Item);
851         evas_object_show(VIEW(navi_it));
852         evas_object_raise(VIEW(navi_it));
853         elm_object_signal_emit(VIEW(navi_it), "elm,state,visible", "elm");
854      }
855    else
856      {
857         wd->stack = eina_inlist_remove(wd->stack, EINA_INLIST_GET(navi_it));
858         _item_del(navi_it);
859         elm_widget_item_free(navi_it);
860      }
861
862    return EINA_TRUE;
863 }
864
865 static void
866 _pushed_finished(void *data,
867                  Evas_Object *obj __UNUSED__,
868                  const char *emission __UNUSED__,
869                  const char *source __UNUSED__)
870 {
871    Widget_Data *wd;
872    Elm_Naviframe_Item *it = data;
873    if (!it) return;
874
875    wd = elm_widget_data_get(WIDGET(it));
876    if (!wd) return;
877
878    evas_object_hide(VIEW(it));
879    evas_object_smart_callback_call(WIDGET(it),
880                                    SIG_PUSH_FINISHED,
881                                    data);
882    if (wd->freeze_events)
883      evas_object_freeze_events_set(VIEW(it), EINA_FALSE);
884 }
885
886 static void
887 _popped_finished(void *data,
888                  Evas_Object *obj __UNUSED__,
889                  const char *emission __UNUSED__,
890                  const char *source __UNUSED__)
891 {
892    Elm_Naviframe_Item *it = data;
893    if (!it) return;
894    evas_object_smart_callback_call(WIDGET(it),
895                                    SIG_POP_FINISHED,
896                                    data);
897    _item_del(data);
898    elm_widget_item_free(data);
899 }
900
901 static void
902 _show_finished(void *data,
903                Evas_Object *obj __UNUSED__,
904                const char *emission __UNUSED__,
905                const char *source __UNUSED__)
906 {
907    Elm_Naviframe_Item *it;
908    Widget_Data *wd;
909
910    it = data;
911    if (!it) return;
912    wd =  elm_widget_data_get(WIDGET(it));
913    if (!wd) return;
914
915    evas_object_smart_callback_call(WIDGET(it),
916                                    SIG_TRANSITION_FINISHED,
917                                    data);
918    if (wd->freeze_events)
919      evas_object_freeze_events_set(VIEW(it), EINA_FALSE);
920 }
921
922 static void
923 _changed_size_hints(void *data,
924                     Evas *e __UNUSED__,
925                     Evas_Object *obj __UNUSED__,
926                     void *event_info __UNUSED__)
927 {
928    _sizing_eval(data);
929 }
930
931 static void
932 _item_content_set(Elm_Naviframe_Item *navi_it, Evas_Object *content)
933 {
934    if (navi_it->content == content) return;
935    if (navi_it->content) evas_object_del(navi_it->content);
936    elm_object_part_content_set(VIEW(navi_it), "elm.swallow.content", content);
937
938    if (content)
939      elm_object_signal_emit(VIEW(navi_it), "elm,state,content,show", "elm");
940    else
941      elm_object_signal_emit(VIEW(navi_it), "elm,state,content,hide", "elm");
942
943    evas_object_event_callback_add(content,
944                                   EVAS_CALLBACK_DEL,
945                                   _item_content_del,
946                                   navi_it);
947    navi_it->content = content;
948    _sizing_eval(WIDGET(navi_it));
949 }
950
951 //FIXME: need to handle if this function is called while transition
952 static void
953 _item_style_set(Elm_Naviframe_Item *navi_it, const char *item_style)
954 {
955    Elm_Naviframe_Content_Item_Pair *content_pair;
956    Elm_Naviframe_Text_Item_Pair *text_pair;
957    Widget_Data *wd;
958    wd = elm_widget_data_get(WIDGET(navi_it));
959    if (!wd) return;
960
961    char buf[256];
962
963    if (!item_style)
964      {
965         snprintf(buf, sizeof(buf), "item/%s", wd->item_style);
966      }
967    else
968      {
969         snprintf(buf, sizeof(buf), "item/%s", item_style);
970         eina_stringshare_replace(&navi_it->style, item_style);
971      }
972    elm_layout_theme_set(VIEW(navi_it),
973                         "naviframe",
974                         buf,
975                         elm_widget_style_get(WIDGET(navi_it)));
976    //recover item
977    EINA_INLIST_FOREACH(navi_it->text_list, text_pair)
978      _item_text_set_hook((Elm_Object_Item *) navi_it,
979                          text_pair->part,
980                          elm_object_part_text_get(VIEW(navi_it),
981                                                   text_pair->part));
982
983    EINA_INLIST_FOREACH(navi_it->content_list, content_pair)
984      _item_content_set_hook((Elm_Object_Item *) navi_it,
985                             content_pair->part,
986                             elm_object_part_content_get(VIEW(navi_it),
987                                                         content_pair->part));
988    //content
989    if (navi_it->content)
990      elm_object_signal_emit(VIEW(navi_it), "elm,state,content,show", "elm");
991
992    //prev button
993    if (navi_it->title_prev_btn)
994      elm_object_signal_emit(VIEW(navi_it), "elm,state,prev_btn,show", "elm");
995
996    //next button
997    if (navi_it->title_next_btn)
998      elm_object_signal_emit(VIEW(navi_it), "elm,state,next_btn,show", "elm");
999
1000    navi_it->title_visible = EINA_TRUE;
1001    _sizing_eval(WIDGET(navi_it));
1002
1003    if (wd->freeze_events)
1004      evas_object_freeze_events_set(VIEW(navi_it), EINA_FALSE);
1005 }
1006
1007 static Elm_Naviframe_Item *
1008 _item_new(Evas_Object *obj,
1009           const char *title_label,
1010           Evas_Object *prev_btn,
1011           Evas_Object *next_btn,
1012           Evas_Object *content,
1013           const char *item_style)
1014 {
1015    Widget_Data *wd = elm_widget_data_get(obj);
1016
1017    //create item
1018    Elm_Naviframe_Item *it = elm_widget_item_new(obj, Elm_Naviframe_Item);
1019    if (!it)
1020      {
1021         ERR("Failed to allocate new item! : naviframe=%p", obj);
1022         return NULL;
1023      }
1024
1025    elm_widget_item_del_pre_hook_set(it, _item_del_pre_hook);
1026    elm_widget_item_text_set_hook_set(it, _item_text_set_hook);
1027    elm_widget_item_text_get_hook_set(it, _item_text_get_hook);
1028    elm_widget_item_content_set_hook_set(it, _item_content_set_hook);
1029    elm_widget_item_content_get_hook_set(it, _item_content_get_hook);
1030    elm_widget_item_content_unset_hook_set(it, _item_content_unset_hook);
1031    elm_widget_item_signal_emit_hook_set(it, _item_signal_emit_hook);
1032
1033    //item base layout
1034    VIEW(it) = elm_layout_add(obj);
1035    evas_object_smart_member_add(VIEW(it), wd->base);
1036
1037    evas_object_event_callback_add(VIEW(it),
1038                                   EVAS_CALLBACK_CHANGED_SIZE_HINTS,
1039                                   _changed_size_hints,
1040                                   obj);
1041    elm_object_signal_callback_add(VIEW(it),
1042                                    "elm,action,show,finished",
1043                                    "",
1044                                    _show_finished, it);
1045    elm_object_signal_callback_add(VIEW(it),
1046                                    "elm,action,pushed,finished",
1047                                    "",
1048                                    _pushed_finished, it);
1049    elm_object_signal_callback_add(VIEW(it),
1050                                    "elm,action,popped,finished",
1051                                    "",
1052                                    _popped_finished, it);
1053    elm_object_signal_callback_add(VIEW(it),
1054                                    "elm,action,title,clicked",
1055                                    "",
1056                                    _title_clicked, it);
1057
1058    _item_style_set(it, item_style);
1059    _item_text_set_hook((Elm_Object_Item *) it, "elm.text.title", title_label);
1060
1061    //title buttons
1062    if ((!prev_btn) && wd->auto_pushed && eina_inlist_count(wd->stack))
1063      {
1064         prev_btn = _back_btn_new(obj);
1065         _title_prev_btn_set(it, prev_btn, EINA_TRUE);
1066      }
1067    else
1068      _title_prev_btn_set(it, prev_btn, EINA_FALSE);
1069
1070    _title_next_btn_set(it, next_btn);
1071    _item_content_set(it, content);
1072    it->title_visible = EINA_TRUE;
1073    return it;
1074 }
1075
1076 static Eina_Bool
1077 _focus_next_hook(const Evas_Object *obj, Elm_Focus_Direction dir, Evas_Object **next)
1078 {
1079    Widget_Data *wd = elm_widget_data_get(obj);
1080    if (!wd || !wd->stack) return EINA_FALSE;
1081    return elm_widget_focus_next_get(VIEW(elm_naviframe_top_item_get(obj)),
1082                                     dir,
1083                                     next);
1084 }
1085
1086 EAPI Evas_Object *
1087 elm_naviframe_add(Evas_Object *parent)
1088 {
1089    Evas_Object *obj;
1090    Evas *e;
1091    Widget_Data *wd;
1092
1093    ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL);
1094    ELM_SET_WIDTYPE(widtype, "naviframe");
1095    elm_widget_type_set(obj, "naviframe");
1096    elm_widget_sub_object_add(parent, obj);
1097    elm_widget_data_set(obj, wd);
1098    elm_widget_del_hook_set(obj, _del_hook);
1099    elm_widget_disable_hook_set(obj, _disable_hook);
1100    elm_widget_theme_hook_set(obj, _theme_hook);
1101    elm_widget_text_set_hook_set(obj, _text_set_hook);
1102    elm_widget_text_get_hook_set(obj, _text_get_hook);
1103    elm_widget_content_set_hook_set(obj, _content_set_hook);
1104    elm_widget_content_get_hook_set(obj, _content_get_hook);
1105    elm_widget_content_unset_hook_set(obj, _content_unset_hook);
1106    elm_widget_signal_emit_hook_set(obj, _emit_hook);
1107    elm_widget_can_focus_set(obj, EINA_FALSE);
1108    elm_widget_focus_next_hook_set(obj, _focus_next_hook);
1109
1110    //base
1111    //FIXME: Is this base layout really needed?
1112    wd->base = elm_layout_add(parent);
1113    evas_object_event_callback_add(wd->base,
1114                                   EVAS_CALLBACK_CHANGED_SIZE_HINTS,
1115                                   _changed_size_hints,
1116                                   obj);
1117    elm_widget_resize_object_set(obj, wd->base);
1118    elm_layout_theme_set(wd->base, "naviframe", "base", "default");
1119
1120    evas_object_event_callback_add(obj, EVAS_CALLBACK_MOVE, _move, obj);
1121    evas_object_event_callback_add(obj, EVAS_CALLBACK_RESIZE, _resize, obj);
1122    evas_object_smart_callbacks_descriptions_set(obj, _signals);
1123
1124    wd->auto_pushed = EINA_TRUE;
1125    wd->freeze_events = EINA_TRUE;
1126    wd->item_style = eina_stringshare_add("basic");
1127
1128    return obj;
1129 }
1130
1131 EAPI Elm_Object_Item *
1132 elm_naviframe_item_push(Evas_Object *obj,
1133                         const char *title_label,
1134                         Evas_Object *prev_btn,
1135                         Evas_Object *next_btn,
1136                         Evas_Object *content,
1137                         const char *item_style)
1138 {
1139    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1140    Widget_Data *wd;
1141    Elm_Naviframe_Item *prev_it, *it;
1142
1143    wd = elm_widget_data_get(obj);
1144    if (!wd) return NULL;
1145
1146    it = _item_new(obj, title_label, prev_btn, next_btn, content, item_style);
1147    if (!it) return NULL;
1148
1149    evas_object_show(VIEW(it));
1150
1151    prev_it = (Elm_Naviframe_Item *) elm_naviframe_top_item_get(obj);
1152    if (prev_it)
1153      {
1154         if (wd->freeze_events)
1155           {
1156              evas_object_freeze_events_set(VIEW(it), EINA_TRUE);
1157              evas_object_freeze_events_set(VIEW(prev_it), EINA_TRUE);
1158           }
1159         elm_object_signal_emit(VIEW(prev_it), "elm,state,cur,pushed", "elm");
1160         elm_object_signal_emit(VIEW(it), "elm,state,new,pushed", "elm");
1161         edje_object_message_signal_process(elm_layout_edje_get(VIEW(prev_it)));
1162         edje_object_message_signal_process(elm_layout_edje_get(VIEW(it)));
1163      }
1164    wd->stack = eina_inlist_append(wd->stack, EINA_INLIST_GET(it));
1165    _sizing_eval(obj);
1166    return (Elm_Object_Item *) it;
1167 }
1168
1169 EAPI Elm_Object_Item *
1170 elm_naviframe_item_insert_before(Elm_Object_Item *before,
1171                                  const char *title_label,
1172                                  Evas_Object *prev_btn,
1173                                  Evas_Object *next_btn,
1174                                  Evas_Object *content,
1175                                  const char *item_style)
1176 {
1177    ELM_OBJ_ITEM_CHECK_OR_RETURN(before, NULL);
1178    Elm_Naviframe_Item *it;
1179    Widget_Data *wd;
1180
1181    wd = elm_widget_data_get(WIDGET(before));
1182    if (!wd) return NULL;
1183
1184    it = _item_new(WIDGET(before), title_label, prev_btn, next_btn, content,
1185                   item_style);
1186    if (!it) return NULL;
1187
1188    wd->stack =
1189       eina_inlist_prepend_relative(wd->stack, EINA_INLIST_GET(it),
1190                                    EINA_INLIST_GET(((Elm_Naviframe_Item *) before)));
1191    _sizing_eval(WIDGET(before));
1192    return (Elm_Object_Item *) it;
1193 }
1194
1195 EAPI Elm_Object_Item *
1196 elm_naviframe_item_insert_after(Elm_Object_Item *after,
1197                                 const char *title_label,
1198                                 Evas_Object *prev_btn,
1199                                 Evas_Object *next_btn,
1200                                 Evas_Object *content,
1201                                 const char *item_style)
1202 {
1203    ELM_OBJ_ITEM_CHECK_OR_RETURN(after, NULL);
1204    Elm_Naviframe_Item *it;
1205    Widget_Data *wd;
1206
1207    wd = elm_widget_data_get(WIDGET(after));
1208    if (!wd) return NULL;
1209
1210    it = _item_new(WIDGET(after), title_label, prev_btn, next_btn, content,
1211                   item_style);
1212    if (!it) return NULL;
1213
1214    if (elm_naviframe_top_item_get(WIDGET(after)) == after)
1215      {
1216         evas_object_hide(VIEW(after));
1217         evas_object_show(VIEW(it));
1218      }
1219    wd->stack =
1220       eina_inlist_append_relative(wd->stack, EINA_INLIST_GET(it),
1221                                   EINA_INLIST_GET(((Elm_Naviframe_Item *) after)));
1222    _sizing_eval(WIDGET(after));
1223    return (Elm_Object_Item *) it;
1224 }
1225
1226 EAPI Evas_Object *
1227 elm_naviframe_item_pop(Evas_Object *obj)
1228 {
1229    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1230    Elm_Naviframe_Item *it, *prev_it = NULL;
1231    Widget_Data *wd;
1232    Evas_Object *content = NULL;
1233
1234    wd = elm_widget_data_get(obj);
1235    if (!wd) return NULL;
1236
1237    it = (Elm_Naviframe_Item *) elm_naviframe_top_item_get(obj);
1238    if (!it) return NULL;
1239    elm_widget_tree_unfocusable_set(it->content, EINA_TRUE);
1240    if (wd->preserve)
1241      content = it->content;
1242
1243    if (wd->stack->last->prev)
1244      prev_it = EINA_INLIST_CONTAINER_GET(wd->stack->last->prev,
1245                                          Elm_Naviframe_Item);
1246    wd->stack = eina_inlist_remove(wd->stack, EINA_INLIST_GET(it));
1247    if (prev_it)
1248      {
1249         if (wd->freeze_events)
1250           {
1251              evas_object_freeze_events_set(VIEW(it), EINA_TRUE);
1252              evas_object_freeze_events_set(VIEW(prev_it), EINA_TRUE);
1253           }
1254         elm_object_signal_emit(VIEW(it), "elm,state,cur,popped", "elm");
1255         evas_object_show(VIEW(prev_it));
1256         evas_object_raise(VIEW(prev_it));
1257         elm_object_signal_emit(VIEW(prev_it),
1258                                "elm,state,prev,popped",
1259                                "elm");
1260         edje_object_message_signal_process(elm_layout_edje_get(VIEW(it)));
1261         edje_object_message_signal_process(elm_layout_edje_get(VIEW(prev_it)));
1262      }
1263    else
1264      {
1265         _item_del(it);
1266         elm_widget_item_free(it);
1267      }
1268
1269    return content;
1270 }
1271
1272 EAPI void
1273 elm_naviframe_item_pop_to(Elm_Object_Item *it)
1274 {
1275    ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1276    Elm_Naviframe_Item *navi_it;
1277    Widget_Data *wd;
1278    Eina_Inlist *l, *prev_l;
1279
1280    navi_it = (Elm_Naviframe_Item *) it;
1281    wd = elm_widget_data_get(WIDGET(navi_it));
1282    if (!wd) return;
1283
1284    if (it == elm_naviframe_top_item_get(WIDGET(navi_it))) return;
1285
1286    l = wd->stack->last->prev;
1287
1288    while(l)
1289      {
1290         if (EINA_INLIST_CONTAINER_GET(l, Elm_Naviframe_Item) ==
1291             ((Elm_Naviframe_Item *) it)) break;
1292         prev_l = l->prev;
1293         wd->stack = eina_inlist_remove(wd->stack, l);
1294         _item_del(EINA_INLIST_CONTAINER_GET(l, Elm_Naviframe_Item));
1295         elm_widget_item_free(EINA_INLIST_CONTAINER_GET(l,
1296                                                        Elm_Naviframe_Item));
1297         l = prev_l;
1298      }
1299    elm_naviframe_item_pop(WIDGET(navi_it));
1300 }
1301
1302 EAPI void
1303 elm_naviframe_item_promote(Elm_Object_Item *it)
1304 {
1305    ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1306    Elm_Naviframe_Item *navi_it;
1307    Elm_Naviframe_Item *prev_it;
1308    Widget_Data *wd;
1309
1310    navi_it = (Elm_Naviframe_Item *) it;
1311    wd = elm_widget_data_get(navi_it->base.widget);
1312    if (!wd) return;
1313
1314    if (it == elm_naviframe_top_item_get(navi_it->base.widget)) return;
1315    wd->stack = eina_inlist_demote(wd->stack, EINA_INLIST_GET(navi_it));
1316    prev_it = EINA_INLIST_CONTAINER_GET(wd->stack->last->prev,
1317                                          Elm_Naviframe_Item);
1318    if (wd->freeze_events)
1319      {
1320         evas_object_freeze_events_set(VIEW(it), EINA_TRUE);
1321         evas_object_freeze_events_set(VIEW(prev_it), EINA_TRUE);
1322      }
1323    elm_object_signal_emit(VIEW(prev_it),
1324                           "elm,state,cur,pushed",
1325                           "elm");
1326    evas_object_show(VIEW(navi_it));
1327    evas_object_raise(VIEW(navi_it));
1328    elm_object_signal_emit(VIEW(navi_it),
1329                           "elm,state,new,pushed",
1330                           "elm");
1331    edje_object_message_signal_process(elm_layout_edje_get(VIEW(prev_it)));
1332    edje_object_message_signal_process(elm_layout_edje_get(VIEW(navi_it)));
1333 }
1334
1335 EAPI void
1336 elm_naviframe_item_simple_promote(Evas_Object *obj, Evas_Object *content)
1337 {
1338    ELM_CHECK_WIDTYPE(obj, widtype);
1339    Widget_Data *wd = elm_widget_data_get(obj);
1340    if (!wd) return;
1341    Elm_Naviframe_Item *itr;
1342    EINA_INLIST_FOREACH(wd->stack, itr)
1343      {
1344         if (elm_object_item_content_get((Elm_Object_Item *) itr) == content)
1345           {
1346              elm_naviframe_item_promote((Elm_Object_Item *) itr);
1347              break;
1348           }
1349      }
1350 }
1351
1352
1353 EAPI void
1354 elm_naviframe_item_del(Elm_Object_Item *it)
1355 {
1356    elm_object_item_del(it);
1357 }
1358
1359 EAPI void
1360 elm_naviframe_content_preserve_on_pop_set(Evas_Object *obj, Eina_Bool preserve)
1361 {
1362    ELM_CHECK_WIDTYPE(obj, widtype);
1363    Widget_Data *wd = elm_widget_data_get(obj);
1364    if (!wd) return;
1365    wd->preserve = !!preserve;
1366 }
1367
1368 EAPI Eina_Bool
1369 elm_naviframe_content_preserve_on_pop_get(const Evas_Object *obj)
1370 {
1371    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
1372    Widget_Data *wd = elm_widget_data_get(obj);
1373    if (!wd) return EINA_FALSE;
1374    return wd->preserve;
1375 }
1376
1377 EAPI Elm_Object_Item*
1378 elm_naviframe_top_item_get(const Evas_Object *obj)
1379 {
1380    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1381    Widget_Data *wd = elm_widget_data_get(obj);
1382    if ((!wd) || (!wd->stack)) return NULL;
1383    return (Elm_Object_Item *) (EINA_INLIST_CONTAINER_GET(wd->stack->last,
1384                                                          Elm_Naviframe_Item));
1385 }
1386
1387 EAPI Elm_Object_Item*
1388 elm_naviframe_bottom_item_get(const Evas_Object *obj)
1389 {
1390    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1391    Widget_Data *wd = elm_widget_data_get(obj);
1392    if ((!wd) || (!wd->stack)) return NULL;
1393    return (Elm_Object_Item *) (EINA_INLIST_CONTAINER_GET(wd->stack,
1394                                                          Elm_Naviframe_Item));
1395 }
1396
1397 EAPI void
1398 elm_naviframe_item_style_set(Elm_Object_Item *it, const char *item_style)
1399 {
1400    ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1401    Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
1402
1403    //Return if new style is exsiting one.
1404    if ((item_style && navi_it->style) && (!strcmp(item_style, navi_it->style)))
1405       return;
1406
1407    if ((!item_style) && (!navi_it->style))
1408       return;
1409
1410    _item_style_set(navi_it, item_style);
1411 }
1412
1413 EAPI const char *
1414 elm_naviframe_item_style_get(const Elm_Object_Item *it)
1415 {
1416    ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
1417    Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
1418    return navi_it->style;
1419 }
1420
1421 EAPI void
1422 elm_naviframe_item_title_visible_set(Elm_Object_Item *it, Eina_Bool visible)
1423 {
1424    ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1425    Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
1426
1427    visible = !!visible;
1428    if (navi_it->title_visible == visible) return;
1429
1430    navi_it->title_visible = visible;
1431    _item_title_visible_update(navi_it);
1432 }
1433
1434 EAPI Eina_Bool
1435 elm_naviframe_item_title_visible_get(const Elm_Object_Item *it)
1436 {
1437    ELM_OBJ_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
1438    Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
1439    return navi_it->title_visible;
1440 }
1441
1442 EAPI void
1443 elm_naviframe_prev_btn_auto_pushed_set(Evas_Object *obj, Eina_Bool auto_pushed)
1444 {
1445    ELM_CHECK_WIDTYPE(obj, widtype);
1446    Widget_Data *wd = elm_widget_data_get(obj);
1447    if (!wd) return;
1448    wd->auto_pushed = !!auto_pushed;
1449 }
1450
1451 EAPI Eina_Bool
1452 elm_naviframe_prev_btn_auto_pushed_get(const Evas_Object *obj)
1453 {
1454    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
1455    Widget_Data *wd = elm_widget_data_get(obj);
1456    if (!wd) return EINA_FALSE;
1457    return wd->auto_pushed;
1458 }
1459
1460 EAPI Eina_List *
1461 elm_naviframe_items_get(const Evas_Object *obj)
1462 {
1463    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1464    Widget_Data *wd = elm_widget_data_get(obj);
1465    if (!wd) return NULL;
1466    Eina_List *ret = NULL;
1467    Elm_Naviframe_Item *itr;
1468    EINA_INLIST_FOREACH(wd->stack, itr)
1469      {
1470         ret = eina_list_append(ret, itr);
1471      }
1472    return ret;
1473 }
1474
1475 EAPI void
1476 elm_naviframe_event_enabled_set(Evas_Object *obj, Eina_Bool enabled)
1477 {
1478    ELM_CHECK_WIDTYPE(obj, widtype);
1479    Widget_Data *wd = elm_widget_data_get(obj);
1480    if (!wd) return;
1481    enabled = !!enabled;
1482    if (wd->freeze_events == !enabled) return;
1483    wd->freeze_events = !enabled;
1484 }
1485
1486 EAPI Eina_Bool
1487 elm_naviframe_event_enabled_get(const Evas_Object *obj)
1488 {
1489    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
1490    Widget_Data *wd = elm_widget_data_get(obj);
1491    if (!wd) return EINA_FALSE;
1492    return !wd->freeze_events;
1493 }
1494
1495 EAPI void
1496 elm_naviframe_item_style_default_set(Evas_Object *obj, const char *style)
1497 {
1498    ELM_CHECK_WIDTYPE(obj, widtype);
1499    Widget_Data *wd = elm_widget_data_get(obj);
1500    if (!wd) return;
1501    eina_stringshare_replace(&wd->item_style, style);
1502    _theme_hook(obj);
1503 }
1504
1505 EAPI const char *
1506 elm_naviframe_item_style_default_get(const Evas_Object *obj)
1507 {
1508    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1509    Widget_Data *wd = elm_widget_data_get(obj);
1510    if (!wd) return NULL;
1511    return wd->item_style;
1512 }