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

Reply via email to