cedric pushed a commit to branch master.

http://git.enlightenment.org/core/efl.git/commit/?id=a5a7c67bdfa76f4c056f89e09b6df664a106b4b0

commit a5a7c67bdfa76f4c056f89e09b6df664a106b4b0
Author: Cedric BAIL <[email protected]>
Date:   Thu Aug 8 14:18:19 2019 -0700

    elementary: add support for efl_ui_property_bind to all efl_part inheriting 
from widget using reflection.
    
    Reviewed-by: Felipe Magno de Almeida <[email protected]>
    Differential Revision: https://phab.enlightenment.org/D9528
---
 src/lib/elementary/efl_ui_widget.c       | 61 +++++++++++++++++++++++++++-----
 src/lib/elementary/efl_ui_widget_part.eo |  3 +-
 2 files changed, 55 insertions(+), 9 deletions(-)

diff --git a/src/lib/elementary/efl_ui_widget.c 
b/src/lib/elementary/efl_ui_widget.c
index e99465b856..0bd18da183 100644
--- a/src/lib/elementary/efl_ui_widget.c
+++ b/src/lib/elementary/efl_ui_widget.c
@@ -53,6 +53,10 @@ typedef struct _Elm_Event_Cb_Data         Elm_Event_Cb_Data;
 typedef struct _Elm_Label_Data            Elm_Label_Data;
 typedef struct _Elm_Translate_String_Data Elm_Translate_String_Data;
 
