evas/gesture: Fix up a couple of APIs, add some FIXME

Some things have clearly not been tested. Some APIs have not been
modified after repeated review comments. C++ failed to build due to
"long" being used as a namespace.

Remaining issues:
 - The original finger_list API was broken by design. I didn't try to
   replace it yet.
 - Long tap is also broken by design: if no move happens the recognizer
   gets no event, and doesn't trigger anything when the timeout is
   reached. An API or event is lacking here.
 - Only 2 very basic gestures have been implemented. All the gestures
   from elm_gesture_layer need to be covered. None of the multi touch
   support has been really implemented, except for a single bool flag.
 - The configuration must be loaded from elm_config, passed on to the
   recognizers.
 - Some micro optimization may be required, especially if the input
   device is high frequency (eg. 1KHz gaming mouse).
This commit is contained in:
Jean-Philippe Andre 2017-10-19 11:05:28 +09:00
parent 20fad2e78e
commit 0a13e15c7d
19 changed files with 235 additions and 351 deletions

View File

@ -339,6 +339,7 @@ tests_evas_cxx_cxx_compile_test_SOURCES = tests/evas_cxx/cxx_compile_test.cc
tests_evas_cxx_cxx_compile_test_CPPFLAGS = -I$(top_builddir)/src/lib/efl \
-I$(top_builddir)/src/lib/efl/interfaces/ \
-I$(top_builddir)/src/lib/evas/canvas/ \
-I$(top_builddir)/src/lib/evas/gesture/ \
-I$(top_builddir)/src/lib/evas/include/ \
-DTESTS_SRC_DIR=\"$(top_srcdir)/src/tests/evas_cxx\" \
-DTESTS_BUILD_DIR=\"$(top_builddir)/src/tests/evas_cxx\" \

View File

