summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCedric BAIL <cedric.bail@free.fr>2019-02-11 18:28:22 -0800
committerCedric BAIL <cedric.bail@free.fr>2019-03-08 14:31:00 -0800
commitd1d30f442bb376817535838a8747764941a2329c (patch)
tree0f04ba697e14319a39a9f64bccd1d854f6bfa66c
parentcbd8c45afeb458560e70ed5c3bc415ac79c66db4 (diff)
elementary: implemente property_bind support on all widget using property reflection.
This means that all property that are registered in the reflection table of any Eo class will be available for binding with a model. This will increase the amount of useful binding quickly. Reviewed-by: Vitor Sousa da Silva <vitorsousa@expertisesolutions.com.br> Differential Revision: https://phab.enlightenment.org/D7941
-rw-r--r--src/lib/elementary/efl_ui_widget.c184
-rw-r--r--src/lib/elementary/efl_ui_widget.eo6
-rw-r--r--src/lib/elementary/elm_widget.h5
3 files changed, 194 insertions, 1 deletions
diff --git a/src/lib/elementary/efl_ui_widget.c b/src/lib/elementary/efl_ui_widget.c
index e39bea0065..2c49d0fecf 100644
--- a/src/lib/elementary/efl_ui_widget.c
+++ b/src/lib/elementary/efl_ui_widget.c
@@ -5940,6 +5940,190 @@ _efl_ui_widget_part_bg_efl_gfx_image_scale_type_get(const Eo *obj, void *pd EINA
5940 return efl_gfx_image_scale_type_get(bg_obj); 5940 return efl_gfx_image_scale_type_get(bg_obj);
5941} 5941}
5942 5942
5943typedef struct _Efl_Ui_Property_Bound Efl_Ui_Property_Bound;
5944struct _Efl_Ui_Property_Bound
5945{
5946 Eina_Stringshare *key; // Local object property
5947 Eina_Stringshare *property; // Model property
5948 Eina_Future *f;
5949};
5950
5951static void
5952_efl_ui_property_bind_free(void *data)
5953{
5954 Efl_Ui_Property_Bound *prop = data;
5955
5956 eina_stringshare_del(prop->key);
5957 eina_stringshare_del(prop->property);
5958 free(prop);
5959}
5960
5961static void
5962_efl_ui_property_bind_clean(Eo *obj EINA_UNUSED,
5963 void *data,
5964 const Eina_Future *f EINA_UNUSED)
5965{
5966 Efl_Ui_Property_Bound *prop = data;
5967
5968 prop->f = NULL;
5969}
5970
5971static void
5972_efl_ui_property_bind_get(Efl_Ui_Widget_Data *pd, Efl_Ui_Property_Bound *prop)
5973{
5974 Eina_Value *value = efl_model_property_get(pd->properties.model, prop->property);
5975 Eina_Future *f;
5976 Eina_Error err;
5977
5978 err = efl_property_reflection_set(pd->obj, prop->key, eina_value_reference_copy(value));
5979 eina_value_free(value);
5980
5981 if (!err) return ;
5982
5983 // Report back the error to the model
5984 if (prop->f) eina_future_cancel(prop->f);
5985 f = efl_model_property_set(pd->properties.model, prop->property,
5986 eina_value_error_new(err));
5987 prop->f = efl_future_then(pd->obj, f, .free = _efl_ui_property_bind_clean, .data = prop);
5988}
5989
5990static void
5991_efl_ui_property_bind_set(Efl_Ui_Widget_Data *pd, Efl_Ui_Property_Bound *prop)
5992{
5993 Eina_Value value = efl_property_reflection_get(pd->obj, prop->key);
5994 Eina_Future *f;
5995
5996 if (prop->f) eina_future_cancel(prop->f);
5997 f = efl_model_property_set(pd->properties.model, prop->property, eina_value_dup(&value));
5998 prop->f = efl_future_then(pd->obj, f, .free = _efl_ui_property_bind_clean, .data = prop);
5999 eina_value_flush(&value);
6000}
6001
6002static void
6003_efl_ui_model_property_bind_changed(void *data, const Efl_Event *event)
6004{
6005 Efl_Model_Property_Event *evt = event->info;
6006 Efl_Ui_Widget_Data *pd = data;
6007 Eina_Array_Iterator it;
6008 const char *prop;
6009 unsigned int i;
6010
6011 EINA_ARRAY_ITER_NEXT(evt->changed_properties, i, prop, it)
6012 {
6013 Eina_Stringshare *sp = eina_stringshare_add(prop);
6014 Efl_Ui_Property_Bound *lookup;
6015
6016 lookup = eina_hash_find(pd->properties.model_lookup, sp);
6017 if (lookup) _efl_ui_property_bind_get(pd, lookup);
6018 eina_stringshare_del(sp);
6019 }
6020}
6021
6022static void
6023_efl_ui_view_property_bind_changed(void *data, const Efl_Event *event)
6024{
6025 Efl_Ui_Property_Event *evt = event->info;
6026 Efl_Ui_Widget_Data *pd = data;
6027 Eina_Array_Iterator it;
6028 Eina_Stringshare *prop;
6029 unsigned int i;
6030
6031 EINA_ARRAY_ITER_NEXT(evt->changed_properties, i, prop, it)
6032 {
6033 Efl_Ui_Property_Bound *lookup;
6034
6035 lookup = eina_hash_find(pd->properties.view_lookup, prop);
6036 if (lookup) _efl_ui_property_bind_set(pd, lookup);
6037 }
6038}
6039
6040static Eina_Error
6041_efl_ui_widget_efl_ui_property_bind_property_bind(Eo *obj, Efl_Ui_Widget_Data *pd,
6042 const char *key, const char *property)
6043{
6044 Efl_Ui_Property_Bound *prop;
6045
6046 // Check if the property is available from the reflection table of the object.
6047 if (!efl_property_reflection_exist(obj, key)) return EFL_PROPERTY_ERROR_INVALID_KEY;
6048
6049 if (!pd->properties.model_lookup)
6050 {
6051 pd->properties.model_lookup = eina_hash_stringshared_new(_efl_ui_property_bind_free);
6052 pd->properties.view_lookup = eina_hash_stringshared_new(NULL);
6053 if (pd->properties.model)
6054 {
6055 efl_event_callback_add(pd->properties.model, EFL_MODEL_EVENT_PROPERTIES_CHANGED,
6056 _efl_ui_model_property_bind_changed, pd);
6057 efl_event_callback_add(obj, EFL_UI_PROPERTY_BIND_EVENT_PROPERTIES_CHANGED,
6058 _efl_ui_view_property_bind_changed, pd);
6059 }
6060 }
6061
6062 prop = calloc(1, sizeof (Efl_Ui_Property_Bound));
6063 if (!prop) return ENOMEM;
6064 prop->key = eina_stringshare_add(key);
6065 prop->property = eina_stringshare_add(property);
6066
6067 eina_hash_direct_add(pd->properties.model_lookup, prop->property, prop);
6068 eina_hash_direct_add(pd->properties.view_lookup, prop->key, prop);
6069
6070 _efl_ui_property_bind_get(pd, prop);
6071
6072
6073 return 0;
6074}
6075
6076static void
6077_efl_ui_widget_efl_ui_view_model_set(Eo *obj,
6078 Efl_Ui_Widget_Data *pd,
6079 Efl_Model *model)
6080{
6081 if (pd->properties.model)
6082 {
6083 // Remove any existing handler that might exist for any reason
6084 efl_event_callback_del(pd->properties.model, EFL_MODEL_EVENT_PROPERTIES_CHANGED,
6085 _efl_ui_model_property_bind_changed, pd);
6086 efl_event_callback_del(obj, EFL_UI_PROPERTY_BIND_EVENT_PROPERTIES_CHANGED,
6087 _efl_ui_view_property_bind_changed, pd);
6088 }
6089
6090 efl_replace(&pd->properties.model, model);
6091
6092 if (pd->properties.model && pd->properties.model_lookup)
6093 {
6094 // Set the properties handler just in case
6095 efl_event_callback_add(pd->properties.model, EFL_MODEL_EVENT_PROPERTIES_CHANGED,
6096 _efl_ui_model_property_bind_changed, pd);
6097 efl_event_callback_add(obj, EFL_UI_PROPERTY_BIND_EVENT_PROPERTIES_CHANGED,
6098 _efl_ui_view_property_bind_changed, pd);
6099 }
6100}
6101
6102static Efl_Model *
6103_efl_ui_widget_efl_ui_view_model_get(const Eo *obj EINA_UNUSED, Efl_Ui_Widget_Data *pd)
6104{
6105 return pd->properties.model;
6106}
6107
6108static void
6109_efl_ui_widget_efl_object_invalidate(Eo *obj, Efl_Ui_Widget_Data *pd)
6110{
6111 efl_invalidate(efl_super(obj, EFL_UI_WIDGET_CLASS));
6112
6113 if (pd->properties.model)
6114 {
6115 efl_event_callback_del(pd->properties.model, EFL_MODEL_EVENT_PROPERTIES_CHANGED,
6116 _efl_ui_model_property_bind_changed, pd);
6117 efl_event_callback_del(obj, EFL_UI_PROPERTY_BIND_EVENT_PROPERTIES_CHANGED,
6118 _efl_ui_view_property_bind_changed, pd);
6119 efl_replace(&pd->properties.model, NULL);
6120 }
6121 if (pd->properties.view_lookup) eina_hash_free(pd->properties.view_lookup);
6122 pd->properties.view_lookup = NULL;
6123 if (pd->properties.model_lookup) eina_hash_free(pd->properties.model_lookup);
6124 pd->properties.model_lookup = NULL;
6125}
6126
5943#include "efl_ui_widget_part_bg.eo.c" 6127#include "efl_ui_widget_part_bg.eo.c"
5944 6128
5945/* Efl.Part Bg end */ 6129/* Efl.Part Bg end */
diff --git a/src/lib/elementary/efl_ui_widget.eo b/src/lib/elementary/efl_ui_widget.eo
index edbdaa5331..21bbb3ebd4 100644
--- a/src/lib/elementary/efl_ui_widget.eo
+++ b/src/lib/elementary/efl_ui_widget.eo
@@ -16,7 +16,8 @@ struct Efl.Ui.Widget_Focus_State {
16abstract @beta Efl.Ui.Widget extends Efl.Canvas.Group implements Efl.Access.Object, 16abstract @beta Efl.Ui.Widget extends Efl.Canvas.Group implements Efl.Access.Object,
17 Efl.Access.Component, Efl.Part, Efl.Ui.Focus.Object, 17 Efl.Access.Component, Efl.Part, Efl.Ui.Focus.Object,
18 Efl.Ui.L10n, 18 Efl.Ui.L10n,
19 Efl.Ui.Selection, Efl.Ui.Dnd 19 Efl.Ui.Selection, Efl.Ui.Dnd,
20 Efl.Ui.Property_Bind, Efl.Ui.View
20{ 21{
21 [[Efl UI widget abstract class]] 22 [[Efl UI widget abstract class]]
22 //eo_prefix: efl_ui_widget; 23 //eo_prefix: efl_ui_widget;
@@ -388,6 +389,7 @@ abstract @beta Efl.Ui.Widget extends Efl.Canvas.Group implements Efl.Access.Obje
388 class.constructor; 389 class.constructor;
389 Efl.Object.constructor; 390 Efl.Object.constructor;
390 Efl.Object.finalize; 391 Efl.Object.finalize;
392 Efl.Object.invalidate;
391 Efl.Object.destructor; 393 Efl.Object.destructor;
392 Efl.Object.provider_find; 394 Efl.Object.provider_find;
393 Efl.Object.debug_name_override; 395 Efl.Object.debug_name_override;
@@ -415,6 +417,8 @@ abstract @beta Efl.Ui.Widget extends Efl.Canvas.Group implements Efl.Access.Obje
415 Efl.Ui.Focus.Object.on_focus_update; 417 Efl.Ui.Focus.Object.on_focus_update;
416 Efl.Ui.L10n.translation_update; [[This implements the calls to $gettext() and $text_set().]] 418 Efl.Ui.L10n.translation_update; [[This implements the calls to $gettext() and $text_set().]]
417 Efl.Part.part_get; [[Returns @Efl.Ui.Widget_Part.]] 419 Efl.Part.part_get; [[Returns @Efl.Ui.Widget_Part.]]
420 Efl.Ui.View.model { get; set; }
421 Efl.Ui.Property_Bind.property_bind;
418 } 422 }
419 constructors { 423 constructors {
420 .style @optional; 424 .style @optional;
diff --git a/src/lib/elementary/elm_widget.h b/src/lib/elementary/elm_widget.h
index 0b8a5df5cb..f6eb21cec7 100644
--- a/src/lib/elementary/elm_widget.h
+++ b/src/lib/elementary/elm_widget.h
@@ -383,6 +383,11 @@ typedef struct _Elm_Widget_Smart_Data
383 Evas_Object *prev, *next, *up, *down, *right, *left; 383 Evas_Object *prev, *next, *up, *down, *right, *left;
384 Elm_Object_Item *item_prev, *item_next, *item_up, *item_down, *item_right, *item_left; 384 Elm_Object_Item *item_prev, *item_next, *item_up, *item_down, *item_right, *item_left;
385 } legacy_focus; 385 } legacy_focus;
386 struct {
387 Efl_Model *model;
388 Eina_Hash *model_lookup;
389 Eina_Hash *view_lookup;
390 } properties;
386 Eina_Bool scroll_x_locked : 1; 391 Eina_Bool scroll_x_locked : 1;
387 Eina_Bool scroll_y_locked : 1; 392 Eina_Bool scroll_y_locked : 1;
388 393