cedric pushed a commit to branch master.

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

commit aa0e89a5901b473502d23f6cff5e497c12308bbc
Author: Cedric BAIL <[email protected]>
Date:   Fri Jan 18 17:58:39 2019 -0800

    elementary: add Efl.Ui.Widget_Factory.
    
    The Widget_Factory is in charge of creating any object that inherit from 
Efl.Ui.Widget Class.
    If the style property is connected to a model property, it will fetch it 
and build the widget
    with that style. This factory is to be used with every View.
    
    Reviewed-by: SangHyeon Jade Lee <[email protected]>
    Differential Revision: https://phab.enlightenment.org/D7704
---
 src/Makefile_Elementary.am                  |   2 +
 src/lib/elementary/Efl_Ui.h                 |   1 +
 src/lib/elementary/Elementary.h             |   1 +
 src/lib/elementary/efl_ui_widget_factory.c  | 131 ++++++++++++++++++++++++++++
 src/lib/elementary/efl_ui_widget_factory.eo |  28 ++++++
 src/lib/elementary/meson.build              |   4 +-
 6 files changed, 166 insertions(+), 1 deletion(-)

diff --git a/src/Makefile_Elementary.am b/src/Makefile_Elementary.am
index 9e9ebc8ea2..f8fca13520 100644
--- a/src/Makefile_Elementary.am
+++ b/src/Makefile_Elementary.am
@@ -133,6 +133,7 @@ elm_public_eolian_files = \
        lib/elementary/efl_ui_widget_focus_manager.eo \
        lib/elementary/efl_ui_text_part.eo \
        lib/elementary/efl_ui_caching_factory.eo \
+       lib/elementary/efl_ui_widget_factory.eo \
        $(NULL)
 
 # More public files -- FIXME
@@ -884,6 +885,7 @@ lib_elementary_libelementary_la_SOURCES = \
        lib/elementary/efl_ui_tab_page.c \
        lib/elementary/efl_ui_widget_focus_manager.c \
        lib/elementary/efl_ui_caching_factory.c \
+       lib/elementary/efl_ui_widget_factory.c \
        $(NULL)
 
 
diff --git a/src/lib/elementary/Efl_Ui.h b/src/lib/elementary/Efl_Ui.h
index c1387290e2..34db59a475 100644
--- a/src/lib/elementary/Efl_Ui.h
+++ b/src/lib/elementary/Efl_Ui.h
@@ -210,6 +210,7 @@ EAPI void efl_ui_focus_relation_free(Efl_Ui_Focus_Relations 
*rel);
 # include <efl_ui_button_eo.h>
 
 # include "efl_ui_caching_factory.eo.h"
+# include "efl_ui_widget_factory.eo.h"
 
 /* FIXME: Multibuttonentry must not use elm_widget_item */
 
diff --git a/src/lib/elementary/Elementary.h b/src/lib/elementary/Elementary.h
index 3854a3e2a9..5bb8374e3a 100644
--- a/src/lib/elementary/Elementary.h
+++ b/src/lib/elementary/Elementary.h
@@ -346,6 +346,7 @@ EAPI void efl_ui_focus_relation_free(Efl_Ui_Focus_Relations 
*rel);
 # include <efl_ui_list_view_model.eo.h>
 # include <efl_ui_list_view.eo.h>
 # include <efl_ui_list_view_pan.eo.h>
+# include <efl_ui_widget_factory.eo.h>
 # include <efl_ui_caching_factory.eo.h>
 # include <efl_ui_pan.eo.h>
 # include <efl_ui_scroll_manager.eo.h>
