aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLarry Jr <larry.olj@gmail.com>2016-07-01 20:45:30 -0300
committerVitor Sousa <vitorsousasilva@gmail.com>2016-07-05 14:13:03 -0300
commitae26833fbd550ebb92f7305db118db50935c0d50 (patch)
tree33fe6ec17afd864aaa5dd5df273ff1939533528e
parentelm widget - stop segv during shutdown when objects become deleted (diff)
downloadefl-ae26833fbd550ebb92f7305db118db50935c0d50.tar.gz
elementary: add model connect in elm_layout
add 2 new interfaces efl_ui_view and efl_ui_model_connect now elm_layout can update elements from model connectected efl_ui_view_model_set(layout, model) efl_ui_model_connect(layout, "part_name", "property")
-rw-r--r--src/Makefile_Efl.am2
-rw-r--r--src/lib/efl/Efl.h3
-rw-r--r--src/lib/efl/interfaces/efl_interfaces_main.c2
-rw-r--r--src/lib/efl/interfaces/efl_ui_model_connect.eo11
-rw-r--r--src/lib/efl/interfaces/efl_ui_view.eo12
-rw-r--r--src/lib/elementary/elm_layout.c185
-rw-r--r--src/lib/elementary/elm_layout.eo5
-rw-r--r--src/lib/elementary/elm_widget_layout.h3
8 files changed, 222 insertions, 1 deletions
diff --git a/src/Makefile_Efl.am b/src/Makefile_Efl.am
index ac5edda4e4..375adc6af6 100644
--- a/src/Makefile_Efl.am
+++ b/src/Makefile_Efl.am
@@ -42,6 +42,8 @@ efl_eolian_files = \
lib/efl/interfaces/efl_vpath_file_core.eo \
lib/efl/interfaces/efl_ui_spin.eo \
lib/efl/interfaces/efl_ui_progress.eo \
+ lib/efl/interfaces/efl_ui_view.eo \
+ lib/efl/interfaces/efl_ui_model_connect.eo \
lib/efl/interfaces/efl_event.eo \
lib/efl/interfaces/efl_input_interface.eo \
lib/efl/interfaces/efl_input_state.eo \
diff --git a/src/lib/efl/Efl.h b/src/lib/efl/Efl.h
index 3a00bb5b28..0105cdd329 100644
--- a/src/lib/efl/Efl.h
+++ b/src/lib/efl/Efl.h
@@ -114,6 +114,9 @@ EAPI extern const Eo_Event_Description _EFL_GFX_PATH_CHANGED;
#include "interfaces/efl_canvas.eo.h"
+#include "interfaces/efl_ui_view.eo.h"
+#include "interfaces/efl_ui_model_connect.eo.h"
+
/* Packing & containers */
#include "interfaces/efl_container.eo.h"
#include "interfaces/efl_pack.eo.h"
diff --git a/src/lib/efl/interfaces/efl_interfaces_main.c b/src/lib/efl/interfaces/efl_interfaces_main.c
index d497be9107..52cebf33ac 100644
--- a/src/lib/efl/interfaces/efl_interfaces_main.c
+++ b/src/lib/efl/interfaces/efl_interfaces_main.c
@@ -53,6 +53,8 @@ EAPI const Eo_Event_Description _EFL_GFX_PATH_CHANGED =
#include "interfaces/efl_flipable.eo.c"
#include "interfaces/efl_ui_spin.eo.c"
#include "interfaces/efl_ui_progress.eo.c"
+#include "interfaces/efl_ui_view.eo.c"
+#include "interfaces/efl_ui_model_connect.eo.c"
#include "interfaces/efl_event.eo.c"
#include "interfaces/efl_input_state.eo.c"
diff --git a/src/lib/efl/interfaces/efl_ui_model_connect.eo b/src/lib/efl/interfaces/efl_ui_model_connect.eo
new file mode 100644
index 0000000000..e855e1d978
--- /dev/null
+++ b/src/lib/efl/interfaces/efl_ui_model_connect.eo
@@ -0,0 +1,11 @@
+interface Efl.Ui.Model.Connect
+{
+ methods {
+ connect {
+ params {
+ name: string;
+ properties: string;
+ }
+ }
+ }
+}
diff --git a/src/lib/efl/interfaces/efl_ui_view.eo b/src/lib/efl/interfaces/efl_ui_view.eo
new file mode 100644
index 0000000000..e5957ee445
--- /dev/null
+++ b/src/lib/efl/interfaces/efl_ui_view.eo
@@ -0,0 +1,12 @@
+interface Efl.Ui.View ()
+{
+ methods {
+ @property model {
+ [[Model that is/will be ]]
+ get {} set {}
+ values {
+ model: Efl.Model;
+ }
+ }
+ }
+}
diff --git a/src/lib/elementary/elm_layout.c b/src/lib/elementary/elm_layout.c
index 97e7bc3520..e0f5d2dcaf 100644
--- a/src/lib/elementary/elm_layout.c
+++ b/src/lib/elementary/elm_layout.c
@@ -19,6 +19,7 @@
#define MY_CLASS_NAME_LEGACY "elm_layout"
Eo *_elm_layout_pack_proxy_get(Elm_Layout *obj, Evas_Object *pack, const char *part);
+static void _efl_model_properties_changed_cb(void *, const Eo_Event *);
static const char SIG_THEME_CHANGED[] = "theme,changed";
const char SIG_LAYOUT_FOCUSED[] = "focused";
@@ -107,6 +108,13 @@ struct _Elm_Layout_Sub_Object_Cursor
Eina_Bool engine_only : 1;
};
+typedef struct _Elm_Layout_Sub_Property_Promise Elm_Layout_Sub_Property_Promise;
+struct _Elm_Layout_Sub_Property_Promise
+{
+ Elm_Layout_Smart_Data *pd;
+ Eina_Stringshare *name;
+};
+
static void
_on_sub_object_size_hint_change(void *data,
Evas *e EINA_UNUSED,
@@ -818,6 +826,15 @@ _elm_layout_efl_canvas_group_group_del(Eo *obj, Elm_Layout_Smart_Data *sd)
free(esd);
}
+ if(sd->model)
+ {
+ eo_event_callback_del(sd->model, EFL_MODEL_EVENT_PROPERTIES_CHANGED, _efl_model_properties_changed_cb, sd);
+ eo_unref(sd->model);
+ sd->model = NULL;
+ }
+ eina_hash_free(sd->prop_connect);
+ sd->prop_connect = NULL;
+
eina_stringshare_del(sd->klass);
eina_stringshare_del(sd->group);
@@ -1332,6 +1349,30 @@ _elm_layout_text_set(Eo *obj, Elm_Layout_Smart_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)
+ {
+ Eina_Hash_Tuple *tuple;
+ Eina_Iterator *it = eina_hash_iterator_tuple_new(sd->prop_connect);
+
+ while (eina_iterator_next(it, (void **)&tuple))
+ {
+ if (tuple->data == sub_d->part)
+ {
+ Eina_Value v;
+ eina_value_setup(&v, EINA_VALUE_TYPE_STRING);
+ eina_value_set(&v, text);
+ efl_model_property_set(sd->model, tuple->key, &v, NULL);
+ eina_value_flush(&v);
+ break;
+ }
+ }
+
+ eina_iterator_free(it);
+ }
+
+ sd->view_updated = EINA_FALSE;
+
return EINA_TRUE;
}
@@ -1909,6 +1950,150 @@ _elm_layout_eo_base_dbg_info_get(Eo *eo_obj, Elm_Layout_Smart_Data *_pd EINA_UNU
}
}
+static void
+_prop_promise_error_cb(void* data, Eina_Error err EINA_UNUSED)
+{
+ Elm_Layout_Sub_Property_Promise *sub_pp = data;
+
+ eina_stringshare_del(sub_pp->name);
+ free(sub_pp);
+}
+
+static void
+_prop_promise_then_cb(void* data, void* v)
+{
+ Elm_Layout_Sub_Property_Promise *sub_pp = data;
+ Elm_Layout_Smart_Data *pd = sub_pp->pd;
+ Eina_Value *value = v;
+ char *text;
+
+ const Eina_Value_Type *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);
+ elm_layout_text_set(pd->obj, sub_pp->name, text);
+ }
+ else
+ {
+ text = eina_value_to_string(value);
+ elm_layout_text_set(pd->obj, sub_pp->name, text);
+ free(text);
+ }
+
+ eina_stringshare_del(sub_pp->name);
+ free(sub_pp);
+}
+
+static void
+_efl_model_properties_changed_cb(void *data, const Eo_Event *event)
+{
+ Elm_Layout_Smart_Data *pd = data;
+ Efl_Model_Property_Event *evt = event->info;
+ Elm_Layout_Sub_Property_Promise *sub_pp;
+ Eina_Stringshare *name;
+ Eina_Array_Iterator it;
+ Eina_Promise *promise;
+ const char *prop;
+ unsigned int i;
+
+ if (!evt->changed_properties)
+ return;
+
+ EINA_ARRAY_ITER_NEXT(evt->changed_properties, i, prop, it)
+ {
+ name = eina_hash_find(pd->prop_connect, prop);
+ if (name)
+ {
+ sub_pp = ELM_NEW(Elm_Layout_Sub_Property_Promise);
+ sub_pp->pd = pd;
+ sub_pp->name = name;
+ eina_stringshare_ref(sub_pp->name);
+ promise = efl_model_property_get(pd->model, prop);
+ eina_promise_then(promise, &_prop_promise_then_cb,
+ &_prop_promise_error_cb, sub_pp);
+ }
+ }
+}
+
+static Eina_Bool
+_elm_layout_view_update_fn(const Eina_Hash *hash EINA_UNUSED, const void *key, void *data, void *fdata)
+{
+ Elm_Layout_Smart_Data *pd = fdata;
+ Eina_Stringshare *prop = key;
+ Eina_Stringshare *name = data;
+
+ if (name)
+ {
+ Elm_Layout_Sub_Property_Promise *sub_pp = ELM_NEW(Elm_Layout_Sub_Property_Promise);
+ Eina_Promise *promise = efl_model_property_get(pd->model, prop);
+ sub_pp->pd = pd;
+ sub_pp->name = eina_stringshare_ref(name);
+ eina_promise_then(promise, &_prop_promise_then_cb,
+ &_prop_promise_error_cb, sub_pp);
+ }
+ return EINA_TRUE;
+}
+
+EOLIAN static void
+_elm_layout_efl_ui_view_model_set(Eo *obj EINA_UNUSED, Elm_Layout_Smart_Data *pd, Efl_Model *model)
+{
+ if (pd->model)
+ {
+ eo_event_callback_del(pd->model, EFL_MODEL_EVENT_PROPERTIES_CHANGED, _efl_model_properties_changed_cb, pd);
+ eo_unref(pd->model);
+ pd->model = NULL;
+ }
+
+ if (model)
+ {
+ pd->model = model;
+ eo_ref(pd->model);
+ eo_event_callback_add(pd->model, EFL_MODEL_EVENT_PROPERTIES_CHANGED, _efl_model_properties_changed_cb, pd);
+ }
+
+ if (pd->prop_connect) eina_hash_foreach(pd->prop_connect, _elm_layout_view_update_fn, pd);
+}
+
+EOLIAN static Efl_Model *
+_elm_layout_efl_ui_view_model_get(Eo *obj EINA_UNUSED, Elm_Layout_Smart_Data *pd)
+{
+ return pd->model;
+}
+
+EOLIAN static void
+_elm_layout_efl_ui_model_connect_connect(Eo *obj EINA_UNUSED, Elm_Layout_Smart_Data *pd, const char *name, const char *property)
+{
+ EINA_SAFETY_ON_NULL_RETURN(name);
+ Eina_Stringshare *ss_name, *ss_prop;
+
+ if (!_elm_layout_part_aliasing_eval(obj, pd, &name, EINA_TRUE))
+ return;
+
+ ss_name = eina_stringshare_add(name);
+ ss_prop = eina_stringshare_add(property);
+ if (!pd->prop_connect)
+ {
+ pd->prop_connect = eina_hash_stringshared_new(EINA_FREE_CB(eina_stringshare_del));
+ }
+
+ eina_stringshare_del(eina_hash_set(pd->prop_connect, ss_prop, ss_name));
+
+ if (pd->model)
+ {
+ Eina_Promise *promise;
+ Elm_Layout_Sub_Property_Promise *sub_pp = ELM_NEW(Elm_Layout_Sub_Property_Promise);
+
+ sub_pp->pd = pd;
+ sub_pp->name = eina_stringshare_ref(ss_name);
+
+ promise = efl_model_property_get(pd->model, ss_prop);
+ eina_promise_then(promise, &_prop_promise_then_cb,
+ &_prop_promise_error_cb, sub_pp);
+ }
+}
+
EAPI Evas_Object *
elm_layout_add(Evas_Object *parent)
{
diff --git a/src/lib/elementary/elm_layout.eo b/src/lib/elementary/elm_layout.eo
index 40c6401953..d68323f318 100644
--- a/src/lib/elementary/elm_layout.eo
+++ b/src/lib/elementary/elm_layout.eo
@@ -17,7 +17,7 @@ struct Elm.Layout_Part_Alias_Description
real_part: string; [[Target part name for the alias set on Elm.Layout_Part_Proxies_Description::real_part. An example of usage would be "default" on that field, with "elm.content.swallow" on this one]]
}
-class Elm.Layout (Elm.Widget, Efl.Part, Efl.Container, Efl.File, Edje.Object)
+class Elm.Layout (Elm.Widget, Efl.Part, Efl.Container, Efl.File, Edje.Object, Efl.Ui.View, Efl.Ui.Model.Connect)
{
legacy_prefix: elm_layout;
eo_prefix: elm_obj_layout;
@@ -256,6 +256,9 @@ class Elm.Layout (Elm.Widget, Efl.Part, Efl.Container, Efl.File, Edje.Object)
Edje.Object.thaw;
Edje.Object.signal_callback_add;
Edje.Object.signal_callback_del;
+ Efl.Ui.View.model.set;
+ Efl.Ui.View.model.get;
+ Efl.Ui.Model.Connect.connect;
}
events {
theme,changed;
diff --git a/src/lib/elementary/elm_widget_layout.h b/src/lib/elementary/elm_widget_layout.h
index ded10f3d67..eb7fe79e52 100644
--- a/src/lib/elementary/elm_widget_layout.h
+++ b/src/lib/elementary/elm_widget_layout.h
@@ -53,6 +53,8 @@ typedef struct _Elm_Layout_Smart_Data
Eina_List *subs; /**< List of Elm_Layout_Sub_Object_Data structs, to hold the actual sub objects such as text, content and the children of box and table. */
Eina_List *edje_signals; /**< The list of edje signal callbacks. */
Eina_List *parts_cursors; /**< The list of cursor names of layout parts. This is a list of Elm_Layout_Sub_Object_Cursor struct. */
+ Eina_Hash *prop_connect; /**< The list of properties connected to layout parts. */
+ Efl_Model *model; /**< The model */
const char *klass; /**< 1st identifier of an edje object group which is used in theme_set. klass and group are used together. */
const char *group; /**< 2nd identifier of an edje object group which is used in theme_set. klass and group are used together. */
int frozen; /**< Layout freeze counter */
@@ -63,6 +65,7 @@ typedef struct _Elm_Layout_Smart_Data
Eina_Bool can_access : 1; /**< This is true when all text(including textblock) parts can be accessible by accessibility. */
Eina_Bool destructed_is : 1; /**< This flag indicates if Elm_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 Elm_Layout source is set from a file*/
+ Eina_Bool view_updated : 1; /**< This flag indicates to Elm_Layout don't update model in text_set */
} Elm_Layout_Smart_Data;
/**