drag-action: Added x-drag-threshold and y-drag-threshold properties
authorHenrik Hedberg <hhedberg@innologies.fi>
Fri, 3 Sep 2010 17:00:40 +0000 (20:00 +0300)
committerEmmanuele Bassi <ebassi@linux.intel.com>
Tue, 7 Sep 2010 09:40:49 +0000 (10:40 +0100)
                *** This is an API change ***

Replaced the original drag-threshold property with two separate
horizontal (x-drag-threshold) and vertical (y-drag-threshold)
thresholds.

It is some times necessary to have different drag thresholds for the
horizontal and vertical axes. For example, when a draggable actor is
inside a horizontal scrolling area, only vertical movement must begin
dragging. That can be achieved by setting the x-drag-threshold to
G_MAXUINT while y-drag-threshold is something usual, say, 20 pixels.

This is different than drag axis, because after the threshold
has been cleared by the pointer, the draggable actor can be dragged
along both axes (if allowed by the drag-axis property).

http://bugzilla.clutter-project.org/show_bug.cgi?id=2291

Signed-off-by: Emmanuele Bassi <ebassi@linux.intel.com>
clutter/clutter-drag-action.c
clutter/clutter-drag-action.h
tests/interactive/test-drag.c

index 0ca4dc2..0e9ecdb 100644 (file)
@@ -72,7 +72,8 @@ struct _ClutterDragActionPrivate
 {
   ClutterActor *stage;
 
-  gfloat drag_threshold;
+  gfloat x_drag_threshold;
+  gfloat y_drag_threshold;
   ClutterActor *drag_handle;
   ClutterDragAxis drag_axis;
 
@@ -98,7 +99,8 @@ enum
 {
   PROP_0,
 
-  PROP_DRAG_THRESHOLD,
+  PROP_X_DRAG_THRESHOLD,
+  PROP_Y_DRAG_THRESHOLD,
   PROP_DRAG_HANDLE,
   PROP_DRAG_AXIS,
 
@@ -188,8 +190,8 @@ emit_drag_motion (ClutterDragAction *action,
 
   if (priv->emit_delayed_press)
     {
-      if (ABS (delta_x) >= priv->drag_threshold ||
-          ABS (delta_y) >= priv->drag_threshold)
+      if (ABS (delta_x) >= priv->x_drag_threshold ||
+          ABS (delta_y) >= priv->y_drag_threshold)
         {
           priv->emit_delayed_press = FALSE;
 
@@ -308,7 +310,7 @@ on_button_press (ClutterActor      *actor,
                                        &priv->transformed_press_x,
                                        &priv->transformed_press_y);
 
-  if (priv->drag_threshold == 0)
+  if (priv->x_drag_threshold == 0 || priv->y_drag_threshold == 0)
     emit_drag_begin (action, actor, event);
   else
     priv->emit_delayed_press = TRUE;
@@ -375,11 +377,18 @@ clutter_drag_action_set_property (GObject      *gobject,
                                   GParamSpec   *pspec)
 {
   ClutterDragAction *action = CLUTTER_DRAG_ACTION (gobject);
+  ClutterDragActionPrivate *priv = action->priv;
 
   switch (prop_id)
     {
-    case PROP_DRAG_THRESHOLD:
-      clutter_drag_action_set_drag_threshold (action, g_value_get_uint (value));
+    case PROP_X_DRAG_THRESHOLD:
+      clutter_drag_action_set_drag_threshold (action, g_value_get_uint (value),
+                                              priv->y_drag_threshold);
+      break;
+
+    case PROP_Y_DRAG_THRESHOLD:
+      clutter_drag_action_set_drag_threshold (action, priv->x_drag_threshold,
+                                              g_value_get_uint (value));
       break;
 
     case PROP_DRAG_HANDLE:
@@ -405,8 +414,12 @@ clutter_drag_action_get_property (GObject    *gobject,
 
   switch (prop_id)
     {
-    case PROP_DRAG_THRESHOLD:
-      g_value_set_uint (value, priv->drag_threshold);
+    case PROP_X_DRAG_THRESHOLD:
+      g_value_set_uint (value, priv->x_drag_threshold);
+      break;
+
+    case PROP_Y_DRAG_THRESHOLD:
+      g_value_set_uint (value, priv->y_drag_threshold);
       break;
 
     case PROP_DRAG_HANDLE:
@@ -466,24 +479,46 @@ clutter_drag_action_class_init (ClutterDragActionClass *klass)
   klass->drag_motion = clutter_drag_action_real_drag_motion;
 
   /**
-   * ClutterDragAction:drag-threshold:
+   * ClutterDragAction:x-drag-threshold:
+   *
+   * The horizontal threshold, in pixels, that begins a drag action
+   *
+   * When set to a non-zero value, #ClutterDragAction will only emit
+   * #ClutterDragAction::drag-begin if the pointer has moved
+   * horizontally at least of the given amount of pixels since
+   * the button press event
+   *
+   * Since: 1.4
+   */
+  pspec = g_param_spec_uint ("x-drag-threshold",
+                             P_("Horizontal Drag Threshold"),
+                             P_("The horizontal amount of pixels required to start dragging"),
+                             0, G_MAXUINT,
+                             0,
+                             CLUTTER_PARAM_READWRITE);
+  obj_props[PROP_X_DRAG_THRESHOLD] = pspec;
+  g_object_class_install_property (gobject_class, PROP_X_DRAG_THRESHOLD, pspec);
+
+  /**
+   * ClutterDragAction:y-drag-threshold:
    *
-   * The threshold, in pixels, that begins a drag action
+   * The vertical threshold, in pixels, that begins a drag action
    *
    * When set to a non-zero value, #ClutterDragAction will only emit
-   * #ClutterDragAction::drag-begin if the pointer has moved at least
-   * of the given amount of pixels since the button press event
+   * #ClutterDragAction::drag-begin if the pointer has moved
+   * vertically at least of the given amount of pixels since
+   * the button press event
    *
    * Since: 1.4
    */
-  pspec = g_param_spec_uint ("drag-threshold",
-                             P_("Drag Threshold"),
-                             P_("The amount of pixels required to start dragging"),
+  pspec = g_param_spec_uint ("y-drag-threshold",
+                             P_("Vertical Drag Threshold"),
+                             P_("The vertical amount of pixels required to start dragging"),
                              0, G_MAXUINT,
                              0,
                              CLUTTER_PARAM_READWRITE);
-  obj_props[PROP_DRAG_THRESHOLD] = pspec;
-  g_object_class_install_property (gobject_class, PROP_DRAG_THRESHOLD, pspec);
+  obj_props[PROP_Y_DRAG_THRESHOLD] = pspec;
+  g_object_class_install_property (gobject_class, PROP_Y_DRAG_THRESHOLD, pspec);
 
   /**
    * ClutterDragAction:drag-handle:
@@ -535,7 +570,8 @@ clutter_drag_action_class_init (ClutterDragActionClass *klass)
    * starts the dragging
    *
    * The emission of this signal can be delayed by using the
-   * #ClutterDragAction:drag-threshold property
+   * #ClutterDragAction:x-drag-threshold and
+   * #ClutterDragAction:y-drag-threshold properties
    *
    * Since: 1.4
    */
@@ -650,45 +686,67 @@ clutter_drag_action_new (void)
  * @action: a #ClutterDragAction
  * @threshold: a distance, in pixels
  *
- * Sets the drag threshold that must be cleared by the pointer
- * before @action can begin the dragging
+ * Sets the horizontal and vertical drag thresholds that must be
+ * cleared by the pointer before @action can begin the dragging
  *
  * Since: 1.4
  */
 void
 clutter_drag_action_set_drag_threshold (ClutterDragAction *action,
-                                        guint              threshold)
+                                        guint              x_threshold,
+                                       guint              y_threshold)
 {
   ClutterDragActionPrivate *priv;
+  GObject *self;
 
   g_return_if_fail (CLUTTER_IS_DRAG_ACTION (action));
 
+  self = G_OBJECT (action);
   priv = action->priv;
 
-  if (priv->drag_threshold == threshold)
-    return;
+  g_object_freeze_notify (self);
+
+  if (priv->x_drag_threshold != x_threshold)
+    {
+      priv->x_drag_threshold = x_threshold;
+
+      _clutter_notify_by_pspec (self, obj_props[PROP_X_DRAG_THRESHOLD]);
+    }
 
-  priv->drag_threshold = threshold;
+  if (priv->y_drag_threshold != y_threshold)
+    {
+      priv->y_drag_threshold = y_threshold;
+
+      _clutter_notify_by_pspec (self, obj_props[PROP_Y_DRAG_THRESHOLD]);
+    }
 
-  _clutter_notify_by_pspec (G_OBJECT (action), obj_props[PROP_DRAG_THRESHOLD]);
+  g_object_thaw_notify (self);
 }
 
 /**
  * clutter_drag_action_get_drag_threshold:
  * @action: a #ClutterDragAction
+ * @x_threshold: (out): return location for the horizontal drag
+ *   threshold value, in pixels
+ * @y_threshold: (out): return location for the vertical drag
+ *   threshold value, in pixels
  *
- * Retrieves the value set by clutter_drag_action_set_drag_threshold()
- *
- * Return value: the drag threshold value, in pixels
+ * Retrieves the values set by clutter_drag_action_set_drag_threshold()
  *
  * Since: 1.4
  */
-guint
-clutter_drag_action_get_drag_threshold (ClutterDragAction *action)
+void
+clutter_drag_action_get_drag_threshold (ClutterDragAction *action,
+                                        guint             *x_threshold,
+                                       guint             *y_threshold)
 {
-  g_return_val_if_fail (CLUTTER_IS_DRAG_ACTION (action), 0);
+  g_return_if_fail (CLUTTER_IS_DRAG_ACTION (action));
+
+  if (x_threshold)
+    *x_threshold = action->priv->x_drag_threshold;
 
-  return action->priv->drag_threshold;
+  if (y_threshold)
+    *y_threshold = action->priv->y_drag_threshold;
 }
 
 /**
index aa7c15c..90903a6 100644 (file)
@@ -124,8 +124,11 @@ GType clutter_drag_action_get_type (void) G_GNUC_CONST;
 ClutterAction * clutter_drag_action_new                   (void);
 
 void            clutter_drag_action_set_drag_threshold (ClutterDragAction *action,
-                                                        guint              threshold);
-guint           clutter_drag_action_get_drag_threshold (ClutterDragAction *action);
+                                                        guint              x_threshold,
+                                                        guint              y_threshold);
+void            clutter_drag_action_get_drag_threshold (ClutterDragAction *action,
+                                                        guint             *x_threshold,
+                                                        guint             *y_threshold);
 void            clutter_drag_action_set_drag_handle    (ClutterDragAction *action,
                                                         ClutterActor      *handle);
 ClutterActor *  clutter_drag_action_get_drag_handle    (ClutterDragAction *action);
index 058c722..6117bae 100644 (file)
@@ -120,15 +120,23 @@ get_drag_axis (const gchar *str)
 }
 
 static gchar *drag_axis = NULL;
-static gint drag_threshold = 0;
+static gint x_drag_threshold = 0;
+static gint y_drag_threshold = 0;
 
 static GOptionEntry entries[] = {
   {
-    "threshold", 't',
+    "x-threshold", 'x',
     0,
     G_OPTION_ARG_INT,
-    &drag_threshold,
-    "Set the drag threshold", "PIXELS"
+    &x_drag_threshold,
+    "Set the horizontal drag threshold", "PIXELS"
+  },
+  {
+    "y-threshold", 'y',
+    0,
+    G_OPTION_ARG_INT,
+    &y_drag_threshold,
+    "Set the vertical drag threshold", "PIXELS"
   },
   {
     "axis", 'a',
@@ -181,7 +189,8 @@ test_drag_main (int argc, char *argv[])
 
   action = clutter_drag_action_new ();
   clutter_drag_action_set_drag_threshold (CLUTTER_DRAG_ACTION (action),
-                                          drag_threshold);
+                                          x_drag_threshold,
+                                          y_drag_threshold);
   clutter_drag_action_set_drag_axis (CLUTTER_DRAG_ACTION (action),
                                      get_drag_axis (drag_axis));