From: barbieri Date: Sun, 7 Sep 2008 01:25:49 +0000 (+0000) Subject: Add calculate callback to Evas_Smart_Class. X-Git-Tag: accepted/2.0/20130306.225542~242^2~2815 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=b25b16968f078945836c8be48c646c0ac4f6000f;p=profile%2Fivi%2Fevas.git Add calculate callback to Evas_Smart_Class. Some people is using it for some time now without problems, so I'm adding it to SVN to get some broader use. Remember to recompile ALL libraries that depend on Evas as it will change the EVAS_SMART_CLASS_VERSION and old classes will fail to load. This will also change Edje so it will postpone _edje_recalc() to render time, calculate() callback, however some methods will force early recalculation. git-svn-id: svn+ssh://svn.enlightenment.org/var/svn/e/trunk/evas@35860 7cbeb6ba-43b4-40fd-8cce-4c39aea84d33 --- diff --git a/src/lib/Evas.h b/src/lib/Evas.h index 73156d6..e5c1e44 100644 --- a/src/lib/Evas.h +++ b/src/lib/Evas.h @@ -137,7 +137,7 @@ typedef enum _Evas_Aspect_Control } Evas_Aspect_Control; -#define EVAS_SMART_CLASS_VERSION 1 /** the version you have to put into the version field in the smart class struct */ +#define EVAS_SMART_CLASS_VERSION 2 /** the version you have to put into the version field in the smart class struct */ struct _Evas_Smart_Class /** a smart object class */ { const char *name; /** the string name of the class */ @@ -153,6 +153,7 @@ struct _Evas_Smart_Class /** a smart object class */ void (*color_set) (Evas_Object *o, int r, int g, int b, int a); // FIXME: DELETE ME void (*clip_set) (Evas_Object *o, Evas_Object *clip); // FIXME: DELETE ME void (*clip_unset) (Evas_Object *o); // FIXME: DELETE ME + void (*calculate) (Evas_Object *o); const void *data; }; @@ -767,6 +768,11 @@ extern "C" { EAPI void evas_object_smart_callback_add (Evas_Object *obj, const char *event, void (*func) (void *data, Evas_Object *obj, void *event_info), const void *data); EAPI void *evas_object_smart_callback_del (Evas_Object *obj, const char *event, void (*func) (void *data, Evas_Object *obj, void *event_info)); EAPI void evas_object_smart_callback_call (Evas_Object *obj, const char *event, void *event_info); + EAPI void evas_object_smart_changed (Evas_Object *obj); + EAPI void evas_object_smart_need_recalculate_set(Evas_Object *obj, Evas_Bool value); + EAPI Evas_Bool evas_object_smart_need_recalculate_get(Evas_Object *obj); + EAPI void evas_object_smart_calculate (Evas_Object *obj); + /* events */ EAPI void evas_event_freeze (Evas *e); diff --git a/src/lib/canvas/evas_main.c b/src/lib/canvas/evas_main.c index 27b3ce6..1a9b34c 100644 --- a/src/lib/canvas/evas_main.c +++ b/src/lib/canvas/evas_main.c @@ -70,6 +70,7 @@ evas_new(void) evas_array_setup(&e->pending_objects, 16); evas_array_setup(&e->obscuring_objects, 16); evas_array_setup(&e->temporary_objects, 16); + evas_array_setup(&e->calculate_objects, 16); return e; } diff --git a/src/lib/canvas/evas_object_smart.c b/src/lib/canvas/evas_object_smart.c index 811cb81..608a828 100644 --- a/src/lib/canvas/evas_object_smart.c +++ b/src/lib/canvas/evas_object_smart.c @@ -13,6 +13,7 @@ struct _Evas_Object_Smart Evas_Object_List *contained; int walking_list; Evas_Bool deletions_waiting : 1; + Evas_Bool need_recalculate : 1; }; struct _Evas_Smart_Callback @@ -436,6 +437,163 @@ evas_object_smart_callback_call(Evas_Object *obj, const char *event, void *event evas_object_smart_callbacks_clear(obj); } +/** + * Set the need_recalculate flag of given smart object. + * + * If this flag is set then calculate() callback (method) of the given + * smart object will be called, if one is provided, during render phase + * usually evas_render(). After this step, this flag will be automatically + * unset. + * + * If no calculate() is provided, this flag will be left unchanged. + * + * @note just setting this flag will not make scene dirty and evas_render() + * will have no effect. To do that, use evas_object_smart_changed(), + * that will automatically call this function with 1 as parameter. + * + * @param obj the smart object + * @param value if one want to set or unset the need_recalculate flag. + * + * @ingroup Evas_Smart_Object_Group + */ +EAPI void +evas_object_smart_need_recalculate_set(Evas_Object *obj, Evas_Bool value) +{ + Evas_Object_Smart *o; + MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ); + return; + MAGIC_CHECK_END(); + o = obj->object_data; + MAGIC_CHECK(o, Evas_Object_Smart, MAGIC_OBJ_SMART); + return; + MAGIC_CHECK_END(); + + value = !!value; + if (o->need_recalculate == value) + return; + o->need_recalculate = value; + + if (!obj->smart.smart->smart_class->calculate) + return; + + /* XXX: objects can be present multiple times in calculate_objects() + * XXX: after a set-unset-set cycle, but it's not a problem since + * XXX: on _evas_render_call_smart_calculate() will check for the flag + * XXX: and it will be unset after the first. + */ + if (o->need_recalculate) + { + Evas *e; + e = obj->layer->evas; + _evas_array_append(&e->calculate_objects, obj); + } + /* TODO: else, remove from array */ +} + +/** + * Get the current value of need_recalculate flag. + * + * @note this flag will be unset during the render phase, after calculate() + * is called if one is provided. If no calculate() is provided, then + * the flag will be left unchanged after render phase. + * + * @param obj the smart object + * @return if flag is set or not. + * + * @ingroup Evas_Smart_Object_Group + */ +EAPI Evas_Bool +evas_object_smart_need_recalculate_get(Evas_Object *obj) +{ + Evas_Object_Smart *o; + MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ); + return; + MAGIC_CHECK_END(); + o = obj->object_data; + MAGIC_CHECK(o, Evas_Object_Smart, MAGIC_OBJ_SMART); + return; + MAGIC_CHECK_END(); + + return o->need_recalculate; +} + +/** + * Call user provided calculate() and unset need_calculate. + * + * @param obj the smart object + * @return if flag is set or not. + * + * @ingroup Evas_Smart_Object_Group + */ +EAPI void +evas_object_smart_calculate(Evas_Object *obj) +{ + Evas_Object_Smart *o; + MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ); + return; + MAGIC_CHECK_END(); + o = obj->object_data; + MAGIC_CHECK(o, Evas_Object_Smart, MAGIC_OBJ_SMART); + return; + MAGIC_CHECK_END(); + + if (obj->smart.smart->smart_class->calculate) + obj->smart.smart->smart_class->calculate(obj); + o->need_recalculate = 0; +} + +/** + * Call calculate() on all smart objects that need_recalculate. + * + * @internal + */ +void +evas_call_smarts_calculate(Evas *e) +{ + Evas_Array *calculate; + unsigned int i; + + calculate = &e->calculate_objects; + for (i = 0; i < calculate->count; ++i) + { + Evas_Object *obj; + Evas_Object_Smart *o; + + obj = _evas_array_get(calculate, i); + if (obj->delete_me) + continue; + + o = obj->object_data; + if (o->need_recalculate) + { + obj->smart.smart->smart_class->calculate(obj); + o->need_recalculate = 0; + } + } + + evas_array_flush(calculate); +} + +/** + * Mark smart object as changed, dirty. + * + * This will inform the scene that it changed and needs to be redraw, also + * setting need_recalculate on the given object. + * + * @see evas_object_smart_need_recalculate_set(). + * + * @ingroup Evas_Smart_Object_Group + */ +EAPI void +evas_object_smart_changed(Evas_Object *obj) +{ + MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ); + return; + MAGIC_CHECK_END(); + evas_object_change(obj); + evas_object_smart_need_recalculate_set(obj, 1); +} + /* internal calls */ static void evas_object_smart_callbacks_clear(Evas_Object *obj) diff --git a/src/lib/canvas/evas_render.c b/src/lib/canvas/evas_render.c index 8eb6a96..c36d438 100644 --- a/src/lib/canvas/evas_render.c +++ b/src/lib/canvas/evas_render.c @@ -341,6 +341,8 @@ evas_render_updates_internal(Evas *e, unsigned char make_updates, unsigned char MAGIC_CHECK_END(); if (!e->changed) return NULL; + evas_call_smarts_calculate(e); + /* Check if the modified object mean recalculating every thing */ if (!e->invalidate) _evas_render_check_pending_objects(&e->pending_objects, e); diff --git a/src/lib/include/evas_private.h b/src/lib/include/evas_private.h index d2d5671..2f6a790 100644 --- a/src/lib/include/evas_private.h +++ b/src/lib/include/evas_private.h @@ -288,6 +288,7 @@ struct _Evas Evas_Array pending_objects; Evas_Array obscuring_objects; Evas_Array temporary_objects; + Evas_Array calculate_objects; int delete_grabs; int walking_grabs; @@ -713,6 +714,7 @@ void evas_object_smart_member_lower(Evas_Object *member); void evas_object_smart_member_stack_above(Evas_Object *member, Evas_Object *other); void evas_object_smart_member_stack_below(Evas_Object *member, Evas_Object *other); const Evas_Object_List *evas_object_smart_members_get_direct(const Evas_Object *obj); +void evas_call_smarts_calculate(Evas *e); void *evas_mem_calloc(int size); void evas_object_event_callback_all_del(Evas_Object *obj); void evas_object_event_callback_cleanup(Evas_Object *obj);