1 #include "efl_canvas_gesture_private.h"
2 
3 #define MY_CLASS                      EFL_CANVAS_GESTURE_RECOGNIZER_LONG_PRESS_CLASS
4 
5 #define EFL_GESTURE_LONG_PRESS_TIME_OUT 1.2
6 
7 EOLIAN static const Efl_Class *
_efl_canvas_gesture_recognizer_long_press_efl_canvas_gesture_recognizer_type_get(const Eo * obj EINA_UNUSED,Efl_Canvas_Gesture_Recognizer_Long_Press_Data * pd EINA_UNUSED)8 _efl_canvas_gesture_recognizer_long_press_efl_canvas_gesture_recognizer_type_get(const Eo *obj EINA_UNUSED, Efl_Canvas_Gesture_Recognizer_Long_Press_Data *pd EINA_UNUSED)
9 {
10    return EFL_CANVAS_GESTURE_LONG_PRESS_CLASS;
11 }
12 
13 EOLIAN static void
_efl_canvas_gesture_recognizer_long_press_efl_object_destructor(Eo * obj,Efl_Canvas_Gesture_Recognizer_Long_Press_Data * pd)14 _efl_canvas_gesture_recognizer_long_press_efl_object_destructor(Eo *obj,
15                                                               Efl_Canvas_Gesture_Recognizer_Long_Press_Data *pd)
16 {
17    if (pd->timeout)
18      ecore_timer_del(pd->timeout);
19 
20    efl_destructor(efl_super(obj, MY_CLASS));
21 }
22 
23 static Eina_Bool
_long_press_timeout_cb(void * data)24 _long_press_timeout_cb(void *data)
25 {
26    Efl_Canvas_Gesture_Recognizer_Long_Press_Data *pd = data;
27 
28    /* FIXME: Needs to propagate this event back to evas! */
29    pd->is_timeout = EINA_TRUE;
30 
31    efl_gesture_state_set(pd->gesture, EFL_GESTURE_STATE_UPDATED);
32    efl_event_callback_call(pd->target, EFL_EVENT_GESTURE_LONG_PRESS, pd->gesture);
33 
34    return ECORE_CALLBACK_RENEW;
35 }
36 
37 EOLIAN static Efl_Canvas_Gesture_Recognizer_Result
_efl_canvas_gesture_recognizer_long_press_efl_canvas_gesture_recognizer_recognize(Eo * obj,Efl_Canvas_Gesture_Recognizer_Long_Press_Data * pd,Efl_Canvas_Gesture * gesture,Efl_Object * watched,Efl_Canvas_Gesture_Touch * event)38 _efl_canvas_gesture_recognizer_long_press_efl_canvas_gesture_recognizer_recognize(Eo *obj,
39                                                                                 Efl_Canvas_Gesture_Recognizer_Long_Press_Data *pd,
40                                                                                 Efl_Canvas_Gesture *gesture,
41                                                                                 Efl_Object *watched,
42                                                                                 Efl_Canvas_Gesture_Touch *event)
43 {
44    double length, start_timeout = pd->start_timeout; // Manhattan distance
45    double timeout = EFL_GESTURE_LONG_PRESS_TIME_OUT;
46    Eina_Position2D pos;
47    Eina_Vector2 dist;
48    Efl_Canvas_Gesture_Recognizer_Result result = EFL_GESTURE_RECOGNIZER_RESULT_CANCEL;
49 
50    pd->target = watched;
51    pd->gesture = gesture;
52 
53    if (!EINA_DBL_NONZERO(start_timeout))
54      {
55         double time;
56         Eina_Value *val = _recognizer_config_get(obj, "glayer_long_tap_start_timeout");
57 
58         if (val)
59           {
60              eina_value_get(val, &time);
61              pd->start_timeout = timeout = time;
62           }
63      }
64    else
65      timeout = start_timeout;
66 
67    switch (efl_gesture_touch_state_get(event))
68      {
69       case EFL_GESTURE_TOUCH_STATE_BEGIN:
70       {
71          pos = efl_gesture_touch_start_point_get(event);
72          efl_gesture_hotspot_set(gesture, pos);
73 
74          if (pd->timeout)
75            {
76               ecore_timer_del(pd->timeout);
77            }
78          pd->timeout = ecore_timer_add(timeout,
79                                        _long_press_timeout_cb, pd);
80 
81          result = EFL_GESTURE_RECOGNIZER_RESULT_TRIGGER;
82 
83          break;
84       }
85 
86       case EFL_GESTURE_TOUCH_STATE_UPDATE:
87       {
88          dist = efl_gesture_touch_distance(event, efl_gesture_touch_current_data_get(event)->id);
89          length = fabs(dist.x) + fabs(dist.y);
90 
91          if ((_event_multi_touch_get(event)) || (length > pd->finger_size))
92            {
93               if (pd->timeout)
94                 {
95                    ecore_timer_del(pd->timeout);
96                    pd->timeout = NULL;
97                 }
98 
99               result = EFL_GESTURE_RECOGNIZER_RESULT_CANCEL;
100            }
101          else
102            {
103               result = EFL_GESTURE_RECOGNIZER_RESULT_MAYBE;
104            }
105 
106          break;
107       }
108 
109       case EFL_GESTURE_TOUCH_STATE_END:
110       {
111          if (pd->timeout)
112            {
113               ecore_timer_del(pd->timeout);
114               pd->timeout = NULL;
115            }
116 
117          if (efl_gesture_state_get(gesture) != EFL_GESTURE_STATE_NONE &&
118              !_event_multi_touch_get(event))
119            {
120               dist = efl_gesture_touch_distance(event, efl_gesture_touch_current_data_get(event)->id);
121               length = fabs(dist.x) + fabs(dist.y);
122               if (length <= pd->finger_size && pd->is_timeout)
123                 {
124                    result = EFL_GESTURE_RECOGNIZER_RESULT_FINISH;
125                 }
126               else
127                 {
128                    result = EFL_GESTURE_RECOGNIZER_RESULT_CANCEL;
129                 }
130            }
131 
132          break;
133       }
134 
135       default:
136 
137         break;
138      }
139 
140    return result;
141 }
142 
143 #include "efl_canvas_gesture_recognizer_long_press.eo.c"
144