From a626a91d69d67199e077c138648183e896f1cc1e Mon Sep 17 00:00:00 2001 From: Cedric Bail Date: Thu, 5 Sep 2013 17:15:58 +0900 Subject: [PATCH] evas: add evas_object_smart_iterator_new(). This is going to break Eo ABI. Rebuild all software using Eo API on top of EFL (Elementary for example). --- ChangeLog | 4 ++ NEWS | 1 + src/lib/evas/Evas_Eo.h | 16 +++++ src/lib/evas/Evas_Legacy.h | 16 +++++ src/lib/evas/canvas/evas_object_smart.c | 82 +++++++++++++++++++++++++ 5 files changed, 119 insertions(+) diff --git a/ChangeLog b/ChangeLog index 27c321a6f7..f115014244 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2013-09-05 Cedric Bail + + * Evas: Add evas_object_smart_iterator_new(). + 2013-09-04 Michael Bouchaud (yoz) * fix edje_object_scale_set to be recursive diff --git a/NEWS b/NEWS index 1da60c23f4..0794a9efc7 100644 --- a/NEWS +++ b/NEWS @@ -209,6 +209,7 @@ Improvements: - Asynchronous preload of GL texture. - Add neon assembly for upscaling and map routines - Use mmap/munmap for image data allocation on system that have mmap. + - Add iterator for walking child of smart objects, table and a box. * Ecore_Con: - Rebase dns.c against upstream * Edje: diff --git a/src/lib/evas/Evas_Eo.h b/src/lib/evas/Evas_Eo.h index e4b83e8034..232483107b 100644 --- a/src/lib/evas/Evas_Eo.h +++ b/src/lib/evas/Evas_Eo.h @@ -2978,6 +2978,7 @@ enum EVAS_OBJ_SMART_SUB_ID_MEMBER_ADD, EVAS_OBJ_SMART_SUB_ID_MEMBER_DEL, EVAS_OBJ_SMART_SUB_ID_MEMBERS_GET, + EVAS_OBJ_SMART_SUB_ID_ITERATOR_NEW, EVAS_OBJ_SMART_SUB_ID_CALLBACKS_DESCRIPTIONS_SET, EVAS_OBJ_SMART_SUB_ID_CALLBACKS_DESCRIPTIONS_GET, EVAS_OBJ_SMART_SUB_ID_CALLBACK_DESCRIPTION_FIND, @@ -3059,9 +3060,24 @@ enum * @param[out] list out * * @see evas_object_smart_members_get + * @see evas_object_smart_iterator_new */ #define evas_obj_smart_members_get(list) EVAS_OBJ_SMART_ID(EVAS_OBJ_SMART_SUB_ID_MEMBERS_GET), EO_TYPECHECK(Eina_List **, list) +/** + * @def evas_obj_smart_iterator_new + * @since 1.8 + * + * Retrieves an iterator of the member objects of a given Evas smart + * object + * + * @param[out] iterator out + * + * @see evas_object_smart_iterator_new + * @see evas_object_smart_members_get + */ +#define evas_obj_smart_iterator_new(it) EVAS_OBJ_SMART_ID(EVAS_OBJ_SMART_SUB_ID_ITERATOR_NEW), EO_TYPECHECK(Eina_Iterator **, it) + /** * @def evas_obj_smart_callback_priority_add * @since 1.8 diff --git a/src/lib/evas/Evas_Legacy.h b/src/lib/evas/Evas_Legacy.h index 25fec60284..5294ce7909 100644 --- a/src/lib/evas/Evas_Legacy.h +++ b/src/lib/evas/Evas_Legacy.h @@ -6322,9 +6322,25 @@ EAPI void evas_object_smart_member_del(Evas_Object *obj) EINA_ARG_NONNUL * * @see evas_object_smart_member_add() * @see evas_object_smart_member_del() + * @see evas_object_smart_iterator_new() */ EAPI Eina_List *evas_object_smart_members_get(const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1); +/** + * Retrieves an iterator of the member objects of a given Evas smart + * object + * + * @param obj the smart object to get members from + * @return Returns the iterator of the member objects of @p obj. + * + * @since 1.8 + * + * @see evas_object_smart_member_add() + * @see evas_object_smart_member_del() + * @see evas_object_smart_members_get() + */ +EAPI Eina_Iterator *evas_object_smart_iterator_new(const Evas_Object *obj) EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1); + /** * Gets the parent smart object of a given Evas object, if it has one. * diff --git a/src/lib/evas/canvas/evas_object_smart.c b/src/lib/evas/canvas/evas_object_smart.c index 8b1d8853b9..f3f26311b3 100644 --- a/src/lib/evas/canvas/evas_object_smart.c +++ b/src/lib/evas/canvas/evas_object_smart.c @@ -51,6 +51,16 @@ typedef struct _Evas_Event_Description *desc; } _eo_evas_smart_cb_info; + +typedef struct _Evas_Object_Smart_Iterator Evas_Object_Smart_Iterator; +struct _Evas_Object_Smart_Iterator +{ + Eina_Iterator iterator; + + const Eina_Inlist *current; + Evas_Object *parent; +}; + static Eina_Bool _eo_evas_smart_cb(void *data, Eo *eo_obj, const Eo_Event_Description *desc EINA_UNUSED, void *event_info) { @@ -447,6 +457,76 @@ evas_smart_legacy_type_register(const char *type, const Eo_Class *klass) eina_hash_set(_evas_smart_class_names_hash_table, type, klass); } +static Eina_Bool +_evas_object_smart_iterator_next(Evas_Object_Smart_Iterator *it, void **data) +{ + Evas_Object *eo; + + if (!it->current) return EINA_FALSE; + + eo = ((const Evas_Object_Protected_Data*)(it->current))->object; + if (data) *data = eo; + + it->current = it->current->next; + + return EINA_TRUE; +} + +static Evas_Object * +_evas_object_smart_iterator_get_container(Evas_Object_Smart_Iterator *it) +{ + return it->parent; +} + +static void +_evas_object_smart_iterator_free(Evas_Object_Smart_Iterator *it) +{ + eo_unref(it->parent); + free(it); +} + +// Should we have an eo_children_iterator_new API and just inherit from it ? +EAPI Eina_Iterator * +evas_object_smart_iterator_new(const Evas_Object *o) +{ + Eina_Iterator *ret = NULL; + eo_do((Eo *)o, evas_obj_smart_iterator_new(&ret)); + return ret; +} + +static void +_iterator_new(Eo *o, void *_pd, va_list *list) +{ + Eina_Iterator **ret = va_arg(*list, Eina_Iterator **); + + Evas_Object_Smart_Iterator *it; + + const Evas_Object_Smart *priv = _pd; + + if (!priv->contained) + { + *ret = NULL; + return ; + } + + it = calloc(1, sizeof(Evas_Object_Smart_Iterator)); + if (!it) + { + *ret = NULL; + return ; + } + + EINA_MAGIC_SET(&it->iterator, EINA_MAGIC_ITERATOR); + it->parent = eo_ref(o); + it->current = priv->contained; + + it->iterator.next = FUNC_ITERATOR_NEXT(_evas_object_smart_iterator_next); + it->iterator.get_container = FUNC_ITERATOR_GET_CONTAINER(_evas_object_smart_iterator_get_container); + it->iterator.free = FUNC_ITERATOR_FREE(_evas_object_smart_iterator_free); + + *ret = &it->iterator; +} + EAPI Eina_List * evas_object_smart_members_get(const Evas_Object *eo_obj) { @@ -1709,6 +1789,7 @@ _class_constructor(Eo_Class *klass) EO_OP_FUNC(EVAS_OBJ_SMART_ID(EVAS_OBJ_SMART_SUB_ID_MEMBER_ADD), _smart_member_add), EO_OP_FUNC(EVAS_OBJ_SMART_ID(EVAS_OBJ_SMART_SUB_ID_MEMBER_DEL), _smart_member_del), EO_OP_FUNC(EVAS_OBJ_SMART_ID(EVAS_OBJ_SMART_SUB_ID_MEMBERS_GET), _smart_members_get), + EO_OP_FUNC(EVAS_OBJ_SMART_ID(EVAS_OBJ_SMART_SUB_ID_ITERATOR_NEW), _iterator_new), EO_OP_FUNC(EVAS_OBJ_SMART_ID(EVAS_OBJ_SMART_SUB_ID_CALLBACKS_DESCRIPTIONS_SET), _smart_callbacks_descriptions_set), EO_OP_FUNC(EVAS_OBJ_SMART_ID(EVAS_OBJ_SMART_SUB_ID_CALLBACKS_DESCRIPTIONS_GET), _smart_callbacks_descriptions_get), EO_OP_FUNC(EVAS_OBJ_SMART_ID(EVAS_OBJ_SMART_SUB_ID_CALLBACK_DESCRIPTION_FIND), _smart_callback_description_find), @@ -1749,6 +1830,7 @@ static const Eo_Op_Description op_desc[] = { EO_OP_DESCRIPTION(EVAS_OBJ_SMART_SUB_ID_MEMBER_ADD, "Set an Evas object as a member of a given smart object."), EO_OP_DESCRIPTION(EVAS_OBJ_SMART_SUB_ID_MEMBER_DEL, "Removes a member object from a given smart object."), EO_OP_DESCRIPTION(EVAS_OBJ_SMART_SUB_ID_MEMBERS_GET, "Retrieves the list of the member objects of a given Evas smart"), + EO_OP_DESCRIPTION(EVAS_OBJ_SMART_SUB_ID_ITERATOR_NEW, "Retrieves an iterator of the member object of a given Evas smart"), EO_OP_DESCRIPTION(EVAS_OBJ_SMART_SUB_ID_CALLBACKS_DESCRIPTIONS_SET, "Set an smart object instance's smart callbacks descriptions."), EO_OP_DESCRIPTION(EVAS_OBJ_SMART_SUB_ID_CALLBACKS_DESCRIPTIONS_GET, "Retrieve an smart object's know smart callback descriptions (both"), EO_OP_DESCRIPTION(EVAS_OBJ_SMART_SUB_ID_CALLBACK_DESCRIPTION_FIND, "Find callback description for callback called name."),