forked from enlightenment/efl
Compare commits
7 Commits
master
...
devs/felip
Author | SHA1 | Date |
---|---|---|
|
62e0d181a9 | |
|
83e498d1ab | |
|
a856b2d8ce | |
|
f04ff73dea | |
|
7cff7432cc | |
|
132f8f1f37 | |
|
ae26833fbd |
|
@ -27,6 +27,9 @@ efl_eolian_files = \
|
|||
lib/efl/interfaces/efl_gfx_filter.eo \
|
||||
lib/efl/interfaces/efl_gfx_size_hint.eo \
|
||||
lib/efl/interfaces/efl_model.eo \
|
||||
lib/efl/interfaces/efl_model_item.eo \
|
||||
lib/efl/interfaces/efl_model_container.eo \
|
||||
lib/efl/interfaces/efl_model_container_item.eo \
|
||||
lib/efl/interfaces/efl_animator.eo \
|
||||
lib/efl/interfaces/efl_orientation.eo \
|
||||
lib/efl/interfaces/efl_flipable.eo \
|
||||
|
@ -42,6 +45,9 @@ 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_event.eo \
|
||||
lib/efl/interfaces/efl_input_interface.eo \
|
||||
lib/efl/interfaces/efl_input_state.eo \
|
||||
|
@ -73,6 +79,7 @@ EXTRA_DIST2 += \
|
|||
lib/efl/Makefile.am \
|
||||
lib/efl/Makefile.in \
|
||||
lib/efl/interfaces/efl_common_internal.h \
|
||||
lib/efl/interfaces/efl_model_private.h \
|
||||
$(efl_eolian_files) \
|
||||
$(efl_eolian_type_files)
|
||||
|
||||
|
@ -84,6 +91,9 @@ lib_LTLIBRARIES += lib/efl/libefl.la
|
|||
lib_efl_libefl_la_SOURCES = \
|
||||
lib/efl/interfaces/efl_interfaces_main.c \
|
||||
lib/efl/interfaces/efl_model_common.c \
|
||||
lib/efl/interfaces/efl_model_item.c \
|
||||
lib/efl/interfaces/efl_model_container.c \
|
||||
lib/efl/interfaces/efl_model_container_item.c \
|
||||
lib/efl/interfaces/efl_gfx_shape.c \
|
||||
lib/efl/interfaces/efl_vpath_file.c \
|
||||
lib/efl/interfaces/efl_vpath_manager.c \
|
||||
|
@ -155,3 +165,26 @@ bin_efl_efl_debug_CPPFLAGS = -I$(top_builddir)/src/bin/efl @EINA_CFLAGS@ @ECORE_
|
|||
bin_efl_efl_debug_LDADD = @EFL_LIBS@ @USE_EINA_INTERNAL_LIBS@ @USE_ECORE_INTERNAL_LIBS@ @USE_ECORE_CON_INTERNAL_LIBS@
|
||||
bin_efl_efl_debug_DEPENDENCIES = @USE_EINA_INTERNAL_LIBS@ @USE_ECORE_INTERNAL_LIBS@ @USE_ECORE_CON_INTERNAL_LIBS@
|
||||
|
||||
|
||||
if EFL_ENABLE_TESTS
|
||||
|
||||
check_PROGRAMS += tests/efl/efl_suite
|
||||
TESTS += tests/efl/efl_suite
|
||||
|
||||
tests_efl_efl_suite_SOURCES = \
|
||||
tests/efl/efl_suite.c \
|
||||
tests/efl/efl_test_model_container.c \
|
||||
tests/efl/efl_suite.h
|
||||
|
||||
tests_efl_efl_suite_CPPFLAGS = -I$(top_builddir)/src/lib/efl \
|
||||
-DTESTS_SRC_DIR=\"$(top_srcdir)/src/tests/efl\" \
|
||||
-DTESTS_BUILD_DIR=\"$(top_builddir)/src/tests/efl\" \
|
||||
@CHECK_CFLAGS@ \
|
||||
@ECORE_CFLAGS@ \
|
||||
@EFL_CFLAGS@
|
||||
|
||||
tests_efl_efl_suite_LDADD = @CHECK_LIBS@ @USE_EFL_LIBS@ @USE_ECORE_LIBS@
|
||||
tests_efl_efl_suite_DEPENDENCIES = @USE_EFL_INTERNAL_LIBS@
|
||||
|
||||
endif
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
||||
|
|
|
@ -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 \
|
||||
|
@ -313,6 +314,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 \
|
||||
|
|
|
@ -0,0 +1,162 @@
|
|||
// 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>
|
||||
#include <Eio.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;
|
||||
};
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
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, *bt;
|
||||
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 */
|
||||
bt = elm_button_add(win);
|
||||
elm_box_pack_end(bxr, bt);
|
||||
elm_object_text_set(bt, "update model");
|
||||
evas_object_smart_callback_add(bt, "clicked", _update_cb, priv);
|
||||
evas_object_show(bt);
|
||||
|
||||
/* Image widget */
|
||||
img_factory = eo_add(EFL_UI_IMAGE_FACTORY_CLASS, win);
|
||||
efl_ui_model_connect(img_factory, "", "path"); //connect to "path" property
|
||||
|
||||
priv->img = efl_ui_factory_create(img_factory, NULL);
|
||||
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()
|
|
@ -114,6 +114,10 @@ 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"
|
||||
|
||||
/* Packing & containers */
|
||||
#include "interfaces/efl_container.eo.h"
|
||||
#include "interfaces/efl_pack.eo.h"
|
||||
|
|
|
@ -10,6 +10,7 @@ EAPI extern Eina_Error EFL_MODEL_ERROR_READ_ONLY;
|
|||
EAPI extern Eina_Error EFL_MODEL_ERROR_INIT_FAILED;
|
||||
EAPI extern Eina_Error EFL_MODEL_ERROR_INCORRECT_VALUE;
|
||||
EAPI extern Eina_Error EFL_MODEL_ERROR_PERMISSION_DENIED;
|
||||
EAPI extern Eina_Error EFL_MODEL_ERROR_INVALID_OBJECT;
|
||||
|
||||
/**
|
||||
* @struct _Efl_Model_Children_Event
|
||||
|
@ -38,6 +39,9 @@ struct _Efl_Model_Children_Event
|
|||
typedef struct _Efl_Model_Children_Event Efl_Model_Children_Event;
|
||||
|
||||
#include "interfaces/efl_model.eo.h"
|
||||
#include "interfaces/efl_model_container.eo.h"
|
||||
#include "interfaces/efl_model_container_item.eo.h"
|
||||
#include "interfaces/efl_model_item.eo.h"
|
||||
|
||||
EAPI int efl_model_init(void);
|
||||
|
||||
|
|
|
@ -27,6 +27,9 @@ interfaces/efl_gfx_gradient_radial.eo \
|
|||
interfaces/efl_gfx_filter.eo \
|
||||
interfaces/efl_gfx_size_hint.eo \
|
||||
interfaces/efl_model.eo \
|
||||
interfaces/efl_model_item.eo \
|
||||
interfaces/efl_model_container.eo \
|
||||
interfaces/efl_model_container_item.eo \
|
||||
interfaces/efl_animator.eo \
|
||||
interfaces/efl_orientation.eo \
|
||||
interfaces/efl_flipable.eo \
|
||||
|
@ -64,6 +67,9 @@ lib_LTLIBRARIES = libefl.la
|
|||
libefl_la_SOURCES = \
|
||||
interfaces/efl_interfaces_main.c \
|
||||
interfaces/efl_model_common.c \
|
||||
interfaces/efl_model_item.c \
|
||||
interfaces/efl_model_container.c \
|
||||
interfaces/efl_model_container_item.c \
|
||||
interfaces/efl_gfx_shape.c \
|
||||
interfaces/efl_vpath_file.c \
|
||||
interfaces/efl_vpath_manager.c \
|
||||
|
|
|
@ -53,6 +53,9 @@ 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_event.eo.c"
|
||||
#include "interfaces/efl_input_state.eo.c"
|
||||
|
|
|
@ -12,6 +12,7 @@ EAPI Eina_Error EFL_MODEL_ERROR_READ_ONLY = 0;
|
|||
EAPI Eina_Error EFL_MODEL_ERROR_INIT_FAILED = 0;
|
||||
EAPI Eina_Error EFL_MODEL_ERROR_PERMISSION_DENIED = 0;
|
||||
EAPI Eina_Error EFL_MODEL_ERROR_INCORRECT_VALUE = 0;
|
||||
EAPI Eina_Error EFL_MODEL_ERROR_INVALID_OBJECT = 0;
|
||||
|
||||
static const char EFL_MODEL_ERROR_UNKNOWN_STR[] = "Unknown Error";
|
||||
static const char EFL_MODEL_ERROR_NOT_SUPPORTED_STR[] = "Operation not supported";
|
||||
|
@ -20,6 +21,8 @@ static const char EFL_MODEL_ERROR_READ_ONLY_STR[] = "Value read only";
|
|||
static const char EFL_MODEL_ERROR_INIT_FAILED_STR[] = "Init failed";
|
||||
static const char EFL_MODEL_ERROR_PERMISSION_DENIED_STR[] = "Permission denied";
|
||||
static const char EFL_MODEL_ERROR_INCORRECT_VALUE_STR[] = "Incorrect value";
|
||||
static const char EFL_MODEL_ERROR_INVALID_OBJECT_STR[] = "Object is invalid";
|
||||
|
||||
|
||||
EAPI int
|
||||
efl_model_init()
|
||||
|
@ -45,6 +48,9 @@ efl_model_init()
|
|||
EFL_MODEL_ERROR_PERMISSION_DENIED = eina_error_msg_static_register(
|
||||
EFL_MODEL_ERROR_PERMISSION_DENIED_STR);
|
||||
|
||||
EFL_MODEL_ERROR_INVALID_OBJECT = eina_error_msg_static_register(
|
||||
EFL_MODEL_ERROR_INVALID_OBJECT_STR);
|
||||
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,291 @@
|
|||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <Efl.h>
|
||||
|
||||
#include "interfaces/efl_model_private.h"
|
||||
|
||||
#define MY_CLASS EFL_MODEL_CONTAINER_CLASS
|
||||
|
||||
void *
|
||||
_value_copy_alloc(void *v, const Eina_Value_Type *type)
|
||||
{
|
||||
if (!v)
|
||||
return v;
|
||||
|
||||
if (type == EINA_VALUE_TYPE_STRINGSHARE)
|
||||
return (void*) eina_stringshare_ref(v);
|
||||
else if (type == EINA_VALUE_TYPE_STRING)
|
||||
return (void*) strdup(v);
|
||||
else
|
||||
{
|
||||
void *ret = malloc(type->value_size);
|
||||
memcpy(ret, v, type->value_size);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
_value_free(void *v, const Eina_Value_Type *type)
|
||||
{
|
||||
if (!v)
|
||||
return;
|
||||
|
||||
if (type == EINA_VALUE_TYPE_STRINGSHARE)
|
||||
return eina_stringshare_del(v);
|
||||
else
|
||||
free(v);
|
||||
}
|
||||
|
||||
static void
|
||||
_values_free(Eina_Array *values, const Eina_Value_Type *type)
|
||||
{
|
||||
unsigned int i;
|
||||
void *v;
|
||||
Eina_Array_Iterator it;
|
||||
EINA_ARRAY_ITER_NEXT(values, i, v, it)
|
||||
{
|
||||
_value_free(v, type);
|
||||
}
|
||||
eina_array_free(values);
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
_stringshared_keys_free(const Eina_Hash *hash EINA_UNUSED, const void *key, void *data EINA_UNUSED, void *fdata EINA_UNUSED)
|
||||
{
|
||||
eina_stringshare_del(key);
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
_property_data_free_cb(void *data)
|
||||
{
|
||||
Child_Property_Data *cpd = data;
|
||||
_values_free(cpd->property_values, cpd->property_type);
|
||||
free(cpd);
|
||||
}
|
||||
|
||||
EOLIAN static Eo *
|
||||
_efl_model_container_eo_base_constructor(Eo *obj, Efl_Model_Container_Data *sd)
|
||||
{
|
||||
obj = eo_constructor(eo_super(obj, MY_CLASS));
|
||||
if (!obj)
|
||||
return NULL;
|
||||
|
||||
sd->obj = obj;
|
||||
sd->property_data = eina_hash_stringshared_new(_property_data_free_cb);
|
||||
sd->defined_properties = eina_array_new(8);
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
EOLIAN static void
|
||||
_efl_model_container_eo_base_destructor(Eo *obj, Efl_Model_Container_Data *sd)
|
||||
{
|
||||
Efl_Model *child;
|
||||
|
||||
EINA_LIST_FREE(sd->children, child)
|
||||
{
|
||||
if (child)
|
||||
{
|
||||
efl_model_container_item_invalidate(child);
|
||||
eo_parent_set(child, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
eina_array_free(sd->defined_properties);
|
||||
|
||||
eina_hash_foreach(sd->property_data, _stringshared_keys_free, NULL);
|
||||
eina_hash_free(sd->property_data);
|
||||
|
||||
eo_destructor(eo_super(obj, MY_CLASS));
|
||||
}
|
||||
|
||||
EOLIAN static const Eina_Value_Type *
|
||||
_efl_model_container_child_property_value_type_get(Eo *obj EINA_UNUSED, Efl_Model_Container_Data *sd, const char *property)
|
||||
{
|
||||
Eina_Stringshare *sshared = eina_stringshare_add(property);
|
||||
Child_Property_Data *cpd = eina_hash_find(sd->property_data, sshared);
|
||||
eina_stringshare_del(sshared);
|
||||
if (!cpd)
|
||||
return NULL;
|
||||
|
||||
return cpd->property_type;
|
||||
}
|
||||
|
||||
EOLIAN static Eina_Iterator *
|
||||
_efl_model_container_child_property_values_get(Eo *obj EINA_UNUSED, Efl_Model_Container_Data *sd, const char *property)
|
||||
{
|
||||
Eina_Stringshare *sshared = eina_stringshare_add(property);
|
||||
Child_Property_Data *cpd = eina_hash_find(sd->property_data, sshared);
|
||||
eina_stringshare_del(sshared);
|
||||
if (!cpd)
|
||||
return NULL;
|
||||
|
||||
return eina_array_iterator_new(cpd->property_values);
|
||||
}
|
||||
|
||||
EOLIAN static Eina_Bool
|
||||
_efl_model_container_child_property_add(Eo *obj, Efl_Model_Container_Data *sd, const char *name, const Eina_Value_Type *type, Eina_Iterator *values)
|
||||
{
|
||||
Eina_Array *arr = NULL;
|
||||
void *data = NULL;
|
||||
Eina_Stringshare *prop_name = NULL;
|
||||
Child_Property_Data *cpd = NULL;
|
||||
unsigned int i, in_count, children_count;
|
||||
|
||||
if (!type || !values)
|
||||
{
|
||||
EINA_LOG_WARN("Invalid input data");
|
||||
eina_error_set(EFL_MODEL_ERROR_INCORRECT_VALUE);
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
arr = eina_array_new(32);
|
||||
if (!arr)
|
||||
{
|
||||
eina_error_set(EFL_MODEL_ERROR_UNKNOWN);
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
EINA_ITERATOR_FOREACH(values, data)
|
||||
{
|
||||
void *new_data = _value_copy_alloc(data, type);
|
||||
if ((data && !new_data) || !eina_array_push(arr, new_data))
|
||||
{
|
||||
if (new_data)
|
||||
_value_free(new_data, type);
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
eina_iterator_free(values);
|
||||
|
||||
prop_name = eina_stringshare_add(name);
|
||||
cpd = eina_hash_find(sd->property_data, prop_name);
|
||||
if (!cpd)
|
||||
{
|
||||
cpd = calloc(1, sizeof(Child_Property_Data));
|
||||
if (!cpd)
|
||||
goto error;
|
||||
|
||||
cpd->property_type = type;
|
||||
cpd->property_values = arr;
|
||||
|
||||
if (!eina_array_push(sd->defined_properties, prop_name))
|
||||
goto error;
|
||||
|
||||
if (!eina_hash_direct_add(sd->property_data, prop_name, cpd))
|
||||
{
|
||||
eina_array_pop(sd->defined_properties);
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
eina_stringshare_del(prop_name);
|
||||
_values_free(cpd->property_values, cpd->property_type);
|
||||
|
||||
cpd->property_type = type;
|
||||
cpd->property_values = arr;
|
||||
}
|
||||
|
||||
in_count = eina_array_count(arr);
|
||||
children_count = eina_list_count(sd->children);
|
||||
|
||||
for (i = children_count; i < in_count; ++i)
|
||||
{
|
||||
Efl_Model_Children_Event cevt;
|
||||
Efl_Model *child;
|
||||
|
||||
child = eo_add(EFL_MODEL_CONTAINER_ITEM_CLASS, obj,
|
||||
efl_model_container_item_define(eo_self, sd, i));
|
||||
sd->children = eina_list_append(sd->children, child);
|
||||
|
||||
cevt.child = child;
|
||||
cevt.index = i;
|
||||
eo_event_callback_call(obj, EFL_MODEL_EVENT_CHILD_ADDED, &cevt);
|
||||
}
|
||||
|
||||
if (in_count > children_count)
|
||||
eo_event_callback_call(obj, EFL_MODEL_EVENT_CHILDREN_COUNT_CHANGED, &in_count);
|
||||
|
||||
return EINA_TRUE;
|
||||
|
||||
error:
|
||||
if (prop_name)
|
||||
eina_stringshare_del(prop_name);
|
||||
if (cpd)
|
||||
free(cpd);
|
||||
if (arr)
|
||||
_values_free(arr, type);
|
||||
eina_error_set(EFL_MODEL_ERROR_UNKNOWN);
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
EOLIAN static const Eina_Array *
|
||||
_efl_model_container_efl_model_properties_get(Eo *obj EINA_UNUSED, Efl_Model_Container_Data *sd EINA_UNUSED)
|
||||
{
|
||||
return sd->defined_properties;
|
||||
}
|
||||
|
||||
|
||||
EOLIAN static void
|
||||
_efl_model_container_efl_model_property_set(Eo *obj EINA_UNUSED, Efl_Model_Container_Data *sd EINA_UNUSED, const char *property EINA_UNUSED, const Eina_Value *value EINA_UNUSED, Eina_Promise_Owner *promise_owner)
|
||||
{
|
||||
eina_promise_owner_error_set(promise_owner, EFL_MODEL_ERROR_NOT_FOUND);
|
||||
}
|
||||
|
||||
EOLIAN static Eina_Promise *
|
||||
_efl_model_container_efl_model_property_get(Eo *obj EINA_UNUSED, Efl_Model_Container_Data *sd EINA_UNUSED, const char *property EINA_UNUSED)
|
||||
{
|
||||
Eina_Promise_Owner *promise_owner = eina_promise_add();
|
||||
Eina_Promise *rpromise = eina_promise_owner_promise_get(promise_owner);
|
||||
|
||||
eina_promise_owner_error_set(promise_owner, EFL_MODEL_ERROR_NOT_FOUND);
|
||||
|
||||
return rpromise;
|
||||
}
|
||||
|
||||
EOLIAN static Eina_Promise *
|
||||
_efl_model_container_efl_model_children_slice_get(Eo *obj EINA_UNUSED, Efl_Model_Container_Data *sd, unsigned int start, unsigned int count)
|
||||
{
|
||||
Eina_Promise_Owner *promise_owner = eina_promise_add();
|
||||
Eina_Promise *rpromise = eina_promise_owner_promise_get(promise_owner);
|
||||
|
||||
Eina_Accessor* accessor = efl_model_list_slice(sd->children, start, count);
|
||||
eina_promise_owner_value_set(promise_owner, accessor, (Eina_Promise_Free_Cb)&eina_accessor_free);
|
||||
|
||||
return rpromise;
|
||||
}
|
||||
|
||||
EOLIAN static Eina_Promise *
|
||||
_efl_model_container_efl_model_children_count_get(Eo *obj EINA_UNUSED, Efl_Model_Container_Data *sd)
|
||||
{
|
||||
Eina_Promise_Owner *promise_owner = eina_promise_add();
|
||||
Eina_Promise *rpromise = eina_promise_owner_promise_get(promise_owner);
|
||||
|
||||
unsigned int *count = calloc(1, sizeof(unsigned int));
|
||||
*count = eina_list_count(sd->children);
|
||||
eina_promise_owner_value_set(promise_owner, count, &free);
|
||||
|
||||
return rpromise;
|
||||
}
|
||||
|
||||
EOLIAN static Eo *
|
||||
_efl_model_container_efl_model_child_add(Eo *obj EINA_UNUSED, Efl_Model_Container_Data *sd EINA_UNUSED)
|
||||
{
|
||||
EINA_LOG_WARN("child_add not supported by Efl.Model.Container");
|
||||
eina_error_set(EFL_MODEL_ERROR_NOT_SUPPORTED);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
EOLIAN static void
|
||||
_efl_model_container_efl_model_child_del(Eo *obj EINA_UNUSED, Efl_Model_Container_Data *sd EINA_UNUSED, Eo *child EINA_UNUSED)
|
||||
{
|
||||
EINA_LOG_WARN("child_del not supported by Efl.Model.Container");
|
||||
eina_error_set(EFL_MODEL_ERROR_NOT_SUPPORTED);
|
||||
}
|
||||
|
||||
#include "interfaces/efl_model_container.eo.c"
|
|
@ -0,0 +1,68 @@
|
|||
import eina_types;
|
||||
|
||||
class Efl.Model.Container (Eo.Base, Efl.Model)
|
||||
{
|
||||
[[
|
||||
Class used to create data models from Eina containers.
|
||||
|
||||
Each container supplied represent a series of property values, each item
|
||||
being the property value for a child object (@Efl.Model.Container.Item).
|
||||
|
||||
The data in the given containers are copied and stored internally.
|
||||
|
||||
Several containers can be supplied, and the number of allocated children is
|
||||
based on the container with the biggest size.
|
||||
As illustrated above:
|
||||
|
||||
|‾‾‾‾‾||‾‾‾‾‾||‾‾‾‾‾||‾‾‾‾‾| <br/>
|
||||
cont1, property: "code" -> ["A"] ["B"] ["C"] ["D"] <br/>
|
||||
cont2, property: "day" -> [ 8 ] [ 24] [ 14] <br/>
|
||||
|_____||_____||_____||_____| <br/>
|
||||
| | | | <br/>
|
||||
child1 child2 child3 child4 <br/>
|
||||
]]
|
||||
methods {
|
||||
child_property_value_type_get {
|
||||
[[Get the type of the given property.]]
|
||||
params {
|
||||
name: string; [[Property name]]
|
||||
}
|
||||
return: const(Eina.Value.Type)*; [[Property type]]
|
||||
}
|
||||
child_property_values_get {
|
||||
[[Get the values for the given property.]]
|
||||
params {
|
||||
name: string; [[Property name]]
|
||||
}
|
||||
return: free(own(iterator<void_ptr>), eina_iterator_free) @warn_unused;
|
||||
[[The currently wrapped values]]
|
||||
}
|
||||
child_property_add {
|
||||
[[Add the given property to child objects and supply the values.
|
||||
|
||||
Each item will represent the value of the given property in the
|
||||
respective child within the data model.
|
||||
|
||||
New children objects are allocated as necessary.
|
||||
|
||||
Value type is required for compatibility with the @Efl.Model API.]]
|
||||
params {
|
||||
name: string; [[Property name]]
|
||||
type: const(Eina.Value.Type)*; [[Property type]]
|
||||
values: own(iterator<const(void_ptr)>); [[Values to be added]]
|
||||
}
|
||||
return: bool; [[$true on success, $false otherwise]]
|
||||
}
|
||||
}
|
||||
implements {
|
||||
Eo.Base.constructor;
|
||||
Eo.Base.destructor;
|
||||
Efl.Model.properties.get;
|
||||
Efl.Model.property_set;
|
||||
Efl.Model.property_get;
|
||||
Efl.Model.child_add;
|
||||
Efl.Model.child_del;
|
||||
Efl.Model.children_slice_get;
|
||||
Efl.Model.children_count_get;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,187 @@
|
|||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <Efl.h>
|
||||
|
||||
#include "interfaces/efl_model_private.h"
|
||||
|
||||
#define MY_CLASS EFL_MODEL_CONTAINER_ITEM_CLASS
|
||||
|
||||
static void
|
||||
_item_value_free_cb(void *data)
|
||||
{
|
||||
eina_value_free(data);
|
||||
}
|
||||
|
||||
EOLIAN static void
|
||||
_efl_model_container_item_define(Eo *obj EINA_UNUSED, Efl_Model_Container_Item_Data *sd, void *parent_data, unsigned int index)
|
||||
{
|
||||
sd->parent_data = parent_data;
|
||||
sd->index = index;
|
||||
}
|
||||
|
||||
EOLIAN static void
|
||||
_efl_model_container_item_invalidate(Eo *obj EINA_UNUSED, Efl_Model_Container_Item_Data *sd)
|
||||
{
|
||||
sd->parent_data = NULL;
|
||||
sd->index = 0;
|
||||
}
|
||||
|
||||
EOLIAN static const Eina_Array *
|
||||
_efl_model_container_item_efl_model_properties_get(Eo *obj EINA_UNUSED, Efl_Model_Container_Item_Data *sd)
|
||||
{
|
||||
if (!sd->parent_data)
|
||||
return NULL;
|
||||
|
||||
return sd->parent_data->defined_properties;
|
||||
}
|
||||
|
||||
EOLIAN static void
|
||||
_efl_model_container_item_efl_model_property_set(Eo *obj EINA_UNUSED, Efl_Model_Container_Item_Data *sd, const char *property, const Eina_Value *value, Eina_Promise_Owner *promise_owner)
|
||||
{
|
||||
Eina_Stringshare *prop_name;
|
||||
Child_Property_Data *cpd;
|
||||
void *data, *new_data;
|
||||
|
||||
if (!sd->parent_data)
|
||||
{
|
||||
eina_promise_owner_error_set(promise_owner, EFL_MODEL_ERROR_INVALID_OBJECT);
|
||||
return;
|
||||
}
|
||||
|
||||
prop_name = eina_stringshare_add(property);
|
||||
cpd = eina_hash_find(sd->parent_data->property_data, prop_name);
|
||||
eina_stringshare_del(prop_name);
|
||||
if (!cpd || !cpd->property_values ||
|
||||
sd->index >= eina_array_count_get(cpd->property_values))
|
||||
{
|
||||
eina_promise_owner_error_set(promise_owner, EFL_MODEL_ERROR_NOT_FOUND);
|
||||
return;
|
||||
}
|
||||
|
||||
if (cpd->property_type != eina_value_type_get(value))
|
||||
{
|
||||
eina_promise_owner_error_set(promise_owner, EFL_MODEL_ERROR_INCORRECT_VALUE);
|
||||
return;
|
||||
}
|
||||
|
||||
data = calloc(1, cpd->property_type->value_size);
|
||||
if (!data || !eina_value_pget(value, data))
|
||||
{
|
||||
if (data)
|
||||
free(data);
|
||||
eina_promise_owner_error_set(promise_owner, EFL_MODEL_ERROR_UNKNOWN);
|
||||
return;
|
||||
}
|
||||
|
||||
new_data = _value_copy_alloc(data, cpd->property_type);
|
||||
free(data);
|
||||
|
||||
_value_free(eina_array_data_get(cpd->property_values, sd->index), cpd->property_type);
|
||||
eina_array_data_set(cpd->property_values, sd->index, new_data);
|
||||
|
||||
{
|
||||
Eina_Value *v = eina_value_new(cpd->property_type);
|
||||
if (v && eina_value_copy(value, v))
|
||||
eina_promise_owner_value_set(promise_owner, v, _item_value_free_cb);
|
||||
else
|
||||
{
|
||||
if (v)
|
||||
eina_value_free(v);
|
||||
eina_promise_owner_error_set(promise_owner, EFL_MODEL_ERROR_UNKNOWN);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
EOLIAN static Eina_Promise *
|
||||
_efl_model_container_item_efl_model_property_get(Eo *obj EINA_UNUSED, Efl_Model_Container_Item_Data *sd, const char *property)
|
||||
{
|
||||
Eina_Stringshare *prop_name;
|
||||
Child_Property_Data *cpd;
|
||||
Eina_Value *value;
|
||||
Eina_Promise_Owner *promise_owner = eina_promise_add();
|
||||
Eina_Promise *rpromise = eina_promise_owner_promise_get(promise_owner);
|
||||
|
||||
if (!sd->parent_data)
|
||||
{
|
||||
eina_promise_owner_error_set(promise_owner, EFL_MODEL_ERROR_INVALID_OBJECT);
|
||||
return rpromise;
|
||||
}
|
||||
|
||||
prop_name = eina_stringshare_add(property);
|
||||
cpd = eina_hash_find(sd->parent_data->property_data, prop_name);
|
||||
eina_stringshare_del(prop_name);
|
||||
if (!cpd || !cpd->property_values ||
|
||||
sd->index >= eina_array_count_get(cpd->property_values))
|
||||
{
|
||||
eina_promise_owner_error_set(promise_owner, EFL_MODEL_ERROR_NOT_FOUND);
|
||||
return rpromise;
|
||||
}
|
||||
|
||||
value = eina_value_new(cpd->property_type);
|
||||
if (!value)
|
||||
eina_promise_owner_error_set(promise_owner, EFL_MODEL_ERROR_UNKNOWN);
|
||||
else
|
||||
{
|
||||
Eina_Bool r = EINA_FALSE;
|
||||
void *data = eina_array_data_get(cpd->property_values, sd->index);
|
||||
|
||||
if (cpd->property_type == EINA_VALUE_TYPE_STRINGSHARE ||
|
||||
cpd->property_type == EINA_VALUE_TYPE_STRING)
|
||||
r = eina_value_set(value, data);
|
||||
else
|
||||
r = eina_value_pset(value, data);
|
||||
|
||||
if (r)
|
||||
eina_promise_owner_value_set(promise_owner, value, _item_value_free_cb);
|
||||
else
|
||||
{
|
||||
eina_promise_owner_error_set(promise_owner, EFL_MODEL_ERROR_UNKNOWN);
|
||||
eina_value_free(value);
|
||||
}
|
||||
}
|
||||
return rpromise;
|
||||
}
|
||||
|
||||
EOLIAN static Eina_Promise *
|
||||
_efl_model_container_item_efl_model_children_slice_get(Eo *obj EINA_UNUSED, Efl_Model_Container_Item_Data *sd EINA_UNUSED, unsigned int start EINA_UNUSED, unsigned int count EINA_UNUSED)
|
||||
{
|
||||
Eina_Promise_Owner *promise_owner = eina_promise_add();
|
||||
Eina_Promise *rpromise = eina_promise_owner_promise_get(promise_owner);
|
||||
|
||||
eina_promise_owner_value_set(promise_owner, NULL, NULL);
|
||||
|
||||
return rpromise;
|
||||
}
|
||||
|
||||
EOLIAN static Eina_Promise *
|
||||
_efl_model_container_item_efl_model_children_count_get(Eo *obj EINA_UNUSED, Efl_Model_Container_Item_Data *sd EINA_UNUSED)
|
||||
{
|
||||
Eina_Promise_Owner *promise_owner = eina_promise_add();
|
||||
Eina_Promise *rpromise = eina_promise_owner_promise_get(promise_owner);
|
||||
|
||||
unsigned int *count = calloc(1, sizeof(unsigned int));
|
||||
*count = 0;
|
||||
eina_promise_owner_value_set(promise_owner, count, &free);
|
||||
|
||||
return rpromise;
|
||||
}
|
||||
|
||||
EOLIAN static Eo *
|
||||
_efl_model_container_item_efl_model_child_add(Eo *obj EINA_UNUSED, Efl_Model_Container_Item_Data *sd EINA_UNUSED)
|
||||
{
|
||||
EINA_LOG_WARN("child_add not supported by Efl.Model.Container.Item");
|
||||
eina_error_set(EFL_MODEL_ERROR_NOT_SUPPORTED);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
EOLIAN static void
|
||||
_efl_model_container_item_efl_model_child_del(Eo *obj EINA_UNUSED, Efl_Model_Container_Item_Data *sd EINA_UNUSED, Eo *child EINA_UNUSED)
|
||||
{
|
||||
EINA_LOG_WARN("child_del not supported by Efl.Model.Container.Item");
|
||||
eina_error_set(EFL_MODEL_ERROR_NOT_SUPPORTED);
|
||||
}
|
||||
|
||||
#include "interfaces/efl_model_container_item.eo.c"
|
|
@ -0,0 +1,39 @@
|
|||
import eina_types;
|
||||
|
||||
class Efl.Model.Container.Item (Eo.Base, Efl.Model)
|
||||
{
|
||||
[[
|
||||
Used as a child of @Efl.Model.Container.
|
||||
|
||||
Provides the @Efl.Model API for elements of @Efl.Model.Container.
|
||||
Should not be used in another context, so do not manually create objects
|
||||
of this class.
|
||||
]]
|
||||
methods {
|
||||
define {
|
||||
[[Define @Efl.Model.Container.Item internal data.]]
|
||||
params {
|
||||
parent_data: void_ptr; [[Pointer to the private data of the
|
||||
@Efl.Model.Container parent object.]]
|
||||
index: uint; [[Index of this item within the @Efl.Model.Container
|
||||
children.]]
|
||||
}
|
||||
}
|
||||
invalidate {
|
||||
[[Invalidate the object preventing it from using the given parent
|
||||
data.]]
|
||||
}
|
||||
}
|
||||
implements {
|
||||
Efl.Model.properties.get;
|
||||
Efl.Model.property_set;
|
||||
Efl.Model.property_get;
|
||||
Efl.Model.child_add;
|
||||
Efl.Model.child_del;
|
||||
Efl.Model.children_slice_get;
|
||||
Efl.Model.children_count_get;
|
||||
}
|
||||
constructors {
|
||||
.define;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,197 @@
|
|||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <Efl.h>
|
||||
|
||||
#define MY_CLASS EFL_MODEL_ITEM_CLASS
|
||||
|
||||
typedef struct _Efl_Model_Item_Data Efl_Model_Item_Data;
|
||||
struct _Efl_Model_Item_Data
|
||||
{
|
||||
Eina_Hash *properties;
|
||||
Eina_Array *defined_properties;
|
||||
Eina_List *children;
|
||||
};
|
||||
|
||||
static void
|
||||
_item_value_free_cb(void *data)
|
||||
{
|
||||
eina_value_free(data);
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
_stringshared_keys_free(const Eina_Hash *hash EINA_UNUSED, const void *key, void *data EINA_UNUSED, void *fdata EINA_UNUSED)
|
||||
{
|
||||
eina_stringshare_del(key);
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
EOLIAN static Eo *
|
||||
_efl_model_item_eo_base_constructor(Eo *obj, Efl_Model_Item_Data *sd)
|
||||
{
|
||||
obj = eo_constructor(eo_super(obj, MY_CLASS));
|
||||
if (!obj)
|
||||
return NULL;
|
||||
|
||||
sd->properties = eina_hash_stringshared_new(_item_value_free_cb);
|
||||
sd->defined_properties = eina_array_new(8);
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
EOLIAN static void
|
||||
_efl_model_item_eo_base_destructor(Eo *obj, Efl_Model_Item_Data *sd)
|
||||
{
|
||||
Efl_Model *child;
|
||||
|
||||
EINA_LIST_FREE(sd->children, child)
|
||||
{
|
||||
if (child)
|
||||
eo_parent_set(child, NULL);
|
||||
}
|
||||
|
||||
eina_hash_foreach(sd->properties, _stringshared_keys_free, NULL);
|
||||
eina_hash_free(sd->properties);
|
||||
|
||||
eina_array_free(sd->defined_properties);
|
||||
|
||||
eo_destructor(eo_super(obj, MY_CLASS));
|
||||
}
|
||||
|
||||
EOLIAN static const Eina_Array *
|
||||
_efl_model_item_efl_model_properties_get(Eo *obj EINA_UNUSED, Efl_Model_Item_Data *sd)
|
||||
{
|
||||
return sd->defined_properties;
|
||||
}
|
||||
|
||||
|
||||
EOLIAN static void
|
||||
_efl_model_item_efl_model_property_set(Eo *obj EINA_UNUSED, Efl_Model_Item_Data *sd, const char *property, const Eina_Value *value, Eina_Promise_Owner *promise_owner)
|
||||
{
|
||||
Eina_Stringshare *sshared = eina_stringshare_add(property);
|
||||
Eina_Value *p_v = eina_hash_find(sd->properties, sshared);
|
||||
if (p_v)
|
||||
{
|
||||
eina_stringshare_del(sshared);
|
||||
if (!eina_value_copy(value, p_v))
|
||||
goto err1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!eina_array_push(sd->defined_properties, sshared))
|
||||
goto err2;
|
||||
|
||||
p_v = eina_value_new(eina_value_type_get(value));
|
||||
if (!p_v)
|
||||
goto err3;
|
||||
|
||||
if (!eina_value_copy(value, p_v) ||
|
||||
!eina_hash_direct_add(sd->properties, sshared, p_v))
|
||||
goto err4;
|
||||
}
|
||||
|
||||
eina_promise_owner_value_set(promise_owner, p_v, NULL);
|
||||
return;
|
||||
|
||||
err4:
|
||||
eina_value_free(p_v);
|
||||
err3:
|
||||
eina_array_pop(sd->defined_properties);
|
||||
err2:
|
||||
eina_stringshare_del(sshared);
|
||||
err1:
|
||||
eina_promise_owner_error_set(promise_owner, EFL_MODEL_ERROR_UNKNOWN);
|
||||
}
|
||||
|
||||
EOLIAN static Eina_Promise *
|
||||
_efl_model_item_efl_model_property_get(Eo *obj EINA_UNUSED, Efl_Model_Item_Data *sd, const char *property)
|
||||
{
|
||||
Eina_Promise_Owner *promise_owner = eina_promise_add();
|
||||
Eina_Promise *rpromise = eina_promise_owner_promise_get(promise_owner);
|
||||
|
||||
Eina_Stringshare *sshare = eina_stringshare_add(property);
|
||||
Eina_Value *p_v = eina_hash_find(sd->properties, sshare);
|
||||
eina_stringshare_del(sshare);
|
||||
if (p_v)
|
||||
eina_promise_owner_value_set(promise_owner, p_v, NULL);
|
||||
else
|
||||
eina_promise_owner_error_set(promise_owner, EFL_MODEL_ERROR_NOT_FOUND);
|
||||
|
||||
return rpromise;
|
||||
}
|
||||
|
||||
EOLIAN static Eina_Promise *
|
||||
_efl_model_item_efl_model_children_slice_get(Eo *obj EINA_UNUSED, Efl_Model_Item_Data *sd, unsigned int start, unsigned int count)
|
||||
{
|
||||
Eina_Promise_Owner *promise_owner = eina_promise_add();
|
||||
Eina_Promise *rpromise = eina_promise_owner_promise_get(promise_owner);
|
||||
|
||||
Eina_Accessor* accessor = efl_model_list_slice(sd->children, start, count);
|
||||
eina_promise_owner_value_set(promise_owner, accessor, (Eina_Promise_Free_Cb)&eina_accessor_free);
|
||||
|
||||
return rpromise;
|
||||
}
|
||||
|
||||
EOLIAN static Eina_Promise *
|
||||
_efl_model_item_efl_model_children_count_get(Eo *obj EINA_UNUSED, Efl_Model_Item_Data *sd)
|
||||
{
|
||||
Eina_Promise_Owner *promise_owner = eina_promise_add();
|
||||
Eina_Promise *rpromise = eina_promise_owner_promise_get(promise_owner);
|
||||
|
||||
unsigned int *count = calloc(1, sizeof(unsigned int));
|
||||
*count = eina_list_count(sd->children);
|
||||
eina_promise_owner_value_set(promise_owner, count, &free);
|
||||
|
||||
return rpromise;
|
||||
}
|
||||
|
||||
EOLIAN static Eo *
|
||||
_efl_model_item_efl_model_child_add(Eo *obj, Efl_Model_Item_Data *sd)
|
||||
{
|
||||
Efl_Model_Children_Event cevt;
|
||||
Efl_Model *child = eo_add(EFL_MODEL_ITEM_CLASS, obj);
|
||||
if (!child)
|
||||
{
|
||||
EINA_LOG_ERR("Could not allocate Efl.Model.Item");
|
||||
eina_error_set(EFL_MODEL_ERROR_UNKNOWN);
|
||||
return NULL;
|
||||
}
|
||||
sd->children = eina_list_append(sd->children, child);
|
||||
cevt.child = child;
|
||||
cevt.index = eina_list_count(sd->children);
|
||||
eo_event_callback_call(obj, EFL_MODEL_EVENT_CHILD_ADDED, &cevt);
|
||||
eo_event_callback_call(obj, EFL_MODEL_EVENT_CHILDREN_COUNT_CHANGED, &cevt.index);
|
||||
return child;
|
||||
}
|
||||
|
||||
EOLIAN static void
|
||||
_efl_model_item_efl_model_child_del(Eo *obj, Efl_Model_Item_Data *sd, Eo *child)
|
||||
{
|
||||
Eina_List *l;
|
||||
Efl_Model *data;
|
||||
unsigned int i = 0;
|
||||
EINA_LIST_FOREACH(sd->children, l, data)
|
||||
{
|
||||
if (data == child)
|
||||
{
|
||||
Efl_Model_Children_Event cevt;
|
||||
sd->children = eina_list_remove_list(sd->children, l);
|
||||
|
||||
cevt.child = eo_ref(child);
|
||||
cevt.index = i;
|
||||
|
||||
eo_parent_set(child, NULL);
|
||||
|
||||
eo_event_callback_call(obj, EFL_MODEL_EVENT_CHILD_REMOVED, &cevt);
|
||||
eo_unref(child);
|
||||
|
||||
i = eina_list_count(sd->children);
|
||||
eo_event_callback_call(obj, EFL_MODEL_EVENT_CHILDREN_COUNT_CHANGED, &i);
|
||||
break;
|
||||
}
|
||||
++i;
|
||||
}
|
||||
}
|
||||
|
||||
#include "interfaces/efl_model_item.eo.c"
|
|
@ -0,0 +1,26 @@
|
|||
import eina_types;
|
||||
|
||||
class Efl.Model.Item (Eo.Base, Efl.Model)
|
||||
{
|
||||
[[
|
||||
Generic model that allows any property to be manually set.
|
||||
Also children of the same type can be added and deleted.
|
||||
|
||||
Intended to be used in scenarios where the user needs a manually defined
|
||||
data model, like in tests.
|
||||
|
||||
It does not model anything in particular and does not affect anything else
|
||||
in the system.
|
||||
]]
|
||||
implements {
|
||||
Eo.Base.constructor;
|
||||
Eo.Base.destructor;
|
||||
Efl.Model.properties.get;
|
||||
Efl.Model.property_set;
|
||||
Efl.Model.property_get;
|
||||
Efl.Model.child_add;
|
||||
Efl.Model.child_del;
|
||||
Efl.Model.children_slice_get;
|
||||
Efl.Model.children_count_get;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
#ifndef EFL_MODEL_PRIVATE_H__
|
||||
# define EFL_MODEL_PRIVATE_H__
|
||||
|
||||
typedef struct _Child_Property_Data Child_Property_Data;
|
||||
struct _Child_Property_Data
|
||||
{
|
||||
const Eina_Value_Type *property_type;
|
||||
Eina_Array *property_values;
|
||||
};
|
||||
|
||||
typedef struct _Efl_Model_Container_Data Efl_Model_Container_Data;
|
||||
struct _Efl_Model_Container_Data
|
||||
{
|
||||
Eo *obj;
|
||||
Eina_Hash *property_data;
|
||||
Eina_Array *defined_properties;
|
||||
Eina_List *children;
|
||||
};
|
||||
|
||||
|
||||
typedef struct _Efl_Model_Container_Item_Data Efl_Model_Container_Item_Data;
|
||||
struct _Efl_Model_Container_Item_Data
|
||||
{
|
||||
Efl_Model_Container_Data *parent_data;
|
||||
unsigned int index;
|
||||
};
|
||||
|
||||
void *_value_copy_alloc(void *v, const Eina_Value_Type *type);
|
||||
|
||||
void _value_free(void *v, const Eina_Value_Type *type);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,12 @@
|
|||
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;
|
||||
}
|
||||
return: Efl.Canvas;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
interface Efl.Ui.Model.Connect
|
||||
{
|
||||
methods {
|
||||
connect {
|
||||
params {
|
||||
name: string;
|
||||
properties: string;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
interface Efl.Ui.View ()
|
||||
{
|
||||
methods {
|
||||
@property model {
|
||||
[[Model that is/will be ]]
|
||||
get {} set {}
|
||||
values {
|
||||
model: Efl.Model;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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 */
|
||||
|
|
|
@ -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},
|
||||
|
@ -632,6 +633,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);
|
||||
|
@ -1693,6 +1702,107 @@ _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;
|
||||
Eina_Array_Iterator it;
|
||||
const char *prop;
|
||||
unsigned int i;
|
||||
|
||||
EFL_UI_IMAGE_DATA_GET(data, pd);
|
||||
|
||||
if (!evt->changed_properties)
|
||||
return;
|
||||
|
||||
if (pd->model && pd->prop_con)
|
||||
{
|
||||
EINA_ARRAY_ITER_NEXT(evt->changed_properties, i, prop, it)
|
||||
{
|
||||
if (!strcmp(pd->prop_con, prop))
|
||||
{
|
||||
Eina_Promise *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)
|
||||
{
|
||||
|
|
|
@ -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 {
|
||||
|
@ -165,6 +166,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;
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
#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;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
static Efl_Canvas *
|
||||
_efl_ui_image_factory_efl_ui_factory_create(Eo *obj EINA_UNUSED, Efl_Ui_Image_Factory_Data *pd, Efl_Model *model)
|
||||
{
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(pd->property, NULL);
|
||||
Efl_Canvas *ev = eo_add(EFL_UI_IMAGE_CLASS, eo_parent_get(obj));
|
||||
efl_ui_view_model_set(ev, model);
|
||||
efl_ui_model_connect(ev, NULL, pd->property);
|
||||
|
||||
return ev;
|
||||
}
|
||||
|
||||
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"
|
|
@ -0,0 +1,9 @@
|
|||
class Efl.Ui.Image.Factory (Eo.Base, Efl.Ui.Factory)
|
||||
{
|
||||
implements {
|
||||
Eo.Base.constructor;
|
||||
Eo.Base.destructor;
|
||||
Efl.Ui.Factory.create;
|
||||
Efl.Ui.Model.Connect.connect;
|
||||
}
|
||||
}
|
|
@ -78,6 +78,8 @@ struct _Efl_Ui_Image_Data
|
|||
|
||||
const char *stdicon;
|
||||
|
||||
Efl_Model *model;
|
||||
Eina_Stringshare *prop_con;
|
||||
|
||||
struct {
|
||||
int requested_size;
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
||||
/**
|
||||
|
|
|
@ -40,3 +40,4 @@ enum @extern Eina.Xattr.Flags {
|
|||
created [[This will only succeed if the extended attribute wasn't previously set]]
|
||||
}
|
||||
|
||||
struct @extern Eina.Value.Type;
|
||||
|
|
|
@ -0,0 +1,51 @@
|
|||
/* EINA - EFL data type library
|
||||
* Copyright (C) 2008 Cedric Bail
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library;
|
||||
* if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include <Eina.h>
|
||||
|
||||
#include "efl_suite.h"
|
||||
#include "../efl_check.h"
|
||||
|
||||
static const Efl_Test_Case etc[] = {
|
||||
{ "Efl_Model_Container", efl_test_case_model_container },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
int failed_count;
|
||||
|
||||
if (!_efl_test_option_disp(argc, argv, etc))
|
||||
return 0;
|
||||
|
||||
putenv("EFL_RUN_IN_TREE=1");
|
||||
|
||||
eina_init();
|
||||
|
||||
failed_count = _efl_suite_build_and_run(argc - 1, (const char **)argv + 1,
|
||||
"Efl", etc);
|
||||
|
||||
eina_shutdown();
|
||||
|
||||
return (failed_count == 0) ? 0 : 255;
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
/* EFL - EFL library
|
||||
* Copyright (C) 2008 Cedric Bail
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library;
|
||||
* if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef EFL_SUITE_H_
|
||||
#define EFL_SUITE_H_
|
||||
|
||||
#include <check.h>
|
||||
|
||||
void efl_test_case_model_container(TCase *tc);
|
||||
|
||||
#endif /* EFL_SUITE_H_ */
|
|
@ -0,0 +1,160 @@
|
|||
/* EFL - EFL library
|
||||
* Copyright (C) 2013 Cedric Bail
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library;
|
||||
* if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include "efl_suite.h"
|
||||
|
||||
#include <Ecore.h>
|
||||
#include <Efl.h>
|
||||
|
||||
typedef struct _Test_Container_Data {
|
||||
int item_count;
|
||||
Eina_Bool pass_flag;
|
||||
Eina_Bool fail_flag;
|
||||
} Test_Container_Data;
|
||||
|
||||
typedef struct _Test_Container_Item_Data {
|
||||
Test_Container_Data* test_data;
|
||||
unsigned int index;
|
||||
} Test_Container_Item_Data;
|
||||
|
||||
const int base_int[7] = {10, 11, 12, 13, 14, 0, 16};
|
||||
const char * const base_str[7] = {"A", "B", "C", "D", "E", "", "GH"};
|
||||
|
||||
static void
|
||||
_container_property_get_then(void *data, void *values)
|
||||
{
|
||||
Eina_Iterator *value_itt = values;
|
||||
Test_Container_Item_Data *test_item_data = data;
|
||||
Eina_Value *value_int = NULL;
|
||||
Eina_Value *value_str = NULL;
|
||||
int cmp_int = 0;
|
||||
const char *cmp_str = NULL;
|
||||
|
||||
test_item_data->test_data->item_count++;
|
||||
|
||||
if (!eina_iterator_next(value_itt, (void**)&value_int) ||
|
||||
!eina_iterator_next(value_itt, (void**)&value_str))
|
||||
{
|
||||
test_item_data->test_data->fail_flag = EINA_TRUE;
|
||||
return;
|
||||
}
|
||||
|
||||
eina_value_get(value_int, &cmp_int);
|
||||
eina_value_get(value_str, &cmp_str);
|
||||
|
||||
if (cmp_int != base_int[test_item_data->index] ||
|
||||
strcmp(cmp_str, base_str[test_item_data->index]) != 0)
|
||||
{
|
||||
test_item_data->test_data->fail_flag = EINA_TRUE;
|
||||
}
|
||||
|
||||
if (test_item_data->test_data->item_count == 7)
|
||||
{
|
||||
test_item_data->test_data->pass_flag = EINA_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
_children_slice_promise_then(void *data, void *value)
|
||||
{
|
||||
Eina_Accessor *children_accessor = value;
|
||||
unsigned int i = 0;
|
||||
Efl_Model *child;
|
||||
|
||||
if (children_accessor)
|
||||
{
|
||||
EINA_ACCESSOR_FOREACH(children_accessor, i, child)
|
||||
{
|
||||
Eina_Promise *promises[3] = {NULL,};
|
||||
Eina_Promise *promise_all = NULL;
|
||||
Test_Container_Item_Data *test_item_data = calloc(1, sizeof(Test_Container_Item_Data));
|
||||
|
||||
test_item_data->test_data = data;
|
||||
test_item_data->index = i;
|
||||
|
||||
promises[0] = efl_model_property_get(child, "test_p_int");
|
||||
promises[1] = efl_model_property_get(child, "test_p_str");
|
||||
|
||||
promise_all = eina_promise_all(eina_carray_iterator_new((void**)promises));
|
||||
eina_promise_then(promise_all, _container_property_get_then, NULL, test_item_data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
START_TEST(efl_test_model_container_values)
|
||||
{
|
||||
Efl_Model_Container* model;
|
||||
Eina_Promise *promise;
|
||||
Test_Container_Data test_data;
|
||||
int **cmp_int;
|
||||
const char **cmp_str;
|
||||
int i;
|
||||
|
||||
eo_init();
|
||||
|
||||
cmp_int = calloc(8, sizeof(int*));
|
||||
cmp_str = calloc(8, sizeof(const char*));
|
||||
for (i = 0; i < 7; ++i)
|
||||
{
|
||||
cmp_int[i] = calloc(1, sizeof(int));
|
||||
*(cmp_int[i]) = base_int[i];
|
||||
cmp_str[i] = strdup(base_str[i]);
|
||||
}
|
||||
|
||||
model = eo_add(EFL_MODEL_CONTAINER_CLASS, NULL);
|
||||
|
||||
efl_model_container_child_property_add(model, "test_p_int", EINA_VALUE_TYPE_INT,
|
||||
eina_carray_iterator_new((void**)cmp_int));
|
||||
efl_model_container_child_property_add(model, "test_p_str", EINA_VALUE_TYPE_STRING,
|
||||
eina_carray_iterator_new((void**)cmp_str));
|
||||
|
||||
for (i = 0; i < 7; ++i)
|
||||
{
|
||||
free(cmp_int[i]);
|
||||
free(cmp_str[i]);
|
||||
}
|
||||
free(cmp_int);
|
||||
free(cmp_str);
|
||||
|
||||
promise = efl_model_children_slice_get(model, 0, 0);
|
||||
|
||||
test_data.item_count = 0;
|
||||
test_data.pass_flag = EINA_FALSE;
|
||||
test_data.fail_flag = EINA_FALSE;
|
||||
|
||||
eina_promise_then(promise, _children_slice_promise_then, NULL, &test_data);
|
||||
|
||||
ecore_main_loop_iterate();
|
||||
|
||||
ck_assert(!!test_data.pass_flag);
|
||||
ck_assert(!test_data.fail_flag);
|
||||
|
||||
eo_shutdown();
|
||||
}
|
||||
END_TEST
|
||||
|
||||
void
|
||||
efl_test_case_model_container(TCase *tc)
|
||||
{
|
||||
tcase_add_test(tc, efl_test_model_container_values);
|
||||
}
|
|
@ -87,9 +87,45 @@ START_TEST(elm_layout_edje_attach)
|
|||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(elm_layout_model_connect)
|
||||
{
|
||||
char buf[PATH_MAX];
|
||||
Evas_Object *win, *ly;
|
||||
Efl_Model_Item *model;
|
||||
Eina_Value v;
|
||||
const char *part_text;
|
||||
const char text_value[] = "A random string for elm_layout_model_connect test";
|
||||
|
||||
elm_init(1, NULL);
|
||||
win = elm_win_add(NULL, "layout", ELM_WIN_BASIC);
|
||||
|
||||
ly = eo_add(ELM_LAYOUT_CLASS, win);
|
||||
snprintf(buf, sizeof(buf), "%s/objects/test.edj", ELM_TEST_DATA_DIR);
|
||||
elm_layout_file_set(ly, buf, "layout");
|
||||
evas_object_show(ly);
|
||||
|
||||
model = eo_add(EFL_MODEL_ITEM_CLASS, win);
|
||||
ck_assert(!!eina_value_setup(&v, EINA_VALUE_TYPE_STRING));
|
||||
ck_assert(!!eina_value_set(&v, text_value));
|
||||
efl_model_property_set(model, "text_property", &v, NULL);
|
||||
|
||||
efl_ui_model_connect(ly, "text", "text_property");
|
||||
efl_ui_view_model_set(ly, model);
|
||||
|
||||
ecore_main_loop_iterate_may_block(EINA_TRUE);
|
||||
|
||||
part_text = elm_layout_text_get(ly, "text");
|
||||
|
||||
ck_assert_str_eq(part_text, text_value);
|
||||
|
||||
elm_shutdown();
|
||||
}
|
||||
END_TEST
|
||||
|
||||
void elm_test_layout(TCase *tc)
|
||||
{
|
||||
tcase_add_test(tc, elm_atspi_role_get);
|
||||
tcase_add_test(tc, elm_layout_swallows);
|
||||
tcase_add_test(tc, elm_layout_edje_attach);
|
||||
tcase_add_test(tc, elm_layout_model_connect);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue