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