edje: edje_edit - image api modification

Changed edje_edit_image_del logic: image can't be deleted if it's in use,
after deletion last image in list is moved to freed position so there are no
"holes" in image list.

Following functions added to api:
   edje_edit_image_replace
   edje_edit_image_usage_list_get
   edje_edit_image_usage_list_free

Reviewers: cedric, seoz, raster

Reviewed By: cedric

CC: reutskiy.v.v, cedric

Differential Revision: https://phab.enlightenment.org/D392

Signed-off-by: Cedric BAIL <cedric.bail@samsung.com>
This commit is contained in:
Andrii Kroitor 2013-12-19 15:47:25 +09:00 committed by Cedric BAIL
parent bf3f0f2f4a
commit 287d63c016
2 changed files with 256 additions and 19 deletions

View File

@ -50,6 +50,17 @@ struct _Edje_Edit_Script_Error
};
typedef struct _Edje_Edit_Script_Error Edje_Edit_Script_Error;
struct _Edje_Part_Image_Use
{
const char *group;
const char *part;
struct {
const char *name;
double value;
} state;
};
typedef struct _Edje_Part_Image_Use Edje_Part_Image_Use;
/**
* @file
* @brief Functions to deal with edje internal object. Don't use in standard
@ -2830,15 +2841,46 @@ EAPI Eina_Bool edje_edit_image_add(Evas_Object *obj, const char *path);
/** Delete an image from the image collection
*
* It actually write directly to the file so you don't have to save.
* Can't delete image if it is used by any part.
*
* @param obj Object being edited.
* @param name The name of the image file to include in the edje.
*
* @return EINA_TRUE if successful, EINA_FALSE otherwise (including the
* case when the name is not valid).
* case when the name is not valid or image is in use).
*/
EAPI Eina_Bool edje_edit_image_del(Evas_Object *obj, const char *name);
/** Replace one image in all descriptions
*
* @param obj Object being edited.
* @param name The name of the image to replace.
* @param name The new_name of the image to replace with.
*
* @return EINA_TRUE if successful, EINA_FALSE otherwise (including the
* case when one of the names is not valid)
*/
EAPI Eina_Bool edje_edit_image_replace(Evas_Object *obj, const char *name, const char *new_name);
/** Get list of (Edje_Part_Image_Use *) - group-part-state triplets where given
* image 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_image_usage_list_get(Evas_Object *obj, const char *name, Eina_Bool first_only);
/** Free an Eina_List of (Edje_Part_Image_Use *) allocated by an edje_edit_image_usage_list_get() function.
*
* @param lst List of strings to free.
*/
EAPI void edje_edit_image_usage_list_free(Eina_List *lst);
/** Add an image entry to the image collection
*
* This function adds the given image entry to the edje image collection. The

View File

@ -4811,11 +4811,149 @@ edje_edit_image_add(Evas_Object *obj, const char* path)
return EINA_TRUE;
}
EAPI Eina_Bool
edje_edit_image_replace(Evas_Object *obj, const char *name, const char *new_name)
{
Eina_Iterator *it;
Edje_Part_Collection_Directory_Entry *pce;
Edje_Part *part;
Edje_Part_Description_Image *part_desc_image;
unsigned int i, j, k;
int image_id, new_image_id;
GET_ED_OR_RETURN(EINA_FALSE);
image_id = edje_edit_image_id_get(obj, name);
new_image_id = edje_edit_image_id_get(obj, new_name);
if ((image_id < 0) || (new_image_id < 0))
return EINA_FALSE;
it = eina_hash_iterator_data_new(ed->file->collection);
EINA_ITERATOR_FOREACH(it, pce)
{
for (i = 0; i < pce->ref->parts_count; i++)
{
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 == image_id)
part_desc_image->image.id = new_image_id;
for (k = 0; k < part_desc_image->image.tweens_count; k++)
if (part_desc_image->image.tweens[k]->id == image_id)
part_desc_image->image.id = new_image_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 == image_id)
part_desc_image->image.id = new_image_id;
for (k = 0; k < part_desc_image->image.tweens_count; k++)
if (part_desc_image->image.tweens[k]->id == image_id)
part_desc_image->image.id = new_image_id;
}
}
}
}
eina_iterator_free(it);
return EINA_TRUE;
}
EAPI Eina_List*
edje_edit_image_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 image_id;
GET_ED_OR_RETURN(NULL);
image_id = edje_edit_image_id_get(obj, name);
if (image_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 == image_id) \
{ \
ITEM_ADD(); \
if (first_only) \
return result; \
else \
continue; \
} \
for (k = 0; k < part_desc_image->image.tweens_count; k++) \
{ \
if (part_desc_image->image.tweens[k]->id == image_id) \
{ \
ITEM_ADD(); \
if (first_only) \
return result; \
else \
continue; \
} \
}
EINA_ITERATOR_FOREACH(it, pce)
{
for (i = 0; i < pce->ref->parts_count; i++)
{
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
eina_iterator_free(it);
return result;
}
EAPI void
edje_edit_image_usage_list_free(Eina_List *list)
{
Edje_Part_Image_Use *item;
EINA_LIST_FREE(list, item)
{
eina_stringshare_del(item->group);
eina_stringshare_del(item->part);
eina_stringshare_del(item->state.name);
free(item);
}
}
EAPI Eina_Bool
edje_edit_image_del(Evas_Object *obj, const char* name)
{
Edje_Image_Directory_Entry *de;
unsigned int i;
Edje_Image_Directory_Entry *de, *de_last;
unsigned int i, j, k;
Eina_List *used;
Eina_Iterator *it;
Edje_Part_Collection_Directory_Entry *pce;
GET_EED_OR_RETURN(EINA_FALSE);
GET_ED_OR_RETURN(EINA_FALSE);
@ -4824,33 +4962,45 @@ edje_edit_image_del(Evas_Object *obj, const char* name)
if (!ed->file) return EINA_FALSE;
if (!ed->path) return EINA_FALSE;
used = edje_edit_image_usage_list_get(obj, name, EINA_TRUE);
if (used)
{
edje_edit_image_usage_list_free(used);
WRN("Image \"%s\" is used", name);
return EINA_FALSE;
}
edje_edit_image_usage_list_free(used);
/* Create Image_Directory if not exist */
if (!ed->file->image_dir)
goto invalid_image;
for (i = 0; i < ed->file->image_dir->entries_count; ++i)
{
de = ed->file->image_dir->entries + i;
de = ed->file->image_dir->entries + i;
if (de->entry
&& !strcmp(name, de->entry))
break;
if ((de->entry) && (!strcmp(name, de->entry)))
break;
}
if (i == ed->file->image_dir->entries_count)
goto invalid_image;
de_last = ed->file->image_dir->entries + ed->file->image_dir->entries_count - 1;
{
char entry[PATH_MAX];
char last_entry[PATH_MAX];
Eet_File *eetf;
void *data;
int size = 0;
/* open the eet file */
eetf = eet_open(ed->path, EET_FILE_MODE_READ_WRITE);
if (!eetf)
{
ERR("Unable to open \"%s\" for writing output", ed->path);
return EINA_FALSE;
}
{
ERR("Unable to open \"%s\" for writing output", ed->path);
return EINA_FALSE;
}
snprintf(entry, sizeof(entry), "edje/images/%i", de->id);
@ -4860,20 +5010,65 @@ edje_edit_image_del(Evas_Object *obj, const char* name)
eet_close(eetf);
return EINA_FALSE;
}
if (de_last->id != de->id)
{
snprintf(last_entry, sizeof(last_entry), "edje/images/%i", de_last->id);
data = eet_read(eetf, last_entry, &size);
eet_delete(eetf, last_entry);
eet_write(eetf, entry, data, size, 0);
}
/* write the edje_file */
if (!_edje_edit_edje_file_save(eetf, ed->file))
{
eet_close(eetf);
return EINA_FALSE;
}
{
eet_close(eetf);
return EINA_FALSE;
}
eet_close(eetf);
}
_edje_if_string_free(ed, de->entry);
de->entry = NULL;
_edje_if_string_free(ed, de->entry);
--ed->file->image_dir->entries_count;
if (de_last->id != de->id)
{
Edje_Part *part;
Edje_Part_Description_Image *part_desc_image;
de->entry = de_last->entry;
it = eina_hash_iterator_data_new(ed->file->collection);
EINA_ITERATOR_FOREACH(it, pce)
{
for (i = 0; i < pce->ref->parts_count; i++)
{
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.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.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.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.id = de->id;
}
}
}
}
eina_iterator_free(it);
}
ed->file->image_dir->entries = realloc(ed->file->image_dir->entries,
sizeof(Edje_Image_Directory_Entry) *
ed->file->image_dir->entries_count);
_edje_edit_flag_script_dirty(eed, EINA_TRUE);
return EINA_TRUE;