Evas callbacks: Added priority to evas callbacks.

This includes evas_event, evas_object_event and evas_object_smart
callbacks.
See the added docs for more info.

SVN revision: 62533
This commit is contained in:
Tom Hacohen 2011-08-17 11:55:29 +00:00
parent b5a619847e
commit ef8476152d
9 changed files with 284 additions and 7 deletions

View File

@ -461,3 +461,7 @@
* Textblock: Added evas_textblock_cursor_visible_range_get which
updates the cursors to the ends of the area currently visible on
screen.
2011-08-17 Tom Hacohen (TAsn)
* Callbacks: Added priority support to callbacks.

View File

@ -432,6 +432,39 @@ typedef enum _Evas_Callback_Type
EVAS_CALLBACK_LAST /**< kept as last element/sentinel -- not really an event */
} Evas_Callback_Type; /**< The types of events triggering a callback */
/**
* @def EVAS_CALLBACK_PRIORITY_BEFORE
* Slightly more prioritized than default.
* @since 1.1.0
*/
#define EVAS_CALLBACK_PRIORITY_BEFORE -100
/**
* @def EVAS_CALLBACK_PRIORITY_DEFAULT
* Default callback priority level
* @since 1.1.0
*/
#define EVAS_CALLBACK_PRIORITY_DEFAULT 0
/**
* @def EVAS_CALLBACK_PRIORITY_AFTER
* Slightly less prioritized than default.
* @since 1.1.0
*/
#define EVAS_CALLBACK_PRIORITY_AFTER 100
/**
* @typedef Evas_Callback_Priority
*
* Callback priority value. Range is -32k - 32k. The lower the number, the
* bigger the priority.
*
* @see EVAS_CALLBACK_PRIORITY_AFTER
* @see EVAS_CALLBACK_PRIORITY_BEFORE
* @see EVAS_CALLBACK_PRIORITY_DEFAULT
*
* @since 1.1.0
*/
typedef short Evas_Callback_Priority;
/**
* Flags for Mouse Button events
*/
@ -2103,6 +2136,23 @@ EAPI Eina_Bool evas_pointer_inside_get (const Evas *e) EINA_WA
*/
EAPI void evas_event_callback_add (Evas *e, Evas_Callback_Type type, Evas_Event_Cb func, const void *data) EINA_ARG_NONNULL(1, 3);
/**
* Add (register) a callback function to a given canvas event with a
* non-default priority set. Except for the priority field, it's exactly the
* same as @ref evas_event_callback_add
*
* @param e Canvas to attach a callback to
* @param type The type of event that will trigger the callback
* @param priority The priority of the callback, lower values called first.
* @param func The (callback) function to be called when the event is
* triggered
* @param data The data pointer to be passed to @p func
*
* @see evas_event_callback_add
* @since 1.1.0
*/
EAPI void evas_event_callback_priority_add(Evas *e, Evas_Callback_Type type, Evas_Callback_Priority priority, Evas_Event_Cb func, const void *data) EINA_ARG_NONNULL(1, 4);
/**
* Delete a callback function from the canvas.
*
@ -3708,6 +3758,22 @@ EAPI Evas_Object *evas_object_below_get (const Evas_Object *obj
*/
EAPI void evas_object_event_callback_add (Evas_Object *obj, Evas_Callback_Type type, Evas_Object_Event_Cb func, const void *data) EINA_ARG_NONNULL(1, 3);
/**
* Add (register) a callback function to a given Evas object event with a
* non-default priority set. Except for the priority field, it's exactly the
* same as @ref evas_object_event_callback_add
*
* @param obj Object to attach a callback to
* @param type The type of event that will trigger the callback
* @param priority The priority of the callback, lower values called first.
* @param func The function to be called when the event is triggered
* @param data The data pointer to be passed to @p func
*
* @see evas_object_event_callback_add
* @since 1.1.0
*/
EAPI void evas_object_event_callback_priority_add(Evas_Object *obj, Evas_Callback_Type type, Evas_Callback_Priority priority, Evas_Object_Event_Cb func, const void *data) EINA_ARG_NONNULL(1, 4);
/**
* Delete a callback function from an object
*
@ -9439,6 +9505,23 @@ EAPI void evas_object_smart_data_set (Evas_Object *obj, void
*/
EAPI void evas_object_smart_callback_add (Evas_Object *obj, const char *event, Evas_Smart_Cb func, const void *data) EINA_ARG_NONNULL(1, 2, 3);
/**
* Add (register) a callback function to the smart event specified by
* @p event on the smart object @p obj. Except for the priority field,
* it's exactly the same as @ref evas_object_smart_callback_add
*
* @param obj a smart object
* @param event the event's name string
* @param priority The priority of the callback, lower values called first.
* @param func the callback function
* @param data user data to be passed to the callback function
*
* @see evas_object_smart_callback_add
* @since 1.1.0
* @ingroup Evas_Smart_Object_Group
*/
EAPI void evas_object_smart_callback_priority_add(Evas_Object *obj, const char *event, Evas_Callback_Priority priority, Evas_Smart_Cb func, const void *data);
/**
* Delete (unregister) a callback function from the smart event
* specified by @p event on the smart object @p obj.

View File

@ -256,10 +256,29 @@ evas_object_event_callback_call(Evas_Object *obj, Evas_Callback_Type type, void
_evas_unwalk(e);
}
static int
_callback_priority_cmp(const void *_a, const void *_b)
{
const Evas_Func_Node *a, *b;
a = EINA_INLIST_CONTAINER_GET(_a, Evas_Func_Node);
b = EINA_INLIST_CONTAINER_GET(_b, Evas_Func_Node);
if (a->priority < b->priority)
return -1;
else if (a->priority == b->priority)
return 0;
else
return 1;
}
EAPI void
evas_object_event_callback_add(Evas_Object *obj, Evas_Callback_Type type, Evas_Object_Event_Cb func, const void *data)
{
evas_object_event_callback_priority_add(obj, type,
EVAS_CALLBACK_PRIORITY_DEFAULT, func, data);
}
EAPI void
evas_object_event_callback_priority_add(Evas_Object *obj, Evas_Callback_Type type, Evas_Callback_Priority priority, Evas_Object_Event_Cb func, const void *data)
{
/* MEM OK */
Evas_Func_Node *fn;
@ -285,9 +304,11 @@ evas_object_event_callback_add(Evas_Object *obj, Evas_Callback_Type type, Evas_O
fn->func = func;
fn->data = (void *)data;
fn->type = type;
fn->priority = priority;
obj->callbacks->callbacks =
eina_inlist_prepend(obj->callbacks->callbacks, EINA_INLIST_GET(fn));
eina_inlist_sorted_insert(obj->callbacks->callbacks, EINA_INLIST_GET(fn),
_callback_priority_cmp);
}
EAPI void *
@ -352,10 +373,15 @@ evas_object_event_callback_del_full(Evas_Object *obj, Evas_Callback_Type type, E
return NULL;
}
EAPI void
evas_event_callback_add(Evas *e, Evas_Callback_Type type, Evas_Event_Cb func, const void *data)
{
evas_event_callback_priority_add(e, type, EVAS_CALLBACK_PRIORITY_DEFAULT,
func, data);
}
EAPI void
evas_event_callback_priority_add(Evas *e, Evas_Callback_Type type, Evas_Callback_Priority priority, Evas_Event_Cb func, const void *data)
{
/* MEM OK */
Evas_Func_Node *fn;
@ -381,9 +407,10 @@ evas_event_callback_add(Evas *e, Evas_Callback_Type type, Evas_Event_Cb func, co
fn->func = func;
fn->data = (void *)data;
fn->type = type;
fn->priority = priority;
e->callbacks->callbacks =
eina_inlist_prepend(e->callbacks->callbacks, EINA_INLIST_GET(fn));
e->callbacks->callbacks = eina_inlist_sorted_insert(e->callbacks->callbacks,
EINA_INLIST_GET(fn), _callback_priority_cmp);
}
EAPI void *

View File

@ -22,6 +22,7 @@ struct _Evas_Smart_Callback
const char *event;
Evas_Smart_Cb func;
void *func_data;
Evas_Callback_Priority priority;
char delete_me : 1;
};
@ -324,8 +325,29 @@ evas_object_smart_add(Evas *e, Evas_Smart *s)
return obj;
}
static int
_callback_priority_cmp(const void *_a, const void *_b)
{
const Evas_Smart_Callback *a, *b;
a = (const Evas_Smart_Callback *) _a;
b = (const Evas_Smart_Callback *) _b;
if (a->priority < b->priority)
return -1;
else if (a->priority == b->priority)
return 0;
else
return 1;
}
EAPI void
evas_object_smart_callback_add(Evas_Object *obj, const char *event, Evas_Smart_Cb func, const void *data)
{
evas_object_smart_callback_priority_add(obj, event,
EVAS_CALLBACK_PRIORITY_DEFAULT, func, data);
}
EAPI void
evas_object_smart_callback_priority_add(Evas_Object *obj, const char *event, Evas_Callback_Priority priority, Evas_Smart_Cb func, const void *data)
{
Evas_Object_Smart *o;
Evas_Smart_Callback *cb;
@ -346,7 +368,9 @@ evas_object_smart_callback_add(Evas_Object *obj, const char *event, Evas_Smart_C
cb->event = eina_stringshare_add(event);
cb->func = func;
cb->func_data = (void *)data;
o->callbacks = eina_list_prepend(o->callbacks, cb);
cb->priority = priority;
o->callbacks = eina_list_sorted_insert(o->callbacks, _callback_priority_cmp,
cb);
}
EAPI void *

View File

@ -553,6 +553,7 @@ struct _Evas_Func_Node
void (*func) ();
void *data;
Evas_Callback_Type type;
Evas_Callback_Priority priority;
unsigned char delete_me : 1;
};

