genlist: supporting homogeneous mode about each item class.
authorSangHyeon Lee <sh10233.lee@samsung.com>
Wed, 2 Dec 2015 07:23:39 +0000 (16:23 +0900)
committerSangHyeon Lee <sh10233.lee@samsung.com>
Mon, 14 Dec 2015 03:03:07 +0000 (12:03 +0900)
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
legacy/elementary/src/lib/elm_widget_genlist.h

index cb42c92..eb0fe4b 100644 (file)
@@ -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);
           }
      }
 }
index 48cd9d5..71f613c 100644 (file)
@@ -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
 {