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;
2085 // TIZEN_ONLY(20171129): add second_level for weight calculate
2086 Eina_Bool second_level = EINA_FALSE;
2089 if (obj1 == obj2) return 0.0;
2092 while (degree >= 360.0)
2094 while (degree < 0.0)
2097 evas_object_geometry_get(obj1, &obj_x1, &obj_y1, &w1, &h1);
2098 cx = obj_x1 + (w1 / 2.0);
2099 cy = obj_y1 + (h1 / 2.0);
2100 evas_object_geometry_get(obj2, &obj_x2, &obj_y2, &w2, &h2);
2102 /* For overlapping cases. */
2103 if (ELM_RECTS_INTERSECT(obj_x1, obj_y1, w1, h1, obj_x2, obj_y2, w2, h2))
2106 /* Change all points to relative one. */
2116 /* Get crossing points (ax, ay) between obj1 and a line extending
2117 * to the direction of current degree. */
2123 else if (degree == 90.0)
2128 else if (degree == 180.0)
2133 else if (degree == 270.0)
2140 g = tan(degree * (M_PI / 180.0));
2141 if ((degree > 0.0) && (degree < 90.0))
2144 if (ay <= yyy1) ax = xx1;
2151 else if ((degree > 90.0) && (degree < 180.0))
2154 if (ay <= yyy1) ax = x1;
2161 else if ((degree > 180.0) && (degree < 270.0))
2164 if (ay >= yy1) ax = x1;
2174 if (ay >= yy1) ax = xx1;
2183 /* Filter obj2, if it is not in the specific derection. */
2185 double rx[4] = {0.0, 0.0, 0.0, 0.0}, ry[4] = {0.0, 0.0, 0.0, 0.0};
2186 double t1, t2, u1, v1, u2, v2;
2188 if ((degree == 45.0) || (degree == 225.0) || (degree == 135.0) ||
2198 double g2 = tan((degree + 45.0) * (M_PI / 180.0));
2203 t1 = (u1 * ax) + (v1 * ay);
2204 t2 = (u2 * ax) + (v2 * ay);
2206 #define _R(x) (int)((x + 0.05) * 10.0)
2208 if ((_R(t1 * ((u1 * x2) + (v1 * yy2))) > 0) && (_R(t2 * ((u2 * x2) +
2214 if ((_R(t1 * ((u1 * x2) + (v1 * yyy2))) > 0) && (_R(t2 * ((u2 * x2) +
2220 if ((_R(t1 * ((u1 * xx2) + (v1 * yy2))) > 0) && (_R(t2 * ((u2 * xx2) +
2226 if ((_R(t1 * ((u1 * xx2) + (v1 * yyy2))) > 0) &&
2227 (_R(t2 * ((u2 * xx2) + (v2 * yyy2))) > 0))
2236 // TIZEN_ONLY(20171129): add second_level for weight calculate
2237 //if ((_R(xx2) < 0) || (_R(yy2) > 0) || (_R(yyy2) < 0)) return 0.0;
2238 if ((_R(xx2) < 0) || (_R(yy2) > 0) || (_R(yyy2) < 0))
2240 if (xx1 <= x2) second_level = EINA_TRUE;
2245 else if (degree == 90.0)
2247 // TIZEN_ONLY(20171129): add second_level for weight calculate
2248 //if ((_R(yyy2) < 0) || (_R(x2) > 0) || (_R(xx2) < 0)) return 0.0;
2249 if ((_R(yyy2) < 0) || (_R(x2) > 0) || (_R(xx2) < 0))
2251 if (yyy1 <= yy2) second_level = EINA_TRUE;
2256 else if (degree == 180.0)
2258 // TIZEN_ONLY(20171129): add second_level for weight calculate
2259 //if ((_R(x2) > 0) || (_R(yy2) > 0) || (_R(yyy2) < 0)) return 0.0;
2260 if ((_R(x2) > 0) || (_R(yy2) > 0) || (_R(yyy2) < 0))
2262 if (x1 >= xx2) second_level = EINA_TRUE;
2267 else if (degree == 270.0)
2269 // TIZEN_ONLY(20171129): add second_level for weight calculate
2270 //if ((_R(yy2) > 0) || (_R(x2) > 0) || (_R(xx2) < 0)) return 0.0;
2271 if ((_R(yy2) > 0) || (_R(x2) > 0) || (_R(xx2) < 0))
2273 if (yy1 >= yyy2) second_level = EINA_TRUE;
2280 if ((_R(g * x2) >= _R(yy2)) && (_R((g * x2)) <= _R(yyy2)))
2282 if (!((_R(ax * x2) > 0) && (_R(ay * (g * x2)) > 0)))
2285 else if ((_R(g * xx2) >= _R(yy2)) && (_R((g * xx2)) <= _R(yyy2)))
2287 if (!((_R(ax * xx2) > 0) && (_R(ay * (g * xx2)) > 0)))
2290 else if ((_R((1.0 / g) * yy2) >= _R(xx2)) && (_R((1.0 / g) * yy2)
2293 if (!((_R(ax * ((1.0 / g) * yy2)) > 0)
2294 && (_R(ay * yy2) > 0)))
2297 else if ((_R((1.0 / g) * yyy2) >= _R(xx2)) &&
2298 (_R((1.0 / g) * yyy2) <= _R(xx2)))
2300 if (!((_R(ax * ((1.0 / g) * yyy2)) > 0)
2301 && (_R(ay * yyy2) > 0))) return 0.0;
2307 /* Calculate the weight for obj2. */
2310 if (_R(xx1) > _R(x2)) weight = -1.0;
2311 else if ((_R(yy2) >= _R(yy1)) && (_R(yyy2) <= _R(yyy1)))
2312 weight = (x2 - xx1) * (x2 - xx1);
2313 else if (_R(yy2) > 0)
2314 weight = ((x2 - xx1) * (x2 - xx1)) + (yy2 * yy2);
2315 else if (_R(yyy2) < 0)
2316 weight = ((x2 - xx1) * (x2 - xx1)) + (yyy2 * yyy2);
2317 else weight = (x2 - xx1) * (x2 - xx1);
2319 else if (degree == 90.0)
2321 if (_R(yyy1) > _R(yy2)) weight = -1.0;
2322 else if ((_R(x2) >= _R(x1)) && (_R(xx2) <= _R(xx1)))
2323 weight = (yy2 - yyy1) * (yy2 - yyy1);
2324 else if (_R(x2) > 0)
2325 weight = (x2 * x2) + ((yy2 - yyy1) * (yy2 - yyy1));
2326 else if (_R(xx2) < 0)
2327 weight = (xx2 * xx2) + ((yy2 - yyy1) * (yy2 - yyy1));
2328 else weight = (yy2 - yyy1) * (yy2 - yyy1);
2330 else if (degree == 180.0)
2332 if (_R(x1) < _R(xx2)) weight = -1.0;
2333 else if ((_R(yy2) >= _R(yy1)) && (_R(yyy2) <= _R(yyy1)))
2334 weight = (x1 - xx2) * (x1 - xx2);
2335 else if (_R(yy2) > 0)
2336 weight = ((x1 - xx2) * (x1 - xx2)) + (yy2 * yy2);
2337 else if (_R(yyy2) < 0)
2338 weight = ((x1 - xx2) * (x1 - xx2)) + (yyy2 * yyy2);
2339 else weight = (x1 - xx2) * (x1 - xx2);
2341 else if (degree == 270.0)
2343 if (_R(yy1) < _R(yyy2)) weight = -1.0;
2344 else if ((_R(x2) >= _R(x1)) && (_R(xx2) <= _R(xx1)))
2345 weight = (yy1 - yyy2) * (yy1 - yyy2);
2346 else if (_R(x2) > 0)
2347 weight = (x2 * x2) + ((yy1 - yyy2) * (yy1 - yyy2));
2348 else if (_R(xx2) < 0)
2349 weight = (xx2 * xx2) + ((yy1 - yyy2) * (yy1 - yyy2));
2350 else weight = (yy1 - yyy2) * (yy1 - yyy2);
2355 double sx[4] = {0.0, 0.0, 0.0, 0.0}, sy[4] = {0.0, 0.0, 0.0, 0.0};
2356 double t_weight[4] = {-1.0, -1.0, -1.0, -1.0};
2357 if ((_R(g * x2) >= _R(yy2)) && (_R(g * x2) <= _R(yyy2)))
2361 t_weight[j++] = ((ax - x2) * (ax - x2)) +
2362 ((ay - (g * x2)) * (ay - (g * x2)));
2364 if ((_R(g * xx2) >= _R(yy2)) && (_R(g * xx2) <= _R(yyy2)))
2368 t_weight[j++] = ((ax - xx2) * (ax - xx2)) +
2369 ((ay - (g * xx2)) * (ay - (g * xx2)));
2371 if ((_R((1.0 / g) * yy2) >= _R(x2)) && (_R((1.0 / g) * yy2) <= _R(xx2)))
2373 sx[j] = (1.0 / g) * yy2;
2376 ((ax - ((1.0 / g) * yy2)) * (ax - ((1.0 / g) * yy2))) +
2377 ((ay - yy2) * (ay - yy2));
2379 if ((_R((1.0 / g) * yyy2) >= _R(x2)) && (_R((1.0 / g) * yyy2)
2382 sx[j] = (1.0 / g) * yyy2;
2385 ((ax - ((1.0 / g) * yyy2)) * (ax - ((1.0 / g) * yyy2))) +
2386 ((ay - yyy2) * (ay - yyy2));
2389 if ((j > 2) || ((j == 2) && ((_R(sx[0]) != _R(sx[1])) ||
2390 (_R(sy[0]) != _R(sy[1])))))
2394 if (_R(t_weight[k]) == 0) return -1.0;
2395 if ((1 / weight) < (1 / t_weight[k])) weight = t_weight[k];
2402 double ccx, ccy, t1_weight, x_diff, y_diff;
2403 ccx = ((1.0 / g) * rx[k] + ry[k]) / (g + (1.0 / g));
2405 x_diff = rx[k] - ccx;
2406 if (x_diff < 0) x_diff *= -1.0;
2407 y_diff = ry[k] - ccy;
2408 if (y_diff < 0) y_diff *= -1.0;
2410 (((ax - ccx) * (ax - ccx)) + ((ay - ccy) * (ay - ccy))) +
2411 ((x_diff * x_diff * x_diff) + (y_diff * y_diff * y_diff));
2412 if ((_R(t1_weight) != 0) && ((1 / weight) < (1 / t1_weight)))
2417 /* Return the current object's weight. */
2418 if (weight == -1.0) return 0.0;
2419 if (_R(weight) == 0) return -1.0;
2423 // TIZEN_ONLY(20171129): add second_level for weight calculate
2424 if (second_level) return 1.0 / (weight * 1000000.0);
2427 return 1.0 / weight;
2433 * Get near object in one direction of base object.
2435 * Get near object(in the object sub-tree) in one direction of
2436 * base object. Return the near object by reference.
2437 * By initializing weight, you can filter objects locating far
2438 * from base object. If object is in the specific direction,
2439 * weight is (1/(distance^2)). If object is not exactly in one
2440 * direction, some penalty will be added.
2442 * @param obj The widget root of sub-tree
2443 * @param base The base object of the direction
2444 * @param degree Degree changes clockwise. i.e. 0-degree: Up,
2445 * 90-degree: Right, 180-degree: Down, and 270-degree: Left
2446 * @param direction The near object in one direction
2447 * @param weight The weight is bigger when the object is located near
2448 * @return EINA_TRUE if near object is updated.
2453 EOLIAN static Eina_Bool
2454 _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)
2458 /* -1 means the best was already decided. Don't need any more searching. */
2459 if (!direction || !weight || !base || (obj == base))
2462 /* Ignore if disabled */
2463 if ((!evas_object_visible_get(obj))
2464 || (elm_widget_disabled_get(obj))
2465 || (elm_widget_tree_unfocusable_get(obj)))
2469 if (_internal_elm_widget_focus_direction_manager_is(obj))
2471 Eina_Bool int_ret = EINA_FALSE;
2472 eo_do((Eo *)obj, int_ret = elm_obj_widget_focus_direction(base, degree, direction, direction_item, weight));
2476 if (!elm_widget_can_focus_get(obj) || _is_focused((Eo *)obj))
2479 c_weight = _elm_widget_focus_direction_weight_get(base, obj, degree);
2480 if ((c_weight == -1.0) ||
2481 ((c_weight != 0.0) && (*weight != -1.0) &&
2482 ((int)(*weight * 1000000) <= (int)(c_weight * 1000000))))
2485 ((int)(*weight * 1000000) == (int)(c_weight * 1000000)))
2487 ELM_WIDGET_DATA_GET(*direction, sd1);
2490 if (sd->focus_order <= sd1->focus_order)
2494 *direction = (Evas_Object *)obj;
2505 * Get near object in one direction of base object in list.
2507 * Get near object in one direction of base object in the specific
2508 * object list. Return the near object by reference.
2509 * By initializing weight, you can filter objects locating far
2510 * from base object. If object is in the specific direction,
2511 * weight is (1/(distance^2)). If object is not exactly in one
2512 * direction, some penalty will be added.
2514 * @param obj The widget root of sub-tree
2515 * @param base The base object of the direction
2516 * @param items list with ordered objects
2517 * @param list_data_get function to get the object from one item of list
2518 * @param degree Degree changes clockwise. i.e. 0-degree: Up,
2519 * 90-degree: Right, 180-degree: Down, and 270-degree: Left
2520 * @param direction The near object in one direction
2521 * @param weight The weight is bigger when the object is located near
2522 * @return EINA_TRUE if near object is updated.
2526 EOLIAN static Eina_Bool
2527 _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)
2529 if (!direction || !weight || !base || !items)
2532 const Eina_List *l = items;
2533 Evas_Object *current_best = *direction;
2535 for (; l; l = eina_list_next(l))
2537 Evas_Object *cur = list_data_get(l);
2538 if (cur && _elm_widget_is(cur))
2539 elm_widget_focus_direction_get(cur, base, degree, direction, direction_item, weight);
2541 if (current_best != *direction) return EINA_TRUE;
2549 * Get next object in focus chain of object tree.
2551 * Get next object in focus chain of one object sub-tree.
2552 * Return the next object by reference. If don't have any candidate to receive
2553 * focus before chain end, the first candidate will be returned.
2555 * @param obj The widget root of sub-tree
2556 * @param dir Direction of focus chain
2557 * @param next The next object in focus chain
2558 * @return EINA_TRUE if don't need focus chain restart/loop back
2559 * to use 'next' obj.
2563 EOLIAN static Eina_Bool
2564 _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)
2566 Elm_Access_Info *ac;
2572 /* Ignore if disabled */
2573 if (_elm_config->access_mode && _elm_access_auto_highlight_get())
2575 if (!evas_object_visible_get(obj)
2576 || (elm_widget_tree_unfocusable_get(obj)))
2581 if ((!evas_object_visible_get(obj))
2582 || (elm_widget_disabled_get(obj))
2583 || (elm_widget_tree_unfocusable_get(obj)))
2588 if (_elm_widget_focus_chain_manager_is(obj))
2590 Eina_Bool int_ret = EINA_FALSE;
2591 eo_do((Eo *)obj, int_ret = elm_obj_widget_focus_next(dir, next, next_item));
2592 if (!int_ret && _is_focused((Eo *)obj))
2594 Evas_Object *o = NULL;
2595 if (dir == ELM_FOCUS_PREVIOUS)
2596 *next_item = sd->item_focus_previous;
2597 else if (dir == ELM_FOCUS_NEXT)
2598 *next_item = sd->item_focus_next;
2599 else if (dir == ELM_FOCUS_UP)
2600 *next_item = sd->item_focus_up;
2601 else if (dir == ELM_FOCUS_DOWN)
2602 *next_item = sd->item_focus_down;
2603 else if (dir == ELM_FOCUS_RIGHT)
2604 *next_item = sd->item_focus_right;
2605 else if (dir == ELM_FOCUS_LEFT)
2606 *next_item = sd->item_focus_left;
2607 o = elm_object_item_widget_get(*next_item);
2611 if (dir == ELM_FOCUS_PREVIOUS)
2612 o = sd->focus_previous;
2613 else if (dir == ELM_FOCUS_NEXT)
2615 else if (dir == ELM_FOCUS_UP)
2617 else if (dir == ELM_FOCUS_DOWN)
2619 else if (dir == ELM_FOCUS_RIGHT)
2620 o = sd->focus_right;
2621 else if (dir == ELM_FOCUS_LEFT)
2634 /* access object does not check sd->can_focus, because an object could
2635 have highlight even though the object is not focusable. */
2636 if (_elm_config->access_mode && _elm_access_auto_highlight_get())
2638 ac = _elm_access_info_get(obj);
2639 if (!ac) return EINA_FALSE;
2641 /* check whether the hover object is visible or not */
2642 if (!evas_object_visible_get(ac->hoverobj))
2645 else if (!elm_widget_can_focus_get(obj))
2648 if (_is_focused((Eo *)obj))
2650 if (dir == ELM_FOCUS_PREVIOUS)
2651 *next_item = sd->item_focus_previous;
2652 else if (dir == ELM_FOCUS_NEXT)
2653 *next_item = sd->item_focus_next;
2654 else if (dir == ELM_FOCUS_UP)
2655 *next_item = sd->item_focus_up;
2656 else if (dir == ELM_FOCUS_DOWN)
2657 *next_item = sd->item_focus_down;
2658 else if (dir == ELM_FOCUS_RIGHT)
2659 *next_item = sd->item_focus_right;
2660 else if (dir == ELM_FOCUS_LEFT)
2661 *next_item = sd->item_focus_left;
2662 *next = elm_object_item_widget_get(*next_item);
2666 if (dir == ELM_FOCUS_PREVIOUS)
2667 *next = sd->focus_previous;
2668 else if (dir == ELM_FOCUS_NEXT)
2669 *next = sd->focus_next;
2670 else if (dir == ELM_FOCUS_UP)
2671 *next = sd->focus_up;
2672 else if (dir == ELM_FOCUS_DOWN)
2673 *next = sd->focus_down;
2674 else if (dir == ELM_FOCUS_RIGHT)
2675 *next = sd->focus_right;
2676 else if (dir == ELM_FOCUS_LEFT)
2677 *next = sd->focus_left;
2680 if (*next) return EINA_TRUE;
2684 *next = (Evas_Object *)obj;
2685 return !ELM_WIDGET_FOCUS_GET(obj);
2691 * Get next object in focus chain of object tree in list.
2693 * Get next object in focus chain of one object sub-tree ordered by one list.
2694 * Return the next object by reference. If don't have any candidate to receive
2695 * focus before list end, the first candidate will be returned.
2697 * @param obj The widget root of sub-tree
2698 * @param items list with ordered objects
2699 * @param list_data_get function to get the object from one item of list
2700 * @param dir Direction of focus chain
2701 * @param next The next object in focus chain
2702 * @return EINA_TRUE if don't need focus chain restart/loop back
2703 * to use 'next' obj.
2707 EOLIAN static Eina_Bool
2708 _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)
2710 Eina_List *(*list_next)(const Eina_List *list) = NULL;
2711 Evas_Object *focused_object = NULL;
2717 if (!_elm_widget_is(obj))
2723 /* When Up, Down, Right, or Left, try direction_get first. */
2724 focused_object = elm_widget_focused_object_get(obj);
2727 if ((dir == ELM_FOCUS_UP)
2728 || (dir == ELM_FOCUS_DOWN)
2729 || (dir == ELM_FOCUS_RIGHT)
2730 || (dir == ELM_FOCUS_LEFT))
2732 *next_item = elm_widget_focus_next_item_get(focused_object, dir);
2734 *next = elm_object_item_widget_get(*next_item);
2736 *next = elm_widget_focus_next_object_get(focused_object, dir);
2737 if (*next) return EINA_TRUE;
2740 Evas_Object *n = NULL;
2741 Elm_Object_Item *n_item = NULL;
2743 double weight = 0.0;
2745 if (dir == ELM_FOCUS_UP) degree = 0.0;
2746 else if (dir == ELM_FOCUS_DOWN) degree = 180.0;
2747 else if (dir == ELM_FOCUS_RIGHT) degree = 90.0;
2748 else if (dir == ELM_FOCUS_LEFT) degree = 270.0;
2750 if (elm_widget_focus_list_direction_get(obj, focused_object,
2751 items, list_data_get,
2752 degree, &n, &n_item,
2755 *next_item = n_item;
2764 if (dir == ELM_FOCUS_PREVIOUS)
2766 items = eina_list_last(items);
2767 list_next = eina_list_prev;
2769 else if ((dir == ELM_FOCUS_NEXT)
2770 || (dir == ELM_FOCUS_UP)
2771 || (dir == ELM_FOCUS_DOWN)
2772 || (dir == ELM_FOCUS_RIGHT)
2773 || (dir == ELM_FOCUS_LEFT))
2774 list_next = eina_list_next;
2778 const Eina_List *l = items;
2780 /* Recovery last focused sub item */
2781 if (ELM_WIDGET_FOCUS_GET(obj))
2783 for (; l; l = list_next(l))
2785 Evas_Object *cur = list_data_get(l);
2786 if (ELM_WIDGET_FOCUS_GET(cur)) break;
2789 /* Focused object, but no focused sub item */
2793 const Eina_List *start = l;
2794 Evas_Object *to_focus = NULL;
2795 Elm_Object_Item *to_focus_item = NULL;
2797 /* Iterate sub items */
2798 /* Go to the end of list */
2799 for (; l; l = list_next(l))
2801 Evas_Object *tmp = NULL;
2802 Elm_Object_Item *tmp_item = NULL;
2803 Evas_Object *cur = list_data_get(l);
2806 if (!_elm_widget_is(cur)) continue;
2807 if (elm_widget_parent_get(cur) != obj)
2810 /* Try Focus cycle in subitem */
2811 if (elm_widget_focus_next_get(cur, dir, &tmp, &tmp_item))
2814 *next_item = tmp_item;
2817 else if ((dir == ELM_FOCUS_UP)
2818 || (dir == ELM_FOCUS_DOWN)
2819 || (dir == ELM_FOCUS_RIGHT)
2820 || (dir == ELM_FOCUS_LEFT))
2822 if (tmp && _is_focused(cur))
2825 *next_item = tmp_item;
2829 else if ((tmp) && (!to_focus))
2832 to_focus_item = tmp_item;
2838 /* Get First possible */
2839 for (; l != start; l = list_next(l))
2841 Evas_Object *tmp = NULL;
2842 Elm_Object_Item *tmp_item = NULL;
2843 Evas_Object *cur = list_data_get(l);
2845 if (elm_widget_parent_get(cur) != obj)
2848 /* Try Focus cycle in subitem */
2849 elm_widget_focus_next_get(cur, dir, &tmp, &tmp_item);
2853 *next_item = tmp_item;
2859 *next_item = to_focus_item;
2866 * Get next object which was set with specific focus direction.
2868 * Get next object which was set by elm_widget_focus_next_object_set
2869 * with specific focus directioin.
2871 * @param obj The widget
2872 * @param dir Direction of focus
2873 * @return Widget which was registered with sepecific focus direction.
2877 EOLIAN static Evas_Object*
2878 _elm_widget_focus_next_object_get(const Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd, Elm_Focus_Direction dir)
2880 Evas_Object *ret = NULL;
2882 if (dir == ELM_FOCUS_PREVIOUS)
2883 ret = sd->focus_previous;
2884 else if (dir == ELM_FOCUS_NEXT)
2885 ret = sd->focus_next;
2886 else if (dir == ELM_FOCUS_UP)
2888 else if (dir == ELM_FOCUS_DOWN)
2889 ret = sd->focus_down;
2890 else if (dir == ELM_FOCUS_RIGHT)
2891 ret = sd->focus_right;
2892 else if (dir == ELM_FOCUS_LEFT)
2893 ret = sd->focus_left;
2901 * Set next object with specific focus direction.
2903 * When a widget is set with specific focus direction, this widget will be
2904 * the first candidate when finding the next focus object.
2905 * Focus next object can be registered with six directions that are previous,
2906 * next, up, down, right, and left.
2908 * @param obj The widget
2909 * @param next Next focus object
2910 * @param dir Direction of focus
2915 _elm_widget_focus_next_object_set(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd, Evas_Object *next, Elm_Focus_Direction dir)
2918 if (dir == ELM_FOCUS_PREVIOUS)
2919 sd->focus_previous = next;
2920 else if (dir == ELM_FOCUS_NEXT)
2921 sd->focus_next = next;
2922 else if (dir == ELM_FOCUS_UP)
2923 sd->focus_up = next;
2924 else if (dir == ELM_FOCUS_DOWN)
2925 sd->focus_down = next;
2926 else if (dir == ELM_FOCUS_RIGHT)
2927 sd->focus_right = next;
2928 else if (dir == ELM_FOCUS_LEFT)
2929 sd->focus_left = next;
2932 EOLIAN static Elm_Object_Item*
2933 _elm_widget_focus_next_item_get(const Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd, Elm_Focus_Direction dir)
2935 Elm_Object_Item *ret = NULL;
2937 if (dir == ELM_FOCUS_PREVIOUS)
2938 ret = sd->item_focus_previous;
2939 else if (dir == ELM_FOCUS_NEXT)
2940 ret = sd->item_focus_next;
2941 else if (dir == ELM_FOCUS_UP)
2942 ret = sd->item_focus_up;
2943 else if (dir == ELM_FOCUS_DOWN)
2944 ret = sd->item_focus_down;
2945 else if (dir == ELM_FOCUS_RIGHT)
2946 ret = sd->item_focus_right;
2947 else if (dir == ELM_FOCUS_LEFT)
2948 ret = sd->item_focus_left;
2954 _elm_widget_focus_next_item_set(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd, Elm_Object_Item *next_item, Elm_Focus_Direction dir)
2956 if (dir == ELM_FOCUS_PREVIOUS)
2957 sd->item_focus_previous = next_item;
2958 else if (dir == ELM_FOCUS_NEXT)
2959 sd->item_focus_next = next_item;
2960 else if (dir == ELM_FOCUS_UP)
2961 sd->item_focus_up = next_item;
2962 else if (dir == ELM_FOCUS_DOWN)
2963 sd->item_focus_down = next_item;
2964 else if (dir == ELM_FOCUS_RIGHT)
2965 sd->item_focus_right = next_item;
2966 else if (dir == ELM_FOCUS_LEFT)
2967 sd->item_focus_left = next_item;
2971 _elm_widget_parent_highlight_set(Eo *obj, Elm_Widget_Smart_Data *sd, Eina_Bool highlighted)
2973 highlighted = !!highlighted;
2975 Evas_Object *o = elm_widget_parent_get(obj);
2977 if (o) elm_widget_parent_highlight_set(o, highlighted);
2979 sd->highlighted = highlighted;
2983 _elm_widget_signal_emit(Eo *obj, Elm_Widget_Smart_Data *_pd EINA_UNUSED, const char *emission, const char *source)
2985 if (evas_object_smart_type_check(obj, "elm_layout"))
2986 elm_layout_signal_emit(obj, emission, source);
2987 else if (evas_object_smart_type_check(obj, "elm_icon"))
2989 WRN("Deprecated function. This functionality on icon objects"
2990 " will be dropped on a next release.");
2991 _elm_icon_signal_emit(obj, emission, source);
2996 _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)
2998 EINA_SAFETY_ON_NULL_RETURN(func);
3000 if (evas_object_smart_type_check(obj, "elm_layout"))
3001 elm_layout_signal_callback_add(obj, emission, source, func, data);
3002 else if (evas_object_smart_type_check(obj, "elm_icon"))
3004 WRN("Deprecated function. This functionality on icon objects"
3005 " will be dropped on a next release.");
3007 _elm_icon_signal_callback_add(obj, emission, source, func, data);
3012 _elm_widget_signal_callback_del(Eo *obj, Elm_Widget_Smart_Data *_pd EINA_UNUSED, const char *emission, const char *source, Edje_Signal_Cb func)
3016 if (evas_object_smart_type_check(obj, "elm_layout"))
3017 data = elm_layout_signal_callback_del(obj, emission, source, func);
3018 else if (evas_object_smart_type_check(obj, "elm_icon"))
3020 WRN("Deprecated function. This functionality on icon objects"
3021 " will be dropped on a next release.");
3023 data = _elm_icon_signal_callback_del(obj, emission, source, func);
3030 _elm_widget_focus_set(Eo *obj, Elm_Widget_Smart_Data *sd, Eina_Bool focus)
3035 sd->focus_order = focus_order;
3036 sd->focused = EINA_TRUE;
3037 eo_do(obj, elm_obj_widget_on_focus(NULL));
3042 if ((_is_focusable(sd->resize_obj)) &&
3043 (!elm_widget_disabled_get(sd->resize_obj)))
3045 elm_widget_focus_set(sd->resize_obj, focus);
3052 EINA_LIST_FOREACH(sd->subobjs, l, child)
3054 if (!_elm_widget_is(child)) continue;
3055 if ((_is_focusable(child)) &&
3056 (!elm_widget_disabled_get(child)))
3058 elm_widget_focus_set(child, focus);
3069 EINA_LIST_REVERSE_FOREACH(sd->subobjs, l, child)
3071 if (!_elm_widget_is(child)) continue;
3072 if ((_is_focusable(child)) &&
3073 (!elm_widget_disabled_get(child)))
3075 elm_widget_focus_set(child, focus);
3082 EOLIAN static Evas_Object*
3083 _elm_widget_parent_get(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd)
3085 return sd->parent_obj;
3089 _elm_widget_focused_object_clear(Eo *obj, Elm_Widget_Smart_Data *sd)
3091 if (!sd->focused) return;
3092 if (sd->resize_obj && elm_widget_is(sd->resize_obj) &&
3093 _is_focused(sd->resize_obj))
3095 eo_do(sd->resize_obj, elm_obj_widget_focused_object_clear());
3101 EINA_LIST_FOREACH(sd->subobjs, l, child)
3103 if (_elm_widget_is(child) && _is_focused(child))
3105 eo_do(child, elm_obj_widget_focused_object_clear());
3110 sd->focused = EINA_FALSE;
3111 if (sd->top_win_focused)
3112 eo_do(obj, elm_obj_widget_on_focus(NULL));
3116 _elm_widget_focus_steal(Eo *obj, Elm_Widget_Smart_Data *sd, Elm_Object_Item *item)
3118 Evas_Object *parent, *parent2, *o;
3120 if (sd->focused) return;
3121 if (sd->disabled) return;
3122 if (!sd->can_focus) return;
3123 if (sd->tree_unfocusable) return;
3127 o = elm_widget_parent_get(parent);
3129 sd = eo_data_scope_get(o, MY_CLASS);
3130 if (sd->disabled || sd->tree_unfocusable) return;
3131 if (sd->focused) break;
3134 if ((!elm_widget_parent_get(parent)) &&
3135 (!elm_widget_parent2_get(parent)))
3136 eo_do(parent, elm_obj_widget_focused_object_clear());
3139 parent2 = elm_widget_parent_get(parent);
3140 if (!parent2) parent2 = elm_widget_parent2_get(parent);
3142 sd = eo_data_scope_get(parent, MY_CLASS);
3145 if (sd->resize_obj && elm_widget_is(sd->resize_obj) &&
3146 _is_focused(sd->resize_obj))
3148 eo_do(sd->resize_obj, elm_obj_widget_focused_object_clear());
3154 EINA_LIST_FOREACH(sd->subobjs, l, child)
3156 if (_elm_widget_is(child) && _is_focused(child))
3158 eo_do(child, elm_obj_widget_focused_object_clear());
3165 /* TIZEN_ONLY(20161212): Some winsets should know whether it's focus target or not in _on_focus */
3166 sd = eo_data_scope_get(obj, MY_CLASS);
3167 sd->is_focus_target = EINA_TRUE;
3169 _parent_focus(obj, item);
3170 /* TIZEN_ONLY(20161212): Some winsets should know whether it's focus target or not in _on_focus */
3171 sd->is_focus_target = EINA_FALSE;
3173 elm_widget_focus_region_show(obj);
3178 _parents_on_focus(Evas_Object *obj)
3181 if (!sd->focused || !sd->top_win_focused) return;
3183 Evas_Object *o = elm_widget_parent_get(obj);
3184 if (o) _parents_on_focus(o);
3185 eo_do(obj, elm_obj_widget_on_focus(NULL));
3189 _elm_widget_focus_restore(Eo *obj, Elm_Widget_Smart_Data *_pd EINA_UNUSED)
3191 Evas_Object *newest = NULL;
3192 unsigned int newest_focus_order = 0;
3194 newest = elm_widget_newest_focus_order_get(obj, &newest_focus_order, EINA_TRUE);
3196 _parents_on_focus(newest);
3200 _elm_widget_focus_auto_show(Evas_Object *obj)
3202 Evas_Object *top = elm_widget_top_get(obj);
3203 if (top && eo_isa(top, ELM_WIN_CLASS)) _elm_win_focus_auto_show(top);
3207 _elm_widget_top_win_focused_set(Evas_Object *obj,
3208 Eina_Bool top_win_focused)
3214 if (sd->top_win_focused == top_win_focused) return;
3215 EINA_LIST_FOREACH(sd->subobjs, l, child)
3217 if (elm_widget_is(child))
3218 _elm_widget_top_win_focused_set(child, top_win_focused);
3220 sd->top_win_focused = top_win_focused;
3222 if (sd->focused && !sd->top_win_focused)
3223 eo_do(obj, elm_obj_widget_on_focus(NULL));
3227 _elm_widget_top_win_focused_get(const Evas_Object *obj)
3229 API_ENTRY return EINA_FALSE;
3230 return sd->top_win_focused;
3234 _elm_widget_disabled_eval(const Evas_Object *obj, Eina_Bool disabled)
3238 ELM_WIDGET_DATA_GET(obj, sd);
3242 EINA_LIST_FOREACH(sd->subobjs, l, child)
3244 if (elm_widget_is(child))
3246 elm_widget_focus_disabled_handle(child);
3247 eo_do(child, elm_obj_widget_disable());
3248 _elm_widget_disabled_eval(child, EINA_TRUE);
3254 EINA_LIST_FOREACH(sd->subobjs, l, child)
3256 ELM_WIDGET_DATA_GET(child, sdc);
3257 if (elm_widget_is(child) && !sdc->disabled)
3259 elm_widget_focus_disabled_handle(child);
3260 eo_do(child, elm_obj_widget_disable());
3261 _elm_widget_disabled_eval(child, EINA_FALSE);
3268 elm_widget_disabled_internal(Eo *obj, Eina_Bool disabled)
3270 Eina_Bool parent_state = EINA_FALSE;
3274 elm_widget_focus_disabled_handle(obj);
3275 eo_do(obj, elm_obj_widget_disable());
3276 _elm_widget_disabled_eval(obj, EINA_TRUE);
3280 parent_state = elm_widget_disabled_get(elm_widget_parent_get(obj));
3281 if (parent_state) return;
3282 elm_widget_focus_disabled_handle(obj);
3283 eo_do(obj, elm_obj_widget_disable());
3284 _elm_widget_disabled_eval(obj, EINA_FALSE);
3289 _elm_widget_disabled_set(Eo *obj, Elm_Widget_Smart_Data *sd, Eina_Bool disabled)
3291 if (sd->disabled == disabled) return;
3292 sd->disabled = !!disabled;
3294 elm_widget_disabled_internal(obj, disabled);
3297 EOLIAN static Eina_Bool
3298 _elm_widget_disabled_get(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd)
3300 Eina_Bool disabled = EINA_FALSE;
3302 if (sd->disabled) disabled = EINA_TRUE;
3303 else disabled = elm_widget_disabled_get(elm_widget_parent_get(obj));
3308 _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)
3311 Evas_Object *parent_obj, *child_obj;
3312 Evas_Coord px, py, cx, cy, nx = 0, ny = 0;
3315 /* TIZEN_ONLY(20161222): Update show region geometry when entry is resized
3316 Move this code to the blow to update show region geometry properly.
3317 evas_smart_objects_calculate(evas_object_evas_get(obj));
3320 if (!forceshow && (x == sd->rx) && (y == sd->ry) &&
3321 (w == sd->rw) && (h == sd->rh)) return;
3328 /* TIZEN_ONLY(20161222): Update show region geometry when entry is resized */
3329 /* Block nested call for evas_smart_objects_calculate() and region showing works */
3330 if (sd->on_show_region_set) return;
3332 sd->on_show_region_set = EINA_TRUE;
3334 evas_smart_objects_calculate(evas_object_evas_get(obj));
3336 sd->on_show_region_set = EINA_FALSE;
3338 /* show_region geometry could be changed during processing elm_widget_show_region_set().
3339 evas_smart_objects_calculate() can trigger nested show_region_set calls */
3346 if (sd->on_show_region)
3349 (sd->on_show_region_data, obj);
3351 if (_elm_scrollable_is(obj))
3353 eo_do(obj, elm_interface_scrollable_content_pos_get(&nx, &ny));
3361 parent_obj = sd->parent_obj;
3362 child_obj = sd->obj;
3363 if ((!parent_obj) || (!_elm_widget_is(parent_obj))) break;
3364 sd = eo_data_scope_get(parent_obj, MY_CLASS);
3367 evas_object_geometry_get(parent_obj, &px, &py, NULL, NULL);
3368 evas_object_geometry_get(child_obj, &cx, &cy, NULL, NULL);
3377 if (sd->on_show_region)
3380 (sd->on_show_region_data, parent_obj);
3387 _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)
3398 * Get the focus region of the given widget.
3400 * @return show region or not
3401 * (@c EINA_TRUE = show region/@c EINA_FALSE = do not show region). Default is @c EINA_FALSE.
3403 * The focus region is the area of a widget that should brought into the
3404 * visible area when the widget is focused. Mostly used to show the part of
3405 * an entry where the cursor is, for example. The area returned is relative
3406 * to the object @p obj.
3408 * @param obj The widget object
3409 * @param x Where to store the x coordinate of the area
3410 * @param y Where to store the y coordinate of the area
3411 * @param w Where to store the width of the area
3412 * @param h Where to store the height of the area
3416 EOLIAN static Eina_Bool
3417 _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)
3419 Eina_Bool int_ret = EINA_FALSE;
3420 eo_do((Eo *)obj, int_ret = elm_obj_widget_on_focus_region(x, y, w, h));
3423 evas_object_geometry_get(obj, NULL, NULL, w, h);
3427 if ((*w <= 0) || (*h <= 0)) return EINA_FALSE;
3432 _elm_widget_parents_bounce_get(Eo *obj, Elm_Widget_Smart_Data *_pd EINA_UNUSED, Eina_Bool *horiz, Eina_Bool *vert)
3434 Evas_Object *parent_obj = obj;
3435 Eina_Bool h = EINA_FALSE, v = EINA_FALSE;
3437 *horiz = EINA_FALSE;
3442 parent_obj = elm_widget_parent_get(parent_obj);
3443 if ((!parent_obj) || (!_elm_widget_is(parent_obj))) break;
3445 if (_elm_scrollable_is(parent_obj))
3447 eo_do(parent_obj, elm_interface_scrollable_bounce_allow_get(&h, &v));
3448 if (h) *horiz = EINA_TRUE;
3449 if (v) *vert = EINA_TRUE;
3455 EOLIAN static Eina_List*
3456 _elm_widget_scrollable_children_get(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd)
3465 EINA_LIST_FOREACH(sd->subobjs, l, child)
3467 if (elm_widget_is(child) && _elm_scrollable_is(child))
3468 ret = eina_list_append(ret, child);
3475 _elm_widget_scroll_hold_push(Eo *obj, Elm_Widget_Smart_Data *sd)
3478 if (sd->scroll_hold == 1)
3480 if (_elm_scrollable_is(obj))
3481 eo_do(obj, elm_interface_scrollable_hold_set(EINA_TRUE));
3484 Eina_List *scr_children, *l;
3487 scr_children = elm_widget_scrollable_children_get(obj);
3488 EINA_LIST_FOREACH(scr_children, l, child)
3490 eo_do(child, elm_interface_scrollable_hold_set(EINA_TRUE));
3492 eina_list_free(scr_children);
3495 if (sd->parent_obj) eo_do(sd->parent_obj, elm_obj_widget_scroll_hold_push());
3496 // FIXME: on delete/reparent hold pop
3500 _elm_widget_scroll_hold_pop(Eo *obj, Elm_Widget_Smart_Data *sd)
3503 if (!sd->scroll_hold)
3505 if (_elm_scrollable_is(obj))
3506 eo_do(obj, elm_interface_scrollable_hold_set(EINA_FALSE));
3509 Eina_List *scr_children, *l;
3512 scr_children = elm_widget_scrollable_children_get(obj);
3513 EINA_LIST_FOREACH(scr_children, l, child)
3515 eo_do(child, elm_interface_scrollable_hold_set(EINA_FALSE));
3517 eina_list_free(scr_children);
3520 if (sd->parent_obj) eo_do(sd->parent_obj, elm_obj_widget_scroll_hold_pop());
3521 if (sd->scroll_hold < 0) sd->scroll_hold = 0;
3525 _elm_widget_scroll_hold_get(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd)
3527 return sd->scroll_hold;
3531 _elm_widget_scroll_freeze_push(Eo *obj, Elm_Widget_Smart_Data *sd)
3533 sd->scroll_freeze++;
3534 if (sd->scroll_freeze == 1)
3536 if (_elm_scrollable_is(obj))
3537 eo_do(obj, elm_interface_scrollable_freeze_set(EINA_TRUE));
3540 Eina_List *scr_children, *l;
3543 scr_children = elm_widget_scrollable_children_get(obj);
3544 EINA_LIST_FOREACH(scr_children, l, child)
3546 eo_do(child, elm_interface_scrollable_freeze_set(EINA_TRUE));
3548 eina_list_free(scr_children);
3551 if (sd->parent_obj) eo_do(sd->parent_obj, elm_obj_widget_scroll_freeze_push());
3552 // FIXME: on delete/reparent freeze pop
3556 _elm_widget_scroll_freeze_pop(Eo *obj, Elm_Widget_Smart_Data *sd)
3558 sd->scroll_freeze--;
3559 if (!sd->scroll_freeze)
3561 if (_elm_scrollable_is(obj))
3562 eo_do(obj, elm_interface_scrollable_freeze_set(EINA_FALSE));
3565 Eina_List *scr_children, *l;
3568 scr_children = elm_widget_scrollable_children_get(obj);
3569 EINA_LIST_FOREACH(scr_children, l, child)
3571 eo_do(child, elm_interface_scrollable_freeze_set(EINA_FALSE));
3573 eina_list_free(scr_children);
3576 if (sd->parent_obj) eo_do(sd->parent_obj, elm_obj_widget_scroll_freeze_pop());
3577 if (sd->scroll_freeze < 0) sd->scroll_freeze = 0;
3581 _elm_widget_scroll_freeze_get(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd)
3583 return sd->scroll_freeze;
3586 // TIZEN_ONLY(20150705): Genlist item align feature
3588 elm_widget_scroll_item_align_enabled_set(Evas_Object *obj,
3589 Eina_Bool scroll_item_align_enable)
3592 if (sd->scroll_item_align_enable == scroll_item_align_enable) return;
3593 sd->scroll_item_align_enable = scroll_item_align_enable;
3597 elm_widget_scroll_item_align_enabled_get(const Evas_Object *obj)
3599 API_ENTRY return EINA_FALSE;
3600 return sd->scroll_item_align_enable;
3604 elm_widget_scroll_item_valign_set(Evas_Object *obj,
3605 const char *scroll_item_valign)
3608 if (sd->scroll_item_valign) eina_stringshare_del(sd->scroll_item_valign);
3609 if (!scroll_item_valign) sd->scroll_item_valign = NULL;
3610 else sd->scroll_item_valign = eina_stringshare_add(scroll_item_valign);
3614 elm_widget_scroll_item_valign_get(const Evas_Object *obj)
3616 API_ENTRY return NULL;
3617 return sd->scroll_item_valign;
3622 _elm_widget_scale_set(Eo *obj, Elm_Widget_Smart_Data *sd, double scale)
3624 if (scale < 0.0) scale = 0.0;
3625 if (sd->scale != scale)
3628 elm_widget_theme(obj);
3632 EOLIAN static double
3633 _elm_widget_scale_get(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd)
3635 // FIXME: save walking up the tree by storing/caching parent scale
3636 if (sd->scale == 0.0)
3638 if (sd->parent_obj && elm_widget_is(sd->parent_obj))
3640 return elm_widget_scale_get(sd->parent_obj);
3651 _elm_widget_theme_set(Eo *obj, Elm_Widget_Smart_Data *sd, Elm_Theme *th)
3653 Eina_Bool apply = EINA_FALSE;
3654 if (sd->theme != th)
3656 if (elm_widget_theme_get(obj) != th) apply = EINA_TRUE;
3657 if (sd->theme) elm_theme_free(sd->theme);
3660 if (apply) elm_widget_theme(obj);
3665 _elm_widget_part_text_set(Eo *obj, Elm_Widget_Smart_Data *_pd EINA_UNUSED, const char *part, const char *label)
3667 if (evas_object_smart_type_check(obj, "elm_layout"))
3668 elm_layout_text_set(obj, part, label);
3671 EOLIAN static const char*
3672 _elm_widget_part_text_get(Eo *obj, Elm_Widget_Smart_Data *_pd EINA_UNUSED, const char *part)
3674 if (evas_object_smart_type_check(obj, "elm_layout"))
3675 return elm_layout_text_get(obj, part);
3680 static Elm_Translate_String_Data *
3681 _translate_string_data_get(Eina_Inlist *translate_strings, const char *part)
3683 Elm_Translate_String_Data *ts;
3684 Eina_Stringshare *str;
3686 if (!translate_strings) return NULL;
3688 str = eina_stringshare_add(part);
3689 EINA_INLIST_FOREACH(translate_strings, ts)
3691 if (ts->id == str) break;
3694 eina_stringshare_del(str);
3699 static Elm_Translate_String_Data *
3700 _part_text_translatable_set(Eina_Inlist **translate_strings, const char *part, Eina_Bool translatable, Eina_Bool preset)
3703 Elm_Translate_String_Data *ts;
3704 t = *translate_strings;
3705 ts = _translate_string_data_get(t, part);
3711 ts = ELM_NEW(Elm_Translate_String_Data);
3712 if (!ts) return NULL;
3714 ts->id = eina_stringshare_add(part);
3715 t = eina_inlist_append(t, (Eina_Inlist*) ts);
3717 if (preset) ts->preset = EINA_TRUE;
3719 //Delete this exist one if this part has been not preset.
3720 //see elm_widget_part_text_translatable_set()
3721 else if (ts && ((preset) || (!ts->preset)))
3723 t = eina_inlist_remove(t, EINA_INLIST_GET(ts));
3724 eina_stringshare_del(ts->id);
3725 eina_stringshare_del(ts->domain);
3726 eina_stringshare_del(ts->string);
3727 ELM_SAFE_FREE(ts, free);
3730 *translate_strings = t;
3736 _elm_widget_domain_translatable_part_text_set(Eo *obj, Elm_Widget_Smart_Data *sd, const char *part, const char *domain, const char *label)
3739 Elm_Translate_String_Data *ts;
3743 _part_text_translatable_set(&sd->translate_strings, part, EINA_FALSE,
3748 ts = _part_text_translatable_set(&sd->translate_strings, part,
3749 EINA_TRUE, EINA_FALSE);
3751 if (!ts->string) ts->string = eina_stringshare_add(label);
3752 else eina_stringshare_replace(&ts->string, label);
3753 if (!ts->domain) ts->domain = eina_stringshare_add(domain);
3754 else eina_stringshare_replace(&ts->domain, domain);
3756 if (label[0]) label = dgettext(domain, label);
3760 sd->on_translate = EINA_TRUE;
3761 eo_do(obj, elm_obj_widget_part_text_set(part, label));
3762 sd->on_translate = EINA_FALSE;
3765 EOLIAN static const char*
3766 _elm_widget_translatable_part_text_get(const Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd, const char *part)
3768 Elm_Translate_String_Data *ts;
3770 ts = _translate_string_data_get(sd->translate_strings, part);
3771 if (ts) return ts->string;
3776 _elm_widget_domain_part_text_translatable_set(Eo *obj, Elm_Widget_Smart_Data *sd, const char *part, const char *domain, Eina_Bool translatable)
3778 Elm_Translate_String_Data *ts;
3779 const char *text = NULL;
3781 ts = _part_text_translatable_set(&sd->translate_strings, part,
3782 translatable, EINA_TRUE);
3784 if (!ts->domain) ts->domain = eina_stringshare_add(domain);
3785 else eina_stringshare_replace(&ts->domain, domain);
3787 eo_do(obj, text = elm_obj_widget_part_text_get(part));
3788 if (!text || !text[0]) return;
3790 if (!ts->string) ts->string = eina_stringshare_add(text);
3792 //Try to translate text since we don't know the text is already translated.
3794 text = dgettext(domain, text);
3796 sd->on_translate = EINA_TRUE;
3797 eo_do(obj, elm_obj_widget_part_text_set(part, text));
3798 sd->on_translate = EINA_FALSE;
3802 elm_widget_translate(Evas_Object *obj)
3804 ELM_WIDGET_CHECK(obj);
3805 eo_do(obj, elm_obj_widget_translate());
3809 _part_text_translate(Eina_Inlist *translate_strings,
3813 Elm_Translate_String_Data *ts;
3814 ts = _translate_string_data_get(translate_strings, part);
3815 if (!ts) return text;
3817 if (!ts->string) ts->string = eina_stringshare_add(text);
3818 else eina_stringshare_replace(&ts->string, text);
3820 if (text && text[0])
3821 text = dgettext(ts->domain, text);
3826 EOLIAN static const char*
3827 _elm_widget_part_text_translate(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd, const char *part, const char *text)
3831 if (!sd->translate_strings || sd->on_translate) return text;
3832 return _part_text_translate(sd->translate_strings, part, text);
3835 EOLIAN static Eina_Bool
3836 _elm_widget_translate(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *_pd EINA_UNUSED)
3840 API_ENTRY return EINA_FALSE;
3842 EINA_LIST_FOREACH(sd->subobjs, l, child)
3844 if (elm_widget_is(child))
3845 elm_widget_translate(child);
3848 if (sd->hover_obj) elm_widget_translate(sd->hover_obj);
3851 Elm_Translate_String_Data *ts;
3852 EINA_INLIST_FOREACH(sd->translate_strings, ts)
3854 if (!ts->string) continue;
3855 const char *s = dgettext(ts->domain, ts->string);
3856 sd->on_translate = EINA_TRUE;
3857 eo_do(obj, elm_obj_widget_part_text_set(ts->id, s));
3858 sd->on_translate = EINA_FALSE;
3861 eo_do(obj, eo_event_callback_call(ELM_WIDGET_EVENT_LANGUAGE_CHANGED, NULL));
3868 * Resets the focus_move_policy mode from the system one
3869 * for widgets that are in automatic mode.
3871 * @param obj The widget.
3875 _elm_widget_focus_move_policy_reload(Evas_Object *obj)
3878 Elm_Focus_Move_Policy focus_move_policy = elm_config_focus_move_policy_get();
3880 if (elm_widget_focus_move_policy_automatic_get(obj) &&
3881 (sd->focus_move_policy != focus_move_policy))
3883 sd->focus_move_policy = focus_move_policy;
3888 _elm_widget_focus_reconfigure(Eo *obj, Elm_Widget_Smart_Data *_pd EINA_UNUSED)
3894 EINA_LIST_FOREACH(sd->subobjs, l, child)
3896 if (elm_widget_is(child))
3897 elm_widget_focus_reconfigure(child);
3900 if (sd->hover_obj) elm_widget_focus_reconfigure(sd->hover_obj);
3902 _elm_widget_focus_move_policy_reload(obj);
3905 //TIZEN_ONLY(20160726): add API elm_object_part_access_object_get
3906 EOLIAN static Evas_Object*
3907 _elm_widget_part_access_object_get(const Eo *obj, Elm_Widget_Smart_Data *_pd EINA_UNUSED, const char *part EINA_UNUSED)
3909 WRN("The %s widget does not implement the \"part_access_object_get\" functions.",
3910 eo_class_name_get(eo_class_get(obj)));
3916 elm_widget_content_part_set(Evas_Object *obj,
3918 Evas_Object *content)
3920 ELM_WIDGET_CHECK(obj);
3921 eo_do(obj, elm_obj_container_content_set(part, content));
3925 * Returns the widget's focus_move_policy mode setting.
3927 * @param obj The widget.
3928 * @return focus_move_policy mode setting of the object.
3931 EOLIAN static Eina_Bool
3932 _elm_widget_focus_move_policy_automatic_get(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd)
3934 return sd->focus_move_policy_auto_mode;
3940 * Sets the widget's focus_move_policy mode setting.
3941 * When widget in automatic mode, it follows the system focus_move_policy mode set by
3942 * elm_config_focus_move_policy_set().
3943 * @param obj The widget.
3944 * @param automatic EINA_TRUE for auto focus_move_policy mode. EINA_FALSE for manual.
3947 _elm_widget_focus_move_policy_automatic_set(Eo *obj, Elm_Widget_Smart_Data *sd, Eina_Bool automatic)
3949 if (sd->focus_move_policy_auto_mode != automatic)
3951 sd->focus_move_policy_auto_mode = automatic;
3955 elm_widget_focus_move_policy_set(obj, elm_config_focus_move_policy_get());
3961 elm_widget_content_part_get(const Evas_Object *obj,
3964 ELM_WIDGET_CHECK(obj) NULL;
3965 Evas_Object *ret = NULL;
3966 eo_do((Eo *) obj, ret = elm_obj_container_content_get(part));
3971 elm_widget_content_part_unset(Evas_Object *obj,
3974 ELM_WIDGET_CHECK(obj) NULL;
3975 Evas_Object *ret = NULL;
3976 eo_do(obj, ret = elm_obj_container_content_unset(part));
3981 _elm_widget_access_info_set(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd, const char *txt)
3983 eina_stringshare_del(sd->access_info);
3984 if (!txt) sd->access_info = NULL;
3985 else sd->access_info = eina_stringshare_add(txt);
3988 EOLIAN static const char*
3989 _elm_widget_access_info_get(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd)
3991 return sd->access_info;
3994 EOLIAN static Elm_Theme*
3995 _elm_widget_theme_get(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd)
3999 if (sd->parent_obj && elm_widget_is(sd->parent_obj))
4000 return elm_widget_theme_get(sd->parent_obj);
4006 EOLIAN static Elm_Theme_Apply
4007 _elm_widget_style_set(Eo *obj, Elm_Widget_Smart_Data *sd, const char *style)
4009 if (eina_stringshare_replace(&sd->style, style))
4010 return elm_widget_theme(obj);
4012 return ELM_THEME_APPLY_SUCCESS;
4015 /* TIZEN_ONLY(20161223): add widget style set furnction for internal usage
4016 this function is same with elm_widget_style_set
4017 but it doesn't apply sub object's theme */
4019 _elm_widget_style_set_internal(Evas_Object *obj, const char *style)
4021 Elm_Theme_Apply ret = ELM_THEME_APPLY_SUCCESS;
4023 API_ENTRY return ELM_THEME_APPLY_FAILED;
4025 if (eina_stringshare_replace(&sd->style, style))
4031 if (sd->hover_obj) ret &= elm_widget_theme(sd->hover_obj);
4033 EINA_LIST_FOREACH(sd->tooltips, l, tt)
4034 elm_tooltip_theme(tt);
4035 EINA_LIST_FOREACH(sd->cursors, l, cur)
4036 elm_cursor_theme(cur);
4038 Elm_Theme_Apply ret2 = ELM_THEME_APPLY_FAILED;
4039 eo_do(obj, ret2 = elm_obj_widget_theme_apply());
4047 EOLIAN static const char*
4048 _elm_widget_style_get(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd)
4052 if (sd->style) ret = sd->style;
4058 _elm_widget_tooltip_add(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd, Elm_Tooltip *tt)
4060 sd->tooltips = eina_list_append(sd->tooltips, tt);
4064 _elm_widget_tooltip_del(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd, Elm_Tooltip *tt)
4066 sd->tooltips = eina_list_remove(sd->tooltips, tt);
4070 _elm_widget_cursor_add(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd, Elm_Cursor *cur)
4072 sd->cursors = eina_list_append(sd->cursors, cur);
4076 _elm_widget_cursor_del(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd, Elm_Cursor *cur)
4078 sd->cursors = eina_list_remove(sd->cursors, cur);
4082 _elm_widget_drag_lock_x_set(Eo *obj, Elm_Widget_Smart_Data *sd, Eina_Bool lock)
4084 if (sd->drag_x_locked == lock) return;
4085 sd->drag_x_locked = lock;
4086 if (sd->drag_x_locked) _propagate_x_drag_lock(obj, 1);
4087 else _propagate_x_drag_lock(obj, -1);
4091 _elm_widget_drag_lock_y_set(Eo *obj, Elm_Widget_Smart_Data *sd, Eina_Bool lock)
4093 if (sd->drag_y_locked == lock) return;
4094 sd->drag_y_locked = lock;
4095 if (sd->drag_y_locked) _propagate_y_drag_lock(obj, 1);
4096 else _propagate_y_drag_lock(obj, -1);
4099 EOLIAN static Eina_Bool
4100 _elm_widget_drag_lock_x_get(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd)
4102 return sd->drag_x_locked;
4105 EOLIAN static Eina_Bool
4106 _elm_widget_drag_lock_y_get(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd)
4108 return sd->drag_y_locked;
4112 _elm_widget_drag_child_locked_x_get(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd)
4114 return sd->child_drag_x_locked;
4118 _elm_widget_drag_child_locked_y_get(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd)
4120 return sd->child_drag_y_locked;
4124 _elm_widget_item_loop_enabled_set(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd EINA_UNUSED, Eina_Bool enable EINA_UNUSED)
4129 EOLIAN static Eina_Bool
4130 _elm_widget_item_loop_enabled_get(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd EINA_UNUSED)
4135 EOLIAN static Elm_Theme_Apply
4136 _elm_widget_theme_object_set(Eo *obj, Elm_Widget_Smart_Data *sd, Evas_Object *edj, const char *wname, const char *welement, const char *wstyle)
4138 Elm_Theme_Apply ret = _elm_theme_object_set(obj, edj, wname, welement, wstyle);
4141 return ELM_THEME_APPLY_FAILED;
4144 if (sd->orient_mode != -1)
4147 snprintf(buf, sizeof(buf), "elm,state,orient,%d", sd->orient_mode);
4148 eo_do(obj, elm_obj_widget_signal_emit(buf, "elm"));
4155 _elm_widget_eo_base_dbg_info_get(Eo *eo_obj, Elm_Widget_Smart_Data *_pd EINA_UNUSED, Eo_Dbg_Info *root)
4157 eo_do_super(eo_obj, MY_CLASS, eo_dbg_info_get(root));
4158 Eo_Dbg_Info *group = EO_DBG_INFO_LIST_APPEND(root, MY_CLASS_NAME);
4160 EO_DBG_INFO_APPEND(group, "Wid-Type", EINA_VALUE_TYPE_STRING, elm_widget_type_get(eo_obj));
4161 EO_DBG_INFO_APPEND(group, "Style", EINA_VALUE_TYPE_STRING, elm_widget_style_get(eo_obj));
4162 EO_DBG_INFO_APPEND(group, "Layer", EINA_VALUE_TYPE_INT,
4163 (int) evas_object_layer_get(eo_obj));
4164 EO_DBG_INFO_APPEND(group, "Scale", EINA_VALUE_TYPE_DOUBLE,
4165 evas_object_scale_get(eo_obj));
4166 EO_DBG_INFO_APPEND(group, "Has focus", EINA_VALUE_TYPE_CHAR,
4167 elm_object_focus_get(eo_obj));
4168 EO_DBG_INFO_APPEND(group, "Disabled", EINA_VALUE_TYPE_CHAR,
4169 elm_widget_disabled_get(eo_obj));
4170 EO_DBG_INFO_APPEND(group, "Mirrored", EINA_VALUE_TYPE_CHAR,
4171 elm_widget_mirrored_get(eo_obj));
4172 EO_DBG_INFO_APPEND(group, "Automatic mirroring", EINA_VALUE_TYPE_CHAR,
4173 elm_widget_mirrored_automatic_get(eo_obj));
4177 elm_widget_is_check(const Evas_Object *obj)
4179 static int abort_on_warn = -1;
4180 if (elm_widget_is(obj))
4183 ERR("Passing Object: %p.", obj);
4184 if (abort_on_warn == -1)
4186 if (getenv("ELM_ERROR_ABORT")) abort_on_warn = 1;
4187 else abort_on_warn = 0;
4189 if (abort_on_warn == 1) abort();
4194 elm_widget_type_get(const Evas_Object *obj)
4196 API_ENTRY return NULL;
4198 return eo_class_name_get(eo_class_get(obj));
4202 elm_widget_type_check(const Evas_Object *obj,
4206 const char *provided, *expected = "(unknown)";
4207 static int abort_on_warn = -1;
4209 provided = elm_widget_type_get(obj);
4210 /* TODO: eventually migrate to check_ptr version */
4211 if (evas_object_smart_type_check(obj, type)) return EINA_TRUE;
4212 if (type) expected = type;
4213 if ((!provided) || (!provided[0]))
4215 provided = evas_object_type_get(obj);
4216 if ((!provided) || (!provided[0]))
4217 provided = "(unknown)";
4219 ERR("Passing Object: %p in function: %s, of type: '%s' when expecting"
4220 " type: '%s'", obj, func, provided, expected);
4221 if (abort_on_warn == -1)
4223 if (getenv("ELM_ERROR_ABORT")) abort_on_warn = 1;
4224 else abort_on_warn = 0;
4226 if (abort_on_warn == 1) abort();
4230 static Evas_Object *
4231 _widget_name_find(const Evas_Object *obj,
4238 INTERNAL_ENTRY NULL;
4240 if (!_elm_widget_is(obj)) return NULL;
4241 EINA_LIST_FOREACH(sd->subobjs, l, child)
4243 s = evas_object_name_get(child);
4244 if ((s) && (!strcmp(s, name))) return child;
4245 if ((recurse != 0) &&
4246 ((child = _widget_name_find(child, name, recurse - 1))))
4251 s = evas_object_name_get(sd->hover_obj);
4252 if ((s) && (!strcmp(s, name))) return sd->hover_obj;
4253 if ((recurse != 0) &&
4254 ((child = _widget_name_find(sd->hover_obj, name, recurse - 1))))
4260 EOLIAN static Evas_Object*
4261 _elm_widget_name_find(const Eo *obj, Elm_Widget_Smart_Data *_pd EINA_UNUSED, const char *name, int recurse)
4263 if (!name) return NULL;
4264 return _widget_name_find(obj, name, recurse);
4270 * Split string in words
4272 * @param str Source string
4273 * @return List of const words
4275 * @see elm_widget_stringlist_free()
4279 elm_widget_stringlist_get(const char *str)
4281 Eina_List *list = NULL;
4283 if (!str) return NULL;
4284 for (b = s = str; 1; s++)
4286 if ((*s == ' ') || (!*s))
4288 char *t = malloc(s - b + 1);
4291 strncpy(t, b, s - b);
4293 list = eina_list_append(list, eina_stringshare_add(t));
4304 elm_widget_stringlist_free(Eina_List *list)
4307 EINA_LIST_FREE(list, s)
4308 eina_stringshare_del(s);
4312 _elm_widget_focus_hide_handle(Eo *obj, Elm_Widget_Smart_Data *_pd EINA_UNUSED)
4314 if (!_elm_widget_is(obj))
4316 _if_focused_revert(obj, EINA_TRUE);
4320 elm_widget_focus_mouse_up_handle(Evas_Object *obj)
4322 Evas_Object *o = obj;
4325 if (_elm_widget_is(o)) break;
4326 o = evas_object_smart_parent_get(o);
4330 eo_do(o, elm_obj_widget_focus_mouse_up_handle());
4334 _elm_widget_focus_mouse_up_handle(Eo *obj, Elm_Widget_Smart_Data *_pd EINA_UNUSED)
4337 if (!_is_focusable(obj)) return;
4339 elm_widget_focus_steal(obj, NULL);
4343 _elm_widget_focus_tree_unfocusable_handle(Eo *obj, Elm_Widget_Smart_Data *_pd EINA_UNUSED)
4345 if (!elm_widget_parent_get(obj))
4346 elm_widget_focused_object_clear(obj);
4348 _if_focused_revert(obj, EINA_TRUE);
4352 _elm_widget_focus_disabled_handle(Eo *obj, Elm_Widget_Smart_Data *_pd EINA_UNUSED)
4354 elm_widget_focus_tree_unfocusable_handle(obj);
4357 EOLIAN static unsigned int
4358 _elm_widget_focus_order_get(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd)
4360 return sd->focus_order;
4363 EOLIAN static Evas_Object*
4364 _elm_widget_newest_focus_order_get(const Eo *obj, Elm_Widget_Smart_Data *sd, unsigned int *newest_focus_order, Eina_Bool can_focus_only)
4367 Evas_Object *child, *cur, *best;
4369 if (!evas_object_visible_get(obj)
4370 || (elm_widget_disabled_get(obj))
4371 || (elm_widget_tree_unfocusable_get(obj)))
4375 if (*newest_focus_order < sd->focus_order)
4377 if (!can_focus_only || elm_widget_can_focus_get(obj))
4379 *newest_focus_order = sd->focus_order;
4380 best = (Evas_Object *)obj;
4383 EINA_LIST_FOREACH(sd->subobjs, l, child)
4385 if (!_elm_widget_is(child)) continue;
4387 cur = elm_widget_newest_focus_order_get
4388 (child, newest_focus_order, can_focus_only);
4398 * Get the focus highlight geometry of an widget.
4400 * @param obj Widget object for the focus highlight
4401 * @param x Focus highlight x coordinate
4402 * @param y Focus highlight y coordinate
4403 * @param w Focus highlight object width
4404 * @param h Focus highlight object height
4405 * @param is_next @c EINA_TRUE if this request is for the new focused object,
4406 * @c EINA_FALSE if this request is for the previously focused object. This
4407 * information becomes important when the focus highlight is changed inside one
4415 * Get the 'focus_part' geometry if there is any
4417 * This queries if there is a 'focus_part' request from the edc style. If edc
4418 * style offers 'focus_part' edje data item, this function requests for the
4419 * geometry of a specific part which is described in 'focus_part' edje data.
4421 * @param obj Widget object for the focus highlight
4422 * @param x Focus highlight x coordinate
4423 * @param y Focus highlight y coordinate
4424 * @param w Focus highlight object width
4425 * @param h Focus highlight object height
4427 * x, y, w, h already contain the object's geometry. If there is a 'focus_part'
4428 * support, these values will be updated accordingly or the values will be
4429 * remained as they were.
4434 elm_widget_focus_highlight_focus_part_geometry_get(const Evas_Object *obj,
4440 Evas_Coord tx = 0, ty = 0, tw = 0, th = 0;
4441 const char *target_hl_part = NULL;
4442 const Evas_Object *edje_obj = NULL;
4444 if (obj && eo_isa(obj, EDJE_OBJECT_CLASS))
4447 if (!(target_hl_part = edje_object_data_get(edje_obj, "focus_part")))
4450 else if (obj && eo_isa(obj, ELM_LAYOUT_CLASS))
4452 edje_obj = elm_layout_edje_get(obj);
4453 if (!(target_hl_part = elm_layout_data_get(obj, "focus_part")))
4459 edje_object_part_geometry_get(edje_obj, target_hl_part,
4460 &tx, &ty, &tw, &th);
4463 if (tw != *w) *w = tw;
4464 if (th != *h) *h = th;
4468 _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)
4470 Evas_Coord ox = 0, oy = 0, ow = 0, oh = 0;
4471 Evas_Object *scroller = (Evas_Object *)obj;
4473 evas_object_geometry_get(obj, x, y, w, h);
4474 elm_widget_focus_highlight_focus_part_geometry_get(sd->resize_obj, x, y, w, h);
4476 if (_elm_config->focus_autoscroll_mode != ELM_FOCUS_AUTOSCROLL_MODE_BRING_IN)
4481 if (_elm_scrollable_is(scroller))
4484 elm_interface_scrollable_content_viewport_geometry_get(&ox, &oy, &ow, &oh));
4488 else if ((oy + oh) < (*y + *h))
4489 *y = (oy + oh - *h);
4492 else if ((ox + ow) < (*x + *w))
4493 *x = (ox + ow - *w);
4497 scroller = elm_widget_parent_get(scroller);
4501 EOLIAN static Elm_Object_Item*
4502 _elm_widget_focused_item_get(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *_pd EINA_UNUSED)
4508 _elm_widget_focus_region_show_mode_set(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *_pd, Elm_Focus_Region_Show_Mode mode)
4510 _pd->focus_region_show_mode = mode;
4513 EOLIAN static Elm_Focus_Region_Show_Mode
4514 _elm_widget_focus_region_show_mode_get(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *_pd)
4516 return _pd->focus_region_show_mode;
4520 elm_widget_activate(Evas_Object *obj, Elm_Activate act)
4522 Evas_Object *parent;
4525 ELM_WIDGET_CHECK(obj);
4529 eo_do(obj, ret = elm_obj_widget_activate(act));
4533 parent = elm_widget_parent_get(obj);
4535 elm_widget_activate(parent, act);
4543 * Sets the widget and child widget's Evas_Display_Mode.
4545 * @param obj The widget.
4546 * @param dispmode Evas_Display_Mode to set widget's mode.
4548 * Widgets are resized by several reasons.
4549 * Evas_Display_Mode can help for widgets to get one more reason of resize.
4550 * For example, elm conform widget resizes it's contents when keypad state changed.
4551 * After keypad showing, conform widget can change child's Evas_Display_Mode.
4555 _elm_widget_display_mode_set(Eo *obj, Elm_Widget_Smart_Data *sd, Evas_Display_Mode dispmode)
4557 Evas_Display_Mode prev_dispmode;
4561 prev_dispmode = evas_object_size_hint_display_mode_get(obj);
4563 if ((prev_dispmode == dispmode) ||
4564 (prev_dispmode == EVAS_DISPLAY_MODE_DONT_CHANGE)) return;
4566 evas_object_size_hint_display_mode_set(obj, dispmode);
4568 EINA_LIST_FOREACH (sd->subobjs, l, child)
4570 if (elm_widget_is(child))
4571 elm_widget_display_mode_set(child, dispmode);
4576 _elm_widget_orientation_mode_disabled_set(Eo *obj, Elm_Widget_Smart_Data *sd, Eina_Bool disabled)
4578 int orient_mode = -1;
4582 //Get current orient mode from it's parent otherwise, 0.
4583 sd->orient_mode = 0;
4584 ELM_WIDGET_DATA_GET(sd->parent_obj, sd_parent);
4585 if (!sd_parent) orient_mode = 0;
4586 else orient_mode = sd_parent->orient_mode;
4588 eo_do(obj, elm_obj_widget_orientation_set(orient_mode));
4591 EOLIAN static Eina_Bool
4592 _elm_widget_orientation_mode_disabled_get(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd)
4594 if (sd->orient_mode == -1) return EINA_TRUE;
4595 else return EINA_FALSE;
4599 _elm_widget_orientation_set(Eo *obj, Elm_Widget_Smart_Data *sd, int orient_mode)
4604 sd->orient_mode = orient_mode;
4606 EINA_LIST_FOREACH (sd->subobjs, l, child)
4608 if (elm_widget_is(child))
4609 eo_do(child, elm_obj_widget_orientation_set(orient_mode));
4612 if (orient_mode != -1)
4615 snprintf(buf, sizeof(buf), "elm,state,orient,%d", orient_mode);
4616 eo_do(obj, elm_obj_widget_signal_emit(buf, "elm"));
4623 * Returns the widget's focus move policy.
4625 * @param obj The widget.
4626 * @return focus move policy of the object.
4629 EOLIAN static Elm_Focus_Move_Policy
4630 _elm_widget_focus_move_policy_get(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd)
4632 return sd->focus_move_policy;
4638 * Sets the widget's focus move policy.
4640 * @param obj The widget.
4641 * @param policy Elm_Focus_Move_Policy to set object's focus move policy.
4645 _elm_widget_focus_move_policy_set(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd, Elm_Focus_Move_Policy policy)
4647 if (sd->focus_move_policy == policy) return;
4648 sd->focus_move_policy = policy;
4651 _track_obj_del(void *data, Evas *e, Evas_Object *obj, void *event_info);
4654 _track_obj_update(Evas_Object *track, Evas_Object *obj)
4657 Evas_Coord x, y, w, h;
4658 evas_object_geometry_get(obj, &x, &y, &w, &h);
4659 evas_object_move(track, x, y);
4660 evas_object_resize(track, w, h);
4663 if (evas_object_visible_get(obj)) evas_object_show(track);
4664 else evas_object_hide(track);
4668 _track_obj_view_update(void *data, Eo *obj,
4669 const Eo_Event_Description *desc EINA_UNUSED,
4670 void *event_info EINA_UNUSED)
4672 Elm_Widget_Item_Data *item = data;
4673 _track_obj_update(item->track_obj, obj);
4674 return EO_CALLBACK_CONTINUE;
4678 _track_obj_view_del(void *data, Eo *obj EINA_UNUSED,
4679 const Eo_Event_Description *desc EINA_UNUSED,
4680 void *event_info EINA_UNUSED);
4682 EO_CALLBACKS_ARRAY_DEFINE(tracker_callbacks,
4683 { EVAS_OBJECT_EVENT_RESIZE, _track_obj_view_update },
4684 { EVAS_OBJECT_EVENT_MOVE, _track_obj_view_update },
4685 { EVAS_OBJECT_EVENT_SHOW, _track_obj_view_update },
4686 { EVAS_OBJECT_EVENT_HIDE, _track_obj_view_update },
4687 { EVAS_OBJECT_EVENT_DEL, _track_obj_view_del });
4690 _track_obj_view_del(void *data, Eo *obj EINA_UNUSED,
4691 const Eo_Event_Description *desc EINA_UNUSED,
4692 void *event_info EINA_UNUSED)
4694 Elm_Widget_Item_Data *item = data;
4696 while (evas_object_ref_get(item->track_obj) > 0)
4697 evas_object_unref(item->track_obj);
4699 evas_object_event_callback_del(item->track_obj, EVAS_CALLBACK_DEL,
4701 evas_object_del(item->track_obj);
4702 item->track_obj = NULL;
4704 return EO_CALLBACK_CONTINUE;
4708 _track_obj_del(void *data, Evas *e EINA_UNUSED,
4709 Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
4711 Elm_Widget_Item_Data *item = data;
4712 item->track_obj = NULL;
4714 if (!item->view) return;
4716 eo_do(item->view, eo_event_callback_array_del(tracker_callbacks(), item));
4720 _elm_widget_item_signal_cb(void *data, Evas_Object *obj EINA_UNUSED, const char *emission,
4723 Elm_Widget_Item_Signal_Data *wisd = data;
4724 wisd->func(wisd->data, wisd->item, emission, source);
4728 _elm_widget_item_signal_callback_list_get(Elm_Widget_Item_Data *item, Eina_List *position)
4730 Elm_Widget_Item_Signal_Data *wisd = eina_list_data_get(position);
4733 item->signals = eina_list_remove_list(item->signals, position);
4736 if (_elm_widget_is(item->view))
4737 elm_object_signal_callback_del(item->view,
4738 wisd->emission, wisd->source,
4739 _elm_widget_item_signal_cb);
4740 else if (eo_isa(item->view, EDJE_OBJECT_CLASS))
4741 edje_object_signal_callback_del_full(item->view,
4742 wisd->emission, wisd->source,
4743 _elm_widget_item_signal_cb, wisd);
4745 eina_stringshare_del(wisd->emission);
4746 eina_stringshare_del(wisd->source);
4752 #define ERR_NOT_SUPPORTED(item, method) ERR("%s does not support %s API.", elm_widget_type_get(item->widget), method);
4755 _eo_del_cb(void *data EINA_UNUSED, Eo *eo_item, const Eo_Event_Description *desc EINA_UNUSED, void *event_info EINA_UNUSED)
4757 Elm_Widget_Item_Data *item = eo_data_scope_get(eo_item, ELM_WIDGET_ITEM_CLASS);
4758 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item, EINA_TRUE);
4760 item->del_func((void *) WIDGET_ITEM_DATA_GET(eo_item), item->widget, item->eo_obj);
4767 * Allocate a new Elm_Widget_Item-derived structure.
4769 * The goal of this structure is to provide common ground for actions
4770 * that a widget item have, such as the owner widget, callback to
4771 * notify deletion, data pointer and maybe more.
4773 * @param widget the owner widget that holds this item, must be an elm_widget!
4774 * @param alloc_size any number greater than sizeof(Elm_Widget_Item) that will
4775 * be used to allocate memory.
4777 * @return allocated memory that is already zeroed out, or NULL on errors.
4779 * @see elm_widget_item_new() convenience macro.
4780 * @see elm_widget_item_del() to release memory.
4784 _elm_widget_item_eo_base_constructor(Eo *eo_item, Elm_Widget_Item_Data *item)
4786 Evas_Object *widget;
4787 eo_do (eo_item, widget = eo_parent_get());
4789 if (!_elm_widget_is(widget))
4795 eo_item = eo_do_super_ret(eo_item, ELM_WIDGET_ITEM_CLASS, eo_item, eo_constructor());
4797 EINA_MAGIC_SET(item, ELM_WIDGET_ITEM_MAGIC);
4799 item->widget = widget;
4800 item->eo_obj = eo_item;
4801 //TIZEN_ONLY(20170717) : expose highlight information on atspi
4802 item->can_highlight = EINA_TRUE;
4805 eo_do(eo_item, eo_event_callback_add(EO_BASE_EVENT_DEL, _eo_del_cb, NULL));
4811 _elm_widget_item_eo_base_destructor(Eo *eo_item, Elm_Widget_Item_Data *item)
4813 Elm_Translate_String_Data *ts;
4815 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
4817 evas_object_del(item->view);
4819 eina_stringshare_del(item->access_info);
4820 eina_stringshare_del(item->accessible_name);
4822 while (item->signals)
4823 _elm_widget_item_signal_callback_list_get(item, item->signals);
4825 while (item->translate_strings)
4827 ts = EINA_INLIST_CONTAINER_GET(item->translate_strings,
4828 Elm_Translate_String_Data);
4829 eina_stringshare_del(ts->id);
4830 eina_stringshare_del(ts->domain);
4831 eina_stringshare_del(ts->string);
4832 item->translate_strings = eina_inlist_remove(item->translate_strings,
4833 item->translate_strings);
4836 eina_hash_free(item->labels);
4839 elm_interface_atspi_accessible_description_set(NULL),
4840 elm_interface_atspi_accessible_name_set(NULL),
4841 //TIZEN_ONLY(20190922): add name callback, description callback.
4842 elm_interface_atspi_accessible_description_cb_set(NULL, NULL),
4843 elm_interface_atspi_accessible_name_cb_set(NULL, NULL),
4846 //TIZEN_ONLY(20170405) Add gesture method to accessible interface
4847 elm_interface_atspi_accessible_gesture_cb_set(NULL, NULL),
4849 elm_interface_atspi_accessible_translation_domain_set(NULL),
4850 elm_interface_atspi_accessible_relationships_clear(),
4851 // TIZEN_ONLY(20160930) : endless recursion fix
4852 elm_interface_atspi_accessible_attributes_clear()
4857 eina_stringshare_del(item->name);
4859 if (item->atspi_custom_relations)
4860 elm_atspi_relation_set_free(&item->atspi_custom_relations);
4862 //TIZEN_ONLY(20150731) : add i18n support for name and description
4863 if (item->atspi_translation_domain)
4864 eina_stringshare_del(item->atspi_translation_domain);
4866 //Tizen Only(20160728) free attribute list
4867 if (item->attr_list)
4869 Elm_Atspi_Attribute *attr;
4870 EINA_LIST_FREE(item->attr_list, attr)
4872 eina_stringshare_del(attr->key);
4873 eina_stringshare_del(attr->value);
4879 //TIZEN_ONLY(20161013): clean up elm color class feature
4880 if (item->color_classes)
4881 ELM_SAFE_FREE(item->color_classes, eina_hash_free);
4884 EINA_MAGIC_SET(item, EINA_MAGIC_NONE);
4886 eo_do_super(eo_item, ELM_WIDGET_ITEM_CLASS, eo_destructor());
4892 * Releases widget item memory, calling back item_del_pre_hook() and
4893 * item_del_cb() if they exist.
4895 * @param item a valid #Elm_Widget_Item to be deleted.
4897 * If there is an Elm_Widget_Item::del_cb, then it will be called prior
4898 * to memory release. Note that elm_widget_item_pre_notify_del() calls
4899 * this function and then unset it, thus being useful for 2 step
4900 * cleanup whenever the del_cb may use any of the data that must be
4901 * deleted from item.
4903 * The Elm_Widget_Item::view will be deleted (evas_object_del()) if it
4906 * Note that if item_del_pre_hook() returns @c EINA_TRUE, item free will be
4907 * deferred, or item will be freed here if it returns @c EINA_FALSE.
4909 * @see elm_widget_item_del() convenience macro.
4913 _elm_widget_item_del(Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item)
4915 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
4916 ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
4917 item->on_deletion = EINA_TRUE;
4919 //Widget item delete callback
4921 eo_do(item->eo_obj, del_ok = elm_wdg_item_del_pre());
4923 eo_del(item->eo_obj);
4927 EOLIAN static Eina_Bool
4928 _elm_widget_item_del_pre(Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item EINA_UNUSED)
4936 * Notify object will be deleted without actually deleting it.
4938 * This function will callback Elm_Widget_Item::del_cb if it is set
4939 * and then unset it so it is not called twice (ie: from
4940 * elm_widget_item_del()).
4942 * @param item a valid #Elm_Widget_Item to be notified
4943 * @see elm_widget_item_pre_notify_del() convenience macro.
4947 _elm_widget_item_pre_notify_del(Eo *eo_item, Elm_Widget_Item_Data *item)
4949 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
4950 if (!item->del_func) return;
4951 item->del_func((void *)WIDGET_ITEM_DATA_GET(eo_item), item->widget, item->eo_obj);
4952 item->del_func = NULL;
4958 * Set the function to notify when item is being deleted.
4960 * This function will complain if there was a callback set already,
4961 * however it will set the new one.
4963 * The callback will be called from elm_widget_item_pre_notify_del()
4964 * or elm_widget_item_del() will be called with:
4965 * - data: the Elm_Widget_Item::data value.
4966 * - obj: the Elm_Widget_Item::widget evas object.
4967 * - event_info: the item being deleted.
4969 * @param item a valid #Elm_Widget_Item to be notified
4970 * @see elm_widget_item_del_cb_set() convenience macro.
4974 _elm_widget_item_del_cb_set(Eo *eo_item EINA_UNUSED,
4975 Elm_Widget_Item_Data *item,
4978 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
4979 ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
4981 if ((item->del_func) && (item->del_func != func))
4982 WRN("You're replacing a previously set del_cb %p of item %p with %p",
4983 item->del_func, item->eo_obj, func);
4985 item->del_func = func;
4991 * Get owner widget of this item.
4993 * @param item a valid #Elm_Widget_Item to get data from.
4994 * @return owner widget of this item.
4997 EOLIAN static Evas_Object *
4998 _elm_widget_item_widget_get(const Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item)
5000 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item, NULL);
5001 ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item, NULL);
5003 return item->widget;
5007 _elm_widget_onscreen_is(Evas_Object *widget)
5009 Evas_Object *parent = widget;
5010 Evas_Coord x, y, w, h, wx, wy, ww, wh;
5012 Evas *evas = evas_object_evas_get(widget);
5013 if (!evas) return EINA_FALSE;
5015 // check if on canvas
5016 evas_output_viewport_get(evas, &x, &y, &w, &h);
5017 evas_object_geometry_get(widget, &wx, &wy, &ww, &wh);
5018 if (((wx < x) && (wx + ww < x)) || ((wx > x + w) && (wx + ww > x + w)) ||
5019 ((wy < y) && (wy + wh < y)) || ((wy > y+ h) && (wy + wh > y + h)))
5022 // check if inside scrollable parent viewport
5024 parent = elm_widget_parent_get(parent);
5025 if (parent && !evas_object_visible_get(parent))
5027 if (parent && eo_isa(parent, ELM_INTERFACE_SCROLLABLE_MIXIN))
5029 evas_object_geometry_get(parent, &x, &y, &w, &h);
5030 if (((wx < x) && (wx + ww < x)) || ((wx > x + w) && (wx + ww > x + w)) ||
5031 ((wy < y) && (wy + wh < y)) || ((wy > y+ h) && (wy + wh > y + h)))
5034 } while (parent && (parent != elm_widget_top_get(widget)));
5040 _elm_widget_item_onscreen_is(Elm_Object_Item *item)
5042 Evas_Coord x, y, w, h, wx, wy, ww, wh;
5043 Elm_Widget_Item_Data *id = eo_data_scope_get(item, ELM_WIDGET_ITEM_CLASS);
5044 if (!id || !id->view) return EINA_FALSE;
5046 if (!evas_object_visible_get(id->view))
5049 if (!_elm_widget_onscreen_is(id->widget))
5052 evas_object_geometry_get(id->view, &x, &y, &w, &h);
5053 evas_object_geometry_get(id->widget, &wx, &wy, &ww, &wh);
5054 if (((wx < x) && (wx + ww < x)) || ((wx > x + w) && (wx + ww > x + w)) ||
5055 ((wy < y) && (wy + wh < y)) || ((wy > y+ h) && (wy + wh > y + h)))
5062 _elm_widget_accessible_plain_name_get(Evas_Object *obj, const char* name)
5064 char *accessible_plain_name;
5066 API_ENTRY return NULL;
5068 accessible_plain_name = _elm_util_mkup_to_text(name);
5069 eina_stringshare_del(sd->accessible_name);
5070 sd->accessible_name = eina_stringshare_add(accessible_plain_name);
5071 free(accessible_plain_name);
5072 return sd->accessible_name;
5076 _elm_widget_item_accessible_plain_name_get(Elm_Object_Item *item, const char* name)
5078 char *accessible_plain_name;
5080 Elm_Widget_Item_Data *id = eo_data_scope_get(item, ELM_WIDGET_ITEM_CLASS);
5081 if (!id) return NULL;
5083 accessible_plain_name = _elm_util_mkup_to_text(name);
5084 eina_stringshare_del(id->accessible_name);
5085 id->accessible_name = eina_stringshare_add(accessible_plain_name);
5086 free(accessible_plain_name);
5087 return id->accessible_name;
5090 //TIZEN_ONLY(20160929) : atspi: Improves how to find the can_highlight of the widget
5092 _elm_widget_can_highlight_get_by_class(Eo *obj)
5094 if (eo_isa(obj, ELM_WIDGET_ITEM_CLASS))
5096 Elm_Widget_Item_Data *id = eo_data_scope_get(obj, ELM_WIDGET_ITEM_CLASS);
5097 if (!id) return EINA_FALSE;
5098 if (!id->can_highlight) return EINA_FALSE;
5102 Elm_Widget_Smart_Data *wd = eo_data_scope_get(obj, ELM_WIDGET_CLASS);
5103 if (!wd) return EINA_FALSE;
5104 if (!wd->can_highlight) return EINA_FALSE;
5110 //TIZEN_ONLY(20161107): enhance elm_atspi_accessible_can_highlight_set to set can_hihglight property to its children
5112 _elm_widget_item_highlightable(Elm_Object_Item *item)
5116 Elm_Widget_Item_Data *id = eo_data_scope_get(item, ELM_WIDGET_ITEM_CLASS);
5117 if (!id) return EINA_FALSE;
5118 if (!id->can_highlight) return EINA_FALSE;
5120 eo_do(item, parent = elm_interface_atspi_accessible_parent_get());
5121 while (parent && !eo_isa(parent, ELM_ATSPI_APP_OBJECT_CLASS))
5123 //TIZEN_ONLY(20160929) : atspi: Improves how to find the can_highlight of the widget
5124 if (!_elm_widget_can_highlight_get_by_class(parent)) return EINA_FALSE;
5126 eo_do(parent, parent = elm_interface_atspi_accessible_parent_get());
5132 //TIZEN_ONLY(20170206): Add check the object is in the scroller content size
5134 _accessible_object_on_scroll_is(Eo* obj)
5136 /* in case of genlist item, the item->view is NULL if item is unrealized.
5137 this function is used to check if obj could have HIGHLIGHTABLE or not.
5138 the unrealized genlist item should have HIGHLIGHTABLE state.
5139 so if obj is NULL return EINA_TRUE */
5140 if(!obj) return EINA_TRUE;
5142 Evas_Object *target = obj;
5143 Evas_Object *parent = NULL;
5144 Evas_Coord x, y, w, h, wx, wy, ww = 0, wh = 0, nx = 0, ny = 0;
5146 evas_object_geometry_get(target, &x, &y ,&w, &h);
5148 if (elm_widget_is(target))
5149 parent = elm_widget_parent_get(target);
5151 parent = elm_widget_parent_widget_get(target);
5155 if (eo_isa(parent, ELM_INTERFACE_SCROLLABLE_MIXIN))
5157 evas_object_geometry_get(parent, &wx, &wy, NULL, NULL);
5158 eo_do(parent, elm_interface_scrollable_content_size_get(&ww, &wh));
5159 eo_do(parent, elm_interface_scrollable_content_pos_get(&nx, &ny));
5161 /* widget implements scrollable interface but does not use scoller
5162 in this case, use widget geometry */
5163 if (ww == 0 || wh == 0)
5165 INF("%s is zero sized scrollable content", eo_class_name_get(eo_class_get(parent)));
5166 evas_object_geometry_get(parent, NULL, NULL, &ww, &wh);
5172 if (((wx < x) && (wx + ww < x)) || ((wx > x + w) && (wx + ww > x + w)) ||
5173 ((wy < y) && (wy + wh < y)) || ((wy > y + h) && (wy + wh > y + h)))
5178 parent = elm_widget_parent_get(parent);
5185 EOLIAN static Elm_Atspi_State_Set
5186 _elm_widget_item_elm_interface_atspi_accessible_state_set_get(Eo *eo_item,
5187 Elm_Widget_Item_Data *item)
5189 Elm_Atspi_State_Set states = 0;
5191 STATE_TYPE_SET(states, ELM_ATSPI_STATE_FOCUSABLE);
5193 if (elm_object_item_focus_get(eo_item))
5194 STATE_TYPE_SET(states, ELM_ATSPI_STATE_FOCUSED);
5195 if (!elm_object_item_disabled_get(eo_item))
5197 STATE_TYPE_SET(states, ELM_ATSPI_STATE_ENABLED);
5198 STATE_TYPE_SET(states, ELM_ATSPI_STATE_SENSITIVE);
5200 if (_elm_widget_item_onscreen_is(eo_item))
5201 STATE_TYPE_SET(states, ELM_ATSPI_STATE_SHOWING);
5203 //TIZEN_ONLY(20170207) : [ATSPI] enhance expose highlight information on atspi
5204 /* unrealized genlist item does not have item->view,
5205 and item cannot change its visibility, only widget can change the visibility */
5206 if (evas_object_visible_get(item->widget))
5207 STATE_TYPE_SET(states, ELM_ATSPI_STATE_VISIBLE);
5210 //TIZEN_ONLY(20170717) : expose highlight information on atspi
5211 if (_elm_widget_item_highlightable(eo_item) && _accessible_object_on_scroll_is(item->view))
5212 STATE_TYPE_SET(states, ELM_ATSPI_STATE_HIGHLIGHTABLE);
5214 STATE_TYPE_UNSET(states, ELM_ATSPI_STATE_HIGHLIGHTABLE);
5216 if (_elm_object_accessibility_currently_highlighted_get() == (void*)item->eo_obj)
5217 STATE_TYPE_SET(states, ELM_ATSPI_STATE_HIGHLIGHTED);
5223 _elm_widget_item_elm_interface_atspi_accessible_parent_get(Eo *eo_item, Elm_Widget_Item_Data *item EINA_UNUSED)
5226 eo_do(eo_item, parent = eo_parent_get());
5231 elm_object_item_data_set(Elm_Object_Item *it, void *data)
5233 WIDGET_ITEM_DATA_SET(it, data);
5237 elm_object_item_data_get(const Elm_Object_Item *it)
5239 return (void *) WIDGET_ITEM_DATA_GET(it);
5243 _elm_widget_item_disabled_set(Eo *eo_item EINA_UNUSED,
5244 Elm_Widget_Item_Data *item,
5247 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
5248 ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
5250 if (item->disabled == disabled) return;
5251 item->disabled = !!disabled;
5252 eo_do(item->eo_obj, elm_wdg_item_disable());
5255 EOLIAN static Eina_Bool
5256 _elm_widget_item_disabled_get(Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item)
5258 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item, EINA_FALSE);
5259 return item->disabled;
5263 _elm_widget_item_style_set(Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item, const char *style EINA_UNUSED)
5265 ERR_NOT_SUPPORTED(item, "elm_object_style_set()");
5268 EOLIAN static const char *
5269 _elm_widget_item_style_get(Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item)
5271 ERR_NOT_SUPPORTED(item, "elm_object_style_get()");
5276 _elm_widget_item_disable(Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item EINA_UNUSED)
5281 _elm_widget_item_focus_set(Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item, Eina_Bool focused EINA_UNUSED)
5283 ERR_NOT_SUPPORTED(item, "elm_object_item_focus_set");
5286 EOLIAN static Eina_Bool
5287 _elm_widget_item_focus_get(Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item)
5289 ERR_NOT_SUPPORTED(item, "elm_object_item_focus_get");
5294 _elm_widget_item_domain_translatable_part_text_set(Eo *eo_item EINA_UNUSED,
5295 Elm_Widget_Item_Data *item,
5300 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
5301 ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
5302 Elm_Translate_String_Data *ts;
5306 _part_text_translatable_set(&item->translate_strings, part, EINA_FALSE,
5311 ts = _part_text_translatable_set(&item->translate_strings, part,
5312 EINA_TRUE, EINA_FALSE);
5314 if (!ts->string) ts->string = eina_stringshare_add(label);
5315 else eina_stringshare_replace(&ts->string, label);
5316 if (!ts->domain) ts->domain = eina_stringshare_add(domain);
5317 else eina_stringshare_replace(&ts->domain, domain);
5319 if (label[0]) label = dgettext(domain, label);
5322 item->on_translate = EINA_TRUE;
5323 eo_do(item->eo_obj, elm_wdg_item_part_text_set(part, label));
5324 item->on_translate = EINA_FALSE;
5327 EOLIAN static const char *
5328 _elm_widget_item_translatable_part_text_get(const Eo *eo_item EINA_UNUSED,
5329 Elm_Widget_Item_Data *item,
5332 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item, NULL);
5333 ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item, NULL);
5335 Elm_Translate_String_Data *ts;
5336 ts = _translate_string_data_get(item->translate_strings, part);
5337 if (ts) return ts->string;
5342 _elm_widget_item_domain_part_text_translatable_set(Eo *eo_item EINA_UNUSED,
5343 Elm_Widget_Item_Data *item,
5346 Eina_Bool translatable)
5348 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
5349 ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
5350 Elm_Translate_String_Data *ts;
5353 ts = _part_text_translatable_set(&item->translate_strings, part,
5354 translatable, EINA_TRUE);
5356 if (!ts->domain) ts->domain = eina_stringshare_add(domain);
5357 else eina_stringshare_replace(&ts->domain, domain);
5359 eo_do(item->eo_obj, text = elm_wdg_item_part_text_get(part));
5361 if (!text || !text[0]) return;
5363 if (!ts->string) ts->string = eina_stringshare_add(text);
5365 //Try to translate text since we don't know the text is already translated.
5367 text = dgettext(domain, text);
5369 item->on_translate = EINA_TRUE;
5370 eo_do (item->eo_obj, elm_wdg_item_part_text_set(part, text));
5371 item->on_translate = EINA_FALSE;
5375 _elm_widget_item_track_cancel(Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item)
5377 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
5378 ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
5380 if (!item->track_obj) return;
5382 while (evas_object_ref_get(item->track_obj) > 0)
5383 evas_object_unref(item->track_obj);
5385 evas_object_del(item->track_obj);
5388 EOLIAN static Evas_Object *
5389 _elm_widget_item_track(Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item)
5391 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item, NULL);
5392 ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item, NULL);
5394 if (item->track_obj)
5396 evas_object_ref(item->track_obj);
5397 return item->track_obj;
5402 WRN("view obj of the item(%p) is invalid. Please make sure the view obj is created!", item);
5406 Evas_Object *track =
5407 evas_object_rectangle_add(evas_object_evas_get(item->widget));
5408 evas_object_color_set(track, 0, 0, 0, 0);
5409 evas_object_pass_events_set(track, EINA_TRUE);
5410 _track_obj_update(track, item->view);
5411 evas_object_event_callback_add(track, EVAS_CALLBACK_DEL, _track_obj_del,
5415 eo_event_callback_array_add(tracker_callbacks(), item));
5417 evas_object_ref(track);
5419 item->track_obj = track;
5425 _elm_widget_item_untrack(Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item)
5427 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
5428 ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
5430 if (!item->track_obj) return;
5431 evas_object_unref(item->track_obj);
5433 if (evas_object_ref_get(item->track_obj) == 0)
5434 evas_object_del(item->track_obj);
5438 _elm_widget_item_track_get(const Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item)
5440 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item, 0);
5441 ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item, 0);
5443 if (!item->track_obj) return 0;
5444 return evas_object_ref_get(item->track_obj);
5447 typedef struct _Elm_Widget_Item_Tooltip Elm_Widget_Item_Tooltip;
5449 struct _Elm_Widget_Item_Tooltip
5451 Elm_Widget_Item_Data *item;
5452 Elm_Tooltip_Item_Content_Cb func;
5453 Evas_Smart_Cb del_cb;
5457 static Evas_Object *
5458 _elm_widget_item_tooltip_label_create(void *data,
5459 Evas_Object *obj EINA_UNUSED,
5460 Evas_Object *tooltip,
5461 void *item EINA_UNUSED)
5463 Evas_Object *label = elm_label_add(tooltip);
5466 elm_object_style_set(label, "tooltip");
5467 elm_object_text_set(label, data);
5471 static Evas_Object *
5472 _elm_widget_item_tooltip_trans_label_create(void *data,
5473 Evas_Object *obj EINA_UNUSED,
5474 Evas_Object *tooltip,
5475 void *item EINA_UNUSED)
5477 Evas_Object *label = elm_label_add(tooltip);
5480 elm_object_style_set(label, "tooltip");
5481 elm_object_translatable_text_set(label, data);
5486 _elm_widget_item_tooltip_label_del_cb(void *data,
5487 Evas_Object *obj EINA_UNUSED,
5488 void *event_info EINA_UNUSED)
5490 eina_stringshare_del(data);
5496 * Set the text to be shown in the widget item.
5498 * @param item Target item
5499 * @param text The text to set in the content
5501 * Setup the text as tooltip to object. The item can have only one tooltip,
5502 * so any previous tooltip data is removed.
5507 _elm_widget_item_tooltip_text_set(Eo *eo_item EINA_UNUSED,
5508 Elm_Widget_Item_Data *item EINA_UNUSED,
5511 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
5512 ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
5513 EINA_SAFETY_ON_NULL_RETURN(text);
5515 text = eina_stringshare_add(text);
5516 eo_do(item->eo_obj, elm_wdg_item_tooltip_content_cb_set(
5517 _elm_widget_item_tooltip_label_create,
5519 _elm_widget_item_tooltip_label_del_cb));
5523 _elm_widget_item_tooltip_translatable_text_set(Eo *eo_item EINA_UNUSED,
5524 Elm_Widget_Item_Data *item EINA_UNUSED,
5527 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
5528 ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
5529 EINA_SAFETY_ON_NULL_RETURN(text);
5531 text = eina_stringshare_add(text);
5532 eo_do(item->eo_obj, elm_wdg_item_tooltip_content_cb_set(
5533 _elm_widget_item_tooltip_trans_label_create,
5535 _elm_widget_item_tooltip_label_del_cb));
5538 static Evas_Object *
5539 _elm_widget_item_tooltip_create(void *data,
5541 Evas_Object *tooltip)
5543 Elm_Widget_Item_Tooltip *wit = data;
5544 return wit->func((void *)wit->data, obj, tooltip, wit->item->eo_obj);
5548 _elm_widget_item_tooltip_del_cb(void *data,
5550 void *event_info EINA_UNUSED)
5552 Elm_Widget_Item_Tooltip *wit = data;
5553 if (wit->del_cb) wit->del_cb((void *)wit->data, obj, wit->item->eo_obj);
5560 * Set the content to be shown in the tooltip item
5562 * Setup the tooltip to item. The item can have only one tooltip,
5563 * so any previous tooltip data is removed. @p func(with @p data) will
5564 * be called every time that need show the tooltip and it should
5565 * return a valid Evas_Object. This object is then managed fully by
5566 * tooltip system and is deleted when the tooltip is gone.
5568 * @param item the widget item being attached a tooltip.
5569 * @param func the function used to create the tooltip contents.
5570 * @param data what to provide to @a func as callback data/context.
5571 * @param del_cb called when data is not needed anymore, either when
5572 * another callback replaces @func, the tooltip is unset with
5573 * elm_widget_item_tooltip_unset() or the owner @a item
5574 * dies. This callback receives as the first parameter the
5575 * given @a data, and @c event_info is the item.
5580 _elm_widget_item_tooltip_content_cb_set(Eo *eo_item EINA_UNUSED,
5581 Elm_Widget_Item_Data *item,
5582 Elm_Tooltip_Item_Content_Cb func,
5584 Evas_Smart_Cb del_cb)
5586 Elm_Widget_Item_Tooltip *wit;
5588 ELM_WIDGET_ITEM_CHECK_OR_GOTO(item, error_noitem);
5589 //ELM_WIDGET_ITEM_RETURN_IF_GOTO(item, error_noitem);
5593 eo_do(item->eo_obj, elm_wdg_item_tooltip_unset());
5597 wit = ELM_NEW(Elm_Widget_Item_Tooltip);
5598 if (!wit) goto error;
5602 wit->del_cb = del_cb;
5604 elm_object_sub_tooltip_content_cb_set
5605 (item->view, item->widget, _elm_widget_item_tooltip_create, wit,
5606 _elm_widget_item_tooltip_del_cb);
5611 if (del_cb) del_cb((void *)data, NULL, item);
5614 if (del_cb) del_cb((void *)data, item->widget, item);
5620 * Unset tooltip from item
5622 * @param item widget item to remove previously set tooltip.
5624 * Remove tooltip from item. The callback provided as del_cb to
5625 * elm_widget_item_tooltip_content_cb_set() will be called to notify
5626 * it is not used anymore.
5628 * @see elm_widget_item_tooltip_content_cb_set()
5633 _elm_widget_item_tooltip_unset(Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item)
5635 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
5636 ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
5638 elm_object_tooltip_unset(item->view);
5644 * Sets a different style for this item tooltip.
5646 * @note before you set a style you should define a tooltip with
5647 * elm_widget_item_tooltip_content_cb_set() or
5648 * elm_widget_item_tooltip_text_set()
5650 * @param item widget item with tooltip already set.
5651 * @param style the theme style to use (default, transparent, ...)
5656 _elm_widget_item_tooltip_style_set(Eo *eo_item EINA_UNUSED,
5657 Elm_Widget_Item_Data *item,
5660 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
5661 ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
5663 elm_object_tooltip_style_set(item->view, style);
5666 EOLIAN static Eina_Bool
5667 _elm_widget_item_tooltip_window_mode_set(Eo *eo_item EINA_UNUSED,
5668 Elm_Widget_Item_Data *item,
5671 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item, EINA_FALSE);
5672 ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item, EINA_FALSE);
5674 return elm_object_tooltip_window_mode_set(item->view, disable);
5677 EOLIAN static Eina_Bool
5678 _elm_widget_item_tooltip_window_mode_get(Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item)
5680 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item, EINA_FALSE);
5681 ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item, EINA_FALSE);
5683 return elm_object_tooltip_window_mode_get(item->view);
5689 * Get the style for this item tooltip.
5691 * @param item widget item with tooltip already set.
5692 * @return style the theme style in use, defaults to "default". If the
5693 * object does not have a tooltip set, then NULL is returned.
5697 EOLIAN static const char *
5698 _elm_widget_item_tooltip_style_get(Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item)
5700 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item, NULL);
5702 return elm_object_tooltip_style_get(item->view);
5706 _elm_widget_item_cursor_set(Eo *eo_item EINA_UNUSED,
5707 Elm_Widget_Item_Data *item,
5710 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
5711 ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
5713 elm_object_sub_cursor_set(item->view, item->widget, cursor);
5716 EOLIAN static const char *
5717 _elm_widget_item_cursor_get(Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item)
5719 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item, NULL);
5720 return elm_object_cursor_get(item->view);
5724 _elm_widget_item_cursor_unset(Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item)
5726 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
5727 ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
5729 elm_object_cursor_unset(item->view);
5735 * Sets a different style for this item cursor.
5737 * @note before you set a style you should define a cursor with
5738 * elm_widget_item_cursor_set()
5740 * @param item widget item with cursor already set.
5741 * @param style the theme style to use (default, transparent, ...)
5746 _elm_widget_item_cursor_style_set(Eo *eo_item EINA_UNUSED,
5747 Elm_Widget_Item_Data *item,
5750 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
5751 ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
5753 elm_object_cursor_style_set(item->view, style);
5759 * Get the style for this item cursor.
5761 * @param item widget item with cursor already set.
5762 * @return style the theme style in use, defaults to "default". If the
5763 * object does not have a cursor set, then NULL is returned.
5767 EOLIAN static const char *
5768 _elm_widget_item_cursor_style_get(Eo *eo_item EINA_UNUSED,
5769 Elm_Widget_Item_Data *item)
5771 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item, NULL);
5772 return elm_object_cursor_style_get(item->view);
5778 * Set if the cursor set should be searched on the theme or should use
5779 * the provided by the engine, only.
5781 * @note before you set if should look on theme you should define a cursor
5782 * with elm_object_cursor_set(). By default it will only look for cursors
5783 * provided by the engine.
5785 * @param item widget item with cursor already set.
5786 * @param engine_only boolean to define it cursors should be looked only
5787 * between the provided by the engine or searched on widget's theme as well.
5792 _elm_widget_item_cursor_engine_only_set(Eo *eo_item EINA_UNUSED,
5793 Elm_Widget_Item_Data *item,
5794 Eina_Bool engine_only)
5796 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
5797 ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
5799 elm_object_cursor_theme_search_enabled_set(item->view, !engine_only);
5805 * Get the cursor engine only usage for this item cursor.
5807 * @param item widget item with cursor already set.
5808 * @return engine_only boolean to define it cursors should be looked only
5809 * between the provided by the engine or searched on widget's theme as well. If
5810 * the object does not have a cursor set, then EINA_FALSE is returned.
5814 EOLIAN static Eina_Bool
5815 _elm_widget_item_cursor_engine_only_get(Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item)
5817 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item, EINA_FALSE);
5818 return !elm_object_cursor_theme_search_enabled_get(item->view);
5822 _elm_widget_item_part_content_set(Eo *eo_item EINA_UNUSED,
5823 Elm_Widget_Item_Data *item,
5824 const char *part EINA_UNUSED,
5825 Evas_Object *content EINA_UNUSED)
5827 ERR_NOT_SUPPORTED(item, "elm_object_part_content_set()");
5830 EOLIAN static Evas_Object *
5831 _elm_widget_item_part_content_get(Eo *eo_item EINA_UNUSED,
5832 Elm_Widget_Item_Data *item,
5833 const char *part EINA_UNUSED)
5835 ERR_NOT_SUPPORTED(item, "elm_object_part_content_get()");
5839 EOLIAN static Evas_Object *
5840 _elm_widget_item_part_content_unset(Eo *eo_item EINA_UNUSED,
5841 Elm_Widget_Item_Data *item,
5842 const char *part EINA_UNUSED)
5844 ERR_NOT_SUPPORTED(item, "elm_object_part_content_unset()");
5849 _elm_widget_item_part_text_set(Eo *eo_item EINA_UNUSED,
5850 Elm_Widget_Item_Data *item,
5851 const char *part EINA_UNUSED,
5852 const char *label EINA_UNUSED)
5854 ERR_NOT_SUPPORTED(item, "elm_object_part_text_set()");
5857 EOLIAN static const char *
5858 _elm_widget_item_part_text_get(Eo *eo_item EINA_UNUSED,
5859 Elm_Widget_Item_Data *item,
5860 const char *part EINA_UNUSED)
5862 ERR_NOT_SUPPORTED(item, "elm_object_part_text_get()");
5867 _elm_widget_item_part_text_custom_free(void *data)
5869 Elm_Label_Data *label;
5871 eina_stringshare_del(label->part);
5872 eina_stringshare_del(label->text);
5877 _elm_widget_item_part_text_custom_set(Eo *eo_item EINA_UNUSED,
5878 Elm_Widget_Item_Data *item,
5882 Elm_Label_Data *label;
5883 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
5884 ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
5888 eina_hash_stringshared_new(_elm_widget_item_part_text_custom_free);
5889 label = eina_hash_find(item->labels, part);
5892 label = malloc(sizeof(Elm_Label_Data));
5895 ERR("Failed to allocate memory");
5898 label->part = eina_stringshare_add(part);
5899 label->text = eina_stringshare_add(text);
5900 eina_hash_add(item->labels, part, label);
5903 eina_stringshare_replace(&label->text, text);
5906 EOLIAN static const char *
5907 _elm_widget_item_part_text_custom_get(Eo *eo_item EINA_UNUSED,
5908 Elm_Widget_Item_Data *item,
5911 Elm_Label_Data *label;
5912 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item, NULL);
5913 label = eina_hash_find(item->labels, part);
5914 return label ? label->text : NULL;
5918 _elm_widget_item_part_text_custom_foreach(const Eina_Hash *labels EINA_UNUSED,
5919 const void *key EINA_UNUSED,
5923 Elm_Label_Data *label;
5924 Elm_Widget_Item_Data *item;
5928 eo_do(item->eo_obj, elm_wdg_item_part_text_set(label->part, label->text));
5934 _elm_widget_item_part_text_custom_update(Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item)
5936 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
5937 ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
5939 eina_hash_foreach(item->labels,
5940 _elm_widget_item_part_text_custom_foreach, item);
5944 _elm_widget_item_signal_emit(Eo *eo_item EINA_UNUSED,
5945 Elm_Widget_Item_Data *item EINA_UNUSED,
5946 const char *emission EINA_UNUSED,
5947 const char *source EINA_UNUSED)
5953 _elm_widget_item_signal_callback_add(Eo *eo_item,
5954 Elm_Widget_Item_Data *item,
5955 const char *emission,
5957 Elm_Object_Item_Signal_Cb func,
5960 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
5961 ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
5962 EINA_SAFETY_ON_NULL_RETURN(func);
5964 Elm_Widget_Item_Signal_Data *wisd;
5966 wisd = malloc(sizeof(Elm_Widget_Item_Signal_Data));
5969 wisd->item = eo_item;
5970 wisd->func = (Elm_Widget_Item_Signal_Cb)func;
5972 wisd->emission = eina_stringshare_add(emission);
5973 wisd->source = eina_stringshare_add(source);
5975 if (_elm_widget_is(item->view))
5976 elm_object_signal_callback_add(item->view, emission, source, _elm_widget_item_signal_cb, wisd);
5977 else if (eo_isa(item->view, EDJE_OBJECT_CLASS))
5978 edje_object_signal_callback_add(item->view, emission, source, _elm_widget_item_signal_cb, wisd);
5981 WRN("The %s widget item doesn't support signal callback add!",
5982 eo_class_name_get(eo_class_get(item->widget)));
5987 item->signals = eina_list_append(item->signals, wisd);
5990 EOLIAN static void *
5991 _elm_widget_item_signal_callback_del(Eo *eo_item EINA_UNUSED,
5992 Elm_Widget_Item_Data *item,
5993 const char *emission,
5995 Elm_Object_Item_Signal_Cb func)
5997 Elm_Widget_Item_Signal_Data *wisd;
6000 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item, NULL);
6001 ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item, NULL);
6002 EINA_SAFETY_ON_NULL_RETURN_VAL(func, NULL);
6004 EINA_LIST_FOREACH(item->signals, l, wisd)
6006 if ((wisd->func == (Elm_Widget_Item_Signal_Cb)func) &&
6007 !strcmp(wisd->emission, emission) &&
6008 !strcmp(wisd->source, source))
6009 return _elm_widget_item_signal_callback_list_get(item, l);
6016 _elm_widget_item_access_info_set(Eo *eo_item EINA_UNUSED,
6017 Elm_Widget_Item_Data *item,
6020 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
6021 ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
6023 eina_stringshare_del(item->access_info);
6024 if (!txt) item->access_info = NULL;
6025 else item->access_info = eina_stringshare_add(txt);
6029 _elm_widget_item_translate(Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item)
6031 ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
6032 ELM_WIDGET_ITEM_RETURN_IF_ONDEL(item);
6035 Elm_Translate_String_Data *ts;
6036 EINA_INLIST_FOREACH(item->translate_strings, ts)
6038 if (!ts->string) continue;
6039 const char *s = dgettext(ts->domain, ts->string);
6040 item->on_translate = EINA_TRUE;
6041 eo_do(item->eo_obj, elm_wdg_item_part_text_set(ts->id, s));
6042 item->on_translate = EINA_FALSE;
6048 _elm_widget_item_access_order_set(Eo *eo_item EINA_UNUSED,
6049 Elm_Widget_Item_Data *item,
6052 _elm_access_widget_item_access_order_set(item, objs);
6055 EOLIAN static const Eina_List *
6056 _elm_widget_item_access_order_get(const Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item)
6058 return _elm_access_widget_item_access_order_get(item);
6062 _elm_widget_item_access_order_unset(Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item)
6064 _elm_access_widget_item_access_order_unset(item);
6067 EOLIAN static Evas_Object*
6068 _elm_widget_item_access_register(Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item)
6070 _elm_access_widget_item_register(item);
6071 return item->access_obj;
6075 _elm_widget_item_access_unregister(Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item)
6077 _elm_access_widget_item_unregister(item);
6080 EOLIAN static Evas_Object*
6081 _elm_widget_item_access_object_get(const Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item)
6083 return item->access_obj;
6086 EOLIAN static Evas_Object *
6087 _elm_widget_item_focus_next_object_get(const Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item, Elm_Focus_Direction dir)
6089 Evas_Object *ret = NULL;
6091 if (dir == ELM_FOCUS_PREVIOUS)
6092 ret = item->focus_previous;
6093 else if (dir == ELM_FOCUS_NEXT)
6094 ret = item->focus_next;
6095 else if (dir == ELM_FOCUS_UP)
6096 ret = item->focus_up;
6097 else if (dir == ELM_FOCUS_DOWN)
6098 ret = item->focus_down;
6099 else if (dir == ELM_FOCUS_RIGHT)
6100 ret = item->focus_right;
6101 else if (dir == ELM_FOCUS_LEFT)
6102 ret = item->focus_left;
6108 _elm_widget_item_focus_next_object_set(Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item, Evas_Object *next, Elm_Focus_Direction dir)
6110 if (dir == ELM_FOCUS_PREVIOUS)
6111 item->focus_previous = next;
6112 else if (dir == ELM_FOCUS_NEXT)
6113 item->focus_next = next;
6114 else if (dir == ELM_FOCUS_UP)
6115 item->focus_up = next;
6116 else if (dir == ELM_FOCUS_DOWN)
6117 item->focus_down = next;
6118 else if (dir == ELM_FOCUS_RIGHT)
6119 item->focus_right = next;
6120 else if (dir == ELM_FOCUS_LEFT)
6121 item->focus_left = next;
6124 EOLIAN static Elm_Object_Item*
6125 _elm_widget_item_focus_next_item_get(const Eo *eo_item EINA_UNUSED, Elm_Widget_Item_Data *item, Elm_Focus_Direction dir)
6127 Elm_Object_Item *ret = NULL;
6129 if (dir == ELM_FOCUS_PREVIOUS)
6130 ret = item->item_focus_previous;
6131 else if (dir == ELM_FOCUS_NEXT)
6132 ret = item->item_focus_next;
6133 else if (dir == ELM_FOCUS_UP)
6134 ret = item->item_focus_up;
6135 else if (dir == ELM_FOCUS_DOWN)
6136 ret = item->item_focus_down;
6137 else if (dir == ELM_FOCUS_RIGHT)
6138 ret = item->item_focus_right;
6139 else if (dir == ELM_FOCUS_LEFT)
6140 ret = item->item_focus_left;
6146 _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)
6148 if (dir == ELM_FOCUS_PREVIOUS)
6149 item->item_focus_previous = next_item;
6150 else if (dir == ELM_FOCUS_NEXT)
6151 item->item_focus_next = next_item;
6152 else if (dir == ELM_FOCUS_UP)
6153 item->item_focus_up = next_item;
6154 else if (dir == ELM_FOCUS_DOWN)
6155 item->item_focus_down = next_item;
6156 else if (dir == ELM_FOCUS_RIGHT)
6157 item->item_focus_right = next_item;
6158 else if (dir == ELM_FOCUS_LEFT)
6159 item->item_focus_left = next_item;
6162 /* happy debug functions */
6165 _sub_obj_tree_dump(const Evas_Object *obj,
6170 for (i = 0; i < lvl * 3; i++)
6173 if (_elm_widget_is(obj))
6178 elm_widget_type_get(obj),
6180 EINA_LIST_FOREACH(sd->subobjs, l, obj)
6181 _sub_obj_tree_dump(obj, lvl + 1);
6184 DBG("+ %s(%p)\n", evas_object_type_get(obj), obj);
6188 _sub_obj_tree_dot_dump(const Evas_Object *obj,
6191 if (!_elm_widget_is(obj))
6195 Eina_Bool visible = evas_object_visible_get(obj);
6196 Eina_Bool disabled = elm_widget_disabled_get(obj);
6197 Eina_Bool focused = elm_widget_focus_get(obj);
6198 Eina_Bool can_focus = elm_widget_can_focus_get(obj);
6202 fprintf(output, "\"%p\" -- \"%p\" [ color=black", sd->parent_obj, obj);
6205 fprintf(output, ", style=bold");
6208 fprintf(output, ", color=gray28");
6210 fprintf(output, " ];\n");
6213 fprintf(output, "\"%p\" [ label = \"{%p|%s|%s|visible: %d|"
6214 "disabled: %d|focused: %d/%d|focus order:%d}\"",
6215 obj, obj, elm_widget_type_get(obj),
6216 evas_object_name_get(obj), visible, disabled, focused, can_focus,
6220 fprintf(output, ", style=bold");
6223 fprintf(output, ", fontcolor=gray28");
6225 if ((disabled) || (!visible))
6226 fprintf(output, ", color=gray");
6228 fprintf(output, " ];\n");
6232 EINA_LIST_FOREACH(sd->subobjs, l, o)
6233 _sub_obj_tree_dot_dump(o, output);
6239 elm_widget_tree_dump(const Evas_Object *top)
6242 if (!_elm_widget_is(top))
6244 _sub_obj_tree_dump(top, 0);
6252 elm_widget_tree_dot_dump(const Evas_Object *top,
6256 if (!_elm_widget_is(top))
6258 fprintf(output, "graph " " { node [shape=record];\n");
6259 _sub_obj_tree_dot_dump(top, output);
6260 fprintf(output, "}\n");
6269 _elm_widget_eo_base_constructor(Eo *obj, Elm_Widget_Smart_Data *sd EINA_UNUSED)
6273 sd->on_create = EINA_TRUE;
6274 obj = eo_do_super_ret(obj, MY_CLASS, obj, eo_constructor());
6276 evas_obj_type_set(MY_CLASS_NAME_LEGACY),
6277 evas_obj_smart_callbacks_descriptions_set(_smart_callbacks),
6278 parent = eo_parent_get());
6279 eo_do(obj, elm_obj_widget_parent_set(parent));
6280 sd->on_create = EINA_FALSE;
6281 //TIZEN_ONLY(20170717) : expose highlight information on atspi
6282 sd->can_highlight = EINA_TRUE;
6284 /* TIZEN_ONLY(20160622): Override Paragraph Direction APIs */
6285 sd->inherit_paragraph_direction = EINA_TRUE;
6288 eo_do(obj, elm_interface_atspi_accessible_role_set(ELM_ATSPI_ROLE_UNKNOWN));
6290 /* TIZEN_ONLY(20161117): Inherit paragraph direction from widget parent */
6291 if (sd->paragraph_direction != evas_object_paragraph_direction_get(parent))
6293 sd->paragraph_direction = evas_object_paragraph_direction_get(parent);
6294 _elm_widget_evas_object_paragraph_direction_set_internal(obj, sd, sd->paragraph_direction);
6295 eo_do_super(obj, MY_CLASS, evas_obj_paragraph_direction_set(sd->paragraph_direction));
6303 _elm_widget_eo_base_destructor(Eo *obj, Elm_Widget_Smart_Data *sd EINA_UNUSED)
6305 sd->on_destroy = EINA_TRUE;
6307 elm_interface_atspi_accessible_description_set(NULL),
6308 elm_interface_atspi_accessible_name_set(NULL),
6309 //TIZEN_ONLY(20190922): add name callback, description callback.
6310 elm_interface_atspi_accessible_description_cb_set(NULL, NULL),
6311 elm_interface_atspi_accessible_name_cb_set(NULL, NULL),
6313 //TIZEN_ONLY(20170405) Add gesture method to accessible interface
6314 elm_interface_atspi_accessible_gesture_cb_set(NULL, NULL),
6316 elm_interface_atspi_accessible_translation_domain_set(NULL),
6317 elm_interface_atspi_accessible_relationships_clear(),
6318 // TIZEN_ONLY(20160930) : endless recursion fix
6319 elm_interface_atspi_accessible_attributes_clear()
6322 // TIZEN_ONLY(20150709) : atspi relations api
6323 if (sd->atspi_custom_relations)
6324 elm_atspi_relation_set_free(&sd->atspi_custom_relations);
6326 //TIZEN_ONLY(20150717) add widget name setter
6328 eina_stringshare_del(sd->name);
6331 //TIZEN_ONLY(20150731) : add i18n support for name and description
6332 if (sd->atspi_translation_domain)
6333 eina_stringshare_del(sd->atspi_translation_domain);
6335 //Tizen Only(20160728) free attribute list
6338 Elm_Atspi_Attribute *attr;
6339 EINA_LIST_FREE(sd->attr_list, attr)
6341 eina_stringshare_del(attr->key);
6342 eina_stringshare_del(attr->value);
6348 eo_do_super(obj, ELM_WIDGET_CLASS, eo_destructor());
6349 sd->on_destroy = EINA_FALSE;
6351 elm_interface_atspi_accessible_removed(obj);
6354 EOLIAN static Eina_Bool
6355 _elm_widget_on_focus(Eo *obj, Elm_Widget_Smart_Data *sd, Elm_Object_Item *item EINA_UNUSED)
6357 if (elm_widget_can_focus_get(obj))
6359 if (elm_widget_focus_get(obj))
6361 if (!sd->resize_obj)
6362 evas_object_focus_set(obj, EINA_TRUE);
6363 eo_do(obj, eo_event_callback_call
6364 (ELM_WIDGET_EVENT_FOCUSED, NULL));
6365 if (_elm_atspi_enabled() && !elm_widget_child_can_focus_get(obj))
6366 elm_interface_atspi_accessible_state_changed_signal_emit(obj, ELM_ATSPI_STATE_FOCUSED, EINA_TRUE);
6370 if (!sd->resize_obj)
6371 evas_object_focus_set(obj, EINA_FALSE);
6372 eo_do(obj, eo_event_callback_call
6373 (ELM_WIDGET_EVENT_UNFOCUSED, NULL));
6374 if (_elm_atspi_enabled() && !elm_widget_child_can_focus_get(obj))
6375 elm_interface_atspi_accessible_state_changed_signal_emit(obj, ELM_ATSPI_STATE_FOCUSED, EINA_FALSE);
6384 EOLIAN static Eina_Bool
6385 _elm_widget_disable(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *_pd EINA_UNUSED)
6390 EOLIAN static Eina_Bool
6391 _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)
6396 EOLIAN static Eina_Bool
6397 _elm_widget_focus_next_manager_is(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *_pd EINA_UNUSED)
6399 WRN("The %s widget does not implement the \"focus_next/focus_next_manager_is\" functions.",
6400 eo_class_name_get(eo_class_get(obj)));
6405 _elm_widget_focus_direction_manager_is(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *_pd EINA_UNUSED)
6407 WRN("The %s widget does not implement the \"focus_direction/focus_direction_manager_is\" functions.",
6408 eo_class_name_get(eo_class_get(obj)));
6412 EOLIAN static Eina_Bool
6413 _elm_widget_activate(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *_pd EINA_UNUSED, Elm_Activate act EINA_UNUSED)
6415 WRN("The %s widget does not implement the \"activate\" functions.",
6416 eo_class_name_get(eo_class_get(obj)));
6421 _elm_widget_class_constructor(Eo_Class *klass)
6423 evas_smart_legacy_type_register(MY_CLASS_NAME_LEGACY, klass);
6426 EOLIAN static Eina_Bool
6427 _elm_widget_elm_interface_atspi_component_focus_grab(Eo *obj, Elm_Widget_Smart_Data *pd EINA_UNUSED)
6429 if (elm_object_focus_allow_get(obj))
6431 Ecore_Evas *ee = ecore_evas_ecore_evas_get(evas_object_evas_get(obj));
6432 if (!ee) return EINA_FALSE;
6433 ecore_evas_activate(ee);
6434 elm_object_focus_set(obj, EINA_TRUE);
6440 //TIZEN_ONLY(20170119): Show the object highlighted by highlight_grab when the object is completely out of the scroll
6442 _elm_widget_showing_geometry_get(Eo *obj, int *x, int *y, int *w, int *h)
6444 Evas_Object *parent;
6445 Evas_Coord px, py, sx, sy, sw, sh;
6454 evas_object_geometry_get(obj, x, y, w, h);
6456 if (elm_widget_is(obj))
6457 parent = elm_widget_parent_get(obj);
6459 parent = elm_widget_parent_widget_get(obj);
6463 if (eo_isa(parent, ELM_INTERFACE_SCROLLABLE_MIXIN))
6465 evas_object_geometry_get(parent, &sx, &sy, &sw, &sh);
6468 *x = *x > sx ? *x : sx;
6469 *y = *y > sy ? *y : sy;
6470 *w = px + *w < sx + sw ? px + *w - *x : sx + sw - *x;
6471 *h = py + *h < sy + sh ? py + *h - *y : sy + sh - *y;
6473 parent = elm_widget_parent_get(parent);
6478 _accessible_object_on_screen_is(Eo *obj, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h, Eina_Bool is_complete)
6480 if(!obj) return EINA_FALSE;
6482 Evas_Object *target = obj;
6483 Evas_Object *parent = NULL;
6484 Evas_Coord px, py, sx, sy, sw, sh, ox, oy, ow, oh;
6486 /* uninitialized data could be read */
6490 if (elm_widget_is(target))
6491 parent = elm_widget_parent_get(target);
6493 parent = elm_widget_parent_widget_get(target);
6497 if (eo_isa(parent, ELM_INTERFACE_SCROLLABLE_MIXIN))
6499 evas_object_geometry_get(parent, &sx, &sy, &sw, &sh);
6504 ox = is_complete ? ox : ox + ow;
6505 oy = is_complete ? oy : oy + oh;
6506 ox = ox > sx ? ox : sx;
6507 oy = oy > sy ? oy : sy;
6508 ow = px + ow < sx + sw ? px + ow - ox : sx + sw - ox;
6509 oh = py + oh < sy + sh ? py + oh - oy : sy + sh - oy;
6511 if (ow <= 0 || oh <= 0)
6514 parent = elm_widget_parent_get(parent);
6520 _accessible_scrollable_parent_list_get(Eo *obj)
6522 if(!obj) return NULL;
6524 Evas_Object *parent = NULL;
6525 Eina_List *plist = NULL;
6527 if (elm_widget_is(obj))
6528 parent = elm_widget_parent_get(obj);
6530 parent = elm_widget_parent_widget_get(obj);
6534 if (_elm_scrollable_is(parent))
6535 plist = eina_list_append(plist, parent);
6537 parent = elm_widget_parent_get(parent);
6543 _accessible_highlight_region_show(Eo* obj)
6547 Evas_Object *target = obj;
6548 Evas_Object *parent = NULL;
6549 Evas_Object *parent_sub = NULL;
6550 Eina_List *plist, *plist_sub;
6553 Evas_Coord target_x, target_y, target_w, target_h;
6555 evas_object_geometry_get(target, &target_x, &target_y, &target_w, &target_h);
6557 plist = _accessible_scrollable_parent_list_get(target);
6560 EINA_LIST_FOREACH(plist, l, parent)
6562 if(!_accessible_object_on_screen_is(target, target_x, target_y, target_w, target_h, EINA_TRUE))
6564 plist_sub = _accessible_scrollable_parent_list_get(parent);
6565 plist_sub = eina_list_prepend(plist_sub, parent);
6566 EINA_LIST_FOREACH(plist_sub, l2, parent_sub)
6568 Evas_Coord scroll_x = 0, scroll_y = 0;
6569 Evas_Coord scroll_x_back = 0, scroll_y_back = 0;
6570 Evas_Coord x, y, w, h;
6573 eo_do(parent_sub, elm_interface_scrollable_content_region_get(&scroll_x_back, &scroll_y_back, NULL, NULL));
6574 evas_object_geometry_get(parent_sub, &px, &py, NULL, NULL);
6575 x = target_x; y = target_y; w = target_w; h = target_h;
6577 x -= (px - scroll_x_back);
6578 y -= (py - scroll_y_back);
6579 switch (_elm_config->focus_autoscroll_mode)
6581 case ELM_FOCUS_AUTOSCROLL_MODE_SHOW:
6582 eo_do(parent_sub, elm_interface_scrollable_content_region_show(x, y, w, h));
6584 case ELM_FOCUS_AUTOSCROLL_MODE_BRING_IN:
6585 eo_do(parent_sub, elm_interface_scrollable_region_bring_in(x, y, w, h));
6590 eo_do(parent_sub, elm_interface_scrollable_content_region_get(&scroll_x, &scroll_y, NULL, NULL));
6592 target_x -= (scroll_x - scroll_x_back);
6593 target_y -= (scroll_y - scroll_y_back);
6595 if(_accessible_object_on_screen_is(target, target_x, target_y, target_w, target_h, EINA_FALSE))
6598 eina_list_free(plist_sub);
6602 eina_list_free(plist);
6606 //TIZEN_ONLY(20171011) : atspi : During the highlight grab, out signal is not sent.
6608 _elm_widget_accessibility_highlight_grabbing_get(Eo *obj)
6610 ELM_WIDGET_DATA_GET(obj, wd);
6611 return wd->highlight_grabbing;
6615 _elm_widget_accessibility_highlight_grabbing_set(Eo *obj, Eina_Bool grabbing)
6617 ELM_WIDGET_DATA_GET(obj, wd);
6618 wd->highlight_grabbing = grabbing;
6622 //TIZEN_ONLY(20160329): atspi: implement HighlightGrab and HighlightClear methods (29e253e2f7ef3c632ac3a64c489bf569df407f30)
6623 EOLIAN static Eina_Bool
6624 _elm_widget_elm_interface_atspi_component_highlight_grab(Eo *obj, Elm_Widget_Smart_Data *pd EINA_UNUSED)
6626 if(!obj) return EINA_FALSE;
6627 if(!_elm_atspi_enabled())
6630 //TIZEN_ONLY(20171011) : atspi : During the highlight grab, out signal is not sent.
6631 _elm_widget_accessibility_highlight_grabbing_set(obj, EINA_TRUE);
6634 //TIZEN_ONLY(20170119): Show the object highlighted by highlight_grab when the object is completely out of the scroll
6635 _accessible_highlight_region_show(obj);
6638 elm_object_accessibility_highlight_set(obj, EINA_TRUE);
6639 elm_interface_atspi_accessible_state_changed_signal_emit(obj, ELM_ATSPI_STATE_HIGHLIGHTED, EINA_TRUE);
6641 // TIZEN_ONLY(20161018): add highlighted/unhighlighted signal for atspi
6642 evas_object_smart_callback_call(obj, SIG_WIDGET_ATSPI_HIGHLIGHTED, NULL);
6644 //TIZEN_ONLY(20171011) : atspi : During the highlight grab, out signal is not sent.
6645 _elm_widget_accessibility_highlight_grabbing_set(obj, EINA_FALSE);
6650 EOLIAN static Eina_Bool
6651 _elm_widget_elm_interface_atspi_component_highlight_clear(Eo *obj, Elm_Widget_Smart_Data *pd EINA_UNUSED)
6653 if(!_elm_atspi_enabled())
6655 elm_object_accessibility_highlight_set(obj, EINA_FALSE);
6656 elm_interface_atspi_accessible_state_changed_signal_emit(obj, ELM_ATSPI_STATE_HIGHLIGHTED, EINA_FALSE);
6658 // TIZEN_ONLY(20161018): add highlighted/unhighlighted signal for atspi
6659 evas_object_smart_callback_call(obj, SIG_WIDGET_ATSPI_UNHIGHLIGHTED, NULL);
6665 EOLIAN static const char*
6666 _elm_widget_elm_interface_atspi_accessible_name_get(Eo *obj, Elm_Widget_Smart_Data *_pd)
6668 //TIZEN_ONLY(20190922): add name callback, description callback.
6669 const char *ret = NULL;
6670 eo_do_super(obj, ELM_WIDGET_CLASS, ret = elm_interface_atspi_accessible_name_get());
6671 if (ret) return ret;
6674 //TIZEN_ONLY(20150717) add widget name setter
6678 if (_pd->atspi_translation_domain)
6679 return dgettext(_pd->atspi_translation_domain, _pd->name);
6685 //TIZEN_ONLY(20170110) : Ignore text from elm_object_text_set in accessible_name_get
6686 Elm_Atspi_Role role;
6687 eo_do(obj, role = elm_interface_atspi_accessible_role_get());
6688 if(role == ELM_ATSPI_ROLE_DIALOG)
6692 ret = elm_object_text_get(obj);
6693 if (!ret) return NULL;
6695 return _elm_widget_accessible_plain_name_get(obj, ret);
6697 //TIZEN_ONLY(20161111) add widget/widget_item description get/set
6699 _elm_widget_elm_interface_atspi_accessible_description_set(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data* _pd EINA_UNUSED, const char *description)
6701 if (_pd->description)
6702 eina_stringshare_del(_pd->description);
6704 _pd->description = eina_stringshare_add(description);
6707 EOLIAN static const char*
6708 _elm_widget_elm_interface_atspi_accessible_description_get(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *_pd EINA_UNUSED)
6710 const char *ret = NULL;
6711 eo_do_super(obj, ELM_WIDGET_CLASS, ret = elm_interface_atspi_accessible_description_get());
6712 if (ret) return ret;
6715 if (_pd->atspi_translation_domain)
6716 return dgettext(_pd->atspi_translation_domain, _pd->description);
6718 return _pd->description;
6722 //TIZEN_ONLY(20150713) : add atspi name setter to widget_item
6724 _elm_widget_item_elm_interface_atspi_accessible_name_set(Eo *obj EINA_UNUSED, Elm_Widget_Item_Data* _pd EINA_UNUSED, const char *name)
6727 eina_stringshare_del(_pd->name);
6729 _pd->name = eina_stringshare_add(name);
6733 _elm_widget_item_elm_interface_atspi_accessible_name_get(Eo *obj EINA_UNUSED, Elm_Widget_Item_Data *_pd EINA_UNUSED)
6735 //TIZEN_ONLY(20190922): add name callback, description callback.
6736 const char *ret = NULL;
6737 eo_do_super(obj, ELM_WIDGET_ITEM_CLASS, ret = elm_interface_atspi_accessible_name_get());
6738 if (ret) return ret;
6744 if (_pd->atspi_translation_domain)
6745 return dgettext(_pd->atspi_translation_domain, _pd->name);
6753 //TIZEN_ONLY(20161111) add widget/widget_item description get/set
6755 _elm_widget_item_elm_interface_atspi_accessible_description_set(Eo *obj EINA_UNUSED, Elm_Widget_Item_Data* _pd EINA_UNUSED, const char *description)
6757 if (_pd->description)
6758 eina_stringshare_del(_pd->description);
6760 _pd->description = eina_stringshare_add(description);
6764 _elm_widget_item_elm_interface_atspi_accessible_description_get(Eo *obj EINA_UNUSED, Elm_Widget_Item_Data *_pd EINA_UNUSED)
6766 const char *ret = NULL;
6767 eo_do_super(obj, ELM_WIDGET_ITEM_CLASS, ret = elm_interface_atspi_accessible_description_get());
6768 if (ret) return ret;
6771 if (_pd->atspi_translation_domain)
6772 return dgettext(_pd->atspi_translation_domain, _pd->description);
6774 return _pd->description;
6777 //TIZEN_ONLY(20150709) : spatially sort atspi children
6778 static int _sort_vertically(const void *data1, const void *data2)
6781 evas_object_geometry_get(data1, NULL, &y1, NULL, NULL);
6782 evas_object_geometry_get(data2, NULL, &y2, NULL, NULL);
6784 return y1 < y2 ? -1 : 1;
6787 static int _sort_horizontally(const void *data1, const void *data2)
6790 evas_object_geometry_get(data1, &x1, NULL, NULL, NULL);
6791 evas_object_geometry_get(data2, &x2, NULL, NULL, NULL);
6793 return x1 < x2 ? -1 : 1;
6796 static Eina_List *_lines_split(Eina_List *children)
6799 Eina_List *lines, *line, *l;
6800 Evas_Coord yl, y, hl, h;
6801 lines = line = NULL;
6803 if (!children) return NULL;
6805 EINA_LIST_FOREACH(children, l, c)
6807 evas_object_geometry_get(c, NULL, &yl, NULL, &hl);
6809 /* remove child if its height == 0 */
6813 EINA_LIST_FREE(children, c)
6815 evas_object_geometry_get(c, NULL, &y, NULL, &h);
6817 /* remove child if its height == 0 */
6818 if (h == 0 && !eo_isa(c, ELM_ATSPI_PROXY_CLASS)) continue;
6820 if ((yl + (int)(0.25 * hl)) >= y)
6823 line = eina_list_append(line,c);
6827 // finish current line & start new
6828 lines = eina_list_append(lines, line);
6830 line = eina_list_append(NULL, c);
6834 return eina_list_append(lines, line);
6838 // TIZEN_ONLY(20160705) - enable atspi_proxy to work
6840 _proxy_widget_move_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
6845 evas_object_geometry_get(obj, &x, &y, NULL, NULL);
6846 elm_atspi_bridge_utils_proxy_offset_set(proxy, x, y);
6851 _on_widget_del(void *data, Eo *obj EINA_UNUSED, const Eo_Event_Description *desc EINA_UNUSED, void *event_info EINA_UNUSED)
6854 // TIZEN_ONLY(20160705) - enable atspi_proxy to work
6855 evas_object_event_callback_del_full(obj, EVAS_CALLBACK_MOVE,
6856 _proxy_widget_move_cb, plug);
6862 // TIZEN_ONLY(20160705) - enable atspi_proxy to work
6864 _on_proxy_connected_cb(void *data, Eo *obj, const Eo_Event_Description *desc EINA_UNUSED, void *event_info EINA_UNUSED)
6867 Evas_Object *widget = data;
6869 evas_object_geometry_get(widget, &x, &y, NULL, NULL);
6870 elm_atspi_bridge_utils_proxy_offset_set(obj, x, y);
6872 evas_object_event_callback_add(widget, EVAS_CALLBACK_MOVE, _proxy_widget_move_cb, obj);
6878 //TIZEN_ONLY(20170621) handle atspi proxy connection at runtime
6880 _plug_type_proxy_get(Eo *obj, Evas_Object *widget)
6883 const char *plug_id;
6884 char *svcname, *svcnum;
6886 if ((plug_id = evas_object_data_get(widget, "___PLUGID")) != NULL)
6888 // TIZEN_ONLY(20160930) : endless recursion fix
6889 eo_do_super(obj, MY_CLASS, elm_interface_atspi_accessible_attribute_append("___PlugID", plug_id));
6891 proxy = evas_object_data_get(widget, "__widget_proxy");
6892 if (proxy) return proxy;
6894 if (_elm_atspi_bridge_plug_id_split(plug_id, &svcname, &svcnum))
6896 proxy = _elm_atspi_bridge_utils_proxy_create(obj, svcname, atoi(svcnum), ELM_ATSPI_PROXY_TYPE_PLUG);
6897 evas_object_data_set(widget, "__widget_proxy", proxy);
6898 eo_do(widget, eo_event_callback_add(EO_EV_DEL, _on_widget_del, proxy));
6899 eo_do(proxy, eo_event_callback_add(ELM_ATSPI_PROXY_EVENT_CONNECTED, _on_proxy_connected_cb, widget));
6900 elm_atspi_bridge_utils_proxy_connect(proxy);
6910 elm_widget_atspi_plug_type_proxy_get(Evas_Object *obj)
6912 Elm_Widget_Smart_Data *wd;
6913 Evas_Object *widget;
6916 wd = eo_data_scope_get(obj, ELM_WIDGET_CLASS);
6917 if (!wd) return NULL;
6920 EINA_LIST_FOREACH(wd->subobjs, l, widget)
6922 if (evas_object_data_get(widget, "___PLUGID"))
6923 proxy = _plug_type_proxy_get(obj, widget);
6930 EOLIAN static Eina_List*
6931 _elm_widget_elm_interface_atspi_accessible_children_get(Eo *obj, Elm_Widget_Smart_Data *pd EINA_UNUSED)
6933 Eina_List *l, *accs = NULL;
6934 Elm_Widget_Smart_Data *wd;
6935 Evas_Object *widget;
6936 // TIZEN_ONLY(20160824): Do not append a child, if its accessible parent is different with widget parent
6940 wd = eo_data_scope_get(obj, ELM_WIDGET_CLASS);
6941 if (!wd) return NULL;
6943 EINA_LIST_FOREACH(wd->subobjs, l, widget)
6945 const char *type = evas_object_type_get(widget);
6947 // Ugly Tizen hack to integrate AT-SPI2 accessibility provided by WebKit/Chromium with elementary one.
6948 // This wrapper class should be implemented in Webkit/Chromium EFL ports
6949 if (type && (!strcmp(type, "EWebView") || !strcmp(type, "WebView"))) {
6950 elm_atspi_ewk_wrapper_a11y_init(obj, widget);
6955 EINA_LIST_FOREACH(wd->subobjs, l, widget)
6957 // TIZEN_ONLY(20160824): Do not append a child, if its accessible parent is different with widget parent
6958 if (eo_isa(widget, ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN)) {
6959 eo_do(widget, parent = elm_interface_atspi_accessible_parent_get());
6960 if (parent && (parent != obj)) continue;
6963 // TIZEN_ONLY(20160705) - enable atspi_proxy to work
6964 /* This assumes that only one proxy exists in obj */
6967 proxy = _plug_type_proxy_get(obj, widget);
6970 accs = eina_list_append(accs, proxy);
6976 if (!elm_object_widget_check(widget)) continue;
6977 if (eo_isa(widget, ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN))
6978 accs = eina_list_append(accs, widget);
6980 //TIZEN_ONLY(20150709) : spatially sort atspi children
6981 // sort children using its top-left coordinate
6982 accs = eina_list_sort(accs, -1, _sort_vertically);
6983 Eina_List *line, *lines = _lines_split(accs);
6985 EINA_LIST_FREE(lines, line)
6986 accs = eina_list_merge(accs, eina_list_sort(line, -1, _sort_horizontally));
6992 accs = eina_list_remove(accs, proxy);
6993 EINA_LIST_FOREACH(accs, l, widget)
6995 if (eo_isa(widget, ELM_ACCESS_CLASS))
6997 Elm_Access_Info *info = _elm_access_info_get(widget);
6998 if (!info) continue;
6999 if (obj == info->part_object)
7009 accs = eina_list_append_relative(accs, proxy, deputy);
7016 _elm_widget_elm_interface_atspi_accessible_parent_get(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *pd)
7019 eo_do_super(obj, ELM_WIDGET_CLASS, ret = elm_interface_atspi_accessible_parent_get());
7021 return ret ? ret : pd->parent_obj;
7024 //TIZEN_ONLY(20161107): enhance elm_atspi_accessible_can_highlight_set to set can_hihglight property to its children
7026 _elm_widget_highlightable(Evas_Object *obj)
7030 Elm_Widget_Smart_Data *wd = eo_data_scope_get(obj, ELM_WIDGET_CLASS);
7031 if (!wd) return EINA_FALSE;
7032 if (!wd->can_highlight) return EINA_FALSE;
7034 eo_do(obj, parent = elm_interface_atspi_accessible_parent_get());
7035 while (parent && !eo_isa(parent, ELM_ATSPI_APP_OBJECT_CLASS))
7037 //TIZEN_ONLY(20160929) : atspi: Improves how to find the can_highlight of the widget
7038 if (!_elm_widget_can_highlight_get_by_class(parent)) return EINA_FALSE;
7040 eo_do(parent, parent = elm_interface_atspi_accessible_parent_get());
7046 EOLIAN static Elm_Atspi_State_Set
7047 _elm_widget_elm_interface_atspi_accessible_state_set_get(Eo *obj, Elm_Widget_Smart_Data *pd)
7049 Elm_Atspi_State_Set states = 0;
7051 eo_do_super(obj, ELM_WIDGET_CLASS, states = elm_interface_atspi_accessible_state_set_get());
7053 if (evas_object_visible_get(obj))
7055 STATE_TYPE_SET(states, ELM_ATSPI_STATE_VISIBLE);
7056 if (_elm_widget_onscreen_is(obj))
7057 STATE_TYPE_SET(states, ELM_ATSPI_STATE_SHOWING);
7059 if (!elm_widget_child_can_focus_get(obj))
7061 if (elm_object_focus_allow_get(obj))
7062 STATE_TYPE_SET(states, ELM_ATSPI_STATE_FOCUSABLE);
7063 if (elm_object_focus_get(obj))
7064 STATE_TYPE_SET(states, ELM_ATSPI_STATE_FOCUSED);
7066 if (!elm_object_disabled_get(obj))
7068 STATE_TYPE_SET(states, ELM_ATSPI_STATE_ENABLED);
7069 STATE_TYPE_SET(states, ELM_ATSPI_STATE_SENSITIVE);
7072 //TIZEN_ONLY(20170717) : expose highlight information on atspi
7073 if (_elm_widget_highlightable(obj) && _accessible_object_on_scroll_is(obj))
7074 STATE_TYPE_SET(states, ELM_ATSPI_STATE_HIGHLIGHTABLE);
7076 STATE_TYPE_UNSET(states, ELM_ATSPI_STATE_HIGHLIGHTABLE);
7078 if (_elm_object_accessibility_currently_highlighted_get() == (void*)pd->obj)
7079 STATE_TYPE_SET(states, ELM_ATSPI_STATE_HIGHLIGHTED);
7085 //TIZEN_ONLY(20160729): attributes_get, append APIs added/updated.
7086 EOLIAN static Eina_List*
7087 _elm_widget_elm_interface_atspi_accessible_attributes_get(Eo *obj, Elm_Widget_Smart_Data *pd EINA_UNUSED)
7089 Eina_List *attr_list = NULL;
7090 // TIZEN_ONLY(20160930) : endless recursion fix
7091 eo_do_super(obj, MY_CLASS, attr_list = elm_interface_atspi_accessible_attributes_get());
7093 //Add type and style information in addition.
7094 Elm_Atspi_Attribute *attr = NULL;
7095 attr = calloc(1, sizeof(Elm_Atspi_Attribute));
7098 attr->key = eina_stringshare_add("type");
7099 attr->value = eina_stringshare_add(elm_widget_type_get(obj));
7100 attr_list = eina_list_append(attr_list, attr);
7103 attr = calloc(1, sizeof(Elm_Atspi_Attribute));
7106 attr->key = eina_stringshare_add("style");
7107 attr->value = eina_stringshare_add(elm_widget_style_get(obj));
7108 attr_list = eina_list_append(attr_list, attr);
7114 //TIZEN_ONLY(20150709) : atspi relations api
7115 EOLIAN static Elm_Atspi_Relation_Set
7116 _elm_widget_elm_interface_atspi_accessible_relation_set_get(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd)
7118 return elm_atspi_relation_set_clone(&sd->atspi_custom_relations);
7121 EOLIAN static Elm_Atspi_Relation_Set
7122 _elm_widget_item_elm_interface_atspi_accessible_relation_set_get(Eo *obj EINA_UNUSED, Elm_Widget_Item_Data *sd)
7124 return elm_atspi_relation_set_clone(&sd->atspi_custom_relations);
7128 _elm_widget_elm_interface_atspi_accessible_relationships_clear(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd)
7130 elm_atspi_relation_set_free(&sd->atspi_custom_relations);
7131 sd->atspi_custom_relations = NULL;
7136 _elm_widget_item_elm_interface_atspi_accessible_relationships_clear(Eo *obj EINA_UNUSED, Elm_Widget_Item_Data *sd)
7138 elm_atspi_relation_set_free(&sd->atspi_custom_relations);
7139 sd->atspi_custom_relations = NULL;
7144 _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)
7157 evas_object_geometry_get(sd->view, x, y, w, h);
7160 Ecore_Evas *ee = ecore_evas_ecore_evas_get(evas_object_evas_get(sd->view));
7162 ecore_evas_geometry_get(ee, &ee_x, &ee_y, NULL, NULL);
7168 EOLIAN static Eina_Bool
7169 _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)
7175 _elm_widget_item_elm_interface_atspi_component_layer_get(Eo *obj EINA_UNUSED, Elm_Widget_Item_Data *sd EINA_UNUSED)
7179 return evas_object_layer_get(sd->view);
7182 EOLIAN static Eina_Bool
7183 _elm_widget_item_elm_interface_atspi_component_focus_grab(Eo *obj EINA_UNUSED, Elm_Widget_Item_Data *_pd EINA_UNUSED)
7185 elm_object_item_focus_set(obj, EINA_TRUE);
7186 return elm_object_item_focus_get(obj);
7189 //TIZEN_ONLY(20160329): atspi: implement HighlightGrab and HighlightClear methods
7191 EOLIAN static Eina_Bool
7192 _elm_widget_item_elm_interface_atspi_component_highlight_grab(Eo *obj, Elm_Widget_Item_Data *sd)
7194 if (!sd) return EINA_FALSE;
7195 if (!sd->view) return EINA_FALSE;
7196 //TIZEN_ONLY(20171011) : atspi : During the highlight grab, out signal is not sent.
7197 _elm_widget_accessibility_highlight_grabbing_set(sd->view, EINA_TRUE);
7200 //TIZEN_ONLY(20170119): Show the object highlighted by highlight_grab when the object is completely out of the scroll
7201 _accessible_highlight_region_show(sd->view);
7204 if (!sd->eo_obj) return EINA_FALSE;
7205 elm_object_accessibility_highlight_set(sd->eo_obj, EINA_TRUE);
7207 if (!obj) return EINA_FALSE;
7208 elm_interface_atspi_accessible_state_changed_signal_emit(obj, ELM_ATSPI_STATE_HIGHLIGHTED, EINA_TRUE);
7210 //TIZEN_ONLY(20170412) Make atspi,(un)highlighted work on widget item
7211 evas_object_smart_callback_call(sd->widget, SIG_WIDGET_ATSPI_HIGHLIGHTED, obj);
7213 //TIZEN_ONLY(20171011) : atspi : During the highlight grab, out signal is not sent.
7214 _elm_widget_accessibility_highlight_grabbing_set(sd->view, EINA_FALSE);
7219 EOLIAN static Eina_Bool
7220 _elm_widget_item_elm_interface_atspi_component_highlight_clear(Eo *obj, Elm_Widget_Item_Data *sd)
7222 if (!obj) return EINA_FALSE;
7223 elm_object_accessibility_highlight_set(sd->eo_obj, EINA_FALSE);
7224 elm_interface_atspi_accessible_state_changed_signal_emit(obj, ELM_ATSPI_STATE_HIGHLIGHTED, EINA_FALSE);
7226 //TIZEN_ONLY(20170412) Make atspi,(un)highlighted work on widget item
7227 evas_object_smart_callback_call(sd->widget, SIG_WIDGET_ATSPI_UNHIGHLIGHTED, obj);
7233 EOLIAN static double
7234 _elm_widget_item_elm_interface_atspi_component_alpha_get(Eo *obj EINA_UNUSED, Elm_Widget_Item_Data *sd EINA_UNUSED)
7238 if (!sd->view) return -1.0;
7239 evas_object_color_get(sd->view, NULL, NULL, NULL, &alpha);
7240 return (double)alpha / 255.0;
7243 //TIZEN_ONLY(20150717) add widget name setter
7245 _elm_widget_elm_interface_atspi_accessible_name_set(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data* _pd EINA_UNUSED, const char *name)
7248 eina_stringshare_del(_pd->name);
7250 _pd->name = eina_stringshare_add(name);
7254 //TIZEN_ONLY(20160329): widget: improve accessibile_at_point getter (a8aff0423202b9a55dbb3843205875226678fbd6)
7256 _coordinate_system_based_point_translate(Eo *obj, Eina_Bool screen_coords, int *x, int *y)
7264 ee = ecore_evas_ecore_evas_get(evas_object_evas_get(obj));
7267 ecore_evas_geometry_get(ee, &ee_x, &ee_y, NULL, NULL);
7273 static Evas_Object *
7274 _parent_get(Evas_Object *obj)
7276 Evas_Object *parent;
7278 parent = evas_object_smart_parent_get(obj);
7281 if (strcmp("Elm_Win", eo_class_name_get(eo_class_get(obj))))
7282 parent = elm_widget_parent_get(obj);
7289 _is_inside(Evas_Object *obj, int x, int y)
7291 Eina_Bool ret = EINA_TRUE;
7296 if (eo_isa(obj, ELM_WIDGET_ITEM_CLASS))
7298 Elm_Widget_Item_Data *id = eo_data_scope_get(obj, ELM_WIDGET_ITEM_CLASS);
7299 evas_object_geometry_get(id->view, &cx, &cy, &cw, &ch);
7302 evas_object_geometry_get(obj, &cx, &cy, &cw, &ch);
7304 /* check the point is out of bound */
7305 if (x < cx || x > cx + cw || y < cy || y > cy + ch)
7313 _is_ancestor_of(Evas_Object *smart_parent, Evas_Object *obj)
7315 Eina_Bool ret = EINA_FALSE;
7316 Evas_Object *parent = elm_widget_parent_get(obj);
7319 /* No need to check more, the smart_parent is parent of obj */
7320 if (smart_parent == parent)
7325 parent = elm_widget_parent_get(parent);
7331 static int _sort_by_size(const void *data1, const void *data2)
7336 evas_object_geometry_get(data1, NULL, NULL, &w, &h);
7337 evas_object_geometry_get(data2, NULL, NULL, &w2, &h2);
7339 if ((w * h) > (w2 * h2)) return 1;
7344 _elm_widget_atspi_role_acceptable_check(Eo *obj)
7346 Elm_Atspi_Role role;
7347 eo_do(obj, role = elm_interface_atspi_accessible_role_get());
7351 case ELM_ATSPI_ROLE_APPLICATION:
7352 case ELM_ATSPI_ROLE_FILLER:
7353 case ELM_ATSPI_ROLE_SCROLL_PANE:
7354 case ELM_ATSPI_ROLE_SPLIT_PANE:
7355 case ELM_ATSPI_ROLE_WINDOW:
7356 case ELM_ATSPI_ROLE_IMAGE:
7357 case ELM_ATSPI_ROLE_LIST:
7358 case ELM_ATSPI_ROLE_ICON:
7359 case ELM_ATSPI_ROLE_TOOL_BAR:
7360 case ELM_ATSPI_ROLE_REDUNDANT_OBJECT:
7361 case ELM_ATSPI_ROLE_COLOR_CHOOSER:
7362 case ELM_ATSPI_ROLE_TREE_TABLE:
7363 case ELM_ATSPI_ROLE_PAGE_TAB_LIST:
7364 case ELM_ATSPI_ROLE_PAGE_TAB:
7365 case ELM_ATSPI_ROLE_SPIN_BUTTON:
7366 case ELM_ATSPI_ROLE_INPUT_METHOD_WINDOW:
7367 case ELM_ATSPI_ROLE_EMBEDDED:
7368 case ELM_ATSPI_ROLE_INVALID:
7369 case ELM_ATSPI_ROLE_NOTIFICATION:
7370 case ELM_ATSPI_ROLE_DATE_EDITOR:
7380 _child_object_at_point_get(Eo *obj, int x, int y)
7382 Eina_List *l, *l_next, *children, *valid_children = NULL;
7387 eo_do(obj, children = elm_interface_atspi_accessible_children_get());
7389 EINA_LIST_FOREACH(children, l, child)
7391 if (_is_inside(child, x, y))
7392 valid_children = eina_list_append(valid_children, child);
7395 EINA_LIST_FOREACH_SAFE(valid_children, l, l_next, child)
7397 eo_do(child, children = elm_interface_atspi_accessible_children_get());
7399 /* do not use unacceptable leaf node */
7400 if (!_elm_widget_atspi_role_acceptable_check(child) &&
7401 eina_list_count(children) == 0)
7402 valid_children = eina_list_remove_list(valid_children, l);
7405 count = eina_list_count(valid_children);
7408 valid_children = eina_list_sort(valid_children, -1, _sort_by_size);
7409 target = eina_list_nth(valid_children, 0);
7411 return _child_object_at_point_get(target, x, y);
7418 _acceptable_child_is(Eo *obj)
7420 Elm_Atspi_Role role;
7421 Eina_List *children;
7422 Elm_Atspi_State_Set ss;
7424 eo_do(obj, role = elm_interface_atspi_accessible_role_get());
7427 case ELM_ATSPI_ROLE_IMAGE:
7428 case ELM_ATSPI_ROLE_ICON:
7429 /* remove unacceptable leaf node */
7430 eo_do(obj, children = elm_interface_atspi_accessible_children_get());
7431 if (!children) return EINA_FALSE;
7434 case ELM_ATSPI_ROLE_PANEL:
7435 /* remove closed panel fron children list */
7436 eo_do(obj, ss = elm_interface_atspi_accessible_state_set_get());
7437 if (!STATE_TYPE_GET(ss, ELM_ATSPI_STATE_SHOWING)) return EINA_FALSE;
7448 _accessible_at_point_top_down_get(Eo *obj, Elm_Widget_Smart_Data *_pd EINA_UNUSED, Eina_Bool screen_coords, int x, int y)
7450 Eina_List *l, *l2, *children, *valid_children = NULL;
7452 Evas_Object *stack_item;
7454 // TIZEN_ONLY(20160705) - enable atspi_proxy to work
7456 Evas_Coord px, py, pw, ph;
7459 _coordinate_system_based_point_translate(obj, screen_coords, &x, &y);
7461 eo_do(obj, children = elm_interface_atspi_accessible_children_get());
7463 EINA_LIST_FOREACH(children, l2, child)
7465 if (_is_inside(child, x, y) && _acceptable_child_is(child))
7466 valid_children = eina_list_append(valid_children, child);
7469 /* If there is only one valid child at point, then return it.
7470 The evas_tree_objects_at_xy_get could not find proper object,
7471 if application does not have well aligned objects. */
7472 if (eina_list_count(valid_children) == 1)
7474 eina_list_free(children);
7475 child = eina_list_nth(valid_children, 0);
7479 /* Get evas_object stacked at given x,y coordinates starting from top */
7480 Eina_List *stack = evas_tree_objects_at_xy_get(evas_object_evas_get(obj), NULL, x, y);
7481 /* Foreach stacked object starting from top */
7482 EINA_LIST_FOREACH(stack, l, stack_item)
7484 /* Foreach at-spi valid children traverse stack_item evas_objects hierarchy */
7485 EINA_LIST_FOREACH(valid_children, l2, child)
7487 /* Compare object used to compare with stacked evas objects */
7488 compare_obj = child;
7489 /* In case of widget_items compare should be different then elm_widget_ item object */
7490 if (eo_isa(child, ELM_WIDGET_ITEM_CLASS))
7492 Elm_Widget_Item_Data *id = eo_data_scope_get(child, ELM_WIDGET_ITEM_CLASS);
7493 compare_obj = id->view;
7494 if (TIZEN_PROFILE_WEARABLE)
7496 Eo* it_view = evas_object_image_source_get(stack_item);
7497 if (it_view && it_view == compare_obj)
7499 eina_list_free(children);
7500 eina_list_free(stack);
7505 /* In case of access object compare should be 'wrapped' evas_object */
7506 if (eo_isa(child, ELM_ACCESS_CLASS))
7508 Elm_Access_Info *info = _elm_access_info_get(child);
7509 if (!info) continue;
7510 compare_obj = info->part_object;
7512 /* In case of widget is registerd by elm_access_object_register */
7513 Evas_Object *ao = elm_access_object_get(child);
7516 eina_list_free(children);
7517 eina_list_free(stack);
7521 /* In case of ewk wrapper object compare with internal ewk_view evas_object */
7522 if (eo_isa(child, ELM_ATSPI_EWK_WRAPPER_CLASS))
7524 compare_obj = elm_atspi_ewk_wrapper_ewk_view_get(child);
7527 /* If spacial eo children do not have backing evas_object continue with search */
7531 Evas_Object *smart_parent = stack_item;
7532 while (smart_parent)
7534 if (smart_parent == compare_obj)
7536 eina_list_free(children);
7537 eina_list_free(stack);
7541 // TIZEN_ONLY(20160705) - enable atspi_proxy to work
7542 proxy = evas_object_data_get(smart_parent, "__widget_proxy");
7545 evas_object_geometry_get(smart_parent, &px, &py, &pw, &ph);
7546 if (x >= px && x <= px + pw && y >= py && y <= py +ph)
7548 eina_list_free(children);
7549 eina_list_free(stack);
7555 smart_parent = _parent_get(smart_parent);
7556 if (_is_ancestor_of(smart_parent, obj)) break;
7561 eina_list_free(children);
7562 eina_list_free(stack);
7566 static int _sort_by_repeat_events(const void *data1, const void *data2)
7568 Evas_Object *ao1, *ao2;
7569 Eina_Bool repeat1, repeat2;
7571 ao1 = elm_access_object_get(data1);
7572 ao2 = elm_access_object_get(data2);
7574 repeat1 = evas_object_repeat_events_get(data1);
7575 repeat2 = evas_object_repeat_events_get(data2);
7577 if (repeat1 != repeat2)
7579 if (repeat1 && !ao1) return 1;
7583 if (repeat1 && !ao1 && ao2) return 1;
7589 static Eo *_item_at_point_get(Evas_Object *obj, int x, int y)
7592 Eina_List *l, *children;
7594 eo_do(obj, children = elm_interface_atspi_accessible_children_get());
7596 EINA_LIST_FOREACH(children, l, child)
7598 if (_is_inside(child, x, y)) return child;
7601 ERR("No child at point (%d, %d) on object %p", x, y, obj);
7606 _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)
7608 Elm_Atspi_Role role;
7610 Evas_Object *stack_item;
7612 eo_do(obj, role = elm_interface_atspi_accessible_role_get());
7616 case ELM_ATSPI_ROLE_WINDOW:
7617 case ELM_ATSPI_ROLE_INPUT_METHOD_WINDOW:
7618 case ELM_ATSPI_ROLE_DIALOG:
7619 case ELM_ATSPI_ROLE_PAGE_TAB:
7620 case ELM_ATSPI_ROLE_POPUP_MENU:
7621 case ELM_ATSPI_ROLE_PANEL:
7622 DBG("Find accessible from bottom");
7626 return _accessible_at_point_top_down_get(obj, _pd, screen_coords, x, y);
7629 _coordinate_system_based_point_translate(obj, screen_coords, &x, &y);
7631 Eina_List *stack = evas_tree_objects_at_xy_get(evas_object_evas_get(obj), NULL, x, y);
7632 stack = eina_list_sort(stack, -1, _sort_by_repeat_events);
7634 EINA_LIST_FOREACH(stack, l, stack_item)
7636 Evas_Object *smart_parent = stack_item;
7637 while (smart_parent)
7639 /* If parent equals to obj, it is not necessary to go upper.
7640 So the top down logic would be better than NULL return. */
7641 if (smart_parent == obj)
7642 return _accessible_at_point_top_down_get(obj, _pd, screen_coords, x, y);
7644 Evas_Object *ao = elm_access_object_get(smart_parent);
7647 if (eo_isa(smart_parent, ELM_INTERFACE_ATSPI_ACCESSIBLE_MIXIN))
7649 Eina_Bool acceptable = EINA_FALSE;
7651 eo_do(smart_parent, role = elm_interface_atspi_accessible_role_get());
7654 case ELM_ATSPI_ROLE_FILLER: /* ex: View of colorselector item is layout */
7655 case ELM_ATSPI_ROLE_ICON:
7656 case ELM_ATSPI_ROLE_IMAGE:
7657 case ELM_ATSPI_ROLE_REDUNDANT_OBJECT:
7658 case ELM_ATSPI_ROLE_WINDOW:
7659 DBG("Go for parent: %s (%p)\n", evas_object_type_get(smart_parent), smart_parent);
7662 case ELM_ATSPI_ROLE_LIST:
7663 item_child = _item_at_point_get(smart_parent, x, y);
7664 if (TIZEN_PROFILE_WEARABLE)
7666 item_child = _child_object_at_point_get(item_child, x, y);
7673 acceptable = EINA_TRUE;
7677 if (acceptable) return smart_parent;
7680 smart_parent = _parent_get(smart_parent);
7683 return _accessible_at_point_top_down_get(obj, _pd, screen_coords, x, y);
7687 //TIZEN_ONLY(20150709) add relations atpi
7688 EOLIAN static Eina_Bool
7689 _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)
7691 return elm_atspi_relation_set_relation_append(&sd->atspi_custom_relations, type, relation_obj);
7695 _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)
7697 elm_atspi_relation_set_relation_remove(&sd->atspi_custom_relations, type, relation_obj);
7700 EOLIAN static Eina_Bool
7701 _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)
7703 return elm_atspi_relation_set_relation_append(&sd->atspi_custom_relations, type, relation_obj);
7707 _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)
7709 elm_atspi_relation_set_relation_remove(&sd->atspi_custom_relations, type, relation_obj);
7713 //TIZEN_ONLY(20150731) : add i18n support for name and description
7715 _elm_widget_elm_interface_atspi_accessible_translation_domain_set(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *_pd, const char *domain)
7717 eina_stringshare_replace(&_pd->atspi_translation_domain, domain);
7720 EOLIAN static const char*
7721 _elm_widget_elm_interface_atspi_accessible_translation_domain_get(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *_pd)
7723 return _pd->atspi_translation_domain;
7727 _elm_widget_item_elm_interface_atspi_accessible_translation_domain_set(Eo *obj EINA_UNUSED, Elm_Widget_Item_Data *_pd, const char *domain)
7729 eina_stringshare_replace(&_pd->atspi_translation_domain, domain);
7732 EOLIAN static const char*
7733 _elm_widget_item_elm_interface_atspi_accessible_translation_domain_get(Eo *obj EINA_UNUSED, Elm_Widget_Item_Data *_pd)
7735 return _pd->atspi_translation_domain;
7738 //TIZEN_ONLY(20160726): add API elm_atspi_accessible_can_highlight_set/get
7740 _children_highlight_check(Eo *obj)
7742 Eina_List *children, *l;
7745 if (_elm_object_accessibility_currently_highlighted_get() == (void *)obj)
7747 eo_do(obj, elm_interface_atspi_component_highlight_clear());
7751 eo_do(obj, children = elm_interface_atspi_accessible_children_get());
7752 EINA_LIST_FOREACH(children, l, child)
7754 if (_children_highlight_check(child)) return EINA_TRUE;
7761 _elm_widget_elm_interface_atspi_accessible_can_highlight_set(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *_pd, Eina_Bool can_highlight)
7763 if (!can_highlight) _children_highlight_check(obj);
7764 _pd->can_highlight = !!can_highlight;
7767 EOLIAN static Eina_Bool
7768 _elm_widget_elm_interface_atspi_accessible_can_highlight_get(Eo *obj, Elm_Widget_Smart_Data *_pd EINA_UNUSED)
7770 return _elm_widget_highlightable(obj);
7774 _elm_widget_item_elm_interface_atspi_accessible_can_highlight_set(Eo *obj EINA_UNUSED, Elm_Widget_Item_Data *_pd, Eina_Bool can_highlight)
7776 if (!can_highlight) _children_highlight_check(obj);
7777 _pd->can_highlight = !!can_highlight;
7780 EOLIAN static Eina_Bool
7781 _elm_widget_item_elm_interface_atspi_accessible_can_highlight_get(Eo *obj, Elm_Widget_Item_Data *_pd EINA_UNUSED)
7783 return _elm_widget_item_highlightable(obj);
7787 //TIZEN_ONLY(20160622): Override Paragraph Direction APIs
7789 _elm_widget_evas_object_paragraph_direction_set_internal(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd, Evas_BiDi_Direction dir)
7794 if (sd->on_destroy) return;
7796 EINA_LIST_FOREACH(sd->subobjs, l, child)
7798 if (_elm_widget_is(child))
7800 Elm_Widget_Smart_Data *sdc = eo_data_scope_get(child, MY_CLASS);
7802 if (sdc->inherit_paragraph_direction &&
7803 (sdc->paragraph_direction != dir))
7805 sdc->paragraph_direction = dir;
7806 _elm_widget_evas_object_paragraph_direction_set_internal(child, sdc, dir);
7807 eo_do_super(child, MY_CLASS, evas_obj_paragraph_direction_set(dir));
7811 /* FIXME: There is no way to handle non-widget child object.
7812 * If a non-widget child object has smart parent, it will get the direction
7813 * from the smart parent. */
7818 _elm_widget_evas_object_paragraph_direction_set(Eo *obj, Elm_Widget_Smart_Data *sd, Evas_BiDi_Direction dir)
7820 if ((!(sd->inherit_paragraph_direction) && (sd->paragraph_direction == dir)) ||
7821 (sd->inherit_paragraph_direction && (dir == EVAS_BIDI_DIRECTION_INHERIT)))
7824 if (dir == EVAS_BIDI_DIRECTION_INHERIT)
7826 sd->inherit_paragraph_direction = EINA_TRUE;
7827 Evas_BiDi_Direction parent_dir = EVAS_BIDI_DIRECTION_NEUTRAL;
7830 parent_dir = evas_object_paragraph_direction_get(sd->parent_obj);
7832 if (parent_dir != sd->paragraph_direction)
7834 sd->paragraph_direction = parent_dir;
7835 _elm_widget_evas_object_paragraph_direction_set_internal(obj, sd, parent_dir);
7840 sd->inherit_paragraph_direction = EINA_FALSE;
7841 sd->paragraph_direction = dir;
7842 _elm_widget_evas_object_paragraph_direction_set_internal(obj, sd, dir);
7845 eo_do_super(obj, MY_CLASS, evas_obj_paragraph_direction_set(dir));
7850 //TIZEN_ONLY(20161013): clean up elm color class feature
7852 _edje_color_class_free(void *data)
7854 Edje_Color_Class *cc = data;
7856 if (cc->name) eina_stringshare_del(cc->name);
7861 _elm_widget_edje_class_get(const Eo_Class *klass, const char *style, const char *part)
7864 Eina_Stringshare *str;
7866 buf = eina_strbuf_new();
7868 eina_strbuf_append(buf, strchr(eo_class_name_get(klass), '_') + 1);
7869 eina_strbuf_tolower(buf);
7873 eina_strbuf_append_printf(buf, "/%s/%s", style, part);
7877 eina_strbuf_append_printf(buf, "/%s", part);
7880 str = eina_stringshare_add(eina_strbuf_string_get(buf));
7882 eina_strbuf_free(buf);
7886 /* TIZEN_ONLY(20161025): Apply color_class parent-child relationship */
7888 _elm_widget_color_class_set_internal(Evas_Object *obj, Evas_Object *edje, const char *color_class,
7889 int r, int g, int b, int a,
7890 int r2, int g2, int b2, int a2,
7891 int r3, int g3, int b3, int a3)
7893 Eina_Bool int_ret = EINA_TRUE;
7894 Eina_Stringshare *buf;
7895 int temp_color[3][4] = { { r, g, b, a },
7897 { r3, g3, b3, a3 } };
7899 if (!color_class) return EINA_FALSE;
7901 buf = _elm_widget_edje_class_get(eo_class_get(obj), NULL, color_class);
7903 #define TEMP_COLOR(x, y) \
7904 ((temp_color[x][y] == -1) ? &temp_color[x][y] : NULL)
7906 edje_object_color_class_get(edje, buf,
7907 TEMP_COLOR(0, 0), TEMP_COLOR(0, 1), TEMP_COLOR(0, 2), TEMP_COLOR(0, 3),
7908 TEMP_COLOR(1, 0), TEMP_COLOR(1, 1), TEMP_COLOR(1, 2), TEMP_COLOR(1, 3),
7909 TEMP_COLOR(2, 0), TEMP_COLOR(2, 1), TEMP_COLOR(2, 2), TEMP_COLOR(2, 3));
7913 #define TEMP_COLOR(x, y) \
7914 ((temp_color[x][y] == -1) ? 0 : temp_color[x][y])
7916 int_ret &= edje_object_color_class_set(edje, buf,
7917 TEMP_COLOR(0, 0), TEMP_COLOR(0, 1), TEMP_COLOR(0, 2), TEMP_COLOR(0, 3),
7918 TEMP_COLOR(1, 0), TEMP_COLOR(1, 1), TEMP_COLOR(1, 2), TEMP_COLOR(1, 3),
7919 TEMP_COLOR(2, 0), TEMP_COLOR(2, 1), TEMP_COLOR(2, 2), TEMP_COLOR(2, 3));
7923 eina_stringshare_del(buf);
7929 _elm_widget_color_class_get_internal(Evas_Object *obj, Evas_Object *edje, const char *color_class,
7930 int *r, int *g, int *b, int *a,
7931 int *r2, int *g2, int *b2, int *a2,
7932 int *r3, int *g3, int *b3, int *a3)
7934 Eina_Bool int_ret = EINA_TRUE;
7935 Eina_Stringshare *buf;
7937 if (!color_class) return EINA_FALSE;
7939 buf = _elm_widget_edje_class_get(eo_class_get(obj), elm_widget_style_get(obj), color_class);
7941 int_ret &= edje_object_color_class_get(edje, buf,
7946 eina_stringshare_del(buf);
7953 _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)
7956 Eina_Bool int_ret = EINA_TRUE;
7958 if (!eo_isa(obj, ELM_LAYOUT_CLASS)) return EINA_FALSE;
7960 edje = elm_layout_edje_get(obj);
7961 int_ret &= _elm_widget_color_class_set_internal(obj, edje, color_class,
7970 _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)
7973 Eina_Bool int_ret = EINA_TRUE;
7975 if (!eo_isa(obj, ELM_LAYOUT_CLASS)) return EINA_FALSE;
7977 edje = elm_layout_edje_get(obj);
7978 int_ret &= _elm_widget_color_class_get_internal(obj, edje, color_class,
7980 NULL, NULL, NULL, NULL,
7981 NULL, NULL, NULL, NULL);
7987 _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)
7990 Eina_Bool int_ret = EINA_TRUE;
7992 if (!eo_isa(obj, ELM_LAYOUT_CLASS)) return EINA_FALSE;
7994 edje = elm_layout_edje_get(obj);
7995 int_ret &= _elm_widget_color_class_set_internal(obj, edje, color_class,
8004 _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)
8007 Eina_Bool int_ret = EINA_TRUE;
8009 if (!eo_isa(obj, ELM_LAYOUT_CLASS)) return EINA_FALSE;
8011 edje = elm_layout_edje_get(obj);
8012 int_ret &= _elm_widget_color_class_get_internal(obj, edje, color_class,
8013 NULL, NULL, NULL, NULL,
8015 NULL, NULL, NULL, NULL);
8021 _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)
8024 Eina_Bool int_ret = EINA_TRUE;
8026 if (!eo_isa(obj, ELM_LAYOUT_CLASS)) return EINA_FALSE;
8028 edje = elm_layout_edje_get(obj);
8029 int_ret &= _elm_widget_color_class_set_internal(obj, edje, color_class,
8038 _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)
8041 Eina_Bool int_ret = EINA_TRUE;
8043 if (!eo_isa(obj, ELM_LAYOUT_CLASS)) return EINA_FALSE;
8045 edje = elm_layout_edje_get(obj);
8046 int_ret &= _elm_widget_color_class_get_internal(obj, edje, color_class,
8047 NULL, NULL, NULL, NULL,
8048 NULL, NULL, NULL, NULL,
8055 _elm_widget_class_color_del(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd, const char *color_class)
8057 Eina_Stringshare *buf;
8059 if (!eo_isa(obj, ELM_LAYOUT_CLASS)) return;
8061 buf = _elm_widget_edje_class_get(eo_class_get(obj), NULL, color_class);
8062 edje_object_color_class_del(sd->resize_obj, buf);
8063 eina_stringshare_del(buf);
8067 _elm_widget_class_color_clear(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *sd)
8069 if (!eo_isa(obj, ELM_LAYOUT_CLASS)) return;
8070 edje_object_color_class_clear(sd->resize_obj);
8073 #define ELM_COLOR_CLASS_UPDATE(obj, hash, cond) \
8074 Evas_Object *edje = NULL; \
8075 Eina_Iterator *itr; \
8076 Edje_Color_Class *cc; \
8077 Eina_Bool int_ret = EINA_TRUE; \
8078 if (cond) return EINA_FALSE; \
8079 if (eo_isa(obj, ELM_LAYOUT_CLASS)) \
8080 edje = elm_layout_edje_get(obj); \
8081 else if (eo_isa(obj, EDJE_OBJECT_CLASS)) \
8083 if (!edje) return EINA_FALSE; \
8084 itr = eina_hash_iterator_data_new(hash); \
8085 EINA_ITERATOR_FOREACH(itr, cc) \
8087 int_ret &= edje_object_color_class_set(edje, cc->name, \
8088 cc->r, cc->g, cc->b, cc->a, \
8089 cc->r2, cc->g2, cc->b2, cc->a2, \
8090 cc->r3, cc->g3, cc->b3, cc->a3); \
8092 eina_iterator_free(itr); \
8096 #define CHECK_BOUND(x) \
8097 if (x > 0xff) x = 0xff; \
8098 else if (x < 0) x = 0
8100 #define ELM_COLOR_CLASS_SET_START(obj, cr, cg, cb, ca) \
8101 Eina_Bool int_ret = EINA_FALSE; \
8102 Edje_Color_Class *cc = NULL; \
8103 Eina_Stringshare *buf; \
8104 buf = _elm_widget_edje_class_get(eo_class_get(obj), NULL, color_class); \
8109 _elm_color_unpremul(a, &r, &g, &b); \
8110 if (!sd->color_classes) \
8111 sd->color_classes = eina_hash_string_small_new(_edje_color_class_free); \
8113 cc = eina_hash_find(sd->color_classes, buf); \
8116 cc = calloc(1, sizeof(Edje_Color_Class)); \
8117 cc->name = eina_stringshare_add(buf); \
8121 eina_stringshare_del(buf); \
8122 return EINA_FALSE; \
8124 eina_hash_direct_add(sd->color_classes, cc->name, cc); \
8126 else if ((cc->cr == r) && (cc->cg == g) && \
8127 (cc->cb == b) && (cc->ca == a)) \
8129 eina_stringshare_del(buf); \
8138 #define ELM_COLOR_CLASS_SET_END() \
8139 eina_stringshare_del(buf); \
8142 #define ELM_COLOR_CLASS_GET(obj, cr, cg, cb, ca) \
8143 Eina_Bool int_ret = EINA_FALSE; \
8144 Edje_Color_Class *cc; \
8145 Eina_Stringshare *buf; \
8147 buf = _elm_widget_edje_class_get(eo_class_get(obj), NULL, color_class); \
8148 if ((!sd->color_classes) || !(cc = eina_hash_find(sd->color_classes, buf))) \
8154 int_ret = EINA_FALSE; \
8158 if (r) *r = cc->cr; \
8159 if (g) *g = cc->cg; \
8160 if (b) *b = cc->cb; \
8161 if (a) *a = cc->ca; \
8163 int_ret = EINA_TRUE; \
8165 _elm_color_premul(alpha, r, g, b); \
8166 eina_stringshare_del(buf); \
8170 _elm_widget_item_color_class_update(Elm_Widget_Item_Data *sd)
8172 ELM_COLOR_CLASS_UPDATE(sd->view, sd->color_classes, (!sd) || (!sd->color_classes) || (!sd->view));
8176 _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)
8178 ELM_COLOR_CLASS_SET_START(obj, r, g, b, a);
8180 int_ret &= _elm_widget_item_color_class_update(sd);
8182 ELM_COLOR_CLASS_SET_END();
8186 _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)
8188 ELM_COLOR_CLASS_GET(obj, r, g, b, a);
8192 _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)
8194 ELM_COLOR_CLASS_SET_START(obj, r2, g2, b2, a2);
8196 int_ret &= _elm_widget_item_color_class_update(sd);
8198 ELM_COLOR_CLASS_SET_END();
8202 _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)
8204 ELM_COLOR_CLASS_GET(obj, r2, g2, b2, a2);
8208 _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)
8210 ELM_COLOR_CLASS_SET_START(obj, r3, g3, b3, a3);
8212 int_ret &= _elm_widget_item_color_class_update(sd);
8214 ELM_COLOR_CLASS_SET_END();
8218 _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)
8220 ELM_COLOR_CLASS_GET(obj, r3, g3, b3, a3);
8223 static Evas_Object *
8224 _elm_widget_item_edje_get(Eo *obj, Elm_Widget_Item_Data *sd)
8227 sd = eo_data_scope_get(obj, ELM_WIDGET_ITEM_CLASS);
8229 if (eo_isa(sd->view, ELM_LAYOUT_CLASS))
8230 return elm_layout_edje_get(sd->view);
8231 else if (eo_isa(sd->view, EDJE_OBJECT_CLASS))
8238 _elm_widget_item_class_color_del(Eo *obj EINA_UNUSED, Elm_Widget_Item_Data *sd, const char *color_class)
8240 Eina_Stringshare *buf;
8242 Edje_Color_Class *cc = NULL;
8244 if (!color_class) return;
8246 buf = _elm_widget_edje_class_get(eo_class_get(obj), NULL, color_class);
8247 eina_hash_del(sd->color_classes, buf, cc);
8249 edje = _elm_widget_item_edje_get(obj, sd);
8251 edje_object_color_class_del(edje, buf);
8253 eina_stringshare_del(buf);
8257 _elm_widget_item_class_color_clear(Eo *obj EINA_UNUSED, Elm_Widget_Item_Data *sd)
8260 ELM_SAFE_FREE(sd->color_classes, eina_hash_free);
8262 edje = _elm_widget_item_edje_get(obj, sd);
8265 edje_object_color_class_clear(edje);
8269 /* TIZEN_ONLY(20161025): Apply color_class parent-child relationship */
8271 _elm_widget_color_class_parent_set(Evas_Object *obj, Evas_Object *parent)
8273 Evas_Object *edje = NULL, *parent_edje = NULL;
8275 if (!obj || !parent) return;
8277 if (eo_isa(obj, ELM_LAYOUT_CLASS))
8278 edje = elm_layout_edje_get(obj);
8279 else if (eo_isa(obj, EDJE_OBJECT_CLASS))
8282 if (eo_isa(parent, ELM_LAYOUT_CLASS))
8283 parent_edje = elm_layout_edje_get(parent);
8284 else if (eo_isa(parent, EDJE_OBJECT_CLASS))
8285 parent_edje = parent;
8287 if (!edje || !parent_edje) return;
8289 edje_object_color_class_parent_set(edje, parent_edje);
8293 _elm_widget_color_class_parent_unset(Evas_Object *obj)
8295 Evas_Object *edje = NULL;
8299 if (eo_isa(obj, ELM_LAYOUT_CLASS))
8300 edje = elm_layout_edje_get(obj);
8301 else if (eo_isa(obj, EDJE_OBJECT_CLASS))
8306 edje_object_color_class_parent_unset(edje);
8310 //TIZEN_ONLY(20160527): widget: add AtspiAction interface to all widgets and widget_items, add handlers for reading stopped/cancelled
8311 EOLIAN const Elm_Atspi_Action *
8312 _elm_widget_elm_interface_atspi_widget_action_elm_actions_get(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *pd EINA_UNUSED)
8317 EOLIAN const Elm_Atspi_Action *
8318 _elm_widget_item_elm_interface_atspi_widget_action_elm_actions_get(Eo *obj EINA_UNUSED, Elm_Widget_Item_Data *pd EINA_UNUSED)
8324 #include "elm_widget_item.eo.c"
8325 #include "elm_widget.eo.c"