forked from enlightenment/efl
1374 lines
38 KiB
C
1374 lines
38 KiB
C
#include <string.h>
|
|
|
|
#include "edje_private.h"
|
|
|
|
#ifdef EDJE_PROGRAM_CACHE
|
|
static Eina_Bool _edje_collection_free_prog_cache_matches_free_cb(const Eina_Hash *hash, const void *key, void *data, void *fdata);
|
|
#endif
|
|
static void _edje_object_pack_item_hints_set(Evas_Object *obj, Edje_Pack_Element *it);
|
|
static void _cb_signal_repeat(void *data, Evas_Object *obj, const char *signal, const char *source);
|
|
|
|
static Eina_List *_edje_swallows_collect(Edje *ed);
|
|
|
|
/************************** API Routines **************************/
|
|
|
|
/* FIXDOC: Verify/expand doc */
|
|
/** Sets the EET file and group to load @a obj from
|
|
* @param obj A valid Evas_Object handle
|
|
* @param file The path to the EET file
|
|
* @param group The group name in the Edje
|
|
* @return 0 on Error\n
|
|
* 1 on Success and sets EDJE_LOAD_ERROR_NONE
|
|
*
|
|
* Edje uses EET files, conventionally ending in .edj, to store object
|
|
* descriptions. A single file contains multiple named groups. This function
|
|
* specifies the file and group name to load @a obj from.
|
|
*/
|
|
EAPI Eina_Bool
|
|
edje_object_file_set(Evas_Object *obj, const char *file, const char *group)
|
|
{
|
|
Edje *ed;
|
|
|
|
ed = _edje_fetch(obj);
|
|
if (!ed)
|
|
return EINA_FALSE;
|
|
return ed->api->file_set(obj, file, group);
|
|
}
|
|
|
|
/* FIXDOC: Verify/expand doc. */
|
|
/** Get the file and group name that @a obj was loaded from
|
|
* @param obj A valid Evas_Object handle
|
|
* @param file A pointer to store a pointer to the filename in
|
|
* @param group A pointer to store a pointer to the group name in
|
|
*
|
|
* This gets the EET file location and group for the given Evas_Object.
|
|
* If @a obj is either not an edje file, or has not had its file/group set
|
|
* using edje_object_file_set(), then both @a file and @a group will be set
|
|
* to NULL.
|
|
*
|
|
* It is valid to pass in NULL for either @a file or @a group if you are not
|
|
* interested in one of the values.
|
|
*/
|
|
EAPI void
|
|
edje_object_file_get(const Evas_Object *obj, const char **file, const char **group)
|
|
{
|
|
Edje *ed;
|
|
|
|
ed = _edje_fetch(obj);
|
|
if (!ed)
|
|
{
|
|
if (file) *file = NULL;
|
|
if (group) *group = NULL;
|
|
return;
|
|
}
|
|
if (file) *file = ed->path;
|
|
if (group) *group = ed->group;
|
|
}
|
|
|
|
/* FIXDOC: Verify. return error? */
|
|
/** Gets the Edje load error
|
|
* @param obj A valid Evas_Object handle
|
|
*
|
|
* @return The Edje load error:\n
|
|
* EDJE_LOAD_ERROR_NONE: No Error\n
|
|
* EDJE_LOAD_ERROR_GENERIC: Generic Error\n
|
|
* EDJE_LOAD_ERROR_DOES_NOT_EXIST: Does not Exist\n
|
|
* EDJE_LOAD_ERROR_PERMISSION_DENIED: Permission Denied\n
|
|
* EDJE_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED: Resource Allocation Failed\n
|
|
* EDJE_LOAD_ERROR_CORRUPT_FILE: Corrupt File\n
|
|
* EDJE_LOAD_ERROR_UNKNOWN_FORMAT: Unknown Format\n
|
|
* EDJE_LOAD_ERROR_INCOMPATIBLE_FILE: Incompatible File\n
|
|
* EDJE_LOAD_ERROR_UNKNOWN_COLLECTION: Unknown Collection\n
|
|
* EDJE_LOAD_ERROR_RECURSIVE_REFERENCE: Recursive Reference\n
|
|
*/
|
|
EAPI int
|
|
edje_object_load_error_get(const Evas_Object *obj)
|
|
{
|
|
Edje *ed;
|
|
|
|
ed = _edje_fetch(obj);
|
|
if (!ed) return EDJE_LOAD_ERROR_NONE;
|
|
return ed->load_error;
|
|
}
|
|
|
|
EAPI const char *
|
|
edje_load_error_str(int error)
|
|
{
|
|
switch (error)
|
|
{
|
|
case EDJE_LOAD_ERROR_NONE:
|
|
return "No Error";
|
|
case EDJE_LOAD_ERROR_GENERIC:
|
|
return "Generic Error";
|
|
case EDJE_LOAD_ERROR_DOES_NOT_EXIST:
|
|
return "File Does Not Exist";
|
|
case EDJE_LOAD_ERROR_PERMISSION_DENIED:
|
|
return "Permission Denied";
|
|
case EDJE_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED:
|
|
return "Resource Allocation Failed";
|
|
case EDJE_LOAD_ERROR_CORRUPT_FILE:
|
|
return "Corrupt File";
|
|
case EDJE_LOAD_ERROR_UNKNOWN_FORMAT:
|
|
return "Unknown Format";
|
|
case EDJE_LOAD_ERROR_INCOMPATIBLE_FILE:
|
|
return "Incompatible File";
|
|
case EDJE_LOAD_ERROR_UNKNOWN_COLLECTION:
|
|
return "Unknown Collection";
|
|
case EDJE_LOAD_ERROR_RECURSIVE_REFERENCE:
|
|
return "Recursive Reference";
|
|
default:
|
|
return "Unknown Error";
|
|
}
|
|
}
|
|
|
|
|
|
/** Get a list of groups in an edje file
|
|
* @param file The path to the edje file
|
|
*
|
|
* @return The Eina_List of group names (char *)
|
|
*
|
|
* Note: the list must be freed using edje_file_collection_list_free()
|
|
* when you are done with it.
|
|
*/
|
|
EAPI Eina_List *
|
|
edje_file_collection_list(const char *file)
|
|
{
|
|
Eina_List *lst = NULL;
|
|
Edje_File *edf;
|
|
int error_ret = 0;
|
|
|
|
if ((!file) || (!*file)) return NULL;
|
|
edf = _edje_cache_file_coll_open(file, NULL, &error_ret, NULL);
|
|
if (edf)
|
|
{
|
|
Eina_Iterator *i;
|
|
const char *key;
|
|
|
|
i = eina_hash_iterator_key_new(edf->collection);
|
|
|
|
EINA_ITERATOR_FOREACH(i, key)
|
|
lst = eina_list_append(lst, eina_stringshare_add(key));
|
|
|
|
eina_iterator_free(i);
|
|
|
|
_edje_cache_file_unref(edf);
|
|
}
|
|
return lst;
|
|
}
|
|
|
|
/** Free file collection list
|
|
* @param lst The Eina_List of groups
|
|
*
|
|
* Frees the list returned by edje_file_collection_list().
|
|
*/
|
|
EAPI void
|
|
edje_file_collection_list_free(Eina_List *lst)
|
|
{
|
|
while (lst)
|
|
{
|
|
if (eina_list_data_get(lst)) eina_stringshare_del(eina_list_data_get(lst));
|
|
lst = eina_list_remove(lst, eina_list_data_get(lst));
|
|
}
|
|
}
|
|
|
|
/** Determine whether a group matching glob exists in an edje file.
|
|
* @param file The file path
|
|
* @param glob A glob to match on
|
|
*
|
|
* @return 1 if a match is found, 0 otherwise
|
|
*/
|
|
EAPI Eina_Bool
|
|
edje_file_group_exists(const char *file, const char *glob)
|
|
{
|
|
Edje_File *edf;
|
|
int error_ret = 0;
|
|
Eina_Bool succeed = EINA_FALSE;
|
|
|
|
if ((!file) || (!*file)) return EINA_FALSE;
|
|
edf = _edje_cache_file_coll_open(file, NULL, &error_ret, NULL);
|
|
if (edf)
|
|
{
|
|
Edje_Patterns *patterns;
|
|
|
|
if (edf->collection_patterns)
|
|
{
|
|
patterns = edf->collection_patterns;
|
|
}
|
|
else
|
|
{
|
|
Edje_Part_Collection_Directory_Entry *ce;
|
|
Eina_Iterator *i;
|
|
Eina_List *l = NULL;
|
|
|
|
i = eina_hash_iterator_data_new(edf->collection);
|
|
|
|
EINA_ITERATOR_FOREACH(i, ce)
|
|
l = eina_list_append(l, ce);
|
|
|
|
eina_iterator_free(i);
|
|
|
|
patterns = edje_match_collection_dir_init(l);
|
|
eina_list_free(l);
|
|
}
|
|
|
|
succeed = edje_match_collection_dir_exec(patterns, glob);
|
|
|
|
edf->collection_patterns = patterns;
|
|
|
|
_edje_cache_file_unref(edf);
|
|
}
|
|
return succeed;
|
|
}
|
|
|
|
|
|
/** Get data from the file level data block of an edje file
|
|
* @param file The path to the .edj file
|
|
* @param key The data key
|
|
* @return The string value of the data
|
|
*
|
|
* If an edje file is built from the following edc:
|
|
*
|
|
* data {
|
|
* item: "key1" "value1";
|
|
* item: "key2" "value2";
|
|
* }
|
|
* collections { ... }
|
|
*
|
|
* Then, edje_file_data_get("key1") will return "value1"
|
|
*/
|
|
EAPI char *
|
|
edje_file_data_get(const char *file, const char *key)
|
|
{
|
|
Edje_File *edf;
|
|
char *str = NULL;
|
|
int error_ret = 0;
|
|
|
|
if (key)
|
|
{
|
|
edf = _edje_cache_file_coll_open(file, NULL, &error_ret, NULL);
|
|
if (edf)
|
|
{
|
|
str = (char*) edje_string_get(eina_hash_find(edf->data, key));
|
|
|
|
if (str) str = strdup(str);
|
|
|
|
_edje_cache_file_unref(edf);
|
|
}
|
|
}
|
|
return str;
|
|
}
|
|
|
|
void
|
|
_edje_programs_patterns_clean(Edje *ed)
|
|
{
|
|
_edje_signals_sources_patterns_clean(&ed->patterns.programs);
|
|
|
|
eina_rbtree_delete(ed->patterns.programs.exact_match,
|
|
EINA_RBTREE_FREE_CB(edje_match_signal_source_free),
|
|
NULL);
|
|
ed->patterns.programs.exact_match = NULL;
|
|
|
|
free(ed->patterns.programs.u.programs.globing);
|
|
ed->patterns.programs.u.programs.globing = NULL;
|
|
}
|
|
|
|
void
|
|
_edje_programs_patterns_init(Edje *ed)
|
|
{
|
|
Edje_Signals_Sources_Patterns *ssp = &ed->patterns.programs;
|
|
Edje_Program **all;
|
|
unsigned int i, j;
|
|
|
|
if (ssp->signals_patterns)
|
|
return;
|
|
|
|
edje_match_program_hash_build(ed->collection->programs.strcmp,
|
|
ed->collection->programs.strcmp_count,
|
|
&ssp->exact_match);
|
|
|
|
j = ed->collection->programs.strncmp_count
|
|
+ ed->collection->programs.strrncmp_count
|
|
+ ed->collection->programs.fnmatch_count
|
|
+ ed->collection->programs.nocmp_count;
|
|
if (j == 0) return ;
|
|
|
|
all = malloc(sizeof (Edje_Program *) * j);
|
|
if (!all) return ;
|
|
j = 0;
|
|
|
|
/* FIXME: Build specialized data type for each case */
|
|
#define EDJE_LOAD_PROGRAMS_ADD(Array, Ed, It, Git, All) \
|
|
for (It = 0; It < Ed->collection->programs.Array##_count; ++It, ++Git) \
|
|
All[Git] = Ed->collection->programs.Array[It];
|
|
|
|
EDJE_LOAD_PROGRAMS_ADD(fnmatch, ed, i, j, all);
|
|
EDJE_LOAD_PROGRAMS_ADD(strncmp, ed, i, j, all);
|
|
EDJE_LOAD_PROGRAMS_ADD(strrncmp, ed, i, j, all);
|
|
/* FIXME: Do a special pass for that one */
|
|
EDJE_LOAD_PROGRAMS_ADD(nocmp, ed, i, j, all);
|
|
|
|
ssp->u.programs.globing = all;
|
|
ssp->u.programs.count = j;
|
|
ssp->signals_patterns = edje_match_programs_signal_init(all, j);
|
|
ssp->sources_patterns = edje_match_programs_source_init(all, j);
|
|
}
|
|
|
|
int
|
|
_edje_object_file_set_internal(Evas_Object *obj, const char *file, const char *group, Eina_List *group_path)
|
|
{
|
|
Edje *ed;
|
|
unsigned int n;
|
|
Eina_List *parts = NULL;
|
|
Eina_List *old_swallows;
|
|
int group_path_started = 0;
|
|
|
|
ed = _edje_fetch(obj);
|
|
if (!ed) return 0;
|
|
if (!file) file = "";
|
|
if (!group) group = "";
|
|
if (((ed->path) && (!strcmp(file, ed->path))) &&
|
|
(ed->group) && (!strcmp(group, ed->group)))
|
|
return 1;
|
|
|
|
old_swallows = _edje_swallows_collect(ed);
|
|
|
|
if (_edje_script_only(ed)) _edje_script_only_shutdown(ed);
|
|
if (_edje_lua_script_only(ed)) _edje_lua_script_only_shutdown(ed);
|
|
_edje_file_del(ed);
|
|
|
|
if (ed->path) eina_stringshare_del(ed->path);
|
|
if (ed->group) eina_stringshare_del(ed->group);
|
|
ed->path = eina_stringshare_add(file);
|
|
ed->group = eina_stringshare_add(group);
|
|
|
|
ed->load_error = EDJE_LOAD_ERROR_NONE;
|
|
_edje_file_add(ed);
|
|
|
|
if (ed->file && ed->file->external_dir)
|
|
{
|
|
unsigned int i;
|
|
|
|
for (i = 0; i < ed->file->external_dir->entries_count; ++i)
|
|
edje_module_load(ed->file->external_dir->entries[i].entry);
|
|
}
|
|
|
|
_edje_textblock_styles_add(ed);
|
|
_edje_textblock_style_all_update(ed);
|
|
|
|
ed->has_entries = EINA_FALSE;
|
|
|
|
if (ed->collection)
|
|
{
|
|
if (ed->collection->script_only)
|
|
{
|
|
ed->load_error = EDJE_LOAD_ERROR_NONE;
|
|
_edje_script_only_init(ed);
|
|
}
|
|
else if (ed->collection->lua_script_only)
|
|
{
|
|
ed->load_error = EDJE_LOAD_ERROR_NONE;
|
|
_edje_lua_script_only_init(ed);
|
|
}
|
|
else
|
|
{
|
|
unsigned int i;
|
|
int errors = 0;
|
|
|
|
/* colorclass stuff */
|
|
for (i = 0; i < ed->collection->parts_count; ++i)
|
|
{
|
|
Edje_Part *ep;
|
|
unsigned int k;
|
|
|
|
ep = ed->collection->parts[i];
|
|
|
|
if (errors)
|
|
break;
|
|
/* Register any color classes in this parts descriptions. */
|
|
if ((ep->default_desc) && (ep->default_desc->color_class))
|
|
_edje_color_class_member_add(ed, ep->default_desc->color_class);
|
|
|
|
for (k = 0; k < ep->other.desc_count; k++)
|
|
{
|
|
Edje_Part_Description_Common *desc;
|
|
|
|
desc = ep->other.desc[k];
|
|
|
|
if (desc->color_class)
|
|
_edje_color_class_member_add(ed, desc->color_class);
|
|
}
|
|
}
|
|
/* build real parts */
|
|
for (n = 0; n < ed->collection->parts_count; n++)
|
|
{
|
|
Edje_Part *ep;
|
|
Edje_Real_Part *rp;
|
|
|
|
ep = ed->collection->parts[n];
|
|
rp = eina_mempool_malloc(_edje_real_part_mp, sizeof(Edje_Real_Part));
|
|
if (!rp)
|
|
{
|
|
ed->load_error = EDJE_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
|
|
return 0;
|
|
}
|
|
|
|
memset(rp, 0, sizeof (Edje_Real_Part));
|
|
|
|
if ((ep->dragable.x != 0) || (ep->dragable.y != 0))
|
|
{
|
|
rp->drag = calloc(1, sizeof (Edje_Real_Part_Drag));
|
|
if (!rp->drag)
|
|
{
|
|
ed->load_error = EDJE_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
|
|
free(rp);
|
|
return 0;
|
|
}
|
|
|
|
rp->drag->step.x = FROM_INT(ep->dragable.step_x);
|
|
rp->drag->step.y = FROM_INT(ep->dragable.step_y);
|
|
}
|
|
|
|
rp->edje = ed;
|
|
_edje_ref(rp->edje);
|
|
rp->part = ep;
|
|
parts = eina_list_append(parts, rp);
|
|
rp->param1.description = ep->default_desc;
|
|
rp->chosen_description = rp->param1.description;
|
|
if (!rp->param1.description)
|
|
ERR("no default part description!");
|
|
|
|
switch (ep->type)
|
|
{
|
|
case EDJE_PART_TYPE_RECTANGLE:
|
|
rp->object = evas_object_rectangle_add(ed->evas);
|
|
break;
|
|
case EDJE_PART_TYPE_IMAGE:
|
|
rp->object = evas_object_image_add(ed->evas);
|
|
break;
|
|
case EDJE_PART_TYPE_TEXT:
|
|
_edje_text_part_on_add(ed, rp);
|
|
rp->object = evas_object_text_add(ed->evas);
|
|
evas_object_text_font_source_set(rp->object, ed->path);
|
|
break;
|
|
case EDJE_PART_TYPE_SWALLOW:
|
|
case EDJE_PART_TYPE_GROUP:
|
|
case EDJE_PART_TYPE_EXTERNAL:
|
|
rp->object = evas_object_rectangle_add(ed->evas);
|
|
evas_object_color_set(rp->object, 0, 0, 0, 0);
|
|
evas_object_pass_events_set(rp->object, 1);
|
|
evas_object_pointer_mode_set(rp->object, EVAS_OBJECT_POINTER_MODE_NOGRAB);
|
|
_edje_callbacks_focus_add(rp->object, ed, rp);
|
|
break;
|
|
case EDJE_PART_TYPE_TEXTBLOCK:
|
|
rp->object = evas_object_textblock_add(ed->evas);
|
|
break;
|
|
case EDJE_PART_TYPE_BOX:
|
|
rp->object = evas_object_box_add(ed->evas);
|
|
break;
|
|
case EDJE_PART_TYPE_TABLE:
|
|
rp->object = evas_object_table_add(ed->evas);
|
|
break;
|
|
case EDJE_PART_TYPE_GRADIENT:
|
|
ERR("SPANK ! SPANK ! SPANK !\nYOU ARE USING GRADIENT IN PART %s FROM GROUP %s INSIDE FILE %s !!\n THEY ARE NOW REMOVED !",
|
|
ep->name, group, file);
|
|
default:
|
|
ERR("wrong part type %i!", ep->type);
|
|
break;
|
|
}
|
|
|
|
if (rp->object)
|
|
{
|
|
evas_object_smart_member_add(rp->object, ed->obj);
|
|
// evas_object_layer_set(rp->object, evas_object_layer_get(ed->obj));
|
|
if (ep->type != EDJE_PART_TYPE_SWALLOW && ep->type != EDJE_PART_TYPE_GROUP && ep->type != EDJE_PART_TYPE_EXTERNAL)
|
|
{
|
|
if (ep->mouse_events)
|
|
{
|
|
_edje_callbacks_add(rp->object, ed, rp);
|
|
if (ep->repeat_events)
|
|
evas_object_repeat_events_set(rp->object, 1);
|
|
|
|
if (ep->pointer_mode != EVAS_OBJECT_POINTER_MODE_AUTOGRAB)
|
|
evas_object_pointer_mode_set(rp->object, ep->pointer_mode);
|
|
}
|
|
else
|
|
{
|
|
evas_object_pass_events_set(rp->object, 1);
|
|
evas_object_pointer_mode_set(rp->object, EVAS_OBJECT_POINTER_MODE_NOGRAB);
|
|
}
|
|
if (ep->precise_is_inside)
|
|
evas_object_precise_is_inside_set(rp->object, 1);
|
|
}
|
|
if (rp->part->clip_to_id < 0)
|
|
evas_object_clip_set(rp->object, ed->clipper);
|
|
}
|
|
}
|
|
if (n > 0)
|
|
{
|
|
Edje_Real_Part *rp;
|
|
Eina_List *l;
|
|
|
|
ed->table_parts = malloc(sizeof(Edje_Real_Part *) * n);
|
|
ed->table_parts_size = n;
|
|
/* FIXME: check malloc return */
|
|
n = 0;
|
|
EINA_LIST_FOREACH(parts, l, rp)
|
|
{
|
|
ed->table_parts[n] = rp;
|
|
n++;
|
|
}
|
|
eina_list_free(parts);
|
|
for (i = 0; i < ed->table_parts_size; i++)
|
|
{
|
|
rp = ed->table_parts[i];
|
|
if (rp->param1.description->rel1.id_x >= 0)
|
|
rp->param1.rel1_to_x = ed->table_parts[rp->param1.description->rel1.id_x % ed->table_parts_size];
|
|
if (rp->param1.description->rel1.id_y >= 0)
|
|
rp->param1.rel1_to_y = ed->table_parts[rp->param1.description->rel1.id_y % ed->table_parts_size];
|
|
if (rp->param1.description->rel2.id_x >= 0)
|
|
rp->param1.rel2_to_x = ed->table_parts[rp->param1.description->rel2.id_x % ed->table_parts_size];
|
|
if (rp->param1.description->rel2.id_y >= 0)
|
|
rp->param1.rel2_to_y = ed->table_parts[rp->param1.description->rel2.id_y % ed->table_parts_size];
|
|
if (rp->part->clip_to_id >= 0)
|
|
{
|
|
rp->clip_to = ed->table_parts[rp->part->clip_to_id % ed->table_parts_size];
|
|
if (rp->clip_to)
|
|
{
|
|
evas_object_pass_events_set(rp->clip_to->object, 1);
|
|
evas_object_pointer_mode_set(rp->clip_to->object, EVAS_OBJECT_POINTER_MODE_NOGRAB);
|
|
evas_object_clip_set(rp->object, rp->clip_to->object);
|
|
}
|
|
}
|
|
if (rp->drag)
|
|
{
|
|
if (rp->part->dragable.confine_id >= 0)
|
|
rp->drag->confine_to = ed->table_parts[rp->part->dragable.confine_id % ed->table_parts_size];
|
|
}
|
|
|
|
/* replay events for dragable */
|
|
if (rp->part->dragable.event_id >= 0)
|
|
{
|
|
rp->events_to =
|
|
ed->table_parts[rp->part->dragable.event_id % ed->table_parts_size];
|
|
/* events_to may be used only with dragable */
|
|
if (!rp->events_to->part->dragable.x &&
|
|
!rp->events_to->part->dragable.y)
|
|
rp->events_to = NULL;
|
|
}
|
|
|
|
rp->swallow_params.min.w = 0;
|
|
rp->swallow_params.min.w = 0;
|
|
rp->swallow_params.max.w = -1;
|
|
rp->swallow_params.max.h = -1;
|
|
|
|
if (rp->part->type == EDJE_PART_TYPE_TEXT
|
|
|| rp->part->type == EDJE_PART_TYPE_TEXTBLOCK)
|
|
{
|
|
Edje_Part_Description_Text *text;
|
|
|
|
text = (Edje_Part_Description_Text *) rp->param1.description;
|
|
|
|
if (ed->file->feature_ver < 1)
|
|
{
|
|
text->text.id_source = -1;
|
|
text->text.id_text_source = -1;
|
|
}
|
|
|
|
if (text->text.id_source >= 0)
|
|
rp->text.source = ed->table_parts[text->text.id_source % ed->table_parts_size];
|
|
if (text->text.id_text_source >= 0)
|
|
rp->text.text_source = ed->table_parts[text->text.id_text_source % ed->table_parts_size];
|
|
if (rp->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE)
|
|
{
|
|
_edje_entry_real_part_init(rp);
|
|
if (!ed->has_entries)
|
|
ed->has_entries = EINA_TRUE;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
_edje_programs_patterns_init(ed);
|
|
|
|
n = ed->collection->programs.fnmatch_count +
|
|
ed->collection->programs.strcmp_count +
|
|
ed->collection->programs.strncmp_count +
|
|
ed->collection->programs.strrncmp_count +
|
|
ed->collection->programs.nocmp_count;
|
|
if (n > 0)
|
|
{
|
|
Edje_Program *pr;
|
|
unsigned int i;
|
|
|
|
ed->table_programs = malloc(sizeof(Edje_Program *) * n);
|
|
if (ed->table_programs)
|
|
{
|
|
ed->table_programs_size = n;
|
|
|
|
#define EDJE_LOAD_BUILD_TABLE(Array, Ed, It, Tmp) \
|
|
for (It = 0; It < Ed->collection->programs.Array##_count; ++It) \
|
|
{ \
|
|
Tmp = Ed->collection->programs.Array[It]; \
|
|
Ed->table_programs[Tmp->id] = Tmp; \
|
|
}
|
|
|
|
EDJE_LOAD_BUILD_TABLE(fnmatch, ed, i, pr);
|
|
EDJE_LOAD_BUILD_TABLE(strcmp, ed, i, pr);
|
|
EDJE_LOAD_BUILD_TABLE(strncmp, ed, i, pr);
|
|
EDJE_LOAD_BUILD_TABLE(strrncmp, ed, i, pr);
|
|
EDJE_LOAD_BUILD_TABLE(nocmp, ed, i, pr);
|
|
}
|
|
}
|
|
_edje_ref(ed);
|
|
_edje_block(ed);
|
|
_edje_freeze(ed);
|
|
// if (ed->collection->script) _edje_embryo_script_init(ed);
|
|
_edje_var_init(ed);
|
|
for (i = 0; i < ed->table_parts_size; i++)
|
|
{
|
|
Edje_Real_Part *rp;
|
|
|
|
rp = ed->table_parts[i];
|
|
evas_object_show(rp->object);
|
|
if (_edje_block_break(ed)) break;
|
|
if (rp->drag)
|
|
{
|
|
if (rp->part->dragable.x < 0) rp->drag->val.x = FROM_DOUBLE(1.0);
|
|
if (rp->part->dragable.y < 0) rp->drag->val.x = FROM_DOUBLE(1.0);
|
|
_edje_dragable_pos_set(ed, rp, rp->drag->val.x, rp->drag->val.y);
|
|
}
|
|
}
|
|
ed->dirty = 1;
|
|
#ifdef EDJE_CALC_CACHE
|
|
ed->all_part_change = 1;
|
|
#endif
|
|
if ((evas_object_clipees_get(ed->clipper)) &&
|
|
(evas_object_visible_get(obj)))
|
|
evas_object_show(ed->clipper);
|
|
|
|
/* instantiate 'internal swallows' */
|
|
for (i = 0; i < ed->table_parts_size; i++)
|
|
{
|
|
Edje_Real_Part *rp;
|
|
/* XXX: curr_item and pack_it don't require to be NULL since
|
|
* XXX: they are just used when source != NULL and type == BOX,
|
|
* XXX: and they're always set in this case, but GCC fails to
|
|
* XXX: notice that, so let's shut it up
|
|
*/
|
|
Edje_Pack_Element **curr_item = NULL;
|
|
unsigned int item_count = 0;
|
|
Edje_Pack_Element *pack_it = NULL;
|
|
const char *source = NULL;
|
|
|
|
rp = ed->table_parts[i];
|
|
|
|
switch (rp->part->type)
|
|
{
|
|
case EDJE_PART_TYPE_GROUP:
|
|
source = rp->part->source;
|
|
break;
|
|
case EDJE_PART_TYPE_BOX:
|
|
case EDJE_PART_TYPE_TABLE:
|
|
if (rp->part->items)
|
|
{
|
|
curr_item = rp->part->items;
|
|
item_count = rp->part->items_count;
|
|
if (item_count > 0)
|
|
{
|
|
pack_it = *curr_item;
|
|
source = pack_it->source;
|
|
item_count--;
|
|
curr_item++;
|
|
}
|
|
}
|
|
break;
|
|
case EDJE_PART_TYPE_EXTERNAL:
|
|
{
|
|
Edje_Part_Description_External *external;
|
|
Evas_Object *child_obj;
|
|
|
|
external = (Edje_Part_Description_External *) rp->part->default_desc;
|
|
child_obj = _edje_external_type_add(rp->part->source,
|
|
evas_object_evas_get(ed->obj), ed->obj,
|
|
external->external_params, rp->part->name);
|
|
if (child_obj)
|
|
{
|
|
_edje_real_part_swallow(rp, child_obj);
|
|
rp->param1.external_params = _edje_external_params_parse(child_obj,
|
|
external->external_params);
|
|
_edje_external_recalc_apply(ed, rp, NULL, rp->chosen_description);
|
|
}
|
|
}
|
|
continue;
|
|
default:
|
|
continue;
|
|
}
|
|
|
|
while (source)
|
|
{
|
|
Eina_List *l;
|
|
Evas_Object *child_obj;
|
|
Edje *child_ed;
|
|
const char *group_path_entry = eina_stringshare_add(source);
|
|
const char *data;
|
|
|
|
if (!group_path)
|
|
{
|
|
group_path = eina_list_append(NULL, eina_stringshare_add(group));
|
|
group_path_started = 1;
|
|
}
|
|
/* make sure that this group isn't already in the tree of parents */
|
|
EINA_LIST_FOREACH(group_path, l, data)
|
|
{
|
|
if (data == group_path_entry)
|
|
{
|
|
_edje_thaw(ed);
|
|
_edje_unblock(ed);
|
|
_edje_unref(ed);
|
|
_edje_file_del(ed);
|
|
eina_stringshare_del(group_path_entry);
|
|
if (group_path_started)
|
|
{
|
|
eina_stringshare_del(eina_list_data_get(group_path));
|
|
eina_list_free(group_path);
|
|
}
|
|
ed->load_error = EDJE_LOAD_ERROR_RECURSIVE_REFERENCE;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
child_obj = edje_object_add(ed->evas);
|
|
group_path = eina_list_append(group_path, group_path_entry);
|
|
if (!_edje_object_file_set_internal(child_obj, file, source, group_path))
|
|
{
|
|
_edje_thaw(ed);
|
|
_edje_unblock(ed);
|
|
_edje_unref(ed);
|
|
_edje_file_del(ed);
|
|
|
|
if (group_path_started)
|
|
{
|
|
while (group_path)
|
|
{
|
|
eina_stringshare_del(eina_list_data_get(group_path));
|
|
group_path = eina_list_remove_list(group_path, group_path);
|
|
}
|
|
}
|
|
ed->load_error = edje_object_load_error_get(child_obj);
|
|
return 0;
|
|
}
|
|
child_ed = _edje_fetch(child_obj);
|
|
child_ed->parent = eina_stringshare_add(rp->part->name);
|
|
|
|
group_path = eina_list_remove(group_path, group_path_entry);
|
|
eina_stringshare_del(group_path_entry);
|
|
|
|
edje_object_signal_callback_add(child_obj, "*", "*", _cb_signal_repeat, obj);
|
|
if (rp->part->type == EDJE_PART_TYPE_GROUP)
|
|
{
|
|
_edje_real_part_swallow(rp, child_obj);
|
|
source = NULL;
|
|
}
|
|
else
|
|
{
|
|
_edje_object_pack_item_hints_set(child_obj, pack_it);
|
|
evas_object_show(child_obj);
|
|
if (pack_it->name)
|
|
evas_object_name_set(child_obj, pack_it->name);
|
|
if (rp->part->type == EDJE_PART_TYPE_BOX)
|
|
{
|
|
_edje_real_part_box_append(rp, child_obj);
|
|
evas_object_data_set(child_obj, "\377 edje.box_item", pack_it);
|
|
}
|
|
else if(rp->part->type == EDJE_PART_TYPE_TABLE)
|
|
{
|
|
_edje_real_part_table_pack(rp, child_obj, pack_it->col, pack_it->row, pack_it->colspan, pack_it->rowspan);
|
|
evas_object_data_set(child_obj, "\377 edje.table_item", pack_it);
|
|
}
|
|
rp->items = eina_list_append(rp->items, child_obj);
|
|
|
|
if (item_count > 0)
|
|
{
|
|
pack_it = *curr_item;
|
|
source = pack_it->source;
|
|
curr_item++;
|
|
item_count--;
|
|
}
|
|
else
|
|
{
|
|
source = NULL;
|
|
curr_item = NULL;
|
|
pack_it = NULL;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (group_path_started)
|
|
{
|
|
const char *str;
|
|
|
|
EINA_LIST_FREE(group_path, str)
|
|
eina_stringshare_del(str);
|
|
}
|
|
|
|
/* reswallow any swallows that existed before setting the file */
|
|
if (old_swallows)
|
|
{
|
|
while (old_swallows)
|
|
{
|
|
const char *name;
|
|
Evas_Object *swallow;
|
|
|
|
name = eina_list_data_get(old_swallows);
|
|
old_swallows = eina_list_remove_list(old_swallows, old_swallows);
|
|
|
|
swallow = eina_list_data_get(old_swallows);
|
|
old_swallows = eina_list_remove_list(old_swallows, old_swallows);
|
|
|
|
edje_object_part_swallow(obj, name, swallow);
|
|
eina_stringshare_del(name);
|
|
}
|
|
}
|
|
|
|
_edje_recalc(ed);
|
|
_edje_thaw(ed);
|
|
_edje_unblock(ed);
|
|
_edje_unref(ed);
|
|
ed->load_error = EDJE_LOAD_ERROR_NONE;
|
|
_edje_emit(ed, "load", NULL);
|
|
/* instantiate 'internal swallows' */
|
|
for (i = 0; i < ed->table_parts_size; i++)
|
|
{
|
|
Edje_Real_Part *rp;
|
|
|
|
rp = ed->table_parts[i];
|
|
if ((rp->part->type == EDJE_PART_TYPE_TEXTBLOCK) &&
|
|
(rp->part->default_desc))
|
|
{
|
|
Edje_Part_Description_Text *text;
|
|
Edje_Style *stl = NULL;
|
|
const char *style;
|
|
|
|
text = (Edje_Part_Description_Text *) rp->part->default_desc;
|
|
style = edje_string_get(&text->text.style);
|
|
if (style)
|
|
{
|
|
Eina_List *l;
|
|
|
|
EINA_LIST_FOREACH(ed->file->styles, l, stl)
|
|
{
|
|
if ((stl->name) && (!strcmp(stl->name, style))) break;
|
|
stl = NULL;
|
|
}
|
|
}
|
|
if (stl)
|
|
{
|
|
if (evas_object_textblock_style_get(rp->object) != stl->style)
|
|
evas_object_textblock_style_set(rp->object, stl->style);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
_edje_entry_init(ed);
|
|
return 1;
|
|
}
|
|
else
|
|
return 0;
|
|
ed->load_error = EDJE_LOAD_ERROR_NONE;
|
|
_edje_entry_init(ed);
|
|
return 1;
|
|
}
|
|
|
|
void
|
|
_edje_file_add(Edje *ed)
|
|
{
|
|
if (!_edje_edd_edje_file) return;
|
|
ed->file = _edje_cache_file_coll_open(ed->path, ed->group,
|
|
&(ed->load_error),
|
|
&(ed->collection));
|
|
|
|
if (!ed->collection)
|
|
{
|
|
if (ed->file)
|
|
{
|
|
_edje_cache_file_unref(ed->file);
|
|
ed->file = NULL;
|
|
}
|
|
}
|
|
}
|
|
|
|
static Eina_List *
|
|
_edje_swallows_collect(Edje *ed)
|
|
{
|
|
Eina_List *swallows = NULL;
|
|
unsigned int i;
|
|
|
|
if (!ed->file || !ed->table_parts) return NULL;
|
|
for (i = 0; i < ed->table_parts_size; i++)
|
|
{
|
|
Edje_Real_Part *rp;
|
|
|
|
rp = ed->table_parts[i];
|
|
if (rp->part->type != EDJE_PART_TYPE_SWALLOW || !rp->swallowed_object) continue;
|
|
swallows = eina_list_append(swallows, eina_stringshare_add(rp->part->name));
|
|
swallows = eina_list_append(swallows, rp->swallowed_object);
|
|
}
|
|
return swallows;
|
|
}
|
|
|
|
void
|
|
_edje_file_del(Edje *ed)
|
|
{
|
|
if (ed->freeze_calc)
|
|
{
|
|
_edje_freeze_calc_list = eina_list_remove(_edje_freeze_calc_list, ed);
|
|
ed->freeze_calc = 0;
|
|
_edje_freeze_calc_count--;
|
|
}
|
|
_edje_entry_shutdown(ed);
|
|
_edje_message_del(ed);
|
|
_edje_block_violate(ed);
|
|
_edje_var_shutdown(ed);
|
|
_edje_programs_patterns_clean(ed);
|
|
// if (ed->collection)
|
|
// {
|
|
// if (ed->collection->script) _edje_embryo_script_shutdown(ed);
|
|
// }
|
|
|
|
if (!((ed->file) && (ed->collection))) return;
|
|
if (ed->table_parts)
|
|
{
|
|
unsigned int i;
|
|
for (i = 0; i < ed->table_parts_size; i++)
|
|
{
|
|
Edje_Real_Part *rp;
|
|
|
|
rp = ed->table_parts[i];
|
|
if (rp->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE)
|
|
_edje_entry_real_part_shutdown(rp);
|
|
if (rp->object)
|
|
{
|
|
_edje_callbacks_del(rp->object, ed);
|
|
_edje_callbacks_focus_del(rp->object, ed);
|
|
evas_object_del(rp->object);
|
|
}
|
|
if (rp->swallowed_object)
|
|
{
|
|
_edje_real_part_swallow_clear(rp);
|
|
/* Objects swallowed by the app do not get deleted,
|
|
but those internally swallowed (GROUP type) do. */
|
|
switch (rp->part->type)
|
|
{
|
|
case EDJE_PART_TYPE_EXTERNAL:
|
|
_edje_external_parsed_params_free(rp->swallowed_object, rp->param1.external_params);
|
|
if (rp->param2)
|
|
_edje_external_parsed_params_free(rp->swallowed_object, rp->param2->external_params);
|
|
case EDJE_PART_TYPE_GROUP:
|
|
evas_object_del(rp->swallowed_object);
|
|
default:
|
|
break;
|
|
}
|
|
rp->swallowed_object = NULL;
|
|
}
|
|
if (rp->items)
|
|
{
|
|
/* evas_box/table handles deletion of objects */
|
|
rp->items = eina_list_free(rp->items);
|
|
}
|
|
if (rp->text.text) eina_stringshare_del(rp->text.text);
|
|
if (rp->text.font) eina_stringshare_del(rp->text.font);
|
|
if (rp->text.cache.in_str) eina_stringshare_del(rp->text.cache.in_str);
|
|
if (rp->text.cache.out_str) eina_stringshare_del(rp->text.cache.out_str);
|
|
|
|
if (rp->custom)
|
|
{
|
|
// xxx: lua2
|
|
_edje_collection_free_part_description_clean(rp->part->type,
|
|
rp->custom->description,
|
|
ed->file->free_strings);
|
|
free(rp->custom->description);
|
|
rp->custom->description = NULL;
|
|
}
|
|
|
|
/* Cleanup optional part. */
|
|
free(rp->drag);
|
|
free(rp->param1.set);
|
|
|
|
if (rp->param2)
|
|
free(rp->param2->set);
|
|
eina_mempool_free(_edje_real_part_state_mp, rp->param2);
|
|
|
|
if (rp->custom)
|
|
free(rp->custom->set);
|
|
eina_mempool_free(_edje_real_part_state_mp, rp->custom);
|
|
|
|
_edje_unref(rp->edje);
|
|
eina_mempool_free(_edje_real_part_mp, rp);
|
|
}
|
|
}
|
|
if ((ed->file) && (ed->collection))
|
|
{
|
|
Edje_Part *ep;
|
|
unsigned int i;
|
|
|
|
_edje_textblock_styles_del(ed);
|
|
for (i = 0; i < ed->collection->parts_count; ++i)
|
|
{
|
|
ep = ed->collection->parts[i];
|
|
|
|
_edje_text_part_on_del(ed, ep);
|
|
_edje_color_class_on_del(ed, ep);
|
|
}
|
|
|
|
_edje_cache_coll_unref(ed->file, ed->collection);
|
|
ed->collection = NULL;
|
|
}
|
|
if (ed->file)
|
|
{
|
|
_edje_cache_file_unref(ed->file);
|
|
ed->file = NULL;
|
|
}
|
|
if (ed->actions)
|
|
{
|
|
Edje_Running_Program *runp;
|
|
|
|
EINA_LIST_FREE(ed->actions, runp)
|
|
{
|
|
_edje_anim_count--;
|
|
free(runp);
|
|
}
|
|
}
|
|
_edje_animators = eina_list_remove(_edje_animators, ed);
|
|
if (ed->pending_actions)
|
|
{
|
|
Edje_Pending_Program *pp;
|
|
|
|
EINA_LIST_FREE(ed->pending_actions, pp)
|
|
{
|
|
ecore_timer_del(pp->timer);
|
|
free(pp);
|
|
}
|
|
}
|
|
if (ed->L)
|
|
_edje_lua2_script_shutdown(ed);
|
|
if (ed->table_parts) free(ed->table_parts);
|
|
ed->table_parts = NULL;
|
|
ed->table_parts_size = 0;
|
|
if (ed->table_programs) free(ed->table_programs);
|
|
ed->table_programs = NULL;
|
|
ed->table_programs_size = 0;
|
|
}
|
|
|
|
void
|
|
_edje_file_free(Edje_File *edf)
|
|
{
|
|
Edje_Color_Class *ecc;
|
|
|
|
#define HASH_FREE(Hash) \
|
|
if (Hash) eina_hash_free(Hash); \
|
|
Hash = NULL;
|
|
|
|
/* Clean cache before cleaning memory pool */
|
|
if (edf->collection_cache) _edje_cache_coll_flush(edf);
|
|
|
|
HASH_FREE(edf->fonts);
|
|
HASH_FREE(edf->collection);
|
|
HASH_FREE(edf->data);
|
|
|
|
if (edf->image_dir)
|
|
{
|
|
unsigned int i;
|
|
|
|
if (edf->free_strings)
|
|
{
|
|
for (i = 0; i < edf->image_dir->entries_count; ++i)
|
|
eina_stringshare_del(edf->image_dir->entries[i].entry);
|
|
}
|
|
|
|
/* Sets have been added after edje received eet dictionnary support */
|
|
for (i = 0; i < edf->image_dir->sets_count; ++i)
|
|
{
|
|
Edje_Image_Directory_Set_Entry *se;
|
|
|
|
EINA_LIST_FREE(edf->image_dir->sets[i].entries, se)
|
|
free(se);
|
|
|
|
}
|
|
|
|
free(edf->image_dir->entries);
|
|
free(edf->image_dir->sets);
|
|
free(edf->image_dir);
|
|
}
|
|
|
|
if (edf->external_dir)
|
|
{
|
|
if (edf->external_dir->entries) free(edf->external_dir->entries);
|
|
free(edf->external_dir);
|
|
}
|
|
|
|
EINA_LIST_FREE(edf->color_classes, ecc)
|
|
{
|
|
if (edf->free_strings && ecc->name) eina_stringshare_del(ecc->name);
|
|
free(ecc);
|
|
}
|
|
|
|
if (edf->collection_patterns) edje_match_patterns_free(edf->collection_patterns);
|
|
if (edf->path) eina_stringshare_del(edf->path);
|
|
if (edf->free_strings && edf->compiler) eina_stringshare_del(edf->compiler);
|
|
_edje_textblock_style_cleanup(edf);
|
|
if (edf->ef) eet_close(edf->ef);
|
|
free(edf);
|
|
}
|
|
|
|
static void
|
|
_edje_program_free(Edje_Program *pr, Eina_Bool free_strings)
|
|
{
|
|
Edje_Program_Target *prt;
|
|
Edje_Program_After *pa;
|
|
|
|
if (free_strings)
|
|
{
|
|
if (pr->name) eina_stringshare_del(pr->name);
|
|
if (pr->signal) eina_stringshare_del(pr->signal);
|
|
if (pr->source) eina_stringshare_del(pr->source);
|
|
if (pr->filter.part) eina_stringshare_del(pr->filter.part);
|
|
if (pr->filter.state) eina_stringshare_del(pr->filter.state);
|
|
if (pr->state) eina_stringshare_del(pr->state);
|
|
if (pr->state2) eina_stringshare_del(pr->state2);
|
|
}
|
|
EINA_LIST_FREE(pr->targets, prt)
|
|
free(prt);
|
|
EINA_LIST_FREE(pr->after, pa)
|
|
free(pa);
|
|
free(pr);
|
|
}
|
|
|
|
void
|
|
_edje_collection_free(Edje_File *edf, Edje_Part_Collection *ec, Edje_Part_Collection_Directory_Entry *ce)
|
|
{
|
|
unsigned int i;
|
|
|
|
_edje_embryo_script_shutdown(ec);
|
|
|
|
#define EDJE_LOAD_PROGRAM_FREE(Array, Ec, It, FreeStrings) \
|
|
for (It = 0; It < Ec->programs.Array##_count; ++It) \
|
|
_edje_program_free(Ec->programs.Array[It], FreeStrings); \
|
|
free(Ec->programs.Array);
|
|
|
|
EDJE_LOAD_PROGRAM_FREE(fnmatch, ec, i, edf->free_strings);
|
|
EDJE_LOAD_PROGRAM_FREE(strcmp, ec, i, edf->free_strings);
|
|
EDJE_LOAD_PROGRAM_FREE(strncmp, ec, i, edf->free_strings);
|
|
EDJE_LOAD_PROGRAM_FREE(strrncmp, ec, i, edf->free_strings);
|
|
EDJE_LOAD_PROGRAM_FREE(nocmp, ec, i, edf->free_strings);
|
|
|
|
for (i = 0; i < ec->parts_count; ++i)
|
|
{
|
|
Edje_Part *ep;
|
|
unsigned int j;
|
|
|
|
ep = ec->parts[i];
|
|
|
|
if (edf->free_strings && ep->name) eina_stringshare_del(ep->name);
|
|
if (ep->default_desc)
|
|
{
|
|
_edje_collection_free_part_description_clean(ep->type, ep->default_desc, edf->free_strings);
|
|
ep->default_desc = NULL;
|
|
}
|
|
for (j = 0; j < ep->other.desc_count; ++j)
|
|
_edje_collection_free_part_description_clean(ep->type, ep->other.desc[j], edf->free_strings);
|
|
|
|
free(ep->other.desc);
|
|
free(ep->items);
|
|
}
|
|
free(ec->parts);
|
|
ec->parts = NULL;
|
|
|
|
if (ec->data)
|
|
{
|
|
Eina_Iterator *it;
|
|
Edje_String *es;
|
|
|
|
it = eina_hash_iterator_data_new(ec->data);
|
|
EINA_ITERATOR_FOREACH(it, es)
|
|
free(es);
|
|
eina_iterator_free(it);
|
|
|
|
eina_hash_free(ec->data);
|
|
}
|
|
#ifdef EDJE_PROGRAM_CACHE
|
|
if (ec->prog_cache.no_matches) eina_hash_free(ec->prog_cache.no_matches);
|
|
if (ec->prog_cache.matches)
|
|
{
|
|
eina_hash_foreach(ec->prog_cache.matches,
|
|
_edje_collection_free_prog_cache_matches_free_cb,
|
|
NULL);
|
|
eina_hash_free(ec->prog_cache.matches);
|
|
}
|
|
#endif
|
|
if (ec->script) embryo_program_free(ec->script);
|
|
_edje_lua2_script_unload(ec);
|
|
|
|
/* Destroy all part and description. */
|
|
eina_mempool_del(ce->mp.RECTANGLE);
|
|
eina_mempool_del(ce->mp.TEXT);
|
|
eina_mempool_del(ce->mp.IMAGE);
|
|
eina_mempool_del(ce->mp.SWALLOW);
|
|
eina_mempool_del(ce->mp.TEXTBLOCK);
|
|
eina_mempool_del(ce->mp.GROUP);
|
|
eina_mempool_del(ce->mp.BOX);
|
|
eina_mempool_del(ce->mp.TABLE);
|
|
eina_mempool_del(ce->mp.EXTERNAL);
|
|
eina_mempool_del(ce->mp.part);
|
|
memset(&ce->mp, 0, sizeof (ce->mp));
|
|
|
|
free(ec);
|
|
ce->ref = NULL;
|
|
}
|
|
|
|
void
|
|
_edje_collection_free_part_description_clean(int type, Edje_Part_Description_Common *desc, Eina_Bool free_strings)
|
|
{
|
|
if (free_strings && desc->color_class) eina_stringshare_del(desc->color_class);
|
|
|
|
switch (type)
|
|
{
|
|
case EDJE_PART_TYPE_IMAGE:
|
|
{
|
|
Edje_Part_Description_Image *img;
|
|
unsigned int i;
|
|
|
|
img = (Edje_Part_Description_Image *) desc;
|
|
|
|
for (i = 0; i < img->image.tweens_count; ++i)
|
|
free(img->image.tweens[i]);
|
|
free(img->image.tweens);
|
|
break;
|
|
}
|
|
case EDJE_PART_TYPE_EXTERNAL:
|
|
{
|
|
Edje_Part_Description_External *external;
|
|
|
|
external = (Edje_Part_Description_External *) desc;
|
|
|
|
if (external->external_params)
|
|
_edje_external_params_free(external->external_params, free_strings);
|
|
break;
|
|
}
|
|
case EDJE_PART_TYPE_TEXT:
|
|
case EDJE_PART_TYPE_TEXTBLOCK:
|
|
if (free_strings)
|
|
{
|
|
Edje_Part_Description_Text *text;
|
|
|
|
text = (Edje_Part_Description_Text *) desc;
|
|
|
|
if (text->text.text.str) eina_stringshare_del(text->text.text.str);
|
|
if (text->text.text_class) eina_stringshare_del(text->text.text_class);
|
|
if (text->text.style.str) eina_stringshare_del(text->text.style.str);
|
|
if (text->text.font.str) eina_stringshare_del(text->text.font.str);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
void
|
|
_edje_collection_free_part_description_free(int type,
|
|
Edje_Part_Description_Common *desc,
|
|
Edje_Part_Collection_Directory_Entry *ce,
|
|
Eina_Bool free_strings)
|
|
{
|
|
#define FREE_POOL(Type, Ce, Desc) \
|
|
case EDJE_PART_TYPE_##Type: eina_mempool_free(Ce->mp.Type, Desc); \
|
|
ce->count.Type--; \
|
|
break;
|
|
|
|
_edje_collection_free_part_description_clean(type, desc, free_strings);
|
|
|
|
switch (type)
|
|
{
|
|
FREE_POOL(RECTANGLE, ce, desc);
|
|
FREE_POOL(TEXT, ce, desc);
|
|
FREE_POOL(IMAGE, ce, desc);
|
|
FREE_POOL(SWALLOW, ce, desc);
|
|
FREE_POOL(TEXTBLOCK, ce, desc);
|
|
FREE_POOL(GROUP, ce, desc);
|
|
FREE_POOL(BOX, ce, desc);
|
|
FREE_POOL(TABLE, ce, desc);
|
|
FREE_POOL(EXTERNAL, ce, desc);
|
|
}
|
|
}
|
|
|
|
#ifdef EDJE_PROGRAM_CACHE
|
|
static Eina_Bool
|
|
_edje_collection_free_prog_cache_matches_free_cb(const Eina_Hash *hash, const void *key, void *data, void *fdata)
|
|
{
|
|
eina_list_free((Eina_List *)data);
|
|
return EINA_TRUE;
|
|
key = NULL;
|
|
hash = NULL;
|
|
fdata = NULL;
|
|
}
|
|
#endif
|
|
|
|
static void
|
|
_edje_object_pack_item_hints_set(Evas_Object *obj, Edje_Pack_Element *it)
|
|
{
|
|
Evas_Coord w = 0, h = 0, minw, minh;
|
|
|
|
minw = it->min.w;
|
|
minh = it->min.h;
|
|
|
|
if ((minw <= 0) && (minh <= 0))
|
|
{
|
|
edje_object_size_min_get(obj, &w, &h);
|
|
if ((w <= 0) && (h <= 0))
|
|
edje_object_size_min_calc(obj, &w, &h);
|
|
}
|
|
else
|
|
{
|
|
w = minw;
|
|
h = minh;
|
|
}
|
|
if (((minw <= 0) && (minh <= 0)) && ((w > 0) || (h > 0)))
|
|
evas_object_size_hint_min_set(obj, w, h);
|
|
else
|
|
evas_object_size_hint_min_set(obj, minw, minh);
|
|
|
|
evas_object_size_hint_request_set(obj, it->prefer.w, it->prefer.h);
|
|
evas_object_size_hint_max_set(obj, it->max.w, it->max.h);
|
|
evas_object_size_hint_padding_set(obj, it->padding.l, it->padding.r, it->padding.t, it->padding.b);
|
|
evas_object_size_hint_align_set(obj, it->align.x, it->align.y);
|
|
evas_object_size_hint_weight_set(obj, it->weight.x, it->weight.y);
|
|
evas_object_size_hint_aspect_set(obj, it->aspect.mode, it->aspect.w, it->aspect.h);
|
|
|
|
evas_object_resize(obj, w, h);
|
|
}
|
|
|
|
static void
|
|
_cb_signal_repeat(void *data, Evas_Object *obj, const char *signal, const char *source)
|
|
{
|
|
Evas_Object *parent;
|
|
Edje *ed;
|
|
char new_src[4096]; /* XXX is this max reasonable? */
|
|
size_t length_parent = 0;
|
|
size_t length_source;
|
|
|
|
parent = data;
|
|
ed = _edje_fetch(obj);
|
|
if (!ed) return;
|
|
/* Replace snprint("%s%c%s") == memcpy + *new_src + memcat */
|
|
if (ed->parent)
|
|
length_parent = strlen(ed->parent);
|
|
length_source = strlen(source);
|
|
if (length_source + length_parent + 2 > sizeof(new_src))
|
|
return;
|
|
|
|
if (ed->parent)
|
|
memcpy(new_src, ed->parent, length_parent);
|
|
new_src[length_parent] = EDJE_PART_PATH_SEPARATOR;
|
|
memcpy(new_src + length_parent + 1, source, length_source + 1);
|
|
|
|
edje_object_signal_emit(parent, signal, new_src);
|
|
}
|