Dear all.

As like genlist item class management api, I added 4 apis to elm_gengrid.

+EAPI Elm_Gengrid_Item_Class *elm_gengrid_item_class_new(void);
+EAPI void elm_gengrid_item_class_free(Elm_Gengrid_Item_Class *itc);
+EAPI void elm_gengrid_item_class_ref(Elm_Gengrid_Item_Class *itc);
+EAPI void elm_gengrid_item_class_unref(Elm_Gengrid_Item_Class *itc);

gengrid item class is maintained by gengrid in automatic manner.
it maintains its reference count. and item_class_free api marks "delete_me".
Unless item_class_free, item class will not be freed.

Thank you.
From 2435dbcf5bbefd5a9dc0db17f7204c38d893cd8b Mon Sep 17 00:00:00 2001
From: Hyoyoung Chang <hyoyoung.ch...@samsung.com>
Date: Tue, 21 Feb 2012 16:53:25 +0900
Subject: [PATCH 1/3] [gengrid] add item class management apis

---
 src/bin/test_gengrid.c     |   56 ++++++++++++++++++++++--------------
 src/lib/elc_fileselector.c |   57 +++++++++++++++++++------------------
 src/lib/elm_gengrid.c      |   53 +++++++++++++++++++++++++++++++++++
 src/lib/elm_gengrid.h      |   66 +++++++++++++++++++++++++++++++++++++++++++-
 src/lib/elm_genlist.h      |    1 -
 5 files changed, 181 insertions(+), 52 deletions(-)

diff --git a/src/bin/test_gengrid.c b/src/bin/test_gengrid.c
index 8f01a51..b7ccfc7 100644
--- a/src/bin/test_gengrid.c
+++ b/src/bin/test_gengrid.c
@@ -24,7 +24,8 @@ static const char *img[9] =
    "wood_01.jpg",
 };
 
-static Elm_Gengrid_Item_Class gic, ggic;
+static Elm_Gengrid_Item_Class *gic;
+static Elm_Gengrid_Item_Class ggic;
 
 static void
 _horizontal_grid(void *data, Evas_Object *obj, void *event_info __UNUSED__)
