From fd192691d5497917c93c4e532b1a4c04348ce61f Mon Sep 17 00:00:00 2001 From: Marcel Hollerbach Date: Mon, 16 Sep 2019 13:50:12 +0200 Subject: [PATCH] efl_ui_collection_view: support focus with this commit you can more or less use focus. The only uncaught case for now is that if the object is not available, no focus can be set. Navigating with focus on the screen however should be possible. Differential Revision: https://phab.enlightenment.org/D9969 --- src/lib/elementary/efl_ui_collection_view.c | 44 +++++++++++++++++++++++++--- src/lib/elementary/efl_ui_collection_view.eo | 1 + 2 files changed, 41 insertions(+), 4 deletions(-) diff --git a/src/lib/elementary/efl_ui_collection_view.c b/src/lib/elementary/efl_ui_collection_view.c index d597c46..aa3b9c5 100644 --- a/src/lib/elementary/efl_ui_collection_view.c +++ b/src/lib/elementary/efl_ui_collection_view.c @@ -508,7 +508,6 @@ _entity_fetched_cb(Eo *obj, void *data, const Eina_Value v) efl_ui_item_container_set(child, obj); efl_ui_widget_sub_object_add(obj, child); efl_canvas_group_member_add(pd->pan, child); - efl_ui_widget_focus_allow_set(child, EINA_FALSE); efl_gfx_entity_visible_set(child, EINA_FALSE); #ifdef VIEWPORT_ENABLE @@ -2180,6 +2179,12 @@ _efl_ui_collection_view_efl_ui_focus_manager_move(Eo *obj, Efl_Ui_Collection_Vie return new_obj; } +EOLIAN static Eina_Bool +_efl_ui_collection_view_efl_ui_widget_focus_state_apply(Eo *obj, Efl_Ui_Collection_View_Data *pd EINA_UNUSED, Efl_Ui_Widget_Focus_State current_state, Efl_Ui_Widget_Focus_State *configured_state, Efl_Ui_Widget *redirect EINA_UNUSED) +{ + return efl_ui_widget_focus_state_apply(efl_super(obj, MY_CLASS), current_state, configured_state, obj); +} + #include "efl_ui_collection_view.eo.c" #define ITEM_IS_OUTSIDE_VISIBLE(id) id < cpd->start_id || id > cpd->end_id @@ -2240,12 +2245,26 @@ _efl_ui_collection_view_focus_manager_efl_ui_focus_manager_manager_focus_set(Eo efl_ui_focus_manager_focus_set(efl_super(obj, EFL_UI_COLLECTION_VIEW_FOCUS_MANAGER_CLASS), focus); } +static int +_id_from_item(Efl_Ui_Item *item, uint64_t *index) +{ + Eina_Value *vindex; + Efl_Model *model; + + model = efl_ui_view_model_get(item); + + vindex = efl_model_property_get(model, "child.index"); + EINA_SAFETY_ON_FALSE_RETURN_VAL(eina_value_uint64_convert(vindex, index), EINA_FALSE); + eina_value_free(vindex); + return EINA_TRUE; +} + EOLIAN static Efl_Ui_Focus_Object * _efl_ui_collection_view_focus_manager_efl_ui_focus_manager_request_move(Eo *obj, Efl_Ui_Collection_View_Focus_Manager_Data *pd, Efl_Ui_Focus_Direction direction, Efl_Ui_Focus_Object *child, Eina_Bool logical) { MY_DATA_GET(pd->collection, cpd); Efl_Ui_Item *new_item, *item; - unsigned int item_id; + uint64_t item_id; if (!child) child = efl_ui_focus_manager_focus_get(obj); @@ -2256,14 +2275,15 @@ _efl_ui_collection_view_focus_manager_efl_ui_focus_manager_request_move(Eo *obj, if (!cpd->manager) return NULL; if (!item) return NULL; - item_id = efl_ui_item_index_get(item); + if (!_id_from_item(item, &item_id)) + return NULL; if (ITEM_IS_OUTSIDE_VISIBLE(item_id)) { int new_id; new_id = efl_ui_position_manager_entity_relative_item(cpd->manager, - efl_ui_item_index_get(item), + item_id, direction); if (new_id == -1) { @@ -2271,6 +2291,7 @@ _efl_ui_collection_view_focus_manager_efl_ui_focus_manager_request_move(Eo *obj, } else { + Efl_Ui_Collection_Item_Lookup *lookup; #ifdef VIEWPORT_ENABLE unsigned int i; @@ -2287,6 +2308,21 @@ _efl_ui_collection_view_focus_manager_efl_ui_focus_manager_request_move(Eo *obj, if (!new_item) break; // Just in case _assert_item_available(new_item, new_id, cpd); } +#else + uint64_t search_index = new_id; + lookup = (void*) eina_rbtree_inline_lookup(cpd->cache, &search_index, + sizeof (new_id), _cache_tree_lookup, + NULL); + if (lookup) + { + _assert_item_available(lookup->item.entity, new_id, cpd); + new_item = lookup->item.entity; + } + else + { + ERR("This item cannot get focus right now. It should be visible first."); + new_item = NULL; + } #endif } } diff --git a/src/lib/elementary/efl_ui_collection_view.eo b/src/lib/elementary/efl_ui_collection_view.eo index ffbbc0e..a0cbbc8 100644 --- a/src/lib/elementary/efl_ui_collection_view.eo +++ b/src/lib/elementary/efl_ui_collection_view.eo @@ -53,6 +53,7 @@ class @beta Efl.Ui.Collection_View extends Efl.Ui.Layout_Base implements Efl.Ui.Scrollable.match_content { set; } Efl.Ui.Widget_Focus_Manager.focus_manager_create; Efl.Ui.Focus.Manager.move; + Efl.Ui.Widget.focus_state_apply; } events { item,realized : Efl.Ui.Item; [[Event triggered when an @Efl.Ui.Item has been provided by the @Efl.Ui.Factory and is about to be used.]] -- 2.7.4