elm naviframe: Fixed formatting.
[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         edje_object_message_signal_process(elm_layout_edje_get(VIEW(it)));
1154      }
1155    wd->stack = eina_inlist_append(wd->stack, EINA_INLIST_GET(it));
1156    _sizing_eval(obj);
1157    return (Elm_Object_Item *) it;
1158 }
1159
1160 EAPI Elm_Object_Item *
1161 elm_naviframe_item_insert_before(Elm_Object_Item *before,
1162                                  const char *title_label,
1163                                  Evas_Object *prev_btn,
1164                                  Evas_Object *next_btn,
1165                                  Evas_Object *content,
1166                                  const char *item_style)
1167 {
1168    ELM_OBJ_ITEM_CHECK_OR_RETURN(before, NULL);
1169    Elm_Naviframe_Item *it;
1170    Widget_Data *wd;
1171
1172    wd = elm_widget_data_get(WIDGET(before));
1173    if (!wd) return NULL;
1174
1175    it = _item_new(WIDGET(before), title_label, prev_btn, next_btn, content,
1176                   item_style);
1177    if (!it) return NULL;
1178
1179    wd->stack =
1180       eina_inlist_prepend_relative(wd->stack,
1181                                    EINA_INLIST_GET(it),
1182                                    EINA_INLIST_GET(((Elm_Naviframe_Item *) before)));
1183    _sizing_eval(WIDGET(before));
1184    return (Elm_Object_Item *) it;
1185 }
1186
1187 EAPI Elm_Object_Item *
1188 elm_naviframe_item_insert_after(Elm_Object_Item *after,
1189                                 const char *title_label,
1190                                 Evas_Object *prev_btn,
1191                                 Evas_Object *next_btn,
1192                                 Evas_Object *content,
1193                                 const char *item_style)
1194 {
1195    ELM_OBJ_ITEM_CHECK_OR_RETURN(after, NULL);
1196    Elm_Naviframe_Item *it;
1197    Widget_Data *wd;
1198
1199    wd = elm_widget_data_get(WIDGET(after));
1200    if (!wd) return NULL;
1201
1202    it = _item_new(WIDGET(after), title_label, prev_btn, next_btn, content,
1203                   item_style);
1204    if (!it) return NULL;
1205
1206    if (elm_naviframe_top_item_get(WIDGET(after)) == after)
1207      {
1208         evas_object_hide(VIEW(after));
1209         evas_object_show(VIEW(it));
1210      }
1211    wd->stack =
1212       eina_inlist_append_relative(wd->stack,
1213                                   EINA_INLIST_GET(it),
1214                                   EINA_INLIST_GET(((Elm_Naviframe_Item *) after)));
1215    _sizing_eval(WIDGET(after));
1216    return (Elm_Object_Item *) it;
1217 }
1218
1219 EAPI Evas_Object *
1220 elm_naviframe_item_pop(Evas_Object *obj)
1221 {
1222    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1223    Elm_Naviframe_Item *it, *prev_it = NULL;
1224    Widget_Data *wd;
1225    Evas_Object *content = NULL;
1226
1227    wd = elm_widget_data_get(obj);
1228    if (!wd) return NULL;
1229
1230    it = (Elm_Naviframe_Item *) elm_naviframe_top_item_get(obj);
1231    if (!it) return NULL;
1232    elm_widget_tree_unfocusable_set(it->content, EINA_TRUE);
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    wd->stack = eina_inlist_demote(wd->stack, EINA_INLIST_GET(navi_it));
1312    prev_it = EINA_INLIST_CONTAINER_GET(wd->stack->last->prev,
1313                                          Elm_Naviframe_Item);
1314    if (wd->freeze_events)
1315      {
1316         evas_object_freeze_events_set(VIEW(it), EINA_TRUE);
1317         evas_object_freeze_events_set(VIEW(prev_it), EINA_TRUE);
1318      }
1319    elm_object_signal_emit(VIEW(prev_it),
1320                           "elm,state,cur,pushed",
1321                           "elm");
1322    evas_object_show(VIEW(navi_it));
1323    evas_object_raise(VIEW(navi_it));
1324    elm_object_signal_emit(VIEW(navi_it),
1325                           "elm,state,new,pushed",
1326                           "elm");
1327    edje_object_message_signal_process(elm_layout_edje_get(VIEW(prev_it)));
1328    edje_object_message_signal_process(elm_layout_edje_get(VIEW(navi_it)));
1329 }
1330
1331 EAPI void
1332 elm_naviframe_item_simple_promote(Evas_Object *obj, Evas_Object *content)
1333 {
1334    ELM_CHECK_WIDTYPE(obj, widtype);
1335    Widget_Data *wd = elm_widget_data_get(obj);
1336    if (!wd) return;
1337    Elm_Naviframe_Item *itr;
1338    EINA_INLIST_FOREACH(wd->stack, itr)
1339      {
1340         if (elm_object_item_content_get((Elm_Object_Item *) itr) == content)
1341           {
1342              elm_naviframe_item_promote((Elm_Object_Item *) itr);
1343              break;
1344           }
1345      }
1346 }
1347
1348
1349 EAPI void
1350 elm_naviframe_item_del(Elm_Object_Item *it)
1351 {
1352    elm_object_item_del(it);
1353 }
1354
1355 EAPI void
1356 elm_naviframe_content_preserve_on_pop_set(Evas_Object *obj, Eina_Bool preserve)
1357 {
1358    ELM_CHECK_WIDTYPE(obj, widtype);
1359    Widget_Data *wd = elm_widget_data_get(obj);
1360    if (!wd) return;
1361    wd->preserve = !!preserve;
1362 }
1363
1364 EAPI Eina_Bool
1365 elm_naviframe_content_preserve_on_pop_get(const Evas_Object *obj)
1366 {
1367    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
1368    Widget_Data *wd = elm_widget_data_get(obj);
1369    if (!wd) return EINA_FALSE;
1370    return wd->preserve;
1371 }
1372
1373 EAPI Elm_Object_Item*
1374 elm_naviframe_top_item_get(const Evas_Object *obj)
1375 {
1376    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1377    Widget_Data *wd = elm_widget_data_get(obj);
1378    if ((!wd) || (!wd->stack)) return NULL;
1379    return (Elm_Object_Item *) (EINA_INLIST_CONTAINER_GET(wd->stack->last,
1380                                                          Elm_Naviframe_Item));
1381 }
1382
1383 EAPI Elm_Object_Item*
1384 elm_naviframe_bottom_item_get(const Evas_Object *obj)
1385 {
1386    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1387    Widget_Data *wd = elm_widget_data_get(obj);
1388    if ((!wd) || (!wd->stack)) return NULL;
1389    return (Elm_Object_Item *) (EINA_INLIST_CONTAINER_GET(wd->stack,
1390                                                          Elm_Naviframe_Item));
1391 }
1392
1393 EAPI void
1394 elm_naviframe_item_style_set(Elm_Object_Item *it, const char *item_style)
1395 {
1396    ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1397    Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
1398
1399    //Return if new style is exsiting one.
1400    if ((item_style && navi_it->style) && (!strcmp(item_style, navi_it->style)))
1401       return;
1402
1403    if ((!item_style) && (!navi_it->style))
1404       return;
1405
1406    _item_style_set(navi_it, item_style);
1407 }
1408
1409 EAPI const char *
1410 elm_naviframe_item_style_get(const Elm_Object_Item *it)
1411 {
1412    ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
1413    Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
1414    return navi_it->style;
1415 }
1416
1417 EAPI void
1418 elm_naviframe_item_title_visible_set(Elm_Object_Item *it, Eina_Bool visible)
1419 {
1420    ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1421    Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
1422
1423    visible = !!visible;
1424    if (navi_it->title_visible == visible) return;
1425
1426    navi_it->title_visible = visible;
1427    _item_title_visible_update(navi_it);
1428 }
1429
1430 EAPI Eina_Bool
1431 elm_naviframe_item_title_visible_get(const Elm_Object_Item *it)
1432 {
1433    ELM_OBJ_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
1434    Elm_Naviframe_Item *navi_it = (Elm_Naviframe_Item *) it;
1435    return navi_it->title_visible;
1436 }
1437
1438 EAPI void
1439 elm_naviframe_prev_btn_auto_pushed_set(Evas_Object *obj, Eina_Bool auto_pushed)
1440 {
1441    ELM_CHECK_WIDTYPE(obj, widtype);
1442    Widget_Data *wd = elm_widget_data_get(obj);
1443    if (!wd) return;
1444    wd->auto_pushed = !!auto_pushed;
1445 }
1446
1447 EAPI Eina_Bool
1448 elm_naviframe_prev_btn_auto_pushed_get(const Evas_Object *obj)
1449 {
1450    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
1451    Widget_Data *wd = elm_widget_data_get(obj);
1452    if (!wd) return EINA_FALSE;
1453    return wd->auto_pushed;
1454 }
1455
1456 EAPI Eina_List *
1457 elm_naviframe_items_get(const Evas_Object *obj)
1458 {
1459    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1460    Widget_Data *wd = elm_widget_data_get(obj);
1461    if (!wd) return NULL;
1462    Eina_List *ret = NULL;
1463    Elm_Naviframe_Item *itr;
1464    EINA_INLIST_FOREACH(wd->stack, itr)
1465      ret = eina_list_append(ret, itr);
1466    return ret;
1467 }
1468
1469 EAPI void
1470 elm_naviframe_event_enabled_set(Evas_Object *obj, Eina_Bool enabled)
1471 {
1472    ELM_CHECK_WIDTYPE(obj, widtype);
1473    Widget_Data *wd = elm_widget_data_get(obj);
1474    if (!wd) return;
1475    enabled = !!enabled;
1476    if (wd->freeze_events == !enabled) return;
1477    wd->freeze_events = !enabled;
1478 }
1479
1480 EAPI Eina_Bool
1481 elm_naviframe_event_enabled_get(const Evas_Object *obj)
1482 {
1483    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
1484    Widget_Data *wd = elm_widget_data_get(obj);
1485    if (!wd) return EINA_FALSE;
1486    return !wd->freeze_events;
1487 }
1488
1489 EAPI void
1490 elm_naviframe_item_style_default_set(Evas_Object *obj, const char *style)
1491 {
1492    ELM_CHECK_WIDTYPE(obj, widtype);
1493    Widget_Data *wd = elm_widget_data_get(obj);
1494    if (!wd) return;
1495    eina_stringshare_replace(&wd->item_style, style);
1496    _theme_hook(obj);
1497 }
1498
1499 EAPI const char *
1500 elm_naviframe_item_style_default_get(const Evas_Object *obj)
1501 {
1502    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1503    Widget_Data *wd = elm_widget_data_get(obj);
1504    if (!wd) return NULL;
1505    return wd->item_style;
1506 }