oooh you'd love to know why this is here.. won't you? :)

SVN revision: 48613
This commit is contained in:
Carsten Haitzler 2010-05-04 15:58:10 +00:00
parent 197a9a879e
commit 7041c968bf
8 changed files with 195 additions and 13 deletions

View File

@ -591,9 +591,10 @@ typedef enum _Evas_Object_Pointer_Mode
EVAS_OBJECT_POINTER_MODE_NOGRAB
} Evas_Object_Pointer_Mode; /**< How mouse pointer should be handled by Evas. */
typedef void (*Evas_Smart_Cb) (void *data, Evas_Object *obj, void *event_info);
typedef void (*Evas_Event_Cb) (void *data, Evas *e, void *event_info);
typedef void (*Evas_Object_Event_Cb) (void *data, Evas *e, Evas_Object *obj, void *event_info);
typedef void (*Evas_Smart_Cb) (void *data, Evas_Object *obj, void *event_info);
typedef void (*Evas_Event_Cb) (void *data, Evas *e, void *event_info);
typedef Eina_Bool (*Evas_Object_Event_Post_Cb) (void *data, Evas *e);
typedef void (*Evas_Object_Event_Cb) (void *data, Evas *e, Evas_Object *obj, void *event_info);
#ifdef __cplusplus
extern "C" {
@ -769,10 +770,13 @@ extern "C" {
* @ingroup Evas_Canvas
*/
EAPI void evas_event_callback_add (Evas *e, Evas_Callback_Type type, Evas_Event_Cb func, const void *data) EINA_ARG_NONNULL(1, 3);
EAPI void *evas_event_callback_del (Evas *e, Evas_Callback_Type type, Evas_Event_Cb func) EINA_ARG_NONNULL(1, 3);
EAPI void *evas_event_callback_del_full (Evas *e, Evas_Callback_Type type, Evas_Event_Cb func, const void *data) EINA_ARG_NONNULL(1, 3);
EAPI void evas_event_callback_add (Evas *e, Evas_Callback_Type type, Evas_Event_Cb func, const void *data) EINA_ARG_NONNULL(1, 3);
EAPI void *evas_event_callback_del (Evas *e, Evas_Callback_Type type, Evas_Event_Cb func) EINA_ARG_NONNULL(1, 3);
EAPI void *evas_event_callback_del_full (Evas *e, Evas_Callback_Type type, Evas_Event_Cb func, const void *data) EINA_ARG_NONNULL(1, 3);
EAPI void evas_post_event_callback_push (Evas *e, Evas_Object_Event_Post_Cb func, const void *data);
EAPI void evas_post_event_callback_remove (Evas *e, Evas_Object_Event_Post_Cb func);
EAPI void evas_post_event_callback_remove_full (Evas *e, Evas_Object_Event_Post_Cb func, const void *data);
/**
* @defgroup Evas_Image_Group Image Functions
*

View File

@ -5,6 +5,37 @@ static void evas_object_event_callback_clear(Evas_Object *obj);
static void evas_event_callback_clear(Evas *e);
int _evas_event_counter = 0;
void
_evas_post_event_callback_call(Evas *e)
{
Evas_Post_Callback *pc;
int skip = 0;
if (e->delete_me) return;
_evas_walk(e);
EINA_LIST_FREE(e->post_events, pc)
{
if ((!skip) && (!e->delete_me) && (!pc->delete_me))
{
if (!pc->func(e, pc->data)) skip = 1;
}
free(pc);
}
_evas_unwalk(e);
}
void
_evas_post_event_callback_free(Evas *e)
{
Evas_Post_Callback *pc;
EINA_LIST_FREE(e->post_events, pc)
{
free(pc);
}
_evas_unwalk(e);
}
void
evas_event_callback_list_post_free(Eina_Inlist **list)
{
@ -748,6 +779,109 @@ evas_event_callback_del_full(Evas *e, Evas_Callback_Type type, Evas_Event_Cb fun
return NULL;
}
/**
* Push a callback on the post-event callback stack
*
* @param e Canvas to push the callback on
* @param func The function that to be called when the stack is unwound
* @param data The data pointer to be passed to the callback
*
* Evas has a stack of callbacks that get called after all the callbacks for
* an event have triggered (all the objects it triggers on and al the callbacks
* in each object triggered). When all these have been called, the stack is
* unwond from most recently to least recently pushed item and removed from the
* stack calling the callback set for it.
*
* This is intended for doing reverse logic-like processing, example - when a
* child object that happens to get the event later is meant to be able to
* "steal" functions from a parent and thus on unwind of this stack hav its
* function called first, thus being able to set flags, or return 0 from the
* post-callback that stops all other post-callbacks in the current stack from
* being called (thus basically allowing a child to take control, if the event
* callback prepares information ready for taking action, but the post callback
* actually does the action).
*
*/
EAPI void
evas_post_event_callback_push(Evas *e, Evas_Object_Event_Post_Cb func, const void *data)
{
Evas_Post_Callback *pc;
MAGIC_CHECK(e, Evas, MAGIC_EVAS);
return;
MAGIC_CHECK_END();
pc = evas_mem_calloc(sizeof(Evas_Post_Callback));
if (!pc) return;
if (e->delete_me) return;
pc->func = func;
pc->data = data;
e->post_events = eina_list_prepend(e->post_events, pc);
}
/**
* Remove a callback from the post-event callback stack
*
* @param e Canvas to push the callback on
* @param func The function that to be called when the stack is unwound
*
* This removes a callback from the stack added with
* evas_post_event_callback_push(). The first instance of the function in
* the callback stack is removed from being executed when the stack is
* unwound. Further instances may still be run on unwind.
*/
EAPI void
evas_post_event_callback_remove(Evas *e, Evas_Object_Event_Post_Cb func)
{
Evas_Post_Callback *pc;
Eina_List *l;
MAGIC_CHECK(e, Evas, MAGIC_EVAS);
return;
MAGIC_CHECK_END();
EINA_LIST_FOREACH(e->post_events, l, pc)
{
if (pc->func == func)
{
pc->delete_me = 1;
return;
}
}
}
/**
* Remove a callback from the post-event callback stack
*
* @param e Canvas to push the callback on
* @param func The function that to be called when the stack is unwound
* @param data The data pointer to be passed to the callback
*
* This removes a callback from the stack added with
* evas_post_event_callback_push(). The first instance of the function and data
* in the callback stack is removed from being executed when the stack is
* unwound. Further instances may still be run on unwind.
*/
EAPI void
evas_post_event_callback_remove_full(Evas *e, Evas_Object_Event_Post_Cb func, const void *data)
{
Evas_Post_Callback *pc;
Eina_List *l;
MAGIC_CHECK(e, Evas, MAGIC_EVAS);
return;
MAGIC_CHECK_END();
EINA_LIST_FOREACH(e->post_events, l, pc)
{
if ((pc->func == func) && (pc->data == data))
{
pc->delete_me = 1;
return;
}
}
}
/**
* @}
*/

View File

@ -343,6 +343,7 @@ evas_event_feed_mouse_down(Evas *e, int b, Evas_Button_Flags flags, unsigned int
}
if (copy) eina_list_free(copy);
e->last_mouse_down_counter++;
_evas_post_event_callback_call(e);
_evas_unwalk(e);
}
@ -413,6 +414,7 @@ evas_event_feed_mouse_up(Evas *e, int b, Evas_Button_Flags flags, unsigned int t
}
if (copy) copy = eina_list_free(copy);
e->last_mouse_up_counter++;
_evas_post_event_callback_call(e);
}
if (!e->pointer.button)
@ -455,6 +457,7 @@ evas_event_feed_mouse_up(Evas *e, int b, Evas_Button_Flags flags, unsigned int t
}
if (e->delete_me) break;
}
_evas_post_event_callback_call(e);
}
if (copy) copy = eina_list_free(copy);
if (e->pointer.inside)
@ -489,6 +492,7 @@ evas_event_feed_mouse_up(Evas *e, int b, Evas_Button_Flags flags, unsigned int t
}
if (e->delete_me) break;
}
_evas_post_event_callback_call(e);
}
else
{
@ -603,6 +607,7 @@ evas_event_feed_mouse_wheel(Evas *e, int direction, int z, unsigned int timestam
if (e->delete_me) break;
}
if (copy) copy = eina_list_free(copy);
_evas_post_event_callback_call(e);
_evas_unwalk(e);
}
@ -695,6 +700,7 @@ evas_event_feed_mouse_move(Evas *e, int x, int y, unsigned int timestamp, const
outs = eina_list_append(outs, obj);
if (e->delete_me) break;
}
_evas_post_event_callback_call(e);
}
{
Evas_Event_Mouse_Out ev;
@ -730,6 +736,7 @@ evas_event_feed_mouse_move(Evas *e, int x, int y, unsigned int timestamp, const
evas_object_event_callback_call(obj, EVAS_CALLBACK_MOUSE_OUT, &ev);
}
}
_evas_post_event_callback_call(e);
}
}
else
@ -820,6 +827,7 @@ evas_event_feed_mouse_move(Evas *e, int x, int y, unsigned int timestamp, const
}
if (e->delete_me) break;
}
_evas_post_event_callback_call(e);
_evas_object_event_new();
@ -844,6 +852,7 @@ evas_event_feed_mouse_move(Evas *e, int x, int y, unsigned int timestamp, const
eina_list_free(e->pointer.object.in);
/* and set up the new one */
e->pointer.object.in = ins;
_evas_post_event_callback_call(e);
}
_evas_unwalk(e);
}
@ -912,6 +921,7 @@ evas_event_feed_mouse_in(Evas *e, unsigned int timestamp, const void *data)
e->pointer.object.in = eina_list_free(e->pointer.object.in);
/* and set up the new one */
e->pointer.object.in = ins;
_evas_post_event_callback_call(e);
evas_event_feed_mouse_move(e, e->pointer.x, e->pointer.y, timestamp, data);
_evas_unwalk(e);
}
@ -977,6 +987,7 @@ evas_event_feed_mouse_out(Evas *e, unsigned int timestamp, const void *data)
if (copy) copy = eina_list_free(copy);
/* free our old list of ins */
e->pointer.object.in = eina_list_free(e->pointer.object.in);
_evas_post_event_callback_call(e);
}
_evas_unwalk(e);
}
@ -1040,6 +1051,7 @@ evas_event_feed_multi_down(Evas *e,
if (e->delete_me) break;
}
if (copy) eina_list_free(copy);
_evas_post_event_callback_call(e);
_evas_unwalk(e);
}
@ -1102,7 +1114,7 @@ evas_event_feed_multi_up(Evas *e,
if (e->delete_me) break;
}
if (copy) copy = eina_list_free(copy);
_evas_post_event_callback_call(e);
_evas_unwalk(e);
}
@ -1174,6 +1186,7 @@ evas_event_feed_multi_move(Evas *e,
}
if (e->delete_me) break;
}
_evas_post_event_callback_call(e);
}
else
{
@ -1240,6 +1253,7 @@ evas_event_feed_multi_move(Evas *e,
eina_list_free(e->pointer.object.in);
/* and set up the new one */
e->pointer.object.in = ins;
_evas_post_event_callback_call(e);
}
_evas_unwalk(e);
}
@ -1332,8 +1346,9 @@ evas_event_feed_key_down(Evas *e, const char *keyname, const char *key, const ch
if ((e->focused) && (!exclusive))
{
if (e->events_frozen <= 0)
evas_object_event_callback_call(e->focused, EVAS_CALLBACK_KEY_DOWN, &ev);
evas_object_event_callback_call(e->focused, EVAS_CALLBACK_KEY_DOWN, &ev);
}
_evas_post_event_callback_call(e);
}
_evas_unwalk(e);
}
@ -1426,8 +1441,9 @@ evas_event_feed_key_up(Evas *e, const char *keyname, const char *key, const char
if ((e->focused) && (!exclusive))
{
if (e->events_frozen <= 0)
evas_object_event_callback_call(e->focused, EVAS_CALLBACK_KEY_UP, &ev);
evas_object_event_callback_call(e->focused, EVAS_CALLBACK_KEY_UP, &ev);
}
_evas_post_event_callback_call(e);
}
_evas_unwalk(e);
}
@ -1473,8 +1489,8 @@ evas_event_feed_hold(Evas *e, int hold, unsigned int timestamp, const void *data
if (e->delete_me) break;
}
if (copy) copy = eina_list_free(copy);
_evas_post_event_callback_call(e);
_evas_unwalk(e);
_evas_object_event_new();
}

