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