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