gengrid: implement reusable content based on genlist implementation
authorMike Blumenkrantz <zmike@osg.samsung.com>
Fri, 23 Jun 2017 21:43:57 +0000 (17:43 -0400)
committerMike Blumenkrantz <zmike@osg.samsung.com>
Fri, 23 Jun 2017 21:43:44 +0000 (17:43 -0400)
@feature

src/lib/elementary/elm_gen.h
src/lib/elementary/elm_gengrid.c
src/lib/elementary/elm_widget_gengrid.h

index 932adf9..9fc1fa3 100644 (file)
@@ -89,7 +89,7 @@ typedef Eina_Bool                     (*Elm_Gen_Item_Filter_Get_Cb)(void *data,
  */
 typedef Evas_Object                  *(*Elm_Gen_Item_Reusable_Content_Get_Cb)(void *data, Evas_Object *obj, const char *part, Evas_Object *old); /**< Cache Pop class function for gen item classes. */
 
-#define ELM_GEN_ITEM_CLASS_VERSION 3
+#define ELM_GEN_ITEM_CLASS_VERSION 4
 #define ELM_GEN_ITEM_CLASS_HEADER ELM_GEN_ITEM_CLASS_VERSION, 0, 0
 
 
index 45254b3..c247084 100644 (file)
@@ -136,11 +136,14 @@ _item_cache_pop(Elm_Gengrid_Data *sd, Item_Cache *itc)
 static void
 _item_cache_free(Item_Cache *itc)
 {
+   Evas_Object *c;
    if (!itc) return;
 
    evas_object_del(itc->spacer);
    evas_object_del(itc->base_view);
    eina_stringshare_del(itc->item_style);
+   EINA_LIST_FREE(itc->contents, c)
+     evas_object_del(c);
    ELM_SAFE_FREE(itc ,free);
 }
 
@@ -173,7 +176,7 @@ _item_cache_zero(Elm_Gengrid_Data *sd)
 
 // add an item to item cache
 static Eina_Bool
-_item_cache_add(Elm_Gen_Item *it)
+_item_cache_add(Elm_Gen_Item *it, Eina_List *contents)
 {
    if (it->item->nocache_once || it->item->nocache) return EINA_FALSE;
 
@@ -196,6 +199,7 @@ _item_cache_add(Elm_Gen_Item *it)
    itc->spacer = it->spacer;
    itc->base_view = VIEW(it);
    itc->item_style = eina_stringshare_add(it->itc->item_style);
+   itc->contents = contents;
 
    if (!it->group)
      {
@@ -255,6 +259,7 @@ _item_cache_find(Elm_Gen_Item *it)
              itc->spacer = NULL;
              itc->base_view = NULL;
 
+             itc->contents = eina_list_free(itc->contents);
              _item_cache_free(itc);
              return EINA_TRUE;
           }
@@ -1014,46 +1019,53 @@ _item_content_realize(Elm_Gen_Item *it,
                       const char *parts)
 {
    Evas_Object *content;
+   Eina_List *source;
+   const char *key;
 
    if (!parts)
      {
         EINA_LIST_FREE(*contents, content)
           evas_object_del(content);
      }
-   if (it->itc->func.content_get)
-     {
-        Eina_List *source;
-        const char *key;
+   if ((!it->itc->func.content_get) &&
+      ((it->itc->version < 4) || (!it->itc->func.reusable_content_get))) return;
 
-        source = elm_widget_stringlist_get(edje_object_data_get(target, src));
+   source = elm_widget_stringlist_get(edje_object_data_get(target, src));
 
-        EINA_LIST_FREE(source, key)
-          {
-             if (parts && fnmatch(parts, key, FNM_PERIOD))
-               continue;
+   EINA_LIST_FREE(source, key)
+     {
+        if (parts && fnmatch(parts, key, FNM_PERIOD))
+          continue;
 
-             Evas_Object *old = edje_object_part_swallow_get(target, key);
-             if (old)
-               {
-                  *contents = eina_list_remove(*contents, old);
-                  evas_object_del(old);
-               }
-             content = NULL;
+        Evas_Object *old = edje_object_part_swallow_get(target, key);
+        // Reuse content by popping from the cache
+        content = NULL;
+        if (it->itc->func.reusable_content_get)
+          content = it->itc->func.reusable_content_get(
+             (void *)WIDGET_ITEM_DATA_GET(EO_OBJ(it)), WIDGET(it), key, old);
+        if (!content)
+          {
              if (it->itc->func.content_get)
                content = it->itc->func.content_get
                   ((void *)WIDGET_ITEM_DATA_GET(EO_OBJ(it)), WIDGET(it), key);
-             if (!content) continue;
-             *contents = eina_list_append(*contents, content);
-             if (!edje_object_part_swallow(target, key, content))
-               {
-                  ERR("%s (%p) can not be swallowed into %s",
-                      evas_object_type_get(content), content, key);
-                  evas_object_hide(content);
-                  continue;
-               }
-             elm_widget_sub_object_add(WIDGET(it), content);
-             if (elm_wdg_item_disabled_get(EO_OBJ(it)))
-               elm_widget_disabled_set(content, EINA_TRUE);
+             if (!content) goto out;
+          }
+        *contents = eina_list_append(*contents, content);
+        if (!edje_object_part_swallow(target, key, content))
+          {
+             ERR("%s (%p) can not be swallowed into %s",
+                 evas_object_type_get(content), content, key);
+             evas_object_del(content);
+             goto out;
+          }
+        elm_widget_sub_object_add(WIDGET(it), content);
+        if (elm_wdg_item_disabled_get(EO_OBJ(it)))
+          elm_widget_disabled_set(content, EINA_TRUE);
+out:
+        if (old && content != old)
+          {
+             *contents = eina_list_remove(*contents, old);
+             evas_object_del(old);
           }
      }
 }
@@ -1154,6 +1166,7 @@ _view_clear(Evas_Object *view, Eina_List **texts, Eina_List **contents)
      edje_object_part_text_set(view, part, NULL);
    ELM_SAFE_FREE(*texts, elm_widget_stringlist_free);
 
+   if (!contents) return;
    EINA_LIST_FREE(*contents, c)
      evas_object_del(c);
 }
@@ -1188,7 +1201,7 @@ _elm_gengrid_item_unrealize(Elm_Gen_Item *it,
      efl_event_callback_legacy_call(WIDGET(it), ELM_GENGRID_EVENT_UNREALIZED, EO_OBJ(it));
    ELM_SAFE_FREE(it->long_timer, ecore_timer_del);
 
-   _view_clear(VIEW(it), &(it->texts), &(it->contents));
+   _view_clear(VIEW(it), &(it->texts), NULL);
 
    ELM_SAFE_FREE(it->states, elm_widget_stringlist_free);
    elm_wdg_item_track_cancel(EO_OBJ(it));
@@ -1396,13 +1409,29 @@ _elm_gengrid_item_index_update(Elm_Gen_Item *it)
      }
 }
 
+static Eina_List *
+_content_cache_add(Elm_Gen_Item *it, Eina_List **cache)
+{
+   Evas_Object *content = NULL;
+   EINA_LIST_FREE(it->contents, content)
+     {
+        *cache = eina_list_append(*cache, content);
+     }
+
+   return *cache;
+}
+
 static void
 _item_unrealize_cb(Elm_Gen_Item *it)
 {
-   if (!_item_cache_add(it))
+   Eina_List *cache = NULL;
+   Evas_Object *c;
+   if (!_item_cache_add(it, _content_cache_add(it, &cache)))
      {
         ELM_SAFE_FREE(VIEW(it), evas_object_del);
         ELM_SAFE_FREE(it->spacer, evas_object_del);
+        EINA_LIST_FREE(cache, c)
+          evas_object_del(c);
      }
 }
 
index f28130f..d9cc692 100644 (file)
@@ -178,6 +178,7 @@ struct _Item_Cache
    EINA_INLIST;
    Evas_Object *base_view, *spacer;
    const char  *item_style; // it->itc->item_style
+   Eina_List *contents;
 };
 
 typedef struct _Elm_Gengrid_Pan_Data Elm_Gengrid_Pan_Data;