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(20230414): Support org.a11y.atspi.Value.Text property.
4388 efl_access_object_value_text_set(eo_item, NULL);
4389 efl_access_object_value_text_cb_set(eo_item, NULL, NULL);
4391 //TIZEN_ONLY(20170405) Add gesture method to accessible interface
4392 efl_access_object_gesture_cb_set(eo_item, NULL, NULL);
4394 //TIZEN_ONLY : elm_widget_item: add at-spi name setter
4395 efl_access_object_translation_domain_set(eo_item, NULL);
4396 efl_access_object_relationships_clear(eo_item);
4399 efl_access_object_attributes_clear(eo_item);
4401 // TIZEN_ONLY(20150709) : atspi relations api
4402 if (item->atspi_custom_relations)
4403 efl_access_relation_set_free(&item->atspi_custom_relations);
4406 //TIZEN_ONLY(20150731) : add i18n support for name and description
4407 if (item->atspi_translation_domain)
4408 eina_stringshare_del(item->atspi_translation_domain);
4411 //TIZEN_ONLY(20150713) : add widget_item name setter
4413 eina_stringshare_del(item->name);
4416 /***********************************************************************************
4417 * TIZEN_ONLY_FEATURE: apply Tizen's color_class features. *
4418 ***********************************************************************************/
4419 if (item->color_classes)
4420 ELM_SAFE_FREE(item->color_classes, eina_hash_free);
4425 EINA_MAGIC_SET(item, EINA_MAGIC_NONE);
4427 efl_destructor(efl_super(eo_item, ELM_WIDGET_ITEM_CLASS));
4433 * Releases widget item memory, calling back item_del_pre_hook() and
4434 * item_del_cb() if they exist.
4436 * @param item a valid #Elm_Widget_Item to be deleted.
4438 * If there is an Elm_Widget_Item::del_cb, then it will be called prior
4439 * to memory release. Note that elm_widget_item_pre_notify_del() calls
4440 * this function and then unset it, thus being useful for 2 step
4441 * cleanup whenever the del_cb may use any of the data that must be
4442 * deleted from item.
4444 * The Elm_Widget_Item::view will be deleted (evas_object_del()) if it
4447 * Note that if item_del_pre_hook() returns @c EINA_TRUE, item free will be
4448 * deferred, or item will be freed here if it returns @c EINA_FALSE.
4450 * @see elm_widget_item_del() convenience macro.
4454 _elm_widget_item_efl_object_invalidate(Eo *eo_item, Elm_Widget_Item_Data *item)
4458 //Widget item delete callback
4459 elm_wdg_item_del_pre(item->eo_obj);
4461 // TIZEN_ONLY(20200109): if item deletion process need to be intercepted for
4462 // provide animation on the view object, widget need to add efl_del_intercept_set()
4463 // and clear the view after all animation processed.
4464 if (!efl_del_intercept_get(eo_item))
4467 if (item->view) efl_wref_del(item->view, &item->view);
4468 // FIXME: Is view an Efl.Ui or a legacy object ?
4469 evas_object_del(view);
4473 efl_invalidate(efl_super(eo_item, ELM_WIDGET_ITEM_CLASS));
4477 _elm_widget_item_del_pre(Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item EINA_UNUSED)
4484 * Notify object will be deleted without actually deleting it.
4486 * This function will callback Elm_Widget_Item::del_cb if it is set
4487 * and then unset it so it is not called twice (ie: from
4488 * elm_widget_item_del()).
4490 * @param item a valid #Elm_Widget_Item to be notified
4491 * @see elm_widget_item_pre_notify_del() convenience macro.
4495 _elm_widget_item_pre_notify_del(Eo *eo_item, Elm_Widget_Item_Data *item)
4497 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
4498 if (!item->del_func) return;
4499 item->del_func((void *)WIDGET_ITEM_DATA_GET(eo_item), item->widget, item->eo_obj);
4500 item->del_func = NULL;
4506 * Set the function to notify when item is being deleted.
4508 * This function will complain if there was a callback set already,
4509 * however it will set the new one.
4511 * The callback will be called from elm_widget_item_pre_notify_del()
4512 * or elm_widget_item_del() will be called with:
4513 * - data: the Elm_Widget_Item::data value.
4514 * - obj: the Elm_Widget_Item::widget evas object.
4515 * - event_info: the item being deleted.
4517 * @param item a valid #Elm_Widget_Item to be notified
4518 * @see elm_widget_item_del_cb_set() convenience macro.
4522 _elm_widget_item_del_cb_set(Eo *eo_item EINA_UNUSED,
4523 Elm_Widget_Item_Data *item,
4526 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
4527 ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
4529 if ((item->del_func) && (item->del_func != func))
4530 WRN("You're replacing a previously set del_cb %p of item %p with %p",
4531 item->del_func, item->eo_obj, func);
4533 item->del_func = func;
4539 * Get owner widget of this item.
4541 * @param item a valid #Elm_Widget_Item to get data from.
4542 * @return owner widget of this item.
4545 EOLIAN static Evas_Object *
4546 _elm_widget_item_widget_get(const Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item)
4548 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item, NULL);
4549 ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item, NULL);
4551 return item->widget;
4555 _elm_widget_onscreen_is(const Evas_Object *widget)
4557 Evas_Object *parent = (Evas_Object *)widget;
4558 Eina_Rectangle r1, r2;
4560 Evas *evas = evas_object_evas_get(widget);
4561 if (!evas) return EINA_FALSE;
4563 evas_object_geometry_get(widget, &r1.x, &r1.y, &r1.w, &r1.h);
4564 if (eina_rectangle_is_empty(&r1))
4567 // window does not have to check viewport and geometry
4568 if (efl_isa(widget, EFL_UI_WIN_CLASS))
4571 // check if on canvas
4572 evas_output_viewport_get(evas, &r2.x, &r2.y, &r2.w, &r2.h);
4573 if (!eina_rectangles_intersect(&r1, &r2))
4576 // check if inside scrollable parent viewport
4578 parent = elm_widget_parent_get(parent);
4579 if (parent && !evas_object_visible_get(parent))
4581 if (parent && efl_isa(parent, ELM_INTERFACE_SCROLLABLE_MIXIN))
4583 evas_object_geometry_get(parent, &r2.x, &r2.y, &r2.w, &r2.h);
4584 if (!eina_rectangles_intersect(&r1, &r2))
4587 } while (parent && (parent != elm_widget_top_get(widget)));
4593 _elm_widget_item_onscreen_is(const Elm_Object_Item *item)
4595 Eina_Rectangle r1, r2;
4596 Elm_Widget_Item_Data *id = efl_data_scope_get(item, ELM_WIDGET_ITEM_CLASS);
4597 if (!id || !id->view) return EINA_FALSE;
4599 if (!evas_object_visible_get(id->view))
4602 if (!_elm_widget_onscreen_is(id->widget))
4605 evas_object_geometry_get(id->view, &r1.x, &r1.y, &r1.w, &r1.h);
4606 if (eina_rectangle_is_empty(&r1))
4609 evas_object_geometry_get(id->widget, &r2.x, &r2.y, &r2.w, &r2.h);
4610 if (!eina_rectangles_intersect(&r1, &r2))
4617 _elm_widget_accessible_plain_name_get(const Evas_Object *obj, const char* name)
4619 char *accessible_plain_name;
4621 API_ENTRY return NULL;
4623 accessible_plain_name = _elm_util_mkup_to_text(name);
4624 eina_stringshare_del(sd->accessible_name);
4625 sd->accessible_name = eina_stringshare_add(accessible_plain_name);
4626 free(accessible_plain_name);
4627 return sd->accessible_name;
4631 _elm_widget_item_accessible_plain_name_get(const Elm_Object_Item *item, const char* name)
4633 char *accessible_plain_name;
4635 Elm_Widget_Item_Data *id = efl_data_scope_get(item, ELM_WIDGET_ITEM_CLASS);
4636 if (!id) return NULL;
4638 accessible_plain_name = _elm_util_mkup_to_text(name);
4639 eina_stringshare_del(id->accessible_name);
4640 id->accessible_name = eina_stringshare_add(accessible_plain_name);
4641 free(accessible_plain_name);
4642 return id->accessible_name;
4645 EOLIAN static Efl_Access_State_Set
4646 _elm_widget_item_efl_access_object_state_set_get(const Eo *eo_item, Elm_Widget_Item_Data *item)
4648 Efl_Access_State_Set states = 0;
4650 // TIZEN_ONLY(20171114) Accessibility Highlight Frame added
4651 // //TIZEN_ONLY(20171108): bring HIGHLIGHT related changes
4652 // Evas_Object *win = elm_widget_top_get(item->widget);
4653 // if (win && efl_isa(win, EFL_UI_WIN_CLASS))
4655 // if (_elm_win_accessibility_highlight_get(win) == item->view)
4656 // STATE_TYPE_SET(states, ELM_ATSPI_STATE_HIGHLIGHTED);
4658 // STATE_TYPE_SET(states, ELM_ATSPI_STATE_HIGHLIGHTABLE);
4662 STATE_TYPE_SET(states, EFL_ACCESS_STATE_TYPE_FOCUSABLE);
4664 if (elm_object_item_focus_get(eo_item))
4665 STATE_TYPE_SET(states, EFL_ACCESS_STATE_TYPE_FOCUSED);
4666 if (!elm_object_item_disabled_get(eo_item))
4668 STATE_TYPE_SET(states, EFL_ACCESS_STATE_TYPE_ENABLED);
4669 STATE_TYPE_SET(states, EFL_ACCESS_STATE_TYPE_SENSITIVE);
4670 STATE_TYPE_SET(states, EFL_ACCESS_STATE_TYPE_VISIBLE);
4672 if (_elm_widget_item_onscreen_is(eo_item))
4673 STATE_TYPE_SET(states, EFL_ACCESS_STATE_TYPE_SHOWING);
4675 //TIZEN_ONLY(20170207) : [ATSPI] enhance expose highlight information on atspi
4676 /* unrealized genlist item does not have item->view,
4677 and item cannot change its visibility, only widget can change the visibility */
4678 if (evas_object_visible_get(item->widget))
4679 STATE_TYPE_SET(states, EFL_ACCESS_STATE_TYPE_VISIBLE);
4682 //TIZEN_ONLY(20170717) : expose highlight information on atspi
4683 if (_elm_widget_item_highlightable((Eo *)eo_item) && _accessible_object_on_scroll_is(item->view))
4684 STATE_TYPE_SET(states, EFL_ACCESS_STATE_TYPE_HIGHLIGHTABLE);
4686 STATE_TYPE_UNSET(states, EFL_ACCESS_STATE_TYPE_HIGHLIGHTABLE);
4688 if (_elm_object_accessibility_currently_highlighted_get() == (void*)item->eo_obj)
4689 STATE_TYPE_SET(states, EFL_ACCESS_STATE_TYPE_HIGHLIGHTED);
4695 elm_object_item_data_set(Elm_Object_Item *it, void *data)
4697 WIDGET_ITEM_DATA_SET(it, data);
4701 elm_object_item_data_get(const Elm_Object_Item *it)
4703 return (void *) WIDGET_ITEM_DATA_GET(it);
4707 _elm_widget_item_disabled_set(Eo *eo_item EINA_UNUSED,
4708 Elm_Widget_Item_Data *item,
4711 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
4712 ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
4714 if (item->disabled == disabled) return;
4715 item->disabled = !!disabled;
4716 elm_wdg_item_disable(item->eo_obj);
4719 EOLIAN static Eina_Bool
4720 _elm_widget_item_disabled_get(const Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item)
4722 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item, EINA_FALSE);
4723 return item->disabled;
4727 _elm_widget_item_style_set(Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item, const char *style)
4729 eina_stringshare_replace(&item->style, style);
4732 EOLIAN static const char *
4733 _elm_widget_item_style_get(const Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item)
4739 _elm_widget_item_disable(Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item EINA_UNUSED)
4744 _elm_widget_item_item_focus_set(Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item, Eina_Bool focused EINA_UNUSED)
4746 ERR_NOT_SUPPORTED(item, "elm_object_item_focus_set");
4749 EOLIAN static Eina_Bool
4750 _elm_widget_item_item_focus_get(const Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item)
4752 ERR_NOT_SUPPORTED(item, "elm_object_item_focus_get");
4757 _elm_widget_item_domain_translatable_part_text_set(Eo *eo_item EINA_UNUSED,
4758 Elm_Widget_Item_Data *item,
4763 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
4764 ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
4765 Elm_Translate_String_Data *ts;
4769 _part_text_translatable_set(&item->translate_strings, part, EINA_FALSE,
4774 ts = _part_text_translatable_set(&item->translate_strings, part,
4775 EINA_TRUE, EINA_FALSE);
4777 if (!ts->string) ts->string = eina_stringshare_add(label);
4778 else eina_stringshare_replace(&ts->string, label);
4779 if (!ts->domain) ts->domain = eina_stringshare_add(domain);
4780 else eina_stringshare_replace(&ts->domain, domain);
4782 if (label[0]) label = dgettext(domain, label);
4785 item->on_translate = EINA_TRUE;
4786 elm_wdg_item_part_text_set(item->eo_obj, part, label);
4787 item->on_translate = EINA_FALSE;
4790 EOLIAN static const char *
4791 _elm_widget_item_translatable_part_text_get(const Eo *eo_item EINA_UNUSED,
4792 Elm_Widget_Item_Data *item,
4795 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item, NULL);
4796 ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item, NULL);
4798 Elm_Translate_String_Data *ts;
4799 ts = _translate_string_data_get(item->translate_strings, part);
4800 if (ts) return ts->string;
4805 _elm_widget_item_domain_part_text_translatable_set(Eo *eo_item EINA_UNUSED,
4806 Elm_Widget_Item_Data *item,
4809 Eina_Bool translatable)
4811 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
4812 ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
4813 Elm_Translate_String_Data *ts;
4816 ts = _part_text_translatable_set(&item->translate_strings, part,
4817 translatable, EINA_TRUE);
4819 if (!ts->domain) ts->domain = eina_stringshare_add(domain);
4820 else eina_stringshare_replace(&ts->domain, domain);
4822 text = elm_wdg_item_part_text_get(item->eo_obj, part);
4824 if (!text || !text[0]) return;
4826 if (!ts->string) ts->string = eina_stringshare_add(text);
4828 //Try to translate text since we don't know the text is already translated.
4830 text = dgettext(domain, text);
4832 item->on_translate = EINA_TRUE;
4833 elm_wdg_item_part_text_set(item->eo_obj, part, text);
4834 item->on_translate = EINA_FALSE;
4838 _elm_widget_item_track_cancel(Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item)
4840 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
4841 ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
4843 if (!item->track_obj) return;
4845 while (evas_object_ref_get(item->track_obj) > 0)
4846 evas_object_unref(item->track_obj);
4848 evas_object_del(item->track_obj);
4851 EOLIAN static Evas_Object *
4852 _elm_widget_item_track(Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item)
4854 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item, NULL);
4855 ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item, NULL);
4857 if (item->track_obj)
4859 evas_object_ref(item->track_obj);
4860 return item->track_obj;
4865 WRN("view obj of the item(%p) is invalid. Please make sure the view obj is created!", item);
4869 Evas_Object *track =
4870 evas_object_rectangle_add(evas_object_evas_get(item->widget));
4871 evas_object_color_set(track, 0, 0, 0, 0);
4872 evas_object_pass_events_set(track, EINA_TRUE);
4873 _track_obj_update(track, item->view);
4874 evas_object_event_callback_add(track, EVAS_CALLBACK_DEL, _track_obj_del,
4877 efl_event_callback_array_add(item->view, tracker_callbacks(), item);
4879 evas_object_ref(track);
4881 item->track_obj = track;
4887 _elm_widget_item_untrack(Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item)
4889 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
4890 ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
4892 if (!item->track_obj) return;
4893 evas_object_unref(item->track_obj);
4895 if (evas_object_ref_get(item->track_obj) == 0)
4896 evas_object_del(item->track_obj);
4900 _elm_widget_item_track_get(const Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item)
4902 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item, 0);
4903 ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item, 0);
4905 if (!item->track_obj) return 0;
4906 return evas_object_ref_get(item->track_obj);
4909 typedef struct _Elm_Widget_Item_Tooltip Elm_Widget_Item_Tooltip;
4911 struct _Elm_Widget_Item_Tooltip
4913 Elm_Widget_Item_Data *item;
4914 Elm_Tooltip_Item_Content_Cb func;
4915 Evas_Smart_Cb del_cb;
4919 static Evas_Object *
4920 _elm_widget_item_tooltip_label_create(void *data,
4921 Evas_Object *obj EINA_UNUSED,
4922 Evas_Object *tooltip,
4923 void *item EINA_UNUSED)
4925 Evas_Object *label = elm_label_add(tooltip);
4928 elm_object_style_set(label, "tooltip");
4929 elm_object_text_set(label, data);
4933 static Evas_Object *
4934 _elm_widget_item_tooltip_trans_label_create(void *data,
4935 Evas_Object *obj EINA_UNUSED,
4936 Evas_Object *tooltip,
4937 void *item EINA_UNUSED)
4939 Evas_Object *label = elm_label_add(tooltip);
4942 elm_object_style_set(label, "tooltip");
4943 elm_object_translatable_text_set(label, data);
4948 _elm_widget_item_tooltip_label_del_cb(void *data,
4949 Evas_Object *obj EINA_UNUSED,
4950 void *event_info EINA_UNUSED)
4952 eina_stringshare_del(data);
4958 * Set the text to be shown in the widget item.
4960 * @param item Target item
4961 * @param text The text to set in the content
4963 * Setup the text as tooltip to object. The item can have only one tooltip,
4964 * so any previous tooltip data is removed.
4969 _elm_widget_item_tooltip_text_set(Eo *eo_item EINA_UNUSED,
4970 Elm_Widget_Item_Data *item EINA_UNUSED,
4973 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
4974 ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
4975 EINA_SAFETY_ON_NULL_RETURN(text);
4977 text = eina_stringshare_add(text);
4978 elm_wdg_item_tooltip_content_cb_set(item->eo_obj, _elm_widget_item_tooltip_label_create, text, _elm_widget_item_tooltip_label_del_cb);
4982 _elm_widget_item_tooltip_translatable_text_set(Eo *eo_item EINA_UNUSED,
4983 Elm_Widget_Item_Data *item EINA_UNUSED,
4986 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
4987 ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
4988 EINA_SAFETY_ON_NULL_RETURN(text);
4990 text = eina_stringshare_add(text);
4991 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);
4994 static Evas_Object *
4995 _elm_widget_item_tooltip_create(void *data,
4997 Evas_Object *tooltip)
4999 Elm_Widget_Item_Tooltip *wit = data;
5000 return wit->func((void *)wit->data, obj, tooltip, wit->item->eo_obj);
5004 _elm_widget_item_tooltip_del_cb(void *data,
5006 void *event_info EINA_UNUSED)
5008 Elm_Widget_Item_Tooltip *wit = data;
5009 if (wit->del_cb) wit->del_cb((void *)wit->data, obj, wit->item->eo_obj);
5016 * Set the content to be shown in the tooltip item
5018 * Setup the tooltip to item. The item can have only one tooltip,
5019 * so any previous tooltip data is removed. @p func(with @p data) will
5020 * be called every time that need show the tooltip and it should
5021 * return a valid Evas_Object. This object is then managed fully by
5022 * tooltip system and is deleted when the tooltip is gone.
5024 * @param item the widget item being attached a tooltip.
5025 * @param func the function used to create the tooltip contents.
5026 * @param data what to provide to @a func as callback data/context.
5027 * @param del_cb called when data is not needed anymore, either when
5028 * another callback replaces @func, the tooltip is unset with
5029 * elm_widget_item_tooltip_unset() or the owner @a item
5030 * dies. This callback receives as the first parameter the
5031 * given @a data, and @c event_info is the item.
5036 _elm_widget_item_tooltip_content_cb_set(Eo *eo_item EINA_UNUSED,
5037 Elm_Widget_Item_Data *item,
5038 Elm_Tooltip_Item_Content_Cb func,
5040 Evas_Smart_Cb del_cb)
5042 Elm_Widget_Item_Tooltip *wit;
5044 ELM_WIDGET_ITEM_CHECK_OR_GOTO(item, error_noitem);
5045 //ELM_WIDGET_ITEM_RETURN_IF_GOTO(item, error_noitem);
5049 elm_wdg_item_tooltip_unset(item->eo_obj);
5053 wit = ELM_NEW(Elm_Widget_Item_Tooltip);
5054 if (!wit) goto error;
5058 wit->del_cb = del_cb;
5060 elm_object_sub_tooltip_content_cb_set
5061 (item->view, item->widget, _elm_widget_item_tooltip_create, wit,
5062 _elm_widget_item_tooltip_del_cb);
5067 if (del_cb) del_cb((void *)data, NULL, item);
5070 if (del_cb) del_cb((void *)data, item->widget, item);
5076 * Unset tooltip from item
5078 * @param item widget item to remove previously set tooltip.
5080 * Remove tooltip from item. The callback provided as del_cb to
5081 * elm_widget_item_tooltip_content_cb_set() will be called to notify
5082 * it is not used anymore.
5084 * @see elm_widget_item_tooltip_content_cb_set()
5089 _elm_widget_item_tooltip_unset(Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item)
5091 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
5092 ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
5094 elm_object_tooltip_unset(item->view);
5100 * Sets a different style for this item tooltip.
5102 * @note before you set a style you should define a tooltip with
5103 * elm_widget_item_tooltip_content_cb_set() or
5104 * elm_widget_item_tooltip_text_set()
5106 * @param item widget item with tooltip already set.
5107 * @param style the theme style to use (default, transparent, ...)
5112 _elm_widget_item_tooltip_style_set(Eo *eo_item EINA_UNUSED,
5113 Elm_Widget_Item_Data *item,
5116 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
5117 ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
5119 elm_object_tooltip_style_set(item->view, style);
5122 EOLIAN static Eina_Bool
5123 _elm_widget_item_tooltip_window_mode_set(Eo *eo_item EINA_UNUSED,
5124 Elm_Widget_Item_Data *item,
5127 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item, EINA_FALSE);
5128 ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item, EINA_FALSE);
5130 return elm_object_tooltip_window_mode_set(item->view, disable);
5133 EOLIAN static Eina_Bool
5134 _elm_widget_item_tooltip_window_mode_get(const Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item)
5136 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item, EINA_FALSE);
5137 ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item, EINA_FALSE);
5139 return elm_object_tooltip_window_mode_get(item->view);
5145 * Get the style for this item tooltip.
5147 * @param item widget item with tooltip already set.
5148 * @return style the theme style in use, defaults to "default". If the
5149 * object does not have a tooltip set, then NULL is returned.
5153 EOLIAN static const char *
5154 _elm_widget_item_tooltip_style_get(const Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item)
5156 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item, NULL);
5158 return elm_object_tooltip_style_get(item->view);
5162 _elm_widget_item_cursor_set(Eo *eo_item EINA_UNUSED,
5163 Elm_Widget_Item_Data *item,
5166 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
5167 ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
5169 elm_object_sub_cursor_set(item->view, item->widget, cursor);
5172 EOLIAN static const char *
5173 _elm_widget_item_cursor_get(const Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item)
5175 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item, NULL);
5176 return elm_object_sub_cursor_get(item->view);
5180 _elm_widget_item_cursor_unset(Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item)
5182 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
5183 ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
5185 elm_object_cursor_unset(item->view);
5191 * Sets a different style for this item cursor.
5193 * @note before you set a style you should define a cursor with
5194 * elm_widget_item_cursor_set()
5196 * @param item widget item with cursor already set.
5197 * @param style the theme style to use (default, transparent, ...)
5202 _elm_widget_item_cursor_style_set(Eo *eo_item EINA_UNUSED,
5203 Elm_Widget_Item_Data *item,
5206 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
5207 ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
5209 elm_object_sub_cursor_style_set(item->view, style);
5215 * Get the style for this item cursor.
5217 * @param item widget item with cursor already set.
5218 * @return style the theme style in use, defaults to "default". If the
5219 * object does not have a cursor set, then NULL is returned.
5223 EOLIAN static const char *
5224 _elm_widget_item_cursor_style_get(const Eo *eo_item EINA_UNUSED,
5225 Elm_Widget_Item_Data *item)
5227 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item, NULL);
5228 return elm_object_sub_cursor_style_get(item->view);
5234 * Set if the cursor set should be searched on the theme or should use
5235 * the provided by the engine, only.
5237 * @note before you set if should look on theme you should define a cursor
5238 * with elm_object_cursor_set(). By default it will only look for cursors
5239 * provided by the engine.
5241 * @param item widget item with cursor already set.
5242 * @param engine_only boolean to define it cursors should be looked only
5243 * between the provided by the engine or searched on widget's theme as well.
5248 _elm_widget_item_cursor_engine_only_set(Eo *eo_item EINA_UNUSED,
5249 Elm_Widget_Item_Data *item,
5250 Eina_Bool engine_only)
5252 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
5253 ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
5255 elm_object_sub_cursor_theme_search_enabled_set(item->view, !engine_only);
5261 * Get the cursor engine only usage for this item cursor.
5263 * @param item widget item with cursor already set.
5264 * @return engine_only boolean to define it cursors should be looked only
5265 * between the provided by the engine or searched on widget's theme as well. If
5266 * the object does not have a cursor set, then EINA_FALSE is returned.
5270 EOLIAN static Eina_Bool
5271 _elm_widget_item_cursor_engine_only_get(const Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item)
5273 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item, EINA_FALSE);
5274 return !elm_object_sub_cursor_theme_search_enabled_get(item->view);
5278 _elm_widget_item_part_content_set(Eo *eo_item EINA_UNUSED,
5279 Elm_Widget_Item_Data *item,
5280 const char *part EINA_UNUSED,
5281 Evas_Object *content EINA_UNUSED)
5283 ERR_NOT_SUPPORTED(item, "elm_object_part_content_set()");
5286 EOLIAN static Evas_Object *
5287 _elm_widget_item_part_content_get(const Eo *eo_item EINA_UNUSED,
5288 Elm_Widget_Item_Data *item,
5289 const char *part EINA_UNUSED)
5291 ERR_NOT_SUPPORTED(item, "elm_object_part_content_get()");
5295 EOLIAN static Evas_Object *
5296 _elm_widget_item_part_content_unset(Eo *eo_item EINA_UNUSED,
5297 Elm_Widget_Item_Data *item,
5298 const char *part EINA_UNUSED)
5300 ERR_NOT_SUPPORTED(item, "elm_object_part_content_unset()");
5305 _elm_widget_item_part_text_set(Eo *eo_item EINA_UNUSED,
5306 Elm_Widget_Item_Data *item,
5307 const char *part EINA_UNUSED,
5308 const char *label EINA_UNUSED)
5310 ERR_NOT_SUPPORTED(item, "elm_object_part_text_set()");
5313 EOLIAN static const char *
5314 _elm_widget_item_part_text_get(const Eo *eo_item EINA_UNUSED,
5315 Elm_Widget_Item_Data *item,
5316 const char *part EINA_UNUSED)
5318 ERR_NOT_SUPPORTED(item, "elm_object_part_text_get()");
5323 _elm_widget_item_part_text_custom_free(void *data)
5325 Elm_Label_Data *label;
5327 eina_stringshare_del(label->part);
5328 eina_stringshare_del(label->text);
5333 _elm_widget_item_part_text_custom_set(Eo *eo_item EINA_UNUSED,
5334 Elm_Widget_Item_Data *item,
5338 Elm_Label_Data *label;
5339 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
5340 ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
5344 eina_hash_stringshared_new(_elm_widget_item_part_text_custom_free);
5345 label = eina_hash_find(item->labels, part);
5348 label = malloc(sizeof(Elm_Label_Data));
5351 ERR("Failed to allocate memory");
5354 label->part = eina_stringshare_add(part);
5355 label->text = eina_stringshare_add(text);
5356 eina_hash_add(item->labels, part, label);
5359 eina_stringshare_replace(&label->text, text);
5362 EOLIAN static const char *
5363 _elm_widget_item_part_text_custom_get(const Eo *eo_item EINA_UNUSED,
5364 Elm_Widget_Item_Data *item,
5367 Elm_Label_Data *label;
5368 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item, NULL);
5369 label = eina_hash_find(item->labels, part);
5370 return label ? label->text : NULL;
5374 _elm_widget_item_part_text_custom_foreach(const Eina_Hash *labels EINA_UNUSED,
5375 const void *key EINA_UNUSED,
5379 Elm_Label_Data *label;
5380 Elm_Widget_Item_Data *item;
5384 elm_wdg_item_part_text_set(item->eo_obj, label->part, label->text);
5390 _elm_widget_item_part_text_custom_update(Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item)
5392 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
5393 ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
5395 eina_hash_foreach(item->labels,
5396 _elm_widget_item_part_text_custom_foreach, item);
5400 _elm_widget_item_signal_emit(Eo *eo_item EINA_UNUSED,
5401 Elm_Widget_Item_Data *item EINA_UNUSED,
5402 const char *emission EINA_UNUSED,
5403 const char *source EINA_UNUSED)
5409 _elm_widget_item_signal_callback_add(Eo *eo_item,
5410 Elm_Widget_Item_Data *item,
5411 const char *emission,
5413 Elm_Object_Item_Signal_Cb func,
5416 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
5417 ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
5418 EINA_SAFETY_ON_NULL_RETURN(func);
5420 Elm_Widget_Item_Signal_Data *wisd;
5422 wisd = malloc(sizeof(Elm_Widget_Item_Signal_Data));
5425 wisd->item = eo_item;
5426 wisd->func = (Elm_Widget_Item_Signal_Cb)func;
5428 wisd->emission = eina_stringshare_add(emission);
5429 wisd->source = eina_stringshare_add(source);
5431 if (_elm_widget_is(item->view))
5432 elm_object_signal_callback_add(item->view, emission, source, _elm_widget_item_signal_cb, wisd);
5433 else if (efl_isa(item->view, EFL_CANVAS_LAYOUT_CLASS))
5434 edje_object_signal_callback_add(item->view, emission, source, _elm_widget_item_signal_cb, wisd);
5437 WRN("The %s widget item doesn't support signal callback add!",
5438 efl_class_name_get(efl_class_get(item->widget)));
5443 item->signals = eina_list_append(item->signals, wisd);
5446 EOLIAN static void *
5447 _elm_widget_item_signal_callback_del(Eo *eo_item EINA_UNUSED,
5448 Elm_Widget_Item_Data *item,
5449 const char *emission,
5451 Elm_Object_Item_Signal_Cb func)
5453 Elm_Widget_Item_Signal_Data *wisd;
5456 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item, NULL);
5457 ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item, NULL);
5458 EINA_SAFETY_ON_NULL_RETURN_VAL(func, NULL);
5460 EINA_LIST_FOREACH(item->signals, l, wisd)
5462 if ((wisd->func == (Elm_Widget_Item_Signal_Cb)func) &&
5463 !strcmp(wisd->emission, emission) &&
5464 !strcmp(wisd->source, source))
5465 return _elm_widget_item_signal_callback_list_get(item, l);
5474 _elm_widget_item_access_info_set(Eo *eo_item EINA_UNUSED,
5475 Elm_Widget_Item_Data *item,
5478 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
5479 ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
5481 eina_stringshare_del(item->access_info);
5482 if (!txt) item->access_info = NULL;
5483 else item->access_info = eina_stringshare_add(txt);
5487 _elm_widget_item_translate(Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item)
5489 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
5490 ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
5493 Elm_Translate_String_Data *ts;
5494 EINA_INLIST_FOREACH(item->translate_strings, ts)
5496 if (!ts->string) continue;
5497 const char *s = dgettext(ts->domain, ts->string);
5498 item->on_translate = EINA_TRUE;
5499 elm_wdg_item_part_text_set(item->eo_obj, ts->id, s);
5500 item->on_translate = EINA_FALSE;
5506 _elm_widget_item_access_order_set(Eo *eo_item EINA_UNUSED,
5507 Elm_Widget_Item_Data *item,
5510 _elm_access_widget_item_access_order_set(item, objs);
5513 EOLIAN static const Eina_List *
5514 _elm_widget_item_access_order_get(const Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item)
5516 return _elm_access_widget_item_access_order_get(item);
5520 _elm_widget_item_access_order_unset(Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item)
5522 _elm_access_widget_item_access_order_unset(item);
5525 EOLIAN static Evas_Object*
5526 _elm_widget_item_access_register(Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item)
5528 _elm_access_widget_item_register(item);
5529 return item->access_obj;
5533 _elm_widget_item_access_unregister(Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item)
5535 _elm_access_widget_item_unregister(item);
5538 EOLIAN static Evas_Object*
5539 _elm_widget_item_access_object_get(const Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item)
5541 return item->access_obj;
5544 EOLIAN static Evas_Object *
5545 _elm_widget_item_focus_next_object_get(const Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item, Elm_Focus_Direction dir)
5547 Evas_Object *ret = NULL;
5549 if (dir == ELM_FOCUS_PREVIOUS)
5550 ret = item->focus_previous;
5551 else if (dir == ELM_FOCUS_NEXT)
5552 ret = item->focus_next;
5553 else if (dir == ELM_FOCUS_UP)
5554 ret = item->focus_up;
5555 else if (dir == ELM_FOCUS_DOWN)
5556 ret = item->focus_down;
5557 else if (dir == ELM_FOCUS_RIGHT)
5558 ret = item->focus_right;
5559 else if (dir == ELM_FOCUS_LEFT)
5560 ret = item->focus_left;
5566 _elm_widget_item_focus_next_object_set(Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item, Evas_Object *next, Elm_Focus_Direction dir)
5568 if (dir == ELM_FOCUS_PREVIOUS)
5569 item->focus_previous = next;
5570 else if (dir == ELM_FOCUS_NEXT)
5571 item->focus_next = next;
5572 else if (dir == ELM_FOCUS_UP)
5573 item->focus_up = next;
5574 else if (dir == ELM_FOCUS_DOWN)
5575 item->focus_down = next;
5576 else if (dir == ELM_FOCUS_RIGHT)
5577 item->focus_right = next;
5578 else if (dir == ELM_FOCUS_LEFT)
5579 item->focus_left = next;
5582 EOLIAN static Elm_Object_Item*
5583 _elm_widget_item_focus_next_item_get(const Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item, Elm_Focus_Direction dir)
5585 Elm_Object_Item *ret = NULL;
5587 if (dir == ELM_FOCUS_PREVIOUS)
5588 ret = item->item_focus_previous;
5589 else if (dir == ELM_FOCUS_NEXT)
5590 ret = item->item_focus_next;
5591 else if (dir == ELM_FOCUS_UP)
5592 ret = item->item_focus_up;
5593 else if (dir == ELM_FOCUS_DOWN)
5594 ret = item->item_focus_down;
5595 else if (dir == ELM_FOCUS_RIGHT)
5596 ret = item->item_focus_right;
5597 else if (dir == ELM_FOCUS_LEFT)
5598 ret = item->item_focus_left;
5604 _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)
5606 if (dir == ELM_FOCUS_PREVIOUS)
5607 item->item_focus_previous = next_item;
5608 else if (dir == ELM_FOCUS_NEXT)
5609 item->item_focus_next = next_item;
5610 else if (dir == ELM_FOCUS_UP)
5611 item->item_focus_up = next_item;
5612 else if (dir == ELM_FOCUS_DOWN)
5613 item->item_focus_down = next_item;
5614 else if (dir == ELM_FOCUS_RIGHT)
5615 item->item_focus_right = next_item;
5616 else if (dir == ELM_FOCUS_LEFT)
5617 item->item_focus_left = next_item;
5620 /* happy debug functions */
5623 _sub_obj_tree_dump(const Evas_Object *obj,
5628 for (i = 0; i < lvl * 3; i++)
5631 if (_elm_widget_is(obj))
5636 elm_widget_type_get(obj),
5638 for (unsigned int i = 0; i < eina_array_count(sd->children); ++i)
5640 obj = eina_array_data_get(sd->children, i);
5641 _sub_obj_tree_dump(obj, lvl + 1);
5645 DBG("+ %s(%p)\n", evas_object_type_get(obj), obj);
5649 _sub_obj_tree_dot_dump(const Evas_Object *obj,
5652 if (!_elm_widget_is(obj))
5656 Eina_Bool visible = evas_object_visible_get(obj);
5657 Eina_Bool disabled = elm_widget_disabled_get(obj);
5658 Eina_Bool focused = efl_ui_focus_object_focus_get(obj);
5659 Eina_Bool can_focus = elm_widget_can_focus_get(obj);
5663 fprintf(output, "\"%p\" -- \"%p\" [ color=black", sd->parent_obj, obj);
5666 fprintf(output, ", style=bold");
5669 fprintf(output, ", color=gray28");
5671 fprintf(output, " ];\n");
5674 fprintf(output, "\"%p\" [ label = \"{%p|%s|%s|visible: %d|"
5675 "disabled: %d|focused: %d/%d|focus order:%d}\"",
5676 obj, obj, elm_widget_type_get(obj),
5677 evas_object_name_get(obj), visible, disabled, focused, can_focus,
5681 fprintf(output, ", style=bold");
5684 fprintf(output, ", fontcolor=gray28");
5686 if ((disabled) || (!visible))
5687 fprintf(output, ", color=gray");
5689 fprintf(output, " ];\n");
5694 for (unsigned int i = 0; i < eina_array_count(sd->children); ++i)
5696 o = eina_array_data_get(sd->children, i);
5697 _sub_obj_tree_dot_dump(o, output);
5704 elm_widget_tree_dump(const Evas_Object *top)
5707 if (!_elm_widget_is(top))
5709 _sub_obj_tree_dump(top, 0);
5717 elm_widget_tree_dot_dump(const Evas_Object *top,
5721 if (!_elm_widget_is(top))
5723 fprintf(output, "graph " " { node [shape=record];\n");
5724 _sub_obj_tree_dot_dump(top, output);
5725 fprintf(output, "}\n");
5733 EINA_UNUSED static void
5734 _focus_event_changed(void *data EINA_UNUSED, const Efl_Event *event)
5736 if (efl_ui_focus_object_focus_get(event->object))
5737 evas_object_smart_callback_call(event->object, "focused", NULL);
5739 evas_object_smart_callback_call(event->object, "unfocused", NULL);
5743 _efl_ui_widget_efl_object_constructor(Eo *obj, Elm_Widget_Smart_Data *sd EINA_UNUSED)
5745 Eo *parent = efl_parent_get(obj);
5746 sd->on_create = EINA_TRUE;
5748 sd->window = efl_provider_find(efl_parent_get(obj), EFL_UI_WIN_CLASS);
5749 if (!efl_isa(obj, EFL_UI_WIN_CLASS))
5751 if (!efl_isa(parent, EFL_UI_WIDGET_CLASS))
5753 ERR("You passed a wrong parent parameter (%p %s). "
5754 "Elementary widget's parent should be an elementary widget.",
5755 parent, evas_object_type_get(parent));
5759 ELM_WIDGET_DATA_GET(parent, parent_sd);
5761 sd->shared_win_data = parent_sd->shared_win_data;
5766 sd->shared_win_data = efl_ui_win_shared_data_get(obj);
5769 _efl_ui_focus_event_redirector(obj, obj);
5770 efl_canvas_group_clipped_set(obj, EINA_FALSE);
5771 obj = efl_constructor(efl_super(obj, MY_CLASS));
5772 efl_canvas_object_type_set(obj, MY_CLASS_NAME_LEGACY);
5773 evas_object_smart_callbacks_descriptions_set(obj, _smart_callbacks);
5775 if (!efl_isa(obj, EFL_UI_WIN_CLASS) && efl_isa(parent, EFL_UI_WIDGET_CLASS))
5776 efl_ui_widget_sub_object_add(parent, obj);
5778 sd->on_create = EINA_FALSE;
5780 efl_access_object_role_set(obj, EFL_ACCESS_ROLE_UNKNOWN);
5781 //TIZEN_ONLY(20170717) : expose highlight information on atspi
5782 sd->can_highlight = EINA_TRUE;
5784 /***********************************************************
5785 * TIZEN_ONLY(20180117): Override Paragraph Direction APIs *
5786 ***********************************************************/
5787 sd->inherit_paragraph_direction = EINA_TRUE;
5789 if (efl_isa(parent, EFL_CANVAS_OBJECT_CLASS))
5791 if (sd->paragraph_direction != efl_canvas_object_paragraph_direction_get(parent))
5793 sd->paragraph_direction = efl_canvas_object_paragraph_direction_get(parent);
5794 _efl_ui_widget_efl_canvas_object_paragraph_direction_set_internal(obj, sd, sd->paragraph_direction);
5795 efl_canvas_object_paragraph_direction_set(efl_super(obj, MY_CLASS), sd->paragraph_direction);
5802 if (!elm_widget_is_legacy(obj))
5803 EINA_SAFETY_ON_NULL_RETURN_VAL(sd->shared_win_data, NULL);
5808 EOLIAN static Efl_Object*
5809 _efl_ui_widget_efl_object_finalize(Eo *obj, Elm_Widget_Smart_Data *pd)
5813 eo = efl_finalize(efl_super(obj, MY_CLASS));
5815 _full_eval(obj, pd);
5822 _efl_ui_widget_efl_object_destructor(Eo *obj, Elm_Widget_Smart_Data *sd)
5824 if (sd->manager.provider)
5826 sd->manager.provider = NULL;
5829 //TIZEN_ONLY : elm_widget_item: add at-spi name setter
5830 efl_access_object_description_set(obj, NULL);
5831 efl_access_object_i18n_name_set(obj, NULL);
5833 efl_access_object_description_cb_set(obj, NULL, NULL);
5834 efl_access_object_name_cb_set(obj, NULL, NULL);
5836 //TIZEN_ONLY(20230414): Support org.a11y.atspi.Value.Text property.
5837 efl_access_object_value_text_set(obj, NULL);
5838 efl_access_object_value_text_cb_set(obj, NULL, NULL);
5840 //TIZEN_ONLY(20170405) Add gesture method to accessible interface
5841 efl_access_object_gesture_cb_set(obj, NULL, NULL);
5843 //TIZEN_ONLY : elm_widget_item: add at-spi name setter
5844 efl_access_object_translation_domain_set(obj, NULL);
5845 efl_access_object_relationships_clear(obj);
5848 efl_access_object_attributes_clear(obj);
5849 if (sd->logical.parent)
5851 efl_weak_unref(&sd->logical.parent);
5852 sd->logical.parent = NULL;
5855 // TIZEN_ONLY(20150709) : atspi relations api
5856 if (sd->atspi_custom_relations)
5857 efl_access_relation_set_free(&sd->atspi_custom_relations);
5860 //TIZEN_ONLY(20150717) add widget name setter
5862 eina_stringshare_del(sd->name);
5865 //TIZEN_ONLY(20150731) : add i18n support for name and description
5866 if (sd->atspi_translation_domain)
5867 eina_stringshare_del(sd->atspi_translation_domain);
5870 // TIZEN_ONLY(20200623) : apply Tizen's color_class features
5871 if (sd->color_classes)
5872 ELM_SAFE_FREE(sd->color_classes, eina_hash_free);
5877 eina_array_free(sd->children);
5878 sd->children = NULL;
5881 sd->on_destroy = EINA_TRUE;
5882 efl_destructor(efl_super(obj, EFL_UI_WIDGET_CLASS));
5883 sd->on_destroy = EINA_FALSE;
5889 _efl_ui_widget_efl_object_debug_name_override(Eo *obj, Elm_Widget_Smart_Data *sd EINA_UNUSED, Eina_Strbuf *sb)
5891 const char *focus = "";
5893 if (efl_ui_focus_object_focus_get(obj)) focus = ":focused";
5894 efl_debug_name_override(efl_super(obj, MY_CLASS), sb);
5895 eina_strbuf_append_printf(sb, "%s", focus);
5898 EOLIAN static Eina_Bool
5899 _efl_ui_widget_efl_ui_focus_object_on_focus_update(Eo *obj, Elm_Widget_Smart_Data *sd)
5903 if (!elm_widget_can_focus_get(obj))
5906 focused = efl_ui_focus_object_focus_get(obj);
5908 if (!sd->resize_obj)
5909 evas_object_focus_set(obj, focused);
5911 //TIZEN_ONLY(20180607): Restore legacy focus
5913 evas_object_smart_callback_call(obj, "focused", NULL);
5915 evas_object_smart_callback_call(obj, "unfocused", NULL);
5918 if (_elm_atspi_enabled() && !elm_widget_child_can_focus_get(obj))
5919 efl_access_state_changed_signal_emit(obj, EFL_ACCESS_STATE_TYPE_FOCUSED, focused);
5924 EOLIAN static Eina_Bool
5925 _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)
5930 EOLIAN static Eina_Bool
5931 _efl_ui_widget_on_access_activate(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *_pd EINA_UNUSED, Efl_Ui_Activate act EINA_UNUSED)
5933 WRN("The %s widget does not implement the \"activate\" functions.",
5934 efl_class_name_get(efl_class_get(obj)));
5939 _efl_ui_widget_class_constructor(Efl_Class *klass)
5941 evas_smart_legacy_type_register(MY_CLASS_NAME_LEGACY, klass);
5944 EOLIAN static Eina_Bool
5945 _efl_ui_widget_efl_access_component_focus_grab(Eo *obj, Elm_Widget_Smart_Data *pd EINA_UNUSED)
5947 if (elm_object_focus_allow_get(obj))
5949 Ecore_Evas *ee = ecore_evas_ecore_evas_get(evas_object_evas_get(obj));
5950 if (!ee) return EINA_FALSE;
5951 ecore_evas_activate(ee);
5952 elm_object_focus_set(obj, EINA_TRUE);
5959 EOLIAN static const char*
5960 _efl_ui_widget_efl_access_object_i18n_name_get(const Eo *obj, Elm_Widget_Smart_Data *_pd EINA_UNUSED)
5962 const char *ret, *name;
5963 name = efl_access_object_i18n_name_get(efl_super(obj, EFL_UI_WIDGET_CLASS));
5965 if (name) return name;
5967 //TIZEN_ONLY(20150717) add widget name setter
5971 if (_pd->atspi_translation_domain)
5972 return dgettext(_pd->atspi_translation_domain, _pd->name);
5978 //TIZEN_ONLY(20170110) : Ignore text from elm_object_text_set in accessible_name_get
5979 Efl_Access_Role role;
5980 role = efl_access_object_role_get(obj);
5981 if(role == EFL_ACCESS_ROLE_DIALOG || role == EFL_ACCESS_ROLE_PASSWORD_TEXT)
5985 ret = elm_object_text_get(obj);
5986 if (!ret) return NULL;
5988 return _elm_widget_accessible_plain_name_get(obj, ret);
5991 EOLIAN static Eina_List*
5992 _efl_ui_widget_efl_access_object_access_children_get(const Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *pd)
5994 Eina_List *l, *accs = NULL;
5995 Evas_Object *widget;
5998 /* this is for webapp which is using window only */
5999 if (efl_access_object_role_get(obj) == EFL_ACCESS_ROLE_WINDOW)
6001 if (evas_object_data_get(obj, "__PlugID"))
6002 elm_atspi_ewk_wrapper_a11y_init((Eo *)obj, (Eo *)obj);
6005 for (unsigned int i = 0; i < eina_array_count(pd->children); ++i)
6007 widget = eina_array_data_get(pd->children, i);
6008 const char *type = evas_object_type_get(widget);
6010 // Ugly Tizen hack to integrate AT-SPI2 accessibility provided by WebKit/Chromium with elementary one.
6011 // This wrapper class should be implemented in Webkit/Chromium EFL ports
6012 if (type && (!strcmp(type, "EWebView") || !strcmp(type, "WebView")))
6014 elm_atspi_ewk_wrapper_a11y_init((Eo *)obj, widget);
6017 for (unsigned int i = 0; i < eina_array_count(pd->children); ++i)
6019 widget = eina_array_data_get(pd->children, i);
6021 // TIZEN_ONLY(20160705) - enable atspi_proxy to work
6022 /* This assumes that only one proxy exists in obj */
6025 proxy = plug_type_proxy_get(obj, widget);
6028 accs = eina_list_append(accs, proxy);
6034 if (!elm_object_widget_check(widget)) continue;
6035 if (!efl_isa(widget, EFL_ACCESS_OBJECT_MIXIN)) continue;
6036 accs = eina_list_append(accs, widget);
6038 //TIZEN_ONLY(20150709) : spatially sort atspi children
6039 // sort children using its top-left coordinate
6040 accs = eina_list_sort(accs, -1, _sort_vertically);
6041 Eina_List *line, *lines = _lines_split(accs);
6043 EINA_LIST_FREE(lines, line)
6044 accs = eina_list_merge(accs, eina_list_sort(line, -1, _sort_horizontally));
6050 accs = eina_list_remove(accs, proxy);
6051 EINA_LIST_FOREACH(accs, l, widget)
6053 if (efl_isa(widget, ELM_ACCESS_CLASS))
6055 Elm_Access_Info *info = _elm_access_info_get(widget);
6056 if (!info) continue;
6057 if (obj == info->part_object)
6067 accs = eina_list_append_relative(accs, proxy, deputy);
6076 EOLIAN static Efl_Access_State_Set
6077 _efl_ui_widget_efl_access_object_state_set_get(const Eo *obj, Elm_Widget_Smart_Data *pd EINA_UNUSED)
6079 Efl_Access_State_Set states = 0;
6081 states = efl_access_object_state_set_get(efl_super(obj, EFL_UI_WIDGET_CLASS));
6083 // TIZEN_ONLY(20171114) Accessibility Highlight Frame added
6084 // //TIZEN_ONLY(20171108): bring HIGHLIGHT related changes
6085 // Evas_Object *win = elm_widget_top_get(obj);
6086 // if (win && efl_isa(win, EFL_UI_WIN_CLASS))
6088 // if (_elm_win_accessibility_highlight_get(win) == obj)
6089 // STATE_TYPE_SET(states, ELM_ATSPI_STATE_HIGHLIGHTED);
6091 // STATE_TYPE_SET(states, ELM_ATSPI_STATE_HIGHLIGHTABLE);
6095 if (evas_object_visible_get(obj))
6097 STATE_TYPE_SET(states, EFL_ACCESS_STATE_TYPE_VISIBLE);
6098 if (_elm_widget_onscreen_is(obj))
6099 STATE_TYPE_SET(states, EFL_ACCESS_STATE_TYPE_SHOWING);
6101 if (!elm_widget_child_can_focus_get(obj))
6103 if (elm_object_focus_allow_get(obj))
6104 STATE_TYPE_SET(states, EFL_ACCESS_STATE_TYPE_FOCUSABLE);
6105 if (elm_object_focus_get(obj))
6106 STATE_TYPE_SET(states, EFL_ACCESS_STATE_TYPE_FOCUSED);
6108 if (!elm_object_disabled_get(obj))
6110 STATE_TYPE_SET(states, EFL_ACCESS_STATE_TYPE_ENABLED);
6111 STATE_TYPE_SET(states, EFL_ACCESS_STATE_TYPE_SENSITIVE);
6114 //TIZEN_ONLY(20170717) : expose highlight information on atspi
6115 if (_elm_widget_highlightable(obj))
6116 STATE_TYPE_SET(states, EFL_ACCESS_STATE_TYPE_HIGHLIGHTABLE);
6118 STATE_TYPE_UNSET(states, EFL_ACCESS_STATE_TYPE_HIGHLIGHTABLE);
6120 if (_elm_object_accessibility_currently_highlighted_get() == (void*)obj)
6121 STATE_TYPE_SET(states, EFL_ACCESS_STATE_TYPE_HIGHLIGHTED);
6127 EOLIAN static Eina_List*
6128 _efl_ui_widget_efl_access_object_attributes_get(const Eo *obj, Elm_Widget_Smart_Data *pd EINA_UNUSED)
6130 const char *type = NULL;
6131 const char *style = NULL;
6132 Eina_List *attr_list = NULL;
6133 Efl_Access_Attribute *attr = NULL;
6135 attr_list = efl_access_object_attributes_get(efl_super(obj, EFL_UI_WIDGET_CLASS));
6137 //Add type and style information in addition.
6138 type = elm_widget_type_get(obj);
6141 attr = calloc(1, sizeof(Efl_Access_Attribute));
6144 attr->key = eina_stringshare_add("type");
6145 attr->value = eina_stringshare_add(type);
6146 attr_list = eina_list_append(attr_list, attr);
6150 style = elm_widget_style_get(obj);
6153 attr = calloc(1, sizeof(Efl_Access_Attribute));
6156 attr->key = eina_stringshare_add("style");
6157 attr->value = eina_stringshare_add(style);
6158 attr_list = eina_list_append(attr_list, attr);
6165 EOLIAN static Eina_List *
6166 _elm_widget_item_efl_access_object_attributes_get(const Eo *eo_item, Elm_Widget_Item_Data *pd EINA_UNUSED)
6168 const char *style = NULL;
6169 Eina_List *attr_list = NULL;
6170 Efl_Access_Attribute *attr = NULL;
6172 attr_list = efl_access_object_attributes_get(efl_super(eo_item, ELM_WIDGET_ITEM_CLASS));
6174 style = elm_object_item_style_get(eo_item);
6177 attr = calloc(1, sizeof(Efl_Access_Attribute));
6180 attr->key = eina_stringshare_add("style");
6181 attr->value = eina_stringshare_add(style);
6182 attr_list = eina_list_append(attr_list, attr);
6188 EOLIAN static Eina_Rect
6189 _elm_widget_item_efl_access_component_extents_get(const Eo *obj EINA_UNUSED, Elm_Widget_Item_Data *sd EINA_UNUSED, Eina_Bool screen_coords)
6191 Eina_Rect r = EINA_RECT(-1, -1, -1, -1);
6193 if (!sd->view) return r;
6195 r = efl_gfx_entity_geometry_get(sd->view);
6198 r = _efl_access_component_screen_coords_extents_get(obj, r);
6203 EOLIAN static Eina_Bool
6204 _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)
6209 EOLIAN static Eina_Bool
6210 _elm_widget_item_efl_access_component_focus_grab(Eo *obj EINA_UNUSED, Elm_Widget_Item_Data *_pd EINA_UNUSED)
6212 elm_object_item_focus_set(obj, EINA_TRUE);
6213 return elm_object_item_focus_get(obj);
6216 EOLIAN static Efl_Object *
6217 _efl_ui_widget_efl_object_provider_find(const Eo *obj, Elm_Widget_Smart_Data *pd, const Efl_Object *klass)
6219 Efl_Object *lookup = NULL;
6221 if ((klass == EFL_CONFIG_INTERFACE) || (klass == EFL_CONFIG_GLOBAL_CLASS))
6222 return _efl_config_obj;
6224 if (klass == EFL_UI_WIN_CLASS)
6228 //let the parent_obj lookup handle this
6231 if (klass == EFL_ACCESS_OBJECT_MIXIN)
6234 if (pd->provider_lookup) return NULL;
6235 pd->provider_lookup = EINA_TRUE;
6237 lookup = efl_provider_find(efl_super(obj, MY_CLASS), klass);
6238 if (!lookup && pd->parent_obj) lookup = efl_provider_find(pd->parent_obj, klass);
6240 pd->provider_lookup = EINA_FALSE;
6245 //TIZEN_ONLY(20191205): fix build warnings of focus_manager functions
6246 #pragma GCC diagnostic push
6247 #pragma GCC diagnostic ignored "-Wunused-function"
6250 EOLIAN static Efl_Ui_Focus_Manager*
6251 _efl_ui_widget_efl_ui_focus_object_focus_parent_get(const Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *pd EINA_UNUSED)
6253 return pd->focus.parent;
6256 EOLIAN static Efl_Ui_Focus_Manager*
6257 _efl_ui_widget_efl_ui_focus_object_focus_manager_get(const Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *pd EINA_UNUSED)
6259 return pd->focus.manager;
6262 EOLIAN static Eina_Rect
6263 _efl_ui_widget_efl_ui_focus_object_focus_geometry_get(const Eo *obj, Elm_Widget_Smart_Data *pd EINA_UNUSED)
6265 return efl_gfx_entity_geometry_get(obj);
6269 _efl_ui_widget_efl_ui_focus_object_focus_set(Eo *obj, Elm_Widget_Smart_Data *pd, Eina_Bool focus)
6271 pd->focused = focus;
6273 efl_ui_focus_object_focus_set(efl_super(obj, MY_CLASS), focus);
6275 efl_ui_focus_object_on_focus_update(obj);
6278 EOLIAN static Efl_Ui_Focus_Manager*
6279 _efl_ui_widget_focus_manager_create(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *pd EINA_UNUSED, Efl_Ui_Focus_Object *root EINA_UNUSED)
6281 ERR("No manager presented");
6285 //TIZEN_ONLY(20191205): fix build warnings of focus_manager functions
6286 #pragma GCC diagnostic pop
6289 //TIZEN_ONLY(20160726): add API elm_object_part_access_object_get
6290 EOLIAN static Evas_Object*
6291 _efl_ui_widget_part_access_object_get(const Eo *obj, Elm_Widget_Smart_Data *_pd EINA_UNUSED, const char *part EINA_UNUSED)
6293 WRN("The %s widget does not implement the \"part_access_object_get\" functions.",
6294 efl_class_name_get(efl_class_get(obj)));
6302 elm_widget_on_show_region_hook_set(Eo *obj, void *data, Elm_Widget_On_Show_Region_Cb func, Eina_Free_Cb func_free_cb)
6304 ELM_WIDGET_DATA_GET(obj, sd);
6307 if ((sd->on_show_region_data == data) && (sd->on_show_region == func))
6310 if (sd->on_show_region_data && sd->on_show_region_data_free)
6311 sd->on_show_region_data_free(sd->on_show_region_data);
6313 sd->on_show_region = func;
6314 sd->on_show_region_data = data;
6315 sd->on_show_region_data_free = func_free_cb;
6319 elm_widget_show_region_set(Eo *obj, Eina_Rect sr, Eina_Bool forceshow)
6321 Evas_Object *parent_obj, *child_obj;
6322 Evas_Coord px, py, cx, cy, nx = 0, ny = 0;
6324 ELM_WIDGET_DATA_GET_OR_RETURN(obj, sd);
6326 /*****************************************************************************
6327 * TIZEN_ONLY_FEATURE: Fix entry size/cursor/region calculation for Tizen UX *
6328 *****************************************************************************
6329 * Move this code to the below to update show region geometry properly.
6330 evas_smart_objects_calculate(evas_object_evas_get(obj));
6336 if (!forceshow && eina_rectangle_equal(&sr.rect, &sd->show_region.rect)) return;
6338 sd->show_region = sr;
6340 /*****************************************************************************
6341 * TIZEN_ONLY_FEATURE: Fix entry size/cursor/region calculation for Tizen UX *
6342 *****************************************************************************/
6343 /* Block nested call for evas_smart_objects_calculate() and region showing works */
6344 if (sd->on_show_region_set) return;
6346 sd->on_show_region_set = EINA_TRUE;
6348 evas_smart_objects_calculate(evas_object_evas_get(obj));
6350 sd->on_show_region_set = EINA_FALSE;
6352 /* show_region geometry could be changed during processing elm_widget_show_region_set().
6353 evas_smart_objects_calculate() can trigger nested show_region_set calls */
6354 sr = sd->show_region;
6359 if (sd->on_show_region)
6361 sd->on_show_region(sd->on_show_region_data, obj, sr);
6363 if (_elm_scrollable_is(obj))
6365 if (elm_widget_is_legacy(obj))
6367 elm_interface_scrollable_content_pos_get(obj, &nx, &ny);
6373 Eina_Position2D pos;
6374 pos = efl_ui_scrollable_content_pos_get(obj);
6383 parent_obj = sd->parent_obj;
6384 if ((!parent_obj)) break;
6385 sd = efl_data_scope_get(parent_obj, MY_CLASS);
6388 evas_object_geometry_get(parent_obj, &px, &py, NULL, NULL);
6389 evas_object_geometry_get(child_obj, &cx, &cy, NULL, NULL);
6393 sd->show_region = sr;
6395 if (sd->on_show_region)
6396 sd->on_show_region(sd->on_show_region_data, parent_obj, sr);
6397 child_obj = parent_obj;
6403 elm_widget_show_region_get(const Eo *obj)
6405 ELM_WIDGET_DATA_GET_OR_RETURN(obj, sd, EINA_RECT_EMPTY());
6406 return (Eina_Rect) sd->show_region;
6408 /* elm_object_content_xxx APIs are supposed to work on all objects for which
6409 * elm_object_widget_check() returns true. The below checks avoid printing out
6410 * undesired ERR messages. */
6412 elm_widget_content_part_set(Evas_Object *obj, const char *part, Evas_Object *content)
6414 ELM_WIDGET_CHECK(obj);
6415 if (efl_isa(obj, EFL_UI_LAYOUT_BASE_CLASS))
6417 elm_layout_content_set(obj, part, content);
6420 if (!efl_isa(obj, EFL_PART_INTERFACE)) return;
6423 part = efl_ui_widget_default_content_part_get(obj);
6426 efl_content_set(efl_part(obj, part), content);
6430 elm_widget_content_part_get(const Evas_Object *obj, const char *part)
6432 ELM_WIDGET_CHECK(obj) NULL;
6433 if (efl_isa(obj, EFL_UI_LAYOUT_BASE_CLASS))
6434 return elm_layout_content_get(obj, part);
6435 if (!efl_isa(obj, EFL_PART_INTERFACE)) return NULL;
6438 part = efl_ui_widget_default_content_part_get(obj);
6439 if (!part) return NULL;
6441 return efl_content_get(efl_part(obj, part));
6445 elm_widget_content_part_unset(Evas_Object *obj, const char *part)
6447 ELM_WIDGET_CHECK(obj) NULL;
6448 if (efl_isa(obj, EFL_UI_LAYOUT_BASE_CLASS))
6449 return elm_layout_content_unset(obj, part);
6450 if (!efl_isa(obj, EFL_PART_INTERFACE)) return NULL;
6453 part = efl_ui_widget_default_content_part_get(obj);
6454 if (!part) return NULL;
6456 return efl_content_unset(efl_part(obj, part));
6460 elm_widget_signal_emit(Eo *obj, const char *emission, const char *source)
6462 ELM_WIDGET_CHECK(obj);
6464 if (efl_isa(obj, EFL_UI_LAYOUT_BASE_CLASS))
6465 elm_layout_signal_emit(obj, emission, source);
6466 else if (evas_object_smart_type_check(obj, "elm_icon"))
6468 WRN("Deprecated function. This functionality on icon objects"
6469 " will be dropped on a next release.");
6470 _elm_icon_signal_emit(obj, emission, source);
6475 elm_widget_signal_callback_add(Eo *obj, const char *emission, const char *source, Edje_Signal_Cb func, void *data)
6477 ELM_WIDGET_CHECK(obj);
6478 EINA_SAFETY_ON_NULL_RETURN(func);
6479 if (evas_object_smart_type_check(obj, "elm_layout"))
6480 elm_layout_signal_callback_add(obj, emission, source, func, data);
6481 else if (evas_object_smart_type_check(obj, "elm_icon"))
6483 WRN("Deprecated function. This functionality on icon objects"
6484 " will be dropped on a next release.");
6486 _elm_icon_signal_callback_add(obj, emission, source, func, data);
6491 elm_widget_signal_callback_del(Eo *obj, const char *emission, const char *source, Edje_Signal_Cb func)
6495 ELM_WIDGET_CHECK(obj) NULL;
6496 EINA_SAFETY_ON_NULL_RETURN_VAL(func, NULL);
6497 if (evas_object_smart_type_check(obj, "elm_layout"))
6498 data = elm_layout_signal_callback_del(obj, emission, source, func);
6499 else if (evas_object_smart_type_check(obj, "elm_icon"))
6501 WRN("Deprecated function. This functionality on icon objects"
6502 " will be dropped on a next release.");
6504 data = _elm_icon_signal_callback_del(obj, emission, source, func);
6511 /* Widget Shadow Begin */
6513 typedef struct _Widget_Shadow
6518 double rx, ry, ox, oy, grow;
6521 Eina_Stringshare *code, *name;
6524 static void _widget_shadow_update(Widget_Shadow *shadow);
6527 _widget_shadow_del_cb(void *data, const Efl_Event *ev EINA_UNUSED)
6529 Widget_Shadow *shadow = data;
6531 efl_del(shadow->surface);
6536 _widget_shadow_event_cb(void *data, const Efl_Event *ev EINA_UNUSED)
6538 Widget_Shadow *shadow = data;
6539 _widget_shadow_update(shadow);
6542 EFL_CALLBACKS_ARRAY_DEFINE(widget_shadow_cb,
6543 { EFL_EVENT_DEL, _widget_shadow_del_cb },
6544 { EFL_GFX_ENTITY_EVENT_POSITION_CHANGED, _widget_shadow_event_cb },
6545 { EFL_GFX_ENTITY_EVENT_SIZE_CHANGED, _widget_shadow_event_cb },
6546 { EFL_GFX_ENTITY_EVENT_STACKING_CHANGED, _widget_shadow_event_cb },
6547 { EFL_GFX_ENTITY_EVENT_VISIBILITY_CHANGED, _widget_shadow_event_cb });
6549 static Widget_Shadow *
6550 _widget_shadow_part_get(const Eo *part_obj)
6552 Elm_Part_Data *pd = efl_data_scope_get(part_obj, EFL_UI_WIDGET_PART_CLASS);
6553 Widget_Shadow *shadow;
6554 Eo *widget = pd->obj;
6556 shadow = efl_key_data_get(widget, "__elm_shadow");
6559 shadow = calloc(1, sizeof(*shadow));
6560 if (!shadow) return NULL;
6561 shadow->widget = pd->obj;
6562 efl_key_data_set(widget, "__elm_shadow", shadow);
6563 efl_event_callback_array_add(widget, widget_shadow_cb(), shadow);
6569 _widget_shadow_update(Widget_Shadow *ws)
6571 int l = 0, r = 0, t = 0, b = 0;
6572 Eina_Rect srect, wrect;
6575 #define FILTER_FMT \
6576 "a = buffer { 'alpha' }" \
6577 "grow { %f, dst = a, alphaonly = true }" \
6578 "blur { src = a, rx = %f, ry = %f, color = color(%d,%d,%d,%d) }"
6582 ws->surface = efl_add(EFL_CANVAS_PROXY_CLASS, ws->widget);
6583 efl_gfx_fill_auto_set(ws->surface, 1);
6584 efl_canvas_proxy_source_clip_set(ws->surface, EINA_FALSE);
6585 efl_canvas_proxy_source_events_set(ws->surface, EINA_FALSE);
6586 efl_canvas_proxy_source_set(ws->surface, ws->widget);
6591 snprintf(filter, sizeof(filter), FILTER_FMT,
6592 ws->props.grow, ws->props.rx, ws->props.ry,
6593 ws->props.r, ws->props.g, ws->props.b, ws->props.a);
6596 efl_gfx_filter_program_set(ws->surface,
6597 ws->code ? ws->code : filter,
6598 ws->name ? ws->name : "shadow");
6599 efl_gfx_filter_padding_get(ws->surface, &l, &r, &t, &b);
6601 wrect = efl_gfx_entity_geometry_get(ws->widget);
6602 srect.x = wrect.x + (int) (-l + ws->props.ox);
6603 srect.y = wrect.y + (int) (-t + ws->props.oy);
6604 srect.w = wrect.w + (int) (l + r);
6605 srect.h = wrect.h + (int) (t + b);
6607 if ((!ws->props.a && !ws->code) ||
6608 !efl_gfx_entity_visible_get(ws->widget))
6610 efl_gfx_entity_visible_set(ws->surface, EINA_FALSE);
6614 efl_canvas_object_clipper_set(ws->surface, efl_canvas_object_clipper_get(ws->widget));
6615 efl_canvas_group_member_add(efl_canvas_object_render_parent_get(ws->widget), ws->surface);
6616 efl_gfx_entity_geometry_set(ws->surface, srect);
6617 efl_gfx_stack_below(ws->surface, ws->widget);
6618 efl_gfx_entity_visible_set(ws->surface, EINA_TRUE);
6622 _elm_widget_shadow_update(Efl_Ui_Widget *obj)
6624 Widget_Shadow *shadow = _widget_shadow_part_get(obj);
6625 _widget_shadow_update(shadow);
6629 _efl_ui_widget_part_shadow_efl_gfx_blur_offset_set(Eo *obj, void *_pd EINA_UNUSED, double ox, double oy)
6631 Widget_Shadow *shadow = _widget_shadow_part_get(obj);
6632 shadow->props.ox = ox;
6633 shadow->props.oy = oy;
6634 _widget_shadow_update(shadow);
6638 _efl_ui_widget_part_shadow_efl_gfx_blur_offset_get(const Eo *obj, void *_pd EINA_UNUSED, double *ox, double *oy)
6640 Widget_Shadow *shadow = _widget_shadow_part_get(obj);
6641 if (ox) *ox = shadow->props.ox;
6642 if (oy) *oy = shadow->props.oy;
6646 _efl_ui_widget_part_shadow_efl_gfx_blur_radius_set(Eo *obj, void *_pd EINA_UNUSED, double rx, double ry)
6648 Widget_Shadow *shadow = _widget_shadow_part_get(obj);
6649 shadow->props.rx = rx;
6650 shadow->props.ry = ry;
6651 _widget_shadow_update(shadow);
6655 _efl_ui_widget_part_shadow_efl_gfx_blur_radius_get(const Eo *obj, void *_pd EINA_UNUSED, double *rx, double *ry)
6657 Widget_Shadow *shadow = _widget_shadow_part_get(obj);
6658 if (rx) *rx = shadow->props.rx;
6659 if (ry) *ry = shadow->props.ry;
6663 _efl_ui_widget_part_shadow_efl_gfx_color_color_set(Eo *obj, void *_pd EINA_UNUSED, int r, int g, int b, int a)
6665 Widget_Shadow *shadow = _widget_shadow_part_get(obj);
6666 shadow->props.r = r;
6667 shadow->props.g = g;
6668 shadow->props.b = b;
6669 shadow->props.a = a;
6670 _widget_shadow_update(shadow);
6674 _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)
6676 Widget_Shadow *shadow = _widget_shadow_part_get(obj);
6677 if (r) *r = shadow->props.r;
6678 if (g) *g = shadow->props.g;
6679 if (b) *b = shadow->props.b;
6680 if (a) *a = shadow->props.a;
6684 _efl_ui_widget_part_shadow_efl_gfx_blur_grow_set(Eo *obj, void *_pd EINA_UNUSED, double radius)
6686 Widget_Shadow *shadow = _widget_shadow_part_get(obj);
6687 shadow->props.grow = radius;
6688 _widget_shadow_update(shadow);
6691 EOLIAN static double
6692 _efl_ui_widget_part_shadow_efl_gfx_blur_grow_get(const Eo *obj, void *_pd EINA_UNUSED)
6694 Widget_Shadow *shadow = _widget_shadow_part_get(obj);
6695 return shadow->props.grow;
6699 _efl_ui_widget_part_shadow_efl_gfx_filter_filter_program_set(Eo *obj, void *_pd EINA_UNUSED, const char *code, const char *name)
6701 Widget_Shadow *ws = _widget_shadow_part_get(obj);
6702 eina_stringshare_replace(&ws->code, code);
6703 eina_stringshare_replace(&ws->name, name);
6704 _widget_shadow_update(ws);
6708 _efl_ui_widget_part_shadow_efl_gfx_filter_filter_program_get(const Eo *obj, void *_pd EINA_UNUSED, const char **code, const char **name)
6710 Widget_Shadow *ws = _widget_shadow_part_get(obj);
6711 efl_gfx_filter_program_get(ws->surface, code, name);
6715 _efl_ui_widget_part_shadow_efl_gfx_filter_filter_source_set(Eo *obj, void *_pd EINA_UNUSED, const char *name, Efl_Gfx_Entity *source)
6717 Widget_Shadow *ws = _widget_shadow_part_get(obj);
6718 _widget_shadow_update(ws);
6719 efl_gfx_filter_source_set(ws->surface, name, source);
6722 EOLIAN static Efl_Gfx_Entity *
6723 _efl_ui_widget_part_shadow_efl_gfx_filter_filter_source_get(const Eo *obj, void *_pd EINA_UNUSED, const char *name)
6725 Widget_Shadow *ws = _widget_shadow_part_get(obj);
6726 return efl_gfx_filter_source_get(ws->surface, name);
6730 _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)
6732 Widget_Shadow *ws = _widget_shadow_part_get(obj);
6733 _widget_shadow_update(ws);
6734 efl_gfx_filter_data_set(ws->surface, name, value, execute);
6738 _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)
6740 Widget_Shadow *ws = _widget_shadow_part_get(obj);
6741 efl_gfx_filter_data_get(ws->surface, name, value, execute);
6745 _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)
6747 Widget_Shadow *ws = _widget_shadow_part_get(obj);
6748 efl_gfx_filter_padding_get(ws->surface, l, r, t, b);
6752 _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)
6754 Widget_Shadow *ws = _widget_shadow_part_get(obj);
6755 efl_gfx_filter_state_set(ws->surface, cur_state, cur_val, next_state, next_val, pos);
6759 _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)
6761 Widget_Shadow *ws = _widget_shadow_part_get(obj);
6762 efl_gfx_filter_state_get(ws->surface, cur_state, cur_val, next_state, next_val, pos);
6765 #include "efl_ui_widget_part_shadow.eo.c"
6767 /* Widget Shadow End */
6770 /* Efl.Part implementation */
6772 EOLIAN static Efl_Object *
6773 _efl_ui_widget_efl_part_part_get(const Eo *obj, Elm_Widget_Smart_Data *wd EINA_UNUSED, const char *part)
6775 if (eina_streq(part, "background"))
6776 return ELM_PART_IMPLEMENT(EFL_UI_WIDGET_PART_BG_CLASS, obj, part);
6777 else if (eina_streq(part, "shadow"))
6778 return ELM_PART_IMPLEMENT(EFL_UI_WIDGET_PART_SHADOW_CLASS, obj, part);
6779 return ELM_PART_IMPLEMENT(EFL_UI_WIDGET_PART_CLASS, obj, part);
6782 EOLIAN static void \
6783 _efl_ui_widget_part_efl_object_destructor(Eo *obj, Elm_Part_Data *pd)
6786 eina_tmpstr_del(pd->part);
6787 efl_destructor(efl_super(obj, EFL_UI_WIDGET_PART_CLASS));
6790 static Efl_Canvas_Layout_Part_Type
6791 _efl_ui_widget_part_efl_canvas_layout_part_type_provider_part_type_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, EFL_CANVAS_LAYOUT_PART_TYPE_NONE);
6795 return efl_canvas_layout_part_type_get(efl_part(sd->resize_obj, pd->part));
6799 _efl_ui_widget_part_efl_gfx_entity_geometry_get(const Eo *obj EINA_UNUSED, Elm_Part_Data *pd)
6801 Elm_Widget_Smart_Data *sd = efl_data_scope_safe_get(pd->obj, MY_CLASS);
6802 EINA_SAFETY_ON_NULL_RETURN_VAL(sd, EINA_RECT_EMPTY());
6803 return efl_gfx_entity_geometry_get(efl_part(sd->resize_obj, pd->part));
6807 _efl_ui_widget_part_efl_ui_property_bind_property_bind(Eo *obj, Elm_Part_Data *ppd,
6808 const char *key, const char *property)
6810 Efl_Ui_Widget_Data *pd;
6813 widget = efl_parent_get(obj);
6814 pd = efl_data_scope_get(widget, EFL_UI_WIDGET_CLASS);
6816 return _efl_ui_property_bind(widget, obj, pd, ppd->part, key, property);
6819 #include "efl_ui_widget_part.eo.c"
6823 /* Efl.Part Bg implementation */
6826 _efl_ui_widget_bg_get(const Efl_Ui_Widget *obj)
6828 Elm_Widget_Smart_Data *sd = efl_data_scope_get(obj, MY_CLASS);
6829 Evas_Object *bg_obj = sd->bg;
6833 bg_obj = efl_add(EFL_UI_BG_CLASS, (Eo *)obj);
6834 EINA_SAFETY_ON_NULL_RETURN_VAL(bg_obj, NULL);
6836 efl_canvas_group_member_add((Eo *)obj, sd->bg);
6837 evas_object_stack_below(sd->bg, sd->resize_obj);
6838 _smart_reconfigure((Eo*)obj, sd);
6844 static inline Efl_Canvas_Object *
6845 efl_ui_widget_part_bg_get(const Eo *part_obj)
6847 Elm_Part_Data *pd = efl_data_scope_get(part_obj, EFL_UI_WIDGET_PART_CLASS);
6848 return _efl_ui_widget_bg_get(pd->obj);
6851 EOLIAN static Eina_Error
6852 _efl_ui_widget_part_bg_efl_file_load(Eo *obj, void *pd EINA_UNUSED)
6854 Evas_Object *bg_obj = efl_ui_widget_part_bg_get(obj);
6856 return efl_file_load(bg_obj);
6860 _efl_ui_widget_part_bg_efl_file_unload(Eo *obj, void *pd EINA_UNUSED)
6862 Evas_Object *bg_obj = efl_ui_widget_part_bg_get(obj);
6864 efl_file_unload(bg_obj);
6867 EOLIAN static const char *
6868 _efl_ui_widget_part_bg_efl_file_file_get(const Eo *obj, void *pd EINA_UNUSED)
6870 Evas_Object *bg_obj = efl_ui_widget_part_bg_get(obj);
6872 return efl_file_get(bg_obj);
6875 EOLIAN static Eina_Error
6876 _efl_ui_widget_part_bg_efl_file_file_set(Eo *obj, void *pd EINA_UNUSED, const char *file)
6878 Evas_Object *bg_obj = efl_ui_widget_part_bg_get(obj);
6880 return efl_file_set(bg_obj, file);
6883 EOLIAN static const char *
6884 _efl_ui_widget_part_bg_efl_file_key_get(const Eo *obj, void *pd EINA_UNUSED)
6886 Evas_Object *bg_obj = efl_ui_widget_part_bg_get(obj);
6888 return efl_file_key_get(bg_obj);
6892 _efl_ui_widget_part_bg_efl_file_key_set(Eo *obj, void *pd EINA_UNUSED, const char *key)
6894 Evas_Object *bg_obj = efl_ui_widget_part_bg_get(obj);
6896 efl_file_key_set(bg_obj, key);
6899 EOLIAN static const Eina_File *
6900 _efl_ui_widget_part_bg_efl_file_mmap_get(const Eo *obj, void *pd EINA_UNUSED)
6902 Evas_Object *bg_obj = efl_ui_widget_part_bg_get(obj);
6904 return efl_file_mmap_get(bg_obj);
6907 EOLIAN static Eina_Error
6908 _efl_ui_widget_part_bg_efl_file_mmap_set(Eo *obj, void *pd EINA_UNUSED, const Eina_File *file)
6910 Evas_Object *bg_obj = efl_ui_widget_part_bg_get(obj);
6912 return efl_file_mmap_set(bg_obj, file);
6916 _efl_ui_widget_part_bg_efl_gfx_color_color_set(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_set(bg_obj, r, g, b, a);
6924 _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)
6926 Evas_Object *bg_obj = efl_ui_widget_part_bg_get(obj);
6928 efl_gfx_color_get(bg_obj, r, g, b, a);
6931 EOLIAN static Efl_Object*
6932 _efl_ui_widget_part_bg_efl_object_finalize(Eo *obj, void *pd EINA_UNUSED)
6934 Evas_Object *bg_obj = efl_ui_widget_part_bg_get(obj);
6936 efl_composite_attach(obj, bg_obj);
6938 return efl_finalize(efl_super(obj, EFL_UI_WIDGET_PART_BG_CLASS));
6942 typedef struct _Efl_Ui_Property_Bound Efl_Ui_Property_Bound;
6943 struct _Efl_Ui_Property_Bound
6945 Eina_Stringshare *part; // Optional part to apply the property on
6946 Eina_Stringshare *key; // Local object property
6947 Eina_Stringshare *property; // Model property
6952 _efl_ui_property_bind_free(void *data)
6954 Efl_Ui_Property_Bound *prop = data;
6956 eina_stringshare_del(prop->part);
6957 eina_stringshare_del(prop->key);
6958 eina_stringshare_del(prop->property);
6963 _efl_ui_property_bind_clean(Eo *obj EINA_UNUSED,
6965 const Eina_Future *f EINA_UNUSED)
6967 Efl_Ui_Property_Bound *prop = data;
6973 _efl_ui_property_bind_get(Eo *obj, Efl_Ui_Widget_Data *pd, Efl_Ui_Property_Bound *prop)
6980 // If there is no model set yet, no need to try anything
6981 if (!pd->properties.model) return ;
6983 value = efl_model_property_get(pd->properties.model, prop->property);
6984 target = prop->part ? efl_part(obj, prop->part) : obj;
6986 err = efl_property_reflection_set(target, prop->key, eina_value_reference_copy(value));
6987 eina_value_free(value);
6991 // Report back the error to the model
6992 if (prop->f) eina_future_cancel(prop->f);
6993 f = efl_model_property_set(pd->properties.model, prop->property,
6994 eina_value_error_new(err));
6995 prop->f = efl_future_then(obj, f, .free = _efl_ui_property_bind_clean, .data = prop);
6999 _efl_ui_property_bind_set(Eo *obj, Efl_Ui_Widget_Data *pd, Efl_Ui_Property_Bound *prop)
7005 target = prop->part ? efl_part(obj, prop->part) : obj;
7006 value = efl_property_reflection_get(target, prop->key);
7008 if (prop->f) eina_future_cancel(prop->f);
7009 f = efl_model_property_set(pd->properties.model, prop->property, eina_value_dup(&value));
7010 prop->f = efl_future_then(obj, f, .free = _efl_ui_property_bind_clean, .data = prop);
7011 eina_value_flush(&value);
7015 _efl_ui_model_property_bind_changed(void *data, const Efl_Event *event)
7017 Efl_Model_Property_Event *evt = event->info;
7018 ELM_WIDGET_DATA_GET(data, pd);
7019 Eina_Array_Iterator it;
7024 EINA_ARRAY_ITER_NEXT(evt->changed_properties, i, prop, it)
7026 Efl_Ui_Property_Bound *lookup;
7028 lookup = eina_hash_find(pd->properties.model_lookup, prop);
7029 if (lookup) _efl_ui_property_bind_get(data, pd, lookup);
7034 _efl_ui_view_property_bind_changed(void *data, const Efl_Event *event)
7036 Efl_Ui_Property_Event *evt = event->info;
7037 ELM_WIDGET_DATA_GET(data, pd);
7038 Eina_Array_Iterator it;
7039 Eina_Stringshare *prop;
7043 EINA_ARRAY_ITER_NEXT(evt->changed_properties, i, prop, it)
7045 Efl_Ui_Property_Bound *lookup;
7047 lookup = eina_hash_find(pd->properties.view_lookup, prop);
7048 if (lookup) _efl_ui_property_bind_set(data, pd, lookup);
7053 _efl_ui_widget_model_update(Eo *obj, Efl_Ui_Widget_Data *pd)
7055 Efl_Ui_Property_Bound *property;
7058 it = eina_hash_iterator_data_new(pd->properties.model_lookup);
7059 EINA_ITERATOR_FOREACH(it, property)
7060 _efl_ui_property_bind_get(obj, pd, property);
7061 eina_iterator_free(it);
7064 static void _efl_ui_widget_model_provider_model_change(void *data, const Efl_Event *event EINA_UNUSED);
7065 static void _efl_ui_widget_model_provider_invalidate(void *data, const Efl_Event *event EINA_UNUSED);
7067 EFL_CALLBACKS_ARRAY_DEFINE(efl_ui_widget_model_provider_callbacks,
7068 { EFL_EVENT_INVALIDATE, _efl_ui_widget_model_provider_invalidate },
7069 { EFL_UI_VIEW_EVENT_MODEL_CHANGED, _efl_ui_widget_model_provider_model_change });
7072 _efl_ui_widget_model_provider_model_change(void *data, const Efl_Event *event)
7074 ELM_WIDGET_DATA_GET(data, pd);
7077 efl_replace(&pd->properties.model,
7078 efl_ui_view_model_get(pd->properties.provider));
7079 _efl_ui_widget_model_update(data, pd);
7081 efl_event_callback_call(data, EFL_UI_VIEW_EVENT_MODEL_CHANGED, event->info);
7085 _efl_ui_widget_model_provider_invalidate(void *data, const Efl_Event *event EINA_UNUSED)
7087 ELM_WIDGET_DATA_GET(data, pd);
7090 efl_event_callback_array_del(pd->properties.provider,
7091 efl_ui_widget_model_provider_callbacks(),
7093 efl_replace(&pd->properties.provider, NULL);
7094 efl_replace(&pd->properties.model, NULL);
7095 pd->properties.callback_to_provider = EINA_FALSE;
7099 _efl_ui_widget_model_register(Eo *obj, Efl_Ui_Widget_Data *pd)
7101 if (pd->properties.registered) return ;
7103 if (!pd->properties.model)
7105 Efl_Model_Changed_Event ev;
7107 efl_replace(&pd->properties.provider,
7108 efl_provider_find(obj, EFL_MODEL_PROVIDER_CLASS));
7109 if (!pd->properties.provider) return ;
7110 if (!pd->properties.callback_to_provider)
7111 efl_event_callback_array_add(pd->properties.provider,
7112 efl_ui_widget_model_provider_callbacks(),
7114 pd->properties.callback_to_provider = EINA_TRUE;
7115 efl_replace(&pd->properties.model,
7116 efl_ui_view_model_get(pd->properties.provider));
7118 if (!pd->properties.model) return ;
7120 ev.current = pd->properties.model;
7122 efl_event_callback_call(obj, EFL_UI_VIEW_EVENT_MODEL_CHANGED, &ev);
7125 if (!pd->properties.model) return ;
7126 if (!pd->properties.model_lookup) return ;
7128 efl_event_callback_add(pd->properties.model, EFL_MODEL_EVENT_PROPERTIES_CHANGED,
7129 _efl_ui_model_property_bind_changed, obj);
7130 efl_event_callback_add(obj, EFL_UI_PROPERTY_BIND_EVENT_PROPERTIES_CHANGED,
7131 _efl_ui_view_property_bind_changed, obj);
7132 pd->properties.registered = EINA_TRUE;
7136 _efl_ui_widget_model_unregister(Eo *obj, Efl_Ui_Widget_Data *pd)
7138 if (pd->properties.registered)
7140 // Remove any existing handler that might exist for any reason
7141 efl_event_callback_del(pd->properties.model, EFL_MODEL_EVENT_PROPERTIES_CHANGED,
7142 _efl_ui_model_property_bind_changed, obj);
7143 efl_event_callback_del(obj, EFL_UI_PROPERTY_BIND_EVENT_PROPERTIES_CHANGED,
7144 _efl_ui_view_property_bind_changed, obj);
7146 pd->properties.registered = EINA_FALSE;
7148 // Invalidate must be called before setting a new model and even if no model is registered
7149 if (pd->properties.provider)
7150 _efl_ui_widget_model_provider_invalidate(obj, NULL);
7154 _efl_ui_property_bind(Eo *widget, Eo *target, Efl_Ui_Widget_Data *pd,
7155 const char *part, const char *key, const char *property)
7157 Efl_Ui_Property_Bound *prop;
7159 // Always check for a model and fetch a provider in case a bound property
7160 // is provided by a class down the hierarchy, but they still need to be notified
7161 // when a model change
7162 _efl_ui_widget_model_register(widget, pd);
7164 // Check if the property is available from the reflection table of the object.
7165 if (!efl_property_reflection_exist(target, key)) return EFL_PROPERTY_ERROR_INVALID_KEY;
7167 if (!pd->properties.model_lookup)
7169 pd->properties.model_lookup = eina_hash_stringshared_new(_efl_ui_property_bind_free);
7170 pd->properties.view_lookup = eina_hash_stringshared_new(NULL);
7173 prop = calloc(1, sizeof (Efl_Ui_Property_Bound));
7174 if (!prop) return ENOMEM;
7175 prop->part = eina_stringshare_add(part);
7176 prop->key = eina_stringshare_add(key);
7177 prop->property = eina_stringshare_add(property);
7179 eina_hash_direct_add(pd->properties.model_lookup, prop->property, prop);
7180 eina_hash_direct_add(pd->properties.view_lookup, prop->key, prop);
7182 _efl_ui_property_bind_get(widget, pd, prop);
7184 efl_event_callback_call(widget, EFL_UI_PROPERTY_BIND_EVENT_PROPERTY_BOUND, (void*) prop->key);
7185 // In case of part, we emit it also on the part so that the part too can act on it
7187 efl_event_callback_call(target, EFL_UI_PROPERTY_BIND_EVENT_PROPERTY_BOUND, (void*) prop->key);
7193 _efl_ui_widget_efl_ui_property_bind_property_bind(Eo *obj, Efl_Ui_Widget_Data *pd,
7194 const char *key, const char *property)
7196 return _efl_ui_property_bind(obj, obj, pd, NULL, key, property);
7200 _efl_ui_widget_efl_ui_view_model_set(Eo *obj,
7201 Efl_Ui_Widget_Data *pd,
7204 Efl_Model_Changed_Event ev;
7206 ev.current = efl_ref(model);
7207 ev.previous = efl_ref(pd->properties.model);
7209 _efl_ui_widget_model_unregister(obj, pd);
7211 efl_replace(&pd->properties.model, model);
7213 // Set the properties handler just in case
7214 _efl_ui_widget_model_register(obj, pd);
7216 // In case the model set was NULL, but we did found a model provider
7217 // we shouldn't emit a second event. Otherwise we should.
7218 if (ev.current == pd->properties.model)
7219 efl_event_callback_call(obj, EFL_UI_VIEW_EVENT_MODEL_CHANGED, &ev);
7221 if (pd->properties.model) _efl_ui_widget_model_update(obj, pd);
7223 efl_unref(ev.current);
7224 efl_unref(ev.previous);
7228 _efl_ui_widget_efl_ui_view_model_get(const Eo *obj EINA_UNUSED, Efl_Ui_Widget_Data *pd)
7230 return pd->properties.model;
7234 _efl_ui_widget_efl_object_invalidate(Eo *obj, Efl_Ui_Widget_Data *pd)
7236 efl_invalidate(efl_super(obj, EFL_UI_WIDGET_CLASS));
7238 _efl_ui_widget_model_unregister(obj, pd);
7239 efl_replace(&pd->properties.model, NULL);
7241 if (pd->properties.view_lookup) eina_hash_free(pd->properties.view_lookup);
7242 pd->properties.view_lookup = NULL;
7243 if (pd->properties.model_lookup) eina_hash_free(pd->properties.model_lookup);
7244 pd->properties.model_lookup = NULL;
7247 #include "efl_ui_widget_part_bg.eo.c"
7250 efl_ui_widget_internal_set(Eo *obj, Eina_Bool b)
7252 ELM_WIDGET_DATA_GET(obj, pd);
7253 EINA_SAFETY_ON_NULL_RETURN(pd);
7259 efl_ui_widget_internal_get(Eo *obj)
7261 ELM_WIDGET_DATA_GET(obj, pd);
7262 EINA_SAFETY_ON_NULL_RETURN_VAL(obj, EINA_FALSE);
7264 return pd->internal;
7267 /* Efl.Part Bg end */
7270 /* Internal EO APIs and hidden overrides */
7272 EFL_FUNC_BODY_CONST(efl_ui_widget_default_content_part_get, const char *, NULL)
7273 EFL_FUNC_BODY_CONST(efl_ui_widget_default_text_part_get, const char *, NULL)
7275 ELM_PART_CONTENT_DEFAULT_GET(efl_ui_widget, NULL)
7276 ELM_PART_TEXT_DEFAULT_GET(efl_ui_widget, NULL)
7278 /***********************************************************************************
7279 * TIZEN_ONLY_FEATURE: apply Tizen's color_class features. *
7280 ***********************************************************************************/
7281 /* Internal EO APIs and hidden overrides */
7282 EAPI EFL_FUNC_BODYV(elm_widget_class_color_set, Eina_Bool, EINA_FALSE,
7283 EFL_FUNC_CALL(color_class, r, g, b, a),
7284 const char *color_class, int r, int g, int b, int a)
7285 EAPI EFL_FUNC_BODYV(elm_widget_class_color_get, Eina_Bool, EINA_FALSE,
7286 EFL_FUNC_CALL(color_class, r, g, b, a),
7287 const char *color_class, int *r, int *g, int *b, int *a)
7288 EAPI EFL_FUNC_BODYV(elm_widget_class_color2_set, Eina_Bool, EINA_FALSE,
7289 EFL_FUNC_CALL(color_class, r, g, b, a),
7290 const char *color_class, int r, int g, int b, int a)
7291 EAPI EFL_FUNC_BODYV(elm_widget_class_color2_get, Eina_Bool, EINA_FALSE,
7292 EFL_FUNC_CALL(color_class, r, g, b, a),
7293 const char *color_class, int *r, int *g, int *b, int *a)
7294 EAPI EFL_FUNC_BODYV(elm_widget_class_color3_set, Eina_Bool, EINA_FALSE,
7295 EFL_FUNC_CALL(color_class, r, g, b, a),
7296 const char *color_class, int r, int g, int b, int a)
7297 EAPI EFL_FUNC_BODYV(elm_widget_class_color3_get, Eina_Bool, EINA_FALSE,
7298 EFL_FUNC_CALL(color_class, r, g, b, a),
7299 const char *color_class, int *r, int *g, int *b, int *a)
7300 EAPI EFL_VOID_FUNC_BODYV(elm_widget_class_color_del,
7301 EFL_FUNC_CALL(color_class),
7302 const char *color_class)
7303 EAPI EFL_VOID_FUNC_BODY(elm_widget_class_color_clear)
7305 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);
7306 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);
7307 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);
7308 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);
7309 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);
7310 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);
7311 static void _elm_widget_class_color_del(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd, const char *color_class);
7312 static void _elm_widget_class_color_clear(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd);
7318 #define EFL_UI_WIDGET_EXTRA_OPS \
7319 EFL_CANVAS_GROUP_ADD_DEL_OPS(efl_ui_widget), \
7320 ELM_PART_CONTENT_DEFAULT_OPS(efl_ui_widget), \
7321 ELM_PART_TEXT_DEFAULT_OPS(efl_ui_widget), \
7322 EFL_OBJECT_OP_FUNC(efl_canvas_object_is_frame_object_set, _efl_ui_widget_efl_canvas_object_is_frame_object_set), \
7323 EFL_OBJECT_OP_FUNC(efl_dbg_info_get, _efl_ui_widget_efl_object_dbg_info_get), \
7324 /*********************************************************************************** \
7325 * TIZEN_ONLY_FEATURE: apply Tizen's color_class features. * \
7326 ***********************************************************************************/ \
7327 EFL_OBJECT_OP_FUNC(elm_widget_class_color_set, _elm_widget_class_color_set), \
7328 EFL_OBJECT_OP_FUNC(elm_widget_class_color_get, _elm_widget_class_color_get), \
7329 EFL_OBJECT_OP_FUNC(elm_widget_class_color2_set, _elm_widget_class_color2_set), \
7330 EFL_OBJECT_OP_FUNC(elm_widget_class_color2_get, _elm_widget_class_color2_get), \
7331 EFL_OBJECT_OP_FUNC(elm_widget_class_color3_set, _elm_widget_class_color3_set), \
7332 EFL_OBJECT_OP_FUNC(elm_widget_class_color3_get, _elm_widget_class_color3_get), \
7333 EFL_OBJECT_OP_FUNC(elm_widget_class_color_del, _elm_widget_class_color_del), \
7334 EFL_OBJECT_OP_FUNC(elm_widget_class_color_clear, _elm_widget_class_color_clear)
7340 // TIZEN_ONLY(20150709) : atspi relations api
7341 EOLIAN static Efl_Access_Relation_Set
7342 _efl_ui_widget_efl_access_object_relation_set_get(const Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd)
7344 return efl_access_relation_set_clone(&sd->atspi_custom_relations);
7346 EOLIAN static Eina_Bool
7347 _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)
7349 return efl_access_relation_set_relation_append(&sd->atspi_custom_relations, type, relation_obj);
7353 _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)
7355 efl_access_relation_set_relation_remove(&sd->atspi_custom_relations, type, relation_obj);
7359 _efl_ui_widget_efl_access_object_relationships_clear(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd)
7361 efl_access_relation_set_free(&sd->atspi_custom_relations);
7362 sd->atspi_custom_relations = NULL;
7365 EOLIAN static Elm_Atspi_Relation_Set
7366 _elm_widget_item_efl_access_object_relation_set_get(const Eo *obj EINA_UNUSED, Elm_Widget_Item_Data *sd)
7368 return efl_access_relation_set_clone(&sd->atspi_custom_relations);
7371 EOLIAN static Eina_Bool
7372 _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)
7374 return efl_access_relation_set_relation_append(&sd->atspi_custom_relations, type, relation_obj);
7378 _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)
7380 efl_access_relation_set_relation_remove(&sd->atspi_custom_relations, type, relation_obj);
7384 _elm_widget_item_efl_access_object_relationships_clear(Eo *obj EINA_UNUSED, Elm_Widget_Item_Data *sd)
7386 efl_access_relation_set_free(&sd->atspi_custom_relations);
7387 sd->atspi_custom_relations = NULL;
7389 //////////////////////////////
7391 //TIZEN_ONLY(20160726): add API elm_atspi_accessible_can_highlight_set/get
7393 _children_highlight_check(Eo *obj)
7395 Eina_List *children, *l;
7398 if (_elm_object_accessibility_currently_highlighted_get() == (void *)obj)
7400 efl_access_component_highlight_clear(obj);
7404 children = efl_access_object_access_children_get(obj);
7405 EINA_LIST_FOREACH(children, l, child)
7407 if (_children_highlight_check(child)) return EINA_TRUE;
7414 _efl_ui_widget_efl_access_object_can_highlight_set(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *_pd, Eina_Bool can_highlight)
7416 if (!can_highlight) _children_highlight_check(obj);
7417 _pd->can_highlight = !!can_highlight;
7420 EOLIAN static Eina_Bool
7421 _efl_ui_widget_efl_access_object_can_highlight_get(const Eo *obj, Elm_Widget_Smart_Data *_pd EINA_UNUSED)
7423 return _elm_widget_highlightable(obj);
7427 _elm_widget_item_efl_access_object_can_highlight_set(Eo *obj EINA_UNUSED, Elm_Widget_Item_Data *_pd, Eina_Bool can_highlight)
7429 if (!can_highlight) _children_highlight_check(obj);
7430 _pd->can_highlight = !!can_highlight;
7433 EOLIAN static Eina_Bool
7434 _elm_widget_item_efl_access_object_can_highlight_get(const Eo *obj, Elm_Widget_Item_Data *_pd EINA_UNUSED)
7436 return _elm_widget_item_highlightable((Eo *)obj);
7440 // TIZEN_ONLY(20150705): Genlist item align feature
7442 elm_widget_scroll_item_align_enabled_set(Evas_Object *obj,
7443 Eina_Bool scroll_item_align_enable)
7446 if (sd->scroll_item_align_enable == scroll_item_align_enable) return;
7447 sd->scroll_item_align_enable = scroll_item_align_enable;
7451 elm_widget_scroll_item_align_enabled_get(const Evas_Object *obj)
7453 API_ENTRY return EINA_FALSE;
7454 return sd->scroll_item_align_enable;
7458 //TIZEN_ONLY(20150717) add widget name setter
7460 _efl_ui_widget_efl_access_object_i18n_name_set(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data* _pd EINA_UNUSED, const char *name)
7462 //TIZEN_ONLY(20220826): Remove markup from accessible name
7465 text = _elm_util_mkup_to_text(name); // NULL is OK
7466 eina_stringshare_replace(&_pd->name, text);
7472 //TIZEN_ONLY(20161111) add widget/widget_item description get/set
7474 _efl_ui_widget_efl_access_object_description_set(Eo *obj EINA_UNUSED, Efl_Ui_Widget_Data* _pd, const char *description)
7476 if (_pd->description)
7477 eina_stringshare_del(_pd->description);
7479 _pd->description = eina_stringshare_add(description);
7482 EOLIAN static const char*
7483 _efl_ui_widget_efl_access_object_description_get(const Eo *obj EINA_UNUSED, Efl_Ui_Widget_Data *_pd EINA_UNUSED)
7485 const char *ret = NULL;
7486 ret = efl_access_object_description_get(efl_super(obj, EFL_UI_WIDGET_CLASS));
7487 if (ret) return ret;
7490 if (_pd->atspi_translation_domain)
7491 return dgettext(_pd->atspi_translation_domain, _pd->description);
7493 return _pd->description;
7497 //TIZEN_ONLY(20171108): make atspi_proxy work
7499 _proxy_widget_move_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
7504 evas_object_geometry_get(obj, &x, &y, NULL, NULL);
7505 elm_atspi_bridge_utils_proxy_offset_set(proxy, x, y);
7509 _on_widget_del(void *data, const Efl_Event *event)
7512 evas_object_event_callback_del_full(event->object, EVAS_CALLBACK_MOVE,
7513 _proxy_widget_move_cb, plug);
7514 efl_access_object_attribute_del(event->object, "child_bus");
7519 _on_proxy_connected_cb(void *data, const Efl_Event *event)
7522 Evas_Object *widget = data;
7524 evas_object_geometry_get(widget, &x, &y, NULL, NULL);
7525 elm_atspi_bridge_utils_proxy_offset_set(event->object, x, y);
7527 evas_object_event_callback_add(widget, EVAS_CALLBACK_MOVE, _proxy_widget_move_cb, event->object);
7531 //TIZEN_ONLY(20161111) add widget/widget_item description get/set
7533 _elm_widget_item_efl_access_object_description_set(Eo *obj EINA_UNUSED, Elm_Widget_Item_Data* _pd EINA_UNUSED, const char *description)
7535 if (_pd->description)
7536 eina_stringshare_del(_pd->description);
7538 _pd->description = eina_stringshare_add(description);
7542 _elm_widget_item_efl_access_object_description_get(const Eo *obj EINA_UNUSED, Elm_Widget_Item_Data *_pd EINA_UNUSED)
7544 const char *ret = NULL;
7545 ret = efl_access_object_description_get(efl_super(obj, ELM_WIDGET_ITEM_CLASS));
7546 if (ret) return ret;
7549 if (_pd->atspi_translation_domain)
7550 return dgettext(_pd->atspi_translation_domain, _pd->description);
7552 return _pd->description;
7556 //TIZEN_ONLY(20150713) : add atspi name setter to widget_item
7558 _elm_widget_item_efl_access_object_i18n_name_set(Eo *obj EINA_UNUSED, Elm_Widget_Item_Data* _pd EINA_UNUSED, const char *name)
7560 //TIZEN_ONLY(20220826): Remove markup from accessible name
7563 text = _elm_util_mkup_to_text(name); // NULL is OK
7564 eina_stringshare_replace(&_pd->name, text);
7570 _elm_widget_item_efl_access_object_i18n_name_get(const Eo *obj EINA_UNUSED, Elm_Widget_Item_Data *_pd EINA_UNUSED)
7572 //TIZEN_ONLY(20190922): add name callback, description callback.
7573 const char *ret = NULL;
7574 ret = efl_access_object_i18n_name_get(efl_super(obj, ELM_WIDGET_ITEM_CLASS));
7575 if (ret) return ret;
7581 if (_pd->atspi_translation_domain)
7582 return dgettext(_pd->atspi_translation_domain, _pd->name);
7591 //TIZEN_ONLY(20150731) : add i18n support for name and description
7593 _efl_ui_widget_efl_access_object_translation_domain_set(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *_pd, const char *domain)
7595 eina_stringshare_replace(&_pd->atspi_translation_domain, domain);
7598 EOLIAN static const char*
7599 _efl_ui_widget_efl_access_object_translation_domain_get(const Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *_pd)
7601 return _pd->atspi_translation_domain;
7605 _elm_widget_item_efl_access_object_translation_domain_set(Eo *obj EINA_UNUSED, Elm_Widget_Item_Data *_pd, const char *domain)
7607 eina_stringshare_replace(&_pd->atspi_translation_domain, domain);
7610 EOLIAN static const char*
7611 _elm_widget_item_efl_access_object_translation_domain_get(const Eo *obj EINA_UNUSED, Elm_Widget_Item_Data *_pd)
7613 return _pd->atspi_translation_domain;
7617 static int _sort_vertically(const void *data1, const void *data2)
7620 evas_object_geometry_get(data1, NULL, &y1, NULL, NULL);
7621 evas_object_geometry_get(data2, NULL, &y2, NULL, NULL);
7623 return y1 < y2 ? -1 : 1;
7626 static int _sort_horizontally(const void *data1, const void *data2)
7629 evas_object_geometry_get(data1, &x1, NULL, NULL, NULL);
7630 evas_object_geometry_get(data2, &x2, NULL, NULL, NULL);
7632 return x1 < x2 ? -1 : 1;
7635 static Eina_List *_lines_split(Eina_List *children)
7638 Eina_List *lines, *line, *l;
7639 Evas_Coord yl, y, hl, h;
7640 lines = line = NULL;
7642 if (!children) return NULL;
7644 EINA_LIST_FOREACH(children, l, c)
7646 evas_object_geometry_get(c, NULL, &yl, NULL, &hl);
7648 /* remove child if its height == 0 */
7652 EINA_LIST_FREE(children, c)
7654 evas_object_geometry_get(c, NULL, &y, NULL, &h);
7656 /* remove child if its height == 0 */
7657 if (h == 0) continue;
7659 if ((yl + (int)(0.25 * hl)) >= y)
7662 line = eina_list_append(line,c);
7666 // finish current line & start new
7667 lines = eina_list_append(lines, line);
7669 line = eina_list_append(NULL, c);
7673 return eina_list_append(lines, line);
7677 //TIZEN_ONLY(20170621) handle atspi proxy connection at runtime
7679 plug_type_proxy_get(const Eo *obj, Evas_Object *widget)
7682 const char *plug_id;
7683 char *svcname, *svcnum;
7685 if ((plug_id = evas_object_data_get(widget, "___PLUGID")) != NULL)
7687 // TIZEN_ONLY(20160930) : endless recursion fix
7688 efl_access_object_attribute_append(efl_super(obj, MY_CLASS), "___PlugID", plug_id);
7689 efl_access_object_role_set((Eo *)obj, EFL_ACCESS_ROLE_EMBEDDED);
7691 proxy = evas_object_data_get(widget, "__widget_proxy");
7692 // TIZEN_ONLY(20171109) : fix for invalid proxy object, when at-spi has been restarted
7695 if (!evas_object_data_get(proxy, "__proxy_invalid")) return proxy;
7696 evas_object_data_del(widget, "__widget_proxy");
7700 if (_elm_atspi_bridge_plug_id_split(plug_id, &svcname, &svcnum))
7702 proxy = _elm_atspi_bridge_utils_proxy_create((Eo *)obj, svcname, atoi(svcnum), ELM_ATSPI_PROXY_TYPE_PLUG);
7703 evas_object_data_set(widget, "__widget_proxy", proxy);
7704 efl_event_callback_add(widget, EFL_EVENT_DEL, _on_widget_del, proxy);
7705 efl_event_callback_add(proxy, ELM_ATSPI_PROXY_EVENT_CONNECTED, _on_proxy_connected_cb, widget);
7706 elm_atspi_bridge_utils_proxy_connect(proxy);
7716 elm_widget_atspi_plug_type_proxy_get(Evas_Object *obj)
7718 Elm_Widget_Smart_Data *wd;
7719 Evas_Object *widget;
7721 wd = efl_data_scope_get(obj, EFL_UI_WIDGET_CLASS);
7722 if (!wd) return NULL;
7725 for (unsigned int i = 0; i < eina_array_count(wd->children); ++i)
7727 widget = eina_array_data_get(wd->children, i);
7728 proxy = plug_type_proxy_get(obj, widget);
7736 //TIZEN_ONLY(20161107): enhance elm_atspi_accessible_can_highlight_set to set can_hihglight property to its children
7738 _elm_widget_highlightable(const Evas_Object *obj)
7742 Elm_Widget_Smart_Data *wd = efl_data_scope_get(obj, EFL_UI_WIDGET_CLASS);
7743 if (!wd) return EINA_FALSE;
7744 if (!wd->can_highlight) return EINA_FALSE;
7746 parent = efl_provider_find(efl_parent_get(obj), EFL_ACCESS_OBJECT_MIXIN);
7747 while (parent && !efl_isa(parent, ELM_ATSPI_APP_OBJECT_CLASS))
7749 //TIZEN_ONLY(20160929) : atspi: Improves how to find the can_highlight of the widget
7750 if (!_elm_widget_can_highlight_get_by_class(parent)) return EINA_FALSE;
7752 parent = efl_provider_find(efl_parent_get(parent), EFL_ACCESS_OBJECT_MIXIN);
7759 elm_widget_scroll_item_valign_set(Evas_Object *obj,
7760 const char *scroll_item_valign)
7763 if (sd->scroll_item_valign) eina_stringshare_del(sd->scroll_item_valign);
7764 if (!scroll_item_valign) sd->scroll_item_valign = NULL;
7765 else sd->scroll_item_valign = eina_stringshare_add(scroll_item_valign);
7769 elm_widget_scroll_item_valign_get(const Evas_Object *obj)
7771 API_ENTRY return NULL;
7772 return sd->scroll_item_valign;
7776 /* TIZEN_ONLY(20180504): add missing item class names and fix edje_class parse rule for legacy */
7778 _elm_widget_item_legacy_type_get(const Evas_Object *obj)
7783 ret = efl_class_name_get(efl_class_get(obj));
7785 /* If the given widget is created for legacy,
7786 * convert type name to legacy. */
7787 for (i = 0; legacy_type_table[i][0] ; i++)
7789 if (eina_streq(ret, legacy_type_table[i][0]))
7790 return legacy_type_table[i][1];
7798 _efl_ui_widget_focus_disabled_handle(Eo *obj, Elm_Widget_Smart_Data *_pd EINA_UNUSED)
7800 efl_ui_widget_focus_tree_unfocusable_handle(obj);
7803 EOLIAN static unsigned int
7804 _efl_ui_widget_focus_order_get(const Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd)
7806 return sd->focus_order;
7809 EOLIAN static Evas_Object*
7810 _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)
7812 Evas_Object *child, *cur, *best;
7814 if (!evas_object_visible_get(obj)
7815 || (elm_widget_disabled_get(obj))
7816 || (elm_widget_tree_unfocusable_get(obj)))
7820 if (*newest_focus_order < sd->focus_order)
7822 if (!can_focus_only || elm_widget_can_focus_get(obj))
7824 *newest_focus_order = sd->focus_order;
7825 best = (Evas_Object *)obj;
7828 for (unsigned int i = 0; i < eina_array_count(sd->children); ++i)
7830 child = eina_array_data_get(sd->children, i);
7831 if (!_elm_widget_is(child)) continue;
7833 cur = efl_ui_widget_newest_focus_order_get
7834 (child, newest_focus_order, can_focus_only);
7841 EOLIAN static Eina_Bool
7842 _efl_ui_widget_focus_next_manager_is(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *_pd EINA_UNUSED)
7844 WRN("The %s widget does not implement the \"focus_next/focus_next_manager_is\" functions.",
7845 efl_class_name_get(efl_class_get(obj)));
7850 _efl_ui_widget_focus_direction_manager_is(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *_pd EINA_UNUSED)
7852 WRN("The %s widget does not implement the \"focus_direction/focus_direction_manager_is\" functions.",
7853 efl_class_name_get(efl_class_get(obj)));
7857 //TIZEN_ONLY(20180607): Restore legacy focus
7859 _efl_ui_widget_focus_mouse_up_handle(Eo *obj, Elm_Widget_Smart_Data *_pd EINA_UNUSED)
7862 if (!_is_focusable(obj)) return;
7864 efl_ui_widget_focus_steal(obj, NULL);
7867 //TIZEN_ONLY(20160929) : atspi: Improves how to find the can_highlight of the widget
7869 _elm_widget_can_highlight_get_by_class(Eo *obj)
7871 if (efl_isa(obj, ELM_WIDGET_ITEM_CLASS))
7873 Elm_Widget_Item_Data *id = efl_data_scope_get(obj, ELM_WIDGET_ITEM_CLASS);
7874 if (!id) return EINA_FALSE;
7875 if (!id->can_highlight) return EINA_FALSE;
7879 Elm_Widget_Smart_Data *wd = efl_data_scope_get(obj, EFL_UI_WIDGET_CLASS);
7880 if (!wd) return EINA_FALSE;
7881 if (!wd->can_highlight) return EINA_FALSE;
7887 //TIZEN_ONLY(20161107): enhance elm_atspi_accessible_can_highlight_set to set can_hihglight property to its children
7889 _elm_widget_item_highlightable(Elm_Object_Item *item)
7893 Elm_Widget_Item_Data *id = efl_data_scope_get(item, ELM_WIDGET_ITEM_CLASS);
7894 if (!id) return EINA_FALSE;
7895 if (!id->can_highlight) return EINA_FALSE;
7897 parent = efl_provider_find(efl_parent_get(item), EFL_ACCESS_OBJECT_MIXIN);
7898 while (parent && !efl_isa(parent, ELM_ATSPI_APP_OBJECT_CLASS))
7900 //TIZEN_ONLY(20160929) : atspi: Improves how to find the can_highlight of the widget
7901 if (!_elm_widget_can_highlight_get_by_class(parent)) return EINA_FALSE;
7903 parent = efl_provider_find(efl_parent_get(parent), EFL_ACCESS_OBJECT_MIXIN);
7909 //TIZEN_ONLY(20170206): Add check the object is in the scroller content size
7911 _accessible_object_on_scroll_is(Eo* obj)
7913 /* in case of genlist item, the item->view is NULL if item is unrealized.
7914 this function is used to check if obj could have HIGHLIGHTABLE or not.
7915 the unrealized genlist item should have HIGHLIGHTABLE state.
7916 so if obj is NULL return EINA_TRUE */
7917 if(!obj) return EINA_TRUE;
7919 Evas_Object *target = obj;
7920 Evas_Object *parent = NULL;
7921 Evas_Coord x, y, w, h, wx, wy, ww = 0, wh = 0, nx = 0, ny = 0;
7923 evas_object_geometry_get(target, &x, &y ,&w, &h);
7925 if (elm_widget_is(target))
7926 parent = elm_widget_parent_get(target);
7928 parent = elm_widget_parent_widget_get(target);
7932 if (efl_isa(parent, ELM_INTERFACE_SCROLLABLE_MIXIN))
7934 evas_object_geometry_get(parent, &wx, &wy, NULL, NULL);
7935 elm_interface_scrollable_content_size_get(parent, &ww, &wh);
7936 elm_interface_scrollable_content_pos_get(parent, &nx, &ny);
7938 /* widget implements scrollable interface but does not use scoller
7939 in this case, use widget geometry */
7940 if (ww == 0 || wh == 0)
7942 INF("%s is zero sized scrollable content", efl_class_name_get(efl_class_get(parent)));
7943 evas_object_geometry_get(parent, NULL, NULL, &ww, &wh);
7949 if (((wx < x) && (wx + ww < x)) || ((wx > x + w) && (wx + ww > x + w)) ||
7950 ((wy < y) && (wy + wh < y)) || ((wy > y + h) && (wy + wh > y + h)))
7955 parent = elm_widget_parent_get(parent);
7962 //TIZEN_ONLY(20180607): Restore legacy focus
7966 * Resets the focus_move_policy mode from the system one
7967 * for widgets that are in automatic mode.
7969 * @param obj The widget.
7973 _elm_widget_focus_move_policy_reload(Evas_Object *obj)
7976 Elm_Focus_Move_Policy focus_move_policy = elm_config_focus_move_policy_get();
7978 if (efl_ui_widget_focus_move_policy_automatic_get(obj) &&
7979 (sd->focus_move_policy != focus_move_policy))
7981 sd->focus_move_policy = focus_move_policy;
7986 _efl_ui_widget_focus_reconfigure(Eo *obj, Elm_Widget_Smart_Data *_pd EINA_UNUSED)
7991 for (unsigned int i = 0; i < eina_array_count(sd->children); ++i)
7993 child = eina_array_data_get(sd->children, i);
7994 if (elm_widget_is(child))
7995 efl_ui_widget_focus_reconfigure(child);
7998 if (sd->hover_obj) efl_ui_widget_focus_reconfigure(sd->hover_obj);
8000 _elm_widget_focus_move_policy_reload(obj);
8004 //TIZEN_ONLY(20160329): widget: improve accessible_at_point getter (a8aff0423202b9a55dbb3843205875226678fbd6)
8006 _coordinate_system_based_point_translate(const Eo *obj, Eina_Bool screen_coords, int *x, int *y)
8014 ee = ecore_evas_ecore_evas_get(evas_object_evas_get(obj));
8017 ecore_evas_geometry_get(ee, &ee_x, &ee_y, NULL, NULL);
8023 static Evas_Object *
8024 _parent_get(Evas_Object *obj)
8026 Evas_Object *parent;
8028 parent = evas_object_smart_parent_get(obj);
8031 if (strcmp("Efl_Ui_Win", efl_class_name_get(efl_class_get(obj))))
8032 parent = elm_widget_parent_get(obj);
8039 _is_inside(Evas_Object *obj, int x, int y)
8041 Eina_Bool ret = EINA_TRUE;
8046 if (efl_isa(obj, ELM_WIDGET_ITEM_CLASS))
8048 Elm_Widget_Item_Data *id = efl_data_scope_get(obj, ELM_WIDGET_ITEM_CLASS);
8049 evas_object_geometry_get(id->view, &cx, &cy, &cw, &ch);
8052 evas_object_geometry_get(obj, &cx, &cy, &cw, &ch);
8054 /* check the point is out of bound */
8055 if (x < cx || x > cx + cw || y < cy || y > cy + ch)
8063 _is_ancestor_of(Evas_Object *smart_parent, const Evas_Object *obj)
8065 Eina_Bool ret = EINA_FALSE;
8066 Evas_Object *parent = elm_widget_parent_get(obj);
8069 /* No need to check more, the smart_parent is parent of obj */
8070 if (smart_parent == parent)
8075 parent = elm_widget_parent_get(parent);
8082 _acceptable_child_is(Eo *obj)
8084 Efl_Access_Role role;
8085 Eina_List *children;
8086 Efl_Access_State_Set ss;
8088 role = efl_access_object_role_get(obj);
8091 case EFL_ACCESS_ROLE_IMAGE:
8092 case EFL_ACCESS_ROLE_ICON:
8093 case EFL_ACCESS_ROLE_REDUNDANT_OBJECT:
8094 /* remove unacceptable leaf node */
8095 children = efl_access_object_access_children_get(obj);
8096 if (!children) return EINA_FALSE;
8099 case EFL_ACCESS_ROLE_PANEL:
8100 /* remove closed panel fron children list */
8101 ss = efl_access_object_state_set_get(obj);
8102 if (!STATE_TYPE_GET(ss, EFL_ACCESS_STATE_TYPE_SHOWING)) return EINA_FALSE;
8112 static int _sort_by_size(const void *data1, const void *data2)
8117 evas_object_geometry_get(data1, NULL, NULL, &w, &h);
8118 evas_object_geometry_get(data2, NULL, NULL, &w2, &h2);
8120 if ((w * h) > (w2 * h2)) return 1;
8125 _elm_widget_atspi_role_acceptable_check(Eo *obj)
8127 Efl_Access_Role role;
8128 role = efl_access_object_role_get(obj);
8132 case EFL_ACCESS_ROLE_APPLICATION:
8133 case EFL_ACCESS_ROLE_FILLER:
8134 case EFL_ACCESS_ROLE_SCROLL_PANE:
8135 case EFL_ACCESS_ROLE_SPLIT_PANE:
8136 case EFL_ACCESS_ROLE_WINDOW:
8137 case EFL_ACCESS_ROLE_IMAGE:
8138 case EFL_ACCESS_ROLE_LIST:
8139 case EFL_ACCESS_ROLE_ICON:
8140 case EFL_ACCESS_ROLE_TOOL_BAR:
8141 case EFL_ACCESS_ROLE_REDUNDANT_OBJECT:
8142 case EFL_ACCESS_ROLE_COLOR_CHOOSER:
8143 case EFL_ACCESS_ROLE_TREE_TABLE:
8144 case EFL_ACCESS_ROLE_PAGE_TAB_LIST:
8145 case EFL_ACCESS_ROLE_PAGE_TAB:
8146 case EFL_ACCESS_ROLE_SPIN_BUTTON:
8147 case EFL_ACCESS_ROLE_INPUT_METHOD_WINDOW:
8148 case EFL_ACCESS_ROLE_EMBEDDED:
8149 case EFL_ACCESS_ROLE_INVALID:
8150 case EFL_ACCESS_ROLE_NOTIFICATION:
8160 _child_object_at_point_get(const Eo *obj, int x, int y)
8162 Eina_List *l, *l_next, *children, *valid_children = NULL;
8167 children = efl_access_object_access_children_get(obj);
8169 EINA_LIST_FOREACH(children, l, child)
8171 if (_is_inside(child, x, y))
8172 valid_children = eina_list_append(valid_children, child);
8175 EINA_LIST_FOREACH_SAFE(valid_children, l, l_next, child)
8177 children = efl_access_object_access_children_get(child);
8179 /* do not use unacceptable leaf node */
8180 if (!_elm_widget_atspi_role_acceptable_check(child) &&
8181 eina_list_count(children) == 0)
8182 valid_children = eina_list_remove_list(valid_children, l);
8185 count = eina_list_count(valid_children);
8188 valid_children = eina_list_sort(valid_children, -1, _sort_by_size);
8189 target = eina_list_nth(valid_children, 0);
8191 //TIZEN_ONLY(20191209):Do not accept children with unacceptable role
8192 //return _child_object_at_point_get(target, x, y);
8193 Eo *ret = (Eo *)_child_object_at_point_get(target, x, y);
8194 if (ret) return ret;
8198 //TIZEN_ONLY(20191209):Do not accept children with unacceptable role
8200 return _elm_widget_atspi_role_acceptable_check((Eo *)obj) ? (Eo *)obj : NULL;
8206 _accessible_at_point_top_down_get(const Eo *obj, Elm_Widget_Smart_Data *_pd EINA_UNUSED, Eina_Bool screen_coords, int x, int y)
8208 Eina_List *l, *l2, *children, *valid_children = NULL;
8210 Evas_Object *stack_item;
8212 // TIZEN_ONLY(20160705) - enable atspi_proxy to work
8214 Evas_Coord px, py, pw, ph;
8217 _coordinate_system_based_point_translate(obj, screen_coords, &x, &y);
8219 children = efl_access_object_access_children_get(obj);
8221 EINA_LIST_FOREACH(children, l2, child)
8223 if (_is_inside(child, x, y) && _acceptable_child_is(child))
8224 valid_children = eina_list_append(valid_children, child);
8227 /* If there is only one valid child at point, then return it.
8228 The evas_tree_objects_at_xy_get could not find proper object,
8229 if application does not have well aligned objects. */
8230 if (eina_list_count(valid_children) == 1)
8232 eina_list_free(children);
8233 child = eina_list_nth(valid_children, 0);
8237 /* Get evas_object stacked at given x,y coordinates starting from top */
8238 Eina_List *stack = evas_tree_objects_at_xy_get(evas_object_evas_get(obj), NULL, x, y);
8239 /* Foreach stacked object starting from top */
8240 EINA_LIST_FOREACH(stack, l, stack_item)
8242 /* Foreach at-spi valid children traverse stack_item evas_objects hierarchy */
8243 EINA_LIST_FOREACH(valid_children, l2, child)
8245 Efl_Access_Role role;
8246 role = efl_access_object_role_get(child);
8247 if (role == EFL_ACCESS_ROLE_REDUNDANT_OBJECT)
8249 /* The redundant object ignores */
8252 /* Compare object used to compare with stacked evas objects */
8253 compare_obj = child;
8254 /* In case of widget_items compare should be different then elm_widget_ item object */
8255 if (efl_isa(child, ELM_WIDGET_ITEM_CLASS))
8257 Elm_Widget_Item_Data *id = efl_data_scope_get(child, ELM_WIDGET_ITEM_CLASS);
8258 compare_obj = id->view;
8259 if (TIZEN_PROFILE_WEARABLE)
8261 Eo* it_view = evas_object_image_source_get(stack_item);
8262 if (it_view && it_view == compare_obj)
8264 eina_list_free(children);
8265 eina_list_free(stack);
8270 /* In case of access object compare should be 'wrapped' evas_object */
8271 if (efl_isa(child, ELM_ACCESS_CLASS))
8273 Elm_Access_Info *info = _elm_access_info_get(child);
8274 if (!info) continue;
8275 compare_obj = info->part_object;
8277 /* In case of widget is registerd by elm_access_object_register */
8278 Evas_Object *ao = elm_access_object_get(child);
8281 eina_list_free(children);
8282 eina_list_free(stack);
8286 /* In case of ewk wrapper object compare with internal ewk_view evas_object */
8287 if (efl_isa(child, ELM_ATSPI_EWK_WRAPPER_CLASS))
8289 compare_obj = elm_atspi_ewk_wrapper_ewk_view_get(child);
8292 /* If spacial eo children do not have backing evas_object continue with search */
8296 Evas_Object *smart_parent = stack_item;
8297 while (smart_parent)
8299 if (smart_parent == compare_obj)
8301 eina_list_free(children);
8302 eina_list_free(stack);
8306 // TIZEN_ONLY(20160705) - enable atspi_proxy to work
8307 proxy = evas_object_data_get(smart_parent, "__widget_proxy");
8310 // TIZEN_ONLY(20171109) : fix for invalid proxy object, when at-spi has been restarted
8312 parent = efl_provider_find(efl_parent_get(smart_parent), EFL_ACCESS_OBJECT_MIXIN);
8313 proxy = plug_type_proxy_get(parent, smart_parent);
8315 evas_object_geometry_get(smart_parent, &px, &py, &pw, &ph);
8316 if (x >= px && x <= px + pw && y >= py && y <= py +ph)
8318 eina_list_free(children);
8319 eina_list_free(stack);
8325 smart_parent = _parent_get(smart_parent);
8326 if (_is_ancestor_of(smart_parent, obj)) break;
8331 eina_list_free(children);
8332 eina_list_free(stack);
8336 static int _sort_by_repeat_events(const void *data1, const void *data2)
8338 Evas_Object *ao1, *ao2;
8339 Eina_Bool repeat1, repeat2;
8341 ao1 = elm_access_object_get(data1);
8342 ao2 = elm_access_object_get(data2);
8344 repeat1 = evas_object_repeat_events_get(data1);
8345 repeat2 = evas_object_repeat_events_get(data2);
8347 if (repeat1 != repeat2)
8349 if (repeat1 && !ao1) return 1;
8353 if (repeat1 && !ao1 && ao2) return 1;
8359 static Eo *_item_at_point_get(Evas_Object *obj, int x, int y)
8362 Eina_List *l, *children;
8364 children = efl_access_object_access_children_get(obj);
8366 EINA_LIST_FOREACH(children, l, child)
8368 if (_is_inside(child, x, y)) return child;
8371 ERR("No child at point (%d, %d) on object %p", x, y, obj);
8375 //TIZEN_ONLY(20171108): bring HIGHLIGHT related changes
8377 _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)
8379 Elm_Atspi_Role role;
8381 Evas_Object *stack_item;
8383 role = efl_access_object_role_get(obj);
8387 case ELM_ATSPI_ROLE_WINDOW:
8388 /* this is for webapp which is using window only */
8389 if (evas_object_data_get(obj, "__PlugID"))
8391 Eina_List *children;
8393 children = efl_access_object_access_children_get(obj);
8394 EINA_LIST_FOREACH(children, l, child)
8396 if (efl_access_object_role_get(child) == EFL_ACCESS_ROLE_EMBEDDED)
8400 DBG("Find accessible from bottom");
8402 case ELM_ATSPI_ROLE_INPUT_METHOD_WINDOW:
8403 case ELM_ATSPI_ROLE_DIALOG:
8404 case ELM_ATSPI_ROLE_PAGE_TAB:
8405 //TIZEN_ONLY(20220915): Use top-down at-point search for POPUP_MENU
8406 //case ELM_ATSPI_ROLE_POPUP_MENU: // Bottom-up search would find buttons absent from the AT-SPI tree in case of CtxPopup
8408 case ELM_ATSPI_ROLE_PANEL:
8409 DBG("Find accessible from bottom");
8413 return _accessible_at_point_top_down_get(obj, _pd, screen_coords, x, y);
8416 _coordinate_system_based_point_translate(obj, screen_coords, &x, &y);
8418 Eina_List *stack = evas_tree_objects_at_xy_get(evas_object_evas_get(obj), NULL, x, y);
8419 stack = eina_list_sort(stack, -1, _sort_by_repeat_events);
8421 EINA_LIST_FOREACH(stack, l, stack_item)
8423 Evas_Object *smart_parent = stack_item;
8424 while (smart_parent)
8426 /* If parent equals to obj, it is not necessary to go upper.
8427 So the top down logic would be better than NULL return. */
8428 if (smart_parent == obj)
8429 return _accessible_at_point_top_down_get(obj, _pd, screen_coords, x, y);
8431 Evas_Object *ao = elm_access_object_get(smart_parent);
8434 if (efl_isa(smart_parent, EFL_ACCESS_OBJECT_MIXIN))
8436 Eina_Bool acceptable = EINA_FALSE;
8438 role = efl_access_object_role_get(smart_parent);
8441 case EFL_ACCESS_ROLE_FILLER: /* ex: View of colorselector item is layout */
8442 case EFL_ACCESS_ROLE_ICON:
8443 case EFL_ACCESS_ROLE_IMAGE:
8444 case EFL_ACCESS_ROLE_REDUNDANT_OBJECT:
8445 case EFL_ACCESS_ROLE_WINDOW:
8446 DBG("Go for parent: %s (%p)\n", evas_object_type_get(smart_parent), smart_parent);
8448 case EFL_ACCESS_ROLE_LIST:
8449 item_child = _item_at_point_get(smart_parent, x, y);
8450 if (TIZEN_PROFILE_WEARABLE)
8452 item_child = _child_object_at_point_get(item_child, x, y);
8458 acceptable = EINA_TRUE;
8462 if (acceptable) return smart_parent;
8465 smart_parent = _parent_get(smart_parent);
8469 eina_list_free(stack);
8470 return _accessible_at_point_top_down_get(obj, _pd, screen_coords, x, y);
8472 // TIZEN_ONLY(20171114) Accessibility Highlight Frame added
8473 // EOLIAN static Eina_Bool
8474 // _elm_widget_item_efl_access_component_highlight_grab(Eo *obj, Elm_Widget_Item_Data *sd)
8476 // Evas_Object *win = elm_widget_top_get(sd->widget);
8477 // if (win && efl_isa(win, EFL_UI_WIN_CLASS))
8479 // _elm_win_accessibility_highlight_set(win, sd->view);
8480 // efl_access_state_changed_signal_emit(obj, EFL_ACCESS_STATE_TYPE_HIGHLIGHTED, EINA_TRUE);
8481 // return EINA_TRUE;
8483 // return EINA_FALSE;
8487 // EOLIAN static Eina_Bool
8488 // _elm_widget_item_efl_access_component_highlight_clear(Eo *obj, Elm_Widget_Item_Data *sd)
8490 // Evas_Object *win = elm_widget_top_get(sd->widget);
8491 // if (win && efl_isa(win, EFL_UI_WIN_CLASS))
8493 // if (_elm_win_accessibility_highlight_get(win) != sd->view)
8494 // return EINA_TRUE;
8496 // _elm_win_accessibility_highlight_set(win, NULL);
8497 // efl_access_state_changed_signal_emit(obj, EFL_ACCESS_STATE_TYPE_HIGHLIGHTED, EINA_FALSE);
8498 // return EINA_TRUE;
8500 // return EINA_FALSE;
8504 //TIZEN_ONLY(20170119): Show the object highlighted by highlight_grab when the object is completely out of the scroll
8506 _elm_widget_showing_geometry_get(Eo *obj, int *x, int *y, int *w, int *h)
8508 Evas_Object *parent;
8509 Evas_Coord px, py, sx, sy, sw, sh;
8517 evas_object_geometry_get(obj, x, y, w, h);
8519 if (elm_widget_is(obj))
8520 parent = elm_widget_parent_get(obj);
8522 parent = elm_widget_parent_widget_get(obj);
8526 if (efl_isa(parent, ELM_INTERFACE_SCROLLABLE_MIXIN))
8528 evas_object_geometry_get(parent, &sx, &sy, &sw, &sh);
8531 *x = *x > sx ? *x : sx;
8532 *y = *y > sy ? *y : sy;
8533 *w = px + *w < sx + sw ? px + *w - *x : sx + sw - *x;
8534 *h = py + *h < sy + sh ? py + *h - *y : sy + sh - *y;
8536 parent = elm_widget_parent_get(parent);
8541 _accessible_object_on_screen_is(Eo *obj, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h, Eina_Bool is_complete)
8543 if(!obj) return EINA_FALSE;
8545 Evas_Object *target = obj;
8546 Evas_Object *parent = NULL;
8547 Evas_Coord px, py, sx, sy, sw, sh, ox, oy, ow, oh;
8549 /* uninitialized data could be read */
8553 if (elm_widget_is(target))
8554 parent = elm_widget_parent_get(target);
8556 parent = elm_widget_parent_widget_get(target);
8560 if (efl_isa(parent, ELM_INTERFACE_SCROLLABLE_MIXIN))
8562 evas_object_geometry_get(parent, &sx, &sy, &sw, &sh);
8567 ox = is_complete ? ox : ox + ow;
8568 oy = is_complete ? oy : oy + oh;
8569 ox = ox > sx ? ox : sx;
8570 oy = oy > sy ? oy : sy;
8571 ow = px + ow < sx + sw ? px + ow - ox : sx + sw - ox;
8572 oh = py + oh < sy + sh ? py + oh - oy : sy + sh - oy;
8574 if (ow <= 0 || oh <= 0)
8577 parent = elm_widget_parent_get(parent);
8583 _accessible_scrollable_parent_list_get(const Eo *obj)
8585 if(!obj) return NULL;
8587 Evas_Object *parent = NULL;
8588 Eina_List *plist = NULL;
8590 if (elm_widget_is(obj))
8591 parent = elm_widget_parent_get(obj);
8593 parent = elm_widget_parent_widget_get(obj);
8597 if (_elm_scrollable_is(parent))
8598 plist = eina_list_append(plist, parent);
8600 parent = elm_widget_parent_get(parent);
8606 _accessible_highlight_region_show(Eo* obj)
8610 Evas_Object *target = obj;
8611 Evas_Object *parent = NULL;
8612 Evas_Object *parent_sub = NULL;
8613 Eina_List *plist, *plist_sub;
8616 Evas_Coord target_x, target_y, target_w, target_h;
8618 evas_object_geometry_get(target, &target_x, &target_y, &target_w, &target_h);
8620 plist = _accessible_scrollable_parent_list_get(target);
8621 if (!plist) return ;
8622 EINA_LIST_FOREACH(plist, l, parent)
8624 if(!_accessible_object_on_screen_is(target, target_x, target_y, target_w, target_h, EINA_TRUE))
8626 plist_sub = _accessible_scrollable_parent_list_get(parent);
8627 plist_sub = eina_list_prepend(plist_sub, parent);
8628 EINA_LIST_FOREACH(plist_sub, l2, parent_sub)
8630 Evas_Coord scroll_x = 0, scroll_y = 0;
8631 Evas_Coord scroll_x_back = 0, scroll_y_back = 0;
8632 Evas_Coord x, y, w, h;
8635 elm_interface_scrollable_content_region_get(parent_sub, &scroll_x_back, &scroll_y_back, NULL, NULL);
8636 evas_object_geometry_get(parent_sub, &px, &py, NULL, NULL);
8637 x = target_x; y = target_y; w = target_w; h = target_h;
8639 x -= (px - scroll_x_back);
8640 y -= (py - scroll_y_back);
8641 switch (_elm_config->focus_autoscroll_mode)
8643 case ELM_FOCUS_AUTOSCROLL_MODE_SHOW:
8644 elm_interface_scrollable_content_region_show(parent_sub, x, y, w, h);
8646 case ELM_FOCUS_AUTOSCROLL_MODE_BRING_IN:
8647 elm_interface_scrollable_region_bring_in(parent_sub, x, y, w, h);
8652 elm_interface_scrollable_content_region_get(parent_sub, &scroll_x, &scroll_y, NULL, NULL);
8654 target_x -= (scroll_x - scroll_x_back);
8655 target_y -= (scroll_y - scroll_y_back);
8657 if(_accessible_object_on_screen_is(target, target_x, target_y, target_w, target_h, EINA_FALSE))
8660 eina_list_free(plist_sub);
8664 eina_list_free(plist);
8668 //TIZEN_ONLY(20171011) : atspi : During the highlight grab, out signal is not sent.
8669 static Eo *_highlight_grabbing_object = NULL;
8672 _elm_widget_accessibility_highlight_grabbing_get(Eo *obj)
8674 return _highlight_grabbing_object == obj;
8678 _elm_widget_accessibility_highlight_grabbing_set(Eo *obj, Eina_Bool grabbing)
8682 if (!_highlight_grabbing_object)
8683 _highlight_grabbing_object = obj;
8684 else if (_highlight_grabbing_object == obj)
8685 ERR("trying to set grabbing for %p, but it's already set to this object", obj);
8687 ERR("trying to set grabbing for %p, but it's already set to %p", obj, _highlight_grabbing_object);
8691 if (_highlight_grabbing_object != obj)
8692 ERR("trying to clear grabbing for %p, but it's set to %p", obj, _highlight_grabbing_object);
8694 _highlight_grabbing_object = NULL;
8699 EOLIAN static Eina_Bool
8700 _efl_ui_widget_efl_access_component_highlight_grab(Eo *obj, Elm_Widget_Smart_Data *pd EINA_UNUSED)
8702 if(!obj) return EINA_FALSE;
8703 if(!_elm_atspi_enabled())
8706 // TIZEN_ONLY(20171020) : atspi : Do not send signal, if current object and highlight object are same
8707 if (_elm_object_accessibility_currently_highlighted_get() == obj)
8711 //TIZEN_ONLY(20171011) : atspi : During the highlight grab, out signal is not sent.
8712 _elm_widget_accessibility_highlight_grabbing_set(obj, EINA_TRUE);
8715 //TIZEN_ONLY(20170119): Show the object highlighted by highlight_grab when the object is completely out of the scroll
8716 _accessible_highlight_region_show(obj);
8719 elm_object_accessibility_highlight_set(obj, EINA_TRUE);
8720 efl_access_state_changed_signal_emit(obj, EFL_ACCESS_STATE_TYPE_HIGHLIGHTED, EINA_TRUE);
8722 // TIZEN_ONLY(20161018): add highlighted/unhighlighted signal for atspi
8723 evas_object_smart_callback_call(obj, SIG_WIDGET_ATSPI_HIGHLIGHTED, NULL);
8726 //TIZEN_ONLY(20171011) : atspi : During the highlight grab, out signal is not sent.
8727 _elm_widget_accessibility_highlight_grabbing_set(obj, EINA_FALSE);
8732 EOLIAN static Eina_Bool
8733 _efl_ui_widget_efl_access_component_highlight_clear(Eo *obj, Elm_Widget_Smart_Data *pd EINA_UNUSED)
8735 if (!obj) return EINA_FALSE;
8736 if (!_elm_atspi_enabled())
8739 elm_object_accessibility_highlight_set(obj, EINA_FALSE);
8740 efl_access_state_changed_signal_emit(obj, EFL_ACCESS_STATE_TYPE_HIGHLIGHTED, EINA_FALSE);
8741 // TIZEN_ONLY(20161018): add highlighted/unhighlighted signal for atspi
8742 evas_object_smart_callback_call(obj, SIG_WIDGET_ATSPI_UNHIGHLIGHTED, NULL);
8748 // TIZEN_ONLY(20171114) Accessibility Highlight Frame added
8749 EOLIAN static Eina_Bool
8750 _elm_widget_item_efl_access_component_highlight_grab(Eo *obj, Elm_Widget_Item_Data *sd)
8752 // TIZEN_ONLY(20171117) Accessibility Highlight frame support for items
8753 // Evas_Object *win = elm_widget_top_get(sd->widget);
8754 // if (win && efl_isa(win, EFL_UI_WIN_CLASS))
8756 // elm_object_accessibility_highlight_set(sd->view, EINA_TRUE);
8757 // efl_access_state_changed_signal_emit(obj, EFL_ACCESS_STATE_TYPE_HIGHLIGHTED, EINA_TRUE);
8758 // return EINA_TRUE;
8760 // return EINA_FALSE;
8762 if (!sd) return EINA_FALSE;
8763 if (!sd->view) return EINA_FALSE;
8764 if (!_elm_atspi_enabled())
8767 // TIZEN_ONLY(20171020) : atspi : Do not send signal, if current object and highlight object are same
8768 if (_elm_object_accessibility_currently_highlighted_get() == obj)
8772 //TIZEN_ONLY(20171011) : atspi : During the highlight grab, out signal is not sent.
8773 _elm_widget_accessibility_highlight_grabbing_set(obj, EINA_TRUE);
8776 //TIZEN_ONLY(20170119): Show the object highlighted by highlight_grab when the object is completely out of the scroll
8777 _accessible_highlight_region_show(sd->view);
8780 if (!sd->eo_obj) return EINA_FALSE;
8781 elm_object_accessibility_highlight_set(sd->eo_obj, EINA_TRUE);
8783 if (!obj) return EINA_FALSE;
8784 efl_access_state_changed_signal_emit(obj, EFL_ACCESS_STATE_TYPE_HIGHLIGHTED, EINA_TRUE);
8785 //TIZEN_ONLY(20170412) Make atspi,(un)highlighted work on widget item
8786 evas_object_smart_callback_call(sd->widget, SIG_WIDGET_ATSPI_HIGHLIGHTED, obj);
8789 //TIZEN_ONLY(20171011) : atspi : During the highlight grab, out signal is not sent.
8790 _elm_widget_accessibility_highlight_grabbing_set(obj, EINA_FALSE);
8797 EOLIAN static Eina_Bool
8798 _elm_widget_item_efl_access_component_highlight_clear(Eo *obj, Elm_Widget_Item_Data *sd)
8800 if (!obj) return EINA_FALSE;
8801 if (!_elm_atspi_enabled())
8804 elm_object_accessibility_highlight_set(sd->eo_obj, EINA_FALSE);
8805 efl_access_state_changed_signal_emit(obj, EFL_ACCESS_STATE_TYPE_HIGHLIGHTED, EINA_FALSE);
8806 //TIZEN_ONLY(20170412) Make atspi,(un)highlighted work on widget item
8807 evas_object_smart_callback_call(sd->widget, SIG_WIDGET_ATSPI_UNHIGHLIGHTED, obj);
8813 //TIZEN_ONLY(20160527): widget: add AtspiAction interface to all widgets and widget_items, add handlers for reading stopped/cancelled
8814 EOLIAN const Efl_Access_Action_Data *
8815 _efl_ui_widget_efl_access_widget_action_elm_actions_get(const Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *pd EINA_UNUSED)
8820 EOLIAN const Efl_Access_Action_Data *
8821 _elm_widget_item_efl_access_widget_action_elm_actions_get(const Eo *obj EINA_UNUSED, Elm_Widget_Item_Data *pd EINA_UNUSED)
8826 /***********************************************************
8827 * TIZEN_ONLY(20180117): Override Paragraph Direction APIs *
8828 ***********************************************************/
8830 _efl_ui_widget_efl_canvas_object_paragraph_direction_set_internal(Eo *obj EINA_UNUSED, Efl_Ui_Widget_Data *sd, Efl_Text_Bidirectional_Type dir)
8834 if (sd->on_destroy) return;
8836 for (unsigned int i = 0; i < eina_array_count(sd->children); ++i)
8838 child = eina_array_data_get(sd->children, i);
8839 if (_elm_widget_is(child))
8841 Efl_Ui_Widget_Data *sdc = efl_data_scope_get(child, MY_CLASS);
8843 if (sdc->inherit_paragraph_direction &&
8844 (sdc->paragraph_direction != dir))
8846 sdc->paragraph_direction = dir;
8847 _efl_ui_widget_efl_canvas_object_paragraph_direction_set_internal(child, sdc, dir);
8848 efl_canvas_object_paragraph_direction_set(efl_super(child, MY_CLASS), dir);
8852 /* FIXME: There is no way to handle non-widget child object.
8853 * If a non-widget child object has smart parent, it will get the direction
8854 * from the smart parent. */
8859 _efl_ui_widget_efl_canvas_object_paragraph_direction_set(Eo *obj, Efl_Ui_Widget_Data *sd, Efl_Text_Bidirectional_Type dir)
8861 if ((!(sd->inherit_paragraph_direction) && (sd->paragraph_direction == dir)) ||
8862 (sd->inherit_paragraph_direction && (dir == EFL_TEXT_BIDIRECTIONAL_TYPE_INHERIT)))
8865 if (dir == EFL_TEXT_BIDIRECTIONAL_TYPE_INHERIT)
8867 sd->inherit_paragraph_direction = EINA_TRUE;
8868 Evas_BiDi_Direction parent_dir = EFL_TEXT_BIDIRECTIONAL_TYPE_NEUTRAL;
8871 parent_dir = efl_canvas_object_paragraph_direction_get(sd->parent_obj);
8873 if (parent_dir != sd->paragraph_direction)
8875 sd->paragraph_direction = parent_dir;
8876 _efl_ui_widget_efl_canvas_object_paragraph_direction_set_internal(obj, sd, parent_dir);
8881 sd->inherit_paragraph_direction = EINA_FALSE;
8882 sd->paragraph_direction = dir;
8883 _efl_ui_widget_efl_canvas_object_paragraph_direction_set_internal(obj, sd, dir);
8886 efl_canvas_object_paragraph_direction_set(efl_super(obj, MY_CLASS), dir);
8892 /***********************************************************************************
8893 * TIZEN_ONLY_FEATURE: apply Tizen's color_class features. *
8894 ***********************************************************************************/
8896 _elm_widget_color_class_parent_set(Evas_Object *obj, Evas_Object *parent)
8898 Evas_Object *edje = NULL, *parent_edje = NULL;
8900 if (!obj || !parent) return;
8902 if (efl_isa(obj, EFL_UI_LAYOUT_BASE_CLASS))
8903 edje = elm_layout_edje_get(obj);
8904 else if (efl_isa(obj, EFL_CANVAS_LAYOUT_CLASS))
8907 if (efl_isa(parent, EFL_UI_LAYOUT_BASE_CLASS))
8908 parent_edje = elm_layout_edje_get(parent);
8909 else if (efl_isa(parent, EFL_CANVAS_LAYOUT_CLASS))
8910 parent_edje = parent;
8912 if (!edje || !parent_edje) return;
8914 edje_object_color_class_parent_set(edje, parent_edje);
8918 _elm_widget_color_class_parent_unset(Evas_Object *obj)
8920 Evas_Object *edje = NULL;
8924 if (efl_isa(obj, EFL_UI_LAYOUT_BASE_CLASS))
8925 edje = elm_layout_edje_get(obj);
8926 else if (efl_isa(obj, EFL_CANVAS_LAYOUT_CLASS))
8931 edje_object_color_class_parent_unset(edje);
8935 _edje_color_class_free(void *data)
8937 Edje_Color_Class *cc = data;
8939 if (cc->name) eina_stringshare_del(cc->name);
8944 _elm_widget_edje_class_get(const Evas_Object *obj, const char *style, const char *part)
8947 Eina_Stringshare *str;
8948 const char *klass_name = NULL;
8949 Eina_Bool is_legacy = EINA_FALSE;
8950 Eina_Bool is_item = efl_isa(obj, ELM_WIDGET_ITEM_CLASS);
8953 is_legacy = elm_widget_is_legacy(elm_object_item_widget_get(obj));
8955 is_legacy = elm_widget_is_legacy(obj);
8957 buf = eina_strbuf_new();
8962 klass_name = _elm_widget_item_legacy_type_get(obj);
8964 klass_name = elm_widget_type_get(obj);
8968 klass_name = efl_class_name_get(efl_class_get(obj));
8973 if (is_legacy && strchr(klass_name, '_'))
8975 eina_strbuf_append(buf, strchr(klass_name, '_') + 1);
8976 eina_strbuf_tolower(buf);
8980 /* Get the last word from the given klass name */
8981 char *temp, *temp_orig, *temp_ret, *last_ret = NULL;
8982 const char *delim = NULL;
8984 temp_orig = temp = strdup(klass_name);
8986 /* If "." is not used for word serperator,
8987 * it assume the given klass name is legacy.
8988 * And legacy klass name was made with "_" as its word seperator. */
8989 if (strchr(klass_name, '.'))
8994 while ((temp_ret = strsep(&temp, delim)) != NULL)
8996 if (strcmp(temp_ret, ""))
8997 last_ret = temp_ret;
9002 eina_strbuf_append(buf, last_ret);
9003 eina_strbuf_tolower(buf);
9012 eina_strbuf_append_printf(buf, "/%s/%s", style, part);
9016 eina_strbuf_append_printf(buf, "/%s", part);
9019 str = eina_stringshare_add(eina_strbuf_string_get(buf));
9021 eina_strbuf_free(buf);
9026 _elm_widget_color_class_set_internal(Evas_Object *obj, Evas_Object *edje, const char *color_class,
9027 int r, int g, int b, int a,
9028 int r2, int g2, int b2, int a2,
9029 int r3, int g3, int b3, int a3)
9031 Eina_Bool int_ret = EINA_TRUE;
9032 Eina_Stringshare *buf;
9033 // TIZEN_ONLY(20200623) : apply Tizen's color_class features
9034 Edje_Color_Class *cc = NULL;
9035 API_ENTRY return EINA_FALSE;
9037 int temp_color[3][4] = { { r, g, b, a },
9039 { r3, g3, b3, a3 } };
9041 if (!color_class) return EINA_FALSE;
9043 buf = _elm_widget_edje_class_get(obj, NULL, color_class);
9045 #define TEMP_COLOR(x, y) \
9046 ((temp_color[x][y] == -1) ? &temp_color[x][y] : NULL)
9048 edje_object_color_class_get(edje, buf,
9049 TEMP_COLOR(0, 0), TEMP_COLOR(0, 1), TEMP_COLOR(0, 2), TEMP_COLOR(0, 3),
9050 TEMP_COLOR(1, 0), TEMP_COLOR(1, 1), TEMP_COLOR(1, 2), TEMP_COLOR(1, 3),
9051 TEMP_COLOR(2, 0), TEMP_COLOR(2, 1), TEMP_COLOR(2, 2), TEMP_COLOR(2, 3));
9055 #define TEMP_COLOR(x, y) \
9056 ((temp_color[x][y] == -1) ? 0 : temp_color[x][y])
9058 int_ret &= edje_object_color_class_set(edje, buf,
9059 TEMP_COLOR(0, 0), TEMP_COLOR(0, 1), TEMP_COLOR(0, 2), TEMP_COLOR(0, 3),
9060 TEMP_COLOR(1, 0), TEMP_COLOR(1, 1), TEMP_COLOR(1, 2), TEMP_COLOR(1, 3),
9061 TEMP_COLOR(2, 0), TEMP_COLOR(2, 1), TEMP_COLOR(2, 2), TEMP_COLOR(2, 3));
9065 // TIZEN_ONLY(20200623) : apply Tizen's color_class features
9068 if (!sd->color_classes)
9069 sd->color_classes = eina_hash_string_small_new(_edje_color_class_free);
9071 cc = eina_hash_find(sd->color_classes, buf);
9074 cc = calloc(1, sizeof(Edje_Color_Class));
9075 if (!cc) goto on_error;
9076 cc->name = eina_stringshare_add(buf);
9077 eina_hash_direct_add(sd->color_classes, cc->name, cc);
9079 cc->r = r; cc->g = g; cc->b = b; cc->a = a;
9080 cc->r2 = r2; cc->g2 = g2; cc->b2 = b2; cc->a2 = a2;
9081 cc->r3 = r3; cc->g3 = g3; cc->b3 = b3; cc->a3 = a3;
9086 eina_stringshare_del(buf);
9092 _elm_widget_color_class_get_internal(Evas_Object *obj, Evas_Object *edje, const char *color_class,
9093 int *r, int *g, int *b, int *a,
9094 int *r2, int *g2, int *b2, int *a2,
9095 int *r3, int *g3, int *b3, int *a3)
9097 Eina_Bool int_ret = EINA_TRUE;
9098 Eina_Stringshare *buf;
9100 if (!color_class) return EINA_FALSE;
9102 buf = _elm_widget_edje_class_get(obj, elm_widget_style_get(obj), color_class);
9104 int_ret &= edje_object_color_class_get(edje, buf,
9109 eina_stringshare_del(buf);
9114 /* Internal EO API */
9116 _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)
9119 Eina_Bool int_ret = EINA_TRUE;
9121 if (!efl_isa(obj, EFL_UI_LAYOUT_BASE_CLASS)) return EINA_FALSE;
9123 edje = elm_layout_edje_get(obj);
9124 int_ret &= _elm_widget_color_class_set_internal(obj, edje, color_class,
9132 /* Internal EO API */
9134 _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)
9137 Eina_Bool int_ret = EINA_TRUE;
9139 if (!efl_isa(obj, EFL_UI_LAYOUT_BASE_CLASS)) return EINA_FALSE;
9141 edje = elm_layout_edje_get(obj);
9142 int_ret &= _elm_widget_color_class_get_internal(obj, edje, color_class,
9144 NULL, NULL, NULL, NULL,
9145 NULL, NULL, NULL, NULL);
9150 /* Internal EO API */
9152 _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)
9155 Eina_Bool int_ret = EINA_TRUE;
9157 if (!efl_isa(obj, EFL_UI_LAYOUT_BASE_CLASS)) return EINA_FALSE;
9159 edje = elm_layout_edje_get(obj);
9160 int_ret &= _elm_widget_color_class_set_internal(obj, edje, color_class,
9168 /* Internal EO API */
9170 _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)
9173 Eina_Bool int_ret = EINA_TRUE;
9175 if (!efl_isa(obj, EFL_UI_LAYOUT_BASE_CLASS)) return EINA_FALSE;
9177 edje = elm_layout_edje_get(obj);
9178 int_ret &= _elm_widget_color_class_get_internal(obj, edje, color_class,
9179 NULL, NULL, NULL, NULL,
9181 NULL, NULL, NULL, NULL);
9186 /* Internal EO API */
9188 _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)
9191 Eina_Bool int_ret = EINA_TRUE;
9193 if (!efl_isa(obj, EFL_UI_LAYOUT_BASE_CLASS)) return EINA_FALSE;
9195 edje = elm_layout_edje_get(obj);
9196 int_ret &= _elm_widget_color_class_set_internal(obj, edje, color_class,
9204 /* Internal EO API */
9206 _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)
9209 Eina_Bool int_ret = EINA_TRUE;
9211 if (!efl_isa(obj, EFL_UI_LAYOUT_BASE_CLASS)) return EINA_FALSE;
9213 edje = elm_layout_edje_get(obj);
9214 int_ret &= _elm_widget_color_class_get_internal(obj, edje, color_class,
9215 NULL, NULL, NULL, NULL,
9216 NULL, NULL, NULL, NULL,
9222 /* Internal EO API */
9224 _elm_widget_class_color_del(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd, const char *color_class)
9226 Eina_Stringshare *buf;
9227 // TIZEN_ONLY(20200623) : apply Tizen's color_class features
9228 Edje_Color_Class *cc = NULL;
9231 if (!efl_isa(obj, EFL_UI_LAYOUT_BASE_CLASS)) return;
9233 buf = _elm_widget_edje_class_get(obj, NULL, color_class);
9234 // TIZEN_ONLY(20200623) : apply Tizen's color_class features
9235 eina_hash_del(sd->color_classes, buf, cc);
9237 edje_object_color_class_del(sd->resize_obj, buf);
9238 eina_stringshare_del(buf);
9241 /* Internal EO API */
9243 _elm_widget_class_color_clear(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd)
9245 if (!efl_isa(obj, EFL_UI_LAYOUT_BASE_CLASS)) return;
9246 // TIZEN_ONLY(20200623) : apply Tizen's color_class features
9247 ELM_SAFE_FREE(sd->color_classes, eina_hash_free);
9249 edje_object_color_class_clear(sd->resize_obj);
9252 #define ELM_COLOR_CLASS_UPDATE(obj, hash, cond) \
9253 Evas_Object *edje = NULL; \
9254 Eina_Iterator *itr; \
9255 Edje_Color_Class *cc; \
9256 Eina_Bool int_ret = EINA_TRUE; \
9257 if (cond) return EINA_FALSE; \
9258 if (efl_isa(obj, EFL_UI_LAYOUT_BASE_CLASS)) \
9259 edje = elm_layout_edje_get(obj); \
9260 else if (efl_isa(obj, EFL_CANVAS_LAYOUT_CLASS)) \
9262 if (!edje) return EINA_FALSE; \
9263 itr = eina_hash_iterator_data_new(hash); \
9264 EINA_ITERATOR_FOREACH(itr, cc) \
9266 int_ret &= edje_object_color_class_set(edje, cc->name, \
9267 cc->r, cc->g, cc->b, cc->a, \
9268 cc->r2, cc->g2, cc->b2, cc->a2, \
9269 cc->r3, cc->g3, cc->b3, cc->a3); \
9271 eina_iterator_free(itr); \
9275 _elm_widget_color_class_update(Eo *obj, Elm_Widget_Smart_Data *sd)
9277 ELM_COLOR_CLASS_UPDATE(obj, sd->color_classes, (!sd) || (!sd->color_classes) || (!obj));
9280 #define CHECK_BOUND(x) \
9281 if (x > 0xff) x = 0xff; \
9282 else if (x < 0) x = 0
9284 #define ELM_COLOR_CLASS_SET_START(obj, cr, cg, cb, ca) \
9285 Eina_Bool int_ret = EINA_FALSE; \
9286 Edje_Color_Class *cc = NULL; \
9287 Eina_Stringshare *buf; \
9288 buf = _elm_widget_edje_class_get(obj, NULL, color_class); \
9293 _elm_color_unpremul(a, &r, &g, &b); \
9294 if (!sd->color_classes) \
9295 sd->color_classes = eina_hash_string_small_new(_edje_color_class_free); \
9297 cc = eina_hash_find(sd->color_classes, buf); \
9300 cc = calloc(1, sizeof(Edje_Color_Class)); \
9301 cc->name = eina_stringshare_add(buf); \
9305 eina_stringshare_del(buf); \
9306 return EINA_FALSE; \
9308 eina_hash_direct_add(sd->color_classes, cc->name, cc); \
9310 else if ((cc->cr == r) && (cc->cg == g) && \
9311 (cc->cb == b) && (cc->ca == a)) \
9313 eina_stringshare_del(buf); \
9322 #define ELM_COLOR_CLASS_SET_END() \
9323 eina_stringshare_del(buf); \
9326 #define ELM_COLOR_CLASS_GET(obj, cr, cg, cb, ca) \
9327 Eina_Bool int_ret = EINA_FALSE; \
9328 Edje_Color_Class *cc; \
9329 Eina_Stringshare *buf; \
9331 buf = _elm_widget_edje_class_get(obj, NULL, color_class); \
9332 if ((!sd->color_classes) || !(cc = eina_hash_find(sd->color_classes, buf))) \
9338 int_ret = EINA_FALSE; \
9342 if (r) *r = cc->cr; \
9343 if (g) *g = cc->cg; \
9344 if (b) *b = cc->cb; \
9345 if (a) *a = cc->ca; \
9347 int_ret = EINA_TRUE; \
9349 _elm_color_premul(alpha, r, g, b); \
9350 eina_stringshare_del(buf); \
9354 _elm_widget_item_color_class_update(Elm_Widget_Item_Data *sd)
9356 ELM_COLOR_CLASS_UPDATE(sd->view, sd->color_classes, (!sd) || (!sd->color_classes) || (!sd->view));
9359 /* Internal EO API */
9361 _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)
9363 ELM_COLOR_CLASS_SET_START(obj, r, g, b, a);
9365 int_ret &= _elm_widget_item_color_class_update(sd);
9367 ELM_COLOR_CLASS_SET_END();
9370 /* Internal EO API */
9372 _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)
9374 ELM_COLOR_CLASS_GET(obj, r, g, b, a);
9377 /* Internal EO API */
9379 _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)
9381 ELM_COLOR_CLASS_SET_START(obj, r2, g2, b2, a2);
9383 int_ret &= _elm_widget_item_color_class_update(sd);
9385 ELM_COLOR_CLASS_SET_END();
9388 /* Internal EO API */
9390 _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)
9392 ELM_COLOR_CLASS_GET(obj, r2, g2, b2, a2);
9395 /* Internal EO API */
9397 _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)
9399 ELM_COLOR_CLASS_SET_START(obj, r3, g3, b3, a3);
9401 int_ret &= _elm_widget_item_color_class_update(sd);
9403 ELM_COLOR_CLASS_SET_END();
9406 /* Internal EO API */
9408 _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)
9410 ELM_COLOR_CLASS_GET(obj, r3, g3, b3, a3);
9413 /* Internal EO API */
9414 static Evas_Object *
9415 _elm_widget_item_edje_get(const Eo *obj, Elm_Widget_Item_Data *sd)
9418 sd = efl_data_scope_get(obj, ELM_WIDGET_ITEM_CLASS);
9420 if (efl_isa(sd->view, EFL_UI_LAYOUT_BASE_CLASS))
9421 return elm_layout_edje_get(sd->view);
9422 else if (efl_isa(sd->view, EFL_CANVAS_LAYOUT_CLASS))
9428 /* Internal EO API */
9430 _elm_widget_item_class_color_del(Eo *obj EINA_UNUSED, Elm_Widget_Item_Data *sd, const char *color_class)
9432 Eina_Stringshare *buf;
9434 Edje_Color_Class *cc = NULL;
9436 if (!color_class) return;
9438 buf = _elm_widget_edje_class_get(obj, NULL, color_class);
9439 eina_hash_del(sd->color_classes, buf, cc);
9441 edje = _elm_widget_item_edje_get(obj, sd);
9443 edje_object_color_class_del(edje, buf);
9445 eina_stringshare_del(buf);
9448 /* Internal EO API */
9450 _elm_widget_item_class_color_clear(Eo *obj EINA_UNUSED, Elm_Widget_Item_Data *sd)
9453 ELM_SAFE_FREE(sd->color_classes, eina_hash_free);
9455 edje = _elm_widget_item_edje_get(obj, sd);
9458 edje_object_color_class_clear(edje);
9461 /* Internal EO APIs and hidden overrides */
9462 EAPI EFL_FUNC_BODYV(elm_widget_item_class_color_set, Eina_Bool, EINA_FALSE,
9463 EFL_FUNC_CALL(color_class, r, g, b, a),
9464 const char *color_class, int r, int g, int b, int a)
9465 EAPI EFL_FUNC_BODYV(elm_widget_item_class_color_get, Eina_Bool, EINA_FALSE,
9466 EFL_FUNC_CALL(color_class, r, g, b, a),
9467 const char *color_class, int *r, int *g, int *b, int *a)
9468 EAPI EFL_FUNC_BODYV(elm_widget_item_class_color2_set, Eina_Bool, EINA_FALSE,
9469 EFL_FUNC_CALL(color_class, r, g, b, a),
9470 const char *color_class, int r, int g, int b, int a)
9471 EAPI EFL_FUNC_BODYV(elm_widget_item_class_color2_get, Eina_Bool, EINA_FALSE,
9472 EFL_FUNC_CALL(color_class, r, g, b, a),
9473 const char *color_class, int *r, int *g, int *b, int *a)
9474 EAPI EFL_FUNC_BODYV(elm_widget_item_class_color3_set, Eina_Bool, EINA_FALSE,
9475 EFL_FUNC_CALL(color_class, r, g, b, a),
9476 const char *color_class, int r, int g, int b, int a)
9477 EAPI EFL_FUNC_BODYV(elm_widget_item_class_color3_get, Eina_Bool, EINA_FALSE,
9478 EFL_FUNC_CALL(color_class, r, g, b, a),
9479 const char *color_class, int *r, int *g, int *b, int *a)
9480 EAPI EFL_VOID_FUNC_BODYV(elm_widget_item_class_color_del,
9481 EFL_FUNC_CALL(color_class),
9482 const char *color_class)
9483 EAPI EFL_VOID_FUNC_BODY(elm_widget_item_class_color_clear)
9485 #define ELM_WIDGET_ITEM_EXTRA_OPS \
9486 EFL_OBJECT_OP_FUNC(elm_widget_item_class_color_set, _elm_widget_item_class_color_set), \
9487 EFL_OBJECT_OP_FUNC(elm_widget_item_class_color_get, _elm_widget_item_class_color_get), \
9488 EFL_OBJECT_OP_FUNC(elm_widget_item_class_color2_set, _elm_widget_item_class_color2_set), \
9489 EFL_OBJECT_OP_FUNC(elm_widget_item_class_color2_get, _elm_widget_item_class_color2_get), \
9490 EFL_OBJECT_OP_FUNC(elm_widget_item_class_color3_set, _elm_widget_item_class_color3_set), \
9491 EFL_OBJECT_OP_FUNC(elm_widget_item_class_color3_get, _elm_widget_item_class_color3_get), \
9492 EFL_OBJECT_OP_FUNC(elm_widget_item_class_color_del, _elm_widget_item_class_color_del), \
9493 EFL_OBJECT_OP_FUNC(elm_widget_item_class_color_clear, _elm_widget_item_class_color_clear)
9499 //TIZEN_ONLY(20180607): Restore legacy focus
9501 _if_focused_revert(Evas_Object *obj,
9502 Eina_Bool can_focus_only)
9505 Evas_Object *newest = NULL;
9506 unsigned int newest_focus_order = 0;
9510 if (!sd->focused) return;
9511 if (!sd->parent_obj) return;
9513 top = elm_widget_top_get(sd->parent_obj);
9516 newest = efl_ui_widget_newest_focus_order_get
9517 (top, &newest_focus_order, can_focus_only);
9522 ELM_WIDGET_DATA_GET(newest, sd2);
9525 if (!_is_focused(newest))
9526 efl_ui_widget_focus_steal(newest, NULL);
9529 if (sd2->resize_obj && _is_focused(sd2->resize_obj))
9530 efl_ui_widget_focused_object_clear(sd2->resize_obj);
9534 for (unsigned int i = 0; i < eina_array_count(sd2->children); ++i)
9536 child = eina_array_data_get(sd2->children, i);
9537 if (!_elm_widget_is(child)) continue;
9538 if (_is_focused(child))
9540 efl_ui_widget_focused_object_clear(child);
9546 evas_object_focus_set(newest, EINA_TRUE);
9550 if (_is_focused(newest))
9551 efl_ui_widget_focused_object_clear(newest);
9552 elm_object_focus_set(newest, EINA_TRUE);
9561 * Set custom focus chain.
9563 * This function i set one new and overwrite any previous custom focus chain
9564 * with the list of objects. The previous list will be deleted and this list
9565 * will be managed. After setted, don't modity it.
9567 * @note On focus cycle, only will be evaluated children of this container.
9569 * @param obj The container widget
9570 * @param objs Chain of objects to pass focus
9574 _efl_ui_widget_focus_custom_chain_set(Eo *obj, Elm_Widget_Smart_Data *sd, Eina_List *objs)
9576 if (!_elm_widget_focus_chain_manager_is(obj)) return;
9578 efl_ui_widget_focus_custom_chain_unset(obj);
9583 EINA_LIST_FOREACH(objs, l, o)
9585 evas_object_event_callback_add(o, EVAS_CALLBACK_DEL,
9586 _elm_object_focus_chain_del_cb, obj);
9589 sd->focus_chain = objs;
9595 * Get custom focus chain
9597 * @param obj The container widget
9600 EOLIAN static const Eina_List*
9601 _efl_ui_widget_focus_custom_chain_get(const Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd)
9603 return (const Eina_List *)sd->focus_chain;
9609 * Unset custom focus chain
9611 * @param obj The container widget
9615 _efl_ui_widget_focus_custom_chain_unset(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd)
9617 Eina_List *l, *l_next;
9620 EINA_LIST_FOREACH_SAFE(sd->focus_chain, l, l_next, o)
9622 evas_object_event_callback_del_full(o, EVAS_CALLBACK_DEL,
9623 _elm_object_focus_chain_del_cb, obj);
9624 sd->focus_chain = eina_list_remove_list(sd->focus_chain, l);
9631 * Append object to custom focus chain.
9633 * @note If relative_child equal to NULL or not in custom chain, the object
9634 * will be added in end.
9636 * @note On focus cycle, only will be evaluated children of this container.
9638 * @param obj The container widget
9639 * @param child The child to be added in custom chain
9640 * @param relative_child The relative object to position the child
9644 _efl_ui_widget_focus_custom_chain_append(Eo *obj, Elm_Widget_Smart_Data *sd, Evas_Object *child, Evas_Object *relative_child)
9646 EINA_SAFETY_ON_NULL_RETURN(child);
9648 if (!_elm_widget_focus_chain_manager_is(obj)) return;
9650 evas_object_event_callback_add(child, EVAS_CALLBACK_DEL,
9651 _elm_object_focus_chain_del_cb, obj);
9653 if (!relative_child)
9654 sd->focus_chain = eina_list_append(sd->focus_chain, child);
9656 sd->focus_chain = eina_list_append_relative(sd->focus_chain,
9657 child, relative_child);
9663 * Prepend object to custom focus chain.
9665 * @note If relative_child equal to NULL or not in custom chain, the object
9666 * will be added in begin.
9668 * @note On focus cycle, only will be evaluated children of this container.
9670 * @param obj The container widget
9671 * @param child The child to be added in custom chain
9672 * @param relative_child The relative object to position the child
9676 _efl_ui_widget_focus_custom_chain_prepend(Eo *obj, Elm_Widget_Smart_Data *sd, Evas_Object *child, Evas_Object *relative_child)
9678 EINA_SAFETY_ON_NULL_RETURN(child);
9680 if (!_elm_widget_focus_chain_manager_is(obj)) return;
9682 evas_object_event_callback_add(child, EVAS_CALLBACK_DEL,
9683 _elm_object_focus_chain_del_cb, obj);
9685 if (!relative_child)
9686 sd->focus_chain = eina_list_prepend(sd->focus_chain, child);
9688 sd->focus_chain = eina_list_prepend_relative(sd->focus_chain,
9689 child, relative_child);
9695 * Give focus to next object in object tree.
9697 * Give focus to next object in focus chain of one object sub-tree.
9698 * If the last object of chain already have focus, the focus will go to the
9699 * first object of chain.
9701 * @param obj The widget root of sub-tree
9702 * @param dir Direction to cycle the focus
9707 _efl_ui_widget_focus_cycle(Eo *obj, Elm_Widget_Smart_Data *_pd EINA_UNUSED, Efl_Ui_Focus_Direction dir)
9709 Evas_Object *target = NULL;
9710 Elm_Object_Item *target_item = NULL;
9711 if (!_elm_widget_is(obj))
9713 efl_ui_widget_focus_next_get(obj, dir, &target, &target_item);
9717 if (_elm_config->access_mode)
9719 /* highlight cycle does not steal a focus, only after window gets
9720 the ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_ACTIVATE message,
9721 target will steal focus, or focus its own job. */
9722 if (!_elm_access_auto_highlight_get())
9723 efl_ui_widget_focus_steal(target, target_item);
9725 _elm_access_highlight_set(target);
9726 elm_widget_focus_region_show(target);
9728 else efl_ui_widget_focus_steal(target, target_item);
9735 * Give focus to near object(in object tree) in one direction.
9737 * Give focus to near object(in object tree) in direction of current
9738 * focused object. If none focusable object in given direction or
9739 * none focused object in object tree, the focus will not change.
9741 * @param obj The reference widget
9742 * @param degree Degree changes clockwise. i.e. 0-degree: Up,
9743 * 90-degree: Right, 180-degree: Down, and 270-degree: Left
9744 * @return EINA_TRUE if focus is moved.
9748 EOLIAN static Eina_Bool
9749 _efl_ui_widget_focus_direction_go(Eo *obj, Elm_Widget_Smart_Data *_pd EINA_UNUSED, double degree)
9751 Evas_Object *target = NULL;
9752 Elm_Object_Item *target_item = NULL;
9753 Evas_Object *current_focused = NULL;
9754 double weight = 0.0;
9756 if (!_elm_widget_is(obj)) return EINA_FALSE;
9757 if (!_is_focused(obj)) return EINA_FALSE;
9759 current_focused = efl_ui_widget_focused_object_get(obj);
9761 if (efl_ui_widget_focus_direction_get
9762 (obj, current_focused, degree, &target, &target_item, &weight))
9764 efl_ui_widget_focus_steal(target, NULL);
9774 * Get near object in one direction of base object.
9776 * Get near object(in the object sub-tree) in one direction of
9777 * base object. Return the near object by reference.
9778 * By initializing weight, you can filter objects locating far
9779 * from base object. If object is in the specific direction,
9780 * weight is (1/(distance^2)). If object is not exactly in one
9781 * direction, some penalty will be added.
9783 * @param obj The widget root of sub-tree
9784 * @param base The base object of the direction
9785 * @param degree Degree changes clockwise. i.e. 0-degree: Up,
9786 * 90-degree: Right, 180-degree: Down, and 270-degree: Left
9787 * @param direction The near object in one direction
9788 * @param weight The weight is bigger when the object is located near
9789 * @return EINA_TRUE if near object is updated.
9794 EOLIAN static Eina_Bool
9795 _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)
9799 /* -1 means the best was already decided. Don't need any more searching. */
9800 if (!direction || !weight || !base || (obj == base))
9803 /* Ignore if disabled */
9804 if ((!evas_object_visible_get(obj))
9805 || (elm_widget_disabled_get(obj))
9806 || (elm_widget_tree_unfocusable_get(obj)))
9810 if (_internal_elm_widget_focus_direction_manager_is(obj))
9812 Eina_Bool int_ret = EINA_FALSE;
9813 int_ret = efl_ui_widget_focus_direction((Eo *)obj, base, degree, direction, direction_item, weight);
9817 if (!elm_widget_can_focus_get(obj) || _is_focused((Eo *)obj))
9820 c_weight = _elm_widget_focus_direction_weight_get(base, obj, degree);
9821 if ((c_weight == -1.0) ||
9822 ((c_weight != 0.0) && (*weight != -1.0) &&
9823 ((int)(*weight * 1000000) <= (int)(c_weight * 1000000))))
9826 ((int)(*weight * 1000000) == (int)(c_weight * 1000000)))
9828 ELM_WIDGET_DATA_GET(*direction, sd1);
9831 if (sd->focus_order <= sd1->focus_order)
9835 *direction = (Evas_Object *)obj;
9846 * Get near object in one direction of base object in list.
9848 * Get near object in one direction of base object in the specific
9849 * object list. Return the near object by reference.
9850 * By initializing weight, you can filter objects locating far
9851 * from base object. If object is in the specific direction,
9852 * weight is (1/(distance^2)). If object is not exactly in one
9853 * direction, some penalty will be added.
9855 * @param obj The widget root of sub-tree
9856 * @param base The base object of the direction
9857 * @param items list with ordered objects
9858 * @param list_data_get function to get the object from one item of list
9859 * @param degree Degree changes clockwise. i.e. 0-degree: Up,
9860 * 90-degree: Right, 180-degree: Down, and 270-degree: Left
9861 * @param direction The near object in one direction
9862 * @param weight The weight is bigger when the object is located near
9863 * @return EINA_TRUE if near object is updated.
9867 EOLIAN static Eina_Bool
9868 _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)
9870 if (!direction || !weight || !base || !items)
9873 const Eina_List *l = items;
9874 Evas_Object *current_best = *direction;
9876 for (; l; l = eina_list_next(l))
9878 Evas_Object *cur = ((list_data_get_func_type)list_data_get)(l);
9879 if (cur && _elm_widget_is(cur))
9880 efl_ui_widget_focus_direction_get(cur, base, degree, direction, direction_item, weight);
9882 if (current_best != *direction) return EINA_TRUE;
9890 * Get next object in focus chain of object tree.
9892 * Get next object in focus chain of one object sub-tree.
9893 * Return the next object by reference. If don't have any candidate to receive
9894 * focus before chain end, the first candidate will be returned.
9896 * @param obj The widget root of sub-tree
9897 * @param dir Direction of focus chain
9898 * @param next The next object in focus chain
9899 * @return EINA_TRUE if don't need focus chain restart/loop back
9900 * to use 'next' obj.
9904 EOLIAN static Eina_Bool
9905 _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)
9907 Elm_Access_Info *ac;
9913 /* Ignore if disabled */
9914 if (_elm_config->access_mode && _elm_access_auto_highlight_get())
9916 if (!evas_object_visible_get(obj)
9917 || (elm_widget_tree_unfocusable_get(obj)))
9922 if ((!evas_object_visible_get(obj))
9923 || (elm_widget_disabled_get(obj))
9924 || (elm_widget_tree_unfocusable_get(obj)))
9929 if (_elm_widget_focus_chain_manager_is(obj))
9931 Eina_Bool int_ret = EINA_FALSE;
9932 int_ret = efl_ui_widget_focus_next((Eo *)obj, dir, next, next_item);
9933 if (!int_ret && _is_focused((Eo *)obj))
9935 Evas_Object *o = NULL;
9936 if (dir == EFL_UI_FOCUS_DIRECTION_PREVIOUS)
9937 *next_item = sd->item_focus_previous;
9938 else if (dir == EFL_UI_FOCUS_DIRECTION_NEXT)
9939 *next_item = sd->item_focus_next;
9940 else if (dir == EFL_UI_FOCUS_DIRECTION_UP)
9941 *next_item = sd->item_focus_up;
9942 else if (dir == EFL_UI_FOCUS_DIRECTION_DOWN)
9943 *next_item = sd->item_focus_down;
9944 else if (dir == EFL_UI_FOCUS_DIRECTION_RIGHT)
9945 *next_item = sd->item_focus_right;
9946 else if (dir == EFL_UI_FOCUS_DIRECTION_LEFT)
9947 *next_item = sd->item_focus_left;
9949 o = elm_object_item_widget_get(*next_item);
9953 if (dir == EFL_UI_FOCUS_DIRECTION_PREVIOUS)
9954 o = sd->focus_previous;
9955 else if (dir == EFL_UI_FOCUS_DIRECTION_NEXT)
9957 else if (dir == EFL_UI_FOCUS_DIRECTION_UP)
9959 else if (dir == EFL_UI_FOCUS_DIRECTION_DOWN)
9961 else if (dir == EFL_UI_FOCUS_DIRECTION_RIGHT)
9962 o = sd->focus_right;
9963 else if (dir == EFL_UI_FOCUS_DIRECTION_LEFT)
9976 /* access object does not check sd->can_focus, because an object could
9977 have highlight even though the object is not focusable. */
9978 if (_elm_config->access_mode && _elm_access_auto_highlight_get())
9980 ac = _elm_access_info_get(obj);
9981 if (!ac) return EINA_FALSE;
9983 /* check whether the hover object is visible or not */
9984 if (!evas_object_visible_get(ac->hoverobj))
9987 else if (!elm_widget_can_focus_get(obj))
9990 if (_is_focused((Eo *)obj))
9992 if (dir == EFL_UI_FOCUS_DIRECTION_PREVIOUS)
9993 *next_item = sd->item_focus_previous;
9994 else if (dir == EFL_UI_FOCUS_DIRECTION_NEXT)
9995 *next_item = sd->item_focus_next;
9996 else if (dir == EFL_UI_FOCUS_DIRECTION_UP)
9997 *next_item = sd->item_focus_up;
9998 else if (dir == EFL_UI_FOCUS_DIRECTION_DOWN)
9999 *next_item = sd->item_focus_down;
10000 else if (dir == EFL_UI_FOCUS_DIRECTION_RIGHT)
10001 *next_item = sd->item_focus_right;
10002 else if (dir == EFL_UI_FOCUS_DIRECTION_LEFT)
10003 *next_item = sd->item_focus_left;
10004 if (*next_item) *next = elm_object_item_widget_get(*next_item);
10008 if (dir == EFL_UI_FOCUS_DIRECTION_PREVIOUS)
10009 *next = sd->focus_previous;
10010 else if (dir == EFL_UI_FOCUS_DIRECTION_NEXT)
10011 *next = sd->focus_next;
10012 else if (dir == EFL_UI_FOCUS_DIRECTION_UP)
10013 *next = sd->focus_up;
10014 else if (dir == EFL_UI_FOCUS_DIRECTION_DOWN)
10015 *next = sd->focus_down;
10016 else if (dir == EFL_UI_FOCUS_DIRECTION_RIGHT)
10017 *next = sd->focus_right;
10018 else if (dir == EFL_UI_FOCUS_DIRECTION_LEFT)
10019 *next = sd->focus_left;
10022 if (*next) return EINA_TRUE;
10026 *next = (Evas_Object *)obj;
10027 return !ELM_WIDGET_FOCUS_GET(obj);
10033 * Get next object in focus chain of object tree in list.
10035 * Get next object in focus chain of one object sub-tree ordered by one list.
10036 * Return the next object by reference. If don't have any candidate to receive
10037 * focus before list end, the first candidate will be returned.
10039 * @param obj The widget root of sub-tree
10040 * @param items list with ordered objects
10041 * @param list_data_get function to get the object from one item of list
10042 * @param dir Direction of focus chain
10043 * @param next The next object in focus chain
10044 * @return EINA_TRUE if don't need focus chain restart/loop back
10045 * to use 'next' obj.
10049 EOLIAN static Eina_Bool
10050 _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)
10052 Eina_List *(*list_next)(const Eina_List *list) = NULL;
10053 Evas_Object *focused_object = NULL;
10059 if (!_elm_widget_is(obj))
10065 /* When Up, Down, Right, or Left, try direction_get first. */
10066 focused_object = efl_ui_widget_focused_object_get(obj);
10067 if (focused_object)
10069 if ((dir == EFL_UI_FOCUS_DIRECTION_UP)
10070 || (dir == EFL_UI_FOCUS_DIRECTION_DOWN)
10071 || (dir == EFL_UI_FOCUS_DIRECTION_RIGHT)
10072 || (dir == EFL_UI_FOCUS_DIRECTION_LEFT))
10074 *next_item = efl_ui_widget_focus_next_item_get(focused_object, dir);
10076 *next = elm_object_item_widget_get(*next_item);
10078 *next = efl_ui_widget_focus_next_object_get(focused_object, dir);
10079 if (*next) return EINA_TRUE;
10082 Evas_Object *n = NULL;
10083 Elm_Object_Item *n_item = NULL;
10085 double weight = 0.0;
10087 if (dir == EFL_UI_FOCUS_DIRECTION_UP) degree = 0.0;
10088 else if (dir == EFL_UI_FOCUS_DIRECTION_DOWN) degree = 180.0;
10089 else if (dir == EFL_UI_FOCUS_DIRECTION_RIGHT) degree = 90.0;
10090 else if (dir == EFL_UI_FOCUS_DIRECTION_LEFT) degree = 270.0;
10092 if (efl_ui_widget_focus_list_direction_get(obj, focused_object,
10093 items, list_data_get,
10094 degree, &n, &n_item,
10097 *next_item = n_item;
10106 if (dir == EFL_UI_FOCUS_DIRECTION_PREVIOUS)
10108 items = eina_list_last(items);
10109 list_next = eina_list_prev;
10111 else if ((dir == EFL_UI_FOCUS_DIRECTION_NEXT)
10112 || (dir == EFL_UI_FOCUS_DIRECTION_UP)
10113 || (dir == EFL_UI_FOCUS_DIRECTION_DOWN)
10114 || (dir == EFL_UI_FOCUS_DIRECTION_RIGHT)
10115 || (dir == EFL_UI_FOCUS_DIRECTION_LEFT))
10116 list_next = eina_list_next;
10120 const Eina_List *l = items;
10122 /* Recovery last focused sub item */
10123 if (ELM_WIDGET_FOCUS_GET(obj))
10125 for (; l; l = list_next(l))
10127 Evas_Object *cur = ((list_data_get_func_type)list_data_get)(l);
10128 if (ELM_WIDGET_FOCUS_GET(cur)) break;
10131 /* Focused object, but no focused sub item */
10135 const Eina_List *start = l;
10136 Evas_Object *to_focus = NULL;
10137 Elm_Object_Item *to_focus_item = NULL;
10139 /* Iterate sub items */
10140 /* Go to the end of list */
10141 for (; l; l = list_next(l))
10143 Evas_Object *tmp = NULL;
10144 Elm_Object_Item *tmp_item = NULL;
10145 Evas_Object *cur = ((list_data_get_func_type)list_data_get)(l);
10147 if (!cur) continue;
10148 if (!_elm_widget_is(cur)) continue;
10149 if (elm_widget_parent_get(cur) != obj)
10152 /* Try Focus cycle in subitem */
10153 if (efl_ui_widget_focus_next_get(cur, dir, &tmp, &tmp_item))
10156 *next_item = tmp_item;
10159 else if ((dir == EFL_UI_FOCUS_DIRECTION_UP)
10160 || (dir == EFL_UI_FOCUS_DIRECTION_DOWN)
10161 || (dir == EFL_UI_FOCUS_DIRECTION_RIGHT)
10162 || (dir == EFL_UI_FOCUS_DIRECTION_LEFT))
10164 if (tmp && _is_focused(cur))
10167 *next_item = tmp_item;
10171 else if ((tmp) && (!to_focus))
10174 to_focus_item = tmp_item;
10180 /* Get First possible */
10181 for (; l != start; l = list_next(l))
10183 Evas_Object *tmp = NULL;
10184 Elm_Object_Item *tmp_item = NULL;
10185 Evas_Object *cur = ((list_data_get_func_type)list_data_get)(l);
10187 if (elm_widget_parent_get(cur) != obj)
10190 /* Try Focus cycle in subitem */
10191 efl_ui_widget_focus_next_get(cur, dir, &tmp, &tmp_item);
10195 *next_item = tmp_item;
10201 *next_item = to_focus_item;
10208 * Get next object which was set with specific focus direction.
10210 * Get next object which was set by elm_widget_focus_next_object_set
10211 * with specific focus directioin.
10213 * @param obj The widget
10214 * @param dir Direction of focus
10215 * @return Widget which was registered with sepecific focus direction.
10219 EOLIAN static Evas_Object*
10220 _efl_ui_widget_focus_next_object_get(const Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd, Efl_Ui_Focus_Direction dir)
10222 Evas_Object *ret = NULL;
10224 if (dir == EFL_UI_FOCUS_DIRECTION_PREVIOUS)
10225 ret = sd->focus_previous;
10226 else if (dir == EFL_UI_FOCUS_DIRECTION_NEXT)
10227 ret = sd->focus_next;
10228 else if (dir == EFL_UI_FOCUS_DIRECTION_UP)
10229 ret = sd->focus_up;
10230 else if (dir == EFL_UI_FOCUS_DIRECTION_DOWN)
10231 ret = sd->focus_down;
10232 else if (dir == EFL_UI_FOCUS_DIRECTION_RIGHT)
10233 ret = sd->focus_right;
10234 else if (dir == EFL_UI_FOCUS_DIRECTION_LEFT)
10235 ret = sd->focus_left;
10243 * Set next object with specific focus direction.
10245 * When a widget is set with specific focus direction, this widget will be
10246 * the first candidate when finding the next focus object.
10247 * Focus next object can be registered with six directions that are previous,
10248 * next, up, down, right, and left.
10250 * @param obj The widget
10251 * @param next Next focus object
10252 * @param dir Direction of focus
10257 _efl_ui_widget_focus_next_object_set(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd, Evas_Object *next, Efl_Ui_Focus_Direction dir)
10260 if (dir == EFL_UI_FOCUS_DIRECTION_PREVIOUS)
10261 sd->focus_previous = next;
10262 else if (dir == EFL_UI_FOCUS_DIRECTION_NEXT)
10263 sd->focus_next = next;
10264 else if (dir == EFL_UI_FOCUS_DIRECTION_UP)
10265 sd->focus_up = next;
10266 else if (dir == EFL_UI_FOCUS_DIRECTION_DOWN)
10267 sd->focus_down = next;
10268 else if (dir == EFL_UI_FOCUS_DIRECTION_RIGHT)
10269 sd->focus_right = next;
10270 else if (dir == EFL_UI_FOCUS_DIRECTION_LEFT)
10271 sd->focus_left = next;
10275 EOLIAN static Elm_Object_Item*
10276 _efl_ui_widget_focus_next_item_get(const Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd, Efl_Ui_Focus_Direction dir)
10278 Elm_Object_Item *ret = NULL;
10280 if (dir == EFL_UI_FOCUS_DIRECTION_PREVIOUS)
10281 ret = sd->item_focus_previous;
10282 else if (dir == EFL_UI_FOCUS_DIRECTION_NEXT)
10283 ret = sd->item_focus_next;
10284 else if (dir == EFL_UI_FOCUS_DIRECTION_UP)
10285 ret = sd->item_focus_up;
10286 else if (dir == EFL_UI_FOCUS_DIRECTION_DOWN)
10287 ret = sd->item_focus_down;
10288 else if (dir == EFL_UI_FOCUS_DIRECTION_RIGHT)
10289 ret = sd->item_focus_right;
10290 else if (dir == EFL_UI_FOCUS_DIRECTION_LEFT)
10291 ret = sd->item_focus_left;
10298 _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)
10300 if (dir == EFL_UI_FOCUS_DIRECTION_PREVIOUS)
10301 sd->item_focus_previous = next_item;
10302 else if (dir == EFL_UI_FOCUS_DIRECTION_NEXT)
10303 sd->item_focus_next = next_item;
10304 else if (dir == EFL_UI_FOCUS_DIRECTION_UP)
10305 sd->item_focus_up = next_item;
10306 else if (dir == EFL_UI_FOCUS_DIRECTION_DOWN)
10307 sd->item_focus_down = next_item;
10308 else if (dir == EFL_UI_FOCUS_DIRECTION_RIGHT)
10309 sd->item_focus_right = next_item;
10310 else if (dir == EFL_UI_FOCUS_DIRECTION_LEFT)
10311 sd->item_focus_left = next_item;
10315 elm_widget_focus_set(Eo *obj, Eina_Bool focus)
10317 ELM_WIDGET_DATA_GET_OR_RETURN(obj, sd);
10321 sd->focus_order = focus_order;
10322 sd->focused = EINA_TRUE;
10323 efl_ui_focus_object_on_focus_update(obj);
10328 if ((_is_focusable(sd->resize_obj)) &&
10329 (!elm_widget_disabled_get(sd->resize_obj)))
10331 elm_widget_focus_set(sd->resize_obj, focus);
10335 Evas_Object *child;
10337 for (unsigned int i = 0; i < eina_array_count(sd->children); ++i)
10339 child = eina_array_data_get(sd->children, i);
10340 if (!_elm_widget_is(child)) continue;
10341 if ((_is_focusable(child)) &&
10342 (!elm_widget_disabled_get(child)))
10344 elm_widget_focus_set(child, focus);
10352 Evas_Object *child;
10353 unsigned int i = eina_array_count(sd->children);
10358 child = eina_array_data_get(sd->children, i);
10359 if (!_elm_widget_is(child)) continue;
10360 if ((_is_focusable(child)) &&
10361 (!elm_widget_disabled_get(child)))
10363 elm_widget_focus_set(child, focus);
10372 _focused_object_clear(Elm_Widget_Smart_Data *sd)
10374 if (sd->resize_obj && elm_widget_is(sd->resize_obj) &&
10375 _is_focused(sd->resize_obj))
10377 efl_ui_widget_focused_object_clear(sd->resize_obj);
10381 Evas_Object *child;
10382 for (unsigned int i = 0; i < eina_array_count(sd->children); ++i)
10384 child = eina_array_data_get(sd->children, i);
10385 if (_elm_widget_is(child) && _is_focused(child))
10387 efl_ui_widget_focused_object_clear(child);
10395 _efl_ui_widget_focused_object_clear(Eo *obj, Elm_Widget_Smart_Data *sd)
10397 if (!sd->focused) return;
10398 _focused_object_clear(sd);
10399 sd->focused = EINA_FALSE;
10400 if (sd->top_win_focused)
10401 efl_ui_focus_object_on_focus_update(obj);
10405 _efl_ui_widget_focus_steal(Eo *obj, Elm_Widget_Smart_Data *sd, Elm_Object_Item *item)
10407 Evas_Object *parent, *parent2, *o;
10409 if (sd->focused) return;
10410 if (sd->disabled) return;
10411 if (!sd->can_focus) return;
10412 if (sd->tree_unfocusable) return;
10416 o = elm_widget_parent_get(parent);
10418 sd = efl_data_scope_get(o, MY_CLASS);
10419 if (sd->disabled || sd->tree_unfocusable) return;
10420 if (sd->focused) break;
10423 if ((!elm_widget_parent_get(parent)))
10424 efl_ui_widget_focused_object_clear(parent);
10427 parent2 = elm_widget_parent_get(parent);
10429 sd = efl_data_scope_get(parent, MY_CLASS);
10430 if (sd) _focused_object_clear(sd);
10432 _parent_focus(obj, item);
10433 elm_widget_focus_region_show(obj);
10438 _parents_on_focus(Evas_Object *obj)
10441 if (!sd->focused || !sd->top_win_focused) return;
10443 Evas_Object *o = elm_widget_parent_get(obj);
10444 if (o) _parents_on_focus(o);
10445 efl_ui_focus_object_on_focus_update(obj);
10449 _efl_ui_widget_focus_restore(Eo *obj, Elm_Widget_Smart_Data *_pd EINA_UNUSED)
10451 Evas_Object *newest = NULL;
10452 unsigned int newest_focus_order = 0;
10454 newest = efl_ui_widget_newest_focus_order_get(obj, &newest_focus_order, EINA_TRUE);
10456 _parents_on_focus(newest);
10462 * Check if the widget has its own focus next function.
10464 * @param obj The widget.
10465 * @return focus next function is implemented/unimplemented.
10466 * (@c EINA_TRUE = implemented/@c EINA_FALSE = unimplemented.)
10468 static inline Eina_Bool
10469 _elm_widget_focus_chain_manager_is(const Evas_Object *obj)
10471 ELM_WIDGET_CHECK(obj) EINA_FALSE;
10473 Eina_Bool manager_is = EINA_FALSE;
10474 manager_is = efl_ui_widget_focus_next_manager_is((Eo *)obj);
10478 static inline Eina_Bool
10479 _internal_elm_widget_focus_direction_manager_is(const Evas_Object *obj)
10481 ELM_WIDGET_CHECK(obj) EINA_FALSE;
10483 Eina_Bool manager_is = EINA_FALSE;
10484 manager_is = efl_ui_widget_focus_direction_manager_is((Eo *)obj);
10489 _parent_focus(Evas_Object *obj, Elm_Object_Item *item)
10493 if (sd->focused) return;
10495 Evas_Object *o = elm_widget_parent_get(obj);
10496 sd->focus_order_on_calc = EINA_TRUE;
10498 if (o) _parent_focus(o, item);
10500 if (!sd->focus_order_on_calc)
10501 return; /* we don't want to override it if by means of any of the
10502 callbacks below one gets to calculate our order
10506 sd->focus_order = focus_order;
10507 sd->focused = EINA_TRUE;
10509 if (sd->top_win_focused)
10510 efl_ui_focus_object_on_focus_update(obj);
10511 sd->focus_order_on_calc = EINA_FALSE;
10513 if (_elm_config->access_mode == ELM_ACCESS_MODE_ON)
10514 _elm_access_highlight_set(obj);
10518 _elm_object_focus_chain_del_cb(void *data,
10519 Evas *e EINA_UNUSED,
10521 void *event_info EINA_UNUSED)
10523 ELM_WIDGET_DATA_GET(data, sd);
10525 sd->focus_chain = eina_list_remove(sd->focus_chain, obj);
10528 //TIZEN_ONLY(20200117): transition duration factor for widget transition customize
10529 EOLIAN static Eina_Bool
10530 _efl_ui_widget_transition_duration_factor_set(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *pd , double duration)
10532 pd->transition_duration = duration;
10533 // the value need to be $true when widget have transition effect.
10537 EOLIAN static double
10538 _efl_ui_widget_transition_duration_factor_get(const Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *pd)
10540 return pd->transition_duration;
10544 //TIZEN_ONLT(20191218): efl_ui_widget: add widget_focus property to handle focus
10545 EOLIAN static Eina_Bool
10546 _efl_ui_widget_widget_focus_get(const Eo *obj, Elm_Widget_Smart_Data *pd EINA_UNUSED)
10548 return elm_object_focus_get(obj);
10552 _efl_ui_widget_widget_focus_set(Eo *obj, Elm_Widget_Smart_Data *pd EINA_UNUSED, Eina_Bool focus)
10555 elm_object_focus_set(obj, focus);
10559 #include "elm_widget_item_eo.c"
10560 #include "elm_widget_item_container_eo.c"
10561 #include "efl_ui_widget.eo.c"
10562 #include "efl_ui_widget_eo.legacy.c"
10565 #include "efl_ui_l10n.eo.c"