+static Eina_Error _efl_ui_property_bind(Eo *widget, Eo *target, 
Efl_Ui_Widget_Data *pd,
+                                        const char *part,
+                                        const char *key, const char *property);
+
 struct _Elm_Event_Cb_Data
 {
    Elm_Event_Cb func;
@@ -5567,6 +5571,19 @@ _efl_ui_widget_part_efl_gfx_entity_geometry_get(const Eo 
*obj EINA_UNUSED, Elm_P
    return efl_gfx_entity_geometry_get(efl_part(sd->resize_obj, pd->part));
 }
 
+static Eina_Error
+_efl_ui_widget_part_efl_ui_property_bind_property_bind(Eo *obj, Elm_Part_Data 
*ppd,
+                                                       const char *key, const 
char *property)
+{
+   Efl_Ui_Widget_Data *pd;
+   Eo *widget;
+
+   widget = efl_parent_get(obj);
+   pd = efl_data_scope_get(widget, EFL_UI_WIDGET_CLASS);
+
+   return _efl_ui_property_bind(widget, obj, pd, ppd->part, key, property);
+}
+
 #define EFL_UI_WIDGET_PART_EXTRA_OPS \
    EFL_OBJECT_OP_FUNC(efl_canvas_layout_part_type_get, 
_efl_ui_widget_part_efl_canvas_layout_part_type_get), \
    EFL_OBJECT_OP_FUNC(efl_gfx_entity_geometry_get, 
_efl_ui_widget_part_efl_gfx_entity_geometry_get)
@@ -5695,6 +5712,7 @@ _efl_ui_widget_part_bg_efl_gfx_image_scale_type_get(const 
Eo *obj, void *pd EINA
 typedef struct _Efl_Ui_Property_Bound Efl_Ui_Property_Bound;
 struct _Efl_Ui_Property_Bound
 {
+   Eina_Stringshare *part; // Optional part to apply the property on
    Eina_Stringshare *key; // Local object property
    Eina_Stringshare *property; // Model property
    Eina_Future *f;
@@ -5705,6 +5723,7 @@ _efl_ui_property_bind_free(void *data)
 {
    Efl_Ui_Property_Bound *prop = data;
 
+   eina_stringshare_del(prop->part);
    eina_stringshare_del(prop->key);
    eina_stringshare_del(prop->property);
    free(prop);
@@ -5723,11 +5742,20 @@ _efl_ui_property_bind_clean(Eo *obj EINA_UNUSED,
 static void
 _efl_ui_property_bind_get(Efl_Ui_Widget_Data *pd, Efl_Ui_Property_Bound *prop)
 {
-   Eina_Value *value = efl_model_property_get(pd->properties.model, 
prop->property);
+   Eina_Value *value;
    Eina_Future *f;
    Eina_Error err;
+   Eo *target;
+
+   // If there is no model set yet, no need to try anything
+   if (!pd->properties.model) return ;
+
+   value = efl_model_property_get(pd->properties.model, prop->property);
+   target = prop->part ? efl_part(pd->obj, prop->part) : pd->obj;
 
-   err = efl_property_reflection_set(pd->obj, prop->key, 
eina_value_reference_copy(value));
+   fprintf(stderr, "setting: %s for %s from %s\n",
+           eina_value_to_string(value), prop->property, 
efl_debug_name_get(pd->properties.model));
+   err = efl_property_reflection_set(target, prop->key, 
eina_value_reference_copy(value));
    eina_value_free(value);
 
    if (!err) return ;
@@ -5742,8 +5770,12 @@ _efl_ui_property_bind_get(Efl_Ui_Widget_Data *pd, 
Efl_Ui_Property_Bound *prop)
 static void
 _efl_ui_property_bind_set(Efl_Ui_Widget_Data *pd, Efl_Ui_Property_Bound *prop)
 {
-   Eina_Value value = efl_property_reflection_get(pd->obj, prop->key);
+   Eina_Value value;
    Eina_Future *f;
+   Eo *target;
+
+   target = prop->part ? efl_part(pd->obj, prop->part) : pd->obj;
+   value = efl_property_reflection_get(target, prop->key);
 
    if (prop->f) eina_future_cancel(prop->f);
    f = efl_model_property_set(pd->properties.model, prop->property, 
eina_value_dup(&value));
@@ -5796,6 +5828,7 @@ _efl_ui_widget_model_update(Efl_Ui_Widget_Data *pd)
    it = eina_hash_iterator_data_new(pd->properties.model_lookup);
    EINA_ITERATOR_FOREACH(it, property)
      _efl_ui_property_bind_get(pd, property);
+   eina_iterator_free(it);
 }
 
 static void _efl_ui_widget_model_provider_model_change(void *data, const 
Efl_Event *event EINA_UNUSED);
@@ -5882,19 +5915,20 @@ _efl_ui_widget_model_unregister(Eo *obj, 
Efl_Ui_Widget_Data *pd)
    if (pd->properties.provider)
      _efl_ui_widget_model_provider_invalidate(pd, NULL);
 }
+
 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)
+_efl_ui_property_bind(Eo *widget, Eo *target, Efl_Ui_Widget_Data *pd,
+                      const char *part, const char *key, const char *property)
 {
    Efl_Ui_Property_Bound *prop;
 
    // Always check for a model and fetch a provider in case a binded property
    // is provided by a class down the hierarchy, but they still need to be 
notified
    // when a model change
-   _efl_ui_widget_model_register(obj, pd);
+   _efl_ui_widget_model_register(widget, pd);
 
    // Check if the property is available from the reflection table of the 
object.
-   if (!efl_property_reflection_exist(obj, key)) return 
EFL_PROPERTY_ERROR_INVALID_KEY;
+   if (!efl_property_reflection_exist(target, key)) return 
EFL_PROPERTY_ERROR_INVALID_KEY;
 
    if (!pd->properties.model_lookup)
      {
@@ -5904,6 +5938,7 @@ _efl_ui_widget_efl_ui_property_bind_property_bind(Eo 
*obj, Efl_Ui_Widget_Data *p
 
    prop = calloc(1, sizeof (Efl_Ui_Property_Bound));
    if (!prop) return ENOMEM;
+   prop->part = eina_stringshare_add(part);
    prop->key = eina_stringshare_add(key);
    prop->property = eina_stringshare_add(property);
 
@@ -5912,11 +5947,21 @@ _efl_ui_widget_efl_ui_property_bind_property_bind(Eo 
*obj, Efl_Ui_Widget_Data *p
 
    _efl_ui_property_bind_get(pd, prop);
 
-   efl_event_callback_call(obj, EFL_UI_PROPERTY_BIND_EVENT_PROPERTY_BOUND, 
(void*) prop->key);
+   efl_event_callback_call(widget, EFL_UI_PROPERTY_BIND_EVENT_PROPERTY_BOUND, 
(void*) prop->key);
+   // In case of part, we emit it also on the part so that the part too can 
act on it
+   if (target)
+     efl_event_callback_call(target, 
EFL_UI_PROPERTY_BIND_EVENT_PROPERTY_BOUND, (void*) prop->key);
 
    return 0;
 }
 
+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)
+{
+   return _efl_ui_property_bind(obj, obj, pd, NULL, key, property);
+}
+
 static void
 _efl_ui_widget_efl_ui_view_model_set(Eo *obj,
                                      Efl_Ui_Widget_Data *pd,
diff --git a/src/lib/elementary/efl_ui_widget_part.eo 
b/src/lib/elementary/efl_ui_widget_part.eo
index a2a51baf9f..e629fdcfa2 100644
--- a/src/lib/elementary/efl_ui_widget_part.eo
+++ b/src/lib/elementary/efl_ui_widget_part.eo
@@ -1,4 +1,4 @@
-class @beta Efl.Ui.Widget_Part extends Efl.Object
+class @beta Efl.Ui.Widget_Part extends Efl.Object implements 
Efl.Ui.Property_Bind
 {
    [[This is the base class for all "Part" handles in Efl.Ui widgets.
 
@@ -9,5 +9,6 @@ class @beta Efl.Ui.Widget_Part extends Efl.Object
    data: Elm_Part_Data;
    implements {
       Efl.Object.destructor;
+      Efl.Ui.Property_Bind.property_bind;
    }
 }

-- 


Reply via email to