diff --git a/src/lib/elementary/efl_ui_focus_manager.c b/src/lib/elementary/efl_ui_focus_manager.c index 31afb9dc98..8f63f8e25c 100644 --- a/src/lib/elementary/efl_ui_focus_manager.c +++ b/src/lib/elementary/efl_ui_focus_manager.c @@ -8,10 +8,10 @@ EAPI void efl_ui_focus_relation_free(Efl_Ui_Focus_Relations *rel) { - eina_list_free(rel->right); - eina_list_free(rel->left); - eina_list_free(rel->top); - eina_list_free(rel->down); + eina_iterator_free(rel->right); + eina_iterator_free(rel->left); + eina_iterator_free(rel->top); + eina_iterator_free(rel->down); free(rel); } diff --git a/src/lib/elementary/efl_ui_focus_manager.eo b/src/lib/elementary/efl_ui_focus_manager.eo index 5bb11e7036..dd95256b6d 100644 --- a/src/lib/elementary/efl_ui_focus_manager.eo +++ b/src/lib/elementary/efl_ui_focus_manager.eo @@ -4,10 +4,10 @@ import eina_types; struct @beta @free(efl_ui_focus_relation_free) Efl.Ui.Focus.Relations { [[Structure holding the graph of relations between focusable objects. ]] - right : list @move; [[List of objects to the right.]] - left : list @move; [[List of objects to the left.]] - top : list @move; [[List of objects above.]] - down : list @move; [[List of objects below.]] + right : iterator @move; [[List of objects to the right.]] + left : iterator @move; [[List of objects to the left.]] + top : iterator @move; [[List of objects above.]] + down : iterator @move; [[List of objects below.]] next : Efl.Ui.Focus.Object; [[Next object.]] prev : Efl.Ui.Focus.Object; [[Previous object.]] parent : Efl.Ui.Focus.Object; [[Parent object.]] diff --git a/src/lib/elementary/efl_ui_focus_manager_calc.c b/src/lib/elementary/efl_ui_focus_manager_calc.c index efb67fcabf..7be3913474 100644 --- a/src/lib/elementary/efl_ui_focus_manager_calc.c +++ b/src/lib/elementary/efl_ui_focus_manager_calc.c @@ -1789,18 +1789,6 @@ _efl_ui_focus_manager_calc_efl_object_finalize(Eo *obj, Efl_Ui_Focus_Manager_Cal return result; } -static Eina_List* -_convert(Border b) -{ - Eina_List *n, *par = NULL; - Node *node; - - EINA_LIST_FOREACH(b.one_direction, n, node) - par = eina_list_append(par, node->focusable); - - return par; -} - EOLIAN static Efl_Ui_Focus_Object* _efl_ui_focus_manager_calc_efl_ui_focus_manager_manager_focus_get(const Eo *obj EINA_UNUSED, Efl_Ui_Focus_Manager_Calc_Data *pd) { @@ -1815,6 +1803,63 @@ _efl_ui_focus_manager_calc_efl_ui_focus_manager_manager_focus_get(const Eo *obj return upper->focusable; } +typedef struct _Eina_Iterator_Focusable Eina_Iterator_Focusable; +struct _Eina_Iterator_Focusable +{ + Eina_Iterator iterator; + + Eina_Iterator *redirect; +}; + +static Eina_Bool +_node_focusable_iterator_next(Eina_Iterator_Focusable *it, void **data) +{ + Node *node = NULL; + Eina_Bool r; + + if (!it->redirect) return EINA_FALSE; + + r = eina_iterator_next(it->redirect, (void **) &node); + if (r && data) *data = node->focusable; + + return r; +} + +static Eina_List * +_node_focusable_iterator_get_container(Eina_Iterator_Focusable *it) +{ + if (!it->redirect) return NULL; + + return eina_iterator_container_get(it->redirect); +} + +static void +_node_focusable_iterator_free(Eina_Iterator_Focusable *it) +{ + eina_iterator_free(it->redirect); + EINA_MAGIC_SET(&it->iterator, 0); + free(it); +} + +static Eina_Iterator * +_node_focusable_iterator_new(Eina_List *nodes) +{ + Eina_Iterator_Focusable *it; + + it = calloc(1, sizeof (Eina_Iterator_Focusable)); + if (!it) return NULL; + + EINA_MAGIC_SET(&it->iterator, EINA_MAGIC_ITERATOR); + it->redirect = eina_list_iterator_new(nodes); + + it->iterator.version = EINA_ITERATOR_VERSION; + it->iterator.next = FUNC_ITERATOR_NEXT(_node_focusable_iterator_next); + it->iterator.get_container = FUNC_ITERATOR_GET_CONTAINER(_node_focusable_iterator_get_container); + it->iterator.free = FUNC_ITERATOR_FREE(_node_focusable_iterator_free); + + return &it->iterator; +} + EOLIAN static Efl_Ui_Focus_Relations* _efl_ui_focus_manager_calc_efl_ui_focus_manager_fetch(Eo *obj, Efl_Ui_Focus_Manager_Calc_Data *pd, Efl_Ui_Focus_Object *child) { @@ -1834,12 +1879,14 @@ _efl_ui_focus_manager_calc_efl_ui_focus_manager_fetch(Eo *obj, Efl_Ui_Focus_Mana efl_ui_focus_object_setup_order(n->tree.parent->focusable); efl_ui_focus_object_setup_order(n->focusable); -#define DIR_CLONE(dir) _convert(DIRECTION_ACCESS(n,dir)); + // FIXME: the iterator must actually return the (Node*)->focusable object in it + // Just redirect to default eina list iterator but offset the returned pointer? +#define DIR_ITERATOR(dir) _node_focusable_iterator_new(DIRECTION_ACCESS(n,dir).one_direction); - res->right = DIR_CLONE(EFL_UI_FOCUS_DIRECTION_RIGHT); - res->left = DIR_CLONE(EFL_UI_FOCUS_DIRECTION_LEFT); - res->top = DIR_CLONE(EFL_UI_FOCUS_DIRECTION_UP); - res->down = DIR_CLONE(EFL_UI_FOCUS_DIRECTION_DOWN); + res->right = DIR_ITERATOR(EFL_UI_FOCUS_DIRECTION_RIGHT); + res->left = DIR_ITERATOR(EFL_UI_FOCUS_DIRECTION_LEFT); + res->top = DIR_ITERATOR(EFL_UI_FOCUS_DIRECTION_UP); + res->down = DIR_ITERATOR(EFL_UI_FOCUS_DIRECTION_DOWN); res->next = (tmp = _next(n)) ? tmp->focusable : NULL; res->prev = (tmp = _prev(n)) ? tmp->focusable : NULL; res->position_in_history = eina_list_data_idx(pd->focus_stack, n); @@ -1850,7 +1897,7 @@ _efl_ui_focus_manager_calc_efl_ui_focus_manager_fetch(Eo *obj, Efl_Ui_Focus_Mana if (T(n).parent) res->parent = T(n).parent->focusable; res->redirect = n->redirect_manager; -#undef DIR_CLONE +#undef DIR_ITERATOR return res; } diff --git a/src/lib/elementary/efl_ui_widget.c b/src/lib/elementary/efl_ui_widget.c index 7218b8b063..c27838b61c 100644 --- a/src/lib/elementary/efl_ui_widget.c +++ b/src/lib/elementary/efl_ui_widget.c @@ -2779,7 +2779,7 @@ _efl_ui_widget_efl_object_dbg_info_get(Eo *eo_obj, Elm_Widget_Smart_Data *_pd EI #define ADD_PTR_LIST(name) \ Efl_Dbg_Info* name = EFL_DBG_INFO_LIST_APPEND(focus, ""#name""); \ - _convert(name, eina_list_iterator_new(rel->name)); + _convert(name, rel->name); ADD_PTR_LIST(top) ADD_PTR_LIST(down) diff --git a/src/tests/elementary/efl_ui_test_focus.c b/src/tests/elementary/efl_ui_test_focus.c index 814ab5c690..3b66515d31 100644 --- a/src/tests/elementary/efl_ui_test_focus.c +++ b/src/tests/elementary/efl_ui_test_focus.c @@ -83,9 +83,15 @@ EFL_START_TEST(pos_check) EFL_END_TEST static Eina_Bool -_equal_set(Eina_List *elems, Efl_Ui_Focus_Object *lst[]) +_equal_set(Eina_Iterator *elems, Efl_Ui_Focus_Object *lst[]) { unsigned int i = 0; + Eina_List *tmp = NULL; + Efl_Gfx_Entity *object; + Eina_Bool r = EINA_FALSE; + + EINA_ITERATOR_FOREACH(elems, object) + tmp = eina_list_append(tmp, object); for (i = 0; lst[i]; ++i) { @@ -93,7 +99,7 @@ _equal_set(Eina_List *elems, Efl_Ui_Focus_Object *lst[]) Eina_List *n; Efl_Ui_Focus_Object *elem; - EINA_LIST_FOREACH(elems, n, elem) + EINA_LIST_FOREACH(tmp, n, elem) { if (lst[i] != elem) continue; @@ -101,11 +107,13 @@ _equal_set(Eina_List *elems, Efl_Ui_Focus_Object *lst[]) break; } - if (!found) return EINA_FALSE; + if (!found) goto end; } - if (eina_list_count(elems) != i) return EINA_FALSE; - return EINA_TRUE; + if (eina_list_count(tmp) == i) r = EINA_TRUE; + end: + eina_list_free(tmp); + return r; } EFL_START_TEST(pos_check2)