1 #define EFL_CANVAS_GESTURE_PROTECTED
2 #define EFL_CANVAS_GESTURE_CUSTOM_PROTECTED
3 #include "efl_canvas_gesture_private.h"
4
5 #define MY_CLASS EFL_CANVAS_GESTURE_MANAGER_CLASS
6
7 typedef struct _Object_Gesture
8 {
9 Eo *object;
10 const Efl_Event_Description *type;
11 Efl_Canvas_Gesture *gesture;
12 Efl_Canvas_Gesture_Recognizer *recognizer;
13 } Object_Gesture;
14
15 typedef struct _Efl_Canvas_Gesture_Manager_Data
16 {
17 //Keeps track of all the gesture request for a particular target
18 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 Eina_Hash *m_object_events; // (*recognizer, *efl_gesture_touch)
21 //Keeps all the recognizer registered to gesture manager
22 Eina_Hash *m_recognizers; // (*gesture_type, *recognizer)
23 Eina_List *custom_recognizers;
24 //Keeps track of all current object gestures.
25 Eina_List *m_object_gestures; //(List of *object_gesture)
26 //Lazy deletion of gestures
27 Eina_Array *m_gestures_to_delete;
28 //Kepps config values for gesture recognize
29 Eina_Bool processing : 1;
30 } Efl_Canvas_Gesture_Manager_Data;
31
32 static void _cleanup_cached_gestures(Efl_Canvas_Gesture_Manager_Data *pd,
33 const Eo *target, const Efl_Event_Description *type, const Efl_Canvas_Gesture_Recognizer *recognizer);
34 static Efl_Canvas_Gesture *
35 _get_state(Efl_Canvas_Gesture_Manager_Data *pd, Eo *target,
36 Efl_Canvas_Gesture_Recognizer *recognizer, const Efl_Event_Description *type);
37
38 static const Efl_Event_Description *
_gesture_recognizer_event_type_get(const Efl_Canvas_Gesture_Recognizer * recognizer)39 _gesture_recognizer_event_type_get(const Efl_Canvas_Gesture_Recognizer *recognizer)
40 {
41 const Efl_Class *type = efl_gesture_recognizer_type_get(recognizer);
42
43 if (type == EFL_CANVAS_GESTURE_TAP_CLASS)
44 return EFL_EVENT_GESTURE_TAP;
45 if (type == EFL_CANVAS_GESTURE_DOUBLE_TAP_CLASS)
46 return EFL_EVENT_GESTURE_DOUBLE_TAP;
47 if (type == EFL_CANVAS_GESTURE_TRIPLE_TAP_CLASS)
48 return EFL_EVENT_GESTURE_TRIPLE_TAP;
49 if (type == EFL_CANVAS_GESTURE_LONG_PRESS_CLASS)
50 return EFL_EVENT_GESTURE_LONG_PRESS;
51 if (type == EFL_CANVAS_GESTURE_MOMENTUM_CLASS)
52 return EFL_EVENT_GESTURE_MOMENTUM;
53 if (type == EFL_CANVAS_GESTURE_FLICK_CLASS)
54 return EFL_EVENT_GESTURE_FLICK;
55 if (type == EFL_CANVAS_GESTURE_ROTATE_CLASS)
56 return EFL_EVENT_GESTURE_ROTATE;
57 if (type == EFL_CANVAS_GESTURE_ZOOM_CLASS)
58 return EFL_EVENT_GESTURE_ZOOM;
59 return EFL_EVENT_GESTURE_CUSTOM;
60 }
61
62 static void
_cleanup_object(Eina_Array * arr)63 _cleanup_object(Eina_Array *arr)
64 {
65 Eo *obj;
66
67 if (!eina_array_count(arr)) return;
68
69 while ((obj = eina_array_pop(arr)))
70 efl_del(obj);
71 }
72
73 static void
_hash_unref_cb(Eo * obj)74 _hash_unref_cb(Eo *obj)
75 {
76 efl_unref(obj);
77 }
78
79 /* updates the data for in-tree recognizers without needing to watch events */
80 static void
_update_finger_sizes(Efl_Canvas_Gesture_Manager_Data * pd,int finger_size)81 _update_finger_sizes(Efl_Canvas_Gesture_Manager_Data *pd, int finger_size)
82 {
83 Efl_Canvas_Gesture_Recognizer *r;
84 Efl_Canvas_Gesture_Recognizer_Tap_Data *td;
85 Efl_Canvas_Gesture_Recognizer_Double_Tap_Data *dtd;
86 Efl_Canvas_Gesture_Recognizer_Triple_Tap_Data *ttd;
87 Efl_Canvas_Gesture_Recognizer_Long_Press_Data *ltd;
88 Efl_Canvas_Gesture_Recognizer_Flick_Data *fd;
89 Efl_Canvas_Gesture_Recognizer_Rotate_Data *rd;
90 Efl_Canvas_Gesture_Recognizer_Zoom_Data *zd;
91 const Efl_Event_Description *type;
92
93 type = EFL_EVENT_GESTURE_TAP;
94 r = eina_hash_find(pd->m_recognizers, &type);
95 td = efl_data_scope_get(r, EFL_CANVAS_GESTURE_RECOGNIZER_TAP_CLASS);
96 td->finger_size = finger_size;
97
98 type = EFL_EVENT_GESTURE_DOUBLE_TAP;
99 r = eina_hash_find(pd->m_recognizers, &type);
100 dtd = efl_data_scope_get(r, EFL_CANVAS_GESTURE_RECOGNIZER_DOUBLE_TAP_CLASS);
101 dtd->finger_size = finger_size;
102
103 type = EFL_EVENT_GESTURE_TRIPLE_TAP;
104 r = eina_hash_find(pd->m_recognizers, &type);
105 ttd = efl_data_scope_get(r, EFL_CANVAS_GESTURE_RECOGNIZER_TRIPLE_TAP_CLASS);
106 ttd->finger_size = finger_size;
107
108 type = EFL_EVENT_GESTURE_LONG_PRESS;
109 r = eina_hash_find(pd->m_recognizers, &type);
110 ltd = efl_data_scope_get(r, EFL_CANVAS_GESTURE_RECOGNIZER_LONG_PRESS_CLASS);
111 ltd->finger_size = finger_size;
112
113 type = EFL_EVENT_GESTURE_FLICK;
114 r = eina_hash_find(pd->m_recognizers, &type);
115 fd = efl_data_scope_get(r, EFL_CANVAS_GESTURE_RECOGNIZER_FLICK_CLASS);
116 fd->finger_size = finger_size;
117
118 type = EFL_EVENT_GESTURE_ROTATE;
119 r = eina_hash_find(pd->m_recognizers, &type);
120 rd = efl_data_scope_get(r, EFL_CANVAS_GESTURE_RECOGNIZER_ROTATE_CLASS);
121 rd->finger_size = finger_size;
122
123 type = EFL_EVENT_GESTURE_ZOOM;
124 r = eina_hash_find(pd->m_recognizers, &type);
125 zd = efl_data_scope_get(r, EFL_CANVAS_GESTURE_RECOGNIZER_ZOOM_CLASS);
126 zd->finger_size = finger_size;
127 }
128
129 static void
_gesture_manager_config_changed(void * data,const Efl_Event * ev)130 _gesture_manager_config_changed(void *data, const Efl_Event *ev)
131 {
132 Efl_Canvas_Gesture_Manager_Data *pd = data;
133
134 if ((!ev->info) || eina_streq(ev->info, "glayer_tap_finger_size"))
135 _update_finger_sizes(pd, efl_config_int_get(ev->object, "glayer_tap_finger_size"));
136 }
137
138 EOLIAN static Efl_Object *
_efl_canvas_gesture_manager_efl_object_constructor(Eo * obj,Efl_Canvas_Gesture_Manager_Data * pd)139 _efl_canvas_gesture_manager_efl_object_constructor(Eo *obj, Efl_Canvas_Gesture_Manager_Data *pd)
140 {
141 Eo *config;
142 int finger_size = 0;
143 obj = efl_constructor(efl_super(obj, MY_CLASS));
144
145 pd->m_recognizers = eina_hash_pointer_new(EINA_FREE_CB(_hash_unref_cb));
146 pd->m_gesture_contex = eina_hash_pointer_new(EINA_FREE_CB(eina_hash_free));
147 pd->m_object_events = eina_hash_pointer_new(EINA_FREE_CB(_hash_unref_cb));
148 pd->m_object_gestures = NULL;
149 pd->m_gestures_to_delete = eina_array_new(1);;
150
151 /* this needs to always be present */
152 config = efl_provider_find(efl_main_loop_get(), EFL_CONFIG_INTERFACE);
153 efl_event_callback_add(config, EFL_CONFIG_EVENT_CONFIG_CHANGED, _gesture_manager_config_changed, pd);
154
155 //Register all types of recognizers at very first time.
156 efl_gesture_manager_recognizer_register(obj, efl_add(EFL_CANVAS_GESTURE_RECOGNIZER_TAP_CLASS, obj));
157 efl_gesture_manager_recognizer_register(obj, efl_add(EFL_CANVAS_GESTURE_RECOGNIZER_LONG_PRESS_CLASS, obj));
158 efl_gesture_manager_recognizer_register(obj, efl_add(EFL_CANVAS_GESTURE_RECOGNIZER_DOUBLE_TAP_CLASS, obj));
159 efl_gesture_manager_recognizer_register(obj, efl_add(EFL_CANVAS_GESTURE_RECOGNIZER_TRIPLE_TAP_CLASS, obj));
160 efl_gesture_manager_recognizer_register(obj, efl_add(EFL_CANVAS_GESTURE_RECOGNIZER_MOMENTUM_CLASS, obj));
161 efl_gesture_manager_recognizer_register(obj, efl_add(EFL_CANVAS_GESTURE_RECOGNIZER_FLICK_CLASS, obj));
162 efl_gesture_manager_recognizer_register(obj, efl_add(EFL_CANVAS_GESTURE_RECOGNIZER_ROTATE_CLASS, obj));
163 efl_gesture_manager_recognizer_register(obj, efl_add(EFL_CANVAS_GESTURE_RECOGNIZER_ZOOM_CLASS, obj));
164 /* realistically this will never fail, but the whole gesture layer breaks if this is 0 */
165 if (!getenv("EFL_RUN_IN_TREE"))
166 finger_size = efl_config_int_get(config, "glayer_tap_finger_size");
167 if (finger_size < 1) finger_size = 10;
168 _update_finger_sizes(pd, finger_size);
169
170 return obj;
171 }
172
173 EOLIAN static void
_efl_canvas_gesture_manager_efl_object_destructor(Eo * obj,Efl_Canvas_Gesture_Manager_Data * pd)174 _efl_canvas_gesture_manager_efl_object_destructor(Eo *obj, Efl_Canvas_Gesture_Manager_Data *pd)
175 {
176 Efl_Canvas_Gesture_Recognizer *recognizer;
177 void *ptr;
178 Eo *config = efl_provider_find(efl_main_loop_get(), EFL_CONFIG_INTERFACE);
179 if (config)
180 efl_event_callback_del(config, EFL_CONFIG_EVENT_CONFIG_CHANGED, _gesture_manager_config_changed, pd);
181
182 eina_hash_free(pd->m_recognizers);
183 EINA_LIST_FREE(pd->custom_recognizers, recognizer)
184 efl_unref(recognizer);
185 eina_hash_free(pd->m_gesture_contex);
186 eina_hash_free(pd->m_object_events);
187 _cleanup_object(pd->m_gestures_to_delete);
188 eina_array_free(pd->m_gestures_to_delete);
189 EINA_LIST_FREE(pd->m_object_gestures, ptr)
190 free(ptr);
191 efl_destructor(efl_super(obj, MY_CLASS));
192 }
193
194 void
_efl_canvas_gesture_manager_callback_add_hook(void * data,Eo * target,const Efl_Event_Description * type)195 _efl_canvas_gesture_manager_callback_add_hook(void *data, Eo *target, const Efl_Event_Description *type)
196 {
197 Efl_Canvas_Gesture_Manager_Data *pd = data;
198 //If there is a recognizer registered for that event then add it to the gesture context
199 Efl_Canvas_Gesture_Recognizer *recognizer;
200
201 if (type == EFL_EVENT_GESTURE_CUSTOM)
202 recognizer = eina_list_data_get(pd->custom_recognizers);
203 else
204 recognizer = eina_hash_find(pd->m_recognizers, &type);
205 if (recognizer)
206 {
207 //Add it to the gesture context.
208 Eina_Hash *thisisreallystupid = eina_hash_find(pd->m_gesture_contex, &target);
209 intptr_t count = 0;
210 /* already present */
211 if (thisisreallystupid)
212 count = (intptr_t)eina_hash_find(thisisreallystupid, &type);
213 else
214 {
215 thisisreallystupid = eina_hash_pointer_new(NULL);
216 eina_hash_set(pd->m_gesture_contex, &target, thisisreallystupid);
217 }
218 count++;
219 eina_hash_set(thisisreallystupid, &type, (intptr_t*)count);
220 }
221 }
222
223 void
_efl_canvas_gesture_manager_callback_del_hook(void * data,Eo * target,const Efl_Event_Description * type)224 _efl_canvas_gesture_manager_callback_del_hook(void *data, Eo *target, const Efl_Event_Description *type)
225 {
226 Efl_Canvas_Gesture_Manager_Data *pd = data;
227 //If there is a recognizer registered for that event then add it to the gesture context
228 Efl_Canvas_Gesture_Recognizer *recognizer;
229
230 if (type == EFL_EVENT_GESTURE_CUSTOM)
231 recognizer = eina_list_data_get(pd->custom_recognizers);
232 else
233 recognizer = eina_hash_find(pd->m_recognizers, &type);
234 if (recognizer)
235 {
236 Eina_Hash *thisisreallystupid = eina_hash_find(pd->m_gesture_contex, &target);
237 intptr_t count;
238
239 if (!thisisreallystupid) return;
240 count = (intptr_t)eina_hash_find(thisisreallystupid, &type);
241 if (!count) return;
242 count--;
243 eina_hash_set(thisisreallystupid, &type, (intptr_t*)count);
244 if (count) return;
245 eina_hash_del_by_key(thisisreallystupid, &type);
246 if (eina_hash_population(thisisreallystupid)) return;
247 eina_hash_del_by_key(pd->m_gesture_contex, &target);
248 _cleanup_cached_gestures(pd, target, type, NULL);
249 }
250 }
251
252 static void
_recognizer_cleanup_internal(Efl_Canvas_Gesture_Manager_Data * pd,const Efl_Canvas_Gesture_Recognizer * recognizer,const Eo * target,const Efl_Event_Description * type)253 _recognizer_cleanup_internal(Efl_Canvas_Gesture_Manager_Data *pd, const Efl_Canvas_Gesture_Recognizer *recognizer, const Eo *target, const Efl_Event_Description *type)
254 {
255 _cleanup_cached_gestures(pd, target, type, recognizer);
256 eina_hash_del(pd->m_object_events, &recognizer, NULL);
257 //FIXME: delete it by object not list.
258 _cleanup_object(pd->m_gestures_to_delete);
259 }
260
261 static void
_gesture_recognizer_process_internal(Efl_Canvas_Gesture_Manager_Data * pd,Efl_Canvas_Gesture_Recognizer * recognizer,Eo * target,const Efl_Event_Description * gesture_type,void * event)262 _gesture_recognizer_process_internal(Efl_Canvas_Gesture_Manager_Data *pd, Efl_Canvas_Gesture_Recognizer *recognizer,
263 Eo *target, const Efl_Event_Description *gesture_type, void *event)
264 {
265 Efl_Canvas_Gesture_Recognizer_Result recog_result;
266 Efl_Canvas_Gesture_Recognizer_Result recog_state = EFL_GESTURE_RECOGNIZER_RESULT_FINISH;
267 Efl_Canvas_Gesture_Touch *touch_event;
268 Efl_Canvas_Gesture_Recognizer_Data *rd = efl_data_scope_get(recognizer, EFL_CANVAS_GESTURE_RECOGNIZER_CLASS);
269 //If the gesture canceled or already finished by recognizer.
270 Efl_Canvas_Gesture *gesture = _get_state(pd, target, recognizer, gesture_type);
271 if (!gesture) return;
272
273 //Check there is already created event exist or not.
274 touch_event = eina_hash_find(pd->m_object_events, &recognizer);
275
276 if (!touch_event)
277 {
278 touch_event = efl_add_ref(EFL_CANVAS_GESTURE_TOUCH_CLASS, NULL);
279 eina_hash_add(pd->m_object_events, &recognizer, touch_event);
280 }
281
282 efl_gesture_touch_point_record(touch_event, event);
283
284 //This is for handling the case that mouse event pairs dont match.
285 //Such as the case of canceling gesture recognition after a mouse down.
286 if (efl_gesture_touch_state_get(touch_event) == EFL_GESTURE_TOUCH_STATE_UNKNOWN)
287 return;
288 if ((!rd->continues) && ((efl_gesture_state_get(gesture) == EFL_GESTURE_STATE_CANCELED) ||
289 (efl_gesture_state_get(gesture) == EFL_GESTURE_STATE_FINISHED)))
290 goto post_event;
291
292 /* this is the "default" value for the event, recognizers may modify it if necessary */
293 efl_gesture_touch_count_set(gesture, efl_gesture_touch_points_count_get(touch_event));
294
295 //Gesture detecting.
296 recog_result = efl_gesture_recognizer_recognize(recognizer, gesture, target, touch_event);
297 recog_state = recog_result & EFL_GESTURE_RECOGNIZER_RESULT_RESULT_MASK;
298
299 if (recog_state == EFL_GESTURE_RECOGNIZER_RESULT_TRIGGER)
300 {
301 if (efl_gesture_state_get(gesture) == EFL_GESTURE_STATE_NONE)
302 efl_gesture_state_set(gesture, EFL_GESTURE_STATE_STARTED);
303 else
304 efl_gesture_state_set(gesture, EFL_GESTURE_STATE_UPDATED);
305 }
306 else if (recog_state == EFL_GESTURE_RECOGNIZER_RESULT_FINISH)
307 {
308 efl_gesture_state_set(gesture, EFL_GESTURE_STATE_FINISHED);
309 }
310 else if (recog_state == EFL_GESTURE_RECOGNIZER_RESULT_MAYBE)
311 {
312 return;
313 }
314 else if (recog_state == EFL_GESTURE_RECOGNIZER_RESULT_CANCEL)
315 {
316 if (efl_gesture_state_get(gesture) != EFL_GESTURE_STATE_NONE)
317 efl_gesture_state_set(gesture, EFL_GESTURE_STATE_CANCELED);
318 else
319 {
320 if (rd->continues)
321 return;
322 goto post_event;
323 }
324 }
325 else if (recog_state == EFL_GESTURE_RECOGNIZER_RESULT_IGNORE)
326 {
327 return;
328 }
329
330 efl_gesture_timestamp_set(gesture, efl_gesture_touch_current_timestamp_get(touch_event));
331 efl_event_callback_call(target, gesture_type, gesture);
332 post_event:
333 /* avoid destroying touch tracking before gesture has ended */
334 if ((!rd->continues) &&
335 ((efl_gesture_touch_state_get(touch_event) != EFL_GESTURE_TOUCH_STATE_END) || efl_gesture_touch_points_count_get(touch_event)))
336 return;
337 //If the current event recognizes the gesture continuously, dont delete gesture.
338 if (((recog_state == EFL_GESTURE_RECOGNIZER_RESULT_FINISH) || (recog_state == EFL_GESTURE_RECOGNIZER_RESULT_CANCEL)) &&
339 !rd->continues)
340 _recognizer_cleanup_internal(pd, recognizer, target, gesture_type);
341 }
342
343 void
_efl_canvas_gesture_manager_filter_event(void * data,Eo * target,void * event)344 _efl_canvas_gesture_manager_filter_event(void *data, Eo *target, void *event)
345 {
346 Efl_Canvas_Gesture_Manager_Data *pd = data;
347 Eina_Hash *thisisreallystupid;
348 Eina_Iterator *it;
349 Eina_Hash_Tuple *tup;
350 Efl_Canvas_Gesture_Recognizer *recognizer;
351
352 thisisreallystupid = eina_hash_find(pd->m_gesture_contex, &target);
353 if (!thisisreallystupid) return;
354 pd->processing = EINA_TRUE;
355 it = eina_hash_iterator_tuple_new(thisisreallystupid);
356 EINA_ITERATOR_FOREACH(it, tup)
357 {
358 const Efl_Event_Description *gesture_type = *(void**)tup->key;
359
360 if (gesture_type == EFL_EVENT_GESTURE_CUSTOM)
361 {
362 Eina_List *l;
363 EINA_LIST_FOREACH(pd->custom_recognizers, l, recognizer)
364 _gesture_recognizer_process_internal(pd, recognizer, target, gesture_type, event);
365 }
366 else
367 {
368 recognizer = eina_hash_find(pd->m_recognizers, &gesture_type);
369 _gesture_recognizer_process_internal(pd, recognizer, target, gesture_type, event);
370 }
371 }
372 eina_iterator_free(it);
373 pd->processing = EINA_FALSE;
374 }
375
376 EOLIAN static void
_efl_canvas_gesture_manager_recognizer_register(Eo * obj EINA_UNUSED,Efl_Canvas_Gesture_Manager_Data * pd,Efl_Canvas_Gesture_Recognizer * recognizer)377 _efl_canvas_gesture_manager_recognizer_register(Eo *obj EINA_UNUSED, Efl_Canvas_Gesture_Manager_Data *pd,
378 Efl_Canvas_Gesture_Recognizer *recognizer)
379 {
380 const Efl_Event_Description *type = _gesture_recognizer_event_type_get(recognizer);
381 //Add the recognizer to the m_recognizers
382 if (type == EFL_EVENT_GESTURE_CUSTOM)
383 {
384 EINA_SAFETY_ON_TRUE_RETURN(pd->custom_recognizers && eina_list_data_find(pd->custom_recognizers, recognizer));
385 pd->custom_recognizers = eina_list_append(pd->custom_recognizers, efl_ref(recognizer));
386 }
387 else
388 {
389 EINA_SAFETY_ON_TRUE_RETURN(!!eina_hash_find(pd->m_recognizers, &type));
390 eina_hash_add(pd->m_recognizers, &type, efl_ref(recognizer));
391 }
392
393 }
394
395 EOLIAN static void
_efl_canvas_gesture_manager_recognizer_unregister(Eo * obj EINA_UNUSED,Efl_Canvas_Gesture_Manager_Data * pd,Efl_Canvas_Gesture_Recognizer * recognizer)396 _efl_canvas_gesture_manager_recognizer_unregister(Eo *obj EINA_UNUSED, Efl_Canvas_Gesture_Manager_Data *pd,
397 Efl_Canvas_Gesture_Recognizer *recognizer)
398 {
399 Eina_List *l, *l_next;
400 Object_Gesture *object_gesture;
401 const Efl_Event_Description *type;
402
403 if (!recognizer) return;
404
405 //Find the type of the recognizer
406 type = _gesture_recognizer_event_type_get(recognizer);
407 //Check if its already registered
408 if (type == EFL_EVENT_GESTURE_CUSTOM)
409 {
410 EINA_SAFETY_ON_TRUE_RETURN((!pd->custom_recognizers) || (!eina_list_data_find(pd->custom_recognizers, recognizer)));
411 pd->custom_recognizers = eina_list_remove(pd->custom_recognizers, recognizer);
412 eina_hash_del_by_key(pd->m_object_events, &recognizer);
413 efl_unref(recognizer);
414 }
415 else
416 {
417 EINA_SAFETY_ON_TRUE_RETURN(!eina_hash_find(pd->m_recognizers, &type));
418 eina_hash_del_by_key(pd->m_object_events, &recognizer);
419 eina_hash_del_by_key(pd->m_recognizers, &type);
420 }
421
422 //Remove that gesture from the list of object gestures
423 EINA_LIST_FOREACH_SAFE(pd->m_object_gestures, l, l_next, object_gesture)
424 {
425 if ((object_gesture->type == type) && (object_gesture->recognizer == recognizer))
426 {
427 eina_array_push(pd->m_gestures_to_delete, object_gesture->gesture);
428 free(object_gesture);
429 pd->m_object_gestures = eina_list_remove_list(pd->m_object_gestures, l);
430 }
431 }
432 if (pd->processing) return;
433 _cleanup_object(pd->m_gestures_to_delete);
434 }
435
436 // EOLIAN static void
437 // _efl_canvas_gesture_manager_ungrab_all(Eo *obj EINA_UNUSED, Efl_Canvas_Gesture_Manager_Data *pd,
438 // Eo *target)
439 // {
440 // const Efl_Event_Description *type;
441 // Eina_List *l;
442
443 // Eina_List *gesture_type_list = eina_hash_find(pd->m_gesture_contex, &target);
444
445 // if (!gesture_type_list) return;
446
447 // EINA_LIST_FOREACH(gesture_type_list, l, type)
448 // {
449 // _cleanup_cached_gestures(obj, pd, target, type);
450 // }
451 // eina_hash_del(pd->m_gesture_contex, &target, NULL);
452 // }
453
454 //Get or create a gesture object that will represent the state for a given object, used by the recognizer
455 Efl_Canvas_Gesture *
_get_state(Efl_Canvas_Gesture_Manager_Data * pd,Eo * target,Efl_Canvas_Gesture_Recognizer * recognizer,const Efl_Event_Description * type)456 _get_state(Efl_Canvas_Gesture_Manager_Data *pd,
457 Eo *target, Efl_Canvas_Gesture_Recognizer *recognizer, const Efl_Event_Description *type)
458 {
459 Eina_List *l;
460 Object_Gesture *object_gesture;
461 Efl_Canvas_Gesture *gesture;
462
463 //If the widget is being deleted we should be careful not to
464 //Create a new state.
465 if (efl_destructed_is(target))
466 return 0;
467
468 //TODO find a optimized way of looking for gesture
469 EINA_LIST_FOREACH(pd->m_object_gestures, l, object_gesture)
470 {
471 if (object_gesture->object == target &&
472 object_gesture->recognizer == recognizer &&
473 object_gesture->type == type)
474 {
475 return object_gesture->gesture;
476 }
477 }
478
479 gesture = efl_add(efl_gesture_recognizer_type_get(recognizer), recognizer);
480 if (!gesture)
481 return 0;
482
483 object_gesture = calloc(1, sizeof(Object_Gesture));
484 object_gesture->object = target;
485 object_gesture->recognizer = recognizer;
486 object_gesture->type = type;
487 object_gesture->gesture = gesture;
488 if (type == EFL_EVENT_GESTURE_CUSTOM)
489 efl_gesture_custom_gesture_name_set(gesture, efl_gesture_recognizer_custom_gesture_name_get(recognizer));
490
491 pd->m_object_gestures = eina_list_append(pd->m_object_gestures, object_gesture);
492
493 return gesture;
494 }
495
496 static void
_cleanup_cached_gestures(Efl_Canvas_Gesture_Manager_Data * pd,const Eo * target,const Efl_Event_Description * type,const Efl_Canvas_Gesture_Recognizer * recognizer)497 _cleanup_cached_gestures(Efl_Canvas_Gesture_Manager_Data *pd,
498 const Eo *target, const Efl_Event_Description *type, const Efl_Canvas_Gesture_Recognizer *recognizer)
499 {
500 Eina_List *l, *l_next;
501 Object_Gesture *object_gesture;
502
503 EINA_LIST_FOREACH_SAFE(pd->m_object_gestures, l, l_next, object_gesture)
504 {
505 if ((object_gesture->type == type) && (target == object_gesture->object) &&
506 ((!recognizer) || (object_gesture->recognizer == recognizer)))
507 {
508 eina_array_push(pd->m_gestures_to_delete, object_gesture->gesture);
509 free(object_gesture);
510 pd->m_object_gestures = eina_list_remove_list(pd->m_object_gestures, l);
511 }
512 }
513 }
514
515 EOLIAN static void
_efl_canvas_gesture_manager_recognizer_cleanup(Eo * obj EINA_UNUSED,Efl_Canvas_Gesture_Manager_Data * pd,const Efl_Canvas_Gesture_Recognizer * recognizer,const Eo * target)516 _efl_canvas_gesture_manager_recognizer_cleanup(Eo *obj EINA_UNUSED, Efl_Canvas_Gesture_Manager_Data *pd, const Efl_Canvas_Gesture_Recognizer *recognizer, const Eo *target)
517 {
518 const Efl_Event_Description *type;
519
520 EINA_SAFETY_ON_NULL_RETURN(recognizer);
521
522 //Find the type of the recognizer
523 type = _gesture_recognizer_event_type_get(recognizer);
524 _recognizer_cleanup_internal(pd, recognizer, target, type);
525 }
526
527 #include "efl_canvas_gesture_manager.eo.c"
528