summaryrefslogtreecommitdiff
path: root/src/lib/evas
diff options
context:
space:
mode:
authorMike Blumenkrantz <zmike@samsung.com>2020-01-28 13:52:23 -0500
committerMarcel Hollerbach <mail@marcel-hollerbach.de>2020-02-05 10:10:49 +0100
commitca2cc5915da861bbad97636a61d4e78c70a0365d (patch)
tree56f2a648125ad0208beb9df166afa6aa530949a9 /src/lib/evas
parent2c8d7aa7c0131727f82e2e4ac15690a98c700de1 (diff)
efl/gesture: implement custom gesture recognizer framework
this adds support for creating custom (out of tree) gesture recognizers by adding an abstract recognizer class that can be inherited and reused docs TBA Reviewed-by: woochan lee <wc0917.lee@samsung.com> Differential Revision: https://phab.enlightenment.org/D11223
Diffstat (limited to 'src/lib/evas')
-rw-r--r--src/lib/evas/Efl_Canvas.h2
-rw-r--r--src/lib/evas/Evas_Eo.h2
-rw-r--r--src/lib/evas/gesture/efl_canvas_gesture_custom.c38
-rw-r--r--src/lib/evas/gesture/efl_canvas_gesture_custom.eo28
-rw-r--r--src/lib/evas/gesture/efl_canvas_gesture_events.eo4
-rw-r--r--src/lib/evas/gesture/efl_canvas_gesture_manager.c128
-rw-r--r--src/lib/evas/gesture/efl_canvas_gesture_private.h14
-rw-r--r--src/lib/evas/gesture/efl_canvas_gesture_recognizer_custom.c32
-rw-r--r--src/lib/evas/gesture/efl_canvas_gesture_recognizer_custom.eo23
-rw-r--r--src/lib/evas/gesture/efl_canvas_gesture_recognizer_double_tap.c2
-rw-r--r--src/lib/evas/gesture/efl_canvas_gesture_recognizer_flick.c2
-rw-r--r--src/lib/evas/gesture/efl_canvas_gesture_recognizer_triple_tap.c2
-rw-r--r--src/lib/evas/gesture/efl_canvas_gesture_recognizer_zoom.c2
-rw-r--r--src/lib/evas/gesture/efl_canvas_gesture_types.eot1
-rw-r--r--src/lib/evas/gesture/meson.build4
15 files changed, 238 insertions, 46 deletions
diff --git a/src/lib/evas/Efl_Canvas.h b/src/lib/evas/Efl_Canvas.h
index fe18f75353..9ef46201bf 100644
--- a/src/lib/evas/Efl_Canvas.h
+++ b/src/lib/evas/Efl_Canvas.h
@@ -118,9 +118,11 @@ extern "C" {
118#include <gesture/efl_canvas_gesture_recognizer_tap.eo.h> 118#include <gesture/efl_canvas_gesture_recognizer_tap.eo.h>
119#include <gesture/efl_canvas_gesture_recognizer_triple_tap.eo.h> 119#include <gesture/efl_canvas_gesture_recognizer_triple_tap.eo.h>
120#include <gesture/efl_canvas_gesture_recognizer_zoom.eo.h> 120#include <gesture/efl_canvas_gesture_recognizer_zoom.eo.h>
121#include <gesture/efl_canvas_gesture_recognizer_custom.eo.h>
121#include <gesture/efl_canvas_gesture_tap.eo.h> 122#include <gesture/efl_canvas_gesture_tap.eo.h>
122#include <gesture/efl_canvas_gesture_triple_tap.eo.h> 123#include <gesture/efl_canvas_gesture_triple_tap.eo.h>
123#include <gesture/efl_canvas_gesture_zoom.eo.h> 124#include <gesture/efl_canvas_gesture_zoom.eo.h>
125#include <gesture/efl_canvas_gesture_custom.eo.h>
124#include <gesture/efl_canvas_gesture_events.eo.h> 126#include <gesture/efl_canvas_gesture_events.eo.h>
125 127
126 128
diff --git a/src/lib/evas/Evas_Eo.h b/src/lib/evas/Evas_Eo.h
index 356a8fcc53..68b65372c3 100644
--- a/src/lib/evas/Evas_Eo.h
+++ b/src/lib/evas/Evas_Eo.h
@@ -205,6 +205,7 @@ struct _Efl_Canvas_Object_Animation_Event
205#include "gesture/efl_canvas_gesture_momentum.eo.h" 205#include "gesture/efl_canvas_gesture_momentum.eo.h"
206#include "gesture/efl_canvas_gesture_flick.eo.h" 206#include "gesture/efl_canvas_gesture_flick.eo.h"
207#include "gesture/efl_canvas_gesture_zoom.eo.h" 207#include "gesture/efl_canvas_gesture_zoom.eo.h"
208#include "gesture/efl_canvas_gesture_custom.eo.h"
208#include "gesture/efl_canvas_gesture_recognizer.eo.h" 209#include "gesture/efl_canvas_gesture_recognizer.eo.h"
209#include "gesture/efl_canvas_gesture_recognizer_tap.eo.h" 210#include "gesture/efl_canvas_gesture_recognizer_tap.eo.h"
210#include "gesture/efl_canvas_gesture_recognizer_long_tap.eo.h" 211#include "gesture/efl_canvas_gesture_recognizer_long_tap.eo.h"
@@ -213,6 +214,7 @@ struct _Efl_Canvas_Object_Animation_Event
213#include "gesture/efl_canvas_gesture_recognizer_momentum.eo.h" 214#include "gesture/efl_canvas_gesture_recognizer_momentum.eo.h"
214#include "gesture/efl_canvas_gesture_recognizer_flick.eo.h" 215#include "gesture/efl_canvas_gesture_recognizer_flick.eo.h"
215#include "gesture/efl_canvas_gesture_recognizer_zoom.eo.h" 216#include "gesture/efl_canvas_gesture_recognizer_zoom.eo.h"
217#include "gesture/efl_canvas_gesture_recognizer_custom.eo.h"
216#include "gesture/efl_canvas_gesture_manager.eo.h" 218#include "gesture/efl_canvas_gesture_manager.eo.h"
217#include "gesture/efl_canvas_gesture_events.eo.h" 219#include "gesture/efl_canvas_gesture_events.eo.h"
218 220
diff --git a/src/lib/evas/gesture/efl_canvas_gesture_custom.c b/src/lib/evas/gesture/efl_canvas_gesture_custom.c
new file mode 100644
index 0000000000..105558b57e
--- /dev/null
+++ b/src/lib/evas/gesture/efl_canvas_gesture_custom.c
@@ -0,0 +1,38 @@
1#define EFL_CANVAS_GESTURE_CUSTOM_PROTECTED
2#include "efl_canvas_gesture_private.h"
3
4#define MY_CLASS EFL_CANVAS_GESTURE_CUSTOM_CLASS
5
6
7EOLIAN static void
8_efl_canvas_gesture_custom_efl_object_destructor(Eo *obj, Efl_Canvas_Gesture_Custom_Data *pd)
9{
10 eina_stringshare_del(pd->gesture_name);
11 efl_destructor(efl_super(obj, MY_CLASS));
12}
13
14EOLIAN static Efl_Object *
15_efl_canvas_gesture_custom_efl_object_constructor(Eo *obj, Efl_Canvas_Gesture_Custom_Data *pd EINA_UNUSED)
16{
17 Efl_Canvas_Gesture_Data *gd;
18
19 obj = efl_constructor(efl_super(obj, MY_CLASS));
20
21 gd = efl_data_scope_get(obj, EFL_CANVAS_GESTURE_CLASS);
22 gd->type = EFL_EVENT_GESTURE_CUSTOM;
23
24 return obj;
25}
26
27EOLIAN static void
28_efl_canvas_gesture_custom_gesture_name_set(Eo *obj EINA_UNUSED, Efl_Canvas_Gesture_Custom_Data *pd, const char *name)
29{
30 eina_stringshare_replace(&pd->gesture_name, name);
31}
32
33EOLIAN static Eina_Stringshare *
34_efl_canvas_gesture_custom_gesture_name_get(const Eo *obj EINA_UNUSED, Efl_Canvas_Gesture_Custom_Data *pd)
35{
36 return pd->gesture_name;
37}
38#include "efl_canvas_gesture_custom.eo.c"
diff --git a/src/lib/evas/gesture/efl_canvas_gesture_custom.eo b/src/lib/evas/gesture/efl_canvas_gesture_custom.eo
new file mode 100644
index 0000000000..6792d1ba8f
--- /dev/null
+++ b/src/lib/evas/gesture/efl_canvas_gesture_custom.eo
@@ -0,0 +1,28 @@
1import eina_types;
2
3class @beta Efl.Canvas.Gesture_Custom extends Efl.Canvas.Gesture
4{
5 [[Custom gesture class holding state information.
6 See @Efl.Canvas.Gesture to see what this state is and
7 @[Efl.Canvas.Gesture_Events.gesture,custom] for a description of the Custom gesture.
8
9 Application developers receive these objects inside a gesture event and do not typically need to create their own.
10 ]]
11 c_prefix: efl_gesture_custom;
12 methods {
13 @property gesture_name {
14 [[This is the name of the custom gesture.]]
15 get {
16 }
17 set @protected {
18 }
19 values {
20 gesture_name: string; [[The name of the custom gesture.]]
21 }
22 }
23 }
24 implements {
25 Efl.Object.constructor;
26 Efl.Object.destructor;
27 }
28}
diff --git a/src/lib/evas/gesture/efl_canvas_gesture_events.eo b/src/lib/evas/gesture/efl_canvas_gesture_events.eo
index 9344d71edb..bbf9ef68fd 100644
--- a/src/lib/evas/gesture/efl_canvas_gesture_events.eo
+++ b/src/lib/evas/gesture/efl_canvas_gesture_events.eo
@@ -43,5 +43,9 @@ interface @beta Efl.Canvas.Gesture_Events
43 getting closer ("zoom out" or "pinch"). 43 getting closer ("zoom out" or "pinch").
44 This gesture cannot be performed with a mouse as it requires more than one pointer. 44 This gesture cannot be performed with a mouse as it requires more than one pointer.
45 ]] 45 ]]
46 gesture,custom: Efl.Canvas.Gesture_Custom; [[Emitted when a Custom gesture has been detected.
47 A Custom gesture is one which is custom-written for use in an application or toolkit and
48 is not shipped with EFL.
49 ]]
46 } 50 }
47} 51}
diff --git a/src/lib/evas/gesture/efl_canvas_gesture_manager.c b/src/lib/evas/gesture/efl_canvas_gesture_manager.c
index c78682c7c3..180cddb2be 100644
--- a/src/lib/evas/gesture/efl_canvas_gesture_manager.c
+++ b/src/lib/evas/gesture/efl_canvas_gesture_manager.c
@@ -1,4 +1,5 @@
1#define EFL_CANVAS_GESTURE_PROTECTED 1#define EFL_CANVAS_GESTURE_PROTECTED
2#define EFL_CANVAS_GESTURE_CUSTOM_PROTECTED
2#include "efl_canvas_gesture_private.h" 3#include "efl_canvas_gesture_private.h"
3 4
4#define MY_CLASS EFL_CANVAS_GESTURE_MANAGER_CLASS 5#define MY_CLASS EFL_CANVAS_GESTURE_MANAGER_CLASS
@@ -17,9 +18,10 @@ typedef struct _Efl_Canvas_Gesture_Manager_Data
17 //Keeps track of all the gesture request for a particular target 18 //Keeps track of all the gesture request for a particular target
18 Eina_Hash *m_gesture_contex; // (*target, Eina_Hash(type, int)) 19 Eina_Hash *m_gesture_contex; // (*target, Eina_Hash(type, int))
19 //Keeps all the event directed to this particular object from touch_begin till touch_end 20 //Keeps all the event directed to this particular object from touch_begin till touch_end
20 Eina_Hash *m_object_events; // (*target, *efl_gesture_touch) 21 Eina_Hash *m_object_events; // (*recognizer, *efl_gesture_touch)
21 //Keeps all the recognizer registered to gesture manager 22 //Keeps all the recognizer registered to gesture manager
22 Eina_Hash *m_recognizers; // (*gesture_type, *recognizer) 23 Eina_Hash *m_recognizers; // (*gesture_type, *recognizer)
24 Eina_List *custom_recognizers;
23 //Keeps track of all current object gestures. 25 //Keeps track of all current object gestures.
24 Eina_List *m_object_gestures; //(List of *object_gesture) 26 Eina_List *m_object_gestures; //(List of *object_gesture)
25 //Lazy deletion of gestures 27 //Lazy deletion of gestures
@@ -29,7 +31,7 @@ typedef struct _Efl_Canvas_Gesture_Manager_Data
29} Efl_Canvas_Gesture_Manager_Data; 31} Efl_Canvas_Gesture_Manager_Data;
30 32
31static void _cleanup_cached_gestures(Efl_Canvas_Gesture_Manager_Data *pd, 33static void _cleanup_cached_gestures(Efl_Canvas_Gesture_Manager_Data *pd,
32 Eo *target, const Efl_Event_Description *type); 34 Eo *target, const Efl_Event_Description *type, Efl_Canvas_Gesture_Recognizer *recognizer);
33static Efl_Canvas_Gesture * 35static Efl_Canvas_Gesture *
34 _get_state(Efl_Canvas_Gesture_Manager_Data *pd, Eo *target, 36 _get_state(Efl_Canvas_Gesture_Manager_Data *pd, Eo *target,
35 Efl_Canvas_Gesture_Recognizer *recognizer, const Efl_Event_Description *type); 37 Efl_Canvas_Gesture_Recognizer *recognizer, const Efl_Event_Description *type);
@@ -151,8 +153,12 @@ _efl_canvas_gesture_manager_config_set(Eo *obj, Efl_Canvas_Gesture_Manager_Data
151EOLIAN static void 153EOLIAN static void
152_efl_canvas_gesture_manager_efl_object_destructor(Eo *obj, Efl_Canvas_Gesture_Manager_Data *pd EINA_UNUSED) 154_efl_canvas_gesture_manager_efl_object_destructor(Eo *obj, Efl_Canvas_Gesture_Manager_Data *pd EINA_UNUSED)
153{ 155{
156 Efl_Canvas_Gesture_Recognizer *recognizer;
157
154 eina_hash_free(pd->m_config); 158 eina_hash_free(pd->m_config);
155 eina_hash_free(pd->m_recognizers); 159 eina_hash_free(pd->m_recognizers);
160 EINA_LIST_FREE(pd->custom_recognizers, recognizer)
161 efl_unref(recognizer);
156 eina_hash_free(pd->m_gesture_contex); 162 eina_hash_free(pd->m_gesture_contex);
157 eina_hash_free(pd->m_object_events); 163 eina_hash_free(pd->m_object_events);
158 _cleanup_object(pd->m_gestures_to_delete); 164 _cleanup_object(pd->m_gestures_to_delete);
@@ -172,7 +178,12 @@ _efl_canvas_gesture_manager_callback_add_hook(void *data, Eo *target, const Efl_
172{ 178{
173 Efl_Canvas_Gesture_Manager_Data *pd = data; 179 Efl_Canvas_Gesture_Manager_Data *pd = data;
174 //If there is a recognizer registered for that event then add it to the gesture context 180 //If there is a recognizer registered for that event then add it to the gesture context
175 Efl_Canvas_Gesture_Recognizer *recognizer = eina_hash_find(pd->m_recognizers, &type); 181 Efl_Canvas_Gesture_Recognizer *recognizer;
182
183 if (type == EFL_EVENT_GESTURE_CUSTOM)
184 recognizer = eina_list_data_get(pd->custom_recognizers);
185 else
186 recognizer = eina_hash_find(pd->m_recognizers, &type);
176 if (recognizer) 187 if (recognizer)
177 { 188 {
178 //Add it to the gesture context. 189 //Add it to the gesture context.
@@ -196,7 +207,12 @@ _efl_canvas_gesture_manager_callback_del_hook(void *data, Eo *target, const Efl_
196{ 207{
197 Efl_Canvas_Gesture_Manager_Data *pd = data; 208 Efl_Canvas_Gesture_Manager_Data *pd = data;
198 //If there is a recognizer registered for that event then add it to the gesture context 209 //If there is a recognizer registered for that event then add it to the gesture context
199 Efl_Canvas_Gesture_Recognizer *recognizer = eina_hash_find(pd->m_recognizers, &type); 210 Efl_Canvas_Gesture_Recognizer *recognizer;
211
212 if (type == EFL_EVENT_GESTURE_CUSTOM)
213 recognizer = eina_list_data_get(pd->custom_recognizers);
214 else
215 recognizer = eina_hash_find(pd->m_recognizers, &type);
200 if (recognizer) 216 if (recognizer)
201 { 217 {
202 Eina_Hash *thisisreallystupid = eina_hash_find(pd->m_gesture_contex, &target); 218 Eina_Hash *thisisreallystupid = eina_hash_find(pd->m_gesture_contex, &target);
@@ -211,20 +227,38 @@ _efl_canvas_gesture_manager_callback_del_hook(void *data, Eo *target, const Efl_
211 eina_hash_del_by_key(thisisreallystupid, &type); 227 eina_hash_del_by_key(thisisreallystupid, &type);
212 if (eina_hash_population(thisisreallystupid)) return; 228 if (eina_hash_population(thisisreallystupid)) return;
213 eina_hash_del_by_key(pd->m_gesture_contex, &target); 229 eina_hash_del_by_key(pd->m_gesture_contex, &target);
214 _cleanup_cached_gestures(pd, target, type); 230 _cleanup_cached_gestures(pd, target, type, NULL);
215 } 231 }
216} 232}
217 233
218static void 234static void
219_gesture_recognizer_process_internal(Efl_Canvas_Gesture_Manager_Data *pd, Efl_Canvas_Gesture_Recognizer *recognizer, 235_gesture_recognizer_process_internal(Efl_Canvas_Gesture_Manager_Data *pd, Efl_Canvas_Gesture_Recognizer *recognizer,
220 Eo *target, const Efl_Event_Description *gesture_type, Efl_Canvas_Gesture_Touch *touch_event) 236 Eo *target, const Efl_Event_Description *gesture_type, void *event)
221{ 237{
222 Efl_Canvas_Gesture_Recognizer_Result recog_result; 238 Efl_Canvas_Gesture_Recognizer_Result recog_result;
223 Efl_Canvas_Gesture_Recognizer_Result recog_state; 239 Efl_Canvas_Gesture_Recognizer_Result recog_state;
240 Efl_Canvas_Gesture_Touch *touch_event;
224 //If the gesture canceled or already finished by recognizer. 241 //If the gesture canceled or already finished by recognizer.
225 Efl_Canvas_Gesture *gesture = _get_state(pd, target, recognizer, gesture_type); 242 Efl_Canvas_Gesture *gesture = _get_state(pd, target, recognizer, gesture_type);
226 if (!gesture) return; 243 if (!gesture) return;
227 244
245 //Check there is already created event exist or not.
246 touch_event = eina_hash_find(pd->m_object_events, &recognizer);
247
248 if (!touch_event)
249 {
250 touch_event = efl_add_ref(EFL_CANVAS_GESTURE_TOUCH_CLASS, NULL);
251 eina_hash_add(pd->m_object_events, &recognizer, touch_event);
252 }
253
254 efl_gesture_touch_point_record(touch_event, event);
255
256 //This is for handling the case that mouse event pairs dont match.
257 //Such as the case of canceling gesture recognition after a mouse down.
258 if (efl_gesture_touch_state_get(touch_event) == EFL_GESTURE_TOUCH_STATE_UNKNOWN)
259 return;
260
261
228 /* this is the "default" value for the event, recognizers may modify it if necessary */ 262 /* this is the "default" value for the event, recognizers may modify it if necessary */
229 efl_gesture_touch_count_set(gesture, efl_gesture_touch_points_count_get(touch_event)); 263 efl_gesture_touch_count_set(gesture, efl_gesture_touch_points_count_get(touch_event));
230 264
@@ -273,8 +307,8 @@ post_event:
273 if (((recog_state == EFL_GESTURE_RECOGNIZER_RESULT_FINISH) || (recog_state == EFL_GESTURE_RECOGNIZER_RESULT_CANCEL)) && 307 if (((recog_state == EFL_GESTURE_RECOGNIZER_RESULT_FINISH) || (recog_state == EFL_GESTURE_RECOGNIZER_RESULT_CANCEL)) &&
274 !rd->continues) 308 !rd->continues)
275 { 309 {
276 _cleanup_cached_gestures(pd, target, gesture_type); 310 _cleanup_cached_gestures(pd, target, gesture_type, recognizer);
277 eina_hash_del(pd->m_object_events, &gesture_type, NULL); 311 eina_hash_del(pd->m_object_events, &recognizer, NULL);
278 //FIXME: delete it by object not list. 312 //FIXME: delete it by object not list.
279 _cleanup_object(pd->m_gestures_to_delete); 313 _cleanup_object(pd->m_gestures_to_delete);
280 pd->m_gestures_to_delete = NULL; 314 pd->m_gestures_to_delete = NULL;
@@ -289,7 +323,6 @@ _efl_canvas_gesture_manager_filter_event(void *data, Eo *target, void *event)
289 Eina_Iterator *it; 323 Eina_Iterator *it;
290 Eina_Hash_Tuple *tup; 324 Eina_Hash_Tuple *tup;
291 Efl_Canvas_Gesture_Recognizer *recognizer; 325 Efl_Canvas_Gesture_Recognizer *recognizer;
292 Efl_Canvas_Gesture_Touch *touch_event;
293 326
294 thisisreallystupid = eina_hash_find(pd->m_gesture_contex, &target); 327 thisisreallystupid = eina_hash_find(pd->m_gesture_contex, &target);
295 if (!thisisreallystupid) return; 328 if (!thisisreallystupid) return;
@@ -297,24 +330,18 @@ _efl_canvas_gesture_manager_filter_event(void *data, Eo *target, void *event)
297 EINA_ITERATOR_FOREACH(it, tup) 330 EINA_ITERATOR_FOREACH(it, tup)
298 { 331 {
299 const Efl_Event_Description *gesture_type = *(void**)tup->key; 332 const Efl_Event_Description *gesture_type = *(void**)tup->key;
300 //Check there is already created event exist or not.
301 touch_event = eina_hash_find(pd->m_object_events, &gesture_type);
302 333
303 if (!touch_event) 334 if (gesture_type == EFL_EVENT_GESTURE_CUSTOM)
304 { 335 {
305 touch_event = efl_add_ref(EFL_CANVAS_GESTURE_TOUCH_CLASS, NULL); 336 Eina_List *l;
306 eina_hash_add(pd->m_object_events, &gesture_type, touch_event); 337 EINA_LIST_FOREACH(pd->custom_recognizers, l, recognizer)
338 _gesture_recognizer_process_internal(pd, recognizer, target, gesture_type, event);
339 }
340 else
341 {
342 recognizer = eina_hash_find(pd->m_recognizers, &gesture_type);
343 _gesture_recognizer_process_internal(pd, recognizer, target, gesture_type, event);
307 } 344 }
308
309 efl_gesture_touch_point_record(touch_event, event);
310
311 //This is for handling the case that mouse event pairs dont match.
312 //Such as the case of canceling gesture recognition after a mouse down.
313 if (efl_gesture_touch_state_get(touch_event) == EFL_GESTURE_TOUCH_STATE_UNKNOWN)
314 continue;
315
316 recognizer = eina_hash_find(pd->m_recognizers, &gesture_type);
317 _gesture_recognizer_process_internal(pd, recognizer, target, gesture_type, touch_event);
318 } 345 }
319 eina_iterator_free(it); 346 eina_iterator_free(it);
320} 347}
@@ -329,11 +356,19 @@ _efl_canvas_gesture_manager_recognizer_register(Eo *obj EINA_UNUSED, Efl_Canvas_
329 return; 356 return;
330 357
331 const Efl_Event_Description *type = _efl_gesture_type_get(dummy); 358 const Efl_Event_Description *type = _efl_gesture_type_get(dummy);
332 359 efl_del(dummy);
333 //Add the recognizer to the m_recognizers 360 //Add the recognizer to the m_recognizers
334 eina_hash_add(pd->m_recognizers, &type, efl_ref(recognizer)); 361 if (type == EFL_EVENT_GESTURE_CUSTOM)
362 {
363 EINA_SAFETY_ON_TRUE_RETURN(pd->custom_recognizers && eina_list_data_find(pd->custom_recognizers, recognizer));
364 pd->custom_recognizers = eina_list_append(pd->custom_recognizers, efl_ref(recognizer));
365 }
366 else
367 {
368 EINA_SAFETY_ON_TRUE_RETURN(!!eina_hash_find(pd->m_recognizers, &type));
369 eina_hash_add(pd->m_recognizers, &type, efl_ref(recognizer));
370 }
335 371
336 efl_del(dummy);
337} 372}
338 373
339EOLIAN static void 374EOLIAN static void
@@ -353,24 +388,31 @@ _efl_canvas_gesture_manager_recognizer_unregister(Eo *obj EINA_UNUSED, Efl_Canva
353 388
354 type = _efl_gesture_type_get(dummy); 389 type = _efl_gesture_type_get(dummy);
355 efl_del(dummy); 390 efl_del(dummy);
356
357 //Check if its already registered 391 //Check if its already registered
358 recognizer = eina_hash_find(pd->m_recognizers, &type); 392 if (type == EFL_EVENT_GESTURE_CUSTOM)
359 393 {
360 if (!recognizer) return; 394 EINA_SAFETY_ON_TRUE_RETURN((!pd->custom_recognizers) || (!eina_list_data_find(pd->custom_recognizers, recognizer)));
395 pd->custom_recognizers = eina_list_remove(pd->custom_recognizers, recognizer);
396 eina_hash_del_by_key(pd->m_object_events, &recognizer);
397 efl_unref(recognizer);
398 }
399 else
400 {
401 EINA_SAFETY_ON_TRUE_RETURN(!eina_hash_find(pd->m_recognizers, &type));
402 eina_hash_del_by_key(pd->m_object_events, &recognizer);
403 eina_hash_del_by_key(pd->m_recognizers, &type);
404 }
361 405
362 //Remove that gesture from the list of object gestures 406 //Remove that gesture from the list of object gestures
363 EINA_LIST_FOREACH_SAFE(pd->m_object_gestures, l, l_next, object_gesture) 407 EINA_LIST_FOREACH_SAFE(pd->m_object_gestures, l, l_next, object_gesture)
364 { 408 {
365 if (object_gesture->type == type) 409 if ((object_gesture->type == type) && (object_gesture->recognizer == recognizer))
366 { 410 {
367 pd->m_gestures_to_delete = eina_list_append(pd->m_gestures_to_delete, object_gesture->gesture); 411 pd->m_gestures_to_delete = eina_list_append(pd->m_gestures_to_delete, object_gesture->gesture);
368 free(object_gesture); 412 free(object_gesture);
369 pd->m_object_gestures = eina_list_remove_list(pd->m_object_gestures, l); 413 pd->m_object_gestures = eina_list_remove_list(pd->m_object_gestures, l);
370 } 414 }
371 } 415 }
372
373 eina_hash_del(pd->m_recognizers, &type, NULL);
374} 416}
375 417
376// EOLIAN static void 418// EOLIAN static void
@@ -419,8 +461,8 @@ _get_state(Efl_Canvas_Gesture_Manager_Data *pd,
419 (efl_gesture_state_get(object_gesture->gesture) == EFL_GESTURE_STATE_CANCELED)) && 461 (efl_gesture_state_get(object_gesture->gesture) == EFL_GESTURE_STATE_CANCELED)) &&
420 (!rd->continues)) 462 (!rd->continues))
421 { 463 {
422 _cleanup_cached_gestures(pd, target, type); 464 _cleanup_cached_gestures(pd, target, type, recognizer);
423 eina_hash_del(pd->m_object_events, &type, NULL); 465 eina_hash_del(pd->m_object_events, &recognizer, NULL);
424 _cleanup_object(pd->m_gestures_to_delete); 466 _cleanup_object(pd->m_gestures_to_delete);
425 pd->m_gestures_to_delete = NULL; 467 pd->m_gestures_to_delete = NULL;
426 return NULL; 468 return NULL;
@@ -438,6 +480,8 @@ _get_state(Efl_Canvas_Gesture_Manager_Data *pd,
438 object_gesture->recognizer = recognizer; 480 object_gesture->recognizer = recognizer;
439 object_gesture->type = type; 481 object_gesture->type = type;
440 object_gesture->gesture = gesture; 482 object_gesture->gesture = gesture;
483 if (type == EFL_EVENT_GESTURE_CUSTOM)
484 efl_gesture_custom_gesture_name_set(gesture, efl_gesture_recognizer_custom_gesture_name_get(recognizer));
441 485
442 pd->m_object_gestures = eina_list_append(pd->m_object_gestures, object_gesture); 486 pd->m_object_gestures = eina_list_append(pd->m_object_gestures, object_gesture);
443 487
@@ -446,14 +490,15 @@ _get_state(Efl_Canvas_Gesture_Manager_Data *pd,
446 490
447static void 491static void
448_cleanup_cached_gestures(Efl_Canvas_Gesture_Manager_Data *pd, 492_cleanup_cached_gestures(Efl_Canvas_Gesture_Manager_Data *pd,
449 Eo *target, const Efl_Event_Description *type) 493 Eo *target, const Efl_Event_Description *type, Efl_Canvas_Gesture_Recognizer *recognizer)
450{ 494{
451 Eina_List *l, *l_next; 495 Eina_List *l, *l_next;
452 Object_Gesture *object_gesture; 496 Object_Gesture *object_gesture;
453 497
454 EINA_LIST_FOREACH_SAFE(pd->m_object_gestures, l, l_next, object_gesture) 498 EINA_LIST_FOREACH_SAFE(pd->m_object_gestures, l, l_next, object_gesture)
455 { 499 {
456 if ((object_gesture->type == type) && (target == object_gesture->object)) 500 if ((object_gesture->type == type) && (target == object_gesture->object) &&
501 ((!recognizer) || (object_gesture->recognizer == recognizer)))
457 { 502 {
458 pd->m_gestures_to_delete = eina_list_append(pd->m_gestures_to_delete, object_gesture->gesture); 503 pd->m_gestures_to_delete = eina_list_append(pd->m_gestures_to_delete, object_gesture->gesture);
459 free(object_gesture); 504 free(object_gesture);
@@ -463,12 +508,13 @@ _cleanup_cached_gestures(Efl_Canvas_Gesture_Manager_Data *pd,
463} 508}
464 509
465void 510void
466efl_gesture_manager_gesture_clean_up(Eo *obj, Eo *target, const Efl_Event_Description *type) 511efl_gesture_manager_gesture_clean_up(Eo *obj, Eo *target, const Efl_Event_Description *type, Efl_Canvas_Gesture_Recognizer *recognizer)
467{ 512{
468 Efl_Canvas_Gesture_Manager_Data *pd = efl_data_scope_get(obj, MY_CLASS); 513 Efl_Canvas_Gesture_Manager_Data *pd = efl_data_scope_get(obj, MY_CLASS);
469 514
470 _cleanup_cached_gestures(pd, target, type); 515 EINA_SAFETY_ON_NULL_RETURN(recognizer);
471 eina_hash_del(pd->m_object_events, &type, NULL); 516 _cleanup_cached_gestures(pd, target, type, recognizer);
517 eina_hash_del(pd->m_object_events, &recognizer, NULL);
472 _cleanup_object(pd->m_gestures_to_delete); 518 _cleanup_object(pd->m_gestures_to_delete);
473 pd->m_gestures_to_delete = NULL; 519 pd->m_gestures_to_delete = NULL;
474} 520}
diff --git a/src/lib/evas/gesture/efl_canvas_gesture_private.h b/src/lib/evas/gesture/efl_canvas_gesture_private.h
index 5c32703d18..dadf5c0123 100644
--- a/src/lib/evas/gesture/efl_canvas_gesture_private.h
+++ b/src/lib/evas/gesture/efl_canvas_gesture_private.h
@@ -12,7 +12,7 @@
12#define TAP_TOUCH_TIME_THRESHOLD (0.1 * 1000) 12#define TAP_TOUCH_TIME_THRESHOLD (0.1 * 1000)
13 13
14const Efl_Event_Description * _efl_gesture_type_get(const Eo *obj); 14const Efl_Event_Description * _efl_gesture_type_get(const Eo *obj);
15void efl_gesture_manager_gesture_clean_up(Eo *obj, Eo *target, const Efl_Event_Description *type); 15void efl_gesture_manager_gesture_clean_up(Eo *obj, Eo *target, const Efl_Event_Description *type, Efl_Canvas_Gesture_Recognizer *recognizer);
16int _direction_get(Evas_Coord xx1, Evas_Coord xx2); 16int _direction_get(Evas_Coord xx1, Evas_Coord xx2);
17Eina_Value *_recognizer_config_get(const Eo *obj, const char *name); 17Eina_Value *_recognizer_config_get(const Eo *obj, const char *name);
18 18
@@ -25,10 +25,12 @@ typedef struct _Efl_Canvas_Gesture_Recognizer_Triple_Tap_Data Efl_Canvas_Gestur
25typedef struct _Efl_Canvas_Gesture_Recognizer_Momentum_Data Efl_Canvas_Gesture_Recognizer_Momentum_Data; 25typedef struct _Efl_Canvas_Gesture_Recognizer_Momentum_Data Efl_Canvas_Gesture_Recognizer_Momentum_Data;
26typedef struct _Efl_Canvas_Gesture_Recognizer_Flick_Data Efl_Canvas_Gesture_Recognizer_Flick_Data; 26typedef struct _Efl_Canvas_Gesture_Recognizer_Flick_Data Efl_Canvas_Gesture_Recognizer_Flick_Data;
27typedef struct _Efl_Canvas_Gesture_Recognizer_Zoom_Data Efl_Canvas_Gesture_Recognizer_Zoom_Data; 27typedef struct _Efl_Canvas_Gesture_Recognizer_Zoom_Data Efl_Canvas_Gesture_Recognizer_Zoom_Data;
28typedef struct _Efl_Canvas_Gesture_Recognizer_Custom_Data Efl_Canvas_Gesture_Recognizer_Custom_Data;
28typedef struct _Efl_Canvas_Gesture_Data Efl_Canvas_Gesture_Data; 29typedef struct _Efl_Canvas_Gesture_Data Efl_Canvas_Gesture_Data;
29typedef struct _Efl_Canvas_Gesture_Momentum_Data Efl_Canvas_Gesture_Momentum_Data; 30typedef struct _Efl_Canvas_Gesture_Momentum_Data Efl_Canvas_Gesture_Momentum_Data;
30typedef struct _Efl_Canvas_Gesture_Flick_Data Efl_Canvas_Gesture_Flick_Data; 31typedef struct _Efl_Canvas_Gesture_Flick_Data Efl_Canvas_Gesture_Flick_Data;
31typedef struct _Efl_Canvas_Gesture_Zoom_Data Efl_Canvas_Gesture_Zoom_Data; 32typedef struct _Efl_Canvas_Gesture_Zoom_Data Efl_Canvas_Gesture_Zoom_Data;
33typedef struct _Efl_Canvas_Gesture_Custom_Data Efl_Canvas_Gesture_Custom_Data;
32 34
33typedef struct _Efl_Canvas_Gesture_Touch_Data 35typedef struct _Efl_Canvas_Gesture_Touch_Data
34{ 36{
@@ -130,6 +132,11 @@ struct _Efl_Canvas_Gesture_Recognizer_Zoom_Data
130 Eina_Bool calc_temp; 132 Eina_Bool calc_temp;
131}; 133};
132 134
135struct _Efl_Canvas_Gesture_Recognizer_Custom_Data
136{
137 Eina_Stringshare *name;
138};
139
133struct _Efl_Canvas_Gesture_Data 140struct _Efl_Canvas_Gesture_Data
134{ 141{
135 Efl_Canvas_Gesture_State state; 142 Efl_Canvas_Gesture_State state;
@@ -158,4 +165,9 @@ struct _Efl_Canvas_Gesture_Zoom_Data
158 double zoom; 165 double zoom;
159}; 166};
160 167
168struct _Efl_Canvas_Gesture_Custom_Data
169{
170 Eina_Stringshare *gesture_name;
171};
172
161#endif 173#endif
diff --git a/src/lib/evas/gesture/efl_canvas_gesture_recognizer_custom.c b/src/lib/evas/gesture/efl_canvas_gesture_recognizer_custom.c
new file mode 100644
index 0000000000..8900abe71a
--- /dev/null
+++ b/src/lib/evas/gesture/efl_canvas_gesture_recognizer_custom.c
@@ -0,0 +1,32 @@
1#include "efl_canvas_gesture_private.h"
2
3#define MY_CLASS EFL_CANVAS_GESTURE_RECOGNIZER_CUSTOM_CLASS
4
5
6EOLIAN static Eo *
7_efl_canvas_gesture_recognizer_custom_efl_object_finalize(Eo *obj, Efl_Canvas_Gesture_Recognizer_Custom_Data *pd)
8{
9 EINA_SAFETY_ON_NULL_RETURN_VAL(pd->name, NULL);
10 return efl_finalize(efl_super(obj, MY_CLASS));
11}
12
13EOLIAN static void
14_efl_canvas_gesture_recognizer_custom_efl_object_destructor(Eo *obj, Efl_Canvas_Gesture_Recognizer_Custom_Data *pd)
15{
16 eina_stringshare_del(pd->name);
17 efl_destructor(efl_super(obj, MY_CLASS));
18}
19
20EOLIAN static void
21_efl_canvas_gesture_recognizer_custom_gesture_name_set(Eo *obj EINA_UNUSED, Efl_Canvas_Gesture_Recognizer_Custom_Data *pd, const char *name)
22{
23 eina_stringshare_replace(&pd->name, name);
24}
25
26EOLIAN static Eina_Stringshare *
27_efl_canvas_gesture_recognizer_custom_gesture_name_get(const Eo *obj EINA_UNUSED, Efl_Canvas_Gesture_Recognizer_Custom_Data *pd)
28{
29 return pd->name;
30}
31
32#include "efl_canvas_gesture_recognizer_custom.eo.c"
diff --git a/src/lib/evas/gesture/efl_canvas_gesture_recognizer_custom.eo b/src/lib/evas/gesture/efl_canvas_gesture_recognizer_custom.eo
new file mode 100644
index 0000000000..f691694e8c
--- /dev/null
+++ b/src/lib/evas/gesture/efl_canvas_gesture_recognizer_custom.eo
@@ -0,0 +1,23 @@
1abstract @beta Efl.Canvas.Gesture_Recognizer_Custom extends Efl.Canvas.Gesture_Recognizer
2{
3 [[This is the recognizer for Custom gestures.
4 See @Efl.Canvas.Gesture_Recognizer.
5 ]]
6 c_prefix: efl_gesture_recognizer_custom;
7 methods {
8 @property gesture_name {
9 [[This is the name of the gesture recognizer.]]
10 get {
11 }
12 set {
13 }
14 values {
15 gesture_name: string; [[The name of the gesture recognizer.]]
16 }
17 }
18 }
19 implements {
20 Efl.Object.destructor;
21 Efl.Object.finalize;
22 }
23}
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
index f6c7e0e44c..1db46da7c3 100644
--- a/src/lib/evas/gesture/efl_canvas_gesture_recognizer_double_tap.c
+++ b/src/lib/evas/gesture/efl_canvas_gesture_recognizer_double_tap.c
@@ -31,7 +31,7 @@ _tap_timeout_cb(void *data)
31 efl_event_callback_call(pd->target, EFL_EVENT_GESTURE_DOUBLE_TAP, pd->gesture); 31 efl_event_callback_call(pd->target, EFL_EVENT_GESTURE_DOUBLE_TAP, pd->gesture);
32 32
33 efl_gesture_manager_gesture_clean_up(efl_provider_find(data, EFL_CANVAS_GESTURE_MANAGER_CLASS), 33 efl_gesture_manager_gesture_clean_up(efl_provider_find(data, EFL_CANVAS_GESTURE_MANAGER_CLASS),
34 pd->target, EFL_EVENT_GESTURE_DOUBLE_TAP); 34 pd->target, EFL_EVENT_GESTURE_DOUBLE_TAP, data);
35 35
36 pd->timeout = NULL; 36 pd->timeout = NULL;
37 pd->tap_count = 0; 37 pd->tap_count = 0;
diff --git a/src/lib/evas/gesture/efl_canvas_gesture_recognizer_flick.c b/src/lib/evas/gesture/efl_canvas_gesture_recognizer_flick.c
index 3b89ebec32..de45dd762a 100644
--- a/src/lib/evas/gesture/efl_canvas_gesture_recognizer_flick.c
+++ b/src/lib/evas/gesture/efl_canvas_gesture_recognizer_flick.c
@@ -212,7 +212,7 @@ _efl_canvas_gesture_recognizer_flick_efl_canvas_gesture_recognizer_recognize(Eo
212 //This is to handle a case with a mouse click on the target object. 212 //This is to handle a case with a mouse click on the target object.
213 if (efl_gesture_touch_state_get(event) == EFL_GESTURE_TOUCH_STATE_END && !pd->touched) 213 if (efl_gesture_touch_state_get(event) == EFL_GESTURE_TOUCH_STATE_END && !pd->touched)
214 { 214 {
215 efl_gesture_manager_gesture_clean_up(efl_provider_find(obj, EFL_CANVAS_GESTURE_MANAGER_CLASS), watched, EFL_EVENT_GESTURE_FLICK); 215 efl_gesture_manager_gesture_clean_up(efl_provider_find(obj, EFL_CANVAS_GESTURE_MANAGER_CLASS), watched, EFL_EVENT_GESTURE_FLICK, obj);
216 dead = EINA_TRUE; 216 dead = EINA_TRUE;
217 } 217 }
218 218
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
index 9c7a70a2e4..3144aa30d1 100644
--- a/src/lib/evas/gesture/efl_canvas_gesture_recognizer_triple_tap.c
+++ b/src/lib/evas/gesture/efl_canvas_gesture_recognizer_triple_tap.c
@@ -30,7 +30,7 @@ _tap_timeout_cb(void *data)
30 efl_gesture_state_set(pd->gesture, EFL_GESTURE_STATE_CANCELED); 30 efl_gesture_state_set(pd->gesture, EFL_GESTURE_STATE_CANCELED);
31 efl_event_callback_call(pd->target, EFL_EVENT_GESTURE_TRIPLE_TAP, pd->gesture); 31 efl_event_callback_call(pd->target, EFL_EVENT_GESTURE_TRIPLE_TAP, pd->gesture);
32 32
33 efl_gesture_manager_gesture_clean_up(efl_provider_find(data, EFL_CANVAS_GESTURE_MANAGER_CLASS), pd->target, EFL_EVENT_GESTURE_TRIPLE_TAP); 33 efl_gesture_manager_gesture_clean_up(efl_provider_find(data, EFL_CANVAS_GESTURE_MANAGER_CLASS), pd->target, EFL_EVENT_GESTURE_TRIPLE_TAP, data);
34 34
35 pd->timeout = NULL; 35 pd->timeout = NULL;
36 pd->tap_count = 0; 36 pd->tap_count = 0;
diff --git a/src/lib/evas/gesture/efl_canvas_gesture_recognizer_zoom.c b/src/lib/evas/gesture/efl_canvas_gesture_recognizer_zoom.c
index 2857dd30d2..40e638a5df 100644
--- a/src/lib/evas/gesture/efl_canvas_gesture_recognizer_zoom.c
+++ b/src/lib/evas/gesture/efl_canvas_gesture_recognizer_zoom.c
@@ -267,7 +267,7 @@ _efl_canvas_gesture_recognizer_zoom_efl_canvas_gesture_recognizer_recognize(Eo *
267 rd->continues = EINA_FALSE; 267 rd->continues = EINA_FALSE;
268 268
269 _reset_recognizer(pd); 269 _reset_recognizer(pd);
270 efl_gesture_manager_gesture_clean_up(efl_provider_find(obj, EFL_CANVAS_GESTURE_MANAGER_CLASS), watched, EFL_EVENT_GESTURE_ZOOM); 270 efl_gesture_manager_gesture_clean_up(efl_provider_find(obj, EFL_CANVAS_GESTURE_MANAGER_CLASS), watched, EFL_EVENT_GESTURE_ZOOM, obj);
271 271
272 return EFL_GESTURE_RECOGNIZER_RESULT_IGNORE; 272 return EFL_GESTURE_RECOGNIZER_RESULT_IGNORE;
273 } 273 }
diff --git a/src/lib/evas/gesture/efl_canvas_gesture_types.eot b/src/lib/evas/gesture/efl_canvas_gesture_types.eot
index ad3ebd7c64..e48c0abf3d 100644
--- a/src/lib/evas/gesture/efl_canvas_gesture_types.eot
+++ b/src/lib/evas/gesture/efl_canvas_gesture_types.eot
@@ -46,6 +46,7 @@ enum @beta Efl.Canvas.Gesture_Recognizer_Type
46 momentum, 46 momentum,
47 flick, 47 flick,
48 zoom, 48 zoom,
49 custom,
49} 50}
50 51
51struct @beta @c_name(Efl_Gesture_Touch_Point_Info) Efl.Canvas.Gesture_Touch_Point_Info { 52struct @beta @c_name(Efl_Gesture_Touch_Point_Info) Efl.Canvas.Gesture_Touch_Point_Info {
diff --git a/src/lib/evas/gesture/meson.build b/src/lib/evas/gesture/meson.build
index 7838efdc9d..5daa6f6f30 100644
--- a/src/lib/evas/gesture/meson.build
+++ b/src/lib/evas/gesture/meson.build
@@ -8,6 +8,7 @@ pub_eo_files = [
8 'efl_canvas_gesture_momentum.eo', 8 'efl_canvas_gesture_momentum.eo',
9 'efl_canvas_gesture_flick.eo', 9 'efl_canvas_gesture_flick.eo',
10 'efl_canvas_gesture_zoom.eo', 10 'efl_canvas_gesture_zoom.eo',
11 'efl_canvas_gesture_custom.eo',
11 'efl_canvas_gesture_recognizer.eo', 12 'efl_canvas_gesture_recognizer.eo',
12 'efl_canvas_gesture_recognizer_tap.eo', 13 'efl_canvas_gesture_recognizer_tap.eo',
13 'efl_canvas_gesture_recognizer_double_tap.eo', 14 'efl_canvas_gesture_recognizer_double_tap.eo',
@@ -16,6 +17,7 @@ pub_eo_files = [
16 'efl_canvas_gesture_recognizer_momentum.eo', 17 'efl_canvas_gesture_recognizer_momentum.eo',
17 'efl_canvas_gesture_recognizer_flick.eo', 18 'efl_canvas_gesture_recognizer_flick.eo',
18 'efl_canvas_gesture_recognizer_zoom.eo', 19 'efl_canvas_gesture_recognizer_zoom.eo',
20 'efl_canvas_gesture_recognizer_custom.eo',
19 'efl_canvas_gesture_manager.eo', 21 'efl_canvas_gesture_manager.eo',
20 'efl_canvas_gesture_events.eo' 22 'efl_canvas_gesture_events.eo'
21] 23]
@@ -70,6 +72,7 @@ evas_src += files([
70 'efl_canvas_gesture_momentum.c', 72 'efl_canvas_gesture_momentum.c',
71 'efl_canvas_gesture_flick.c', 73 'efl_canvas_gesture_flick.c',
72 'efl_canvas_gesture_zoom.c', 74 'efl_canvas_gesture_zoom.c',
75 'efl_canvas_gesture_custom.c',
73 'efl_canvas_gesture_recognizer.c', 76 'efl_canvas_gesture_recognizer.c',
74 'efl_canvas_gesture_recognizer_tap.c', 77 'efl_canvas_gesture_recognizer_tap.c',
75 'efl_canvas_gesture_recognizer_double_tap.c', 78 'efl_canvas_gesture_recognizer_double_tap.c',
@@ -78,6 +81,7 @@ evas_src += files([
78 'efl_canvas_gesture_recognizer_momentum.c', 81 'efl_canvas_gesture_recognizer_momentum.c',
79 'efl_canvas_gesture_recognizer_flick.c', 82 'efl_canvas_gesture_recognizer_flick.c',
80 'efl_canvas_gesture_recognizer_zoom.c', 83 'efl_canvas_gesture_recognizer_zoom.c',
84 'efl_canvas_gesture_recognizer_custom.c',
81 'efl_canvas_gesture_manager.c', 85 'efl_canvas_gesture_manager.c',
82]) 86])
83 87