Merge branch 'master' into devs/hermet/lottie

This commit is contained in:
Hermet Park 2019-07-18 10:59:15 +09:00
commit 755f944f4d
65 changed files with 1106 additions and 328 deletions

View File

@ -181,6 +181,7 @@ void test_scroller4(void *data, Evas_Object *obj, void *event_info);
void test_scroller5(void *data, Evas_Object *obj, void *event_info);
void test_scroller6(void *data, Evas_Object *obj, void *event_info);
void test_scroller7(void *data, Evas_Object *obj, void *event_info);
void test_scroller_simple(void *data, Evas_Object *obj, void *event_info);
void test_efl_ui_scroller(void *data, Evas_Object *obj, void *event_info);
void test_efl_ui_scroller2(void *data, Evas_Object *obj, void *event_info);
void test_spinner(void *data, Evas_Object *obj, void *event_info);
@ -1093,7 +1094,9 @@ add_tests:
ADD_TEST(NULL, "Scroller", "Scroller on Popup", test_scroller5);
ADD_TEST(NULL, "Scroller", "Scroller 6", test_scroller6);
ADD_TEST(NULL, "Scroller", "Scroller 7", test_scroller7);
ADD_TEST(NULL, "Scroller", "Scroller Simple", test_scroller_simple);
ADD_TEST_EO(NULL, "Scroller", "Efl.Ui.Scroller", test_efl_ui_scroller);
ADD_TEST_EO(NULL, "Scroller", "Efl.Ui.Scroller Simple", test_efl_ui_scroller2);
//------------------------------//
// FIXME: add frame test

View File

