[clutter/clutter-1.18] GestureActions: Add per-action thresholds
- From: Bastien Nocera <hadess src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [clutter/clutter-1.18] GestureActions: Add per-action thresholds
- Date: Thu, 13 Feb 2014 17:53:55 +0000 (UTC)
commit 32b3d27bb91fd305e0d095910a75295e455edd8c
Author: Bastien Nocera <hadess hadess net>
Date: Wed Feb 12 17:41:03 2014 +0100
GestureActions: Add per-action thresholds
Instead of relying on the dnd drag threshold, add per-action
horizontal and vertical thresholds. Use them in the swipe action
as well.
https://bugzilla.gnome.org/show_bug.cgi?id=724242
clutter/clutter-gesture-action.c | 163 ++++++++++++++++++++++++++++++++++---
clutter/clutter-gesture-action.h | 10 +++
clutter/clutter-swipe-action.c | 24 +++---
3 files changed, 172 insertions(+), 25 deletions(-)
---
diff --git a/clutter/clutter-gesture-action.c b/clutter/clutter-gesture-action.c
index 3e8b50c..35019a7 100644
--- a/clutter/clutter-gesture-action.c
+++ b/clutter/clutter-gesture-action.c
@@ -124,6 +124,7 @@ struct _ClutterGestureActionPrivate
gulong stage_capture_id;
ClutterGestureTriggerEdge edge;
+ float distance_x, distance_y;
guint in_gesture : 1;
};
@@ -134,6 +135,8 @@ enum
PROP_N_TOUCH_POINTS,
PROP_THRESHOLD_TRIGGER_EDGE,
+ PROP_THRESHOLD_TRIGGER_DISTANCE_X,
+ PROP_THRESHOLD_TRIGGER_DISTANCE_Y,
PROP_LAST
};
@@ -265,7 +268,7 @@ gesture_update_release_point (GesturePoint *point,
}
static gint
-gesture_get_threshold (void)
+gesture_get_default_threshold (void)
{
gint threshold;
ClutterSettings *settings = clutter_settings_get_default ();
@@ -274,15 +277,18 @@ gesture_get_threshold (void)
}
static gboolean
-gesture_point_pass_threshold (GesturePoint *point, ClutterEvent *event)
+gesture_point_pass_threshold (ClutterGestureAction *action,
+ GesturePoint *point,
+ ClutterEvent *event)
{
- gint drag_threshold = gesture_get_threshold ();
+ float threshold_x, threshold_y;
gfloat motion_x, motion_y;
clutter_event_get_coords (event, &motion_x, &motion_y);
+ clutter_gesture_action_get_threshold_trigger_distance (action, &threshold_x, &threshold_y);
- if ((fabsf (point->press_y - motion_y) < drag_threshold) &&
- (fabsf (point->press_x - motion_x) < drag_threshold))
+ if ((fabsf (point->press_y - motion_y) < threshold_y) &&
+ (fabsf (point->press_x - motion_x) < threshold_x))
return TRUE;
return FALSE;
}
@@ -352,7 +358,8 @@ stage_captured_event_cb (ClutterActor *stage,
{
ClutterGestureActionPrivate *priv = action->priv;
ClutterActor *actor;
- gint position, drag_threshold;
+ gint position;
+ float threshold_x, threshold_y;
gboolean return_value;
GesturePoint *point;
@@ -391,7 +398,7 @@ stage_captured_event_cb (ClutterActor *stage,
/* Wait until the drag threshold has been exceeded
* before starting _TRIGGER_EDGE_AFTER gestures. */
if (priv->edge == CLUTTER_GESTURE_TRIGGER_EDGE_AFTER &&
- gesture_point_pass_threshold (point, event))
+ gesture_point_pass_threshold (action, point, event))
{
gesture_update_motion_point (point, event);
return CLUTTER_EVENT_PROPAGATE;
@@ -420,10 +427,10 @@ stage_captured_event_cb (ClutterActor *stage,
/* Check if a _TRIGGER_EDGE_BEFORE gesture needs to be cancelled because
* the drag threshold has been exceeded. */
- drag_threshold = gesture_get_threshold ();
+ clutter_gesture_action_get_threshold_trigger_distance (action, &threshold_x, &threshold_y);
if (priv->edge == CLUTTER_GESTURE_TRIGGER_EDGE_BEFORE &&
- ((fabsf (point->press_y - point->last_motion_y) > drag_threshold) ||
- (fabsf (point->press_x - point->last_motion_x) > drag_threshold)))
+ ((fabsf (point->press_y - point->last_motion_y) > threshold_y) ||
+ (fabsf (point->press_x - point->last_motion_x) > threshold_x)))
{
cancel_gesture (action);
return CLUTTER_EVENT_PROPAGATE;
@@ -571,6 +578,14 @@ clutter_gesture_action_set_property (GObject *gobject,
clutter_gesture_action_set_threshold_trigger_edge (self, g_value_get_enum (value));
break;
+ case PROP_THRESHOLD_TRIGGER_DISTANCE_X:
+ clutter_gesture_action_set_threshold_trigger_distance (self, g_value_get_float (value),
self->priv->distance_y);
+ break;
+
+ case PROP_THRESHOLD_TRIGGER_DISTANCE_Y:
+ clutter_gesture_action_set_threshold_trigger_distance (self, self->priv->distance_x, g_value_get_float
(value));
+ break;
+
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
break;
@@ -595,6 +610,20 @@ clutter_gesture_action_get_property (GObject *gobject,
g_value_set_enum (value, self->priv->edge);
break;
+ case PROP_THRESHOLD_TRIGGER_DISTANCE_X:
+ if (self->priv->distance_x > 0.0)
+ g_value_set_float (value, self->priv->distance_x);
+ else
+ g_value_set_float (value, gesture_get_default_threshold ());
+ break;
+
+ case PROP_THRESHOLD_TRIGGER_DISTANCE_Y:
+ if (self->priv->distance_y > 0.0)
+ g_value_set_float (value, self->priv->distance_y);
+ else
+ g_value_set_float (value, gesture_get_default_threshold ());
+ break;
+
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
break;
@@ -659,6 +688,44 @@ clutter_gesture_action_class_init (ClutterGestureActionClass *klass)
CLUTTER_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY);
+ /**
+ * ClutterGestureAction:threshold-trigger-distance-x:
+ *
+ * The horizontal trigger distance to be used by the action to either
+ * emit the #ClutterGestureAction::gesture-begin signal or to emit
+ * the #ClutterGestureAction::gesture-cancel signal.
+ *
+ * A negative value will be interpreted as the default drag threshold.
+ *
+ * Since: 1.18
+ */
+ gesture_props[PROP_THRESHOLD_TRIGGER_DISTANCE_X] =
+ g_param_spec_float ("threshold-trigger-distance-x",
+ P_("Threshold Trigger Horizontal Distance"),
+ P_("The horizontal trigger distance used by the action"),
+ -1.0, G_MAXFLOAT, -1.0,
+ CLUTTER_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY);
+
+ /**
+ * ClutterGestureAction:threshold-trigger-distance-y:
+ *
+ * The vertical trigger distance to be used by the action to either
+ * emit the #ClutterGestureAction::gesture-begin signal or to emit
+ * the #ClutterGestureAction::gesture-cancel signal.
+ *
+ * A negative value will be interpreted as the default drag threshold.
+ *
+ * Since: 1.18
+ */
+ gesture_props[PROP_THRESHOLD_TRIGGER_DISTANCE_Y] =
+ g_param_spec_float ("threshold-trigger-distance-y",
+ P_("Threshold Trigger Vertical Distance"),
+ P_("The vertical trigger distance used by the action"),
+ -1.0, G_MAXFLOAT, -1.0,
+ CLUTTER_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY);
+
g_object_class_install_properties (gobject_class,
PROP_LAST,
gesture_props);
@@ -1030,16 +1097,17 @@ clutter_gesture_action_set_n_touch_points (ClutterGestureAction *action,
{
ClutterActor *actor =
clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (action));
- gint i, drag_threshold;
+ gint i;
+ float threshold_x, threshold_y;
- drag_threshold = gesture_get_threshold ();
+ clutter_gesture_action_get_threshold_trigger_distance (action, &threshold_x, &threshold_y);
for (i = 0; i < priv->points->len; i++)
{
GesturePoint *point = &g_array_index (priv->points, GesturePoint, i);
- if ((ABS (point->press_y - point->last_motion_y) >= drag_threshold) ||
- (ABS (point->press_x - point->last_motion_x) >= drag_threshold))
+ if ((fabsf (point->press_y - point->last_motion_y) >= threshold_y) ||
+ (fabsf (point->press_x - point->last_motion_x) >= threshold_x))
{
begin_gesture (action, actor);
break;
@@ -1200,3 +1268,70 @@ clutter_gesture_action_get_threshold_trigger_egde (ClutterGestureAction *action)
return action->priv->edge;
}
+
+/**
+ * clutter_gesture_action_set_threshold_trigger_distance:
+ * @action: a #ClutterGestureAction
+ * @x: the distance on the horizontal axis
+ * @y: the distance on the vertical axis
+ *
+ * Sets the threshold trigger distance for the gesture drag threshold, if any.
+ *
+ * This function should only be called by sub-classes of
+ * #ClutterGestureAction during their construction phase.
+ *
+ * Since: 1.18
+ */
+void
+clutter_gesture_action_set_threshold_trigger_distance (ClutterGestureAction *action,
+ float x,
+ float y)
+{
+ g_return_if_fail (CLUTTER_IS_GESTURE_ACTION (action));
+
+ if (fabsf (x - action->priv->distance_x) > FLOAT_EPSILON)
+ {
+ action->priv->distance_x = x;
+ g_object_notify_by_pspec (G_OBJECT (action), gesture_props[PROP_THRESHOLD_TRIGGER_DISTANCE_X]);
+ }
+
+ if (fabsf (y - action->priv->distance_y) > FLOAT_EPSILON)
+ {
+ action->priv->distance_y = y;
+ g_object_notify_by_pspec (G_OBJECT (action), gesture_props[PROP_THRESHOLD_TRIGGER_DISTANCE_Y]);
+ }
+}
+
+/**
+ * clutter_gesture_action_get_threshold_trigger_distance:
+ * @action: a #ClutterGestureAction
+ * @x: (out) (allow-none): The return location for the horizontal distance, or %NULL
+ * @y: (out) (allow-none): The return location for the vertical distance, or %NULL
+ *
+ * Retrieves the threshold trigger distance of the gesture @action,
+ * as set using clutter_gesture_action_set_threshold_trigger_distance().
+ *
+ * Since: 1.18
+ */
+void
+clutter_gesture_action_get_threshold_trigger_distance (ClutterGestureAction *action,
+ float *x,
+ float *y)
+{
+ g_return_if_fail (CLUTTER_IS_GESTURE_ACTION (action));
+
+ if (x != NULL)
+ {
+ if (action->priv->distance_x > 0.0)
+ *x = action->priv->distance_x;
+ else
+ *x = gesture_get_default_threshold ();
+ }
+ if (y != NULL)
+ {
+ if (action->priv->distance_y > 0.0)
+ *y = action->priv->distance_y;
+ else
+ *y = gesture_get_default_threshold ();
+ }
+}
diff --git a/clutter/clutter-gesture-action.h b/clutter/clutter-gesture-action.h
index 9660c3e..3f4691e 100644
--- a/clutter/clutter-gesture-action.h
+++ b/clutter/clutter-gesture-action.h
@@ -155,6 +155,16 @@ void clutter_gesture_action_set_threshold_trigger_edg
CLUTTER_AVAILABLE_IN_1_18
ClutterGestureTriggerEdge clutter_gesture_action_get_threshold_trigger_egde
(ClutterGestureAction *action);
+CLUTTER_AVAILABLE_IN_1_18
+void clutter_gesture_action_set_threshold_trigger_distance
(ClutterGestureAction *action,
+ float
x,
+ float
y);
+
+CLUTTER_AVAILABLE_IN_1_18
+void clutter_gesture_action_get_threshold_trigger_distance
(ClutterGestureAction *action,
+ float
*x,
+ float
*y);
+
G_END_DECLS
#endif /* __CLUTTER_GESTURE_ACTION_H__ */
diff --git a/clutter/clutter-swipe-action.c b/clutter/clutter-swipe-action.c
index cac6199..452a5a0 100644
--- a/clutter/clutter-swipe-action.c
+++ b/clutter/clutter-swipe-action.c
@@ -54,7 +54,7 @@ struct _ClutterSwipeActionPrivate
ClutterSwipeDirection h_direction;
ClutterSwipeDirection v_direction;
- int threshold;
+ float distance_x, distance_y;
};
enum
@@ -74,13 +74,15 @@ gesture_begin (ClutterGestureAction *action,
ClutterActor *actor)
{
ClutterSwipeActionPrivate *priv = CLUTTER_SWIPE_ACTION (action)->priv;
- ClutterSettings *settings = clutter_settings_get_default ();
/* reset the state at the beginning of a new gesture */
priv->h_direction = 0;
priv->v_direction = 0;
- g_object_get (settings, "dnd-drag-threshold", &priv->threshold, NULL);
+ g_object_get (action,
+ "threshold-trigger-distance-x", &priv->distance_x,
+ "threshold-trigger-distance-y", &priv->distance_y,
+ NULL);
return TRUE;
}
@@ -108,14 +110,14 @@ gesture_progress (ClutterGestureAction *action,
delta_x = press_x - motion_x;
delta_y = press_y - motion_y;
- if (delta_x >= priv->threshold)
+ if (delta_x >= priv->distance_x)
h_direction = CLUTTER_SWIPE_DIRECTION_RIGHT;
- else if (delta_x < -priv->threshold)
+ else if (delta_x < -priv->distance_x)
h_direction = CLUTTER_SWIPE_DIRECTION_LEFT;
- if (delta_y >= priv->threshold)
+ if (delta_y >= priv->distance_y)
v_direction = CLUTTER_SWIPE_DIRECTION_DOWN;
- else if (delta_y < -priv->threshold)
+ else if (delta_y < -priv->distance_y)
v_direction = CLUTTER_SWIPE_DIRECTION_UP;
/* cancel gesture on direction reversal */
@@ -152,14 +154,14 @@ gesture_end (ClutterGestureAction *action,
0,
&release_x, &release_y);
- if (release_x - press_x > priv->threshold)
+ if (release_x - press_x > priv->distance_y)
direction |= CLUTTER_SWIPE_DIRECTION_RIGHT;
- else if (press_x - release_x > priv->threshold)
+ else if (press_x - release_x > priv->distance_x)
direction |= CLUTTER_SWIPE_DIRECTION_LEFT;
- if (release_y - press_y > priv->threshold)
+ if (release_y - press_y > priv->distance_y)
direction |= CLUTTER_SWIPE_DIRECTION_DOWN;
- else if (press_y - release_y > priv->threshold)
+ else if (press_y - release_y > priv->distance_y)
direction |= CLUTTER_SWIPE_DIRECTION_UP;
/* XXX:2.0 remove */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]