evas: Add pseudo-internal API to intercept basic calls

This is a poor man's solution to get rid of group functions such
as clip_set, clip_unset, color_set, etc... See the following
commits.

This API needs to be EAPI for elementary but shouldn't be used
outside EFL. This is required purely for legacy compatibility.

Here's the call flow, inside show(obj):
1. if (intercept_show(obj)) return;
2. show(super(obj));
3. do other stuff
This commit is contained in:
Jean-Philippe Andre 2016-10-07 12:43:21 +09:00
parent dfc3f9deab
commit 39949b022d
8 changed files with 171 additions and 48 deletions

View File

@ -2483,6 +2483,33 @@ EAPI void evas_object_intercept_focus_set_callback_add(Evas_Object *obj, Evas_O
*/
EAPI void *evas_object_intercept_focus_set_callback_del(Evas_Object *obj, Evas_Object_Intercept_Focus_Set_Cb func) EINA_ARG_NONNULL(1, 2);
/* Internal APIs for legacy compatibility */
#ifdef EFL_CANVAS_OBJECT_PROTECTED
typedef enum _Evas_Object_Intercept_Cb_Type Evas_Object_Intercept_Cb_Type;
enum _Evas_Object_Intercept_Cb_Type
{
EVAS_OBJECT_INTERCEPT_CB_SHOW,
EVAS_OBJECT_INTERCEPT_CB_HIDE,
EVAS_OBJECT_INTERCEPT_CB_MOVE,
EVAS_OBJECT_INTERCEPT_CB_RESIZE,
EVAS_OBJECT_INTERCEPT_CB_RAISE,
EVAS_OBJECT_INTERCEPT_CB_LOWER,
EVAS_OBJECT_INTERCEPT_CB_STACK_ABOVE,
EVAS_OBJECT_INTERCEPT_CB_STACK_BELOW,
EVAS_OBJECT_INTERCEPT_CB_LAYER_SET,
EVAS_OBJECT_INTERCEPT_CB_FOCUS_SET,
EVAS_OBJECT_INTERCEPT_CB_COLOR_SET,
EVAS_OBJECT_INTERCEPT_CB_CLIP_SET,
EVAS_OBJECT_INTERCEPT_CB_CLIP_UNSET,
};
EWAPI Eina_Bool _evas_object_intercept_call(Evas_Object *obj, Evas_Object_Intercept_Cb_Type type, Eina_Bool internal, ...);
#endif
/**
* @}
*/

View File

@ -267,10 +267,9 @@ _efl_canvas_object_clip_set(Eo *eo_obj, Evas_Object_Protected_Data *obj, Evas_Ob
return;
}
if (evas_object_intercept_call_clip_set(eo_obj, obj, eo_clip))
{
return;
}
if (_evas_object_intercept_call(eo_obj, EVAS_OBJECT_INTERCEPT_CB_CLIP_SET, 1, eo_clip))
return;
// illegal to set anything but a rect or an image as a clip
if (clip->type != o_rect_type && clip->type != o_image_type)
{
@ -411,7 +410,7 @@ _efl_canvas_object_clip_unset(Eo *eo_obj, Evas_Object_Protected_Data *obj)
obj->clip.cache_clipees_answer = eina_list_free(obj->clip.cache_clipees_answer);
/* unclip */
if (evas_object_intercept_call_clip_unset(eo_obj, obj)) return;
if (_evas_object_intercept_call(eo_obj, EVAS_OBJECT_INTERCEPT_CB_CLIP_UNSET, 1)) return;
if (obj->is_smart)
{
efl_canvas_group_clip_unset(eo_obj);

View File

@ -18,7 +18,7 @@ _efl_canvas_object_key_focus_set(Eo *eo_obj, Evas_Object_Protected_Data *obj, Ei
event_id = _evas_object_event_new();
if (obj->focused == focus) goto end;
if (evas_object_intercept_call_focus_set(eo_obj, obj, focus)) goto end;
if (_evas_object_intercept_call(eo_obj, EVAS_OBJECT_INTERCEPT_CB_FOCUS_SET, 1, focus)) return;
if (focus)
{
if (obj->layer->evas->focused)

View File

@ -224,7 +224,7 @@ _efl_canvas_object_efl_gfx_stack_layer_set(Eo *eo_obj,
if (obj->delete_me) return;
evas_object_async_block(obj);
if (evas_object_intercept_call_layer_set(eo_obj, obj, l)) return;
if (_evas_object_intercept_call(eo_obj, EVAS_OBJECT_INTERCEPT_CB_LAYER_SET, 1, l)) return;
if (obj->smart.parent) return;
if (obj->cur->layer == l)
{

View File

@ -1,3 +1,9 @@
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <stdarg.h>
#include "evas_common_private.h"
#include "evas_private.h"
@ -51,7 +57,7 @@ evas_object_intercept_cleanup(Evas_Object *eo_obj)
#define UNPACK_ARG4(a, b, c, d) , a, b, c, d
#define EVAS_OBJECT_INTERCEPT_CALL(Type, Args, ...) \
int evas_object_intercept_call_##Type Args \
static inline int evas_object_intercept_call_##Type Args \
{ \
if (!obj->interceptors) return 0; \
if (obj->interceptors->Type.intercepted) return 0; \
@ -67,15 +73,134 @@ EVAS_OBJECT_INTERCEPT_CALL(hide, (COMMON_ARGS))
EVAS_OBJECT_INTERCEPT_CALL(raise, (COMMON_ARGS))
EVAS_OBJECT_INTERCEPT_CALL(lower, (COMMON_ARGS))
EVAS_OBJECT_INTERCEPT_CALL(clip_unset, (COMMON_ARGS))
EVAS_OBJECT_INTERCEPT_CALL(move, (COMMON_ARGS, Evas_Coord a, Evas_Coord b), UNPACK_ARG2(a, b))
EVAS_OBJECT_INTERCEPT_CALL(resize, (COMMON_ARGS, Evas_Coord a, Evas_Coord b), UNPACK_ARG2(a, b))
EVAS_OBJECT_INTERCEPT_CALL(move, (COMMON_ARGS, int a, int b), UNPACK_ARG2(a, b))
EVAS_OBJECT_INTERCEPT_CALL(resize, (COMMON_ARGS, int a, int b), UNPACK_ARG2(a, b))
EVAS_OBJECT_INTERCEPT_CALL(stack_above, (COMMON_ARGS, Evas_Object *rel_to), UNPACK_ARG1(rel_to))
EVAS_OBJECT_INTERCEPT_CALL(stack_below, (COMMON_ARGS, Evas_Object *rel_to), UNPACK_ARG1(rel_to))
EVAS_OBJECT_INTERCEPT_CALL(layer_set, (COMMON_ARGS, int l), UNPACK_ARG1(l))
EVAS_OBJECT_INTERCEPT_CALL(focus_set, (COMMON_ARGS, Eina_Bool focus), UNPACK_ARG1(focus))
EVAS_OBJECT_INTERCEPT_CALL(focus_set, (COMMON_ARGS, int focus), UNPACK_ARG1(focus))
EVAS_OBJECT_INTERCEPT_CALL(color_set, (COMMON_ARGS, int r, int g, int b, int a), UNPACK_ARG4(r, g, b, a))
EVAS_OBJECT_INTERCEPT_CALL(clip_set, (COMMON_ARGS, Evas_Object *clip), UNPACK_ARG1(clip))
/* This is a legacy-only compatibility function.
* Made public for other parts of EFL (elm, ecore_evas).
*/
EWAPI Eina_Bool
_evas_object_intercept_call(Evas_Object *eo_obj, Evas_Object_Intercept_Cb_Type cb_type,
Eina_Bool internal, ...)
{
Evas_Object_Protected_Data *obj = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS);
Eina_Bool blocked = 0;
Evas_Object *eo_other;
int r, g, b, a, i, j;
va_list args;
if (!obj || obj->delete_me || !obj->layer) return 1;
evas_object_async_block(obj);
switch (cb_type)
{
case EVAS_OBJECT_INTERCEPT_CB_SHOW:
if (obj->cur->visible) return 1;
if (!obj->interceptors) return 0;
blocked = evas_object_intercept_call_show(eo_obj, obj);
break;
case EVAS_OBJECT_INTERCEPT_CB_HIDE:
if (!obj->cur->visible) return 1;
if (!obj->interceptors) return 0;
blocked = evas_object_intercept_call_hide(eo_obj, obj);
break;
case EVAS_OBJECT_INTERCEPT_CB_MOVE:
if (!obj->interceptors) return 0;
va_start(args, cb_type);
i = va_arg(args, int);
j = va_arg(args, int);
blocked = evas_object_intercept_call_move(eo_obj, obj, i, j);
va_end(args);
break;
case EVAS_OBJECT_INTERCEPT_CB_RESIZE:
if (!obj->interceptors) return 0;
va_start(args, cb_type);
i = va_arg(args, int);
j = va_arg(args, int);
blocked = evas_object_intercept_call_resize(eo_obj, obj, i, j);
va_end(args);
break;
case EVAS_OBJECT_INTERCEPT_CB_RAISE:
if (!obj->interceptors) return 0;
blocked = evas_object_intercept_call_raise(eo_obj, obj);
break;
case EVAS_OBJECT_INTERCEPT_CB_LOWER:
if (!obj->interceptors) return 0;
blocked = evas_object_intercept_call_lower(eo_obj, obj);
break;
case EVAS_OBJECT_INTERCEPT_CB_STACK_ABOVE:
if (!obj->interceptors) return 0;
va_start(args, cb_type);
eo_other = va_arg(args, Evas_Object *);
blocked = evas_object_intercept_call_stack_above(eo_obj, obj, eo_other);
va_end(args);
break;
case EVAS_OBJECT_INTERCEPT_CB_STACK_BELOW:
if (!obj->interceptors) return 0;
va_start(args, cb_type);
eo_other = va_arg(args, Evas_Object *);
blocked = evas_object_intercept_call_stack_below(eo_obj, obj, eo_other);
va_end(args);
break;
case EVAS_OBJECT_INTERCEPT_CB_LAYER_SET:
if (!obj->interceptors) return 0;
va_start(args, cb_type);
i = va_arg(args, int);
blocked = evas_object_intercept_call_layer_set(eo_obj, obj, i);
va_end(args);
break;
case EVAS_OBJECT_INTERCEPT_CB_FOCUS_SET:
if (!obj->interceptors) return 0;
va_start(args, cb_type);
i = va_arg(args, int);
blocked = evas_object_intercept_call_focus_set(eo_obj, obj, !!i);
va_end(args);
break;
case EVAS_OBJECT_INTERCEPT_CB_COLOR_SET:
if (!obj->interceptors) return 0;
va_start(args, cb_type);
r = va_arg(args, int);
g = va_arg(args, int);
b = va_arg(args, int);
a = va_arg(args, int);
blocked = evas_object_intercept_call_color_set(eo_obj, obj, r, g, b, a);
va_end(args);
break;
case EVAS_OBJECT_INTERCEPT_CB_CLIP_SET:
if (!obj->interceptors) return 0;
va_start(args, cb_type);
eo_other = va_arg(args, Evas_Object *);
blocked = evas_object_intercept_call_clip_set(eo_obj, obj, eo_other);
va_end(args);
break;
case EVAS_OBJECT_INTERCEPT_CB_CLIP_UNSET:
if (!obj->interceptors) return 0;
blocked = evas_object_intercept_call_clip_unset(eo_obj, obj);
break;
}
return blocked;
}
/* public calls */
#define EVAS_OBJECT_INTERCEPT_CALLBACK_DEFINE(Up_Type, Lower_Type) \

View File

@ -804,7 +804,7 @@ _efl_canvas_object_efl_gfx_position_set(Eo *eo_obj, Evas_Object_Protected_Data *
if (!obj->layer) return;
evas_object_async_block(obj);
if (evas_object_intercept_call_move(eo_obj, obj, x, y)) return;
if (_evas_object_intercept_call(eo_obj, EVAS_OBJECT_INTERCEPT_CB_MOVE, 1, x, y)) return;
if (obj->doing.in_move > 0)
{
@ -896,7 +896,7 @@ _efl_canvas_object_efl_gfx_size_set(Eo *eo_obj, Evas_Object_Protected_Data *obj,
if (h < 0) h = 0;
evas_object_async_block(obj);
if (evas_object_intercept_call_resize(eo_obj, obj, w, h)) return;
if (_evas_object_intercept_call(eo_obj, EVAS_OBJECT_INTERCEPT_CB_RESIZE, 1, w, h)) return;
if (obj->doing.in_resize > 0)
{
@ -1326,13 +1326,7 @@ _efl_canvas_object_efl_gfx_visible_set(Eo *eo_obj,
static void
_show(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj)
{
if (!obj->layer) return;
if (obj->delete_me) return;
if (obj->cur->visible)
{
return;
}
if (evas_object_intercept_call_show(eo_obj, obj)) return;
if (_evas_object_intercept_call(eo_obj, EVAS_OBJECT_INTERCEPT_CB_SHOW, 1)) return;
if (obj->is_smart)
{
efl_canvas_group_show(eo_obj);
@ -1373,16 +1367,7 @@ _show(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj)
static void
_hide(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj)
{
MAGIC_CHECK(eo_obj, Evas_Object, MAGIC_OBJ);
return;
MAGIC_CHECK_END();
if (!obj->layer) return;
if (obj->delete_me) return;
if (!obj->cur->visible)
{
return;
}
if (evas_object_intercept_call_hide(eo_obj, obj)) return;
if (_evas_object_intercept_call(eo_obj, EVAS_OBJECT_INTERCEPT_CB_HIDE, 1)) return;
if (obj->is_smart)
{
efl_canvas_group_hide(eo_obj);
@ -1519,7 +1504,7 @@ _efl_canvas_object_efl_gfx_color_set(Eo *eo_obj, Evas_Object_Protected_Data *obj
ERR("Evas only handles premultiplied colors (0 <= R,G,B <= A <= 255)");
evas_object_async_block(obj);
if (evas_object_intercept_call_color_set(eo_obj, obj, r, g, b, a)) return;
if (_evas_object_intercept_call(eo_obj, EVAS_OBJECT_INTERCEPT_CB_COLOR_SET, 1, r, g, b, a)) return;
if ((obj->cur->color.r == r) &&
(obj->cur->color.g == g) &&
(obj->cur->color.b == b) &&

View File

@ -47,7 +47,7 @@ EOLIAN void
_efl_canvas_object_efl_gfx_stack_raise(Eo *eo_obj, Evas_Object_Protected_Data *obj)
{
evas_object_async_block(obj);
if (evas_object_intercept_call_raise(eo_obj, obj)) return;
if (_evas_object_intercept_call(eo_obj, EVAS_OBJECT_INTERCEPT_CB_RAISE, 1)) return;
if (!((EINA_INLIST_GET(obj))->next))
{
@ -100,7 +100,7 @@ EOLIAN void
_efl_canvas_object_efl_gfx_stack_lower(Eo *eo_obj, Evas_Object_Protected_Data *obj)
{
evas_object_async_block(obj);
if (evas_object_intercept_call_lower(eo_obj, obj)) return;
if (_evas_object_intercept_call(eo_obj, EVAS_OBJECT_INTERCEPT_CB_LOWER, 1)) return;
if (!((EINA_INLIST_GET(obj))->prev))
{
@ -160,7 +160,7 @@ _efl_canvas_object_efl_gfx_stack_stack_above(Eo *eo_obj, Evas_Object_Protected_D
return;
}
if (eo_obj == eo_above) return;
if (evas_object_intercept_call_stack_above(eo_obj, obj, eo_above)) return;
if (_evas_object_intercept_call(eo_obj, EVAS_OBJECT_INTERCEPT_CB_STACK_ABOVE, 1, eo_above)) return;
Evas_Object_Protected_Data *above = efl_data_scope_get(eo_above, EFL_CANVAS_OBJECT_CLASS);
if ((EINA_INLIST_GET(obj))->prev == EINA_INLIST_GET(above))
{
@ -242,7 +242,7 @@ _efl_canvas_object_efl_gfx_stack_stack_below(Eo *eo_obj, Evas_Object_Protected_D
return;
}
if (eo_obj == eo_below) return;
if (evas_object_intercept_call_stack_below(eo_obj, obj, eo_below)) return;
if (_evas_object_intercept_call(eo_obj, EVAS_OBJECT_INTERCEPT_CB_STACK_BELOW, 1, eo_below)) return;
Evas_Object_Protected_Data *below = efl_data_scope_get(eo_below, EFL_CANVAS_OBJECT_CLASS);
if ((EINA_INLIST_GET(obj))->next == EINA_INLIST_GET(below))
{

View File

@ -1612,19 +1612,6 @@ void evas_object_inform_call_image_preloaded(Evas_Object *obj);
void evas_object_inform_call_image_unloaded(Evas_Object *obj);
void evas_object_inform_call_image_resize(Evas_Object *obj);
void evas_object_intercept_cleanup(Evas_Object *obj);
int evas_object_intercept_call_show(Evas_Object *obj, Evas_Object_Protected_Data *pd);
int evas_object_intercept_call_hide(Evas_Object *obj, Evas_Object_Protected_Data *pd);
int evas_object_intercept_call_move(Evas_Object *obj, Evas_Object_Protected_Data *pd, Evas_Coord x, Evas_Coord y);
int evas_object_intercept_call_resize(Evas_Object *obj, Evas_Object_Protected_Data *pd, Evas_Coord w, Evas_Coord h);
int evas_object_intercept_call_raise(Evas_Object *obj, Evas_Object_Protected_Data *pd);
int evas_object_intercept_call_lower(Evas_Object *obj, Evas_Object_Protected_Data *pd);
int evas_object_intercept_call_stack_above(Evas_Object *obj, Evas_Object_Protected_Data *pd, Evas_Object *above);
int evas_object_intercept_call_stack_below(Evas_Object *obj, Evas_Object_Protected_Data *pd, Evas_Object *below);
int evas_object_intercept_call_layer_set(Evas_Object *obj, Evas_Object_Protected_Data *pd, int l);
int evas_object_intercept_call_color_set(Evas_Object *obj, Evas_Object_Protected_Data *pd, int r, int g, int b, int a);
int evas_object_intercept_call_clip_set(Evas_Object *obj, Evas_Object_Protected_Data *pd, Evas_Object *clip);
int evas_object_intercept_call_clip_unset(Evas_Object *obj, Evas_Object_Protected_Data *pd);
int evas_object_intercept_call_focus_set(Evas_Object *obj, Evas_Object_Protected_Data *pd, Eina_Bool focus);
void evas_object_grabs_cleanup(Evas_Object *obj, Evas_Object_Protected_Data *pd);
void evas_key_grab_free(Evas_Object *obj, Evas_Object_Protected_Data *pd, const char *keyname, Evas_Modifier_Mask modifiers, Evas_Modifier_Mask not_modifiers);
void evas_font_dir_cache_free(void);