forked from enlightenment/efl
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:
parent
20fad2e78e
commit
0a13e15c7d
|
@ -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\" \
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -32,4 +32,4 @@ abstract Efl.Gesture(Efl.Object)
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -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"
|
||||
|
||||
|
||||
|
|
|
@ -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]]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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(<p->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"
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue