adrunko's precise event patch

SVN revision: 30939
This commit is contained in:
Carsten Haitzler 2007-07-23 14:22:57 +00:00
parent b8b5b958f2
commit d6f9cc797e
13 changed files with 208 additions and 6 deletions

View File

@ -43,6 +43,7 @@ static void st_collections_group_parts_part_type(void);
static void st_collections_group_parts_part_effect(void);
static void st_collections_group_parts_part_mouse_events(void);
static void st_collections_group_parts_part_repeat_events(void);
static void st_collections_group_parts_part_precise_is_inside(void);
static void st_collections_group_parts_part_use_alternate_font_metrics(void);
static void st_collections_group_parts_part_clip_to_id(void);
static void st_collections_group_parts_part_source(void);
@ -179,6 +180,7 @@ New_Statement_Handler statement_handlers[] =
{"collections.group.parts.part.effect", st_collections_group_parts_part_effect},
{"collections.group.parts.part.mouse_events", st_collections_group_parts_part_mouse_events},
{"collections.group.parts.part.repeat_events", st_collections_group_parts_part_repeat_events},
{"collections.group.parts.part.precise_is_inside", st_collections_group_parts_part_precise_is_inside},
{"collections.group.parts.part.use_alternate_font_metrics", st_collections_group_parts_part_use_alternate_font_metrics},
{"collections.group.parts.part.clip_to", st_collections_group_parts_part_clip_to_id},
{"collections.group.parts.part.source", st_collections_group_parts_part_source},
@ -899,6 +901,7 @@ ob_collections_group_parts_part(void)
ep->type = EDJE_PART_TYPE_IMAGE;
ep->mouse_events = 1;
ep->repeat_events = 0;
ep->precise_is_inside = 0;
ep->use_alternate_font_metrics = 0;
ep->clip_to_id = -1;
ep->dragable.confine_id = -1;
@ -983,6 +986,19 @@ st_collections_group_parts_part_repeat_events(void)
ep->repeat_events = parse_bool(0);
}
static void
st_collections_group_parts_part_precise_is_inside(void)
{
Edje_Part_Collection *pc;
Edje_Part *ep;
check_arg_count(1);
pc = evas_list_data(evas_list_last(edje_collections));
ep = evas_list_data(evas_list_last(pc->parts));
ep->precise_is_inside = parse_bool(0);
}
static void
st_collections_group_parts_part_use_alternate_font_metrics(void)
{

View File

@ -345,6 +345,7 @@ _edje_edd_setup(void)
EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_part, Edje_Part, "effect", effect, EET_T_CHAR);
EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_part, Edje_Part, "mouse_events", mouse_events, EET_T_CHAR);
EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_part, Edje_Part, "repeat_events", repeat_events, EET_T_CHAR);
EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_part, Edje_Part, "precise_is_inside", precise_is_inside, EET_T_CHAR);
EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_part, Edje_Part, "clip_to_id", clip_to_id, EET_T_INT);
EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_part, Edje_Part, "use_alternate_font_metrics", use_alternate_font_metrics, EET_T_UCHAR);
EET_DATA_DESCRIPTOR_ADD_SUB(_edje_edd_edje_part, Edje_Part, "default_desc", default_desc, _edje_edd_edje_part_description);

View File

@ -326,6 +326,8 @@ _edje_object_file_set_internal(Evas_Object *obj, const char *file, const char *p
}
else
evas_object_pass_events_set(rp->object, 1);
if (ep->precise_is_inside)
evas_object_precise_is_inside_set(rp->object, 1);
}
if (rp->part->clip_to_id < 0)
evas_object_clip_set(rp->object, ed->clipper);

View File

@ -427,6 +427,7 @@ struct _Edje_Part
unsigned char effect; /* 0 = plain... */
unsigned char mouse_events; /* it will affect/respond to mouse events */
unsigned char repeat_events; /* it will repeat events to objects below */
unsigned char precise_is_inside;
unsigned char use_alternate_font_metrics;
};

View File

@ -2121,6 +2121,8 @@ _edje_real_part_swallow(Edje_Real_Part *rp, Evas_Object *obj_swallow)
else
evas_object_pass_events_set(obj_swallow, 1);
if (rp->part->precise_is_inside)
evas_object_precise_is_inside_set(obj_swallow, 1);
rp->edje->dirty = 1;
_edje_recalc(rp->edje);

View File

