From 9dd3112f1562360684f9cdf4033bcbcb7e67703c Mon Sep 17 00:00:00 2001 From: Daniel Juyung Seo Date: Wed, 19 Mar 2014 00:48:07 +0900 Subject: [PATCH] genlist: Fixed annoying autoscrolling bug in genlist item focus. Now, genlist does not autoscroll to last focused/selected item when the genlist is focused. It tries to find the nearest visible item instead of the last focused/selected item. --- legacy/elementary/src/lib/elm_genlist.c | 69 +++++++++++++++++++++---- legacy/elementary/src/lib/elm_macros.h | 3 ++ 2 files changed, 62 insertions(+), 10 deletions(-) diff --git a/legacy/elementary/src/lib/elm_genlist.c b/legacy/elementary/src/lib/elm_genlist.c index f7efbef637..a2d372864d 100644 --- a/legacy/elementary/src/lib/elm_genlist.c +++ b/legacy/elementary/src/lib/elm_genlist.c @@ -2822,6 +2822,52 @@ _elm_genlist_smart_sub_object_del(Eo *obj, void *_pd, va_list *list) if (ret) *ret = EINA_TRUE; } +/* + * This function searches the nearest visible item based on the given item. + * If the given item is in the genlist viewport, this returns the give item. + * Or this searches the realied items and checks the nearest fully visible item + * according to the given item's position. + */ +static Elm_Object_Item * +_elm_genlist_nearest_visible_item_get(Evas_Object *obj, Elm_Object_Item *it) +{ + Evas_Coord vx = 0, vy = 0, vw = 0, vh = 0; // genlist viewport geometry + Evas_Coord ix = 0, iy = 0, iw = 0, ih = 0; // given item geometry + Evas_Coord cx = 0, cy = 0, cw = 0, ch = 0; // candidate item geometry + Eina_List *item_list = NULL, *l = NULL; + Elm_Object_Item *item = NULL; + ELM_GENLIST_DATA_GET(obj, sd); + + if (!it) return NULL; + + evas_object_geometry_get(sd->pan_obj, &vx, &vy, &vw, &vh); + evas_object_geometry_get(VIEW(it), &ix, &iy, &iw, &ih); // FIXME: check if the item is realized or not + + if (ELM_RECTS_INCLUDE(vx, vy, vw, vh, ix, iy, iw, ih)) + return it; + + item_list = elm_genlist_realized_items_get(obj); + if (iy < vy) + { + EINA_LIST_FOREACH(item_list, l, item) + { + evas_object_geometry_get(VIEW(item), &cx, &cy, &cw, &ch); + if (ELM_RECTS_INCLUDE(vx, vy, vw, vh, cx, cy, cw, ch)) + return item; + } + } + else + { + EINA_LIST_REVERSE_FOREACH(item_list, l, item) + { + evas_object_geometry_get(VIEW(item), &cx, &cy, &cw, &ch); + if (ELM_RECTS_INCLUDE(vx, vy, vw, vh, cx, cy, cw, ch)) + return item; + } + } + return NULL; +} + static void _elm_genlist_smart_on_focus(Eo *obj, void *_pd EINA_UNUSED, va_list *list) { @@ -2840,16 +2886,19 @@ _elm_genlist_smart_on_focus(Eo *obj, void *_pd EINA_UNUSED, va_list *list) if (elm_widget_focus_get(obj)) { - if (sd->last_focused_item) - elm_object_item_focus_set(sd->last_focused_item, EINA_TRUE); - else if (sd->last_selected_item) - elm_object_item_focus_set(sd->last_selected_item, EINA_TRUE); - else - { - it = elm_genlist_first_item_get(obj); - if (it) - elm_object_item_focus_set(it, EINA_TRUE); - } + if (sd->last_focused_item) + it = sd->last_focused_item; + else if (sd->last_selected_item) + it = sd->last_selected_item; + else + it = elm_genlist_first_item_get(obj); + + if (it) + { + it = _elm_genlist_nearest_visible_item_get(obj, it); + if (it) + elm_object_item_focus_set(it, EINA_TRUE); + } } else { diff --git a/legacy/elementary/src/lib/elm_macros.h b/legacy/elementary/src/lib/elm_macros.h index 176ef4742e..4656a89625 100644 --- a/legacy/elementary/src/lib/elm_macros.h +++ b/legacy/elementary/src/lib/elm_macros.h @@ -4,3 +4,6 @@ // checks if the point(xx, yy) stays out of the rectangle(x, y, w, h) area. #define ELM_RECTS_POINT_OUT(x, y, w, h, xx, yy) (((xx) < (x)) || ((yy) < (y)) || ((xx) > ((x) + (w))) || ((yy) > ((y) + (h)))) + +// check if the rect (x, y, w, h) includes whole body of rect (xx, yy, ww, hh) +#define ELM_RECTS_INCLUDE(x, y, w, h, xx, yy, ww, hh) (((x) <= (xx)) && (((x) + (w)) >= (xx)) && ((y) <= (yy)) && (((y) + (h)) >= (yy)))