@ -691,6 +691,64 @@ test_scroller2(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event
}
}
static void
_scroll_anim_start(void *data EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
{
int x, y;
elm_scroller_region_get(obj, &x, &y, NULL, NULL);
printf("scroll start: %p x: %d y: %d\n", obj, x, y);
}
static void
_scroll_anim_stop(void *data EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
{
int x, y;
elm_scroller_region_get(obj, &x, &y, NULL, NULL);
printf("scroll stop: %p x: %d y: %d\n", obj, x, y);
}
void
test_scroller_simple(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
{
Evas_Object *win, *bt, *bx, *sc;
int i;
win = elm_win_util_standard_add("scroller2", "Scroller Simple");
elm_win_autodel_set(win, EINA_TRUE);
bx = elm_box_add(win);
evas_object_size_hint_weight_set(bx, EVAS_HINT_EXPAND, 0);
evas_object_size_hint_align_set(bx, 0.5, 0);
/* { */
sc = elm_scroller_add(win);
evas_object_smart_callback_add(sc, "scroll,anim,start", _scroll_anim_start, NULL);
evas_object_smart_callback_add(sc, "scroll,anim,stop", _scroll_anim_stop, NULL);
evas_object_size_hint_weight_set(sc, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
evas_object_size_hint_align_set(sc, EVAS_HINT_FILL, EVAS_HINT_FILL);
elm_scroller_bounce_set(sc, EINA_TRUE, EINA_TRUE);
evas_object_show(sc);
evas_object_show(bx);
elm_object_content_set(sc, bx);
elm_win_resize_object_add(win, sc);
/* } */
for (i = 0; i < 2000; i++)
{
bt = elm_button_add(win);
elm_object_text_set(bt, "Vertical");
evas_object_smart_callback_add(bt, "clicked", _click_through, NULL);
evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0);
evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, 0.5);
elm_box_pack_end(bx, bt);
evas_object_show(bt);
}
evas_object_resize(win, 320, 400);
evas_object_show(win);
}
static Ecore_Timer *_timer = NULL;
static int _append = 0;
static int _count = 0;

View File

@ -129,3 +129,39 @@ test_efl_ui_scroller(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void
efl_pack(bx, efl_added));
}
}
void
test_efl_ui_scroller2(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
{
Eo *win, *sc, *bx;
int i;
win = efl_add_ref(EFL_UI_WIN_CLASS, NULL,
efl_ui_win_type_set(efl_added, EFL_UI_WIN_TYPE_BASIC),
efl_text_set(efl_added, "Efl Ui Scroller Simple"),
efl_ui_win_autodel_set(efl_added, EINA_TRUE));
efl_gfx_entity_size_set(win, EINA_SIZE2D(320, 400));
sc = efl_add(EFL_UI_SCROLLER_CLASS, win,
efl_gfx_hint_weight_set(efl_added, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND),
efl_event_callback_add(efl_added, EFL_UI_EVENT_SCROLL_START, _scroll_start_cb, NULL),
efl_event_callback_add(efl_added, EFL_UI_EVENT_SCROLL_STOP, _scroll_stop_cb, NULL),
efl_content_set(win, efl_added));
bx = efl_add(EFL_UI_BOX_CLASS, sc,
efl_ui_layout_orientation_set(efl_added, EFL_UI_LAYOUT_ORIENTATION_VERTICAL),
efl_gfx_hint_weight_set(efl_added, EVAS_HINT_EXPAND, 0),
efl_gfx_hint_align_set(efl_added, 0.5, 0),
efl_gfx_hint_fill_set(efl_added, EINA_TRUE, EINA_FALSE),
efl_content_set(sc, efl_added));
for (i = 0; i < 2000; i++)
{
efl_add(EFL_UI_BUTTON_CLASS, bx,
efl_text_set(efl_added, "Vertical"),
efl_gfx_hint_weight_set(efl_added, EVAS_HINT_EXPAND, 0.0),
efl_gfx_hint_fill_set(efl_added, EINA_TRUE, EINA_FALSE),
efl_event_callback_add(efl_added, EFL_UI_EVENT_CLICKED, _bt_clicked, NULL),
efl_pack(bx, efl_added));
}
}

View File

@ -4,17 +4,6 @@
#include <Efl_Ui.h>
#include <Elementary.h>
static double
_step_size_calculate(double min, double max)
{
double step = 0.0;
int steps = 0;
steps = max - min;
if (steps) step = (1.0 / steps);
return step;
}
static void
_slider_changed_cb(void *data EINA_UNUSED, const Efl_Event *ev)
{
@ -31,7 +20,6 @@ void
test_ui_slider(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
{
Eo *win, *bx, *hbx;
double step;
win = efl_add_ref(EFL_UI_WIN_CLASS, NULL,
efl_ui_win_type_set(efl_added, EFL_UI_WIN_TYPE_BASIC),
@ -67,11 +55,10 @@ test_ui_slider(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event
efl_text_interactive_editable_set(efl_added, EINA_FALSE),
efl_pack(bx, efl_added));
step = _step_size_calculate(0, 9);
efl_add(EFL_UI_SLIDER_CLASS, bx,
efl_gfx_hint_size_min_set(efl_added, EINA_SIZE2D(120, 0)),
efl_gfx_hint_align_set(efl_added, 0.5, 0.5),
efl_ui_range_step_set(efl_added, step),
efl_ui_range_step_set(efl_added, 0.1),
efl_pack(bx, efl_added));
efl_add(EFL_UI_TEXT_CLASS, bx,
@ -82,7 +69,7 @@ test_ui_slider(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event
efl_add(EFL_UI_SLIDER_CLASS, bx,
efl_gfx_hint_size_min_set(efl_added, EINA_SIZE2D(120, 0)),
efl_ui_range_limits_set(efl_added, 10, 145),
efl_ui_range_step_set(efl_added, step),
efl_ui_range_step_set(efl_added, 9),
elm_object_disabled_set(efl_added, EINA_TRUE),
efl_pack(bx, efl_added));
@ -98,7 +85,7 @@ test_ui_slider(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event
efl_add(EFL_UI_SLIDER_CLASS, hbx,
efl_gfx_hint_size_min_set(efl_added, EINA_SIZE2D(0, 160)),
efl_ui_range_limits_set(efl_added, 10, 145),
efl_ui_range_step_set(efl_added, step),
efl_ui_range_step_set(efl_added, 9),
efl_ui_range_value_set(efl_added, 70),
efl_ui_layout_orientation_set(efl_added, EFL_UI_LAYOUT_ORIENTATION_VERTICAL),
efl_pack(hbx, efl_added));
@ -106,7 +93,7 @@ test_ui_slider(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event
efl_add(EFL_UI_SLIDER_CLASS, hbx,
efl_gfx_hint_size_min_set(efl_added, EINA_SIZE2D(0, 160)),
efl_ui_range_limits_set(efl_added, 10, 145),
efl_ui_range_step_set(efl_added, step),
efl_ui_range_step_set(efl_added, 9),
efl_ui_layout_orientation_set(efl_added, EFL_UI_LAYOUT_ORIENTATION_VERTICAL),
elm_object_disabled_set(efl_added, EINA_TRUE),
efl_pack(hbx, efl_added));
@ -115,7 +102,7 @@ test_ui_slider(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event
efl_gfx_hint_size_min_set(efl_added, EINA_SIZE2D(0, 160)),
efl_ui_range_limits_set(efl_added, 10, 145),
efl_ui_range_value_set(efl_added, 35),
efl_ui_range_step_set(efl_added, step),
efl_ui_range_step_set(efl_added, 9),
efl_ui_layout_orientation_set(efl_added, EFL_UI_LAYOUT_ORIENTATION_VERTICAL | EFL_UI_LAYOUT_ORIENTATION_INVERTED),
efl_pack(hbx, efl_added));
@ -127,7 +114,7 @@ test_ui_slider(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event
efl_add(EFL_UI_SLIDER_CLASS, bx,
efl_gfx_hint_size_min_set(efl_added, EINA_SIZE2D(260, 0)),
efl_ui_range_limits_set(efl_added, 0, 150),
efl_ui_range_step_set(efl_added, step),
efl_ui_range_step_set(efl_added, 9),
efl_event_callback_add(efl_added, EFL_UI_SLIDER_EVENT_CHANGED, _slider_changed_cb, NULL),
efl_pack(bx, efl_added));
}

View File

@ -298,7 +298,7 @@ void _create_methods_specification_impl(Method const& method, Eldbus_Method2& el
// C++ always raises a warning for such conversions, so this warning
// can be disabled just here.
#pragma GCC diagnostic push
#ifndef __clang__
#if !defined(__clang__) && __GNUC__ >= 8
#pragma GCC diagnostic ignored "-Wcast-function-type"
#endif
Eldbus_Method_Cb method_cb =

View File

@ -162,7 +162,8 @@ ffi.cdef [[
EOLIAN_TYPE_BUILTIN_ANY_VALUE,
EOLIAN_TYPE_BUILTIN_ANY_VALUE_PTR,
EOLIAN_TYPE_BUILTIN_BINBUF,
EOLIAN_TYPE_BUILTIN_EVENT,
EOLIAN_TYPE_BUILTIN_MSTRING,
EOLIAN_TYPE_BUILTIN_STRING,
EOLIAN_TYPE_BUILTIN_STRINGSHARE,
@ -965,14 +966,15 @@ M.type_builtin_type = {
ANY_VALUE = 40,
ANY_VALUE_PTR = 41,
BINBUF = 42,
EVENT = 43,
MSTRING = 44,
STRING = 45,
STRINGSHARE = 46,
STRBUF = 47,
MSTRING = 42,
STRING = 43,
STRINGSHARE = 44,
STRBUF = 45,
VOID_PTR = 46,
FREE_CB = 47
VOID_PTR = 48,
FREE_CB = 49
}
M.typedecl_type = {

View File

@ -18,6 +18,7 @@ struct _Layout_Model_Data
{
Eo *fileview;
Eo *model;
Eo *provider;
Evas_Object *label;
Evas_Object *entry;
Evas_Object *img;
@ -55,10 +56,7 @@ _list_selected_cb(void *data EINA_UNUSED, const Efl_Event *event)
Eo *child = event->info;
printf("LIST selected model\n");
efl_ui_view_model_set(priv->label, child);
efl_ui_view_model_set(priv->entry, child);
efl_ui_view_model_set(priv->img, child);
efl_ui_view_model_set(priv->bt, child);
efl_ui_view_model_set(priv->provider, child);
}
static void
@ -140,13 +138,16 @@ elm_main(int argc EINA_UNUSED, char **argv EINA_UNUSED)
_widget_init(bxr);
elm_object_part_content_set(panes, "right", bxr);
priv->provider = efl_add(EFL_MODEL_PROVIDER_CLASS, win);
efl_provider_register(bxr, EFL_MODEL_PROVIDER_CLASS, priv->provider);
/*Label widget */
_label_init(win, bxr, "FILENAME:");
priv->label = _label_init(win, bxr, "");
efl_ui_property_bind(priv->label, "default", "path"); //connect "default" to "filename" property
/* Entry widget */
priv->entry = elm_entry_add(win);
priv->entry = elm_entry_add(bxr);
efl_ui_property_bind(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);
@ -155,7 +156,7 @@ elm_main(int argc EINA_UNUSED, char **argv EINA_UNUSED)
evas_object_show(priv->entry);
/* Button widget */
priv->bt = elm_button_add(win);
priv->bt = elm_button_add(bxr);
elm_box_pack_end(bxr, priv->bt);
elm_object_text_set(priv->bt, "update model");
evas_object_smart_callback_add(priv->bt, "clicked", _update_cb, priv);
@ -164,11 +165,11 @@ elm_main(int argc EINA_UNUSED, char **argv EINA_UNUSED)
evas_object_show(priv->bt);
/* Image widget */
img_factory = efl_add(EFL_UI_IMAGE_FACTORY_CLASS, win);
img_factory = efl_add(EFL_UI_IMAGE_FACTORY_CLASS, bxr);
efl_ui_property_bind(img_factory, "", "path"); //connect to "path" property
efl_ui_factory_bind(priv->bt, "icon", img_factory);
efl_future_then(win, efl_ui_factory_create(img_factory, NULL, win),
efl_future_then(win, efl_ui_factory_create(img_factory, NULL, bxr),
.success = _wait_for_image,
.data = priv);

View File

@ -42,6 +42,13 @@
#include "efl_app.eo.h"
#include "efl_appthread.eo.h"
/* To be deprecated at some point */
/** Please use efl_provider_register instead. */
EAPI Eina_Bool efl_loop_register(Efl_Loop *obj, const Efl_Class *klass, const Efl_Object *provider);
/** Please use efl_provider_unregister instead. */
EAPI Eina_Bool efl_loop_unregister(Efl_Loop *obj, const Efl_Class *klass, const Efl_Object *provider);
/**
* @brief Quits the main loop once all the events currently on the queue have
* been processed.

View File

@ -233,7 +233,7 @@ _ecore_event_init(void)
if ((!choice) || (!choice[0])) choice = "chained_mempool";
_event_msg_handler = efl_add(ECORE_EVENT_MESSAGE_HANDLER_CLASS, _mainloop_singleton);
efl_loop_register(_mainloop_singleton, ECORE_EVENT_MESSAGE_HANDLER_CLASS, _event_msg_handler);
efl_provider_register(_mainloop_singleton, ECORE_EVENT_MESSAGE_HANDLER_CLASS, _event_msg_handler);
if (!_event_msg_handler)
{

View File

@ -116,7 +116,6 @@ struct _Efl_Loop_Future_Scheduler
struct _Efl_Loop_Data
{
double loop_time;
Eina_Hash *providers;
Efl_Loop_Future_Scheduler future_scheduler;

View File

@ -87,19 +87,6 @@ efl_exit(int exit_code)
efl_loop_quit(efl_main_loop_get(), v);
}
EOLIAN static Efl_Object *
_efl_loop_efl_object_provider_find(const Eo *obj, Efl_Loop_Data *pd, const Efl_Object *klass)
{
Efl_Object *r;
if (klass == EFL_LOOP_CLASS) return (Efl_Object *) obj;
r = eina_hash_find(pd->providers, &klass);
if (r) return r;
return efl_provider_find(efl_super(obj, EFL_LOOP_CLASS), klass);
}
EAPI int
efl_loop_exit_code_process(Eina_Value *value)
{
@ -286,11 +273,10 @@ _efl_loop_efl_object_constructor(Eo *obj, Efl_Loop_Data *pd)
efl_event_callback_array_add(obj, event_catcher_watch(), pd);
pd->loop_time = ecore_time_get();
pd->providers = eina_hash_pointer_new(EINA_FREE_CB(efl_unref));
pd->epoll_fd = -1;
pd->timer_fd = -1;
pd->future_message_handler = efl_add(EFL_LOOP_MESSAGE_FUTURE_HANDLER_CLASS, obj);
efl_loop_register(obj, EFL_LOOP_MESSAGE_FUTURE_HANDLER_CLASS, pd->future_message_handler);
efl_provider_register(obj, EFL_LOOP_MESSAGE_FUTURE_HANDLER_CLASS, pd->future_message_handler);
return obj;
}
@ -302,10 +288,6 @@ _efl_loop_efl_object_invalidate(Eo *obj, Efl_Loop_Data *pd)
_ecore_main_content_clear(obj, pd);
// Even if we are just refcounting provider, efl_provider_find won't reach them after invalidate
eina_hash_free(pd->providers);
pd->providers = NULL;
pd->poll_low = NULL;
pd->poll_medium = NULL;
pd->poll_high = NULL;
@ -517,22 +499,23 @@ timer_error:
}
static Eina_Bool
_efl_loop_register(Eo *obj EINA_UNUSED, Efl_Loop_Data *pd, const Efl_Class *klass, const Efl_Object *provider)
_efl_loop_register(Eo *obj, Efl_Loop_Data *pd EINA_UNUSED,
const Efl_Class *klass, const Efl_Object *provider)
{
// The passed object does not provide that said class.
if (!efl_isa(provider, klass)) return EINA_FALSE;
// Note: I would prefer to use efl_xref here, but I can't figure a nice way to
// call efl_xunref on hash destruction.
return eina_hash_add(pd->providers, &klass, efl_ref(provider));
return efl_provider_register(obj, klass, provider);
}
EFL_FUNC_BODYV(efl_loop_register, Eina_Bool, EINA_FALSE, EFL_FUNC_CALL(klass, provider), const Efl_Class *klass, const Efl_Object *provider);
static Eina_Bool
_efl_loop_unregister(Eo *obj EINA_UNUSED, Efl_Loop_Data *pd, const Efl_Class *klass, const Efl_Object *provider)
_efl_loop_unregister(Eo *obj, Efl_Loop_Data *pd EINA_UNUSED,
const Efl_Class *klass, const Efl_Object *provider)
{
return eina_hash_del(pd->providers, &klass, provider);
return efl_provider_unregister(obj, klass, provider);
}
EFL_FUNC_BODYV(efl_loop_unregister, Eina_Bool, EINA_FALSE, EFL_FUNC_CALL(klass, provider), const Efl_Class *klass, const Efl_Object *provider);
void
_efl_loop_messages_filter(Eo *obj EINA_UNUSED, Efl_Loop_Data *pd, void *handler_pd)
{
@ -693,7 +676,9 @@ efl_loop_future_scheduler_get(const Eo *obj)
return NULL;
}
#define EFL_LOOP_EXTRA_OPS \
EFL_OBJECT_OP_FUNC(efl_loop_message_process, _efl_loop_message_process)
#define EFL_LOOP_EXTRA_OPS \
EFL_OBJECT_OP_FUNC(efl_loop_message_process, _efl_loop_message_process), \
EFL_OBJECT_OP_FUNC(efl_loop_register, _efl_loop_register), \
EFL_OBJECT_OP_FUNC(efl_loop_unregister, _efl_loop_unregister)
#include "efl_loop.eo.c"

View File

@ -102,22 +102,6 @@ abstract Efl.Loop extends Efl.Task
}
return: future<void> @owned; [[The future handle.]]
}
register {
[[Will register a manager of a specific class to be answered by eo.provider_find.]]
params {
@in klass: const(Efl.Class); [[The class provided by the registered provider.]]
@in provider: const(Efl.Object); [[The provider for the newly registered class that has to provide that said Efl.Class.]]
}
return: bool; [[$true if successfully register, $false otherwise.]]
}
unregister {
[[Will unregister a manager of a specific class that was previously registered and answered by eo.provider_find.]]
params {
@in klass: const(Efl.Class); [[The class provided by the provider to unregister for.]]
@in provider: const(Efl.Object); [[The provider for the registered class to unregister.]]
}
return: bool; [[$true if successfully unregistered, $false otherwise.]]
}
}
events {
idle,enter @restart: void; [[Event occurs once the main loop enters the idle state.]]
@ -133,7 +117,6 @@ abstract Efl.Loop extends Efl.Task
Efl.Object.constructor;
Efl.Object.invalidate;
Efl.Object.destructor;
Efl.Object.provider_find;
Efl.Task.run;
Efl.Task.end;
}

View File

@ -84,9 +84,9 @@ edje_init(void)
_edje_scale = FROM_DOUBLE(1.0);
_edje_global_obj = efl_add(EDJE_GLOBAL_CLASS, efl_main_loop_get());
EINA_SAFETY_ON_TRUE_GOTO(!_edje_global_obj, shutdown_efreet);
EINA_SAFETY_ON_TRUE_GOTO(!efl_loop_register(efl_main_loop_get(), EFL_GFX_COLOR_CLASS_MIXIN, _edje_global_obj), shutdown_efreet);
EINA_SAFETY_ON_TRUE_GOTO(!efl_loop_register(efl_main_loop_get(), EFL_GFX_TEXT_CLASS_INTERFACE, _edje_global_obj), shutdown_efreet);
EINA_SAFETY_ON_TRUE_GOTO(!efl_loop_register(efl_main_loop_get(), EFL_GFX_SIZE_CLASS_INTERFACE, _edje_global_obj), shutdown_efreet);
EINA_SAFETY_ON_TRUE_GOTO(!efl_provider_register(efl_main_loop_get(), EFL_GFX_COLOR_CLASS_MIXIN, _edje_global_obj), shutdown_efreet);
EINA_SAFETY_ON_TRUE_GOTO(!efl_provider_register(efl_main_loop_get(), EFL_GFX_TEXT_CLASS_INTERFACE, _edje_global_obj), shutdown_efreet);
EINA_SAFETY_ON_TRUE_GOTO(!efl_provider_register(efl_main_loop_get(), EFL_GFX_SIZE_CLASS_INTERFACE, _edje_global_obj), shutdown_efreet);
_edje_edd_init();
_edje_text_init();
@ -154,9 +154,9 @@ shutdown_all:
_edje_edd_shutdown();
if (_edje_global_obj)
{
efl_loop_unregister(efl_main_loop_get(), EFL_GFX_COLOR_CLASS_MIXIN, _edje_global_obj);
efl_loop_unregister(efl_main_loop_get(), EFL_GFX_TEXT_CLASS_INTERFACE, _edje_global_obj);
efl_loop_unregister(efl_main_loop_get(), EFL_GFX_SIZE_CLASS_INTERFACE, _edje_global_obj);
efl_provider_unregister(efl_main_loop_get(), EFL_GFX_COLOR_CLASS_MIXIN, _edje_global_obj);
efl_provider_unregister(efl_main_loop_get(), EFL_GFX_TEXT_CLASS_INTERFACE, _edje_global_obj);
efl_provider_unregister(efl_main_loop_get(), EFL_GFX_SIZE_CLASS_INTERFACE, _edje_global_obj);
efl_del(_edje_global_obj);
_edje_global_obj = NULL;
}
@ -213,9 +213,9 @@ _edje_shutdown_core(void)
_edje_text_class_hash_free();
_edje_size_class_hash_free();
_edje_edd_shutdown();
efl_loop_unregister(efl_main_loop_get(), EFL_GFX_COLOR_CLASS_MIXIN, _edje_global_obj);
efl_loop_unregister(efl_main_loop_get(), EFL_GFX_TEXT_CLASS_INTERFACE, _edje_global_obj);
efl_loop_unregister(efl_main_loop_get(), EFL_GFX_SIZE_CLASS_INTERFACE, _edje_global_obj);
efl_provider_unregister(efl_main_loop_get(), EFL_GFX_COLOR_CLASS_MIXIN, _edje_global_obj);
efl_provider_unregister(efl_main_loop_get(), EFL_GFX_TEXT_CLASS_INTERFACE, _edje_global_obj);
efl_provider_unregister(efl_main_loop_get(), EFL_GFX_SIZE_CLASS_INTERFACE, _edje_global_obj);
efl_del(_edje_global_obj);
_edje_global_obj = NULL;

View File

@ -147,6 +147,7 @@ typedef Efl_Gfx_Path_Command_Type Efl_Gfx_Path_Command;
#include "interfaces/efl_ui_property_bind.eo.h"
#include "interfaces/efl_ui_factory.eo.h"
#include "interfaces/efl_ui_factory_bind.eo.h"
#include "interfaces/efl_model_provider.eo.h"
#include "interfaces/efl_cached_item.eo.h"
/* Observable interface */

View File

@ -0,0 +1,36 @@
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include "Efl.h"
typedef struct _Efl_Model_Provider_Data Efl_Model_Provider_Data;
struct _Efl_Model_Provider_Data
{
Efl_Model *model;
};
static void
_efl_model_provider_efl_ui_view_model_set(Eo *obj, Efl_Model_Provider_Data *pd,
Efl_Model *model)
{
Efl_Model_Changed_Event ev;
ev.previous = efl_ref(pd->model);
ev.current = efl_ref(model);
efl_replace(&pd->model, model);
efl_event_callback_call(obj, EFL_UI_VIEW_EVENT_MODEL_CHANGED, &ev);
efl_unref(ev.previous);
efl_unref(ev.current);
}
static Efl_Model *
_efl_model_provider_efl_ui_view_model_get(const Eo *obj EINA_UNUSED,
Efl_Model_Provider_Data *pd)
{
return pd->model;
}
#include "efl_model_provider.eo.c"

View File

@ -0,0 +1,12 @@
class @beta Efl.Model_Provider extends Efl.Object implements Efl.Ui.View
{
[[EFL object that provide a model to all.
You can use this when you would otherwise have to call @Efl.Ui.View.model.set
on multiple widgets by registering this object using @Efl.Object.provider_register
on a parent that they all depends on.
]]
implements {
Efl.Ui.View.model { get; set; }
}
}

View File

@ -1,3 +1,9 @@
struct @beta Efl.Model_Changed_Event {
[[Every time the model is changed on the object.]]
current: Efl.Model; [[The newly set model.]]
previous: Efl.Model; [[The previously set model.]]
}
interface @beta Efl.Ui.View
{
[[Efl UI view interface]]
@ -10,4 +16,7 @@ interface @beta Efl.Ui.View
}
}
}
events {
model,changed: Efl.Model_Changed_Event; [[Event dispatched when a new model is set.]]
}
}

View File

@ -63,6 +63,7 @@ pub_eo_files = [
'efl_gfx_blur.eo',
'efl_gfx_hint.eo',
'efl_model.eo',
'efl_model_provider.eo',
'efl_interpolator.eo',
'efl_gfx_image_orientable.eo',
'efl_container.eo',
@ -167,6 +168,7 @@ efl_src += files([
'efl_file.c',
'efl_ui_layout_orientable_readonly.c',
'efl_text_markup_util.c',
'efl_model_provider.c',
])
#efl_header_src += files([

View File

@ -54,7 +54,7 @@ static Eina_Hash *_eina_value_inner_mps = NULL;
static Eina_Lock _eina_value_inner_mps_lock;
static char *_eina_value_mp_choice = NULL;
static int _eina_value_log_dom = -1;
static const Eina_Value _eina_value_empty = EINA_VALUE_EMPTY;
static Eina_Value _eina_value_empty;
#ifdef ERR
#undef ERR
@ -5400,6 +5400,7 @@ eina_value_inner_free(size_t size, void *mem)
Eina_Bool
eina_value_init(void)
{
const Eina_Value empty = EINA_VALUE_EMPTY;
const char *choice, *tmp;
_eina_value_log_dom = eina_log_domain_register("eina_value",
@ -5486,6 +5487,8 @@ eina_value_init(void)
EINA_ERROR_VALUE_FAILED = eina_error_msg_static_register("Eina_Value failed to copy/convert.");
memcpy(&_eina_value_empty, &empty, sizeof (empty));
return EINA_TRUE;
on_init_fail_hash:

View File

@ -320,7 +320,7 @@ eio_init(void)
efreet_mime_init();
io_manager = efl_add(EFL_IO_MANAGER_CLASS, efl_main_loop_get());
efl_loop_register(efl_main_loop_get(), EFL_IO_MANAGER_CLASS, io_manager);
efl_provider_register(efl_main_loop_get(), EFL_IO_MANAGER_CLASS, io_manager);
eina_log_timing(_eio_log_dom_global,
EINA_LOG_STATE_STOP,
@ -358,7 +358,7 @@ eio_shutdown(void)
EINA_LOG_STATE_START,
EINA_LOG_STATE_SHUTDOWN);
efl_loop_unregister(efl_main_loop_get(), EFL_IO_MANAGER_CLASS, io_manager);
efl_provider_unregister(efl_main_loop_get(), EFL_IO_MANAGER_CLASS, io_manager);
efl_del(io_manager);
io_manager = NULL;

View File

@ -138,7 +138,7 @@ EOLIAN static void
_efl_ui_box_efl_gfx_entity_size_set(Eo *obj, Efl_Ui_Box_Data *_pd EINA_UNUSED, Eina_Size2D sz)
{
efl_gfx_entity_size_set(efl_super(obj, MY_CLASS), sz);
efl_canvas_group_change(obj);
efl_pack_layout_request(obj);
}
EOLIAN static void
@ -186,6 +186,7 @@ _efl_ui_box_efl_object_constructor(Eo *obj, Efl_Ui_Box_Data *pd)
pd->dir = EFL_UI_LAYOUT_ORIENTATION_VERTICAL;
pd->align.h = 0.5;
pd->align.v = 0.5;
pd->full_recalc = EINA_TRUE;
return obj;
}
@ -360,8 +361,9 @@ _efl_ui_box_efl_pack_linear_pack_index_get(Eo *obj EINA_UNUSED, Efl_Ui_Box_Data
}
EOLIAN static void
_efl_ui_box_efl_pack_layout_layout_request(Eo *obj, Efl_Ui_Box_Data *pd EINA_UNUSED)
_efl_ui_box_efl_pack_layout_layout_request(Eo *obj, Efl_Ui_Box_Data *pd)
{
pd->full_recalc = EINA_TRUE;
efl_canvas_group_need_recalculate_set(obj, EINA_TRUE);
}

View File

@ -27,6 +27,28 @@ _weight_sort_cb(const void *l1, const void *l2)
return it2->weight_factor <= it1->weight_factor ? -1 : 1;
}
/* this function performs a simplified layout when the box has changed position
* but no other changes have occurred, e.g., when a box is being scrolled
*/
static void
_efl_ui_box_layout_simple(Efl_Ui_Box *ui_box, Efl_Ui_Box_Data *pd)
{
Eo *child;
Eina_List *l;
Eina_Position2D pos = efl_gfx_entity_position_get(ui_box);
EINA_LIST_FOREACH(pd->children, l, child)
{
Eina_Position2D child_pos = efl_gfx_entity_position_get(child);
efl_gfx_entity_position_set(child,
EINA_POSITION2D(pos.x - pd->last_pos.x + child_pos.x,
pos.y - pd->last_pos.y + child_pos.y));
}
pd->last_pos = pos;
efl_event_callback_call(ui_box, EFL_PACK_EVENT_LAYOUT_UPDATED, NULL);
}
void
_efl_ui_box_custom_layout(Efl_Ui_Box *ui_box, Efl_Ui_Box_Data *pd)
{
@ -49,10 +71,25 @@ _efl_ui_box_custom_layout(Efl_Ui_Box *ui_box, Efl_Ui_Box_Data *pd)
efl_gfx_hint_size_restricted_min_set(ui_box, EINA_SIZE2D(0, 0));
return;
}
if (!pd->full_recalc)
{
_efl_ui_box_layout_simple(ui_box, pd);
return;
}
_efl_ui_container_layout_init(ui_box, box_calc);
pd->last_pos.x = box_calc[0].pos - box_calc[0].margin[0];
pd->last_pos.y = box_calc[1].pos - box_calc[1].margin[0];
items = alloca(count * sizeof(*items));
/* Item_Calc struct is currently 152 bytes.
* this is pretty big to be allocating a huge number of, and we don't want to explode the stack
*/
if (count >= 500)
{
items = malloc(count * sizeof(*items));
EINA_SAFETY_ON_NULL_RETURN(items);
}
else
items = alloca(count * sizeof(*items));
#ifdef DEBUG
memset(items, 0, count * sizeof(*items));
#endif
@ -198,7 +235,9 @@ _efl_ui_box_custom_layout(Efl_Ui_Box *ui_box, Efl_Ui_Box_Data *pd)
want[1] += (box_calc[1].margin[0] + box_calc[1].margin[1]) +
(box_calc[1].pad * (count - 1));
pd->full_recalc = EINA_FALSE;
efl_gfx_hint_size_restricted_min_set(ui_box, EINA_SIZE2D(want[0], want[1]));
efl_event_callback_call(ui_box, EFL_PACK_EVENT_LAYOUT_UPDATED, NULL);
if (count >= 500) free(items);
}

View File

@ -27,7 +27,10 @@ struct _Efl_Ui_Box_Data
double h, v;
} align;
Eina_Position2D last_pos;
Eina_Bool homogeneous : 1;
Eina_Bool full_recalc : 1; //whether to force full recalc
};
#endif

View File

@ -1,23 +1,36 @@
class @beta Efl.Ui.Clickable_Util {
[[Helper class that connects theme signals or object events to the @Efl.Ui.Clickable interface.
This simplifies creating widgets that implement the @Efl.Ui.Clickable interface.
]]
methods {
bind_to_theme @class {
[[This will listen to the standard events of a theme, and emit the events on clickable
[[This will listen to the standard "click" events on a theme and emit the appropriate
events through the @Efl.Ui.Clickable interface.
This means, widgets themselfs do not neccessarily need to listen to the theme signals. This function does this, and calls the correct clickable functions.
Using these methods widgets do not need to listen to the theme signals. This class
does it and calls the correct clickable functions.
This handles theme signals "efl,action,press", "efl,action,unpress" and "efl,action,mouse_out",
and the @[Efl.Input.Interface.pointer,move] event.
]]
params {
object : Efl.Canvas.Layout; [[The object to listen on]]
clickable : Efl.Ui.Clickable; [[The object to call the clickable events on]]
object : Efl.Canvas.Layout; [[The object to listen on.]]
clickable : Efl.Ui.Clickable; [[The object to call the clickable methods on.]]
}
}
bind_to_object @class {
[[This will listen to the standard events on a object, and call the correct methods on clickable
[[This will listen to the standard "click" events on an object, and emit the appropriate
events through the @Efl.Ui.Clickable interface.
This means, widgets themselfs do not neccessarily need to listen to the events on the object. This function does this, and calls the correct clickable functions.
Using these methods widgets do not need to listen to the object events. This class
does it and calls the correct clickable functions.
The handled events are @[Efl.Input.Interface.pointer,up] and @[Efl.Input.Interface.pointer,down].
]]
params {
object : Efl.Input.Interface; [[The object to listen on]]
clickable : Efl.Ui.Clickable; [[The object to call the clickable events on]]
object : Efl.Input.Interface; [[The object to listen on.]]
clickable : Efl.Ui.Clickable; [[The object to call the clickable methods on.]]
}
}
}

View File

@ -53,6 +53,7 @@ void _efl_ui_image_sizing_eval(Evas_Object *obj);
static void _efl_ui_image_model_properties_changed_cb(void *data, const Efl_Event *event);
static void _on_size_hints_changed(void *data, const Efl_Event *e);
static Eina_Bool _efl_ui_image_download(Eo *obj, Efl_Ui_Image_Data *sd, const char *url);
static void _update_viewmodel(Eo *obj, Efl_Ui_Image_Data *pd);
static const Elm_Action key_actions[] = {
{"activate", _key_action_activate},
@ -848,6 +849,21 @@ _on_size_hints_changed(void *data EINA_UNUSED, const Efl_Event *ev)
_efl_ui_image_sizing_eval(ev->object);
}
static void
_efl_ui_image_model_changed(void *data, const Efl_Event *event)
{
Efl_Model_Changed_Event *ev = event->info;
if (ev->previous)
efl_event_callback_del(ev->previous, EFL_MODEL_EVENT_PROPERTIES_CHANGED,
_efl_ui_image_model_properties_changed_cb, event->object);
if (ev->current)
efl_event_callback_add(ev->current, EFL_MODEL_EVENT_PROPERTIES_CHANGED,
_efl_ui_image_model_properties_changed_cb, event->object);
_update_viewmodel(event->object, data);
}
EOLIAN static Eo *
_efl_ui_image_efl_object_constructor(Eo *obj, Efl_Ui_Image_Data *pd)
{
@ -861,6 +877,22 @@ _efl_ui_image_efl_object_constructor(Eo *obj, Efl_Ui_Image_Data *pd)
return obj;
}
EOLIAN static void
_efl_ui_image_efl_object_invalidate(Eo *obj, Efl_Ui_Image_Data *pd EINA_UNUSED)
{
Efl_Model *model;
if (pd->property_watch)
efl_event_callback_del(obj, EFL_UI_VIEW_EVENT_MODEL_CHANGED,
_efl_ui_image_model_changed, pd);
model = efl_ui_view_model_get(obj);
if (model)
efl_event_callback_del(model, EFL_MODEL_EVENT_PROPERTIES_CHANGED,
_efl_ui_image_model_properties_changed_cb, obj);
efl_invalidate(efl_super(obj, EFL_UI_IMAGE_CLASS));
}
static const Eina_Slice remote_uri[] = {
EINA_SLICE_STR_LITERAL("http://"),
EINA_SLICE_STR_LITERAL("https://"),
@ -1829,6 +1861,15 @@ _update_viewmodel(Eo *obj, Efl_Ui_Image_Data *pd)
char *key = NULL;
Efl_Model *model;
if (!pd->property.file) return ;
if (!pd->property_watch)
{
efl_event_callback_add(obj, EFL_UI_VIEW_EVENT_MODEL_CHANGED,
_efl_ui_image_model_changed, pd);
pd->property_watch = EINA_TRUE;
}
model = efl_ui_view_model_get(obj);
if (!model) return ;
@ -1903,35 +1944,14 @@ _efl_ui_image_model_properties_changed_cb(void *data, const Efl_Event *event)
if (refresh) _update_viewmodel(obj, pd);
}
EOLIAN static void
_efl_ui_image_efl_ui_view_model_set(Eo *obj, Efl_Ui_Image_Data *pd, Efl_Model *model)
{
Efl_Model *setted;
setted = efl_ui_view_model_get(obj);
if (setted)
{
efl_event_callback_del(setted, EFL_MODEL_EVENT_PROPERTIES_CHANGED,
_efl_ui_image_model_properties_changed_cb, obj);
}
efl_ui_view_model_set(efl_super(obj, EFL_UI_IMAGE_CLASS), model);
setted = efl_ui_view_model_get(obj);
if (setted)
{
efl_event_callback_add(setted, EFL_MODEL_EVENT_PROPERTIES_CHANGED,
_efl_ui_image_model_properties_changed_cb, obj);
}
_update_viewmodel(obj, pd);
}
EOLIAN static Eina_Error
_efl_ui_image_efl_ui_property_bind_property_bind(Eo *obj, Efl_Ui_Image_Data *pd, const char *key, const char *property)
{
Eina_Stringshare *sk;
if (efl_ui_property_bind(efl_super(obj, EFL_UI_IMAGE_CLASS), key, property) == 0)
return 0;
if (strcmp(key, "filename") == 0)
{
pd->property.icon = EINA_FALSE;
@ -1949,7 +1969,7 @@ _efl_ui_image_efl_ui_property_bind_property_bind(Eo *obj, Efl_Ui_Image_Data *pd,
}
else
{
return efl_ui_property_bind(efl_super(obj, EFL_UI_IMAGE_CLASS), key, property);
return EFL_PROPERTY_ERROR_INVALID_KEY;
}
_update_viewmodel(obj, pd);

View File

@ -89,6 +89,7 @@ class @beta Efl.Ui.Image extends Efl.Ui.Widget implements Efl.Ui.Clickable, Efl.
}
implements {
Efl.Object.constructor;
Efl.Object.invalidate;
Efl.File.load;
Efl.File.unload;
Efl.Gfx.Color.color { set; }
@ -118,7 +119,6 @@ class @beta Efl.Ui.Image extends Efl.Ui.Widget implements Efl.Ui.Clickable, Efl.
Efl.Canvas.Group.group_member_add;
Efl.Ui.Draggable.drag_target { get; set; }
Efl.Ui.Property_Bind.property_bind;
Efl.Ui.View.model { set; }
Efl.Ui.Widget.theme_apply;
Efl.Ui.Widget.widget_input_event_handler;
Efl.Access.Component.extents { get; }

View File

@ -2225,24 +2225,34 @@ _efl_ui_layout_connect_hash(Efl_Ui_Layout_Data *pd)
pd->connect.factories = eina_hash_stringshared_new(EINA_FREE_CB(_efl_ui_layout_factory_free)); // Hash of property triggering a content creation
}
EOLIAN static void
_efl_ui_layout_base_efl_ui_view_model_set(Eo *obj, Efl_Ui_Layout_Data *pd, Efl_Model *model)
static void
_efl_ui_layout_base_model_unregister(Eo *obj EINA_UNUSED, Efl_Ui_Layout_Data *pd,
Efl_Model *model)
{
if (!model) return ;
if (!pd->model_bound) return ;
efl_event_callback_del(model, EFL_MODEL_EVENT_PROPERTIES_CHANGED,
_efl_model_properties_changed_cb, pd);
pd->model_bound = EINA_FALSE;
}
static void
_efl_ui_layout_base_model_register(Eo *obj, Efl_Ui_Layout_Data *pd,
Efl_Model *model)
{
Eina_Stringshare *key;
Eina_Hash_Tuple *tuple;
Eina_Iterator *it;
Efl_Model *setted;
setted = efl_ui_view_model_get(obj);
if (setted)
efl_event_callback_del(setted, EFL_MODEL_EVENT_PROPERTIES_CHANGED,
_efl_model_properties_changed_cb, pd);
if (!model) return ;
if (pd->model_bound) return;
pd->model_bound = EINA_TRUE;
efl_ui_view_model_set(efl_super(obj, EFL_UI_LAYOUT_BASE_CLASS), model);
if (model)
efl_event_callback_add(model, EFL_MODEL_EVENT_PROPERTIES_CHANGED,
_efl_model_properties_changed_cb, pd);
efl_event_callback_add(model, EFL_MODEL_EVENT_PROPERTIES_CHANGED,
_efl_model_properties_changed_cb, pd);
_efl_ui_layout_connect_hash(pd);
@ -2279,6 +2289,31 @@ _efl_ui_layout_base_efl_ui_view_model_set(Eo *obj, Efl_Ui_Layout_Data *pd, Efl_M
_efl_ui_layout_view_model_update(pd);
}
static void
_efl_ui_layout_base_model_update(void *data, const Efl_Event *event)
{
Efl_Ui_Layout_Data *pd = data;
Efl_Model_Changed_Event *ev = event->info;
_efl_ui_layout_base_model_unregister(event->object, pd, ev->previous);
_efl_ui_layout_base_model_register(event->object, pd, ev->current);
}
static void
_efl_ui_layout_base_model_watch(Eo *obj, Efl_Ui_Layout_Data *pd)
{
Efl_Model *model;
if (pd->model_watch) return ;
pd->model_watch = EINA_TRUE;
efl_event_callback_add(obj, EFL_UI_VIEW_EVENT_MODEL_CHANGED,
_efl_ui_layout_base_model_update, pd);
model = efl_ui_view_model_get(obj);
if (!model) return ;
_efl_ui_layout_base_model_register(obj, pd, model);
}
EOLIAN static Eina_Error
_efl_ui_layout_base_efl_ui_property_bind_property_bind(Eo *obj, Efl_Ui_Layout_Data *pd, const char *key, const char *property)
{
@ -2298,6 +2333,9 @@ _efl_ui_layout_base_efl_ui_property_bind_property_bind(Eo *obj, Efl_Ui_Layout_Da
if (!_elm_layout_part_aliasing_eval(obj, &key, EINA_TRUE))
return EFL_PROPERTY_ERROR_INVALID_KEY;
// Check if there is a model and register it
_efl_ui_layout_base_model_watch(obj, pd);
_efl_ui_layout_connect_hash(pd);
sprop = eina_stringshare_add(property);
@ -2354,6 +2392,9 @@ _efl_ui_layout_base_efl_ui_factory_bind_factory_bind(Eo *obj EINA_UNUSED, Efl_Ui
if (!_elm_layout_part_aliasing_eval(obj, &key, EINA_TRUE))
return;
// Check if there is a model and register it
_efl_ui_layout_base_model_watch(obj, pd);
if (!pd->connect.factories)
pd->connect.factories = eina_hash_stringshared_new(EINA_FREE_CB(_efl_ui_layout_factory_free));
@ -2421,6 +2462,27 @@ _efl_ui_layout_base_efl_object_finalize(Eo *obj, Efl_Ui_Layout_Data *pd EINA_UNU
return eo;
}
static void
_efl_ui_layout_base_efl_object_invalidate(Eo *obj, Efl_Ui_Layout_Data *pd)
{
if (pd->model_watch)
{
Efl_Model *model;
pd->model_watch = EINA_FALSE;
efl_event_callback_del(obj, EFL_UI_VIEW_EVENT_MODEL_CHANGED,
_efl_ui_layout_base_model_update, pd);
model = efl_ui_view_model_get(obj);
if (!model)
{
_efl_ui_layout_base_model_unregister(obj, pd, model);
}
}
efl_invalidate(efl_super(obj, EFL_UI_LAYOUT_BASE_CLASS));
}
EOLIAN static void
_efl_ui_layout_base_efl_layout_signal_message_send(Eo *obj, Efl_Ui_Layout_Data *pd EINA_UNUSED, int id, const Eina_Value msg)
{

View File

@ -60,6 +60,7 @@ abstract Efl.Ui.Layout_Base extends Efl.Ui.Widget implements Efl.Container,
class.constructor;
Efl.Object.constructor;
Efl.Object.finalize;
Efl.Object.invalidate;
Efl.Canvas.Group.group_calculate;
Efl.Layout.Calc.calc_freeze;
Efl.Layout.Calc.calc_thaw;
@ -86,7 +87,6 @@ abstract Efl.Ui.Layout_Base extends Efl.Ui.Widget implements Efl.Container,
Efl.Part.part_get;
Efl.Ui.Property_Bind.property_bind;
Efl.Ui.Factory_Bind.factory_bind;
Efl.Ui.View.model { set; }
}
events {
theme,changed: void; [[Called when theme changed]]

View File

@ -1555,10 +1555,11 @@ _scroll_manager_scrollto_y_animator_del(Efl_Ui_Scroll_Manager_Data *sd)
static void
_scroll_manager_scrollto_animator_add(Efl_Ui_Scroll_Manager_Data *sd, Evas_Coord sx, Evas_Coord sy, Evas_Coord x, Evas_Coord y, double tx, double ty, InterpType interp)
{
_scroll_manager_scrollto_animator_del(sd);
if (!sd->pan_obj) return;
if (sd->freeze) return;
if (!sd->pan_obj || sd->freeze)
{
_scroll_manager_scrollto_animator_del(sd);
return;
}
_scroll_manager_scrollto_x_animator_add(sd, sx, x, tx, interp);
_scroll_manager_scrollto_y_animator_add(sd, sy, y, ty, interp);
}

View File

@ -205,6 +205,7 @@ _drag_up(void *data,
const char *source EINA_UNUSED)
{
double step;
double relative_step;
EFL_UI_SLIDER_DATA_GET(data, sd);
step = sd->step;
@ -212,12 +213,14 @@ _drag_up(void *data,
if (efl_ui_layout_orientation_is_inverted(sd->dir)) step *= -1.0;
ELM_WIDGET_DATA_GET_OR_RETURN(data, wd);
relative_step = step/(sd->val_max - sd->val_min);
if (elm_widget_is_legacy(obj))
efl_ui_drag_step_move(efl_part(wd->resize_obj, "elm.dragable.slider"),
step, step);
else
efl_ui_drag_step_move(efl_part(wd->resize_obj, "efl.dragable.slider"),
step, step);
relative_step, relative_step);
_slider_update(data, EINA_TRUE);
}
static void
@ -227,6 +230,7 @@ _drag_down(void *data,
const char *source EINA_UNUSED)
{
double step;
double relative_step;
EFL_UI_SLIDER_DATA_GET(data, sd);
step = -sd->step;
@ -234,12 +238,14 @@ _drag_down(void *data,
if (efl_ui_layout_orientation_is_inverted(sd->dir)) step *= -1.0;
ELM_WIDGET_DATA_GET_OR_RETURN(data, wd);
relative_step = step/(sd->val_max - sd->val_min);
if (elm_widget_is_legacy(obj))
efl_ui_drag_step_move(efl_part(wd->resize_obj, "elm.dragable.slider"),
step, step);
else
efl_ui_drag_step_move(efl_part(wd->resize_obj, "efl.dragable.slider"),
step, step);
relative_step, relative_step);
_slider_update(data, EINA_TRUE);
}
static Eina_Bool
@ -247,6 +253,9 @@ _key_action_drag(Evas_Object *obj, const char *params)
{
EFL_UI_SLIDER_DATA_GET(obj, sd);
const char *dir = params;
double old_value, new_value;
old_value = efl_ui_range_value_get(obj);
if (!strcmp(dir, "left"))
{
@ -282,7 +291,8 @@ _key_action_drag(Evas_Object *obj, const char *params)
}
else return EINA_FALSE;
return EINA_TRUE;
new_value = efl_ui_range_value_get(obj);
return !EINA_DBL_EQ(new_value, old_value);
}
// _slider_efl_ui_widget_widget_input_event_handler

View File

@ -113,15 +113,20 @@ _label_write(Evas_Object *obj)
eina_strbuf_free(strbuf);
}
static Eina_Bool
_delay_change_timer_cb(void *data)
static Eina_Value
_delay_change_timer_cb(Eo *o, void *data EINA_UNUSED, const Eina_Value v)
{
Efl_Ui_Spin_Button_Data *sd = efl_data_scope_get(data, MY_CLASS);
efl_event_callback_call(o, EFL_UI_SPIN_BUTTON_EVENT_DELAY_CHANGED, NULL);
return v;
}
static void
_delay_change_timer_cleanup(Eo *o EINA_UNUSED, void *data, const Eina_Future *dead_future EINA_UNUSED)
{
Efl_Ui_Spin_Button_Data *sd = data;
sd->delay_change_timer = NULL;
efl_event_callback_call(data, EFL_UI_SPIN_BUTTON_EVENT_DELAY_CHANGED, NULL);
return ECORE_CALLBACK_CANCEL;
}
static Eina_Bool
@ -130,6 +135,7 @@ _value_set(Evas_Object *obj,
{
Efl_Ui_Spin_Button_Data *sd = efl_data_scope_get(obj, MY_CLASS);
Efl_Ui_Spin_Data *pd = efl_data_scope_get(obj, EFL_UI_SPIN_CLASS);
Eina_Future *f;
if (sd->circulate)
{
@ -146,9 +152,12 @@ _value_set(Evas_Object *obj,
if (EINA_DBL_EQ(new_val, efl_ui_range_value_get(obj))) return EINA_TRUE;
efl_ui_range_value_set(obj, new_val);
ecore_timer_del(sd->delay_change_timer);
sd->delay_change_timer = ecore_timer_add(EFL_UI_SPIN_BUTTON_DELAY_CHANGE_TIME,
_delay_change_timer_cb, obj);
if (sd->delay_change_timer) eina_future_cancel(sd->delay_change_timer);
f = efl_loop_timeout(efl_loop_get(obj), EFL_UI_SPIN_BUTTON_DELAY_CHANGE_TIME);
sd->delay_change_timer = efl_future_then(obj, f,
.success = _delay_change_timer_cb,
.free = _delay_change_timer_cleanup,
.data = sd);
return EINA_TRUE;
}

View File

@ -5,7 +5,7 @@ typedef struct _Efl_Ui_Spin_Button_Data Efl_Ui_Spin_Button_Data;
struct _Efl_Ui_Spin_Button_Data
{
Evas_Object *ent, *inc_button, *dec_button, *text_button;
Ecore_Timer *delay_change_timer; /**< a timer for a delay,changed smart callback */
Eina_Future *delay_change_timer; /**< a timer for a delay,changed smart callback */
Efl_Ui_Layout_Orientation dir;

View File

@ -383,4 +383,5 @@ _efl_ui_table_custom_layout(Efl_Ui_Table *ui_table, Efl_Ui_Table_Data *pd)
efl_gfx_hint_size_restricted_min_set(ui_table,
EINA_SIZE2D(table_calc.want[0],
table_calc.want[1]));
efl_event_callback_call(ui_table, EFL_PACK_EVENT_LAYOUT_UPDATED, NULL);
}

View File

@ -2213,7 +2213,7 @@ _efl_ui_text_efl_object_finalize(Eo *obj,
efl_event_callback_add(obj, EFL_GFX_ENTITY_EVENT_SIZE_CHANGED,
_text_size_changed_cb, obj);
elm_widget_can_focus_set(obj, EINA_TRUE);
efl_ui_widget_focus_allow_set(obj, sd->editable);
efl_ui_text_input_panel_layout_set(obj, ELM_INPUT_PANEL_LAYOUT_NORMAL);
efl_ui_text_input_panel_enabled_set(obj, EINA_TRUE);
@ -2390,6 +2390,7 @@ _efl_ui_text_efl_text_interactive_editable_set(Eo *obj, Efl_Ui_Text_Data *sd, Ei
if (sd->editable == editable) return;
sd->editable = editable;
efl_ui_widget_theme_apply(obj);
efl_ui_widget_focus_allow_set(obj, editable);
elm_drop_target_del(obj, sd->drop_format,
_dnd_enter_cb, NULL,

View File

@ -300,17 +300,6 @@ _candidacy_exam(Eo *obj)
static void _full_eval(Eo *obj, Elm_Widget_Smart_Data *pd);
static void
_manager_changed_cb(void *data, const Efl_Event *event EINA_UNUSED)
{
if (!efl_alive_get(data))
return;
ELM_WIDGET_DATA_GET(data, pd);
_full_eval(data, pd);
}
static Efl_Ui_Focus_Object*
_focus_manager_eval(Eo *obj, Elm_Widget_Smart_Data *pd, Eina_Bool want, Eina_Bool should)
{
@ -333,19 +322,9 @@ _focus_manager_eval(Eo *obj, Elm_Widget_Smart_Data *pd, Eina_Bool want, Eina_Boo
{
old = pd->manager.manager;
if (pd->manager.provider)
efl_event_callback_del(pd->manager.provider, EFL_UI_FOCUS_OBJECT_EVENT_FOCUS_MANAGER_CHANGED, _manager_changed_cb, obj);
pd->manager.manager = new;
pd->manager.provider = provider;
}
if (pd->manager.provider)
{
if (!want && !should)
efl_event_callback_del(pd->manager.provider, EFL_UI_FOCUS_OBJECT_EVENT_FOCUS_MANAGER_CHANGED, _manager_changed_cb, obj);
else
efl_event_callback_add(pd->manager.provider, EFL_UI_FOCUS_OBJECT_EVENT_FOCUS_MANAGER_CHANGED, _manager_changed_cb, obj);
}
return old;
}
@ -490,6 +469,10 @@ _logical_parent_eval(Eo *obj EINA_UNUSED, Elm_Widget_Smart_Data *pd, Eina_Bool s
{
ELM_WIDGET_DATA_GET_OR_RETURN(pd->logical.parent, logical_wd, NULL);
logical_wd->logical.child_count --;
if (logical_wd->logical.child_count == 0)
{
*state_change_to_parent = EINA_TRUE;
}
}
old = pd->logical.parent;
efl_weak_unref(&pd->logical.parent);
@ -525,18 +508,22 @@ _full_eval(Eo *obj, Elm_Widget_Smart_Data *pd)
old_parent = _logical_parent_eval(obj, pd, should, &state_change_to_parent);
if (efl_isa(old_parent, EFL_UI_WIDGET_CLASS))
if (state_change_to_parent)
{
//emit signal and focus eval old and new
ELM_WIDGET_DATA_GET(old_parent, old_pd);
_full_eval(old_parent, old_pd);
if (efl_isa(old_parent, EFL_UI_WIDGET_CLASS))
{
//emit signal and focus eval old and new
ELM_WIDGET_DATA_GET(old_parent, old_pd);
_full_eval(old_parent, old_pd);
}
if (efl_isa(pd->logical.parent, EFL_UI_WIDGET_CLASS))
{
ELM_WIDGET_DATA_GET(pd->logical.parent, new_pd);
_full_eval(pd->logical.parent, new_pd);
}
}
if (state_change_to_parent && efl_isa(pd->logical.parent, EFL_UI_WIDGET_CLASS))
{
ELM_WIDGET_DATA_GET(pd->logical.parent, new_pd);
_full_eval(pd->logical.parent, new_pd);
}
_focus_manager_eval(obj, pd, want_full, should);
@ -553,6 +540,7 @@ _full_eval(Eo *obj, Elm_Widget_Smart_Data *pd)
if (old_registered_manager != pd->focus.manager)
{
_elm_widget_full_eval_children(obj, pd);
efl_event_callback_call(obj,
EFL_UI_FOCUS_OBJECT_EVENT_FOCUS_MANAGER_CHANGED, old_registered_manager);
}
@ -4786,7 +4774,6 @@ _efl_ui_widget_efl_object_destructor(Eo *obj, Elm_Widget_Smart_Data *sd)
{
if (sd->manager.provider)
{
efl_event_callback_del(sd->manager.provider, EFL_UI_FOCUS_OBJECT_EVENT_FOCUS_MANAGER_CHANGED, _manager_changed_cb, obj);
sd->manager.provider = NULL;
}
efl_access_object_attributes_clear(obj);
@ -5056,8 +5043,8 @@ _efl_ui_widget_efl_object_provider_find(const Eo *obj, Elm_Widget_Smart_Data *pd
if (pd->provider_lookup) return NULL;
pd->provider_lookup = EINA_TRUE;
if (pd->parent_obj) lookup = efl_provider_find(pd->parent_obj, klass);
if (!lookup) lookup = efl_provider_find(efl_super(obj, MY_CLASS), klass);
lookup = efl_provider_find(efl_super(obj, MY_CLASS), klass);
if (!lookup && pd->parent_obj) lookup = efl_provider_find(pd->parent_obj, klass);
pd->provider_lookup = EINA_FALSE;
@ -5554,6 +5541,24 @@ _efl_ui_widget_part_efl_object_destructor(Eo *obj, Elm_Part_Data *pd)
efl_destructor(efl_super(obj, EFL_UI_WIDGET_PART_CLASS));
}
static Efl_Canvas_Layout_Part_Type
_efl_ui_widget_part_efl_canvas_layout_part_type_get(const Eo *obj EINA_UNUSED, Elm_Part_Data *pd)
{
Elm_Widget_Smart_Data *sd = efl_data_scope_safe_get(pd->obj, MY_CLASS);
return efl_canvas_layout_part_type_get(efl_part(sd->resize_obj, pd->part));
}
static Eina_Rect
_efl_ui_widget_part_efl_gfx_entity_geometry_get(const Eo *obj EINA_UNUSED, Elm_Part_Data *pd)
{
Elm_Widget_Smart_Data *sd = efl_data_scope_safe_get(pd->obj, MY_CLASS);
return efl_gfx_entity_geometry_get(efl_part(sd->resize_obj, pd->part));
}
#define EFL_UI_WIDGET_PART_EXTRA_OPS \
EFL_OBJECT_OP_FUNC(efl_canvas_layout_part_type_get, _efl_ui_widget_part_efl_canvas_layout_part_type_get), \
EFL_OBJECT_OP_FUNC(efl_gfx_entity_geometry_get, _efl_ui_widget_part_efl_gfx_entity_geometry_get)
#include "efl_ui_widget_part.eo.c"
/* Efl.Part end */
@ -5770,12 +5775,112 @@ _efl_ui_view_property_bind_changed(void *data, const Efl_Event *event)
}
}
static void
_efl_ui_widget_model_update(Efl_Ui_Widget_Data *pd)
{
Efl_Ui_Property_Bound *property;
Eina_Iterator *it;
it = eina_hash_iterator_data_new(pd->properties.model_lookup);
EINA_ITERATOR_FOREACH(it, property)
_efl_ui_property_bind_get(pd, property);
}
static void _efl_ui_widget_model_provider_model_change(void *data, const Efl_Event *event EINA_UNUSED);
static void _efl_ui_widget_model_provider_invalidate(void *data, const Efl_Event *event EINA_UNUSED);
EFL_CALLBACKS_ARRAY_DEFINE(efl_ui_widget_model_provider_callbacks,
{ EFL_EVENT_INVALIDATE, _efl_ui_widget_model_provider_invalidate },
{ EFL_UI_VIEW_EVENT_MODEL_CHANGED, _efl_ui_widget_model_provider_model_change });
static void
_efl_ui_widget_model_provider_model_change(void *data, const Efl_Event *event)
{
Efl_Ui_Widget_Data *pd = data;
efl_replace(&pd->properties.model,
efl_ui_view_model_get(pd->properties.provider));
_efl_ui_widget_model_update(pd);
efl_event_callback_call(pd->obj, EFL_UI_VIEW_EVENT_MODEL_CHANGED, event->info);
}
static void
_efl_ui_widget_model_provider_invalidate(void *data, const Efl_Event *event EINA_UNUSED)
{
Efl_Ui_Widget_Data *pd = data;
efl_event_callback_array_del(pd->properties.provider,
efl_ui_widget_model_provider_callbacks(),
pd);
efl_replace(&pd->properties.provider, NULL);
efl_replace(&pd->properties.model, NULL);
}
static void
_efl_ui_widget_model_register(Eo *obj, Efl_Ui_Widget_Data *pd)
{
if (pd->properties.registered) return ;
if (!pd->properties.model)
{
Efl_Model_Changed_Event ev;
efl_replace(&pd->properties.provider,
efl_provider_find(obj, EFL_MODEL_PROVIDER_CLASS));
if (!pd->properties.provider) return ;
efl_event_callback_array_add(pd->properties.provider,
efl_ui_widget_model_provider_callbacks(),
pd);
efl_replace(&pd->properties.model,
efl_ui_view_model_get(pd->properties.provider));
if (!pd->properties.model) return ;
ev.current = pd->properties.model;
ev.previous = NULL;
efl_event_callback_call(obj, EFL_UI_VIEW_EVENT_MODEL_CHANGED, &ev);
}
if (!pd->properties.model) return ;
if (!pd->properties.model_lookup) return ;
efl_event_callback_add(pd->properties.model, EFL_MODEL_EVENT_PROPERTIES_CHANGED,
_efl_ui_model_property_bind_changed, pd);
efl_event_callback_add(obj, EFL_UI_PROPERTY_BIND_EVENT_PROPERTIES_CHANGED,
_efl_ui_view_property_bind_changed, pd);
pd->properties.registered = EINA_TRUE;
}
static void
_efl_ui_widget_model_unregister(Eo *obj, Efl_Ui_Widget_Data *pd)
{
if (pd->properties.registered)
{
// Remove any existing handler that might exist for any reason
efl_event_callback_del(pd->properties.model, EFL_MODEL_EVENT_PROPERTIES_CHANGED,
_efl_ui_model_property_bind_changed, pd);
efl_event_callback_del(obj, EFL_UI_PROPERTY_BIND_EVENT_PROPERTIES_CHANGED,
_efl_ui_view_property_bind_changed, pd);
pd->properties.registered = EINA_FALSE;
}
// Invalidate must be called before setting a new model and even if no model is registered
if (pd->properties.provider)
_efl_ui_widget_model_provider_invalidate(pd, NULL);
}
static Eina_Error
_efl_ui_widget_efl_ui_property_bind_property_bind(Eo *obj, Efl_Ui_Widget_Data *pd,
const char *key, const char *property)
{
Efl_Ui_Property_Bound *prop;
// Always check for a model and fetch a provider in case a binded property
// is provided by a class down the hierarchy, but they still need to be notified
// when a model change
_efl_ui_widget_model_register(obj, pd);
// Check if the property is available from the reflection table of the object.
if (!efl_property_reflection_exist(obj, key)) return EFL_PROPERTY_ERROR_INVALID_KEY;
@ -5783,13 +5888,6 @@ _efl_ui_widget_efl_ui_property_bind_property_bind(Eo *obj, Efl_Ui_Widget_Data *p
{
pd->properties.model_lookup = eina_hash_stringshared_new(_efl_ui_property_bind_free);
pd->properties.view_lookup = eina_hash_stringshared_new(NULL);
if (pd->properties.model)
{
efl_event_callback_add(pd->properties.model, EFL_MODEL_EVENT_PROPERTIES_CHANGED,
_efl_ui_model_property_bind_changed, pd);
efl_event_callback_add(obj, EFL_UI_PROPERTY_BIND_EVENT_PROPERTIES_CHANGED,
_efl_ui_view_property_bind_changed, pd);
}
}
prop = calloc(1, sizeof (Efl_Ui_Property_Bound));
@ -5812,25 +5910,27 @@ _efl_ui_widget_efl_ui_view_model_set(Eo *obj,
Efl_Ui_Widget_Data *pd,
Efl_Model *model)
{
if (pd->properties.model)
{
// Remove any existing handler that might exist for any reason
efl_event_callback_del(pd->properties.model, EFL_MODEL_EVENT_PROPERTIES_CHANGED,
_efl_ui_model_property_bind_changed, pd);
efl_event_callback_del(obj, EFL_UI_PROPERTY_BIND_EVENT_PROPERTIES_CHANGED,
_efl_ui_view_property_bind_changed, pd);
}
Efl_Model_Changed_Event ev;
ev.current = efl_ref(model);
ev.previous = efl_ref(pd->properties.model);
_efl_ui_widget_model_unregister(obj, pd);
efl_replace(&pd->properties.model, model);
if (pd->properties.model && pd->properties.model_lookup)
{
// Set the properties handler just in case
efl_event_callback_add(pd->properties.model, EFL_MODEL_EVENT_PROPERTIES_CHANGED,
_efl_ui_model_property_bind_changed, pd);
efl_event_callback_add(obj, EFL_UI_PROPERTY_BIND_EVENT_PROPERTIES_CHANGED,
_efl_ui_view_property_bind_changed, pd);
}
// Set the properties handler just in case
_efl_ui_widget_model_register(obj, pd);
// In case the model set was NULL, but we did found a model provider
// we shouldn't emit a second event. Otherwise we should.
if (ev.current == pd->properties.model)
efl_event_callback_call(obj, EFL_UI_VIEW_EVENT_MODEL_CHANGED, &ev);
if (pd->properties.model) _efl_ui_widget_model_update(pd);
efl_unref(ev.current);
efl_unref(ev.previous);
}
static Efl_Model *
@ -5844,14 +5944,9 @@ _efl_ui_widget_efl_object_invalidate(Eo *obj, Efl_Ui_Widget_Data *pd)
{
efl_invalidate(efl_super(obj, EFL_UI_WIDGET_CLASS));
if (pd->properties.model)
{
efl_event_callback_del(pd->properties.model, EFL_MODEL_EVENT_PROPERTIES_CHANGED,
_efl_ui_model_property_bind_changed, pd);
efl_event_callback_del(obj, EFL_UI_PROPERTY_BIND_EVENT_PROPERTIES_CHANGED,
_efl_ui_view_property_bind_changed, pd);
efl_replace(&pd->properties.model, NULL);
}
_efl_ui_widget_model_unregister(obj, pd);
efl_replace(&pd->properties.model, NULL);
if (pd->properties.view_lookup) eina_hash_free(pd->properties.view_lookup);
pd->properties.view_lookup = NULL;
if (pd->properties.model_lookup) eina_hash_free(pd->properties.model_lookup);

View File

@ -103,6 +103,7 @@ struct _Efl_Ui_Image_Data
Eina_Bool scale_up : 1;
Eina_Bool scale_down : 1;
Eina_Bool legacy_align : 1;
Eina_Bool property_watch : 1;
};
/**

View File

@ -2979,6 +2979,8 @@ _elm_win_img_callbacks_del(Evas_Object *obj, Evas_Object *imgobj)
EOLIAN static void
_efl_ui_win_efl_canvas_group_group_del(Eo *obj, Efl_Ui_Win_Data *sd)
{
efl_event_freeze(sd->evas);
if ((sd->modal) && (evas_object_visible_get(obj)))
_elm_win_modality_decrement(sd);

View File

@ -237,7 +237,7 @@ _button_animator(void *data)
_text_get(obj, &left, &right, &center);
if ((!EINA_DBL_EQ(sd->final_position, 0)) &&
if ((EINA_DBL_EQ(sd->final_position, 0)) &&
(sd->enabled_position & ELM_ACTIONSLIDER_LEFT))
evas_object_smart_callback_call(obj, "selected",(char *)left);
else if ((EINA_DBL_EQ(sd->final_position, 0.5)) &&
@ -548,7 +548,7 @@ _elm_actionslider_efl_object_constructor(Eo *obj, Elm_Actionslider_Data *_pd EIN
}
EOLIAN static void
_elm_actionslider_indicator_pos_set(Eo *obj, Elm_Actionslider_Data *_pd EINA_UNUSED, Elm_Actionslider_Pos pos)
_elm_actionslider_indicator_pos_set(Eo *obj, Elm_Actionslider_Data *sd, Elm_Actionslider_Pos pos)
{
double position = 0.0;
@ -559,6 +559,7 @@ _elm_actionslider_indicator_pos_set(Eo *obj, Elm_Actionslider_Data *_pd EINA_UNU
if (pos == ELM_ACTIONSLIDER_CENTER) position = 0.5;
else if (pos == ELM_ACTIONSLIDER_RIGHT)
position = 1.0;
sd->final_position = position;
edje_object_part_drag_value_set
(wd->resize_obj, "elm.drag_button_base", position, 0.5);

View File

@ -1712,8 +1712,8 @@ _config_load(void)
if (_efl_config_obj)
{
efl_del_intercept_set(_efl_config_obj, NULL);
efl_loop_unregister(efl_main_loop_get(), EFL_CONFIG_INTERFACE, _efl_config_obj);
efl_loop_unregister(efl_main_loop_get(), EFL_CONFIG_GLOBAL_CLASS, _efl_config_obj);
efl_provider_unregister(efl_main_loop_get(), EFL_CONFIG_INTERFACE, _efl_config_obj);
efl_provider_unregister(efl_main_loop_get(), EFL_CONFIG_GLOBAL_CLASS, _efl_config_obj);
ELM_SAFE_FREE(_efl_config_obj, efl_del);
ELM_SAFE_FREE(_elm_config, _config_free);
_elm_font_overlays_del_free();
@ -1721,8 +1721,8 @@ _config_load(void)
ELM_SAFE_FREE(_elm_key_bindings, eina_hash_free);
}
_efl_config_obj = efl_add(EFL_CONFIG_GLOBAL_CLASS, efl_main_loop_get());
efl_loop_register(efl_main_loop_get(), EFL_CONFIG_INTERFACE, _efl_config_obj);
efl_loop_register(efl_main_loop_get(), EFL_CONFIG_GLOBAL_CLASS, _efl_config_obj);
efl_provider_register(efl_main_loop_get(), EFL_CONFIG_INTERFACE, _efl_config_obj);
efl_provider_register(efl_main_loop_get(), EFL_CONFIG_GLOBAL_CLASS, _efl_config_obj);
efl_del_intercept_set(_efl_config_obj, _efl_config_obj_del);
if (!_use_build_config)
{
@ -4662,8 +4662,8 @@ void
_elm_config_shutdown(void)
{
efl_del_intercept_set(_efl_config_obj, NULL);
efl_loop_unregister(efl_main_loop_get(), EFL_CONFIG_INTERFACE, _efl_config_obj);
efl_loop_unregister(efl_main_loop_get(), EFL_CONFIG_GLOBAL_CLASS, _efl_config_obj);
efl_provider_unregister(efl_main_loop_get(), EFL_CONFIG_INTERFACE, _efl_config_obj);
efl_provider_unregister(efl_main_loop_get(), EFL_CONFIG_GLOBAL_CLASS, _efl_config_obj);
ELM_SAFE_FREE(_efl_config_obj, efl_del);
ELM_SAFE_FREE(_elm_config, _config_free);
ELM_SAFE_FREE(_elm_preferred_engine, eina_stringshare_del);

View File

@ -1285,7 +1285,10 @@ _elm_interface_scrollable_content_viewport_geometry_get(const Eo *obj EINA_UNUSE
{
if (!sid->pan_obj || !sid->edje_obj) return;
edje_object_calc_force(sid->edje_obj);
/* we want to trigger any pending edje recalcs here but we don't strictly need to
* trigger one if it isn't necessary
*/
efl_canvas_group_calculate(sid->edje_obj);
evas_object_geometry_get(sid->pan_obj, x, y, w, h);
}

View File

@ -386,8 +386,10 @@ typedef struct _Elm_Widget_Smart_Data
} legacy_focus;
struct {
Efl_Model *model;
Efl_Model_Provider *provider;
Eina_Hash *model_lookup;
Eina_Hash *view_lookup;
Eina_Bool registered : 1;
} properties;
Eina_Bool scroll_x_locked : 1;
Eina_Bool scroll_y_locked : 1;

View File

@ -71,6 +71,8 @@ typedef struct _Elm_Layout_Smart_Data
Eina_Bool destructed_is : 1; /**< This flag indicates if Efl.Ui.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 Efl.Ui.Layout source is set from a file*/
Eina_Bool automatic_orientation_apply : 1;
Eina_Bool model_bound : 1; /**< Set to true once we are watching over a model*/
Eina_Bool model_watch : 1; /**< Set to true once we do watch for model change*/
} Efl_Ui_Layout_Data;
/**

View File

@ -214,6 +214,34 @@ typedef void (*Efl_Del_Intercept) (Eo *obj_id);
#include "efl_object_override.eo.h"
#include "efl_object.eo.h"
/**
* @brief A parameter passed in event callbacks holding extra event parameters.
*
* This is the full event information passed to callbacks in C.
*
* @since 1.22
*
* @ingroup Efl
*/
typedef struct _Efl_Event
{
Efl_Object *object; /**< The object the callback was called on.
*
* @since 1.22 */
const Efl_Event_Description *desc; /**< The event description.
*
* @since 1.22 */
void *info; /**< Extra event information passed by the event caller. Must be
* cast to the event type declared in the EO file. Keep in mind
* that: 1) Objects are passed as a normal Eo*. Event subscribers
* can call functions on these objects. 2) Structs, built-in
* types and containers are passed as const pointers, with one
* level of indirection.
*
* @since 1.22 */
} Efl_Event;
#define EO_CLASS EFL_OBJECT_CLASS
/** An event callback prototype. */

View File

@ -402,6 +402,22 @@ abstract Efl.Object
even if @.parent is not $null.]]
}
}
provider_register {
[[Will register a manager of a specific class to be answered by eo.provider_find.]]
params {
@in klass: const(Efl.Class); [[The class provided by the registered provider.]]
@in provider: const(Efl.Object); [[The provider for the newly registered class that has to provide that said Efl.Class.]]
}
return: bool; [[$true if successfully register, $false otherwise.]]
}
provider_unregister {
[[Will unregister a manager of a specific class that was previously registered and answered by eo.provider_find.]]
params {
@in klass: const(Efl.Class); [[The class provided by the provider to unregister for.]]
@in provider: const(Efl.Object); [[The provider for the registered class to unregister.]]
}
return: bool; [[$true if successfully unregistered, $false otherwise.]]
}
}
implements {
class.constructor;
@ -422,7 +438,7 @@ abstract Efl.Object
}
}
struct Efl.Event {
struct @extern Efl.Event {
[[A parameter passed in event callbacks holding extra event parameters.
This is the full event information passed to callbacks in C.

View File

@ -39,6 +39,7 @@ typedef struct
Eo *composite_parent;
Eina_Inlist *generic_data;
Eo ***wrefs;
Eina_Hash *providers;
} Efl_Object_Extension;
struct _Efl_Object_Data
@ -125,11 +126,46 @@ _efl_pending_futures_clear(Efl_Object_Data *pd)
}
}
static inline void
_efl_object_extension_free(Efl_Object_Extension *ext)
{
eina_freeq_ptr_main_add(ext, free, sizeof(*ext));
}
static inline Efl_Object_Extension *
_efl_object_extension_need(Efl_Object_Data *pd)
{
if (!pd->ext) pd->ext = calloc(1, sizeof(Efl_Object_Extension));
return pd->ext;
}
static inline void
_efl_object_extension_noneed(Efl_Object_Data *pd)
{
Efl_Object_Extension *ext = pd->ext;
if ((!ext) ||
(ext->name) ||
(ext->comment) ||
(ext->generic_data) ||
(ext->wrefs) ||
(ext->composite_parent) ||
(ext->providers)) return;
_efl_object_extension_free(pd->ext);
pd->ext = NULL;
}
static void
_efl_object_invalidate(Eo *obj_id, Efl_Object_Data *pd)
{
_efl_pending_futures_clear(pd);
if (pd->ext && pd->ext->providers)
{
eina_hash_free(pd->ext->providers);
pd->ext->providers = NULL;
_efl_object_extension_noneed(pd);
}
EO_OBJ_POINTER_RETURN(obj_id, obj);
// Finally invalidate itself if it wasn't done already
@ -185,33 +221,6 @@ _efl_invalidate(_Eo_Object *obj)
obj->invalidate = EINA_TRUE;
}
static inline void
_efl_object_extension_free(Efl_Object_Extension *ext)
{
eina_freeq_ptr_main_add(ext, free, sizeof(*ext));
}
static inline Efl_Object_Extension *
_efl_object_extension_need(Efl_Object_Data *pd)
{
if (!pd->ext) pd->ext = calloc(1, sizeof(Efl_Object_Extension));
return pd->ext;
}
static inline void
_efl_object_extension_noneed(Efl_Object_Data *pd)
{
Efl_Object_Extension *ext = pd->ext;
if ((!ext) ||
(ext->name) ||
(ext->comment) ||
(ext->generic_data) ||
(ext->wrefs) ||
(ext->composite_parent)) return;
_efl_object_extension_free(pd->ext);
pd->ext = NULL;
}
static void _key_generic_cb_del(void *data, const Efl_Event *event);
static void
@ -832,6 +841,7 @@ EOLIAN static Efl_Object *
_efl_object_provider_find(const Eo *obj, Efl_Object_Data *pd, const Efl_Object *klass)
{
Eina_Bool invalidate;
Efl_Object *r = NULL;
invalidate = _efl_object_invalidated_get((Eo*) obj, NULL);
if (invalidate)
@ -839,10 +849,50 @@ _efl_object_provider_find(const Eo *obj, Efl_Object_Data *pd, const Efl_Object *
ERR("Calling efl_provider_find(%p) after the object was invalidated.", obj);
return NULL;
}
if (efl_isa(obj, klass)) return (Eo *) obj;
if (pd->ext) r = eina_hash_find(pd->ext->providers, &klass);
if (r) return r;
if (pd->parent) return efl_provider_find(pd->parent, klass);
return NULL;
}
static Eina_Bool
_efl_object_provider_register(Eo *obj EINA_UNUSED, Efl_Object_Data *pd, const Efl_Class *klass, const Efl_Object *provider)
{
// The passed object does not provide that said class.
if (!efl_isa(provider, klass)) return EINA_FALSE;
_efl_object_extension_need(pd);
if (!pd->ext) return EINA_FALSE;
if (!pd->ext->providers) pd->ext->providers = eina_hash_pointer_new(EINA_FREE_CB(efl_unref));
// Prevent double insertion for the same class
if (eina_hash_find(pd->ext->providers, &klass)) return EINA_FALSE;
// Note: I would prefer to use efl_xref here, but I can't figure a nice way to
// call efl_xunref on hash destruction.
return eina_hash_add(pd->ext->providers, &klass, efl_ref(provider));
}
static Eina_Bool
_efl_object_provider_unregister(Eo *obj EINA_UNUSED, Efl_Object_Data *pd, const Efl_Class *klass, const Efl_Object *provider)
{
Eina_Bool r;
if (!pd->ext) return EINA_FALSE;
r = eina_hash_del(pd->ext->providers, &klass, provider);
if (eina_hash_population(pd->ext->providers) != 0) return r;
eina_hash_free(pd->ext->providers);
pd->ext->providers = NULL;
_efl_object_extension_noneed(pd);
return r;
}
/* Children accessor */
typedef struct _Eo_Children_Iterator Eo_Children_Iterator;
struct _Eo_Children_Iterator

View File

@ -341,7 +341,8 @@ typedef enum
EOLIAN_TYPE_BUILTIN_ANY_VALUE,
EOLIAN_TYPE_BUILTIN_ANY_VALUE_PTR,
EOLIAN_TYPE_BUILTIN_BINBUF,
EOLIAN_TYPE_BUILTIN_EVENT,
EOLIAN_TYPE_BUILTIN_MSTRING,
EOLIAN_TYPE_BUILTIN_STRING,
EOLIAN_TYPE_BUILTIN_STRINGSHARE,

View File

@ -14,7 +14,6 @@ database_type_del(Eolian_Type *tp)
eina_stringshare_del(tp->base.c_name);
database_type_del(tp->base_type);
database_type_del(tp->next_type);
if (tp->freefunc) eina_stringshare_del(tp->freefunc);
free(tp);
}

View File

@ -283,14 +283,12 @@ _validate_type(Validate_State *vals, Eolian_Type *tp)
case KW_stringshare:
case KW_any_value:
case KW_any_value_ptr:
case KW_binbuf:
tp->ownable = EINA_TRUE;
break;
default:
break;
}
/* FIXME: remove this after c++/c# has fixed their stuff */
if (tp->freefunc)
tp->ownable = EINA_TRUE;
return _validate_ownable(tp);
}
/* user defined */
@ -309,7 +307,7 @@ _validate_type(Validate_State *vals, Eolian_Type *tp)
}
if (!_validate_typedecl(vals, tp->tdecl))
return EINA_FALSE;
if (tp->tdecl->ownable || tp->freefunc)
if (tp->tdecl->ownable)
tp->ownable = EINA_TRUE;
tp->base.c_name = eina_stringshare_ref(tp->tdecl->base.c_name);
return _validate_ownable(tp);

View File

@ -77,7 +77,7 @@ static const char * const ctypes[] =
"Eina_Accessor *", "Eina_Array *", "Eina_Future *", "Eina_Iterator *",
"Eina_Hash *", "Eina_List *",
"Eina_Value", "Eina_Value *",
"Eina_Value", "Eina_Value *", "Eina_Binbuf *", "Efl_Event *",
"char *", "const char *", "Eina_Stringshare *", "Eina_Strbuf *",
"void *",

View File

@ -60,7 +60,7 @@ enum Tokens
KW(void), \
\
KW(accessor), KW(array), KW(future), KW(iterator), KW(hash), KW(list), \
KW(any_value), KW(any_value_ptr), \
KW(any_value), KW(any_value_ptr), KW(binbuf), KW(event), \
KW(mstring), KW(string), KW(stringshare), KW(strbuf), \
\
KW(void_ptr), \

View File

@ -708,22 +708,6 @@ parse_type_void(Eo_Lexer *ls, Eina_Bool allow_ptr)
check_match(ls, ')', '(', pline, pcol);
return def;
}
case KW_free:
{
int pline, pcolumn;
eo_lexer_get(ls);
pline = ls->line_number;
pcolumn = ls->column;
check_next(ls, '(');
def = parse_type_void(ls, allow_ptr);
check_next(ls, ',');
check(ls, TOK_VALUE);
def->freefunc = eina_stringshare_ref(ls->t.value.s);
eo_lexer_get(ls);
FILL_BASE(def->base, ls, line, col, TYPE);
check_match(ls, ')', '(', pline, pcolumn);
return def;
}
case KW_error:
{
int pline, pcolumn;

View File

@ -264,7 +264,6 @@ struct _Eolian_Type
Eolian_Type_Builtin_Type btype;
Eolian_Type *base_type;
Eolian_Type *next_type;
Eina_Stringshare *freefunc;
union
{
Eolian_Class *klass;

View File

@ -67,10 +67,3 @@ getpwnam(const char *n)
return &pw;
}
struct passwd *
getpwuid(uid_t uid)
{
return getpwnam(getlogin());
(void)uid;
}

View File

@ -72,21 +72,6 @@ struct passwd {
*/
EAPI struct passwd *getpwnam(const char *n);
/**
* @brief Return a passwd structure.
*
* @param uid The User ID.
* @return A stacally allocated passwd structure.
*
* This function fills a static buffer @ref passwd with @p uid and the
* user name.
*
* Conformity: None.
*
* Supported OS: Windows XP.
*/
EAPI struct passwd *getpwuid (uid_t uid);
#ifdef __cplusplus
}

View File

@ -683,13 +683,16 @@ _apply_gradient_property(Svg_Style_Gradient *g, Efl_VG *vg, Efl_VG *parent, Vg_F
stop_count = eina_list_count(g->stops);
if (stop_count)
{
double opacity;
stops = calloc(stop_count, sizeof(Efl_Gfx_Gradient_Stop));
i = 0;
EINA_LIST_FOREACH(g->stops, l, stop)
{
stops[i].r = stop->r;
stops[i].g = stop->g;
stops[i].b = stop->b;
// Use premultiplied color
opacity = (double)stop->a / 255;
stops[i].r = stop->r * opacity;
stops[i].g = stop->g * opacity;
stops[i].b = stop->b * opacity;
stops[i].a = stop->a;
stops[i].offset = stop->offset;
i++;

View File

@ -10,7 +10,7 @@
#include "efl_app_suite.h"
#include "../efl_check.h"
EFL_START_TEST(efl_app_test_efl_loop_register)
EFL_START_TEST(efl_app_test_efl_provider_register)
{
Efl_Object *t, *n;
@ -25,13 +25,13 @@ EFL_START_TEST(efl_app_test_efl_loop_register)
n = efl_add(EFL_LOOP_TIMER_CLASS, efl_app_main_get(),
efl_loop_timer_interval_set(efl_added, 1.0));
efl_loop_register(efl_app_main_get(), EFL_LOOP_TIMER_CLASS, n);
efl_provider_register(efl_app_main_get(), EFL_LOOP_TIMER_CLASS, n);
t = efl_provider_find(efl_app_main_get(), EFL_LOOP_TIMER_CLASS);
fail_if(!efl_isa(t, EFL_LOOP_TIMER_CLASS));
fail_if(t != n);
efl_loop_unregister(efl_app_main_get(), EFL_LOOP_TIMER_CLASS, n);
efl_provider_unregister(efl_app_main_get(), EFL_LOOP_TIMER_CLASS, n);
t = efl_provider_find(efl_app_main_get(), EFL_LOOP_TIMER_CLASS);
fail_if(t != NULL);
@ -101,7 +101,7 @@ EFL_END_TEST
void efl_app_test_efl_loop(TCase *tc)
{
tcase_add_test(tc, efl_app_test_efl_loop_register);
tcase_add_test(tc, efl_app_test_efl_provider_register);
tcase_add_test(tc, efl_app_test_efl_loop_concentric);
tcase_add_test(tc, efl_loop_test_realized_name);
}

View File

@ -53,6 +53,45 @@ EFL_START_TEST(efl_ui_layout_test_property_bind)
}
EFL_END_TEST
EFL_START_TEST(efl_ui_layout_test_property_bind_provider)
{
char buf[PATH_MAX];
Evas_Object *win, *ly;
Efl_Generic_Model *model;
Efl_Model_Provider *provider;
Eina_Value v;
Eina_Future *f;
const char *part_text;
const char text_value[] = "A random string for elm_layout_property_bind test";
win = win_add(NULL, "layout", EFL_UI_WIN_TYPE_BASIC);
provider = efl_add(EFL_MODEL_PROVIDER_CLASS, win);
efl_provider_register(win, EFL_MODEL_PROVIDER_CLASS, provider);
ly = efl_add(EFL_UI_LAYOUT_CLASS, win);
snprintf(buf, sizeof(buf), "%s/objects/test.edj", ELM_TEST_DATA_DIR);
efl_file_simple_load(ly, buf, "layout");
efl_gfx_entity_visible_set(ly, EINA_TRUE);
model = efl_add(EFL_GENERIC_MODEL_CLASS, win);
ck_assert(!!eina_value_setup(&v, EINA_VALUE_TYPE_STRING));
ck_assert(!!eina_value_set(&v, text_value));
f = efl_model_property_set(model, "text_property", &v);
eina_future_then(f, _propagated_cb, NULL, NULL);
efl_ui_property_bind(ly, "text", "text_property");
efl_ui_view_model_set(provider, model);
ecore_main_loop_begin();
part_text = efl_text_get(efl_part(ly, "text"));
ck_assert_str_eq(part_text, text_value);
}
EFL_END_TEST
EFL_START_TEST(efl_ui_layout_test_layout_api_size_min)
{
Evas_Object *win;
@ -130,4 +169,5 @@ void efl_ui_test_layout(TCase *tc)
tcase_add_test(tc, efl_ui_layout_test_layout_force);
tcase_add_test(tc, efl_ui_layout_test_layout_theme);
tcase_add_test(tc, efl_ui_layout_test_api_ordering);
tcase_add_test(tc, efl_ui_layout_test_property_bind_provider);
}

View File

@ -52,7 +52,44 @@ EFL_START_TEST(efl_ui_test_slider_events)
}
EFL_END_TEST
EFL_START_TEST(efl_ui_test_slider_step)
{
Eo *slider;
Evas *e;
Eo *win = win_add();
efl_gfx_entity_size_set(win, EINA_SIZE2D(400, 100));
slider = efl_add(EFL_UI_SLIDER_CLASS, win,
efl_event_callback_add(efl_added, EFL_UI_SLIDER_EVENT_CHANGED, slider_changed, NULL),
efl_event_callback_add(efl_added, EFL_UI_SLIDER_EVENT_STEADY, slider_changed, NULL),
efl_gfx_entity_size_set(efl_added, EINA_SIZE2D(400, 100))
);
efl_ui_range_limits_set(slider, 0, 100);
efl_ui_range_step_set(slider, 10);
efl_ui_range_value_set(slider, 20);
e = evas_object_evas_get(win);
efl_layout_signal_process(slider, EINA_TRUE);
get_me_to_those_events(slider);
int x, y, w, h;
int sx, sy, sw, sh;
evas_object_geometry_get(elm_object_part_content_get(slider, "efl.bar"), &x, &y, &w, &h);
evas_object_geometry_get(slider, &sx, &sy, &sw, &sh);
evas_event_feed_mouse_in(e, 0, NULL);
evas_event_feed_mouse_move(e, x + (w / 2), y + (h / 2), 0, NULL);
evas_event_feed_mouse_wheel(e, -1, 1, 0, NULL);
evas_event_feed_mouse_up(e, 1, 0, 0, NULL);
efl_layout_signal_process(slider, EINA_TRUE);
get_me_to_those_events(slider);
ck_assert_int_eq(efl_ui_range_value_get(slider), 10);
}
EFL_END_TEST
void efl_ui_test_slider(TCase *tc)
{
tcase_add_test(tc, efl_ui_test_slider_events);
tcase_add_test(tc, efl_ui_test_slider_step);
}

View File

@ -41,8 +41,99 @@ EFL_START_TEST(elm_atspi_role_get)
}
EFL_END_TEST
static const char *test_val;
static void
test_selected_cb(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
{
/* if the test crashes with a crazy stack trace, this assert failed */
ck_assert_str_eq(event_info, test_val);
ecore_main_loop_quit();
}
EFL_START_TEST(elm_actionslider_test_callbacks)
{
Evas_Object *win, *as;
int called = 0;
win = win_add(NULL, "as", ELM_WIN_BASIC);
as = elm_actionslider_add(win);
evas_object_resize(as, 200, 200);
evas_object_resize(win, 200, 200);
evas_object_show(win);
evas_object_show(as);
elm_actionslider_indicator_pos_set(as, ELM_ACTIONSLIDER_RIGHT);
elm_actionslider_magnet_pos_set(as, ELM_ACTIONSLIDER_RIGHT);
elm_object_part_text_set(as, "left", "test1");
elm_object_part_text_set(as, "center", "test2");
elm_object_part_text_set(as, "right", "test3");
elm_actionslider_enabled_pos_set(as, ELM_ACTIONSLIDER_LEFT |
ELM_ACTIONSLIDER_CENTER | ELM_ACTIONSLIDER_RIGHT);
evas_object_smart_callback_add(as, "pos_changed",
event_callback_that_is_called_exactly_one_time_and_sets_a_single_int_data_pointer_when_called, &called);
evas_object_smart_callback_add(as, "selected", test_selected_cb, &called);
get_me_to_those_events(as);
test_val = "test2";
called = 0;
click_part(as, "elm.text.left");
edje_object_message_signal_process(as);
ecore_main_loop_begin();
ck_assert_int_eq(called, 1);
test_val = "test1";
called = 0;
click_part(as, "elm.text.left");
edje_object_message_signal_process(as);
ecore_main_loop_begin();
ck_assert_int_eq(called, 1);
test_val = "test2";
called = 0;
click_part(as, "elm.text.center");
edje_object_message_signal_process(as);
ecore_main_loop_begin();
ck_assert_int_eq(called, 1);
test_val = "test3";
called = 0;
click_part(as, "elm.text.right");
edje_object_message_signal_process(as);
ecore_main_loop_begin();
ck_assert_int_eq(called, 1);
}
EFL_END_TEST
EFL_START_TEST(elm_actionslider_test_parts)
{
Evas_Object *win, *as;
win = win_add(NULL, "as", ELM_WIN_BASIC);
as = elm_actionslider_add(win);
elm_actionslider_indicator_pos_set(as, ELM_ACTIONSLIDER_RIGHT);
ck_assert_int_eq(elm_actionslider_indicator_pos_get(as), ELM_ACTIONSLIDER_RIGHT);
elm_actionslider_magnet_pos_set(as, ELM_ACTIONSLIDER_RIGHT);
ck_assert_int_eq(elm_actionslider_magnet_pos_get(as), ELM_ACTIONSLIDER_RIGHT);
elm_object_part_text_set(as, "left", "Snooze");
ck_assert_str_eq(elm_object_part_text_get(as, "left"), "Snooze");
elm_object_part_text_set(as, "center", NULL);
ck_assert_ptr_eq(elm_object_part_text_get(as, "center"), NULL);
elm_object_part_text_set(as, "right", "Stop");
ck_assert_str_eq(elm_object_part_text_get(as, "right"), "Stop");
elm_actionslider_enabled_pos_set(as, ELM_ACTIONSLIDER_LEFT | ELM_ACTIONSLIDER_RIGHT);
ck_assert_int_eq(elm_actionslider_enabled_pos_get(as), ELM_ACTIONSLIDER_LEFT | ELM_ACTIONSLIDER_RIGHT);
}
EFL_END_TEST
void elm_test_actionslider(TCase *tc)
{
tcase_add_test(tc, elm_actionslider_legacy_type_check);
tcase_add_test(tc, elm_atspi_role_get);
tcase_add_test(tc, elm_actionslider_test_callbacks);
tcase_add_test(tc, elm_actionslider_test_parts);
}

View File

@ -41,9 +41,51 @@ EFL_START_TEST(elm_atspi_role_get)
}
EFL_END_TEST
EFL_START_TEST(elm_bubble_test_callbacks)
{
Evas_Object *win, *bb, *ic, *ct;
int called = 0;
win = win_add(NULL, "bubble", ELM_WIN_BASIC);
ic = elm_icon_add(win);
ck_assert(elm_image_file_set(ic, ELM_IMAGE_DATA_DIR "/images/logo_small.png", NULL));
elm_image_resizable_set(ic, EINA_FALSE, EINA_FALSE);
evas_object_size_hint_aspect_set(ic, EVAS_ASPECT_CONTROL_HORIZONTAL, 1, 1);
bb = elm_bubble_add(win);
elm_object_text_set(bb, "Message 1");
elm_object_part_text_set(bb, "info", "Corner: bottom_right");
elm_object_part_content_set(bb, "icon", ic);
elm_bubble_pos_set(bb, ELM_BUBBLE_POS_BOTTOM_RIGHT);
evas_object_smart_callback_add(bb, "clicked", event_callback_that_is_called_exactly_one_time_and_sets_a_single_int_data_pointer_when_called, &called);
evas_object_show(ic);
evas_object_size_hint_weight_set(bb, EVAS_HINT_EXPAND, 0.0);
evas_object_size_hint_align_set(bb, EVAS_HINT_FILL, EVAS_HINT_FILL);
ct = elm_label_add(win);
elm_object_text_set(ct,
"\"The future of the art: R or G or B?\", by Rusty");
elm_object_content_set(bb, ct);
evas_object_resize(bb, 240, 100);
evas_object_resize(win, 240, 100);
evas_object_show(bb);
evas_object_show(win);
get_me_to_those_events(bb);
click_object(ct);
ck_assert_int_eq(called, 1);
called = 0;
click_part(bb, "elm.info");
ck_assert_int_eq(called, 1);
}
EFL_END_TEST
void elm_test_bubble(TCase *tc)
{
tcase_add_test(tc, elm_bubble_legacy_type_check);
tcase_add_test(tc, elm_atspi_role_get);
tcase_add_test(tc, elm_bubble_test_callbacks);
}

View File

@ -0,0 +1,65 @@
#ifdef HAVE_CONFIG_H
# include "elementary_config.h"
#endif
#include <Efl_Ui.h>
#include "efl_ui_spec_suite.h"
#include "suite_helpers.h"
/* spec-meta-start
{"test-interface":"Efl.Ui.View",
"test-widgets": ["Efl.Ui.Image", "Efl.Ui.Layout", "Efl.Ui.Button"]}
spec-meta-end */
typedef struct _Efl_Ui_Image_Model_Change Efl_Ui_Image_Model_Change;
struct _Efl_Ui_Image_Model_Change
{
Efl_Model *expected_current;
Eina_Bool called;
Eina_Bool previous;
Eina_Bool current;
};
static void
_efl_ui_image_model_changed(void *data, const Efl_Event *event)
{
Efl_Ui_Image_Model_Change *change = data;
Efl_Model_Changed_Event *ev = event->info;
ck_assert(!change->called);
change->called = EINA_TRUE;
change->previous = ev->previous ? EINA_TRUE : EINA_FALSE;
ck_assert_ptr_eq(ev->current, change->expected_current);
change->current = ev->current ? EINA_TRUE : EINA_FALSE;
}
EFL_START_TEST(model_change_event)
{
Efl_Model *model = efl_add(EFL_GENERIC_MODEL_CLASS, efl_main_loop_get());
Efl_Ui_Image_Model_Change test = { NULL, EINA_FALSE, EINA_FALSE, EINA_FALSE };
efl_event_callback_add(widget, EFL_UI_VIEW_EVENT_MODEL_CHANGED,
_efl_ui_image_model_changed, &test);
ck_assert_int_eq(test.called, EINA_FALSE);
test.expected_current = model;
efl_ui_view_model_set(widget, model);
ck_assert_int_eq(test.called, EINA_TRUE);
ck_assert_int_eq(test.previous, EINA_FALSE);
ck_assert_int_eq(test.current, EINA_TRUE);
test.called = EINA_FALSE;
test.expected_current = NULL;
efl_ui_view_model_set(widget, NULL);
ck_assert_int_eq(test.called, EINA_TRUE);
ck_assert_int_eq(test.previous, EINA_TRUE);
ck_assert_int_eq(test.current, EINA_FALSE);
}
EFL_END_TEST
void
efl_ui_view_behavior_test(TCase *tc)
{
tcase_add_test(tc, model_change_event);
}

View File

@ -18,6 +18,7 @@ void efl_ui_clickable_behavior_test(TCase *tc);
void efl_ui_format_behavior_test(TCase *tc);
void efl_ui_range_display_behavior_test(TCase *tc);
void efl_ui_range_display_interactive_behavior_test(TCase *tc);
void efl_ui_view_behavior_test(TCase *tc);
void efl_test_container_content_equal(Efl_Ui_Widget **wid, unsigned int len);
void efl_test_container_expect_evt_content_added(Efl_Ui_Widget *widget, const Efl_Event_Description *ev, Eina_Bool *flag, void *event_data);

View File

@ -8,6 +8,7 @@ efl_ui_suite_behavior_test_files = files([
'efl_test_format.c',
'efl_test_range_display.c',
'efl_test_range_interactive.c',
'efl_test_ui_view.c',
])
efl_ui_suite_behavior_src = files([

View File

@ -391,24 +391,77 @@ get_me_to_those_events(Eo *obj)
ecore_main_loop_begin();
}
enum
{
NONE = 0,
LEFT = 1 << 0,
RIGHT = 1 << 1,
TOP = 1 << 2,
BOTTOM = 1 << 3,
};
static void
click_object_internal(Eo *obj, int dir)
{
int x, y;
Evas *e = evas_object_evas_get(obj);
Eina_Rect r = efl_gfx_entity_geometry_get(obj);
if (dir & LEFT)
x = r.x + (.1 * r.w);
else if (dir & RIGHT)
x = r.x + (.9 * r.w);
else
x = r.x + r.w / 2;
if (dir & TOP)
y = r.y + (.1 * r.h);
else if (dir & BOTTOM)
y = r.y + (.9 * r.h);
else
y = r.y + r.h / 2;
evas_event_feed_mouse_move(e, x, y, 0, NULL);
evas_event_feed_mouse_down(e, 1, 0, 0, NULL);
evas_event_feed_mouse_up(e, 1, 0, 0, NULL);
}
void
click_object(Eo *obj)
{
Evas *e = evas_object_evas_get(obj);
Eina_Rect r = efl_gfx_entity_geometry_get(obj);
evas_event_feed_mouse_move(e, r.x + r.w / 2, r.y + r.h / 2, 0, NULL);
evas_event_feed_mouse_down(e, 1, 0, 0, NULL);
evas_event_feed_mouse_up(e, 1, 0, 0, NULL);
click_object_internal(obj, NONE);
}
void
click_part(Eo *obj, const char *part)
{
Efl_Part *part_obj = efl_ref(efl_part(obj, part));
Eo *content = efl_content_get(part_obj);
click_object(content);
Eo *content;
int dir = 0;
if (efl_canvas_layout_part_type_get(part_obj) == EFL_CANVAS_LAYOUT_PART_TYPE_SWALLOW)
content = efl_content_get(part_obj);
else
{
content = part_obj;
if (strstr(part, "left"))
dir |= LEFT;
else if (strstr(part, "right"))
dir |= RIGHT;
if (strstr(part, "top"))
dir |= TOP;
else if (strstr(part, "bottom"))
dir |= BOTTOM;
}
click_object_internal(content, dir);
if (efl_isa(content, EFL_LAYOUT_SIGNAL_INTERFACE))
edje_object_message_signal_process(content);
edje_object_message_signal_process(obj);
efl_unref(part_obj);
}
void
event_callback_that_is_called_exactly_one_time_and_sets_a_single_int_data_pointer_when_called(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
{
int *called = data;
ck_assert_int_eq(*called, 0);
*called = 1;
}

View File

@ -13,4 +13,5 @@ void fail_on_errors_setup(void);
void get_me_to_those_events(Eo *obj);
void click_object(Eo *obj);
void click_part(Eo *obj, const char *part);
void event_callback_that_is_called_exactly_one_time_and_sets_a_single_int_data_pointer_when_called(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED);
#endif