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