From 561842d30b1a4065f1f6cdf2c97b5c45b387b924 Mon Sep 17 00:00:00 2001 From: Larry Lira Date: Thu, 29 Nov 2018 15:11:51 -0200 Subject: [PATCH] Efl.Ui.List.View: fixed MVVM life-cycle Fix bugs on Views and Model related with null items and proper ownership and life-cycle of components. Configure default theme for default factory on finalize. --- .../elementary/efl_ui_list_view_example_1.c | 5 +- .../elementary/efl_ui_list_view_example_2.c | 2 +- .../elementary/efl_ui_list_view_example_3.c | 16 ++--- src/lib/ecore/efl_model_container.c | 6 +- src/lib/ecore/efl_model_item.c | 9 +-- src/lib/elementary/efl_ui_layout.c | 16 ++--- src/lib/elementary/efl_ui_layout_factory.c | 59 ++++++++--------- src/lib/elementary/efl_ui_list_view.c | 73 +++++++++++----------- .../elementary/efl_ui_list_view_precise_layouter.c | 47 ++++++++------ src/lib/elementary/efl_ui_list_view_seg_array.c | 9 +-- 10 files changed, 118 insertions(+), 124 deletions(-) diff --git a/src/examples/elementary/efl_ui_list_view_example_1.c b/src/examples/elementary/efl_ui_list_view_example_1.c index f0a6adc..dc30026 100644 --- a/src/examples/elementary/efl_ui_list_view_example_1.c +++ b/src/examples/elementary/efl_ui_list_view_example_1.c @@ -22,7 +22,7 @@ const char *styles[] = { char edj_path[PATH_MAX]; static void -_realized_cb(void *data, const Efl_Event *event) +_realized_cb(void *data EINA_UNUSED, const Efl_Event *event) { Efl_Ui_List_View_Item_Event *ie = event->info; if (!ie->layout) return; @@ -69,7 +69,7 @@ _make_model(Evas_Object *win) } EAPI_MAIN int -elm_main(int argc, char **argv) +elm_main(int argc EINA_UNUSED, char **argv EINA_UNUSED) { Efl_Ui_Factory *factory; Evas_Object *win, *li; @@ -110,7 +110,6 @@ elm_main(int argc, char **argv) evas_object_show(win); elm_run(); - efl_unref(model); return 0; } diff --git a/src/examples/elementary/efl_ui_list_view_example_2.c b/src/examples/elementary/efl_ui_list_view_example_2.c index c624cad..ca56f37 100644 --- a/src/examples/elementary/efl_ui_list_view_example_2.c +++ b/src/examples/elementary/efl_ui_list_view_example_2.c @@ -15,7 +15,7 @@ #define EFL_MODEL_TEST_FILENAME_PATH "/tmp" EAPI_MAIN int -elm_main(int argc, char **argv) +elm_main(int argc EINA_UNUSED, char **argv EINA_UNUSED) { Efl_Ui_Layout_Factory *factory; Efl_Ui_Image_Factory *imgf; diff --git a/src/examples/elementary/efl_ui_list_view_example_3.c b/src/examples/elementary/efl_ui_list_view_example_3.c index 46d5ca5..eaf5dc9 100644 --- a/src/examples/elementary/efl_ui_list_view_example_3.c +++ b/src/examples/elementary/efl_ui_list_view_example_3.c @@ -66,7 +66,7 @@ _focused(void *data, const Efl_Event *event) } static void -_bt_add_clicked(void *data, Evas_Object *obj, void *event_info) +_bt_add_clicked(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) { Priv_Data *priv = (Priv_Data*)data; Eina_Value vtext, value; @@ -90,7 +90,7 @@ _bt_add_clicked(void *data, Evas_Object *obj, void *event_info) } static void -_bt_del_clicked(void *data, Evas_Object *obj, void *event_info EINA_UNUSED) +_bt_del_clicked(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) { Priv_Data *priv = (Priv_Data*)data; Eo *child = NULL; @@ -110,35 +110,35 @@ _bt_del_clicked(void *data, Evas_Object *obj, void *event_info EINA_UNUSED) } static void -_bt_none_clicked(void *data, Evas_Object *obj, void *event_info EINA_UNUSED) +_bt_none_clicked(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) { Evas_Object *li = data; efl_ui_list_view_select_mode_set(li, ELM_OBJECT_SELECT_MODE_NONE); } static void -_bt_donly_clicked(void *data, Evas_Object *obj, void *event_info EINA_UNUSED) +_bt_donly_clicked(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) { Evas_Object *li = data; efl_ui_list_view_select_mode_set(li, ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY); } static void -_bt_default_clicked(void *data, Evas_Object *obj, void *event_info EINA_UNUSED) +_bt_default_clicked(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) { Evas_Object *li = data; efl_ui_list_view_select_mode_set(li, ELM_OBJECT_SELECT_MODE_DEFAULT); } static void -_bt_set_clicked(void *data, Evas_Object *obj, void *event_info EINA_UNUSED) +_bt_set_clicked(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) { Priv_Data *priv = data; efl_ui_view_model_set(priv->list2, priv->model); } static void -_bt_unset_clicked(void *data, Evas_Object *obj, void *event_info EINA_UNUSED) +_bt_unset_clicked(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) { Evas_Object *li = data; efl_ui_view_model_set(li, NULL); @@ -201,7 +201,7 @@ _make_model() } EAPI_MAIN int -elm_main(int argc, char **argv) +elm_main(int argc EINA_UNUSED, char **argv EINA_UNUSED) { Priv_Data *priv; Evas_Object *win, *bx, *vbx, *bt; diff --git a/src/lib/ecore/efl_model_container.c b/src/lib/ecore/efl_model_container.c index 5449ae4..ce5dc49 100644 --- a/src/lib/ecore/efl_model_container.c +++ b/src/lib/ecore/efl_model_container.c @@ -84,12 +84,8 @@ _efl_model_container_efl_object_destructor(Eo *obj, { Eina_Stringshare *key; Eina_Iterator *it; - Efl_Model *child; - EINA_LIST_FREE(sd->childrens, child) - { - if (child) efl_parent_set(child, NULL); - } + eina_list_free(sd->childrens); it = eina_hash_iterator_key_new(sd->properties); EINA_ITERATOR_FOREACH(it, key) diff --git a/src/lib/ecore/efl_model_item.c b/src/lib/ecore/efl_model_item.c index 104125a..13f6029 100644 --- a/src/lib/ecore/efl_model_item.c +++ b/src/lib/ecore/efl_model_item.c @@ -44,14 +44,7 @@ _efl_model_item_efl_object_constructor(Eo *obj, Efl_Model_Item_Data *sd) static void _efl_model_item_efl_object_destructor(Eo *obj, Efl_Model_Item_Data *sd) { - Efl_Model *child; - - EINA_LIST_FREE(sd->childrens, child) - { - if (child) - efl_parent_set(child, NULL); - } - + eina_list_free(sd->childrens); eina_hash_foreach(sd->properties, _stringshared_keys_free, NULL); eina_hash_free(sd->properties); diff --git a/src/lib/elementary/efl_ui_layout.c b/src/lib/elementary/efl_ui_layout.c index a46c716..d35a4b9 100644 --- a/src/lib/elementary/efl_ui_layout.c +++ b/src/lib/elementary/efl_ui_layout.c @@ -2306,9 +2306,8 @@ _efl_ui_layout_connect_hash(Efl_Ui_Layout_Data *pd) { if (pd->connect.properties) return ; - // FIXME: fix destruction function definition - pd->connect.properties = eina_hash_stringshared_new(NULL); // Hash of property targeting a part - pd->connect.signals = eina_hash_stringshared_new(NULL); // Hash of property triggering a signal + pd->connect.properties = eina_hash_stringshared_new(EINA_FREE_CB(free)); // Hash of property targeting a part + pd->connect.signals = eina_hash_stringshared_new(EINA_FREE_CB(free)); // Hash of property triggering a signal pd->connect.factories = eina_hash_stringshared_new(EINA_FREE_CB(efl_unref)); // Hash of property triggering a content creation } @@ -2319,13 +2318,16 @@ _efl_ui_layout_efl_ui_view_model_set(Eo *obj, Efl_Ui_Layout_Data *pd, Efl_Model Eina_Hash_Tuple *tuple; Eina_Iterator *it; - efl_replace(&pd->connect.model, model); + if (pd->connect.model && pd->connect.model != model) + efl_event_callback_del(pd->connect.model, EFL_MODEL_EVENT_PROPERTIES_CHANGED, + _efl_model_properties_changed_cb, pd); + + if (!efl_replace(&pd->connect.model, model)) + return; if (model) - { - efl_event_callback_add(pd->connect.model, EFL_MODEL_EVENT_PROPERTIES_CHANGED, + efl_event_callback_add(pd->connect.model, EFL_MODEL_EVENT_PROPERTIES_CHANGED, _efl_model_properties_changed_cb, pd); - } _efl_ui_layout_connect_hash(pd); diff --git a/src/lib/elementary/efl_ui_layout_factory.c b/src/lib/elementary/efl_ui_layout_factory.c index 43d0a0f..cbd8139 100644 --- a/src/lib/elementary/efl_ui_layout_factory.c +++ b/src/lib/elementary/efl_ui_layout_factory.c @@ -10,7 +10,6 @@ typedef struct _Efl_Ui_Layout_Factory_Data { - Eina_Array *layouts; Eina_Hash *connects; Eina_Hash *factory_connects; Eina_Stringshare *klass; @@ -46,12 +45,8 @@ _efl_ui_layout_factory_efl_object_constructor(Eo *obj, Efl_Ui_Layout_Factory_Dat { obj = efl_constructor(efl_super(obj, MY_CLASS)); - pd->klass = NULL; - pd->group = NULL; - pd->style = NULL; - pd->layouts = eina_array_new(8); pd->connects = eina_hash_stringshared_new(EINA_FREE_CB(eina_stringshare_del)); - pd->factory_connects = eina_hash_stringshared_new(EINA_FREE_CB(efl_del)); + pd->factory_connects = eina_hash_stringshared_new(EINA_FREE_CB(efl_unref)); return obj; } @@ -59,18 +54,10 @@ _efl_ui_layout_factory_efl_object_constructor(Eo *obj, Efl_Ui_Layout_Factory_Dat EOLIAN static void _efl_ui_layout_factory_efl_object_destructor(Eo *obj, Efl_Ui_Layout_Factory_Data *pd) { - Eina_Array_Iterator iterator; - Eo *layout; - unsigned int i; - eina_stringshare_del(pd->klass); eina_stringshare_del(pd->group); eina_stringshare_del(pd->style); - EINA_ARRAY_ITER_NEXT(pd->layouts, i, layout, iterator) - efl_parent_set(layout, NULL); - - eina_array_free(pd->layouts); eina_hash_free(pd->connects); eina_hash_free(pd->factory_connects); @@ -83,25 +70,16 @@ _efl_ui_layout_factory_efl_ui_factory_create(Eo *obj EINA_UNUSED, Efl_Ui_Layout_ { Efl_Gfx_Entity *layout; EINA_SAFETY_ON_NULL_RETURN_VAL(parent, NULL); -/* - if (eina_array_count(pd->layouts)) - { - layout = eina_array_pop(pd->layouts); - efl_parent_set(layout, parent); - efl_ui_view_model_set(layout, model); - } - else */ - { - layout = efl_add(EFL_UI_LAYOUT_CLASS, parent, - efl_ui_view_model_set(efl_added, model), - efl_ui_layout_theme_set(efl_added, pd->klass, pd->group, pd->style)); - eina_hash_foreach(pd->connects, _model_connect, layout); - eina_hash_foreach(pd->factory_connects, _factory_model_connect, layout); + layout = efl_add(EFL_UI_LAYOUT_CLASS, parent, + efl_ui_view_model_set(efl_added, model), + efl_ui_layout_theme_set(efl_added, pd->klass, pd->group, pd->style)); - evas_object_size_hint_weight_set(layout, EVAS_HINT_EXPAND, 0); - evas_object_size_hint_align_set(layout, EVAS_HINT_FILL, EVAS_HINT_FILL); - } + eina_hash_foreach(pd->connects, _model_connect, layout); + eina_hash_foreach(pd->factory_connects, _factory_model_connect, layout); + + evas_object_size_hint_weight_set(layout, EVAS_HINT_EXPAND, 0); + evas_object_size_hint_align_set(layout, EVAS_HINT_FILL, EVAS_HINT_FILL); return layout; } @@ -118,6 +96,7 @@ _efl_ui_layout_factory_efl_ui_factory_model_connect(Eo *obj EINA_UNUSED, Efl_Ui_ , const char *name, Efl_Ui_Factory *factory) { Eina_Stringshare *ss_name; + Efl_Ui_Factory *f_old; ss_name = eina_stringshare_add(name); if (factory == NULL) @@ -126,24 +105,36 @@ _efl_ui_layout_factory_efl_ui_factory_model_connect(Eo *obj EINA_UNUSED, Efl_Ui_ return; } - eina_stringshare_del(eina_hash_set(pd->factory_connects, ss_name, factory)); + f_old = eina_hash_set(pd->factory_connects, ss_name, efl_ref(factory)); + if (f_old) + { + efl_unref(f_old); + eina_stringshare_del(ss_name); + } } EOLIAN static void _efl_ui_layout_factory_efl_ui_model_connect_connect(Eo *obj EINA_UNUSED, Efl_Ui_Layout_Factory_Data *pd , const char *name, const char *property) { - Eina_Stringshare *ss_name, *ss_prop; + Eina_Stringshare *ss_name, *ss_prop, *ss_old; ss_name = eina_stringshare_add(name); if (property == NULL) { eina_hash_del(pd->connects, ss_name, NULL); + eina_stringshare_del(ss_name); return; } ss_prop = eina_stringshare_add(property); - eina_stringshare_del(eina_hash_set(pd->connects, ss_name, ss_prop)); + ss_old = eina_hash_set(pd->connects, ss_name, ss_prop); + if (ss_old) + { + eina_stringshare_del(ss_old); + eina_stringshare_del(ss_name); + } + } EOLIAN static void diff --git a/src/lib/elementary/efl_ui_list_view.c b/src/lib/elementary/efl_ui_list_view.c index 69ee9b6..91b9007 100644 --- a/src/lib/elementary/efl_ui_list_view.c +++ b/src/lib/elementary/efl_ui_list_view.c @@ -619,7 +619,9 @@ _efl_ui_list_view_efl_canvas_group_group_add(Eo *obj, Efl_Ui_List_View_Data *pd) EOLIAN static void _efl_ui_list_view_efl_canvas_group_group_del(Eo *obj, Efl_Ui_List_View_Data *pd) { - ELM_SAFE_FREE(pd->pan_obj, evas_object_del); + efl_ui_list_view_relayout_model_set(pd->relayout, NULL); + + ELM_SAFE_FREE(pd->pan_obj, efl_del); efl_canvas_group_del(efl_super(obj, MY_CLASS)); } @@ -636,15 +638,16 @@ _efl_ui_list_view_efl_ui_widget_focus_manager_focus_manager_create(Eo *obj EINA_ EOLIAN static Eo * _efl_ui_list_view_efl_object_finalize(Eo *obj, Efl_Ui_List_View_Data *pd) { - if (!pd->factory) - pd->factory = efl_add(EFL_UI_LAYOUT_FACTORY_CLASS, obj); + { + pd->factory = efl_new(EFL_UI_LAYOUT_FACTORY_CLASS); + efl_ui_layout_factory_theme_config(pd->factory, "list_item", NULL, "default"); + } if(!pd->relayout) { - pd->relayout = efl_add(EFL_UI_LIST_VIEW_PRECISE_LAYOUTER_CLASS, obj); - if (pd->model) - efl_ui_list_view_relayout_model_set(pd->relayout, pd->model); + pd->relayout = efl_new(EFL_UI_LIST_VIEW_PRECISE_LAYOUTER_CLASS); + efl_ui_list_view_relayout_model_set(pd->relayout, pd->model); } return obj; } @@ -658,7 +661,7 @@ _efl_ui_list_view_efl_object_constructor(Eo *obj, Efl_Ui_List_View_Data *pd) evas_object_smart_callbacks_descriptions_set(obj, _smart_callbacks); efl_access_object_role_set(obj, EFL_ACCESS_ROLE_LIST); - pd->seg_array = efl_add(EFL_UI_LIST_VIEW_SEG_ARRAY_CLASS, obj, efl_ui_list_view_seg_array_setup(efl_added, 32)); + pd->seg_array = efl_new(EFL_UI_LIST_VIEW_SEG_ARRAY_CLASS, efl_ui_list_view_seg_array_setup(efl_added, 32)); efl_event_callback_add(obj, EFL_UI_FOCUS_MANAGER_EVENT_FOCUS_CHANGED, _list_element_focused, NULL); @@ -677,45 +680,37 @@ _efl_ui_list_view_efl_object_constructor(Eo *obj, Efl_Ui_List_View_Data *pd) EOLIAN static void _efl_ui_list_view_efl_object_destructor(Eo *obj, Efl_Ui_List_View_Data *pd) { - efl_ui_list_view_relayout_model_set(pd->relayout, NULL); - - efl_unref(pd->model); - eina_stringshare_del(pd->style); + efl_event_callback_del(obj, EFL_UI_FOCUS_MANAGER_EVENT_FOCUS_CHANGED, + _list_element_focused, NULL); _efl_ui_list_view_edje_object_detach(obj); - ELM_SAFE_FREE(pd->pan_obj, evas_object_del); - efl_canvas_group_del(efl_super(obj, MY_CLASS)); + efl_replace(&pd->model, NULL); + efl_replace(&pd->relayout, NULL); + efl_replace(&pd->factory, NULL); + + efl_ui_list_view_seg_array_flush(pd->seg_array); + efl_unref(pd->seg_array); + eina_stringshare_del(pd->style); efl_destructor(efl_super(obj, MY_CLASS)); } EOLIAN static void _efl_ui_list_view_layout_factory_set(Eo *obj EINA_UNUSED, Efl_Ui_List_View_Data *pd, Efl_Ui_Factory *factory) { - if (pd->factory) - efl_unref(pd->factory); - - pd->factory = factory; - efl_ref(pd->factory); + efl_replace(&pd->factory, factory); } EOLIAN static void _efl_ui_list_view_efl_ui_view_model_set(Eo *obj EINA_UNUSED, Efl_Ui_List_View_Data *pd, Efl_Model *model) { - if (pd->model == model) + if (!efl_replace(&pd->model, model)) return; - if (pd->model) - { - if (pd->relayout) - efl_ui_list_view_relayout_model_set(pd->relayout, NULL); - efl_ui_list_view_seg_array_flush(pd->seg_array); - } - - efl_replace(&pd->model, model); + efl_ui_list_view_seg_array_flush(pd->seg_array); - if (pd->model && pd->relayout) + if (pd->relayout) efl_ui_list_view_relayout_model_set(pd->relayout, pd->model); evas_object_smart_changed(pd->obj); @@ -814,7 +809,7 @@ _efl_ui_list_view_item_select_set(Efl_Ui_List_View_Layout_Item *item, Eina_Bool if (_efl_model_properties_has(item->children, sprop)) { Eina_Value v; - eina_value_setup(&v, EINA_VALUE_TYPE_UCHAR); + eina_value_setup(&v, EINA_VALUE_TYPE_BOOL); eina_value_set(&v, selected); efl_model_property_set(item->children, sprop, &v); eina_value_flush(&v); @@ -825,8 +820,7 @@ _efl_ui_list_view_item_select_set(Efl_Ui_List_View_Layout_Item *item, Eina_Bool static void _efl_ui_list_view_relayout_set(Eo *obj EINA_UNUSED, Efl_Ui_List_View_Data *pd EINA_UNUSED, Efl_Ui_List_View_Relayout *object) { - efl_replace(&pd->relayout, object); - if (pd->model && pd->relayout) + if (efl_replace(&pd->relayout, object) && pd->model && pd->relayout) efl_ui_list_view_relayout_model_set(pd->relayout, pd->model); } @@ -917,9 +911,13 @@ EOLIAN static Efl_Ui_List_View_Layout_Item * _efl_ui_list_view_efl_ui_list_view_model_realize(Eo *obj, Efl_Ui_List_View_Data *pd, Efl_Ui_List_View_Layout_Item *item) { Efl_Ui_List_View_Item_Event evt; - EINA_SAFETY_ON_NULL_RETURN_VAL(item->children, item); + EINA_SAFETY_ON_NULL_RETURN_VAL(item, NULL); + + if (!item->children) + return item; item->layout = efl_ui_factory_create(pd->factory, item->children, obj); + EINA_SAFETY_ON_NULL_RETURN_VAL(item->layout, NULL); evas_object_smart_member_add(item->layout, pd->pan_obj); evas_object_event_callback_add(item->layout, EVAS_CALLBACK_MOUSE_UP, _on_item_mouse_up, item); @@ -943,13 +941,16 @@ EOLIAN static void _efl_ui_list_view_efl_ui_list_view_model_unrealize(Eo *obj, Efl_Ui_List_View_Data *pd, Efl_Ui_List_View_Layout_Item *item) { Efl_Ui_List_View_Item_Event evt; - EINA_SAFETY_ON_NULL_RETURN(item->layout); + EINA_SAFETY_ON_NULL_RETURN(item); + + if (!item->layout) + return; evas_object_event_callback_del_full(item->layout, EVAS_CALLBACK_MOUSE_UP, _on_item_mouse_up, item); if (elm_object_focus_allow_get(item->layout)) { - if (elm_object_focus_get(item->layout)) - elm_object_focus_set(item->layout, EINA_FALSE); + if (efl_ui_focus_object_focus_get(item->layout)) + efl_ui_focus_object_focus_set(item->layout, EINA_FALSE); efl_ui_focus_manager_calc_unregister(obj, item->layout); } evas_object_hide(item->layout); @@ -960,8 +961,8 @@ _efl_ui_list_view_efl_ui_list_view_model_unrealize(Eo *obj, Efl_Ui_List_View_Dat evt.index = efl_ui_list_view_item_index_get(item); efl_event_callback_call(obj, EFL_UI_LIST_VIEW_EVENT_ITEM_UNREALIZED, &evt); - evas_object_smart_member_del(item->layout); efl_ui_factory_release(pd->factory, item->layout); + evas_object_smart_member_del(item->layout); item->layout = NULL; } diff --git a/src/lib/elementary/efl_ui_list_view_precise_layouter.c b/src/lib/elementary/efl_ui_list_view_precise_layouter.c index 3beac4d..9b6ba9f 100644 --- a/src/lib/elementary/efl_ui_list_view_precise_layouter.c +++ b/src/lib/elementary/efl_ui_list_view_precise_layouter.c @@ -325,14 +325,15 @@ _initilize(Eo *obj EINA_UNUSED, Efl_Ui_List_View_Precise_Layouter_Data *pd, Efl_ if(pd->initialized) return EINA_TRUE; - if(!pd->model || !pd->count_total) + efl_replace(&pd->modeler, modeler); + + if(!pd->model || !pd->modeler) return EINA_FALSE; pd->recalc = EINA_TRUE; pd->initialized = EINA_TRUE; - pd->modeler = modeler; - pd->seg_array = seg_array; + efl_replace(&pd->seg_array, seg_array); efl_ui_list_view_model_load_range_set(pd->modeler, 0, pd->count_total); // load all efl_event_callback_add(pd->model, EFL_MODEL_EVENT_CHILD_ADDED, _child_added_cb, pd); @@ -351,27 +352,36 @@ _finalize(Eo *obj EINA_UNUSED, Efl_Ui_List_View_Precise_Layouter_Data *pd) Efl_Ui_List_View_Seg_Array_Node* node; int i = 0; - evas_object_event_callback_del_full(pd->modeler, EVAS_CALLBACK_RESIZE, _on_modeler_resize, pd); - efl_event_callback_del(pd->model, EFL_MODEL_EVENT_CHILD_ADDED, _child_added_cb, pd); - efl_event_callback_del(pd->model, EFL_MODEL_EVENT_CHILD_REMOVED, _child_removed_cb, pd); - pd->count_total = 0; - - Eina_Accessor *nodes = efl_ui_list_view_seg_array_node_accessor_get(pd->seg_array); - EINA_ACCESSOR_FOREACH(nodes, i, node) + if (pd->model) { - _node_unrealize(pd, node); - free(node->layout_data); + efl_event_callback_del(pd->model, EFL_MODEL_EVENT_CHILD_ADDED, _child_added_cb, pd); + efl_event_callback_del(pd->model, EFL_MODEL_EVENT_CHILD_REMOVED, _child_removed_cb, pd); + pd->count_total = 0; } - eina_accessor_free(nodes); + if (pd->seg_array) + { + Eina_Accessor *nodes = efl_ui_list_view_seg_array_node_accessor_get(pd->seg_array); + EINA_ACCESSOR_FOREACH(nodes, i, node) + { + _node_unrealize(pd, node); + free(node->layout_data); + } + + eina_accessor_free(nodes); + } pd->min.w = 0; pd->min.h = 0; - efl_ui_list_view_model_min_size_set(pd->modeler, pd->min); + if (pd->modeler) + { + evas_object_event_callback_del_full(pd->modeler, EVAS_CALLBACK_RESIZE, _on_modeler_resize, pd); + efl_ui_list_view_model_min_size_set(pd->modeler, pd->min); + } - pd->seg_array = NULL; - pd->modeler = NULL; + efl_replace(&pd->seg_array, NULL); + efl_replace(&pd->modeler, NULL); pd->initialized = EINA_FALSE; pd->recalc = EINA_TRUE; @@ -567,7 +577,8 @@ _efl_ui_list_view_precise_layouter_efl_ui_list_view_relayout_elements_get(const } } - return elements_order; + eina_accessor_free(nodes); + return elements_order; } EOLIAN static void @@ -682,7 +693,7 @@ _efl_ui_list_view_precise_layouter_efl_ui_list_view_relayout_layout_do (Eo *obj EINA_UNUSED, Efl_Ui_List_View_Precise_Layouter_Data *pd , Efl_Ui_List_View_Model *modeler, int first, Efl_Ui_List_View_Seg_Array *seg_array) { - if (!_initilize(obj, pd, modeler, seg_array)) + if (!_initilize(obj, pd, modeler, seg_array) || !pd->seg_array) return; pd->first = first; diff --git a/src/lib/elementary/efl_ui_list_view_seg_array.c b/src/lib/elementary/efl_ui_list_view_seg_array.c index bf379a6..8c6c0ed 100644 --- a/src/lib/elementary/efl_ui_list_view_seg_array.c +++ b/src/lib/elementary/efl_ui_list_view_seg_array.c @@ -56,7 +56,6 @@ static Eina_Rbtree_Direction _rbtree_compare(Efl_Ui_List_View_Seg_Array_Node con return EINA_RBTREE_RIGHT; } - static void _free_node(Efl_Ui_List_View_Seg_Array_Node* node, void* data EINA_UNUSED) { @@ -64,8 +63,10 @@ _free_node(Efl_Ui_List_View_Seg_Array_Node* node, void* data EINA_UNUSED) while (i < node->length) { - free(node->pointers[i]); - ++i; + Efl_Ui_List_View_Layout_Item* item = node->pointers[i]; + efl_unref(item->children); + free(item); + ++i; } free(node); @@ -98,7 +99,7 @@ _efl_ui_list_view_seg_array_flush(Eo* obj EINA_UNUSED, Efl_Ui_List_View_Seg_Arra static Efl_Ui_List_View_Layout_Item* _create_item_partial(Efl_Model* model) { Efl_Ui_List_View_Layout_Item* item = calloc(1, sizeof(Efl_Ui_List_View_Layout_Item)); - item->children = model; + item->children = efl_ref(model); return item; } -- 2.7.4