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 #ifdef HAVE_CONFORMANT_AUTOSCROLL
46 Evas_Object * (*imp_region_get_func) (const Evas_Object *obj, Evas_Coord *x, Evas_Coord *y, Evas_Coord *w, Evas_Coord *h);
48 void (*on_show_region_func) (void *data, Evas_Object *obj);
49 void *on_show_region_data;
51 Evas_Coord rx, ry, rw, rh;
57 unsigned int focus_order;
59 int child_drag_x_locked;
60 int child_drag_y_locked;
61 Eina_Bool drag_x_locked : 1;
62 Eina_Bool drag_y_locked : 1;
64 Eina_Bool can_focus : 1;
65 Eina_Bool child_can_focus : 1;
66 Eina_Bool focused : 1;
67 Eina_Bool disabled : 1;
70 /* local subsystem functions */
71 static void _smart_reconfigure(Smart_Data *sd);
72 static void _smart_add(Evas_Object *obj);
73 static void _smart_del(Evas_Object *obj);
74 static void _smart_move(Evas_Object *obj, Evas_Coord x, Evas_Coord y);
75 static void _smart_resize(Evas_Object *obj, Evas_Coord w, Evas_Coord h);
76 static void _smart_show(Evas_Object *obj);
77 static void _smart_hide(Evas_Object *obj);
78 static void _smart_color_set(Evas_Object *obj, int r, int g, int b, int a);
79 static void _smart_clip_set(Evas_Object *obj, Evas_Object * clip);
80 static void _smart_clip_unset(Evas_Object *obj);
81 static void _smart_calculate(Evas_Object *obj);
82 static void _smart_init(void);
83 static inline Eina_Bool _elm_widget_is(const Evas_Object *obj);
85 static void _if_focused_revert(Evas_Object *obj);
87 /* local subsystem globals */
88 static Evas_Smart *_e_smart = NULL;
90 static unsigned int focus_order = 0;
93 _unfocus_parents(Evas_Object *obj)
95 for (; obj; obj = elm_widget_parent_get(obj))
97 Smart_Data *sd = evas_object_smart_data_get(obj);
99 if (!sd->focused) return;
105 _focus_parents(Evas_Object *obj)
107 for (; obj; obj = elm_widget_parent_get(obj))
109 Smart_Data *sd = evas_object_smart_data_get(obj);
111 if (sd->focused) return;
117 _sub_obj_del(void *data, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
119 Smart_Data *sd = data;
121 if (_elm_widget_is(obj))
123 if (elm_widget_focus_get(obj)) _unfocus_parents(sd->obj);
125 if (obj == sd->resize_obj)
126 sd->resize_obj = NULL;
127 else if (obj == sd->hover_obj)
128 sd->hover_obj = NULL;
130 sd->subobjs = eina_list_remove(sd->subobjs, obj);
131 evas_object_smart_callback_call(sd->obj, "sub-object-del", obj);
135 _sub_obj_mouse_down(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
137 Evas_Object *o = obj;
140 if (_elm_widget_is(o)) break;
141 o = evas_object_smart_parent_get(o);
145 if (!elm_widget_can_focus_get(o)) return;
146 elm_widget_focus_steal(o);
150 elm_widget_add(Evas *evas)
153 return evas_object_smart_add(evas, _e_smart);
157 elm_widget_del_hook_set(Evas_Object *obj, void (*func) (Evas_Object *obj))
164 elm_widget_del_pre_hook_set(Evas_Object *obj, void (*func) (Evas_Object *obj))
167 sd->del_pre_func = func;
171 elm_widget_focus_hook_set(Evas_Object *obj, void (*func) (Evas_Object *obj))
174 sd->focus_func = func;
178 elm_widget_activate_hook_set(Evas_Object *obj, void (*func) (Evas_Object *obj))
181 sd->activate_func = func;
185 elm_widget_disable_hook_set(Evas_Object *obj, void (*func) (Evas_Object *obj))
188 sd->disable_func = func;
192 elm_widget_theme_hook_set(Evas_Object *obj, void (*func) (Evas_Object *obj))
195 sd->theme_func = func;
199 elm_widget_changed_hook_set(Evas_Object *obj, void (*func) (Evas_Object *obj))
202 sd->changed_func = func;
206 elm_widget_signal_emit_hook_set(Evas_Object *obj, void (*func) (Evas_Object *obj, const char *emission, const char *source))
209 sd->signal_func = func;
213 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))
216 sd->callback_add_func = func;
220 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)))
223 sd->callback_del_func = func;
227 elm_widget_theme(Evas_Object *obj)
233 EINA_LIST_FOREACH(sd->subobjs, l, child)
234 elm_widget_theme(child);
235 if (sd->resize_obj) elm_widget_theme(sd->resize_obj);
236 if (sd->hover_obj) elm_widget_theme(sd->hover_obj);
237 if (sd->theme_func) sd->theme_func(obj);
241 elm_widget_on_focus_hook_set(Evas_Object *obj, void (*func) (void *data, Evas_Object *obj), void *data)
244 sd->on_focus_func = func;
245 sd->on_focus_data = data;
249 elm_widget_on_change_hook_set(Evas_Object *obj, void (*func) (void *data, Evas_Object *obj), void *data)
252 sd->on_change_func = func;
253 sd->on_change_data = data;
256 #ifdef HAVE_CONFORMANT_AUTOSCROLL
258 elm_widget_imp_region_get_hook_set(Evas_Object *obj, Evas_Object * (*func) (const Evas_Object *obj, Evas_Coord *x, Evas_Coord *y, Evas_Coord *w, Evas_Coord *h), void *data)
261 sd->imp_region_get_func = func;
266 elm_widget_on_show_region_hook_set(Evas_Object *obj, void (*func) (void *data, Evas_Object *obj), void *data)
269 sd->on_show_region_func = func;
270 sd->on_show_region_data = data;
274 elm_widget_data_set(Evas_Object *obj, void *data)
281 elm_widget_data_get(const Evas_Object *obj)
283 API_ENTRY return NULL;
288 elm_widget_sub_object_add(Evas_Object *obj, Evas_Object *sobj)
291 double scale, pscale = elm_widget_scale_get(sobj);
292 Elm_Theme *th, *pth = elm_widget_theme_get(sobj);
294 sd->subobjs = eina_list_append(sd->subobjs, sobj);
295 if (!sd->child_can_focus)
297 if (elm_widget_can_focus_get(sobj)) sd->child_can_focus = 1;
299 if (_elm_widget_is(sobj))
301 Smart_Data *sd2 = evas_object_smart_data_get(sobj);
305 elm_widget_sub_object_del(sd2->parent_obj, sobj);
306 sd2->parent_obj = obj;
309 evas_object_data_set(sobj, "elm-parent", obj);
310 evas_object_event_callback_add(sobj, EVAS_CALLBACK_DEL, _sub_obj_del, sd);
311 evas_object_smart_callback_call(obj, "sub-object-add", sobj);
312 scale = elm_widget_scale_get(sobj);
313 th = elm_widget_theme_get(sobj);
314 if ((scale != pscale) || (th != pth)) elm_widget_theme(sobj);
315 if (_elm_widget_is(sobj))
317 if (elm_widget_focus_get(sobj)) _focus_parents(obj);
322 elm_widget_sub_object_del(Evas_Object *obj, Evas_Object *sobj)
324 Evas_Object *sobj_parent;
328 sobj_parent = evas_object_data_del(sobj, "elm-parent");
329 if (sobj_parent != obj)
331 static int abort_on_warn = -1;
332 ERR("removing sub object %p from parent %p, "
333 "but elm-parent is different %p!",
334 sobj, obj, sobj_parent);
335 if (EINA_UNLIKELY(abort_on_warn == -1))
337 if (getenv("ELM_ERROR_ABORT")) abort_on_warn = 1;
338 else abort_on_warn = 0;
340 if (abort_on_warn == 1) abort();
342 sd->subobjs = eina_list_remove(sd->subobjs, sobj);
343 if (!sd->child_can_focus)
345 if (elm_widget_can_focus_get(sobj)) sd->child_can_focus = 0;
347 if (_elm_widget_is(sobj))
349 Smart_Data *sd2 = evas_object_smart_data_get(sobj);
350 if (sd2) sd2->parent_obj = NULL;
351 if (elm_widget_focus_get(sobj)) _unfocus_parents(obj);
353 evas_object_event_callback_del_full(sobj, EVAS_CALLBACK_DEL, _sub_obj_del, sd);
354 evas_object_smart_callback_call(obj, "sub-object-del", sobj);
358 elm_widget_resize_object_set(Evas_Object *obj, Evas_Object *sobj)
363 evas_object_data_del(sd->resize_obj, "elm-parent");
364 if (_elm_widget_is(sd->resize_obj))
366 Smart_Data *sd2 = evas_object_smart_data_get(sd->resize_obj);
367 if (sd2) sd2->parent_obj = NULL;
369 evas_object_event_callback_del_full(sd->resize_obj, EVAS_CALLBACK_DEL,
371 evas_object_event_callback_del_full(sd->resize_obj, EVAS_CALLBACK_MOUSE_DOWN,
372 _sub_obj_mouse_down, sd);
373 evas_object_smart_member_del(sd->resize_obj);
374 if (_elm_widget_is(sd->resize_obj))
376 if (elm_widget_focus_get(sd->resize_obj)) _unfocus_parents(obj);
379 sd->resize_obj = sobj;
382 if (_elm_widget_is(sd->resize_obj))
384 Smart_Data *sd2 = evas_object_smart_data_get(sd->resize_obj);
385 if (sd2) sd2->parent_obj = obj;
387 evas_object_clip_set(sobj, evas_object_clip_get(obj));
388 evas_object_smart_member_add(sobj, obj);
389 evas_object_event_callback_add(sobj, EVAS_CALLBACK_DEL, _sub_obj_del, sd);
390 evas_object_event_callback_add(sobj, EVAS_CALLBACK_MOUSE_DOWN,
391 _sub_obj_mouse_down, sd);
392 _smart_reconfigure(sd);
393 evas_object_data_set(sobj, "elm-parent", obj);
394 evas_object_smart_callback_call(obj, "sub-object-add", sobj);
395 if (_elm_widget_is(sobj))
397 if (elm_widget_focus_get(sobj)) _focus_parents(obj);
403 elm_widget_hover_object_set(Evas_Object *obj, Evas_Object *sobj)
408 evas_object_event_callback_del_full(sd->hover_obj, EVAS_CALLBACK_DEL,
411 sd->hover_obj = sobj;
414 evas_object_event_callback_add(sobj, EVAS_CALLBACK_DEL, _sub_obj_del, sd);
415 _smart_reconfigure(sd);
420 elm_widget_can_focus_set(Evas_Object *obj, int can_focus)
423 sd->can_focus = can_focus;
427 elm_widget_can_focus_get(const Evas_Object *obj)
430 if (sd->can_focus) return 1;
431 if (sd->child_can_focus) return 1;
436 elm_widget_focus_get(const Evas_Object *obj)
443 elm_widget_focused_object_get(const Evas_Object *obj)
445 const Evas_Object *subobj;
447 API_ENTRY return NULL;
449 if (!sd->focused) return NULL;
450 EINA_LIST_FOREACH(sd->subobjs, l, subobj)
452 Evas_Object *fobj = elm_widget_focused_object_get(subobj);
453 if (fobj) return fobj;
455 return (Evas_Object *)obj;
459 elm_widget_top_get(const Evas_Object *obj)
462 API_ENTRY return NULL;
463 if (sd->parent_obj) return elm_widget_top_get(sd->parent_obj);
464 return (Evas_Object *)obj;
466 Smart_Data *sd = evas_object_smart_data_get(obj);
469 if (!obj) return NULL;
470 if ((sd) && _elm_widget_is(obj))
472 if ((sd->type) && (!strcmp(sd->type, "win")))
473 return (Evas_Object *)obj;
475 return elm_widget_top_get(sd->parent_obj);
477 par = evas_object_smart_parent_get(obj);
478 if (!par) return (Evas_Object *)obj;
479 return elm_widget_top_get(par);
484 elm_widget_is(const Evas_Object *obj)
486 return _elm_widget_is(obj);
490 elm_widget_parent_widget_get(const Evas_Object *obj)
494 if (_elm_widget_is(obj))
496 Smart_Data *sd = evas_object_smart_data_get(obj);
497 if (!sd) return NULL;
498 parent = sd->parent_obj;
502 parent = evas_object_data_get(obj, "elm-parent");
504 parent = evas_object_smart_data_get(obj);
509 Evas_Object *elm_parent;
510 if (_elm_widget_is(parent)) break;
511 elm_parent = evas_object_data_get(parent, "elm-parent");
515 parent = evas_object_smart_parent_get(parent);
521 elm_widget_focus_jump(Evas_Object *obj, int forward)
524 if (!elm_widget_can_focus_get(obj)) return 0;
526 /* if it has a focus func its an end-point widget like a button */
532 sd->focus_order = focus_order;
535 else sd->focused = 0;
536 if (sd->on_focus_func) sd->on_focus_func(sd->on_focus_data, obj);
540 /* its some container */
549 elm_widget_focus_set(obj, forward);
556 if (elm_widget_can_focus_get(sd->resize_obj))
559 (!elm_widget_disabled_get(sd->resize_obj)))
561 /* the previous focused item was unfocused - so focus
562 * the next one (that can be focused) */
563 if (elm_widget_focus_jump(sd->resize_obj, forward))
569 if (elm_widget_focus_get(sd->resize_obj))
571 /* jump to the next focused item or focus this item */
572 if (elm_widget_focus_jump(sd->resize_obj, forward))
574 /* it returned 0 - it got to the last item and is past it */
583 EINA_LIST_FOREACH(sd->subobjs, l, child)
585 if (elm_widget_can_focus_get(child))
588 (!elm_widget_disabled_get(child)))
590 /* the previous focused item was unfocused - so focus
591 * the next one (that can be focused) */
592 if (elm_widget_focus_jump(child, forward))
598 if (elm_widget_focus_get(child))
600 /* jump to the next focused item or focus this item */
601 if (elm_widget_focus_jump(child, forward))
603 /* it returned 0 - it got to the last item and is past it */
616 EINA_LIST_REVERSE_FOREACH(sd->subobjs, l, child)
618 if (elm_widget_can_focus_get(child))
621 (!elm_widget_disabled_get(child)))
623 /* the previous focused item was unfocused - so focus
624 * the next one (that can be focused) */
625 if (elm_widget_focus_jump(child, forward))
631 if (elm_widget_focus_get(child))
633 /* jump to the next focused item or focus this item */
634 if (elm_widget_focus_jump(child, forward))
636 /* it returned 0 - it got to the last item and is past it */
644 if (elm_widget_can_focus_get(sd->resize_obj))
647 (!elm_widget_disabled_get(sd->resize_obj)))
649 /* the previous focused item was unfocused - so focus
650 * the next one (that can be focused) */
651 if (elm_widget_focus_jump(sd->resize_obj, forward))
656 if (elm_widget_focus_get(sd->resize_obj))
658 /* jump to the next focused item or focus this item */
659 if (elm_widget_focus_jump(sd->resize_obj, forward))
661 /* it returned 0 - it got to the last item and is past it */
670 /* no next item can be focused */
674 if (sd->on_focus_func) sd->on_focus_func(sd->on_focus_data, obj);
680 elm_widget_signal_emit(Evas_Object *obj, const char *emission, const char *source)
683 if (!sd->signal_func) return;
684 sd->signal_func(obj, emission, source);
688 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)
691 if (!sd->callback_add_func) return;
692 sd->callback_add_func(obj, emission, source, func, data);
696 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))
698 API_ENTRY return NULL;
699 if (!sd->callback_del_func) return NULL;
700 return sd->callback_del_func(obj, emission, source, func);
704 elm_widget_focus_set(Evas_Object *obj, int first)
710 sd->focus_order = focus_order;
712 if (sd->on_focus_func) sd->on_focus_func(sd->on_focus_data, obj);
723 if ((elm_widget_can_focus_get(sd->resize_obj)) &&
724 (!elm_widget_disabled_get(sd->resize_obj)))
726 elm_widget_focus_set(sd->resize_obj, first);
732 EINA_LIST_FOREACH(sd->subobjs, l, child)
734 if ((elm_widget_can_focus_get(child)) &&
735 (!elm_widget_disabled_get(child)))
737 elm_widget_focus_set(child, first);
747 EINA_LIST_REVERSE_FOREACH(sd->subobjs, l, child)
749 if ((elm_widget_can_focus_get(child)) &&
750 (!elm_widget_disabled_get(child)))
752 elm_widget_focus_set(child, first);
758 if ((elm_widget_can_focus_get(sd->resize_obj)) &&
759 (!elm_widget_disabled_get(sd->resize_obj)))
761 elm_widget_focus_set(sd->resize_obj, first);
769 elm_widget_parent_get(const Evas_Object *obj)
771 API_ENTRY return NULL;
772 return sd->parent_obj;
776 elm_widget_focused_object_clear(Evas_Object *obj)
779 if (!sd->focused) return;
780 if (elm_widget_focus_get(sd->resize_obj))
781 elm_widget_focused_object_clear(sd->resize_obj);
786 EINA_LIST_FOREACH(sd->subobjs, l, child)
788 if (elm_widget_focus_get(child))
790 elm_widget_focused_object_clear(child);
796 if (sd->on_focus_func) sd->on_focus_func(sd->on_focus_data, obj);
797 if (sd->focus_func) sd->focus_func(obj);
801 _elm_widget_parent_focus(Evas_Object *obj)
804 Evas_Object *o = elm_widget_parent_get(obj);
806 if (sd->focused) return;
807 if (o) _elm_widget_parent_focus(o);
809 sd->focus_order = focus_order;
811 if (sd->on_focus_func) sd->on_focus_func(sd->on_focus_data, obj);
812 if (sd->focus_func) sd->focus_func(obj);
816 elm_widget_focus_steal(Evas_Object *obj)
818 Evas_Object *parent, *o;
821 if (sd->focused) return;
822 if (sd->disabled) return;
826 o = elm_widget_parent_get(parent);
828 sd = evas_object_smart_data_get(o);
829 if (sd->focused) break;
832 if (!elm_widget_parent_get(parent))
833 elm_widget_focused_object_clear(parent);
836 parent = elm_widget_parent_get(parent);
837 sd = evas_object_smart_data_get(parent);
838 if (elm_widget_focus_get(sd->resize_obj))
840 elm_widget_focused_object_clear(sd->resize_obj);
846 EINA_LIST_FOREACH(sd->subobjs, l, child)
848 if (elm_widget_focus_get(child))
850 elm_widget_focused_object_clear(child);
856 _elm_widget_parent_focus(obj);
861 elm_widget_activate(Evas_Object *obj)
864 elm_widget_change(obj);
865 if (sd->activate_func) sd->activate_func(obj);
869 elm_widget_change(Evas_Object *obj)
872 elm_widget_change(elm_widget_parent_get(obj));
873 if (sd->on_change_func) sd->on_change_func(sd->on_change_data, obj);
877 elm_widget_disabled_set(Evas_Object *obj, int disabled)
881 if (sd->disabled == disabled) return;
882 sd->disabled = disabled;
885 Evas_Object *o, *parent;
890 o = elm_widget_parent_get(parent);
894 elm_widget_focus_jump(parent, 1);
896 if (sd->disable_func) sd->disable_func(obj);
900 elm_widget_disabled_get(const Evas_Object *obj)
906 #ifdef HAVE_CONFORMANT_AUTOSCROLL
908 elm_widget_imp_region_get(const Evas_Object *obj, Evas_Coord *x, Evas_Coord *y, Evas_Coord *w, Evas_Coord *h)
911 if (sd->imp_region_get_func)
912 return sd->imp_region_get_func(obj, x, y, w, h);
919 elm_widget_show_region_set(Evas_Object *obj, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h)
922 if ((x == sd->rx) && (y == sd->ry) && (w == sd->rw) && (h == sd->rh)) return;
927 if (sd->on_show_region_func)
928 sd->on_show_region_func(sd->on_show_region_data, obj);
930 Evas_Object *parent_obj, *child_obj;
931 Evas_Coord px, py, cx, cy;
934 parent_obj = sd->parent_obj;
936 sd = evas_object_smart_data_get(parent_obj);
938 if ((!parent_obj) || (!sd) || (!_elm_widget_is(parent_obj))) break;
940 evas_object_geometry_get(parent_obj, &px, &py, NULL, NULL);
941 evas_object_geometry_get(child_obj, &cx, &cy, NULL, NULL);
950 if (sd->on_show_region_func)
952 sd->on_show_region_func(sd->on_show_region_data, parent_obj);
959 elm_widget_show_region_get(const Evas_Object *obj, Evas_Coord *x, Evas_Coord *y, Evas_Coord *w, Evas_Coord *h)
969 elm_widget_scroll_hold_push(Evas_Object *obj)
973 if (sd->scroll_hold == 1)
974 evas_object_smart_callback_call(obj, "scroll-hold-on", obj);
975 if (sd->parent_obj) elm_widget_scroll_hold_push(sd->parent_obj);
976 // FIXME: on delete/reparent hold pop
980 elm_widget_scroll_hold_pop(Evas_Object *obj)
984 if (sd->scroll_hold < 0) sd->scroll_hold = 0;
985 if (sd->scroll_hold == 0)
986 evas_object_smart_callback_call(obj, "scroll-hold-off", obj);
987 if (sd->parent_obj) elm_widget_scroll_hold_pop(sd->parent_obj);
991 elm_widget_scroll_hold_get(const Evas_Object *obj)
994 return sd->scroll_hold;
998 elm_widget_scroll_freeze_push(Evas_Object *obj)
1001 sd->scroll_freeze++;
1002 if (sd->scroll_freeze == 1)
1003 evas_object_smart_callback_call(obj, "scroll-freeze-on", obj);
1004 if (sd->parent_obj) elm_widget_scroll_freeze_push(sd->parent_obj);
1005 // FIXME: on delete/reparent freeze pop
1009 elm_widget_scroll_freeze_pop(Evas_Object *obj)
1012 sd->scroll_freeze--;
1013 if (sd->scroll_freeze < 0) sd->scroll_freeze = 0;
1014 if (sd->scroll_freeze == 0)
1015 evas_object_smart_callback_call(obj, "scroll-freeze-off", obj);
1016 if (sd->parent_obj) elm_widget_scroll_freeze_pop(sd->parent_obj);
1020 elm_widget_scroll_freeze_get(const Evas_Object *obj)
1023 return sd->scroll_freeze;
1027 elm_widget_scale_set(Evas_Object *obj, double scale)
1030 if (scale <= 0.0) scale = 0.0;
1031 if (sd->scale != scale)
1034 elm_widget_theme(obj);
1039 elm_widget_scale_get(const Evas_Object *obj)
1041 API_ENTRY return 1.0;
1042 // FIXME: save walking up the tree by storing/caching parent scale
1043 if (sd->scale == 0.0)
1046 return elm_widget_scale_get(sd->parent_obj);
1054 elm_widget_theme_set(Evas_Object *obj, Elm_Theme *th)
1057 if (sd->theme != th)
1059 if (sd->theme) elm_theme_free(sd->theme);
1062 elm_widget_theme(obj);
1067 elm_widget_theme_get(const Evas_Object *obj)
1069 API_ENTRY return NULL;
1073 return elm_widget_theme_get(sd->parent_obj);
1081 elm_widget_style_set(Evas_Object *obj, const char *style)
1085 if (eina_stringshare_replace(&sd->style, style))
1086 elm_widget_theme(obj);
1090 elm_widget_style_get(const Evas_Object *obj)
1092 API_ENTRY return "";
1093 if (sd->style) return sd->style;
1098 elm_widget_type_set(Evas_Object *obj, const char *type)
1101 eina_stringshare_replace(&sd->type, type);
1105 elm_widget_type_get(const Evas_Object *obj)
1107 API_ENTRY return "";
1108 if (sd->type) return sd->type;
1113 _propagate_x_drag_lock(Evas_Object *obj, int dir)
1115 Smart_Data *sd = evas_object_smart_data_get(obj);
1118 Smart_Data *sd2 = evas_object_smart_data_get(sd->parent_obj);
1121 sd2->child_drag_x_locked += dir;
1122 _propagate_x_drag_lock(sd->parent_obj, dir);
1128 _propagate_y_drag_lock(Evas_Object *obj, int dir)
1130 Smart_Data *sd = evas_object_smart_data_get(obj);
1133 Smart_Data *sd2 = evas_object_smart_data_get(sd->parent_obj);
1136 sd2->child_drag_y_locked += dir;
1137 _propagate_y_drag_lock(sd->parent_obj, dir);
1142 elm_widget_drag_lock_x_set(Evas_Object *obj, Eina_Bool lock)
1145 if (sd->drag_x_locked == lock) return;
1146 sd->drag_x_locked = lock;
1147 if (sd->drag_x_locked) _propagate_x_drag_lock(obj, 1);
1148 else _propagate_x_drag_lock(obj, -1);
1152 elm_widget_drag_lock_y_set(Evas_Object *obj, Eina_Bool lock)
1155 if (sd->drag_y_locked == lock) return;
1156 sd->drag_y_locked = lock;
1157 if (sd->drag_y_locked) _propagate_y_drag_lock(obj, 1);
1158 else _propagate_y_drag_lock(obj, -1);
1162 elm_widget_drag_lock_x_get(const Evas_Object *obj)
1164 API_ENTRY return EINA_FALSE;
1165 return sd->drag_x_locked;
1169 elm_widget_drag_lock_y_get(const Evas_Object *obj)
1171 API_ENTRY return EINA_FALSE;
1172 return sd->drag_y_locked;
1176 elm_widget_drag_child_locked_x_get(const Evas_Object *obj)
1179 return sd->child_drag_x_locked;
1183 elm_widget_drag_child_locked_y_get(const Evas_Object *obj)
1186 return sd->child_drag_y_locked;
1199 /* local subsystem functions */
1201 _smart_reconfigure(Smart_Data *sd)
1205 evas_object_move(sd->resize_obj, sd->x, sd->y);
1206 evas_object_resize(sd->resize_obj, sd->w, sd->h);
1210 evas_object_move(sd->hover_obj, sd->x, sd->y);
1211 evas_object_resize(sd->hover_obj, sd->w, sd->h);
1216 _smart_add(Evas_Object *obj)
1220 sd = calloc(1, sizeof(Smart_Data));
1228 evas_object_smart_data_set(obj, sd);
1231 static Evas_Object *
1232 _newest_focus_order_get(Evas_Object *obj, unsigned int *newest_focus_order)
1235 Evas_Object *child, *ret, *best;
1237 API_ENTRY return NULL;
1238 if (!evas_object_visible_get(obj)) return NULL;
1240 if (*newest_focus_order < sd->focus_order)
1242 *newest_focus_order = sd->focus_order;
1245 EINA_LIST_FOREACH(sd->subobjs, l, child)
1247 ret = _newest_focus_order_get(child, newest_focus_order);
1255 _if_focused_revert(Evas_Object *obj)
1258 Evas_Object *newest = NULL;
1259 unsigned int newest_focus_order = 0;
1263 if (!sd->focused) return;
1264 if (!sd->parent_obj) return;
1266 top = elm_widget_top_get(sd->parent_obj);
1269 newest = _newest_focus_order_get(top, &newest_focus_order);
1272 elm_object_unfocus(newest);
1273 elm_object_focus(newest);
1279 _smart_del(Evas_Object *obj)
1284 if (sd->del_pre_func) sd->del_pre_func(obj);
1287 sobj = sd->resize_obj;
1288 sd->resize_obj = NULL;
1289 evas_object_event_callback_del_full(sobj, EVAS_CALLBACK_DEL, _sub_obj_del, sd);
1290 evas_object_smart_callback_call(sd->obj, "sub-object-del", sobj);
1291 evas_object_del(sobj);
1295 sobj = sd->hover_obj;
1296 sd->hover_obj = NULL;
1297 evas_object_event_callback_del_full(sobj, EVAS_CALLBACK_DEL, _sub_obj_del, sd);
1298 evas_object_smart_callback_call(sd->obj, "sub-object-del", sobj);
1299 evas_object_del(sobj);
1301 EINA_LIST_FREE(sd->subobjs, sobj)
1303 evas_object_event_callback_del_full(sobj, EVAS_CALLBACK_DEL, _sub_obj_del, sd);
1304 evas_object_smart_callback_call(sd->obj, "sub-object-del", sobj);
1305 evas_object_del(sobj);
1307 if (sd->del_func) sd->del_func(obj);
1308 if (sd->style) eina_stringshare_del(sd->style);
1309 if (sd->type) eina_stringshare_del(sd->type);
1310 if (sd->theme) elm_theme_free(sd->theme);
1311 _if_focused_revert(obj);
1316 _smart_move(Evas_Object *obj, Evas_Coord x, Evas_Coord y)
1321 _smart_reconfigure(sd);
1325 _smart_resize(Evas_Object *obj, Evas_Coord w, Evas_Coord h)
1330 _smart_reconfigure(sd);
1334 _smart_show(Evas_Object *obj)
1336 Eina_List *list, *l;
1339 list = evas_object_smart_members_get(obj);
1340 EINA_LIST_FOREACH(list, l, o)
1342 if (evas_object_data_get(o, "_elm_leaveme")) continue;
1343 evas_object_show(o);
1348 _smart_hide(Evas_Object *obj)
1350 Eina_List *list, *l;
1353 list = evas_object_smart_members_get(obj);
1354 EINA_LIST_FOREACH(list, l, o)
1356 if (evas_object_data_get(o, "_elm_leaveme")) continue;
1357 evas_object_hide(o);
1359 _if_focused_revert(obj);
1363 _smart_color_set(Evas_Object *obj, int r, int g, int b, int a)
1365 Eina_List *list, *l;
1368 list = evas_object_smart_members_get(obj);
1369 EINA_LIST_FOREACH(list, l, o)
1371 if (evas_object_data_get(o, "_elm_leaveme")) continue;
1372 evas_object_color_set(o, r, g, b, a);
1377 _smart_clip_set(Evas_Object *obj, Evas_Object *clip)
1379 Eina_List *list, *l;
1382 list = evas_object_smart_members_get(obj);
1383 EINA_LIST_FOREACH(list, l, o)
1385 if (evas_object_data_get(o, "_elm_leaveme")) continue;
1386 evas_object_clip_set(o, clip);
1391 _smart_clip_unset(Evas_Object *obj)
1393 Eina_List *list, *l;
1396 list = evas_object_smart_members_get(obj);
1397 EINA_LIST_FOREACH(list, l, o)
1399 if (evas_object_data_get(o, "_elm_leaveme")) continue;
1400 evas_object_clip_unset(o);
1405 _smart_calculate(Evas_Object *obj)
1408 if (sd->changed_func) sd->changed_func(obj);
1411 /* never need to touch this */
1416 if (_e_smart) return;
1418 static const Evas_Smart_Class sc =
1421 EVAS_SMART_CLASS_VERSION,
1439 _e_smart = evas_smart_class_new(&sc);
1446 _elm_stringlist_get(const char *str)
1448 Eina_List *list = NULL;
1450 if (!str) return NULL;
1451 for (b = s = str; 1; s++)
1453 if ((*s == ' ') || (*s == 0))
1455 char *t = malloc(s - b + 1);
1458 strncpy(t, b, s - b);
1460 list = eina_list_append(list, eina_stringshare_add(t));
1471 _elm_stringlist_free(Eina_List *list)
1474 EINA_LIST_FREE(list, s) eina_stringshare_del(s);
1478 _elm_widget_type_check(const Evas_Object *obj, const char *type)
1480 const char *provided, *expected = "(unknown)";
1481 static int abort_on_warn = -1;
1482 provided = elm_widget_type_get(obj);
1483 if (EINA_LIKELY(provided == type)) return EINA_TRUE;
1484 if (type) expected = type;
1485 if ((!provided) || (provided[0] == 0))
1487 provided = evas_object_type_get(obj);
1488 if ((!provided) || (provided[0] == 0))
1489 provided = "(unknown)";
1491 ERR("Passing Object: %p, of type: '%s' when expecting type: '%s'", obj, provided, expected);
1492 if (abort_on_warn == -1)
1494 if (getenv("ELM_ERROR_ABORT")) abort_on_warn = 1;
1495 else abort_on_warn = 0;
1497 if (abort_on_warn == 1) abort();
1501 static inline Eina_Bool
1502 _elm_widget_is(const Evas_Object *obj)
1504 const char *type = evas_object_type_get(obj);
1505 return type == SMART_NAME;