forked from enlightenment/efl
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:
parent
bf3f0f2f4a
commit
287d63c016
|
@ -50,6 +50,17 @@ struct _Edje_Edit_Script_Error
|
||||||
};
|
};
|
||||||
typedef struct _Edje_Edit_Script_Error 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
|
* @file
|
||||||
* @brief Functions to deal with edje internal object. Don't use in standard
|
* @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
|
/** Delete an image from the image collection
|
||||||
*
|
*
|
||||||
* It actually write directly to the file so you don't have to save.
|
* 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 obj Object being edited.
|
||||||
* @param name The name of the image file to include in the edje.
|
* @param name The name of the image file to include in the edje.
|
||||||
*
|
*
|
||||||
* @return EINA_TRUE if successful, EINA_FALSE otherwise (including the
|
* @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);
|
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
|
/** Add an image entry to the image collection
|
||||||
*
|
*
|
||||||
* This function adds the given image entry to the edje image collection. The
|
* This function adds the given image entry to the edje image collection. The
|
||||||
|
|
|
@ -4811,11 +4811,149 @@ edje_edit_image_add(Evas_Object *obj, const char* path)
|
||||||
return EINA_TRUE;
|
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
|
EAPI Eina_Bool
|
||||||
edje_edit_image_del(Evas_Object *obj, const char* name)
|
edje_edit_image_del(Evas_Object *obj, const char* name)
|
||||||
{
|
{
|
||||||
Edje_Image_Directory_Entry *de;
|
Edje_Image_Directory_Entry *de, *de_last;
|
||||||
unsigned int i;
|
unsigned int i, j, k;
|
||||||
|
Eina_List *used;
|
||||||
|
Eina_Iterator *it;
|
||||||
|
Edje_Part_Collection_Directory_Entry *pce;
|
||||||
|
|
||||||
GET_EED_OR_RETURN(EINA_FALSE);
|
GET_EED_OR_RETURN(EINA_FALSE);
|
||||||
GET_ED_OR_RETURN(EINA_FALSE);
|
GET_ED_OR_RETURN(EINA_FALSE);
|
||||||
|
@ -4824,6 +4962,15 @@ edje_edit_image_del(Evas_Object *obj, const char* name)
|
||||||
if (!ed->file) return EINA_FALSE;
|
if (!ed->file) return EINA_FALSE;
|
||||||
if (!ed->path) 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 */
|
/* Create Image_Directory if not exist */
|
||||||
if (!ed->file->image_dir)
|
if (!ed->file->image_dir)
|
||||||
goto invalid_image;
|
goto invalid_image;
|
||||||
|
@ -4832,17 +4979,20 @@ edje_edit_image_del(Evas_Object *obj, const char* name)
|
||||||
{
|
{
|
||||||
de = ed->file->image_dir->entries + i;
|
de = ed->file->image_dir->entries + i;
|
||||||
|
|
||||||
if (de->entry
|
if ((de->entry) && (!strcmp(name, de->entry)))
|
||||||
&& !strcmp(name, de->entry))
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i == ed->file->image_dir->entries_count)
|
if (i == ed->file->image_dir->entries_count)
|
||||||
goto invalid_image;
|
goto invalid_image;
|
||||||
|
|
||||||
|
de_last = ed->file->image_dir->entries + ed->file->image_dir->entries_count - 1;
|
||||||
|
|
||||||
{
|
{
|
||||||
char entry[PATH_MAX];
|
char entry[PATH_MAX];
|
||||||
|
char last_entry[PATH_MAX];
|
||||||
Eet_File *eetf;
|
Eet_File *eetf;
|
||||||
|
void *data;
|
||||||
|
int size = 0;
|
||||||
|
|
||||||
/* open the eet file */
|
/* open the eet file */
|
||||||
eetf = eet_open(ed->path, EET_FILE_MODE_READ_WRITE);
|
eetf = eet_open(ed->path, EET_FILE_MODE_READ_WRITE);
|
||||||
|
@ -4860,7 +5010,13 @@ edje_edit_image_del(Evas_Object *obj, const char* name)
|
||||||
eet_close(eetf);
|
eet_close(eetf);
|
||||||
return EINA_FALSE;
|
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 */
|
/* write the edje_file */
|
||||||
if (!_edje_edit_edje_file_save(eetf, ed->file))
|
if (!_edje_edit_edje_file_save(eetf, ed->file))
|
||||||
{
|
{
|
||||||
|
@ -4871,9 +5027,48 @@ edje_edit_image_del(Evas_Object *obj, const char* name)
|
||||||
eet_close(eetf);
|
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);
|
_edje_edit_flag_script_dirty(eed, EINA_TRUE);
|
||||||
|
|
||||||
return EINA_TRUE;
|
return EINA_TRUE;
|
||||||
|
|
Loading…
Reference in New Issue