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