@ -175,7 +175,7 @@ _color_and_icon_set(infra_data *infra, char *name, int n, int max,
static void
finger_tap_start(void *data , Efl_Gesture *tap)
{
Eina_Vector2 pos = efl_gesture_tap_position_get(tap);
Eina_Vector2 pos = efl_gesture_hotspot_get(tap);
_color_and_icon_set(data, TAP_NAME, 1, MAX_TAP, START_COLOR);
printf("Tap Gesture started x,y=<%f,%f> \n", pos.x, pos.y);
@ -190,7 +190,7 @@ finger_tap_update(void *data , Efl_Gesture *tap EINA_UNUSED)
static void
finger_tap_end(void *data , Efl_Gesture *tap)
{
Eina_Vector2 pos = efl_gesture_tap_position_get(tap);
Eina_Vector2 pos = efl_gesture_hotspot_get(tap);
_color_and_icon_set(data, TAP_NAME, 1, MAX_TAP, END_COLOR);
printf("Tap Gesture ended x,y=<%f,%f> \n", pos.x, pos.y);
@ -206,7 +206,7 @@ finger_tap_abort(void *data , Efl_Gesture *tap EINA_UNUSED)
static void
finger_long_tap_start(void *data , Efl_Gesture *tap)
{
Eina_Vector2 pos = efl_gesture_long_tap_position_get(tap);
Eina_Vector2 pos = efl_gesture_hotspot_get(tap);
_color_and_icon_set(data, LONG_TAP_NAME, 1, MAX_TAP, START_COLOR);
printf("Long Tap Gesture started x,y=<%f,%f> \n", pos.x, pos.y);
@ -222,7 +222,7 @@ finger_long_tap_update(void *data , Efl_Gesture *tap EINA_UNUSED)
static void
finger_long_tap_end(void *data , Efl_Gesture *tap)
{
Eina_Vector2 pos = efl_gesture_long_tap_position_get(tap);
Eina_Vector2 pos = efl_gesture_hotspot_get(tap);
_color_and_icon_set(data, LONG_TAP_NAME, 1, MAX_TAP, END_COLOR);
printf("Long Tap Gesture ended x,y=<%f,%f> \n",pos.x, pos.y);
@ -322,7 +322,7 @@ test_gesture_framework(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED,
infra_data *infra = _infra_data_alloc();
win = elm_win_util_standard_add("gesture-layer2", "Gesture Layer 2");
win = elm_win_util_standard_add("gesture-layer2", "Gesture (EO)");
elm_win_autodel_set(win, EINA_TRUE);
evas_object_smart_callback_add(win, "delete,request", my_win_del, infra);

View File

@ -32,4 +32,4 @@ abstract Efl.Gesture(Efl.Object)
}
}
}
}
}

View File

@ -3,19 +3,6 @@
#define MY_CLASS EFL_GESTURE_LONG_TAP_CLASS
EOLIAN static void
_efl_gesture_long_tap_position_set(Eo *obj EINA_UNUSED, Efl_Gesture_Long_Tap_Data *pd,
Eina_Vector2 pos)
{
pd->pos = pos;
}
EOLIAN static Eina_Vector2
_efl_gesture_long_tap_position_get(Eo *obj EINA_UNUSED, Efl_Gesture_Long_Tap_Data *pd)
{
return pd->pos;
}
EOLIAN static Efl_Object *
_efl_gesture_long_tap_efl_object_constructor(Eo *obj, Efl_Gesture_Long_Tap_Data *pd EINA_UNUSED)
{
@ -37,4 +24,4 @@ _efl_gesture_long_tap_efl_object_destructor(Eo *obj, Efl_Gesture_Long_Tap_Data *
efl_destructor(efl_super(obj, MY_CLASS));
}
#include "efl_gesture_long_tap.eo.c"
#include "efl_gesture_long_tap.eo.c"

View File

@ -1,26 +1,13 @@
import efl_gesture_types;
class Efl.Gesture.Long.Tap(Efl.Gesture)
class Efl.Gesture.Long_Tap (Efl.Gesture)
{
methods {
@property position {
[[This property holds the type of the gesture.]]
set {
}
get {
}
values {
pos: Eina.Vector2;[[position of the mouse event]]
}
}
}
event_prefix: efl;
events {
gesture_long_tap; [[Event for tap gesture]]
gesture,long_tap; [[Event for tap gesture]]
}
implements {
Efl.Object.constructor;
Efl.Object.destructor;
}
}
}

View File

@ -107,7 +107,6 @@ _efl_gesture_manager_callback_add_hook(Eo *obj, Eo *target, const Efl_Event_Desc
// add it to the gesture context.
eina_hash_list_append(pd->m_gesture_contex, &target, type);
}
}
void
@ -142,19 +141,15 @@ _efl_gesture_manager_filter_event(Eo *obj, Eo *target, void *event)
{
// get the touch event for this particular widget
touch_event = eina_hash_find(pd->m_object_events, &target);
if (touch_event)
{
efl_gesture_touch_point_record(touch_event, pointer_data->tool, pointer_data->cur.x, pointer_data->cur.y,
pointer_data->timestamp, pointer_data->action);
}
else
if (!touch_event)
{
touch_event = efl_add(EFL_GESTURE_TOUCH_CLASS, NULL);
efl_gesture_touch_point_record(touch_event, pointer_data->tool, pointer_data->cur.x, pointer_data->cur.y,
pointer_data->timestamp, pointer_data->action);
eina_hash_add(pd->m_object_events, &target, touch_event);
}
efl_gesture_touch_point_record(touch_event, pointer_data->tool, pointer_data->cur,
pointer_data->timestamp, pointer_data->action);
if (efl_gesture_touch_state_get(touch_event) == EFL_GESTURE_TOUCH_UNKNOWN)
return;

View File

@ -1,24 +1,22 @@
import efl_gesture_types;
class Efl.Gesture.Manager(Efl.Object)
class Efl.Gesture.Manager (Efl.Object)
{
methods {
recognizer_register {
[[This function is called to register a new Efl.Gesture.Recognizer]]
params {
@in recognizer: Efl.Gesture.Recognizer; [[The gesture recognizer object]]
}
return: ptr(const(Efl.Event.Description)); [[Returns the Efl.Event.Description type the recognizer supports]]
}
recognizer_unregister {
[[This function is called to unregister a Efl.Gesture.Recognizer ]]
[[This function is called to unregister a Efl.Gesture.Recognizer]]
params {
@in recognizer: Efl.Gesture.Recognizer; [[The gesture recognizer object]]
}
}
@property config{
@property config {
[[This property holds the config value for the recognizer]]
set {
}
@ -28,7 +26,7 @@ class Efl.Gesture.Manager(Efl.Object)
name: string; [[propery name]]
}
values {
value: ptr(any_value); [[value of the property]]
value: any_value_ptr; [[value of the property]]
}
}
}
@ -36,4 +34,4 @@ class Efl.Gesture.Manager(Efl.Object)
Efl.Object.constructor;
Efl.Object.destructor;
}
}
}

View File

@ -31,12 +31,10 @@ struct _Efl_Gesture_Data
struct _Efl_Gesture_Tap_Data
{
Eina_Vector2 pos;
};
struct _Efl_Gesture_Long_Tap_Data
{
Eina_Vector2 pos;
Ecore_Timer *timeout;
Eina_Bool is_timeout;
};

