bu5hm4n pushed a commit to branch master. http://git.enlightenment.org/core/efl.git/commit/?id=d5445918ec9fd5f6399ed7c4649df9ac72c2be85
commit d5445918ec9fd5f6399ed7c4649df9ac72c2be85 Author: Yeongjong Lee <[email protected]> Date: Fri Apr 12 10:18:04 2019 +0000 ui.box: remove leagcy evas_box from Efl.Ui.Box Remove legacy stuff from Efl.Ui.Box. This expect to improve performance by removing internal function call related evas_box. Reviewed-by: Xavi Artigas <[email protected]> Reviewed-by: Marcel Hollerbach <[email protected]> Differential Revision: https://phab.enlightenment.org/D8417 --- src/lib/elementary/efl_ui_box.c | 476 ++++++++++++-------------------- src/lib/elementary/efl_ui_box.eo | 2 + src/lib/elementary/efl_ui_box_flow.c | 28 +- src/lib/elementary/efl_ui_box_layout.c | 13 +- src/lib/elementary/efl_ui_box_private.h | 20 +- src/lib/elementary/efl_ui_box_stack.c | 14 +- src/tests/elementary/efl_ui_test_box.c | 152 +++++++++- 7 files changed, 348 insertions(+), 357 deletions(-) diff --git a/src/lib/elementary/efl_ui_box.c b/src/lib/elementary/efl_ui_box.c index eec5a645d8..5e33ed8602 100644 --- a/src/lib/elementary/efl_ui_box.c +++ b/src/lib/elementary/efl_ui_box.c @@ -7,86 +7,94 @@ * - removed transition stuff (TODO: add back - needs clean API first) */ -static const char SIG_CHILD_ADDED[] = "child,added"; -static const char SIG_CHILD_REMOVED[] = "child,removed"; -static const Evas_Smart_Cb_Description _smart_callbacks[] = { - {SIG_CHILD_ADDED, ""}, - {SIG_CHILD_REMOVED, ""}, - {NULL, NULL} -}; +#define EFL_UI_BOX_DATA_GET(o, sd) \ + Efl_Ui_Box_Data *sd = efl_data_scope_get(o, EFL_UI_BOX_CLASS) + +void _efl_ui_box_custom_layout(Efl_Ui_Box *ui_box, Efl_Ui_Box_Data *pd); static void -_child_added_cb_proxy(void *data, const Efl_Event *event) +_on_child_size_changed(void *data, const Efl_Event *event EINA_UNUSED) { - Evas_Object *box = data; - Evas_Object_Box_Option *opt = event->info; - - efl_event_callback_legacy_call(box, EFL_CONTAINER_EVENT_CONTENT_ADDED, opt->obj); + Eo *box = data; + efl_pack_layout_request(box); } static void -_child_removed_cb_proxy(void *data, const Efl_Event *event) +_on_child_del(void *data, const Efl_Event *event) { - Evas_Object *box = data; - Evas_Object *child = event->info; + Eo *box = data; + EFL_UI_BOX_DATA_GET(box, sd); - efl_event_callback_legacy_call(box, EFL_CONTAINER_EVENT_CONTENT_REMOVED, child); + sd->children = eina_list_remove(sd->children, event->object); + + efl_pack_layout_request(box); } static void -_sizing_eval(Evas_Object *obj, Efl_Ui_Box_Data *sd) +_on_child_hints_changed(void *data, const Efl_Event *event EINA_UNUSED) { - Evas_Coord minw = -1, minh = -1, maxw = -1, maxh = -1; - Evas_Coord w, h; + Eo *box = data; + efl_pack_layout_request(box); +} - ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd); +EFL_CALLBACKS_ARRAY_DEFINE(efl_ui_box_callbacks, + { EFL_GFX_ENTITY_EVENT_SIZE_CHANGED, _on_child_size_changed }, + { EFL_GFX_ENTITY_EVENT_HINTS_CHANGED, _on_child_hints_changed }, + { EFL_EVENT_DEL, _on_child_del } +); - if (!efl_alive_get(obj)) return; - if (sd->delete_me) - return; +static inline Eina_Bool +_efl_ui_box_child_register(Eo *obj, Efl_Ui_Box_Data *pd, Efl_Gfx_Entity *subobj) +{ + if (!subobj || (efl_canvas_object_render_parent_get(subobj) == obj)) + return EINA_FALSE; - evas_object_size_hint_combined_min_get(wd->resize_obj, &minw, &minh); - evas_object_size_hint_max_get(wd->resize_obj, &maxw, &maxh); - evas_object_size_hint_min_set(obj, minw, minh); - evas_object_size_hint_max_set(obj, maxw, maxh); + if (!efl_ui_widget_sub_object_add(obj, subobj)) + return EINA_FALSE; - evas_object_geometry_get(obj, NULL, NULL, &w, &h); - if (w < minw) w = minw; - if (h < minh) h = minh; - if ((maxw >= 0) && (w > maxw)) w = maxw; - if ((maxh >= 0) && (h > maxh)) h = maxh; - evas_object_resize(obj, w, h); + efl_key_data_set(subobj, "_elm_leaveme", obj); + efl_canvas_group_member_add(obj, subobj); + efl_canvas_object_clipper_set(subobj, pd->clipper); + efl_pack_layout_request(obj); + + efl_event_callback_array_add(subobj, efl_ui_box_callbacks(), obj); + efl_event_callback_call(obj, EFL_CONTAINER_EVENT_CONTENT_ADDED, subobj); + + return EINA_TRUE; } -static void -_on_size_hints_changed(void *data, Evas *e EINA_UNUSED, - Evas_Object *resizeobj, void *event_info EINA_UNUSED) +static inline Eina_Bool +_efl_ui_box_child_unregister(Eo *obj, Efl_Ui_Box_Data *pd EINA_UNUSED, Efl_Gfx_Entity *subobj) { - Efl_Ui_Box *obj = data; - Efl_Ui_Box_Data *pd = efl_data_scope_get(obj, EFL_UI_BOX_CLASS); + if (!subobj || !_elm_widget_sub_object_redirect_to_top(obj, subobj)) + return EINA_FALSE; + + efl_canvas_group_member_remove(obj, subobj); + efl_canvas_object_clipper_set(subobj, NULL); + efl_key_data_set(subobj, "_elm_leaveme", NULL); + efl_pack_layout_request(obj); + + efl_event_callback_array_del(subobj, efl_ui_box_callbacks(), obj); + efl_event_callback_call(obj, EFL_CONTAINER_EVENT_CONTENT_REMOVED, subobj); - if (obj == resizeobj) - efl_pack_layout_request(obj); - else - _sizing_eval(data, pd); + return EINA_TRUE; } static void -_evas_box_custom_layout(Evas_Object *evas_box EINA_UNUSED, - Evas_Object_Box_Data *bd EINA_UNUSED, void *data) +_efl_ui_box_size_hints_changed_cb(void *data EINA_UNUSED, const Efl_Event *ev) { - Efl_Ui_Box *obj = data; - - efl_pack_layout_update(obj); + efl_pack_layout_request(ev->object); } EOLIAN static void _efl_ui_box_homogeneous_set(Eo *obj, Efl_Ui_Box_Data *pd, Eina_Bool homogeneous) { - if (pd->homogeneous == !!homogeneous) + homogeneous = !!homogeneous; + + if (pd->homogeneous == homogeneous) return; - pd->homogeneous = !!homogeneous; + pd->homogeneous = homogeneous; efl_pack_layout_request(obj); } @@ -97,74 +105,55 @@ _efl_ui_box_homogeneous_get(const Eo *obj EINA_UNUSED, Efl_Ui_Box_Data *pd) } EOLIAN static void -_efl_ui_box_efl_pack_layout_layout_update(Eo *obj, Efl_Ui_Box_Data *pd EINA_UNUSED) +_efl_ui_box_efl_pack_layout_layout_update(Eo *obj, Efl_Ui_Box_Data *pd) { - ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd); - Evas_Object_Box_Data *bd; - - bd = evas_object_smart_data_get(wd->resize_obj); - _efl_ui_box_custom_layout(obj, bd); - efl_event_callback_legacy_call(obj, EFL_PACK_EVENT_LAYOUT_UPDATED, NULL); + _efl_ui_box_custom_layout(obj, pd); } EOLIAN static void -_efl_ui_box_efl_canvas_group_group_calculate(Eo *obj, Efl_Ui_Box_Data *pd) +_efl_ui_box_efl_canvas_group_group_calculate(Eo *obj, Efl_Ui_Box_Data *_pd EINA_UNUSED) { - if (pd->recalc) return; - - ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd); - evas_object_smart_need_recalculate_set(wd->resize_obj, EINA_TRUE); - pd->recalc = EINA_TRUE; - evas_object_smart_calculate(wd->resize_obj); - pd->recalc = EINA_FALSE; + efl_pack_layout_update(obj); } EOLIAN static void -_efl_ui_box_efl_canvas_group_group_add(Eo *obj, Efl_Ui_Box_Data *_pd EINA_UNUSED) +_efl_ui_box_efl_gfx_entity_size_set(Eo *obj, Efl_Ui_Box_Data *_pd EINA_UNUSED, Eina_Size2D sz) { - Evas *e = evas_object_evas_get(obj); + efl_gfx_entity_size_set(efl_super(obj, MY_CLASS), sz); + efl_canvas_group_change(obj); +} - ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd); - elm_widget_resize_object_set(obj, evas_object_box_add(e)); - evas_object_box_layout_set(wd->resize_obj, _evas_box_custom_layout, obj, NULL); +EOLIAN static void +_efl_ui_box_efl_gfx_entity_position_set(Eo *obj, Efl_Ui_Box_Data *_pd EINA_UNUSED, Eina_Position2D pos) +{ + efl_gfx_entity_position_set(efl_super(obj, MY_CLASS), pos); + efl_canvas_group_change(obj); +} - evas_object_event_callback_add(wd->resize_obj, EVAS_CALLBACK_CHANGED_SIZE_HINTS, _on_size_hints_changed, obj); - evas_object_event_callback_add(obj, EVAS_CALLBACK_CHANGED_SIZE_HINTS, _on_size_hints_changed, obj); +EOLIAN static void +_efl_ui_box_efl_canvas_group_group_add(Eo *obj, Efl_Ui_Box_Data *pd) +{ + pd->clipper = efl_add(EFL_CANVAS_RECTANGLE_CLASS, obj); + evas_object_static_clip_set(pd->clipper, EINA_TRUE); + efl_gfx_entity_geometry_set(pd->clipper, EINA_RECT(-49999, -49999, 99999, 99999)); + efl_canvas_group_member_add(obj, pd->clipper); + efl_ui_widget_sub_object_add(obj, pd->clipper); efl_canvas_group_add(efl_super(obj, MY_CLASS)); elm_widget_sub_object_parent_add(obj); - efl_event_callback_add(wd->resize_obj, EVAS_BOX_EVENT_CHILD_ADDED, _child_added_cb_proxy, obj); - efl_event_callback_add(wd->resize_obj, EVAS_BOX_EVENT_CHILD_REMOVED, _child_removed_cb_proxy, obj); - - elm_widget_can_focus_set(obj, EINA_FALSE); + efl_ui_widget_focus_allow_set(obj, EINA_FALSE); elm_widget_highlight_ignore_set(obj, EINA_TRUE); + + efl_event_callback_add(obj, EFL_GFX_ENTITY_EVENT_HINTS_CHANGED, + _efl_ui_box_size_hints_changed_cb, NULL); } EOLIAN static void -_efl_ui_box_efl_canvas_group_group_del(Eo *obj, Efl_Ui_Box_Data *sd) +_efl_ui_box_efl_canvas_group_group_del(Eo *obj, Efl_Ui_Box_Data *_pd EINA_UNUSED) { - Eina_List *l; - Evas_Object *child; - - sd->delete_me = EINA_TRUE; - - ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd); - evas_object_event_callback_del_full - (wd->resize_obj, EVAS_CALLBACK_CHANGED_SIZE_HINTS, - _on_size_hints_changed, obj); - - /* let's make our box object the *last* to be processed, since it - * may (smart) parent other sub objects here */ - EINA_LIST_FOREACH (wd->subobjs, l, child) - { - if (child == wd->resize_obj) - { - wd->subobjs = - eina_list_demote_list(wd->subobjs, l); - break; - } - } + efl_event_callback_del(obj, EFL_GFX_ENTITY_EVENT_HINTS_CHANGED, + _efl_ui_box_size_hints_changed_cb, NULL); efl_canvas_group_del(efl_super(obj, MY_CLASS)); } @@ -174,10 +163,10 @@ _efl_ui_box_efl_object_constructor(Eo *obj, Efl_Ui_Box_Data *pd) { obj = efl_constructor(efl_super(obj, MY_CLASS)); efl_canvas_object_type_set(obj, MY_CLASS_NAME); - evas_object_smart_callbacks_descriptions_set(obj, _smart_callbacks); efl_access_object_access_type_set(obj, EFL_ACCESS_TYPE_SKIPPED); efl_access_object_role_set(obj, EFL_ACCESS_ROLE_FILLER); + pd->dir = EFL_UI_DIR_VERTICAL; pd->align.h = 0.5; pd->align.v = 0.5; @@ -187,48 +176,34 @@ _efl_ui_box_efl_object_constructor(Eo *obj, Efl_Ui_Box_Data *pd) /* CLEAN API BELOW */ EOLIAN static int -_efl_ui_box_efl_container_content_count(Eo *obj, Efl_Ui_Box_Data *pd EINA_UNUSED) +_efl_ui_box_efl_container_content_count(Eo *obj EINA_UNUSED, Efl_Ui_Box_Data *pd) { - Evas_Object_Box_Data *bd; - - ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd, 0); - - bd = evas_object_smart_data_get(wd->resize_obj); - return bd ? eina_list_count(bd->children) : 0; + return eina_list_count(pd->children); } EOLIAN static Eina_Bool _efl_ui_box_efl_pack_pack_clear(Eo *obj, Efl_Ui_Box_Data *pd) { - Eina_Bool ret; - - ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd, EINA_FALSE); + Eo *child; + EINA_LIST_FREE(pd->children, child) + { + efl_event_callback_array_del(child, efl_ui_box_callbacks(), obj); + efl_del(child); + } - ret = evas_object_box_remove_all(wd->resize_obj, EINA_TRUE); - _sizing_eval(obj, pd); + efl_pack_layout_request(obj); - return ret; + return EINA_TRUE; } EOLIAN static Eina_Bool _efl_ui_box_efl_pack_unpack_all(Eo *obj, Efl_Ui_Box_Data *pd) { - Evas_Object_Box_Data *bd; - Evas_Object_Box_Option *opt; - Eina_List *l; - Eina_Bool ret; + Eo *child; + Eina_Bool ret = EINA_TRUE; - ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd, EINA_FALSE); - - /* set this to block _sizing_eval() calls */ - pd->delete_me = EINA_TRUE; - bd = evas_object_smart_data_get(wd->resize_obj); - EINA_LIST_FOREACH(bd->children, l, opt) - _elm_widget_sub_object_redirect_to_top(obj, opt->obj); - pd->delete_me = EINA_FALSE; - - ret = evas_object_box_remove_all(wd->resize_obj, EINA_FALSE); - _sizing_eval(obj, pd); + EINA_LIST_FREE(pd->children, child) + ret &= _efl_ui_box_child_unregister(obj, pd, child); return ret; } @@ -236,16 +211,12 @@ _efl_ui_box_efl_pack_unpack_all(Eo *obj, Efl_Ui_Box_Data *pd) EOLIAN static Eina_Bool _efl_ui_box_efl_pack_unpack(Eo *obj, Efl_Ui_Box_Data *pd, Efl_Gfx_Entity *subobj) { - Eina_Bool ret = EINA_FALSE; - ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd, EINA_FALSE); + if (!_efl_ui_box_child_unregister(obj, pd, subobj)) + return EINA_FALSE; - if (evas_object_box_remove(wd->resize_obj, subobj)) - { - ret = _elm_widget_sub_object_redirect_to_top(obj, subobj); - _sizing_eval(obj, pd); - } + pd->children = eina_list_remove(pd->children, subobj); - return ret; + return EINA_TRUE; } EOLIAN static Eina_Bool @@ -255,133 +226,91 @@ _efl_ui_box_efl_pack_pack(Eo *obj, Efl_Ui_Box_Data *pd EINA_UNUSED, Efl_Gfx_Enti } EOLIAN static Eina_Bool -_efl_ui_box_efl_pack_linear_pack_end(Eo *obj, Efl_Ui_Box_Data *pd EINA_UNUSED, Efl_Gfx_Entity *subobj) +_efl_ui_box_efl_pack_linear_pack_end(Eo *obj, Efl_Ui_Box_Data *pd, Efl_Gfx_Entity *subobj) { - Eina_Bool ret; - - ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd, EINA_FALSE); + if (!_efl_ui_box_child_register(obj, pd, subobj)) + return EINA_FALSE; - ret = elm_widget_sub_object_add(obj, subobj); - ret &= (evas_object_box_append(wd->resize_obj, subobj) != NULL); + pd->children = eina_list_append(pd->children, subobj); - return ret; + return EINA_TRUE; } EOLIAN static Eina_Bool -_efl_ui_box_efl_pack_linear_pack_begin(Eo *obj, Efl_Ui_Box_Data *_pd EINA_UNUSED, Efl_Gfx_Entity *subobj) +_efl_ui_box_efl_pack_linear_pack_begin(Eo *obj, Efl_Ui_Box_Data *pd, Efl_Gfx_Entity *subobj) { - Eina_Bool ret; - - ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd, EINA_FALSE); + if (!_efl_ui_box_child_register(obj, pd, subobj)) + return EINA_FALSE; - ret = elm_widget_sub_object_add(obj, subobj); - ret &= (evas_object_box_prepend(wd->resize_obj, subobj) != NULL); + pd->children = eina_list_prepend(pd->children, subobj); - return ret; + return EINA_TRUE; } EOLIAN static Eina_Bool -_efl_ui_box_efl_pack_linear_pack_before(Eo *obj, Efl_Ui_Box_Data *_pd EINA_UNUSED, Efl_Gfx_Entity *subobj, const Efl_Gfx_Entity *existing) +_efl_ui_box_efl_pack_linear_pack_before(Eo *obj, Efl_Ui_Box_Data *pd, Efl_Gfx_Entity *subobj, const Efl_Gfx_Entity *existing) { - ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd, EINA_FALSE); - - if (!elm_widget_sub_object_add(obj, subobj)) + if (!_efl_ui_box_child_register(obj, pd, subobj)) return EINA_FALSE; - if (!evas_object_box_insert_before(wd->resize_obj, subobj, existing)) - { - elm_widget_sub_object_del(obj, subobj); - return EINA_FALSE; - } + pd->children = eina_list_prepend_relative(pd->children, subobj, existing); return EINA_TRUE; } EOLIAN static Eina_Bool -_efl_ui_box_efl_pack_linear_pack_after(Eo *obj, Efl_Ui_Box_Data *_pd EINA_UNUSED, Efl_Gfx_Entity *subobj, const Efl_Gfx_Entity *existing) +_efl_ui_box_efl_pack_linear_pack_after(Eo *obj, Efl_Ui_Box_Data *pd, Efl_Gfx_Entity *subobj, const Efl_Gfx_Entity *existing) { - ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd, EINA_FALSE); - - if (!elm_widget_sub_object_add(obj, subobj)) + if (!_efl_ui_box_child_register(obj, pd, subobj)) return EINA_FALSE; - if (!evas_object_box_insert_after(wd->resize_obj, subobj, existing)) - { - elm_widget_sub_object_del(obj, subobj); - return EINA_FALSE; - } + pd->children = eina_list_append_relative(pd->children, subobj, existing); return EINA_TRUE; } EOLIAN static Eina_Bool -_efl_ui_box_efl_pack_linear_pack_at(Eo *obj, Efl_Ui_Box_Data *pd EINA_UNUSED, - Efl_Gfx_Entity *subobj, int index) +_efl_ui_box_efl_pack_linear_pack_at(Eo *obj, Efl_Ui_Box_Data *pd, Efl_Gfx_Entity *subobj, int index) { - if (!index) + int count = eina_list_count(pd->children); + + if (index < -count) return efl_pack_begin(obj, subobj); - else if (index == -1) + + if (index >= count) return efl_pack_end(obj, subobj); - else - { - Evas_Object_Box_Data *bd; - int cnt; - - ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd, EINA_FALSE); - - bd = evas_object_smart_data_get(wd->resize_obj); - cnt = eina_list_count(bd ? bd->children : NULL); - if (!cnt) - index = 0; - else - { - index %= cnt; - if (index < 0) index += cnt; - } - return (evas_object_box_insert_at(wd->resize_obj, subobj, index) != NULL); - } -} -static inline Efl_Gfx_Entity * -_box_item(Evas_Object_Box_Option *opt) -{ - return opt ? opt->obj : NULL; + if (index < 0) + index += count; + + if (!_efl_ui_box_child_register(obj, pd, subobj)) + return EINA_FALSE; + + pd->children = eina_list_prepend_relative_list(pd->children, subobj, + eina_list_nth_list(pd->children, index)); + + return EINA_TRUE; } EOLIAN static Efl_Gfx_Entity * -_efl_ui_box_efl_pack_linear_pack_content_get(Eo *obj, Efl_Ui_Box_Data *pd EINA_UNUSED, - int index) +_efl_ui_box_efl_pack_linear_pack_content_get(Eo *obj EINA_UNUSED, Efl_Ui_Box_Data *pd, int index) { - Evas_Object_Box_Data *bd; - int cnt; - - ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd, NULL); - bd = evas_object_smart_data_get(wd->resize_obj); - if (!bd || !bd->children) return NULL; + int count = eina_list_count(pd->children); - if (!index) - return _box_item(eina_list_data_get(bd->children)); - else if (index == -1) - return _box_item(eina_list_last_data_get(bd->children)); + if (index <= -count) + return eina_list_data_get(pd->children); - cnt = eina_list_count(bd->children); - if (!cnt) return NULL; + if (index >= count) + return eina_list_last_data_get(pd->children); - if (index >= (cnt - 1)) - return _box_item(eina_list_last_data_get(bd->children)); - else if (index <= (-cnt)) - return _box_item(eina_list_data_get(bd->children)); + if (index < 0) + index += count; - // this should loop only once - while (index < 0) - index += cnt; - - return _box_item(eina_list_nth(bd->children, index)); + return eina_list_nth(pd->children, index); } EOLIAN static Efl_Gfx_Entity * -_efl_ui_box_efl_pack_linear_pack_unpack_at(Eo *obj, Efl_Ui_Box_Data *pd EINA_UNUSED, - int index) +_efl_ui_box_efl_pack_linear_pack_unpack_at(Eo *obj, Efl_Ui_Box_Data *pd EINA_UNUSED, int index) { Efl_Gfx_Entity *content; @@ -395,90 +324,28 @@ _efl_ui_box_efl_pack_linear_pack_unpack_at(Eo *obj, Efl_Ui_Box_Data *pd EINA_UNU } EOLIAN static int -_efl_ui_box_efl_pack_linear_pack_index_get(Eo *obj, Efl_Ui_Box_Data *pd EINA_UNUSED, - const Efl_Gfx_Entity *subobj) +_efl_ui_box_efl_pack_linear_pack_index_get(Eo *obj EINA_UNUSED, Efl_Ui_Box_Data *pd, const Efl_Gfx_Entity *subobj) { - ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd, -1); - Evas_Object_Box_Data *bd; - Evas_Object_Box_Option *opt; - Eina_List *l; - int k = 0; - - if (evas_object_smart_parent_get(subobj) != wd->resize_obj) - goto end; - - bd = evas_object_smart_data_get(wd->resize_obj); - EINA_LIST_FOREACH(bd->children, l, opt) - { - if (opt->obj == subobj) - return k; - k++; - } - -end: - ERR("object %p (%s) is not a child of %p (%s)", - subobj, efl_class_name_get(subobj), obj, efl_class_name_get(obj)); - return -1; + return eina_list_data_idx(pd->children, (Efl_Gfx_Entity *)subobj); } EOLIAN static void _efl_ui_box_efl_pack_layout_layout_request(Eo *obj, Efl_Ui_Box_Data *pd EINA_UNUSED) { - evas_object_smart_need_recalculate_set(obj, EINA_TRUE); -} - -static Eina_Bool -_box_item_iterator_next(Box_Item_Iterator *it, void **data) -{ - Efl_Gfx_Entity *sub; - - if (!eina_iterator_next(it->real_iterator, (void **) &sub)) - return EINA_FALSE; - - if (data) *data = sub; - return EINA_TRUE; -} - -static Eo * -_box_item_iterator_get_container(Box_Item_Iterator *it) -{ - return it->object; -} - -static void -_box_item_iterator_free(Box_Item_Iterator *it) -{ - eina_iterator_free(it->real_iterator); - eina_list_free(it->list); - free(it); + efl_canvas_group_need_recalculate_set(obj, EINA_TRUE); } EOLIAN static Eina_Iterator * -_efl_ui_box_efl_container_content_iterate(Eo *obj, Efl_Ui_Box_Data *pd EINA_UNUSED) +_efl_ui_box_efl_container_content_iterate(Eo *obj EINA_UNUSED, Efl_Ui_Box_Data *pd) { - Box_Item_Iterator *it; - - ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd, NULL); - - it = calloc(1, sizeof(*it)); - if (!it) return NULL; - - EINA_MAGIC_SET(&it->iterator, EINA_MAGIC_ITERATOR); - - it->list = evas_object_box_children_get(wd->resize_obj); - it->real_iterator = eina_list_iterator_new(it->list); - it->iterator.version = EINA_ITERATOR_VERSION; - it->iterator.next = FUNC_ITERATOR_NEXT(_box_item_iterator_next); - it->iterator.get_container = FUNC_ITERATOR_GET_CONTAINER(_box_item_iterator_get_container); - it->iterator.free = FUNC_ITERATOR_FREE(_box_item_iterator_free); - it->object = obj; - - return &it->iterator; + return eina_list_iterator_new(pd->children); } EOLIAN static void _efl_ui_box_efl_ui_direction_direction_set(Eo *obj, Efl_Ui_Box_Data *pd, Efl_Ui_Dir dir) { + if (pd->dir == dir) return; + switch (dir) { case EFL_UI_DIR_RTL: @@ -510,28 +377,24 @@ _efl_ui_box_efl_ui_direction_direction_get(const Eo *obj EINA_UNUSED, Efl_Ui_Box EOLIAN static void _efl_ui_box_efl_pack_pack_padding_set(Eo *obj, Efl_Ui_Box_Data *pd, double h, double v, Eina_Bool scalable) { - - ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd); - + scalable = !!scalable; if (h < 0) h = 0; if (v < 0) v = 0; + + if (EINA_DBL_EQ(pd->pad.h, h) && EINA_DBL_EQ(pd->pad.v, v) && + (pd->pad.scalable == scalable)) + return; + pd->pad.h = h; pd->pad.v = v; - pd->pad.scalable = !!scalable; - if (pd->pad.scalable) - { - double scale = elm_object_scale_get(obj); - evas_object_box_padding_set(wd->resize_obj, h * scale, v * scale); - } - else - evas_object_box_padding_set(wd->resize_obj, h, v); + pd->pad.scalable = scalable; + + efl_pack_layout_request(obj); } EOLIAN static void -_efl_ui_box_efl_pack_pack_padding_get(const Eo *obj, Efl_Ui_Box_Data *pd, double *h, double *v, Eina_Bool *scalable) +_efl_ui_box_efl_pack_pack_padding_get(const Eo *obj EINA_UNUSED, Efl_Ui_Box_Data *pd, double *h, double *v, Eina_Bool *scalable) { - ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd); - if (scalable) *scalable = pd->pad.scalable; if (h) *h = pd->pad.h; if (v) *v = pd->pad.v; @@ -540,16 +403,17 @@ _efl_ui_box_efl_pack_pack_padding_get(const Eo *obj, Efl_Ui_Box_Data *pd, double EOLIAN static void _efl_ui_box_efl_pack_pack_align_set(Eo *obj, Efl_Ui_Box_Data *pd, double h, double v) { - ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd); - if (h < 0) h = -1; + else if (h > 1) h = 1; if (v < 0) v = -1; - if (h > 1) h = 1; - if (v > 1) v = 1; + else if (v > 1) v = 1; + + if (EINA_DBL_EQ(pd->align.h, h) && EINA_DBL_EQ(pd->align.v, v)) + return; + pd->align.h = h; pd->align.v = v; - evas_object_box_align_set(wd->resize_obj, h, v); efl_pack_layout_request(obj); } diff --git a/src/lib/elementary/efl_ui_box.eo b/src/lib/elementary/efl_ui_box.eo index 6ec2da277f..5e5950cd63 100644 --- a/src/lib/elementary/efl_ui_box.eo +++ b/src/lib/elementary/efl_ui_box.eo @@ -30,6 +30,8 @@ class @beta Efl.Ui.Box extends Efl.Ui.Widget implements Efl.Pack_Linear, Efl.Pac implements { Efl.Object.constructor; Efl.Canvas.Group.group_calculate; + Efl.Gfx.Entity.position { set; } + Efl.Gfx.Entity.size { set; } Efl.Container.content_iterate; Efl.Container.content_count; Efl.Ui.Direction.direction { get; set; } diff --git a/src/lib/elementary/efl_ui_box_flow.c b/src/lib/elementary/efl_ui_box_flow.c index 38bcb7d626..2600acffd9 100644 --- a/src/lib/elementary/efl_ui_box_flow.c +++ b/src/lib/elementary/efl_ui_box_flow.c @@ -63,18 +63,14 @@ _row_weight_sort_cb(const void *l1, const void *l2) EOLIAN static void _efl_ui_box_flow_efl_pack_layout_layout_update(Eo *obj, Efl_Ui_Box_Flow_Data *pd EINA_UNUSED) { - Evas_Object_Box_Data *bd; - - ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd); - bd = efl_data_scope_get(wd->resize_obj, EVAS_BOX_CLASS); - Efl_Ui_Box_Data *bcd = efl_data_scope_get(obj, EFL_UI_BOX_CLASS); - Evas_Object_Box_Option *opt; + Efl_Ui_Box_Data *bd = efl_data_scope_get(obj, EFL_UI_BOX_CLASS); + Eo *child; Eina_List *li; Eina_Inlist *inlist = NULL; Item_Calc *items, *item; Row_Calc *rows, *row; Efl_Ui_Container_Item_Hints *hints, *hint; - Eina_Bool axis = !efl_ui_dir_is_horizontal(bcd->dir, EINA_FALSE); + Eina_Bool axis = !efl_ui_dir_is_horizontal(bd->dir, EINA_FALSE); Eina_Bool c_axis = !axis; int want[2] = { 0, 0 }; int rc = 0, count, i = 0, id, item_last = 0; @@ -84,7 +80,7 @@ _efl_ui_box_flow_efl_pack_layout_layout_update(Eo *obj, Efl_Ui_Box_Flow_Data *pd count = eina_list_count(bd->children); if (!count) { - efl_gfx_hint_size_min_set(obj, EINA_SIZE2D(0, 0)); + efl_gfx_hint_size_restricted_min_set(obj, EINA_SIZE2D(0, 0)); return; } @@ -99,20 +95,20 @@ _efl_ui_box_flow_efl_pack_layout_layout_update(Eo *obj, Efl_Ui_Box_Flow_Data *pd #endif // scan all items, get their properties, calculate total weight & min size - EINA_LIST_FOREACH(bd->children, li, opt) + EINA_LIST_FOREACH(bd->children, li, child) { item = &items[i++]; - item->obj = opt->obj; + item->obj = child; hints = item->hints; _efl_ui_container_layout_item_init(item->obj, hints); - if ((bcd->homogeneous && !axis) || box_calc[0].fill) + if ((bd->homogeneous && !axis) || box_calc[0].fill) hints[0].weight = 1; else if (hints[0].weight < 0) hints[0].weight = 0; - if ((bcd->homogeneous && axis) || box_calc[1].fill) + if ((bd->homogeneous && axis) || box_calc[1].fill) hints[1].weight = 1; else if (hints[1].weight < 0) hints[1].weight = 0; @@ -120,7 +116,7 @@ _efl_ui_box_flow_efl_pack_layout_layout_update(Eo *obj, Efl_Ui_Box_Flow_Data *pd if (want[axis] < hints[axis].space) want[axis] = hints[axis].space; - if (bcd->homogeneous) + if (bd->homogeneous) continue; if (i == 1) @@ -150,7 +146,7 @@ _efl_ui_box_flow_efl_pack_layout_layout_update(Eo *obj, Efl_Ui_Box_Flow_Data *pd } // initialize homogeneous properties - if (bcd->homogeneous) + if (bd->homogeneous) { min_sum = 0; for (i = 0; i < count; i++) @@ -198,7 +194,7 @@ _efl_ui_box_flow_efl_pack_layout_layout_update(Eo *obj, Efl_Ui_Box_Flow_Data *pd cross_min_sum += row->cross_space; cross_weight_sum += row->cross_weight; - if (bcd->homogeneous) + if (bd->homogeneous) continue; if (row->weight_sum > 0) @@ -323,7 +319,7 @@ _efl_ui_box_flow_efl_pack_layout_layout_update(Eo *obj, Efl_Ui_Box_Flow_Data *pd row = item->row; - if (bcd->homogeneous) + if (bd->homogeneous) hints[axis].space = row->hgsize; hints[c_axis].space = row->cross_space; sw = hints[0].space - (hints[0].margin[0] + hints[0].margin[1]); diff --git a/src/lib/elementary/efl_ui_box_layout.c b/src/lib/elementary/efl_ui_box_layout.c index 4cc00e0c48..7240cd012c 100644 --- a/src/lib/elementary/efl_ui_box_layout.c +++ b/src/lib/elementary/efl_ui_box_layout.c @@ -28,10 +28,9 @@ _weight_sort_cb(const void *l1, const void *l2) } void -_efl_ui_box_custom_layout(Efl_Ui_Box *ui_box, Evas_Object_Box_Data *bd) +_efl_ui_box_custom_layout(Efl_Ui_Box *ui_box, Efl_Ui_Box_Data *pd) { - Efl_Ui_Box_Data *pd = efl_data_scope_get(ui_box, EFL_UI_BOX_CLASS); - Evas_Object_Box_Option *opt; + Eo *child; Eina_List *li; Eina_Inlist *inlist = NULL; Item_Calc *items, *item; @@ -44,7 +43,7 @@ _efl_ui_box_custom_layout(Efl_Ui_Box *ui_box, Evas_Object_Box_Data *bd) Efl_Ui_Container_Layout_Calc box_calc[2]; /* 0 is x-axis, 1 is y-axis */ - count = eina_list_count(bd->children); + count = eina_list_count(pd->children); if (!count) { efl_gfx_hint_size_restricted_min_set(ui_box, EINA_SIZE2D(0, 0)); @@ -59,10 +58,10 @@ _efl_ui_box_custom_layout(Efl_Ui_Box *ui_box, Evas_Object_Box_Data *bd) #endif // scan all items, get their properties, calculate total weight & min size - EINA_LIST_FOREACH(bd->children, li, opt) + EINA_LIST_FOREACH(pd->children, li, child) { item = &items[i++]; - item->obj = opt->obj; + item->obj = child; hints = item->hints; _efl_ui_container_layout_item_init(item->obj, hints); @@ -200,4 +199,6 @@ _efl_ui_box_custom_layout(Efl_Ui_Box *ui_box, Evas_Object_Box_Data *bd) (box_calc[1].pad * (count - 1)); 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); } diff --git a/src/lib/elementary/efl_ui_box_private.h b/src/lib/elementary/efl_ui_box_private.h index 86a51398d2..5921eaf783 100644 --- a/src/lib/elementary/efl_ui_box_private.h +++ b/src/lib/elementary/efl_ui_box_private.h @@ -10,21 +10,13 @@ #include <Elementary.h> #include "elm_priv.h" -// FIXME: stop using Evas.Box -#include <../evas/canvas/evas_box_eo.h> - -// FIXME: stop using evas box -void _efl_ui_box_custom_layout(Efl_Ui_Box *box, Evas_Object_Box_Data *priv); - typedef struct _Efl_Ui_Box_Data Efl_Ui_Box_Data; -typedef struct _Box_Item_Iterator Box_Item_Iterator; struct _Efl_Ui_Box_Data { Efl_Ui_Dir dir; - Eina_Bool homogeneous : 1; - Eina_Bool delete_me : 1; - Eina_Bool recalc : 1; + Eo *clipper; + Eina_List *children; struct { double h, v; @@ -34,14 +26,8 @@ struct _Efl_Ui_Box_Data struct { double h, v; } align; -}; -struct _Box_Item_Iterator -{ - Eina_Iterator iterator; - Eina_List *list; - Eina_Iterator *real_iterator; - Efl_Ui_Box *object; + Eina_Bool homogeneous : 1; }; #endif diff --git a/src/lib/elementary/efl_ui_box_stack.c b/src/lib/elementary/efl_ui_box_stack.c index 69e72ea586..212368b4c0 100644 --- a/src/lib/elementary/efl_ui_box_stack.c +++ b/src/lib/elementary/efl_ui_box_stack.c @@ -16,8 +16,8 @@ struct _Item_Calc EOLIAN static void _efl_ui_box_stack_efl_pack_layout_layout_update(Eo *obj, void *_pd EINA_UNUSED) { - Evas_Object_Box_Option *opt; - Evas_Object_Box_Data *bd; + Efl_Ui_Box_Data *bd = efl_data_scope_get(obj, EFL_UI_BOX_CLASS); + Eo *child; Efl_Ui_Container_Layout_Calc box_calc[2]; Efl_Ui_Container_Item_Hints *hints; Item_Calc *items, *item; @@ -26,10 +26,6 @@ _efl_ui_box_stack_efl_pack_layout_layout_update(Eo *obj, void *_pd EINA_UNUSED) Evas_Object *old_child = NULL; int i = 0, count; - EINA_SAFETY_ON_FALSE_RETURN(efl_isa(obj, EFL_UI_BOX_CLASS)); - ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd); - bd = efl_data_scope_get(wd->resize_obj, EVAS_BOX_CLASS); - count = eina_list_count(bd->children); if (!count) { @@ -44,13 +40,13 @@ _efl_ui_box_stack_efl_pack_layout_layout_update(Eo *obj, void *_pd EINA_UNUSED) memset(items, 0, count * sizeof(*items)); #endif - EINA_LIST_FOREACH(bd->children, l, opt) + EINA_LIST_FOREACH(bd->children, l, child) { item = &items[i++]; - item->obj = opt->obj; + item->obj = child; hints = item->hints; - _efl_ui_container_layout_item_init(opt->obj, hints); + _efl_ui_container_layout_item_init(child, hints); if (want.w < hints[0].space) want.w = hints[0].space; diff --git a/src/tests/elementary/efl_ui_test_box.c b/src/tests/elementary/efl_ui_test_box.c index b1792c96a4..ca9b0c134e 100644 --- a/src/tests/elementary/efl_ui_test_box.c +++ b/src/tests/elementary/efl_ui_test_box.c @@ -224,9 +224,7 @@ layout_setup() { win = win_add(); - layout = efl_add(EFL_UI_BOX_CLASS, win, - efl_pack_align_set(efl_added, 0.8, 0.2), - efl_ui_direction_set(efl_added, EFL_UI_DIR_VERTICAL)); + layout = efl_add(EFL_UI_BOX_CLASS, win); } static void @@ -254,6 +252,9 @@ EFL_START_TEST (efl_ui_box_layout_update) { int i, max_index = (sizeof(hints) / sizeof(Hint)); + efl_pack_align_set(layout, 0.8, 0.2); + efl_ui_direction_set(layout, EFL_UI_DIR_VERTICAL); + Eo *btn = efl_add(EFL_UI_BUTTON_CLASS, layout, efl_pack_end(layout, efl_added)); @@ -270,6 +271,9 @@ EFL_START_TEST (efl_ui_box_layout_update_pack) int i, max_index2, max_index3; Eo *btn, *btn2, *btn3; + efl_pack_align_set(layout, 0.8, 0.2); + efl_ui_direction_set(layout, EFL_UI_DIR_VERTICAL); + max_index2 = ((sizeof(hints2) / sizeof(Hint)) / 2); max_index3 = ((sizeof(hints3) / sizeof(Hint)) / 3); @@ -364,6 +368,8 @@ EFL_START_TEST (efl_ui_box_size) Eo *btn, *btn2, *btn3; Eina_Size2D min, user_min; + efl_ui_direction_set(layout, EFL_UI_DIR_VERTICAL); + btn = efl_add(EFL_UI_BUTTON_CLASS, layout, efl_gfx_hint_size_min_set(efl_added, EINA_SIZE2D(100, 100)), efl_pack_end(layout, efl_added)); @@ -407,6 +413,144 @@ EFL_START_TEST (efl_ui_box_size) } EFL_END_TEST +EFL_START_TEST (efl_ui_box_pack_unpack) +{ +#define BTN_NUM 6 + Eo *o, *btn[BTN_NUM]; + Eina_Iterator *itr; + int i; + + for (i = 0; i < BTN_NUM; i++) + btn[i] = efl_add(EFL_UI_BUTTON_CLASS, layout); + + //pack test + ck_assert(efl_pack(layout, btn[1])); + ck_assert_ptr_eq(efl_pack_content_get(layout, 0), btn[1]); + ck_assert_int_eq(efl_pack_index_get(layout, btn[1]), 0); + ck_assert(!efl_pack_end(layout, btn[1])); + ck_assert(!efl_pack(layout, NULL)); + ck_assert(efl_pack_after(layout, btn[3], btn[1])); + ck_assert_ptr_eq(efl_pack_content_get(layout, 1), btn[3]); + ck_assert_int_eq(efl_pack_index_get(layout, btn[3]), 1); + ck_assert(efl_pack_after(layout, btn[5], NULL)); + ck_assert_ptr_eq(efl_pack_content_get(layout, 2), btn[5]); + ck_assert_int_eq(efl_pack_index_get(layout, btn[5]), 2); + ck_assert_ptr_eq(efl_pack_content_get(layout, -1), btn[5]); + ck_assert_int_eq(efl_pack_index_get(layout, btn[5]), 2); + ck_assert(!efl_pack_after(layout, btn[5], NULL)); + ck_assert(!efl_pack_after(layout, NULL, btn[5])); + ck_assert(efl_pack_before(layout, btn[4], btn[5])); + ck_assert(efl_pack_begin(layout, btn[0])); + ck_assert_ptr_eq(efl_pack_content_get(layout, 0), btn[0]); + ck_assert_int_eq(efl_pack_index_get(layout, btn[0]), 0); + ck_assert(efl_pack_at(layout, btn[2], 2)); + ck_assert_ptr_eq(efl_pack_content_get(layout, 2), btn[2]); + ck_assert_int_eq(efl_pack_index_get(layout, btn[2]), 2); + + ck_assert_int_eq(efl_content_count(layout), BTN_NUM); + + i = 0; + itr = efl_content_iterate(layout); + EINA_ITERATOR_FOREACH(itr, o) + { + ck_assert_ptr_eq(o, btn[i++]); + } + eina_iterator_free(itr); + + /* btn array index : 0 1 2 3 4 5 + * children index : 0 1 2 3 4 5 + * negative index : -6 -5 -4 -3 -2 -1 + */ + //negative index test + for (i = -1; i >= -BTN_NUM; i--) + { + o = efl_pack_content_get(layout, i); + ck_assert_ptr_eq(o, btn[BTN_NUM + i]); + ck_assert_int_eq(efl_pack_index_get(layout, o), BTN_NUM + i); + } + + //unpack test + ck_assert_ptr_eq(efl_pack_unpack_at(layout, 2), btn[2]); + ck_assert(!efl_pack_unpack(layout, btn[2])); + efl_pack_at(layout, btn[2], 2); + ck_assert(efl_pack_unpack(layout, efl_pack_content_get(layout, 2))); + ck_assert(!efl_pack_unpack(layout, btn[2])); + + efl_pack_at(layout, btn[2], 2); + ck_assert_ptr_eq(efl_pack_unpack_at(layout, efl_pack_index_get(layout, btn[2])), btn[2]); + + ck_assert(!efl_pack_unpack(layout, NULL)); + ck_assert_int_eq(efl_content_count(layout), BTN_NUM - 1); + + efl_pack_unpack_all(layout); + ck_assert_int_eq(efl_content_count(layout), 0); + ck_assert(!efl_invalidated_get(btn[0])); + + for (i = 0; i < BTN_NUM; i++) + efl_pack_end(layout, btn[i]); + + efl_pack_clear(layout); + ck_assert_int_eq(efl_content_count(layout), 0); + ck_assert(efl_invalidated_get(btn[0])); +#undef BTN_NUM +} +EFL_END_TEST + +EFL_START_TEST (efl_ui_box_properties) +{ + double h, v; + Eina_Bool b; + + //align test + efl_pack_align_get(layout, &h, &v); + ck_assert(EINA_DBL_EQ(h, 0.5)); + ck_assert(EINA_DBL_EQ(v, 0.5)); + + efl_pack_align_set(layout, 0.3, 0.8234); + efl_pack_align_get(layout, &h, &v); + ck_assert(EINA_DBL_EQ(h, 0.3)); + ck_assert(EINA_DBL_EQ(v, 0.8234)); + + efl_pack_align_set(layout, -0.23, 123); + efl_pack_align_get(layout, &h, &v); + ck_assert(EINA_DBL_EQ(h, -1)); + ck_assert(EINA_DBL_EQ(v, 1)); + + //padding test + efl_pack_padding_get(layout, &h, &v, &b); + ck_assert(EINA_DBL_EQ(h, 0.0)); + ck_assert(EINA_DBL_EQ(v, 0.0)); + ck_assert_int_eq(b, 0); + + efl_pack_padding_set(layout, 0.3, 0.8234, 1); + efl_pack_padding_get(layout, &h, &v, &b); + ck_assert(EINA_DBL_EQ(h, 0.3)); + ck_assert(EINA_DBL_EQ(v, 0.8234)); + ck_assert_int_eq(b, 1); + + efl_pack_padding_set(layout, -1.23, 123, 45); + efl_pack_padding_get(layout, &h, &v, &b); + ck_assert(EINA_DBL_EQ(h, 0)); + ck_assert(EINA_DBL_EQ(v, 123)); + ck_assert_int_eq(b, 1); + + //direction test + ck_assert_int_eq(efl_ui_direction_get(layout), EFL_UI_DIR_VERTICAL); + + efl_ui_direction_set(layout, EFL_UI_DIR_DEFAULT); + ck_assert_int_eq(efl_ui_direction_get(layout), EFL_UI_DIR_VERTICAL); + + efl_ui_direction_set(layout, EFL_UI_DIR_HORIZONTAL); + ck_assert_int_eq(efl_ui_direction_get(layout), EFL_UI_DIR_HORIZONTAL); + + //homogeneous test + ck_assert_int_eq(efl_ui_box_homogeneous_get(layout), 0); + + efl_ui_box_homogeneous_set(layout, 123); + ck_assert_int_eq(efl_ui_box_homogeneous_get(layout), 1); +} +EFL_END_TEST + void efl_ui_test_box(TCase *tc) { tcase_add_checked_fixture(tc, layout_setup, layout_teardown); @@ -414,4 +558,6 @@ void efl_ui_test_box(TCase *tc) tcase_add_test(tc, efl_ui_box_layout_update); tcase_add_test(tc, efl_ui_box_layout_update_pack); tcase_add_test(tc, efl_ui_box_size); + tcase_add_test(tc, efl_ui_box_pack_unpack); + tcase_add_test(tc, efl_ui_box_properties); } --
