summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEmanuele Aina <emanuele.aina@collabora.com>2012-08-25 16:04:24 +0200
committerGustavo Noronha Silva <gns@gnome.org>2012-08-28 09:57:33 -0300
commit436ebb2716b24743b3873aa7b330073c48793b86 (patch)
tree1464c1aa1d0286d5ceb46cb8a563a30d881cccef
parente8e91b62c896223d8f7bc4421862b87ef002a972 (diff)
downloadclutter-436ebb2716b24743b3873aa7b330073c48793b86.tar.gz
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
-rw-r--r--clutter/clutter-gesture-action.c121
-rw-r--r--clutter/clutter-gesture-action.h10
-rw-r--r--clutter/clutter.symbols2
-rw-r--r--doc/reference/clutter/clutter-sections.txt2
4 files changed, 131 insertions, 4 deletions
diff --git a/clutter/clutter-gesture-action.c b/clutter/clutter-gesture-action.c
index ace980b86..5994107ef 100644
--- a/clutter/clutter-gesture-action.c
+++ b/clutter/clutter-gesture-action.c
@@ -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);
}
@@ -573,6 +600,49 @@ clutter_gesture_action_get_motion_coords (ClutterGestureAction *action,
}
/**
+ * 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
* @device: currently unused, set to 0
@@ -607,6 +677,49 @@ clutter_gesture_action_get_release_coords (ClutterGestureAction *action,
}
/**
+ * 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
*
diff --git a/clutter/clutter-gesture-action.h b/clutter/clutter-gesture-action.h
index 3aade5b4b..7587bd0ef 100644
--- a/clutter/clutter-gesture-action.h
+++ b/clutter/clutter-gesture-action.h
@@ -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
diff --git a/clutter/clutter.symbols b/clutter/clutter.symbols
index 261ac8351..9991579eb 100644
--- a/clutter/clutter.symbols
+++ b/clutter/clutter.symbols
@@ -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
diff --git a/doc/reference/clutter/clutter-sections.txt b/doc/reference/clutter/clutter-sections.txt
index 1b2a08d4a..72b788965 100644
--- a/doc/reference/clutter/clutter-sections.txt
+++ b/doc/reference/clutter/clutter-sections.txt
@@ -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>