2 #include <sigc++/bind_return.h>
3 #include "gesturedetector.h"
4 #include "touchscreen.h"
11 GestureDetector::GestureDetector(Touchscreen &ts):
13 current_gesture(GESTURE_NONE),
15 invalid_gesture(false)
19 touchscreen.signal_button_press.connect(sigc::bind_return(sigc::mem_fun(this, &GestureDetector::touch_down), false));
20 touchscreen.signal_button_release.connect(sigc::bind_return(sigc::mem_fun(this, &GestureDetector::touch_up), false));
21 touchscreen.signal_axis_motion.connect(sigc::bind_return(sigc::mem_fun(this, &GestureDetector::touch_move), false));
22 Graphics::Window &window = touchscreen.get_window();
23 window.signal_resize.connect(sigc::mem_fun(this, &GestureDetector::window_resized));
24 window_resized(window.get_width(), window.get_height());
27 string GestureDetector::get_button_name(unsigned btn) const
29 if(btn==GESTURE_SWIPE_DOWN)
31 else if(btn==GESTURE_SWIPE_UP)
33 else if(btn==GESTURE_SWIPE_LEFT)
35 else if(btn==GESTURE_SWIPE_RIGHT)
37 else if(btn==GESTURE_PINCH)
40 return Device::get_button_name(btn);
43 string GestureDetector::get_axis_name(unsigned axis) const
52 return Device::get_axis_name(axis);
55 void GestureDetector::touch_down(unsigned btn)
59 TouchPoint &p = points[btn];
66 void GestureDetector::touch_up(unsigned btn)
70 TouchPoint &p = points[btn];
73 if(active_points&(1<<btn))
75 set_button_state(current_gesture, false, true);
76 set_axis_value(2, 0, false);
77 current_gesture = GESTURE_NONE;
79 invalid_gesture = true;
84 invalid_gesture = false;
85 for(unsigned i=0; i<3; ++i)
87 invalid_gesture = true;
92 void GestureDetector::touch_move(unsigned axis, float value, float)
97 TouchPoint &p = points[i];
105 if(current_gesture==GESTURE_NONE && !invalid_gesture)
107 else if(active_points&(1<<i))
113 void GestureDetector::start_gesture()
115 TouchPoint &p = points[0];
119 float dx = p.x-p.down_x;
120 float dy = p.y-p.down_y;
121 if(dx*dx/threshold_x_sq+dy*dy/threshold_y_sq<1)
124 invalid_gesture = false;
127 TouchPoint &p2 = points[1];
128 float dx2 = p2.x-p2.down_x;
129 float dy2 = p2.y-p2.down_y;
130 float ddx = p.down_x-p2.down_x;
131 float ddy = p.down_y-p2.down_y;
132 /* TODO Should the second point be also required to exceeded the
134 if(dx*dx2+dy*dy2<0 && (dx*ddx+dy*ddy)*(dx2*ddx+dy2*ddy)<0)
136 current_gesture = GESTURE_PINCH;
140 invalid_gesture = true;
142 if(current_gesture!=GESTURE_NONE)
144 set_axis_value(0, (p.down_x+p2.down_x)/2, true);
145 set_axis_value(1, (p.down_y+p2.down_y)/2, true);
151 if(abs(dx)>2*abs(dy))
152 current_gesture = (dx>0 ? GESTURE_SWIPE_RIGHT : GESTURE_SWIPE_LEFT);
153 else if(abs(dy)>2*abs(dx))
154 current_gesture = (dy>0 ? GESTURE_SWIPE_UP : GESTURE_SWIPE_DOWN);
156 invalid_gesture = true;
158 if(current_gesture!=GESTURE_NONE)
160 set_axis_value(0, p.down_x, true);
161 set_axis_value(1, p.down_y, true);
167 if(current_gesture!=GESTURE_NONE)
168 set_button_state(current_gesture, true, true);
171 void GestureDetector::update_progress()
173 TouchPoint &p = points[0];
175 if(current_gesture==GESTURE_SWIPE_DOWN)
176 set_axis_value(2, p.down_y-p.y, true);
177 else if(current_gesture==GESTURE_SWIPE_UP)
178 set_axis_value(2, p.y-p.down_y, true);
179 else if(current_gesture==GESTURE_SWIPE_LEFT)
180 set_axis_value(2, p.down_x-p.x, true);
181 else if(current_gesture==GESTURE_SWIPE_RIGHT)
182 set_axis_value(2, p.x-p.down_x, true);
183 else if(current_gesture==GESTURE_PINCH)
185 TouchPoint &p2 = points[1];
188 float ddx = p.down_x-p2.down_x;
189 float ddy = p.down_y-p2.down_y;
190 set_axis_value(2, sqrt(dx*dx+dy*dy)/sqrt(ddx*ddx+ddy*ddy)-1, true);
194 void GestureDetector::window_resized(unsigned w, unsigned h)
196 threshold_x_sq = 2500.0/(w*w);
197 threshold_y_sq = 2500.0/(h*h);
201 GestureDetector::TouchPoint::TouchPoint():