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