1eae9fcd7e
*** This is an API change *** Replaced the original drag-threshold property with two separate horizontal (x-drag-threshold) and vertical (y-drag-threshold) thresholds. It is some times necessary to have different drag thresholds for the horizontal and vertical axes. For example, when a draggable actor is inside a horizontal scrolling area, only vertical movement must begin dragging. That can be achieved by setting the x-drag-threshold to G_MAXUINT while y-drag-threshold is something usual, say, 20 pixels. This is different than drag axis, because after the threshold has been cleared by the pointer, the draggable actor can be dragged along both axes (if allowed by the drag-axis property). http://bugzilla.clutter-project.org/show_bug.cgi?id=2291 Signed-off-by: Emmanuele Bassi <ebassi@linux.intel.com>
211 lines
6.1 KiB
C
211 lines
6.1 KiB
C
#include <stdlib.h>
|
|
#include <gmodule.h>
|
|
#include <clutter/clutter.h>
|
|
|
|
static gboolean
|
|
on_enter (ClutterActor *actor,
|
|
ClutterEvent *event)
|
|
{
|
|
clutter_actor_animate (actor, CLUTTER_LINEAR, 150,
|
|
"@effects.curl.period", 0.25,
|
|
NULL);
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
static gboolean
|
|
on_leave (ClutterActor *actor,
|
|
ClutterEvent *event)
|
|
{
|
|
clutter_actor_animate (actor, CLUTTER_LINEAR, 150,
|
|
"@effects.curl.period", 0.0,
|
|
NULL);
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
static void
|
|
on_drag_begin (ClutterDragAction *action,
|
|
ClutterActor *actor,
|
|
gfloat event_x,
|
|
gfloat event_y,
|
|
ClutterModifierType modifiers)
|
|
{
|
|
gboolean is_copy = (modifiers & CLUTTER_SHIFT_MASK) ? TRUE : FALSE;
|
|
ClutterActor *drag_handle = NULL;
|
|
|
|
if (is_copy)
|
|
{
|
|
ClutterActor *stage = clutter_actor_get_stage (actor);
|
|
ClutterColor handle_color;
|
|
|
|
drag_handle = clutter_rectangle_new ();
|
|
clutter_actor_set_size (drag_handle, 48, 48);
|
|
|
|
clutter_color_from_string (&handle_color, "#204a87aa");
|
|
clutter_rectangle_set_color (CLUTTER_RECTANGLE (drag_handle), &handle_color);
|
|
|
|
clutter_container_add_actor (CLUTTER_CONTAINER (stage), drag_handle);
|
|
clutter_actor_set_position (drag_handle, event_x, event_y);
|
|
}
|
|
else
|
|
drag_handle = actor;
|
|
|
|
clutter_drag_action_set_drag_handle (action, drag_handle);
|
|
|
|
/* fully desaturate the actor */
|
|
clutter_actor_animate (actor, CLUTTER_LINEAR, 150,
|
|
"@effects.disable.factor", 1.0,
|
|
NULL);
|
|
}
|
|
|
|
static void
|
|
on_drag_end (ClutterDragAction *action,
|
|
ClutterActor *actor,
|
|
gfloat event_x,
|
|
gfloat event_y,
|
|
ClutterModifierType modifiers)
|
|
{
|
|
ClutterActor *drag_handle;
|
|
|
|
drag_handle = clutter_drag_action_get_drag_handle (action);
|
|
if (actor != drag_handle)
|
|
{
|
|
gfloat real_x, real_y;
|
|
ClutterActor *parent;
|
|
|
|
/* if we are dragging a copy we can destroy the copy now
|
|
* and animate the real actor to the drop coordinates,
|
|
* transformed in the parent's coordinate space
|
|
*/
|
|
clutter_actor_animate (drag_handle, CLUTTER_LINEAR, 150,
|
|
"opacity", 0,
|
|
"signal-swapped-after::completed",
|
|
G_CALLBACK (clutter_actor_destroy),
|
|
drag_handle,
|
|
NULL);
|
|
|
|
parent = clutter_actor_get_parent (actor);
|
|
clutter_actor_transform_stage_point (parent, event_x, event_y,
|
|
&real_x,
|
|
&real_y);
|
|
|
|
clutter_actor_animate (actor, CLUTTER_EASE_OUT_CUBIC, 150,
|
|
"@effects.disable.factor", 0.0,
|
|
"x", real_x,
|
|
"y", real_y,
|
|
NULL);
|
|
}
|
|
else
|
|
clutter_actor_animate (actor, CLUTTER_LINEAR, 150,
|
|
"@effects.disable.factor", 0.0,
|
|
NULL);
|
|
}
|
|
|
|
static ClutterDragAxis
|
|
get_drag_axis (const gchar *str)
|
|
{
|
|
if (str == NULL || *str == '\0')
|
|
return CLUTTER_DRAG_AXIS_NONE;
|
|
|
|
if (*str == 'x' || *str == 'X')
|
|
return CLUTTER_DRAG_X_AXIS;
|
|
|
|
if (*str == 'y' || *str == 'Y')
|
|
return CLUTTER_DRAG_Y_AXIS;
|
|
|
|
g_warn_if_reached ();
|
|
|
|
return CLUTTER_DRAG_AXIS_NONE;
|
|
}
|
|
|
|
static gchar *drag_axis = NULL;
|
|
static gint x_drag_threshold = 0;
|
|
static gint y_drag_threshold = 0;
|
|
|
|
static GOptionEntry entries[] = {
|
|
{
|
|
"x-threshold", 'x',
|
|
0,
|
|
G_OPTION_ARG_INT,
|
|
&x_drag_threshold,
|
|
"Set the horizontal drag threshold", "PIXELS"
|
|
},
|
|
{
|
|
"y-threshold", 'y',
|
|
0,
|
|
G_OPTION_ARG_INT,
|
|
&y_drag_threshold,
|
|
"Set the vertical drag threshold", "PIXELS"
|
|
},
|
|
{
|
|
"axis", 'a',
|
|
0,
|
|
G_OPTION_ARG_STRING,
|
|
&drag_axis,
|
|
"Set the drag axis", "AXIS"
|
|
},
|
|
|
|
{ NULL }
|
|
};
|
|
|
|
G_MODULE_EXPORT int
|
|
test_drag_main (int argc, char *argv[])
|
|
{
|
|
ClutterActor *stage, *handle;
|
|
ClutterAction *action;
|
|
ClutterColor handle_color;
|
|
GError *error;
|
|
|
|
error = NULL;
|
|
clutter_init_with_args (&argc, &argv,
|
|
"test-drag",
|
|
entries,
|
|
NULL,
|
|
&error);
|
|
if (error != NULL)
|
|
{
|
|
g_print ("Unable to run test-drag: %s\n", error->message);
|
|
g_error_free (error);
|
|
|
|
return EXIT_FAILURE;
|
|
}
|
|
|
|
stage = clutter_stage_new ();
|
|
clutter_stage_set_title (CLUTTER_STAGE (stage), "Drag Test");
|
|
clutter_actor_set_size (stage, 800, 600);
|
|
g_signal_connect (stage, "destroy", G_CALLBACK (clutter_main_quit), NULL);
|
|
|
|
clutter_color_from_string (&handle_color, "#729fcfff");
|
|
|
|
handle = clutter_rectangle_new ();
|
|
clutter_rectangle_set_color (CLUTTER_RECTANGLE (handle), &handle_color);
|
|
clutter_actor_set_size (handle, 128, 128);
|
|
clutter_actor_set_position (handle, (800 - 128) / 2, (600 - 128) / 2);
|
|
clutter_actor_set_reactive (handle, TRUE);
|
|
clutter_container_add_actor (CLUTTER_CONTAINER (stage), handle);
|
|
g_signal_connect (handle, "enter-event", G_CALLBACK (on_enter), NULL);
|
|
g_signal_connect (handle, "leave-event", G_CALLBACK (on_leave), NULL);
|
|
|
|
action = clutter_drag_action_new ();
|
|
clutter_drag_action_set_drag_threshold (CLUTTER_DRAG_ACTION (action),
|
|
x_drag_threshold,
|
|
y_drag_threshold);
|
|
clutter_drag_action_set_drag_axis (CLUTTER_DRAG_ACTION (action),
|
|
get_drag_axis (drag_axis));
|
|
|
|
g_signal_connect (action, "drag-begin", G_CALLBACK (on_drag_begin), NULL);
|
|
g_signal_connect (action, "drag-end", G_CALLBACK (on_drag_end), NULL);
|
|
|
|
clutter_actor_add_action (handle, action);
|
|
|
|
clutter_actor_add_effect_with_name (handle, "disable", clutter_desaturate_effect_new (0.0));
|
|
clutter_actor_add_effect_with_name (handle, "curl", clutter_page_turn_effect_new (0.0, 45.0, 12.0));
|
|
|
|
clutter_actor_show (stage);
|
|
|
|
clutter_main ();
|
|
|
|
return EXIT_SUCCESS;
|
|
}
|