1 #include <Elementary.h>
4 static const char SMART_NAME[] = "elm_widget";
7 Smart_Data * sd = evas_object_smart_data_get(obj); \
8 if ((!sd) || (!_elm_widget_is(obj)))
9 #define INTERNAL_ENTRY \
10 Smart_Data * sd = evas_object_smart_data_get(obj); \
13 #undef elm_widget_text_set_hook_set
14 #undef elm_widget_text_get_hook_set
15 #undef elm_widget_content_set_hook_set
16 #undef elm_widget_content_get_hook_set
17 #undef elm_widget_content_unset_hook_set
19 typedef struct _Smart_Data Smart_Data;
20 typedef struct _Edje_Signal_Data Edje_Signal_Data;
21 typedef struct _Elm_Event_Cb_Data Elm_Event_Cb_Data;
22 typedef struct _Elm_Translate_String_Data Elm_Translate_String_Data;
28 Evas_Object *parent_obj;
30 Evas_Coord x, y, w, h;
32 Evas_Object *resize_obj;
33 Evas_Object *hover_obj;
34 Eina_List *tooltips, *cursors;
35 void (*del_func)(Evas_Object *obj);
36 void (*del_pre_func)(Evas_Object *obj);
37 void (*focus_func)(Evas_Object *obj);
38 void (*activate_func)(Evas_Object *obj);
39 void (*disable_func)(Evas_Object *obj);
40 void (*theme_func)(Evas_Object *obj);
41 void (*translate_func)(Evas_Object *obj);
42 Eina_Bool (*event_func)(Evas_Object *obj,
44 Evas_Callback_Type type,
46 void (*signal_func)(Evas_Object *obj,
49 void (*callback_add_func)(Evas_Object *obj,
54 void (*callback_del_func)(Evas_Object *obj,
59 void (*changed_func)(Evas_Object *obj);
60 Eina_Bool (*focus_next_func)(const Evas_Object *obj,
61 Elm_Focus_Direction dir,
63 void (*on_focus_func)(void *data,
66 void (*on_change_func)(void *data,
69 void (*on_show_region_func)(void *data,
71 void *on_show_region_data;
72 void (*focus_region_func)(Evas_Object *obj,
77 void (*on_focus_region_func)(const Evas_Object *obj,
82 Elm_Widget_Text_Set_Cb text_set_func;
83 Elm_Widget_Text_Get_Cb text_get_func;
84 Elm_Widget_Content_Set_Cb content_set_func;
85 Elm_Widget_Content_Get_Cb content_get_func;
86 Elm_Widget_Content_Unset_Cb content_unset_func;
88 Evas_Coord rx, ry, rw, rh;
94 const char *access_info;
95 unsigned int focus_order;
96 Eina_Bool focus_order_on_calc;
98 int child_drag_x_locked;
99 int child_drag_y_locked;
101 Eina_List *edje_signals;
102 Eina_List *translate_strings;
104 Eina_Bool drag_x_locked : 1;
105 Eina_Bool drag_y_locked : 1;
107 Eina_Bool can_focus : 1;
108 Eina_Bool child_can_focus : 1;
109 Eina_Bool focused : 1;
110 Eina_Bool top_win_focused : 1;
111 Eina_Bool tree_unfocusable : 1;
112 Eina_Bool highlight_ignore : 1;
113 Eina_Bool highlight_in_theme : 1;
114 Eina_Bool disabled : 1;
115 Eina_Bool is_mirrored : 1;
116 Eina_Bool mirrored_auto_mode : 1; /* This is TRUE by default */
117 Eina_Bool still_in : 1;
119 Eina_List *focus_chain;
123 struct _Edje_Signal_Data
127 const char *emission;
132 struct _Elm_Event_Cb_Data
138 struct _Elm_Translate_String_Data
145 /* local subsystem functions */
146 static void _smart_reconfigure(Smart_Data *sd);
147 static void _smart_add(Evas_Object *obj);
148 static void _smart_del(Evas_Object *obj);
149 static void _smart_move(Evas_Object *obj,
152 static void _smart_resize(Evas_Object *obj,
155 static void _smart_show(Evas_Object *obj);
156 static void _smart_hide(Evas_Object *obj);
157 static void _smart_color_set(Evas_Object *obj,
162 static void _smart_clip_set(Evas_Object *obj,
164 static void _smart_clip_unset(Evas_Object *obj);
165 static void _smart_calculate(Evas_Object *obj);
166 static void _smart_member_add(Evas_Object *obj, Evas_Object *child);
167 static void _smart_member_del(Evas_Object *obj, Evas_Object *child);
168 static void _smart_init(void);
170 static void _if_focused_revert(Evas_Object *obj,
171 Eina_Bool can_focus_only);
172 static Evas_Object *_newest_focus_order_get(Evas_Object *obj,
173 unsigned int *newest_focus_order,
174 Eina_Bool can_focus_only);
176 /* local subsystem globals */
177 static Evas_Smart *_e_smart = NULL;
178 static Eina_List *widtypes = NULL;
180 static unsigned int focus_order = 0;
183 static inline Eina_Bool
184 _elm_widget_is(const Evas_Object *obj)
186 const char *type = evas_object_type_get(obj);
187 return type == SMART_NAME;
190 static inline Eina_Bool
191 _is_focusable(Evas_Object *obj)
193 API_ENTRY return EINA_FALSE;
194 return sd->can_focus || (sd->child_can_focus);
198 _unfocus_parents(Evas_Object *obj)
200 for (; obj; obj = elm_widget_parent_get(obj))
203 if (!sd->focused) return;
209 _focus_parents(Evas_Object *obj)
211 for (; obj; obj = elm_widget_parent_get(obj))
214 if (sd->focused) return;
220 _sub_obj_del(void *data,
223 void *event_info __UNUSED__)
225 Smart_Data *sd = data;
227 if (_elm_widget_is(obj))
229 if (elm_widget_focus_get(obj)) _unfocus_parents(sd->obj);
231 if (obj == sd->resize_obj)
232 sd->resize_obj = NULL;
233 else if (obj == sd->hover_obj)
234 sd->hover_obj = NULL;
236 sd->subobjs = eina_list_remove(sd->subobjs, obj);
237 evas_object_smart_callback_call(sd->obj, "sub-object-del", obj);
241 _sub_obj_hide(void *data __UNUSED__,
244 void *event_info __UNUSED__)
246 elm_widget_focus_hide_handle(obj);
250 _sub_obj_mouse_down(void *data,
252 Evas_Object *obj __UNUSED__,
255 Smart_Data *sd = data;
256 Evas_Event_Mouse_Down *ev = event_info;
257 if (!(ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD))
258 sd->still_in = EINA_TRUE;
262 _sub_obj_mouse_move(void *data,
267 Smart_Data *sd = data;
268 Evas_Event_Mouse_Move *ev = event_info;
271 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD)
272 sd->still_in = EINA_FALSE;
275 Evas_Coord x, y, w, h;
276 evas_object_geometry_get(obj, &x, &y, &w, &h);
277 if ((ev->cur.canvas.x < x) || (ev->cur.canvas.y < y) ||
278 (ev->cur.canvas.x >= (x + w)) || (ev->cur.canvas.y >= (y + h)))
279 sd->still_in = EINA_FALSE;
285 _sub_obj_mouse_up(void *data,
288 void *event_info __UNUSED__)
290 Smart_Data *sd = data;
292 elm_widget_focus_mouse_up_handle(obj);
293 sd->still_in = EINA_FALSE;
297 _propagate_x_drag_lock(Evas_Object *obj,
303 Smart_Data *sd2 = evas_object_smart_data_get(sd->parent_obj);
306 sd2->child_drag_x_locked += dir;
307 _propagate_x_drag_lock(sd->parent_obj, dir);
313 _propagate_y_drag_lock(Evas_Object *obj,
319 Smart_Data *sd2 = evas_object_smart_data_get(sd->parent_obj);
322 sd2->child_drag_y_locked += dir;
323 _propagate_y_drag_lock(sd->parent_obj, dir);
329 _propagate_event(void *data,
335 Evas_Callback_Type type = (Evas_Callback_Type)(long)data;
336 Evas_Event_Flags *event_flags = NULL;
340 case EVAS_CALLBACK_KEY_DOWN:
342 Evas_Event_Key_Down *ev = event_info;
343 event_flags = &(ev->event_flags);
347 case EVAS_CALLBACK_KEY_UP:
349 Evas_Event_Key_Up *ev = event_info;
350 event_flags = &(ev->event_flags);
354 case EVAS_CALLBACK_MOUSE_WHEEL:
356 Evas_Event_Mouse_Wheel *ev = event_info;
357 event_flags = &(ev->event_flags);
365 elm_widget_event_propagate(obj, type, event_info, event_flags);
369 _parent_focus(Evas_Object *obj)
372 if (sd->focused) return;
374 Evas_Object *o = elm_widget_parent_get(obj);
375 sd->focus_order_on_calc = EINA_TRUE;
377 if (o) _parent_focus(o);
379 if (!sd->focus_order_on_calc)
380 return; /* we don't want to override it if by means of any of the
381 callbacks below one gets to calculate our order
385 sd->focus_order = focus_order;
386 if (sd->top_win_focused)
388 sd->focused = EINA_TRUE;
389 if (sd->on_focus_func) sd->on_focus_func(sd->on_focus_data, obj);
390 if (sd->focus_func) sd->focus_func(obj);
391 _elm_widget_focus_region_show(obj);
393 sd->focus_order_on_calc = EINA_FALSE;
397 _elm_object_focus_chain_del_cb(void *data,
400 void *event_info __UNUSED__)
402 Smart_Data *sd = data;
404 sd->focus_chain = eina_list_remove(sd->focus_chain, obj);
407 // exposed util funcs to elm
409 _elm_widget_type_clear(void)
413 EINA_LIST_FREE(widtypes, ptr)
415 eina_stringshare_del(*ptr);
421 _elm_widget_focus_region_show(const Evas_Object *obj)
423 Evas_Coord x, y, w, h, ox, oy;
429 o = elm_widget_parent_get(obj);
432 elm_widget_focus_region_get(obj, &x, &y, &w, &h);
433 evas_object_geometry_get(obj, &ox, &oy, NULL, NULL);
437 sd2 = evas_object_smart_data_get(o);
438 if (sd2->focus_region_func)
440 sd2->focus_region_func(o, x, y, w, h);
441 elm_widget_focus_region_get(o, &x, &y, &w, &h);
445 evas_object_geometry_get(o, &px, &py, NULL, NULL);
451 o = elm_widget_parent_get(o);
456 * @defgroup Widget Widget
459 * Exposed api for making widgets
462 elm_widget_type_register(const char **ptr)
464 widtypes = eina_list_append(widtypes, (void *)ptr);
468 * @defgroup Widget Widget
471 * Disposed api for making widgets
474 elm_widget_type_unregister(const char **ptr)
476 widtypes = eina_list_remove(widtypes, (void *)ptr);
480 elm_widget_api_check(int ver)
482 if (ver != ELM_INTERNAL_API_VERSION)
484 CRITICAL("Elementary widget api versions do not match");
491 elm_widget_add(Evas *evas)
495 obj = evas_object_smart_add(evas, _e_smart);
496 elm_widget_mirrored_set(obj, elm_config_mirrored_get());
501 elm_widget_del_hook_set(Evas_Object *obj,
502 void (*func)(Evas_Object *obj))
509 elm_widget_del_pre_hook_set(Evas_Object *obj,
510 void (*func)(Evas_Object *obj))
513 sd->del_pre_func = func;
517 elm_widget_focus_hook_set(Evas_Object *obj,
518 void (*func)(Evas_Object *obj))
521 sd->focus_func = func;
525 elm_widget_activate_hook_set(Evas_Object *obj,
526 void (*func)(Evas_Object *obj))
529 sd->activate_func = func;
533 elm_widget_disable_hook_set(Evas_Object *obj,
534 void (*func)(Evas_Object *obj))
537 sd->disable_func = func;
541 elm_widget_theme_hook_set(Evas_Object *obj,
542 void (*func)(Evas_Object *obj))
545 sd->theme_func = func;
549 elm_widget_translate_hook_set(Evas_Object *obj,
550 void (*func)(Evas_Object *obj))
553 sd->translate_func = func;
557 elm_widget_event_hook_set(Evas_Object *obj,
558 Eina_Bool (*func)(Evas_Object *obj,
560 Evas_Callback_Type type,
564 sd->event_func = func;
568 elm_widget_text_set_hook_set(Evas_Object *obj,
569 Elm_Widget_Text_Set_Cb func)
572 sd->text_set_func = func;
576 elm_widget_text_get_hook_set(Evas_Object *obj,
577 Elm_Widget_Text_Get_Cb func)
580 sd->text_get_func = func;
584 elm_widget_content_set_hook_set(Evas_Object *obj,
585 Elm_Widget_Content_Set_Cb func)
588 sd->content_set_func = func;
592 elm_widget_content_get_hook_set(Evas_Object *obj,
593 Elm_Widget_Content_Get_Cb func)
596 sd->content_get_func = func;
600 elm_widget_content_unset_hook_set(Evas_Object *obj,
601 Elm_Widget_Content_Unset_Cb func)
604 sd->content_unset_func = func;
608 elm_widget_changed_hook_set(Evas_Object *obj,
609 void (*func)(Evas_Object *obj))
612 sd->changed_func = func;
616 elm_widget_signal_emit_hook_set(Evas_Object *obj,
617 void (*func)(Evas_Object *obj,
618 const char *emission,
622 sd->signal_func = func;
626 elm_widget_signal_callback_add_hook_set(Evas_Object *obj,
627 void (*func)(Evas_Object *obj,
628 const char *emission,
630 Edje_Signal_Cb func_cb,
634 sd->callback_add_func = func;
638 elm_widget_signal_callback_del_hook_set(Evas_Object *obj,
639 void (*func)(Evas_Object *obj,
640 const char *emission,
642 Edje_Signal_Cb func_cb,
646 sd->callback_del_func = func;
650 elm_widget_theme(Evas_Object *obj)
656 Eina_Bool ret = EINA_TRUE;
658 API_ENTRY return EINA_FALSE;
659 EINA_LIST_FOREACH(sd->subobjs, l, child) ret &= elm_widget_theme(child);
660 if (sd->resize_obj && _elm_widget_is(sd->resize_obj))
661 ret &= elm_widget_theme(sd->resize_obj);
662 if (sd->hover_obj) ret &= elm_widget_theme(sd->hover_obj);
663 EINA_LIST_FOREACH(sd->tooltips, l, tt) elm_tooltip_theme(tt);
664 EINA_LIST_FOREACH(sd->cursors, l, cur) elm_cursor_theme(cur);
665 if (sd->theme_func) sd->theme_func(obj);
671 elm_widget_theme_specific(Evas_Object *obj,
679 Elm_Theme *th2, *thdef;
682 thdef = elm_theme_default_get();
687 if (!th2) th2 = thdef;
695 if (th2 == thdef) break;
696 th2 = th2->ref_theme;
697 if (!th2) th2 = thdef;
701 EINA_LIST_FOREACH(sd->subobjs, l, child)
702 elm_widget_theme_specific(child, th, force);
703 if (sd->resize_obj) elm_widget_theme(sd->resize_obj);
704 if (sd->hover_obj) elm_widget_theme(sd->hover_obj);
705 EINA_LIST_FOREACH(sd->tooltips, l, tt) elm_tooltip_theme(tt);
706 EINA_LIST_FOREACH(sd->cursors, l, cur) elm_cursor_theme(cur);
707 if (sd->theme_func) sd->theme_func(obj);
713 * Set hook to get next object in object focus chain.
715 * @param obj The widget object.
716 * @param func The hook to be used with this widget.
721 elm_widget_focus_next_hook_set(Evas_Object *obj,
722 Eina_Bool (*func)(const Evas_Object *obj,
723 Elm_Focus_Direction dir,
727 sd->focus_next_func = func;
731 * Returns the widget's mirrored mode.
733 * @param obj The widget.
734 * @return mirrored mode of the object.
738 elm_widget_mirrored_get(const Evas_Object *obj)
740 API_ENTRY return EINA_FALSE;
741 return sd->is_mirrored;
745 * Sets the widget's mirrored mode.
747 * @param obj The widget.
748 * @param mirrored EINA_TRUE to set mirrored mode. EINA_FALSE to unset.
751 elm_widget_mirrored_set(Evas_Object *obj,
755 if (sd->is_mirrored != mirrored)
757 sd->is_mirrored = mirrored;
758 elm_widget_theme(obj);
764 * Resets the mirrored mode from the system mirror mode for widgets that are in
765 * automatic mirroring mode. This function does not call elm_widget_theme.
767 * @param obj The widget.
768 * @param mirrored EINA_TRUE to set mirrored mode. EINA_FALSE to unset.
771 _elm_widget_mirrored_reload(Evas_Object *obj)
774 Eina_Bool mirrored = elm_config_mirrored_get();
775 if (elm_widget_mirrored_automatic_get(obj) && (sd->is_mirrored != mirrored))
777 sd->is_mirrored = mirrored;
782 * Returns the widget's mirrored mode setting.
784 * @param obj The widget.
785 * @return mirrored mode setting of the object.
789 elm_widget_mirrored_automatic_get(const Evas_Object *obj)
791 API_ENTRY return EINA_FALSE;
792 return sd->mirrored_auto_mode;
796 * Sets the widget's mirrored mode setting.
797 * When widget in automatic mode, it follows the system mirrored mode set by
798 * elm_mirrored_set().
799 * @param obj The widget.
800 * @param automatic EINA_TRUE for auto mirrored mode. EINA_FALSE for manual.
803 elm_widget_mirrored_automatic_set(Evas_Object *obj,
807 if (sd->mirrored_auto_mode != automatic)
809 sd->mirrored_auto_mode = automatic;
813 elm_widget_mirrored_set(obj, elm_config_mirrored_get());
819 elm_widget_on_focus_hook_set(Evas_Object *obj,
820 void (*func)(void *data,
825 sd->on_focus_func = func;
826 sd->on_focus_data = data;
830 elm_widget_on_change_hook_set(Evas_Object *obj,
831 void (*func)(void *data,
836 sd->on_change_func = func;
837 sd->on_change_data = data;
841 elm_widget_on_show_region_hook_set(Evas_Object *obj,
842 void (*func)(void *data,
847 sd->on_show_region_func = func;
848 sd->on_show_region_data = data;
854 * Set the hook to use to show the focused region.
856 * Whenever a new widget gets focused or it's needed to show the focused
857 * area of the current one, this hook will be called on objects that may
858 * want to move their children into their visible area.
859 * The area given in the hook function is relative to the @p obj widget.
861 * @param obj The widget object
862 * @param func The function to call to show the specified area.
867 elm_widget_focus_region_hook_set(Evas_Object *obj,
868 void (*func)(Evas_Object *obj,
875 sd->focus_region_func = func;
881 * Set the hook to retrieve the focused region of a widget.
883 * This hook will be called by elm_widget_focus_region_get() whenever
884 * it's needed to get the focused area of a widget. The area must be relative
885 * to the widget itself and if no hook is set, it will default to the entire
888 * @param obj The widget object
889 * @param func The function used to retrieve the focus region.
894 elm_widget_on_focus_region_hook_set(Evas_Object *obj,
895 void (*func)(const Evas_Object *obj,
902 sd->on_focus_region_func = func;
906 elm_widget_data_set(Evas_Object *obj,
914 elm_widget_data_get(const Evas_Object *obj)
916 API_ENTRY return NULL;
921 elm_widget_sub_object_add(Evas_Object *obj,
925 double scale, pscale = elm_widget_scale_get(sobj);
926 Elm_Theme *th, *pth = elm_widget_theme_get(sobj);
927 Eina_Bool mirrored, pmirrored = elm_widget_mirrored_get(obj);
929 if (sobj == sd->parent_obj)
931 elm_widget_sub_object_del(sobj, obj);
932 WRN("You passed a parent object of obj = %p as the sub object = %p!", obj, sobj);
935 if (_elm_widget_is(sobj))
937 Smart_Data *sd2 = evas_object_smart_data_get(sobj);
940 if (sd2->parent_obj == obj)
943 elm_widget_sub_object_del(sd2->parent_obj, sobj);
944 sd2->parent_obj = obj;
945 _elm_widget_top_win_focused_set(sobj, sd->top_win_focused);
946 if (!sd->child_can_focus && (_is_focusable(sobj)))
947 sd->child_can_focus = EINA_TRUE;
952 void *data = evas_object_data_get(sobj, "elm-parent");
955 if (data == obj) return;
956 evas_object_event_callback_del(sobj, EVAS_CALLBACK_DEL,
960 sd->subobjs = eina_list_append(sd->subobjs, sobj);
961 evas_object_data_set(sobj, "elm-parent", obj);
962 evas_object_event_callback_add(sobj, EVAS_CALLBACK_DEL, _sub_obj_del, sd);
963 if (_elm_widget_is(sobj))
964 evas_object_event_callback_add(sobj, EVAS_CALLBACK_HIDE, _sub_obj_hide, sd);
965 evas_object_smart_callback_call(obj, "sub-object-add", sobj);
966 scale = elm_widget_scale_get(sobj);
967 th = elm_widget_theme_get(sobj);
968 mirrored = elm_widget_mirrored_get(sobj);
969 if ((scale != pscale) || (th != pth) || (pmirrored != mirrored)) elm_widget_theme(sobj);
970 if (elm_widget_focus_get(sobj)) _focus_parents(obj);
974 elm_widget_sub_object_del(Evas_Object *obj,
977 Evas_Object *sobj_parent;
981 sobj_parent = evas_object_data_del(sobj, "elm-parent");
982 if (sobj_parent != obj)
984 static int abort_on_warn = -1;
985 ERR("removing sub object %p (%s) from parent %p (%s), "
986 "but elm-parent is different %p (%s)!",
987 sobj, elm_widget_type_get(sobj), obj, elm_widget_type_get(obj),
988 sobj_parent, elm_widget_type_get(sobj_parent));
989 if (EINA_UNLIKELY(abort_on_warn == -1))
991 if (getenv("ELM_ERROR_ABORT")) abort_on_warn = 1;
992 else abort_on_warn = 0;
994 if (abort_on_warn == 1) abort();
996 if (_elm_widget_is(sobj))
998 if (elm_widget_focus_get(sobj))
1000 elm_widget_tree_unfocusable_set(sobj, EINA_TRUE);
1001 elm_widget_tree_unfocusable_set(sobj, EINA_FALSE);
1003 if ((sd->child_can_focus) && (_is_focusable(sobj)))
1005 Evas_Object *subobj;
1007 sd->child_can_focus = EINA_FALSE;
1008 EINA_LIST_FOREACH(sd->subobjs, l, subobj)
1010 if (_is_focusable(subobj))
1012 sd->child_can_focus = EINA_TRUE;
1017 Smart_Data *sd2 = evas_object_smart_data_get(sobj);
1020 sd2->parent_obj = NULL;
1021 if (sd2->resize_obj == sobj)
1022 sd2->resize_obj = NULL;
1024 sd->subobjs = eina_list_remove(sd->subobjs, sobj);
1027 sd->subobjs = eina_list_remove(sd->subobjs, sobj);
1030 sd->subobjs = eina_list_remove(sd->subobjs, sobj);
1031 evas_object_event_callback_del_full(sobj, EVAS_CALLBACK_DEL,
1033 if (_elm_widget_is(sobj))
1034 evas_object_event_callback_del_full(sobj, EVAS_CALLBACK_HIDE,
1036 evas_object_smart_callback_call(obj, "sub-object-del", sobj);
1040 elm_widget_resize_object_set(Evas_Object *obj,
1044 // orphan previous resize obj
1047 evas_object_clip_unset(sd->resize_obj);
1048 evas_object_data_del(sd->resize_obj, "elm-parent");
1049 if (_elm_widget_is(sd->resize_obj))
1051 Smart_Data *sd2 = evas_object_smart_data_get(sd->resize_obj);
1052 if (sd2) sd2->parent_obj = NULL;
1053 evas_object_event_callback_del_full(sd->resize_obj,
1057 evas_object_event_callback_del_full(sd->resize_obj, EVAS_CALLBACK_DEL,
1059 evas_object_event_callback_del_full(sd->resize_obj,
1060 EVAS_CALLBACK_MOUSE_DOWN,
1061 _sub_obj_mouse_down, sd);
1062 evas_object_event_callback_del_full(sd->resize_obj,
1063 EVAS_CALLBACK_MOUSE_MOVE,
1064 _sub_obj_mouse_move, sd);
1065 evas_object_event_callback_del_full(sd->resize_obj,
1066 EVAS_CALLBACK_MOUSE_UP,
1067 _sub_obj_mouse_up, sd);
1068 evas_object_smart_member_del(sd->resize_obj);
1070 if (_elm_widget_is(sd->resize_obj))
1072 if (elm_widget_focus_get(sd->resize_obj)) _unfocus_parents(obj);
1076 sd->resize_obj = sobj;
1079 // orphan new resize obj
1080 evas_object_data_del(sobj, "elm-parent");
1081 if (_elm_widget_is(sobj))
1083 Smart_Data *sd2 = evas_object_smart_data_get(sobj);
1084 if (sd2) sd2->parent_obj = NULL;
1085 evas_object_event_callback_del_full(sobj, EVAS_CALLBACK_HIDE,
1088 evas_object_event_callback_del_full(sobj, EVAS_CALLBACK_DEL,
1090 evas_object_event_callback_del_full(sobj, EVAS_CALLBACK_MOUSE_DOWN,
1091 _sub_obj_mouse_down, sd);
1092 evas_object_event_callback_del_full(sobj, EVAS_CALLBACK_MOUSE_MOVE,
1093 _sub_obj_mouse_move, sd);
1094 evas_object_event_callback_del_full(sobj, EVAS_CALLBACK_MOUSE_UP,
1095 _sub_obj_mouse_up, sd);
1096 evas_object_smart_member_del(sobj);
1097 if (_elm_widget_is(sobj))
1099 if (elm_widget_focus_get(sobj)) _unfocus_parents(obj);
1102 // set the resize obj up
1103 if (_elm_widget_is(sobj))
1105 Smart_Data *sd2 = evas_object_smart_data_get(sobj);
1108 sd2->parent_obj = obj;
1109 sd2->top_win_focused = sd->top_win_focused;
1111 evas_object_event_callback_add(sobj, EVAS_CALLBACK_HIDE,
1114 evas_object_smart_member_add(sobj, obj);
1115 evas_object_event_callback_add(sobj, EVAS_CALLBACK_DEL,
1117 evas_object_event_callback_add(sobj, EVAS_CALLBACK_MOUSE_DOWN,
1118 _sub_obj_mouse_down, sd);
1119 evas_object_event_callback_add(sobj, EVAS_CALLBACK_MOUSE_MOVE,
1120 _sub_obj_mouse_move, sd);
1121 evas_object_event_callback_add(sobj, EVAS_CALLBACK_MOUSE_UP,
1122 _sub_obj_mouse_up, sd);
1123 _smart_reconfigure(sd);
1124 evas_object_data_set(sobj, "elm-parent", obj);
1125 evas_object_smart_callback_call(obj, "sub-object-add", sobj);
1126 if (_elm_widget_is(sobj))
1128 if (elm_widget_focus_get(sobj)) _focus_parents(obj);
1133 elm_widget_hover_object_set(Evas_Object *obj,
1139 evas_object_event_callback_del_full(sd->hover_obj, EVAS_CALLBACK_DEL,
1142 sd->hover_obj = sobj;
1145 evas_object_event_callback_add(sobj, EVAS_CALLBACK_DEL,
1147 _smart_reconfigure(sd);
1152 elm_widget_can_focus_set(Evas_Object *obj,
1153 Eina_Bool can_focus)
1157 can_focus = !!can_focus;
1159 if (sd->can_focus == can_focus) return;
1160 sd->can_focus = can_focus;
1163 evas_object_event_callback_add(obj, EVAS_CALLBACK_KEY_DOWN,
1165 (void *)(long)EVAS_CALLBACK_KEY_DOWN);
1166 evas_object_event_callback_add(obj, EVAS_CALLBACK_KEY_UP,
1168 (void *)(long)EVAS_CALLBACK_KEY_UP);
1169 evas_object_event_callback_add(obj, EVAS_CALLBACK_MOUSE_WHEEL,
1171 (void *)(long)EVAS_CALLBACK_MOUSE_WHEEL);
1175 evas_object_event_callback_del(obj, EVAS_CALLBACK_KEY_DOWN,
1177 evas_object_event_callback_del(obj, EVAS_CALLBACK_KEY_UP,
1179 evas_object_event_callback_del(obj, EVAS_CALLBACK_MOUSE_WHEEL,
1185 elm_widget_can_focus_get(const Evas_Object *obj)
1187 API_ENTRY return EINA_FALSE;
1188 return sd->can_focus;
1192 elm_widget_child_can_focus_get(const Evas_Object *obj)
1194 API_ENTRY return EINA_FALSE;
1195 return sd->child_can_focus;
1201 * This API makes the widget object and its children to be unfocusable.
1203 * This API can be helpful for an object to be deleted.
1204 * When an object will be deleted soon, it and its children may not
1205 * want to get focus (by focus reverting or by other focus controls).
1206 * Then, just use this API before deleting.
1208 * @param obj The widget root of sub-tree
1209 * @param tree_unfocusable If true, set the object sub-tree as unfocusable
1214 elm_widget_tree_unfocusable_set(Evas_Object *obj,
1215 Eina_Bool tree_unfocusable)
1219 tree_unfocusable = !!tree_unfocusable;
1220 if (sd->tree_unfocusable == tree_unfocusable) return;
1221 sd->tree_unfocusable = tree_unfocusable;
1222 elm_widget_focus_tree_unfocusable_handle(obj);
1228 * This returns true, if the object sub-tree is unfocusable.
1230 * @param obj The widget root of sub-tree
1231 * @return EINA_TRUE if the object sub-tree is unfocusable
1236 elm_widget_tree_unfocusable_get(const Evas_Object *obj)
1238 API_ENTRY return EINA_FALSE;
1239 return sd->tree_unfocusable;
1245 * Get the list of focusable child objects.
1247 * This function retruns list of child objects which can get focus.
1249 * @param obj The parent widget
1250 * @retrun list of focusable child objects.
1255 elm_widget_can_focus_child_list_get(const Evas_Object *obj)
1257 API_ENTRY return NULL;
1260 Eina_List *child_list = NULL;
1265 EINA_LIST_FOREACH(sd->subobjs, l, child)
1267 if ((elm_widget_can_focus_get(child)) &&
1268 (evas_object_visible_get(child)) &&
1269 (!elm_widget_disabled_get(child)))
1270 child_list = eina_list_append(child_list, child);
1271 else if (elm_widget_is(child))
1273 Eina_List *can_focus_list;
1274 can_focus_list = elm_widget_can_focus_child_list_get(child);
1276 child_list = eina_list_merge(child_list, can_focus_list);
1284 elm_widget_highlight_ignore_set(Evas_Object *obj,
1288 sd->highlight_ignore = !!ignore;
1292 elm_widget_highlight_ignore_get(const Evas_Object *obj)
1294 API_ENTRY return EINA_FALSE;
1295 return sd->highlight_ignore;
1299 elm_widget_highlight_in_theme_set(Evas_Object *obj,
1300 Eina_Bool highlight)
1303 sd->highlight_in_theme = !!highlight;
1304 /* FIXME: if focused, it should switch from one mode to the other */
1308 elm_widget_highlight_in_theme_get(const Evas_Object *obj)
1310 API_ENTRY return EINA_FALSE;
1311 return sd->highlight_in_theme;
1315 elm_widget_focus_get(const Evas_Object *obj)
1317 API_ENTRY return EINA_FALSE;
1322 elm_widget_focused_object_get(const Evas_Object *obj)
1324 const Evas_Object *subobj;
1326 API_ENTRY return NULL;
1328 if (!sd->focused) return NULL;
1329 EINA_LIST_FOREACH(sd->subobjs, l, subobj)
1331 Evas_Object *fobj = elm_widget_focused_object_get(subobj);
1332 if (fobj) return fobj;
1334 return (Evas_Object *)obj;
1338 elm_widget_top_get(const Evas_Object *obj)
1340 API_ENTRY return NULL;
1341 if (sd->parent_obj) return elm_widget_top_get(sd->parent_obj);
1342 return (Evas_Object *)obj;
1346 elm_widget_is(const Evas_Object *obj)
1348 return _elm_widget_is(obj);
1352 elm_widget_parent_widget_get(const Evas_Object *obj)
1354 Evas_Object *parent;
1356 if (_elm_widget_is(obj))
1358 Smart_Data *sd = evas_object_smart_data_get(obj);
1359 if (!sd) return NULL;
1360 parent = sd->parent_obj;
1364 parent = evas_object_data_get(obj, "elm-parent");
1365 if (!parent) parent = evas_object_smart_parent_get(obj);
1370 Evas_Object *elm_parent;
1371 if (_elm_widget_is(parent)) break;
1372 elm_parent = evas_object_data_get(parent, "elm-parent");
1373 if (elm_parent) parent = elm_parent;
1374 else parent = evas_object_smart_parent_get(parent);
1380 elm_widget_parent2_get(const Evas_Object *obj)
1382 if (_elm_widget_is(obj))
1384 Smart_Data *sd = evas_object_smart_data_get(obj);
1385 if (sd) return sd->parent2;
1391 elm_widget_parent2_set(Evas_Object *obj, Evas_Object *parent)
1394 sd->parent2 = parent;
1398 elm_widget_event_callback_add(Evas_Object *obj,
1403 EINA_SAFETY_ON_NULL_RETURN(func);
1404 Elm_Event_Cb_Data *ecb = ELM_NEW(Elm_Event_Cb_Data);
1407 sd->event_cb = eina_list_append(sd->event_cb, ecb);
1411 elm_widget_event_callback_del(Evas_Object *obj,
1415 API_ENTRY return NULL;
1416 EINA_SAFETY_ON_NULL_RETURN_VAL(func, NULL);
1418 Elm_Event_Cb_Data *ecd;
1419 EINA_LIST_FOREACH(sd->event_cb, l, ecd)
1420 if ((ecd->func == func) && (ecd->data == data))
1423 sd->event_cb = eina_list_remove_list(sd->event_cb, l);
1424 return (void *)data;
1430 elm_widget_event_propagate(Evas_Object *obj,
1431 Evas_Callback_Type type,
1433 Evas_Event_Flags *event_flags)
1435 API_ENTRY return EINA_FALSE; //TODO reduce.
1436 if (!_elm_widget_is(obj)) return EINA_FALSE;
1437 Evas_Object *parent = obj;
1438 Elm_Event_Cb_Data *ecd;
1439 Eina_List *l, *l_prev;
1442 (!(event_flags && ((*event_flags) & EVAS_EVENT_FLAG_ON_HOLD))))
1444 sd = evas_object_smart_data_get(parent);
1445 if ((!sd) || (!_elm_widget_is(obj)))
1446 return EINA_FALSE; //Not Elm Widget
1448 if (sd->event_func && (sd->event_func(parent, obj, type, event_info)))
1451 EINA_LIST_FOREACH_SAFE(sd->event_cb, l, l_prev, ecd)
1453 if (ecd->func((void *)ecd->data, parent, obj, type, event_info) ||
1454 (event_flags && ((*event_flags) & EVAS_EVENT_FLAG_ON_HOLD)))
1457 parent = sd->parent_obj;
1466 * Set custom focus chain.
1468 * This function i set one new and overwrite any previous custom focus chain
1469 * with the list of objects. The previous list will be deleted and this list
1470 * will be managed. After setted, don't modity it.
1472 * @note On focus cycle, only will be evaluated children of this container.
1474 * @param obj The container widget
1475 * @param objs Chain of objects to pass focus
1479 elm_widget_focus_custom_chain_set(Evas_Object *obj,
1483 if (!sd->focus_next_func)
1486 elm_widget_focus_custom_chain_unset(obj);
1491 EINA_LIST_FOREACH(objs, l, o)
1493 evas_object_event_callback_add(o, EVAS_CALLBACK_DEL,
1494 _elm_object_focus_chain_del_cb, sd);
1497 sd->focus_chain = objs;
1503 * Get custom focus chain
1505 * @param obj The container widget
1508 EAPI const Eina_List *
1509 elm_widget_focus_custom_chain_get(const Evas_Object *obj)
1511 API_ENTRY return NULL;
1512 return (const Eina_List *)sd->focus_chain;
1518 * Unset custom focus chain
1520 * @param obj The container widget
1524 elm_widget_focus_custom_chain_unset(Evas_Object *obj)
1527 Eina_List *l, *l_next;
1530 EINA_LIST_FOREACH_SAFE(sd->focus_chain, l, l_next, o)
1532 evas_object_event_callback_del_full(o, EVAS_CALLBACK_DEL,
1533 _elm_object_focus_chain_del_cb, sd);
1534 sd->focus_chain = eina_list_remove_list(sd->focus_chain, l);
1541 * Append object to custom focus chain.
1543 * @note If relative_child equal to NULL or not in custom chain, the object
1544 * will be added in end.
1546 * @note On focus cycle, only will be evaluated children of this container.
1548 * @param obj The container widget
1549 * @param child The child to be added in custom chain
1550 * @param relative_child The relative object to position the child
1554 elm_widget_focus_custom_chain_append(Evas_Object *obj,
1556 Evas_Object *relative_child)
1559 EINA_SAFETY_ON_NULL_RETURN(child);
1560 if (!sd->focus_next_func) return;
1562 evas_object_event_callback_del_full(child, EVAS_CALLBACK_DEL,
1563 _elm_object_focus_chain_del_cb, sd);
1565 if (!relative_child)
1566 sd->focus_chain = eina_list_append(sd->focus_chain, child);
1568 sd->focus_chain = eina_list_append_relative(sd->focus_chain,
1569 child, relative_child);
1575 * Prepend object to custom focus chain.
1577 * @note If relative_child equal to NULL or not in custom chain, the object
1578 * will be added in begin.
1580 * @note On focus cycle, only will be evaluated children of this container.
1582 * @param obj The container widget
1583 * @param child The child to be added in custom chain
1584 * @param relative_child The relative object to position the child
1588 elm_widget_focus_custom_chain_prepend(Evas_Object *obj,
1590 Evas_Object *relative_child)
1593 EINA_SAFETY_ON_NULL_RETURN(child);
1595 if (!sd->focus_next_func) return;
1597 evas_object_event_callback_del_full(child, EVAS_CALLBACK_DEL,
1598 _elm_object_focus_chain_del_cb, sd);
1600 if (!relative_child)
1601 sd->focus_chain = eina_list_prepend(sd->focus_chain, child);
1603 sd->focus_chain = eina_list_prepend_relative(sd->focus_chain,
1604 child, relative_child);
1610 * Give focus to next object in object tree.
1612 * Give focus to next object in focus chain of one object sub-tree.
1613 * If the last object of chain already have focus, the focus will go to the
1614 * first object of chain.
1616 * @param obj The widget root of sub-tree
1617 * @param dir Direction to cycle the focus
1622 elm_widget_focus_cycle(Evas_Object *obj,
1623 Elm_Focus_Direction dir)
1625 Evas_Object *target = NULL;
1626 if (!_elm_widget_is(obj))
1628 elm_widget_focus_next_get(obj, dir, &target);
1630 elm_widget_focus_steal(target);
1636 * Give focus to near object in one direction.
1638 * Give focus to near object in direction of one object.
1639 * If none focusable object in given direction, the focus will not change.
1641 * @param obj The reference widget
1642 * @param x Horizontal component of direction to focus
1643 * @param y Vertical component of direction to focus
1647 //FIXME: If x, y indicates the elements of the directional vector,
1648 //It would be better if these values are the normalized value(float x, float y)
1650 EINA_DEPRECATED EAPI void
1651 elm_widget_focus_direction_go(Evas_Object *obj __UNUSED__,
1661 * Get next object in focus chain of object tree.
1663 * Get next object in focus chain of one object sub-tree.
1664 * Return the next object by reference. If don't have any candidate to receive
1665 * focus before chain end, the first candidate will be returned.
1667 * @param obj The widget root of sub-tree
1668 * @param dir Direction os focus chain
1669 * @param next The next object in focus chain
1670 * @return EINA_TRUE if don't need focus chain restart/loop back
1671 * to use 'next' obj.
1676 elm_widget_focus_next_get(const Evas_Object *obj,
1677 Elm_Focus_Direction dir,
1684 API_ENTRY return EINA_FALSE;
1686 /* Ignore if disabled */
1687 if ((!evas_object_visible_get(obj))
1688 || (elm_widget_disabled_get(obj))
1689 || (elm_widget_tree_unfocusable_get(obj)))
1693 if (sd->focus_next_func)
1694 return sd->focus_next_func(obj, dir, next);
1696 if (!elm_widget_can_focus_get(obj))
1700 *next = (Evas_Object *)obj;
1701 return !elm_widget_focus_get(obj);
1707 * Get next object in focus chain of object tree in list.
1709 * Get next object in focus chain of one object sub-tree ordered by one list.
1710 * Return the next object by reference. If don't have any candidate to receive
1711 * focus before list end, the first candidate will be returned.
1713 * @param obj The widget root of sub-tree
1714 * @param dir Direction os focus chain
1715 * @param items list with ordered objects
1716 * @param list_data_get function to get the object from one item of list
1717 * @param next The next object in focus chain
1718 * @return EINA_TRUE if don't need focus chain restart/loop back
1719 * to use 'next' obj.
1724 elm_widget_focus_list_next_get(const Evas_Object *obj,
1725 const Eina_List *items,
1726 void *(*list_data_get)(const Eina_List * list),
1727 Elm_Focus_Direction dir,
1730 Eina_List *(*list_next)(const Eina_List * list) = NULL;
1736 if (!_elm_widget_is(obj))
1743 if (dir == ELM_FOCUS_PREVIOUS)
1745 items = eina_list_last(items);
1746 list_next = eina_list_prev;
1748 else if (dir == ELM_FOCUS_NEXT)
1749 list_next = eina_list_next;
1753 const Eina_List *l = items;
1755 /* Recovery last focused sub item */
1756 if (elm_widget_focus_get(obj))
1757 for (; l; l = list_next(l))
1759 Evas_Object *cur = list_data_get(l);
1760 if (elm_widget_focus_get(cur)) break;
1763 const Eina_List *start = l;
1764 Evas_Object *to_focus = NULL;
1766 /* Interate sub items */
1767 /* Go to end of list */
1768 for (; l; l = list_next(l))
1770 Evas_Object *tmp = NULL;
1771 Evas_Object *cur = list_data_get(l);
1773 if (elm_widget_parent_get(cur) != obj)
1776 /* Try Focus cycle in subitem */
1777 if (elm_widget_focus_next_get(cur, dir, &tmp))
1782 else if ((tmp) && (!to_focus))
1788 /* Get First possible */
1789 for (; l != start; l = list_next(l))
1791 Evas_Object *tmp = NULL;
1792 Evas_Object *cur = list_data_get(l);
1794 if (elm_widget_parent_get(cur) != obj)
1797 /* Try Focus cycle in subitem */
1798 elm_widget_focus_next_get(cur, dir, &tmp);
1811 elm_widget_signal_emit(Evas_Object *obj,
1812 const char *emission,
1816 if (!sd->signal_func) return;
1817 sd->signal_func(obj, emission, source);
1821 _edje_signal_callback(void *data,
1822 Evas_Object *obj __UNUSED__,
1823 const char *emission,
1826 Edje_Signal_Data *esd = data;
1827 esd->func(esd->data, esd->obj, emission, source);
1831 elm_widget_signal_callback_add(Evas_Object *obj,
1832 const char *emission,
1834 Edje_Signal_Cb func,
1837 Edje_Signal_Data *esd;
1839 if (!sd->callback_add_func) return;
1840 EINA_SAFETY_ON_NULL_RETURN(func);
1842 esd = ELM_NEW(Edje_Signal_Data);
1847 esd->emission = eina_stringshare_add(emission);
1848 esd->source = eina_stringshare_add(source);
1850 sd->edje_signals = eina_list_append(sd->edje_signals, esd);
1851 sd->callback_add_func(obj, emission, source, _edje_signal_callback, esd);
1855 elm_widget_signal_callback_del(Evas_Object *obj,
1856 const char *emission,
1858 Edje_Signal_Cb func)
1860 Edje_Signal_Data *esd;
1863 API_ENTRY return NULL;
1864 if (!sd->callback_del_func) return NULL;
1866 EINA_LIST_FOREACH(sd->edje_signals, l, esd)
1868 if ((esd->func == func) && (!strcmp(esd->emission, emission)) &&
1869 (!strcmp(esd->source, source)))
1871 sd->edje_signals = eina_list_remove_list(sd->edje_signals, l);
1872 eina_stringshare_del(esd->emission);
1873 eina_stringshare_del(esd->source);
1877 sd->callback_del_func
1878 (obj, emission, source, _edje_signal_callback, esd);
1887 elm_widget_focus_set(Evas_Object *obj,
1894 sd->focus_order = focus_order;
1895 sd->focused = EINA_TRUE;
1896 if (sd->on_focus_func) sd->on_focus_func(sd->on_focus_data, obj);
1900 sd->focus_func(obj);
1907 if ((_is_focusable(sd->resize_obj)) &&
1908 (!elm_widget_disabled_get(sd->resize_obj)))
1910 elm_widget_focus_set(sd->resize_obj, first);
1916 EINA_LIST_FOREACH(sd->subobjs, l, child)
1918 if ((_is_focusable(child)) &&
1919 (!elm_widget_disabled_get(child)))
1921 elm_widget_focus_set(child, first);
1931 EINA_LIST_REVERSE_FOREACH(sd->subobjs, l, child)
1933 if ((_is_focusable(child)) &&
1934 (!elm_widget_disabled_get(child)))
1936 elm_widget_focus_set(child, first);
1942 if ((_is_focusable(sd->resize_obj)) &&
1943 (!elm_widget_disabled_get(sd->resize_obj)))
1945 elm_widget_focus_set(sd->resize_obj, first);
1953 elm_widget_parent_get(const Evas_Object *obj)
1955 API_ENTRY return NULL;
1956 return sd->parent_obj;
1960 elm_widget_focused_object_clear(Evas_Object *obj)
1963 if (!sd->focused) return;
1964 if (sd->resize_obj && elm_widget_focus_get(sd->resize_obj))
1965 elm_widget_focused_object_clear(sd->resize_obj);
1970 EINA_LIST_FOREACH(sd->subobjs, l, child)
1972 if (elm_widget_focus_get(child))
1974 elm_widget_focused_object_clear(child);
1979 sd->focused = EINA_FALSE;
1980 if (sd->on_focus_func) sd->on_focus_func(sd->on_focus_data, obj);
1981 if (sd->focus_func) sd->focus_func(obj);
1985 elm_widget_focus_steal(Evas_Object *obj)
1987 Evas_Object *parent, *parent2, *o;
1990 if (sd->focused) return;
1991 if (sd->disabled) return;
1992 if (!sd->can_focus) return;
1993 if (sd->tree_unfocusable) return;
1997 o = elm_widget_parent_get(parent);
1999 sd = evas_object_smart_data_get(o);
2000 if (sd->disabled || sd->tree_unfocusable) return;
2001 if (sd->focused) break;
2004 if ((!elm_widget_parent_get(parent)) &&
2005 (!elm_widget_parent2_get(parent)))
2006 elm_widget_focused_object_clear(parent);
2009 parent2 = elm_widget_parent_get(parent);
2010 if (!parent2) parent2 = elm_widget_parent2_get(parent);
2012 sd = evas_object_smart_data_get(parent);
2015 if ((sd->resize_obj) && (elm_widget_focus_get(sd->resize_obj)))
2016 elm_widget_focused_object_clear(sd->resize_obj);
2021 EINA_LIST_FOREACH(sd->subobjs, l, child)
2023 if (elm_widget_focus_get(child))
2025 elm_widget_focused_object_clear(child);
2037 elm_widget_focus_restore(Evas_Object *obj)
2039 Evas_Object *newest = NULL;
2040 unsigned int newest_focus_order = 0;
2043 newest = _newest_focus_order_get(obj, &newest_focus_order, EINA_TRUE);
2046 elm_object_focus_set(newest, EINA_FALSE);
2047 elm_object_focus_set(newest, EINA_TRUE);
2052 _elm_widget_top_win_focused_set(Evas_Object *obj, Eina_Bool top_win_focused)
2058 if (sd->top_win_focused == top_win_focused) return;
2060 _elm_widget_top_win_focused_set(sd->resize_obj, top_win_focused);
2061 EINA_LIST_FOREACH(sd->subobjs, l, child)
2063 _elm_widget_top_win_focused_set(child, top_win_focused);
2065 sd->top_win_focused = top_win_focused;
2069 _elm_widget_top_win_focused_get(const Evas_Object *obj)
2071 API_ENTRY return EINA_FALSE;
2072 return sd->top_win_focused;
2076 elm_widget_activate(Evas_Object *obj)
2079 elm_widget_change(obj);
2080 if (sd->activate_func) sd->activate_func(obj);
2084 elm_widget_change(Evas_Object *obj)
2087 elm_widget_change(elm_widget_parent_get(obj));
2088 if (sd->on_change_func) sd->on_change_func(sd->on_change_data, obj);
2092 elm_widget_disabled_set(Evas_Object *obj,
2097 if (sd->disabled == disabled) return;
2098 sd->disabled = !!disabled;
2099 elm_widget_focus_disabled_handle(obj);
2100 if (sd->disable_func) sd->disable_func(obj);
2104 elm_widget_disabled_get(const Evas_Object *obj)
2107 return sd->disabled;
2111 elm_widget_show_region_set(Evas_Object *obj,
2116 Eina_Bool forceshow)
2118 Evas_Object *parent_obj, *child_obj;
2119 Evas_Coord px, py, cx, cy;
2123 evas_smart_objects_calculate(evas_object_evas_get(obj));
2125 if (!forceshow && (x == sd->rx) && (y == sd->ry) &&
2126 (w == sd->rw) && (h == sd->rh)) return;
2131 if (sd->on_show_region_func)
2132 sd->on_show_region_func(sd->on_show_region_data, obj);
2136 parent_obj = sd->parent_obj;
2137 child_obj = sd->obj;
2138 if ((!parent_obj) || (!_elm_widget_is(parent_obj))) break;
2139 sd = evas_object_smart_data_get(parent_obj);
2142 evas_object_geometry_get(parent_obj, &px, &py, NULL, NULL);
2143 evas_object_geometry_get(child_obj, &cx, &cy, NULL, NULL);
2152 if (sd->on_show_region_func)
2154 sd->on_show_region_func(sd->on_show_region_data, parent_obj);
2161 elm_widget_show_region_get(const Evas_Object *obj,
2177 * Get the focus region of the given widget.
2179 * The focus region is the area of a widget that should brought into the
2180 * visible area when the widget is focused. Mostly used to show the part of
2181 * an entry where the cursor is, for example. The area returned is relative
2182 * to the object @p obj.
2183 * If the @p obj doesn't have the proper on_focus_region_hook set, this
2184 * function will return the full size of the object.
2186 * @param obj The widget object
2187 * @param x Where to store the x coordinate of the area
2188 * @param y Where to store the y coordinate of the area
2189 * @param w Where to store the width of the area
2190 * @param h Where to store the height of the area
2195 elm_widget_focus_region_get(const Evas_Object *obj,
2205 sd = evas_object_smart_data_get(obj);
2206 if (!sd || !_elm_widget_is(obj) || !sd->on_focus_region_func)
2208 evas_object_geometry_get(obj, NULL, NULL, w, h);
2213 sd->on_focus_region_func(obj, x, y, w, h);
2217 elm_widget_scroll_hold_push(Evas_Object *obj)
2221 if (sd->scroll_hold == 1)
2222 evas_object_smart_callback_call(obj, "scroll-hold-on", obj);
2223 if (sd->parent_obj) elm_widget_scroll_hold_push(sd->parent_obj);
2224 // FIXME: on delete/reparent hold pop
2228 elm_widget_scroll_hold_pop(Evas_Object *obj)
2232 if (!sd->scroll_hold)
2233 evas_object_smart_callback_call(obj, "scroll-hold-off", obj);
2234 if (sd->parent_obj) elm_widget_scroll_hold_pop(sd->parent_obj);
2235 if (sd->scroll_hold < 0) sd->scroll_hold = 0;
2239 elm_widget_scroll_hold_get(const Evas_Object *obj)
2242 return sd->scroll_hold;
2246 elm_widget_scroll_freeze_push(Evas_Object *obj)
2249 sd->scroll_freeze++;
2250 if (sd->scroll_freeze == 1)
2251 evas_object_smart_callback_call(obj, "scroll-freeze-on", obj);
2252 if (sd->parent_obj) elm_widget_scroll_freeze_push(sd->parent_obj);
2253 // FIXME: on delete/reparent freeze pop
2257 elm_widget_scroll_freeze_pop(Evas_Object *obj)
2260 sd->scroll_freeze--;
2261 if (!sd->scroll_freeze)
2262 evas_object_smart_callback_call(obj, "scroll-freeze-off", obj);
2263 if (sd->parent_obj) elm_widget_scroll_freeze_pop(sd->parent_obj);
2264 if (sd->scroll_freeze < 0) sd->scroll_freeze = 0;
2268 elm_widget_scroll_freeze_get(const Evas_Object *obj)
2271 return sd->scroll_freeze;
2275 elm_widget_scale_set(Evas_Object *obj,
2279 if (scale <= 0.0) scale = 0.0;
2280 if (sd->scale != scale)
2283 elm_widget_theme(obj);
2288 elm_widget_scale_get(const Evas_Object *obj)
2290 API_ENTRY return 1.0;
2291 // FIXME: save walking up the tree by storing/caching parent scale
2292 if (sd->scale == 0.0)
2295 return elm_widget_scale_get(sd->parent_obj);
2303 elm_widget_theme_set(Evas_Object *obj,
2307 if (sd->theme != th)
2309 if (sd->theme) elm_theme_free(sd->theme);
2312 elm_widget_theme(obj);
2317 elm_widget_text_part_set(Evas_Object *obj, const char *part, const char *label)
2321 if (!sd->text_set_func)
2324 sd->text_set_func(obj, part, label);
2328 elm_widget_text_part_get(const Evas_Object *obj, const char *part)
2330 API_ENTRY return NULL;
2332 if (!sd->text_get_func)
2335 return sd->text_get_func(obj, part);
2339 elm_widget_domain_translatable_text_part_set(Evas_Object *obj, const char *part, const char *domain, const char *label)
2343 Elm_Translate_String_Data *ts = NULL;
2346 str = eina_stringshare_add(part);
2347 EINA_LIST_FOREACH(sd->translate_strings, l, ts)
2354 eina_stringshare_del(str);
2357 ts = malloc(sizeof(Elm_Translate_String_Data));
2361 ts->domain = eina_stringshare_add(domain);
2362 ts->string = eina_stringshare_add(label);
2363 sd->translate_strings = eina_list_append(sd->translate_strings, ts);
2369 eina_stringshare_replace(&ts->domain, domain);
2370 eina_stringshare_replace(&ts->string, label);
2374 sd->translate_strings = eina_list_remove_list(
2375 sd->translate_strings, l);
2376 eina_stringshare_del(ts->id);
2377 eina_stringshare_del(ts->domain);
2378 eina_stringshare_del(ts->string);
2381 eina_stringshare_del(str);
2385 if (label && label[0])
2386 label = dgettext(domain, label);
2388 elm_widget_text_part_set(obj, part, label);
2392 elm_widget_translatable_text_part_get(const Evas_Object *obj, const char *part)
2394 const char *str, *ret = NULL;
2396 Elm_Translate_String_Data *ts;
2397 API_ENTRY return NULL;
2399 str = eina_stringshare_add(part);
2400 EINA_LIST_FOREACH(sd->translate_strings, l, ts)
2406 eina_stringshare_del(str);
2411 elm_widget_translate(Evas_Object *obj)
2416 Elm_Translate_String_Data *ts;
2420 EINA_LIST_FOREACH(sd->subobjs, l, child) elm_widget_translate(child);
2421 if (sd->resize_obj) elm_widget_translate(sd->resize_obj);
2422 if (sd->hover_obj) elm_widget_translate(sd->hover_obj);
2423 if (sd->translate_func) sd->translate_func(obj);
2426 EINA_LIST_FOREACH(sd->translate_strings, l, ts)
2428 const char *s = dgettext(ts->domain, ts->string);
2429 elm_widget_text_part_set(obj, ts->id, s);
2435 elm_widget_content_part_set(Evas_Object *obj, const char *part, Evas_Object *content)
2439 if (!sd->content_set_func) return;
2440 sd->content_set_func(obj, part, content);
2444 elm_widget_content_part_get(const Evas_Object *obj, const char *part)
2446 API_ENTRY return NULL;
2448 if (!sd->content_get_func) return NULL;
2449 return sd->content_get_func(obj, part);
2453 elm_widget_content_part_unset(Evas_Object *obj, const char *part)
2455 API_ENTRY return NULL;
2457 if (!sd->content_unset_func) return NULL;
2458 return sd->content_unset_func(obj, part);
2462 elm_widget_access_info_set(Evas_Object *obj, const char *txt)
2465 if (sd->access_info) eina_stringshare_del(sd->access_info);
2466 if (!txt) sd->access_info = NULL;
2467 else sd->access_info = eina_stringshare_add(txt);
2471 elm_widget_access_info_get(const Evas_Object *obj)
2473 API_ENTRY return NULL;
2474 return sd->access_info;
2478 elm_widget_theme_get(const Evas_Object *obj)
2480 API_ENTRY return NULL;
2484 return elm_widget_theme_get(sd->parent_obj);
2492 elm_widget_style_set(Evas_Object *obj,
2495 API_ENTRY return EINA_FALSE;
2497 if (eina_stringshare_replace(&sd->style, style))
2498 return elm_widget_theme(obj);
2504 elm_widget_style_get(const Evas_Object *obj)
2506 API_ENTRY return NULL;
2507 if (sd->style) return sd->style;
2512 elm_widget_type_set(Evas_Object *obj,
2516 eina_stringshare_replace(&sd->type, type);
2520 elm_widget_type_get(const Evas_Object *obj)
2522 API_ENTRY return NULL;
2523 if (sd->type) return sd->type;
2528 elm_widget_tooltip_add(Evas_Object *obj,
2532 sd->tooltips = eina_list_append(sd->tooltips, tt);
2536 elm_widget_tooltip_del(Evas_Object *obj,
2540 sd->tooltips = eina_list_remove(sd->tooltips, tt);
2544 elm_widget_cursor_add(Evas_Object *obj,
2548 sd->cursors = eina_list_append(sd->cursors, cur);
2552 elm_widget_cursor_del(Evas_Object *obj,
2556 sd->cursors = eina_list_remove(sd->cursors, cur);
2560 elm_widget_drag_lock_x_set(Evas_Object *obj,
2564 if (sd->drag_x_locked == lock) return;
2565 sd->drag_x_locked = lock;
2566 if (sd->drag_x_locked) _propagate_x_drag_lock(obj, 1);
2567 else _propagate_x_drag_lock(obj, -1);
2571 elm_widget_drag_lock_y_set(Evas_Object *obj,
2575 if (sd->drag_y_locked == lock) return;
2576 sd->drag_y_locked = lock;
2577 if (sd->drag_y_locked) _propagate_y_drag_lock(obj, 1);
2578 else _propagate_y_drag_lock(obj, -1);
2582 elm_widget_drag_lock_x_get(const Evas_Object *obj)
2584 API_ENTRY return EINA_FALSE;
2585 return sd->drag_x_locked;
2589 elm_widget_drag_lock_y_get(const Evas_Object *obj)
2591 API_ENTRY return EINA_FALSE;
2592 return sd->drag_y_locked;
2596 elm_widget_drag_child_locked_x_get(const Evas_Object *obj)
2599 return sd->child_drag_x_locked;
2603 elm_widget_drag_child_locked_y_get(const Evas_Object *obj)
2606 return sd->child_drag_y_locked;
2610 elm_widget_theme_object_set(Evas_Object *obj,
2613 const char *welement,
2616 API_ENTRY return EINA_FALSE;
2617 return _elm_theme_object_set(obj, edj, wname, welement, wstyle);
2621 elm_widget_is_check(const Evas_Object *obj)
2623 static int abort_on_warn = -1;
2624 if (elm_widget_is(obj))
2627 ERR("Passing Object: %p.", obj);
2628 if (abort_on_warn == -1)
2630 if (getenv("ELM_ERROR_ABORT")) abort_on_warn = 1;
2631 else abort_on_warn = 0;
2633 if (abort_on_warn == 1) abort();
2638 elm_widget_type_check(const Evas_Object *obj,
2642 const char *provided, *expected = "(unknown)";
2643 static int abort_on_warn = -1;
2644 provided = elm_widget_type_get(obj);
2645 if (EINA_LIKELY(provided == type)) return EINA_TRUE;
2646 if (type) expected = type;
2647 if ((!provided) || (!provided[0]))
2649 provided = evas_object_type_get(obj);
2650 if ((!provided) || (!provided[0]))
2651 provided = "(unknown)";
2653 ERR("Passing Object: %p in function: %s, of type: '%s' when expecting type: '%s'", obj, func, provided, expected);
2654 if (abort_on_warn == -1)
2656 if (getenv("ELM_ERROR_ABORT")) abort_on_warn = 1;
2657 else abort_on_warn = 0;
2659 if (abort_on_warn == 1) abort();
2663 static Evas_Object *
2664 _widget_name_find(const Evas_Object *obj, const char *name, int recurse)
2669 INTERNAL_ENTRY NULL;
2671 if (!_elm_widget_is(obj)) return NULL;
2674 s = evas_object_name_get(sd->resize_obj);
2675 if ((s) && (!strcmp(s, name))) return sd->resize_obj;
2676 if ((recurse != 0) &&
2677 ((child = _widget_name_find(sd->resize_obj, name, recurse - 1))))
2680 EINA_LIST_FOREACH(sd->subobjs, l, child)
2682 s = evas_object_name_get(child);
2683 if ((s) && (!strcmp(s, name))) return child;
2684 if ((recurse != 0) &&
2685 ((child = _widget_name_find(child, name, recurse - 1))))
2690 s = evas_object_name_get(sd->hover_obj);
2691 if ((s) && (!strcmp(s, name))) return sd->hover_obj;
2692 if ((recurse != 0) &&
2693 ((child = _widget_name_find(sd->hover_obj, name, recurse - 1))))
2700 elm_widget_name_find(const Evas_Object *obj, const char *name, int recurse)
2702 API_ENTRY return NULL;
2703 if (!name) return NULL;
2704 return _widget_name_find(obj, name, recurse);
2710 * Split string in words
2712 * @param str Source string
2713 * @return List of const words
2715 * @see elm_widget_stringlist_free()
2719 elm_widget_stringlist_get(const char *str)
2721 Eina_List *list = NULL;
2723 if (!str) return NULL;
2724 for (b = s = str; 1; s++)
2726 if ((*s == ' ') || (!*s))
2728 char *t = malloc(s - b + 1);
2731 strncpy(t, b, s - b);
2733 list = eina_list_append(list, eina_stringshare_add(t));
2744 elm_widget_stringlist_free(Eina_List *list)
2747 EINA_LIST_FREE(list, s) eina_stringshare_del(s);
2751 elm_widget_focus_hide_handle(Evas_Object *obj)
2753 if (!_elm_widget_is(obj))
2755 _if_focused_revert(obj, EINA_TRUE);
2759 elm_widget_focus_mouse_up_handle(Evas_Object *obj)
2761 Evas_Object *o = obj;
2764 if (_elm_widget_is(o)) break;
2765 o = evas_object_smart_parent_get(o);
2769 if (!_is_focusable(o)) return;
2770 elm_widget_focus_steal(o);
2774 elm_widget_focus_tree_unfocusable_handle(Evas_Object *obj)
2778 //FIXME: Need to check whether the object is unfocusable or not.
2780 if (!elm_widget_parent_get(obj))
2781 elm_widget_focused_object_clear(obj);
2783 _if_focused_revert(obj, EINA_TRUE);
2787 elm_widget_focus_disabled_handle(Evas_Object *obj)
2791 elm_widget_focus_tree_unfocusable_handle(obj);
2795 elm_widget_focus_order_get(const Evas_Object *obj)
2798 return sd->focus_order;
2804 * Allocate a new Elm_Widget_Item-derived structure.
2806 * The goal of this structure is to provide common ground for actions
2807 * that a widget item have, such as the owner widget, callback to
2808 * notify deletion, data pointer and maybe more.
2810 * @param widget the owner widget that holds this item, must be an elm_widget!
2811 * @param alloc_size any number greater than sizeof(Elm_Widget_Item) that will
2812 * be used to allocate memory.
2814 * @return allocated memory that is already zeroed out, or NULL on errors.
2816 * @see elm_widget_item_new() convenience macro.
2817 * @see elm_widget_item_del() to release memory.
2820 EAPI Elm_Widget_Item *
2821 _elm_widget_item_new(Evas_Object *widget,
2824 if (!_elm_widget_is(widget))
2827 Elm_Widget_Item *item;
2829 EINA_SAFETY_ON_TRUE_RETURN_VAL(alloc_size < sizeof(Elm_Widget_Item), NULL);
2830 EINA_SAFETY_ON_TRUE_RETURN_VAL(!_elm_widget_is(widget), NULL);
2832 item = calloc(1, alloc_size);
2833 EINA_SAFETY_ON_NULL_RETURN_VAL(item, NULL);
2835 EINA_MAGIC_SET(item, ELM_WIDGET_ITEM_MAGIC);
2836 item->widget = widget;
2841 _elm_widget_item_free(Elm_Widget_Item *item)
2843 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
2845 _elm_access_item_unregister(item);
2848 item->del_func((void *)item->data, item->widget, item);
2851 evas_object_del(item->view);
2855 _elm_access_clear(item->access);
2859 if (item->access_info)
2860 eina_stringshare_del(item->access_info);
2862 EINA_MAGIC_SET(item, EINA_MAGIC_NONE);
2869 * Releases widget item memory, calling back del_cb() if it exists.
2871 * If there is a Elm_Widget_Item::del_cb, then it will be called prior
2872 * to memory release. Note that elm_widget_item_pre_notify_del() calls
2873 * this function and then unset it, thus being useful for 2 step
2874 * cleanup whenever the del_cb may use any of the data that must be
2875 * deleted from item.
2877 * The Elm_Widget_Item::view will be deleted (evas_object_del()) if it
2880 * @param item a valid #Elm_Widget_Item to be deleted.
2881 * @see elm_widget_item_del() convenience macro.
2885 _elm_widget_item_del(Elm_Widget_Item *item)
2887 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
2889 //Widget item delete callback
2890 if (item->del_pre_func)
2892 if (item->del_pre_func((Elm_Object_Item *)item))
2893 _elm_widget_item_free(item);
2896 _elm_widget_item_free(item);
2902 * Set the function to notify to widgets when item is being deleted by user.
2904 * @param item a valid #Elm_Widget_Item to be notified
2905 * @see elm_widget_item_del_pre_hook_set() convenience macro.
2909 _elm_widget_item_del_pre_hook_set(Elm_Widget_Item *item, Elm_Widget_Del_Pre_Cb func)
2911 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
2912 item->del_pre_func = func;
2918 * Notify object will be deleted without actually deleting it.
2920 * This function will callback Elm_Widget_Item::del_cb if it is set
2921 * and then unset it so it is not called twice (ie: from
2922 * elm_widget_item_del()).
2924 * @param item a valid #Elm_Widget_Item to be notified
2925 * @see elm_widget_item_pre_notify_del() convenience macro.
2929 _elm_widget_item_pre_notify_del(Elm_Widget_Item *item)
2931 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
2932 if (!item->del_func) return;
2933 item->del_func((void *)item->data, item->widget, item);
2934 item->del_func = NULL;
2940 * Set the function to notify when item is being deleted.
2942 * This function will complain if there was a callback set already,
2943 * however it will set the new one.
2945 * The callback will be called from elm_widget_item_pre_notify_del()
2946 * or elm_widget_item_del() will be called with:
2947 * - data: the Elm_Widget_Item::data value.
2948 * - obj: the Elm_Widget_Item::widget evas object.
2949 * - event_info: the item being deleted.
2951 * @param item a valid #Elm_Widget_Item to be notified
2952 * @see elm_widget_item_del_cb_set() convenience macro.
2956 _elm_widget_item_del_cb_set(Elm_Widget_Item *item,
2959 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
2961 if ((item->del_func) && (item->del_func != func))
2962 WRN("You're replacing a previously set del_cb %p of item %p with %p",
2963 item->del_func, item, func);
2965 item->del_func = func;
2971 * Set user-data in this item.
2973 * User data may be used to identify this item or just store any
2974 * application data. It is automatically given as the first parameter
2975 * of the deletion notify callback.
2977 * @param item a valid #Elm_Widget_Item to store data in.
2978 * @param data user data to store.
2979 * @see elm_widget_item_del_cb_set() convenience macro.
2983 _elm_widget_item_data_set(Elm_Widget_Item *item,
2986 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
2987 if ((item->data) && (item->data != data))
2988 DBG("Replacing item %p data %p with %p", item, item->data, data);
2995 * Retrieves user-data of this item.
2997 * @param item a valid #Elm_Widget_Item to get data from.
2998 * @see elm_widget_item_data_set()
3002 _elm_widget_item_data_get(const Elm_Widget_Item *item)
3004 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item, NULL);
3005 return (void *)item->data;
3009 _elm_widget_item_disabled_set(Elm_Widget_Item *item, Eina_Bool disabled)
3011 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
3013 if (item->disabled == disabled) return;
3014 item->disabled = !!disabled;
3015 if (item->disable_func) item->disable_func(item);
3019 _elm_widget_item_disabled_get(const Elm_Widget_Item *item)
3021 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item, EINA_FALSE);
3022 return item->disabled;
3026 _elm_widget_item_disable_hook_set(Elm_Widget_Item *item,
3027 Elm_Widget_Disable_Cb func)
3029 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
3030 item->disable_func = func;
3033 typedef struct _Elm_Widget_Item_Tooltip Elm_Widget_Item_Tooltip;
3035 struct _Elm_Widget_Item_Tooltip
3037 Elm_Widget_Item *item;
3038 Elm_Tooltip_Item_Content_Cb func;
3039 Evas_Smart_Cb del_cb;
3043 static Evas_Object *
3044 _elm_widget_item_tooltip_label_create(void *data,
3045 Evas_Object *obj __UNUSED__,
3046 Evas_Object *tooltip,
3047 void *item __UNUSED__)
3049 Evas_Object *label = elm_label_add(tooltip);
3052 elm_object_style_set(label, "tooltip");
3053 elm_object_text_set(label, data);
3057 static Evas_Object *
3058 _elm_widget_item_tooltip_trans_label_create(void *data,
3059 Evas_Object *obj __UNUSED__,
3060 Evas_Object *tooltip,
3061 void *item __UNUSED__)
3063 Evas_Object *label = elm_label_add(tooltip);
3066 elm_object_style_set(label, "tooltip");
3067 elm_object_translatable_text_set(label, data);
3072 _elm_widget_item_tooltip_label_del_cb(void *data,
3073 Evas_Object *obj __UNUSED__,
3074 void *event_info __UNUSED__)
3076 eina_stringshare_del(data);
3082 * Set the text to be shown in the widget item.
3084 * @param item Target item
3085 * @param text The text to set in the content
3087 * Setup the text as tooltip to object. The item can have only one tooltip,
3088 * so any previous tooltip data is removed.
3093 _elm_widget_item_tooltip_text_set(Elm_Widget_Item *item,
3096 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
3097 EINA_SAFETY_ON_NULL_RETURN(text);
3099 text = eina_stringshare_add(text);
3100 _elm_widget_item_tooltip_content_cb_set
3101 (item, _elm_widget_item_tooltip_label_create, text,
3102 _elm_widget_item_tooltip_label_del_cb);
3106 _elm_widget_item_tooltip_translatable_text_set(Elm_Widget_Item *item,
3109 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
3110 EINA_SAFETY_ON_NULL_RETURN(text);
3112 text = eina_stringshare_add(text);
3113 _elm_widget_item_tooltip_content_cb_set
3114 (item, _elm_widget_item_tooltip_trans_label_create, text,
3115 _elm_widget_item_tooltip_label_del_cb);
3118 static Evas_Object *
3119 _elm_widget_item_tooltip_create(void *data,
3121 Evas_Object *tooltip)
3123 Elm_Widget_Item_Tooltip *wit = data;
3124 return wit->func((void *)wit->data, obj, tooltip, wit->item);
3128 _elm_widget_item_tooltip_del_cb(void *data,
3130 void *event_info __UNUSED__)
3132 Elm_Widget_Item_Tooltip *wit = data;
3133 if (wit->del_cb) wit->del_cb((void *)wit->data, obj, wit->item);
3140 * Set the content to be shown in the tooltip item
3142 * Setup the tooltip to item. The item can have only one tooltip,
3143 * so any previous tooltip data is removed. @p func(with @p data) will
3144 * be called every time that need show the tooltip and it should
3145 * return a valid Evas_Object. This object is then managed fully by
3146 * tooltip system and is deleted when the tooltip is gone.
3148 * @param item the widget item being attached a tooltip.
3149 * @param func the function used to create the tooltip contents.
3150 * @param data what to provide to @a func as callback data/context.
3151 * @param del_cb called when data is not needed anymore, either when
3152 * another callback replaces @func, the tooltip is unset with
3153 * elm_widget_item_tooltip_unset() or the owner @a item
3154 * dies. This callback receives as the first parameter the
3155 * given @a data, and @c event_info is the item.
3160 _elm_widget_item_tooltip_content_cb_set(Elm_Widget_Item *item,
3161 Elm_Tooltip_Item_Content_Cb func,
3163 Evas_Smart_Cb del_cb)
3165 Elm_Widget_Item_Tooltip *wit;
3167 ELM_WIDGET_ITEM_CHECK_OR_GOTO(item, error_noitem);
3171 _elm_widget_item_tooltip_unset(item);
3175 wit = ELM_NEW(Elm_Widget_Item_Tooltip);
3176 if (!wit) goto error;
3180 wit->del_cb = del_cb;
3182 elm_object_sub_tooltip_content_cb_set
3183 (item->view, item->widget, _elm_widget_item_tooltip_create, wit,
3184 _elm_widget_item_tooltip_del_cb);
3189 if (del_cb) del_cb((void *)data, NULL, item);
3192 if (del_cb) del_cb((void *)data, item->widget, item);
3198 * Unset tooltip from item
3200 * @param item widget item to remove previously set tooltip.
3202 * Remove tooltip from item. The callback provided as del_cb to
3203 * elm_widget_item_tooltip_content_cb_set() will be called to notify
3204 * it is not used anymore.
3206 * @see elm_widget_item_tooltip_content_cb_set()
3211 _elm_widget_item_tooltip_unset(Elm_Widget_Item *item)
3213 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
3214 elm_object_tooltip_unset(item->view);
3220 * Sets a different style for this item tooltip.
3222 * @note before you set a style you should define a tooltip with
3223 * elm_widget_item_tooltip_content_cb_set() or
3224 * elm_widget_item_tooltip_text_set()
3226 * @param item widget item with tooltip already set.
3227 * @param style the theme style to use (default, transparent, ...)
3232 _elm_widget_item_tooltip_style_set(Elm_Widget_Item *item,
3235 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
3236 elm_object_tooltip_style_set(item->view, style);
3240 _elm_widget_item_tooltip_window_mode_set(Elm_Widget_Item *item, Eina_Bool disable)
3242 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item, EINA_FALSE);
3243 return elm_object_tooltip_window_mode_set(item->view, disable);
3247 _elm_widget_item_tooltip_window_mode_get(const Elm_Widget_Item *item)
3249 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item, EINA_FALSE);
3250 return elm_object_tooltip_window_mode_get(item->view);
3256 * Get the style for this item tooltip.
3258 * @param item widget item with tooltip already set.
3259 * @return style the theme style in use, defaults to "default". If the
3260 * object does not have a tooltip set, then NULL is returned.
3265 _elm_widget_item_tooltip_style_get(const Elm_Widget_Item *item)
3267 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item, NULL);
3268 return elm_object_tooltip_style_get(item->view);
3272 _elm_widget_item_cursor_set(Elm_Widget_Item *item,
3275 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
3276 elm_object_sub_cursor_set(item->view, item->widget, cursor);
3280 _elm_widget_item_cursor_get(const Elm_Widget_Item *item)
3282 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item, NULL);
3283 return elm_object_cursor_get(item->view);
3287 _elm_widget_item_cursor_unset(Elm_Widget_Item *item)
3289 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
3290 elm_object_cursor_unset(item->view);
3296 * Sets a different style for this item cursor.
3298 * @note before you set a style you should define a cursor with
3299 * elm_widget_item_cursor_set()
3301 * @param item widget item with cursor already set.
3302 * @param style the theme style to use (default, transparent, ...)
3307 _elm_widget_item_cursor_style_set(Elm_Widget_Item *item,
3310 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
3311 elm_object_cursor_style_set(item->view, style);
3317 * Get the style for this item cursor.
3319 * @param item widget item with cursor already set.
3320 * @return style the theme style in use, defaults to "default". If the
3321 * object does not have a cursor set, then NULL is returned.
3326 _elm_widget_item_cursor_style_get(const Elm_Widget_Item *item)
3328 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item, NULL);
3329 return elm_object_cursor_style_get(item->view);
3335 * Set if the cursor set should be searched on the theme or should use
3336 * the provided by the engine, only.
3338 * @note before you set if should look on theme you should define a cursor
3339 * with elm_object_cursor_set(). By default it will only look for cursors
3340 * provided by the engine.
3342 * @param item widget item with cursor already set.
3343 * @param engine_only boolean to define it cursors should be looked only
3344 * between the provided by the engine or searched on widget's theme as well.
3349 _elm_widget_item_cursor_engine_only_set(Elm_Widget_Item *item,
3350 Eina_Bool engine_only)
3352 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
3353 elm_object_cursor_theme_search_enabled_set(item->view, engine_only);
3359 * Get the cursor engine only usage for this item cursor.
3361 * @param item widget item with cursor already set.
3362 * @return engine_only boolean to define it cursors should be looked only
3363 * between the provided by the engine or searched on widget's theme as well. If
3364 * the object does not have a cursor set, then EINA_FALSE is returned.
3369 _elm_widget_item_cursor_engine_only_get(const Elm_Widget_Item *item)
3371 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item, EINA_FALSE);
3372 return elm_object_cursor_theme_search_enabled_get(item->view);
3375 // smart object funcs
3377 _smart_reconfigure(Smart_Data *sd)
3381 evas_object_move(sd->resize_obj, sd->x, sd->y);
3382 evas_object_resize(sd->resize_obj, sd->w, sd->h);
3386 evas_object_move(sd->hover_obj, sd->x, sd->y);
3387 evas_object_resize(sd->hover_obj, sd->w, sd->h);
3392 _elm_widget_item_content_part_set(Elm_Widget_Item *item,
3394 Evas_Object *content)
3396 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
3397 if (!item->content_set_func) return;
3398 item->content_set_func((Elm_Object_Item *)item, part, content);
3402 _elm_widget_item_content_part_get(const Elm_Widget_Item *item,
3405 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item, NULL);
3406 if (!item->content_get_func) return NULL;
3407 return item->content_get_func((Elm_Object_Item *)item, part);
3411 _elm_widget_item_content_part_unset(Elm_Widget_Item *item,
3414 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item, NULL);
3415 if (!item->content_unset_func) return NULL;
3416 return item->content_unset_func((Elm_Object_Item *)item, part);
3420 _elm_widget_item_text_part_set(Elm_Widget_Item *item,
3424 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
3425 if (!item->text_set_func) return;
3426 item->text_set_func((Elm_Object_Item *)item, part, label);
3430 _elm_widget_item_signal_emit(Elm_Widget_Item *item,
3431 const char *emission,
3434 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
3435 if (item->signal_emit_func)
3436 item->signal_emit_func((Elm_Object_Item *)item, emission, source);
3440 _elm_widget_item_text_part_get(const Elm_Widget_Item *item,
3443 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item, NULL);
3444 if (!item->text_get_func) return NULL;
3445 return item->text_get_func((Elm_Object_Item *)item, part);
3449 _elm_widget_item_content_set_hook_set(Elm_Widget_Item *item,
3450 Elm_Widget_Content_Set_Cb func)
3452 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
3453 item->content_set_func = func;
3457 _elm_widget_item_content_get_hook_set(Elm_Widget_Item *item,
3458 Elm_Widget_Content_Get_Cb func)
3460 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
3461 item->content_get_func = func;
3465 _elm_widget_item_content_unset_hook_set(Elm_Widget_Item *item,
3466 Elm_Widget_Content_Unset_Cb func)
3468 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
3469 item->content_unset_func = func;
3473 _elm_widget_item_text_set_hook_set(Elm_Widget_Item *item,
3474 Elm_Widget_Text_Set_Cb func)
3476 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
3477 item->text_set_func = func;
3481 _elm_widget_item_text_get_hook_set(Elm_Widget_Item *item,
3482 Elm_Widget_Text_Get_Cb func)
3484 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
3485 item->text_get_func = func;
3489 _elm_widget_item_signal_emit_hook_set(Elm_Widget_Item *item,
3490 Elm_Widget_Signal_Emit_Cb func)
3492 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
3493 item->signal_emit_func = func;
3497 _elm_widget_item_access_info_set(Elm_Widget_Item *item, const char *txt)
3499 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
3500 if (item->access_info) eina_stringshare_del(item->access_info);
3501 if (!txt) item->access_info = NULL;
3502 else item->access_info = eina_stringshare_add(txt);
3506 _smart_add(Evas_Object *obj)
3510 sd = calloc(1, sizeof(Smart_Data));
3513 sd->x = sd->y = sd->w = sd->h = 0;
3514 sd->mirrored_auto_mode = EINA_TRUE; /* will follow system locale settings */
3515 evas_object_smart_data_set(obj, sd);
3516 elm_widget_can_focus_set(obj, EINA_TRUE);
3519 static Evas_Object *
3520 _newest_focus_order_get(Evas_Object *obj,
3521 unsigned int *newest_focus_order,
3522 Eina_Bool can_focus_only)
3525 Evas_Object *child, *ret, *best;
3527 API_ENTRY return NULL;
3529 if (!evas_object_visible_get(obj)
3530 || (elm_widget_disabled_get(obj))
3531 || (elm_widget_tree_unfocusable_get(obj)))
3535 if (*newest_focus_order < sd->focus_order)
3537 *newest_focus_order = sd->focus_order;
3540 EINA_LIST_FOREACH(sd->subobjs, l, child)
3542 ret = _newest_focus_order_get(child, newest_focus_order, can_focus_only);
3548 if ((!best) || (!elm_widget_can_focus_get(best)))
3555 _if_focused_revert(Evas_Object *obj,
3556 Eina_Bool can_focus_only)
3559 Evas_Object *newest = NULL;
3560 unsigned int newest_focus_order = 0;
3564 if (!sd->focused) return;
3565 if (!sd->parent_obj) return;
3567 top = elm_widget_top_get(sd->parent_obj);
3570 newest = _newest_focus_order_get(top, &newest_focus_order, can_focus_only);
3573 elm_object_focus_set(newest, EINA_FALSE);
3574 elm_object_focus_set(newest, EINA_TRUE);
3580 _smart_del(Evas_Object *obj)
3583 Edje_Signal_Data *esd;
3584 Elm_Translate_String_Data *ts;
3588 if (sd->del_pre_func) sd->del_pre_func(obj);
3591 sobj = sd->resize_obj;
3592 sd->resize_obj = NULL;
3593 evas_object_event_callback_del_full(sobj, EVAS_CALLBACK_DEL, _sub_obj_del, sd);
3594 evas_object_smart_callback_call(sd->obj, "sub-object-del", sobj);
3595 evas_object_del(sobj);
3596 sd->resize_obj = NULL;
3600 sobj = sd->hover_obj;
3601 sd->hover_obj = NULL;
3602 evas_object_event_callback_del_full(sobj, EVAS_CALLBACK_DEL, _sub_obj_del, sd);
3603 evas_object_smart_callback_call(sd->obj, "sub-object-del", sobj);
3604 evas_object_del(sobj);
3605 sd->hover_obj = NULL;
3607 EINA_LIST_FREE(sd->subobjs, sobj)
3609 evas_object_event_callback_del_full(sobj, EVAS_CALLBACK_DEL, _sub_obj_del, sd);
3610 evas_object_smart_callback_call(sd->obj, "sub-object-del", sobj);
3611 evas_object_del(sobj);
3613 sd->tooltips = eina_list_free(sd->tooltips); /* should be empty anyway */
3614 sd->cursors = eina_list_free(sd->cursors); /* should be empty anyway */
3615 EINA_LIST_FREE(sd->edje_signals, esd)
3617 eina_stringshare_del(esd->emission);
3618 eina_stringshare_del(esd->source);
3621 EINA_LIST_FREE(sd->translate_strings, ts)
3623 eina_stringshare_del(ts->id);
3624 eina_stringshare_del(ts->domain);
3625 eina_stringshare_del(ts->string);
3628 sd->event_cb = eina_list_free(sd->event_cb); /* should be empty anyway */
3629 if (sd->del_func) sd->del_func(obj);
3630 if (sd->style) eina_stringshare_del(sd->style);
3631 if (sd->type) eina_stringshare_del(sd->type);
3632 if (sd->theme) elm_theme_free(sd->theme);
3634 _if_focused_revert(obj, EINA_TRUE);
3635 if (sd->access_info) eina_stringshare_del(sd->access_info);
3637 evas_object_smart_data_set(obj, NULL);
3641 _smart_move(Evas_Object *obj,
3648 _smart_reconfigure(sd);
3652 _smart_resize(Evas_Object *obj,
3659 _smart_reconfigure(sd);
3663 _smart_show(Evas_Object *obj)
3668 if ((list = evas_object_smart_members_get(obj)))
3670 EINA_LIST_FREE(list, o)
3672 if (evas_object_data_get(o, "_elm_leaveme")) continue;
3673 evas_object_show(o);
3679 _smart_hide(Evas_Object *obj)
3685 list = evas_object_smart_members_get(obj);
3686 EINA_LIST_FREE(list, o)
3688 if (evas_object_data_get(o, "_elm_leaveme")) continue;
3689 evas_object_hide(o);
3694 _smart_color_set(Evas_Object *obj,
3703 if ((list = evas_object_smart_members_get(obj)))
3705 EINA_LIST_FREE(list, o)
3707 if (evas_object_data_get(o, "_elm_leaveme")) continue;
3708 evas_object_color_set(o, r, g, b, a);
3714 _smart_clip_set(Evas_Object *obj,
3720 if ((list = evas_object_smart_members_get(obj)))
3722 EINA_LIST_FREE(list, o)
3724 if (evas_object_data_get(o, "_elm_leaveme")) continue;
3725 evas_object_clip_set(o, clip);
3731 _smart_clip_unset(Evas_Object *obj)
3736 if ((list = evas_object_smart_members_get(obj)))
3738 EINA_LIST_FREE(list, o)
3740 if (evas_object_data_get(o, "_elm_leaveme")) continue;
3741 evas_object_clip_unset(o);
3747 _smart_calculate(Evas_Object *obj)
3750 if (sd->changed_func) sd->changed_func(obj);
3754 _smart_member_add(Evas_Object *obj, Evas_Object *child)
3758 if (evas_object_data_get(child, "_elm_leaveme")) return;
3760 evas_object_color_get(obj, &r, &g, &b, &a);
3761 evas_object_color_set(child, r, g, b, a);
3763 evas_object_clip_set(child, evas_object_clip_get(obj));
3765 if (evas_object_visible_get(obj))
3766 evas_object_show(child);
3768 evas_object_hide(child);
3772 _smart_member_del(Evas_Object *obj __UNUSED__, Evas_Object *child)
3774 if (evas_object_data_get(child, "_elm_leaveme")) return;
3775 evas_object_clip_unset(child);
3778 /* never need to touch this */
3782 if (_e_smart) return;
3784 static const Evas_Smart_Class sc =
3787 EVAS_SMART_CLASS_VERSION,
3805 _e_smart = evas_smart_class_new(&sc);
3809 /* happy debug functions */
3812 _sub_obj_tree_dump(const Evas_Object *obj,
3817 for (i = 0; i < lvl * 3; i++)
3820 if (_elm_widget_is(obj))
3824 printf("+ %s(%p)\n",
3828 _sub_obj_tree_dump(sd->resize_obj, lvl + 1);
3829 EINA_LIST_FOREACH(sd->subobjs, l, obj)
3831 if (obj != sd->resize_obj)
3832 _sub_obj_tree_dump(obj, lvl + 1);
3836 printf("+ %s(%p)\n", evas_object_type_get(obj), obj);
3840 _sub_obj_tree_dot_dump(const Evas_Object *obj,
3843 if (!_elm_widget_is(obj))
3847 Eina_Bool visible = evas_object_visible_get(obj);
3848 Eina_Bool disabled = elm_widget_disabled_get(obj);
3849 Eina_Bool focused = elm_widget_focus_get(obj);
3850 Eina_Bool can_focus = elm_widget_can_focus_get(obj);
3854 fprintf(output, "\"%p\" -- \"%p\" [ color=black", sd->parent_obj, obj);
3857 fprintf(output, ", style=bold");
3860 fprintf(output, ", color=gray28");
3862 fprintf(output, " ];\n");
3865 fprintf(output, "\"%p\" [ label = \"{%p|%s|%s|visible: %d|"
3866 "disabled: %d|focused: %d/%d|focus order:%d}\"", obj, obj, sd->type,
3867 evas_object_name_get(obj), visible, disabled, focused, can_focus,
3871 fprintf(output, ", style=bold");
3874 fprintf(output, ", fontcolor=gray28");
3876 if ((disabled) || (!visible))
3877 fprintf(output, ", color=gray");
3879 fprintf(output, " ];\n");
3883 EINA_LIST_FOREACH(sd->subobjs, l, o)
3884 _sub_obj_tree_dot_dump(o, output);
3889 elm_widget_tree_dump(const Evas_Object *top)
3892 if (!_elm_widget_is(top))
3894 _sub_obj_tree_dump(top, 0);
3902 elm_widget_tree_dot_dump(const Evas_Object *top,
3906 if (!_elm_widget_is(top))
3908 fprintf(output, "graph " " { node [shape=record];\n");
3909 _sub_obj_tree_dot_dump(top, output);
3910 fprintf(output, "}\n");