From 28e89a5ac7e556b198dbe7e883d248c12f4844df Mon Sep 17 00:00:00 2001 From: Mike Blumenkrantz Date: Mon, 13 Jan 2020 15:04:38 -0500 Subject: [PATCH] efl/gesture: move Point_Data to eo and add methods to fetch it for recognizers this lets gesture framework track two touch points in order to distinguish between successive presses and e.g., treat a simultaneous two finger tap as a single tap gesture rather than two it also simplifies some internal code and removes most hash lookups Reviewed-by: woochan lee Differential Revision: https://phab.enlightenment.org/D11085 --- .../evas/gesture/efl_canvas_gesture_private.h | 23 ++---- .../efl_canvas_gesture_recognizer_zoom.c | 20 +++-- .../evas/gesture/efl_canvas_gesture_touch.c | 81 +++++++++++-------- .../evas/gesture/efl_canvas_gesture_touch.eo | 23 ++++++ .../evas/gesture/efl_canvas_gesture_types.eot | 18 +++++ 5 files changed, 103 insertions(+), 62 deletions(-) diff --git a/src/lib/evas/gesture/efl_canvas_gesture_private.h b/src/lib/evas/gesture/efl_canvas_gesture_private.h index fb24d0f549..e24dea8307 100644 --- a/src/lib/evas/gesture/efl_canvas_gesture_private.h +++ b/src/lib/evas/gesture/efl_canvas_gesture_private.h @@ -25,22 +25,13 @@ typedef struct _Efl_Canvas_Gesture_Momentum_Data Efl_Canvas_Gestur typedef struct _Efl_Canvas_Gesture_Flick_Data Efl_Canvas_Gesture_Flick_Data; typedef struct _Efl_Canvas_Gesture_Zoom_Data Efl_Canvas_Gesture_Zoom_Data; -typedef struct _Pointer_Data -{ - struct - { - Eina_Position2D pos; - unsigned int timestamp; - } start, prev, cur; - int id; - Efl_Pointer_Action action; -} Pointer_Data; - typedef struct _Efl_Canvas_Gesture_Touch_Data { Efl_Canvas_Gesture_Touch_State state; - Eina_Hash *touch_points; + Eina_Array *touch_points; int touch_down; + Efl_Gesture_Touch_Point_Data *cur_touch; + Efl_Gesture_Touch_Point_Data *prev_touch; Eina_Bool multi_touch; Eo *target; } Efl_Canvas_Gesture_Touch_Data; @@ -115,11 +106,11 @@ struct _Efl_Canvas_Gesture_Recognizer_Flick_Data struct _Efl_Canvas_Gesture_Recognizer_Zoom_Data { - Pointer_Data zoom_st; - Pointer_Data zoom_st1; + Efl_Gesture_Touch_Point_Data zoom_st; + Efl_Gesture_Touch_Point_Data zoom_st1; - Pointer_Data zoom_mv; - Pointer_Data zoom_mv1; + Efl_Gesture_Touch_Point_Data zoom_mv; + Efl_Gesture_Touch_Point_Data zoom_mv1; Evas_Coord zoom_base; /* Holds gap between fingers on * zoom-start */ diff --git a/src/lib/evas/gesture/efl_canvas_gesture_recognizer_zoom.c b/src/lib/evas/gesture/efl_canvas_gesture_recognizer_zoom.c index 0603098539..d88a9c0050 100644 --- a/src/lib/evas/gesture/efl_canvas_gesture_recognizer_zoom.c +++ b/src/lib/evas/gesture/efl_canvas_gesture_recognizer_zoom.c @@ -126,8 +126,6 @@ _efl_canvas_gesture_recognizer_zoom_efl_canvas_gesture_recognizer_recognize(Eo * Efl_Object *watched, Efl_Canvas_Gesture_Touch *event) { - int id1 = 0; - int id2 = 1; Eina_Value *val; unsigned char zoom_finger_enable; unsigned char glayer_continues_enable; @@ -186,14 +184,14 @@ _efl_canvas_gesture_recognizer_zoom_efl_canvas_gesture_recognizer_recognize(Eo * if (!efl_gesture_touch_multi_touch_get(event)) return EFL_GESTURE_RECOGNIZER_RESULT_IGNORE; - Pointer_Data *p1 = eina_hash_find(td->touch_points, &id1); - Pointer_Data *p2 = eina_hash_find(td->touch_points, &id2); + const Efl_Gesture_Touch_Point_Data *p1 = efl_gesture_touch_data_get(event, 0); + const Efl_Gesture_Touch_Point_Data *p2 = efl_gesture_touch_data_get(event, 1); - memcpy(&pd->zoom_st, p2, sizeof(Pointer_Data)); - memcpy(&pd->zoom_st1, p1, sizeof(Pointer_Data)); + memcpy(&pd->zoom_st, p2, sizeof(Efl_Gesture_Touch_Point_Data)); + memcpy(&pd->zoom_st1, p1, sizeof(Efl_Gesture_Touch_Point_Data)); - memcpy(&pd->zoom_mv, p2, sizeof(Pointer_Data)); - memcpy(&pd->zoom_mv1, p1, sizeof(Pointer_Data)); + memcpy(&pd->zoom_mv, p2, sizeof(Efl_Gesture_Touch_Point_Data)); + memcpy(&pd->zoom_mv1, p1, sizeof(Efl_Gesture_Touch_Point_Data)); int x, y; //Hot spot zd->zoom = 1.0; @@ -212,11 +210,11 @@ _efl_canvas_gesture_recognizer_zoom_efl_canvas_gesture_recognizer_recognize(Eo * return EFL_GESTURE_RECOGNIZER_RESULT_CANCEL; } - Pointer_Data *p2 = eina_hash_find(td->touch_points, &id2); + const Efl_Gesture_Touch_Point_Data *p2 = efl_gesture_touch_data_get(event, 1); if (p2->id == pd->zoom_mv.id) - memcpy(&pd->zoom_mv, p2, sizeof(Pointer_Data)); + memcpy(&pd->zoom_mv, p2, sizeof(Efl_Gesture_Touch_Point_Data)); else if (p2->id == pd->zoom_mv1.id) - memcpy(&pd->zoom_mv1, p2, sizeof(Pointer_Data)); + memcpy(&pd->zoom_mv1, p2, sizeof(Efl_Gesture_Touch_Point_Data)); zd->zoom = _zoom_compute(pd, zd, pd->zoom_mv.cur.pos.x, pd->zoom_mv.cur.pos.y, pd->zoom_mv1.cur.pos.x, diff --git a/src/lib/evas/gesture/efl_canvas_gesture_touch.c b/src/lib/evas/gesture/efl_canvas_gesture_touch.c index 6ddb3be59e..3ed9dfe2b2 100644 --- a/src/lib/evas/gesture/efl_canvas_gesture_touch.c +++ b/src/lib/evas/gesture/efl_canvas_gesture_touch.c @@ -6,33 +6,30 @@ //that are directed to a particular object from the //first finger down to the last finger up -static void -_hash_free_cb(Pointer_Data *point) -{ - free(point); -} - static inline void _touch_points_reset(Efl_Canvas_Gesture_Touch_Data *pd) { - eina_hash_free(pd->touch_points); - pd->touch_points = eina_hash_int32_new(EINA_FREE_CB(_hash_free_cb)); + while (eina_array_count(pd->touch_points)) + free(eina_array_pop(pd->touch_points)); pd->touch_down = 0; + pd->prev_touch = pd->cur_touch = NULL; pd->state = EFL_GESTURE_TOUCH_STATE_UNKNOWN; } EOLIAN static Efl_Object * _efl_canvas_gesture_touch_efl_object_constructor(Eo *obj, Efl_Canvas_Gesture_Touch_Data *pd) { - obj = efl_constructor(efl_super(obj, MY_CLASS)); - _touch_points_reset(pd); - return obj; + pd->touch_points = eina_array_new(2); + EINA_SAFETY_ON_NULL_RETURN_VAL(pd->touch_points, NULL); + return efl_constructor(efl_super(obj, MY_CLASS)); } EOLIAN static void _efl_canvas_gesture_touch_efl_object_destructor(Eo *obj, Efl_Canvas_Gesture_Touch_Data *pd) { - eina_hash_free(pd->touch_points); + while (eina_array_count(pd->touch_points)) + free(eina_array_pop(pd->touch_points)); + eina_array_free(pd->touch_points); efl_destructor(efl_super(obj, MY_CLASS)); } @@ -51,14 +48,16 @@ _efl_canvas_gesture_touch_point_record(Eo *obj EINA_UNUSED, Efl_Canvas_Gesture_T Efl_Pointer_Action action = pointer_data->action; Eina_Vector2 pos = pointer_data->cur; - Pointer_Data *point = eina_hash_find(pd->touch_points, &id); Eina_Position2D _pos = { pos.x, pos.y }; + Efl_Gesture_Touch_Point_Data *point = NULL; + + if (eina_array_count(pd->touch_points) >= (unsigned int)id + 1) + point = eina_array_data_get(pd->touch_points, id); if (action == EFL_POINTER_ACTION_DOWN) { pd->touch_down++; - //TODO: Need to handle 2 or more case. - if (pd->touch_down == 2) + if (pd->touch_down >= 2) pd->multi_touch = EINA_TRUE; } else if ((action == EFL_POINTER_ACTION_UP) || @@ -86,18 +85,17 @@ _efl_canvas_gesture_touch_point_record(Eo *obj EINA_UNUSED, Efl_Canvas_Gesture_T //Discard any other event return; } - point = calloc(1, sizeof(Pointer_Data)); + point = calloc(1, sizeof(Efl_Gesture_Touch_Point_Data)); if (!point) return; point->start.pos = point->prev.pos = point->cur.pos = _pos; point->start.timestamp = point->prev.timestamp = point->cur.timestamp = timestamp; point->id = id; - //Add to the hash - eina_hash_add(pd->touch_points, &id, point); - //FIXME: finger_list was broken - if (id) - pd->multi_touch = EINA_TRUE; + eina_array_push(pd->touch_points, point); } + if (pd->cur_touch != point) + pd->prev_touch = pd->cur_touch; + pd->cur_touch = point; point->action = action; if (!id && (action == EFL_POINTER_ACTION_DOWN)) @@ -124,11 +122,28 @@ _efl_canvas_gesture_touch_multi_touch_get(const Eo *obj EINA_UNUSED, Efl_Canvas_ return pd->multi_touch; } -EOLIAN static Eina_Position2D -_efl_canvas_gesture_touch_start_point_get(const Eo *obj EINA_UNUSED, Efl_Canvas_Gesture_Touch_Data *pd) +EOLIAN static const Efl_Gesture_Touch_Point_Data * +_efl_canvas_gesture_touch_cur_data_get(const Eo *obj EINA_UNUSED, Efl_Canvas_Gesture_Touch_Data *pd) { - int tool = 0; - Pointer_Data *point = eina_hash_find(pd->touch_points, &tool); + return pd->cur_touch; +} + +EOLIAN static const Efl_Gesture_Touch_Point_Data * +_efl_canvas_gesture_touch_prev_data_get(const Eo *obj EINA_UNUSED, Efl_Canvas_Gesture_Touch_Data *pd) +{ + return pd->prev_touch; +} + +EOLIAN static const Efl_Gesture_Touch_Point_Data * +_efl_canvas_gesture_touch_data_get(const Eo *obj EINA_UNUSED, Efl_Canvas_Gesture_Touch_Data *pd, unsigned int id) +{ + return eina_array_count(pd->touch_points) >= id + 1 ? eina_array_data_get(pd->touch_points, id) : NULL; +} + +EOLIAN static Eina_Position2D +_efl_canvas_gesture_touch_start_point_get(const Eo *obj EINA_UNUSED, Efl_Canvas_Gesture_Touch_Data *pd EINA_UNUSED) +{ + const Efl_Gesture_Touch_Point_Data *point = efl_gesture_touch_data_get(obj, 0); Eina_Position2D vec = { 0, 0 }; if (!point) @@ -140,8 +155,7 @@ _efl_canvas_gesture_touch_start_point_get(const Eo *obj EINA_UNUSED, Efl_Canvas_ EOLIAN static Eina_Position2D _efl_canvas_gesture_touch_cur_point_get(const Eo *obj EINA_UNUSED, Efl_Canvas_Gesture_Touch_Data *pd) { - int tool = 0; - Pointer_Data *point = eina_hash_find(pd->touch_points, &tool); + const Efl_Gesture_Touch_Point_Data *point = pd->cur_touch; Eina_Position2D vec = { 0, 0 }; if (!point) @@ -153,8 +167,7 @@ _efl_canvas_gesture_touch_cur_point_get(const Eo *obj EINA_UNUSED, Efl_Canvas_Ge EOLIAN static unsigned int _efl_canvas_gesture_touch_cur_timestamp_get(const Eo *obj EINA_UNUSED, Efl_Canvas_Gesture_Touch_Data *pd) { - int tool = 0; - Pointer_Data *point = eina_hash_find(pd->touch_points, &tool); + const Efl_Gesture_Touch_Point_Data *point = pd->cur_touch; if (!point) return 0; @@ -165,11 +178,10 @@ _efl_canvas_gesture_touch_cur_timestamp_get(const Eo *obj EINA_UNUSED, Efl_Canva EOLIAN static Eina_Vector2 _efl_canvas_gesture_touch_delta(const Eo *obj EINA_UNUSED, Efl_Canvas_Gesture_Touch_Data *pd, int tool) { - Pointer_Data *point = eina_hash_find(pd->touch_points, &tool); + Efl_Gesture_Touch_Point_Data *point = eina_array_count(pd->touch_points) >= (unsigned)tool + 1 ? eina_array_data_get(pd->touch_points, tool) : NULL; Eina_Vector2 vec = { 0, 0 }; - if (!point) - return vec; + EINA_SAFETY_ON_NULL_RETURN_VAL(point, vec); Eina_Vector2 v1 = { point->cur.pos.x, point->cur.pos.y }; Eina_Vector2 v2 = { point->prev.pos.x, point->prev.pos.y }; @@ -181,11 +193,10 @@ _efl_canvas_gesture_touch_delta(const Eo *obj EINA_UNUSED, Efl_Canvas_Gesture_To EOLIAN static Eina_Vector2 _efl_canvas_gesture_touch_distance(const Eo *obj EINA_UNUSED, Efl_Canvas_Gesture_Touch_Data *pd, int tool) { - Pointer_Data *point = eina_hash_find(pd->touch_points, &tool); + Efl_Gesture_Touch_Point_Data *point = eina_array_count(pd->touch_points) >= (unsigned)tool + 1 ? eina_array_data_get(pd->touch_points, tool) : NULL; Eina_Vector2 vec = { 0, 0 }; - if (!point) - return vec; + EINA_SAFETY_ON_NULL_RETURN_VAL(point, vec); Eina_Vector2 v1 = { point->cur.pos.x, point->cur.pos.y }; Eina_Vector2 v2 = { point->start.pos.x, point->start.pos.y }; diff --git a/src/lib/evas/gesture/efl_canvas_gesture_touch.eo b/src/lib/evas/gesture/efl_canvas_gesture_touch.eo index 0425aa7fdc..a12d26d3b9 100644 --- a/src/lib/evas/gesture/efl_canvas_gesture_touch.eo +++ b/src/lib/evas/gesture/efl_canvas_gesture_touch.eo @@ -66,6 +66,29 @@ class @beta Efl.Canvas.Gesture_Touch extends Efl.Object return : Efl.Canvas.Gesture_Touch_State; [[touch event state]] } } + @property cur_data { + [[This property holds the data struct of the most recent touch point.]] + get {} + values { + data: const(Efl.Canvas.Gesture_Touch_Point_Data) @by_ref; [[The current data.]] + } + } + @property prev_data { + [[This property holds the data struct of the second-most recent touch point. + If there is only one touch point active, it will return NULL. + ]] + get {} + values { + data: const(Efl.Canvas.Gesture_Touch_Point_Data) @by_ref; [[The previous touch point's data.]] + } + } + data_get @const { + [[This fetches the data for a specified touch point.]] + params { + @in id: uint; [[The id of the touch point to return.]] + } + return: const(Efl.Canvas.Gesture_Touch_Point_Data) @by_ref; [[The specified data if it exists.]] + } /* FIXME: finger_list was broken by design - TODO */ } implements { diff --git a/src/lib/evas/gesture/efl_canvas_gesture_types.eot b/src/lib/evas/gesture/efl_canvas_gesture_types.eot index 8cde6e18a0..600518b31c 100644 --- a/src/lib/evas/gesture/efl_canvas_gesture_types.eot +++ b/src/lib/evas/gesture/efl_canvas_gesture_types.eot @@ -1,3 +1,6 @@ +import eina_types; +import efl_input_types; + enum @beta Efl.Canvas.Gesture_Touch_State { [[ This enum type describes the state of a touch event. ]] @@ -44,3 +47,18 @@ enum @beta Efl.Canvas.Gesture_Recognizer_Type flick, zoom, } + +struct @beta @c_name(Efl_Gesture_Touch_Point_Info) Efl.Canvas.Gesture_Touch_Point_Info { + [[This struct represents the underlying data of a touch point.]] + pos: Eina.Position2D; [[The canvas position of the touch point data.]] + timestamp: uint; [[The timestamp of the touch point data.]] +} + +struct @beta @c_name(Efl_Gesture_Touch_Point_Data) Efl.Canvas.Gesture_Touch_Point_Data { + [[This struct represents the state of a touch point.]] + id: int; [[Touch id of the point.]] + action: Efl.Pointer.Action; [[The last event with this point.]] + start: Efl.Canvas.Gesture_Touch_Point_Info; [[The start data for the touch point.]] + prev: Efl.Canvas.Gesture_Touch_Point_Info; [[The previous data for the touch point.]] + cur: Efl.Canvas.Gesture_Touch_Point_Info; [[The current data for the touch point.]] +}