GestureDetector::GestureDetector(Touchscreen &ts):
touchscreen(ts),
current_gesture(GESTURE_NONE),
- active_points(0),
pending_tap(GESTURE_NONE),
invalid_gesture(false)
{
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)
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);
if(current_gesture==GESTURE_NONE && !invalid_gesture)
start_gesture();
- else if(active_points&(1<<i))
+ else if(i<gesture_points(current_gesture))
update_progress();
}
}
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);
}
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. */
set_button_state(current_gesture, false, true);
set_axis_value(2, 0, false);
current_gesture = GESTURE_NONE;
- active_points = 0;
pending_tap = GESTURE_NONE;
}
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