diff --git a/legacy/elementary/src/lib/elm_genlist.c b/legacy/elementary/src/lib/elm_genlist.c index 6223411d21..bd24175a17 100644 --- a/legacy/elementary/src/lib/elm_genlist.c +++ b/legacy/elementary/src/lib/elm_genlist.c @@ -135,6 +135,9 @@ static void _item_move_before(Elm_Gen_Item *it, Elm_Gen_Item *before); static void _item_auto_scroll(Widget_Data *wd); static void _elm_genlist_clear(Evas_Object *obj, Eina_Bool standby); +static void _pan_child_size_get(Evas_Object *obj, + Evas_Coord *w, + Evas_Coord *h); static Evas_Smart_Class _pan_sc = EVAS_SMART_CLASS_INIT_VERSION; @@ -2283,12 +2286,67 @@ _must_recalc_idler(void *data) return ECORE_CALLBACK_CANCEL; } +static void +_scroll_item(Widget_Data *wd) +{ + Elm_Genlist_Item *it = NULL; + Evas_Coord gith = 0; + Evas_Coord ow, oh, dx = 0, dy = 0, dw = 0, dh = 0; + + evas_object_geometry_get(wd->pan_smart, NULL, NULL, &ow, &oh); + it = wd->show_item; + dx = it->x + it->item->block->x; + dy = it->y + it->item->block->y; + dw = it->item->block->w; + dh = oh; + switch (wd->scrollto_type) + { + case ELM_GENLIST_ITEM_SCROLLTO_TOP: + if (it->item->group_item) gith = it->item->group_item->item->h; + dy -= gith; + break; + case ELM_GENLIST_ITEM_SCROLLTO_MIDDLE: + dy += (it->item->h / 2 - oh / 2); + break; + case ELM_GENLIST_ITEM_SCROLLTO_IN: + default: + if ((wd->expanded_item) && + ((wd->show_item->y + wd->show_item->item->block->y + wd->show_item->item->h) + - (wd->expanded_item->y + wd->expanded_item->item->block->y) > oh)) + { + it = wd->expanded_item; + if (it->item->group_item) gith = it->item->group_item->item->h; + dx = it->x + it->item->block->x; + dy = it->y + it->item->block->y - gith; + dw = it->item->block->w; + } + else + { + if ((it->item->group_item) && (wd->pan_y > (it->y + it->item->block->y))) + gith = it->item->group_item->item->h; + dy -= gith; + dh = it->item->h; + } + break; + } + if (wd->bring_in) + elm_smart_scroller_region_bring_in(wd->scr, dx, dy, dw, dh); + else + elm_smart_scroller_child_region_show(wd->scr, dx, dy, dw, dh); + + it->item->showme = EINA_FALSE; + wd->show_item = NULL; + wd->auto_scroll_enabled = EINA_FALSE; + wd->check_scroll = EINA_FALSE; +} + static void _calc_job(void *data) { Widget_Data *wd = data; Item_Block *itb, *chb = NULL; - Evas_Coord minw = -1, minh = 0, y = 0, ow; + Evas_Coord minw = -1, minh = 0, y = 0, ow, dy = 0; + Evas_Coord pan_w = 0, pan_h = 0; int in = 0; Eina_Bool minw_change = EINA_FALSE; Eina_Bool did_must_recalc = EINA_FALSE; @@ -2340,26 +2398,7 @@ _calc_job(void *data) y += itb->h; in += itb->count; if ((showme) && (wd->show_item) && (!wd->show_item->item->queued)) - { - wd->show_item->item->showme = EINA_FALSE; - if (wd->bring_in) - elm_smart_scroller_region_bring_in(wd->scr, - wd->show_item->x + - wd->show_item->item->block->x, - wd->show_item->y + - wd->show_item->item->block->y, - wd->show_item->item->block->w, - wd->show_item->item->h); - else - elm_smart_scroller_child_region_show(wd->scr, - wd->show_item->x + - wd->show_item->item->block->x, - wd->show_item->y + - wd->show_item->item->block->y, - wd->show_item->item->block->w, - wd->show_item->item->h); - wd->show_item = NULL; - } + wd->check_scroll = EINA_TRUE; } if (minw_change) { @@ -2402,6 +2441,30 @@ _calc_job(void *data) if (!wd->must_recalc_idler) wd->must_recalc_idler = ecore_idler_add(_must_recalc_idler, wd); } + if (wd->check_scroll) + { + _pan_child_size_get(wd->pan_smart, &pan_w, &pan_h); + if (EINA_INLIST_GET(wd->show_item) == wd->items->last) + wd->scrollto_type = ELM_GENLIST_ITEM_SCROLLTO_IN; + switch (wd->scrollto_type) + { + case ELM_GENLIST_ITEM_SCROLLTO_TOP: + dy = wd->h; + break; + case ELM_GENLIST_ITEM_SCROLLTO_MIDDLE: + dy = wd->h / 2; + break; + case ELM_GENLIST_ITEM_SCROLLTO_IN: + default: + dy = 0; + break; + } + if ((pan_w > (wd->show_item->x + wd->show_item->item->block->x)) && + (pan_h > (wd->show_item->y + wd->show_item->item->block->y + dy))) + { + _scroll_item(wd); + } + } wd->calc_job = NULL; evas_object_smart_changed(wd->pan_smart); evas_event_thaw(evas_object_evas_get(wd->obj)); @@ -2959,19 +3022,22 @@ static void _item_auto_scroll(Widget_Data *wd) { if (!wd) return; - Elm_Gen_Item *it; - Eina_List *l; - Evas_Coord ox, oy, ow, oh; + Elm_Gen_Item *tmp_item = NULL; if ((wd->expanded_item) && (wd->auto_scroll_enabled)) { - evas_object_geometry_get(wd->obj, &ox, &oy, &ow, &oh); - if (wd->expanded_item->item->scrl_y > (oh + oy) / 2) + tmp_item = eina_list_data_get(eina_list_last(wd->expanded_item->item->items)); + if (!tmp_item) return; + wd->show_item = tmp_item; + wd->bring_in = EINA_TRUE; + wd->scrollto_type = ELM_GENLIST_ITEM_SCROLLTO_IN; + if ((wd->show_item->item->queued) || (!wd->show_item->item->mincalcd)) { - EINA_LIST_FOREACH(wd->expanded_item->item->items, l, it) - elm_genlist_item_bring_in(it); + wd->show_item->item->showme = EINA_TRUE; + wd->auto_scroll_enabled = EINA_FALSE; } - wd->auto_scroll_enabled = EINA_FALSE; + else + _scroll_item(wd); } } @@ -4243,6 +4309,7 @@ elm_genlist_item_show(Elm_Gen_Item *it) { it->wd->show_item = it; it->wd->bring_in = EINA_FALSE; + it->wd->scrollto_type = ELM_GENLIST_ITEM_SCROLLTO_IN; it->item->showme = EINA_TRUE; return; } @@ -4285,6 +4352,7 @@ elm_genlist_item_bring_in(Elm_Gen_Item *it) { it->wd->show_item = it; it->wd->bring_in = EINA_TRUE; + it->wd->scrollto_type = ELM_GENLIST_ITEM_SCROLLTO_IN; it->item->showme = EINA_TRUE; return; } @@ -4313,6 +4381,7 @@ elm_genlist_item_top_show(Elm_Gen_Item *it) { it->wd->show_item = it; it->wd->bring_in = EINA_FALSE; + it->wd->scrollto_type = ELM_GENLIST_ITEM_SCROLLTO_TOP; it->item->showme = EINA_TRUE; return; } @@ -4341,6 +4410,7 @@ elm_genlist_item_top_bring_in(Elm_Gen_Item *it) { it->wd->show_item = it; it->wd->bring_in = EINA_TRUE; + it->wd->scrollto_type = ELM_GENLIST_ITEM_SCROLLTO_TOP; it->item->showme = EINA_TRUE; return; } @@ -4368,6 +4438,7 @@ elm_genlist_item_middle_show(Elm_Gen_Item *it) { it->wd->show_item = it; it->wd->bring_in = EINA_FALSE; + it->wd->scrollto_type = ELM_GENLIST_ITEM_SCROLLTO_MIDDLE; it->item->showme = EINA_TRUE; return; } @@ -4394,6 +4465,7 @@ elm_genlist_item_middle_bring_in(Elm_Gen_Item *it) { it->wd->show_item = it; it->wd->bring_in = EINA_TRUE; + it->wd->scrollto_type = ELM_GENLIST_ITEM_SCROLLTO_MIDDLE; it->item->showme = EINA_TRUE; return; } diff --git a/legacy/elementary/src/lib/elm_genlist.h b/legacy/elementary/src/lib/elm_genlist.h index 3c656c0a16..fa6866b7e0 100644 --- a/legacy/elementary/src/lib/elm_genlist.h +++ b/legacy/elementary/src/lib/elm_genlist.h @@ -14,6 +14,14 @@ typedef struct Elm_Gen_Item_Type Elm_Gen_Item_Type; typedef struct Elm_Gen_Item_Tooltip Elm_Gen_Item_Tooltip; typedef struct _Widget_Data Widget_Data; +typedef enum _Elm_Genlist_Item_Scrollto_Type + { + ELM_GENLIST_ITEM_SCROLLTO_NONE = 0, /**< no scrollto */ + ELM_GENLIST_ITEM_SCROLLTO_IN = (1 << 0), /**< show, bring in */ + ELM_GENLIST_ITEM_SCROLLTO_TOP = (1 << 1), /**< top show, top bring in */ + ELM_GENLIST_ITEM_SCROLLTO_MIDDLE = (1 << 2) /**< middle show, middle bring in */ + } Elm_Genlist_Item_Scrollto_Type; + struct Elm_Gen_Item_Tooltip { const void *data; @@ -125,7 +133,7 @@ struct _Widget_Data Eina_Bool multi_timeout : 1; Eina_Bool multitouched : 1; Eina_Bool longpressed : 1; - Eina_Bool bring_in : 1; + Eina_Bool bring_in : 1; /* a flag to describe the scroll animation. (show, bring in) */ Eina_Bool compress : 1; Eina_Bool height_for_width : 1; Eina_Bool homogeneous : 1; @@ -134,6 +142,7 @@ struct _Widget_Data Eina_Bool auto_scroll_enabled : 1; Eina_Bool pan_changed : 1; Eina_Bool requeued : 1; /* this is set to EINA_TRUE when the item is re-queued. this happens when the item is un-queued but the rel item is still in the queue. this item will be processed later. */ + Eina_Bool check_scroll : 1; /* this flag means genlist is supposed to be scrolled. if this flag is set to EINA_TRUE, genlist checks whether it's ok to scroll genlist now or not. */ struct { Evas_Coord x, y; @@ -145,9 +154,9 @@ struct _Widget_Data int max_items_per_block; /* maximum number of items per block */ double longpress_timeout; /* longpress timeout. this value comes from _elm_config by default. this can be changed by elm_genlist_longpress_timeout_set() */ int generation; /* a generation of genlist. when genlist is cleared, this value will be increased and a new generation will start */ - Eina_Compare_Cb item_compare_cb; Eina_Compare_Cb item_compare_data_cb; + Elm_Genlist_Item_Scrollto_Type scrollto_type; /* a scrollto type which remembers where to scroll ex) in, top, middle */ /* The stuff below directly come from gengrid without any thinking */ unsigned int nmax;