View File

@ -20,6 +20,7 @@ evas_suite.c \
evas_test_init.c \
evas_test_textblock.c \
evas_test_text.c \
evas_test_callbacks.c \
evas_tests_helpers.h \
evas_suite.h

View File

@ -21,6 +21,7 @@ static const Evas_Test_Case etc[] = {
{ "Evas", evas_test_init },
{ "Object Textblock", evas_test_textblock },
{ "Object Text", evas_test_text },
{ "Callbacks", evas_test_callbacks },
{ NULL, NULL }
};

View File

@ -6,6 +6,7 @@
void evas_test_init(TCase *tc);
void evas_test_textblock(TCase *tc);
void evas_test_text(TCase *tc);
void evas_test_callbacks(TCase *tc);
#endif /* _EVAS_SUITE_H */

View File

@ -0,0 +1,135 @@
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <stdio.h>
#include "evas_suite.h"
#include "Evas.h"
#include "evas_tests_helpers.h"
#define START_CALLBACK_TEST() \
Evas *evas; \
Evas_Object *rect; \
evas = EVAS_TEST_INIT_EVAS(); \
rect = evas_object_rectangle_add(evas); \
do \
{ \
} \
while (0)
#define END_CALLBACK_TEST() \
do \
{ \
evas_object_del(rect); \
evas_free(evas); \
evas_shutdown(); \
} \
while (0)
static int counter = 1;
static void
_obj_event_cb(void *data, Evas *e, Evas_Object *obj, void *event_info)
{
(void) e;
(void) obj;
(void) event_info;
fail_if(((int) data) != counter);
counter++;
}
START_TEST(evas_object_event_callbacks_priority)
{
START_CALLBACK_TEST();
counter = 1;
evas_object_event_callback_priority_add(rect, EVAS_CALLBACK_MOVE, -10,
_obj_event_cb, (void *) 1);
evas_object_event_callback_priority_add(rect, EVAS_CALLBACK_MOVE, 0,
_obj_event_cb, (void *) 2);
evas_object_event_callback_priority_add(rect, EVAS_CALLBACK_MOVE, 10,
_obj_event_cb, (void *) 3);
evas_object_move(rect, 2, 2);
/* Make sure we got through all the callbacks */
fail_if(counter != 4);
/* Delete _obj_event_cb 3 times */
evas_object_event_callback_del(rect, EVAS_CALLBACK_MOVE, _obj_event_cb);
evas_object_event_callback_del(rect, EVAS_CALLBACK_MOVE, _obj_event_cb);
evas_object_event_callback_del(rect, EVAS_CALLBACK_MOVE, _obj_event_cb);
counter = 1;
evas_object_event_callback_priority_add(rect, EVAS_CALLBACK_MOVE, 0,
_obj_event_cb, (void *) 2);
evas_object_event_callback_priority_add(rect, EVAS_CALLBACK_MOVE, -10,
_obj_event_cb, (void *) 1);
evas_object_event_callback_priority_add(rect, EVAS_CALLBACK_MOVE, 10,
_obj_event_cb, (void *) 3);
evas_object_move(rect, 3, 3);
/* Make sure we got through all the callbacks */
fail_if(counter != 4);
END_CALLBACK_TEST();
}
END_TEST
static void
_event_cb(void *data, Evas *e, void *event_info)
{
(void) e;
(void) event_info;
fail_if(((int) data) != counter);
counter++;
}
START_TEST(evas_event_callbacks_priority)
{
START_CALLBACK_TEST();
evas_object_focus_set(rect, EINA_FALSE);
counter = 1;
evas_event_callback_priority_add(evas, EVAS_CALLBACK_CANVAS_OBJECT_FOCUS_IN,
-10, _event_cb, (void *) 1);
evas_event_callback_priority_add(evas, EVAS_CALLBACK_CANVAS_OBJECT_FOCUS_IN,
0, _event_cb, (void *) 2);
evas_event_callback_priority_add(evas, EVAS_CALLBACK_CANVAS_OBJECT_FOCUS_IN,
10, _event_cb, (void *) 3);
evas_object_focus_set(rect, EINA_TRUE);
/* Make sure we got through all the callbacks */
fail_if(counter != 4);
/* Delete _event_cb 3 times */
evas_event_callback_del(evas, EVAS_CALLBACK_CANVAS_OBJECT_FOCUS_IN,
_event_cb);
evas_event_callback_del(evas, EVAS_CALLBACK_CANVAS_OBJECT_FOCUS_IN,
_event_cb);
evas_event_callback_del(evas, EVAS_CALLBACK_CANVAS_OBJECT_FOCUS_IN,
_event_cb);
evas_object_focus_set(rect, EINA_FALSE);
counter = 1;
evas_event_callback_priority_add(evas, EVAS_CALLBACK_CANVAS_OBJECT_FOCUS_IN,
0, _event_cb, (void *) 2);
evas_event_callback_priority_add(evas, EVAS_CALLBACK_CANVAS_OBJECT_FOCUS_IN,
-10, _event_cb, (void *) 1);
evas_event_callback_priority_add(evas, EVAS_CALLBACK_CANVAS_OBJECT_FOCUS_IN,
10, _event_cb, (void *) 3);
evas_object_focus_set(rect, EINA_TRUE);
/* Make sure we got through all the callbacks */
fail_if(counter != 4);
END_CALLBACK_TEST();
}
END_TEST
void evas_test_callbacks(TCase *tc)
{
tcase_add_test(tc, evas_object_event_callbacks_priority);
tcase_add_test(tc, evas_event_callbacks_priority);
}