1 #include "evas_common.h"
2 #include "evas_private.h"
4 static void evas_object_event_callback_list_post_free(Evas_Object_List **list);
5 static void evas_object_event_callback_clear(Evas_Object *obj);
8 evas_object_event_callback_list_post_free(Evas_Object_List **list)
17 fn = (Evas_Func_Node *)l;
21 *list = evas_object_list_remove(*list, fn);
28 evas_object_event_callback_clear(Evas_Object *obj)
30 if (!obj->callbacks) return;
31 if (!obj->callbacks->deletions_waiting) return;
32 obj->callbacks->deletions_waiting = 0;
33 evas_object_event_callback_list_post_free(&obj->callbacks->callbacks);
34 if (!obj->callbacks->callbacks)
37 obj->callbacks = NULL;
42 evas_object_event_callback_all_del(Evas_Object *obj)
46 if (!obj->callbacks) return;
47 for (l = obj->callbacks->callbacks; l; l = l->next)
51 fn = (Evas_Func_Node *)l;
57 evas_object_event_callback_cleanup(Evas_Object *obj)
60 if (!obj->callbacks) return;
61 evas_object_event_callback_list_post_free(&obj->callbacks->callbacks);
63 obj->callbacks = NULL;
67 evas_object_event_callback_call(Evas_Object *obj, Evas_Callback_Type type, void *event_info)
70 Evas_Object_List **l_mod = NULL, *l;
71 Evas_Button_Flags flags = EVAS_BUTTON_NONE;
74 if (obj->delete_me) return;
75 e = evas_object_evas_get(obj);
80 l_mod = &obj->callbacks->callbacks;
83 case EVAS_CALLBACK_MOUSE_DOWN:
85 Evas_Event_Mouse_Down *ev = event_info;
88 if (ev->flags & (EVAS_BUTTON_DOUBLE_CLICK | EVAS_BUTTON_TRIPLE_CLICK))
90 if (obj->last_mouse_down_counter < (e->last_mouse_down_counter - 1))
91 ev->flags &= ~(EVAS_BUTTON_DOUBLE_CLICK | EVAS_BUTTON_TRIPLE_CLICK);
93 obj->last_mouse_down_counter = e->last_mouse_down_counter;
96 case EVAS_CALLBACK_MOUSE_UP:
98 Evas_Event_Mouse_Up *ev = event_info;
101 if (ev->flags & (EVAS_BUTTON_DOUBLE_CLICK | EVAS_BUTTON_TRIPLE_CLICK))
103 if (obj->last_mouse_up_counter < (e->last_mouse_up_counter - 1))
104 ev->flags &= ~(EVAS_BUTTON_DOUBLE_CLICK | EVAS_BUTTON_TRIPLE_CLICK);
106 obj->last_mouse_up_counter = e->last_mouse_up_counter;
112 obj->callbacks->walking_list++;
113 for (l = *l_mod; l; l = l->next)
117 fn = (Evas_Func_Node *)l;
118 if ((fn->type == type) && (!fn->delete_me))
121 fn->func(fn->data, obj->layer->evas, obj, event_info);
123 if (obj->delete_me) break;
125 obj->callbacks->walking_list--;
126 if (!obj->callbacks->walking_list)
128 evas_object_event_callback_clear(obj);
132 if (type == EVAS_CALLBACK_MOUSE_DOWN)
134 Evas_Event_Mouse_Down *ev = event_info;
137 else if (type == EVAS_CALLBACK_MOUSE_UP)
139 Evas_Event_Mouse_Up *ev = event_info;
144 if (!((obj->no_propagate) && (l_mod) && (*l_mod)))
146 if ((obj->smart.parent) && (type != EVAS_CALLBACK_FREE) &&
147 (type <= EVAS_CALLBACK_KEY_UP))
148 evas_object_event_callback_call(obj->smart.parent, type, event_info);
154 * @defgroup Evas_Object_Callback_Group Object Callback Functions
156 * Functions that add and remove callbacks to evas objects.
160 * @todo Move this next code example and most of the documentation for
161 * this next function into the group documentation.
165 * Add a callback function to an object
166 * @param obj Object to attach a callback to
167 * @param type The type of event that will trigger the callback
168 * @param func The function to be called when the event is triggered
169 * @param data The data pointer to be passed to @p func
171 * This function adds a function callback to an object when the event of type
172 * @p type occurs on object @p obj. The function is @p func.
174 * In the event of a memory allocation error during addition of the callback to
175 * the object, evas_alloc_error() should be used to determine the nature of
176 * the error, if any, and the program should sensibly try and recover.
178 * The function will be passed the pointer @p data when it is called. A
179 * callback function must look like this:
182 * void callback (void *data, Evas *e, Evas_Object *obj, void *event_info);
185 * The first parameter @p data in this function will be the same value passed
186 * to evas_object_event_callback_add() as the @p data parameter. The second
187 * parameter is a convenience for the programmer to know what evas canvas the
188 * event occured on. The third parameter @p obj is the Object handle on which
189 * the event occured. The foruth parameter @p event_info is a pointer to a
190 * data structure that may or may not be passed to the callback, depending on
191 * the event type that triggered the callback.
193 * The event type @p type to trigger the function may be one of
194 * EVAS_CALLBACK_MOUSE_IN, EVAS_CALLBACK_MOUSE_OUT, EVAS_CALLBACK_MOUSE_DOWN,
195 * EVAS_CALLBACK_MOUSE_UP, EVAS_CALLBACK_MOUSE_MOVE, EVAS_CALLBACK_MOUSE_WHEEL,
196 * EVAS_CALLBACK_FREE, EVAS_CALLBACK_KEY_DOWN, EVAS_CALLBACK_KEY_UP,
197 * EVAS_CALLBACK_FOCUS_IN, EVAS_CALLBACK_FOCUS_OUT, EVAS_CALLBACK_SHOW,
198 * EVAS_CALLBACK_HIDE, EVAS_CALLBACK_MOVE, EVAS_CALLBACK_RESIZE or EVAS_CALLBACK_RESTACK.
199 * This determines the kind of event that will trigger the callback to be called.
200 * The @p event_info pointer passed to the callback will be one of the
201 * following, depending on the event triggering it:
203 * EVAS_CALLBACK_MOUSE_IN: event_info = pointer to Evas_Event_Mouse_In
205 * This event is triggered when the mouse pointer enters the region of
206 * the object @p obj. This may occur by the mouse pointer being moved by
207 * evas_event_feed_mouse_move() or evas_event_feed_mouse_move_data() calls,
208 * or by the object being shown, raised, moved, resized, or other objects
209 * being moved out of the way, hidden, lowered or moved out of the way.
211 * EVAS_CALLBACK_MOUSE_OUT: event_info = pointer to Evas_Event_Mouse_Out
213 * This event is triggered exactly like EVAS_CALLBACK_MOUSE_IN is, but occurs
214 * when the mouse pointer exits an object. Note that no out events will be
215 * reported if the mouse pointer is implicitly grabbed to an object (the
216 * mouse buttons are down at all and any were pressed on that object). An
217 * out event will be reported as soon as the mouse is no longer grabbed (no
218 * mouse buttons are depressed). Out events will be reported once all buttons
219 * are released, if the mouse has left the object.
221 * EVAS_CALLBACK_MOUSE_DOWN: event_info = pointer to Evas_Event_Mouse_Down
223 * This event is triggered by a mouse button being depressed while over an
224 * object. If pointermode is EVAS_OBJECT_POINTER_MODE_AUTOGRAB (default)
225 * this causes this object to passively grab the mouse until all mouse
226 * buttons have been released.
227 * That means if this mouse button is the first to be pressed, all future
228 * mouse events will be reported to only this object until no buttons are
229 * down. That includes mouse move events, in and out events, and further
230 * button presses. When all buttons are released, event propagation occurs
233 * EVAS_CALLBACK_MOUSE_UP: event_info = pointer to Evas_Event_Mouse_Up
235 * This event is triggered by a mouse button being released while over an
236 * object or when passively grabbed to an object. If this is the last mouse
237 * button to be raised on an object then the passive grab is released and
238 * event processing will continue as normal.
240 * EVAS_CALLBACK_MOUSE_MOVE: event_info = pointer to Evas_Event_Mouse_Move
242 * This event is triggered by the mouse pointer moving while over an object or
243 * passively grabbed to an object.
245 * EVAS_CALLBACK_MOUSE_WHEEL: event_info = pointer to Evas_Event_Mouse_Wheel
247 * This event is triggered by the mouse wheel being rolled while over an object
248 * or passively grabbed to an object.
250 * EVAS_CALLBACK_FREE: event_info = NULL
252 * This event is triggered just before Evas is about to free all memory used
253 * by an object and remove all references to it. This is useful for programs
254 * to use if they attached data to an object and want to free it when the
255 * object is deleted. The object is still valid when this callback is called,
256 * but after this callback returns, there is no guarantee on the object's
259 * EVAS_CALLBACK_KEY_DOWN: event_info = pointer to Evas_Event_Key_Down
261 * This callback is called when a key is pressed and the focus is on the
262 * object, or a key has been grabbed to a particular object which wants to
263 * intercept the key press regardless of what object has the focus.
265 * EVAS_CALLBACK_KEY_UP: event_info = pointer to Evas_Event_Key_Up
267 * This callback is called when a key is released and the focus is on the
268 * object, or a key has been grabbed to a particular object which wants to
269 * intercept the key release regardless of what object has the focus.
271 * EVAS_CALLBACK_FOCUS_IN: event_info = NULL
273 * This event is called when an object gains the focus. When the callback is
274 * called the object has already gained the focus.
276 * EVAS_CALLBACK_FOCUS_OUT: event_info = NULL
278 * This event is triggered by an object losing the focus. When the callback is
279 * called the object has already lost the focus.
281 * EVAS_CALLBACK_SHOW: event_info = NULL
283 * This event is triggered by the object being shown by evas_object_show().
285 * EVAS_CALLBACK_HIDE: event_info = NULL
287 * This event is triggered by an object being hidden by evas_object_hide().
289 * EVAS_CALLBACK_MOVE: event_info = NULL
291 * This event is triggered by an object being moved. evas_object_move() can
292 * trigger this, as can any object-specific manipulations that would mean the
293 * object's origin could move.
295 * EVAS_CALLBACK_RESIZE: event_info = NULL
297 * This event is triggered by an object being resized. Resizes can be
298 * triggered by evas_object_resize() or by any object-specific calls that may
299 * cause the object to resize.
303 * extern Evas_Object *object;
304 * extern void *my_data;
305 * void down_callback(void *data, Evas *e, Evas_Object *obj, void *event_info);
306 * void up_callback(void *data, Evas *e, Evas_Object *obj, void *event_info);
308 * evas_object_event_callback_add(object, EVAS_CALLBACK_MOUSE_UP, up_callback, my_data);
309 * if (evas_alloc_error() != EVAS_ALLOC_ERROR_NONE)
311 * fprintf(stderr, "ERROR: Callback registering failed! Abort!\n");
314 * evas_object_event_callback_add(object, EVAS_CALLBACK_MOUSE_DOWN, down_callback, my_data);
315 * if (evas_alloc_error() != EVAS_ALLOC_ERROR_NONE)
317 * fprintf(stderr, "ERROR: Callback registering failed! Abort!\n");
321 * @ingroup Evas_Object_Callback_Group
324 evas_object_event_callback_add(Evas_Object *obj, Evas_Callback_Type type, void (*func) (void *data, Evas *e, Evas_Object *obj, void *event_info), const void *data)
329 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
335 fn = evas_mem_calloc(sizeof(Evas_Func_Node));
338 fn->data = (void *)data;
342 obj->callbacks = evas_mem_calloc(sizeof(Evas_Callbacks));
348 obj->callbacks->callbacks =
349 evas_object_list_append(obj->callbacks->callbacks, fn);
353 * Delete a callback function from an object
354 * @param obj Object to remove a callback from
355 * @param type The type of event that was triggering the callback
356 * @param func The function that was to be called when the event was triggered
357 * @return The data pointer that was to be passed to the callback
359 * This function removes the most recently added callback from the object
360 * @p obj which was triggered by the event type @p type and was calling the
361 * function @p func when triggered. If the removal is successful it will also
362 * return the data pointer that was passed to evas_object_event_callback_add()
363 * when the callback was added to the object. If not successful NULL will be
368 * extern Evas_Object *object;
370 * void up_callback(void *data, Evas *e, Evas_Object *obj, void *event_info);
372 * my_data = evas_object_event_callback_del(object, EVAS_CALLBACK_MOUSE_UP, up_callback);
374 * @ingroup Evas_Object_Callback_Group
377 evas_object_event_callback_del(Evas_Object *obj, Evas_Callback_Type type, void (*func) (void *data, Evas *e, Evas_Object *obj, void *event_info))
382 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
386 if (!func) return NULL;
388 if (!obj->callbacks) return NULL;
390 for (l = obj->callbacks->callbacks; l; l = l->next)
394 fn = (Evas_Func_Node *)l;
395 if ((fn->func == func) && (fn->type == type) && (!fn->delete_me))
401 obj->callbacks->deletions_waiting = 1;
402 if (!obj->callbacks->walking_list)
403 evas_object_event_callback_clear(obj);
411 * Delete a callback function from an object
412 * @param obj Object to remove a callback from
413 * @param type The type of event that was triggering the callback
414 * @param func The function that was to be called when the event was triggered
415 * @param data The data pointer that was to be passed to the callback
416 * @return The data pointer that was to be passed to the callback
418 * This function removes the most recently added callback from the object
419 * @p obj which was triggered by the event type @p type and was calling the
420 * function @p func with data @p data when triggered. If the removal is
421 * successful it will also return the data pointer that was passed to
422 * evas_object_event_callback_add() (that will be the same as the parameter)
423 * when the callback was added to the object. If not successful NULL will be
428 * extern Evas_Object *object;
430 * void up_callback(void *data, Evas *e, Evas_Object *obj, void *event_info);
432 * my_data = evas_object_event_callback_del_full(object, EVAS_CALLBACK_MOUSE_UP, up_callback, data);
434 * @ingroup Evas_Object_Callback_Group
437 evas_object_event_callback_del_full(Evas_Object *obj, Evas_Callback_Type type, void (*func) (void *data, Evas *e, Evas_Object *obj, void *event_info), const void *data)
442 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
446 if (!func) return NULL;
448 if (!obj->callbacks) return NULL;
450 for (l = obj->callbacks->callbacks; l; l = l->next)
454 fn = (Evas_Func_Node *)l;
455 if ((fn->func == func) && (fn->type == type) && (fn->data == data) && (!fn->delete_me))
461 obj->callbacks->deletions_waiting = 1;
462 if (!obj->callbacks->walking_list)
463 evas_object_event_callback_clear(obj);