Hi Guys,

On Thu, Nov 01, 2012 at 09:37:18AM +0900, ChunEon Park wrote:
> Ok i will see this. 
> 
> Thank you for reporting.
> 
> 
> 
> ------------------------------------
> 
> -Regards, Hermet-
> 
> -----Original Message-----
> From: "Bruno Dilly"<bdi...@profusion.mobi> 
> To: "Enlightenment developer 
> list"<enlightenment-devel@lists.sourceforge.net>; 
> Cc: 
> Sent: 2012-11-01 (목) 06:29:06
> Subject: Re: [E-devel] E SVN: hermet IN trunk/evas/src/lib: . canvas include
> 
> On Mon, Oct 29, 2012 at 11:28 PM, ChunEon Park <hermet>@naver.com> 
> wrote:
> > evas_object_image_source_event_set(proxy, EINA_TRUE);
> > this one?
> >
> >
> > I can say Evas Events can be passed to the source definitely now.
> >
> > (if not, then it's bug. should be fixed.)
> >
> >
> > But some smart events (i.e. in elementary widgets) may not be happened 
> by this mechanism because  of the focus or whatever event hold or grab 
> problem.
> >
> >
> >
> > What object type of the source is?
> 
> Elm image.
> 
> >
> >
> >
> > Could u  give me test case for it?
> 
> OK, the initial issue was that my proxies were smaller (obj size) then
> source / map. So it was receiving events only on part of the map.
> It was fixed setting the same size for proxies and source.
> 
> But when I was looking for this issue, I found the following line on
> _image_source_visible_set
> evas_object_image.c:633
> //FIXME: Feed mouse events here.
> 
> So I decided to send this email.
> 
> OK, that was solved, but when I'm trying to grab an object it receives
> a wrong value on Evas_Event_Mouse_Move, received on the move callback
> of the source object.
> 
> I'm not sure if it's an issue with proxy -> source events conversion,
> or it's an issue on map conversion, or even a misuse on ephysics,
> since I wasn't able to reproduce it on a smaller example.
> The ephysics test displaying such error has about 450 proxy objects.
> 


I`ve managed to reproduce the proble. I`m attaching an example program
to explore the problem. To test it click on over the evas object and grab it
out - keep grabbing to better notice the coord inconsistence.

There`re two big issues here, the first is about evas map, if you "grab"
off of the evas object Evas will not handle the event coord properly,
what happens is that the point is not inside the map but we keep assuming that.

The problem is not specifically related to source object events, the same will
happen if handling an evas object mouse move event or a proxy -> source one.

The second issue is about the _evas_event_source_mouse_move_events function,
there the canvas and output event attribute values are considered to be the 
same, so
the user will receive the same values both on canvas and output. I`m not sure
if the same happens for other cases/events, I don't even know the "proper" 
meaning of
each(but I think canvas and output mean different things in this context).

I`m attaching a patch which cares about both the 2 cases I`ve mentioned, I 
would love
your review and a better test since I`ve not tested all the possible use 
cases/scenarios
so I can not be sure if I`m breaking something else.

PS: Let me know if I`ve misunderstood the problem here or have fixed the wrong 
bug. :-)

Regards....


-- 
Leandro Dorileo
ProFUSION embedded systems
http://profusion.mobi

#include <Ecore.h>
#include <Ecore_Evas.h>

#define WIDTH 500
#define HEIGHT 500

static void
_on_delete(Ecore_Evas *ee)
{
  ecore_main_loop_quit();
}

static void
_mouse_move_cb(void *data, Evas *evas, Evas_Object *obj, void *event_info)
{
  Evas_Event_Mouse_Move *mmove = event_info;

  printf("canvas: (%d, %d) - ", mmove->cur.canvas.x, mmove->cur.canvas.y);
  printf("output: (%d, %d)\n", mmove->cur.output.x, mmove->cur.output.y);
}

int main(int argc, const char *argv[])
{
  Ecore_Evas *ee;
  Evas *evas;
  Evas_Object *bg, *rect, *proxy;
  Evas_Map *map;
  Evas_Coord x, y, w, h;

  if (!ecore_evas_init())
    return EXIT_FAILURE;
  
  ee = ecore_evas_new(NULL, 0, 0, WIDTH, HEIGHT, NULL);
  if (!ee)
    goto no_ee;
  
  ecore_evas_title_set(ee, "Test");
  ecore_evas_callback_delete_request_set(ee, _on_delete);
  ecore_evas_show(ee);
  
  evas = ecore_evas_get(ee);
  
  bg = evas_object_rectangle_add(evas);
  evas_object_resize(bg, WIDTH, HEIGHT);
  evas_object_move(bg, 0, 0);
  evas_object_color_set(bg, 255, 255, 255, 255);
  evas_object_show(bg);
  
  evas_object_focus_set(bg, EINA_TRUE);

  rect = evas_object_rectangle_add(evas);
  evas_object_color_set(rect, 0, 0, 0, 122);
  evas_object_resize(rect, 70, 70);
  evas_object_move(rect, 0, 0);
  evas_object_show(rect);

  evas_object_event_callback_add(rect, EVAS_CALLBACK_MOUSE_MOVE, _mouse_move_cb,
				 NULL);

  proxy = evas_object_image_filled_add(evas);
  evas_object_image_source_set(proxy, rect);
  evas_object_resize(proxy, 70, 70);
  evas_object_move(proxy, WIDTH - 70, 0);
  evas_object_show(proxy);
  evas_object_image_source_visible_set(proxy, EINA_FALSE);
  evas_object_image_source_events_set(proxy, EINA_TRUE);

  evas_object_geometry_get(proxy, &x, &y, &w, &h);

  map = evas_map_new(4);
  evas_map_util_points_populate_from_object(map, proxy);
  
  evas_map_point_coord_set(map, 2, x, y + h, 0);

  evas_object_map_set(proxy, map);
  evas_object_map_enable_set(proxy, EINA_TRUE);
  evas_map_free(map);

  ecore_main_loop_begin();
  
  ecore_evas_shutdown();
  return EXIT_SUCCESS;
  
 no_ee:
  printf("Couldn't create a new canvas.");
  return EXIT_FAILURE;
}
diff --git a/src/lib/canvas/evas_events.c b/src/lib/canvas/evas_events.c
index 36e9660..920f4ec 100644
--- a/src/lib/canvas/evas_events.c
+++ b/src/lib/canvas/evas_events.c
@@ -13,6 +13,8 @@ evas_event_list_copy(Eina_List *list);
 static void
 _evas_event_havemap_adjust(Evas_Object *eo_obj EINA_UNUSED, Evas_Object_Protected_Data *obj, Evas_Coord *x, Evas_Coord *y, Eina_Bool mouse_grabbed)
 {
+   Eina_Bool map_coords = EINA_FALSE;
+
    if (obj->smart.parent)
      {
         Evas_Object_Protected_Data *smart_parent_obj = eo_data_get(obj->smart.parent, EVAS_OBJ_CLASS);
@@ -22,9 +24,12 @@ _evas_event_havemap_adjust(Evas_Object *eo_obj EINA_UNUSED, Evas_Object_Protecte
    if ((!obj->cur.usemap) || (!obj->cur.map) || (!obj->cur.map->count == 4))
       return;
 
-   evas_map_coords_get(obj->cur.map, *x, *y, x, y, mouse_grabbed);
-   *x += obj->cur.geometry.x;
-   *y += obj->cur.geometry.y;
+   map_coords = evas_map_coords_get(obj->cur.map, *x, *y, x, y, mouse_grabbed);
+   if (map_coords)
+     {
+        *x += obj->cur.geometry.x;
+        *y += obj->cur.geometry.y;
+     }
 }
 
 static void
@@ -275,15 +280,10 @@ _evas_event_source_mouse_move_events(Evas_Object *eo_obj, Evas *eo_e, Evas_Event
 
    _transform_to_src_space(obj, src, &ev->cur.canvas.x, &ev->cur.canvas.y);
 
-   ev->cur.output.x = ev->cur.canvas.x;
-   ev->cur.output.y = ev->cur.canvas.y;
-
    //FIXME: transform previous coords also.
    Eina_List *l;
    Evas_Object *eo_child;
    Evas_Object_Protected_Data *child;
-   Evas_Coord point_x = ev->cur.canvas.x;
-   Evas_Coord point_y = ev->cur.canvas.y;
 
    if (e->pointer.mouse_grabbed)
      {
@@ -299,8 +299,6 @@ _evas_event_source_mouse_move_events(Evas_Object *eo_obj, Evas *eo_e, Evas_Event
                (!evas_event_freezes_through(eo_child, child)) &&
                (!child->clip.clipees))
                {
-                  ev->cur.canvas.x = point_x;
-                  ev->cur.canvas.y = point_y;
                   _evas_event_framespace_adjust(eo_child, &ev->cur.canvas.x,
                                                 &ev->cur.canvas.y);
                   _evas_event_havemap_adjust(eo_child, child, &ev->cur.canvas.x,
@@ -360,9 +358,6 @@ _evas_event_source_mouse_move_events(Evas_Object *eo_obj, Evas *eo_e, Evas_Event
           {
              child = eo_data_get(eo_child, EVAS_OBJ_CLASS);
 
-             ev->cur.canvas.x = point_x;
-             ev->cur.canvas.y = point_y;
-
              if (evas_object_is_in_output_rect(eo_child, child,
                                                ev->cur.canvas.x,
                                                ev->cur.canvas.y, 1, 1) &&
@@ -389,8 +384,6 @@ _evas_event_source_mouse_move_events(Evas_Object *eo_obj, Evas *eo_e, Evas_Event
                {
                   child->mouse_in = 0;
                   if (e->is_frozen) continue;
-                  ev->cur.canvas.x = point_x;
-                  ev->cur.canvas.y = point_y;
                   _evas_event_framespace_adjust(eo_child,
                                                 &ev->cur.canvas.x,
                                                 &ev->cur.canvas.y);
@@ -418,8 +411,6 @@ _evas_event_source_mouse_move_events(Evas_Object *eo_obj, Evas *eo_e, Evas_Event
                      {
                         child->mouse_in = 1;
                         if (e->is_frozen) continue;
-                        ev->cur.canvas.x = point_x;
-                        ev->cur.canvas.y = point_y;
                         _evas_event_framespace_adjust(eo_child,
                                                       &ev->cur.canvas.x,
                                                       &ev->cur.canvas.y);
diff --git a/src/lib/canvas/evas_map.c b/src/lib/canvas/evas_map.c
index 3338d37..bcbec33 100644
--- a/src/lib/canvas/evas_map.c
+++ b/src/lib/canvas/evas_map.c
@@ -233,21 +233,45 @@ evas_map_coords_get(const Evas_Map *m, Evas_Coord x, Evas_Coord y,
    double v[2] = { 0.0, 0.0 };
 
    if (m->count < 4) return 0;
-   // FIXME need to handle grab mode and extrapolte coords outside
-   // map
    if (grab)
      {
-        Evas_Coord ymin, ymax;
+        Evas_Coord ymin, ymax, xmin, xmax, cx, cy, lx, ly;
+        Eina_Bool within = EINA_FALSE;
+        int j = m->count - 1;
+
+        for (i = 0; i < m->count; i++)
+          {
+             cx = m->points[i].x;
+             cy = m->points[i].y;
+             lx = m->points[j].x;
+             ly = m->points[j].y;
+
+             if (cy < y && ly >= y ||  ly < y && cy >= y)
+               if (cx + (y - cy) / (ly - cy) * (lx - cx) < x)
+                 within = !within;
+             j=i;
+          }
+
+        if (!within)
+          return EINA_FALSE;
 
         ymin = m->points[0].y;
         ymax = m->points[0].y;
+        xmin = m->points[0].x;
+        xmax = m->points[0].x;
+
         for (i = 1; i < m->count; i++)
           {
              if (m->points[i].y < ymin) ymin = m->points[i].y;
              else if (m->points[i].y > ymax) ymax = m->points[i].y;
+             if (m->points[i].x < xmin) xmin = m->points[i].x;
+             else if (m->points[i].x > xmax) xmax = m->points[i].x;
           }
-        if (y <= ymin) y = ymin + 1;
-        if (y >= ymax) y = ymax - 1;
+
+        if (y < ymin || x < xmin || y > ymax || x > xmax) return EINA_FALSE;
+
+        if (y = ymin) y = ymin + 1;
+        if (y = ymax) y = ymax - 1;
      }
    edges = 0;
    for (i = 0; i < m->count; i++)
------------------------------------------------------------------------------
LogMeIn Central: Instant, anywhere, Remote PC access and management.
Stay in control, update software, and manage PCs from one command center
Diagnose problems and improve visibility into emerging IT issues
Automate, monitor and manage. Do more in less time with Central
http://p.sf.net/sfu/logmein12331_d2d
_______________________________________________
enlightenment-devel mailing list
enlightenment-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/enlightenment-devel

Reply via email to