3d, gesturelayer, index, naviframe, transit, fileselector, frame, glview, layout...
[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(Evas_Object *obj,
1164                                  Elm_Object_Item *before,
1165                                  const char *title_label,
1166                                  Evas_Object *prev_btn,
1167                                  Evas_Object *next_btn,
1168                                  Evas_Object *content,
1169                                  const char *item_style)
1170 {
1171    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1172    ELM_OBJ_ITEM_CHECK_OR_RETURN(before, NULL);
1173    Elm_Naviframe_Item *it;
1174    Widget_Data *wd;
1175
1176    wd = elm_widget_data_get(obj);
1177    if (!wd) return NULL;
1178
1179    it = _item_new(WIDGET(before), title_label, prev_btn, next_btn, content,
1180                   item_style);
1181    if (!it) return NULL;
1182
1183    wd->stack =
1184       eina_inlist_prepend_relative(wd->stack,
1185                                    EINA_INLIST_GET(it),
1186                                    EINA_INLIST_GET(((Elm_Naviframe_Item *) before)));
1187    _sizing_eval(WIDGET(before));
1188    return (Elm_Object_Item *)it;
1189 }
1190
1191 EAPI Elm_Object_Item *
1192 elm_naviframe_item_insert_after(Evas_Object *obj,
1193                                 Elm_Object_Item *after,
1194                                 const char *title_label,
1195                                 Evas_Object *prev_btn,
1196                                 Evas_Object *next_btn,
1197                                 Evas_Object *content,
1198                                 const char *item_style)
1199 {
1200    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1201    ELM_OBJ_ITEM_CHECK_OR_RETURN(after, NULL);
1202    Elm_Naviframe_Item *it;
1203    Widget_Data *wd;
1204
1205    wd = elm_widget_data_get(obj);
1206    if (!wd) return NULL;
1207
1208    it = _item_new(WIDGET(after), title_label, prev_btn, next_btn, content,
1209                   item_style);
1210    if (!it) return NULL;
1211
1212    if (elm_naviframe_top_item_get(WIDGET(after)) == after)
1213      {
1214         evas_object_hide(VIEW(after));
1215         evas_object_show(VIEW(it));
1216      }
1217    wd->stack =
1218       eina_inlist_append_relative(wd->stack,
1219                                   EINA_INLIST_GET(it),
1220                                   EINA_INLIST_GET(((Elm_Naviframe_Item *) after)));
1221    _sizing_eval(WIDGET(after));
1222    return (Elm_Object_Item *)it;
1223 }
1224
1225 EAPI Evas_Object *
1226 elm_naviframe_item_pop(Evas_Object *obj)
1227 {
1228    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1229    Elm_Naviframe_Item *it, *prev_it = NULL;
1230    Widget_Data *wd;
1231    Evas_Object *content = NULL;
1232
1233    wd = elm_widget_data_get(obj);
1234    if (!wd) return NULL;
1235
1236    it = (Elm_Naviframe_Item *) elm_naviframe_top_item_get(obj);
1237    if (!it) return NULL;
1238    if (wd->preserve)
1239      content = it->content;
1240
1241    if (wd->stack->last->prev)
1242      prev_it = EINA_INLIST_CONTAINER_GET(wd->stack->last->prev,
1243                                          Elm_Naviframe_Item);
1244    wd->stack = eina_inlist_remove(wd->stack, EINA_INLIST_GET(it));
1245    if (prev_it)
1246      {
1247         if (wd->freeze_events)
1248           {
1249              evas_object_freeze_events_set(VIEW(it), EINA_TRUE);
1250              evas_object_freeze_events_set(VIEW(prev_it), EINA_TRUE);
1251           }
1252         elm_object_signal_emit(VIEW(it), "elm,state,cur,popped", "elm");
1253         evas_object_show(VIEW(prev_it));
1254         evas_object_raise(VIEW(prev_it));
1255         elm_object_signal_emit(VIEW(prev_it),
1256                                "elm,state,prev,popped",
1257                                "elm");
1258         edje_object_message_signal_process(elm_layout_edje_get(VIEW(it)));
1259         edje_object_message_signal_process(elm_layout_edje_get(VIEW(prev_it)));
1260         elm_widget_item_smart_callback_call(prev_it,
1261                                             SIG_ITEM_SHOW_BEGIN,
1262                                             NULL);
1263      }
1264    else
1265      {
1266         _item_del(it);
1267         elm_widget_item_free(it);
1268      }
1269
1270    return content;
1271 }
1272
1273 EAPI void
1274 elm_naviframe_item_pop_to(Elm_Object_Item *it)
1275 {
1276    ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1277    Elm_Naviframe_Item *navi_it;
1278    Widget_Data *wd;
1279    Eina_Inlist *l, *prev_l;
1280
1281    navi_it = (Elm_Naviframe_Item *)it;
1282    wd = elm_widget_data_get(WIDGET(navi_it));
1283    if (!wd) return;
1284
1285    if (it == elm_naviframe_top_item_get(WIDGET(navi_it))) return;
1286
1287    l = wd->stack->last->prev;
1288
1289    while(l)
1290      {
1291         if (EINA_INLIST_CONTAINER_GET(l, Elm_Naviframe_Item) ==
1292             ((Elm_Naviframe_Item *)it)) break;
1293         prev_l = l->prev;
1294         wd->stack = eina_inlist_remove(wd->stack, l);
1295         _item_del(EINA_INLIST_CONTAINER_GET(l, Elm_Naviframe_Item));
1296         elm_widget_item_free(EINA_INLIST_CONTAINER_GET(l,
1297                                                        Elm_Naviframe_Item));
1298         l = prev_l;
1299      }
1300    elm_naviframe_item_pop(WIDGET(navi_it));
1301 }
1302
1303 EAPI void
1304 elm_naviframe_item_promote(Elm_Object_Item *it)
1305 {
1306    ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1307    Elm_Naviframe_Item *navi_it;
1308    Elm_Naviframe_Item *prev_it;
1309    Widget_Data *wd;
1310
1311    navi_it = (Elm_Naviframe_Item *)it;
1312    wd = elm_widget_data_get(navi_it->base.widget);
1313    if (!wd) return;
1314
1315    if (it == elm_naviframe_top_item_get(navi_it->base.widget)) return;
1316    elm_widget_tree_unfocusable_set(navi_it->content, EINA_FALSE);
1317    wd->stack = eina_inlist_demote(wd->stack, EINA_INLIST_GET(navi_it));
1318    prev_it = EINA_INLIST_CONTAINER_GET(wd->stack->last->prev,
1319                                          Elm_Naviframe_Item);
1320    elm_widget_tree_unfocusable_set(prev_it->content, EINA_FALSE);
1321    if (wd->freeze_events)
1322      {
1323         evas_object_freeze_events_set(VIEW(it), EINA_TRUE);
1324         evas_object_freeze_events_set(VIEW(prev_it), EINA_TRUE);
1325      }
1326    elm_object_signal_emit(VIEW(prev_it),
1327                           "elm,state,cur,pushed",
1328                           "elm");
1329    evas_object_show(VIEW(navi_it));
1330    evas_object_raise(VIEW(navi_it));
1331    elm_object_signal_emit(VIEW(navi_it),
1332                           "elm,state,new,pushed",
1333                           "elm");
1334    edje_object_message_signal_process(elm_layout_edje_get(VIEW(prev_it)));
1335    edje_object_message_signal_process(elm_layout_edje_get(VIEW(navi_it)));
1336 }
1337
1338 EAPI void
1339 elm_naviframe_item_simple_promote(Evas_Object *obj, Evas_Object *content)
1340 {
1341    ELM_CHECK_WIDTYPE(obj, widtype);
1342    Widget_Data *wd = elm_widget_data_get(obj);
1343    if (!wd) return;
1344    Elm_Naviframe_Item *itr;
1345    EINA_INLIST_FOREACH(wd->stack, itr)
1346      {
1347         if (elm_object_item_content_get((Elm_Object_Item *)itr) == content)
1348           {
1349              elm_naviframe_item_promote((Elm_Object_Item *)itr);
1350              break;
1351           }
1352      }
1353 }
1354
1355
1356 EAPI void
1357 elm_naviframe_item_del(Elm_Object_Item *it)
1358 {
1359    elm_object_item_del(it);
1360 }
1361
1362 EAPI void
1363 elm_naviframe_content_preserve_on_pop_set(Evas_Object *obj, Eina_Bool preserve)
1364 {
1365    ELM_CHECK_WIDTYPE(obj, widtype);
1366    Widget_Data *wd = elm_widget_data_get(obj);
1367    if (!wd) return;
1368    wd->preserve = !!preserve;
1369 }
1370
1371 EAPI Eina_Bool
1372 elm_naviframe_content_preserve_on_pop_get(const Evas_Object *obj)
1373 {
1374    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
1375    Widget_Data *wd = elm_widget_data_get(obj);
1376    if (!wd) return EINA_FALSE;
1377    return wd->preserve;
1378 }
1379
1380 EAPI Elm_Object_Item*
1381 elm_naviframe_top_item_get(const Evas_Object *obj)
1382 {
1383    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1384    Widget_Data *wd = elm_widget_data_get(obj);
1385    if ((!wd) || (!wd->stack)) return NULL;
1386    return (Elm_Object_Item *) (EINA_INLIST_CONTAINER_GET(wd->stack->last,
1387                                                          Elm_Naviframe_Item));
1388 }
1389
1390 EAPI Elm_Object_Item*
1391 elm_naviframe_bottom_item_get(const Evas_Object *obj)
1392 {
1393    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1394    Widget_Data *wd = elm_widget_data_get(obj);
1395    if ((!wd) || (!wd->stack)) return NULL;
1396    return (Elm_Object_Item *) (EINA_INLIST_CONTAINER_GET(wd->stack,
1397                                                          Elm_Naviframe_Item));
1398 }
1399
1400 EAPI void
1401 elm_naviframe_item_style_set(Elm_Object_Item *it, const char *item_style)
1402 {
1403    ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1404    Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *)it;
1405
1406    if (item_style)
1407      if (!strcmp(item_style, navi_it->style)) return;
1408
1409    if (!item_style)
1410      if (!strcmp("basic", navi_it->style)) return;
1411
1412    _item_style_set(navi_it, item_style);
1413 }
1414
1415 EAPI const char *
1416 elm_naviframe_item_style_get(const Elm_Object_Item *it)
1417 {
1418    ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
1419    Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *)it;
1420    return navi_it->style;
1421 }
1422
1423 EAPI void
1424 elm_naviframe_item_title_visible_set(Elm_Object_Item *it, Eina_Bool visible)
1425 {
1426    ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1427    Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *)it;
1428
1429    visible = !!visible;
1430    if (navi_it->title_visible == visible) return;
1431
1432    navi_it->title_visible = visible;
1433    _item_title_visible_update(navi_it);
1434 }
1435
1436 EAPI Eina_Bool
1437 elm_naviframe_item_title_visible_get(const Elm_Object_Item *it)
1438 {
1439    ELM_OBJ_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
1440    Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *)it;
1441    return navi_it->title_visible;
1442 }
1443
1444 EAPI void
1445 elm_naviframe_prev_btn_auto_pushed_set(Evas_Object *obj, Eina_Bool auto_pushed)
1446 {
1447    ELM_CHECK_WIDTYPE(obj, widtype);
1448    Widget_Data *wd = elm_widget_data_get(obj);
1449    if (!wd) return;
1450    wd->auto_pushed = !!auto_pushed;
1451 }
1452
1453 EAPI Eina_Bool
1454 elm_naviframe_prev_btn_auto_pushed_get(const Evas_Object *obj)
1455 {
1456    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
1457    Widget_Data *wd = elm_widget_data_get(obj);
1458    if (!wd) return EINA_FALSE;
1459    return wd->auto_pushed;
1460 }
1461
1462 EAPI Eina_List *
1463 elm_naviframe_items_get(const Evas_Object *obj)
1464 {
1465    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1466    Widget_Data *wd = elm_widget_data_get(obj);
1467    if (!wd) return NULL;
1468    Eina_List *ret = NULL;
1469    Elm_Naviframe_Item *itr;
1470    EINA_INLIST_FOREACH(wd->stack, itr)
1471      ret = eina_list_append(ret, itr);
1472    return ret;
1473 }
1474
1475 EAPI void
1476 elm_naviframe_event_enabled_set(Evas_Object *obj, Eina_Bool enabled)
1477 {
1478    ELM_CHECK_WIDTYPE(obj, widtype);
1479    Widget_Data *wd = elm_widget_data_get(obj);
1480    if (!wd) return;
1481    enabled = !!enabled;
1482    if (wd->freeze_events == !enabled) return;
1483    wd->freeze_events = !enabled;
1484 }
1485
1486 EAPI Eina_Bool
1487 elm_naviframe_event_enabled_get(const Evas_Object *obj)
1488 {
1489    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
1490    Widget_Data *wd = elm_widget_data_get(obj);
1491    if (!wd) return EINA_FALSE;
1492    return !wd->freeze_events;
1493 }