diff --git a/clutter/clutter/clutter-autocleanups.h b/clutter/clutter/clutter-autocleanups.h index 8e17d002e..ef50a9048 100644 --- a/clutter/clutter/clutter-autocleanups.h +++ b/clutter/clutter/clutter-autocleanups.h @@ -50,8 +50,6 @@ G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterConstraint, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterContainer, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterDeformEffect, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterDesaturateEffect, g_object_unref) -G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterDragAction, g_object_unref) -G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterDropAction, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterEffect, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterFixedLayout, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterFlowLayout, g_object_unref) diff --git a/clutter/clutter/clutter-drag-action.c b/clutter/clutter/clutter-drag-action.c deleted file mode 100644 index 162ebb3d4..000000000 --- a/clutter/clutter/clutter-drag-action.c +++ /dev/null @@ -1,1316 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright (C) 2010 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * Author: - * Emmanuele Bassi - */ - -/** - * SECTION:clutter-drag-action - * @Title: ClutterDragAction - * @Short_Description: Action enabling dragging on actors - * - * #ClutterDragAction is a sub-class of #ClutterAction that implements - * all the necessary logic for dragging actors. - * - * The simplest usage of #ClutterDragAction consists in adding it to - * a #ClutterActor and setting it as reactive; for instance, the following - * code: - * - * |[ - * clutter_actor_add_action (actor, clutter_drag_action_new ()); - * clutter_actor_set_reactive (actor, TRUE); - * ]| - * - * will automatically result in the actor moving to follow the pointer - * whenever the pointer's button is pressed over the actor and moved - * across the stage. - * - * The #ClutterDragAction will signal the begin and the end of a dragging - * through the #ClutterDragAction::drag-begin and #ClutterDragAction::drag-end - * signals, respectively. Each pointer motion during a drag will also result - * in the #ClutterDragAction::drag-motion signal to be emitted. - * - * It is also possible to set another #ClutterActor as the dragged actor - * by calling clutter_drag_action_set_drag_handle() from within a handle - * of the #ClutterDragAction::drag-begin signal. The drag handle must be - * parented and exist between the emission of #ClutterDragAction::drag-begin - * and #ClutterDragAction::drag-end. - * - * The [drag-action example](https://git.gnome.org/browse/clutter/tree/examples/drag-action.c?h=clutter-1.18) - * allows dragging the rectangle around the stage using a #ClutterDragAction. - * When pressing the `Shift` key the actor that is being dragged will be a - * separate rectangle, and when the drag ends, the original rectangle will be - * animated to the final drop coordinates. - * - * #ClutterDragAction is available since Clutter 1.4 - */ - -#include "clutter-build-config.h" - -#include "clutter-drag-action.h" - -#include "clutter-debug.h" -#include "clutter-enum-types.h" -#include "clutter-marshal.h" -#include "clutter-private.h" -#include "clutter-stage-private.h" - -struct _ClutterDragActionPrivate -{ - ClutterStage *stage; - - gint x_drag_threshold; - gint y_drag_threshold; - ClutterActor *drag_handle; - ClutterDragAxis drag_axis; - graphene_rect_t drag_area; - - ClutterInputDevice *device; - ClutterEventSequence *sequence; - gulong button_press_id; - gulong touch_begin_id; - gulong capture_id; - - gfloat press_x; - gfloat press_y; - ClutterModifierType press_state; - - gfloat last_motion_x; - gfloat last_motion_y; - ClutterModifierType last_motion_state; - ClutterInputDevice *last_motion_device; - - gfloat transformed_press_x; - gfloat transformed_press_y; - - guint emit_delayed_press : 1; - guint in_drag : 1; - guint motion_events_enabled : 1; - guint drag_area_set : 1; -}; - -enum -{ - PROP_0, - - PROP_X_DRAG_THRESHOLD, - PROP_Y_DRAG_THRESHOLD, - PROP_DRAG_HANDLE, - PROP_DRAG_AXIS, - PROP_DRAG_AREA, - PROP_DRAG_AREA_SET, - - PROP_LAST -}; - -static GParamSpec *drag_props[PROP_LAST] = { NULL, }; - -enum -{ - DRAG_BEGIN, - DRAG_PROGRESS, - DRAG_MOTION, - DRAG_END, - - LAST_SIGNAL -}; - -static guint drag_signals[LAST_SIGNAL] = { 0, }; - -/* forward declaration */ -static gboolean on_captured_event (ClutterActor *stage, - ClutterEvent *event, - ClutterDragAction *action); - -G_DEFINE_TYPE_WITH_PRIVATE (ClutterDragAction, clutter_drag_action, CLUTTER_TYPE_ACTION) - -static void -get_drag_threshold (ClutterDragAction *action, - gint *x_threshold, - gint *y_threshold) -{ - ClutterDragActionPrivate *priv = action->priv; - ClutterSettings *settings = clutter_settings_get_default (); - gint x_res, y_res, default_threshold; - - g_object_get (settings, "dnd-drag-threshold", &default_threshold, NULL); - - if (priv->x_drag_threshold < 0) - x_res = default_threshold; - else - x_res = priv->x_drag_threshold; - - if (priv->y_drag_threshold < 0) - y_res = default_threshold; - else - y_res = priv->y_drag_threshold; - - if (x_threshold != NULL) - *x_threshold = x_res; - - if (y_threshold != NULL) - *y_threshold = y_res; -} - -static void -emit_drag_begin (ClutterDragAction *action, - ClutterActor *actor, - ClutterEvent *event) -{ - ClutterDragActionPrivate *priv = action->priv; - - if (priv->stage != NULL) - { - clutter_stage_set_motion_events_enabled (priv->stage, FALSE); - 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, - actor, - priv->press_x, priv->press_y, - priv->press_state); -} - -static void -emit_drag_motion (ClutterDragAction *action, - ClutterActor *actor, - ClutterEvent *event) -{ - ClutterDragActionPrivate *priv = action->priv; - 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); - priv->last_motion_device = clutter_event_get_device (event); - - if (priv->drag_handle != NULL && !priv->emit_delayed_press) - drag_handle = priv->drag_handle; - else - drag_handle = actor; - - motion_x = motion_y = 0.0f; - clutter_actor_transform_stage_point (drag_handle, - priv->last_motion_x, - priv->last_motion_y, - &motion_x, &motion_y); - - delta_x = delta_y = 0.0f; - - switch (priv->drag_axis) - { - case CLUTTER_DRAG_AXIS_NONE: - delta_x = motion_x - priv->transformed_press_x; - delta_y = motion_y - priv->transformed_press_y; - break; - - case CLUTTER_DRAG_X_AXIS: - delta_x = motion_x - priv->transformed_press_x; - break; - - case CLUTTER_DRAG_Y_AXIS: - delta_y = motion_y - priv->transformed_press_y; - break; - - default: - g_assert_not_reached (); - return; - } - - if (priv->emit_delayed_press) - { - gint x_drag_threshold, y_drag_threshold; - - get_drag_threshold (action, &x_drag_threshold, &y_drag_threshold); - - if (ABS (delta_x) >= x_drag_threshold || - ABS (delta_y) >= y_drag_threshold) - { - priv->emit_delayed_press = FALSE; - - emit_drag_begin (action, actor, event); - } - else - return; - } - - g_signal_emit (action, drag_signals[DRAG_PROGRESS], 0, - actor, - 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 -emit_drag_end (ClutterDragAction *action, - ClutterActor *actor, - ClutterEvent *event) -{ - ClutterDragActionPrivate *priv = action->priv; - - /* ::drag-end may result in the destruction of the actor, which in turn - * will lead to the removal and finalization of the action, so we need - * to keep the action alive for the entire emission sequence - */ - g_object_ref (action); - - /* if we have an event, update our own state, otherwise we'll - * just use the currently stored state when emitting the ::drag-end - * signal - */ - if (event != NULL) - { - 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_device = clutter_event_get_device (event); - } - - priv->in_drag = FALSE; - - /* we might not have emitted ::drag-begin yet */ - if (!priv->emit_delayed_press) - g_signal_emit (action, drag_signals[DRAG_END], 0, - actor, - priv->last_motion_x, priv->last_motion_y, - priv->last_motion_state); - - if (priv->stage == NULL) - goto out; - - /* disconnect the capture */ - g_clear_signal_handler (&priv->capture_id, priv->stage); - - clutter_stage_set_motion_events_enabled (priv->stage, - priv->motion_events_enabled); - - if (priv->last_motion_device != NULL && event != NULL) - { - 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); - } - -out: - priv->last_motion_device = NULL; - priv->sequence = NULL; - - g_object_unref (action); -} - -static gboolean -on_captured_event (ClutterActor *stage, - ClutterEvent *event, - ClutterDragAction *action) -{ - ClutterDragActionPrivate *priv = action->priv; - ClutterActor *actor; - - actor = clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (action)); - - if (!priv->in_drag) - return CLUTTER_EVENT_PROPAGATE; - - if (clutter_event_get_device (event) != priv->device || - clutter_event_get_event_sequence (event) != priv->sequence) - return CLUTTER_EVENT_PROPAGATE; - - switch (clutter_event_type (event)) - { - case CLUTTER_TOUCH_UPDATE: - emit_drag_motion (action, actor, event); - break; - - case CLUTTER_MOTION: - { - ClutterModifierType mods = clutter_event_get_state (event); - - /* we might miss a button-release event in case of grabs, - * so we need to check whether the button is still down - * during a motion event - */ - if (mods & CLUTTER_BUTTON1_MASK) - emit_drag_motion (action, actor, event); - else - emit_drag_end (action, actor, event); - } - break; - - case CLUTTER_TOUCH_END: - case CLUTTER_TOUCH_CANCEL: - emit_drag_end (action, actor, event); - break; - - case CLUTTER_BUTTON_RELEASE: - if (priv->in_drag) - emit_drag_end (action, actor, event); - break; - - case CLUTTER_ENTER: - case CLUTTER_LEAVE: - if (priv->in_drag) - return CLUTTER_EVENT_STOP; - break; - - default: - break; - } - - return CLUTTER_EVENT_PROPAGATE; -} - -static gboolean -on_drag_begin (ClutterActor *actor, - ClutterEvent *event, - ClutterDragAction *action) -{ - ClutterDragActionPrivate *priv = action->priv; - - if (!clutter_actor_meta_get_enabled (CLUTTER_ACTOR_META (action))) - return CLUTTER_EVENT_PROPAGATE; - - /* dragging is only performed using the primary button */ - switch (clutter_event_type (event)) - { - case CLUTTER_BUTTON_PRESS: - if (priv->sequence != NULL) - return CLUTTER_EVENT_PROPAGATE; - 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)); - - clutter_event_get_coords (event, &priv->press_x, &priv->press_y); - priv->press_state = clutter_event_get_state (event); - - priv->device = clutter_event_get_device (event); - - priv->last_motion_x = priv->press_x; - priv->last_motion_y = priv->press_y; - - priv->transformed_press_x = priv->press_x; - priv->transformed_press_y = priv->press_y; - clutter_actor_transform_stage_point (actor, priv->press_x, priv->press_y, - &priv->transformed_press_x, - &priv->transformed_press_y); - - priv->motion_events_enabled = - clutter_stage_get_motion_events_enabled (priv->stage); - - if (priv->x_drag_threshold == 0 || priv->y_drag_threshold == 0) - emit_drag_begin (action, actor, event); - else - priv->emit_delayed_press = TRUE; - - priv->in_drag = TRUE; - priv->capture_id = g_signal_connect_after (priv->stage, "captured-event", - G_CALLBACK (on_captured_event), - action); - - return CLUTTER_EVENT_PROPAGATE; -} - -static void -clutter_drag_action_set_actor (ClutterActorMeta *meta, - ClutterActor *actor) -{ - ClutterDragActionPrivate *priv = CLUTTER_DRAG_ACTION (meta)->priv; - - if (priv->button_press_id != 0) - { - ClutterActor *old_actor; - - old_actor = clutter_actor_meta_get_actor (meta); - if (old_actor != NULL) - { - g_clear_signal_handler (&priv->button_press_id, old_actor); - g_clear_signal_handler (&priv->touch_begin_id, old_actor); - } - - priv->button_press_id = 0; - priv->touch_begin_id = 0; - } - - if (priv->capture_id != 0) - { - if (priv->stage != NULL) - g_clear_signal_handler (&priv->capture_id, priv->stage); - - priv->capture_id = 0; - priv->stage = NULL; - } - - clutter_drag_action_set_drag_handle (CLUTTER_DRAG_ACTION (meta), NULL); - - priv->in_drag = FALSE; - - if (actor != NULL) - { - 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); -} - -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, - gfloat delta_x, - gfloat delta_y) -{ - ClutterActor *drag_handle; - gfloat x, y; - - if (action->priv->drag_handle != NULL) - drag_handle = action->priv->drag_handle; - else - drag_handle = actor; - - clutter_actor_get_position (drag_handle, &x, &y); - - x += delta_x; - y += delta_y; - - if (action->priv->drag_area_set) - { - graphene_rect_t *drag_area = &action->priv->drag_area; - - x = CLAMP (x, drag_area->origin.x, drag_area->origin.x + drag_area->size.width); - y = CLAMP (y, drag_area->origin.y, drag_area->origin.y + drag_area->size.height); - } - - clutter_actor_set_position (drag_handle, x, y); -} - -static void -clutter_drag_action_set_property (GObject *gobject, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - ClutterDragAction *action = CLUTTER_DRAG_ACTION (gobject); - ClutterDragActionPrivate *priv = action->priv; - - switch (prop_id) - { - case PROP_X_DRAG_THRESHOLD: - clutter_drag_action_set_drag_threshold (action, - g_value_get_int (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_int (value)); - break; - - case PROP_DRAG_HANDLE: - clutter_drag_action_set_drag_handle (action, g_value_get_object (value)); - break; - - case PROP_DRAG_AXIS: - clutter_drag_action_set_drag_axis (action, g_value_get_enum (value)); - break; - - case PROP_DRAG_AREA: - clutter_drag_action_set_drag_area (action, g_value_get_boxed (value)); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); - } -} - -static void -clutter_drag_action_get_property (GObject *gobject, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - ClutterDragActionPrivate *priv = CLUTTER_DRAG_ACTION (gobject)->priv; - - switch (prop_id) - { - case PROP_X_DRAG_THRESHOLD: - { - gint threshold; - - get_drag_threshold (CLUTTER_DRAG_ACTION (gobject), &threshold, NULL); - g_value_set_int (value, threshold); - } - break; - - case PROP_Y_DRAG_THRESHOLD: - { - gint threshold; - - get_drag_threshold (CLUTTER_DRAG_ACTION (gobject), NULL, &threshold); - g_value_set_int (value, threshold); - } - break; - - case PROP_DRAG_HANDLE: - g_value_set_object (value, priv->drag_handle); - break; - - case PROP_DRAG_AXIS: - g_value_set_enum (value, priv->drag_axis); - break; - - case PROP_DRAG_AREA: - g_value_set_boxed (value, &priv->drag_area); - break; - - case PROP_DRAG_AREA_SET: - g_value_set_boolean (value, priv->drag_area_set); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); - } -} - -static void -clutter_drag_action_dispose (GObject *gobject) -{ - ClutterDragActionPrivate *priv = CLUTTER_DRAG_ACTION (gobject)->priv; - - /* if we're being disposed while a capture is still present, we - * need to reset the state we are currently holding - */ - if (priv->last_motion_device != NULL) - { - _clutter_stage_remove_pointer_drag_actor (priv->stage, - priv->last_motion_device); - priv->last_motion_device = NULL; - } - - if (priv->sequence != NULL) - { - _clutter_stage_remove_touch_drag_actor (priv->stage, - priv->sequence); - priv->sequence = NULL; - } - - if (priv->capture_id != 0) - { - clutter_stage_set_motion_events_enabled (priv->stage, - priv->motion_events_enabled); - - if (priv->stage != NULL) - g_clear_signal_handler (&priv->capture_id, priv->stage); - - priv->capture_id = 0; - priv->stage = NULL; - } - - if (priv->button_press_id != 0) - { - ClutterActor *actor; - - actor = clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (gobject)); - if (actor != NULL) - { - g_clear_signal_handler (&priv->button_press_id, actor); - g_clear_signal_handler (&priv->touch_begin_id, actor); - } - - 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_area (CLUTTER_DRAG_ACTION (gobject), NULL); - - G_OBJECT_CLASS (clutter_drag_action_parent_class)->dispose (gobject); -} - -static void -clutter_drag_action_class_init (ClutterDragActionClass *klass) -{ - ClutterActorMetaClass *meta_class = CLUTTER_ACTOR_META_CLASS (klass); - GObjectClass *gobject_class = G_OBJECT_CLASS (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; - - /** - * ClutterDragAction:x-drag-threshold: - * - * The horizontal threshold, in pixels, that the cursor must travel - * in order to begin a drag action. - * - * When set to a positive 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. - * - * When set to -1, #ClutterDragAction will use the default threshold - * stored in the #ClutterSettings:dnd-drag-threshold property of - * #ClutterSettings. - * - * When read, this property will always return a valid drag - * threshold, either as set or the default one. - * - * Since: 1.4 - */ - drag_props[PROP_X_DRAG_THRESHOLD] = - g_param_spec_int ("x-drag-threshold", - P_("Horizontal Drag Threshold"), - P_("The horizontal amount of pixels required to start dragging"), - -1, G_MAXINT, - 0, - CLUTTER_PARAM_READWRITE); - - /** - * ClutterDragAction:y-drag-threshold: - * - * The vertical threshold, in pixels, that the cursor must travel - * in order to begin a drag action. - * - * When set to a positive value, #ClutterDragAction will only emit - * #ClutterDragAction::drag-begin if the pointer has moved - * vertically at least of the given amount of pixels since - * the button press event. - * - * When set to -1, #ClutterDragAction will use the value stored - * in the #ClutterSettings:dnd-drag-threshold property of - * #ClutterSettings. - * - * When read, this property will always return a valid drag - * threshold, either as set or the default one. - * - * Since: 1.4 - */ - drag_props[PROP_Y_DRAG_THRESHOLD] = - g_param_spec_int ("y-drag-threshold", - P_("Vertical Drag Threshold"), - P_("The vertical amount of pixels required to start dragging"), - -1, G_MAXINT, - 0, - CLUTTER_PARAM_READWRITE); - - /** - * ClutterDragAction:drag-handle: - * - * The #ClutterActor that is effectively being dragged - * - * A #ClutterDragAction will, be default, use the #ClutterActor that - * has been attached to the action; it is possible to create a - * separate #ClutterActor and use it instead. - * - * Setting this property has no effect on the #ClutterActor argument - * passed to the #ClutterDragAction signals - * - * Since: 1.4 - */ - drag_props[PROP_DRAG_HANDLE] = - g_param_spec_object ("drag-handle", - P_("Drag Handle"), - P_("The actor that is being dragged"), - CLUTTER_TYPE_ACTOR, - CLUTTER_PARAM_READWRITE); - - /** - * ClutterDragAction:drag-axis: - * - * Constraints the dragging action to the specified axis - * - * Since: 1.4 - */ - drag_props[PROP_DRAG_AXIS] = - g_param_spec_enum ("drag-axis", - P_("Drag Axis"), - P_("Constraints the dragging to an axis"), - CLUTTER_TYPE_DRAG_AXIS, - CLUTTER_DRAG_AXIS_NONE, - CLUTTER_PARAM_READWRITE); - - /** - * ClutterDragAction:drag-area: - * - * Constains the dragging action (or in particular, the resulting - * actor position) to the specified #ClutterRect, in parent's - * coordinates. - * - * Since: 1.12 - */ - drag_props[PROP_DRAG_AREA] = - g_param_spec_boxed ("drag-area", - P_("Drag Area"), - P_("Constrains the dragging to a rectangle"), - GRAPHENE_TYPE_RECT, - CLUTTER_PARAM_READWRITE); - - /** - * ClutterDragAction:drag-area-set: - * - * Whether the #ClutterDragAction:drag-area property has been set. - * - * Since: 1.12 - */ - drag_props[PROP_DRAG_AREA_SET] = - g_param_spec_boolean ("drag-area-set", - P_("Drag Area Set"), - P_("Whether the drag area is set"), - FALSE, - CLUTTER_PARAM_READABLE); - - - gobject_class->set_property = clutter_drag_action_set_property; - gobject_class->get_property = clutter_drag_action_get_property; - gobject_class->dispose = clutter_drag_action_dispose; - g_object_class_install_properties (gobject_class, - PROP_LAST, - drag_props); - - /** - * ClutterDragAction::drag-begin: - * @action: the #ClutterDragAction that emitted the signal - * @actor: the #ClutterActor attached to the action - * @event_x: the X coordinate (in stage space) of the press event - * @event_y: the Y coordinate (in stage space) of the press event - * @modifiers: the modifiers of the press event - * - * The ::drag-begin signal is emitted when the #ClutterDragAction - * starts the dragging - * - * The emission of this signal can be delayed by using the - * #ClutterDragAction:x-drag-threshold and - * #ClutterDragAction:y-drag-threshold properties - * - * Since: 1.4 - */ - drag_signals[DRAG_BEGIN] = - g_signal_new (I_("drag-begin"), - CLUTTER_TYPE_DRAG_ACTION, - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ClutterDragActionClass, drag_begin), - NULL, NULL, - _clutter_marshal_VOID__OBJECT_FLOAT_FLOAT_FLAGS, - G_TYPE_NONE, 4, - CLUTTER_TYPE_ACTOR, - G_TYPE_FLOAT, - 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), - _clutter_boolean_continue_accumulator, 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 - * @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-motion 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 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 the - * #ClutterDragAction::drag-progress signal and return %FALSE from the - * handler. - * - * Since: 1.4 - */ - drag_signals[DRAG_MOTION] = - g_signal_new (I_("drag-motion"), - CLUTTER_TYPE_DRAG_ACTION, - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ClutterDragActionClass, drag_motion), - NULL, NULL, - _clutter_marshal_VOID__OBJECT_FLOAT_FLOAT, - G_TYPE_NONE, 3, - CLUTTER_TYPE_ACTOR, - G_TYPE_FLOAT, - G_TYPE_FLOAT); - - /** - * ClutterDragAction::drag-end: - * @action: the #ClutterDragAction that emitted the signal - * @actor: the #ClutterActor attached to the action - * @event_x: the X coordinate (in stage space) of the release event - * @event_y: the Y coordinate (in stage space) of the release event - * @modifiers: the modifiers of the release event - * - * The ::drag-end signal is emitted at the end of the dragging, - * when the pointer button's is released - * - * This signal is emitted if and only if the #ClutterDragAction::drag-begin - * signal has been emitted first - * - * Since: 1.4 - */ - drag_signals[DRAG_END] = - g_signal_new (I_("drag-end"), - CLUTTER_TYPE_DRAG_ACTION, - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ClutterDragActionClass, drag_end), - NULL, NULL, - _clutter_marshal_VOID__OBJECT_FLOAT_FLOAT_FLAGS, - G_TYPE_NONE, 4, - CLUTTER_TYPE_ACTOR, - G_TYPE_FLOAT, - G_TYPE_FLOAT, - CLUTTER_TYPE_MODIFIER_TYPE); -} - -static void -clutter_drag_action_init (ClutterDragAction *self) -{ - self->priv = clutter_drag_action_get_instance_private (self); -} - -/** - * clutter_drag_action_new: - * - * Creates a new #ClutterDragAction instance - * - * Return value: the newly created #ClutterDragAction - * - * Since: 1.4 - */ -ClutterAction * -clutter_drag_action_new (void) -{ - return g_object_new (CLUTTER_TYPE_DRAG_ACTION, NULL); -} - -/** - * clutter_drag_action_set_drag_threshold: - * @action: a #ClutterDragAction - * @x_threshold: a distance on the horizontal axis, in pixels, or - * -1 to use the default drag threshold from #ClutterSettings - * @y_threshold: a distance on the vertical axis, in pixels, or - * -1 to use the default drag threshold from #ClutterSettings - * - * Sets the horizontal and vertical drag thresholds that must be - * cleared by the pointer before @action can begin the dragging. - * - * If @x_threshold or @y_threshold are set to -1 then the default - * drag threshold stored in the #ClutterSettings:dnd-drag-threshold - * property of #ClutterSettings will be used. - * - * Since: 1.4 - */ -void -clutter_drag_action_set_drag_threshold (ClutterDragAction *action, - gint x_threshold, - gint y_threshold) -{ - ClutterDragActionPrivate *priv; - GObject *self; - - g_return_if_fail (CLUTTER_IS_DRAG_ACTION (action)); - - self = G_OBJECT (action); - priv = action->priv; - - g_object_freeze_notify (self); - - if (priv->x_drag_threshold != x_threshold) - { - priv->x_drag_threshold = x_threshold; - - g_object_notify_by_pspec (self, drag_props[PROP_X_DRAG_THRESHOLD]); - } - - if (priv->y_drag_threshold != y_threshold) - { - priv->y_drag_threshold = y_threshold; - - g_object_notify_by_pspec (self, drag_props[PROP_Y_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 values set by clutter_drag_action_set_drag_threshold(). - * - * If the #ClutterDragAction:x-drag-threshold property or the - * #ClutterDragAction:y-drag-threshold property have been set to -1 then - * this function will return the default drag threshold value as stored - * by the #ClutterSettings:dnd-drag-threshold property of #ClutterSettings. - * - * Since: 1.4 - */ -void -clutter_drag_action_get_drag_threshold (ClutterDragAction *action, - guint *x_threshold, - guint *y_threshold) -{ - gint x_res, y_res; - - g_return_if_fail (CLUTTER_IS_DRAG_ACTION (action)); - - get_drag_threshold (action, &x_res, &y_res); - - if (x_threshold != NULL) - *x_threshold = x_res; - - if (y_threshold != NULL) - *y_threshold = y_res; -} - -static void -on_drag_handle_destroy (ClutterActor *handle, - ClutterDragAction *action) -{ - ClutterDragActionPrivate *priv = action->priv; - ClutterActor *actor; - - /* make sure we reset the state */ - actor = clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (action)); - if (priv->in_drag) - emit_drag_end (action, actor, NULL); - - priv->drag_handle = NULL; -} - -/** - * clutter_drag_action_set_drag_handle: - * @action: a #ClutterDragAction - * @handle: (allow-none): a #ClutterActor, or %NULL to unset - * - * Sets the actor to be used as the drag handle. - * - * Since: 1.4 - */ -void -clutter_drag_action_set_drag_handle (ClutterDragAction *action, - ClutterActor *handle) -{ - ClutterDragActionPrivate *priv; - - g_return_if_fail (CLUTTER_IS_DRAG_ACTION (action)); - g_return_if_fail (handle == NULL || CLUTTER_IS_ACTOR (handle)); - - priv = action->priv; - - if (priv->drag_handle == handle) - return; - - if (priv->drag_handle != NULL) - g_signal_handlers_disconnect_by_func (priv->drag_handle, - G_CALLBACK (on_drag_handle_destroy), - action); - - priv->drag_handle = handle; - - priv->transformed_press_x = priv->press_x; - priv->transformed_press_y = priv->press_y; - - if (priv->drag_handle != NULL) - { - clutter_actor_transform_stage_point (priv->drag_handle, - priv->press_x, - priv->press_y, - &priv->transformed_press_x, - &priv->transformed_press_y); - g_signal_connect (priv->drag_handle, "destroy", - G_CALLBACK (on_drag_handle_destroy), - action); - } - - g_object_notify_by_pspec (G_OBJECT (action), drag_props[PROP_DRAG_HANDLE]); -} - -/** - * clutter_drag_action_get_drag_handle: - * @action: a #ClutterDragAction - * - * Retrieves the drag handle set by clutter_drag_action_set_drag_handle() - * - * Return value: (transfer none): a #ClutterActor, used as the drag - * handle, or %NULL if none was set - * - * Since: 1.4 - */ -ClutterActor * -clutter_drag_action_get_drag_handle (ClutterDragAction *action) -{ - g_return_val_if_fail (CLUTTER_IS_DRAG_ACTION (action), NULL); - - return action->priv->drag_handle; -} - -/** - * clutter_drag_action_set_drag_axis: - * @action: a #ClutterDragAction - * @axis: the axis to constraint the dragging to - * - * Restricts the dragging action to a specific axis - * - * Since: 1.4 - */ -void -clutter_drag_action_set_drag_axis (ClutterDragAction *action, - ClutterDragAxis axis) -{ - ClutterDragActionPrivate *priv; - - g_return_if_fail (CLUTTER_IS_DRAG_ACTION (action)); - g_return_if_fail (axis >= CLUTTER_DRAG_AXIS_NONE && - axis <= CLUTTER_DRAG_Y_AXIS); - - priv = action->priv; - - if (priv->drag_axis == axis) - return; - - priv->drag_axis = axis; - - g_object_notify_by_pspec (G_OBJECT (action), drag_props[PROP_DRAG_AXIS]); -} - -/** - * clutter_drag_action_get_drag_axis: - * @action: a #ClutterDragAction - * - * Retrieves the axis constraint set by clutter_drag_action_set_drag_axis() - * - * Return value: the axis constraint - * - * Since: 1.4 - */ -ClutterDragAxis -clutter_drag_action_get_drag_axis (ClutterDragAction *action) -{ - g_return_val_if_fail (CLUTTER_IS_DRAG_ACTION (action), - CLUTTER_DRAG_AXIS_NONE); - - return action->priv->drag_axis; -} - -/** - * clutter_drag_action_get_press_coords: - * @action: a #ClutterDragAction - * @press_x: (out): return location for the press event's X coordinate - * @press_y: (out): return location for the press event's Y coordinate - * - * Retrieves the coordinates, in stage space, of the press event - * that started the dragging - * - * Since: 1.4 - */ -void -clutter_drag_action_get_press_coords (ClutterDragAction *action, - gfloat *press_x, - gfloat *press_y) -{ - g_return_if_fail (CLUTTER_IS_DRAG_ACTION (action)); - - if (press_x) - *press_x = action->priv->press_x; - - if (press_y) - *press_y = action->priv->press_y; -} - -/** - * clutter_drag_action_get_motion_coords: - * @action: a #ClutterDragAction - * @motion_x: (out): return location for the latest motion - * event's X coordinate - * @motion_y: (out): return location for the latest motion - * event's Y coordinate - * - * Retrieves the coordinates, in stage space, of the latest motion - * event during the dragging - * - * Since: 1.4 - */ -void -clutter_drag_action_get_motion_coords (ClutterDragAction *action, - gfloat *motion_x, - gfloat *motion_y) -{ - g_return_if_fail (CLUTTER_IS_DRAG_ACTION (action)); - - if (motion_x) - *motion_x = action->priv->last_motion_x; - - if (motion_y) - *motion_y = action->priv->last_motion_y; -} - -/** - * clutter_drag_action_get_drag_area: - * @action: a #ClutterDragAction - * @drag_area: (out caller-allocates): a #graphene_rect_t to be filled - * - * Retrieves the "drag area" associated with @action, that - * is a #graphene_rect_t that constrains the actor movements, - * in parents coordinates. - * - * Returns: %TRUE if the actor is actually constrained (and thus - * @drag_area is valid), %FALSE otherwise - */ -gboolean -clutter_drag_action_get_drag_area (ClutterDragAction *action, - graphene_rect_t *drag_area) -{ - g_return_val_if_fail (CLUTTER_IS_DRAG_ACTION (action), FALSE); - - if (drag_area != NULL) - *drag_area = action->priv->drag_area; - return action->priv->drag_area_set; -} - -/** - * clutter_drag_action_set_drag_area: - * @action: a #ClutterDragAction - * @drag_area: (allow-none): a #ClutterRect - * - * Sets @drag_area to constrain the dragging of the actor associated - * with @action, so that it position is always within @drag_area, expressed - * in parent's coordinates. - * If @drag_area is %NULL, the actor is not constrained. - */ -void -clutter_drag_action_set_drag_area (ClutterDragAction *action, - const graphene_rect_t *drag_area) -{ - ClutterDragActionPrivate *priv; - - g_return_if_fail (CLUTTER_IS_DRAG_ACTION (action)); - - priv = action->priv; - - if (drag_area != NULL) - { - priv->drag_area = *drag_area; - priv->drag_area_set = TRUE; - } - else - priv->drag_area_set = FALSE; - - g_object_notify_by_pspec (G_OBJECT (action), drag_props[PROP_DRAG_AREA_SET]); - g_object_notify_by_pspec (G_OBJECT (action), drag_props[PROP_DRAG_AREA]); -} diff --git a/clutter/clutter/clutter-drag-action.h b/clutter/clutter/clutter-drag-action.h deleted file mode 100644 index 6904dc5ed..000000000 --- a/clutter/clutter/clutter-drag-action.h +++ /dev/null @@ -1,152 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright (C) 2010 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * Author: - * Emmanuele Bassi - */ - -#ifndef __CLUTTER_DRAG_ACTION_H__ -#define __CLUTTER_DRAG_ACTION_H__ - -#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION) -#error "Only can be included directly." -#endif - -#include -#include - -G_BEGIN_DECLS - -#define CLUTTER_TYPE_DRAG_ACTION (clutter_drag_action_get_type ()) -#define CLUTTER_DRAG_ACTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_DRAG_ACTION, ClutterDragAction)) -#define CLUTTER_IS_DRAG_ACTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_DRAG_ACTION)) -#define CLUTTER_DRAG_ACTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CLUTTER_TYPE_DRAG_ACTION, ClutterDragActionClass)) -#define CLUTTER_IS_DRAG_ACTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CLUTTER_TYPE_DRAG_ACTION)) -#define CLUTTER_DRAG_ACTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CLUTTER_TYPE_DRAG_ACTION, ClutterDragActionClass)) - -typedef struct _ClutterDragAction ClutterDragAction; -typedef struct _ClutterDragActionPrivate ClutterDragActionPrivate; -typedef struct _ClutterDragActionClass ClutterDragActionClass; - -/** - * ClutterDragAction: - * - * The #ClutterDragAction structure contains only - * private data and should be accessed using the provided API - * - * Since: 1.4 - */ -struct _ClutterDragAction -{ - /*< private >*/ - ClutterAction parent_instance; - - ClutterDragActionPrivate *priv; -}; - -/** - * ClutterDragActionClass: - * @drag_begin: class handler of the #ClutterDragAction::drag-begin signal - * @drag_motion: class handler of the #ClutterDragAction::drag-motion signal - * @drag_end: class handler of the #ClutterDragAction::drag-end signal - * @drag_progress: class handler of the #ClutterDragAction::drag-progress signal - * - * The #ClutterDragActionClass structure contains - * only private data - * - * Since: 1.4 - */ -struct _ClutterDragActionClass -{ - /*< private >*/ - 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); - 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); -}; - -CLUTTER_EXPORT -GType clutter_drag_action_get_type (void) G_GNUC_CONST; - -CLUTTER_EXPORT -ClutterAction * clutter_drag_action_new (void); - -CLUTTER_EXPORT -void clutter_drag_action_set_drag_threshold (ClutterDragAction *action, - gint x_threshold, - gint y_threshold); -CLUTTER_EXPORT -void clutter_drag_action_get_drag_threshold (ClutterDragAction *action, - guint *x_threshold, - guint *y_threshold); -CLUTTER_EXPORT -void clutter_drag_action_set_drag_handle (ClutterDragAction *action, - ClutterActor *handle); -CLUTTER_EXPORT -ClutterActor * clutter_drag_action_get_drag_handle (ClutterDragAction *action); -CLUTTER_EXPORT -void clutter_drag_action_set_drag_axis (ClutterDragAction *action, - ClutterDragAxis axis); -CLUTTER_EXPORT -ClutterDragAxis clutter_drag_action_get_drag_axis (ClutterDragAction *action); - -CLUTTER_EXPORT -void clutter_drag_action_get_press_coords (ClutterDragAction *action, - gfloat *press_x, - gfloat *press_y); -CLUTTER_EXPORT -void clutter_drag_action_get_motion_coords (ClutterDragAction *action, - gfloat *motion_x, - gfloat *motion_y); - -CLUTTER_EXPORT -gboolean clutter_drag_action_get_drag_area (ClutterDragAction *action, - graphene_rect_t *drag_area); - -CLUTTER_EXPORT -void clutter_drag_action_set_drag_area (ClutterDragAction *action, - const graphene_rect_t *drag_area); - -G_END_DECLS - -#endif /* __CLUTTER_DRAG_ACTION_H__ */ diff --git a/clutter/clutter/clutter-drop-action.c b/clutter/clutter/clutter-drop-action.c deleted file mode 100644 index f9e934aaa..000000000 --- a/clutter/clutter/clutter-drop-action.c +++ /dev/null @@ -1,527 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright © 2011 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * Author: - * Emmanuele Bassi - */ - -/** - * SECTION:clutter-drop-action - * @Title: ClutterDropAction - * @short_description: An action for drop targets - * - * #ClutterDropAction is a #ClutterAction that allows a #ClutterActor - * implementation to control what happens when an actor dragged using - * a #ClutterDragAction crosses the target area or when a dragged actor - * is released (or "dropped") on the target area. - * - * A trivial use of #ClutterDropAction consists in connecting to the - * #ClutterDropAction::drop signal and handling the drop from there, - * for instance: - * - * |[ - * ClutterAction *action = clutter_drop_action (); - * - * g_signal_connect (action, "drop", G_CALLBACK (on_drop), NULL); - * clutter_actor_add_action (an_actor, action); - * ]| - * - * The #ClutterDropAction::can-drop can be used to control whether the - * #ClutterDropAction::drop signal is going to be emitted; returning %FALSE - * from a handler connected to the #ClutterDropAction::can-drop signal will - * cause the #ClutterDropAction::drop signal to be skipped when the input - * device button is released. - * - * It's important to note that #ClutterDropAction will only work with - * actors dragged using #ClutterDragAction. - * - * See [drop-action.c](https://git.gnome.org/browse/clutter/tree/examples/drop-action.c?h=clutter-1.18) - * for an example of how to use #ClutterDropAction. - * - * #ClutterDropAction is available since Clutter 1.8 - */ - -#include "clutter-build-config.h" - -#include "clutter-drop-action.h" - -#include "clutter-actor-meta-private.h" -#include "clutter-actor-private.h" -#include "clutter-drag-action.h" -#include "clutter-main.h" -#include "clutter-marshal.h" -#include "clutter-stage-private.h" - -struct _ClutterDropActionPrivate -{ - ClutterActor *actor; - ClutterActor *stage; - - gulong mapped_id; -}; - -typedef struct _DropTarget { - ClutterActor *stage; - - gulong capture_id; - - GHashTable *actions; - - ClutterDropAction *last_action; -} DropTarget; - -enum -{ - CAN_DROP, - OVER_IN, - OVER_OUT, - DROP, - DROP_CANCEL, - - LAST_SIGNAL -}; - -static guint drop_signals[LAST_SIGNAL] = { 0, }; - -G_DEFINE_TYPE_WITH_PRIVATE (ClutterDropAction, clutter_drop_action, CLUTTER_TYPE_ACTION) - -static void -drop_target_free (gpointer _data) -{ - DropTarget *data = _data; - - g_clear_signal_handler (&data->capture_id, data->stage); - g_hash_table_destroy (data->actions); - g_free (data); -} - -static gboolean -on_stage_capture (ClutterStage *stage, - ClutterEvent *event, - gpointer user_data) -{ - DropTarget *data = user_data; - gfloat event_x, event_y; - ClutterActor *actor, *drag_actor; - ClutterDropAction *drop_action; - ClutterInputDevice *device; - gboolean was_reactive; - - switch (clutter_event_type (event)) - { - case CLUTTER_MOTION: - case CLUTTER_BUTTON_RELEASE: - if (clutter_event_type (event) == CLUTTER_MOTION && - !(clutter_event_get_state (event) & CLUTTER_BUTTON1_MASK)) - return CLUTTER_EVENT_PROPAGATE; - - if (clutter_event_type (event) == CLUTTER_BUTTON_RELEASE && - clutter_event_get_button (event) != CLUTTER_BUTTON_PRIMARY) - 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); - - /* get the actor under the cursor, excluding the dragged actor; we - * use reactivity because it won't cause any scene invalidation - */ - was_reactive = clutter_actor_get_reactive (drag_actor); - clutter_actor_set_reactive (drag_actor, FALSE); - - actor = clutter_stage_get_actor_at_pos (stage, CLUTTER_PICK_REACTIVE, - event_x, - event_y); - if (actor == NULL || actor == CLUTTER_ACTOR (stage)) - { - if (data->last_action != NULL) - { - ClutterActorMeta *meta = CLUTTER_ACTOR_META (data->last_action); - - g_signal_emit (data->last_action, drop_signals[OVER_OUT], 0, - clutter_actor_meta_get_actor (meta)); - - data->last_action = NULL; - } - - goto out; - } - - drop_action = g_hash_table_lookup (data->actions, actor); - - if (drop_action == NULL) - { - if (data->last_action != NULL) - { - ClutterActorMeta *meta = CLUTTER_ACTOR_META (data->last_action); - - g_signal_emit (data->last_action, drop_signals[OVER_OUT], 0, - clutter_actor_meta_get_actor (meta)); - - data->last_action = NULL; - } - - goto out; - } - else - { - if (data->last_action != drop_action) - { - ClutterActorMeta *meta; - - if (data->last_action != NULL) - { - meta = CLUTTER_ACTOR_META (data->last_action); - - g_signal_emit (data->last_action, drop_signals[OVER_OUT], 0, - clutter_actor_meta_get_actor (meta)); - } - - meta = CLUTTER_ACTOR_META (drop_action); - - g_signal_emit (drop_action, drop_signals[OVER_IN], 0, - clutter_actor_meta_get_actor (meta)); - } - - data->last_action = drop_action; - } - -out: - if (clutter_event_type (event) == CLUTTER_BUTTON_RELEASE || - clutter_event_type (event) == CLUTTER_TOUCH_END) - { - if (data->last_action != NULL) - { - ClutterActorMeta *meta = CLUTTER_ACTOR_META (data->last_action); - gboolean can_drop = FALSE; - - g_signal_emit (data->last_action, drop_signals[CAN_DROP], 0, - clutter_actor_meta_get_actor (meta), - event_x, event_y, - &can_drop); - - if (can_drop) - { - g_signal_emit (data->last_action, drop_signals[DROP], 0, - clutter_actor_meta_get_actor (meta), - event_x, event_y); - } - else - { - g_signal_emit (data->last_action, drop_signals[DROP_CANCEL], 0, - clutter_actor_meta_get_actor (meta), - event_x, event_y); - } - - } - - data->last_action = NULL; - } - - if (drag_actor != NULL) - clutter_actor_set_reactive (drag_actor, was_reactive); - - return CLUTTER_EVENT_PROPAGATE; -} - -static void -drop_action_register (ClutterDropAction *self) -{ - ClutterDropActionPrivate *priv = self->priv; - DropTarget *data; - - g_assert (priv->stage != NULL); - - data = g_object_get_data (G_OBJECT (priv->stage), "__clutter_drop_targets"); - if (data == NULL) - { - data = g_new0 (DropTarget, 1); - - data->stage = priv->stage; - data->actions = g_hash_table_new (NULL, NULL); - data->capture_id = g_signal_connect (priv->stage, "captured-event", - G_CALLBACK (on_stage_capture), - data); - g_object_set_data_full (G_OBJECT (priv->stage), "__clutter_drop_targets", - data, - drop_target_free); - } - - g_hash_table_replace (data->actions, priv->actor, self); -} - -static void -drop_action_unregister (ClutterDropAction *self) -{ - ClutterDropActionPrivate *priv = self->priv; - DropTarget *data = NULL; - - if (priv->stage != NULL) - data = g_object_get_data (G_OBJECT (priv->stage), "__clutter_drop_targets"); - - if (data == NULL) - return; - - g_hash_table_remove (data->actions, priv->actor); - if (g_hash_table_size (data->actions) == 0) - g_object_set_data (G_OBJECT (data->stage), "__clutter_drop_targets", NULL); -} - -static void -on_actor_mapped (ClutterActor *actor, - GParamSpec *pspec, - ClutterDropAction *self) -{ - if (clutter_actor_is_mapped (actor)) - { - if (self->priv->stage == NULL) - self->priv->stage = clutter_actor_get_stage (actor); - - drop_action_register (self); - } - else - drop_action_unregister (self); -} - -static void -clutter_drop_action_set_actor (ClutterActorMeta *meta, - ClutterActor *actor) -{ - ClutterDropActionPrivate *priv = CLUTTER_DROP_ACTION (meta)->priv; - - if (priv->actor != NULL) - { - drop_action_unregister (CLUTTER_DROP_ACTION (meta)); - - g_clear_signal_handler (&priv->mapped_id, priv->actor); - - priv->stage = NULL; - priv->actor = NULL; - } - - priv->actor = actor; - - if (priv->actor != NULL) - { - priv->stage = clutter_actor_get_stage (actor); - priv->mapped_id = g_signal_connect (actor, "notify::mapped", - G_CALLBACK (on_actor_mapped), - meta); - - if (priv->stage != NULL) - drop_action_register (CLUTTER_DROP_ACTION (meta)); - } - - CLUTTER_ACTOR_META_CLASS (clutter_drop_action_parent_class)->set_actor (meta, actor); -} - -static gboolean -signal_accumulator (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 gboolean -clutter_drop_action_real_can_drop (ClutterDropAction *action, - ClutterActor *actor, - gfloat event_x, - gfloat event_y) -{ - return TRUE; -} - -static void -clutter_drop_action_class_init (ClutterDropActionClass *klass) -{ - ClutterActorMetaClass *meta_class = CLUTTER_ACTOR_META_CLASS (klass); - - meta_class->set_actor = clutter_drop_action_set_actor; - - klass->can_drop = clutter_drop_action_real_can_drop; - - /** - * ClutterDropAction::can-drop: - * @action: the #ClutterDropAction that emitted the signal - * @actor: the #ClutterActor attached to the @action - * @event_x: the X coordinate (in stage space) of the drop event - * @event_y: the Y coordinate (in stage space) of the drop event - * - * The ::can-drop signal is emitted when the dragged actor is dropped - * on @actor. The return value of the ::can-drop signal will determine - * whether or not the #ClutterDropAction::drop signal is going to be - * emitted on @action. - * - * The default implementation of #ClutterDropAction returns %TRUE for - * this signal. - * - * Return value: %TRUE if the drop is accepted, and %FALSE otherwise - * - * Since: 1.8 - */ - drop_signals[CAN_DROP] = - g_signal_new (I_("can-drop"), - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ClutterDropActionClass, can_drop), - signal_accumulator, NULL, - _clutter_marshal_BOOLEAN__OBJECT_FLOAT_FLOAT, - G_TYPE_BOOLEAN, 3, - CLUTTER_TYPE_ACTOR, - G_TYPE_FLOAT, - G_TYPE_FLOAT); - - /** - * ClutterDropAction::over-in: - * @action: the #ClutterDropAction that emitted the signal - * @actor: the #ClutterActor attached to the @action - * - * The ::over-in signal is emitted when the dragged actor crosses - * into @actor. - * - * Since: 1.8 - */ - drop_signals[OVER_IN] = - g_signal_new (I_("over-in"), - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ClutterDropActionClass, over_in), - NULL, NULL, NULL, - G_TYPE_NONE, 1, - CLUTTER_TYPE_ACTOR); - - /** - * ClutterDropAction::over-out: - * @action: the #ClutterDropAction that emitted the signal - * @actor: the #ClutterActor attached to the @action - * - * The ::over-out signal is emitted when the dragged actor crosses - * outside @actor. - * - * Since: 1.8 - */ - drop_signals[OVER_OUT] = - g_signal_new (I_("over-out"), - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ClutterDropActionClass, over_out), - NULL, NULL, NULL, - G_TYPE_NONE, 1, - CLUTTER_TYPE_ACTOR); - - /** - * ClutterDropAction::drop: - * @action: the #ClutterDropAction that emitted the signal - * @actor: the #ClutterActor attached to the @action - * @event_x: the X coordinate (in stage space) of the drop event - * @event_y: the Y coordinate (in stage space) of the drop event - * - * The ::drop signal is emitted when the dragged actor is dropped - * on @actor. This signal is only emitted if at least an handler of - * #ClutterDropAction::can-drop returns %TRUE. - * - * Since: 1.8 - */ - drop_signals[DROP] = - g_signal_new (I_("drop"), - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ClutterDropActionClass, drop), - NULL, NULL, - _clutter_marshal_VOID__OBJECT_FLOAT_FLOAT, - G_TYPE_NONE, 3, - CLUTTER_TYPE_ACTOR, - G_TYPE_FLOAT, - G_TYPE_FLOAT); - - - /** - * ClutterDropAction::drop-cancel: - * @action: the #ClutterDropAction that emitted the signal - * @actor: the #ClutterActor attached to the @action - * @event_x: the X coordinate (in stage space) of the drop event - * @event_y: the Y coordinate (in stage space) of the drop event - * - * The ::drop-cancel signal is emitted when the drop is refused - * by an emission of the #ClutterDropAction::can-drop signal. - * - * After the ::drop-cancel signal is fired the active drag is - * terminated. - * - * Since: 1.12 - */ - drop_signals[DROP_CANCEL] = - g_signal_new (I_("drop-cancel"), - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ClutterDropActionClass, drop), - NULL, NULL, - _clutter_marshal_VOID__OBJECT_FLOAT_FLOAT, - G_TYPE_NONE, 3, - CLUTTER_TYPE_ACTOR, - G_TYPE_FLOAT, - G_TYPE_FLOAT); -} - -static void -clutter_drop_action_init (ClutterDropAction *self) -{ - self->priv = clutter_drop_action_get_instance_private (self); -} - -/** - * clutter_drop_action_new: - * - * Creates a new #ClutterDropAction. - * - * Use clutter_actor_add_action() to add the action to a #ClutterActor. - * - * Return value: the newly created #ClutterDropAction - * - * Since: 1.8 - */ -ClutterAction * -clutter_drop_action_new (void) -{ - return g_object_new (CLUTTER_TYPE_DROP_ACTION, NULL); -} diff --git a/clutter/clutter/clutter-drop-action.h b/clutter/clutter/clutter-drop-action.h deleted file mode 100644 index d3b973d96..000000000 --- a/clutter/clutter/clutter-drop-action.h +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright © 2011 Intel Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - * - * Author: - * Emmanuele Bassi - */ - -#ifndef __CLUTTER_DROP_ACTION_H__ -#define __CLUTTER_DROP_ACTION_H__ - -#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION) -#error "Only can be directly included." -#endif - -#include - -G_BEGIN_DECLS - -#define CLUTTER_TYPE_DROP_ACTION (clutter_drop_action_get_type ()) -#define CLUTTER_DROP_ACTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_DROP_ACTION, ClutterDropAction)) -#define CLUTTER_IS_DROP_ACTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_DROP_ACTION)) -#define CLUTTER_DROP_ACTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CLUTTER_TYPE_DROP_ACTION, ClutterDropActionClass)) -#define CLUTTER_IS_DROP_ACTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CLUTTER_TYPE_DROP_ACTION)) -#define CLUTTER_DROP_ACTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CLUTTER_TYPE_DROP_ACTION, ClutterDropActionClass)) - -typedef struct _ClutterDropAction ClutterDropAction; -typedef struct _ClutterDropActionPrivate ClutterDropActionPrivate; -typedef struct _ClutterDropActionClass ClutterDropActionClass; - -/** - * ClutterDropAction: - * - * The #ClutterDropAction structure contains only - * private data and should be accessed using the provided API. - * - * Since: 1.8 - */ -struct _ClutterDropAction -{ - /*< private >*/ - ClutterAction parent_instance; - - ClutterDropActionPrivate *priv; -}; - -/** - * ClutterDropActionClass: - * @can_drop: class handler for the #ClutterDropAction::can-drop signal - * @over_in: class handler for the #ClutterDropAction::over-in signal - * @over_out: class handler for the #ClutterDropAction::over-out signal - * @drop: class handler for the #ClutterDropAction::drop signal - * - * The #ClutterDropActionClass structure contains - * only private data. - * - * Since: 1.8 - */ -struct _ClutterDropActionClass -{ - /*< private >*/ - ClutterActionClass parent_class; - - /*< public >*/ - gboolean (* can_drop) (ClutterDropAction *action, - ClutterActor *actor, - gfloat event_x, - gfloat event_y); - - void (* over_in) (ClutterDropAction *action, - ClutterActor *actor); - void (* over_out) (ClutterDropAction *action, - ClutterActor *actor); - - void (* drop) (ClutterDropAction *action, - ClutterActor *actor, - gfloat event_x, - gfloat event_y); - - /*< private >*/ - void (*_clutter_drop_action1) (void); - void (*_clutter_drop_action2) (void); - void (*_clutter_drop_action3) (void); - void (*_clutter_drop_action4) (void); - void (*_clutter_drop_action5) (void); - void (*_clutter_drop_action6) (void); - void (*_clutter_drop_action7) (void); - void (*_clutter_drop_action8) (void); -}; - -CLUTTER_EXPORT -GType clutter_drop_action_get_type (void) G_GNUC_CONST; - -CLUTTER_EXPORT -ClutterAction * clutter_drop_action_new (void); - -G_END_DECLS - -#endif /* __CLUTTER_DROP_ACTION_H__ */ diff --git a/clutter/clutter/clutter.h b/clutter/clutter/clutter.h index 9dd69c3d3..d5ffdd04f 100644 --- a/clutter/clutter/clutter.h +++ b/clutter/clutter/clutter.h @@ -56,8 +56,6 @@ #include "clutter-content.h" #include "clutter-deform-effect.h" #include "clutter-desaturate-effect.h" -#include "clutter-drag-action.h" -#include "clutter-drop-action.h" #include "clutter-effect.h" #include "clutter-enums.h" #include "clutter-enum-types.h" diff --git a/clutter/clutter/meson.build b/clutter/clutter/meson.build index a13f637b2..bba8a23c9 100644 --- a/clutter/clutter/meson.build +++ b/clutter/clutter/meson.build @@ -30,8 +30,6 @@ clutter_headers = [ 'clutter-deform-effect.h', 'clutter-deprecated.h', 'clutter-desaturate-effect.h', - 'clutter-drag-action.h', - 'clutter-drop-action.h', 'clutter-effect.h', 'clutter-enums.h', 'clutter-event.h', @@ -118,8 +116,6 @@ clutter_sources = [ 'clutter-content.c', 'clutter-deform-effect.c', 'clutter-desaturate-effect.c', - 'clutter-drag-action.c', - 'clutter-drop-action.c', 'clutter-effect.c', 'clutter-event.c', 'clutter-feature.c', diff --git a/src/tests/clutter/interactive/meson.build b/src/tests/clutter/interactive/meson.build index 12274768e..c22970722 100644 --- a/src/tests/clutter/interactive/meson.build +++ b/src/tests/clutter/interactive/meson.build @@ -37,7 +37,6 @@ clutter_tests_interactive_test_sources = [ 'test-cairo-clock.c', 'test-cairo-flowers.c', 'test-stage-sizing.c', - 'test-scrolling.c', 'test-swipe-action.c', 'test-cogl-point-sprites.c', 'test-path-constraint.c', diff --git a/src/tests/clutter/interactive/test-scrolling.c b/src/tests/clutter/interactive/test-scrolling.c deleted file mode 100644 index d4137bf14..000000000 --- a/src/tests/clutter/interactive/test-scrolling.c +++ /dev/null @@ -1,137 +0,0 @@ -#include -#include -#include -#include - -#define RECT_WIDTH 400 -#define RECT_HEIGHT 300 -#define N_RECTS 7 - -static const gchar *rect_color[N_RECTS] = { - "#edd400", - "#f57900", - "#c17d11", - "#73d216", - "#3465a4", - "#75507b", - "#cc0000" -}; - -static ClutterActor *rectangle[N_RECTS]; -static ClutterActor *viewport = NULL; - -int -test_scrolling_main (int argc, char *argv[]); - -static void -on_drag_end (ClutterDragAction *action, - ClutterActor *actor, - gfloat event_x, - gfloat event_y, - ClutterModifierType modifiers) -{ - gfloat viewport_x = clutter_actor_get_x (viewport); - gfloat offset_x; - gint child_visible; - - /* check if we're at the viewport edges */ - if (viewport_x > 0) - { - clutter_actor_save_easing_state (viewport); - clutter_actor_set_easing_mode (viewport, CLUTTER_EASE_OUT_BOUNCE); - clutter_actor_set_x (viewport, 0); - clutter_actor_restore_easing_state (viewport); - return; - } - - if (viewport_x < (-1.0f * (RECT_WIDTH * (N_RECTS - 1)))) - { - clutter_actor_save_easing_state (viewport); - clutter_actor_set_easing_mode (viewport, CLUTTER_EASE_OUT_BOUNCE); - clutter_actor_set_x (viewport, -1.0f * (RECT_WIDTH * (N_RECTS - 1))); - clutter_actor_restore_easing_state (viewport); - return; - } - - /* animate the viewport to fully show the child once we pass - * a certain threshold with the dragging action - */ - offset_x = fabsf (viewport_x) / RECT_WIDTH + 0.5f; - if (offset_x > (RECT_WIDTH * 0.33)) - child_visible = (int) offset_x + 1; - else - child_visible = (int) offset_x; - - /* sanity check on the children number */ - child_visible = CLAMP (child_visible, 0, N_RECTS); - - clutter_actor_save_easing_state (viewport); - clutter_actor_set_x (viewport, -1.0f * RECT_WIDTH * child_visible); - clutter_actor_restore_easing_state (viewport); -} - -G_MODULE_EXPORT int -test_scrolling_main (int argc, char *argv[]) -{ - ClutterActor *stage; - ClutterActor *scroll; - ClutterAction *action; - gint i; - - if (clutter_init (&argc, &argv) != CLUTTER_INIT_SUCCESS) - return 1; - - stage = clutter_stage_new (); - clutter_stage_set_title (CLUTTER_STAGE (stage), "Scrolling"); - clutter_actor_set_size (stage, 800, 600); - g_signal_connect (stage, "destroy", G_CALLBACK (clutter_main_quit), NULL); - - /* scroll: the group that contains the scrolling viewport; we set its - * size to be the same as one rectangle, position it in the middle of - * the stage and set it to clip its contents to the allocated size - */ - scroll = clutter_actor_new (); - clutter_actor_add_child (stage, scroll); - clutter_actor_set_size (scroll, RECT_WIDTH, RECT_HEIGHT); - clutter_actor_add_constraint (scroll, clutter_align_constraint_new (stage, CLUTTER_ALIGN_BOTH, 0.5)); - clutter_actor_set_clip_to_allocation (scroll, TRUE); - - /* viewport: the actual container for the children; we scroll it using - * the Drag action constrained to the horizontal axis, and every time - * the dragging ends we check whether we're dragging past the end of - * the viewport - */ - viewport = clutter_actor_new (); - clutter_actor_set_layout_manager (viewport, clutter_box_layout_new ()); - clutter_actor_add_child (scroll, viewport); - - /* add dragging capabilities to the viewport; the heavy lifting is - * all done by the DragAction itself, plus the ::drag-end signal - * handler in our code - */ - action = clutter_drag_action_new (); - clutter_actor_add_action (viewport, action); - clutter_drag_action_set_drag_axis (CLUTTER_DRAG_ACTION (action), - CLUTTER_DRAG_X_AXIS); - g_signal_connect (action, "drag-end", G_CALLBACK (on_drag_end), NULL); - clutter_actor_set_reactive (viewport, TRUE); - - /* children of the viewport */ - for (i = 0; i < N_RECTS; i++) - { - ClutterColor color; - - clutter_color_from_string (&color, rect_color[i]); - - rectangle[i] = clutter_actor_new (); - clutter_actor_set_background_color (rectangle[i], &color); - clutter_actor_add_child (viewport, rectangle[i]); - clutter_actor_set_size (rectangle[i], RECT_WIDTH, RECT_HEIGHT); - } - - clutter_actor_show (stage); - - clutter_main (); - - return EXIT_SUCCESS; -}