Ooops,
Forgot to attach the modified patch.
On 7/9/07, Andre Magalhaes <[EMAIL PROTECTED]> wrote:
Hi,
On 7/9/07, Gustavo Sverzut Barbieri <[EMAIL PROTECTED]> wrote:
> On 7/9/07, Andre Magalhaes <[EMAIL PROTECTED]> wrote:
> > Hey Raster,
> >
> > On 7/9/07, The Rasterman Carsten Haitzler <[EMAIL PROTECTED]> wrote:
> > > On Fri, 6 Jul 2007 18:00:08 -0300 "Andre Magalhaes" <[EMAIL PROTECTED]>
> > > babbled:
> > >
> > > > Hi all,
> > > >
> > > > As this is my first post here, let me introduce myself. I am Andre
> > > > Moreira Magalhaes, aka andrunko, and I work for INdT in Brazil.
> > >
> > > hey andre :)
> > >
> > > > Now let's go to the point. I am working on a project that requires
> > > > that an Evas_Object to have a custom click area. This object is a
> > > > non-retangular object (a circle for eg) with a transparent backgroung.
> > > > When i click on the background of this object, if the click was in a
> > > > transparent area this object shouldn't receive any event. I was
> > > > investigating the Evas code and i found 3 ways that this could be
> > > > done.
> > >
> > > currently evas doesn't do this. in theory it could - but it doesn't.
> > >
> > > > 1 - Change evas_object_was_in_output_rect to always return 0 if the
> > > > rect is in a transparent area of the object (not desired)
> > > > 2 - Change evas_object_event_callback_call to return a boolean value
> > > > indicating if the object handled the event and if not, keep sending
> > > > event to the other objects in the list. If the object handled the
> > > > event, stop there. This would require a lot of changes.
> > > > 3 - Change evas_object_was_in_output_rect to check a for a custom
> > > > "in_output_rect" method on the object, and if this method is set, use
> > > > it to check if the rect is in output rect. This would require a new
> > > > function, evas_object_is_in_output_rect_cb_set (or something similar)
> > > > that could be implemented whenever is needed. If this method is not
> > > > set, check the clip rectangle as it's done today.
> > >
> > > actually i already designed for this. there is an is_inside and was_inside
> > > method for objects. only line and polygon objects provide them and they
just
> > > return 1 - these CAN be called if a point is inside the object rect and
the
> > > code wants to determine if an event is still inside the object based on
private
> > > object data (eg polygon outline, image pixel alpha channel data etc.).
right
> > > now it basically isn't used - but its intent was to be used for this. the
> > > problem is this is actually relatively slow/expensive to do. you probably
also
> > > want a way of enabling or disabling this level of event processing per
object
> > > to save cost. so we probably need to add an object flag to use these
methods,
> > > if they exist, or disable them (disabled by default), then provide
methods for
> > > image objects at the least - then actually use them, if they are
provided, and
> > > the flag is enabled for that object. implementing this won't be too hrd,
but it
> > > won't be trivial. you need to be able to figure otu any x,y co-ord within
the
> > > object and what pixel of the image that may map to based on paremeters of
the
> > > object, then go check that pixel's alpha channel (if the image has an
alpha
> > > channel). for polygon nd line objects you need to do some half-plane point
> > > intersection math (easy but its order(n) where n is the number of sides
of the
> > > polygon). for lines its strange - you might want perfect inclusion, but
that's a
> > > very small space unless its a thick line (doesn't exist currently). for
text...
> > > thats hard as you need to figure out what character is in that x,y
(that's easy)
> > > and then check the character glyph pixels to see if its inside...
> > >
> > > but anyway - i added this mechanism in at the very start but have never
used it
> > > (or really needed it enough to implement the rest of it).
> > hmmm, i didn't know about this is_inside method, it's similar to what
> > i wanted but with some improvements :D. Attached there is a patch to
> > implement it on evas_object_image and edje, and a callback to
> > enable/disable it. I didn't like the name convention but this is
> > something easy to change. I tested it here and it seems to be working.
> > This is my first patch to evas, so please let me know where i can
> > improve. Any comment is welcome
>
>
> + if (x > w || y > h) {
> + return 0;
> + }
>
> coding style, raster likes ((cond1) || (cond2))
Fixed.
>
> + o->engine_data =
>
obj->layer->evas->engine.func->image_data_get(obj->layer->evas->engine.data.output,
> +
o->engine_data,
> + 0,
> + &data);
> + data += (y * w) + x;
> + a = (*data >> 24) & 0xff;
>
> this will not work for engines != 32bpp, like my 16bpp. If not
> existent, we need to write an engine-provided get_pixel(), that give
> normalized 0-255 components.
I imagined that but in the documentation of evas_object_image_data_get it says:
* @return A pointer to the raw data as 32 bit unsigned integer in format ARGB.
I thought that all engines should convert it to 32 bits in this case,
as it's stated on documentation. I am using the same method as
evas_object_image_data_get uses. Please someone could clarify this.
BR
Andrunko
BR
Andrunko
Index: src/lib/Evas.h
===================================================================
RCS file: /var/cvs/e/e17/libs/evas/src/lib/Evas.h,v
retrieving revision 1.99
diff -u -r1.99 Evas.h
--- src/lib/Evas.h 17 Jun 2007 02:56:57 -0000 1.99
+++ src/lib/Evas.h 9 Jul 2007 23:15:00 -0000
@@ -768,6 +768,9 @@
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));
Index: src/lib/canvas/evas_events.c
===================================================================
RCS file: /var/cvs/e/e17/libs/evas/src/lib/canvas/evas_events.c,v
retrieving revision 1.51
diff -u -r1.51 evas_events.c
--- src/lib/canvas/evas_events.c 30 Apr 2007 04:22:42 -0000 1.51
+++ src/lib/canvas/evas_events.c 9 Jul 2007 23:15:03 -0000
@@ -57,7 +57,9 @@
}
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_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_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 @@
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,
Index: src/lib/canvas/evas_object_image.c
===================================================================
RCS file: /var/cvs/e/e17/libs/evas/src/lib/canvas/evas_object_image.c,v
retrieving revision 1.52
diff -u -r1.52 evas_object_image.c
--- src/lib/canvas/evas_object_image.c 28 Jun 2007 23:22:20 -0000 1.52
+++ src/lib/canvas/evas_object_image.c 9 Jul 2007 23:15:08 -0000
@@ -67,6 +67,7 @@
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 @@
NULL,
evas_object_image_is_opaque,
evas_object_image_was_opaque,
- NULL,
+ evas_object_image_is_inside,
NULL,
NULL
};
@@ -2249,3 +2250,32 @@
return 0;
return 1;
}
+
+static int
+evas_object_image_is_inside(Evas_Object *obj, Evas_Coord x, Evas_Coord y)
+{
+ Evas_Object_Image *o;
+ DATA32 *data;
+ int w, h;
+ 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;
+ }
+
+ o->engine_data = obj->layer->evas->engine.func->image_data_get(obj->layer->evas->engine.data.output,
+ o->engine_data,
+ 0,
+ &data);
+ data += (y * w) + x;
+ a = (*data >> 24) & 0xff;
+
+ return (a != 0);
+}
Index: src/lib/canvas/evas_object_main.c
===================================================================
RCS file: /var/cvs/e/e17/libs/evas/src/lib/canvas/evas_object_main.c,v
retrieving revision 1.56
diff -u -r1.56 evas_object_main.c
--- src/lib/canvas/evas_object_main.c 21 Feb 2007 21:43:45 -0000 1.56
+++ src/lib/canvas/evas_object_main.c 9 Jul 2007 23:15:11 -0000
@@ -419,6 +419,23 @@
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 @@
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;
+}
Index: src/lib/include/evas_private.h
===================================================================
RCS file: /var/cvs/e/e17/libs/evas/src/lib/include/evas_private.h,v
retrieving revision 1.85
diff -u -r1.85 evas_private.h
--- src/lib/include/evas_private.h 28 Jun 2007 23:22:20 -0000 1.85
+++ src/lib/include/evas_private.h 9 Jul 2007 23:15:14 -0000
@@ -448,6 +448,8 @@
unsigned short in_layer : 1;
unsigned short no_propagate : 1;
+ unsigned short precise_is_inside : 1;
+
unsigned char delete_me;
};
@@ -678,6 +680,8 @@
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);
-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/
_______________________________________________
enlightenment-devel mailing list
enlightenment-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/enlightenment-devel