1 #include <Elementary.h>
4 static const char SMART_NAME[] = "elm_widget";
7 Smart_Data *sd = evas_object_smart_data_get(obj); \
8 if ((!obj) || (!sd) || (!_elm_widget_is(obj)))
9 #define INTERNAL_ENTRY \
10 Smart_Data *sd = evas_object_smart_data_get(obj); \
13 typedef struct _Smart_Data Smart_Data;
19 Evas_Object *parent_obj;
20 Evas_Coord x, y, w, h;
22 Evas_Object *resize_obj;
23 Evas_Object *hover_obj;
24 void (*del_func) (Evas_Object *obj);
25 void (*del_pre_func) (Evas_Object *obj);
26 void (*focus_func) (Evas_Object *obj);
27 void (*activate_func) (Evas_Object *obj);
28 void (*disable_func) (Evas_Object *obj);
29 void (*theme_func) (Evas_Object *obj);
30 void (*signal_func) (Evas_Object *obj, const char *emission,
32 void (*callback_add_func) (Evas_Object *obj, const char *emission,
33 const char *source, void (*func) (void *data,
34 Evas_Object *o, const char *emission,
35 const char *source), void *data);
36 void *(*callback_del_func) (Evas_Object *obj, const char *emission,
37 const char *source, void (*func) (void *data,
38 Evas_Object *o, const char *emission,
40 void (*changed_func) (Evas_Object *obj);
41 void (*on_focus_func) (void *data, Evas_Object *obj);
43 void (*on_change_func) (void *data, Evas_Object *obj);
45 void (*on_show_region_func) (void *data, Evas_Object *obj);
46 void *on_show_region_data;
48 Evas_Coord rx, ry, rw, rh;
54 unsigned int focus_order;
56 int child_drag_x_locked;
57 int child_drag_y_locked;
58 Eina_Bool drag_x_locked : 1;
59 Eina_Bool drag_y_locked : 1;
61 Eina_Bool can_focus : 1;
62 Eina_Bool child_can_focus : 1;
63 Eina_Bool focused : 1;
64 Eina_Bool disabled : 1;
67 /* local subsystem functions */
68 static void _smart_reconfigure(Smart_Data *sd);
69 static void _smart_add(Evas_Object *obj);
70 static void _smart_del(Evas_Object *obj);
71 static void _smart_move(Evas_Object *obj, Evas_Coord x, Evas_Coord y);
72 static void _smart_resize(Evas_Object *obj, Evas_Coord w, Evas_Coord h);
73 static void _smart_show(Evas_Object *obj);
74 static void _smart_hide(Evas_Object *obj);
75 static void _smart_color_set(Evas_Object *obj, int r, int g, int b, int a);
76 static void _smart_clip_set(Evas_Object *obj, Evas_Object * clip);
77 static void _smart_clip_unset(Evas_Object *obj);
78 static void _smart_calculate(Evas_Object *obj);
79 static void _smart_init(void);
80 static inline Eina_Bool _elm_widget_is(const Evas_Object *obj);
82 static void _if_focused_revert(Evas_Object *obj);
84 /* local subsystem globals */
85 static Evas_Smart *_e_smart = NULL;
87 static unsigned int focus_order = 0;
90 _sub_obj_del(void *data, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
92 Smart_Data *sd = data;
94 if (obj == sd->resize_obj)
95 sd->resize_obj = NULL;
96 else if (obj == sd->hover_obj)
99 sd->subobjs = eina_list_remove(sd->subobjs, obj);
100 evas_object_smart_callback_call(sd->obj, "sub-object-del", obj);
104 _sub_obj_mouse_down(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
106 Evas_Object *o = obj;
109 if (_elm_widget_is(o)) break;
110 o = evas_object_smart_parent_get(o);
114 if (!elm_widget_can_focus_get(o)) return;
115 elm_widget_focus_steal(o);
119 elm_widget_add(Evas *evas)
122 return evas_object_smart_add(evas, _e_smart);
126 elm_widget_del_hook_set(Evas_Object *obj, void (*func) (Evas_Object *obj))
133 elm_widget_del_pre_hook_set(Evas_Object *obj, void (*func) (Evas_Object *obj))
136 sd->del_pre_func = func;
140 elm_widget_focus_hook_set(Evas_Object *obj, void (*func) (Evas_Object *obj))
143 sd->focus_func = func;
147 elm_widget_activate_hook_set(Evas_Object *obj, void (*func) (Evas_Object *obj))
150 sd->activate_func = func;
154 elm_widget_disable_hook_set(Evas_Object *obj, void (*func) (Evas_Object *obj))
157 sd->disable_func = func;
161 elm_widget_theme_hook_set(Evas_Object *obj, void (*func) (Evas_Object *obj))
164 sd->theme_func = func;
168 elm_widget_changed_hook_set(Evas_Object *obj, void (*func) (Evas_Object *obj))
171 sd->changed_func = func;
175 elm_widget_signal_emit_hook_set(Evas_Object *obj, void (*func) (Evas_Object *obj, const char *emission, const char *source))
178 sd->signal_func = func;
182 elm_widget_signal_callback_add_hook_set(Evas_Object *obj, void (*func) (Evas_Object *obj, const char *emission, const char *source, void (*func_cb) (void *data, Evas_Object *o, const char *emission, const char *source), void *data))
185 sd->callback_add_func = func;
189 elm_widget_signal_callback_del_hook_set(Evas_Object *obj, void *(*func) (Evas_Object *obj, const char *emission, const char *source, void (*func_cb) (void *data, Evas_Object *o, const char *emission, const char *source)))
192 sd->callback_del_func = func;
196 elm_widget_theme(Evas_Object *obj)
202 EINA_LIST_FOREACH(sd->subobjs, l, child)
203 elm_widget_theme(child);
204 if (sd->resize_obj) elm_widget_theme(sd->resize_obj);
205 if (sd->hover_obj) elm_widget_theme(sd->hover_obj);
206 if (sd->theme_func) sd->theme_func(obj);
210 elm_widget_on_focus_hook_set(Evas_Object *obj, void (*func) (void *data, Evas_Object *obj), void *data)
213 sd->on_focus_func = func;
214 sd->on_focus_data = data;
218 elm_widget_on_change_hook_set(Evas_Object *obj, void (*func) (void *data, Evas_Object *obj), void *data)
221 sd->on_change_func = func;
222 sd->on_change_data = data;
226 elm_widget_on_show_region_hook_set(Evas_Object *obj, void (*func) (void *data, Evas_Object *obj), void *data)
229 sd->on_show_region_func = func;
230 sd->on_show_region_data = data;
234 elm_widget_data_set(Evas_Object *obj, void *data)
241 elm_widget_data_get(const Evas_Object *obj)
243 API_ENTRY return NULL;
248 elm_widget_sub_object_add(Evas_Object *obj, Evas_Object *sobj)
251 double scale, pscale = elm_widget_scale_get(sobj);
252 Elm_Theme *th, *pth = elm_widget_theme_get(sobj);
254 sd->subobjs = eina_list_append(sd->subobjs, sobj);
255 if (!sd->child_can_focus)
257 if (elm_widget_can_focus_get(sobj)) sd->child_can_focus = 1;
259 if (_elm_widget_is(sobj))
261 Smart_Data *sd2 = evas_object_smart_data_get(sobj);
265 elm_widget_sub_object_del(sd2->parent_obj, sobj);
266 sd2->parent_obj = obj;
269 evas_object_data_set(sobj, "elm-parent", obj);
270 evas_object_event_callback_add(sobj, EVAS_CALLBACK_DEL, _sub_obj_del, sd);
271 evas_object_smart_callback_call(obj, "sub-object-add", sobj);
272 scale = elm_widget_scale_get(sobj);
273 th = elm_widget_theme_get(sobj);
274 if ((scale != pscale) || (th != pth)) elm_widget_theme(sobj);
278 elm_widget_sub_object_del(Evas_Object *obj, Evas_Object *sobj)
280 Evas_Object *sobj_parent;
284 sobj_parent = evas_object_data_del(sobj, "elm-parent");
285 if (sobj_parent != obj)
287 static int abort_on_warn = -1;
288 ERR("removing sub object %p from parent %p, "
289 "but elm-parent is different %p!",
290 sobj, obj, sobj_parent);
291 if (EINA_UNLIKELY(abort_on_warn == -1))
293 if (getenv("ELM_ERROR_ABORT")) abort_on_warn = 1;
294 else abort_on_warn = 0;
296 if (abort_on_warn == 1) abort();
298 sd->subobjs = eina_list_remove(sd->subobjs, sobj);
299 if (!sd->child_can_focus)
301 if (elm_widget_can_focus_get(sobj)) sd->child_can_focus = 0;
303 if (_elm_widget_is(sobj))
305 Smart_Data *sd2 = evas_object_smart_data_get(sobj);
306 if (sd2) sd2->parent_obj = NULL;
308 evas_object_event_callback_del_full(sobj, EVAS_CALLBACK_DEL, _sub_obj_del, sd);
309 evas_object_smart_callback_call(obj, "sub-object-del", sobj);
313 elm_widget_resize_object_set(Evas_Object *obj, Evas_Object *sobj)
318 evas_object_data_del(sd->resize_obj, "elm-parent");
319 if (_elm_widget_is(sd->resize_obj))
321 Smart_Data *sd2 = evas_object_smart_data_get(sd->resize_obj);
322 if (sd2) sd2->parent_obj = NULL;
324 evas_object_event_callback_del_full(sd->resize_obj, EVAS_CALLBACK_DEL,
326 evas_object_event_callback_del_full(sd->resize_obj, EVAS_CALLBACK_MOUSE_DOWN,
327 _sub_obj_mouse_down, sd);
328 evas_object_smart_member_del(sd->resize_obj);
330 sd->resize_obj = sobj;
333 if (_elm_widget_is(sd->resize_obj))
335 Smart_Data *sd2 = evas_object_smart_data_get(sd->resize_obj);
336 if (sd2) sd2->parent_obj = obj;
338 evas_object_clip_set(sobj, evas_object_clip_get(obj));
339 evas_object_smart_member_add(sobj, obj);
340 evas_object_event_callback_add(sobj, EVAS_CALLBACK_DEL, _sub_obj_del, sd);
341 evas_object_event_callback_add(sobj, EVAS_CALLBACK_MOUSE_DOWN,
342 _sub_obj_mouse_down, sd);
343 _smart_reconfigure(sd);
344 evas_object_data_set(sobj, "elm-parent", obj);
345 evas_object_smart_callback_call(obj, "sub-object-add", sobj);
350 elm_widget_hover_object_set(Evas_Object *obj, Evas_Object *sobj)
355 evas_object_event_callback_del_full(sd->hover_obj, EVAS_CALLBACK_DEL,
358 sd->hover_obj = sobj;
361 evas_object_event_callback_add(sobj, EVAS_CALLBACK_DEL, _sub_obj_del, sd);
362 _smart_reconfigure(sd);
367 elm_widget_can_focus_set(Evas_Object *obj, int can_focus)
370 sd->can_focus = can_focus;
374 elm_widget_can_focus_get(const Evas_Object *obj)
377 if (sd->can_focus) return 1;
378 if (sd->child_can_focus) return 1;
383 elm_widget_focus_get(const Evas_Object *obj)
390 elm_widget_focused_object_get(const Evas_Object *obj)
392 const Evas_Object *subobj;
394 API_ENTRY return NULL;
396 if (!sd->focused) return NULL;
397 EINA_LIST_FOREACH(sd->subobjs, l, subobj)
399 Evas_Object *fobj = elm_widget_focused_object_get(subobj);
400 if (fobj) return fobj;
402 return (Evas_Object *)obj;
406 elm_widget_top_get(const Evas_Object *obj)
409 API_ENTRY return NULL;
410 if (sd->parent_obj) return elm_widget_top_get(sd->parent_obj);
411 return (Evas_Object *)obj;
413 Smart_Data *sd = evas_object_smart_data_get(obj);
416 if (!obj) return NULL;
417 if ((sd) && _elm_widget_is(obj))
419 if ((sd->type) && (!strcmp(sd->type, "win")))
420 return (Evas_Object *)obj;
422 return elm_widget_top_get(sd->parent_obj);
424 par = evas_object_smart_parent_get(obj);
425 if (!par) return (Evas_Object *)obj;
426 return elm_widget_top_get(par);
431 elm_widget_is(const Evas_Object *obj)
433 return _elm_widget_is(obj);
437 elm_widget_parent_widget_get(const Evas_Object *obj)
441 if (_elm_widget_is(obj))
443 Smart_Data *sd = evas_object_smart_data_get(obj);
444 if (!sd) return NULL;
445 parent = sd->parent_obj;
449 parent = evas_object_data_get(obj, "elm-parent");
451 parent = evas_object_smart_data_get(obj);
456 Evas_Object *elm_parent;
457 if (_elm_widget_is(parent)) break;
458 elm_parent = evas_object_data_get(parent, "elm-parent");
462 parent = evas_object_smart_parent_get(parent);
468 elm_widget_focus_jump(Evas_Object *obj, int forward)
471 if (!elm_widget_can_focus_get(obj)) return 0;
473 /* if it has a focus func its an end-point widget like a button */
479 sd->focus_order = focus_order;
482 else sd->focused = 0;
483 if (sd->on_focus_func) sd->on_focus_func(sd->on_focus_data, obj);
487 /* its some container */
496 elm_widget_focus_set(obj, forward);
503 if (elm_widget_can_focus_get(sd->resize_obj))
506 (!elm_widget_disabled_get(sd->resize_obj)))
508 /* the previous focused item was unfocused - so focus
509 * the next one (that can be focused) */
510 if (elm_widget_focus_jump(sd->resize_obj, forward))
516 if (elm_widget_focus_get(sd->resize_obj))
518 /* jump to the next focused item or focus this item */
519 if (elm_widget_focus_jump(sd->resize_obj, forward))
521 /* it returned 0 - it got to the last item and is past it */
530 EINA_LIST_FOREACH(sd->subobjs, l, child)
532 if (elm_widget_can_focus_get(child))
535 (!elm_widget_disabled_get(child)))
537 /* the previous focused item was unfocused - so focus
538 * the next one (that can be focused) */
539 if (elm_widget_focus_jump(child, forward))
545 if (elm_widget_focus_get(child))
547 /* jump to the next focused item or focus this item */
548 if (elm_widget_focus_jump(child, forward))
550 /* it returned 0 - it got to the last item and is past it */
563 EINA_LIST_REVERSE_FOREACH(sd->subobjs, l, child)
565 if (elm_widget_can_focus_get(child))
568 (!elm_widget_disabled_get(child)))
570 /* the previous focused item was unfocused - so focus
571 * the next one (that can be focused) */
572 if (elm_widget_focus_jump(child, forward))
578 if (elm_widget_focus_get(child))
580 /* jump to the next focused item or focus this item */
581 if (elm_widget_focus_jump(child, forward))
583 /* it returned 0 - it got to the last item and is past it */
591 if (elm_widget_can_focus_get(sd->resize_obj))
594 (!elm_widget_disabled_get(sd->resize_obj)))
596 /* the previous focused item was unfocused - so focus
597 * the next one (that can be focused) */
598 if (elm_widget_focus_jump(sd->resize_obj, forward))
603 if (elm_widget_focus_get(sd->resize_obj))
605 /* jump to the next focused item or focus this item */
606 if (elm_widget_focus_jump(sd->resize_obj, forward))
608 /* it returned 0 - it got to the last item and is past it */
617 /* no next item can be focused */
621 if (sd->on_focus_func) sd->on_focus_func(sd->on_focus_data, obj);
627 elm_widget_signal_emit(Evas_Object *obj, const char *emission, const char *source)
630 if (!sd->signal_func) return;
631 sd->signal_func(obj, emission, source);
635 elm_widget_signal_callback_add(Evas_Object *obj, const char *emission, const char *source, void (*func) (void *data, Evas_Object *o, const char *emission, const char *source), void *data)
638 if (!sd->callback_add_func) return;
639 sd->callback_add_func(obj, emission, source, func, data);
643 elm_widget_signal_callback_del(Evas_Object *obj, const char *emission, const char *source, void (*func) (void *data, Evas_Object *o, const char *emission, const char *source))
645 API_ENTRY return NULL;
646 if (!sd->callback_del_func) return NULL;
647 return sd->callback_del_func(obj, emission, source, func);
651 elm_widget_focus_set(Evas_Object *obj, int first)
657 sd->focus_order = focus_order;
659 if (sd->on_focus_func) sd->on_focus_func(sd->on_focus_data, obj);
670 if ((elm_widget_can_focus_get(sd->resize_obj)) &&
671 (!elm_widget_disabled_get(sd->resize_obj)))
673 elm_widget_focus_set(sd->resize_obj, first);
679 EINA_LIST_FOREACH(sd->subobjs, l, child)
681 if ((elm_widget_can_focus_get(child)) &&
682 (!elm_widget_disabled_get(child)))
684 elm_widget_focus_set(child, first);
694 EINA_LIST_REVERSE_FOREACH(sd->subobjs, l, child)
696 if ((elm_widget_can_focus_get(child)) &&
697 (!elm_widget_disabled_get(child)))
699 elm_widget_focus_set(child, first);
705 if ((elm_widget_can_focus_get(sd->resize_obj)) &&
706 (!elm_widget_disabled_get(sd->resize_obj)))
708 elm_widget_focus_set(sd->resize_obj, first);
716 elm_widget_parent_get(const Evas_Object *obj)
718 API_ENTRY return NULL;
719 return sd->parent_obj;
723 elm_widget_focused_object_clear(Evas_Object *obj)
726 if (!sd->focused) return;
727 if (elm_widget_focus_get(sd->resize_obj))
728 elm_widget_focused_object_clear(sd->resize_obj);
733 EINA_LIST_FOREACH(sd->subobjs, l, child)
735 if (elm_widget_focus_get(child))
737 elm_widget_focused_object_clear(child);
743 if (sd->on_focus_func) sd->on_focus_func(sd->on_focus_data, obj);
744 if (sd->focus_func) sd->focus_func(obj);
748 _elm_widget_parent_focus(Evas_Object *obj)
751 Evas_Object *o = elm_widget_parent_get(obj);
753 if (sd->focused) return;
754 if (o) _elm_widget_parent_focus(o);
756 sd->focus_order = focus_order;
758 if (sd->on_focus_func) sd->on_focus_func(sd->on_focus_data, obj);
759 if (sd->focus_func) sd->focus_func(obj);
763 elm_widget_focus_steal(Evas_Object *obj)
765 Evas_Object *parent, *o;
768 if (sd->focused) return;
769 if (sd->disabled) return;
773 o = elm_widget_parent_get(parent);
775 sd = evas_object_smart_data_get(o);
776 if (sd->focused) break;
779 if (!elm_widget_parent_get(parent))
780 elm_widget_focused_object_clear(parent);
783 parent = elm_widget_parent_get(parent);
784 sd = evas_object_smart_data_get(parent);
785 if (elm_widget_focus_get(sd->resize_obj))
787 elm_widget_focused_object_clear(sd->resize_obj);
793 EINA_LIST_FOREACH(sd->subobjs, l, child)
795 if (elm_widget_focus_get(child))
797 elm_widget_focused_object_clear(child);
803 _elm_widget_parent_focus(obj);
808 elm_widget_activate(Evas_Object *obj)
811 elm_widget_change(obj);
812 if (sd->activate_func) sd->activate_func(obj);
816 elm_widget_change(Evas_Object *obj)
819 elm_widget_change(elm_widget_parent_get(obj));
820 if (sd->on_change_func) sd->on_change_func(sd->on_change_data, obj);
824 elm_widget_disabled_set(Evas_Object *obj, int disabled)
828 if (sd->disabled == disabled) return;
829 sd->disabled = disabled;
832 Evas_Object *o, *parent;
837 o = elm_widget_parent_get(parent);
841 elm_widget_focus_jump(parent, 1);
843 if (sd->disable_func) sd->disable_func(obj);
847 elm_widget_disabled_get(const Evas_Object *obj)
854 elm_widget_show_region_set(Evas_Object *obj, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h)
857 if ((x == sd->rx) && (y == sd->ry) && (w == sd->rw) && (h == sd->rh)) return;
862 if (sd->on_show_region_func)
863 sd->on_show_region_func(sd->on_show_region_data, obj);
867 elm_widget_show_region_get(const Evas_Object *obj, Evas_Coord *x, Evas_Coord *y, Evas_Coord *w, Evas_Coord *h)
877 elm_widget_scroll_hold_push(Evas_Object *obj)
881 if (sd->scroll_hold == 1)
882 evas_object_smart_callback_call(obj, "scroll-hold-on", obj);
883 if (sd->parent_obj) elm_widget_scroll_hold_push(sd->parent_obj);
884 // FIXME: on delete/reparent hold pop
888 elm_widget_scroll_hold_pop(Evas_Object *obj)
892 if (sd->scroll_hold < 0) sd->scroll_hold = 0;
893 if (sd->scroll_hold == 0)
894 evas_object_smart_callback_call(obj, "scroll-hold-off", obj);
895 if (sd->parent_obj) elm_widget_scroll_hold_pop(sd->parent_obj);
899 elm_widget_scroll_hold_get(const Evas_Object *obj)
902 return sd->scroll_hold;
906 elm_widget_scroll_freeze_push(Evas_Object *obj)
910 if (sd->scroll_freeze == 1)
911 evas_object_smart_callback_call(obj, "scroll-freeze-on", obj);
912 if (sd->parent_obj) elm_widget_scroll_freeze_push(sd->parent_obj);
913 // FIXME: on delete/reparent freeze pop
917 elm_widget_scroll_freeze_pop(Evas_Object *obj)
921 if (sd->scroll_freeze < 0) sd->scroll_freeze = 0;
922 if (sd->scroll_freeze == 0)
923 evas_object_smart_callback_call(obj, "scroll-freeze-off", obj);
924 if (sd->parent_obj) elm_widget_scroll_freeze_pop(sd->parent_obj);
928 elm_widget_scroll_freeze_get(const Evas_Object *obj)
931 return sd->scroll_freeze;
935 elm_widget_scale_set(Evas_Object *obj, double scale)
938 if (scale <= 0.0) scale = 0.0;
939 if (sd->scale != scale)
942 elm_widget_theme(obj);
947 elm_widget_scale_get(const Evas_Object *obj)
949 API_ENTRY return 1.0;
950 // FIXME: save walking up the tree by storing/caching parent scale
951 if (sd->scale == 0.0)
954 return elm_widget_scale_get(sd->parent_obj);
962 elm_widget_theme_set(Evas_Object *obj, Elm_Theme *th)
967 if (sd->theme) elm_theme_free(sd->theme);
970 elm_widget_theme(obj);
975 elm_widget_theme_get(const Evas_Object *obj)
977 API_ENTRY return NULL;
981 return elm_widget_theme_get(sd->parent_obj);
989 elm_widget_style_set(Evas_Object *obj, const char *style)
993 if (eina_stringshare_replace(&sd->style, style))
994 elm_widget_theme(obj);
998 elm_widget_style_get(const Evas_Object *obj)
1000 API_ENTRY return "";
1001 if (sd->style) return sd->style;
1006 elm_widget_type_set(Evas_Object *obj, const char *type)
1009 eina_stringshare_replace(&sd->type, type);
1013 elm_widget_type_get(const Evas_Object *obj)
1015 API_ENTRY return "";
1016 if (sd->type) return sd->type;
1029 _propagate_x_drag_lock(Evas_Object *obj, int dir)
1031 Smart_Data *sd = evas_object_smart_data_get(obj);
1034 Smart_Data *sd2 = evas_object_smart_data_get(sd->parent_obj);
1037 sd2->child_drag_x_locked += dir;
1038 _propagate_x_drag_lock(sd->parent_obj, dir);
1044 _propagate_y_drag_lock(Evas_Object *obj, int dir)
1046 Smart_Data *sd = evas_object_smart_data_get(obj);
1049 Smart_Data *sd2 = evas_object_smart_data_get(sd->parent_obj);
1052 sd2->child_drag_y_locked += dir;
1053 _propagate_y_drag_lock(sd->parent_obj, dir);
1059 elm_widget_drag_lock_x_set(Evas_Object *obj, Eina_Bool lock)
1062 if (sd->drag_x_locked == lock) return;
1063 sd->drag_x_locked = lock;
1064 if (sd->drag_x_locked) _propagate_x_drag_lock(obj, 1);
1065 else _propagate_x_drag_lock(obj, -1);
1069 elm_widget_drag_lock_y_set(Evas_Object *obj, Eina_Bool lock)
1072 if (sd->drag_y_locked == lock) return;
1073 sd->drag_y_locked = lock;
1074 if (sd->drag_y_locked) _propagate_y_drag_lock(obj, 1);
1075 else _propagate_y_drag_lock(obj, -1);
1079 elm_widget_drag_lock_x_get(const Evas_Object *obj)
1081 API_ENTRY return EINA_FALSE;
1082 return sd->drag_x_locked;
1086 elm_widget_drag_lock_y_get(const Evas_Object *obj)
1088 API_ENTRY return EINA_FALSE;
1089 return sd->drag_y_locked;
1093 elm_widget_drag_child_locked_x_get(const Evas_Object *obj)
1096 return sd->child_drag_x_locked;
1100 elm_widget_drag_child_locked_y_get(const Evas_Object *obj)
1103 return sd->child_drag_y_locked;
1116 /* local subsystem functions */
1118 _smart_reconfigure(Smart_Data *sd)
1122 evas_object_move(sd->resize_obj, sd->x, sd->y);
1123 evas_object_resize(sd->resize_obj, sd->w, sd->h);
1127 evas_object_move(sd->hover_obj, sd->x, sd->y);
1128 evas_object_resize(sd->hover_obj, sd->w, sd->h);
1133 _smart_add(Evas_Object *obj)
1137 sd = calloc(1, sizeof(Smart_Data));
1145 evas_object_smart_data_set(obj, sd);
1148 static Evas_Object *
1149 _newest_focus_order_get(Evas_Object *obj, unsigned int *newest_focus_order)
1152 Evas_Object *child, *ret, *best;
1154 API_ENTRY return NULL;
1155 if (!evas_object_visible_get(obj)) return NULL;
1157 if (*newest_focus_order < sd->focus_order)
1159 *newest_focus_order = sd->focus_order;
1162 EINA_LIST_FOREACH(sd->subobjs, l, child)
1164 ret = _newest_focus_order_get(child, newest_focus_order);
1172 _if_focused_revert(Evas_Object *obj)
1175 Evas_Object *newest = NULL;
1176 unsigned int newest_focus_order = 0;
1180 if (!sd->focused) return;
1181 if (!sd->parent_obj) return;
1183 top = elm_widget_top_get(sd->parent_obj);
1186 newest = _newest_focus_order_get(top, &newest_focus_order);
1189 elm_object_unfocus(newest);
1190 elm_object_focus(newest);
1196 _smart_del(Evas_Object *obj)
1201 if (sd->del_pre_func) sd->del_pre_func(obj);
1204 sobj = sd->resize_obj;
1205 sd->resize_obj = NULL;
1206 evas_object_event_callback_del_full(sobj, EVAS_CALLBACK_DEL, _sub_obj_del, sd);
1207 evas_object_smart_callback_call(sd->obj, "sub-object-del", sobj);
1208 evas_object_del(sobj);
1212 sobj = sd->hover_obj;
1213 sd->hover_obj = NULL;
1214 evas_object_event_callback_del_full(sobj, EVAS_CALLBACK_DEL, _sub_obj_del, sd);
1215 evas_object_smart_callback_call(sd->obj, "sub-object-del", sobj);
1216 evas_object_del(sobj);
1218 EINA_LIST_FREE(sd->subobjs, sobj)
1220 evas_object_event_callback_del_full(sobj, EVAS_CALLBACK_DEL, _sub_obj_del, sd);
1221 evas_object_smart_callback_call(sd->obj, "sub-object-del", sobj);
1222 evas_object_del(sobj);
1224 if (sd->del_func) sd->del_func(obj);
1225 if (sd->style) eina_stringshare_del(sd->style);
1226 if (sd->type) eina_stringshare_del(sd->type);
1227 if (sd->theme) elm_theme_free(sd->theme);
1228 _if_focused_revert(obj);
1233 _smart_move(Evas_Object *obj, Evas_Coord x, Evas_Coord y)
1238 _smart_reconfigure(sd);
1242 _smart_resize(Evas_Object *obj, Evas_Coord w, Evas_Coord h)
1247 _smart_reconfigure(sd);
1251 _smart_show(Evas_Object *obj)
1254 evas_object_show(sd->resize_obj);
1258 _smart_hide(Evas_Object *obj)
1261 evas_object_hide(sd->resize_obj);
1262 _if_focused_revert(obj);
1266 _smart_color_set(Evas_Object *obj, int r, int g, int b, int a)
1269 evas_object_color_set(sd->resize_obj, r, g, b, a);
1273 _smart_clip_set(Evas_Object *obj, Evas_Object *clip)
1276 evas_object_clip_set(sd->resize_obj, clip);
1280 _smart_clip_unset(Evas_Object *obj)
1283 evas_object_clip_unset(sd->resize_obj);
1287 _smart_calculate(Evas_Object *obj)
1290 if (sd->changed_func) sd->changed_func(obj);
1293 /* never need to touch this */
1298 if (_e_smart) return;
1300 static const Evas_Smart_Class sc =
1303 EVAS_SMART_CLASS_VERSION,
1321 _e_smart = evas_smart_class_new(&sc);
1328 _elm_stringlist_get(const char *str)
1330 Eina_List *list = NULL;
1332 if (!str) return NULL;
1333 for (b = s = str; 1; s++)
1335 if ((*s == ' ') || (*s == 0))
1337 char *t = malloc(s - b + 1);
1340 strncpy(t, b, s - b);
1342 list = eina_list_append(list, eina_stringshare_add(t));
1353 _elm_stringlist_free(Eina_List *list)
1356 EINA_LIST_FREE(list, s) eina_stringshare_del(s);
1360 _elm_widget_type_check(const Evas_Object *obj, const char *type)
1362 const char *provided, *expected = "(unknown)";
1363 static int abort_on_warn = -1;
1364 provided = elm_widget_type_get(obj);
1365 if (EINA_LIKELY(provided == type)) return EINA_TRUE;
1366 if (type) expected = type;
1367 if ((!provided) || (provided[0] == 0))
1369 provided = evas_object_type_get(obj);
1370 if ((!provided) || (provided[0] == 0))
1371 provided = "(unknown)";
1373 ERR("Passing Object: %p, of type: '%s' when expecting type: '%s'", obj, provided, expected);
1374 if (abort_on_warn == -1)
1376 if (getenv("ELM_ERROR_ABORT")) abort_on_warn = 1;
1377 else abort_on_warn = 0;
1379 if (abort_on_warn == 1) abort();
1383 static inline Eina_Bool
1384 _elm_widget_is(const Evas_Object *obj)
1386 const char *type = evas_object_type_get(obj);
1387 return type == SMART_NAME;