@@ -179,11 +180,12 @@ test_gengrid(void *data __UNUSED__, Evas_Object *obj __UNUSED__, void *event_inf
    evas_object_smart_callback_add(grid, "drag,stop", grid_drag_stop, NULL);
    evas_object_size_hint_weight_set(grid, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
 
-   gic.item_style = "default";
-   gic.func.text_get = grid_text_get;
-   gic.func.content_get = grid_content_get;
-   gic.func.state_get = grid_state_get;
-   gic.func.del = grid_del;
+   gic = elm_gengrid_item_class_new();
+   gic->item_style = "default";
+   gic->func.text_get = grid_text_get;
+   gic->func.content_get = grid_content_get;
+   gic->func.state_get = grid_state_get;
+   gic->func.del = grid_del;
 
    n = 0;
    for (i = 0; i < 12 * 12; i++)
@@ -192,11 +194,13 @@ test_gengrid(void *data __UNUSED__, Evas_Object *obj __UNUSED__, void *event_inf
         n = (n + 1) % 9;
         ti[i].mode = i;
         ti[i].path = eina_stringshare_add(buf);
-        ti[i].item = elm_gengrid_item_append(grid, &gic, &(ti[i]), grid_sel, NULL);
+        ti[i].item = elm_gengrid_item_append(grid, gic, &(ti[i]), grid_sel, NULL);
         if (!(i % 5))
           elm_gengrid_item_selected_set(ti[i].item, EINA_TRUE);
      }
 
+   elm_gengrid_item_class_free(gic);
+
    evas_object_show(grid);
    elm_win_resize_object_add(win, grid);
 
@@ -219,7 +223,7 @@ _before_bt_clicked(void *data, Evas_Object *obj __UNUSED__, void *event_info __U
    ti = malloc(sizeof(*ti));
    ti->mode = 0;
    ti->path = eina_stringshare_add(buf);
-   ti->item = elm_gengrid_item_insert_before(grid, &gic, ti, sel, grid_sel,
+   ti->item = elm_gengrid_item_insert_before(grid, gic, ti, sel, grid_sel,
                                              NULL);
 }
 
@@ -238,7 +242,7 @@ _after_bt_clicked(void *data, Evas_Object *obj __UNUSED__, void *event_info __UN
    ti = malloc(sizeof(*ti));
    ti->mode = 0;
    ti->path = eina_stringshare_add(buf);
-   ti->item = elm_gengrid_item_insert_after(grid, &gic, ti, sel, grid_sel,
+   ti->item = elm_gengrid_item_insert_after(grid, gic, ti, sel, grid_sel,
                                             NULL);
 }
 
@@ -266,7 +270,7 @@ _prepend_bt_clicked(void *data, Evas_Object *obj __UNUSED__, void *event_info __
    ti = malloc(sizeof(*ti));
    ti->mode = 0;
    ti->path = eina_stringshare_add(buf);
-   ti->item = elm_gengrid_item_prepend(grid, &gic, ti, grid_sel, NULL);
+   ti->item = elm_gengrid_item_prepend(grid, gic, ti, grid_sel, NULL);
 }
 
 static void
@@ -280,7 +284,7 @@ _append_bt_clicked(void *data, Evas_Object *obj __UNUSED__, void *event_info __U
    ti = malloc(sizeof(*ti));
    ti->mode = 0;
    ti->path = eina_stringshare_add(buf);
-   ti->item = elm_gengrid_item_append(grid, &gic, ti, grid_sel, NULL);
+   ti->item = elm_gengrid_item_append(grid, gic, ti, grid_sel, NULL);
 }
 
 static void
@@ -371,11 +375,17 @@ test_gengrid2(void *data __UNUSED__, Evas_Object *obj __UNUSED__, void *event_in
    elm_box_pack_end(hbx, ck);
    evas_object_show(ck);
 
-   gic.item_style = "default";
-   gic.func.text_get = grid_text_get;
-   gic.func.content_get = grid_content_get;
-   gic.func.state_get = grid_state_get;
-   gic.func.del = grid_del;
+   gic = elm_gengrid_item_class_new();
+
+   gic->item_style = "default";
+   gic->func.text_get = grid_text_get;
+   gic->func.content_get = grid_content_get;
+   gic->func.state_get = grid_state_get;
+   gic->func.del = grid_del;
+
+   /* item_class_ref is needed for gic. some items can be added in callbacks */
+   elm_gengrid_item_class_ref(gic);
+   elm_gengrid_item_class_free(gic);
 
    evas_object_resize(win, 600, 600);
    evas_object_show(win);
@@ -416,11 +426,12 @@ test_gengrid3(void *data __UNUSED__, Evas_Object *obj __UNUSED__, void *event_in
    evas_object_smart_callback_add(grid, "drag,stop", grid_drag_stop, NULL);
    evas_object_size_hint_weight_set(grid, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
 
-   gic.item_style = "default";
-   gic.func.text_get = grid_text_get;
-   gic.func.content_get = grid_content_get;
-   gic.func.state_get = grid_state_get;
-   gic.func.del = grid_del;
+   gic = elm_gengrid_item_class_new();
+   gic->item_style = "default";
+   gic->func.text_get = grid_text_get;
+   gic->func.content_get = grid_content_get;
+   gic->func.state_get = grid_state_get;
+   gic->func.del = grid_del;
 
    ggic.item_style = "group_index";
    ggic.func.text_get = grid_text_get;
@@ -439,10 +450,11 @@ test_gengrid3(void *data __UNUSED__, Evas_Object *obj __UNUSED__, void *event_in
           //if (i == 0 || i == 18)
           ti[i].item = elm_gengrid_item_append(grid, &ggic, &(ti[i]), grid_sel, NULL);
         else
-          ti[i].item = elm_gengrid_item_append(grid, &gic, &(ti[i]), grid_sel, NULL);
+          ti[i].item = elm_gengrid_item_append(grid, gic, &(ti[i]), grid_sel, NULL);
         if (!(i % 5))
           elm_gengrid_item_selected_set(ti[i].item, EINA_TRUE);
      }
+   elm_gengrid_item_class_free(gic);
 
    evas_object_show(grid);
    elm_win_resize_object_add(win, grid);
diff --git a/src/lib/elc_fileselector.c b/src/lib/elc_fileselector.c
index 67fc79f..9240013 100644
--- a/src/lib/elc_fileselector.c
+++ b/src/lib/elc_fileselector.c
@@ -79,11 +79,7 @@ typedef enum {
 } Elm_Fileselector_Type;
 
 static Elm_Genlist_Item_Class *list_itc[ELM_FILE_LAST];
-static Elm_Gengrid_Item_Class grid_itc[ELM_FILE_LAST] = {
-	{ ELM_GENGRID_ITEM_CLASS_HEADER, "default", { NULL, NULL, NULL, NULL } },
-	{ ELM_GENGRID_ITEM_CLASS_HEADER, "default", { NULL, NULL, NULL, NULL } },
-	{ ELM_GENGRID_ITEM_CLASS_HEADER, "default", { NULL, NULL, NULL, NULL } },
-};
+static Elm_Gengrid_Item_Class *grid_itc[ELM_FILE_LAST];
 
 static const char *widtype = NULL;
 
@@ -123,13 +119,16 @@ static void
 _del_hook(Evas_Object *obj)
 {
    Widget_Data *wd;
+   int i;
 
    wd = elm_widget_data_get(obj);
    if (!wd) return;
 
-   elm_genlist_item_class_free(list_itc[ELM_DIRECTORY]);
-   elm_genlist_item_class_free(list_itc[ELM_FILE_IMAGE]);
-   elm_genlist_item_class_free(list_itc[ELM_FILE_UNKNOW]);
+   for (i = 0; i < ELM_FILE_LAST; ++i)
+     {
+        elm_genlist_item_class_free(list_itc[i]);
+        elm_gengrid_item_class_free(grid_itc[i]);
+     }
 
 #ifdef HAVE_EIO
    if (wd->current)
@@ -561,19 +560,19 @@ _filter_cb(void *data __UNUSED__, Eio_File *handler, const Eina_File_Direct_Info
 
    if (info->type == EINA_FILE_DIR)
      {
-        eio_file_associate_direct_add(handler, "type/grid", &grid_itc[ELM_DIRECTORY], NULL);
+        eio_file_associate_direct_add(handler, "type/grid", grid_itc[ELM_DIRECTORY], NULL);
         eio_file_associate_direct_add(handler, "type/list", list_itc[ELM_DIRECTORY], NULL);
      }
    else
      {
         if (evas_object_image_extension_can_load_get(info->path + info->name_start))
           {
-             eio_file_associate_direct_add(handler, "type/grid", &grid_itc[ELM_FILE_IMAGE], NULL);
+             eio_file_associate_direct_add(handler, "type/grid", grid_itc[ELM_FILE_IMAGE], NULL);
              eio_file_associate_direct_add(handler, "type/list", list_itc[ELM_FILE_IMAGE], NULL);
           }
         else
           {
-             eio_file_associate_direct_add(handler, "type/grid", &grid_itc[ELM_FILE_UNKNOW], NULL);
+             eio_file_associate_direct_add(handler, "type/grid", grid_itc[ELM_FILE_UNKNOW], NULL);
              eio_file_associate_direct_add(handler, "type/list", list_itc[ELM_FILE_UNKNOW], NULL);
           }
      }
@@ -589,12 +588,12 @@ _file_grid_cmp(const void *a, const void *b)
    const Elm_Gengrid_Item_Class *ca = elm_gengrid_item_item_class_get(ga);
    const Elm_Gengrid_Item_Class *cb = elm_gengrid_item_item_class_get(gb);
 
-   if (ca == &grid_itc[ELM_DIRECTORY])
+   if (ca == grid_itc[ELM_DIRECTORY])
      {
-        if (cb != &grid_itc[ELM_DIRECTORY])
+        if (cb != grid_itc[ELM_DIRECTORY])
           return -1;
      }
-   else if (cb == &grid_itc[ELM_DIRECTORY])
+   else if (cb == grid_itc[ELM_DIRECTORY])
      {
         return 1;
      }
@@ -762,7 +761,7 @@ _populate(Evas_Object      *obj,
                                   ELM_GENLIST_ITEM_NONE,
                                   NULL, NULL);
         else if (wd->mode == ELM_FILESELECTOR_GRID)
-          elm_gengrid_item_append(wd->files_grid, &grid_itc[ELM_DIRECTORY],
+          elm_gengrid_item_append(wd->files_grid, grid_itc[ELM_DIRECTORY],
                                   real, /* item data */
                                   NULL, NULL);
      }
@@ -778,7 +777,7 @@ _populate(Evas_Object      *obj,
                                   parent, ELM_GENLIST_ITEM_NONE,
                                   NULL, NULL);
         else if (wd->mode == ELM_FILESELECTOR_GRID)
-          elm_gengrid_item_append(wd->files_grid, &grid_itc[type],
+          elm_gengrid_item_append(wd->files_grid, grid_itc[type],
                                   real, /* item data */
                                   NULL, NULL);
      }
@@ -863,22 +862,24 @@ elm_fileselector_add(Evas_Object *parent)
    elm_widget_sub_object_add(obj, bt);
    wd->home_button = bt;
 
-   list_itc[ELM_DIRECTORY] = elm_genlist_item_class_new();
-   list_itc[ELM_FILE_IMAGE] = elm_genlist_item_class_new();
-   list_itc[ELM_FILE_UNKNOW] = elm_genlist_item_class_new();
-
-   list_itc[ELM_DIRECTORY]->func.content_get = grid_itc[ELM_DIRECTORY].func.content_get = _itc_icon_folder_get;
-   list_itc[ELM_FILE_IMAGE]->func.content_get = grid_itc[ELM_FILE_IMAGE].func.content_get = _itc_icon_image_get;
-   list_itc[ELM_FILE_UNKNOW]->func.content_get = grid_itc[ELM_FILE_UNKNOW].func.content_get = _itc_icon_file_get;
-
    for (i = 0; i < ELM_FILE_LAST; ++i)
      {
-		 list_itc[i]->item_style = "default";
-		 list_itc[i]->func.text_get = grid_itc[i].func.text_get = _itc_text_get;
-		 list_itc[i]->func.state_get = grid_itc[i].func.state_get = _itc_state_get;
-		 list_itc[i]->func.del = grid_itc[i].func.del = _itc_del;
+        list_itc[i] = elm_genlist_item_class_new();
+        grid_itc[i] = elm_gengrid_item_class_new();
+
+        list_itc[i]->item_style = "default";
+        list_itc[i]->func.text_get = grid_itc[i]->func.text_get = _itc_text_get;
+        list_itc[i]->func.state_get = grid_itc[i]->func.state_get = _itc_state_get;
+        list_itc[i]->func.del = grid_itc[i]->func.del = _itc_del;
      }
 
+   list_itc[ELM_DIRECTORY]->func.content_get =
+     grid_itc[ELM_DIRECTORY]->func.content_get = _itc_icon_folder_get;
+   list_itc[ELM_FILE_IMAGE]->func.content_get =
+     grid_itc[ELM_FILE_IMAGE]->func.content_get = _itc_icon_image_get;
+   list_itc[ELM_FILE_UNKNOW]->func.content_get =
+     grid_itc[ELM_FILE_UNKNOW]->func.content_get = _itc_icon_file_get;
+
    li = elm_genlist_add(parent);
    elm_widget_mirrored_automatic_set(li, EINA_FALSE);
    evas_object_size_hint_align_set(li, EVAS_HINT_FILL, EVAS_HINT_FILL);
diff --git a/src/lib/elm_gengrid.c b/src/lib/elm_gengrid.c
index ae3a39e..182298c 100644
--- a/src/lib/elm_gengrid.c
+++ b/src/lib/elm_gengrid.c
@@ -1447,6 +1447,7 @@ _item_del(Elm_Gen_Item *it)
    if (it->realized) _elm_genlist_item_unrealize(it, EINA_FALSE);
    it->wd->count--;
    _elm_genlist_item_del_serious(it);
+   elm_gengrid_item_class_unref((Elm_Gengrid_Item_Class *)it->itc);
    evas_event_thaw(evas_object_evas_get(obj));
    evas_event_thaw_eval(evas_object_evas_get(obj));
 }
@@ -1896,6 +1897,7 @@ _item_new(Widget_Data                  *wd,
    if (!it) return NULL;
    elm_widget_item_disable_hook_set(it, _item_disable_hook);
    elm_widget_item_del_pre_hook_set(it, _item_del_pre_hook);
+   elm_gengrid_item_class_ref((Elm_Gengrid_Item_Class *)itc);
    it->item = ELM_NEW(Elm_Gen_Item_Type);
    wd->count++;
    it->group = it->itc->item_style && (!strcmp(it->itc->item_style, "group_index"));
@@ -2775,3 +2777,54 @@ elm_gengrid_filled_get(const Evas_Object *obj)
    return wd->filled;
 }
 
+EAPI Elm_Gengrid_Item_Class *
+elm_gengrid_item_class_new(void)
+{
+   Elm_Gengrid_Item_Class *itc;
+
+   itc = calloc(1, sizeof(Elm_Gengrid_Item_Class));
+   if (!itc)
+     return NULL;
+   itc->version = ELM_GENGRID_ITEM_CLASS_VERSION;
+   itc->refcount = 1;
+   itc->delete_me = EINA_FALSE;
+
+   return itc;
+}
+
+EAPI void
+elm_gengrid_item_class_free(Elm_Gengrid_Item_Class *itc)
+{
+   if (itc && (itc->version == ELM_GENGRID_ITEM_CLASS_VERSION))
+     {
+        if (!itc->delete_me) itc->delete_me = EINA_TRUE;
+        if (itc->refcount > 0) elm_gengrid_item_class_unref(itc);
+        else
+          {
+             itc->version = 0;
+             free(itc);
+          }
+     }
+}
+
+EAPI void
+elm_gengrid_item_class_ref(Elm_Gengrid_Item_Class *itc)
+{
+   if (itc && (itc->version == ELM_GENGRID_ITEM_CLASS_VERSION))
+     {
+        itc->refcount++;
+        if (itc->refcount == 0) itc->refcount--;
+     }
+}
+
+EAPI void
+elm_gengrid_item_class_unref(Elm_Gengrid_Item_Class *itc)
+{
+   if (itc && (itc->version == ELM_GENGRID_ITEM_CLASS_VERSION))
+     {
+        if (itc->refcount > 0) itc->refcount--;
+        if (itc->delete_me && (!itc->refcount))
+          elm_gengrid_item_class_free(itc);
+     }
+}
+
diff --git a/src/lib/elm_gengrid.h b/src/lib/elm_gengrid.h
index b7a4605..fc502b4 100644
--- a/src/lib/elm_gengrid.h
+++ b/src/lib/elm_gengrid.h
@@ -223,7 +223,6 @@
  */
 
 typedef struct _Elm_Gengrid_Item_Class      Elm_Gengrid_Item_Class; /**< Gengrid item class definition structs */
-#define ELM_GENGRID_ITEM_CLASS_HEADER       0, 0, 0
 
 #define Elm_Gengrid_Item_Class Elm_Gen_Item_Class
 typedef struct _Elm_Gengrid_Item_Class_Func Elm_Gengrid_Item_Class_Func;    /**< Class functions for gengrid item classes. */
@@ -1471,6 +1470,71 @@ EAPI void                          elm_gengrid_filled_set(Evas_Object *obj, Eina
  */
 EAPI Eina_Bool                     elm_gengrid_filled_get(const Evas_Object *obj);
 
+#define ELM_GENGRID_ITEM_CLASS_VERSION 2 /* current version number */
+
+/**
+ * Add a new gengrid item class in a given gengrid widget.
+ *
+ * @return New allocated a gengrid item class.
+ *
+ * This adds gengrid item class for the gengrid widget. When adding a item,
+ * gengrid_item_{append, prepend, insert} function needs item class of the item.
+ * Given callback paramters are used at retrieving {text, content} of
+ * added item. Set as NULL if it's not used.
+ * If there's no available memory, return can be NULL.
+ *
+ * @see elm_gengrid_item_class_free()
+ * @see elm_gengrid_item_append()
+ *
+ * @ingroup Gengrid
+ */
+EAPI Elm_Gengrid_Item_Class *elm_gengrid_item_class_new(void);
+
+/**
+ * Remove a item class in a given gengrid widget.
+ *
+ * @param itc The itc to be removed.
+ *
+ * This removes item class from the gengrid widget.
+ * Whenever it has no more references to it, item class is going to be freed.
+ * Otherwise it just decreases its reference count.
+ *
+ * @see elm_gengrid_item_class_new()
+ * @see elm_gengrid_item_class_ref()
+ * @see elm_gengrid_item_class_unref()
+ *
+ * @ingroup Gengrid
+ */
+EAPI void elm_gengrid_item_class_free(Elm_Gengrid_Item_Class *itc);
+
+/**
+ * Increments object reference count for the item class.
+ *
+ * @param itc The given item class object to reference
+ *
+ * This API just increases its reference count for item class management.
+ *
+ * @see elm_gengrid_item_class_unref()
+ *
+ * @ingroup Gengrid
+ */
+EAPI void elm_gengrid_item_class_ref(Elm_Gengrid_Item_Class *itc);
+
+/**
+ * Decrements object reference count for the item class.
+ *
+ * @param itc The given item class object to reference
+ *
+ * This API just decreases its reference count for item class management.
+ * Reference count can't be less than 0.
+ *
+ * @see elm_gengrid_item_class_ref()
+ * @see elm_gengrid_item_class_free()
+ *
+ * @ingroup Gengrid
+ */
+EAPI void elm_gengrid_item_class_unref(Elm_Gengrid_Item_Class *itc);
+
 /**
  * @}
  */
diff --git a/src/lib/elm_genlist.h b/src/lib/elm_genlist.h
index 85736eb..0775cec 100644
--- a/src/lib/elm_genlist.h
+++ b/src/lib/elm_genlist.h
@@ -364,7 +364,6 @@ typedef enum
    ELM_GENLIST_ITEM_FIELD_STATE = (1 << 2)
 } Elm_Genlist_Item_Field_Flags;
 typedef struct _Elm_Genlist_Item_Class      Elm_Genlist_Item_Class; /**< Genlist item class definition structs */
-#define ELM_GENLIST_ITEM_CLASS_HEADER       0, 0, 0
 
 #define Elm_Genlist_Item_Class Elm_Gen_Item_Class
 typedef struct _Elm_Genlist_Item_Class_Func Elm_Genlist_Item_Class_Func;    /**< Class functions for genlist item class */
-- 
1.7.5.4

------------------------------------------------------------------------------
Virtualization & Cloud Management Using Capacity Planning
Cloud computing makes use of virtualization - but cloud computing 
also focuses on allowing computing to be delivered as a service.
http://www.accelacomm.com/jaw/sfnl/114/51521223/
_______________________________________________
enlightenment-devel mailing list
enlightenment-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/enlightenment-devel

Reply via email to