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")
This commit is contained in:
Larry Jr 2016-07-01 20:45:30 -03:00 committed by Vitor Sousa
parent 38ba68a7c7
commit ae26833fbd
8 changed files with 222 additions and 1 deletions

View File

@ -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 \

View File

@ -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"

View File

@ -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"

View File

@ -0,0 +1,11 @@
interface Efl.Ui.Model.Connect
{
methods {
connect {
params {
name: string;
properties: string;
}
}
}
}

View File

@ -0,0 +1,12 @@
interface Efl.Ui.View ()
{
methods {
@property model {
[[Model that is/will be ]]
get {} set {}
values {
model: Efl.Model;
}
}
}
}

View File

@ -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)
{

View File

@ -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;

View File

@ -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;
/**