summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFelipe Magno de Almeida <felipe@expertisesolutions.com.br>2017-09-07 12:07:08 +0900
committerFelipe Magno de Almeida <felipe@expertisesolutions.com.br>2017-09-07 14:23:56 +0900
commitc03afadf40560ad5fdddf08a817eb33acf6459b2 (patch)
tree4632acd84aeb870d57c046854eb5557bbf320f29
parentdf9f2e07722fa384cba09e934351e90f0d237009 (diff)
downloadefl-c03afadf40560ad5fdddf08a817eb33acf6459b2.tar.gz
elm: Fix multiple connections from model to properties in Layout
-rw-r--r--src/lib/elementary/efl_ui_layout.c234
1 files changed, 95 insertions, 139 deletions
diff --git a/src/lib/elementary/efl_ui_layout.c b/src/lib/elementary/efl_ui_layout.c
index 605fc15f28..a2b3c7e0d2 100644
--- a/src/lib/elementary/efl_ui_layout.c
+++ b/src/lib/elementary/efl_ui_layout.c
@@ -66,6 +66,7 @@ static const char *_efl_ui_layout_swallow_parts[] = {
typedef struct _Efl_Ui_Layout_Sub_Object_Data Efl_Ui_Layout_Sub_Object_Data;
typedef struct _Efl_Ui_Layout_Sub_Object_Cursor Efl_Ui_Layout_Sub_Object_Cursor;
typedef struct _Efl_Ui_Layout_Sub_Iterator Efl_Ui_Layout_Sub_Iterator;
+typedef struct _Efl_Ui_Layout_Sub_Connect Efl_Ui_Layout_Sub_Connect;
struct _Efl_Ui_Layout_Sub_Iterator
{
@@ -111,11 +112,13 @@ struct _Efl_Ui_Layout_Sub_Object_Cursor
Eina_Bool engine_only : 1;
};
-typedef struct _Efl_Ui_Layout_Sub_Property_Future Efl_Ui_Layout_Sub_Property_Future;
-struct _Efl_Ui_Layout_Sub_Property_Future
+struct _Efl_Ui_Layout_Sub_Connect
{
- Efl_Ui_Layout_Data *pd;
- Eina_Array *name_arr;
+ Eina_Stringshare *name;
+ Eina_Stringshare *property;
+ Eina_Bool is_signal;
+ Eo *obj;
+ Efl_Future *future;
};
static void
@@ -745,6 +748,7 @@ _efl_ui_layout_efl_canvas_group_group_del(Eo *obj, Efl_Ui_Layout_Data *sd)
{
Efl_Ui_Layout_Sub_Object_Data *sub_d;
Efl_Ui_Layout_Sub_Object_Cursor *pc;
+ Efl_Ui_Layout_Sub_Connect *sc;
Edje_Signal_Data *esd;
Evas_Object *child;
Eina_List *l;
@@ -778,7 +782,15 @@ _efl_ui_layout_efl_canvas_group_group_del(Eo *obj, Efl_Ui_Layout_Data *sd)
efl_unref(sd->model);
sd->model = NULL;
}
- eina_hash_free(sd->prop_connect);
+
+ EINA_LIST_FREE(sd->prop_connect, sc)
+ {
+ if (sc->future) efl_future_cancel(sc->future);
+ sc->future = NULL;
+ eina_stringshare_del(sc->name);
+ eina_stringshare_del(sc->property);
+ free(sc);
+ }
sd->prop_connect = NULL;
eina_hash_free(sd->factories);
sd->factories = NULL;
@@ -1226,6 +1238,7 @@ _efl_ui_layout_text_set(Eo *obj, Efl_Ui_Layout_Data *sd, const char *part, const
Eina_List *l;
Efl_Ui_Layout_Sub_Object_Data *sub_d = NULL;
+ Efl_Ui_Layout_Sub_Connect *sc;
if (!_elm_layout_part_aliasing_eval(obj, &part, EINA_TRUE))
return EINA_FALSE;
@@ -1274,20 +1287,22 @@ _efl_ui_layout_text_set(Eo *obj, Efl_Ui_Layout_Data *sd, const char *part, const
sub_d->obj = _elm_access_edje_object_part_object_register
(obj, elm_layout_edje_get(obj), part);
- if (sd->model && !sd->view_updated)
+ if (sd->model)
{
- Eina_Stringshare *prop = eina_hash_find(sd->prop_connect, sub_d->part);
- if (prop)
+ EINA_LIST_FOREACH(sd->prop_connect, l, sc)
{
- Eina_Value v;
- eina_value_setup(&v, EINA_VALUE_TYPE_STRING);
- eina_value_set(&v, text);
- efl_model_property_set(sd->model, prop, &v);
- eina_value_flush(&v);
+ if (sc->name == sub_d->part && !sd->view_updated)
+ {
+ Eina_Value v;
+ eina_value_setup(&v, EINA_VALUE_TYPE_STRING);
+ eina_value_set(&v, text);
+ efl_model_property_set(sd->model, sc->property, &v);
+ eina_value_flush(&v);
+ break;
+ }
}
}
- sd->view_updated = EINA_FALSE;
return EINA_TRUE;
}
@@ -1889,110 +1904,70 @@ _efl_ui_layout_efl_object_dbg_info_get(Eo *eo_obj, Efl_Ui_Layout_Data *_pd EINA_
static void
_prop_future_error_cb(void* data, Efl_Event const*event EINA_UNUSED)
{
- Efl_Ui_Layout_Sub_Property_Future *sub_pp = data;
- Eina_Array_Iterator iterator;
- Eina_Stringshare *name;
- unsigned int i = 0;
-
- EINA_ARRAY_ITER_NEXT(sub_pp->name_arr, i, name, iterator)
- eina_stringshare_del(name);
-
- eina_array_free(sub_pp->name_arr);
- free(sub_pp);
+ Efl_Ui_Layout_Sub_Connect *sc = data;
+ sc->future = NULL;
}
static void
-_view_update(Efl_Ui_Layout_Data *pd, const char *name, const char *property)
+_view_update(Efl_Ui_Layout_Sub_Connect *sc, const char *property)
{
Eina_Strbuf *buf;
- if (strncmp(SIGNAL_PREFIX, name, sizeof(SIGNAL_PREFIX) -1) != 0)
+ if (sc->is_signal == EINA_FALSE)
{
- elm_layout_text_set(pd->obj, name, property);
+ EFL_UI_LAYOUT_DATA_GET(sc->obj, pd);
+ pd->view_updated = EINA_TRUE;
+ elm_layout_text_set(sc->obj, sc->name, property);
+ pd->view_updated = EINA_FALSE;
return;
}
- ELM_WIDGET_DATA_GET_OR_RETURN(pd->obj, wd);
-
buf = eina_strbuf_new();
- eina_strbuf_append(buf, name);
- eina_strbuf_remove(buf, 0, sizeof(SIGNAL_PREFIX)-1);
+ eina_strbuf_append(buf, sc->name);
eina_strbuf_replace_all(buf, "%v", property);
- edje_object_signal_emit(wd->resize_obj, eina_strbuf_string_get(buf), "elm");
+ elm_layout_signal_emit(sc->obj, eina_strbuf_string_get(buf), "elm");
eina_strbuf_free(buf);
}
static void
_prop_future_then_cb(void* data, Efl_Event const*event)
{
- Efl_Ui_Layout_Sub_Property_Future *sub_pp = data;
- Efl_Ui_Layout_Data *pd = sub_pp->pd;
- Eina_Accessor *value_acc = (Eina_Accessor *)((Efl_Future_Event_Success*)event->info)->value;
- Eina_Value *value;
- Eina_Stringshare *name;
+ Efl_Ui_Layout_Sub_Connect *sc = data;
+ const Eina_Value_Type *vtype;
+ Eina_Value *value = (Eina_Value *)((Efl_Future_Event_Success*)event->info)->value;
char *text;
- unsigned int i = 0;
- unsigned int acc_i = 0;
- while (eina_accessor_data_get(value_acc, acc_i, (void **)&value))
- {
- const Eina_Value_Type *vtype = eina_value_type_get(value);
- name = eina_array_data_get(sub_pp->name_arr, i);
+ sc->future = NULL;
+ vtype= eina_value_type_get(value);
- pd->view_updated = EINA_TRUE;
- if (vtype == EINA_VALUE_TYPE_STRING || vtype == EINA_VALUE_TYPE_STRINGSHARE)
- {
- eina_value_get(value, &text);
- _view_update(pd, name, text);
- }
- else
- {
- text = eina_value_to_string(value);
- _view_update(pd, name, text);
- free(text);
- }
- eina_stringshare_del(name);
- ++acc_i;
+ if (vtype == EINA_VALUE_TYPE_STRING || vtype == EINA_VALUE_TYPE_STRINGSHARE)
+ {
+ eina_value_get(value, &text);
+ _view_update(sc, text);
+ }
+ else
+ {
+ text = eina_value_to_string(value);
+ _view_update(sc, text);
+ free(text);
}
- eina_array_free(sub_pp->name_arr);
- free(sub_pp);
}
static void
_efl_ui_layout_view_model_update(Efl_Ui_Layout_Data *pd)
{
- Efl_Ui_Layout_Sub_Property_Future *sub_pp;
- Efl_Future **future_arr, **f, *future_all;
- Eina_Hash_Tuple *tuple;
- Eina_Iterator *it_p;
- int size;
+ Efl_Ui_Layout_Sub_Connect *sc;
+ Eina_List *l;
if (!pd->prop_connect || !pd->model) return;
- size = eina_hash_population(pd->prop_connect);
- if (size == 0) return;
-
- future_arr = alloca((size + 1) * sizeof(Efl_Future*));
- f = future_arr;
-
- sub_pp = ELM_NEW(Efl_Ui_Layout_Sub_Property_Future);
- sub_pp->pd = pd;
- sub_pp->name_arr = eina_array_new(size);
-
- it_p = eina_hash_iterator_tuple_new(pd->prop_connect);
- while (eina_iterator_next(it_p, (void **)&tuple))
+ EINA_LIST_FOREACH(pd->prop_connect, l, sc)
{
- *f = efl_model_property_get(pd->model, tuple->data);
- eina_array_push(sub_pp->name_arr, eina_stringshare_ref(tuple->key));
- f++;
+ if (sc->future) efl_future_cancel(sc->future);
+ sc->future = efl_model_property_get(pd->model, sc->property);
+ efl_future_then(sc->future, &_prop_future_then_cb, &_prop_future_error_cb, NULL, sc);
}
- eina_iterator_free(it_p);
- *f = NULL;
-
- future_all = efl_future_iterator_all(eina_carray_iterator_new((void**)future_arr));
-
- efl_future_then(future_all, &_prop_future_then_cb, &_prop_future_error_cb, NULL, sub_pp);
}
static void
@@ -2001,50 +1976,27 @@ _efl_model_properties_changed_cb(void *data, const Efl_Event *event)
Efl_Ui_Layout_Data *pd = data;
Efl_Model_Property_Event *evt = event->info;
Eina_Stringshare *ss_prop;
- Eina_Hash_Tuple *tuple;
- Eina_Array *names, *futures;
- Eina_Iterator *it_p;
+ Efl_Ui_Layout_Sub_Connect *sc;
const char *prop;
Eina_Array_Iterator it;
unsigned int i;
+ Eina_List *l;
if (!evt->changed_properties || !pd->prop_connect) return;
- names = eina_array_new(1);
- futures = eina_array_new(1);
-
EINA_ARRAY_ITER_NEXT(evt->changed_properties, i, prop, it)
{
ss_prop = eina_stringshare_add(prop);
- it_p = eina_hash_iterator_tuple_new(pd->prop_connect);
- while (eina_iterator_next(it_p, (void **)&tuple))
+ EINA_LIST_FOREACH(pd->prop_connect, l, sc)
{
- if (tuple->data == ss_prop)
+ if (sc->property == ss_prop)
{
- eina_array_push(names, eina_stringshare_ref(tuple->key));
- eina_array_push(futures, efl_model_property_get(pd->model, prop));
+ sc->future = efl_model_property_get(pd->model, sc->property);
+ efl_future_then(sc->future, &_prop_future_then_cb, &_prop_future_error_cb, NULL, sc);
}
}
- eina_iterator_free(it_p);
eina_stringshare_del(ss_prop);
}
-
- if (eina_array_count(names))
- {
- Efl_Ui_Layout_Sub_Property_Future *sub_pp;
- Efl_Future *future_all;
-
- sub_pp = ELM_NEW(Efl_Ui_Layout_Sub_Property_Future);
- sub_pp->pd = pd;
- sub_pp->name_arr = names;
-
- future_all = efl_future_iterator_all(eina_array_iterator_new(futures));
- efl_future_then(future_all, &_prop_future_then_cb, &_prop_future_error_cb, NULL, sub_pp);
- }
- else
- eina_array_free(names);
-
- eina_array_free(futures);
}
EOLIAN static void
@@ -2108,44 +2060,48 @@ EOLIAN static void
_efl_ui_layout_efl_ui_model_connect_connect(Eo *obj EINA_UNUSED, Efl_Ui_Layout_Data *pd, const char *name, const char *property)
{
EINA_SAFETY_ON_NULL_RETURN(name);
- Eina_Stringshare *ss_name, *ss_prop;
-
- if (property == NULL && pd->prop_connect)
- {
- ss_name = eina_stringshare_add(name);
- eina_hash_del(pd->prop_connect, ss_name, NULL);
- return;
- }
+ EINA_SAFETY_ON_NULL_RETURN(property);
+ Efl_Ui_Layout_Sub_Connect *sc, *fsc;
+ Eina_List *l;
if (!_elm_layout_part_aliasing_eval(obj, &name, EINA_TRUE))
return;
- ss_name = eina_stringshare_add(name);
- ss_prop = eina_stringshare_add(property);
- if (!pd->prop_connect)
+ sc = calloc(1, sizeof(*sc));
+ sc->obj = obj;
+ sc->property = eina_stringshare_add(property);
+
+ if (strncmp(SIGNAL_PREFIX, name, sizeof(SIGNAL_PREFIX) -1) == 0)
{
- pd->prop_connect = eina_hash_stringshared_new(EINA_FREE_CB(eina_stringshare_del));
+ sc->name = eina_stringshare_add(name+sizeof(SIGNAL_PREFIX) -1);
+ sc->is_signal = EINA_TRUE;
+ }
+ else
+ {
+ sc->name = eina_stringshare_add(name);
+ sc->is_signal = EINA_FALSE;
}
- eina_stringshare_del(eina_hash_set(pd->prop_connect, ss_name, ss_prop));
-
- if (pd->model)
+ EINA_LIST_FOREACH(pd->prop_connect, l, fsc)
{
- Efl_Ui_Layout_Sub_Property_Future *sub_pp = ELM_NEW(Efl_Ui_Layout_Sub_Property_Future);
- Efl_Future *futures[2] = {NULL,};
- Efl_Future *future_all = NULL;
+ if (fsc->name == sc->name && fsc->property == sc->property)
+ {
+ eina_stringshare_del(sc->name);
+ eina_stringshare_del(sc->property);
+ free(sc);
+ return;
+ }
+ }
- sub_pp->pd = pd;
- sub_pp->name_arr = eina_array_new(1);
- eina_array_push(sub_pp->name_arr, eina_stringshare_ref(ss_name));
- futures[0] = efl_model_property_get(pd->model, ss_prop);
+ pd->prop_connect = eina_list_append(pd->prop_connect, sc);
- future_all = efl_future_iterator_all(eina_carray_iterator_new((void**)futures));
- efl_future_then(future_all, &_prop_future_then_cb, &_prop_future_error_cb, NULL, sub_pp);
+ if (pd->model)
+ {
+ sc->future = efl_model_property_get(pd->model, sc->property);
+ efl_future_then(sc->future, &_prop_future_then_cb, &_prop_future_error_cb, NULL, sc);
}
}
-
EOLIAN static void
_efl_ui_layout_efl_ui_model_factory_connect_connect(Eo *obj EINA_UNUSED, Efl_Ui_Layout_Data *pd,
const char *name, Efl_Ui_Factory *factory)