forked from enlightenment/efl
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
This commit is contained in:
parent
1ede2302d3
commit
80bdbc8b54
|
@ -180,6 +180,7 @@ void test_scroller3(void *data, Evas_Object *obj, void *event_info);
|
||||||
void test_scroller4(void *data, Evas_Object *obj, void *event_info);
|
void test_scroller4(void *data, Evas_Object *obj, void *event_info);
|
||||||
void test_scroller5(void *data, Evas_Object *obj, void *event_info);
|
void test_scroller5(void *data, Evas_Object *obj, void *event_info);
|
||||||
void test_scroller6(void *data, Evas_Object *obj, void *event_info);
|
void test_scroller6(void *data, Evas_Object *obj, void *event_info);
|
||||||
|
void test_scroller7(void *data, Evas_Object *obj, void *event_info);
|
||||||
void test_efl_ui_scroller(void *data, Evas_Object *obj, void *event_info);
|
void test_efl_ui_scroller(void *data, Evas_Object *obj, void *event_info);
|
||||||
void test_efl_ui_scroller2(void *data, Evas_Object *obj, void *event_info);
|
void test_efl_ui_scroller2(void *data, Evas_Object *obj, void *event_info);
|
||||||
void test_spinner(void *data, Evas_Object *obj, void *event_info);
|
void test_spinner(void *data, Evas_Object *obj, void *event_info);
|
||||||
|
@ -1062,6 +1063,7 @@ add_tests:
|
||||||
ADD_TEST(NULL, "Scroller", "Page Scroller", test_scroller4);
|
ADD_TEST(NULL, "Scroller", "Page Scroller", test_scroller4);
|
||||||
ADD_TEST(NULL, "Scroller", "Scroller on Popup", test_scroller5);
|
ADD_TEST(NULL, "Scroller", "Scroller on Popup", test_scroller5);
|
||||||
ADD_TEST(NULL, "Scroller", "Scroller 6", test_scroller6);
|
ADD_TEST(NULL, "Scroller", "Scroller 6", test_scroller6);
|
||||||
|
ADD_TEST(NULL, "Scroller", "Scroller 7", test_scroller7);
|
||||||
ADD_TEST_EO(NULL, "Scroller", "Efl.Ui.Scroller", test_efl_ui_scroller);
|
ADD_TEST_EO(NULL, "Scroller", "Efl.Ui.Scroller", test_efl_ui_scroller);
|
||||||
|
|
||||||
//------------------------------//
|
//------------------------------//
|
||||||
|
|
|
@ -1061,3 +1061,75 @@ test_scroller6(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event
|
||||||
evas_object_resize(win, 400, 550);
|
evas_object_resize(win, 400, 550);
|
||||||
evas_object_show(win);
|
evas_object_show(win);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
test_scroller7(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
|
||||||
|
{
|
||||||
|
Evas_Object *win, *scr, *lb, *table, *btn, *btn2, *inner_table, *o, *inner_button;
|
||||||
|
|
||||||
|
win = elm_win_util_standard_add("Scroller with unfocusable content", "Scroller with unfocusable content");
|
||||||
|
elm_win_autodel_set(win, EINA_TRUE);
|
||||||
|
elm_win_focus_highlight_enabled_set(win, EINA_TRUE);
|
||||||
|
|
||||||
|
table = elm_table_add(win);
|
||||||
|
evas_object_size_hint_weight_set(table, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
|
||||||
|
evas_object_size_hint_align_set(table, EVAS_HINT_FILL, EVAS_HINT_FILL);
|
||||||
|
elm_win_resize_object_add(win, table);
|
||||||
|
evas_object_show(table);
|
||||||
|
|
||||||
|
scr = elm_scroller_add(win);
|
||||||
|
evas_object_size_hint_weight_set(scr, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
|
||||||
|
evas_object_size_hint_align_set(scr, EVAS_HINT_FILL, EVAS_HINT_FILL);
|
||||||
|
elm_table_pack(table, scr, 0, 0, 1, 1);
|
||||||
|
evas_object_show(scr);
|
||||||
|
|
||||||
|
inner_table = o = elm_table_add(win);
|
||||||
|
evas_object_size_hint_weight_set(scr, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
|
||||||
|
evas_object_size_hint_align_set(scr, EVAS_HINT_FILL, EVAS_HINT_FILL);
|
||||||
|
elm_object_content_set(scr, inner_table);
|
||||||
|
evas_object_show(scr);
|
||||||
|
|
||||||
|
lb = elm_label_add(scr);
|
||||||
|
elm_object_text_set(lb, "Enlightenment started out way back in 1996 as a project to build a Window Manager for X11. It has grown much more since then. Enlightenment still produces this Window Manager, but it has evolved to also cover Mobile, Wearable and TV UI requirements for projects such as Tizen as well as the traditional “desktop” UI. We still push out releases. See our download page for more details on the this. Visit our contribute page for our latest source code repositories. The project is currently transitioning from X11 to Wayland. We are fully committed to moving to Wayland eventually, as its the future of graphical display layers on Linux. We still primarily support Linux for Enlightenment, but there is some effort (based on help and support from users and some developers) to support BSD too.");
|
||||||
|
elm_table_pack(inner_table, lb, 0, 1, 1, 1);
|
||||||
|
evas_object_show(lb);
|
||||||
|
|
||||||
|
lb = elm_label_add(scr);
|
||||||
|
elm_object_text_set(lb, "Enlightenment started out way back in 1996 as a project to build a Window Manager for X11. It has grown much more since then. Enlightenment still produces this Window Manager, but it has evolved to also cover Mobile, Wearable and TV UI requirements for projects such as Tizen as well as the traditional “desktop” UI. We still push out releases. See our download page for more details on the this. Visit our contribute page for our latest source code repositories. The project is currently transitioning from X11 to Wayland. We are fully committed to moving to Wayland eventually, as its the future of graphical display layers on Linux. We still primarily support Linux for Enlightenment, but there is some effort (based on help and support from users and some developers) to support BSD too.");
|
||||||
|
elm_table_pack(inner_table, lb, 1, 0, 1, 1);
|
||||||
|
evas_object_show(lb);
|
||||||
|
|
||||||
|
lb = elm_label_add(scr);
|
||||||
|
elm_object_text_set(lb, "Enlightenment started out way back in 1996 as a project to build a Window Manager for X11. It has grown much more since then. Enlightenment still produces this Window Manager, but it has evolved to also cover Mobile, Wearable and TV UI requirements for projects such as Tizen as well as the traditional “desktop” UI. We still push out releases. See our download page for more details on the this. Visit our contribute page for our latest source code repositories. The project is currently transitioning from X11 to Wayland. We are fully committed to moving to Wayland eventually, as its the future of graphical display layers on Linux. We still primarily support Linux for Enlightenment, but there is some effort (based on help and support from users and some developers) to support BSD too.");
|
||||||
|
elm_table_pack(inner_table, lb, 1, 2, 1, 1);
|
||||||
|
evas_object_show(lb);
|
||||||
|
|
||||||
|
lb = elm_label_add(scr);
|
||||||
|
elm_object_text_set(lb, "Enlightenment started out way back in 1996 as a project to build a Window Manager for X11. It has grown much more since then. Enlightenment still produces this Window Manager, but it has evolved to also cover Mobile, Wearable and TV UI requirements for projects such as Tizen as well as the traditional “desktop” UI. We still push out releases. See our download page for more details on the this. Visit our contribute page for our latest source code repositories. The project is currently transitioning from X11 to Wayland. We are fully committed to moving to Wayland eventually, as its the future of graphical display layers on Linux. We still primarily support Linux for Enlightenment, but there is some effort (based on help and support from users and some developers) to support BSD too.");
|
||||||
|
elm_table_pack(inner_table, lb, 2, 1, 1, 1);
|
||||||
|
evas_object_show(lb);
|
||||||
|
|
||||||
|
btn = elm_button_add(table);
|
||||||
|
evas_object_size_hint_weight_set(btn, EVAS_HINT_EXPAND, 0.0);
|
||||||
|
evas_object_size_hint_align_set(btn, EVAS_HINT_FILL, 0.0);
|
||||||
|
elm_object_text_set(btn, "Button 2");
|
||||||
|
elm_table_pack(inner_table, btn, 1, 1, 1, 1);
|
||||||
|
evas_object_show(btn);
|
||||||
|
|
||||||
|
btn = elm_button_add(table);
|
||||||
|
evas_object_size_hint_weight_set(btn, EVAS_HINT_EXPAND, 0.0);
|
||||||
|
evas_object_size_hint_align_set(btn, EVAS_HINT_FILL, 0.0);
|
||||||
|
elm_object_text_set(btn, "Button 2");
|
||||||
|
elm_table_pack(table, btn, 0, 1, 2, 1);
|
||||||
|
evas_object_show(btn);
|
||||||
|
|
||||||
|
btn2 = elm_button_add(table);
|
||||||
|
evas_object_size_hint_weight_set(btn2, 0.0, EVAS_HINT_EXPAND);
|
||||||
|
evas_object_size_hint_align_set(btn2, 0.0, EVAS_HINT_FILL);
|
||||||
|
elm_object_text_set(btn2, "Button 3");
|
||||||
|
elm_table_pack(table, btn2, 1, 0, 1, 1);
|
||||||
|
evas_object_show(btn2);
|
||||||
|
|
||||||
|
evas_object_resize(win, 400, 550);
|
||||||
|
evas_object_show(win);
|
||||||
|
}
|
||||||
|
|
|
@ -82,27 +82,6 @@ _elm_scroller_proxy_set(Evas_Object *obj, Elm_Scroller_Data *sd, Evas_Object *pr
|
||||||
evas_object_image_source_set(proxy, content);
|
evas_object_image_source_set(proxy, content);
|
||||||
evas_object_show(proxy);
|
evas_object_show(proxy);
|
||||||
}
|
}
|
||||||
//describe position of rect2 relative to rect1
|
|
||||||
// 1 = top outside
|
|
||||||
// 2 = left outside
|
|
||||||
// 4 = bottom outside
|
|
||||||
// 8 = right outside
|
|
||||||
static char
|
|
||||||
_intersect_direction(Eina_Rectangle *rect1, Eina_Rectangle *rect2)
|
|
||||||
{
|
|
||||||
char ret = 0;
|
|
||||||
|
|
||||||
if (rect1->y > rect2->y)
|
|
||||||
ret |= 1;
|
|
||||||
if (rect1->x > rect2->x)
|
|
||||||
ret |= 2;
|
|
||||||
if (rect1->y + rect1->h < rect2->y + rect2->h)
|
|
||||||
ret |= 4;
|
|
||||||
if (rect1->x + rect1->w < rect2->x + rect2->w)
|
|
||||||
ret |= 8;
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static Eina_Bool
|
static Eina_Bool
|
||||||
_key_action_move(Evas_Object *obj, const char *params)
|
_key_action_move(Evas_Object *obj, const char *params)
|
||||||
|
@ -133,42 +112,73 @@ _key_action_move(Evas_Object *obj, const char *params)
|
||||||
evas_object_geometry_get(sd->content, NULL, NULL, &max_x, &max_y);
|
evas_object_geometry_get(sd->content, NULL, NULL, &max_x, &max_y);
|
||||||
|
|
||||||
{
|
{
|
||||||
Efl_Ui_Focus_Object *focused;
|
Efl_Ui_Focus_Direction focus_dir = 0;
|
||||||
|
Efl_Ui_Focus_Object *focused, *next_target;
|
||||||
Eina_Rectangle focused_geom, viewport;
|
Eina_Rectangle focused_geom, viewport;
|
||||||
|
Eina_Bool scroller_adjustment = EINA_FALSE;
|
||||||
|
|
||||||
|
if (!strcmp(dir, "prior"))
|
||||||
|
focus_dir = EFL_UI_FOCUS_DIRECTION_PREVIOUS;
|
||||||
|
else if (!strcmp(dir, "next"))
|
||||||
|
focus_dir = EFL_UI_FOCUS_DIRECTION_NEXT;
|
||||||
|
else if (!strcmp(dir, "left"))
|
||||||
|
focus_dir = EFL_UI_FOCUS_DIRECTION_LEFT;
|
||||||
|
else if (!strcmp(dir, "right"))
|
||||||
|
focus_dir = EFL_UI_FOCUS_DIRECTION_RIGHT;
|
||||||
|
else if (!strcmp(dir, "up"))
|
||||||
|
focus_dir = EFL_UI_FOCUS_DIRECTION_UP;
|
||||||
|
else if (!strcmp(dir, "down"))
|
||||||
|
focus_dir = EFL_UI_FOCUS_DIRECTION_DOWN;
|
||||||
|
else return EINA_FALSE;
|
||||||
|
|
||||||
focused = efl_ui_focus_manager_focus_get(obj);
|
focused = efl_ui_focus_manager_focus_get(obj);
|
||||||
|
next_target = efl_ui_focus_manager_request_move(obj, focus_dir, focused, EINA_FALSE);
|
||||||
|
|
||||||
|
//logical movement is handled by focus directly
|
||||||
if (focused &&
|
if (focused &&
|
||||||
(!strcmp(dir, "next") ||
|
(focus_dir == EFL_UI_FOCUS_DIRECTION_NEXT ||
|
||||||
!strcmp(dir, "prior")))
|
focus_dir == EFL_UI_FOCUS_DIRECTION_PREVIOUS))
|
||||||
return EINA_FALSE;
|
return EINA_FALSE;
|
||||||
|
|
||||||
if (focused &&
|
//check if a object that is focused is lapping out of the viewport
|
||||||
(!strcmp(dir, "left") ||
|
// if this is the case, and the object is lapping out of the viewport in
|
||||||
!strcmp(dir, "right") ||
|
// the direction we want to move, then move the scroller
|
||||||
!strcmp(dir, "up") ||
|
if (focused)
|
||||||
!strcmp(dir, "down")))
|
|
||||||
{
|
{
|
||||||
char relative;
|
Eina_Rectangle_Outside relative;
|
||||||
|
|
||||||
evas_object_geometry_get(focused,
|
evas_object_geometry_get(focused,
|
||||||
&focused_geom.x, &focused_geom.y, &focused_geom.w, &focused_geom.h);
|
&focused_geom.x, &focused_geom.y, &focused_geom.w, &focused_geom.h);
|
||||||
elm_interface_scrollable_content_viewport_geometry_get(obj,
|
elm_interface_scrollable_content_viewport_geometry_get(obj,
|
||||||
&viewport.x, &viewport.y, &viewport.w, &viewport.h);
|
&viewport.x, &viewport.y, &viewport.w, &viewport.h);
|
||||||
|
|
||||||
relative = _intersect_direction(&viewport, &focused_geom);
|
relative = eina_rectangle_outside_position(&viewport, &focused_geom);
|
||||||
|
|
||||||
//now precisly check if the direction is also lapping out
|
//now precisly check if the direction is also lapping out
|
||||||
if ((!strcmp(dir, "up") && !(relative & 1)) ||
|
if ((focus_dir == EFL_UI_FOCUS_DIRECTION_UP && (relative & EINA_RECTANGLE_OUTSIDE_TOP)) ||
|
||||||
(!strcmp(dir, "left") && !(relative & 2)) ||
|
(focus_dir == EFL_UI_FOCUS_DIRECTION_LEFT && (relative & EINA_RECTANGLE_OUTSIDE_LEFT)) ||
|
||||||
(!strcmp(dir, "down") && !(relative & 4)) ||
|
(focus_dir == EFL_UI_FOCUS_DIRECTION_DOWN && (relative & EINA_RECTANGLE_OUTSIDE_BOTTOM)) ||
|
||||||
(!strcmp(dir, "right") && !(relative & 8)))
|
(focus_dir == EFL_UI_FOCUS_DIRECTION_RIGHT && (relative & EINA_RECTANGLE_OUTSIDE_RIGHT)))
|
||||||
{
|
{
|
||||||
//focus will handle that
|
scroller_adjustment = EINA_TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//check if there is a next target in the direction where we want to move
|
||||||
|
//if not, and the scroller is not at its max in that relation,
|
||||||
|
//then move the scroller instead of the focus
|
||||||
|
if (!next_target)
|
||||||
|
{
|
||||||
|
if ((focus_dir == EFL_UI_FOCUS_DIRECTION_UP && (y != 0)) ||
|
||||||
|
(focus_dir == EFL_UI_FOCUS_DIRECTION_LEFT && (x != 0)) ||
|
||||||
|
(focus_dir == EFL_UI_FOCUS_DIRECTION_DOWN && (y != max_y)) ||
|
||||||
|
(focus_dir == EFL_UI_FOCUS_DIRECTION_RIGHT && (x != max_x)))
|
||||||
|
{
|
||||||
|
scroller_adjustment = EINA_TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!scroller_adjustment)
|
||||||
return EINA_FALSE;
|
return EINA_FALSE;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
elm_interface_scrollable_paging_get(obj, NULL, NULL, &pagesize_h, &pagesize_v);
|
elm_interface_scrollable_paging_get(obj, NULL, NULL, &pagesize_h, &pagesize_v);
|
||||||
elm_interface_scrollable_current_page_get(obj, &pagenumber_h, &pagenumber_v);
|
elm_interface_scrollable_current_page_get(obj, &pagenumber_h, &pagenumber_v);
|
||||||
|
|
Loading…
Reference in New Issue