Merge "partial merged with opensource for elm common APIs merged naviframe which...
[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    elm_widget_sub_object_add(it->base.widget, btn);
527    evas_object_event_callback_add(btn,
528                                   EVAS_CALLBACK_DEL,
529                                   _title_prev_btn_del,
530                                   it);
531    edje_object_part_swallow(it->base.view, "elm.swallow.prev_btn", btn);
532    it->back_btn = back_btn;
533
534    _item_sizing_eval(it);
535 }
536
537 static void
538 _title_next_btn_set(Elm_Naviframe_Item *it, Evas_Object *btn)
539 {
540    char buf[1024];
541
542    if (it->title_next_btn == btn) return;
543
544    if (it->title_next_btn)
545      evas_object_del(it->title_next_btn);
546
547    it->title_next_btn = btn;
548
549    if (!btn) return;
550
551    elm_object_style_set(btn, buf);
552    elm_widget_sub_object_add(it->base.widget, btn);
553    evas_object_event_callback_add(btn,
554                                   EVAS_CALLBACK_DEL,
555                                   _title_next_btn_del,
556                                   it);
557    edje_object_part_swallow(it->base.view, "elm.swallow.next_btn", btn);
558
559    _item_sizing_eval(it);
560 }
561
562 static void
563 _item_del(Elm_Naviframe_Item *it)
564 {
565    Widget_Data *wd;
566    Eina_List *l;
567    Elm_Naviframe_Content_Item_Pair *content_pair;
568    Elm_Naviframe_Text_Item_Pair *text_pair;
569
570    if (!it) return;
571
572    wd = elm_widget_data_get(it->base.widget);
573    if (!wd) return;
574
575    if (it->title_prev_btn)
576      evas_object_del(it->title_prev_btn);
577    if (it->title_next_btn)
578      evas_object_del(it->title_next_btn);
579       if ((it->content) && (!wd->preserve))
580      evas_object_del(it->content);
581
582    EINA_LIST_FOREACH(it->content_list, l, content_pair)
583      evas_object_del(content_pair->content);
584
585    EINA_LIST_FOREACH(it->text_list, l, text_pair)
586      {
587         eina_stringshare_del(text_pair->part);
588         eina_stringshare_del(text_pair->text);
589      }
590
591    eina_list_free(it->content_list);
592    eina_list_free(it->text_list);
593
594    evas_object_del(it->base.view);
595
596    wd->stack = eina_list_remove(wd->stack, it);
597
598    free(it);
599 }
600
601 static void
602 _pushed_finished(void *data,
603                  Evas_Object *obj __UNUSED__,
604                  const char *emission __UNUSED__,
605                  const char *source __UNUSED__)
606 {
607    Elm_Naviframe_Item *it = data;
608    if (!it) return;
609    evas_object_hide(it->base.view);
610 }
611
612 static void
613 _popped_finished(void *data,
614                  Evas_Object *obj __UNUSED__,
615                  const char *emission __UNUSED__,
616                  const char *source __UNUSED__)
617 {
618    _item_del(data);
619 }
620
621 static void
622 _show_finished(void *data,
623                Evas_Object *obj __UNUSED__,
624                const char *emission __UNUSED__,
625                const char *source __UNUSED__)
626 {
627    Elm_Naviframe_Item *it;
628    Widget_Data *wd;
629
630    it = data;
631    if (!it) return;
632    wd =  elm_widget_data_get(it->base.widget);
633    if (!wd) return;
634
635    evas_object_smart_callback_call(it->base.widget,
636                                    SIG_TRANSITION_FINISHED,
637                                    (void *) EINA_TRUE);
638    if (wd->pass_events)
639      evas_object_pass_events_set(wd->base, EINA_FALSE);
640 }
641
642 static void
643 _item_content_set(Elm_Naviframe_Item *navi_it, Evas_Object *content)
644 {
645    if (navi_it->content == content) return;
646    if (navi_it->content) evas_object_del(navi_it->content);
647    elm_widget_sub_object_add(navi_it->base.widget, content);
648    edje_object_part_swallow(navi_it->base.view, "elm.swallow.content", content);
649    if (content)
650      edje_object_signal_emit(navi_it->base.view,
651                              "elm,state,content,show",
652                              "elm");
653    else
654      edje_object_signal_emit(navi_it->base.view,
655                              "elm,state,content,hide",
656                              "elm");
657    evas_object_event_callback_add(content,
658                                   EVAS_CALLBACK_DEL,
659                                   _item_content_del,
660                                   navi_it);
661    navi_it->content = content;
662    _item_sizing_eval(navi_it);
663 }
664
665 EAPI Evas_Object *
666 elm_naviframe_add(Evas_Object *parent)
667 {
668    Evas_Object *obj;
669    Evas *e;
670    Widget_Data *wd;
671
672    ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL);
673    ELM_SET_WIDTYPE(widtype, "naviframe");
674    elm_widget_type_set(obj, "naviframe");
675    elm_widget_sub_object_add(parent, obj);
676    elm_widget_data_set(obj, wd);
677    elm_widget_del_hook_set(obj, _del_hook);
678    elm_widget_disable_hook_set(obj, _disable_hook);
679    elm_widget_theme_hook_set(obj, _theme_hook);
680
681    //base
682    wd->base = edje_object_add(e);
683    elm_widget_resize_object_set(obj, wd->base);
684    _elm_theme_object_set(obj, wd->base, "naviframe", "base", "default");
685
686    evas_object_event_callback_add(obj, EVAS_CALLBACK_MOVE, _move, obj);
687    evas_object_event_callback_add(obj, EVAS_CALLBACK_RESIZE, _resize, obj);
688    evas_object_smart_callbacks_descriptions_set(obj, _signals);
689
690    wd->pass_events = EINA_TRUE;
691
692    return obj;
693 }
694
695 EAPI Elm_Object_Item *
696 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)
697 {
698    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
699    Widget_Data *wd;
700    Elm_Naviframe_Item *prev_it, *it;
701
702    wd = elm_widget_data_get(obj);
703    if (!wd) return NULL;
704
705    //create item
706    it = elm_widget_item_new(obj, Elm_Naviframe_Item);
707    if (!it)
708      {
709         ERR("Failed to allocate new item! : naviframe=%p", obj);
710         return NULL;
711      }
712
713    elm_widget_item_text_set_hook_set(it, _text_set_hook);
714    elm_widget_item_text_get_hook_set(it, _text_get_hook);
715    elm_widget_item_content_set_hook_set(it, _content_set_hook);
716    elm_widget_item_content_get_hook_set(it, _content_get_hook);
717    elm_widget_item_content_unset_hook_set(it, _content_unset_hook);
718
719    //item base layout
720    it->base.view = edje_object_add(evas_object_evas_get(obj));
721    evas_object_smart_member_add(it->base.view, wd->base);
722    elm_widget_sub_object_add(obj, it->base.view);
723    edje_object_signal_callback_add(it->base.view,
724                                    "elm,action,show,finished",
725                                    "",
726                                    _show_finished, it);
727    edje_object_signal_callback_add(it->base.view,
728                                    "elm,action,pushed,finished",
729                                    "",
730                                    _pushed_finished, it);
731    edje_object_signal_callback_add(it->base.view,
732                                    "elm,action,popped,finished",
733                                    "",
734                                    _popped_finished, it);
735    elm_naviframe_item_style_set(ELM_CAST(it), item_style);
736
737    //title
738    edje_object_signal_callback_add(it->base.view,
739                                    "elm,title,clicked",
740                                    "elm",
741                                    _title_clicked, it);
742
743    _text_set_hook(ELM_CAST(it), "elm.text.title", title_label);
744
745    //title buttons
746    if ((!prev_btn) && (eina_list_count(wd->stack)))
747      {
748         prev_btn = _back_btn_new(obj);
749         _title_prev_btn_set(it, prev_btn, EINA_TRUE);
750      }
751    else
752      _title_prev_btn_set(it, prev_btn, EINA_FALSE);
753
754    _title_next_btn_set(it, next_btn);
755
756    _item_content_set(it, content);
757
758    _item_sizing_eval(it);
759    evas_object_show(it->base.view);
760
761    prev_it = ELM_CAST(elm_naviframe_top_item_get(obj));
762    if (prev_it)
763      {
764         if (wd->pass_events)
765           evas_object_pass_events_set(wd->base, EINA_TRUE);
766         edje_object_signal_emit(prev_it->base.view,
767                                 "elm,state,pushed",
768                                 "elm");
769         edje_object_signal_emit(it->base.view,
770                                 "elm,state,show",
771                                 "elm");
772      }
773    else
774      edje_object_signal_emit(it->base.view, "elm,state,visible", "elm");
775    it->title_visible = EINA_TRUE;
776    wd->stack = eina_list_append(wd->stack, it);
777    return ELM_CAST(it);
778 }
779
780 EAPI Evas_Object *
781 elm_naviframe_item_pop(Evas_Object *obj)
782 {
783    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
784    Elm_Naviframe_Item *it, *prev_it;
785    Widget_Data *wd;
786    Evas_Object *content = NULL;
787
788    wd = elm_widget_data_get(obj);
789    if (!wd) return NULL;
790
791    it = ELM_CAST(elm_naviframe_top_item_get(obj));
792    if (!it) return NULL;
793    wd->stack = eina_list_remove(wd->stack, it);
794
795    if (wd->preserve)
796      content = it->content;
797
798    prev_it = ELM_CAST(elm_naviframe_top_item_get(obj));
799    if (prev_it)
800      {
801         if (wd->pass_events)
802           evas_object_pass_events_set(wd->base, EINA_TRUE);
803         evas_object_show(prev_it->base.view);
804         evas_object_raise(prev_it->base.view);
805         edje_object_signal_emit(prev_it->base.view,
806                                 "elm,state,show",
807                                 "elm");
808         edje_object_signal_emit(it->base.view, "elm,state,popped", "elm");
809      }
810    else
811      _item_del(it);
812
813    return content;
814 }
815
816 EAPI void
817 elm_naviframe_content_preserve_on_pop_set(Evas_Object *obj, Eina_Bool preserve)
818 {
819    ELM_CHECK_WIDTYPE(obj, widtype);
820    Widget_Data *wd = elm_widget_data_get(obj);
821    if (!wd) return;
822    wd->preserve = !!preserve;
823 }
824
825 EAPI Eina_Bool
826 elm_naviframe_content_preserve_on_pop_get(const Evas_Object *obj)
827 {
828    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
829    Widget_Data *wd = elm_widget_data_get(obj);
830    if (!wd) return EINA_FALSE;
831    return wd->preserve;
832 }
833
834 EAPI Elm_Object_Item*
835 elm_naviframe_top_item_get(const Evas_Object *obj)
836 {
837    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
838    Widget_Data *wd = elm_widget_data_get(obj);
839    if ((!wd) || (!wd->stack)) return NULL;
840    return eina_list_last(wd->stack)->data;
841 }
842
843 EAPI Elm_Object_Item*
844 elm_naviframe_bottom_item_get(const Evas_Object *obj)
845 {
846    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
847    Widget_Data *wd = elm_widget_data_get(obj);
848    if (!wd) return NULL;
849    return NULL;
850 }
851
852 EAPI void
853 elm_naviframe_item_style_set(Elm_Object_Item *it, const char *item_style)
854 {
855    ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
856    Elm_Naviframe_Item *navi_it = ELM_CAST(it);
857
858    char buf[256];
859
860    if (!item_style) sprintf(buf, "item/basic");
861    else
862      {
863         if (strlen(item_style) > sizeof(buf))
864           WRN("too much long style name! : naviframe=%p", navi_it->base.widget);
865         else
866           sprintf(buf, "item/%s", item_style);
867      }
868    _elm_theme_object_set(navi_it->base.widget,
869                          navi_it->base.view,
870                          "naviframe",
871                          buf,
872                          elm_widget_style_get(navi_it->base.widget));
873 }
874
875 EAPI const char *
876 elm_naviframe_item_style_get(const Elm_Object_Item *it)
877 {
878    ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
879    Elm_Naviframe_Item *navi_it = ELM_CAST(it);
880    return navi_it->style;
881 }
882
883 EAPI void
884 elm_naviframe_item_title_visible_set(Elm_Object_Item *it, Eina_Bool visible)
885 {
886    ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
887    Elm_Naviframe_Item *navi_it = ELM_CAST(it);
888
889    visible = !!visible;
890    if (navi_it->title_visible == visible) return;
891
892    if (visible)
893      edje_object_signal_emit(navi_it->base.view, "elm,state,title,show", "elm");
894    else
895      edje_object_signal_emit(navi_it->base.view, "elm,state,title,hide", "elm");
896
897    navi_it->title_visible = visible;
898 }
899
900 EAPI Eina_Bool
901 elm_naviframe_item_title_visible_get(const Elm_Object_Item *it)
902 {
903    ELM_OBJ_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
904    Elm_Naviframe_Item *navi_it = ELM_CAST(it);
905    return navi_it->title_visible;
906 }
907