diff options
author | Cedric BAIL <cedric.bail@free.fr> | 2019-07-10 17:54:46 -0700 |
---|---|---|
committer | Marcel Hollerbach <mail@marcel-hollerbach.de> | 2019-07-17 21:57:49 +0200 |
commit | 4d071ff1cbc020ecbb833e97e577ecee07274efa (patch) | |
tree | 102d624473c722bcb0f3b24c52f8c9ad53369722 | |
parent | 65b4782682318055db57697064349ef8e4983064 (diff) | |
download | efl-4d071ff1cbc020ecbb833e97e577ecee07274efa.tar.gz |
efl: implement notification for when the model is changed on a widget.
Reviewed-by: Marcel Hollerbach <mail@marcel-hollerbach.de>
Differential Revision: https://phab.enlightenment.org/D9288
-rw-r--r-- | src/lib/efl/interfaces/efl_ui_view.eo | 9 | ||||
-rw-r--r-- | src/lib/elementary/efl_ui_widget.c | 91 | ||||
-rw-r--r-- | src/lib/elementary/elm_widget.h | 1 |
3 files changed, 70 insertions, 31 deletions
diff --git a/src/lib/efl/interfaces/efl_ui_view.eo b/src/lib/efl/interfaces/efl_ui_view.eo index 33919d5c96..56026a0ed2 100644 --- a/src/lib/efl/interfaces/efl_ui_view.eo +++ b/src/lib/efl/interfaces/efl_ui_view.eo @@ -1,3 +1,9 @@ +struct @beta Efl.Model_Changed_Event { + [[Every time the model is changed on the object.]] + current: Efl.Model; [[The newly set model.]] + previous: Efl.Model; [[The previously set model.]] +} + interface @beta Efl.Ui.View { [[Efl UI view interface]] @@ -10,4 +16,7 @@ interface @beta Efl.Ui.View } } } + events { + model,changed: Efl.Model_Changed_Event; [[Event dispatched when a new model is set.]] + } } diff --git a/src/lib/elementary/efl_ui_widget.c b/src/lib/elementary/efl_ui_widget.c index f6ddf3270f..f7749d9a66 100644 --- a/src/lib/elementary/efl_ui_widget.c +++ b/src/lib/elementary/efl_ui_widget.c @@ -5775,6 +5775,47 @@ _efl_ui_view_property_bind_changed(void *data, const Efl_Event *event) } } +static void +_efl_ui_widget_model_update(Efl_Ui_Widget_Data *pd) +{ + Efl_Ui_Property_Bound *property; + Eina_Iterator *it; + + it = eina_hash_iterator_data_new(pd->properties.model_lookup); + EINA_ITERATOR_FOREACH(it, property) + _efl_ui_property_bind_get(pd, property); +} + +static void +_efl_ui_widget_model_register(Eo *obj, Efl_Ui_Widget_Data *pd) +{ + if (pd->properties.registered) return ; + if (pd->properties.model_lookup) + { + if (!pd->properties.model) return ; + + efl_event_callback_add(pd->properties.model, EFL_MODEL_EVENT_PROPERTIES_CHANGED, + _efl_ui_model_property_bind_changed, pd); + efl_event_callback_add(obj, EFL_UI_PROPERTY_BIND_EVENT_PROPERTIES_CHANGED, + _efl_ui_view_property_bind_changed, pd); + pd->properties.registered = EINA_TRUE; + } +} + +static void +_efl_ui_widget_model_unregister(Eo *obj, Efl_Ui_Widget_Data *pd) +{ + if (pd->properties.registered) + { + // Remove any existing handler that might exist for any reason + efl_event_callback_del(pd->properties.model, EFL_MODEL_EVENT_PROPERTIES_CHANGED, + _efl_ui_model_property_bind_changed, pd); + efl_event_callback_del(obj, EFL_UI_PROPERTY_BIND_EVENT_PROPERTIES_CHANGED, + _efl_ui_view_property_bind_changed, pd); + + pd->properties.registered = EINA_FALSE; + } +} static Eina_Error _efl_ui_widget_efl_ui_property_bind_property_bind(Eo *obj, Efl_Ui_Widget_Data *pd, const char *key, const char *property) @@ -5788,14 +5829,8 @@ _efl_ui_widget_efl_ui_property_bind_property_bind(Eo *obj, Efl_Ui_Widget_Data *p { pd->properties.model_lookup = eina_hash_stringshared_new(_efl_ui_property_bind_free); pd->properties.view_lookup = eina_hash_stringshared_new(NULL); - if (pd->properties.model) - { - efl_event_callback_add(pd->properties.model, EFL_MODEL_EVENT_PROPERTIES_CHANGED, - _efl_ui_model_property_bind_changed, pd); - efl_event_callback_add(obj, EFL_UI_PROPERTY_BIND_EVENT_PROPERTIES_CHANGED, - _efl_ui_view_property_bind_changed, pd); - } } + _efl_ui_widget_model_register(obj, pd); prop = calloc(1, sizeof (Efl_Ui_Property_Bound)); if (!prop) return ENOMEM; @@ -5817,25 +5852,24 @@ _efl_ui_widget_efl_ui_view_model_set(Eo *obj, Efl_Ui_Widget_Data *pd, Efl_Model *model) { - if (pd->properties.model) - { - // Remove any existing handler that might exist for any reason - efl_event_callback_del(pd->properties.model, EFL_MODEL_EVENT_PROPERTIES_CHANGED, - _efl_ui_model_property_bind_changed, pd); - efl_event_callback_del(obj, EFL_UI_PROPERTY_BIND_EVENT_PROPERTIES_CHANGED, - _efl_ui_view_property_bind_changed, pd); - } + Efl_Model_Changed_Event ev; + + ev.current = efl_ref(model); + ev.previous = efl_ref(pd->properties.model); + + _efl_ui_widget_model_unregister(obj, pd); efl_replace(&pd->properties.model, model); - if (pd->properties.model && pd->properties.model_lookup) - { - // Set the properties handler just in case - efl_event_callback_add(pd->properties.model, EFL_MODEL_EVENT_PROPERTIES_CHANGED, - _efl_ui_model_property_bind_changed, pd); - efl_event_callback_add(obj, EFL_UI_PROPERTY_BIND_EVENT_PROPERTIES_CHANGED, - _efl_ui_view_property_bind_changed, pd); - } + // Set the properties handler just in case + _efl_ui_widget_model_register(obj, pd); + + efl_event_callback_call(obj, EFL_UI_VIEW_EVENT_MODEL_CHANGED, &ev); + + if (pd->properties.model) _efl_ui_widget_model_update(pd); + + efl_unref(ev.current); + efl_unref(ev.previous); } static Efl_Model * @@ -5849,14 +5883,9 @@ _efl_ui_widget_efl_object_invalidate(Eo *obj, Efl_Ui_Widget_Data *pd) { efl_invalidate(efl_super(obj, EFL_UI_WIDGET_CLASS)); - if (pd->properties.model) - { - efl_event_callback_del(pd->properties.model, EFL_MODEL_EVENT_PROPERTIES_CHANGED, - _efl_ui_model_property_bind_changed, pd); - efl_event_callback_del(obj, EFL_UI_PROPERTY_BIND_EVENT_PROPERTIES_CHANGED, - _efl_ui_view_property_bind_changed, pd); - efl_replace(&pd->properties.model, NULL); - } + _efl_ui_widget_model_unregister(obj, pd); + efl_replace(&pd->properties.model, NULL); + if (pd->properties.view_lookup) eina_hash_free(pd->properties.view_lookup); pd->properties.view_lookup = NULL; if (pd->properties.model_lookup) eina_hash_free(pd->properties.model_lookup); diff --git a/src/lib/elementary/elm_widget.h b/src/lib/elementary/elm_widget.h index fec163dc44..f9fe403388 100644 --- a/src/lib/elementary/elm_widget.h +++ b/src/lib/elementary/elm_widget.h @@ -388,6 +388,7 @@ typedef struct _Elm_Widget_Smart_Data Efl_Model *model; Eina_Hash *model_lookup; Eina_Hash *view_lookup; + Eina_Bool registered : 1; } properties; Eina_Bool scroll_x_locked : 1; Eina_Bool scroll_y_locked : 1; |