summaryrefslogtreecommitdiff
path: root/src/lib/evas/gesture/efl_canvas_gesture_recognizer_flick.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/evas/gesture/efl_canvas_gesture_recognizer_flick.c')
-rw-r--r--src/lib/evas/gesture/efl_canvas_gesture_recognizer_flick.c325
1 files changed, 161 insertions, 164 deletions
diff --git a/src/lib/evas/gesture/efl_canvas_gesture_recognizer_flick.c b/src/lib/evas/gesture/efl_canvas_gesture_recognizer_flick.c
index 4968c61b34..962ed3ddda 100644
--- a/src/lib/evas/gesture/efl_canvas_gesture_recognizer_flick.c
+++ b/src/lib/evas/gesture/efl_canvas_gesture_recognizer_flick.c
@@ -1,19 +1,30 @@
#include "efl_canvas_gesture_private.h"
-#define MY_CLASS EFL_CANVAS_GESTURE_RECOGNIZER_FLICK_CLASS
+#define MY_CLASS EFL_CANVAS_GESTURE_RECOGNIZER_FLICK_CLASS
-#define MOMENTUM_TIMEOUT 50
-#define THUMBSCROLL_FRICTION 0.95
+#define MOMENTUM_TIMEOUT 50
+#define THUMBSCROLL_FRICTION 0.95
#define THUMBSCROLL_MOMENTUM_THRESHOLD 100.0
-#define EFL_GESTURE_MINIMUM_MOMENTUM 0.001
+#define EFL_GESTURE_MINIMUM_MOMENTUM 0.001
-#define RAD2DEG(x) ((x) * 57.295779513)
#define DEG2RAD(x) ((x) / 57.295779513)
-EOLIAN static Efl_Canvas_Gesture *
-_efl_canvas_gesture_recognizer_flick_efl_canvas_gesture_recognizer_add(Eo *obj, Efl_Canvas_Gesture_Recognizer_Flick_Data *pd EINA_UNUSED, Efl_Object *target EINA_UNUSED)
+#define memset do not use memset to reset flick data, use _reset_recognizer
+
+static void
+_reset_recognizer(Efl_Canvas_Gesture_Recognizer_Flick_Data *pd)
+{
+ pd->st_line = EINA_POSITION2D(0, 0);
+ pd->t_st = pd->t_end = 0;
+ pd->line_length = 0;
+ pd->line_angle = -1;
+ pd->touched = EINA_FALSE;
+}
+
+EOLIAN static const Efl_Class *
+_efl_canvas_gesture_recognizer_flick_efl_canvas_gesture_recognizer_type_get(const Eo *obj EINA_UNUSED, Efl_Canvas_Gesture_Recognizer_Flick_Data *pd EINA_UNUSED)
{
- return efl_add(EFL_CANVAS_GESTURE_FLICK_CLASS, obj);
+ return EFL_CANVAS_GESTURE_FLICK_CLASS;
}
static void
@@ -29,7 +40,7 @@ _momentum_set(Eo *obj,
Evas_Coord dy = v2.y - v1.y;
int dt = t2 - t1;
Eina_Value *tf, *tmt;
- double thumbscroll_friction, thumbscroll_momentum_threshold;
+ double thumbscroll_momentum_friction, thumbscroll_momentum_threshold;
if (dt > 0)
{
@@ -39,15 +50,15 @@ _momentum_set(Eo *obj,
vel = sqrt((velx * velx) + (vely * vely));
- tf = efl_gesture_recognizer_config_get(obj, "thumbscroll_friction");
- if (tf) eina_value_get(tf, &thumbscroll_friction);
- else thumbscroll_friction = THUMBSCROLL_FRICTION;
+ tf = _recognizer_config_get(obj, "thumbscroll_momentum_friction");
+ if (tf) eina_value_get(tf, &thumbscroll_momentum_friction);
+ else thumbscroll_momentum_friction = THUMBSCROLL_FRICTION;
- tmt = efl_gesture_recognizer_config_get(obj, "thumbscroll_momentum_threshold");
+ tmt = _recognizer_config_get(obj, "thumbscroll_momentum_threshold");
if (tmt) eina_value_get(tmt, &thumbscroll_momentum_threshold);
else thumbscroll_momentum_threshold = THUMBSCROLL_MOMENTUM_THRESHOLD;
- if ((thumbscroll_friction > 0.0) &&
+ if ((thumbscroll_momentum_friction > 0.0) &&
(vel > thumbscroll_momentum_threshold)) /* report
* momentum */
{
@@ -70,90 +81,38 @@ _single_line_process(Eo *obj,
{
switch (efl_gesture_touch_state_get(event))
{
- case EFL_GESTURE_TOUCH_BEGIN:
- case EFL_GESTURE_TOUCH_UPDATE:
- if (!pd->t_st)
- {
- pd->st_line = efl_gesture_touch_cur_point_get(event);
- pd->t_st = efl_gesture_touch_cur_timestamp_get(event);
-
- efl_gesture_hotspot_set(gesture, pd->st_line);
-
- return;
- }
-
- break;
-
- case EFL_GESTURE_TOUCH_END:
- {
- if (!pd->t_st) return;
-
- pd->t_end = efl_gesture_touch_cur_timestamp_get(event);
+ case EFL_GESTURE_TOUCH_STATE_BEGIN:
+ case EFL_GESTURE_TOUCH_STATE_UPDATE:
+ if (!pd->t_st)
+ {
+ pd->st_line = efl_gesture_touch_current_point_get(event);
+ pd->t_st = efl_gesture_touch_current_timestamp_get(event);
- break;
- }
+ efl_gesture_hotspot_set(gesture, pd->st_line);
- default:
+ return;
+ }
- return;
- }
+ break;
- _momentum_set(obj, fd, pd->st_line, efl_gesture_touch_cur_point_get(event),
- pd->t_st, efl_gesture_touch_cur_timestamp_get(event));
-}
+ case EFL_GESTURE_TOUCH_STATE_END:
+ {
+ if (!pd->t_st) return;
-static double
-_angle_get(Evas_Coord xx1,
- Evas_Coord yy1,
- Evas_Coord xx2,
- Evas_Coord yy2)
-{
- double a, xx, yy, rt = (-1);
+ pd->t_end = efl_gesture_touch_current_timestamp_get(event);
- xx = abs(xx2 - xx1);
- yy = abs(yy2 - yy1);
+ break;
+ }
- if (((int)xx) && ((int)yy))
- {
- rt = a = RAD2DEG(atan(yy / xx));
- if (xx1 < xx2)
- {
- if (yy1 < yy2) rt = 360 - a;
- else rt = a;
- }
- else
- {
- if (yy1 < yy2) rt = 180 + a;
- else rt = 180 - a;
- }
- }
+ default:
- if (rt < 0) /* Do this only if rt is not set */
- {
- if (((int)xx)) /* Horizontal line */
- {
- if (xx2 < xx1) rt = 180;
- else rt = 0.0;
- }
- else
- { /* Vertical line */
- if (yy2 < yy1) rt = 90;
- else rt = 270;
- }
+ return;
}
- /* Now we want to change from:
- * 90 0
- * original circle 180 0 We want: 270 90
- * 270 180
- */
- rt = 450 - rt;
- if (rt >= 360) rt -= 360;
-
- return rt;
+ _momentum_set(obj, fd, pd->st_line, efl_gesture_touch_current_point_get(event),
+ pd->t_st, efl_gesture_touch_current_timestamp_get(event));
}
-
static void
_vector_get(Eina_Position2D v1,
Eina_Position2D v2,
@@ -174,15 +133,17 @@ _efl_canvas_gesture_recognizer_flick_efl_canvas_gesture_recognizer_recognize(Eo
Efl_Canvas_Gesture *gesture, Efl_Object *watched,
Efl_Canvas_Gesture_Touch *event)
{
- double angle;
+ double angle, line_angle;
Eina_Value *val;
unsigned char glayer_continues_enable;
- Efl_Canvas_Gesture_Recognizer_Result result = EFL_GESTURE_CANCEL;
+ Efl_Canvas_Gesture_Recognizer_Result result = EFL_GESTURE_RECOGNIZER_RESULT_CANCEL;
Eina_Bool touch_up = EINA_FALSE;
+ int points = efl_gesture_touch_points_count_get(event);
Efl_Canvas_Gesture_Flick_Data *fd = efl_data_scope_get(gesture, EFL_CANVAS_GESTURE_FLICK_CLASS);
Efl_Canvas_Gesture_Recognizer_Data *rd = efl_data_scope_get(obj, EFL_CANVAS_GESTURE_RECOGNIZER_CLASS);
+ Eina_Bool dead = EINA_FALSE;
- val = efl_gesture_recognizer_config_get(obj, "glayer_continues_enable");
+ val = _recognizer_config_get(obj, "glayer_continues_enable");
if (val) eina_value_get(val, &glayer_continues_enable);
else glayer_continues_enable = 1;
@@ -190,55 +151,88 @@ _efl_canvas_gesture_recognizer_flick_efl_canvas_gesture_recognizer_recognize(Eo
//without mouse up.
//Recognizing the gesture again, even though it was canceled during gesture
//recognition.
- if (efl_gesture_state_get(gesture) == EFL_GESTURE_CANCELED)
- efl_gesture_state_set(gesture, EFL_GESTURE_NONE);
+ if (efl_gesture_state_get(gesture) == EFL_GESTURE_STATE_CANCELED)
+ efl_gesture_state_set(gesture, EFL_GESTURE_STATE_NONE);
- if (efl_gesture_touch_state_get(event) == EFL_GESTURE_TOUCH_END)
+ if (efl_gesture_touch_state_get(event) == EFL_GESTURE_TOUCH_STATE_END)
touch_up = EINA_TRUE;
//This is to handle a case with a mouse click on the target object.
- if (efl_gesture_touch_state_get(event) == EFL_GESTURE_TOUCH_END && !pd->touched)
- efl_gesture_manager_gesture_clean_up(rd->manager, watched, EFL_EVENT_GESTURE_FLICK);
+ if (efl_gesture_touch_state_get(event) == EFL_GESTURE_TOUCH_STATE_END && !pd->touched)
+ {
+ efl_gesture_manager_recognizer_cleanup(efl_provider_find(obj, EFL_CANVAS_GESTURE_MANAGER_CLASS), obj, watched);
+ dead = EINA_TRUE;
+ }
if (glayer_continues_enable && !pd->touched)
{
- pd->touched = EINA_TRUE;
- pd->line_angle = -1.0;
- rd->continues = EINA_TRUE;
-
- return EFL_GESTURE_IGNORE;
+ pd->touched = EINA_TRUE;
+ pd->line_angle = -1.0;
+ rd->continues = EINA_TRUE;
+ /* this has been deleted */
+ if (!dead)
+ fd->id = -1;
+
+ return EFL_GESTURE_RECOGNIZER_RESULT_IGNORE;
+ }
+ if (pd->touched && (efl_gesture_touch_current_data_get(event)->action == EFL_POINTER_ACTION_DOWN))
+ {
+ /* a second finger was pressed at the same time-ish as the first: combine into same event */
+ if (efl_gesture_touch_current_timestamp_get(event) - efl_gesture_timestamp_get(gesture) < TAP_TOUCH_TIME_THRESHOLD)
+ return EFL_GESTURE_RECOGNIZER_RESULT_IGNORE;
+ }
+ if (pd->t_st && (points > 1) && (fd->id != efl_gesture_touch_current_data_get(event)->id))
+ {
+ int xdir[2], ydir[2];
+ const Efl_Gesture_Touch_Point_Data *data = efl_gesture_touch_current_data_get(event);
+ const Efl_Gesture_Touch_Point_Data *data2;
+
+ if (fd->id == -1) return EFL_GESTURE_RECOGNIZER_RESULT_IGNORE;
+ data2 = efl_gesture_touch_data_get(event, fd->id);
+ xdir[0] = _direction_get(data->prev.pos.x, data->cur.pos.x);
+ ydir[0] = _direction_get(data->prev.pos.y, data->cur.pos.y);
+ xdir[1] = _direction_get(data2->prev.pos.x, data2->cur.pos.x);
+ ydir[1] = _direction_get(data2->prev.pos.y, data2->cur.pos.y);
+ if ((xdir[0] != xdir[1]) || (ydir[0] != ydir[1]))
+ {
+ rd->continues = EINA_FALSE;
+ _reset_recognizer(pd);
+ return EFL_GESTURE_RECOGNIZER_RESULT_CANCEL;
+ }
+ return EFL_GESTURE_RECOGNIZER_RESULT_IGNORE;
}
_single_line_process(obj, pd, gesture, fd, event);
- _vector_get(pd->st_line, efl_gesture_touch_cur_point_get(event),
+ _vector_get(pd->st_line, efl_gesture_touch_current_point_get(event),
&pd->line_length, &angle);
+ line_angle = pd->line_angle;
if (pd->t_st)
{
- if (pd->line_angle >= 0.0)
+ if ((line_angle > 0.0) || EINA_DBL_EQ(line_angle, 0.0))
{
double line_distance_tolerance, line_angular_tolerance;
- double a = fabs(angle - pd->line_angle);
+ double a = fabs(angle - line_angle);
double d = (tan(DEG2RAD(a))) * pd->line_length;
- val = efl_gesture_recognizer_config_get(obj, "glayer_line_distance_tolerance");
+ val = _recognizer_config_get(obj, "glayer_line_distance_tolerance");
if (val) eina_value_get(val, &line_distance_tolerance);
else line_distance_tolerance = 3.0;
- line_distance_tolerance *= rd->finger_size;
+ line_distance_tolerance *= pd->finger_size;
- val = efl_gesture_recognizer_config_get(obj, "glayer_line_angular_tolerance");
+ val = _recognizer_config_get(obj, "glayer_line_angular_tolerance");
if (val) eina_value_get(val, &line_angular_tolerance);
else line_angular_tolerance = 20.0;
if ((d > line_distance_tolerance) ||
(a > line_angular_tolerance))
{
- memset(pd, 0, sizeof(Efl_Canvas_Gesture_Recognizer_Flick_Data));
+ _reset_recognizer(pd);
if (touch_up) rd->continues = EINA_FALSE;
- return EFL_GESTURE_CANCEL;
+ return EFL_GESTURE_RECOGNIZER_RESULT_CANCEL;
}
/* We may finish line if momentum is zero */
@@ -246,39 +240,38 @@ _efl_canvas_gesture_recognizer_flick_efl_canvas_gesture_recognizer_recognize(Eo
{
/* This is for continues-gesture */
/* Finish line on zero momentum for continues gesture */
- if ((!fd->momentum.x) && (!fd->momentum.y))
- pd->t_end = efl_gesture_touch_cur_timestamp_get(event);
+ if (EINA_DBL_EQ(fd->momentum.x, 0) && EINA_DBL_EQ(fd->momentum.y, 0))
+ pd->t_end = efl_gesture_touch_current_timestamp_get(event);
}
}
else
{
double line_min_length;
- val = efl_gesture_recognizer_config_get(obj, "glayer_line_min_length");
+ val = _recognizer_config_get(obj, "glayer_line_min_length");
if (val) eina_value_get(val, &line_min_length);
else line_min_length = 1.0;
- line_min_length *= rd->finger_size;
+ line_min_length *= pd->finger_size;
if (pd->line_length >= line_min_length)
- fd->angle = pd->line_angle = angle;
-
+ line_angle = fd->angle = pd->line_angle = angle;
}
if (pd->t_end)
{
- if (pd->line_angle < 0.0)
+ if (line_angle < 0.0)
{
- memset(pd, 0, sizeof(Efl_Canvas_Gesture_Recognizer_Flick_Data));
+ _reset_recognizer(pd);
if (touch_up) rd->continues = EINA_FALSE;
- return EFL_GESTURE_CANCEL;
+ return EFL_GESTURE_RECOGNIZER_RESULT_CANCEL;
}
}
}
- unsigned int tm_end = efl_gesture_touch_cur_timestamp_get(event);
+ unsigned int tm_end = efl_gesture_touch_current_timestamp_get(event);
if (pd->t_end)
{
if (pd->t_end < tm_end)
@@ -286,62 +279,66 @@ _efl_canvas_gesture_recognizer_flick_efl_canvas_gesture_recognizer_recognize(Eo
}
unsigned int time_limit_ms;
- val = efl_gesture_recognizer_config_get(obj, "glayer_flick_time_limit_ms");
+ val = _recognizer_config_get(obj, "glayer_flick_time_limit_ms");
if (val) eina_value_get(val, &time_limit_ms);
else time_limit_ms = 120;
if ((tm_end - pd->t_st) > time_limit_ms)
- {
- memset(pd, 0, sizeof(Efl_Canvas_Gesture_Recognizer_Flick_Data));
+ {
+ _reset_recognizer(pd);
- if (touch_up) rd->continues = EINA_FALSE;
+ if (touch_up) rd->continues = EINA_FALSE;
- return EFL_GESTURE_CANCEL;
- }
+ return EFL_GESTURE_RECOGNIZER_RESULT_CANCEL;
+ }
switch (efl_gesture_touch_state_get(event))
{
- case EFL_GESTURE_TOUCH_BEGIN:
- case EFL_GESTURE_TOUCH_UPDATE:
- {
- if (pd->t_st)
- {
- if (glayer_continues_enable && pd->t_end)
- {
- result = EFL_GESTURE_FINISH;
- }
- else
- {
- result = EFL_GESTURE_TRIGGER;
- }
- }
- break;
- }
-
- case EFL_GESTURE_TOUCH_END:
- {
- if (!pd->t_st)
- {
- pd->touched = EINA_FALSE;
- rd->continues = EINA_FALSE;
-
- return EFL_GESTURE_CANCEL;
- }
- if (pd->t_st && pd->t_end)
- {
- rd->continues = EINA_FALSE;
-
- result = EFL_GESTURE_FINISH;
- }
-
- efl_gesture_hotspot_set(gesture, efl_gesture_touch_cur_point_get(event));
-
- memset(pd, 0, sizeof(Efl_Canvas_Gesture_Recognizer_Flick_Data));
-
- rd->continues = EINA_FALSE;
-
- break;
- }
+ case EFL_GESTURE_TOUCH_STATE_BEGIN:
+ fd->id = efl_gesture_touch_current_data_get(event)->id;
+ EINA_FALLTHROUGH;
+ case EFL_GESTURE_TOUCH_STATE_UPDATE:
+ {
+ if (fd->id == -1)
+ fd->id = efl_gesture_touch_current_data_get(event)->id;
+ if (pd->t_st)
+ {
+ if (glayer_continues_enable && pd->t_end)
+ {
+ result = EFL_GESTURE_RECOGNIZER_RESULT_FINISH;
+ }
+ else
+ {
+ result = EFL_GESTURE_RECOGNIZER_RESULT_TRIGGER;
+ }
+ }
+ break;
+ }
+
+ case EFL_GESTURE_TOUCH_STATE_END:
+ {
+ if (!pd->t_st)
+ {
+ pd->touched = EINA_FALSE;
+ rd->continues = EINA_FALSE;
+
+ return EFL_GESTURE_RECOGNIZER_RESULT_CANCEL;
+ }
+ if (pd->t_st && pd->t_end)
+ {
+ rd->continues = EINA_FALSE;
+
+ result = EFL_GESTURE_RECOGNIZER_RESULT_FINISH;
+ }
+
+ efl_gesture_hotspot_set(gesture, efl_gesture_touch_current_point_get(event));
+
+ _reset_recognizer(pd);
+
+ rd->continues = EINA_FALSE;
+
+ break;
+ }
default: