summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWoochanlee <wc0917.lee@samsung.com>2019-05-14 16:37:20 +0900
committerJaehyun Cho <jae_hyun.cho@samsung.com>2019-05-14 16:37:20 +0900
commit54175998d538e0b2173fc023bb822f1e6536e58f (patch)
tree5c240f08eff5dddd9a2c6d7b4d1cdfaf948a86a1
parentf93eb3fc043fcc945fb2e65a27a05447ac8ce603 (diff)
Gesture Manager: Add gestures and fix gesture managing, recognizer logic.
Summary: https://phab.enlightenment.org/T7544 Provides a way for a user to get a gesture manager, recognizer instance. Supports different recognizer properties for each target(Eo). Gesture, Touch Class Life-cycle re-implementation. for supporting multiple touches. Add below gestures. efl_canvas_gesture_tap efl_canvas_gesture_double_tap efl_canvas_gesture_triple_tap efl_canvas_gesture_long_tap efl_canvas_gesture_momentum efl_canvas_gesture_zoom efl_canvas_gesture_flick Test Plan: Simple test -> test_gesture_framework.c More test cases will upload. Reviewers: woohyun, smohanty, segfaultxavi, Jaehyun_Cho Reviewed By: Jaehyun_Cho Subscribers: Jaehyun_Cho, segfaultxavi, cedric Tags: #efl, #do_not_merge Differential Revision: https://phab.enlightenment.org/D7579
-rw-r--r--src/Makefile_Evas.am40
-rw-r--r--src/bin/elementary/test_gesture_framework.c281
-rw-r--r--src/lib/evas/Evas_Eo.h29
-rw-r--r--src/lib/evas/canvas/efl_canvas_object.eo6
-rw-r--r--src/lib/evas/canvas/evas_callbacks.c6
-rw-r--r--src/lib/evas/canvas/evas_object_main.c9
-rw-r--r--src/lib/evas/gesture/efl_canvas_gesture.c19
-rw-r--r--src/lib/evas/gesture/efl_canvas_gesture.eo20
-rw-r--r--src/lib/evas/gesture/efl_canvas_gesture_double_tap.c18
-rw-r--r--src/lib/evas/gesture/efl_canvas_gesture_double_tap.eo9
-rw-r--r--src/lib/evas/gesture/efl_canvas_gesture_flick.c30
-rw-r--r--src/lib/evas/gesture/efl_canvas_gesture_flick.eo20
-rw-r--r--src/lib/evas/gesture/efl_canvas_gesture_long_tap.c8
-rw-r--r--src/lib/evas/gesture/efl_canvas_gesture_long_tap.eo5
-rw-r--r--src/lib/evas/gesture/efl_canvas_gesture_manager.c235
-rw-r--r--src/lib/evas/gesture/efl_canvas_gesture_manager.eo8
-rw-r--r--src/lib/evas/gesture/efl_canvas_gesture_momentum.c24
-rw-r--r--src/lib/evas/gesture/efl_canvas_gesture_momentum.eo16
-rw-r--r--src/lib/evas/gesture/efl_canvas_gesture_private.h141
-rw-r--r--src/lib/evas/gesture/efl_canvas_gesture_recognizer.c10
-rw-r--r--src/lib/evas/gesture/efl_canvas_gesture_recognizer.eo15
-rw-r--r--src/lib/evas/gesture/efl_canvas_gesture_recognizer_double_tap.c191
-rw-r--r--src/lib/evas/gesture/efl_canvas_gesture_recognizer_double_tap.eo22
-rw-r--r--src/lib/evas/gesture/efl_canvas_gesture_recognizer_flick.c354
-rw-r--r--src/lib/evas/gesture/efl_canvas_gesture_recognizer_flick.eo9
-rw-r--r--src/lib/evas/gesture/efl_canvas_gesture_recognizer_long_tap.c151
-rw-r--r--src/lib/evas/gesture/efl_canvas_gesture_recognizer_long_tap.eo16
-rw-r--r--src/lib/evas/gesture/efl_canvas_gesture_recognizer_momentum.c197
-rw-r--r--src/lib/evas/gesture/efl_canvas_gesture_recognizer_momentum.eo9
-rw-r--r--src/lib/evas/gesture/efl_canvas_gesture_recognizer_tap.c56
-rw-r--r--src/lib/evas/gesture/efl_canvas_gesture_recognizer_tap.eo3
-rw-r--r--src/lib/evas/gesture/efl_canvas_gesture_recognizer_triple_tap.c191
-rw-r--r--src/lib/evas/gesture/efl_canvas_gesture_recognizer_triple_tap.eo22
-rw-r--r--src/lib/evas/gesture/efl_canvas_gesture_recognizer_zoom.c275
-rw-r--r--src/lib/evas/gesture/efl_canvas_gesture_recognizer_zoom.eo9
-rw-r--r--src/lib/evas/gesture/efl_canvas_gesture_tap.c3
-rw-r--r--src/lib/evas/gesture/efl_canvas_gesture_tap.eo5
-rw-r--r--src/lib/evas/gesture/efl_canvas_gesture_touch.c102
-rw-r--r--src/lib/evas/gesture/efl_canvas_gesture_touch.eo18
-rw-r--r--src/lib/evas/gesture/efl_canvas_gesture_triple_tap.c18
-rw-r--r--src/lib/evas/gesture/efl_canvas_gesture_triple_tap.eo9
-rw-r--r--src/lib/evas/gesture/efl_canvas_gesture_types.eot13
-rw-r--r--src/lib/evas/gesture/efl_canvas_gesture_zoom.c35
-rw-r--r--src/lib/evas/gesture/efl_canvas_gesture_zoom.eo19
-rw-r--r--src/lib/evas/gesture/efl_gesture_events.eo13
-rw-r--r--src/lib/evas/gesture/meson.build50
46 files changed, 2470 insertions, 269 deletions
diff --git a/src/Makefile_Evas.am b/src/Makefile_Evas.am
index 95ec86e756..9abbe585a3 100644
--- a/src/Makefile_Evas.am
+++ b/src/Makefile_Evas.am
@@ -59,16 +59,25 @@ evas_gesture_eolian_pub_files = \
59 lib/evas/gesture/efl_canvas_gesture.eo \ 59 lib/evas/gesture/efl_canvas_gesture.eo \
60 lib/evas/gesture/efl_canvas_gesture_tap.eo \ 60 lib/evas/gesture/efl_canvas_gesture_tap.eo \
61 lib/evas/gesture/efl_canvas_gesture_long_tap.eo \ 61 lib/evas/gesture/efl_canvas_gesture_long_tap.eo \
62 lib/evas/gesture/efl_canvas_gesture_double_tap.eo \
63 lib/evas/gesture/efl_canvas_gesture_triple_tap.eo \
64 lib/evas/gesture/efl_canvas_gesture_momentum.eo \
65 lib/evas/gesture/efl_canvas_gesture_flick.eo \
66 lib/evas/gesture/efl_canvas_gesture_zoom.eo \
62 lib/evas/gesture/efl_canvas_gesture_recognizer.eo \ 67 lib/evas/gesture/efl_canvas_gesture_recognizer.eo \
68 lib/evas/gesture/efl_canvas_gesture_recognizer_tap.eo \
69 lib/evas/gesture/efl_canvas_gesture_recognizer_long_tap.eo \
70 lib/evas/gesture/efl_canvas_gesture_recognizer_double_tap.eo \
71 lib/evas/gesture/efl_canvas_gesture_recognizer_triple_tap.eo \
72 lib/evas/gesture/efl_canvas_gesture_recognizer_momentum.eo \
73 lib/evas/gesture/efl_canvas_gesture_recognizer_flick.eo \
74 lib/evas/gesture/efl_canvas_gesture_recognizer_zoom.eo \
63 lib/evas/gesture/efl_canvas_gesture_manager.eo \ 75 lib/evas/gesture/efl_canvas_gesture_manager.eo \
76 lib/evas/gesture/efl_gesture_events.eo \
64 $(NULL) 77 $(NULL)
65 78
66evas_canvas_eolian_priv_files = \ 79evas_canvas_eolian_priv_files = \
67 lib/evas/include/evas_ector_buffer.eo 80 lib/evas/include/evas_ector_buffer.eo
68
69evas_gesture_eolian_priv_files = \
70 lib/evas/gesture/efl_canvas_gesture_recognizer_tap.eo \
71 lib/evas/gesture/efl_canvas_gesture_recognizer_long_tap.eo
72 81
73evas_canvas_eolian_type_files = \ 82evas_canvas_eolian_type_files = \
74 lib/evas/canvas/evas_canvas3d_types.eot \ 83 lib/evas/canvas/evas_canvas3d_types.eot \
@@ -80,9 +89,6 @@ evas_gesture_eolian_type_files = \
80evas_canvas_eolian_priv_c = $(evas_canvas_eolian_priv_files:%.eo=%.eo.c) 89evas_canvas_eolian_priv_c = $(evas_canvas_eolian_priv_files:%.eo=%.eo.c)
81evas_canvas_eolian_priv_h = $(evas_canvas_eolian_priv_files:%.eo=%.eo.h) 90evas_canvas_eolian_priv_h = $(evas_canvas_eolian_priv_files:%.eo=%.eo.h)
82 91
83evas_gesture_eolian_priv_c = $(evas_gesture_eolian_priv_files:%.eo=%.eo.c)
84evas_gesture_eolian_priv_h = $(evas_gesture_eolian_priv_files:%.eo=%.eo.h)
85
86evas_canvas_eolian_pub_c = $(evas_canvas_eolian_pub_files:%.eo=%.eo.c) 92evas_canvas_eolian_pub_c = $(evas_canvas_eolian_pub_files:%.eo=%.eo.c)
87evas_canvas_eolian_pub_h = $(evas_canvas_eolian_pub_files:%.eo=%.eo.h) \ 93evas_canvas_eolian_pub_h = $(evas_canvas_eolian_pub_files:%.eo=%.eo.h) \
88 $(evas_canvas_eolian_type_files:%.eot=%.eot.h) 94 $(evas_canvas_eolian_type_files:%.eot=%.eot.h)
@@ -97,13 +103,15 @@ evas_eolian_files = $(evas_canvas_eolian_pub_files) \
97 $(evas_gesture_eolian_type_files) 103 $(evas_gesture_eolian_type_files)
98 104
99evas_eolian_internal_files = $(evas_canvas_eolian_priv_files) \ 105evas_eolian_internal_files = $(evas_canvas_eolian_priv_files) \
100 $(evas_gesture_eolian_priv_files) 106 $(evas_eolian_legacy_files)
101 107
102evas_eolian_c = $(evas_canvas_eolian_pub_c) $(evas_canvas_eolian_priv_c) \ 108evas_eolian_c = $(evas_canvas_eolian_pub_c) $(evas_canvas_eolian_priv_c) \
103 $(evas_gesture_eolian_pub_c) $(evas_gesture_eolian_priv_c) 109 $(evas_gesture_eolian_pub_c) \
110 $(evas_eolian_legacy_c)
104 111
105evas_eolian_h = $(evas_canvas_eolian_pub_h) $(evas_canvas_eolian_priv_h) \ 112evas_eolian_h = $(evas_canvas_eolian_pub_h) $(evas_canvas_eolian_priv_h) \
106 $(evas_gesture_eolian_pub_h) $(evas_gesture_eolian_priv_h) 113 $(evas_gesture_eolian_pub_h) \
114 $(evas_eolian_legacy_h)
107 115
108BUILT_SOURCES += \ 116BUILT_SOURCES += \
109 $(evas_eolian_c) \ 117 $(evas_eolian_c) \
@@ -319,9 +327,19 @@ lib/evas/gesture/efl_canvas_gesture_touch.c \
319lib/evas/gesture/efl_canvas_gesture.c \ 327lib/evas/gesture/efl_canvas_gesture.c \
320lib/evas/gesture/efl_canvas_gesture_tap.c \ 328lib/evas/gesture/efl_canvas_gesture_tap.c \
321lib/evas/gesture/efl_canvas_gesture_long_tap.c \ 329lib/evas/gesture/efl_canvas_gesture_long_tap.c \
330lib/evas/gesture/efl_canvas_gesture_double_tap.c \
331lib/evas/gesture/efl_canvas_gesture_triple_tap.c \
332lib/evas/gesture/efl_canvas_gesture_momentum.c \
333lib/evas/gesture/efl_canvas_gesture_flick.c \
334lib/evas/gesture/efl_canvas_gesture_zoom.c \
322lib/evas/gesture/efl_canvas_gesture_recognizer.c \ 335lib/evas/gesture/efl_canvas_gesture_recognizer.c \
323lib/evas/gesture/efl_canvas_gesture_recognizer_tap.c \ 336lib/evas/gesture/efl_canvas_gesture_recognizer_tap.c \
324lib/evas/gesture/efl_canvas_gesture_recognizer_long_tap.c \ 337lib/evas/gesture/efl_canvas_gesture_recognizer_long_tap.c \
338lib/evas/gesture/efl_canvas_gesture_recognizer_double_tap.c \
339lib/evas/gesture/efl_canvas_gesture_recognizer_triple_tap.c \
340lib/evas/gesture/efl_canvas_gesture_recognizer_momentum.c \
341lib/evas/gesture/efl_canvas_gesture_recognizer_flick.c \
342lib/evas/gesture/efl_canvas_gesture_recognizer_zoom.c \
325lib/evas/gesture/efl_canvas_gesture_manager.c \ 343lib/evas/gesture/efl_canvas_gesture_manager.c \
326lib/evas/common/region.c \ 344lib/evas/common/region.c \
327lib/evas/common/region.h \ 345lib/evas/common/region.h \
diff --git a/src/bin/elementary/test_gesture_framework.c b/src/bin/elementary/test_gesture_framework.c
index ada28bc50f..5e2e935e49 100644
--- a/src/bin/elementary/test_gesture_framework.c
+++ b/src/bin/elementary/test_gesture_framework.c
@@ -175,25 +175,19 @@ _color_and_icon_set(infra_data *infra, char *name, int n, int max,
175static void 175static void
176finger_tap_start(void *data , Efl_Canvas_Gesture *tap) 176finger_tap_start(void *data , Efl_Canvas_Gesture *tap)
177{ 177{
178 Eina_Vector2 pos = efl_gesture_hotspot_get(tap); 178 Eina_Position2D pos = efl_gesture_hotspot_get(tap);
179 179
180 _color_and_icon_set(data, TAP_NAME, 1, MAX_TAP, START_COLOR); 180 _color_and_icon_set(data, TAP_NAME, 1, MAX_TAP, START_COLOR);
181 printf("Tap Gesture started x,y=<%f,%f> \n", pos.x, pos.y); 181 printf("Tap Gesture started x,y=<%d,%d> \n", pos.x, pos.y);
182}
183
184static void
185finger_tap_update(void *data , Efl_Canvas_Gesture *tap EINA_UNUSED)
186{
187 _color_and_icon_set(data, TAP_NAME, 1, MAX_TAP, UPDATE_COLOR);
188} 182}
189 183
190static void 184static void
191finger_tap_end(void *data , Efl_Canvas_Gesture *tap) 185finger_tap_end(void *data , Efl_Canvas_Gesture *tap)
192{ 186{
193 Eina_Vector2 pos = efl_gesture_hotspot_get(tap); 187 Eina_Position2D pos = efl_gesture_hotspot_get(tap);
194 188
195 _color_and_icon_set(data, TAP_NAME, 1, MAX_TAP, END_COLOR); 189 _color_and_icon_set(data, TAP_NAME, 1, MAX_TAP, END_COLOR);
196 printf("Tap Gesture ended x,y=<%f,%f> \n", pos.x, pos.y); 190 printf("Tap Gesture ended x,y=<%d,%d> \n", pos.x, pos.y);
197} 191}
198 192
199static void 193static void
@@ -204,12 +198,147 @@ finger_tap_abort(void *data , Efl_Canvas_Gesture *tap EINA_UNUSED)
204} 198}
205 199
206static void 200static void
201finger_flick_start(void *data , Efl_Canvas_Gesture *tap)
202{
203 Eina_Position2D pos = efl_gesture_hotspot_get(tap);
204
205 _color_and_icon_set(data, FLICK_NAME, 1, MAX_TAP, START_COLOR);
206 printf("Flick Gesture started x,y=<%d,%d> \n", pos.x, pos.y);
207}
208
209static void
210finger_flick_end(void *data , Efl_Canvas_Gesture *tap)
211{
212 Eina_Position2D pos = efl_gesture_hotspot_get(tap);
213 double angle = efl_gesture_flick_angle_get(tap);
214
215 _color_and_icon_set(data, FLICK_NAME, 1, MAX_TAP, END_COLOR);
216 printf("Flick Gesture ended x,y=<%d,%d> angle=<%f>\n", pos.x, pos.y, angle);
217}
218
219static void
220finger_flick_abort(void *data , Efl_Canvas_Gesture *tap EINA_UNUSED)
221{
222 _color_and_icon_set(data, FLICK_NAME, 1, MAX_TAP, ABORT_COLOR);
223 printf("Flick Aborted\n");
224}
225
226static void
227finger_momentum_start(void *data , Efl_Canvas_Gesture *tap)
228{
229 Eina_Position2D pos = efl_gesture_hotspot_get(tap);
230 unsigned int t = efl_gesture_timestamp_get(tap);
231
232 _color_and_icon_set(data, MOMENTUM_NAME, 1, MAX_TAP, START_COLOR);
233 printf("Momentum Gesture started x,y=<%d,%d> time=<%d>\n", pos.x, pos.y, t);
234}
235
236static void
237finger_momentum_update(void *data , Efl_Canvas_Gesture *tap EINA_UNUSED)
238{
239 Eina_Position2D pos = efl_gesture_hotspot_get(tap);
240 Eina_Vector2 m = efl_gesture_momentum_get(tap);
241 unsigned int t = efl_gesture_timestamp_get(tap);
242
243 _color_and_icon_set(data, MOMENTUM_NAME, 1, MAX_TAP, UPDATE_COLOR);
244 printf("Momentum Gesture updated x,y=<%d,%d> momentum=<%f %f> time=<%d>\n",
245 pos.x, pos.y, m.x, m.y, t);
246}
247
248static void
249finger_momentum_end(void *data , Efl_Canvas_Gesture *tap)
250{
251 Eina_Position2D pos = efl_gesture_hotspot_get(tap);
252 Eina_Vector2 m = efl_gesture_momentum_get(tap);
253 unsigned int t = efl_gesture_timestamp_get(tap);
254
255 _color_and_icon_set(data, MOMENTUM_NAME, 1, MAX_TAP, END_COLOR);
256 printf("Momentum Gesture ended x,y=<%d,%d> momentum=<%f %f> time=<%d>\n",
257 pos.x, pos.y, m.x, m.y, t);
258}
259
260static void
261finger_momentum_abort(void *data , Efl_Canvas_Gesture *tap EINA_UNUSED)
262{
263 _color_and_icon_set(data, MOMENTUM_NAME, 1, MAX_TAP, ABORT_COLOR);
264 printf("Momentum Aborted\n");
265}
266
267static void
268finger_triple_tap_start(void *data , Efl_Canvas_Gesture *tap)
269{
270 Eina_Position2D pos = efl_gesture_hotspot_get(tap);
271
272 _color_and_icon_set(data, TRIPLE_TAP_NAME, 1, MAX_TAP, START_COLOR);
273 printf("Triple Tap Gesture started x,y=<%d,%d> \n", pos.x, pos.y);
274}
275
276static void
277finger_triple_tap_update(void *data , Efl_Canvas_Gesture *tap EINA_UNUSED)
278{
279 Eina_Position2D pos = efl_gesture_hotspot_get(tap);
280
281 _color_and_icon_set(data, TRIPLE_TAP_NAME, 1, MAX_TAP, UPDATE_COLOR);
282 printf("Triple Tap Gesture updated x,y=<%d,%d> \n", pos.x, pos.y);
283}
284
285static void
286finger_triple_tap_end(void *data , Efl_Canvas_Gesture *tap)
287{
288 Eina_Position2D pos = efl_gesture_hotspot_get(tap);
289
290 _color_and_icon_set(data, TRIPLE_TAP_NAME, 1, MAX_TAP, END_COLOR);
291 printf("Triple Tap Gesture ended x,y=<%d,%d> \n", pos.x, pos.y);
292}
293
294static void
295finger_triple_tap_abort(void *data , Efl_Canvas_Gesture *tap EINA_UNUSED)
296{
297 _color_and_icon_set(data, TRIPLE_TAP_NAME, 1, MAX_TAP, ABORT_COLOR);
298 printf("Triple Tap Aborted\n");
299}
300
301static void
302finger_double_tap_start(void *data , Efl_Canvas_Gesture *tap)
303{
304 Eina_Position2D pos = efl_gesture_hotspot_get(tap);
305
306 _color_and_icon_set(data, DOUBLE_TAP_NAME, 1, MAX_TAP, START_COLOR);
307 printf("Double Tap Gesture started x,y=<%d,%d> \n", pos.x, pos.y);
308}
309
310static void
311finger_double_tap_update(void *data , Efl_Canvas_Gesture *tap EINA_UNUSED)
312{
313 Eina_Position2D pos = efl_gesture_hotspot_get(tap);
314
315 _color_and_icon_set(data, DOUBLE_TAP_NAME, 1, MAX_TAP, UPDATE_COLOR);
316 printf("Double Tap Gesture updated x,y=<%d,%d> \n", pos.x, pos.y);
317}
318
319static void
320finger_double_tap_end(void *data , Efl_Canvas_Gesture *tap)
321{
322 Eina_Position2D pos = efl_gesture_hotspot_get(tap);
323
324 _color_and_icon_set(data, DOUBLE_TAP_NAME, 1, MAX_TAP, END_COLOR);
325 printf("Double Tap Gesture ended x,y=<%d,%d> \n", pos.x, pos.y);
326}
327
328static void
329finger_double_tap_abort(void *data , Efl_Canvas_Gesture *tap EINA_UNUSED)
330{
331 _color_and_icon_set(data, DOUBLE_TAP_NAME, 1, MAX_TAP, ABORT_COLOR);
332 printf("Double Tap Aborted\n");
333}
334
335static void
207finger_long_tap_start(void *data , Efl_Canvas_Gesture *tap) 336finger_long_tap_start(void *data , Efl_Canvas_Gesture *tap)
208{ 337{
209 Eina_Vector2 pos = efl_gesture_hotspot_get(tap); 338 Eina_Position2D pos = efl_gesture_hotspot_get(tap);
210 339
211 _color_and_icon_set(data, LONG_TAP_NAME, 1, MAX_TAP, START_COLOR); 340 _color_and_icon_set(data, LONG_TAP_NAME, 1, MAX_TAP, START_COLOR);
212 printf("Long Tap Gesture started x,y=<%f,%f> \n", pos.x, pos.y); 341 printf("Long Tap Gesture started x,y=<%d,%d> \n", pos.x, pos.y);
213} 342}
214 343
215static void 344static void
@@ -222,10 +351,10 @@ finger_long_tap_update(void *data , Efl_Canvas_Gesture *tap EINA_UNUSED)
222static void 351static void
223finger_long_tap_end(void *data , Efl_Canvas_Gesture *tap) 352finger_long_tap_end(void *data , Efl_Canvas_Gesture *tap)
224{ 353{
225 Eina_Vector2 pos = efl_gesture_hotspot_get(tap); 354 Eina_Position2D pos = efl_gesture_hotspot_get(tap);
226 355
227 _color_and_icon_set(data, LONG_TAP_NAME, 1, MAX_TAP, END_COLOR); 356 _color_and_icon_set(data, LONG_TAP_NAME, 1, MAX_TAP, END_COLOR);
228 printf("Long Tap Gesture ended x,y=<%f,%f> \n",pos.x, pos.y); 357 printf("Long Tap Gesture ended x,y=<%d,%d> \n",pos.x, pos.y);
229} 358}
230 359
231static void 360static void
@@ -244,9 +373,6 @@ tap_gesture_cb(void *data , const Efl_Event *ev)
244 case EFL_GESTURE_STARTED: 373 case EFL_GESTURE_STARTED:
245 finger_tap_start(data, g); 374 finger_tap_start(data, g);
246 break; 375 break;
247 case EFL_GESTURE_UPDATED:
248 finger_tap_update(data, g);
249 break;
250 case EFL_GESTURE_CANCELED: 376 case EFL_GESTURE_CANCELED:
251 finger_tap_abort(data, g); 377 finger_tap_abort(data, g);
252 break; 378 break;
@@ -259,6 +385,95 @@ tap_gesture_cb(void *data , const Efl_Event *ev)
259} 385}
260 386
261static void 387static void
388flick_gesture_cb(void *data , const Efl_Event *ev)
389{
390 Efl_Canvas_Gesture *g = ev->info;
391 switch(efl_gesture_state_get(g))
392 {
393 case EFL_GESTURE_STARTED:
394 finger_flick_start(data, g);
395 break;
396 case EFL_GESTURE_CANCELED:
397 finger_flick_abort(data, g);
398 break;
399 case EFL_GESTURE_FINISHED:
400 finger_flick_end(data, g);
401 break;
402 default:
403 break;
404 }
405}
406
407static void
408momentum_gesture_cb(void *data , const Efl_Event *ev)
409{
410 Efl_Canvas_Gesture *g = ev->info;
411 switch(efl_gesture_state_get(g))
412 {
413 case EFL_GESTURE_STARTED:
414 finger_momentum_start(data, g);
415 break;
416 case EFL_GESTURE_UPDATED:
417 finger_momentum_update(data, g);
418 break;
419 case EFL_GESTURE_CANCELED:
420 finger_momentum_abort(data, g);
421 break;
422 case EFL_GESTURE_FINISHED:
423 finger_momentum_end(data, g);
424 break;
425 default:
426 break;
427 }
428}
429
430static void
431triple_tap_gesture_cb(void *data , const Efl_Event *ev)
432{
433 Efl_Canvas_Gesture *g = ev->info;
434 switch(efl_gesture_state_get(g))
435 {
436 case EFL_GESTURE_STARTED:
437 finger_triple_tap_start(data, g);
438 break;
439 case EFL_GESTURE_UPDATED:
440 finger_triple_tap_update(data, g);
441 break;
442 case EFL_GESTURE_CANCELED:
443 finger_triple_tap_abort(data, g);
444 break;
445 case EFL_GESTURE_FINISHED:
446 finger_triple_tap_end(data, g);
447 break;
448 default:
449 break;
450 }
451}
452
453static void
454double_tap_gesture_cb(void *data , const Efl_Event *ev)
455{
456 Efl_Canvas_Gesture *g = ev->info;
457 switch(efl_gesture_state_get(g))
458 {
459 case EFL_GESTURE_STARTED:
460 finger_double_tap_start(data, g);
461 break;
462 case EFL_GESTURE_UPDATED:
463 finger_double_tap_update(data, g);
464 break;
465 case EFL_GESTURE_CANCELED:
466 finger_double_tap_abort(data, g);
467 break;
468 case EFL_GESTURE_FINISHED:
469 finger_double_tap_end(data, g);
470 break;
471 default:
472 break;
473 }
474}
475
476static void
262long_tap_gesture_cb(void *data , const Efl_Event *ev) 477long_tap_gesture_cb(void *data , const Efl_Event *ev)
263{ 478{
264 Efl_Canvas_Gesture *g = ev->info; 479 Efl_Canvas_Gesture *g = ev->info;
@@ -314,11 +529,22 @@ create_gesture_box(Evas_Object *win, icon_properties *icons,
314} 529}
315 530
316void 531void
532_tb_resize(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
533{
534 int w,h;
535
536 evas_object_geometry_get(obj, NULL, NULL, &w, &h);
537 evas_object_resize(data, w, h);
538 evas_object_color_set(data, 0, 0, 0, 0);
539 evas_object_show(data);
540}
541
542void
317test_gesture_framework(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, 543test_gesture_framework(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED,
318 void *event_info EINA_UNUSED) 544 void *event_info EINA_UNUSED)
319{ 545{
320 Evas_Object *win, *tb, *lb, *bx; 546 Evas_Object *win, *tb, *lb, *bx;
321 Evas_Object *r; /* Gesture layer transparent object */ 547 Evas_Object *r, *target; /* Gesture layer transparent object */
322 548
323 infra_data *infra = _infra_data_alloc(); 549 infra_data *infra = _infra_data_alloc();
324 550
@@ -336,6 +562,9 @@ test_gesture_framework(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED,
336 evas_object_show(tb); 562 evas_object_show(tb);
337 evas_object_show(bx); 563 evas_object_show(bx);
338 564
565 target = evas_object_rectangle_add(evas_object_evas_get(win));
566 evas_object_event_callback_add(win, EVAS_CALLBACK_RESIZE, _tb_resize, target);
567
339 /* Box of Tap icon and label */ 568 /* Box of Tap icon and label */
340 bx = create_gesture_box(win, infra->icons, 0, TAP_NAME, "Tap"); 569 bx = create_gesture_box(win, infra->icons, 0, TAP_NAME, "Tap");
341 elm_table_pack(tb, bx, 0, 0, 1, 1); 570 elm_table_pack(tb, bx, 0, 0, 1, 1);
@@ -458,15 +687,13 @@ test_gesture_framework(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED,
458 evas_object_show(lb); 687 evas_object_show(lb);
459 /* END - Building icons table */ 688 /* END - Building icons table */
460 689
461 r = evas_object_rectangle_add(evas_object_evas_get(win)); 690 // LISTEN FOR GESTURES
462 evas_object_move(r, 250, 300); 691 efl_event_callback_add(target, EFL_EVENT_GESTURE_TAP, tap_gesture_cb, infra);
463 evas_object_color_set(r, 0, 0, 255, 255); 692 efl_event_callback_add(target, EFL_EVENT_GESTURE_LONG_TAP, long_tap_gesture_cb, infra);
464 evas_object_resize(r, 70, 70); 693 efl_event_callback_add(target, EFL_EVENT_GESTURE_DOUBLE_TAP, double_tap_gesture_cb, infra);
465 evas_object_show(r); 694 efl_event_callback_add(target, EFL_EVENT_GESTURE_TRIPLE_TAP, triple_tap_gesture_cb, infra);
466 695 efl_event_callback_add(target, EFL_EVENT_GESTURE_MOMENTUM, momentum_gesture_cb, infra);
467 // LISTEN FOR TAP GESTURE 696 efl_event_callback_add(target, EFL_EVENT_GESTURE_FLICK, flick_gesture_cb, infra);
468 efl_event_callback_add(r, EFL_EVENT_GESTURE_TAP, tap_gesture_cb, infra);
469 efl_event_callback_add(r, EFL_EVENT_GESTURE_LONG_TAP, long_tap_gesture_cb, infra);
470 697
471 /* Update color state 20 times a second */ 698 /* Update color state 20 times a second */
472 infra->colortimer = ecore_timer_add(0.05, _icon_color_set_cb, infra->icons); 699 infra->colortimer = ecore_timer_add(0.05, _icon_color_set_cb, infra->icons);
diff --git a/src/lib/evas/Evas_Eo.h b/src/lib/evas/Evas_Eo.h
index a4f611e201..f3bcb6eb32 100644
--- a/src/lib/evas/Evas_Eo.h
+++ b/src/lib/evas/Evas_Eo.h
@@ -187,6 +187,27 @@ struct _Efl_Canvas_Object_Animation_Event
187 187
188#include "canvas/efl_canvas_animation_types.eot.h" 188#include "canvas/efl_canvas_animation_types.eot.h"
189 189
190#include "gesture/efl_canvas_gesture_types.eot.h"
191#include "gesture/efl_canvas_gesture_touch.eo.h"
192#include "gesture/efl_canvas_gesture.eo.h"
193#include "gesture/efl_canvas_gesture_tap.eo.h"
194#include "gesture/efl_canvas_gesture_long_tap.eo.h"
195#include "gesture/efl_canvas_gesture_double_tap.eo.h"
196#include "gesture/efl_canvas_gesture_triple_tap.eo.h"
197#include "gesture/efl_canvas_gesture_momentum.eo.h"
198#include "gesture/efl_canvas_gesture_flick.eo.h"
199#include "gesture/efl_canvas_gesture_zoom.eo.h"
200#include "gesture/efl_canvas_gesture_recognizer.eo.h"
201#include "gesture/efl_canvas_gesture_recognizer_tap.eo.h"
202#include "gesture/efl_canvas_gesture_recognizer_long_tap.eo.h"
203#include "gesture/efl_canvas_gesture_recognizer_double_tap.eo.h"
204#include "gesture/efl_canvas_gesture_recognizer_triple_tap.eo.h"
205#include "gesture/efl_canvas_gesture_recognizer_momentum.eo.h"
206#include "gesture/efl_canvas_gesture_recognizer_flick.eo.h"
207#include "gesture/efl_canvas_gesture_recognizer_zoom.eo.h"
208#include "gesture/efl_canvas_gesture_manager.eo.h"
209#include "gesture/efl_gesture_events.eo.h"
210
190#include "canvas/efl_canvas_object.eo.h" 211#include "canvas/efl_canvas_object.eo.h"
191 212
192#include "canvas/efl_canvas_animation.eo.h" 213#include "canvas/efl_canvas_animation.eo.h"
@@ -442,11 +463,3 @@ typedef void (Evas_Canvas3D_Surface_Func)(Evas_Real *out_x,
442#include "canvas/efl_input_hold.eo.h" 463#include "canvas/efl_input_hold.eo.h"
443#include "canvas/efl_input_interface.eo.h" 464#include "canvas/efl_input_interface.eo.h"
444#include "canvas/efl_input_focus.eo.h" 465#include "canvas/efl_input_focus.eo.h"
445
446# include "gesture/efl_canvas_gesture_types.eot.h"
447# include "gesture/efl_canvas_gesture_touch.eo.h"
448# include "gesture/efl_canvas_gesture.eo.h"
449# include "gesture/efl_canvas_gesture_tap.eo.h"
450# include "gesture/efl_canvas_gesture_long_tap.eo.h"
451# include "gesture/efl_canvas_gesture_recognizer.eo.h"
452# include "gesture/efl_canvas_gesture_manager.eo.h"
diff --git a/src/lib/evas/canvas/efl_canvas_object.eo b/src/lib/evas/canvas/efl_canvas_object.eo
index 9a5f89dbe8..6cd64ea713 100644
--- a/src/lib/evas/canvas/efl_canvas_object.eo
+++ b/src/lib/evas/canvas/efl_canvas_object.eo
@@ -8,7 +8,7 @@ struct Efl.Event_Animator_Tick {
8 8
9abstract Efl.Canvas.Object extends Efl.Loop_Consumer implements Efl.Gfx.Entity, Efl.Gfx.Color, Efl.Gfx.Stack, 9abstract Efl.Canvas.Object extends Efl.Loop_Consumer implements Efl.Gfx.Entity, Efl.Gfx.Color, Efl.Gfx.Stack,
10 Efl.Input.Interface, Efl.Gfx.Hint, 10 Efl.Input.Interface, Efl.Gfx.Hint,
11 Efl.Gfx.Mapping, Efl.Ui.I18n, Efl.Canvas.Pointer 11 Efl.Gfx.Mapping, Efl.Ui.I18n, Efl.Canvas.Pointer, Efl.Gesture.Events
12{ 12{
13 [[Efl canvas object abstract class 13 [[Efl canvas object abstract class
14 14
@@ -494,6 +494,10 @@ abstract Efl.Canvas.Object extends Efl.Loop_Consumer implements Efl.Gfx.Entity,
494 return: bool; [[$true if the coords are inside the object, $false otherwise]] 494 return: bool; [[$true if the coords are inside the object, $false otherwise]]
495 } 495 }
496 } 496 }
497 gesture_manager_get @beta {
498 [[Returns current canvas's gesture manager]]
499 return: const(Efl.Canvas.Gesture_Manager); [[The gesture manager]]
500 }
497 } 501 }
498 implements { 502 implements {
499 Efl.Object.constructor; 503 Efl.Object.constructor;
diff --git a/src/lib/evas/canvas/evas_callbacks.c b/src/lib/evas/canvas/evas_callbacks.c
index dcd3338dd6..0e9be65f05 100644
--- a/src/lib/evas/canvas/evas_callbacks.c
+++ b/src/lib/evas/canvas/evas_callbacks.c
@@ -811,8 +811,7 @@ _check_event_catcher_add(void *data, const Efl_Event *event)
811 811
812 for (i = 0; array[i].desc != NULL; i++) 812 for (i = 0; array[i].desc != NULL; i++)
813 { 813 {
814 if (obj->layer->evas->gesture_manager && 814 if (obj->layer->evas->gesture_manager)
815 _efl_canvas_gesture_manager_watches(array[i].desc))
816 { 815 {
817 if (!gd) gd = _efl_canvas_gesture_manager_private_data_get(obj->layer->evas->gesture_manager); 816 if (!gd) gd = _efl_canvas_gesture_manager_private_data_get(obj->layer->evas->gesture_manager);
818 817
@@ -853,8 +852,7 @@ _check_event_catcher_del(void *data, const Efl_Event *event)
853 852
854 for (i = 0; array[i].desc != NULL; i++) 853 for (i = 0; array[i].desc != NULL; i++)
855 { 854 {
856 if (obj->layer->evas->gesture_manager && 855 if (obj->layer->evas->gesture_manager)
857 _efl_canvas_gesture_manager_watches(array[i].desc))
858 { 856 {
859 if (!gd) gd = _efl_canvas_gesture_manager_private_data_get(obj->layer->evas->gesture_manager); 857 if (!gd) gd = _efl_canvas_gesture_manager_private_data_get(obj->layer->evas->gesture_manager);
860 858
diff --git a/src/lib/evas/canvas/evas_object_main.c b/src/lib/evas/canvas/evas_object_main.c
index 07193790ba..35556cbf77 100644
--- a/src/lib/evas/canvas/evas_object_main.c
+++ b/src/lib/evas/canvas/evas_object_main.c
@@ -258,6 +258,15 @@ end:
258 return efl_finalize(efl_super(eo_obj, MY_CLASS)); 258 return efl_finalize(efl_super(eo_obj, MY_CLASS));
259} 259}
260 260
261EOLIAN const Efl_Canvas_Gesture_Manager *
262_efl_canvas_object_gesture_manager_get(Eo *eo_obj EINA_UNUSED, Evas_Object_Protected_Data *pd)
263{
264 if (!pd->layer || !pd->layer->evas)
265 return NULL;
266
267 return (pd->layer->evas)->gesture_manager;
268}
269
261void 270void
262evas_object_change_reset(Evas_Object_Protected_Data *obj) 271evas_object_change_reset(Evas_Object_Protected_Data *obj)
263{ 272{
diff --git a/src/lib/evas/gesture/efl_canvas_gesture.c b/src/lib/evas/gesture/efl_canvas_gesture.c
index 7386a90396..9017f822b5 100644
--- a/src/lib/evas/gesture/efl_canvas_gesture.c
+++ b/src/lib/evas/gesture/efl_canvas_gesture.c
@@ -21,16 +21,29 @@ _efl_canvas_gesture_state_set(Eo *obj EINA_UNUSED, Efl_Canvas_Gesture_Data *pd,
21} 21}
22 22
23EOLIAN static void 23EOLIAN static void
24_efl_canvas_gesture_hotspot_set(Eo *obj EINA_UNUSED, Efl_Canvas_Gesture_Data *pd, Eina_Vector2 hotspot) 24_efl_canvas_gesture_hotspot_set(Eo *obj EINA_UNUSED, Efl_Canvas_Gesture_Data *pd, Eina_Position2D hotspot)
25{ 25{
26 pd->hotspot = hotspot; 26 pd->hotspot = hotspot;
27} 27}
28 28
29 29
30EOLIAN static Eina_Vector2 30EOLIAN static Eina_Position2D
31_efl_canvas_gesture_hotspot_get(const Eo *obj EINA_UNUSED, Efl_Canvas_Gesture_Data *pd) 31_efl_canvas_gesture_hotspot_get(const Eo *obj EINA_UNUSED, Efl_Canvas_Gesture_Data *pd)
32{ 32{
33 return pd->hotspot; 33 return pd->hotspot;
34} 34}
35 35
36#include "efl_canvas_gesture.eo.c" \ No newline at end of file 36EOLIAN static void
37_efl_canvas_gesture_timestamp_set(Eo *obj EINA_UNUSED, Efl_Canvas_Gesture_Data *pd, unsigned int timestamp)
38{
39 pd->timestamp = timestamp;
40}
41
42
43EOLIAN static unsigned int
44_efl_canvas_gesture_timestamp_get(const Eo *obj EINA_UNUSED, Efl_Canvas_Gesture_Data *pd)
45{
46 return pd->timestamp;
47}
48
49#include "efl_canvas_gesture.eo.c"
diff --git a/src/lib/evas/gesture/efl_canvas_gesture.eo b/src/lib/evas/gesture/efl_canvas_gesture.eo
index eafb1d983a..2a097d5fad 100644
--- a/src/lib/evas/gesture/efl_canvas_gesture.eo
+++ b/src/lib/evas/gesture/efl_canvas_gesture.eo
@@ -2,7 +2,13 @@ import efl_canvas_gesture_types;
2 2
3abstract @beta Efl.Canvas.Gesture extends Efl.Object 3abstract @beta Efl.Canvas.Gesture extends Efl.Object
4{ 4{
5 [[EFL Gesture abstract class]] 5 [[EFL Gesture abstract class
6
7 A gesture class defines a method that spcific gesture event and privides information
8 about the gesture's type, state, and associated pointer information.
9
10 For cetain gesture types, additional methods are defined to provide meaningful gesture
11 information to the user.]]
6 c_prefix: efl_gesture; 12 c_prefix: efl_gesture;
7 methods { 13 methods {
8 @property type { 14 @property type {
@@ -30,7 +36,17 @@ abstract @beta Efl.Canvas.Gesture extends Efl.Object
30 set { 36 set {
31 } 37 }
32 values { 38 values {
33 hotspot: Eina.Vector2;[[hotspot co-ordinate]] 39 hotspot: Eina.Position2D;[[hotspot co-ordinate]]
40 }
41 }
42 @property timestamp {
43 [[This property holds the timestamp of the current gesture.]]
44 get {
45 }
46 set {
47 }
48 values {
49 timestamp: uint;[[The timestamp]]
34 } 50 }
35 } 51 }
36 } 52 }
diff --git a/src/lib/evas/gesture/efl_canvas_gesture_double_tap.c b/src/lib/evas/gesture/efl_canvas_gesture_double_tap.c
new file mode 100644
index 0000000000..971d49e3b6
--- /dev/null
+++ b/src/lib/evas/gesture/efl_canvas_gesture_double_tap.c
@@ -0,0 +1,18 @@
1#include "efl_canvas_gesture_private.h"
2
3#define MY_CLASS EFL_CANVAS_GESTURE_DOUBLE_TAP_CLASS
4
5EOLIAN static Efl_Object *
6_efl_canvas_gesture_double_tap_efl_object_constructor(Eo *obj, void *pd EINA_UNUSED)
7{
8 Efl_Canvas_Gesture_Data *gd;
9
10 obj = efl_constructor(efl_super(obj, MY_CLASS));
11
12 gd = efl_data_scope_get(obj, EFL_CANVAS_GESTURE_CLASS);
13 gd->type = EFL_EVENT_GESTURE_DOUBLE_TAP;
14
15 return obj;
16}
17
18#include "efl_canvas_gesture_double_tap.eo.c"
diff --git a/src/lib/evas/gesture/efl_canvas_gesture_double_tap.eo b/src/lib/evas/gesture/efl_canvas_gesture_double_tap.eo
new file mode 100644
index 0000000000..39d84b86f2
--- /dev/null
+++ b/src/lib/evas/gesture/efl_canvas_gesture_double_tap.eo
@@ -0,0 +1,9 @@
1class @beta Efl.Canvas.Gesture_Double_Tap extends Efl.Canvas.Gesture
2{
3 [[EFL Gesture Double Tap class]]
4 data: null;
5 c_prefix: efl_gesture_double_tap;
6 implements {
7 Efl.Object.constructor;
8 }
9}
diff --git a/src/lib/evas/gesture/efl_canvas_gesture_flick.c b/src/lib/evas/gesture/efl_canvas_gesture_flick.c
new file mode 100644
index 0000000000..1095a84652
--- /dev/null
+++ b/src/lib/evas/gesture/efl_canvas_gesture_flick.c
@@ -0,0 +1,30 @@
1#include "efl_canvas_gesture_private.h"
2
3#define MY_CLASS EFL_CANVAS_GESTURE_FLICK_CLASS
4
5EOLIAN static Efl_Object *
6_efl_canvas_gesture_flick_efl_object_constructor(Eo *obj, Efl_Canvas_Gesture_Flick_Data *pd EINA_UNUSED)
7{
8 Efl_Canvas_Gesture_Data *gd;
9
10 obj = efl_constructor(efl_super(obj, MY_CLASS));
11
12 gd = efl_data_scope_get(obj, EFL_CANVAS_GESTURE_CLASS);
13 gd->type = EFL_EVENT_GESTURE_FLICK;
14
15 return obj;
16}
17
18EOLIAN static Eina_Vector2
19_efl_canvas_gesture_flick_momentum_get(Eo *obj EINA_UNUSED, Efl_Canvas_Gesture_Flick_Data *pd)
20{
21 return pd->momentum;
22}
23
24EOLIAN static double
25_efl_canvas_gesture_flick_angle_get(Eo *obj EINA_UNUSED, Efl_Canvas_Gesture_Flick_Data *pd)
26{
27 return pd->angle;
28}
29
30#include "efl_canvas_gesture_flick.eo.c"
diff --git a/src/lib/evas/gesture/efl_canvas_gesture_flick.eo b/src/lib/evas/gesture/efl_canvas_gesture_flick.eo
new file mode 100644
index 0000000000..7e87c55f71
--- /dev/null
+++ b/src/lib/evas/gesture/efl_canvas_gesture_flick.eo
@@ -0,0 +1,20 @@
1import eina_types;
2
3class @beta Efl.Canvas.Gesture_Flick extends Efl.Canvas.Gesture
4{
5 [[EFL Gesture Flick class]]
6 c_prefix: efl_gesture_flick;
7 methods {
8 momentum_get {
9 [[Gets flick gesture momentum value]]
10 return: Eina.Vector2; [[The momentum vector]]
11 }
12 angle_get {
13 [[Gets flick direction angle]]
14 return: double; [[The angle value]]
15 }
16 }
17 implements {
18 Efl.Object.constructor;
19 }
20}
diff --git a/src/lib/evas/gesture/efl_canvas_gesture_long_tap.c b/src/lib/evas/gesture/efl_canvas_gesture_long_tap.c
index 099893a58e..21f0055414 100644
--- a/src/lib/evas/gesture/efl_canvas_gesture_long_tap.c
+++ b/src/lib/evas/gesture/efl_canvas_gesture_long_tap.c
@@ -2,9 +2,8 @@
2 2
3#define MY_CLASS EFL_CANVAS_GESTURE_LONG_TAP_CLASS 3#define MY_CLASS EFL_CANVAS_GESTURE_LONG_TAP_CLASS
4 4
5
6EOLIAN static Efl_Object * 5EOLIAN static Efl_Object *
7_efl_canvas_gesture_long_tap_efl_object_constructor(Eo *obj, Efl_Canvas_Gesture_Long_Tap_Data *pd EINA_UNUSED) 6_efl_canvas_gesture_long_tap_efl_object_constructor(Eo *obj, void *pd EINA_UNUSED)
8{ 7{
9 Efl_Canvas_Gesture_Data *gd; 8 Efl_Canvas_Gesture_Data *gd;
10 9
@@ -16,11 +15,8 @@ _efl_canvas_gesture_long_tap_efl_object_constructor(Eo *obj, Efl_Canvas_Gesture_
16} 15}
17 16
18EOLIAN static void 17EOLIAN static void
19_efl_canvas_gesture_long_tap_efl_object_destructor(Eo *obj, Efl_Canvas_Gesture_Long_Tap_Data *pd) 18_efl_canvas_gesture_long_tap_efl_object_destructor(Eo *obj, void *pd EINA_UNUSED)
20{ 19{
21 if (pd->timeout)
22 ecore_timer_del(pd->timeout);
23
24 efl_destructor(efl_super(obj, MY_CLASS)); 20 efl_destructor(efl_super(obj, MY_CLASS));
25} 21}
26 22
diff --git a/src/lib/evas/gesture/efl_canvas_gesture_long_tap.eo b/src/lib/evas/gesture/efl_canvas_gesture_long_tap.eo
index 1a690b0d65..79c5c6d0e6 100644
--- a/src/lib/evas/gesture/efl_canvas_gesture_long_tap.eo
+++ b/src/lib/evas/gesture/efl_canvas_gesture_long_tap.eo
@@ -1,11 +1,8 @@
1class @beta Efl.Canvas.Gesture_Long_Tap extends Efl.Canvas.Gesture 1class @beta Efl.Canvas.Gesture_Long_Tap extends Efl.Canvas.Gesture
2{ 2{
3 [[EFL Gesture Long Tap class]] 3 [[EFL Gesture Long Tap class]]
4 data: null;
4 c_prefix: efl_gesture_long_tap; 5 c_prefix: efl_gesture_long_tap;
5 event_prefix: efl;
6 events {
7 gesture,long_tap: Efl.Canvas.Gesture; [[Event for tap gesture]]
8 }
9 implements { 6 implements {
10 Efl.Object.constructor; 7 Efl.Object.constructor;
11 Efl.Object.destructor; 8 Efl.Object.destructor;
diff --git a/src/lib/evas/gesture/efl_canvas_gesture_manager.c b/src/lib/evas/gesture/efl_canvas_gesture_manager.c
index b174e49b7b..86960046ff 100644
--- a/src/lib/evas/gesture/efl_canvas_gesture_manager.c
+++ b/src/lib/evas/gesture/efl_canvas_gesture_manager.c
@@ -4,25 +4,25 @@
4 4
5typedef struct _Object_Gesture 5typedef struct _Object_Gesture
6{ 6{
7 Eo *object; 7 Eo *object;
8 const Efl_Event_Description *type; 8 const Efl_Event_Description *type;
9 Efl_Canvas_Gesture *gesture; 9 Efl_Canvas_Gesture *gesture;
10 Efl_Canvas_Gesture_Recognizer *recognizer; 10 Efl_Canvas_Gesture_Recognizer *recognizer;
11}Object_Gesture; 11} Object_Gesture;
12 12
13typedef struct _Efl_Canvas_Gesture_Manager_Data 13typedef struct _Efl_Canvas_Gesture_Manager_Data
14{ 14{
15 // keeps track of all the gesture request for a particular target 15 //Keeps track of all the gesture request for a particular target
16 Eina_Hash *m_gesture_contex; // (*target, *event_desc) 16 Eina_Hash *m_gesture_contex; // (*target, *event_desc)
17 // keeps all the event directed to this particular object from touch_begin till touch_end 17 //Keeps all the event directed to this particular object from touch_begin till touch_end
18 Eina_Hash *m_object_events; // (*target, *efl_gesture_touch) 18 Eina_Hash *m_object_events; // (*target, *efl_gesture_touch)
19 // keeps all the recognizer registered to gesture manager 19 //Keeps all the recognizer registered to gesture manager
20 Eina_Hash *m_recognizers; // (*gesture_type, *recognizer) 20 Eina_Hash *m_recognizers; // (*gesture_type, *recognizer)
21 // keeps track of all current object gestures. 21 //Keeps track of all current object gestures.
22 Eina_List *m_object_gestures; //(List of *object_gesture) 22 Eina_List *m_object_gestures; //(List of *object_gesture)
23 // lazy deletion of gestures 23 //Lazy deletion of gestures
24 Eina_List *m_gestures_to_delete; 24 Eina_List *m_gestures_to_delete;
25 25 //Kepps config values for gesture recognize
26 Eina_Hash *m_config; 26 Eina_Hash *m_config;
27} Efl_Canvas_Gesture_Manager_Data; 27} Efl_Canvas_Gesture_Manager_Data;
28 28
@@ -65,13 +65,18 @@ _efl_canvas_gesture_manager_efl_object_constructor(Eo *obj, Efl_Canvas_Gesture_M
65 65
66 pd->m_config = eina_hash_string_superfast_new(EINA_FREE_CB(eina_value_free)); 66 pd->m_config = eina_hash_string_superfast_new(EINA_FREE_CB(eina_value_free));
67 67
68 //Register all types of recognizers at very first time.
68 efl_gesture_manager_recognizer_register(obj, efl_add(EFL_CANVAS_GESTURE_RECOGNIZER_TAP_CLASS, obj)); 69 efl_gesture_manager_recognizer_register(obj, efl_add(EFL_CANVAS_GESTURE_RECOGNIZER_TAP_CLASS, obj));
69 efl_gesture_manager_recognizer_register(obj, efl_add(EFL_CANVAS_GESTURE_RECOGNIZER_LONG_TAP_CLASS, obj)); 70 efl_gesture_manager_recognizer_register(obj, efl_add(EFL_CANVAS_GESTURE_RECOGNIZER_LONG_TAP_CLASS, obj));
71 efl_gesture_manager_recognizer_register(obj, efl_add(EFL_CANVAS_GESTURE_RECOGNIZER_DOUBLE_TAP_CLASS, obj));
72 efl_gesture_manager_recognizer_register(obj, efl_add(EFL_CANVAS_GESTURE_RECOGNIZER_TRIPLE_TAP_CLASS, obj));
73 efl_gesture_manager_recognizer_register(obj, efl_add(EFL_CANVAS_GESTURE_RECOGNIZER_MOMENTUM_CLASS, obj));
74 efl_gesture_manager_recognizer_register(obj, efl_add(EFL_CANVAS_GESTURE_RECOGNIZER_FLICK_CLASS, obj));
75 efl_gesture_manager_recognizer_register(obj, efl_add(EFL_CANVAS_GESTURE_RECOGNIZER_ZOOM_CLASS, obj));
70 76
71 return obj; 77 return obj;
72} 78}
73 79
74
75EOLIAN static Eina_Value * 80EOLIAN static Eina_Value *
76_efl_canvas_gesture_manager_config_get(const Eo *obj EINA_UNUSED, Efl_Canvas_Gesture_Manager_Data *pd, const char *name) 81_efl_canvas_gesture_manager_config_get(const Eo *obj EINA_UNUSED, Efl_Canvas_Gesture_Manager_Data *pd, const char *name)
77{ 82{
@@ -84,6 +89,22 @@ _efl_canvas_gesture_manager_config_set(Eo *obj EINA_UNUSED, Efl_Canvas_Gesture_M
84 Eina_Value *v = eina_value_new(eina_value_type_get(value)); 89 Eina_Value *v = eina_value_new(eina_value_type_get(value));
85 eina_value_copy(value, v); 90 eina_value_copy(value, v);
86 eina_hash_add(pd->m_config, name, v); 91 eina_hash_add(pd->m_config, name, v);
92
93 //Sets recognizer class property.
94 if (!strcmp(name, "glayer_tap_finger_size"))
95 {
96 int finger_size;
97 Efl_Canvas_Gesture_Recognizer *r;
98 Efl_Canvas_Gesture_Recognizer_Data *rd;
99
100 eina_value_get(value, &finger_size);
101
102 const Efl_Event_Description *type = EFL_EVENT_GESTURE_TAP;
103
104 r = eina_hash_find(pd->m_recognizers, &type);
105 rd = efl_data_scope_get(r, EFL_CANVAS_GESTURE_RECOGNIZER_CLASS);
106 rd->finger_size = finger_size;
107 }
87} 108}
88 109
89EOLIAN static void 110EOLIAN static void
@@ -109,11 +130,11 @@ void
109_efl_canvas_gesture_manager_callback_add_hook(void *data, Eo *target, const Efl_Event_Description *type) 130_efl_canvas_gesture_manager_callback_add_hook(void *data, Eo *target, const Efl_Event_Description *type)
110{ 131{
111 Efl_Canvas_Gesture_Manager_Data *pd = data; 132 Efl_Canvas_Gesture_Manager_Data *pd = data;
112 // if there is a recognizer registered for that event then add it to the gesture context 133 //If there is a recognizer registered for that event then add it to the gesture context
113 Efl_Canvas_Gesture_Recognizer *recognizer = eina_hash_find (pd->m_recognizers, &type); 134 Efl_Canvas_Gesture_Recognizer *recognizer = eina_hash_find (pd->m_recognizers, &type);
114 if (recognizer) 135 if (recognizer)
115 { 136 {
116 // add it to the gesture context. 137 //Add it to the gesture context.
117 eina_hash_list_append(pd->m_gesture_contex, &target, type); 138 eina_hash_list_append(pd->m_gesture_contex, &target, type);
118 } 139 }
119} 140}
@@ -122,7 +143,7 @@ void
122_efl_canvas_gesture_manager_callback_del_hook(void *data, Eo *target, const Efl_Event_Description *type) 143_efl_canvas_gesture_manager_callback_del_hook(void *data, Eo *target, const Efl_Event_Description *type)
123{ 144{
124 Efl_Canvas_Gesture_Manager_Data *pd = data; 145 Efl_Canvas_Gesture_Manager_Data *pd = data;
125 // if there is a recognizer registered for that event then add it to the gesture context 146 //If there is a recognizer registered for that event then add it to the gesture context
126 Efl_Canvas_Gesture_Recognizer *recognizer = eina_hash_find (pd->m_recognizers, &type); 147 Efl_Canvas_Gesture_Recognizer *recognizer = eina_hash_find (pd->m_recognizers, &type);
127 if (recognizer) 148 if (recognizer)
128 { 149 {
@@ -148,28 +169,39 @@ _efl_canvas_gesture_manager_filter_event(Eo *obj, Eo *target, void *event)
148 gesture_context = eina_hash_find(pd->m_gesture_contex, &target); 169 gesture_context = eina_hash_find(pd->m_gesture_contex, &target);
149 if (gesture_context) 170 if (gesture_context)
150 { 171 {
151 // get the touch event for this particular widget 172 EINA_LIST_FOREACH(gesture_context, l, gesture_type)
152 touch_event = eina_hash_find(pd->m_object_events, &target);
153 if (!touch_event)
154 { 173 {
155 touch_event = efl_add_ref(EFL_CANVAS_GESTURE_TOUCH_CLASS, NULL); 174 //Check there is already created event exist or not.
156 eina_hash_add(pd->m_object_events, &target, touch_event); 175 touch_event = eina_hash_find(pd->m_object_events, &gesture_type);
157 }
158 176
159 efl_gesture_touch_point_record(touch_event, pointer_data->tool, pointer_data->cur, 177 if (!touch_event)
160 pointer_data->timestamp, pointer_data->action); 178 {
179 touch_event = efl_add_ref(EFL_CANVAS_GESTURE_TOUCH_CLASS, NULL);
180 eina_hash_add(pd->m_object_events, &gesture_type, touch_event);
181 }
161 182
162 if (efl_gesture_touch_state_get(touch_event) == EFL_GESTURE_TOUCH_UNKNOWN) 183 efl_gesture_touch_point_record(touch_event, pointer_data->tool, pointer_data->cur,
163 return; 184 pointer_data->timestamp, pointer_data->action);
185
186 //This is for handling the case that mouse event pairs dont match.
187 //Such as the case of canceling gesture recognition after a mouse down.
188 if (efl_gesture_touch_state_get(touch_event) == EFL_GESTURE_TOUCH_UNKNOWN)
189 continue;
164 190
165 EINA_LIST_FOREACH(gesture_context, l, gesture_type)
166 {
167 recognizer = eina_hash_find(pd->m_recognizers, &gesture_type); 191 recognizer = eina_hash_find(pd->m_recognizers, &gesture_type);
192
193 //If the gesture canceled or already finished by recognizer.
168 gesture = _get_state(pd, target, recognizer, gesture_type); 194 gesture = _get_state(pd, target, recognizer, gesture_type);
169 if (!gesture) 195 if (!gesture)
170 continue; 196 continue;
197
198 //Gesture detecting.
171 recog_result = efl_gesture_recognizer_recognize(recognizer, gesture, target, touch_event); 199 recog_result = efl_gesture_recognizer_recognize(recognizer, gesture, target, touch_event);
172 recog_state = recog_result & EFL_GESTURE_RESULT_MASK; 200 recog_state = recog_result & EFL_GESTURE_RESULT_MASK;
201
202 Efl_Canvas_Gesture_Recognizer_Data *rd =
203 efl_data_scope_get(recognizer, EFL_CANVAS_GESTURE_RECOGNIZER_CLASS);
204
173 if (recog_state == EFL_GESTURE_TRIGGER) 205 if (recog_state == EFL_GESTURE_TRIGGER)
174 { 206 {
175 if (efl_gesture_state_get(gesture) == EFL_GESTURE_NONE) 207 if (efl_gesture_state_get(gesture) == EFL_GESTURE_NONE)
@@ -188,53 +220,57 @@ _efl_canvas_gesture_manager_filter_event(Eo *obj, Eo *target, void *event)
188 else if (recog_state == EFL_GESTURE_CANCEL) 220 else if (recog_state == EFL_GESTURE_CANCEL)
189 { 221 {
190 if (efl_gesture_state_get(gesture) != EFL_GESTURE_NONE) 222 if (efl_gesture_state_get(gesture) != EFL_GESTURE_NONE)
223 efl_gesture_state_set(gesture, EFL_GESTURE_CANCELED);
224 else
191 { 225 {
192 efl_gesture_state_set(gesture, EFL_GESTURE_CANCELED); 226 //Need to recognize events that occur consecutively
227 //in a mouse-down state.
228 if (rd->continues)
229 continue;
193 } 230 }
194 else
195 continue;
196 } 231 }
197 else if (recog_state == EFL_GESTURE_IGNORE) 232 else if (recog_state == EFL_GESTURE_IGNORE)
198 { 233 {
199 continue; 234 continue;
200 } 235 }
236
237 efl_gesture_timestamp_set(gesture, efl_gesture_touch_cur_timestamp_get(touch_event));
201 efl_event_callback_call(target, gesture_type, gesture); 238 efl_event_callback_call(target, gesture_type, gesture);
202 }
203 239
204 if (efl_gesture_touch_state_get(touch_event) == EFL_GESTURE_TOUCH_END) 240 //If the current event recognizes the gesture continuously, dont delete gesture.
205 { 241 if (((recog_state == EFL_GESTURE_FINISH) || (recog_state == EFL_GESTURE_CANCEL)) &&
206 EINA_LIST_FOREACH(gesture_context, l, gesture_type) 242 !rd->continues)
207 _cleanup_cached_gestures(pd, target, gesture_type); 243 {
244 _cleanup_cached_gestures(pd, target, gesture_type);
245 eina_hash_del(pd->m_object_events, &gesture_type, NULL);
246 //FIXME: delete it by object not list.
247 _cleanup_object(pd->m_gestures_to_delete);
248 pd->m_gestures_to_delete = NULL;
208 249
209 eina_hash_del(pd->m_object_events, &target, NULL); 250 }
210 // free gesture_to_delete list
211 _cleanup_object(pd->m_gestures_to_delete);
212 pd->m_gestures_to_delete = NULL;
213 } 251 }
214 } 252 }
215} 253}
216 254
217EOLIAN static const Efl_Event_Description * 255EOLIAN static void
218_efl_canvas_gesture_manager_recognizer_register(Eo *obj EINA_UNUSED, Efl_Canvas_Gesture_Manager_Data *pd, 256_efl_canvas_gesture_manager_recognizer_register(Eo *obj EINA_UNUSED, Efl_Canvas_Gesture_Manager_Data *pd,
219 Efl_Canvas_Gesture_Recognizer *recognizer) 257 Efl_Canvas_Gesture_Recognizer *recognizer)
220{ 258{
221 Efl_Canvas_Gesture_Recognizer_Data *rpd; 259 Efl_Canvas_Gesture_Recognizer_Data *rpd;
222 Efl_Canvas_Gesture *dummy = efl_gesture_recognizer_create(recognizer, 0); 260 Efl_Canvas_Gesture *dummy = efl_gesture_recognizer_add(recognizer, NULL);
223 261
224 if (!dummy) 262 if (!dummy)
225 return NULL; 263 return;
226 264
227 const Efl_Event_Description *type = efl_gesture_type_get(dummy); 265 const Efl_Event_Description *type = efl_gesture_type_get(dummy);
228 266
229 // Add the recognizer to the m_recognizers 267 //Add the recognizer to the m_recognizers
230 eina_hash_add(pd->m_recognizers, &type, efl_ref(recognizer)); 268 eina_hash_add(pd->m_recognizers, &type, efl_ref(recognizer));
231 // update the manager 269 //Update the manager
232 rpd = efl_data_scope_get(recognizer, EFL_CANVAS_GESTURE_RECOGNIZER_CLASS); 270 rpd = efl_data_scope_get(recognizer, EFL_CANVAS_GESTURE_RECOGNIZER_CLASS);
233 rpd->manager = obj; 271 rpd->manager = obj;
234 272
235 efl_del(dummy); 273 efl_del(dummy);
236
237 return type;
238} 274}
239 275
240EOLIAN static void 276EOLIAN static void
@@ -248,19 +284,19 @@ _efl_canvas_gesture_manager_recognizer_unregister(Eo *obj EINA_UNUSED, Efl_Canva
248 284
249 if (!recognizer) return; 285 if (!recognizer) return;
250 286
251 // find the type of the recognizer 287 //Find the type of the recognizer
252 dummy = efl_gesture_recognizer_create(recognizer, 0); 288 dummy = efl_gesture_recognizer_add(recognizer, 0);
253 if (!dummy)return; 289 if (!dummy)return;
254 290
255 type = efl_gesture_type_get(dummy); 291 type = efl_gesture_type_get(dummy);
256 efl_del(dummy); 292 efl_del(dummy);
257 293
258 // check if its already registered 294 //Check if its already registered
259 recognizer = eina_hash_find(pd->m_recognizers, &type); 295 recognizer = eina_hash_find(pd->m_recognizers, &type);
260 296
261 if (!recognizer) return; 297 if (!recognizer) return;
262 298
263 // remove that gesture from the list of object gestures 299 //Remove that gesture from the list of object gestures
264 EINA_LIST_FOREACH_SAFE(pd->m_object_gestures, l, l_next, object_gesture) 300 EINA_LIST_FOREACH_SAFE(pd->m_object_gestures, l, l_next, object_gesture)
265 { 301 {
266 if (object_gesture->type == type) 302 if (object_gesture->type == type)
@@ -270,9 +306,71 @@ _efl_canvas_gesture_manager_recognizer_unregister(Eo *obj EINA_UNUSED, Efl_Canva
270 pd->m_object_gestures = eina_list_remove_list(pd->m_object_gestures, l); 306 pd->m_object_gestures = eina_list_remove_list(pd->m_object_gestures, l);
271 } 307 }
272 } 308 }
309
273 eina_hash_del(pd->m_recognizers, &type, NULL); 310 eina_hash_del(pd->m_recognizers, &type, NULL);
274} 311}
275 312
313static Efl_Canvas_Gesture_Recognizer *
314_find_match_recognizer(Efl_Canvas_Gesture_Manager_Data *pd, Efl_Canvas_Gesture_Recognizer_Type type)
315{
316 const Efl_Event_Description *event_type;
317
318 switch (type)
319 {
320 case EFL_GESTURE_TAP:
321 {
322 event_type = EFL_EVENT_GESTURE_TAP;
323 break;
324 }
325 case EFL_GESTURE_DOUBLETAP:
326 {
327 event_type = EFL_EVENT_GESTURE_DOUBLE_TAP;
328 break;
329 }
330 case EFL_GESTURE_TRIPLETAP:
331 {
332 event_type = EFL_EVENT_GESTURE_TRIPLE_TAP;
333 break;
334 }
335 case EFL_GESTURE_LONGTAP:
336 {
337 event_type = EFL_EVENT_GESTURE_LONG_TAP;
338 break;
339 }
340 case EFL_GESTURE_MOMENTUM:
341 {
342 event_type = EFL_EVENT_GESTURE_MOMENTUM;
343 break;
344 }
345 case EFL_GESTURE_FLICK:
346 {
347 event_type = EFL_EVENT_GESTURE_FLICK;
348 break;
349 }
350 case EFL_GESTURE_ZOOM:
351 {
352 event_type = EFL_EVENT_GESTURE_ZOOM;
353 break;
354 }
355 default:
356 return NULL;
357 }
358
359 return eina_hash_find(pd->m_recognizers, &event_type);
360}
361
362EOLIAN static const Efl_Canvas_Gesture_Recognizer *
363_efl_canvas_gesture_manager_recognizer_get(Eo *obj EINA_UNUSED, Efl_Canvas_Gesture_Manager_Data *pd,
364 Efl_Canvas_Gesture_Recognizer_Type type)
365{
366 Efl_Canvas_Gesture_Recognizer *recognizer = _find_match_recognizer(pd, type);
367
368 if (recognizer)
369 return recognizer;
370 else
371 return NULL;
372}
373
276// EOLIAN static void 374// EOLIAN static void
277// _efl_canvas_gesture_manager_ungrab_all(Eo *obj EINA_UNUSED, Efl_Canvas_Gesture_Manager_Data *pd, 375// _efl_canvas_gesture_manager_ungrab_all(Eo *obj EINA_UNUSED, Efl_Canvas_Gesture_Manager_Data *pd,
278// Eo *target) 376// Eo *target)
@@ -291,7 +389,7 @@ _efl_canvas_gesture_manager_recognizer_unregister(Eo *obj EINA_UNUSED, Efl_Canva
291// eina_hash_del(pd->m_gesture_contex, &target, NULL); 389// eina_hash_del(pd->m_gesture_contex, &target, NULL);
292// } 390// }
293 391
294// get or create a gesture object that will represent the state for a given object, used by the recognizer 392//Get or create a gesture object that will represent the state for a given object, used by the recognizer
295Efl_Canvas_Gesture* 393Efl_Canvas_Gesture*
296_get_state(Efl_Canvas_Gesture_Manager_Data *pd, 394_get_state(Efl_Canvas_Gesture_Manager_Data *pd,
297 Eo *target, Efl_Canvas_Gesture_Recognizer *recognizer, const Efl_Event_Description *type) 395 Eo *target, Efl_Canvas_Gesture_Recognizer *recognizer, const Efl_Event_Description *type)
@@ -299,9 +397,11 @@ _get_state(Efl_Canvas_Gesture_Manager_Data *pd,
299 Eina_List *l; 397 Eina_List *l;
300 Object_Gesture *object_gesture; 398 Object_Gesture *object_gesture;
301 Efl_Canvas_Gesture *gesture; 399 Efl_Canvas_Gesture *gesture;
400 Efl_Canvas_Gesture_Recognizer_Data *rd =
401 efl_data_scope_get(recognizer, EFL_CANVAS_GESTURE_RECOGNIZER_CLASS);
302 402
303 // if the widget is being deleted we should be careful not to 403 //If the widget is being deleted we should be careful not to
304 // create a new state. 404 //Create a new state.
305 if (efl_destructed_is(target)) 405 if (efl_destructed_is(target))
306 return 0; 406 return 0;
307 407
@@ -310,19 +410,27 @@ _get_state(Efl_Canvas_Gesture_Manager_Data *pd,
310 { 410 {
311 if (object_gesture->object == target && 411 if (object_gesture->object == target &&
312 object_gesture->recognizer == recognizer && 412 object_gesture->recognizer == recognizer &&
313 object_gesture->type == type) 413 object_gesture->type == type)
314 { 414 {
315 // the gesture is already processed waiting for cleanup 415 //The gesture is already processed waiting for cleanup
316 if ((efl_gesture_state_get(object_gesture->gesture) == EFL_GESTURE_FINISHED) || 416 if (((efl_gesture_state_get(object_gesture->gesture) == EFL_GESTURE_FINISHED) ||
317 (efl_gesture_state_get(object_gesture->gesture) == EFL_GESTURE_CANCELED)) 417 (efl_gesture_state_get(object_gesture->gesture) == EFL_GESTURE_CANCELED)) &&
318 return NULL; 418 (!rd->continues))
419 {
420 _cleanup_cached_gestures(pd, target, type);
421 eina_hash_del(pd->m_object_events, &type, NULL);
422 _cleanup_object(pd->m_gestures_to_delete);
423 pd->m_gestures_to_delete = NULL;
424 return NULL;
425 }
319 return object_gesture->gesture; 426 return object_gesture->gesture;
320 } 427 }
321 } 428 }
322 429
323 gesture = efl_gesture_recognizer_create(recognizer, target); 430 gesture = efl_gesture_recognizer_add(recognizer, target);
324 if (!gesture) 431 if (!gesture)
325 return 0; 432 return 0;
433
326 object_gesture = calloc(1, sizeof(Object_Gesture)); 434 object_gesture = calloc(1, sizeof(Object_Gesture));
327 object_gesture->object = target; 435 object_gesture->object = target;
328 object_gesture->recognizer = recognizer; 436 object_gesture->recognizer = recognizer;
@@ -343,7 +451,7 @@ _cleanup_cached_gestures(Efl_Canvas_Gesture_Manager_Data *pd,
343 451
344 EINA_LIST_FOREACH_SAFE(pd->m_object_gestures, l, l_next, object_gesture) 452 EINA_LIST_FOREACH_SAFE(pd->m_object_gestures, l, l_next, object_gesture)
345 { 453 {
346 if ( (object_gesture->type == type) && (target == object_gesture->object)) 454 if ((object_gesture->type == type) && (target == object_gesture->object))
347 { 455 {
348 pd->m_gestures_to_delete = eina_list_append(pd->m_gestures_to_delete, object_gesture->gesture); 456 pd->m_gestures_to_delete = eina_list_append(pd->m_gestures_to_delete, object_gesture->gesture);
349 free(object_gesture); 457 free(object_gesture);
@@ -371,4 +479,15 @@ _efl_canvas_gesture_manager_watches(const Efl_Event_Description *ev)
371 return EINA_FALSE; 479 return EINA_FALSE;
372} 480}
373 481
482void
483efl_gesture_manager_gesture_clean_up(Eo *obj, Eo *target, const Efl_Event_Description *type)
484{
485 Efl_Canvas_Gesture_Manager_Data *pd = efl_data_scope_get(obj, MY_CLASS);
486
487 _cleanup_cached_gestures(pd, target, type);
488 eina_hash_del(pd->m_object_events, &type, NULL);
489 _cleanup_object(pd->m_gestures_to_delete);
490 pd->m_gestures_to_delete = NULL;
491}
492
374#include "efl_canvas_gesture_manager.eo.c" 493#include "efl_canvas_gesture_manager.eo.c"
diff --git a/src/lib/evas/gesture/efl_canvas_gesture_manager.eo b/src/lib/evas/gesture/efl_canvas_gesture_manager.eo
index a39318aea0..d626ca16de 100644
--- a/src/lib/evas/gesture/efl_canvas_gesture_manager.eo
+++ b/src/lib/evas/gesture/efl_canvas_gesture_manager.eo
@@ -8,7 +8,6 @@ class @beta Efl.Canvas.Gesture_Manager extends Efl.Object
8 params { 8 params {
9 @in recognizer: Efl.Canvas.Gesture_Recognizer; [[The gesture recognizer object]] 9 @in recognizer: Efl.Canvas.Gesture_Recognizer; [[The gesture recognizer object]]
10 } 10 }
11 return: ptr(const(Efl.Event_Description)); [[Returns the Efl.Event_Description type the recognizer supports]]
12 } 11 }
13 recognizer_unregister { 12 recognizer_unregister {
14 [[This function is called to unregister a Efl.Canvas.Gesture_Recognizer]] 13 [[This function is called to unregister a Efl.Canvas.Gesture_Recognizer]]
@@ -16,6 +15,13 @@ class @beta Efl.Canvas.Gesture_Manager extends Efl.Object
16 @in recognizer: Efl.Canvas.Gesture_Recognizer; [[The gesture recognizer object]] 15 @in recognizer: Efl.Canvas.Gesture_Recognizer; [[The gesture recognizer object]]
17 } 16 }
18 } 17 }
18 recognizer_get {
19 [[Gets event type's recognizer]]
20 params {
21 @in gesture_type: Efl.Canvas.Gesture_Recognizer_Type; [[The gesture type]]
22 }
23 return: const(Efl.Canvas.Gesture_Recognizer); [[The gesture recognizer]]
24 }
19 @property config { 25 @property config {
20 [[This property holds the config value for the recognizer]] 26 [[This property holds the config value for the recognizer]]
21 set { 27 set {
diff --git a/src/lib/evas/gesture/efl_canvas_gesture_momentum.c b/src/lib/evas/gesture/efl_canvas_gesture_momentum.c
new file mode 100644
index 0000000000..e7eb34ad2b
--- /dev/null
+++ b/src/lib/evas/gesture/efl_canvas_gesture_momentum.c
@@ -0,0 +1,24 @@
1#include "efl_canvas_gesture_private.h"
2
3#define MY_CLASS EFL_CANVAS_GESTURE_MOMENTUM_CLASS
4
5EOLIAN static Efl_Object *
6_efl_canvas_gesture_momentum_efl_object_constructor(Eo *obj, Efl_Canvas_Gesture_Momentum_Data *pd EINA_UNUSED)
7{
8 Efl_Canvas_Gesture_Data *gd;
9
10 obj = efl_constructor(efl_super(obj, MY_CLASS));
11
12 gd = efl_data_scope_get(obj, EFL_CANVAS_GESTURE_CLASS);
13 gd->type = EFL_EVENT_GESTURE_MOMENTUM;
14
15 return obj;
16}
17
18EOLIAN static Eina_Vector2
19_efl_canvas_gesture_momentum_momentum_get(Eo *obj EINA_UNUSED, Efl_Canvas_Gesture_Momentum_Data *pd)
20{
21 return pd->momentum;
22}
23
24#include "efl_canvas_gesture_momentum.eo.c"
diff --git a/src/lib/evas/gesture/efl_canvas_gesture_momentum.eo b/src/lib/evas/gesture/efl_canvas_gesture_momentum.eo
new file mode 100644
index 0000000000..c5aebcb5d2
--- /dev/null
+++ b/src/lib/evas/gesture/efl_canvas_gesture_momentum.eo
@@ -0,0 +1,16 @@
1import eina_types;
2
3class @beta Efl.Canvas.Gesture_Momentum extends Efl.Canvas.Gesture
4{
5 [[EFL Gesture Momentum class]]
6 c_prefix: efl_gesture_momentum;
7 methods {
8 momentum_get {
9 [[Gets momentum value]]
10 return: Eina.Vector2; [[The momentum vector]]
11 }
12 }
13 implements {
14 Efl.Object.constructor;
15 }
16}
diff --git a/src/lib/evas/gesture/efl_canvas_gesture_private.h b/src/lib/evas/gesture/efl_canvas_gesture_private.h
index c09fd26779..e1de45cb78 100644
--- a/src/lib/evas/gesture/efl_canvas_gesture_private.h
+++ b/src/lib/evas/gesture/efl_canvas_gesture_private.h
@@ -6,37 +6,154 @@
6#define EFL_INTERNAL_UNSTABLE 6#define EFL_INTERNAL_UNSTABLE
7#include "interfaces/efl_common_internal.h" 7#include "interfaces/efl_common_internal.h"
8 8
9#include "efl_gesture_events.eo.c"
10
9#include <Ecore.h> 11#include <Ecore.h>
10 12
11//private gesture classes 13void efl_gesture_manager_gesture_clean_up(Eo *obj, Eo *target, const Efl_Event_Description *type);
12#include "efl_canvas_gesture_recognizer_tap.eo.h"
13#include "efl_canvas_gesture_recognizer_long_tap.eo.h"
14 14
15typedef struct _Efl_Canvas_Gesture_Manager_Data Efl_Canvas_Gesture_Manager_Data;
15typedef struct _Efl_Canvas_Gesture_Recognizer_Data Efl_Canvas_Gesture_Recognizer_Data; 16typedef struct _Efl_Canvas_Gesture_Recognizer_Data Efl_Canvas_Gesture_Recognizer_Data;
17typedef struct _Efl_Canvas_Gesture_Recognizer_Tap_Data Efl_Canvas_Gesture_Recognizer_Tap_Data;
18typedef struct _Efl_Canvas_Gesture_Recognizer_Long_Tap_Data Efl_Canvas_Gesture_Recognizer_Long_Tap_Data;
19typedef struct _Efl_Canvas_Gesture_Recognizer_Double_Tap_Data Efl_Canvas_Gesture_Recognizer_Double_Tap_Data;
20typedef struct _Efl_Canvas_Gesture_Recognizer_Triple_Tap_Data Efl_Canvas_Gesture_Recognizer_Triple_Tap_Data;
21typedef struct _Efl_Canvas_Gesture_Recognizer_Momentum_Data Efl_Canvas_Gesture_Recognizer_Momentum_Data;
22typedef struct _Efl_Canvas_Gesture_Recognizer_Flick_Data Efl_Canvas_Gesture_Recognizer_Flick_Data;
23typedef struct _Efl_Canvas_Gesture_Recognizer_Zoom_Data Efl_Canvas_Gesture_Recognizer_Zoom_Data;
16typedef struct _Efl_Canvas_Gesture_Data Efl_Canvas_Gesture_Data; 24typedef struct _Efl_Canvas_Gesture_Data Efl_Canvas_Gesture_Data;
17typedef struct _Efl_Canvas_Gesture_Tap_Data Efl_Canvas_Gesture_Tap_Data; 25typedef struct _Efl_Canvas_Gesture_Momentum_Data Efl_Canvas_Gesture_Momentum_Data;
18typedef struct _Efl_Canvas_Gesture_Long_Tap_Data Efl_Canvas_Gesture_Long_Tap_Data; 26typedef struct _Efl_Canvas_Gesture_Flick_Data Efl_Canvas_Gesture_Flick_Data;
27typedef struct _Efl_Canvas_Gesture_Zoom_Data Efl_Canvas_Gesture_Zoom_Data;
28
29typedef struct _Pointer_Data
30{
31 struct
32 {
33 Eina_Position2D pos;
34 unsigned int timestamp;
35 } start, prev, cur;
36 int id;
37 Efl_Pointer_Action action;
38} Pointer_Data;
39
40typedef struct _Efl_Canvas_Gesture_Touch_Data
41{
42 Efl_Canvas_Gesture_Touch_State state;
43 Eina_Hash *touch_points;
44 int touch_down;
45 Eina_Bool multi_touch;
46 Eo *target;
47} Efl_Canvas_Gesture_Touch_Data;
19 48
20struct _Efl_Canvas_Gesture_Recognizer_Data 49struct _Efl_Canvas_Gesture_Recognizer_Data
21{ 50{
22 Eo *manager; // keeps a reference of the manager 51 Eo *manager; // keeps a reference of the manager
52 Eo *gesture;
53 int finger_size;
54 Eina_Bool continues;
55};
56
57struct _Efl_Canvas_Gesture_Recognizer_Tap_Data
58{
59 Eo *target;
60 Eo *gesture;
61 Ecore_Timer *timeout;
62};
63
64struct _Efl_Canvas_Gesture_Recognizer_Long_Tap_Data
65{
66 Eina_List *target_timeout;
67 Eo *target;
68 Efl_Canvas_Gesture *gesture;
69 Ecore_Timer *timeout;
70 double start_timeout;
71 Eina_Bool is_timeout;
72};
73
74struct _Efl_Canvas_Gesture_Recognizer_Double_Tap_Data
75{
76 Eina_List *target_timeout;
77 Eo *target;
78 Eo *gesture;
79 Ecore_Timer *timeout;
80 double start_timeout;
81 Eina_Bool is_timeout;
82 int tap_count;
83};
84
85struct _Efl_Canvas_Gesture_Recognizer_Triple_Tap_Data
86{
87 Eina_List *target_timeout;
88 Eo *target;
89 Eo *gesture;
90 Ecore_Timer *timeout;
91 double start_timeout;
92 Eina_Bool is_timeout;
93 int tap_count;
94};
95
96struct _Efl_Canvas_Gesture_Recognizer_Momentum_Data
97{
98 Eina_Position2D st_line;
99 Eina_Position2D end_line;
100 unsigned int t_st;
101 unsigned int t_end;
102 int xdir;
103 int ydir;
104 Eina_Bool touched;
105};
106
107struct _Efl_Canvas_Gesture_Recognizer_Flick_Data
108{
109 Eina_Position2D st_line;
110 unsigned int t_st;
111 unsigned int t_end;
112 int line_length;
113 double line_angle;
114 Eina_Bool touched;
115};
116
117struct _Efl_Canvas_Gesture_Recognizer_Zoom_Data
118{
119 Pointer_Data zoom_st;
120 Pointer_Data zoom_st1;
121
122 Pointer_Data zoom_mv;
123 Pointer_Data zoom_mv1;
124
125 Evas_Coord zoom_base; /* Holds gap between fingers on
126 * zoom-start */
127 double zoom_distance_tolerance;
128 double zoom_finger_factor;
129 double zoom_step;
130 double next_step;
131 Eina_Bool calc_temp;
23}; 132};
24 133
25struct _Efl_Canvas_Gesture_Data 134struct _Efl_Canvas_Gesture_Data
26{ 135{
27 const Efl_Event_Description *type; 136 const Efl_Event_Description *type;
28 Efl_Canvas_Gesture_State state; 137 Efl_Canvas_Gesture_State state;
29 Eina_Vector2 hotspot; 138 Eina_Position2D hotspot;
139 unsigned int timestamp;
140};
141
142struct _Efl_Canvas_Gesture_Momentum_Data
143{
144 Eina_Vector2 momentum;
30}; 145};
31 146
32struct _Efl_Canvas_Gesture_Tap_Data 147struct _Efl_Canvas_Gesture_Flick_Data
33{ 148{
149 Eina_Vector2 momentum;
150 double angle;
34}; 151};
35 152
36struct _Efl_Canvas_Gesture_Long_Tap_Data 153struct _Efl_Canvas_Gesture_Zoom_Data
37{ 154{
38 Ecore_Timer *timeout; 155 double radius;
39 Eina_Bool is_timeout; 156 double zoom;
40}; 157};
41 158
42#endif 159#endif
diff --git a/src/lib/evas/gesture/efl_canvas_gesture_recognizer.c b/src/lib/evas/gesture/efl_canvas_gesture_recognizer.c
index eac5f1cecf..8a83e2f945 100644
--- a/src/lib/evas/gesture/efl_canvas_gesture_recognizer.c
+++ b/src/lib/evas/gesture/efl_canvas_gesture_recognizer.c
@@ -2,6 +2,7 @@
2 2
3#define MY_CLASS EFL_CANVAS_GESTURE_RECOGNIZER_CLASS 3#define MY_CLASS EFL_CANVAS_GESTURE_RECOGNIZER_CLASS
4 4
5#define EFL_GESTURE_TAP_FINGER_SIZE 10
5EOLIAN static Eina_Value * 6EOLIAN static Eina_Value *
6_efl_canvas_gesture_recognizer_config_get(const Eo *obj EINA_UNUSED, Efl_Canvas_Gesture_Recognizer_Data *pd, const char *name) 7_efl_canvas_gesture_recognizer_config_get(const Eo *obj EINA_UNUSED, Efl_Canvas_Gesture_Recognizer_Data *pd, const char *name)
7{ 8{
@@ -15,4 +16,13 @@ _efl_canvas_gesture_recognizer_reset(Eo *obj EINA_UNUSED, Efl_Canvas_Gesture_Rec
15 16
16} 17}
17 18
19EOLIAN static Efl_Object *
20_efl_canvas_gesture_recognizer_efl_object_constructor(Eo *obj, Efl_Canvas_Gesture_Recognizer_Data *pd)
21{
22 obj = efl_constructor(efl_super(obj, MY_CLASS));
23
24 pd->finger_size = EFL_GESTURE_TAP_FINGER_SIZE;
25
26 return obj;
27}
18#include "efl_canvas_gesture_recognizer.eo.c" 28#include "efl_canvas_gesture_recognizer.eo.c"
diff --git a/src/lib/evas/gesture/efl_canvas_gesture_recognizer.eo b/src/lib/evas/gesture/efl_canvas_gesture_recognizer.eo
index 857408913b..aaee7d29b1 100644
--- a/src/lib/evas/gesture/efl_canvas_gesture_recognizer.eo
+++ b/src/lib/evas/gesture/efl_canvas_gesture_recognizer.eo
@@ -2,10 +2,18 @@ import efl_canvas_gesture_types;
2 2
3abstract @beta Efl.Canvas.Gesture_Recognizer extends Efl.Object 3abstract @beta Efl.Canvas.Gesture_Recognizer extends Efl.Object
4{ 4{
5 [[EFL Gesture Recognizer abstract class]] 5 [[EFL Gesture Recognizer abstract class
6
7 The gesture recognizer class grabs events that occur on the target
8 object that user register to see if a particluar gesture has occurred.
9
10 Uesr can adjust the config value involved in gesture recognition
11 through the method provided by the gesture recognizer.
12
13 The default config values follow the system default config value.]]
6 c_prefix: efl_gesture_recognizer; 14 c_prefix: efl_gesture_recognizer;
7 methods { 15 methods {
8 create @pure_virtual { 16 add @pure_virtual {
9 [[This function is called to create a new Efl.Canvas.Gesture object for the given target]] 17 [[This function is called to create a new Efl.Canvas.Gesture object for the given target]]
10 params { 18 params {
11 @in target: Efl.Object; [[The target widget]] 19 @in target: Efl.Object; [[The target widget]]
@@ -44,4 +52,7 @@ abstract @beta Efl.Canvas.Gesture_Recognizer extends Efl.Object
44 } 52 }
45 } 53 }
46 } 54 }
55 implements {
56 Efl.Object.constructor;
57 }
47} 58}
diff --git a/src/lib/evas/gesture/efl_canvas_gesture_recognizer_double_tap.c b/src/lib/evas/gesture/efl_canvas_gesture_recognizer_double_tap.c
new file mode 100644
index 0000000000..1656bb633f
--- /dev/null
+++ b/src/lib/evas/gesture/efl_canvas_gesture_recognizer_double_tap.c
@@ -0,0 +1,191 @@
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
7EOLIAN static Efl_Canvas_Gesture *
8_efl_canvas_gesture_recognizer_double_tap_efl_canvas_gesture_recognizer_add(Eo *obj, Efl_Canvas_Gesture_Recognizer_Double_Tap_Data *pd EINA_UNUSED, Efl_Object *target EINA_UNUSED)
9{
10 return efl_add(EFL_CANVAS_GESTURE_DOUBLE_TAP_CLASS, obj);
11}
12
13EOLIAN static void
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
23static Eina_Bool
24_tap_timeout_cb(void *data)
25{
26 Efl_Canvas_Gesture_Recognizer_Data *rd;
27 Efl_Canvas_Gesture_Recognizer_Double_Tap_Data *pd;
28
29 rd = efl_data_scope_get(data, EFL_CANVAS_GESTURE_RECOGNIZER_CLASS);
30 pd = efl_data_scope_get(data, EFL_CANVAS_GESTURE_RECOGNIZER_DOUBLE_TAP_CLASS);
31
32 efl_gesture_state_set(pd->gesture, EFL_GESTURE_CANCELED);
33 efl_event_callback_call(pd->target, EFL_EVENT_GESTURE_DOUBLE_TAP, pd->gesture);
34
35 efl_gesture_manager_gesture_clean_up(rd->manager, pd->target, EFL_EVENT_GESTURE_DOUBLE_TAP);
36
37 pd->timeout = NULL;
38 pd->tap_count = 0;
39
40 return ECORE_CALLBACK_CANCEL;
41}
42
43EOLIAN static Efl_Canvas_Gesture_Recognizer_Result
44_efl_canvas_gesture_recognizer_double_tap_efl_canvas_gesture_recognizer_recognize(Eo *obj,
45 Efl_Canvas_Gesture_Recognizer_Double_Tap_Data *pd,
46 Efl_Canvas_Gesture *gesture, Efl_Object *watched,
47 Efl_Canvas_Gesture_Touch *event)
48{
49 double length;
50 double timeout = TAP_TIME_OUT;
51 Eina_Position2D pos;
52 Eina_Vector2 dist;
53 Efl_Canvas_Gesture_Recognizer_Result result = EFL_GESTURE_CANCEL;
54 Efl_Canvas_Gesture_Recognizer_Data *rd = efl_data_scope_get(obj, EFL_CANVAS_GESTURE_RECOGNIZER_CLASS);
55
56 pd->target = watched;
57 pd->gesture = gesture;
58
59 if (!pd->start_timeout)
60 {
61 double time;
62 Eina_Value *val = efl_gesture_recognizer_config_get(obj, "glayer_doublee_tap_timeout");
63
64 if (val)
65 {
66 eina_value_get(val, &time);
67 pd->start_timeout = timeout = time;
68 }
69 }
70 else
71 timeout = pd->start_timeout;
72
73 switch (efl_gesture_touch_state_get(event))
74 {
75 case EFL_GESTURE_TOUCH_BEGIN:
76 {
77 pos = efl_gesture_touch_start_point_get(event);
78 efl_gesture_hotspot_set(gesture, pos);
79
80 if (pd->timeout)
81 ecore_timer_reset(pd->timeout);
82 else
83 pd->timeout = ecore_timer_add(timeout, _tap_timeout_cb, obj);
84
85 result = EFL_GESTURE_TRIGGER;
86
87 break;
88 }
89
90 case EFL_GESTURE_TOUCH_UPDATE:
91 {
92 result = EFL_GESTURE_IGNORE;
93
94 if (efl_gesture_state_get(gesture) != EFL_GESTURE_NONE &&
95 !efl_gesture_touch_multi_touch_get(event))
96 {
97 dist = efl_gesture_touch_distance(event, 0);
98 length = fabs(dist.x) + fabs(dist.y);
99
100 if (length > rd->finger_size)
101 {
102 if (pd->timeout)
103 {
104 ecore_timer_del(pd->timeout);
105 pd->timeout = NULL;
106 }
107
108 result = EFL_GESTURE_CANCEL;
109
110 pd->tap_count = 0;
111 }
112 }
113
114 break;
115 }
116 case EFL_GESTURE_TOUCH_END:
117 {
118
119 if (efl_gesture_state_get(gesture) != EFL_GESTURE_NONE &&
120 !efl_gesture_touch_multi_touch_get(event))
121 {
122 dist = efl_gesture_touch_distance(event, 0);
123 length = fabs(dist.x) + fabs(dist.y);
124
125 if (length <= rd->finger_size)
126 {
127 pd->tap_count++;
128 if (pd->tap_count == 1)
129 {
130 if (pd->timeout)
131 ecore_timer_reset(pd->timeout);
132
133 result = EFL_GESTURE_TRIGGER;
134 }
135 else
136 {
137 if (pd->timeout)
138 {
139 ecore_timer_del(pd->timeout);
140 pd->timeout = NULL;
141 }
142
143 if (efl_gesture_touch_state_get(event) == EFL_GESTURE_TOUCH_END)
144 result = EFL_GESTURE_FINISH;
145 else
146 result = EFL_GESTURE_TRIGGER;
147
148 pd->tap_count = 0;
149 }
150 }
151 else
152 {
153 if (pd->timeout)
154 {
155 ecore_timer_del(pd->timeout);
156 pd->timeout = NULL;
157 }
158
159 result = EFL_GESTURE_CANCEL;
160
161 pd->tap_count = 0;
162 }
163 }
164
165 break;
166 }
167
168 default:
169
170 break;
171 }
172
173 return result;
174}
175
176EOLIAN static double
177_efl_canvas_gesture_recognizer_double_tap_timeout_get(const Eo *obj EINA_UNUSED,
178 Efl_Canvas_Gesture_Recognizer_Double_Tap_Data *pd)
179{
180 return pd->start_timeout;
181}
182
183EOLIAN static void
184_efl_canvas_gesture_recognizer_double_tap_timeout_set(Eo *obj EINA_UNUSED,
185 Efl_Canvas_Gesture_Recognizer_Double_Tap_Data *pd,
186 double time)
187{
188 pd->start_timeout = time;
189}
190
191#include "efl_canvas_gesture_recognizer_double_tap.eo.c"
diff --git a/src/lib/evas/gesture/efl_canvas_gesture_recognizer_double_tap.eo b/src/lib/evas/gesture/efl_canvas_gesture_recognizer_double_tap.eo
new file mode 100644
index 0000000000..9f3ab0a93c
--- /dev/null
+++ b/src/lib/evas/gesture/efl_canvas_gesture_recognizer_double_tap.eo
@@ -0,0 +1,22 @@
1class @beta Efl.Canvas.Gesture_Recognizer_Double_Tap extends Efl.Canvas.Gesture_Recognizer
2{
3 [[EFL Gesture Recognizer Double Tap class]]
4 c_prefix: efl_gesture_recognizer_double_tap;
5 methods {
6 @property timeout {
7 [[Sets the time between taps to be recognized as a double tap]]
8 set {
9 }
10 get {
11 }
12 values {
13 time: double; [[Allowed time gap value]]
14 }
15 }
16 }
17 implements {
18 Efl.Object.destructor;
19 Efl.Canvas.Gesture_Recognizer.add;
20 Efl.Canvas.Gesture_Recognizer.recognize;
21 }
22}
diff --git a/src/lib/evas/gesture/efl_canvas_gesture_recognizer_flick.c b/src/lib/evas/gesture/efl_canvas_gesture_recognizer_flick.c
new file mode 100644
index 0000000000..4968c61b34
--- /dev/null
+++ b/src/lib/evas/gesture/efl_canvas_gesture_recognizer_flick.c
@@ -0,0 +1,354 @@
1#include "efl_canvas_gesture_private.h"
2
3#define MY_CLASS EFL_CANVAS_GESTURE_RECOGNIZER_FLICK_CLASS
4
5#define MOMENTUM_TIMEOUT 50
6#define THUMBSCROLL_FRICTION 0.95
7#define THUMBSCROLL_MOMENTUM_THRESHOLD 100.0
8#define EFL_GESTURE_MINIMUM_MOMENTUM 0.001
9
10#define RAD2DEG(x) ((x) * 57.295779513)
11#define DEG2RAD(x) ((x) / 57.295779513)
12
13EOLIAN static Efl_Canvas_Gesture *
14_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)
15{
16 return efl_add(EFL_CANVAS_GESTURE_FLICK_CLASS, obj);
17}
18
19static void
20_momentum_set(Eo *obj,
21 Efl_Canvas_Gesture_Flick_Data *fd,
22 Eina_Position2D v1,
23 Eina_Position2D v2,
24 unsigned int t1,
25 unsigned int t2)
26{
27 Evas_Coord velx = 0, vely = 0, vel;
28 Evas_Coord dx = v2.x - v1.x;
29 Evas_Coord dy = v2.y - v1.y;
30 int dt = t2 - t1;
31 Eina_Value *tf, *tmt;
32 double thumbscroll_friction, thumbscroll_momentum_threshold;
33
34 if (dt > 0)
35 {
36 velx = (dx * 1000) / dt;
37 vely = (dy * 1000) / dt;
38 }
39
40 vel = sqrt((velx * velx) + (vely * vely));
41
42 tf = efl_gesture_recognizer_config_get(obj, "thumbscroll_friction");
43 if (tf) eina_value_get(tf, &thumbscroll_friction);
44 else thumbscroll_friction = THUMBSCROLL_FRICTION;
45
46 tmt = efl_gesture_recognizer_config_get(obj, "thumbscroll_momentum_threshold");
47 if (tmt) eina_value_get(tmt, &thumbscroll_momentum_threshold);
48 else thumbscroll_momentum_threshold = THUMBSCROLL_MOMENTUM_THRESHOLD;
49
50 if ((thumbscroll_friction > 0.0) &&
51 (vel > thumbscroll_momentum_threshold)) /* report
52 * momentum */
53 {
54 fd->momentum.x = velx;
55 fd->momentum.y = vely;
56 }
57 else
58 {
59 fd->momentum.x = 0;
60 fd->momentum.y = 0;
61 }
62}
63
64static void
65_single_line_process(Eo *obj,
66 Efl_Canvas_Gesture_Recognizer_Flick_Data *pd,
67 Efl_Canvas_Gesture *gesture,
68 Efl_Canvas_Gesture_Flick_Data *fd,
69 Efl_Canvas_Gesture_Touch *event)
70{
71 switch (efl_gesture_touch_state_get(event))
72 {
73 case EFL_GESTURE_TOUCH_BEGIN:
74 case EFL_GESTURE_TOUCH_UPDATE:
75 if (!pd->t_st)
76 {
77 pd->st_line = efl_gesture_touch_cur_point_get(event);
78 pd->t_st = efl_gesture_touch_cur_timestamp_get(event);
79
80 efl_gesture_hotspot_set(gesture, pd->st_line);
81
82 return;
83 }
84
85 break;
86
87 case EFL_GESTURE_TOUCH_END:
88 {
89 if (!pd->t_st) return;
90
91 pd->t_end = efl_gesture_touch_cur_timestamp_get(event);
92
93 break;
94 }
95
96 default:
97
98 return;
99 }
100
101 _momentum_set(obj, fd, pd->st_line, efl_gesture_touch_cur_point_get(event),
102 pd->t_st, efl_gesture_touch_cur_timestamp_get(event));
103}
104
105static double
106_angle_get(Evas_Coord xx1,
107 Evas_Coord yy1,
108 Evas_Coord xx2,
109 Evas_Coord yy2)
110{
111 double a, xx, yy, rt = (-1);
112
113 xx = abs(xx2 - xx1);
114 yy = abs(yy2 - yy1);
115
116 if (((int)xx) && ((int)yy))
117 {
118 rt = a = RAD2DEG(atan(yy / xx));
119 if (xx1 < xx2)
120 {
121 if (yy1 < yy2) rt = 360 - a;
122 else rt = a;
123 }
124 else
125 {
126 if (yy1 < yy2) rt = 180 + a;
127 else rt = 180 - a;
128 }
129 }
130
131 if (rt < 0) /* Do this only if rt is not set */
132 {
133 if (((int)xx)) /* Horizontal line */
134 {
135 if (xx2 < xx1) rt = 180;
136 else rt = 0.0;
137 }
138 else
139 { /* Vertical line */
140 if (yy2 < yy1) rt = 90;
141 else rt = 270;
142 }
143 }
144
145 /* Now we want to change from:
146 * 90 0
147 * original circle 180 0 We want: 270 90
148 * 270 180
149 */
150 rt = 450 - rt;
151 if (rt >= 360) rt -= 360;
152
153 return rt;
154}
155
156
157static void
158_vector_get(Eina_Position2D v1,
159 Eina_Position2D v2,
160 int *l,
161 double *a)
162{
163 int xx, yy;
164
165 xx = (int)(v2.x - v1.x);
166 yy = (int)(v2.y - v1.y);
167 *l = (int)sqrt((xx * xx) + (yy * yy));
168 *a = _angle_get((int)v1.x, (int)v1.y, (int)v2.x, (int)v2.y);
169}
170
171EOLIAN static Efl_Canvas_Gesture_Recognizer_Result
172_efl_canvas_gesture_recognizer_flick_efl_canvas_gesture_recognizer_recognize(Eo *obj,
173 Efl_Canvas_Gesture_Recognizer_Flick_Data *pd,
174 Efl_Canvas_Gesture *gesture, Efl_Object *watched,
175 Efl_Canvas_Gesture_Touch *event)
176{
177 double angle;
178 Eina_Value *val;
179 unsigned char glayer_continues_enable;
180 Efl_Canvas_Gesture_Recognizer_Result result = EFL_GESTURE_CANCEL;
181 Eina_Bool touch_up = EINA_FALSE;
182 Efl_Canvas_Gesture_Flick_Data *fd = efl_data_scope_get(gesture, EFL_CANVAS_GESTURE_FLICK_CLASS);
183 Efl_Canvas_Gesture_Recognizer_Data *rd = efl_data_scope_get(obj, EFL_CANVAS_GESTURE_RECOGNIZER_CLASS);
184
185 val = efl_gesture_recognizer_config_get(obj, "glayer_continues_enable");
186 if (val) eina_value_get(val, &glayer_continues_enable);
187 else glayer_continues_enable = 1;
188
189 //We need to cover events that occur continuously in the mouse down state
190 //without mouse up.
191 //Recognizing the gesture again, even though it was canceled during gesture
192 //recognition.
193 if (efl_gesture_state_get(gesture) == EFL_GESTURE_CANCELED)
194 efl_gesture_state_set(gesture, EFL_GESTURE_NONE);
195
196 if (efl_gesture_touch_state_get(event) == EFL_GESTURE_TOUCH_END)
197 touch_up = EINA_TRUE;
198
199 //This is to handle a case with a mouse click on the target object.
200 if (efl_gesture_touch_state_get(event) == EFL_GESTURE_TOUCH_END && !pd->touched)
201 efl_gesture_manager_gesture_clean_up(rd->manager, watched, EFL_EVENT_GESTURE_FLICK);
202
203 if (glayer_continues_enable && !pd->touched)
204 {
205 pd->touched = EINA_TRUE;
206 pd->line_angle = -1.0;
207 rd->continues = EINA_TRUE;
208
209 return EFL_GESTURE_IGNORE;
210 }
211
212 _single_line_process(obj, pd, gesture, fd, event);
213 _vector_get(pd->st_line, efl_gesture_touch_cur_point_get(event),
214 &pd->line_length, &angle);
215
216 if (pd->t_st)
217 {
218 if (pd->line_angle >= 0.0)
219 {
220 double line_distance_tolerance, line_angular_tolerance;
221 double a = fabs(angle - pd->line_angle);
222 double d = (tan(DEG2RAD(a))) * pd->line_length;
223
224 val = efl_gesture_recognizer_config_get(obj, "glayer_line_distance_tolerance");
225 if (val) eina_value_get(val, &line_distance_tolerance);
226 else line_distance_tolerance = 3.0;
227
228 line_distance_tolerance *= rd->finger_size;
229
230 val = efl_gesture_recognizer_config_get(obj, "glayer_line_angular_tolerance");
231 if (val) eina_value_get(val, &line_angular_tolerance);
232 else line_angular_tolerance = 20.0;
233
234 if ((d > line_distance_tolerance) ||
235 (a > line_angular_tolerance))
236 {
237 memset(pd, 0, sizeof(Efl_Canvas_Gesture_Recognizer_Flick_Data));
238
239 if (touch_up) rd->continues = EINA_FALSE;
240
241 return EFL_GESTURE_CANCEL;
242 }
243
244 /* We may finish line if momentum is zero */
245 if (glayer_continues_enable)
246 {
247 /* This is for continues-gesture */
248 /* Finish line on zero momentum for continues gesture */
249 if ((!fd->momentum.x) && (!fd->momentum.y))
250 pd->t_end = efl_gesture_touch_cur_timestamp_get(event);
251 }
252 }
253 else
254 {
255 double line_min_length;
256
257 val = efl_gesture_recognizer_config_get(obj, "glayer_line_min_length");
258 if (val) eina_value_get(val, &line_min_length);
259 else line_min_length = 1.0;
260
261 line_min_length *= rd->finger_size;
262
263 if (pd->line_length >= line_min_length)
264 fd->angle = pd->line_angle = angle;
265
266 }
267
268 if (pd->t_end)
269 {
270 if (pd->line_angle < 0.0)
271 {
272 memset(pd, 0, sizeof(Efl_Canvas_Gesture_Recognizer_Flick_Data));
273
274 if (touch_up) rd->continues = EINA_FALSE;
275
276 return EFL_GESTURE_CANCEL;
277 }
278 }
279 }
280
281 unsigned int tm_end = efl_gesture_touch_cur_timestamp_get(event);
282 if (pd->t_end)
283 {
284 if (pd->t_end < tm_end)
285 tm_end = pd->t_end;
286 }
287
288 unsigned int time_limit_ms;
289 val = efl_gesture_recognizer_config_get(obj, "glayer_flick_time_limit_ms");
290 if (val) eina_value_get(val, &time_limit_ms);
291 else time_limit_ms = 120;
292
293 if ((tm_end - pd->t_st) > time_limit_ms)
294 {
295 memset(pd, 0, sizeof(Efl_Canvas_Gesture_Recognizer_Flick_Data));
296
297 if (touch_up) rd->continues = EINA_FALSE;
298
299 return EFL_GESTURE_CANCEL;
300 }
301
302 switch (efl_gesture_touch_state_get(event))
303 {
304 case EFL_GESTURE_TOUCH_BEGIN:
305 case EFL_GESTURE_TOUCH_UPDATE:
306 {
307 if (pd->t_st)
308 {
309 if (glayer_continues_enable && pd->t_end)
310 {
311 result = EFL_GESTURE_FINISH;
312 }
313 else
314 {
315 result = EFL_GESTURE_TRIGGER;
316 }
317 }
318 break;
319 }
320
321 case EFL_GESTURE_TOUCH_END:
322 {
323 if (!pd->t_st)
324 {
325 pd->touched = EINA_FALSE;
326 rd->continues = EINA_FALSE;
327
328 return EFL_GESTURE_CANCEL;
329 }
330 if (pd->t_st && pd->t_end)
331 {
332 rd->continues = EINA_FALSE;
333
334 result = EFL_GESTURE_FINISH;
335 }
336
337 efl_gesture_hotspot_set(gesture, efl_gesture_touch_cur_point_get(event));
338
339 memset(pd, 0, sizeof(Efl_Canvas_Gesture_Recognizer_Flick_Data));
340
341 rd->continues = EINA_FALSE;
342
343 break;
344 }
345
346 default:
347
348 break;
349 }
350
351 return result;
352}
353
354#include "efl_canvas_gesture_recognizer_flick.eo.c"
diff --git a/src/lib/evas/gesture/efl_canvas_gesture_recognizer_flick.eo b/src/lib/evas/gesture/efl_canvas_gesture_recognizer_flick.eo
new file mode 100644
index 0000000000..c7103ad33f
--- /dev/null
+++ b/src/lib/evas/gesture/efl_canvas_gesture_recognizer_flick.eo
@@ -0,0 +1,9 @@
1class @beta Efl.Canvas.Gesture_Recognizer_Flick extends Efl.Canvas.Gesture_Recognizer
2{
3 [[EFL Gesture Recognizer Flick Class]]
4 c_prefix: efl_gesture_recognizer_flick;
5 implements {
6 Efl.Canvas.Gesture_Recognizer.add;
7 Efl.Canvas.Gesture_Recognizer.recognize;
8 }
9}
diff --git a/src/lib/evas/gesture/efl_canvas_gesture_recognizer_long_tap.c b/src/lib/evas/gesture/efl_canvas_gesture_recognizer_long_tap.c
index 9f5463cf49..8f6773588b 100644
--- a/src/lib/evas/gesture/efl_canvas_gesture_recognizer_long_tap.c
+++ b/src/lib/evas/gesture/efl_canvas_gesture_recognizer_long_tap.c
@@ -2,36 +2,71 @@
2 2
3#define MY_CLASS EFL_CANVAS_GESTURE_RECOGNIZER_LONG_TAP_CLASS 3#define MY_CLASS EFL_CANVAS_GESTURE_RECOGNIZER_LONG_TAP_CLASS
4 4
5#define LONG_TAP_TIME_OUT 0.2 5#define EFL_GESTURE_LONG_TAP_TIME_OUT 1.2
6 6
7EOLIAN static Efl_Canvas_Gesture * 7EOLIAN static Efl_Canvas_Gesture *
8_efl_canvas_gesture_recognizer_long_tap_efl_canvas_gesture_recognizer_create(Eo *obj, void *pd EINA_UNUSED, 8_efl_canvas_gesture_recognizer_long_tap_efl_canvas_gesture_recognizer_add(Eo *obj,
9 Efl_Object *target EINA_UNUSED) 9 Efl_Canvas_Gesture_Recognizer_Long_Tap_Data *pd EINA_UNUSED,
10 Efl_Object *target EINA_UNUSED)
10{ 11{
11 return efl_add(EFL_CANVAS_GESTURE_LONG_TAP_CLASS, obj); 12 return efl_add(EFL_CANVAS_GESTURE_LONG_TAP_CLASS, obj);
12} 13}
13 14
15EOLIAN static void
16_efl_canvas_gesture_recognizer_long_tap_efl_object_destructor(Eo *obj,
17 Efl_Canvas_Gesture_Recognizer_Long_Tap_Data *pd)
18{
19 if (pd->timeout)
20 ecore_timer_del(pd->timeout);
21
22 efl_destructor(efl_super(obj, MY_CLASS));
23}
24
14static Eina_Bool 25static Eina_Bool
15_long_tap_timeout_cb(void *data) 26_long_tap_timeout_cb(void *data)
16{ 27{
17 Efl_Canvas_Gesture_Long_Tap_Data *ltp = data; 28 Efl_Canvas_Gesture_Recognizer_Long_Tap_Data *pd = data;
18 29
19 /* FIXME: Needs to propagate this event back to evas! */ 30 /* FIXME: Needs to propagate this event back to evas! */
20 ltp->is_timeout = EINA_TRUE; 31 pd->is_timeout = EINA_TRUE;
32
33 efl_gesture_state_set(pd->gesture, EFL_GESTURE_UPDATED);
34 efl_event_callback_call(pd->target, EFL_EVENT_GESTURE_LONG_TAP, pd->gesture);
21 35
22 return ECORE_CALLBACK_RENEW; 36 return ECORE_CALLBACK_RENEW;
23} 37}
24 38
25EOLIAN static Efl_Canvas_Gesture_Recognizer_Result 39EOLIAN static Efl_Canvas_Gesture_Recognizer_Result
26_efl_canvas_gesture_recognizer_long_tap_efl_canvas_gesture_recognizer_recognize(Eo *obj EINA_UNUSED, 40_efl_canvas_gesture_recognizer_long_tap_efl_canvas_gesture_recognizer_recognize(Eo *obj,
27 void *pd EINA_UNUSED, 41 Efl_Canvas_Gesture_Recognizer_Long_Tap_Data *pd,
28 Efl_Canvas_Gesture *gesture, Efl_Object *watched EINA_UNUSED, 42 Efl_Canvas_Gesture *gesture,
29 Efl_Canvas_Gesture_Touch *event) 43 Efl_Object *watched,
44 Efl_Canvas_Gesture_Touch *event)
30{ 45{
31 double length; // Manhattan distance 46 double length; // Manhattan distance
32 Eina_Vector2 pos, dist; 47 double timeout = EFL_GESTURE_LONG_TAP_TIME_OUT;
48 Eina_Position2D pos;
49 Eina_Vector2 dist;
33 Efl_Canvas_Gesture_Recognizer_Result result = EFL_GESTURE_CANCEL; 50 Efl_Canvas_Gesture_Recognizer_Result result = EFL_GESTURE_CANCEL;
34 Efl_Canvas_Gesture_Long_Tap_Data *ltp = efl_data_scope_get(gesture, EFL_CANVAS_GESTURE_LONG_TAP_CLASS); 51 Efl_Canvas_Gesture_Recognizer_Data *rd = efl_data_scope_get(obj, EFL_CANVAS_GESTURE_RECOGNIZER_CLASS);
52
53 pd->target = watched;
54 pd->gesture = gesture;
55
56 if (!pd->start_timeout)
57 {
58 double time;
59 Eina_Value *val = efl_gesture_recognizer_config_get(obj, "glayer_long_tap_start_timeout");
60
61 if (val)
62 {
63 eina_value_get(val, &time);
64 pd->start_timeout = timeout = time;
65 }
66 }
67 else
68 timeout = pd->start_timeout;
69
35 70
36 switch (efl_gesture_touch_state_get(event)) 71 switch (efl_gesture_touch_state_get(event))
37 { 72 {
@@ -39,49 +74,56 @@ _efl_canvas_gesture_recognizer_long_tap_efl_canvas_gesture_recognizer_recognize(
39 { 74 {
40 pos = efl_gesture_touch_start_point_get(event); 75 pos = efl_gesture_touch_start_point_get(event);
41 efl_gesture_hotspot_set(gesture, pos); 76 efl_gesture_hotspot_set(gesture, pos);
42 if (ltp->timeout) 77
43 ecore_timer_del(ltp->timeout); 78 if (pd->timeout)
44 ltp->timeout = ecore_timer_add(LONG_TAP_TIME_OUT, 79 {
45 _long_tap_timeout_cb, ltp); 80 ecore_timer_del(pd->timeout);
46 result = EFL_GESTURE_MAYBE; 81 }
82 pd->timeout = ecore_timer_add(timeout,
83 _long_tap_timeout_cb, pd);
84
85 result = EFL_GESTURE_TRIGGER;
86
47 break; 87 break;
48 } 88 }
89
49 case EFL_GESTURE_TOUCH_UPDATE: 90 case EFL_GESTURE_TOUCH_UPDATE:
50 { 91 {
51 if (!efl_gesture_touch_multi_touch_get(event)) 92 dist = efl_gesture_touch_distance(event, 0);
93 length = fabs(dist.x) + fabs(dist.y);
94
95 if ((efl_gesture_touch_multi_touch_get(event)) || (length > rd->finger_size))
52 { 96 {
53 dist = efl_gesture_touch_distance(event, 0); 97 if (pd->timeout)
54 length = fabs(dist.x) + fabs(dist.y);
55 if (length <= 50) // FIXME config!
56 {
57 if (ltp->is_timeout)
58 {
59 ltp->is_timeout = EINA_FALSE;
60 result = EFL_GESTURE_TRIGGER;
61 }
62 else
63 {
64 result = EFL_GESTURE_MAYBE;
65 }
66 }
67 else
68 { 98 {
69 result = EFL_GESTURE_CANCEL; 99 ecore_timer_del(pd->timeout);
100 pd->timeout = NULL;
70 } 101 }
102
103 result = EFL_GESTURE_CANCEL;
71 } 104 }
105 else
106 {
107 result = EFL_GESTURE_MAYBE;
108 }
109
72 break; 110 break;
73 } 111 }
112
74 case EFL_GESTURE_TOUCH_END: 113 case EFL_GESTURE_TOUCH_END:
75 { 114 {
76 if (ltp->timeout) 115 if (pd->timeout)
77 ecore_timer_del(ltp->timeout); 116 {
78 ltp->timeout = NULL; 117 ecore_timer_del(pd->timeout);
118 pd->timeout = NULL;
119 }
120
79 if (efl_gesture_state_get(gesture) != EFL_GESTURE_NONE && 121 if (efl_gesture_state_get(gesture) != EFL_GESTURE_NONE &&
80 !efl_gesture_touch_multi_touch_get(event)) 122 !efl_gesture_touch_multi_touch_get(event))
81 { 123 {
82 dist = efl_gesture_touch_distance(event, 0); 124 dist = efl_gesture_touch_distance(event, 0);
83 length = fabs(dist.x) + fabs(dist.y); 125 length = fabs(dist.x) + fabs(dist.y);
84 if (length <= 50 && ltp->is_timeout) // FIXME config! 126 if (length <= rd->finger_size && pd->is_timeout)
85 { 127 {
86 result = EFL_GESTURE_FINISH; 128 result = EFL_GESTURE_FINISH;
87 } 129 }
@@ -90,26 +132,45 @@ _efl_canvas_gesture_recognizer_long_tap_efl_canvas_gesture_recognizer_recognize(
90 result = EFL_GESTURE_CANCEL; 132 result = EFL_GESTURE_CANCEL;
91 } 133 }
92 } 134 }
135
93 break; 136 break;
94 } 137 }
138
95 default: 139 default:
140
96 break; 141 break;
97 } 142 }
143
98 return result; 144 return result;
99} 145}
100 146
101EOLIAN static void 147EOLIAN static void
102_efl_canvas_gesture_recognizer_long_tap_efl_canvas_gesture_recognizer_reset(Eo *obj, 148_efl_canvas_gesture_recognizer_long_tap_efl_canvas_gesture_recognizer_reset(Eo *obj,
103 void *pd EINA_UNUSED, 149 Efl_Canvas_Gesture_Recognizer_Long_Tap_Data *pd,
104 Efl_Canvas_Gesture *gesture) 150 Efl_Canvas_Gesture *gesture)
105{ 151{
106 Efl_Canvas_Gesture_Long_Tap_Data *ltp; 152 if (pd->timeout)
107 ltp = efl_data_scope_get(gesture, EFL_CANVAS_GESTURE_LONG_TAP_CLASS); 153 {
108 if (ltp->timeout) 154 ecore_timer_del(pd->timeout);
109 ecore_timer_del(ltp->timeout); 155 pd->timeout = NULL;
110 ltp->timeout = NULL; 156 }
111 ltp->is_timeout = EINA_FALSE; 157 pd->is_timeout = EINA_FALSE;
112 efl_gesture_recognizer_reset(efl_super(obj, MY_CLASS), gesture); 158 efl_gesture_recognizer_reset(efl_super(obj, MY_CLASS), gesture);
113} 159}
114 160
161EOLIAN static double
162_efl_canvas_gesture_recognizer_long_tap_timeout_get(const Eo *obj EINA_UNUSED,
163 Efl_Canvas_Gesture_Recognizer_Long_Tap_Data *pd)
164{
165 return pd->start_timeout;
166}
167
168EOLIAN static void
169_efl_canvas_gesture_recognizer_long_tap_timeout_set(Eo *obj EINA_UNUSED,
170 Efl_Canvas_Gesture_Recognizer_Long_Tap_Data *pd,
171 double time)
172{
173 pd->start_timeout = time;
174}
175
115#include "efl_canvas_gesture_recognizer_long_tap.eo.c" 176#include "efl_canvas_gesture_recognizer_long_tap.eo.c"
diff --git a/src/lib/evas/gesture/efl_canvas_gesture_recognizer_long_tap.eo b/src/lib/evas/gesture/efl_canvas_gesture_recognizer_long_tap.eo
index 8094655f13..7c8df2cfeb 100644
--- a/src/lib/evas/gesture/efl_canvas_gesture_recognizer_long_tap.eo
+++ b/src/lib/evas/gesture/efl_canvas_gesture_recognizer_long_tap.eo
@@ -1,10 +1,22 @@
1class @beta Efl.Canvas.Gesture_Recognizer_Long_Tap extends Efl.Canvas.Gesture_Recognizer 1class @beta Efl.Canvas.Gesture_Recognizer_Long_Tap extends Efl.Canvas.Gesture_Recognizer
2{ 2{
3 [[EFL Gesture Recognizer Long Tap class]] 3 [[EFL Gesture Recognizer Long Tap class]]
4 data: null;
5 c_prefix: efl_gesture_recognizer_long_tap; 4 c_prefix: efl_gesture_recognizer_long_tap;
5 methods {
6 @property timeout {
7 [[Sets the holding time to be recognized as a long tap.]]
8 set {
9 }
10 get {
11 }
12 values {
13 time: double; [[Allowed time gap value]]
14 }
15 }
16 }
6 implements { 17 implements {
7 Efl.Canvas.Gesture_Recognizer.create; 18 Efl.Object.destructor;
19 Efl.Canvas.Gesture_Recognizer.add;
8 Efl.Canvas.Gesture_Recognizer.recognize; 20 Efl.Canvas.Gesture_Recognizer.recognize;
9 Efl.Canvas.Gesture_Recognizer.reset; 21 Efl.Canvas.Gesture_Recognizer.reset;
10 } 22 }
diff --git a/src/lib/evas/gesture/efl_canvas_gesture_recognizer_momentum.c b/src/lib/evas/gesture/efl_canvas_gesture_recognizer_momentum.c
new file mode 100644
index 0000000000..34c9030ad3
--- /dev/null
+++ b/src/lib/evas/gesture/efl_canvas_gesture_recognizer_momentum.c
@@ -0,0 +1,197 @@
1#include "efl_canvas_gesture_private.h"
2
3#define MY_CLASS EFL_CANVAS_GESTURE_RECOGNIZER_MOMENTUM_CLASS
4
5#define MOMENTUM_TIMEOUT 50
6#define THUMBSCROLL_FRICTION 0.95
7#define THUMBSCROLL_MOMENTUM_THRESHOLD 100.0
8#define EFL_GESTURE_MINIMUM_MOMENTUM 0.001
9
10EOLIAN static Efl_Canvas_Gesture *
11_efl_canvas_gesture_recognizer_momentum_efl_canvas_gesture_recognizer_add(Eo *obj, Efl_Canvas_Gesture_Recognizer_Momentum_Data *pd EINA_UNUSED, Efl_Object *target EINA_UNUSED)
12{
13 return efl_add(EFL_CANVAS_GESTURE_MOMENTUM_CLASS, obj);
14}
15
16static void
17_momentum_set(Eo *obj,
18 Efl_Canvas_Gesture_Momentum_Data *md,
19 Eina_Position2D v1,
20 Eina_Position2D v2,
21 unsigned int t1,
22 unsigned int t2)
23{
24 Evas_Coord velx = 0, vely = 0, vel;
25 Evas_Coord dx = v2.x - v1.x;
26 Evas_Coord dy = v2.y - v1.y;
27 int dt = t2 - t1;
28 Eina_Value *tf, *tmt;
29 double thumbscroll_friction, thumbscroll_momentum_threshold;
30
31 if (dt > 0)
32 {
33 velx = (dx * 1000) / dt;
34 vely = (dy * 1000) / dt;
35 }
36
37 vel = sqrt((velx * velx) + (vely * vely));
38
39 tf = efl_gesture_recognizer_config_get(obj, "thumbscroll_friction");
40 if (tf) eina_value_get(tf, &thumbscroll_friction);
41 else thumbscroll_friction = THUMBSCROLL_FRICTION;
42
43 tmt = efl_gesture_recognizer_config_get(obj, "thumbscroll_momentum_threshold");
44 if (tmt) eina_value_get(tmt, &thumbscroll_momentum_threshold);
45 else thumbscroll_momentum_threshold = THUMBSCROLL_MOMENTUM_THRESHOLD;
46
47 if ((thumbscroll_friction > 0.0) &&
48 (vel > thumbscroll_momentum_threshold)) /* report
49 * momentum */
50 {
51 md->momentum.x = velx;
52 md->momentum.y = vely;
53 }
54 else
55 {
56 md->momentum.x = 0;
57 md->momentum.y = 0;
58 }
59}
60
61static int
62_direction_get(Evas_Coord xx1,
63 Evas_Coord xx2)
64{
65 if (xx2 < xx1) return -1;
66 if (xx2 > xx1) return 1;
67
68 return 0;
69}
70
71EOLIAN static Efl_Canvas_Gesture_Recognizer_Result
72_efl_canvas_gesture_recognizer_momentum_efl_canvas_gesture_recognizer_recognize(Eo *obj,
73 Efl_Canvas_Gesture_Recognizer_Momentum_Data *pd,
74 Efl_Canvas_Gesture *gesture, Efl_Object *watched EINA_UNUSED,
75 Efl_Canvas_Gesture_Touch *event)
76{
77 Eina_Value *val;
78 unsigned char glayer_continues_enable;
79 Efl_Canvas_Gesture_Recognizer_Result result = EFL_GESTURE_CANCEL;
80 Efl_Canvas_Gesture_Momentum_Data *md = efl_data_scope_get(gesture, EFL_CANVAS_GESTURE_MOMENTUM_CLASS);
81
82 val = efl_gesture_recognizer_config_get(obj, "glayer_continues_enable");
83 if (val) eina_value_get(val, &glayer_continues_enable);
84 else glayer_continues_enable = 1;
85
86 //Check the touched to ignore very first event.
87 //It does not have any meanging of this gesture.
88 if (glayer_continues_enable && !pd->touched)
89 {
90 pd->touched = EINA_TRUE;
91
92 return EFL_GESTURE_IGNORE;
93 }
94
95 switch (efl_gesture_touch_state_get(event))
96 {
97 case EFL_GESTURE_TOUCH_BEGIN:
98 case EFL_GESTURE_TOUCH_UPDATE:
99 {
100 if (!pd->t_st)
101 {
102 if (efl_gesture_touch_state_get(event) == EFL_GESTURE_TOUCH_BEGIN ||
103 glayer_continues_enable)
104 {
105 pd->t_st = pd->t_end = efl_gesture_touch_cur_timestamp_get(event);
106
107 pd->st_line = pd->end_line =
108 efl_gesture_touch_start_point_get(event);
109
110 efl_gesture_hotspot_set(gesture, pd->st_line);
111
112 return EFL_GESTURE_TRIGGER;
113 }
114 }
115
116 if ((efl_gesture_touch_cur_timestamp_get(event) - MOMENTUM_TIMEOUT) >
117 pd->t_end)
118 {
119 pd->st_line = efl_gesture_touch_cur_point_get(event);
120 pd->t_st = efl_gesture_touch_cur_timestamp_get(event);
121 pd->xdir = pd->ydir = 0;
122 }
123 else
124 {
125 int xdir, ydir;
126 Eina_Position2D cur_p = efl_gesture_touch_cur_point_get(event);
127
128 xdir = _direction_get(pd->end_line.x, cur_p.x);
129 ydir = _direction_get(pd->end_line.y, cur_p.y);
130
131 if (xdir && (xdir != pd->xdir))
132 {
133 pd->st_line.x = pd->end_line.x;
134 pd->t_st = pd->t_end;
135 pd->xdir = xdir;
136 }
137
138 if (ydir && (ydir != pd->ydir))
139 {
140 pd->st_line.y = pd->end_line.y;
141 pd->t_st = pd->t_end;
142 pd->ydir = ydir;
143 }
144 }
145
146 pd->end_line = efl_gesture_touch_cur_point_get(event);
147 pd->t_end = efl_gesture_touch_cur_timestamp_get(event);
148 efl_gesture_hotspot_set(gesture, pd->end_line);
149
150 _momentum_set(obj, md, pd->st_line, efl_gesture_touch_cur_point_get(event),
151 pd->t_st, efl_gesture_touch_cur_timestamp_get(event));
152
153 result = EFL_GESTURE_TRIGGER;
154
155 break;
156 }
157
158 case EFL_GESTURE_TOUCH_END:
159 {
160 if (!pd->t_st)
161 {
162 pd->touched = EINA_FALSE;
163
164 return EFL_GESTURE_CANCEL;
165 }
166
167 if ((efl_gesture_touch_cur_timestamp_get(event) - MOMENTUM_TIMEOUT) > pd->t_end)
168 {
169 pd->st_line = efl_gesture_touch_cur_point_get(event);
170 pd->t_st = efl_gesture_touch_cur_timestamp_get(event);
171 pd->xdir = pd->ydir = 0;
172 }
173
174 pd->end_line = efl_gesture_touch_cur_point_get(event);
175 pd->t_end = efl_gesture_touch_cur_timestamp_get(event);
176 efl_gesture_hotspot_set(gesture, pd->end_line);
177
178 if ((abs(md->momentum.x) > EFL_GESTURE_MINIMUM_MOMENTUM) ||
179 (abs(md->momentum.y) > EFL_GESTURE_MINIMUM_MOMENTUM))
180 result = EFL_GESTURE_FINISH;
181 else
182 result = EFL_GESTURE_CANCEL;
183
184 memset(pd, 0, sizeof(Efl_Canvas_Gesture_Recognizer_Momentum_Data));
185
186 break;
187 }
188
189 default:
190
191 break;
192 }
193
194 return result;
195}
196
197#include "efl_canvas_gesture_recognizer_momentum.eo.c"
diff --git a/src/lib/evas/gesture/efl_canvas_gesture_recognizer_momentum.eo b/src/lib/evas/gesture/efl_canvas_gesture_recognizer_momentum.eo
new file mode 100644
index 0000000000..1ae250dbba
--- /dev/null
+++ b/src/lib/evas/gesture/efl_canvas_gesture_recognizer_momentum.eo
@@ -0,0 +1,9 @@
1class @beta Efl.Canvas.Gesture_Recognizer_Momentum extends Efl.Canvas.Gesture_Recognizer
2{
3 [[EFL Gesture Recognizer Momentum class]]
4 c_prefix: efl_gesture_recognizer_momentum;
5 implements {
6 Efl.Canvas.Gesture_Recognizer.add;
7 Efl.Canvas.Gesture_Recognizer.recognize;
8 }
9}
diff --git a/src/lib/evas/gesture/efl_canvas_gesture_recognizer_tap.c b/src/lib/evas/gesture/efl_canvas_gesture_recognizer_tap.c
index 2e4a5a6b76..8f53a0585a 100644
--- a/src/lib/evas/gesture/efl_canvas_gesture_recognizer_tap.c
+++ b/src/lib/evas/gesture/efl_canvas_gesture_recognizer_tap.c
@@ -2,22 +2,45 @@
2 2
3#define MY_CLASS EFL_CANVAS_GESTURE_RECOGNIZER_TAP_CLASS 3#define MY_CLASS EFL_CANVAS_GESTURE_RECOGNIZER_TAP_CLASS
4 4
5//FIXME: It doesnt have matched config value.
6// may using dobule tap timeout value?
7#define EFL_GESTURE_TAP_TIME_OUT 0.33
8
5EOLIAN static Efl_Canvas_Gesture * 9EOLIAN static Efl_Canvas_Gesture *
6_efl_canvas_gesture_recognizer_tap_efl_canvas_gesture_recognizer_create(Eo *obj, void *pd EINA_UNUSED, 10_efl_canvas_gesture_recognizer_tap_efl_canvas_gesture_recognizer_add(Eo *obj,
7 Efl_Object *target EINA_UNUSED) 11 Efl_Canvas_Gesture_Recognizer_Tap_Data *pd EINA_UNUSED,
12 Efl_Object *target EINA_UNUSED)
8{ 13{
9 return efl_add(EFL_CANVAS_GESTURE_TAP_CLASS, obj); 14 return efl_add(EFL_CANVAS_GESTURE_TAP_CLASS, obj);
10} 15}
11 16
17static Eina_Bool
18_tap_timeout_cb(void *data)
19{
20 Efl_Canvas_Gesture_Recognizer_Tap_Data *pd = data;
21
22 efl_gesture_state_set(pd->gesture, EFL_GESTURE_CANCELED);
23 efl_event_callback_call(pd->target, EFL_EVENT_GESTURE_TAP, pd->gesture);
24
25 return ECORE_CALLBACK_CANCEL;
26}
27
28
12EOLIAN static Efl_Canvas_Gesture_Recognizer_Result 29EOLIAN static Efl_Canvas_Gesture_Recognizer_Result
13_efl_canvas_gesture_recognizer_tap_efl_canvas_gesture_recognizer_recognize(Eo *obj EINA_UNUSED, 30_efl_canvas_gesture_recognizer_tap_efl_canvas_gesture_recognizer_recognize(Eo *obj,
14 void *pd EINA_UNUSED, 31 Efl_Canvas_Gesture_Recognizer_Tap_Data *pd,
15 Efl_Canvas_Gesture *gesture, Efl_Object *watched EINA_UNUSED, 32 Efl_Canvas_Gesture *gesture,
16 Efl_Canvas_Gesture_Touch *event EINA_UNUSED) 33 Efl_Object *watched,
34 Efl_Canvas_Gesture_Touch *event)
17{ 35{
18 double length; 36 double length;
19 Eina_Vector2 pos, dist; 37 Eina_Position2D pos;
38 Eina_Vector2 dist;
20 Efl_Canvas_Gesture_Recognizer_Result result = EFL_GESTURE_CANCEL; 39 Efl_Canvas_Gesture_Recognizer_Result result = EFL_GESTURE_CANCEL;
40 Efl_Canvas_Gesture_Recognizer_Data *rd = efl_data_scope_get(obj, EFL_CANVAS_GESTURE_RECOGNIZER_CLASS);
41
42 pd->target = watched;
43 pd->gesture = gesture;
21 44
22 switch (efl_gesture_touch_state_get(event)) 45 switch (efl_gesture_touch_state_get(event))
23 { 46 {
@@ -25,18 +48,31 @@ _efl_canvas_gesture_recognizer_tap_efl_canvas_gesture_recognizer_recognize(Eo *o
25 { 48 {
26 pos = efl_gesture_touch_start_point_get(event); 49 pos = efl_gesture_touch_start_point_get(event);
27 efl_gesture_hotspot_set(gesture, pos); 50 efl_gesture_hotspot_set(gesture, pos);
51
52 if (pd->timeout)
53 ecore_timer_del(pd->timeout);
54 pd->timeout = ecore_timer_add(EFL_GESTURE_TAP_TIME_OUT, _tap_timeout_cb, pd);
55
28 result = EFL_GESTURE_TRIGGER; 56 result = EFL_GESTURE_TRIGGER;
57
29 break; 58 break;
30 } 59 }
60
31 case EFL_GESTURE_TOUCH_UPDATE: 61 case EFL_GESTURE_TOUCH_UPDATE:
32 case EFL_GESTURE_TOUCH_END: 62 case EFL_GESTURE_TOUCH_END:
33 { 63 {
64 if (pd->timeout)
65 {
66 ecore_timer_del(pd->timeout);
67 pd->timeout = NULL;
68 }
69
34 if (efl_gesture_state_get(gesture) != EFL_GESTURE_NONE && 70 if (efl_gesture_state_get(gesture) != EFL_GESTURE_NONE &&
35 !efl_gesture_touch_multi_touch_get(event)) 71 !efl_gesture_touch_multi_touch_get(event))
36 { 72 {
37 dist = efl_gesture_touch_distance(event, 0); 73 dist = efl_gesture_touch_distance(event, 0);
38 length = fabs(dist.x) + fabs(dist.y); 74 length = fabs(dist.x) + fabs(dist.y);
39 if (length <= 50) // FIXME config! 75 if (length <= rd->finger_size)
40 { 76 {
41 if (efl_gesture_touch_state_get(event) == EFL_GESTURE_TOUCH_END) 77 if (efl_gesture_touch_state_get(event) == EFL_GESTURE_TOUCH_END)
42 result = EFL_GESTURE_FINISH; 78 result = EFL_GESTURE_FINISH;
@@ -44,11 +80,15 @@ _efl_canvas_gesture_recognizer_tap_efl_canvas_gesture_recognizer_recognize(Eo *o
44 result = EFL_GESTURE_TRIGGER; 80 result = EFL_GESTURE_TRIGGER;
45 } 81 }
46 } 82 }
83
47 break; 84 break;
48 } 85 }
86
49 default: 87 default:
88
50 break; 89 break;
51 } 90 }
91
52 return result; 92 return result;
53} 93}
54 94
diff --git a/src/lib/evas/gesture/efl_canvas_gesture_recognizer_tap.eo b/src/lib/evas/gesture/efl_canvas_gesture_recognizer_tap.eo
index 65ae8c0c10..d7aabc7cdb 100644
--- a/src/lib/evas/gesture/efl_canvas_gesture_recognizer_tap.eo
+++ b/src/lib/evas/gesture/efl_canvas_gesture_recognizer_tap.eo
@@ -1,10 +1,9 @@
1class @beta Efl.Canvas.Gesture_Recognizer_Tap extends Efl.Canvas.Gesture_Recognizer 1class @beta Efl.Canvas.Gesture_Recognizer_Tap extends Efl.Canvas.Gesture_Recognizer
2{ 2{
3 [[EFL Gesture Recognizer Tap class]] 3 [[EFL Gesture Recognizer Tap class]]
4 data: null;
5 c_prefix: efl_gesture_recognizer_tap; 4 c_prefix: efl_gesture_recognizer_tap;
6 implements { 5 implements {
7 Efl.Canvas.Gesture_Recognizer.create; 6 Efl.Canvas.Gesture_Recognizer.add;
8 Efl.Canvas.Gesture_Recognizer.recognize; 7 Efl.Canvas.Gesture_Recognizer.recognize;
9 } 8 }
10} 9}
diff --git a/src/lib/evas/gesture/efl_canvas_gesture_recognizer_triple_tap.c b/src/lib/evas/gesture/efl_canvas_gesture_recognizer_triple_tap.c
new file mode 100644
index 0000000000..cd54d45886
--- /dev/null
+++ b/src/lib/evas/gesture/efl_canvas_gesture_recognizer_triple_tap.c
@@ -0,0 +1,191 @@
1#include "efl_canvas_gesture_private.h"
2
3#define MY_CLASS EFL_CANVAS_GESTURE_RECOGNIZER_TRIPLE_TAP_CLASS
4
5#define TAP_TIME_OUT 0.33
6
7EOLIAN static Efl_Canvas_Gesture *
8_efl_canvas_gesture_recognizer_triple_tap_efl_canvas_gesture_recognizer_add(Eo *obj, Efl_Canvas_Gesture_Recognizer_Triple_Tap_Data *pd EINA_UNUSED, Efl_Object *target EINA_UNUSED)
9{
10 return efl_add(EFL_CANVAS_GESTURE_TRIPLE_TAP_CLASS, obj);
11}
12
13EOLIAN static void
14_efl_canvas_gesture_recognizer_triple_tap_efl_object_destructor(Eo *obj,
15 Efl_Canvas_Gesture_Recognizer_Triple_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
23static Eina_Bool
24_tap_timeout_cb(void *data)
25{
26 Efl_Canvas_Gesture_Recognizer_Data *rd;
27 Efl_Canvas_Gesture_Recognizer_Triple_Tap_Data *pd;
28
29 rd = efl_data_scope_get(data, EFL_CANVAS_GESTURE_RECOGNIZER_CLASS);
30 pd = efl_data_scope_get(data, EFL_CANVAS_GESTURE_RECOGNIZER_TRIPLE_TAP_CLASS);
31
32 efl_gesture_state_set(pd->gesture, EFL_GESTURE_CANCELED);
33 efl_event_callback_call(pd->target, EFL_EVENT_GESTURE_TRIPLE_TAP, pd->gesture);
34
35 efl_gesture_manager_gesture_clean_up(rd->manager, pd->target, EFL_EVENT_GESTURE_TRIPLE_TAP);
36
37 pd->timeout = NULL;
38 pd->tap_count = 0;
39
40 return ECORE_CALLBACK_CANCEL;
41}
42
43EOLIAN static Efl_Canvas_Gesture_Recognizer_Result
44_efl_canvas_gesture_recognizer_triple_tap_efl_canvas_gesture_recognizer_recognize(Eo *obj,
45 Efl_Canvas_Gesture_Recognizer_Triple_Tap_Data *pd,
46 Efl_Canvas_Gesture *gesture, Efl_Object *watched,
47 Efl_Canvas_Gesture_Touch *event)
48{
49 double length;
50 double timeout = TAP_TIME_OUT;
51 Eina_Position2D pos;
52 Eina_Vector2 dist;
53 Efl_Canvas_Gesture_Recognizer_Result result = EFL_GESTURE_CANCEL;
54 Efl_Canvas_Gesture_Recognizer_Data *rd = efl_data_scope_get(obj, EFL_CANVAS_GESTURE_RECOGNIZER_CLASS);
55
56 pd->target = watched;
57 pd->gesture = gesture;
58
59 if (!pd->start_timeout)
60 {
61 double time;
62 Eina_Value *val = efl_gesture_recognizer_config_get(obj, "glayer_doublee_tap_timeout");
63
64 if (val)
65 {
66 eina_value_get(val, &time);
67 pd->start_timeout = timeout = time;
68 }
69 }
70 else
71 timeout = pd->start_timeout;
72
73 switch (efl_gesture_touch_state_get(event))
74 {
75 case EFL_GESTURE_TOUCH_BEGIN:
76 {
77 pos = efl_gesture_touch_start_point_get(event);
78 efl_gesture_hotspot_set(gesture, pos);
79
80 if (pd->timeout)
81 ecore_timer_reset(pd->timeout);
82 else
83 pd->timeout = ecore_timer_add(timeout, _tap_timeout_cb, obj);
84
85 result = EFL_GESTURE_TRIGGER;
86
87 break;
88 }
89
90 case EFL_GESTURE_TOUCH_UPDATE:
91 {
92 result = EFL_GESTURE_IGNORE;
93
94 if (efl_gesture_state_get(gesture) != EFL_GESTURE_NONE &&
95 !efl_gesture_touch_multi_touch_get(event))
96 {
97 dist = efl_gesture_touch_distance(event, 0);
98 length = fabs(dist.x) + fabs(dist.y);
99
100 if (length > rd->finger_size)
101 {
102 if (pd->timeout)
103 {
104 ecore_timer_del(pd->timeout);
105 pd->timeout = NULL;
106 }
107
108 result = EFL_GESTURE_CANCEL;
109
110 pd->tap_count = 0;
111 }
112 }
113
114 break;
115 }
116 case EFL_GESTURE_TOUCH_END:
117 {
118
119 if (efl_gesture_state_get(gesture) != EFL_GESTURE_NONE &&
120 !efl_gesture_touch_multi_touch_get(event))
121 {
122 dist = efl_gesture_touch_distance(event, 0);
123 length = fabs(dist.x) + fabs(dist.y);
124
125 if (length <= rd->finger_size)
126 {
127 pd->tap_count++;
128 if (pd->tap_count < 3)
129 {
130 if (pd->timeout)
131 ecore_timer_reset(pd->timeout);
132
133 result = EFL_GESTURE_TRIGGER;
134 }
135 else
136 {
137 if (pd->timeout)
138 {
139 ecore_timer_del(pd->timeout);
140 pd->timeout = NULL;
141 }
142
143 if (efl_gesture_touch_state_get(event) == EFL_GESTURE_TOUCH_END)
144 result = EFL_GESTURE_FINISH;
145 else
146 result = EFL_GESTURE_TRIGGER;
147
148 pd->tap_count = 0;
149 }
150 }
151 else
152 {
153 if (pd->timeout)
154 {
155 ecore_timer_del(pd->timeout);
156 pd->timeout = NULL;
157 }
158
159 result = EFL_GESTURE_CANCEL;
160
161 pd->tap_count = 0;
162 }
163 }
164
165 break;
166 }
167
168 default:
169
170 break;
171 }
172
173 return result;
174}
175
176EOLIAN static double
177_efl_canvas_gesture_recognizer_triple_tap_timeout_get(const Eo *obj EINA_UNUSED,
178 Efl_Canvas_Gesture_Recognizer_Triple_Tap_Data *pd)
179{
180 return pd->start_timeout;
181}
182
183EOLIAN static void
184_efl_canvas_gesture_recognizer_triple_tap_timeout_set(Eo *obj EINA_UNUSED,
185 Efl_Canvas_Gesture_Recognizer_Triple_Tap_Data *pd,
186 double time)
187{
188 pd->start_timeout = time;
189}
190
191#include "efl_canvas_gesture_recognizer_triple_tap.eo.c"
diff --git a/src/lib/evas/gesture/efl_canvas_gesture_recognizer_triple_tap.eo b/src/lib/evas/gesture/efl_canvas_gesture_recognizer_triple_tap.eo
new file mode 100644
index 0000000000..2ed02bb047
--- /dev/null
+++ b/src/lib/evas/gesture/efl_canvas_gesture_recognizer_triple_tap.eo
@@ -0,0 +1,22 @@
1class @beta Efl.Canvas.Gesture_Recognizer_Triple_Tap extends Efl.Canvas.Gesture_Recognizer
2{
3 [[EFL Gesture Recognizer Triple Tap class]]
4 c_prefix: efl_gesture_recognizer_triple_tap;
5 methods {
6 @property timeout {
7 [[Sets the time between taps to be recognized as a double tap.]]
8 set {
9 }
10 get {
11 }
12 values {
13 time: double; [[Time value.]]
14 }
15 }
16 }
17 implements {
18 Efl.Object.destructor;
19 Efl.Canvas.Gesture_Recognizer.add;
20 Efl.Canvas.Gesture_Recognizer.recognize;
21 }
22}
diff --git a/src/lib/evas/gesture/efl_canvas_gesture_recognizer_zoom.c b/src/lib/evas/gesture/efl_canvas_gesture_recognizer_zoom.c
new file mode 100644
index 0000000000..190e476312
--- /dev/null
+++ b/src/lib/evas/gesture/efl_canvas_gesture_recognizer_zoom.c
@@ -0,0 +1,275 @@
1#include "efl_canvas_gesture_private.h"
2
3#define MY_CLASS EFL_CANVAS_GESTURE_RECOGNIZER_ZOOM_CLASS
4
5static Evas_Coord
6_finger_gap_length_get(Evas_Coord xx1,
7 Evas_Coord yy1,
8 Evas_Coord xx2,
9 Evas_Coord yy2,
10 Evas_Coord *x,
11 Evas_Coord *y)
12{
13 double a, b, xx, yy, gap;
14 xx = abs(xx2 - xx1);
15 yy = abs(yy2 - yy1);
16 gap = sqrt((xx * xx) + (yy * yy));
17
18 /* START - Compute zoom center point */
19 /* The triangle defined as follows:
20 * B
21 * / |
22 * / |
23 * gap / | a
24 * / |
25 * A-----C
26 * b
27 * http://en.wikipedia.org/wiki/Trigonometric_functions
28 *************************************/
29 if (((int)xx) && ((int)yy))
30 {
31 double A = atan((yy / xx));
32 a = (Evas_Coord)((gap / 2) * sin(A));
33 b = (Evas_Coord)((gap / 2) * cos(A));
34 *x = (Evas_Coord)((xx2 > xx1) ? (xx1 + b) : (xx2 + b));
35 *y = (Evas_Coord)((yy2 > yy1) ? (yy1 + a) : (yy2 + a));
36 }
37 else
38 {
39 if ((int)xx) /* horiz line, take half width */
40 {
41 *x = (Evas_Coord)((xx1 + xx2) / 2);
42 *y = (Evas_Coord)(yy1);
43 }
44
45 if ((int)yy) /* vert line, take half width */
46 {
47 *x = (Evas_Coord)(xx1);
48 *y = (Evas_Coord)((yy1 + yy2) / 2);
49 }
50 }
51 /* END - Compute zoom center point */
52
53 return (Evas_Coord)gap;
54}
55
56static double
57_zoom_compute(Efl_Canvas_Gesture_Recognizer_Zoom_Data *pd,
58 Efl_Canvas_Gesture_Zoom_Data *zd,
59 Evas_Coord xx1,
60 Evas_Coord yy1,
61 Evas_Coord xx2,
62 Evas_Coord yy2,
63 double zoom_finger_factor)
64{
65 double rt = 1.0;
66 //TODO: Enable below code if the zoom momentum is need
67 //unsigned int tm_end = (pd->zoom_mv.cur.timestamp > pd->zoom_mv1.cur.timestamp) ?
68 // pd->zoom_mv.cur.timestamp : pd->zoom_mv1.cur.timestamp;
69
70 int x,y; //Hot spot
71 Evas_Coord diam = _finger_gap_length_get(xx1, yy1, xx2, yy2,
72 &x, &y);
73
74 zd->radius = diam / 2;
75
76 if (!pd->zoom_base)
77 {
78 pd->zoom_base = diam;
79 return zd->zoom;
80 }
81
82 if (pd->zoom_distance_tolerance) /* zoom tolerance <> ZERO, means
83 * zoom action NOT started yet */
84 {
85 /* avoid jump with zoom value when break tolerance */
86 if (diam < (pd->zoom_base - pd->zoom_distance_tolerance))
87 {
88 pd->zoom_base -= pd->zoom_distance_tolerance;
89 pd->zoom_distance_tolerance = 0;
90 }
91
92 /* avoid jump with zoom value when break tolerance */
93 if (diam > (pd->zoom_base + pd->zoom_distance_tolerance))
94 {
95 pd->zoom_base += pd->zoom_distance_tolerance;
96 pd->zoom_distance_tolerance = 0;
97 }
98
99 return rt;
100 }
101
102 /* We use factor only on the difference between gap-base */
103 /* if gap=120, base=100, we get ((120-100)/100)=0.2*factor */
104 rt = ((1.0) + ((((float)diam - (float)pd->zoom_base) /
105 (float)pd->zoom_base) * zoom_finger_factor));
106
107 //TODO: Enable below code if the zoom momentum is need
108 /* Momentum: zoom per second: */
109 //zd->momentum = _zoom_momentum_get(st, tm_end, rt);
110
111 return rt;
112}
113
114EOLIAN static Efl_Canvas_Gesture *
115_efl_canvas_gesture_recognizer_zoom_efl_canvas_gesture_recognizer_add(Eo *obj,
116 Efl_Canvas_Gesture_Recognizer_Zoom_Data *pd EINA_UNUSED,
117 Efl_Object *target EINA_UNUSED)
118{
119 return efl_add(EFL_CANVAS_GESTURE_ZOOM_CLASS, obj);
120}
121
122EOLIAN static Efl_Canvas_Gesture_Recognizer_Result
123_efl_canvas_gesture_recognizer_zoom_efl_canvas_gesture_recognizer_recognize(Eo *obj,
124 Efl_Canvas_Gesture_Recognizer_Zoom_Data *pd,
125 Efl_Canvas_Gesture *gesture,
126 Efl_Object *watched,
127 Efl_Canvas_Gesture_Touch *event)
128{
129 int id1 = 0;
130 int id2 = 1;
131 Eina_Value *val;
132 unsigned char zoom_finger_enable;
133 unsigned char glayer_continues_enable;
134 Efl_Canvas_Gesture_Recognizer_Result result = EFL_GESTURE_CANCEL;
135 Efl_Canvas_Gesture_Zoom_Data *zd = efl_data_scope_get(gesture, EFL_CANVAS_GESTURE_ZOOM_CLASS);
136 Efl_Canvas_Gesture_Touch_Data *td = efl_data_scope_get(event, EFL_CANVAS_GESTURE_TOUCH_CLASS);
137 Efl_Canvas_Gesture_Recognizer_Data *rd = efl_data_scope_get(obj, EFL_CANVAS_GESTURE_RECOGNIZER_CLASS);
138
139 //FIXME: Wheel zoom test first here.
140
141 val = efl_gesture_recognizer_config_get(obj, "glayer_continues_enable");
142 if (val) eina_value_get(val, &glayer_continues_enable);
143 else glayer_continues_enable = 1;
144
145 val = efl_gesture_recognizer_config_get(obj, "glayer_zoom_finger_enable");
146 if (val) eina_value_get(val, &zoom_finger_enable);
147 else zoom_finger_enable = 1;
148
149 val = efl_gesture_recognizer_config_get(obj, "glayer_zoom_finger_factor");
150 if (val) eina_value_get(val, &pd->zoom_finger_factor);
151 else pd->zoom_finger_factor = 1.0;
152
153 rd->continues = EINA_TRUE;
154
155 if (!pd->zoom_distance_tolerance && !pd->calc_temp)
156 {
157 pd->calc_temp = EINA_TRUE;
158 val = efl_gesture_recognizer_config_get(obj, "glayer_zoom_distance_tolerance");
159 if (val) eina_value_get(val, &pd->zoom_distance_tolerance);
160 else pd->zoom_distance_tolerance = 1.0;
161
162 pd->zoom_distance_tolerance *= rd->finger_size;
163 }
164
165 switch (efl_gesture_touch_state_get(event))
166 {
167 case EFL_GESTURE_TOUCH_UPDATE:
168 {
169 if ((!glayer_continues_enable) && (!pd->zoom_st.cur.timestamp))
170 {
171 return EFL_GESTURE_IGNORE;
172 }
173 EINA_FALLTHROUGH;
174 }
175 case EFL_GESTURE_TOUCH_BEGIN:
176 {
177 if (td->touch_down > 2)
178 {
179 return EFL_GESTURE_CANCEL;
180 }
181
182 if (!pd->zoom_st.cur.timestamp) /* Now scan touched-devices list
183 * and find other finger */
184 {
185 if (!efl_gesture_touch_multi_touch_get(event))
186 return EFL_GESTURE_IGNORE;
187
188 Pointer_Data *p1 = eina_hash_find(td->touch_points, &id1);
189 Pointer_Data *p2 = eina_hash_find(td->touch_points, &id2);
190
191 memcpy(&pd->zoom_st, p2, sizeof(Pointer_Data));
192 memcpy(&pd->zoom_st1, p1, sizeof(Pointer_Data));
193
194 memcpy(&pd->zoom_mv, p2, sizeof(Pointer_Data));
195 memcpy(&pd->zoom_mv1, p1, sizeof(Pointer_Data));
196
197 int x,y; //Hot spot
198 zd->zoom = 1.0;
199 pd->zoom_base = _finger_gap_length_get(pd->zoom_st1.cur.pos.x,
200 pd->zoom_st1.cur.pos.y,
201 pd->zoom_st.cur.pos.x,
202 pd->zoom_st.cur.pos.y,
203 &x, &y);
204
205 zd->radius = pd->zoom_base / 2;
206
207 if ((efl_gesture_state_get(gesture) != EFL_GESTURE_STARTED) &&
208 (efl_gesture_state_get(gesture) != EFL_GESTURE_UPDATED))
209 return EFL_GESTURE_TRIGGER;
210
211 return EFL_GESTURE_CANCEL;
212 }
213
214 Pointer_Data *p2 = eina_hash_find(td->touch_points, &id2);
215 if (p2->id == pd->zoom_mv.id)
216 memcpy(&pd->zoom_mv, p2, sizeof(Pointer_Data));
217 else if (p2->id == pd->zoom_mv1.id)
218 memcpy(&pd->zoom_mv1, p2, sizeof(Pointer_Data));
219
220 zd->zoom = _zoom_compute(pd, zd, pd->zoom_mv.cur.pos.x,
221 pd->zoom_mv.cur.pos.y, pd->zoom_mv1.cur.pos.x,
222 pd->zoom_mv1.cur.pos.y, pd->zoom_finger_factor);
223
224
225 if (!pd->zoom_distance_tolerance)
226 {
227 double d = zd->zoom - pd->next_step;
228
229 if (d < 0.0) d = (-d);
230
231 if (d >= pd->zoom_step)
232 {
233 pd->next_step = zd->zoom;
234
235 return EFL_GESTURE_TRIGGER;
236 }
237 }
238
239 return EFL_GESTURE_IGNORE;
240 }
241 case EFL_GESTURE_TOUCH_END:
242 {
243 if (td->touch_down == 0)
244 {
245 rd->continues = EINA_FALSE;
246
247 memset(pd, 0, sizeof(Efl_Canvas_Gesture_Recognizer_Zoom_Data));
248 efl_gesture_manager_gesture_clean_up(rd->manager, watched, EFL_EVENT_GESTURE_ZOOM);
249
250 return EFL_GESTURE_IGNORE;
251 }
252 if ((pd->zoom_base) && (pd->zoom_distance_tolerance == 0))
253 {
254 memset(pd, 0, sizeof(Efl_Canvas_Gesture_Recognizer_Zoom_Data));
255
256 return EFL_GESTURE_FINISH;
257 }
258
259 if (efl_gesture_state_get(gesture) != EFL_GESTURE_NONE)
260 {
261 memset(pd, 0, sizeof(Efl_Canvas_Gesture_Recognizer_Zoom_Data));
262
263 return EFL_GESTURE_CANCEL;
264 }
265 }
266
267 default:
268
269 break;
270 }
271
272 return result;
273}
274
275#include "efl_canvas_gesture_recognizer_zoom.eo.c"
diff --git a/src/lib/evas/gesture/efl_canvas_gesture_recognizer_zoom.eo b/src/lib/evas/gesture/efl_canvas_gesture_recognizer_zoom.eo
new file mode 100644
index 0000000000..350614c50c
--- /dev/null
+++ b/src/lib/evas/gesture/efl_canvas_gesture_recognizer_zoom.eo
@@ -0,0 +1,9 @@
1class @beta Efl.Canvas.Gesture_Recognizer_Zoom extends Efl.Canvas.Gesture_Recognizer
2{
3 [[EFL Gesture Recognizer Zoom class]]
4 c_prefix: efl_gesture_recognizer_zoom;
5 implements {
6 Efl.Canvas.Gesture_Recognizer.add;
7 Efl.Canvas.Gesture_Recognizer.recognize;
8 }
9}
diff --git a/src/lib/evas/gesture/efl_canvas_gesture_tap.c b/src/lib/evas/gesture/efl_canvas_gesture_tap.c
index aca24a9dbd..d777bebba1 100644
--- a/src/lib/evas/gesture/efl_canvas_gesture_tap.c
+++ b/src/lib/evas/gesture/efl_canvas_gesture_tap.c
@@ -2,9 +2,8 @@
2 2
3#define MY_CLASS EFL_CANVAS_GESTURE_TAP_CLASS 3#define MY_CLASS EFL_CANVAS_GESTURE_TAP_CLASS
4 4
5
6EOLIAN static Efl_Object * 5EOLIAN static Efl_Object *
7_efl_canvas_gesture_tap_efl_object_constructor(Eo *obj, Efl_Canvas_Gesture_Tap_Data *pd EINA_UNUSED) 6_efl_canvas_gesture_tap_efl_object_constructor(Eo *obj, void *pd EINA_UNUSED)
8{ 7{
9 Efl_Canvas_Gesture_Data *gd; 8 Efl_Canvas_Gesture_Data *gd;
10 9
diff --git a/src/lib/evas/gesture/efl_canvas_gesture_tap.eo b/src/lib/evas/gesture/efl_canvas_gesture_tap.eo
index a994b90abe..bd6daba234 100644
--- a/src/lib/evas/gesture/efl_canvas_gesture_tap.eo
+++ b/src/lib/evas/gesture/efl_canvas_gesture_tap.eo
@@ -1,11 +1,8 @@
1class @beta Efl.Canvas.Gesture_Tap extends Efl.Canvas.Gesture 1class @beta Efl.Canvas.Gesture_Tap extends Efl.Canvas.Gesture
2{ 2{
3 [[EFL Gesture Tap class]] 3 [[EFL Gesture Tap class]]
4 data: null;
4 c_prefix: efl_gesture_tap; 5 c_prefix: efl_gesture_tap;
5 event_prefix: efl;
6 events {
7 gesture,tap: Efl.Canvas.Gesture; [[Event for tap gesture]]
8 }
9 implements { 6 implements {
10 Efl.Object.constructor; 7 Efl.Object.constructor;
11 } 8 }
diff --git a/src/lib/evas/gesture/efl_canvas_gesture_touch.c b/src/lib/evas/gesture/efl_canvas_gesture_touch.c
index 9f997f59e6..4a5f5ca422 100644
--- a/src/lib/evas/gesture/efl_canvas_gesture_touch.c
+++ b/src/lib/evas/gesture/efl_canvas_gesture_touch.c
@@ -2,29 +2,9 @@
2 2
3#define MY_CLASS EFL_CANVAS_GESTURE_TOUCH_CLASS 3#define MY_CLASS EFL_CANVAS_GESTURE_TOUCH_CLASS
4 4
5typedef struct _Pointer_Data 5//This event object accumulates all the touch points
6{ 6//that are directed to a particular object from the
7 struct 7//first finger down to the last finger up
8 {
9 Eina_Vector2 pos;
10 double timestamp;
11 } start, prev, cur;
12 Efl_Pointer_Action action;
13} Pointer_Data;
14
15typedef struct _Efl_Canvas_Gesture_Touch_Data
16{
17 Efl_Canvas_Gesture_Touch_State state;
18 Eina_Hash *touch_points;
19 int touch_down;
20 Eina_Bool multi_touch;
21 Eo *target;
22} Efl_Canvas_Gesture_Touch_Data;
23
24
25// This event object accumulates all the touch points
26// that are directed to a particular object from the
27// first finger down to the last finger up
28 8
29static void _hash_free_cb(Pointer_Data *point) 9static void _hash_free_cb(Pointer_Data *point)