@ -469,6 +469,7 @@ extern "C" {
EAPI void evas_object_image_fill_get (Evas_Object *obj, Evas_Coord *x, Evas_Coord *y, Evas_Coord *w, Evas_Coord *h);
EAPI void evas_object_image_size_set (Evas_Object *obj, int w, int h);
EAPI void evas_object_image_size_get (Evas_Object *obj, int *w, int *h);
EAPI int evas_object_image_stride_get (Evas_Object *obj);
EAPI int evas_object_image_load_error_get (Evas_Object *obj);
EAPI void evas_object_image_data_set (Evas_Object *obj, void *data);
EAPI void *evas_object_image_data_get (Evas_Object *obj, Evas_Bool for_writing);
@ -767,6 +768,9 @@ extern "C" {
EAPI void evas_object_propagate_events_set (Evas_Object *obj, Evas_Bool prop);
EAPI Evas_Bool evas_object_propagate_events_get (Evas_Object *obj);
EAPI void evas_object_precise_is_inside_set (Evas_Object *obj, Evas_Bool precise);
EAPI Evas_Bool evas_object_precise_is_inside_get (Evas_Object *obj);
EAPI void evas_object_event_callback_add (Evas_Object *obj, Evas_Callback_Type type, void (*func) (void *data, Evas *e, Evas_Object *obj, void *event_info), const void *data);
EAPI void *evas_object_event_callback_del (Evas_Object *obj, Evas_Callback_Type type, void (*func) (void *data, Evas *e, Evas_Object *obj, void *event_info));

View File

@ -57,7 +57,9 @@ _evas_event_object_list_in_get(Evas *e, Evas_List *in, Evas_Object_List *list, E
}
else
{
if (evas_object_is_in_output_rect(obj, x, y, 1, 1))
if (evas_object_is_in_output_rect(obj, x, y, 1, 1) &&
((!obj->precise_is_inside) ||
(evas_object_is_inside(obj, x, y))))
{
in = evas_list_append(in, obj);
if (!obj->repeat_events)
@ -584,7 +586,9 @@ evas_event_feed_mouse_move(Evas *e, int x, int y, unsigned int timestamp, const
(evas_object_clippers_is_visible(obj)) &&
(evas_list_find(ins, obj)) &&
(!evas_event_passes_through(obj)) &&
(!obj->clip.clipees))
(!obj->clip.clipees) &&
((!obj->precise_is_inside) ||
(evas_object_is_inside(obj, x, y))))
{
if ((px != x) || (py != y))
{
@ -989,7 +993,11 @@ evas_object_pass_events_set(Evas_Object *obj, Evas_Bool pass)
evas_object_smart_member_cache_invalidate(obj);
if (evas_object_is_in_output_rect(obj,
obj->layer->evas->pointer.x,
obj->layer->evas->pointer.y, 1, 1))
obj->layer->evas->pointer.y, 1, 1) &&
((!obj->precise_is_inside) ||
(evas_object_is_inside(obj,
obj->layer->evas->pointer.x,
obj->layer->evas->pointer.y))))
evas_event_feed_mouse_move(obj->layer->evas,
obj->layer->evas->pointer.x,
obj->layer->evas->pointer.y,
@ -1036,7 +1044,11 @@ evas_object_repeat_events_set(Evas_Object *obj, Evas_Bool repeat)
obj->repeat_events = repeat;
if (evas_object_is_in_output_rect(obj,
obj->layer->evas->pointer.x,
obj->layer->evas->pointer.y, 1, 1))
obj->layer->evas->pointer.y, 1, 1) &&
((!obj->precise_is_inside) ||
(evas_object_is_inside(obj,
obj->layer->evas->pointer.x,
obj->layer->evas->pointer.y))))
evas_event_feed_mouse_move(obj->layer->evas,
obj->layer->evas->pointer.x,
obj->layer->evas->pointer.y,

View File

@ -16,7 +16,7 @@ struct _Evas_Object_Image
Evas_Coord x, y, w, h;
} fill;
struct {
short w, h;
short w, h, stride;
} image;
struct {
short l, r, t, b;
@ -67,6 +67,7 @@ static void evas_object_image_render_post(Evas_Object *obj);
static int evas_object_image_is_opaque(Evas_Object *obj);
static int evas_object_image_was_opaque(Evas_Object *obj);
static int evas_object_image_is_inside(Evas_Object *obj, Evas_Coord x, Evas_Coord y);
static const Evas_Object_Func object_func =
{
@ -82,7 +83,7 @@ static const Evas_Object_Func object_func =
NULL,
evas_object_image_is_opaque,
evas_object_image_was_opaque,
NULL,
evas_object_image_is_inside,
NULL,
NULL
};
@ -241,15 +242,22 @@ evas_object_image_file_set(Evas_Object *obj, const char *file, const char *key)
if (o->engine_data)
{
int w, h;
int stride;
obj->layer->evas->engine.func->image_size_get(obj->layer->evas->engine.data.output,
o->engine_data, &w, &h);
if (obj->layer->evas->engine.func->image_stride_get)
obj->layer->evas->engine.func->image_stride_get(obj->layer->evas->engine.data.output,
o->engine_data, &stride);
else
stride = w;
o->cur.has_alpha = obj->layer->evas->engine.func->image_alpha_get(obj->layer->evas->engine.data.output,
o->engine_data);
o->cur.cspace = obj->layer->evas->engine.func->image_colorspace_get(obj->layer->evas->engine.data.output,
o->engine_data);
o->cur.image.w = w;
o->cur.image.h = h;
o->cur.image.stride = stride;
}
else
{
@ -258,6 +266,7 @@ evas_object_image_file_set(Evas_Object *obj, const char *file, const char *key)
o->cur.cspace = EVAS_COLORSPACE_ARGB8888;
o->cur.image.w = 0;
o->cur.image.h = 0;
o->cur.image.stride = 0;
}
o->changed = 1;
evas_object_change(obj);
@ -562,6 +571,7 @@ EAPI void
evas_object_image_size_set(Evas_Object *obj, int w, int h)
{
Evas_Object_Image *o;
int stride;
MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
return;
@ -586,6 +596,14 @@ evas_object_image_size_set(Evas_Object *obj, int w, int h)
o->engine_data = obj->layer->evas->engine.func->image_new_from_copied_data
(obj->layer->evas->engine.data.output, w, h, NULL, o->cur.has_alpha,
o->cur.cspace);
if (obj->layer->evas->engine.func->image_stride_get)
obj->layer->evas->engine.func->image_stride_get(obj->layer->evas->engine.data.output,
o->engine_data, &stride);
else
stride = w;
o->cur.image.stride = stride;
/* FIXME - in engine call above
if (o->engine_data)
o->engine_data = obj->layer->evas->engine.func->image_alpha_set(obj->layer->evas->engine.data.output,
@ -626,6 +644,28 @@ evas_object_image_size_get(Evas_Object *obj, int *w, int *h)
if (h) *h = o->cur.image.h;
}
/**
* Retrieves the row stride, which is the number of units between the start of a row and the start of the next row.
* @param obj The given image object.
* @param stride A pointer to an integer in which to store the stride. Can be
* @c NULL.
* @ingroup Evas_Object_Image_Size
*/
EAPI int
evas_object_image_stride_get(Evas_Object *obj)
{
Evas_Object_Image *o;
MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
return 0;
MAGIC_CHECK_END();
o = (Evas_Object_Image *)(obj->object_data);
MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE);
return 0;
MAGIC_CHECK_END();
return o->cur.image.stride;
}
/**
* Retrieves a number representing any error that occurred during the last
* load for the given image object.
@ -693,6 +733,7 @@ evas_object_image_data_set(Evas_Object *obj, void *data)
o->load_error = EVAS_LOAD_ERROR_NONE;
o->cur.image.w = 0;
o->cur.image.h = 0;
o->cur.image.stride = 0;
o->engine_data = NULL;
}
/* FIXME - in engine call above
@ -1641,6 +1682,7 @@ evas_object_image_unload(Evas_Object *obj)
o->cur.cspace = EVAS_COLORSPACE_ARGB8888;
o->cur.image.w = 0;
o->cur.image.h = 0;
o->cur.image.stride = 0;
}
static void
@ -1664,15 +1706,22 @@ evas_object_image_load(Evas_Object *obj)
if (o->engine_data)
{
int w, h;
int stride;
obj->layer->evas->engine.func->image_size_get(obj->layer->evas->engine.data.output,
o->engine_data, &w, &h);
if (obj->layer->evas->engine.func->image_stride_get)
obj->layer->evas->engine.func->image_stride_get(obj->layer->evas->engine.data.output,
o->engine_data, &stride);
else
stride = w;
o->cur.has_alpha = obj->layer->evas->engine.func->image_alpha_get(obj->layer->evas->engine.data.output,
o->engine_data);
o->cur.cspace = obj->layer->evas->engine.func->image_colorspace_get(obj->layer->evas->engine.data.output,
o->engine_data);
o->cur.image.w = w;
o->cur.image.h = h;
o->cur.image.stride = stride;
}
else
{
@ -2318,3 +2367,52 @@ evas_object_image_was_opaque(Evas_Object *obj)
return 0;
return 1;
}
static int
evas_object_image_is_inside(Evas_Object *obj, Evas_Coord x, Evas_Coord y)
{
Evas_Object_Image *o;
void *data;
int w, h, stride;
int a;
o = (Evas_Object_Image *)(obj->object_data);
x -= obj->cur.cache.clip.x;
y -= obj->cur.cache.clip.y;
w = o->cur.image.w;
h = o->cur.image.h;
if ((x > w) || (y > h))
return 0;
if (!o->cur.has_alpha)
return 1;
stride = o->cur.image.stride;
o->engine_data = obj->layer->evas->engine.func->image_data_get(obj->layer->evas->engine.data.output,
o->engine_data,
0,
(DATA32**) &data);
if (!data)
return 0;
switch (o->cur.cspace)
{
case EVAS_COLORSPACE_ARGB8888:
data = ((DATA32*)(data) + ((y * stride) + x));
a = (*((DATA32*)(data)) >> 24) & 0xff;
break;
case EVAS_COLORSPACE_RGB565_A5P:
data = ((DATA16*)(data) + (h * stride));
data = ((DATA8*)(data) + ((y * stride) + x));
a = (*((DATA8*)(data))) & 0x1f;
break;
default:
return 1;
break;
}
return (a != 0);
}

View File

@ -419,6 +419,23 @@ evas_object_was_opaque(Evas_Object *obj)
return 0;
}
int
evas_object_is_inside(Evas_Object *obj, Evas_Coord x, Evas_Coord y)
{
if (obj->smart.smart) return 0;
if (obj->func->is_inside)
return obj->func->is_inside(obj, x, y);
return 0;
}
int
evas_object_was_inside(Evas_Object *obj, Evas_Coord x, Evas_Coord y)
{
if (obj->smart.smart) return 0;
if (obj->func->was_inside)
return obj->func->was_inside(obj, x, y);
return 0;
}
/* routines apps will call */
/**
@ -1221,3 +1238,33 @@ evas_object_type_get(Evas_Object *obj)
if (obj->delete_me) return "";
return obj->type;
}
/**
* Set whether to use a precise (usually expensive) point collision detection.
* @param obj The given object.
* @param precise wheter to use a precise point collision detection or not
* The default value is false.
* @ingroup Evas_Object_Group
*/
EAPI void
evas_object_precise_is_inside_set(Evas_Object *obj, Evas_Bool precise)
{
MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
return;
MAGIC_CHECK_END();
obj->precise_is_inside = precise;
}
/**
* Determine whether an object is set to use a precise point collision detection.
* @param obj The given object.
* @ingroup Evas_Object_Group
*/
EAPI Evas_Bool
evas_object_precise_is_inside_get(Evas_Object *obj)
{
MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
return 0;
MAGIC_CHECK_END();
return obj->precise_is_inside;
}

View File

@ -448,6 +448,8 @@ struct _Evas_Object
unsigned short in_layer : 1;
unsigned short no_propagate : 1;
unsigned short precise_is_inside : 1;
unsigned char delete_me;
};
@ -587,6 +589,7 @@ struct _Evas_Func
void (*image_free) (void *data, void *image);
void (*image_size_get) (void *data, void *image, int *w, int *h);
void *(*image_size_set) (void *data, void *image, int w, int h);
void (*image_stride_get) (void *data, void *image, int *stride);
void *(*image_dirty_region) (void *data, void *image, int x, int y, int w, int h);
void *(*image_data_get) (void *data, void *image, int to_write, DATA32 **image_data);
void *(*image_data_put) (void *data, void *image, DATA32 *image_data);
@ -678,6 +681,8 @@ int evas_object_is_visible(Evas_Object *obj);
int evas_object_was_visible(Evas_Object *obj);
int evas_object_is_opaque(Evas_Object *obj);
int evas_object_was_opaque(Evas_Object *obj);
int evas_object_is_inside(Evas_Object *obj, Evas_Coord x, Evas_Coord y);
int evas_object_was_inside(Evas_Object *obj, Evas_Coord x, Evas_Coord y);
//void evas_object_recalc_clippees(Evas_Object *obj);
int evas_object_clippers_is_visible(Evas_Object *obj);
int evas_object_clippers_was_visible(Evas_Object *obj);

View File

@ -193,6 +193,7 @@ static Evas_Func eng_func =
eng_image_free,
eng_image_size_get,
eng_image_size_set,
NULL,
eng_image_dirty_region,
eng_image_data_get,
eng_image_data_put,

View File

@ -416,6 +416,17 @@ eng_image_size_set(void *data, void *image, int w, int h)
return image;
}
static void
eng_image_stride_get(void *data, void *image, int *stride)
{
Soft16_Image *im;
if (stride) *stride = 0;
if (!image) return;
im = image;
if (stride) *stride = im->stride;
}
static void *
eng_image_dirty_region(void *data, void *image, int x, int y, int w, int h)
{
@ -726,6 +737,7 @@ static Evas_Func func =
eng_image_free,
eng_image_size_get,
eng_image_size_set,
eng_image_stride_get,
eng_image_dirty_region,
eng_image_data_get,
eng_image_data_put,

View File

@ -860,6 +860,7 @@ static Evas_Func func =
eng_image_free,
eng_image_size_get,
eng_image_size_set,
NULL,
eng_image_dirty_region,
eng_image_data_get,
eng_image_data_put,