elementary/naviframe - refactored title_content_set
[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 (part)
566      {
567         if (pair->content && (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         elm_widget_sub_object_add(WIDGET(it), content);
598         evas_object_event_callback_add(content,
599                                        EVAS_CALLBACK_DEL,
600                                        _title_content_del,
601                                        pair);
602         evas_object_event_callback_add(content,
603                                        EVAS_CALLBACK_CHANGED_SIZE_HINTS,
604                                        _changed_size_hints,
605                                        WIDGET(it));
606      }
607      edje_object_part_swallow(VIEW(it), part, content);
608      snprintf(buf, sizeof(buf), "elm,state,%s,show", part);
609      edje_object_signal_emit(VIEW(it), buf, "elm");
610      pair->content = content;
611
612    _sizing_eval(WIDGET(it));
613 }
614
615 static void
616 _title_prev_btn_set(Elm_Naviframe_Item *it,
617                     Evas_Object *btn,
618                     Eina_Bool back_btn)
619 {
620    if (it->title_prev_btn == btn) return;
621
622    if (it->title_prev_btn)
623      evas_object_del(it->title_prev_btn);
624
625    it->title_prev_btn = btn;
626    if (!btn) return;
627
628    elm_widget_sub_object_add(WIDGET(it), btn);
629    evas_object_event_callback_add(btn,
630                                   EVAS_CALLBACK_DEL,
631                                   _title_prev_btn_del,
632                                   it);
633    evas_object_event_callback_add(btn,
634                                   EVAS_CALLBACK_CHANGED_SIZE_HINTS,
635                                   _changed_size_hints,
636                                   WIDGET(it));
637    edje_object_part_swallow(VIEW(it), "elm.swallow.prev_btn", btn);
638    edje_object_signal_emit(VIEW(it), "elm,state,prev_btn,show", "elm");
639    it->back_btn = back_btn;
640
641    _sizing_eval(WIDGET(it));
642 }
643
644 static void
645 _title_next_btn_set(Elm_Naviframe_Item *it, Evas_Object *btn)
646 {
647    if (it->title_next_btn == btn) return;
648
649    if (it->title_next_btn)
650      evas_object_del(it->title_next_btn);
651
652    it->title_next_btn = btn;
653    if (!btn) return;
654
655    elm_widget_sub_object_add(WIDGET(it), btn);
656    evas_object_event_callback_add(btn,
657                                   EVAS_CALLBACK_DEL,
658                                   _title_next_btn_del,
659                                   it);
660    evas_object_event_callback_add(btn,
661                                   EVAS_CALLBACK_CHANGED_SIZE_HINTS,
662                                   _changed_size_hints,
663                                   WIDGET(it));
664    edje_object_part_swallow(VIEW(it), "elm.swallow.next_btn", btn);
665    edje_object_signal_emit(VIEW(it), "elm,state,next_btn,show", "elm");
666
667    _sizing_eval(WIDGET(it));
668 }
669
670 static void
671 _title_icon_set(Elm_Naviframe_Item *it, Evas_Object *icon)
672 {
673    if (it->title_icon == icon) return;
674
675    if (it->title_icon)
676      evas_object_del(it->title_icon);
677
678    it->title_icon = icon;
679    if (!icon) return;
680
681    elm_widget_sub_object_add(WIDGET(it), icon);
682    evas_object_event_callback_add(icon,
683                                   EVAS_CALLBACK_DEL,
684                                   _title_icon_del,
685                                   it);
686    evas_object_event_callback_add(icon,
687                                   EVAS_CALLBACK_CHANGED_SIZE_HINTS,
688                                   _changed_size_hints,
689                                   WIDGET(it));
690    edje_object_part_swallow(VIEW(it), "elm.swallow.icon", icon);
691    edje_object_signal_emit(VIEW(it), "elm,state,icon,show", "elm");
692
693    _sizing_eval(WIDGET(it));
694 }
695
696 static Evas_Object *
697 _item_content_unset(Elm_Naviframe_Item *it)
698 {
699    Evas_Object *content = it->content;
700    if (!content) return NULL;
701
702    elm_widget_sub_object_del(WIDGET(it), content);
703    edje_object_part_unswallow(VIEW(it), content);
704    edje_object_signal_emit(VIEW(it), "elm,state,content,hide", "elm");
705    evas_object_event_callback_del(content,
706                                   EVAS_CALLBACK_DEL,
707                                   _item_content_del);
708    evas_object_event_callback_del(content,
709                                   EVAS_CALLBACK_CHANGED_SIZE_HINTS,
710                                   _changed_size_hints);
711    _sizing_eval(WIDGET(it));
712
713    it->content = NULL;
714    return content;
715 }
716
717 static Evas_Object *
718 _title_prev_btn_unset(Elm_Naviframe_Item *it)
719 {
720    Evas_Object *content = it->title_prev_btn;
721    if (!content) return NULL;
722
723    elm_widget_sub_object_del(WIDGET(it), content);
724    edje_object_part_unswallow(VIEW(it), content);
725    edje_object_signal_emit(VIEW(it), "elm,state,prev_btn,hide", "elm");
726    evas_object_event_callback_del(content,
727                                   EVAS_CALLBACK_DEL,
728                                   _title_prev_btn_del);
729    evas_object_event_callback_del(content,
730                                   EVAS_CALLBACK_CHANGED_SIZE_HINTS,
731                                   _changed_size_hints);
732    _sizing_eval(WIDGET(it));
733
734    it->title_prev_btn = NULL;
735    return content;
736 }
737
738 static Evas_Object *
739 _title_next_btn_unset(Elm_Naviframe_Item *it)
740 {
741    Evas_Object *content = it->title_next_btn;
742    if (!content) return NULL;
743
744    elm_widget_sub_object_del(WIDGET(it), content);
745    edje_object_part_unswallow(VIEW(it), content);
746    edje_object_signal_emit(VIEW(it), "elm,state,next_btn,hide", "elm");
747    evas_object_event_callback_del(content,
748                                   EVAS_CALLBACK_DEL,
749                                   _title_next_btn_del);
750    evas_object_event_callback_del(content,
751                                   EVAS_CALLBACK_CHANGED_SIZE_HINTS,
752                                   _changed_size_hints);
753    _sizing_eval(WIDGET(it));
754
755    it->title_next_btn = NULL;
756    return content;
757 }
758
759 static Evas_Object *
760 _title_icon_unset(Elm_Naviframe_Item *it)
761 {
762    Evas_Object *content = it->title_icon;
763    if (!content) return NULL;
764
765    elm_widget_sub_object_del(WIDGET(it), content);
766    edje_object_part_unswallow(VIEW(it), content);
767    edje_object_signal_emit(VIEW(it), "elm,state,icon,hide", "elm");
768    evas_object_event_callback_del(content,
769                                   EVAS_CALLBACK_DEL,
770                                   _title_icon_del);
771    evas_object_event_callback_del(content,
772                                   EVAS_CALLBACK_CHANGED_SIZE_HINTS,
773                                   _changed_size_hints);
774    _sizing_eval(WIDGET(it));
775    it->title_icon = NULL;
776
777    return content;
778 }
779
780 static Evas_Object *
781 _title_content_unset(Elm_Naviframe_Item *it, const char *part)
782 {
783    Elm_Naviframe_Content_Item_Pair *pair = NULL;
784    char buf[1028];
785    Evas_Object *content = NULL;
786
787    EINA_INLIST_FOREACH(it->content_list, pair)
788      {
789         if (!strcmp(part, pair->part))
790           {
791              content = pair->content;
792              eina_stringshare_del(pair->part);
793              it->content_list = eina_inlist_remove(it->content_list,
794                                                    EINA_INLIST_GET(pair));
795              free(pair);
796              break;
797           }
798      }
799
800    if (!content) return NULL;
801
802    elm_widget_sub_object_del(WIDGET(it), content);
803    edje_object_part_unswallow(VIEW(it), content);
804    snprintf(buf, sizeof(buf), "elm,state,%s,hide", part);
805    edje_object_signal_emit(VIEW(it), buf, "elm");
806    evas_object_event_callback_del(content,
807                                   EVAS_CALLBACK_DEL,
808                                   _title_content_del);
809    evas_object_event_callback_del(content,
810                                   EVAS_CALLBACK_CHANGED_SIZE_HINTS,
811                                   _changed_size_hints);
812    _sizing_eval(WIDGET(it));
813
814    return content;
815 }
816
817
818 static void
819 _item_del(Elm_Naviframe_Item *it)
820 {
821    Widget_Data *wd;
822    Elm_Naviframe_Content_Item_Pair *content_pair;
823    Elm_Naviframe_Text_Item_Pair *text_pair;
824
825    if (!it) return;
826
827    wd = elm_widget_data_get(WIDGET(it));
828    if (!wd) return;
829
830    if (it->title_prev_btn)
831      evas_object_del(it->title_prev_btn);
832    if (it->title_next_btn)
833      evas_object_del(it->title_next_btn);
834    if (it->title_icon)
835      evas_object_del(it->title_icon);
836    if ((it->content) && (!wd->preserve))
837      evas_object_del(it->content);
838
839    while (it->content_list)
840      {
841         content_pair = EINA_INLIST_CONTAINER_GET(it->content_list,
842                                                  Elm_Naviframe_Content_Item_Pair);
843         evas_object_event_callback_del(content_pair->content,
844                                        EVAS_CALLBACK_DEL,
845                                        _title_content_del);
846         evas_object_event_callback_del(content_pair->content,
847                                        EVAS_CALLBACK_CHANGED_SIZE_HINTS,
848                                        _changed_size_hints);
849         evas_object_del(content_pair->content);
850         eina_stringshare_del(content_pair->part);
851         it->content_list = eina_inlist_remove(it->content_list,
852                                               it->content_list);
853         free(content_pair);
854      }
855
856    while (it->text_list)
857      {
858         text_pair = EINA_INLIST_CONTAINER_GET(it->text_list,
859                                               Elm_Naviframe_Text_Item_Pair);
860         eina_stringshare_del(text_pair->part);
861         eina_stringshare_del(text_pair->text);
862         it->text_list = eina_inlist_remove(it->text_list,
863                                            it->text_list);
864         free(text_pair);
865      }
866
867    eina_stringshare_del(it->style);
868
869    elm_widget_item_del(it);
870 }
871
872 static void
873 _pushed_finished(void *data,
874                  Evas_Object *obj __UNUSED__,
875                  const char *emission __UNUSED__,
876                  const char *source __UNUSED__)
877 {
878    Widget_Data *wd;
879    Elm_Naviframe_Item *it = data;
880    if (!it) return;
881
882    wd = elm_widget_data_get(WIDGET(it));
883    if (!wd) return;
884
885    evas_object_hide(VIEW(it));
886    evas_object_smart_callback_call(WIDGET(it),
887                                    SIG_PUSH_FINISHED,
888                                    data);
889    if (wd->freeze_events)
890      evas_object_freeze_events_set(VIEW(it), EINA_FALSE);
891 }
892
893 static void
894 _popped_finished(void *data,
895                  Evas_Object *obj __UNUSED__,
896                  const char *emission __UNUSED__,
897                  const char *source __UNUSED__)
898 {
899    Elm_Naviframe_Item *it = data;
900    if (!it) return;
901    evas_object_smart_callback_call(WIDGET(it),
902                                    SIG_POP_FINISHED,
903                                    data);
904    _item_del(data);
905 }
906
907 static void
908 _show_finished(void *data,
909                Evas_Object *obj __UNUSED__,
910                const char *emission __UNUSED__,
911                const char *source __UNUSED__)
912 {
913    Elm_Naviframe_Item *it;
914    Widget_Data *wd;
915
916    it = data;
917    if (!it) return;
918    wd =  elm_widget_data_get(WIDGET(it));
919    if (!wd) return;
920
921    evas_object_smart_callback_call(WIDGET(it),
922                                    SIG_TRANSITION_FINISHED,
923                                    data);
924    if (wd->freeze_events)
925      evas_object_freeze_events_set(VIEW(it), EINA_FALSE);
926 }
927
928 static void
929 _changed_size_hints(void *data,
930                     Evas *e __UNUSED__,
931                     Evas_Object *obj __UNUSED__,
932                     void *event_info __UNUSED__)
933 {
934    _sizing_eval(data);
935 }
936
937 static void
938 _item_content_set(Elm_Naviframe_Item *navi_it, Evas_Object *content)
939 {
940    if (navi_it->content == content) return;
941    if (navi_it->content) evas_object_del(navi_it->content);
942    elm_widget_sub_object_add(WIDGET(navi_it), content);
943    edje_object_part_swallow(VIEW(navi_it),
944                             "elm.swallow.content",
945                             content);
946    if (content)
947      edje_object_signal_emit(VIEW(navi_it),
948                              "elm,state,content,show",
949                              "elm");
950    else
951      edje_object_signal_emit(VIEW(navi_it),
952                              "elm,state,content,hide",
953                              "elm");
954    evas_object_event_callback_add(content,
955                                   EVAS_CALLBACK_DEL,
956                                   _item_content_del,
957                                   navi_it);
958    evas_object_event_callback_add(content,
959                                   EVAS_CALLBACK_CHANGED_SIZE_HINTS,
960                                   _changed_size_hints,
961                                   WIDGET(navi_it));
962    navi_it->content = content;
963    _sizing_eval(WIDGET(navi_it));
964 }
965
966 //FIXME: need to handle if this function is called while transition
967 static void
968 _item_style_set(Elm_Naviframe_Item *navi_it, const char *item_style)
969 {
970    Elm_Naviframe_Content_Item_Pair *content_pair;
971    Elm_Naviframe_Text_Item_Pair *text_pair;
972    Widget_Data *wd;
973
974    char buf[256];
975
976    if (!item_style)
977      {
978         sprintf(buf, "item/basic");
979         eina_stringshare_replace(&navi_it->style, "basic");
980      }
981    else
982      {
983         if (strlen(item_style) > sizeof(buf))
984           WRN("too much long style name! : naviframe=%p", WIDGET(navi_it));
985         sprintf(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         navi_it = EINA_INLIST_CONTAINER_GET(wd->stack->last,
1363                                             Elm_Naviframe_Item);
1364         evas_object_show(VIEW(navi_it));
1365         evas_object_raise(VIEW(navi_it));
1366         edje_object_signal_emit(VIEW(navi_it), "elm,state,visible", "elm");
1367      }
1368    else
1369      {
1370         wd->stack = eina_inlist_remove(wd->stack, EINA_INLIST_GET(navi_it));
1371         _item_del(navi_it);
1372      }
1373 }
1374
1375 EAPI void
1376 elm_naviframe_content_preserve_on_pop_set(Evas_Object *obj, Eina_Bool preserve)
1377 {
1378    ELM_CHECK_WIDTYPE(obj, widtype);
1379    Widget_Data *wd = elm_widget_data_get(obj);
1380    if (!wd) return;
1381    wd->preserve = !!preserve;
1382 }
1383
1384 EAPI Eina_Bool
1385 elm_naviframe_content_preserve_on_pop_get(const Evas_Object *obj)
1386 {
1387    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
1388    Widget_Data *wd = elm_widget_data_get(obj);
1389    if (!wd) return EINA_FALSE;
1390    return wd->preserve;
1391 }
1392
1393 EAPI Elm_Object_Item*
1394 elm_naviframe_top_item_get(const Evas_Object *obj)
1395 {
1396    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1397    Widget_Data *wd = elm_widget_data_get(obj);
1398    if ((!wd) || (!wd->stack)) return NULL;
1399    return (Elm_Object_Item *) (EINA_INLIST_CONTAINER_GET(wd->stack->last,
1400                                                          Elm_Naviframe_Item));
1401 }
1402
1403 EAPI Elm_Object_Item*
1404 elm_naviframe_bottom_item_get(const Evas_Object *obj)
1405 {
1406    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1407    Widget_Data *wd = elm_widget_data_get(obj);
1408    if ((!wd) || (!wd->stack)) return NULL;
1409    return (Elm_Object_Item *) (EINA_INLIST_CONTAINER_GET(wd->stack,
1410                                                          Elm_Naviframe_Item));
1411 }
1412
1413 EAPI void
1414 elm_naviframe_item_style_set(Elm_Object_Item *it, const char *item_style)
1415 {
1416    ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1417    Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
1418
1419    //Return if new style is exsiting one.
1420    if (item_style)
1421      if (!strcmp(item_style, navi_it->style)) return;
1422
1423    if (!item_style)
1424      if (!strcmp("basic", navi_it->style)) return;
1425
1426    _item_style_set(navi_it, item_style);
1427 }
1428
1429 EAPI const char *
1430 elm_naviframe_item_style_get(const Elm_Object_Item *it)
1431 {
1432    ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
1433    Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
1434    return navi_it->style;
1435 }
1436
1437 EAPI void
1438 elm_naviframe_item_title_visible_set(Elm_Object_Item *it, Eina_Bool visible)
1439 {
1440    ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1441    Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
1442
1443    visible = !!visible;
1444    if (navi_it->title_visible == visible) return;
1445
1446    navi_it->title_visible = visible;
1447    _item_title_visible_update(navi_it);
1448 }
1449
1450 EAPI Eina_Bool
1451 elm_naviframe_item_title_visible_get(const Elm_Object_Item *it)
1452 {
1453    ELM_OBJ_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
1454    Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
1455    return navi_it->title_visible;
1456 }
1457
1458 EAPI void
1459 elm_naviframe_prev_btn_auto_pushed_set(Evas_Object *obj, Eina_Bool auto_pushed)
1460 {
1461    ELM_CHECK_WIDTYPE(obj, widtype);
1462    Widget_Data *wd = elm_widget_data_get(obj);
1463    if (!wd) return;
1464    wd->auto_pushed = !!auto_pushed;
1465 }
1466
1467 EAPI Eina_Bool
1468 elm_naviframe_prev_btn_auto_pushed_get(const Evas_Object *obj)
1469 {
1470    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
1471    Widget_Data *wd = elm_widget_data_get(obj);
1472    if (!wd) return EINA_FALSE;
1473    return wd->auto_pushed;
1474 }
1475
1476 EAPI Eina_Inlist *
1477 elm_naviframe_items_get(const Evas_Object *obj)
1478 {
1479    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1480    Widget_Data *wd = elm_widget_data_get(obj);
1481    if (!wd) return NULL;
1482    return wd->stack;
1483 }
1484
1485 EAPI void
1486 elm_naviframe_event_enabled_set(Evas_Object *obj, Eina_Bool enabled)
1487 {
1488    ELM_CHECK_WIDTYPE(obj, widtype);
1489    Widget_Data *wd = elm_widget_data_get(obj);
1490    if (!wd) return;
1491    enabled = !!enabled;
1492    if (wd->freeze_events == !enabled) return;
1493    wd->freeze_events = !enabled;
1494 }
1495
1496 EAPI Eina_Bool
1497 elm_naviframe_event_enabled_get(const Evas_Object *obj)
1498 {
1499    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
1500    Widget_Data *wd = elm_widget_data_get(obj);
1501    if (!wd) return EINA_FALSE;
1502    return !wd->freeze_events;
1503 }