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