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