elementary: add internal Efl_Ui_Model_Homogeneous.
authorCedric BAIL <cedric.bail@free.fr>
Fri, 28 Dec 2018 23:41:44 +0000 (15:41 -0800)
committerTaehyub Kim <taehyub.kim@samsung.com>
Thu, 31 Jan 2019 03:45:42 +0000 (12:45 +0900)
This model enable View that require to compute the size of their item
to rely on its logic to have all items of the same size. It is the
equivalent of the Homogeneous behavior of Genlist, except that now this
behavior can be customized outside of the View logic itself.

Differential Revision: https://phab.enlightenment.org/D7659

src/Makefile_Elementary.am
src/lib/elementary/efl_ui_model_homogeneous.c [new file with mode: 0644]
src/lib/elementary/efl_ui_model_homogeneous.eo [new file with mode: 0644]
src/lib/elementary/elm_priv.h
src/lib/elementary/meson.build

index ef99e47..0884359 100644 (file)
@@ -179,6 +179,7 @@ elm_private_eolian_files = \
        lib/elementary/efl_ui_list_view_relayout.eo \
        lib/elementary/efl_ui_list_view_precise_layouter.eo \
        lib/elementary/efl_ui_model_size.eo \
+       lib/elementary/efl_ui_model_homogeneous.eo \
        $(NULL)
 
 ## TIZEN_ONLY(20180509): support elementary optional build
@@ -914,6 +915,7 @@ lib_elementary_libelementary_la_SOURCES = \
        lib/elementary/efl_ui_caching_factory.c \
        lib/elementary/efl_ui_widget_factory.c \
        lib/elementary/efl_ui_model_size.c \
+       lib/elementary/efl_ui_model_homogeneous.c \
        $(NULL)
 
 
