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