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
|
||||
{
|
||||
DRAG_BEGIN,
|
||||
DRAG_PROGRESS,
|
||||
DRAG_MOTION,
|
||||
DRAG_END,
|
||||
|
||||
@ -214,6 +215,7 @@ emit_drag_motion (ClutterDragAction *action,
|
||||
ClutterActor *drag_handle = NULL;
|
||||
gfloat delta_x, delta_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);
|
||||
priv->last_motion_state = clutter_event_get_state (event);
|
||||
@ -269,9 +271,17 @@ emit_drag_motion (ClutterDragAction *action,
|
||||
return;
|
||||
}
|
||||
|
||||
g_signal_emit (action, drag_signals[DRAG_MOTION], 0,
|
||||
g_signal_emit (action, drag_signals[DRAG_PROGRESS], 0,
|
||||
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
|
||||
@ -494,6 +504,15 @@ clutter_drag_action_set_actor (ClutterActorMeta *meta,
|
||||
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
|
||||
clutter_drag_action_real_drag_motion (ClutterDragAction *action,
|
||||
ClutterActor *actor,
|
||||
@ -621,6 +640,20 @@ clutter_drag_action_dispose (GObject *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
|
||||
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;
|
||||
|
||||
klass->drag_progress = clutter_drag_action_real_drag_progress;
|
||||
klass->drag_motion = clutter_drag_action_real_drag_motion;
|
||||
|
||||
/**
|
||||
@ -762,6 +796,46 @@ clutter_drag_action_class_init (ClutterDragActionClass *klass)
|
||||
G_TYPE_FLOAT,
|
||||
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:
|
||||
* @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()
|
||||
* either on @actor or, if set, of #ClutterDragAction:drag-handle using
|
||||
* the @delta_x and @delta_y components of the dragging motion. If you
|
||||
* want to override the default behaviour, you can connect to this
|
||||
* signal and call g_signal_stop_emission_by_name() from within your
|
||||
* callback.
|
||||
* want to override the default behaviour, you can connect to the
|
||||
* #ClutterDragAction::drag-progress signal and return %FALSE from the
|
||||
* handler.
|
||||
*
|
||||
* Since: 1.4
|
||||
*/
|
||||
|
@ -78,27 +78,30 @@ struct _ClutterDragActionClass
|
||||
ClutterActionClass parent_class;
|
||||
|
||||
/*< public >*/
|
||||
void (* drag_begin) (ClutterDragAction *action,
|
||||
ClutterActor *actor,
|
||||
gfloat event_x,
|
||||
gfloat event_y,
|
||||
ClutterModifierType modifiers);
|
||||
void (* drag_motion) (ClutterDragAction *action,
|
||||
ClutterActor *actor,
|
||||
gfloat delta_x,
|
||||
gfloat delta_y);
|
||||
void (* drag_end) (ClutterDragAction *action,
|
||||
ClutterActor *actor,
|
||||
gfloat event_x,
|
||||
gfloat event_y,
|
||||
ClutterModifierType modifiers);
|
||||
void (* drag_begin) (ClutterDragAction *action,
|
||||
ClutterActor *actor,
|
||||
gfloat event_x,
|
||||
gfloat event_y,
|
||||
ClutterModifierType modifiers);
|
||||
void (* drag_motion) (ClutterDragAction *action,
|
||||
ClutterActor *actor,
|
||||
gfloat delta_x,
|
||||
gfloat delta_y);
|
||||
void (* drag_end) (ClutterDragAction *action,
|
||||
ClutterActor *actor,
|
||||
gfloat event_x,
|
||||
gfloat event_y,
|
||||
ClutterModifierType modifiers);
|
||||
gboolean (* drag_progress) (ClutterDragAction *action,
|
||||
ClutterActor *actor,
|
||||
gfloat delta_x,
|
||||
gfloat delta_y);
|
||||
|
||||
/*< private >*/
|
||||
void (* _clutter_drag_action1) (void);
|
||||
void (* _clutter_drag_action2) (void);
|
||||
void (* _clutter_drag_action3) (void);
|
||||
void (* _clutter_drag_action4) (void);
|
||||
void (* _clutter_drag_action5) (void);
|
||||
};
|
||||
|
||||
GType clutter_drag_action_get_type (void) G_GNUC_CONST;
|
||||
|
Loading…
Reference in New Issue
Block a user