X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Finput%2Fgesturedetector.cpp;h=aecfa81bb3b7ab88fb4602956f6ca11368a74634;hb=9580908b4c206675f912c0639d8f450bc42c504b;hp=112121ee456a86736876b01e23c09a394045c498;hpb=5858aa055277dbd376c33bb3bbeb6aa74137a17f;p=libs%2Fgui.git diff --git a/source/input/gesturedetector.cpp b/source/input/gesturedetector.cpp index 112121e..aecfa81 100644 --- a/source/input/gesturedetector.cpp +++ b/source/input/gesturedetector.cpp @@ -26,16 +26,14 @@ GestureDetector::GestureDetector(Touchscreen &ts): string GestureDetector::get_button_name(unsigned btn) const { - if(btn==GESTURE_SWIPE_DOWN) - return "Swipe down"; - else if(btn==GESTURE_SWIPE_UP) - return "Swipe up"; - else if(btn==GESTURE_SWIPE_LEFT) - return "Swipe left"; - else if(btn==GESTURE_SWIPE_RIGHT) - return "Swipe right"; + if(btn==GESTURE_DRAG) + return "Drag"; + else if(btn==GESTURE_DRAG_2) + return "Two-finger drag"; else if(btn==GESTURE_PINCH) return "Pinch"; + else if(btn==GESTURE_ROTATE) + return "Rotate"; else return Device::get_button_name(btn); } @@ -133,12 +131,21 @@ void GestureDetector::start_gesture() TouchPoint &p2 = points[1]; float ddx = p.down_x-p2.down_x; float ddy = p.down_y-p2.down_y; - if(p.x*p2.x+p.y*p2.y<0 && (p.x*ddx+p.y*ddy)*(p2.x*ddx+p2.y*ddy)<0) - /* If the points moved in different directions and also both away from - or towards the other, it's a pinch gesture. */ + float away = p.x*ddx+p.y*ddy; + float turn = p.y*ddx-p.x*ddy; + float away2 = -(p2.x*ddx+p2.y*ddy); + float turn2 = -(p2.y*ddx-p2.x*ddy); + if(away*away2>0 && abs(away)>abs(turn) && abs(away2)>abs(turn2)) + /* If the points moved away from or towards each other without rotating + significantly, it's a pinch gesture. */ current_gesture = GESTURE_PINCH; - else - invalid_gesture = true; + else if(turn*turn2>0 && abs(turn)>abs(away) && abs(turn2)>abs(away2)) + /* If the points both turned in the same direction without significant + changes in distance, it's a rotate gesture. */ + current_gesture = GESTURE_ROTATE; + else if((p.x*p2.x+p.y*p2.y)>2*abs(p.x*p2.y-p.y*p2.x)) + // If both points moved in the same direction, it's a two-finger drag. + current_gesture = GESTURE_DRAG_2; if(current_gesture!=GESTURE_NONE) { @@ -149,41 +156,36 @@ void GestureDetector::start_gesture() } else { - // 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); - } + current_gesture = GESTURE_DRAG; + active_points = 1; + set_axis_value(0, p.down_x, true); + set_axis_value(1, p.down_y, true); } update_progress(); if(current_gesture!=GESTURE_NONE) set_button_state(current_gesture, true, true); + else + invalid_gesture = true; } void GestureDetector::update_progress() { TouchPoint &p = points[0]; - if(current_gesture==GESTURE_SWIPE_DOWN) - set_axis_value(2, -p.y, true); - else if(current_gesture==GESTURE_SWIPE_UP) - set_axis_value(2, p.y, true); - else if(current_gesture==GESTURE_SWIPE_LEFT) - set_axis_value(2, -p.x, true); - else if(current_gesture==GESTURE_SWIPE_RIGHT) + if(current_gesture==GESTURE_DRAG) + { set_axis_value(2, p.x, true); - else if(current_gesture==GESTURE_PINCH) + set_axis_value(3, p.y, true); + } + else if(current_gesture==GESTURE_DRAG_2) + { + TouchPoint &p2 = points[1]; + set_axis_value(2, (p.x+p2.x)/2, true); + set_axis_value(3, (p.y+p2.y)/2, true); + } + else if(current_gesture==GESTURE_PINCH || current_gesture==GESTURE_ROTATE) { TouchPoint &p2 = points[1]; /* Pinch progress is the ratio between the current distance of the points @@ -192,7 +194,16 @@ void GestureDetector::update_progress() 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); + if(current_gesture==GESTURE_PINCH) + { + set_axis_value(2, sqrt(dx*dx+dy*dy)/sqrt(ddx*ddx+ddy*ddy)-1, true); + set_axis_value(3, 0, true); + } + else if(current_gesture==GESTURE_ROTATE) + { + set_axis_value(2, atan2(dy*ddx-dx*ddy, dx*ddx+dy*ddy)/M_PI/2, true); + set_axis_value(3, 0, true); + } } }