1 #include "efl_canvas_gesture_private.h"
2
3 #define MY_CLASS EFL_CANVAS_GESTURE_RECOGNIZER_DOUBLE_TAP_CLASS
4
5 #define TAP_TIME_OUT 0.33
6
7 EOLIAN static const Efl_Class *
_efl_canvas_gesture_recognizer_double_tap_efl_canvas_gesture_recognizer_type_get(const Eo * obj EINA_UNUSED,Efl_Canvas_Gesture_Recognizer_Double_Tap_Data * pd EINA_UNUSED)8 _efl_canvas_gesture_recognizer_double_tap_efl_canvas_gesture_recognizer_type_get(const Eo *obj EINA_UNUSED, Efl_Canvas_Gesture_Recognizer_Double_Tap_Data *pd EINA_UNUSED)
9 {
10 return EFL_CANVAS_GESTURE_DOUBLE_TAP_CLASS;
11 }
12
13 EOLIAN static void
_efl_canvas_gesture_recognizer_double_tap_efl_object_destructor(Eo * obj,Efl_Canvas_Gesture_Recognizer_Double_Tap_Data * pd)14 _efl_canvas_gesture_recognizer_double_tap_efl_object_destructor(Eo *obj,
15 Efl_Canvas_Gesture_Recognizer_Double_Tap_Data *pd)
16 {
17 if (pd->timeout)
18 ecore_timer_del(pd->timeout);
19
20 efl_destructor(efl_super(obj, MY_CLASS));
21 }
22
23 static Eina_Bool
_tap_timeout_cb(void * data)24 _tap_timeout_cb(void *data)
25 {
26 Efl_Canvas_Gesture_Recognizer_Double_Tap_Data *pd;
27
28 pd = efl_data_scope_get(data, EFL_CANVAS_GESTURE_RECOGNIZER_DOUBLE_TAP_CLASS);
29
30 efl_gesture_state_set(pd->gesture, EFL_GESTURE_STATE_CANCELED);
31 efl_event_callback_call(pd->target, EFL_EVENT_GESTURE_DOUBLE_TAP, pd->gesture);
32
33 efl_gesture_manager_recognizer_cleanup(efl_provider_find(data, EFL_CANVAS_GESTURE_MANAGER_CLASS), data,
34 pd->target);
35
36 pd->timeout = NULL;
37 pd->tap_count = 0;
38
39 return ECORE_CALLBACK_CANCEL;
40 }
41
42 EOLIAN static Efl_Canvas_Gesture_Recognizer_Result
_efl_canvas_gesture_recognizer_double_tap_efl_canvas_gesture_recognizer_recognize(Eo * obj,Efl_Canvas_Gesture_Recognizer_Double_Tap_Data * pd,Efl_Canvas_Gesture * gesture,Efl_Object * watched,Efl_Canvas_Gesture_Touch * event)43 _efl_canvas_gesture_recognizer_double_tap_efl_canvas_gesture_recognizer_recognize(Eo *obj,
44 Efl_Canvas_Gesture_Recognizer_Double_Tap_Data *pd,
45 Efl_Canvas_Gesture *gesture, Efl_Object *watched,
46 Efl_Canvas_Gesture_Touch *event)
47 {
48 double length, start_timeout = pd->start_timeout;
49 double timeout = TAP_TIME_OUT;
50 Eina_Position2D pos;
51 Eina_Vector2 dist;
52 Efl_Canvas_Gesture_Recognizer_Result result = EFL_GESTURE_RECOGNIZER_RESULT_CANCEL;
53
54 pd->target = watched;
55 pd->gesture = gesture;
56
57 if (!EINA_DBL_NONZERO(start_timeout))
58 {
59 double time;
60 Eina_Value *val = _recognizer_config_get(obj, "glayer_double_tap_timeout");
61
62 if (val)
63 {
64 eina_value_get(val, &time);
65 pd->start_timeout = timeout = time;
66 }
67 }
68 else
69 timeout = start_timeout;
70
71 switch (efl_gesture_touch_state_get(event))
72 {
73 case EFL_GESTURE_TOUCH_STATE_BEGIN:
74 {
75 pos = efl_gesture_touch_start_point_get(event);
76 efl_gesture_hotspot_set(gesture, pos);
77
78 if (pd->timeout)
79 ecore_timer_reset(pd->timeout);
80 else
81 pd->timeout = ecore_timer_add(timeout, _tap_timeout_cb, obj);
82
83 result = EFL_GESTURE_RECOGNIZER_RESULT_TRIGGER;
84
85 break;
86 }
87
88 case EFL_GESTURE_TOUCH_STATE_UPDATE:
89 {
90 /* multi-touch */
91 if (efl_gesture_touch_current_data_get(event)->action == EFL_POINTER_ACTION_DOWN)
92 {
93 /* a second finger was pressed at the same time-ish as the first: combine into same event */
94 if (efl_gesture_touch_current_timestamp_get(event) - efl_gesture_timestamp_get(gesture) < TAP_TOUCH_TIME_THRESHOLD)
95 {
96 result = EFL_GESTURE_RECOGNIZER_RESULT_IGNORE;
97 break;
98 }
99 }
100 result = EFL_GESTURE_RECOGNIZER_RESULT_IGNORE;
101
102 if (efl_gesture_state_get(gesture) != EFL_GESTURE_STATE_NONE &&
103 !_event_multi_touch_get(event))
104 {
105 dist = efl_gesture_touch_distance(event, efl_gesture_touch_current_data_get(event)->id);
106 length = fabs(dist.x) + fabs(dist.y);
107
108 if (length > pd->finger_size)
109 {
110 if (pd->timeout)
111 {
112 ecore_timer_del(pd->timeout);
113 pd->timeout = NULL;
114 }
115
116 result = EFL_GESTURE_RECOGNIZER_RESULT_CANCEL;
117
118 pd->tap_count = 0;
119 }
120 }
121
122 break;
123 }
124
125 case EFL_GESTURE_TOUCH_STATE_END:
126 {
127 if (efl_gesture_state_get(gesture) != EFL_GESTURE_STATE_NONE &&
128 !_event_multi_touch_get(event))
129 {
130 if (efl_gesture_touch_previous_data_get(event))
131 {
132 Efl_Pointer_Action prev_act = efl_gesture_touch_previous_data_get(event)->action;
133 /* multi-touch */
134 if ((prev_act == EFL_POINTER_ACTION_UP) || (prev_act == EFL_POINTER_ACTION_CANCEL))
135 {
136 /* a second finger was pressed at the same time-ish as the first: combine into same event */
137 if (efl_gesture_touch_current_timestamp_get(event) - efl_gesture_timestamp_get(gesture) < TAP_TOUCH_TIME_THRESHOLD)
138 {
139 result = EFL_GESTURE_RECOGNIZER_RESULT_IGNORE;
140 break;
141 }
142 }
143 }
144 dist = efl_gesture_touch_distance(event, efl_gesture_touch_current_data_get(event)->id);
145 length = fabs(dist.x) + fabs(dist.y);
146
147 if (length <= pd->finger_size)
148 {
149 pd->tap_count++;
150 if (pd->tap_count == 1)
151 {
152 if (pd->timeout)
153 ecore_timer_reset(pd->timeout);
154
155 result = EFL_GESTURE_RECOGNIZER_RESULT_TRIGGER;
156 }
157 else
158 {
159 if (pd->timeout)
160 {
161 ecore_timer_del(pd->timeout);
162 pd->timeout = NULL;
163 }
164
165 if (efl_gesture_touch_state_get(event) == EFL_GESTURE_TOUCH_STATE_END)
166 result = EFL_GESTURE_RECOGNIZER_RESULT_FINISH;
167 else
168 result = EFL_GESTURE_RECOGNIZER_RESULT_TRIGGER;
169
170 pd->tap_count = 0;
171 }
172 }
173 else
174 {
175 if (pd->timeout)
176 {
177 ecore_timer_del(pd->timeout);
178 pd->timeout = NULL;
179 }
180
181 result = EFL_GESTURE_RECOGNIZER_RESULT_CANCEL;
182
183 pd->tap_count = 0;
184 }
185 }
186
187 break;
188 }
189
190 default:
191
192 break;
193 }
194
195 return result;
196 }
197
198 #include "efl_canvas_gesture_recognizer_double_tap.eo.c"
199