gesture-action: add _get_motion_delta()/_get_velocity()
Add some accessors to simplify common tasks for GestureAction users: • clutter_gesture_action_get_motion_delta() to get the delta on the X and Y axis in stage coordinates since the last motion event, and the scalar distance travelled; • clutter_gesture_action_get_velocity() to get an estimate of the speed of the last motion event along the X and Y axis and as a scalar value in pixels per millisecond. https://bugzilla.gnome.org/show_bug.cgi?id=681648
This commit is contained in:
parent
e8e91b62c8
commit
436ebb2716
@ -62,7 +62,10 @@
|
||||
#include "clutter-marshal.h"
|
||||
#include "clutter-private.h"
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#define MAX_GESTURE_POINTS (10)
|
||||
#define FLOAT_EPSILON (1e-15)
|
||||
|
||||
typedef struct
|
||||
{
|
||||
@ -70,7 +73,10 @@ typedef struct
|
||||
ClutterEventSequence *sequence;
|
||||
|
||||
gfloat press_x, press_y;
|
||||
gint64 last_motion_time;
|
||||
gfloat last_motion_x, last_motion_y;
|
||||
gint64 last_delta_time;
|
||||
gfloat last_delta_x, last_delta_y;
|
||||
gfloat release_x, release_y;
|
||||
} GesturePoint;
|
||||
|
||||
@ -118,6 +124,10 @@ gesture_register_point (ClutterGestureAction *action, ClutterEvent *event)
|
||||
clutter_event_get_coords (event, &point->press_x, &point->press_y);
|
||||
point->last_motion_x = point->press_x;
|
||||
point->last_motion_y = point->press_y;
|
||||
point->last_motion_time = clutter_event_get_time (event);
|
||||
|
||||
point->last_delta_x = point->last_delta_y = 0;
|
||||
point->last_delta_time = 0;
|
||||
|
||||
if (clutter_event_type (event) != CLUTTER_BUTTON_PRESS)
|
||||
point->sequence = clutter_event_get_event_sequence (event);
|
||||
@ -192,6 +202,8 @@ stage_captured_event_cb (ClutterActor *stage,
|
||||
gint position;
|
||||
gboolean return_value;
|
||||
GesturePoint *point;
|
||||
gfloat motion_x, motion_y;
|
||||
gint64 time;
|
||||
|
||||
if ((point = gesture_find_point (action, event, &position)) == NULL)
|
||||
return CLUTTER_EVENT_PROPAGATE;
|
||||
@ -218,8 +230,8 @@ stage_captured_event_cb (ClutterActor *stage,
|
||||
|
||||
case CLUTTER_TOUCH_UPDATE:
|
||||
clutter_event_get_coords (event,
|
||||
&point->last_motion_x,
|
||||
&point->last_motion_y);
|
||||
&motion_x,
|
||||
&motion_y);
|
||||
|
||||
if (priv->points->len < priv->requested_nb_points)
|
||||
return CLUTTER_EVENT_PROPAGATE;
|
||||
@ -233,8 +245,8 @@ stage_captured_event_cb (ClutterActor *stage,
|
||||
"dnd-drag-threshold", &drag_threshold,
|
||||
NULL);
|
||||
|
||||
if ((ABS (point->press_y - point->last_motion_y) >= drag_threshold) ||
|
||||
(ABS (point->press_x - point->last_motion_x) >= drag_threshold))
|
||||
if ((ABS (point->press_y - motion_y) >= drag_threshold) ||
|
||||
(ABS (point->press_x - motion_x) >= drag_threshold))
|
||||
{
|
||||
priv->in_gesture = TRUE;
|
||||
|
||||
@ -250,6 +262,15 @@ stage_captured_event_cb (ClutterActor *stage,
|
||||
return CLUTTER_EVENT_PROPAGATE;
|
||||
}
|
||||
|
||||
point->last_delta_x = motion_x - point->last_motion_x;
|
||||
point->last_delta_y = motion_y - point->last_motion_y;
|
||||
point->last_motion_x = motion_x;
|
||||
point->last_motion_y = motion_y;
|
||||
|
||||
time = clutter_event_get_time (event);
|
||||
point->last_delta_time = time - point->last_motion_time;
|
||||
point->last_motion_time = time;
|
||||
|
||||
g_signal_emit (action, gesture_signals[GESTURE_PROGRESS], 0, actor,
|
||||
&return_value);
|
||||
if (!return_value)
|
||||
@ -267,6 +288,12 @@ stage_captured_event_cb (ClutterActor *stage,
|
||||
if (priv->in_gesture &&
|
||||
((priv->points->len - 1) < priv->requested_nb_points))
|
||||
{
|
||||
/* Treat the release event as the continuation of the last motion,
|
||||
* in case the user keeps the pointer still for a while before
|
||||
* releasing it. */
|
||||
time = clutter_event_get_time (event);
|
||||
point->last_delta_time += time - point->last_motion_time;
|
||||
|
||||
priv->in_gesture = FALSE;
|
||||
g_signal_emit (action, gesture_signals[GESTURE_END], 0, actor);
|
||||
}
|
||||
@ -572,6 +599,49 @@ clutter_gesture_action_get_motion_coords (ClutterGestureAction *action,
|
||||
device).last_motion_y;
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_gesture_action_get_motion_delta:
|
||||
* @action: a #ClutterGestureAction
|
||||
* @device: currently unused, set to 0
|
||||
* @delta_x: (out) (allow-none): return location for the X axis
|
||||
* component of the incremental motion delta
|
||||
* @delta_y: (out) (allow-none): return location for the Y axis
|
||||
* component of the incremental motion delta
|
||||
*
|
||||
* Retrieves the incremental delta since the last motion event
|
||||
* during the dragging.
|
||||
*
|
||||
* Return value: the distance since last motion event
|
||||
*
|
||||
* Since: 1.12
|
||||
*/
|
||||
gfloat
|
||||
clutter_gesture_action_get_motion_delta (ClutterGestureAction *action,
|
||||
guint device,
|
||||
gfloat *delta_x,
|
||||
gfloat *delta_y)
|
||||
{
|
||||
gfloat d_x, d_y;
|
||||
|
||||
g_return_val_if_fail (CLUTTER_IS_GESTURE_ACTION (action), 0);
|
||||
g_return_val_if_fail (action->priv->points->len > device, 0);
|
||||
|
||||
d_x = g_array_index (action->priv->points,
|
||||
GesturePoint,
|
||||
device).last_delta_x;
|
||||
d_y = g_array_index (action->priv->points,
|
||||
GesturePoint,
|
||||
device).last_delta_y;
|
||||
|
||||
if (delta_x)
|
||||
*delta_x = d_x;
|
||||
|
||||
if (delta_y)
|
||||
*delta_y = d_y;
|
||||
|
||||
return sqrt ((d_x * d_x) + (d_y * d_y));
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_gesture_action_get_release_coords:
|
||||
* @action: a #ClutterGestureAction
|
||||
@ -606,6 +676,49 @@ clutter_gesture_action_get_release_coords (ClutterGestureAction *action,
|
||||
device).release_y;
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_gesture_action_get_velocity:
|
||||
* @action: a #ClutterGestureAction
|
||||
* @device: currently unused, set to 0
|
||||
* @velocity_x: (out) (allow-none): return location for the latest motion
|
||||
* event's X velocity
|
||||
* @velocity_y: (out) (allow-none): return location for the latest motion
|
||||
* event's Y velocity
|
||||
*
|
||||
* Retrieves the velocity, in stage pixels per microseconds, of the
|
||||
* latest motion event during the dragging
|
||||
*
|
||||
* Since: 1.12
|
||||
*/
|
||||
gfloat
|
||||
clutter_gesture_action_get_velocity (ClutterGestureAction *action,
|
||||
guint device,
|
||||
gfloat *velocity_x,
|
||||
gfloat *velocity_y)
|
||||
{
|
||||
gfloat d_x, d_y, distance, velocity;
|
||||
gint64 d_t;
|
||||
|
||||
g_return_val_if_fail (CLUTTER_IS_GESTURE_ACTION (action), 0);
|
||||
g_return_val_if_fail (action->priv->points->len > device, 0);
|
||||
|
||||
distance = clutter_gesture_action_get_motion_delta (action, device,
|
||||
&d_x, &d_y);
|
||||
|
||||
d_t = g_array_index (action->priv->points,
|
||||
GesturePoint,
|
||||
device).last_delta_time;
|
||||
|
||||
if (velocity_x)
|
||||
*velocity_x = d_t > FLOAT_EPSILON ? d_x / d_t : 0;
|
||||
|
||||
if (velocity_y)
|
||||
*velocity_y = d_t > FLOAT_EPSILON ? d_y / d_t : 0;
|
||||
|
||||
velocity = d_t > FLOAT_EPSILON ? distance / d_t : 0;
|
||||
return velocity;
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_gesture_action_get_n_touch_points:
|
||||
* @action: a #ClutterGestureAction
|
||||
|
@ -113,10 +113,20 @@ void clutter_gesture_action_get_motion_coords (ClutterGestureA
|
||||
guint device,
|
||||
gfloat *motion_x,
|
||||
gfloat *motion_y);
|
||||
CLUTTER_AVAILABLE_IN_1_12
|
||||
gfloat clutter_gesture_action_get_motion_delta (ClutterGestureAction *action,
|
||||
guint device,
|
||||
gfloat *delta_x,
|
||||
gfloat *delta_y);
|
||||
void clutter_gesture_action_get_release_coords (ClutterGestureAction *action,
|
||||
guint device,
|
||||
gfloat *release_x,
|
||||
gfloat *release_y);
|
||||
CLUTTER_AVAILABLE_IN_1_12
|
||||
gfloat clutter_gesture_action_get_velocity (ClutterGestureAction *action,
|
||||
guint device,
|
||||
gfloat *velocity_x,
|
||||
gfloat *velocity_y);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
@ -734,10 +734,12 @@ clutter_geometry_get_type
|
||||
clutter_geometry_intersects
|
||||
clutter_geometry_union
|
||||
clutter_gesture_action_get_motion_coords
|
||||
clutter_gesture_action_get_motion_delta
|
||||
clutter_gesture_action_get_n_touch_points
|
||||
clutter_gesture_action_get_press_coords
|
||||
clutter_gesture_action_get_release_coords
|
||||
clutter_gesture_action_get_type
|
||||
clutter_gesture_action_get_velocity
|
||||
clutter_gesture_action_set_n_touch_points
|
||||
clutter_gesture_action_new
|
||||
clutter_get_accessibility_enabled
|
||||
|
@ -2941,7 +2941,9 @@ ClutterGestureActionClass
|
||||
clutter_gesture_action_new
|
||||
clutter_gesture_action_get_press_coords
|
||||
clutter_gesture_action_get_motion_coords
|
||||
clutter_gesture_action_get_motion_delta
|
||||
clutter_gesture_action_get_release_coords
|
||||
clutter_gesture_action_get_velocity
|
||||
clutter_gesture_action_get_n_touch_points
|
||||
clutter_gesture_action_set_n_touch_points
|
||||
<SUBSECTION Standard>
|
||||
|
Loading…
Reference in New Issue
Block a user