mirror of
https://github.com/brl/mutter.git
synced 2024-11-23 00:20:42 -05:00
drag/drop actions: add touch event support
https://bugzilla.gnome.org/show_bug.cgi?id=678049
This commit is contained in:
parent
1af7de8ac8
commit
132e4b98d1
@ -93,7 +93,9 @@ struct _ClutterDragActionPrivate
|
|||||||
ClutterDragAxis drag_axis;
|
ClutterDragAxis drag_axis;
|
||||||
|
|
||||||
ClutterInputDevice *device;
|
ClutterInputDevice *device;
|
||||||
|
ClutterEventSequence *sequence;
|
||||||
gulong button_press_id;
|
gulong button_press_id;
|
||||||
|
gulong touch_begin_id;
|
||||||
gulong capture_id;
|
gulong capture_id;
|
||||||
|
|
||||||
gfloat press_x;
|
gfloat press_x;
|
||||||
@ -183,11 +185,18 @@ emit_drag_begin (ClutterDragAction *action,
|
|||||||
if (priv->stage != NULL)
|
if (priv->stage != NULL)
|
||||||
{
|
{
|
||||||
clutter_stage_set_motion_events_enabled (priv->stage, FALSE);
|
clutter_stage_set_motion_events_enabled (priv->stage, FALSE);
|
||||||
_clutter_stage_add_drag_actor (priv->stage,
|
if (clutter_event_type (event) == CLUTTER_TOUCH_BEGIN)
|
||||||
clutter_event_get_device (event),
|
_clutter_stage_add_touch_drag_actor (priv->stage,
|
||||||
priv->drag_handle != NULL
|
clutter_event_get_event_sequence (event),
|
||||||
? priv->drag_handle
|
priv->drag_handle != NULL
|
||||||
: actor);
|
? priv->drag_handle
|
||||||
|
: actor);
|
||||||
|
else
|
||||||
|
_clutter_stage_add_pointer_drag_actor (priv->stage,
|
||||||
|
clutter_event_get_device (event),
|
||||||
|
priv->drag_handle != NULL
|
||||||
|
? priv->drag_handle
|
||||||
|
: actor);
|
||||||
}
|
}
|
||||||
|
|
||||||
g_signal_emit (action, drag_signals[DRAG_BEGIN], 0,
|
g_signal_emit (action, drag_signals[DRAG_BEGIN], 0,
|
||||||
@ -301,7 +310,16 @@ emit_drag_end (ClutterDragAction *action,
|
|||||||
priv->motion_events_enabled);
|
priv->motion_events_enabled);
|
||||||
|
|
||||||
if (priv->last_motion_device != NULL)
|
if (priv->last_motion_device != NULL)
|
||||||
_clutter_stage_remove_drag_actor (priv->stage, priv->last_motion_device);
|
{
|
||||||
|
if (clutter_event_type (event) == CLUTTER_BUTTON_RELEASE)
|
||||||
|
_clutter_stage_remove_pointer_drag_actor (priv->stage,
|
||||||
|
priv->last_motion_device);
|
||||||
|
else
|
||||||
|
_clutter_stage_remove_touch_drag_actor (priv->stage,
|
||||||
|
priv->sequence);
|
||||||
|
}
|
||||||
|
|
||||||
|
priv->sequence = NULL;
|
||||||
|
|
||||||
priv->in_drag = FALSE;
|
priv->in_drag = FALSE;
|
||||||
}
|
}
|
||||||
@ -313,7 +331,7 @@ on_captured_event (ClutterActor *stage,
|
|||||||
{
|
{
|
||||||
ClutterDragActionPrivate *priv = action->priv;
|
ClutterDragActionPrivate *priv = action->priv;
|
||||||
ClutterActor *actor;
|
ClutterActor *actor;
|
||||||
|
|
||||||
actor = clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (action));
|
actor = clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (action));
|
||||||
|
|
||||||
if (!priv->in_drag)
|
if (!priv->in_drag)
|
||||||
@ -324,6 +342,11 @@ on_captured_event (ClutterActor *stage,
|
|||||||
|
|
||||||
switch (clutter_event_type (event))
|
switch (clutter_event_type (event))
|
||||||
{
|
{
|
||||||
|
case CLUTTER_TOUCH_UPDATE:
|
||||||
|
if (clutter_event_get_event_sequence (event) == priv->sequence)
|
||||||
|
emit_drag_motion (action, actor, event);
|
||||||
|
break;
|
||||||
|
|
||||||
case CLUTTER_MOTION:
|
case CLUTTER_MOTION:
|
||||||
{
|
{
|
||||||
ClutterModifierType mods = clutter_event_get_state (event);
|
ClutterModifierType mods = clutter_event_get_state (event);
|
||||||
@ -339,6 +362,12 @@ on_captured_event (ClutterActor *stage,
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case CLUTTER_TOUCH_END:
|
||||||
|
case CLUTTER_TOUCH_CANCEL:
|
||||||
|
if (clutter_event_get_event_sequence (event) == priv->sequence)
|
||||||
|
emit_drag_end (action, actor, event);
|
||||||
|
break;
|
||||||
|
|
||||||
case CLUTTER_BUTTON_RELEASE:
|
case CLUTTER_BUTTON_RELEASE:
|
||||||
if (priv->in_drag)
|
if (priv->in_drag)
|
||||||
emit_drag_end (action, actor, event);
|
emit_drag_end (action, actor, event);
|
||||||
@ -358,9 +387,9 @@ on_captured_event (ClutterActor *stage,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
on_button_press (ClutterActor *actor,
|
on_drag_begin (ClutterActor *actor,
|
||||||
ClutterEvent *event,
|
ClutterEvent *event,
|
||||||
ClutterDragAction *action)
|
ClutterDragAction *action)
|
||||||
{
|
{
|
||||||
ClutterDragActionPrivate *priv = action->priv;
|
ClutterDragActionPrivate *priv = action->priv;
|
||||||
|
|
||||||
@ -368,8 +397,22 @@ on_button_press (ClutterActor *actor,
|
|||||||
return CLUTTER_EVENT_PROPAGATE;
|
return CLUTTER_EVENT_PROPAGATE;
|
||||||
|
|
||||||
/* dragging is only performed using the primary button */
|
/* dragging is only performed using the primary button */
|
||||||
if (clutter_event_get_button (event) != CLUTTER_BUTTON_PRIMARY)
|
switch (clutter_event_type (event))
|
||||||
return CLUTTER_EVENT_PROPAGATE;
|
{
|
||||||
|
case CLUTTER_BUTTON_PRESS:
|
||||||
|
if (clutter_event_get_button (event) != CLUTTER_BUTTON_PRIMARY)
|
||||||
|
return CLUTTER_EVENT_PROPAGATE;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CLUTTER_TOUCH_BEGIN:
|
||||||
|
if (priv->sequence != NULL)
|
||||||
|
return CLUTTER_EVENT_PROPAGATE;
|
||||||
|
priv->sequence = clutter_event_get_event_sequence (event);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return CLUTTER_EVENT_PROPAGATE;
|
||||||
|
}
|
||||||
|
|
||||||
if (priv->stage == NULL)
|
if (priv->stage == NULL)
|
||||||
priv->stage = CLUTTER_STAGE (clutter_actor_get_stage (actor));
|
priv->stage = CLUTTER_STAGE (clutter_actor_get_stage (actor));
|
||||||
@ -416,9 +459,13 @@ clutter_drag_action_set_actor (ClutterActorMeta *meta,
|
|||||||
|
|
||||||
old_actor = clutter_actor_meta_get_actor (meta);
|
old_actor = clutter_actor_meta_get_actor (meta);
|
||||||
if (old_actor != NULL)
|
if (old_actor != NULL)
|
||||||
g_signal_handler_disconnect (old_actor, priv->button_press_id);
|
{
|
||||||
|
g_signal_handler_disconnect (old_actor, priv->button_press_id);
|
||||||
|
g_signal_handler_disconnect (old_actor, priv->touch_begin_id);
|
||||||
|
}
|
||||||
|
|
||||||
priv->button_press_id = 0;
|
priv->button_press_id = 0;
|
||||||
|
priv->touch_begin_id = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (priv->capture_id != 0)
|
if (priv->capture_id != 0)
|
||||||
@ -435,9 +482,14 @@ clutter_drag_action_set_actor (ClutterActorMeta *meta,
|
|||||||
priv->in_drag = FALSE;
|
priv->in_drag = FALSE;
|
||||||
|
|
||||||
if (actor != NULL)
|
if (actor != NULL)
|
||||||
priv->button_press_id = g_signal_connect (actor, "button-press-event",
|
{
|
||||||
G_CALLBACK (on_button_press),
|
priv->button_press_id = g_signal_connect (actor, "button-press-event",
|
||||||
meta);
|
G_CALLBACK (on_drag_begin),
|
||||||
|
meta);
|
||||||
|
priv->touch_begin_id = g_signal_connect (actor, "touch-event",
|
||||||
|
G_CALLBACK (on_drag_begin),
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
@ -555,9 +607,13 @@ clutter_drag_action_dispose (GObject *gobject)
|
|||||||
|
|
||||||
actor = clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (gobject));
|
actor = clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (gobject));
|
||||||
if (actor != NULL)
|
if (actor != NULL)
|
||||||
g_signal_handler_disconnect (actor, priv->button_press_id);
|
{
|
||||||
|
g_signal_handler_disconnect (actor, priv->button_press_id);
|
||||||
|
g_signal_handler_disconnect (actor, priv->touch_begin_id);
|
||||||
|
}
|
||||||
|
|
||||||
priv->button_press_id = 0;
|
priv->button_press_id = 0;
|
||||||
|
priv->touch_begin_id = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
clutter_drag_action_set_drag_handle (CLUTTER_DRAG_ACTION (gobject), NULL);
|
clutter_drag_action_set_drag_handle (CLUTTER_DRAG_ACTION (gobject), NULL);
|
||||||
|
@ -127,24 +127,40 @@ on_stage_capture (ClutterStage *stage,
|
|||||||
{
|
{
|
||||||
DropTarget *data = user_data;
|
DropTarget *data = user_data;
|
||||||
gfloat event_x, event_y;
|
gfloat event_x, event_y;
|
||||||
ClutterInputDevice *device;
|
|
||||||
ClutterActor *actor, *drag_actor;
|
ClutterActor *actor, *drag_actor;
|
||||||
ClutterDropAction *drop_action;
|
ClutterDropAction *drop_action;
|
||||||
gboolean was_reactive;
|
gboolean was_reactive;
|
||||||
|
|
||||||
if (!(clutter_event_type (event) == CLUTTER_MOTION ||
|
switch (clutter_event_type (event))
|
||||||
clutter_event_type (event) == CLUTTER_BUTTON_RELEASE))
|
{
|
||||||
return CLUTTER_EVENT_PROPAGATE;
|
case CLUTTER_MOTION:
|
||||||
|
case CLUTTER_BUTTON_RELEASE:
|
||||||
|
{
|
||||||
|
ClutterInputDevice *device;
|
||||||
|
|
||||||
if (!(clutter_event_get_state (event) & CLUTTER_BUTTON1_MASK))
|
if (!(clutter_event_get_state (event) & CLUTTER_BUTTON1_MASK))
|
||||||
return CLUTTER_EVENT_PROPAGATE;
|
return CLUTTER_EVENT_PROPAGATE;
|
||||||
|
|
||||||
|
device = clutter_event_get_device (event);
|
||||||
|
drag_actor = _clutter_stage_get_pointer_drag_actor (stage, device);
|
||||||
|
if (drag_actor == NULL)
|
||||||
|
return CLUTTER_EVENT_PROPAGATE;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CLUTTER_TOUCH_UPDATE:
|
||||||
|
case CLUTTER_TOUCH_END:
|
||||||
|
drag_actor = _clutter_stage_get_touch_drag_actor (stage,
|
||||||
|
clutter_event_get_event_sequence (event));
|
||||||
|
if (drag_actor == NULL)
|
||||||
|
return CLUTTER_EVENT_PROPAGATE;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return CLUTTER_EVENT_PROPAGATE;
|
||||||
|
}
|
||||||
|
|
||||||
clutter_event_get_coords (event, &event_x, &event_y);
|
clutter_event_get_coords (event, &event_x, &event_y);
|
||||||
device = clutter_event_get_device (event);
|
|
||||||
|
|
||||||
drag_actor = _clutter_stage_get_drag_actor (stage, device);
|
|
||||||
if (drag_actor == NULL)
|
|
||||||
return CLUTTER_EVENT_PROPAGATE;
|
|
||||||
|
|
||||||
/* get the actor under the cursor, excluding the dragged actor; we
|
/* get the actor under the cursor, excluding the dragged actor; we
|
||||||
* use reactivity because it won't cause any scene invalidation
|
* use reactivity because it won't cause any scene invalidation
|
||||||
@ -210,7 +226,8 @@ on_stage_capture (ClutterStage *stage,
|
|||||||
}
|
}
|
||||||
|
|
||||||
out:
|
out:
|
||||||
if (clutter_event_type (event) == CLUTTER_BUTTON_RELEASE)
|
if (clutter_event_type (event) == CLUTTER_BUTTON_RELEASE ||
|
||||||
|
clutter_event_type (event) == CLUTTER_TOUCH_END)
|
||||||
{
|
{
|
||||||
if (data->last_action != NULL)
|
if (data->last_action != NULL)
|
||||||
{
|
{
|
||||||
|
@ -101,13 +101,21 @@ void _clutter_stage_release_pick_id (ClutterStage *stage,
|
|||||||
ClutterActor * _clutter_stage_get_actor_by_pick_id (ClutterStage *stage,
|
ClutterActor * _clutter_stage_get_actor_by_pick_id (ClutterStage *stage,
|
||||||
gint32 pick_id);
|
gint32 pick_id);
|
||||||
|
|
||||||
void _clutter_stage_add_drag_actor (ClutterStage *stage,
|
void _clutter_stage_add_pointer_drag_actor (ClutterStage *stage,
|
||||||
ClutterInputDevice *device,
|
ClutterInputDevice *device,
|
||||||
ClutterActor *actor);
|
ClutterActor *actor);
|
||||||
ClutterActor * _clutter_stage_get_drag_actor (ClutterStage *stage,
|
ClutterActor * _clutter_stage_get_pointer_drag_actor (ClutterStage *stage,
|
||||||
ClutterInputDevice *device);
|
ClutterInputDevice *device);
|
||||||
void _clutter_stage_remove_drag_actor (ClutterStage *stage,
|
void _clutter_stage_remove_pointer_drag_actor (ClutterStage *stage,
|
||||||
ClutterInputDevice *device);
|
ClutterInputDevice *device);
|
||||||
|
|
||||||
|
void _clutter_stage_add_touch_drag_actor (ClutterStage *stage,
|
||||||
|
ClutterEventSequence *sequence,
|
||||||
|
ClutterActor *actor);
|
||||||
|
ClutterActor * _clutter_stage_get_touch_drag_actor (ClutterStage *stage,
|
||||||
|
ClutterEventSequence *sequence);
|
||||||
|
void _clutter_stage_remove_touch_drag_actor (ClutterStage *stage,
|
||||||
|
ClutterEventSequence *sequence);
|
||||||
|
|
||||||
ClutterStageState _clutter_stage_get_state (ClutterStage *stage);
|
ClutterStageState _clutter_stage_get_state (ClutterStage *stage);
|
||||||
gboolean _clutter_stage_is_activated (ClutterStage *stage);
|
gboolean _clutter_stage_is_activated (ClutterStage *stage);
|
||||||
|
@ -4299,17 +4299,19 @@ _clutter_stage_get_actor_by_pick_id (ClutterStage *stage,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
_clutter_stage_add_drag_actor (ClutterStage *stage,
|
_clutter_stage_add_pointer_drag_actor (ClutterStage *stage,
|
||||||
ClutterInputDevice *device,
|
ClutterInputDevice *device,
|
||||||
ClutterActor *actor)
|
ClutterActor *actor)
|
||||||
{
|
{
|
||||||
GHashTable *drag_actors;
|
GHashTable *drag_actors;
|
||||||
|
|
||||||
drag_actors = g_object_get_data (G_OBJECT (stage), "__clutter_stage_drag_actors");
|
drag_actors = g_object_get_data (G_OBJECT (stage),
|
||||||
|
"__clutter_stage_pointer_drag_actors");
|
||||||
if (drag_actors == NULL)
|
if (drag_actors == NULL)
|
||||||
{
|
{
|
||||||
drag_actors = g_hash_table_new (NULL, NULL);
|
drag_actors = g_hash_table_new (NULL, NULL);
|
||||||
g_object_set_data_full (G_OBJECT (stage), "__clutter_stage_drag_actors",
|
g_object_set_data_full (G_OBJECT (stage),
|
||||||
|
"__clutter_stage_pointer_drag_actors",
|
||||||
drag_actors,
|
drag_actors,
|
||||||
(GDestroyNotify) g_hash_table_destroy);
|
(GDestroyNotify) g_hash_table_destroy);
|
||||||
}
|
}
|
||||||
@ -4318,12 +4320,13 @@ _clutter_stage_add_drag_actor (ClutterStage *stage,
|
|||||||
}
|
}
|
||||||
|
|
||||||
ClutterActor *
|
ClutterActor *
|
||||||
_clutter_stage_get_drag_actor (ClutterStage *stage,
|
_clutter_stage_get_pointer_drag_actor (ClutterStage *stage,
|
||||||
ClutterInputDevice *device)
|
ClutterInputDevice *device)
|
||||||
{
|
{
|
||||||
GHashTable *drag_actors;
|
GHashTable *drag_actors;
|
||||||
|
|
||||||
drag_actors = g_object_get_data (G_OBJECT (stage), "__clutter_stage_drag_actors");
|
drag_actors = g_object_get_data (G_OBJECT (stage),
|
||||||
|
"__clutter_stage_pointer_drag_actors");
|
||||||
if (drag_actors == NULL)
|
if (drag_actors == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
@ -4331,19 +4334,76 @@ _clutter_stage_get_drag_actor (ClutterStage *stage,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
_clutter_stage_remove_drag_actor (ClutterStage *stage,
|
_clutter_stage_remove_pointer_drag_actor (ClutterStage *stage,
|
||||||
ClutterInputDevice *device)
|
ClutterInputDevice *device)
|
||||||
{
|
{
|
||||||
GHashTable *drag_actors;
|
GHashTable *drag_actors;
|
||||||
|
|
||||||
drag_actors = g_object_get_data (G_OBJECT (stage), "__clutter_stage_drag_actors");
|
drag_actors = g_object_get_data (G_OBJECT (stage),
|
||||||
|
"__clutter_stage_pointer_drag_actors");
|
||||||
if (drag_actors == NULL)
|
if (drag_actors == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
g_hash_table_remove (drag_actors, device);
|
g_hash_table_remove (drag_actors, device);
|
||||||
|
|
||||||
if (g_hash_table_size (drag_actors) == 0)
|
if (g_hash_table_size (drag_actors) == 0)
|
||||||
g_object_set_data (G_OBJECT (stage), "__clutter_stage_drag_actors", NULL);
|
g_object_set_data (G_OBJECT (stage),
|
||||||
|
"__clutter_stage_pointer_drag_actors",
|
||||||
|
NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
_clutter_stage_add_touch_drag_actor (ClutterStage *stage,
|
||||||
|
ClutterEventSequence *sequence,
|
||||||
|
ClutterActor *actor)
|
||||||
|
{
|
||||||
|
GHashTable *drag_actors;
|
||||||
|
|
||||||
|
drag_actors = g_object_get_data (G_OBJECT (stage),
|
||||||
|
"__clutter_stage_touch_drag_actors");
|
||||||
|
if (drag_actors == NULL)
|
||||||
|
{
|
||||||
|
drag_actors = g_hash_table_new (NULL, NULL);
|
||||||
|
g_object_set_data_full (G_OBJECT (stage),
|
||||||
|
"__clutter_stage_touch_drag_actors",
|
||||||
|
drag_actors,
|
||||||
|
(GDestroyNotify) g_hash_table_destroy);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_hash_table_replace (drag_actors, sequence, actor);
|
||||||
|
}
|
||||||
|
|
||||||
|
ClutterActor *
|
||||||
|
_clutter_stage_get_touch_drag_actor (ClutterStage *stage,
|
||||||
|
ClutterEventSequence *sequence)
|
||||||
|
{
|
||||||
|
GHashTable *drag_actors;
|
||||||
|
|
||||||
|
drag_actors = g_object_get_data (G_OBJECT (stage),
|
||||||
|
"__clutter_stage_touch_drag_actors");
|
||||||
|
if (drag_actors == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
return g_hash_table_lookup (drag_actors, sequence);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
_clutter_stage_remove_touch_drag_actor (ClutterStage *stage,
|
||||||
|
ClutterEventSequence *sequence)
|
||||||
|
{
|
||||||
|
GHashTable *drag_actors;
|
||||||
|
|
||||||
|
drag_actors = g_object_get_data (G_OBJECT (stage),
|
||||||
|
"__clutter_stage_touch_drag_actors");
|
||||||
|
if (drag_actors == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
g_hash_table_remove (drag_actors, sequence);
|
||||||
|
|
||||||
|
if (g_hash_table_size (drag_actors) == 0)
|
||||||
|
g_object_set_data (G_OBJECT (stage),
|
||||||
|
"__clutter_stage_touch_drag_actors",
|
||||||
|
NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*< private >
|
/*< private >
|
||||||
|
Loading…
Reference in New Issue
Block a user