1 #include <Elementary.h>
4 typedef struct _Widget_Data Widget_Data;
10 Eina_Bool preserve: 1;
11 Eina_Bool pass_events: 1;
14 struct _Elm_Naviframe_Item
19 const char *title_label;
20 const char *title_sublabel;
21 Evas_Object *title_prev_btn;
22 Evas_Object *title_next_btn;
23 Evas_Object *title_icon;
25 Eina_Bool back_btn: 1;
26 Eina_Bool title_visible: 1;
29 static const char *widtype = NULL;
31 static const char SIG_TRANSITION_FINISHED[] = "transition,finished";
32 static const char SIG_TITLE_CLICKED[] = "title,clicked";
34 static const Evas_Smart_Cb_Description _signals[] = {
35 {SIG_TRANSITION_FINISHED, ""},
36 {SIG_TITLE_CLICKED, ""},
40 #define ELM_NAVIFRAME_ITEM_CHECK_RETURN(it, ...) \
41 ELM_WIDGET_ITEM_CHECK_OR_RETURN((Elm_Widget_Item *) it, __VA_ARGS__); \
42 ELM_CHECK_WIDTYPE(it->base.widget, widtype) __VA_ARGS__;
44 static void _del_hook(Evas_Object *obj);
45 static void _theme_hook(Evas_Object *obj);
46 static void _disable_hook(Evas_Object *obj);
47 static void _sizing_eval(Evas_Object *obj);
48 static void _item_sizing_eval(Elm_Naviframe_Item *it);
49 static void _move(void *data, Evas *e, Evas_Object *obj, void *event_info);
50 static void _resize(void *data,
54 static void _title_clicked(void *data, Evas_Object *obj,
57 static void _back_btn_clicked(void *data,
60 static Evas_Object *_back_btn_new(Evas_Object *obj);
61 static void _title_prev_btn_del(void *data,
65 static void _title_next_btn_del(void *data,
69 static void _title_icon_del(void *data,
73 static void _content_del(void *data,
77 static void _title_prev_btn_set(Elm_Naviframe_Item *it,
80 static void _title_next_btn_set(Elm_Naviframe_Item *it, Evas_Object *btn);
81 static void _item_del(Elm_Naviframe_Item *it);
82 static void _pushed_finished(void *data,
86 static void _popped_finished(void *data,
90 static void _show_finished(void *data,
96 _del_hook(Evas_Object *obj)
100 Elm_Naviframe_Item *it;
102 wd = elm_widget_data_get(obj);
105 EINA_LIST_FOREACH(wd->stack, list, it)
107 eina_list_free(wd->stack);
112 _theme_hook(Evas_Object *obj __UNUSED__)
118 _disable_hook(Evas_Object *obj __UNUSED__)
124 _sizing_eval(Evas_Object *obj)
128 Elm_Naviframe_Item *it;
129 wd = elm_widget_data_get(obj);
132 list = eina_list_last(wd->stack);
135 EINA_LIST_FOREACH(wd->stack, list, it)
136 _item_sizing_eval(it);
140 _item_sizing_eval(Elm_Naviframe_Item *it)
143 Evas_Coord x, y, w, h;
146 wd = elm_widget_data_get(it->base.widget);
149 evas_object_geometry_get(it->base.widget, &x, &y, &w, &h);
150 evas_object_move(it->base.view, x, y);
151 evas_object_resize(it->base.view, w, h);
155 _move(void *data __UNUSED__,
158 void *event_info __UNUSED__)
164 _resize(void *data __UNUSED__,
167 void *event_info __UNUSED__)
173 _title_clicked(void *data,
174 Evas_Object *obj __UNUSED__,
175 const char *emission __UNUSED__,
176 const char *source __UNUSED__)
178 Elm_Naviframe_Item *it = data;
179 evas_object_smart_callback_call(it->base.widget, SIG_TITLE_CLICKED, it);
183 _back_btn_clicked(void *data,
184 Evas_Object *obj __UNUSED__,
185 void *event_info __UNUSED__)
187 elm_naviframe_item_pop(data);
191 _back_btn_new(Evas_Object *obj)
194 char buf[256]; //FIXME: How to guarantee the size of style name?
195 btn = elm_button_add(obj);
196 if (!btn) return NULL;
197 evas_object_smart_callback_add(btn, "clicked", _back_btn_clicked, obj);
198 snprintf(buf, sizeof(buf), "naviframe/back_btn/%s", elm_widget_style_get(obj));
199 elm_object_style_set(btn, buf);
204 _title_prev_btn_del(void *data,
206 Evas_Object *obj __UNUSED__,
207 void *event_info __UNUSED__)
209 Elm_Naviframe_Item *it = data;
210 it->back_btn = EINA_FALSE;
211 it->title_prev_btn = NULL;
215 _title_next_btn_del(void *data,
217 Evas_Object *obj __UNUSED__,
218 void *event_info __UNUSED__)
220 Elm_Naviframe_Item *it = data;
221 it->title_next_btn = NULL;
225 _title_icon_del(void *data,
227 Evas_Object *obj __UNUSED__,
228 void *event_info __UNUSED__)
230 Elm_Naviframe_Item *it = data;
231 it->title_icon = NULL;
232 edje_object_signal_emit(it->base.view, "elm,state,icon,hide", "elm");
236 _content_del(void *data,
238 Evas_Object *obj __UNUSED__,
239 void *event_info __UNUSED__)
241 Elm_Naviframe_Item *it = data;
243 edje_object_signal_emit(it->base.view, "elm,state,content,hide", "elm");
247 _title_prev_btn_set(Elm_Naviframe_Item *it, Evas_Object *btn, Eina_Bool back_btn)
249 char buf[256]; //FIXME: How to guarantee the size of style name?
251 if (it->title_prev_btn == btn) return;
253 if (it->title_prev_btn)
254 evas_object_del(it->title_prev_btn);
256 it->title_prev_btn = btn;
264 "naviframe/prev_btn/%s",
265 elm_widget_style_get(it->base.widget));
266 elm_object_style_set(btn, buf);
268 elm_widget_sub_object_add(it->base.widget, btn);
269 evas_object_event_callback_add(btn,
273 edje_object_part_swallow(it->title, "elm.swallow.prev_btn", btn);
274 it->back_btn = back_btn;
278 _title_next_btn_set(Elm_Naviframe_Item *it, Evas_Object *btn)
280 char buf[256]; //FIXME: How to guarantee the size of style name?
282 if (it->title_next_btn == btn) return;
284 if (it->title_next_btn)
285 evas_object_del(it->title_next_btn);
287 it->title_next_btn = btn;
293 "naviframe/next_btn/%s",
294 elm_widget_style_get(it->base.widget));
295 elm_object_style_set(btn, buf);
296 elm_widget_sub_object_add(it->base.widget, btn);
297 evas_object_event_callback_add(btn,
301 edje_object_part_swallow(it->title, "elm.swallow.next_btn", btn);
305 _item_del(Elm_Naviframe_Item *it)
311 wd = elm_widget_data_get(it->base.widget);
314 if (it->title_prev_btn)
315 evas_object_del(it->title_prev_btn);
316 if (it->title_next_btn)
317 evas_object_del(it->title_next_btn);
319 evas_object_del(it->title_icon);
320 if ((it->content) && (!wd->preserve))
321 evas_object_del(it->content);
323 evas_object_del(it->title);
324 evas_object_del(it->base.view);
326 wd->stack = eina_list_remove(wd->stack, it);
332 _pushed_finished(void *data,
333 Evas_Object *obj __UNUSED__,
334 const char *emission __UNUSED__,
335 const char *source __UNUSED__)
337 Elm_Naviframe_Item *it = data;
339 evas_object_hide(it->base.view);
343 _popped_finished(void *data,
344 Evas_Object *obj __UNUSED__,
345 const char *emission __UNUSED__,
346 const char *source __UNUSED__)
352 _show_finished(void *data,
353 Evas_Object *obj __UNUSED__,
354 const char *emission __UNUSED__,
355 const char *source __UNUSED__)
357 Elm_Naviframe_Item *it;
362 wd = elm_widget_data_get(it->base.widget);
365 evas_object_smart_callback_call(it->base.widget,
366 SIG_TRANSITION_FINISHED,
369 evas_object_pass_events_set(wd->base, EINA_FALSE);
373 elm_naviframe_add(Evas_Object *parent)
379 ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL);
380 ELM_SET_WIDTYPE(widtype, "naviframe");
381 elm_widget_type_set(obj, "naviframe");
382 elm_widget_sub_object_add(parent, obj);
383 elm_widget_data_set(obj, wd);
384 elm_widget_del_hook_set(obj, _del_hook);
385 elm_widget_disable_hook_set(obj, _disable_hook);
386 elm_widget_theme_hook_set(obj, _theme_hook);
389 wd->base = edje_object_add(e);
390 elm_widget_resize_object_set(obj, wd->base);
391 _elm_theme_object_set(obj, wd->base, "naviframe", "base", "default");
393 evas_object_event_callback_add(obj, EVAS_CALLBACK_MOVE, _move, obj);
394 evas_object_event_callback_add(obj, EVAS_CALLBACK_RESIZE, _resize, obj);
395 evas_object_smart_callbacks_descriptions_set(obj, _signals);
397 wd->pass_events = EINA_TRUE;
402 EAPI Elm_Naviframe_Item *
403 elm_naviframe_item_push(Evas_Object *obj, const char *title_label, Evas_Object *prev_btn, Evas_Object *next_btn, Evas_Object *content, const char *item_style)
405 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
407 Elm_Naviframe_Item *prev_it, *it;
409 wd = elm_widget_data_get(obj);
410 if (!wd) return NULL;
413 it = elm_widget_item_new(obj, Elm_Naviframe_Item);
416 ERR("Failed to allocate new item! : naviframe=%p", obj);
420 it->base.view = edje_object_add(evas_object_evas_get(obj));
421 evas_object_smart_member_add(it->base.view, wd->base);
422 elm_widget_sub_object_add(obj, it->base.view);
423 edje_object_signal_callback_add(it->base.view,
424 "elm,action,show,finished",
427 edje_object_signal_callback_add(it->base.view,
428 "elm,action,pushed,finished",
430 _pushed_finished, it);
431 edje_object_signal_callback_add(it->base.view,
432 "elm,action,popped,finished",
434 _popped_finished, it);
435 elm_naviframe_item_style_set(it, item_style);
438 it->title = edje_object_add(evas_object_evas_get(obj));
439 elm_widget_sub_object_add(obj, it->title);
440 _elm_theme_object_set(obj,
441 it->title, "naviframe",
443 elm_widget_style_get(obj));
444 edje_object_signal_callback_add(it->title,
445 "elm,action,clicked",
449 elm_naviframe_item_title_label_set(it, title_label);
452 if ((!prev_btn) && (eina_list_count(wd->stack)))
454 prev_btn = _back_btn_new(obj);
455 _title_prev_btn_set(it, prev_btn, EINA_TRUE);
458 _title_prev_btn_set(it, prev_btn, EINA_FALSE);
460 _title_next_btn_set(it, next_btn);
461 edje_object_part_swallow(it->base.view, "elm.swallow.title", it->title);
463 elm_naviframe_item_content_set(it, content);
465 _item_sizing_eval(it);
466 evas_object_show(it->base.view);
468 prev_it = elm_naviframe_top_item_get(obj);
472 evas_object_pass_events_set(wd->base, EINA_TRUE);
473 edje_object_signal_emit(prev_it->base.view,
476 edje_object_signal_emit(it->base.view,
481 edje_object_signal_emit(it->base.view, "elm,state,visible", "elm");
482 it->title_visible = EINA_TRUE;
483 wd->stack = eina_list_append(wd->stack, it);
488 elm_naviframe_item_pop(Evas_Object *obj)
490 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
491 Elm_Naviframe_Item *it, *prev_it;
493 Evas_Object *content = NULL;
495 wd = elm_widget_data_get(obj);
496 if (!wd) return NULL;
498 it = elm_naviframe_top_item_get(obj);
499 if (!it) return NULL;
500 wd->stack = eina_list_remove(wd->stack, it);
503 content = it->content;
505 prev_it = elm_naviframe_top_item_get(obj);
509 evas_object_pass_events_set(wd->base, EINA_TRUE);
510 evas_object_show(prev_it->base.view);
511 evas_object_raise(prev_it->base.view);
512 edje_object_signal_emit(prev_it->base.view,
515 edje_object_signal_emit(it->base.view, "elm,state,popped", "elm");
524 elm_naviframe_content_preserve_on_pop_set(Evas_Object *obj, Eina_Bool preserve)
526 ELM_CHECK_WIDTYPE(obj, widtype);
527 Widget_Data *wd = elm_widget_data_get(obj);
529 wd->preserve = !!preserve;
533 elm_naviframe_content_preserve_on_pop_get(const Evas_Object *obj)
535 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
536 Widget_Data *wd = elm_widget_data_get(obj);
537 if (!wd) return EINA_FALSE;
542 elm_naviframe_item_content_set(Elm_Naviframe_Item *it, Evas_Object *content)
544 ELM_NAVIFRAME_ITEM_CHECK_RETURN(it);
546 if (it->content == content) return;
547 if (it->content) evas_object_del(it->content);
548 elm_widget_sub_object_add(it->base.widget, content);
549 edje_object_part_swallow(it->base.view, "elm.swallow.content", content);
551 edje_object_signal_emit(it->base.view,
552 "elm,state,content,show",
555 edje_object_signal_emit(it->base.view,
556 "elm,state,content,hide",
558 evas_object_event_callback_add(content,
562 it->content = content;
563 _item_sizing_eval(it);
567 elm_naviframe_item_content_get(const Elm_Naviframe_Item *it)
569 ELM_NAVIFRAME_ITEM_CHECK_RETURN(it, NULL);
574 elm_naviframe_item_title_label_set(Elm_Naviframe_Item *it, const char *label)
576 ELM_NAVIFRAME_ITEM_CHECK_RETURN(it);
578 edje_object_part_text_set(it->title, "elm.text.title", label);
580 edje_object_signal_emit(it->title, "elm,state,title,show", "elm");
582 edje_object_signal_emit(it->title, "elm,state,title,hidew", "elm");
584 eina_stringshare_replace(&it->title_label, label);
585 _item_sizing_eval(it);
589 elm_naviframe_item_title_label_get(const Elm_Naviframe_Item *it)
591 ELM_NAVIFRAME_ITEM_CHECK_RETURN(it, NULL);
592 return it->title_label;
596 elm_naviframe_item_subtitle_label_set(Elm_Naviframe_Item *it, const char *label)
598 ELM_NAVIFRAME_ITEM_CHECK_RETURN(it);
600 edje_object_part_text_set(it->title, "elm.text.subtitle", label);
602 edje_object_signal_emit(it->title, "elm,state,subtitle,show", "elm");
604 edje_object_signal_emit(it->title, "elm,state,subtitle,hide", "elm");
606 eina_stringshare_replace(&it->title_sublabel, label);
607 _item_sizing_eval(it);
611 elm_naviframe_item_subtitle_label_get(const Elm_Naviframe_Item *it)
613 ELM_NAVIFRAME_ITEM_CHECK_RETURN(it, NULL);
614 return it->title_sublabel;
617 EAPI Elm_Naviframe_Item*
618 elm_naviframe_top_item_get(const Evas_Object *obj)
620 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
621 Widget_Data *wd = elm_widget_data_get(obj);
622 if ((!wd) || (!wd->stack)) return NULL;
623 return eina_list_last(wd->stack)->data;
626 EAPI Elm_Naviframe_Item*
627 elm_naviframe_bottom_item_get(const Evas_Object *obj)
629 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
630 Widget_Data *wd = elm_widget_data_get(obj);
631 if (!wd) return NULL;
636 elm_naviframe_item_button_set(Elm_Naviframe_Item *it, Evas_Object *btn, Elm_Naviframe_Button_Type btn_type)
638 ELM_NAVIFRAME_ITEM_CHECK_RETURN(it);
642 case ELM_NAVIFRAME_PREV_BUTTON:
643 _title_prev_btn_set(it, btn, EINA_FALSE);
645 case ELM_NAVIFRAME_NEXT_BUTTON:
646 _title_next_btn_set(it, btn);
649 WRN("Button type is invalid! : naviframe=%p", it->base.widget);
652 _item_sizing_eval(it);
656 elm_naviframe_item_button_get(const Elm_Naviframe_Item *it, Elm_Naviframe_Button_Type btn_type)
658 ELM_NAVIFRAME_ITEM_CHECK_RETURN(it, NULL);
662 case ELM_NAVIFRAME_PREV_BUTTON:
663 return it->title_prev_btn;
664 case ELM_NAVIFRAME_NEXT_BUTTON:
665 return it->title_next_btn;
667 WRN("Button type is invalid! : naviframe=%p", it->base.widget);
674 elm_naviframe_item_icon_set(Elm_Naviframe_Item *it, Evas_Object *icon)
676 ELM_NAVIFRAME_ITEM_CHECK_RETURN(it);
678 Widget_Data *wd = elm_widget_data_get(it->base.widget);
681 if (it->title_icon == icon) return;
682 if (it->title_icon) evas_object_del(it->title_icon);
683 it->title_icon = icon;
686 edje_object_signal_emit(it->title,
687 "elm,state,icon,hide",
691 elm_widget_sub_object_add(it->base.widget, icon);
692 edje_object_part_swallow(it->title, "elm.swallow.icon", icon);
693 edje_object_signal_emit(it->title, "elm,state,icon,show", "elm");
695 evas_object_event_callback_add(icon, EVAS_CALLBACK_DEL, _title_icon_del, it);
696 _item_sizing_eval(it);
700 elm_naviframe_item_icon_get(const Elm_Naviframe_Item *it)
702 ELM_NAVIFRAME_ITEM_CHECK_RETURN(it, NULL);
703 return it->title_icon;
707 elm_naviframe_item_style_set(Elm_Naviframe_Item *it, const char *item_style)
709 ELM_NAVIFRAME_ITEM_CHECK_RETURN(it);
713 if (!item_style) sprintf(buf, "item/basic");
716 if (strlen(item_style) > sizeof(buf))
717 WRN("too much long style name! : naviframe=%p", it->base.widget);
719 sprintf(buf, "item/%s", item_style);
721 _elm_theme_object_set(it->base.widget,
725 elm_widget_style_get(it->base.widget));
729 elm_naviframe_item_style_get(const Elm_Naviframe_Item *it)
731 ELM_NAVIFRAME_ITEM_CHECK_RETURN(it, NULL);
736 elm_naviframe_item_title_visible_set(Elm_Naviframe_Item *it, Eina_Bool visible)
738 ELM_NAVIFRAME_ITEM_CHECK_RETURN(it);
741 if (it->title_visible == visible) return;
744 edje_object_signal_emit(it->base.view, "elm,state,title,show", "elm");
746 edje_object_signal_emit(it->base.view, "elm,state,title,hide", "elm");
748 it->title_visible = visible;
752 elm_naviframe_item_title_visible_get(const Elm_Naviframe_Item *it)
754 ELM_NAVIFRAME_ITEM_CHECK_RETURN(it, EINA_FALSE);
755 return it->title_visible;
759 elm_naviframe_extension_set(Elm_Naviframe_Item *it, const char *swallow, Evas_Object *extension)
761 ELM_NAVIFRAME_ITEM_CHECK_RETURN(it);
762 Evas_Object *prev = elm_naviframe_extension_get(it, swallow);
763 if (prev) evas_object_del(prev);
764 edje_object_part_swallow(it->base.view, swallow, extension);
765 _sizing_eval(it->base.view);
769 elm_naviframe_extension_unset(Elm_Naviframe_Item *it, const char *swallow)
771 ELM_NAVIFRAME_ITEM_CHECK_RETURN(it, NULL);
772 Evas_Object *part_obj;
773 part_obj = edje_object_part_swallow_get(it->base.view, swallow);
774 if (!part_obj) return NULL;
775 edje_object_part_unswallow(it->base.view, part_obj);
776 _sizing_eval(it->base.widget);
781 elm_naviframe_extension_get(const Elm_Naviframe_Item *it, const char *swallow)
783 ELM_NAVIFRAME_ITEM_CHECK_RETURN(it, NULL);
784 Evas_Object *part_obj;
785 part_obj = edje_object_part_swallow_get(it->base.view, swallow);
790 elm_naviframe_item_promote(Elm_Naviframe_Item *it)
795 elm_naviframe_to_item_pop(Elm_Naviframe_Item *it)
801 elm_naviframe_extension_visible_set(Elm_Naviframe_Item *it, Eina_Bool visible)
806 elm_naviframe_extension_visible_get(const Elm_Naviframe_Item *it)