2 # include "elementary_config.h"
5 #define ELM_INTERFACE_ATSPI_ACCESSIBLE_PROTECTED
6 #define ELM_INTERFACE_ATSPI_COMPONENT_PROTECTED
7 #define ELM_INTERFACE_ATSPI_WIDGET_ACTION_PROTECTED
8 #define ELM_WIDGET_ITEM_PROTECTED
9 #include <Elementary.h>
12 #include "elm_widget_container.h"
13 #include "elm_interface_scrollable.h"
15 #define MY_CLASS ELM_WIDGET_CLASS
17 #define MY_CLASS_NAME "Elm_Widget"
18 #define MY_CLASS_NAME_LEGACY "elm_widget"
20 #define ELM_WIDGET_DATA_GET(o, wd) \
21 Elm_Widget_Smart_Data *wd = eo_data_scope_get(o, MY_CLASS)
24 ELM_WIDGET_DATA_GET(obj, sd); \
25 if ((!sd) || (!_elm_widget_is(obj)))
26 #define INTERNAL_ENTRY \
27 ELM_WIDGET_DATA_GET(obj, sd); \
30 #define ELM_WIDGET_FOCUS_GET(obj) \
31 (eo_isa(obj, ELM_WIDGET_CLASS) && \
32 ((_elm_access_auto_highlight_get()) ? (elm_widget_highlight_get(obj)) : \
33 (elm_widget_focus_get(obj))))
35 const char SIG_WIDGET_FOCUSED[] = "focused";
36 const char SIG_WIDGET_UNFOCUSED[] = "unfocused";
37 const char SIG_WIDGET_LANG_CHANGED[] = "language,changed";
38 const char SIG_WIDGET_ACCESS_CHANGED[] = "access,changed";
40 // TIZEN_ONLY(20161018): add highlighted/unhighlighted signal for atspi
41 const char SIG_WIDGET_ATSPI_HIGHLIGHTED[] = "atspi,highlighted";
42 const char SIG_WIDGET_ATSPI_UNHIGHLIGHTED[] = "atspi,unhighlighted";
45 typedef struct _Elm_Event_Cb_Data Elm_Event_Cb_Data;
46 typedef struct _Elm_Label_Data Elm_Label_Data;
47 typedef struct _Elm_Translate_String_Data Elm_Translate_String_Data;
49 struct _Elm_Event_Cb_Data
55 struct _Elm_Label_Data
61 struct _Elm_Translate_String_Data
65 Eina_Stringshare *domain;
66 Eina_Stringshare *string;
70 /* TIZEN_ONLY(20160622): Override Paragraph Direction APIs */
72 _elm_widget_evas_object_paragraph_direction_set_internal(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd, Evas_BiDi_Direction dir);
75 /* local subsystem globals */
76 static unsigned int focus_order = 0;
78 static inline Eina_Bool
79 _elm_widget_is(const Evas_Object *obj)
81 return eo_isa(obj, MY_CLASS);
84 static inline Eina_Bool
85 _is_focusable(Evas_Object *obj)
87 API_ENTRY return EINA_FALSE;
88 return sd->can_focus || (sd->child_can_focus);
91 static inline Eina_Bool
92 _is_focused(Evas_Object *obj)
94 API_ENTRY return EINA_FALSE;
98 static inline Eina_Bool
99 _elm_scrollable_is(const Evas_Object *obj)
101 INTERNAL_ENTRY EINA_FALSE;
103 eo_isa(obj, ELM_INTERFACE_SCROLLABLE_MIXIN);
107 elm_widget_disabled_internal(Eo *obj, Eina_Bool disabled);
109 _on_sub_obj_del(void *data,
111 const Eo_Event_Description *desc,
114 _on_sub_obj_hide(void *data,
116 const Eo_Event_Description *desc,
119 _propagate_event(void *data,
121 const Eo_Event_Description *desc,
124 EO_CALLBACKS_ARRAY_DEFINE(elm_widget_subitems_callbacks,
125 { EVAS_OBJECT_EVENT_DEL, _on_sub_obj_del },
126 { EVAS_OBJECT_EVENT_HIDE, _on_sub_obj_hide });
127 EO_CALLBACKS_ARRAY_DEFINE(efl_subitems_callbacks,
128 { EVAS_OBJECT_EVENT_DEL, _on_sub_obj_del });
129 EO_CALLBACKS_ARRAY_DEFINE(focus_callbacks,
130 { EVAS_OBJECT_EVENT_KEY_DOWN, _propagate_event },
131 { EVAS_OBJECT_EVENT_KEY_UP, _propagate_event },
132 { EVAS_OBJECT_EVENT_MOUSE_WHEEL, _propagate_event });
135 _callbacks_add(Eo *widget, void *data)
137 if (_elm_widget_is(widget))
140 eo_event_callback_array_add(elm_widget_subitems_callbacks(), data));
145 eo_event_callback_array_add(efl_subitems_callbacks(), data));
150 _callbacks_del(Eo *widget, void *data)
152 if (_elm_widget_is(widget))
155 eo_event_callback_array_del(elm_widget_subitems_callbacks(), data));
160 eo_event_callback_array_del(efl_subitems_callbacks(), data));
165 _elm_widget_item_highlight_in_theme(Evas_Object *obj, Elm_Object_Item *eo_it)
170 if (eo_isa(eo_it, ELM_WIDGET_ITEM_CLASS))
172 Elm_Widget_Item_Data *it = eo_data_scope_get(eo_it, ELM_WIDGET_ITEM_CLASS);
174 if (eo_isa(it->view, ELM_LAYOUT_CLASS))
175 str = edje_object_data_get(elm_layout_edje_get(it->view), "focus_highlight");
177 str = edje_object_data_get(it->view, "focus_highlight");
180 str = edje_object_data_get(((Elm_Widget_Item_Data *)eo_it)->view, "focus_highlight");
181 if ((str) && (!strcmp(str, "on")))
182 elm_widget_highlight_in_theme_set(obj, EINA_TRUE);
184 elm_widget_highlight_in_theme_set(obj, EINA_FALSE);
188 _elm_widget_focus_highlight_start(const Evas_Object *obj)
190 Evas_Object *top = elm_widget_top_get(obj);
192 if (top && eo_isa(top, ELM_WIN_CLASS))
193 _elm_win_focus_highlight_start(top);
197 _elm_widget_focus_highlight_object_get(const Evas_Object *obj)
199 Evas_Object *top = elm_widget_top_get(obj);
201 if (top && eo_isa(top, ELM_WIN_CLASS))
202 return _elm_win_focus_highlight_object_get(top);
207 elm_widget_focus_highlight_enabled_get(const Evas_Object *obj)
209 const Evas_Object *win = elm_widget_top_get(obj);
211 if (win && eo_isa(win, ELM_WIN_CLASS))
212 return elm_win_focus_highlight_enabled_get(win);
219 * Resets the mirrored mode from the system mirror mode for widgets that are in
220 * automatic mirroring mode. This function does not call elm_widget_theme.
222 * @param obj The widget.
223 * @param mirrored EINA_TRUE to set mirrored mode. EINA_FALSE to unset.
226 _elm_widget_mirrored_reload(Evas_Object *obj)
229 Eina_Bool mirrored = elm_config_mirrored_get();
231 if (elm_widget_mirrored_automatic_get(obj) && (sd->is_mirrored != mirrored))
233 sd->is_mirrored = mirrored;
237 EOLIAN static Eina_Bool
238 _elm_widget_on_focus_region(Eo *obj, Elm_Widget_Smart_Data *_pd EINA_UNUSED, Evas_Coord *x EINA_UNUSED, Evas_Coord *y EINA_UNUSED, Evas_Coord *w EINA_UNUSED, Evas_Coord *h EINA_UNUSED)
240 WRN("The %s widget does not implement the \"on_focus_region\" function.",
241 eo_class_name_get(eo_class_get(obj)));
247 _parents_focus(Evas_Object *obj)
249 for (; obj; obj = elm_widget_parent_get(obj))
252 if (sd->focused) return;
258 _parents_unfocus(Evas_Object *obj)
260 for (; obj; obj = elm_widget_parent_get(obj))
263 if (!sd->focused) return;
269 _on_sub_obj_hide(void *data EINA_UNUSED,
271 const Eo_Event_Description *desc EINA_UNUSED,
272 void *event_info EINA_UNUSED)
274 elm_widget_focus_hide_handle(obj);
275 return EO_CALLBACK_CONTINUE;
279 _on_sub_obj_del(void *data,
281 const Eo_Event_Description *desc EINA_UNUSED,
282 void *event_info EINA_UNUSED)
284 ELM_WIDGET_DATA_GET_OR_RETURN(data, sd, EINA_FALSE);
286 if (_elm_widget_is(obj))
288 if (_is_focused((Eo *)obj)) _parents_unfocus(sd->obj);
290 if (obj == sd->resize_obj)
292 /* already dels sub object */
293 elm_widget_resize_object_set(sd->obj, NULL, EINA_TRUE);
295 else if (obj == sd->hover_obj)
297 sd->hover_obj = NULL;
301 if (!elm_widget_sub_object_del(sd->obj, obj))
302 ERR("failed to remove sub object %p from %p\n", obj, sd->obj);
305 return EO_CALLBACK_CONTINUE;
308 static const Evas_Smart_Cb_Description _smart_callbacks[] =
310 {SIG_WIDGET_FOCUSED, ""},
311 {SIG_WIDGET_UNFOCUSED, ""},
312 {SIG_WIDGET_LANG_CHANGED, ""},
313 {SIG_WIDGET_ACCESS_CHANGED, ""},
314 // TIZEN_ONLY(20161018): add highlighted/unhighlighted signal for atspi
315 {SIG_WIDGET_ATSPI_HIGHLIGHTED, ""},
316 {SIG_WIDGET_ATSPI_UNHIGHLIGHTED, ""},
322 _obj_mouse_down(void *data,
324 Evas_Object *obj EINA_UNUSED,
329 ELM_WIDGET_DATA_GET(data, sd);
330 Evas_Event_Mouse_Down *ev = event_info;
331 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return;
333 top = elm_widget_top_get(data);
334 if (top && eo_isa(top, ELM_WIN_CLASS)) _elm_win_focus_auto_hide(top);
335 sd->still_in = EINA_TRUE;
339 _obj_mouse_move(void *data,
344 ELM_WIDGET_DATA_GET(data, sd);
345 Evas_Event_Mouse_Move *ev = event_info;
346 if (!sd->still_in) return;
348 if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD)
349 sd->still_in = EINA_FALSE;
352 Evas_Coord x, y, w, h;
353 evas_object_geometry_get(obj, &x, &y, &w, &h);
354 if (ELM_RECTS_POINT_OUT(x, y, w, h, ev->cur.canvas.x, ev->cur.canvas.y))
355 sd->still_in = EINA_FALSE;
360 _obj_mouse_up(void *data,
363 void *event_info EINA_UNUSED)
365 ELM_WIDGET_DATA_GET(data, sd);
367 (sd->focus_move_policy == ELM_FOCUS_MOVE_POLICY_CLICK))
368 elm_widget_focus_mouse_up_handle(obj);
370 sd->still_in = EINA_FALSE;
374 _obj_mouse_in(void *data,
377 void *event_info EINA_UNUSED)
379 ELM_WIDGET_DATA_GET(data, sd);
380 if (sd->focus_move_policy == ELM_FOCUS_MOVE_POLICY_IN)
381 elm_widget_focus_mouse_up_handle(obj);
385 _elm_widget_evas_object_smart_add(Eo *obj, Elm_Widget_Smart_Data *priv)
389 priv->mirrored_auto_mode = EINA_TRUE; /* will follow system locale
391 priv->focus_move_policy_auto_mode = EINA_TRUE;
392 priv->focus_region_show_mode = ELM_FOCUS_REGION_SHOW_WIDGET;
393 elm_widget_can_focus_set(obj, EINA_TRUE);
394 priv->is_mirrored = elm_config_mirrored_get();
395 priv->focus_move_policy = _elm_config->focus_move_policy;
397 evas_object_event_callback_add(obj, EVAS_CALLBACK_MOUSE_DOWN,
398 _obj_mouse_down, obj);
399 evas_object_event_callback_add(obj, EVAS_CALLBACK_MOUSE_MOVE,
400 _obj_mouse_move, obj);
401 evas_object_event_callback_add(obj, EVAS_CALLBACK_MOUSE_UP,
403 evas_object_event_callback_add(obj, EVAS_CALLBACK_MOUSE_IN,
405 /* just a helper for inheriting classes */
406 if (priv->resize_obj)
408 Evas_Object *r_obj = priv->resize_obj;
409 priv->resize_obj = NULL;
411 elm_widget_resize_object_set(obj, r_obj, EINA_TRUE);
416 _if_focused_revert(Evas_Object *obj,
417 Eina_Bool can_focus_only)
420 Evas_Object *newest = NULL;
421 unsigned int newest_focus_order = 0;
425 if (!sd->focused) return;
426 if (!sd->parent_obj) return;
428 top = elm_widget_top_get(sd->parent_obj);
431 newest = elm_widget_newest_focus_order_get
432 (top, &newest_focus_order, can_focus_only);
437 ELM_WIDGET_DATA_GET(newest, sd2);
440 if (!_is_focused(newest))
441 elm_widget_focus_steal(newest, NULL);
444 if (sd2->resize_obj && _is_focused(sd2->resize_obj))
445 elm_widget_focused_object_clear(sd2->resize_obj);
450 EINA_LIST_FOREACH(sd2->subobjs, l, child)
452 if (_is_focused(child))
454 elm_widget_focused_object_clear(child);
460 evas_object_focus_set(newest, EINA_TRUE);
464 elm_object_focus_set(newest, EINA_FALSE);
465 elm_object_focus_set(newest, EINA_TRUE);
472 _elm_widget_evas_object_smart_del(Eo *obj, Elm_Widget_Smart_Data *sd)
475 Elm_Translate_String_Data *ts;
476 Elm_Event_Cb_Data *ecb;
480 /* detach it from us */
481 _callbacks_del(sd->hover_obj, obj);
482 sd->hover_obj = NULL;
487 sobj = eina_list_data_get(sd->subobjs);
489 /* let the objects clean-up themselves and get rid of this list */
490 if (!elm_widget_sub_object_del(obj, sobj))
492 ERR("failed to remove sub object %p from %p\n", sobj, obj);
493 sd->subobjs = eina_list_remove_list
494 (sd->subobjs, sd->subobjs);
496 evas_object_del(sobj);
498 sd->tooltips = eina_list_free(sd->tooltips); /* should be empty anyway */
499 sd->cursors = eina_list_free(sd->cursors); /* should be empty anyway */
500 while (sd->translate_strings)
502 ts = EINA_INLIST_CONTAINER_GET(sd->translate_strings,
503 Elm_Translate_String_Data);
504 eina_stringshare_del(ts->id);
505 eina_stringshare_del(ts->domain);
506 eina_stringshare_del(ts->string);
507 sd->translate_strings = eina_inlist_remove(sd->translate_strings,
508 sd->translate_strings);
512 EINA_LIST_FREE(sd->event_cb, ecb)
515 eina_stringshare_del(sd->style);
516 if (sd->theme) elm_theme_free(sd->theme);
517 _if_focused_revert(obj, EINA_TRUE);
518 elm_widget_focus_custom_chain_unset(obj);
519 eina_stringshare_del(sd->access_info);
520 eina_stringshare_del(sd->accessible_name);
521 evas_object_smart_data_set(obj, NULL);
525 _smart_reconfigure(Elm_Widget_Smart_Data *sd)
529 evas_object_move(sd->resize_obj, sd->x, sd->y);
530 evas_object_resize(sd->resize_obj, sd->w, sd->h);
534 evas_object_move(sd->hover_obj, sd->x, sd->y);
535 evas_object_resize(sd->hover_obj, sd->w, sd->h);
540 _elm_widget_evas_object_smart_move(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd, Evas_Coord x, Evas_Coord y)
545 _smart_reconfigure(sd);
549 _elm_widget_evas_object_smart_resize(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd, Evas_Coord w, Evas_Coord h)
554 _smart_reconfigure(sd);
558 _elm_widget_evas_object_smart_show(Eo *obj, Elm_Widget_Smart_Data *_pd EINA_UNUSED)
563 if (_elm_atspi_enabled())
566 eo_do(obj, parent = elm_interface_atspi_accessible_parent_get());
567 if (parent) elm_interface_atspi_accessible_children_changed_added_signal_emit(parent, obj);
570 it = evas_object_smart_iterator_new(obj);
571 EINA_ITERATOR_FOREACH(it, o)
573 if (evas_object_data_get(o, "_elm_leaveme")) continue;
576 eina_iterator_free(it);
578 if (_elm_atspi_enabled())
580 elm_interface_atspi_accessible_added(obj);
581 if (_elm_widget_onscreen_is(obj))
582 elm_interface_atspi_accessible_state_changed_signal_emit(obj, ELM_ATSPI_STATE_SHOWING, EINA_TRUE);
587 _elm_widget_evas_object_smart_hide(Eo *obj, Elm_Widget_Smart_Data *_pd EINA_UNUSED)
592 it = evas_object_smart_iterator_new(obj);
593 EINA_ITERATOR_FOREACH(it, o)
595 if (evas_object_data_get(o, "_elm_leaveme")) continue;
598 eina_iterator_free(it);
600 if (_elm_atspi_enabled())
602 //TIZEN_ONLY(20161223) check if the parent of highlighted object is hide
604 highlighted_obj = _elm_object_accessibility_currently_highlighted_get();
605 if (highlighted_obj && highlighted_obj != obj)
608 eo_do(highlighted_obj, parent = elm_interface_atspi_accessible_parent_get());
613 elm_interface_atspi_accessible_state_changed_signal_emit(highlighted_obj, ELM_ATSPI_STATE_SHOWING, EINA_FALSE);
614 eo_do(highlighted_obj, elm_interface_atspi_component_highlight_clear());
617 eo_do(parent, parent = elm_interface_atspi_accessible_parent_get());
622 elm_interface_atspi_accessible_state_changed_signal_emit(obj, ELM_ATSPI_STATE_SHOWING, EINA_FALSE);
627 _elm_widget_evas_object_smart_color_set(Eo *obj, Elm_Widget_Smart_Data *_pd EINA_UNUSED, int r, int g, int b, int a)
632 it = evas_object_smart_iterator_new(obj);
633 EINA_ITERATOR_FOREACH(it, o)
635 if (evas_object_data_get(o, "_elm_leaveme")) continue;
636 evas_object_color_set(o, r, g, b, a);
638 eina_iterator_free(it);
642 _elm_widget_evas_object_smart_clip_set(Eo *obj, Elm_Widget_Smart_Data *_pd EINA_UNUSED, Evas_Object *clip)
647 it = evas_object_smart_iterator_new(obj);
648 EINA_ITERATOR_FOREACH(it, o)
650 if (evas_object_data_get(o, "_elm_leaveme")) continue;
651 evas_object_clip_set(o, clip);
653 eina_iterator_free(it);
657 _elm_widget_evas_object_smart_clip_unset(Eo *obj, Elm_Widget_Smart_Data *_pd EINA_UNUSED)
662 it = evas_object_smart_iterator_new(obj);
663 EINA_ITERATOR_FOREACH(it, o)
665 if (evas_object_data_get(o, "_elm_leaveme")) continue;
666 evas_object_clip_unset(o);
668 eina_iterator_free(it);
672 _elm_widget_evas_object_smart_calculate(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *_pd EINA_UNUSED)
674 /* a NO-OP, on the base */
678 _elm_widget_evas_object_smart_member_add(Eo *obj, Elm_Widget_Smart_Data *_pd EINA_UNUSED, Evas_Object *child)
681 eo_do_super(obj, MY_CLASS, evas_obj_smart_member_add(child));
683 if (evas_object_data_get(child, "_elm_leaveme")) return;
685 evas_object_color_get(obj, &r, &g, &b, &a);
686 evas_object_color_set(child, r, g, b, a);
688 evas_object_clip_set(child, evas_object_clip_get(obj));
690 if (evas_object_visible_get(obj))
691 evas_object_show(child);
693 evas_object_hide(child);
697 _elm_widget_evas_object_smart_member_del(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *_pd EINA_UNUSED, Evas_Object *child)
699 if (!evas_object_data_get(child, "_elm_leaveme"))
700 evas_object_clip_unset(child);
701 eo_do_super(obj, MY_CLASS, evas_obj_smart_member_del(child));
708 * Check if the widget has its own focus next function.
710 * @param obj The widget.
711 * @return focus next function is implemented/unimplemented.
712 * (@c EINA_TRUE = implemented/@c EINA_FALSE = unimplemented.)
714 static inline Eina_Bool
715 _elm_widget_focus_chain_manager_is(const Evas_Object *obj)
717 ELM_WIDGET_CHECK(obj) EINA_FALSE;
719 Eina_Bool manager_is = EINA_FALSE;
720 eo_do((Eo *)obj, manager_is = elm_obj_widget_focus_next_manager_is());
724 static inline Eina_Bool
725 _internal_elm_widget_focus_direction_manager_is(const Evas_Object *obj)
727 ELM_WIDGET_CHECK(obj) EINA_FALSE;
729 Eina_Bool manager_is = EINA_FALSE;
730 eo_do((Eo *)obj, manager_is = elm_obj_widget_focus_direction_manager_is());
735 _propagate_x_drag_lock(Evas_Object *obj,
741 ELM_WIDGET_DATA_GET(sd->parent_obj, sd2);
744 sd2->child_drag_x_locked += dir;
745 _propagate_x_drag_lock(sd->parent_obj, dir);
751 _propagate_y_drag_lock(Evas_Object *obj,
757 ELM_WIDGET_DATA_GET(sd->parent_obj, sd2);
760 sd2->child_drag_y_locked += dir;
761 _propagate_y_drag_lock(sd->parent_obj, dir);
767 _propagate_event(void *data EINA_UNUSED,
769 const Eo_Event_Description *desc,
772 INTERNAL_ENTRY EO_CALLBACK_CONTINUE;
773 Evas_Callback_Type type;
774 Evas_Event_Flags *event_flags = NULL;
776 if (desc == EVAS_OBJECT_EVENT_KEY_DOWN)
778 Evas_Event_Key_Down *ev = event_info;
779 event_flags = &(ev->event_flags);
780 type = EVAS_CALLBACK_KEY_DOWN;
782 else if (desc == EVAS_OBJECT_EVENT_KEY_UP)
784 Evas_Event_Key_Up *ev = event_info;
785 event_flags = &(ev->event_flags);
786 type = EVAS_CALLBACK_KEY_UP;
788 else if (desc == EVAS_OBJECT_EVENT_MOUSE_WHEEL)
790 Evas_Event_Mouse_Wheel *ev = event_info;
791 event_flags = &(ev->event_flags);
792 type = EVAS_CALLBACK_MOUSE_WHEEL;
795 return EO_CALLBACK_CONTINUE;
797 elm_widget_event_propagate(obj, type, event_info, event_flags);
799 return EO_CALLBACK_CONTINUE;
805 * If elm_widget_focus_region_get() returns EINA_FALSE, this function will
806 * ignore region show action.
809 _elm_widget_focus_region_show(const Eo *obj, Elm_Widget_Smart_Data *_pd EINA_UNUSED)
811 Evas_Coord x, y, w, h, ox, oy;
814 o = elm_widget_parent_get(obj);
817 if (!elm_widget_focus_region_get(obj, &x, &y, &w, &h))
820 evas_object_geometry_get(obj, &ox, &oy, NULL, NULL);
825 evas_object_geometry_get(o, &px, &py, NULL, NULL);
827 if (_elm_scrollable_is(o) && !elm_widget_disabled_get(o))
830 eo_do(o, elm_interface_scrollable_content_region_get(&sx, &sy, NULL, NULL));
832 // Get the object's on_focus_region position relative to the scroller.
834 rx = ox + x - px + sx;
835 ry = oy + y - py + sy;
837 switch (_elm_config->focus_autoscroll_mode)
839 case ELM_FOCUS_AUTOSCROLL_MODE_SHOW:
840 eo_do(o, elm_interface_scrollable_content_region_show(rx, ry, w, h));
842 case ELM_FOCUS_AUTOSCROLL_MODE_BRING_IN:
843 eo_do(o, elm_interface_scrollable_region_bring_in(rx, ry, w, h));
849 elm_widget_focus_region_get(o, &x, &y, &w, &h);
850 evas_object_geometry_get(o, &ox, &oy, NULL, NULL);
859 o = elm_widget_parent_get(o);
863 EOLIAN static Eina_Bool
864 _elm_widget_focus_highlight_style_set(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd, const char *style)
866 if (eina_stringshare_replace(&sd->focus_highlight_style, style)) return EINA_TRUE;
870 EOLIAN static const char*
871 _elm_widget_focus_highlight_style_get(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd)
873 return sd->focus_highlight_style;
877 _parent_focus(Evas_Object *obj, Elm_Object_Item *item)
881 if (sd->focused) return;
883 Evas_Object *o = elm_widget_parent_get(obj);
884 sd->focus_order_on_calc = EINA_TRUE;
886 if (o) _parent_focus(o, item);
888 if (!sd->focus_order_on_calc)
889 return; /* we don't want to override it if by means of any of the
890 callbacks below one gets to calculate our order
894 sd->focus_order = focus_order;
895 sd->focused = EINA_TRUE;
897 if (sd->top_win_focused)
898 eo_do(obj, elm_obj_widget_on_focus(item));
899 sd->focus_order_on_calc = EINA_FALSE;
901 if (_elm_config->access_mode == ELM_ACCESS_MODE_ON)
902 _elm_access_highlight_set(obj);
906 _elm_object_focus_chain_del_cb(void *data,
909 void *event_info EINA_UNUSED)
911 ELM_WIDGET_DATA_GET(data, sd);
913 sd->focus_chain = eina_list_remove(sd->focus_chain, obj);
917 _elm_widget_parent_set(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *_pd EINA_UNUSED, Evas_Object *parent EINA_UNUSED)
922 elm_widget_api_check(int ver)
924 if (ver != ELM_INTERNAL_API_VERSION)
926 CRI("Elementary widget api versions do not match");
933 elm_widget_access(Evas_Object *obj,
938 Eina_Bool ret = EINA_TRUE;
940 API_ENTRY return EINA_FALSE;
941 EINA_LIST_FOREACH(sd->subobjs, l, child)
943 if (elm_widget_is(child))
944 ret &= elm_widget_access(child, is_access);
947 eo_do(obj, elm_obj_widget_access(is_access));
948 eo_do(obj, eo_event_callback_call(ELM_WIDGET_EVENT_ACCESS_CHANGED, NULL));
953 //TIZEN_ONLY(20160822): When atspi mode is dynamically switched on/off,
954 //register/unregister access objects accordingly.
955 // TIZEN_ONLY(20170516): connect to at-spi dbus based on org.a11y.Status.IsEnabled property
957 elm_widget_screen_reader(Evas_Object *obj,
958 Eina_Bool is_screen_reader)
962 Eina_Bool ret = EINA_TRUE;
964 API_ENTRY return EINA_FALSE;
965 EINA_LIST_FOREACH(sd->subobjs, l, child)
967 if (elm_widget_is(child))
968 ret &= elm_widget_screen_reader(child, is_screen_reader);
970 eo_do(obj, elm_obj_widget_screen_reader(is_screen_reader));
976 _elm_widget_screen_reader(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *_pd EINA_UNUSED, Eina_Bool is_screen_reader EINA_UNUSED)
980 //TIZEN_ONLY(20170621) handle atspi proxy connection at runtime
982 elm_widget_atspi(Evas_Object *obj, Eina_Bool is_atspi)
984 Eina_List *l, *children;
986 Eina_Bool ret = EINA_TRUE;
988 API_ENTRY return EINA_FALSE;
989 eo_do(obj, children = elm_interface_atspi_accessible_children_get());
990 EINA_LIST_FOREACH(children, l, child)
992 ret &= elm_widget_atspi(child, is_atspi);
994 eo_do(obj, elm_obj_widget_atspi(is_atspi));
1000 _elm_widget_atspi(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *_pd EINA_UNUSED, Eina_Bool is_atspi EINA_UNUSED)
1008 _elm_widget_access(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *_pd EINA_UNUSED, Eina_Bool is_access EINA_UNUSED)
1012 EAPI Elm_Theme_Apply
1013 elm_widget_theme(Evas_Object *obj)
1019 Elm_Theme_Apply ret = ELM_THEME_APPLY_SUCCESS;
1021 API_ENTRY return ELM_THEME_APPLY_FAILED;
1023 EINA_LIST_FOREACH(sd->subobjs, l, child)
1024 if (_elm_widget_is(child))
1025 ret &= elm_widget_theme(child);
1027 if (sd->hover_obj) ret &= elm_widget_theme(sd->hover_obj);
1029 EINA_LIST_FOREACH(sd->tooltips, l, tt)
1030 elm_tooltip_theme(tt);
1031 EINA_LIST_FOREACH(sd->cursors, l, cur)
1032 elm_cursor_theme(cur);
1034 Elm_Theme_Apply ret2 = ELM_THEME_APPLY_FAILED;
1035 eo_do(obj, ret2 = elm_obj_widget_theme_apply());
1042 elm_widget_theme_specific(Evas_Object *obj,
1050 Elm_Theme *th2, *thdef;
1054 thdef = elm_theme_default_get();
1055 if (!th) th = thdef;
1059 if (!th2) th2 = thdef;
1067 if (th2 == thdef) break;
1068 th2 = th2->ref_theme;
1069 if (!th2) th2 = thdef;
1073 EINA_LIST_FOREACH(sd->subobjs, l, child)
1075 if (elm_widget_is(child))
1076 elm_widget_theme_specific(child, th, force);
1078 if (sd->hover_obj) elm_widget_theme(sd->hover_obj);
1079 EINA_LIST_FOREACH(sd->tooltips, l, tt)
1080 elm_tooltip_theme(tt);
1081 EINA_LIST_FOREACH(sd->cursors, l, cur)
1082 elm_cursor_theme(cur);
1083 eo_do(obj, elm_obj_widget_theme_apply());
1086 EOLIAN static Elm_Theme_Apply
1087 _elm_widget_theme_apply(Eo *obj, Elm_Widget_Smart_Data *_pd EINA_UNUSED)
1089 _elm_widget_mirrored_reload(obj);
1090 if (elm_widget_disabled_get(obj))
1091 elm_widget_disabled_internal(obj, elm_widget_disabled_get(obj));
1093 return ELM_THEME_APPLY_SUCCESS;
1099 * Returns the widget's mirrored mode.
1101 * @param obj The widget.
1102 * @return mirrored mode of the object.
1105 EOLIAN static Eina_Bool
1106 _elm_widget_mirrored_get(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd)
1108 return sd->is_mirrored;
1114 * Sets the widget's mirrored mode.
1116 * @param obj The widget.
1117 * @param mirrored EINA_TRUE to set mirrored mode. EINA_FALSE to unset.
1120 _elm_widget_mirrored_set(Eo *obj, Elm_Widget_Smart_Data *sd, Eina_Bool mirrored)
1122 mirrored = !!mirrored;
1124 if (sd->is_mirrored == mirrored) return;
1126 sd->is_mirrored = mirrored;
1127 elm_widget_theme(obj);
1131 * Returns the widget's mirrored mode setting.
1133 * @param obj The widget.
1134 * @return mirrored mode setting of the object.
1137 EOLIAN static Eina_Bool
1138 _elm_widget_mirrored_automatic_get(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd)
1140 return sd->mirrored_auto_mode;
1146 * Sets the widget's mirrored mode setting.
1147 * When widget in automatic mode, it follows the system mirrored mode set by
1148 * elm_mirrored_set().
1149 * @param obj The widget.
1150 * @param automatic EINA_TRUE for auto mirrored mode. EINA_FALSE for manual.
1153 _elm_widget_mirrored_automatic_set(Eo *obj, Elm_Widget_Smart_Data *sd, Eina_Bool automatic)
1155 if (sd->mirrored_auto_mode != automatic)
1157 sd->mirrored_auto_mode = automatic;
1161 elm_widget_mirrored_set(obj, elm_config_mirrored_get());
1167 _elm_widget_on_show_region_hook_set(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd, region_hook_func_type func, void *data)
1169 sd->on_show_region = func;
1170 sd->on_show_region_data = data;
1176 * Add myself as a sub object of parent object
1178 * @see elm_widget_sub_object_add()
1181 elm_widget_sub_object_parent_add(Evas_Object *sobj)
1183 Eina_Bool ret = EINA_FALSE;
1186 eo_do(sobj, parent = eo_parent_get());
1187 if (!eo_isa(parent, ELM_WIDGET_CLASS))
1189 ERR("You passed a wrong parent parameter (%p %s). "
1190 "Elementary widget's parent should be an elementary widget.", parent, evas_object_type_get(parent));
1194 eo_do(parent, ret = elm_obj_widget_sub_object_add(sobj));
1202 * Add sobj to obj's sub object.
1204 * What does elementary sub object mean? This is unique in elementary, it
1205 * handles overall elementary policies between parent and sub objects.
1206 * focus, access, deletion, theme, scale, mirror, scrollable child get,
1207 * translate, name find, display mode set, orientation set, tree dump
1210 * @see elm_widget_sub_object_parent_add()
1212 EOLIAN static Eina_Bool
1213 _elm_widget_sub_object_add(Eo *obj, Elm_Widget_Smart_Data *sd, Evas_Object *sobj)
1215 Eina_Bool mirrored, pmirrored = elm_widget_mirrored_get(obj);
1217 EINA_SAFETY_ON_TRUE_RETURN_VAL(obj == sobj, EINA_FALSE);
1219 if (sobj == sd->parent_obj)
1221 /* in this case, sobj must be an elm widget, or something
1222 * very wrong is happening */
1223 if (!_elm_widget_is(sobj)) return EINA_FALSE;
1225 if (!elm_widget_sub_object_del(sobj, obj)) return EINA_FALSE;
1226 WRN("You passed a parent object of obj = %p as the sub object = %p!",
1230 if (_elm_widget_is(sobj))
1232 ELM_WIDGET_DATA_GET(sobj, sdc);
1234 if (sdc->parent_obj == obj) goto end;
1235 if (sdc->parent_obj)
1237 if (!elm_widget_sub_object_del(sdc->parent_obj, sobj))
1240 sdc->parent_obj = obj;
1242 if (!sdc->on_create)
1243 eo_do(sobj, elm_obj_widget_orientation_set(sd->orient_mode));
1245 sdc->orient_mode = sd->orient_mode;
1247 if (!sdc->on_create)
1249 if (!sdc->disabled && (elm_widget_disabled_get(obj)))
1251 elm_widget_focus_disabled_handle(sobj);
1252 eo_do(sobj, elm_obj_widget_disable());
1256 _elm_widget_top_win_focused_set(sobj, sd->top_win_focused);
1258 /* update child focusable-ness on self and parents, now that a
1259 * focusable child got in */
1260 if (!sd->child_can_focus && (_is_focusable(sobj)))
1262 Elm_Widget_Smart_Data *sdp = sd;
1264 sdp->child_can_focus = EINA_TRUE;
1265 while (sdp->parent_obj)
1267 sdp = eo_data_scope_get(sdp->parent_obj, MY_CLASS);
1269 if (sdp->child_can_focus) break;
1271 sdp->child_can_focus = EINA_TRUE;
1277 void *data = evas_object_data_get(sobj, "elm-parent");
1281 if (data == obj) goto end;
1282 if (!elm_widget_sub_object_del(data, sobj)) return EINA_FALSE;
1285 sd->subobjs = eina_list_append(sd->subobjs, sobj);
1286 evas_object_data_set(sobj, "elm-parent", obj);
1288 _callbacks_add(sobj, obj);
1289 if (_elm_widget_is(sobj))
1291 ELM_WIDGET_DATA_GET(sobj, sdc);
1293 /* NOTE: In the following two lines, 'sobj' is correct. Do not change it.
1294 * Due to elementary's scale policy, scale and pscale can be different in
1295 * some cases. This happens when sobj's previous parent and new parent have
1296 * different scale value.
1297 * For example, if sobj's previous parent's scale is 5 and new parent's scale
1298 * is 2 while sobj's scale is 0. Then 'pscale' is 5 and 'scale' is 2. So we
1299 * need to reset sobj's scale to 5.
1300 * Note that each widget's scale is 0 by default.
1302 double scale, pscale = elm_widget_scale_get(sobj);
1303 Elm_Theme *th, *pth = elm_widget_theme_get(sobj);
1305 scale = elm_widget_scale_get(sobj);
1306 th = elm_widget_theme_get(sobj);
1307 mirrored = elm_widget_mirrored_get(sobj);
1309 if (!sdc->on_create)
1311 if ((scale != pscale) || (th != pth) || (pmirrored != mirrored))
1312 elm_widget_theme(sobj);
1315 if (_is_focused(sobj)) _parents_focus(obj);
1317 elm_widget_display_mode_set(sobj,
1318 evas_object_size_hint_display_mode_get(obj));
1319 if (_elm_atspi_enabled() && !sdc->on_create)
1321 Elm_Interface_Atspi_Accessible *aparent;
1322 eo_do(sobj, aparent = elm_interface_atspi_accessible_parent_get());
1324 elm_interface_atspi_accessible_children_changed_added_signal_emit(obj, sobj);
1327 /* TIZEN_ONLY(20160622): Override Paragraph Direction APIs */
1328 if (sdc->inherit_paragraph_direction &&
1329 (sdc->paragraph_direction != evas_object_paragraph_direction_get(obj)))
1331 sdc->paragraph_direction = evas_object_paragraph_direction_get(obj);
1332 _elm_widget_evas_object_paragraph_direction_set_internal(sobj, sdc, sdc->paragraph_direction);
1333 eo_do_super(sobj, MY_CLASS, evas_obj_paragraph_direction_set(sdc->paragraph_direction));
1342 EOLIAN static Eina_Bool
1343 _elm_widget_sub_object_del(Eo *obj, Elm_Widget_Smart_Data *sd, Evas_Object *sobj)
1345 Evas_Object *sobj_parent;
1347 if (!sobj) return EINA_FALSE;
1349 EINA_SAFETY_ON_TRUE_RETURN_VAL(obj == sobj, EINA_FALSE);
1351 sobj_parent = evas_object_data_del(sobj, "elm-parent");
1352 if (sobj_parent && sobj_parent != obj)
1354 static int abort_on_warn = -1;
1356 ERR("removing sub object %p (%s) from parent %p (%s), "
1357 "but elm-parent is different %p (%s)!",
1358 sobj, elm_widget_type_get(sobj), obj, elm_widget_type_get(obj),
1359 sobj_parent, elm_widget_type_get(sobj_parent));
1361 if (EINA_UNLIKELY(abort_on_warn == -1))
1363 if (getenv("ELM_ERROR_ABORT")) abort_on_warn = 1;
1364 else abort_on_warn = 0;
1366 if (abort_on_warn == 1) abort();
1371 if (_elm_widget_is(sobj))
1373 if (_is_focused(sobj))
1375 elm_widget_tree_unfocusable_set(sobj, EINA_TRUE);
1376 elm_widget_tree_unfocusable_set(sobj, EINA_FALSE);
1378 if ((sd->child_can_focus) && (_is_focusable(sobj)))
1380 Evas_Object *parent = obj;
1382 /* update child focusable-ness on self and parents, now that a
1383 * focusable child is gone */
1387 Evas_Object *subobj;
1389 ELM_WIDGET_DATA_GET(parent, sdp);
1391 sdp->child_can_focus = EINA_FALSE;
1392 EINA_LIST_FOREACH(sdp->subobjs, l, subobj)
1394 if ((subobj != sobj) && (_is_focusable(subobj)))
1396 sdp->child_can_focus = EINA_TRUE;
1401 /* break again, child_can_focus went back to
1403 if (sdp->child_can_focus) break;
1404 parent = sdp->parent_obj;
1407 if (_elm_atspi_enabled() && !sd->on_destroy)
1409 Elm_Interface_Atspi_Accessible *aparent;
1410 eo_do(sobj, aparent = elm_interface_atspi_accessible_parent_get());
1412 elm_interface_atspi_accessible_children_changed_del_signal_emit(obj, sobj);
1415 ELM_WIDGET_DATA_GET(sobj, sdc);
1416 sdc->parent_obj = NULL;
1418 /* TIZEN_ONLY(20160622): Override Paragraph Direction APIs */
1419 if (sdc->inherit_paragraph_direction &&
1420 (sdc->paragraph_direction != EVAS_BIDI_DIRECTION_NEUTRAL))
1422 sdc->paragraph_direction = EVAS_BIDI_DIRECTION_NEUTRAL;
1423 _elm_widget_evas_object_paragraph_direction_set_internal(sobj, sdc, sdc->paragraph_direction);
1424 eo_do_super(sobj, MY_CLASS, evas_obj_paragraph_direction_set(EVAS_BIDI_DIRECTION_NEUTRAL));
1429 if (sd->resize_obj == sobj) sd->resize_obj = NULL;
1431 sd->subobjs = eina_list_remove(sd->subobjs, sobj);
1433 _callbacks_del(sobj, obj);
1441 * a resize object is added to and deleted from the smart member and the sub object
1442 * of the parent if the third argument, Eina_Bool sub_obj, is set as EINA_TRUE.
1445 _elm_widget_resize_object_set(Eo *obj, Elm_Widget_Smart_Data *sd,
1449 Evas_Object *parent;
1451 if (sd->resize_obj == sobj) return;
1453 // orphan previous resize obj
1454 if (sd->resize_obj && sub_obj)
1456 evas_object_clip_unset(sd->resize_obj);
1457 evas_object_smart_member_del(sd->resize_obj);
1459 if (_elm_widget_is(sd->resize_obj))
1461 if (_is_focused(sd->resize_obj)) _parents_unfocus(obj);
1463 elm_widget_sub_object_del(obj, sd->resize_obj);
1466 sd->resize_obj = sobj;
1469 // orphan new resize obj
1470 parent = evas_object_data_get(sobj, "elm-parent");
1471 if (parent && parent != obj)
1473 ELM_WIDGET_DATA_GET(parent, sdp);
1475 /* should be there, just being paranoid */
1478 if (sdp->resize_obj == sobj)
1479 elm_widget_resize_object_set(parent, NULL, sub_obj);
1481 elm_widget_sub_object_del(parent, sobj);
1486 elm_widget_sub_object_add(obj, sobj);
1487 evas_object_smart_member_add(sobj, obj);
1490 _smart_reconfigure(sd);
1496 * WARNING: the programmer is responsible, in the scenario of
1497 * exchanging a hover object, of cleaning the old hover "target"
1501 _elm_widget_hover_object_set(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd, Evas_Object *sobj)
1505 _callbacks_del(sd->hover_obj, obj);
1507 sd->hover_obj = sobj;
1510 _callbacks_add(sobj, obj);
1511 _smart_reconfigure(sd);
1516 _elm_widget_can_focus_set(Eo *obj, Elm_Widget_Smart_Data *sd, Eina_Bool can_focus)
1518 can_focus = !!can_focus;
1520 if (sd->can_focus == can_focus) return;
1521 sd->can_focus = can_focus;
1524 /* update child_can_focus of parents */
1525 Evas_Object *o = obj;
1529 o = elm_widget_parent_get(o);
1531 sd = eo_data_scope_get(o, MY_CLASS);
1532 if (!sd || sd->child_can_focus) break;
1533 sd->child_can_focus = EINA_TRUE;
1536 eo_do(obj, eo_event_callback_array_add(focus_callbacks(), NULL));
1540 // update child_can_focus of parents */
1541 Evas_Object *parent = elm_widget_parent_get(obj);
1545 Evas_Object *subobj;
1547 ELM_WIDGET_DATA_GET(parent, sdp);
1549 sdp->child_can_focus = EINA_FALSE;
1550 EINA_LIST_FOREACH(sdp->subobjs, l, subobj)
1552 if (_is_focusable(subobj))
1554 sdp->child_can_focus = EINA_TRUE;
1558 /* break again, child_can_focus went back to
1560 if (sdp->child_can_focus) break;
1561 parent = sdp->parent_obj;
1563 eo_do(obj, eo_event_callback_array_del(focus_callbacks(), NULL));
1567 EOLIAN static Eina_Bool
1568 _elm_widget_can_focus_get(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd)
1570 return sd->can_focus;
1573 EOLIAN static Eina_Bool
1574 _elm_widget_child_can_focus_get(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd)
1576 return sd->child_can_focus;
1582 * This API makes the widget object and its children to be unfocusable.
1584 * This API can be helpful for an object to be deleted.
1585 * When an object will be deleted soon, it and its children may not
1586 * want to get focus (by focus reverting or by other focus controls).
1587 * Then, just use this API before deleting.
1589 * @param obj The widget root of sub-tree
1590 * @param tree_unfocusable If true, set the object sub-tree as unfocusable
1595 _elm_widget_tree_unfocusable_set(Eo *obj, Elm_Widget_Smart_Data *sd, Eina_Bool tree_unfocusable)
1597 tree_unfocusable = !!tree_unfocusable;
1598 if (sd->tree_unfocusable == tree_unfocusable) return;
1599 sd->tree_unfocusable = tree_unfocusable;
1600 elm_widget_focus_tree_unfocusable_handle(obj);
1606 * This returns true, if the object sub-tree is unfocusable.
1608 * @param obj The widget root of sub-tree
1609 * @return EINA_TRUE if the object sub-tree is unfocusable
1613 EOLIAN static Eina_Bool
1614 _elm_widget_tree_unfocusable_get(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd)
1616 return sd->tree_unfocusable;
1622 * Get the list of focusable child objects.
1624 * This function retruns list of child objects which can get focus.
1626 * @param obj The parent widget
1627 * @retrun list of focusable child objects.
1631 EOLIAN static Eina_List*
1632 _elm_widget_can_focus_child_list_get(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd)
1635 Eina_List *child_list = NULL;
1638 EINA_LIST_FOREACH(sd->subobjs, l, child)
1640 if (!_elm_widget_is(child)) continue;
1641 if ((elm_widget_can_focus_get(child)) &&
1642 (evas_object_visible_get(child)) &&
1643 (!elm_widget_disabled_get(child)))
1644 child_list = eina_list_append(child_list, child);
1647 Eina_List *can_focus_list;
1648 can_focus_list = elm_widget_can_focus_child_list_get(child);
1650 child_list = eina_list_merge(child_list, can_focus_list);
1658 _elm_widget_highlight_ignore_set(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd, Eina_Bool ignore)
1660 sd->highlight_ignore = !!ignore;
1663 EOLIAN static Eina_Bool
1664 _elm_widget_highlight_ignore_get(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd)
1666 return sd->highlight_ignore;
1670 _elm_widget_highlight_in_theme_set(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd, Eina_Bool highlight)
1672 sd->highlight_in_theme = !!highlight;
1673 /* FIXME: if focused, it should switch from one mode to the other */
1677 _elm_widget_highlight_in_theme_update(Eo *obj)
1679 Evas_Object *top = elm_widget_top_get(obj);
1681 if (top && eo_isa(top, ELM_WIN_CLASS))
1683 _elm_win_focus_highlight_in_theme_update(
1684 top, elm_widget_highlight_in_theme_get(obj));
1688 EOLIAN static Eina_Bool
1689 _elm_widget_highlight_in_theme_get(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd)
1691 return sd->highlight_in_theme;
1695 _elm_widget_access_highlight_in_theme_set(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd, Eina_Bool highlight)
1697 sd->access_highlight_in_theme = !!highlight;
1700 EOLIAN static Eina_Bool
1701 _elm_widget_access_highlight_in_theme_get(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd)
1703 return sd->access_highlight_in_theme;
1706 EOLIAN static Eina_Bool
1707 _elm_widget_focus_get(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd)
1709 return (sd->focused && sd->top_win_focused);
1712 EOLIAN static Eina_Bool
1713 _elm_widget_highlight_get(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd)
1715 return sd->highlighted;
1718 EOLIAN static Evas_Object*
1719 _elm_widget_focused_object_get(Eo *obj, Elm_Widget_Smart_Data *sd)
1721 const Evas_Object *subobj;
1724 if (!sd->focused || !sd->top_win_focused) return NULL;
1725 EINA_LIST_FOREACH(sd->subobjs, l, subobj)
1728 if (!_elm_widget_is(subobj)) continue;
1729 fobj = elm_widget_focused_object_get(subobj);
1730 if (fobj) return fobj;
1732 return (Evas_Object *)obj;
1735 EOLIAN static Evas_Object*
1736 _elm_widget_top_get(Eo *obj, Elm_Widget_Smart_Data *sd)
1740 Evas_Object *ret = NULL;
1741 if (!eo_isa(sd->parent_obj, ELM_WIDGET_CLASS)) return NULL;
1742 eo_do((Eo *) sd->parent_obj, ret = elm_obj_widget_top_get());
1745 return (Evas_Object *)obj;
1749 elm_widget_is(const Evas_Object *obj)
1751 return _elm_widget_is(obj);
1755 elm_widget_parent_widget_get(const Evas_Object *obj)
1757 Evas_Object *parent;
1759 if (_elm_widget_is(obj))
1761 ELM_WIDGET_DATA_GET(obj, sd);
1762 if (!sd) return NULL;
1763 parent = sd->parent_obj;
1767 parent = evas_object_data_get(obj, "elm-parent");
1768 if (!parent) parent = evas_object_smart_parent_get(obj);
1773 Evas_Object *elm_parent;
1774 if (_elm_widget_is(parent)) break;
1775 elm_parent = evas_object_data_get(parent, "elm-parent");
1776 if (elm_parent) parent = elm_parent;
1777 else parent = evas_object_smart_parent_get(parent);
1782 EOLIAN static Evas_Object *
1783 _elm_widget_parent2_get(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd)
1789 _elm_widget_parent2_set(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd, Evas_Object *parent)
1791 sd->parent2 = parent;
1795 _elm_widget_event_callback_add(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd, Elm_Event_Cb func, const void *data)
1797 EINA_SAFETY_ON_NULL_RETURN(func);
1799 Elm_Event_Cb_Data *ecb = ELM_NEW(Elm_Event_Cb_Data);
1802 ERR("Failed to allocate memory");
1807 sd->event_cb = eina_list_append(sd->event_cb, ecb);
1811 _elm_widget_event_callback_del(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd, Elm_Event_Cb func, const void *data)
1813 EINA_SAFETY_ON_NULL_RETURN_VAL(func, NULL);
1815 Elm_Event_Cb_Data *ecd;
1816 EINA_LIST_FOREACH(sd->event_cb, l, ecd)
1817 if ((ecd->func == func) && (ecd->data == data))
1820 sd->event_cb = eina_list_remove_list(sd->event_cb, l);
1821 return (void *)data;
1827 EOLIAN static Eina_Bool
1828 _elm_widget_event_propagate(Eo *obj, Elm_Widget_Smart_Data *_pd EINA_UNUSED, Evas_Callback_Type type, void *event_info, Evas_Event_Flags *event_flags)
1830 Evas_Object *parent = obj;
1831 Elm_Event_Cb_Data *ecd;
1832 Eina_List *l, *l_prev;
1835 (!(event_flags && ((*event_flags) & EVAS_EVENT_FLAG_ON_HOLD))))
1837 ELM_WIDGET_CHECK(parent) EINA_FALSE;
1838 Elm_Widget_Smart_Data *sd = eo_data_scope_get(parent, MY_CLASS);
1840 Eina_Bool int_ret = EINA_FALSE;
1842 if (elm_widget_disabled_get(obj))
1844 parent = sd->parent_obj;
1848 eo_do(parent, int_ret = elm_obj_widget_event(obj, type, event_info));
1849 if (int_ret) return EINA_TRUE;
1851 EINA_LIST_FOREACH_SAFE(sd->event_cb, l, l_prev, ecd)
1853 if (ecd->func((void *)ecd->data, parent, obj, type, event_info) ||
1854 (event_flags && ((*event_flags) & EVAS_EVENT_FLAG_ON_HOLD)))
1857 parent = sd->parent_obj;
1866 * Set custom focus chain.
1868 * This function i set one new and overwrite any previous custom focus chain
1869 * with the list of objects. The previous list will be deleted and this list
1870 * will be managed. After setted, don't modity it.
1872 * @note On focus cycle, only will be evaluated children of this container.
1874 * @param obj The container widget
1875 * @param objs Chain of objects to pass focus
1879 _elm_widget_focus_custom_chain_set(Eo *obj, Elm_Widget_Smart_Data *sd, Eina_List *objs)
1881 if (!_elm_widget_focus_chain_manager_is(obj)) return;
1883 elm_widget_focus_custom_chain_unset(obj);
1888 EINA_LIST_FOREACH(objs, l, o)
1890 evas_object_event_callback_add(o, EVAS_CALLBACK_DEL,
1891 _elm_object_focus_chain_del_cb, obj);
1894 sd->focus_chain = objs;
1900 * Get custom focus chain
1902 * @param obj The container widget
1905 EOLIAN static const Eina_List*
1906 _elm_widget_focus_custom_chain_get(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd)
1908 return (const Eina_List *)sd->focus_chain;
1914 * Unset custom focus chain
1916 * @param obj The container widget
1920 _elm_widget_focus_custom_chain_unset(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd)
1922 Eina_List *l, *l_next;
1925 EINA_LIST_FOREACH_SAFE(sd->focus_chain, l, l_next, o)
1927 evas_object_event_callback_del_full(o, EVAS_CALLBACK_DEL,
1928 _elm_object_focus_chain_del_cb, obj);
1929 sd->focus_chain = eina_list_remove_list(sd->focus_chain, l);
1936 * Append object to custom focus chain.
1938 * @note If relative_child equal to NULL or not in custom chain, the object
1939 * will be added in end.
1941 * @note On focus cycle, only will be evaluated children of this container.
1943 * @param obj The container widget
1944 * @param child The child to be added in custom chain
1945 * @param relative_child The relative object to position the child
1949 _elm_widget_focus_custom_chain_append(Eo *obj, Elm_Widget_Smart_Data *sd, Evas_Object *child, Evas_Object *relative_child)
1951 EINA_SAFETY_ON_NULL_RETURN(child);
1953 if (!_elm_widget_focus_chain_manager_is(obj)) return;
1955 evas_object_event_callback_add(child, EVAS_CALLBACK_DEL,
1956 _elm_object_focus_chain_del_cb, obj);
1958 if (!relative_child)
1959 sd->focus_chain = eina_list_append(sd->focus_chain, child);
1961 sd->focus_chain = eina_list_append_relative(sd->focus_chain,
1962 child, relative_child);
1968 * Prepend object to custom focus chain.
1970 * @note If relative_child equal to NULL or not in custom chain, the object
1971 * will be added in begin.
1973 * @note On focus cycle, only will be evaluated children of this container.
1975 * @param obj The container widget
1976 * @param child The child to be added in custom chain
1977 * @param relative_child The relative object to position the child
1981 _elm_widget_focus_custom_chain_prepend(Eo *obj, Elm_Widget_Smart_Data *sd, Evas_Object *child, Evas_Object *relative_child)
1983 EINA_SAFETY_ON_NULL_RETURN(child);
1985 if (!_elm_widget_focus_chain_manager_is(obj)) return;
1987 evas_object_event_callback_add(child, EVAS_CALLBACK_DEL,
1988 _elm_object_focus_chain_del_cb, obj);
1990 if (!relative_child)
1991 sd->focus_chain = eina_list_prepend(sd->focus_chain, child);
1993 sd->focus_chain = eina_list_prepend_relative(sd->focus_chain,
1994 child, relative_child);
2000 * Give focus to next object in object tree.
2002 * Give focus to next object in focus chain of one object sub-tree.
2003 * If the last object of chain already have focus, the focus will go to the
2004 * first object of chain.
2006 * @param obj The widget root of sub-tree
2007 * @param dir Direction to cycle the focus
2012 _elm_widget_focus_cycle(Eo *obj, Elm_Widget_Smart_Data *_pd EINA_UNUSED, Elm_Focus_Direction dir)
2014 Evas_Object *target = NULL;
2015 Elm_Object_Item *target_item = NULL;
2016 if (!_elm_widget_is(obj))
2018 elm_widget_focus_next_get(obj, dir, &target, &target_item);
2022 if (_elm_config->access_mode)
2024 /* highlight cycle does not steal a focus, only after window gets
2025 the ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_ACTIVATE message,
2026 target will steal focus, or focus its own job. */
2027 if (!_elm_access_auto_highlight_get())
2028 elm_widget_focus_steal(target, target_item);
2030 _elm_access_highlight_set(target);
2031 elm_widget_focus_region_show(target);
2033 else elm_widget_focus_steal(target, target_item);
2040 * Give focus to near object(in object tree) in one direction.
2042 * Give focus to near object(in object tree) in direction of current
2043 * focused object. If none focusable object in given direction or
2044 * none focused object in object tree, the focus will not change.
2046 * @param obj The reference widget
2047 * @param degree Degree changes clockwise. i.e. 0-degree: Up,
2048 * 90-degree: Right, 180-degree: Down, and 270-degree: Left
2049 * @return EINA_TRUE if focus is moved.
2053 EOLIAN static Eina_Bool
2054 _elm_widget_focus_direction_go(Eo *obj, Elm_Widget_Smart_Data *_pd EINA_UNUSED, double degree)
2056 Evas_Object *target = NULL;
2057 Elm_Object_Item *target_item = NULL;
2058 Evas_Object *current_focused = NULL;
2059 double weight = 0.0;
2061 if (!_elm_widget_is(obj)) return EINA_FALSE;
2062 if (!_is_focused(obj)) return EINA_FALSE;
2064 current_focused = elm_widget_focused_object_get(obj);
2066 if (elm_widget_focus_direction_get
2067 (obj, current_focused, degree, &target, &target_item, &weight))
2069 elm_widget_focus_steal(target, NULL);
2077 _elm_widget_focus_direction_weight_get(const Evas_Object *obj1,
2078 const Evas_Object *obj2,
2081 Evas_Coord obj_x1, obj_y1, w1, h1, obj_x2, obj_y2, w2, h2;
2082 double x1, yy1, x2, yy2, xx1, yyy1, xx2, yyy2;
2083 double ax, ay, cx, cy;
2084 double weight = -1.0, g = 0.0;
2086 if (obj1 == obj2) return 0.0;
2089 while (degree >= 360.0)
2091 while (degree < 0.0)
2094 evas_object_geometry_get(obj1, &obj_x1, &obj_y1, &w1, &h1);
2095 cx = obj_x1 + (w1 / 2.0);
2096 cy = obj_y1 + (h1 / 2.0);
2097 evas_object_geometry_get(obj2, &obj_x2, &obj_y2, &w2, &h2);
2099 /* For overlapping cases. */
2100 if (ELM_RECTS_INTERSECT(obj_x1, obj_y1, w1, h1, obj_x2, obj_y2, w2, h2))
2103 /* Change all points to relative one. */
2113 /* Get crossing points (ax, ay) between obj1 and a line extending
2114 * to the direction of current degree. */
2120 else if (degree == 90.0)
2125 else if (degree == 180.0)
2130 else if (degree == 270.0)
2137 g = tan(degree * (M_PI / 180.0));
2138 if ((degree > 0.0) && (degree < 90.0))
2141 if (ay <= yyy1) ax = xx1;
2148 else if ((degree > 90.0) && (degree < 180.0))
2151 if (ay <= yyy1) ax = x1;
2158 else if ((degree > 180.0) && (degree < 270.0))
2161 if (ay >= yy1) ax = x1;
2171 if (ay >= yy1) ax = xx1;
2180 /* Filter obj2, if it is not in the specific derection. */
2182 double rx[4] = {0.0, 0.0, 0.0, 0.0}, ry[4] = {0.0, 0.0, 0.0, 0.0};
2183 double t1, t2, u1, v1, u2, v2;
2185 if ((degree == 45.0) || (degree == 225.0) || (degree == 135.0) ||
2195 double g2 = tan((degree + 45.0) * (M_PI / 180.0));
2200 t1 = (u1 * ax) + (v1 * ay);
2201 t2 = (u2 * ax) + (v2 * ay);
2203 #define _R(x) (int)((x + 0.05) * 10.0)
2205 if ((_R(t1 * ((u1 * x2) + (v1 * yy2))) > 0) && (_R(t2 * ((u2 * x2) +
2211 if ((_R(t1 * ((u1 * x2) + (v1 * yyy2))) > 0) && (_R(t2 * ((u2 * x2) +
2217 if ((_R(t1 * ((u1 * xx2) + (v1 * yy2))) > 0) && (_R(t2 * ((u2 * xx2) +
2223 if ((_R(t1 * ((u1 * xx2) + (v1 * yyy2))) > 0) &&
2224 (_R(t2 * ((u2 * xx2) + (v2 * yyy2))) > 0))
2233 if ((_R(xx2) < 0) || (_R(yy2) > 0) || (_R(yyy2) < 0)) return 0.0;
2235 else if (degree == 90.0)
2237 if ((_R(yyy2) < 0) || (_R(x2) > 0) || (_R(xx2) < 0)) return 0.0;
2239 else if (degree == 180.0)
2241 if ((_R(x2) > 0) || (_R(yy2) > 0) || (_R(yyy2) < 0)) return 0.0;
2243 else if (degree == 270.0)
2245 if ((_R(yy2) > 0) || (_R(x2) > 0) || (_R(xx2) < 0)) return 0.0;
2249 if ((_R(g * x2) >= _R(yy2)) && (_R((g * x2)) <= _R(yyy2)))
2251 if (!((_R(ax * x2) > 0) && (_R(ay * (g * x2)) > 0)))
2254 else if ((_R(g * xx2) >= _R(yy2)) && (_R((g * xx2)) <= _R(yyy2)))
2256 if (!((_R(ax * xx2) > 0) && (_R(ay * (g * xx2)) > 0)))
2259 else if ((_R((1.0 / g) * yy2) >= _R(xx2)) && (_R((1.0 / g) * yy2)
2262 if (!((_R(ax * ((1.0 / g) * yy2)) > 0)
2263 && (_R(ay * yy2) > 0)))
2266 else if ((_R((1.0 / g) * yyy2) >= _R(xx2)) &&
2267 (_R((1.0 / g) * yyy2) <= _R(xx2)))
2269 if (!((_R(ax * ((1.0 / g) * yyy2)) > 0)
2270 && (_R(ay * yyy2) > 0))) return 0.0;
2276 /* Calculate the weight for obj2. */
2279 if (_R(xx1) > _R(x2)) weight = -1.0;
2280 else if ((_R(yy2) >= _R(yy1)) && (_R(yyy2) <= _R(yyy1)))
2281 weight = (x2 - xx1) * (x2 - xx1);
2282 else if (_R(yy2) > 0)
2283 weight = ((x2 - xx1) * (x2 - xx1)) + (yy2 * yy2);
2284 else if (_R(yyy2) < 0)
2285 weight = ((x2 - xx1) * (x2 - xx1)) + (yyy2 * yyy2);
2286 else weight = (x2 - xx1) * (x2 - xx1);
2288 else if (degree == 90.0)
2290 if (_R(yyy1) > _R(yy2)) weight = -1.0;
2291 else if ((_R(x2) >= _R(x1)) && (_R(xx2) <= _R(xx1)))
2292 weight = (yy2 - yyy1) * (yy2 - yyy1);
2293 else if (_R(x2) > 0)
2294 weight = (x2 * x2) + ((yy2 - yyy1) * (yy2 - yyy1));
2295 else if (_R(xx2) < 0)
2296 weight = (xx2 * xx2) + ((yy2 - yyy1) * (yy2 - yyy1));
2297 else weight = (yy2 - yyy1) * (yy2 - yyy1);
2299 else if (degree == 180.0)
2301 if (_R(x1) < _R(xx2)) weight = -1.0;
2302 else if ((_R(yy2) >= _R(yy1)) && (_R(yyy2) <= _R(yyy1)))
2303 weight = (x1 - xx2) * (x1 - xx2);
2304 else if (_R(yy2) > 0)
2305 weight = ((x1 - xx2) * (x1 - xx2)) + (yy2 * yy2);
2306 else if (_R(yyy2) < 0)
2307 weight = ((x1 - xx2) * (x1 - xx2)) + (yyy2 * yyy2);
2308 else weight = (x1 - xx2) * (x1 - xx2);
2310 else if (degree == 270.0)
2312 if (_R(yy1) < _R(yyy2)) weight = -1.0;
2313 else if ((_R(x2) >= _R(x1)) && (_R(xx2) <= _R(xx1)))
2314 weight = (yy1 - yyy2) * (yy1 - yyy2);
2315 else if (_R(x2) > 0)
2316 weight = (x2 * x2) + ((yy1 - yyy2) * (yy1 - yyy2));
2317 else if (_R(xx2) < 0)
2318 weight = (xx2 * xx2) + ((yy1 - yyy2) * (yy1 - yyy2));
2319 else weight = (yy1 - yyy2) * (yy1 - yyy2);
2324 double sx[4] = {0.0, 0.0, 0.0, 0.0}, sy[4] = {0.0, 0.0, 0.0, 0.0};
2325 double t_weight[4] = {-1.0, -1.0, -1.0, -1.0};
2326 if ((_R(g * x2) >= _R(yy2)) && (_R(g * x2) <= _R(yyy2)))
2330 t_weight[j++] = ((ax - x2) * (ax - x2)) +
2331 ((ay - (g * x2)) * (ay - (g * x2)));
2333 if ((_R(g * xx2) >= _R(yy2)) && (_R(g * xx2) <= _R(yyy2)))
2337 t_weight[j++] = ((ax - xx2) * (ax - xx2)) +
2338 ((ay - (g * xx2)) * (ay - (g * xx2)));
2340 if ((_R((1.0 / g) * yy2) >= _R(x2)) && (_R((1.0 / g) * yy2) <= _R(xx2)))
2342 sx[j] = (1.0 / g) * yy2;
2345 ((ax - ((1.0 / g) * yy2)) * (ax - ((1.0 / g) * yy2))) +
2346 ((ay - yy2) * (ay - yy2));
2348 if ((_R((1.0 / g) * yyy2) >= _R(x2)) && (_R((1.0 / g) * yyy2)
2351 sx[j] = (1.0 / g) * yyy2;
2354 ((ax - ((1.0 / g) * yyy2)) * (ax - ((1.0 / g) * yyy2))) +
2355 ((ay - yyy2) * (ay - yyy2));
2358 if ((j > 2) || ((j == 2) && ((_R(sx[0]) != _R(sx[1])) ||
2359 (_R(sy[0]) != _R(sy[1])))))
2363 if (_R(t_weight[k]) == 0) return -1.0;
2364 if ((1 / weight) < (1 / t_weight[k])) weight = t_weight[k];
2371 double ccx, ccy, t1_weight, x_diff, y_diff;
2372 ccx = ((1.0 / g) * rx[k] + ry[k]) / (g + (1.0 / g));
2374 x_diff = rx[k] - ccx;
2375 if (x_diff < 0) x_diff *= -1.0;
2376 y_diff = ry[k] - ccy;
2377 if (y_diff < 0) y_diff *= -1.0;
2379 (((ax - ccx) * (ax - ccx)) + ((ay - ccy) * (ay - ccy))) +
2380 ((x_diff * x_diff * x_diff) + (y_diff * y_diff * y_diff));
2381 if ((_R(t1_weight) != 0) && ((1 / weight) < (1 / t1_weight)))
2386 /* Return the current object's weight. */
2387 if (weight == -1.0) return 0.0;
2388 if (_R(weight) == 0) return -1.0;
2392 return 1.0 / weight;
2398 * Get near object in one direction of base object.
2400 * Get near object(in the object sub-tree) in one direction of
2401 * base object. Return the near object by reference.
2402 * By initializing weight, you can filter objects locating far
2403 * from base object. If object is in the specific direction,
2404 * weight is (1/(distance^2)). If object is not exactly in one
2405 * direction, some penalty will be added.
2407 * @param obj The widget root of sub-tree
2408 * @param base The base object of the direction
2409 * @param degree Degree changes clockwise. i.e. 0-degree: Up,
2410 * 90-degree: Right, 180-degree: Down, and 270-degree: Left
2411 * @param direction The near object in one direction
2412 * @param weight The weight is bigger when the object is located near
2413 * @return EINA_TRUE if near object is updated.
2418 EOLIAN static Eina_Bool
2419 _elm_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)
2423 /* -1 means the best was already decided. Don't need any more searching. */
2424 if (!direction || !weight || !base || (obj == base))
2427 /* Ignore if disabled */
2428 if ((!evas_object_visible_get(obj))
2429 || (elm_widget_disabled_get(obj))
2430 || (elm_widget_tree_unfocusable_get(obj)))
2434 if (_internal_elm_widget_focus_direction_manager_is(obj))
2436 Eina_Bool int_ret = EINA_FALSE;
2437 eo_do((Eo *)obj, int_ret = elm_obj_widget_focus_direction(base, degree, direction, direction_item, weight));
2441 if (!elm_widget_can_focus_get(obj) || _is_focused((Eo *)obj))
2444 c_weight = _elm_widget_focus_direction_weight_get(base, obj, degree);
2445 if ((c_weight == -1.0) ||
2446 ((c_weight != 0.0) && (*weight != -1.0) &&
2447 ((int)(*weight * 1000000) <= (int)(c_weight * 1000000))))
2450 ((int)(*weight * 1000000) == (int)(c_weight * 1000000)))
2452 ELM_WIDGET_DATA_GET(*direction, sd1);
2455 if (sd->focus_order <= sd1->focus_order)
2459 *direction = (Evas_Object *)obj;
2470 * Get near object in one direction of base object in list.
2472 * Get near object in one direction of base object in the specific
2473 * object list. Return the near object by reference.
2474 * By initializing weight, you can filter objects locating far
2475 * from base object. If object is in the specific direction,
2476 * weight is (1/(distance^2)). If object is not exactly in one
2477 * direction, some penalty will be added.
2479 * @param obj The widget root of sub-tree
2480 * @param base The base object of the direction
2481 * @param items list with ordered objects
2482 * @param list_data_get function to get the object from one item of list
2483 * @param degree Degree changes clockwise. i.e. 0-degree: Up,
2484 * 90-degree: Right, 180-degree: Down, and 270-degree: Left
2485 * @param direction The near object in one direction
2486 * @param weight The weight is bigger when the object is located near
2487 * @return EINA_TRUE if near object is updated.
2491 EOLIAN static Eina_Bool
2492 _elm_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, list_data_get_func_type list_data_get, double degree, Evas_Object **direction, Elm_Object_Item **direction_item, double *weight)
2494 if (!direction || !weight || !base || !items)
2497 const Eina_List *l = items;
2498 Evas_Object *current_best = *direction;
2500 for (; l; l = eina_list_next(l))
2502 Evas_Object *cur = list_data_get(l);
2503 if (cur && _elm_widget_is(cur))
2504 elm_widget_focus_direction_get(cur, base, degree, direction, direction_item, weight);
2506 if (current_best != *direction) return EINA_TRUE;
2514 * Get next object in focus chain of object tree.
2516 * Get next object in focus chain of one object sub-tree.
2517 * Return the next object by reference. If don't have any candidate to receive
2518 * focus before chain end, the first candidate will be returned.
2520 * @param obj The widget root of sub-tree
2521 * @param dir Direction of focus chain
2522 * @param next The next object in focus chain
2523 * @return EINA_TRUE if don't need focus chain restart/loop back
2524 * to use 'next' obj.
2528 EOLIAN static Eina_Bool
2529 _elm_widget_focus_next_get(const Eo *obj, Elm_Widget_Smart_Data *sd, Elm_Focus_Direction dir, Evas_Object **next, Elm_Object_Item **next_item)
2531 Elm_Access_Info *ac;
2537 /* Ignore if disabled */
2538 if (_elm_config->access_mode && _elm_access_auto_highlight_get())
2540 if (!evas_object_visible_get(obj)
2541 || (elm_widget_tree_unfocusable_get(obj)))
2546 if ((!evas_object_visible_get(obj))
2547 || (elm_widget_disabled_get(obj))
2548 || (elm_widget_tree_unfocusable_get(obj)))
2553 if (_elm_widget_focus_chain_manager_is(obj))
2555 Eina_Bool int_ret = EINA_FALSE;
2556 eo_do((Eo *)obj, int_ret = elm_obj_widget_focus_next(dir, next, next_item));
2557 if (!int_ret && _is_focused((Eo *)obj))
2559 Evas_Object *o = NULL;
2560 if (dir == ELM_FOCUS_PREVIOUS)
2561 *next_item = sd->item_focus_previous;
2562 else if (dir == ELM_FOCUS_NEXT)
2563 *next_item = sd->item_focus_next;
2564 else if (dir == ELM_FOCUS_UP)
2565 *next_item = sd->item_focus_up;
2566 else if (dir == ELM_FOCUS_DOWN)
2567 *next_item = sd->item_focus_down;
2568 else if (dir == ELM_FOCUS_RIGHT)
2569 *next_item = sd->item_focus_right;
2570 else if (dir == ELM_FOCUS_LEFT)
2571 *next_item = sd->item_focus_left;
2572 o = elm_object_item_widget_get(*next_item);
2576 if (dir == ELM_FOCUS_PREVIOUS)
2577 o = sd->focus_previous;
2578 else if (dir == ELM_FOCUS_NEXT)
2580 else if (dir == ELM_FOCUS_UP)
2582 else if (dir == ELM_FOCUS_DOWN)
2584 else if (dir == ELM_FOCUS_RIGHT)
2585 o = sd->focus_right;
2586 else if (dir == ELM_FOCUS_LEFT)
2599 /* access object does not check sd->can_focus, because an object could
2600 have highlight even though the object is not focusable. */
2601 if (_elm_config->access_mode && _elm_access_auto_highlight_get())
2603 ac = _elm_access_info_get(obj);
2604 if (!ac) return EINA_FALSE;
2606 /* check whether the hover object is visible or not */
2607 if (!evas_object_visible_get(ac->hoverobj))
2610 else if (!elm_widget_can_focus_get(obj))
2613 if (_is_focused((Eo *)obj))
2615 if (dir == ELM_FOCUS_PREVIOUS)
2616 *next_item = sd->item_focus_previous;
2617 else if (dir == ELM_FOCUS_NEXT)
2618 *next_item = sd->item_focus_next;
2619 else if (dir == ELM_FOCUS_UP)
2620 *next_item = sd->item_focus_up;
2621 else if (dir == ELM_FOCUS_DOWN)
2622 *next_item = sd->item_focus_down;
2623 else if (dir == ELM_FOCUS_RIGHT)
2624 *next_item = sd->item_focus_right;
2625 else if (dir == ELM_FOCUS_LEFT)
2626 *next_item = sd->item_focus_left;
2627 *next = elm_object_item_widget_get(*next_item);
2631 if (dir == ELM_FOCUS_PREVIOUS)
2632 *next = sd->focus_previous;
2633 else if (dir == ELM_FOCUS_NEXT)
2634 *next = sd->focus_next;
2635 else if (dir == ELM_FOCUS_UP)
2636 *next = sd->focus_up;
2637 else if (dir == ELM_FOCUS_DOWN)
2638 *next = sd->focus_down;
2639 else if (dir == ELM_FOCUS_RIGHT)
2640 *next = sd->focus_right;
2641 else if (dir == ELM_FOCUS_LEFT)
2642 *next = sd->focus_left;
2645 if (*next) return EINA_TRUE;
2649 *next = (Evas_Object *)obj;
2650 return !ELM_WIDGET_FOCUS_GET(obj);
2656 * Get next object in focus chain of object tree in list.
2658 * Get next object in focus chain of one object sub-tree ordered by one list.
2659 * Return the next object by reference. If don't have any candidate to receive
2660 * focus before list end, the first candidate will be returned.
2662 * @param obj The widget root of sub-tree
2663 * @param items list with ordered objects
2664 * @param list_data_get function to get the object from one item of list
2665 * @param dir Direction of focus chain
2666 * @param next The next object in focus chain
2667 * @return EINA_TRUE if don't need focus chain restart/loop back
2668 * to use 'next' obj.
2672 EOLIAN static Eina_Bool
2673 _elm_widget_focus_list_next_get(const Eo *obj, Elm_Widget_Smart_Data *_pd EINA_UNUSED, const Eina_List *items, list_data_get_func_type list_data_get, Elm_Focus_Direction dir, Evas_Object **next, Elm_Object_Item **next_item)
2675 Eina_List *(*list_next)(const Eina_List *list) = NULL;
2676 Evas_Object *focused_object = NULL;
2682 if (!_elm_widget_is(obj))
2688 /* When Up, Down, Right, or Left, try direction_get first. */
2689 focused_object = elm_widget_focused_object_get(obj);
2692 if ((dir == ELM_FOCUS_UP)
2693 || (dir == ELM_FOCUS_DOWN)
2694 || (dir == ELM_FOCUS_RIGHT)
2695 || (dir == ELM_FOCUS_LEFT))
2697 *next_item = elm_widget_focus_next_item_get(focused_object, dir);
2699 *next = elm_object_item_widget_get(*next_item);
2701 *next = elm_widget_focus_next_object_get(focused_object, dir);
2702 if (*next) return EINA_TRUE;
2705 Evas_Object *n = NULL;
2706 Elm_Object_Item *n_item = NULL;
2708 double weight = 0.0;
2710 if (dir == ELM_FOCUS_UP) degree = 0.0;
2711 else if (dir == ELM_FOCUS_DOWN) degree = 180.0;
2712 else if (dir == ELM_FOCUS_RIGHT) degree = 90.0;
2713 else if (dir == ELM_FOCUS_LEFT) degree = 270.0;
2715 if (elm_widget_focus_list_direction_get(obj, focused_object,
2716 items, list_data_get,
2717 degree, &n, &n_item,
2720 *next_item = n_item;
2729 if (dir == ELM_FOCUS_PREVIOUS)
2731 items = eina_list_last(items);
2732 list_next = eina_list_prev;
2734 else if ((dir == ELM_FOCUS_NEXT)
2735 || (dir == ELM_FOCUS_UP)
2736 || (dir == ELM_FOCUS_DOWN)
2737 || (dir == ELM_FOCUS_RIGHT)
2738 || (dir == ELM_FOCUS_LEFT))
2739 list_next = eina_list_next;
2743 const Eina_List *l = items;
2745 /* Recovery last focused sub item */
2746 if (ELM_WIDGET_FOCUS_GET(obj))
2748 for (; l; l = list_next(l))
2750 Evas_Object *cur = list_data_get(l);
2751 if (ELM_WIDGET_FOCUS_GET(cur)) break;
2754 /* Focused object, but no focused sub item */
2758 const Eina_List *start = l;
2759 Evas_Object *to_focus = NULL;
2760 Elm_Object_Item *to_focus_item = NULL;
2762 /* Iterate sub items */
2763 /* Go to the end of list */
2764 for (; l; l = list_next(l))
2766 Evas_Object *tmp = NULL;
2767 Elm_Object_Item *tmp_item = NULL;
2768 Evas_Object *cur = list_data_get(l);
2771 if (!_elm_widget_is(cur)) continue;
2772 if (elm_widget_parent_get(cur) != obj)
2775 /* Try Focus cycle in subitem */
2776 if (elm_widget_focus_next_get(cur, dir, &tmp, &tmp_item))
2779 *next_item = tmp_item;
2782 else if ((dir == ELM_FOCUS_UP)
2783 || (dir == ELM_FOCUS_DOWN)
2784 || (dir == ELM_FOCUS_RIGHT)
2785 || (dir == ELM_FOCUS_LEFT))
2787 if (tmp && _is_focused(cur))
2790 *next_item = tmp_item;
2794 else if ((tmp) && (!to_focus))
2797 to_focus_item = tmp_item;
2803 /* Get First possible */
2804 for (; l != start; l = list_next(l))
2806 Evas_Object *tmp = NULL;
2807 Elm_Object_Item *tmp_item = NULL;
2808 Evas_Object *cur = list_data_get(l);
2810 if (elm_widget_parent_get(cur) != obj)
2813 /* Try Focus cycle in subitem */
2814 elm_widget_focus_next_get(cur, dir, &tmp, &tmp_item);
2818 *next_item = tmp_item;
2824 *next_item = to_focus_item;
2831 * Get next object which was set with specific focus direction.
2833 * Get next object which was set by elm_widget_focus_next_object_set
2834 * with specific focus directioin.
2836 * @param obj The widget
2837 * @param dir Direction of focus
2838 * @return Widget which was registered with sepecific focus direction.
2842 EOLIAN static Evas_Object*
2843 _elm_widget_focus_next_object_get(const Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd, Elm_Focus_Direction dir)
2845 Evas_Object *ret = NULL;
2847 if (dir == ELM_FOCUS_PREVIOUS)
2848 ret = sd->focus_previous;
2849 else if (dir == ELM_FOCUS_NEXT)
2850 ret = sd->focus_next;
2851 else if (dir == ELM_FOCUS_UP)
2853 else if (dir == ELM_FOCUS_DOWN)
2854 ret = sd->focus_down;
2855 else if (dir == ELM_FOCUS_RIGHT)
2856 ret = sd->focus_right;
2857 else if (dir == ELM_FOCUS_LEFT)
2858 ret = sd->focus_left;
2866 * Set next object with specific focus direction.
2868 * When a widget is set with specific focus direction, this widget will be
2869 * the first candidate when finding the next focus object.
2870 * Focus next object can be registered with six directions that are previous,
2871 * next, up, down, right, and left.
2873 * @param obj The widget
2874 * @param next Next focus object
2875 * @param dir Direction of focus
2880 _elm_widget_focus_next_object_set(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd, Evas_Object *next, Elm_Focus_Direction dir)
2883 if (dir == ELM_FOCUS_PREVIOUS)
2884 sd->focus_previous = next;
2885 else if (dir == ELM_FOCUS_NEXT)
2886 sd->focus_next = next;
2887 else if (dir == ELM_FOCUS_UP)
2888 sd->focus_up = next;
2889 else if (dir == ELM_FOCUS_DOWN)
2890 sd->focus_down = next;
2891 else if (dir == ELM_FOCUS_RIGHT)
2892 sd->focus_right = next;
2893 else if (dir == ELM_FOCUS_LEFT)
2894 sd->focus_left = next;
2897 EOLIAN static Elm_Object_Item*
2898 _elm_widget_focus_next_item_get(const Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd, Elm_Focus_Direction dir)
2900 Elm_Object_Item *ret = NULL;
2902 if (dir == ELM_FOCUS_PREVIOUS)
2903 ret = sd->item_focus_previous;
2904 else if (dir == ELM_FOCUS_NEXT)
2905 ret = sd->item_focus_next;
2906 else if (dir == ELM_FOCUS_UP)
2907 ret = sd->item_focus_up;
2908 else if (dir == ELM_FOCUS_DOWN)
2909 ret = sd->item_focus_down;
2910 else if (dir == ELM_FOCUS_RIGHT)
2911 ret = sd->item_focus_right;
2912 else if (dir == ELM_FOCUS_LEFT)
2913 ret = sd->item_focus_left;
2919 _elm_widget_focus_next_item_set(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd, Elm_Object_Item *next_item, Elm_Focus_Direction dir)
2921 if (dir == ELM_FOCUS_PREVIOUS)
2922 sd->item_focus_previous = next_item;
2923 else if (dir == ELM_FOCUS_NEXT)
2924 sd->item_focus_next = next_item;
2925 else if (dir == ELM_FOCUS_UP)
2926 sd->item_focus_up = next_item;
2927 else if (dir == ELM_FOCUS_DOWN)
2928 sd->item_focus_down = next_item;
2929 else if (dir == ELM_FOCUS_RIGHT)
2930 sd->item_focus_right = next_item;
2931 else if (dir == ELM_FOCUS_LEFT)
2932 sd->item_focus_left = next_item;
2936 _elm_widget_parent_highlight_set(Eo *obj, Elm_Widget_Smart_Data *sd, Eina_Bool highlighted)
2938 highlighted = !!highlighted;
2940 Evas_Object *o = elm_widget_parent_get(obj);
2942 if (o) elm_widget_parent_highlight_set(o, highlighted);
2944 sd->highlighted = highlighted;
2948 _elm_widget_signal_emit(Eo *obj, Elm_Widget_Smart_Data *_pd EINA_UNUSED, const char *emission, const char *source)
2950 if (evas_object_smart_type_check(obj, "elm_layout"))
2951 elm_layout_signal_emit(obj, emission, source);
2952 else if (evas_object_smart_type_check(obj, "elm_icon"))
2954 WRN("Deprecated function. This functionality on icon objects"
2955 " will be dropped on a next release.");
2956 _elm_icon_signal_emit(obj, emission, source);
2961 _elm_widget_signal_callback_add(Eo *obj, Elm_Widget_Smart_Data *_pd EINA_UNUSED, const char *emission, const char *source, Edje_Signal_Cb func, void *data)
2963 EINA_SAFETY_ON_NULL_RETURN(func);
2965 if (evas_object_smart_type_check(obj, "elm_layout"))
2966 elm_layout_signal_callback_add(obj, emission, source, func, data);
2967 else if (evas_object_smart_type_check(obj, "elm_icon"))
2969 WRN("Deprecated function. This functionality on icon objects"
2970 " will be dropped on a next release.");
2972 _elm_icon_signal_callback_add(obj, emission, source, func, data);
2977 _elm_widget_signal_callback_del(Eo *obj, Elm_Widget_Smart_Data *_pd EINA_UNUSED, const char *emission, const char *source, Edje_Signal_Cb func)
2981 if (evas_object_smart_type_check(obj, "elm_layout"))
2982 data = elm_layout_signal_callback_del(obj, emission, source, func);
2983 else if (evas_object_smart_type_check(obj, "elm_icon"))
2985 WRN("Deprecated function. This functionality on icon objects"
2986 " will be dropped on a next release.");
2988 data = _elm_icon_signal_callback_del(obj, emission, source, func);
2995 _elm_widget_focus_set(Eo *obj, Elm_Widget_Smart_Data *sd, Eina_Bool focus)
3000 sd->focus_order = focus_order;
3001 sd->focused = EINA_TRUE;
3002 eo_do(obj, elm_obj_widget_on_focus(NULL));
3007 if ((_is_focusable(sd->resize_obj)) &&
3008 (!elm_widget_disabled_get(sd->resize_obj)))
3010 elm_widget_focus_set(sd->resize_obj, focus);
3017 EINA_LIST_FOREACH(sd->subobjs, l, child)
3019 if (!_elm_widget_is(child)) continue;
3020 if ((_is_focusable(child)) &&
3021 (!elm_widget_disabled_get(child)))
3023 elm_widget_focus_set(child, focus);
3034 EINA_LIST_REVERSE_FOREACH(sd->subobjs, l, child)
3036 if (!_elm_widget_is(child)) continue;
3037 if ((_is_focusable(child)) &&
3038 (!elm_widget_disabled_get(child)))
3040 elm_widget_focus_set(child, focus);
3047 EOLIAN static Evas_Object*
3048 _elm_widget_parent_get(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd)
3050 return sd->parent_obj;
3054 _elm_widget_focused_object_clear(Eo *obj, Elm_Widget_Smart_Data *sd)
3056 if (!sd->focused) return;
3057 if (sd->resize_obj && elm_widget_is(sd->resize_obj) &&
3058 _is_focused(sd->resize_obj))
3060 eo_do(sd->resize_obj, elm_obj_widget_focused_object_clear());
3066 EINA_LIST_FOREACH(sd->subobjs, l, child)
3068 if (_elm_widget_is(child) && _is_focused(child))
3070 eo_do(child, elm_obj_widget_focused_object_clear());
3075 sd->focused = EINA_FALSE;
3076 if (sd->top_win_focused)
3077 eo_do(obj, elm_obj_widget_on_focus(NULL));
3081 _elm_widget_focus_steal(Eo *obj, Elm_Widget_Smart_Data *sd, Elm_Object_Item *item)
3083 Evas_Object *parent, *parent2, *o;
3085 if (sd->focused) return;
3086 if (sd->disabled) return;
3087 if (!sd->can_focus) return;
3088 if (sd->tree_unfocusable) return;
3092 o = elm_widget_parent_get(parent);
3094 sd = eo_data_scope_get(o, MY_CLASS);
3095 if (sd->disabled || sd->tree_unfocusable) return;
3096 if (sd->focused) break;
3099 if ((!elm_widget_parent_get(parent)) &&
3100 (!elm_widget_parent2_get(parent)))
3101 eo_do(parent, elm_obj_widget_focused_object_clear());
3104 parent2 = elm_widget_parent_get(parent);
3105 if (!parent2) parent2 = elm_widget_parent2_get(parent);
3107 sd = eo_data_scope_get(parent, MY_CLASS);
3110 if (sd->resize_obj && elm_widget_is(sd->resize_obj) &&
3111 _is_focused(sd->resize_obj))
3113 eo_do(sd->resize_obj, elm_obj_widget_focused_object_clear());
3119 EINA_LIST_FOREACH(sd->subobjs, l, child)
3121 if (_elm_widget_is(child) && _is_focused(child))
3123 eo_do(child, elm_obj_widget_focused_object_clear());
3130 /* TIZEN_ONLY(20161212): Some winsets should know whether it's focus target or not in _on_focus */
3131 sd = eo_data_scope_get(obj, MY_CLASS);
3132 sd->is_focus_target = EINA_TRUE;
3134 _parent_focus(obj, item);
3135 /* TIZEN_ONLY(20161212): Some winsets should know whether it's focus target or not in _on_focus */
3136 sd->is_focus_target = EINA_FALSE;
3138 elm_widget_focus_region_show(obj);
3143 _parents_on_focus(Evas_Object *obj)
3146 if (!sd->focused || !sd->top_win_focused) return;
3148 Evas_Object *o = elm_widget_parent_get(obj);
3149 if (o) _parents_on_focus(o);
3150 eo_do(obj, elm_obj_widget_on_focus(NULL));
3154 _elm_widget_focus_restore(Eo *obj, Elm_Widget_Smart_Data *_pd EINA_UNUSED)
3156 Evas_Object *newest = NULL;
3157 unsigned int newest_focus_order = 0;
3159 newest = elm_widget_newest_focus_order_get(obj, &newest_focus_order, EINA_TRUE);
3161 _parents_on_focus(newest);
3165 _elm_widget_focus_auto_show(Evas_Object *obj)
3167 Evas_Object *top = elm_widget_top_get(obj);
3168 if (top && eo_isa(top, ELM_WIN_CLASS)) _elm_win_focus_auto_show(top);
3172 _elm_widget_top_win_focused_set(Evas_Object *obj,
3173 Eina_Bool top_win_focused)
3179 if (sd->top_win_focused == top_win_focused) return;
3180 EINA_LIST_FOREACH(sd->subobjs, l, child)
3182 if (elm_widget_is(child))
3183 _elm_widget_top_win_focused_set(child, top_win_focused);
3185 sd->top_win_focused = top_win_focused;
3187 if (sd->focused && !sd->top_win_focused)
3188 eo_do(obj, elm_obj_widget_on_focus(NULL));
3192 _elm_widget_top_win_focused_get(const Evas_Object *obj)
3194 API_ENTRY return EINA_FALSE;
3195 return sd->top_win_focused;
3199 _elm_widget_disabled_eval(const Evas_Object *obj, Eina_Bool disabled)
3203 ELM_WIDGET_DATA_GET(obj, sd);
3207 EINA_LIST_FOREACH(sd->subobjs, l, child)
3209 if (elm_widget_is(child))
3211 elm_widget_focus_disabled_handle(child);
3212 eo_do(child, elm_obj_widget_disable());
3213 _elm_widget_disabled_eval(child, EINA_TRUE);
3219 EINA_LIST_FOREACH(sd->subobjs, l, child)
3221 ELM_WIDGET_DATA_GET(child, sdc);
3222 if (elm_widget_is(child) && !sdc->disabled)
3224 elm_widget_focus_disabled_handle(child);
3225 eo_do(child, elm_obj_widget_disable());
3226 _elm_widget_disabled_eval(child, EINA_FALSE);
3233 elm_widget_disabled_internal(Eo *obj, Eina_Bool disabled)
3235 Eina_Bool parent_state = EINA_FALSE;
3239 elm_widget_focus_disabled_handle(obj);
3240 eo_do(obj, elm_obj_widget_disable());
3241 _elm_widget_disabled_eval(obj, EINA_TRUE);
3245 parent_state = elm_widget_disabled_get(elm_widget_parent_get(obj));
3246 if (parent_state) return;
3247 elm_widget_focus_disabled_handle(obj);
3248 eo_do(obj, elm_obj_widget_disable());
3249 _elm_widget_disabled_eval(obj, EINA_FALSE);
3254 _elm_widget_disabled_set(Eo *obj, Elm_Widget_Smart_Data *sd, Eina_Bool disabled)
3256 if (sd->disabled == disabled) return;
3257 sd->disabled = !!disabled;
3259 elm_widget_disabled_internal(obj, disabled);
3262 EOLIAN static Eina_Bool
3263 _elm_widget_disabled_get(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd)
3265 Eina_Bool disabled = EINA_FALSE;
3267 if (sd->disabled) disabled = EINA_TRUE;
3268 else disabled = elm_widget_disabled_get(elm_widget_parent_get(obj));
3273 _elm_widget_show_region_set(Eo *obj, Elm_Widget_Smart_Data *sd, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h, Eina_Bool forceshow)
3276 Evas_Object *parent_obj, *child_obj;
3277 Evas_Coord px, py, cx, cy, nx = 0, ny = 0;
3280 /* TIZEN_ONLY(20161222): Update show region geometry when entry is resized
3281 Move this code to the blow to update show region geometry properly.
3282 evas_smart_objects_calculate(evas_object_evas_get(obj));
3285 if (!forceshow && (x == sd->rx) && (y == sd->ry) &&
3286 (w == sd->rw) && (h == sd->rh)) return;
3293 /* TIZEN_ONLY(20161222): Update show region geometry when entry is resized */
3294 /* Block nested call for evas_smart_objects_calculate() and region showing works */
3295 if (sd->on_show_region_set) return;
3297 sd->on_show_region_set = EINA_TRUE;
3299 evas_smart_objects_calculate(evas_object_evas_get(obj));
3301 sd->on_show_region_set = EINA_FALSE;
3303 /* show_region geometry could be changed during processing elm_widget_show_region_set().
3304 evas_smart_objects_calculate() can trigger nested show_region_set calls */
3311 if (sd->on_show_region)
3314 (sd->on_show_region_data, obj);
3316 if (_elm_scrollable_is(obj))
3318 eo_do(obj, elm_interface_scrollable_content_pos_get(&nx, &ny));
3326 parent_obj = sd->parent_obj;
3327 child_obj = sd->obj;
3328 if ((!parent_obj) || (!_elm_widget_is(parent_obj))) break;
3329 sd = eo_data_scope_get(parent_obj, MY_CLASS);
3332 evas_object_geometry_get(parent_obj, &px, &py, NULL, NULL);
3333 evas_object_geometry_get(child_obj, &cx, &cy, NULL, NULL);
3342 if (sd->on_show_region)
3345 (sd->on_show_region_data, parent_obj);
3352 _elm_widget_show_region_get(const Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd, Evas_Coord *x, Evas_Coord *y, Evas_Coord *w, Evas_Coord *h)
3363 * Get the focus region of the given widget.
3365 * @return show region or not
3366 * (@c EINA_TRUE = show region/@c EINA_FALSE = do not show region). Default is @c EINA_FALSE.
3368 * The focus region is the area of a widget that should brought into the
3369 * visible area when the widget is focused. Mostly used to show the part of
3370 * an entry where the cursor is, for example. The area returned is relative
3371 * to the object @p obj.
3373 * @param obj The widget object
3374 * @param x Where to store the x coordinate of the area
3375 * @param y Where to store the y coordinate of the area
3376 * @param w Where to store the width of the area
3377 * @param h Where to store the height of the area
3381 EOLIAN static Eina_Bool
3382 _elm_widget_focus_region_get(Eo *obj, Elm_Widget_Smart_Data *_pd EINA_UNUSED, Evas_Coord *x, Evas_Coord *y, Evas_Coord *w, Evas_Coord *h)
3384 Eina_Bool int_ret = EINA_FALSE;
3385 eo_do((Eo *)obj, int_ret = elm_obj_widget_on_focus_region(x, y, w, h));
3388 evas_object_geometry_get(obj, NULL, NULL, w, h);
3392 if ((*w <= 0) || (*h <= 0)) return EINA_FALSE;
3397 _elm_widget_parents_bounce_get(Eo *obj, Elm_Widget_Smart_Data *_pd EINA_UNUSED, Eina_Bool *horiz, Eina_Bool *vert)
3399 Evas_Object *parent_obj = obj;
3400 Eina_Bool h = EINA_FALSE, v = EINA_FALSE;
3402 *horiz = EINA_FALSE;
3407 parent_obj = elm_widget_parent_get(parent_obj);
3408 if ((!parent_obj) || (!_elm_widget_is(parent_obj))) break;
3410 if (_elm_scrollable_is(parent_obj))
3412 eo_do(parent_obj, elm_interface_scrollable_bounce_allow_get(&h, &v));
3413 if (h) *horiz = EINA_TRUE;
3414 if (v) *vert = EINA_TRUE;
3420 EOLIAN static Eina_List*
3421 _elm_widget_scrollable_children_get(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd)
3430 EINA_LIST_FOREACH(sd->subobjs, l, child)
3432 if (elm_widget_is(child) && _elm_scrollable_is(child))
3433 ret = eina_list_append(ret, child);
3440 _elm_widget_scroll_hold_push(Eo *obj, Elm_Widget_Smart_Data *sd)
3443 if (sd->scroll_hold == 1)
3445 if (_elm_scrollable_is(obj))
3446 eo_do(obj, elm_interface_scrollable_hold_set(EINA_TRUE));
3449 Eina_List *scr_children, *l;
3452 scr_children = elm_widget_scrollable_children_get(obj);
3453 EINA_LIST_FOREACH(scr_children, l, child)
3455 eo_do(child, elm_interface_scrollable_hold_set(EINA_TRUE));
3457 eina_list_free(scr_children);
3460 if (sd->parent_obj) eo_do(sd->parent_obj, elm_obj_widget_scroll_hold_push());
3461 // FIXME: on delete/reparent hold pop
3465 _elm_widget_scroll_hold_pop(Eo *obj, Elm_Widget_Smart_Data *sd)
3468 if (!sd->scroll_hold)
3470 if (_elm_scrollable_is(obj))
3471 eo_do(obj, elm_interface_scrollable_hold_set(EINA_FALSE));
3474 Eina_List *scr_children, *l;
3477 scr_children = elm_widget_scrollable_children_get(obj);
3478 EINA_LIST_FOREACH(scr_children, l, child)
3480 eo_do(child, elm_interface_scrollable_hold_set(EINA_FALSE));
3482 eina_list_free(scr_children);
3485 if (sd->parent_obj) eo_do(sd->parent_obj, elm_obj_widget_scroll_hold_pop());
3486 if (sd->scroll_hold < 0) sd->scroll_hold = 0;
3490 _elm_widget_scroll_hold_get(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd)
3492 return sd->scroll_hold;
3496 _elm_widget_scroll_freeze_push(Eo *obj, Elm_Widget_Smart_Data *sd)
3498 sd->scroll_freeze++;
3499 if (sd->scroll_freeze == 1)
3501 if (_elm_scrollable_is(obj))
3502 eo_do(obj, elm_interface_scrollable_freeze_set(EINA_TRUE));
3505 Eina_List *scr_children, *l;
3508 scr_children = elm_widget_scrollable_children_get(obj);
3509 EINA_LIST_FOREACH(scr_children, l, child)
3511 eo_do(child, elm_interface_scrollable_freeze_set(EINA_TRUE));
3513 eina_list_free(scr_children);
3516 if (sd->parent_obj) eo_do(sd->parent_obj, elm_obj_widget_scroll_freeze_push());
3517 // FIXME: on delete/reparent freeze pop
3521 _elm_widget_scroll_freeze_pop(Eo *obj, Elm_Widget_Smart_Data *sd)
3523 sd->scroll_freeze--;
3524 if (!sd->scroll_freeze)
3526 if (_elm_scrollable_is(obj))
3527 eo_do(obj, elm_interface_scrollable_freeze_set(EINA_FALSE));
3530 Eina_List *scr_children, *l;
3533 scr_children = elm_widget_scrollable_children_get(obj);
3534 EINA_LIST_FOREACH(scr_children, l, child)
3536 eo_do(child, elm_interface_scrollable_freeze_set(EINA_FALSE));
3538 eina_list_free(scr_children);
3541 if (sd->parent_obj) eo_do(sd->parent_obj, elm_obj_widget_scroll_freeze_pop());
3542 if (sd->scroll_freeze < 0) sd->scroll_freeze = 0;
3546 _elm_widget_scroll_freeze_get(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd)
3548 return sd->scroll_freeze;
3551 // TIZEN_ONLY(20150705): Genlist item align feature
3553 elm_widget_scroll_item_align_enabled_set(Evas_Object *obj,
3554 Eina_Bool scroll_item_align_enable)
3557 if (sd->scroll_item_align_enable == scroll_item_align_enable) return;
3558 sd->scroll_item_align_enable = scroll_item_align_enable;
3562 elm_widget_scroll_item_align_enabled_get(const Evas_Object *obj)
3564 API_ENTRY return EINA_FALSE;
3565 return sd->scroll_item_align_enable;
3569 elm_widget_scroll_item_valign_set(Evas_Object *obj,
3570 const char *scroll_item_valign)
3573 if (sd->scroll_item_valign) eina_stringshare_del(sd->scroll_item_valign);
3574 if (!scroll_item_valign) sd->scroll_item_valign = NULL;
3575 else sd->scroll_item_valign = eina_stringshare_add(scroll_item_valign);
3579 elm_widget_scroll_item_valign_get(const Evas_Object *obj)
3581 API_ENTRY return NULL;
3582 return sd->scroll_item_valign;
3587 _elm_widget_scale_set(Eo *obj, Elm_Widget_Smart_Data *sd, double scale)
3589 if (scale < 0.0) scale = 0.0;
3590 if (sd->scale != scale)
3593 elm_widget_theme(obj);
3597 EOLIAN static double
3598 _elm_widget_scale_get(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd)
3600 // FIXME: save walking up the tree by storing/caching parent scale
3601 if (sd->scale == 0.0)
3603 if (sd->parent_obj && elm_widget_is(sd->parent_obj))
3605 return elm_widget_scale_get(sd->parent_obj);
3616 _elm_widget_theme_set(Eo *obj, Elm_Widget_Smart_Data *sd, Elm_Theme *th)
3618 Eina_Bool apply = EINA_FALSE;
3619 if (sd->theme != th)
3621 if (elm_widget_theme_get(obj) != th) apply = EINA_TRUE;
3622 if (sd->theme) elm_theme_free(sd->theme);
3625 if (apply) elm_widget_theme(obj);
3630 _elm_widget_part_text_set(Eo *obj, Elm_Widget_Smart_Data *_pd EINA_UNUSED, const char *part, const char *label)
3632 if (evas_object_smart_type_check(obj, "elm_layout"))
3633 elm_layout_text_set(obj, part, label);
3636 EOLIAN static const char*
3637 _elm_widget_part_text_get(Eo *obj, Elm_Widget_Smart_Data *_pd EINA_UNUSED, const char *part)
3639 if (evas_object_smart_type_check(obj, "elm_layout"))
3640 return elm_layout_text_get(obj, part);
3645 static Elm_Translate_String_Data *
3646 _translate_string_data_get(Eina_Inlist *translate_strings, const char *part)
3648 Elm_Translate_String_Data *ts;
3649 Eina_Stringshare *str;
3651 if (!translate_strings) return NULL;
3653 str = eina_stringshare_add(part);
3654 EINA_INLIST_FOREACH(translate_strings, ts)
3656 if (ts->id == str) break;
3659 eina_stringshare_del(str);
3664 static Elm_Translate_String_Data *
3665 _part_text_translatable_set(Eina_Inlist **translate_strings, const char *part, Eina_Bool translatable, Eina_Bool preset)
3668 Elm_Translate_String_Data *ts;
3669 t = *translate_strings;
3670 ts = _translate_string_data_get(t, part);
3676 ts = ELM_NEW(Elm_Translate_String_Data);
3677 if (!ts) return NULL;
3679 ts->id = eina_stringshare_add(part);
3680 t = eina_inlist_append(t, (Eina_Inlist*) ts);
3682 if (preset) ts->preset = EINA_TRUE;
3684 //Delete this exist one if this part has been not preset.
3685 //see elm_widget_part_text_translatable_set()
3686 else if (ts && ((preset) || (!ts->preset)))
3688 t = eina_inlist_remove(t, EINA_INLIST_GET(ts));
3689 eina_stringshare_del(ts->id);
3690 eina_stringshare_del(ts->domain);
3691 eina_stringshare_del(ts->string);
3692 ELM_SAFE_FREE(ts, free);
3695 *translate_strings = t;
3701 _elm_widget_domain_translatable_part_text_set(Eo *obj, Elm_Widget_Smart_Data *sd, const char *part, const char *domain, const char *label)
3704 Elm_Translate_String_Data *ts;
3708 _part_text_translatable_set(&sd->translate_strings, part, EINA_FALSE,
3713 ts = _part_text_translatable_set(&sd->translate_strings, part,
3714 EINA_TRUE, EINA_FALSE);
3716 if (!ts->string) ts->string = eina_stringshare_add(label);
3717 else eina_stringshare_replace(&ts->string, label);
3718 if (!ts->domain) ts->domain = eina_stringshare_add(domain);
3719 else eina_stringshare_replace(&ts->domain, domain);
3721 if (label[0]) label = dgettext(domain, label);
3725 sd->on_translate = EINA_TRUE;
3726 eo_do(obj, elm_obj_widget_part_text_set(part, label));
3727 sd->on_translate = EINA_FALSE;
3730 EOLIAN static const char*
3731 _elm_widget_translatable_part_text_get(const Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd, const char *part)
3733 Elm_Translate_String_Data *ts;
3735 ts = _translate_string_data_get(sd->translate_strings, part);
3736 if (ts) return ts->string;
3741 _elm_widget_domain_part_text_translatable_set(Eo *obj, Elm_Widget_Smart_Data *sd, const char *part, const char *domain, Eina_Bool translatable)
3743 Elm_Translate_String_Data *ts;
3744 const char *text = NULL;
3746 ts = _part_text_translatable_set(&sd->translate_strings, part,
3747 translatable, EINA_TRUE);
3749 if (!ts->domain) ts->domain = eina_stringshare_add(domain);
3750 else eina_stringshare_replace(&ts->domain, domain);
3752 eo_do(obj, text = elm_obj_widget_part_text_get(part));
3753 if (!text || !text[0]) return;
3755 if (!ts->string) ts->string = eina_stringshare_add(text);
3757 //Try to translate text since we don't know the text is already translated.
3759 text = dgettext(domain, text);
3761 sd->on_translate = EINA_TRUE;
3762 eo_do(obj, elm_obj_widget_part_text_set(part, text));
3763 sd->on_translate = EINA_FALSE;
3767 elm_widget_translate(Evas_Object *obj)
3769 ELM_WIDGET_CHECK(obj);
3770 eo_do(obj, elm_obj_widget_translate());
3774 _part_text_translate(Eina_Inlist *translate_strings,
3778 Elm_Translate_String_Data *ts;
3779 ts = _translate_string_data_get(translate_strings, part);
3780 if (!ts) return text;
3782 if (!ts->string) ts->string = eina_stringshare_add(text);
3783 else eina_stringshare_replace(&ts->string, text);
3785 if (text && text[0])
3786 text = dgettext(ts->domain, text);
3791 EOLIAN static const char*
3792 _elm_widget_part_text_translate(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd, const char *part, const char *text)
3796 if (!sd->translate_strings || sd->on_translate) return text;
3797 return _part_text_translate(sd->translate_strings, part, text);
3800 EOLIAN static Eina_Bool
3801 _elm_widget_translate(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *_pd EINA_UNUSED)
3805 API_ENTRY return EINA_FALSE;
3807 EINA_LIST_FOREACH(sd->subobjs, l, child)
3809 if (elm_widget_is(child))
3810 elm_widget_translate(child);
3813 if (sd->hover_obj) elm_widget_translate(sd->hover_obj);
3816 Elm_Translate_String_Data *ts;
3817 EINA_INLIST_FOREACH(sd->translate_strings, ts)
3819 if (!ts->string) continue;
3820 const char *s = dgettext(ts->domain, ts->string);
3821 sd->on_translate = EINA_TRUE;
3822 eo_do(obj, elm_obj_widget_part_text_set(ts->id, s));
3823 sd->on_translate = EINA_FALSE;
3826 eo_do(obj, eo_event_callback_call(ELM_WIDGET_EVENT_LANGUAGE_CHANGED, NULL));
3833 * Resets the focus_move_policy mode from the system one
3834 * for widgets that are in automatic mode.
3836 * @param obj The widget.
3840 _elm_widget_focus_move_policy_reload(Evas_Object *obj)
3843 Elm_Focus_Move_Policy focus_move_policy = elm_config_focus_move_policy_get();
3845 if (elm_widget_focus_move_policy_automatic_get(obj) &&
3846 (sd->focus_move_policy != focus_move_policy))
3848 sd->focus_move_policy = focus_move_policy;
3853 _elm_widget_focus_reconfigure(Eo *obj, Elm_Widget_Smart_Data *_pd EINA_UNUSED)
3859 EINA_LIST_FOREACH(sd->subobjs, l, child)
3861 if (elm_widget_is(child))
3862 elm_widget_focus_reconfigure(child);
3865 if (sd->hover_obj) elm_widget_focus_reconfigure(sd->hover_obj);
3867 _elm_widget_focus_move_policy_reload(obj);
3870 //TIZEN_ONLY(20160726): add API elm_object_part_access_object_get
3871 EOLIAN static Evas_Object*
3872 _elm_widget_part_access_object_get(const Eo *obj, Elm_Widget_Smart_Data *_pd EINA_UNUSED, const char *part EINA_UNUSED)
3874 WRN("The %s widget does not implement the \"part_access_object_get\" functions.",
3875 eo_class_name_get(eo_class_get(obj)));
3881 elm_widget_content_part_set(Evas_Object *obj,
3883 Evas_Object *content)
3885 ELM_WIDGET_CHECK(obj);
3886 eo_do(obj, elm_obj_container_content_set(part, content));
3890 * Returns the widget's focus_move_policy mode setting.
3892 * @param obj The widget.
3893 * @return focus_move_policy mode setting of the object.
3896 EOLIAN static Eina_Bool
3897 _elm_widget_focus_move_policy_automatic_get(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd)
3899 return sd->focus_move_policy_auto_mode;
3905 * Sets the widget's focus_move_policy mode setting.
3906 * When widget in automatic mode, it follows the system focus_move_policy mode set by
3907 * elm_config_focus_move_policy_set().
3908 * @param obj The widget.
3909 * @param automatic EINA_TRUE for auto focus_move_policy mode. EINA_FALSE for manual.
3912 _elm_widget_focus_move_policy_automatic_set(Eo *obj, Elm_Widget_Smart_Data *sd, Eina_Bool automatic)
3914 if (sd->focus_move_policy_auto_mode != automatic)
3916 sd->focus_move_policy_auto_mode = automatic;
3920 elm_widget_focus_move_policy_set(obj, elm_config_focus_move_policy_get());
3926 elm_widget_content_part_get(const Evas_Object *obj,
3929 ELM_WIDGET_CHECK(obj) NULL;
3930 Evas_Object *ret = NULL;
3931 eo_do((Eo *) obj, ret = elm_obj_container_content_get(part));
3936 elm_widget_content_part_unset(Evas_Object *obj,
3939 ELM_WIDGET_CHECK(obj) NULL;
3940 Evas_Object *ret = NULL;
3941 eo_do(obj, ret = elm_obj_container_content_unset(part));
3946 _elm_widget_access_info_set(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd, const char *txt)
3948 eina_stringshare_del(sd->access_info);
3949 if (!txt) sd->access_info = NULL;
3950 else sd->access_info = eina_stringshare_add(txt);
3953 EOLIAN static const char*
3954 _elm_widget_access_info_get(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd)
3956 return sd->access_info;
3959 EOLIAN static Elm_Theme*
3960 _elm_widget_theme_get(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd)
3964 if (sd->parent_obj && elm_widget_is(sd->parent_obj))
3965 return elm_widget_theme_get(sd->parent_obj);
3971 EOLIAN static Elm_Theme_Apply
3972 _elm_widget_style_set(Eo *obj, Elm_Widget_Smart_Data *sd, const char *style)
3974 if (eina_stringshare_replace(&sd->style, style))
3975 return elm_widget_theme(obj);
3977 return ELM_THEME_APPLY_SUCCESS;
3980 /* TIZEN_ONLY(20161223): add widget style set furnction for internal usage
3981 this function is same with elm_widget_style_set
3982 but it doesn't apply sub object's theme */
3984 _elm_widget_style_set_internal(Evas_Object *obj, const char *style)
3986 Elm_Theme_Apply ret = ELM_THEME_APPLY_SUCCESS;
3988 API_ENTRY return ELM_THEME_APPLY_FAILED;
3990 if (eina_stringshare_replace(&sd->style, style))
3996 if (sd->hover_obj) ret &= elm_widget_theme(sd->hover_obj);
3998 EINA_LIST_FOREACH(sd->tooltips, l, tt)
3999 elm_tooltip_theme(tt);
4000 EINA_LIST_FOREACH(sd->cursors, l, cur)
4001 elm_cursor_theme(cur);
4003 Elm_Theme_Apply ret2 = ELM_THEME_APPLY_FAILED;
4004 eo_do(obj, ret2 = elm_obj_widget_theme_apply());
4012 EOLIAN static const char*
4013 _elm_widget_style_get(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd)
4017 if (sd->style) ret = sd->style;
4023 _elm_widget_tooltip_add(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd, Elm_Tooltip *tt)
4025 sd->tooltips = eina_list_append(sd->tooltips, tt);
4029 _elm_widget_tooltip_del(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd, Elm_Tooltip *tt)
4031 sd->tooltips = eina_list_remove(sd->tooltips, tt);
4035 _elm_widget_cursor_add(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd, Elm_Cursor *cur)
4037 sd->cursors = eina_list_append(sd->cursors, cur);
4041 _elm_widget_cursor_del(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd, Elm_Cursor *cur)
4043 sd->cursors = eina_list_remove(sd->cursors, cur);
4047 _elm_widget_drag_lock_x_set(Eo *obj, Elm_Widget_Smart_Data *sd, Eina_Bool lock)
4049 if (sd->drag_x_locked == lock) return;
4050 sd->drag_x_locked = lock;
4051 if (sd->drag_x_locked) _propagate_x_drag_lock(obj, 1);
4052 else _propagate_x_drag_lock(obj, -1);
4056 _elm_widget_drag_lock_y_set(Eo *obj, Elm_Widget_Smart_Data *sd, Eina_Bool lock)
4058 if (sd->drag_y_locked == lock) return;
4059 sd->drag_y_locked = lock;
4060 if (sd->drag_y_locked) _propagate_y_drag_lock(obj, 1);
4061 else _propagate_y_drag_lock(obj, -1);
4064 EOLIAN static Eina_Bool
4065 _elm_widget_drag_lock_x_get(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd)
4067 return sd->drag_x_locked;
4070 EOLIAN static Eina_Bool
4071 _elm_widget_drag_lock_y_get(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd)
4073 return sd->drag_y_locked;
4077 _elm_widget_drag_child_locked_x_get(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd)
4079 return sd->child_drag_x_locked;
4083 _elm_widget_drag_child_locked_y_get(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd)
4085 return sd->child_drag_y_locked;
4089 _elm_widget_item_loop_enabled_set(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd EINA_UNUSED, Eina_Bool enable EINA_UNUSED)
4094 EOLIAN static Eina_Bool
4095 _elm_widget_item_loop_enabled_get(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd EINA_UNUSED)
4100 EOLIAN static Elm_Theme_Apply
4101 _elm_widget_theme_object_set(Eo *obj, Elm_Widget_Smart_Data *sd, Evas_Object *edj, const char *wname, const char *welement, const char *wstyle)
4103 Elm_Theme_Apply ret = _elm_theme_object_set(obj, edj, wname, welement, wstyle);
4106 return ELM_THEME_APPLY_FAILED;
4109 if (sd->orient_mode != -1)
4112 snprintf(buf, sizeof(buf), "elm,state,orient,%d", sd->orient_mode);
4113 eo_do(obj, elm_obj_widget_signal_emit(buf, "elm"));
4120 _elm_widget_eo_base_dbg_info_get(Eo *eo_obj, Elm_Widget_Smart_Data *_pd EINA_UNUSED, Eo_Dbg_Info *root)
4122 eo_do_super(eo_obj, MY_CLASS, eo_dbg_info_get(root));
4123 Eo_Dbg_Info *group = EO_DBG_INFO_LIST_APPEND(root, MY_CLASS_NAME);
4125 EO_DBG_INFO_APPEND(group, "Wid-Type", EINA_VALUE_TYPE_STRING, elm_widget_type_get(eo_obj));
4126 EO_DBG_INFO_APPEND(group, "Style", EINA_VALUE_TYPE_STRING, elm_widget_style_get(eo_obj));
4127 EO_DBG_INFO_APPEND(group, "Layer", EINA_VALUE_TYPE_INT,
4128 (int) evas_object_layer_get(eo_obj));
4129 EO_DBG_INFO_APPEND(group, "Scale", EINA_VALUE_TYPE_DOUBLE,
4130 evas_object_scale_get(eo_obj));
4131 EO_DBG_INFO_APPEND(group, "Has focus", EINA_VALUE_TYPE_CHAR,
4132 elm_object_focus_get(eo_obj));
4133 EO_DBG_INFO_APPEND(group, "Disabled", EINA_VALUE_TYPE_CHAR,
4134 elm_widget_disabled_get(eo_obj));
4135 EO_DBG_INFO_APPEND(group, "Mirrored", EINA_VALUE_TYPE_CHAR,
4136 elm_widget_mirrored_get(eo_obj));
4137 EO_DBG_INFO_APPEND(group, "Automatic mirroring", EINA_VALUE_TYPE_CHAR,
4138 elm_widget_mirrored_automatic_get(eo_obj));
4142 elm_widget_is_check(const Evas_Object *obj)
4144 static int abort_on_warn = -1;
4145 if (elm_widget_is(obj))
4148 ERR("Passing Object: %p.", obj);
4149 if (abort_on_warn == -1)
4151 if (getenv("ELM_ERROR_ABORT")) abort_on_warn = 1;
4152 else abort_on_warn = 0;
4154 if (abort_on_warn == 1) abort();
4159 elm_widget_type_get(const Evas_Object *obj)
4161 API_ENTRY return NULL;
4163 return eo_class_name_get(eo_class_get(obj));
4167 elm_widget_type_check(const Evas_Object *obj,
4171 const char *provided, *expected = "(unknown)";
4172 static int abort_on_warn = -1;
4174 provided = elm_widget_type_get(obj);
4175 /* TODO: eventually migrate to check_ptr version */
4176 if (evas_object_smart_type_check(obj, type)) return EINA_TRUE;
4177 if (type) expected = type;
4178 if ((!provided) || (!provided[0]))
4180 provided = evas_object_type_get(obj);
4181 if ((!provided) || (!provided[0]))
4182 provided = "(unknown)";
4184 ERR("Passing Object: %p in function: %s, of type: '%s' when expecting"
4185 " type: '%s'", obj, func, provided, expected);
4186 if (abort_on_warn == -1)
4188 if (getenv("ELM_ERROR_ABORT")) abort_on_warn = 1;
4189 else abort_on_warn = 0;
4191 if (abort_on_warn == 1) abort();
4195 static Evas_Object *
4196 _widget_name_find(const Evas_Object *obj,
4203 INTERNAL_ENTRY NULL;
4205 if (!_elm_widget_is(obj)) return NULL;
4206 EINA_LIST_FOREACH(sd->subobjs, l, child)
4208 s = evas_object_name_get(child);
4209 if ((s) && (!strcmp(s, name))) return child;
4210 if ((recurse != 0) &&
4211 ((child = _widget_name_find(child, name, recurse - 1))))
4216 s = evas_object_name_get(sd->hover_obj);
4217 if ((s) && (!strcmp(s, name))) return sd->hover_obj;
4218 if ((recurse != 0) &&
4219 ((child = _widget_name_find(sd->hover_obj, name, recurse - 1))))
4225 EOLIAN static Evas_Object*
4226 _elm_widget_name_find(const Eo *obj, Elm_Widget_Smart_Data *_pd EINA_UNUSED, const char *name, int recurse)
4228 if (!name) return NULL;
4229 return _widget_name_find(obj, name, recurse);
4235 * Split string in words
4237 * @param str Source string
4238 * @return List of const words
4240 * @see elm_widget_stringlist_free()
4244 elm_widget_stringlist_get(const char *str)
4246 Eina_List *list = NULL;
4248 if (!str) return NULL;
4249 for (b = s = str; 1; s++)
4251 if ((*s == ' ') || (!*s))
4253 char *t = malloc(s - b + 1);
4256 strncpy(t, b, s - b);
4258 list = eina_list_append(list, eina_stringshare_add(t));
4269 elm_widget_stringlist_free(Eina_List *list)
4272 EINA_LIST_FREE(list, s)
4273 eina_stringshare_del(s);
4277 _elm_widget_focus_hide_handle(Eo *obj, Elm_Widget_Smart_Data *_pd EINA_UNUSED)
4279 if (!_elm_widget_is(obj))
4281 _if_focused_revert(obj, EINA_TRUE);
4285 elm_widget_focus_mouse_up_handle(Evas_Object *obj)
4287 Evas_Object *o = obj;
4290 if (_elm_widget_is(o)) break;
4291 o = evas_object_smart_parent_get(o);
4295 eo_do(o, elm_obj_widget_focus_mouse_up_handle());
4299 _elm_widget_focus_mouse_up_handle(Eo *obj, Elm_Widget_Smart_Data *_pd EINA_UNUSED)
4302 if (!_is_focusable(obj)) return;
4304 elm_widget_focus_steal(obj, NULL);
4308 _elm_widget_focus_tree_unfocusable_handle(Eo *obj, Elm_Widget_Smart_Data *_pd EINA_UNUSED)
4310 if (!elm_widget_parent_get(obj))
4311 elm_widget_focused_object_clear(obj);
4313 _if_focused_revert(obj, EINA_TRUE);
4317 _elm_widget_focus_disabled_handle(Eo *obj, Elm_Widget_Smart_Data *_pd EINA_UNUSED)
4319 elm_widget_focus_tree_unfocusable_handle(obj);
4322 EOLIAN static unsigned int
4323 _elm_widget_focus_order_get(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd)
4325 return sd->focus_order;
4328 EOLIAN static Evas_Object*
4329 _elm_widget_newest_focus_order_get(const Eo *obj, Elm_Widget_Smart_Data *sd, unsigned int *newest_focus_order, Eina_Bool can_focus_only)
4332 Evas_Object *child, *cur, *best;
4334 if (!evas_object_visible_get(obj)
4335 || (elm_widget_disabled_get(obj))
4336 || (elm_widget_tree_unfocusable_get(obj)))
4340 if (*newest_focus_order < sd->focus_order)
4342 if (!can_focus_only || elm_widget_can_focus_get(obj))
4344 *newest_focus_order = sd->focus_order;
4345 best = (Evas_Object *)obj;
4348 EINA_LIST_FOREACH(sd->subobjs, l, child)
4350 if (!_elm_widget_is(child)) continue;
4352 cur = elm_widget_newest_focus_order_get
4353 (child, newest_focus_order, can_focus_only);
4363 * Get the focus highlight geometry of an widget.
4365 * @param obj Widget object for the focus highlight
4366 * @param x Focus highlight x coordinate
4367 * @param y Focus highlight y coordinate
4368 * @param w Focus highlight object width
4369 * @param h Focus highlight object height
4370 * @param is_next @c EINA_TRUE if this request is for the new focused object,
4371 * @c EINA_FALSE if this request is for the previously focused object. This
4372 * information becomes important when the focus highlight is changed inside one
4380 * Get the 'focus_part' geometry if there is any
4382 * This queries if there is a 'focus_part' request from the edc style. If edc
4383 * style offers 'focus_part' edje data item, this function requests for the
4384 * geometry of a specific part which is described in 'focus_part' edje data.
4386 * @param obj Widget object for the focus highlight
4387 * @param x Focus highlight x coordinate
4388 * @param y Focus highlight y coordinate
4389 * @param w Focus highlight object width
4390 * @param h Focus highlight object height
4392 * x, y, w, h already contain the object's geometry. If there is a 'focus_part'
4393 * support, these values will be updated accordingly or the values will be
4394 * remained as they were.
4399 elm_widget_focus_highlight_focus_part_geometry_get(const Evas_Object *obj,
4405 Evas_Coord tx = 0, ty = 0, tw = 0, th = 0;
4406 const char *target_hl_part = NULL;
4407 const Evas_Object *edje_obj = NULL;
4409 if (obj && eo_isa(obj, EDJE_OBJECT_CLASS))
4412 if (!(target_hl_part = edje_object_data_get(edje_obj, "focus_part")))
4415 else if (obj && eo_isa(obj, ELM_LAYOUT_CLASS))
4417 edje_obj = elm_layout_edje_get(obj);
4418 if (!(target_hl_part = elm_layout_data_get(obj, "focus_part")))
4424 edje_object_part_geometry_get(edje_obj, target_hl_part,
4425 &tx, &ty, &tw, &th);
4428 if (tw != *w) *w = tw;
4429 if (th != *h) *h = th;
4433 _elm_widget_focus_highlight_geometry_get(const Eo *obj, Elm_Widget_Smart_Data *sd, Evas_Coord *x, Evas_Coord *y, Evas_Coord *w, Evas_Coord *h)
4435 Evas_Coord ox = 0, oy = 0, ow = 0, oh = 0;
4436 Evas_Object *scroller = (Evas_Object *)obj;
4438 evas_object_geometry_get(obj, x, y, w, h);
4439 elm_widget_focus_highlight_focus_part_geometry_get(sd->resize_obj, x, y, w, h);
4441 if (_elm_config->focus_autoscroll_mode != ELM_FOCUS_AUTOSCROLL_MODE_BRING_IN)
4446 if (_elm_scrollable_is(scroller))
4449 elm_interface_scrollable_content_viewport_geometry_get(&ox, &oy, &ow, &oh));
4453 else if ((oy + oh) < (*y + *h))
4454 *y = (oy + oh - *h);
4457 else if ((ox + ow) < (*x + *w))
4458 *x = (ox + ow - *w);
4462 scroller = elm_widget_parent_get(scroller);
4466 EOLIAN static Elm_Object_Item*
4467 _elm_widget_focused_item_get(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *_pd EINA_UNUSED)
4473 _elm_widget_focus_region_show_mode_set(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *_pd, Elm_Focus_Region_Show_Mode mode)
4475 _pd->focus_region_show_mode = mode;
4478 EOLIAN static Elm_Focus_Region_Show_Mode
4479 _elm_widget_focus_region_show_mode_get(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *_pd)
4481 return _pd->focus_region_show_mode;
4485 elm_widget_activate(Evas_Object *obj, Elm_Activate act)
4487 Evas_Object *parent;
4490 ELM_WIDGET_CHECK(obj);
4494 eo_do(obj, ret = elm_obj_widget_activate(act));
4498 parent = elm_widget_parent_get(obj);
4500 elm_widget_activate(parent, act);
4508 * Sets the widget and child widget's Evas_Display_Mode.
4510 * @param obj The widget.
4511 * @param dispmode Evas_Display_Mode to set widget's mode.
4513 * Widgets are resized by several reasons.
4514 * Evas_Display_Mode can help for widgets to get one more reason of resize.
4515 * For example, elm conform widget resizes it's contents when keypad state changed.
4516 * After keypad showing, conform widget can change child's Evas_Display_Mode.
4520 _elm_widget_display_mode_set(Eo *obj, Elm_Widget_Smart_Data *sd, Evas_Display_Mode dispmode)
4522 Evas_Display_Mode prev_dispmode;
4526 prev_dispmode = evas_object_size_hint_display_mode_get(obj);
4528 if ((prev_dispmode == dispmode) ||
4529 (prev_dispmode == EVAS_DISPLAY_MODE_DONT_CHANGE)) return;
4531 evas_object_size_hint_display_mode_set(obj, dispmode);
4533 EINA_LIST_FOREACH (sd->subobjs, l, child)
4535 if (elm_widget_is(child))
4536 elm_widget_display_mode_set(child, dispmode);
4541 _elm_widget_orientation_mode_disabled_set(Eo *obj, Elm_Widget_Smart_Data *sd, Eina_Bool disabled)
4543 int orient_mode = -1;
4547 //Get current orient mode from it's parent otherwise, 0.
4548 sd->orient_mode = 0;
4549 ELM_WIDGET_DATA_GET(sd->parent_obj, sd_parent);
4550 if (!sd_parent) orient_mode = 0;
4551 else orient_mode = sd_parent->orient_mode;
4553 eo_do(obj, elm_obj_widget_orientation_set(orient_mode));
4556 EOLIAN static Eina_Bool
4557 _elm_widget_orientation_mode_disabled_get(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd)
4559 if (sd->orient_mode == -1) return EINA_TRUE;
4560 else return EINA_FALSE;
4564 _elm_widget_orientation_set(Eo *obj, Elm_Widget_Smart_Data *sd, int orient_mode)
4569 sd->orient_mode = orient_mode;
4571 EINA_LIST_FOREACH (sd->subobjs, l, child)
4573 if (elm_widget_is(child))
4574 eo_do(child, elm_obj_widget_orientation_set(orient_mode));
4577 if (orient_mode != -1)
4580 snprintf(buf, sizeof(buf), "elm,state,orient,%d", orient_mode);
4581 eo_do(obj, elm_obj_widget_signal_emit(buf, "elm"));
4588 * Returns the widget's focus move policy.
4590 * @param obj The widget.
4591 * @return focus move policy of the object.
4594 EOLIAN static Elm_Focus_Move_Policy
4595 _elm_widget_focus_move_policy_get(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd)
4597 return sd->focus_move_policy;
4603 * Sets the widget's focus move policy.
4605 * @param obj The widget.
4606 * @param policy Elm_Focus_Move_Policy to set object's focus move policy.
4610 _elm_widget_focus_move_policy_set(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd, Elm_Focus_Move_Policy policy)
4612 if (sd->focus_move_policy == policy) return;
4613 sd->focus_move_policy = policy;
4616 _track_obj_del(void *data, Evas *e, Evas_Object *obj, void *event_info);
4619 _track_obj_update(Evas_Object *track, Evas_Object *obj)
4622 Evas_Coord x, y, w, h;
4623 evas_object_geometry_get(obj, &x, &y, &w, &h);
4624 evas_object_move(track, x, y);
4625 evas_object_resize(track, w, h);
4628 if (evas_object_visible_get(obj)) evas_object_show(track);
4629 else evas_object_hide(track);
4633 _track_obj_view_update(void *data, Eo *obj,
4634 const Eo_Event_Description *desc EINA_UNUSED,
4635 void *event_info EINA_UNUSED)
4637 Elm_Widget_Item_Data *item = data;
4638 _track_obj_update(item->track_obj, obj);
4639 return EO_CALLBACK_CONTINUE;
4643 _track_obj_view_del(void *data, Eo *obj EINA_UNUSED,
4644 const Eo_Event_Description *desc EINA_UNUSED,
4645 void *event_info EINA_UNUSED);
4647 EO_CALLBACKS_ARRAY_DEFINE(tracker_callbacks,
4648 { EVAS_OBJECT_EVENT_RESIZE, _track_obj_view_update },
4649 { EVAS_OBJECT_EVENT_MOVE, _track_obj_view_update },
4650 { EVAS_OBJECT_EVENT_SHOW, _track_obj_view_update },
4651 { EVAS_OBJECT_EVENT_HIDE, _track_obj_view_update },
4652 { EVAS_OBJECT_EVENT_DEL, _track_obj_view_del });
4655 _track_obj_view_del(void *data, Eo *obj EINA_UNUSED,
4656 const Eo_Event_Description *desc EINA_UNUSED,
4657 void *event_info EINA_UNUSED)
4659 Elm_Widget_Item_Data *item = data;
4661 while (evas_object_ref_get(item->track_obj) > 0)
4662 evas_object_unref(item->track_obj);
4664 evas_object_event_callback_del(item->track_obj, EVAS_CALLBACK_DEL,
4666 evas_object_del(item->track_obj);
4667 item->track_obj = NULL;
4669 return EO_CALLBACK_CONTINUE;
4673 _track_obj_del(void *data, Evas *e EINA_UNUSED,
4674 Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
4676 Elm_Widget_Item_Data *item = data;
4677 item->track_obj = NULL;
4679 if (!item->view) return;
4681 eo_do(item->view, eo_event_callback_array_del(tracker_callbacks(), item));
4685 _elm_widget_item_signal_cb(void *data, Evas_Object *obj EINA_UNUSED, const char *emission,
4688 Elm_Widget_Item_Signal_Data *wisd = data;
4689 wisd->func(wisd->data, wisd->item, emission, source);
4693 _elm_widget_item_signal_callback_list_get(Elm_Widget_Item_Data *item, Eina_List *position)
4695 Elm_Widget_Item_Signal_Data *wisd = eina_list_data_get(position);
4698 item->signals = eina_list_remove_list(item->signals, position);
4701 if (_elm_widget_is(item->view))
4702 elm_object_signal_callback_del(item->view,
4703 wisd->emission, wisd->source,
4704 _elm_widget_item_signal_cb);
4705 else if (eo_isa(item->view, EDJE_OBJECT_CLASS))
4706 edje_object_signal_callback_del_full(item->view,
4707 wisd->emission, wisd->source,
4708 _elm_widget_item_signal_cb, wisd);
4710 eina_stringshare_del(wisd->emission);
4711 eina_stringshare_del(wisd->source);
4717 #define ERR_NOT_SUPPORTED(item, method) ERR("%s does not support %s API.", elm_widget_type_get(item->widget), method);
4720 _eo_del_cb(void *data EINA_UNUSED, Eo *eo_item, const Eo_Event_Description *desc EINA_UNUSED, void *event_info EINA_UNUSED)
4722 Elm_Widget_Item_Data *item = eo_data_scope_get(eo_item, ELM_WIDGET_ITEM_CLASS);
4723 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item, EINA_TRUE);
4725 item->del_func((void *) WIDGET_ITEM_DATA_GET(eo_item), item->widget, item->eo_obj);
4732 * Allocate a new Elm_Widget_Item-derived structure.
4734 * The goal of this structure is to provide common ground for actions
4735 * that a widget item have, such as the owner widget, callback to
4736 * notify deletion, data pointer and maybe more.
4738 * @param widget the owner widget that holds this item, must be an elm_widget!
4739 * @param alloc_size any number greater than sizeof(Elm_Widget_Item) that will
4740 * be used to allocate memory.
4742 * @return allocated memory that is already zeroed out, or NULL on errors.
4744 * @see elm_widget_item_new() convenience macro.
4745 * @see elm_widget_item_del() to release memory.
4749 _elm_widget_item_eo_base_constructor(Eo *eo_item, Elm_Widget_Item_Data *item)
4751 Evas_Object *widget;
4752 eo_do (eo_item, widget = eo_parent_get());
4754 if (!_elm_widget_is(widget))
4760 eo_item = eo_do_super_ret(eo_item, ELM_WIDGET_ITEM_CLASS, eo_item, eo_constructor());
4762 EINA_MAGIC_SET(item, ELM_WIDGET_ITEM_MAGIC);
4764 item->widget = widget;
4765 item->eo_obj = eo_item;
4766 //TIZEN_ONLY(20170717) : expose highlight information on atspi
4767 item->can_highlight = EINA_TRUE;
4770 eo_do(eo_item, eo_event_callback_add(EO_BASE_EVENT_DEL, _eo_del_cb, NULL));
4776 _elm_widget_item_eo_base_destructor(Eo *eo_item, Elm_Widget_Item_Data *item)
4778 Elm_Translate_String_Data *ts;
4780 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
4782 evas_object_del(item->view);
4784 eina_stringshare_del(item->access_info);
4785 eina_stringshare_del(item->accessible_name);
4787 while (item->signals)
4788 _elm_widget_item_signal_callback_list_get(item, item->signals);
4790 while (item->translate_strings)
4792 ts = EINA_INLIST_CONTAINER_GET(item->translate_strings,
4793 Elm_Translate_String_Data);
4794 eina_stringshare_del(ts->id);
4795 eina_stringshare_del(ts->domain);
4796 eina_stringshare_del(ts->string);
4797 item->translate_strings = eina_inlist_remove(item->translate_strings,
4798 item->translate_strings);
4801 eina_hash_free(item->labels);
4804 elm_interface_atspi_accessible_description_set(NULL),
4805 elm_interface_atspi_accessible_name_set(NULL),
4806 //TIZEN_ONLY(20190922): add name callback, description callback.
4807 elm_interface_atspi_accessible_description_cb_set(NULL, NULL),
4808 elm_interface_atspi_accessible_name_cb_set(NULL, NULL),
4811 //TIZEN_ONLY(20170405) Add gesture method to accessible interface
4812 elm_interface_atspi_accessible_gesture_cb_set(NULL, NULL),
4814 elm_interface_atspi_accessible_translation_domain_set(NULL),
4815 elm_interface_atspi_accessible_relationships_clear(),
4816 // TIZEN_ONLY(20160930) : endless recursion fix
4817 elm_interface_atspi_accessible_attributes_clear()
4822 eina_stringshare_del(item->name);
4824 if (item->atspi_custom_relations)
4825 elm_atspi_relation_set_free(&item->atspi_custom_relations);
4827 //TIZEN_ONLY(20150731) : add i18n support for name and description
4828 if (item->atspi_translation_domain)
4829 eina_stringshare_del(item->atspi_translation_domain);
4831 //Tizen Only(20160728) free attribute list
4832 if (item->attr_list)
4834 Elm_Atspi_Attribute *attr;
4835 EINA_LIST_FREE(item->attr_list, attr)
4837 eina_stringshare_del(attr->key);
4838 eina_stringshare_del(attr->value);
4844 //TIZEN_ONLY(20161013): clean up elm color class feature
4845 if (item->color_classes)
4846 ELM_SAFE_FREE(item->color_classes, eina_hash_free);
4849 EINA_MAGIC_SET(item, EINA_MAGIC_NONE);
4851 eo_do_super(eo_item, ELM_WIDGET_ITEM_CLASS, eo_destructor());
4857 * Releases widget item memory, calling back item_del_pre_hook() and
4858 * item_del_cb() if they exist.
4860 * @param item a valid #Elm_Widget_Item to be deleted.
4862 * If there is an Elm_Widget_Item::del_cb, then it will be called prior
4863 * to memory release. Note that elm_widget_item_pre_notify_del() calls
4864 * this function and then unset it, thus being useful for 2 step
4865 * cleanup whenever the del_cb may use any of the data that must be
4866 * deleted from item.
4868 * The Elm_Widget_Item::view will be deleted (evas_object_del()) if it
4871 * Note that if item_del_pre_hook() returns @c EINA_TRUE, item free will be
4872 * deferred, or item will be freed here if it returns @c EINA_FALSE.
4874 * @see elm_widget_item_del() convenience macro.
4878 _elm_widget_item_del(Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item)
4880 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
4881 ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
4882 item->on_deletion = EINA_TRUE;
4884 //Widget item delete callback
4886 eo_do(item->eo_obj, del_ok = elm_wdg_item_del_pre());
4888 eo_del(item->eo_obj);
4892 EOLIAN static Eina_Bool
4893 _elm_widget_item_del_pre(Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item EINA_UNUSED)
4901 * Notify object will be deleted without actually deleting it.
4903 * This function will callback Elm_Widget_Item::del_cb if it is set
4904 * and then unset it so it is not called twice (ie: from
4905 * elm_widget_item_del()).
4907 * @param item a valid #Elm_Widget_Item to be notified
4908 * @see elm_widget_item_pre_notify_del() convenience macro.
4912 _elm_widget_item_pre_notify_del(Eo *eo_item, Elm_Widget_Item_Data *item)
4914 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
4915 if (!item->del_func) return;
4916 item->del_func((void *)WIDGET_ITEM_DATA_GET(eo_item), item->widget, item->eo_obj);
4917 item->del_func = NULL;
4923 * Set the function to notify when item is being deleted.
4925 * This function will complain if there was a callback set already,
4926 * however it will set the new one.
4928 * The callback will be called from elm_widget_item_pre_notify_del()
4929 * or elm_widget_item_del() will be called with:
4930 * - data: the Elm_Widget_Item::data value.
4931 * - obj: the Elm_Widget_Item::widget evas object.
4932 * - event_info: the item being deleted.
4934 * @param item a valid #Elm_Widget_Item to be notified
4935 * @see elm_widget_item_del_cb_set() convenience macro.
4939 _elm_widget_item_del_cb_set(Eo *eo_item EINA_UNUSED,
4940 Elm_Widget_Item_Data *item,
4943 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
4944 ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
4946 if ((item->del_func) && (item->del_func != func))
4947 WRN("You're replacing a previously set del_cb %p of item %p with %p",
4948 item->del_func, item->eo_obj, func);
4950 item->del_func = func;
4956 * Get owner widget of this item.
4958 * @param item a valid #Elm_Widget_Item to get data from.
4959 * @return owner widget of this item.
4962 EOLIAN static Evas_Object *
4963 _elm_widget_item_widget_get(const Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item)
4965 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item, NULL);
4966 ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item, NULL);
4968 return item->widget;
4972 _elm_widget_onscreen_is(Evas_Object *widget)
4974 Evas_Object *parent = widget;
4975 Evas_Coord x, y, w, h, wx, wy, ww, wh;
4977 Evas *evas = evas_object_evas_get(widget);
4978 if (!evas) return EINA_FALSE;
4980 // check if on canvas
4981 evas_output_viewport_get(evas, &x, &y, &w, &h);
4982 evas_object_geometry_get(widget, &wx, &wy, &ww, &wh);
4983 if (((wx < x) && (wx + ww < x)) || ((wx > x + w) && (wx + ww > x + w)) ||
4984 ((wy < y) && (wy + wh < y)) || ((wy > y+ h) && (wy + wh > y + h)))
4987 // check if inside scrollable parent viewport
4989 parent = elm_widget_parent_get(parent);
4990 if (parent && !evas_object_visible_get(parent))
4992 if (parent && eo_isa(parent, ELM_INTERFACE_SCROLLABLE_MIXIN))
4994 evas_object_geometry_get(parent, &x, &y, &w, &h);
4995 if (((wx < x) && (wx + ww < x)) || ((wx > x + w) && (wx + ww > x + w)) ||
4996 ((wy < y) && (wy + wh < y)) || ((wy > y+ h) && (wy + wh > y + h)))
4999 } while (parent && (parent != elm_widget_top_get(widget)));
5005 _elm_widget_item_onscreen_is(Elm_Object_Item *item)
5007 Evas_Coord x, y, w, h, wx, wy, ww, wh;
5008 Elm_Widget_Item_Data *id = eo_data_scope_get(item, ELM_WIDGET_ITEM_CLASS);
5009 if (!id || !id->view) return EINA_FALSE;
5011 if (!evas_object_visible_get(id->view))
5014 if (!_elm_widget_onscreen_is(id->widget))
5017 evas_object_geometry_get(id->view, &x, &y, &w, &h);
5018 evas_object_geometry_get(id->widget, &wx, &wy, &ww, &wh);
5019 if (((wx < x) && (wx + ww < x)) || ((wx > x + w) && (wx + ww > x + w)) ||
5020 ((wy < y) && (wy + wh < y)) || ((wy > y+ h) && (wy + wh > y + h)))
5027 _elm_widget_accessible_plain_name_get(Evas_Object *obj, const char* name)
5029 char *accessible_plain_name;
5031 API_ENTRY return NULL;
5033 accessible_plain_name = _elm_util_mkup_to_text(name);
5034 eina_stringshare_del(sd->accessible_name);
5035 sd->accessible_name = eina_stringshare_add(accessible_plain_name);
5036 free(accessible_plain_name);
5037 return sd->accessible_name;
5041 _elm_widget_item_accessible_plain_name_get(Elm_Object_Item *item, const char* name)
5043 char *accessible_plain_name;
5045 Elm_Widget_Item_Data *id = eo_data_scope_get(item, ELM_WIDGET_ITEM_CLASS);
5046 if (!id) return NULL;
5048 accessible_plain_name = _elm_util_mkup_to_text(name);
5049 eina_stringshare_del(id->accessible_name);
5050 id->accessible_name = eina_stringshare_add(accessible_plain_name);
5051 free(accessible_plain_name);
5052 return id->accessible_name;
5055 //TIZEN_ONLY(20161107): enhance elm_atspi_accessible_can_highlight_set to set can_hihglight property to its children
5057 _elm_widget_item_highlightable(Elm_Object_Item *item)
5060 Eina_Bool can_highlight;
5062 Elm_Widget_Item_Data *id = eo_data_scope_get(item, ELM_WIDGET_ITEM_CLASS);
5063 if (!id) return EINA_FALSE;
5064 if (!id->can_highlight) return EINA_FALSE;
5066 eo_do(item, parent = elm_interface_atspi_accessible_parent_get());
5067 while (parent && !eo_isa(parent, ELM_ATSPI_APP_OBJECT_CLASS))
5069 eo_do(parent, can_highlight = elm_interface_atspi_accessible_can_highlight_get());
5070 if (!can_highlight) return EINA_FALSE;
5071 eo_do(parent, parent = elm_interface_atspi_accessible_parent_get());
5077 //TIZEN_ONLY(20170206): Add check the object is in the scroller content size
5079 _accessible_object_on_scroll_is(Eo* obj)
5081 /* in case of genlist item, the item->view is NULL if item is unrealized.
5082 this function is used to check if obj could have HIGHLIGHTABLE or not.
5083 the unrealized genlist item should have HIGHLIGHTABLE state.
5084 so if obj is NULL return EINA_TRUE */
5085 if(!obj) return EINA_TRUE;
5087 Evas_Object *target = obj;
5088 Evas_Object *parent = NULL;
5089 Evas_Coord x, y, w, h, wx, wy, ww = 0, wh = 0, nx = 0, ny = 0;
5091 evas_object_geometry_get(target, &x, &y ,&w, &h);
5093 if (elm_widget_is(target))
5094 parent = elm_widget_parent_get(target);
5096 parent = elm_widget_parent_widget_get(target);
5100 if (eo_isa(parent, ELM_INTERFACE_SCROLLABLE_MIXIN))
5102 evas_object_geometry_get(parent, &wx, &wy, NULL, NULL);
5103 eo_do(parent, elm_interface_scrollable_content_size_get(&ww, &wh));
5104 eo_do(parent, elm_interface_scrollable_content_pos_get(&nx, &ny));
5106 /* widget implements scrollable interface but does not use scoller
5107 in this case, use widget geometry */
5108 if (ww == 0 || wh == 0)
5110 INF("%s is zero sized scrollable content", eo_class_name_get(eo_class_get(parent)));
5111 evas_object_geometry_get(parent, NULL, NULL, &ww, &wh);
5117 if (((wx < x) && (wx + ww < x)) || ((wx > x + w) && (wx + ww > x + w)) ||
5118 ((wy < y) && (wy + wh < y)) || ((wy > y + h) && (wy + wh > y + h)))
5123 parent = elm_widget_parent_get(parent);
5130 EOLIAN static Elm_Atspi_State_Set
5131 _elm_widget_item_elm_interface_atspi_accessible_state_set_get(Eo *eo_item,
5132 Elm_Widget_Item_Data *item)
5134 Elm_Atspi_State_Set states = 0;
5136 STATE_TYPE_SET(states, ELM_ATSPI_STATE_FOCUSABLE);
5138 if (elm_object_item_focus_get(eo_item))
5139 STATE_TYPE_SET(states, ELM_ATSPI_STATE_FOCUSED);
5140 if (!elm_object_item_disabled_get(eo_item))
5142 STATE_TYPE_SET(states, ELM_ATSPI_STATE_ENABLED);
5143 STATE_TYPE_SET(states, ELM_ATSPI_STATE_SENSITIVE);
5145 if (_elm_widget_item_onscreen_is(eo_item))
5146 STATE_TYPE_SET(states, ELM_ATSPI_STATE_SHOWING);
5148 //TIZEN_ONLY(20170207) : [ATSPI] enhance expose highlight information on atspi
5149 /* unrealized genlist item does not have item->view,
5150 and item cannot change its visibility, only widget can change the visibility */
5151 if (evas_object_visible_get(item->widget))
5152 STATE_TYPE_SET(states, ELM_ATSPI_STATE_VISIBLE);
5155 //TIZEN_ONLY(20170717) : expose highlight information on atspi
5156 if (_elm_widget_item_highlightable(eo_item) && _accessible_object_on_scroll_is(item->view))
5157 STATE_TYPE_SET(states, ELM_ATSPI_STATE_HIGHLIGHTABLE);
5159 STATE_TYPE_UNSET(states, ELM_ATSPI_STATE_HIGHLIGHTABLE);
5161 if (_elm_object_accessibility_currently_highlighted_get() == (void*)item->eo_obj)
5162 STATE_TYPE_SET(states, ELM_ATSPI_STATE_HIGHLIGHTED);
5168 _elm_widget_item_elm_interface_atspi_accessible_parent_get(Eo *eo_item, Elm_Widget_Item_Data *item EINA_UNUSED)
5171 eo_do(eo_item, parent = eo_parent_get());
5176 elm_object_item_data_set(Elm_Object_Item *it, void *data)
5178 WIDGET_ITEM_DATA_SET(it, data);
5182 elm_object_item_data_get(const Elm_Object_Item *it)
5184 return (void *) WIDGET_ITEM_DATA_GET(it);
5188 _elm_widget_item_disabled_set(Eo *eo_item EINA_UNUSED,
5189 Elm_Widget_Item_Data *item,
5192 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
5193 ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
5195 if (item->disabled == disabled) return;
5196 item->disabled = !!disabled;
5197 eo_do(item->eo_obj, elm_wdg_item_disable());
5200 EOLIAN static Eina_Bool
5201 _elm_widget_item_disabled_get(Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item)
5203 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item, EINA_FALSE);
5204 return item->disabled;
5208 _elm_widget_item_style_set(Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item, const char *style EINA_UNUSED)
5210 ERR_NOT_SUPPORTED(item, "elm_object_style_set()");
5213 EOLIAN static const char *
5214 _elm_widget_item_style_get(Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item)
5216 ERR_NOT_SUPPORTED(item, "elm_object_style_get()");
5221 _elm_widget_item_disable(Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item EINA_UNUSED)
5226 _elm_widget_item_focus_set(Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item, Eina_Bool focused EINA_UNUSED)
5228 ERR_NOT_SUPPORTED(item, "elm_object_item_focus_set");
5231 EOLIAN static Eina_Bool
5232 _elm_widget_item_focus_get(Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item)
5234 ERR_NOT_SUPPORTED(item, "elm_object_item_focus_get");
5239 _elm_widget_item_domain_translatable_part_text_set(Eo *eo_item EINA_UNUSED,
5240 Elm_Widget_Item_Data *item,
5245 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
5246 ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
5247 Elm_Translate_String_Data *ts;
5251 _part_text_translatable_set(&item->translate_strings, part, EINA_FALSE,
5256 ts = _part_text_translatable_set(&item->translate_strings, part,
5257 EINA_TRUE, EINA_FALSE);
5259 if (!ts->string) ts->string = eina_stringshare_add(label);
5260 else eina_stringshare_replace(&ts->string, label);
5261 if (!ts->domain) ts->domain = eina_stringshare_add(domain);
5262 else eina_stringshare_replace(&ts->domain, domain);
5264 if (label[0]) label = dgettext(domain, label);
5267 item->on_translate = EINA_TRUE;
5268 eo_do(item->eo_obj, elm_wdg_item_part_text_set(part, label));
5269 item->on_translate = EINA_FALSE;
5272 EOLIAN static const char *
5273 _elm_widget_item_translatable_part_text_get(const Eo *eo_item EINA_UNUSED,
5274 Elm_Widget_Item_Data *item,
5277 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item, NULL);
5278 ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item, NULL);
5280 Elm_Translate_String_Data *ts;
5281 ts = _translate_string_data_get(item->translate_strings, part);
5282 if (ts) return ts->string;
5287 _elm_widget_item_domain_part_text_translatable_set(Eo *eo_item EINA_UNUSED,
5288 Elm_Widget_Item_Data *item,
5291 Eina_Bool translatable)
5293 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
5294 ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
5295 Elm_Translate_String_Data *ts;
5298 ts = _part_text_translatable_set(&item->translate_strings, part,
5299 translatable, EINA_TRUE);
5301 if (!ts->domain) ts->domain = eina_stringshare_add(domain);
5302 else eina_stringshare_replace(&ts->domain, domain);
5304 eo_do(item->eo_obj, text = elm_wdg_item_part_text_get(part));
5306 if (!text || !text[0]) return;
5308 if (!ts->string) ts->string = eina_stringshare_add(text);
5310 //Try to translate text since we don't know the text is already translated.
5312 text = dgettext(domain, text);
5314 item->on_translate = EINA_TRUE;
5315 eo_do (item->eo_obj, elm_wdg_item_part_text_set(part, text));
5316 item->on_translate = EINA_FALSE;
5320 _elm_widget_item_track_cancel(Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item)
5322 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
5323 ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
5325 if (!item->track_obj) return;
5327 while (evas_object_ref_get(item->track_obj) > 0)
5328 evas_object_unref(item->track_obj);
5330 evas_object_del(item->track_obj);
5333 EOLIAN static Evas_Object *
5334 _elm_widget_item_track(Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item)
5336 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item, NULL);
5337 ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item, NULL);
5339 if (item->track_obj)
5341 evas_object_ref(item->track_obj);
5342 return item->track_obj;
5347 WRN("view obj of the item(%p) is invalid. Please make sure the view obj is created!", item);
5351 Evas_Object *track =
5352 evas_object_rectangle_add(evas_object_evas_get(item->widget));
5353 evas_object_color_set(track, 0, 0, 0, 0);
5354 evas_object_pass_events_set(track, EINA_TRUE);
5355 _track_obj_update(track, item->view);
5356 evas_object_event_callback_add(track, EVAS_CALLBACK_DEL, _track_obj_del,
5360 eo_event_callback_array_add(tracker_callbacks(), item));
5362 evas_object_ref(track);
5364 item->track_obj = track;
5370 _elm_widget_item_untrack(Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item)
5372 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
5373 ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
5375 if (!item->track_obj) return;
5376 evas_object_unref(item->track_obj);
5378 if (evas_object_ref_get(item->track_obj) == 0)
5379 evas_object_del(item->track_obj);
5383 _elm_widget_item_track_get(const Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item)
5385 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item, 0);
5386 ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item, 0);
5388 if (!item->track_obj) return 0;
5389 return evas_object_ref_get(item->track_obj);
5392 typedef struct _Elm_Widget_Item_Tooltip Elm_Widget_Item_Tooltip;
5394 struct _Elm_Widget_Item_Tooltip
5396 Elm_Widget_Item_Data *item;
5397 Elm_Tooltip_Item_Content_Cb func;
5398 Evas_Smart_Cb del_cb;
5402 static Evas_Object *
5403 _elm_widget_item_tooltip_label_create(void *data,
5404 Evas_Object *obj EINA_UNUSED,
5405 Evas_Object *tooltip,
5406 void *item EINA_UNUSED)
5408 Evas_Object *label = elm_label_add(tooltip);
5411 elm_object_style_set(label, "tooltip");
5412 elm_object_text_set(label, data);
5416 static Evas_Object *
5417 _elm_widget_item_tooltip_trans_label_create(void *data,
5418 Evas_Object *obj EINA_UNUSED,
5419 Evas_Object *tooltip,
5420 void *item EINA_UNUSED)
5422 Evas_Object *label = elm_label_add(tooltip);
5425 elm_object_style_set(label, "tooltip");
5426 elm_object_translatable_text_set(label, data);
5431 _elm_widget_item_tooltip_label_del_cb(void *data,
5432 Evas_Object *obj EINA_UNUSED,
5433 void *event_info EINA_UNUSED)
5435 eina_stringshare_del(data);
5441 * Set the text to be shown in the widget item.
5443 * @param item Target item
5444 * @param text The text to set in the content
5446 * Setup the text as tooltip to object. The item can have only one tooltip,
5447 * so any previous tooltip data is removed.
5452 _elm_widget_item_tooltip_text_set(Eo *eo_item EINA_UNUSED,
5453 Elm_Widget_Item_Data *item EINA_UNUSED,
5456 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
5457 ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
5458 EINA_SAFETY_ON_NULL_RETURN(text);
5460 text = eina_stringshare_add(text);
5461 eo_do(item->eo_obj, elm_wdg_item_tooltip_content_cb_set(
5462 _elm_widget_item_tooltip_label_create,
5464 _elm_widget_item_tooltip_label_del_cb));
5468 _elm_widget_item_tooltip_translatable_text_set(Eo *eo_item EINA_UNUSED,
5469 Elm_Widget_Item_Data *item EINA_UNUSED,
5472 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
5473 ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
5474 EINA_SAFETY_ON_NULL_RETURN(text);
5476 text = eina_stringshare_add(text);
5477 eo_do(item->eo_obj, elm_wdg_item_tooltip_content_cb_set(
5478 _elm_widget_item_tooltip_trans_label_create,
5480 _elm_widget_item_tooltip_label_del_cb));
5483 static Evas_Object *
5484 _elm_widget_item_tooltip_create(void *data,
5486 Evas_Object *tooltip)
5488 Elm_Widget_Item_Tooltip *wit = data;
5489 return wit->func((void *)wit->data, obj, tooltip, wit->item->eo_obj);
5493 _elm_widget_item_tooltip_del_cb(void *data,
5495 void *event_info EINA_UNUSED)
5497 Elm_Widget_Item_Tooltip *wit = data;
5498 if (wit->del_cb) wit->del_cb((void *)wit->data, obj, wit->item->eo_obj);
5505 * Set the content to be shown in the tooltip item
5507 * Setup the tooltip to item. The item can have only one tooltip,
5508 * so any previous tooltip data is removed. @p func(with @p data) will
5509 * be called every time that need show the tooltip and it should
5510 * return a valid Evas_Object. This object is then managed fully by
5511 * tooltip system and is deleted when the tooltip is gone.
5513 * @param item the widget item being attached a tooltip.
5514 * @param func the function used to create the tooltip contents.
5515 * @param data what to provide to @a func as callback data/context.
5516 * @param del_cb called when data is not needed anymore, either when
5517 * another callback replaces @func, the tooltip is unset with
5518 * elm_widget_item_tooltip_unset() or the owner @a item
5519 * dies. This callback receives as the first parameter the
5520 * given @a data, and @c event_info is the item.
5525 _elm_widget_item_tooltip_content_cb_set(Eo *eo_item EINA_UNUSED,
5526 Elm_Widget_Item_Data *item,
5527 Elm_Tooltip_Item_Content_Cb func,
5529 Evas_Smart_Cb del_cb)
5531 Elm_Widget_Item_Tooltip *wit;
5533 ELM_WIDGET_ITEM_CHECK_OR_GOTO(item, error_noitem);
5534 //ELM_WIDGET_ITEM_RETURN_IF_GOTO(item, error_noitem);
5538 eo_do(item->eo_obj, elm_wdg_item_tooltip_unset());
5542 wit = ELM_NEW(Elm_Widget_Item_Tooltip);
5543 if (!wit) goto error;
5547 wit->del_cb = del_cb;
5549 elm_object_sub_tooltip_content_cb_set
5550 (item->view, item->widget, _elm_widget_item_tooltip_create, wit,
5551 _elm_widget_item_tooltip_del_cb);
5556 if (del_cb) del_cb((void *)data, NULL, item);
5559 if (del_cb) del_cb((void *)data, item->widget, item);
5565 * Unset tooltip from item
5567 * @param item widget item to remove previously set tooltip.
5569 * Remove tooltip from item. The callback provided as del_cb to
5570 * elm_widget_item_tooltip_content_cb_set() will be called to notify
5571 * it is not used anymore.
5573 * @see elm_widget_item_tooltip_content_cb_set()
5578 _elm_widget_item_tooltip_unset(Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item)
5580 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
5581 ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
5583 elm_object_tooltip_unset(item->view);
5589 * Sets a different style for this item tooltip.
5591 * @note before you set a style you should define a tooltip with
5592 * elm_widget_item_tooltip_content_cb_set() or
5593 * elm_widget_item_tooltip_text_set()
5595 * @param item widget item with tooltip already set.
5596 * @param style the theme style to use (default, transparent, ...)
5601 _elm_widget_item_tooltip_style_set(Eo *eo_item EINA_UNUSED,
5602 Elm_Widget_Item_Data *item,
5605 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
5606 ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
5608 elm_object_tooltip_style_set(item->view, style);
5611 EOLIAN static Eina_Bool
5612 _elm_widget_item_tooltip_window_mode_set(Eo *eo_item EINA_UNUSED,
5613 Elm_Widget_Item_Data *item,
5616 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item, EINA_FALSE);
5617 ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item, EINA_FALSE);
5619 return elm_object_tooltip_window_mode_set(item->view, disable);
5622 EOLIAN static Eina_Bool
5623 _elm_widget_item_tooltip_window_mode_get(Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item)
5625 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item, EINA_FALSE);
5626 ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item, EINA_FALSE);
5628 return elm_object_tooltip_window_mode_get(item->view);
5634 * Get the style for this item tooltip.
5636 * @param item widget item with tooltip already set.
5637 * @return style the theme style in use, defaults to "default". If the
5638 * object does not have a tooltip set, then NULL is returned.
5642 EOLIAN static const char *
5643 _elm_widget_item_tooltip_style_get(Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item)
5645 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item, NULL);
5647 return elm_object_tooltip_style_get(item->view);
5651 _elm_widget_item_cursor_set(Eo *eo_item EINA_UNUSED,
5652 Elm_Widget_Item_Data *item,
5655 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
5656 ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
5658 elm_object_sub_cursor_set(item->view, item->widget, cursor);
5661 EOLIAN static const char *
5662 _elm_widget_item_cursor_get(Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item)
5664 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item, NULL);
5665 return elm_object_cursor_get(item->view);
5669 _elm_widget_item_cursor_unset(Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item)
5671 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
5672 ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
5674 elm_object_cursor_unset(item->view);
5680 * Sets a different style for this item cursor.
5682 * @note before you set a style you should define a cursor with
5683 * elm_widget_item_cursor_set()
5685 * @param item widget item with cursor already set.
5686 * @param style the theme style to use (default, transparent, ...)
5691 _elm_widget_item_cursor_style_set(Eo *eo_item EINA_UNUSED,
5692 Elm_Widget_Item_Data *item,
5695 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
5696 ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
5698 elm_object_cursor_style_set(item->view, style);
5704 * Get the style for this item cursor.
5706 * @param item widget item with cursor already set.
5707 * @return style the theme style in use, defaults to "default". If the
5708 * object does not have a cursor set, then NULL is returned.
5712 EOLIAN static const char *
5713 _elm_widget_item_cursor_style_get(Eo *eo_item EINA_UNUSED,
5714 Elm_Widget_Item_Data *item)
5716 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item, NULL);
5717 return elm_object_cursor_style_get(item->view);
5723 * Set if the cursor set should be searched on the theme or should use
5724 * the provided by the engine, only.
5726 * @note before you set if should look on theme you should define a cursor
5727 * with elm_object_cursor_set(). By default it will only look for cursors
5728 * provided by the engine.
5730 * @param item widget item with cursor already set.
5731 * @param engine_only boolean to define it cursors should be looked only
5732 * between the provided by the engine or searched on widget's theme as well.
5737 _elm_widget_item_cursor_engine_only_set(Eo *eo_item EINA_UNUSED,
5738 Elm_Widget_Item_Data *item,
5739 Eina_Bool engine_only)
5741 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
5742 ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
5744 elm_object_cursor_theme_search_enabled_set(item->view, !engine_only);
5750 * Get the cursor engine only usage for this item cursor.
5752 * @param item widget item with cursor already set.
5753 * @return engine_only boolean to define it cursors should be looked only
5754 * between the provided by the engine or searched on widget's theme as well. If
5755 * the object does not have a cursor set, then EINA_FALSE is returned.
5759 EOLIAN static Eina_Bool
5760 _elm_widget_item_cursor_engine_only_get(Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item)
5762 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item, EINA_FALSE);
5763 return !elm_object_cursor_theme_search_enabled_get(item->view);
5767 _elm_widget_item_part_content_set(Eo *eo_item EINA_UNUSED,
5768 Elm_Widget_Item_Data *item,
5769 const char *part EINA_UNUSED,
5770 Evas_Object *content EINA_UNUSED)
5772 ERR_NOT_SUPPORTED(item, "elm_object_part_content_set()");
5775 EOLIAN static Evas_Object *
5776 _elm_widget_item_part_content_get(Eo *eo_item EINA_UNUSED,
5777 Elm_Widget_Item_Data *item,
5778 const char *part EINA_UNUSED)
5780 ERR_NOT_SUPPORTED(item, "elm_object_part_content_get()");
5784 EOLIAN static Evas_Object *
5785 _elm_widget_item_part_content_unset(Eo *eo_item EINA_UNUSED,
5786 Elm_Widget_Item_Data *item,
5787 const char *part EINA_UNUSED)
5789 ERR_NOT_SUPPORTED(item, "elm_object_part_content_unset()");
5794 _elm_widget_item_part_text_set(Eo *eo_item EINA_UNUSED,
5795 Elm_Widget_Item_Data *item,
5796 const char *part EINA_UNUSED,
5797 const char *label EINA_UNUSED)
5799 ERR_NOT_SUPPORTED(item, "elm_object_part_text_set()");
5802 EOLIAN static const char *
5803 _elm_widget_item_part_text_get(Eo *eo_item EINA_UNUSED,
5804 Elm_Widget_Item_Data *item,
5805 const char *part EINA_UNUSED)
5807 ERR_NOT_SUPPORTED(item, "elm_object_part_text_get()");
5812 _elm_widget_item_part_text_custom_free(void *data)
5814 Elm_Label_Data *label;
5816 eina_stringshare_del(label->part);
5817 eina_stringshare_del(label->text);
5822 _elm_widget_item_part_text_custom_set(Eo *eo_item EINA_UNUSED,
5823 Elm_Widget_Item_Data *item,
5827 Elm_Label_Data *label;
5828 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
5829 ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
5833 eina_hash_stringshared_new(_elm_widget_item_part_text_custom_free);
5834 label = eina_hash_find(item->labels, part);
5837 label = malloc(sizeof(Elm_Label_Data));
5840 ERR("Failed to allocate memory");
5843 label->part = eina_stringshare_add(part);
5844 label->text = eina_stringshare_add(text);
5845 eina_hash_add(item->labels, part, label);
5848 eina_stringshare_replace(&label->text, text);
5851 EOLIAN static const char *
5852 _elm_widget_item_part_text_custom_get(Eo *eo_item EINA_UNUSED,
5853 Elm_Widget_Item_Data *item,
5856 Elm_Label_Data *label;
5857 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item, NULL);
5858 label = eina_hash_find(item->labels, part);
5859 return label ? label->text : NULL;
5863 _elm_widget_item_part_text_custom_foreach(const Eina_Hash *labels EINA_UNUSED,
5864 const void *key EINA_UNUSED,
5868 Elm_Label_Data *label;
5869 Elm_Widget_Item_Data *item;
5873 eo_do(item->eo_obj, elm_wdg_item_part_text_set(label->part, label->text));
5879 _elm_widget_item_part_text_custom_update(Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item)
5881 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
5882 ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
5884 eina_hash_foreach(item->labels,
5885 _elm_widget_item_part_text_custom_foreach, item);
5889 _elm_widget_item_signal_emit(Eo *eo_item EINA_UNUSED,
5890 Elm_Widget_Item_Data *item EINA_UNUSED,
5891 const char *emission EINA_UNUSED,
5892 const char *source EINA_UNUSED)
5898 _elm_widget_item_signal_callback_add(Eo *eo_item,
5899 Elm_Widget_Item_Data *item,
5900 const char *emission,
5902 Elm_Object_Item_Signal_Cb func,
5905 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
5906 ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
5907 EINA_SAFETY_ON_NULL_RETURN(func);
5909 Elm_Widget_Item_Signal_Data *wisd;
5911 wisd = malloc(sizeof(Elm_Widget_Item_Signal_Data));
5914 wisd->item = eo_item;
5915 wisd->func = (Elm_Widget_Item_Signal_Cb)func;
5917 wisd->emission = eina_stringshare_add(emission);
5918 wisd->source = eina_stringshare_add(source);
5920 if (_elm_widget_is(item->view))
5921 elm_object_signal_callback_add(item->view, emission, source, _elm_widget_item_signal_cb, wisd);
5922 else if (eo_isa(item->view, EDJE_OBJECT_CLASS))
5923 edje_object_signal_callback_add(item->view, emission, source, _elm_widget_item_signal_cb, wisd);
5926 WRN("The %s widget item doesn't support signal callback add!",
5927 eo_class_name_get(eo_class_get(item->widget)));
5932 item->signals = eina_list_append(item->signals, wisd);
5935 EOLIAN static void *
5936 _elm_widget_item_signal_callback_del(Eo *eo_item EINA_UNUSED,
5937 Elm_Widget_Item_Data *item,
5938 const char *emission,
5940 Elm_Object_Item_Signal_Cb func)
5942 Elm_Widget_Item_Signal_Data *wisd;
5945 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item, NULL);
5946 ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item, NULL);
5947 EINA_SAFETY_ON_NULL_RETURN_VAL(func, NULL);
5949 EINA_LIST_FOREACH(item->signals, l, wisd)
5951 if ((wisd->func == (Elm_Widget_Item_Signal_Cb)func) &&
5952 !strcmp(wisd->emission, emission) &&
5953 !strcmp(wisd->source, source))
5954 return _elm_widget_item_signal_callback_list_get(item, l);
5961 _elm_widget_item_access_info_set(Eo *eo_item EINA_UNUSED,
5962 Elm_Widget_Item_Data *item,
5965 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
5966 ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
5968 eina_stringshare_del(item->access_info);
5969 if (!txt) item->access_info = NULL;
5970 else item->access_info = eina_stringshare_add(txt);
5974 _elm_widget_item_translate(Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item)
5976 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
5977 ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
5980 Elm_Translate_String_Data *ts;
5981 EINA_INLIST_FOREACH(item->translate_strings, ts)
5983 if (!ts->string) continue;
5984 const char *s = dgettext(ts->domain, ts->string);
5985 item->on_translate = EINA_TRUE;
5986 eo_do(item->eo_obj, elm_wdg_item_part_text_set(ts->id, s));
5987 item->on_translate = EINA_FALSE;
5993 _elm_widget_item_access_order_set(Eo *eo_item EINA_UNUSED,
5994 Elm_Widget_Item_Data *item,
5997 _elm_access_widget_item_access_order_set(item, objs);
6000 EOLIAN static const Eina_List *
6001 _elm_widget_item_access_order_get(const Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item)
6003 return _elm_access_widget_item_access_order_get(item);
6007 _elm_widget_item_access_order_unset(Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item)
6009 _elm_access_widget_item_access_order_unset(item);
6012 EOLIAN static Evas_Object*
6013 _elm_widget_item_access_register(Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item)
6015 _elm_access_widget_item_register(item);
6016 return item->access_obj;
6020 _elm_widget_item_access_unregister(Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item)
6022 _elm_access_widget_item_unregister(item);
6025 EOLIAN static Evas_Object*
6026 _elm_widget_item_access_object_get(const Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item)
6028 return item->access_obj;
6031 EOLIAN static Evas_Object *
6032 _elm_widget_item_focus_next_object_get(const Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item, Elm_Focus_Direction dir)
6034 Evas_Object *ret = NULL;
6036 if (dir == ELM_FOCUS_PREVIOUS)
6037 ret = item->focus_previous;
6038 else if (dir == ELM_FOCUS_NEXT)
6039 ret = item->focus_next;
6040 else if (dir == ELM_FOCUS_UP)
6041 ret = item->focus_up;
6042 else if (dir == ELM_FOCUS_DOWN)
6043 ret = item->focus_down;
6044 else if (dir == ELM_FOCUS_RIGHT)
6045 ret = item->focus_right;
6046 else if (dir == ELM_FOCUS_LEFT)
6047 ret = item->focus_left;
6053 _elm_widget_item_focus_next_object_set(Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item, Evas_Object *next, Elm_Focus_Direction dir)
6055 if (dir == ELM_FOCUS_PREVIOUS)
6056 item->focus_previous = next;
6057 else if (dir == ELM_FOCUS_NEXT)
6058 item->focus_next = next;
6059 else if (dir == ELM_FOCUS_UP)
6060 item->focus_up = next;
6061 else if (dir == ELM_FOCUS_DOWN)
6062 item->focus_down = next;
6063 else if (dir == ELM_FOCUS_RIGHT)
6064 item->focus_right = next;
6065 else if (dir == ELM_FOCUS_LEFT)
6066 item->focus_left = next;
6069 EOLIAN static Elm_Object_Item*
6070 _elm_widget_item_focus_next_item_get(const Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item, Elm_Focus_Direction dir)
6072 Elm_Object_Item *ret = NULL;
6074 if (dir == ELM_FOCUS_PREVIOUS)
6075 ret = item->item_focus_previous;
6076 else if (dir == ELM_FOCUS_NEXT)
6077 ret = item->item_focus_next;
6078 else if (dir == ELM_FOCUS_UP)
6079 ret = item->item_focus_up;
6080 else if (dir == ELM_FOCUS_DOWN)
6081 ret = item->item_focus_down;
6082 else if (dir == ELM_FOCUS_RIGHT)
6083 ret = item->item_focus_right;
6084 else if (dir == ELM_FOCUS_LEFT)
6085 ret = item->item_focus_left;
6091 _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)
6093 if (dir == ELM_FOCUS_PREVIOUS)
6094 item->item_focus_previous = next_item;
6095 else if (dir == ELM_FOCUS_NEXT)
6096 item->item_focus_next = next_item;
6097 else if (dir == ELM_FOCUS_UP)
6098 item->item_focus_up = next_item;
6099 else if (dir == ELM_FOCUS_DOWN)
6100 item->item_focus_down = next_item;
6101 else if (dir == ELM_FOCUS_RIGHT)
6102 item->item_focus_right = next_item;
6103 else if (dir == ELM_FOCUS_LEFT)
6104 item->item_focus_left = next_item;
6107 /* happy debug functions */
6110 _sub_obj_tree_dump(const Evas_Object *obj,
6115 for (i = 0; i < lvl * 3; i++)
6118 if (_elm_widget_is(obj))
6123 elm_widget_type_get(obj),
6125 EINA_LIST_FOREACH(sd->subobjs, l, obj)
6126 _sub_obj_tree_dump(obj, lvl + 1);
6129 DBG("+ %s(%p)\n", evas_object_type_get(obj), obj);
6133 _sub_obj_tree_dot_dump(const Evas_Object *obj,
6136 if (!_elm_widget_is(obj))
6140 Eina_Bool visible = evas_object_visible_get(obj);
6141 Eina_Bool disabled = elm_widget_disabled_get(obj);
6142 Eina_Bool focused = elm_widget_focus_get(obj);
6143 Eina_Bool can_focus = elm_widget_can_focus_get(obj);
6147 fprintf(output, "\"%p\" -- \"%p\" [ color=black", sd->parent_obj, obj);
6150 fprintf(output, ", style=bold");
6153 fprintf(output, ", color=gray28");
6155 fprintf(output, " ];\n");
6158 fprintf(output, "\"%p\" [ label = \"{%p|%s|%s|visible: %d|"
6159 "disabled: %d|focused: %d/%d|focus order:%d}\"",
6160 obj, obj, elm_widget_type_get(obj),
6161 evas_object_name_get(obj), visible, disabled, focused, can_focus,
6165 fprintf(output, ", style=bold");
6168 fprintf(output, ", fontcolor=gray28");
6170 if ((disabled) || (!visible))
6171 fprintf(output, ", color=gray");
6173 fprintf(output, " ];\n");
6177 EINA_LIST_FOREACH(sd->subobjs, l, o)
6178 _sub_obj_tree_dot_dump(o, output);
6184 elm_widget_tree_dump(const Evas_Object *top)
6187 if (!_elm_widget_is(top))
6189 _sub_obj_tree_dump(top, 0);
6197 elm_widget_tree_dot_dump(const Evas_Object *top,
6201 if (!_elm_widget_is(top))
6203 fprintf(output, "graph " " { node [shape=record];\n");
6204 _sub_obj_tree_dot_dump(top, output);
6205 fprintf(output, "}\n");
6214 _elm_widget_eo_base_constructor(Eo *obj, Elm_Widget_Smart_Data *sd EINA_UNUSED)
6218 sd->on_create = EINA_TRUE;
6219 obj = eo_do_super_ret(obj, MY_CLASS, obj, eo_constructor());
6221 evas_obj_type_set(MY_CLASS_NAME_LEGACY),
6222 evas_obj_smart_callbacks_descriptions_set(_smart_callbacks),
6223 parent = eo_parent_get());
6224 eo_do(obj, elm_obj_widget_parent_set(parent));
6225 sd->on_create = EINA_FALSE;
6226 //TIZEN_ONLY(20170717) : expose highlight information on atspi
6227 sd->can_highlight = EINA_TRUE;
6229 /* TIZEN_ONLY(20160622): Override Paragraph Direction APIs */
6230 sd->inherit_paragraph_direction = EINA_TRUE;
6233 eo_do(obj, elm_interface_atspi_accessible_role_set(ELM_ATSPI_ROLE_UNKNOWN));
6235 /* TIZEN_ONLY(20161117): Inherit paragraph direction from widget parent */
6236 if (sd->paragraph_direction != evas_object_paragraph_direction_get(parent))
6238 sd->paragraph_direction = evas_object_paragraph_direction_get(parent);
6239 _elm_widget_evas_object_paragraph_direction_set_internal(obj, sd, sd->paragraph_direction);
6240 eo_do_super(obj, MY_CLASS, evas_obj_paragraph_direction_set(sd->paragraph_direction));
6248 _elm_widget_eo_base_destructor(Eo *obj, Elm_Widget_Smart_Data *sd EINA_UNUSED)
6250 sd->on_destroy = EINA_TRUE;
6252 elm_interface_atspi_accessible_description_set(NULL),
6253 elm_interface_atspi_accessible_name_set(NULL),
6254 //TIZEN_ONLY(20190922): add name callback, description callback.
6255 elm_interface_atspi_accessible_description_cb_set(NULL, NULL),
6256 elm_interface_atspi_accessible_name_cb_set(NULL, NULL),
6258 //TIZEN_ONLY(20170405) Add gesture method to accessible interface
6259 elm_interface_atspi_accessible_gesture_cb_set(NULL, NULL),
6261 elm_interface_atspi_accessible_translation_domain_set(NULL),
6262 elm_interface_atspi_accessible_relationships_clear(),
6263 // TIZEN_ONLY(20160930) : endless recursion fix
6264 elm_interface_atspi_accessible_attributes_clear()
6267 // TIZEN_ONLY(20150709) : atspi relations api
6268 if (sd->atspi_custom_relations)
6269 elm_atspi_relation_set_free(&sd->atspi_custom_relations);
6271 //TIZEN_ONLY(20150717) add widget name setter
6273 eina_stringshare_del(sd->name);
6276 //TIZEN_ONLY(20150731) : add i18n support for name and description
6277 if (sd->atspi_translation_domain)
6278 eina_stringshare_del(sd->atspi_translation_domain);
6280 //Tizen Only(20160728) free attribute list
6283 Elm_Atspi_Attribute *attr;
6284 EINA_LIST_FREE(sd->attr_list, attr)
6286 eina_stringshare_del(attr->key);
6287 eina_stringshare_del(attr->value);
6293 eo_do_super(obj, ELM_WIDGET_CLASS, eo_destructor());
6294 sd->on_destroy = EINA_FALSE;
6296 elm_interface_atspi_accessible_removed(obj);
6299 EOLIAN static Eina_Bool
6300 _elm_widget_on_focus(Eo *obj, Elm_Widget_Smart_Data *sd, Elm_Object_Item *item EINA_UNUSED)
6302 if (elm_widget_can_focus_get(obj))
6304 if (elm_widget_focus_get(obj))
6306 if (!sd->resize_obj)
6307 evas_object_focus_set(obj, EINA_TRUE);
6308 eo_do(obj, eo_event_callback_call
6309 (ELM_WIDGET_EVENT_FOCUSED, NULL));
6310 if (_elm_atspi_enabled() && !elm_widget_child_can_focus_get(obj))
6311 elm_interface_atspi_accessible_state_changed_signal_emit(obj, ELM_ATSPI_STATE_FOCUSED, EINA_TRUE);
6315 if (!sd->resize_obj)
6316 evas_object_focus_set(obj, EINA_FALSE);
6317 eo_do(obj, eo_event_callback_call
6318 (ELM_WIDGET_EVENT_UNFOCUSED, NULL));
6319 if (_elm_atspi_enabled() && !elm_widget_child_can_focus_get(obj))
6320 elm_interface_atspi_accessible_state_changed_signal_emit(obj, ELM_ATSPI_STATE_FOCUSED, EINA_FALSE);
6329 EOLIAN static Eina_Bool
6330 _elm_widget_disable(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *_pd EINA_UNUSED)
6335 EOLIAN static Eina_Bool
6336 _elm_widget_event(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *_pd EINA_UNUSED, Evas_Object *source EINA_UNUSED, Evas_Callback_Type type EINA_UNUSED, void *event_info EINA_UNUSED)
6341 EOLIAN static Eina_Bool
6342 _elm_widget_focus_next_manager_is(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *_pd EINA_UNUSED)
6344 WRN("The %s widget does not implement the \"focus_next/focus_next_manager_is\" functions.",
6345 eo_class_name_get(eo_class_get(obj)));
6350 _elm_widget_focus_direction_manager_is(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *_pd EINA_UNUSED)
6352 WRN("The %s widget does not implement the \"focus_direction/focus_direction_manager_is\" functions.",
6353 eo_class_name_get(eo_class_get(obj)));
6357 EOLIAN static Eina_Bool
6358 _elm_widget_activate(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *_pd EINA_UNUSED, Elm_Activate act EINA_UNUSED)
6360 WRN("The %s widget does not implement the \"activate\" functions.",
6361 eo_class_name_get(eo_class_get(obj)));
6366 _elm_widget_class_constructor(Eo_Class *klass)
6368 evas_smart_legacy_type_register(MY_CLASS_NAME_LEGACY, klass);
6371 EOLIAN static Eina_Bool
6372 _elm_widget_elm_interface_atspi_component_focus_grab(Eo *obj, Elm_Widget_Smart_Data *pd EINA_UNUSED)
6374 if (elm_object_focus_allow_get(obj))
6376 Ecore_Evas *ee = ecore_evas_ecore_evas_get(evas_object_evas_get(obj));
6377 if (!ee) return EINA_FALSE;
6378 ecore_evas_activate(ee);
6379 elm_object_focus_set(obj, EINA_TRUE);
6385 //TIZEN_ONLY(20170119): Show the object highlighted by highlight_grab when the object is completely out of the scroll
6387 _elm_widget_showing_geometry_get(Eo *obj, int *x, int *y, int *w, int *h)
6389 Evas_Object *parent;
6390 Evas_Coord px, py, sx, sy, sw, sh;
6399 evas_object_geometry_get(obj, x, y, w, h);
6401 if (elm_widget_is(obj))
6402 parent = elm_widget_parent_get(obj);
6404 parent = elm_widget_parent_widget_get(obj);
6408 if (eo_isa(parent, ELM_INTERFACE_SCROLLABLE_MIXIN))
6410 evas_object_geometry_get(parent, &sx, &sy, &sw, &sh);
6413 *x = *x > sx ? *x : sx;
6414 *y = *y > sy ? *y : sy;
6415 *w = px + *w < sx + sw ? px + *w - *x : sx + sw - *x;
6416 *h = py + *h < sy + sh ? py + *h - *y : sy + sh - *y;
6418 parent = elm_widget_parent_get(parent);
6423 _accessible_object_on_screen_is(Eo *obj, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h, Eina_Bool is_complete)
6425 if(!obj) return EINA_FALSE;
6427 Evas_Object *target = obj;
6428 Evas_Object *parent = NULL;
6429 Evas_Coord px, py, sx, sy, sw, sh, ox, oy, ow, oh;
6431 /* uninitialized data could be read */
6435 if (elm_widget_is(target))
6436 parent = elm_widget_parent_get(target);
6438 parent = elm_widget_parent_widget_get(target);
6442 if (eo_isa(parent, ELM_INTERFACE_SCROLLABLE_MIXIN))
6444 evas_object_geometry_get(parent, &sx, &sy, &sw, &sh);
6449 ox = is_complete ? ox : ox + ow;
6450 oy = is_complete ? oy : oy + oh;
6451 ox = ox > sx ? ox : sx;
6452 oy = oy > sy ? oy : sy;
6453 ow = px + ow < sx + sw ? px + ow - ox : sx + sw - ox;
6454 oh = py + oh < sy + sh ? py + oh - oy : sy + sh - oy;
6456 if (ow <= 0 || oh <= 0)
6459 parent = elm_widget_parent_get(parent);
6465 _accessible_scrollable_parent_list_get(Eo *obj)
6467 if(!obj) return NULL;
6469 Evas_Object *parent = NULL;
6470 Eina_List *plist = NULL;
6472 if (elm_widget_is(obj))
6473 parent = elm_widget_parent_get(obj);
6475 parent = elm_widget_parent_widget_get(obj);
6479 if (_elm_scrollable_is(parent))
6480 plist = eina_list_append(plist, parent);
6482 parent = elm_widget_parent_get(parent);
6488 _accessible_highlight_region_show(Eo* obj)
6492 Evas_Object *target = obj;
6493 Evas_Object *parent = NULL;
6494 Evas_Object *parent_sub = NULL;
6495 Eina_List *plist, *plist_sub;
6498 Evas_Coord target_x, target_y, target_w, target_h;
6500 evas_object_geometry_get(target, &target_x, &target_y, &target_w, &target_h);
6502 plist = _accessible_scrollable_parent_list_get(target);
6505 EINA_LIST_FOREACH(plist, l, parent)
6507 if(!_accessible_object_on_screen_is(target, target_x, target_y, target_w, target_h, EINA_TRUE))
6509 plist_sub = _accessible_scrollable_parent_list_get(parent);
6510 plist_sub = eina_list_prepend(plist_sub, parent);
6511 EINA_LIST_FOREACH(plist_sub, l2, parent_sub)
6513 Evas_Coord scroll_x = 0, scroll_y = 0;
6514 Evas_Coord scroll_x_back = 0, scroll_y_back = 0;
6515 Evas_Coord x, y, w, h;
6518 eo_do(parent_sub, elm_interface_scrollable_content_region_get(&scroll_x_back, &scroll_y_back, NULL, NULL));
6519 evas_object_geometry_get(parent_sub, &px, &py, NULL, NULL);
6520 x = target_x; y = target_y; w = target_w; h = target_h;
6522 x -= (px - scroll_x_back);
6523 y -= (py - scroll_y_back);
6524 switch (_elm_config->focus_autoscroll_mode)
6526 case ELM_FOCUS_AUTOSCROLL_MODE_SHOW:
6527 eo_do(parent_sub, elm_interface_scrollable_content_region_show(x, y, w, h));
6529 case ELM_FOCUS_AUTOSCROLL_MODE_BRING_IN:
6530 eo_do(parent_sub, elm_interface_scrollable_region_bring_in(x, y, w, h));
6535 eo_do(parent_sub, elm_interface_scrollable_content_region_get(&scroll_x, &scroll_y, NULL, NULL));
6537 target_x -= (scroll_x - scroll_x_back);
6538 target_y -= (scroll_y - scroll_y_back);
6540 if(_accessible_object_on_screen_is(target, target_x, target_y, target_w, target_h, EINA_FALSE))
6543 eina_list_free(plist_sub);
6547 eina_list_free(plist);
6551 //TIZEN_ONLY(20160329): atspi: implement HighlightGrab and HighlightClear methods (29e253e2f7ef3c632ac3a64c489bf569df407f30)
6552 EOLIAN static Eina_Bool
6553 _elm_widget_elm_interface_atspi_component_highlight_grab(Eo *obj, Elm_Widget_Smart_Data *pd EINA_UNUSED)
6555 if(!obj) return EINA_FALSE;
6556 if(!_elm_atspi_enabled())
6559 //TIZEN_ONLY(20170119): Show the object highlighted by highlight_grab when the object is completely out of the scroll
6560 _accessible_highlight_region_show(obj);
6563 elm_object_accessibility_highlight_set(obj, EINA_TRUE);
6564 elm_interface_atspi_accessible_state_changed_signal_emit(obj, ELM_ATSPI_STATE_HIGHLIGHTED, EINA_TRUE);
6566 // TIZEN_ONLY(20161018): add highlighted/unhighlighted signal for atspi
6567 evas_object_smart_callback_call(obj, SIG_WIDGET_ATSPI_HIGHLIGHTED, NULL);
6572 EOLIAN static Eina_Bool
6573 _elm_widget_elm_interface_atspi_component_highlight_clear(Eo *obj, Elm_Widget_Smart_Data *pd EINA_UNUSED)
6575 if(!_elm_atspi_enabled())
6577 elm_object_accessibility_highlight_set(obj, EINA_FALSE);
6578 elm_interface_atspi_accessible_state_changed_signal_emit(obj, ELM_ATSPI_STATE_HIGHLIGHTED, EINA_FALSE);
6580 // TIZEN_ONLY(20161018): add highlighted/unhighlighted signal for atspi
6581 evas_object_smart_callback_call(obj, SIG_WIDGET_ATSPI_UNHIGHLIGHTED, NULL);
6587 EOLIAN static const char*
6588 _elm_widget_elm_interface_atspi_accessible_name_get(Eo *obj, Elm_Widget_Smart_Data *_pd)
6590 //TIZEN_ONLY(20190922): add name callback, description callback.
6591 const char *ret = NULL;
6592 eo_do_super(obj, ELM_WIDGET_CLASS, ret = elm_interface_atspi_accessible_name_get());
6593 if (ret) return ret;
6596 //TIZEN_ONLY(20150717) add widget name setter
6600 if (_pd->atspi_translation_domain)
6601 return dgettext(_pd->atspi_translation_domain, _pd->name);
6607 //TIZEN_ONLY(20170110) : Ignore text from elm_object_text_set in accessible_name_get
6608 Elm_Atspi_Role role;
6609 eo_do(obj, role = elm_interface_atspi_accessible_role_get());
6610 if(role == ELM_ATSPI_ROLE_DIALOG)
6614 ret = elm_object_text_get(obj);
6615 if (!ret) return NULL;
6617 return _elm_widget_accessible_plain_name_get(obj, ret);
6619 //TIZEN_ONLY(20161111) add widget/widget_item description get/set
6621 _elm_widget_elm_interface_atspi_accessible_description_set(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data* _pd EINA_UNUSED, const char *description)
6623 if (_pd->description)
6624 eina_stringshare_del(_pd->description);
6626 _pd->description = eina_stringshare_add(description);
6629 EOLIAN static const char*
6630 _elm_widget_elm_interface_atspi_accessible_description_get(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *_pd EINA_UNUSED)
6632 const char *ret = NULL;
6633 eo_do_super(obj, ELM_WIDGET_CLASS, ret = elm_interface_atspi_accessible_description_get());
6634 if (ret) return ret;
6637 if (_pd->atspi_translation_domain)
6638 return dgettext(_pd->atspi_translation_domain, _pd->description);
6640 return _pd->description;
6644 //TIZEN_ONLY(20150713) : add atspi name setter to widget_item
6646 _elm_widget_item_elm_interface_atspi_accessible_name_set(Eo *obj EINA_UNUSED, Elm_Widget_Item_Data* _pd EINA_UNUSED, const char *name)
6649 eina_stringshare_del(_pd->name);
6651 _pd->name = eina_stringshare_add(name);
6655 _elm_widget_item_elm_interface_atspi_accessible_name_get(Eo *obj EINA_UNUSED, Elm_Widget_Item_Data *_pd EINA_UNUSED)
6657 //TIZEN_ONLY(20190922): add name callback, description callback.
6658 const char *ret = NULL;
6659 eo_do_super(obj, ELM_WIDGET_ITEM_CLASS, ret = elm_interface_atspi_accessible_name_get());
6660 if (ret) return ret;
6666 if (_pd->atspi_translation_domain)
6667 return dgettext(_pd->atspi_translation_domain, _pd->name);
6675 //TIZEN_ONLY(20161111) add widget/widget_item description get/set
6677 _elm_widget_item_elm_interface_atspi_accessible_description_set(Eo *obj EINA_UNUSED, Elm_Widget_Item_Data* _pd EINA_UNUSED, const char *description)
6679 if (_pd->description)
6680 eina_stringshare_del(_pd->description);
6682 _pd->description = eina_stringshare_add(description);
6686 _elm_widget_item_elm_interface_atspi_accessible_description_get(Eo *obj EINA_UNUSED, Elm_Widget_Item_Data *_pd EINA_UNUSED)
6688 const char *ret = NULL;
6689 eo_do_super(obj, ELM_WIDGET_ITEM_CLASS, ret = elm_interface_atspi_accessible_description_get());
6690 if (ret) return ret;
6693 if (_pd->atspi_translation_domain)
6694 return dgettext(_pd->atspi_translation_domain, _pd->description);
6696 return _pd->description;
6699 //TIZEN_ONLY(20150709) : spatially sort atspi children
6700 static int _sort_vertically(const void *data1, const void *data2)
6703 evas_object_geometry_get(data1, NULL, &y1, NULL, NULL);
6704 evas_object_geometry_get(data2, NULL, &y2, NULL, NULL);
6706 return y1 < y2 ? -1 : 1;
6709 static int _sort_horizontally(const void *data1, const void *data2)
6712 evas_object_geometry_get(data1, &x1, NULL, NULL, NULL);
6713 evas_object_geometry_get(data2, &x2, NULL, NULL, NULL);
6715 return x1 < x2 ? -1 : 1;
6718 static Eina_List *_lines_split(Eina_List *children)
6721 Eina_List *lines, *line, *l;
6722 Evas_Coord yl, y, hl, h;
6723 lines = line = NULL;
6725 if (!children) return NULL;
6727 EINA_LIST_FOREACH(children, l, c)
6729 evas_object_geometry_get(c, NULL, &yl, NULL, &hl);
6731 /* remove child if its height == 0 */
6735 EINA_LIST_FREE(children, c)
6737 evas_object_geometry_get(c, NULL, &y, NULL, &h);
6739 /* remove child if its height == 0 */
6740 if (h == 0 && !eo_isa(c, ELM_ATSPI_PROXY_CLASS)) continue;
6742 if ((yl + (int)(0.25 * hl)) >= y)
6745 line = eina_list_append(line,c);
6749 // finish current line & start new
6750 lines = eina_list_append(lines, line);
6752 line = eina_list_append(NULL, c);
6756 return eina_list_append(lines, line);
6760 // TIZEN_ONLY(20160705) - enable atspi_proxy to work
6762 _proxy_widget_move_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
6767 evas_object_geometry_get(obj, &x, &y, NULL, NULL);
6768 elm_atspi_bridge_utils_proxy_offset_set(proxy, x, y);
6773 _on_widget_del(void *data, Eo *obj EINA_UNUSED, const Eo_Event_Description *desc EINA_UNUSED, void *event_info EINA_UNUSED)
6776 // TIZEN_ONLY(20160705) - enable atspi_proxy to work
6777 evas_object_event_callback_del_full(obj, EVAS_CALLBACK_MOVE,
6778 _proxy_widget_move_cb, plug);
6784 // TIZEN_ONLY(20160705) - enable atspi_proxy to work
6786 _on_proxy_connected_cb(void *data, Eo *obj, const Eo_Event_Description *desc EINA_UNUSED, void *event_info EINA_UNUSED)
6789 Evas_Object *widget = data;
6791 evas_object_geometry_get(widget, &x, &y, NULL, NULL);
6792 elm_atspi_bridge_utils_proxy_offset_set(obj, x, y);
6794 evas_object_event_callback_add(widget, EVAS_CALLBACK_MOVE, _proxy_widget_move_cb, obj);
6800 //TIZEN_ONLY(20170621) handle atspi proxy connection at runtime
6802 _plug_type_proxy_get(Eo *obj, Evas_Object *widget)
6805 const char *plug_id;
6806 char *svcname, *svcnum;
6808 if ((plug_id = evas_object_data_get(widget, "___PLUGID")) != NULL)
6810 // TIZEN_ONLY(20160930) : endless recursion fix
6811 eo_do_super(obj, MY_CLASS, elm_interface_atspi_accessible_attribute_append("___PlugID", plug_id));
6813 proxy = evas_object_data_get(widget, "__widget_proxy");
6814 if (proxy) return proxy;
6816 if (_elm_atspi_bridge_plug_id_split(plug_id, &svcname, &svcnum))
6818 proxy = _elm_atspi_bridge_utils_proxy_create(obj, svcname, atoi(svcnum), ELM_ATSPI_PROXY_TYPE_PLUG);
6819 evas_object_data_set(widget, "__widget_proxy", proxy);
6820 eo_do(widget, eo_event_callback_add(EO_EV_DEL, _on_widget_del, proxy));
6821 eo_do(proxy, eo_event_callback_add(ELM_ATSPI_PROXY_EVENT_CONNECTED, _on_proxy_connected_cb, widget));
6822 elm_atspi_bridge_utils_proxy_connect(proxy);
6832 elm_widget_atspi_plug_type_proxy_get(Evas_Object *obj)
6834 Elm_Widget_Smart_Data *wd;
6835 Evas_Object *widget;
6838 wd = eo_data_scope_get(obj, ELM_WIDGET_CLASS);
6839 if (!wd) return NULL;
6842 EINA_LIST_FOREACH(wd->subobjs, l, widget)
6844 if (evas_object_data_get(widget, "___PLUGID"))
6845 proxy = _plug_type_proxy_get(obj, widget);
6852 EOLIAN static Eina_List*
6853 _elm_widget_elm_interface_atspi_accessible_children_get(Eo *obj, Elm_Widget_Smart_Data *pd EINA_UNUSED)
6855 Eina_List *l, *accs = NULL;
6856 Elm_Widget_Smart_Data *wd;
6857 Evas_Object *widget;
6858 // TIZEN_ONLY(20160824): Do not append a child, if its accessible parent is different with widget parent
6862 wd = eo_data_scope_get(obj, ELM_WIDGET_CLASS);
6863 if (!wd) return NULL;
6865 EINA_LIST_FOREACH(wd->subobjs, l, widget)
6867 const char *type = evas_object_type_get(widget);
6869 // Ugly Tizen hack to integrate AT-SPI2 accessibility provided by WebKit/Chromium with elementary one.
6870 // This wrapper class should be implemented in Webkit/Chromium EFL ports
6871 if (type && (!strcmp(type, "EWebView") || !strcmp(type, "WebView"))) {
6872 elm_atspi_ewk_wrapper_a11y_init(obj, widget);
6877 EINA_LIST_FOREACH(wd->subobjs, l, widget)
6879 // TIZEN_ONLY(20160824): Do not append a child, if its accessible parent is different with widget parent
6880 if (eo_isa(widget, ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN)) {
6881 eo_do(widget, parent = elm_interface_atspi_accessible_parent_get());
6882 if (parent && (parent != obj)) continue;
6885 // TIZEN_ONLY(20160705) - enable atspi_proxy to work
6886 /* This assumes that only one proxy exists in obj */
6889 proxy = _plug_type_proxy_get(obj, widget);
6892 accs = eina_list_append(accs, proxy);
6898 if (!elm_object_widget_check(widget)) continue;
6899 if (eo_isa(widget, ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN))
6900 accs = eina_list_append(accs, widget);
6902 //TIZEN_ONLY(20150709) : spatially sort atspi children
6903 // sort children using its top-left coordinate
6904 accs = eina_list_sort(accs, -1, _sort_vertically);
6905 Eina_List *line, *lines = _lines_split(accs);
6907 EINA_LIST_FREE(lines, line)
6908 accs = eina_list_merge(accs, eina_list_sort(line, -1, _sort_horizontally));
6914 accs = eina_list_remove(accs, proxy);
6915 EINA_LIST_FOREACH(accs, l, widget)
6917 if (eo_isa(widget, ELM_ACCESS_CLASS))
6919 Elm_Access_Info *info = _elm_access_info_get(widget);
6920 if (!info) continue;
6921 if (obj == info->part_object)
6931 accs = eina_list_append_relative(accs, proxy, deputy);
6938 _elm_widget_elm_interface_atspi_accessible_parent_get(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *pd)
6941 eo_do_super(obj, ELM_WIDGET_CLASS, ret = elm_interface_atspi_accessible_parent_get());
6943 return ret ? ret : pd->parent_obj;
6946 //TIZEN_ONLY(20161107): enhance elm_atspi_accessible_can_highlight_set to set can_hihglight property to its children
6948 _elm_widget_highlightable(Evas_Object *obj)
6951 Eina_Bool can_highlight;
6953 Elm_Widget_Smart_Data *wd = eo_data_scope_get(obj, ELM_WIDGET_CLASS);
6954 if (!wd) return EINA_FALSE;
6955 if (!wd->can_highlight) return EINA_FALSE;
6957 eo_do(obj, parent = elm_interface_atspi_accessible_parent_get());
6958 while (parent && !eo_isa(parent, ELM_ATSPI_APP_OBJECT_CLASS))
6960 eo_do(parent, can_highlight = elm_interface_atspi_accessible_can_highlight_get());
6961 if (!can_highlight) return EINA_FALSE;
6962 eo_do(parent, parent = elm_interface_atspi_accessible_parent_get());
6968 EOLIAN static Elm_Atspi_State_Set
6969 _elm_widget_elm_interface_atspi_accessible_state_set_get(Eo *obj, Elm_Widget_Smart_Data *pd)
6971 Elm_Atspi_State_Set states = 0;
6973 eo_do_super(obj, ELM_WIDGET_CLASS, states = elm_interface_atspi_accessible_state_set_get());
6975 if (evas_object_visible_get(obj))
6977 STATE_TYPE_SET(states, ELM_ATSPI_STATE_VISIBLE);
6978 if (_elm_widget_onscreen_is(obj))
6979 STATE_TYPE_SET(states, ELM_ATSPI_STATE_SHOWING);
6981 if (!elm_widget_child_can_focus_get(obj))
6983 if (elm_object_focus_allow_get(obj))
6984 STATE_TYPE_SET(states, ELM_ATSPI_STATE_FOCUSABLE);
6985 if (elm_object_focus_get(obj))
6986 STATE_TYPE_SET(states, ELM_ATSPI_STATE_FOCUSED);
6988 if (!elm_object_disabled_get(obj))
6990 STATE_TYPE_SET(states, ELM_ATSPI_STATE_ENABLED);
6991 STATE_TYPE_SET(states, ELM_ATSPI_STATE_SENSITIVE);
6994 //TIZEN_ONLY(20170717) : expose highlight information on atspi
6995 if (_elm_widget_highlightable(obj) && _accessible_object_on_scroll_is(obj))
6996 STATE_TYPE_SET(states, ELM_ATSPI_STATE_HIGHLIGHTABLE);
6998 STATE_TYPE_UNSET(states, ELM_ATSPI_STATE_HIGHLIGHTABLE);
7000 if (_elm_object_accessibility_currently_highlighted_get() == (void*)pd->obj)
7001 STATE_TYPE_SET(states, ELM_ATSPI_STATE_HIGHLIGHTED);
7007 //TIZEN_ONLY(20160729): attributes_get, append APIs added/updated.
7008 EOLIAN static Eina_List*
7009 _elm_widget_elm_interface_atspi_accessible_attributes_get(Eo *obj, Elm_Widget_Smart_Data *pd EINA_UNUSED)
7011 Eina_List *attr_list = NULL;
7012 // TIZEN_ONLY(20160930) : endless recursion fix
7013 eo_do_super(obj, MY_CLASS, attr_list = elm_interface_atspi_accessible_attributes_get());
7015 //Add type and style information in addition.
7016 Elm_Atspi_Attribute *attr = NULL;
7017 attr = calloc(1, sizeof(Elm_Atspi_Attribute));
7020 attr->key = eina_stringshare_add("type");
7021 attr->value = eina_stringshare_add(elm_widget_type_get(obj));
7022 attr_list = eina_list_append(attr_list, attr);
7025 attr = calloc(1, sizeof(Elm_Atspi_Attribute));
7028 attr->key = eina_stringshare_add("style");
7029 attr->value = eina_stringshare_add(elm_widget_style_get(obj));
7030 attr_list = eina_list_append(attr_list, attr);
7036 //TIZEN_ONLY(20150709) : atspi relations api
7037 EOLIAN static Elm_Atspi_Relation_Set
7038 _elm_widget_elm_interface_atspi_accessible_relation_set_get(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd)
7040 return elm_atspi_relation_set_clone(&sd->atspi_custom_relations);
7043 EOLIAN static Elm_Atspi_Relation_Set
7044 _elm_widget_item_elm_interface_atspi_accessible_relation_set_get(Eo *obj EINA_UNUSED, Elm_Widget_Item_Data *sd)
7046 return elm_atspi_relation_set_clone(&sd->atspi_custom_relations);
7050 _elm_widget_elm_interface_atspi_accessible_relationships_clear(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd)
7052 elm_atspi_relation_set_free(&sd->atspi_custom_relations);
7053 sd->atspi_custom_relations = NULL;
7058 _elm_widget_item_elm_interface_atspi_accessible_relationships_clear(Eo *obj EINA_UNUSED, Elm_Widget_Item_Data *sd)
7060 elm_atspi_relation_set_free(&sd->atspi_custom_relations);
7061 sd->atspi_custom_relations = NULL;
7066 _elm_widget_item_elm_interface_atspi_component_extents_get(Eo *obj EINA_UNUSED, Elm_Widget_Item_Data *sd EINA_UNUSED, Eina_Bool screen_coords, int *x, int *y, int *w, int *h)
7079 evas_object_geometry_get(sd->view, x, y, w, h);
7082 Ecore_Evas *ee = ecore_evas_ecore_evas_get(evas_object_evas_get(sd->view));
7084 ecore_evas_geometry_get(ee, &ee_x, &ee_y, NULL, NULL);
7090 EOLIAN static Eina_Bool
7091 _elm_widget_item_elm_interface_atspi_component_extents_set(Eo *obj EINA_UNUSED, Elm_Widget_Item_Data *sd EINA_UNUSED, Eina_Bool screen_coords EINA_UNUSED, int x EINA_UNUSED, int y EINA_UNUSED, int w EINA_UNUSED, int h EINA_UNUSED)
7097 _elm_widget_item_elm_interface_atspi_component_layer_get(Eo *obj EINA_UNUSED, Elm_Widget_Item_Data *sd EINA_UNUSED)
7101 return evas_object_layer_get(sd->view);
7104 EOLIAN static Eina_Bool
7105 _elm_widget_item_elm_interface_atspi_component_focus_grab(Eo *obj EINA_UNUSED, Elm_Widget_Item_Data *_pd EINA_UNUSED)
7107 elm_object_item_focus_set(obj, EINA_TRUE);
7108 return elm_object_item_focus_get(obj);
7111 //TIZEN_ONLY(20160329): atspi: implement HighlightGrab and HighlightClear methods
7113 EOLIAN static Eina_Bool
7114 _elm_widget_item_elm_interface_atspi_component_highlight_grab(Eo *obj, Elm_Widget_Item_Data *sd)
7116 if (!sd) return EINA_FALSE;
7117 if (!sd->view) return EINA_FALSE;
7119 //TIZEN_ONLY(20170119): Show the object highlighted by highlight_grab when the object is completely out of the scroll
7120 _accessible_highlight_region_show(sd->view);
7123 if (!sd->eo_obj) return EINA_FALSE;
7124 elm_object_accessibility_highlight_set(sd->eo_obj, EINA_TRUE);
7126 if (!obj) return EINA_FALSE;
7127 elm_interface_atspi_accessible_state_changed_signal_emit(obj, ELM_ATSPI_STATE_HIGHLIGHTED, EINA_TRUE);
7129 //TIZEN_ONLY(20170412) Make atspi,(un)highlighted work on widget item
7130 evas_object_smart_callback_call(sd->widget, SIG_WIDGET_ATSPI_HIGHLIGHTED, obj);
7135 EOLIAN static Eina_Bool
7136 _elm_widget_item_elm_interface_atspi_component_highlight_clear(Eo *obj, Elm_Widget_Item_Data *sd)
7138 if (!obj) return EINA_FALSE;
7139 elm_object_accessibility_highlight_set(sd->eo_obj, EINA_FALSE);
7140 elm_interface_atspi_accessible_state_changed_signal_emit(obj, ELM_ATSPI_STATE_HIGHLIGHTED, EINA_FALSE);
7142 //TIZEN_ONLY(20170412) Make atspi,(un)highlighted work on widget item
7143 evas_object_smart_callback_call(sd->widget, SIG_WIDGET_ATSPI_UNHIGHLIGHTED, obj);
7149 EOLIAN static double
7150 _elm_widget_item_elm_interface_atspi_component_alpha_get(Eo *obj EINA_UNUSED, Elm_Widget_Item_Data *sd EINA_UNUSED)
7154 if (!sd->view) return -1.0;
7155 evas_object_color_get(sd->view, NULL, NULL, NULL, &alpha);
7156 return (double)alpha / 255.0;
7159 //TIZEN_ONLY(20150717) add widget name setter
7161 _elm_widget_elm_interface_atspi_accessible_name_set(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data* _pd EINA_UNUSED, const char *name)
7164 eina_stringshare_del(_pd->name);
7166 _pd->name = eina_stringshare_add(name);
7170 //TIZEN_ONLY(20160329): widget: improve accessibile_at_point getter (a8aff0423202b9a55dbb3843205875226678fbd6)
7172 _coordinate_system_based_point_translate(Eo *obj, Eina_Bool screen_coords, int *x, int *y)
7180 ee = ecore_evas_ecore_evas_get(evas_object_evas_get(obj));
7183 ecore_evas_geometry_get(ee, &ee_x, &ee_y, NULL, NULL);
7189 static Evas_Object *
7190 _parent_get(Evas_Object *obj)
7192 Evas_Object *parent;
7194 parent = evas_object_smart_parent_get(obj);
7197 if (strcmp("Elm_Win", eo_class_name_get(eo_class_get(obj))))
7198 parent = elm_widget_parent_get(obj);
7205 _is_inside(Evas_Object *obj, int x, int y)
7207 Eina_Bool ret = EINA_TRUE;
7212 if (eo_isa(obj, ELM_WIDGET_ITEM_CLASS))
7214 Elm_Widget_Item_Data *id = eo_data_scope_get(obj, ELM_WIDGET_ITEM_CLASS);
7215 evas_object_geometry_get(id->view, &cx, &cy, &cw, &ch);
7218 evas_object_geometry_get(obj, &cx, &cy, &cw, &ch);
7220 /* check the point is out of bound */
7221 if (x < cx || x > cx + cw || y < cy || y > cy + ch)
7229 _is_ancestor_of(Evas_Object *smart_parent, Evas_Object *obj)
7231 Eina_Bool ret = EINA_FALSE;
7232 Evas_Object *parent = elm_widget_parent_get(obj);
7235 /* No need to check more, the smart_parent is parent of obj */
7236 if (smart_parent == parent)
7241 parent = elm_widget_parent_get(parent);
7247 static int _sort_by_size(const void *data1, const void *data2)
7252 evas_object_geometry_get(data1, NULL, NULL, &w, &h);
7253 evas_object_geometry_get(data2, NULL, NULL, &w2, &h2);
7255 if ((w * h) > (w2 * h2)) return 1;
7260 _elm_widget_atspi_role_acceptable_check(Eo *obj)
7262 Elm_Atspi_Role role;
7263 eo_do(obj, role = elm_interface_atspi_accessible_role_get());
7267 case ELM_ATSPI_ROLE_APPLICATION:
7268 case ELM_ATSPI_ROLE_FILLER:
7269 case ELM_ATSPI_ROLE_SCROLL_PANE:
7270 case ELM_ATSPI_ROLE_SPLIT_PANE:
7271 case ELM_ATSPI_ROLE_WINDOW:
7272 case ELM_ATSPI_ROLE_IMAGE:
7273 case ELM_ATSPI_ROLE_LIST:
7274 case ELM_ATSPI_ROLE_ICON:
7275 case ELM_ATSPI_ROLE_TOOL_BAR:
7276 case ELM_ATSPI_ROLE_REDUNDANT_OBJECT:
7277 case ELM_ATSPI_ROLE_COLOR_CHOOSER:
7278 case ELM_ATSPI_ROLE_TREE_TABLE:
7279 case ELM_ATSPI_ROLE_PAGE_TAB_LIST:
7280 case ELM_ATSPI_ROLE_PAGE_TAB:
7281 case ELM_ATSPI_ROLE_SPIN_BUTTON:
7282 case ELM_ATSPI_ROLE_INPUT_METHOD_WINDOW:
7283 case ELM_ATSPI_ROLE_EMBEDDED:
7284 case ELM_ATSPI_ROLE_INVALID:
7285 case ELM_ATSPI_ROLE_NOTIFICATION:
7295 _child_object_at_point_get(Eo *obj, int x, int y)
7297 Eina_List *l, *l_next, *children, *valid_children = NULL;
7302 eo_do(obj, children = elm_interface_atspi_accessible_children_get());
7304 EINA_LIST_FOREACH(children, l, child)
7306 if (_is_inside(child, x, y))
7307 valid_children = eina_list_append(valid_children, child);
7310 EINA_LIST_FOREACH_SAFE(valid_children, l, l_next, child)
7312 eo_do(child, children = elm_interface_atspi_accessible_children_get());
7314 /* do not use unacceptable leaf node */
7315 if (!_elm_widget_atspi_role_acceptable_check(child) &&
7316 eina_list_count(children) == 0)
7317 valid_children = eina_list_remove_list(valid_children, l);
7320 count = eina_list_count(valid_children);
7323 valid_children = eina_list_sort(valid_children, -1, _sort_by_size);
7324 target = eina_list_nth(valid_children, 0);
7326 return _child_object_at_point_get(target, x, y);
7333 _is_acceptable_leaf(Eo *obj)
7335 Elm_Atspi_Role role;
7336 Eina_List *children;
7338 eo_do(obj, role = elm_interface_atspi_accessible_role_get());
7341 case ELM_ATSPI_ROLE_IMAGE:
7342 case ELM_ATSPI_ROLE_ICON:
7343 eo_do(obj, children = elm_interface_atspi_accessible_children_get());
7344 if (!children) return EINA_FALSE;
7355 _accessible_at_point_top_down_get(Eo *obj, Elm_Widget_Smart_Data *_pd EINA_UNUSED, Eina_Bool screen_coords, int x, int y)
7357 Eina_List *l, *l2, *children, *valid_children = NULL;
7359 Evas_Object *stack_item;
7361 // TIZEN_ONLY(20160705) - enable atspi_proxy to work
7363 Evas_Coord px, py, pw, ph;
7366 _coordinate_system_based_point_translate(obj, screen_coords, &x, &y);
7368 eo_do(obj, children = elm_interface_atspi_accessible_children_get());
7370 EINA_LIST_FOREACH(children, l2, child)
7372 if (_is_inside(child, x, y) && _is_acceptable_leaf(child))
7373 valid_children = eina_list_append(valid_children, child);
7375 /* Get evas_object stacked at given x,y coordinates starting from top */
7376 Eina_List *stack = evas_tree_objects_at_xy_get(evas_object_evas_get(obj), NULL, x, y);
7377 /* Foreach stacked object starting from top */
7378 EINA_LIST_FOREACH(stack, l, stack_item)
7380 /* Foreach at-spi valid children traverse stack_item evas_objects hierarchy */
7381 EINA_LIST_FOREACH(valid_children, l2, child)
7383 Elm_Atspi_Role role;
7384 eo_do(child, role = elm_interface_atspi_accessible_role_get());
7385 if (role == ELM_ATSPI_ROLE_REDUNDANT_OBJECT)
7387 /* The redundant object ignores */
7390 /* Compare object used to compare with stacked evas objects */
7391 compare_obj = child;
7392 /* In case of widget_items compare should be different then elm_widget_ item object */
7393 if (eo_isa(child, ELM_WIDGET_ITEM_CLASS))
7395 Elm_Widget_Item_Data *id = eo_data_scope_get(child, ELM_WIDGET_ITEM_CLASS);
7396 compare_obj = id->view;
7397 if (TIZEN_PROFILE_WEARABLE)
7399 Eo* it_view = evas_object_image_source_get(stack_item);
7400 if (it_view && it_view == compare_obj)
7402 eina_list_free(children);
7403 eina_list_free(stack);
7408 /* In case of access object compare should be 'wrapped' evas_object */
7409 if (eo_isa(child, ELM_ACCESS_CLASS))
7411 Elm_Access_Info *info = _elm_access_info_get(child);
7412 if (!info) continue;
7413 compare_obj = info->part_object;
7415 /* In case of widget is registerd by elm_access_object_register */
7416 Evas_Object *ao = elm_access_object_get(child);
7419 eina_list_free(children);
7420 eina_list_free(stack);
7424 /* In case of ewk wrapper object compare with internal ewk_view evas_object */
7425 if (eo_isa(child, ELM_ATSPI_EWK_WRAPPER_CLASS))
7427 compare_obj = elm_atspi_ewk_wrapper_ewk_view_get(child);
7430 /* If spacial eo children do not have backing evas_object continue with search */
7434 Evas_Object *smart_parent = stack_item;
7435 while (smart_parent)
7437 if (smart_parent == compare_obj)
7439 eina_list_free(children);
7440 eina_list_free(stack);
7444 // TIZEN_ONLY(20160705) - enable atspi_proxy to work
7445 proxy = evas_object_data_get(smart_parent, "__widget_proxy");
7448 evas_object_geometry_get(smart_parent, &px, &py, &pw, &ph);
7449 if (x >= px && x <= px + pw && y >= py && y <= py +ph)
7451 eina_list_free(children);
7452 eina_list_free(stack);
7458 smart_parent = _parent_get(smart_parent);
7459 if (_is_ancestor_of(smart_parent, obj)) break;
7464 eina_list_free(children);
7465 eina_list_free(stack);
7469 static int _sort_by_repeat_events(const void *data1, const void *data2)
7471 Evas_Object *ao1, *ao2;
7472 Eina_Bool repeat1, repeat2;
7474 ao1 = elm_access_object_get(data1);
7475 ao2 = elm_access_object_get(data2);
7477 repeat1 = evas_object_repeat_events_get(data1);
7478 repeat2 = evas_object_repeat_events_get(data2);
7480 if (repeat1 != repeat2)
7482 if (repeat1 && !ao1) return 1;
7486 if (repeat1 && !ao1 && ao2) return 1;
7492 static Eo *_item_at_point_get(Evas_Object *obj, int x, int y)
7495 Eina_List *l, *children;
7497 eo_do(obj, children = elm_interface_atspi_accessible_children_get());
7499 EINA_LIST_FOREACH(children, l, child)
7501 if (_is_inside(child, x, y)) return child;
7504 ERR("No child at point (%d, %d) on object %p", x, y, obj);
7509 _elm_widget_elm_interface_atspi_component_accessible_at_point_get(Eo *obj, Elm_Widget_Smart_Data *_pd EINA_UNUSED, Eina_Bool screen_coords, int x, int y)
7512 Evas_Object *stack_item;
7514 if(strcmp("Elm_Win", eo_class_name_get(eo_class_get(obj))))
7515 return _accessible_at_point_top_down_get(obj, _pd, screen_coords, x, y);
7517 _coordinate_system_based_point_translate(obj, screen_coords, &x, &y);
7519 Eina_List *stack = evas_tree_objects_at_xy_get(evas_object_evas_get(obj), NULL, x, y);
7520 stack = eina_list_sort(stack, -1, _sort_by_repeat_events);
7522 EINA_LIST_FOREACH(stack, l, stack_item)
7524 Evas_Object *smart_parent = stack_item;
7525 while (smart_parent)
7527 Evas_Object *ao = elm_access_object_get(smart_parent);
7530 if (eo_isa(smart_parent, ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN))
7532 Eina_Bool acceptable = EINA_FALSE;
7534 Elm_Atspi_Role role;
7535 eo_do(smart_parent, role = elm_interface_atspi_accessible_role_get());
7538 case ELM_ATSPI_ROLE_FILLER: /* ex: View of colorselector item is layout */
7539 case ELM_ATSPI_ROLE_ICON:
7540 case ELM_ATSPI_ROLE_IMAGE:
7541 case ELM_ATSPI_ROLE_REDUNDANT_OBJECT:
7542 case ELM_ATSPI_ROLE_WINDOW:
7543 DBG("Go for parent: %s (%p)\n", evas_object_type_get(smart_parent), smart_parent);
7546 case ELM_ATSPI_ROLE_LIST:
7547 item_child = _item_at_point_get(smart_parent, x, y);
7548 if (TIZEN_PROFILE_WEARABLE)
7550 item_child = _child_object_at_point_get(item_child, x, y);
7557 acceptable = EINA_TRUE;
7561 if (acceptable) return smart_parent;
7564 smart_parent = _parent_get(smart_parent);
7567 return _accessible_at_point_top_down_get(obj, _pd, screen_coords, x, y);
7571 //TIZEN_ONLY(20150709) add relations atpi
7572 EOLIAN static Eina_Bool
7573 _elm_widget_elm_interface_atspi_accessible_relationship_append(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd, Elm_Atspi_Relation_Type type, const Eo *relation_obj)
7575 return elm_atspi_relation_set_relation_append(&sd->atspi_custom_relations, type, relation_obj);
7579 _elm_widget_elm_interface_atspi_accessible_relationship_remove(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd, Elm_Atspi_Relation_Type type, const Eo *relation_obj)
7581 elm_atspi_relation_set_relation_remove(&sd->atspi_custom_relations, type, relation_obj);
7584 EOLIAN static Eina_Bool
7585 _elm_widget_item_elm_interface_atspi_accessible_relationship_append(Eo *obj EINA_UNUSED, Elm_Widget_Item_Data *sd, Elm_Atspi_Relation_Type type, const Eo *relation_obj)
7587 return elm_atspi_relation_set_relation_append(&sd->atspi_custom_relations, type, relation_obj);
7591 _elm_widget_item_elm_interface_atspi_accessible_relationship_remove(Eo *obj EINA_UNUSED, Elm_Widget_Item_Data *sd, Elm_Atspi_Relation_Type type, const Eo *relation_obj)
7593 elm_atspi_relation_set_relation_remove(&sd->atspi_custom_relations, type, relation_obj);
7597 //TIZEN_ONLY(20150731) : add i18n support for name and description
7599 _elm_widget_elm_interface_atspi_accessible_translation_domain_set(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *_pd, const char *domain)
7601 eina_stringshare_replace(&_pd->atspi_translation_domain, domain);
7604 EOLIAN static const char*
7605 _elm_widget_elm_interface_atspi_accessible_translation_domain_get(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *_pd)
7607 return _pd->atspi_translation_domain;
7611 _elm_widget_item_elm_interface_atspi_accessible_translation_domain_set(Eo *obj EINA_UNUSED, Elm_Widget_Item_Data *_pd, const char *domain)
7613 eina_stringshare_replace(&_pd->atspi_translation_domain, domain);
7616 EOLIAN static const char*
7617 _elm_widget_item_elm_interface_atspi_accessible_translation_domain_get(Eo *obj EINA_UNUSED, Elm_Widget_Item_Data *_pd)
7619 return _pd->atspi_translation_domain;
7622 //TIZEN_ONLY(20160726): add API elm_atspi_accessible_can_highlight_set/get
7624 _children_highlight_check(Eo *obj)
7626 Eina_List *children, *l;
7629 if (_elm_object_accessibility_currently_highlighted_get() == (void *)obj)
7631 eo_do(obj, elm_interface_atspi_component_highlight_clear());
7635 eo_do(obj, children = elm_interface_atspi_accessible_children_get());
7636 EINA_LIST_FOREACH(children, l, child)
7638 if (_children_highlight_check(child)) return EINA_TRUE;
7645 _elm_widget_elm_interface_atspi_accessible_can_highlight_set(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *_pd, Eina_Bool can_highlight)
7647 if (!can_highlight) _children_highlight_check(obj);
7648 _pd->can_highlight = !!can_highlight;
7651 EOLIAN static Eina_Bool
7652 _elm_widget_elm_interface_atspi_accessible_can_highlight_get(Eo *obj, Elm_Widget_Smart_Data *_pd EINA_UNUSED)
7654 return _elm_widget_highlightable(obj);
7658 _elm_widget_item_elm_interface_atspi_accessible_can_highlight_set(Eo *obj EINA_UNUSED, Elm_Widget_Item_Data *_pd, Eina_Bool can_highlight)
7660 if (!can_highlight) _children_highlight_check(obj);
7661 _pd->can_highlight = !!can_highlight;
7664 EOLIAN static Eina_Bool
7665 _elm_widget_item_elm_interface_atspi_accessible_can_highlight_get(Eo *obj, Elm_Widget_Item_Data *_pd EINA_UNUSED)
7667 return _elm_widget_item_highlightable(obj);
7671 //TIZEN_ONLY(20160622): Override Paragraph Direction APIs
7673 _elm_widget_evas_object_paragraph_direction_set_internal(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd, Evas_BiDi_Direction dir)
7678 if (sd->on_destroy) return;
7680 EINA_LIST_FOREACH(sd->subobjs, l, child)
7682 if (_elm_widget_is(child))
7684 Elm_Widget_Smart_Data *sdc = eo_data_scope_get(child, MY_CLASS);
7686 if (sdc->inherit_paragraph_direction &&
7687 (sdc->paragraph_direction != dir))
7689 sdc->paragraph_direction = dir;
7690 _elm_widget_evas_object_paragraph_direction_set_internal(child, sdc, dir);
7691 eo_do_super(child, MY_CLASS, evas_obj_paragraph_direction_set(dir));
7695 /* FIXME: There is no way to handle non-widget child object.
7696 * If a non-widget child object has smart parent, it will get the direction
7697 * from the smart parent. */
7702 _elm_widget_evas_object_paragraph_direction_set(Eo *obj, Elm_Widget_Smart_Data *sd, Evas_BiDi_Direction dir)
7704 if ((!(sd->inherit_paragraph_direction) && (sd->paragraph_direction == dir)) ||
7705 (sd->inherit_paragraph_direction && (dir == EVAS_BIDI_DIRECTION_INHERIT)))
7708 if (dir == EVAS_BIDI_DIRECTION_INHERIT)
7710 sd->inherit_paragraph_direction = EINA_TRUE;
7711 Evas_BiDi_Direction parent_dir = EVAS_BIDI_DIRECTION_NEUTRAL;
7714 parent_dir = evas_object_paragraph_direction_get(sd->parent_obj);
7716 if (parent_dir != sd->paragraph_direction)
7718 sd->paragraph_direction = parent_dir;
7719 _elm_widget_evas_object_paragraph_direction_set_internal(obj, sd, parent_dir);
7724 sd->inherit_paragraph_direction = EINA_FALSE;
7725 sd->paragraph_direction = dir;
7726 _elm_widget_evas_object_paragraph_direction_set_internal(obj, sd, dir);
7729 eo_do_super(obj, MY_CLASS, evas_obj_paragraph_direction_set(dir));
7734 //TIZEN_ONLY(20161013): clean up elm color class feature
7736 _edje_color_class_free(void *data)
7738 Edje_Color_Class *cc = data;
7740 if (cc->name) eina_stringshare_del(cc->name);
7745 _elm_widget_edje_class_get(const Eo_Class *klass, const char *style, const char *part)
7748 Eina_Stringshare *str;
7750 buf = eina_strbuf_new();
7752 eina_strbuf_append(buf, strchr(eo_class_name_get(klass), '_') + 1);
7753 eina_strbuf_tolower(buf);
7757 eina_strbuf_append_printf(buf, "/%s/%s", style, part);
7761 eina_strbuf_append_printf(buf, "/%s", part);
7764 str = eina_stringshare_add(eina_strbuf_string_get(buf));
7766 eina_strbuf_free(buf);
7770 /* TIZEN_ONLY(20161025): Apply color_class parent-child relationship */
7772 _elm_widget_color_class_set_internal(Evas_Object *obj, Evas_Object *edje, const char *color_class,
7773 int r, int g, int b, int a,
7774 int r2, int g2, int b2, int a2,
7775 int r3, int g3, int b3, int a3)
7777 Eina_Bool int_ret = EINA_TRUE;
7778 Eina_Stringshare *buf;
7779 int temp_color[3][4] = { { r, g, b, a },
7781 { r3, g3, b3, a3 } };
7783 if (!color_class) return EINA_FALSE;
7785 buf = _elm_widget_edje_class_get(eo_class_get(obj), NULL, color_class);
7787 #define TEMP_COLOR(x, y) \
7788 ((temp_color[x][y] == -1) ? &temp_color[x][y] : NULL)
7790 edje_object_color_class_get(edje, buf,
7791 TEMP_COLOR(0, 0), TEMP_COLOR(0, 1), TEMP_COLOR(0, 2), TEMP_COLOR(0, 3),
7792 TEMP_COLOR(1, 0), TEMP_COLOR(1, 1), TEMP_COLOR(1, 2), TEMP_COLOR(1, 3),
7793 TEMP_COLOR(2, 0), TEMP_COLOR(2, 1), TEMP_COLOR(2, 2), TEMP_COLOR(2, 3));
7797 #define TEMP_COLOR(x, y) \
7798 ((temp_color[x][y] == -1) ? 0 : temp_color[x][y])
7800 int_ret &= edje_object_color_class_set(edje, buf,
7801 TEMP_COLOR(0, 0), TEMP_COLOR(0, 1), TEMP_COLOR(0, 2), TEMP_COLOR(0, 3),
7802 TEMP_COLOR(1, 0), TEMP_COLOR(1, 1), TEMP_COLOR(1, 2), TEMP_COLOR(1, 3),
7803 TEMP_COLOR(2, 0), TEMP_COLOR(2, 1), TEMP_COLOR(2, 2), TEMP_COLOR(2, 3));
7807 eina_stringshare_del(buf);
7813 _elm_widget_color_class_get_internal(Evas_Object *obj, Evas_Object *edje, const char *color_class,
7814 int *r, int *g, int *b, int *a,
7815 int *r2, int *g2, int *b2, int *a2,
7816 int *r3, int *g3, int *b3, int *a3)
7818 Eina_Bool int_ret = EINA_TRUE;
7819 Eina_Stringshare *buf;
7821 if (!color_class) return EINA_FALSE;
7823 buf = _elm_widget_edje_class_get(eo_class_get(obj), elm_widget_style_get(obj), color_class);
7825 int_ret &= edje_object_color_class_get(edje, buf,
7830 eina_stringshare_del(buf);
7837 _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)
7840 Eina_Bool int_ret = EINA_TRUE;
7842 if (!eo_isa(obj, ELM_LAYOUT_CLASS)) return EINA_FALSE;
7844 edje = elm_layout_edje_get(obj);
7845 int_ret &= _elm_widget_color_class_set_internal(obj, edje, color_class,
7854 _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)
7857 Eina_Bool int_ret = EINA_TRUE;
7859 if (!eo_isa(obj, ELM_LAYOUT_CLASS)) return EINA_FALSE;
7861 edje = elm_layout_edje_get(obj);
7862 int_ret &= _elm_widget_color_class_get_internal(obj, edje, color_class,
7864 NULL, NULL, NULL, NULL,
7865 NULL, NULL, NULL, NULL);
7871 _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)
7874 Eina_Bool int_ret = EINA_TRUE;
7876 if (!eo_isa(obj, ELM_LAYOUT_CLASS)) return EINA_FALSE;
7878 edje = elm_layout_edje_get(obj);
7879 int_ret &= _elm_widget_color_class_set_internal(obj, edje, color_class,
7888 _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)
7891 Eina_Bool int_ret = EINA_TRUE;
7893 if (!eo_isa(obj, ELM_LAYOUT_CLASS)) return EINA_FALSE;
7895 edje = elm_layout_edje_get(obj);
7896 int_ret &= _elm_widget_color_class_get_internal(obj, edje, color_class,
7897 NULL, NULL, NULL, NULL,
7899 NULL, NULL, NULL, NULL);
7905 _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)
7908 Eina_Bool int_ret = EINA_TRUE;
7910 if (!eo_isa(obj, ELM_LAYOUT_CLASS)) return EINA_FALSE;
7912 edje = elm_layout_edje_get(obj);
7913 int_ret &= _elm_widget_color_class_set_internal(obj, edje, color_class,
7922 _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)
7925 Eina_Bool int_ret = EINA_TRUE;
7927 if (!eo_isa(obj, ELM_LAYOUT_CLASS)) return EINA_FALSE;
7929 edje = elm_layout_edje_get(obj);
7930 int_ret &= _elm_widget_color_class_get_internal(obj, edje, color_class,
7931 NULL, NULL, NULL, NULL,
7932 NULL, NULL, NULL, NULL,
7939 _elm_widget_class_color_del(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd, const char *color_class)
7941 Eina_Stringshare *buf;
7943 if (!eo_isa(obj, ELM_LAYOUT_CLASS)) return;
7945 buf = _elm_widget_edje_class_get(eo_class_get(obj), NULL, color_class);
7946 edje_object_color_class_del(sd->resize_obj, buf);
7947 eina_stringshare_del(buf);
7951 _elm_widget_class_color_clear(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd)
7953 if (!eo_isa(obj, ELM_LAYOUT_CLASS)) return;
7954 edje_object_color_class_clear(sd->resize_obj);
7957 #define ELM_COLOR_CLASS_UPDATE(obj, hash, cond) \
7958 Evas_Object *edje = NULL; \
7959 Eina_Iterator *itr; \
7960 Edje_Color_Class *cc; \
7961 Eina_Bool int_ret = EINA_TRUE; \
7962 if (cond) return EINA_FALSE; \
7963 if (eo_isa(obj, ELM_LAYOUT_CLASS)) \
7964 edje = elm_layout_edje_get(obj); \
7965 else if (eo_isa(obj, EDJE_OBJECT_CLASS)) \
7967 if (!edje) return EINA_FALSE; \
7968 itr = eina_hash_iterator_data_new(hash); \
7969 EINA_ITERATOR_FOREACH(itr, cc) \
7971 int_ret &= edje_object_color_class_set(edje, cc->name, \
7972 cc->r, cc->g, cc->b, cc->a, \
7973 cc->r2, cc->g2, cc->b2, cc->a2, \
7974 cc->r3, cc->g3, cc->b3, cc->a3); \
7976 eina_iterator_free(itr); \
7980 #define CHECK_BOUND(x) \
7981 if (x > 0xff) x = 0xff; \
7982 else if (x < 0) x = 0
7984 #define ELM_COLOR_CLASS_SET_START(obj, cr, cg, cb, ca) \
7985 Eina_Bool int_ret = EINA_FALSE; \
7986 Edje_Color_Class *cc = NULL; \
7987 Eina_Stringshare *buf; \
7988 buf = _elm_widget_edje_class_get(eo_class_get(obj), NULL, color_class); \
7993 _elm_color_unpremul(a, &r, &g, &b); \
7994 if (!sd->color_classes) \
7995 sd->color_classes = eina_hash_string_small_new(_edje_color_class_free); \
7997 cc = eina_hash_find(sd->color_classes, buf); \
8000 cc = calloc(1, sizeof(Edje_Color_Class)); \
8001 cc->name = eina_stringshare_add(buf); \
8005 eina_stringshare_del(buf); \
8006 return EINA_FALSE; \
8008 eina_hash_direct_add(sd->color_classes, cc->name, cc); \
8010 else if ((cc->cr == r) && (cc->cg == g) && \
8011 (cc->cb == b) && (cc->ca == a)) \
8013 eina_stringshare_del(buf); \
8022 #define ELM_COLOR_CLASS_SET_END() \
8023 eina_stringshare_del(buf); \
8026 #define ELM_COLOR_CLASS_GET(obj, cr, cg, cb, ca) \
8027 Eina_Bool int_ret = EINA_FALSE; \
8028 Edje_Color_Class *cc; \
8029 Eina_Stringshare *buf; \
8031 buf = _elm_widget_edje_class_get(eo_class_get(obj), NULL, color_class); \
8032 if ((!sd->color_classes) || !(cc = eina_hash_find(sd->color_classes, buf))) \
8038 int_ret = EINA_FALSE; \
8042 if (r) *r = cc->cr; \
8043 if (g) *g = cc->cg; \
8044 if (b) *b = cc->cb; \
8045 if (a) *a = cc->ca; \
8047 int_ret = EINA_TRUE; \
8049 _elm_color_premul(alpha, r, g, b); \
8050 eina_stringshare_del(buf); \
8054 _elm_widget_item_color_class_update(Elm_Widget_Item_Data *sd)
8056 ELM_COLOR_CLASS_UPDATE(sd->view, sd->color_classes, (!sd) || (!sd->color_classes) || (!sd->view));
8060 _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)
8062 ELM_COLOR_CLASS_SET_START(obj, r, g, b, a);
8064 int_ret &= _elm_widget_item_color_class_update(sd);
8066 ELM_COLOR_CLASS_SET_END();
8070 _elm_widget_item_class_color_get(Eo *obj, Elm_Widget_Item_Data *sd, const char *color_class, int *r, int *g, int *b, int *a)
8072 ELM_COLOR_CLASS_GET(obj, r, g, b, a);
8076 _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)
8078 ELM_COLOR_CLASS_SET_START(obj, r2, g2, b2, a2);
8080 int_ret &= _elm_widget_item_color_class_update(sd);
8082 ELM_COLOR_CLASS_SET_END();
8086 _elm_widget_item_class_color2_get(Eo *obj, Elm_Widget_Item_Data *sd, const char *color_class, int *r, int *g, int *b, int *a)
8088 ELM_COLOR_CLASS_GET(obj, r2, g2, b2, a2);
8092 _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)
8094 ELM_COLOR_CLASS_SET_START(obj, r3, g3, b3, a3);
8096 int_ret &= _elm_widget_item_color_class_update(sd);
8098 ELM_COLOR_CLASS_SET_END();
8102 _elm_widget_item_class_color3_get(Eo *obj, Elm_Widget_Item_Data *sd, const char *color_class, int *r, int *g, int *b, int *a)
8104 ELM_COLOR_CLASS_GET(obj, r3, g3, b3, a3);
8107 static Evas_Object *
8108 _elm_widget_item_edje_get(Eo *obj, Elm_Widget_Item_Data *sd)
8111 sd = eo_data_scope_get(obj, ELM_WIDGET_ITEM_CLASS);
8113 if (eo_isa(sd->view, ELM_LAYOUT_CLASS))
8114 return elm_layout_edje_get(sd->view);
8115 else if (eo_isa(sd->view, EDJE_OBJECT_CLASS))
8122 _elm_widget_item_class_color_del(Eo *obj EINA_UNUSED, Elm_Widget_Item_Data *sd, const char *color_class)
8124 Eina_Stringshare *buf;
8126 Edje_Color_Class *cc = NULL;
8128 if (!color_class) return;
8130 buf = _elm_widget_edje_class_get(eo_class_get(obj), NULL, color_class);
8131 eina_hash_del(sd->color_classes, buf, cc);
8133 edje = _elm_widget_item_edje_get(obj, sd);
8135 edje_object_color_class_del(edje, buf);
8137 eina_stringshare_del(buf);
8141 _elm_widget_item_class_color_clear(Eo *obj EINA_UNUSED, Elm_Widget_Item_Data *sd)
8144 ELM_SAFE_FREE(sd->color_classes, eina_hash_free);
8146 edje = _elm_widget_item_edje_get(obj, sd);
8149 edje_object_color_class_clear(edje);
8153 /* TIZEN_ONLY(20161025): Apply color_class parent-child relationship */
8155 _elm_widget_color_class_parent_set(Evas_Object *obj, Evas_Object *parent)
8157 Evas_Object *edje = NULL, *parent_edje = NULL;
8159 if (!obj || !parent) return;
8161 if (eo_isa(obj, ELM_LAYOUT_CLASS))
8162 edje = elm_layout_edje_get(obj);
8163 else if (eo_isa(obj, EDJE_OBJECT_CLASS))
8166 if (eo_isa(parent, ELM_LAYOUT_CLASS))
8167 parent_edje = elm_layout_edje_get(parent);
8168 else if (eo_isa(parent, EDJE_OBJECT_CLASS))
8169 parent_edje = parent;
8171 if (!edje || !parent_edje) return;
8173 edje_object_color_class_parent_set(edje, parent_edje);
8177 _elm_widget_color_class_parent_unset(Evas_Object *obj)
8179 Evas_Object *edje = NULL;
8183 if (eo_isa(obj, ELM_LAYOUT_CLASS))
8184 edje = elm_layout_edje_get(obj);
8185 else if (eo_isa(obj, EDJE_OBJECT_CLASS))
8190 edje_object_color_class_parent_unset(edje);
8194 //TIZEN_ONLY(20160527): widget: add AtspiAction interface to all widgets and widget_items, add handlers for reading stopped/cancelled
8195 EOLIAN const Elm_Atspi_Action *
8196 _elm_widget_elm_interface_atspi_widget_action_elm_actions_get(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *pd EINA_UNUSED)
8201 EOLIAN const Elm_Atspi_Action *
8202 _elm_widget_item_elm_interface_atspi_widget_action_elm_actions_get(Eo *obj EINA_UNUSED, Elm_Widget_Item_Data *pd EINA_UNUSED)
8208 #include "elm_widget_item.eo.c"
8209 #include "elm_widget.eo.c"