summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarcel Hollerbach <mail@marcel-hollerbach.de>2019-08-06 09:34:42 -0400
committerMike Blumenkrantz <zmike@samsung.com>2019-08-06 09:34:42 -0400
commit63d3af3ce938c1efc8b44075075f2caa55a63a49 (patch)
treec86dbf20f7ae54945b82f261d27eb2ee908694b2
parent49e8334024f81017acc37b3aa42d015b0ec500e3 (diff)
efl_ui_collection: implement initial focus behaviour
Summary: the behaviour here is that the next item according to the direction is getting focused. This sounds easy but is quite complex given the fact that the items might be hidden. This is the first draft for this, to see how good it performes. Reviewers: zmike, stefan_schmidt, cedric Reviewed By: zmike Subscribers: #reviewers, #committers Tags: #efl Differential Revision: https://phab.enlightenment.org/D9496
-rw-r--r--src/bin/elementary/test_ui_item_container.c39
-rw-r--r--src/lib/elementary/efl_ui_collection.c125
-rw-r--r--src/lib/elementary/efl_ui_collection_focus_manager.eo7
-rw-r--r--src/lib/elementary/efl_ui_position_manager_common.h5
-rw-r--r--src/lib/elementary/efl_ui_position_manager_entity.eo9
-rw-r--r--src/lib/elementary/efl_ui_position_manager_grid.c31
-rw-r--r--src/lib/elementary/efl_ui_position_manager_grid.eo1
-rw-r--r--src/lib/elementary/efl_ui_position_manager_list.c27
-rw-r--r--src/lib/elementary/efl_ui_position_manager_list.eo1
-rw-r--r--src/lib/elementary/meson.build1
10 files changed, 230 insertions, 16 deletions
diff --git a/src/bin/elementary/test_ui_item_container.c b/src/bin/elementary/test_ui_item_container.c
index e87a6ba9a7..e1e7654e5d 100644
--- a/src/bin/elementary/test_ui_item_container.c
+++ b/src/bin/elementary/test_ui_item_container.c
@@ -14,6 +14,16 @@ _selection_changed_cb(void *data, const Efl_Event *ev EINA_UNUSED)
14} 14}
15 15
16static void 16static void
17_focus_item_cb(void *data, const Efl_Event *ev EINA_UNUSED)
18{
19 Efl_Ui_Widget *element_0 = efl_pack_content_get(data, 0);
20
21 EINA_SAFETY_ON_NULL_RETURN(element_0);
22
23 efl_ui_focus_manager_focus_set(data, element_0);
24}
25
26static void
17_scroll_to_animated_cb(void *data, const Efl_Event *ev EINA_UNUSED) 27_scroll_to_animated_cb(void *data, const Efl_Event *ev EINA_UNUSED)
18{ 28{
19 Efl_Ui_Widget *element_1154 = efl_pack_content_get(data, 1154); 29 Efl_Ui_Widget *element_1154 = efl_pack_content_get(data, 1154);
@@ -168,29 +178,36 @@ void create_item_container_ui(Efl_Ui_Position_Manager_Entity *manager, const Efl
168 { 178 {
169 _add_item(o); 179 _add_item(o);
170 } 180 }
171 efl_pack_table(tbl, o, 1, 0, 1, 11); 181 efl_pack_table(tbl, o, 1, 0, 1, 12);
172 ctx->c = o; 182 ctx->c = o;
173 183
174 o = efl_add(EFL_UI_BUTTON_CLASS, tbl, 184 o = efl_add(EFL_UI_BUTTON_CLASS, tbl,
175 efl_gfx_hint_weight_set(efl_added, 0.0, 0.0), 185 efl_gfx_hint_weight_set(efl_added, 0.0, 0.0),
176 efl_gfx_hint_align_set(efl_added, 0, 0.5)); 186 efl_gfx_hint_align_set(efl_added, 0, 0.5));
187 efl_text_set(o, "Focus item 0");
188 efl_event_callback_add(o, EFL_INPUT_EVENT_CLICKED, _focus_item_cb, item_container);
189 efl_pack_table(tbl, o, 0, 1, 1, 1);
190
191 o = efl_add(EFL_UI_BUTTON_CLASS, tbl,
192 efl_gfx_hint_weight_set(efl_added, 0.0, 0.0),
193 efl_gfx_hint_align_set(efl_added, 0, 0.5));
177 efl_text_set(o, "Scroll to 1154 ANIMATED"); 194 efl_text_set(o, "Scroll to 1154 ANIMATED");
178 efl_event_callback_add(o, EFL_INPUT_EVENT_CLICKED, _scroll_to_animated_cb, item_container); 195 efl_event_callback_add(o, EFL_INPUT_EVENT_CLICKED, _scroll_to_animated_cb, item_container);
179 efl_pack_table(tbl, o, 0, 1, 1, 1); 196 efl_pack_table(tbl, o, 0, 2, 1, 1);
180 197
181 o = efl_add(EFL_UI_BUTTON_CLASS, tbl, 198 o = efl_add(EFL_UI_BUTTON_CLASS, tbl,
182 efl_gfx_hint_weight_set(efl_added, 0.0, 0.0), 199 efl_gfx_hint_weight_set(efl_added, 0.0, 0.0),
183 efl_gfx_hint_align_set(efl_added, 0, 0.5)); 200 efl_gfx_hint_align_set(efl_added, 0, 0.5));
184 efl_text_set(o, "Scroll to 10"); 201 efl_text_set(o, "Scroll to 10");
185 efl_event_callback_add(o, EFL_INPUT_EVENT_CLICKED, _scroll_to_cb, item_container); 202 efl_event_callback_add(o, EFL_INPUT_EVENT_CLICKED, _scroll_to_cb, item_container);
186 efl_pack_table(tbl, o, 0, 2, 1, 1); 203 efl_pack_table(tbl, o, 0, 3, 1, 1);
187 204
188 o = efl_add(EFL_UI_BUTTON_CLASS, tbl, 205 o = efl_add(EFL_UI_BUTTON_CLASS, tbl,
189 efl_gfx_hint_weight_set(efl_added, 0.0, 0.0), 206 efl_gfx_hint_weight_set(efl_added, 0.0, 0.0),
190 efl_gfx_hint_align_set(efl_added, 0, 0.5)); 207 efl_gfx_hint_align_set(efl_added, 0, 0.5));
191 efl_text_set(o, "Change min size of 0"); 208 efl_text_set(o, "Change min size of 0");
192 efl_event_callback_add(o, EFL_INPUT_EVENT_CLICKED, _change_min_size_cb, item_container); 209 efl_event_callback_add(o, EFL_INPUT_EVENT_CLICKED, _change_min_size_cb, item_container);
193 efl_pack_table(tbl, o, 0, 3, 1, 1); 210 efl_pack_table(tbl, o, 0, 4, 1, 1);
194 211
195 o = efl_add(EFL_UI_CHECK_CLASS, tbl, 212 o = efl_add(EFL_UI_CHECK_CLASS, tbl,
196 efl_gfx_hint_weight_set(efl_added, 0.0, 0.0), 213 efl_gfx_hint_weight_set(efl_added, 0.0, 0.0),
@@ -198,14 +215,14 @@ void create_item_container_ui(Efl_Ui_Position_Manager_Entity *manager, const Efl
198 efl_text_set(o, "Vertical"); 215 efl_text_set(o, "Vertical");
199 efl_event_callback_add(o, EFL_UI_CHECK_EVENT_SELECTED_CHANGED, _selection_changed_cb, item_container); 216 efl_event_callback_add(o, EFL_UI_CHECK_EVENT_SELECTED_CHANGED, _selection_changed_cb, item_container);
200 efl_ui_check_selected_set(o, EINA_TRUE); 217 efl_ui_check_selected_set(o, EINA_TRUE);
201 efl_pack_table(tbl, o, 0, 4, 1, 1); 218 efl_pack_table(tbl, o, 0, 5, 1, 1);
202 219
203 o = efl_add(EFL_UI_CHECK_CLASS, tbl, 220 o = efl_add(EFL_UI_CHECK_CLASS, tbl,
204 efl_gfx_hint_weight_set(efl_added, 0.0, 0.0), 221 efl_gfx_hint_weight_set(efl_added, 0.0, 0.0),
205 efl_gfx_hint_align_set(efl_added, 0, 0.5)); 222 efl_gfx_hint_align_set(efl_added, 0, 0.5));
206 efl_text_set(o, "Match Vertical"); 223 efl_text_set(o, "Match Vertical");
207 efl_event_callback_add(o, EFL_UI_CHECK_EVENT_SELECTED_CHANGED, _selection_changed_match_content_cb, ctx); 224 efl_event_callback_add(o, EFL_UI_CHECK_EVENT_SELECTED_CHANGED, _selection_changed_match_content_cb, ctx);
208 efl_pack_table(tbl, o, 0, 5, 1, 1); 225 efl_pack_table(tbl, o, 0, 6, 1, 1);
209 ctx->v = o; 226 ctx->v = o;
210 227
211 o = efl_add(EFL_UI_CHECK_CLASS, tbl, 228 o = efl_add(EFL_UI_CHECK_CLASS, tbl,
@@ -213,7 +230,7 @@ void create_item_container_ui(Efl_Ui_Position_Manager_Entity *manager, const Efl
213 efl_gfx_hint_align_set(efl_added, 0, 0.5)); 230 efl_gfx_hint_align_set(efl_added, 0, 0.5));
214 efl_text_set(o, "Match Horizontal"); 231 efl_text_set(o, "Match Horizontal");
215 efl_event_callback_add(o, EFL_UI_CHECK_EVENT_SELECTED_CHANGED, _selection_changed_match_content_cb, ctx); 232 efl_event_callback_add(o, EFL_UI_CHECK_EVENT_SELECTED_CHANGED, _selection_changed_match_content_cb, ctx);
216 efl_pack_table(tbl, o, 0, 6, 1, 1); 233 efl_pack_table(tbl, o, 0, 7, 1, 1);
217 efl_gfx_entity_size_set(win, EINA_SIZE2D(260, 200)); 234 efl_gfx_entity_size_set(win, EINA_SIZE2D(260, 200));
218 ctx->h = o; 235 ctx->h = o;
219 236
@@ -222,27 +239,27 @@ void create_item_container_ui(Efl_Ui_Position_Manager_Entity *manager, const Efl
222 efl_gfx_hint_align_set(efl_added, 0, 0.5)); 239 efl_gfx_hint_align_set(efl_added, 0, 0.5));
223 efl_text_set(o, "Remove all items"); 240 efl_text_set(o, "Remove all items");
224 efl_event_callback_add(o, EFL_INPUT_EVENT_CLICKED, _remove_all_cb, item_container); 241 efl_event_callback_add(o, EFL_INPUT_EVENT_CLICKED, _remove_all_cb, item_container);
225 efl_pack_table(tbl, o, 0, 7, 1, 1); 242 efl_pack_table(tbl, o, 0, 8, 1, 1);
226 243
227 o = efl_add(EFL_UI_BUTTON_CLASS, tbl, 244 o = efl_add(EFL_UI_BUTTON_CLASS, tbl,
228 efl_gfx_hint_weight_set(efl_added, 0.0, 0.0), 245 efl_gfx_hint_weight_set(efl_added, 0.0, 0.0),
229 efl_gfx_hint_align_set(efl_added, 0, 0.5)); 246 efl_gfx_hint_align_set(efl_added, 0, 0.5));
230 efl_text_set(o, "Add 1 item"); 247 efl_text_set(o, "Add 1 item");
231 efl_event_callback_add(o, EFL_INPUT_EVENT_CLICKED, _add_one_item, item_container); 248 efl_event_callback_add(o, EFL_INPUT_EVENT_CLICKED, _add_one_item, item_container);
232 efl_pack_table(tbl, o, 0, 8, 1, 1); 249 efl_pack_table(tbl, o, 0, 9, 1, 1);
233 250
234 o = efl_add(EFL_UI_BUTTON_CLASS, tbl, 251 o = efl_add(EFL_UI_BUTTON_CLASS, tbl,
235 efl_gfx_hint_weight_set(efl_added, 0.0, 0.0), 252 efl_gfx_hint_weight_set(efl_added, 0.0, 0.0),
236 efl_gfx_hint_align_set(efl_added, 0, 0.5)); 253 efl_gfx_hint_align_set(efl_added, 0, 0.5));
237 efl_text_set(o, "Add 1000 item"); 254 efl_text_set(o, "Add 1000 item");
238 efl_event_callback_add(o, EFL_INPUT_EVENT_CLICKED, _add_thousend_items, item_container); 255 efl_event_callback_add(o, EFL_INPUT_EVENT_CLICKED, _add_thousend_items, item_container);
239 efl_pack_table(tbl, o, 0, 9, 1, 1); 256 efl_pack_table(tbl, o, 0, 10, 1, 1);
240 257
241 bx = efl_add(EFL_UI_RADIO_BOX_CLASS, tbl, 258 bx = efl_add(EFL_UI_RADIO_BOX_CLASS, tbl,
242 efl_gfx_hint_weight_set(efl_added, 0.0, 0.0), 259 efl_gfx_hint_weight_set(efl_added, 0.0, 0.0),
243 efl_gfx_hint_align_set(efl_added, 0, 0.5)); 260 efl_gfx_hint_align_set(efl_added, 0, 0.5));
244 efl_event_callback_add(bx, EFL_UI_RADIO_GROUP_EVENT_VALUE_CHANGED, _select_value_cb, item_container); 261 efl_event_callback_add(bx, EFL_UI_RADIO_GROUP_EVENT_VALUE_CHANGED, _select_value_cb, item_container);
245 efl_pack_table(tbl, bx, 0, 10, 1, 1); 262 efl_pack_table(tbl, bx, 0, 11, 1, 1);
246 o = efl_add(EFL_UI_RADIO_CLASS, bx, 263 o = efl_add(EFL_UI_RADIO_CLASS, bx,
247 efl_ui_radio_state_value_set(efl_added, EFL_UI_SELECT_MODE_SINGLE)); 264 efl_ui_radio_state_value_set(efl_added, EFL_UI_SELECT_MODE_SINGLE));
248 efl_text_set(o, "Singleselect"); 265 efl_text_set(o, "Singleselect");
diff --git a/src/lib/elementary/efl_ui_collection.c b/src/lib/elementary/efl_ui_collection.c
index 2241c5209d..f1c5b568c3 100644
--- a/src/lib/elementary/efl_ui_collection.c
+++ b/src/lib/elementary/efl_ui_collection.c
@@ -11,6 +11,11 @@
11#include <Elementary.h> 11#include <Elementary.h>
12#include "elm_widget.h" 12#include "elm_widget.h"
13#include "elm_priv.h" 13#include "elm_priv.h"
14#include "efl_ui_collection_focus_manager.eo.h"
15
16typedef struct {
17 Eo *collection;
18} Efl_Ui_Collection_Focus_Manager_Data;
14 19
15typedef struct { 20typedef struct {
16 unsigned int last_index; 21 unsigned int last_index;
@@ -138,6 +143,7 @@ typedef struct {
138 Fast_Accessor obj_accessor; 143 Fast_Accessor obj_accessor;
139 Fast_Accessor size_accessor; 144 Fast_Accessor size_accessor;
140 Efl_Gfx_Entity *sizer; 145 Efl_Gfx_Entity *sizer;
146 unsigned int start_id, end_id;
141} Efl_Ui_Collection_Data; 147} Efl_Ui_Collection_Data;
142 148
143static Eina_Bool register_item(Eo *obj, Efl_Ui_Collection_Data *pd, Efl_Ui_Item *item); 149static Eina_Bool register_item(Eo *obj, Efl_Ui_Collection_Data *pd, Efl_Ui_Item *item);
@@ -745,9 +751,20 @@ _pos_content_min_size_changed_cb(void *data EINA_UNUSED, const Efl_Event *ev)
745 flush_min_size(data, pd); 751 flush_min_size(data, pd);
746} 752}
747 753
754static void
755_visible_range_changed_cb(void *data EINA_UNUSED, const Efl_Event *ev)
756{
757 Efl_Ui_Position_Manager_Range_Update *info = ev->info;
758 MY_DATA_GET(data, pd);
759
760 pd->start_id = info->start_id;
761 pd->end_id = info->end_id;
762}
763
748EFL_CALLBACKS_ARRAY_DEFINE(pos_manager_cbs, 764EFL_CALLBACKS_ARRAY_DEFINE(pos_manager_cbs,
749 {EFL_UI_POSITION_MANAGER_ENTITY_EVENT_CONTENT_SIZE_CHANGED, _pos_content_size_changed_cb}, 765 {EFL_UI_POSITION_MANAGER_ENTITY_EVENT_CONTENT_SIZE_CHANGED, _pos_content_size_changed_cb},
750 {EFL_UI_POSITION_MANAGER_ENTITY_EVENT_CONTENT_MIN_SIZE_CHANGED, _pos_content_min_size_changed_cb}, 766 {EFL_UI_POSITION_MANAGER_ENTITY_EVENT_CONTENT_MIN_SIZE_CHANGED, _pos_content_min_size_changed_cb},
767 {EFL_UI_POSITION_MANAGER_ENTITY_EVENT_VISIBLE_RANGE_CHANGED, _visible_range_changed_cb}
751) 768)
752 769
753EOLIAN static void 770EOLIAN static void
@@ -786,8 +803,11 @@ _efl_ui_collection_position_manager_get(const Eo *obj EINA_UNUSED, Efl_Ui_Collec
786EOLIAN static Efl_Ui_Focus_Manager* 803EOLIAN static Efl_Ui_Focus_Manager*
787_efl_ui_collection_efl_ui_widget_focus_manager_focus_manager_create(Eo *obj, Efl_Ui_Collection_Data *pd EINA_UNUSED, Efl_Ui_Focus_Object *root) 804_efl_ui_collection_efl_ui_widget_focus_manager_focus_manager_create(Eo *obj, Efl_Ui_Collection_Data *pd EINA_UNUSED, Efl_Ui_Focus_Object *root)
788{ 805{
789 return efl_add(EFL_UI_FOCUS_MANAGER_CALC_CLASS, obj, 806 Eo *man = efl_add(EFL_UI_COLLECTION_FOCUS_MANAGER_CLASS, obj,
790 efl_ui_focus_manager_root_set(efl_added, root)); 807 efl_ui_focus_manager_root_set(efl_added, root));
808 Efl_Ui_Collection_Focus_Manager_Data *fm_pd = efl_data_scope_safe_get(man, EFL_UI_COLLECTION_FOCUS_MANAGER_CLASS);
809 fm_pd->collection = obj;
810 return man;
791} 811}
792 812
793EOLIAN static Eina_Bool 813EOLIAN static Eina_Bool
@@ -796,6 +816,19 @@ _efl_ui_collection_efl_ui_widget_focus_state_apply(Eo *obj, Efl_Ui_Collection_Da
796 return efl_ui_widget_focus_state_apply(efl_super(obj, MY_CLASS), current_state, configured_state, obj); 816 return efl_ui_widget_focus_state_apply(efl_super(obj, MY_CLASS), current_state, configured_state, obj);
797} 817}
798 818
819static Efl_Ui_Item *
820_find_item(Eo *obj EINA_UNUSED, Efl_Ui_Collection_Data *pd EINA_UNUSED, Eo *focused_element)
821{
822 if (!focused_element) return NULL;
823
824 while (focused_element && !efl_isa(focused_element, EFL_UI_ITEM_CLASS))
825 {
826 focused_element = efl_ui_widget_parent_get(focused_element);
827 }
828
829 return focused_element;
830}
831
799EOLIAN static Efl_Ui_Focus_Object* 832EOLIAN static Efl_Ui_Focus_Object*
800_efl_ui_collection_efl_ui_focus_manager_move(Eo *obj, Efl_Ui_Collection_Data *pd, Efl_Ui_Focus_Direction direction) 833_efl_ui_collection_efl_ui_focus_manager_move(Eo *obj, Efl_Ui_Collection_Data *pd, Efl_Ui_Focus_Direction direction)
801{ 834{
@@ -803,7 +836,10 @@ _efl_ui_collection_efl_ui_focus_manager_move(Eo *obj, Efl_Ui_Collection_Data *pd
803 Eina_Size2D step; 836 Eina_Size2D step;
804 837
805 focus = efl_ui_focus_manager_focus_get(obj); 838 focus = efl_ui_focus_manager_focus_get(obj);
806 if (focus) 839 new_obj = efl_ui_focus_manager_move(efl_super(obj, MY_CLASS), direction);
840 step = efl_gfx_hint_size_combined_min_get(focus);
841
842 if (new_obj)
807 { 843 {
808 /* if this is outside the viewport, then we must bring that in first */ 844 /* if this is outside the viewport, then we must bring that in first */
809 Eina_Rect viewport; 845 Eina_Rect viewport;
@@ -817,8 +853,7 @@ _efl_ui_collection_efl_ui_focus_manager_move(Eo *obj, Efl_Ui_Collection_Data *pd
817 return focus; 853 return focus;
818 } 854 }
819 } 855 }
820 new_obj = efl_ui_focus_manager_move(efl_super(obj, MY_CLASS), direction); 856
821 step = efl_gfx_hint_size_min_get(focus);
822 if (!new_obj) 857 if (!new_obj)
823 { 858 {
824 Eina_Rect pos = efl_gfx_entity_geometry_get(focus); 859 Eina_Rect pos = efl_gfx_entity_geometry_get(focus);
@@ -875,3 +910,83 @@ _efl_ui_collection_efl_ui_focus_manager_move(Eo *obj, Efl_Ui_Collection_Data *pd
875} 910}
876 911
877#include "efl_ui_collection.eo.c" 912#include "efl_ui_collection.eo.c"
913
914#define ITEM_IS_OUTSIDE_VISIBLE(id) id < collection_pd->start_id || id > collection_pd->end_id
915
916static inline void
917_assert_item_available(Eo *item, int new_id, Efl_Ui_Collection_Data *pd)
918{
919 efl_gfx_entity_visible_set(item, EINA_TRUE);
920 efl_gfx_entity_geometry_set(item, efl_ui_position_manager_entity_position_single_item(pd->pos_man, new_id));
921}
922
923EOLIAN static Efl_Ui_Focus_Object*
924_efl_ui_collection_focus_manager_efl_ui_focus_manager_request_move(Eo *obj, Efl_Ui_Collection_Focus_Manager_Data *pd, Efl_Ui_Focus_Direction direction, Efl_Ui_Focus_Object *child, Eina_Bool logical)
925{
926 MY_DATA_GET(pd->collection, collection_pd);
927 Efl_Ui_Item *new_item, *item;
928 unsigned int item_id;
929
930 if (!child)
931 child = efl_ui_focus_manager_focus_get(obj);
932
933 item = _find_item(obj, collection_pd, child);
934
935 //if this is NULL then we are before finalize, we cannot serve any sane value here
936 if (!collection_pd->pos_man) return NULL;
937 EINA_SAFETY_ON_NULL_RETURN_VAL(item, NULL);
938
939 item_id = efl_ui_item_index_get(item);
940
941 if (ITEM_IS_OUTSIDE_VISIBLE(item_id))
942 {
943 int new_id = efl_ui_position_manager_entity_relative_item(collection_pd->pos_man, efl_ui_item_index_get(item), direction);
944 if (new_id == -1)
945 {
946 new_item = NULL;
947 }
948 else
949 {
950 new_item = eina_list_nth(collection_pd->items, new_id);;
951 _assert_item_available(new_item, new_id, collection_pd);
952 }
953 }
954 else
955 {
956 new_item = efl_ui_focus_manager_request_move(efl_super(obj, EFL_UI_COLLECTION_FOCUS_MANAGER_CLASS), direction, child, logical);
957 }
958
959 return new_item;
960}
961
962
963EOLIAN static void
964_efl_ui_collection_focus_manager_efl_ui_focus_manager_manager_focus_set(Eo *obj, Efl_Ui_Collection_Focus_Manager_Data *pd, Efl_Ui_Focus_Object *focus)
965{
966 MY_DATA_GET(pd->collection, collection_pd);
967 Efl_Ui_Item *item;
968 unsigned int item_id;
969
970 if (focus == efl_ui_focus_manager_root_get(obj))
971 {
972 item = eina_list_data_get(collection_pd->items);
973 }
974 else
975 {
976 item = _find_item(obj, collection_pd, focus);
977 }
978
979 //if this is NULL then we are before finalize, we cannot serve any sane value here
980 if (!collection_pd->pos_man) return;
981 EINA_SAFETY_ON_NULL_RETURN(item);
982
983 item_id = efl_ui_item_index_get(item);
984
985 if (ITEM_IS_OUTSIDE_VISIBLE(item_id))
986 {
987 _assert_item_available(item, item_id, collection_pd);
988 }
989 efl_ui_focus_manager_focus_set(efl_super(obj, EFL_UI_COLLECTION_FOCUS_MANAGER_CLASS), focus);
990}
991
992#include "efl_ui_collection_focus_manager.eo.c"
diff --git a/src/lib/elementary/efl_ui_collection_focus_manager.eo b/src/lib/elementary/efl_ui_collection_focus_manager.eo
new file mode 100644
index 0000000000..6fbf57d89a
--- /dev/null
+++ b/src/lib/elementary/efl_ui_collection_focus_manager.eo
@@ -0,0 +1,7 @@
1class @beta Efl.Ui.Collection.Focus_Manager extends Efl.Ui.Focus.Manager_Calc {
2 [[Internal class which implements collection specific behaviour, cannot be used outside of collection]]
3 implements {
4 Efl.Ui.Focus.Manager.manager_focus { set; }
5 Efl.Ui.Focus.Manager.request_move;
6 }
7}
diff --git a/src/lib/elementary/efl_ui_position_manager_common.h b/src/lib/elementary/efl_ui_position_manager_common.h
index 56c7eeef08..7f84087b00 100644
--- a/src/lib/elementary/efl_ui_position_manager_common.h
+++ b/src/lib/elementary/efl_ui_position_manager_common.h
@@ -39,6 +39,11 @@ vis_change_segment(Api_Callback *cb, int a, int b, Eina_Bool flag)
39 EINA_SAFETY_ON_FALSE_RETURN(_fill_buffer(cb, MIN(a,b), len, data) >= 0); 39 EINA_SAFETY_ON_FALSE_RETURN(_fill_buffer(cb, MIN(a,b), len, data) >= 0);
40 } 40 }
41 ent = data[i - MIN(a,b)]; 41 ent = data[i - MIN(a,b)];
42 if (ent && !flag && (efl_ui_focus_object_focus_get(ent) || efl_ui_focus_object_child_focus_get(ent)))
43 {
44 //we should not make focused object invisible, rather move it to some parking lot
45 efl_gfx_entity_position_set(ent, EINA_POSITION2D(-9999,-9999));
46 }
42 if (ent && !efl_ui_focus_object_focus_get(ent)) 47 if (ent && !efl_ui_focus_object_focus_get(ent))
43 { 48 {
44 efl_gfx_entity_visible_set(ent, flag); 49 efl_gfx_entity_visible_set(ent, flag);
diff --git a/src/lib/elementary/efl_ui_position_manager_entity.eo b/src/lib/elementary/efl_ui_position_manager_entity.eo
index 64c68344d8..fb3bb2d14a 100644
--- a/src/lib/elementary/efl_ui_position_manager_entity.eo
+++ b/src/lib/elementary/efl_ui_position_manager_entity.eo
@@ -1,3 +1,4 @@
1import efl_ui;
1 2
2function Efl.Ui.Position_Manager.Batch_Access_Entity { 3function Efl.Ui.Position_Manager.Batch_Access_Entity {
3 [[ Function callback for getting a batch of items]] 4 [[ Function callback for getting a batch of items]]
@@ -114,6 +115,14 @@ interface @beta Efl.Ui.Position_Manager.Entity extends Efl.Ui.Layout_Orientable
114 end_id : int; [[The last item that has a new size]] 115 end_id : int; [[The last item that has a new size]]
115 } 116 }
116 } 117 }
118 relative_item {
119 [[translate the current_id, into a new id which is oriented in the $direction of $current_id. In case that there is no item, -1 is returned]]
120 params {
121 current_id : uint; [[The id where the direction is oriented at]]
122 direction : Efl.Ui.Focus.Direction; [[The direction where the new id is]]
123 }
124 return : int; [[The id of the item in that direction, or -1 if there is no item in that direction]]
125 }
117 } 126 }
118 events { 127 events {
119 content_size,changed : Eina.Size2D; [[Emitted when the aggregate size of all items has changed. This can be used to resize an enclosing Pan object.]] 128 content_size,changed : Eina.Size2D; [[Emitted when the aggregate size of all items has changed. This can be used to resize an enclosing Pan object.]]
diff --git a/src/lib/elementary/efl_ui_position_manager_grid.c b/src/lib/elementary/efl_ui_position_manager_grid.c
index bf8f793d12..909f986f3e 100644
--- a/src/lib/elementary/efl_ui_position_manager_grid.c
+++ b/src/lib/elementary/efl_ui_position_manager_grid.c
@@ -329,4 +329,35 @@ _efl_ui_position_manager_grid_efl_ui_position_manager_entity_position_single_ite
329 return geom; 329 return geom;
330} 330}
331 331
332EOLIAN static int
333_efl_ui_position_manager_grid_efl_ui_position_manager_entity_relative_item(Eo *obj EINA_UNUSED, Efl_Ui_Position_Manager_Grid_Data *pd, unsigned int current_id, Efl_Ui_Focus_Direction direction)
334{
335 int new_id = current_id;
336 switch(direction)
337 {
338 case EFL_UI_FOCUS_DIRECTION_RIGHT:
339 case EFL_UI_FOCUS_DIRECTION_NEXT:
340 new_id += 1;
341 break;
342 case EFL_UI_FOCUS_DIRECTION_LEFT:
343 case EFL_UI_FOCUS_DIRECTION_PREVIOUS:
344 new_id -= 1;
345 break;
346 case EFL_UI_FOCUS_DIRECTION_UP:
347 new_id -= pd->current_display_table.columns;
348 break;
349 case EFL_UI_FOCUS_DIRECTION_DOWN:
350 new_id += pd->current_display_table.columns;
351 break;
352 default:
353 new_id = -1;
354 ERR("Uncaught case!");
355 break;
356 }
357 if (new_id < 0 || new_id > (int)pd->size)
358 return -1;
359 else
360 return new_id;
361}
362
332#include "efl_ui_position_manager_grid.eo.c" 363#include "efl_ui_position_manager_grid.eo.c"
diff --git a/src/lib/elementary/efl_ui_position_manager_grid.eo b/src/lib/elementary/efl_ui_position_manager_grid.eo
index c7aba19da0..164b48ff52 100644
--- a/src/lib/elementary/efl_ui_position_manager_grid.eo
+++ b/src/lib/elementary/efl_ui_position_manager_grid.eo
@@ -12,6 +12,7 @@ class @beta Efl.Ui.Position_Manager.Grid extends Efl.Object implements Efl.Ui.Po
12 Efl.Ui.Position_Manager.Entity.item_removed; 12 Efl.Ui.Position_Manager.Entity.item_removed;
13 Efl.Ui.Position_Manager.Entity.position_single_item; 13 Efl.Ui.Position_Manager.Entity.position_single_item;
14 Efl.Ui.Position_Manager.Entity.item_size_changed; 14 Efl.Ui.Position_Manager.Entity.item_size_changed;
15 Efl.Ui.Position_Manager.Entity.relative_item;
15 Efl.Ui.Layout_Orientable.orientation {set; get;} 16 Efl.Ui.Layout_Orientable.orientation {set; get;}
16 } 17 }
17} 18}
diff --git a/src/lib/elementary/efl_ui_position_manager_list.c b/src/lib/elementary/efl_ui_position_manager_list.c
index e644a77736..d3cd973a06 100644
--- a/src/lib/elementary/efl_ui_position_manager_list.c
+++ b/src/lib/elementary/efl_ui_position_manager_list.c
@@ -407,5 +407,32 @@ _efl_ui_position_manager_list_efl_object_destructor(Eo *obj, Efl_Ui_Position_Man
407 efl_destructor(efl_super(obj, MY_CLASS)); 407 efl_destructor(efl_super(obj, MY_CLASS));
408} 408}
409 409
410EOLIAN static int
411_efl_ui_position_manager_list_efl_ui_position_manager_entity_relative_item(Eo *obj EINA_UNUSED, Efl_Ui_Position_Manager_List_Data *pd, unsigned int current_id, Efl_Ui_Focus_Direction direction)
412{
413 int new_id = current_id;
414 switch(direction)
415 {
416 case EFL_UI_FOCUS_DIRECTION_RIGHT:
417 case EFL_UI_FOCUS_DIRECTION_NEXT:
418 case EFL_UI_FOCUS_DIRECTION_DOWN:
419 new_id += 1;
420 break;
421 case EFL_UI_FOCUS_DIRECTION_LEFT:
422 case EFL_UI_FOCUS_DIRECTION_PREVIOUS:
423 case EFL_UI_FOCUS_DIRECTION_UP:
424 new_id -= 1;
425 break;
426 default:
427 ERR("Uncaught case!");
428 new_id = -1;
429 break;
430 }
431 if (new_id < 0 || new_id > (int)pd->size)
432 return -1;
433 else
434 return new_id;
435}
436
410 437
411#include "efl_ui_position_manager_list.eo.c" 438#include "efl_ui_position_manager_list.eo.c"
diff --git a/src/lib/elementary/efl_ui_position_manager_list.eo b/src/lib/elementary/efl_ui_position_manager_list.eo
index 5295612724..4764424131 100644
--- a/src/lib/elementary/efl_ui_position_manager_list.eo
+++ b/src/lib/elementary/efl_ui_position_manager_list.eo
@@ -13,6 +13,7 @@ class @beta Efl.Ui.Position_Manager.List extends Efl.Object implements Efl.Ui.Po
13 Efl.Ui.Position_Manager.Entity.item_removed; 13 Efl.Ui.Position_Manager.Entity.item_removed;
14 Efl.Ui.Position_Manager.Entity.position_single_item; 14 Efl.Ui.Position_Manager.Entity.position_single_item;
15 Efl.Ui.Position_Manager.Entity.item_size_changed; 15 Efl.Ui.Position_Manager.Entity.item_size_changed;
16 Efl.Ui.Position_Manager.Entity.relative_item;
16 Efl.Ui.Layout_Orientable.orientation {set; get;} 17 Efl.Ui.Layout_Orientable.orientation {set; get;}
17 } 18 }
18} 19}
diff --git a/src/lib/elementary/meson.build b/src/lib/elementary/meson.build
index 8f0c85a12a..e42223682b 100644
--- a/src/lib/elementary/meson.build
+++ b/src/lib/elementary/meson.build
@@ -237,6 +237,7 @@ priv_eo_files = [
237 'efl_ui_exact_model.eo', 237 'efl_ui_exact_model.eo',
238 'efl_ui_average_model.eo', 238 'efl_ui_average_model.eo',
239 'efl_ui_spotlight_manager_plain.eo', 239 'efl_ui_spotlight_manager_plain.eo',
240 'efl_ui_collection_focus_manager.eo',
240] 241]
241 242
242priv_eo_file_target = [] 243priv_eo_file_target = []