diff --git a/clutter/clutter-drag-action.c b/clutter/clutter-drag-action.c index cd25ecd69..c89fd7959 100644 --- a/clutter/clutter-drag-action.c +++ b/clutter/clutter-drag-action.c @@ -93,7 +93,9 @@ struct _ClutterDragActionPrivate ClutterDragAxis drag_axis; ClutterInputDevice *device; + ClutterEventSequence *sequence; gulong button_press_id; + gulong touch_begin_id; gulong capture_id; gfloat press_x; @@ -183,11 +185,18 @@ emit_drag_begin (ClutterDragAction *action, if (priv->stage != NULL) { clutter_stage_set_motion_events_enabled (priv->stage, FALSE); - _clutter_stage_add_drag_actor (priv->stage, - clutter_event_get_device (event), - priv->drag_handle != NULL - ? priv->drag_handle - : actor); + if (clutter_event_type (event) == CLUTTER_TOUCH_BEGIN) + _clutter_stage_add_touch_drag_actor (priv->stage, + clutter_event_get_event_sequence (event), + priv->drag_handle != NULL + ? 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, @@ -301,7 +310,16 @@ emit_drag_end (ClutterDragAction *action, priv->motion_events_enabled); 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; } @@ -313,7 +331,7 @@ on_captured_event (ClutterActor *stage, { ClutterDragActionPrivate *priv = action->priv; ClutterActor *actor; - + actor = clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (action)); if (!priv->in_drag) @@ -324,6 +342,11 @@ on_captured_event (ClutterActor *stage, 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: { ClutterModifierType mods = clutter_event_get_state (event); @@ -339,6 +362,12 @@ on_captured_event (ClutterActor *stage, } 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: if (priv->in_drag) emit_drag_end (action, actor, event); @@ -358,9 +387,9 @@ on_captured_event (ClutterActor *stage, } static gboolean -on_button_press (ClutterActor *actor, - ClutterEvent *event, - ClutterDragAction *action) +on_drag_begin (ClutterActor *actor, + ClutterEvent *event, + ClutterDragAction *action) { ClutterDragActionPrivate *priv = action->priv; @@ -368,8 +397,22 @@ on_button_press (ClutterActor *actor, return CLUTTER_EVENT_PROPAGATE; /* dragging is only performed using the primary button */ - if (clutter_event_get_button (event) != CLUTTER_BUTTON_PRIMARY) - return CLUTTER_EVENT_PROPAGATE; + switch (clutter_event_type (event)) + { + 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) 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); 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->touch_begin_id = 0; } if (priv->capture_id != 0) @@ -435,9 +482,14 @@ clutter_drag_action_set_actor (ClutterActorMeta *meta, priv->in_drag = FALSE; if (actor != NULL) - priv->button_press_id = g_signal_connect (actor, "button-press-event", - G_CALLBACK (on_button_press), - meta); + { + priv->button_press_id = g_signal_connect (actor, "button-press-event", + 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); } @@ -555,9 +607,13 @@ clutter_drag_action_dispose (GObject *gobject) actor = clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (gobject)); 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->touch_begin_id = 0; } clutter_drag_action_set_drag_handle (CLUTTER_DRAG_ACTION (gobject), NULL); diff --git a/clutter/clutter-drop-action.c b/clutter/clutter-drop-action.c index 8c4def2ad..adf6aeb9f 100644 --- a/clutter/clutter-drop-action.c +++ b/clutter/clutter-drop-action.c @@ -127,24 +127,40 @@ on_stage_capture (ClutterStage *stage, { DropTarget *data = user_data; gfloat event_x, event_y; - ClutterInputDevice *device; ClutterActor *actor, *drag_actor; ClutterDropAction *drop_action; gboolean was_reactive; - if (!(clutter_event_type (event) == CLUTTER_MOTION || - clutter_event_type (event) == CLUTTER_BUTTON_RELEASE)) - return CLUTTER_EVENT_PROPAGATE; + switch (clutter_event_type (event)) + { + case CLUTTER_MOTION: + case CLUTTER_BUTTON_RELEASE: + { + ClutterInputDevice *device; - if (!(clutter_event_get_state (event) & CLUTTER_BUTTON1_MASK)) - return CLUTTER_EVENT_PROPAGATE; + if (!(clutter_event_get_state (event) & CLUTTER_BUTTON1_MASK)) + 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); - 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 * use reactivity because it won't cause any scene invalidation @@ -210,7 +226,8 @@ on_stage_capture (ClutterStage *stage, } 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) { diff --git a/clutter/clutter-stage-private.h b/clutter/clutter-stage-private.h index d2c7f7845..739046ed3 100644 --- a/clutter/clutter-stage-private.h +++ b/clutter/clutter-stage-private.h @@ -101,13 +101,21 @@ void _clutter_stage_release_pick_id (ClutterStage *stage, ClutterActor * _clutter_stage_get_actor_by_pick_id (ClutterStage *stage, gint32 pick_id); -void _clutter_stage_add_drag_actor (ClutterStage *stage, - ClutterInputDevice *device, - ClutterActor *actor); -ClutterActor * _clutter_stage_get_drag_actor (ClutterStage *stage, - ClutterInputDevice *device); -void _clutter_stage_remove_drag_actor (ClutterStage *stage, - ClutterInputDevice *device); +void _clutter_stage_add_pointer_drag_actor (ClutterStage *stage, + ClutterInputDevice *device, + ClutterActor *actor); +ClutterActor * _clutter_stage_get_pointer_drag_actor (ClutterStage *stage, + ClutterInputDevice *device); +void _clutter_stage_remove_pointer_drag_actor (ClutterStage *stage, + 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); gboolean _clutter_stage_is_activated (ClutterStage *stage); diff --git a/clutter/clutter-stage.c b/clutter/clutter-stage.c index 8d01214d3..bf8a32fe8 100644 --- a/clutter/clutter-stage.c +++ b/clutter/clutter-stage.c @@ -4299,17 +4299,19 @@ _clutter_stage_get_actor_by_pick_id (ClutterStage *stage, } void -_clutter_stage_add_drag_actor (ClutterStage *stage, - ClutterInputDevice *device, - ClutterActor *actor) +_clutter_stage_add_pointer_drag_actor (ClutterStage *stage, + ClutterInputDevice *device, + ClutterActor *actor) { 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) { 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, (GDestroyNotify) g_hash_table_destroy); } @@ -4318,12 +4320,13 @@ _clutter_stage_add_drag_actor (ClutterStage *stage, } ClutterActor * -_clutter_stage_get_drag_actor (ClutterStage *stage, - ClutterInputDevice *device) +_clutter_stage_get_pointer_drag_actor (ClutterStage *stage, + ClutterInputDevice *device) { 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) return NULL; @@ -4331,19 +4334,76 @@ _clutter_stage_get_drag_actor (ClutterStage *stage, } void -_clutter_stage_remove_drag_actor (ClutterStage *stage, - ClutterInputDevice *device) +_clutter_stage_remove_pointer_drag_actor (ClutterStage *stage, + ClutterInputDevice *device) { 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) return; g_hash_table_remove (drag_actors, device); 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 >