From 08277c48e52c1182c8069a3364e079725769db28 Mon Sep 17 00:00:00 2001 From: SangHyeon Lee Date: Wed, 2 Dec 2015 16:23:39 +0900 Subject: [PATCH] genlist: supporting homogeneous mode about each item class. Summary: previously, homogeneous was only supported for one type of items or group items, so if user want to use various item styles with different height, they should set homogeneous false. This patch is increase usability of homogeneous to make possible homogeneous for each item class, with the assumption that every item in same class have same height. Now the item class not only define it's style and class funcitons, also define the shape properties of item including height and width also. @feature Test Plan: Already exist test case in genlist group Reviewers: raster, cedric Differential Revision: https://phab.enlightenment.org/D3396 --- legacy/elementary/src/lib/elm_genlist.c | 142 +++++++----------- .../elementary/src/lib/elm_widget_genlist.h | 13 +- 2 files changed, 67 insertions(+), 88 deletions(-) diff --git a/legacy/elementary/src/lib/elm_genlist.c b/legacy/elementary/src/lib/elm_genlist.c index cb42c92c81..eb0fe4b7e0 100644 --- a/legacy/elementary/src/lib/elm_genlist.c +++ b/legacy/elementary/src/lib/elm_genlist.c @@ -167,6 +167,11 @@ static const Elm_Action key_actions[] = { {NULL, NULL} }; +static void +_size_cache_free(void *data) +{ + if(data) free(data); +} static Eina_Bool _is_no_select(Elm_Gen_Item *it) @@ -1716,6 +1721,7 @@ _item_realize(Elm_Gen_Item *it, Eina_Bool calc) { const char *treesize; + Item_Size *size = NULL; int tsize = 20; ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd); @@ -1800,21 +1806,12 @@ _item_realize(Elm_Gen_Item *it, } } + size = eina_hash_find(sd->size_caches, &(it->itc)); /* homogeneous genlist shortcut */ - if ((calc) && (sd->homogeneous) && (!it->item->mincalcd) && - (((GL_IT(it)->type & ELM_GENLIST_ITEM_GROUP) && sd->group_item_width) || - (!(GL_IT(it)->type & ELM_GENLIST_ITEM_GROUP) && sd->item_width))) + if ((calc) && (sd->homogeneous) && (!it->item->mincalcd) && size) { - if (GL_IT(it)->type & ELM_GENLIST_ITEM_GROUP) - { - it->item->w = it->item->minw = sd->group_item_width; - it->item->h = it->item->minh = sd->group_item_height; - } - else - { - it->item->w = it->item->minw = sd->item_width; - it->item->h = it->item->minh = sd->item_height; - } + GL_IT(it)->w = GL_IT(it)->minw = size->minw; + GL_IT(it)->h = GL_IT(it)->minh = size->minh; it->item->mincalcd = EINA_TRUE; } else @@ -1840,28 +1837,36 @@ _item_realize(Elm_Gen_Item *it, if (!it->item->mincalcd) { - Evas_Coord mw = -1, mh = -1; - - if (it->select_mode != ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY) - elm_coords_finger_size_adjust(1, &mw, 1, &mh); - if (sd->mode == ELM_LIST_COMPRESS) - mw = sd->prev_viewport_w; - edje_object_size_min_restricted_calc(VIEW(it), &mw, &mh, mw, mh); - it->item->w = it->item->minw = mw; - it->item->h = it->item->minh = mh; - it->item->mincalcd = EINA_TRUE; - - if ((!sd->group_item_width) && - (GL_IT(it)->type & ELM_GENLIST_ITEM_GROUP)) + if (sd->homogeneous && size) { - sd->group_item_width = mw; - sd->group_item_height = mh; + GL_IT(it)->w = GL_IT(it)->minw = size->minw; + GL_IT(it)->h = GL_IT(it)->minh = size->minh; + it->item->mincalcd = EINA_TRUE; } - else if ((!sd->item_width) && - (it->item->type == ELM_GENLIST_ITEM_NONE)) + else { - sd->item_width = mw; - sd->item_height = mh; + Evas_Coord mw = -1, mh = -1; + + if (it->select_mode != ELM_OBJECT_SELECT_MODE_DISPLAY_ONLY) + elm_coords_finger_size_adjust(1, &mw, 1, &mh); + if (sd->mode == ELM_LIST_COMPRESS) + mw = sd->prev_viewport_w; + edje_object_size_min_restricted_calc(VIEW(it), &mw, &mh, mw, mh); + it->item->w = it->item->minw = mw; + it->item->h = it->item->minh = mh; + it->item->mincalcd = EINA_TRUE; + + if (sd->homogeneous) + { + if (size) + eina_hash_del_by_key(sd->size_caches, &(it->itc)); + + size = ELM_NEW(Item_Size); + size->itc = it->itc; + size->minw = mw; + size->minh = mh; + eina_hash_add(sd->size_caches, &(it->itc), size); + } } } if (!calc) evas_object_show(VIEW(it)); @@ -3330,8 +3335,7 @@ _elm_genlist_elm_widget_theme_apply(Eo *obj, Elm_Genlist_Data *sd) _item_cache_zero(sd); _mirrored_set(obj, elm_widget_mirrored_get(obj)); - sd->item_width = sd->item_height = 0; - sd->group_item_width = sd->group_item_height = 0; + eina_hash_free_buckets(sd->size_caches); sd->minw = sd->minh = sd->realminw = 0; EINA_INLIST_FOREACH(sd->blocks, itb) @@ -3679,6 +3683,9 @@ _item_del(Elm_Gen_Item *it) it->parent->item->items = eina_list_remove(it->parent->item->items, EO_OBJ(it)); ELM_SAFE_FREE(it->item->swipe_timer, ecore_timer_del); _elm_genlist_item_del_serious(it); + + if (it->itc->refcount <= 1 && eina_hash_find(sd->size_caches, &(it->itc))) + eina_hash_del_by_key(sd->size_caches, it->itc); elm_genlist_item_class_unref((Elm_Genlist_Item_Class *)it->itc); evas_event_thaw(evas_object_evas_get(obj)); evas_event_thaw_eval(evas_object_evas_get(obj)); @@ -5053,6 +5060,7 @@ _item_block_recalc(Item_Block *itb, Eina_Bool show_me = EINA_FALSE, changed = EINA_FALSE; Evas_Coord y = 0; Elm_Genlist_Data *sd = NULL; + Item_Size *size = NULL; itb->num = in; EINA_LIST_FOREACH(itb->items, l, it) @@ -5068,71 +5076,34 @@ _item_block_recalc(Item_Block *itb, } if (!itb->realized) { - if (qadd || (itb->sd->homogeneous && - (((GL_IT(it)->type & ELM_GENLIST_ITEM_GROUP) && - (!itb->sd->group_item_height)) || - (!(GL_IT(it)->type & ELM_GENLIST_ITEM_GROUP) && - (!itb->sd->item_height))))) + if (itb->sd->homogeneous && + ((!size) || it->itc != size->itc)) + size = eina_hash_find(itb->sd->size_caches, &(it->itc)); + if (qadd || (itb->sd->homogeneous && !size)) { if (!it->item->mincalcd) changed = EINA_TRUE; if (changed) { - Eina_Bool doit = EINA_TRUE; - - if (itb->sd->homogeneous) - { - if ((GL_IT(it)->type & ELM_GENLIST_ITEM_GROUP) && - (itb->sd->group_item_height == 0)) - doit = EINA_TRUE; - else if (itb->sd->item_height == 0) - doit = EINA_TRUE; - else - doit = EINA_FALSE; - } - if (doit) + if (!size) { _item_realize(it, in, EINA_TRUE); _elm_genlist_item_unrealize(it, EINA_TRUE); } else { - if (GL_IT(it)->type & ELM_GENLIST_ITEM_GROUP) - { - it->item->w = it->item->minw = - sd->group_item_width; - it->item->h = it->item->minh = - sd->group_item_height; - } - else - { - it->item->w = it->item->minw = - sd->item_width; - it->item->h = it->item->minh = - sd->item_height; - } + it->item->w = it->item->minw = size->minw; + it->item->h = it->item->minh = size->minh; it->item->mincalcd = EINA_TRUE; } } } else { - if ((itb->sd->homogeneous) && + if ((itb->sd->homogeneous) && size && (itb->sd->mode == ELM_LIST_COMPRESS)) { - if (GL_IT(it)->type & ELM_GENLIST_ITEM_GROUP) - { - it->item->w = it->item->minw = - sd->group_item_width; - it->item->h = it->item->minh = - sd->group_item_height; - } - else - { - it->item->w = it->item->minw = - sd->item_width; - it->item->h = it->item->minh = - sd->item_height; - } + it->item->w = it->item->minw = size->minw; + it->item->h = it->item->minh = size->minh; it->item->mincalcd = EINA_TRUE; } else @@ -5482,6 +5453,7 @@ _elm_genlist_evas_object_smart_add(Eo *obj, Elm_Genlist_Data *priv) eo_do_super(obj, MY_CLASS, evas_obj_smart_add()); elm_widget_sub_object_parent_add(obj); + priv->size_caches = eina_hash_pointer_new(_size_cache_free); priv->hit_rect = evas_object_rectangle_add(evas_object_evas_get(obj)); evas_object_smart_member_add(priv->hit_rect, obj); elm_widget_sub_object_add(obj, priv->hit_rect); @@ -8024,10 +7996,10 @@ _elm_genlist_item_select_mode_set(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it, // reset homogeneous item size if (sd->homogeneous) { - if (GL_IT(it)->type & ELM_GENLIST_ITEM_GROUP) - sd->group_item_width = sd->group_item_height = 0; - else - sd->item_width = sd->item_height = 0; + Item_Size *size = + eina_hash_find(sd->size_caches, &(it->itc)); + if (size) + eina_hash_del_by_key(sd->size_caches, it->itc); } } } diff --git a/legacy/elementary/src/lib/elm_widget_genlist.h b/legacy/elementary/src/lib/elm_widget_genlist.h index 48cd9d52ea..71f613cf16 100644 --- a/legacy/elementary/src/lib/elm_widget_genlist.h +++ b/legacy/elementary/src/lib/elm_widget_genlist.h @@ -57,8 +57,6 @@ struct _Elm_Genlist_Data Elm_Object_Item *last_focused_item; /**< This records the last focused item when widget looses focus. This is required to set the focus on last focused item when widgets gets focus. */ Ecore_Job *calc_job; int walking; - int item_width, item_height; - int group_item_width, group_item_height; int minw, minh; Eina_Bool scr_minw : 1; /* a flag for determining * minimum width to limit @@ -149,8 +147,9 @@ struct _Elm_Genlist_Data unsigned int processed_count; unsigned int filtered_count; Ecore_Idle_Enterer *queue_filter_enterer; - Eina_Bool filter; + Eina_Hash *size_caches; + Eina_Bool filter; Eina_Bool focus_on_selection_enabled : 1; Eina_Bool tree_effect_enabled : 1; Eina_Bool auto_scroll_enabled : 1; @@ -204,6 +203,7 @@ struct _Elm_Genlist_Data typedef struct _Item_Block Item_Block; typedef struct _Item_Cache Item_Cache; +typedef struct _Item_Size Item_Size; struct Elm_Gen_Item_Type { @@ -279,6 +279,13 @@ struct _Item_Cache Eina_Bool tree : 1; // it->group }; +struct _Item_Size +{ + const Elm_Genlist_Item_Class *itc; + Evas_Coord minw; + Evas_Coord minh; +}; + typedef struct _Elm_Genlist_Pan_Data Elm_Genlist_Pan_Data; struct _Elm_Genlist_Pan_Data {