tizen 2.3.1 release
[framework/uifw/elementary.git] / src / lib / elc_naviframe.c
1 #include <Elementary.h>
2 #include "elm_priv.h"
3 #include "elm_widget_naviframe.h"
4
5 #define KEY_END "XF86Stop"         //Tizen Only
6 #define KEY_MENU "XF86Send"        //Tizen Only
7
8 EAPI const char ELM_NAVIFRAME_SMART_NAME[] = "elm_naviframe";
9
10 static const char CONTENT_PART[] = "elm.swallow.content";
11 static const char PREV_BTN_PART[] = "elm.swallow.prev_btn";
12 static const char NEXT_BTN_PART[] = "elm.swallow.next_btn";
13 static const char ICON_PART[] = "elm.swallow.icon";
14 static const char TITLE_PART[] = "elm.text.title";
15 static const char SUBTITLE_PART[] = "elm.text.subtitle";
16 static const char TITLE_ACCESS_PART[] = "access.title";
17
18 static const char SIG_LANG_CHANGED[] = "language,changed";
19 static const char SIG_TRANSITION_FINISHED[] = "transition,finished";
20 static const char SIG_TITLE_TRANSITION_FINISHED[] = "title,transition,finished";
21 static const char SIG_TITLE_CLICKED[] = "title,clicked";
22 static const char SIG_ACCESS_CHANGED[] = "access,changed";
23 static const Evas_Smart_Cb_Description _smart_callbacks[] = {
24    {SIG_LANG_CHANGED, ""},
25    {SIG_TRANSITION_FINISHED, ""},
26    {SIG_TITLE_TRANSITION_FINISHED, ""},
27    {SIG_TITLE_CLICKED, ""},
28    {SIG_ACCESS_CHANGED, ""},
29    {NULL, NULL}
30 };
31
32 EVAS_SMART_SUBCLASS_NEW
33   (ELM_NAVIFRAME_SMART_NAME, _elm_naviframe, Elm_Naviframe_Smart_Class,
34   Elm_Layout_Smart_Class, elm_layout_smart_class_get, _smart_callbacks);
35
36 static const char SIG_CLICKED[] = "clicked";
37
38 static int initted = 0;
39 static Elm_Naviframe_Mod_Api *nf_mod = NULL;
40
41 static Elm_Naviframe_Mod_Api *
42 _nf_mod_init(void)
43 {
44    Elm_Module *mod;
45    initted++;
46    ERR("_nf_mod_init initted %d", initted);
47    if (initted > 1) return;
48    if (!(mod = _elm_module_find_as("naviframe/api"))) return;
49
50    mod->api = malloc(sizeof(Elm_Naviframe_Mod_Api));
51    if (!mod->api) return;
52
53    ((Elm_Naviframe_Mod_Api *)(mod->api))->tizen_push_effect = 
54       _elm_module_symbol_get(mod, "tizen_push_effect");
55    ((Elm_Naviframe_Mod_Api *)(mod->api))->tizen_pop_effect =
56       _elm_module_symbol_get(mod, "tizen_pop_effect");
57    return mod->api;
58 }
59
60 static void _on_item_back_btn_clicked(void *data, Evas_Object *obj, void *event_info __UNUSED__);
61 static void _access_focus_set(Elm_Naviframe_Item *it);
62
63 static void
64 _resize_object_reset(Evas_Object *obj, Elm_Naviframe_Item *it)
65 {
66    if (it)
67      {
68         elm_widget_resize_object_set(obj, VIEW(it), EINA_FALSE);
69         evas_object_raise(VIEW(it));
70      }
71 }
72
73 static void
74 _prev_page_focus_recover(Elm_Naviframe_Item *it)
75 {
76    Evas_Object *newest;
77    unsigned int order = 0;
78
79    ELM_WIDGET_DATA_GET(VIEW(it), sd);
80    order = sd->focus_order;
81
82    if (_elm_config->access_mode)
83      _access_focus_set(it);
84    else
85      {
86         newest = elm_widget_newest_focus_order_get(VIEW(it), &order, EINA_TRUE);
87         if (newest)
88           elm_object_focus_set(newest, EINA_TRUE);
89         else
90           {
91              if (elm_object_focus_allow_get(VIEW(it)))
92                elm_object_focus_set(VIEW(it), EINA_TRUE);
93              else
94                elm_object_focus_set(WIDGET(it), EINA_TRUE);
95           }
96      }
97 }
98
99 static Eina_Bool
100 _elm_naviframe_smart_translate(Evas_Object *obj)
101 {
102    ELM_NAVIFRAME_DATA_GET(obj, sd);
103    Elm_Naviframe_Item *it;
104
105    EINA_INLIST_FOREACH(sd->stack, it)
106      elm_widget_item_translate(it);
107
108    evas_object_smart_callback_call(obj, SIG_LANG_CHANGED, NULL);
109
110    return EINA_TRUE;
111 }
112
113 static void
114 _item_content_del_cb(void *data,
115                      Evas *e __UNUSED__,
116                      Evas_Object *obj __UNUSED__,
117                      void *event_info __UNUSED__)
118 {
119    Elm_Naviframe_Item *it = data;
120
121    it->content = NULL;
122    elm_object_signal_emit(VIEW(it), "elm,state,content,hide", "elm");
123 }
124
125 static void
126 _item_title_prev_btn_del_cb(void *data,
127                             Evas *e __UNUSED__,
128                             Evas_Object *obj __UNUSED__,
129                             void *event_info __UNUSED__)
130 {
131    Elm_Naviframe_Item *it = data;
132
133    it->title_prev_btn = NULL;
134    elm_object_signal_emit(VIEW(it), "elm,state,prev_btn,hide", "elm");
135 }
136
137 static void
138 _item_title_next_btn_del_cb(void *data,
139                             Evas *e __UNUSED__,
140                             Evas_Object *obj __UNUSED__,
141                             void *event_info __UNUSED__)
142 {
143    Elm_Naviframe_Item *it = data;
144
145    it->title_next_btn = NULL;
146    elm_object_signal_emit(VIEW(it), "elm,state,next_btn,hide", "elm");
147 }
148
149 static void
150 _item_title_icon_del_cb(void *data,
151                         Evas *e __UNUSED__,
152                         Evas_Object *obj __UNUSED__,
153                         void *event_info __UNUSED__)
154 {
155    Elm_Naviframe_Item *it = data;
156
157    it->title_icon = NULL;
158    elm_object_signal_emit(VIEW(it), "elm,state,icon,hide", "elm");
159 }
160
161 static void
162 _title_content_del(void *data,
163                    Evas *e __UNUSED__,
164                    Evas_Object *obj __UNUSED__,
165                    void *event_info __UNUSED__)
166 {
167    char buf[1024];
168    Elm_Naviframe_Content_Item_Pair *pair = data;
169    Elm_Naviframe_Item *it = pair->it;
170    snprintf(buf, sizeof(buf), "elm,state,%s,hide", pair->part);
171    elm_object_signal_emit(VIEW(it), buf, "elm");
172    it->content_list = eina_inlist_remove(it->content_list,
173                                          EINA_INLIST_GET(pair));
174    eina_stringshare_del(pair->part);
175    free(pair);
176 }
177
178 static void
179 _item_free(Elm_Naviframe_Item *it)
180 {
181    Eina_Inlist *l;
182    Elm_Naviframe_Content_Item_Pair *content_pair = NULL;
183    Elm_Naviframe_Text_Item_Pair *text_pair = NULL;
184
185    ELM_NAVIFRAME_DATA_GET(WIDGET(it), sd);
186
187    eina_stringshare_del(it->style);
188    eina_stringshare_del(it->title_label);
189    eina_stringshare_del(it->subtitle_label);
190
191    EINA_INLIST_FOREACH_SAFE(it->content_list, l, content_pair)
192      {
193         if (content_pair->content)
194           {
195              evas_object_event_callback_del(content_pair->content,
196                                             EVAS_CALLBACK_DEL,
197                                             _title_content_del);
198              evas_object_del(content_pair->content);
199           }
200         eina_stringshare_del(content_pair->part);
201         free(content_pair);
202         content_pair = NULL;
203      }
204    EINA_INLIST_FOREACH_SAFE(it->text_list, l, text_pair)
205      {
206         eina_stringshare_del(text_pair->part);
207         free(text_pair);
208         text_pair = NULL;
209      }
210
211    if (it->content)
212      {
213         if ((sd->preserve) && (!sd->on_deletion))
214           {
215              /* so that elm does not delete the contents with the item's
216               * view after the del_pre_hook */
217              elm_object_part_content_unset(VIEW(it), CONTENT_PART);
218              evas_object_event_callback_del
219                 (it->content, EVAS_CALLBACK_DEL, _item_content_del_cb);
220           }
221      }
222 }
223
224 static void
225 _item_content_signals_emit(Elm_Naviframe_Item *it)
226 {
227    Elm_Naviframe_Content_Item_Pair *content_pair;
228    char buf[1024];
229    //content
230    if (it->content)
231      elm_object_signal_emit(VIEW(it), "elm,state,content,show", "elm");
232    else
233      elm_object_signal_emit(VIEW(it), "elm,state,content,hide", "elm");
234
235    //prev button
236    if (it->title_prev_btn)
237      elm_object_signal_emit(VIEW(it), "elm,state,prev_btn,show", "elm");
238    else
239      elm_object_signal_emit(VIEW(it), "elm,state,prev_btn,hide", "elm");
240
241    //next button
242    if (it->title_next_btn)
243      elm_object_signal_emit(VIEW(it), "elm,state,next_btn,show", "elm");
244    else
245      elm_object_signal_emit(VIEW(it), "elm,state,next_btn,hide", "elm");
246
247    if (it->title_icon)
248      elm_object_signal_emit(VIEW(it), "elm,state,icon,show", "elm");
249    else
250      elm_object_signal_emit(VIEW(it), "elm,state,icon,hide", "elm");
251
252    EINA_INLIST_FOREACH(it->content_list, content_pair)
253      {
254         if (content_pair->content)
255           snprintf(buf, sizeof(buf), "elm,state,%s,show", content_pair->part);
256         else
257           snprintf(buf, sizeof(buf), "elm,state,%s,hide", content_pair->part);
258         elm_object_signal_emit(VIEW(it), buf, "elm");
259      }
260 }
261
262 static void
263 _item_text_signals_emit(Elm_Naviframe_Item *it)
264 {
265    Elm_Naviframe_Text_Item_Pair *text_pair;
266    const char *text;
267    char buf[1024];
268
269    if ((it->title_label) && (it->title_label[0]))
270      elm_object_signal_emit(VIEW(it), "elm,state,title_label,show", "elm");
271    else
272      elm_object_signal_emit(VIEW(it), "elm,state,title_label,hide", "elm");
273
274    if ((it->subtitle_label) && (it->subtitle_label[0]))
275      elm_object_signal_emit(VIEW(it), "elm,state,subtitle,show", "elm");
276    else
277      elm_object_signal_emit(VIEW(it), "elm,state,subtitle,hide", "elm");
278
279    EINA_INLIST_FOREACH(it->text_list, text_pair)
280      {
281         text = elm_object_part_text_get(VIEW(it), text_pair->part);
282         if (text && strlen(text))
283           snprintf(buf, sizeof(buf), "elm,state,%s,show", text_pair->part);
284         else
285           snprintf(buf, sizeof(buf), "elm,state,%s,hide", text_pair->part);
286         elm_object_signal_emit(VIEW(it), buf, "elm");
287      }
288 }
289
290 static void
291 _access_focus_set(Elm_Naviframe_Item *it)
292 {
293    Evas_Object *ao;
294
295    if (elm_widget_tree_unfocusable_get(VIEW(it))) return;
296
297    ao = ((Elm_Widget_Item *)it)->access_obj;
298
299    if (ao && it->title_enabled)
300      _elm_access_highlight_set(ao, EINA_TRUE);
301    else
302      {
303         if (!elm_widget_highlight_get(VIEW(it)))
304           _elm_access_highlight_cycle(VIEW(it), ELM_ACCESS_ACTION_HIGHLIGHT_NEXT);
305      }
306 }
307
308 static void
309 _item_signals_emit(Elm_Naviframe_Item *it)
310 {
311    _item_text_signals_emit(it);
312    _item_content_signals_emit(it);
313 }
314
315 /* FIXME: we need to handle the case when this function is called
316  * during a transition */
317 static void
318 _item_style_set(Elm_Naviframe_Item *it,
319                 const char *item_style)
320 {
321    char buf[256];
322
323    ELM_NAVIFRAME_DATA_GET(WIDGET(it), sd);
324
325    if (!item_style)
326      {
327         strcpy(buf, "item/basic");
328         eina_stringshare_replace(&it->style, "basic");
329      }
330    else
331      {
332         snprintf(buf, sizeof(buf), "item/%s", item_style);
333         eina_stringshare_replace(&it->style, item_style);
334      }
335
336    elm_layout_theme_set(VIEW(it), "naviframe", buf,
337                         elm_widget_style_get(WIDGET(it)));
338    edje_object_message_signal_process(elm_layout_edje_get(VIEW(it)));
339
340    if (sd->freeze_events)
341      evas_object_freeze_events_set(VIEW(it), EINA_FALSE);
342
343    //Tizen Only
344    char *tizen_zoom =
345       (char *)edje_object_data_get(elm_layout_edje_get(VIEW(it)), "tizen_zoom");
346    if (tizen_zoom) it->tizen_zoom = atoi(tizen_zoom);
347 }
348
349 static void
350 _on_item_title_transition_finished(void *data,
351                                    Evas_Object *obj __UNUSED__,
352                                    const char *emission __UNUSED__,
353                                    const char *source __UNUSED__)
354 {
355    Elm_Naviframe_Item *it = data;
356
357    evas_object_smart_callback_call(WIDGET(it), SIG_TITLE_TRANSITION_FINISHED, data);
358 }
359
360 static void
361 _item_title_enabled_update(Elm_Naviframe_Item *nit, Eina_Bool transition)
362 {
363    transition = !!transition;
364    if (transition)
365      {
366         if (nit->title_enabled)
367           elm_object_signal_emit(VIEW(nit), "elm,action,title,show", "elm");
368         else
369           elm_object_signal_emit(VIEW(nit), "elm,action,title,hide", "elm");
370      }
371    else
372      {
373         if (nit->title_enabled)
374           elm_object_signal_emit(VIEW(nit), "elm,state,title,show", "elm");
375         else
376           elm_object_signal_emit(VIEW(nit), "elm,state,title,hide", "elm");
377      }
378    edje_object_message_signal_process(elm_layout_edje_get(VIEW(nit)));
379 }
380
381 static Eina_Bool
382 _elm_naviframe_smart_theme(Evas_Object *obj)
383 {
384    Elm_Naviframe_Item *it;
385    const char *style, *sstyle;
386
387    ELM_NAVIFRAME_DATA_GET(obj, sd);
388
389    style = elm_widget_style_get(obj);
390
391    EINA_INLIST_FOREACH(sd->stack, it)
392      {
393         sstyle = elm_widget_style_get(VIEW(it));
394         if ((style && sstyle) && strcmp(style, sstyle))
395           _item_style_set(it, it->style);
396         _item_signals_emit(it);
397         _item_title_enabled_update(it, EINA_FALSE);
398      }
399
400    elm_layout_sizing_eval(obj);
401
402    return EINA_TRUE;
403 }
404
405 static char *
406 _access_info_cb(void *data, Evas_Object *obj __UNUSED__)
407 {
408    Evas_Object *layout;
409    Elm_Naviframe_Item *nit;
410    Eina_Strbuf *buf;
411    const char *info;
412    char *ret;
413
414    nit = data;
415
416    if (!nit->title_enabled) return NULL;
417
418    layout = VIEW(nit);
419    info = elm_object_part_text_get(layout, TITLE_PART);
420    if (!info) return NULL;
421
422    buf = eina_strbuf_new();
423    eina_strbuf_append(buf, info);
424
425    info = elm_object_part_text_get(layout, SUBTITLE_PART);
426    if (!info) goto end;
427
428    eina_strbuf_append_printf(buf, ", %s", info);
429
430 end:
431    ret = eina_strbuf_string_steal(buf);
432    eina_strbuf_free(buf);
433    return ret;
434 }
435
436 static void
437 _access_obj_process(Elm_Naviframe_Item *it, Eina_Bool is_access)
438 {
439    Evas_Object *ao, *eo;
440
441    if (is_access && (it->title_label || it->subtitle_label))
442      {
443         ao = ((Elm_Widget_Item *)it)->access_obj;
444
445         if (!ao)
446           {
447              eo = elm_layout_edje_get(VIEW(it));
448              ao =_elm_access_edje_object_part_object_register(VIEW(it), eo,
449                                                               TITLE_ACCESS_PART);
450              _elm_access_callback_set(_elm_access_object_get(ao),
451                                       ELM_ACCESS_INFO, _access_info_cb, it);
452
453              /* to access title access object, any idea? */
454              ((Elm_Widget_Item *)it)->access_obj = ao;
455           }
456      }
457    else
458      {
459         /* to access title access object, any idea? */
460         ao = ((Elm_Widget_Item *)it)->access_obj;
461         if (!ao) return;
462
463         if (it->title_label || it->subtitle_label)
464           {
465              _elm_access_edje_object_part_object_unregister
466                (VIEW(it), elm_layout_edje_get(VIEW(it)), TITLE_ACCESS_PART);
467
468              /* deletion of access object occurs in
469                 _elm_access_edje_object_part_object_unregister(); */
470              ((Elm_Widget_Item *)it)->access_obj = NULL;
471           }
472      }
473 }
474
475 static void
476 _item_text_set_hook(Elm_Object_Item *it,
477                     const char *part,
478                     const char *label)
479 {
480    Elm_Naviframe_Item *nit = (Elm_Naviframe_Item *)it;
481    Elm_Naviframe_Text_Item_Pair *pair = NULL;
482    char buf[1024];
483
484    if ((!part) || (!strcmp(part, "default")) ||
485        (!strcmp(part, TITLE_PART)))
486      {
487         eina_stringshare_replace(&nit->title_label, label);
488         if (label)
489           elm_object_signal_emit(VIEW(it), "elm,state,title_label,show", "elm");
490         else
491           elm_object_signal_emit(VIEW(it), "elm,state,title_label,hide", "elm");
492         elm_object_part_text_set(VIEW(it), TITLE_PART, label);
493      }
494    else if (!strcmp("subtitle", part))
495      {
496         eina_stringshare_replace(&nit->subtitle_label, label);
497         if (label)
498           elm_object_signal_emit(VIEW(it), "elm,state,subtitle,show", "elm");
499         else
500           elm_object_signal_emit(VIEW(it), "elm,state,subtitle,hide", "elm");
501         elm_object_part_text_set(VIEW(it), SUBTITLE_PART, label);
502      }
503    else
504      {
505         EINA_INLIST_FOREACH(nit->text_list, pair)
506           if (!strcmp(part, pair->part)) break;
507
508         if (!pair)
509           {
510              pair = ELM_NEW(Elm_Naviframe_Text_Item_Pair);
511              if (!pair)
512                {
513                   ERR("Failed to allocate new text part of the item! : naviframe=%p",
514                   WIDGET(it));
515                   return;
516                }
517              eina_stringshare_replace(&pair->part, part);
518              nit->text_list = eina_inlist_append(nit->text_list,
519                                                  EINA_INLIST_GET(pair));
520           }
521         if (label)
522           {
523              snprintf(buf, sizeof(buf), "elm,state,%s,show", part);
524              elm_object_part_text_set(VIEW(it), part, label);
525           }
526         else
527           {
528              snprintf(buf, sizeof(buf), "elm,state,%s,hide", part);
529              elm_object_part_text_set(VIEW(it), part, "");
530           }
531         elm_object_signal_emit(VIEW(it), buf, "elm");
532      }
533
534    /* access */
535    if (_elm_config->access_mode)
536      _access_obj_process(nit, EINA_TRUE);
537
538    elm_layout_sizing_eval(WIDGET(nit));
539 }
540
541 static const char *
542 _item_text_get_hook(const Elm_Object_Item *it,
543                     const char *part)
544 {
545    char buf[1024];
546
547    if (!part || !strcmp(part, "default"))
548      snprintf(buf, sizeof(buf), TITLE_PART);
549    else if (!strcmp("subtitle", part))
550      snprintf(buf, sizeof(buf), SUBTITLE_PART);
551    else
552      snprintf(buf, sizeof(buf), "%s", part);
553
554    return elm_object_part_text_get(VIEW(it), buf);
555 }
556
557 static Eina_Bool
558 _item_del_pre_hook(Elm_Object_Item *it)
559 {
560    Elm_Naviframe_Item *nit, *prev_it = NULL;
561    Eina_Bool top;
562
563    nit = (Elm_Naviframe_Item *)it;
564    ELM_NAVIFRAME_DATA_GET(WIDGET(nit), sd);
565
566    nit->delete_me = EINA_TRUE;
567    if (nit->ref > 0) return EINA_FALSE;
568
569    if (nit->animator) ecore_animator_del(nit->animator);
570
571    top = (it == elm_naviframe_top_item_get(WIDGET(nit)));
572    if (evas_object_data_get(VIEW(nit), "out_of_list"))
573      goto end;
574
575    sd->stack = eina_inlist_remove(sd->stack, EINA_INLIST_GET(nit));
576
577    if (top && !sd->on_deletion) /* must raise another one */
578      {
579         if (sd->stack && sd->stack->last)
580           prev_it = EINA_INLIST_CONTAINER_GET(sd->stack->last,
581                                               Elm_Naviframe_Item);
582         if (!prev_it) goto end;
583
584         elm_widget_tree_unfocusable_set(VIEW(prev_it), EINA_FALSE);
585         elm_widget_tree_unfocusable_set(VIEW(nit), EINA_TRUE);
586
587         if (sd->freeze_events)
588           evas_object_freeze_events_set(VIEW(prev_it), EINA_FALSE);
589         _resize_object_reset(WIDGET(prev_it), prev_it);
590         evas_object_show(VIEW(prev_it));
591
592         _prev_page_focus_recover(prev_it);
593
594         elm_object_signal_emit(VIEW(prev_it), "elm,state,visible",
595                                "elm");
596      }
597 end:
598    _item_free(nit);
599
600    return EINA_TRUE;
601 }
602
603 static void
604 _item_content_set(Elm_Naviframe_Item *it,
605                   Evas_Object *content)
606 {
607    if (it->content == content) return;
608
609    if (it->content) evas_object_del(it->content);
610    it->content = content;
611
612    if (!content) return;
613
614    elm_object_part_content_set(VIEW(it), CONTENT_PART, content);
615    elm_object_signal_emit(VIEW(it), "elm,state,content,show", "elm");
616
617    evas_object_event_callback_add
618      (content, EVAS_CALLBACK_DEL, _item_content_del_cb, it);
619 }
620
621 char *
622 _access_prev_btn_info_cb(void *data __UNUSED__ , Evas_Object *obj __UNUSED__)
623 {
624    return strdup(E_("Back"));
625 }
626
627 static void
628 _item_title_prev_btn_set(Elm_Naviframe_Item *it,
629                          Evas_Object *btn)
630 {
631    const char* txt;
632    if (it->title_prev_btn == btn) return;
633    if (it->title_prev_btn) evas_object_del(it->title_prev_btn);
634    it->title_prev_btn = btn;
635    if (!btn) return;
636
637    elm_object_part_content_set(VIEW(it), PREV_BTN_PART, btn);
638    elm_object_signal_emit(VIEW(it), "elm,state,prev_btn,show", "elm");
639    evas_object_event_callback_add
640      (btn, EVAS_CALLBACK_DEL, _item_title_prev_btn_del_cb, it);
641    evas_object_smart_callback_add
642      (btn, SIG_CLICKED, _on_item_back_btn_clicked, WIDGET(it));
643
644    txt = elm_layout_text_get(btn, NULL);
645    if (txt && (strlen(txt) > 0)) return;
646
647     _elm_access_callback_set
648       (_elm_access_object_get(btn), ELM_ACCESS_INFO,
649        (Elm_Access_Info_Cb)_access_prev_btn_info_cb, it);
650 }
651
652 static void
653 _item_title_next_btn_set(Elm_Naviframe_Item *it,
654                          Evas_Object *btn)
655 {
656    if (it->title_next_btn == btn) return;
657    if (it->title_next_btn) evas_object_del(it->title_next_btn);
658    it->title_next_btn = btn;
659    if (!btn) return;
660
661    elm_object_part_content_set(VIEW(it), NEXT_BTN_PART, btn);
662    elm_object_signal_emit(VIEW(it), "elm,state,next_btn,show", "elm");
663
664    evas_object_event_callback_add
665      (btn, EVAS_CALLBACK_DEL, _item_title_next_btn_del_cb, it);
666 }
667
668 static void
669 _item_title_icon_set(Elm_Naviframe_Item *it,
670                      Evas_Object *icon)
671 {
672    if (it->title_icon == icon) return;
673    if (it->title_icon) evas_object_del(it->title_icon);
674    it->title_icon = icon;
675    if (!icon) return;
676
677    elm_object_part_content_set(VIEW(it), ICON_PART, icon);
678    elm_object_signal_emit(VIEW(it), "elm,state,icon,show", "elm");
679
680    evas_object_event_callback_add
681      (icon, EVAS_CALLBACK_DEL, _item_title_icon_del_cb, it);
682 }
683
684 static Evas_Object *
685 _item_content_unset(Elm_Naviframe_Item *it)
686 {
687    Evas_Object *content = it->content;
688
689    if (!content) return NULL;
690
691    elm_object_part_content_unset(VIEW(it), CONTENT_PART);
692    elm_object_signal_emit(VIEW(it), "elm,state,content,hide", "elm");
693
694    evas_object_event_callback_del
695      (content, EVAS_CALLBACK_DEL, _item_content_del_cb);
696
697    it->content = NULL;
698    return content;
699 }
700
701 static Evas_Object *
702 _item_title_prev_btn_unset(Elm_Naviframe_Item *it)
703 {
704    Evas_Object *content = it->title_prev_btn;
705
706    if (!content) return NULL;
707
708    elm_object_part_content_unset(VIEW(it), PREV_BTN_PART);
709    elm_object_signal_emit(VIEW(it), "elm,state,prev_btn,hide", "elm");
710
711    evas_object_event_callback_del
712      (content, EVAS_CALLBACK_DEL, _item_title_prev_btn_del_cb);
713
714    evas_object_smart_callback_del(content, SIG_CLICKED,
715                                   _on_item_back_btn_clicked);
716
717    it->title_prev_btn = NULL;
718    return content;
719 }
720
721 static Evas_Object *
722 _item_title_next_btn_unset(Elm_Naviframe_Item *it)
723 {
724    Evas_Object *content = it->title_next_btn;
725
726    if (!content) return NULL;
727
728    elm_object_part_content_unset(VIEW(it), NEXT_BTN_PART);
729    elm_object_signal_emit(VIEW(it), "elm,state,next_btn,hide", "elm");
730
731    evas_object_event_callback_del
732      (content, EVAS_CALLBACK_DEL, _item_title_next_btn_del_cb);
733
734    it->title_next_btn = NULL;
735    return content;
736 }
737
738 static Evas_Object *
739 _item_title_icon_unset(Elm_Naviframe_Item *it)
740 {
741    Evas_Object *content = it->title_icon;
742
743    if (!content) return NULL;
744
745    elm_object_part_content_unset(VIEW(it), ICON_PART);
746    elm_object_signal_emit(VIEW(it), "elm,state,icon,hide", "elm");
747
748    evas_object_event_callback_del
749      (content, EVAS_CALLBACK_DEL, _item_title_icon_del_cb);
750
751    it->title_icon = NULL;
752    return content;
753 }
754
755 /* since we have each item as layout, we can't reusing the layout's
756  * aliasing, so let's do it ourselves */
757 static void
758 _part_aliasing_eval(const char **part)
759 {
760    if (!*part || !strcmp("default", *part))
761      *part = CONTENT_PART;
762    else if (!strcmp(*part, "prev_btn"))
763      *part = PREV_BTN_PART;
764    else if (!strcmp(*part, "next_btn"))
765      *part = NEXT_BTN_PART;
766    else if (!strcmp(*part, "icon"))
767      *part = ICON_PART;
768 }
769
770 static void
771 _title_content_set(Elm_Naviframe_Item *it,
772                    const char *part,
773                    Evas_Object *content)
774 {
775    Elm_Naviframe_Content_Item_Pair *pair = NULL;
776    char buf[1024];
777
778    EINA_INLIST_FOREACH(it->content_list, pair)
779      if (!strcmp(part, pair->part)) break;
780    if (pair)
781      {
782         if (pair->content == content) return;
783         if (pair->content)
784           evas_object_event_callback_del(pair->content,
785                                          EVAS_CALLBACK_DEL,
786                                          _title_content_del);
787        if (content) elm_object_part_content_set(VIEW(it), part, content);
788      }
789    else
790      {
791         if (!content) return;
792
793         //Remove the pair if new content was swallowed into other part.
794         EINA_INLIST_FOREACH(it->content_list, pair)
795           {
796              if (pair->content == content)
797                {
798                   eina_stringshare_del(pair->part);
799                   it->content_list = eina_inlist_remove(it->content_list,
800                                                         EINA_INLIST_GET(pair));
801                   evas_object_event_callback_del(pair->content,
802                                                  EVAS_CALLBACK_DEL,
803                                                  _title_content_del);
804                   free(pair);
805                   break;
806                }
807           }
808
809         //New pair
810         pair = ELM_NEW(Elm_Naviframe_Content_Item_Pair);
811         if (!pair)
812           {
813              ERR("Failed to allocate new content part of the item! : naviframe=%p",
814              WIDGET(it));
815              return;
816           }
817         pair->it = it;
818         eina_stringshare_replace(&pair->part, part);
819         it->content_list = eina_inlist_append(it->content_list,
820                                               EINA_INLIST_GET(pair));
821         elm_object_part_content_set(VIEW(it), part, content);
822         snprintf(buf, sizeof(buf), "elm,state,%s,show", part);
823         elm_object_signal_emit(VIEW(it), buf, "elm");
824      }
825    pair->content = content;
826    evas_object_event_callback_add(content,
827                                   EVAS_CALLBACK_DEL,
828                                   _title_content_del,
829                                   pair);
830    /* access */
831    if (_elm_config->access_mode)
832      _access_obj_process(it, EINA_TRUE);
833 }
834
835 static void
836 _item_content_set_hook(Elm_Object_Item *it,
837                        const char *part,
838                        Evas_Object *content)
839 {
840    Elm_Naviframe_Item *nit = (Elm_Naviframe_Item *)it;
841
842    _part_aliasing_eval(&part);
843
844    //specified parts
845    if (!part || !strcmp(CONTENT_PART, part))
846      _item_content_set(nit, content);
847    else if (!strcmp(part, PREV_BTN_PART))
848      _item_title_prev_btn_set(nit, content);
849    else if (!strcmp(part, NEXT_BTN_PART))
850      _item_title_next_btn_set(nit, content);
851    else if (!strcmp(part, ICON_PART))
852      _item_title_icon_set(nit, content);
853    else
854      _title_content_set(nit, part, content);
855
856    elm_layout_sizing_eval(WIDGET(it));
857 }
858
859 static Evas_Object *
860 _item_content_get_hook(const Elm_Object_Item *it,
861                        const char *part)
862 {
863    Elm_Naviframe_Item *nit = (Elm_Naviframe_Item *)it;
864
865    _part_aliasing_eval(&part);
866
867    //specified parts
868    if (!part || !strcmp(CONTENT_PART, part))
869      return nit->content;
870    else if (!strcmp(part, PREV_BTN_PART))
871      return nit->title_prev_btn;
872    else if (!strcmp(part, NEXT_BTN_PART))
873      return nit->title_next_btn;
874    else if (!strcmp(part, ICON_PART))
875      return nit->title_icon;
876
877    //common parts
878    return elm_object_part_content_get(VIEW(nit), part);
879 }
880
881 static Evas_Object *
882 _title_content_unset(Elm_Naviframe_Item *it, const char *part)
883 {
884    Elm_Naviframe_Content_Item_Pair *pair = NULL;
885    char buf[1028];
886    Evas_Object *content = NULL;
887
888    EINA_INLIST_FOREACH(it->content_list, pair)
889      {
890         if (!strcmp(part, pair->part))
891           {
892              content = pair->content;
893              eina_stringshare_del(pair->part);
894              it->content_list = eina_inlist_remove(it->content_list,
895                                                    EINA_INLIST_GET(pair));
896              free(pair);
897              break;
898           }
899      }
900
901    if (!content) return NULL;
902
903    elm_object_part_content_unset(VIEW(it), part);
904    snprintf(buf, sizeof(buf), "elm,state,%s,hide", part);
905    elm_object_signal_emit(VIEW(it), buf, "elm");
906    evas_object_event_callback_del(content,
907                                   EVAS_CALLBACK_DEL,
908                                   _title_content_del);
909    return content;
910 }
911
912 static Evas_Object *
913 _item_content_unset_hook(Elm_Object_Item *it,
914                          const char *part)
915 {
916    Elm_Naviframe_Item *nit = (Elm_Naviframe_Item *)it;
917    Evas_Object *o = NULL;
918
919    _part_aliasing_eval(&part);
920
921    //specified parts
922    if (!part || !strcmp(CONTENT_PART, part))
923      o = _item_content_unset(nit);
924    else if (!strcmp(part, PREV_BTN_PART))
925      o = _item_title_prev_btn_unset(nit);
926    else if (!strcmp(part, NEXT_BTN_PART))
927      o = _item_title_next_btn_unset(nit);
928    else if (!strcmp(part, ICON_PART))
929      o = _item_title_icon_unset(nit);
930    else
931      o = _title_content_unset(nit, part);
932
933    elm_layout_sizing_eval(WIDGET(it));
934
935    return o;
936 }
937
938 static void
939 _item_signal_emit_hook(Elm_Object_Item *it,
940                        const char *emission,
941                        const char *source)
942 {
943    elm_object_signal_emit(VIEW(it), emission, source);
944 }
945
946 static void
947 _elm_naviframe_smart_sizing_eval(Evas_Object *obj)
948 {
949    Evas_Coord minw = -1, minh = -1;
950    Elm_Naviframe_Item *it, *top;
951    Evas_Coord x, y, w, h;
952
953    ELM_NAVIFRAME_DATA_GET(obj, sd);
954
955    if (sd->on_deletion) return;
956
957    if (!sd->stack) return;
958
959    top = (EINA_INLIST_CONTAINER_GET(sd->stack->last, Elm_Naviframe_Item));
960    evas_object_geometry_get(obj, &x, &y, &w, &h);
961    EINA_INLIST_FOREACH(sd->stack, it)
962      {
963         evas_object_move(VIEW(it), x, y);
964         evas_object_resize(VIEW(it), w, h);
965
966         if (it == top)
967           {
968              edje_object_size_min_calc(elm_layout_edje_get(VIEW(it)),
969                                        &it->minw, &it->minh);
970              minw = it->minw;
971              minh = it->minh;
972           }
973      }
974
975    evas_object_size_hint_min_set(obj, minw, minh);
976    evas_object_size_hint_max_set(obj, -1, -1);
977 }
978
979 static void
980 _on_item_back_btn_clicked(void *data,
981                           Evas_Object *obj,
982                           void *event_info __UNUSED__)
983 {
984    /* Since edje has the event queue, clicked event could be happend
985       multiple times on some heavy environment. This callback del will
986       prevent those scenario and guarantee only one clicked for it's own
987       page. */
988    evas_object_smart_callback_del(obj, SIG_CLICKED, _on_item_back_btn_clicked);
989    elm_naviframe_item_pop(data);
990 }
991
992 static Evas_Object *
993 _back_btn_new(Evas_Object *obj, const char *title_label)
994 {
995    Evas_Object *btn, *ed;
996    char buf[1024];
997
998    btn = elm_button_add(obj);
999
1000    if (!btn) return NULL;
1001    snprintf
1002      (buf, sizeof(buf), "naviframe/back_btn/%s", elm_widget_style_get(obj));
1003    elm_object_style_set(btn, buf);
1004    if (title_label)
1005      elm_layout_text_set(btn, NULL, title_label);
1006    else
1007      elm_object_domain_translatable_text_set(btn, PACKAGE, N_("Back"));
1008
1009    /* HACK NOTE: this explicit check only exists to avoid an ERR()
1010     * message from elm_layout_content_set().
1011     *
1012     * The button was ALWAYS supposed to support an elm.swallow.content, but
1013     * default naviframe/back_btn/default theme did not provide such, then
1014     * old themes would emit such error message.
1015     *
1016     * Once we can break the theme API, remove this check and always
1017     * set an icon.
1018     */
1019    ed = elm_layout_edje_get(btn);
1020    if (edje_object_part_exists(ed, CONTENT_PART))
1021      {
1022         Evas_Object *ico = elm_icon_add(btn);
1023         elm_icon_standard_set(ico, "arrow_left");
1024         elm_layout_content_set(btn, CONTENT_PART, ico);
1025      }
1026
1027    return btn;
1028 }
1029
1030 static void
1031 _elm_naviframe_smart_signal_callback_add(Evas_Object *obj,
1032                                   const char *emission,
1033                                   const char *source,
1034                                   Edje_Signal_Cb func_cb,
1035                                   void *data)
1036 {
1037    ELM_NAVIFRAME_DATA_GET(obj, sd);
1038    Elm_Object_Item *it;
1039
1040    if (!sd->stack) return;
1041
1042    _elm_naviframe_parent_sc->callback_add(obj, emission, source, func_cb, data);
1043
1044    it = elm_naviframe_top_item_get(obj);
1045    if (!it) return;
1046
1047    elm_object_signal_callback_add(VIEW(it), emission, source, func_cb, data);
1048 }
1049
1050 static void
1051 _elm_naviframe_smart_signal(Evas_Object *obj,
1052                             const char *emission,
1053                             const char *source)
1054 {
1055    ELM_NAVIFRAME_DATA_GET(obj, sd);
1056    Elm_Object_Item *it;
1057
1058    if (!sd->stack) return;
1059
1060    _elm_naviframe_parent_sc->signal(obj, emission, source);
1061
1062    it = elm_naviframe_top_item_get(obj);
1063    if (!it) return;
1064
1065    elm_object_signal_emit(VIEW(it), emission, source);
1066 }
1067
1068 /* content/text smart functions proxying things to the top item, which
1069  * is the resize object of the layout */
1070 static Eina_Bool
1071 _elm_naviframe_smart_text_set(Evas_Object *obj,
1072                               const char *part,
1073                               const char *label)
1074 {
1075    Elm_Object_Item *it = NULL;
1076    const char *ret = NULL;
1077
1078    it = elm_naviframe_top_item_get(obj);
1079    if (!it) return EINA_FALSE;
1080
1081    elm_object_item_part_text_set(it, part, label);
1082    ret = elm_object_item_part_text_get(it, part);
1083
1084    if (ret && label)
1085      return !strcmp(ret, label);
1086    else return EINA_FALSE;
1087
1088 }
1089
1090 static const char *
1091 _elm_naviframe_smart_text_get(const Evas_Object *obj,
1092                               const char *part)
1093 {
1094    Elm_Object_Item *it = elm_naviframe_top_item_get(obj);
1095
1096    if (!it) return NULL;
1097
1098    return elm_object_item_part_text_get(it, part);
1099 }
1100
1101 /* we have to keep a "manual" set here because of the callbacks on the
1102  * children */
1103 static Eina_Bool
1104 _elm_naviframe_smart_content_set(Evas_Object *obj,
1105                                  const char *part,
1106                                  Evas_Object *content)
1107 {
1108    Elm_Object_Item *it;
1109
1110    it = elm_naviframe_top_item_get(obj);
1111    if (!it) return EINA_FALSE;
1112
1113    elm_object_item_part_content_set(it, part, content);
1114
1115    return content == elm_object_item_part_content_get(it, part);
1116 }
1117
1118 static Evas_Object *
1119 _elm_naviframe_smart_content_get(const Evas_Object *obj,
1120                                  const char *part)
1121 {
1122    Elm_Object_Item *it = elm_naviframe_top_item_get(obj);
1123
1124    if (!it) return NULL;
1125
1126    return elm_object_item_part_content_get(it, part);
1127 }
1128
1129 static Evas_Object *
1130 _elm_naviframe_smart_content_unset(Evas_Object *obj,
1131                                    const char *part)
1132 {
1133    Elm_Object_Item *it = elm_naviframe_top_item_get(obj);
1134
1135    if (!it) return NULL;
1136
1137    return elm_object_item_part_content_unset(it, part);
1138 }
1139
1140 static void
1141 _on_item_title_clicked(void *data,
1142                        Evas_Object *obj __UNUSED__,
1143                        const char *emission __UNUSED__,
1144                        const char *source __UNUSED__)
1145 {
1146    Elm_Naviframe_Item *it = data;
1147
1148    evas_object_smart_callback_call(WIDGET(it), SIG_TITLE_CLICKED, it);
1149 }
1150
1151 /* "elm,state,cur,pushed"
1152  */
1153 static void
1154 _on_item_push_finished(void *data,
1155                        Evas_Object *obj __UNUSED__,
1156                        const char *emission __UNUSED__,
1157                        const char *source __UNUSED__)
1158 {
1159    Elm_Naviframe_Item *it = data;
1160
1161    if (!it) return;
1162
1163    ELM_NAVIFRAME_DATA_GET(WIDGET(it), sd);
1164
1165    evas_object_hide(VIEW(it));
1166
1167    elm_object_signal_emit(VIEW(it), "elm,state,invisible", "elm");
1168
1169    if (sd->freeze_events)
1170      evas_object_freeze_events_set(VIEW(it), EINA_FALSE);
1171 }
1172
1173
1174 /* "elm,state,new,pushed",
1175  * "elm,state,prev,popped
1176  */
1177 static void
1178 _on_item_show_finished(void *data,
1179                        Evas_Object *obj __UNUSED__,
1180                        const char *emission __UNUSED__,
1181                        const char *source __UNUSED__)
1182 {
1183    Elm_Naviframe_Item *it = data;
1184
1185    ELM_NAVIFRAME_DATA_GET(WIDGET(it), sd);
1186
1187    elm_object_signal_emit(VIEW(it), "elm,state,visible", "elm");
1188
1189    if (_elm_config->access_mode)
1190      _elm_access_highlight_read_enable_set(WIDGET(it), EINA_TRUE, EINA_FALSE);
1191
1192    _prev_page_focus_recover(it);
1193
1194    if (sd->freeze_events)
1195      evas_object_freeze_events_set(VIEW(it), EINA_FALSE);
1196
1197    evas_object_smart_callback_call(WIDGET(it), SIG_TRANSITION_FINISHED, data);
1198 }
1199
1200 static void
1201 _on_item_size_hints_changed(void *data,
1202                             Evas *e __UNUSED__,
1203                             Evas_Object *obj __UNUSED__,
1204                             void *event_info __UNUSED__)
1205 {
1206    elm_layout_sizing_eval(data);
1207 }
1208
1209 static void
1210 _item_dispmode_set(Elm_Naviframe_Item *it, Evas_Display_Mode dispmode)
1211 {
1212    if (it->dispmode == dispmode) return;
1213    switch (dispmode)
1214      {
1215       case EVAS_DISPLAY_MODE_COMPRESS:
1216          elm_object_signal_emit(VIEW(it), "elm,state,display,compress", "elm");
1217          break;
1218       default:
1219          elm_object_signal_emit(VIEW(it), "elm,state,display,default", "elm");
1220          break;
1221      }
1222    it->dispmode = dispmode;
1223 }
1224
1225 static void
1226 _on_item_pop_finished(void *data,
1227                       Evas_Object *obj __UNUSED__,
1228                       const char *emission __UNUSED__,
1229                       const char *source __UNUSED__)
1230 {
1231    Elm_Naviframe_Item *it = data;
1232
1233    ELM_NAVIFRAME_DATA_GET(WIDGET(it), sd);
1234
1235    if (sd->preserve)
1236      elm_widget_tree_unfocusable_set(VIEW(it), EINA_FALSE);
1237
1238    sd->popping = eina_list_remove(sd->popping, it);
1239
1240    elm_widget_item_del(data);
1241 }
1242
1243 static Elm_Naviframe_Item *
1244 _item_new(Evas_Object *obj,
1245           const Elm_Naviframe_Item *prev_it,
1246           const char *title_label,
1247           Evas_Object *prev_btn,
1248           Evas_Object *next_btn,
1249           Evas_Object *content,
1250           const char *item_style)
1251 {
1252    Elm_Naviframe_Item *it;
1253
1254    ELM_NAVIFRAME_DATA_GET(obj, sd);
1255
1256    it = elm_widget_item_new(obj, Elm_Naviframe_Item);
1257    if (!it)
1258      {
1259         ERR("Failed to allocate new item! : naviframe=%p", obj);
1260         return NULL;
1261      }
1262
1263    elm_widget_item_del_pre_hook_set(it, _item_del_pre_hook);
1264    elm_widget_item_text_set_hook_set(it, _item_text_set_hook);
1265    elm_widget_item_text_get_hook_set(it, _item_text_get_hook);
1266    elm_widget_item_content_set_hook_set(it, _item_content_set_hook);
1267    elm_widget_item_content_get_hook_set(it, _item_content_get_hook);
1268    elm_widget_item_content_unset_hook_set(it, _item_content_unset_hook);
1269    elm_widget_item_signal_emit_hook_set(it, _item_signal_emit_hook);
1270
1271    //item base layout
1272    VIEW(it) = elm_layout_add(obj);
1273    evas_object_smart_member_add(VIEW(it), obj);
1274
1275    if (!elm_widget_sub_object_add(obj, VIEW(it)))
1276      ERR("could not add %p as sub object of %p", VIEW(it), obj);
1277
1278    evas_object_event_callback_add
1279      (VIEW(it), EVAS_CALLBACK_CHANGED_SIZE_HINTS,
1280      _on_item_size_hints_changed, obj);
1281
1282    elm_object_signal_callback_add
1283      (VIEW(it), "elm,action,show,finished", "", _on_item_show_finished, it);
1284    elm_object_signal_callback_add
1285      (VIEW(it), "elm,action,pushed,finished", "", _on_item_push_finished, it);
1286    elm_object_signal_callback_add
1287       (VIEW(it), "elm,action,popped,finished", "", _on_item_pop_finished, it);
1288    elm_object_signal_callback_add
1289      (VIEW(it), "elm,action,title,transition,finished", "", _on_item_title_transition_finished, it);
1290    elm_object_signal_callback_add
1291      (VIEW(it), "elm,action,title,clicked", "", _on_item_title_clicked, it);
1292
1293    _item_style_set(it, item_style);
1294
1295    if (title_label)
1296      _item_text_set_hook((Elm_Object_Item *)it, TITLE_PART, title_label);
1297
1298    //title buttons
1299    if ((!prev_btn) && sd->auto_pushed && prev_it)
1300      {
1301         const char *prev_title = prev_it->title_label;
1302         prev_btn = _back_btn_new(obj, prev_title);
1303      }
1304
1305    if (prev_btn)
1306      _item_content_set_hook((Elm_Object_Item *)it, PREV_BTN_PART, prev_btn);
1307
1308    if (next_btn)
1309      {
1310         _item_content_set_hook((Elm_Object_Item *)it, NEXT_BTN_PART, next_btn);
1311
1312         if (!elm_layout_text_get(next_btn, NULL))
1313           {
1314              char *text = NULL;
1315              text = elm_access_info_get(next_btn, ELM_ACCESS_INFO);
1316              if (text)
1317                {
1318                   free(text);
1319                }
1320              else
1321                {
1322                   _elm_access_text_set
1323                      (_elm_access_object_get(next_btn), ELM_ACCESS_INFO, E_("Next"));
1324                }
1325           }
1326      }
1327
1328    _item_content_set(it, content);
1329    _item_dispmode_set(it, sd->dispmode);
1330
1331    it->title_enabled = EINA_TRUE;
1332
1333    return it;
1334 }
1335
1336 //Tizen Only: Pop an item by clicking mouse right button
1337 static void
1338 _elm_naviframe_mouse_up_cb(void *data __UNUSED__, Evas *e __UNUSED__,
1339                              Evas_Object *obj, void *event_info)
1340 {
1341    Elm_Naviframe_Item *it;
1342    Evas_Event_Mouse_Up *ev = event_info;
1343
1344    if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return;
1345    if (elm_widget_disabled_get(obj)) return;
1346    if (ev->button != 3) return;
1347
1348    it = (Elm_Naviframe_Item *) elm_naviframe_top_item_get(obj);
1349    if (!it) return;
1350
1351    ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
1352
1353    elm_naviframe_item_pop(obj);
1354 }
1355
1356 static void
1357 _on_obj_size_hints_changed(void *data __UNUSED__, Evas *e __UNUSED__,
1358                            Evas_Object *obj, void *event_info __UNUSED__)
1359 {
1360    Elm_Naviframe_Item *it;
1361    Evas_Display_Mode dispmode;
1362
1363    ELM_NAVIFRAME_DATA_GET(obj, sd);
1364
1365    dispmode = evas_object_size_hint_display_mode_get(obj);
1366    if (sd->dispmode == dispmode) return;
1367
1368    sd->dispmode = dispmode;
1369
1370    EINA_INLIST_FOREACH(sd->stack, it)
1371      _item_dispmode_set(it, dispmode);
1372 }
1373
1374 static Eina_Bool
1375 _elm_naviframe_smart_focus_next(const Evas_Object *obj,
1376                                 Elm_Focus_Direction dir,
1377                                 Evas_Object **next)
1378 {
1379    Evas_Object *ao;
1380    Eina_Bool ret = EINA_FALSE;
1381    Eina_List *l = NULL;
1382    Elm_Naviframe_Item *top_it;
1383    void *(*list_data_get)(const Eina_List *list);
1384
1385    top_it = (Elm_Naviframe_Item *)elm_naviframe_top_item_get(obj);
1386    if (!top_it) goto end;
1387
1388    ao = ((Elm_Widget_Item *)top_it)->access_obj;
1389
1390    list_data_get = eina_list_data_get;
1391
1392    l = eina_list_append(l, VIEW(top_it));
1393
1394    /* access */
1395    if (_elm_access_auto_highlight_get() &&
1396        top_it->title_enabled)
1397      {
1398         if (elm_widget_tree_unfocusable_get(VIEW(top_it))) return EINA_FALSE;
1399
1400         if (ao &&
1401             !elm_widget_highlight_get(ao) &&
1402             !elm_widget_highlight_get(VIEW(top_it)))
1403           {
1404              /* if title does not have a highlight and sub object of item layout
1405                 does not have a highlight, give a highlight to the title */
1406              *next = ao;
1407              return EINA_TRUE;
1408           }
1409      }
1410
1411    ret = elm_widget_focus_list_next_get(obj, l, list_data_get, dir, next);
1412    eina_list_free(l);
1413
1414    if (!_elm_access_auto_highlight_get()) goto end;
1415
1416    if (ret && ao && top_it->title_enabled && (dir == ELM_FOCUS_PREVIOUS) &&
1417        elm_widget_highlight_get(ao))
1418      return EINA_FALSE;
1419
1420    if (!ret)
1421      {
1422        if (top_it->title_enabled)
1423          {
1424             if (elm_widget_tree_unfocusable_get(VIEW(top_it)))
1425               return EINA_FALSE;
1426
1427             if (ao && !elm_widget_highlight_get(ao))
1428               {
1429                  /* if a highlight meets end, give a highlight to the title directly
1430                     or let parent object decide to give a highlight to the title */
1431                  *next = ao;
1432                  if (dir == ELM_FOCUS_PREVIOUS) return EINA_TRUE;
1433                  else return EINA_FALSE;
1434               }
1435          }
1436
1437        /* if focus next object is not found, highlight can go to item layout */
1438        if (*next) return EINA_FALSE;
1439        else if (VIEW(top_it))
1440          {
1441             *next = VIEW(top_it);
1442             return EINA_FALSE;
1443          }
1444      }
1445 end:
1446    if (!ret && !*next)
1447      {
1448         *next = (Evas_Object *)obj;
1449         ret = !elm_widget_focus_get(obj);
1450      }
1451    return ret;
1452 }
1453
1454 static Eina_Bool
1455 _elm_naviframe_smart_focus_direction_manager_is(const Evas_Object *obj __UNUSED__)
1456 {
1457    return EINA_TRUE;
1458 }
1459
1460 static Eina_Bool
1461 _elm_naviframe_smart_focus_direction(const Evas_Object *obj,
1462                                      const Evas_Object *base,
1463                                      double degree,
1464                                      Evas_Object **direction,
1465                                      double *weight)
1466 {
1467    Eina_Bool ret;
1468    Eina_List *l = NULL;
1469    Elm_Naviframe_Item *top_it;
1470    void *(*list_data_get)(const Eina_List *list);
1471
1472    top_it = (Elm_Naviframe_Item *)elm_naviframe_top_item_get(obj);
1473    if (!top_it) return EINA_FALSE;
1474
1475    list_data_get = eina_list_data_get;
1476
1477    l = eina_list_append(l, VIEW(top_it));
1478    ret = elm_widget_focus_list_direction_get
1479       (obj, base, l, list_data_get, degree, direction, weight);
1480    eina_list_free(l);
1481
1482    return ret;
1483 }
1484
1485 static void
1486 _elm_naviframe_smart_add(Evas_Object *obj)
1487 {
1488    EVAS_SMART_DATA_ALLOC(obj, Elm_Naviframe_Smart_Data);
1489
1490    ELM_WIDGET_CLASS(_elm_naviframe_parent_sc)->base.add(obj);
1491 }
1492
1493 static Eina_Bool
1494 _pop_transition_cb(void *data)
1495 {
1496    Elm_Naviframe_Item *prev_it, *it;
1497    it = (Elm_Naviframe_Item *)data;
1498
1499    it->animator = NULL;
1500
1501    prev_it = (Elm_Naviframe_Item *) elm_naviframe_top_item_get(WIDGET(it));
1502    if (prev_it)
1503      {
1504         elm_object_signal_emit(VIEW(prev_it), "elm,state,prev,popped,deferred",
1505                                "elm");
1506         edje_object_message_signal_process(elm_layout_edje_get(VIEW(prev_it)));
1507
1508 #ifdef ELM_FEATURE_WEARABLE_RECTANGLE
1509         if (nf_mod && nf_mod->tizen_pop_effect) nf_mod->tizen_pop_effect(prev_it);
1510 #endif
1511      }
1512    elm_object_signal_emit(VIEW(it), "elm,state,cur,popped,deferred", "elm");
1513    edje_object_message_signal_process(elm_layout_edje_get(VIEW(it)));
1514
1515 #ifndef ELM_FEATURE_WEARABLE_RECTANGLE
1516    // TIZEN ONLY
1517    if (nf_mod && nf_mod->tizen_pop_effect) nf_mod->tizen_pop_effect(it);
1518 #endif
1519
1520    return ECORE_CALLBACK_CANCEL;
1521 }
1522
1523 static void
1524 _elm_naviframe_smart_del(Evas_Object *obj)
1525 {
1526    Elm_Naviframe_Item *it;
1527
1528    ELM_NAVIFRAME_DATA_GET(obj, sd);
1529
1530    sd->on_deletion = EINA_TRUE;
1531
1532    while (sd->stack)
1533      {
1534         it = EINA_INLIST_CONTAINER_GET(sd->stack, Elm_Naviframe_Item);
1535         elm_widget_item_del(it);
1536      }
1537
1538    //All popping items which are not called yet by animator.
1539    EINA_LIST_FREE(sd->popping, it)
1540      {
1541         if (it->animator) ecore_animator_del(it->animator);
1542         elm_widget_item_del(it);
1543      }
1544
1545    evas_object_del(sd->dummy_edje);
1546
1547    ELM_WIDGET_CLASS(_elm_naviframe_parent_sc)->base.del(obj);
1548 }
1549
1550 static void
1551 _elm_naviframe_smart_access(Evas_Object *obj, Eina_Bool is_access)
1552 {
1553    Elm_Naviframe_Item *it;
1554
1555    ELM_NAVIFRAME_CHECK(obj);
1556    ELM_NAVIFRAME_DATA_GET(obj, sd);
1557
1558    EINA_INLIST_FOREACH(sd->stack, it)
1559      _access_obj_process(it, is_access);
1560
1561    it = (Elm_Naviframe_Item *)elm_naviframe_top_item_get(obj);
1562    if (it && is_access) _access_focus_set(it);
1563    evas_object_smart_callback_call(obj, SIG_ACCESS_CHANGED, NULL);
1564 }
1565
1566 static Eina_Bool
1567 _elm_naviframe_smart_event(Evas_Object *obj,
1568                            Evas_Object *src __UNUSED__,
1569                            Evas_Callback_Type type,
1570                            void *event_info)
1571 {
1572    //Elm_Naviframe_Item *it;
1573    Evas_Event_Key_Down *ev = event_info;
1574
1575    if (elm_widget_disabled_get(obj)) return EINA_FALSE;
1576    if (type != EVAS_CALLBACK_KEY_DOWN) return EINA_FALSE;
1577    if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return EINA_FALSE;
1578
1579    /* Tizen Only: Need key binding. At this moment, Naviframe doesn't support
1580       any key events. */
1581    //if (strcmp(ev->keyname, "Escape")) return EINA_FALSE;
1582    return EINA_FALSE;
1583
1584    /*it = (Elm_Naviframe_Item *) elm_naviframe_top_item_get(obj);
1585        if (!it) return EINA_FALSE;
1586        ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
1587        if (it->title_prev_btn)
1588        evas_object_smart_callback_call(it->title_prev_btn, SIG_CLICKED, NULL);
1589        return EINA_TRUE;*/
1590
1591 }
1592
1593 static Eina_Bool
1594 _elm_naviframe_smart_activate(Evas_Object *obj, Elm_Activate act)
1595 {
1596    Elm_Naviframe_Item *it;
1597
1598    if (act != ELM_ACTIVATE_BACK) return EINA_FALSE;
1599    if (elm_widget_disabled_get(obj)) return EINA_FALSE;
1600
1601    it = (Elm_Naviframe_Item *)elm_naviframe_top_item_get(obj);
1602    if (!it) return EINA_FALSE;
1603
1604    if (it->title_prev_btn)
1605      evas_object_smart_callback_call(it->title_prev_btn, SIG_CLICKED, NULL);
1606
1607    return EINA_TRUE;
1608 }
1609
1610 static void
1611 _elm_naviframe_smart_show(Evas_Object *obj)
1612 {
1613    Elm_Naviframe_Item *top;
1614    top = (Elm_Naviframe_Item *)elm_naviframe_top_item_get(obj);
1615
1616    if (top && !top->delete_me)
1617      evas_object_show(VIEW(top));
1618 }
1619
1620 static void
1621 _elm_naviframe_smart_set_user(Elm_Naviframe_Smart_Class *sc)
1622 {
1623    ELM_WIDGET_CLASS(sc)->base.add = _elm_naviframe_smart_add;
1624    ELM_WIDGET_CLASS(sc)->base.del = _elm_naviframe_smart_del;
1625    ELM_WIDGET_CLASS(sc)->base.show = _elm_naviframe_smart_show;
1626
1627    ELM_WIDGET_CLASS(sc)->theme = _elm_naviframe_smart_theme;
1628    ELM_WIDGET_CLASS(sc)->translate = _elm_naviframe_smart_translate;
1629    ELM_WIDGET_CLASS(sc)->focus_next = _elm_naviframe_smart_focus_next;
1630    ELM_WIDGET_CLASS(sc)->focus_direction_manager_is =
1631       _elm_naviframe_smart_focus_direction_manager_is;
1632    ELM_WIDGET_CLASS(sc)->focus_direction = _elm_naviframe_smart_focus_direction;
1633    ELM_WIDGET_CLASS(sc)->access = _elm_naviframe_smart_access;
1634    ELM_WIDGET_CLASS(sc)->event = _elm_naviframe_smart_event;
1635    ELM_WIDGET_CLASS(sc)->activate = _elm_naviframe_smart_activate;
1636
1637    ELM_CONTAINER_CLASS(sc)->content_set = _elm_naviframe_smart_content_set;
1638    ELM_CONTAINER_CLASS(sc)->content_get = _elm_naviframe_smart_content_get;
1639    ELM_CONTAINER_CLASS(sc)->content_unset = _elm_naviframe_smart_content_unset;
1640
1641    ELM_LAYOUT_CLASS(sc)->signal = _elm_naviframe_smart_signal;
1642    ELM_LAYOUT_CLASS(sc)->callback_add = _elm_naviframe_smart_signal_callback_add;
1643    ELM_LAYOUT_CLASS(sc)->text_set = _elm_naviframe_smart_text_set;
1644    ELM_LAYOUT_CLASS(sc)->text_get = _elm_naviframe_smart_text_get;
1645    ELM_LAYOUT_CLASS(sc)->sizing_eval = _elm_naviframe_smart_sizing_eval;
1646 }
1647
1648 static Eina_Bool
1649 _push_transition_cb(void *data)
1650 {
1651    Elm_Naviframe_Item *prev_it, *it = data;
1652
1653    ELM_NAVIFRAME_DATA_GET(WIDGET(it), sd);
1654
1655    it->animator = NULL;
1656
1657    if (sd->stack->last->prev)
1658      {
1659         prev_it = EINA_INLIST_CONTAINER_GET(sd->stack->last->prev,
1660                                             Elm_Naviframe_Item);
1661         elm_object_signal_emit(VIEW(prev_it), "elm,state,cur,pushed,deferred",
1662                                "elm");
1663         edje_object_message_signal_process(elm_layout_edje_get(VIEW(prev_it)));
1664
1665 #ifdef ELM_FEATURE_WEARABLE_RECTANGLE
1666         if (nf_mod && nf_mod->tizen_push_effect) nf_mod->tizen_push_effect(prev_it);
1667 #endif
1668      }
1669    elm_object_signal_emit(VIEW(it), "elm,state,new,pushed,deferred", "elm");
1670    edje_object_message_signal_process(elm_layout_edje_get(VIEW(it)));
1671
1672 #ifndef ELM_FEATURE_WEARABLE_RECTANGLE
1673    // TIZEN ONLY
1674    if (nf_mod && nf_mod->tizen_push_effect) nf_mod->tizen_push_effect(it);
1675 #endif
1676    return ECORE_CALLBACK_CANCEL;
1677 }
1678
1679 EAPI const Elm_Naviframe_Smart_Class *
1680 elm_naviframe_smart_class_get(void)
1681 {
1682    static Elm_Naviframe_Smart_Class _sc =
1683      ELM_NAVIFRAME_SMART_CLASS_INIT_NAME_VERSION
1684        (ELM_NAVIFRAME_SMART_NAME);
1685    static const Elm_Naviframe_Smart_Class *class = NULL;
1686    Evas_Smart_Class *esc = (Evas_Smart_Class *)&_sc;
1687
1688    if (class)
1689      return class;
1690
1691    _elm_naviframe_smart_set(&_sc);
1692    esc->callbacks = _smart_callbacks;
1693    class = &_sc;
1694
1695    return class;
1696 }
1697
1698 EAPI Evas_Object *
1699 elm_naviframe_add(Evas_Object *parent)
1700 {
1701    Evas_Object *obj;
1702
1703    EINA_SAFETY_ON_NULL_RETURN_VAL(parent, NULL);
1704
1705    obj = elm_widget_add(_elm_naviframe_smart_class_new(), parent);
1706    if (!obj) return NULL;
1707
1708    if (!elm_widget_sub_object_add(parent, obj))
1709      ERR("could not add %p as sub object of %p", obj, parent);
1710
1711    if (!nf_mod) nf_mod = _nf_mod_init();
1712    ELM_NAVIFRAME_DATA_GET(obj, sd);
1713
1714    sd->dummy_edje = ELM_WIDGET_DATA(sd)->resize_obj;
1715    evas_object_smart_member_add(sd->dummy_edje, obj);
1716
1717    // TIZEN ONLY: for color class setting //
1718    elm_layout_theme_set(obj, "naviframe", "base", elm_widget_style_get(obj));
1719
1720    sd->auto_pushed = EINA_TRUE;
1721    sd->freeze_events = EINA_TRUE;
1722
1723    evas_object_event_callback_add(obj, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
1724                                   _on_obj_size_hints_changed, obj);
1725
1726    //Tizen Only: Pop an item by clicking mouse right button
1727    evas_object_event_callback_add(obj, EVAS_CALLBACK_MOUSE_UP,
1728                                   _elm_naviframe_mouse_up_cb, NULL);
1729
1730    elm_widget_can_focus_set(obj, EINA_TRUE);
1731
1732    //Tizen Only: This should be removed when eo is applied.
1733    ELM_WIDGET_DATA_GET(obj, wsd);
1734    wsd->on_create = EINA_FALSE;
1735
1736    return obj;
1737 }
1738
1739 EAPI Elm_Object_Item *
1740 elm_naviframe_item_push(Evas_Object *obj,
1741                         const char *title_label,
1742                         Evas_Object *prev_btn,
1743                         Evas_Object *next_btn,
1744                         Evas_Object *content,
1745                         const char *item_style)
1746 {
1747    Elm_Naviframe_Item *prev_it, *it;
1748
1749    ELM_NAVIFRAME_CHECK(obj) NULL;
1750
1751    ELM_NAVIFRAME_DATA_GET(obj, sd);
1752
1753    prev_it = (Elm_Naviframe_Item *)elm_naviframe_top_item_get(obj);
1754    it = _item_new(obj, prev_it,
1755                   title_label, prev_btn, next_btn, content, item_style);
1756    if (!it) return NULL;
1757
1758 #ifdef ELM_FEATURE_WEARABLE_CIRCLE
1759    //Tizen Only: give the new item's view to decorate it
1760    evas_object_smart_callback_call(obj, "item,pushed,internal", VIEW(it));
1761 #endif
1762
1763    evas_object_show(VIEW(it));
1764
1765    if (prev_it) elm_widget_focused_object_clear(VIEW(prev_it));
1766    _resize_object_reset(obj, it);
1767    if (prev_it)
1768      {
1769         if (sd->freeze_events)
1770           {
1771              evas_object_freeze_events_set(VIEW(it), EINA_TRUE);
1772              evas_object_freeze_events_set(VIEW(prev_it), EINA_TRUE);
1773           }
1774
1775         elm_object_signal_emit(VIEW(prev_it), "elm,state,cur,pushed", "elm");
1776         elm_object_signal_emit(VIEW(it), "elm,state,new,pushed", "elm");
1777         edje_object_message_signal_process(elm_layout_edje_get(VIEW(prev_it)));
1778         edje_object_message_signal_process(elm_layout_edje_get(VIEW(it)));
1779
1780         if (_elm_config->access_mode)
1781           _elm_access_highlight_read_enable_set(WIDGET(prev_it), EINA_FALSE, EINA_FALSE);
1782         elm_widget_tree_unfocusable_set(VIEW(prev_it), EINA_TRUE);
1783
1784         if (it->animator) ecore_animator_del(it->animator);
1785         it->animator = ecore_animator_add(_push_transition_cb, it);
1786      }
1787    else
1788      {
1789         /* access */
1790         if (_elm_config->access_mode)
1791           _access_focus_set(it);
1792         else
1793           {
1794              if (elm_object_focus_allow_get(VIEW(it)))
1795                elm_object_focus_set(VIEW(it), EINA_TRUE);
1796              else
1797                elm_object_focus_set(WIDGET(it), EINA_TRUE);
1798           }
1799      }
1800
1801    sd->stack = eina_inlist_append(sd->stack, EINA_INLIST_GET(it));
1802
1803    elm_layout_sizing_eval(obj);
1804
1805    if (!prev_it)
1806      elm_object_signal_emit(VIEW(it), "elm,state,visible", "elm");
1807
1808    return (Elm_Object_Item *)it;
1809 }
1810
1811 EAPI Elm_Object_Item *
1812 elm_naviframe_item_insert_before(Evas_Object *obj,
1813                                  Elm_Object_Item *before,
1814                                  const char *title_label,
1815                                  Evas_Object *prev_btn,
1816                                  Evas_Object *next_btn,
1817                                  Evas_Object *content,
1818                                  const char *item_style)
1819 {
1820    Elm_Naviframe_Item *it, *prev_it = NULL;
1821
1822    ELM_NAVIFRAME_CHECK(obj) NULL;
1823    ELM_NAVIFRAME_ITEM_CHECK_OR_RETURN(before, NULL);
1824    ELM_NAVIFRAME_DATA_GET(obj, sd);
1825
1826    it = (Elm_Naviframe_Item *)before;
1827    if (EINA_INLIST_GET(it)->prev)
1828      prev_it = EINA_INLIST_CONTAINER_GET(EINA_INLIST_GET(it)->prev,
1829                                          Elm_Naviframe_Item);
1830    it = _item_new(obj, prev_it,
1831                   title_label, prev_btn, next_btn, content, item_style);
1832    if (!it) return NULL;
1833
1834 #ifdef ELM_FEATURE_WEARABLE_CIRCLE
1835    //Tizen Only: give the new item's view to decorate it
1836    evas_object_smart_callback_call(obj, "item,pushed,internal", VIEW(it));
1837 #endif
1838
1839    sd->stack = eina_inlist_prepend_relative
1840        (sd->stack, EINA_INLIST_GET(it),
1841        EINA_INLIST_GET(((Elm_Naviframe_Item *)before)));
1842
1843    elm_widget_tree_unfocusable_set(VIEW(it), EINA_TRUE);
1844    evas_object_hide(VIEW(it));
1845    elm_object_signal_emit(VIEW(it), "elm,state,invisible", "elm");
1846
1847    elm_layout_sizing_eval(obj);
1848
1849    return (Elm_Object_Item *)it;
1850 }
1851
1852 EAPI Elm_Object_Item *
1853 elm_naviframe_item_insert_after(Evas_Object *obj,
1854                                 Elm_Object_Item *after,
1855                                 const char *title_label,
1856                                 Evas_Object *prev_btn,
1857                                 Evas_Object *next_btn,
1858                                 Evas_Object *content,
1859                                 const char *item_style)
1860 {
1861    Elm_Naviframe_Item *it;
1862    Eina_Bool top_inserted = EINA_FALSE;
1863
1864    ELM_NAVIFRAME_CHECK(obj) NULL;
1865    ELM_NAVIFRAME_ITEM_CHECK_OR_RETURN(after, NULL);
1866    ELM_NAVIFRAME_DATA_GET(obj, sd);
1867
1868    it = _item_new(obj, (Elm_Naviframe_Item *)after,
1869                   title_label, prev_btn, next_btn, content, item_style);
1870    if (!it) return NULL;
1871
1872 #ifdef ELM_FEATURE_WEARABLE_CIRCLE
1873    //Tizen Only: give the new item's view to decorate it
1874    evas_object_smart_callback_call(obj, "item,pushed,internal", VIEW(it));
1875 #endif
1876
1877    if (elm_naviframe_top_item_get(obj) == after) top_inserted = EINA_TRUE;
1878
1879    sd->stack = eina_inlist_append_relative
1880        (sd->stack, EINA_INLIST_GET(it),
1881        EINA_INLIST_GET(((Elm_Naviframe_Item *)after)));
1882
1883    if (top_inserted)
1884      {
1885         elm_widget_focused_object_clear(VIEW(after));
1886         elm_widget_tree_unfocusable_set(VIEW(after), EINA_TRUE);
1887         _resize_object_reset(obj, it);
1888         evas_object_show(VIEW(it));
1889         evas_object_hide(VIEW(after));
1890
1891         /* access */
1892         if (_elm_config->access_mode)
1893           _access_focus_set(it);
1894         else
1895           {
1896              if (elm_object_focus_allow_get(VIEW(it)))
1897                elm_object_focus_set(VIEW(it), EINA_TRUE);
1898              else
1899                elm_object_focus_set(WIDGET(it), EINA_TRUE);
1900           }
1901         elm_object_signal_emit(VIEW(it), "elm,state,visible", "elm");
1902         elm_object_signal_emit(VIEW(after), "elm,state,invisible", "elm");
1903      }
1904    else
1905      elm_object_signal_emit(VIEW(it), "elm,state,invisible", "elm");
1906
1907    elm_layout_sizing_eval(obj);
1908
1909    return (Elm_Object_Item *)it;
1910 }
1911
1912 EAPI Evas_Object *
1913 elm_naviframe_item_pop(Evas_Object *obj)
1914 {
1915    Elm_Naviframe_Item *it, *prev_it = NULL;
1916    Evas_Object *content = NULL;
1917
1918    ELM_NAVIFRAME_CHECK(obj) NULL;
1919    ELM_NAVIFRAME_DATA_GET(obj, sd);
1920
1921    if (sd->freeze_events && sd->popping) return NULL;
1922
1923    it = (Elm_Naviframe_Item *)elm_naviframe_top_item_get(obj);
1924    if (!it) return NULL;
1925
1926    if (it->popping) return NULL;
1927    it->popping = EINA_TRUE;
1928
1929    evas_object_ref(obj);
1930    if (it->pop_cb)
1931      {
1932         it->ref++;
1933         if (!it->pop_cb(it->pop_data, (Elm_Object_Item *)it))
1934           {
1935              it->ref--;
1936              if (it->delete_me)
1937                {
1938                   _item_del_pre_hook((Elm_Object_Item*)it);
1939                   _elm_widget_item_free((Elm_Widget_Item*)it);
1940                }
1941              else
1942                it->popping = EINA_FALSE;
1943              evas_object_unref(obj);
1944              return NULL;
1945           }
1946         it->ref--;
1947      }
1948    evas_object_unref(obj);
1949
1950    if (sd->preserve)
1951      content = it->content;
1952
1953    evas_object_data_set(VIEW(it), "out_of_list", (void *)1);
1954
1955    if (sd->stack->last->prev)
1956      prev_it = EINA_INLIST_CONTAINER_GET
1957         (sd->stack->last->prev, Elm_Naviframe_Item);
1958
1959    sd->stack = eina_inlist_remove(sd->stack, EINA_INLIST_GET(it));
1960
1961    if (prev_it)
1962      {
1963         if (_elm_config->access_mode)
1964           _elm_access_highlight_read_enable_set(WIDGET(it), EINA_FALSE, EINA_FALSE);
1965         elm_widget_tree_unfocusable_set(VIEW(it), EINA_TRUE);
1966         elm_widget_tree_unfocusable_set(VIEW(prev_it), EINA_FALSE);
1967
1968         if (sd->freeze_events)
1969           {
1970              evas_object_freeze_events_set(VIEW(it), EINA_TRUE);
1971              evas_object_freeze_events_set(VIEW(prev_it), EINA_TRUE);
1972           }
1973
1974         elm_widget_resize_object_set(obj, VIEW(prev_it), EINA_FALSE);
1975
1976         /* these 2 signals MUST take place simultaneously */
1977         elm_object_signal_emit(VIEW(it), "elm,state,cur,popped", "elm");
1978         evas_object_show(VIEW(prev_it));
1979         elm_object_signal_emit(VIEW(prev_it), "elm,state,prev,popped", "elm");
1980
1981         edje_object_message_signal_process(elm_layout_edje_get(VIEW(it)));
1982         edje_object_message_signal_process(elm_layout_edje_get(VIEW(prev_it)));
1983
1984         if (it->animator) ecore_animator_del(it->animator);
1985         it->animator = ecore_animator_add(_pop_transition_cb, it);
1986         sd->popping = eina_list_append(sd->popping, it);
1987      }
1988    else
1989      elm_widget_item_del(it);
1990
1991    return content;
1992 }
1993
1994 EAPI void
1995 elm_naviframe_item_pop_to(Elm_Object_Item *it)
1996 {
1997    Elm_Naviframe_Item *nit;
1998    Eina_Inlist *l;
1999
2000    ELM_NAVIFRAME_ITEM_CHECK_OR_RETURN(it);
2001
2002    nit = (Elm_Naviframe_Item *)it;
2003    ELM_NAVIFRAME_DATA_GET(WIDGET(nit), sd);
2004
2005    if (it == elm_naviframe_top_item_get(WIDGET(nit))) return;
2006
2007    l = sd->stack->last->prev;
2008
2009    sd->on_deletion = EINA_TRUE;
2010
2011    while (l)
2012      {
2013         Elm_Naviframe_Item *iit = EINA_INLIST_CONTAINER_GET
2014             (l, Elm_Naviframe_Item);
2015
2016         if (iit == nit) break;
2017
2018         l = l->prev;
2019
2020         elm_widget_item_del(iit);
2021      }
2022
2023    sd->on_deletion = EINA_FALSE;
2024
2025    elm_naviframe_item_pop(WIDGET(nit));
2026 }
2027
2028 EAPI void
2029 elm_naviframe_item_promote(Elm_Object_Item *it)
2030 {
2031    Elm_Object_Item *prev_top;
2032    Elm_Naviframe_Item *nit;
2033    Elm_Naviframe_Item *prev_it;
2034
2035    ELM_NAVIFRAME_ITEM_CHECK_OR_RETURN(it);
2036
2037    nit = (Elm_Naviframe_Item *)it;
2038    ELM_NAVIFRAME_DATA_GET(WIDGET(nit), sd);
2039
2040    prev_top = elm_naviframe_top_item_get(WIDGET(nit));
2041    if (it == prev_top) return;
2042
2043    /* remember, last is 1st on the naviframe, push it to last pos. */
2044    sd->stack = eina_inlist_demote(sd->stack, EINA_INLIST_GET(nit));
2045
2046    evas_object_show(VIEW(nit));
2047
2048    /* this was the previous top one */
2049    prev_it = EINA_INLIST_CONTAINER_GET
2050        (sd->stack->last->prev, Elm_Naviframe_Item);
2051
2052    elm_widget_focused_object_clear(VIEW(nit));
2053    _resize_object_reset(WIDGET(it), nit);
2054
2055    if (_elm_config->access_mode)
2056      _elm_access_highlight_read_enable_set(WIDGET(prev_it), EINA_FALSE, EINA_FALSE);
2057    elm_widget_tree_unfocusable_set(VIEW(nit), EINA_FALSE);
2058    elm_widget_tree_unfocusable_set(VIEW(prev_it), EINA_TRUE);
2059
2060    if (sd->freeze_events)
2061      {
2062         evas_object_freeze_events_set(VIEW(it), EINA_TRUE);
2063         evas_object_freeze_events_set(VIEW(prev_it), EINA_TRUE);
2064      }
2065
2066    elm_object_signal_emit(VIEW(prev_it), "elm,state,cur,pushed", "elm");
2067    elm_object_signal_emit(VIEW(nit), "elm,state,new,pushed", "elm");
2068
2069    edje_object_message_signal_process(elm_layout_edje_get(VIEW(prev_it)));
2070    edje_object_message_signal_process(elm_layout_edje_get(VIEW(nit)));
2071    if (nit->animator) ecore_animator_del(nit->animator);
2072    nit->animator = ecore_animator_add(_push_transition_cb, nit);
2073 }
2074
2075 EAPI void
2076 elm_naviframe_item_simple_promote(Evas_Object *obj,
2077                                   Evas_Object *content)
2078 {
2079    Elm_Naviframe_Item *itr;
2080
2081    ELM_NAVIFRAME_CHECK(obj);
2082    ELM_NAVIFRAME_DATA_GET(obj, sd);
2083
2084    EINA_INLIST_FOREACH(sd->stack, itr)
2085      {
2086         if (elm_object_item_content_get((Elm_Object_Item *)itr) == content)
2087           {
2088              elm_naviframe_item_promote((Elm_Object_Item *)itr);
2089              break;
2090           }
2091      }
2092 }
2093
2094 EAPI void
2095 elm_naviframe_content_preserve_on_pop_set(Evas_Object *obj,
2096                                           Eina_Bool preserve)
2097 {
2098    ELM_NAVIFRAME_CHECK(obj);
2099    ELM_NAVIFRAME_DATA_GET(obj, sd);
2100
2101    sd->preserve = !!preserve;
2102 }
2103
2104 EAPI Eina_Bool
2105 elm_naviframe_content_preserve_on_pop_get(const Evas_Object *obj)
2106 {
2107    ELM_NAVIFRAME_CHECK(obj) EINA_FALSE;
2108    ELM_NAVIFRAME_DATA_GET(obj, sd);
2109
2110    return sd->preserve;
2111 }
2112
2113 EAPI Elm_Object_Item *
2114 elm_naviframe_top_item_get(const Evas_Object *obj)
2115 {
2116    ELM_NAVIFRAME_CHECK(obj) NULL;
2117    ELM_NAVIFRAME_DATA_GET(obj, sd);
2118
2119    if (!sd->stack) return NULL;
2120    return (Elm_Object_Item *)(EINA_INLIST_CONTAINER_GET
2121                                 (sd->stack->last, Elm_Naviframe_Item));
2122 }
2123
2124 EAPI Elm_Object_Item *
2125 elm_naviframe_bottom_item_get(const Evas_Object *obj)
2126 {
2127    ELM_NAVIFRAME_CHECK(obj) NULL;
2128    ELM_NAVIFRAME_DATA_GET(obj, sd);
2129
2130    if (!sd->stack) return NULL;
2131    return (Elm_Object_Item *)(EINA_INLIST_CONTAINER_GET
2132                                 (sd->stack, Elm_Naviframe_Item));
2133 }
2134
2135 EAPI void
2136 elm_naviframe_item_style_set(Elm_Object_Item *it,
2137                              const char *item_style)
2138 {
2139    Elm_Naviframe_Item *nit = (Elm_Naviframe_Item *)it;
2140
2141    ELM_NAVIFRAME_ITEM_CHECK_OR_RETURN(it);
2142
2143    if (item_style && !strcmp(item_style, nit->style)) return;
2144
2145    if (!item_style)
2146      if (!strcmp("basic", nit->style)) return;
2147
2148    _item_style_set(nit, item_style);
2149    _item_signals_emit(nit);
2150    _item_title_enabled_update(nit, EINA_FALSE);
2151 }
2152
2153 EAPI const char *
2154 elm_naviframe_item_style_get(const Elm_Object_Item *it)
2155 {
2156    Elm_Naviframe_Item *nit = (Elm_Naviframe_Item *)it;
2157
2158    ELM_NAVIFRAME_ITEM_CHECK_OR_RETURN(it, NULL);
2159
2160    return nit->style;
2161 }
2162
2163 EAPI void
2164 elm_naviframe_item_title_visible_set(Elm_Object_Item *it,
2165                                      Eina_Bool visible)
2166 {
2167    elm_naviframe_item_title_enabled_set(it, visible, EINA_FALSE);
2168 }
2169
2170 EAPI Eina_Bool
2171 elm_naviframe_item_title_visible_get(const Elm_Object_Item *it)
2172 {
2173    return elm_naviframe_item_title_enabled_get(it);
2174 }
2175
2176 EAPI void
2177 elm_naviframe_item_title_enabled_set(Elm_Object_Item *it,
2178                                      Eina_Bool enabled,
2179                                      Eina_Bool transition)
2180 {
2181    Elm_Naviframe_Item *nit = (Elm_Naviframe_Item *)it;
2182
2183    ELM_NAVIFRAME_ITEM_CHECK_OR_RETURN(it);
2184
2185    enabled = !!enabled;
2186    if (nit->title_enabled == enabled) return;
2187
2188    nit->title_enabled = enabled;
2189
2190    transition = !!transition;
2191    _item_title_enabled_update(nit, transition);
2192 }
2193
2194 EAPI Eina_Bool
2195 elm_naviframe_item_title_enabled_get(const Elm_Object_Item *it)
2196 {
2197    Elm_Naviframe_Item *nit = (Elm_Naviframe_Item *)it;
2198
2199    ELM_NAVIFRAME_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
2200
2201    return nit->title_enabled;
2202 }
2203
2204 EAPI void
2205 elm_naviframe_item_pop_cb_set(Elm_Object_Item *it, Elm_Naviframe_Item_Pop_Cb func, void *data)
2206 {
2207    Elm_Naviframe_Item *nit = (Elm_Naviframe_Item *)it;
2208
2209    ELM_NAVIFRAME_ITEM_CHECK_OR_RETURN(it);
2210
2211    nit->pop_cb = func;
2212    nit->pop_data = data;
2213 }
2214
2215 EAPI void
2216 elm_naviframe_prev_btn_auto_pushed_set(Evas_Object *obj,
2217                                        Eina_Bool auto_pushed)
2218 {
2219    ELM_NAVIFRAME_CHECK(obj);
2220    ELM_NAVIFRAME_DATA_GET(obj, sd);
2221
2222    sd->auto_pushed = !!auto_pushed;
2223 }
2224
2225 EAPI Eina_Bool
2226 elm_naviframe_prev_btn_auto_pushed_get(const Evas_Object *obj)
2227 {
2228    ELM_NAVIFRAME_CHECK(obj) EINA_FALSE;
2229    ELM_NAVIFRAME_DATA_GET(obj, sd);
2230
2231    return sd->auto_pushed;
2232 }
2233
2234 EAPI Eina_List *
2235 elm_naviframe_items_get(const Evas_Object *obj)
2236 {
2237    Eina_List *ret = NULL;
2238    Elm_Naviframe_Item *itr;
2239
2240    ELM_NAVIFRAME_CHECK(obj) NULL;
2241    ELM_NAVIFRAME_DATA_GET(obj, sd);
2242
2243    EINA_INLIST_FOREACH(sd->stack, itr)
2244      ret = eina_list_append(ret, itr);
2245
2246    return ret;
2247 }
2248
2249 EAPI void
2250 elm_naviframe_event_enabled_set(Evas_Object *obj,
2251                                 Eina_Bool enabled)
2252 {
2253    ELM_NAVIFRAME_CHECK(obj);
2254    ELM_NAVIFRAME_DATA_GET(obj, sd);
2255
2256    enabled = !!enabled;
2257    if (sd->freeze_events == !enabled) return;
2258    sd->freeze_events = !enabled;
2259 }
2260
2261 EAPI Eina_Bool
2262 elm_naviframe_event_enabled_get(const Evas_Object *obj)
2263 {
2264    ELM_NAVIFRAME_CHECK(obj) EINA_FALSE;
2265    ELM_NAVIFRAME_DATA_GET(obj, sd);
2266
2267    return !sd->freeze_events;
2268 }