View File

@ -2,21 +2,17 @@
#define MY_CLASS EFL_GESTURE_RECOGNIZER_CLASS
EOLIAN static Eina_Value *
_efl_gesture_recognizer_config_get(Eo *obj EINA_UNUSED, Efl_Gesture_Recognizer_Data *pd, const char *name)
{
return efl_gesture_manager_config_get(pd->manager, name);
}
EOLIAN static void
_efl_gesture_recognizer_reset(Eo *obj EINA_UNUSED, Efl_Gesture_Recognizer_Data *pd EINA_UNUSED,
Efl_Gesture *gesture EINA_UNUSED)
Efl_Gesture *gesture EINA_UNUSED)
{
}
#include "efl_gesture_recognizer.eo.c"

View File

@ -1,35 +1,36 @@
import efl_gesture_types;
abstract Efl.Gesture.Recognizer(Efl.Object)
abstract Efl.Gesture.Recognizer (Efl.Object)
{
methods {
create @pure_virtual{
create @pure_virtual {
[[This function is called to create a new Efl.Gesture object for the given target]]
params {
@in target: Efl.Object; [[The target widget]]
}
return: Efl.Gesture; [[Returns the Efl.Gesture event object]]
}
recognize @pure_virtual{
[[Handles the given event for the watched object, updating the state of the gesture object as required, and returns a suitable result for the current recognition step.]]
recognize @pure_virtual {
[[Handles the given event for the watched object.
Updates the state of the gesture object as required, and returns a
suitable result for the current recognition step.
]]
params {
@in gesture: Efl.Gesture; [[The gesture object]]
@in watched: Efl.Object; [[The watched object]]
@in event: Efl.Gesture.Touch; [[The pointer event]]
}
return: Efl.Gesture.Recognizer.Result; [[Returns the Efl.Gesture event object]]
return: Efl.Gesture.Recognizer_Result; [[Returns the Efl.Gesture event object]]
}
/* FIXME: This function is not used? */
reset {
[[This function is called by the framework to reset a given gesture.]]
params {
@in gesture: Efl.Gesture; [[The gesture object]]
}
}
@property config{
@property config {
[[This property holds the config value for the recognizer]]
get {
}
@ -37,8 +38,8 @@ abstract Efl.Gesture.Recognizer(Efl.Object)
name: string; [[propery name]]
}
values {
value: ptr(any_value); [[value of the property]]
value: any_value_ptr; [[value of the property]]
}
}
}
}
}

View File

@ -4,26 +4,8 @@
#define LONG_TAP_TIME_OUT 0.2
typedef struct _Efl_Gesture_Recognizer_Long_Tap_Data
{
} Efl_Gesture_Recognizer_Long_Tap_Data;
EOLIAN static Efl_Object *
_efl_gesture_recognizer_long_tap_efl_object_constructor(Eo *obj, Efl_Gesture_Recognizer_Long_Tap_Data *pd EINA_UNUSED)
{
obj = efl_constructor(efl_super(obj, MY_CLASS));
return obj;
}
EOLIAN static void
_efl_gesture_recognizer_long_tap_efl_object_destructor(Eo *obj EINA_UNUSED, Efl_Gesture_Recognizer_Long_Tap_Data *pd EINA_UNUSED)
{
efl_destructor(efl_super(obj, MY_CLASS));
}
EOLIAN static Efl_Gesture *
_efl_gesture_recognizer_long_tap_efl_gesture_recognizer_create(Eo *obj, Efl_Gesture_Recognizer_Long_Tap_Data *pd EINA_UNUSED,
_efl_gesture_recognizer_long_tap_efl_gesture_recognizer_create(Eo *obj, void *pd EINA_UNUSED,
Efl_Object *target EINA_UNUSED)
{
return efl_add(EFL_GESTURE_LONG_TAP_CLASS, obj);
@ -34,96 +16,95 @@ _long_tap_timeout_cb(void *data)
{
Efl_Gesture_Long_Tap_Data *ltp = data;
/* FIXME: Needs to propagate this event back to evas! */
ltp->is_timeout = EINA_TRUE;
return ECORE_CALLBACK_RENEW;
}
EOLIAN static Efl_Gesture_Recognizer_Result
_efl_gesture_recognizer_long_tap_efl_gesture_recognizer_recognize(Eo *obj EINA_UNUSED,
Efl_Gesture_Recognizer_Long_Tap_Data *pd EINA_UNUSED,
Efl_Gesture *gesture, Efl_Object *watched EINA_UNUSED,
Efl_Gesture_Touch *event)
void *pd EINA_UNUSED,
Efl_Gesture *gesture, Efl_Object *watched EINA_UNUSED,
Efl_Gesture_Touch *event)
{
double dist_x, dist_y, length, x, y;
Eina_Vector2 pos;
Efl_Gesture_Recognizer_Result result = EFL_GESTURE_CANCEL;
Efl_Gesture_Long_Tap_Data *ltp = efl_data_scope_get(gesture, EFL_GESTURE_LONG_TAP_CLASS);
double length; // Manhattan distance
Eina_Vector2 pos, dist;
Efl_Gesture_Recognizer_Result result = EFL_GESTURE_CANCEL;
Efl_Gesture_Long_Tap_Data *ltp = efl_data_scope_get(gesture, EFL_GESTURE_LONG_TAP_CLASS);
switch (efl_gesture_touch_state_get(event))
{
case EFL_GESTURE_TOUCH_BEGIN:
{
efl_gesture_touch_start_point(event, &x, &y);
eina_vector2_set(&pos, x, y);
efl_gesture_long_tap_position_set(gesture, pos);
efl_gesture_hotspot_set(gesture, pos);
if (ltp->timeout)
ecore_timer_del(ltp->timeout);
ltp->timeout = ecore_timer_add(LONG_TAP_TIME_OUT,
_long_tap_timeout_cb, ltp);
result = EFL_GESTURE_MAYBE;
break;
}
case EFL_GESTURE_TOUCH_UPDATE:
{
if (!efl_gesture_touch_multi_touch_get(event))
{
efl_gesture_touch_distance(event, 0, &dist_x, &dist_y);
length = abs(dist_x) + abs(dist_y);
if (length <= 50)
{
if (ltp->is_timeout)
{
ltp->is_timeout = EINA_FALSE;
result = EFL_GESTURE_TRIGGER;
}
else
{
result = EFL_GESTURE_MAYBE;
}
}
else
{
result = EFL_GESTURE_CANCEL;
}
}
break;
}
case EFL_GESTURE_TOUCH_END:
{
if (ltp->timeout)
ecore_timer_del(ltp->timeout);
ltp->timeout = NULL;
if (efl_gesture_state_get(gesture) != EFL_GESTURE_NONE &&
!efl_gesture_touch_multi_touch_get(event))
{
efl_gesture_touch_distance(event, 0, &dist_x, &dist_y);
length = abs(dist_x) + abs(dist_y);
if (length <= 50 && ltp->is_timeout)
{
result = EFL_GESTURE_FINISH;
}
else
{
result = EFL_GESTURE_CANCEL;
}
}
break;
}
default:
break;
}
switch (efl_gesture_touch_state_get(event))
{
case EFL_GESTURE_TOUCH_BEGIN:
{
pos = efl_gesture_touch_start_point_get(event);
efl_gesture_hotspot_set(gesture, pos);
if (ltp->timeout)
ecore_timer_del(ltp->timeout);
ltp->timeout = ecore_timer_add(LONG_TAP_TIME_OUT,
_long_tap_timeout_cb, ltp);
result = EFL_GESTURE_MAYBE;
break;
}
case EFL_GESTURE_TOUCH_UPDATE:
{
if (!efl_gesture_touch_multi_touch_get(event))
{
dist = efl_gesture_touch_distance(event, 0);
length = fabs(dist.x) + fabs(dist.y);
if (length <= 50) // FIXME config!
{
if (ltp->is_timeout)
{
ltp->is_timeout = EINA_FALSE;
result = EFL_GESTURE_TRIGGER;
}
else
{
result = EFL_GESTURE_MAYBE;
}
}
else
{
result = EFL_GESTURE_CANCEL;
}
}
break;
}
case EFL_GESTURE_TOUCH_END:
{
if (ltp->timeout)
ecore_timer_del(ltp->timeout);
ltp->timeout = NULL;
if (efl_gesture_state_get(gesture) != EFL_GESTURE_NONE &&
!efl_gesture_touch_multi_touch_get(event))
{
dist = efl_gesture_touch_distance(event, 0);
length = fabs(dist.x) + fabs(dist.y);
if (length <= 50 && ltp->is_timeout) // FIXME config!
{
result = EFL_GESTURE_FINISH;
}
else
{
result = EFL_GESTURE_CANCEL;
}
}
break;
}
default:
break;
}
return result;
}
EOLIAN static void
_efl_gesture_recognizer_long_tap_efl_gesture_recognizer_reset(Eo *obj,
Efl_Gesture_Recognizer_Long_Tap_Data *pd EINA_UNUSED,
void *pd EINA_UNUSED,
Efl_Gesture *gesture)
{
Efl_Gesture_Long_Tap_Data *ltp;
ltp = efl_data_scope_get(gesture, EFL_GESTURE_LONG_TAP_CLASS);
eina_vector2_set(&ltp->pos, 0, 0);
if (ltp->timeout)
ecore_timer_del(ltp->timeout);
ltp->timeout = NULL;
@ -131,4 +112,4 @@ _efl_gesture_recognizer_long_tap_efl_gesture_recognizer_reset(Eo *obj,
efl_gesture_recognizer_reset(efl_super(obj, MY_CLASS), gesture);
}
#include "efl_gesture_recognizer_long_tap.eo.c"
#include "efl_gesture_recognizer_long_tap.eo.c"

View File

@ -1,10 +1,9 @@
class Efl.Gesture.Recognizer.Long.Tap(Efl.Gesture.Recognizer)
class Efl.Gesture.Recognizer_Long_Tap (Efl.Gesture.Recognizer)
{
data: null;
implements {
Efl.Object.constructor;
Efl.Object.destructor;
Efl.Gesture.Recognizer.create;
Efl.Gesture.Recognizer.recognize;
Efl.Gesture.Recognizer.reset;
}
}
}

View File

@ -2,26 +2,8 @@
#define MY_CLASS EFL_GESTURE_RECOGNIZER_TAP_CLASS
typedef struct _Efl_Gesture_Recognizer_Tap_Data
{
} Efl_Gesture_Recognizer_Tap_Data;
EOLIAN static Efl_Object *
_efl_gesture_recognizer_tap_efl_object_constructor(Eo *obj, Efl_Gesture_Recognizer_Tap_Data *pd EINA_UNUSED)
{
obj = efl_constructor(efl_super(obj, MY_CLASS));
return obj;
}
EOLIAN static void
_efl_gesture_recognizer_tap_efl_object_destructor(Eo *obj EINA_UNUSED, Efl_Gesture_Recognizer_Tap_Data *pd EINA_UNUSED)
{
efl_destructor(efl_super(obj, MY_CLASS));
}
EOLIAN static Efl_Gesture *
_efl_gesture_recognizer_tap_efl_gesture_recognizer_create(Eo *obj, Efl_Gesture_Recognizer_Tap_Data *pd EINA_UNUSED,
_efl_gesture_recognizer_tap_efl_gesture_recognizer_create(Eo *obj, void *pd EINA_UNUSED,
Efl_Object *target EINA_UNUSED)
{
return efl_add(EFL_GESTURE_TAP_CLASS, obj);
@ -29,58 +11,45 @@ _efl_gesture_recognizer_tap_efl_gesture_recognizer_create(Eo *obj, Efl_Gesture_R
EOLIAN static Efl_Gesture_Recognizer_Result
_efl_gesture_recognizer_tap_efl_gesture_recognizer_recognize(Eo *obj EINA_UNUSED,
Efl_Gesture_Recognizer_Tap_Data *pd EINA_UNUSED,
Efl_Gesture *gesture, Efl_Object *watched EINA_UNUSED,
Efl_Gesture_Touch *event EINA_UNUSED)
void *pd EINA_UNUSED,
Efl_Gesture *gesture, Efl_Object *watched EINA_UNUSED,
Efl_Gesture_Touch *event EINA_UNUSED)
{
double dist_x, dist_y, length, x, y;
Eina_Vector2 pos;
Efl_Gesture_Recognizer_Result result = EFL_GESTURE_CANCEL;
double length;
Eina_Vector2 pos, dist;
Efl_Gesture_Recognizer_Result result = EFL_GESTURE_CANCEL;
switch (efl_gesture_touch_state_get(event))
{
case EFL_GESTURE_TOUCH_BEGIN:
{
efl_gesture_touch_start_point(event, &x, &y);
eina_vector2_set(&pos, x, y);
efl_gesture_tap_position_set(gesture, pos);
efl_gesture_hotspot_set(gesture, pos);
result = EFL_GESTURE_TRIGGER;
break;
}
case EFL_GESTURE_TOUCH_UPDATE:
case EFL_GESTURE_TOUCH_END:
{
if (efl_gesture_state_get(gesture) != EFL_GESTURE_NONE &&
!efl_gesture_touch_multi_touch_get(event))
{
efl_gesture_touch_distance(event, 0, &dist_x, &dist_y);
length = abs(dist_x) + abs(dist_y);
if (length <= 50)
{
if (efl_gesture_touch_state_get(event) == EFL_GESTURE_TOUCH_END)
result = EFL_GESTURE_FINISH;
else
result = EFL_GESTURE_TRIGGER;
}
}
break;
}
default:
break;
}
switch (efl_gesture_touch_state_get(event))
{
case EFL_GESTURE_TOUCH_BEGIN:
{
pos = efl_gesture_touch_start_point_get(event);
efl_gesture_hotspot_set(gesture, pos);
result = EFL_GESTURE_TRIGGER;
break;
}
case EFL_GESTURE_TOUCH_UPDATE:
case EFL_GESTURE_TOUCH_END:
{
if (efl_gesture_state_get(gesture) != EFL_GESTURE_NONE &&
!efl_gesture_touch_multi_touch_get(event))
{
dist = efl_gesture_touch_distance(event, 0);
length = fabs(dist.x) + fabs(dist.y);
if (length <= 50) // FIXME config!
{
if (efl_gesture_touch_state_get(event) == EFL_GESTURE_TOUCH_END)
result = EFL_GESTURE_FINISH;
else
result = EFL_GESTURE_TRIGGER;
}
}
break;
}
default:
break;
}
return result;
}
EOLIAN static void
_efl_gesture_recognizer_tap_efl_gesture_recognizer_reset(Eo *obj,
Efl_Gesture_Recognizer_Tap_Data *pd EINA_UNUSED,
Efl_Gesture *gesture)
{
Efl_Gesture_Tap_Data *tap;
tap = efl_data_scope_get(gesture, EFL_GESTURE_TAP_CLASS);
eina_vector2_set(&tap->pos, 0, 0);
efl_gesture_recognizer_reset(efl_super(obj, MY_CLASS), gesture);
}
#include "efl_gesture_recognizer_tap.eo.c"
#include "efl_gesture_recognizer_tap.eo.c"

View File

@ -1,10 +1,8 @@
class Efl.Gesture.Recognizer.Tap(Efl.Gesture.Recognizer)
class Efl.Gesture.Recognizer_Tap (Efl.Gesture.Recognizer)
{
data: null;
implements {
Efl.Object.constructor;
Efl.Object.destructor;
Efl.Gesture.Recognizer.create;
Efl.Gesture.Recognizer.recognize;
Efl.Gesture.Recognizer.reset;
}
}
}

View File

@ -3,18 +3,6 @@
#define MY_CLASS EFL_GESTURE_TAP_CLASS
EOLIAN static void
_efl_gesture_tap_position_set(Eo *obj EINA_UNUSED, Efl_Gesture_Tap_Data *pd, Eina_Vector2 pos)
{
pd->pos = pos;
}
EOLIAN static Eina_Vector2
_efl_gesture_tap_position_get(Eo *obj EINA_UNUSED, Efl_Gesture_Tap_Data *pd)
{
return pd->pos;
}
EOLIAN static Efl_Object *
_efl_gesture_tap_efl_object_constructor(Eo *obj, Efl_Gesture_Tap_Data *pd EINA_UNUSED)
{
@ -28,4 +16,4 @@ _efl_gesture_tap_efl_object_constructor(Eo *obj, Efl_Gesture_Tap_Data *pd EINA_U
return obj;
}
#include "efl_gesture_tap.eo.c"
#include "efl_gesture_tap.eo.c"

View File

@ -2,24 +2,11 @@ import efl_gesture_types;
class Efl.Gesture.Tap(Efl.Gesture)
{
methods {
@property position {
[[This property holds the type of the gesture.]]
set {
}
get {
}
values {
pos: Eina.Vector2;[[position of the mouse event]]
}
}
}
event_prefix: efl;
events {
gesture,tap; [[Event for tap gesture]]
}
implements {
Efl.Object.constructor;
}
}
}

View File

@ -5,19 +5,18 @@
typedef struct _Pointer_Data
{
struct
{
double x;
double y;
double timestamp;
} start, prev, cur ;
{
Eina_Vector2 pos;
double timestamp;
} start, prev, cur;
Efl_Pointer_Action action;
}Pointer_Data;
} Pointer_Data;
typedef struct _Efl_Gesture_Touch_Data
{
Efl_Gesture_Touch_State type;
Efl_Gesture_Touch_State state;
Eina_Hash *touch_points;
Eina_List *finger_list;
int touch_down;
Eina_Bool multi_touch;
Eo *target;
} Efl_Gesture_Touch_Data;
@ -32,12 +31,20 @@ static void _hash_free_cb(Pointer_Data *point)
free(point);
}
static inline void
_touch_points_reset(Efl_Gesture_Touch_Data *pd)
{
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;
}
EOLIAN static Efl_Object *
_efl_gesture_touch_efl_object_constructor(Eo *obj, Efl_Gesture_Touch_Data *pd)
{
obj = efl_constructor(efl_super(obj, MY_CLASS));
pd->touch_points = eina_hash_int32_new(EINA_FREE_CB(_hash_free_cb));
_touch_points_reset(pd);
return obj;
}
@ -51,23 +58,28 @@ _efl_gesture_touch_efl_object_destructor(Eo *obj, Efl_Gesture_Touch_Data *pd)
EOLIAN static Efl_Gesture_Touch_State
_efl_gesture_touch_state_get(Eo *obj EINA_UNUSED, Efl_Gesture_Touch_Data *pd)
{
return pd->type;
return pd->state;
}
EOLIAN static void
_efl_gesture_touch_point_record(Eo *obj EINA_UNUSED, Efl_Gesture_Touch_Data *pd,
int id, double x, double y, double timestamp, Efl_Pointer_Action action)
int id, Eina_Vector2 pos, double timestamp, Efl_Pointer_Action action)
{
Pointer_Data *point = eina_hash_find(pd->touch_points, &id);
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);
if (point)
{
// the point already exists. update the cur and prev point
point->prev.x = point->cur.x;
point->prev.y = point->cur.y;
point->prev.timestamp = point->cur.timestamp;
point->cur.x = x;
point->cur.y = y;
point->cur.timestamp = timestamp;
// the point already exists. update the cur and prev point
point->prev = point->cur;
point->cur.pos = pos;
point->cur.timestamp = timestamp;
}
else
{
@ -78,13 +90,13 @@ _efl_gesture_touch_point_record(Eo *obj EINA_UNUSED, Efl_Gesture_Touch_Data *pd,
return;
}
point = calloc(1, sizeof(Pointer_Data));
point->start.x = point->prev.x = point->cur.x = x;
point->start.y = point->prev.y = point->cur.y = y;
if (!point) return;
point->start.pos = point->prev.pos = point->cur.pos = pos;
point->start.timestamp = point->prev.timestamp = point->cur.timestamp = timestamp;
// add to the hash
eina_hash_add(pd->touch_points, &id, point);
pd->finger_list = eina_list_append(pd->finger_list, &id);
// FIXME: finger_list was broken
if (id)
pd->multi_touch = EINA_TRUE;
}
@ -92,17 +104,21 @@ _efl_gesture_touch_point_record(Eo *obj EINA_UNUSED, Efl_Gesture_Touch_Data *pd,
if (!id && (action == EFL_POINTER_ACTION_DOWN))
{
pd->type = EFL_GESTURE_TOUCH_BEGIN;
pd->state = EFL_GESTURE_TOUCH_BEGIN;
}
else if ((action == EFL_POINTER_ACTION_UP) && (eina_list_count(pd->finger_list) == 1))
else if ((action == EFL_POINTER_ACTION_UP) && (pd->touch_down == 0))
{
pd->type = EFL_GESTURE_TOUCH_END;
pd->state = EFL_GESTURE_TOUCH_END;
}
else
{
pd->type = EFL_GESTURE_TOUCH_UPDATE;
pd->state = EFL_GESTURE_TOUCH_UPDATE;
}
return;
bad_fingers:
ERR("Inconsistent touch events received!");
_touch_points_reset(pd);
}
EOLIAN static Eina_Bool
@ -111,56 +127,43 @@ _efl_gesture_touch_multi_touch_get(Eo *obj EINA_UNUSED, Efl_Gesture_Touch_Data *
return pd->multi_touch;
}
EOLIAN static void
_efl_gesture_touch_start_point(Eo *obj EINA_UNUSED, Efl_Gesture_Touch_Data *pd, double *x, double *y)
EOLIAN static Eina_Vector2
_efl_gesture_touch_start_point_get(Eo *obj EINA_UNUSED, Efl_Gesture_Touch_Data *pd)
{
int tool = 0;
Pointer_Data *point = eina_hash_find(pd->touch_points, &tool);
Eina_Vector2 vec = { 0, 0 };
*x = 0;
*y = 0;
if (!point)
return vec;
if (point)
{
*x = point->start.x;
*y = point->start.y;
}
return point->start.pos;
}
EOLIAN static void
_efl_gesture_touch_delta(Eo *obj EINA_UNUSED, Efl_Gesture_Touch_Data *pd, int tool, double *x, double *y)
EOLIAN static Eina_Vector2
_efl_gesture_touch_delta(const Eo *obj EINA_UNUSED, Efl_Gesture_Touch_Data *pd, int tool)
{
Pointer_Data *point = eina_hash_find(pd->touch_points, &tool);
Eina_Vector2 vec = { 0, 0 };
*x = 0;
*y = 0;
if (!point)
return vec;
if (point)
{
*x = point->cur.x - point->prev.x;
*y = point->cur.y - point->prev.y;
}
eina_vector2_subtract(&vec, &point->cur.pos, &point->prev.pos);
return vec;
}
EOLIAN static void
_efl_gesture_touch_distance(Eo *obj EINA_UNUSED, Efl_Gesture_Touch_Data *pd, int tool, double *x, double *y)
EOLIAN static Eina_Vector2
_efl_gesture_touch_distance(const Eo *obj EINA_UNUSED, Efl_Gesture_Touch_Data *pd, int tool)
{
Pointer_Data *point = eina_hash_find(pd->touch_points, &tool);
Eina_Vector2 vec = { 0, 0 };
*x = 0;
*y = 0;
if (!point)
return vec;
if (point)
{
*x = point->cur.x - point->start.x;
*y = point->cur.y - point->start.y;
}
eina_vector2_subtract(&vec, &point->cur.pos, &point->start.pos);
return vec;
}
EOLIAN static const Eina_List *
_efl_gesture_touch_finger_list_get(Eo *obj EINA_UNUSED, Efl_Gesture_Touch_Data *pd)
{
return pd->finger_list;
}
#include "efl_gesture_touch.eo.c"
#include "efl_gesture_touch.eo.c"

