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