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