From 3b10089ff338e5c5874e630f422e8dc6fb5c5dc2 Mon Sep 17 00:00:00 2001 From: Cedric BAIL Date: Fri, 28 Dec 2018 15:41:44 -0800 Subject: [PATCH] elementary: add internal Efl_Ui_Model_Homogeneous. 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 | 2 + src/lib/elementary/efl_ui_model_homogeneous.c | 142 ++++++++++++++++++ .../elementary/efl_ui_model_homogeneous.eo | 20 +++ src/lib/elementary/elm_priv.h | 3 +- src/lib/elementary/meson.build | 7 +- 5 files changed, 170 insertions(+), 4 deletions(-) create mode 100644 src/lib/elementary/efl_ui_model_homogeneous.c create mode 100644 src/lib/elementary/efl_ui_model_homogeneous.eo diff --git a/src/Makefile_Elementary.am b/src/Makefile_Elementary.am index 9df6326dcd..d12698d814 100644 --- a/src/Makefile_Elementary.am +++ b/src/Makefile_Elementary.am @@ -177,6 +177,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) # Legacy classes - not part of public EO API @@ -888,6 +889,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 index 0000000000..174350e84f --- /dev/null +++ b/src/lib/elementary/efl_ui_model_homogeneous.c @@ -0,0 +1,142 @@ +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#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 index 0000000000..c0c001a8b3 --- /dev/null +++ b/src/lib/elementary/efl_ui_model_homogeneous.eo @@ -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; } + } +} diff --git a/src/lib/elementary/elm_priv.h b/src/lib/elementary/elm_priv.h index 9410fd4213..aa97ee3c51 100644 --- a/src/lib/elementary/elm_priv.h +++ b/src/lib/elementary/elm_priv.h @@ -67,9 +67,10 @@ # 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; diff --git a/src/lib/elementary/meson.build b/src/lib/elementary/meson.build index 90cfa83ead..1b2b539731 100644 --- a/src/lib/elementary/meson.build +++ b/src/lib/elementary/meson.build @@ -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, @@ -340,9 +338,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, @@ -907,7 +907,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]