elementary/elm_object_item - added smart callback feature.

SVN revision: 68377
This commit is contained in:
ChunEon Park 2012-02-24 04:31:03 +00:00
parent 30556baca7
commit 9536b08c36
4 changed files with 184 additions and 4 deletions

View File

@ -2095,3 +2095,16 @@ elm_object_item_cursor_engine_only_get(const Elm_Object_Item *it)
{
return elm_widget_item_cursor_engine_only_get(it);
}
EAPI void
elm_object_item_smart_callback_add(Elm_Object_Item *it, const char *event, Elm_Object_Item_Smart_Cb func, const void *data)
{
elm_widget_item_smart_callback_add((Elm_Widget_Item *)it, event, func, data);
}
EAPI void *
elm_object_item_smart_callback_del(Elm_Object_Item *it, const char *event, Elm_Object_Item_Smart_Cb func)
{
return elm_widget_item_smart_callback_del((Elm_Widget_Item *)it, event,
func);
}

View File

@ -1,3 +1,5 @@
typedef void (*Elm_Object_Item_Smart_Cb) (void *data, Elm_Object_Item *it, void *event_info);
/**
* Get the widget object's handle which contains a given item
*
@ -418,7 +420,7 @@ EAPI void elm_object_item_cursor_engine_only_set(Elm_Obj
* searched in its theme, also, or is only relying on the rendering
* engine.
*
* @param item an item
* @param it an object item
* @return @c EINA_TRUE, if cursors are being looked for only on
* those provided by the rendering engine, @c EINA_FALSE if they
* are being searched on the widget's theme, as well.
@ -427,4 +429,54 @@ EAPI void elm_object_item_cursor_engine_only_set(Elm_Obj
*
* @ingroup General
*/
EAPI Eina_Bool elm_object_item_cursor_engine_only_get(const Elm_Object_Item *item);
EAPI Eina_Bool elm_object_item_cursor_engine_only_get(const Elm_Object_Item *it);
/**
* Add (register) a callback function to the smart event specified by @p event
* on the elm_object_item @p it.
*
* @param it an object item
* @param event the event's name string
* @param func the callback function
* @param data user data to be passed to the callback function
*
* Smart callbacks look very similar to Evas Smart callbacks, but are
* implemented as elementary object item's custom ones.
*
* This function adds a function callback to an elementary object item when the
* event named @p event occurs in it. The function is @p func.
*
* A smart callback function must have the Elm_Object_Item_Smart_Cb prototype
* definition. The first parameter (@p data) in this definition will be a user
* specific data. The second parameter @p it is a handle to the object item on
* which event occurred. The third parameter, @p event_info, is a pointer to
* data which is totally dependent on the elementary object item's
* implementation and semantic for the given event.
*
* @see elm_object_item_smart_callback_del()
*
* @ingroup General
*/
EAPI void elm_object_item_smart_callback_add(Elm_Object_Item *it, const char *event, Elm_Object_Item_Smart_Cb func, const void *data);
/**
* Delete (unregister) a callback function from the smart event specified by @p
* event on the elementary object item @p it.
*
* @param it an object item
* @param event the event's name string
* @param func the callback function
* @return data user data.
*
* This function removes <b>the first</b> added smart callback on the item @p it
* matching the event name @p event and the registered function pointer @p func.
* If the removal is successful it will also return the data pointer that was
* passed to elm_object_item_smart_callback_add() (that will be the same as the
* parameter) when the callback(s) was(were) added to the item. If not
* successful @c NULL will be returned.
*
* @see elm_object_item_smart_callback_add()
*
* @ingroup General
*/
EAPI void *elm_object_item_smart_callback_del(Elm_Object_Item *it, const char *event, Elm_Object_Item_Smart_Cb func);

View File

