drag-action: Add ::drag-progress signal
Overriding the default behaviour of ClutterDragAction::drag-motion is currently a pain; you either need to subclass the ClutterDragAction and override the class closure for the signal, or you need to connect to the signal and call g_signal_stop_emission_by_name() - neither option being particularly nice or clean. The established pattern for these cases would be to have a boolean return value on the ::drag-motion signal, but we cannot do that without breaking ABI. To solve the issue in a backward compatible way, we should introduce a new signal, ::drag-progress, with a boolean return value. If the signal emission chain returns TRUE, the ::drag-motion signal will be emitted, and the default behaviour will be honoured; if the signal emission chain returns FALSE, instead, the ::drag-motion signal will not be emitted. https://bugzilla.gnome.org/show_bug.cgi?id=679451
This commit is contained in:
parent
0e4c6d0a87
commit
721caece5d
@ -132,6 +132,7 @@ static GParamSpec *drag_props[PROP_LAST] = { NULL, };
|
|||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
DRAG_BEGIN,
|
DRAG_BEGIN,
|
||||||
|
DRAG_PROGRESS,
|
||||||
DRAG_MOTION,
|
DRAG_MOTION,
|
||||||
DRAG_END,
|
DRAG_END,
|
||||||
|
|
||||||
@ -214,6 +215,7 @@ emit_drag_motion (ClutterDragAction *action,
|
|||||||
ClutterActor *drag_handle = NULL;
|
ClutterActor *drag_handle = NULL;
|
||||||
gfloat delta_x, delta_y;
|
gfloat delta_x, delta_y;
|
||||||
gfloat motion_x, motion_y;
|
gfloat motion_x, motion_y;
|
||||||
|
gboolean can_emit_drag_motion = TRUE;
|
||||||
|
|
||||||
clutter_event_get_coords (event, &priv->last_motion_x, &priv->last_motion_y);
|
clutter_event_get_coords (event, &priv->last_motion_x, &priv->last_motion_y);
|
||||||
priv->last_motion_state = clutter_event_get_state (event);
|
priv->last_motion_state = clutter_event_get_state (event);
|
||||||
@ -269,9 +271,17 @@ emit_drag_motion (ClutterDragAction *action,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
g_signal_emit (action, drag_signals[DRAG_MOTION], 0,
|
g_signal_emit (action, drag_signals[DRAG_PROGRESS], 0,
|
||||||
actor,
|
actor,
|
||||||
delta_x, delta_y);
|
delta_x, delta_y,
|
||||||
|
&can_emit_drag_motion);
|
||||||
|
|
||||||
|
if (can_emit_drag_motion)
|
||||||
|
{
|
||||||
|
g_signal_emit (action, drag_signals[DRAG_MOTION], 0,
|
||||||
|
actor,
|
||||||
|
delta_x, delta_y);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -494,6 +504,15 @@ clutter_drag_action_set_actor (ClutterActorMeta *meta,
|
|||||||
CLUTTER_ACTOR_META_CLASS (clutter_drag_action_parent_class)->set_actor (meta, actor);
|
CLUTTER_ACTOR_META_CLASS (clutter_drag_action_parent_class)->set_actor (meta, actor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
clutter_drag_action_real_drag_progress (ClutterDragAction *action,
|
||||||
|
ClutterActor *actor,
|
||||||
|
gfloat delta_x,
|
||||||
|
gfloat delta_y)
|
||||||
|
{
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
clutter_drag_action_real_drag_motion (ClutterDragAction *action,
|
clutter_drag_action_real_drag_motion (ClutterDragAction *action,
|
||||||
ClutterActor *actor,
|
ClutterActor *actor,
|
||||||
@ -621,6 +640,20 @@ clutter_drag_action_dispose (GObject *gobject)
|
|||||||
G_OBJECT_CLASS (clutter_drag_action_parent_class)->dispose (gobject);
|
G_OBJECT_CLASS (clutter_drag_action_parent_class)->dispose (gobject);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
drag_progress_accum (GSignalInvocationHint *ihint,
|
||||||
|
GValue *return_accu,
|
||||||
|
const GValue *handler_return,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
gboolean continue_emission;
|
||||||
|
|
||||||
|
continue_emission = g_value_get_boolean (handler_return);
|
||||||
|
g_value_set_boolean (return_accu, continue_emission);
|
||||||
|
|
||||||
|
return continue_emission;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
clutter_drag_action_class_init (ClutterDragActionClass *klass)
|
clutter_drag_action_class_init (ClutterDragActionClass *klass)
|
||||||
{
|
{
|
||||||
@ -631,6 +664,7 @@ clutter_drag_action_class_init (ClutterDragActionClass *klass)
|
|||||||
|
|
||||||
meta_class->set_actor = clutter_drag_action_set_actor;
|
meta_class->set_actor = clutter_drag_action_set_actor;
|
||||||
|
|
||||||
|
klass->drag_progress = clutter_drag_action_real_drag_progress;
|
||||||
klass->drag_motion = clutter_drag_action_real_drag_motion;
|
klass->drag_motion = clutter_drag_action_real_drag_motion;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -762,6 +796,46 @@ clutter_drag_action_class_init (ClutterDragActionClass *klass)
|
|||||||
G_TYPE_FLOAT,
|
G_TYPE_FLOAT,
|
||||||
CLUTTER_TYPE_MODIFIER_TYPE);
|
CLUTTER_TYPE_MODIFIER_TYPE);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ClutterDragAction::drag-progress:
|
||||||
|
* @action: the #ClutterDragAction that emitted the signal
|
||||||
|
* @actor: the #ClutterActor attached to the action
|
||||||
|
* @delta_x: the X component of the distance between the press event
|
||||||
|
* that began the dragging and the current position of the pointer,
|
||||||
|
* as of the latest motion event
|
||||||
|
* @delta_y: the Y component of the distance between the press event
|
||||||
|
* that began the dragging and the current position of the pointer,
|
||||||
|
* as of the latest motion event
|
||||||
|
*
|
||||||
|
* The ::drag-progress signal is emitted for each motion event after
|
||||||
|
* the #ClutterDragAction::drag-begin signal has been emitted.
|
||||||
|
*
|
||||||
|
* The components of the distance between the press event and the
|
||||||
|
* latest motion event are computed in the actor's coordinate space,
|
||||||
|
* to take into account eventual transformations. If you want the
|
||||||
|
* stage coordinates of the latest motion event you can use
|
||||||
|
* clutter_drag_action_get_motion_coords().
|
||||||
|
*
|
||||||
|
* The default handler will emit #ClutterDragAction::drag-motion,
|
||||||
|
* if #ClutterDragAction::drag-progress emission returns %TRUE.
|
||||||
|
*
|
||||||
|
* Return value: %TRUE if the drag should continue, and %FALSE
|
||||||
|
* if it should be stopped.
|
||||||
|
*
|
||||||
|
* Since: 1.12
|
||||||
|
*/
|
||||||
|
drag_signals[DRAG_PROGRESS] =
|
||||||
|
g_signal_new (I_("drag-progress"),
|
||||||
|
CLUTTER_TYPE_DRAG_ACTION,
|
||||||
|
G_SIGNAL_RUN_LAST,
|
||||||
|
G_STRUCT_OFFSET (ClutterDragActionClass, drag_progress),
|
||||||
|
drag_progress_accum, NULL,
|
||||||
|
_clutter_marshal_BOOLEAN__OBJECT_FLOAT_FLOAT,
|
||||||
|
G_TYPE_BOOLEAN, 3,
|
||||||
|
CLUTTER_TYPE_ACTOR,
|
||||||
|
G_TYPE_FLOAT,
|
||||||
|
G_TYPE_FLOAT);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ClutterDragAction::drag-motion:
|
* ClutterDragAction::drag-motion:
|
||||||
* @action: the #ClutterDragAction that emitted the signal
|
* @action: the #ClutterDragAction that emitted the signal
|
||||||
@ -785,9 +859,9 @@ clutter_drag_action_class_init (ClutterDragActionClass *klass)
|
|||||||
* The default handler of the signal will call clutter_actor_move_by()
|
* The default handler of the signal will call clutter_actor_move_by()
|
||||||
* either on @actor or, if set, of #ClutterDragAction:drag-handle using
|
* either on @actor or, if set, of #ClutterDragAction:drag-handle using
|
||||||
* the @delta_x and @delta_y components of the dragging motion. If you
|
* the @delta_x and @delta_y components of the dragging motion. If you
|
||||||
* want to override the default behaviour, you can connect to this
|
* want to override the default behaviour, you can connect to the
|
||||||
* signal and call g_signal_stop_emission_by_name() from within your
|
* #ClutterDragAction::drag-progress signal and return %FALSE from the
|
||||||
* callback.
|
* handler.
|
||||||
*
|
*
|
||||||
* Since: 1.4
|
* Since: 1.4
|
||||||
*/
|
*/
|
||||||
|
@ -78,27 +78,30 @@ struct _ClutterDragActionClass
|
|||||||
ClutterActionClass parent_class;
|
ClutterActionClass parent_class;
|
||||||
|
|
||||||
/*< public >*/
|
/*< public >*/
|
||||||
void (* drag_begin) (ClutterDragAction *action,
|
void (* drag_begin) (ClutterDragAction *action,
|
||||||
ClutterActor *actor,
|
ClutterActor *actor,
|
||||||
gfloat event_x,
|
gfloat event_x,
|
||||||
gfloat event_y,
|
gfloat event_y,
|
||||||
ClutterModifierType modifiers);
|
ClutterModifierType modifiers);
|
||||||
void (* drag_motion) (ClutterDragAction *action,
|
void (* drag_motion) (ClutterDragAction *action,
|
||||||
ClutterActor *actor,
|
ClutterActor *actor,
|
||||||
gfloat delta_x,
|
gfloat delta_x,
|
||||||
gfloat delta_y);
|
gfloat delta_y);
|
||||||
void (* drag_end) (ClutterDragAction *action,
|
void (* drag_end) (ClutterDragAction *action,
|
||||||
ClutterActor *actor,
|
ClutterActor *actor,
|
||||||
gfloat event_x,
|
gfloat event_x,
|
||||||
gfloat event_y,
|
gfloat event_y,
|
||||||
ClutterModifierType modifiers);
|
ClutterModifierType modifiers);
|
||||||
|
gboolean (* drag_progress) (ClutterDragAction *action,
|
||||||
|
ClutterActor *actor,
|
||||||
|
gfloat delta_x,
|
||||||
|
gfloat delta_y);
|
||||||
|
|
||||||
/*< private >*/
|
/*< private >*/
|
||||||
void (* _clutter_drag_action1) (void);
|
void (* _clutter_drag_action1) (void);
|
||||||
void (* _clutter_drag_action2) (void);
|
void (* _clutter_drag_action2) (void);
|
||||||
void (* _clutter_drag_action3) (void);
|
void (* _clutter_drag_action3) (void);
|
||||||
void (* _clutter_drag_action4) (void);
|
void (* _clutter_drag_action4) (void);
|
||||||
void (* _clutter_drag_action5) (void);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
GType clutter_drag_action_get_type (void) G_GNUC_CONST;
|
GType clutter_drag_action_get_type (void) G_GNUC_CONST;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user