614de96e24eefe242eca6144a23ac47fede1fa3f
[platform/core/api/maps-service.git] / src / view / gesture_detector.cpp
1 /* Copyright (c) 2010-2014 Samsung Electronics Co., Ltd. All rights reserved.
2  *
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17
18 #include "gesture_detector.h"
19 #include <glib.h>
20 #include <math.h>
21
22
23 extern bool _maps_view_is_gesture_available(maps_view_h view,
24                                            maps_view_gesture_e gesture);
25
26
27 /*----------------------------------------------------------------------------*/
28
29 int view::gesture_detector::__CLICK_AREA = 50;
30
31 view::gesture_detector::gesture_detector(maps_view_h v)
32         : _view(v)
33         , _gp(this)
34         , _tap_timer(NULL)
35         , _long_press_timer(NULL)
36 {
37         int dpi;
38         if (maps_get_screen_dpi(&dpi) == MAPS_ERROR_NONE)
39                 __CLICK_AREA = dpi / 5; /* expected about 0.5cm */
40 }
41
42 view::gesture_detector::~gesture_detector()
43 {
44         stop_tap_timer();
45         stop_long_press_timer();
46 }
47
48 void view::gesture_detector::halt_gesture()
49 {
50 }
51
52 void view::gesture_detector::reset()
53 {
54         MAPS_LOGI("%c[%d;%d;%dm"
55                   "%s"
56                   "%c[%d;%d;%dm",
57                   0x1B, 1, 41, FG_GREEN,
58                   "RESET RUNTIME INFO",
59                   0x1B, 0, 0, 0);
60
61         /* Store the previous gesture data for possible future analysis */
62         _info_history = _info;
63
64         /* Save Map View state for complex multi-click gestures */
65         const map_state saved_state = _info._start_view_state;
66
67         /* Reset current gesture info */
68         _info.reset();
69
70         /* We would use this state in the complex gestures */
71         _info._start_view_state = saved_state;
72
73         /* There is definitelly not long enough for "long press" gesture */
74         stop_long_press_timer();
75
76         /*MAPS_LOGI("Historic timestamps: tap: %d, move: %d, up: %d",
77                   _info_history._finger_down[0]._timestamp,
78                   _info_history._finger_move[0]._timestamp,
79                   _info_history._finger_up[0]._timestamp);*/
80 }
81
82 void view::gesture_detector::tap(int finger_no, const touch_point &tp)
83 {
84 }
85
86 void view::gesture_detector::up(int finger_no, const touch_point &tp)
87 {
88 }
89
90 void view::gesture_detector::move(int finger_no, const touch_point &tp)
91 {
92 }
93
94 void view::gesture_detector::on_tap_timer()
95 {
96 }
97
98 void view::gesture_detector::start_tap_timer()
99 {
100         log("START TAP TIMER", FG_MAGENTA);
101         if(_tap_timer)
102                 stop_tap_timer();
103         _tap_timer = ecore_timer_add(__TAP_DURATION,
104                                         __on_tap_timer,
105                                         this);
106 }
107
108 void view::gesture_detector::stop_tap_timer()
109 {
110         log("STOP TAP TIMER", FG_MAGENTA);
111         if(_tap_timer)
112                 ecore_timer_del(_tap_timer);
113         _tap_timer = NULL;
114 }
115
116 Eina_Bool view::gesture_detector::__on_tap_timer(void *data)
117 {
118         gesture_detector *d = (gesture_detector *)data;
119         if (!d)
120                 return ECORE_CALLBACK_CANCEL;
121
122         d->log("------- TAP TIMER EVENT -------", FG_MAGENTA);
123         d->_tap_timer = NULL;
124         d->on_tap_timer();
125
126         return ECORE_CALLBACK_CANCEL;
127 }
128
129 void view::gesture_detector::on_long_press_timer()
130 {
131 }
132
133 void view::gesture_detector::start_long_press_timer()
134 {
135         log("START LONG PRESS TIMER", FG_MAGENTA);
136         if(_long_press_timer)
137                 stop_long_press_timer();
138         _long_press_timer = ecore_timer_add(__LONG_PRESS_DURATION,
139                                             __on_long_press_timer,
140                                             this);
141 }
142
143 void view::gesture_detector::stop_long_press_timer()
144 {
145         log("STOP LONG PRESS TIMER", FG_MAGENTA);
146         if(_long_press_timer)
147                 ecore_timer_del(_long_press_timer);
148         _long_press_timer = NULL;
149 }
150
151 Eina_Bool view::gesture_detector::__on_long_press_timer(void *data)
152 {
153         gesture_detector *d = (gesture_detector *)data;
154         if (!d)
155                 return ECORE_CALLBACK_CANCEL;
156
157         d->log("------- LONG PRESS TIMER EVENT -------", FG_MAGENTA);
158         d->_long_press_timer = NULL;
159         d->on_long_press_timer();
160
161         return ECORE_CALLBACK_CANCEL;
162 }
163
164 bool view::gesture_detector::is_gesture_available(maps_view_gesture_e gesture)
165 {
166         return _maps_view_is_gesture_available(_view, gesture);
167 }
168
169 bool view::gesture_detector::finger_dragged_enough(int finger_no)
170 {
171         const touch_point p1 = _info._finger_down[finger_no];
172         const touch_point p2 = _info._finger_move[finger_no];
173         return (get_trajectory_effective_length(p1, p2) >= __CLICK_AREA);
174 }
175
176 bool view::gesture_detector::finger_pressed_enough(int finger_no,
177                                                    unsigned int duration_min,
178                                                    unsigned int duration_max)
179 {
180         unsigned int press_time = _info._finger_down[finger_no]._timestamp;
181         unsigned int up_time = _info._finger_up[finger_no]._timestamp;
182
183         unsigned int press_duration_tmp = up_time - press_time;
184         MAPS_LOGI("finger_pressed_enough: finger: %d, press: %d, up: %d [%d]",
185                   finger_no, press_time, up_time, press_duration_tmp);
186
187         if(up_time < press_time)
188                 return false; /* Not yet unpressed */
189         unsigned int press_duration = up_time - press_time;
190         if ((press_duration >= duration_min) && (press_duration <= duration_max))
191                 return true;
192         return false;
193 }
194
195 int view::gesture_detector::get_trajectory_effective_length(
196                                                         const touch_point &p1,
197                                                         const touch_point &p2)
198 {
199         int dx = p2._x - p1._x;
200         int dy = p2._y - p1._y;
201         int etl = sqrt(dx * dx + dy * dy);
202         return etl;
203 }
204
205 void view::gesture_detector::log(const char *str, log_colors color)
206 {
207         MAPS_LOGI("%c[%d;%d;%dm"
208                   "%s"
209                   "%c[%d;%d;%dm",
210                   0x1B, 1, 0, color,
211                   str,
212                   0x1B, 0, 0, 0);
213 }
214
215
216 void view::gesture_detector::log_map_center(int color)
217 {
218         maps_coordinates_h central_coords = NULL;
219         maps_view_get_center(_view, &central_coords);
220         double lat = .0, lon = .0;
221         maps_coordinates_get_latitude_longitude(central_coords, &lat, &lon);
222         maps_coordinates_destroy(central_coords);
223         MAPS_LOGI("%c[%d;%d;%dm"
224                   "central coordinates: (%f, %f)"
225                   "%c[%d;%d;%dm",
226                   0x1B, 1, 0, color,
227                   lat, lon,
228                   0x1B, 0, 0, 0);
229 }