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);
1039 EAPI const Eina_List *
1040 elm_widget_sub_object_list_get(const Evas_Object *obj)
1042 API_ENTRY return NULL;
1043 return (const Eina_List *)sd->subobjs;
1047 elm_widget_resize_object_set(Evas_Object *obj,
1051 // orphan previous resize obj
1054 evas_object_clip_unset(sd->resize_obj);
1055 evas_object_data_del(sd->resize_obj, "elm-parent");
1056 if (_elm_widget_is(sd->resize_obj))
1058 Smart_Data *sd2 = evas_object_smart_data_get(sd->resize_obj);
1059 if (sd2) sd2->parent_obj = NULL;
1060 evas_object_event_callback_del_full(sd->resize_obj,
1064 evas_object_event_callback_del_full(sd->resize_obj, EVAS_CALLBACK_DEL,
1066 evas_object_event_callback_del_full(sd->resize_obj,
1067 EVAS_CALLBACK_MOUSE_DOWN,
1068 _sub_obj_mouse_down, sd);
1069 evas_object_event_callback_del_full(sd->resize_obj,
1070 EVAS_CALLBACK_MOUSE_MOVE,
1071 _sub_obj_mouse_move, sd);
1072 evas_object_event_callback_del_full(sd->resize_obj,
1073 EVAS_CALLBACK_MOUSE_UP,
1074 _sub_obj_mouse_up, sd);
1075 evas_object_smart_member_del(sd->resize_obj);
1077 if (_elm_widget_is(sd->resize_obj))
1079 if (elm_widget_focus_get(sd->resize_obj)) _unfocus_parents(obj);
1083 sd->resize_obj = sobj;
1086 // orphan new resize obj
1087 evas_object_data_del(sobj, "elm-parent");
1088 if (_elm_widget_is(sobj))
1090 Smart_Data *sd2 = evas_object_smart_data_get(sobj);
1091 if (sd2) sd2->parent_obj = NULL;
1092 evas_object_event_callback_del_full(sobj, EVAS_CALLBACK_HIDE,
1095 evas_object_event_callback_del_full(sobj, EVAS_CALLBACK_DEL,
1097 evas_object_event_callback_del_full(sobj, EVAS_CALLBACK_MOUSE_DOWN,
1098 _sub_obj_mouse_down, sd);
1099 evas_object_event_callback_del_full(sobj, EVAS_CALLBACK_MOUSE_MOVE,
1100 _sub_obj_mouse_move, sd);
1101 evas_object_event_callback_del_full(sobj, EVAS_CALLBACK_MOUSE_UP,
1102 _sub_obj_mouse_up, sd);
1103 evas_object_smart_member_del(sobj);
1104 if (_elm_widget_is(sobj))
1106 if (elm_widget_focus_get(sobj)) _unfocus_parents(obj);
1109 // set the resize obj up
1110 if (_elm_widget_is(sobj))
1112 Smart_Data *sd2 = evas_object_smart_data_get(sobj);
1115 sd2->parent_obj = obj;
1116 sd2->top_win_focused = sd->top_win_focused;
1118 evas_object_event_callback_add(sobj, EVAS_CALLBACK_HIDE,
1121 evas_object_smart_member_add(sobj, obj);
1122 evas_object_event_callback_add(sobj, EVAS_CALLBACK_DEL,
1124 evas_object_event_callback_add(sobj, EVAS_CALLBACK_MOUSE_DOWN,
1125 _sub_obj_mouse_down, sd);
1126 evas_object_event_callback_add(sobj, EVAS_CALLBACK_MOUSE_MOVE,
1127 _sub_obj_mouse_move, sd);
1128 evas_object_event_callback_add(sobj, EVAS_CALLBACK_MOUSE_UP,
1129 _sub_obj_mouse_up, sd);
1130 _smart_reconfigure(sd);
1131 evas_object_data_set(sobj, "elm-parent", obj);
1132 evas_object_smart_callback_call(obj, "sub-object-add", sobj);
1133 if (_elm_widget_is(sobj))
1135 if (elm_widget_focus_get(sobj)) _focus_parents(obj);
1140 elm_widget_hover_object_set(Evas_Object *obj,
1146 evas_object_event_callback_del_full(sd->hover_obj, EVAS_CALLBACK_DEL,
1149 sd->hover_obj = sobj;
1152 evas_object_event_callback_add(sobj, EVAS_CALLBACK_DEL,
1154 _smart_reconfigure(sd);
1159 elm_widget_can_focus_set(Evas_Object *obj,
1160 Eina_Bool can_focus)
1164 can_focus = !!can_focus;
1166 if (sd->can_focus == can_focus) return;
1167 sd->can_focus = can_focus;
1170 evas_object_event_callback_add(obj, EVAS_CALLBACK_KEY_DOWN,
1172 (void *)(long)EVAS_CALLBACK_KEY_DOWN);
1173 evas_object_event_callback_add(obj, EVAS_CALLBACK_KEY_UP,
1175 (void *)(long)EVAS_CALLBACK_KEY_UP);
1176 evas_object_event_callback_add(obj, EVAS_CALLBACK_MOUSE_WHEEL,
1178 (void *)(long)EVAS_CALLBACK_MOUSE_WHEEL);
1182 evas_object_event_callback_del(obj, EVAS_CALLBACK_KEY_DOWN,
1184 evas_object_event_callback_del(obj, EVAS_CALLBACK_KEY_UP,
1186 evas_object_event_callback_del(obj, EVAS_CALLBACK_MOUSE_WHEEL,
1192 elm_widget_can_focus_get(const Evas_Object *obj)
1194 API_ENTRY return EINA_FALSE;
1195 return sd->can_focus;
1199 elm_widget_child_can_focus_get(const Evas_Object *obj)
1201 API_ENTRY return EINA_FALSE;
1202 return sd->child_can_focus;
1208 * This API makes the widget object and its children to be unfocusable.
1210 * This API can be helpful for an object to be deleted.
1211 * When an object will be deleted soon, it and its children may not
1212 * want to get focus (by focus reverting or by other focus controls).
1213 * Then, just use this API before deleting.
1215 * @param obj The widget root of sub-tree
1216 * @param tree_unfocusable If true, set the object sub-tree as unfocusable
1221 elm_widget_tree_unfocusable_set(Evas_Object *obj,
1222 Eina_Bool tree_unfocusable)
1226 tree_unfocusable = !!tree_unfocusable;
1227 if (sd->tree_unfocusable == tree_unfocusable) return;
1228 sd->tree_unfocusable = tree_unfocusable;
1229 elm_widget_focus_tree_unfocusable_handle(obj);
1235 * This returns true, if the object sub-tree is unfocusable.
1237 * @param obj The widget root of sub-tree
1238 * @return EINA_TRUE if the object sub-tree is unfocusable
1243 elm_widget_tree_unfocusable_get(const Evas_Object *obj)
1245 API_ENTRY return EINA_FALSE;
1246 return sd->tree_unfocusable;
1252 * Get the list of focusable child objects.
1254 * This function retruns list of child objects which can get focus.
1256 * @param obj The parent widget
1257 * @retrun list of focusable child objects.
1262 elm_widget_can_focus_child_list_get(const Evas_Object *obj)
1264 API_ENTRY return NULL;
1267 Eina_List *child_list = NULL;
1272 EINA_LIST_FOREACH(sd->subobjs, l, child)
1274 if ((elm_widget_can_focus_get(child)) &&
1275 (evas_object_visible_get(child)) &&
1276 (!elm_widget_disabled_get(child)))
1277 child_list = eina_list_append(child_list, child);
1278 else if (elm_widget_is(child))
1280 Eina_List *can_focus_list;
1281 can_focus_list = elm_widget_can_focus_child_list_get(child);
1283 child_list = eina_list_merge(child_list, can_focus_list);
1291 elm_widget_highlight_ignore_set(Evas_Object *obj,
1295 sd->highlight_ignore = !!ignore;
1299 elm_widget_highlight_ignore_get(const Evas_Object *obj)
1301 API_ENTRY return EINA_FALSE;
1302 return sd->highlight_ignore;
1306 elm_widget_highlight_in_theme_set(Evas_Object *obj,
1307 Eina_Bool highlight)
1310 sd->highlight_in_theme = !!highlight;
1311 /* FIXME: if focused, it should switch from one mode to the other */
1315 elm_widget_highlight_in_theme_get(const Evas_Object *obj)
1317 API_ENTRY return EINA_FALSE;
1318 return sd->highlight_in_theme;
1322 elm_widget_focus_get(const Evas_Object *obj)
1324 API_ENTRY return EINA_FALSE;
1329 elm_widget_focused_object_get(const Evas_Object *obj)
1331 const Evas_Object *subobj;
1333 API_ENTRY return NULL;
1335 if (!sd->focused) return NULL;
1336 EINA_LIST_FOREACH(sd->subobjs, l, subobj)
1338 Evas_Object *fobj = elm_widget_focused_object_get(subobj);
1339 if (fobj) return fobj;
1341 return (Evas_Object *)obj;
1345 elm_widget_top_get(const Evas_Object *obj)
1347 API_ENTRY return NULL;
1348 if (sd->parent_obj) return elm_widget_top_get(sd->parent_obj);
1349 return (Evas_Object *)obj;
1353 elm_widget_is(const Evas_Object *obj)
1355 return _elm_widget_is(obj);
1359 elm_widget_parent_widget_get(const Evas_Object *obj)
1361 Evas_Object *parent;
1363 if (_elm_widget_is(obj))
1365 Smart_Data *sd = evas_object_smart_data_get(obj);
1366 if (!sd) return NULL;
1367 parent = sd->parent_obj;
1371 parent = evas_object_data_get(obj, "elm-parent");
1372 if (!parent) parent = evas_object_smart_parent_get(obj);
1377 Evas_Object *elm_parent;
1378 if (_elm_widget_is(parent)) break;
1379 elm_parent = evas_object_data_get(parent, "elm-parent");
1380 if (elm_parent) parent = elm_parent;
1381 else parent = evas_object_smart_parent_get(parent);
1387 elm_widget_parent2_get(const Evas_Object *obj)
1389 if (_elm_widget_is(obj))
1391 Smart_Data *sd = evas_object_smart_data_get(obj);
1392 if (sd) return sd->parent2;
1398 elm_widget_parent2_set(Evas_Object *obj, Evas_Object *parent)
1401 sd->parent2 = parent;
1405 elm_widget_event_callback_add(Evas_Object *obj,
1410 EINA_SAFETY_ON_NULL_RETURN(func);
1411 Elm_Event_Cb_Data *ecb = ELM_NEW(Elm_Event_Cb_Data);
1414 sd->event_cb = eina_list_append(sd->event_cb, ecb);
1418 elm_widget_event_callback_del(Evas_Object *obj,
1422 API_ENTRY return NULL;
1423 EINA_SAFETY_ON_NULL_RETURN_VAL(func, NULL);
1425 Elm_Event_Cb_Data *ecd;
1426 EINA_LIST_FOREACH(sd->event_cb, l, ecd)
1427 if ((ecd->func == func) && (ecd->data == data))
1430 sd->event_cb = eina_list_remove_list(sd->event_cb, l);
1431 return (void *)data;
1437 elm_widget_event_propagate(Evas_Object *obj,
1438 Evas_Callback_Type type,
1440 Evas_Event_Flags *event_flags)
1442 API_ENTRY return EINA_FALSE; //TODO reduce.
1443 if (!_elm_widget_is(obj)) return EINA_FALSE;
1444 Evas_Object *parent = obj;
1445 Elm_Event_Cb_Data *ecd;
1446 Eina_List *l, *l_prev;
1449 (!(event_flags && ((*event_flags) & EVAS_EVENT_FLAG_ON_HOLD))))
1451 sd = evas_object_smart_data_get(parent);
1452 if ((!sd) || (!_elm_widget_is(obj)))
1453 return EINA_FALSE; //Not Elm Widget
1455 if (sd->event_func && (sd->event_func(parent, obj, type, event_info)))
1458 EINA_LIST_FOREACH_SAFE(sd->event_cb, l, l_prev, ecd)
1460 if (ecd->func((void *)ecd->data, parent, obj, type, event_info) ||
1461 (event_flags && ((*event_flags) & EVAS_EVENT_FLAG_ON_HOLD)))
1464 parent = sd->parent_obj;
1473 * Set custom focus chain.
1475 * This function i set one new and overwrite any previous custom focus chain
1476 * with the list of objects. The previous list will be deleted and this list
1477 * will be managed. After setted, don't modity it.
1479 * @note On focus cycle, only will be evaluated children of this container.
1481 * @param obj The container widget
1482 * @param objs Chain of objects to pass focus
1486 elm_widget_focus_custom_chain_set(Evas_Object *obj,
1490 if (!sd->focus_next_func)
1493 elm_widget_focus_custom_chain_unset(obj);
1498 EINA_LIST_FOREACH(objs, l, o)
1500 evas_object_event_callback_add(o, EVAS_CALLBACK_DEL,
1501 _elm_object_focus_chain_del_cb, sd);
1504 sd->focus_chain = objs;
1510 * Get custom focus chain
1512 * @param obj The container widget
1515 EAPI const Eina_List *
1516 elm_widget_focus_custom_chain_get(const Evas_Object *obj)
1518 API_ENTRY return NULL;
1519 return (const Eina_List *)sd->focus_chain;
1525 * Unset custom focus chain
1527 * @param obj The container widget
1531 elm_widget_focus_custom_chain_unset(Evas_Object *obj)
1534 Eina_List *l, *l_next;
1537 EINA_LIST_FOREACH_SAFE(sd->focus_chain, l, l_next, o)
1539 evas_object_event_callback_del_full(o, EVAS_CALLBACK_DEL,
1540 _elm_object_focus_chain_del_cb, sd);
1541 sd->focus_chain = eina_list_remove_list(sd->focus_chain, l);
1548 * Append object to custom focus chain.
1550 * @note If relative_child equal to NULL or not in custom chain, the object
1551 * will be added in end.
1553 * @note On focus cycle, only will be evaluated children of this container.
1555 * @param obj The container widget
1556 * @param child The child to be added in custom chain
1557 * @param relative_child The relative object to position the child
1561 elm_widget_focus_custom_chain_append(Evas_Object *obj,
1563 Evas_Object *relative_child)
1566 EINA_SAFETY_ON_NULL_RETURN(child);
1567 if (!sd->focus_next_func) return;
1569 evas_object_event_callback_del_full(child, EVAS_CALLBACK_DEL,
1570 _elm_object_focus_chain_del_cb, sd);
1572 if (!relative_child)
1573 sd->focus_chain = eina_list_append(sd->focus_chain, child);
1575 sd->focus_chain = eina_list_append_relative(sd->focus_chain,
1576 child, relative_child);
1582 * Prepend object to custom focus chain.
1584 * @note If relative_child equal to NULL or not in custom chain, the object
1585 * will be added in begin.
1587 * @note On focus cycle, only will be evaluated children of this container.
1589 * @param obj The container widget
1590 * @param child The child to be added in custom chain
1591 * @param relative_child The relative object to position the child
1595 elm_widget_focus_custom_chain_prepend(Evas_Object *obj,
1597 Evas_Object *relative_child)
1600 EINA_SAFETY_ON_NULL_RETURN(child);
1602 if (!sd->focus_next_func) return;
1604 evas_object_event_callback_del_full(child, EVAS_CALLBACK_DEL,
1605 _elm_object_focus_chain_del_cb, sd);
1607 if (!relative_child)
1608 sd->focus_chain = eina_list_prepend(sd->focus_chain, child);
1610 sd->focus_chain = eina_list_prepend_relative(sd->focus_chain,
1611 child, relative_child);
1617 * Give focus to next object in object tree.
1619 * Give focus to next object in focus chain of one object sub-tree.
1620 * If the last object of chain already have focus, the focus will go to the
1621 * first object of chain.
1623 * @param obj The widget root of sub-tree
1624 * @param dir Direction to cycle the focus
1629 elm_widget_focus_cycle(Evas_Object *obj,
1630 Elm_Focus_Direction dir)
1632 Evas_Object *target = NULL;
1633 if (!_elm_widget_is(obj))
1635 elm_widget_focus_next_get(obj, dir, &target);
1637 elm_widget_focus_steal(target);
1643 * Give focus to near object in one direction.
1645 * Give focus to near object in direction of one object.
1646 * If none focusable object in given direction, the focus will not change.
1648 * @param obj The reference widget
1649 * @param x Horizontal component of direction to focus
1650 * @param y Vertical component of direction to focus
1654 //FIXME: If x, y indicates the elements of the directional vector,
1655 //It would be better if these values are the normalized value(float x, float y)
1657 EINA_DEPRECATED EAPI void
1658 elm_widget_focus_direction_go(Evas_Object *obj __UNUSED__,
1668 * Get next object in focus chain of object tree.
1670 * Get next object in focus chain of one object sub-tree.
1671 * Return the next object by reference. If don't have any candidate to receive
1672 * focus before chain end, the first candidate will be returned.
1674 * @param obj The widget root of sub-tree
1675 * @param dir Direction os focus chain
1676 * @param next The next object in focus chain
1677 * @return EINA_TRUE if don't need focus chain restart/loop back
1678 * to use 'next' obj.
1683 elm_widget_focus_next_get(const Evas_Object *obj,
1684 Elm_Focus_Direction dir,
1691 API_ENTRY return EINA_FALSE;
1693 /* Ignore if disabled */
1694 if ((!evas_object_visible_get(obj))
1695 || (elm_widget_disabled_get(obj))
1696 || (elm_widget_tree_unfocusable_get(obj)))
1700 if (sd->focus_next_func)
1701 return sd->focus_next_func(obj, dir, next);
1703 if (!elm_widget_can_focus_get(obj))
1707 *next = (Evas_Object *)obj;
1708 return !elm_widget_focus_get(obj);
1714 * Get next object in focus chain of object tree in list.
1716 * Get next object in focus chain of one object sub-tree ordered by one list.
1717 * Return the next object by reference. If don't have any candidate to receive
1718 * focus before list end, the first candidate will be returned.
1720 * @param obj The widget root of sub-tree
1721 * @param dir Direction os focus chain
1722 * @param items list with ordered objects
1723 * @param list_data_get function to get the object from one item of list
1724 * @param next The next object in focus chain
1725 * @return EINA_TRUE if don't need focus chain restart/loop back
1726 * to use 'next' obj.
1731 elm_widget_focus_list_next_get(const Evas_Object *obj,
1732 const Eina_List *items,
1733 void *(*list_data_get)(const Eina_List * list),
1734 Elm_Focus_Direction dir,
1737 Eina_List *(*list_next)(const Eina_List * list) = NULL;
1743 if (!_elm_widget_is(obj))
1750 if (dir == ELM_FOCUS_PREVIOUS)
1752 items = eina_list_last(items);
1753 list_next = eina_list_prev;
1755 else if (dir == ELM_FOCUS_NEXT)
1756 list_next = eina_list_next;
1760 const Eina_List *l = items;
1762 /* Recovery last focused sub item */
1763 if (elm_widget_focus_get(obj))
1764 for (; l; l = list_next(l))
1766 Evas_Object *cur = list_data_get(l);
1767 if (elm_widget_focus_get(cur)) break;
1770 const Eina_List *start = l;
1771 Evas_Object *to_focus = NULL;
1773 /* Interate sub items */
1774 /* Go to end of list */
1775 for (; l; l = list_next(l))
1777 Evas_Object *tmp = NULL;
1778 Evas_Object *cur = list_data_get(l);
1780 if (elm_widget_parent_get(cur) != obj)
1783 /* Try Focus cycle in subitem */
1784 if (elm_widget_focus_next_get(cur, dir, &tmp))
1789 else if ((tmp) && (!to_focus))
1795 /* Get First possible */
1796 for (; l != start; l = list_next(l))
1798 Evas_Object *tmp = NULL;
1799 Evas_Object *cur = list_data_get(l);
1801 if (elm_widget_parent_get(cur) != obj)
1804 /* Try Focus cycle in subitem */
1805 elm_widget_focus_next_get(cur, dir, &tmp);
1818 elm_widget_signal_emit(Evas_Object *obj,
1819 const char *emission,
1823 if (!sd->signal_func) return;
1824 sd->signal_func(obj, emission, source);
1828 _edje_signal_callback(void *data,
1829 Evas_Object *obj __UNUSED__,
1830 const char *emission,
1833 Edje_Signal_Data *esd = data;
1834 esd->func(esd->data, esd->obj, emission, source);
1838 elm_widget_signal_callback_add(Evas_Object *obj,
1839 const char *emission,
1841 Edje_Signal_Cb func,
1844 Edje_Signal_Data *esd;
1846 if (!sd->callback_add_func) return;
1847 EINA_SAFETY_ON_NULL_RETURN(func);
1849 esd = ELM_NEW(Edje_Signal_Data);
1854 esd->emission = eina_stringshare_add(emission);
1855 esd->source = eina_stringshare_add(source);
1857 sd->edje_signals = eina_list_append(sd->edje_signals, esd);
1858 sd->callback_add_func(obj, emission, source, _edje_signal_callback, esd);
1862 elm_widget_signal_callback_del(Evas_Object *obj,
1863 const char *emission,
1865 Edje_Signal_Cb func)
1867 Edje_Signal_Data *esd;
1870 API_ENTRY return NULL;
1871 if (!sd->callback_del_func) return NULL;
1873 EINA_LIST_FOREACH(sd->edje_signals, l, esd)
1875 if ((esd->func == func) && (!strcmp(esd->emission, emission)) &&
1876 (!strcmp(esd->source, source)))
1878 sd->edje_signals = eina_list_remove_list(sd->edje_signals, l);
1879 eina_stringshare_del(esd->emission);
1880 eina_stringshare_del(esd->source);
1884 sd->callback_del_func
1885 (obj, emission, source, _edje_signal_callback, esd);
1894 elm_widget_focus_set(Evas_Object *obj,
1901 sd->focus_order = focus_order;
1902 sd->focused = EINA_TRUE;
1903 if (sd->on_focus_func) sd->on_focus_func(sd->on_focus_data, obj);
1907 sd->focus_func(obj);
1914 if ((_is_focusable(sd->resize_obj)) &&
1915 (!elm_widget_disabled_get(sd->resize_obj)))
1917 elm_widget_focus_set(sd->resize_obj, first);
1923 EINA_LIST_FOREACH(sd->subobjs, l, child)
1925 if ((_is_focusable(child)) &&
1926 (!elm_widget_disabled_get(child)))
1928 elm_widget_focus_set(child, first);
1938 EINA_LIST_REVERSE_FOREACH(sd->subobjs, l, child)
1940 if ((_is_focusable(child)) &&
1941 (!elm_widget_disabled_get(child)))
1943 elm_widget_focus_set(child, first);
1949 if ((_is_focusable(sd->resize_obj)) &&
1950 (!elm_widget_disabled_get(sd->resize_obj)))
1952 elm_widget_focus_set(sd->resize_obj, first);
1960 elm_widget_parent_get(const Evas_Object *obj)
1962 API_ENTRY return NULL;
1963 return sd->parent_obj;
1967 elm_widget_focused_object_clear(Evas_Object *obj)
1970 if (!sd->focused) return;
1971 if (sd->resize_obj && elm_widget_focus_get(sd->resize_obj))
1972 elm_widget_focused_object_clear(sd->resize_obj);
1977 EINA_LIST_FOREACH(sd->subobjs, l, child)
1979 if (elm_widget_focus_get(child))
1981 elm_widget_focused_object_clear(child);
1986 sd->focused = EINA_FALSE;
1987 if (sd->on_focus_func) sd->on_focus_func(sd->on_focus_data, obj);
1988 if (sd->focus_func) sd->focus_func(obj);
1992 elm_widget_focus_steal(Evas_Object *obj)
1994 Evas_Object *parent, *parent2, *o;
1997 if (sd->focused) return;
1998 if (sd->disabled) return;
1999 if (!sd->can_focus) return;
2000 if (sd->tree_unfocusable) return;
2004 o = elm_widget_parent_get(parent);
2006 sd = evas_object_smart_data_get(o);
2007 if (sd->disabled || sd->tree_unfocusable) return;
2008 if (sd->focused) break;
2011 if ((!elm_widget_parent_get(parent)) &&
2012 (!elm_widget_parent2_get(parent)))
2013 elm_widget_focused_object_clear(parent);
2016 parent2 = elm_widget_parent_get(parent);
2017 if (!parent2) parent2 = elm_widget_parent2_get(parent);
2019 sd = evas_object_smart_data_get(parent);
2022 if ((sd->resize_obj) && (elm_widget_focus_get(sd->resize_obj)))
2023 elm_widget_focused_object_clear(sd->resize_obj);
2028 EINA_LIST_FOREACH(sd->subobjs, l, child)
2030 if (elm_widget_focus_get(child))
2032 elm_widget_focused_object_clear(child);
2044 elm_widget_focus_restore(Evas_Object *obj)
2046 Evas_Object *newest = NULL;
2047 unsigned int newest_focus_order = 0;
2050 newest = _newest_focus_order_get(obj, &newest_focus_order, EINA_TRUE);
2053 elm_object_focus_set(newest, EINA_FALSE);
2054 elm_object_focus_set(newest, EINA_TRUE);
2059 _elm_widget_top_win_focused_set(Evas_Object *obj, Eina_Bool top_win_focused)
2065 if (sd->top_win_focused == top_win_focused) return;
2067 _elm_widget_top_win_focused_set(sd->resize_obj, top_win_focused);
2068 EINA_LIST_FOREACH(sd->subobjs, l, child)
2070 _elm_widget_top_win_focused_set(child, top_win_focused);
2072 sd->top_win_focused = top_win_focused;
2076 _elm_widget_top_win_focused_get(const Evas_Object *obj)
2078 API_ENTRY return EINA_FALSE;
2079 return sd->top_win_focused;
2083 elm_widget_activate(Evas_Object *obj)
2086 elm_widget_change(obj);
2087 if (sd->activate_func) sd->activate_func(obj);
2091 elm_widget_change(Evas_Object *obj)
2094 elm_widget_change(elm_widget_parent_get(obj));
2095 if (sd->on_change_func) sd->on_change_func(sd->on_change_data, obj);
2099 elm_widget_disabled_set(Evas_Object *obj,
2104 if (sd->disabled == disabled) return;
2105 sd->disabled = !!disabled;
2106 elm_widget_focus_disabled_handle(obj);
2107 if (sd->disable_func) sd->disable_func(obj);
2111 elm_widget_disabled_get(const Evas_Object *obj)
2114 return sd->disabled;
2118 elm_widget_show_region_set(Evas_Object *obj,
2123 Eina_Bool forceshow)
2125 Evas_Object *parent_obj, *child_obj;
2126 Evas_Coord px, py, cx, cy;
2130 evas_smart_objects_calculate(evas_object_evas_get(obj));
2132 if (!forceshow && (x == sd->rx) && (y == sd->ry) &&
2133 (w == sd->rw) && (h == sd->rh)) return;
2138 if (sd->on_show_region_func)
2139 sd->on_show_region_func(sd->on_show_region_data, obj);
2143 parent_obj = sd->parent_obj;
2144 child_obj = sd->obj;
2145 if ((!parent_obj) || (!_elm_widget_is(parent_obj))) break;
2146 sd = evas_object_smart_data_get(parent_obj);
2149 evas_object_geometry_get(parent_obj, &px, &py, NULL, NULL);
2150 evas_object_geometry_get(child_obj, &cx, &cy, NULL, NULL);
2159 if (sd->on_show_region_func)
2161 sd->on_show_region_func(sd->on_show_region_data, parent_obj);
2168 elm_widget_show_region_get(const Evas_Object *obj,
2184 * Get the focus region of the given widget.
2186 * The focus region is the area of a widget that should brought into the
2187 * visible area when the widget is focused. Mostly used to show the part of
2188 * an entry where the cursor is, for example. The area returned is relative
2189 * to the object @p obj.
2190 * If the @p obj doesn't have the proper on_focus_region_hook set, this
2191 * function will return the full size of the object.
2193 * @param obj The widget object
2194 * @param x Where to store the x coordinate of the area
2195 * @param y Where to store the y coordinate of the area
2196 * @param w Where to store the width of the area
2197 * @param h Where to store the height of the area
2202 elm_widget_focus_region_get(const Evas_Object *obj,
2212 sd = evas_object_smart_data_get(obj);
2213 if (!sd || !_elm_widget_is(obj) || !sd->on_focus_region_func)
2215 evas_object_geometry_get(obj, NULL, NULL, w, h);
2220 sd->on_focus_region_func(obj, x, y, w, h);
2224 elm_widget_scroll_hold_push(Evas_Object *obj)
2228 if (sd->scroll_hold == 1)
2229 evas_object_smart_callback_call(obj, "scroll-hold-on", obj);
2230 if (sd->parent_obj) elm_widget_scroll_hold_push(sd->parent_obj);
2231 // FIXME: on delete/reparent hold pop
2235 elm_widget_scroll_hold_pop(Evas_Object *obj)
2239 if (!sd->scroll_hold)
2240 evas_object_smart_callback_call(obj, "scroll-hold-off", obj);
2241 if (sd->parent_obj) elm_widget_scroll_hold_pop(sd->parent_obj);
2242 if (sd->scroll_hold < 0) sd->scroll_hold = 0;
2246 elm_widget_scroll_hold_get(const Evas_Object *obj)
2249 return sd->scroll_hold;
2253 elm_widget_scroll_freeze_push(Evas_Object *obj)
2256 sd->scroll_freeze++;
2257 if (sd->scroll_freeze == 1)
2258 evas_object_smart_callback_call(obj, "scroll-freeze-on", obj);
2259 if (sd->parent_obj) elm_widget_scroll_freeze_push(sd->parent_obj);
2260 // FIXME: on delete/reparent freeze pop
2264 elm_widget_scroll_freeze_pop(Evas_Object *obj)
2267 sd->scroll_freeze--;
2268 if (!sd->scroll_freeze)
2269 evas_object_smart_callback_call(obj, "scroll-freeze-off", obj);
2270 if (sd->parent_obj) elm_widget_scroll_freeze_pop(sd->parent_obj);
2271 if (sd->scroll_freeze < 0) sd->scroll_freeze = 0;
2275 elm_widget_scroll_freeze_get(const Evas_Object *obj)
2278 return sd->scroll_freeze;
2282 elm_widget_scale_set(Evas_Object *obj,
2286 if (scale <= 0.0) scale = 0.0;
2287 if (sd->scale != scale)
2290 elm_widget_theme(obj);
2295 elm_widget_scale_get(const Evas_Object *obj)
2297 API_ENTRY return 1.0;
2298 // FIXME: save walking up the tree by storing/caching parent scale
2299 if (sd->scale == 0.0)
2302 return elm_widget_scale_get(sd->parent_obj);
2310 elm_widget_theme_set(Evas_Object *obj,
2314 if (sd->theme != th)
2316 if (sd->theme) elm_theme_free(sd->theme);
2319 elm_widget_theme(obj);
2324 elm_widget_text_part_set(Evas_Object *obj, const char *part, const char *label)
2328 if (!sd->text_set_func)
2331 sd->text_set_func(obj, part, label);
2335 elm_widget_text_part_get(const Evas_Object *obj, const char *part)
2337 API_ENTRY return NULL;
2339 if (!sd->text_get_func)
2342 return sd->text_get_func(obj, part);
2346 elm_widget_domain_translatable_text_part_set(Evas_Object *obj, const char *part, const char *domain, const char *label)
2350 Elm_Translate_String_Data *ts = NULL;
2353 str = eina_stringshare_add(part);
2354 EINA_LIST_FOREACH(sd->translate_strings, l, ts)
2361 eina_stringshare_del(str);
2364 ts = malloc(sizeof(Elm_Translate_String_Data));
2368 ts->domain = eina_stringshare_add(domain);
2369 ts->string = eina_stringshare_add(label);
2370 sd->translate_strings = eina_list_append(sd->translate_strings, ts);
2376 eina_stringshare_replace(&ts->domain, domain);
2377 eina_stringshare_replace(&ts->string, label);
2381 sd->translate_strings = eina_list_remove_list(
2382 sd->translate_strings, l);
2383 eina_stringshare_del(ts->id);
2384 eina_stringshare_del(ts->domain);
2385 eina_stringshare_del(ts->string);
2388 eina_stringshare_del(str);
2392 if (label && label[0])
2393 label = dgettext(domain, label);
2395 elm_widget_text_part_set(obj, part, label);
2399 elm_widget_translatable_text_part_get(const Evas_Object *obj, const char *part)
2401 const char *str, *ret = NULL;
2403 Elm_Translate_String_Data *ts;
2404 API_ENTRY return NULL;
2406 str = eina_stringshare_add(part);
2407 EINA_LIST_FOREACH(sd->translate_strings, l, ts)
2413 eina_stringshare_del(str);
2418 elm_widget_translate(Evas_Object *obj)
2423 Elm_Translate_String_Data *ts;
2427 EINA_LIST_FOREACH(sd->subobjs, l, child) elm_widget_translate(child);
2428 if (sd->resize_obj) elm_widget_translate(sd->resize_obj);
2429 if (sd->hover_obj) elm_widget_translate(sd->hover_obj);
2430 if (sd->translate_func) sd->translate_func(obj);
2433 EINA_LIST_FOREACH(sd->translate_strings, l, ts)
2435 const char *s = dgettext(ts->domain, ts->string);
2436 elm_widget_text_part_set(obj, ts->id, s);
2442 elm_widget_content_part_set(Evas_Object *obj, const char *part, Evas_Object *content)
2446 if (!sd->content_set_func) return;
2447 sd->content_set_func(obj, part, content);
2451 elm_widget_content_part_get(const Evas_Object *obj, const char *part)
2453 API_ENTRY return NULL;
2455 if (!sd->content_get_func) return NULL;
2456 return sd->content_get_func(obj, part);
2460 elm_widget_content_part_unset(Evas_Object *obj, const char *part)
2462 API_ENTRY return NULL;
2464 if (!sd->content_unset_func) return NULL;
2465 return sd->content_unset_func(obj, part);
2469 elm_widget_access_info_set(Evas_Object *obj, const char *txt)
2472 if (sd->access_info) eina_stringshare_del(sd->access_info);
2473 if (!txt) sd->access_info = NULL;
2474 else sd->access_info = eina_stringshare_add(txt);
2478 elm_widget_access_info_get(const Evas_Object *obj)
2480 API_ENTRY return NULL;
2481 return sd->access_info;
2485 elm_widget_theme_get(const Evas_Object *obj)
2487 API_ENTRY return NULL;
2491 return elm_widget_theme_get(sd->parent_obj);
2499 elm_widget_style_set(Evas_Object *obj,
2502 API_ENTRY return EINA_FALSE;
2504 if (eina_stringshare_replace(&sd->style, style))
2505 return elm_widget_theme(obj);
2511 elm_widget_style_get(const Evas_Object *obj)
2513 API_ENTRY return NULL;
2514 if (sd->style) return sd->style;
2519 elm_widget_type_set(Evas_Object *obj,
2523 eina_stringshare_replace(&sd->type, type);
2527 elm_widget_type_get(const Evas_Object *obj)
2529 API_ENTRY return NULL;
2530 if (sd->type) return sd->type;
2535 elm_widget_tooltip_add(Evas_Object *obj,
2539 sd->tooltips = eina_list_append(sd->tooltips, tt);
2543 elm_widget_tooltip_del(Evas_Object *obj,
2547 sd->tooltips = eina_list_remove(sd->tooltips, tt);
2551 elm_widget_cursor_add(Evas_Object *obj,
2555 sd->cursors = eina_list_append(sd->cursors, cur);
2559 elm_widget_cursor_del(Evas_Object *obj,
2563 sd->cursors = eina_list_remove(sd->cursors, cur);
2567 elm_widget_drag_lock_x_set(Evas_Object *obj,
2571 if (sd->drag_x_locked == lock) return;
2572 sd->drag_x_locked = lock;
2573 if (sd->drag_x_locked) _propagate_x_drag_lock(obj, 1);
2574 else _propagate_x_drag_lock(obj, -1);
2578 elm_widget_drag_lock_y_set(Evas_Object *obj,
2582 if (sd->drag_y_locked == lock) return;
2583 sd->drag_y_locked = lock;
2584 if (sd->drag_y_locked) _propagate_y_drag_lock(obj, 1);
2585 else _propagate_y_drag_lock(obj, -1);
2589 elm_widget_drag_lock_x_get(const Evas_Object *obj)
2591 API_ENTRY return EINA_FALSE;
2592 return sd->drag_x_locked;
2596 elm_widget_drag_lock_y_get(const Evas_Object *obj)
2598 API_ENTRY return EINA_FALSE;
2599 return sd->drag_y_locked;
2603 elm_widget_drag_child_locked_x_get(const Evas_Object *obj)
2606 return sd->child_drag_x_locked;
2610 elm_widget_drag_child_locked_y_get(const Evas_Object *obj)
2613 return sd->child_drag_y_locked;
2617 elm_widget_theme_object_set(Evas_Object *obj,
2620 const char *welement,
2623 API_ENTRY return EINA_FALSE;
2624 return _elm_theme_object_set(obj, edj, wname, welement, wstyle);
2628 elm_widget_is_check(const Evas_Object *obj)
2630 static int abort_on_warn = -1;
2631 if (elm_widget_is(obj))
2634 ERR("Passing Object: %p.", obj);
2635 if (abort_on_warn == -1)
2637 if (getenv("ELM_ERROR_ABORT")) abort_on_warn = 1;
2638 else abort_on_warn = 0;
2640 if (abort_on_warn == 1) abort();
2645 elm_widget_type_check(const Evas_Object *obj,
2649 const char *provided, *expected = "(unknown)";
2650 static int abort_on_warn = -1;
2651 provided = elm_widget_type_get(obj);
2652 if (EINA_LIKELY(provided == type)) return EINA_TRUE;
2653 if (type) expected = type;
2654 if ((!provided) || (!provided[0]))
2656 provided = evas_object_type_get(obj);
2657 if ((!provided) || (!provided[0]))
2658 provided = "(unknown)";
2660 ERR("Passing Object: %p in function: %s, of type: '%s' when expecting type: '%s'", obj, func, provided, expected);
2661 if (abort_on_warn == -1)
2663 if (getenv("ELM_ERROR_ABORT")) abort_on_warn = 1;
2664 else abort_on_warn = 0;
2666 if (abort_on_warn == 1) abort();
2670 static Evas_Object *
2671 _widget_name_find(const Evas_Object *obj, const char *name, int recurse)
2676 INTERNAL_ENTRY NULL;
2678 if (!_elm_widget_is(obj)) return NULL;
2681 s = evas_object_name_get(sd->resize_obj);
2682 if ((s) && (!strcmp(s, name))) return sd->resize_obj;
2683 if ((recurse != 0) &&
2684 ((child = _widget_name_find(sd->resize_obj, name, recurse - 1))))
2687 EINA_LIST_FOREACH(sd->subobjs, l, child)
2689 s = evas_object_name_get(child);
2690 if ((s) && (!strcmp(s, name))) return child;
2691 if ((recurse != 0) &&
2692 ((child = _widget_name_find(child, name, recurse - 1))))
2697 s = evas_object_name_get(sd->hover_obj);
2698 if ((s) && (!strcmp(s, name))) return sd->hover_obj;
2699 if ((recurse != 0) &&
2700 ((child = _widget_name_find(sd->hover_obj, name, recurse - 1))))
2707 elm_widget_name_find(const Evas_Object *obj, const char *name, int recurse)
2709 API_ENTRY return NULL;
2710 if (!name) return NULL;
2711 return _widget_name_find(obj, name, recurse);
2717 * Split string in words
2719 * @param str Source string
2720 * @return List of const words
2722 * @see elm_widget_stringlist_free()
2726 elm_widget_stringlist_get(const char *str)
2728 Eina_List *list = NULL;
2730 if (!str) return NULL;
2731 for (b = s = str; 1; s++)
2733 if ((*s == ' ') || (!*s))
2735 char *t = malloc(s - b + 1);
2738 strncpy(t, b, s - b);
2740 list = eina_list_append(list, eina_stringshare_add(t));
2751 elm_widget_stringlist_free(Eina_List *list)
2754 EINA_LIST_FREE(list, s) eina_stringshare_del(s);
2758 elm_widget_focus_hide_handle(Evas_Object *obj)
2760 if (!_elm_widget_is(obj))
2762 _if_focused_revert(obj, EINA_TRUE);
2766 elm_widget_focus_mouse_up_handle(Evas_Object *obj)
2768 Evas_Object *o = obj;
2771 if (_elm_widget_is(o)) break;
2772 o = evas_object_smart_parent_get(o);
2776 if (!_is_focusable(o)) return;
2777 elm_widget_focus_steal(o);
2781 elm_widget_focus_tree_unfocusable_handle(Evas_Object *obj)
2785 //FIXME: Need to check whether the object is unfocusable or not.
2787 if (!elm_widget_parent_get(obj))
2788 elm_widget_focused_object_clear(obj);
2790 _if_focused_revert(obj, EINA_TRUE);
2794 elm_widget_focus_disabled_handle(Evas_Object *obj)
2798 elm_widget_focus_tree_unfocusable_handle(obj);
2802 elm_widget_focus_order_get(const Evas_Object *obj)
2805 return sd->focus_order;
2811 * Allocate a new Elm_Widget_Item-derived structure.
2813 * The goal of this structure is to provide common ground for actions
2814 * that a widget item have, such as the owner widget, callback to
2815 * notify deletion, data pointer and maybe more.
2817 * @param widget the owner widget that holds this item, must be an elm_widget!
2818 * @param alloc_size any number greater than sizeof(Elm_Widget_Item) that will
2819 * be used to allocate memory.
2821 * @return allocated memory that is already zeroed out, or NULL on errors.
2823 * @see elm_widget_item_new() convenience macro.
2824 * @see elm_widget_item_del() to release memory.
2827 EAPI Elm_Widget_Item *
2828 _elm_widget_item_new(Evas_Object *widget,
2831 if (!_elm_widget_is(widget))
2834 Elm_Widget_Item *item;
2836 EINA_SAFETY_ON_TRUE_RETURN_VAL(alloc_size < sizeof(Elm_Widget_Item), NULL);
2837 EINA_SAFETY_ON_TRUE_RETURN_VAL(!_elm_widget_is(widget), NULL);
2839 item = calloc(1, alloc_size);
2840 EINA_SAFETY_ON_NULL_RETURN_VAL(item, NULL);
2842 EINA_MAGIC_SET(item, ELM_WIDGET_ITEM_MAGIC);
2843 item->widget = widget;
2848 _elm_widget_item_free(Elm_Widget_Item *item)
2850 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
2852 _elm_access_item_unregister(item);
2855 item->del_func((void *)item->data, item->widget, item);
2858 evas_object_del(item->view);
2862 _elm_access_clear(item->access);
2866 if (item->access_info)
2867 eina_stringshare_del(item->access_info);
2869 EINA_MAGIC_SET(item, EINA_MAGIC_NONE);
2876 * Releases widget item memory, calling back del_cb() if it exists.
2878 * If there is a Elm_Widget_Item::del_cb, then it will be called prior
2879 * to memory release. Note that elm_widget_item_pre_notify_del() calls
2880 * this function and then unset it, thus being useful for 2 step
2881 * cleanup whenever the del_cb may use any of the data that must be
2882 * deleted from item.
2884 * The Elm_Widget_Item::view will be deleted (evas_object_del()) if it
2887 * @param item a valid #Elm_Widget_Item to be deleted.
2888 * @see elm_widget_item_del() convenience macro.
2892 _elm_widget_item_del(Elm_Widget_Item *item)
2894 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
2896 //Widget item delete callback
2897 if (item->del_pre_func)
2899 if (item->del_pre_func((Elm_Object_Item *)item))
2900 _elm_widget_item_free(item);
2903 _elm_widget_item_free(item);
2909 * Set the function to notify to widgets when item is being deleted by user.
2911 * @param item a valid #Elm_Widget_Item to be notified
2912 * @see elm_widget_item_del_pre_hook_set() convenience macro.
2916 _elm_widget_item_del_pre_hook_set(Elm_Widget_Item *item, Elm_Widget_Del_Pre_Cb func)
2918 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
2919 item->del_pre_func = func;
2925 * Notify object will be deleted without actually deleting it.
2927 * This function will callback Elm_Widget_Item::del_cb if it is set
2928 * and then unset it so it is not called twice (ie: from
2929 * elm_widget_item_del()).
2931 * @param item a valid #Elm_Widget_Item to be notified
2932 * @see elm_widget_item_pre_notify_del() convenience macro.
2936 _elm_widget_item_pre_notify_del(Elm_Widget_Item *item)
2938 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
2939 if (!item->del_func) return;
2940 item->del_func((void *)item->data, item->widget, item);
2941 item->del_func = NULL;
2947 * Set the function to notify when item is being deleted.
2949 * This function will complain if there was a callback set already,
2950 * however it will set the new one.
2952 * The callback will be called from elm_widget_item_pre_notify_del()
2953 * or elm_widget_item_del() will be called with:
2954 * - data: the Elm_Widget_Item::data value.
2955 * - obj: the Elm_Widget_Item::widget evas object.
2956 * - event_info: the item being deleted.
2958 * @param item a valid #Elm_Widget_Item to be notified
2959 * @see elm_widget_item_del_cb_set() convenience macro.
2963 _elm_widget_item_del_cb_set(Elm_Widget_Item *item,
2966 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
2968 if ((item->del_func) && (item->del_func != func))
2969 WRN("You're replacing a previously set del_cb %p of item %p with %p",
2970 item->del_func, item, func);
2972 item->del_func = func;
2978 * Set user-data in this item.
2980 * User data may be used to identify this item or just store any
2981 * application data. It is automatically given as the first parameter
2982 * of the deletion notify callback.
2984 * @param item a valid #Elm_Widget_Item to store data in.
2985 * @param data user data to store.
2986 * @see elm_widget_item_del_cb_set() convenience macro.
2990 _elm_widget_item_data_set(Elm_Widget_Item *item,
2993 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
2994 if ((item->data) && (item->data != data))
2995 DBG("Replacing item %p data %p with %p", item, item->data, data);
3002 * Retrieves user-data of this item.
3004 * @param item a valid #Elm_Widget_Item to get data from.
3005 * @see elm_widget_item_data_set()
3009 _elm_widget_item_data_get(const Elm_Widget_Item *item)
3011 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item, NULL);
3012 return (void *)item->data;
3016 _elm_widget_item_disabled_set(Elm_Widget_Item *item, Eina_Bool disabled)
3018 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
3020 if (item->disabled == disabled) return;
3021 item->disabled = !!disabled;
3022 if (item->disable_func) item->disable_func(item);
3026 _elm_widget_item_disabled_get(const Elm_Widget_Item *item)
3028 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item, EINA_FALSE);
3029 return item->disabled;
3033 _elm_widget_item_disable_hook_set(Elm_Widget_Item *item,
3034 Elm_Widget_Disable_Cb func)
3036 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
3037 item->disable_func = func;
3040 typedef struct _Elm_Widget_Item_Tooltip Elm_Widget_Item_Tooltip;
3042 struct _Elm_Widget_Item_Tooltip
3044 Elm_Widget_Item *item;
3045 Elm_Tooltip_Item_Content_Cb func;
3046 Evas_Smart_Cb del_cb;
3050 static Evas_Object *
3051 _elm_widget_item_tooltip_label_create(void *data,
3052 Evas_Object *obj __UNUSED__,
3053 Evas_Object *tooltip,
3054 void *item __UNUSED__)
3056 Evas_Object *label = elm_label_add(tooltip);
3059 elm_object_style_set(label, "tooltip");
3060 elm_object_text_set(label, data);
3064 static Evas_Object *
3065 _elm_widget_item_tooltip_trans_label_create(void *data,
3066 Evas_Object *obj __UNUSED__,
3067 Evas_Object *tooltip,
3068 void *item __UNUSED__)
3070 Evas_Object *label = elm_label_add(tooltip);
3073 elm_object_style_set(label, "tooltip");
3074 elm_object_translatable_text_set(label, data);
3079 _elm_widget_item_tooltip_label_del_cb(void *data,
3080 Evas_Object *obj __UNUSED__,
3081 void *event_info __UNUSED__)
3083 eina_stringshare_del(data);
3089 * Set the text to be shown in the widget item.
3091 * @param item Target item
3092 * @param text The text to set in the content
3094 * Setup the text as tooltip to object. The item can have only one tooltip,
3095 * so any previous tooltip data is removed.
3100 _elm_widget_item_tooltip_text_set(Elm_Widget_Item *item,
3103 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
3104 EINA_SAFETY_ON_NULL_RETURN(text);
3106 text = eina_stringshare_add(text);
3107 _elm_widget_item_tooltip_content_cb_set
3108 (item, _elm_widget_item_tooltip_label_create, text,
3109 _elm_widget_item_tooltip_label_del_cb);
3113 _elm_widget_item_tooltip_translatable_text_set(Elm_Widget_Item *item,
3116 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
3117 EINA_SAFETY_ON_NULL_RETURN(text);
3119 text = eina_stringshare_add(text);
3120 _elm_widget_item_tooltip_content_cb_set
3121 (item, _elm_widget_item_tooltip_trans_label_create, text,
3122 _elm_widget_item_tooltip_label_del_cb);
3125 static Evas_Object *
3126 _elm_widget_item_tooltip_create(void *data,
3128 Evas_Object *tooltip)
3130 Elm_Widget_Item_Tooltip *wit = data;
3131 return wit->func((void *)wit->data, obj, tooltip, wit->item);
3135 _elm_widget_item_tooltip_del_cb(void *data,
3137 void *event_info __UNUSED__)
3139 Elm_Widget_Item_Tooltip *wit = data;
3140 if (wit->del_cb) wit->del_cb((void *)wit->data, obj, wit->item);
3147 * Set the content to be shown in the tooltip item
3149 * Setup the tooltip to item. The item can have only one tooltip,
3150 * so any previous tooltip data is removed. @p func(with @p data) will
3151 * be called every time that need show the tooltip and it should
3152 * return a valid Evas_Object. This object is then managed fully by
3153 * tooltip system and is deleted when the tooltip is gone.
3155 * @param item the widget item being attached a tooltip.
3156 * @param func the function used to create the tooltip contents.
3157 * @param data what to provide to @a func as callback data/context.
3158 * @param del_cb called when data is not needed anymore, either when
3159 * another callback replaces @func, the tooltip is unset with
3160 * elm_widget_item_tooltip_unset() or the owner @a item
3161 * dies. This callback receives as the first parameter the
3162 * given @a data, and @c event_info is the item.
3167 _elm_widget_item_tooltip_content_cb_set(Elm_Widget_Item *item,
3168 Elm_Tooltip_Item_Content_Cb func,
3170 Evas_Smart_Cb del_cb)
3172 Elm_Widget_Item_Tooltip *wit;
3174 ELM_WIDGET_ITEM_CHECK_OR_GOTO(item, error_noitem);
3178 _elm_widget_item_tooltip_unset(item);
3182 wit = ELM_NEW(Elm_Widget_Item_Tooltip);
3183 if (!wit) goto error;
3187 wit->del_cb = del_cb;
3189 elm_object_sub_tooltip_content_cb_set
3190 (item->view, item->widget, _elm_widget_item_tooltip_create, wit,
3191 _elm_widget_item_tooltip_del_cb);
3196 if (del_cb) del_cb((void *)data, NULL, item);
3199 if (del_cb) del_cb((void *)data, item->widget, item);
3205 * Unset tooltip from item
3207 * @param item widget item to remove previously set tooltip.
3209 * Remove tooltip from item. The callback provided as del_cb to
3210 * elm_widget_item_tooltip_content_cb_set() will be called to notify
3211 * it is not used anymore.
3213 * @see elm_widget_item_tooltip_content_cb_set()
3218 _elm_widget_item_tooltip_unset(Elm_Widget_Item *item)
3220 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
3221 elm_object_tooltip_unset(item->view);
3227 * Sets a different style for this item tooltip.
3229 * @note before you set a style you should define a tooltip with
3230 * elm_widget_item_tooltip_content_cb_set() or
3231 * elm_widget_item_tooltip_text_set()
3233 * @param item widget item with tooltip already set.
3234 * @param style the theme style to use (default, transparent, ...)
3239 _elm_widget_item_tooltip_style_set(Elm_Widget_Item *item,
3242 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
3243 elm_object_tooltip_style_set(item->view, style);
3247 _elm_widget_item_tooltip_window_mode_set(Elm_Widget_Item *item, Eina_Bool disable)
3249 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item, EINA_FALSE);
3250 return elm_object_tooltip_window_mode_set(item->view, disable);
3254 _elm_widget_item_tooltip_window_mode_get(const Elm_Widget_Item *item)
3256 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item, EINA_FALSE);
3257 return elm_object_tooltip_window_mode_get(item->view);
3263 * Get the style for this item tooltip.
3265 * @param item widget item with tooltip already set.
3266 * @return style the theme style in use, defaults to "default". If the
3267 * object does not have a tooltip set, then NULL is returned.
3272 _elm_widget_item_tooltip_style_get(const Elm_Widget_Item *item)
3274 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item, NULL);
3275 return elm_object_tooltip_style_get(item->view);
3279 _elm_widget_item_cursor_set(Elm_Widget_Item *item,
3282 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
3283 elm_object_sub_cursor_set(item->view, item->widget, cursor);
3287 _elm_widget_item_cursor_get(const Elm_Widget_Item *item)
3289 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item, NULL);
3290 return elm_object_cursor_get(item->view);
3294 _elm_widget_item_cursor_unset(Elm_Widget_Item *item)
3296 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
3297 elm_object_cursor_unset(item->view);
3303 * Sets a different style for this item cursor.
3305 * @note before you set a style you should define a cursor with
3306 * elm_widget_item_cursor_set()
3308 * @param item widget item with cursor already set.
3309 * @param style the theme style to use (default, transparent, ...)
3314 _elm_widget_item_cursor_style_set(Elm_Widget_Item *item,
3317 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
3318 elm_object_cursor_style_set(item->view, style);
3324 * Get the style for this item cursor.
3326 * @param item widget item with cursor already set.
3327 * @return style the theme style in use, defaults to "default". If the
3328 * object does not have a cursor set, then NULL is returned.
3333 _elm_widget_item_cursor_style_get(const Elm_Widget_Item *item)
3335 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item, NULL);
3336 return elm_object_cursor_style_get(item->view);
3342 * Set if the cursor set should be searched on the theme or should use
3343 * the provided by the engine, only.
3345 * @note before you set if should look on theme you should define a cursor
3346 * with elm_object_cursor_set(). By default it will only look for cursors
3347 * provided by the engine.
3349 * @param item widget item with cursor already set.
3350 * @param engine_only boolean to define it cursors should be looked only
3351 * between the provided by the engine or searched on widget's theme as well.
3356 _elm_widget_item_cursor_engine_only_set(Elm_Widget_Item *item,
3357 Eina_Bool engine_only)
3359 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
3360 elm_object_cursor_theme_search_enabled_set(item->view, engine_only);
3366 * Get the cursor engine only usage for this item cursor.
3368 * @param item widget item with cursor already set.
3369 * @return engine_only boolean to define it cursors should be looked only
3370 * between the provided by the engine or searched on widget's theme as well. If
3371 * the object does not have a cursor set, then EINA_FALSE is returned.
3376 _elm_widget_item_cursor_engine_only_get(const Elm_Widget_Item *item)
3378 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item, EINA_FALSE);
3379 return elm_object_cursor_theme_search_enabled_get(item->view);
3382 // smart object funcs
3384 _smart_reconfigure(Smart_Data *sd)
3388 evas_object_move(sd->resize_obj, sd->x, sd->y);
3389 evas_object_resize(sd->resize_obj, sd->w, sd->h);
3393 evas_object_move(sd->hover_obj, sd->x, sd->y);
3394 evas_object_resize(sd->hover_obj, sd->w, sd->h);
3399 _elm_widget_item_content_part_set(Elm_Widget_Item *item,
3401 Evas_Object *content)
3403 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
3404 if (!item->content_set_func) return;
3405 item->content_set_func((Elm_Object_Item *)item, part, content);
3409 _elm_widget_item_content_part_get(const Elm_Widget_Item *item,
3412 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item, NULL);
3413 if (!item->content_get_func) return NULL;
3414 return item->content_get_func((Elm_Object_Item *)item, part);
3418 _elm_widget_item_content_part_unset(Elm_Widget_Item *item,
3421 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item, NULL);
3422 if (!item->content_unset_func) return NULL;
3423 return item->content_unset_func((Elm_Object_Item *)item, part);
3427 _elm_widget_item_text_part_set(Elm_Widget_Item *item,
3431 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
3432 if (!item->text_set_func) return;
3433 item->text_set_func((Elm_Object_Item *)item, part, label);
3437 _elm_widget_item_signal_emit(Elm_Widget_Item *item,
3438 const char *emission,
3441 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
3442 if (item->signal_emit_func)
3443 item->signal_emit_func((Elm_Object_Item *)item, emission, source);
3447 _elm_widget_item_text_part_get(const Elm_Widget_Item *item,
3450 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item, NULL);
3451 if (!item->text_get_func) return NULL;
3452 return item->text_get_func((Elm_Object_Item *)item, part);
3456 _elm_widget_item_content_set_hook_set(Elm_Widget_Item *item,
3457 Elm_Widget_Content_Set_Cb func)
3459 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
3460 item->content_set_func = func;
3464 _elm_widget_item_content_get_hook_set(Elm_Widget_Item *item,
3465 Elm_Widget_Content_Get_Cb func)
3467 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
3468 item->content_get_func = func;
3472 _elm_widget_item_content_unset_hook_set(Elm_Widget_Item *item,
3473 Elm_Widget_Content_Unset_Cb func)
3475 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
3476 item->content_unset_func = func;
3480 _elm_widget_item_text_set_hook_set(Elm_Widget_Item *item,
3481 Elm_Widget_Text_Set_Cb func)
3483 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
3484 item->text_set_func = func;
3488 _elm_widget_item_text_get_hook_set(Elm_Widget_Item *item,
3489 Elm_Widget_Text_Get_Cb func)
3491 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
3492 item->text_get_func = func;
3496 _elm_widget_item_signal_emit_hook_set(Elm_Widget_Item *item,
3497 Elm_Widget_Signal_Emit_Cb func)
3499 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
3500 item->signal_emit_func = func;
3504 _elm_widget_item_access_info_set(Elm_Widget_Item *item, const char *txt)
3506 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
3507 if (item->access_info) eina_stringshare_del(item->access_info);
3508 if (!txt) item->access_info = NULL;
3509 else item->access_info = eina_stringshare_add(txt);
3513 _smart_add(Evas_Object *obj)
3517 sd = calloc(1, sizeof(Smart_Data));
3520 sd->x = sd->y = sd->w = sd->h = 0;
3521 sd->mirrored_auto_mode = EINA_TRUE; /* will follow system locale settings */
3522 evas_object_smart_data_set(obj, sd);
3523 elm_widget_can_focus_set(obj, EINA_TRUE);
3526 static Evas_Object *
3527 _newest_focus_order_get(Evas_Object *obj,
3528 unsigned int *newest_focus_order,
3529 Eina_Bool can_focus_only)
3532 Evas_Object *child, *ret, *best;
3534 API_ENTRY return NULL;
3536 if (!evas_object_visible_get(obj)
3537 || (elm_widget_disabled_get(obj))
3538 || (elm_widget_tree_unfocusable_get(obj)))
3542 if (*newest_focus_order < sd->focus_order)
3544 *newest_focus_order = sd->focus_order;
3547 EINA_LIST_FOREACH(sd->subobjs, l, child)
3549 ret = _newest_focus_order_get(child, newest_focus_order, can_focus_only);
3555 if ((!best) || (!elm_widget_can_focus_get(best)))
3562 _if_focused_revert(Evas_Object *obj,
3563 Eina_Bool can_focus_only)
3566 Evas_Object *newest = NULL;
3567 unsigned int newest_focus_order = 0;
3571 if (!sd->focused) return;
3572 if (!sd->parent_obj) return;
3574 top = elm_widget_top_get(sd->parent_obj);
3577 newest = _newest_focus_order_get(top, &newest_focus_order, can_focus_only);
3580 elm_object_focus_set(newest, EINA_FALSE);
3581 elm_object_focus_set(newest, EINA_TRUE);
3587 _smart_del(Evas_Object *obj)
3590 Edje_Signal_Data *esd;
3591 Elm_Translate_String_Data *ts;
3595 if (sd->del_pre_func) sd->del_pre_func(obj);
3598 sobj = sd->resize_obj;
3599 sd->resize_obj = NULL;
3600 evas_object_event_callback_del_full(sobj, EVAS_CALLBACK_DEL, _sub_obj_del, sd);
3601 evas_object_smart_callback_call(sd->obj, "sub-object-del", sobj);
3602 evas_object_del(sobj);
3603 sd->resize_obj = NULL;
3607 sobj = sd->hover_obj;
3608 sd->hover_obj = NULL;
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);
3612 sd->hover_obj = NULL;
3614 EINA_LIST_FREE(sd->subobjs, sobj)
3616 evas_object_event_callback_del_full(sobj, EVAS_CALLBACK_DEL, _sub_obj_del, sd);
3617 evas_object_smart_callback_call(sd->obj, "sub-object-del", sobj);
3618 evas_object_del(sobj);
3620 sd->tooltips = eina_list_free(sd->tooltips); /* should be empty anyway */
3621 sd->cursors = eina_list_free(sd->cursors); /* should be empty anyway */
3622 EINA_LIST_FREE(sd->edje_signals, esd)
3624 eina_stringshare_del(esd->emission);
3625 eina_stringshare_del(esd->source);
3628 EINA_LIST_FREE(sd->translate_strings, ts)
3630 eina_stringshare_del(ts->id);
3631 eina_stringshare_del(ts->domain);
3632 eina_stringshare_del(ts->string);
3635 sd->event_cb = eina_list_free(sd->event_cb); /* should be empty anyway */
3636 if (sd->del_func) sd->del_func(obj);
3637 if (sd->style) eina_stringshare_del(sd->style);
3638 if (sd->type) eina_stringshare_del(sd->type);
3639 if (sd->theme) elm_theme_free(sd->theme);
3641 _if_focused_revert(obj, EINA_TRUE);
3642 if (sd->access_info) eina_stringshare_del(sd->access_info);
3644 evas_object_smart_data_set(obj, NULL);
3648 _smart_move(Evas_Object *obj,
3655 _smart_reconfigure(sd);
3659 _smart_resize(Evas_Object *obj,
3666 _smart_reconfigure(sd);
3670 _smart_show(Evas_Object *obj)
3675 if ((list = evas_object_smart_members_get(obj)))
3677 EINA_LIST_FREE(list, o)
3679 if (evas_object_data_get(o, "_elm_leaveme")) continue;
3680 evas_object_show(o);
3686 _smart_hide(Evas_Object *obj)
3692 list = evas_object_smart_members_get(obj);
3693 EINA_LIST_FREE(list, o)
3695 if (evas_object_data_get(o, "_elm_leaveme")) continue;
3696 evas_object_hide(o);
3701 _smart_color_set(Evas_Object *obj,
3710 if ((list = evas_object_smart_members_get(obj)))
3712 EINA_LIST_FREE(list, o)
3714 if (evas_object_data_get(o, "_elm_leaveme")) continue;
3715 evas_object_color_set(o, r, g, b, a);
3721 _smart_clip_set(Evas_Object *obj,
3727 if ((list = evas_object_smart_members_get(obj)))
3729 EINA_LIST_FREE(list, o)
3731 if (evas_object_data_get(o, "_elm_leaveme")) continue;
3732 evas_object_clip_set(o, clip);
3738 _smart_clip_unset(Evas_Object *obj)
3743 if ((list = evas_object_smart_members_get(obj)))
3745 EINA_LIST_FREE(list, o)
3747 if (evas_object_data_get(o, "_elm_leaveme")) continue;
3748 evas_object_clip_unset(o);
3754 _smart_calculate(Evas_Object *obj)
3757 if (sd->changed_func) sd->changed_func(obj);
3761 _smart_member_add(Evas_Object *obj, Evas_Object *child)
3765 if (evas_object_data_get(child, "_elm_leaveme")) return;
3767 evas_object_color_get(obj, &r, &g, &b, &a);
3768 evas_object_color_set(child, r, g, b, a);
3770 evas_object_clip_set(child, evas_object_clip_get(obj));
3772 if (evas_object_visible_get(obj))
3773 evas_object_show(child);
3775 evas_object_hide(child);
3779 _smart_member_del(Evas_Object *obj __UNUSED__, Evas_Object *child)
3781 if (evas_object_data_get(child, "_elm_leaveme")) return;
3782 evas_object_clip_unset(child);
3785 /* never need to touch this */
3789 if (_e_smart) return;
3791 static const Evas_Smart_Class sc =
3794 EVAS_SMART_CLASS_VERSION,
3812 _e_smart = evas_smart_class_new(&sc);
3816 /* happy debug functions */
3819 _sub_obj_tree_dump(const Evas_Object *obj,
3824 for (i = 0; i < lvl * 3; i++)
3827 if (_elm_widget_is(obj))
3831 printf("+ %s(%p)\n",
3835 _sub_obj_tree_dump(sd->resize_obj, lvl + 1);
3836 EINA_LIST_FOREACH(sd->subobjs, l, obj)
3838 if (obj != sd->resize_obj)
3839 _sub_obj_tree_dump(obj, lvl + 1);
3843 printf("+ %s(%p)\n", evas_object_type_get(obj), obj);
3847 _sub_obj_tree_dot_dump(const Evas_Object *obj,
3850 if (!_elm_widget_is(obj))
3854 Eina_Bool visible = evas_object_visible_get(obj);
3855 Eina_Bool disabled = elm_widget_disabled_get(obj);
3856 Eina_Bool focused = elm_widget_focus_get(obj);
3857 Eina_Bool can_focus = elm_widget_can_focus_get(obj);
3861 fprintf(output, "\"%p\" -- \"%p\" [ color=black", sd->parent_obj, obj);
3864 fprintf(output, ", style=bold");
3867 fprintf(output, ", color=gray28");
3869 fprintf(output, " ];\n");
3872 fprintf(output, "\"%p\" [ label = \"{%p|%s|%s|visible: %d|"
3873 "disabled: %d|focused: %d/%d|focus order:%d}\"", obj, obj, sd->type,
3874 evas_object_name_get(obj), visible, disabled, focused, can_focus,
3878 fprintf(output, ", style=bold");
3881 fprintf(output, ", fontcolor=gray28");
3883 if ((disabled) || (!visible))
3884 fprintf(output, ", color=gray");
3886 fprintf(output, " ];\n");
3890 EINA_LIST_FOREACH(sd->subobjs, l, o)
3891 _sub_obj_tree_dot_dump(o, output);
3896 elm_widget_tree_dump(const Evas_Object *top)
3899 if (!_elm_widget_is(top))
3901 _sub_obj_tree_dump(top, 0);
3909 elm_widget_tree_dot_dump(const Evas_Object *top,
3913 if (!_elm_widget_is(top))
3915 fprintf(output, "graph " " { node [shape=record];\n");
3916 _sub_obj_tree_dot_dump(top, output);
3917 fprintf(output, "}\n");