1 #include "evas_common.h"
2 #include "evas_private.h"
4 typedef struct _Evas_Object_Smart Evas_Object_Smart;
5 typedef struct _Evas_Smart_Callback Evas_Smart_Callback;
7 struct _Evas_Object_Smart
13 Eina_Inlist *contained;
14 Evas_Smart_Cb_Description_Array callbacks_descriptions;
17 Eina_Bool deletions_waiting : 1;
18 Eina_Bool need_recalculate : 1;
19 Eina_Bool update_boundingbox_needed : 1;
22 struct _Evas_Smart_Callback
27 Evas_Callback_Priority priority;
31 /* private methods for smart objects */
32 static void evas_object_smart_callbacks_clear(Evas_Object *obj);
33 static void evas_object_smart_init(Evas_Object *obj);
34 static void *evas_object_smart_new(void);
35 static void evas_object_smart_render(Evas_Object *obj, void *output, void *context, void *surface, int x, int y);
36 static void evas_object_smart_free(Evas_Object *obj);
37 static void evas_object_smart_render_pre(Evas_Object *obj);
38 static void evas_object_smart_render_post(Evas_Object *obj);
40 static unsigned int evas_object_smart_id_get(Evas_Object *obj);
41 static unsigned int evas_object_smart_visual_id_get(Evas_Object *obj);
42 static void *evas_object_smart_engine_data_get(Evas_Object *obj);
44 static const Evas_Object_Func object_func =
46 /* methods (compulsory) */
47 evas_object_smart_free,
48 evas_object_smart_render,
49 evas_object_smart_render_pre,
50 evas_object_smart_render_post,
51 evas_object_smart_id_get,
52 evas_object_smart_visual_id_get,
53 evas_object_smart_engine_data_get,
54 /* these are optional. NULL = nothing */
70 EVAS_MEMPOOL(_mp_obj);
75 evas_object_smart_data_set(Evas_Object *obj, void *data)
79 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
82 o = (Evas_Object_Smart *)(obj->object_data);
83 MAGIC_CHECK(o, Evas_Object_Smart, MAGIC_OBJ_SMART);
90 evas_object_smart_data_get(const Evas_Object *obj)
94 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
97 o = (Evas_Object_Smart *)(obj->object_data);
99 if (o->magic != MAGIC_OBJ_SMART) return NULL;
104 evas_object_smart_interface_get(const Evas_Object *obj,
110 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
114 s = evas_object_smart_smart_get(obj);
116 for (i = 0; i < s->interfaces.size; i++)
118 const Evas_Smart_Interface *iface;
120 iface = s->interfaces.array[i];
122 if (iface->name == name)
130 evas_object_smart_interface_data_get(const Evas_Object *obj,
131 const Evas_Smart_Interface *iface)
136 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
140 s = evas_object_smart_smart_get(obj);
142 for (i = 0; i < s->interfaces.size; i++)
144 if (iface == s->interfaces.array[i])
145 return obj->interface_privates[i];
152 evas_object_smart_smart_get(const Evas_Object *obj)
154 Evas_Object_Smart *o;
156 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
159 o = (Evas_Object_Smart *)(obj->object_data);
160 MAGIC_CHECK(o, Evas_Object_Smart, MAGIC_OBJ_SMART);
163 return obj->smart.smart;
167 evas_object_smart_member_add(Evas_Object *obj, Evas_Object *smart_obj)
169 Evas_Object_Smart *o;
171 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
174 MAGIC_CHECK(smart_obj, Evas_Object, MAGIC_OBJ);
177 o = (Evas_Object_Smart *)(smart_obj->object_data);
178 MAGIC_CHECK(o, Evas_Object_Smart, MAGIC_OBJ_SMART);
184 CRIT("Adding deleted object %p to smart obj %p", obj, smart_obj);
188 if (smart_obj->delete_me)
190 CRIT("Adding object %p to deleted smart obj %p", obj, smart_obj);
194 if (!smart_obj->layer)
196 CRIT("No evas surface associated with smart object (%p)", smart_obj);
200 if ((obj->layer && smart_obj->layer) &&
201 (obj->layer->evas != smart_obj->layer->evas))
203 CRIT("Adding object %p from Evas (%p) from another Evas (%p)", obj, obj->layer->evas, smart_obj->layer->evas);
208 if (obj->smart.parent == smart_obj) return;
210 if (obj->smart.parent) evas_object_smart_member_del(obj);
213 evas_object_release(obj, 1);
214 obj->layer = smart_obj->layer;
215 obj->cur.layer = obj->layer->layer;
217 obj->smart.parent = smart_obj;
218 o->contained = eina_inlist_append(o->contained, EINA_INLIST_GET(obj));
219 evas_object_smart_member_cache_invalidate(obj, EINA_TRUE, EINA_TRUE);
221 evas_object_change(obj);
222 evas_object_mapped_clip_across_mark(obj);
223 if (smart_obj->smart.smart->smart_class->member_add)
224 smart_obj->smart.smart->smart_class->member_add(smart_obj, obj);
225 evas_object_update_bounding_box(obj);
229 evas_object_smart_member_del(Evas_Object *obj)
231 Evas_Object_Smart *o;
232 Evas_Object *smart_obj;
234 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
238 if (!obj->smart.parent) return;
240 smart_obj = obj->smart.parent;
241 if (smart_obj->smart.smart->smart_class->member_del)
242 smart_obj->smart.smart->smart_class->member_del(smart_obj, obj);
244 o = (Evas_Object_Smart *)(obj->smart.parent->object_data);
245 o->contained = eina_inlist_remove(o->contained, EINA_INLIST_GET(obj));
247 obj->smart.parent = NULL;
248 evas_object_smart_member_cache_invalidate(obj, EINA_TRUE, EINA_TRUE);
250 obj->cur.layer = obj->layer->layer;
251 evas_object_inject(obj, obj->layer->evas);
253 evas_object_change(obj);
254 evas_object_mapped_clip_across_mark(obj);
258 evas_object_smart_parent_get(const Evas_Object *obj)
260 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
264 return obj->smart.parent;
268 evas_object_smart_type_check(const Evas_Object *obj, const char *type)
270 const Evas_Smart_Class *sc;
272 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
276 EINA_SAFETY_ON_FALSE_RETURN_VAL(type, EINA_FALSE);
278 if (!obj->smart.smart)
280 sc = obj->smart.smart->smart_class;
283 if (!strcmp(sc->name, type))
292 evas_object_smart_type_check_ptr(const Evas_Object *obj, const char *type)
294 const Evas_Smart_Class *sc;
296 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
300 EINA_SAFETY_ON_FALSE_RETURN_VAL(type, EINA_FALSE);
302 if (!obj->smart.smart)
304 sc = obj->smart.smart->smart_class;
307 if (sc->name == type)
316 evas_object_smart_members_get(const Evas_Object *obj)
318 Evas_Object_Smart *o;
322 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
325 if (!obj->smart.smart) return NULL;
326 o = (Evas_Object_Smart *)(obj->object_data);
327 MAGIC_CHECK(o, Evas_Object_Smart, MAGIC_OBJ_SMART);
332 for (member = o->contained; member; member = member->next)
333 members = eina_list_append(members, member);
339 evas_object_smart_members_get_direct(const Evas_Object *obj)
341 Evas_Object_Smart *o;
343 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
346 if (!obj->smart.smart) return NULL;
347 o = (Evas_Object_Smart *)(obj->object_data);
348 MAGIC_CHECK(o, Evas_Object_Smart, MAGIC_OBJ_SMART);
355 _evas_object_smart_members_all_del(Evas_Object *obj)
357 Evas_Object_Smart *o = (Evas_Object_Smart *)(obj->object_data);
360 EINA_INLIST_FOREACH_SAFE(o->contained, itrn, memobj)
362 evas_object_del((Evas_Object *) memobj);
367 _evas_smart_class_ifaces_private_data_alloc(Evas_Object *obj,
370 unsigned int i, total_priv_sz = 0;
371 const Evas_Smart_Class *sc;
374 /* get total size of interfaces private data */
375 for (sc = s->smart_class; sc; sc = sc->parent)
377 const Evas_Smart_Interface **ifaces_array = sc->interfaces;
378 if (!ifaces_array) continue;
380 while (*ifaces_array)
382 const Evas_Smart_Interface *iface = *ifaces_array;
384 if (!iface->name) break;
386 if (iface->private_size > 0)
388 unsigned int size = iface->private_size;
390 if (size % sizeof(void *) != 0)
391 size += sizeof(void *) - (size % sizeof(void *));
392 total_priv_sz += size;
399 obj->interface_privates = malloc
400 (s->interfaces.size * sizeof(void *) + total_priv_sz);
401 if (!obj->interface_privates)
403 ERR("malloc failed!");
407 /* make private data array ptrs point to right places, WHICH LIE ON
408 * THE SAME STRUCT, AFTER THE # OF INTERFACES COUNT */
409 ptr = (unsigned char *)(obj->interface_privates + s->interfaces.size);
410 for (i = 0; i < s->interfaces.size; i++)
414 size = s->interfaces.array[i]->private_size;
418 obj->interface_privates[i] = NULL;
422 obj->interface_privates[i] = ptr;
423 memset(ptr, 0, size);
425 if (size % sizeof(void *) != 0)
426 size += sizeof(void *) - (size % sizeof(void *));
432 evas_object_smart_add(Evas *e, Evas_Smart *s)
437 MAGIC_CHECK(e, Evas, MAGIC_EVAS);
440 MAGIC_CHECK(s, Evas_Smart, MAGIC_SMART);
444 obj = evas_object_new(e);
445 if (!obj) return NULL;
446 obj->smart.smart = s;
447 obj->type = s->smart_class->name;
448 evas_object_smart_init(obj);
449 evas_object_inject(obj, e);
451 evas_object_smart_use(s);
453 _evas_smart_class_ifaces_private_data_alloc(obj, s);
455 for (i = 0; i < s->interfaces.size; i++)
457 const Evas_Smart_Interface *iface;
459 iface = s->interfaces.array[i];
462 if (!iface->add(obj))
464 ERR("failed to create interface %s\n", iface->name);
465 evas_object_del(obj);
471 if (s->smart_class->add) s->smart_class->add(obj);
477 _callback_priority_cmp(const void *_a, const void *_b)
479 const Evas_Smart_Callback *a, *b;
480 a = (const Evas_Smart_Callback *) _a;
481 b = (const Evas_Smart_Callback *) _b;
482 if (a->priority < b->priority)
489 evas_object_smart_callback_add(Evas_Object *obj, const char *event, Evas_Smart_Cb func, const void *data)
491 evas_object_smart_callback_priority_add(obj, event,
492 EVAS_CALLBACK_PRIORITY_DEFAULT, func, data);
496 evas_object_smart_callback_priority_add(Evas_Object *obj, const char *event, Evas_Callback_Priority priority, Evas_Smart_Cb func, const void *data)
498 Evas_Object_Smart *o;
499 Evas_Smart_Callback *cb;
501 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
504 o = (Evas_Object_Smart *)(obj->object_data);
505 MAGIC_CHECK(o, Evas_Object_Smart, MAGIC_OBJ_SMART);
510 EVAS_MEMPOOL_INIT(_mp_cb, "evas_smart_callback", Evas_Smart_Callback, 32, );
511 cb = EVAS_MEMPOOL_ALLOC(_mp_cb, Evas_Smart_Callback);
513 EVAS_MEMPOOL_PREP(_mp_cb, cb, Evas_Smart_Callback);
514 cb->event = eina_stringshare_add(event);
516 cb->func_data = (void *)data;
517 cb->priority = priority;
518 o->callbacks = eina_list_sorted_insert(o->callbacks, _callback_priority_cmp,
523 evas_object_smart_callback_del(Evas_Object *obj, const char *event, Evas_Smart_Cb func)
525 Evas_Object_Smart *o;
527 Evas_Smart_Callback *cb;
529 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
532 o = (Evas_Object_Smart *)(obj->object_data);
533 MAGIC_CHECK(o, Evas_Object_Smart, MAGIC_OBJ_SMART);
536 if (!event) return NULL;
537 EINA_LIST_FOREACH(o->callbacks, l, cb)
539 if ((!strcmp(cb->event, event)) && (cb->func == func))
543 data = cb->func_data;
545 o->deletions_waiting = 1;
546 evas_object_smart_callbacks_clear(obj);
554 evas_object_smart_callback_del_full(Evas_Object *obj, const char *event, Evas_Smart_Cb func, const void *data)
556 Evas_Object_Smart *o;
558 Evas_Smart_Callback *cb;
560 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
563 o = (Evas_Object_Smart *)(obj->object_data);
564 MAGIC_CHECK(o, Evas_Object_Smart, MAGIC_OBJ_SMART);
567 if (!event) return NULL;
568 EINA_LIST_FOREACH(o->callbacks, l, cb)
570 if ((!strcmp(cb->event, event)) && (cb->func == func) && (cb->func_data == data))
576 o->deletions_waiting = 1;
577 evas_object_smart_callbacks_clear(obj);
585 evas_object_smart_callback_call(Evas_Object *obj, const char *event, void *event_info)
587 Evas_Object_Smart *o;
589 Evas_Smart_Callback *cb;
590 const char *strshare;
592 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
595 o = (Evas_Object_Smart *)(obj->object_data);
596 MAGIC_CHECK(o, Evas_Object_Smart, MAGIC_OBJ_SMART);
600 if (obj->delete_me) return;
602 strshare = eina_stringshare_add(event);
603 EINA_LIST_FOREACH(o->callbacks, l, cb)
607 if (cb->event == strshare)
608 cb->func(cb->func_data, obj, event_info);
613 eina_stringshare_del(strshare);
615 evas_object_smart_callbacks_clear(obj);
619 evas_object_smart_callbacks_descriptions_set(Evas_Object *obj, const Evas_Smart_Cb_Description *descriptions)
621 const Evas_Smart_Cb_Description *d;
622 Evas_Object_Smart *o;
623 unsigned int i, count = 0;
625 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
628 o = (Evas_Object_Smart *)(obj->object_data);
629 MAGIC_CHECK(o, Evas_Object_Smart, MAGIC_OBJ_SMART);
633 if ((!descriptions) || (!descriptions->name))
635 evas_smart_cb_descriptions_resize(&o->callbacks_descriptions, 0);
639 for (count = 0, d = descriptions; d->name; d++)
642 evas_smart_cb_descriptions_resize(&o->callbacks_descriptions, count);
643 if (count == 0) return EINA_TRUE;
645 for (i = 0, d = descriptions; i < count; d++, i++)
646 o->callbacks_descriptions.array[i] = d;
648 evas_smart_cb_descriptions_fix(&o->callbacks_descriptions);
654 evas_object_smart_callbacks_descriptions_get(const Evas_Object *obj, const Evas_Smart_Cb_Description ***class_descriptions, unsigned int *class_count, const Evas_Smart_Cb_Description ***instance_descriptions, unsigned int *instance_count)
656 Evas_Object_Smart *o;
658 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
659 if (class_descriptions) *class_descriptions = NULL;
660 if (class_count) *class_count = 0;
661 if (instance_descriptions) *instance_descriptions = NULL;
662 if (instance_count) *instance_count = 0;
665 o = (Evas_Object_Smart *)(obj->object_data);
666 MAGIC_CHECK(o, Evas_Object_Smart, MAGIC_OBJ_SMART);
667 if (class_descriptions) *class_descriptions = NULL;
668 if (class_count) *class_count = 0;
669 if (instance_descriptions) *instance_descriptions = NULL;
670 if (instance_count) *instance_count = 0;
674 if (class_descriptions)
675 *class_descriptions = obj->smart.smart->callbacks.array;
677 *class_count = obj->smart.smart->callbacks.size;
679 if (instance_descriptions)
680 *instance_descriptions = o->callbacks_descriptions.array;
682 *instance_count = o->callbacks_descriptions.size;
686 evas_object_smart_callback_description_find(const Evas_Object *obj, const char *name, const Evas_Smart_Cb_Description **class_description, const Evas_Smart_Cb_Description **instance_description)
688 Evas_Object_Smart *o;
692 if (class_description) *class_description = NULL;
693 if (instance_description) *instance_description = NULL;
697 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
698 if (class_description) *class_description = NULL;
699 if (instance_description) *instance_description = NULL;
702 o = (Evas_Object_Smart *)(obj->object_data);
703 MAGIC_CHECK(o, Evas_Object_Smart, MAGIC_OBJ_SMART);
704 if (class_description) *class_description = NULL;
705 if (instance_description) *instance_description = NULL;
709 if (class_description)
710 *class_description = evas_smart_cb_description_find
711 (&obj->smart.smart->callbacks, name);
713 if (instance_description)
714 *instance_description = evas_smart_cb_description_find
715 (&o->callbacks_descriptions, name);
719 evas_object_smart_need_recalculate_set(Evas_Object *obj, Eina_Bool value)
721 Evas_Object_Smart *o;
722 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
725 o = obj->object_data;
726 MAGIC_CHECK(o, Evas_Object_Smart, MAGIC_OBJ_SMART);
730 // XXX: do i need this?
731 if (obj->delete_me) return;
733 /* remove this entry from calc_list or processed list */
734 if (eina_clist_element_is_linked(&obj->calc_entry))
735 eina_clist_remove(&obj->calc_entry);
739 eina_clist_add_tail(&obj->layer->evas->calc_list, &obj->calc_entry);
741 eina_clist_add_tail(&obj->layer->evas->calc_done, &obj->calc_entry);
743 if (o->need_recalculate == value) return;
745 if (obj->recalculate_cycle > 254)
747 ERR("Object %p is not stable during recalc loop", obj);
750 if (obj->layer->evas->in_smart_calc) obj->recalculate_cycle++;
751 o->need_recalculate = value;
755 evas_object_smart_need_recalculate_get(const Evas_Object *obj)
757 Evas_Object_Smart *o;
758 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
761 o = obj->object_data;
762 MAGIC_CHECK(o, Evas_Object_Smart, MAGIC_OBJ_SMART);
766 return o->need_recalculate;
770 evas_object_smart_calculate(Evas_Object *obj)
772 Evas_Object_Smart *o;
773 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
776 o = obj->object_data;
777 MAGIC_CHECK(o, Evas_Object_Smart, MAGIC_OBJ_SMART);
781 if (!obj->smart.smart->smart_class->calculate)
784 o->need_recalculate = 0;
785 obj->smart.smart->smart_class->calculate(obj);
789 evas_smart_objects_calculate(Evas *e)
791 MAGIC_CHECK(e, Evas, MAGIC_EVAS);
794 evas_call_smarts_calculate(e);
798 evas_smart_objects_calculate_count_get(const Evas *e)
800 MAGIC_CHECK(e, Evas, MAGIC_EVAS);
803 return e->smart_calc_count;
807 * Call calculate() on all smart objects that need_recalculate.
812 evas_call_smarts_calculate(Evas *e)
817 // printf("+CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALC-----------v\n");
818 evas_event_freeze(e);
821 while (NULL != (elem = eina_clist_head(&e->calc_list)))
823 Evas_Object_Smart *o;
825 /* move the item to the processed list */
826 obj = EINA_CLIST_ENTRY(elem, Evas_Object, calc_entry);
827 eina_clist_remove(&obj->calc_entry);
828 if (obj->delete_me) continue;
829 eina_clist_add_tail(&e->calc_done, &obj->calc_entry);
831 o = obj->object_data;
833 if (o->need_recalculate)
835 o->need_recalculate = 0;
836 obj->smart.smart->smart_class->calculate(obj);
840 while (NULL != (elem = eina_clist_head(&e->calc_done)))
842 obj = EINA_CLIST_ENTRY(elem, Evas_Object, calc_entry);
843 obj->recalculate_cycle = 0;
844 eina_clist_remove(&obj->calc_entry);
848 if (e->in_smart_calc == 0) e->smart_calc_count++;
850 evas_event_thaw_eval(e);
854 evas_object_smart_changed(Evas_Object *obj)
856 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
859 evas_object_change(obj);
860 evas_object_smart_need_recalculate_set(obj, 1);
865 evas_object_smart_callbacks_clear(Evas_Object *obj)
867 Evas_Object_Smart *o;
869 Evas_Smart_Callback *cb;
871 o = (Evas_Object_Smart *)(obj->object_data);
873 if (o->walking_list) return;
874 if (!o->deletions_waiting) return;
875 for (l = o->callbacks; l;)
877 cb = eina_list_data_get(l);
878 l = eina_list_next(l);
881 o->callbacks = eina_list_remove(o->callbacks, cb);
882 if (cb->event) eina_stringshare_del(cb->event);
883 EVAS_MEMPOOL_FREE(_mp_cb, cb);
889 evas_object_smart_del(Evas_Object *obj)
894 if (obj->delete_me) return;
895 s = obj->smart.smart;
897 if ((s) && (s->smart_class->del)) s->smart_class->del(obj);
898 if (obj->smart.parent) evas_object_smart_member_del(obj);
900 for (i = 0; i < s->interfaces.size; i++)
902 const Evas_Smart_Interface *iface;
904 iface = s->interfaces.array[i];
905 if (iface->del) iface->del(obj);
908 free(obj->interface_privates);
909 obj->interface_privates = NULL;
911 if (s) evas_object_smart_unuse(s);
915 evas_object_smart_cleanup(Evas_Object *obj)
917 Evas_Object_Smart *o;
919 if (obj->smart.parent)
920 evas_object_smart_member_del(obj);
922 o = (Evas_Object_Smart *)(obj->object_data);
923 if (o->magic == MAGIC_OBJ_SMART)
925 if (obj->calc_entry.next)
926 eina_clist_remove(&obj->calc_entry);
929 evas_object_smart_member_del((Evas_Object *)o->contained);
933 Evas_Smart_Callback *cb = o->callbacks->data;
934 o->callbacks = eina_list_remove(o->callbacks, cb);
935 if (cb->event) eina_stringshare_del(cb->event);
936 EVAS_MEMPOOL_FREE(_mp_cb, cb);
939 evas_smart_cb_descriptions_resize(&o->callbacks_descriptions, 0);
943 obj->smart.parent = NULL;
944 obj->smart.smart = NULL;
948 evas_object_smart_member_cache_invalidate(Evas_Object *obj,
949 Eina_Bool pass_events,
950 Eina_Bool freeze_events)
952 Evas_Object_Smart *o;
955 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
960 obj->parent_cache.pass_events_valid = EINA_FALSE;
962 obj->parent_cache.freeze_events_valid = EINA_FALSE;
964 o = obj->object_data;
965 if (o->magic != MAGIC_OBJ_SMART) return;
967 EINA_INLIST_FOREACH(o->contained, member)
968 evas_object_smart_member_cache_invalidate(member,
974 evas_object_smart_member_raise(Evas_Object *member)
976 Evas_Object_Smart *o;
978 o = (Evas_Object_Smart *)(member->smart.parent->object_data);
979 o->contained = eina_inlist_demote(o->contained, EINA_INLIST_GET(member));
983 evas_object_smart_member_lower(Evas_Object *member)
985 Evas_Object_Smart *o;
987 o = (Evas_Object_Smart *)(member->smart.parent->object_data);
988 o->contained = eina_inlist_promote(o->contained, EINA_INLIST_GET(member));
992 evas_object_smart_member_stack_above(Evas_Object *member, Evas_Object *other)
994 Evas_Object_Smart *o;
996 o = (Evas_Object_Smart *)(member->smart.parent->object_data);
997 o->contained = eina_inlist_remove(o->contained, EINA_INLIST_GET(member));
998 o->contained = eina_inlist_append_relative(o->contained, EINA_INLIST_GET(member), EINA_INLIST_GET(other));
1002 evas_object_smart_member_stack_below(Evas_Object *member, Evas_Object *other)
1004 Evas_Object_Smart *o;
1006 o = (Evas_Object_Smart *)(member->smart.parent->object_data);
1007 o->contained = eina_inlist_remove(o->contained, EINA_INLIST_GET(member));
1008 o->contained = eina_inlist_prepend_relative(o->contained, EINA_INLIST_GET(member), EINA_INLIST_GET(other));
1012 evas_object_smart_need_bounding_box_update(Evas_Object *obj)
1014 Evas_Object_Smart *o;
1016 o = (Evas_Object_Smart *)(obj->object_data);
1018 if (o->update_boundingbox_needed) return ;
1019 o->update_boundingbox_needed = EINA_TRUE;
1021 if (obj->smart.parent) evas_object_smart_need_bounding_box_update(obj->smart.parent);
1025 evas_object_smart_bouding_box_update(Evas_Object *obj)
1029 Evas_Object_Smart *os;
1032 Evas_Coord maxw = 0;
1033 Evas_Coord maxh = 0;
1035 os = (Evas_Object_Smart *)(obj->object_data);
1037 if (!os->update_boundingbox_needed) return ;
1038 os->update_boundingbox_needed = EINA_FALSE;
1040 minx = obj->layer->evas->output.w;
1041 miny = obj->layer->evas->output.h;
1043 list = os->contained;
1044 EINA_INLIST_FOREACH(list, o)
1051 if (o == obj) continue ;
1052 if (o->clip.clipees || o->is_static_clip) continue ;
1056 evas_object_smart_bouding_box_update(o);
1058 tx = o->cur.bounding_box.x;
1059 ty = o->cur.bounding_box.y;
1060 tw = o->cur.bounding_box.x + o->cur.bounding_box.w;
1061 th = o->cur.bounding_box.y + o->cur.bounding_box.h;
1065 tx = o->cur.geometry.x;
1066 ty = o->cur.geometry.y;
1067 tw = o->cur.geometry.x + o->cur.geometry.w;
1068 th = o->cur.geometry.y + o->cur.geometry.h;
1071 if (tx < minx) minx = tx;
1072 if (ty < miny) miny = ty;
1073 if (tw > maxw) maxw = tw;
1074 if (th > maxh) maxh = th;
1077 if (minx != obj->cur.bounding_box.x)
1079 obj->cur.bounding_box.w += obj->cur.bounding_box.x - minx;
1080 obj->cur.bounding_box.x = minx;
1083 if (miny != obj->cur.bounding_box.y)
1085 obj->cur.bounding_box.h += obj->cur.bounding_box.y - miny;
1086 obj->cur.bounding_box.y = miny;
1089 if (maxw != obj->cur.bounding_box.x + obj->cur.bounding_box.w)
1091 obj->cur.bounding_box.w = maxw - obj->cur.bounding_box.x;
1094 if (maxh != obj->cur.bounding_box.y + obj->cur.bounding_box.h)
1096 obj->cur.bounding_box.h = maxh - obj->cur.bounding_box.y;
1100 /* all nice and private */
1102 evas_object_smart_init(Evas_Object *obj)
1104 /* alloc smart obj, setup methods and default values */
1105 obj->object_data = evas_object_smart_new();
1106 /* set up default settings for this kind of object */
1107 obj->cur.color.r = 255;
1108 obj->cur.color.g = 255;
1109 obj->cur.color.b = 255;
1110 obj->cur.color.a = 255;
1111 obj->cur.geometry.x = 0;
1112 obj->cur.geometry.y = 0;
1113 obj->cur.geometry.w = 0;
1114 obj->cur.geometry.h = 0;
1116 /* set up object-specific settings */
1117 obj->prev = obj->cur;
1118 /* set up methods (compulsory) */
1119 obj->func = &object_func;
1123 evas_object_smart_new(void)
1125 Evas_Object_Smart *o;
1127 /* alloc obj private data */
1128 EVAS_MEMPOOL_INIT(_mp_obj, "evas_object_smart", Evas_Object_Smart, 32, NULL);
1129 o = EVAS_MEMPOOL_ALLOC(_mp_obj, Evas_Object_Smart);
1130 if (!o) return NULL;
1131 EVAS_MEMPOOL_PREP(_mp_obj, o, Evas_Object_Smart);
1132 o->magic = MAGIC_OBJ_SMART;
1137 evas_object_smart_free(Evas_Object *obj)
1139 Evas_Object_Smart *o;
1141 /* frees private object data. very simple here */
1142 o = (Evas_Object_Smart *)(obj->object_data);
1143 MAGIC_CHECK(o, Evas_Object_Smart, MAGIC_OBJ_SMART);
1148 EVAS_MEMPOOL_FREE(_mp_obj, o);
1152 evas_object_smart_render(Evas_Object *obj __UNUSED__, void *output __UNUSED__, void *context __UNUSED__, void *surface __UNUSED__, int x __UNUSED__, int y __UNUSED__)
1158 evas_object_smart_render_pre(Evas_Object *obj)
1162 if (obj->pre_render_done) return;
1163 if (!obj->child_has_map && !obj->cur.cached_surface)
1166 Evas_Object_Smart *o;
1168 fprintf(stderr, "");
1169 o = (Evas_Object_Smart *)(obj->object_data);
1170 if (/* o->member_count > 1 && */
1171 obj->cur.bounding_box.w == obj->prev.bounding_box.w &&
1172 obj->cur.bounding_box.h == obj->prev.bounding_box.h &&
1173 (obj->cur.bounding_box.x != obj->prev.bounding_box.x ||
1174 obj->cur.bounding_box.y != obj->prev.bounding_box.y))
1176 Eina_Bool cache_map = EINA_FALSE;
1178 /* Check parent speed */
1179 /* - same speed => do not map this object */
1180 /* - different speed => map this object */
1181 /* - if parent is mapped then map this object */
1183 if (!obj->smart.parent || obj->smart.parent->child_has_map)
1185 cache_map = EINA_TRUE;
1189 if (_evas_render_has_map(obj->smart.parent))
1191 cache_map = EINA_TRUE;
1195 int speed_x, speed_y;
1196 int speed_px, speed_py;
1198 speed_x = obj->cur.geometry.x - obj->prev.geometry.x;
1199 speed_y = obj->cur.geometry.y - obj->prev.geometry.y;
1201 speed_px = obj->smart.parent->cur.geometry.x - obj->smart.parent->prev.geometry.x;
1202 speed_py = obj->smart.parent->cur.geometry.y - obj->smart.parent->prev.geometry.y;
1204 /* speed_x = obj->cur.bounding_box.x - obj->prev.bounding_box.x; */
1205 /* speed_y = obj->cur.bounding_box.y - obj->prev.bounding_box.y; */
1207 /* speed_px = obj->smart.parent->cur.bounding_box.x - obj->smart.parent->prev.bounding_box.x; */
1208 /* speed_py = obj->smart.parent->cur.bounding_box.y - obj->smart.parent->prev.bounding_box.y; */
1210 fprintf(stderr, "speed: '%s',%p (%i, %i) vs '%s',%p (%i, %i)\n",
1211 evas_object_type_get(obj), obj, speed_x, speed_y,
1212 evas_object_type_get(obj->smart.parent), obj->smart.parent, speed_px, speed_py);
1214 if (speed_x != speed_px || speed_y != speed_py)
1215 cache_map = EINA_TRUE;
1220 fprintf(stderr, "Wouhou, I can detect moving smart object (%s, %p [%i, %i, %i, %i] < %s, %p [%i, %i, %i, %i])\n",
1221 evas_object_type_get(obj), obj,
1222 obj->cur.bounding_box.x - obj->prev.bounding_box.x,
1223 obj->cur.bounding_box.y - obj->prev.bounding_box.y,
1224 obj->cur.bounding_box.w, obj->cur.bounding_box.h,
1225 evas_object_type_get(obj->smart.parent), obj->smart.parent,
1226 obj->smart.parent->cur.bounding_box.x - obj->smart.parent->prev.bounding_box.x,
1227 obj->smart.parent->cur.bounding_box.y - obj->smart.parent->prev.bounding_box.y,
1228 obj->smart.parent->cur.bounding_box.w, obj->smart.parent->cur.bounding_box.h);
1230 obj->cur.cached_surface = cache_map;
1235 e = obj->layer->evas;
1237 if (obj->changed_map)
1239 evas_object_render_pre_prev_cur_add(&e->clip_changes, obj);
1242 obj->pre_render_done = EINA_TRUE;
1246 evas_object_smart_render_post(Evas_Object *obj)
1248 evas_object_cur_prev(obj);
1251 static unsigned int evas_object_smart_id_get(Evas_Object *obj)
1253 Evas_Object_Smart *o;
1255 o = (Evas_Object_Smart *)(obj->object_data);
1257 return MAGIC_OBJ_SMART;
1260 static unsigned int evas_object_smart_visual_id_get(Evas_Object *obj)
1262 Evas_Object_Smart *o;
1264 o = (Evas_Object_Smart *)(obj->object_data);
1266 return MAGIC_OBJ_CONTAINER;
1269 static void *evas_object_smart_engine_data_get(Evas_Object *obj)
1271 Evas_Object_Smart *o;
1273 o = (Evas_Object_Smart *)(obj->object_data);
1274 if (!o) return NULL;
1275 return o->engine_data;