Clutter Reference Manual | ||||
---|---|---|---|---|
Top | Description | Object Hierarchy | Signals |
struct ClutterDropAction;
struct ClutterDropActionClass;
ClutterAction * clutter_drop_action_new (void
);
GObject +----GInitiallyUnowned +----ClutterActorMeta +----ClutterAction +----ClutterDropAction
"can-drop" :Run Last
"drop" :Run Last
"drop-cancel" :Run Last
"over-in" :Run Last
"over-out" :Run Last
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 "drop" signal and handling the drop from there, for instance:
1 2 3 4 |
ClutterAction *action = clutter_drop_action (); g_signal_connect (action, "drop", G_CALLBACK (on_drop), NULL); clutter_actor_add_action (an_actor, action); |
The "can-drop" can be used to control whether the
"drop" signal is going to be emitted; returning FALSE
from a handler connected to the "can-drop" signal will
cause the "drop" signal to be skipped when the input
device button is released.
Example 6. Drop targets
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 |
#include <stdlib.h> #include <clutter/clutter.h> #define TARGET_SIZE 200 #define HANDLE_SIZE 128 static ClutterActor *stage = NULL; static ClutterActor *target1 = NULL; static ClutterActor *target2 = NULL; static ClutterActor *drag = NULL; static gboolean drop_successful = FALSE; static void add_drag_object (ClutterActor *target); static void on_drag_end (ClutterDragAction *action, ClutterActor *actor, gfloat event_x, gfloat event_y, ClutterModifierType modifiers) { ClutterActor *handle = clutter_drag_action_get_drag_handle (action); g_print ("Drag ended at: %.0f, %.0f\n", event_x, event_y); clutter_actor_save_easing_state (actor); clutter_actor_set_easing_mode (actor, CLUTTER_LINEAR); clutter_actor_set_opacity (actor, 255); clutter_actor_restore_easing_state (actor); clutter_actor_save_easing_state (handle); if (!drop_successful) { ClutterActor *parent = clutter_actor_get_parent (actor); gfloat x_pos, y_pos; clutter_actor_save_easing_state (parent); clutter_actor_set_easing_mode (parent, CLUTTER_LINEAR); clutter_actor_set_opacity (parent, 255); clutter_actor_restore_easing_state (parent); clutter_actor_get_transformed_position (actor, &x_pos, &y_pos); clutter_actor_set_easing_mode (handle, CLUTTER_EASE_OUT_BOUNCE); clutter_actor_set_position (handle, x_pos, y_pos); clutter_actor_set_opacity (handle, 0); clutter_actor_restore_easing_state (handle); } else { clutter_actor_set_easing_mode (handle, CLUTTER_LINEAR); clutter_actor_set_opacity (handle, 0); } clutter_actor_restore_easing_state (handle); g_signal_connect (handle, "transitions-completed", G_CALLBACK (clutter_actor_destroy), NULL); } static void on_drag_begin (ClutterDragAction *action, ClutterActor *actor, gfloat event_x, gfloat event_y, ClutterModifierType modifiers) { ClutterActor *handle; gfloat x_pos, y_pos; clutter_actor_get_position (actor, &x_pos, &y_pos); handle = clutter_actor_new (); clutter_actor_set_background_color (handle, CLUTTER_COLOR_DarkSkyBlue); clutter_actor_set_size (handle, 128, 128); clutter_actor_set_position (handle, event_x - x_pos, event_y - y_pos); clutter_actor_add_child (stage, handle); clutter_drag_action_set_drag_handle (action, handle); clutter_actor_save_easing_state (actor); clutter_actor_set_easing_mode (actor, CLUTTER_LINEAR); clutter_actor_set_opacity (actor, 128); clutter_actor_restore_easing_state (actor); drop_successful = FALSE; } static void add_drag_object (ClutterActor *target) { ClutterActor *parent; if (drag == NULL) { ClutterAction *action; drag = clutter_actor_new (); clutter_actor_set_background_color (drag, CLUTTER_COLOR_LightSkyBlue); clutter_actor_set_size (drag, HANDLE_SIZE, HANDLE_SIZE); clutter_actor_set_position (drag, (TARGET_SIZE - HANDLE_SIZE) / 2.0, (TARGET_SIZE - HANDLE_SIZE) / 2.0); clutter_actor_set_reactive (drag, TRUE); action = clutter_drag_action_new (); 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 (drag, action); } parent = clutter_actor_get_parent (drag); if (parent == target) { clutter_actor_save_easing_state (target); clutter_actor_set_easing_mode (target, CLUTTER_LINEAR); clutter_actor_set_opacity (target, 255); clutter_actor_restore_easing_state (target); return; } g_object_ref (drag); if (parent != NULL && parent != stage) { clutter_actor_remove_child (parent, drag); clutter_actor_save_easing_state (parent); clutter_actor_set_easing_mode (parent, CLUTTER_LINEAR); clutter_actor_set_opacity (parent, 64); clutter_actor_restore_easing_state (parent); } clutter_actor_add_child (target, drag); clutter_actor_save_easing_state (target); clutter_actor_set_easing_mode (target, CLUTTER_LINEAR); clutter_actor_set_opacity (target, 255); clutter_actor_restore_easing_state (target); g_object_unref (drag); } static void on_target_over (ClutterDropAction *action, ClutterActor *actor, gpointer _data) { gboolean is_over = GPOINTER_TO_UINT (_data); guint8 final_opacity = is_over ? 128 : 64; ClutterActor *target; target = clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (action)); clutter_actor_save_easing_state (target); clutter_actor_set_easing_mode (target, CLUTTER_LINEAR); clutter_actor_set_opacity (target, final_opacity); clutter_actor_restore_easing_state (target); } static void on_target_drop (ClutterDropAction *action, ClutterActor *actor, gfloat event_x, gfloat event_y) { gfloat actor_x, actor_y; actor_x = actor_y = 0.0f; clutter_actor_transform_stage_point (actor, event_x, event_y, &actor_x, &actor_y); g_print ("Dropped at %.0f, %.0f (screen: %.0f, %.0f)\n", actor_x, actor_y, event_x, event_y); drop_successful = TRUE; add_drag_object (actor); } int main (int argc, char *argv[]) { ClutterActor *dummy; if (clutter_init (&argc, &argv) != CLUTTER_INIT_SUCCESS) return EXIT_FAILURE; stage = clutter_stage_new (); clutter_stage_set_title (CLUTTER_STAGE (stage), "Drop Action"); g_signal_connect (stage, "destroy", G_CALLBACK (clutter_main_quit), NULL); target1 = clutter_actor_new (); clutter_actor_set_background_color (target1, CLUTTER_COLOR_LightScarletRed); clutter_actor_set_size (target1, TARGET_SIZE, TARGET_SIZE); clutter_actor_set_opacity (target1, 64); clutter_actor_add_constraint (target1, clutter_align_constraint_new (stage, CLUTTER_ALIGN_Y_AXIS, 0.5)); clutter_actor_set_x (target1, 10); clutter_actor_set_reactive (target1, TRUE); clutter_actor_add_action_with_name (target1, "drop", clutter_drop_action_new ()); g_signal_connect (clutter_actor_get_action (target1, "drop"), "over-in", G_CALLBACK (on_target_over), GUINT_TO_POINTER (TRUE)); g_signal_connect (clutter_actor_get_action (target1, "drop"), "over-out", G_CALLBACK (on_target_over), GUINT_TO_POINTER (FALSE)); g_signal_connect (clutter_actor_get_action (target1, "drop"), "drop", G_CALLBACK (on_target_drop), NULL); dummy = clutter_actor_new (); clutter_actor_set_background_color (dummy, CLUTTER_COLOR_DarkOrange); clutter_actor_set_size (dummy, 640 - (2 * 10) - (2 * (TARGET_SIZE + 10)), TARGET_SIZE); clutter_actor_add_constraint (dummy, clutter_align_constraint_new (stage, CLUTTER_ALIGN_X_AXIS, 0.5)); clutter_actor_add_constraint (dummy, clutter_align_constraint_new (stage, CLUTTER_ALIGN_Y_AXIS, 0.5)); clutter_actor_set_reactive (dummy, TRUE); target2 = clutter_actor_new (); clutter_actor_set_background_color (target2, CLUTTER_COLOR_LightChameleon); clutter_actor_set_size (target2, TARGET_SIZE, TARGET_SIZE); clutter_actor_set_opacity (target2, 64); clutter_actor_add_constraint (target2, clutter_align_constraint_new (stage, CLUTTER_ALIGN_Y_AXIS, 0.5)); clutter_actor_set_x (target2, 640 - TARGET_SIZE - 10); clutter_actor_set_reactive (target2, TRUE); clutter_actor_add_action_with_name (target2, "drop", clutter_drop_action_new ()); g_signal_connect (clutter_actor_get_action (target2, "drop"), "over-in", G_CALLBACK (on_target_over), GUINT_TO_POINTER (TRUE)); g_signal_connect (clutter_actor_get_action (target2, "drop"), "over-out", G_CALLBACK (on_target_over), GUINT_TO_POINTER (FALSE)); g_signal_connect (clutter_actor_get_action (target2, "drop"), "drop", G_CALLBACK (on_target_drop), NULL); clutter_actor_add_child (stage, target1); clutter_actor_add_child (stage, dummy); clutter_actor_add_child (stage, target2); add_drag_object (target1); clutter_actor_show (stage); clutter_main (); return EXIT_SUCCESS; } |
It's important to note that ClutterDropAction will only work with actors dragged using ClutterDragAction.
ClutterDropAction is available since Clutter 1.8
struct ClutterDropAction;
The ClutterDropAction structure contains only private data and should be accessed using the provided API.
Since 1.8
struct ClutterDropActionClass { 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); };
The ClutterDropActionClass structure contains only private data.
class handler for the "can-drop" signal | |
class handler for the "over-in" signal | |
class handler for the "over-out" signal | |
class handler for the "drop" signal |
Since 1.8
ClutterAction * clutter_drop_action_new (void
);
Creates a new ClutterDropAction.
Use clutter_actor_add_action()
to add the action to a ClutterActor.
Returns : |
the newly created ClutterDropAction |
Since 1.8
"can-drop"
signalgboolean user_function (ClutterDropAction *action,
ClutterActor *actor,
gfloat event_x,
gfloat event_y,
gpointer user_data) : Run Last
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 "drop" signal is going to be
emitted on action
.
The default implementation of ClutterDropAction returns TRUE
for
this signal.
|
the ClutterDropAction that emitted the signal |
|
the ClutterActor attached to the action
|
|
the X coordinate (in stage space) of the drop event |
|
the Y coordinate (in stage space) of the drop event |
|
user data set when the signal handler was connected. |
Returns : |
TRUE if the drop is accepted, and FALSE otherwise |
Since 1.8
"drop"
signalvoid user_function (ClutterDropAction *action,
ClutterActor *actor,
gfloat event_x,
gfloat event_y,
gpointer user_data) : Run Last
The ::drop signal is emitted when the dragged actor is dropped
on actor
. This signal is only emitted if at least an handler of
"can-drop" returns TRUE
.
|
the ClutterDropAction that emitted the signal |
|
the ClutterActor attached to the action
|
|
the X coordinate (in stage space) of the drop event |
|
the Y coordinate (in stage space) of the drop event |
|
user data set when the signal handler was connected. |
Since 1.8
"drop-cancel"
signalvoid user_function (ClutterDropAction *action,
ClutterActor *actor,
gfloat event_x,
gfloat event_y,
gpointer user_data) : Run Last
The ::drop-cancel signal is emitted when the drop is refused by an emission of the "can-drop" signal.
After the ::drop-cancel signal is fired the active drag is terminated.
|
the ClutterDropAction that emitted the signal |
|
the ClutterActor attached to the action
|
|
the X coordinate (in stage space) of the drop event |
|
the Y coordinate (in stage space) of the drop event |
|
user data set when the signal handler was connected. |
Since 1.12
"over-in"
signalvoid user_function (ClutterDropAction *action,
ClutterActor *actor,
gpointer user_data) : Run Last
The ::over-in signal is emitted when the dragged actor crosses
into actor
.
|
the ClutterDropAction that emitted the signal |
|
the ClutterActor attached to the action
|
|
user data set when the signal handler was connected. |
Since 1.8
"over-out"
signalvoid user_function (ClutterDropAction *action,
ClutterActor *actor,
gpointer user_data) : Run Last
The ::over-out signal is emitted when the dragged actor crosses
outside actor
.
|
the ClutterDropAction that emitted the signal |
|
the ClutterActor attached to the action
|
|
user data set when the signal handler was connected. |
Since 1.8