elementary/naviframe - merged groups base and title
[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_List    *stack;
12    Evas_Object  *base;
13    Eina_Bool     preserve: 1;
14    Eina_Bool     pass_events: 1;
15 };
16
17 struct _Elm_Naviframe_Content_Item_Pair
18 {
19    const char *part;
20    Evas_Object *content;
21    Elm_Naviframe_Item *it;
22 };
23
24 struct _Elm_Naviframe_Text_Item_Pair
25 {
26    const char *part;
27    const char *text;
28 };
29
30 struct _Elm_Naviframe_Item
31 {
32    Elm_Widget_Item    base;
33    Eina_List         *content_list;
34    Eina_List         *text_list;
35    Evas_Object       *content;
36    Evas_Object       *title_prev_btn;
37    Evas_Object       *title_next_btn;
38    const char        *style;
39    Eina_Bool          back_btn: 1;
40    Eina_Bool          title_visible: 1;
41 };
42
43 static const char *widtype = NULL;
44
45 static const char SIG_TRANSITION_FINISHED[] = "transition,finished";
46 static const char SIG_TITLE_CLICKED[] = "title,clicked";
47
48 static const Evas_Smart_Cb_Description _signals[] = {
49        {SIG_TRANSITION_FINISHED, ""},
50        {SIG_TITLE_CLICKED, ""},
51        {NULL, NULL}
52 };
53
54 static void _del_hook(Evas_Object *obj);
55 static void _theme_hook(Evas_Object *obj);
56 static void _disable_hook(Evas_Object *obj);
57 static void _text_set_hook(Elm_Object_Item *it,
58                            const char *part,
59                            const char *label);
60 static const char *_text_get_hook(const Elm_Object_Item *it,
61                                    const char *part);
62 static void _content_set_hook(Elm_Object_Item *it,
63                               const char *part,
64                               Evas_Object *content);
65 static Evas_Object *_content_get_hook(const Elm_Object_Item *it,
66                                       const char *part);
67 static Evas_Object *_content_unset_hook(Elm_Object_Item *it,
68                                         const char *part);
69 static void _sizing_eval(Evas_Object *obj);
70 static void _item_sizing_eval(Elm_Naviframe_Item *it);
71 static void _move(void *data, Evas *e, Evas_Object *obj, void *event_info);
72 static void _resize(void *data,
73                     Evas *e,
74                     Evas_Object *obj,
75                     void *event_info);
76 static void _title_clicked(void *data, Evas_Object *obj,
77                            const char *emission,
78                            const char *source);
79 static void _back_btn_clicked(void *data,
80                               Evas_Object *obj,
81                               void *event_info);
82 static Evas_Object *_back_btn_new(Evas_Object *obj);
83 static void _item_content_del(void *data,
84                               Evas *e,
85                               Evas_Object *obj,
86                               void *event_info);
87 static void _title_content_del(void *data,
88                                Evas *e,
89                                Evas_Object *obj,
90                                void *event_info);
91 static void _title_prev_btn_del(void *data,
92                                 Evas *e,
93                                 Evas_Object *obj,
94                                 void *event_info);
95 static void _title_next_btn_del(void *data,
96                                 Evas *e,
97                                 Evas_Object *obj,
98                                 void *event_info);
99 static void _title_content_set(Elm_Naviframe_Item *it,
100                                Elm_Naviframe_Content_Item_Pair *pair,
101                                const char *part,
102                                Evas_Object *content);
103 static void _title_prev_btn_set(Elm_Naviframe_Item *it,
104                                 Evas_Object *btn,
105                                 Eina_Bool back_btn);
106 static void _title_next_btn_set(Elm_Naviframe_Item *it, Evas_Object *btn);
107 static void _item_del(Elm_Naviframe_Item *it);
108 static void _pushed_finished(void *data,
109                              Evas_Object *obj,
110                              const char *emission,
111                              const char *source);
112 static void _popped_finished(void *data,
113                              Evas_Object *obj,
114                              const char *emission,
115                              const char *source);
116 static void _show_finished(void *data,
117                            Evas_Object *obj,
118                            const char *emission,
119                            const char *source);
120 static void _item_content_set(Elm_Naviframe_Item *navi_it,
121                               Evas_Object *content);
122
123 static void
124 _del_hook(Evas_Object *obj)
125 {
126    Widget_Data *wd;
127    Eina_List *list;
128    Elm_Naviframe_Item *it;
129
130    wd = elm_widget_data_get(obj);
131    if (!wd) return;
132
133    EINA_LIST_FOREACH(wd->stack, list, it)
134      _item_del(it);
135    eina_list_free(wd->stack);
136    free(wd);
137 }
138
139 static void
140 _theme_hook(Evas_Object *obj __UNUSED__)
141 {
142    //FIXME:
143 }
144
145 static void
146 _disable_hook(Evas_Object *obj __UNUSED__)
147 {
148    //FIXME:
149 }
150
151 static void
152 _text_set_hook(Elm_Object_Item *it, const char *part, const char *label)
153 {
154    ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
155
156    Eina_List *l = NULL;
157    Elm_Naviframe_Text_Item_Pair *pair = NULL;
158    Elm_Naviframe_Item *navi_it = ELM_CAST(it);
159    char buf[1024];
160
161    if (!part) return;
162
163    EINA_LIST_FOREACH(navi_it->text_list, l, pair)
164      {
165         if (!strcmp(part, pair->part))
166           {
167              if (pair->text)
168                {
169                   if (!strcmp(pair->text, label))
170                     return;
171                }
172              break;
173           }
174      }
175
176    if (!pair)
177      {
178         pair = ELM_NEW(Elm_Naviframe_Text_Item_Pair);
179         if (!pair)
180           {
181              ERR("Failed to allocate new text part of the item! : naviframe=%p", navi_it->base.widget);
182              return;
183           }
184         eina_stringshare_replace(&pair->part, part);
185         navi_it->text_list = eina_list_append(navi_it->text_list, pair);
186      }
187
188    eina_stringshare_replace(&pair->text, label);
189    edje_object_part_text_set(navi_it->base.view, part, label);
190
191    snprintf(buf, sizeof(buf), "elm,state,%s,show", part);
192
193    if (label)
194      edje_object_signal_emit(navi_it->base.view, buf, "elm");
195    else
196      edje_object_signal_emit(navi_it->base.view, buf, "elm");
197
198    _item_sizing_eval(navi_it);
199 }
200
201 static const char *
202 _text_get_hook(const Elm_Object_Item *it, const char *part)
203 {
204    ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
205    Eina_List *l = NULL;
206    Elm_Naviframe_Text_Item_Pair *pair = NULL;
207    Elm_Naviframe_Item *navi_it = ELM_CAST(it);
208
209    if (!part) return NULL;
210
211    EINA_LIST_FOREACH(navi_it->text_list, l, pair)
212      {
213         if (!strcmp(part, pair->part))
214           return pair->text;
215      }
216    return NULL;
217 }
218
219 static void
220 _content_set_hook(Elm_Object_Item *it,
221                   const char *part,
222                   Evas_Object *content)
223 {
224    ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
225
226    Elm_Naviframe_Content_Item_Pair *pair = NULL;
227    Elm_Naviframe_Item *navi_it = ELM_CAST(it);
228
229    if (!part) return;
230
231    //specified parts
232    if (!strcmp(part, "elm.swallow.content"))
233      {
234        _item_content_set(navi_it, content);
235        return;
236      }
237    else if (!strcmp(part, "elm.swallow.prev_btn"))
238      {
239        _title_prev_btn_set(navi_it, content, EINA_FALSE);
240        return;
241      }
242    else if(!strcmp(part, "elm.swallow.next_btn"))
243      {
244        _title_next_btn_set(navi_it, content);
245        return;
246      }
247
248    //common part
249    _title_content_set(navi_it, pair, part, content);
250 }
251
252 /*
253    */
254 static Evas_Object *
255 _content_get_hook(const Elm_Object_Item *it,
256                   const char *part)
257 {
258    ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
259    Eina_List *l = NULL;
260    Elm_Naviframe_Content_Item_Pair *pair = NULL;
261    Elm_Naviframe_Item *navi_it = ELM_CAST(it);
262
263    //specified parts 
264    if (!strcmp(part, "elm.swallow.content"))
265      return navi_it->content;
266    else if (!strcmp(part, "elm.swallow.prev_btn"))
267      return navi_it->title_prev_btn;
268    else if(!strcmp(part, "elm.swallow.next_btn"))
269      return navi_it->title_next_btn;
270
271    //common parts
272    EINA_LIST_FOREACH(navi_it->content_list, l, pair)
273      {
274         if (!strcmp(part, pair->part))
275           return pair->content;
276      }
277    return NULL;
278 }
279
280 static Evas_Object *
281 _content_unset_hook(Elm_Object_Item *it __UNUSED__,
282                     const char *part __UNUSED__)
283 {
284    ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
285    Eina_List *l = NULL;
286    Elm_Naviframe_Content_Item_Pair *pair = NULL;
287    Elm_Naviframe_Item *navi_it = ELM_CAST(it);
288    Evas_Object *content = NULL;
289    char buf[1028];
290
291   if (!part) return NULL;
292
293   //specified parts
294   //FIXME: could be unset the below specified contents also. 
295    if (!strcmp(part, "elm.swallow.content") ||
296        !strcmp(part, "elm.swallow.prev_btn") ||
297        !strcmp(part, "elm.swallow.next_btn"))
298      {
299         WRN("You can not unset the content! : naviframe=%p",
300             navi_it->base.widget);
301         return NULL;
302      }
303
304   //common parts
305    EINA_LIST_FOREACH(navi_it->content_list, l, pair)
306      {
307         if (!strcmp(part, pair->part))
308           {
309              content = pair->content;
310              eina_stringshare_del(pair->part);
311              navi_it->content_list = eina_list_remove(navi_it->content_list,
312                                                       pair);
313              free(pair);
314              break;
315           }
316      }
317
318    if (!content) return NULL;
319
320    elm_widget_sub_object_del(navi_it->base.widget, content);
321    edje_object_part_unswallow(navi_it->base.view, content);
322    snprintf(buf, sizeof(buf), "elm,state,%s,hide", part);
323    edje_object_signal_emit(navi_it->base.view, buf, "elm");
324    evas_object_event_callback_del(content,
325                                   EVAS_CALLBACK_DEL,
326                                   _title_content_del);
327    _item_sizing_eval(navi_it);
328
329    return content;
330 }
331
332 static void
333 _sizing_eval(Evas_Object *obj)
334 {
335    Widget_Data *wd;
336    Eina_List *list;
337    Elm_Naviframe_Item *it;
338    wd  = elm_widget_data_get(obj);
339    if (!wd) return;
340
341    list = eina_list_last(wd->stack);
342    if (!list) return;
343
344    EINA_LIST_FOREACH(wd->stack, list, it)
345      _item_sizing_eval(it);
346 }
347
348 static void
349 _item_sizing_eval(Elm_Naviframe_Item *it)
350 {
351    Widget_Data *wd;
352    Evas_Coord x, y, w, h;
353    if (!it) return;
354
355    wd = elm_widget_data_get(it->base.widget);
356    if (!wd) return;
357
358    evas_object_geometry_get(it->base.widget, &x, &y, &w, &h);
359    evas_object_move(it->base.view, x, y);
360    evas_object_resize(it->base.view, w, h);
361 }
362
363 static void
364 _move(void *data __UNUSED__,
365       Evas *e __UNUSED__,
366       Evas_Object *obj,
367       void *event_info __UNUSED__)
368 {
369    _sizing_eval(obj);
370 }
371
372 static void
373 _resize(void *data __UNUSED__,
374         Evas *e __UNUSED__,
375         Evas_Object *obj,
376         void *event_info __UNUSED__)
377 {
378    _sizing_eval(obj);
379 }
380
381 static void
382 _title_clicked(void *data,
383                Evas_Object *obj __UNUSED__,
384                const char *emission __UNUSED__,
385                const char *source __UNUSED__)
386 {
387    Elm_Naviframe_Item *it = data;
388    evas_object_smart_callback_call(it->base.widget, SIG_TITLE_CLICKED, it);
389 }
390
391 static void
392 _back_btn_clicked(void *data,
393                   Evas_Object *obj __UNUSED__,
394                   void *event_info __UNUSED__)
395 {
396    elm_naviframe_item_pop(data);
397 }
398
399 static Evas_Object *
400 _back_btn_new(Evas_Object *obj)
401 {
402    Evas_Object *btn;
403    char buf[1024];
404    btn = elm_button_add(obj);
405    if (!btn) return NULL;
406    evas_object_smart_callback_add(btn, "clicked", _back_btn_clicked, obj);
407    snprintf(buf, sizeof(buf), "naviframe/back_btn/%s", elm_widget_style_get(obj));
408    elm_object_style_set(btn, buf);
409    return btn;
410 }
411
412 static void
413 _title_content_del(void *data,
414                    Evas *e __UNUSED__,
415                    Evas_Object *obj __UNUSED__,
416                    void *event_info __UNUSED__)
417 {
418    char buf[1024];
419    Elm_Naviframe_Content_Item_Pair *pair = data;
420    Elm_Naviframe_Item *it = pair->it;
421    snprintf(buf, sizeof(buf), "elm,state,%s,hide", pair->part);
422    edje_object_signal_emit(it->base.view, buf, "elm");
423    it->content_list = eina_list_remove(it->content_list, pair);
424    eina_stringshare_del(pair->part);
425    free(pair);
426 }
427
428 static void
429 _title_prev_btn_del(void *data,
430                     Evas *e __UNUSED__,
431                     Evas_Object *obj __UNUSED__,
432                     void *event_info __UNUSED__)
433 {
434    Elm_Naviframe_Item *it = data;
435    it->back_btn = EINA_FALSE;
436    it->title_prev_btn = NULL;
437 }
438
439 static void
440 _title_next_btn_del(void *data,
441                     Evas *e __UNUSED__,
442                     Evas_Object *obj __UNUSED__,
443                     void *event_info __UNUSED__)
444 {
445    Elm_Naviframe_Item *it = data;
446    it->title_next_btn = NULL;
447 }
448
449 static void
450 _item_content_del(void *data,
451                   Evas *e __UNUSED__,
452                   Evas_Object *obj __UNUSED__,
453                   void *event_info __UNUSED__)
454 {
455    Elm_Naviframe_Item *it = data;
456    it->content = NULL;
457    edje_object_signal_emit(it->base.view, "elm,state,content,hide", "elm");
458 }
459
460 static void
461 _title_content_set(Elm_Naviframe_Item *it,
462                    Elm_Naviframe_Content_Item_Pair *pair,
463                    const char *part,
464                    Evas_Object *content)
465 {
466    Eina_List *l = NULL;
467    char buf[1024];
468
469    EINA_LIST_FOREACH(it->content_list, l, pair)
470      {
471         if (!strcmp(part, pair->part))
472           {
473              if (pair->content == content) return;
474              break;
475           }
476      }
477
478    if (!pair)
479      {
480         pair = ELM_NEW(Elm_Naviframe_Content_Item_Pair);
481         if (!pair)
482           {
483              ERR("Failed to allocate new content part of the item! : naviframe=%p", it->base.widget);
484              return;
485           }
486         pair->it = it;
487         eina_stringshare_replace(&pair->part, part);
488         it->content_list = eina_list_append(it->content_list, pair);
489      }
490
491    if (pair->content) evas_object_del(pair->content);
492    pair->content = content;
493
494    if (!content)
495      {
496         snprintf(buf, sizeof(buf), "elm,state,%s,hide", part);
497         edje_object_signal_emit(it->base.view, buf, "elm");
498         return;
499      }
500
501    elm_widget_sub_object_add(it->base.widget, content);
502    edje_object_part_swallow(it->base.view, part, content);
503    snprintf(buf, sizeof(buf), "elm,state,%s,show", part);
504    edje_object_signal_emit(it->base.view, buf, "elm");
505    evas_object_event_callback_add(content,
506                                   EVAS_CALLBACK_DEL,
507                                   _title_content_del,
508                                   pair);
509    _item_sizing_eval(it);
510 }
511
512 static void
513 _title_prev_btn_set(Elm_Naviframe_Item *it, Evas_Object *btn, Eina_Bool back_btn)
514 {
515    char buf[1024];
516
517    if (it->title_prev_btn == btn) return;
518
519    if (it->title_prev_btn)
520      evas_object_del(it->title_prev_btn);
521
522    it->title_prev_btn = btn;
523
524    if (!btn) return;
525
526    if (!back_btn)
527      {
528         snprintf(buf,
529                  sizeof(buf),
530                  "naviframe/prev_btn/%s",
531                  elm_widget_style_get(it->base.widget));
532         elm_object_style_set(btn, buf);
533      }
534    elm_widget_sub_object_add(it->base.widget, btn);
535    evas_object_event_callback_add(btn,
536                                   EVAS_CALLBACK_DEL,
537                                   _title_prev_btn_del,
538                                   it);
539    edje_object_part_swallow(it->base.view, "elm.swallow.prev_btn", btn);
540    it->back_btn = back_btn;
541
542    _item_sizing_eval(it);
543 }
544
545 static void
546 _title_next_btn_set(Elm_Naviframe_Item *it, Evas_Object *btn)
547 {
548    char buf[1024];
549
550    if (it->title_next_btn == btn) return;
551
552    if (it->title_next_btn)
553      evas_object_del(it->title_next_btn);
554
555    it->title_next_btn = btn;
556
557    if (!btn) return;
558
559    snprintf(buf,
560             sizeof(buf),
561             "naviframe/next_btn/%s",
562             elm_widget_style_get(it->base.widget));
563    elm_object_style_set(btn, buf);
564    elm_widget_sub_object_add(it->base.widget, btn);
565    evas_object_event_callback_add(btn,
566                                   EVAS_CALLBACK_DEL,
567                                   _title_next_btn_del,
568                                   it);
569    edje_object_part_swallow(it->base.view, "elm.swallow.next_btn", btn);
570
571    _item_sizing_eval(it);
572 }
573
574 static void
575 _item_del(Elm_Naviframe_Item *it)
576 {
577    Widget_Data *wd;
578    Eina_List *l;
579    Elm_Naviframe_Content_Item_Pair *content_pair;
580    Elm_Naviframe_Text_Item_Pair *text_pair;
581
582    if (!it) return;
583
584    wd = elm_widget_data_get(it->base.widget);
585    if (!wd) return;
586
587    if (it->title_prev_btn)
588      evas_object_del(it->title_prev_btn);
589    if (it->title_next_btn)
590      evas_object_del(it->title_next_btn);
591       if ((it->content) && (!wd->preserve))
592      evas_object_del(it->content);
593
594    EINA_LIST_FOREACH(it->content_list, l, content_pair)
595      evas_object_del(content_pair->content);
596
597    EINA_LIST_FOREACH(it->text_list, l, text_pair)
598      {
599         eina_stringshare_del(text_pair->part);
600         eina_stringshare_del(text_pair->text);
601      }
602
603    eina_list_free(it->content_list);
604    eina_list_free(it->text_list);
605
606    evas_object_del(it->base.view);
607
608    wd->stack = eina_list_remove(wd->stack, it);
609
610    free(it);
611 }
612
613 static void
614 _pushed_finished(void *data,
615                  Evas_Object *obj __UNUSED__,
616                  const char *emission __UNUSED__,
617                  const char *source __UNUSED__)
618 {
619    Elm_Naviframe_Item *it = data;
620    if (!it) return;
621    evas_object_hide(it->base.view);
622 }
623
624 static void
625 _popped_finished(void *data,
626                  Evas_Object *obj __UNUSED__,
627                  const char *emission __UNUSED__,
628                  const char *source __UNUSED__)
629 {
630    _item_del(data);
631 }
632
633 static void
634 _show_finished(void *data,
635                Evas_Object *obj __UNUSED__,
636                const char *emission __UNUSED__,
637                const char *source __UNUSED__)
638 {
639    Elm_Naviframe_Item *it;
640    Widget_Data *wd;
641
642    it = data;
643    if (!it) return;
644    wd =  elm_widget_data_get(it->base.widget);
645    if (!wd) return;
646
647    evas_object_smart_callback_call(it->base.widget,
648                                    SIG_TRANSITION_FINISHED,
649                                    (void *) EINA_TRUE);
650    if (wd->pass_events)
651      evas_object_pass_events_set(wd->base, EINA_FALSE);
652 }
653
654 static void
655 _item_content_set(Elm_Naviframe_Item *navi_it, Evas_Object *content)
656 {
657    if (navi_it->content == content) return;
658    if (navi_it->content) evas_object_del(navi_it->content);
659    elm_widget_sub_object_add(navi_it->base.widget, content);
660    edje_object_part_swallow(navi_it->base.view, "elm.swallow.content", content);
661    if (content)
662      edje_object_signal_emit(navi_it->base.view,
663                              "elm,state,content,show",
664                              "elm");
665    else
666      edje_object_signal_emit(navi_it->base.view,
667                              "elm,state,content,hide",
668                              "elm");
669    evas_object_event_callback_add(content,
670                                   EVAS_CALLBACK_DEL,
671                                   _item_content_del,
672                                   navi_it);
673    navi_it->content = content;
674    _item_sizing_eval(navi_it);
675 }
676
677 EAPI Evas_Object *
678 elm_naviframe_add(Evas_Object *parent)
679 {
680    Evas_Object *obj;
681    Evas *e;
682    Widget_Data *wd;
683
684    ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL);
685    ELM_SET_WIDTYPE(widtype, "naviframe");
686    elm_widget_type_set(obj, "naviframe");
687    elm_widget_sub_object_add(parent, obj);
688    elm_widget_data_set(obj, wd);
689    elm_widget_del_hook_set(obj, _del_hook);
690    elm_widget_disable_hook_set(obj, _disable_hook);
691    elm_widget_theme_hook_set(obj, _theme_hook);
692
693    //base
694    wd->base = edje_object_add(e);
695    elm_widget_resize_object_set(obj, wd->base);
696    _elm_theme_object_set(obj, wd->base, "naviframe", "base", "default");
697
698    evas_object_event_callback_add(obj, EVAS_CALLBACK_MOVE, _move, obj);
699    evas_object_event_callback_add(obj, EVAS_CALLBACK_RESIZE, _resize, obj);
700    evas_object_smart_callbacks_descriptions_set(obj, _signals);
701
702    wd->pass_events = EINA_TRUE;
703
704    return obj;
705 }
706
707 EAPI Elm_Object_Item *
708 elm_naviframe_item_push(Evas_Object *obj, const char *title_label, Evas_Object *prev_btn, Evas_Object *next_btn, Evas_Object *content, const char *item_style)
709 {
710    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
711    Widget_Data *wd;
712    Elm_Naviframe_Item *prev_it, *it;
713
714    wd = elm_widget_data_get(obj);
715    if (!wd) return NULL;
716
717    //create item
718    it = elm_widget_item_new(obj, Elm_Naviframe_Item);
719    if (!it)
720      {
721         ERR("Failed to allocate new item! : naviframe=%p", obj);
722         return NULL;
723      }
724
725    elm_widget_item_text_set_hook_set(it, _text_set_hook);
726    elm_widget_item_text_get_hook_set(it, _text_get_hook);
727    elm_widget_item_content_set_hook_set(it, _content_set_hook);
728    elm_widget_item_content_get_hook_set(it, _content_get_hook);
729    elm_widget_item_content_unset_hook_set(it, _content_unset_hook);
730
731    //item base layout
732    it->base.view = edje_object_add(evas_object_evas_get(obj));
733    evas_object_smart_member_add(it->base.view, wd->base);
734    elm_widget_sub_object_add(obj, it->base.view);
735    edje_object_signal_callback_add(it->base.view,
736                                    "elm,action,show,finished",
737                                    "",
738                                    _show_finished, it);
739    edje_object_signal_callback_add(it->base.view,
740                                    "elm,action,pushed,finished",
741                                    "",
742                                    _pushed_finished, it);
743    edje_object_signal_callback_add(it->base.view,
744                                    "elm,action,popped,finished",
745                                    "",
746                                    _popped_finished, it);
747    elm_naviframe_item_style_set(ELM_CAST(it), item_style);
748
749    //title
750    edje_object_signal_callback_add(it->base.view,
751                                    "elm,title,clicked",
752                                    "elm",
753                                    _title_clicked, it);
754
755    _text_set_hook(ELM_CAST(it), "elm.text.title", title_label);
756
757    //title buttons
758    if ((!prev_btn) && (eina_list_count(wd->stack)))
759      {
760         prev_btn = _back_btn_new(obj);
761         _title_prev_btn_set(it, prev_btn, EINA_TRUE);
762      }
763    else
764      _title_prev_btn_set(it, prev_btn, EINA_FALSE);
765
766    _title_next_btn_set(it, next_btn);
767
768    _item_content_set(it, content);
769
770    _item_sizing_eval(it);
771    evas_object_show(it->base.view);
772
773    prev_it = ELM_CAST(elm_naviframe_top_item_get(obj));
774    if (prev_it)
775      {
776         if (wd->pass_events)
777           evas_object_pass_events_set(wd->base, EINA_TRUE);
778         edje_object_signal_emit(prev_it->base.view,
779                                 "elm,state,pushed",
780                                 "elm");
781         edje_object_signal_emit(it->base.view,
782                                 "elm,state,show",
783                                 "elm");
784      }
785    else
786      edje_object_signal_emit(it->base.view, "elm,state,visible", "elm");
787    it->title_visible = EINA_TRUE;
788    wd->stack = eina_list_append(wd->stack, it);
789    return ELM_CAST(it);
790 }
791
792 EAPI Evas_Object *
793 elm_naviframe_item_pop(Evas_Object *obj)
794 {
795    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
796    Elm_Naviframe_Item *it, *prev_it;
797    Widget_Data *wd;
798    Evas_Object *content = NULL;
799
800    wd = elm_widget_data_get(obj);
801    if (!wd) return NULL;
802
803    it = ELM_CAST(elm_naviframe_top_item_get(obj));
804    if (!it) return NULL;
805    wd->stack = eina_list_remove(wd->stack, it);
806
807    if (wd->preserve)
808      content = it->content;
809
810    prev_it = ELM_CAST(elm_naviframe_top_item_get(obj));
811    if (prev_it)
812      {
813         if (wd->pass_events)
814           evas_object_pass_events_set(wd->base, EINA_TRUE);
815         evas_object_show(prev_it->base.view);
816         evas_object_raise(prev_it->base.view);
817         edje_object_signal_emit(prev_it->base.view,
818                                 "elm,state,show",
819                                 "elm");
820         edje_object_signal_emit(it->base.view, "elm,state,popped", "elm");
821      }
822    else
823      _item_del(it);
824
825    return content;
826 }
827
828 EAPI void
829 elm_naviframe_content_preserve_on_pop_set(Evas_Object *obj, Eina_Bool preserve)
830 {
831    ELM_CHECK_WIDTYPE(obj, widtype);
832    Widget_Data *wd = elm_widget_data_get(obj);
833    if (!wd) return;
834    wd->preserve = !!preserve;
835 }
836
837 EAPI Eina_Bool
838 elm_naviframe_content_preserve_on_pop_get(const Evas_Object *obj)
839 {
840    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
841    Widget_Data *wd = elm_widget_data_get(obj);
842    if (!wd) return EINA_FALSE;
843    return wd->preserve;
844 }
845
846 EAPI Elm_Object_Item*
847 elm_naviframe_top_item_get(const Evas_Object *obj)
848 {
849    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
850    Widget_Data *wd = elm_widget_data_get(obj);
851    if ((!wd) || (!wd->stack)) return NULL;
852    return eina_list_last(wd->stack)->data;
853 }
854
855 EAPI Elm_Object_Item*
856 elm_naviframe_bottom_item_get(const Evas_Object *obj)
857 {
858    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
859    Widget_Data *wd = elm_widget_data_get(obj);
860    if (!wd) return NULL;
861    return NULL;
862 }
863
864 EAPI void
865 elm_naviframe_item_style_set(Elm_Object_Item *it, const char *item_style)
866 {
867    ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
868    Elm_Naviframe_Item *navi_it = ELM_CAST(it);
869
870    char buf[256];
871
872    if (!item_style) sprintf(buf, "item/basic");
873    else
874      {
875         if (strlen(item_style) > sizeof(buf))
876           WRN("too much long style name! : naviframe=%p", navi_it->base.widget);
877         else
878           sprintf(buf, "item/%s", item_style);
879      }
880    _elm_theme_object_set(navi_it->base.widget,
881                          navi_it->base.view,
882                          "naviframe",
883                          buf,
884                          elm_widget_style_get(navi_it->base.widget));
885 }
886
887 EAPI const char *
888 elm_naviframe_item_style_get(const Elm_Object_Item *it)
889 {
890    ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
891    Elm_Naviframe_Item *navi_it = ELM_CAST(it);
892    return navi_it->style;
893 }
894
895 EAPI void
896 elm_naviframe_item_title_visible_set(Elm_Object_Item *it, Eina_Bool visible)
897 {
898    ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
899    Elm_Naviframe_Item *navi_it = ELM_CAST(it);
900
901    visible = !!visible;
902    if (navi_it->title_visible == visible) return;
903
904    if (visible)
905      edje_object_signal_emit(navi_it->base.view, "elm,state,title,show", "elm");
906    else
907      edje_object_signal_emit(navi_it->base.view, "elm,state,title,hide", "elm");
908
909    navi_it->title_visible = visible;
910 }
911
912 EAPI Eina_Bool
913 elm_naviframe_item_title_visible_get(const Elm_Object_Item *it)
914 {
915    ELM_OBJ_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
916    Elm_Naviframe_Item *navi_it = ELM_CAST(it);
917    return navi_it->title_visible;
918 }
919