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