View File

@ -39,7 +39,7 @@ evas_object_focus_set(Evas_Object *obj, Eina_Bool focus)
if (focus)
{
if (obj->focused) return;
if (obj->focused) goto end;
if (obj->layer->evas->focused)
evas_object_focus_set(obj->layer->evas->focused, 0);
obj->focused = 1;
@ -48,11 +48,13 @@ evas_object_focus_set(Evas_Object *obj, Eina_Bool focus)
}
else
{
if (!obj->focused) return;
if (!obj->focused) goto end;
obj->focused = 0;
obj->layer->evas->focused = NULL;
evas_object_event_callback_call(obj, EVAS_CALLBACK_FOCUS_OUT, NULL);
}
end:
_evas_post_event_callback_call(obj->layer->evas);
}
/**

View File

@ -194,6 +194,8 @@ evas_free(Evas *e)
e->callbacks = NULL;
}
_evas_post_event_callback_free(e);
del = 1;
e->walking_list++;
e->cleanup = 1;

View File

@ -9,6 +9,7 @@ evas_object_inform_call_show(Evas_Object *obj)
_evas_object_event_new();
evas_object_event_callback_call(obj, EVAS_CALLBACK_SHOW, NULL);
_evas_post_event_callback_call(obj->layer->evas);
}
void
@ -17,6 +18,7 @@ evas_object_inform_call_hide(Evas_Object *obj)
_evas_object_event_new();
evas_object_event_callback_call(obj, EVAS_CALLBACK_HIDE, NULL);
_evas_post_event_callback_call(obj->layer->evas);
}
void
@ -25,6 +27,7 @@ evas_object_inform_call_move(Evas_Object *obj)
_evas_object_event_new();
evas_object_event_callback_call(obj, EVAS_CALLBACK_MOVE, NULL);
_evas_post_event_callback_call(obj->layer->evas);
}
void
@ -33,6 +36,7 @@ evas_object_inform_call_resize(Evas_Object *obj)
_evas_object_event_new();
evas_object_event_callback_call(obj, EVAS_CALLBACK_RESIZE, NULL);
_evas_post_event_callback_call(obj->layer->evas);
}
void
@ -41,6 +45,7 @@ evas_object_inform_call_restack(Evas_Object *obj)
_evas_object_event_new();
evas_object_event_callback_call(obj, EVAS_CALLBACK_RESTACK, NULL);
_evas_post_event_callback_call(obj->layer->evas);
}
void
@ -49,6 +54,7 @@ evas_object_inform_call_changed_size_hints(Evas_Object *obj)
_evas_object_event_new();
evas_object_event_callback_call(obj, EVAS_CALLBACK_CHANGED_SIZE_HINTS, NULL);
_evas_post_event_callback_call(obj->layer->evas);
}
void
@ -57,4 +63,5 @@ evas_object_inform_call_image_preloaded(Evas_Object *obj)
_evas_object_event_new();
evas_object_event_callback_call(obj, EVAS_CALLBACK_IMAGE_PRELOADED, NULL);
_evas_post_event_callback_call(obj->layer->evas);
}

View File

@ -371,6 +371,7 @@ evas_object_del(Evas_Object *obj)
_evas_object_event_new();
evas_object_event_callback_call(obj, EVAS_CALLBACK_DEL, NULL);
_evas_post_event_callback_call(obj->layer->evas);
if (obj->name) evas_object_name_set(obj, NULL);
if (!obj->layer)
{
@ -383,6 +384,7 @@ evas_object_del(Evas_Object *obj)
obj->layer->evas->focused = NULL;
_evas_object_event_new();
evas_object_event_callback_call(obj, EVAS_CALLBACK_FOCUS_OUT, NULL);
_evas_post_event_callback_call(obj->layer->evas);
}
obj->layer->evas->pointer.mouse_grabbed -= obj->mouse_grabbed;
obj->mouse_grabbed = 0;
@ -394,6 +396,7 @@ evas_object_del(Evas_Object *obj)
evas_object_map_set(obj, NULL);
_evas_object_event_new();
evas_object_event_callback_call(obj, EVAS_CALLBACK_FREE, NULL);
_evas_post_event_callback_call(obj->layer->evas);
evas_object_smart_cleanup(obj);
obj->delete_me = 1;
evas_object_change(obj);
@ -1174,6 +1177,7 @@ evas_object_hide(Evas_Object *obj)
ev.timestamp = obj->layer->evas->last_timestamp;
ev.event_flags = EVAS_EVENT_FLAG_NONE;
evas_object_event_callback_call(obj, EVAS_CALLBACK_MOUSE_OUT, &ev);
_evas_post_event_callback_call(obj->layer->evas);
}
}
}

View File

@ -50,6 +50,7 @@ typedef struct _Evas_Callbacks Evas_Callbacks;
typedef struct _Evas_Format Evas_Format;
typedef struct _Evas_Map_Point Evas_Map_Point;
typedef struct _Evas_Smart_Cb_Description_Array Evas_Smart_Cb_Description_Array;
typedef struct _Evas_Post_Callback Evas_Post_Callback;
#define MAGIC_EVAS 0x70777770
#define MAGIC_OBJ 0x71777770
@ -213,6 +214,14 @@ struct _Evas_Lock
Evas_Modifier_Mask mask; /* we have a max of 64 locks */
};
struct _Evas_Post_Callback
{
Evas_Object *obj;
Evas_Object_Event_Post_Cb func;
const void *data;
unsigned char delete_me : 1;
};
struct _Evas_Callbacks
{
Eina_Inlist *callbacks;
@ -304,6 +313,8 @@ struct _Evas
Eina_Array calculate_objects;
Eina_Array clip_changes;
Eina_List *post_events; // free me on evas_free
Evas_Callbacks *callbacks;
int delete_grabs;
@ -790,6 +801,8 @@ void evas_object_smart_member_stack_below(Evas_Object *member, Evas_Object *othe
const Eina_Inlist *evas_object_smart_members_get_direct(const Evas_Object *obj);
void evas_call_smarts_calculate(Evas *e);
void *evas_mem_calloc(int size);
void _evas_post_event_callback_call(Evas *e);
void _evas_post_event_callback_free(Evas *e);
void evas_event_callback_list_post_free(Eina_Inlist **list);
void evas_object_event_callback_all_del(Evas_Object *obj);
void evas_object_event_callback_cleanup(Evas_Object *obj);