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