@ -20,6 +20,7 @@ typedef struct _Smart_Data Smart_Data;
typedef struct _Edje_Signal_Data Edje_Signal_Data;
typedef struct _Elm_Event_Cb_Data Elm_Event_Cb_Data;
typedef struct _Elm_Translate_String_Data Elm_Translate_String_Data;
typedef struct _Elm_Widget_Item_Callback Elm_Widget_Item_Callback;
struct _Smart_Data
{
@ -142,6 +143,16 @@ struct _Elm_Translate_String_Data
const char *string;
};
struct _Elm_Widget_Item_Callback
{
const char *event;
Elm_Object_Item_Smart_Cb func;
void *data;
int walking : 1;
Eina_Bool delete_me : 1;
};
/* local subsystem functions */
static void _smart_reconfigure(Smart_Data *sd);
static void _smart_add(Evas_Object *obj);
@ -2832,6 +2843,16 @@ _elm_widget_item_free(Elm_Widget_Item *item)
{
ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
Elm_Object_Item_Smart_Cb cb;
if (item->walking > 0)
{
item->delete_me = EINA_TRUE;
return;
}
EINA_LIST_FREE(item->callbacks, cb) free(cb);
if (item->del_func)
item->del_func((void *)item->data, item->widget, item);
@ -2880,6 +2901,8 @@ _elm_widget_item_del(Elm_Widget_Item *item)
if (item->del_pre_func((Elm_Object_Item *) item))
_elm_widget_item_free(item);
}
else
_elm_widget_item_free(item);
}
/**
@ -3488,6 +3511,87 @@ _elm_widget_item_access_info_set(Elm_Widget_Item *item, const char *txt)
else item->access_info = eina_stringshare_add(txt);
}
EAPI void
elm_widget_item_smart_callback_add(Elm_Widget_Item *item, const char *event, Elm_Object_Item_Smart_Cb func, const void *data)
{
ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
if ((!event) || (!func)) return;
Elm_Widget_Item_Callback *cb = ELM_NEW(Elm_Widget_Item_Callback);
if (!cb) return;
//TODO: apply MEMPOOL?
cb->event = eina_stringshare_add(event);
cb->func = func;
cb->data = (void *)data;
item->callbacks = eina_list_append(item->callbacks, cb);
}
EAPI void*
elm_widget_item_smart_callback_del(Elm_Widget_Item *item, const char *event, Elm_Object_Item_Smart_Cb func)
{
ELM_WIDGET_ITEM_CHECK_OR_RETURN(item, NULL);
Eina_List *l, *l_next;
Elm_Widget_Item_Callback *cb;
if ((!event) || (!func)) return NULL;
EINA_LIST_FOREACH_SAFE(item->callbacks, l, l_next, cb)
{
if ((!strcmp(cb->event, event)) && (cb->func == func))
{
void *data = cb->data;
if (!cb->walking)
{
item->callbacks = eina_list_remove_list(item->callbacks, l);
free(cb);
}
else
cb->delete_me = EINA_TRUE;
return data;
}
}
return NULL;
}
EAPI void
_elm_widget_item_smart_callback_call(Elm_Widget_Item *item, const char *event, void *event_info)
{
ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
Eina_List *l, *l_next;
Elm_Widget_Item_Callback *cb;
const char *strshare;
if (!event) return;
strshare = eina_stringshare_add(event);
EINA_LIST_FOREACH(item->callbacks, l, cb)
{
if (strcmp(cb->event, strshare)) continue;
if (cb->delete_me) continue;
cb->walking++;
item->walking++;
cb->func(cb->data, (Elm_Object_Item *) item, event_info);
item->walking--;
cb->walking--;
if (item->delete_me) break;
}
//Clear callbacks
EINA_LIST_FOREACH_SAFE(item->callbacks, l, l_next, cb)
{
if (!cb->delete_me) continue;
item->callbacks = eina_list_remove_list(item->callbacks, l);
free(cb);
}
if (item->delete_me && !item->walking)
elm_widget_item_free(item);
}
static void
_smart_add(Evas_Object *obj)
{

View File

@ -268,6 +268,7 @@ struct _Elm_Widget_Item
Evas_Smart_Cb del_func;
/**< widget delete callback function. don't expose this callback call */
Elm_Widget_Del_Pre_Cb del_pre_func;
Eina_List *callbacks;
Elm_Widget_Content_Set_Cb content_set_func;
Elm_Widget_Content_Get_Cb content_get_func;
@ -278,9 +279,10 @@ struct _Elm_Widget_Item
Elm_Widget_Disable_Cb disable_func;
Elm_Access_Info *access;
const char *access_info;
Eina_Bool disabled : 1;
/* widget variations should have data from here and on */
/* @todo: TODO check if this is enough for 1.0 release, maybe add padding! */
Eina_Bool walking : 1;
Eina_Bool delete_me : 1;
};
struct _Elm_Object_Item
@ -477,6 +479,9 @@ EAPI void _elm_widget_item_disabled_set(Elm_Widget_Item *item, Eina_
EAPI Eina_Bool _elm_widget_item_disabled_get(const Elm_Widget_Item *item);
EAPI void _elm_widget_item_disable_hook_set(Elm_Widget_Item *item, Elm_Widget_Disable_Cb func);
EAPI void _elm_widget_item_del_pre_hook_set(Elm_Widget_Item *item, Elm_Widget_Del_Pre_Cb func);
EAPI void elm_widget_item_smart_callback_add(Elm_Widget_Item *item, const char *event, Elm_Object_Item_Smart_Cb func, const void *data);
EAPI void *elm_widget_item_smart_callback_del(Elm_Widget_Item *item, const char *event, Elm_Object_Item_Smart_Cb func);
EAPI void _elm_widget_item_smart_callback_call(Elm_Widget_Item *item, const char *event, void *event_info);
/* debug function. don't use it unless you are tracking parenting issues */
EAPI void elm_widget_tree_dump(const Evas_Object *top);
@ -670,6 +675,12 @@ EAPI void elm_widget_tree_dot_dump(const Evas_Object *top, FILE *out
*/
#define elm_widget_item_del_pre_hook_set(item, func) \
_elm_widget_item_del_pre_hook_set((Elm_Widget_Item *)item, (Elm_Widget_Del_Pre_Cb)func)
/**
* Convenience function to query callback call hook
* @see _elm_widget_item_smart_callback_call()
*/
#define elm_widget_item_smart_callback_call(item, event, event_info) \
_elm_widget_item_smart_callback_call((Elm_Widget_Item *) item, event, event_info)
#define ELM_WIDGET_ITEM_CHECK_OR_RETURN(item, ...) \
do { \