elemenatry/navifrmae - killed 2 more apis.
[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 //widget item signals
55 static const char SIG_ITEM_SHOW_BEGIN[] = "show,begin";
56 static const char SIG_ITEM_HIDE_FINISHED[] = "hide,finished";
57
58 static const Evas_Smart_Cb_Description _signals[] = {
59        {SIG_TRANSITION_FINISHED, ""},
60        {SIG_TITLE_CLICKED, ""},
61        {SIG_ITEM_SHOW_BEGIN, ""},
62        {SIG_ITEM_HIDE_FINISHED, ""},
63        {NULL, NULL}
64 };
65
66 static void _text_set_hook(Evas_Object *obj,
67                            const char *part,
68                            const char *label);
69 static const char *_text_get_hook(const Evas_Object *obj, const char *part);
70 static void _content_set_hook(Evas_Object *obj,
71                               const char *part,
72                               Evas_Object *content);
73 static Evas_Object *_content_get_hook(const Evas_Object *obj, const char *part);
74 static Evas_Object *_content_unset_hook(Evas_Object *obj, const char *part);
75 static void _del_hook(Evas_Object *obj);
76 static void _theme_hook(Evas_Object *obj);
77 static void _emit_hook(Evas_Object *obj,
78                        const char *emission,
79                        const char *source);
80 static void _disable_hook(Evas_Object *obj);
81 static void _item_text_set_hook(Elm_Object_Item *it,
82                                 const char *part,
83                                 const char *label);
84 static const char *_item_text_get_hook(const Elm_Object_Item *it,
85                                        const char *part);
86 static void _item_content_set_hook(Elm_Object_Item *it,
87                                    const char *part,
88                                    Evas_Object *content);
89 static Evas_Object *_item_content_get_hook(const Elm_Object_Item *it,
90                                            const char *part);
91 static Evas_Object *_item_content_unset_hook(Elm_Object_Item *it,
92                                              const char *part);
93 static void _item_signal_emit_hook(Elm_Object_Item *it,
94                                    const char *emission,
95                                    const char *source);
96 static void _item_title_visible_update(Elm_Naviframe_Item *navi_it);
97 static void _sizing_eval(Evas_Object *obj);
98 static void _move(void *data, Evas *e, Evas_Object *obj, void *event_info);
99 static void _resize(void *data,
100                     Evas *e,
101                     Evas_Object *obj,
102                     void *event_info);
103 static void _title_clicked(void *data, Evas_Object *obj,
104                            const char *emission,
105                            const char *source);
106 static void _back_btn_clicked(void *data,
107                               Evas_Object *obj,
108                               void *event_info);
109 static Evas_Object *_back_btn_new(Evas_Object *obj);
110 static void _item_content_del(void *data,
111                               Evas *e,
112                               Evas_Object *obj,
113                               void *event_info);
114 static void _title_content_del(void *data,
115                                Evas *e,
116                                Evas_Object *obj,
117                                void *event_info);
118 static void _title_prev_btn_del(void *data,
119                                 Evas *e,
120                                 Evas_Object *obj,
121                                 void *event_info);
122 static void _title_next_btn_del(void *data,
123                                 Evas *e,
124                                 Evas_Object *obj,
125                                 void *event_info);
126 static void _title_icon_del(void *data,
127                             Evas *e,
128                             Evas_Object *obj,
129                             void *event_info);
130 static void _title_content_set(Elm_Naviframe_Item *it,
131                                const char *part,
132                                Evas_Object *content);
133 static void _title_prev_btn_set(Elm_Naviframe_Item *it,
134                                 Evas_Object *btn,
135                                 Eina_Bool back_btn);
136 static void _title_next_btn_set(Elm_Naviframe_Item *it, Evas_Object *btn);
137 static void _title_icon_set(Elm_Naviframe_Item *it, Evas_Object *icon);
138 static Evas_Object * _item_content_unset(Elm_Naviframe_Item *it);
139 static Evas_Object * _title_prev_btn_unset(Elm_Naviframe_Item *it);
140 static Evas_Object * _title_next_btn_unset(Elm_Naviframe_Item *it);
141 static Evas_Object * _title_icon_unset(Elm_Naviframe_Item *it);
142 static Evas_Object * _title_content_unset(Elm_Naviframe_Item *it,
143                                           const char *part);
144 static void _item_del(Elm_Naviframe_Item *it);
145 static Eina_Bool _item_del_pre_hook(Elm_Object_Item *it);
146 static void _pushed_finished(void *data,
147                              Evas_Object *obj,
148                              const char *emission,
149                              const char *source);
150 static void _popped_finished(void *data,
151                              Evas_Object *obj,
152                              const char *emission,
153                              const char *source);
154 static void _show_finished(void *data,
155                            Evas_Object *obj,
156                            const char *emission,
157                            const char *source);
158 static void _changed_size_hints(void *data,
159                                 Evas *e,
160                                 Evas_Object *obj,
161                                 void *event_info);
162 static void _item_content_set(Elm_Naviframe_Item *navi_it,
163                               Evas_Object *content);
164 static void _item_style_set(Elm_Naviframe_Item *navi_it,
165                             const char *item_style);
166 static Elm_Naviframe_Item * _item_new(Evas_Object *obj,
167                                       const char *title_label,
168                                       Evas_Object *prev_btn,
169                                       Evas_Object *next_btn,
170                                       Evas_Object *content,
171                                       const char *item_style);
172 static Eina_Bool _focus_next_hook(const Evas_Object *obj,
173                                   Elm_Focus_Direction dir,
174                                   Evas_Object **next);
175
176 static void
177 _del_hook(Evas_Object *obj)
178 {
179    Widget_Data *wd;
180    Elm_Naviframe_Item *it;
181
182    wd = elm_widget_data_get(obj);
183    if (!wd) return;
184
185    if (wd->stack)
186      {
187         while (wd->stack->last)
188           {
189              it = EINA_INLIST_CONTAINER_GET(wd->stack->last,
190                                             Elm_Naviframe_Item);
191              wd->stack = eina_inlist_remove(wd->stack, wd->stack->last);
192              _item_del(it);
193              elm_widget_item_free(it);
194              if (!wd->stack) break;
195           }
196      }
197    free(wd);
198 }
199
200 static void
201 _theme_hook(Evas_Object *obj)
202 {
203    Widget_Data *wd;
204    Elm_Naviframe_Item *it;
205
206    wd  = elm_widget_data_get(obj);
207    if (!wd) return;
208
209    _elm_theme_object_set(obj,
210                          wd->base,
211                          "naviframe",
212                          "base",
213                          elm_widget_style_get(obj));
214
215    EINA_INLIST_FOREACH(wd->stack, it)
216      {
217         _item_style_set(it, it->style);
218         _item_title_visible_update(it);
219      }
220 }
221
222 static void _emit_hook(Evas_Object *obj,
223                        const char *emission,
224                        const char *source)
225 {
226    Elm_Object_Item *it = elm_naviframe_top_item_get(obj);
227    if (!it) return;
228    return elm_object_item_signal_emit(it, emission, source);
229 }
230
231 static void
232 _disable_hook(Evas_Object *obj __UNUSED__)
233 {
234    //FIXME:
235 }
236
237 static void
238 _item_text_set_hook(Elm_Object_Item *it,
239                     const char *part,
240                     const char *label)
241 {
242    Elm_Naviframe_Text_Item_Pair *pair = NULL;
243    Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *)it;
244    char buf[1024];
245
246    if (!part || !strcmp(part, "default"))
247      snprintf(buf, sizeof(buf), "elm.text.title");
248    else if(!strcmp("subtitle", part))
249      snprintf(buf, sizeof(buf), "elm.text.subtitle");
250    else
251      snprintf(buf, sizeof(buf), "%s", part);
252
253    EINA_INLIST_FOREACH(navi_it->text_list, pair)
254      if (!strcmp(buf, pair->part)) break;
255
256    if (!pair)
257      {
258         pair = ELM_NEW(Elm_Naviframe_Text_Item_Pair);
259         if (!pair)
260           {
261              ERR("Failed to allocate new text part of the item! : naviframe=%p",
262              WIDGET(navi_it));
263              return;
264           }
265         eina_stringshare_replace(&pair->part, buf);
266         navi_it->text_list = eina_inlist_append(navi_it->text_list,
267                                                 EINA_INLIST_GET(pair));
268      }
269    elm_object_part_text_set(VIEW(navi_it), buf, label);
270
271    if (label)
272      {
273         snprintf(buf, sizeof(buf), "elm,state,%s,show", buf);
274         elm_object_signal_emit(VIEW(navi_it), buf, "elm");
275      }
276    else
277      {
278         snprintf(buf, sizeof(buf), "elm,state,%s,hide", buf);
279         elm_object_signal_emit(VIEW(navi_it), buf, "elm");
280      }
281
282    _sizing_eval(WIDGET(navi_it));
283 }
284
285 static const char *
286 _item_text_get_hook(const Elm_Object_Item *it, const char *part)
287 {
288    char buf[1024];
289
290    if (!part || !strcmp(part, "default"))
291      snprintf(buf, sizeof(buf), "elm.text.title");
292    else if(!strcmp("subtitle", part))
293      snprintf(buf, sizeof(buf), "elm.text.subtitle");
294    else
295      snprintf(buf, sizeof(buf), "%s", part);
296
297    return elm_object_part_text_get(VIEW(it), buf);
298 }
299
300 static void
301 _item_content_set_hook(Elm_Object_Item *it,
302                        const char *part,
303                        Evas_Object *content)
304 {
305    Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *)it;
306
307    //specified parts
308    if (!part || !strcmp("default", part))
309      {
310         _item_content_set(navi_it, content);
311         return;
312      }
313    else if (!strcmp(part, "prev_btn"))
314      {
315         _title_prev_btn_set(navi_it, content, EINA_FALSE);
316         return;
317      }
318    else if (!strcmp(part, "next_btn"))
319      {
320         _title_next_btn_set(navi_it, content);
321         return;
322      }
323    else if (!strcmp(part, "icon"))
324      {
325         _title_icon_set(navi_it, content);
326         return;
327      }
328
329    //common part
330    _title_content_set(navi_it, part, content);
331 }
332
333 static Evas_Object *
334 _item_content_get_hook(const Elm_Object_Item *it, const char *part)
335 {
336    Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *)it;
337
338    //specified parts
339    if (!part || !strcmp("default", part))
340      return navi_it->content;
341    else if (!strcmp(part, "prev_btn"))
342      return navi_it->title_prev_btn;
343    else if (!strcmp(part, "next_btn"))
344      return navi_it->title_next_btn;
345    else if (!strcmp(part, "icon"))
346      return navi_it->title_icon;
347
348    //common parts
349    return elm_object_part_content_get(VIEW(navi_it), part);
350 }
351
352 static Evas_Object *
353 _item_content_unset_hook(Elm_Object_Item *it, const char *part)
354 {
355    Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *)it;
356
357    //specified parts
358    if (!part || !strcmp("default", part))
359      return _item_content_unset(navi_it);
360    else if (!strcmp(part, "prev_btn"))
361      return _title_prev_btn_unset(navi_it);
362    else if (!strcmp(part, "next_btn"))
363      return _title_next_btn_unset(navi_it);
364    else if (!strcmp(part, "icon"))
365      return _title_icon_unset(navi_it);
366
367    return _title_content_unset(navi_it, part);
368 }
369
370 static void
371 _item_signal_emit_hook(Elm_Object_Item *it,
372                        const char *emission,
373                        const char *source)
374 {
375    elm_object_signal_emit(VIEW(it), emission, source);
376 }
377
378 static void
379 _item_title_visible_update(Elm_Naviframe_Item *navi_it)
380 {
381    if (navi_it->title_visible)
382      elm_object_signal_emit(VIEW(navi_it), "elm,state,title,show", "elm");
383    else
384      elm_object_signal_emit(VIEW(navi_it), "elm,state,title,hide", "elm");
385 }
386
387 static void
388 _sizing_eval(Evas_Object *obj)
389 {
390    Widget_Data *wd;
391    Elm_Naviframe_Item *it;
392    Evas_Coord x, y, w, h;
393    Evas_Coord minw = -1, minh = -1;
394
395    wd = elm_widget_data_get(obj);
396    if (!wd) return;
397
398    evas_object_geometry_get(obj, &x, &y, &w, &h);
399
400    EINA_INLIST_FOREACH(wd->stack, it)
401      {
402         evas_object_move(VIEW(it), x, y);
403         evas_object_resize(VIEW(it), w, h);
404         edje_object_size_min_calc(elm_layout_edje_get(VIEW(it)),
405                                   &it->minw,
406                                   &it->minh);
407         if (it->minw > minw) minw = it->minw;
408         if (it->minh > minh) minh = it->minh;
409      }
410    evas_object_size_hint_min_set(obj, minw, minh);
411    evas_object_size_hint_max_set(obj, -1, -1);
412 }
413
414 static void
415 _move(void *data __UNUSED__,
416       Evas *e __UNUSED__,
417       Evas_Object *obj,
418       void *event_info __UNUSED__)
419 {
420    _sizing_eval(obj);
421 }
422
423 static void
424 _resize(void *data __UNUSED__,
425         Evas *e __UNUSED__,
426         Evas_Object *obj,
427         void *event_info __UNUSED__)
428 {
429    _sizing_eval(obj);
430 }
431
432 static void
433 _title_clicked(void *data,
434                Evas_Object *obj __UNUSED__,
435                const char *emission __UNUSED__,
436                const char *source __UNUSED__)
437 {
438    Elm_Naviframe_Item *it = data;
439    evas_object_smart_callback_call(WIDGET(it), SIG_TITLE_CLICKED, it);
440 }
441
442 static void
443 _back_btn_clicked(void *data,
444                   Evas_Object *obj,
445                   void *event_info __UNUSED__)
446 {
447 /* Since edje has the event queue, clicked event could be happend multiple times
448    on some heavy environment. This callback del will prevent those  scenario and
449    guarantee only one clicked for it's own page. */
450    evas_object_smart_callback_del(obj, "clicked", _back_btn_clicked);
451    elm_naviframe_item_pop(data);
452 }
453
454 static Evas_Object *
455 _back_btn_new(Evas_Object *obj)
456 {
457    Evas_Object *btn;
458    char buf[1024];
459    btn = elm_button_add(obj);
460    if (!btn) return NULL;
461    evas_object_smart_callback_add(btn, "clicked", _back_btn_clicked, obj);
462    snprintf(buf, sizeof(buf), "naviframe/back_btn/%s",
463             elm_widget_style_get(obj));
464    elm_object_style_set(btn, buf);
465    return btn;
466 }
467
468 static void _text_set_hook(Evas_Object *obj,
469                            const char *part,
470                            const char *label)
471 {
472    Elm_Object_Item *it = elm_naviframe_top_item_get(obj);
473    if (!it) return;
474    elm_object_item_part_text_set(it, part, label);
475 }
476
477 static const char *_text_get_hook(const Evas_Object *obj, const char *part)
478 {
479    Elm_Object_Item *it = elm_naviframe_top_item_get(obj);
480    if (!it) return NULL;
481    return elm_object_item_part_text_get(it, part);
482 }
483
484 static void
485 _content_set_hook(Evas_Object *obj, const char *part, Evas_Object *content)
486 {
487    Elm_Object_Item *it = elm_naviframe_top_item_get(obj);
488    if (!it) return;
489    elm_object_item_part_content_set(it, part, content);
490 }
491
492 static Evas_Object *
493 _content_unset_hook(Evas_Object *obj, const char *part)
494 {
495    Elm_Object_Item *it = elm_naviframe_top_item_get(obj);
496    if (!it) return NULL;
497    return elm_object_item_part_content_unset(it, part);
498 }
499
500 static Evas_Object *
501 _content_get_hook(const Evas_Object *obj, const char *part)
502 {
503    Elm_Object_Item *it = elm_naviframe_top_item_get(obj);
504    if (!it) return NULL;
505    return elm_object_item_part_content_get(it, part);
506 }
507
508 static void
509 _title_content_del(void *data,
510                    Evas *e __UNUSED__,
511                    Evas_Object *obj __UNUSED__,
512                    void *event_info __UNUSED__)
513 {
514    char buf[1024];
515    Elm_Naviframe_Content_Item_Pair *pair = data;
516    Elm_Naviframe_Item *it = pair->it;
517    snprintf(buf, sizeof(buf), "elm,state,%s,hide", pair->part);
518    elm_object_signal_emit(VIEW(it), buf, "elm");
519    it->content_list = eina_inlist_remove(it->content_list,
520                                          EINA_INLIST_GET(pair));
521    eina_stringshare_del(pair->part);
522    free(pair);
523 }
524
525 static void
526 _title_prev_btn_del(void *data,
527                     Evas *e __UNUSED__,
528                     Evas_Object *obj __UNUSED__,
529                     void *event_info __UNUSED__)
530 {
531    Elm_Naviframe_Item *it = data;
532    it->back_btn = EINA_FALSE;
533    it->title_prev_btn = NULL;
534    elm_object_signal_emit(VIEW(it), "elm,state,prev_btn,hide", "elm");
535 }
536
537 static void
538 _title_next_btn_del(void *data,
539                     Evas *e __UNUSED__,
540                     Evas_Object *obj __UNUSED__,
541                     void *event_info __UNUSED__)
542 {
543    Elm_Naviframe_Item *it = data;
544    it->title_next_btn = NULL;
545    elm_object_signal_emit(VIEW(it), "elm,state,next_btn,hide", "elm");
546 }
547
548 static void
549 _title_icon_del(void *data,
550                 Evas *e __UNUSED__,
551                 Evas_Object *obj __UNUSED__,
552                 void *event_info __UNUSED__)
553 {
554    Elm_Naviframe_Item *it = data;
555    it->title_icon = NULL;
556    elm_object_signal_emit(VIEW(it), "elm,state,icon,hide", "elm");
557 }
558
559 static void
560 _item_content_del(void *data,
561                   Evas *e __UNUSED__,
562                   Evas_Object *obj __UNUSED__,
563                   void *event_info __UNUSED__)
564 {
565    Elm_Naviframe_Item *it = data;
566    it->content = NULL;
567    elm_object_signal_emit(VIEW(it), "elm,state,content,hide", "elm");
568 }
569
570 static void
571 _title_content_set(Elm_Naviframe_Item *it,
572                    const char *part,
573                    Evas_Object *content)
574 {
575    char buf[1024];
576    Elm_Naviframe_Content_Item_Pair *pair = NULL;
577    Evas_Object *prev_content = NULL;
578
579    EINA_INLIST_FOREACH(it->content_list, pair)
580      if (!strcmp(part, pair->part)) break;
581
582    if (pair)
583      {
584         prev_content = elm_object_part_content_get(VIEW(it), part);
585         if (prev_content != content)
586           {
587              if (content)
588                {
589                   evas_object_event_callback_del(prev_content,
590                                                  EVAS_CALLBACK_DEL,
591                                                  _title_content_del);
592                   snprintf(buf, sizeof(buf), "elm,state,%s,hide", part);
593                   elm_object_signal_emit(VIEW(it), buf, "elm");
594                }
595              evas_object_del(prev_content);
596              if (!content) return;
597           }
598      }
599    else
600      {
601         if (!content) return;
602         pair = ELM_NEW(Elm_Naviframe_Content_Item_Pair);
603         if (!pair)
604           {
605              ERR("Failed to allocate new content part of the item! : naviframe=%p", WIDGET(it));
606              return;
607           }
608         pair->it = it;
609         eina_stringshare_replace(&pair->part, part);
610         it->content_list = eina_inlist_append(it->content_list,
611                                               EINA_INLIST_GET(pair));
612      }
613    if (prev_content != content)
614      {
615         evas_object_event_callback_add(content,
616                                        EVAS_CALLBACK_DEL,
617                                        _title_content_del,
618                                        pair);
619      }
620    elm_object_part_content_set(VIEW(it), part, content);
621    snprintf(buf, sizeof(buf), "elm,state,%s,show", part);
622    elm_object_signal_emit(VIEW(it), buf, "elm");
623
624    _sizing_eval(WIDGET(it));
625 }
626
627 static void
628 _title_prev_btn_set(Elm_Naviframe_Item *it,
629                     Evas_Object *btn,
630                     Eina_Bool back_btn)
631 {
632    if (it->title_prev_btn == btn) return;
633    if (it->title_prev_btn) evas_object_del(it->title_prev_btn);
634    it->title_prev_btn = btn;
635    if (!btn) return;
636
637    evas_object_event_callback_add(btn,
638                                   EVAS_CALLBACK_DEL,
639                                   _title_prev_btn_del,
640                                   it);
641    elm_object_part_content_set(VIEW(it), "elm.swallow.prev_btn", btn);
642    elm_object_signal_emit(VIEW(it), "elm,state,prev_btn,show", "elm");
643    it->back_btn = back_btn;
644
645    _sizing_eval(WIDGET(it));
646 }
647
648 static void
649 _title_next_btn_set(Elm_Naviframe_Item *it, Evas_Object *btn)
650 {
651    if (it->title_next_btn == btn) return;
652    if (it->title_next_btn) evas_object_del(it->title_next_btn);
653    it->title_next_btn = btn;
654    if (!btn) return;
655
656    evas_object_event_callback_add(btn,
657                                   EVAS_CALLBACK_DEL,
658                                   _title_next_btn_del,
659                                   it);
660    elm_object_part_content_set(VIEW(it), "elm.swallow.next_btn", btn);
661    elm_object_signal_emit(VIEW(it), "elm,state,next_btn,show", "elm");
662
663    _sizing_eval(WIDGET(it));
664 }
665
666 static void
667 _title_icon_set(Elm_Naviframe_Item *it, Evas_Object *icon)
668 {
669    if (it->title_icon == icon) return;
670    if (it->title_icon) evas_object_del(it->title_icon);
671    it->title_icon = icon;
672    if (!icon) return;
673
674    evas_object_event_callback_add(icon,
675                                   EVAS_CALLBACK_DEL,
676                                   _title_icon_del,
677                                   it);
678    elm_object_part_content_set(VIEW(it), "elm.swallow.icon", icon);
679    elm_object_signal_emit(VIEW(it), "elm,state,icon,show", "elm");
680
681    _sizing_eval(WIDGET(it));
682 }
683
684 static Evas_Object *
685 _item_content_unset(Elm_Naviframe_Item *it)
686 {
687    Evas_Object *content = it->content;
688    if (!content) return NULL;
689
690    elm_object_part_content_unset(VIEW(it), "elm.swallow.content");
691    elm_object_signal_emit(VIEW(it), "elm,state,content,hide", "elm");
692    evas_object_event_callback_del(content,
693                                   EVAS_CALLBACK_DEL,
694                                   _item_content_del);
695    _sizing_eval(WIDGET(it));
696
697    it->content = NULL;
698    return content;
699 }
700
701 static Evas_Object *
702 _title_prev_btn_unset(Elm_Naviframe_Item *it)
703 {
704    Evas_Object *content = it->title_prev_btn;
705    if (!content) return NULL;
706
707    elm_object_part_content_unset(VIEW(it), "elm.swallow.prev_btn");
708    elm_object_signal_emit(VIEW(it), "elm,state,prev_btn,hide", "elm");
709    evas_object_event_callback_del(content,
710                                   EVAS_CALLBACK_DEL,
711                                   _title_prev_btn_del);
712    _sizing_eval(WIDGET(it));
713
714    it->title_prev_btn = NULL;
715    return content;
716 }
717
718 static Evas_Object *
719 _title_next_btn_unset(Elm_Naviframe_Item *it)
720 {
721    Evas_Object *content = it->title_next_btn;
722    if (!content) return NULL;
723
724    elm_object_part_content_unset(VIEW(it), "elm.swallow.next_btn");
725    elm_object_signal_emit(VIEW(it), "elm,state,next_btn,hide", "elm");
726    evas_object_event_callback_del(content,
727                                   EVAS_CALLBACK_DEL,
728                                   _title_next_btn_del);
729    _sizing_eval(WIDGET(it));
730
731    it->title_next_btn = NULL;
732    return content;
733 }
734
735 static Evas_Object *
736 _title_icon_unset(Elm_Naviframe_Item *it)
737 {
738    Evas_Object *content = it->title_icon;
739    if (!content) return NULL;
740
741    elm_object_part_content_unset(VIEW(it), "elm.swallow.icon");
742    elm_object_signal_emit(VIEW(it), "elm,state,icon,hide", "elm");
743    evas_object_event_callback_del(content,
744                                   EVAS_CALLBACK_DEL,
745                                   _title_icon_del);
746    _sizing_eval(WIDGET(it));
747    it->title_icon = NULL;
748
749    return content;
750 }
751
752 static Evas_Object *
753 _title_content_unset(Elm_Naviframe_Item *it, const char *part)
754 {
755    Elm_Naviframe_Content_Item_Pair *pair = NULL;
756    char buf[1028];
757    Evas_Object *content = NULL;
758
759    EINA_INLIST_FOREACH(it->content_list, pair)
760      {
761         if (!strcmp(part, pair->part))
762           {
763              content = elm_object_part_content_get(VIEW(it), part);
764              eina_stringshare_del(pair->part);
765              it->content_list = eina_inlist_remove(it->content_list,
766                                                    EINA_INLIST_GET(pair));
767              free(pair);
768              break;
769           }
770      }
771
772    if (!content) return NULL;
773
774    elm_object_part_content_unset(VIEW(it), part);
775    snprintf(buf, sizeof(buf), "elm,state,%s,hide", part);
776    elm_object_signal_emit(VIEW(it), buf, "elm");
777    evas_object_event_callback_del(content,
778                                   EVAS_CALLBACK_DEL,
779                                   _title_content_del);
780    _sizing_eval(WIDGET(it));
781
782    return content;
783 }
784
785 static void
786 _item_del(Elm_Naviframe_Item *it)
787 {
788    Widget_Data *wd;
789    Elm_Naviframe_Content_Item_Pair *content_pair;
790    Elm_Naviframe_Text_Item_Pair *text_pair;
791    Evas_Object *content;
792
793    if (!it) return;
794
795    wd = elm_widget_data_get(WIDGET(it));
796    if (!wd) return;
797
798    while (it->content_list)
799      {
800         content_pair =
801            EINA_INLIST_CONTAINER_GET(it->content_list,
802                                      Elm_Naviframe_Content_Item_Pair);
803         content = elm_object_part_content_get(VIEW(it), content_pair->part);
804         evas_object_event_callback_del(content,
805                                        EVAS_CALLBACK_DEL,
806                                        _title_content_del);
807         eina_stringshare_del(content_pair->part);
808         it->content_list = eina_inlist_remove(it->content_list,
809                                               it->content_list);
810         free(content_pair);
811      }
812
813    while (it->text_list)
814      {
815         text_pair = EINA_INLIST_CONTAINER_GET(it->text_list,
816                                               Elm_Naviframe_Text_Item_Pair);
817         eina_stringshare_del(text_pair->part);
818         it->text_list = eina_inlist_remove(it->text_list,
819                                            it->text_list);
820         free(text_pair);
821      }
822
823    eina_stringshare_del(it->style);
824 }
825
826 static Eina_Bool
827 _item_del_pre_hook(Elm_Object_Item *it)
828 {
829    Elm_Naviframe_Item *navi_it;
830    Widget_Data *wd;
831
832    navi_it =(Elm_Naviframe_Item *)it;
833    wd = elm_widget_data_get(WIDGET(navi_it));
834    if (!wd) return EINA_FALSE;
835
836    if (it == elm_naviframe_top_item_get(WIDGET(navi_it)))
837      {
838         wd->stack = eina_inlist_remove(wd->stack, EINA_INLIST_GET(navi_it));
839         _item_del(navi_it);
840         //If the item is only one, the stack will be empty
841         if (!wd->stack) return EINA_TRUE;
842         navi_it = EINA_INLIST_CONTAINER_GET(wd->stack->last,
843                                             Elm_Naviframe_Item);
844         evas_object_show(VIEW(navi_it));
845         evas_object_raise(VIEW(navi_it));
846         elm_object_signal_emit(VIEW(navi_it), "elm,state,visible", "elm");
847      }
848    else
849      {
850         wd->stack = eina_inlist_remove(wd->stack, EINA_INLIST_GET(navi_it));
851         _item_del(navi_it);
852      }
853
854    return EINA_TRUE;
855 }
856
857 static void
858 _pushed_finished(void *data,
859                  Evas_Object *obj __UNUSED__,
860                  const char *emission __UNUSED__,
861                  const char *source __UNUSED__)
862 {
863    Widget_Data *wd;
864    Elm_Naviframe_Item *it = data;
865    if (!it) return;
866
867    wd = elm_widget_data_get(WIDGET(it));
868    if (!wd) return;
869
870    evas_object_hide(VIEW(it));
871    if (wd->freeze_events)
872      evas_object_freeze_events_set(VIEW(it), EINA_FALSE);
873
874    elm_widget_item_smart_callback_call(it,
875                                        SIG_ITEM_HIDE_FINISHED,
876                                        NULL);
877 }
878
879 static void
880 _popped_finished(void *data,
881                  Evas_Object *obj __UNUSED__,
882                  const char *emission __UNUSED__,
883                  const char *source __UNUSED__)
884 {
885    Elm_Naviframe_Item *it = data;
886    if (!it) return;
887    _item_del(data);
888    elm_widget_item_free(data);
889 }
890
891 static void
892 _show_finished(void *data,
893                Evas_Object *obj __UNUSED__,
894                const char *emission __UNUSED__,
895                const char *source __UNUSED__)
896 {
897    Elm_Naviframe_Item *it;
898    Widget_Data *wd;
899
900    it = data;
901    if (!it) return;
902    wd =  elm_widget_data_get(WIDGET(it));
903    if (!wd) return;
904
905    evas_object_smart_callback_call(WIDGET(it),
906                                    SIG_TRANSITION_FINISHED,
907                                    data);
908    if (wd->freeze_events)
909      evas_object_freeze_events_set(VIEW(it), EINA_FALSE);
910 }
911
912 static void
913 _changed_size_hints(void *data,
914                     Evas *e __UNUSED__,
915                     Evas_Object *obj __UNUSED__,
916                     void *event_info __UNUSED__)
917 {
918    _sizing_eval(data);
919 }
920
921 static void
922 _item_content_set(Elm_Naviframe_Item *navi_it, Evas_Object *content)
923 {
924    if (navi_it->content == content) return;
925    if (navi_it->content) evas_object_del(navi_it->content);
926    elm_object_part_content_set(VIEW(navi_it), "elm.swallow.content", content);
927
928    if (content)
929      elm_object_signal_emit(VIEW(navi_it), "elm,state,content,show", "elm");
930    else
931      elm_object_signal_emit(VIEW(navi_it), "elm,state,content,hide", "elm");
932
933    evas_object_event_callback_add(content,
934                                   EVAS_CALLBACK_DEL,
935                                   _item_content_del,
936                                   navi_it);
937    navi_it->content = content;
938    _sizing_eval(WIDGET(navi_it));
939 }
940
941 //FIXME: need to handle if this function is called while transition
942 static void
943 _item_style_set(Elm_Naviframe_Item *navi_it, const char *item_style)
944 {
945    Elm_Naviframe_Content_Item_Pair *content_pair;
946    Elm_Naviframe_Text_Item_Pair *text_pair;
947    Widget_Data *wd;
948
949    char buf[256];
950
951    if (!item_style)
952      {
953         strcpy(buf, "item/basic");
954         eina_stringshare_replace(&navi_it->style, "basic");
955      }
956    else
957      {
958         snprintf(buf, sizeof(buf), "item/%s", item_style);
959         eina_stringshare_replace(&navi_it->style, item_style);
960      }
961    elm_layout_theme_set(VIEW(navi_it),
962                         "naviframe",
963                         buf,
964                         elm_widget_style_get(WIDGET(navi_it)));
965    //recover item
966    EINA_INLIST_FOREACH(navi_it->text_list, text_pair)
967      _item_text_set_hook((Elm_Object_Item *) navi_it,
968                          text_pair->part,
969                          elm_object_part_text_get(VIEW(navi_it),
970                                                   text_pair->part));
971
972    EINA_INLIST_FOREACH(navi_it->content_list, content_pair)
973      _item_content_set_hook((Elm_Object_Item *) navi_it,
974                             content_pair->part,
975                             elm_object_part_content_get(VIEW(navi_it),
976                                                         content_pair->part));
977    //content
978    if (navi_it->content)
979      elm_object_signal_emit(VIEW(navi_it), "elm,state,content,show", "elm");
980
981    //prev button
982    if (navi_it->title_prev_btn)
983      elm_object_signal_emit(VIEW(navi_it), "elm,state,prev_btn,show", "elm");
984
985    //next button
986    if (navi_it->title_next_btn)
987      elm_object_signal_emit(VIEW(navi_it), "elm,state,next_btn,show", "elm");
988
989 // why does this forcibly enable title? isnt that separate to style?   
990 //   navi_it->title_visible = EINA_TRUE;
991    _sizing_eval(WIDGET(navi_it));
992
993    wd = elm_widget_data_get(WIDGET(navi_it));
994    if (!wd) return;
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
1120    return obj;
1121 }
1122
1123 EAPI Elm_Object_Item *
1124 elm_naviframe_item_push(Evas_Object *obj,
1125                         const char *title_label,
1126                         Evas_Object *prev_btn,
1127                         Evas_Object *next_btn,
1128                         Evas_Object *content,
1129                         const char *item_style)
1130 {
1131    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1132    Widget_Data *wd;
1133    Elm_Naviframe_Item *prev_it, *it;
1134
1135    wd = elm_widget_data_get(obj);
1136    if (!wd) return NULL;
1137
1138    it = _item_new(obj, title_label, prev_btn, next_btn, content, item_style);
1139    if (!it) return NULL;
1140
1141    evas_object_show(VIEW(it));
1142
1143    prev_it = (Elm_Naviframe_Item *) elm_naviframe_top_item_get(obj);
1144    if (prev_it)
1145      {
1146         if (wd->freeze_events)
1147           {
1148              evas_object_freeze_events_set(VIEW(it), EINA_TRUE);
1149              evas_object_freeze_events_set(VIEW(prev_it), EINA_TRUE);
1150           }
1151         elm_object_signal_emit(VIEW(prev_it), "elm,state,cur,pushed", "elm");
1152         elm_object_signal_emit(VIEW(it), "elm,state,new,pushed", "elm");
1153         edje_object_message_signal_process(elm_layout_edje_get(VIEW(prev_it)));
1154         elm_widget_tree_unfocusable_set(it->content, EINA_TRUE);
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    if (wd->preserve)
1235      content = it->content;
1236
1237    if (wd->stack->last->prev)
1238      prev_it = EINA_INLIST_CONTAINER_GET(wd->stack->last->prev,
1239                                          Elm_Naviframe_Item);
1240    wd->stack = eina_inlist_remove(wd->stack, EINA_INLIST_GET(it));
1241    if (prev_it)
1242      {
1243         if (wd->freeze_events)
1244           {
1245              evas_object_freeze_events_set(VIEW(it), EINA_TRUE);
1246              evas_object_freeze_events_set(VIEW(prev_it), EINA_TRUE);
1247           }
1248         elm_object_signal_emit(VIEW(it), "elm,state,cur,popped", "elm");
1249         evas_object_show(VIEW(prev_it));
1250         evas_object_raise(VIEW(prev_it));
1251         elm_object_signal_emit(VIEW(prev_it),
1252                                "elm,state,prev,popped",
1253                                "elm");
1254         edje_object_message_signal_process(elm_layout_edje_get(VIEW(it)));
1255         edje_object_message_signal_process(elm_layout_edje_get(VIEW(prev_it)));
1256         elm_widget_item_smart_callback_call(prev_it,
1257                                             SIG_ITEM_SHOW_BEGIN,
1258                                             NULL);
1259      }
1260    else
1261      {
1262         _item_del(it);
1263         elm_widget_item_free(it);
1264      }
1265
1266    return content;
1267 }
1268
1269 EAPI void
1270 elm_naviframe_item_pop_to(Elm_Object_Item *it)
1271 {
1272    ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1273    Elm_Naviframe_Item *navi_it;
1274    Widget_Data *wd;
1275    Eina_Inlist *l, *prev_l;
1276
1277    navi_it = (Elm_Naviframe_Item *)it;
1278    wd = elm_widget_data_get(WIDGET(navi_it));
1279    if (!wd) return;
1280
1281    if (it == elm_naviframe_top_item_get(WIDGET(navi_it))) return;
1282
1283    l = wd->stack->last->prev;
1284
1285    while(l)
1286      {
1287         if (EINA_INLIST_CONTAINER_GET(l, Elm_Naviframe_Item) ==
1288             ((Elm_Naviframe_Item *)it)) break;
1289         prev_l = l->prev;
1290         wd->stack = eina_inlist_remove(wd->stack, l);
1291         _item_del(EINA_INLIST_CONTAINER_GET(l, Elm_Naviframe_Item));
1292         elm_widget_item_free(EINA_INLIST_CONTAINER_GET(l,
1293                                                        Elm_Naviframe_Item));
1294         l = prev_l;
1295      }
1296    elm_naviframe_item_pop(WIDGET(navi_it));
1297 }
1298
1299 EAPI void
1300 elm_naviframe_item_promote(Elm_Object_Item *it)
1301 {
1302    ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1303    Elm_Naviframe_Item *navi_it;
1304    Elm_Naviframe_Item *prev_it;
1305    Widget_Data *wd;
1306
1307    navi_it = (Elm_Naviframe_Item *)it;
1308    wd = elm_widget_data_get(navi_it->base.widget);
1309    if (!wd) return;
1310
1311    if (it == elm_naviframe_top_item_get(navi_it->base.widget)) return;
1312    elm_widget_tree_unfocusable_set(navi_it->content, EINA_FALSE);
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    elm_widget_tree_unfocusable_set(prev_it->content, EINA_FALSE);
1317    if (wd->freeze_events)
1318      {
1319         evas_object_freeze_events_set(VIEW(it), EINA_TRUE);
1320         evas_object_freeze_events_set(VIEW(prev_it), EINA_TRUE);
1321      }
1322    elm_object_signal_emit(VIEW(prev_it),
1323                           "elm,state,cur,pushed",
1324                           "elm");
1325    evas_object_show(VIEW(navi_it));
1326    evas_object_raise(VIEW(navi_it));
1327    elm_object_signal_emit(VIEW(navi_it),
1328                           "elm,state,new,pushed",
1329                           "elm");
1330    edje_object_message_signal_process(elm_layout_edje_get(VIEW(prev_it)));
1331    edje_object_message_signal_process(elm_layout_edje_get(VIEW(navi_it)));
1332 }
1333
1334 EAPI void
1335 elm_naviframe_item_simple_promote(Evas_Object *obj, Evas_Object *content)
1336 {
1337    ELM_CHECK_WIDTYPE(obj, widtype);
1338    Widget_Data *wd = elm_widget_data_get(obj);
1339    if (!wd) return;
1340    Elm_Naviframe_Item *itr;
1341    EINA_INLIST_FOREACH(wd->stack, itr)
1342      {
1343         if (elm_object_item_content_get((Elm_Object_Item *)itr) == content)
1344           {
1345              elm_naviframe_item_promote((Elm_Object_Item *)itr);
1346              break;
1347           }
1348      }
1349 }
1350
1351
1352 EAPI void
1353 elm_naviframe_item_del(Elm_Object_Item *it)
1354 {
1355    elm_object_item_del(it);
1356 }
1357
1358 EAPI void
1359 elm_naviframe_content_preserve_on_pop_set(Evas_Object *obj, Eina_Bool preserve)
1360 {
1361    ELM_CHECK_WIDTYPE(obj, widtype);
1362    Widget_Data *wd = elm_widget_data_get(obj);
1363    if (!wd) return;
1364    wd->preserve = !!preserve;
1365 }
1366
1367 EAPI Eina_Bool
1368 elm_naviframe_content_preserve_on_pop_get(const Evas_Object *obj)
1369 {
1370    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
1371    Widget_Data *wd = elm_widget_data_get(obj);
1372    if (!wd) return EINA_FALSE;
1373    return wd->preserve;
1374 }
1375
1376 EAPI Elm_Object_Item*
1377 elm_naviframe_top_item_get(const Evas_Object *obj)
1378 {
1379    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1380    Widget_Data *wd = elm_widget_data_get(obj);
1381    if ((!wd) || (!wd->stack)) return NULL;
1382    return (Elm_Object_Item *) (EINA_INLIST_CONTAINER_GET(wd->stack->last,
1383                                                          Elm_Naviframe_Item));
1384 }
1385
1386 EAPI Elm_Object_Item*
1387 elm_naviframe_bottom_item_get(const Evas_Object *obj)
1388 {
1389    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1390    Widget_Data *wd = elm_widget_data_get(obj);
1391    if ((!wd) || (!wd->stack)) return NULL;
1392    return (Elm_Object_Item *) (EINA_INLIST_CONTAINER_GET(wd->stack,
1393                                                          Elm_Naviframe_Item));
1394 }
1395
1396 EAPI void
1397 elm_naviframe_item_style_set(Elm_Object_Item *it, const char *item_style)
1398 {
1399    ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1400    Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *)it;
1401
1402    if (item_style)
1403      if (!strcmp(item_style, navi_it->style)) return;
1404
1405    if (!item_style)
1406      if (!strcmp("basic", navi_it->style)) 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      ret = eina_list_append(ret, itr);
1468    return ret;
1469 }
1470
1471 EAPI void
1472 elm_naviframe_event_enabled_set(Evas_Object *obj, Eina_Bool enabled)
1473 {
1474    ELM_CHECK_WIDTYPE(obj, widtype);
1475    Widget_Data *wd = elm_widget_data_get(obj);
1476    if (!wd) return;
1477    enabled = !!enabled;
1478    if (wd->freeze_events == !enabled) return;
1479    wd->freeze_events = !enabled;
1480 }
1481
1482 EAPI Eina_Bool
1483 elm_naviframe_event_enabled_get(const Evas_Object *obj)
1484 {
1485    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
1486    Widget_Data *wd = elm_widget_data_get(obj);
1487    if (!wd) return EINA_FALSE;
1488    return !wd->freeze_events;
1489 }