diff --git a/src/lib/elementary/efl_ui_relative_layout.c b/src/lib/elementary/efl_ui_relative_layout.c index d0d5ff441e..530179cab4 100644 --- a/src/lib/elementary/efl_ui_relative_layout.c +++ b/src/lib/elementary/efl_ui_relative_layout.c @@ -27,29 +27,25 @@ _chain_sort_cb(const void *l1, const void *l2) static void _on_child_size_changed(void *data, const Efl_Event *event EINA_UNUSED) { - Efl_Ui_Relative_Layout_Data *pd = data; + Efl_Ui_Relative_Layout *obj = data; - efl_pack_layout_request(pd->obj); + efl_pack_layout_request(obj); } static void _on_child_hints_changed(void *data, const Efl_Event *event EINA_UNUSED) { - Efl_Ui_Relative_Layout_Data *pd = data; + Efl_Ui_Relative_Layout *obj = data; - efl_pack_layout_request(pd->obj); + efl_pack_layout_request(obj); } static void _on_child_del(void *data, const Efl_Event *event) { - Efl_Ui_Relative_Layout_Data *pd = data; + Efl_Ui_Relative_Layout *obj = data; - if (eina_hash_del_by_key(pd->children, &event->object)) - efl_pack_layout_request(pd->obj); - else - ERR("child(%p(%s)) is not registered", event->object, - efl_class_name_get(event->object)); + efl_pack_unpack(obj, event->object); } EFL_CALLBACKS_ARRAY_DEFINE(efl_ui_relative_layout_callbacks, @@ -82,7 +78,7 @@ _efl_ui_relative_layout_register(Efl_Ui_Relative_Layout_Data *pd, Eo *child) efl_key_data_set(child, "_elm_leaveme", pd->obj); efl_canvas_object_clipper_set(child, pd->clipper); - efl_event_callback_array_add(child, efl_ui_relative_layout_callbacks(), pd); + efl_event_callback_array_add(child, efl_ui_relative_layout_callbacks(), pd->obj); efl_canvas_group_member_add(pd->obj, child); efl_canvas_group_change(pd->obj); @@ -366,19 +362,26 @@ _hash_free_cb(void *data) { Efl_Ui_Relative_Layout_Child *child = data; + efl_canvas_group_member_remove(child->layout, child->obj); + efl_canvas_object_clipper_set(child->obj, NULL); + efl_key_data_set(child->obj, "_elm_leaveme", NULL); + efl_event_callback_array_del(child->obj, efl_ui_relative_layout_callbacks(), + child->layout); + + if (!efl_invalidated_get(child->obj)) + _elm_widget_sub_object_redirect_to_top(child->layout, child->obj); + free(child); } -static Eina_Bool -_hash_free_foreach_cb(const Eina_Hash *hash EINA_UNUSED, const void *key EINA_UNUSED, - void *data, void *fdata EINA_UNUSED) +static void +_hash_clear_cb(void *data) { Efl_Ui_Relative_Layout_Child *child = data; - _elm_widget_sub_object_redirect_to_top(child->layout, child->obj); - _hash_free_cb(child); - - return EINA_TRUE; + efl_event_callback_array_del(child->obj, efl_ui_relative_layout_callbacks(), + child->layout); + efl_del(child->obj); } static Eina_Bool @@ -558,14 +561,9 @@ _efl_ui_relative_layout_efl_object_constructor(Eo *obj, Efl_Ui_Relative_Layout_D EOLIAN static void _efl_ui_relative_layout_efl_object_invalidate(Eo *obj, Efl_Ui_Relative_Layout_Data *pd) { - Eo *child; - efl_invalidate(efl_super(obj, MY_CLASS)); - EINA_LIST_FREE(pd->children, child) - { - efl_event_callback_array_del(child, efl_ui_relative_layout_callbacks(), pd); - } + eina_hash_free_buckets(pd->children); } EOLIAN static void @@ -578,35 +576,101 @@ _efl_ui_relative_layout_efl_object_destructor(Eo *obj, Efl_Ui_Relative_Layout_Da efl_destructor(efl_super(obj, MY_CLASS)); } -EOLIAN static void -_efl_ui_relative_layout_unregister(Eo *obj, Efl_Ui_Relative_Layout_Data *pd, Efl_Object *child) +EOLIAN static Eina_Bool +_efl_ui_relative_layout_efl_pack_pack(Eo *obj EINA_UNUSED, Efl_Ui_Relative_Layout_Data *pd, Efl_Gfx_Entity *subobj) { - _elm_widget_sub_object_redirect_to_top(obj, child); - if (eina_hash_del_by_key(pd->children, &child)) - { - efl_canvas_group_member_remove(obj, child); - efl_canvas_object_clipper_set(child, NULL); - efl_key_data_set(child, "_elm_leaveme", NULL); - efl_event_callback_array_del(child, efl_ui_relative_layout_callbacks(), pd); - efl_pack_layout_request(obj); - } - else - { - ERR("child(%p(%s)) is not registered", child, efl_class_name_get(child)); - } + EINA_SAFETY_ON_FALSE_RETURN_VAL(subobj, EINA_FALSE); + EINA_SAFETY_ON_TRUE_RETURN_VAL(!!eina_hash_find(pd->children, &subobj), EINA_FALSE); + + return !!_efl_ui_relative_layout_register(pd, subobj); } -EOLIAN static void -_efl_ui_relative_layout_unregister_all(Eo *obj, Efl_Ui_Relative_Layout_Data *pd) +EOLIAN static Eina_Bool +_efl_ui_relative_layout_efl_pack_unpack(Eo *obj, Efl_Ui_Relative_Layout_Data *pd, Efl_Object *child) { - eina_hash_foreach(pd->children, _hash_free_foreach_cb, NULL); + if (!eina_hash_del_by_key(pd->children, &child)) + { + ERR("child(%p(%s)) is not registered", child, efl_class_name_get(child)); + return EINA_FALSE; + } + efl_pack_layout_request(obj); + + return EINA_TRUE; +} + +EOLIAN static Eina_Bool +_efl_ui_relative_layout_efl_pack_unpack_all(Eo *obj, Efl_Ui_Relative_Layout_Data *pd) +{ + eina_hash_free_buckets(pd->children); + efl_pack_layout_request(obj); + + return EINA_TRUE; +} + +EOLIAN static Eina_Bool +_efl_ui_relative_layout_efl_pack_pack_clear(Eo *obj, Efl_Ui_Relative_Layout_Data *pd) +{ + eina_hash_free_cb_set(pd->children, _hash_clear_cb); + eina_hash_free_buckets(pd->children); + eina_hash_free_cb_set(pd->children, _hash_free_cb); + + efl_pack_layout_request(obj); + + return EINA_TRUE; +} + +static Eina_Bool +_efl_ui_relative_layout_content_iterator_next(Efl_Ui_Relative_Layout_Content_Iterator *it, void **data) +{ + Efl_Ui_Relative_Layout_Child *child; + + if (!eina_iterator_next(it->real_iterator, (void **) &child)) + return EINA_FALSE; + + if (data) *data = child->obj; + return EINA_TRUE; +} + +static Eo * +_efl_ui_relative_layout_content_iterator_get_container(Efl_Ui_Relative_Layout_Content_Iterator *it) +{ + return it->relative_layout; +} + +static void +_efl_ui_relative_layout_content_iterator_free(Efl_Ui_Relative_Layout_Content_Iterator *it) +{ + eina_iterator_free(it->real_iterator); + free(it); } EOLIAN static Eina_Iterator * -_efl_ui_relative_layout_children_iterate(Eo *obj EINA_UNUSED, Efl_Ui_Relative_Layout_Data *pd) +_efl_ui_relative_layout_efl_container_content_iterate(Eo *obj, Efl_Ui_Relative_Layout_Data *pd) { - return eina_hash_iterator_data_new(pd->children); + Efl_Ui_Relative_Layout_Content_Iterator *it; + + it = calloc(1, sizeof(*it)); + if (!it) return NULL; + + EINA_MAGIC_SET(&it->iterator, EINA_MAGIC_ITERATOR); + + it->relative_layout = obj; + it->real_iterator = eina_hash_iterator_data_new(pd->children); + + it->iterator.version = EINA_ITERATOR_VERSION; + it->iterator.next = FUNC_ITERATOR_NEXT(_efl_ui_relative_layout_content_iterator_next); + it->iterator.get_container = FUNC_ITERATOR_GET_CONTAINER( + _efl_ui_relative_layout_content_iterator_get_container); + it->iterator.free = FUNC_ITERATOR_FREE(_efl_ui_relative_layout_content_iterator_free); + + return &it->iterator; +} + +EOLIAN static int +_efl_ui_relative_layout_efl_container_content_count(Eo *obj EINA_UNUSED, Efl_Ui_Relative_Layout_Data *pd) +{ + return eina_hash_population(pd->children); } EFL_UI_RELATIVE_LAYOUT_RELATION_SET_GET(left, LEFT); diff --git a/src/lib/elementary/efl_ui_relative_layout.eo b/src/lib/elementary/efl_ui_relative_layout.eo index b312070daa..03b31831bb 100644 --- a/src/lib/elementary/efl_ui_relative_layout.eo +++ b/src/lib/elementary/efl_ui_relative_layout.eo @@ -1,4 +1,4 @@ -class @beta Efl.Ui.Relative_Layout extends Efl.Ui.Widget implements Efl.Pack_Layout +class @beta Efl.Ui.Relative_Layout extends Efl.Ui.Widget implements Efl.Pack_Layout, Efl.Pack { [[The relative layout class. @@ -53,25 +53,18 @@ class @beta Efl.Ui.Relative_Layout extends Efl.Ui.Widget implements Efl.Pack_Lay ranging from 0.0 to 1.0.]] } } - unregister { - [[Remove all relations of the child.]] - params { - @in child: Efl.Object; [[The child to unregister]] - } - } - unregister_all { - [[Remove all relations from the registered children. ]] - } - children_iterate { - [[Begin iterating over this object's children.]] - return: iterator @owned @warn_unused; [[Iterator to object children.]] - } } implements { Efl.Object.constructor; Efl.Object.invalidate; Efl.Object.destructor; Efl.Canvas.Group.group_calculate; + Efl.Pack.pack_clear; + Efl.Pack.unpack_all; + Efl.Pack.unpack; + Efl.Pack.pack; + Efl.Container.content_iterate; + Efl.Container.content_count; Efl.Gfx.Entity.position { set; } Efl.Gfx.Entity.size { set; } Efl.Pack_Layout.layout_update; diff --git a/src/lib/elementary/efl_ui_relative_layout_private.h b/src/lib/elementary/efl_ui_relative_layout_private.h index e0f2abfee0..2aa150a333 100644 --- a/src/lib/elementary/efl_ui_relative_layout_private.h +++ b/src/lib/elementary/efl_ui_relative_layout_private.h @@ -21,6 +21,7 @@ typedef struct _Efl_Ui_Relative_Layout_Data Efl_Ui_Relative_Layout_Data; typedef struct _Efl_Ui_Relative_Layout_Child Efl_Ui_Relative_Layout_Child; typedef struct _Efl_Ui_Relative_Layout_Calc Efl_Ui_Relative_Layout_Calc; typedef struct _Efl_Ui_Relative_Layout_Relation Efl_Ui_Relative_Layout_Relation; +typedef struct _Efl_Ui_Relative_Layout_Content_Iterator Efl_Ui_Relative_Layout_Content_Iterator; struct _Efl_Ui_Relative_Layout_Calc { @@ -68,6 +69,13 @@ struct _Efl_Ui_Relative_Layout_Child Efl_Ui_Relative_Layout_Calc calc; }; +struct _Efl_Ui_Relative_Layout_Content_Iterator +{ + Eina_Iterator iterator; + Eina_Iterator *real_iterator; + Eo *relative_layout; +}; + #define EFL_UI_RELATIVE_LAYOUT_RELATION_SET_GET(direction, DIRECTION) \ EOLIAN static void \ _efl_ui_relative_layout_relation_ ## direction ## _set(Eo *obj, Efl_Ui_Relative_Layout_Data *pd, Eo *child, Eo *target, double relative) \ diff --git a/src/tests/elementary/efl_ui_test_relative_layout.c b/src/tests/elementary/efl_ui_test_relative_layout.c index 3027bdb082..06031aad8c 100644 --- a/src/tests/elementary/efl_ui_test_relative_layout.c +++ b/src/tests/elementary/efl_ui_test_relative_layout.c @@ -243,8 +243,7 @@ EFL_START_TEST (efl_ui_relative_layout_layout_update) { int i, max_index = (sizeof(hints) / sizeof(Hint)); - Eo *btn = efl_add(EFL_UI_BUTTON_CLASS, layout, - efl_ui_relative_layout_relation_left_set(layout, efl_added, NULL, 0.0)); + Eo *btn = efl_add(EFL_UI_BUTTON_CLASS, layout, efl_pack(layout, efl_added)); for (i = 0; i < max_index; i++) { @@ -342,6 +341,38 @@ EFL_START_TEST (efl_ui_relative_layout_relation_set) } EFL_END_TEST +EFL_START_TEST (efl_ui_relative_layout_pack) +{ + Eo *btn[3], *child; + Eina_Iterator *it; + int i; + + for (i = 0; i < 3; i++) + btn[i] = efl_add(EFL_UI_BUTTON_CLASS, layout, efl_pack(layout, efl_added)); + ck_assert_int_eq(efl_content_count(layout), 3); + + it = efl_content_iterate(layout); + EINA_ITERATOR_FOREACH(it, child) + ck_assert_ptr_eq(layout, efl_canvas_object_render_parent_get(child)); + eina_iterator_free(it); + + efl_pack_unpack(layout, NULL); + ck_assert_int_eq(efl_content_count(layout), 3); + efl_pack_unpack(layout, btn[0]); + ck_assert_int_eq(efl_content_count(layout), 2); + efl_pack_unpack_all(layout); + ck_assert_int_eq(efl_content_count(layout), 0); + + for (i = 0; i < 3; i++) + efl_pack(layout, btn[i]); + ck_assert_int_eq(efl_content_count(layout), 3); + efl_pack_clear(layout); + ck_assert_int_eq(efl_content_count(layout), 0); + for (i = 0; i < 3; i++) + ck_assert(efl_invalidated_get(btn[i])); +} +EFL_END_TEST + void efl_ui_test_relative_layout(TCase *tc) { tcase_add_checked_fixture(tc, layout_setup, layout_teardown); @@ -349,4 +380,5 @@ void efl_ui_test_relative_layout(TCase *tc) tcase_add_test(tc, efl_ui_relative_layout_layout_update); tcase_add_test(tc, efl_ui_relative_layout_layout_update_chain); tcase_add_test(tc, efl_ui_relative_layout_relation_set); + tcase_add_test(tc, efl_ui_relative_layout_pack); } diff --git a/src/tests/elementary/spec/efl_test_pack.c b/src/tests/elementary/spec/efl_test_pack.c index fbf756ed22..ab3b19615c 100644 --- a/src/tests/elementary/spec/efl_test_pack.c +++ b/src/tests/elementary/spec/efl_test_pack.c @@ -8,7 +8,7 @@ /* spec-meta-start {"test-interface":"Efl.Pack", - "test-widgets": ["Efl.Ui.Table"]} + "test-widgets": ["Efl.Ui.Table", "Efl.Ui.Relative_Layout"]} spec-meta-end */