2 # include "elementary_config.h"
5 #define EFL_ACCESS_OBJECT_PROTECTED
6 #define EFL_ACCESS_COMPONENT_PROTECTED
7 #define EFL_ACCESS_WIDGET_ACTION_PROTECTED
8 #define ELM_WIDGET_PROTECTED
9 #define ELM_WIDGET_ITEM_PROTECTED
10 #define EFL_INPUT_EVENT_PROTECTED
11 #define EFL_UI_L10N_PROTECTED
12 #define EFL_UI_FOCUS_OBJECT_PROTECTED
13 #define EFL_UI_WIDGET_PART_BG_PROTECTED
14 #define EFL_PART_PROTECTED
16 #include <Elementary.h>
19 #include "elm_widget_container.h"
20 #include "elm_interface_scrollable.h"
21 #include "elm_pan_eo.h"
22 #include "elm_part_helper.h"
23 #include "elm_widget_combobox.h"
25 #define MY_CLASS EFL_UI_WIDGET_CLASS
27 #define MY_CLASS_NAME "Efl_Ui_Widget"
28 #define MY_CLASS_NAME_LEGACY "elm_widget"
31 Elm_Widget_Smart_Data *sd = NULL; \
32 if (!_elm_widget_is(obj) || \
33 (!(sd = efl_data_scope_get(obj, MY_CLASS))))
35 #define INTERNAL_ENTRY \
36 ELM_WIDGET_DATA_GET(obj, sd); \
39 #define ELM_WIDGET_FOCUS_GET(obj) \
40 (efl_isa(obj, EFL_UI_WIDGET_CLASS) && \
41 ((_elm_access_auto_highlight_get()) ? (elm_widget_highlight_get(obj)) : \
42 (efl_ui_focus_object_focus_get(obj))))
44 const char SIG_WIDGET_FOCUSED[] = "focused";
45 const char SIG_WIDGET_UNFOCUSED[] = "unfocused";
46 const char SIG_WIDGET_LANG_CHANGED[] = "language,changed";
47 const char SIG_WIDGET_ACCESS_CHANGED[] = "access,changed";
49 // TIZEN_ONLY(20161018): add highlighted/unhighlighted signal for atspi
50 const char SIG_WIDGET_ATSPI_HIGHLIGHTED[] = "atspi,highlighted";
51 const char SIG_WIDGET_ATSPI_UNHIGHLIGHTED[] = "atspi,unhighlighted";
53 typedef struct _Elm_Event_Cb_Data Elm_Event_Cb_Data;
54 typedef struct _Elm_Label_Data Elm_Label_Data;
55 typedef struct _Elm_Translate_String_Data Elm_Translate_String_Data;
57 static Eina_Error _efl_ui_property_bind(Eo *widget, Eo *target, Efl_Ui_Widget_Data *pd,
59 const char *key, const char *property);
61 struct _Elm_Event_Cb_Data
67 struct _Elm_Label_Data
73 struct _Elm_Translate_String_Data
77 Eina_Stringshare *domain;
78 Eina_Stringshare *string;
82 // TIZEN_ONLY PROTOTYPES
83 static void _efl_ui_widget_efl_canvas_object_paragraph_direction_set_internal(Eo *obj EINA_UNUSED, Efl_Ui_Widget_Data *sd, Efl_Text_Bidirectional_Type dir); // TIZEN_ONLY(20180117): Override Paragraph Direction APIs
84 static void _if_focused_revert(Evas_Object *obj, Eina_Bool can_focus_only); //TIZEN_ONLY(20180607): Restore legacy focus
86 static void _on_sub_obj_hide(void *data, const Efl_Event *event);
88 static inline Eina_Bool _elm_widget_focus_chain_manager_is(const Evas_Object *obj);
89 static inline Eina_Bool _internal_elm_widget_focus_direction_manager_is(const Evas_Object *obj);
90 static void _parent_focus(Evas_Object *obj, Elm_Object_Item *item);
91 static void _elm_object_focus_chain_del_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED);
93 static Eina_List *_lines_split(Eina_List *children);
94 static int _sort_vertically(const void *data1, const void *data2);
95 static int _sort_horizontally(const void *data1, const void *data2);
97 Eo * plug_type_proxy_get(const Eo *obj, Evas_Object *widget);
99 // TIZEN_ONLY(20200623) : apply Tizen's color_class features
100 static Eina_Bool _elm_widget_color_class_update(Eo *obj, Elm_Widget_Smart_Data *sd);
103 static Eina_Bool _elm_widget_can_highlight_get_by_class(Eo *obj);
104 static Eina_Bool _accessible_object_on_scroll_is(Eo* obj);
110 /* For keeping backward compatibility (EFL 1.18 or older versions).
111 * Since EFL 1.19 which starts to use eolian_gen2, it does not convert
112 * "." to "_" among the class name. */
113 static const char *legacy_type_table[][2] =
115 { "Efl.Ui.Bg_Legacy", "Elm_Bg" },
116 { "Efl.Ui.Button_Legacy", "Elm_Button" },
117 { "Efl.Ui.Check_Legacy", "Elm_Check" },
118 { "Efl.Ui.Clock_Legacy", "Elm_Datetime" },
119 { "Efl.Ui.Flip_Legacy", "Elm_Flip" },
120 { "Efl.Ui.Frame_Legacy", "Elm_Frame" },
121 { "Efl.Ui.Image_Legacy", "Elm_Image" },
122 { "Efl.Ui.Image_Zoomable_Legacy", "Elm_Photocam" },
123 { "Efl.Ui.Layout_Legacy", "Elm_Layout" },
124 { "Efl.Ui.Panes_Legacy", "Elm_Panes" },
125 { "Efl.Ui.Progressbar_Legacy", "Elm_Progressbar" },
126 { "Efl.Ui.Radio_Legacy", "Elm_Radio" },
127 { "Efl.Ui.Video_Legacy", "Elm_Video" },
128 { "Efl.Ui.Win_Legacy", "Elm_Win" },
129 { "Efl.Ui.Win_Socket_Legacy", "Elm_Win" },
130 { "Efl.Ui.Win_Inlined_Legacy", "Elm_Win" },
131 { "Elm.Code_Widget_Legacy", "Elm_Code_Widget" },
132 { "Elm.Ctxpopup", "Elm_Ctxpopup" },
133 { "Elm.Entry", "Elm_Entry" },
134 { "Elm.Colorselector", "Elm_Colorselector" },
135 { "Elm.List", "Elm_List" },
136 { "Elm.Photo", "Elm_Photo" },
137 { "Elm.Actionslider", "Elm_Actionslider" },
138 { "Elm.Box", "Elm_Box" },
139 { "Elm.Table", "Elm_Table" },
140 { "Elm.Thumb", "Elm_Thumb" },
141 { "Elm.Menu", "Elm_Menu" },
142 { "Elm.Icon", "Elm_Icon" },
143 { "Elm.Prefs", "Elm_Prefs" },
144 { "Elm.Map", "Elm_Map" },
145 { "Elm.Glview", "Elm_Glview" },
146 { "Elm.Web", "Elm_Web" },
147 { "Elm.Toolbar", "Elm_Toolbar" },
148 { "Elm.Grid", "Elm_Grid" },
149 { "Elm.Diskselector", "Elm_Diskselector" },
150 { "Elm.Notify", "Elm_Notify" },
151 { "Elm.Mapbuf", "Elm_Mapbuf" },
152 { "Elm.Separator", "Elm_Separator" },
153 { "Elm.Calendar", "Elm_Calendar" },
154 { "Elm.Inwin", "Elm_Inwin" },
155 { "Elm.Gengrid", "Elm_Gengrid" },
156 { "Elm.Scroller", "Elm_Scroller" },
157 { "Elm.Player", "Elm_Player" },
158 { "Elm.Segment_Control", "Elm_Segment_Control" },
159 { "Elm.Fileselector", "Elm_Fileselector" },
160 { "Elm.Fileselector_Button", "Elm_Fileselector_Button" },
161 { "Elm.Fileselector_Entry", "Elm_Fileselector_Entry" },
162 { "Elm.Flipselector", "Elm_Flipselector" },
163 { "Elm.Hoversel", "Elm_Hoversel" },
164 { "Elm.Naviframe", "Elm_Naviframe" },
165 { "Elm.Popup", "Elm_Popup" },
166 { "Elm.Bubble", "Elm_Bubble" },
167 { "Elm.Clock", "Elm_Clock" },
168 { "Elm.Conformant", "Elm_Conformant" },
169 { "Elm.Dayselector", "Elm_Dayselector" },
170 { "Elm.Genlist", "Elm_Genlist" },
171 { "Elm.Hover", "Elm_Hover" },
172 { "Elm.Index", "Elm_Index" },
173 { "Elm.Label", "Elm_Label" },
174 { "Elm.Panel", "Elm_Panel" },
175 { "Elm.Slider", "Elm_Slider" },
176 { "Elm.Slideshow", "Elm_Slideshow" },
177 { "Elm.Spinner", "Elm_Spinner" },
178 { "Elm.Plug", "Elm_Plug" },
179 { "Elm.Web.None", "Elm_Web" },
180 { "Elm.Multibuttonentry", "Elm_Multibuttonentry" },
181 /* TIZEN_ONLY(20180423): add additional class names for legacy API calls */
182 { "Efl.Ui.Bg", "Elm_Bg" },
183 { "Efl.Ui.Button", "Elm_Button" },
184 { "Efl.Ui.Check", "Elm_Check" },
185 { "Efl.Ui.Clock", "Elm_Datetime" },
186 { "Efl.Ui.Flip", "Elm_Flip" },
187 { "Efl.Ui.Frame", "Elm_Frame" },
188 { "Efl.Ui.Image", "Elm_Image" },
189 { "Efl.Ui.Image_Zoomable", "Elm_Photocam" },
190 { "Efl.Ui.Layout", "Elm_Layout" },
191 { "Efl.Ui.Multibuttonentry", "Elm_Multibuttonentry" },
192 { "Efl.Ui.Panes", "Elm_Panes" },
193 { "Efl.Ui.Progressbar", "Elm_Progressbar" },
194 { "Efl.Ui.Radio", "Elm_Radio" },
195 { "Efl.Ui.Slider", "Elm_Slider" },
196 { "Efl.Ui.Video", "Elm_Video" },
197 { "Efl.Ui.Win", "Elm_Win" },
198 { "Elm.Code_Widget", "Elm_Code_Widget" },
199 { "Elm.Gesture_Layer", "Elm_Gesture_Layer" },
201 /* TIZEN_ONLY(20180504): add missing item class names and fix edje_class parse rule for legacy */
202 { "Elm.Naviframe.Item", "Elm_Naviframe_Item" },
203 { "Elm.Genlist.Item", "Elm_Genlist_Item" },
204 { "Elm.Gengrid.Item", "Elm_Gengrid_Item" },
205 { "Elm.Toolbar_Item", "Elm_Toolbar_Item" },
206 { "Elm.Multibuttonentry_Item", "Elm_Multibuttonentry_Item" },
207 { "Elm.Ctxpopup.Item", "Elm_Ctxpopup_Item" },
208 { "Elm.Hoversel.Item", "Elm_Hoversel_Item" },
209 { "Elm.Index.Item", "Elm_Index_Item" },
210 { "Elm.Popup.Item", "Elm_Popup_Item" },
211 { "Elm.List.Item", "Elm_List_Item" },
212 { "Elm.Color.Item", "Elm_Color_Item" },
217 //TIZEN_ONLY(20180607): Restore legacy focus
218 static unsigned int focus_order = 0;
221 /* local subsystem globals */
222 static inline Eina_Bool
223 _elm_widget_is(const Evas_Object *obj)
225 return efl_isa(obj, MY_CLASS);
228 static inline Eina_Bool
229 _is_focusable(Evas_Object *obj)
231 API_ENTRY return EINA_FALSE;
232 //TIZEN_ONLY(20190312): Restore child_can_focus
233 //return sd->can_focus || (sd->logical.child_count > 0);
234 return sd->can_focus || (sd->child_can_focus);
238 static inline Eina_Bool
239 _is_focused(Evas_Object *obj)
241 API_ENTRY return EINA_FALSE;
245 static inline Eina_Bool
246 _elm_scrollable_is(const Evas_Object *obj)
248 INTERNAL_ENTRY EINA_FALSE;
249 if (elm_widget_is_legacy(obj))
251 efl_isa(obj, ELM_INTERFACE_SCROLLABLE_MIXIN);
254 efl_isa(obj, EFL_UI_SCROLLABLE_INTERFACE);
258 _on_sub_obj_del(void *data, const Efl_Event *event);
259 static void _propagate_event(void *data, const Efl_Event *eo_event);
260 static void _elm_widget_shadow_update(Efl_Ui_Widget *obj);
262 EFL_CALLBACKS_ARRAY_DEFINE(elm_widget_subitems_callbacks,
263 //TIZEN_ONLY(20180607): Restore legacy focus
264 { EFL_GFX_ENTITY_EVENT_VISIBILITY_CHANGED, _on_sub_obj_hide });
266 EFL_CALLBACKS_ARRAY_DEFINE(efl_subitems_callbacks,
267 { EFL_EVENT_DEL, _on_sub_obj_del });
268 EFL_CALLBACKS_ARRAY_DEFINE(focus_callbacks,
269 { EFL_EVENT_KEY_DOWN, _propagate_event },
270 { EFL_EVENT_KEY_UP, _propagate_event },
271 { EFL_EVENT_POINTER_WHEEL, _propagate_event });
274 _callbacks_add(Eo *widget, void *data)
276 efl_event_callback_array_add(widget, efl_subitems_callbacks(), data);
280 _callbacks_del(Eo *widget, void *data)
282 efl_event_callback_array_del(widget, efl_subitems_callbacks(), data);
286 _elm_widget_item_highlight_in_theme(Evas_Object *obj, Elm_Object_Item *eo_it)
291 if (efl_isa(eo_it, ELM_WIDGET_ITEM_CLASS))
293 Elm_Widget_Item_Data *it = efl_data_scope_get(eo_it, ELM_WIDGET_ITEM_CLASS);
295 if (efl_isa(it->view, EFL_UI_LAYOUT_BASE_CLASS))
296 str = edje_object_data_get(elm_layout_edje_get(it->view), "focus_highlight");
298 str = edje_object_data_get(it->view, "focus_highlight");
301 str = edje_object_data_get(((Elm_Widget_Item_Data *)eo_it)->view, "focus_highlight");
302 if ((str) && (!strcmp(str, "on")))
303 elm_widget_highlight_in_theme_set(obj, EINA_TRUE);
305 elm_widget_highlight_in_theme_set(obj, EINA_FALSE);
309 _elm_widget_focus_highlight_start(const Evas_Object *obj)
311 Evas_Object *top = efl_provider_find(obj, EFL_UI_WIN_CLASS);
313 EINA_SAFETY_ON_FALSE_RETURN(efl_isa(top, EFL_UI_WIN_CLASS));
315 _elm_win_focus_highlight_start(top);
319 _efl_ui_widget_focus_highlight_object_get(const Evas_Object *obj)
321 Evas_Object *top = efl_provider_find(obj, EFL_UI_WIN_CLASS);
323 EINA_SAFETY_ON_FALSE_RETURN_VAL(efl_isa(top, EFL_UI_WIN_CLASS), NULL);
325 return _elm_win_focus_highlight_object_get(top);
328 //TIZEN_ONLY(20200217): comment out unused function
331 _legacy_focus_eval(Eo *obj)
334 Efl_Ui_Widget *wid = obj, *top;
335 Elm_Widget_Smart_Data *wid_pd;
337 wid_pd = efl_data_scope_get(wid, MY_CLASS);
342 wid = elm_widget_parent_get(wid);
344 wid_pd = efl_data_scope_get(wid, MY_CLASS);
346 lst = wid_pd->legacy_focus.custom_chain;
349 if (!eina_list_data_find(lst, top))
351 WRN("Widget %p disabled due to custom chain of %p", top, wid);
358 return !efl_isa(top, EFL_UI_WIN_CLASS);
362 static void _full_eval(Eo *obj, Elm_Widget_Smart_Data *pd);
363 //TIZEN_ONLY(20200217): comment out unused function
365 static Efl_Ui_Focus_Object*
366 _focus_manager_eval(Eo *obj, Elm_Widget_Smart_Data *pd)
368 Evas_Object *provider = NULL;
370 Efl_Ui_Focus_Manager *new = NULL, *old = NULL;
372 parent = elm_widget_parent_get(obj);
373 if (efl_isa(parent, EFL_UI_FOCUS_MANAGER_INTERFACE))
379 new = efl_ui_focus_object_focus_manager_get(parent);
383 if (new != pd->manager.manager)
385 old = pd->manager.manager;
387 pd->manager.manager = new;
388 pd->manager.provider = provider;
395 EOLIAN static Eina_Bool
396 _efl_ui_widget_focus_state_apply(Eo *obj, Elm_Widget_Smart_Data *pd EINA_UNUSED, Efl_Ui_Widget_Focus_State current_state, Efl_Ui_Widget_Focus_State *configured_state, Efl_Ui_Widget *redirect)
398 Eina_Bool registered = EINA_TRUE;
400 //shortcut for having the same configurations
401 if (current_state.manager == configured_state->manager && !current_state.manager)
402 return !!current_state.manager;
404 if (configured_state->logical == current_state.logical &&
405 configured_state->manager == current_state.manager &&
406 configured_state->parent == current_state.parent)
407 return !!current_state.manager;
409 //this thing doesnt want to be registered, but it is ...
410 if (!configured_state->manager && current_state.manager)
412 efl_ui_focus_manager_calc_unregister(current_state.manager, obj);
415 //by that point we have always a configured manager
417 if (!current_state.manager) registered = EINA_FALSE;
419 if ((//check if we have changed the manager
420 (current_state.manager != configured_state->manager) ||
421 //check if we are already registered but in a different state
422 (current_state.logical != configured_state->logical))
425 //we need to unregister here
426 efl_ui_focus_manager_calc_unregister(current_state.manager, obj);
427 registered = EINA_FALSE;
430 //the parent may has changed
431 if (current_state.parent != configured_state->parent && registered)
433 return efl_ui_focus_manager_calc_update_parent(current_state.manager, obj, configured_state->parent);
438 if (configured_state->logical)
439 return efl_ui_focus_manager_calc_register_logical(configured_state->manager, obj, configured_state->parent, redirect);
441 return efl_ui_focus_manager_calc_register(configured_state->manager, obj, configured_state->parent, redirect);
443 ERR("Uncaught focus state consider this as unregistered (%d) \n (%p,%p,%d) \n (%p,%p,%d) ", registered,
444 configured_state->manager, configured_state->parent, configured_state->logical,
445 current_state.manager, current_state.parent, current_state.logical
449 //TIZEN_ONLY(20200217): comment out unused function
452 _eval_registration_candidate(Eo *obj, Elm_Widget_Smart_Data *pd, Eina_Bool *should, Eina_Bool *want_full)
454 *should = *want_full = EINA_FALSE;
456 //can focus can be overridden by the following properties
457 if ((!pd->parent_obj) ||
458 (!evas_object_visible_get(obj)) ||
460 pd->tree_unfocusable > 0)
463 if (!pd->shared_win_data || ((Efl_Ui_Shared_Win_Data*)pd->shared_win_data)->legacy_focus_api_used)
465 if (_legacy_focus_eval(obj))
471 *should = *want_full = EINA_TRUE;
473 else if (pd->logical.child_count > 0)
480 _focus_state_eval(Eo *obj, Elm_Widget_Smart_Data *pd, Eina_Bool should, Eina_Bool want_full)
482 Efl_Ui_Widget_Focus_State configuration;
484 //this would mean we are registering again the root, we dont want that
485 if (pd->manager.manager == obj) return;
487 //there are two reasons to be registered, the child count is bigger than 0, or the widget is flagged to be able to handle focus
490 configuration.parent = pd->logical.parent;
491 configuration.manager = pd->manager.manager;
492 configuration.logical = !want_full;
496 configuration.parent = NULL;
497 configuration.manager = NULL;
498 configuration.logical = EINA_FALSE;
501 if (!efl_ui_widget_focus_state_apply(obj, pd->focus, &configuration, NULL))
503 //things went wrong or this thing is unregistered. Purge the current configuration.
504 pd->focus.manager = NULL;
505 pd->focus.parent = NULL;
506 pd->focus.logical = EINA_FALSE;
510 pd->focus.parent = configuration.parent;
511 pd->focus.manager = configuration.manager;
512 pd->focus.logical = configuration.logical;
517 static Efl_Ui_Focus_Object*
518 _logical_parent_eval(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *pd, Eina_Bool should, Eina_Bool *state_change_to_parent)
520 Efl_Ui_Widget *parent;
521 Efl_Ui_Focus_Parent_Provider *provider;
523 if (!pd->shared_win_data || ((Efl_Ui_Shared_Win_Data*)pd->shared_win_data)->custom_parent_provider)
527 provider = efl_provider_find(obj, EFL_UI_FOCUS_PARENT_PROVIDER_INTERFACE);
528 EINA_SAFETY_ON_NULL_RETURN_VAL(provider, NULL);
529 parent = efl_ui_focus_parent_provider_find_logical_parent(provider, obj);
536 parent = efl_ui_widget_parent_get(obj);
540 if (pd->logical.parent != parent)
542 Efl_Ui_Focus_Object *old = NULL;
544 //update old logical parent;
545 if (pd->logical.parent)
547 if (efl_isa(pd->logical.parent, EFL_UI_WIDGET_CLASS))
549 ELM_WIDGET_DATA_GET_OR_RETURN(pd->logical.parent, logical_wd, NULL);
550 logical_wd->logical.child_count --;
551 if (logical_wd->logical.child_count == 0)
553 *state_change_to_parent = EINA_TRUE;
556 old = pd->logical.parent;
557 efl_weak_unref(&pd->logical.parent);
558 pd->logical.parent = NULL;
562 if (efl_isa(parent, EFL_UI_WIDGET_CLASS))
564 ELM_WIDGET_DATA_GET_OR_RETURN(parent, parent_wd, NULL);
565 parent_wd->logical.child_count ++;
566 if (parent_wd->logical.child_count == 1)
568 *state_change_to_parent = EINA_TRUE;
571 pd->logical.parent = parent;
572 efl_weak_ref(&pd->logical.parent);
581 //TIZEN_ONLY(20200220): add EINA_UNUSED for unused parameters
582 _full_eval(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *pd EINA_UNUSED)
583 //_full_eval(Eo *obj, Elm_Widget_Smart_Data *pd)
586 //TIZEN_ONLY(20180607): Restore legacy focus
589 Efl_Ui_Focus_Object *old_parent;
590 Efl_Ui_Focus_Object *old_registered_parent, *old_registered_manager;
591 Eina_Bool should, want_full, state_change_to_parent = EINA_FALSE;
593 _eval_registration_candidate(obj, pd, &should, &want_full);
595 old_parent = _logical_parent_eval(obj, pd, should, &state_change_to_parent);
597 if (state_change_to_parent)
599 if (efl_isa(old_parent, EFL_UI_WIDGET_CLASS))
601 //emit signal and focus eval old and new
602 ELM_WIDGET_DATA_GET(old_parent, old_pd);
603 if (old_pd) _full_eval(old_parent, old_pd);
606 if (efl_isa(pd->logical.parent, EFL_UI_WIDGET_CLASS))
608 ELM_WIDGET_DATA_GET(pd->logical.parent, new_pd);
609 if (new_pd) _full_eval(pd->logical.parent, new_pd);
614 _focus_manager_eval(obj, pd);
616 old_registered_parent = pd->focus.parent;
617 old_registered_manager = pd->focus.manager;
619 _focus_state_eval(obj, pd, should, want_full);
621 if (old_registered_parent != pd->focus.parent)
623 efl_event_callback_call(obj,
624 EFL_UI_FOCUS_OBJECT_EVENT_FOCUS_PARENT_CHANGED, old_registered_parent);
627 if (old_registered_manager != pd->focus.manager)
629 _elm_widget_full_eval_children(obj, pd);
630 efl_event_callback_call(obj,
631 EFL_UI_FOCUS_OBJECT_EVENT_FOCUS_MANAGER_CHANGED, old_registered_manager);
639 _elm_widget_full_eval(Eo *obj)
641 ELM_WIDGET_DATA_GET(obj, pd);
642 if (pd) _full_eval(obj, pd);
648 * Resets the mirrored mode from the system mirror mode for widgets that are in
649 * automatic mirroring mode. This function does not call elm_widget_theme.
651 * @param obj The widget.
652 * @param mirrored EINA_TRUE to set mirrored mode. EINA_FALSE to unset.
655 _elm_widget_mirrored_reload(Evas_Object *obj)
658 Eina_Bool mirrored = elm_config_mirrored_get();
660 if (efl_ui_mirrored_automatic_get(obj) && (sd->is_mirrored != mirrored))
662 sd->is_mirrored = mirrored;
667 _parents_focus(Evas_Object *obj)
669 for (; obj; obj = elm_widget_parent_get(obj))
672 if (sd->focused) return;
678 _parents_unfocus(Evas_Object *obj)
680 for (; obj; obj = elm_widget_parent_get(obj))
683 if (!sd->focused) return;
687 //TIZEN_ONLY(20180607): Restore legacy focus
689 _on_sub_obj_hide(void *data EINA_UNUSED, const Efl_Event *event)
691 Eina_Bool *visible = event->info;
692 if ((*visible) == EINA_FALSE)
693 efl_ui_widget_focus_hide_handle(event->object);
697 _on_sub_obj_del(void *data, const Efl_Event *event)
699 ELM_WIDGET_DATA_GET_OR_RETURN(data, sd);
701 if (_elm_widget_is(event->object))
703 if (_is_focused(event->object)) _parents_unfocus(data);
705 if (event->object == sd->resize_obj)
707 /* already dels sub object */
708 elm_widget_resize_object_set(data, NULL);
710 else if (event->object == sd->hover_obj)
712 sd->hover_obj = NULL;
716 if (!elm_widget_sub_object_del(data, event->object))
717 ERR("failed to remove sub object %p from %p\n", event->object, data);
721 static const Evas_Smart_Cb_Description _smart_callbacks[] =
723 {SIG_WIDGET_FOCUSED, ""},
724 {SIG_WIDGET_UNFOCUSED, ""},
725 {SIG_WIDGET_LANG_CHANGED, ""},
726 {SIG_WIDGET_ACCESS_CHANGED, ""},
727 // TIZEN_ONLY(20161018): add highlighted/unhighlighted signal for atspi
728 {SIG_WIDGET_ATSPI_HIGHLIGHTED, ""},
729 {SIG_WIDGET_ATSPI_UNHIGHLIGHTED, ""},
735 _obj_mouse_down(void *data,
737 Evas_Object *obj EINA_UNUSED,
742 ELM_WIDGET_DATA_GET(data, sd);
744 Evas_Event_Mouse_Down *ev = event_info;
745 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return;
747 top = elm_widget_top_get(data);
748 if (top && efl_isa(top, EFL_UI_WIN_CLASS)) _elm_win_focus_auto_hide(top);
749 sd->still_in = EINA_TRUE;
753 _obj_mouse_move(void *data,
758 ELM_WIDGET_DATA_GET(data, sd);
760 Evas_Event_Mouse_Move *ev = event_info;
761 if (!sd->still_in) return;
763 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD)
764 sd->still_in = EINA_FALSE;
767 Evas_Coord x, y, w, h;
768 evas_object_geometry_get(obj, &x, &y, &w, &h);
769 if (ELM_RECTS_POINT_OUT(x, y, w, h, ev->cur.canvas.x, ev->cur.canvas.y))
770 sd->still_in = EINA_FALSE;
775 _obj_mouse_up(void *data,
780 ELM_WIDGET_DATA_GET(data, sd);
782 Evas_Event_Mouse_Up *ev = event_info;
784 if (sd->still_in && (ev->flags == EVAS_BUTTON_NONE) &&
785 (sd->focus_move_policy == ELM_FOCUS_MOVE_POLICY_CLICK) &&
786 !efl_invalidated_get(data))
787 elm_widget_focus_mouse_up_handle(evas_object_widget_parent_find(obj));
789 sd->still_in = EINA_FALSE;
793 _obj_mouse_in(void *data,
796 void *event_info EINA_UNUSED)
798 ELM_WIDGET_DATA_GET(data, sd);
800 if (sd->focus_move_policy == ELM_FOCUS_MOVE_POLICY_IN &&
801 !efl_invalidated_get(data))
802 elm_widget_focus_mouse_up_handle(evas_object_widget_parent_find(obj));
806 _efl_ui_widget_efl_canvas_group_group_add(Eo *obj, Elm_Widget_Smart_Data *priv)
808 priv->mirrored_auto_mode = EINA_TRUE; /* will follow system locale
810 priv->focus_move_policy_auto_mode = EINA_TRUE;
811 priv->focus_region_show_mode = ELM_FOCUS_REGION_SHOW_WIDGET;
812 elm_widget_can_focus_set(obj, EINA_TRUE);
813 priv->is_mirrored = elm_config_mirrored_get();
814 priv->focus_move_policy = _elm_config->focus_move_policy;
816 evas_object_event_callback_add(obj, EVAS_CALLBACK_MOUSE_DOWN,
817 _obj_mouse_down, obj);
818 evas_object_event_callback_add(obj, EVAS_CALLBACK_MOUSE_MOVE,
819 _obj_mouse_move, obj);
820 evas_object_event_callback_add(obj, EVAS_CALLBACK_MOUSE_UP,
822 evas_object_event_callback_add(obj, EVAS_CALLBACK_MOUSE_IN,
827 _keep(void *data, void *gdata)
835 _efl_ui_widget_efl_canvas_group_group_del(Eo *obj, Elm_Widget_Smart_Data *sd)
838 Elm_Translate_String_Data *ts;
839 Elm_Event_Cb_Data *ecb;
843 /* detach it from us */
844 _callbacks_del(sd->hover_obj, obj);
845 sd->hover_obj = NULL;
847 while(eina_array_count(sd->children))
849 sobj = eina_array_data_get(sd->children, 0);
851 if (!elm_widget_sub_object_del(obj, sobj))
853 ERR("failed to remove sub object %p from %p\n", sobj, obj);
854 eina_array_remove(sd->children, _keep, sobj);
856 // FIXME: is that a legacy or a new object ?
857 evas_object_del(sobj);
858 EINA_SAFETY_ON_TRUE_RETURN(eina_array_count(sd->children) && sobj == eina_array_data_get(sd->children, 0));
860 sd->tooltips = eina_list_free(sd->tooltips); /* should be empty anyway */
861 sd->cursors = eina_list_free(sd->cursors); /* should be empty anyway */
862 while (sd->translate_strings)
864 ts = EINA_INLIST_CONTAINER_GET(sd->translate_strings,
865 Elm_Translate_String_Data);
866 eina_stringshare_del(ts->id);
867 eina_stringshare_del(ts->domain);
868 eina_stringshare_del(ts->string);
869 sd->translate_strings = eina_inlist_remove(sd->translate_strings,
870 sd->translate_strings);
874 EINA_LIST_FREE(sd->event_cb, ecb)
877 eina_stringshare_del(sd->klass);
878 eina_stringshare_del(sd->group);
879 eina_stringshare_del(sd->style);
880 if (sd->theme) elm_theme_free(sd->theme);
881 //TIZEN_ONLY(20180607): Restore legacy focus
882 _if_focused_revert(obj, EINA_TRUE);
883 efl_ui_widget_focus_custom_chain_unset(obj);
885 eina_stringshare_del(sd->access_info);
886 eina_stringshare_del(sd->accessible_name);
887 evas_object_smart_data_set(obj, NULL);
888 efl_canvas_group_del(efl_super(obj, MY_CLASS));
892 _smart_reconfigure(Eo *obj, Elm_Widget_Smart_Data *sd)
894 Eina_Rect geom = efl_gfx_entity_geometry_get(obj);
898 efl_gfx_entity_geometry_set(sd->resize_obj, geom);
902 efl_gfx_entity_geometry_set(sd->hover_obj, geom);
906 efl_gfx_entity_geometry_set(sd->bg, geom);
909 _elm_widget_shadow_update(obj);
913 _efl_ui_widget_efl_gfx_entity_position_set(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd, Eina_Position2D pos)
915 if (_evas_object_intercept_call(obj, EVAS_OBJECT_INTERCEPT_CB_MOVE, 0, pos.x, pos.y))
919 efl_gfx_entity_position_set(sd->resize_obj, pos);
921 efl_gfx_entity_position_set(sd->hover_obj, pos);
923 efl_gfx_entity_position_set(sd->bg, pos);
926 _elm_widget_shadow_update(obj);
928 efl_gfx_entity_position_set(efl_super(obj, MY_CLASS), pos);
932 _efl_ui_widget_efl_gfx_entity_size_set(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd, Eina_Size2D sz)
934 if (_evas_object_intercept_call(obj, EVAS_OBJECT_INTERCEPT_CB_RESIZE, 0, sz.w, sz.h))
938 efl_gfx_entity_size_set(sd->resize_obj, sz);
940 efl_gfx_entity_size_set(sd->hover_obj, sz);
942 efl_gfx_entity_size_set(sd->bg, sz);
945 _elm_widget_shadow_update(obj);
947 efl_gfx_entity_size_set(efl_super(obj, MY_CLASS), sz);
951 //TIZEN_ONLY(20200220): add EINA_UNUSED for unused parameters
952 _elm_widget_full_eval_children(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd EINA_UNUSED)
953 //_elm_widget_full_eval_children(Eo *obj, Elm_Widget_Smart_Data *sd)
956 //TIZEN_ONLY(20180607): Restore legacy focus
963 for (unsigned int i = 0; i < eina_array_count(sd->children); ++i)
965 Elm_Widget_Smart_Data *sd_child;
966 child = eina_array_data_get(sd->children, i);
968 if (!efl_isa(child, EFL_UI_WIDGET_CLASS)) continue;
970 sd_child = efl_data_scope_get(child, EFL_UI_WIDGET_CLASS);
971 _elm_widget_full_eval_children(child, sd_child);
978 _efl_ui_widget_efl_gfx_entity_visible_set(Eo *obj, Elm_Widget_Smart_Data *pd, Eina_Bool vis)
983 if (_evas_object_intercept_call(obj, EVAS_OBJECT_INTERCEPT_CB_VISIBLE, 0, vis))
985 _elm_widget_full_eval_children(obj, pd);
989 efl_gfx_entity_visible_set(efl_super(obj, MY_CLASS), vis);
991 _elm_widget_full_eval_children(obj, pd);
994 it = evas_object_smart_iterator_new(obj);
995 EINA_ITERATOR_FOREACH(it, o)
997 if (evas_object_data_get(o, "_elm_leaveme")) continue;
998 efl_gfx_entity_visible_set(o, vis);
1000 eina_iterator_free(it);
1002 if (!_elm_atspi_enabled() || pd->on_destroy)
1007 efl_access_added(obj);
1008 if (_elm_widget_onscreen_is(obj))
1009 efl_access_state_changed_signal_emit(obj, EFL_ACCESS_STATE_TYPE_SHOWING, EINA_TRUE);
1013 //TIZEN_ONLY(20161223) check if the parent of highlighted object is hide
1014 Eo *highlighted_obj;
1015 highlighted_obj = _elm_object_accessibility_currently_highlighted_get();
1016 if (highlighted_obj && highlighted_obj != obj)
1019 parent = efl_provider_find(efl_parent_get(highlighted_obj), EFL_ACCESS_OBJECT_MIXIN);
1024 efl_access_state_changed_signal_emit(highlighted_obj, EFL_ACCESS_STATE_TYPE_SHOWING, EINA_FALSE);
1025 efl_access_component_highlight_clear(highlighted_obj);
1028 parent = efl_provider_find(efl_parent_get(parent), EFL_ACCESS_OBJECT_MIXIN);
1032 efl_access_state_changed_signal_emit(obj, EFL_ACCESS_STATE_TYPE_SHOWING, EINA_FALSE);
1037 _efl_ui_widget_efl_gfx_color_color_set(Eo *obj, Elm_Widget_Smart_Data *pd, int r, int g, int b, int a)
1042 if (_evas_object_intercept_call(obj, EVAS_OBJECT_INTERCEPT_CB_COLOR_SET, 0, r, g, b, a))
1045 efl_gfx_color_set(efl_super(obj, MY_CLASS), r, g, b, a);
1047 it = evas_object_smart_iterator_new(obj);
1048 EINA_ITERATOR_FOREACH(it, o)
1050 if (pd->bg == o) continue;
1051 if (evas_object_data_get(o, "_elm_leaveme")) continue;
1052 evas_object_color_set(o, r, g, b, a);
1054 eina_iterator_free(it);
1058 _efl_ui_widget_efl_canvas_object_no_render_set(Eo *obj, Elm_Widget_Smart_Data *_pd EINA_UNUSED, Eina_Bool hide)
1064 if (efl_canvas_object_no_render_get(obj) == hide)
1067 it = evas_object_smart_iterator_new(obj);
1068 EINA_ITERATOR_FOREACH(it, o)
1070 if (evas_object_data_get(o, "_elm_leaveme")) continue;
1071 efl_canvas_object_no_render_set(o, hide);
1073 eina_iterator_free(it);
1075 // bypass implementation in Efl.Canvas.Group
1076 efl_canvas_object_no_render_set(efl_super(obj, EFL_CANVAS_GROUP_CLASS), hide);
1080 _efl_ui_widget_efl_canvas_object_is_frame_object_set(Eo *obj, Elm_Widget_Smart_Data *pd, Eina_Bool frame)
1085 efl_canvas_object_is_frame_object_set(efl_super(obj, MY_CLASS), frame);
1086 for (unsigned int i = 0; i < eina_array_count(pd->children); ++i)
1088 o = eina_array_data_get(pd->children, i);
1090 if (evas_object_data_get(o, "_elm_leaveme")) continue;
1091 efl_canvas_object_is_frame_object_set(o, frame);
1096 _efl_ui_widget_efl_canvas_object_clipper_set(Eo *obj, Elm_Widget_Smart_Data *_pd EINA_UNUSED, Evas_Object *clip)
1101 if (_evas_object_intercept_call(obj, EVAS_OBJECT_INTERCEPT_CB_CLIP_SET, 0, clip))
1104 efl_canvas_object_clipper_set(efl_super(obj, MY_CLASS), clip);
1106 it = evas_object_smart_iterator_new(obj);
1107 EINA_ITERATOR_FOREACH(it, o)
1109 if (evas_object_data_get(o, "_elm_leaveme")) continue;
1110 evas_object_clip_set(o, clip);
1112 eina_iterator_free(it);
1116 _efl_ui_widget_efl_canvas_group_group_calculate(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *_pd EINA_UNUSED)
1118 /* a NO-OP, on the base */
1119 efl_canvas_group_need_recalculate_set(obj, EINA_FALSE);
1123 _efl_ui_widget_efl_canvas_group_group_member_add(Eo *obj, Elm_Widget_Smart_Data *pd, Evas_Object *child)
1126 efl_canvas_group_member_add(efl_super(obj, MY_CLASS), child);
1128 if (evas_object_data_get(child, "_elm_leaveme")) return;
1130 if (pd->bg != child)
1132 evas_object_color_get(obj, &r, &g, &b, &a);
1133 evas_object_color_set(child, r, g, b, a);
1136 efl_canvas_object_no_render_set(child, efl_canvas_object_no_render_get(obj));
1137 evas_object_clip_set(child, evas_object_clip_get(obj));
1139 if (evas_object_visible_get(obj))
1140 evas_object_show(child);
1142 evas_object_hide(child);
1146 _efl_ui_widget_efl_canvas_group_group_member_remove(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *_pd EINA_UNUSED, Evas_Object *child)
1148 if (!evas_object_data_get(child, "_elm_leaveme"))
1149 evas_object_clip_unset(child);
1150 efl_canvas_group_member_remove(efl_super(obj, MY_CLASS), child);
1155 _propagate_x_drag_lock(Evas_Object *obj,
1161 ELM_WIDGET_DATA_GET(sd->parent_obj, sd2);
1164 sd2->child_drag_x_locked += dir;
1165 _propagate_x_drag_lock(sd->parent_obj, dir);
1171 _propagate_y_drag_lock(Evas_Object *obj,
1177 ELM_WIDGET_DATA_GET(sd->parent_obj, sd2);
1180 sd2->child_drag_y_locked += dir;
1181 _propagate_y_drag_lock(sd->parent_obj, dir);
1187 _propagate_event_legacy(Eo *parent, const Efl_Event *event, Eo *obj, Elm_Event_Cb_Data *ecd)
1189 Evas_Callback_Type type;
1190 Evas_Event_Flags *event_flags, prev_flags;
1192 Evas_Event_Key_Down *down;
1193 Evas_Event_Key_Up *up;
1194 Evas_Event_Mouse_Wheel *wheel;
1198 if (event->desc == EFL_EVENT_KEY_DOWN)
1200 event_info.down = efl_input_legacy_info_get(event->info);
1201 EINA_SAFETY_ON_NULL_RETURN_VAL(event_info.down, EINA_FALSE);
1202 type = EVAS_CALLBACK_KEY_DOWN;
1203 event_flags = &event_info.down->event_flags;
1205 else if (event->desc == EFL_EVENT_KEY_UP)
1207 event_info.up = efl_input_legacy_info_get(event->info);
1208 EINA_SAFETY_ON_NULL_RETURN_VAL(event_info.up, EINA_FALSE);
1209 type = EVAS_CALLBACK_KEY_UP;
1210 event_flags = &event_info.up->event_flags;
1212 else if (event->desc == EFL_EVENT_POINTER_WHEEL)
1214 event_info.wheel = efl_input_legacy_info_get(event->info);
1215 EINA_SAFETY_ON_NULL_RETURN_VAL(event_info.wheel, EINA_FALSE);
1216 type = EVAS_CALLBACK_MOUSE_WHEEL;
1217 event_flags = &event_info.wheel->event_flags;
1222 prev_flags = *event_flags;
1223 if (ecd->func((void *)ecd->data, parent, obj, type, event_info.any) ||
1224 ((*event_flags) & EVAS_EVENT_FLAG_ON_HOLD))
1226 if (prev_flags != *event_flags)
1227 efl_input_event_flags_set(event->info, (Efl_Input_Flags)*event_flags);
1237 * If elm_widget_focus_region_get() returns an empty rect (w or h <= 0),
1238 * this function will ignore region show action.
1241 elm_widget_focus_region_show(Eo *obj)
1247 o = elm_widget_parent_get(obj);
1250 r = elm_widget_focus_region_get(obj);
1251 if (eina_rectangle_is_empty(&r.rect)) return;
1253 evas_object_geometry_get(obj, &ox, &oy, NULL, NULL);
1258 evas_object_geometry_get(o, &px, &py, NULL, NULL);
1260 if (_elm_scrollable_is(o) && !elm_widget_disabled_get(o))
1265 //TIZEN_ONLY(202191209): restore legacy focus of scrollable
1266 if (elm_widget_is_legacy(o))
1268 elm_interface_scrollable_content_region_get(o, &sx, &sy, NULL, NULL);
1269 elm_interface_scrollable_content_viewport_geometry_get(o, &vx, &vy, NULL, NULL);
1273 Eina_Position2D pos = efl_ui_scrollable_content_pos_get(o);
1274 Eina_Rect rect = efl_ui_scrollable_viewport_geometry_get(o);
1281 //elm_interface_scrollable_content_region_get(o, &sx, &sy, NULL, NULL);
1282 //elm_interface_scrollable_content_viewport_geometry_get(o, &vx, &vy, NULL, NULL);
1285 // Get the object's on_focus_region position relative to the pan in the scroller.
1287 rx = ox + r.x - vx + sx;
1288 ry = oy + r.y - vy + sy;
1290 switch (_elm_config->focus_autoscroll_mode)
1292 case ELM_FOCUS_AUTOSCROLL_MODE_SHOW:
1293 if (elm_widget_is_legacy(o))
1294 //TIZEN_ONLY(20200917): disable auto scroll
1296 int popup_data = evas_object_data_get(o, "popup_scroll");
1298 elm_interface_scrollable_content_region_show(o, rx, ry, r.w, r.h);
1302 efl_ui_scrollable_scroll(o, r, EINA_FALSE);
1304 case ELM_FOCUS_AUTOSCROLL_MODE_BRING_IN:
1305 if (elm_widget_is_legacy(o))
1306 elm_interface_scrollable_region_bring_in(o, rx, ry, r.w, r.h);
1308 efl_ui_scrollable_scroll(o, r, EINA_TRUE);
1314 r = elm_widget_focus_region_get(o);
1315 evas_object_geometry_get(o, &ox, &oy, NULL, NULL);
1324 o = elm_widget_parent_get(o);
1330 elm_widget_api_check(int ver)
1332 if (ver != ELM_INTERNAL_API_VERSION)
1334 CRI("Elementary widget api versions do not match");
1341 elm_widget_access(Evas_Object *obj,
1342 Eina_Bool is_access)
1345 Eina_Bool ret = EINA_TRUE;
1347 API_ENTRY return EINA_FALSE;
1348 for (unsigned int i = 0; i < eina_array_count(sd->children); ++i)
1350 child = eina_array_data_get(sd->children, i);
1352 if (elm_widget_is(child))
1353 ret &= elm_widget_access(child, is_access);
1356 efl_ui_widget_on_access_update(obj, is_access);
1357 efl_event_callback_legacy_call(obj, EFL_UI_WIDGET_EVENT_ACCESS_CHANGED, NULL);
1363 _efl_ui_widget_on_access_update(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *_pd EINA_UNUSED, Eina_Bool is_access EINA_UNUSED)
1368 _elm_widget_theme_helper(Eina_Error err, Eina_Bool *err_default, Eina_Bool *err_generic)
1370 if (err == EFL_UI_THEME_APPLY_ERROR_DEFAULT)
1371 *err_default = EINA_TRUE;
1372 else if (err == EFL_UI_THEME_APPLY_ERROR_GENERIC)
1373 *err_generic = EINA_TRUE;
1377 elm_widget_theme(Evas_Object *obj)
1383 Eina_Bool err_default = EINA_FALSE;
1384 Eina_Bool err_generic = EINA_FALSE;
1386 API_ENTRY return EFL_UI_THEME_APPLY_ERROR_GENERIC;
1387 for (unsigned int i = 0; i < eina_array_count(sd->children); ++i)
1389 child = eina_array_data_get(sd->children, i);
1390 if (_elm_widget_is(child))
1391 _elm_widget_theme_helper(elm_widget_theme(child), &err_default, &err_generic);
1395 _elm_widget_theme_helper(elm_widget_theme(sd->hover_obj), &err_default, &err_generic);
1397 EINA_LIST_FOREACH(sd->tooltips, l, tt)
1398 elm_tooltip_theme(tt);
1399 EINA_LIST_FOREACH(sd->cursors, l, cur)
1400 elm_cursor_theme(cur);
1402 _elm_widget_theme_helper(efl_ui_widget_theme_apply(obj), &err_default, &err_generic);
1403 if (err_generic) return EFL_UI_THEME_APPLY_ERROR_GENERIC;
1404 if (err_default) return EFL_UI_THEME_APPLY_ERROR_DEFAULT;
1406 // TIZEN_ONLY(20200623) : apply Tizen's color_class features
1407 if (sd->color_classes)
1408 _elm_widget_color_class_update(obj, sd);
1410 return EFL_UI_THEME_APPLY_ERROR_NONE;
1414 elm_widget_theme_specific(Evas_Object *obj,
1422 Elm_Theme *th2, *thdef;
1426 thdef = elm_theme_default_get();
1427 if (!th) th = thdef;
1431 if (!th2) th2 = thdef;
1439 if (th2 == thdef) break;
1440 th2 = th2->ref_theme;
1441 if (!th2) th2 = thdef;
1445 for (unsigned int i = 0; i < eina_array_count(sd->children); ++i)
1447 child = eina_array_data_get(sd->children, i);
1448 if (elm_widget_is(child))
1449 elm_widget_theme_specific(child, th, force);
1451 if (sd->hover_obj) elm_widget_theme(sd->hover_obj);
1452 EINA_LIST_FOREACH(sd->tooltips, l, tt)
1453 elm_tooltip_theme(tt);
1454 EINA_LIST_FOREACH(sd->cursors, l, cur)
1455 elm_cursor_theme(cur);
1456 efl_ui_widget_theme_apply(obj);
1459 EOLIAN static Eina_Error
1460 _efl_ui_widget_theme_apply(Eo *obj, Elm_Widget_Smart_Data *_pd EINA_UNUSED)
1462 _elm_widget_mirrored_reload(obj);
1464 return EFL_UI_THEME_APPLY_ERROR_NONE;
1470 * Returns the widget's mirrored mode.
1472 * @param obj The widget.
1473 * @return mirrored mode of the object.
1476 EOLIAN static Eina_Bool
1477 _efl_ui_widget_efl_ui_i18n_mirrored_get(const Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd)
1479 return sd->is_mirrored;
1485 * Sets the widget's mirrored mode.
1487 * @param obj The widget.
1488 * @param mirrored EINA_TRUE to set mirrored mode. EINA_FALSE to unset.
1491 _efl_ui_widget_efl_ui_i18n_mirrored_set(Eo *obj, Elm_Widget_Smart_Data *sd, Eina_Bool mirrored)
1493 mirrored = !!mirrored;
1495 if (sd->is_mirrored == mirrored) return;
1497 sd->is_mirrored = mirrored;
1498 elm_widget_theme(obj);
1502 * Returns the widget's mirrored mode setting.
1504 * @param obj The widget.
1505 * @return mirrored mode setting of the object.
1508 EOLIAN static Eina_Bool
1509 _efl_ui_widget_efl_ui_i18n_mirrored_automatic_get(const Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd)
1511 return sd->mirrored_auto_mode;
1517 * Sets the widget's mirrored mode setting.
1518 * When widget in automatic mode, it follows the system mirrored mode set by
1519 * elm_mirrored_set().
1520 * @param obj The widget.
1521 * @param automatic EINA_TRUE for auto mirrored mode. EINA_FALSE for manual.
1524 _efl_ui_widget_efl_ui_i18n_mirrored_automatic_set(Eo *obj, Elm_Widget_Smart_Data *sd, Eina_Bool automatic)
1526 if (sd->mirrored_auto_mode != automatic)
1528 sd->mirrored_auto_mode = automatic;
1532 efl_ui_mirrored_set(obj, elm_config_mirrored_get());
1540 * Add myself as a sub object of parent object
1542 * @see elm_widget_sub_object_add()
1545 elm_widget_sub_object_parent_add(Evas_Object *sobj)
1549 parent = efl_parent_get(sobj);
1550 if (!efl_isa(parent, EFL_UI_WIDGET_CLASS))
1552 ERR("You passed a wrong parent parameter (%p %s). "
1553 "Elementary widget's parent should be an elementary widget.", parent, evas_object_type_get(parent));
1557 return elm_widget_sub_object_add(parent, sobj);
1561 _disabled_counter_get(Eo *widget)
1563 ELM_WIDGET_DATA_GET_OR_RETURN(widget, pd, -1);
1565 return pd->disabled;
1569 _mirror_disabled_state(Eo *obj, Elm_Widget_Smart_Data *pd, int disabled_delta)
1571 int prev_disabled = pd->disabled;
1573 pd->disabled = (pd->parent_obj ? _disabled_counter_get(pd->parent_obj) : 0) + disabled_delta;
1575 //The current disabled state is the same as the parent
1576 //when the parent is assigned or changed, no further action is required.
1577 if (((prev_disabled > 0 && pd->disabled > 0)) ||
1578 ((prev_disabled <= 0 && pd->disabled <= 0)))
1581 //we should not call disabled_set when things are invalidated
1582 //otherwise we will unleashe an amount of errors in efl_ui_layout
1583 if (efl_invalidated_get(obj)) return;
1585 if (pd->disabled > 0)
1588 efl_ui_widget_disabled_set(obj, EINA_TRUE);
1593 efl_ui_widget_disabled_set(obj, EINA_FALSE);
1598 _efl_ui_widget_widget_parent_set(Eo *obj, Elm_Widget_Smart_Data *pd, Efl_Ui_Widget *parent)
1600 Efl_Ui_Widget *old_parent;
1601 //check if we are in the subobject list of parents
1604 ELM_WIDGET_DATA_GET_OR_RETURN(parent, ppd);
1605 EINA_SAFETY_ON_FALSE_RETURN(eina_array_find(ppd->children, obj, NULL));
1606 if (ppd->parent_obj == parent)
1608 CRI("ATTEMPTING TO SET CHILD OF PARENT AS PARENT OF ITS OWN PARENT. THIS IS A BUG.");
1613 /* NOTE: In the following two lines, 'obj' is correct. Do not change it.
1614 * Due to elementary's scale policy, scale and prev_scale can be different in
1615 * some cases. This happens when obj's previous parent and new parent have
1616 * different scale value.
1617 * For example, if obj's previous parent's scale is 5 and new parent's scale
1618 * is 2 while obj's scale is 0. Then 'prev_pscale' is 5 and 'scale' is 2. So
1619 * we need to reset obj's scale to 5.
1620 * Note that each widget's scale is 1.0 by default.
1622 double scale, prev_scale = efl_gfx_entity_scale_get(obj);
1623 Elm_Theme *th, *prev_th = elm_widget_theme_get(obj);
1624 int disabled_delta = pd->disabled - (pd->parent_obj ? _disabled_counter_get(pd->parent_obj) : 0);
1626 old_parent = pd->parent_obj;
1627 pd->parent_obj = parent;
1629 // now lets sync up all states
1632 Eina_Bool mirrored, pmirrored = efl_ui_mirrored_get(pd->parent_obj);
1633 scale = efl_gfx_entity_scale_get(obj);
1634 th = elm_widget_theme_get(obj);
1635 mirrored = efl_ui_mirrored_get(obj);
1639 if (!EINA_DBL_EQ(scale, prev_scale) || (th != prev_th) ||
1640 (pmirrored != mirrored))
1641 elm_widget_theme(obj);
1643 if (_is_focused(obj)) _parents_focus(parent);
1644 elm_widget_display_mode_set(obj, evas_object_size_hint_display_mode_get(parent));
1645 _elm_widget_top_win_focused_set(obj, _elm_widget_top_win_focused_get(parent));
1647 _mirror_disabled_state(obj, pd, disabled_delta);
1648 _full_eval(obj, pd);
1650 if (!efl_alive_get(obj)) return;
1651 if (old_parent && _elm_config->atspi_mode)
1653 Efl_Access_Object *aparent;
1654 aparent = efl_provider_find(efl_parent_get(obj), EFL_ACCESS_OBJECT_MIXIN);
1656 efl_access_children_changed_del_signal_emit(aparent, obj);
1659 if (pd->parent_obj && _elm_config->atspi_mode && efl_finalized_get(parent))
1661 Efl_Access_Object *aparent;
1662 aparent = efl_provider_find(efl_parent_get(obj), EFL_ACCESS_OBJECT_MIXIN);
1664 efl_access_children_changed_added_signal_emit(aparent, obj);
1669 _widget_add_sub(Eo *obj, Elm_Widget_Smart_Data *sd, Evas_Object *sobj)
1671 if (!sd->children) sd->children = eina_array_new(1);
1672 eina_array_push(sd->children, sobj);
1673 evas_object_data_set(sobj, "elm-parent", obj);
1674 //TIZEN_ONLY(20181024): Fix parent-children incosistencies in atspi tree
1675 if (efl_isa(sobj, EFL_ACCESS_OBJECT_MIXIN))
1676 efl_access_object_access_parent_set(sobj, obj);
1678 _callbacks_add(sobj, obj);
1682 _widget_del_sub(Eo *obj, Elm_Widget_Smart_Data *sd, Evas_Object *sobj)
1684 eina_array_remove(sd->children, _keep, sobj);
1685 evas_object_data_del(sobj, "elm-parent");
1686 _callbacks_del(sobj, obj);
1689 EOLIAN static Eina_Bool
1690 _efl_ui_widget_widget_sub_object_add(Eo *obj, Elm_Widget_Smart_Data *sd, Evas_Object *sobj)
1692 Efl_Ui_Widget *parent;
1693 Eina_Bool is_widget;
1695 EINA_SAFETY_ON_FALSE_RETURN_VAL(efl_isa(sobj, EFL_GFX_ENTITY_INTERFACE), EINA_FALSE);
1696 EINA_SAFETY_ON_TRUE_RETURN_VAL(obj == sobj, EINA_FALSE);
1698 is_widget = elm_widget_is(sobj);
1699 //first make sure that we unregister the sobj from the parent
1701 parent = efl_ui_widget_parent_get(sobj);
1703 parent = evas_object_data_get(sobj, "elm-parent");
1704 if (parent == obj) return EINA_TRUE;
1707 if (sd->parent_obj == sobj)
1709 CRI("ATTEMPTING TO SET CHILD OF PARENT AS PARENT OF ITS OWN PARENT. THIS IS A BUG.");
1713 if (!efl_ui_widget_sub_object_del(parent, sobj))
1717 //sobj does not have a parent here
1718 //first add it to our own children list
1719 _widget_add_sub(obj, sd, sobj);
1721 //TIZEN_ONLY(20200911): restore hide callback for sub-object
1723 efl_event_callback_add(sobj, EFL_GFX_ENTITY_EVENT_VISIBILITY_CHANGED, _on_sub_obj_hide, obj);
1726 //and if it is a widget, please set the correct parent on the widget itself
1727 //the parent set method will take care of the property syncing etc.
1729 efl_ui_widget_parent_set(sobj, obj);
1731 //TIZEN_ONLY(20190312): Restore child_can_focus
1732 if (elm_widget_is(sobj))
1734 /* update child focusable-ness on self and parents, now that a
1735 * focusable child got in */
1736 if (!sd->child_can_focus && (_is_focusable(sobj)))
1738 Elm_Widget_Smart_Data *sdp = sd;
1740 sdp->child_can_focus = EINA_TRUE;
1741 while (sdp->parent_obj)
1743 sdp = efl_data_scope_get(sdp->parent_obj, MY_CLASS);
1745 if (sdp->child_can_focus) break;
1747 sdp->child_can_focus = EINA_TRUE;
1752 /***********************************************************
1753 * TIZEN_ONLY(20180117): Override Paragraph Direction APIs *
1754 ***********************************************************/
1755 ELM_WIDGET_DATA_GET(sobj, sdc);
1756 if (sdc->inherit_paragraph_direction &&
1757 (sdc->paragraph_direction != efl_canvas_object_paragraph_direction_get(obj)))
1759 sdc->paragraph_direction = efl_canvas_object_paragraph_direction_get(obj);
1760 _efl_ui_widget_efl_canvas_object_paragraph_direction_set_internal(sobj, sdc, sdc->paragraph_direction);
1761 efl_canvas_object_paragraph_direction_set(efl_super(sobj, MY_CLASS), sdc->paragraph_direction);
1771 EOLIAN static Eina_Bool
1772 _efl_ui_widget_widget_sub_object_del(Eo *obj, Elm_Widget_Smart_Data *sd, Evas_Object *sobj)
1774 Evas_Object *sobj_parent = NULL;
1775 Eina_Bool is_widget;
1777 if (!sobj) return EINA_FALSE;
1779 EINA_SAFETY_ON_TRUE_RETURN_VAL(obj == sobj, EINA_FALSE);
1781 is_widget = _elm_widget_is(sobj);
1783 if (!is_widget) sobj_parent = evas_object_data_del(sobj, "elm-parent");
1785 //TIZEN_ONLY(20181024): Fix parent-children incosistencies in atspi tree
1786 if (efl_isa(sobj, EFL_ACCESS_OBJECT_MIXIN))
1787 efl_access_object_access_parent_set(sobj, NULL);
1790 if (sobj_parent && sobj_parent != obj)
1792 static int abort_on_warn = -1;
1794 ERR("removing sub object %p (%s) from parent %p (%s), "
1795 "but elm-parent is different %p (%s)!",
1796 sobj, elm_widget_type_get(sobj), obj, elm_widget_type_get(obj),
1797 sobj_parent, elm_widget_type_get(sobj_parent));
1799 if (EINA_UNLIKELY(abort_on_warn == -1))
1801 if (getenv("ELM_ERROR_ABORT")) abort_on_warn = 1;
1802 else abort_on_warn = 0;
1804 if (abort_on_warn == 1) abort();
1811 if (efl_ui_widget_parent_get(sobj) != obj)
1813 if (_is_focused(sobj))
1815 elm_widget_tree_unfocusable_set(sobj, EINA_TRUE);
1816 elm_widget_tree_unfocusable_set(sobj, EINA_FALSE);
1819 //TIZEN_ONLY(20190312): Restore child_can_focus
1820 if ((sd->child_can_focus) && (_is_focusable(sobj)))
1822 Evas_Object *parent = obj;
1824 /* update child focusable-ness on self and parents, now that a
1825 * focusable child is gone */
1828 Evas_Object *subobj;
1830 ELM_WIDGET_DATA_GET(parent, sdp);
1832 sdp->child_can_focus = EINA_FALSE;
1833 for (unsigned int i = 0; i < eina_array_count(sdp->children); ++i)
1835 subobj = eina_array_data_get(sdp->children, i);
1836 if ((subobj != sobj) && (_is_focusable(subobj)))
1838 sdp->child_can_focus = EINA_TRUE;
1843 /* break again, child_can_focus went back to
1845 if (sdp->child_can_focus) break;
1846 parent = sdp->parent_obj;
1850 /***********************************************************
1851 * TIZEN_ONLY(20180117): Override Paragraph Direction APIs *
1852 ***********************************************************/
1853 ELM_WIDGET_DATA_GET(sobj, sdc);
1856 if (sdc->inherit_paragraph_direction &&
1857 (sdc->paragraph_direction != EFL_TEXT_BIDIRECTIONAL_TYPE_NEUTRAL))
1859 sdc->paragraph_direction = EFL_TEXT_BIDIRECTIONAL_TYPE_NEUTRAL;
1860 _efl_ui_widget_efl_canvas_object_paragraph_direction_set_internal(sobj, sdc, sdc->paragraph_direction);
1861 efl_canvas_object_paragraph_direction_set(efl_super(sobj, MY_CLASS), EFL_TEXT_BIDIRECTIONAL_TYPE_NEUTRAL);
1868 efl_ui_widget_parent_set(sobj, NULL);
1871 if (sd->resize_obj == sobj) sd->resize_obj = NULL;
1873 _widget_del_sub(obj, sd, sobj);
1875 //TIZEN_ONLY(20200911): restore hide callback for sub-object
1877 efl_event_callback_del(sobj, EFL_GFX_ENTITY_EVENT_VISIBILITY_CHANGED, _on_sub_obj_hide, obj);
1883 /* protected function - for widget developers only */
1885 _efl_ui_widget_resize_object_set(Eo *obj, Elm_Widget_Smart_Data *sd, Eo *sobj)
1887 Evas_Object *parent;
1889 if (sd->resize_obj == sobj) return;
1890 EINA_SAFETY_ON_TRUE_RETURN(sobj && !efl_isa(sobj, EFL_CANVAS_OBJECT_CLASS));
1892 // orphan previous resize obj
1895 evas_object_clip_unset(sd->resize_obj);
1896 evas_object_smart_member_del(sd->resize_obj);
1898 if (_elm_widget_is(sd->resize_obj))
1900 if (_is_focused(sd->resize_obj)) _parents_unfocus(obj);
1902 elm_widget_sub_object_del(obj, sd->resize_obj);
1905 sd->resize_obj = sobj;
1908 // orphan new resize obj
1909 parent = evas_object_data_get(sobj, "elm-parent");
1910 if (parent && parent != obj)
1912 ELM_WIDGET_DATA_GET(parent, sdp);
1914 /* should be there, just being paranoid */
1917 if (sdp->resize_obj == sobj)
1918 elm_widget_resize_object_set(parent, NULL);
1920 elm_widget_sub_object_del(parent, sobj);
1924 elm_widget_sub_object_add(obj, sobj);
1925 evas_object_smart_member_add(sobj, obj);
1926 _smart_reconfigure(obj, sd);
1932 * WARNING: the programmer is responsible, in the scenario of
1933 * exchanging a hover object, of cleaning the old hover "target"
1937 elm_widget_hover_object_set(Eo *obj, Evas_Object *sobj)
1939 Elm_Widget_Smart_Data *sd = efl_data_scope_safe_get(obj, MY_CLASS);
1944 _callbacks_del(sd->hover_obj, obj);
1946 sd->hover_obj = sobj;
1949 _callbacks_add(sobj, obj);
1950 _smart_reconfigure(obj, sd);
1955 _efl_ui_widget_focus_allow_set(Eo *obj, Elm_Widget_Smart_Data *sd, Eina_Bool can_focus)
1957 can_focus = !!can_focus;
1959 if (sd->can_focus == can_focus) return;
1960 sd->can_focus = can_focus;
1963 //TIZEN_ONLY(20190312): Restore child_can_focus
1964 /* update child_can_focus of parents */
1965 Evas_Object *o = obj;
1969 o = elm_widget_parent_get(o);
1971 ELM_WIDGET_DATA_GET(o, sdp);
1972 if (!sdp || sdp->child_can_focus) break;
1973 sdp->child_can_focus = EINA_TRUE;
1977 efl_event_callback_array_add(obj, focus_callbacks(), NULL);
1981 //TIZEN_ONLY(20190312): Restore child_can_focus
1982 // update child_can_focus of parents */
1983 Evas_Object *parent = elm_widget_parent_get(obj);
1986 Evas_Object *subobj;
1988 ELM_WIDGET_DATA_GET(parent, sdp);
1991 sdp->child_can_focus = EINA_FALSE;
1992 for (unsigned int i = 0; i < eina_array_count(sdp->children); ++i)
1994 subobj = eina_array_data_get(sdp->children, i);
1995 if (_is_focusable(subobj))
1997 sdp->child_can_focus = EINA_TRUE;
2001 /* break again, child_can_focus went back to
2003 if (sdp->child_can_focus) break;
2004 parent = sdp->parent_obj;
2007 efl_event_callback_array_del(obj, focus_callbacks(), NULL);
2009 if (efl_finalized_get(obj))
2010 _full_eval(obj, sd);
2013 EOLIAN static Eina_Bool
2014 _efl_ui_widget_focus_allow_get(const Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd)
2016 return sd->can_focus;
2020 elm_widget_child_can_focus_get(const Eo *obj)
2022 Elm_Widget_Smart_Data *sd = efl_data_scope_safe_get(obj, MY_CLASS);
2023 if (!sd) return EINA_FALSE;
2025 //TIZEN_ONLY(20190312): Restore child_can_focus
2026 //return sd->logical.child_count > 0;
2027 return sd->child_can_focus;
2032 EINA_UNUSED static int
2033 _tree_unfocusable_counter_get(Eo *widget)
2035 ELM_WIDGET_DATA_GET_OR_RETURN(widget, pd, -1);
2037 return pd->tree_unfocusable;
2041 * Evalulate tree number.
2043 * This is here to support properties which are propagating through the widget tree. If this property is set to true,
2044 * every widget in the subtree, will also be automatically true.
2045 * When one of the widgets in the subtree then seperatly will be set to true, the unsetting on the original widget will not unset the flag automatically in this tree.
2047 * The basic idea here is:
2048 * - The numeric number beeing bigger than 0, means that the property is true
2049 * - The difference between the number of the parent, and the number of the object, represents the boolean flag
2050 * (0 means that the flag is equal to the one of the parent, 1 means that if the parent is false, this child is true).
2053 _calculate_tree_number(int self_counter, int parent_counter, Eina_Bool flag)
2055 int distance = self_counter - parent_counter;
2062 distance = self_counter - parent_counter;
2064 if ((distance < 0) || (distance > 1))
2066 distance = MAX(MIN(flag, 1), 0);
2067 self_counter = parent_counter + distance;
2070 return self_counter;
2073 /* TIZEN_ONLY(20190821): keep legacy focus logic
2075 _propagate_bool_property(Elm_Widget_Smart_Data *pd, Eina_Bool flag, void (*property_setting)(Eo *obj, Eina_Bool flag))
2077 Efl_Ui_Widget *subs;
2078 for (unsigned int i = 0; i < eina_array_count(pd->children); ++i)
2080 subs = eina_array_data_get(pd->children, i);
2081 if (efl_isa(subs, EFL_UI_WIDGET_CLASS))
2082 property_setting(subs, flag);
2090 * This API makes the widget object and its children to be unfocusable.
2092 * This API can be helpful for an object to be deleted.
2093 * When an object will be deleted soon, it and its children may not
2094 * want to get focus (by focus reverting or by other focus controls).
2095 * Then, just use this API before deleting.
2097 * @param obj The widget root of sub-tree
2098 * @param tree_unfocusable If true, set the object sub-tree as unfocusable
2103 elm_widget_tree_unfocusable_set(Eo *obj, Eina_Bool tree_unfocusable)
2105 /* TIZEN_ONLY(20190821): keep legacy focus logic
2106 Elm_Widget_Smart_Data *pd = efl_data_scope_safe_get(obj, MY_CLASS);
2107 EINA_SAFETY_ON_NULL_RETURN(pd);
2108 int old_tree_unfocusable;
2110 old_tree_unfocusable = pd->tree_unfocusable;
2112 pd->tree_unfocusable = _calculate_tree_number(pd->tree_unfocusable,
2113 (pd->parent_obj ? _tree_unfocusable_counter_get(pd->parent_obj) : 0),
2116 if (old_tree_unfocusable != pd->tree_unfocusable)
2118 _full_eval(obj, pd);
2119 _propagate_bool_property(pd, tree_unfocusable, elm_widget_tree_unfocusable_set);
2123 Elm_Widget_Smart_Data *sd = efl_data_scope_safe_get(obj, MY_CLASS);
2126 tree_unfocusable = !!tree_unfocusable;
2127 if (sd->tree_unfocusable == tree_unfocusable) return;
2128 sd->tree_unfocusable = tree_unfocusable;
2129 efl_ui_widget_focus_tree_unfocusable_handle(obj);
2136 * This returns true, if the object sub-tree is unfocusable.
2138 * @param obj The widget root of sub-tree
2139 * @return EINA_TRUE if the object sub-tree is unfocusable
2144 elm_widget_tree_unfocusable_get(const Eo *obj)
2146 Elm_Widget_Smart_Data *sd = efl_data_scope_safe_get(obj, MY_CLASS);
2147 EINA_SAFETY_ON_NULL_RETURN_VAL(sd, EINA_FALSE);
2149 return !!sd->tree_unfocusable;
2152 //TIZEN_ONLY(20191007): Add a API to raise focus_order.
2156 * Raise focus_order of @p obj. this API can be helpful to keep last focus
2157 * state of widgets which have items.
2162 elm_widget_focus_order_raise(Evas_Object *obj)
2166 sd->focus_order = focus_order;
2173 * Get the list of focusable child objects.
2175 * This function returns list of child objects which can get focus.
2177 * @param obj The parent widget
2178 * @return list of focusable child objects.
2183 elm_widget_can_focus_child_list_get(const Eo *obj)
2185 Elm_Widget_Smart_Data *sd = efl_data_scope_safe_get(obj, MY_CLASS);
2186 Eina_List *child_list = NULL;
2189 if (!sd) return NULL;
2190 for (unsigned int i = 0; i < eina_array_count(sd->children); ++i)
2192 child = eina_array_data_get(sd->children, i);
2193 if (!_elm_widget_is(child)) continue;
2194 if ((elm_widget_can_focus_get(child)) &&
2195 (evas_object_visible_get(child)) &&
2196 (!elm_widget_disabled_get(child)))
2197 child_list = eina_list_append(child_list, child);
2200 Eina_List *can_focus_list;
2201 can_focus_list = elm_widget_can_focus_child_list_get(child);
2203 child_list = eina_list_merge(child_list, can_focus_list);
2212 elm_widget_highlight_ignore_set(Eo *obj, Eina_Bool ignore)
2214 Elm_Widget_Smart_Data *sd = efl_data_scope_safe_get(obj, MY_CLASS);
2217 sd->highlight_ignore = !!ignore;
2222 elm_widget_highlight_ignore_get(const Eo *obj)
2224 Elm_Widget_Smart_Data *sd = efl_data_scope_safe_get(obj, MY_CLASS);
2225 if (!sd) return EINA_FALSE;
2227 return sd->highlight_ignore;
2232 elm_widget_highlight_in_theme_set(Eo *obj, Eina_Bool highlight)
2234 Elm_Widget_Smart_Data *sd = efl_data_scope_safe_get(obj, MY_CLASS);
2237 sd->highlight_in_theme = !!highlight;
2238 /* FIXME: if focused, it should switch from one mode to the other */
2242 _elm_widget_highlight_in_theme_update(Eo *obj)
2244 Evas_Object *top = elm_widget_top_get(obj);
2246 if (top && efl_isa(top, EFL_UI_WIN_CLASS))
2248 _elm_win_focus_highlight_in_theme_update(
2249 top, elm_widget_highlight_in_theme_get(obj));
2255 elm_widget_highlight_in_theme_get(const Eo *obj)
2257 Elm_Widget_Smart_Data *sd = efl_data_scope_safe_get(obj, MY_CLASS);
2258 if (!sd) return EINA_FALSE;
2260 return sd->highlight_in_theme;
2265 elm_widget_access_highlight_in_theme_set(Eo *obj, Eina_Bool highlight)
2267 Elm_Widget_Smart_Data *sd = efl_data_scope_safe_get(obj, MY_CLASS);
2270 sd->access_highlight_in_theme = !!highlight;
2275 elm_widget_access_highlight_in_theme_get(const Eo *obj)
2277 Elm_Widget_Smart_Data *sd = efl_data_scope_safe_get(obj, MY_CLASS);
2278 if (!sd) return EINA_FALSE;
2280 return sd->access_highlight_in_theme;
2285 elm_widget_highlight_get(const Eo *obj)
2287 Elm_Widget_Smart_Data *sd = efl_data_scope_safe_get(obj, MY_CLASS);
2288 if (!sd) return EINA_FALSE;
2290 return sd->highlighted;
2292 //TIZEN_ONLY(20180607): Restore legacy focus
2294 elm_widget_focus_get(const Eo *obj)
2296 ELM_WIDGET_DATA_GET_OR_RETURN(obj, sd, EINA_FALSE);
2297 return (sd->focused && sd->top_win_focused);
2300 EOLIAN static Evas_Object*
2301 _efl_ui_widget_focused_object_get(const Eo *obj, Elm_Widget_Smart_Data *sd)
2303 const Evas_Object *subobj;
2305 if (!sd->focused || !sd->top_win_focused) return NULL;
2306 for (unsigned int i = 0; i < eina_array_count(sd->children); ++i)
2308 subobj = eina_array_data_get(sd->children, i);
2310 if (!_elm_widget_is(subobj)) continue;
2311 fobj = efl_ui_widget_focused_object_get(subobj);
2312 if (fobj) return fobj;
2314 return (Evas_Object *)obj;
2319 elm_widget_is(const Evas_Object *obj)
2321 return _elm_widget_is(obj);
2325 elm_widget_access_info_set(Efl_Ui_Widget *obj, const char *txt)
2327 efl_ui_widget_access_info_set(obj, txt);
2331 elm_widget_access_info_get(const Efl_Ui_Widget *obj)
2333 return efl_ui_widget_access_info_get(obj);
2337 elm_widget_top_get(const Eo *obj)
2339 Efl_Ui_Widget *parent = elm_widget_parent_get(obj);
2342 if (!efl_isa(parent, EFL_UI_WIDGET_CLASS)) return NULL;
2343 return elm_widget_top_get(parent);
2346 return (Evas_Object *)obj;
2350 elm_widget_parent_widget_get(const Evas_Object *obj)
2352 Evas_Object *parent;
2354 if (_elm_widget_is(obj))
2356 ELM_WIDGET_DATA_GET(obj, sd);
2357 if (!sd) return NULL;
2358 parent = sd->parent_obj;
2362 parent = evas_object_data_get(obj, "elm-parent");
2363 if (!parent) parent = evas_object_smart_parent_get(obj);
2368 Evas_Object *elm_parent;
2369 if (_elm_widget_is(parent)) break;
2370 elm_parent = evas_object_data_get(parent, "elm-parent");
2371 if (elm_parent) parent = elm_parent;
2372 else parent = evas_object_smart_parent_get(parent);
2378 elm_widget_event_callback_add(Eo *obj, Elm_Event_Cb func, const void *data)
2381 EINA_SAFETY_ON_NULL_RETURN(func);
2383 Elm_Event_Cb_Data *ecb = ELM_NEW(Elm_Event_Cb_Data);
2386 ERR("Failed to allocate memory");
2391 sd->event_cb = eina_list_append(sd->event_cb, ecb);
2395 elm_widget_event_callback_del(Eo *obj, Elm_Event_Cb func, const void *data)
2397 API_ENTRY return NULL;
2398 EINA_SAFETY_ON_NULL_RETURN_VAL(func, NULL);
2400 Elm_Event_Cb_Data *ecd;
2402 EINA_LIST_FOREACH(sd->event_cb, l, ecd)
2403 if ((ecd->func == func) && (ecd->data == data))
2406 sd->event_cb = eina_list_remove_list(sd->event_cb, l);
2407 return (void *)data;
2414 _propagate_event(void *data EINA_UNUSED, const Efl_Event *eo_event)
2416 Evas_Object *obj = eo_event->object;
2417 Evas_Object *parent = obj;
2418 Elm_Event_Cb_Data *ecd;
2419 Eina_List *l, *l_prev;
2421 if ((evas_focus_get(evas_object_evas_get(obj)) != elm_widget_top_get(obj)) &&
2422 efl_isa(obj, EFL_UI_WIN_CLASS))
2425 while (parent && !efl_input_processed_get(eo_event->info))
2427 Elm_Widget_Smart_Data *sd = efl_data_scope_safe_get(parent, MY_CLASS);
2430 if (elm_widget_disabled_get(obj))
2432 parent = sd->parent_obj;
2436 if (efl_ui_widget_input_event_handler(parent, eo_event, obj))
2439 EINA_LIST_FOREACH_SAFE(sd->event_cb, l, l_prev, ecd)
2441 if (_propagate_event_legacy(parent, eo_event, obj, ecd))
2445 parent = sd->parent_obj;
2450 _elm_widget_focus_direction_weight_get(const Evas_Object *obj1,
2451 const Evas_Object *obj2,
2454 Evas_Coord obj_x1, obj_y1, w1, h1, obj_x2, obj_y2, w2, h2;
2455 double x1, yy1, x2, yy2, xx1, yyy1, xx2, yyy2;
2456 double ax, ay, cx, cy;
2457 double weight = -1.0, g = 0.0;
2458 // TIZEN_ONLY(20171129): add second_level for weight calculate
2459 Eina_Bool second_level = EINA_FALSE;
2462 if (obj1 == obj2) return 0.0;
2465 while (degree >= 360.0)
2467 while (degree < 0.0)
2470 evas_object_geometry_get(obj1, &obj_x1, &obj_y1, &w1, &h1);
2471 cx = obj_x1 + (w1 / 2.0);
2472 cy = obj_y1 + (h1 / 2.0);
2473 evas_object_geometry_get(obj2, &obj_x2, &obj_y2, &w2, &h2);
2475 /* For overlapping cases. */
2476 if (ELM_RECTS_INTERSECT(obj_x1, obj_y1, w1, h1, obj_x2, obj_y2, w2, h2))
2479 /* Change all points to relative one. */
2489 /* Get crossing points (ax, ay) between obj1 and a line extending
2490 * to the direction of current degree. */
2496 else if (degree == 90.0)
2501 else if (degree == 180.0)
2506 else if (degree == 270.0)
2513 g = tan(degree * (M_PI / 180.0));
2514 if ((degree > 0.0) && (degree < 90.0))
2517 if (ay <= yyy1) ax = xx1;
2524 else if ((degree > 90.0) && (degree < 180.0))
2527 if (ay <= yyy1) ax = x1;
2534 else if ((degree > 180.0) && (degree < 270.0))
2537 if (ay >= yy1) ax = x1;
2547 if (ay >= yy1) ax = xx1;
2556 /* Filter obj2, if it is not in the specific derection. */
2558 double rx[4] = {0.0, 0.0, 0.0, 0.0}, ry[4] = {0.0, 0.0, 0.0, 0.0};
2559 double t1, t2, u1, v1, u2, v2;
2561 if ((degree == 45.0) || (degree == 225.0) || (degree == 135.0) ||
2571 double g2 = tan((degree + 45.0) * (M_PI / 180.0));
2576 t1 = (u1 * ax) + (v1 * ay);
2577 t2 = (u2 * ax) + (v2 * ay);
2579 #define _R(x) (int)((x + 0.05) * 10.0)
2581 if ((_R(t1 * ((u1 * x2) + (v1 * yy2))) > 0) && (_R(t2 * ((u2 * x2) +
2587 if ((_R(t1 * ((u1 * x2) + (v1 * yyy2))) > 0) && (_R(t2 * ((u2 * x2) +
2593 if ((_R(t1 * ((u1 * xx2) + (v1 * yy2))) > 0) && (_R(t2 * ((u2 * xx2) +
2599 if ((_R(t1 * ((u1 * xx2) + (v1 * yyy2))) > 0) &&
2600 (_R(t2 * ((u2 * xx2) + (v2 * yyy2))) > 0))
2609 // TIZEN_ONLY(20171129): add second_level for weight calculate
2610 //if ((_R(xx2) < 0) || (_R(yy2) > 0) || (_R(yyy2) < 0)) return 0.0;
2611 if ((_R(xx2) < 0) || (_R(yy2) > 0) || (_R(yyy2) < 0))
2613 if (xx1 <= x2) second_level = EINA_TRUE;
2618 else if (degree == 90.0)
2620 // TIZEN_ONLY(20171129): add second_level for weight calculate
2621 //if ((_R(yyy2) < 0) || (_R(x2) > 0) || (_R(xx2) < 0)) return 0.0;
2622 if ((_R(yyy2) < 0) || (_R(x2) > 0) || (_R(xx2) < 0))
2624 if (yyy1 <= yy2) second_level = EINA_TRUE;
2629 else if (degree == 180.0)
2631 // TIZEN_ONLY(20171129): add second_level for weight calculate
2632 //if ((_R(x2) > 0) || (_R(yy2) > 0) || (_R(yyy2) < 0)) return 0.0;
2633 if ((_R(x2) > 0) || (_R(yy2) > 0) || (_R(yyy2) < 0))
2635 if (x1 >= xx2) second_level = EINA_TRUE;
2640 else if (degree == 270.0)
2642 // TIZEN_ONLY(20171129): add second_level for weight calculate
2643 //if ((_R(yy2) > 0) || (_R(x2) > 0) || (_R(xx2) < 0)) return 0.0;
2644 if ((_R(yy2) > 0) || (_R(x2) > 0) || (_R(xx2) < 0))
2646 if (yy1 >= yyy2) second_level = EINA_TRUE;
2653 if ((_R(g * x2) >= _R(yy2)) && (_R((g * x2)) <= _R(yyy2)))
2655 if (!((_R(ax * x2) > 0) && (_R(ay * (g * x2)) > 0)))
2658 else if ((_R(g * xx2) >= _R(yy2)) && (_R((g * xx2)) <= _R(yyy2)))
2660 if (!((_R(ax * xx2) > 0) && (_R(ay * (g * xx2)) > 0)))
2663 else if ((_R((1.0 / g) * yy2) >= _R(xx2)) && (_R((1.0 / g) * yy2)
2666 if (!((_R(ax * ((1.0 / g) * yy2)) > 0)
2667 && (_R(ay * yy2) > 0)))
2670 else if ((_R((1.0 / g) * yyy2) >= _R(xx2)) &&
2671 (_R((1.0 / g) * yyy2) <= _R(xx2)))
2673 if (!((_R(ax * ((1.0 / g) * yyy2)) > 0)
2674 && (_R(ay * yyy2) > 0))) return 0.0;
2680 /* Calculate the weight for obj2. */
2683 if (_R(xx1) > _R(x2)) weight = -1.0;
2684 else if ((_R(yy2) >= _R(yy1)) && (_R(yyy2) <= _R(yyy1)))
2685 weight = (x2 - xx1) * (x2 - xx1);
2686 else if (_R(yy2) > 0)
2687 weight = ((x2 - xx1) * (x2 - xx1)) + (yy2 * yy2);
2688 else if (_R(yyy2) < 0)
2689 weight = ((x2 - xx1) * (x2 - xx1)) + (yyy2 * yyy2);
2690 else weight = (x2 - xx1) * (x2 - xx1);
2692 else if (degree == 90.0)
2694 if (_R(yyy1) > _R(yy2)) weight = -1.0;
2695 else if ((_R(x2) >= _R(x1)) && (_R(xx2) <= _R(xx1)))
2696 weight = (yy2 - yyy1) * (yy2 - yyy1);
2697 else if (_R(x2) > 0)
2698 weight = (x2 * x2) + ((yy2 - yyy1) * (yy2 - yyy1));
2699 else if (_R(xx2) < 0)
2700 weight = (xx2 * xx2) + ((yy2 - yyy1) * (yy2 - yyy1));
2701 else weight = (yy2 - yyy1) * (yy2 - yyy1);
2703 else if (degree == 180.0)
2705 if (_R(x1) < _R(xx2)) weight = -1.0;
2706 else if ((_R(yy2) >= _R(yy1)) && (_R(yyy2) <= _R(yyy1)))
2707 weight = (x1 - xx2) * (x1 - xx2);
2708 else if (_R(yy2) > 0)
2709 weight = ((x1 - xx2) * (x1 - xx2)) + (yy2 * yy2);
2710 else if (_R(yyy2) < 0)
2711 weight = ((x1 - xx2) * (x1 - xx2)) + (yyy2 * yyy2);
2712 else weight = (x1 - xx2) * (x1 - xx2);
2714 else if (degree == 270.0)
2716 if (_R(yy1) < _R(yyy2)) weight = -1.0;
2717 else if ((_R(x2) >= _R(x1)) && (_R(xx2) <= _R(xx1)))
2718 weight = (yy1 - yyy2) * (yy1 - yyy2);
2719 else if (_R(x2) > 0)
2720 weight = (x2 * x2) + ((yy1 - yyy2) * (yy1 - yyy2));
2721 else if (_R(xx2) < 0)
2722 weight = (xx2 * xx2) + ((yy1 - yyy2) * (yy1 - yyy2));
2723 else weight = (yy1 - yyy2) * (yy1 - yyy2);
2728 double sx[4] = {0.0, 0.0, 0.0, 0.0}, sy[4] = {0.0, 0.0, 0.0, 0.0};
2729 double t_weight[4] = {-1.0, -1.0, -1.0, -1.0};
2730 if ((_R(g * x2) >= _R(yy2)) && (_R(g * x2) <= _R(yyy2)))
2734 t_weight[j++] = ((ax - x2) * (ax - x2)) +
2735 ((ay - (g * x2)) * (ay - (g * x2)));
2737 if ((_R(g * xx2) >= _R(yy2)) && (_R(g * xx2) <= _R(yyy2)))
2741 t_weight[j++] = ((ax - xx2) * (ax - xx2)) +
2742 ((ay - (g * xx2)) * (ay - (g * xx2)));
2744 if ((_R((1.0 / g) * yy2) >= _R(x2)) && (_R((1.0 / g) * yy2) <= _R(xx2)))
2746 sx[j] = (1.0 / g) * yy2;
2749 ((ax - ((1.0 / g) * yy2)) * (ax - ((1.0 / g) * yy2))) +
2750 ((ay - yy2) * (ay - yy2));
2752 if ((_R((1.0 / g) * yyy2) >= _R(x2)) && (_R((1.0 / g) * yyy2)
2755 sx[j] = (1.0 / g) * yyy2;
2758 ((ax - ((1.0 / g) * yyy2)) * (ax - ((1.0 / g) * yyy2))) +
2759 ((ay - yyy2) * (ay - yyy2));
2762 if ((j > 2) || ((j == 2) && ((_R(sx[0]) != _R(sx[1])) ||
2763 (_R(sy[0]) != _R(sy[1])))))
2767 if (_R(t_weight[k]) == 0) return -1.0;
2768 if ((1 / weight) < (1 / t_weight[k])) weight = t_weight[k];
2775 double ccx, ccy, t1_weight, x_diff, y_diff;
2776 ccx = ((1.0 / g) * rx[k] + ry[k]) / (g + (1.0 / g));
2778 x_diff = rx[k] - ccx;
2779 if (x_diff < 0) x_diff *= -1.0;
2780 y_diff = ry[k] - ccy;
2781 if (y_diff < 0) y_diff *= -1.0;
2783 (((ax - ccx) * (ax - ccx)) + ((ay - ccy) * (ay - ccy))) +
2784 ((x_diff * x_diff * x_diff) + (y_diff * y_diff * y_diff));
2785 if ((_R(t1_weight) != 0) && ((1 / weight) < (1 / t1_weight)))
2790 /* Return the current object's weight. */
2791 if (weight == -1.0) return 0.0;
2792 if (_R(weight) == 0) return -1.0;
2796 // TIZEN_ONLY(20171129): add second_level for weight calculate
2797 if (second_level) return 1.0 / (weight * 1000000.0);
2800 return 1.0 / weight;
2805 elm_widget_parent_highlight_set(Eo *obj, Eina_Bool highlighted)
2807 Elm_Widget_Smart_Data *sd =efl_data_scope_safe_get(obj, MY_CLASS);
2810 highlighted = !!highlighted;
2812 Evas_Object *o = elm_widget_parent_get(obj);
2814 if (o) elm_widget_parent_highlight_set(o, highlighted);
2816 sd->highlighted = highlighted;
2819 EOLIAN static Evas_Object*
2820 _efl_ui_widget_widget_parent_get(const Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd)
2822 return sd->parent_obj;
2826 _elm_widget_focus_auto_show(Evas_Object *obj)
2828 Evas_Object *top = elm_widget_top_get(obj);
2829 if (top && efl_isa(top, EFL_UI_WIN_CLASS)) _elm_win_focus_auto_show(top);
2833 _elm_widget_top_win_focused_set(Evas_Object *obj,
2834 Eina_Bool top_win_focused)
2839 if (sd->top_win_focused == top_win_focused) return;
2840 for (unsigned int i = 0; i < eina_array_count(sd->children); ++i)
2842 child = eina_array_data_get(sd->children, i);
2843 if (elm_widget_is(child))
2844 _elm_widget_top_win_focused_set(child, top_win_focused);
2846 sd->top_win_focused = top_win_focused;
2848 if (sd->focused && !sd->top_win_focused)
2849 efl_ui_focus_object_on_focus_update(obj);
2853 _elm_widget_top_win_focused_get(const Evas_Object *obj)
2855 API_ENTRY return EINA_FALSE;
2856 return sd->top_win_focused;
2860 _efl_ui_widget_disabled_set(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *pd, Eina_Bool disabled)
2862 Efl_Ui_Widget *subs;
2865 old_state = pd->disabled;
2867 pd->disabled = _calculate_tree_number(pd->disabled, (pd->parent_obj ? _disabled_counter_get(pd->parent_obj) : 0), disabled);
2868 if (old_state != pd->disabled)
2870 //TIZEN_ONLY(20191028): Restore focus revert in disabled_set
2871 efl_ui_widget_focus_disabled_handle(obj);
2873 if (efl_finalized_get(obj))
2874 _full_eval(obj, pd);
2875 for (unsigned int i = 0; i < eina_array_count(pd->children); ++i)
2877 subs = eina_array_data_get(pd->children, i);
2878 //TIZEN_ONLY(20180607): Restore legacy focus
2879 if (elm_widget_is(subs))
2880 efl_ui_widget_focus_disabled_handle((Evas_Object *)subs);
2882 if (efl_isa(subs, EFL_UI_WIDGET_CLASS))
2883 efl_ui_widget_disabled_set(subs, disabled);
2888 EOLIAN static Eina_Bool
2889 _efl_ui_widget_disabled_get(const Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *pd)
2891 return pd->disabled > 0;
2897 * Get the focus region of the given widget.
2899 * @return The region to show. If it's not a valid rectangle it will not show.
2901 * The focus region is the area of a widget that should brought into the
2902 * visible area when the widget is focused. Mostly used to show the part of
2903 * an entry where the cursor is, for example. The area returned is relative
2904 * to the object @p obj.
2906 * @param obj The widget object
2907 * @return The region to show, in relative coordinates. If it's not a valid
2908 * rectangle (i.e. w or h <= 0) it will be ignored.
2912 EOLIAN static Eina_Rect
2913 _efl_ui_widget_interest_region_get(const Eo *obj, Elm_Widget_Smart_Data *_pd EINA_UNUSED)
2916 r.size = efl_gfx_entity_size_get(obj);
2921 _efl_ui_widget_scroll_hold_push(Eo *obj, Elm_Widget_Smart_Data *sd)
2924 if (sd->scroll_hold == 1)
2926 if (_elm_scrollable_is(obj))
2928 if (elm_widget_is_legacy(obj))
2929 elm_interface_scrollable_hold_set(obj, EINA_TRUE);
2931 efl_ui_scrollable_scroll_hold_set(obj, EINA_TRUE);
2937 for (unsigned int i = 0; i < eina_array_count(sd->children); ++i)
2939 child = eina_array_data_get(sd->children, i);
2940 if (elm_widget_is(child) && _elm_scrollable_is(child))
2942 if (elm_widget_is_legacy(child))
2943 elm_interface_scrollable_hold_set(child, EINA_TRUE);
2945 efl_ui_scrollable_scroll_hold_set(child, EINA_TRUE);
2950 if (sd->parent_obj) efl_ui_widget_scroll_hold_push(sd->parent_obj);
2951 // FIXME: on delete/reparent hold pop
2955 _efl_ui_widget_scroll_hold_pop(Eo *obj, Elm_Widget_Smart_Data *sd)
2958 if (!sd->scroll_hold)
2960 if (_elm_scrollable_is(obj))
2962 if (elm_widget_is_legacy(obj))
2963 elm_interface_scrollable_hold_set(obj, EINA_FALSE);
2965 efl_ui_scrollable_scroll_hold_set(obj, EINA_FALSE);
2971 for (unsigned int i = 0; i < eina_array_count(sd->children); ++i)
2973 child = eina_array_data_get(sd->children, i);
2974 if (elm_widget_is(child) && _elm_scrollable_is(child))
2976 if (elm_widget_is_legacy(child))
2977 elm_interface_scrollable_hold_set(child, EINA_FALSE);
2979 efl_ui_scrollable_scroll_hold_set(child, EINA_FALSE);
2984 if (sd->parent_obj) efl_ui_widget_scroll_hold_pop(sd->parent_obj);
2985 if (sd->scroll_hold < 0) sd->scroll_hold = 0;
2989 elm_widget_scroll_hold_get(const Eo *obj)
2991 Elm_Widget_Smart_Data *sd = efl_data_scope_safe_get(obj, MY_CLASS);
2994 return sd->scroll_hold;
2998 _efl_ui_widget_scroll_freeze_push(Eo *obj, Elm_Widget_Smart_Data *sd)
3000 sd->scroll_freeze++;
3001 if (sd->scroll_freeze == 1)
3003 if (_elm_scrollable_is(obj))
3005 if (elm_widget_is_legacy(obj))
3006 elm_interface_scrollable_freeze_set(obj, EINA_TRUE);
3008 efl_ui_scrollable_scroll_freeze_set(obj, EINA_TRUE);
3014 for (unsigned int i = 0; i < eina_array_count(sd->children); ++i)
3016 child = eina_array_data_get(sd->children, i);
3017 if (elm_widget_is(child) && _elm_scrollable_is(child))
3019 if (elm_widget_is_legacy(child))
3020 elm_interface_scrollable_freeze_set(child, EINA_TRUE);
3022 efl_ui_scrollable_scroll_freeze_set(child, EINA_TRUE);
3027 if (sd->parent_obj) efl_ui_widget_scroll_freeze_push(sd->parent_obj);
3028 // FIXME: on delete/reparent freeze pop
3032 _efl_ui_widget_scroll_freeze_pop(Eo *obj, Elm_Widget_Smart_Data *sd)
3034 sd->scroll_freeze--;
3035 if (!sd->scroll_freeze)
3037 if (_elm_scrollable_is(obj))
3039 if (elm_widget_is_legacy(obj))
3040 elm_interface_scrollable_freeze_set(obj, EINA_FALSE);
3042 efl_ui_scrollable_scroll_freeze_set(obj, EINA_FALSE);
3048 for (unsigned int i = 0; i < eina_array_count(sd->children); ++i)
3050 child = eina_array_data_get(sd->children, i);
3052 if (elm_widget_is(child) && _elm_scrollable_is(child))
3054 if (elm_widget_is_legacy(child))
3055 elm_interface_scrollable_freeze_set(child, EINA_FALSE);
3057 efl_ui_scrollable_scroll_freeze_set(child, EINA_FALSE);
3062 if (sd->parent_obj) efl_ui_widget_scroll_freeze_pop(sd->parent_obj);
3063 if (sd->scroll_freeze < 0) sd->scroll_freeze = 0;
3067 elm_widget_scroll_freeze_get(const Eo *obj)
3069 Elm_Widget_Smart_Data *sd = efl_data_scope_safe_get(obj, MY_CLASS);
3072 return sd->scroll_freeze;
3076 _efl_ui_widget_efl_gfx_entity_scale_set(Eo *obj, Elm_Widget_Smart_Data *sd, double scale)
3078 if (scale < 0.0) scale = 0.0;
3079 if (!EINA_DBL_EQ(sd->scale, scale))
3082 elm_widget_theme(obj);
3086 EOLIAN static double
3087 _efl_ui_widget_efl_gfx_entity_scale_get(const Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd)
3089 // FIXME: save walking up the tree by storing/caching parent scale
3090 if (EINA_DBL_EQ(sd->scale, 0.0))
3094 return efl_gfx_entity_scale_get(sd->parent_obj);
3105 elm_widget_theme_set(Evas_Object *obj, Elm_Theme *th)
3107 Elm_Widget_Smart_Data *sd = efl_data_scope_safe_get(obj, MY_CLASS);
3110 Eina_Bool apply = EINA_FALSE;
3111 if (sd->theme != th)
3113 if (elm_widget_theme_get(obj) != th) apply = EINA_TRUE;
3114 if (sd->theme) elm_theme_free(sd->theme);
3116 if (th) efl_ref(th->eo_theme);
3117 if (apply) elm_widget_theme(obj);
3122 elm_widget_part_text_set(Eo *obj, const char *part, const char *label)
3124 /* legacy support: combobox was special (internal entry is text object). */
3125 //TIZEN_ONLY(20180426):stop creating unused class.
3126 if (efl_isa(obj, EFL_UI_LAYOUT_BASE_CLASS))
3127 elm_layout_text_set(obj, part, label);
3128 else if (efl_isa(obj, ELM_COMBOBOX_CLASS))
3129 _elm_combobox_part_text_set(obj, part, label);
3134 elm_widget_part_text_get(const Eo *obj, const char *part)
3136 /* legacy support: combobox was special (internal entry is text object). */
3137 //TIZEN_ONLY(20180426):stop creating unused class.
3138 if (efl_isa(obj, EFL_UI_LAYOUT_BASE_CLASS))
3139 return elm_layout_text_get(obj, part);
3140 else if (efl_isa(obj, ELM_COMBOBOX_CLASS))
3141 return _elm_combobox_part_text_get(obj, part);
3147 static Elm_Translate_String_Data *
3148 _translate_string_data_get(Eina_Inlist *translate_strings, const char *part)
3150 Elm_Translate_String_Data *ts;
3151 Eina_Stringshare *str;
3153 if (!translate_strings) return NULL;
3155 str = eina_stringshare_add(part);
3156 EINA_INLIST_FOREACH(translate_strings, ts)
3158 if (ts->id == str) break;
3161 eina_stringshare_del(str);
3166 static Elm_Translate_String_Data *
3167 _part_text_translatable_set(Eina_Inlist **translate_strings, const char *part, Eina_Bool translatable, Eina_Bool preset)
3170 Elm_Translate_String_Data *ts;
3171 t = *translate_strings;
3172 ts = _translate_string_data_get(t, part);
3178 ts = ELM_NEW(Elm_Translate_String_Data);
3179 if (!ts) return NULL;
3181 ts->id = eina_stringshare_add(part);
3182 t = eina_inlist_append(t, (Eina_Inlist*) ts);
3184 if (preset) ts->preset = EINA_TRUE;
3186 //Delete this exist one if this part has been not preset.
3187 //see elm_widget_part_text_translatable_set()
3188 else if (ts && ((preset) || (!ts->preset)))
3190 t = eina_inlist_remove(t, EINA_INLIST_GET(ts));
3191 eina_stringshare_del(ts->id);
3192 eina_stringshare_del(ts->domain);
3193 eina_stringshare_del(ts->string);
3194 ELM_SAFE_FREE(ts, free);
3197 *translate_strings = t;
3204 elm_widget_part_translatable_text_set(Eo *obj, const char *part, const char *label, const char *domain)
3206 Elm_Translate_String_Data *ts;
3207 Elm_Widget_Smart_Data *sd;
3209 sd = efl_data_scope_safe_get(obj, MY_CLASS);
3214 _part_text_translatable_set(&sd->translate_strings, part, EINA_FALSE,
3219 ts = _part_text_translatable_set(&sd->translate_strings, part,
3220 EINA_TRUE, EINA_FALSE);
3222 if (!ts->string) ts->string = eina_stringshare_add(label);
3223 else eina_stringshare_replace(&ts->string, label);
3224 if (!ts->domain) ts->domain = eina_stringshare_add(domain);
3225 else eina_stringshare_replace(&ts->domain, domain);
3227 if (label[0]) label = dgettext(domain, label);
3231 sd->on_translate = EINA_TRUE;
3232 elm_widget_part_text_set(obj, part, label);
3233 sd->on_translate = EINA_FALSE;
3238 elm_widget_domain_part_text_translatable_set(Eo *obj, const char *part, const char *domain, Eina_Bool translatable)
3240 Elm_Translate_String_Data *ts;
3241 Elm_Widget_Smart_Data *sd;
3242 const char *text = NULL;
3244 sd = efl_data_scope_safe_get(obj, MY_CLASS);
3247 ts = _part_text_translatable_set(&sd->translate_strings, part,
3248 translatable, EINA_TRUE);
3250 if (!ts->domain) ts->domain = eina_stringshare_add(domain);
3251 else eina_stringshare_replace(&ts->domain, domain);
3253 text = elm_widget_part_text_get(obj, part);
3254 if (!text || !text[0]) return;
3256 if (!ts->string) ts->string = eina_stringshare_add(text);
3258 //Try to translate text since we don't know the text is already translated.
3260 text = dgettext(domain, text);
3262 sd->on_translate = EINA_TRUE;
3263 elm_widget_part_text_set(obj, part, text);
3264 sd->on_translate = EINA_FALSE;
3269 elm_widget_part_translatable_text_get(const Eo *obj, const char *part, const char **domain)
3271 Elm_Widget_Smart_Data *sd;
3272 Elm_Translate_String_Data *ts;
3274 if (domain) *domain = NULL;
3276 sd = efl_data_scope_safe_get(obj, MY_CLASS);
3277 if (!sd) return NULL;
3279 ts = _translate_string_data_get(sd->translate_strings, part);
3280 if (!ts) return NULL;
3282 if (domain) *domain = ts->domain;
3287 _efl_ui_widget_efl_ui_l10n_translation_update(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd)
3291 for (unsigned int i = 0; i < eina_array_count(sd->children); ++i)
3293 child = eina_array_data_get(sd->children, i);
3294 if (elm_widget_is(child))
3295 efl_ui_l10n_translation_update(child);
3299 if (sd->hover_obj) efl_ui_l10n_translation_update(sd->hover_obj);
3302 Elm_Translate_String_Data *ts;
3303 EINA_INLIST_FOREACH(sd->translate_strings, ts)
3305 if (!ts->string) continue;
3306 const char *s = dgettext(ts->domain, ts->string);
3307 sd->on_translate = EINA_TRUE;
3308 elm_widget_part_text_set(obj, ts->id, s);
3309 sd->on_translate = EINA_FALSE;
3312 efl_event_callback_legacy_call(obj, EFL_UI_WIDGET_EVENT_LANGUAGE_CHANGED, NULL);
3316 _efl_ui_widget_access_info_set(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd, const char *txt)
3318 eina_stringshare_replace(&sd->access_info, txt);
3321 EOLIAN static const char*
3322 _efl_ui_widget_access_info_get(const Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd)
3324 return sd->access_info;
3327 //TIZEN_ONLY(20160822): When atspi mode is dynamically switched on/off,
3328 //register/unregister access objects accordingly.
3330 elm_widget_screen_reader(Evas_Object *obj,
3331 Eina_Bool is_screen_reader)
3334 Eina_Bool ret = EINA_TRUE;
3336 API_ENTRY return EINA_FALSE;
3337 for (unsigned int i = 0; i < eina_array_count(sd->children); ++i)
3339 child = eina_array_data_get(sd->children, i);
3340 if (elm_widget_is(child))
3341 ret &= elm_widget_screen_reader(child, is_screen_reader);
3343 efl_ui_widget_screen_reader(obj, is_screen_reader);
3349 _efl_ui_widget_screen_reader(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *_pd EINA_UNUSED, Eina_Bool is_screen_reader EINA_UNUSED)
3354 //TIZEN_ONLY(20170621) handle atspi proxy connection at runtime
3356 elm_widget_atspi(Evas_Object *obj, Eina_Bool is_atspi)
3358 Eina_List *l, *children;
3360 Eina_Bool ret = EINA_TRUE;
3362 API_ENTRY return EINA_FALSE;
3363 children = efl_access_object_access_children_get(obj);
3364 EINA_LIST_FOREACH(children, l, child)
3366 ret &= elm_widget_atspi(child, is_atspi);
3368 efl_ui_widget_atspi(obj, is_atspi);
3374 _efl_ui_widget_atspi(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *_pd EINA_UNUSED, Eina_Bool is_atspi EINA_UNUSED)
3381 elm_widget_scroll_hold_push(Efl_Ui_Widget *obj)
3383 efl_ui_widget_scroll_hold_push(obj);
3387 elm_widget_scroll_hold_pop(Efl_Ui_Widget *obj)
3389 efl_ui_widget_scroll_hold_pop(obj);
3393 elm_widget_scroll_freeze_push(Efl_Ui_Widget *obj)
3395 efl_ui_widget_scroll_freeze_push(obj);
3399 elm_widget_scroll_freeze_pop(Efl_Ui_Widget *obj)
3401 efl_ui_widget_scroll_freeze_pop(obj);
3405 elm_widget_theme_get(const Evas_Object *obj)
3407 Elm_Widget_Smart_Data *sd = efl_data_scope_safe_get(obj, MY_CLASS);
3408 if (!sd) return NULL;
3413 return elm_widget_theme_get(sd->parent_obj);
3419 EOLIAN static Eina_Error
3420 _efl_ui_widget_style_set(Eo *obj, Elm_Widget_Smart_Data *sd, const char *style)
3422 if (!elm_widget_is_legacy(obj) && efl_finalized_get(obj))
3424 ERR("Efl.Ui.Widget.style can only be set before finalize!");
3425 return EFL_UI_THEME_APPLY_ERROR_GENERIC;
3428 if (eina_stringshare_replace(&sd->style, style))
3429 return elm_widget_theme(obj);
3431 return EFL_UI_THEME_APPLY_ERROR_NONE;
3434 EOLIAN static const char*
3435 _efl_ui_widget_style_get(const Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd)
3439 if (sd->style) ret = sd->style;
3445 elm_widget_tooltip_add(Eo *obj, Elm_Tooltip *tt)
3447 Elm_Widget_Smart_Data *sd = efl_data_scope_safe_get(obj, MY_CLASS);
3450 sd->tooltips = eina_list_append(sd->tooltips, tt);
3454 elm_widget_tooltip_del(Eo *obj, Elm_Tooltip *tt)
3456 Elm_Widget_Smart_Data *sd = efl_data_scope_safe_get(obj, MY_CLASS);
3459 sd->tooltips = eina_list_remove(sd->tooltips, tt);
3463 elm_widget_cursor_add(Eo *obj, Elm_Cursor *cur)
3465 Elm_Widget_Smart_Data *sd = efl_data_scope_safe_get(obj, MY_CLASS);
3468 sd->cursors = eina_list_append(sd->cursors, cur);
3472 elm_widget_cursor_del(Eo *obj, Elm_Cursor *cur)
3474 Elm_Widget_Smart_Data *sd = efl_data_scope_safe_get(obj, MY_CLASS);
3477 sd->cursors = eina_list_remove(sd->cursors, cur);
3481 elm_widget_scroll_lock_set(Eo *obj, Efl_Ui_Layout_Orientation block)
3483 Elm_Widget_Smart_Data *sd = efl_data_scope_safe_get(obj, MY_CLASS);
3487 lx = !!(block & EFL_UI_LAYOUT_ORIENTATION_HORIZONTAL);
3488 ly = !!(block & EFL_UI_LAYOUT_ORIENTATION_VERTICAL);
3489 if (sd->scroll_x_locked != lx)
3491 sd->scroll_x_locked = lx;
3492 _propagate_x_drag_lock(obj, lx ? 1 : -1);
3494 if (sd->scroll_y_locked != ly)
3496 sd->scroll_y_locked = ly;
3497 _propagate_y_drag_lock(obj, ly ? 1 : -1);
3501 EAPI Efl_Ui_Layout_Orientation
3502 elm_widget_scroll_lock_get(const Eo *obj)
3504 Elm_Widget_Smart_Data *sd = efl_data_scope_safe_get(obj, MY_CLASS);
3505 Efl_Ui_Layout_Orientation block = EFL_UI_LAYOUT_ORIENTATION_DEFAULT;
3507 if (!sd) return block;
3508 if (sd->scroll_x_locked) block |= EFL_UI_LAYOUT_ORIENTATION_HORIZONTAL;
3509 if (sd->scroll_y_locked) block |= EFL_UI_LAYOUT_ORIENTATION_VERTICAL;
3515 elm_widget_scroll_child_locked_x_get(const Eo *obj)
3517 Elm_Widget_Smart_Data *sd = efl_data_scope_safe_get(obj, MY_CLASS);
3518 if (!sd) return EINA_FALSE;
3519 return sd->child_drag_x_locked;
3523 elm_widget_scroll_child_locked_y_get(const Eo *obj)
3525 Elm_Widget_Smart_Data *sd = efl_data_scope_safe_get(obj, MY_CLASS);
3526 if (!sd) return EINA_FALSE;
3527 return sd->child_drag_y_locked;
3531 elm_widget_theme_object_set(Evas_Object *obj, Evas_Object *edj, const char *wname, const char *welement, const char *wstyle)
3533 Elm_Widget_Smart_Data *sd = efl_data_scope_safe_get(obj, MY_CLASS);
3534 if (!sd) return EFL_UI_THEME_APPLY_ERROR_GENERIC;
3536 if (eina_streq(welement, "base"))
3538 if (eina_streq(wstyle, "default"))
3540 return _elm_theme_object_set(obj, edj, wname, welement, wstyle);
3544 _convert(Efl_Dbg_Info *info, Eina_Iterator *ptr_list)
3549 EINA_ITERATOR_FOREACH(ptr_list, p)
3553 snprintf(name, sizeof(name), "Candidate %d", i);
3555 EFL_DBG_INFO_APPEND(info, name, EINA_VALUE_TYPE_UINT64, p);
3559 eina_iterator_free(ptr_list);
3563 _efl_ui_widget_efl_object_dbg_info_get(Eo *eo_obj, Elm_Widget_Smart_Data *_pd EINA_UNUSED, Efl_Dbg_Info *root)
3565 efl_dbg_info_get(efl_super(eo_obj, MY_CLASS), root);
3566 Efl_Ui_Focus_Relations *rel = NULL;
3567 Efl_Dbg_Info *focus, *group = EFL_DBG_INFO_LIST_APPEND(root, MY_CLASS_NAME);
3569 EFL_DBG_INFO_APPEND(group, "Wid-Type", EINA_VALUE_TYPE_STRING, elm_widget_type_get(eo_obj));
3570 EFL_DBG_INFO_APPEND(group, "Style", EINA_VALUE_TYPE_STRING, elm_widget_style_get(eo_obj));
3571 EFL_DBG_INFO_APPEND(group, "Layer", EINA_VALUE_TYPE_INT,
3572 (int) evas_object_layer_get(eo_obj));
3573 EFL_DBG_INFO_APPEND(group, "Scale", EINA_VALUE_TYPE_DOUBLE,
3574 evas_object_scale_get(eo_obj));
3575 EFL_DBG_INFO_APPEND(group, "Has focus", EINA_VALUE_TYPE_CHAR,
3576 elm_object_focus_get(eo_obj));
3577 EFL_DBG_INFO_APPEND(group, "Can focus", EINA_VALUE_TYPE_CHAR,
3578 elm_widget_can_focus_get(eo_obj));
3579 EFL_DBG_INFO_APPEND(group, "Disabled", EINA_VALUE_TYPE_CHAR,
3580 elm_widget_disabled_get(eo_obj));
3581 EFL_DBG_INFO_APPEND(group, "Mirrored", EINA_VALUE_TYPE_CHAR,
3582 efl_ui_mirrored_get(eo_obj));
3583 EFL_DBG_INFO_APPEND(group, "Tree Unfocusable", EINA_VALUE_TYPE_CHAR,
3584 elm_widget_tree_unfocusable_get(eo_obj));
3585 EFL_DBG_INFO_APPEND(group, "Automatic mirroring", EINA_VALUE_TYPE_CHAR,
3586 efl_ui_mirrored_automatic_get(eo_obj));
3588 rel = efl_ui_focus_manager_fetch(_pd->focus.manager, eo_obj);
3591 focus = EFL_DBG_INFO_LIST_APPEND(group, "Focus");
3593 EFL_DBG_INFO_APPEND(focus, "logical", EINA_VALUE_TYPE_CHAR, rel->logical );
3594 EFL_DBG_INFO_APPEND(focus, "manager", EINA_VALUE_TYPE_UINT64, _pd->focus.manager);
3595 EFL_DBG_INFO_APPEND(focus, "parent", EINA_VALUE_TYPE_UINT64, rel->parent);
3596 EFL_DBG_INFO_APPEND(focus, "next", EINA_VALUE_TYPE_UINT64 , rel->next);
3597 EFL_DBG_INFO_APPEND(focus, "prev", EINA_VALUE_TYPE_UINT64 , rel->prev);
3599 EFL_DBG_INFO_APPEND(focus, "redirect", EINA_VALUE_TYPE_UINT64 , rel->redirect);
3601 #define ADD_PTR_LIST(name) \
3602 Efl_Dbg_Info* name = EFL_DBG_INFO_LIST_APPEND(focus, ""#name""); \
3603 _convert(name, rel->name);
3614 //if that's a focus manager, give useful information like the border elements
3615 if (efl_isa(eo_obj, EFL_UI_FOCUS_MANAGER_INTERFACE))
3617 Efl_Dbg_Info *border;
3619 focus = EFL_DBG_INFO_LIST_APPEND(group, "Focus Manager");
3620 border = EFL_DBG_INFO_LIST_APPEND(focus, "Border Elements");
3623 efl_ui_focus_manager_border_elements_get(eo_obj)
3626 EFL_DBG_INFO_APPEND(focus, "redirect", EINA_VALUE_TYPE_UINT64,
3627 efl_ui_focus_manager_redirect_get(eo_obj));
3632 elm_widget_is_check(const Evas_Object *obj)
3634 static int abort_on_warn = -1;
3635 if (elm_widget_is(obj))
3638 ERR("Passing Object: %p.", obj);
3639 if (abort_on_warn == -1)
3641 if (getenv("ELM_ERROR_ABORT")) abort_on_warn = 1;
3642 else abort_on_warn = 0;
3644 if (abort_on_warn == 1) abort();
3648 /* If you changed a legacy widget's class name,
3649 * please update the "legacy_type_table". */
3651 elm_widget_type_get(const Evas_Object *obj)
3656 API_ENTRY return NULL;
3658 ret = efl_class_name_get(efl_class_get(obj));
3660 /* If the given widget is created for legacy,
3661 * convert type name to legacy. */
3662 if (elm_widget_is_legacy(obj))
3664 for (i = 0; legacy_type_table[i][0] ; i++)
3666 if (eina_streq(ret, legacy_type_table[i][0]))
3667 return legacy_type_table[i][1];
3675 elm_widget_type_check(const Evas_Object *obj,
3679 const char *provided, *expected = "(unknown)";
3680 static int abort_on_warn = -1;
3682 provided = elm_widget_type_get(obj);
3683 /* TODO: eventually migrate to check_ptr version */
3684 if (evas_object_smart_type_check(obj, type)) return EINA_TRUE;
3685 if (type) expected = type;
3686 if ((!provided) || (!provided[0]))
3688 provided = evas_object_type_get(obj);
3689 if ((!provided) || (!provided[0]))
3690 provided = "(unknown)";
3692 ERR("Passing Object: %p in function: %s, of type: '%s' when expecting"
3693 " type: '%s'", obj, func, provided, expected);
3694 if (abort_on_warn == -1)
3696 if (getenv("ELM_ERROR_ABORT")) abort_on_warn = 1;
3697 else abort_on_warn = 0;
3699 if (abort_on_warn == 1) abort();
3705 elm_widget_name_find(const Eo *obj, const char *name, int recurse)
3709 INTERNAL_ENTRY NULL;
3711 if (!name) return NULL;
3712 if (!_elm_widget_is(obj)) return NULL;
3714 for (unsigned int i = 0; i < eina_array_count(sd->children); ++i)
3716 child = eina_array_data_get(sd->children, i);
3717 s = evas_object_name_get(child);
3718 if ((s) && (!strcmp(s, name))) return child;
3719 if ((recurse != 0) &&
3720 ((child = elm_widget_name_find(child, name, recurse - 1))))
3725 s = evas_object_name_get(sd->hover_obj);
3726 if ((s) && (!strcmp(s, name))) return sd->hover_obj;
3727 if ((recurse != 0) &&
3728 ((child = elm_widget_name_find(sd->hover_obj, name, recurse - 1))))
3737 * Split string in words
3739 * @param str Source string
3740 * @return List of const words
3742 * @see elm_widget_stringlist_free()
3746 elm_widget_stringlist_get(const char *str)
3748 Eina_List *list = NULL;
3750 if (!str) return NULL;
3751 for (b = s = str; 1; s++)
3753 if ((*s == ' ') || (!*s))
3755 char *t = malloc(s - b + 1);
3758 strncpy(t, b, s - b);
3760 list = eina_list_append(list, eina_stringshare_add(t));
3771 elm_widget_stringlist_free(Eina_List *list)
3774 EINA_LIST_FREE(list, s)
3775 eina_stringshare_del(s);
3777 //TIZEN_ONLY(20180607): Restore legacy focus
3779 _efl_ui_widget_focus_hide_handle(Eo *obj, Elm_Widget_Smart_Data *_pd EINA_UNUSED)
3781 if (!_elm_widget_is(obj))
3783 _if_focused_revert(obj, EINA_TRUE);
3788 elm_widget_focus_mouse_up_handle(Eo *obj)
3790 if (!_is_focusable(obj)) return;
3792 /* TIZEN_ONLY(20180607): Restore legacy focus
3793 Elm_Widget_Smart_Data *pd = efl_data_scope_get(obj, MY_CLASS);
3794 if (pd->focus.manager && !pd->focus.logical)
3796 efl_ui_focus_util_focus(obj);
3799 Evas_Object *o = obj;
3802 if (_elm_widget_is(o)) break;
3803 o = evas_object_smart_parent_get(o);
3807 efl_ui_widget_focus_mouse_up_handle(o);
3810 // TIZEN_ONLY(20190821): keep legacy focus logic
3812 _efl_ui_widget_focus_tree_unfocusable_handle(Eo *obj, Elm_Widget_Smart_Data *_pd EINA_UNUSED)
3814 if (!elm_widget_parent_get(obj))
3815 efl_ui_widget_focused_object_clear(obj);
3817 _if_focused_revert(obj, EINA_TRUE);
3825 * Get the focus highlight geometry of a widget.
3827 * @param obj Widget object for the focus highlight
3828 * @param x Focus highlight x coordinate
3829 * @param y Focus highlight y coordinate
3830 * @param w Focus highlight object width
3831 * @param h Focus highlight object height
3832 * @param is_next @c EINA_TRUE if this request is for the new focused object,
3833 * @c EINA_FALSE if this request is for the previously focused object. This
3834 * information becomes important when the focus highlight is changed inside one
3842 * Get the 'focus_part' geometry if there is any
3844 * This queries if there is a 'focus_part' request from the edc style. If edc
3845 * style offers 'focus_part' edje data item, this function requests for the
3846 * geometry of a specific part which is described in 'focus_part' edje data.
3848 * @param obj Widget object for the focus highlight
3849 * @param x Focus highlight x coordinate
3850 * @param y Focus highlight y coordinate
3851 * @param w Focus highlight object width
3852 * @param h Focus highlight object height
3854 * x, y, w, h already contain the object's geometry. If there is a 'focus_part'
3855 * support, these values will be updated accordingly or the values will be
3856 * remained as they were.
3861 elm_widget_focus_highlight_focus_part_geometry_get(const Evas_Object *obj,
3867 Evas_Coord tx = 0, ty = 0, tw = 0, th = 0;
3868 const char *target_hl_part = NULL;
3869 const Evas_Object *edje_obj = NULL;
3871 if (obj && efl_isa(obj, EFL_CANVAS_LAYOUT_CLASS))
3874 if (!(target_hl_part = edje_object_data_get(edje_obj, "focus_part")))
3877 else if (obj && efl_isa(obj, EFL_UI_LAYOUT_BASE_CLASS))
3879 edje_obj = elm_layout_edje_get(obj);
3880 if (!(target_hl_part = elm_layout_data_get(obj, "focus_part")))
3886 edje_object_part_geometry_get(edje_obj, target_hl_part,
3887 &tx, &ty, &tw, &th);
3890 if (tw != *w) *w = tw;
3891 if (th != *h) *h = th;
3894 EOLIAN static Eina_Rect
3895 _efl_ui_widget_focus_highlight_geometry_get(const Eo *obj, Elm_Widget_Smart_Data *sd)
3897 Evas_Coord ox = 0, oy = 0, ow = 0, oh = 0;
3898 Evas_Object *scroller = (Evas_Object *)obj;
3901 evas_object_geometry_get(obj, &r.x, &r.y, &r.w, &r.h);
3902 elm_widget_focus_highlight_focus_part_geometry_get(sd->resize_obj, &r.x, &r.y, &r.w, &r.h);
3904 if (_elm_config->focus_autoscroll_mode != ELM_FOCUS_AUTOSCROLL_MODE_BRING_IN)
3909 if (_elm_scrollable_is(scroller))
3911 elm_interface_scrollable_content_viewport_geometry_get(scroller, &ox, &oy, &ow, &oh);
3915 else if ((oy + oh) < (r.y + r.h))
3916 r.y = (oy + oh - r.h);
3919 else if ((ox + ow) < (r.x + r.w))
3920 r.x = (ox + ow - r.w);
3924 scroller = elm_widget_parent_get(scroller);
3931 elm_widget_activate(Evas_Object *obj, Efl_Ui_Activate act)
3933 Evas_Object *parent;
3936 ELM_WIDGET_CHECK(obj);
3940 ret = efl_ui_widget_on_access_activate(obj, act);
3944 parent = elm_widget_parent_get(obj);
3946 elm_widget_activate(parent, act);
3954 * Sets the widget and child widget's Evas_Display_Mode.
3956 * @param obj The widget.
3957 * @param dispmode Evas_Display_Mode to set widget's mode.
3959 * Widgets are resized by several reasons.
3960 * Evas_Display_Mode can help for widgets to get one more reason of resize.
3961 * For example, elm conform widget resizes it's contents when keypad state changed.
3962 * After keypad showing, conform widget can change child's Evas_Display_Mode.
3967 elm_widget_display_mode_set(Evas_Object *obj, Evas_Display_Mode dispmode)
3969 Evas_Display_Mode prev_dispmode;
3973 prev_dispmode = evas_object_size_hint_display_mode_get(obj);
3975 if ((prev_dispmode == dispmode) ||
3976 (prev_dispmode == EVAS_DISPLAY_MODE_DONT_CHANGE)) return;
3978 evas_object_size_hint_display_mode_set(obj, dispmode);
3980 for (unsigned int i = 0; i < eina_array_count(sd->children); ++i)
3982 child = eina_array_data_get(sd->children, i);
3983 if (elm_widget_is(child))
3984 elm_widget_display_mode_set(child, dispmode);
3991 * Returns the widget's focus move policy.
3993 * @param obj The widget.
3994 * @return focus move policy of the object.
3997 EOLIAN static Efl_Ui_Focus_Move_Policy
3998 _efl_ui_widget_focus_move_policy_get(const Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd)
4000 return (Efl_Ui_Focus_Move_Policy)sd->focus_move_policy;
4006 * Sets the widget's focus move policy.
4008 * @param obj The widget.
4009 * @param policy Elm_Focus_Move_Policy to set object's focus move policy.
4013 _efl_ui_widget_focus_move_policy_set(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd, Efl_Ui_Focus_Move_Policy policy)
4015 if (sd->focus_move_policy == (Elm_Focus_Move_Policy)policy) return;
4016 sd->focus_move_policy = (Elm_Focus_Move_Policy)policy;
4020 * Returns the widget's focus_move_policy mode setting.
4022 * @param obj The widget.
4023 * @return focus_move_policy mode setting of the object.
4026 EOLIAN static Eina_Bool
4027 _efl_ui_widget_focus_move_policy_automatic_get(const Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd)
4029 return sd->focus_move_policy_auto_mode;
4035 * Sets the widget's focus_move_policy mode setting.
4036 * When widget in automatic mode, it follows the system focus_move_policy mode set by
4037 * elm_config_focus_move_policy_set().
4038 * @param obj The widget.
4039 * @param automatic EINA_TRUE for auto focus_move_policy mode. EINA_FALSE for manual.
4042 _efl_ui_widget_focus_move_policy_automatic_set(Eo *obj, Elm_Widget_Smart_Data *sd, Eina_Bool automatic)
4044 if (sd->focus_move_policy_auto_mode != automatic)
4046 sd->focus_move_policy_auto_mode = automatic;
4050 efl_ui_widget_focus_move_policy_set
4051 (obj, (Efl_Ui_Focus_Move_Policy)elm_config_focus_move_policy_get());
4059 * Sets the klass name of a widget.
4060 * @param obj The widget.
4061 * @param name Name of the klass to use.
4062 * @return Whether the name was different and thus replaced.
4065 elm_widget_theme_klass_set(Evas_Object *obj, const char *name)
4067 Elm_Widget_Smart_Data *pd = efl_data_scope_safe_get(obj, MY_CLASS);
4068 if (!pd) return EINA_FALSE;
4070 return eina_stringshare_replace(&(pd->klass), name);
4076 * Gets the klass name of a widget.
4077 * @param obj The widget.
4078 * @return The current klass name of internal canvas object.
4081 elm_widget_theme_klass_get(const Evas_Object *obj)
4083 Elm_Widget_Smart_Data *pd = efl_data_scope_safe_get(obj, MY_CLASS);
4084 if (!pd) return NULL;
4086 return (const char *)pd->klass;
4092 * Sets the element name of a widget.
4094 * @param obj The widget.
4095 * @param name Name of the element to use.
4096 * @return Whether the name was different and thus replaced.
4099 elm_widget_theme_element_set(Evas_Object *obj, const char *name)
4101 Elm_Widget_Smart_Data *pd = efl_data_scope_safe_get(obj, MY_CLASS);
4102 if (!pd) return EINA_FALSE;
4104 if (eina_streq(name, "base"))
4107 return eina_stringshare_replace(&(pd->group), name);
4113 * Gets the element name of a widget.
4114 * @param obj The widget.
4115 * @return The current element name of internal canvas object.
4118 elm_widget_theme_element_get(const Evas_Object *obj)
4120 Elm_Widget_Smart_Data *pd = efl_data_scope_safe_get(obj, MY_CLASS);
4121 if (!pd) return NULL;
4123 return (const char *)pd->group;
4129 * Sets the style name of a widget.
4131 * @param obj The widget.
4132 * @param name Name of the style to use.
4133 * @return Whether the name was different and thus replaced.
4136 elm_widget_theme_style_set(Evas_Object *obj, const char *name)
4138 Elm_Widget_Smart_Data *pd = efl_data_scope_safe_get(obj, MY_CLASS);
4139 if (!pd) return EINA_FALSE;
4141 if (eina_streq(name, "default"))
4144 return eina_stringshare_replace(&(pd->style), name);
4150 * Gets the style name of a widget.
4151 * @param obj The widget.
4152 * @return The current style name of internal canvas object.
4155 elm_widget_theme_style_get(const Evas_Object *obj)
4157 Elm_Widget_Smart_Data *pd = efl_data_scope_safe_get(obj, MY_CLASS);
4158 if (!pd) return NULL;
4160 return (const char *)pd->style;
4166 * Register sub object as a group of a widget and re-apply its theme.
4167 * @param obj The widget.
4168 * @param component A sub object to be added as an element of the widget.
4169 * @param name An element name of sub object.
4170 * @return Whether the style was successfully applied or not.
4173 elm_widget_element_update(Evas_Object *obj, Evas_Object *component, const char *name)
4175 Eina_Error ret = EFL_UI_THEME_APPLY_ERROR_NONE;
4176 Eina_Bool changed = EINA_FALSE;
4177 const char *obj_group;
4178 Eina_Stringshare *group;
4180 obj_group = elm_widget_theme_element_get(obj);
4182 group = eina_stringshare_add(name);
4184 group = eina_stringshare_printf("%s/%s", elm_widget_theme_element_get(obj), name);
4185 if (efl_isa(component, EFL_UI_WIDGET_CLASS))
4187 changed |= elm_widget_theme_klass_set(component, elm_widget_theme_klass_get(obj));
4188 changed |= elm_widget_theme_element_set(component, (const char *)group);
4189 changed |= elm_widget_theme_style_set(component, elm_widget_theme_style_get(obj));
4191 ret = efl_ui_widget_theme_apply(component);
4195 ret = elm_widget_theme_object_set(obj, component,
4196 elm_widget_theme_klass_get(obj),
4197 (const char *)group,
4198 elm_widget_theme_style_get(obj));
4200 eina_stringshare_del(group);
4206 _track_obj_del(void *data, Evas *e, Evas_Object *obj, void *event_info);
4209 _track_obj_update(Evas_Object *track, Evas_Object *obj)
4212 Evas_Coord x, y, w, h;
4213 evas_object_geometry_get(obj, &x, &y, &w, &h);
4214 evas_object_move(track, x, y);
4215 evas_object_resize(track, w, h);
4218 if (evas_object_visible_get(obj)) evas_object_show(track);
4219 else evas_object_hide(track);
4223 _track_obj_view_update(void *data, const Efl_Event *event)
4225 Elm_Widget_Item_Data *item = data;
4226 _track_obj_update(item->track_obj, event->object);
4230 _track_obj_view_del(void *data, const Efl_Event *event);
4232 EFL_CALLBACKS_ARRAY_DEFINE(tracker_callbacks,
4233 { EFL_GFX_ENTITY_EVENT_SIZE_CHANGED, _track_obj_view_update },
4234 { EFL_GFX_ENTITY_EVENT_POSITION_CHANGED, _track_obj_view_update },
4235 { EFL_GFX_ENTITY_EVENT_VISIBILITY_CHANGED, _track_obj_view_update },
4236 { EFL_EVENT_DEL, _track_obj_view_del });
4239 _track_obj_view_del(void *data, const Efl_Event *event EINA_UNUSED)
4241 Elm_Widget_Item_Data *item = data;
4243 while (evas_object_ref_get(item->track_obj) > 0)
4244 evas_object_unref(item->track_obj);
4246 evas_object_event_callback_del(item->track_obj, EVAS_CALLBACK_DEL,
4248 evas_object_del(item->track_obj);
4249 item->track_obj = NULL;
4253 _track_obj_del(void *data, Evas *e EINA_UNUSED,
4254 Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
4256 Elm_Widget_Item_Data *item = data;
4257 item->track_obj = NULL;
4259 if (!item->view) return;
4261 efl_event_callback_array_del(item->view, tracker_callbacks(), item);
4265 _elm_widget_item_signal_cb(void *data, Evas_Object *obj EINA_UNUSED, const char *emission,
4268 Elm_Widget_Item_Signal_Data *wisd = data;
4269 wisd->func(wisd->data, wisd->item, emission, source);
4273 _elm_widget_item_signal_callback_list_get(Elm_Widget_Item_Data *item, Eina_List *position)
4275 Elm_Widget_Item_Signal_Data *wisd = eina_list_data_get(position);
4278 item->signals = eina_list_remove_list(item->signals, position);
4281 if (_elm_widget_is(item->view))
4282 elm_object_signal_callback_del(item->view,
4283 wisd->emission, wisd->source,
4284 _elm_widget_item_signal_cb);
4285 else if (efl_isa(item->view, EFL_CANVAS_LAYOUT_CLASS))
4286 edje_object_signal_callback_del_full(item->view,
4287 wisd->emission, wisd->source,
4288 _elm_widget_item_signal_cb, wisd);
4290 eina_stringshare_del(wisd->emission);
4291 eina_stringshare_del(wisd->source);
4297 #define ERR_NOT_SUPPORTED(item, method) ERR("%s does not support %s API.", elm_widget_type_get(item->widget), method);
4300 _efl_del_cb(void *data EINA_UNUSED, const Efl_Event *event)
4302 Elm_Widget_Item_Data *item = efl_data_scope_get(event->object, ELM_WIDGET_ITEM_CLASS);
4303 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
4305 item->del_func((void *) WIDGET_ITEM_DATA_GET(event->object), item->widget, item->eo_obj);
4311 * Allocate a new Elm_Widget_Item-derived structure.
4313 * The goal of this structure is to provide common ground for actions
4314 * that a widget item have, such as the owner widget, callback to
4315 * notify deletion, data pointer and maybe more.
4317 * @param widget the owner widget that holds this item, must be an elm_widget!
4318 * @param alloc_size any number greater than sizeof(Elm_Widget_Item) that will
4319 * be used to allocate memory.
4321 * @return allocated memory that is already zeroed out, or NULL on errors.
4323 * @see elm_widget_item_new() convenience macro.
4324 * @see elm_widget_item_del() to release memory.
4328 _elm_widget_item_efl_object_constructor(Eo *eo_item, Elm_Widget_Item_Data *item)
4330 Evas_Object *widget;
4331 widget = efl_parent_get(eo_item);
4333 if (!_elm_widget_is(widget))
4339 eo_item = efl_constructor(efl_super(eo_item, ELM_WIDGET_ITEM_CLASS));
4341 EINA_MAGIC_SET(item, ELM_WIDGET_ITEM_MAGIC);
4343 item->widget = widget;
4344 item->eo_obj = eo_item;
4345 //TIZEN_ONLY(20170717) : expose highlight information on atspi
4346 item->can_highlight = EINA_TRUE;
4348 efl_event_callback_add(eo_item, EFL_EVENT_DEL, _efl_del_cb, NULL);
4354 _elm_widget_item_efl_object_destructor(Eo *eo_item, Elm_Widget_Item_Data *item)
4356 Elm_Translate_String_Data *ts;
4358 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
4360 eina_stringshare_del(item->style);
4361 eina_stringshare_del(item->access_info);
4362 eina_stringshare_del(item->accessible_name);
4364 while (item->signals)
4365 _elm_widget_item_signal_callback_list_get(item, item->signals);
4367 while (item->translate_strings)
4369 ts = EINA_INLIST_CONTAINER_GET(item->translate_strings,
4370 Elm_Translate_String_Data);
4371 eina_stringshare_del(ts->id);
4372 eina_stringshare_del(ts->domain);
4373 eina_stringshare_del(ts->string);
4374 item->translate_strings = eina_inlist_remove(item->translate_strings,
4375 item->translate_strings);
4378 eina_hash_free(item->labels);
4380 //TIZEN_ONLY : elm_widget_item: add at-spi name setter
4381 efl_access_object_description_set(eo_item, NULL);
4382 efl_access_object_i18n_name_set(eo_item, NULL);
4384 efl_access_object_description_cb_set(eo_item, NULL, NULL);
4385 efl_access_object_name_cb_set(eo_item, NULL, NULL);
4387 //TIZEN_ONLY(20170405) Add gesture method to accessible interface
4388 efl_access_object_gesture_cb_set(eo_item, NULL, NULL);
4390 //TIZEN_ONLY : elm_widget_item: add at-spi name setter
4391 efl_access_object_translation_domain_set(eo_item, NULL);
4392 efl_access_object_relationships_clear(eo_item);
4395 efl_access_object_attributes_clear(eo_item);
4397 // TIZEN_ONLY(20150709) : atspi relations api
4398 if (item->atspi_custom_relations)
4399 efl_access_relation_set_free(&item->atspi_custom_relations);
4402 //TIZEN_ONLY(20150731) : add i18n support for name and description
4403 if (item->atspi_translation_domain)
4404 eina_stringshare_del(item->atspi_translation_domain);
4407 //TIZEN_ONLY(20150713) : add widget_item name setter
4409 eina_stringshare_del(item->name);
4412 /***********************************************************************************
4413 * TIZEN_ONLY_FEATURE: apply Tizen's color_class features. *
4414 ***********************************************************************************/
4415 if (item->color_classes)
4416 ELM_SAFE_FREE(item->color_classes, eina_hash_free);
4421 EINA_MAGIC_SET(item, EINA_MAGIC_NONE);
4423 efl_destructor(efl_super(eo_item, ELM_WIDGET_ITEM_CLASS));
4429 * Releases widget item memory, calling back item_del_pre_hook() and
4430 * item_del_cb() if they exist.
4432 * @param item a valid #Elm_Widget_Item to be deleted.
4434 * If there is an Elm_Widget_Item::del_cb, then it will be called prior
4435 * to memory release. Note that elm_widget_item_pre_notify_del() calls
4436 * this function and then unset it, thus being useful for 2 step
4437 * cleanup whenever the del_cb may use any of the data that must be
4438 * deleted from item.
4440 * The Elm_Widget_Item::view will be deleted (evas_object_del()) if it
4443 * Note that if item_del_pre_hook() returns @c EINA_TRUE, item free will be
4444 * deferred, or item will be freed here if it returns @c EINA_FALSE.
4446 * @see elm_widget_item_del() convenience macro.
4450 _elm_widget_item_efl_object_invalidate(Eo *eo_item, Elm_Widget_Item_Data *item)
4454 //Widget item delete callback
4455 elm_wdg_item_del_pre(item->eo_obj);
4457 // TIZEN_ONLY(20200109): if item deletion process need to be intercepted for
4458 // provide animation on the view object, widget need to add efl_del_intercept_set()
4459 // and clear the view after all animation processed.
4460 if (!efl_del_intercept_get(eo_item))
4463 if (item->view) efl_wref_del(item->view, &item->view);
4464 // FIXME: Is view an Efl.Ui or a legacy object ?
4465 evas_object_del(view);
4469 efl_invalidate(efl_super(eo_item, ELM_WIDGET_ITEM_CLASS));
4473 _elm_widget_item_del_pre(Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item EINA_UNUSED)
4480 * Notify object will be deleted without actually deleting it.
4482 * This function will callback Elm_Widget_Item::del_cb if it is set
4483 * and then unset it so it is not called twice (ie: from
4484 * elm_widget_item_del()).
4486 * @param item a valid #Elm_Widget_Item to be notified
4487 * @see elm_widget_item_pre_notify_del() convenience macro.
4491 _elm_widget_item_pre_notify_del(Eo *eo_item, Elm_Widget_Item_Data *item)
4493 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
4494 if (!item->del_func) return;
4495 item->del_func((void *)WIDGET_ITEM_DATA_GET(eo_item), item->widget, item->eo_obj);
4496 item->del_func = NULL;
4502 * Set the function to notify when item is being deleted.
4504 * This function will complain if there was a callback set already,
4505 * however it will set the new one.
4507 * The callback will be called from elm_widget_item_pre_notify_del()
4508 * or elm_widget_item_del() will be called with:
4509 * - data: the Elm_Widget_Item::data value.
4510 * - obj: the Elm_Widget_Item::widget evas object.
4511 * - event_info: the item being deleted.
4513 * @param item a valid #Elm_Widget_Item to be notified
4514 * @see elm_widget_item_del_cb_set() convenience macro.
4518 _elm_widget_item_del_cb_set(Eo *eo_item EINA_UNUSED,
4519 Elm_Widget_Item_Data *item,
4522 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
4523 ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
4525 if ((item->del_func) && (item->del_func != func))
4526 WRN("You're replacing a previously set del_cb %p of item %p with %p",
4527 item->del_func, item->eo_obj, func);
4529 item->del_func = func;
4535 * Get owner widget of this item.
4537 * @param item a valid #Elm_Widget_Item to get data from.
4538 * @return owner widget of this item.
4541 EOLIAN static Evas_Object *
4542 _elm_widget_item_widget_get(const Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item)
4544 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item, NULL);
4545 ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item, NULL);
4547 return item->widget;
4551 _elm_widget_onscreen_is(const Evas_Object *widget)
4553 Evas_Object *parent = (Evas_Object *)widget;
4554 Eina_Rectangle r1, r2;
4556 Evas *evas = evas_object_evas_get(widget);
4557 if (!evas) return EINA_FALSE;
4559 evas_object_geometry_get(widget, &r1.x, &r1.y, &r1.w, &r1.h);
4560 if (eina_rectangle_is_empty(&r1))
4563 // window does not have to check viewport and geometry
4564 if (efl_isa(widget, EFL_UI_WIN_CLASS))
4567 // check if on canvas
4568 evas_output_viewport_get(evas, &r2.x, &r2.y, &r2.w, &r2.h);
4569 if (!eina_rectangles_intersect(&r1, &r2))
4572 // check if inside scrollable parent viewport
4574 parent = elm_widget_parent_get(parent);
4575 if (parent && !evas_object_visible_get(parent))
4577 if (parent && efl_isa(parent, ELM_INTERFACE_SCROLLABLE_MIXIN))
4579 evas_object_geometry_get(parent, &r2.x, &r2.y, &r2.w, &r2.h);
4580 if (!eina_rectangles_intersect(&r1, &r2))
4583 } while (parent && (parent != elm_widget_top_get(widget)));
4589 _elm_widget_item_onscreen_is(const Elm_Object_Item *item)
4591 Eina_Rectangle r1, r2;
4592 Elm_Widget_Item_Data *id = efl_data_scope_get(item, ELM_WIDGET_ITEM_CLASS);
4593 if (!id || !id->view) return EINA_FALSE;
4595 if (!evas_object_visible_get(id->view))
4598 if (!_elm_widget_onscreen_is(id->widget))
4601 evas_object_geometry_get(id->view, &r1.x, &r1.y, &r1.w, &r1.h);
4602 if (eina_rectangle_is_empty(&r1))
4605 evas_object_geometry_get(id->widget, &r2.x, &r2.y, &r2.w, &r2.h);
4606 if (!eina_rectangles_intersect(&r1, &r2))
4613 _elm_widget_accessible_plain_name_get(const Evas_Object *obj, const char* name)
4615 char *accessible_plain_name;
4617 API_ENTRY return NULL;
4619 accessible_plain_name = _elm_util_mkup_to_text(name);
4620 eina_stringshare_del(sd->accessible_name);
4621 sd->accessible_name = eina_stringshare_add(accessible_plain_name);
4622 free(accessible_plain_name);
4623 return sd->accessible_name;
4627 _elm_widget_item_accessible_plain_name_get(const Elm_Object_Item *item, const char* name)
4629 char *accessible_plain_name;
4631 Elm_Widget_Item_Data *id = efl_data_scope_get(item, ELM_WIDGET_ITEM_CLASS);
4632 if (!id) return NULL;
4634 accessible_plain_name = _elm_util_mkup_to_text(name);
4635 eina_stringshare_del(id->accessible_name);
4636 id->accessible_name = eina_stringshare_add(accessible_plain_name);
4637 free(accessible_plain_name);
4638 return id->accessible_name;
4641 EOLIAN static Efl_Access_State_Set
4642 _elm_widget_item_efl_access_object_state_set_get(const Eo *eo_item, Elm_Widget_Item_Data *item)
4644 Efl_Access_State_Set states = 0;
4646 // TIZEN_ONLY(20171114) Accessibility Highlight Frame added
4647 // //TIZEN_ONLY(20171108): bring HIGHLIGHT related changes
4648 // Evas_Object *win = elm_widget_top_get(item->widget);
4649 // if (win && efl_isa(win, EFL_UI_WIN_CLASS))
4651 // if (_elm_win_accessibility_highlight_get(win) == item->view)
4652 // STATE_TYPE_SET(states, ELM_ATSPI_STATE_HIGHLIGHTED);
4654 // STATE_TYPE_SET(states, ELM_ATSPI_STATE_HIGHLIGHTABLE);
4658 STATE_TYPE_SET(states, EFL_ACCESS_STATE_TYPE_FOCUSABLE);
4660 if (elm_object_item_focus_get(eo_item))
4661 STATE_TYPE_SET(states, EFL_ACCESS_STATE_TYPE_FOCUSED);
4662 if (!elm_object_item_disabled_get(eo_item))
4664 STATE_TYPE_SET(states, EFL_ACCESS_STATE_TYPE_ENABLED);
4665 STATE_TYPE_SET(states, EFL_ACCESS_STATE_TYPE_SENSITIVE);
4666 STATE_TYPE_SET(states, EFL_ACCESS_STATE_TYPE_VISIBLE);
4668 if (_elm_widget_item_onscreen_is(eo_item))
4669 STATE_TYPE_SET(states, EFL_ACCESS_STATE_TYPE_SHOWING);
4671 //TIZEN_ONLY(20170207) : [ATSPI] enhance expose highlight information on atspi
4672 /* unrealized genlist item does not have item->view,
4673 and item cannot change its visibility, only widget can change the visibility */
4674 if (evas_object_visible_get(item->widget))
4675 STATE_TYPE_SET(states, EFL_ACCESS_STATE_TYPE_VISIBLE);
4678 //TIZEN_ONLY(20170717) : expose highlight information on atspi
4679 if (_elm_widget_item_highlightable((Eo *)eo_item) && _accessible_object_on_scroll_is(item->view))
4680 STATE_TYPE_SET(states, EFL_ACCESS_STATE_TYPE_HIGHLIGHTABLE);
4682 STATE_TYPE_UNSET(states, EFL_ACCESS_STATE_TYPE_HIGHLIGHTABLE);
4684 if (_elm_object_accessibility_currently_highlighted_get() == (void*)item->eo_obj)
4685 STATE_TYPE_SET(states, EFL_ACCESS_STATE_TYPE_HIGHLIGHTED);
4691 elm_object_item_data_set(Elm_Object_Item *it, void *data)
4693 WIDGET_ITEM_DATA_SET(it, data);
4697 elm_object_item_data_get(const Elm_Object_Item *it)
4699 return (void *) WIDGET_ITEM_DATA_GET(it);
4703 _elm_widget_item_disabled_set(Eo *eo_item EINA_UNUSED,
4704 Elm_Widget_Item_Data *item,
4707 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
4708 ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
4710 if (item->disabled == disabled) return;
4711 item->disabled = !!disabled;
4712 elm_wdg_item_disable(item->eo_obj);
4715 EOLIAN static Eina_Bool
4716 _elm_widget_item_disabled_get(const Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item)
4718 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item, EINA_FALSE);
4719 return item->disabled;
4723 _elm_widget_item_style_set(Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item, const char *style)
4725 eina_stringshare_replace(&item->style, style);
4728 EOLIAN static const char *
4729 _elm_widget_item_style_get(const Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item)
4735 _elm_widget_item_disable(Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item EINA_UNUSED)
4740 _elm_widget_item_item_focus_set(Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item, Eina_Bool focused EINA_UNUSED)
4742 ERR_NOT_SUPPORTED(item, "elm_object_item_focus_set");
4745 EOLIAN static Eina_Bool
4746 _elm_widget_item_item_focus_get(const Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item)
4748 ERR_NOT_SUPPORTED(item, "elm_object_item_focus_get");
4753 _elm_widget_item_domain_translatable_part_text_set(Eo *eo_item EINA_UNUSED,
4754 Elm_Widget_Item_Data *item,
4759 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
4760 ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
4761 Elm_Translate_String_Data *ts;
4765 _part_text_translatable_set(&item->translate_strings, part, EINA_FALSE,
4770 ts = _part_text_translatable_set(&item->translate_strings, part,
4771 EINA_TRUE, EINA_FALSE);
4773 if (!ts->string) ts->string = eina_stringshare_add(label);
4774 else eina_stringshare_replace(&ts->string, label);
4775 if (!ts->domain) ts->domain = eina_stringshare_add(domain);
4776 else eina_stringshare_replace(&ts->domain, domain);
4778 if (label[0]) label = dgettext(domain, label);
4781 item->on_translate = EINA_TRUE;
4782 elm_wdg_item_part_text_set(item->eo_obj, part, label);
4783 item->on_translate = EINA_FALSE;
4786 EOLIAN static const char *
4787 _elm_widget_item_translatable_part_text_get(const Eo *eo_item EINA_UNUSED,
4788 Elm_Widget_Item_Data *item,
4791 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item, NULL);
4792 ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item, NULL);
4794 Elm_Translate_String_Data *ts;
4795 ts = _translate_string_data_get(item->translate_strings, part);
4796 if (ts) return ts->string;
4801 _elm_widget_item_domain_part_text_translatable_set(Eo *eo_item EINA_UNUSED,
4802 Elm_Widget_Item_Data *item,
4805 Eina_Bool translatable)
4807 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
4808 ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
4809 Elm_Translate_String_Data *ts;
4812 ts = _part_text_translatable_set(&item->translate_strings, part,
4813 translatable, EINA_TRUE);
4815 if (!ts->domain) ts->domain = eina_stringshare_add(domain);
4816 else eina_stringshare_replace(&ts->domain, domain);
4818 text = elm_wdg_item_part_text_get(item->eo_obj, part);
4820 if (!text || !text[0]) return;
4822 if (!ts->string) ts->string = eina_stringshare_add(text);
4824 //Try to translate text since we don't know the text is already translated.
4826 text = dgettext(domain, text);
4828 item->on_translate = EINA_TRUE;
4829 elm_wdg_item_part_text_set(item->eo_obj, part, text);
4830 item->on_translate = EINA_FALSE;
4834 _elm_widget_item_track_cancel(Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item)
4836 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
4837 ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
4839 if (!item->track_obj) return;
4841 while (evas_object_ref_get(item->track_obj) > 0)
4842 evas_object_unref(item->track_obj);
4844 evas_object_del(item->track_obj);
4847 EOLIAN static Evas_Object *
4848 _elm_widget_item_track(Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item)
4850 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item, NULL);
4851 ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item, NULL);
4853 if (item->track_obj)
4855 evas_object_ref(item->track_obj);
4856 return item->track_obj;
4861 WRN("view obj of the item(%p) is invalid. Please make sure the view obj is created!", item);
4865 Evas_Object *track =
4866 evas_object_rectangle_add(evas_object_evas_get(item->widget));
4867 evas_object_color_set(track, 0, 0, 0, 0);
4868 evas_object_pass_events_set(track, EINA_TRUE);
4869 _track_obj_update(track, item->view);
4870 evas_object_event_callback_add(track, EVAS_CALLBACK_DEL, _track_obj_del,
4873 efl_event_callback_array_add(item->view, tracker_callbacks(), item);
4875 evas_object_ref(track);
4877 item->track_obj = track;
4883 _elm_widget_item_untrack(Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item)
4885 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
4886 ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
4888 if (!item->track_obj) return;
4889 evas_object_unref(item->track_obj);
4891 if (evas_object_ref_get(item->track_obj) == 0)
4892 evas_object_del(item->track_obj);
4896 _elm_widget_item_track_get(const Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item)
4898 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item, 0);
4899 ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item, 0);
4901 if (!item->track_obj) return 0;
4902 return evas_object_ref_get(item->track_obj);
4905 typedef struct _Elm_Widget_Item_Tooltip Elm_Widget_Item_Tooltip;
4907 struct _Elm_Widget_Item_Tooltip
4909 Elm_Widget_Item_Data *item;
4910 Elm_Tooltip_Item_Content_Cb func;
4911 Evas_Smart_Cb del_cb;
4915 static Evas_Object *
4916 _elm_widget_item_tooltip_label_create(void *data,
4917 Evas_Object *obj EINA_UNUSED,
4918 Evas_Object *tooltip,
4919 void *item EINA_UNUSED)
4921 Evas_Object *label = elm_label_add(tooltip);
4924 elm_object_style_set(label, "tooltip");
4925 elm_object_text_set(label, data);
4929 static Evas_Object *
4930 _elm_widget_item_tooltip_trans_label_create(void *data,
4931 Evas_Object *obj EINA_UNUSED,
4932 Evas_Object *tooltip,
4933 void *item EINA_UNUSED)
4935 Evas_Object *label = elm_label_add(tooltip);
4938 elm_object_style_set(label, "tooltip");
4939 elm_object_translatable_text_set(label, data);
4944 _elm_widget_item_tooltip_label_del_cb(void *data,
4945 Evas_Object *obj EINA_UNUSED,
4946 void *event_info EINA_UNUSED)
4948 eina_stringshare_del(data);
4954 * Set the text to be shown in the widget item.
4956 * @param item Target item
4957 * @param text The text to set in the content
4959 * Setup the text as tooltip to object. The item can have only one tooltip,
4960 * so any previous tooltip data is removed.
4965 _elm_widget_item_tooltip_text_set(Eo *eo_item EINA_UNUSED,
4966 Elm_Widget_Item_Data *item EINA_UNUSED,
4969 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
4970 ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
4971 EINA_SAFETY_ON_NULL_RETURN(text);
4973 text = eina_stringshare_add(text);
4974 elm_wdg_item_tooltip_content_cb_set(item->eo_obj, _elm_widget_item_tooltip_label_create, text, _elm_widget_item_tooltip_label_del_cb);
4978 _elm_widget_item_tooltip_translatable_text_set(Eo *eo_item EINA_UNUSED,
4979 Elm_Widget_Item_Data *item EINA_UNUSED,
4982 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
4983 ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
4984 EINA_SAFETY_ON_NULL_RETURN(text);
4986 text = eina_stringshare_add(text);
4987 elm_wdg_item_tooltip_content_cb_set(item->eo_obj, _elm_widget_item_tooltip_trans_label_create, text, _elm_widget_item_tooltip_label_del_cb);
4990 static Evas_Object *
4991 _elm_widget_item_tooltip_create(void *data,
4993 Evas_Object *tooltip)
4995 Elm_Widget_Item_Tooltip *wit = data;
4996 return wit->func((void *)wit->data, obj, tooltip, wit->item->eo_obj);
5000 _elm_widget_item_tooltip_del_cb(void *data,
5002 void *event_info EINA_UNUSED)
5004 Elm_Widget_Item_Tooltip *wit = data;
5005 if (wit->del_cb) wit->del_cb((void *)wit->data, obj, wit->item->eo_obj);
5012 * Set the content to be shown in the tooltip item
5014 * Setup the tooltip to item. The item can have only one tooltip,
5015 * so any previous tooltip data is removed. @p func(with @p data) will
5016 * be called every time that need show the tooltip and it should
5017 * return a valid Evas_Object. This object is then managed fully by
5018 * tooltip system and is deleted when the tooltip is gone.
5020 * @param item the widget item being attached a tooltip.
5021 * @param func the function used to create the tooltip contents.
5022 * @param data what to provide to @a func as callback data/context.
5023 * @param del_cb called when data is not needed anymore, either when
5024 * another callback replaces @func, the tooltip is unset with
5025 * elm_widget_item_tooltip_unset() or the owner @a item
5026 * dies. This callback receives as the first parameter the
5027 * given @a data, and @c event_info is the item.
5032 _elm_widget_item_tooltip_content_cb_set(Eo *eo_item EINA_UNUSED,
5033 Elm_Widget_Item_Data *item,
5034 Elm_Tooltip_Item_Content_Cb func,
5036 Evas_Smart_Cb del_cb)
5038 Elm_Widget_Item_Tooltip *wit;
5040 ELM_WIDGET_ITEM_CHECK_OR_GOTO(item, error_noitem);
5041 //ELM_WIDGET_ITEM_RETURN_IF_GOTO(item, error_noitem);
5045 elm_wdg_item_tooltip_unset(item->eo_obj);
5049 wit = ELM_NEW(Elm_Widget_Item_Tooltip);
5050 if (!wit) goto error;
5054 wit->del_cb = del_cb;
5056 elm_object_sub_tooltip_content_cb_set
5057 (item->view, item->widget, _elm_widget_item_tooltip_create, wit,
5058 _elm_widget_item_tooltip_del_cb);
5063 if (del_cb) del_cb((void *)data, NULL, item);
5066 if (del_cb) del_cb((void *)data, item->widget, item);
5072 * Unset tooltip from item
5074 * @param item widget item to remove previously set tooltip.
5076 * Remove tooltip from item. The callback provided as del_cb to
5077 * elm_widget_item_tooltip_content_cb_set() will be called to notify
5078 * it is not used anymore.
5080 * @see elm_widget_item_tooltip_content_cb_set()
5085 _elm_widget_item_tooltip_unset(Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item)
5087 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
5088 ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
5090 elm_object_tooltip_unset(item->view);
5096 * Sets a different style for this item tooltip.
5098 * @note before you set a style you should define a tooltip with
5099 * elm_widget_item_tooltip_content_cb_set() or
5100 * elm_widget_item_tooltip_text_set()
5102 * @param item widget item with tooltip already set.
5103 * @param style the theme style to use (default, transparent, ...)
5108 _elm_widget_item_tooltip_style_set(Eo *eo_item EINA_UNUSED,
5109 Elm_Widget_Item_Data *item,
5112 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
5113 ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
5115 elm_object_tooltip_style_set(item->view, style);
5118 EOLIAN static Eina_Bool
5119 _elm_widget_item_tooltip_window_mode_set(Eo *eo_item EINA_UNUSED,
5120 Elm_Widget_Item_Data *item,
5123 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item, EINA_FALSE);
5124 ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item, EINA_FALSE);
5126 return elm_object_tooltip_window_mode_set(item->view, disable);
5129 EOLIAN static Eina_Bool
5130 _elm_widget_item_tooltip_window_mode_get(const Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item)
5132 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item, EINA_FALSE);
5133 ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item, EINA_FALSE);
5135 return elm_object_tooltip_window_mode_get(item->view);
5141 * Get the style for this item tooltip.
5143 * @param item widget item with tooltip already set.
5144 * @return style the theme style in use, defaults to "default". If the
5145 * object does not have a tooltip set, then NULL is returned.
5149 EOLIAN static const char *
5150 _elm_widget_item_tooltip_style_get(const Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item)
5152 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item, NULL);
5154 return elm_object_tooltip_style_get(item->view);
5158 _elm_widget_item_cursor_set(Eo *eo_item EINA_UNUSED,
5159 Elm_Widget_Item_Data *item,
5162 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
5163 ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
5165 elm_object_sub_cursor_set(item->view, item->widget, cursor);
5168 EOLIAN static const char *
5169 _elm_widget_item_cursor_get(const Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item)
5171 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item, NULL);
5172 return elm_object_sub_cursor_get(item->view);
5176 _elm_widget_item_cursor_unset(Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item)
5178 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
5179 ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
5181 elm_object_cursor_unset(item->view);
5187 * Sets a different style for this item cursor.
5189 * @note before you set a style you should define a cursor with
5190 * elm_widget_item_cursor_set()
5192 * @param item widget item with cursor already set.
5193 * @param style the theme style to use (default, transparent, ...)
5198 _elm_widget_item_cursor_style_set(Eo *eo_item EINA_UNUSED,
5199 Elm_Widget_Item_Data *item,
5202 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
5203 ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
5205 elm_object_sub_cursor_style_set(item->view, style);
5211 * Get the style for this item cursor.
5213 * @param item widget item with cursor already set.
5214 * @return style the theme style in use, defaults to "default". If the
5215 * object does not have a cursor set, then NULL is returned.
5219 EOLIAN static const char *
5220 _elm_widget_item_cursor_style_get(const Eo *eo_item EINA_UNUSED,
5221 Elm_Widget_Item_Data *item)
5223 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item, NULL);
5224 return elm_object_sub_cursor_style_get(item->view);
5230 * Set if the cursor set should be searched on the theme or should use
5231 * the provided by the engine, only.
5233 * @note before you set if should look on theme you should define a cursor
5234 * with elm_object_cursor_set(). By default it will only look for cursors
5235 * provided by the engine.
5237 * @param item widget item with cursor already set.
5238 * @param engine_only boolean to define it cursors should be looked only
5239 * between the provided by the engine or searched on widget's theme as well.
5244 _elm_widget_item_cursor_engine_only_set(Eo *eo_item EINA_UNUSED,
5245 Elm_Widget_Item_Data *item,
5246 Eina_Bool engine_only)
5248 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
5249 ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
5251 elm_object_sub_cursor_theme_search_enabled_set(item->view, !engine_only);
5257 * Get the cursor engine only usage for this item cursor.
5259 * @param item widget item with cursor already set.
5260 * @return engine_only boolean to define it cursors should be looked only
5261 * between the provided by the engine or searched on widget's theme as well. If
5262 * the object does not have a cursor set, then EINA_FALSE is returned.
5266 EOLIAN static Eina_Bool
5267 _elm_widget_item_cursor_engine_only_get(const Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item)
5269 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item, EINA_FALSE);
5270 return !elm_object_sub_cursor_theme_search_enabled_get(item->view);
5274 _elm_widget_item_part_content_set(Eo *eo_item EINA_UNUSED,
5275 Elm_Widget_Item_Data *item,
5276 const char *part EINA_UNUSED,
5277 Evas_Object *content EINA_UNUSED)
5279 ERR_NOT_SUPPORTED(item, "elm_object_part_content_set()");
5282 EOLIAN static Evas_Object *
5283 _elm_widget_item_part_content_get(const Eo *eo_item EINA_UNUSED,
5284 Elm_Widget_Item_Data *item,
5285 const char *part EINA_UNUSED)
5287 ERR_NOT_SUPPORTED(item, "elm_object_part_content_get()");
5291 EOLIAN static Evas_Object *
5292 _elm_widget_item_part_content_unset(Eo *eo_item EINA_UNUSED,
5293 Elm_Widget_Item_Data *item,
5294 const char *part EINA_UNUSED)
5296 ERR_NOT_SUPPORTED(item, "elm_object_part_content_unset()");
5301 _elm_widget_item_part_text_set(Eo *eo_item EINA_UNUSED,
5302 Elm_Widget_Item_Data *item,
5303 const char *part EINA_UNUSED,
5304 const char *label EINA_UNUSED)
5306 ERR_NOT_SUPPORTED(item, "elm_object_part_text_set()");
5309 EOLIAN static const char *
5310 _elm_widget_item_part_text_get(const Eo *eo_item EINA_UNUSED,
5311 Elm_Widget_Item_Data *item,
5312 const char *part EINA_UNUSED)
5314 ERR_NOT_SUPPORTED(item, "elm_object_part_text_get()");
5319 _elm_widget_item_part_text_custom_free(void *data)
5321 Elm_Label_Data *label;
5323 eina_stringshare_del(label->part);
5324 eina_stringshare_del(label->text);
5329 _elm_widget_item_part_text_custom_set(Eo *eo_item EINA_UNUSED,
5330 Elm_Widget_Item_Data *item,
5334 Elm_Label_Data *label;
5335 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
5336 ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
5340 eina_hash_stringshared_new(_elm_widget_item_part_text_custom_free);
5341 label = eina_hash_find(item->labels, part);
5344 label = malloc(sizeof(Elm_Label_Data));
5347 ERR("Failed to allocate memory");
5350 label->part = eina_stringshare_add(part);
5351 label->text = eina_stringshare_add(text);
5352 eina_hash_add(item->labels, part, label);
5355 eina_stringshare_replace(&label->text, text);
5358 EOLIAN static const char *
5359 _elm_widget_item_part_text_custom_get(const Eo *eo_item EINA_UNUSED,
5360 Elm_Widget_Item_Data *item,
5363 Elm_Label_Data *label;
5364 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item, NULL);
5365 label = eina_hash_find(item->labels, part);
5366 return label ? label->text : NULL;
5370 _elm_widget_item_part_text_custom_foreach(const Eina_Hash *labels EINA_UNUSED,
5371 const void *key EINA_UNUSED,
5375 Elm_Label_Data *label;
5376 Elm_Widget_Item_Data *item;
5380 elm_wdg_item_part_text_set(item->eo_obj, label->part, label->text);
5386 _elm_widget_item_part_text_custom_update(Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item)
5388 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
5389 ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
5391 eina_hash_foreach(item->labels,
5392 _elm_widget_item_part_text_custom_foreach, item);
5396 _elm_widget_item_signal_emit(Eo *eo_item EINA_UNUSED,
5397 Elm_Widget_Item_Data *item EINA_UNUSED,
5398 const char *emission EINA_UNUSED,
5399 const char *source EINA_UNUSED)
5405 _elm_widget_item_signal_callback_add(Eo *eo_item,
5406 Elm_Widget_Item_Data *item,
5407 const char *emission,
5409 Elm_Object_Item_Signal_Cb func,
5412 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
5413 ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
5414 EINA_SAFETY_ON_NULL_RETURN(func);
5416 Elm_Widget_Item_Signal_Data *wisd;
5418 wisd = malloc(sizeof(Elm_Widget_Item_Signal_Data));
5421 wisd->item = eo_item;
5422 wisd->func = (Elm_Widget_Item_Signal_Cb)func;
5424 wisd->emission = eina_stringshare_add(emission);
5425 wisd->source = eina_stringshare_add(source);
5427 if (_elm_widget_is(item->view))
5428 elm_object_signal_callback_add(item->view, emission, source, _elm_widget_item_signal_cb, wisd);
5429 else if (efl_isa(item->view, EFL_CANVAS_LAYOUT_CLASS))
5430 edje_object_signal_callback_add(item->view, emission, source, _elm_widget_item_signal_cb, wisd);
5433 WRN("The %s widget item doesn't support signal callback add!",
5434 efl_class_name_get(efl_class_get(item->widget)));
5439 item->signals = eina_list_append(item->signals, wisd);
5442 EOLIAN static void *
5443 _elm_widget_item_signal_callback_del(Eo *eo_item EINA_UNUSED,
5444 Elm_Widget_Item_Data *item,
5445 const char *emission,
5447 Elm_Object_Item_Signal_Cb func)
5449 Elm_Widget_Item_Signal_Data *wisd;
5452 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item, NULL);
5453 ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item, NULL);
5454 EINA_SAFETY_ON_NULL_RETURN_VAL(func, NULL);
5456 EINA_LIST_FOREACH(item->signals, l, wisd)
5458 if ((wisd->func == (Elm_Widget_Item_Signal_Cb)func) &&
5459 !strcmp(wisd->emission, emission) &&
5460 !strcmp(wisd->source, source))
5461 return _elm_widget_item_signal_callback_list_get(item, l);
5470 _elm_widget_item_access_info_set(Eo *eo_item EINA_UNUSED,
5471 Elm_Widget_Item_Data *item,
5474 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
5475 ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
5477 eina_stringshare_del(item->access_info);
5478 if (!txt) item->access_info = NULL;
5479 else item->access_info = eina_stringshare_add(txt);
5483 _elm_widget_item_translate(Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item)
5485 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
5486 ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
5489 Elm_Translate_String_Data *ts;
5490 EINA_INLIST_FOREACH(item->translate_strings, ts)
5492 if (!ts->string) continue;
5493 const char *s = dgettext(ts->domain, ts->string);
5494 item->on_translate = EINA_TRUE;
5495 elm_wdg_item_part_text_set(item->eo_obj, ts->id, s);
5496 item->on_translate = EINA_FALSE;
5502 _elm_widget_item_access_order_set(Eo *eo_item EINA_UNUSED,
5503 Elm_Widget_Item_Data *item,
5506 _elm_access_widget_item_access_order_set(item, objs);
5509 EOLIAN static const Eina_List *
5510 _elm_widget_item_access_order_get(const Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item)
5512 return _elm_access_widget_item_access_order_get(item);
5516 _elm_widget_item_access_order_unset(Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item)
5518 _elm_access_widget_item_access_order_unset(item);
5521 EOLIAN static Evas_Object*
5522 _elm_widget_item_access_register(Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item)
5524 _elm_access_widget_item_register(item);
5525 return item->access_obj;
5529 _elm_widget_item_access_unregister(Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item)
5531 _elm_access_widget_item_unregister(item);
5534 EOLIAN static Evas_Object*
5535 _elm_widget_item_access_object_get(const Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item)
5537 return item->access_obj;
5540 EOLIAN static Evas_Object *
5541 _elm_widget_item_focus_next_object_get(const Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item, Elm_Focus_Direction dir)
5543 Evas_Object *ret = NULL;
5545 if (dir == ELM_FOCUS_PREVIOUS)
5546 ret = item->focus_previous;
5547 else if (dir == ELM_FOCUS_NEXT)
5548 ret = item->focus_next;
5549 else if (dir == ELM_FOCUS_UP)
5550 ret = item->focus_up;
5551 else if (dir == ELM_FOCUS_DOWN)
5552 ret = item->focus_down;
5553 else if (dir == ELM_FOCUS_RIGHT)
5554 ret = item->focus_right;
5555 else if (dir == ELM_FOCUS_LEFT)
5556 ret = item->focus_left;
5562 _elm_widget_item_focus_next_object_set(Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item, Evas_Object *next, Elm_Focus_Direction dir)
5564 if (dir == ELM_FOCUS_PREVIOUS)
5565 item->focus_previous = next;
5566 else if (dir == ELM_FOCUS_NEXT)
5567 item->focus_next = next;
5568 else if (dir == ELM_FOCUS_UP)
5569 item->focus_up = next;
5570 else if (dir == ELM_FOCUS_DOWN)
5571 item->focus_down = next;
5572 else if (dir == ELM_FOCUS_RIGHT)
5573 item->focus_right = next;
5574 else if (dir == ELM_FOCUS_LEFT)
5575 item->focus_left = next;
5578 EOLIAN static Elm_Object_Item*
5579 _elm_widget_item_focus_next_item_get(const Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item, Elm_Focus_Direction dir)
5581 Elm_Object_Item *ret = NULL;
5583 if (dir == ELM_FOCUS_PREVIOUS)
5584 ret = item->item_focus_previous;
5585 else if (dir == ELM_FOCUS_NEXT)
5586 ret = item->item_focus_next;
5587 else if (dir == ELM_FOCUS_UP)
5588 ret = item->item_focus_up;
5589 else if (dir == ELM_FOCUS_DOWN)
5590 ret = item->item_focus_down;
5591 else if (dir == ELM_FOCUS_RIGHT)
5592 ret = item->item_focus_right;
5593 else if (dir == ELM_FOCUS_LEFT)
5594 ret = item->item_focus_left;
5600 _elm_widget_item_focus_next_item_set(Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item, Elm_Object_Item *next_item, Elm_Focus_Direction dir)
5602 if (dir == ELM_FOCUS_PREVIOUS)
5603 item->item_focus_previous = next_item;
5604 else if (dir == ELM_FOCUS_NEXT)
5605 item->item_focus_next = next_item;
5606 else if (dir == ELM_FOCUS_UP)
5607 item->item_focus_up = next_item;
5608 else if (dir == ELM_FOCUS_DOWN)
5609 item->item_focus_down = next_item;
5610 else if (dir == ELM_FOCUS_RIGHT)
5611 item->item_focus_right = next_item;
5612 else if (dir == ELM_FOCUS_LEFT)
5613 item->item_focus_left = next_item;
5616 /* happy debug functions */
5619 _sub_obj_tree_dump(const Evas_Object *obj,
5624 for (i = 0; i < lvl * 3; i++)
5627 if (_elm_widget_is(obj))
5632 elm_widget_type_get(obj),
5634 for (unsigned int i = 0; i < eina_array_count(sd->children); ++i)
5636 obj = eina_array_data_get(sd->children, i);
5637 _sub_obj_tree_dump(obj, lvl + 1);
5641 DBG("+ %s(%p)\n", evas_object_type_get(obj), obj);
5645 _sub_obj_tree_dot_dump(const Evas_Object *obj,
5648 if (!_elm_widget_is(obj))
5652 Eina_Bool visible = evas_object_visible_get(obj);
5653 Eina_Bool disabled = elm_widget_disabled_get(obj);
5654 Eina_Bool focused = efl_ui_focus_object_focus_get(obj);
5655 Eina_Bool can_focus = elm_widget_can_focus_get(obj);
5659 fprintf(output, "\"%p\" -- \"%p\" [ color=black", sd->parent_obj, obj);
5662 fprintf(output, ", style=bold");
5665 fprintf(output, ", color=gray28");
5667 fprintf(output, " ];\n");
5670 fprintf(output, "\"%p\" [ label = \"{%p|%s|%s|visible: %d|"
5671 "disabled: %d|focused: %d/%d|focus order:%d}\"",
5672 obj, obj, elm_widget_type_get(obj),
5673 evas_object_name_get(obj), visible, disabled, focused, can_focus,
5677 fprintf(output, ", style=bold");
5680 fprintf(output, ", fontcolor=gray28");
5682 if ((disabled) || (!visible))
5683 fprintf(output, ", color=gray");
5685 fprintf(output, " ];\n");
5690 for (unsigned int i = 0; i < eina_array_count(sd->children); ++i)
5692 o = eina_array_data_get(sd->children, i);
5693 _sub_obj_tree_dot_dump(o, output);
5700 elm_widget_tree_dump(const Evas_Object *top)
5703 if (!_elm_widget_is(top))
5705 _sub_obj_tree_dump(top, 0);
5713 elm_widget_tree_dot_dump(const Evas_Object *top,
5717 if (!_elm_widget_is(top))
5719 fprintf(output, "graph " " { node [shape=record];\n");
5720 _sub_obj_tree_dot_dump(top, output);
5721 fprintf(output, "}\n");
5729 EINA_UNUSED static void
5730 _focus_event_changed(void *data EINA_UNUSED, const Efl_Event *event)
5732 if (efl_ui_focus_object_focus_get(event->object))
5733 evas_object_smart_callback_call(event->object, "focused", NULL);
5735 evas_object_smart_callback_call(event->object, "unfocused", NULL);
5739 _efl_ui_widget_efl_object_constructor(Eo *obj, Elm_Widget_Smart_Data *sd EINA_UNUSED)
5741 Eo *parent = efl_parent_get(obj);
5742 sd->on_create = EINA_TRUE;
5744 sd->window = efl_provider_find(efl_parent_get(obj), EFL_UI_WIN_CLASS);
5745 if (!efl_isa(obj, EFL_UI_WIN_CLASS))
5747 if (!efl_isa(parent, EFL_UI_WIDGET_CLASS))
5749 ERR("You passed a wrong parent parameter (%p %s). "
5750 "Elementary widget's parent should be an elementary widget.",
5751 parent, evas_object_type_get(parent));
5755 ELM_WIDGET_DATA_GET(parent, parent_sd);
5757 sd->shared_win_data = parent_sd->shared_win_data;
5762 sd->shared_win_data = efl_ui_win_shared_data_get(obj);
5765 _efl_ui_focus_event_redirector(obj, obj);
5766 efl_canvas_group_clipped_set(obj, EINA_FALSE);
5767 obj = efl_constructor(efl_super(obj, MY_CLASS));
5768 efl_canvas_object_type_set(obj, MY_CLASS_NAME_LEGACY);
5769 evas_object_smart_callbacks_descriptions_set(obj, _smart_callbacks);
5771 if (!efl_isa(obj, EFL_UI_WIN_CLASS) && efl_isa(parent, EFL_UI_WIDGET_CLASS))
5772 efl_ui_widget_sub_object_add(parent, obj);
5774 sd->on_create = EINA_FALSE;
5776 efl_access_object_role_set(obj, EFL_ACCESS_ROLE_UNKNOWN);
5777 //TIZEN_ONLY(20170717) : expose highlight information on atspi
5778 sd->can_highlight = EINA_TRUE;
5780 /***********************************************************
5781 * TIZEN_ONLY(20180117): Override Paragraph Direction APIs *
5782 ***********************************************************/
5783 sd->inherit_paragraph_direction = EINA_TRUE;
5785 if (efl_isa(parent, EFL_CANVAS_OBJECT_CLASS))
5787 if (sd->paragraph_direction != efl_canvas_object_paragraph_direction_get(parent))
5789 sd->paragraph_direction = efl_canvas_object_paragraph_direction_get(parent);
5790 _efl_ui_widget_efl_canvas_object_paragraph_direction_set_internal(obj, sd, sd->paragraph_direction);
5791 efl_canvas_object_paragraph_direction_set(efl_super(obj, MY_CLASS), sd->paragraph_direction);
5798 if (!elm_widget_is_legacy(obj))
5799 EINA_SAFETY_ON_NULL_RETURN_VAL(sd->shared_win_data, NULL);
5804 EOLIAN static Efl_Object*
5805 _efl_ui_widget_efl_object_finalize(Eo *obj, Elm_Widget_Smart_Data *pd)
5809 eo = efl_finalize(efl_super(obj, MY_CLASS));
5811 _full_eval(obj, pd);
5818 _efl_ui_widget_efl_object_destructor(Eo *obj, Elm_Widget_Smart_Data *sd)
5820 if (sd->manager.provider)
5822 sd->manager.provider = NULL;
5825 //TIZEN_ONLY : elm_widget_item: add at-spi name setter
5826 efl_access_object_description_set(obj, NULL);
5827 efl_access_object_i18n_name_set(obj, NULL);
5829 efl_access_object_description_cb_set(obj, NULL, NULL);
5830 efl_access_object_name_cb_set(obj, NULL, NULL);
5832 //TIZEN_ONLY(20170405) Add gesture method to accessible interface
5833 efl_access_object_gesture_cb_set(obj, NULL, NULL);
5835 //TIZEN_ONLY : elm_widget_item: add at-spi name setter
5836 efl_access_object_translation_domain_set(obj, NULL);
5837 efl_access_object_relationships_clear(obj);
5840 efl_access_object_attributes_clear(obj);
5841 if (sd->logical.parent)
5843 efl_weak_unref(&sd->logical.parent);
5844 sd->logical.parent = NULL;
5847 // TIZEN_ONLY(20150709) : atspi relations api
5848 if (sd->atspi_custom_relations)
5849 efl_access_relation_set_free(&sd->atspi_custom_relations);
5852 //TIZEN_ONLY(20150717) add widget name setter
5854 eina_stringshare_del(sd->name);
5857 //TIZEN_ONLY(20150731) : add i18n support for name and description
5858 if (sd->atspi_translation_domain)
5859 eina_stringshare_del(sd->atspi_translation_domain);
5862 // TIZEN_ONLY(20200623) : apply Tizen's color_class features
5863 if (sd->color_classes)
5864 ELM_SAFE_FREE(sd->color_classes, eina_hash_free);
5869 eina_array_free(sd->children);
5870 sd->children = NULL;
5873 sd->on_destroy = EINA_TRUE;
5874 efl_destructor(efl_super(obj, EFL_UI_WIDGET_CLASS));
5875 sd->on_destroy = EINA_FALSE;
5881 _efl_ui_widget_efl_object_debug_name_override(Eo *obj, Elm_Widget_Smart_Data *sd EINA_UNUSED, Eina_Strbuf *sb)
5883 const char *focus = "";
5885 if (efl_ui_focus_object_focus_get(obj)) focus = ":focused";
5886 efl_debug_name_override(efl_super(obj, MY_CLASS), sb);
5887 eina_strbuf_append_printf(sb, "%s", focus);
5890 EOLIAN static Eina_Bool
5891 _efl_ui_widget_efl_ui_focus_object_on_focus_update(Eo *obj, Elm_Widget_Smart_Data *sd)
5895 if (!elm_widget_can_focus_get(obj))
5898 focused = efl_ui_focus_object_focus_get(obj);
5900 if (!sd->resize_obj)
5901 evas_object_focus_set(obj, focused);
5903 //TIZEN_ONLY(20180607): Restore legacy focus
5905 evas_object_smart_callback_call(obj, "focused", NULL);
5907 evas_object_smart_callback_call(obj, "unfocused", NULL);
5910 if (_elm_atspi_enabled() && !elm_widget_child_can_focus_get(obj))
5911 efl_access_state_changed_signal_emit(obj, EFL_ACCESS_STATE_TYPE_FOCUSED, focused);
5916 EOLIAN static Eina_Bool
5917 _efl_ui_widget_widget_input_event_handler(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *_pd EINA_UNUSED, const Efl_Event *eo_event EINA_UNUSED, Evas_Object *source EINA_UNUSED)
5922 EOLIAN static Eina_Bool
5923 _efl_ui_widget_on_access_activate(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *_pd EINA_UNUSED, Efl_Ui_Activate act EINA_UNUSED)
5925 WRN("The %s widget does not implement the \"activate\" functions.",
5926 efl_class_name_get(efl_class_get(obj)));
5931 _efl_ui_widget_class_constructor(Efl_Class *klass)
5933 evas_smart_legacy_type_register(MY_CLASS_NAME_LEGACY, klass);
5936 EOLIAN static Eina_Bool
5937 _efl_ui_widget_efl_access_component_focus_grab(Eo *obj, Elm_Widget_Smart_Data *pd EINA_UNUSED)
5939 if (elm_object_focus_allow_get(obj))
5941 Ecore_Evas *ee = ecore_evas_ecore_evas_get(evas_object_evas_get(obj));
5942 if (!ee) return EINA_FALSE;
5943 ecore_evas_activate(ee);
5944 elm_object_focus_set(obj, EINA_TRUE);
5951 EOLIAN static const char*
5952 _efl_ui_widget_efl_access_object_i18n_name_get(const Eo *obj, Elm_Widget_Smart_Data *_pd EINA_UNUSED)
5954 const char *ret, *name;
5955 name = efl_access_object_i18n_name_get(efl_super(obj, EFL_UI_WIDGET_CLASS));
5957 if (name) return name;
5959 //TIZEN_ONLY(20150717) add widget name setter
5963 if (_pd->atspi_translation_domain)
5964 return dgettext(_pd->atspi_translation_domain, _pd->name);
5970 //TIZEN_ONLY(20170110) : Ignore text from elm_object_text_set in accessible_name_get
5971 Efl_Access_Role role;
5972 role = efl_access_object_role_get(obj);
5973 if(role == EFL_ACCESS_ROLE_DIALOG || role == EFL_ACCESS_ROLE_PASSWORD_TEXT)
5977 ret = elm_object_text_get(obj);
5978 if (!ret) return NULL;
5980 return _elm_widget_accessible_plain_name_get(obj, ret);
5983 EOLIAN static Eina_List*
5984 _efl_ui_widget_efl_access_object_access_children_get(const Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *pd)
5986 Eina_List *l, *accs = NULL;
5987 Evas_Object *widget;
5990 /* this is for webapp which is using window only */
5991 if (efl_access_object_role_get(obj) == EFL_ACCESS_ROLE_WINDOW)
5993 if (evas_object_data_get(obj, "__PlugID"))
5994 elm_atspi_ewk_wrapper_a11y_init((Eo *)obj, (Eo *)obj);
5997 for (unsigned int i = 0; i < eina_array_count(pd->children); ++i)
5999 widget = eina_array_data_get(pd->children, i);
6000 const char *type = evas_object_type_get(widget);
6002 // Ugly Tizen hack to integrate AT-SPI2 accessibility provided by WebKit/Chromium with elementary one.
6003 // This wrapper class should be implemented in Webkit/Chromium EFL ports
6004 if (type && (!strcmp(type, "EWebView") || !strcmp(type, "WebView")))
6006 elm_atspi_ewk_wrapper_a11y_init((Eo *)obj, widget);
6009 for (unsigned int i = 0; i < eina_array_count(pd->children); ++i)
6011 widget = eina_array_data_get(pd->children, i);
6013 // TIZEN_ONLY(20160705) - enable atspi_proxy to work
6014 /* This assumes that only one proxy exists in obj */
6017 proxy = plug_type_proxy_get(obj, widget);
6020 accs = eina_list_append(accs, proxy);
6026 if (!elm_object_widget_check(widget)) continue;
6027 if (!efl_isa(widget, EFL_ACCESS_OBJECT_MIXIN)) continue;
6028 accs = eina_list_append(accs, widget);
6030 //TIZEN_ONLY(20150709) : spatially sort atspi children
6031 // sort children using its top-left coordinate
6032 accs = eina_list_sort(accs, -1, _sort_vertically);
6033 Eina_List *line, *lines = _lines_split(accs);
6035 EINA_LIST_FREE(lines, line)
6036 accs = eina_list_merge(accs, eina_list_sort(line, -1, _sort_horizontally));
6042 accs = eina_list_remove(accs, proxy);
6043 EINA_LIST_FOREACH(accs, l, widget)
6045 if (efl_isa(widget, ELM_ACCESS_CLASS))
6047 Elm_Access_Info *info = _elm_access_info_get(widget);
6048 if (!info) continue;
6049 if (obj == info->part_object)
6059 accs = eina_list_append_relative(accs, proxy, deputy);
6068 EOLIAN static Efl_Access_State_Set
6069 _efl_ui_widget_efl_access_object_state_set_get(const Eo *obj, Elm_Widget_Smart_Data *pd EINA_UNUSED)
6071 Efl_Access_State_Set states = 0;
6073 states = efl_access_object_state_set_get(efl_super(obj, EFL_UI_WIDGET_CLASS));
6075 // TIZEN_ONLY(20171114) Accessibility Highlight Frame added
6076 // //TIZEN_ONLY(20171108): bring HIGHLIGHT related changes
6077 // Evas_Object *win = elm_widget_top_get(obj);
6078 // if (win && efl_isa(win, EFL_UI_WIN_CLASS))
6080 // if (_elm_win_accessibility_highlight_get(win) == obj)
6081 // STATE_TYPE_SET(states, ELM_ATSPI_STATE_HIGHLIGHTED);
6083 // STATE_TYPE_SET(states, ELM_ATSPI_STATE_HIGHLIGHTABLE);
6087 if (evas_object_visible_get(obj))
6089 STATE_TYPE_SET(states, EFL_ACCESS_STATE_TYPE_VISIBLE);
6090 if (_elm_widget_onscreen_is(obj))
6091 STATE_TYPE_SET(states, EFL_ACCESS_STATE_TYPE_SHOWING);
6093 if (!elm_widget_child_can_focus_get(obj))
6095 if (elm_object_focus_allow_get(obj))
6096 STATE_TYPE_SET(states, EFL_ACCESS_STATE_TYPE_FOCUSABLE);
6097 if (elm_object_focus_get(obj))
6098 STATE_TYPE_SET(states, EFL_ACCESS_STATE_TYPE_FOCUSED);
6100 if (!elm_object_disabled_get(obj))
6102 STATE_TYPE_SET(states, EFL_ACCESS_STATE_TYPE_ENABLED);
6103 STATE_TYPE_SET(states, EFL_ACCESS_STATE_TYPE_SENSITIVE);
6106 //TIZEN_ONLY(20170717) : expose highlight information on atspi
6107 if (_elm_widget_highlightable(obj))
6108 STATE_TYPE_SET(states, EFL_ACCESS_STATE_TYPE_HIGHLIGHTABLE);
6110 STATE_TYPE_UNSET(states, EFL_ACCESS_STATE_TYPE_HIGHLIGHTABLE);
6112 if (_elm_object_accessibility_currently_highlighted_get() == (void*)obj)
6113 STATE_TYPE_SET(states, EFL_ACCESS_STATE_TYPE_HIGHLIGHTED);
6119 EOLIAN static Eina_List*
6120 _efl_ui_widget_efl_access_object_attributes_get(const Eo *obj, Elm_Widget_Smart_Data *pd EINA_UNUSED)
6122 const char *type = NULL;
6123 const char *style = NULL;
6124 Eina_List *attr_list = NULL;
6125 Efl_Access_Attribute *attr = NULL;
6127 attr_list = efl_access_object_attributes_get(efl_super(obj, EFL_UI_WIDGET_CLASS));
6129 //Add type and style information in addition.
6130 type = elm_widget_type_get(obj);
6133 attr = calloc(1, sizeof(Efl_Access_Attribute));
6136 attr->key = eina_stringshare_add("type");
6137 attr->value = eina_stringshare_add(type);
6138 attr_list = eina_list_append(attr_list, attr);
6142 style = elm_widget_style_get(obj);
6145 attr = calloc(1, sizeof(Efl_Access_Attribute));
6148 attr->key = eina_stringshare_add("style");
6149 attr->value = eina_stringshare_add(style);
6150 attr_list = eina_list_append(attr_list, attr);
6157 EOLIAN static Eina_List *
6158 _elm_widget_item_efl_access_object_attributes_get(const Eo *eo_item, Elm_Widget_Item_Data *pd EINA_UNUSED)
6160 const char *style = NULL;
6161 Eina_List *attr_list = NULL;
6162 Efl_Access_Attribute *attr = NULL;
6164 attr_list = efl_access_object_attributes_get(efl_super(eo_item, ELM_WIDGET_ITEM_CLASS));
6166 style = elm_object_item_style_get(eo_item);
6169 attr = calloc(1, sizeof(Efl_Access_Attribute));
6172 attr->key = eina_stringshare_add("style");
6173 attr->value = eina_stringshare_add(style);
6174 attr_list = eina_list_append(attr_list, attr);
6180 EOLIAN static Eina_Rect
6181 _elm_widget_item_efl_access_component_extents_get(const Eo *obj EINA_UNUSED, Elm_Widget_Item_Data *sd EINA_UNUSED, Eina_Bool screen_coords)
6183 Eina_Rect r = EINA_RECT(-1, -1, -1, -1);
6185 if (!sd->view) return r;
6187 r = efl_gfx_entity_geometry_get(sd->view);
6190 r = _efl_access_component_screen_coords_extents_get(obj, r);
6195 EOLIAN static Eina_Bool
6196 _elm_widget_item_efl_access_component_extents_set(Eo *obj EINA_UNUSED, Elm_Widget_Item_Data *sd EINA_UNUSED, Eina_Bool screen_coords EINA_UNUSED, Eina_Rect r EINA_UNUSED)
6201 EOLIAN static Eina_Bool
6202 _elm_widget_item_efl_access_component_focus_grab(Eo *obj EINA_UNUSED, Elm_Widget_Item_Data *_pd EINA_UNUSED)
6204 elm_object_item_focus_set(obj, EINA_TRUE);
6205 return elm_object_item_focus_get(obj);
6208 EOLIAN static Efl_Object *
6209 _efl_ui_widget_efl_object_provider_find(const Eo *obj, Elm_Widget_Smart_Data *pd, const Efl_Object *klass)
6211 Efl_Object *lookup = NULL;
6213 if ((klass == EFL_CONFIG_INTERFACE) || (klass == EFL_CONFIG_GLOBAL_CLASS))
6214 return _efl_config_obj;
6216 if (klass == EFL_UI_WIN_CLASS)
6220 //let the parent_obj lookup handle this
6223 if (klass == EFL_ACCESS_OBJECT_MIXIN)
6226 if (pd->provider_lookup) return NULL;
6227 pd->provider_lookup = EINA_TRUE;
6229 lookup = efl_provider_find(efl_super(obj, MY_CLASS), klass);
6230 if (!lookup && pd->parent_obj) lookup = efl_provider_find(pd->parent_obj, klass);
6232 pd->provider_lookup = EINA_FALSE;
6237 //TIZEN_ONLY(20191205): fix build warnings of focus_manager functions
6238 #pragma GCC diagnostic push
6239 #pragma GCC diagnostic ignored "-Wunused-function"
6242 EOLIAN static Efl_Ui_Focus_Manager*
6243 _efl_ui_widget_efl_ui_focus_object_focus_parent_get(const Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *pd EINA_UNUSED)
6245 return pd->focus.parent;
6248 EOLIAN static Efl_Ui_Focus_Manager*
6249 _efl_ui_widget_efl_ui_focus_object_focus_manager_get(const Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *pd EINA_UNUSED)
6251 return pd->focus.manager;
6254 EOLIAN static Eina_Rect
6255 _efl_ui_widget_efl_ui_focus_object_focus_geometry_get(const Eo *obj, Elm_Widget_Smart_Data *pd EINA_UNUSED)
6257 return efl_gfx_entity_geometry_get(obj);
6261 _efl_ui_widget_efl_ui_focus_object_focus_set(Eo *obj, Elm_Widget_Smart_Data *pd, Eina_Bool focus)
6263 pd->focused = focus;
6265 efl_ui_focus_object_focus_set(efl_super(obj, MY_CLASS), focus);
6267 efl_ui_focus_object_on_focus_update(obj);
6270 EOLIAN static Efl_Ui_Focus_Manager*
6271 _efl_ui_widget_focus_manager_create(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *pd EINA_UNUSED, Efl_Ui_Focus_Object *root EINA_UNUSED)
6273 ERR("No manager presented");
6277 //TIZEN_ONLY(20191205): fix build warnings of focus_manager functions
6278 #pragma GCC diagnostic pop
6281 //TIZEN_ONLY(20160726): add API elm_object_part_access_object_get
6282 EOLIAN static Evas_Object*
6283 _efl_ui_widget_part_access_object_get(const Eo *obj, Elm_Widget_Smart_Data *_pd EINA_UNUSED, const char *part EINA_UNUSED)
6285 WRN("The %s widget does not implement the \"part_access_object_get\" functions.",
6286 efl_class_name_get(efl_class_get(obj)));
6294 elm_widget_on_show_region_hook_set(Eo *obj, void *data, Elm_Widget_On_Show_Region_Cb func, Eina_Free_Cb func_free_cb)
6296 ELM_WIDGET_DATA_GET(obj, sd);
6299 if ((sd->on_show_region_data == data) && (sd->on_show_region == func))
6302 if (sd->on_show_region_data && sd->on_show_region_data_free)
6303 sd->on_show_region_data_free(sd->on_show_region_data);
6305 sd->on_show_region = func;
6306 sd->on_show_region_data = data;
6307 sd->on_show_region_data_free = func_free_cb;
6311 elm_widget_show_region_set(Eo *obj, Eina_Rect sr, Eina_Bool forceshow)
6313 Evas_Object *parent_obj, *child_obj;
6314 Evas_Coord px, py, cx, cy, nx = 0, ny = 0;
6316 ELM_WIDGET_DATA_GET_OR_RETURN(obj, sd);
6318 /*****************************************************************************
6319 * TIZEN_ONLY_FEATURE: Fix entry size/cursor/region calculation for Tizen UX *
6320 *****************************************************************************
6321 * Move this code to the below to update show region geometry properly.
6322 evas_smart_objects_calculate(evas_object_evas_get(obj));
6328 if (!forceshow && eina_rectangle_equal(&sr.rect, &sd->show_region.rect)) return;
6330 sd->show_region = sr;
6332 /*****************************************************************************
6333 * TIZEN_ONLY_FEATURE: Fix entry size/cursor/region calculation for Tizen UX *
6334 *****************************************************************************/
6335 /* Block nested call for evas_smart_objects_calculate() and region showing works */
6336 if (sd->on_show_region_set) return;
6338 sd->on_show_region_set = EINA_TRUE;
6340 evas_smart_objects_calculate(evas_object_evas_get(obj));
6342 sd->on_show_region_set = EINA_FALSE;
6344 /* show_region geometry could be changed during processing elm_widget_show_region_set().
6345 evas_smart_objects_calculate() can trigger nested show_region_set calls */
6346 sr = sd->show_region;
6351 if (sd->on_show_region)
6353 sd->on_show_region(sd->on_show_region_data, obj, sr);
6355 if (_elm_scrollable_is(obj))
6357 if (elm_widget_is_legacy(obj))
6359 elm_interface_scrollable_content_pos_get(obj, &nx, &ny);
6365 Eina_Position2D pos;
6366 pos = efl_ui_scrollable_content_pos_get(obj);
6375 parent_obj = sd->parent_obj;
6376 if ((!parent_obj)) break;
6377 sd = efl_data_scope_get(parent_obj, MY_CLASS);
6380 evas_object_geometry_get(parent_obj, &px, &py, NULL, NULL);
6381 evas_object_geometry_get(child_obj, &cx, &cy, NULL, NULL);
6385 sd->show_region = sr;
6387 if (sd->on_show_region)
6388 sd->on_show_region(sd->on_show_region_data, parent_obj, sr);
6389 child_obj = parent_obj;
6395 elm_widget_show_region_get(const Eo *obj)
6397 ELM_WIDGET_DATA_GET_OR_RETURN(obj, sd, EINA_RECT_EMPTY());
6398 return (Eina_Rect) sd->show_region;
6400 /* elm_object_content_xxx APIs are supposed to work on all objects for which
6401 * elm_object_widget_check() returns true. The below checks avoid printing out
6402 * undesired ERR messages. */
6404 elm_widget_content_part_set(Evas_Object *obj, const char *part, Evas_Object *content)
6406 ELM_WIDGET_CHECK(obj);
6407 if (efl_isa(obj, EFL_UI_LAYOUT_BASE_CLASS))
6409 elm_layout_content_set(obj, part, content);
6412 if (!efl_isa(obj, EFL_PART_INTERFACE)) return;
6415 part = efl_ui_widget_default_content_part_get(obj);
6418 efl_content_set(efl_part(obj, part), content);
6422 elm_widget_content_part_get(const Evas_Object *obj, const char *part)
6424 ELM_WIDGET_CHECK(obj) NULL;
6425 if (efl_isa(obj, EFL_UI_LAYOUT_BASE_CLASS))
6426 return elm_layout_content_get(obj, part);
6427 if (!efl_isa(obj, EFL_PART_INTERFACE)) return NULL;
6430 part = efl_ui_widget_default_content_part_get(obj);
6431 if (!part) return NULL;
6433 return efl_content_get(efl_part(obj, part));
6437 elm_widget_content_part_unset(Evas_Object *obj, const char *part)
6439 ELM_WIDGET_CHECK(obj) NULL;
6440 if (efl_isa(obj, EFL_UI_LAYOUT_BASE_CLASS))
6441 return elm_layout_content_unset(obj, part);
6442 if (!efl_isa(obj, EFL_PART_INTERFACE)) return NULL;
6445 part = efl_ui_widget_default_content_part_get(obj);
6446 if (!part) return NULL;
6448 return efl_content_unset(efl_part(obj, part));
6452 elm_widget_signal_emit(Eo *obj, const char *emission, const char *source)
6454 ELM_WIDGET_CHECK(obj);
6456 if (efl_isa(obj, EFL_UI_LAYOUT_BASE_CLASS))
6457 elm_layout_signal_emit(obj, emission, source);
6458 else if (evas_object_smart_type_check(obj, "elm_icon"))
6460 WRN("Deprecated function. This functionality on icon objects"
6461 " will be dropped on a next release.");
6462 _elm_icon_signal_emit(obj, emission, source);
6467 elm_widget_signal_callback_add(Eo *obj, const char *emission, const char *source, Edje_Signal_Cb func, void *data)
6469 ELM_WIDGET_CHECK(obj);
6470 EINA_SAFETY_ON_NULL_RETURN(func);
6471 if (evas_object_smart_type_check(obj, "elm_layout"))
6472 elm_layout_signal_callback_add(obj, emission, source, func, data);
6473 else if (evas_object_smart_type_check(obj, "elm_icon"))
6475 WRN("Deprecated function. This functionality on icon objects"
6476 " will be dropped on a next release.");
6478 _elm_icon_signal_callback_add(obj, emission, source, func, data);
6483 elm_widget_signal_callback_del(Eo *obj, const char *emission, const char *source, Edje_Signal_Cb func)
6487 ELM_WIDGET_CHECK(obj) NULL;
6488 EINA_SAFETY_ON_NULL_RETURN_VAL(func, NULL);
6489 if (evas_object_smart_type_check(obj, "elm_layout"))
6490 data = elm_layout_signal_callback_del(obj, emission, source, func);
6491 else if (evas_object_smart_type_check(obj, "elm_icon"))
6493 WRN("Deprecated function. This functionality on icon objects"
6494 " will be dropped on a next release.");
6496 data = _elm_icon_signal_callback_del(obj, emission, source, func);
6503 /* Widget Shadow Begin */
6505 typedef struct _Widget_Shadow
6510 double rx, ry, ox, oy, grow;
6513 Eina_Stringshare *code, *name;
6516 static void _widget_shadow_update(Widget_Shadow *shadow);
6519 _widget_shadow_del_cb(void *data, const Efl_Event *ev EINA_UNUSED)
6521 Widget_Shadow *shadow = data;
6523 efl_del(shadow->surface);
6528 _widget_shadow_event_cb(void *data, const Efl_Event *ev EINA_UNUSED)
6530 Widget_Shadow *shadow = data;
6531 _widget_shadow_update(shadow);
6534 EFL_CALLBACKS_ARRAY_DEFINE(widget_shadow_cb,
6535 { EFL_EVENT_DEL, _widget_shadow_del_cb },
6536 { EFL_GFX_ENTITY_EVENT_POSITION_CHANGED, _widget_shadow_event_cb },
6537 { EFL_GFX_ENTITY_EVENT_SIZE_CHANGED, _widget_shadow_event_cb },
6538 { EFL_GFX_ENTITY_EVENT_STACKING_CHANGED, _widget_shadow_event_cb },
6539 { EFL_GFX_ENTITY_EVENT_VISIBILITY_CHANGED, _widget_shadow_event_cb });
6541 static Widget_Shadow *
6542 _widget_shadow_part_get(const Eo *part_obj)
6544 Elm_Part_Data *pd = efl_data_scope_get(part_obj, EFL_UI_WIDGET_PART_CLASS);
6545 Widget_Shadow *shadow;
6546 Eo *widget = pd->obj;
6548 shadow = efl_key_data_get(widget, "__elm_shadow");
6551 shadow = calloc(1, sizeof(*shadow));
6552 if (!shadow) return NULL;
6553 shadow->widget = pd->obj;
6554 efl_key_data_set(widget, "__elm_shadow", shadow);
6555 efl_event_callback_array_add(widget, widget_shadow_cb(), shadow);
6561 _widget_shadow_update(Widget_Shadow *ws)
6563 int l = 0, r = 0, t = 0, b = 0;
6564 Eina_Rect srect, wrect;
6567 #define FILTER_FMT \
6568 "a = buffer { 'alpha' }" \
6569 "grow { %f, dst = a, alphaonly = true }" \
6570 "blur { src = a, rx = %f, ry = %f, color = color(%d,%d,%d,%d) }"
6574 ws->surface = efl_add(EFL_CANVAS_PROXY_CLASS, ws->widget);
6575 efl_gfx_fill_auto_set(ws->surface, 1);
6576 efl_canvas_proxy_source_clip_set(ws->surface, EINA_FALSE);
6577 efl_canvas_proxy_source_events_set(ws->surface, EINA_FALSE);
6578 efl_canvas_proxy_source_set(ws->surface, ws->widget);
6583 snprintf(filter, sizeof(filter), FILTER_FMT,
6584 ws->props.grow, ws->props.rx, ws->props.ry,
6585 ws->props.r, ws->props.g, ws->props.b, ws->props.a);
6588 efl_gfx_filter_program_set(ws->surface,
6589 ws->code ? ws->code : filter,
6590 ws->name ? ws->name : "shadow");
6591 efl_gfx_filter_padding_get(ws->surface, &l, &r, &t, &b);
6593 wrect = efl_gfx_entity_geometry_get(ws->widget);
6594 srect.x = wrect.x + (int) (-l + ws->props.ox);
6595 srect.y = wrect.y + (int) (-t + ws->props.oy);
6596 srect.w = wrect.w + (int) (l + r);
6597 srect.h = wrect.h + (int) (t + b);
6599 if ((!ws->props.a && !ws->code) ||
6600 !efl_gfx_entity_visible_get(ws->widget))
6602 efl_gfx_entity_visible_set(ws->surface, EINA_FALSE);
6606 efl_canvas_object_clipper_set(ws->surface, efl_canvas_object_clipper_get(ws->widget));
6607 efl_canvas_group_member_add(efl_canvas_object_render_parent_get(ws->widget), ws->surface);
6608 efl_gfx_entity_geometry_set(ws->surface, srect);
6609 efl_gfx_stack_below(ws->surface, ws->widget);
6610 efl_gfx_entity_visible_set(ws->surface, EINA_TRUE);
6614 _elm_widget_shadow_update(Efl_Ui_Widget *obj)
6616 Widget_Shadow *shadow = _widget_shadow_part_get(obj);
6617 _widget_shadow_update(shadow);
6621 _efl_ui_widget_part_shadow_efl_gfx_blur_offset_set(Eo *obj, void *_pd EINA_UNUSED, double ox, double oy)
6623 Widget_Shadow *shadow = _widget_shadow_part_get(obj);
6624 shadow->props.ox = ox;
6625 shadow->props.oy = oy;
6626 _widget_shadow_update(shadow);
6630 _efl_ui_widget_part_shadow_efl_gfx_blur_offset_get(const Eo *obj, void *_pd EINA_UNUSED, double *ox, double *oy)
6632 Widget_Shadow *shadow = _widget_shadow_part_get(obj);
6633 if (ox) *ox = shadow->props.ox;
6634 if (oy) *oy = shadow->props.oy;
6638 _efl_ui_widget_part_shadow_efl_gfx_blur_radius_set(Eo *obj, void *_pd EINA_UNUSED, double rx, double ry)
6640 Widget_Shadow *shadow = _widget_shadow_part_get(obj);
6641 shadow->props.rx = rx;
6642 shadow->props.ry = ry;
6643 _widget_shadow_update(shadow);
6647 _efl_ui_widget_part_shadow_efl_gfx_blur_radius_get(const Eo *obj, void *_pd EINA_UNUSED, double *rx, double *ry)
6649 Widget_Shadow *shadow = _widget_shadow_part_get(obj);
6650 if (rx) *rx = shadow->props.rx;
6651 if (ry) *ry = shadow->props.ry;
6655 _efl_ui_widget_part_shadow_efl_gfx_color_color_set(Eo *obj, void *_pd EINA_UNUSED, int r, int g, int b, int a)
6657 Widget_Shadow *shadow = _widget_shadow_part_get(obj);
6658 shadow->props.r = r;
6659 shadow->props.g = g;
6660 shadow->props.b = b;
6661 shadow->props.a = a;
6662 _widget_shadow_update(shadow);
6666 _efl_ui_widget_part_shadow_efl_gfx_color_color_get(const Eo *obj, void *_pd EINA_UNUSED, int *r, int *g, int *b, int *a)
6668 Widget_Shadow *shadow = _widget_shadow_part_get(obj);
6669 if (r) *r = shadow->props.r;
6670 if (g) *g = shadow->props.g;
6671 if (b) *b = shadow->props.b;
6672 if (a) *a = shadow->props.a;
6676 _efl_ui_widget_part_shadow_efl_gfx_blur_grow_set(Eo *obj, void *_pd EINA_UNUSED, double radius)
6678 Widget_Shadow *shadow = _widget_shadow_part_get(obj);
6679 shadow->props.grow = radius;
6680 _widget_shadow_update(shadow);
6683 EOLIAN static double
6684 _efl_ui_widget_part_shadow_efl_gfx_blur_grow_get(const Eo *obj, void *_pd EINA_UNUSED)
6686 Widget_Shadow *shadow = _widget_shadow_part_get(obj);
6687 return shadow->props.grow;
6691 _efl_ui_widget_part_shadow_efl_gfx_filter_filter_program_set(Eo *obj, void *_pd EINA_UNUSED, const char *code, const char *name)
6693 Widget_Shadow *ws = _widget_shadow_part_get(obj);
6694 eina_stringshare_replace(&ws->code, code);
6695 eina_stringshare_replace(&ws->name, name);
6696 _widget_shadow_update(ws);
6700 _efl_ui_widget_part_shadow_efl_gfx_filter_filter_program_get(const Eo *obj, void *_pd EINA_UNUSED, const char **code, const char **name)
6702 Widget_Shadow *ws = _widget_shadow_part_get(obj);
6703 efl_gfx_filter_program_get(ws->surface, code, name);
6707 _efl_ui_widget_part_shadow_efl_gfx_filter_filter_source_set(Eo *obj, void *_pd EINA_UNUSED, const char *name, Efl_Gfx_Entity *source)
6709 Widget_Shadow *ws = _widget_shadow_part_get(obj);
6710 _widget_shadow_update(ws);
6711 efl_gfx_filter_source_set(ws->surface, name, source);
6714 EOLIAN static Efl_Gfx_Entity *
6715 _efl_ui_widget_part_shadow_efl_gfx_filter_filter_source_get(const Eo *obj, void *_pd EINA_UNUSED, const char *name)
6717 Widget_Shadow *ws = _widget_shadow_part_get(obj);
6718 return efl_gfx_filter_source_get(ws->surface, name);
6722 _efl_ui_widget_part_shadow_efl_gfx_filter_filter_data_set(Eo *obj, void *_pd EINA_UNUSED, const char *name, const char *value, Eina_Bool execute)
6724 Widget_Shadow *ws = _widget_shadow_part_get(obj);
6725 _widget_shadow_update(ws);
6726 efl_gfx_filter_data_set(ws->surface, name, value, execute);
6730 _efl_ui_widget_part_shadow_efl_gfx_filter_filter_data_get(const Eo *obj, void *_pd EINA_UNUSED, const char *name, const char **value, Eina_Bool *execute)
6732 Widget_Shadow *ws = _widget_shadow_part_get(obj);
6733 efl_gfx_filter_data_get(ws->surface, name, value, execute);
6737 _efl_ui_widget_part_shadow_efl_gfx_filter_filter_padding_get(const Eo *obj, void *_pd EINA_UNUSED, int *l, int *r, int *t, int *b)
6739 Widget_Shadow *ws = _widget_shadow_part_get(obj);
6740 efl_gfx_filter_padding_get(ws->surface, l, r, t, b);
6744 _efl_ui_widget_part_shadow_efl_gfx_filter_filter_state_set(Eo *obj, void *_pd EINA_UNUSED, const char *cur_state, double cur_val, const char *next_state, double next_val, double pos)
6746 Widget_Shadow *ws = _widget_shadow_part_get(obj);
6747 efl_gfx_filter_state_set(ws->surface, cur_state, cur_val, next_state, next_val, pos);
6751 _efl_ui_widget_part_shadow_efl_gfx_filter_filter_state_get(const Eo *obj, void *_pd EINA_UNUSED, const char **cur_state, double *cur_val, const char **next_state, double *next_val, double *pos)
6753 Widget_Shadow *ws = _widget_shadow_part_get(obj);
6754 efl_gfx_filter_state_get(ws->surface, cur_state, cur_val, next_state, next_val, pos);
6757 #include "efl_ui_widget_part_shadow.eo.c"
6759 /* Widget Shadow End */
6762 /* Efl.Part implementation */
6764 EOLIAN static Efl_Object *
6765 _efl_ui_widget_efl_part_part_get(const Eo *obj, Elm_Widget_Smart_Data *wd EINA_UNUSED, const char *part)
6767 if (eina_streq(part, "background"))
6768 return ELM_PART_IMPLEMENT(EFL_UI_WIDGET_PART_BG_CLASS, obj, part);
6769 else if (eina_streq(part, "shadow"))
6770 return ELM_PART_IMPLEMENT(EFL_UI_WIDGET_PART_SHADOW_CLASS, obj, part);
6771 return ELM_PART_IMPLEMENT(EFL_UI_WIDGET_PART_CLASS, obj, part);
6774 EOLIAN static void \
6775 _efl_ui_widget_part_efl_object_destructor(Eo *obj, Elm_Part_Data *pd)
6778 eina_tmpstr_del(pd->part);
6779 efl_destructor(efl_super(obj, EFL_UI_WIDGET_PART_CLASS));
6782 static Efl_Canvas_Layout_Part_Type
6783 _efl_ui_widget_part_efl_canvas_layout_part_type_provider_part_type_get(const Eo *obj EINA_UNUSED, Elm_Part_Data *pd)
6785 Elm_Widget_Smart_Data *sd = efl_data_scope_safe_get(pd->obj, MY_CLASS);
6786 EINA_SAFETY_ON_NULL_RETURN_VAL(sd, EFL_CANVAS_LAYOUT_PART_TYPE_NONE);
6787 return efl_canvas_layout_part_type_get(efl_part(sd->resize_obj, pd->part));
6791 _efl_ui_widget_part_efl_gfx_entity_geometry_get(const Eo *obj EINA_UNUSED, Elm_Part_Data *pd)
6793 Elm_Widget_Smart_Data *sd = efl_data_scope_safe_get(pd->obj, MY_CLASS);
6794 EINA_SAFETY_ON_NULL_RETURN_VAL(sd, EINA_RECT_EMPTY());
6795 return efl_gfx_entity_geometry_get(efl_part(sd->resize_obj, pd->part));
6799 _efl_ui_widget_part_efl_ui_property_bind_property_bind(Eo *obj, Elm_Part_Data *ppd,
6800 const char *key, const char *property)
6802 Efl_Ui_Widget_Data *pd;
6805 widget = efl_parent_get(obj);
6806 pd = efl_data_scope_get(widget, EFL_UI_WIDGET_CLASS);
6808 return _efl_ui_property_bind(widget, obj, pd, ppd->part, key, property);
6811 #include "efl_ui_widget_part.eo.c"
6815 /* Efl.Part Bg implementation */
6818 _efl_ui_widget_bg_get(const Efl_Ui_Widget *obj)
6820 Elm_Widget_Smart_Data *sd = efl_data_scope_get(obj, MY_CLASS);
6821 Evas_Object *bg_obj = sd->bg;
6825 bg_obj = efl_add(EFL_UI_BG_CLASS, (Eo *)obj);
6826 EINA_SAFETY_ON_NULL_RETURN_VAL(bg_obj, NULL);
6828 efl_canvas_group_member_add((Eo *)obj, sd->bg);
6829 evas_object_stack_below(sd->bg, sd->resize_obj);
6830 _smart_reconfigure((Eo*)obj, sd);
6836 static inline Efl_Canvas_Object *
6837 efl_ui_widget_part_bg_get(const Eo *part_obj)
6839 Elm_Part_Data *pd = efl_data_scope_get(part_obj, EFL_UI_WIDGET_PART_CLASS);
6840 return _efl_ui_widget_bg_get(pd->obj);
6843 EOLIAN static Eina_Error
6844 _efl_ui_widget_part_bg_efl_file_load(Eo *obj, void *pd EINA_UNUSED)
6846 Evas_Object *bg_obj = efl_ui_widget_part_bg_get(obj);
6848 return efl_file_load(bg_obj);
6852 _efl_ui_widget_part_bg_efl_file_unload(Eo *obj, void *pd EINA_UNUSED)
6854 Evas_Object *bg_obj = efl_ui_widget_part_bg_get(obj);
6856 efl_file_unload(bg_obj);
6859 EOLIAN static const char *
6860 _efl_ui_widget_part_bg_efl_file_file_get(const Eo *obj, void *pd EINA_UNUSED)
6862 Evas_Object *bg_obj = efl_ui_widget_part_bg_get(obj);
6864 return efl_file_get(bg_obj);
6867 EOLIAN static Eina_Error
6868 _efl_ui_widget_part_bg_efl_file_file_set(Eo *obj, void *pd EINA_UNUSED, const char *file)
6870 Evas_Object *bg_obj = efl_ui_widget_part_bg_get(obj);
6872 return efl_file_set(bg_obj, file);
6875 EOLIAN static const char *
6876 _efl_ui_widget_part_bg_efl_file_key_get(const Eo *obj, void *pd EINA_UNUSED)
6878 Evas_Object *bg_obj = efl_ui_widget_part_bg_get(obj);
6880 return efl_file_key_get(bg_obj);
6884 _efl_ui_widget_part_bg_efl_file_key_set(Eo *obj, void *pd EINA_UNUSED, const char *key)
6886 Evas_Object *bg_obj = efl_ui_widget_part_bg_get(obj);
6888 efl_file_key_set(bg_obj, key);
6891 EOLIAN static const Eina_File *
6892 _efl_ui_widget_part_bg_efl_file_mmap_get(const Eo *obj, void *pd EINA_UNUSED)
6894 Evas_Object *bg_obj = efl_ui_widget_part_bg_get(obj);
6896 return efl_file_mmap_get(bg_obj);
6899 EOLIAN static Eina_Error
6900 _efl_ui_widget_part_bg_efl_file_mmap_set(Eo *obj, void *pd EINA_UNUSED, const Eina_File *file)
6902 Evas_Object *bg_obj = efl_ui_widget_part_bg_get(obj);
6904 return efl_file_mmap_set(bg_obj, file);
6908 _efl_ui_widget_part_bg_efl_gfx_color_color_set(Eo *obj, void *pd EINA_UNUSED, int r, int g, int b, int a)
6910 Evas_Object *bg_obj = efl_ui_widget_part_bg_get(obj);
6912 efl_gfx_color_set(bg_obj, r, g, b, a);
6916 _efl_ui_widget_part_bg_efl_gfx_color_color_get(const Eo *obj, void *pd EINA_UNUSED, int *r, int *g, int *b, int *a)
6918 Evas_Object *bg_obj = efl_ui_widget_part_bg_get(obj);
6920 efl_gfx_color_get(bg_obj, r, g, b, a);
6923 EOLIAN static Efl_Object*
6924 _efl_ui_widget_part_bg_efl_object_finalize(Eo *obj, void *pd EINA_UNUSED)
6926 Evas_Object *bg_obj = efl_ui_widget_part_bg_get(obj);
6928 efl_composite_attach(obj, bg_obj);
6930 return efl_finalize(efl_super(obj, EFL_UI_WIDGET_PART_BG_CLASS));
6934 typedef struct _Efl_Ui_Property_Bound Efl_Ui_Property_Bound;
6935 struct _Efl_Ui_Property_Bound
6937 Eina_Stringshare *part; // Optional part to apply the property on
6938 Eina_Stringshare *key; // Local object property
6939 Eina_Stringshare *property; // Model property
6944 _efl_ui_property_bind_free(void *data)
6946 Efl_Ui_Property_Bound *prop = data;
6948 eina_stringshare_del(prop->part);
6949 eina_stringshare_del(prop->key);
6950 eina_stringshare_del(prop->property);
6955 _efl_ui_property_bind_clean(Eo *obj EINA_UNUSED,
6957 const Eina_Future *f EINA_UNUSED)
6959 Efl_Ui_Property_Bound *prop = data;
6965 _efl_ui_property_bind_get(Eo *obj, Efl_Ui_Widget_Data *pd, Efl_Ui_Property_Bound *prop)
6972 // If there is no model set yet, no need to try anything
6973 if (!pd->properties.model) return ;
6975 value = efl_model_property_get(pd->properties.model, prop->property);
6976 target = prop->part ? efl_part(obj, prop->part) : obj;
6978 err = efl_property_reflection_set(target, prop->key, eina_value_reference_copy(value));
6979 eina_value_free(value);
6983 // Report back the error to the model
6984 if (prop->f) eina_future_cancel(prop->f);
6985 f = efl_model_property_set(pd->properties.model, prop->property,
6986 eina_value_error_new(err));
6987 prop->f = efl_future_then(obj, f, .free = _efl_ui_property_bind_clean, .data = prop);
6991 _efl_ui_property_bind_set(Eo *obj, Efl_Ui_Widget_Data *pd, Efl_Ui_Property_Bound *prop)
6997 target = prop->part ? efl_part(obj, prop->part) : obj;
6998 value = efl_property_reflection_get(target, prop->key);
7000 if (prop->f) eina_future_cancel(prop->f);
7001 f = efl_model_property_set(pd->properties.model, prop->property, eina_value_dup(&value));
7002 prop->f = efl_future_then(obj, f, .free = _efl_ui_property_bind_clean, .data = prop);
7003 eina_value_flush(&value);
7007 _efl_ui_model_property_bind_changed(void *data, const Efl_Event *event)
7009 Efl_Model_Property_Event *evt = event->info;
7010 ELM_WIDGET_DATA_GET(data, pd);
7011 Eina_Array_Iterator it;
7016 EINA_ARRAY_ITER_NEXT(evt->changed_properties, i, prop, it)
7018 Efl_Ui_Property_Bound *lookup;
7020 lookup = eina_hash_find(pd->properties.model_lookup, prop);
7021 if (lookup) _efl_ui_property_bind_get(data, pd, lookup);
7026 _efl_ui_view_property_bind_changed(void *data, const Efl_Event *event)
7028 Efl_Ui_Property_Event *evt = event->info;
7029 ELM_WIDGET_DATA_GET(data, pd);
7030 Eina_Array_Iterator it;
7031 Eina_Stringshare *prop;
7035 EINA_ARRAY_ITER_NEXT(evt->changed_properties, i, prop, it)
7037 Efl_Ui_Property_Bound *lookup;
7039 lookup = eina_hash_find(pd->properties.view_lookup, prop);
7040 if (lookup) _efl_ui_property_bind_set(data, pd, lookup);
7045 _efl_ui_widget_model_update(Eo *obj, Efl_Ui_Widget_Data *pd)
7047 Efl_Ui_Property_Bound *property;
7050 it = eina_hash_iterator_data_new(pd->properties.model_lookup);
7051 EINA_ITERATOR_FOREACH(it, property)
7052 _efl_ui_property_bind_get(obj, pd, property);
7053 eina_iterator_free(it);
7056 static void _efl_ui_widget_model_provider_model_change(void *data, const Efl_Event *event EINA_UNUSED);
7057 static void _efl_ui_widget_model_provider_invalidate(void *data, const Efl_Event *event EINA_UNUSED);
7059 EFL_CALLBACKS_ARRAY_DEFINE(efl_ui_widget_model_provider_callbacks,
7060 { EFL_EVENT_INVALIDATE, _efl_ui_widget_model_provider_invalidate },
7061 { EFL_UI_VIEW_EVENT_MODEL_CHANGED, _efl_ui_widget_model_provider_model_change });
7064 _efl_ui_widget_model_provider_model_change(void *data, const Efl_Event *event)
7066 ELM_WIDGET_DATA_GET(data, pd);
7069 efl_replace(&pd->properties.model,
7070 efl_ui_view_model_get(pd->properties.provider));
7071 _efl_ui_widget_model_update(data, pd);
7073 efl_event_callback_call(data, EFL_UI_VIEW_EVENT_MODEL_CHANGED, event->info);
7077 _efl_ui_widget_model_provider_invalidate(void *data, const Efl_Event *event EINA_UNUSED)
7079 ELM_WIDGET_DATA_GET(data, pd);
7082 efl_event_callback_array_del(pd->properties.provider,
7083 efl_ui_widget_model_provider_callbacks(),
7085 efl_replace(&pd->properties.provider, NULL);
7086 efl_replace(&pd->properties.model, NULL);
7087 pd->properties.callback_to_provider = EINA_FALSE;
7091 _efl_ui_widget_model_register(Eo *obj, Efl_Ui_Widget_Data *pd)
7093 if (pd->properties.registered) return ;
7095 if (!pd->properties.model)
7097 Efl_Model_Changed_Event ev;
7099 efl_replace(&pd->properties.provider,
7100 efl_provider_find(obj, EFL_MODEL_PROVIDER_CLASS));
7101 if (!pd->properties.provider) return ;
7102 if (!pd->properties.callback_to_provider)
7103 efl_event_callback_array_add(pd->properties.provider,
7104 efl_ui_widget_model_provider_callbacks(),
7106 pd->properties.callback_to_provider = EINA_TRUE;
7107 efl_replace(&pd->properties.model,
7108 efl_ui_view_model_get(pd->properties.provider));
7110 if (!pd->properties.model) return ;
7112 ev.current = pd->properties.model;
7114 efl_event_callback_call(obj, EFL_UI_VIEW_EVENT_MODEL_CHANGED, &ev);
7117 if (!pd->properties.model) return ;
7118 if (!pd->properties.model_lookup) return ;
7120 efl_event_callback_add(pd->properties.model, EFL_MODEL_EVENT_PROPERTIES_CHANGED,
7121 _efl_ui_model_property_bind_changed, obj);
7122 efl_event_callback_add(obj, EFL_UI_PROPERTY_BIND_EVENT_PROPERTIES_CHANGED,
7123 _efl_ui_view_property_bind_changed, obj);
7124 pd->properties.registered = EINA_TRUE;
7128 _efl_ui_widget_model_unregister(Eo *obj, Efl_Ui_Widget_Data *pd)
7130 if (pd->properties.registered)
7132 // Remove any existing handler that might exist for any reason
7133 efl_event_callback_del(pd->properties.model, EFL_MODEL_EVENT_PROPERTIES_CHANGED,
7134 _efl_ui_model_property_bind_changed, obj);
7135 efl_event_callback_del(obj, EFL_UI_PROPERTY_BIND_EVENT_PROPERTIES_CHANGED,
7136 _efl_ui_view_property_bind_changed, obj);
7138 pd->properties.registered = EINA_FALSE;
7140 // Invalidate must be called before setting a new model and even if no model is registered
7141 if (pd->properties.provider)
7142 _efl_ui_widget_model_provider_invalidate(obj, NULL);
7146 _efl_ui_property_bind(Eo *widget, Eo *target, Efl_Ui_Widget_Data *pd,
7147 const char *part, const char *key, const char *property)
7149 Efl_Ui_Property_Bound *prop;
7151 // Always check for a model and fetch a provider in case a bound property
7152 // is provided by a class down the hierarchy, but they still need to be notified
7153 // when a model change
7154 _efl_ui_widget_model_register(widget, pd);
7156 // Check if the property is available from the reflection table of the object.
7157 if (!efl_property_reflection_exist(target, key)) return EFL_PROPERTY_ERROR_INVALID_KEY;
7159 if (!pd->properties.model_lookup)
7161 pd->properties.model_lookup = eina_hash_stringshared_new(_efl_ui_property_bind_free);
7162 pd->properties.view_lookup = eina_hash_stringshared_new(NULL);
7165 prop = calloc(1, sizeof (Efl_Ui_Property_Bound));
7166 if (!prop) return ENOMEM;
7167 prop->part = eina_stringshare_add(part);
7168 prop->key = eina_stringshare_add(key);
7169 prop->property = eina_stringshare_add(property);
7171 eina_hash_direct_add(pd->properties.model_lookup, prop->property, prop);
7172 eina_hash_direct_add(pd->properties.view_lookup, prop->key, prop);
7174 _efl_ui_property_bind_get(widget, pd, prop);
7176 efl_event_callback_call(widget, EFL_UI_PROPERTY_BIND_EVENT_PROPERTY_BOUND, (void*) prop->key);
7177 // In case of part, we emit it also on the part so that the part too can act on it
7179 efl_event_callback_call(target, EFL_UI_PROPERTY_BIND_EVENT_PROPERTY_BOUND, (void*) prop->key);
7185 _efl_ui_widget_efl_ui_property_bind_property_bind(Eo *obj, Efl_Ui_Widget_Data *pd,
7186 const char *key, const char *property)
7188 return _efl_ui_property_bind(obj, obj, pd, NULL, key, property);
7192 _efl_ui_widget_efl_ui_view_model_set(Eo *obj,
7193 Efl_Ui_Widget_Data *pd,
7196 Efl_Model_Changed_Event ev;
7198 ev.current = efl_ref(model);
7199 ev.previous = efl_ref(pd->properties.model);
7201 _efl_ui_widget_model_unregister(obj, pd);
7203 efl_replace(&pd->properties.model, model);
7205 // Set the properties handler just in case
7206 _efl_ui_widget_model_register(obj, pd);
7208 // In case the model set was NULL, but we did found a model provider
7209 // we shouldn't emit a second event. Otherwise we should.
7210 if (ev.current == pd->properties.model)
7211 efl_event_callback_call(obj, EFL_UI_VIEW_EVENT_MODEL_CHANGED, &ev);
7213 if (pd->properties.model) _efl_ui_widget_model_update(obj, pd);
7215 efl_unref(ev.current);
7216 efl_unref(ev.previous);
7220 _efl_ui_widget_efl_ui_view_model_get(const Eo *obj EINA_UNUSED, Efl_Ui_Widget_Data *pd)
7222 return pd->properties.model;
7226 _efl_ui_widget_efl_object_invalidate(Eo *obj, Efl_Ui_Widget_Data *pd)
7228 efl_invalidate(efl_super(obj, EFL_UI_WIDGET_CLASS));
7230 _efl_ui_widget_model_unregister(obj, pd);
7231 efl_replace(&pd->properties.model, NULL);
7233 if (pd->properties.view_lookup) eina_hash_free(pd->properties.view_lookup);
7234 pd->properties.view_lookup = NULL;
7235 if (pd->properties.model_lookup) eina_hash_free(pd->properties.model_lookup);
7236 pd->properties.model_lookup = NULL;
7239 #include "efl_ui_widget_part_bg.eo.c"
7242 efl_ui_widget_internal_set(Eo *obj, Eina_Bool b)
7244 ELM_WIDGET_DATA_GET(obj, pd);
7245 EINA_SAFETY_ON_NULL_RETURN(pd);
7251 efl_ui_widget_internal_get(Eo *obj)
7253 ELM_WIDGET_DATA_GET(obj, pd);
7254 EINA_SAFETY_ON_NULL_RETURN_VAL(obj, EINA_FALSE);
7256 return pd->internal;
7259 /* Efl.Part Bg end */
7262 /* Internal EO APIs and hidden overrides */
7264 EFL_FUNC_BODY_CONST(efl_ui_widget_default_content_part_get, const char *, NULL)
7265 EFL_FUNC_BODY_CONST(efl_ui_widget_default_text_part_get, const char *, NULL)
7267 ELM_PART_CONTENT_DEFAULT_GET(efl_ui_widget, NULL)
7268 ELM_PART_TEXT_DEFAULT_GET(efl_ui_widget, NULL)
7270 /***********************************************************************************
7271 * TIZEN_ONLY_FEATURE: apply Tizen's color_class features. *
7272 ***********************************************************************************/
7273 /* Internal EO APIs and hidden overrides */
7274 EAPI EFL_FUNC_BODYV(elm_widget_class_color_set, Eina_Bool, EINA_FALSE,
7275 EFL_FUNC_CALL(color_class, r, g, b, a),
7276 const char *color_class, int r, int g, int b, int a)
7277 EAPI EFL_FUNC_BODYV(elm_widget_class_color_get, Eina_Bool, EINA_FALSE,
7278 EFL_FUNC_CALL(color_class, r, g, b, a),
7279 const char *color_class, int *r, int *g, int *b, int *a)
7280 EAPI EFL_FUNC_BODYV(elm_widget_class_color2_set, Eina_Bool, EINA_FALSE,
7281 EFL_FUNC_CALL(color_class, r, g, b, a),
7282 const char *color_class, int r, int g, int b, int a)
7283 EAPI EFL_FUNC_BODYV(elm_widget_class_color2_get, Eina_Bool, EINA_FALSE,
7284 EFL_FUNC_CALL(color_class, r, g, b, a),
7285 const char *color_class, int *r, int *g, int *b, int *a)
7286 EAPI EFL_FUNC_BODYV(elm_widget_class_color3_set, Eina_Bool, EINA_FALSE,
7287 EFL_FUNC_CALL(color_class, r, g, b, a),
7288 const char *color_class, int r, int g, int b, int a)
7289 EAPI EFL_FUNC_BODYV(elm_widget_class_color3_get, Eina_Bool, EINA_FALSE,
7290 EFL_FUNC_CALL(color_class, r, g, b, a),
7291 const char *color_class, int *r, int *g, int *b, int *a)
7292 EAPI EFL_VOID_FUNC_BODYV(elm_widget_class_color_del,
7293 EFL_FUNC_CALL(color_class),
7294 const char *color_class)
7295 EAPI EFL_VOID_FUNC_BODY(elm_widget_class_color_clear)
7297 static Eina_Bool _elm_widget_class_color_set(Eo *obj, Elm_Widget_Smart_Data *sd EINA_UNUSED, const char *color_class, int r, int g, int b, int a);
7298 static Eina_Bool _elm_widget_class_color_get(Eo *obj, Elm_Widget_Smart_Data *sd EINA_UNUSED, const char *color_class, int *r, int *g, int *b, int *a);
7299 static Eina_Bool _elm_widget_class_color2_set(Eo *obj, Elm_Widget_Smart_Data *sd EINA_UNUSED, const char *color_class, int r, int g, int b, int a);
7300 static Eina_Bool _elm_widget_class_color2_get(Eo *obj, Elm_Widget_Smart_Data *sd EINA_UNUSED, const char *color_class, int *r, int *g, int *b, int *a);
7301 static Eina_Bool _elm_widget_class_color3_set(Eo *obj, Elm_Widget_Smart_Data *sd EINA_UNUSED, const char *color_class, int r, int g, int b, int a);
7302 static Eina_Bool _elm_widget_class_color3_get(Eo *obj, Elm_Widget_Smart_Data *sd EINA_UNUSED, const char *color_class, int *r, int *g, int *b, int *a);
7303 static void _elm_widget_class_color_del(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd, const char *color_class);
7304 static void _elm_widget_class_color_clear(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd);
7310 #define EFL_UI_WIDGET_EXTRA_OPS \
7311 EFL_CANVAS_GROUP_ADD_DEL_OPS(efl_ui_widget), \
7312 ELM_PART_CONTENT_DEFAULT_OPS(efl_ui_widget), \
7313 ELM_PART_TEXT_DEFAULT_OPS(efl_ui_widget), \
7314 EFL_OBJECT_OP_FUNC(efl_canvas_object_is_frame_object_set, _efl_ui_widget_efl_canvas_object_is_frame_object_set), \
7315 EFL_OBJECT_OP_FUNC(efl_dbg_info_get, _efl_ui_widget_efl_object_dbg_info_get), \
7316 /*********************************************************************************** \
7317 * TIZEN_ONLY_FEATURE: apply Tizen's color_class features. * \
7318 ***********************************************************************************/ \
7319 EFL_OBJECT_OP_FUNC(elm_widget_class_color_set, _elm_widget_class_color_set), \
7320 EFL_OBJECT_OP_FUNC(elm_widget_class_color_get, _elm_widget_class_color_get), \
7321 EFL_OBJECT_OP_FUNC(elm_widget_class_color2_set, _elm_widget_class_color2_set), \
7322 EFL_OBJECT_OP_FUNC(elm_widget_class_color2_get, _elm_widget_class_color2_get), \
7323 EFL_OBJECT_OP_FUNC(elm_widget_class_color3_set, _elm_widget_class_color3_set), \
7324 EFL_OBJECT_OP_FUNC(elm_widget_class_color3_get, _elm_widget_class_color3_get), \
7325 EFL_OBJECT_OP_FUNC(elm_widget_class_color_del, _elm_widget_class_color_del), \
7326 EFL_OBJECT_OP_FUNC(elm_widget_class_color_clear, _elm_widget_class_color_clear)
7332 // TIZEN_ONLY(20150709) : atspi relations api
7333 EOLIAN static Efl_Access_Relation_Set
7334 _efl_ui_widget_efl_access_object_relation_set_get(const Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd)
7336 return efl_access_relation_set_clone(&sd->atspi_custom_relations);
7338 EOLIAN static Eina_Bool
7339 _efl_ui_widget_efl_access_object_relationship_append(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd, Efl_Access_Relation_Type type, const Eo *relation_obj)
7341 return efl_access_relation_set_relation_append(&sd->atspi_custom_relations, type, relation_obj);
7345 _efl_ui_widget_efl_access_object_relationship_remove(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd, Efl_Access_Relation_Type type, const Eo *relation_obj)
7347 efl_access_relation_set_relation_remove(&sd->atspi_custom_relations, type, relation_obj);
7351 _efl_ui_widget_efl_access_object_relationships_clear(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd)
7353 efl_access_relation_set_free(&sd->atspi_custom_relations);
7354 sd->atspi_custom_relations = NULL;
7357 EOLIAN static Elm_Atspi_Relation_Set
7358 _elm_widget_item_efl_access_object_relation_set_get(const Eo *obj EINA_UNUSED, Elm_Widget_Item_Data *sd)
7360 return efl_access_relation_set_clone(&sd->atspi_custom_relations);
7363 EOLIAN static Eina_Bool
7364 _elm_widget_item_efl_access_object_relationship_append(Eo *obj EINA_UNUSED, Elm_Widget_Item_Data *sd, Efl_Access_Relation_Type type, const Eo *relation_obj)
7366 return efl_access_relation_set_relation_append(&sd->atspi_custom_relations, type, relation_obj);
7370 _elm_widget_item_efl_access_object_relationship_remove(Eo *obj EINA_UNUSED, Elm_Widget_Item_Data *sd, Efl_Access_Relation_Type type, const Eo *relation_obj)
7372 efl_access_relation_set_relation_remove(&sd->atspi_custom_relations, type, relation_obj);
7376 _elm_widget_item_efl_access_object_relationships_clear(Eo *obj EINA_UNUSED, Elm_Widget_Item_Data *sd)
7378 efl_access_relation_set_free(&sd->atspi_custom_relations);
7379 sd->atspi_custom_relations = NULL;
7381 //////////////////////////////
7383 //TIZEN_ONLY(20160726): add API elm_atspi_accessible_can_highlight_set/get
7385 _children_highlight_check(Eo *obj)
7387 Eina_List *children, *l;
7390 if (_elm_object_accessibility_currently_highlighted_get() == (void *)obj)
7392 efl_access_component_highlight_clear(obj);
7396 children = efl_access_object_access_children_get(obj);
7397 EINA_LIST_FOREACH(children, l, child)
7399 if (_children_highlight_check(child)) return EINA_TRUE;
7406 _efl_ui_widget_efl_access_object_can_highlight_set(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *_pd, Eina_Bool can_highlight)
7408 if (!can_highlight) _children_highlight_check(obj);
7409 _pd->can_highlight = !!can_highlight;
7412 EOLIAN static Eina_Bool
7413 _efl_ui_widget_efl_access_object_can_highlight_get(const Eo *obj, Elm_Widget_Smart_Data *_pd EINA_UNUSED)
7415 return _elm_widget_highlightable(obj);
7419 _elm_widget_item_efl_access_object_can_highlight_set(Eo *obj EINA_UNUSED, Elm_Widget_Item_Data *_pd, Eina_Bool can_highlight)
7421 if (!can_highlight) _children_highlight_check(obj);
7422 _pd->can_highlight = !!can_highlight;
7425 EOLIAN static Eina_Bool
7426 _elm_widget_item_efl_access_object_can_highlight_get(const Eo *obj, Elm_Widget_Item_Data *_pd EINA_UNUSED)
7428 return _elm_widget_item_highlightable((Eo *)obj);
7432 // TIZEN_ONLY(20150705): Genlist item align feature
7434 elm_widget_scroll_item_align_enabled_set(Evas_Object *obj,
7435 Eina_Bool scroll_item_align_enable)
7438 if (sd->scroll_item_align_enable == scroll_item_align_enable) return;
7439 sd->scroll_item_align_enable = scroll_item_align_enable;
7443 elm_widget_scroll_item_align_enabled_get(const Evas_Object *obj)
7445 API_ENTRY return EINA_FALSE;
7446 return sd->scroll_item_align_enable;
7450 //TIZEN_ONLY(20150717) add widget name setter
7452 _efl_ui_widget_efl_access_object_i18n_name_set(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data* _pd EINA_UNUSED, const char *name)
7454 //TIZEN_ONLY(20220826): Remove markup from accessible name
7457 text = _elm_util_mkup_to_text(name); // NULL is OK
7458 eina_stringshare_replace(&_pd->name, text);
7464 //TIZEN_ONLY(20161111) add widget/widget_item description get/set
7466 _efl_ui_widget_efl_access_object_description_set(Eo *obj EINA_UNUSED, Efl_Ui_Widget_Data* _pd, const char *description)
7468 if (_pd->description)
7469 eina_stringshare_del(_pd->description);
7471 _pd->description = eina_stringshare_add(description);
7474 EOLIAN static const char*
7475 _efl_ui_widget_efl_access_object_description_get(const Eo *obj EINA_UNUSED, Efl_Ui_Widget_Data *_pd EINA_UNUSED)
7477 const char *ret = NULL;
7478 ret = efl_access_object_description_get(efl_super(obj, EFL_UI_WIDGET_CLASS));
7479 if (ret) return ret;
7482 if (_pd->atspi_translation_domain)
7483 return dgettext(_pd->atspi_translation_domain, _pd->description);
7485 return _pd->description;
7489 //TIZEN_ONLY(20171108): make atspi_proxy work
7491 _proxy_widget_move_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
7496 evas_object_geometry_get(obj, &x, &y, NULL, NULL);
7497 elm_atspi_bridge_utils_proxy_offset_set(proxy, x, y);
7501 _on_widget_del(void *data, const Efl_Event *event)
7504 evas_object_event_callback_del_full(event->object, EVAS_CALLBACK_MOVE,
7505 _proxy_widget_move_cb, plug);
7506 efl_access_object_attribute_del(event->object, "child_bus");
7511 _on_proxy_connected_cb(void *data, const Efl_Event *event)
7514 Evas_Object *widget = data;
7516 evas_object_geometry_get(widget, &x, &y, NULL, NULL);
7517 elm_atspi_bridge_utils_proxy_offset_set(event->object, x, y);
7519 evas_object_event_callback_add(widget, EVAS_CALLBACK_MOVE, _proxy_widget_move_cb, event->object);
7523 //TIZEN_ONLY(20161111) add widget/widget_item description get/set
7525 _elm_widget_item_efl_access_object_description_set(Eo *obj EINA_UNUSED, Elm_Widget_Item_Data* _pd EINA_UNUSED, const char *description)
7527 if (_pd->description)
7528 eina_stringshare_del(_pd->description);
7530 _pd->description = eina_stringshare_add(description);
7534 _elm_widget_item_efl_access_object_description_get(const Eo *obj EINA_UNUSED, Elm_Widget_Item_Data *_pd EINA_UNUSED)
7536 const char *ret = NULL;
7537 ret = efl_access_object_description_get(efl_super(obj, ELM_WIDGET_ITEM_CLASS));
7538 if (ret) return ret;
7541 if (_pd->atspi_translation_domain)
7542 return dgettext(_pd->atspi_translation_domain, _pd->description);
7544 return _pd->description;
7548 //TIZEN_ONLY(20150713) : add atspi name setter to widget_item
7550 _elm_widget_item_efl_access_object_i18n_name_set(Eo *obj EINA_UNUSED, Elm_Widget_Item_Data* _pd EINA_UNUSED, const char *name)
7552 //TIZEN_ONLY(20220826): Remove markup from accessible name
7555 text = _elm_util_mkup_to_text(name); // NULL is OK
7556 eina_stringshare_replace(&_pd->name, text);
7562 _elm_widget_item_efl_access_object_i18n_name_get(const Eo *obj EINA_UNUSED, Elm_Widget_Item_Data *_pd EINA_UNUSED)
7564 //TIZEN_ONLY(20190922): add name callback, description callback.
7565 const char *ret = NULL;
7566 ret = efl_access_object_i18n_name_get(efl_super(obj, ELM_WIDGET_ITEM_CLASS));
7567 if (ret) return ret;
7573 if (_pd->atspi_translation_domain)
7574 return dgettext(_pd->atspi_translation_domain, _pd->name);
7583 //TIZEN_ONLY(20150731) : add i18n support for name and description
7585 _efl_ui_widget_efl_access_object_translation_domain_set(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *_pd, const char *domain)
7587 eina_stringshare_replace(&_pd->atspi_translation_domain, domain);
7590 EOLIAN static const char*
7591 _efl_ui_widget_efl_access_object_translation_domain_get(const Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *_pd)
7593 return _pd->atspi_translation_domain;
7597 _elm_widget_item_efl_access_object_translation_domain_set(Eo *obj EINA_UNUSED, Elm_Widget_Item_Data *_pd, const char *domain)
7599 eina_stringshare_replace(&_pd->atspi_translation_domain, domain);
7602 EOLIAN static const char*
7603 _elm_widget_item_efl_access_object_translation_domain_get(const Eo *obj EINA_UNUSED, Elm_Widget_Item_Data *_pd)
7605 return _pd->atspi_translation_domain;
7609 static int _sort_vertically(const void *data1, const void *data2)
7612 evas_object_geometry_get(data1, NULL, &y1, NULL, NULL);
7613 evas_object_geometry_get(data2, NULL, &y2, NULL, NULL);
7615 return y1 < y2 ? -1 : 1;
7618 static int _sort_horizontally(const void *data1, const void *data2)
7621 evas_object_geometry_get(data1, &x1, NULL, NULL, NULL);
7622 evas_object_geometry_get(data2, &x2, NULL, NULL, NULL);
7624 return x1 < x2 ? -1 : 1;
7627 static Eina_List *_lines_split(Eina_List *children)
7630 Eina_List *lines, *line, *l;
7631 Evas_Coord yl, y, hl, h;
7632 lines = line = NULL;
7634 if (!children) return NULL;
7636 EINA_LIST_FOREACH(children, l, c)
7638 evas_object_geometry_get(c, NULL, &yl, NULL, &hl);
7640 /* remove child if its height == 0 */
7644 EINA_LIST_FREE(children, c)
7646 evas_object_geometry_get(c, NULL, &y, NULL, &h);
7648 /* remove child if its height == 0 */
7649 if (h == 0) continue;
7651 if ((yl + (int)(0.25 * hl)) >= y)
7654 line = eina_list_append(line,c);
7658 // finish current line & start new
7659 lines = eina_list_append(lines, line);
7661 line = eina_list_append(NULL, c);
7665 return eina_list_append(lines, line);
7669 //TIZEN_ONLY(20170621) handle atspi proxy connection at runtime
7671 plug_type_proxy_get(const Eo *obj, Evas_Object *widget)
7674 const char *plug_id;
7675 char *svcname, *svcnum;
7677 if ((plug_id = evas_object_data_get(widget, "___PLUGID")) != NULL)
7679 // TIZEN_ONLY(20160930) : endless recursion fix
7680 efl_access_object_attribute_append(efl_super(obj, MY_CLASS), "___PlugID", plug_id);
7681 efl_access_object_role_set((Eo *)obj, EFL_ACCESS_ROLE_EMBEDDED);
7683 proxy = evas_object_data_get(widget, "__widget_proxy");
7684 // TIZEN_ONLY(20171109) : fix for invalid proxy object, when at-spi has been restarted
7687 if (!evas_object_data_get(proxy, "__proxy_invalid")) return proxy;
7688 evas_object_data_del(widget, "__widget_proxy");
7692 if (_elm_atspi_bridge_plug_id_split(plug_id, &svcname, &svcnum))
7694 proxy = _elm_atspi_bridge_utils_proxy_create((Eo *)obj, svcname, atoi(svcnum), ELM_ATSPI_PROXY_TYPE_PLUG);
7695 evas_object_data_set(widget, "__widget_proxy", proxy);
7696 efl_event_callback_add(widget, EFL_EVENT_DEL, _on_widget_del, proxy);
7697 efl_event_callback_add(proxy, ELM_ATSPI_PROXY_EVENT_CONNECTED, _on_proxy_connected_cb, widget);
7698 elm_atspi_bridge_utils_proxy_connect(proxy);
7708 elm_widget_atspi_plug_type_proxy_get(Evas_Object *obj)
7710 Elm_Widget_Smart_Data *wd;
7711 Evas_Object *widget;
7713 wd = efl_data_scope_get(obj, EFL_UI_WIDGET_CLASS);
7714 if (!wd) return NULL;
7717 for (unsigned int i = 0; i < eina_array_count(wd->children); ++i)
7719 widget = eina_array_data_get(wd->children, i);
7720 proxy = plug_type_proxy_get(obj, widget);
7728 //TIZEN_ONLY(20161107): enhance elm_atspi_accessible_can_highlight_set to set can_hihglight property to its children
7730 _elm_widget_highlightable(const Evas_Object *obj)
7734 Elm_Widget_Smart_Data *wd = efl_data_scope_get(obj, EFL_UI_WIDGET_CLASS);
7735 if (!wd) return EINA_FALSE;
7736 if (!wd->can_highlight) return EINA_FALSE;
7738 parent = efl_provider_find(efl_parent_get(obj), EFL_ACCESS_OBJECT_MIXIN);
7739 while (parent && !efl_isa(parent, ELM_ATSPI_APP_OBJECT_CLASS))
7741 //TIZEN_ONLY(20160929) : atspi: Improves how to find the can_highlight of the widget
7742 if (!_elm_widget_can_highlight_get_by_class(parent)) return EINA_FALSE;
7744 parent = efl_provider_find(efl_parent_get(parent), EFL_ACCESS_OBJECT_MIXIN);
7751 elm_widget_scroll_item_valign_set(Evas_Object *obj,
7752 const char *scroll_item_valign)
7755 if (sd->scroll_item_valign) eina_stringshare_del(sd->scroll_item_valign);
7756 if (!scroll_item_valign) sd->scroll_item_valign = NULL;
7757 else sd->scroll_item_valign = eina_stringshare_add(scroll_item_valign);
7761 elm_widget_scroll_item_valign_get(const Evas_Object *obj)
7763 API_ENTRY return NULL;
7764 return sd->scroll_item_valign;
7768 /* TIZEN_ONLY(20180504): add missing item class names and fix edje_class parse rule for legacy */
7770 _elm_widget_item_legacy_type_get(const Evas_Object *obj)
7775 ret = efl_class_name_get(efl_class_get(obj));
7777 /* If the given widget is created for legacy,
7778 * convert type name to legacy. */
7779 for (i = 0; legacy_type_table[i][0] ; i++)
7781 if (eina_streq(ret, legacy_type_table[i][0]))
7782 return legacy_type_table[i][1];
7790 _efl_ui_widget_focus_disabled_handle(Eo *obj, Elm_Widget_Smart_Data *_pd EINA_UNUSED)
7792 efl_ui_widget_focus_tree_unfocusable_handle(obj);
7795 EOLIAN static unsigned int
7796 _efl_ui_widget_focus_order_get(const Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd)
7798 return sd->focus_order;
7801 EOLIAN static Evas_Object*
7802 _efl_ui_widget_newest_focus_order_get(const Eo *obj, Elm_Widget_Smart_Data *sd, unsigned int *newest_focus_order, Eina_Bool can_focus_only)
7804 Evas_Object *child, *cur, *best;
7806 if (!evas_object_visible_get(obj)
7807 || (elm_widget_disabled_get(obj))
7808 || (elm_widget_tree_unfocusable_get(obj)))
7812 if (*newest_focus_order < sd->focus_order)
7814 if (!can_focus_only || elm_widget_can_focus_get(obj))
7816 *newest_focus_order = sd->focus_order;
7817 best = (Evas_Object *)obj;
7820 for (unsigned int i = 0; i < eina_array_count(sd->children); ++i)
7822 child = eina_array_data_get(sd->children, i);
7823 if (!_elm_widget_is(child)) continue;
7825 cur = efl_ui_widget_newest_focus_order_get
7826 (child, newest_focus_order, can_focus_only);
7833 EOLIAN static Eina_Bool
7834 _efl_ui_widget_focus_next_manager_is(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *_pd EINA_UNUSED)
7836 WRN("The %s widget does not implement the \"focus_next/focus_next_manager_is\" functions.",
7837 efl_class_name_get(efl_class_get(obj)));
7842 _efl_ui_widget_focus_direction_manager_is(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *_pd EINA_UNUSED)
7844 WRN("The %s widget does not implement the \"focus_direction/focus_direction_manager_is\" functions.",
7845 efl_class_name_get(efl_class_get(obj)));
7849 //TIZEN_ONLY(20180607): Restore legacy focus
7851 _efl_ui_widget_focus_mouse_up_handle(Eo *obj, Elm_Widget_Smart_Data *_pd EINA_UNUSED)
7854 if (!_is_focusable(obj)) return;
7856 efl_ui_widget_focus_steal(obj, NULL);
7859 //TIZEN_ONLY(20160929) : atspi: Improves how to find the can_highlight of the widget
7861 _elm_widget_can_highlight_get_by_class(Eo *obj)
7863 if (efl_isa(obj, ELM_WIDGET_ITEM_CLASS))
7865 Elm_Widget_Item_Data *id = efl_data_scope_get(obj, ELM_WIDGET_ITEM_CLASS);
7866 if (!id) return EINA_FALSE;
7867 if (!id->can_highlight) return EINA_FALSE;
7871 Elm_Widget_Smart_Data *wd = efl_data_scope_get(obj, EFL_UI_WIDGET_CLASS);
7872 if (!wd) return EINA_FALSE;
7873 if (!wd->can_highlight) return EINA_FALSE;
7879 //TIZEN_ONLY(20161107): enhance elm_atspi_accessible_can_highlight_set to set can_hihglight property to its children
7881 _elm_widget_item_highlightable(Elm_Object_Item *item)
7885 Elm_Widget_Item_Data *id = efl_data_scope_get(item, ELM_WIDGET_ITEM_CLASS);
7886 if (!id) return EINA_FALSE;
7887 if (!id->can_highlight) return EINA_FALSE;
7889 parent = efl_provider_find(efl_parent_get(item), EFL_ACCESS_OBJECT_MIXIN);
7890 while (parent && !efl_isa(parent, ELM_ATSPI_APP_OBJECT_CLASS))
7892 //TIZEN_ONLY(20160929) : atspi: Improves how to find the can_highlight of the widget
7893 if (!_elm_widget_can_highlight_get_by_class(parent)) return EINA_FALSE;
7895 parent = efl_provider_find(efl_parent_get(parent), EFL_ACCESS_OBJECT_MIXIN);
7901 //TIZEN_ONLY(20170206): Add check the object is in the scroller content size
7903 _accessible_object_on_scroll_is(Eo* obj)
7905 /* in case of genlist item, the item->view is NULL if item is unrealized.
7906 this function is used to check if obj could have HIGHLIGHTABLE or not.
7907 the unrealized genlist item should have HIGHLIGHTABLE state.
7908 so if obj is NULL return EINA_TRUE */
7909 if(!obj) return EINA_TRUE;
7911 Evas_Object *target = obj;
7912 Evas_Object *parent = NULL;
7913 Evas_Coord x, y, w, h, wx, wy, ww = 0, wh = 0, nx = 0, ny = 0;
7915 evas_object_geometry_get(target, &x, &y ,&w, &h);
7917 if (elm_widget_is(target))
7918 parent = elm_widget_parent_get(target);
7920 parent = elm_widget_parent_widget_get(target);
7924 if (efl_isa(parent, ELM_INTERFACE_SCROLLABLE_MIXIN))
7926 evas_object_geometry_get(parent, &wx, &wy, NULL, NULL);
7927 elm_interface_scrollable_content_size_get(parent, &ww, &wh);
7928 elm_interface_scrollable_content_pos_get(parent, &nx, &ny);
7930 /* widget implements scrollable interface but does not use scoller
7931 in this case, use widget geometry */
7932 if (ww == 0 || wh == 0)
7934 INF("%s is zero sized scrollable content", efl_class_name_get(efl_class_get(parent)));
7935 evas_object_geometry_get(parent, NULL, NULL, &ww, &wh);
7941 if (((wx < x) && (wx + ww < x)) || ((wx > x + w) && (wx + ww > x + w)) ||
7942 ((wy < y) && (wy + wh < y)) || ((wy > y + h) && (wy + wh > y + h)))
7947 parent = elm_widget_parent_get(parent);
7954 //TIZEN_ONLY(20180607): Restore legacy focus
7958 * Resets the focus_move_policy mode from the system one
7959 * for widgets that are in automatic mode.
7961 * @param obj The widget.
7965 _elm_widget_focus_move_policy_reload(Evas_Object *obj)
7968 Elm_Focus_Move_Policy focus_move_policy = elm_config_focus_move_policy_get();
7970 if (efl_ui_widget_focus_move_policy_automatic_get(obj) &&
7971 (sd->focus_move_policy != focus_move_policy))
7973 sd->focus_move_policy = focus_move_policy;
7978 _efl_ui_widget_focus_reconfigure(Eo *obj, Elm_Widget_Smart_Data *_pd EINA_UNUSED)
7983 for (unsigned int i = 0; i < eina_array_count(sd->children); ++i)
7985 child = eina_array_data_get(sd->children, i);
7986 if (elm_widget_is(child))
7987 efl_ui_widget_focus_reconfigure(child);
7990 if (sd->hover_obj) efl_ui_widget_focus_reconfigure(sd->hover_obj);
7992 _elm_widget_focus_move_policy_reload(obj);
7996 //TIZEN_ONLY(20160329): widget: improve accessible_at_point getter (a8aff0423202b9a55dbb3843205875226678fbd6)
7998 _coordinate_system_based_point_translate(const Eo *obj, Eina_Bool screen_coords, int *x, int *y)
8006 ee = ecore_evas_ecore_evas_get(evas_object_evas_get(obj));
8009 ecore_evas_geometry_get(ee, &ee_x, &ee_y, NULL, NULL);
8015 static Evas_Object *
8016 _parent_get(Evas_Object *obj)
8018 Evas_Object *parent;
8020 parent = evas_object_smart_parent_get(obj);
8023 if (strcmp("Efl_Ui_Win", efl_class_name_get(efl_class_get(obj))))
8024 parent = elm_widget_parent_get(obj);
8031 _is_inside(Evas_Object *obj, int x, int y)
8033 Eina_Bool ret = EINA_TRUE;
8038 if (efl_isa(obj, ELM_WIDGET_ITEM_CLASS))
8040 Elm_Widget_Item_Data *id = efl_data_scope_get(obj, ELM_WIDGET_ITEM_CLASS);
8041 evas_object_geometry_get(id->view, &cx, &cy, &cw, &ch);
8044 evas_object_geometry_get(obj, &cx, &cy, &cw, &ch);
8046 /* check the point is out of bound */
8047 if (x < cx || x > cx + cw || y < cy || y > cy + ch)
8055 _is_ancestor_of(Evas_Object *smart_parent, const Evas_Object *obj)
8057 Eina_Bool ret = EINA_FALSE;
8058 Evas_Object *parent = elm_widget_parent_get(obj);
8061 /* No need to check more, the smart_parent is parent of obj */
8062 if (smart_parent == parent)
8067 parent = elm_widget_parent_get(parent);
8074 _acceptable_child_is(Eo *obj)
8076 Efl_Access_Role role;
8077 Eina_List *children;
8078 Efl_Access_State_Set ss;
8080 role = efl_access_object_role_get(obj);
8083 case EFL_ACCESS_ROLE_IMAGE:
8084 case EFL_ACCESS_ROLE_ICON:
8085 case EFL_ACCESS_ROLE_REDUNDANT_OBJECT:
8086 /* remove unacceptable leaf node */
8087 children = efl_access_object_access_children_get(obj);
8088 if (!children) return EINA_FALSE;
8091 case EFL_ACCESS_ROLE_PANEL:
8092 /* remove closed panel fron children list */
8093 ss = efl_access_object_state_set_get(obj);
8094 if (!STATE_TYPE_GET(ss, EFL_ACCESS_STATE_TYPE_SHOWING)) return EINA_FALSE;
8104 static int _sort_by_size(const void *data1, const void *data2)
8109 evas_object_geometry_get(data1, NULL, NULL, &w, &h);
8110 evas_object_geometry_get(data2, NULL, NULL, &w2, &h2);
8112 if ((w * h) > (w2 * h2)) return 1;
8117 _elm_widget_atspi_role_acceptable_check(Eo *obj)
8119 Efl_Access_Role role;
8120 role = efl_access_object_role_get(obj);
8124 case EFL_ACCESS_ROLE_APPLICATION:
8125 case EFL_ACCESS_ROLE_FILLER:
8126 case EFL_ACCESS_ROLE_SCROLL_PANE:
8127 case EFL_ACCESS_ROLE_SPLIT_PANE:
8128 case EFL_ACCESS_ROLE_WINDOW:
8129 case EFL_ACCESS_ROLE_IMAGE:
8130 case EFL_ACCESS_ROLE_LIST:
8131 case EFL_ACCESS_ROLE_ICON:
8132 case EFL_ACCESS_ROLE_TOOL_BAR:
8133 case EFL_ACCESS_ROLE_REDUNDANT_OBJECT:
8134 case EFL_ACCESS_ROLE_COLOR_CHOOSER:
8135 case EFL_ACCESS_ROLE_TREE_TABLE:
8136 case EFL_ACCESS_ROLE_PAGE_TAB_LIST:
8137 case EFL_ACCESS_ROLE_PAGE_TAB:
8138 case EFL_ACCESS_ROLE_SPIN_BUTTON:
8139 case EFL_ACCESS_ROLE_INPUT_METHOD_WINDOW:
8140 case EFL_ACCESS_ROLE_EMBEDDED:
8141 case EFL_ACCESS_ROLE_INVALID:
8142 case EFL_ACCESS_ROLE_NOTIFICATION:
8152 _child_object_at_point_get(const Eo *obj, int x, int y)
8154 Eina_List *l, *l_next, *children, *valid_children = NULL;
8159 children = efl_access_object_access_children_get(obj);
8161 EINA_LIST_FOREACH(children, l, child)
8163 if (_is_inside(child, x, y))
8164 valid_children = eina_list_append(valid_children, child);
8167 EINA_LIST_FOREACH_SAFE(valid_children, l, l_next, child)
8169 children = efl_access_object_access_children_get(child);
8171 /* do not use unacceptable leaf node */
8172 if (!_elm_widget_atspi_role_acceptable_check(child) &&
8173 eina_list_count(children) == 0)
8174 valid_children = eina_list_remove_list(valid_children, l);
8177 count = eina_list_count(valid_children);
8180 valid_children = eina_list_sort(valid_children, -1, _sort_by_size);
8181 target = eina_list_nth(valid_children, 0);
8183 //TIZEN_ONLY(20191209):Do not accept children with unacceptable role
8184 //return _child_object_at_point_get(target, x, y);
8185 Eo *ret = (Eo *)_child_object_at_point_get(target, x, y);
8186 if (ret) return ret;
8190 //TIZEN_ONLY(20191209):Do not accept children with unacceptable role
8192 return _elm_widget_atspi_role_acceptable_check((Eo *)obj) ? (Eo *)obj : NULL;
8198 _accessible_at_point_top_down_get(const Eo *obj, Elm_Widget_Smart_Data *_pd EINA_UNUSED, Eina_Bool screen_coords, int x, int y)
8200 Eina_List *l, *l2, *children, *valid_children = NULL;
8202 Evas_Object *stack_item;
8204 // TIZEN_ONLY(20160705) - enable atspi_proxy to work
8206 Evas_Coord px, py, pw, ph;
8209 _coordinate_system_based_point_translate(obj, screen_coords, &x, &y);
8211 children = efl_access_object_access_children_get(obj);
8213 EINA_LIST_FOREACH(children, l2, child)
8215 if (_is_inside(child, x, y) && _acceptable_child_is(child))
8216 valid_children = eina_list_append(valid_children, child);
8219 /* If there is only one valid child at point, then return it.
8220 The evas_tree_objects_at_xy_get could not find proper object,
8221 if application does not have well aligned objects. */
8222 if (eina_list_count(valid_children) == 1)
8224 eina_list_free(children);
8225 child = eina_list_nth(valid_children, 0);
8229 /* Get evas_object stacked at given x,y coordinates starting from top */
8230 Eina_List *stack = evas_tree_objects_at_xy_get(evas_object_evas_get(obj), NULL, x, y);
8231 /* Foreach stacked object starting from top */
8232 EINA_LIST_FOREACH(stack, l, stack_item)
8234 /* Foreach at-spi valid children traverse stack_item evas_objects hierarchy */
8235 EINA_LIST_FOREACH(valid_children, l2, child)
8237 Efl_Access_Role role;
8238 role = efl_access_object_role_get(child);
8239 if (role == EFL_ACCESS_ROLE_REDUNDANT_OBJECT)
8241 /* The redundant object ignores */
8244 /* Compare object used to compare with stacked evas objects */
8245 compare_obj = child;
8246 /* In case of widget_items compare should be different then elm_widget_ item object */
8247 if (efl_isa(child, ELM_WIDGET_ITEM_CLASS))
8249 Elm_Widget_Item_Data *id = efl_data_scope_get(child, ELM_WIDGET_ITEM_CLASS);
8250 compare_obj = id->view;
8251 if (TIZEN_PROFILE_WEARABLE)
8253 Eo* it_view = evas_object_image_source_get(stack_item);
8254 if (it_view && it_view == compare_obj)
8256 eina_list_free(children);
8257 eina_list_free(stack);
8262 /* In case of access object compare should be 'wrapped' evas_object */
8263 if (efl_isa(child, ELM_ACCESS_CLASS))
8265 Elm_Access_Info *info = _elm_access_info_get(child);
8266 if (!info) continue;
8267 compare_obj = info->part_object;
8269 /* In case of widget is registerd by elm_access_object_register */
8270 Evas_Object *ao = elm_access_object_get(child);
8273 eina_list_free(children);
8274 eina_list_free(stack);
8278 /* In case of ewk wrapper object compare with internal ewk_view evas_object */
8279 if (efl_isa(child, ELM_ATSPI_EWK_WRAPPER_CLASS))
8281 compare_obj = elm_atspi_ewk_wrapper_ewk_view_get(child);
8284 /* If spacial eo children do not have backing evas_object continue with search */
8288 Evas_Object *smart_parent = stack_item;
8289 while (smart_parent)
8291 if (smart_parent == compare_obj)
8293 eina_list_free(children);
8294 eina_list_free(stack);
8298 // TIZEN_ONLY(20160705) - enable atspi_proxy to work
8299 proxy = evas_object_data_get(smart_parent, "__widget_proxy");
8302 // TIZEN_ONLY(20171109) : fix for invalid proxy object, when at-spi has been restarted
8304 parent = efl_provider_find(efl_parent_get(smart_parent), EFL_ACCESS_OBJECT_MIXIN);
8305 proxy = plug_type_proxy_get(parent, smart_parent);
8307 evas_object_geometry_get(smart_parent, &px, &py, &pw, &ph);
8308 if (x >= px && x <= px + pw && y >= py && y <= py +ph)
8310 eina_list_free(children);
8311 eina_list_free(stack);
8317 smart_parent = _parent_get(smart_parent);
8318 if (_is_ancestor_of(smart_parent, obj)) break;
8323 eina_list_free(children);
8324 eina_list_free(stack);
8328 static int _sort_by_repeat_events(const void *data1, const void *data2)
8330 Evas_Object *ao1, *ao2;
8331 Eina_Bool repeat1, repeat2;
8333 ao1 = elm_access_object_get(data1);
8334 ao2 = elm_access_object_get(data2);
8336 repeat1 = evas_object_repeat_events_get(data1);
8337 repeat2 = evas_object_repeat_events_get(data2);
8339 if (repeat1 != repeat2)
8341 if (repeat1 && !ao1) return 1;
8345 if (repeat1 && !ao1 && ao2) return 1;
8351 static Eo *_item_at_point_get(Evas_Object *obj, int x, int y)
8354 Eina_List *l, *children;
8356 children = efl_access_object_access_children_get(obj);
8358 EINA_LIST_FOREACH(children, l, child)
8360 if (_is_inside(child, x, y)) return child;
8363 ERR("No child at point (%d, %d) on object %p", x, y, obj);
8367 //TIZEN_ONLY(20171108): bring HIGHLIGHT related changes
8369 _efl_ui_widget_efl_access_component_accessible_at_point_get(Eo *obj, Elm_Widget_Smart_Data *_pd EINA_UNUSED, Eina_Bool screen_coords, int x, int y)
8371 Elm_Atspi_Role role;
8373 Evas_Object *stack_item;
8375 role = efl_access_object_role_get(obj);
8379 case ELM_ATSPI_ROLE_WINDOW:
8380 /* this is for webapp which is using window only */
8381 if (evas_object_data_get(obj, "__PlugID"))
8383 Eina_List *children;
8385 children = efl_access_object_access_children_get(obj);
8386 EINA_LIST_FOREACH(children, l, child)
8388 if (efl_access_object_role_get(child) == EFL_ACCESS_ROLE_EMBEDDED)
8392 DBG("Find accessible from bottom");
8394 case ELM_ATSPI_ROLE_INPUT_METHOD_WINDOW:
8395 case ELM_ATSPI_ROLE_DIALOG:
8396 case ELM_ATSPI_ROLE_PAGE_TAB:
8397 //TIZEN_ONLY(20220915): Use top-down at-point search for POPUP_MENU
8398 //case ELM_ATSPI_ROLE_POPUP_MENU: // Bottom-up search would find buttons absent from the AT-SPI tree in case of CtxPopup
8400 case ELM_ATSPI_ROLE_PANEL:
8401 DBG("Find accessible from bottom");
8405 return _accessible_at_point_top_down_get(obj, _pd, screen_coords, x, y);
8408 _coordinate_system_based_point_translate(obj, screen_coords, &x, &y);
8410 Eina_List *stack = evas_tree_objects_at_xy_get(evas_object_evas_get(obj), NULL, x, y);
8411 stack = eina_list_sort(stack, -1, _sort_by_repeat_events);
8413 EINA_LIST_FOREACH(stack, l, stack_item)
8415 Evas_Object *smart_parent = stack_item;
8416 while (smart_parent)
8418 /* If parent equals to obj, it is not necessary to go upper.
8419 So the top down logic would be better than NULL return. */
8420 if (smart_parent == obj)
8421 return _accessible_at_point_top_down_get(obj, _pd, screen_coords, x, y);
8423 Evas_Object *ao = elm_access_object_get(smart_parent);
8426 if (efl_isa(smart_parent, EFL_ACCESS_OBJECT_MIXIN))
8428 Eina_Bool acceptable = EINA_FALSE;
8430 role = efl_access_object_role_get(smart_parent);
8433 case EFL_ACCESS_ROLE_FILLER: /* ex: View of colorselector item is layout */
8434 case EFL_ACCESS_ROLE_ICON:
8435 case EFL_ACCESS_ROLE_IMAGE:
8436 case EFL_ACCESS_ROLE_REDUNDANT_OBJECT:
8437 case EFL_ACCESS_ROLE_WINDOW:
8438 DBG("Go for parent: %s (%p)\n", evas_object_type_get(smart_parent), smart_parent);
8440 case EFL_ACCESS_ROLE_LIST:
8441 item_child = _item_at_point_get(smart_parent, x, y);
8442 if (TIZEN_PROFILE_WEARABLE)
8444 item_child = _child_object_at_point_get(item_child, x, y);
8450 acceptable = EINA_TRUE;
8454 if (acceptable) return smart_parent;
8457 smart_parent = _parent_get(smart_parent);
8461 eina_list_free(stack);
8462 return _accessible_at_point_top_down_get(obj, _pd, screen_coords, x, y);
8464 // TIZEN_ONLY(20171114) Accessibility Highlight Frame added
8465 // EOLIAN static Eina_Bool
8466 // _elm_widget_item_efl_access_component_highlight_grab(Eo *obj, Elm_Widget_Item_Data *sd)
8468 // Evas_Object *win = elm_widget_top_get(sd->widget);
8469 // if (win && efl_isa(win, EFL_UI_WIN_CLASS))
8471 // _elm_win_accessibility_highlight_set(win, sd->view);
8472 // efl_access_state_changed_signal_emit(obj, EFL_ACCESS_STATE_TYPE_HIGHLIGHTED, EINA_TRUE);
8473 // return EINA_TRUE;
8475 // return EINA_FALSE;
8479 // EOLIAN static Eina_Bool
8480 // _elm_widget_item_efl_access_component_highlight_clear(Eo *obj, Elm_Widget_Item_Data *sd)
8482 // Evas_Object *win = elm_widget_top_get(sd->widget);
8483 // if (win && efl_isa(win, EFL_UI_WIN_CLASS))
8485 // if (_elm_win_accessibility_highlight_get(win) != sd->view)
8486 // return EINA_TRUE;
8488 // _elm_win_accessibility_highlight_set(win, NULL);
8489 // efl_access_state_changed_signal_emit(obj, EFL_ACCESS_STATE_TYPE_HIGHLIGHTED, EINA_FALSE);
8490 // return EINA_TRUE;
8492 // return EINA_FALSE;
8496 //TIZEN_ONLY(20170119): Show the object highlighted by highlight_grab when the object is completely out of the scroll
8498 _elm_widget_showing_geometry_get(Eo *obj, int *x, int *y, int *w, int *h)
8500 Evas_Object *parent;
8501 Evas_Coord px, py, sx, sy, sw, sh;
8509 evas_object_geometry_get(obj, x, y, w, h);
8511 if (elm_widget_is(obj))
8512 parent = elm_widget_parent_get(obj);
8514 parent = elm_widget_parent_widget_get(obj);
8518 if (efl_isa(parent, ELM_INTERFACE_SCROLLABLE_MIXIN))
8520 evas_object_geometry_get(parent, &sx, &sy, &sw, &sh);
8523 *x = *x > sx ? *x : sx;
8524 *y = *y > sy ? *y : sy;
8525 *w = px + *w < sx + sw ? px + *w - *x : sx + sw - *x;
8526 *h = py + *h < sy + sh ? py + *h - *y : sy + sh - *y;
8528 parent = elm_widget_parent_get(parent);
8533 _accessible_object_on_screen_is(Eo *obj, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h, Eina_Bool is_complete)
8535 if(!obj) return EINA_FALSE;
8537 Evas_Object *target = obj;
8538 Evas_Object *parent = NULL;
8539 Evas_Coord px, py, sx, sy, sw, sh, ox, oy, ow, oh;
8541 /* uninitialized data could be read */
8545 if (elm_widget_is(target))
8546 parent = elm_widget_parent_get(target);
8548 parent = elm_widget_parent_widget_get(target);
8552 if (efl_isa(parent, ELM_INTERFACE_SCROLLABLE_MIXIN))
8554 evas_object_geometry_get(parent, &sx, &sy, &sw, &sh);
8559 ox = is_complete ? ox : ox + ow;
8560 oy = is_complete ? oy : oy + oh;
8561 ox = ox > sx ? ox : sx;
8562 oy = oy > sy ? oy : sy;
8563 ow = px + ow < sx + sw ? px + ow - ox : sx + sw - ox;
8564 oh = py + oh < sy + sh ? py + oh - oy : sy + sh - oy;
8566 if (ow <= 0 || oh <= 0)
8569 parent = elm_widget_parent_get(parent);
8575 _accessible_scrollable_parent_list_get(const Eo *obj)
8577 if(!obj) return NULL;
8579 Evas_Object *parent = NULL;
8580 Eina_List *plist = NULL;
8582 if (elm_widget_is(obj))
8583 parent = elm_widget_parent_get(obj);
8585 parent = elm_widget_parent_widget_get(obj);
8589 if (_elm_scrollable_is(parent))
8590 plist = eina_list_append(plist, parent);
8592 parent = elm_widget_parent_get(parent);
8598 _accessible_highlight_region_show(Eo* obj)
8602 Evas_Object *target = obj;
8603 Evas_Object *parent = NULL;
8604 Evas_Object *parent_sub = NULL;
8605 Eina_List *plist, *plist_sub;
8608 Evas_Coord target_x, target_y, target_w, target_h;
8610 evas_object_geometry_get(target, &target_x, &target_y, &target_w, &target_h);
8612 plist = _accessible_scrollable_parent_list_get(target);
8613 if (!plist) return ;
8614 EINA_LIST_FOREACH(plist, l, parent)
8616 if(!_accessible_object_on_screen_is(target, target_x, target_y, target_w, target_h, EINA_TRUE))
8618 plist_sub = _accessible_scrollable_parent_list_get(parent);
8619 plist_sub = eina_list_prepend(plist_sub, parent);
8620 EINA_LIST_FOREACH(plist_sub, l2, parent_sub)
8622 Evas_Coord scroll_x = 0, scroll_y = 0;
8623 Evas_Coord scroll_x_back = 0, scroll_y_back = 0;
8624 Evas_Coord x, y, w, h;
8627 elm_interface_scrollable_content_region_get(parent_sub, &scroll_x_back, &scroll_y_back, NULL, NULL);
8628 evas_object_geometry_get(parent_sub, &px, &py, NULL, NULL);
8629 x = target_x; y = target_y; w = target_w; h = target_h;
8631 x -= (px - scroll_x_back);
8632 y -= (py - scroll_y_back);
8633 switch (_elm_config->focus_autoscroll_mode)
8635 case ELM_FOCUS_AUTOSCROLL_MODE_SHOW:
8636 elm_interface_scrollable_content_region_show(parent_sub, x, y, w, h);
8638 case ELM_FOCUS_AUTOSCROLL_MODE_BRING_IN:
8639 elm_interface_scrollable_region_bring_in(parent_sub, x, y, w, h);
8644 elm_interface_scrollable_content_region_get(parent_sub, &scroll_x, &scroll_y, NULL, NULL);
8646 target_x -= (scroll_x - scroll_x_back);
8647 target_y -= (scroll_y - scroll_y_back);
8649 if(_accessible_object_on_screen_is(target, target_x, target_y, target_w, target_h, EINA_FALSE))
8652 eina_list_free(plist_sub);
8656 eina_list_free(plist);
8660 //TIZEN_ONLY(20171011) : atspi : During the highlight grab, out signal is not sent.
8661 static Eo *_highlight_grabbing_object = NULL;
8664 _elm_widget_accessibility_highlight_grabbing_get(Eo *obj)
8666 return _highlight_grabbing_object == obj;
8670 _elm_widget_accessibility_highlight_grabbing_set(Eo *obj, Eina_Bool grabbing)
8674 if (!_highlight_grabbing_object)
8675 _highlight_grabbing_object = obj;
8676 else if (_highlight_grabbing_object == obj)
8677 ERR("trying to set grabbing for %p, but it's already set to this object", obj);
8679 ERR("trying to set grabbing for %p, but it's already set to %p", obj, _highlight_grabbing_object);
8683 if (_highlight_grabbing_object != obj)
8684 ERR("trying to clear grabbing for %p, but it's set to %p", obj, _highlight_grabbing_object);
8686 _highlight_grabbing_object = NULL;
8691 EOLIAN static Eina_Bool
8692 _efl_ui_widget_efl_access_component_highlight_grab(Eo *obj, Elm_Widget_Smart_Data *pd EINA_UNUSED)
8694 if(!obj) return EINA_FALSE;
8695 if(!_elm_atspi_enabled())
8698 // TIZEN_ONLY(20171020) : atspi : Do not send signal, if current object and highlight object are same
8699 if (_elm_object_accessibility_currently_highlighted_get() == obj)
8703 //TIZEN_ONLY(20171011) : atspi : During the highlight grab, out signal is not sent.
8704 _elm_widget_accessibility_highlight_grabbing_set(obj, EINA_TRUE);
8707 //TIZEN_ONLY(20170119): Show the object highlighted by highlight_grab when the object is completely out of the scroll
8708 _accessible_highlight_region_show(obj);
8711 elm_object_accessibility_highlight_set(obj, EINA_TRUE);
8712 efl_access_state_changed_signal_emit(obj, EFL_ACCESS_STATE_TYPE_HIGHLIGHTED, EINA_TRUE);
8714 // TIZEN_ONLY(20161018): add highlighted/unhighlighted signal for atspi
8715 evas_object_smart_callback_call(obj, SIG_WIDGET_ATSPI_HIGHLIGHTED, NULL);
8718 //TIZEN_ONLY(20171011) : atspi : During the highlight grab, out signal is not sent.
8719 _elm_widget_accessibility_highlight_grabbing_set(obj, EINA_FALSE);
8724 EOLIAN static Eina_Bool
8725 _efl_ui_widget_efl_access_component_highlight_clear(Eo *obj, Elm_Widget_Smart_Data *pd EINA_UNUSED)
8727 if (!obj) return EINA_FALSE;
8728 if (!_elm_atspi_enabled())
8731 elm_object_accessibility_highlight_set(obj, EINA_FALSE);
8732 efl_access_state_changed_signal_emit(obj, EFL_ACCESS_STATE_TYPE_HIGHLIGHTED, EINA_FALSE);
8733 // TIZEN_ONLY(20161018): add highlighted/unhighlighted signal for atspi
8734 evas_object_smart_callback_call(obj, SIG_WIDGET_ATSPI_UNHIGHLIGHTED, NULL);
8740 // TIZEN_ONLY(20171114) Accessibility Highlight Frame added
8741 EOLIAN static Eina_Bool
8742 _elm_widget_item_efl_access_component_highlight_grab(Eo *obj, Elm_Widget_Item_Data *sd)
8744 // TIZEN_ONLY(20171117) Accessibility Highlight frame support for items
8745 // Evas_Object *win = elm_widget_top_get(sd->widget);
8746 // if (win && efl_isa(win, EFL_UI_WIN_CLASS))
8748 // elm_object_accessibility_highlight_set(sd->view, EINA_TRUE);
8749 // efl_access_state_changed_signal_emit(obj, EFL_ACCESS_STATE_TYPE_HIGHLIGHTED, EINA_TRUE);
8750 // return EINA_TRUE;
8752 // return EINA_FALSE;
8754 if (!sd) return EINA_FALSE;
8755 if (!sd->view) return EINA_FALSE;
8756 if (!_elm_atspi_enabled())
8759 // TIZEN_ONLY(20171020) : atspi : Do not send signal, if current object and highlight object are same
8760 if (_elm_object_accessibility_currently_highlighted_get() == obj)
8764 //TIZEN_ONLY(20171011) : atspi : During the highlight grab, out signal is not sent.
8765 _elm_widget_accessibility_highlight_grabbing_set(obj, EINA_TRUE);
8768 //TIZEN_ONLY(20170119): Show the object highlighted by highlight_grab when the object is completely out of the scroll
8769 _accessible_highlight_region_show(sd->view);
8772 if (!sd->eo_obj) return EINA_FALSE;
8773 elm_object_accessibility_highlight_set(sd->eo_obj, EINA_TRUE);
8775 if (!obj) return EINA_FALSE;
8776 efl_access_state_changed_signal_emit(obj, EFL_ACCESS_STATE_TYPE_HIGHLIGHTED, EINA_TRUE);
8777 //TIZEN_ONLY(20170412) Make atspi,(un)highlighted work on widget item
8778 evas_object_smart_callback_call(sd->widget, SIG_WIDGET_ATSPI_HIGHLIGHTED, obj);
8781 //TIZEN_ONLY(20171011) : atspi : During the highlight grab, out signal is not sent.
8782 _elm_widget_accessibility_highlight_grabbing_set(obj, EINA_FALSE);
8789 EOLIAN static Eina_Bool
8790 _elm_widget_item_efl_access_component_highlight_clear(Eo *obj, Elm_Widget_Item_Data *sd)
8792 if (!obj) return EINA_FALSE;
8793 if (!_elm_atspi_enabled())
8796 elm_object_accessibility_highlight_set(sd->eo_obj, EINA_FALSE);
8797 efl_access_state_changed_signal_emit(obj, EFL_ACCESS_STATE_TYPE_HIGHLIGHTED, EINA_FALSE);
8798 //TIZEN_ONLY(20170412) Make atspi,(un)highlighted work on widget item
8799 evas_object_smart_callback_call(sd->widget, SIG_WIDGET_ATSPI_UNHIGHLIGHTED, obj);
8805 //TIZEN_ONLY(20160527): widget: add AtspiAction interface to all widgets and widget_items, add handlers for reading stopped/cancelled
8806 EOLIAN const Efl_Access_Action_Data *
8807 _efl_ui_widget_efl_access_widget_action_elm_actions_get(const Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *pd EINA_UNUSED)
8812 EOLIAN const Efl_Access_Action_Data *
8813 _elm_widget_item_efl_access_widget_action_elm_actions_get(const Eo *obj EINA_UNUSED, Elm_Widget_Item_Data *pd EINA_UNUSED)
8818 /***********************************************************
8819 * TIZEN_ONLY(20180117): Override Paragraph Direction APIs *
8820 ***********************************************************/
8822 _efl_ui_widget_efl_canvas_object_paragraph_direction_set_internal(Eo *obj EINA_UNUSED, Efl_Ui_Widget_Data *sd, Efl_Text_Bidirectional_Type dir)
8826 if (sd->on_destroy) return;
8828 for (unsigned int i = 0; i < eina_array_count(sd->children); ++i)
8830 child = eina_array_data_get(sd->children, i);
8831 if (_elm_widget_is(child))
8833 Efl_Ui_Widget_Data *sdc = efl_data_scope_get(child, MY_CLASS);
8835 if (sdc->inherit_paragraph_direction &&
8836 (sdc->paragraph_direction != dir))
8838 sdc->paragraph_direction = dir;
8839 _efl_ui_widget_efl_canvas_object_paragraph_direction_set_internal(child, sdc, dir);
8840 efl_canvas_object_paragraph_direction_set(efl_super(child, MY_CLASS), dir);
8844 /* FIXME: There is no way to handle non-widget child object.
8845 * If a non-widget child object has smart parent, it will get the direction
8846 * from the smart parent. */
8851 _efl_ui_widget_efl_canvas_object_paragraph_direction_set(Eo *obj, Efl_Ui_Widget_Data *sd, Efl_Text_Bidirectional_Type dir)
8853 if ((!(sd->inherit_paragraph_direction) && (sd->paragraph_direction == dir)) ||
8854 (sd->inherit_paragraph_direction && (dir == EFL_TEXT_BIDIRECTIONAL_TYPE_INHERIT)))
8857 if (dir == EFL_TEXT_BIDIRECTIONAL_TYPE_INHERIT)
8859 sd->inherit_paragraph_direction = EINA_TRUE;
8860 Evas_BiDi_Direction parent_dir = EFL_TEXT_BIDIRECTIONAL_TYPE_NEUTRAL;
8863 parent_dir = efl_canvas_object_paragraph_direction_get(sd->parent_obj);
8865 if (parent_dir != sd->paragraph_direction)
8867 sd->paragraph_direction = parent_dir;
8868 _efl_ui_widget_efl_canvas_object_paragraph_direction_set_internal(obj, sd, parent_dir);
8873 sd->inherit_paragraph_direction = EINA_FALSE;
8874 sd->paragraph_direction = dir;
8875 _efl_ui_widget_efl_canvas_object_paragraph_direction_set_internal(obj, sd, dir);
8878 efl_canvas_object_paragraph_direction_set(efl_super(obj, MY_CLASS), dir);
8884 /***********************************************************************************
8885 * TIZEN_ONLY_FEATURE: apply Tizen's color_class features. *
8886 ***********************************************************************************/
8888 _elm_widget_color_class_parent_set(Evas_Object *obj, Evas_Object *parent)
8890 Evas_Object *edje = NULL, *parent_edje = NULL;
8892 if (!obj || !parent) return;
8894 if (efl_isa(obj, EFL_UI_LAYOUT_BASE_CLASS))
8895 edje = elm_layout_edje_get(obj);
8896 else if (efl_isa(obj, EFL_CANVAS_LAYOUT_CLASS))
8899 if (efl_isa(parent, EFL_UI_LAYOUT_BASE_CLASS))
8900 parent_edje = elm_layout_edje_get(parent);
8901 else if (efl_isa(parent, EFL_CANVAS_LAYOUT_CLASS))
8902 parent_edje = parent;
8904 if (!edje || !parent_edje) return;
8906 edje_object_color_class_parent_set(edje, parent_edje);
8910 _elm_widget_color_class_parent_unset(Evas_Object *obj)
8912 Evas_Object *edje = NULL;
8916 if (efl_isa(obj, EFL_UI_LAYOUT_BASE_CLASS))
8917 edje = elm_layout_edje_get(obj);
8918 else if (efl_isa(obj, EFL_CANVAS_LAYOUT_CLASS))
8923 edje_object_color_class_parent_unset(edje);
8927 _edje_color_class_free(void *data)
8929 Edje_Color_Class *cc = data;
8931 if (cc->name) eina_stringshare_del(cc->name);
8936 _elm_widget_edje_class_get(const Evas_Object *obj, const char *style, const char *part)
8939 Eina_Stringshare *str;
8940 const char *klass_name = NULL;
8941 Eina_Bool is_legacy = EINA_FALSE;
8942 Eina_Bool is_item = efl_isa(obj, ELM_WIDGET_ITEM_CLASS);
8945 is_legacy = elm_widget_is_legacy(elm_object_item_widget_get(obj));
8947 is_legacy = elm_widget_is_legacy(obj);
8949 buf = eina_strbuf_new();
8954 klass_name = _elm_widget_item_legacy_type_get(obj);
8956 klass_name = elm_widget_type_get(obj);
8960 klass_name = efl_class_name_get(efl_class_get(obj));
8965 if (is_legacy && strchr(klass_name, '_'))
8967 eina_strbuf_append(buf, strchr(klass_name, '_') + 1);
8968 eina_strbuf_tolower(buf);
8972 /* Get the last word from the given klass name */
8973 char *temp, *temp_orig, *temp_ret, *last_ret = NULL;
8974 const char *delim = NULL;
8976 temp_orig = temp = strdup(klass_name);
8978 /* If "." is not used for word serperator,
8979 * it assume the given klass name is legacy.
8980 * And legacy klass name was made with "_" as its word seperator. */
8981 if (strchr(klass_name, '.'))
8986 while ((temp_ret = strsep(&temp, delim)) != NULL)
8988 if (strcmp(temp_ret, ""))
8989 last_ret = temp_ret;
8994 eina_strbuf_append(buf, last_ret);
8995 eina_strbuf_tolower(buf);
9004 eina_strbuf_append_printf(buf, "/%s/%s", style, part);
9008 eina_strbuf_append_printf(buf, "/%s", part);
9011 str = eina_stringshare_add(eina_strbuf_string_get(buf));
9013 eina_strbuf_free(buf);
9018 _elm_widget_color_class_set_internal(Evas_Object *obj, Evas_Object *edje, const char *color_class,
9019 int r, int g, int b, int a,
9020 int r2, int g2, int b2, int a2,
9021 int r3, int g3, int b3, int a3)
9023 Eina_Bool int_ret = EINA_TRUE;
9024 Eina_Stringshare *buf;
9025 // TIZEN_ONLY(20200623) : apply Tizen's color_class features
9026 Edje_Color_Class *cc = NULL;
9027 API_ENTRY return EINA_FALSE;
9029 int temp_color[3][4] = { { r, g, b, a },
9031 { r3, g3, b3, a3 } };
9033 if (!color_class) return EINA_FALSE;
9035 buf = _elm_widget_edje_class_get(obj, NULL, color_class);
9037 #define TEMP_COLOR(x, y) \
9038 ((temp_color[x][y] == -1) ? &temp_color[x][y] : NULL)
9040 edje_object_color_class_get(edje, buf,
9041 TEMP_COLOR(0, 0), TEMP_COLOR(0, 1), TEMP_COLOR(0, 2), TEMP_COLOR(0, 3),
9042 TEMP_COLOR(1, 0), TEMP_COLOR(1, 1), TEMP_COLOR(1, 2), TEMP_COLOR(1, 3),
9043 TEMP_COLOR(2, 0), TEMP_COLOR(2, 1), TEMP_COLOR(2, 2), TEMP_COLOR(2, 3));
9047 #define TEMP_COLOR(x, y) \
9048 ((temp_color[x][y] == -1) ? 0 : temp_color[x][y])
9050 int_ret &= edje_object_color_class_set(edje, buf,
9051 TEMP_COLOR(0, 0), TEMP_COLOR(0, 1), TEMP_COLOR(0, 2), TEMP_COLOR(0, 3),
9052 TEMP_COLOR(1, 0), TEMP_COLOR(1, 1), TEMP_COLOR(1, 2), TEMP_COLOR(1, 3),
9053 TEMP_COLOR(2, 0), TEMP_COLOR(2, 1), TEMP_COLOR(2, 2), TEMP_COLOR(2, 3));
9057 // TIZEN_ONLY(20200623) : apply Tizen's color_class features
9060 if (!sd->color_classes)
9061 sd->color_classes = eina_hash_string_small_new(_edje_color_class_free);
9063 cc = eina_hash_find(sd->color_classes, buf);
9066 cc = calloc(1, sizeof(Edje_Color_Class));
9067 if (!cc) goto on_error;
9068 cc->name = eina_stringshare_add(buf);
9069 eina_hash_direct_add(sd->color_classes, cc->name, cc);
9071 cc->r = r; cc->g = g; cc->b = b; cc->a = a;
9072 cc->r2 = r2; cc->g2 = g2; cc->b2 = b2; cc->a2 = a2;
9073 cc->r3 = r3; cc->g3 = g3; cc->b3 = b3; cc->a3 = a3;
9078 eina_stringshare_del(buf);
9084 _elm_widget_color_class_get_internal(Evas_Object *obj, Evas_Object *edje, const char *color_class,
9085 int *r, int *g, int *b, int *a,
9086 int *r2, int *g2, int *b2, int *a2,
9087 int *r3, int *g3, int *b3, int *a3)
9089 Eina_Bool int_ret = EINA_TRUE;
9090 Eina_Stringshare *buf;
9092 if (!color_class) return EINA_FALSE;
9094 buf = _elm_widget_edje_class_get(obj, elm_widget_style_get(obj), color_class);
9096 int_ret &= edje_object_color_class_get(edje, buf,
9101 eina_stringshare_del(buf);
9106 /* Internal EO API */
9108 _elm_widget_class_color_set(Eo *obj, Elm_Widget_Smart_Data *sd EINA_UNUSED, const char *color_class, int r, int g, int b, int a)
9111 Eina_Bool int_ret = EINA_TRUE;
9113 if (!efl_isa(obj, EFL_UI_LAYOUT_BASE_CLASS)) return EINA_FALSE;
9115 edje = elm_layout_edje_get(obj);
9116 int_ret &= _elm_widget_color_class_set_internal(obj, edje, color_class,
9124 /* Internal EO API */
9126 _elm_widget_class_color_get(Eo *obj, Elm_Widget_Smart_Data *sd EINA_UNUSED, const char *color_class, int *r, int *g, int *b, int *a)
9129 Eina_Bool int_ret = EINA_TRUE;
9131 if (!efl_isa(obj, EFL_UI_LAYOUT_BASE_CLASS)) return EINA_FALSE;
9133 edje = elm_layout_edje_get(obj);
9134 int_ret &= _elm_widget_color_class_get_internal(obj, edje, color_class,
9136 NULL, NULL, NULL, NULL,
9137 NULL, NULL, NULL, NULL);
9142 /* Internal EO API */
9144 _elm_widget_class_color2_set(Eo *obj, Elm_Widget_Smart_Data *sd EINA_UNUSED, const char *color_class, int r, int g, int b, int a)
9147 Eina_Bool int_ret = EINA_TRUE;
9149 if (!efl_isa(obj, EFL_UI_LAYOUT_BASE_CLASS)) return EINA_FALSE;
9151 edje = elm_layout_edje_get(obj);
9152 int_ret &= _elm_widget_color_class_set_internal(obj, edje, color_class,
9160 /* Internal EO API */
9162 _elm_widget_class_color2_get(Eo *obj, Elm_Widget_Smart_Data *sd EINA_UNUSED, const char *color_class, int *r, int *g, int *b, int *a)
9165 Eina_Bool int_ret = EINA_TRUE;
9167 if (!efl_isa(obj, EFL_UI_LAYOUT_BASE_CLASS)) return EINA_FALSE;
9169 edje = elm_layout_edje_get(obj);
9170 int_ret &= _elm_widget_color_class_get_internal(obj, edje, color_class,
9171 NULL, NULL, NULL, NULL,
9173 NULL, NULL, NULL, NULL);
9178 /* Internal EO API */
9180 _elm_widget_class_color3_set(Eo *obj, Elm_Widget_Smart_Data *sd EINA_UNUSED, const char *color_class, int r, int g, int b, int a)
9183 Eina_Bool int_ret = EINA_TRUE;
9185 if (!efl_isa(obj, EFL_UI_LAYOUT_BASE_CLASS)) return EINA_FALSE;
9187 edje = elm_layout_edje_get(obj);
9188 int_ret &= _elm_widget_color_class_set_internal(obj, edje, color_class,
9196 /* Internal EO API */
9198 _elm_widget_class_color3_get(Eo *obj, Elm_Widget_Smart_Data *sd EINA_UNUSED, const char *color_class, int *r, int *g, int *b, int *a)
9201 Eina_Bool int_ret = EINA_TRUE;
9203 if (!efl_isa(obj, EFL_UI_LAYOUT_BASE_CLASS)) return EINA_FALSE;
9205 edje = elm_layout_edje_get(obj);
9206 int_ret &= _elm_widget_color_class_get_internal(obj, edje, color_class,
9207 NULL, NULL, NULL, NULL,
9208 NULL, NULL, NULL, NULL,
9214 /* Internal EO API */
9216 _elm_widget_class_color_del(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd, const char *color_class)
9218 Eina_Stringshare *buf;
9219 // TIZEN_ONLY(20200623) : apply Tizen's color_class features
9220 Edje_Color_Class *cc = NULL;
9223 if (!efl_isa(obj, EFL_UI_LAYOUT_BASE_CLASS)) return;
9225 buf = _elm_widget_edje_class_get(obj, NULL, color_class);
9226 // TIZEN_ONLY(20200623) : apply Tizen's color_class features
9227 eina_hash_del(sd->color_classes, buf, cc);
9229 edje_object_color_class_del(sd->resize_obj, buf);
9230 eina_stringshare_del(buf);
9233 /* Internal EO API */
9235 _elm_widget_class_color_clear(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd)
9237 if (!efl_isa(obj, EFL_UI_LAYOUT_BASE_CLASS)) return;
9238 // TIZEN_ONLY(20200623) : apply Tizen's color_class features
9239 ELM_SAFE_FREE(sd->color_classes, eina_hash_free);
9241 edje_object_color_class_clear(sd->resize_obj);
9244 #define ELM_COLOR_CLASS_UPDATE(obj, hash, cond) \
9245 Evas_Object *edje = NULL; \
9246 Eina_Iterator *itr; \
9247 Edje_Color_Class *cc; \
9248 Eina_Bool int_ret = EINA_TRUE; \
9249 if (cond) return EINA_FALSE; \
9250 if (efl_isa(obj, EFL_UI_LAYOUT_BASE_CLASS)) \
9251 edje = elm_layout_edje_get(obj); \
9252 else if (efl_isa(obj, EFL_CANVAS_LAYOUT_CLASS)) \
9254 if (!edje) return EINA_FALSE; \
9255 itr = eina_hash_iterator_data_new(hash); \
9256 EINA_ITERATOR_FOREACH(itr, cc) \
9258 int_ret &= edje_object_color_class_set(edje, cc->name, \
9259 cc->r, cc->g, cc->b, cc->a, \
9260 cc->r2, cc->g2, cc->b2, cc->a2, \
9261 cc->r3, cc->g3, cc->b3, cc->a3); \
9263 eina_iterator_free(itr); \
9267 _elm_widget_color_class_update(Eo *obj, Elm_Widget_Smart_Data *sd)
9269 ELM_COLOR_CLASS_UPDATE(obj, sd->color_classes, (!sd) || (!sd->color_classes) || (!obj));
9272 #define CHECK_BOUND(x) \
9273 if (x > 0xff) x = 0xff; \
9274 else if (x < 0) x = 0
9276 #define ELM_COLOR_CLASS_SET_START(obj, cr, cg, cb, ca) \
9277 Eina_Bool int_ret = EINA_FALSE; \
9278 Edje_Color_Class *cc = NULL; \
9279 Eina_Stringshare *buf; \
9280 buf = _elm_widget_edje_class_get(obj, NULL, color_class); \
9285 _elm_color_unpremul(a, &r, &g, &b); \
9286 if (!sd->color_classes) \
9287 sd->color_classes = eina_hash_string_small_new(_edje_color_class_free); \
9289 cc = eina_hash_find(sd->color_classes, buf); \
9292 cc = calloc(1, sizeof(Edje_Color_Class)); \
9293 cc->name = eina_stringshare_add(buf); \
9297 eina_stringshare_del(buf); \
9298 return EINA_FALSE; \
9300 eina_hash_direct_add(sd->color_classes, cc->name, cc); \
9302 else if ((cc->cr == r) && (cc->cg == g) && \
9303 (cc->cb == b) && (cc->ca == a)) \
9305 eina_stringshare_del(buf); \
9314 #define ELM_COLOR_CLASS_SET_END() \
9315 eina_stringshare_del(buf); \
9318 #define ELM_COLOR_CLASS_GET(obj, cr, cg, cb, ca) \
9319 Eina_Bool int_ret = EINA_FALSE; \
9320 Edje_Color_Class *cc; \
9321 Eina_Stringshare *buf; \
9323 buf = _elm_widget_edje_class_get(obj, NULL, color_class); \
9324 if ((!sd->color_classes) || !(cc = eina_hash_find(sd->color_classes, buf))) \
9330 int_ret = EINA_FALSE; \
9334 if (r) *r = cc->cr; \
9335 if (g) *g = cc->cg; \
9336 if (b) *b = cc->cb; \
9337 if (a) *a = cc->ca; \
9339 int_ret = EINA_TRUE; \
9341 _elm_color_premul(alpha, r, g, b); \
9342 eina_stringshare_del(buf); \
9346 _elm_widget_item_color_class_update(Elm_Widget_Item_Data *sd)
9348 ELM_COLOR_CLASS_UPDATE(sd->view, sd->color_classes, (!sd) || (!sd->color_classes) || (!sd->view));
9351 /* Internal EO API */
9353 _elm_widget_item_class_color_set(Eo *obj, Elm_Widget_Item_Data *sd, const char *color_class, int r, int g, int b, int a)
9355 ELM_COLOR_CLASS_SET_START(obj, r, g, b, a);
9357 int_ret &= _elm_widget_item_color_class_update(sd);
9359 ELM_COLOR_CLASS_SET_END();
9362 /* Internal EO API */
9364 _elm_widget_item_class_color_get(const Eo *obj, Elm_Widget_Item_Data *sd, const char *color_class, int *r, int *g, int *b, int *a)
9366 ELM_COLOR_CLASS_GET(obj, r, g, b, a);
9369 /* Internal EO API */
9371 _elm_widget_item_class_color2_set(Eo *obj, Elm_Widget_Item_Data *sd, const char *color_class, int r, int g, int b, int a)
9373 ELM_COLOR_CLASS_SET_START(obj, r2, g2, b2, a2);
9375 int_ret &= _elm_widget_item_color_class_update(sd);
9377 ELM_COLOR_CLASS_SET_END();
9380 /* Internal EO API */
9382 _elm_widget_item_class_color2_get(const Eo *obj, Elm_Widget_Item_Data *sd, const char *color_class, int *r, int *g, int *b, int *a)
9384 ELM_COLOR_CLASS_GET(obj, r2, g2, b2, a2);
9387 /* Internal EO API */
9389 _elm_widget_item_class_color3_set(Eo *obj, Elm_Widget_Item_Data *sd, const char *color_class, int r, int g, int b, int a)
9391 ELM_COLOR_CLASS_SET_START(obj, r3, g3, b3, a3);
9393 int_ret &= _elm_widget_item_color_class_update(sd);
9395 ELM_COLOR_CLASS_SET_END();
9398 /* Internal EO API */
9400 _elm_widget_item_class_color3_get(const Eo *obj, Elm_Widget_Item_Data *sd, const char *color_class, int *r, int *g, int *b, int *a)
9402 ELM_COLOR_CLASS_GET(obj, r3, g3, b3, a3);
9405 /* Internal EO API */
9406 static Evas_Object *
9407 _elm_widget_item_edje_get(const Eo *obj, Elm_Widget_Item_Data *sd)
9410 sd = efl_data_scope_get(obj, ELM_WIDGET_ITEM_CLASS);
9412 if (efl_isa(sd->view, EFL_UI_LAYOUT_BASE_CLASS))
9413 return elm_layout_edje_get(sd->view);
9414 else if (efl_isa(sd->view, EFL_CANVAS_LAYOUT_CLASS))
9420 /* Internal EO API */
9422 _elm_widget_item_class_color_del(Eo *obj EINA_UNUSED, Elm_Widget_Item_Data *sd, const char *color_class)
9424 Eina_Stringshare *buf;
9426 Edje_Color_Class *cc = NULL;
9428 if (!color_class) return;
9430 buf = _elm_widget_edje_class_get(obj, NULL, color_class);
9431 eina_hash_del(sd->color_classes, buf, cc);
9433 edje = _elm_widget_item_edje_get(obj, sd);
9435 edje_object_color_class_del(edje, buf);
9437 eina_stringshare_del(buf);
9440 /* Internal EO API */
9442 _elm_widget_item_class_color_clear(Eo *obj EINA_UNUSED, Elm_Widget_Item_Data *sd)
9445 ELM_SAFE_FREE(sd->color_classes, eina_hash_free);
9447 edje = _elm_widget_item_edje_get(obj, sd);
9450 edje_object_color_class_clear(edje);
9453 /* Internal EO APIs and hidden overrides */
9454 EAPI EFL_FUNC_BODYV(elm_widget_item_class_color_set, Eina_Bool, EINA_FALSE,
9455 EFL_FUNC_CALL(color_class, r, g, b, a),
9456 const char *color_class, int r, int g, int b, int a)
9457 EAPI EFL_FUNC_BODYV(elm_widget_item_class_color_get, Eina_Bool, EINA_FALSE,
9458 EFL_FUNC_CALL(color_class, r, g, b, a),
9459 const char *color_class, int *r, int *g, int *b, int *a)
9460 EAPI EFL_FUNC_BODYV(elm_widget_item_class_color2_set, Eina_Bool, EINA_FALSE,
9461 EFL_FUNC_CALL(color_class, r, g, b, a),
9462 const char *color_class, int r, int g, int b, int a)
9463 EAPI EFL_FUNC_BODYV(elm_widget_item_class_color2_get, Eina_Bool, EINA_FALSE,
9464 EFL_FUNC_CALL(color_class, r, g, b, a),
9465 const char *color_class, int *r, int *g, int *b, int *a)
9466 EAPI EFL_FUNC_BODYV(elm_widget_item_class_color3_set, Eina_Bool, EINA_FALSE,
9467 EFL_FUNC_CALL(color_class, r, g, b, a),
9468 const char *color_class, int r, int g, int b, int a)
9469 EAPI EFL_FUNC_BODYV(elm_widget_item_class_color3_get, Eina_Bool, EINA_FALSE,
9470 EFL_FUNC_CALL(color_class, r, g, b, a),
9471 const char *color_class, int *r, int *g, int *b, int *a)
9472 EAPI EFL_VOID_FUNC_BODYV(elm_widget_item_class_color_del,
9473 EFL_FUNC_CALL(color_class),
9474 const char *color_class)
9475 EAPI EFL_VOID_FUNC_BODY(elm_widget_item_class_color_clear)
9477 #define ELM_WIDGET_ITEM_EXTRA_OPS \
9478 EFL_OBJECT_OP_FUNC(elm_widget_item_class_color_set, _elm_widget_item_class_color_set), \
9479 EFL_OBJECT_OP_FUNC(elm_widget_item_class_color_get, _elm_widget_item_class_color_get), \
9480 EFL_OBJECT_OP_FUNC(elm_widget_item_class_color2_set, _elm_widget_item_class_color2_set), \
9481 EFL_OBJECT_OP_FUNC(elm_widget_item_class_color2_get, _elm_widget_item_class_color2_get), \
9482 EFL_OBJECT_OP_FUNC(elm_widget_item_class_color3_set, _elm_widget_item_class_color3_set), \
9483 EFL_OBJECT_OP_FUNC(elm_widget_item_class_color3_get, _elm_widget_item_class_color3_get), \
9484 EFL_OBJECT_OP_FUNC(elm_widget_item_class_color_del, _elm_widget_item_class_color_del), \
9485 EFL_OBJECT_OP_FUNC(elm_widget_item_class_color_clear, _elm_widget_item_class_color_clear)
9491 //TIZEN_ONLY(20180607): Restore legacy focus
9493 _if_focused_revert(Evas_Object *obj,
9494 Eina_Bool can_focus_only)
9497 Evas_Object *newest = NULL;
9498 unsigned int newest_focus_order = 0;
9502 if (!sd->focused) return;
9503 if (!sd->parent_obj) return;
9505 top = elm_widget_top_get(sd->parent_obj);
9508 newest = efl_ui_widget_newest_focus_order_get
9509 (top, &newest_focus_order, can_focus_only);
9514 ELM_WIDGET_DATA_GET(newest, sd2);
9517 if (!_is_focused(newest))
9518 efl_ui_widget_focus_steal(newest, NULL);
9521 if (sd2->resize_obj && _is_focused(sd2->resize_obj))
9522 efl_ui_widget_focused_object_clear(sd2->resize_obj);
9526 for (unsigned int i = 0; i < eina_array_count(sd2->children); ++i)
9528 child = eina_array_data_get(sd2->children, i);
9529 if (!_elm_widget_is(child)) continue;
9530 if (_is_focused(child))
9532 efl_ui_widget_focused_object_clear(child);
9538 evas_object_focus_set(newest, EINA_TRUE);
9542 if (_is_focused(newest))
9543 efl_ui_widget_focused_object_clear(newest);
9544 elm_object_focus_set(newest, EINA_TRUE);
9553 * Set custom focus chain.
9555 * This function i set one new and overwrite any previous custom focus chain
9556 * with the list of objects. The previous list will be deleted and this list
9557 * will be managed. After setted, don't modity it.
9559 * @note On focus cycle, only will be evaluated children of this container.
9561 * @param obj The container widget
9562 * @param objs Chain of objects to pass focus
9566 _efl_ui_widget_focus_custom_chain_set(Eo *obj, Elm_Widget_Smart_Data *sd, Eina_List *objs)
9568 if (!_elm_widget_focus_chain_manager_is(obj)) return;
9570 efl_ui_widget_focus_custom_chain_unset(obj);
9575 EINA_LIST_FOREACH(objs, l, o)
9577 evas_object_event_callback_add(o, EVAS_CALLBACK_DEL,
9578 _elm_object_focus_chain_del_cb, obj);
9581 sd->focus_chain = objs;
9587 * Get custom focus chain
9589 * @param obj The container widget
9592 EOLIAN static const Eina_List*
9593 _efl_ui_widget_focus_custom_chain_get(const Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd)
9595 return (const Eina_List *)sd->focus_chain;
9601 * Unset custom focus chain
9603 * @param obj The container widget
9607 _efl_ui_widget_focus_custom_chain_unset(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd)
9609 Eina_List *l, *l_next;
9612 EINA_LIST_FOREACH_SAFE(sd->focus_chain, l, l_next, o)
9614 evas_object_event_callback_del_full(o, EVAS_CALLBACK_DEL,
9615 _elm_object_focus_chain_del_cb, obj);
9616 sd->focus_chain = eina_list_remove_list(sd->focus_chain, l);
9623 * Append object to custom focus chain.
9625 * @note If relative_child equal to NULL or not in custom chain, the object
9626 * will be added in end.
9628 * @note On focus cycle, only will be evaluated children of this container.
9630 * @param obj The container widget
9631 * @param child The child to be added in custom chain
9632 * @param relative_child The relative object to position the child
9636 _efl_ui_widget_focus_custom_chain_append(Eo *obj, Elm_Widget_Smart_Data *sd, Evas_Object *child, Evas_Object *relative_child)
9638 EINA_SAFETY_ON_NULL_RETURN(child);
9640 if (!_elm_widget_focus_chain_manager_is(obj)) return;
9642 evas_object_event_callback_add(child, EVAS_CALLBACK_DEL,
9643 _elm_object_focus_chain_del_cb, obj);
9645 if (!relative_child)
9646 sd->focus_chain = eina_list_append(sd->focus_chain, child);
9648 sd->focus_chain = eina_list_append_relative(sd->focus_chain,
9649 child, relative_child);
9655 * Prepend object to custom focus chain.
9657 * @note If relative_child equal to NULL or not in custom chain, the object
9658 * will be added in begin.
9660 * @note On focus cycle, only will be evaluated children of this container.
9662 * @param obj The container widget
9663 * @param child The child to be added in custom chain
9664 * @param relative_child The relative object to position the child
9668 _efl_ui_widget_focus_custom_chain_prepend(Eo *obj, Elm_Widget_Smart_Data *sd, Evas_Object *child, Evas_Object *relative_child)
9670 EINA_SAFETY_ON_NULL_RETURN(child);
9672 if (!_elm_widget_focus_chain_manager_is(obj)) return;
9674 evas_object_event_callback_add(child, EVAS_CALLBACK_DEL,
9675 _elm_object_focus_chain_del_cb, obj);
9677 if (!relative_child)
9678 sd->focus_chain = eina_list_prepend(sd->focus_chain, child);
9680 sd->focus_chain = eina_list_prepend_relative(sd->focus_chain,
9681 child, relative_child);
9687 * Give focus to next object in object tree.
9689 * Give focus to next object in focus chain of one object sub-tree.
9690 * If the last object of chain already have focus, the focus will go to the
9691 * first object of chain.
9693 * @param obj The widget root of sub-tree
9694 * @param dir Direction to cycle the focus
9699 _efl_ui_widget_focus_cycle(Eo *obj, Elm_Widget_Smart_Data *_pd EINA_UNUSED, Efl_Ui_Focus_Direction dir)
9701 Evas_Object *target = NULL;
9702 Elm_Object_Item *target_item = NULL;
9703 if (!_elm_widget_is(obj))
9705 efl_ui_widget_focus_next_get(obj, dir, &target, &target_item);
9709 if (_elm_config->access_mode)
9711 /* highlight cycle does not steal a focus, only after window gets
9712 the ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_ACTIVATE message,
9713 target will steal focus, or focus its own job. */
9714 if (!_elm_access_auto_highlight_get())
9715 efl_ui_widget_focus_steal(target, target_item);
9717 _elm_access_highlight_set(target);
9718 elm_widget_focus_region_show(target);
9720 else efl_ui_widget_focus_steal(target, target_item);
9727 * Give focus to near object(in object tree) in one direction.
9729 * Give focus to near object(in object tree) in direction of current
9730 * focused object. If none focusable object in given direction or
9731 * none focused object in object tree, the focus will not change.
9733 * @param obj The reference widget
9734 * @param degree Degree changes clockwise. i.e. 0-degree: Up,
9735 * 90-degree: Right, 180-degree: Down, and 270-degree: Left
9736 * @return EINA_TRUE if focus is moved.
9740 EOLIAN static Eina_Bool
9741 _efl_ui_widget_focus_direction_go(Eo *obj, Elm_Widget_Smart_Data *_pd EINA_UNUSED, double degree)
9743 Evas_Object *target = NULL;
9744 Elm_Object_Item *target_item = NULL;
9745 Evas_Object *current_focused = NULL;
9746 double weight = 0.0;
9748 if (!_elm_widget_is(obj)) return EINA_FALSE;
9749 if (!_is_focused(obj)) return EINA_FALSE;
9751 current_focused = efl_ui_widget_focused_object_get(obj);
9753 if (efl_ui_widget_focus_direction_get
9754 (obj, current_focused, degree, &target, &target_item, &weight))
9756 efl_ui_widget_focus_steal(target, NULL);
9766 * Get near object in one direction of base object.
9768 * Get near object(in the object sub-tree) in one direction of
9769 * base object. Return the near object by reference.
9770 * By initializing weight, you can filter objects locating far
9771 * from base object. If object is in the specific direction,
9772 * weight is (1/(distance^2)). If object is not exactly in one
9773 * direction, some penalty will be added.
9775 * @param obj The widget root of sub-tree
9776 * @param base The base object of the direction
9777 * @param degree Degree changes clockwise. i.e. 0-degree: Up,
9778 * 90-degree: Right, 180-degree: Down, and 270-degree: Left
9779 * @param direction The near object in one direction
9780 * @param weight The weight is bigger when the object is located near
9781 * @return EINA_TRUE if near object is updated.
9786 EOLIAN static Eina_Bool
9787 _efl_ui_widget_focus_direction_get(const Eo *obj, Elm_Widget_Smart_Data *sd, const Evas_Object *base, double degree, Evas_Object **direction, Elm_Object_Item **direction_item, double *weight)
9791 /* -1 means the best was already decided. Don't need any more searching. */
9792 if (!direction || !weight || !base || (obj == base))
9795 /* Ignore if disabled */
9796 if ((!evas_object_visible_get(obj))
9797 || (elm_widget_disabled_get(obj))
9798 || (elm_widget_tree_unfocusable_get(obj)))
9802 if (_internal_elm_widget_focus_direction_manager_is(obj))
9804 Eina_Bool int_ret = EINA_FALSE;
9805 int_ret = efl_ui_widget_focus_direction((Eo *)obj, base, degree, direction, direction_item, weight);
9809 if (!elm_widget_can_focus_get(obj) || _is_focused((Eo *)obj))
9812 c_weight = _elm_widget_focus_direction_weight_get(base, obj, degree);
9813 if ((c_weight == -1.0) ||
9814 ((c_weight != 0.0) && (*weight != -1.0) &&
9815 ((int)(*weight * 1000000) <= (int)(c_weight * 1000000))))
9818 ((int)(*weight * 1000000) == (int)(c_weight * 1000000)))
9820 ELM_WIDGET_DATA_GET(*direction, sd1);
9823 if (sd->focus_order <= sd1->focus_order)
9827 *direction = (Evas_Object *)obj;
9838 * Get near object in one direction of base object in list.
9840 * Get near object in one direction of base object in the specific
9841 * object list. Return the near object by reference.
9842 * By initializing weight, you can filter objects locating far
9843 * from base object. If object is in the specific direction,
9844 * weight is (1/(distance^2)). If object is not exactly in one
9845 * direction, some penalty will be added.
9847 * @param obj The widget root of sub-tree
9848 * @param base The base object of the direction
9849 * @param items list with ordered objects
9850 * @param list_data_get function to get the object from one item of list
9851 * @param degree Degree changes clockwise. i.e. 0-degree: Up,
9852 * 90-degree: Right, 180-degree: Down, and 270-degree: Left
9853 * @param direction The near object in one direction
9854 * @param weight The weight is bigger when the object is located near
9855 * @return EINA_TRUE if near object is updated.
9859 EOLIAN static Eina_Bool
9860 _efl_ui_widget_focus_list_direction_get(const Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *_pd EINA_UNUSED, const Evas_Object *base, const Eina_List *items, void* list_data_get, double degree, Evas_Object **direction, Elm_Object_Item **direction_item, double *weight)
9862 if (!direction || !weight || !base || !items)
9865 const Eina_List *l = items;
9866 Evas_Object *current_best = *direction;
9868 for (; l; l = eina_list_next(l))
9870 Evas_Object *cur = ((list_data_get_func_type)list_data_get)(l);
9871 if (cur && _elm_widget_is(cur))
9872 efl_ui_widget_focus_direction_get(cur, base, degree, direction, direction_item, weight);
9874 if (current_best != *direction) return EINA_TRUE;
9882 * Get next object in focus chain of object tree.
9884 * Get next object in focus chain of one object sub-tree.
9885 * Return the next object by reference. If don't have any candidate to receive
9886 * focus before chain end, the first candidate will be returned.
9888 * @param obj The widget root of sub-tree
9889 * @param dir Direction of focus chain
9890 * @param next The next object in focus chain
9891 * @return EINA_TRUE if don't need focus chain restart/loop back
9892 * to use 'next' obj.
9896 EOLIAN static Eina_Bool
9897 _efl_ui_widget_focus_next_get(const Eo *obj, Elm_Widget_Smart_Data *sd, Efl_Ui_Focus_Direction dir, Evas_Object **next, Elm_Object_Item **next_item)
9899 Elm_Access_Info *ac;
9905 /* Ignore if disabled */
9906 if (_elm_config->access_mode && _elm_access_auto_highlight_get())
9908 if (!evas_object_visible_get(obj)
9909 || (elm_widget_tree_unfocusable_get(obj)))
9914 if ((!evas_object_visible_get(obj))
9915 || (elm_widget_disabled_get(obj))
9916 || (elm_widget_tree_unfocusable_get(obj)))
9921 if (_elm_widget_focus_chain_manager_is(obj))
9923 Eina_Bool int_ret = EINA_FALSE;
9924 int_ret = efl_ui_widget_focus_next((Eo *)obj, dir, next, next_item);
9925 if (!int_ret && _is_focused((Eo *)obj))
9927 Evas_Object *o = NULL;
9928 if (dir == EFL_UI_FOCUS_DIRECTION_PREVIOUS)
9929 *next_item = sd->item_focus_previous;
9930 else if (dir == EFL_UI_FOCUS_DIRECTION_NEXT)
9931 *next_item = sd->item_focus_next;
9932 else if (dir == EFL_UI_FOCUS_DIRECTION_UP)
9933 *next_item = sd->item_focus_up;
9934 else if (dir == EFL_UI_FOCUS_DIRECTION_DOWN)
9935 *next_item = sd->item_focus_down;
9936 else if (dir == EFL_UI_FOCUS_DIRECTION_RIGHT)
9937 *next_item = sd->item_focus_right;
9938 else if (dir == EFL_UI_FOCUS_DIRECTION_LEFT)
9939 *next_item = sd->item_focus_left;
9941 o = elm_object_item_widget_get(*next_item);
9945 if (dir == EFL_UI_FOCUS_DIRECTION_PREVIOUS)
9946 o = sd->focus_previous;
9947 else if (dir == EFL_UI_FOCUS_DIRECTION_NEXT)
9949 else if (dir == EFL_UI_FOCUS_DIRECTION_UP)
9951 else if (dir == EFL_UI_FOCUS_DIRECTION_DOWN)
9953 else if (dir == EFL_UI_FOCUS_DIRECTION_RIGHT)
9954 o = sd->focus_right;
9955 else if (dir == EFL_UI_FOCUS_DIRECTION_LEFT)
9968 /* access object does not check sd->can_focus, because an object could
9969 have highlight even though the object is not focusable. */
9970 if (_elm_config->access_mode && _elm_access_auto_highlight_get())
9972 ac = _elm_access_info_get(obj);
9973 if (!ac) return EINA_FALSE;
9975 /* check whether the hover object is visible or not */
9976 if (!evas_object_visible_get(ac->hoverobj))
9979 else if (!elm_widget_can_focus_get(obj))
9982 if (_is_focused((Eo *)obj))
9984 if (dir == EFL_UI_FOCUS_DIRECTION_PREVIOUS)
9985 *next_item = sd->item_focus_previous;
9986 else if (dir == EFL_UI_FOCUS_DIRECTION_NEXT)
9987 *next_item = sd->item_focus_next;
9988 else if (dir == EFL_UI_FOCUS_DIRECTION_UP)
9989 *next_item = sd->item_focus_up;
9990 else if (dir == EFL_UI_FOCUS_DIRECTION_DOWN)
9991 *next_item = sd->item_focus_down;
9992 else if (dir == EFL_UI_FOCUS_DIRECTION_RIGHT)
9993 *next_item = sd->item_focus_right;
9994 else if (dir == EFL_UI_FOCUS_DIRECTION_LEFT)
9995 *next_item = sd->item_focus_left;
9996 if (*next_item) *next = elm_object_item_widget_get(*next_item);
10000 if (dir == EFL_UI_FOCUS_DIRECTION_PREVIOUS)
10001 *next = sd->focus_previous;
10002 else if (dir == EFL_UI_FOCUS_DIRECTION_NEXT)
10003 *next = sd->focus_next;
10004 else if (dir == EFL_UI_FOCUS_DIRECTION_UP)
10005 *next = sd->focus_up;
10006 else if (dir == EFL_UI_FOCUS_DIRECTION_DOWN)
10007 *next = sd->focus_down;
10008 else if (dir == EFL_UI_FOCUS_DIRECTION_RIGHT)
10009 *next = sd->focus_right;
10010 else if (dir == EFL_UI_FOCUS_DIRECTION_LEFT)
10011 *next = sd->focus_left;
10014 if (*next) return EINA_TRUE;
10018 *next = (Evas_Object *)obj;
10019 return !ELM_WIDGET_FOCUS_GET(obj);
10025 * Get next object in focus chain of object tree in list.
10027 * Get next object in focus chain of one object sub-tree ordered by one list.
10028 * Return the next object by reference. If don't have any candidate to receive
10029 * focus before list end, the first candidate will be returned.
10031 * @param obj The widget root of sub-tree
10032 * @param items list with ordered objects
10033 * @param list_data_get function to get the object from one item of list
10034 * @param dir Direction of focus chain
10035 * @param next The next object in focus chain
10036 * @return EINA_TRUE if don't need focus chain restart/loop back
10037 * to use 'next' obj.
10041 EOLIAN static Eina_Bool
10042 _efl_ui_widget_focus_list_next_get(const Eo *obj, Elm_Widget_Smart_Data *_pd EINA_UNUSED, const Eina_List *items, void * list_data_get, Efl_Ui_Focus_Direction dir, Evas_Object **next, Elm_Object_Item **next_item)
10044 Eina_List *(*list_next)(const Eina_List *list) = NULL;
10045 Evas_Object *focused_object = NULL;
10051 if (!_elm_widget_is(obj))
10057 /* When Up, Down, Right, or Left, try direction_get first. */
10058 focused_object = efl_ui_widget_focused_object_get(obj);
10059 if (focused_object)
10061 if ((dir == EFL_UI_FOCUS_DIRECTION_UP)
10062 || (dir == EFL_UI_FOCUS_DIRECTION_DOWN)
10063 || (dir == EFL_UI_FOCUS_DIRECTION_RIGHT)
10064 || (dir == EFL_UI_FOCUS_DIRECTION_LEFT))
10066 *next_item = efl_ui_widget_focus_next_item_get(focused_object, dir);
10068 *next = elm_object_item_widget_get(*next_item);
10070 *next = efl_ui_widget_focus_next_object_get(focused_object, dir);
10071 if (*next) return EINA_TRUE;
10074 Evas_Object *n = NULL;
10075 Elm_Object_Item *n_item = NULL;
10077 double weight = 0.0;
10079 if (dir == EFL_UI_FOCUS_DIRECTION_UP) degree = 0.0;
10080 else if (dir == EFL_UI_FOCUS_DIRECTION_DOWN) degree = 180.0;
10081 else if (dir == EFL_UI_FOCUS_DIRECTION_RIGHT) degree = 90.0;
10082 else if (dir == EFL_UI_FOCUS_DIRECTION_LEFT) degree = 270.0;
10084 if (efl_ui_widget_focus_list_direction_get(obj, focused_object,
10085 items, list_data_get,
10086 degree, &n, &n_item,
10089 *next_item = n_item;
10098 if (dir == EFL_UI_FOCUS_DIRECTION_PREVIOUS)
10100 items = eina_list_last(items);
10101 list_next = eina_list_prev;
10103 else if ((dir == EFL_UI_FOCUS_DIRECTION_NEXT)
10104 || (dir == EFL_UI_FOCUS_DIRECTION_UP)
10105 || (dir == EFL_UI_FOCUS_DIRECTION_DOWN)
10106 || (dir == EFL_UI_FOCUS_DIRECTION_RIGHT)
10107 || (dir == EFL_UI_FOCUS_DIRECTION_LEFT))
10108 list_next = eina_list_next;
10112 const Eina_List *l = items;
10114 /* Recovery last focused sub item */
10115 if (ELM_WIDGET_FOCUS_GET(obj))
10117 for (; l; l = list_next(l))
10119 Evas_Object *cur = ((list_data_get_func_type)list_data_get)(l);
10120 if (ELM_WIDGET_FOCUS_GET(cur)) break;
10123 /* Focused object, but no focused sub item */
10127 const Eina_List *start = l;
10128 Evas_Object *to_focus = NULL;
10129 Elm_Object_Item *to_focus_item = NULL;
10131 /* Iterate sub items */
10132 /* Go to the end of list */
10133 for (; l; l = list_next(l))
10135 Evas_Object *tmp = NULL;
10136 Elm_Object_Item *tmp_item = NULL;
10137 Evas_Object *cur = ((list_data_get_func_type)list_data_get)(l);
10139 if (!cur) continue;
10140 if (!_elm_widget_is(cur)) continue;
10141 if (elm_widget_parent_get(cur) != obj)
10144 /* Try Focus cycle in subitem */
10145 if (efl_ui_widget_focus_next_get(cur, dir, &tmp, &tmp_item))
10148 *next_item = tmp_item;
10151 else if ((dir == EFL_UI_FOCUS_DIRECTION_UP)
10152 || (dir == EFL_UI_FOCUS_DIRECTION_DOWN)
10153 || (dir == EFL_UI_FOCUS_DIRECTION_RIGHT)
10154 || (dir == EFL_UI_FOCUS_DIRECTION_LEFT))
10156 if (tmp && _is_focused(cur))
10159 *next_item = tmp_item;
10163 else if ((tmp) && (!to_focus))
10166 to_focus_item = tmp_item;
10172 /* Get First possible */
10173 for (; l != start; l = list_next(l))
10175 Evas_Object *tmp = NULL;
10176 Elm_Object_Item *tmp_item = NULL;
10177 Evas_Object *cur = ((list_data_get_func_type)list_data_get)(l);
10179 if (elm_widget_parent_get(cur) != obj)
10182 /* Try Focus cycle in subitem */
10183 efl_ui_widget_focus_next_get(cur, dir, &tmp, &tmp_item);
10187 *next_item = tmp_item;
10193 *next_item = to_focus_item;
10200 * Get next object which was set with specific focus direction.
10202 * Get next object which was set by elm_widget_focus_next_object_set
10203 * with specific focus directioin.
10205 * @param obj The widget
10206 * @param dir Direction of focus
10207 * @return Widget which was registered with sepecific focus direction.
10211 EOLIAN static Evas_Object*
10212 _efl_ui_widget_focus_next_object_get(const Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd, Efl_Ui_Focus_Direction dir)
10214 Evas_Object *ret = NULL;
10216 if (dir == EFL_UI_FOCUS_DIRECTION_PREVIOUS)
10217 ret = sd->focus_previous;
10218 else if (dir == EFL_UI_FOCUS_DIRECTION_NEXT)
10219 ret = sd->focus_next;
10220 else if (dir == EFL_UI_FOCUS_DIRECTION_UP)
10221 ret = sd->focus_up;
10222 else if (dir == EFL_UI_FOCUS_DIRECTION_DOWN)
10223 ret = sd->focus_down;
10224 else if (dir == EFL_UI_FOCUS_DIRECTION_RIGHT)
10225 ret = sd->focus_right;
10226 else if (dir == EFL_UI_FOCUS_DIRECTION_LEFT)
10227 ret = sd->focus_left;
10235 * Set next object with specific focus direction.
10237 * When a widget is set with specific focus direction, this widget will be
10238 * the first candidate when finding the next focus object.
10239 * Focus next object can be registered with six directions that are previous,
10240 * next, up, down, right, and left.
10242 * @param obj The widget
10243 * @param next Next focus object
10244 * @param dir Direction of focus
10249 _efl_ui_widget_focus_next_object_set(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd, Evas_Object *next, Efl_Ui_Focus_Direction dir)
10252 if (dir == EFL_UI_FOCUS_DIRECTION_PREVIOUS)
10253 sd->focus_previous = next;
10254 else if (dir == EFL_UI_FOCUS_DIRECTION_NEXT)
10255 sd->focus_next = next;
10256 else if (dir == EFL_UI_FOCUS_DIRECTION_UP)
10257 sd->focus_up = next;
10258 else if (dir == EFL_UI_FOCUS_DIRECTION_DOWN)
10259 sd->focus_down = next;
10260 else if (dir == EFL_UI_FOCUS_DIRECTION_RIGHT)
10261 sd->focus_right = next;
10262 else if (dir == EFL_UI_FOCUS_DIRECTION_LEFT)
10263 sd->focus_left = next;
10267 EOLIAN static Elm_Object_Item*
10268 _efl_ui_widget_focus_next_item_get(const Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd, Efl_Ui_Focus_Direction dir)
10270 Elm_Object_Item *ret = NULL;
10272 if (dir == EFL_UI_FOCUS_DIRECTION_PREVIOUS)
10273 ret = sd->item_focus_previous;
10274 else if (dir == EFL_UI_FOCUS_DIRECTION_NEXT)
10275 ret = sd->item_focus_next;
10276 else if (dir == EFL_UI_FOCUS_DIRECTION_UP)
10277 ret = sd->item_focus_up;
10278 else if (dir == EFL_UI_FOCUS_DIRECTION_DOWN)
10279 ret = sd->item_focus_down;
10280 else if (dir == EFL_UI_FOCUS_DIRECTION_RIGHT)
10281 ret = sd->item_focus_right;
10282 else if (dir == EFL_UI_FOCUS_DIRECTION_LEFT)
10283 ret = sd->item_focus_left;
10290 _efl_ui_widget_focus_next_item_set(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd, Elm_Object_Item *next_item, Efl_Ui_Focus_Direction dir)
10292 if (dir == EFL_UI_FOCUS_DIRECTION_PREVIOUS)
10293 sd->item_focus_previous = next_item;
10294 else if (dir == EFL_UI_FOCUS_DIRECTION_NEXT)
10295 sd->item_focus_next = next_item;
10296 else if (dir == EFL_UI_FOCUS_DIRECTION_UP)
10297 sd->item_focus_up = next_item;
10298 else if (dir == EFL_UI_FOCUS_DIRECTION_DOWN)
10299 sd->item_focus_down = next_item;
10300 else if (dir == EFL_UI_FOCUS_DIRECTION_RIGHT)
10301 sd->item_focus_right = next_item;
10302 else if (dir == EFL_UI_FOCUS_DIRECTION_LEFT)
10303 sd->item_focus_left = next_item;
10307 elm_widget_focus_set(Eo *obj, Eina_Bool focus)
10309 ELM_WIDGET_DATA_GET_OR_RETURN(obj, sd);
10313 sd->focus_order = focus_order;
10314 sd->focused = EINA_TRUE;
10315 efl_ui_focus_object_on_focus_update(obj);
10320 if ((_is_focusable(sd->resize_obj)) &&
10321 (!elm_widget_disabled_get(sd->resize_obj)))
10323 elm_widget_focus_set(sd->resize_obj, focus);
10327 Evas_Object *child;
10329 for (unsigned int i = 0; i < eina_array_count(sd->children); ++i)
10331 child = eina_array_data_get(sd->children, i);
10332 if (!_elm_widget_is(child)) continue;
10333 if ((_is_focusable(child)) &&
10334 (!elm_widget_disabled_get(child)))
10336 elm_widget_focus_set(child, focus);
10344 Evas_Object *child;
10345 unsigned int i = eina_array_count(sd->children);
10350 child = eina_array_data_get(sd->children, i);
10351 if (!_elm_widget_is(child)) continue;
10352 if ((_is_focusable(child)) &&
10353 (!elm_widget_disabled_get(child)))
10355 elm_widget_focus_set(child, focus);
10364 _focused_object_clear(Elm_Widget_Smart_Data *sd)
10366 if (sd->resize_obj && elm_widget_is(sd->resize_obj) &&
10367 _is_focused(sd->resize_obj))
10369 efl_ui_widget_focused_object_clear(sd->resize_obj);
10373 Evas_Object *child;
10374 for (unsigned int i = 0; i < eina_array_count(sd->children); ++i)
10376 child = eina_array_data_get(sd->children, i);
10377 if (_elm_widget_is(child) && _is_focused(child))
10379 efl_ui_widget_focused_object_clear(child);
10387 _efl_ui_widget_focused_object_clear(Eo *obj, Elm_Widget_Smart_Data *sd)
10389 if (!sd->focused) return;
10390 _focused_object_clear(sd);
10391 sd->focused = EINA_FALSE;
10392 if (sd->top_win_focused)
10393 efl_ui_focus_object_on_focus_update(obj);
10397 _efl_ui_widget_focus_steal(Eo *obj, Elm_Widget_Smart_Data *sd, Elm_Object_Item *item)
10399 Evas_Object *parent, *parent2, *o;
10401 if (sd->focused) return;
10402 if (sd->disabled) return;
10403 if (!sd->can_focus) return;
10404 if (sd->tree_unfocusable) return;
10408 o = elm_widget_parent_get(parent);
10410 sd = efl_data_scope_get(o, MY_CLASS);
10411 if (sd->disabled || sd->tree_unfocusable) return;
10412 if (sd->focused) break;
10415 if ((!elm_widget_parent_get(parent)))
10416 efl_ui_widget_focused_object_clear(parent);
10419 parent2 = elm_widget_parent_get(parent);
10421 sd = efl_data_scope_get(parent, MY_CLASS);
10422 if (sd) _focused_object_clear(sd);
10424 _parent_focus(obj, item);
10425 elm_widget_focus_region_show(obj);
10430 _parents_on_focus(Evas_Object *obj)
10433 if (!sd->focused || !sd->top_win_focused) return;
10435 Evas_Object *o = elm_widget_parent_get(obj);
10436 if (o) _parents_on_focus(o);
10437 efl_ui_focus_object_on_focus_update(obj);
10441 _efl_ui_widget_focus_restore(Eo *obj, Elm_Widget_Smart_Data *_pd EINA_UNUSED)
10443 Evas_Object *newest = NULL;
10444 unsigned int newest_focus_order = 0;
10446 newest = efl_ui_widget_newest_focus_order_get(obj, &newest_focus_order, EINA_TRUE);
10448 _parents_on_focus(newest);
10454 * Check if the widget has its own focus next function.
10456 * @param obj The widget.
10457 * @return focus next function is implemented/unimplemented.
10458 * (@c EINA_TRUE = implemented/@c EINA_FALSE = unimplemented.)
10460 static inline Eina_Bool
10461 _elm_widget_focus_chain_manager_is(const Evas_Object *obj)
10463 ELM_WIDGET_CHECK(obj) EINA_FALSE;
10465 Eina_Bool manager_is = EINA_FALSE;
10466 manager_is = efl_ui_widget_focus_next_manager_is((Eo *)obj);
10470 static inline Eina_Bool
10471 _internal_elm_widget_focus_direction_manager_is(const Evas_Object *obj)
10473 ELM_WIDGET_CHECK(obj) EINA_FALSE;
10475 Eina_Bool manager_is = EINA_FALSE;
10476 manager_is = efl_ui_widget_focus_direction_manager_is((Eo *)obj);
10481 _parent_focus(Evas_Object *obj, Elm_Object_Item *item)
10485 if (sd->focused) return;
10487 Evas_Object *o = elm_widget_parent_get(obj);
10488 sd->focus_order_on_calc = EINA_TRUE;
10490 if (o) _parent_focus(o, item);
10492 if (!sd->focus_order_on_calc)
10493 return; /* we don't want to override it if by means of any of the
10494 callbacks below one gets to calculate our order
10498 sd->focus_order = focus_order;
10499 sd->focused = EINA_TRUE;
10501 if (sd->top_win_focused)
10502 efl_ui_focus_object_on_focus_update(obj);
10503 sd->focus_order_on_calc = EINA_FALSE;
10505 if (_elm_config->access_mode == ELM_ACCESS_MODE_ON)
10506 _elm_access_highlight_set(obj);
10510 _elm_object_focus_chain_del_cb(void *data,
10511 Evas *e EINA_UNUSED,
10513 void *event_info EINA_UNUSED)
10515 ELM_WIDGET_DATA_GET(data, sd);
10517 sd->focus_chain = eina_list_remove(sd->focus_chain, obj);
10520 //TIZEN_ONLY(20200117): transition duration factor for widget transition customize
10521 EOLIAN static Eina_Bool
10522 _efl_ui_widget_transition_duration_factor_set(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *pd , double duration)
10524 pd->transition_duration = duration;
10525 // the value need to be $true when widget have transition effect.
10529 EOLIAN static double
10530 _efl_ui_widget_transition_duration_factor_get(const Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *pd)
10532 return pd->transition_duration;
10536 //TIZEN_ONLT(20191218): efl_ui_widget: add widget_focus property to handle focus
10537 EOLIAN static Eina_Bool
10538 _efl_ui_widget_widget_focus_get(const Eo *obj, Elm_Widget_Smart_Data *pd EINA_UNUSED)
10540 return elm_object_focus_get(obj);
10544 _efl_ui_widget_widget_focus_set(Eo *obj, Elm_Widget_Smart_Data *pd EINA_UNUSED, Eina_Bool focus)
10547 elm_object_focus_set(obj, focus);
10551 #include "elm_widget_item_eo.c"
10552 #include "elm_widget_item_container_eo.c"
10553 #include "efl_ui_widget.eo.c"
10554 #include "efl_ui_widget_eo.legacy.c"
10557 #include "efl_ui_l10n.eo.c"