2018-02-21 11:20:09 -08:00
|
|
|
#include "efl_canvas_gesture_private.h"
|
2017-09-19 00:55:45 -07:00
|
|
|
|
2018-02-21 11:20:09 -08:00
|
|
|
#define MY_CLASS EFL_CANVAS_GESTURE_TOUCH_CLASS
|
2017-09-19 00:55:45 -07:00
|
|
|
|
|
|
|
typedef struct _Pointer_Data
|
|
|
|
{
|
|
|
|
struct
|
2017-10-18 19:05:28 -07:00
|
|
|
{
|
|
|
|
Eina_Vector2 pos;
|
|
|
|
double timestamp;
|
|
|
|
} start, prev, cur;
|
2017-09-19 00:55:45 -07:00
|
|
|
Efl_Pointer_Action action;
|
2017-10-18 19:05:28 -07:00
|
|
|
} Pointer_Data;
|
2017-09-19 00:55:45 -07:00
|
|
|
|
2018-02-21 11:20:09 -08:00
|
|
|
typedef struct _Efl_Canvas_Gesture_Touch_Data
|
2017-09-19 00:55:45 -07:00
|
|
|
{
|
2018-02-21 11:20:09 -08:00
|
|
|
Efl_Canvas_Gesture_Touch_State state;
|
2017-09-19 00:55:45 -07:00
|
|
|
Eina_Hash *touch_points;
|
2017-10-18 19:05:28 -07:00
|
|
|
int touch_down;
|
2017-09-19 00:55:45 -07:00
|
|
|
Eina_Bool multi_touch;
|
|
|
|
Eo *target;
|
2018-02-21 11:20:09 -08:00
|
|
|
} Efl_Canvas_Gesture_Touch_Data;
|
2017-09-19 00:55:45 -07:00
|
|
|
|
|
|
|
|
|
|
|
// This event object accumulates all the touch points
|
|
|
|
// 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);
|
|
|
|
}
|
|
|
|
|
2017-10-18 19:05:28 -07:00
|
|
|
static inline void
|
2018-02-21 11:20:09 -08:00
|
|
|
_touch_points_reset(Efl_Canvas_Gesture_Touch_Data *pd)
|
2017-10-18 19:05:28 -07:00
|
|
|
{
|
|
|
|
eina_hash_free(pd->touch_points);
|
|
|
|
pd->touch_points = eina_hash_int32_new(EINA_FREE_CB(_hash_free_cb));
|
|
|
|
pd->touch_down = 0;
|
|
|
|
pd->state = EFL_GESTURE_TOUCH_UNKNOWN;
|
|
|
|
}
|
|
|
|
|
2017-09-19 00:55:45 -07:00
|
|
|
EOLIAN static Efl_Object *
|
2018-02-21 11:20:09 -08:00
|
|
|
_efl_canvas_gesture_touch_efl_object_constructor(Eo *obj, Efl_Canvas_Gesture_Touch_Data *pd)
|
2017-09-19 00:55:45 -07:00
|
|
|
{
|
|
|
|
obj = efl_constructor(efl_super(obj, MY_CLASS));
|
2017-10-18 19:05:28 -07:00
|
|
|
_touch_points_reset(pd);
|
2017-09-19 00:55:45 -07:00
|
|
|
return obj;
|
|
|
|
}
|
|
|
|
|
|
|
|
EOLIAN static void
|
2018-02-21 11:20:09 -08:00
|
|
|
_efl_canvas_gesture_touch_efl_object_destructor(Eo *obj, Efl_Canvas_Gesture_Touch_Data *pd)
|
2017-09-19 00:55:45 -07:00
|
|
|
{
|
|
|
|
eina_hash_free(pd->touch_points);
|
|
|
|
efl_destructor(efl_super(obj, MY_CLASS));
|
|
|
|
}
|
|
|
|
|
2018-02-21 11:20:09 -08:00
|
|
|
EOLIAN static Efl_Canvas_Gesture_Touch_State
|
|
|
|
_efl_canvas_gesture_touch_state_get(Eo *obj EINA_UNUSED, Efl_Canvas_Gesture_Touch_Data *pd)
|
2017-09-19 00:55:45 -07:00
|
|
|
{
|
2017-10-18 19:05:28 -07:00
|
|
|
return pd->state;
|
2017-09-19 00:55:45 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
EOLIAN static void
|
2018-02-21 11:20:09 -08:00
|
|
|
_efl_canvas_gesture_touch_point_record(Eo *obj EINA_UNUSED, Efl_Canvas_Gesture_Touch_Data *pd,
|
2017-10-18 19:05:28 -07:00
|
|
|
int id, Eina_Vector2 pos, double timestamp, Efl_Pointer_Action action)
|
2017-09-19 00:55:45 -07:00
|
|
|
{
|
|
|
|
Pointer_Data *point = eina_hash_find(pd->touch_points, &id);
|
2017-10-18 19:05:28 -07:00
|
|
|
|
|
|
|
if (action == EFL_POINTER_ACTION_DOWN)
|
|
|
|
pd->touch_down++;
|
|
|
|
else if ((action == EFL_POINTER_ACTION_UP) ||
|
|
|
|
(action == EFL_POINTER_ACTION_CANCEL))
|
|
|
|
pd->touch_down--;
|
|
|
|
EINA_SAFETY_ON_FALSE_GOTO(pd->touch_down >= 0, bad_fingers);
|
|
|
|
|
2017-09-19 00:55:45 -07:00
|
|
|
if (point)
|
|
|
|
{
|
2017-10-18 19:05:28 -07:00
|
|
|
// the point already exists. update the cur and prev point
|
|
|
|
point->prev = point->cur;
|
|
|
|
point->cur.pos = pos;
|
|
|
|
point->cur.timestamp = timestamp;
|
2017-09-19 00:55:45 -07:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// new finger
|
|
|
|
if (!id && (action != EFL_POINTER_ACTION_DOWN))
|
|
|
|
{
|
|
|
|
// discard any other event
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
point = calloc(1, sizeof(Pointer_Data));
|
2017-10-18 19:05:28 -07:00
|
|
|
if (!point) return;
|
|
|
|
point->start.pos = point->prev.pos = point->cur.pos = pos;
|
2017-09-19 00:55:45 -07:00
|
|
|
point->start.timestamp = point->prev.timestamp = point->cur.timestamp = timestamp;
|
|
|
|
|
|
|
|
// add to the hash
|
|
|
|
eina_hash_add(pd->touch_points, &id, point);
|
2017-10-18 19:05:28 -07:00
|
|
|
// FIXME: finger_list was broken
|
2017-09-19 00:55:45 -07:00
|
|
|
if (id)
|
|
|
|
pd->multi_touch = EINA_TRUE;
|
|
|
|
}
|
|
|
|
point->action = action;
|
|
|
|
|
|
|
|
if (!id && (action == EFL_POINTER_ACTION_DOWN))
|
|
|
|
{
|
2017-10-18 19:05:28 -07:00
|
|
|
pd->state = EFL_GESTURE_TOUCH_BEGIN;
|
2017-09-19 00:55:45 -07:00
|
|
|
}
|
2017-10-18 19:05:28 -07:00
|
|
|
else if ((action == EFL_POINTER_ACTION_UP) && (pd->touch_down == 0))
|
2017-09-19 00:55:45 -07:00
|
|
|
{
|
2017-10-18 19:05:28 -07:00
|
|
|
pd->state = EFL_GESTURE_TOUCH_END;
|
2017-09-19 00:55:45 -07:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2017-10-18 19:05:28 -07:00
|
|
|
pd->state = EFL_GESTURE_TOUCH_UPDATE;
|
2017-09-19 00:55:45 -07:00
|
|
|
}
|
2017-10-18 19:05:28 -07:00
|
|
|
return;
|
2017-09-19 00:55:45 -07:00
|
|
|
|
2017-10-18 19:05:28 -07:00
|
|
|
bad_fingers:
|
|
|
|
ERR("Inconsistent touch events received!");
|
|
|
|
_touch_points_reset(pd);
|
2017-09-19 00:55:45 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
EOLIAN static Eina_Bool
|
2018-02-21 11:20:09 -08:00
|
|
|
_efl_canvas_gesture_touch_multi_touch_get(Eo *obj EINA_UNUSED, Efl_Canvas_Gesture_Touch_Data *pd)
|
2017-09-19 00:55:45 -07:00
|
|
|
{
|
|
|
|
return pd->multi_touch;
|
|
|
|
}
|
|
|
|
|
2017-10-18 19:05:28 -07:00
|
|
|
EOLIAN static Eina_Vector2
|
2018-02-21 11:20:09 -08:00
|
|
|
_efl_canvas_gesture_touch_start_point_get(Eo *obj EINA_UNUSED, Efl_Canvas_Gesture_Touch_Data *pd)
|
2017-09-19 00:55:45 -07:00
|
|
|
{
|
|
|
|
int tool = 0;
|
|
|
|
Pointer_Data *point = eina_hash_find(pd->touch_points, &tool);
|
2017-10-18 19:05:28 -07:00
|
|
|
Eina_Vector2 vec = { 0, 0 };
|
2017-09-19 00:55:45 -07:00
|
|
|
|
2017-10-18 19:05:28 -07:00
|
|
|
if (!point)
|
|
|
|
return vec;
|
2017-09-19 00:55:45 -07:00
|
|
|
|
2017-10-18 19:05:28 -07:00
|
|
|
return point->start.pos;
|
2017-09-19 00:55:45 -07:00
|
|
|
}
|
|
|
|
|
2017-10-18 19:05:28 -07:00
|
|
|
EOLIAN static Eina_Vector2
|
2018-02-21 11:20:09 -08:00
|
|
|
_efl_canvas_gesture_touch_delta(const Eo *obj EINA_UNUSED, Efl_Canvas_Gesture_Touch_Data *pd, int tool)
|
2017-09-19 00:55:45 -07:00
|
|
|
{
|
|
|
|
Pointer_Data *point = eina_hash_find(pd->touch_points, &tool);
|
2017-10-18 19:05:28 -07:00
|
|
|
Eina_Vector2 vec = { 0, 0 };
|
2017-09-19 00:55:45 -07:00
|
|
|
|
2017-10-18 19:05:28 -07:00
|
|
|
if (!point)
|
|
|
|
return vec;
|
2017-09-19 00:55:45 -07:00
|
|
|
|
2017-10-18 19:05:28 -07:00
|
|
|
eina_vector2_subtract(&vec, &point->cur.pos, &point->prev.pos);
|
|
|
|
return vec;
|
2017-09-19 00:55:45 -07:00
|
|
|
}
|
|
|
|
|
2017-10-18 19:05:28 -07:00
|
|
|
EOLIAN static Eina_Vector2
|
2018-02-21 11:20:09 -08:00
|
|
|
_efl_canvas_gesture_touch_distance(const Eo *obj EINA_UNUSED, Efl_Canvas_Gesture_Touch_Data *pd, int tool)
|
2017-09-19 00:55:45 -07:00
|
|
|
{
|
|
|
|
Pointer_Data *point = eina_hash_find(pd->touch_points, &tool);
|
2017-10-18 19:05:28 -07:00
|
|
|
Eina_Vector2 vec = { 0, 0 };
|
2017-09-19 00:55:45 -07:00
|
|
|
|
2017-10-18 19:05:28 -07:00
|
|
|
if (!point)
|
|
|
|
return vec;
|
2017-09-19 00:55:45 -07:00
|
|
|
|
2017-10-18 19:05:28 -07:00
|
|
|
eina_vector2_subtract(&vec, &point->cur.pos, &point->start.pos);
|
|
|
|
return vec;
|
2017-09-19 00:55:45 -07:00
|
|
|
}
|
|
|
|
|
2018-02-21 11:20:09 -08:00
|
|
|
#include "efl_canvas_gesture_touch.eo.c"
|