diff options
author | Larry Jr <larry.olj@gmail.com> | 2016-07-01 20:45:30 -0300 |
---|---|---|
committer | Larry Jr <larry.olj@gmail.com> | 2016-07-28 15:19:52 -0300 |
commit | 0dfe2ccde8a3c372d57d3e03a4f1ab156a510add (patch) | |
tree | 2a1447a531e9168c677e2779100a2081782f8440 | |
parent | 742fbc5717f3b70a4f3c900f648f9cc761985966 (diff) | |
download | efl-0dfe2ccde8a3c372d57d3e03a4f1ab156a510add.tar.gz |
Efl-Interface, Elementary: Added Efl_Ui_View and Efl_Ui_Model interfaces
New interfaces:
Efl_Ui_View (to add model_get/set)
Efl_Ui_Model_Connect (connect part_name/property_name)
Efl_Ui_Factory (use model property to create new elements)
Efl_Ui_Factory_Connect (connect part_name/factory)
elm_layout and efl_ui_image use new interfaces
added new factory to create efl_ui_image
added example layout_model_connect
-rw-r--r-- | src/Makefile_Efl.am | 4 | ||||
-rw-r--r-- | src/Makefile_Elementary.am | 2 | ||||
-rw-r--r-- | src/examples/elementary/Makefile.am | 2 | ||||
-rw-r--r-- | src/examples/elementary/layout_model_connect.c | 164 | ||||
-rw-r--r-- | src/lib/efl/Efl.h | 5 | ||||
-rw-r--r-- | src/lib/efl/interfaces/efl_interfaces_main.c | 4 | ||||
-rw-r--r-- | src/lib/efl/interfaces/efl_ui_factory.eo | 19 | ||||
-rw-r--r-- | src/lib/efl/interfaces/efl_ui_model_connect.eo | 11 | ||||
-rw-r--r-- | src/lib/efl/interfaces/efl_ui_model_factory_connect.eo | 11 | ||||
-rw-r--r-- | src/lib/efl/interfaces/efl_ui_view.eo | 12 | ||||
-rw-r--r-- | src/lib/elementary/Elementary.h.in | 1 | ||||
-rw-r--r-- | src/lib/elementary/efl_ui_image.c | 111 | ||||
-rw-r--r-- | src/lib/elementary/efl_ui_image.eo | 6 | ||||
-rw-r--r-- | src/lib/elementary/efl_ui_image_factory.c | 59 | ||||
-rw-r--r-- | src/lib/elementary/efl_ui_image_factory.eo | 10 | ||||
-rw-r--r-- | src/lib/elementary/efl_ui_widget_image.h | 2 | ||||
-rw-r--r-- | src/lib/elementary/elm_layout.c | 241 | ||||
-rw-r--r-- | src/lib/elementary/elm_layout.eo | 7 | ||||
-rw-r--r-- | src/lib/elementary/elm_widget_layout.h | 4 |
19 files changed, 673 insertions, 2 deletions
diff --git a/src/Makefile_Efl.am b/src/Makefile_Efl.am index ac5edda4e4..6ba0309051 100644 --- a/src/Makefile_Efl.am +++ b/src/Makefile_Efl.am @@ -42,6 +42,10 @@ 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_ui_factory.eo \ + lib/efl/interfaces/efl_ui_model_factory_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/Makefile_Elementary.am b/src/Makefile_Elementary.am index c999455e32..70138f16ae 100644 --- a/src/Makefile_Elementary.am +++ b/src/Makefile_Elementary.am @@ -142,6 +142,7 @@ elm_public_eolian_files = \ lib/elementary/efl_ui_text.eo \ lib/elementary/efl_ui_text_editable.eo \ lib/elementary/efl_config_global.eo \ + lib/elementary/efl_ui_image_factory.eo \ $(NULL) # Private classes (not exposed or shipped) @@ -697,6 +698,7 @@ lib_elementary_libelementary_la_SOURCES = \ lib/elementary/efl_ui_grid_static.c \ lib/elementary/efl_ui_grid_private.h \ lib/elementary/efl_ui_text.c \ + lib/elementary/efl_ui_image_factory.c \ $(NULL) diff --git a/src/examples/elementary/Makefile.am b/src/examples/elementary/Makefile.am index 1b08ee0b78..c609741962 100644 --- a/src/examples/elementary/Makefile.am +++ b/src/examples/elementary/Makefile.am @@ -116,6 +116,7 @@ layout_example.edc \ layout_example_01.c \ layout_example_02.c \ layout_example_03.c \ +layout_model_connect.c \ list_example_01.c \ list_example_02.c \ list_example_03.c \ @@ -314,6 +315,7 @@ label_example_01 \ layout_example_01 \ layout_example_02 \ layout_example_03 \ +layout_model_connect \ list_example_01 \ list_example_02 \ list_example_03 \ diff --git a/src/examples/elementary/layout_model_connect.c b/src/examples/elementary/layout_model_connect.c new file mode 100644 index 0000000000..6f78e6f7a6 --- /dev/null +++ b/src/examples/elementary/layout_model_connect.c @@ -0,0 +1,164 @@ +// gcc -o layout_model_connect layout_model_connect.c `pkg-config --cflags --libs elementary` + +#ifdef HAVE_CONFIG_H +# include "config.h" +#else +# define EFL_BETA_API_SUPPORT 1 +# define EFL_EO_API_SUPPORT 1 +#endif + +#include <Elementary.h> +#include <Efl.h> +#include <Eio.h> +#include <stdio.h> + +#define EFL_MODEL_TEST_FILENAME_PATH "/tmp" + +struct _Layout_Model_Data +{ + Eo *fileview; + Eo *model; + Evas_Object *label; + Evas_Object *entry; + Evas_Object *img; + Evas_Object *bt; +}; +typedef struct _Layout_Model_Data Layout_Model_Data; + +static void +_cleanup_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) +{ + Layout_Model_Data *priv = (Layout_Model_Data*)data; + eo_unref(priv->fileview); + eo_unref(priv->model); +} + +static void +_list_selected_cb(void *data EINA_UNUSED, const Eo_Event *event) +{ + Layout_Model_Data *priv = data; + Eo *child = event->info; + + printf("LIST selected model\n"); + efl_ui_view_model_set(priv->label, child); + efl_ui_view_model_set(priv->entry, child); + efl_ui_view_model_set(priv->img, child); + efl_ui_view_model_set(priv->bt, child); +} + + +static void +_update_cb(void *data, Evas_Object *obj, void *ev) +{ + Layout_Model_Data *priv = data; + + const char *text = elm_object_text_get(priv->entry); + elm_layout_text_set(priv->label, "default", text); +} + +static void +_widget_init(Evas_Object *widget) +{ + evas_object_size_hint_weight_set(widget, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_size_hint_align_set(widget, EVAS_HINT_FILL, EVAS_HINT_FILL); + evas_object_show(widget); +} + +Evas_Object * +_label_init(Evas_Object *win, Evas_Object *box, const char *text) +{ + Evas_Object *widget = elm_label_add(win); + elm_label_line_wrap_set(widget, ELM_WRAP_CHAR); + elm_object_text_set(widget, text); + elm_box_pack_end(box, widget); + evas_object_size_hint_weight_set(widget, EVAS_HINT_FILL, EVAS_HINT_FILL); + evas_object_size_hint_align_set(widget, EVAS_HINT_FILL, EVAS_HINT_FILL); + evas_object_show(widget); + + return widget; +} + +EAPI_MAIN int +elm_main(int argc, char **argv) +{ + Layout_Model_Data *priv; + Evas_Object *win, *panes, *bxr, *genlist; + Eo *img_factory; + char *dirname; + + priv = alloca(sizeof(Layout_Model_Data)); + memset(priv, 0, sizeof(Layout_Model_Data)); + + //win + win = elm_win_util_standard_add("viewlist", "Viewlist"); + elm_policy_set(ELM_POLICY_QUIT, ELM_POLICY_QUIT_LAST_WINDOW_CLOSED); + elm_win_autodel_set(win, EINA_TRUE); + + panes = elm_panes_add(win); + evas_object_size_hint_weight_set(panes, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + elm_win_resize_object_add(win, panes); + + if(argv[1] != NULL) dirname = argv[1]; + else dirname = EFL_MODEL_TEST_FILENAME_PATH; + + priv->model = eo_add(EIO_MODEL_CLASS, NULL, eio_model_path_set(eo_self, dirname)); + + genlist = elm_genlist_add(win); + priv->fileview = eo_add(ELM_VIEW_LIST_CLASS, NULL, elm_view_list_genlist_set(eo_self, genlist, ELM_GENLIST_ITEM_NONE, NULL)); + elm_view_list_property_connect(priv->fileview, "filename", "elm.text"); + elm_view_list_model_set(priv->fileview, priv->model); + _widget_init(genlist); + elm_object_part_content_set(panes, "left", genlist); + elm_obj_panes_content_left_size_set(panes, 0.3); + eo_event_callback_add(priv->fileview, ELM_VIEW_LIST_EVENT_MODEL_SELECTED, _list_selected_cb, priv); + + bxr = elm_box_add(win); + _widget_init(bxr); + elm_object_part_content_set(panes, "right", bxr); + + /*Label widget */ + + _label_init(win, bxr, "FILENAME:"); + priv->label = _label_init(win, bxr, ""); + efl_ui_model_connect(priv->label, "default", "path"); //connect "default" to "filename" property + + /* Entry widget */ + priv->entry = elm_entry_add(win); + efl_ui_model_connect(priv->entry, "elm.text", "path"); //connect "elm.text" to "path" property + elm_entry_single_line_set(priv->entry, EINA_TRUE); + elm_box_pack_end(bxr, priv->entry); + evas_object_size_hint_weight_set(priv->entry, EVAS_HINT_FILL, 0); + evas_object_size_hint_align_set(priv->entry, EVAS_HINT_FILL, EVAS_HINT_FILL); + evas_object_show(priv->entry); + + /* Button widget */ + priv->bt = elm_button_add(win); + elm_box_pack_end(bxr, priv->bt); + elm_object_text_set(priv->bt, "update model"); + evas_object_smart_callback_add(priv->bt, "clicked", _update_cb, priv); + evas_object_show(priv->bt); + + /* Image widget */ + img_factory = eo_add(EFL_UI_IMAGE_FACTORY_CLASS, win); + efl_ui_model_connect(img_factory, "", "path"); //connect to "path" property + efl_ui_model_factory_connect(priv->bt, "icon", img_factory); + + priv->img = efl_ui_factory_create(img_factory, NULL, win); + elm_box_pack_end(bxr, priv->img); + evas_object_size_hint_weight_set(priv->img, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_size_hint_align_set(priv->img, EVAS_HINT_FILL, EVAS_HINT_FILL); + evas_object_show(priv->img); + + evas_object_event_callback_add(win, EVAS_CALLBACK_DEL, _cleanup_cb, priv); + //showall + evas_object_resize(win, 800, 400); + evas_object_show(panes); + evas_object_show(win); + + elm_run(); + elm_shutdown(); + ecore_shutdown(); + + return 0; +} +ELM_MAIN() diff --git a/src/lib/efl/Efl.h b/src/lib/efl/Efl.h index 3a00bb5b28..7567d0a070 100644 --- a/src/lib/efl/Efl.h +++ b/src/lib/efl/Efl.h @@ -114,6 +114,11 @@ 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" +#include "interfaces/efl_ui_factory.eo.h" +#include "interfaces/efl_ui_model_factory_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..e4a0f88ab3 100644 --- a/src/lib/efl/interfaces/efl_interfaces_main.c +++ b/src/lib/efl/interfaces/efl_interfaces_main.c @@ -53,6 +53,10 @@ 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_ui_factory.eo.c" +#include "interfaces/efl_ui_model_factory_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_factory.eo b/src/lib/efl/interfaces/efl_ui_factory.eo new file mode 100644 index 0000000000..fc3e84baff --- /dev/null +++ b/src/lib/efl/interfaces/efl_ui_factory.eo @@ -0,0 +1,19 @@ +interface Efl.Ui.Factory (Efl.Ui.Model.Connect) +{ + methods { + create { + [[Create a UI object from the necessary properties in the specified model.]] + params { + model: Efl.Model; + parent: Efl.Canvas; + } + return: Efl.Canvas; + } + release { + [[Release a UI object and disconnec from models.]] + params { + ui_view: Efl.Canvas; + } + } + } +} 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..42eb89e721 --- /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; + property: string; + } + } + } +} diff --git a/src/lib/efl/interfaces/efl_ui_model_factory_connect.eo b/src/lib/efl/interfaces/efl_ui_model_factory_connect.eo new file mode 100644 index 0000000000..1330e5ad37 --- /dev/null +++ b/src/lib/efl/interfaces/efl_ui_model_factory_connect.eo @@ -0,0 +1,11 @@ +interface Efl.Ui.Model.Factory.Connect +{ + methods { + connect { + params { + name: string; + factory: Efl.Ui.Factory; + } + } + } +} 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/Elementary.h.in b/src/lib/elementary/Elementary.h.in index 0257805a6c..44d2ee68e3 100644 --- a/src/lib/elementary/Elementary.h.in +++ b/src/lib/elementary/Elementary.h.in @@ -280,6 +280,7 @@ EAPI extern Elm_Version *elm_version; # include <efl_ui_text_interactive.eo.h> # include <efl_ui_text.eo.h> # include <efl_ui_text_editable.eo.h> +# include <efl_ui_image_factory.eo.h> #endif /* include deprecated calls last of all */ diff --git a/src/lib/elementary/efl_ui_image.c b/src/lib/elementary/efl_ui_image.c index 8bf16a894f..37c2e74519 100644 --- a/src/lib/elementary/efl_ui_image.c +++ b/src/lib/elementary/efl_ui_image.c @@ -39,6 +39,7 @@ static const Evas_Smart_Cb_Description _smart_callbacks[] = { static Eina_Bool _key_action_activate(Evas_Object *obj, const char *params); static Eina_Bool _efl_ui_image_smart_internal_file_set(Eo *obj, Efl_Ui_Image_Data *sd, const char *file, const Eina_File *f, const char *key); static void _efl_ui_image_sizing_eval(Eo *obj); +static void _efl_ui_image_model_properties_changed_cb(void *data, const Eo_Event *event); static const Elm_Action key_actions[] = { {"activate", _key_action_activate}, @@ -636,6 +637,14 @@ _efl_ui_image_efl_canvas_group_group_del(Eo *obj, Efl_Ui_Image_Data *sd) sd->async.th = NULL; } + if (sd->model) + { + eo_event_callback_del(sd->model, EFL_MODEL_EVENT_PROPERTIES_CHANGED, + _efl_ui_image_model_properties_changed_cb, obj); + eo_unref(sd->model); + sd->model = NULL; + } + _async_open_data_free(sd->async.done); _async_open_data_free(sd->async.todo); eina_stringshare_del(sd->async.file); @@ -1688,6 +1697,108 @@ _efl_ui_image_icon_get(Eo *obj EINA_UNUSED, Efl_Ui_Image_Data *sd) return sd->stdicon; } +static void +_prop_promise_error_cb(void* data EINA_UNUSED, Eina_Error err EINA_UNUSED) +{ + +} + +static void +_prop_promise_then_cb(void* data, void* v) +{ + Eo *obj = data; + Eina_Value *value = v; + char *text; + + const Eina_Value_Type *vtype = eina_value_type_get(value); + + if (vtype == EINA_VALUE_TYPE_STRING || vtype == EINA_VALUE_TYPE_STRINGSHARE) + { + eina_value_get(value, &text); + elm_image_file_set(obj, text, NULL); + } + else + { + text = eina_value_to_string(value); + elm_image_file_set(obj, text, NULL); + free(text); + } +} + +static void +_efl_ui_image_model_properties_changed_cb(void *data, const Eo_Event *event) +{ + Efl_Model_Property_Event *evt = event->info; + EFL_UI_IMAGE_DATA_GET(data, pd); + + if (!evt->changed_properties) + return; + + if (pd->model && pd->prop_con) + { + Eina_Promise *promise; + Eina_Array_Iterator it; + const char *prop; + unsigned int i; + + EINA_ARRAY_ITER_NEXT(evt->changed_properties, i, prop, it) + { + if (!strcmp(pd->prop_con, prop)) + { + promise = efl_model_property_get(pd->model, pd->prop_con); + eina_promise_then(promise, &_prop_promise_then_cb, &_prop_promise_error_cb, data); + return; + } + } + } +} + +EOLIAN static void +_efl_ui_image_efl_ui_view_model_set(Eo *obj, Efl_Ui_Image_Data *pd, Efl_Model *model) +{ + if (pd->model) + { + eo_event_callback_del(pd->model, EFL_MODEL_EVENT_PROPERTIES_CHANGED, + _efl_ui_image_model_properties_changed_cb, obj); + 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_ui_image_model_properties_changed_cb, obj); + } + + if (pd->prop_con && pd->model) + { + Eina_Promise *promise = efl_model_property_get(pd->model, pd->prop_con); + eina_promise_then(promise, &_prop_promise_then_cb, + &_prop_promise_error_cb, obj); + } +} + +EOLIAN static Efl_Model * +_efl_ui_image_efl_ui_view_model_get(Eo *obj EINA_UNUSED, Efl_Ui_Image_Data *pd) +{ + return pd->model; +} + +EOLIAN static void +_efl_ui_image_efl_ui_model_connect_connect(Eo *obj, Efl_Ui_Image_Data *pd, const char *name EINA_UNUSED, const char *property) +{ + eina_stringshare_replace(&pd->prop_con, property); + + if (pd->model && pd->prop_con) + { + Eina_Promise *promise = efl_model_property_get(pd->model, pd->prop_con); + eina_promise_then(promise, &_prop_promise_then_cb, + &_prop_promise_error_cb, obj); + } +} + EAPI void elm_image_smooth_set(Evas_Object *obj, Eina_Bool smooth) { diff --git a/src/lib/elementary/efl_ui_image.eo b/src/lib/elementary/efl_ui_image.eo index 3b9a8ef7af..c24b2abc3c 100644 --- a/src/lib/elementary/efl_ui_image.eo +++ b/src/lib/elementary/efl_ui_image.eo @@ -45,7 +45,8 @@ struct Efl.Ui.Image.Error class Efl.Ui.Image (Elm.Widget, Efl.Ui.Clickable, Efl.Ui.Draggable, Efl.File, Efl.Image, Efl.Image.Load, Efl.Player, Efl.Gfx.View, Elm.Interface.Atspi_Image, Elm.Interface.Atspi_Widget_Action, - Edje.Object, Efl.Orientation, Efl.Flipable) + Edje.Object, Efl.Orientation, Efl.Flipable, + Efl.Ui.View, Efl.Ui.Model.Connect) { event_prefix: efl_ui_image; methods { @@ -166,6 +167,9 @@ class Efl.Ui.Image (Elm.Widget, Efl.Ui.Clickable, Efl.Ui.Draggable, Efl.Canvas.Group.group_resize; Efl.Ui.Draggable.drag_target.set; Efl.Ui.Draggable.drag_target.get; + Efl.Ui.Model.Connect.connect; + Efl.Ui.View.model.set; + Efl.Ui.View.model.get; Elm.Widget.theme_apply; Elm.Widget.event; Elm.Interface.Atspi_Image.extents.get; diff --git a/src/lib/elementary/efl_ui_image_factory.c b/src/lib/elementary/efl_ui_image_factory.c new file mode 100644 index 0000000000..3efe6cfdfc --- /dev/null +++ b/src/lib/elementary/efl_ui_image_factory.c @@ -0,0 +1,59 @@ +#ifdef HAVE_CONFIG_H +# include "elementary_config.h" +#endif + +#include <Elementary.h> +#include "elm_priv.h" + +#define MY_CLASS EFL_UI_IMAGE_FACTORY_CLASS +#define MY_CLASS_NAME "Efl.Ui.Image_Factory" + +typedef struct _Efl_Ui_Image_Factory_Data +{ + Eina_Stringshare *property; +} Efl_Ui_Image_Factory_Data; + +EOLIAN static Eo * +_efl_ui_image_factory_eo_base_constructor(Eo *obj, Efl_Ui_Image_Factory_Data *pd) +{ + obj = eo_constructor(eo_super(obj, MY_CLASS)); + + pd->property = NULL; + + return obj; +} + +EOLIAN static void +_efl_ui_image_factory_eo_base_destructor(Eo *obj EINA_UNUSED, Efl_Ui_Image_Factory_Data *pd) +{ + eina_stringshare_del(pd->property); + pd->property = NULL; + + eo_destructor(eo_super(obj, MY_CLASS)); +} + +EOLIAN static Efl_Canvas * +_efl_ui_image_factory_efl_ui_factory_create(Eo *obj EINA_UNUSED, Efl_Ui_Image_Factory_Data *pd, Efl_Model *model, Efl_Canvas *parent) +{ + EINA_SAFETY_ON_NULL_RETURN_VAL(pd->property, NULL); + EINA_SAFETY_ON_NULL_RETURN_VAL(parent, NULL); + Efl_Canvas *ui_view = eo_add(EFL_UI_IMAGE_CLASS, parent); + efl_ui_view_model_set(ui_view, model); + efl_ui_model_connect(ui_view, NULL, pd->property); + + return ui_view; +} + +EOLIAN static void +_efl_ui_image_factory_efl_ui_factory_release(Eo *obj EINA_UNUSED, Efl_Ui_Image_Factory_Data *pd EINA_UNUSED, Efl_Canvas *ui_view) +{ + eo_parent_set(ui_view, NULL); +} + +EOLIAN static void +_efl_ui_image_factory_efl_ui_model_connect_connect(Eo *obj EINA_UNUSED, Efl_Ui_Image_Factory_Data *pd, const char *name EINA_UNUSED, const char *property) +{ + eina_stringshare_replace(&pd->property, property); +} + +#include "efl_ui_image_factory.eo.c" diff --git a/src/lib/elementary/efl_ui_image_factory.eo b/src/lib/elementary/efl_ui_image_factory.eo new file mode 100644 index 0000000000..8159f416e7 --- /dev/null +++ b/src/lib/elementary/efl_ui_image_factory.eo @@ -0,0 +1,10 @@ +class Efl.Ui.Image.Factory (Eo.Base, Efl.Ui.Factory) +{ + implements { + Eo.Base.constructor; + Eo.Base.destructor; + Efl.Ui.Factory.create; + Efl.Ui.Factory.release; + Efl.Ui.Model.Connect.connect; + } +} diff --git a/src/lib/elementary/efl_ui_widget_image.h b/src/lib/elementary/efl_ui_widget_image.h index 64f7b9715c..778412ee85 100644 --- a/src/lib/elementary/efl_ui_widget_image.h +++ b/src/lib/elementary/efl_ui_widget_image.h @@ -78,6 +78,8 @@ struct _Efl_Ui_Image_Data const char *stdicon; + Efl_Model *model; + Eina_Stringshare *prop_con; struct { int requested_size; diff --git a/src/lib/elementary/elm_layout.c b/src/lib/elementary/elm_layout.c index ebc21cd5aa..47d1855d1b 100644 --- a/src/lib/elementary/elm_layout.c +++ b/src/lib/elementary/elm_layout.c @@ -22,6 +22,7 @@ #define MY_CLASS_NAME_LEGACY "elm_layout" Eo *_elm_layout_pack_proxy_get(Elm_Layout *obj, Edje_Part_Type type, 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"; @@ -110,6 +111,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, @@ -821,6 +829,17 @@ _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_hash_free(sd->factories); + sd->factories = NULL; + eina_stringshare_del(sd->klass); eina_stringshare_del(sd->group); @@ -1335,6 +1354,20 @@ _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_Stringshare *prop = eina_hash_find(sd->prop_connect, sub_d->part); + if (prop) + { + Eina_Value v; + eina_value_setup(&v, EINA_VALUE_TYPE_STRING); + eina_value_set(&v, text); + efl_model_property_set(sd->model, prop, &v, NULL); + eina_value_flush(&v); + } + } + + sd->view_updated = EINA_FALSE; return EINA_TRUE; } @@ -1912,6 +1945,214 @@ _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 *ss_prop; + Eina_Hash_Tuple *tuple; + Eina_Array_Iterator it; + Eina_Iterator *it_p; + Eina_Promise *promise; + const char *prop; + unsigned int i; + + if (!evt->changed_properties) + return; + + 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)) + { + if (tuple->data == ss_prop) + { + sub_pp = ELM_NEW(Elm_Layout_Sub_Property_Promise); + sub_pp->pd = pd; + sub_pp->name = tuple->key; + 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); + } + } + eina_iterator_free(it_p); + eina_stringshare_del(ss_prop); + } +} + +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 = data; + Eina_Stringshare *name = key; + + 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; +} + +static Eina_Bool +_elm_layout_view_factory_update_fn(const Eina_Hash *hash EINA_UNUSED, const void *key, void *data, void *fdata) +{ + Elm_Layout_Smart_Data *pd = fdata; + Eina_Stringshare *name = key; + Efl_Ui_Factory *factory = data; + Efl_Canvas *content = elm_layout_content_get(pd->obj, name); + + if (content && eo_isa(content, EFL_UI_VIEW_INTERFACE)) + { + efl_ui_view_model_set(content, pd->model); + } + else + { + efl_ui_factory_release(factory, content); + content = efl_ui_factory_create(factory, pd->model, pd->obj); + elm_layout_content_set(pd->obj, name, content); + } + + 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); + if (pd->factories) eina_hash_foreach(pd->factories, _elm_layout_view_factory_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_name, ss_prop)); + + 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); + } +} + + +EOLIAN static void +_elm_layout_efl_ui_model_factory_connect_connect(Eo *obj EINA_UNUSED, Elm_Layout_Smart_Data *pd, + const char *name, Efl_Ui_Factory *factory) +{ + EINA_SAFETY_ON_NULL_RETURN(name); + Eina_Stringshare *ss_name; + Efl_Ui_Factory *old_factory; + Evas_Object *new_ev, *old_ev; + + if (!_elm_layout_part_aliasing_eval(obj, pd, &name, EINA_TRUE)) + return; + + ss_name = eina_stringshare_add(name); + + if (!pd->factories) + pd->factories = eina_hash_stringshared_new(EINA_FREE_CB(eo_unref)); + + new_ev = efl_ui_factory_create(factory, pd->model, obj); + EINA_SAFETY_ON_NULL_RETURN(new_ev); + + old_factory = eina_hash_set(pd->factories, ss_name, eo_ref(factory)); + if (old_factory) + { + old_ev = elm_layout_content_get(obj, name); + if (old_ev) + efl_ui_factory_release(old_factory, old_ev); + eo_unref(old_factory); + } + + elm_layout_content_set(obj, name, new_ev); +} + 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..a33a0a631b 100644 --- a/src/lib/elementary/elm_layout.eo +++ b/src/lib/elementary/elm_layout.eo @@ -17,7 +17,8 @@ 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, Efl.Ui.Model.Factory.Connect) { legacy_prefix: elm_layout; eo_prefix: elm_obj_layout; @@ -256,6 +257,10 @@ 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; + Efl.Ui.Model.Factory.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..24e374e5cf 100644 --- a/src/lib/elementary/elm_widget_layout.h +++ b/src/lib/elementary/elm_widget_layout.h @@ -53,6 +53,9 @@ 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 hash of properties connected to layout parts. */ + Eina_Hash *factories; /**< The hash with parts connected to factories. */ + 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 +66,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; /** |