forked from enlightenment/efl
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. SVN revision: 35860
This commit is contained in:
parent
3deae56fa1
commit
58a49c2f69
|
@ -135,6 +135,14 @@ _edje_part_description_apply(Edje *ed, Edje_Real_Part *ep, const char *d1, doubl
|
|||
|
||||
void
|
||||
_edje_recalc(Edje *ed)
|
||||
{
|
||||
if (ed->postponed) return ;
|
||||
evas_object_smart_changed(ed->obj);
|
||||
ed->postponed = 1;
|
||||
}
|
||||
|
||||
void
|
||||
_edje_recalc_do(Edje *ed)
|
||||
{
|
||||
int i;
|
||||
|
||||
|
@ -142,7 +150,8 @@ _edje_recalc(Edje *ed)
|
|||
if (ed->freeze)
|
||||
{
|
||||
ed->recalc = 1;
|
||||
if (!ed->calc_only) return;
|
||||
if (!ed->calc_only &&
|
||||
!ed->postponed) return;
|
||||
}
|
||||
for (i = 0; i < ed->table_parts_size; i++)
|
||||
{
|
||||
|
@ -161,6 +170,7 @@ _edje_recalc(Edje *ed)
|
|||
_edje_part_recalc(ed, ep, (~ep->calculated) & FLAG_XY);
|
||||
}
|
||||
ed->dirty = 0;
|
||||
ed->postponed = 0;
|
||||
if (!ed->calc_only) ed->recalc = 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -681,6 +681,7 @@ struct _Edje
|
|||
unsigned short walking_actions : 1;
|
||||
unsigned short block_break : 1;
|
||||
unsigned short delete_me : 1;
|
||||
unsigned short postponed : 1;
|
||||
};
|
||||
|
||||
struct _Edje_Real_Part
|
||||
|
@ -1007,6 +1008,7 @@ void _edje_part_pos_set(Edje *ed, Edje_Real_Part *ep, int mode, double pos);
|
|||
Edje_Part_Description *_edje_part_description_find(Edje *ed, Edje_Real_Part *rp, const char *name, double val);
|
||||
void _edje_part_description_apply(Edje *ed, Edje_Real_Part *ep, const char *d1, double v1, const char *d2, double v2);
|
||||
void _edje_recalc(Edje *ed);
|
||||
void _edje_recalc_do(Edje *ed);
|
||||
int _edje_part_dragable_calc(Edje *ed, Edje_Real_Part *ep, double *x, double *y);
|
||||
void _edje_dragable_pos_set(Edje *ed, Edje_Real_Part *ep, double x, double y);
|
||||
|
||||
|
|
|
@ -13,6 +13,7 @@ static void _edje_smart_hide(Evas_Object * obj);
|
|||
static void _edje_smart_color_set(Evas_Object * obj, int r, int g, int b, int a);
|
||||
static void _edje_smart_clip_set(Evas_Object * obj, Evas_Object * clip);
|
||||
static void _edje_smart_clip_unset(Evas_Object * obj);
|
||||
static void _edje_smart_calculate(Evas_Object * obj);
|
||||
|
||||
static Evas_Smart *_edje_smart = NULL;
|
||||
|
||||
|
@ -45,6 +46,7 @@ edje_object_add(Evas *evas)
|
|||
_edje_smart_color_set,
|
||||
_edje_smart_clip_set,
|
||||
_edje_smart_clip_unset,
|
||||
_edje_smart_calculate,
|
||||
NULL
|
||||
};
|
||||
_edje_smart = evas_smart_class_new(&sc);
|
||||
|
@ -237,3 +239,13 @@ _edje_smart_clip_unset(Evas_Object * obj)
|
|||
evas_object_clip_unset(ed->clipper);
|
||||
// _edje_emit(ed, "clip_unset", NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
_edje_smart_calculate(Evas_Object *obj)
|
||||
{
|
||||
Edje *ed;
|
||||
|
||||
ed = evas_object_smart_data_get(obj);
|
||||
if (!ed) return;
|
||||
_edje_recalc_do(ed);
|
||||
}
|
||||
|
|
|
@ -715,6 +715,10 @@ edje_object_part_object_get(const Evas_Object *obj, const char *part)
|
|||
|
||||
ed = _edje_fetch(obj);
|
||||
if ((!ed) || (!part)) return NULL;
|
||||
|
||||
/* Need to recalc before providing the object. */
|
||||
_edje_recalc_do(ed);
|
||||
|
||||
rp = _edje_real_part_recursive_get(ed, (char *)part);
|
||||
if (!rp) return NULL;
|
||||
return rp->object;
|
||||
|
@ -748,6 +752,10 @@ edje_object_part_geometry_get(const Evas_Object *obj, const char *part, Evas_Coo
|
|||
if (h) *h = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Need to recalc before providing the object. */
|
||||
_edje_recalc_do(ed);
|
||||
|
||||
rp = _edje_real_part_recursive_get(ed, (char *)part);
|
||||
if (!rp)
|
||||
{
|
||||
|
@ -828,6 +836,10 @@ edje_object_part_text_get(const Evas_Object *obj, const char *part)
|
|||
|
||||
ed = _edje_fetch(obj);
|
||||
if ((!ed) || (!part)) return NULL;
|
||||
|
||||
/* Need to recalc before providing the object. */
|
||||
_edje_recalc_do(ed);
|
||||
|
||||
rp = _edje_real_part_recursive_get(ed, (char *)part);
|
||||
if (!rp) return NULL;
|
||||
if (rp->part->type == EDJE_PART_TYPE_TEXT)
|
||||
|
@ -855,6 +867,10 @@ edje_object_part_swallow(Evas_Object *obj, const char *part, Evas_Object *obj_sw
|
|||
|
||||
ed = _edje_fetch(obj);
|
||||
if ((!ed) || (!part)) return;
|
||||
|
||||
/* Need to recalc before providing the object. */
|
||||
_edje_recalc_do(ed);
|
||||
|
||||
rp = _edje_real_part_recursive_get(ed, (char *)part);
|
||||
if (!rp) return;
|
||||
if (rp->part->type != EDJE_PART_TYPE_SWALLOW) return;
|
||||
|
@ -1021,7 +1037,7 @@ edje_object_part_unswallow(Evas_Object *obj, Evas_Object *obj_swallow)
|
|||
rp->swallow_params.max.w = 0;
|
||||
rp->swallow_params.max.h = 0;
|
||||
rp->edje->dirty = 1;
|
||||
_edje_recalc(rp->edje);
|
||||
_edje_recalc_do(rp->edje);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -1039,6 +1055,10 @@ edje_object_part_swallow_get(const Evas_Object *obj, const char *part)
|
|||
|
||||
ed = _edje_fetch(obj);
|
||||
if ((!ed) || (!part)) return NULL;
|
||||
|
||||
/* Need to recalc before providing the object. */
|
||||
_edje_recalc_do(ed);
|
||||
|
||||
rp = _edje_real_part_recursive_get(ed, (char *)part);
|
||||
if (!rp) return NULL;
|
||||
return rp->swallowed_object;
|
||||
|
@ -1088,6 +1108,10 @@ edje_object_size_max_get(const Evas_Object *obj, Evas_Coord *maxw, Evas_Coord *m
|
|||
if (maxh) *maxh = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Need to recalc before providing the object. */
|
||||
_edje_recalc_do(ed);
|
||||
|
||||
if (ed->collection->prop.max.w == 0)
|
||||
{
|
||||
/* XXX TODO: convert maxw to 0, fix things that break. */
|
||||
|
@ -1125,7 +1149,7 @@ edje_object_calc_force(Evas_Object *obj)
|
|||
ed->dirty = 1;
|
||||
pf = ed->freeze;
|
||||
ed->freeze = 0;
|
||||
_edje_recalc(ed);
|
||||
_edje_recalc_do(ed);
|
||||
ed->freeze = pf;
|
||||
}
|
||||
|
||||
|
@ -1187,7 +1211,7 @@ edje_object_size_min_restricted_calc(Evas_Object *obj, Evas_Coord *minw, Evas_Co
|
|||
|
||||
ok = 0;
|
||||
ed->dirty = 1;
|
||||
_edje_recalc(ed);
|
||||
_edje_recalc_do(ed);
|
||||
if (reset_maxwh)
|
||||
{
|
||||
maxw = 0;
|
||||
|
@ -1291,6 +1315,10 @@ edje_object_part_state_get(const Evas_Object *obj, const char *part, double *val
|
|||
if (val_ret) *val_ret = 0;
|
||||
return "";
|
||||
}
|
||||
|
||||
/* Need to recalc before providing the object. */
|
||||
_edje_recalc_do(ed);
|
||||
|
||||
rp = _edje_real_part_recursive_get(ed, (char *)part);
|
||||
if (!rp)
|
||||
{
|
||||
|
@ -1335,6 +1363,10 @@ edje_object_part_drag_dir_get(const Evas_Object *obj, const char *part)
|
|||
|
||||
ed = _edje_fetch(obj);
|
||||
if ((!ed) || (!part)) return EDJE_DRAG_DIR_NONE;
|
||||
|
||||
/* Need to recalc before providing the object. */
|
||||
_edje_recalc_do(ed);
|
||||
|
||||
rp = _edje_real_part_recursive_get(ed, (char *)part);
|
||||
if (!rp) return EDJE_DRAG_DIR_NONE;
|
||||
if ((rp->part->dragable.x) && (rp->part->dragable.y)) return EDJE_DRAG_DIR_XY;
|
||||
|
@ -1399,6 +1431,10 @@ edje_object_part_drag_value_get(const Evas_Object *obj, const char *part, double
|
|||
if (dy) *dy = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Need to recalc before providing the object. */
|
||||
_edje_recalc_do(ed);
|
||||
|
||||
rp = _edje_real_part_recursive_get(ed, (char *)part);
|
||||
if (!rp)
|
||||
{
|
||||
|
@ -1464,6 +1500,10 @@ edje_object_part_drag_size_get(const Evas_Object *obj, const char *part, double
|
|||
if (dh) *dh = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Need to recalc before providing the object. */
|
||||
_edje_recalc_do(ed);
|
||||
|
||||
rp = _edje_real_part_recursive_get(ed, (char *)part);
|
||||
if (!rp)
|
||||
{
|
||||
|
@ -1522,6 +1562,10 @@ edje_object_part_drag_step_get(const Evas_Object *obj, const char *part, double
|
|||
if (dy) *dy = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Need to recalc before providing the object. */
|
||||
_edje_recalc_do(ed);
|
||||
|
||||
rp = _edje_real_part_recursive_get(ed, (char *)part);
|
||||
if (!rp)
|
||||
{
|
||||
|
@ -1580,6 +1624,10 @@ edje_object_part_drag_page_get(const Evas_Object *obj, const char *part, double
|
|||
if (dy) *dy = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Need to recalc before providing the object. */
|
||||
_edje_recalc_do(ed);
|
||||
|
||||
rp = _edje_real_part_recursive_get(ed, (char *)part);
|
||||
if (!rp)
|
||||
{
|
||||
|
@ -2097,5 +2145,5 @@ _edje_real_part_swallow(Edje_Real_Part *rp, Evas_Object *obj_swallow)
|
|||
evas_object_precise_is_inside_set(obj_swallow, 1);
|
||||
|
||||
rp->edje->dirty = 1;
|
||||
_edje_recalc(rp->edje);
|
||||
_edje_recalc_do(rp->edje);
|
||||
}
|
||||
|
|
|
@ -1164,6 +1164,7 @@ _smart_init(void)
|
|||
_smart_color_set,
|
||||
_smart_clip_set,
|
||||
_smart_clip_unset,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
smart = evas_smart_class_new(&sc);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue