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