From 9ec49c3f4f3565121e71a94fbd6a16c53056f690 Mon Sep 17 00:00:00 2001 From: Vitalii Vorobiov Date: Thu, 28 Apr 2016 15:06:20 +0300 Subject: [PATCH] Edje_Edit: API to delete set of images Allow to delete set if it is not used by any part Function to check if set is used by any part is: edje_edit_set_usage_list_get Since it uses same struct as image_used_list_get function, it can be freed by edje_edit_image_usage_list_free. --- src/lib/edje/Edje_Edit.h | 32 +++++++- src/lib/edje/edje_edit.c | 168 ++++++++++++++++++++++++++++++++++++++- 2 files changed, 196 insertions(+), 4 deletions(-) diff --git a/src/lib/edje/Edje_Edit.h b/src/lib/edje/Edje_Edit.h index f5dd78d92b..df1785e9d6 100644 --- a/src/lib/edje/Edje_Edit.h +++ b/src/lib/edje/Edje_Edit.h @@ -113,11 +113,11 @@ typedef struct _Edje_Edit_Script_Error Edje_Edit_Script_Error; */ struct _Edje_Part_Image_Use { - const char *group; /**< name of group that use image */ + const char *group; /**< name of group (or set) that use image */ const char *part; /**< name of part that use image */ struct { const char *name; /**< name of the state */ - double value; /**< value of the state */ + double value; /**< value of the state (-1 if it is set) */ } state; /**< structure that contain state's information */ }; typedef struct _Edje_Part_Image_Use Edje_Part_Image_Use; @@ -5570,6 +5570,20 @@ edje_edit_image_set_rename(Evas_Object *obj, const char *set, const char *new_se EAPI Eina_List * edje_edit_image_set_list_get(Evas_Object *obj); +/** Get list of (Edje_Part_Image_Use *) - group-part-state triplets where given + * set is used + * + * Use edje_edit_image_usage_list_free() when you don't need it anymore. + * + * @param obj Object being edited. + * @param name The name of the image. + * @param first_only If EINA_TRUE, return only one triplete. + * + * @return Eina_List containing Edje_Part_Image_Use if successful, NULL otherwise + */ +EAPI Eina_List* +edje_edit_set_usage_list_get(Evas_Object *obj, const char *name, Eina_Bool first_only); + /** Add new image set. * * @param obj Object being edited. @@ -5582,6 +5596,20 @@ edje_edit_image_set_list_get(Evas_Object *obj); EAPI Eina_Bool edje_edit_image_set_add(Evas_Object *obj, const char *name); +/** Delete image set. + * + * Can't delete set if it is used by any part. + * + * @param obj Object being edited. + * @param name image set's name. + * + * @return @c EINA_TRUE on success, @c EINA_FALSE otherwise. + * + * @since 1.18 + */ +EAPI Eina_Bool +edje_edit_image_set_del(Evas_Object *obj, const char *name); + /** Get the list of all images inside of given set in the given edje. * Use edje_edit_string_list_free() when you don't need the list anymore. * diff --git a/src/lib/edje/edje_edit.c b/src/lib/edje/edje_edit.c index a5581bf6b0..0d480d1759 100644 --- a/src/lib/edje/edje_edit.c +++ b/src/lib/edje/edje_edit.c @@ -8552,6 +8552,168 @@ edje_edit_image_set_add(Evas_Object *obj, const char *name) return EINA_TRUE; } +EAPI Eina_List * +edje_edit_set_usage_list_get(Evas_Object *obj, const char *name, Eina_Bool first_only) +{ + Eina_List *result = NULL; + Eina_Iterator *it; + Edje_Part_Collection_Directory_Entry *pce; + Edje_Part_Image_Use *item; + Edje_Part *part; + Edje_Part_Description_Image *part_desc_image; + unsigned int i, j, k; + int set_id; + + GET_ED_OR_RETURN(NULL); + + set_id = edje_edit_image_set_id_get(obj, name); + if (set_id < 0) + return NULL; + + it = eina_hash_iterator_data_new(ed->file->collection); + +#define ITEM_ADD() \ + item = (Edje_Part_Image_Use *)calloc(1, sizeof(Edje_Part_Image_Use)); \ + item->group = eina_stringshare_add(pce->entry); \ + item->part = eina_stringshare_add(part->name); \ + item->state.name = eina_stringshare_add(part_desc_image->common.state.name); \ + item->state.value = part_desc_image->common.state.value; \ + result = eina_list_append(result, item); + + #define FIND_IN_PART_DESCRIPTION() \ + if ((part_desc_image->image.id == set_id) && \ + (part_desc_image->image.set)) \ + { \ + ITEM_ADD(); \ + if (first_only) \ + goto end; \ + else \ + continue; \ + } \ + for (k = 0; k < part_desc_image->image.tweens_count; k++) \ + { \ + if ((part_desc_image->image.tweens[k]->id == set_id) \ + && (part_desc_image->image.tweens[k]->set)) \ + { \ + ITEM_ADD(); \ + if (first_only) \ + goto end; \ + else \ + continue; \ + } \ + } + + EINA_ITERATOR_FOREACH(it, pce) + { + if (!pce->ref) continue; + for (i = 0; i < pce->ref->parts_count; i++) + { + if (!pce->ref->parts) continue; + part = pce->ref->parts[i]; + if (part->type == EDJE_PART_TYPE_IMAGE) + { + part_desc_image = (Edje_Part_Description_Image *)part->default_desc; + FIND_IN_PART_DESCRIPTION(); + for (j = 0; j < part->other.desc_count; j++) + { + part_desc_image = (Edje_Part_Description_Image *)part->other.desc[j]; + FIND_IN_PART_DESCRIPTION(); + } + } + } + } + #undef ITEM_ADD + #undef FIND_IN_PART_DESCRIPTION +end: + eina_iterator_free(it); + + return result; +} + +EAPI Eina_Bool +edje_edit_image_set_del(Evas_Object *obj, const char *name) +{ + Edje_Image_Directory_Set *de = NULL, *de_last = NULL; + Edje_Image_Directory_Set_Entry *dim = NULL; + unsigned int i, j, k; + Eina_List *used; + Eina_Iterator *it; + Edje_Part_Collection_Directory_Entry *pce; + + GET_ED_OR_RETURN(EINA_FALSE); + + if (!ed->file) return EINA_FALSE; + if (!ed->file->image_dir) return EINA_FALSE; + /* check if used */ + used = edje_edit_set_usage_list_get(obj, name, EINA_TRUE); + if (used) + { + edje_edit_image_usage_list_free(used); + WRN("Set \"%s\" is used", name); + return EINA_FALSE; + } + edje_edit_image_usage_list_free(used); + + /* find set */ + for (i = 0; i < ed->file->image_dir->sets_count; ++i) + { + de = ed->file->image_dir->sets + i; + if ((de->name) && (!strcmp(name, de->name))) + break; + } + if (i == ed->file->image_dir->sets_count) return EINA_FALSE; + de_last = ed->file->image_dir->sets + ed->file->image_dir->sets_count - 1; + + /* clear all links to images */ + EINA_LIST_FREE(de->entries, dim) + free(dim); + + --ed->file->image_dir->sets_count; + + if (de_last->id != de->id) + { + Edje_Part *part; + Edje_Part_Description_Image *part_desc_image; + + de->name = de_last->name; + it = eina_hash_iterator_data_new(ed->file->collection); + EINA_ITERATOR_FOREACH(it, pce) + { + if (!pce->ref) continue; + for (i = 0; i < pce->ref->parts_count; i++) + { + if (!pce->ref->parts) continue; + part = pce->ref->parts[i]; + if (part->type == EDJE_PART_TYPE_IMAGE) + { + part_desc_image = (Edje_Part_Description_Image *)part->default_desc; + if ((part_desc_image->image.id == de_last->id) && (part_desc_image->image.set)) + part_desc_image->image.id = de->id; + for (k = 0; k < part_desc_image->image.tweens_count; k++) + if ((part_desc_image->image.id == de_last->id) && (part_desc_image->image.set)) + part_desc_image->image.id = de->id; + + for (j = 0; j < part->other.desc_count; j++) + { + part_desc_image = (Edje_Part_Description_Image *)part->other.desc[j]; + if ((part_desc_image->image.id == de_last->id) && (part_desc_image->image.set)) + part_desc_image->image.id = de->id; + for (k = 0; k < part_desc_image->image.tweens_count; k++) + if ((part_desc_image->image.id == de_last->id) && (part_desc_image->image.set)) + part_desc_image->image.id = de->id; + } + } + } + } + eina_iterator_free(it); + } + ed->file->image_dir->sets = realloc(ed->file->image_dir->sets, + sizeof(Edje_Image_Directory_Set_Entry) * + ed->file->image_dir->sets_count); + + return EINA_TRUE; +} + EAPI Eina_List * edje_edit_image_set_images_list_get(Evas_Object *obj, const char *name) { @@ -9007,7 +9169,8 @@ edje_edit_image_usage_list_get(Evas_Object *obj, const char *name, Eina_Bool fir result = eina_list_append(result, item); #define FIND_IN_PART_DESCRIPTION() \ - if (part_desc_image->image.id == image_id) \ + if ((part_desc_image->image.id == image_id) && \ + (!part_desc_image->image.set)) \ { \ ITEM_ADD(); \ if (first_only) \ @@ -9017,7 +9180,8 @@ edje_edit_image_usage_list_get(Evas_Object *obj, const char *name, Eina_Bool fir } \ for (k = 0; k < part_desc_image->image.tweens_count; k++) \ { \ - if (part_desc_image->image.tweens[k]->id == image_id) \ + if ((part_desc_image->image.tweens[k]->id == image_id)\ + && (!part_desc_image->image.tweens[k]->set)) \ { \ ITEM_ADD(); \ if (first_only) \