Efl.Ui.List.View: fixed MVVM life-cycle
authorLarry Lira <larry@expertisesolutions.com.br>
Thu, 29 Nov 2018 17:11:51 +0000 (15:11 -0200)
committerHermet Park <hermetpark@gmail.com>
Wed, 5 Dec 2018 05:52:40 +0000 (14:52 +0900)
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.

src/examples/elementary/efl_ui_list_view_example_1.c
src/examples/elementary/efl_ui_list_view_example_2.c
src/examples/elementary/efl_ui_list_view_example_3.c
src/lib/ecore/efl_model_container.c
src/lib/ecore/efl_model_item.c
src/lib/elementary/efl_ui_layout.c
src/lib/elementary/efl_ui_layout_factory.c
src/lib/elementary/efl_ui_list_view.c
src/lib/elementary/efl_ui_list_view_precise_layouter.c
src/lib/elementary/efl_ui_list_view_seg_array.c

index f0a6adc..dc30026 100644 (file)
@@ -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;
 }
index c624cad..ca56f37 100644 (file)
@@ -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;
index 46d5ca5..eaf5dc9 100644 (file)
@@ -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;
index 5449ae4..ce5dc49 100644 (file)
@@ -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)
index 104125a..13f6029 100644 (file)
@@ -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);
 
index a46c716..d35a4b9 100644 (file)
@@ -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);
 
index 43d0a0f..cbd8139 100644 (file)
@@ -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
index 69ee9b6..91b9007 100644 (file)
@@ -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;
 }
 
index 3beac4d..9b6ba9f 100644 (file)
@@ -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;
index bf379a6..8c6c0ed 100644 (file)
@@ -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;
 }