From 7ab200383d1b18fb8d409c38a28b6154b8a2416e Mon Sep 17 00:00:00 2001 From: Hyoyoung Chang Date: Thu, 23 Feb 2012 07:36:12 +0000 Subject: [PATCH] From: Hyoyoung Chang Subject: [E-devel] [patch] elm_gengrid - add item class management api (1/3) 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. SVN revision: 68308 --- legacy/elementary/src/bin/test_gengrid.c | 56 ++++++++++------- legacy/elementary/src/lib/elc_fileselector.c | 57 ++++++++--------- legacy/elementary/src/lib/elm_gengrid.c | 53 ++++++++++++++++ legacy/elementary/src/lib/elm_gengrid.h | 66 +++++++++++++++++++- legacy/elementary/src/lib/elm_genlist.h | 1 - 5 files changed, 181 insertions(+), 52 deletions(-) diff --git a/legacy/elementary/src/bin/test_gengrid.c b/legacy/elementary/src/bin/test_gengrid.c index 8f01a51fe7..b7ccfc7e5c 100644 --- a/legacy/elementary/src/bin/test_gengrid.c +++ b/legacy/elementary/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/legacy/elementary/src/lib/elc_fileselector.c b/legacy/elementary/src/lib/elc_fileselector.c index 67fc79f0e2..9240013f85 100644 --- a/legacy/elementary/src/lib/elc_fileselector.c +++ b/legacy/elementary/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/legacy/elementary/src/lib/elm_gengrid.c b/legacy/elementary/src/lib/elm_gengrid.c index 93af724a9a..36c76a2a8a 100644 --- a/legacy/elementary/src/lib/elm_gengrid.c +++ b/legacy/elementary/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->item_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->item_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/legacy/elementary/src/lib/elm_gengrid.h b/legacy/elementary/src/lib/elm_gengrid.h index b7a4605495..fc502b4559 100644 --- a/legacy/elementary/src/lib/elm_gengrid.h +++ b/legacy/elementary/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/legacy/elementary/src/lib/elm_genlist.h b/legacy/elementary/src/lib/elm_genlist.h index d1bd9485ab..6f9619ac67 100644 --- a/legacy/elementary/src/lib/elm_genlist.h +++ b/legacy/elementary/src/lib/elm_genlist.h @@ -365,7 +365,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 */