View File

@ -1,36 +1,39 @@
import efl_gesture_types;
import efl_input_types;
/* FIXME: This class lacks a lot of useful helpers. */
class Efl.Gesture.Touch(Efl.Object)
{
methods {
point_record {
params {
@in tool : int; [[The finger id ]]
@in x : double; [[The x co-ordinate of the event]]
@in y : double; [[The y co-ordinate of the event]]
@in pos : Eina.Vector2; [[Position of the event]]
@in timestamp : double; [[The timestamp of the event]]
@in action : Efl.Pointer.Action; [[action of the event]]
}
}
delta {
/* FIXME: This is most likely not useful (without timestamps). */
delta @const {
[[Compute the distance between the last two events]]
params {
@in tool : int; [[The finger id ]]
@out x : double; [[The x co-ordinate of the event]]
@out y : double; [[The y co-ordinate of the event]]
}
return: Eina.Vector2; [[The distance vector.]]
}
distance {
distance @const {
[[Compute the distance between the first touch and the last event.]]
params {
@in tool : int; [[The finger id ]]
@out x : double; [[The x co-ordinate of the event]]
@out y : double; [[The y co-ordinate of the event]]
}
return: Eina.Vector2; [[The distance vector.]]
}
start_point {
params {
@out x : double; [[The x co-ordinate of the event]]
@out y : double; [[The y co-ordinate of the event]]
@property start_point {
[[Returns the first touch point.]]
get {}
values {
pos: Eina.Vector2; [[The start position.]]
}
}
@property multi_touch {
@ -45,17 +48,10 @@ class Efl.Gesture.Touch(Efl.Object)
return : Efl.Gesture.Touch.State; [[touch event state]]
}
}
@property finger_list {
get {
[[Get the list of finger id .]]
}
values {
ret: const(list<int>); [[List of finger id]]
}
}
/* FIXME: finger_list was broken by design - TODO */
}
implements {
Efl.Object.constructor;
Efl.Object.destructor;
}
}
}

View File

@ -19,7 +19,7 @@ enum Efl.Gesture.State
canceled, [[A gesture was canceled.]]
}
enum Efl.Gesture.Recognizer.Result
enum Efl.Gesture.Recognizer_Result
{
[[ This enum type describes the state of a gesture recognizer. ]]
legacy: efl_gesture;
@ -30,4 +30,4 @@ enum Efl.Gesture.Recognizer.Result
finish = 0x0008, [[The gesture has been finished successfully.]]
cancel = 0x0010, [[The event made it clear that it is not a gesture. If the gesture recognizer was in Triggered state before, then the gesture is canceled.]]
result_mask = 0x00ff,
}
}