summaryrefslogtreecommitdiff
path: root/src/lib/elementary
diff options
context:
space:
mode:
authorMarcel Hollerbach <mail@marcel-hollerbach.de>2018-11-26 12:40:17 +0100
committerMarcel Hollerbach <mail@marcel-hollerbach.de>2018-12-04 08:45:49 +0100
commita444ff743f87c0387247835c6c78efd1a93d6f55 (patch)
treef44ca10f29705385984160c6701924e11dcfbdc9 /src/lib/elementary
parentc435cdf1731b22c4c607771180aac711bd90b48c (diff)
elm_interface_scrollable: add support for *jumping* into a scroller
Until recently we have been only registering the border elements of the graph, (so only the elements that don't have a neighboor). However this lead to the situation that a scroller that is scrolled into the middle (so not the x nor the y axis is scrolled to the max), is not accessable. Now, we register all elements that have a neighboor in the outside. The patch in the test suite is required in order to provide the correct geometry to the implementation of efl_ui_focus_manager_sub. Differential Revision: https://phab.enlightenment.org/D7360
Diffstat (limited to 'src/lib/elementary')
-rw-r--r--src/lib/elementary/efl_ui_focus_manager.eo15
-rw-r--r--src/lib/elementary/efl_ui_focus_manager_calc.c103
-rw-r--r--src/lib/elementary/efl_ui_focus_manager_calc.eo1
-rw-r--r--src/lib/elementary/efl_ui_focus_manager_root_focus.c9
-rw-r--r--src/lib/elementary/efl_ui_focus_manager_root_focus.eo1
-rw-r--r--src/lib/elementary/efl_ui_focus_manager_sub.c2
-rw-r--r--src/lib/elementary/elm_interface_scrollable.c4
7 files changed, 126 insertions, 9 deletions
diff --git a/src/lib/elementary/efl_ui_focus_manager.eo b/src/lib/elementary/efl_ui_focus_manager.eo
index 767c0b6b8d..35614712b7 100644
--- a/src/lib/elementary/efl_ui_focus_manager.eo
+++ b/src/lib/elementary/efl_ui_focus_manager.eo
@@ -1,4 +1,5 @@
1import efl_ui; 1import efl_ui;
2import eina_types;
2 3
3struct Efl.Ui.Focus.Relations { 4struct Efl.Ui.Focus.Relations {
4 [[Structure holding the graph of relations between focussable objects. 5 [[Structure holding the graph of relations between focussable objects.
@@ -90,6 +91,20 @@ interface Efl.Ui.Focus.Manager {
90 over the border objects.]] 91 over the border objects.]]
91 } 92 }
92 } 93 }
94 @property viewport_elements {
95 [[The list of elements which are at the border of the viewport.
96
97 This means one of the relations right,left or down,up are not set.
98 This call flushes all changes. See @Efl.Ui.Focus.Manager.move
99 ]]
100 get {}
101 keys {
102 viewport : Eina.Rect;
103 }
104 values {
105 viewport_elements : iterator<Efl.Ui.Focus.Object>;
106 }
107 }
93 @property root { 108 @property root {
94 [[Root node for all logical subtrees. 109 [[Root node for all logical subtrees.
95 110
diff --git a/src/lib/elementary/efl_ui_focus_manager_calc.c b/src/lib/elementary/efl_ui_focus_manager_calc.c
index e4d0332889..d6b5569cd1 100644
--- a/src/lib/elementary/efl_ui_focus_manager_calc.c
+++ b/src/lib/elementary/efl_ui_focus_manager_calc.c
@@ -937,26 +937,96 @@ typedef struct {
937 Eina_Iterator iterator; 937 Eina_Iterator iterator;
938 Eina_Iterator *real_iterator; 938 Eina_Iterator *real_iterator;
939 Efl_Ui_Focus_Manager *object; 939 Efl_Ui_Focus_Manager *object;
940 Eina_Each_Cb filter_cb;
941 Eina_Rect viewport;
942 Eina_Bool use_viewport;
940} Border_Elements_Iterator; 943} Border_Elements_Iterator;
941 944
942static Eina_Bool 945static Eina_Bool
946_border_filter_cb(Node *node, Border_Elements_Iterator *pd EINA_UNUSED)
947{
948 for(int i = EFL_UI_FOCUS_DIRECTION_UP ;i < EFL_UI_FOCUS_DIRECTION_LAST; i++)
949 {
950 if (!DIRECTION_ACCESS(node, i).one_direction)
951 {
952 return EINA_TRUE;
953 }
954 }
955 return EINA_FALSE;
956}
957
958static Eina_Bool
959eina_rectangle_real_inside(Eina_Rect rect, Eina_Rect geom)
960{
961 int min_x, max_x, min_y, max_y;
962
963 min_x = geom.rect.x;
964 min_y = geom.rect.y;
965 max_x = eina_rectangle_max_x(&geom.rect);
966 max_y = eina_rectangle_max_y(&geom.rect);
967
968 Eina_Bool inside = eina_rectangle_coords_inside(&rect.rect, min_x, min_y) &&
969 eina_rectangle_coords_inside(&rect.rect, min_x, max_y) &&
970 eina_rectangle_coords_inside(&rect.rect, max_x, min_y) &&
971 eina_rectangle_coords_inside(&rect.rect, max_x, max_y);
972
973 return inside;
974}
975
976static Eina_Bool
977_viewport_filter_cb(Node *node, Border_Elements_Iterator *pd)
978{
979 Node *partner;
980 Eina_Rect geom;
981
982 if (node->type == NODE_TYPE_ONLY_LOGICAL) return EINA_FALSE;
983
984 geom = efl_ui_focus_object_focus_geometry_get(node->focusable);
985
986 if (eina_rectangle_real_inside(pd->viewport, geom))
987 {
988 for (int i = 0; i < 4; ++i)
989 {
990 Eina_List *n, *lst = G(node).directions[i].one_direction;
991
992 if (!lst)
993 return EINA_TRUE;
994
995 EINA_LIST_FOREACH(lst, n, partner)
996 {
997 Eina_Rect partner_geom;
998 partner_geom = efl_ui_focus_object_focus_geometry_get(partner->focusable);
999 if (!eina_rectangle_real_inside(pd->viewport, partner_geom))
1000 return EINA_TRUE;
1001 }
1002 }
1003 }
1004 return EINA_FALSE;
1005}
1006
1007
1008static Eina_Bool
943_iterator_next(Border_Elements_Iterator *it, void **data) 1009_iterator_next(Border_Elements_Iterator *it, void **data)
944{ 1010{
945 Node *node; 1011 Node *node;
946 1012
947 EINA_ITERATOR_FOREACH(it->real_iterator, node) 1013 EINA_ITERATOR_FOREACH(it->real_iterator, node)
948 { 1014 {
1015 Eina_Bool use = EINA_FALSE;
949 if (node->type == NODE_TYPE_ONLY_LOGICAL) continue; 1016 if (node->type == NODE_TYPE_ONLY_LOGICAL) continue;
950 1017
951 for(int i = EFL_UI_FOCUS_DIRECTION_UP ;i < EFL_UI_FOCUS_DIRECTION_LAST; i++) 1018 if (!it->use_viewport)
1019 use = _border_filter_cb(node, it);
1020 else
1021 use = _viewport_filter_cb(node, it);
1022
1023 if (use)
952 { 1024 {
953 if (!DIRECTION_ACCESS(node, i).one_direction) 1025 *data = node->focusable;
954 { 1026 return EINA_TRUE;
955 *data = node->focusable;
956 return EINA_TRUE;
957 }
958 } 1027 }
959 } 1028 }
1029
960 return EINA_FALSE; 1030 return EINA_FALSE;
961} 1031}
962 1032
@@ -987,8 +1057,8 @@ _prepare_node(Node *root)
987 } 1057 }
988} 1058}
989 1059
990EOLIAN static Eina_Iterator* 1060static Border_Elements_Iterator*
991_efl_ui_focus_manager_calc_efl_ui_focus_manager_border_elements_get(const Eo *obj, Efl_Ui_Focus_Manager_Calc_Data *pd) 1061_elements_iterator_new(const Eo *obj, Efl_Ui_Focus_Manager_Calc_Data *pd)
992{ 1062{
993 Border_Elements_Iterator *it; 1063 Border_Elements_Iterator *it;
994 1064
@@ -1009,6 +1079,23 @@ _efl_ui_focus_manager_calc_efl_ui_focus_manager_border_elements_get(const Eo *ob
1009 it->iterator.free = FUNC_ITERATOR_FREE(_iterator_free); 1079 it->iterator.free = FUNC_ITERATOR_FREE(_iterator_free);
1010 it->object = (Eo *)obj; 1080 it->object = (Eo *)obj;
1011 1081
1082 return it;
1083}
1084
1085EOLIAN static Eina_Iterator*
1086_efl_ui_focus_manager_calc_efl_ui_focus_manager_border_elements_get(const Eo *obj, Efl_Ui_Focus_Manager_Calc_Data *pd)
1087{
1088 return (Eina_Iterator*) _elements_iterator_new(obj, pd);
1089}
1090
1091EOLIAN static Eina_Iterator*
1092_efl_ui_focus_manager_calc_efl_ui_focus_manager_viewport_elements_get(const Eo *obj, Efl_Ui_Focus_Manager_Calc_Data *pd, Eina_Rect viewport)
1093{
1094 Border_Elements_Iterator *it = _elements_iterator_new(obj, pd);
1095
1096 it->use_viewport = EINA_TRUE;
1097 it->viewport = viewport;
1098
1012 return (Eina_Iterator*) it; 1099 return (Eina_Iterator*) it;
1013} 1100}
1014 1101
diff --git a/src/lib/elementary/efl_ui_focus_manager_calc.eo b/src/lib/elementary/efl_ui_focus_manager_calc.eo
index ba4addf3d3..8bf30964a2 100644
--- a/src/lib/elementary/efl_ui_focus_manager_calc.eo
+++ b/src/lib/elementary/efl_ui_focus_manager_calc.eo
@@ -95,6 +95,7 @@ class Efl.Ui.Focus.Manager_Calc (Efl.Object, Efl.Ui.Focus.Manager) {
95 Efl.Ui.Focus.Manager.manager_focus {get; set;} 95 Efl.Ui.Focus.Manager.manager_focus {get; set;}
96 Efl.Ui.Focus.Manager.redirect {set; get;} 96 Efl.Ui.Focus.Manager.redirect {set; get;}
97 Efl.Ui.Focus.Manager.border_elements {get;} 97 Efl.Ui.Focus.Manager.border_elements {get;}
98 Efl.Ui.Focus.Manager.viewport_elements {get;}
98 Efl.Ui.Focus.Manager.root {set; get;} 99 Efl.Ui.Focus.Manager.root {set; get;}
99 Efl.Ui.Focus.Manager.request_subchild; 100 Efl.Ui.Focus.Manager.request_subchild;
100 Efl.Ui.Focus.Manager.fetch; 101 Efl.Ui.Focus.Manager.fetch;
diff --git a/src/lib/elementary/efl_ui_focus_manager_root_focus.c b/src/lib/elementary/efl_ui_focus_manager_root_focus.c
index 3070a6f183..0df8b5e862 100644
--- a/src/lib/elementary/efl_ui_focus_manager_root_focus.c
+++ b/src/lib/elementary/efl_ui_focus_manager_root_focus.c
@@ -141,6 +141,15 @@ _efl_ui_focus_manager_root_focus_efl_ui_focus_manager_border_elements_get(const
141 return efl_ui_focus_manager_border_elements_get(efl_super(obj, MY_CLASS)); 141 return efl_ui_focus_manager_border_elements_get(efl_super(obj, MY_CLASS));
142} 142}
143 143
144EOLIAN static Eina_Iterator *
145_efl_ui_focus_manager_root_focus_efl_ui_focus_manager_viewport_elements_get(const Eo *obj, Efl_Ui_Focus_Manager_Root_Focus_Data *pd, Eina_Rect viewport)
146{
147 if (pd->rect_registered)
148 return eina_list_iterator_new(pd->iterator_list);
149
150 return efl_ui_focus_manager_border_elements_get(efl_super(obj, MY_CLASS));
151}
152
144EOLIAN static Efl_Ui_Focus_Object* 153EOLIAN static Efl_Ui_Focus_Object*
145_efl_ui_focus_manager_root_focus_efl_ui_focus_manager_request_move(Eo *obj, Efl_Ui_Focus_Manager_Root_Focus_Data *pd, Efl_Ui_Focus_Direction direction, Efl_Ui_Focus_Object *child, Eina_Bool logical) 154_efl_ui_focus_manager_root_focus_efl_ui_focus_manager_request_move(Eo *obj, Efl_Ui_Focus_Manager_Root_Focus_Data *pd, Efl_Ui_Focus_Direction direction, Efl_Ui_Focus_Object *child, Eina_Bool logical)
146{ 155{
diff --git a/src/lib/elementary/efl_ui_focus_manager_root_focus.eo b/src/lib/elementary/efl_ui_focus_manager_root_focus.eo
index 81bd312abf..3f89751623 100644
--- a/src/lib/elementary/efl_ui_focus_manager_root_focus.eo
+++ b/src/lib/elementary/efl_ui_focus_manager_root_focus.eo
@@ -20,6 +20,7 @@ class Efl.Ui.Focus.Manager_Root_Focus(Efl.Ui.Focus.Manager_Calc) {
20 Efl.Ui.Focus.Manager.fetch; 20 Efl.Ui.Focus.Manager.fetch;
21 Efl.Ui.Focus.Manager.logical_end; 21 Efl.Ui.Focus.Manager.logical_end;
22 Efl.Ui.Focus.Manager.border_elements {get;} 22 Efl.Ui.Focus.Manager.border_elements {get;}
23 Efl.Ui.Focus.Manager.viewport_elements {get;}
23 Efl.Ui.Focus.Manager.request_move; 24 Efl.Ui.Focus.Manager.request_move;
24 Efl.Ui.Focus.Manager.move; 25 Efl.Ui.Focus.Manager.move;
25 Efl.Object.constructor; 26 Efl.Object.constructor;
diff --git a/src/lib/elementary/efl_ui_focus_manager_sub.c b/src/lib/elementary/efl_ui_focus_manager_sub.c
index 90ac4f7387..7fb1383ad6 100644
--- a/src/lib/elementary/efl_ui_focus_manager_sub.c
+++ b/src/lib/elementary/efl_ui_focus_manager_sub.c
@@ -53,7 +53,7 @@ _border_flush(Eo *obj, Efl_Ui_Focus_Manager_Sub_Data *pd)
53 53
54 manager = efl_ui_focus_object_focus_manager_get(obj); 54 manager = efl_ui_focus_object_focus_manager_get(obj);
55 logical = obj; 55 logical = obj;
56 borders = efl_ui_focus_manager_border_elements_get(obj); 56 borders = efl_ui_focus_manager_viewport_elements_get(obj, efl_gfx_entity_geometry_get(obj));
57 57
58 selection = NULL; 58 selection = NULL;
59 EINA_ITERATOR_FOREACH(borders, node) 59 EINA_ITERATOR_FOREACH(borders, node)
diff --git a/src/lib/elementary/elm_interface_scrollable.c b/src/lib/elementary/elm_interface_scrollable.c
index df77c8a793..3bfac1e625 100644
--- a/src/lib/elementary/elm_interface_scrollable.c
+++ b/src/lib/elementary/elm_interface_scrollable.c
@@ -103,6 +103,10 @@ _elm_pan_update(Elm_Pan_Smart_Data *psd)
103 efl_ui_focus_manager_dirty_logic_freeze(manager); 103 efl_ui_focus_manager_dirty_logic_freeze(manager);
104 evas_object_move(psd->content, psd->x - psd->px, psd->y - psd->py); 104 evas_object_move(psd->content, psd->x - psd->px, psd->y - psd->py);
105 efl_ui_focus_manager_dirty_logic_unfreeze(manager); 105 efl_ui_focus_manager_dirty_logic_unfreeze(manager);
106 //XXX: hack, right now there is no api in efl_ui_focus_manager_sub.eo to mark it dirty
107 // If we have moved the content, then emit this event, in order to ensure that the focus_manager_sub
108 // logic tries to fetch the viewport again
109 efl_event_callback_call(manager, EFL_UI_FOCUS_MANAGER_EVENT_COORDS_DIRTY, NULL);
106 } 110 }
107} 111}
108 112