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