]> git.tdb.fi Git - libs/gui.git/commitdiff
Refactor GestureDetector logic
authorMikko Rasa <tdb@tdb.fi>
Mon, 19 Sep 2016 20:30:14 +0000 (23:30 +0300)
committerMikko Rasa <tdb@tdb.fi>
Mon, 19 Sep 2016 20:30:14 +0000 (23:30 +0300)
Active_points only ever had the one or two bottom bits set and always
matched current gesture.  It's simpler to just use the number of points
for the gesture.

source/input/gesturedetector.cpp
source/input/gesturedetector.h

index 145262a762ce438d03bb777ca1ed06fc325c7607..26968c03c988a16d1b0035c652a0bc6b991c64a6 100644 (file)
@@ -12,7 +12,6 @@ namespace Input {
 GestureDetector::GestureDetector(Touchscreen &ts):
        touchscreen(ts),
        current_gesture(GESTURE_NONE),
-       active_points(0),
        pending_tap(GESTURE_NONE),
        invalid_gesture(false)
 {
@@ -90,7 +89,7 @@ void GestureDetector::touch_up(unsigned btn)
        p.y += p.down_y;
        p.down = false;
 
-       if(active_points&(1<<btn))
+       if(btn<gesture_points(current_gesture))
                end_gesture();
 
        if(current_gesture==GESTURE_NONE)
@@ -102,8 +101,7 @@ void GestureDetector::touch_up(unsigned btn)
 
                if(!invalid_gesture && pending_tap!=GESTURE_NONE)
                {
-                       unsigned n_points = min<unsigned>((pending_tap-GESTURE_TAP)+1, MAX_POINTS);
-                       set_gesture_location((1<<n_points)-1);
+                       set_gesture_location(gesture_points(pending_tap));
                        set_button_state(pending_tap, true, true);
                        set_button_state(pending_tap, false, true);
 
@@ -135,7 +133,7 @@ void GestureDetector::touch_move(unsigned axis, float value, float)
 
                if(current_gesture==GESTURE_NONE && !invalid_gesture)
                        start_gesture();
-               else if(active_points&(1<<i))
+               else if(i<gesture_points(current_gesture))
                        update_progress();
        }
 }
@@ -175,20 +173,13 @@ void GestureDetector::start_gesture()
                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)
-                       active_points = 3;
        }
        else
-       {
                current_gesture = GESTURE_DRAG;
-               active_points = 1;
-       }
-
 
        if(current_gesture!=GESTURE_NONE)
        {
-               set_gesture_location(active_points);
+               set_gesture_location(gesture_points(current_gesture));
                update_progress();
                set_button_state(current_gesture, true, true);
        }
@@ -196,40 +187,41 @@ void GestureDetector::start_gesture()
                invalid_gesture = true;
 }
 
-void GestureDetector::set_gesture_location(unsigned mask)
+void GestureDetector::set_gesture_location(unsigned n_points)
 {
        float x = 0;
        float y = 0;
-       unsigned count = 0;
-       for(unsigned i=0; i<MAX_POINTS; ++i)
-               if(mask&(1<<i))
-               {
-                       x += points[i].down_x;
-                       y += points[i].down_y;
-                       ++count;
-               }
+       for(unsigned i=0; i<n_points; ++i)
+       {
+               x += points[i].down_x;
+               y += points[i].down_y;
+       }
 
-       set_axis_value(0, x/count, true);
-       set_axis_value(1, y/count, true);
+       set_axis_value(0, x/n_points, true);
+       set_axis_value(1, y/n_points, true);
 }
 
-void GestureDetector::update_progress()
+void GestureDetector::set_gesture_delta(unsigned n_points)
 {
-       TouchPoint &p = points[0];
-
-       if(current_gesture==GESTURE_DRAG)
-       {
-               set_axis_value(2, p.x, true);
-               set_axis_value(3, p.y, true);
-       }
-       else if(current_gesture==GESTURE_DRAG_2)
+       float x = 0;
+       float y = 0;
+       for(unsigned i=0; i<n_points; ++i)
        {
-               TouchPoint &p2 = points[1];
-               set_axis_value(2, (p.x+p2.x)/2, true);
-               set_axis_value(3, (p.y+p2.y)/2, true);
+               x += points[i].x;
+               y += points[i].y;
        }
+
+       set_axis_value(2, x/n_points, true);
+       set_axis_value(3, y/n_points, true);
+}
+
+void GestureDetector::update_progress()
+{
+       if(current_gesture>=GESTURE_DRAG && current_gesture<=GESTURE_DRAG_2)
+               set_gesture_delta(gesture_points(current_gesture));
        else if(current_gesture==GESTURE_PINCH || current_gesture==GESTURE_ROTATE)
        {
+               TouchPoint &p = points[0];
                TouchPoint &p2 = points[1];
                /* Pinch progress is the ratio between the current distance of the points
                and their distance when they were pressed. */
@@ -255,7 +247,6 @@ void GestureDetector::end_gesture()
        set_button_state(current_gesture, false, true);
        set_axis_value(2, 0, false);
        current_gesture = GESTURE_NONE;
-       active_points = 0;
        pending_tap = GESTURE_NONE;
 }
 
@@ -275,5 +266,23 @@ GestureDetector::TouchPoint::TouchPoint():
        threshold_exceeded(false)
 { }
 
+
+unsigned gesture_points(Gesture gesture)
+{
+       switch(gesture)
+       {
+       case GESTURE_NONE: return 0;
+       case GESTURE_TAP: return 1;
+       case GESTURE_TAP_2: return 2;
+       case GESTURE_TAP_3: return 3;
+       case GESTURE_DRAG: return 1;
+       case GESTURE_DRAG_2: return 2;
+       case GESTURE_DRAG_3: return 3;
+       case GESTURE_PINCH: return 2;
+       case GESTURE_ROTATE: return 2;
+       default: throw invalid_argument("gesture_points");
+       }
+}
+
 } // namespace Input
 } // namespace Msp
index a6186fdef815dce6fa56956bd8261360b1632f3f..f39fdce98e609f5b345d02efdcb9c9a5fe8be9c7 100644 (file)
@@ -48,7 +48,6 @@ private:
        Touchscreen &touchscreen;
        TouchPoint points[MAX_POINTS];
        Gesture current_gesture;
-       unsigned active_points;
        Gesture pending_tap;
        bool invalid_gesture;
        float threshold_x_sq;
@@ -66,11 +65,15 @@ private:
        void touch_move(unsigned, float, float);
        void start_gesture();
        void set_gesture_location(unsigned);
+       void set_gesture_delta(unsigned);
        void update_progress();
        void end_gesture();
        void window_resized(unsigned, unsigned);
 };
 
+
+unsigned gesture_points(Gesture);
+
 } // namespace Input
 } // namespace Msp