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