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(20160929) : atspi: Improves how to find the can_highlight of the widget
5057 _elm_widget_can_highlight_get_by_class(Eo *obj)
5059 if (eo_isa(obj, ELM_WIDGET_ITEM_CLASS))
5061 Elm_Widget_Item_Data *id = eo_data_scope_get(obj, ELM_WIDGET_ITEM_CLASS);
5062 if (!id) return EINA_FALSE;
5063 if (!id->can_highlight) return EINA_FALSE;
5067 Elm_Widget_Smart_Data *wd = eo_data_scope_get(obj, ELM_WIDGET_CLASS);
5068 if (!wd) return EINA_FALSE;
5069 if (!wd->can_highlight) return EINA_FALSE;
5075 //TIZEN_ONLY(20161107): enhance elm_atspi_accessible_can_highlight_set to set can_hihglight property to its children
5077 _elm_widget_item_highlightable(Elm_Object_Item *item)
5080 Eina_Bool can_highlight;
5082 Elm_Widget_Item_Data *id = eo_data_scope_get(item, ELM_WIDGET_ITEM_CLASS);
5083 if (!id) return EINA_FALSE;
5084 if (!id->can_highlight) return EINA_FALSE;
5086 eo_do(item, parent = elm_interface_atspi_accessible_parent_get());
5087 while (parent && !eo_isa(parent, ELM_ATSPI_APP_OBJECT_CLASS))
5089 //TIZEN_ONLY(20160929) : atspi: Improves how to find the can_highlight of the widget
5090 if (!_elm_widget_can_highlight_get_by_class(parent)) return EINA_FALSE;
5092 eo_do(parent, parent = elm_interface_atspi_accessible_parent_get());
5098 //TIZEN_ONLY(20170206): Add check the object is in the scroller content size
5100 _accessible_object_on_scroll_is(Eo* obj)
5102 /* in case of genlist item, the item->view is NULL if item is unrealized.
5103 this function is used to check if obj could have HIGHLIGHTABLE or not.
5104 the unrealized genlist item should have HIGHLIGHTABLE state.
5105 so if obj is NULL return EINA_TRUE */
5106 if(!obj) return EINA_TRUE;
5108 Evas_Object *target = obj;
5109 Evas_Object *parent = NULL;
5110 Evas_Coord x, y, w, h, wx, wy, ww = 0, wh = 0, nx = 0, ny = 0;
5112 evas_object_geometry_get(target, &x, &y ,&w, &h);
5114 if (elm_widget_is(target))
5115 parent = elm_widget_parent_get(target);
5117 parent = elm_widget_parent_widget_get(target);
5121 if (eo_isa(parent, ELM_INTERFACE_SCROLLABLE_MIXIN))
5123 evas_object_geometry_get(parent, &wx, &wy, NULL, NULL);
5124 eo_do(parent, elm_interface_scrollable_content_size_get(&ww, &wh));
5125 eo_do(parent, elm_interface_scrollable_content_pos_get(&nx, &ny));
5127 /* widget implements scrollable interface but does not use scoller
5128 in this case, use widget geometry */
5129 if (ww == 0 || wh == 0)
5131 INF("%s is zero sized scrollable content", eo_class_name_get(eo_class_get(parent)));
5132 evas_object_geometry_get(parent, NULL, NULL, &ww, &wh);
5138 if (((wx < x) && (wx + ww < x)) || ((wx > x + w) && (wx + ww > x + w)) ||
5139 ((wy < y) && (wy + wh < y)) || ((wy > y + h) && (wy + wh > y + h)))
5144 parent = elm_widget_parent_get(parent);
5151 EOLIAN static Elm_Atspi_State_Set
5152 _elm_widget_item_elm_interface_atspi_accessible_state_set_get(Eo *eo_item,
5153 Elm_Widget_Item_Data *item)
5155 Elm_Atspi_State_Set states = 0;
5157 STATE_TYPE_SET(states, ELM_ATSPI_STATE_FOCUSABLE);
5159 if (elm_object_item_focus_get(eo_item))
5160 STATE_TYPE_SET(states, ELM_ATSPI_STATE_FOCUSED);
5161 if (!elm_object_item_disabled_get(eo_item))
5163 STATE_TYPE_SET(states, ELM_ATSPI_STATE_ENABLED);
5164 STATE_TYPE_SET(states, ELM_ATSPI_STATE_SENSITIVE);
5166 if (_elm_widget_item_onscreen_is(eo_item))
5167 STATE_TYPE_SET(states, ELM_ATSPI_STATE_SHOWING);
5169 //TIZEN_ONLY(20170207) : [ATSPI] enhance expose highlight information on atspi
5170 /* unrealized genlist item does not have item->view,
5171 and item cannot change its visibility, only widget can change the visibility */
5172 if (evas_object_visible_get(item->widget))
5173 STATE_TYPE_SET(states, ELM_ATSPI_STATE_VISIBLE);
5176 //TIZEN_ONLY(20170717) : expose highlight information on atspi
5177 if (_elm_widget_item_highlightable(eo_item) && _accessible_object_on_scroll_is(item->view))
5178 STATE_TYPE_SET(states, ELM_ATSPI_STATE_HIGHLIGHTABLE);
5180 STATE_TYPE_UNSET(states, ELM_ATSPI_STATE_HIGHLIGHTABLE);
5182 if (_elm_object_accessibility_currently_highlighted_get() == (void*)item->eo_obj)
5183 STATE_TYPE_SET(states, ELM_ATSPI_STATE_HIGHLIGHTED);
5189 _elm_widget_item_elm_interface_atspi_accessible_parent_get(Eo *eo_item, Elm_Widget_Item_Data *item EINA_UNUSED)
5192 eo_do(eo_item, parent = eo_parent_get());
5197 elm_object_item_data_set(Elm_Object_Item *it, void *data)
5199 WIDGET_ITEM_DATA_SET(it, data);
5203 elm_object_item_data_get(const Elm_Object_Item *it)
5205 return (void *) WIDGET_ITEM_DATA_GET(it);
5209 _elm_widget_item_disabled_set(Eo *eo_item EINA_UNUSED,
5210 Elm_Widget_Item_Data *item,
5213 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
5214 ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
5216 if (item->disabled == disabled) return;
5217 item->disabled = !!disabled;
5218 eo_do(item->eo_obj, elm_wdg_item_disable());
5221 EOLIAN static Eina_Bool
5222 _elm_widget_item_disabled_get(Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item)
5224 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item, EINA_FALSE);
5225 return item->disabled;
5229 _elm_widget_item_style_set(Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item, const char *style EINA_UNUSED)
5231 ERR_NOT_SUPPORTED(item, "elm_object_style_set()");
5234 EOLIAN static const char *
5235 _elm_widget_item_style_get(Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item)
5237 ERR_NOT_SUPPORTED(item, "elm_object_style_get()");
5242 _elm_widget_item_disable(Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item EINA_UNUSED)
5247 _elm_widget_item_focus_set(Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item, Eina_Bool focused EINA_UNUSED)
5249 ERR_NOT_SUPPORTED(item, "elm_object_item_focus_set");
5252 EOLIAN static Eina_Bool
5253 _elm_widget_item_focus_get(Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item)
5255 ERR_NOT_SUPPORTED(item, "elm_object_item_focus_get");
5260 _elm_widget_item_domain_translatable_part_text_set(Eo *eo_item EINA_UNUSED,
5261 Elm_Widget_Item_Data *item,
5266 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
5267 ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
5268 Elm_Translate_String_Data *ts;
5272 _part_text_translatable_set(&item->translate_strings, part, EINA_FALSE,
5277 ts = _part_text_translatable_set(&item->translate_strings, part,
5278 EINA_TRUE, EINA_FALSE);
5280 if (!ts->string) ts->string = eina_stringshare_add(label);
5281 else eina_stringshare_replace(&ts->string, label);
5282 if (!ts->domain) ts->domain = eina_stringshare_add(domain);
5283 else eina_stringshare_replace(&ts->domain, domain);
5285 if (label[0]) label = dgettext(domain, label);
5288 item->on_translate = EINA_TRUE;
5289 eo_do(item->eo_obj, elm_wdg_item_part_text_set(part, label));
5290 item->on_translate = EINA_FALSE;
5293 EOLIAN static const char *
5294 _elm_widget_item_translatable_part_text_get(const Eo *eo_item EINA_UNUSED,
5295 Elm_Widget_Item_Data *item,
5298 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item, NULL);
5299 ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item, NULL);
5301 Elm_Translate_String_Data *ts;
5302 ts = _translate_string_data_get(item->translate_strings, part);
5303 if (ts) return ts->string;
5308 _elm_widget_item_domain_part_text_translatable_set(Eo *eo_item EINA_UNUSED,
5309 Elm_Widget_Item_Data *item,
5312 Eina_Bool translatable)
5314 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
5315 ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
5316 Elm_Translate_String_Data *ts;
5319 ts = _part_text_translatable_set(&item->translate_strings, part,
5320 translatable, EINA_TRUE);
5322 if (!ts->domain) ts->domain = eina_stringshare_add(domain);
5323 else eina_stringshare_replace(&ts->domain, domain);
5325 eo_do(item->eo_obj, text = elm_wdg_item_part_text_get(part));
5327 if (!text || !text[0]) return;
5329 if (!ts->string) ts->string = eina_stringshare_add(text);
5331 //Try to translate text since we don't know the text is already translated.
5333 text = dgettext(domain, text);
5335 item->on_translate = EINA_TRUE;
5336 eo_do (item->eo_obj, elm_wdg_item_part_text_set(part, text));
5337 item->on_translate = EINA_FALSE;
5341 _elm_widget_item_track_cancel(Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item)
5343 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
5344 ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
5346 if (!item->track_obj) return;
5348 while (evas_object_ref_get(item->track_obj) > 0)
5349 evas_object_unref(item->track_obj);
5351 evas_object_del(item->track_obj);
5354 EOLIAN static Evas_Object *
5355 _elm_widget_item_track(Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item)
5357 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item, NULL);
5358 ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item, NULL);
5360 if (item->track_obj)
5362 evas_object_ref(item->track_obj);
5363 return item->track_obj;
5368 WRN("view obj of the item(%p) is invalid. Please make sure the view obj is created!", item);
5372 Evas_Object *track =
5373 evas_object_rectangle_add(evas_object_evas_get(item->widget));
5374 evas_object_color_set(track, 0, 0, 0, 0);
5375 evas_object_pass_events_set(track, EINA_TRUE);
5376 _track_obj_update(track, item->view);
5377 evas_object_event_callback_add(track, EVAS_CALLBACK_DEL, _track_obj_del,
5381 eo_event_callback_array_add(tracker_callbacks(), item));
5383 evas_object_ref(track);
5385 item->track_obj = track;
5391 _elm_widget_item_untrack(Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item)
5393 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
5394 ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
5396 if (!item->track_obj) return;
5397 evas_object_unref(item->track_obj);
5399 if (evas_object_ref_get(item->track_obj) == 0)
5400 evas_object_del(item->track_obj);
5404 _elm_widget_item_track_get(const Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item)
5406 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item, 0);
5407 ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item, 0);
5409 if (!item->track_obj) return 0;
5410 return evas_object_ref_get(item->track_obj);
5413 typedef struct _Elm_Widget_Item_Tooltip Elm_Widget_Item_Tooltip;
5415 struct _Elm_Widget_Item_Tooltip
5417 Elm_Widget_Item_Data *item;
5418 Elm_Tooltip_Item_Content_Cb func;
5419 Evas_Smart_Cb del_cb;
5423 static Evas_Object *
5424 _elm_widget_item_tooltip_label_create(void *data,
5425 Evas_Object *obj EINA_UNUSED,
5426 Evas_Object *tooltip,
5427 void *item EINA_UNUSED)
5429 Evas_Object *label = elm_label_add(tooltip);
5432 elm_object_style_set(label, "tooltip");
5433 elm_object_text_set(label, data);
5437 static Evas_Object *
5438 _elm_widget_item_tooltip_trans_label_create(void *data,
5439 Evas_Object *obj EINA_UNUSED,
5440 Evas_Object *tooltip,
5441 void *item EINA_UNUSED)
5443 Evas_Object *label = elm_label_add(tooltip);
5446 elm_object_style_set(label, "tooltip");
5447 elm_object_translatable_text_set(label, data);
5452 _elm_widget_item_tooltip_label_del_cb(void *data,
5453 Evas_Object *obj EINA_UNUSED,
5454 void *event_info EINA_UNUSED)
5456 eina_stringshare_del(data);
5462 * Set the text to be shown in the widget item.
5464 * @param item Target item
5465 * @param text The text to set in the content
5467 * Setup the text as tooltip to object. The item can have only one tooltip,
5468 * so any previous tooltip data is removed.
5473 _elm_widget_item_tooltip_text_set(Eo *eo_item EINA_UNUSED,
5474 Elm_Widget_Item_Data *item EINA_UNUSED,
5477 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
5478 ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
5479 EINA_SAFETY_ON_NULL_RETURN(text);
5481 text = eina_stringshare_add(text);
5482 eo_do(item->eo_obj, elm_wdg_item_tooltip_content_cb_set(
5483 _elm_widget_item_tooltip_label_create,
5485 _elm_widget_item_tooltip_label_del_cb));
5489 _elm_widget_item_tooltip_translatable_text_set(Eo *eo_item EINA_UNUSED,
5490 Elm_Widget_Item_Data *item EINA_UNUSED,
5493 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
5494 ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
5495 EINA_SAFETY_ON_NULL_RETURN(text);
5497 text = eina_stringshare_add(text);
5498 eo_do(item->eo_obj, elm_wdg_item_tooltip_content_cb_set(
5499 _elm_widget_item_tooltip_trans_label_create,
5501 _elm_widget_item_tooltip_label_del_cb));
5504 static Evas_Object *
5505 _elm_widget_item_tooltip_create(void *data,
5507 Evas_Object *tooltip)
5509 Elm_Widget_Item_Tooltip *wit = data;
5510 return wit->func((void *)wit->data, obj, tooltip, wit->item->eo_obj);
5514 _elm_widget_item_tooltip_del_cb(void *data,
5516 void *event_info EINA_UNUSED)
5518 Elm_Widget_Item_Tooltip *wit = data;
5519 if (wit->del_cb) wit->del_cb((void *)wit->data, obj, wit->item->eo_obj);
5526 * Set the content to be shown in the tooltip item
5528 * Setup the tooltip to item. The item can have only one tooltip,
5529 * so any previous tooltip data is removed. @p func(with @p data) will
5530 * be called every time that need show the tooltip and it should
5531 * return a valid Evas_Object. This object is then managed fully by
5532 * tooltip system and is deleted when the tooltip is gone.
5534 * @param item the widget item being attached a tooltip.
5535 * @param func the function used to create the tooltip contents.
5536 * @param data what to provide to @a func as callback data/context.
5537 * @param del_cb called when data is not needed anymore, either when
5538 * another callback replaces @func, the tooltip is unset with
5539 * elm_widget_item_tooltip_unset() or the owner @a item
5540 * dies. This callback receives as the first parameter the
5541 * given @a data, and @c event_info is the item.
5546 _elm_widget_item_tooltip_content_cb_set(Eo *eo_item EINA_UNUSED,
5547 Elm_Widget_Item_Data *item,
5548 Elm_Tooltip_Item_Content_Cb func,
5550 Evas_Smart_Cb del_cb)
5552 Elm_Widget_Item_Tooltip *wit;
5554 ELM_WIDGET_ITEM_CHECK_OR_GOTO(item, error_noitem);
5555 //ELM_WIDGET_ITEM_RETURN_IF_GOTO(item, error_noitem);
5559 eo_do(item->eo_obj, elm_wdg_item_tooltip_unset());
5563 wit = ELM_NEW(Elm_Widget_Item_Tooltip);
5564 if (!wit) goto error;
5568 wit->del_cb = del_cb;
5570 elm_object_sub_tooltip_content_cb_set
5571 (item->view, item->widget, _elm_widget_item_tooltip_create, wit,
5572 _elm_widget_item_tooltip_del_cb);
5577 if (del_cb) del_cb((void *)data, NULL, item);
5580 if (del_cb) del_cb((void *)data, item->widget, item);
5586 * Unset tooltip from item
5588 * @param item widget item to remove previously set tooltip.
5590 * Remove tooltip from item. The callback provided as del_cb to
5591 * elm_widget_item_tooltip_content_cb_set() will be called to notify
5592 * it is not used anymore.
5594 * @see elm_widget_item_tooltip_content_cb_set()
5599 _elm_widget_item_tooltip_unset(Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item)
5601 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
5602 ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
5604 elm_object_tooltip_unset(item->view);
5610 * Sets a different style for this item tooltip.
5612 * @note before you set a style you should define a tooltip with
5613 * elm_widget_item_tooltip_content_cb_set() or
5614 * elm_widget_item_tooltip_text_set()
5616 * @param item widget item with tooltip already set.
5617 * @param style the theme style to use (default, transparent, ...)
5622 _elm_widget_item_tooltip_style_set(Eo *eo_item EINA_UNUSED,
5623 Elm_Widget_Item_Data *item,
5626 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
5627 ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
5629 elm_object_tooltip_style_set(item->view, style);
5632 EOLIAN static Eina_Bool
5633 _elm_widget_item_tooltip_window_mode_set(Eo *eo_item EINA_UNUSED,
5634 Elm_Widget_Item_Data *item,
5637 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item, EINA_FALSE);
5638 ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item, EINA_FALSE);
5640 return elm_object_tooltip_window_mode_set(item->view, disable);
5643 EOLIAN static Eina_Bool
5644 _elm_widget_item_tooltip_window_mode_get(Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item)
5646 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item, EINA_FALSE);
5647 ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item, EINA_FALSE);
5649 return elm_object_tooltip_window_mode_get(item->view);
5655 * Get the style for this item tooltip.
5657 * @param item widget item with tooltip already set.
5658 * @return style the theme style in use, defaults to "default". If the
5659 * object does not have a tooltip set, then NULL is returned.
5663 EOLIAN static const char *
5664 _elm_widget_item_tooltip_style_get(Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item)
5666 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item, NULL);
5668 return elm_object_tooltip_style_get(item->view);
5672 _elm_widget_item_cursor_set(Eo *eo_item EINA_UNUSED,
5673 Elm_Widget_Item_Data *item,
5676 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
5677 ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
5679 elm_object_sub_cursor_set(item->view, item->widget, cursor);
5682 EOLIAN static const char *
5683 _elm_widget_item_cursor_get(Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item)
5685 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item, NULL);
5686 return elm_object_cursor_get(item->view);
5690 _elm_widget_item_cursor_unset(Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item)
5692 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
5693 ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
5695 elm_object_cursor_unset(item->view);
5701 * Sets a different style for this item cursor.
5703 * @note before you set a style you should define a cursor with
5704 * elm_widget_item_cursor_set()
5706 * @param item widget item with cursor already set.
5707 * @param style the theme style to use (default, transparent, ...)
5712 _elm_widget_item_cursor_style_set(Eo *eo_item EINA_UNUSED,
5713 Elm_Widget_Item_Data *item,
5716 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
5717 ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
5719 elm_object_cursor_style_set(item->view, style);
5725 * Get the style for this item cursor.
5727 * @param item widget item with cursor already set.
5728 * @return style the theme style in use, defaults to "default". If the
5729 * object does not have a cursor set, then NULL is returned.
5733 EOLIAN static const char *
5734 _elm_widget_item_cursor_style_get(Eo *eo_item EINA_UNUSED,
5735 Elm_Widget_Item_Data *item)
5737 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item, NULL);
5738 return elm_object_cursor_style_get(item->view);
5744 * Set if the cursor set should be searched on the theme or should use
5745 * the provided by the engine, only.
5747 * @note before you set if should look on theme you should define a cursor
5748 * with elm_object_cursor_set(). By default it will only look for cursors
5749 * provided by the engine.
5751 * @param item widget item with cursor already set.
5752 * @param engine_only boolean to define it cursors should be looked only
5753 * between the provided by the engine or searched on widget's theme as well.
5758 _elm_widget_item_cursor_engine_only_set(Eo *eo_item EINA_UNUSED,
5759 Elm_Widget_Item_Data *item,
5760 Eina_Bool engine_only)
5762 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
5763 ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
5765 elm_object_cursor_theme_search_enabled_set(item->view, !engine_only);
5771 * Get the cursor engine only usage for this item cursor.
5773 * @param item widget item with cursor already set.
5774 * @return engine_only boolean to define it cursors should be looked only
5775 * between the provided by the engine or searched on widget's theme as well. If
5776 * the object does not have a cursor set, then EINA_FALSE is returned.
5780 EOLIAN static Eina_Bool
5781 _elm_widget_item_cursor_engine_only_get(Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item)
5783 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item, EINA_FALSE);
5784 return !elm_object_cursor_theme_search_enabled_get(item->view);
5788 _elm_widget_item_part_content_set(Eo *eo_item EINA_UNUSED,
5789 Elm_Widget_Item_Data *item,
5790 const char *part EINA_UNUSED,
5791 Evas_Object *content EINA_UNUSED)
5793 ERR_NOT_SUPPORTED(item, "elm_object_part_content_set()");
5796 EOLIAN static Evas_Object *
5797 _elm_widget_item_part_content_get(Eo *eo_item EINA_UNUSED,
5798 Elm_Widget_Item_Data *item,
5799 const char *part EINA_UNUSED)
5801 ERR_NOT_SUPPORTED(item, "elm_object_part_content_get()");
5805 EOLIAN static Evas_Object *
5806 _elm_widget_item_part_content_unset(Eo *eo_item EINA_UNUSED,
5807 Elm_Widget_Item_Data *item,
5808 const char *part EINA_UNUSED)
5810 ERR_NOT_SUPPORTED(item, "elm_object_part_content_unset()");
5815 _elm_widget_item_part_text_set(Eo *eo_item EINA_UNUSED,
5816 Elm_Widget_Item_Data *item,
5817 const char *part EINA_UNUSED,
5818 const char *label EINA_UNUSED)
5820 ERR_NOT_SUPPORTED(item, "elm_object_part_text_set()");
5823 EOLIAN static const char *
5824 _elm_widget_item_part_text_get(Eo *eo_item EINA_UNUSED,
5825 Elm_Widget_Item_Data *item,
5826 const char *part EINA_UNUSED)
5828 ERR_NOT_SUPPORTED(item, "elm_object_part_text_get()");
5833 _elm_widget_item_part_text_custom_free(void *data)
5835 Elm_Label_Data *label;
5837 eina_stringshare_del(label->part);
5838 eina_stringshare_del(label->text);
5843 _elm_widget_item_part_text_custom_set(Eo *eo_item EINA_UNUSED,
5844 Elm_Widget_Item_Data *item,
5848 Elm_Label_Data *label;
5849 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
5850 ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
5854 eina_hash_stringshared_new(_elm_widget_item_part_text_custom_free);
5855 label = eina_hash_find(item->labels, part);
5858 label = malloc(sizeof(Elm_Label_Data));
5861 ERR("Failed to allocate memory");
5864 label->part = eina_stringshare_add(part);
5865 label->text = eina_stringshare_add(text);
5866 eina_hash_add(item->labels, part, label);
5869 eina_stringshare_replace(&label->text, text);
5872 EOLIAN static const char *
5873 _elm_widget_item_part_text_custom_get(Eo *eo_item EINA_UNUSED,
5874 Elm_Widget_Item_Data *item,
5877 Elm_Label_Data *label;
5878 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item, NULL);
5879 label = eina_hash_find(item->labels, part);
5880 return label ? label->text : NULL;
5884 _elm_widget_item_part_text_custom_foreach(const Eina_Hash *labels EINA_UNUSED,
5885 const void *key EINA_UNUSED,
5889 Elm_Label_Data *label;
5890 Elm_Widget_Item_Data *item;
5894 eo_do(item->eo_obj, elm_wdg_item_part_text_set(label->part, label->text));
5900 _elm_widget_item_part_text_custom_update(Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item)
5902 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
5903 ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
5905 eina_hash_foreach(item->labels,
5906 _elm_widget_item_part_text_custom_foreach, item);
5910 _elm_widget_item_signal_emit(Eo *eo_item EINA_UNUSED,
5911 Elm_Widget_Item_Data *item EINA_UNUSED,
5912 const char *emission EINA_UNUSED,
5913 const char *source EINA_UNUSED)
5919 _elm_widget_item_signal_callback_add(Eo *eo_item,
5920 Elm_Widget_Item_Data *item,
5921 const char *emission,
5923 Elm_Object_Item_Signal_Cb func,
5926 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
5927 ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
5928 EINA_SAFETY_ON_NULL_RETURN(func);
5930 Elm_Widget_Item_Signal_Data *wisd;
5932 wisd = malloc(sizeof(Elm_Widget_Item_Signal_Data));
5935 wisd->item = eo_item;
5936 wisd->func = (Elm_Widget_Item_Signal_Cb)func;
5938 wisd->emission = eina_stringshare_add(emission);
5939 wisd->source = eina_stringshare_add(source);
5941 if (_elm_widget_is(item->view))
5942 elm_object_signal_callback_add(item->view, emission, source, _elm_widget_item_signal_cb, wisd);
5943 else if (eo_isa(item->view, EDJE_OBJECT_CLASS))
5944 edje_object_signal_callback_add(item->view, emission, source, _elm_widget_item_signal_cb, wisd);
5947 WRN("The %s widget item doesn't support signal callback add!",
5948 eo_class_name_get(eo_class_get(item->widget)));
5953 item->signals = eina_list_append(item->signals, wisd);
5956 EOLIAN static void *
5957 _elm_widget_item_signal_callback_del(Eo *eo_item EINA_UNUSED,
5958 Elm_Widget_Item_Data *item,
5959 const char *emission,
5961 Elm_Object_Item_Signal_Cb func)
5963 Elm_Widget_Item_Signal_Data *wisd;
5966 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item, NULL);
5967 ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item, NULL);
5968 EINA_SAFETY_ON_NULL_RETURN_VAL(func, NULL);
5970 EINA_LIST_FOREACH(item->signals, l, wisd)
5972 if ((wisd->func == (Elm_Widget_Item_Signal_Cb)func) &&
5973 !strcmp(wisd->emission, emission) &&
5974 !strcmp(wisd->source, source))
5975 return _elm_widget_item_signal_callback_list_get(item, l);
5982 _elm_widget_item_access_info_set(Eo *eo_item EINA_UNUSED,
5983 Elm_Widget_Item_Data *item,
5986 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
5987 ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
5989 eina_stringshare_del(item->access_info);
5990 if (!txt) item->access_info = NULL;
5991 else item->access_info = eina_stringshare_add(txt);
5995 _elm_widget_item_translate(Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item)
5997 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
5998 ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
6001 Elm_Translate_String_Data *ts;
6002 EINA_INLIST_FOREACH(item->translate_strings, ts)
6004 if (!ts->string) continue;
6005 const char *s = dgettext(ts->domain, ts->string);
6006 item->on_translate = EINA_TRUE;
6007 eo_do(item->eo_obj, elm_wdg_item_part_text_set(ts->id, s));
6008 item->on_translate = EINA_FALSE;
6014 _elm_widget_item_access_order_set(Eo *eo_item EINA_UNUSED,
6015 Elm_Widget_Item_Data *item,
6018 _elm_access_widget_item_access_order_set(item, objs);
6021 EOLIAN static const Eina_List *
6022 _elm_widget_item_access_order_get(const Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item)
6024 return _elm_access_widget_item_access_order_get(item);
6028 _elm_widget_item_access_order_unset(Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item)
6030 _elm_access_widget_item_access_order_unset(item);
6033 EOLIAN static Evas_Object*
6034 _elm_widget_item_access_register(Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item)
6036 _elm_access_widget_item_register(item);
6037 return item->access_obj;
6041 _elm_widget_item_access_unregister(Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item)
6043 _elm_access_widget_item_unregister(item);
6046 EOLIAN static Evas_Object*
6047 _elm_widget_item_access_object_get(const Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item)
6049 return item->access_obj;
6052 EOLIAN static Evas_Object *
6053 _elm_widget_item_focus_next_object_get(const Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item, Elm_Focus_Direction dir)
6055 Evas_Object *ret = NULL;
6057 if (dir == ELM_FOCUS_PREVIOUS)
6058 ret = item->focus_previous;
6059 else if (dir == ELM_FOCUS_NEXT)
6060 ret = item->focus_next;
6061 else if (dir == ELM_FOCUS_UP)
6062 ret = item->focus_up;
6063 else if (dir == ELM_FOCUS_DOWN)
6064 ret = item->focus_down;
6065 else if (dir == ELM_FOCUS_RIGHT)
6066 ret = item->focus_right;
6067 else if (dir == ELM_FOCUS_LEFT)
6068 ret = item->focus_left;
6074 _elm_widget_item_focus_next_object_set(Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item, Evas_Object *next, Elm_Focus_Direction dir)
6076 if (dir == ELM_FOCUS_PREVIOUS)
6077 item->focus_previous = next;
6078 else if (dir == ELM_FOCUS_NEXT)
6079 item->focus_next = next;
6080 else if (dir == ELM_FOCUS_UP)
6081 item->focus_up = next;
6082 else if (dir == ELM_FOCUS_DOWN)
6083 item->focus_down = next;
6084 else if (dir == ELM_FOCUS_RIGHT)
6085 item->focus_right = next;
6086 else if (dir == ELM_FOCUS_LEFT)
6087 item->focus_left = next;
6090 EOLIAN static Elm_Object_Item*
6091 _elm_widget_item_focus_next_item_get(const Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item, Elm_Focus_Direction dir)
6093 Elm_Object_Item *ret = NULL;
6095 if (dir == ELM_FOCUS_PREVIOUS)
6096 ret = item->item_focus_previous;
6097 else if (dir == ELM_FOCUS_NEXT)
6098 ret = item->item_focus_next;
6099 else if (dir == ELM_FOCUS_UP)
6100 ret = item->item_focus_up;
6101 else if (dir == ELM_FOCUS_DOWN)
6102 ret = item->item_focus_down;
6103 else if (dir == ELM_FOCUS_RIGHT)
6104 ret = item->item_focus_right;
6105 else if (dir == ELM_FOCUS_LEFT)
6106 ret = item->item_focus_left;
6112 _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)
6114 if (dir == ELM_FOCUS_PREVIOUS)
6115 item->item_focus_previous = next_item;
6116 else if (dir == ELM_FOCUS_NEXT)
6117 item->item_focus_next = next_item;
6118 else if (dir == ELM_FOCUS_UP)
6119 item->item_focus_up = next_item;
6120 else if (dir == ELM_FOCUS_DOWN)
6121 item->item_focus_down = next_item;
6122 else if (dir == ELM_FOCUS_RIGHT)
6123 item->item_focus_right = next_item;
6124 else if (dir == ELM_FOCUS_LEFT)
6125 item->item_focus_left = next_item;
6128 /* happy debug functions */
6131 _sub_obj_tree_dump(const Evas_Object *obj,
6136 for (i = 0; i < lvl * 3; i++)
6139 if (_elm_widget_is(obj))
6144 elm_widget_type_get(obj),
6146 EINA_LIST_FOREACH(sd->subobjs, l, obj)
6147 _sub_obj_tree_dump(obj, lvl + 1);
6150 DBG("+ %s(%p)\n", evas_object_type_get(obj), obj);
6154 _sub_obj_tree_dot_dump(const Evas_Object *obj,
6157 if (!_elm_widget_is(obj))
6161 Eina_Bool visible = evas_object_visible_get(obj);
6162 Eina_Bool disabled = elm_widget_disabled_get(obj);
6163 Eina_Bool focused = elm_widget_focus_get(obj);
6164 Eina_Bool can_focus = elm_widget_can_focus_get(obj);
6168 fprintf(output, "\"%p\" -- \"%p\" [ color=black", sd->parent_obj, obj);
6171 fprintf(output, ", style=bold");
6174 fprintf(output, ", color=gray28");
6176 fprintf(output, " ];\n");
6179 fprintf(output, "\"%p\" [ label = \"{%p|%s|%s|visible: %d|"
6180 "disabled: %d|focused: %d/%d|focus order:%d}\"",
6181 obj, obj, elm_widget_type_get(obj),
6182 evas_object_name_get(obj), visible, disabled, focused, can_focus,
6186 fprintf(output, ", style=bold");
6189 fprintf(output, ", fontcolor=gray28");
6191 if ((disabled) || (!visible))
6192 fprintf(output, ", color=gray");
6194 fprintf(output, " ];\n");
6198 EINA_LIST_FOREACH(sd->subobjs, l, o)
6199 _sub_obj_tree_dot_dump(o, output);
6205 elm_widget_tree_dump(const Evas_Object *top)
6208 if (!_elm_widget_is(top))
6210 _sub_obj_tree_dump(top, 0);
6218 elm_widget_tree_dot_dump(const Evas_Object *top,
6222 if (!_elm_widget_is(top))
6224 fprintf(output, "graph " " { node [shape=record];\n");
6225 _sub_obj_tree_dot_dump(top, output);
6226 fprintf(output, "}\n");
6235 _elm_widget_eo_base_constructor(Eo *obj, Elm_Widget_Smart_Data *sd EINA_UNUSED)
6239 sd->on_create = EINA_TRUE;
6240 obj = eo_do_super_ret(obj, MY_CLASS, obj, eo_constructor());
6242 evas_obj_type_set(MY_CLASS_NAME_LEGACY),
6243 evas_obj_smart_callbacks_descriptions_set(_smart_callbacks),
6244 parent = eo_parent_get());
6245 eo_do(obj, elm_obj_widget_parent_set(parent));
6246 sd->on_create = EINA_FALSE;
6247 //TIZEN_ONLY(20170717) : expose highlight information on atspi
6248 sd->can_highlight = EINA_TRUE;
6250 /* TIZEN_ONLY(20160622): Override Paragraph Direction APIs */
6251 sd->inherit_paragraph_direction = EINA_TRUE;
6254 eo_do(obj, elm_interface_atspi_accessible_role_set(ELM_ATSPI_ROLE_UNKNOWN));
6256 /* TIZEN_ONLY(20161117): Inherit paragraph direction from widget parent */
6257 if (sd->paragraph_direction != evas_object_paragraph_direction_get(parent))
6259 sd->paragraph_direction = evas_object_paragraph_direction_get(parent);
6260 _elm_widget_evas_object_paragraph_direction_set_internal(obj, sd, sd->paragraph_direction);
6261 eo_do_super(obj, MY_CLASS, evas_obj_paragraph_direction_set(sd->paragraph_direction));
6269 _elm_widget_eo_base_destructor(Eo *obj, Elm_Widget_Smart_Data *sd EINA_UNUSED)
6271 sd->on_destroy = EINA_TRUE;
6273 elm_interface_atspi_accessible_description_set(NULL),
6274 elm_interface_atspi_accessible_name_set(NULL),
6275 //TIZEN_ONLY(20190922): add name callback, description callback.
6276 elm_interface_atspi_accessible_description_cb_set(NULL, NULL),
6277 elm_interface_atspi_accessible_name_cb_set(NULL, NULL),
6279 //TIZEN_ONLY(20170405) Add gesture method to accessible interface
6280 elm_interface_atspi_accessible_gesture_cb_set(NULL, NULL),
6282 elm_interface_atspi_accessible_translation_domain_set(NULL),
6283 elm_interface_atspi_accessible_relationships_clear(),
6284 // TIZEN_ONLY(20160930) : endless recursion fix
6285 elm_interface_atspi_accessible_attributes_clear()
6288 // TIZEN_ONLY(20150709) : atspi relations api
6289 if (sd->atspi_custom_relations)
6290 elm_atspi_relation_set_free(&sd->atspi_custom_relations);
6292 //TIZEN_ONLY(20150717) add widget name setter
6294 eina_stringshare_del(sd->name);
6297 //TIZEN_ONLY(20150731) : add i18n support for name and description
6298 if (sd->atspi_translation_domain)
6299 eina_stringshare_del(sd->atspi_translation_domain);
6301 //Tizen Only(20160728) free attribute list
6304 Elm_Atspi_Attribute *attr;
6305 EINA_LIST_FREE(sd->attr_list, attr)
6307 eina_stringshare_del(attr->key);
6308 eina_stringshare_del(attr->value);
6314 eo_do_super(obj, ELM_WIDGET_CLASS, eo_destructor());
6315 sd->on_destroy = EINA_FALSE;
6317 elm_interface_atspi_accessible_removed(obj);
6320 EOLIAN static Eina_Bool
6321 _elm_widget_on_focus(Eo *obj, Elm_Widget_Smart_Data *sd, Elm_Object_Item *item EINA_UNUSED)
6323 if (elm_widget_can_focus_get(obj))
6325 if (elm_widget_focus_get(obj))
6327 if (!sd->resize_obj)
6328 evas_object_focus_set(obj, EINA_TRUE);
6329 eo_do(obj, eo_event_callback_call
6330 (ELM_WIDGET_EVENT_FOCUSED, NULL));
6331 if (_elm_atspi_enabled() && !elm_widget_child_can_focus_get(obj))
6332 elm_interface_atspi_accessible_state_changed_signal_emit(obj, ELM_ATSPI_STATE_FOCUSED, EINA_TRUE);
6336 if (!sd->resize_obj)
6337 evas_object_focus_set(obj, EINA_FALSE);
6338 eo_do(obj, eo_event_callback_call
6339 (ELM_WIDGET_EVENT_UNFOCUSED, NULL));
6340 if (_elm_atspi_enabled() && !elm_widget_child_can_focus_get(obj))
6341 elm_interface_atspi_accessible_state_changed_signal_emit(obj, ELM_ATSPI_STATE_FOCUSED, EINA_FALSE);
6350 EOLIAN static Eina_Bool
6351 _elm_widget_disable(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *_pd EINA_UNUSED)
6356 EOLIAN static Eina_Bool
6357 _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)
6362 EOLIAN static Eina_Bool
6363 _elm_widget_focus_next_manager_is(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *_pd EINA_UNUSED)
6365 WRN("The %s widget does not implement the \"focus_next/focus_next_manager_is\" functions.",
6366 eo_class_name_get(eo_class_get(obj)));
6371 _elm_widget_focus_direction_manager_is(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *_pd EINA_UNUSED)
6373 WRN("The %s widget does not implement the \"focus_direction/focus_direction_manager_is\" functions.",
6374 eo_class_name_get(eo_class_get(obj)));
6378 EOLIAN static Eina_Bool
6379 _elm_widget_activate(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *_pd EINA_UNUSED, Elm_Activate act EINA_UNUSED)
6381 WRN("The %s widget does not implement the \"activate\" functions.",
6382 eo_class_name_get(eo_class_get(obj)));
6387 _elm_widget_class_constructor(Eo_Class *klass)
6389 evas_smart_legacy_type_register(MY_CLASS_NAME_LEGACY, klass);
6392 EOLIAN static Eina_Bool
6393 _elm_widget_elm_interface_atspi_component_focus_grab(Eo *obj, Elm_Widget_Smart_Data *pd EINA_UNUSED)
6395 if (elm_object_focus_allow_get(obj))
6397 Ecore_Evas *ee = ecore_evas_ecore_evas_get(evas_object_evas_get(obj));
6398 if (!ee) return EINA_FALSE;
6399 ecore_evas_activate(ee);
6400 elm_object_focus_set(obj, EINA_TRUE);
6406 //TIZEN_ONLY(20170119): Show the object highlighted by highlight_grab when the object is completely out of the scroll
6408 _elm_widget_showing_geometry_get(Eo *obj, int *x, int *y, int *w, int *h)
6410 Evas_Object *parent;
6411 Evas_Coord px, py, sx, sy, sw, sh;
6420 evas_object_geometry_get(obj, x, y, w, h);
6422 if (elm_widget_is(obj))
6423 parent = elm_widget_parent_get(obj);
6425 parent = elm_widget_parent_widget_get(obj);
6429 if (eo_isa(parent, ELM_INTERFACE_SCROLLABLE_MIXIN))
6431 evas_object_geometry_get(parent, &sx, &sy, &sw, &sh);
6434 *x = *x > sx ? *x : sx;
6435 *y = *y > sy ? *y : sy;
6436 *w = px + *w < sx + sw ? px + *w - *x : sx + sw - *x;
6437 *h = py + *h < sy + sh ? py + *h - *y : sy + sh - *y;
6439 parent = elm_widget_parent_get(parent);
6444 _accessible_object_on_screen_is(Eo *obj, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h, Eina_Bool is_complete)
6446 if(!obj) return EINA_FALSE;
6448 Evas_Object *target = obj;
6449 Evas_Object *parent = NULL;
6450 Evas_Coord px, py, sx, sy, sw, sh, ox, oy, ow, oh;
6452 /* uninitialized data could be read */
6456 if (elm_widget_is(target))
6457 parent = elm_widget_parent_get(target);
6459 parent = elm_widget_parent_widget_get(target);
6463 if (eo_isa(parent, ELM_INTERFACE_SCROLLABLE_MIXIN))
6465 evas_object_geometry_get(parent, &sx, &sy, &sw, &sh);
6470 ox = is_complete ? ox : ox + ow;
6471 oy = is_complete ? oy : oy + oh;
6472 ox = ox > sx ? ox : sx;
6473 oy = oy > sy ? oy : sy;
6474 ow = px + ow < sx + sw ? px + ow - ox : sx + sw - ox;
6475 oh = py + oh < sy + sh ? py + oh - oy : sy + sh - oy;
6477 if (ow <= 0 || oh <= 0)
6480 parent = elm_widget_parent_get(parent);
6486 _accessible_scrollable_parent_list_get(Eo *obj)
6488 if(!obj) return NULL;
6490 Evas_Object *parent = NULL;
6491 Eina_List *plist = NULL;
6493 if (elm_widget_is(obj))
6494 parent = elm_widget_parent_get(obj);
6496 parent = elm_widget_parent_widget_get(obj);
6500 if (_elm_scrollable_is(parent))
6501 plist = eina_list_append(plist, parent);
6503 parent = elm_widget_parent_get(parent);
6509 _accessible_highlight_region_show(Eo* obj)
6513 Evas_Object *target = obj;
6514 Evas_Object *parent = NULL;
6515 Evas_Object *parent_sub = NULL;
6516 Eina_List *plist, *plist_sub;
6519 Evas_Coord target_x, target_y, target_w, target_h;
6521 evas_object_geometry_get(target, &target_x, &target_y, &target_w, &target_h);
6523 plist = _accessible_scrollable_parent_list_get(target);
6526 EINA_LIST_FOREACH(plist, l, parent)
6528 if(!_accessible_object_on_screen_is(target, target_x, target_y, target_w, target_h, EINA_TRUE))
6530 plist_sub = _accessible_scrollable_parent_list_get(parent);
6531 plist_sub = eina_list_prepend(plist_sub, parent);
6532 EINA_LIST_FOREACH(plist_sub, l2, parent_sub)
6534 Evas_Coord scroll_x = 0, scroll_y = 0;
6535 Evas_Coord scroll_x_back = 0, scroll_y_back = 0;
6536 Evas_Coord x, y, w, h;
6539 eo_do(parent_sub, elm_interface_scrollable_content_region_get(&scroll_x_back, &scroll_y_back, NULL, NULL));
6540 evas_object_geometry_get(parent_sub, &px, &py, NULL, NULL);
6541 x = target_x; y = target_y; w = target_w; h = target_h;
6543 x -= (px - scroll_x_back);
6544 y -= (py - scroll_y_back);
6545 switch (_elm_config->focus_autoscroll_mode)
6547 case ELM_FOCUS_AUTOSCROLL_MODE_SHOW:
6548 eo_do(parent_sub, elm_interface_scrollable_content_region_show(x, y, w, h));
6550 case ELM_FOCUS_AUTOSCROLL_MODE_BRING_IN:
6551 eo_do(parent_sub, elm_interface_scrollable_region_bring_in(x, y, w, h));
6556 eo_do(parent_sub, elm_interface_scrollable_content_region_get(&scroll_x, &scroll_y, NULL, NULL));
6558 target_x -= (scroll_x - scroll_x_back);
6559 target_y -= (scroll_y - scroll_y_back);
6561 if(_accessible_object_on_screen_is(target, target_x, target_y, target_w, target_h, EINA_FALSE))
6564 eina_list_free(plist_sub);
6568 eina_list_free(plist);
6572 //TIZEN_ONLY(20171011) : atspi : During the highlight grab, out signal is not sent.
6574 _elm_widget_accessibility_highlight_grabbing_get(Eo *obj)
6576 ELM_WIDGET_DATA_GET(obj, wd);
6577 return wd->highlight_grabbing;
6581 _elm_widget_accessibility_highlight_grabbing_set(Eo *obj, Eina_Bool grabbing)
6583 ELM_WIDGET_DATA_GET(obj, wd);
6584 wd->highlight_grabbing = grabbing;
6588 //TIZEN_ONLY(20160329): atspi: implement HighlightGrab and HighlightClear methods (29e253e2f7ef3c632ac3a64c489bf569df407f30)
6589 EOLIAN static Eina_Bool
6590 _elm_widget_elm_interface_atspi_component_highlight_grab(Eo *obj, Elm_Widget_Smart_Data *pd EINA_UNUSED)
6592 if(!obj) return EINA_FALSE;
6593 if(!_elm_atspi_enabled())
6595 // TIZEN_ONLY(20171020) : atspi : Do not send signal, if current object and highlight object are same
6596 if (_elm_object_accessibility_currently_highlighted_get() == obj)
6600 //TIZEN_ONLY(20171011) : atspi : During the highlight grab, out signal is not sent.
6601 _elm_widget_accessibility_highlight_grabbing_set(obj, EINA_TRUE);
6604 //TIZEN_ONLY(20170119): Show the object highlighted by highlight_grab when the object is completely out of the scroll
6605 _accessible_highlight_region_show(obj);
6608 elm_object_accessibility_highlight_set(obj, EINA_TRUE);
6609 elm_interface_atspi_accessible_state_changed_signal_emit(obj, ELM_ATSPI_STATE_HIGHLIGHTED, EINA_TRUE);
6611 // TIZEN_ONLY(20161018): add highlighted/unhighlighted signal for atspi
6612 evas_object_smart_callback_call(obj, SIG_WIDGET_ATSPI_HIGHLIGHTED, NULL);
6614 //TIZEN_ONLY(20171011) : atspi : During the highlight grab, out signal is not sent.
6615 _elm_widget_accessibility_highlight_grabbing_set(obj, EINA_FALSE);
6620 EOLIAN static Eina_Bool
6621 _elm_widget_elm_interface_atspi_component_highlight_clear(Eo *obj, Elm_Widget_Smart_Data *pd EINA_UNUSED)
6623 if(!_elm_atspi_enabled())
6625 elm_object_accessibility_highlight_set(obj, EINA_FALSE);
6626 elm_interface_atspi_accessible_state_changed_signal_emit(obj, ELM_ATSPI_STATE_HIGHLIGHTED, EINA_FALSE);
6628 // TIZEN_ONLY(20161018): add highlighted/unhighlighted signal for atspi
6629 evas_object_smart_callback_call(obj, SIG_WIDGET_ATSPI_UNHIGHLIGHTED, NULL);
6635 EOLIAN static const char*
6636 _elm_widget_elm_interface_atspi_accessible_name_get(Eo *obj, Elm_Widget_Smart_Data *_pd)
6638 //TIZEN_ONLY(20190922): add name callback, description callback.
6639 const char *ret = NULL;
6640 eo_do_super(obj, ELM_WIDGET_CLASS, ret = elm_interface_atspi_accessible_name_get());
6641 if (ret) return ret;
6644 //TIZEN_ONLY(20150717) add widget name setter
6648 if (_pd->atspi_translation_domain)
6649 return dgettext(_pd->atspi_translation_domain, _pd->name);
6655 //TIZEN_ONLY(20170110) : Ignore text from elm_object_text_set in accessible_name_get
6656 Elm_Atspi_Role role;
6657 eo_do(obj, role = elm_interface_atspi_accessible_role_get());
6658 if(role == ELM_ATSPI_ROLE_DIALOG)
6662 ret = elm_object_text_get(obj);
6663 if (!ret) return NULL;
6665 return _elm_widget_accessible_plain_name_get(obj, ret);
6667 //TIZEN_ONLY(20161111) add widget/widget_item description get/set
6669 _elm_widget_elm_interface_atspi_accessible_description_set(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data* _pd EINA_UNUSED, const char *description)
6671 if (_pd->description)
6672 eina_stringshare_del(_pd->description);
6674 _pd->description = eina_stringshare_add(description);
6677 EOLIAN static const char*
6678 _elm_widget_elm_interface_atspi_accessible_description_get(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *_pd EINA_UNUSED)
6680 const char *ret = NULL;
6681 eo_do_super(obj, ELM_WIDGET_CLASS, ret = elm_interface_atspi_accessible_description_get());
6682 if (ret) return ret;
6685 if (_pd->atspi_translation_domain)
6686 return dgettext(_pd->atspi_translation_domain, _pd->description);
6688 return _pd->description;
6692 //TIZEN_ONLY(20150713) : add atspi name setter to widget_item
6694 _elm_widget_item_elm_interface_atspi_accessible_name_set(Eo *obj EINA_UNUSED, Elm_Widget_Item_Data* _pd EINA_UNUSED, const char *name)
6697 eina_stringshare_del(_pd->name);
6699 _pd->name = eina_stringshare_add(name);
6703 _elm_widget_item_elm_interface_atspi_accessible_name_get(Eo *obj EINA_UNUSED, Elm_Widget_Item_Data *_pd EINA_UNUSED)
6705 //TIZEN_ONLY(20190922): add name callback, description callback.
6706 const char *ret = NULL;
6707 eo_do_super(obj, ELM_WIDGET_ITEM_CLASS, ret = elm_interface_atspi_accessible_name_get());
6708 if (ret) return ret;
6714 if (_pd->atspi_translation_domain)
6715 return dgettext(_pd->atspi_translation_domain, _pd->name);
6723 //TIZEN_ONLY(20161111) add widget/widget_item description get/set
6725 _elm_widget_item_elm_interface_atspi_accessible_description_set(Eo *obj EINA_UNUSED, Elm_Widget_Item_Data* _pd EINA_UNUSED, const char *description)
6727 if (_pd->description)
6728 eina_stringshare_del(_pd->description);
6730 _pd->description = eina_stringshare_add(description);
6734 _elm_widget_item_elm_interface_atspi_accessible_description_get(Eo *obj EINA_UNUSED, Elm_Widget_Item_Data *_pd EINA_UNUSED)
6736 const char *ret = NULL;
6737 eo_do_super(obj, ELM_WIDGET_ITEM_CLASS, ret = elm_interface_atspi_accessible_description_get());
6738 if (ret) return ret;
6741 if (_pd->atspi_translation_domain)
6742 return dgettext(_pd->atspi_translation_domain, _pd->description);
6744 return _pd->description;
6747 //TIZEN_ONLY(20150709) : spatially sort atspi children
6748 static int _sort_vertically(const void *data1, const void *data2)
6751 evas_object_geometry_get(data1, NULL, &y1, NULL, NULL);
6752 evas_object_geometry_get(data2, NULL, &y2, NULL, NULL);
6754 return y1 < y2 ? -1 : 1;
6757 static int _sort_horizontally(const void *data1, const void *data2)
6760 evas_object_geometry_get(data1, &x1, NULL, NULL, NULL);
6761 evas_object_geometry_get(data2, &x2, NULL, NULL, NULL);
6763 return x1 < x2 ? -1 : 1;
6766 static Eina_List *_lines_split(Eina_List *children)
6769 Eina_List *lines, *line, *l;
6770 Evas_Coord yl, y, hl, h;
6771 lines = line = NULL;
6773 if (!children) return NULL;
6775 EINA_LIST_FOREACH(children, l, c)
6777 evas_object_geometry_get(c, NULL, &yl, NULL, &hl);
6779 /* remove child if its height == 0 */
6783 EINA_LIST_FREE(children, c)
6785 evas_object_geometry_get(c, NULL, &y, NULL, &h);
6787 /* remove child if its height == 0 */
6788 if (h == 0 && !eo_isa(c, ELM_ATSPI_PROXY_CLASS)) continue;
6790 if ((yl + (int)(0.25 * hl)) >= y)
6793 line = eina_list_append(line,c);
6797 // finish current line & start new
6798 lines = eina_list_append(lines, line);
6800 line = eina_list_append(NULL, c);
6804 return eina_list_append(lines, line);
6808 // TIZEN_ONLY(20160705) - enable atspi_proxy to work
6810 _proxy_widget_move_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
6815 evas_object_geometry_get(obj, &x, &y, NULL, NULL);
6816 elm_atspi_bridge_utils_proxy_offset_set(proxy, x, y);
6821 _on_widget_del(void *data, Eo *obj EINA_UNUSED, const Eo_Event_Description *desc EINA_UNUSED, void *event_info EINA_UNUSED)
6824 // TIZEN_ONLY(20160705) - enable atspi_proxy to work
6825 evas_object_event_callback_del_full(obj, EVAS_CALLBACK_MOVE,
6826 _proxy_widget_move_cb, plug);
6832 // TIZEN_ONLY(20160705) - enable atspi_proxy to work
6834 _on_proxy_connected_cb(void *data, Eo *obj, const Eo_Event_Description *desc EINA_UNUSED, void *event_info EINA_UNUSED)
6837 Evas_Object *widget = data;
6839 evas_object_geometry_get(widget, &x, &y, NULL, NULL);
6840 elm_atspi_bridge_utils_proxy_offset_set(obj, x, y);
6842 evas_object_event_callback_add(widget, EVAS_CALLBACK_MOVE, _proxy_widget_move_cb, obj);
6848 //TIZEN_ONLY(20170621) handle atspi proxy connection at runtime
6850 _plug_type_proxy_get(Eo *obj, Evas_Object *widget)
6853 const char *plug_id;
6854 char *svcname, *svcnum;
6856 if ((plug_id = evas_object_data_get(widget, "___PLUGID")) != NULL)
6858 // TIZEN_ONLY(20160930) : endless recursion fix
6859 eo_do_super(obj, MY_CLASS, elm_interface_atspi_accessible_attribute_append("___PlugID", plug_id));
6861 proxy = evas_object_data_get(widget, "__widget_proxy");
6862 if (proxy) return proxy;
6864 if (_elm_atspi_bridge_plug_id_split(plug_id, &svcname, &svcnum))
6866 proxy = _elm_atspi_bridge_utils_proxy_create(obj, svcname, atoi(svcnum), ELM_ATSPI_PROXY_TYPE_PLUG);
6867 evas_object_data_set(widget, "__widget_proxy", proxy);
6868 eo_do(widget, eo_event_callback_add(EO_EV_DEL, _on_widget_del, proxy));
6869 eo_do(proxy, eo_event_callback_add(ELM_ATSPI_PROXY_EVENT_CONNECTED, _on_proxy_connected_cb, widget));
6870 elm_atspi_bridge_utils_proxy_connect(proxy);
6880 elm_widget_atspi_plug_type_proxy_get(Evas_Object *obj)
6882 Elm_Widget_Smart_Data *wd;
6883 Evas_Object *widget;
6886 wd = eo_data_scope_get(obj, ELM_WIDGET_CLASS);
6887 if (!wd) return NULL;
6890 EINA_LIST_FOREACH(wd->subobjs, l, widget)
6892 if (evas_object_data_get(widget, "___PLUGID"))
6893 proxy = _plug_type_proxy_get(obj, widget);
6900 EOLIAN static Eina_List*
6901 _elm_widget_elm_interface_atspi_accessible_children_get(Eo *obj, Elm_Widget_Smart_Data *pd EINA_UNUSED)
6903 Eina_List *l, *accs = NULL;
6904 Elm_Widget_Smart_Data *wd;
6905 Evas_Object *widget;
6906 // TIZEN_ONLY(20160824): Do not append a child, if its accessible parent is different with widget parent
6910 wd = eo_data_scope_get(obj, ELM_WIDGET_CLASS);
6911 if (!wd) return NULL;
6913 EINA_LIST_FOREACH(wd->subobjs, l, widget)
6915 const char *type = evas_object_type_get(widget);
6917 // Ugly Tizen hack to integrate AT-SPI2 accessibility provided by WebKit/Chromium with elementary one.
6918 // This wrapper class should be implemented in Webkit/Chromium EFL ports
6919 if (type && (!strcmp(type, "EWebView") || !strcmp(type, "WebView"))) {
6920 elm_atspi_ewk_wrapper_a11y_init(obj, widget);
6925 EINA_LIST_FOREACH(wd->subobjs, l, widget)
6927 // TIZEN_ONLY(20160824): Do not append a child, if its accessible parent is different with widget parent
6928 if (eo_isa(widget, ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN)) {
6929 eo_do(widget, parent = elm_interface_atspi_accessible_parent_get());
6930 if (parent && (parent != obj)) continue;
6933 // TIZEN_ONLY(20160705) - enable atspi_proxy to work
6934 /* This assumes that only one proxy exists in obj */
6937 proxy = _plug_type_proxy_get(obj, widget);
6940 accs = eina_list_append(accs, proxy);
6946 if (!elm_object_widget_check(widget)) continue;
6947 if (eo_isa(widget, ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN))
6948 accs = eina_list_append(accs, widget);
6950 //TIZEN_ONLY(20150709) : spatially sort atspi children
6951 // sort children using its top-left coordinate
6952 accs = eina_list_sort(accs, -1, _sort_vertically);
6953 Eina_List *line, *lines = _lines_split(accs);
6955 EINA_LIST_FREE(lines, line)
6956 accs = eina_list_merge(accs, eina_list_sort(line, -1, _sort_horizontally));
6962 accs = eina_list_remove(accs, proxy);
6963 EINA_LIST_FOREACH(accs, l, widget)
6965 if (eo_isa(widget, ELM_ACCESS_CLASS))
6967 Elm_Access_Info *info = _elm_access_info_get(widget);
6968 if (!info) continue;
6969 if (obj == info->part_object)
6979 accs = eina_list_append_relative(accs, proxy, deputy);
6986 _elm_widget_elm_interface_atspi_accessible_parent_get(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *pd)
6989 eo_do_super(obj, ELM_WIDGET_CLASS, ret = elm_interface_atspi_accessible_parent_get());
6991 return ret ? ret : pd->parent_obj;
6994 //TIZEN_ONLY(20161107): enhance elm_atspi_accessible_can_highlight_set to set can_hihglight property to its children
6996 _elm_widget_highlightable(Evas_Object *obj)
6999 Eina_Bool can_highlight;
7001 Elm_Widget_Smart_Data *wd = eo_data_scope_get(obj, ELM_WIDGET_CLASS);
7002 if (!wd) return EINA_FALSE;
7003 if (!wd->can_highlight) return EINA_FALSE;
7005 eo_do(obj, parent = elm_interface_atspi_accessible_parent_get());
7006 while (parent && !eo_isa(parent, ELM_ATSPI_APP_OBJECT_CLASS))
7008 //TIZEN_ONLY(20160929) : atspi: Improves how to find the can_highlight of the widget
7009 if (!_elm_widget_can_highlight_get_by_class(parent)) return EINA_FALSE;
7011 eo_do(parent, parent = elm_interface_atspi_accessible_parent_get());
7017 EOLIAN static Elm_Atspi_State_Set
7018 _elm_widget_elm_interface_atspi_accessible_state_set_get(Eo *obj, Elm_Widget_Smart_Data *pd)
7020 Elm_Atspi_State_Set states = 0;
7022 eo_do_super(obj, ELM_WIDGET_CLASS, states = elm_interface_atspi_accessible_state_set_get());
7024 if (evas_object_visible_get(obj))
7026 STATE_TYPE_SET(states, ELM_ATSPI_STATE_VISIBLE);
7027 if (_elm_widget_onscreen_is(obj))
7028 STATE_TYPE_SET(states, ELM_ATSPI_STATE_SHOWING);
7030 if (!elm_widget_child_can_focus_get(obj))
7032 if (elm_object_focus_allow_get(obj))
7033 STATE_TYPE_SET(states, ELM_ATSPI_STATE_FOCUSABLE);
7034 if (elm_object_focus_get(obj))
7035 STATE_TYPE_SET(states, ELM_ATSPI_STATE_FOCUSED);
7037 if (!elm_object_disabled_get(obj))
7039 STATE_TYPE_SET(states, ELM_ATSPI_STATE_ENABLED);
7040 STATE_TYPE_SET(states, ELM_ATSPI_STATE_SENSITIVE);
7043 //TIZEN_ONLY(20170717) : expose highlight information on atspi
7044 if (_elm_widget_highlightable(obj) && _accessible_object_on_scroll_is(obj))
7045 STATE_TYPE_SET(states, ELM_ATSPI_STATE_HIGHLIGHTABLE);
7047 STATE_TYPE_UNSET(states, ELM_ATSPI_STATE_HIGHLIGHTABLE);
7049 if (_elm_object_accessibility_currently_highlighted_get() == (void*)pd->obj)
7050 STATE_TYPE_SET(states, ELM_ATSPI_STATE_HIGHLIGHTED);
7056 //TIZEN_ONLY(20160729): attributes_get, append APIs added/updated.
7057 EOLIAN static Eina_List*
7058 _elm_widget_elm_interface_atspi_accessible_attributes_get(Eo *obj, Elm_Widget_Smart_Data *pd EINA_UNUSED)
7060 Eina_List *attr_list = NULL;
7061 // TIZEN_ONLY(20160930) : endless recursion fix
7062 eo_do_super(obj, MY_CLASS, attr_list = elm_interface_atspi_accessible_attributes_get());
7064 //Add type and style information in addition.
7065 Elm_Atspi_Attribute *attr = NULL;
7066 attr = calloc(1, sizeof(Elm_Atspi_Attribute));
7069 attr->key = eina_stringshare_add("type");
7070 attr->value = eina_stringshare_add(elm_widget_type_get(obj));
7071 attr_list = eina_list_append(attr_list, attr);
7074 attr = calloc(1, sizeof(Elm_Atspi_Attribute));
7077 attr->key = eina_stringshare_add("style");
7078 attr->value = eina_stringshare_add(elm_widget_style_get(obj));
7079 attr_list = eina_list_append(attr_list, attr);
7085 //TIZEN_ONLY(20150709) : atspi relations api
7086 EOLIAN static Elm_Atspi_Relation_Set
7087 _elm_widget_elm_interface_atspi_accessible_relation_set_get(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd)
7089 return elm_atspi_relation_set_clone(&sd->atspi_custom_relations);
7092 EOLIAN static Elm_Atspi_Relation_Set
7093 _elm_widget_item_elm_interface_atspi_accessible_relation_set_get(Eo *obj EINA_UNUSED, Elm_Widget_Item_Data *sd)
7095 return elm_atspi_relation_set_clone(&sd->atspi_custom_relations);
7099 _elm_widget_elm_interface_atspi_accessible_relationships_clear(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd)
7101 elm_atspi_relation_set_free(&sd->atspi_custom_relations);
7102 sd->atspi_custom_relations = NULL;
7107 _elm_widget_item_elm_interface_atspi_accessible_relationships_clear(Eo *obj EINA_UNUSED, Elm_Widget_Item_Data *sd)
7109 elm_atspi_relation_set_free(&sd->atspi_custom_relations);
7110 sd->atspi_custom_relations = NULL;
7115 _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)
7128 evas_object_geometry_get(sd->view, x, y, w, h);
7131 Ecore_Evas *ee = ecore_evas_ecore_evas_get(evas_object_evas_get(sd->view));
7133 ecore_evas_geometry_get(ee, &ee_x, &ee_y, NULL, NULL);
7139 EOLIAN static Eina_Bool
7140 _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)
7146 _elm_widget_item_elm_interface_atspi_component_layer_get(Eo *obj EINA_UNUSED, Elm_Widget_Item_Data *sd EINA_UNUSED)
7150 return evas_object_layer_get(sd->view);
7153 EOLIAN static Eina_Bool
7154 _elm_widget_item_elm_interface_atspi_component_focus_grab(Eo *obj EINA_UNUSED, Elm_Widget_Item_Data *_pd EINA_UNUSED)
7156 elm_object_item_focus_set(obj, EINA_TRUE);
7157 return elm_object_item_focus_get(obj);
7160 //TIZEN_ONLY(20160329): atspi: implement HighlightGrab and HighlightClear methods
7162 EOLIAN static Eina_Bool
7163 _elm_widget_item_elm_interface_atspi_component_highlight_grab(Eo *obj, Elm_Widget_Item_Data *sd)
7165 if (!sd) return EINA_FALSE;
7166 if (!sd->view) return EINA_FALSE;
7167 // TIZEN_ONLY(20171020) : atspi : Do not send signal, if current object and highlight object are same
7168 if (_elm_object_accessibility_currently_highlighted_get() == obj)
7172 //TIZEN_ONLY(20171011) : atspi : During the highlight grab, out signal is not sent.
7173 _elm_widget_accessibility_highlight_grabbing_set(sd->view, EINA_TRUE);
7176 //TIZEN_ONLY(20170119): Show the object highlighted by highlight_grab when the object is completely out of the scroll
7177 _accessible_highlight_region_show(sd->view);
7180 if (!sd->eo_obj) return EINA_FALSE;
7181 elm_object_accessibility_highlight_set(sd->eo_obj, EINA_TRUE);
7183 if (!obj) return EINA_FALSE;
7184 elm_interface_atspi_accessible_state_changed_signal_emit(obj, ELM_ATSPI_STATE_HIGHLIGHTED, EINA_TRUE);
7186 //TIZEN_ONLY(20170412) Make atspi,(un)highlighted work on widget item
7187 evas_object_smart_callback_call(sd->widget, SIG_WIDGET_ATSPI_HIGHLIGHTED, obj);
7189 //TIZEN_ONLY(20171011) : atspi : During the highlight grab, out signal is not sent.
7190 _elm_widget_accessibility_highlight_grabbing_set(sd->view, EINA_FALSE);
7195 EOLIAN static Eina_Bool
7196 _elm_widget_item_elm_interface_atspi_component_highlight_clear(Eo *obj, Elm_Widget_Item_Data *sd)
7198 if (!obj) return EINA_FALSE;
7199 elm_object_accessibility_highlight_set(sd->eo_obj, EINA_FALSE);
7200 elm_interface_atspi_accessible_state_changed_signal_emit(obj, ELM_ATSPI_STATE_HIGHLIGHTED, EINA_FALSE);
7202 //TIZEN_ONLY(20170412) Make atspi,(un)highlighted work on widget item
7203 evas_object_smart_callback_call(sd->widget, SIG_WIDGET_ATSPI_UNHIGHLIGHTED, obj);
7209 EOLIAN static double
7210 _elm_widget_item_elm_interface_atspi_component_alpha_get(Eo *obj EINA_UNUSED, Elm_Widget_Item_Data *sd EINA_UNUSED)
7214 if (!sd->view) return -1.0;
7215 evas_object_color_get(sd->view, NULL, NULL, NULL, &alpha);
7216 return (double)alpha / 255.0;
7219 //TIZEN_ONLY(20150717) add widget name setter
7221 _elm_widget_elm_interface_atspi_accessible_name_set(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data* _pd EINA_UNUSED, const char *name)
7224 eina_stringshare_del(_pd->name);
7226 _pd->name = eina_stringshare_add(name);
7230 //TIZEN_ONLY(20160329): widget: improve accessibile_at_point getter (a8aff0423202b9a55dbb3843205875226678fbd6)
7232 _coordinate_system_based_point_translate(Eo *obj, Eina_Bool screen_coords, int *x, int *y)
7240 ee = ecore_evas_ecore_evas_get(evas_object_evas_get(obj));
7243 ecore_evas_geometry_get(ee, &ee_x, &ee_y, NULL, NULL);
7249 static Evas_Object *
7250 _parent_get(Evas_Object *obj)
7252 Evas_Object *parent;
7254 parent = evas_object_smart_parent_get(obj);
7257 if (strcmp("Elm_Win", eo_class_name_get(eo_class_get(obj))))
7258 parent = elm_widget_parent_get(obj);
7265 _is_inside(Evas_Object *obj, int x, int y)
7267 Eina_Bool ret = EINA_TRUE;
7272 if (eo_isa(obj, ELM_WIDGET_ITEM_CLASS))
7274 Elm_Widget_Item_Data *id = eo_data_scope_get(obj, ELM_WIDGET_ITEM_CLASS);
7275 evas_object_geometry_get(id->view, &cx, &cy, &cw, &ch);
7278 evas_object_geometry_get(obj, &cx, &cy, &cw, &ch);
7280 /* check the point is out of bound */
7281 if (x < cx || x > cx + cw || y < cy || y > cy + ch)
7289 _is_ancestor_of(Evas_Object *smart_parent, Evas_Object *obj)
7291 Eina_Bool ret = EINA_FALSE;
7292 Evas_Object *parent = elm_widget_parent_get(obj);
7295 /* No need to check more, the smart_parent is parent of obj */
7296 if (smart_parent == parent)
7301 parent = elm_widget_parent_get(parent);
7307 static int _sort_by_size(const void *data1, const void *data2)
7312 evas_object_geometry_get(data1, NULL, NULL, &w, &h);
7313 evas_object_geometry_get(data2, NULL, NULL, &w2, &h2);
7315 if ((w * h) > (w2 * h2)) return 1;
7320 _elm_widget_atspi_role_acceptable_check(Eo *obj)
7322 Elm_Atspi_Role role;
7323 eo_do(obj, role = elm_interface_atspi_accessible_role_get());
7327 case ELM_ATSPI_ROLE_APPLICATION:
7328 case ELM_ATSPI_ROLE_FILLER:
7329 case ELM_ATSPI_ROLE_SCROLL_PANE:
7330 case ELM_ATSPI_ROLE_SPLIT_PANE:
7331 case ELM_ATSPI_ROLE_WINDOW:
7332 case ELM_ATSPI_ROLE_IMAGE:
7333 case ELM_ATSPI_ROLE_LIST:
7334 case ELM_ATSPI_ROLE_ICON:
7335 case ELM_ATSPI_ROLE_TOOL_BAR:
7336 case ELM_ATSPI_ROLE_REDUNDANT_OBJECT:
7337 case ELM_ATSPI_ROLE_COLOR_CHOOSER:
7338 case ELM_ATSPI_ROLE_TREE_TABLE:
7339 case ELM_ATSPI_ROLE_PAGE_TAB_LIST:
7340 case ELM_ATSPI_ROLE_PAGE_TAB:
7341 case ELM_ATSPI_ROLE_SPIN_BUTTON:
7342 case ELM_ATSPI_ROLE_INPUT_METHOD_WINDOW:
7343 case ELM_ATSPI_ROLE_EMBEDDED:
7344 case ELM_ATSPI_ROLE_INVALID:
7345 case ELM_ATSPI_ROLE_NOTIFICATION:
7346 case ELM_ATSPI_ROLE_DATE_EDITOR:
7356 _child_object_at_point_get(Eo *obj, int x, int y)
7358 Eina_List *l, *l_next, *children, *valid_children = NULL;
7363 eo_do(obj, children = elm_interface_atspi_accessible_children_get());
7365 EINA_LIST_FOREACH(children, l, child)
7367 if (_is_inside(child, x, y))
7368 valid_children = eina_list_append(valid_children, child);
7371 EINA_LIST_FOREACH_SAFE(valid_children, l, l_next, child)
7373 eo_do(child, children = elm_interface_atspi_accessible_children_get());
7375 /* do not use unacceptable leaf node */
7376 if (!_elm_widget_atspi_role_acceptable_check(child) &&
7377 eina_list_count(children) == 0)
7378 valid_children = eina_list_remove_list(valid_children, l);
7381 count = eina_list_count(valid_children);
7384 valid_children = eina_list_sort(valid_children, -1, _sort_by_size);
7385 target = eina_list_nth(valid_children, 0);
7387 return _child_object_at_point_get(target, x, y);
7394 _acceptable_child_is(Eo *obj)
7396 Elm_Atspi_Role role;
7397 Eina_List *children;
7398 Elm_Atspi_State_Set ss;
7400 eo_do(obj, role = elm_interface_atspi_accessible_role_get());
7403 case ELM_ATSPI_ROLE_IMAGE:
7404 case ELM_ATSPI_ROLE_ICON:
7405 /* remove unacceptable leaf node */
7406 eo_do(obj, children = elm_interface_atspi_accessible_children_get());
7407 if (!children) return EINA_FALSE;
7410 case ELM_ATSPI_ROLE_PANEL:
7411 /* remove closed panel fron children list */
7412 eo_do(obj, ss = elm_interface_atspi_accessible_state_set_get());
7413 if (!STATE_TYPE_GET(ss, ELM_ATSPI_STATE_SHOWING)) return EINA_FALSE;
7424 _accessible_at_point_top_down_get(Eo *obj, Elm_Widget_Smart_Data *_pd EINA_UNUSED, Eina_Bool screen_coords, int x, int y)
7426 Eina_List *l, *l2, *children, *valid_children = NULL;
7428 Evas_Object *stack_item;
7430 // TIZEN_ONLY(20160705) - enable atspi_proxy to work
7432 Evas_Coord px, py, pw, ph;
7435 _coordinate_system_based_point_translate(obj, screen_coords, &x, &y);
7437 eo_do(obj, children = elm_interface_atspi_accessible_children_get());
7439 EINA_LIST_FOREACH(children, l2, child)
7441 if (_is_inside(child, x, y) && _acceptable_child_is(child))
7442 valid_children = eina_list_append(valid_children, child);
7445 /* If there is only one valid child at point, then return it.
7446 The evas_tree_objects_at_xy_get could not find proper object,
7447 if application does not have well aligned objects. */
7448 if (eina_list_count(valid_children) == 1)
7450 eina_list_free(children);
7451 child = eina_list_nth(valid_children, 0);
7455 /* Get evas_object stacked at given x,y coordinates starting from top */
7456 Eina_List *stack = evas_tree_objects_at_xy_get(evas_object_evas_get(obj), NULL, x, y);
7457 /* Foreach stacked object starting from top */
7458 EINA_LIST_FOREACH(stack, l, stack_item)
7460 /* Foreach at-spi valid children traverse stack_item evas_objects hierarchy */
7461 EINA_LIST_FOREACH(valid_children, l2, child)
7463 /* Compare object used to compare with stacked evas objects */
7464 compare_obj = child;
7465 /* In case of widget_items compare should be different then elm_widget_ item object */
7466 if (eo_isa(child, ELM_WIDGET_ITEM_CLASS))
7468 Elm_Widget_Item_Data *id = eo_data_scope_get(child, ELM_WIDGET_ITEM_CLASS);
7469 compare_obj = id->view;
7470 if (TIZEN_PROFILE_WEARABLE)
7472 Eo* it_view = evas_object_image_source_get(stack_item);
7473 if (it_view && it_view == compare_obj)
7475 eina_list_free(children);
7476 eina_list_free(stack);
7481 /* In case of access object compare should be 'wrapped' evas_object */
7482 if (eo_isa(child, ELM_ACCESS_CLASS))
7484 Elm_Access_Info *info = _elm_access_info_get(child);
7485 if (!info) continue;
7486 compare_obj = info->part_object;
7488 /* In case of widget is registerd by elm_access_object_register */
7489 Evas_Object *ao = elm_access_object_get(child);
7492 eina_list_free(children);
7493 eina_list_free(stack);
7497 /* In case of ewk wrapper object compare with internal ewk_view evas_object */
7498 if (eo_isa(child, ELM_ATSPI_EWK_WRAPPER_CLASS))
7500 compare_obj = elm_atspi_ewk_wrapper_ewk_view_get(child);
7503 /* If spacial eo children do not have backing evas_object continue with search */
7507 Evas_Object *smart_parent = stack_item;
7508 while (smart_parent)
7510 if (smart_parent == compare_obj)
7512 eina_list_free(children);
7513 eina_list_free(stack);
7517 // TIZEN_ONLY(20160705) - enable atspi_proxy to work
7518 proxy = evas_object_data_get(smart_parent, "__widget_proxy");
7521 evas_object_geometry_get(smart_parent, &px, &py, &pw, &ph);
7522 if (x >= px && x <= px + pw && y >= py && y <= py +ph)
7524 eina_list_free(children);
7525 eina_list_free(stack);
7531 smart_parent = _parent_get(smart_parent);
7532 if (_is_ancestor_of(smart_parent, obj)) break;
7537 eina_list_free(children);
7538 eina_list_free(stack);
7542 static int _sort_by_repeat_events(const void *data1, const void *data2)
7544 Evas_Object *ao1, *ao2;
7545 Eina_Bool repeat1, repeat2;
7547 ao1 = elm_access_object_get(data1);
7548 ao2 = elm_access_object_get(data2);
7550 repeat1 = evas_object_repeat_events_get(data1);
7551 repeat2 = evas_object_repeat_events_get(data2);
7553 if (repeat1 != repeat2)
7555 if (repeat1 && !ao1) return 1;
7559 if (repeat1 && !ao1 && ao2) return 1;
7565 static Eo *_item_at_point_get(Evas_Object *obj, int x, int y)
7568 Eina_List *l, *children;
7570 eo_do(obj, children = elm_interface_atspi_accessible_children_get());
7572 EINA_LIST_FOREACH(children, l, child)
7574 if (_is_inside(child, x, y)) return child;
7577 ERR("No child at point (%d, %d) on object %p", x, y, obj);
7582 _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)
7585 Evas_Object *stack_item;
7587 if(strcmp("Elm_Win", eo_class_name_get(eo_class_get(obj))) &&
7588 strcmp("Elm_Popup", eo_class_name_get(eo_class_get(obj))) &&
7589 strcmp("Elm_Panel", eo_class_name_get(eo_class_get(obj))))
7590 return _accessible_at_point_top_down_get(obj, _pd, screen_coords, x, y);
7592 _coordinate_system_based_point_translate(obj, screen_coords, &x, &y);
7594 Eina_List *stack = evas_tree_objects_at_xy_get(evas_object_evas_get(obj), NULL, x, y);
7595 stack = eina_list_sort(stack, -1, _sort_by_repeat_events);
7597 EINA_LIST_FOREACH(stack, l, stack_item)
7599 Evas_Object *smart_parent = stack_item;
7600 while (smart_parent)
7602 /* If parent equals to obj, it is not necessary to go upper.
7603 So the top down logic would be better than NULL return. */
7604 if (smart_parent == obj)
7605 return _accessible_at_point_top_down_get(obj, _pd, screen_coords, x, y);
7607 Evas_Object *ao = elm_access_object_get(smart_parent);
7610 if (eo_isa(smart_parent, ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN))
7612 Eina_Bool acceptable = EINA_FALSE;
7614 Elm_Atspi_Role role;
7615 eo_do(smart_parent, role = elm_interface_atspi_accessible_role_get());
7618 case ELM_ATSPI_ROLE_FILLER: /* ex: View of colorselector item is layout */
7619 case ELM_ATSPI_ROLE_ICON:
7620 case ELM_ATSPI_ROLE_IMAGE:
7621 case ELM_ATSPI_ROLE_REDUNDANT_OBJECT:
7622 case ELM_ATSPI_ROLE_WINDOW:
7623 DBG("Go for parent: %s (%p)\n", evas_object_type_get(smart_parent), smart_parent);
7626 case ELM_ATSPI_ROLE_LIST:
7627 item_child = _item_at_point_get(smart_parent, x, y);
7628 if (TIZEN_PROFILE_WEARABLE)
7630 item_child = _child_object_at_point_get(item_child, x, y);
7637 acceptable = EINA_TRUE;
7641 if (acceptable) return smart_parent;
7644 smart_parent = _parent_get(smart_parent);
7647 return _accessible_at_point_top_down_get(obj, _pd, screen_coords, x, y);
7651 //TIZEN_ONLY(20150709) add relations atpi
7652 EOLIAN static Eina_Bool
7653 _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)
7655 return elm_atspi_relation_set_relation_append(&sd->atspi_custom_relations, type, relation_obj);
7659 _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)
7661 elm_atspi_relation_set_relation_remove(&sd->atspi_custom_relations, type, relation_obj);
7664 EOLIAN static Eina_Bool
7665 _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)
7667 return elm_atspi_relation_set_relation_append(&sd->atspi_custom_relations, type, relation_obj);
7671 _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)
7673 elm_atspi_relation_set_relation_remove(&sd->atspi_custom_relations, type, relation_obj);
7677 //TIZEN_ONLY(20150731) : add i18n support for name and description
7679 _elm_widget_elm_interface_atspi_accessible_translation_domain_set(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *_pd, const char *domain)
7681 eina_stringshare_replace(&_pd->atspi_translation_domain, domain);
7684 EOLIAN static const char*
7685 _elm_widget_elm_interface_atspi_accessible_translation_domain_get(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *_pd)
7687 return _pd->atspi_translation_domain;
7691 _elm_widget_item_elm_interface_atspi_accessible_translation_domain_set(Eo *obj EINA_UNUSED, Elm_Widget_Item_Data *_pd, const char *domain)
7693 eina_stringshare_replace(&_pd->atspi_translation_domain, domain);
7696 EOLIAN static const char*
7697 _elm_widget_item_elm_interface_atspi_accessible_translation_domain_get(Eo *obj EINA_UNUSED, Elm_Widget_Item_Data *_pd)
7699 return _pd->atspi_translation_domain;
7702 //TIZEN_ONLY(20160726): add API elm_atspi_accessible_can_highlight_set/get
7704 _children_highlight_check(Eo *obj)
7706 Eina_List *children, *l;
7709 if (_elm_object_accessibility_currently_highlighted_get() == (void *)obj)
7711 eo_do(obj, elm_interface_atspi_component_highlight_clear());
7715 eo_do(obj, children = elm_interface_atspi_accessible_children_get());
7716 EINA_LIST_FOREACH(children, l, child)
7718 if (_children_highlight_check(child)) return EINA_TRUE;
7725 _elm_widget_elm_interface_atspi_accessible_can_highlight_set(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *_pd, Eina_Bool can_highlight)
7727 if (!can_highlight) _children_highlight_check(obj);
7728 _pd->can_highlight = !!can_highlight;
7731 EOLIAN static Eina_Bool
7732 _elm_widget_elm_interface_atspi_accessible_can_highlight_get(Eo *obj, Elm_Widget_Smart_Data *_pd EINA_UNUSED)
7734 return _elm_widget_highlightable(obj);
7738 _elm_widget_item_elm_interface_atspi_accessible_can_highlight_set(Eo *obj EINA_UNUSED, Elm_Widget_Item_Data *_pd, Eina_Bool can_highlight)
7740 if (!can_highlight) _children_highlight_check(obj);
7741 _pd->can_highlight = !!can_highlight;
7744 EOLIAN static Eina_Bool
7745 _elm_widget_item_elm_interface_atspi_accessible_can_highlight_get(Eo *obj, Elm_Widget_Item_Data *_pd EINA_UNUSED)
7747 return _elm_widget_item_highlightable(obj);
7751 //TIZEN_ONLY(20160622): Override Paragraph Direction APIs
7753 _elm_widget_evas_object_paragraph_direction_set_internal(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd, Evas_BiDi_Direction dir)
7758 if (sd->on_destroy) return;
7760 EINA_LIST_FOREACH(sd->subobjs, l, child)
7762 if (_elm_widget_is(child))
7764 Elm_Widget_Smart_Data *sdc = eo_data_scope_get(child, MY_CLASS);
7766 if (sdc->inherit_paragraph_direction &&
7767 (sdc->paragraph_direction != dir))
7769 sdc->paragraph_direction = dir;
7770 _elm_widget_evas_object_paragraph_direction_set_internal(child, sdc, dir);
7771 eo_do_super(child, MY_CLASS, evas_obj_paragraph_direction_set(dir));
7775 /* FIXME: There is no way to handle non-widget child object.
7776 * If a non-widget child object has smart parent, it will get the direction
7777 * from the smart parent. */
7782 _elm_widget_evas_object_paragraph_direction_set(Eo *obj, Elm_Widget_Smart_Data *sd, Evas_BiDi_Direction dir)
7784 if ((!(sd->inherit_paragraph_direction) && (sd->paragraph_direction == dir)) ||
7785 (sd->inherit_paragraph_direction && (dir == EVAS_BIDI_DIRECTION_INHERIT)))
7788 if (dir == EVAS_BIDI_DIRECTION_INHERIT)
7790 sd->inherit_paragraph_direction = EINA_TRUE;
7791 Evas_BiDi_Direction parent_dir = EVAS_BIDI_DIRECTION_NEUTRAL;
7794 parent_dir = evas_object_paragraph_direction_get(sd->parent_obj);
7796 if (parent_dir != sd->paragraph_direction)
7798 sd->paragraph_direction = parent_dir;
7799 _elm_widget_evas_object_paragraph_direction_set_internal(obj, sd, parent_dir);
7804 sd->inherit_paragraph_direction = EINA_FALSE;
7805 sd->paragraph_direction = dir;
7806 _elm_widget_evas_object_paragraph_direction_set_internal(obj, sd, dir);
7809 eo_do_super(obj, MY_CLASS, evas_obj_paragraph_direction_set(dir));
7814 //TIZEN_ONLY(20161013): clean up elm color class feature
7816 _edje_color_class_free(void *data)
7818 Edje_Color_Class *cc = data;
7820 if (cc->name) eina_stringshare_del(cc->name);
7825 _elm_widget_edje_class_get(const Eo_Class *klass, const char *style, const char *part)
7828 Eina_Stringshare *str;
7830 buf = eina_strbuf_new();
7832 eina_strbuf_append(buf, strchr(eo_class_name_get(klass), '_') + 1);
7833 eina_strbuf_tolower(buf);
7837 eina_strbuf_append_printf(buf, "/%s/%s", style, part);
7841 eina_strbuf_append_printf(buf, "/%s", part);
7844 str = eina_stringshare_add(eina_strbuf_string_get(buf));
7846 eina_strbuf_free(buf);
7850 /* TIZEN_ONLY(20161025): Apply color_class parent-child relationship */
7852 _elm_widget_color_class_set_internal(Evas_Object *obj, Evas_Object *edje, const char *color_class,
7853 int r, int g, int b, int a,
7854 int r2, int g2, int b2, int a2,
7855 int r3, int g3, int b3, int a3)
7857 Eina_Bool int_ret = EINA_TRUE;
7858 Eina_Stringshare *buf;
7859 int temp_color[3][4] = { { r, g, b, a },
7861 { r3, g3, b3, a3 } };
7863 if (!color_class) return EINA_FALSE;
7865 buf = _elm_widget_edje_class_get(eo_class_get(obj), NULL, color_class);
7867 #define TEMP_COLOR(x, y) \
7868 ((temp_color[x][y] == -1) ? &temp_color[x][y] : NULL)
7870 edje_object_color_class_get(edje, buf,
7871 TEMP_COLOR(0, 0), TEMP_COLOR(0, 1), TEMP_COLOR(0, 2), TEMP_COLOR(0, 3),
7872 TEMP_COLOR(1, 0), TEMP_COLOR(1, 1), TEMP_COLOR(1, 2), TEMP_COLOR(1, 3),
7873 TEMP_COLOR(2, 0), TEMP_COLOR(2, 1), TEMP_COLOR(2, 2), TEMP_COLOR(2, 3));
7877 #define TEMP_COLOR(x, y) \
7878 ((temp_color[x][y] == -1) ? 0 : temp_color[x][y])
7880 int_ret &= edje_object_color_class_set(edje, buf,
7881 TEMP_COLOR(0, 0), TEMP_COLOR(0, 1), TEMP_COLOR(0, 2), TEMP_COLOR(0, 3),
7882 TEMP_COLOR(1, 0), TEMP_COLOR(1, 1), TEMP_COLOR(1, 2), TEMP_COLOR(1, 3),
7883 TEMP_COLOR(2, 0), TEMP_COLOR(2, 1), TEMP_COLOR(2, 2), TEMP_COLOR(2, 3));
7887 eina_stringshare_del(buf);
7893 _elm_widget_color_class_get_internal(Evas_Object *obj, Evas_Object *edje, const char *color_class,
7894 int *r, int *g, int *b, int *a,
7895 int *r2, int *g2, int *b2, int *a2,
7896 int *r3, int *g3, int *b3, int *a3)
7898 Eina_Bool int_ret = EINA_TRUE;
7899 Eina_Stringshare *buf;
7901 if (!color_class) return EINA_FALSE;
7903 buf = _elm_widget_edje_class_get(eo_class_get(obj), elm_widget_style_get(obj), color_class);
7905 int_ret &= edje_object_color_class_get(edje, buf,
7910 eina_stringshare_del(buf);
7917 _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)
7920 Eina_Bool int_ret = EINA_TRUE;
7922 if (!eo_isa(obj, ELM_LAYOUT_CLASS)) return EINA_FALSE;
7924 edje = elm_layout_edje_get(obj);
7925 int_ret &= _elm_widget_color_class_set_internal(obj, edje, color_class,
7934 _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)
7937 Eina_Bool int_ret = EINA_TRUE;
7939 if (!eo_isa(obj, ELM_LAYOUT_CLASS)) return EINA_FALSE;
7941 edje = elm_layout_edje_get(obj);
7942 int_ret &= _elm_widget_color_class_get_internal(obj, edje, color_class,
7944 NULL, NULL, NULL, NULL,
7945 NULL, NULL, NULL, NULL);
7951 _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)
7954 Eina_Bool int_ret = EINA_TRUE;
7956 if (!eo_isa(obj, ELM_LAYOUT_CLASS)) return EINA_FALSE;
7958 edje = elm_layout_edje_get(obj);
7959 int_ret &= _elm_widget_color_class_set_internal(obj, edje, color_class,
7968 _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)
7971 Eina_Bool int_ret = EINA_TRUE;
7973 if (!eo_isa(obj, ELM_LAYOUT_CLASS)) return EINA_FALSE;
7975 edje = elm_layout_edje_get(obj);
7976 int_ret &= _elm_widget_color_class_get_internal(obj, edje, color_class,
7977 NULL, NULL, NULL, NULL,
7979 NULL, NULL, NULL, NULL);
7985 _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)
7988 Eina_Bool int_ret = EINA_TRUE;
7990 if (!eo_isa(obj, ELM_LAYOUT_CLASS)) return EINA_FALSE;
7992 edje = elm_layout_edje_get(obj);
7993 int_ret &= _elm_widget_color_class_set_internal(obj, edje, color_class,
8002 _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)
8005 Eina_Bool int_ret = EINA_TRUE;
8007 if (!eo_isa(obj, ELM_LAYOUT_CLASS)) return EINA_FALSE;
8009 edje = elm_layout_edje_get(obj);
8010 int_ret &= _elm_widget_color_class_get_internal(obj, edje, color_class,
8011 NULL, NULL, NULL, NULL,
8012 NULL, NULL, NULL, NULL,
8019 _elm_widget_class_color_del(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd, const char *color_class)
8021 Eina_Stringshare *buf;
8023 if (!eo_isa(obj, ELM_LAYOUT_CLASS)) return;
8025 buf = _elm_widget_edje_class_get(eo_class_get(obj), NULL, color_class);
8026 edje_object_color_class_del(sd->resize_obj, buf);
8027 eina_stringshare_del(buf);
8031 _elm_widget_class_color_clear(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd)
8033 if (!eo_isa(obj, ELM_LAYOUT_CLASS)) return;
8034 edje_object_color_class_clear(sd->resize_obj);
8037 #define ELM_COLOR_CLASS_UPDATE(obj, hash, cond) \
8038 Evas_Object *edje = NULL; \
8039 Eina_Iterator *itr; \
8040 Edje_Color_Class *cc; \
8041 Eina_Bool int_ret = EINA_TRUE; \
8042 if (cond) return EINA_FALSE; \
8043 if (eo_isa(obj, ELM_LAYOUT_CLASS)) \
8044 edje = elm_layout_edje_get(obj); \
8045 else if (eo_isa(obj, EDJE_OBJECT_CLASS)) \
8047 if (!edje) return EINA_FALSE; \
8048 itr = eina_hash_iterator_data_new(hash); \
8049 EINA_ITERATOR_FOREACH(itr, cc) \
8051 int_ret &= edje_object_color_class_set(edje, cc->name, \
8052 cc->r, cc->g, cc->b, cc->a, \
8053 cc->r2, cc->g2, cc->b2, cc->a2, \
8054 cc->r3, cc->g3, cc->b3, cc->a3); \
8056 eina_iterator_free(itr); \
8060 #define CHECK_BOUND(x) \
8061 if (x > 0xff) x = 0xff; \
8062 else if (x < 0) x = 0
8064 #define ELM_COLOR_CLASS_SET_START(obj, cr, cg, cb, ca) \
8065 Eina_Bool int_ret = EINA_FALSE; \
8066 Edje_Color_Class *cc = NULL; \
8067 Eina_Stringshare *buf; \
8068 buf = _elm_widget_edje_class_get(eo_class_get(obj), NULL, color_class); \
8073 _elm_color_unpremul(a, &r, &g, &b); \
8074 if (!sd->color_classes) \
8075 sd->color_classes = eina_hash_string_small_new(_edje_color_class_free); \
8077 cc = eina_hash_find(sd->color_classes, buf); \
8080 cc = calloc(1, sizeof(Edje_Color_Class)); \
8081 cc->name = eina_stringshare_add(buf); \
8085 eina_stringshare_del(buf); \
8086 return EINA_FALSE; \
8088 eina_hash_direct_add(sd->color_classes, cc->name, cc); \
8090 else if ((cc->cr == r) && (cc->cg == g) && \
8091 (cc->cb == b) && (cc->ca == a)) \
8093 eina_stringshare_del(buf); \
8102 #define ELM_COLOR_CLASS_SET_END() \
8103 eina_stringshare_del(buf); \
8106 #define ELM_COLOR_CLASS_GET(obj, cr, cg, cb, ca) \
8107 Eina_Bool int_ret = EINA_FALSE; \
8108 Edje_Color_Class *cc; \
8109 Eina_Stringshare *buf; \
8111 buf = _elm_widget_edje_class_get(eo_class_get(obj), NULL, color_class); \
8112 if ((!sd->color_classes) || !(cc = eina_hash_find(sd->color_classes, buf))) \
8118 int_ret = EINA_FALSE; \
8122 if (r) *r = cc->cr; \
8123 if (g) *g = cc->cg; \
8124 if (b) *b = cc->cb; \
8125 if (a) *a = cc->ca; \
8127 int_ret = EINA_TRUE; \
8129 _elm_color_premul(alpha, r, g, b); \
8130 eina_stringshare_del(buf); \
8134 _elm_widget_item_color_class_update(Elm_Widget_Item_Data *sd)
8136 ELM_COLOR_CLASS_UPDATE(sd->view, sd->color_classes, (!sd) || (!sd->color_classes) || (!sd->view));
8140 _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)
8142 ELM_COLOR_CLASS_SET_START(obj, r, g, b, a);
8144 int_ret &= _elm_widget_item_color_class_update(sd);
8146 ELM_COLOR_CLASS_SET_END();
8150 _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)
8152 ELM_COLOR_CLASS_GET(obj, r, g, b, a);
8156 _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)
8158 ELM_COLOR_CLASS_SET_START(obj, r2, g2, b2, a2);
8160 int_ret &= _elm_widget_item_color_class_update(sd);
8162 ELM_COLOR_CLASS_SET_END();
8166 _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)
8168 ELM_COLOR_CLASS_GET(obj, r2, g2, b2, a2);
8172 _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)
8174 ELM_COLOR_CLASS_SET_START(obj, r3, g3, b3, a3);
8176 int_ret &= _elm_widget_item_color_class_update(sd);
8178 ELM_COLOR_CLASS_SET_END();
8182 _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)
8184 ELM_COLOR_CLASS_GET(obj, r3, g3, b3, a3);
8187 static Evas_Object *
8188 _elm_widget_item_edje_get(Eo *obj, Elm_Widget_Item_Data *sd)
8191 sd = eo_data_scope_get(obj, ELM_WIDGET_ITEM_CLASS);
8193 if (eo_isa(sd->view, ELM_LAYOUT_CLASS))
8194 return elm_layout_edje_get(sd->view);
8195 else if (eo_isa(sd->view, EDJE_OBJECT_CLASS))
8202 _elm_widget_item_class_color_del(Eo *obj EINA_UNUSED, Elm_Widget_Item_Data *sd, const char *color_class)
8204 Eina_Stringshare *buf;
8206 Edje_Color_Class *cc = NULL;
8208 if (!color_class) return;
8210 buf = _elm_widget_edje_class_get(eo_class_get(obj), NULL, color_class);
8211 eina_hash_del(sd->color_classes, buf, cc);
8213 edje = _elm_widget_item_edje_get(obj, sd);
8215 edje_object_color_class_del(edje, buf);
8217 eina_stringshare_del(buf);
8221 _elm_widget_item_class_color_clear(Eo *obj EINA_UNUSED, Elm_Widget_Item_Data *sd)
8224 ELM_SAFE_FREE(sd->color_classes, eina_hash_free);
8226 edje = _elm_widget_item_edje_get(obj, sd);
8229 edje_object_color_class_clear(edje);
8233 /* TIZEN_ONLY(20161025): Apply color_class parent-child relationship */
8235 _elm_widget_color_class_parent_set(Evas_Object *obj, Evas_Object *parent)
8237 Evas_Object *edje = NULL, *parent_edje = NULL;
8239 if (!obj || !parent) return;
8241 if (eo_isa(obj, ELM_LAYOUT_CLASS))
8242 edje = elm_layout_edje_get(obj);
8243 else if (eo_isa(obj, EDJE_OBJECT_CLASS))
8246 if (eo_isa(parent, ELM_LAYOUT_CLASS))
8247 parent_edje = elm_layout_edje_get(parent);
8248 else if (eo_isa(parent, EDJE_OBJECT_CLASS))
8249 parent_edje = parent;
8251 if (!edje || !parent_edje) return;
8253 edje_object_color_class_parent_set(edje, parent_edje);
8257 _elm_widget_color_class_parent_unset(Evas_Object *obj)
8259 Evas_Object *edje = NULL;
8263 if (eo_isa(obj, ELM_LAYOUT_CLASS))
8264 edje = elm_layout_edje_get(obj);
8265 else if (eo_isa(obj, EDJE_OBJECT_CLASS))
8270 edje_object_color_class_parent_unset(edje);
8274 //TIZEN_ONLY(20160527): widget: add AtspiAction interface to all widgets and widget_items, add handlers for reading stopped/cancelled
8275 EOLIAN const Elm_Atspi_Action *
8276 _elm_widget_elm_interface_atspi_widget_action_elm_actions_get(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *pd EINA_UNUSED)
8281 EOLIAN const Elm_Atspi_Action *
8282 _elm_widget_item_elm_interface_atspi_widget_action_elm_actions_get(Eo *obj EINA_UNUSED, Elm_Widget_Item_Data *pd EINA_UNUSED)
8288 #include "elm_widget_item.eo.c"
8289 #include "elm_widget.eo.c"