diff --git a/src/lib/elementary/efl_ui_widget_factory.c 
b/src/lib/elementary/efl_ui_widget_factory.c
new file mode 100644
index 0000000000..b83a0a79aa
--- /dev/null
+++ b/src/lib/elementary/efl_ui_widget_factory.c
@@ -0,0 +1,131 @@
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#define EFL_UI_WIDGET_PROTECTED
+
+#include <Elementary.h>
+#include "elm_priv.h"
+
+typedef struct _Efl_Ui_Widget_Factory_Data Efl_Ui_Widget_Factory_Data;
+typedef struct _Efl_Ui_Widget_Factory_Request Efl_Ui_Widget_Factory_Request;
+
+struct _Efl_Ui_Widget_Factory_Data
+{
+   const Efl_Class *klass;
+
+   Eina_Stringshare *style;
+};
+
+struct _Efl_Ui_Widget_Factory_Request
+{
+   Efl_Ui_Widget_Factory_Data *pd;
+   Eo *parent;
+   Efl_Model *model;
+};
+
+static void
+_efl_ui_widget_factory_item_class_set(Eo *obj, Efl_Ui_Widget_Factory_Data *pd,
+                                      const Efl_Class *klass)
+{
+   if (!efl_isa(klass, EFL_UI_VIEW_INTERFACE) ||
+       !efl_isa(klass, EFL_UI_WIDGET_CLASS))
+     {
+        ERR("Provided class '%s' for factory '%s' doesn't implement '%s' and 
'%s' interfaces.",
+            efl_class_name_get(klass),
+            efl_class_name_get(obj),
+            efl_class_name_get(EFL_UI_WIDGET_CLASS),
+            efl_class_name_get(EFL_UI_VIEW_INTERFACE));
+        return ;
+     }
+   pd->klass = klass;
+}
+
+static const Efl_Class *
+_efl_ui_widget_factory_item_class_get(const Eo *obj EINA_UNUSED,
+                                      Efl_Ui_Widget_Factory_Data *pd)
+{
+   return pd->klass;
+}
+
+static Eina_Value
+_efl_ui_widget_factory_create_then(Eo *obj EINA_UNUSED, void *data, const 
Eina_Value v)
+{
+   Efl_Ui_Widget_Factory_Request *r = data;
+   Efl_Ui_Widget *w;
+   const char *string = NULL;
+
+   if (!eina_value_string_get(&v, &string))
+     return eina_value_error_init(EFL_MODEL_ERROR_NOT_SUPPORTED);
+
+   w = efl_add(r->pd->klass, r->parent,
+               efl_ui_widget_style_set(efl_added, string),
+               efl_ui_view_model_set(efl_added, r->model));
+
+   return eina_value_object_init(w);
+}
+
+static void
+_efl_ui_widget_factory_create_cleanup(Eo *o EINA_UNUSED, void *data, const 
Eina_Future *dead_future EINA_UNUSED)
+{
+   Efl_Ui_Widget_Factory_Request *r = data;
+
+   efl_unref(r->model);
+   efl_unref(r->parent);
+   free(r);
+}
+
+static Eina_Future *
+_efl_ui_widget_factory_efl_ui_factory_create(Eo *obj, 
Efl_Ui_Widget_Factory_Data *pd,
+                                             Efl_Model *model, Efl_Gfx_Entity 
*parent)
+{
+   Efl_Ui_Widget_Factory_Request *r;
+
+   if (!pd->klass)
+     return efl_loop_future_rejected(obj, EFL_MODEL_ERROR_INCORRECT_VALUE);
+
+   if (!pd->style)
+     {
+        Efl_Ui_Widget *w;
+
+        w = efl_add(pd->klass, parent,
+                    efl_ui_view_model_set(efl_added, model));
+        return efl_loop_future_resolved(obj, eina_value_object_init(w));
+     }
+
+   r = calloc(1, sizeof (Efl_Ui_Widget_Factory_Request));
+   if (!r) return efl_loop_future_rejected(obj, ENOMEM);
+
+   r->pd = pd;
+   r->parent = efl_ref(parent);
+   r->model = efl_ref(model);
+
+   return efl_future_then(obj, efl_model_property_ready_get(obj, pd->style),
+                          .success = _efl_ui_widget_factory_create_then,
+                          .data = r,
+                          .free = _efl_ui_widget_factory_create_cleanup);
+}
+
+static void
+_efl_ui_widget_factory_efl_ui_factory_release(Eo *obj EINA_UNUSED,
+                                              Efl_Ui_Widget_Factory_Data *pd 
EINA_UNUSED,
+                                              Efl_Gfx_Entity *ui_view)
+{
+   // We do not cache or track this item, just get rid of them asap
+   efl_del(ui_view);
+}
+
+static void
+_efl_ui_widget_factory_efl_ui_model_connect_connect(Eo *obj, 
Efl_Ui_Widget_Factory_Data *pd,
+                                                    const char *name, const 
char *property)
+{
+   if (!strcmp(name, "style"))
+     {
+        eina_stringshare_replace(&pd->style, property);
+        return ;
+     }
+
+   efl_ui_model_connect(efl_super(obj, EFL_UI_WIDGET_FACTORY_CLASS), name, 
property);
+}
+
+#include "efl_ui_widget_factory.eo.c"
diff --git a/src/lib/elementary/efl_ui_widget_factory.eo 
b/src/lib/elementary/efl_ui_widget_factory.eo
new file mode 100644
index 0000000000..3652010735
--- /dev/null
+++ b/src/lib/elementary/efl_ui_widget_factory.eo
@@ -0,0 +1,28 @@
+class Efl.Ui.Widget_Factory extends Efl.Loop_Consumer implements Efl.Ui.Factory
+{
+   [[Efl Ui Factory that provides @Efl.Ui.Widget.
+
+     This factory is designed to build @Efl.Ui.Widget and optionally set their
+     @Efl.Ui.Widget.style if it was connected with 
@Efl.Ui.Model.Connect.connect "$style".
+
+   ]]
+   methods {
+      @property item_class {
+         [[Define the class of the item returned by this factory.]]
+         get {}
+         set {}
+         values {
+            klass: const(Efl.Class); [[The class identifier to create item 
from.]]
+         }
+      }
+   }
+
+   implements {
+      Efl.Ui.Factory.create;
+      Efl.Ui.Factory.release;
+      Efl.Ui.Model.Connect.connect;
+   }
+   constructors {
+      .item_class;
+   }
+}
\ No newline at end of file
diff --git a/src/lib/elementary/meson.build b/src/lib/elementary/meson.build
index 0c7c9cb166..fa5b42b4a1 100644
--- a/src/lib/elementary/meson.build
+++ b/src/lib/elementary/meson.build
@@ -278,6 +278,7 @@ pub_eo_files = [
   'elm_widget_item.eo',
   'efl_ui_text_part.eo',
   'efl_ui_caching_factory.eo',
+  'efl_ui_widget_factory.eo',
 ]
 
 foreach eo_file : pub_eo_files
@@ -903,7 +904,8 @@ elementary_src = [
   'efl_ui_tab_bar.c',
   'efl_ui_tab_page.c',
   'efl_ui_widget_focus_manager.c',
-  'efl_ui_caching_factory.c'
+  'efl_ui_caching_factory.c',
+  'efl_ui_widget_factory.c'
 ]
 
 elementary_deps = [emile, eo, efl, edje, ethumb, ethumb_client, emotion, 
ecore_imf, ecore_con, eldbus, efreet, efreet_mime, efreet_trash, eio, atspi, 
dl, intl]

-- 


Reply via email to