From 5858aa055277dbd376c33bb3bbeb6aa74137a17f Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Thu, 19 Nov 2015 23:12:38 +0200 Subject: [PATCH] Refactor GestureDetector and add some comments to it --- source/input/gesturedetector.cpp | 137 +++++++++++++++++-------------- source/input/gesturedetector.h | 9 +- 2 files changed, 83 insertions(+), 63 deletions(-) diff --git a/source/input/gesturedetector.cpp b/source/input/gesturedetector.cpp index c43e65a..112121e 100644 --- a/source/input/gesturedetector.cpp +++ b/source/input/gesturedetector.cpp @@ -54,59 +54,62 @@ string GestureDetector::get_axis_name(unsigned axis) const void GestureDetector::touch_down(unsigned btn) { - if(btn<3) - { - TouchPoint &p = points[btn]; - p.down = true; - p.down_x = p.x; - p.down_y = p.y; - } + if(btn>=MAX_POINTS) + return; + + TouchPoint &p = points[btn]; + p.down = true; + p.down_x = p.x; + p.down_y = p.y; + p.x = 0; + p.y = 0; + p.threshold_exceeded = false; } void GestureDetector::touch_up(unsigned btn) { - if(btn<3) - { - TouchPoint &p = points[btn]; - p.down = false; + if(btn>=MAX_POINTS) + return; - if(active_points&(1<=MAX_POINTS*2) + return; + + unsigned i = axis>>1; + TouchPoint &p = points[i]; + // Track relative position when pressed, absolute when not. + if(axis&1) + p.y = (p.down ? value-p.down_y : value); + else + p.x = (p.down ? value-p.down_x : value); + + if(p.down) { - unsigned i = axis>>1; - TouchPoint &p = points[i]; - if(axis&1) - p.y = value; - else - p.x = value; + if(p.x*p.x/threshold_x_sq+p.y*p.y/threshold_y_sq>=1) + p.threshold_exceeded = true; - if(p.down) - { - if(current_gesture==GESTURE_NONE && !invalid_gesture) - start_gesture(); - else if(active_points&(1<2*abs(dy)) - current_gesture = (dx>0 ? GESTURE_SWIPE_RIGHT : GESTURE_SWIPE_LEFT); - else if(abs(dy)>2*abs(dx)) - current_gesture = (dy>0 ? GESTURE_SWIPE_UP : GESTURE_SWIPE_DOWN); + // Allow a maximum deviation of about 26° to recognize a swipe gesture. + if(abs(p.x)>2*abs(p.y)) + current_gesture = (p.x>0 ? GESTURE_SWIPE_RIGHT : GESTURE_SWIPE_LEFT); + else if(abs(p.y)>2*abs(p.x)) + current_gesture = (p.y>0 ? GESTURE_SWIPE_UP : GESTURE_SWIPE_DOWN); else invalid_gesture = true; if(current_gesture!=GESTURE_NONE) { + active_points = 1; set_axis_value(0, p.down_x, true); set_axis_value(1, p.down_y, true); } @@ -173,24 +176,34 @@ void GestureDetector::update_progress() TouchPoint &p = points[0]; if(current_gesture==GESTURE_SWIPE_DOWN) - set_axis_value(2, p.down_y-p.y, true); + set_axis_value(2, -p.y, true); else if(current_gesture==GESTURE_SWIPE_UP) - set_axis_value(2, p.y-p.down_y, true); + set_axis_value(2, p.y, true); else if(current_gesture==GESTURE_SWIPE_LEFT) - set_axis_value(2, p.down_x-p.x, true); + set_axis_value(2, -p.x, true); else if(current_gesture==GESTURE_SWIPE_RIGHT) - set_axis_value(2, p.x-p.down_x, true); + set_axis_value(2, p.x, true); else if(current_gesture==GESTURE_PINCH) { TouchPoint &p2 = points[1]; - float dx = p.x-p2.x; - float dy = p.y-p2.y; + /* Pinch progress is the ratio between the current distance of the points + and their distance when they were pressed. */ float ddx = p.down_x-p2.down_x; float ddy = p.down_y-p2.down_y; + float dx = ddx+p.x-p2.x; + float dy = ddy+p.y-p2.y; set_axis_value(2, sqrt(dx*dx+dy*dy)/sqrt(ddx*ddx+ddy*ddy)-1, true); } } +void GestureDetector::end_gesture() +{ + set_button_state(current_gesture, false, true); + set_axis_value(2, 0, false); + current_gesture = GESTURE_NONE; + active_points = 0; +} + void GestureDetector::window_resized(unsigned w, unsigned h) { threshold_x_sq = 2500.0/(w*w); diff --git a/source/input/gesturedetector.h b/source/input/gesturedetector.h index 2b5ea3c..b2d0d4f 100644 --- a/source/input/gesturedetector.h +++ b/source/input/gesturedetector.h @@ -27,6 +27,11 @@ absolute values greater than one. class GestureDetector: public Device { private: + enum + { + MAX_POINTS = 3 + }; + struct TouchPoint { bool down; @@ -34,12 +39,13 @@ private: float down_y; float x; float y; + bool threshold_exceeded; TouchPoint(); }; Touchscreen &touchscreen; - TouchPoint points[3]; + TouchPoint points[MAX_POINTS]; Gesture current_gesture; unsigned active_points; bool invalid_gesture; @@ -58,6 +64,7 @@ private: void touch_move(unsigned, float, float); void start_gesture(); void update_progress(); + void end_gesture(); void window_resized(unsigned, unsigned); }; -- 2.45.2