diff --git a/legacy/edje/src/bin/edje_cc_handlers.c b/legacy/edje/src/bin/edje_cc_handlers.c index 96f936b7e7..d80f8b5da5 100644 --- a/legacy/edje/src/bin/edje_cc_handlers.c +++ b/legacy/edje/src/bin/edje_cc_handlers.c @@ -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) { diff --git a/legacy/edje/src/lib/edje_data.c b/legacy/edje/src/lib/edje_data.c index 4cb9e2dd81..556839ca9c 100644 --- a/legacy/edje/src/lib/edje_data.c +++ b/legacy/edje/src/lib/edje_data.c @@ -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); diff --git a/legacy/edje/src/lib/edje_load.c b/legacy/edje/src/lib/edje_load.c index a815f8edbb..53c9e3414f 100644 --- a/legacy/edje/src/lib/edje_load.c +++ b/legacy/edje/src/lib/edje_load.c @@ -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); diff --git a/legacy/edje/src/lib/edje_private.h b/legacy/edje/src/lib/edje_private.h index 45a812a530..19966faf65 100644 --- a/legacy/edje/src/lib/edje_private.h +++ b/legacy/edje/src/lib/edje_private.h @@ -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; }; diff --git a/legacy/edje/src/lib/edje_util.c b/legacy/edje/src/lib/edje_util.c index 4802d0ab99..b7984e67a4 100644 --- a/legacy/edje/src/lib/edje_util.c +++ b/legacy/edje/src/lib/edje_util.c @@ -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); diff --git a/legacy/evas/src/lib/Evas.h b/legacy/evas/src/lib/Evas.h index b450ac5c37..28e5bd6279 100644 --- a/legacy/evas/src/lib/Evas.h +++ b/legacy/evas/src/lib/Evas.h @@ -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)); diff --git a/legacy/evas/src/lib/canvas/evas_events.c b/legacy/evas/src/lib/canvas/evas_events.c index 720a7a5160..3ce9c2391e 100644 --- a/legacy/evas/src/lib/canvas/evas_events.c +++ b/legacy/evas/src/lib/canvas/evas_events.c @@ -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, diff --git a/legacy/evas/src/lib/canvas/evas_object_image.c b/legacy/evas/src/lib/canvas/evas_object_image.c index da39bc14e7..69f8a9b7e4 100644 --- a/legacy/evas/src/lib/canvas/evas_object_image.c +++ b/legacy/evas/src/lib/canvas/evas_object_image.c @@ -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); +} diff --git a/legacy/evas/src/lib/canvas/evas_object_main.c b/legacy/evas/src/lib/canvas/evas_object_main.c index de045b4dc5..08faa8d319 100644 --- a/legacy/evas/src/lib/canvas/evas_object_main.c +++ b/legacy/evas/src/lib/canvas/evas_object_main.c @@ -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; +} diff --git a/legacy/evas/src/lib/include/evas_private.h b/legacy/evas/src/lib/include/evas_private.h index 34f8f12ec7..08cf9fafae 100644 --- a/legacy/evas/src/lib/include/evas_private.h +++ b/legacy/evas/src/lib/include/evas_private.h @@ -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); diff --git a/legacy/evas/src/modules/engines/cairo_x11/evas_engine.c b/legacy/evas/src/modules/engines/cairo_x11/evas_engine.c index 91bc43b62e..27ed9868a0 100644 --- a/legacy/evas/src/modules/engines/cairo_x11/evas_engine.c +++ b/legacy/evas/src/modules/engines/cairo_x11/evas_engine.c @@ -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, diff --git a/legacy/evas/src/modules/engines/software_16/evas_engine.c b/legacy/evas/src/modules/engines/software_16/evas_engine.c index 53041a9925..9269dfad04 100644 --- a/legacy/evas/src/modules/engines/software_16/evas_engine.c +++ b/legacy/evas/src/modules/engines/software_16/evas_engine.c @@ -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, diff --git a/legacy/evas/src/modules/engines/software_generic/evas_engine.c b/legacy/evas/src/modules/engines/software_generic/evas_engine.c index 7bfc94c83a..494cf5aad3 100644 --- a/legacy/evas/src/modules/engines/software_generic/evas_engine.c +++ b/legacy/evas/src/modules/engines/software_generic/evas_engine.c @@ -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,