diff --git a/src/lib/elementary/efl_ui_model_homogeneous.c b/src/lib/elementary/efl_ui_model_homogeneous.c
new file mode 100644 (file)
index 0000000..174350e
--- /dev/null
@@ -0,0 +1,142 @@
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <Elementary.h>
+#include "elm_priv.h"
+
+// For now only vertical logic is implemented. Horizontal list and grid are not supported.
+
+typedef struct _Efl_Ui_Model_Homogeneous_Data Efl_Ui_Model_Homogeneous_Data;
+struct _Efl_Ui_Model_Homogeneous_Data
+{
+   Efl_Ui_Model_Homogeneous_Data *parent;
+
+   struct {
+      unsigned int width;
+      unsigned int height;
+
+      struct {
+         Eina_Bool width;
+         Eina_Bool height;
+      } defined;
+   } item;
+};
+
+static Eina_Future *
+_efl_ui_model_homogeneous_property_set(Eo *obj, Eina_Value *value,
+                                       Eina_Bool *defined, unsigned int *r)
+{
+   Eina_Future *f;
+
+   if (*defined)
+     return efl_loop_future_rejected(obj, EFL_MODEL_ERROR_READ_ONLY);
+   if (!eina_value_uint_convert(value, r))
+     return efl_loop_future_rejected(obj, EFL_MODEL_ERROR_INCORRECT_VALUE);
+   *defined = EINA_TRUE;
+   f = efl_loop_future_resolved(obj, *value);
+   eina_value_free(value);
+   return f;
+}
+
+static Eina_Future *
+_efl_ui_model_homogeneous_efl_model_property_set(Eo *obj,
+                                                 Efl_Ui_Model_Homogeneous_Data *pd,
+                                                 const char *property, Eina_Value *value)
+{
+   if (pd->parent)
+     {
+        if (!strcmp(property, _efl_model_property_selfw))
+          return _efl_ui_model_homogeneous_property_set(obj, value,
+                                                        &pd->parent->item.defined.width,
+                                                        &pd->parent->item.width);
+        if (!strcmp(property, _efl_model_property_selfh))
+          return _efl_ui_model_homogeneous_property_set(obj, value,
+                                                        &pd->parent->item.defined.height,
+                                                        &pd->parent->item.height);
+        if (!strcmp(property, _efl_model_property_totalw) ||
+            !strcmp(property, _efl_model_property_totalh))
+          return efl_loop_future_rejected(obj, EFL_MODEL_ERROR_READ_ONLY);
+     }
+   if (!strcmp(property, _efl_model_property_itemw))
+     {
+        return _efl_ui_model_homogeneous_property_set(obj, value,
+                                                      &pd->item.defined.width,
+                                                      &pd->item.width);
+     }
+   if (!strcmp(property, _efl_model_property_itemh))
+     {
+        return _efl_ui_model_homogeneous_property_set(obj, value,
+                                                      &pd->item.defined.height,
+                                                      &pd->item.height);
+     }
+
+   return efl_model_property_set(efl_super(obj, EFL_UI_MODEL_HOMOGENEOUS_CLASS),
+                                 property, value);
+}
+
+static Eina_Value *
+_efl_ui_model_homogeneous_efl_model_property_get(const Eo *obj,
+                                                 Efl_Ui_Model_Homogeneous_Data *pd,
+                                                 const char *property)
+{
+   if (pd->parent)
+     {
+        if (!strcmp(property, _efl_model_property_selfw))
+          {
+             if (pd->parent->item.defined.width)
+               return eina_value_uint_new(pd->parent->item.width);
+             goto not_ready;
+          }
+        if (!strcmp(property, _efl_model_property_selfh))
+          {
+             if (pd->parent->item.defined.height)
+               return eina_value_uint_new(pd->parent->item.height);
+             goto not_ready;
+          }
+     }
+   if (!strcmp(property, _efl_model_property_itemw))
+     {
+        if (pd->item.defined.width)
+          return eina_value_uint_new(pd->item.width);
+        goto not_ready;
+     }
+   if (!strcmp(property, _efl_model_property_itemh))
+     {
+        if (pd->item.defined.height)
+          return eina_value_uint_new(pd->item.height);
+        goto not_ready;
+     }
+   if (!strcmp(property, _efl_model_property_totalh))
+     {
+        if (pd->item.defined.height)
+          return eina_value_uint_new(pd->item.height *
+                                     efl_model_children_count_get(obj));
+        goto not_ready;
+     }
+   if (!strcmp(property, _efl_model_property_totalw))
+     {
+        if (pd->item.defined.width)
+          // We only handle vertical list at this point, so total width is the width of one item.
+          return eina_value_uint_new(pd->item.width);
+        goto not_ready;
+     }
+
+   return efl_model_property_get(efl_super(obj, EFL_UI_MODEL_HOMOGENEOUS_CLASS), property);
+
+ not_ready:
+   return eina_value_error_new(EAGAIN);
+}
+
+static Efl_Object *
+_efl_ui_model_homogeneous_efl_object_constructor(Eo *obj, Efl_Ui_Model_Homogeneous_Data *pd)
+{
+   Eo *parent = efl_parent_get(obj);
+
+   if (parent && efl_isa(parent, EFL_UI_MODEL_HOMOGENEOUS_CLASS))
+     pd->parent = efl_data_scope_get(efl_parent_get(obj), EFL_UI_MODEL_HOMOGENEOUS_CLASS);
+
+   return efl_constructor(efl_super(obj, EFL_UI_MODEL_HOMOGENEOUS_CLASS));
+}
+
+#include "efl_ui_model_homogeneous.eo.c"
diff --git a/src/lib/elementary/efl_ui_model_homogeneous.eo b/src/lib/elementary/efl_ui_model_homogeneous.eo
new file mode 100644 (file)
index 0000000..c0c001a
--- /dev/null
@@ -0,0 +1,20 @@
+class Efl.Ui.Model_Homogeneous extends Efl.Ui.Model_Size
+{
+   [[Class to be used to store object item size for List/Grid View.
+
+   This model provides the properties "$item.width" and "$item.height" which have the
+   same value for all siblings of this object. The first sibling that defines "$self.width"
+   and "$self.height" set them for all other siblings and also set "$item.width" and
+   "$item.height" for the parent (See @Efl.Ui.Model_Size).
+
+   Subsequent attempts to set "$self.width" or "$self.height" will fail with a
+   Read Only error code.
+
+   The properties "$total.width" and "$total.height" are computed from the number of node,
+   the "$self.width" and "$self.height" assuming that the View is a vertical list.]]
+
+   implements {
+      Efl.Object.constructor;
+      Efl.Model.property { set; get; }
+   }
+}
index 89561cb..2d7f4a2 100644 (file)
 # include "efl_ui_widget_focus_manager.eo.h"
 # include "efl_ui_focus_parent_provider_standard.eo.h"
 # include "elm_widget_item_static_focus.eo.h"
-#include "efl_ui_selection_manager.eo.h"
+# include "efl_ui_selection_manager.eo.h"
 # include "efl_datetime_manager.eo.h"
 # include "efl_ui_model_size.eo.h"
+# include "efl_ui_model_homogeneous.eo.h"
 
 extern const char *_efl_model_property_itemw;
 extern const char *_efl_model_property_itemh;
index 2ec2428..b7d8857 100644 (file)
@@ -109,8 +109,6 @@ pub_legacy_eo_files = [
 
 pub_eo_file_target = []
 
-priv_eo_file_target = []
-
 foreach eo_file : pub_legacy_eo_files
   pub_eo_file_target += custom_target('eolian_gen_' + eo_file,
     input : eo_file,
@@ -341,9 +339,11 @@ priv_eo_files = [
   'efl_ui_list_view_precise_layouter.eo',
   'efl_ui_list_view_relayout.eo',
   'efl_ui_model_size.eo',
+  'efl_ui_model_homogeneous.eo',
 ]
 
 priv_eo_file_target = []
+
 foreach eo_file : priv_eo_files
   priv_eo_file_target += custom_target('eolian_gen_' + eo_file,
     input : eo_file,
@@ -912,7 +912,8 @@ elementary_src = [
   'efl_ui_widget_focus_manager.c',
   'efl_ui_caching_factory.c',
   'efl_ui_widget_factory.c',
-  'efl_ui_model_size.c'
+  'efl_ui_model_size.c',
+  'efl_ui_model_homogeneous.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]