Just delete children and related from del_pre_hook, not del_hook!

At del_hook() stuff are already gone and invalid access may
happen. Doing it from del_pre_hook you still have things working nice.

Also refactor the destructor to do recursion and stop allocate list
nodes to avoid it... simpler.



SVN revision: 52114
This commit is contained in:
Gustavo Sverzut Barbieri 2010-09-10 01:35:46 +00:00
parent 17ac79248f
commit c559b06577
1 changed files with 25 additions and 18 deletions

View File

@ -54,36 +54,43 @@ static void _submenu_open(void *data, Evas_Object *obj, const char *emission, co
static void _parent_resize(void *data, Evas *e, Evas_Object *obj, void *event_info);
static void _menu_hide(void *data, Evas_Object *obj, void *event_info);
static void
_del_item(Elm_Menu_Item *item)
{
Elm_Menu_Item *child;
if (item->del_cb) item->del_cb((void*)item->data, item->o, item);
EINA_LIST_FREE(item->items, child)
_del_item(child);
if (item->label) eina_stringshare_del(item->label);
if (item->hv) evas_object_del(item->hv);
if (item->location) evas_object_del(item->location);
if (item->o) evas_object_del(item->o);
free(item);
}
static void
_del_pre_hook(Evas_Object *obj)
{
Elm_Menu_Item *item;
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return;
evas_object_event_callback_del_full(wd->parent, EVAS_CALLBACK_RESIZE, _parent_resize, obj);
EINA_LIST_FREE(wd->items, item)
_del_item(item);
if (wd->hv) evas_object_del(wd->hv);
if (wd->location) evas_object_del(wd->location);
}
static void
_del_hook(Evas_Object *obj)
{
Eina_List *l, *ll = NULL;
Elm_Menu_Item *item;
Widget_Data *wd = elm_widget_data_get(obj);
if (!wd) return;
ll = eina_list_append(ll, wd->items);
EINA_LIST_FOREACH(ll, ll, l)
{
EINA_LIST_FREE(l, item)
{
ll = eina_list_append(ll, item->items);
if (item->del_cb) item->del_cb((void*)item->data, item->o, item);
if (item->label) eina_stringshare_del(item->label);
if (item->hv) evas_object_del(item->hv);
if (item->location) evas_object_del(item->location);
free(item);
}
}
if (wd->hv) evas_object_del(wd->hv);
if (wd->location) evas_object_del(wd->location);
free(wd);
}