summaryrefslogtreecommitdiff
path: root/src/lib/elementary
diff options
context:
space:
mode:
authorMarcel Hollerbach <mail@marcel-hollerbach.de>2018-11-28 14:17:28 +0100
committerMarcel Hollerbach <mail@marcel-hollerbach.de>2018-12-04 08:45:49 +0100
commit80bdbc8b54a03d94573a63836d5d6d191dc9384f (patch)
treec54f00e4714b3d6778ce8275868200a57142dec2 /src/lib/elementary
parent1ede2302d3bf6170fc7987d38056ce0e05001738 (diff)
elm_scroller: update behaviour to match legacy behaviour more closely
This implements scrolling the scroller when the scroller is not in the maximum position of the requested relation, but there is no more focus object in that relation. Summing up, the scroller is scrolled manually, when the focus object is not fitting in the viewport, and the object is beeing out of the viewport in the requested direction. Or the scroller is not at its max position in the requested direction, and there is no more focusable object in this requested direction. ref T6804 Differential Revision: https://phab.enlightenment.org/D7382
Diffstat (limited to 'src/lib/elementary')
-rw-r--r--src/lib/elementary/elm_scroller.c84
1 files changed, 47 insertions, 37 deletions
diff --git a/src/lib/elementary/elm_scroller.c b/src/lib/elementary/elm_scroller.c
index 418d96759c..b32067e2cf 100644
--- a/src/lib/elementary/elm_scroller.c
+++ b/src/lib/elementary/elm_scroller.c
@@ -82,27 +82,6 @@ _elm_scroller_proxy_set(Evas_Object *obj, Elm_Scroller_Data *sd, Evas_Object *pr
82 evas_object_image_source_set(proxy, content); 82 evas_object_image_source_set(proxy, content);
83 evas_object_show(proxy); 83 evas_object_show(proxy);
84} 84}
85//describe position of rect2 relative to rect1
86// 1 = top outside
87// 2 = left outside
88// 4 = bottom outside
89// 8 = right outside
90static char
91_intersect_direction(Eina_Rectangle *rect1, Eina_Rectangle *rect2)
92{
93 char ret = 0;
94
95 if (rect1->y > rect2->y)
96 ret |= 1;
97 if (rect1->x > rect2->x)
98 ret |= 2;
99 if (rect1->y + rect1->h < rect2->y + rect2->h)
100 ret |= 4;
101 if (rect1->x + rect1->w < rect2->x + rect2->w)
102 ret |= 8;
103
104 return ret;
105}
106 85
107static Eina_Bool 86static Eina_Bool
108_key_action_move(Evas_Object *obj, const char *params) 87_key_action_move(Evas_Object *obj, const char *params)
@@ -133,41 +112,72 @@ _key_action_move(Evas_Object *obj, const char *params)
133 evas_object_geometry_get(sd->content, NULL, NULL, &max_x, &max_y); 112 evas_object_geometry_get(sd->content, NULL, NULL, &max_x, &max_y);
134 113
135 { 114 {
136 Efl_Ui_Focus_Object *focused; 115 Efl_Ui_Focus_Direction focus_dir = 0;
116 Efl_Ui_Focus_Object *focused, *next_target;
137 Eina_Rectangle focused_geom, viewport; 117 Eina_Rectangle focused_geom, viewport;
118 Eina_Bool scroller_adjustment = EINA_FALSE;
119
120 if (!strcmp(dir, "prior"))
121 focus_dir = EFL_UI_FOCUS_DIRECTION_PREVIOUS;
122 else if (!strcmp(dir, "next"))
123 focus_dir = EFL_UI_FOCUS_DIRECTION_NEXT;
124 else if (!strcmp(dir, "left"))
125 focus_dir = EFL_UI_FOCUS_DIRECTION_LEFT;
126 else if (!strcmp(dir, "right"))
127 focus_dir = EFL_UI_FOCUS_DIRECTION_RIGHT;
128 else if (!strcmp(dir, "up"))
129 focus_dir = EFL_UI_FOCUS_DIRECTION_UP;
130 else if (!strcmp(dir, "down"))
131 focus_dir = EFL_UI_FOCUS_DIRECTION_DOWN;
132 else return EINA_FALSE;
138 133
139 focused = efl_ui_focus_manager_focus_get(obj); 134 focused = efl_ui_focus_manager_focus_get(obj);
135 next_target = efl_ui_focus_manager_request_move(obj, focus_dir, focused, EINA_FALSE);
140 136
137 //logical movement is handled by focus directly
141 if (focused && 138 if (focused &&
142 (!strcmp(dir, "next") || 139 (focus_dir == EFL_UI_FOCUS_DIRECTION_NEXT ||
143 !strcmp(dir, "prior"))) 140 focus_dir == EFL_UI_FOCUS_DIRECTION_PREVIOUS))
144 return EINA_FALSE; 141 return EINA_FALSE;
145 142
146 if (focused && 143 //check if a object that is focused is lapping out of the viewport
147 (!strcmp(dir, "left") || 144 // if this is the case, and the object is lapping out of the viewport in
148 !strcmp(dir, "right") || 145 // the direction we want to move, then move the scroller
149 !strcmp(dir, "up") || 146 if (focused)
150 !strcmp(dir, "down")))
151 { 147 {
152 char relative; 148 Eina_Rectangle_Outside relative;
153 149
154 evas_object_geometry_get(focused, 150 evas_object_geometry_get(focused,
155 &focused_geom.x, &focused_geom.y, &focused_geom.w, &focused_geom.h); 151 &focused_geom.x, &focused_geom.y, &focused_geom.w, &focused_geom.h);
156 elm_interface_scrollable_content_viewport_geometry_get(obj, 152 elm_interface_scrollable_content_viewport_geometry_get(obj,
157 &viewport.x, &viewport.y, &viewport.w, &viewport.h); 153 &viewport.x, &viewport.y, &viewport.w, &viewport.h);
158 154
159 relative = _intersect_direction(&viewport, &focused_geom); 155 relative = eina_rectangle_outside_position(&viewport, &focused_geom);
160 156
161 //now precisly check if the direction is also lapping out 157 //now precisly check if the direction is also lapping out
162 if ((!strcmp(dir, "up") && !(relative & 1)) || 158 if ((focus_dir == EFL_UI_FOCUS_DIRECTION_UP && (relative & EINA_RECTANGLE_OUTSIDE_TOP)) ||
163 (!strcmp(dir, "left") && !(relative & 2)) || 159 (focus_dir == EFL_UI_FOCUS_DIRECTION_LEFT && (relative & EINA_RECTANGLE_OUTSIDE_LEFT)) ||
164 (!strcmp(dir, "down") && !(relative & 4)) || 160 (focus_dir == EFL_UI_FOCUS_DIRECTION_DOWN && (relative & EINA_RECTANGLE_OUTSIDE_BOTTOM)) ||
165 (!strcmp(dir, "right") && !(relative & 8))) 161 (focus_dir == EFL_UI_FOCUS_DIRECTION_RIGHT && (relative & EINA_RECTANGLE_OUTSIDE_RIGHT)))
166 { 162 {
167 //focus will handle that 163 scroller_adjustment = EINA_TRUE;
168 return EINA_FALSE;
169 } 164 }
170 } 165 }
166 //check if there is a next target in the direction where we want to move
167 //if not, and the scroller is not at its max in that relation,
168 //then move the scroller instead of the focus
169 if (!next_target)
170 {
171 if ((focus_dir == EFL_UI_FOCUS_DIRECTION_UP && (y != 0)) ||
172 (focus_dir == EFL_UI_FOCUS_DIRECTION_LEFT && (x != 0)) ||
173 (focus_dir == EFL_UI_FOCUS_DIRECTION_DOWN && (y != max_y)) ||
174 (focus_dir == EFL_UI_FOCUS_DIRECTION_RIGHT && (x != max_x)))
175 {
176 scroller_adjustment = EINA_TRUE;
177 }
178 }
179 if (!scroller_adjustment)
180 return EINA_FALSE;
171 } 181 }
172 182
173 elm_interface_scrollable_paging_get(obj, NULL, NULL, &pagesize_h, &pagesize_v); 183 elm_interface_scrollable_paging_get(obj, NULL, NULL, &pagesize_h, &pagesize_v);