elementary: Efl.Ui.Layout now rely on model change event to track the model.
authorCedric BAIL <cedric.bail@free.fr>
Thu, 11 Jul 2019 17:56:51 +0000 (10:56 -0700)
committerSangHyeon Jade Lee <sh10233.lee@samsung.com>
Tue, 23 Jul 2019 05:04:40 +0000 (14:04 +0900)
This means that this will work nicely with model provider too.

Reviewed-by: Marcel Hollerbach <mail@marcel-hollerbach.de>
Differential Revision: https://phab.enlightenment.org/D9291

src/lib/elementary/efl_ui_layout.c
src/lib/elementary/efl_ui_layout_base.eo
src/lib/elementary/elm_widget_layout.h

index f582a50..cef9286 100644 (file)
@@ -2428,24 +2428,34 @@ _efl_ui_layout_connect_hash(Efl_Ui_Layout_Data *pd)
    pd->connect.factories = eina_hash_stringshared_new(EINA_FREE_CB(_efl_ui_layout_factory_free)); // Hash of property triggering a content creation
 }
 
-EOLIAN static void
-_efl_ui_layout_base_efl_ui_view_model_set(Eo *obj, Efl_Ui_Layout_Data *pd, Efl_Model *model)
+
+static void
+_efl_ui_layout_base_model_unregister(Eo *obj EINA_UNUSED, Efl_Ui_Layout_Data *pd,
+                                     Efl_Model *model)
+{
+   if (!model) return ;
+   if (!pd->model_bound) return ;
+
+   efl_event_callback_del(model, EFL_MODEL_EVENT_PROPERTIES_CHANGED,
+                          _efl_model_properties_changed_cb, pd);
+
+   pd->model_bound = EINA_FALSE;
+}
+
+static void
+_efl_ui_layout_base_model_register(Eo *obj, Efl_Ui_Layout_Data *pd,
+                                   Efl_Model *model)
 {
    Eina_Stringshare *key;
    Eina_Hash_Tuple *tuple;
    Eina_Iterator *it;
-   Efl_Model *setted;
 
-   setted = efl_ui_view_model_get(obj);
-   if (setted)
-     efl_event_callback_del(setted, EFL_MODEL_EVENT_PROPERTIES_CHANGED,
-                            _efl_model_properties_changed_cb, pd);
+   if (!model) return ;
+   if (pd->model_bound) return;
+   pd->model_bound = EINA_TRUE;
 
-   efl_ui_view_model_set(efl_super(obj, EFL_UI_LAYOUT_BASE_CLASS), model);
-
-   if (model)
-     efl_event_callback_add(model, EFL_MODEL_EVENT_PROPERTIES_CHANGED,
-                            _efl_model_properties_changed_cb, pd);
+   efl_event_callback_add(model, EFL_MODEL_EVENT_PROPERTIES_CHANGED,
+                          _efl_model_properties_changed_cb, pd);
 
    _efl_ui_layout_connect_hash(pd);
 
@@ -2482,6 +2492,31 @@ _efl_ui_layout_base_efl_ui_view_model_set(Eo *obj, Efl_Ui_Layout_Data *pd, Efl_M
    _efl_ui_layout_view_model_update(pd);
 }
 
+static void
+_efl_ui_layout_base_model_update(void *data, const Efl_Event *event)
+{
+   Efl_Ui_Layout_Data *pd = data;
+   Efl_Model_Changed_Event *ev = event->info;
+
+   _efl_ui_layout_base_model_unregister(event->object, pd, ev->previous);
+   _efl_ui_layout_base_model_register(event->object, pd, ev->current);
+}
+
+static void
+_efl_ui_layout_base_model_watch(Eo *obj, Efl_Ui_Layout_Data *pd)
+{
+   Efl_Model *model;
+
+   if (pd->model_watch) return ;
+   pd->model_watch = EINA_TRUE;
+
+   efl_event_callback_add(obj, EFL_UI_VIEW_EVENT_MODEL_CHANGED,
+                          _efl_ui_layout_base_model_update, pd);
+   model = efl_ui_view_model_get(obj);
+   if (!model) return ;
+   _efl_ui_layout_base_model_register(obj, pd, model);
+}
+
 EOLIAN static Eina_Error
 _efl_ui_layout_base_efl_ui_property_bind_property_bind(Eo *obj, Efl_Ui_Layout_Data *pd, const char *key, const char *property)
 {
@@ -2501,6 +2536,9 @@ _efl_ui_layout_base_efl_ui_property_bind_property_bind(Eo *obj, Efl_Ui_Layout_Da
    if (!_elm_layout_part_aliasing_eval(obj, &key, EINA_TRUE))
      return EFL_PROPERTY_ERROR_INVALID_KEY;
 
+   // Check if there is a model and register it
+   _efl_ui_layout_base_model_watch(obj, pd);
+
    _efl_ui_layout_connect_hash(pd);
 
    sprop = eina_stringshare_add(property);
@@ -2557,6 +2595,9 @@ _efl_ui_layout_base_efl_ui_factory_bind_factory_bind(Eo *obj EINA_UNUSED, Efl_Ui
    if (!_elm_layout_part_aliasing_eval(obj, &key, EINA_TRUE))
      return;
 
+   // Check if there is a model and register it
+   _efl_ui_layout_base_model_watch(obj, pd);
+
    if (!pd->connect.factories)
      pd->connect.factories = eina_hash_stringshared_new(EINA_FREE_CB(_efl_ui_layout_factory_free));
 
@@ -2639,6 +2680,27 @@ _efl_ui_layout_base_efl_object_finalize(Eo *obj, Efl_Ui_Layout_Data *pd EINA_UNU
    return eo;
 }
 
+static void
+_efl_ui_layout_base_efl_object_invalidate(Eo *obj, Efl_Ui_Layout_Data *pd)
+{
+   if (pd->model_watch)
+     {
+        Efl_Model *model;
+
+        pd->model_watch = EINA_FALSE;
+        efl_event_callback_del(obj, EFL_UI_VIEW_EVENT_MODEL_CHANGED,
+                               _efl_ui_layout_base_model_update, pd);
+
+        model = efl_ui_view_model_get(obj);
+        if (!model)
+          {
+             _efl_ui_layout_base_model_unregister(obj, pd, model);
+          }
+     }
+
+   efl_invalidate(efl_super(obj, EFL_UI_LAYOUT_BASE_CLASS));
+}
+
 EOLIAN static void
 _efl_ui_layout_base_efl_layout_signal_message_send(Eo *obj, Efl_Ui_Layout_Data *pd EINA_UNUSED, int id, const Eina_Value msg)
 {
index d10ae27..3497e19 100644 (file)
@@ -60,6 +60,7 @@ abstract Efl.Ui.Layout_Base extends Efl.Ui.Widget implements Efl.Container,
       class.constructor;
       Efl.Object.constructor;
       Efl.Object.finalize;
+      Efl.Object.invalidate;
       Efl.Canvas.Group.group_calculate;
       Efl.Layout.Calc.calc_freeze;
       Efl.Layout.Calc.calc_thaw;
@@ -86,7 +87,6 @@ abstract Efl.Ui.Layout_Base extends Efl.Ui.Widget implements Efl.Container,
       Efl.Part.part_get;
       Efl.Ui.Property_Bind.property_bind;
       Efl.Ui.Factory_Bind.factory_bind;
-      Efl.Ui.View.model { set; }
 
       //TIZEN_ONLY(20161212): apply screen_reader_changed callback
       // TIZEN_ONLY(20170516): connect to at-spi dbus based on org.a11y.Status.IsEnabled property
index cdd4cb7..91aaed1 100644 (file)
@@ -72,6 +72,8 @@ typedef struct _Elm_Layout_Smart_Data
    Eina_Bool             destructed_is : 1; /**< This flag indicates if Efl.Ui.Layout destructor was called. This is needed to avoid unnecessary calculation of subobject deletion during layout object's deletion. */
    Eina_Bool             file_set : 1; /**< This flag indicates if Efl.Ui.Layout source is set from a file*/
    Eina_Bool             automatic_orientation_apply : 1;
+   Eina_Bool             model_bound : 1; /**< Set to true once we are watching over a model*/
+   Eina_Bool             model_watch : 1; /**< Set to true once we do watch for model change*/
 } Efl_Ui_Layout_Data;
 
 /**