/* * TODO * ----------------------------------------------------------------- * Add LUA Support :) * Remove images/fonts * Clean the saving routines * */ #include "edje_private.h" #define EDJE_EDIT_IS_UNSTABLE_AND_I_KNOW_ABOUT_IT #include "Edje_Edit.h" #include #ifdef MY_CLASS # undef MY_CLASS #endif #define MY_CLASS EDJE_EDIT_CLASS static const char EDJE_EDIT_ERROR_GROUP_CURRENTLY_USED_STR[] = "Current group cannot be deleted"; static const char EDJE_EDIT_ERROR_GROUP_REFERENCED_STR[] = "Group still in use"; static const char EDJE_EDIT_ERROR_GROUP_DOES_NOT_EXIST_STR[] = "Group does not exist"; EAPI Eina_Error EDJE_EDIT_ERROR_GROUP_CURRENTLY_USED = 0; EAPI Eina_Error EDJE_EDIT_ERROR_GROUP_REFERENCED = 0; EAPI Eina_Error EDJE_EDIT_ERROR_GROUP_DOES_NOT_EXIST = 0; /* Get eed(Edje_Edit*) from obj(Evas_Object*) */ #define GET_EED_OR_RETURN(RET) \ Edje_Edit *eed; \ if (!eo_isa(obj, MY_CLASS)) \ return RET; \ eed = eo_data_scope_get(obj, MY_CLASS); \ if (!eed) return RET; /* Get ed(Edje*) from obj(Evas_Object*) */ #define GET_ED_OR_RETURN(RET) \ Edje *ed; \ if (!eo_isa(obj, EDJE_CLASS)) \ return RET; \ ed = eo_data_scope_get(obj, EDJE_CLASS); /* Get rp(Edje_Real_Part*) from obj(Evas_Object*) and part(char*) */ #define GET_RP_OR_RETURN(RET) \ GET_ED_OR_RETURN(RET) \ Edje_Real_Part *rp; \ rp = _edje_real_part_get(ed, part); \ if (!rp) return RET; /* Get pd(Edje_Part_Description*) from obj(Evas_Object*), part(char*) and state (char*) */ #define GET_PD_OR_RETURN(RET) \ GET_EED_OR_RETURN(RET) \ GET_ED_OR_RETURN(RET) \ Edje_Real_Part *rp; \ Edje_Part_Description_Common *pd; \ rp = _edje_real_part_get(ed, part); \ if (!rp) return RET; \ pd = _edje_part_description_find_byname(eed, part, state, value); \ if (!pd) return RET; /* Get epr(Edje_Program*) from obj(Evas_Object*) and prog(char*)*/ #define GET_EPR_OR_RETURN(RET) \ Edje_Program *epr; \ if (!eo_isa(obj, MY_CLASS)) \ return RET; \ epr = _edje_program_get_byname(obj, prog); \ if (!epr) return RET; static void * _alloc(size_t size) { void *mem; mem = calloc(1, size); if (mem) return mem; ERR("Edje_Edit: Error. memory allocation of %i bytes failed. %s", (int)size, strerror(errno)); return NULL; } /*************/ /* INTERNALS */ /*************/ /* Edje_Edit smart! Overloads the edje one adding some more control stuff */ static const char _edje_edit_type[] = "edje_edit"; typedef struct _Edje_Edit Edje_Edit; struct _Edje_Edit { Edje *base; void *bytecode; int bytecode_size; char *embryo_source; char *embryo_processed; Eina_Hash *program_scripts; Eina_List *errors; Eina_Bool bytecode_dirty:1; Eina_Bool embryo_source_dirty:1; Eina_Bool all_dirty:1; Eina_Bool script_need_recompile:1; }; typedef struct _Program_Script Program_Script; struct _Program_Script { int id; char *code; char *processed; Eina_Bool dirty:1; Eina_Bool delete_me:1; }; static Eina_Bool _edje_edit_edje_file_save(Eet_File *eetf, Edje_File *ef); static void _edje_edit_data_clean(Edje_Edit *eed) { Edje_Edit_Script_Error *se; free(eed->bytecode); free(eed->embryo_source); free(eed->embryo_processed); if (eed->program_scripts) eina_hash_free(eed->program_scripts); EINA_LIST_FREE(eed->errors, se) { eina_stringshare_del(se->program_name); eina_stringshare_del(se->error_str); free(se); } eed->bytecode = NULL; eed->embryo_source = NULL; eed->embryo_processed = NULL; eed->program_scripts = NULL; eed->bytecode_size = 0; eed->bytecode_dirty = EINA_FALSE; eed->embryo_source_dirty = EINA_FALSE; eed->all_dirty = EINA_FALSE; eed->script_need_recompile = EINA_FALSE; } EOLIAN static void _edje_edit_evas_object_smart_del(Eo *obj, Edje_Edit *eed) { _edje_edit_data_clean(eed); eo_do_super(obj, MY_CLASS, evas_obj_smart_del()); } static void _edje_edit_program_script_free(Program_Script *ps) { free(ps->code); free(ps->processed); free(ps); } EOLIAN static Eina_Bool _edje_edit_edje_file_set(Eo *obj, Edje_Edit *eed, const char *file, const char *group) { Eina_Bool ret; Eet_File *ef; char **keys, buf[64]; int count, i; int len = strlen("edje/scripts/embryo/source/"); ret = EINA_FALSE; _edje_edit_data_clean(eed); /* TODO and maybes: * * The whole point of this thing is keep track of stuff such as * strings to free and who knows what, so we need to take care * of those if the file/group changes. * * Maybe have the possibility to open just files, not always with * a group given. * * A way to skip the cache? Could help avoid some issues when editing * a group being used by the application in some other way, or multiple * opens of the same file. * * Here we probably want to allow opening groups with broken references * (GROUP parts or BOX/TABLE items pointing to non-existent/renamed * groups). */ Eina_Bool int_ret = EINA_FALSE; eo_do_super(obj, MY_CLASS, int_ret = edje_obj_file_set(file, group)); if (!int_ret) return ret; eed->program_scripts = eina_hash_int32_new((Eina_Free_Cb)_edje_edit_program_script_free); ef = eet_open(file, EET_FILE_MODE_READ); snprintf(buf, sizeof(buf), "edje/scripts/embryo/source/%i", eed->base->collection->id); eed->embryo_source = eet_read(ef, buf, &count); snprintf(buf, sizeof(buf), "edje/scripts/embryo/source/%i/*", eed->base->collection->id); keys = eet_list(ef, buf, &count); for (i = 0; i < count; i++) { Program_Script *ps; int size; ps = calloc(1, sizeof(Program_Script)); sscanf(keys[i] + len, "%*i/%i", &ps->id); ps->code = eet_read(ef, keys[i], &size); eina_hash_add(eed->program_scripts, &ps->id, ps); } if (keys) free(keys); eet_close(ef); ret = EINA_TRUE; return ret; } EAPI Evas_Object * edje_edit_object_add(Evas *evas) { Evas_Object *e; e = eo_add(MY_CLASS, evas); eo_unref(e); return e; } EOLIAN static void _edje_edit_eo_base_constructor(Eo *obj, Edje_Edit *eed) { eed->base = eo_data_ref(obj, EDJE_CLASS); eo_do_super(obj, MY_CLASS, eo_constructor()); } EOLIAN static void _edje_edit_eo_base_destructor(Eo *obj, Edje_Edit *class_data EINA_UNUSED) { eo_do_super(obj, MY_CLASS, eo_destructor()); eo_data_unref(obj, class_data); } /* End of Edje_Edit smart stuff */ static Edje_Part_Description_Common * _edje_part_description_find_byname(Edje_Edit *eed, const char *part, const char *state, double value) { Edje_Real_Part *rp; Edje_Part_Description_Common *pd; if (!eed || !part || !state) return NULL; rp = _edje_real_part_get(eed->base, part); if (!rp) return NULL; pd = _edje_part_description_find(eed->base, rp, state, value, EINA_FALSE); return pd; } static int _edje_image_id_find(Edje_Edit *eed, const char *image_name) { unsigned int i; if (!eed->base->file) return -1; if (!eed->base->file->image_dir) return -1; //printf("SEARCH IMAGE %s\n", image_name); for (i = 0; i < eed->base->file->image_dir->entries_count; ++i) if (eed->base->file->image_dir->entries[i].entry && !strcmp(image_name, eed->base->file->image_dir->entries[i].entry)) return i; return -1; } static const char * _edje_image_name_find(Edje_Edit *eed, int image_id) { if (!eed->base->file) return NULL; if (!eed->base->file->image_dir) return NULL; /* Special case for external image */ if (image_id < 0) image_id = -image_id - 1; //printf("SEARCH IMAGE ID %d\n", image_id); if ((unsigned int) image_id >= eed->base->file->image_dir->entries_count) return NULL; return eed->base->file->image_dir->entries[image_id].entry; } static void _edje_real_part_free(Edje *ed, Edje_Real_Part *rp) { if (!rp) return; if (rp->object) { _edje_callbacks_del(rp->object, ed); evas_object_del(rp->object); } if ((rp->type == EDJE_RP_TYPE_SWALLOW) && (rp->typedata.swallow) && (rp->typedata.swallow->swallowed_object)) { evas_object_smart_member_del(rp->typedata.swallow->swallowed_object); evas_object_event_callback_del(rp->typedata.swallow->swallowed_object, EVAS_CALLBACK_FREE, _edje_object_part_swallow_free_cb); evas_object_clip_unset(rp->typedata.swallow->swallowed_object); evas_object_data_del(rp->typedata.swallow->swallowed_object, "\377 edje.swallowing_part"); if (rp->part->mouse_events) _edje_callbacks_del(rp->typedata.swallow->swallowed_object, ed); if (rp->part->type == EDJE_PART_TYPE_GROUP || rp->part->type == EDJE_PART_TYPE_EXTERNAL) evas_object_del(rp->typedata.swallow->swallowed_object); rp->typedata.swallow->swallowed_object = NULL; } if ((rp->type == EDJE_RP_TYPE_TEXT) && (rp->typedata.text) && (rp->typedata.text->text)) eina_stringshare_del(rp->typedata.text->text); if ((rp->type == EDJE_RP_TYPE_TEXT) && (rp->typedata.text) && (rp->typedata.text->font)) eina_stringshare_del(rp->typedata.text->font); if ((rp->type == EDJE_RP_TYPE_TEXT) && (rp->typedata.text) && (rp->typedata.text->cache.in_str)) eina_stringshare_del(rp->typedata.text->cache.in_str); if ((rp->type == EDJE_RP_TYPE_TEXT) && (rp->typedata.text) && (rp->typedata.text->cache.out_str)) eina_stringshare_del(rp->typedata.text->cache.out_str); if (rp->custom) { _edje_collection_free_part_description_clean(rp->part->type, rp->custom->description, 0); if (rp->custom) free(rp->custom->set); eina_mempool_free(_edje_real_part_state_mp, rp->custom); rp->custom = NULL; } free(rp->drag); if (rp->param2) free(rp->param2->set); eina_mempool_free(_edje_real_part_state_mp, rp->param2); _edje_unref(ed); eina_mempool_free(_edje_real_part_mp, rp); } static Eina_Bool _edje_import_font_file(Edje *ed, const char *path, const char *entry) { Eina_File *f; Eet_File *eetf = NULL; void *fdata = NULL; long fsize = 0; /* Read font data from file */ f = eina_file_open(path, 0); if (!f) { ERR("Unable to open font file \"%s\"", path); return EINA_FALSE; } fsize = eina_file_size_get(f); fdata = eina_file_map_all(f, EINA_FILE_SEQUENTIAL); if (!fdata) { ERR("Unable to map font file \"%s\"", path); goto on_error; } /* Write font to edje file */ eetf = eet_open(ed->path, EET_FILE_MODE_READ_WRITE); if (!eetf) { ERR("Unable to open \"%s\" for writing output", ed->path); goto on_error; } if (eet_write(eetf, entry, fdata, fsize, 1) <= 0) { ERR("Unable to write font part \"%s\" as \"%s\" part entry", path, entry); goto on_error; } /* write the edje_file */ if (!_edje_edit_edje_file_save(eetf, ed->file)) goto on_error; eet_close(eetf); eina_file_map_free(f, fdata); eina_file_close(f); return EINA_TRUE; on_error: if (eetf) eet_close(eetf); eina_file_map_free(f, fdata); eina_file_close(f); return EINA_FALSE; } static Eina_Bool _edje_import_image_file(Edje *ed, const char *path, int id) { char entry[PATH_MAX]; Evas_Object *im; Eet_File *eetf; void *im_data; int im_w, im_h; int im_alpha; int bytes; /* Try to load the file */ im = evas_object_image_add(ed->base->evas); if (!im) return EINA_FALSE; evas_object_image_file_set(im, path, NULL); if (evas_object_image_load_error_get(im) != EVAS_LOAD_ERROR_NONE) { ERR("Edje_Edit: unable to load image \"%s\"." "Missing PNG or JPEG loader modules for Evas or " "file does not exist, or is not readable.", path); evas_object_del(im); im = NULL; return EINA_FALSE; } /* Write the loaded image to the edje file */ evas_object_image_size_get(im, &im_w, &im_h); im_alpha = evas_object_image_alpha_get(im); im_data = evas_object_image_data_get(im, 0); if ((!im_data) || !(im_w > 0) || !(im_h > 0)) { evas_object_del(im); return EINA_FALSE; } /* 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); evas_object_del(im); return EINA_FALSE; } snprintf(entry, sizeof(entry), "edje/images/%i", id); /* write the image data */ bytes = eet_data_image_write(eetf, entry, im_data, im_w, im_h, im_alpha, 0, 100, 1); if (bytes <= 0) { ERR("Unable to write image part \"%s\" part entry to %s", entry, ed->path); eet_close(eetf); evas_object_del(im); return EINA_FALSE; } evas_object_del(im); /* write the edje_file */ if (!_edje_edit_edje_file_save(eetf, ed->file)) { eet_delete(eetf, entry); eet_close(eetf); return EINA_FALSE; } eet_close(eetf); return EINA_TRUE; } static int _edje_part_id_find(Edje *ed, const char *part) { unsigned int id; for (id = 0; id < ed->table_parts_size; id++) { Edje_Real_Part *rp = ed->table_parts[id]; if (!strcmp(rp->part->name, part)) return id; } return -1; } static void _edje_part_description_id_set(int type, Edje_Part_Description_Common *c, int old_id, int new_id) { if (c->rel1.id_x == old_id) c->rel1.id_x = new_id; if (c->rel1.id_y == old_id) c->rel1.id_y = new_id; if (c->rel2.id_x == old_id) c->rel2.id_x = new_id; if (c->rel2.id_y == old_id) c->rel2.id_y = new_id; if (type == EDJE_PART_TYPE_TEXT || type == EDJE_PART_TYPE_TEXTBLOCK) { Edje_Part_Description_Text *t; t = (Edje_Part_Description_Text *) c; if (t->text.id_source == old_id) t->text.id_source = new_id; if (t->text.id_text_source == old_id) t->text.id_text_source = new_id; } } static void _edje_part_program_id_set(Edje_Program *epr, int old_id, int new_id) { Edje_Program_Target *pt; Eina_List *ll, *l_next; if (epr->action != EDJE_ACTION_TYPE_STATE_SET) return; EINA_LIST_FOREACH_SAFE(epr->targets, ll, l_next, pt) { if (pt->id == old_id) { if (new_id == -1) epr->targets = eina_list_remove_list(epr->targets, ll); else pt->id = new_id; } } } static void _edje_part_id_set(Edje *ed, Edje_Real_Part *rp, int new_id) { /* This function change the id of a given real_part. * All the depedency will be updated too. * Also the table_parts is updated, and the current *rp in the table * is lost. * If new Id = -1 then all the depencies will be deleted */ Edje_Part *part; unsigned int j; int old_id; part = rp->part; if (!part) return; //printf("CHANGE ID OF PART %s TO %d\n", part->name, new_id); if (!ed || new_id < -1) return; if (part->id == new_id) return; old_id = part->id; part->id = new_id; /* Fix all the dependecies in all parts... */ for (j = 0; j < ed->collection->parts_count; ++j) { Edje_Part *p; unsigned int k; p = ed->collection->parts[j]; //printf(" search id: %d in %s\n", old_id, p->name); if (p->clip_to_id == old_id) p->clip_to_id = new_id; if (p->dragable.confine_id == old_id) p->dragable.confine_id = new_id; /* ...in default description */ _edje_part_description_id_set(p->type, p->default_desc, old_id, new_id); /* ...and in all other descriptions */ for (k = 0; k < p->other.desc_count; ++k) _edje_part_description_id_set(p->type, p->other.desc[k], old_id, new_id); } /*...and also in programs targets */ #define EDJE_EDIT_PROGRAM_ID_SET(Array, Ed, It, Old, New) \ for (It = 0; It < Ed->collection->programs.Array##_count; ++It) \ _edje_part_program_id_set(Ed->collection->programs.Array[It], Old, New); EDJE_EDIT_PROGRAM_ID_SET(fnmatch, ed, j, old_id, new_id); EDJE_EDIT_PROGRAM_ID_SET(strcmp, ed, j, old_id, new_id); EDJE_EDIT_PROGRAM_ID_SET(strncmp, ed, j, old_id, new_id); EDJE_EDIT_PROGRAM_ID_SET(strrncmp, ed, j, old_id, new_id); EDJE_EDIT_PROGRAM_ID_SET(nocmp, ed, j, old_id, new_id); /* Adjust table_parts */ if (new_id >= 0) ed->table_parts[new_id] = rp; } static void _edje_part_description_id_switch(int type, Edje_Part_Description_Common *c, int id1, int id2) { if (c->rel1.id_x == id1) c->rel1.id_x = id2; else if (c->rel1.id_x == id2) c->rel1.id_x = id1; if (c->rel1.id_y == id1) c->rel1.id_y = id2; else if (c->rel1.id_y == id2) c->rel1.id_y = id1; if (c->rel2.id_x == id1) c->rel2.id_x = id2; else if (c->rel2.id_x == id2) c->rel2.id_x = id1; if (c->rel2.id_y == id1) c->rel2.id_y = id2; else if (c->rel2.id_y == id2) c->rel2.id_y = id1; if (type == EDJE_PART_TYPE_TEXT || type == EDJE_PART_TYPE_TEXTBLOCK) { Edje_Part_Description_Text *t; t = (Edje_Part_Description_Text *) c; if (t->text.id_source == id1) t->text.id_source = id2; else if (t->text.id_source == id2) t->text.id_source = id1; if (t->text.id_text_source == id1) t->text.id_text_source = id2; else if (t->text.id_text_source == id2) t->text.id_text_source = id2; } } static void _edje_part_program_id_switch(Edje_Program *epr, int id1, int id2) { Edje_Program_Target *pt; Eina_List *ll; if (epr->action != EDJE_ACTION_TYPE_STATE_SET) return; EINA_LIST_FOREACH(epr->targets, ll, pt) { if (pt->id == id1) pt->id = id2; else if (pt->id == id2) pt->id = id1; } } static void _edje_parts_id_switch(Edje *ed, Edje_Real_Part *rp1, Edje_Real_Part *rp2) { /* This function switch the id of two parts. * All the depedency will be updated too. * Also the table_parts is updated, * The parts list isn't touched */ int id1; int id2; unsigned int i; //printf("SWITCH ID OF PART %d AND %d\n", rp1->part->id, rp2->part->id); if (!ed || !rp1 || !rp2) return; if (rp1 == rp2) return; id1 = rp1->part->id; id2 = rp2->part->id; /* Switch ids */ rp1->part->id = id2; rp2->part->id = id1; /* adjust table_parts */ ed->table_parts[id1] = rp2; ed->table_parts[id2] = rp1; // Fix all the dependecies in all parts... for (i = 0; i < ed->collection->parts_count; ++i) { unsigned int j; Edje_Part *p; p = ed->collection->parts[i]; //printf(" search id: %d in %s\n", old_id, p->name); if (p->clip_to_id == id1) p->clip_to_id = id2; else if (p->clip_to_id == id2) p->clip_to_id = id1; if (p->dragable.confine_id == id1) p->dragable.confine_id = id2; else if (p->dragable.confine_id == id2) p->dragable.confine_id = id1; // ...in default description _edje_part_description_id_switch(p->type, p->default_desc, id1, id2); // ...and in all other descriptions for (j = 0; j < p->other.desc_count; ++j) _edje_part_description_id_switch(p->type, p->other.desc[j], id1, id2); } //...and also in programs targets #define EDJE_EDIT_PROGRAM_SWITCH(Array, Ed, It, Id1, Id2) \ for (It = 0; It < Ed->collection->programs.Array##_count; ++It) \ _edje_part_program_id_switch(Ed->collection->programs.Array[i], Id1, Id2); EDJE_EDIT_PROGRAM_SWITCH(fnmatch, ed, i, id1, id2); EDJE_EDIT_PROGRAM_SWITCH(strcmp, ed, i, id1, id2); EDJE_EDIT_PROGRAM_SWITCH(strncmp, ed, i, id1, id2); EDJE_EDIT_PROGRAM_SWITCH(strrncmp, ed, i, id1, id2); EDJE_EDIT_PROGRAM_SWITCH(nocmp, ed, i, id1, id2); //TODO Real part dependencies are ok? } static void _edje_fix_parts_id(Edje *ed) { /* We use this to clear the id hole leaved when a part is removed. * After the execution of this function all parts will have a right * (uniqe & ordered) id. The table_parts is also updated. */ unsigned int i; int correct_id; unsigned int count; //printf("FIXING PARTS ID \n"); //TODO order the list first to be more robust /* Give a correct id to all the parts */ correct_id = 0; for (i = 0; i < ed->collection->parts_count; ++i) { Edje_Part *p; p = ed->collection->parts[i]; //printf(" [%d]Checking part: %s id: %d\n", correct_id, p->name, p->id); if (p->id != correct_id) if (ed->table_parts[p->id]) _edje_part_id_set(ed, ed->table_parts[p->id], correct_id); correct_id++; } /* If we have removed some parts realloc table_parts */ count = ed->collection->parts_count; if (count != ed->table_parts_size) { ed->table_parts = realloc(ed->table_parts, sizeof(Edje_Real_Part *) * count); ed->table_parts_size = count; } //printf("\n"); } static void _edje_if_string_free(Edje *ed, const char *str) { Eet_Dictionary *dict; if (!ed || !str) return; dict = eet_dictionary_get(ed->file->ef); if (eet_dictionary_string_check(dict, str)) return; eina_stringshare_del(str); str = NULL; } static Edje_Style * _edje_edit_style_get(Edje *ed, const char *name) { Eina_List *l; Edje_Style *s; if (!ed || !ed->file || !ed->file->styles || !name) return NULL; EINA_LIST_FOREACH(ed->file->styles, l, s) if (s->name && !strcmp(s->name, name)) return s; return NULL; } static Edje_Style_Tag * _edje_edit_style_tag_get(Edje *ed, const char *style, const char *name) { Eina_List *l; Edje_Style *s; Edje_Style_Tag *t; if (!ed || !ed->file || !ed->file->styles || !name) return NULL; s = _edje_edit_style_get(ed, style); EINA_LIST_FOREACH(s->tags, l, t) if (t->key && !strcmp(t->key, name)) return t; return NULL; } static Edje_External_Directory_Entry * _edje_edit_external_get(Edje *ed, const char *name) { unsigned int i; if (!ed || !ed->file || !ed->file->external_dir || !name) return NULL; for (i = 0; i < ed->file->external_dir->entries_count; ++i) if (ed->file->external_dir->entries[i].entry && !strcmp(ed->file->external_dir->entries[i].entry, name)) return ed->file->external_dir->entries + i; return NULL; } static void _edje_edit_group_references_update(Evas_Object *obj, const char *old_group_name, const char *new_group_name) { Eina_Iterator *i; Eina_List *pll, *pl; // Edje_Part_Collection *pc; Edje_Part_Collection_Directory_Entry *pce; char *part_name; const char *source, *old; Edje_Part_Type type; Evas_Object *part_obj; GET_ED_OR_RETURN(); // pc = ed->collection; part_obj = edje_edit_object_add(ed->base->evas); old = eina_stringshare_add(old_group_name); i = eina_hash_iterator_data_new(ed->file->collection); EINA_ITERATOR_FOREACH(i, pce) { edje_object_file_set(part_obj, ed->file->path, pce->entry); pl = edje_edit_parts_list_get(part_obj); EINA_LIST_FOREACH(pl, pll, part_name) { source = edje_edit_part_source_get(part_obj, part_name); type = edje_edit_part_type_get(part_obj, part_name); if (type == EDJE_PART_TYPE_GROUP && source == old) edje_edit_part_source_set(part_obj, part_name, new_group_name); if (source) eina_stringshare_del(source); } } eina_iterator_free(i); eina_stringshare_del(old); evas_object_del(part_obj); } static void _edje_edit_flag_script_dirty(Edje_Edit *eed, Eina_Bool all) { eed->script_need_recompile = EINA_TRUE; if (all) eed->all_dirty = EINA_TRUE; } /*****************/ /* GENERAL API */ /*****************/ EAPI void edje_edit_string_list_free(Eina_List *lst) { //printf("FREE LIST: \n"); while (lst) { if (eina_list_data_get(lst)) eina_stringshare_del(eina_list_data_get(lst)); //printf("FREE: %s\n", eina_list_data_get(lst)); lst = eina_list_remove(lst, eina_list_data_get(lst)); } } EAPI void edje_edit_string_free(const char *str) { if (str) eina_stringshare_del(str); } EAPI const char* edje_edit_compiler_get(Evas_Object *obj) { GET_ED_OR_RETURN(0); return eina_stringshare_add(ed->file->compiler); } /****************/ /* GROUPS API */ /****************/ EAPI Eina_Bool edje_edit_group_copy(Evas_Object *obj, const char *group_name, const char *copy_name) { Edje_Part_Collection_Directory_Entry *e; Edje_Part_Collection_Directory_Entry *de; Edje_Part_Collection_Directory_Entry *d; Edje_Part_Collection *epc; int id; int search; Eet_File *eetf; char buf[64]; int count, script_count; void *data; char **keys, **c; GET_ED_OR_RETURN(EINA_FALSE); if (!ed->file || !ed->file->collection) return EINA_FALSE; e = eina_hash_find(ed->file->collection, group_name); if (!e) return EINA_FALSE; if (eina_hash_find(ed->file->collection, copy_name)) return EINA_FALSE; eetf = eet_open(ed->file->path, EET_FILE_MODE_READ_WRITE); if (!eetf) { ERR("Edje_Edit: Error. unable to open \"%s\" " "for writing output", ed->file->path); return EINA_FALSE; } snprintf(buf, sizeof(buf), "edje/collections/%d", e->id); epc = eet_data_read(eetf, _edje_edd_edje_part_collection, buf); /* Search first free id */ id = -1; search = 0; while (id == -1) { Eina_Iterator *i; Eina_Bool found = 0; i = eina_hash_iterator_data_new(ed->file->collection); EINA_ITERATOR_FOREACH(i, d) { if (search == d->id) { found = 1; break; } } eina_iterator_free(i); if (!found) id = search; else search++; } /* Create structs */ de = _alloc(sizeof(Edje_Part_Collection_Directory_Entry)); if (!de) return EINA_FALSE; /* Init Edje_Part_Collection_Directory_Entry */ de->id = id; de->entry = eina_stringshare_add(copy_name); memcpy(&de->count, &e->count, sizeof (de->count)); #define EDIT_EMN(Tp, Sz, Ce) \ Ce->mp.Tp = eina_mempool_add("chained_mempool", #Tp, NULL, sizeof (Sz), 8); #define EDIT_EMNP(Tp, Sz, Ce) \ Ce->mp_rtl.Tp = eina_mempool_add("chained_mempool", #Tp, NULL, sizeof (Sz), 8); eina_hash_direct_add(ed->file->collection, de->entry, de); EDIT_EMN(RECTANGLE, Edje_Part_Description_Common, de); EDIT_EMN(TEXT, Edje_Part_Description_Text, de); EDIT_EMN(IMAGE, Edje_Part_Description_Image, de); EDIT_EMN(PROXY, Edje_Part_Description_Proxy, de); EDIT_EMN(SWALLOW, Edje_Part_Description_Common, de); EDIT_EMN(TEXTBLOCK, Edje_Part_Description_Text, de); EDIT_EMN(GROUP, Edje_Part_Description_Common, de); EDIT_EMN(BOX, Edje_Part_Description_Box, de); EDIT_EMN(TABLE, Edje_Part_Description_Table, de); EDIT_EMN(EXTERNAL, Edje_Part_Description_External, de); EDIT_EMN(SPACER, Edje_Part_Description_Common, de); EDIT_EMN(part, Edje_Part, de); EDIT_EMNP(RECTANGLE, Edje_Part_Description_Common, de); EDIT_EMNP(TEXT, Edje_Part_Description_Text, de); EDIT_EMNP(IMAGE, Edje_Part_Description_Image, de); EDIT_EMNP(PROXY, Edje_Part_Description_Proxy, de); EDIT_EMNP(SWALLOW, Edje_Part_Description_Common, de); EDIT_EMNP(TEXTBLOCK, Edje_Part_Description_Text, de); EDIT_EMNP(GROUP, Edje_Part_Description_Common, de); EDIT_EMNP(BOX, Edje_Part_Description_Box, de); EDIT_EMNP(TABLE, Edje_Part_Description_Table, de); EDIT_EMNP(EXTERNAL, Edje_Part_Description_External, de); EDIT_EMNP(SPACER, Edje_Part_Description_Common, de); epc->id = id; epc->part = eina_stringshare_add(copy_name); ed->file->collection_cache = eina_list_prepend(ed->file->collection_cache, epc); /* Copying Scripts */ snprintf(buf, sizeof(buf), "edje/scripts/embryo/compiled/%d", e->id); data = eet_read(eetf, buf, &count); snprintf(buf, sizeof(buf), "edje/scripts/embryo/compiled/%d", epc->id); eet_write(eetf, buf, data, count, 1); snprintf(buf, sizeof(buf), "edje/scripts/embryo/source/%d", e->id); data = eet_read(eetf, buf, &count); snprintf(buf, sizeof(buf), "edje/scripts/embryo/source/%d", epc->id); eet_write(eetf, buf, data, count, 0); snprintf(buf, sizeof(buf), "edje/scripts/embryo/source/%d/*", e->id); keys = eet_list(eetf, buf, &count); if (keys) { while(count) { count--; data = eet_read(eetf, keys[count], &script_count); /* we need to save id of every script we are going to copy. */ c = eina_str_split(keys[count], "/", 6); snprintf(buf, sizeof(buf), "edje/scripts/embryo/source/%d/%s", epc->id, c[5]); eet_write(eetf, buf, data, script_count, 0); free(c[0]); free(c); } free(keys); } eet_close(eetf); /* we need to save everything to make sure the file won't have broken * references the next time is loaded */ edje_edit_save_all(obj); return EINA_TRUE; } EAPI Eina_Bool edje_edit_group_add(Evas_Object *obj, const char *name) { Edje_Part_Collection_Directory_Entry *de; Edje_Part_Collection_Directory_Entry *d; Edje_Part_Collection *pc; int id; int search; //Code *cd; GET_ED_OR_RETURN(EINA_FALSE); //printf("ADD GROUP: %s \n", name); /* check if a group with the same name already exists */ if (eina_hash_find(ed->file->collection, name)) return EINA_FALSE; /* Create structs */ de = _alloc(sizeof(Edje_Part_Collection_Directory_Entry)); if (!de) return EINA_FALSE; pc = _alloc(sizeof(Edje_Part_Collection)); if (!pc) { free(de); return EINA_FALSE; } /* Search first free id */ id = -1; search = 0; while (id == -1) { Eina_Iterator *i; Eina_Bool found = 0; i = eina_hash_iterator_data_new(ed->file->collection); EINA_ITERATOR_FOREACH(i, d) { // printf("search if %d is free [id %d]\n", search, d->id); if (search == d->id) { found = 1; break; } } eina_iterator_free(i); if (!found) id = search; else search++; } /* Init Edje_Part_Collection_Directory_Entry */ //printf(" new id: %d\n", id); de->id = id; de->entry = eina_stringshare_add(name); eina_hash_direct_add(ed->file->collection, de->entry, de); /* Init Edje_Part_Collection */ pc->id = id; pc->references = 0; memset(&pc->programs, 0, sizeof (pc->programs)); pc->parts = NULL; pc->data = NULL; pc->script = NULL; pc->part = eina_stringshare_add(name); //cd = _alloc(sizeof(Code)); //codes = eina_list_append(codes, cd); EDIT_EMN(RECTANGLE, Edje_Part_Description_Common, de); EDIT_EMN(TEXT, Edje_Part_Description_Text, de); EDIT_EMN(IMAGE, Edje_Part_Description_Image, de); EDIT_EMN(SWALLOW, Edje_Part_Description_Common, de); EDIT_EMN(TEXTBLOCK, Edje_Part_Description_Text, de); EDIT_EMN(GROUP, Edje_Part_Description_Common, de); EDIT_EMN(BOX, Edje_Part_Description_Box, de); EDIT_EMN(TABLE, Edje_Part_Description_Table, de); EDIT_EMN(EXTERNAL, Edje_Part_Description_External, de); EDIT_EMN(SPACER, Edje_Part_Description_Common, de); EDIT_EMN(part, Edje_Part, de); ed->file->collection_cache = eina_list_prepend(ed->file->collection_cache, pc); _edje_cache_coll_clean(ed->file); return EINA_TRUE; } EAPI Eina_Bool edje_edit_group_del(Evas_Object *obj, const char *group_name) { Edje_Part_Collection_Directory_Entry *e, *e_del; Edje_Part_Collection *die = NULL; Edje_Part_Collection *g; Eina_List *l; Eet_File *eetf; char buf[64], **keys; int count; GET_ED_OR_RETURN(EINA_FALSE); if (strcmp(ed->group, group_name) == 0) return EINA_FALSE; e = eina_hash_find(ed->file->collection, group_name); if (!e) return EINA_FALSE; if (e->id == ed->collection->id) return EINA_FALSE; if (e->ref) return EINA_FALSE; _edje_edit_group_references_update(obj, group_name, NULL); EINA_LIST_FOREACH(ed->file->collection_cache, l, g) { if (strcmp(g->part, e->entry) == 0) { ed->file->collection_cache = eina_list_remove_list(ed->file->collection_cache, l); die = g; break; } } /* Remove collection/id from eet file */ eetf = eet_open(ed->file->path, EET_FILE_MODE_READ_WRITE); if (!eetf) { ERR("Edje_Edit: Error. unable to open \"%s\" " "for writing output", ed->file->path); return EINA_FALSE; } snprintf(buf, sizeof(buf), "edje/collections/%d", e->id); eet_delete(eetf, buf); snprintf(buf, sizeof(buf), "edje/scripts/embryo/compiled/%d", e->id); eet_delete(eetf, buf); snprintf(buf, sizeof(buf), "edje/scripts/embryo/source/%d", e->id); eet_delete(eetf, buf); snprintf(buf, sizeof(buf), "edje/scripts/embryo/source/%d/*", e->id); keys = eet_list(eetf, buf, &count); if (keys) { do { count--; eet_delete(eetf, keys[count]); } while(count); free(keys); } eet_close(eetf); l = NULL; g = NULL; /* Free Group and all it's Aliases */ if (!e->group_alias) { EINA_LIST_FOREACH(ed->file->collection_cache, l, g) { if (e->id == g->id) { ed->file->collection_cache = eina_list_remove_list(ed->file->collection_cache, l); e_del = eina_hash_find(ed->file->collection, g->part); eina_hash_del(ed->file->collection, g->part, e_del); _edje_collection_free(ed->file, g, e_del); } } } if (die) _edje_collection_free(ed->file, die, e); eina_hash_del(ed->file->collection, group_name, e); /* we need to save everything to make sure the file won't have broken * references the next time is loaded */ edje_edit_save_all(obj); return EINA_TRUE; } EAPI Eina_Bool edje_edit_group_exist(Evas_Object *obj, const char *group) { GET_ED_OR_RETURN(EINA_FALSE); if (eina_hash_find(ed->file->collection, group)) return EINA_TRUE; return EINA_FALSE; } EAPI Eina_Bool edje_edit_group_name_set(Evas_Object *obj, const char *new_name) { Edje_Part_Collection_Directory_Entry *pce; Edje_Part_Collection *pc; GET_ED_OR_RETURN(EINA_FALSE); if (!new_name) return EINA_FALSE; pc = ed->collection; if (!strcmp(pc->part, new_name)) return EINA_TRUE; if (edje_edit_group_exist(obj, new_name)) return EINA_FALSE; _edje_edit_group_references_update(obj, pc->part, new_name); //printf("Set name of current group: %s [id: %d][new name: %s]\n", // pc->part, pc->id, new_name); //if (pc->part && ed->file->free_strings) eina_stringshare_del(pc->part); TODO FIXME pce = eina_hash_find(ed->file->collection, pc->part); eina_hash_move(ed->file->collection, pce->entry, new_name); pce->entry = eina_stringshare_add(new_name); pc->part = pce->entry; eina_stringshare_replace(&ed->group, new_name); return EINA_TRUE; } #define FUNC_GROUP_ACCESSOR(Class, Value) \ EAPI int \ edje_edit_group_##Class##_##Value##_get(Evas_Object *obj) \ { \ GET_ED_OR_RETURN(-1); \ if (!ed->collection) return -1; \ return ed->collection->prop.Class.Value; \ } \ EAPI Eina_Bool \ edje_edit_group_##Class##_##Value##_set(Evas_Object *obj, int v) \ { \ GET_ED_OR_RETURN(EINA_FALSE); \ if (!ed->collection) return EINA_FALSE; \ if (v < 0) return EINA_FALSE; \ ed->collection->prop.Class.Value = v; \ return EINA_TRUE; \ } FUNC_GROUP_ACCESSOR(min, w); FUNC_GROUP_ACCESSOR(min, h); FUNC_GROUP_ACCESSOR(max, w); FUNC_GROUP_ACCESSOR(max, h); /****************/ /* ALIAS API */ /****************/ EAPI Eina_List * edje_edit_group_aliases_get(Evas_Object *obj, const char *group_name) { Eina_Iterator *i; Edje_Part_Collection_Directory_Entry *e; Edje_Part_Collection_Directory_Entry *d; Eina_List *alias_list = NULL; GET_ED_OR_RETURN(NULL); if (!ed->file || !ed->file->collection) return NULL; e = eina_hash_find(ed->file->collection, group_name); if (!e) return NULL; i = eina_hash_iterator_data_new(ed->file->collection); EINA_ITERATOR_FOREACH(i, d) { if ((e->id == d->id) && (d->group_alias)) alias_list = eina_list_append(alias_list, eina_stringshare_add(d->entry)); } eina_iterator_free(i); return alias_list; } EAPI Eina_Bool edje_edit_group_alias_is(Evas_Object *obj, const char *alias_name) { Edje_Part_Collection_Directory_Entry *e; GET_ED_OR_RETURN(EINA_FALSE); if (!ed->file || !ed->file->collection) return EINA_FALSE; e = eina_hash_find(ed->file->collection, alias_name); if (!e) return EINA_FALSE; return e->group_alias; } EAPI const char * edje_edit_group_aliased_get(Evas_Object *obj, const char *alias_name) { Eina_Iterator *i; Edje_Part_Collection_Directory_Entry *e; Edje_Part_Collection_Directory_Entry *d; const char *group_name = NULL; GET_ED_OR_RETURN(NULL); if (!ed->file || !ed->file->collection) return NULL; e = eina_hash_find(ed->file->collection, alias_name); if (!e) return NULL; if (!e->group_alias) return eina_stringshare_add(alias_name); i = eina_hash_iterator_data_new(ed->file->collection); EINA_ITERATOR_FOREACH(i, d) { if ((e->id == d->id) && (!d->group_alias)) { group_name = d->entry; break; } } eina_iterator_free(i); return eina_stringshare_add(group_name); } EAPI Eina_Bool edje_edit_group_alias_add(Evas_Object *obj, const char *group_name, const char *alias_name) { Edje_Part_Collection_Directory_Entry *e; Edje_Part_Collection_Directory_Entry *de; GET_ED_OR_RETURN(EINA_FALSE); if (!ed->file || !ed->file->collection) return EINA_FALSE; /* check if a group with the same alias already exists */ if (eina_hash_find(ed->file->collection, alias_name)) return EINA_FALSE; /* check if a group that is being aliased is really exists */ e = eina_hash_find(ed->file->collection, group_name); if (!e) return EINA_FALSE; /* check that a group that is being aliased is not an alias */ if (e->group_alias) return EINA_FALSE; /* Create structs */ de = _alloc(sizeof(Edje_Part_Collection_Directory_Entry)); if (!de) return EINA_FALSE; /* Init Edje_Part_Collection_Directory_Entry */ de->id = e->id; de->entry = eina_stringshare_add(alias_name); de->group_alias = EINA_TRUE; memcpy(&de->count, &e->count, sizeof (de->count)); eina_hash_direct_add(ed->file->collection, de->entry, de); EDIT_EMN(RECTANGLE, Edje_Part_Description_Common, de); EDIT_EMN(TEXT, Edje_Part_Description_Text, de); EDIT_EMN(IMAGE, Edje_Part_Description_Image, de); EDIT_EMN(SWALLOW, Edje_Part_Description_Common, de); EDIT_EMN(TEXTBLOCK, Edje_Part_Description_Text, de); EDIT_EMN(GROUP, Edje_Part_Description_Common, de); EDIT_EMN(BOX, Edje_Part_Description_Box, de); EDIT_EMN(TABLE, Edje_Part_Description_Table, de); EDIT_EMN(EXTERNAL, Edje_Part_Description_External, de); EDIT_EMN(SPACER, Edje_Part_Description_Common, de); EDIT_EMN(part, Edje_Part, de); return EINA_TRUE; } /***************/ /* DATA API */ /***************/ EAPI Eina_List * edje_edit_group_data_list_get(Evas_Object * obj) { Eina_Iterator *it; Eina_List *datas = NULL; const char *key; GET_ED_OR_RETURN(NULL); if (!ed->file || !ed->collection || !ed->collection->data) return NULL; it = eina_hash_iterator_key_new(ed->collection->data); if (!it) return NULL; EINA_ITERATOR_FOREACH(it, key) datas = eina_list_append(datas, eina_stringshare_add(key)); eina_iterator_free(it); return datas; } EAPI Eina_List * edje_edit_data_list_get(Evas_Object * obj) { Eina_Iterator *i; Eina_List *datas = NULL; const char *key; GET_ED_OR_RETURN(NULL); if (!ed->file || !ed->file->data) return NULL; i = eina_hash_iterator_key_new(ed->file->data); EINA_ITERATOR_FOREACH(i, key) datas = eina_list_append(datas, eina_stringshare_add(key)); eina_iterator_free(i); return datas; } EAPI Eina_Bool edje_edit_group_data_add(Evas_Object *obj, const char *key, const char *value) { Edje_String *es; GET_ED_OR_RETURN(EINA_FALSE); if (!key || !ed->file || !ed->collection) return EINA_FALSE; if (!ed->collection->data) ed->collection->data = eina_hash_string_small_new(NULL); if (eina_hash_find(ed->collection->data, key)) return EINA_FALSE; es = calloc(1, sizeof(Edje_String)); if (!es) return EINA_FALSE; es->str = eina_stringshare_add(value); if (!eina_hash_add(ed->collection->data, key, es)) { eina_stringshare_del(es->str); free(es); return EINA_FALSE; } return EINA_TRUE; } EAPI Eina_Bool edje_edit_data_add(Evas_Object *obj, const char *itemname, const char *value) { Edje_String *es; GET_ED_OR_RETURN(EINA_FALSE); if (!itemname || !ed->file) return EINA_FALSE; if (eina_hash_find(ed->file->data, itemname)) return EINA_FALSE; es = calloc(1, sizeof(Edje_String)); if (!es) return EINA_FALSE; es->str = eina_stringshare_add(value); if (!eina_hash_add(ed->file->data, itemname, es)) { eina_stringshare_del(es->str); free(es); return EINA_FALSE; } return EINA_TRUE; } EAPI Eina_Bool edje_edit_group_data_del(Evas_Object *obj, const char *key) { Edje_String *value; GET_ED_OR_RETURN(EINA_FALSE); if (!key || !ed->file || !ed->collection) return EINA_FALSE; value = eina_hash_find(ed->collection->data, key); if (!value) return EINA_FALSE; eina_hash_del(ed->collection->data, key, value); _edje_if_string_free(ed, value->str); free(value); return EINA_TRUE; } EAPI Eina_Bool edje_edit_data_del(Evas_Object *obj, const char *itemname) { Edje_String *value; GET_ED_OR_RETURN(EINA_FALSE); if (!itemname || !ed->file || !ed->file->data) return 0; value = eina_hash_find(ed->file->data, itemname); if (!value) return EINA_FALSE; eina_hash_del(ed->file->data, itemname, value); _edje_if_string_free(ed, value->str); free(value); return EINA_TRUE; } EAPI const char * edje_edit_group_data_value_get(Evas_Object * obj, const char *key) { Edje_String *value; GET_ED_OR_RETURN(NULL); if (!key || !ed->file || !ed->collection) return NULL; value = eina_hash_find(ed->collection->data, key); if (!value) return NULL; return eina_stringshare_add(edje_string_get(value)); } EAPI const char * edje_edit_data_value_get(Evas_Object * obj, const char *itemname) { Edje_String *value; GET_ED_OR_RETURN(NULL); if (!itemname || !ed->file || !ed->file->data) return NULL; value = eina_hash_find(ed->file->data, itemname); if (!value) return NULL; return eina_stringshare_add(edje_string_get(value)); } EAPI Eina_Bool edje_edit_group_data_value_set(Evas_Object *obj, const char *key, const char *value) { Edje_String *es; GET_ED_OR_RETURN(EINA_FALSE); if (!key || !value || !ed->file || !ed->collection) return EINA_FALSE; es = eina_hash_find(ed->collection->data, key); if (es) { _edje_if_string_free(ed, es->str); es->str = eina_stringshare_add(value); es->id = 0; return EINA_TRUE; } return EINA_FALSE; } EAPI Eina_Bool edje_edit_data_value_set(Evas_Object *obj, const char *itemname, const char *value) { Edje_String *es; GET_ED_OR_RETURN(EINA_FALSE); if (!itemname || !value || !ed->file || !ed->file->data) return EINA_FALSE; es = eina_hash_find(ed->file->data, itemname); if (es) { _edje_if_string_free(ed, es->str); es->str = eina_stringshare_add(value); es->id = 0; return EINA_TRUE; } return EINA_FALSE; } EAPI Eina_Bool edje_edit_group_data_name_set(Evas_Object *obj, const char *key, const char *new_key) { GET_ED_OR_RETURN(EINA_FALSE); if (!key || !new_key || !ed->file || !ed->collection) { return EINA_FALSE; } return eina_hash_move(ed->collection->data, key, new_key); } EAPI Eina_Bool edje_edit_data_name_set(Evas_Object *obj, const char *itemname, const char *newname) { GET_ED_OR_RETURN(EINA_FALSE); if (!itemname || !newname || !ed->file || !ed->file->data) return EINA_FALSE; return eina_hash_move(ed->file->data, itemname, newname); } /***********************/ /* COLOR CLASSES API */ /***********************/ EAPI Eina_List * edje_edit_color_classes_list_get(Evas_Object * obj) { Eina_List *classes = NULL; Eina_List *l; Edje_Color_Class *cc; GET_ED_OR_RETURN(NULL); if (!ed->file || !ed->file->color_classes) return NULL; //printf("GET CLASSES LIST %d %d\n", eina_list_count(ed->color_classes), eina_list_count(ed->file->color_classes)); EINA_LIST_FOREACH(ed->file->color_classes, l, cc) classes = eina_list_append(classes, eina_stringshare_add(cc->name)); return classes; } EAPI Eina_Bool edje_edit_color_class_colors_get(Evas_Object *obj, const char *class_name, int *r, int *g, int *b, int *a, int *r2, int *g2, int *b2, int *a2, int *r3, int *g3, int *b3, int *a3) { Eina_List *l; Edje_Color_Class *cc; GET_ED_OR_RETURN(EINA_FALSE); if (!ed->file || !ed->file->color_classes) return EINA_FALSE; EINA_LIST_FOREACH(ed->file->color_classes, l, cc) if (!strcmp(cc->name, class_name)) { if (r) *r = cc->r; if (g) *g = cc->g; if (b) *b = cc->b; if (a) *a = cc->a; if (r2) *r2 = cc->r2; if (g2) *g2 = cc->g2; if (b2) *b2 = cc->b2; if (a2) *a2 = cc->a2; if (r3) *r3 = cc->r3; if (g3) *g3 = cc->g3; if (b3) *b3 = cc->b3; if (a3) *a3 = cc->a3; return EINA_TRUE; } return EINA_FALSE; } EAPI Eina_Bool edje_edit_color_class_colors_set(Evas_Object *obj, const char *class_name, int r, int g, int b, int a, int r2, int g2, int b2, int a2, int r3, int g3, int b3, int a3) { Eina_List *l; Edje_Color_Class *cc; GET_ED_OR_RETURN(EINA_FALSE); if (!ed->file || !ed->file->color_classes) return EINA_FALSE; EINA_LIST_FOREACH(ed->file->color_classes, l, cc) if (!strcmp(cc->name, class_name)) { if (r > -1) cc->r = r; if (g > -1) cc->g = g; if (b > -1) cc->b = b; if (a > -1) cc->a = a; if (r2 > -1) cc->r2 = r2; if (g2 > -1) cc->g2 = g2; if (b2 > -1) cc->b2 = b2; if (a2 > -1) cc->a2 = a2; if (r3 > -1) cc->r3 = r3; if (g3 > -1) cc->g3 = g3; if (b3 > -1) cc->b3 = b3; if (a3 > -1) cc->a3 = a3; return EINA_TRUE; } return EINA_FALSE; } EAPI Eina_Bool edje_edit_color_class_add(Evas_Object *obj, const char *name) { Eina_List *l; Edje_Color_Class *c; Edje_Color_Class *cc; GET_ED_OR_RETURN(EINA_FALSE); if (!name || !ed->file) return EINA_FALSE; EINA_LIST_FOREACH(ed->file->color_classes, l, cc) if (strcmp(cc->name, name) == 0) return EINA_FALSE; c = _alloc(sizeof(Edje_Color_Class)); if (!c) return EINA_FALSE; c->name = (char*)eina_stringshare_add(name); c->r = c->g = c->b = c->a = 255; c->r2 = c->g2 = c->b2 = c->a2 = 255; c->r3 = c->g3 = c->b3 = c->a3 = 255; ed->file->color_classes = eina_list_append(ed->file->color_classes, c); return EINA_TRUE; } EAPI Eina_Bool edje_edit_color_class_del(Evas_Object *obj, const char *name) { Eina_List *l; Edje_Color_Class *cc; GET_ED_OR_RETURN(EINA_FALSE); if (!name || !ed->file || !ed->file->color_classes) return EINA_FALSE; EINA_LIST_FOREACH(ed->file->color_classes, l, cc) if (strcmp(cc->name, name) == 0) { _edje_if_string_free(ed, cc->name); ed->file->color_classes = eina_list_remove(ed->file->color_classes, cc); free(cc); return EINA_TRUE; } return EINA_FALSE; } EAPI Eina_Bool edje_edit_color_class_name_set(Evas_Object *obj, const char *name, const char *newname) { Eina_List *l; Edje_Color_Class *cc; GET_ED_OR_RETURN(EINA_FALSE); if (!ed->file || !ed->file->color_classes) return EINA_FALSE; EINA_LIST_FOREACH(ed->file->color_classes, l, cc) if (!strcmp(cc->name, name)) { _edje_if_string_free(ed, cc->name); cc->name = (char*)eina_stringshare_add(newname); return EINA_TRUE; } return EINA_FALSE; } /*********************/ /* TEXT STYLES API */ /*********************/ EAPI Eina_List * edje_edit_styles_list_get(Evas_Object * obj) { Eina_List *styles = NULL; Eina_List *l; Edje_Style *s; GET_ED_OR_RETURN(NULL); if (!ed->file || !ed->file->styles) return NULL; //printf("GET STYLES LIST %d\n", eina_list_count(ed->file->styles)); EINA_LIST_FOREACH(ed->file->styles, l, s) styles = eina_list_append(styles, eina_stringshare_add(s->name)); return styles; } EAPI Eina_Bool edje_edit_style_add(Evas_Object * obj, const char* style) { Edje_Style *s; GET_ED_OR_RETURN(EINA_FALSE); //printf("ADD STYLE '%s'\n", style); s = _edje_edit_style_get(ed, style); if (s) return EINA_FALSE; s = _alloc(sizeof(Edje_Style)); if (!s) return EINA_FALSE; s->name = (char*)eina_stringshare_add(style); s->tags = NULL; s->style = NULL; ed->file->styles = eina_list_append(ed->file->styles, s); return EINA_TRUE; } EAPI Eina_Bool edje_edit_style_del(Evas_Object * obj, const char* style) { Edje_Style *s; GET_ED_OR_RETURN(EINA_FALSE); s = _edje_edit_style_get(ed, style); if (!s) return EINA_FALSE; ed->file->styles = eina_list_remove(ed->file->styles, s); _edje_if_string_free(ed, s->name); //~ //s->style HOWTO FREE ??? while (s->tags) { Edje_Style_Tag *t; t = s->tags->data; s->tags = eina_list_remove(s->tags, t); _edje_if_string_free(ed, t->key); _edje_if_string_free(ed, t->value); _edje_if_string_free(ed, t->font); _edje_if_string_free(ed, t->text_class); free(t); t = NULL; } free(s); s = NULL; s = NULL; return EINA_TRUE; } EAPI Eina_List * edje_edit_style_tags_list_get(Evas_Object * obj, const char* style) { Eina_List *tags = NULL; Eina_List *l; Edje_Style *s; Edje_Style_Tag *t; GET_ED_OR_RETURN(NULL); if (!ed->file || !ed->file->styles || !style) return NULL; s = _edje_edit_style_get(ed, style); //printf("GET STYLE TAG LIST %d\n", eina_list_count(s->tags)); EINA_LIST_FOREACH(s->tags, l, t) tags = eina_list_append(tags, eina_stringshare_add(t->key)); return tags; } EAPI Eina_Bool edje_edit_style_tag_name_set(Evas_Object * obj, const char* style, const char* tag, const char*new_name) { Edje_Style_Tag *t; GET_ED_OR_RETURN(EINA_FALSE); if (!ed->file || !ed->file->styles || !style || !tag) return EINA_FALSE; t = _edje_edit_style_tag_get(ed, style, tag); if (!t) return EINA_FALSE; _edje_if_string_free(ed, t->key); t->key = eina_stringshare_add(new_name); return EINA_TRUE; } EAPI const char* edje_edit_style_tag_value_get(Evas_Object * obj, const char* style, const char* tag) { Edje_Style_Tag *t; GET_ED_OR_RETURN(NULL); //printf("GET TAG '%s' FOR STYLE '%s'\n", tag, style); if (!ed->file || !ed->file->styles || !style || !tag) return NULL; t = _edje_edit_style_tag_get(ed, style, tag); if (t && t->value) return eina_stringshare_add(t->value); return NULL; } EAPI Eina_Bool edje_edit_style_tag_value_set(Evas_Object * obj, const char* style, const char* tag, const char*new_value) { Edje_Style_Tag *t; GET_ED_OR_RETURN(EINA_FALSE); if (!ed->file || !ed->file->styles || !style || !tag || !new_value) return EINA_FALSE; t = _edje_edit_style_tag_get(ed, style, tag); if (!t) return EINA_FALSE; _edje_if_string_free(ed, t->value); t->value = eina_stringshare_add(new_value); return EINA_TRUE; } EAPI Eina_Bool edje_edit_style_tag_add(Evas_Object * obj, const char* style, const char* tag_name) { Edje_Style *s; Edje_Style_Tag *t; GET_ED_OR_RETURN(EINA_FALSE); //printf("ADD TAG '%s' IN STYLE '%s'\n", tag_name, style); t = _edje_edit_style_tag_get(ed, style, tag_name); if (t) return EINA_FALSE; s = _edje_edit_style_get(ed, style); if (!s) return EINA_FALSE; t = _alloc(sizeof(Edje_Style_Tag)); if (!t) return EINA_FALSE; t->key = eina_stringshare_add(tag_name); t->value = NULL; t->font = NULL; t->text_class = NULL; s->tags = eina_list_append(s->tags, t); return EINA_TRUE; } EAPI Eina_Bool edje_edit_style_tag_del(Evas_Object * obj, const char* style, const char* tag) { Edje_Style *s; Edje_Style_Tag *t; GET_ED_OR_RETURN(EINA_FALSE); if (!ed->file || !ed->file->styles || !style || !tag ) return EINA_FALSE; s = _edje_edit_style_get(ed, style); t = _edje_edit_style_tag_get(ed, style, tag); if (!s || !t) return EINA_FALSE; s->tags = eina_list_remove(s->tags, t); _edje_if_string_free(ed, t->key); _edje_if_string_free(ed, t->value); _edje_if_string_free(ed, t->font); _edje_if_string_free(ed, t->text_class); free(t); t = NULL; return EINA_TRUE; } /*******************/ /* EXTERNALS API */ /*******************/ EAPI Eina_List * edje_edit_externals_list_get(Evas_Object *obj) { Eina_List *externals = NULL; unsigned int i; GET_ED_OR_RETURN(NULL); if (!ed->file || !ed->file->external_dir) return NULL; //printf("GET STYLES LIST %d\n", eina_list_count(ed->file->styles)); for (i = 0; i < ed->file->external_dir->entries_count; ++i) externals = eina_list_append(externals, eina_stringshare_add(ed->file->external_dir->entries[i].entry)); return externals; } EAPI Eina_Bool edje_edit_external_add(Evas_Object *obj, const char *external) { Edje_External_Directory_Entry *e; unsigned int freeid; unsigned int i; GET_ED_OR_RETURN(EINA_FALSE); e = _edje_edit_external_get(ed, external); if (e) return EINA_FALSE; if (!ed->file->external_dir) ed->file->external_dir = _alloc(sizeof(Edje_External_Directory)); for (i = 0; i < ed->file->external_dir->entries_count; ++i) if (!ed->file->external_dir->entries[i].entry) break ; if (i == ed->file->external_dir->entries_count) { Edje_External_Directory_Entry *tmp; unsigned int max; max = ed->file->external_dir->entries_count + 1; tmp = realloc(ed->file->external_dir->entries, sizeof (Edje_External_Directory_Entry) * max); if (!tmp) return EINA_FALSE; ed->file->external_dir->entries = tmp; freeid = ed->file->external_dir->entries_count; ed->file->external_dir->entries_count = max; } else freeid = i; ed->file->external_dir->entries[freeid].entry = (char*)eina_stringshare_add(external); return EINA_TRUE; } EAPI Eina_Bool edje_edit_external_del(Evas_Object *obj, const char *external) { Edje_External_Directory_Entry *e; GET_ED_OR_RETURN(EINA_FALSE); e = _edje_edit_external_get(ed, external); if (!e) return EINA_FALSE; _edje_if_string_free(ed, e->entry); e->entry = NULL; return EINA_TRUE; } /***************/ /* PARTS API */ /***************/ EAPI Eina_List * edje_edit_parts_list_get(Evas_Object *obj) { Eina_List *parts = NULL; unsigned int i; GET_ED_OR_RETURN(NULL); //printf("EE: Found %d parts\n", ed->table_parts_size); parts = NULL; for (i = 0; i < ed->table_parts_size; i++) { Edje_Real_Part *rp; rp = ed->table_parts[i]; parts = eina_list_append(parts, eina_stringshare_add(rp->part->name)); } return parts; } EAPI Eina_Bool edje_edit_part_name_set(Evas_Object *obj, const char* part, const char* new_name) { GET_EED_OR_RETURN(EINA_FALSE); GET_RP_OR_RETURN(EINA_FALSE); if (!new_name) return EINA_FALSE; if (!strcmp(part, new_name)) return EINA_TRUE; if (_edje_real_part_get(ed, new_name)) return EINA_FALSE; //printf("Set name of part: %s [new name: %s]\n", part, new_name); _edje_if_string_free(ed, rp->part->name); rp->part->name = (char *)eina_stringshare_add(new_name); _edje_edit_flag_script_dirty(eed, EINA_TRUE); return EINA_TRUE; } #define FUNC_PART_API_STRING(Value) \ EAPI const char * \ edje_edit_part_api_##Value##_get(Evas_Object *obj, const char *part) \ { \ GET_RP_OR_RETURN(NULL); \ return eina_stringshare_add(rp->part->api.Value); \ } \ EAPI Eina_Bool \ edje_edit_part_api_##Value##_set(Evas_Object *obj, const char *part, const char *s) \ { \ GET_RP_OR_RETURN(EINA_FALSE); \ _edje_if_string_free(ed, rp->part->api.Value); \ rp->part->api.Value = eina_stringshare_add(s); \ return EINA_TRUE; \ } FUNC_PART_API_STRING(name); FUNC_PART_API_STRING(description); static Eina_Bool _edje_edit_real_part_add(Evas_Object *obj, const char *name, Edje_Part_Type type, const char *source) { Edje_Part_Collection_Directory_Entry *ce; Edje_Part_Collection *pc; Edje_Part **tmp; Edje_Part *ep; Edje_Real_Part *rp; int id; GET_ED_OR_RETURN(EINA_FALSE); //printf("ADD PART: %s [type: %d]\n", name, type); /* Check if part already exists */ if (_edje_real_part_get(ed, name)) return EINA_FALSE; if (!ed->file) return EINA_FALSE; ce = eina_hash_find(ed->file->collection, ed->group); /* Alloc Edje_Part or return */ ep = eina_mempool_malloc(ce->mp.part, sizeof(Edje_Part)); if (!ep) return EINA_FALSE; memset(ep, 0, sizeof(Edje_Part)); /* Alloc Edje_Real_Part or return */ rp = eina_mempool_malloc(_edje_real_part_mp, sizeof(Edje_Real_Part)); if (!rp) { eina_mempool_free(ce->mp.part, ep); return EINA_FALSE; } memset(rp, 0, sizeof(Edje_Real_Part)); /* Init Edje_Part */ pc = ed->collection; tmp = realloc(pc->parts, (pc->parts_count + 1) * sizeof (Edje_Part *)); if (!tmp) { eina_mempool_free(ce->mp.part, ep); eina_mempool_free(_edje_real_part_mp, rp); return EINA_FALSE; } id = pc->parts_count++; pc->parts = tmp; pc->parts[id] = ep; ep->id = id; ep->type = type; ep->name = eina_stringshare_add(name); ep->mouse_events = 1; ep->repeat_events = 0; ep->ignore_flags = EVAS_EVENT_FLAG_NONE; ep->pointer_mode = EVAS_OBJECT_POINTER_MODE_AUTOGRAB; ep->precise_is_inside = 0; ep->use_alternate_font_metrics = 0; ep->clip_to_id = -1; ep->dragable.confine_id = -1; ep->dragable.event_id = -1; if (source) ep->source = eina_stringshare_add(source); ep->default_desc = NULL; ep->other.desc = NULL; ep->other.desc_count = 0; /* Init Edje_Real_Part */ _edje_ref(ed); rp->part = ep; if (ep->type == EDJE_PART_TYPE_RECTANGLE) rp->object = evas_object_rectangle_add(ed->base->evas); else if (ep->type == EDJE_PART_TYPE_IMAGE || ep->type == EDJE_PART_TYPE_PROXY) rp->object = evas_object_image_add(ed->base->evas); else if (ep->type == EDJE_PART_TYPE_TEXT) { rp->type = EDJE_RP_TYPE_TEXT; rp->typedata.text = calloc(1, sizeof(Edje_Real_Part_Text)); _edje_text_part_on_add(ed, rp); rp->object = evas_object_text_add(ed->base->evas); evas_object_text_font_source_set(rp->object, ed->path); } else if (ep->type == EDJE_PART_TYPE_SWALLOW || ep->type == EDJE_PART_TYPE_GROUP || ep->type == EDJE_PART_TYPE_EXTERNAL) { rp->type = EDJE_RP_TYPE_SWALLOW; rp->typedata.swallow = calloc(1, sizeof(Edje_Real_Part_Swallow)); rp->object = evas_object_rectangle_add(ed->base->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); } else if (ep->type == EDJE_PART_TYPE_TEXTBLOCK) { rp->type = EDJE_RP_TYPE_TEXT; rp->typedata.text = calloc(1, sizeof(Edje_Real_Part_Text)); rp->object = evas_object_textblock_add(ed->base->evas); } else if (ep->type == EDJE_PART_TYPE_BOX || ep->type == EDJE_PART_TYPE_TABLE) { rp->type = EDJE_RP_TYPE_CONTAINER; rp->typedata.container = calloc(1, sizeof(Edje_Real_Part_Container)); } else if (ep->type != EDJE_PART_TYPE_SPACER) ERR("wrong part type %i!", ep->type); if (rp->object) { evas_object_show(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) { 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 (ep->type == EDJE_PART_TYPE_EXTERNAL) { Evas_Object *child; child = _edje_external_type_add(source, evas_object_evas_get(ed->obj), ed->obj, NULL, name); if (child) _edje_real_part_swallow(ed, rp, child, EINA_TRUE); } evas_object_clip_set(rp->object, ed->base->clipper); evas_object_show(ed->base->clipper); } /* Update table_parts */ ed->table_parts_size++; ed->table_parts = realloc(ed->table_parts, sizeof(Edje_Real_Part *) * ed->table_parts_size); ed->table_parts[ep->id % ed->table_parts_size] = rp; /* Create default description */ if (!edje_edit_state_add(obj, name, "default", 0.0)) { _edje_if_string_free(ed, ep->name); if (source) _edje_if_string_free(ed, ep->source); eina_mempool_free(ce->mp.part, ep); eina_mempool_free(_edje_real_part_mp, rp); return EINA_FALSE; } edje_edit_part_selected_state_set(obj, name, "default", 0.0); ce->count.part++; return EINA_TRUE; } EAPI Eina_Bool edje_edit_part_add(Evas_Object *obj, const char *name, Edje_Part_Type type) { if (type == EDJE_PART_TYPE_EXTERNAL) return EINA_FALSE; return _edje_edit_real_part_add(obj, name, type, NULL); } EAPI Eina_Bool edje_edit_part_external_add(Evas_Object *obj, const char *name, const char *source) { if (!source) return EINA_FALSE; return _edje_edit_real_part_add(obj, name, EDJE_PART_TYPE_EXTERNAL, source); } EAPI Eina_Bool edje_edit_part_del(Evas_Object *obj, const char* part) { Edje_Part_Collection_Directory_Entry *ce; Edje_Part_Collection *pc; Edje_Part *ep; unsigned int k; unsigned int id; unsigned int i; GET_EED_OR_RETURN(EINA_FALSE); GET_RP_OR_RETURN(EINA_FALSE); //printf("REMOVE PART: %s\n", part); ep = rp->part; id = ep->id; /* Unlik Edje_Real_Parts that link to the removed one */ for (i = 0; i < ed->table_parts_size; i++) { Edje_Real_Part *real; if (i == id) continue; //don't check the deleted id real = ed->table_parts[i]; if ((real->typedata.text) && (real->typedata.text->source == rp)) real->typedata.text->source = NULL; if ((real->typedata.text) && (real->typedata.text->text_source == rp)) real->typedata.text->text_source = NULL; if (real->part->clip_to_id == rp->part->id) { evas_object_clip_set(real->object, ed->base->clipper); real->part->clip_to_id = -1; } if (real->drag && real->drag->confine_to == rp) { real->drag->confine_to = NULL; } if (real->part->dragable.event_id != -1) { if (real->part->dragable.event_id == TO_INT(id)) real->part->dragable.event_id = -1; else if (i > id) real->part->dragable.event_id--; } } /* Unlink all the parts and descriptions that refer to id */ _edje_part_id_set(ed, rp, -1); /* Remove part from parts list */ pc = ed->collection; pc->parts_count--; if (id < pc->parts_count) /* Forward parts */ { int mcount = (pc->parts_count - id) * sizeof(Edje_Part *); memmove(&pc->parts[id], &pc->parts[id+1], mcount); } pc->parts[pc->parts_count] = NULL; _edje_fix_parts_id(ed); /* Free Edje_Part and all descriptions */ ce = eina_hash_find(ed->file->collection, ed->group); _edje_if_string_free(ed, ep->name); if (ep->default_desc) { _edje_collection_free_part_description_free(ep->type, ep->default_desc, ce, 0); ep->default_desc = NULL; } for (k = 0; k < ep->other.desc_count; ++k) _edje_collection_free_part_description_free(ep->type, ep->other.desc[k], ce, 0); free(ep->other.desc); eina_mempool_free(ce->mp.part, ep); /* Free Edje_Real_Part */ _edje_real_part_free(ed, rp); /* if all parts are gone, hide the clipper */ if (ed->table_parts_size == 0) evas_object_hide(ed->base->clipper); edje_object_calc_force(obj); ce->count.part--; _edje_edit_flag_script_dirty(eed, EINA_TRUE); return EINA_TRUE; } static Eina_Bool _edje_edit_part_state_copy(Evas_Object *obj, const char *part_from, const char *part_to, const char *from, double val_from, const char *to, double val_to); EAPI Eina_Bool edje_edit_part_copy(Evas_Object *obj, const char *part, const char *new_copy) { Edje_Part *ep, *epcopy; unsigned int i, count; Edje_Real_Part *rpcopy; GET_RP_OR_RETURN(EINA_FALSE); ep = rp->part; /* Check if part doesn't exists */ if (_edje_real_part_get(ed, new_copy)) return EINA_FALSE; if (!ed->file) return EINA_FALSE; /* Create part (EXTERNAL or not) */ if (!_edje_edit_real_part_add(obj, new_copy, ep->type, ep->source)) return EINA_FALSE; /* Copy part's data */ rpcopy = _edje_real_part_get(ed, new_copy); if (!rpcopy) return EINA_FALSE; epcopy = rpcopy->part; #define _PARAM_PART_COPY(param) \ epcopy->param = ep->param; _PARAM_PART_COPY(scale) _PARAM_PART_COPY(mouse_events) _PARAM_PART_COPY(repeat_events) _PARAM_PART_COPY(ignore_flags) _PARAM_PART_COPY(pointer_mode) _PARAM_PART_COPY(precise_is_inside) _PARAM_PART_COPY(use_alternate_font_metrics) _PARAM_PART_COPY(clip_to_id) _PARAM_PART_COPY(dragable.event_id) _PARAM_PART_COPY(dragable.confine_id) _PARAM_PART_COPY(dragable.threshold_id) _PARAM_PART_COPY(dragable.step_x) _PARAM_PART_COPY(dragable.step_y) _PARAM_PART_COPY(dragable.count_x) _PARAM_PART_COPY(dragable.count_y) _PARAM_PART_COPY(dragable.x) _PARAM_PART_COPY(dragable.y) if (rp->part->type == EDJE_PART_TYPE_TEXTBLOCK) { epcopy->source2 = (char *)eina_stringshare_add(ep->source2); epcopy->source3 = (char *)eina_stringshare_add(ep->source3); epcopy->source4 = (char *)eina_stringshare_add(ep->source4); epcopy->source5 = (char *)eina_stringshare_add(ep->source5); epcopy->source6 = (char *)eina_stringshare_add(ep->source6); } #ifdef HAVE_EPHYSICS _PARAM_PART_COPY(physics_body) #endif _PARAM_PART_COPY(effect) _PARAM_PART_COPY(entry_mode) _PARAM_PART_COPY(select_mode) _PARAM_PART_COPY(cursor_mode) _PARAM_PART_COPY(multiline) _PARAM_PART_COPY(access) if (ep->api.name) epcopy->api.name = eina_stringshare_add(ep->api.name); if (ep->api.description) epcopy->api.description = eina_stringshare_add(ep->api.description); #undef _PARAM_PART_COPY /* Copy default state */ _edje_edit_part_state_copy(obj, part, new_copy, "default", 0.0, "default", 0.0); /* Copy all other states */ count = rp->part->other.desc_count; for (i = 0; i < count; ++i) { _edje_edit_part_state_copy(obj, part, new_copy, rp->part->other.desc[i]->state.name, rp->part->other.desc[i]->state.value, rp->part->other.desc[i]->state.name, rp->part->other.desc[i]->state.value); } return EINA_TRUE; } EAPI Eina_Bool edje_edit_part_exist(Evas_Object *obj, const char *part) { GET_RP_OR_RETURN(EINA_FALSE); return EINA_TRUE; } EAPI const char* edje_edit_part_below_get(Evas_Object *obj, const char* part) { Edje_Real_Part *prev; GET_RP_OR_RETURN(0); if (rp->part->id < 1) return NULL; prev = ed->table_parts[(rp->part->id - 1) % ed->table_parts_size]; return eina_stringshare_add(prev->part->name); } EAPI const char* edje_edit_part_above_get(Evas_Object *obj, const char* part) { Edje_Real_Part *next; GET_RP_OR_RETURN(0); if ((unsigned int) rp->part->id >= ed->table_parts_size - 1) return 0; next = ed->table_parts[(rp->part->id + 1) % ed->table_parts_size]; return eina_stringshare_add(next->part->name); } EAPI Eina_Bool edje_edit_part_restack_below(Evas_Object *obj, const char* part) { Edje_Part_Collection *group; Edje_Real_Part *prev; Edje_Part *swap; GET_EED_OR_RETURN(EINA_FALSE); GET_RP_OR_RETURN(EINA_FALSE); //printf("RESTACK PART: %s BELOW\n", part); if (rp->part->id < 1) return EINA_FALSE; group = ed->collection; /* update parts list */ prev = ed->table_parts[(rp->part->id - 1) % ed->table_parts_size]; swap = group->parts[rp->part->id]; group->parts[rp->part->id] = group->parts[prev->part->id]; group->parts[prev->part->id] = swap; _edje_parts_id_switch(ed, rp, prev); evas_object_stack_below(rp->object, prev->object); if ((rp->typedata.swallow) && (rp->typedata.swallow->swallowed_object)) evas_object_stack_above(rp->typedata.swallow->swallowed_object, rp->object); _edje_edit_flag_script_dirty(eed, EINA_TRUE); return EINA_TRUE; } EAPI Eina_Bool edje_edit_part_restack_part_below(Evas_Object *obj, const char* part, const char *below) { Edje_Part_Collection *group; Edje_Real_Part *rp, *rp_below, *prev; Edje_Part *swap; GET_EED_OR_RETURN(EINA_FALSE); GET_ED_OR_RETURN(EINA_FALSE); rp = _edje_real_part_get(ed, part); if (!rp) return EINA_FALSE; rp_below = _edje_real_part_get(ed, below); if (!rp_below) return EINA_FALSE; if (rp->part->id < 1) return EINA_FALSE; if (rp_below->part->id < 1) return EINA_FALSE; group = ed->collection; while (rp->part->id != (rp_below->part->id - 1)) { if (rp->part->id > rp_below->part->id) prev = ed->table_parts[(rp->part->id - 1) % ed->table_parts_size]; else prev = ed->table_parts[(rp->part->id + 1) % ed->table_parts_size]; swap = group->parts[rp->part->id]; group->parts[rp->part->id] = group->parts[prev->part->id]; group->parts[prev->part->id] = swap; _edje_parts_id_switch(ed, rp, prev); } evas_object_stack_below(rp->object, rp_below->object); if ((rp->typedata.swallow) && (rp->typedata.swallow->swallowed_object)) evas_object_stack_above(rp->typedata.swallow->swallowed_object, rp->object); _edje_edit_flag_script_dirty(eed, EINA_TRUE); return EINA_TRUE; } EAPI Eina_Bool edje_edit_part_restack_above(Evas_Object *obj, const char* part) { Edje_Part_Collection *group; Edje_Real_Part *next; Edje_Part *swap; GET_EED_OR_RETURN(EINA_FALSE); GET_RP_OR_RETURN(EINA_FALSE); //printf("RESTACK PART: %s ABOVE\n", part); if ((unsigned int) rp->part->id >= ed->table_parts_size - 1) return EINA_FALSE; group = ed->collection; /* update parts list */ next = ed->table_parts[(rp->part->id + 1) % ed->table_parts_size]; swap = group->parts[rp->part->id]; group->parts[rp->part->id] = group->parts[next->part->id]; group->parts[next->part->id] = swap; /* update ids */ _edje_parts_id_switch(ed, rp, next); evas_object_stack_above(rp->object, next->object); if ((rp->typedata.swallow) && (rp->typedata.swallow->swallowed_object)) evas_object_stack_above(rp->typedata.swallow->swallowed_object, rp->object); _edje_edit_flag_script_dirty(eed, EINA_TRUE); return EINA_TRUE; } EAPI Eina_Bool edje_edit_part_restack_part_above(Evas_Object *obj, const char* part, const char *above) { Edje_Part_Collection *group; Edje_Real_Part *rp, *rp_above, *next; Edje_Part *swap; GET_EED_OR_RETURN(EINA_FALSE); GET_ED_OR_RETURN(EINA_FALSE); rp = _edje_real_part_get(ed, part); if (!rp) return EINA_FALSE; rp_above = _edje_real_part_get(ed, above); if (!rp_above) return EINA_FALSE; if (rp->part->id < 1) return EINA_FALSE; if (rp_above->part->id < 1) return EINA_FALSE; group = ed->collection; while (rp->part->id != rp_above->part->id + 1) { if (rp->part->id > rp_above->part->id) next = ed->table_parts[(rp->part->id - 1) % ed->table_parts_size]; else next = ed->table_parts[(rp->part->id + 1) % ed->table_parts_size]; swap = group->parts[rp->part->id]; group->parts[rp->part->id] = group->parts[next->part->id]; group->parts[next->part->id] = swap; _edje_parts_id_switch(ed, rp, next); } evas_object_stack_above(rp->object, rp_above->object); if ((rp->typedata.swallow) && (rp->typedata.swallow->swallowed_object)) evas_object_stack_above(rp->typedata.swallow->swallowed_object, rp->object); _edje_edit_flag_script_dirty(eed, EINA_TRUE); return EINA_TRUE; } EAPI Edje_Part_Type edje_edit_part_type_get(Evas_Object *obj, const char *part) { GET_RP_OR_RETURN(0); return rp->part->type; } EAPI const char * edje_edit_part_selected_state_get(Evas_Object *obj, const char *part, double *value) { GET_RP_OR_RETURN(NULL); if (!rp->chosen_description) { if (value) *value = 0.0; // FIXME: Make sure edje_edit supports correctly the default having any value return eina_stringshare_add("default"); } if (value) *value = rp->chosen_description->state.value; return eina_stringshare_add(rp->chosen_description->state.name); } EAPI Eina_Bool edje_edit_part_selected_state_set(Evas_Object *obj, const char *part, const char *state, double value) { Edje_Part_Description_Common *pd; GET_EED_OR_RETURN(EINA_FALSE); GET_RP_OR_RETURN(EINA_FALSE); pd = _edje_part_description_find_byname(eed, part, state, value); if (!pd) return EINA_FALSE; //printf("EDJE: Set state: %s %f\n", pd->state.name, pd->state.value); _edje_part_description_apply(ed, rp, pd->state.name, pd->state.value, NULL, 0.0); edje_object_calc_force(obj); return EINA_TRUE; } EAPI const char * edje_edit_part_clip_to_get(Evas_Object *obj, const char *part) { Edje_Real_Part *clip = NULL; GET_RP_OR_RETURN(NULL); //printf("Get clip_to for part: %s [to_id: %d]\n", part, rp->part->clip_to_id); if (rp->part->clip_to_id < 0) return NULL; clip = ed->table_parts[rp->part->clip_to_id % ed->table_parts_size]; if (!clip || !clip->part || !clip->part->name) return NULL; return eina_stringshare_add(clip->part->name); } EAPI Eina_Bool edje_edit_part_clip_to_set(Evas_Object *obj, const char *part, const char *clip_to) { Edje_Real_Part *clip; Evas_Object *o, *oo; GET_RP_OR_RETURN(EINA_FALSE); /* unset clipping */ if (!clip_to) { if (rp->part->clip_to_id >= 0) { clip = ed->table_parts[rp->part->clip_to_id % ed->table_parts_size]; evas_object_pointer_mode_set(clip->object, EVAS_OBJECT_POINTER_MODE_AUTOGRAB); evas_object_clip_unset(rp->object); } evas_object_clip_set(rp->object, ed->base->clipper); if ((rp->typedata.swallow) && (rp->typedata.swallow->swallowed_object)) evas_object_clip_set(rp->typedata.swallow->swallowed_object, ed->base->clipper); rp->part->clip_to_id = -1; edje_object_calc_force(obj); return EINA_TRUE; } /* set clipping */ //printf("Set clip_to for part: %s [to: %s]\n", part, clip_to); clip = _edje_real_part_get(ed, clip_to); if (!clip || !clip->part) return EINA_FALSE; o = clip->object; while ((oo = evas_object_clip_get(o))) { if (o == rp->object) return EINA_FALSE; o = oo; } rp->part->clip_to_id = clip->part->id; evas_object_pass_events_set(clip->object, 1); evas_object_pointer_mode_set(clip->object, EVAS_OBJECT_POINTER_MODE_NOGRAB); evas_object_clip_set(rp->object, clip->object); if ((rp->typedata.swallow) && (rp->typedata.swallow->swallowed_object)) evas_object_clip_set(rp->typedata.swallow->swallowed_object, clip->object); edje_object_calc_force(obj); return EINA_TRUE; } EAPI Eina_Bool edje_edit_part_mouse_events_get(Evas_Object *obj, const char *part) { GET_RP_OR_RETURN(EINA_FALSE); return rp->part->mouse_events; } EAPI Eina_Bool edje_edit_part_mouse_events_set(Evas_Object *obj, const char *part, Eina_Bool mouse_events) { GET_RP_OR_RETURN(EINA_FALSE); if (!rp->object) return EINA_FALSE; rp->part->mouse_events = mouse_events ? 1 : 0; if (mouse_events) { evas_object_pass_events_set(rp->object, 0); _edje_callbacks_add(rp->object, ed, rp); } else { evas_object_pass_events_set(rp->object, 1); _edje_callbacks_del(rp->object, ed); } return EINA_TRUE; } EAPI Eina_Bool edje_edit_part_repeat_events_get(Evas_Object *obj, const char *part) { GET_RP_OR_RETURN(EINA_FALSE); return rp->part->repeat_events; } EAPI Eina_Bool edje_edit_part_repeat_events_set(Evas_Object *obj, const char *part, Eina_Bool repeat_events) { GET_RP_OR_RETURN(EINA_FALSE); if (!rp->object) return EINA_FALSE; rp->part->repeat_events = repeat_events ? 1 : 0; if (repeat_events) evas_object_repeat_events_set(rp->object, 1); else evas_object_repeat_events_set(rp->object, 0); return EINA_TRUE; } EAPI Eina_Bool edje_edit_part_precise_is_inside_get(Evas_Object *obj, const char *part) { GET_RP_OR_RETURN(0); return rp->part->precise_is_inside; } EAPI Eina_Bool edje_edit_part_precise_is_inside_set(Evas_Object *obj, const char *part, Eina_Bool precise_is_inside) { GET_RP_OR_RETURN(EINA_FALSE); if (!rp->object) return EINA_FALSE; rp->part->precise_is_inside = precise_is_inside; return EINA_TRUE; } EAPI Eina_Bool edje_edit_part_access_get(Evas_Object *obj, const char *part) { GET_RP_OR_RETURN(0); return rp->part->access; } EAPI Eina_Bool edje_edit_part_access_set(Evas_Object *obj, const char *part, Eina_Bool access) { GET_RP_OR_RETURN(EINA_FALSE); if (!rp->object) return EINA_FALSE; rp->part->access = access; return EINA_TRUE; } EAPI Evas_Event_Flags edje_edit_part_ignore_flags_get(Evas_Object *obj, const char *part) { GET_RP_OR_RETURN(0); return rp->part->ignore_flags; } EAPI Eina_Bool edje_edit_part_ignore_flags_set(Evas_Object *obj, const char *part, Evas_Event_Flags ignore_flags) { GET_RP_OR_RETURN(EINA_FALSE); if (!rp->object) return EINA_FALSE; rp->part->ignore_flags = ignore_flags; return EINA_TRUE; } EAPI Evas_Object_Pointer_Mode edje_edit_part_pointer_mode_get(Evas_Object *obj, const char *part) { GET_RP_OR_RETURN(0); return rp->part->pointer_mode; } EAPI Eina_Bool edje_edit_part_pointer_mode_set(Evas_Object *obj, const char *part, Evas_Object_Pointer_Mode pointer_mode) { GET_RP_OR_RETURN(EINA_FALSE); if (!rp->object) return EINA_FALSE; rp->part->pointer_mode = pointer_mode; return EINA_TRUE; } EAPI Eina_Bool edje_edit_part_scale_set(Evas_Object *obj, const char *part, Eina_Bool scale) { GET_RP_OR_RETURN(EINA_FALSE); rp->part->scale = scale ? 1 : 0; edje_object_calc_force(obj); return EINA_TRUE; } EAPI Eina_Bool edje_edit_part_scale_get(Evas_Object *obj, const char *part) { GET_RP_OR_RETURN(EINA_FALSE); return rp->part->scale; } EAPI const char * edje_edit_part_source_get(Evas_Object *obj, const char *part) { GET_RP_OR_RETURN(NULL); //printf("Get source for part: %s\n", part); if (!rp->part->source) return NULL; return eina_stringshare_add(rp->part->source); } EAPI Eina_Bool edje_edit_part_source_set(Evas_Object *obj, const char *part, const char *source) { GET_RP_OR_RETURN(EINA_FALSE); Evas_Object *child_obj; //printf("Set source for part: %s [source: %s]\n", part, source); switch(rp->part->type) { case EDJE_PART_TYPE_GROUP: { if ((rp->typedata.swallow) && (rp->typedata.swallow->swallowed_object)) { _edje_real_part_swallow_clear(ed, rp); evas_object_del(rp->typedata.swallow->swallowed_object); rp->typedata.swallow->swallowed_object = NULL; } if (source) { child_obj = edje_object_add(ed->base->evas); edje_object_file_set(child_obj, ed->file->path, source); _edje_real_part_swallow(ed, rp, child_obj, EINA_TRUE); } } case EDJE_PART_TYPE_TEXTBLOCK: { _edje_if_string_free(ed, rp->part->source); if (source) rp->part->source = eina_stringshare_add(source); else rp->part->source = NULL; return EINA_TRUE; } case EDJE_PART_TYPE_EXTERNAL: //EXTERNAL part has source property but it cannot be changed default: { return EINA_FALSE; } } } #define TEXT_BLOCK_SOURCE_GET(N) \ EAPI const char * \ edje_edit_part_source ## N ## _get(Evas_Object *obj, const char *part) \ { \ GET_RP_OR_RETURN(NULL); \ if (!rp->part->source ## N) return NULL; \ return eina_stringshare_add(rp->part->source ## N); \ } #define TEXT_BLOCK_SOURCE_SET(N) \ EAPI Eina_Bool \ edje_edit_part_source ## N ##_set(Evas_Object *obj, const char *part, const char *source) \ { \ GET_RP_OR_RETURN(EINA_FALSE); \ \ if (rp->part->type != EDJE_PART_TYPE_TEXTBLOCK) \ return EINA_FALSE; \ \ eina_stringshare_del(rp->part->source ## N); \ if (source) \ rp->part->source ## N = eina_stringshare_add(source); \ else \ rp->part->source ## N = NULL; \ edje_object_calc_force(obj); \ return EINA_TRUE; \ } TEXT_BLOCK_SOURCE_GET(2); TEXT_BLOCK_SOURCE_GET(3); TEXT_BLOCK_SOURCE_GET(4); TEXT_BLOCK_SOURCE_GET(5); TEXT_BLOCK_SOURCE_GET(6); TEXT_BLOCK_SOURCE_SET(2); TEXT_BLOCK_SOURCE_SET(3); TEXT_BLOCK_SOURCE_SET(4); TEXT_BLOCK_SOURCE_SET(5); TEXT_BLOCK_SOURCE_SET(6); EAPI int edje_edit_part_drag_x_get(Evas_Object *obj, const char *part) { GET_RP_OR_RETURN(0); return rp->part->dragable.x; } EAPI Eina_Bool edje_edit_part_drag_x_set(Evas_Object *obj, const char *part, int drag) { GET_RP_OR_RETURN(EINA_FALSE); rp->part->dragable.x = drag; if (!drag && !rp->part->dragable.y) { free(rp->drag); rp->drag = NULL; return EINA_TRUE; } if (rp->drag) return EINA_TRUE; rp->drag = _alloc(sizeof (Edje_Real_Part_Drag)); if (!rp->drag) return EINA_FALSE; rp->drag->step.x = rp->part->dragable.step_x; rp->drag->step.y = rp->part->dragable.step_y; return EINA_TRUE; } EAPI int edje_edit_part_drag_y_get(Evas_Object *obj, const char *part) { GET_RP_OR_RETURN(0); return rp->part->dragable.y; } EAPI Eina_Bool edje_edit_part_drag_y_set(Evas_Object *obj, const char *part, int drag) { GET_RP_OR_RETURN(EINA_FALSE); rp->part->dragable.y = drag; if (!drag && !rp->part->dragable.x) { free(rp->drag); rp->drag = NULL; return EINA_TRUE; } if (rp->drag) return EINA_TRUE; rp->drag = _alloc(sizeof (Edje_Real_Part_Drag)); if (!rp->drag) return EINA_FALSE; rp->drag->step.x = rp->part->dragable.step_x; rp->drag->step.y = rp->part->dragable.step_y; return EINA_TRUE; } #define FUNC_PART_DRAG_INT(Class, Value) \ EAPI int \ edje_edit_part_drag_##Class##_##Value##_get(Evas_Object *obj, const char *part) \ { \ GET_RP_OR_RETURN(0); \ return rp->part->dragable.Class##_##Value; \ } \ EAPI Eina_Bool \ edje_edit_part_drag_##Class##_##Value##_set(Evas_Object *obj, const char *part, int v) \ { \ GET_RP_OR_RETURN(EINA_FALSE); \ rp->part->dragable.Class##_##Value = v; \ return EINA_TRUE; \ } FUNC_PART_DRAG_INT(step, x); FUNC_PART_DRAG_INT(step, y); FUNC_PART_DRAG_INT(count, x); FUNC_PART_DRAG_INT(count, y); #define FUNC_PART_DRAG_ID(Id) \ EAPI const char* \ edje_edit_part_drag_##Id##_get(Evas_Object *obj, const char *part) \ { \ Edje_Real_Part *p; \ \ GET_RP_OR_RETURN(NULL); \ \ if (rp->part->dragable.Id##_id < 0) \ return NULL; \ \ p = ed->table_parts[rp->part->dragable.Id##_id]; \ return eina_stringshare_add(p->part->name); \ } \ EAPI Eina_Bool \ edje_edit_part_drag_##Id##_set(Evas_Object *obj, const char *part, const char *e) \ { \ Edje_Real_Part *e_part; \ \ eina_error_set(0); \ if ((!obj) || (!part)) \ return EINA_FALSE; \ \ GET_RP_OR_RETURN(EINA_FALSE); \ if (!e) \ { \ rp->part->dragable.Id##_id = -1; \ return EINA_TRUE; \ } \ e_part = _edje_real_part_get(ed, e); \ if (!e_part) return EINA_FALSE; \ rp->part->dragable.Id##_id = e_part->part->id; \ return EINA_TRUE; \ } FUNC_PART_DRAG_ID(confine); FUNC_PART_DRAG_ID(event); FUNC_PART_DRAG_ID(threshold); /*********************/ /* PART STATES API */ /*********************/ EAPI Eina_List * edje_edit_part_states_list_get(Evas_Object *obj, const char *part) { char state_name[PATH_MAX]; Eina_List *states = NULL; unsigned int i; GET_RP_OR_RETURN(NULL); //Is there a better place to put this? maybe edje_edit_init() ? setlocale(LC_NUMERIC, "C"); states = NULL; //append default state snprintf(state_name, PATH_MAX, "%s %.2f", rp->part->default_desc->state.name, rp->part->default_desc->state.value); states = eina_list_append(states, eina_stringshare_add(state_name)); //printf("NEW STATE def: %s\n", state->state.name); //append other states for (i = 0; i < rp->part->other.desc_count; ++i) { snprintf(state_name, sizeof(state_name), "%s %.2f", rp->part->other.desc[i]->state.name, rp->part->other.desc[i]->state.value); states = eina_list_append(states, eina_stringshare_add(state_name)); //printf("NEW STATE: %s\n", state_name); } return states; } EAPI Eina_Bool edje_edit_state_name_set(Evas_Object *obj, const char *part, const char *state, double value, const char *new_name, double new_value) { int part_id; int i; GET_PD_OR_RETURN(EINA_FALSE); //printf("Set name of state: %s in part: %s [new name: %s]\n", // part, state, new_name); if (!new_name) return EINA_FALSE; /* update programs */ /* update the 'state' field in all programs. update only if program has a single target */ part_id = _edje_part_id_find(ed, part); for (i = 0; i < ed->collection->patterns.table_programs_size; i++) { Edje_Program *epr = ed->collection->patterns.table_programs[i]; if (eina_list_count(epr->targets) == 1) { Edje_Program_Target *t = eina_list_data_get(epr->targets); if (t->id == part_id && !strcmp(epr->state, pd->state.name) && pd->state.value == epr->value) { _edje_if_string_free(ed, epr->state); epr->state = eina_stringshare_add(new_name); epr->value = value; } } } /* set name */ _edje_if_string_free(ed, pd->state.name); pd->state.name = (char *)eina_stringshare_add(new_name); /* set value */ pd->state.value = new_value; return EINA_TRUE; } EAPI Eina_Bool edje_edit_state_del(Evas_Object *obj, const char *part, const char *state, double value) { Edje_Part_Collection_Directory_Entry *ce; Edje_Part_Description_Common *pd; unsigned int i; GET_EED_OR_RETURN(EINA_FALSE); GET_RP_OR_RETURN(EINA_FALSE); if (!edje_edit_state_exist(obj, part, state, value)) return EINA_FALSE; pd = _edje_part_description_find_byname(eed, part, state, value); if (!pd) return EINA_FALSE; /* Don't allow to delete default state, for now at least; */ if (pd == rp->part->default_desc) return EINA_FALSE; /* And if we are deleting the current state, go back to default first */ if (pd == rp->chosen_description) _edje_part_description_apply(ed, rp, "default", 0.0, NULL, 0.0); ce = eina_hash_find(ed->file->collection, ed->group); for (i = 0; i < rp->part->other.desc_count; ++i) if (pd == rp->part->other.desc[i]) { memmove(rp->part->other.desc + i, rp->part->other.desc + i + 1, sizeof (Edje_Part_Description_Common*) * (rp->part->other.desc_count - i - 1)); rp->part->other.desc_count--; break; } _edje_collection_free_part_description_free(rp->part->type, pd, ce, 0); return EINA_TRUE; } static Edje_Part_Description_Common * _edje_edit_state_alloc(int type, Edje *ed) { Edje_Part_Collection_Directory_Entry *ce; Edje_Part_Description_Common *pd = NULL; ce = eina_hash_find(ed->file->collection, ed->group); switch (type) { case EDJE_PART_TYPE_RECTANGLE: pd = eina_mempool_malloc(ce->mp.RECTANGLE, sizeof (Edje_Part_Description_Common)); ce->count.RECTANGLE++; break; case EDJE_PART_TYPE_SPACER: pd = eina_mempool_malloc(ce->mp.SPACER, sizeof (Edje_Part_Description_Common)); ce->count.SPACER++; break; case EDJE_PART_TYPE_SWALLOW: pd = eina_mempool_malloc(ce->mp.SWALLOW, sizeof (Edje_Part_Description_Common)); ce->count.SWALLOW++; break; case EDJE_PART_TYPE_GROUP: pd = eina_mempool_malloc(ce->mp.GROUP, sizeof (Edje_Part_Description_Common)); ce->count.GROUP++; break; #define EDIT_ALLOC_POOL(Short, Type, Name) \ case EDJE_PART_TYPE_##Short: \ { \ Edje_Part_Description_##Type *Name; \ \ Name = eina_mempool_malloc(ce->mp.Short, \ sizeof (Edje_Part_Description_##Type)); \ memset(Name, 0, sizeof(Edje_Part_Description_##Type)); \ pd = &Name->common; \ ce->count.Short++; \ break; \ } EDIT_ALLOC_POOL(IMAGE, Image, image); EDIT_ALLOC_POOL(TEXT, Text, text); EDIT_ALLOC_POOL(TEXTBLOCK, Text, text); EDIT_ALLOC_POOL(BOX, Box, box); EDIT_ALLOC_POOL(TABLE, Table, table); EDIT_ALLOC_POOL(EXTERNAL, External, external_params); } return pd; } EAPI Eina_Bool edje_edit_state_add(Evas_Object *obj, const char *part, const char *name, double value) { Edje_Part_Description_Common *pd; GET_RP_OR_RETURN(EINA_FALSE); if (edje_edit_state_exist(obj, part, name, value)) return EINA_FALSE; //printf("ADD STATE: %s TO PART: %s\n", name , part); pd = _edje_edit_state_alloc(rp->part->type, ed); if (!pd) return EINA_FALSE; if (!rp->part->default_desc) { rp->part->default_desc = pd; } else { Edje_Part_Description_Common **tmp; tmp = realloc(rp->part->other.desc, sizeof (Edje_Part_Description_Common *) * (rp->part->other.desc_count + 1)); if (!tmp) { free(pd); return EINA_FALSE; } rp->part->other.desc = tmp; rp->part->other.desc[rp->part->other.desc_count++] = pd; } memset(pd, 0, sizeof (*pd)); pd->state.name = eina_stringshare_add(name); pd->state.value = value; pd->visible = 1; pd->align.x = 0.5; pd->align.y = 0.5; pd->min.w = 0; pd->min.h = 0; pd->fixed.w = 0; pd->fixed.h = 0; pd->max.w = -1; pd->max.h = -1; pd->rel1.relative_x = 0.0; pd->rel1.relative_y = 0.0; pd->rel1.offset_x = 0; pd->rel1.offset_y = 0; pd->rel1.id_x = -1; pd->rel1.id_y = -1; pd->rel2.relative_x = 1.0; pd->rel2.relative_y = 1.0; pd->rel2.offset_x = -1; pd->rel2.offset_y = -1; pd->rel2.id_x = -1; pd->rel2.id_y = -1; pd->color_class = NULL; pd->color.r = 255; pd->color.g = 255; pd->color.b = 255; pd->color.a = 255; pd->color2.r = 0; pd->color2.g = 0; pd->color2.b = 0; pd->color2.a = 255; pd->map.id_persp = -1; pd->map.id_light = -1; pd->map.rot.id_center = -1; pd->map.rot.x = FROM_DOUBLE(0.0); pd->map.rot.y = FROM_DOUBLE(0.0); pd->map.rot.z = FROM_DOUBLE(0.0); pd->map.colors = NULL; pd->map.on = EINA_FALSE; pd->map.smooth = EINA_TRUE; pd->map.alpha = EINA_TRUE; pd->map.backcull = EINA_FALSE; pd->map.persp_on = EINA_FALSE; pd->persp.zplane = EINA_FALSE; pd->persp.focal = 1000; 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*) pd; memset(&text->text, 0, sizeof (text->text)); text->text.color3.r = 0; text->text.color3.g = 0; text->text.color3.b = 0; text->text.color3.a = 128; text->text.align.x = 0.5; text->text.align.y = 0.5; text->text.id_source = -1; text->text.id_text_source = -1; } else if (rp->part->type == EDJE_PART_TYPE_IMAGE) { Edje_Part_Description_Image *img; img = (Edje_Part_Description_Image*) pd; memset(&img->image, 0, sizeof (img->image)); img->image.id = -1; img->image.fill.smooth = 1; img->image.fill.pos_rel_x = 0.0; img->image.fill.pos_abs_x = 0; img->image.fill.rel_x = 1.0; img->image.fill.abs_x = 0; img->image.fill.pos_rel_y = 0.0; img->image.fill.pos_abs_y = 0; img->image.fill.rel_y = 1.0; img->image.fill.abs_y = 0; img->image.fill.angle = 0; img->image.fill.spread = 0; img->image.fill.type = EDJE_FILL_TYPE_SCALE; } else if (rp->part->type == EDJE_PART_TYPE_PROXY) { Edje_Part_Description_Proxy *pro; pro = (Edje_Part_Description_Proxy*) pd; memset(&pro->proxy, 0, sizeof (pro->proxy)); pro->proxy.id = -1; pro->proxy.source_visible = EINA_TRUE; pro->proxy.source_clip = EINA_TRUE; pro->proxy.fill.smooth = 1; pro->proxy.fill.pos_rel_x = 0.0; pro->proxy.fill.pos_abs_x = 0; pro->proxy.fill.rel_x = 1.0; pro->proxy.fill.abs_x = 0; pro->proxy.fill.pos_rel_y = 0.0; pro->proxy.fill.pos_abs_y = 0; pro->proxy.fill.rel_y = 1.0; pro->proxy.fill.abs_y = 0; pro->proxy.fill.angle = 0; pro->proxy.fill.spread = 0; pro->proxy.fill.type = EDJE_FILL_TYPE_SCALE; } else if (rp->part->type == EDJE_PART_TYPE_EXTERNAL) { Edje_Part_Description_External *external; Edje_External_Param_Info *pi; external = (Edje_Part_Description_External*) pd; external->external_params = NULL; if (rp->part->source) { pi = (Edje_External_Param_Info *)edje_external_param_info_get(rp->part->source); while (pi && pi->name) { Edje_External_Param *p; p = _alloc(sizeof(Edje_External_Param)); /* error checking.. meh */ p->name = eina_stringshare_add(pi->name); p->type = pi->type; switch(p->type) { case EDJE_EXTERNAL_PARAM_TYPE_INT: case EDJE_EXTERNAL_PARAM_TYPE_BOOL: if (pi->info.i.def != EDJE_EXTERNAL_INT_UNSET) p->i = pi->info.i.def; break; case EDJE_EXTERNAL_PARAM_TYPE_DOUBLE: if (pi->info.d.def != EDJE_EXTERNAL_DOUBLE_UNSET) p->d = pi->info.d.def; break; case EDJE_EXTERNAL_PARAM_TYPE_CHOICE: if (pi->info.c.def) p->s = eina_stringshare_add(pi->info.c.def); break; case EDJE_EXTERNAL_PARAM_TYPE_STRING: if (pi->info.s.def) p->s = eina_stringshare_add(pi->info.s.def); break; default: ERR("unknown external parameter type '%d'", p->type); } external->external_params = eina_list_append(external->external_params, p); pi++; } if (external->external_params && rp->typedata.swallow) rp->param1.external_params = _edje_external_params_parse(rp->typedata.swallow->swallowed_object, external->external_params); } } else if (rp->part->type == EDJE_PART_TYPE_BOX) { Edje_Part_Description_Box *box; box = (Edje_Part_Description_Box*) pd; memset(&box->box, 0, sizeof (box->box)); } else if (rp->part->type == EDJE_PART_TYPE_TABLE) { Edje_Part_Description_Table *table; table = (Edje_Part_Description_Table*) pd; memset(&table->table, 0, sizeof (table->table)); } return EINA_TRUE; } EAPI Eina_Bool edje_edit_state_exist(Evas_Object *obj, const char *part, const char *state, double value) { GET_PD_OR_RETURN(EINA_FALSE); return EINA_TRUE; } static Eina_Bool _edje_edit_part_state_copy(Evas_Object *obj, const char *part, const char *part_to, const char *from, double val_from, const char *to, double val_to) { Edje_Part_Description_Common *pdfrom, *pdto; Edje_External_Param *p; Edje_Real_Part *rpto; GET_EED_OR_RETURN(EINA_FALSE); GET_RP_OR_RETURN(EINA_FALSE); pdfrom = _edje_part_description_find_byname(eed, part, from, val_from); if (!pdfrom) return EINA_FALSE; rpto = _edje_real_part_get(ed, part_to); if (!rpto) return EINA_FALSE; pdto = _edje_part_description_find_byname(eed, part_to, to, val_to); if (!pdto) { Edje_Part_Description_Common **tmp; pdto = _edje_edit_state_alloc(rpto->part->type, ed); if (!pdto) return EINA_FALSE; /* No need to check for default desc, at this point it must exist */ tmp = realloc(rpto->part->other.desc, sizeof (Edje_Part_Description_Common *) * (rpto->part->other.desc_count + 1)); if (!tmp) { free(pdto); return EINA_FALSE; } rpto->part->other.desc = tmp; rpto->part->other.desc[rpto->part->other.desc_count++] = pdto; } #define PD_STRING_COPY(To, From, _x) \ _edje_if_string_free(ed, To->_x); \ To->_x = (char *)eina_stringshare_add(From->_x); /* Copy all value */ *pdto = *pdfrom; /* Keeping the pdto state name and value */ pdto->state.name = eina_stringshare_add(to); pdto->state.value = val_to; /* Update pointer. */ PD_STRING_COPY(pdto, pdfrom, color_class); switch (rp->part->type) { case EDJE_PART_TYPE_PROXY: { Edje_Part_Description_Proxy *pro_to = (Edje_Part_Description_Proxy*) pdto; Edje_Part_Description_Proxy *pro_from = (Edje_Part_Description_Proxy*) pdfrom; pro_to->proxy = pro_from->proxy; break; } case EDJE_PART_TYPE_IMAGE: { Edje_Part_Description_Image *img_to = (Edje_Part_Description_Image*) pdto; Edje_Part_Description_Image *img_from = (Edje_Part_Description_Image*) pdfrom; unsigned int i; img_to->image = img_from->image; /* Update pointers. */ for (i = 0; i < img_to->image.tweens_count; ++i) free(img_to->image.tweens[i]); if (img_to->image.tweens_count > 0) free(img_to->image.tweens); img_to->image.tweens_count = img_from->image.tweens_count; img_to->image.tweens = calloc(img_to->image.tweens_count, sizeof (Edje_Part_Image_Id*)); if (!img_to->image.tweens) break; for (i = 0; i < img_to->image.tweens_count; ++i) { Edje_Part_Image_Id *new_i; new_i = _alloc(sizeof(Edje_Part_Image_Id)); if (!new_i) continue ; *new_i = *img_from->image.tweens[i]; img_to->image.tweens[i] = new_i; } break; } case EDJE_PART_TYPE_TEXT: case EDJE_PART_TYPE_TEXTBLOCK: { Edje_Part_Description_Text *text_to = (Edje_Part_Description_Text*) pdto; Edje_Part_Description_Text *text_from = (Edje_Part_Description_Text*) pdfrom; text_to->text = text_from->text; /* Update pointers. */ PD_STRING_COPY(text_to, text_from, text.text.str); PD_STRING_COPY(text_to, text_from, text.text_class); PD_STRING_COPY(text_to, text_from, text.style.str); PD_STRING_COPY(text_to, text_from, text.font.str); PD_STRING_COPY(text_to, text_from, text.repch.str); break; } case EDJE_PART_TYPE_BOX: { Edje_Part_Description_Box *box_to = (Edje_Part_Description_Box*) pdto; Edje_Part_Description_Box *box_from = (Edje_Part_Description_Box*) pdfrom; box_to->box = box_from->box; PD_STRING_COPY(box_to, box_from, box.layout); PD_STRING_COPY(box_to, box_from, box.alt_layout); break; } case EDJE_PART_TYPE_TABLE: { Edje_Part_Description_Table *table_to = (Edje_Part_Description_Table*) pdto; Edje_Part_Description_Table *table_from = (Edje_Part_Description_Table*) pdfrom; table_to->table = table_from->table; break; } case EDJE_PART_TYPE_EXTERNAL: { Edje_Part_Description_External *ext_to = (Edje_Part_Description_External*) pdto; Edje_Part_Description_External *ext_from = (Edje_Part_Description_External*) pdfrom; Eina_List *l; /* XXX: optimize this, most likely we don't need to remove and add */ EINA_LIST_FREE(ext_to->external_params, p) { _edje_if_string_free(ed, p->name); if (p->s) _edje_if_string_free(ed, p->s); free(p); } EINA_LIST_FOREACH(ext_from->external_params, l, p) { Edje_External_Param *new_p; new_p = _alloc(sizeof(Edje_External_Param)); new_p->name = eina_stringshare_add(p->name); new_p->type = p->type; switch (p->type) { case EDJE_EXTERNAL_PARAM_TYPE_INT: new_p->i = p->i; break; case EDJE_EXTERNAL_PARAM_TYPE_DOUBLE: new_p->d = p->d; break; case EDJE_EXTERNAL_PARAM_TYPE_CHOICE: case EDJE_EXTERNAL_PARAM_TYPE_STRING: new_p->s = eina_stringshare_add(p->s); break; default: break; } ext_to->external_params = eina_list_append(ext_to->external_params, new_p); } break; } } #undef PD_STRING_COPY return EINA_TRUE; } EAPI Eina_Bool edje_edit_state_copy(Evas_Object *obj, const char *part, const char *from, double val_from, const char *to, double val_to) { return _edje_edit_part_state_copy(obj, part, part, from, val_from, to, val_to); } #define FUNC_STATE_RELATIVE_DOUBLE(Sub, Value) \ EAPI double \ edje_edit_state_##Sub##_relative_##Value##_get(Evas_Object *obj, const char *part, const char *state, double value) \ { \ GET_PD_OR_RETURN(0); \ return TO_DOUBLE(pd->Sub.relative_##Value); \ } \ EAPI Eina_Bool \ edje_edit_state_##Sub##_relative_##Value##_set(Evas_Object *obj, const char *part, const char *state, double value, double v) \ { \ GET_PD_OR_RETURN(EINA_FALSE); \ pd->Sub.relative_##Value = FROM_DOUBLE(v); \ edje_object_calc_force(obj); \ return EINA_TRUE; \ } FUNC_STATE_RELATIVE_DOUBLE(rel1, x); FUNC_STATE_RELATIVE_DOUBLE(rel1, y); FUNC_STATE_RELATIVE_DOUBLE(rel2, x); FUNC_STATE_RELATIVE_DOUBLE(rel2, y); #define FUNC_STATE_OFFSET_INT(Sub, Value) \ EAPI int \ edje_edit_state_##Sub##_offset_##Value##_get(Evas_Object *obj, const char *part, const char *state, double value) \ { \ GET_PD_OR_RETURN(0); \ return pd->Sub.offset_##Value; \ } \ EAPI Eina_Bool \ edje_edit_state_##Sub##_offset_##Value##_set(Evas_Object *obj, const char *part, const char *state, double value, int v) \ { \ GET_PD_OR_RETURN(EINA_FALSE); \ pd->Sub.offset_##Value = v; \ edje_object_calc_force(obj); \ return EINA_TRUE; \ } FUNC_STATE_OFFSET_INT(rel1, x); FUNC_STATE_OFFSET_INT(rel1, y); FUNC_STATE_OFFSET_INT(rel2, x); FUNC_STATE_OFFSET_INT(rel2, y); #define FUNC_STATE_REL(Sub, Value) \ EAPI const char * \ edje_edit_state_##Sub##_to_##Value##_get(Evas_Object *obj, const char *part, const char *state, double value) \ { \ Edje_Real_Part *rel; \ GET_PD_OR_RETURN(NULL); \ if (pd->Sub.id_##Value == -1) return NULL; \ rel = ed->table_parts[pd->Sub.id_##Value % ed->table_parts_size]; \ if (rel->part->name) return eina_stringshare_add(rel->part->name); \ return NULL; \ } \ EAPI Eina_Bool \ edje_edit_state_##Sub##_to_##Value##_set(Evas_Object *obj, const char *part, const char *state, double value, const char *to) \ { \ Edje_Real_Part *relp; \ GET_PD_OR_RETURN(EINA_FALSE); \ if ((to) && (strcmp(to, ""))) \ { \ relp = _edje_real_part_get(ed, to); \ if (!relp) return EINA_FALSE; \ pd->Sub.id_##Value = relp->part->id; \ return EINA_TRUE; \ } \ else \ { \ pd->Sub.id_##Value = -1; \ return EINA_TRUE; \ } \ } //note after this call edje_edit_part_selected_state_set() to update !! need to fix this //_edje_part_description_apply(ed, rp, pd->state.name, pd->state.value, "state", 0.1); //Why segfault?? // edje_object_calc_force(obj);//don't work for redraw FUNC_STATE_REL(rel1, x); FUNC_STATE_REL(rel1, y); FUNC_STATE_REL(rel2, x); FUNC_STATE_REL(rel2, y); //colors #define FUNC_COLOR(Code) \ EAPI void \ edje_edit_state_##Code##_get(Evas_Object *obj, const char *part, const char *state, double value, int *r, int *g, int *b, int *a) \ { \ GET_PD_OR_RETURN(); \ \ if (r) *r = pd->Code.r; \ if (g) *g = pd->Code.g; \ if (b) *b = pd->Code.b; \ if (a) *a = pd->Code.a; \ } \ EAPI Eina_Bool \ edje_edit_state_##Code##_set(Evas_Object *obj, const char *part, const char *state, double value, int r, int g, int b, int a) \ { \ if ((!obj) || (!part) || (!state)) \ return EINA_FALSE; \ GET_PD_OR_RETURN(EINA_FALSE); \ \ if (r > -1 && r < 256) pd->Code.r = r; \ else return EINA_FALSE; \ if (g > -1 && g < 256) pd->Code.g = g; \ else return EINA_FALSE; \ if (b > -1 && b < 256) pd->Code.b = b; \ else return EINA_FALSE; \ if (a > -1 && a < 256) pd->Code.a = a; \ else return EINA_FALSE; \ \ edje_object_calc_force(obj); \ return EINA_TRUE; \ } FUNC_COLOR(color); FUNC_COLOR(color2); EAPI void edje_edit_state_color3_get(Evas_Object *obj, const char *part, const char *state, double value, int *r, int *g, int *b, int *a) { Edje_Part_Description_Text *txt; GET_PD_OR_RETURN(); if ((rp->part->type != EDJE_PART_TYPE_TEXT) && (rp->part->type != EDJE_PART_TYPE_TEXTBLOCK)) { if (r) *r = 0; if (g) *g = 0; if (b) *b = 0; if (a) *a = 0; return; } txt = (Edje_Part_Description_Text*) pd; if (r) *r = txt->text.color3.r; if (g) *g = txt->text.color3.g; if (b) *b = txt->text.color3.b; if (a) *a = txt->text.color3.a; } EAPI Eina_Bool edje_edit_state_color3_set(Evas_Object *obj, const char *part, const char *state, double value, int r, int g, int b, int a) { Edje_Part_Description_Text *txt; if ((!obj) || (!part) || (!state)) return EINA_FALSE; GET_PD_OR_RETURN(EINA_FALSE); if ((rp->part->type != EDJE_PART_TYPE_TEXT) && (rp->part->type != EDJE_PART_TYPE_TEXTBLOCK)) return EINA_FALSE; txt = (Edje_Part_Description_Text*) pd; if (r > -1 && r < 256) txt->text.color3.r = r; else return EINA_FALSE; if (g > -1 && g < 256) txt->text.color3.g = g; else return EINA_FALSE; if (b > -1 && b < 256) txt->text.color3.b = b; else return EINA_FALSE; if (a > -1 && a < 256) txt->text.color3.a = a; else return EINA_FALSE; edje_object_calc_force(obj); return EINA_TRUE; } #define FUNC_STATE_DOUBLE(Class, Value) \ EAPI double \ edje_edit_state_##Class##_##Value##_get(Evas_Object *obj, const char *part, const char *state, double value) \ { \ GET_PD_OR_RETURN(0); \ return TO_DOUBLE(pd->Class.Value); \ } \ EAPI Eina_Bool \ edje_edit_state_##Class##_##Value##_set(Evas_Object *obj, const char *part, const char *state, double value, double v) \ { \ GET_PD_OR_RETURN(EINA_FALSE); \ pd->Class.Value = FROM_DOUBLE(v); \ edje_object_calc_force(obj); \ return EINA_TRUE; \ } #define FUNC_STATE_INT(Class, Value, Min) \ EAPI int \ edje_edit_state_##Class##_##Value##_get(Evas_Object *obj, const char *part, const char *state, double value) \ { \ GET_PD_OR_RETURN(0); \ return pd->Class.Value; \ } \ EAPI Eina_Bool \ edje_edit_state_##Class##_##Value##_set(Evas_Object *obj, const char *part, const char *state, double value, int v) \ { \ if ((!obj) || (!part) || (!state)) \ return EINA_FALSE; \ if (v < Min) return EINA_FALSE; \ GET_PD_OR_RETURN(EINA_FALSE); \ pd->Class.Value = v; \ edje_object_calc_force(obj); \ return EINA_TRUE; \ } #define FUNC_STATE_BOOL(Class, Value) \ EAPI Eina_Bool \ edje_edit_state_##Class##_##Value##_get(Evas_Object *obj, const char *part, const char *state, double value) \ { \ GET_PD_OR_RETURN(0); \ return pd->Class.Value; \ } \ EAPI Eina_Bool \ edje_edit_state_##Class##_##Value##_set(Evas_Object *obj, const char *part, const char *state, double value, Eina_Bool v) \ { \ if ((!obj) || (!part) || (!state)) \ return EINA_FALSE; \ GET_PD_OR_RETURN(EINA_FALSE); \ pd->Class.Value = v; \ edje_object_calc_force(obj); \ return EINA_TRUE; \ } FUNC_STATE_DOUBLE(align, x); FUNC_STATE_DOUBLE(align, y); FUNC_STATE_INT(min, w, 0); FUNC_STATE_INT(min, h, 0); FUNC_STATE_INT(max, w, -1); FUNC_STATE_INT(max, h, -1); FUNC_STATE_BOOL(fixed, w); FUNC_STATE_BOOL(fixed, h); FUNC_STATE_DOUBLE(aspect, min); FUNC_STATE_DOUBLE(aspect, max); EAPI Eina_Bool edje_edit_state_fill_smooth_get(Evas_Object *obj, const char *part, const char *state, double value) { GET_PD_OR_RETURN(EINA_FALSE) switch (rp->part->type) { case EDJE_PART_TYPE_IMAGE: { Edje_Part_Description_Image *img; img = (Edje_Part_Description_Image*) pd; return img->image.fill.smooth; } case EDJE_PART_TYPE_PROXY: { Edje_Part_Description_Proxy *pro; pro = (Edje_Part_Description_Proxy*) pd; return pro->proxy.fill.smooth; } } return EINA_FALSE; } EAPI Eina_Bool edje_edit_state_fill_smooth_set(Evas_Object *obj, const char *part, const char *state, double value, Eina_Bool smooth) { GET_PD_OR_RETURN(EINA_FALSE) switch (rp->part->type) { case EDJE_PART_TYPE_IMAGE: { Edje_Part_Description_Image *img; img = (Edje_Part_Description_Image*) pd; img->image.fill.smooth = smooth; return EINA_TRUE; } case EDJE_PART_TYPE_PROXY: { Edje_Part_Description_Proxy *pro; pro = (Edje_Part_Description_Proxy*) pd; pro->proxy.fill.smooth = smooth; return EINA_TRUE; } } return EINA_FALSE; } #define FUNC_STATE_DOUBLE_FILL(Class, Type, Value) \ EAPI double \ edje_edit_state_fill_##Type##_relative_##Value##_get(Evas_Object *obj, const char *part, const char *state, double value) \ { \ GET_PD_OR_RETURN(0); \ \ switch (rp->part->type) \ { \ case EDJE_PART_TYPE_IMAGE: \ { \ Edje_Part_Description_Image *img; \ \ img = (Edje_Part_Description_Image*) pd; \ \ return TO_DOUBLE(img->image.fill.Class##rel_##Value); \ } \ case EDJE_PART_TYPE_PROXY: \ { \ Edje_Part_Description_Proxy *pro; \ \ pro = (Edje_Part_Description_Proxy*) pd; \ \ return TO_DOUBLE(pro->proxy.fill.Class##rel_##Value); \ } \ } \ \ return 0; \ } \ EAPI Eina_Bool \ edje_edit_state_fill_##Type##_relative_##Value##_set(Evas_Object *obj, const char *part, const char *state, double value, double v) \ { \ GET_PD_OR_RETURN(EINA_FALSE); \ \ switch (rp->part->type) \ { \ case EDJE_PART_TYPE_IMAGE: \ { \ Edje_Part_Description_Image *img; \ \ img = (Edje_Part_Description_Image*) pd; \ \ img->image.fill.Class##rel_##Value = FROM_DOUBLE(v); \ \ break; \ } \ case EDJE_PART_TYPE_PROXY: \ { \ Edje_Part_Description_Proxy *pro; \ \ pro = (Edje_Part_Description_Proxy*) pd; \ \ pro->proxy.fill.Class##rel_##Value = FROM_DOUBLE(v); \ \ break; \ } \ default: \ return EINA_FALSE; \ } \ \ edje_object_calc_force(obj); \ return EINA_TRUE; \ } #define FUNC_STATE_INT_FILL(Class, Type, Value) \ EAPI int \ edje_edit_state_fill_##Type##_offset_##Value##_get(Evas_Object *obj, const char *part, const char *state, double value) \ { \ GET_PD_OR_RETURN(0); \ \ switch (rp->part->type) \ { \ case EDJE_PART_TYPE_IMAGE: \ { \ Edje_Part_Description_Image *img; \ \ img = (Edje_Part_Description_Image*) pd; \ \ return img->image.fill.Class##abs_##Value; \ } \ case EDJE_PART_TYPE_PROXY: \ { \ Edje_Part_Description_Proxy *pro; \ \ pro = (Edje_Part_Description_Proxy*) pd; \ \ return pro->proxy.fill.Class##abs_##Value; \ } \ } \ return 0; \ } \ EAPI Eina_Bool \ edje_edit_state_fill_##Type##_offset_##Value##_set(Evas_Object *obj, const char *part, const char *state, double value, double v) \ { \ GET_PD_OR_RETURN(EINA_FALSE); \ \ switch (rp->part->type) \ { \ case EDJE_PART_TYPE_IMAGE: \ { \ Edje_Part_Description_Image *img; \ \ img = (Edje_Part_Description_Image*) pd; \ \ img->image.fill.Class##abs_##Value = FROM_DOUBLE(v); \ break; \ } \ case EDJE_PART_TYPE_PROXY: \ { \ Edje_Part_Description_Proxy *pro; \ \ pro = (Edje_Part_Description_Proxy*) pd; \ \ pro->proxy.fill.Class##abs_##Value = FROM_DOUBLE(v); \ break; \ } \ default: \ return EINA_FALSE; \ } \ \ edje_object_calc_force(obj); \ return EINA_TRUE; \ } FUNC_STATE_DOUBLE_FILL(pos_, origin, x); FUNC_STATE_DOUBLE_FILL(pos_, origin, y); FUNC_STATE_INT_FILL(pos_, origin, x); FUNC_STATE_INT_FILL(pos_, origin, y); FUNC_STATE_DOUBLE_FILL(, size, x); FUNC_STATE_DOUBLE_FILL(, size, y); FUNC_STATE_INT_FILL(, size, x); FUNC_STATE_INT_FILL(, size, y); EAPI Eina_Bool edje_edit_state_visible_get(Evas_Object *obj, const char *part, const char *state, double value) { GET_PD_OR_RETURN(EINA_FALSE); //printf("Get state visible flag of part: %s state: %s\n", part, state); return pd->visible; } EAPI Eina_Bool edje_edit_state_visible_set(Evas_Object *obj, const char *part, const char *state, double value, Eina_Bool visible) { if ((!obj) || (!part) || (!state)) return EINA_FALSE; GET_PD_OR_RETURN(EINA_FALSE); if (visible) pd->visible = 1; else pd->visible = 0; edje_object_calc_force(obj); return EINA_TRUE; } EAPI unsigned char edje_edit_state_aspect_pref_get(Evas_Object *obj, const char *part, const char *state, double value) { GET_PD_OR_RETURN(0); //printf("GET ASPECT_PREF of state '%s' [%d]\n", state, pd->aspect.prefer); return pd->aspect.prefer; } EAPI Eina_Bool edje_edit_state_aspect_pref_set(Evas_Object *obj, const char *part, const char *state, double value, unsigned char pref) { GET_PD_OR_RETURN(EINA_FALSE); if ((!pref) || (pref > 3)) return EINA_FALSE; pd->aspect.prefer = pref; return EINA_TRUE; } EAPI const char* edje_edit_state_color_class_get(Evas_Object *obj, const char *part, const char *state, double value) { GET_PD_OR_RETURN(NULL); //printf("Get ColorClass of part: %s state: %s\n", part, state); return eina_stringshare_add(pd->color_class); } EAPI Eina_Bool edje_edit_state_color_class_set(Evas_Object *obj, const char *part, const char *state, double value, const char *color_class) { Eina_List *l; Edje_Color_Class *cc; if ((!obj) || (!part) || (!state)) return EINA_FALSE; GET_PD_OR_RETURN(EINA_FALSE); if (!color_class) { pd->color_class = NULL; return EINA_FALSE; } if (!ed->file->color_classes) return EINA_FALSE; EINA_LIST_FOREACH(ed->file->color_classes, l, cc) { if (strcmp(cc->name, color_class) == 0) { pd->color.r = cc->r; pd->color.g = cc->g; pd->color.b = cc->b; pd->color.a = cc->a; pd->color2.r = cc->r2; pd->color2.g = cc->g2; pd->color2.b = cc->b2; pd->color2.a = cc->a2; if ((rp->type == EDJE_PART_TYPE_TEXT) || (rp->type == EDJE_PART_TYPE_TEXTBLOCK)) { Edje_Part_Description_Text *txt = (Edje_Part_Description_Text *)pd; txt->text.color3.r = cc->r3; txt->text.color3.g = cc->g3; txt->text.color3.b = cc->b3; txt->text.color3.a = cc->a3; } pd->color_class = (char *)eina_stringshare_add(color_class); edje_object_calc_force(obj); return EINA_TRUE; } } pd->color_class = NULL; return EINA_FALSE; } EAPI const Eina_List * edje_edit_state_external_params_list_get(Evas_Object *obj, const char *part, const char *state, double value) { Edje_Part_Description_External *external; GET_PD_OR_RETURN(NULL); if (rp->part->type != EDJE_PART_TYPE_EXTERNAL) return NULL; external = (Edje_Part_Description_External *) pd; return external->external_params; } EAPI Eina_Bool edje_edit_state_external_param_get(Evas_Object *obj, const char *part, const char *state, double value, const char *param, Edje_External_Param_Type *type, void **val) { Edje_Part_Description_External *external; Edje_External_Param *p; Eina_List *l; GET_PD_OR_RETURN(EINA_FALSE); if (rp->part->type != EDJE_PART_TYPE_EXTERNAL) return EINA_FALSE; if (!param) return EINA_FALSE; external = (Edje_Part_Description_External *) pd; EINA_LIST_FOREACH(external->external_params, l, p) if (!strcmp(p->name, param)) { if (type) *type = p->type; if (val) switch (p->type) { case EDJE_EXTERNAL_PARAM_TYPE_INT: case EDJE_EXTERNAL_PARAM_TYPE_BOOL: *val = &p->i; break; case EDJE_EXTERNAL_PARAM_TYPE_DOUBLE: *val = &p->d; break; case EDJE_EXTERNAL_PARAM_TYPE_CHOICE: case EDJE_EXTERNAL_PARAM_TYPE_STRING: *val = (void *)p->s; break; default: ERR("unknown external parameter type '%d'", p->type); } return EINA_TRUE; } return EINA_FALSE; } EAPI Eina_Bool edje_edit_state_external_param_int_get(Evas_Object *obj, const char *part, const char *state, double value, const char *param, int *val) { Edje_Part_Description_External *external; Edje_External_Param *p; Eina_List *l; GET_PD_OR_RETURN(EINA_FALSE); if (rp->part->type != EDJE_PART_TYPE_EXTERNAL) { if (val) *val = 0; return EINA_FALSE; } if (!param) return EINA_FALSE; external = (Edje_Part_Description_External *) pd; EINA_LIST_FOREACH(external->external_params, l, p) if (!strcmp(p->name, param)) { if (p->type != EDJE_EXTERNAL_PARAM_TYPE_INT) return EINA_FALSE; if (val) *val = p->i; return EINA_TRUE; } return EINA_FALSE; } EAPI Eina_Bool edje_edit_state_external_param_bool_get(Evas_Object *obj, const char *part, const char *state, double value, const char *param, Eina_Bool *val) { Edje_Part_Description_External *external; Edje_External_Param *p; Eina_List *l; GET_PD_OR_RETURN(EINA_FALSE); if (rp->part->type != EDJE_PART_TYPE_EXTERNAL) { if (val) *val = 0; return EINA_FALSE; } if (!param) return EINA_FALSE; external = (Edje_Part_Description_External *) pd; EINA_LIST_FOREACH(external->external_params, l, p) if (!strcmp(p->name, param)) { if (p->type != EDJE_EXTERNAL_PARAM_TYPE_BOOL) return EINA_FALSE; if (val) *val = p->i; return EINA_TRUE; } return EINA_FALSE; } EAPI Eina_Bool edje_edit_state_external_param_double_get(Evas_Object *obj, const char *part, const char *state, double value, const char *param, double *val) { Edje_Part_Description_External *external; Edje_External_Param *p; Eina_List *l; GET_PD_OR_RETURN(EINA_FALSE); if (rp->part->type != EDJE_PART_TYPE_EXTERNAL) { if (val) *val = 0; return EINA_FALSE; } if (!param) return EINA_FALSE; external = (Edje_Part_Description_External *) pd; EINA_LIST_FOREACH(external->external_params, l, p) if (!strcmp(p->name, param)) { if (p->type != EDJE_EXTERNAL_PARAM_TYPE_DOUBLE) return EINA_FALSE; if (val) *val = p->d; return EINA_TRUE; } return EINA_FALSE; } EAPI Eina_Bool edje_edit_state_external_param_string_get(Evas_Object *obj, const char *part, const char *state, double value, const char *param, const char **val) { Edje_Part_Description_External *external; Edje_External_Param *p; Eina_List *l; GET_PD_OR_RETURN(EINA_FALSE); if (rp->part->type != EDJE_PART_TYPE_EXTERNAL) { if (val) *val = NULL; return EINA_FALSE; } if (!param) return EINA_FALSE; external = (Edje_Part_Description_External *) pd; EINA_LIST_FOREACH(external->external_params, l, p) if (!strcmp(p->name, param)) { if (p->type != EDJE_EXTERNAL_PARAM_TYPE_STRING) return EINA_FALSE; if (val) *val = p->s; return EINA_TRUE; } return EINA_FALSE; } EAPI Eina_Bool edje_edit_state_external_param_choice_get(Evas_Object *obj, const char *part, const char *state, double value, const char *param, const char **val) { Edje_Part_Description_External *external; Edje_External_Param *p; Eina_List *l; GET_PD_OR_RETURN(EINA_FALSE); if (rp->part->type != EDJE_PART_TYPE_EXTERNAL) { if (val) *val = NULL; return EINA_FALSE; } if (!param) return EINA_FALSE; external = (Edje_Part_Description_External *) pd; EINA_LIST_FOREACH(external->external_params, l, p) if (!strcmp(p->name, param)) { if (p->type != EDJE_EXTERNAL_PARAM_TYPE_CHOICE) return EINA_FALSE; if (val) *val = p->s; return EINA_TRUE; } return EINA_FALSE; } EAPI Eina_Bool edje_edit_state_external_param_set(Evas_Object *obj, const char *part, const char *state, double value, const char *param, Edje_External_Param_Type type, ...) { va_list ap; Eina_List *l; Edje_Part_Description_External *external; Edje_External_Param *p = NULL, old_p = { 0, 0, 0, 0, 0 }; int found = 0; GET_PD_OR_RETURN(EINA_FALSE); if (rp->part->type != EDJE_PART_TYPE_EXTERNAL) return EINA_FALSE; if (!param) return EINA_FALSE; external = (Edje_Part_Description_External *) pd; va_start(ap, type); EINA_LIST_FOREACH(external->external_params, l, p) if (!strcmp(p->name, param)) { found = 1; old_p = *p; break; } if (!found) { p = _alloc(sizeof(Edje_External_Param)); if (!p) { va_end(ap); return EINA_FALSE; } p->name = eina_stringshare_add(param); } p->type = type; p->i = 0; p->d = 0; _edje_if_string_free(ed, p->s); p->s = NULL; switch (type) { case EDJE_EXTERNAL_PARAM_TYPE_INT: case EDJE_EXTERNAL_PARAM_TYPE_BOOL: p->i = (int)va_arg(ap, int); break; case EDJE_EXTERNAL_PARAM_TYPE_DOUBLE: p->d = (double)va_arg(ap, double); break; case EDJE_EXTERNAL_PARAM_TYPE_CHOICE: case EDJE_EXTERNAL_PARAM_TYPE_STRING: p->s = eina_stringshare_add((const char *)va_arg(ap, char *)); break; default: ERR("unknown external parameter type '%d'", type); va_end(ap); if (!found) free(p); else *p = old_p; return EINA_FALSE; } va_end(ap); //FIXME: //For now, we're just setting the value if the state is the selected state. //This is a conceptual error and is incoherent with the rest of the API! { const char *sname; double svalue; sname = edje_edit_part_selected_state_get(obj, part, &svalue); if (!strcmp(state, sname) && svalue == value) if (!edje_object_part_external_param_set(obj, part, p)) if ((type == EDJE_EXTERNAL_PARAM_TYPE_CHOICE) || (type == EDJE_EXTERNAL_PARAM_TYPE_STRING)) { _edje_if_string_free(ed, p->s); if (!found) free(p); else *p = old_p; eina_stringshare_del(sname); return EINA_FALSE; } eina_stringshare_del(sname); } if (!found) { external->external_params = eina_list_append(external->external_params, p); } if (rp->typedata.swallow && rp->param1.external_params) _edje_external_parsed_params_free(rp->typedata.swallow->swallowed_object, rp->param1.external_params); if (rp->typedata.swallow && external->external_params) rp->param1.external_params = \ _edje_external_params_parse(rp->typedata.swallow->swallowed_object, external->external_params); return EINA_TRUE; } EAPI Eina_Bool edje_edit_state_external_param_int_set(Evas_Object *obj, const char *part, const char *state, double value, const char *param, int val) { return edje_edit_state_external_param_set(obj, part, state, value, param, EDJE_EXTERNAL_PARAM_TYPE_INT, val); } EAPI Eina_Bool edje_edit_state_external_param_bool_set(Evas_Object *obj, const char *part, const char *state, double value, const char *param, Eina_Bool val) { return edje_edit_state_external_param_set(obj, part, state, value, param, EDJE_EXTERNAL_PARAM_TYPE_BOOL, (int)val); } EAPI Eina_Bool edje_edit_state_external_param_double_set(Evas_Object *obj, const char *part, const char *state, double value, const char *param, double val) { return edje_edit_state_external_param_set(obj, part, state, value, param, EDJE_EXTERNAL_PARAM_TYPE_DOUBLE, val); } EAPI Eina_Bool edje_edit_state_external_param_string_set(Evas_Object *obj, const char *part, const char *state, double value, const char *param, const char *val) { return edje_edit_state_external_param_set(obj, part, state, value, param, EDJE_EXTERNAL_PARAM_TYPE_STRING, val); } EAPI Eina_Bool edje_edit_state_external_param_choice_set(Evas_Object *obj, const char *part, const char *state, double value, const char *param, const char *val) { return edje_edit_state_external_param_set(obj, part, state, value, param, EDJE_EXTERNAL_PARAM_TYPE_CHOICE, val); } /**************/ /* TEXT API */ /**************/ EAPI const char * edje_edit_state_text_get(Evas_Object *obj, const char *part, const char *state, double value) { Edje_Part_Description_Text *txt; GET_PD_OR_RETURN(NULL); if ((rp->part->type != EDJE_PART_TYPE_TEXT) && (rp->part->type != EDJE_PART_TYPE_TEXTBLOCK)) return NULL; txt = (Edje_Part_Description_Text *) pd; return eina_stringshare_add(edje_string_get(&txt->text.text)); } EAPI Eina_Bool edje_edit_state_text_set(Evas_Object *obj, const char *part, const char *state, double value, const char *text) { Edje_Part_Description_Text *txt; if ((!obj) || (!part) || (!state) || (!text)) return EINA_FALSE; GET_PD_OR_RETURN(EINA_FALSE); if ((rp->part->type != EDJE_PART_TYPE_TEXT) && (rp->part->type != EDJE_PART_TYPE_TEXTBLOCK)) return EINA_FALSE; txt = (Edje_Part_Description_Text *) pd; _edje_if_string_free(ed, txt->text.text.str); txt->text.text.str = (char *)eina_stringshare_add(text); txt->text.text.id = 0; edje_object_calc_force(obj); return EINA_TRUE; } EAPI int edje_edit_state_text_size_get(Evas_Object *obj, const char *part, const char *state, double value) { Edje_Part_Description_Text *txt; GET_PD_OR_RETURN(-1); if ((rp->part->type != EDJE_PART_TYPE_TEXT) && (rp->part->type != EDJE_PART_TYPE_TEXTBLOCK)) return -1; txt = (Edje_Part_Description_Text *) pd; return txt->text.size; } EAPI Eina_Bool edje_edit_state_text_size_set(Evas_Object *obj, const char *part, const char *state, double value, int size) { Edje_Part_Description_Text *txt; if ((!obj) || (!part) || (!state)) return EINA_FALSE; if (size < 0) return EINA_FALSE; GET_PD_OR_RETURN(EINA_FALSE); if ((rp->part->type != EDJE_PART_TYPE_TEXT) && (rp->part->type != EDJE_PART_TYPE_TEXTBLOCK)) return EINA_FALSE; txt = (Edje_Part_Description_Text *) pd; txt->text.size = size; edje_object_calc_force(obj); return EINA_TRUE; } #define FUNC_TEXT_DOUBLE(Name, Value, Min) \ EAPI double \ edje_edit_state_text_##Name##_get(Evas_Object *obj, const char *part, const char *state, double value) \ { \ Edje_Part_Description_Text *txt; \ \ GET_PD_OR_RETURN(0); \ \ if ((rp->part->type != EDJE_PART_TYPE_TEXT) && \ (rp->part->type != EDJE_PART_TYPE_TEXTBLOCK)) \ return 0; \ \ txt = (Edje_Part_Description_Text *) pd; \ return TO_DOUBLE(txt->text.Value); \ } \ EAPI Eina_Bool \ edje_edit_state_text_##Name##_set(Evas_Object *obj, const char *part, const char *state, double value, double v) \ { \ Edje_Part_Description_Text *txt; \ if ((!obj) || (!part) || (!state)) \ return EINA_FALSE; \ if ((v < Min) || (v > 1.0)) \ return EINA_FALSE; \ \ GET_PD_OR_RETURN(EINA_FALSE); \ \ if ((rp->part->type != EDJE_PART_TYPE_TEXT) && \ (rp->part->type != EDJE_PART_TYPE_TEXTBLOCK)) \ return EINA_FALSE; \ \ txt = (Edje_Part_Description_Text *) pd; \ txt->text.Value = FROM_DOUBLE(v); \ edje_object_calc_force(obj); \ return EINA_TRUE; \ } FUNC_TEXT_DOUBLE(align_x, align.x, -1.0); FUNC_TEXT_DOUBLE(align_y, align.y, 0.0); FUNC_TEXT_DOUBLE(elipsis, ellipsis, -1.0); #define FUNC_TEXT_BOOL(Name, Type) \ EAPI Eina_Bool \ edje_edit_state_text_##Name##_##Type##_get(Evas_Object *obj, const char *part, const char *state, double value) \ { \ Edje_Part_Description_Text *txt; \ \ GET_PD_OR_RETURN(EINA_FALSE); \ \ if ((rp->part->type != EDJE_PART_TYPE_TEXT) && \ (rp->part->type != EDJE_PART_TYPE_TEXTBLOCK)) \ return EINA_FALSE; \ \ txt = (Edje_Part_Description_Text *) pd; \ return txt->text.Name##_##Type; \ } \ EAPI Eina_Bool \ edje_edit_state_text_##Name##_##Type##_set(Evas_Object *obj, const char *part, const char *state, double value, Eina_Bool v) \ { \ Edje_Part_Description_Text *txt; \ if ((!obj) || (!part) || (!state)) \ return EINA_FALSE; \ GET_PD_OR_RETURN(EINA_FALSE); \ \ if ((rp->part->type != EDJE_PART_TYPE_TEXT) && \ (rp->part->type != EDJE_PART_TYPE_TEXTBLOCK)) \ return EINA_FALSE; \ \ txt = (Edje_Part_Description_Text *) pd; \ txt->text.Name##_##Type = v ? 1 : 0; \ edje_object_calc_force(obj); \ return EINA_TRUE; \ } FUNC_TEXT_BOOL(fit, x); FUNC_TEXT_BOOL(fit, y); FUNC_TEXT_BOOL(min, x); FUNC_TEXT_BOOL(min, y); FUNC_TEXT_BOOL(max, x); FUNC_TEXT_BOOL(max, y); EAPI const char * edje_edit_state_text_style_get(Evas_Object *obj, const char *part, const char *state, double value) { Edje_Part_Description_Text *txt; GET_PD_OR_RETURN(NULL); if ((rp->part->type != EDJE_PART_TYPE_TEXT) && (rp->part->type != EDJE_PART_TYPE_TEXTBLOCK)) return NULL; txt = (Edje_Part_Description_Text *)pd; return eina_stringshare_add(txt->text.style.str); } EAPI Eina_Bool edje_edit_state_text_style_set(Evas_Object *obj, const char *part, const char *state, double value, const char *style) { Edje_Part_Description_Text *txt; GET_PD_OR_RETURN(EINA_FALSE); if (!style) return EINA_FALSE; if ((rp->part->type != EDJE_PART_TYPE_TEXT) && (rp->part->type != EDJE_PART_TYPE_TEXTBLOCK)) return EINA_FALSE; txt = (Edje_Part_Description_Text *)pd; txt->text.style.str = eina_stringshare_add(style); edje_object_calc_force(obj); return EINA_TRUE; } EAPI Eina_List * edje_edit_fonts_list_get(Evas_Object *obj) { Eina_Iterator *it; Eina_List *fonts = NULL; Edje_Font_Directory_Entry *f; GET_ED_OR_RETURN(NULL); if (!ed->file || !ed->file->fonts) return NULL; it = eina_hash_iterator_data_new(ed->file->fonts); if (!it) return NULL; EINA_ITERATOR_FOREACH(it, f) fonts = eina_list_append(fonts, eina_stringshare_add(f->entry)); eina_iterator_free(it); return fonts; } EAPI Eina_Bool edje_edit_font_add(Evas_Object *obj, const char* path, const char* alias) { char entry[PATH_MAX]; char *new_path; struct stat st; Edje_Font_Directory_Entry *fnt; GET_ED_OR_RETURN(EINA_FALSE); INF("ADD FONT: %s", path); if (!path) return EINA_FALSE; if (stat(path, &st) || !S_ISREG(st.st_mode)) return EINA_FALSE; if (!ed->file) return EINA_FALSE; if (!ed->path) return EINA_FALSE; /* Alias */ if (alias) { if ((new_path = strrchr(path, '/'))) new_path ++; else new_path = (char *)path; } else { if ((alias = strrchr(path, '/'))) alias ++; else alias = (char *)path; new_path = (char *)alias; } snprintf(entry, sizeof(entry), "edje/fonts/%s", alias); /* Initializing a new font hash, if no exist */ if (!ed->file->fonts) { ed->file->fonts = eina_hash_string_small_new(NULL); if (!ed->file->fonts) return EINA_FALSE; } /* Check if exists */ fnt = eina_hash_find(ed->file->fonts, alias); if (fnt) return EINA_FALSE; /* Create Edje_Font_Directory_Entry */ fnt = _alloc(sizeof(Edje_Font_Directory_Entry)); if (!fnt) { ERR("Unable to alloc font entry part \"%s\"", alias); return EINA_FALSE; } fnt->file = eina_stringshare_add(new_path); fnt->entry = eina_stringshare_add(alias); eina_hash_direct_add(ed->file->fonts, fnt->entry, fnt); /* Import font */ if (!_edje_import_font_file(ed, path, entry)) { eina_hash_del(ed->file->fonts, fnt->entry, fnt); eina_stringshare_del(fnt->file); eina_stringshare_del(fnt->entry); return EINA_FALSE; } return EINA_TRUE; } EAPI Eina_Bool edje_edit_font_del(Evas_Object *obj, const char* alias) { Edje_Font_Directory_Entry *fnt; GET_ED_OR_RETURN(EINA_FALSE); INF("DEL FONT: %s", alias); if (!alias) return EINA_FALSE; if (!ed->file) return EINA_FALSE; if (!ed->path) return EINA_FALSE; fnt = eina_hash_find(ed->file->fonts, alias); if (!fnt) { WRN("Unable to find font entry part \"%s\"", alias); return EINA_FALSE; } /* Erase font to edje file */ { char entry[PATH_MAX]; Eet_File *eetf; /* 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; } snprintf(entry, sizeof(entry), "edje/fonts/%s", alias); if (eet_delete(eetf, entry) <= 0) { ERR("Unable to delete \"%s\" font entry", entry); eet_close(eetf); return EINA_FALSE; } /* write the edje_file */ if (!_edje_edit_edje_file_save(eetf, ed->file)) { eet_close(eetf); return EINA_FALSE; } eet_close(eetf); } eina_hash_del(ed->file->fonts, alias, fnt); return EINA_TRUE; } EAPI const char * edje_edit_font_path_get(Evas_Object *obj, const char *alias) { Eina_Iterator *it; Edje_Font_Directory_Entry *f; const char *str = NULL; if (!alias) return NULL; GET_ED_OR_RETURN(NULL); if (!ed->file || !ed->file->fonts) return NULL; it = eina_hash_iterator_data_new(ed->file->fonts); if (!it) return NULL; EINA_ITERATOR_FOREACH(it, f) if (!strcmp(f->entry, alias)) { str = f->file; break; } eina_iterator_free(it); return eina_stringshare_add(str); } EAPI const char * edje_edit_state_font_get(Evas_Object *obj, const char *part, const char *state, double value) { Edje_Part_Description_Text *txt; GET_PD_OR_RETURN(NULL); if ((rp->part->type != EDJE_PART_TYPE_TEXT) && (rp->part->type != EDJE_PART_TYPE_TEXTBLOCK)) return NULL; txt = (Edje_Part_Description_Text*) pd; return eina_stringshare_add(edje_string_get(&txt->text.font)); } EAPI Eina_Bool edje_edit_state_font_set(Evas_Object *obj, const char *part, const char *state, double value, const char *font) { Edje_Part_Description_Text *txt; if ((!obj) || (!part) || (!state)) return EINA_FALSE; GET_PD_OR_RETURN(EINA_FALSE); if ((rp->part->type != EDJE_PART_TYPE_TEXT) && (rp->part->type != EDJE_PART_TYPE_TEXTBLOCK)) return EINA_FALSE; txt = (Edje_Part_Description_Text*) pd; _edje_if_string_free(ed, txt->text.font.str); txt->text.font.str = (char *)eina_stringshare_add(font); txt->text.font.id = 0; edje_object_calc_force(obj); return EINA_TRUE; } EAPI Edje_Text_Effect edje_edit_part_effect_get(Evas_Object *obj, const char *part) { GET_RP_OR_RETURN(0); //printf("GET EFFECT of part: %s\n", part); return rp->part->effect; } EAPI Eina_Bool edje_edit_part_effect_set(Evas_Object *obj, const char *part, Edje_Text_Effect effect) { if ((!obj) || (!part)) return EINA_FALSE; GET_RP_OR_RETURN(EINA_FALSE); if ((rp->part->type != EDJE_PART_TYPE_TEXT) && (rp->part->type != EDJE_PART_TYPE_TEXTBLOCK)) return EINA_FALSE; rp->part->effect = effect; edje_object_calc_force(obj); return EINA_TRUE; } EAPI const char * edje_edit_state_text_source_get(Evas_Object *obj, const char *part, const char *state, double value) { Edje_Real_Part *rel; GET_PD_OR_RETURN(NULL); if ((rp->part->type == EDJE_PART_TYPE_TEXT) || (rp->part->type == EDJE_PART_TYPE_TEXTBLOCK)) { Edje_Part_Description_Text *txt; txt = (Edje_Part_Description_Text *) pd; if (txt->text.id_text_source == -1) return NULL; rel = ed->table_parts[txt->text.id_text_source % ed->table_parts_size]; if (rel->part->name) return eina_stringshare_add(rel->part->name); } return NULL; } EAPI Eina_Bool edje_edit_state_text_source_set(Evas_Object *obj, const char *part, const char *state, double value, const char *source) { Edje_Part_Description_Text *txt; int id_text_source; GET_PD_OR_RETURN(EINA_FALSE); if (!source) return EINA_FALSE; if ((rp->part->type != EDJE_PART_TYPE_TEXT) || (rp->part->type != EDJE_PART_TYPE_TEXTBLOCK)) return EINA_FALSE; txt = (Edje_Part_Description_Text *) pd; id_text_source = _edje_part_id_find(ed, source); txt->text.id_text_source = id_text_source; /* need to recalc, because the source part can has a text */ edje_object_calc_force(obj); return EINA_TRUE; } /****************/ /* IMAGES API */ /****************/ EAPI Eina_List * edje_edit_images_list_get(Evas_Object *obj) { Eina_List *images = NULL; unsigned int i; GET_ED_OR_RETURN(NULL); if (!ed->file) return NULL; if (!ed->file->image_dir) return NULL; //printf("GET IMAGES LIST for %s\n", ed->file->path); for (i = 0; i < ed->file->image_dir->entries_count; ++i) images = eina_list_append(images, eina_stringshare_add(ed->file->image_dir->entries[i].entry)); return images; } EAPI Eina_Bool edje_edit_image_add(Evas_Object *obj, const char* path) { Edje_Image_Directory_Entry *de; unsigned int i; int free_id = -1; char *name; GET_ED_OR_RETURN(EINA_FALSE); if (!path) return EINA_FALSE; if (!ed->file) return EINA_FALSE; if (!ed->path) return EINA_FALSE; /* Create Image_Directory if not exist */ if (!ed->file->image_dir) { ed->file->image_dir = _alloc(sizeof(Edje_Image_Directory)); if (!ed->file->image_dir) return EINA_FALSE; } /* Image name */ if ((name = strrchr(path, '/'))) name++; else name = (char *)path; /* Loop trough image directory to find if image exist */ for (i = 0; i < ed->file->image_dir->entries_count; ++i) { de = ed->file->image_dir->entries + i; if (!de->entry) free_id = i; else if (!strcmp(name, de->entry)) return EINA_FALSE; } if (free_id == -1) { Edje_Image_Directory_Entry *tmp; unsigned int count; count = ed->file->image_dir->entries_count + 1; tmp = realloc(ed->file->image_dir->entries, sizeof (Edje_Image_Directory_Entry) * count); if (!tmp) return EINA_FALSE; ed->file->image_dir->entries = tmp; free_id = ed->file->image_dir->entries_count; ed->file->image_dir->entries_count = count; } /* Set Image Entry */ de = ed->file->image_dir->entries + free_id; de->entry = eina_stringshare_add(name); de->id = free_id; de->source_type = 1; de->source_param = 1; /* Import image */ if (!_edje_import_image_file(ed, path, free_id)) { eina_stringshare_del(de->entry); de->entry = NULL; return EINA_FALSE; } 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) { 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 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, *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); if (!name) return EINA_FALSE; 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; 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; } snprintf(entry, sizeof(entry), "edje/images/%i", de->id); if (eet_delete(eetf, entry) <= 0) { ERR("Unable to delete \"%s\" font entry", entry); 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); } _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) { 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.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); /* write the edje_file */ if (!_edje_edit_edje_file_save(eetf, ed->file)) { eet_close(eetf); return EINA_FALSE; } eet_close(eetf); } _edje_edit_flag_script_dirty(eed, EINA_TRUE); return EINA_TRUE; invalid_image: WRN("Unable to find image entry part \"%s\"", name); return EINA_FALSE; } EAPI Eina_Bool edje_edit_image_data_add(Evas_Object *obj, const char *name, int id) { Edje_Image_Directory_Entry *de; GET_ED_OR_RETURN(EINA_FALSE); if (!name) return EINA_FALSE; if (!ed->file) return EINA_FALSE; if (!ed->path) return EINA_FALSE; /* Create Image_Directory if not exist */ if (!ed->file->image_dir) { ed->file->image_dir = _alloc(sizeof(Edje_Image_Directory)); if (!ed->file->image_dir) return EINA_FALSE; } /* Loop trough image directory to find if image exist */ if (id < 0) id = - id - 1; if ((unsigned int) id >= ed->file->image_dir->entries_count) return EINA_FALSE; de = ed->file->image_dir->entries + id; _edje_if_string_free(ed, de->entry); de->entry = eina_stringshare_add(name); de->source_type = 1; de->source_param = 1; return EINA_TRUE; } EAPI int edje_edit_image_id_get(Evas_Object *obj, const char *image_name) { GET_EED_OR_RETURN(-1); return _edje_image_id_find(eed, image_name); } EAPI Edje_Edit_Image_Comp edje_edit_image_compression_type_get(Evas_Object *obj, const char *image) { Edje_Image_Directory_Entry *de = NULL; unsigned int i; GET_ED_OR_RETURN(-1); if (!ed->file) return -1; if (!ed->file->image_dir) return -1; for (i = 0; i < ed->file->image_dir->entries_count; ++i) { de = ed->file->image_dir->entries + i; if (de->entry && !strcmp(image, de->entry)) break; } if (i == ed->file->image_dir->entries_count) return -1; switch(de->source_type) { case EDJE_IMAGE_SOURCE_TYPE_INLINE_PERFECT: if (de->source_param == 0) // RAW return EDJE_EDIT_IMAGE_COMP_RAW; else // COMP return EDJE_EDIT_IMAGE_COMP_COMP; case EDJE_IMAGE_SOURCE_TYPE_INLINE_LOSSY: // LOSSY return EDJE_EDIT_IMAGE_COMP_LOSSY; case EDJE_IMAGE_SOURCE_TYPE_INLINE_LOSSY_ETC1: // LOSSY_ETC1 return EDJE_EDIT_IMAGE_COMP_LOSSY_ETC1; case EDJE_IMAGE_SOURCE_TYPE_EXTERNAL: // USER return EDJE_EDIT_IMAGE_COMP_USER; } return -1; } EAPI Eina_Bool edje_edit_image_compression_type_set(Evas_Object *obj, const char *image, Edje_Edit_Image_Comp ic) { Edje_Image_Directory_Entry *de = NULL; unsigned int i; GET_ED_OR_RETURN(EINA_FALSE); if (!ed->file) return EINA_FALSE; if (!ed->file->image_dir) return EINA_FALSE; for (i = 0; i < ed->file->image_dir->entries_count; ++i) { de = ed->file->image_dir->entries + i; if ((de->entry) && (!strcmp(image, de->entry))) break; } if (i == ed->file->image_dir->entries_count) return EINA_FALSE; switch(ic) { case EDJE_EDIT_IMAGE_COMP_RAW: // RAW if (de->source_param == 0) { de->source_type = EDJE_IMAGE_SOURCE_TYPE_INLINE_PERFECT; return EINA_TRUE; } else return EINA_FALSE; case EDJE_EDIT_IMAGE_COMP_COMP: // COMP if (de->source_param == 1) { de->source_type = EDJE_IMAGE_SOURCE_TYPE_INLINE_PERFECT; return EINA_TRUE; } else return EINA_FALSE; case EDJE_EDIT_IMAGE_COMP_LOSSY: // LOSSY { de->source_type = EDJE_IMAGE_SOURCE_TYPE_INLINE_LOSSY; return EINA_TRUE; } case EDJE_EDIT_IMAGE_COMP_LOSSY_ETC1: // LOSSY_ETC1 { de->source_type = EDJE_IMAGE_SOURCE_TYPE_INLINE_LOSSY_ETC1; return EINA_TRUE; } case EDJE_EDIT_IMAGE_COMP_USER: // USER { de->source_type = EDJE_IMAGE_SOURCE_TYPE_EXTERNAL; return EINA_TRUE; } } return EINA_FALSE; } EAPI int edje_edit_image_compression_rate_get(Evas_Object *obj, const char *image) { Edje_Image_Directory_Entry *de; unsigned int i; GET_ED_OR_RETURN(-1); // Gets the Image Entry for (i = 0; i < ed->file->image_dir->entries_count; ++i) { de = ed->file->image_dir->entries + i; if (de->entry && !strcmp(de->entry, image)) break; } if (i == ed->file->image_dir->entries_count) return -1; if ((de->source_type != EDJE_IMAGE_SOURCE_TYPE_INLINE_LOSSY) && (de->source_type != EDJE_IMAGE_SOURCE_TYPE_INLINE_LOSSY_ETC1)) return -2; return de->source_param; } EAPI const char * edje_edit_state_image_get(Evas_Object *obj, const char *part, const char *state, double value) { Edje_Part_Description_Image *img; const char *image; GET_PD_OR_RETURN(NULL); if (rp->part->type != EDJE_PART_TYPE_IMAGE) return NULL; img = (Edje_Part_Description_Image *) pd; image = _edje_image_name_find(eed, img->image.id); if (!image) return NULL; //printf("GET IMAGE for %s [%s]\n", state, image); return eina_stringshare_add(image); } EAPI Eina_Bool edje_edit_state_image_set(Evas_Object *obj, const char *part, const char *state, double value, const char *image) { Edje_Part_Description_Image *img; int id; if ((!obj) || (!part) || (!state) || (!image)) return EINA_FALSE; eina_error_set(0); GET_PD_OR_RETURN(EINA_FALSE); if (rp->part->type != EDJE_PART_TYPE_IMAGE) return EINA_FALSE; id = _edje_image_id_find(eed, image); img = (Edje_Part_Description_Image *) pd; if (id > -1) img->image.id = id; else return EINA_FALSE; edje_object_calc_force(obj); return EINA_TRUE; } EAPI Eina_List * edje_edit_state_tweens_list_get(Evas_Object *obj, const char *part, const char *state, double value) { Edje_Part_Description_Image *img; Eina_List *tweens = NULL; const char *name; unsigned int i; GET_PD_OR_RETURN(NULL); if (rp->part->type != EDJE_PART_TYPE_IMAGE) return NULL; img = (Edje_Part_Description_Image *) pd; for (i = 0; i < img->image.tweens_count; ++i) { name = _edje_image_name_find(eed, img->image.tweens[i]->id); //printf(" t: %s\n", name); tweens = eina_list_append(tweens, eina_stringshare_add(name)); } return tweens; } EAPI Eina_Bool edje_edit_state_tween_add(Evas_Object *obj, const char *part, const char *state, double value, const char *tween) { Edje_Part_Description_Image *img; Edje_Part_Image_Id **tmp; Edje_Part_Image_Id *i; int id; GET_PD_OR_RETURN(EINA_FALSE); if (rp->part->type != EDJE_PART_TYPE_IMAGE) return EINA_FALSE; id = _edje_image_id_find(eed, tween); if (id < EINA_FALSE) return 0; /* alloc Edje_Part_Image_Id */ i = _alloc(sizeof(Edje_Part_Image_Id)); if (!i) return EINA_FALSE; i->id = id; img = (Edje_Part_Description_Image *) pd; /* add to tween list */ tmp = realloc(img->image.tweens, sizeof (Edje_Part_Image_Id*) * img->image.tweens_count); if (!tmp) { free(i); return EINA_FALSE; } tmp[img->image.tweens_count++] = i; img->image.tweens = tmp; return EINA_TRUE; } EAPI Eina_Bool edje_edit_state_tween_del(Evas_Object *obj, const char *part, const char *state, double value, const char *tween) { Edje_Part_Description_Image *img; unsigned int i; int search; GET_PD_OR_RETURN(EINA_FALSE); if (rp->part->type != EDJE_PART_TYPE_IMAGE) return EINA_FALSE; img = (Edje_Part_Description_Image *) pd; if (!img->image.tweens_count) return EINA_FALSE; search = _edje_image_id_find(eed, tween); if (search < 0) return EINA_FALSE; for (i = 0; i < img->image.tweens_count; ++i) { if (img->image.tweens[i]->id == search) { img->image.tweens_count--; free(img->image.tweens[i]); memmove(img->image.tweens + i, img->image.tweens + i + 1, sizeof (Edje_Part_Description_Image*) * (img->image.tweens_count - i)); return EINA_TRUE; } } return EINA_FALSE; } EAPI void edje_edit_state_image_border_get(Evas_Object *obj, const char *part, const char *state, double value, int *l, int *r, int *t, int *b) { Edje_Part_Description_Image *img; GET_PD_OR_RETURN(); if (rp->part->type != EDJE_PART_TYPE_IMAGE) { if (l) *l = 0; if (r) *r = 0; if (t) *t = 0; if (b) *b = 0; return; } img = (Edje_Part_Description_Image *) pd; //printf("GET IMAGE_BORDER of state '%s'\n", state); if (l) *l = img->image.border.l; if (r) *r = img->image.border.r; if (t) *t = img->image.border.t; if (b) *b = img->image.border.b; } EAPI Eina_Bool edje_edit_state_image_border_set(Evas_Object *obj, const char *part, const char *state, double value, int l, int r, int t, int b) { Edje_Part_Description_Image *img; if ((!obj) || (!part) || (!state)) return EINA_FALSE; if ((l < -1) || (r < -1) || (t < -1) || (b < -1)) return EINA_FALSE; eina_error_set(0); GET_PD_OR_RETURN(EINA_FALSE); if (rp->part->type != EDJE_PART_TYPE_IMAGE) return EINA_FALSE; img = (Edje_Part_Description_Image *) pd; img->image.border.l = l; img->image.border.r = r; img->image.border.t = t; img->image.border.b = b; edje_object_calc_force(obj); return EINA_TRUE; } EAPI unsigned char edje_edit_state_image_border_fill_get(Evas_Object *obj, const char *part, const char *state, double value) { Edje_Part_Description_Image *img; GET_PD_OR_RETURN(0); if (rp->part->type != EDJE_PART_TYPE_IMAGE) return 0; img = (Edje_Part_Description_Image *) pd; if (img->image.border.no_fill == 2) return 2; else return !img->image.border.no_fill; return 0; } EAPI Eina_Bool edje_edit_state_image_border_fill_set(Evas_Object *obj, const char *part, const char *state, double value, unsigned char fill) { Edje_Part_Description_Image *img; if ((!obj) || (!part) || (!state)) return EINA_FALSE; if (fill > 2) return EINA_FALSE; eina_error_set(0); GET_PD_OR_RETURN(EINA_FALSE); if (rp->part->type != EDJE_PART_TYPE_IMAGE) return EINA_FALSE; img = (Edje_Part_Description_Image *) pd; if (fill == 2) img->image.border.no_fill = 2; else img->image.border.no_fill = !fill; edje_object_calc_force(obj); return EINA_TRUE; } /****************/ /* SOUNDS API */ /****************/ EAPI Eina_List * edje_edit_sounds_samples_list_get(Evas_Object *obj) { Eina_List *sounds_samples = NULL; unsigned int i; GET_ED_OR_RETURN(NULL); if ((!ed->file) || (!ed->file->sound_dir)) return NULL; for (i = 0; i < ed->file->sound_dir->samples_count; ++i) sounds_samples = eina_list_append(sounds_samples, eina_stringshare_add(ed->file->sound_dir->samples[i].name)); return sounds_samples; } EAPI Eina_List * edje_edit_sounds_tones_list_get(Evas_Object *obj) { Eina_List *sounds_tones = NULL; unsigned int i; GET_ED_OR_RETURN(NULL); if ((!ed->file) || (!ed->file->sound_dir)) return NULL; for (i = 0; i < ed->file->sound_dir->tones_count; ++i) sounds_tones = eina_list_append(sounds_tones, eina_stringshare_add(ed->file->sound_dir->tones[i].name)); return sounds_tones; } /******************/ /* PROGRAMS API */ /******************/ static int _edje_program_id_find(Edje_Edit *eed, const char *program) { Edje_Program *epr; int i; for (i = 0; i < eed->base->collection->patterns.table_programs_size; i++) { epr = eed->base->collection->patterns.table_programs[i]; if (epr->name && !strcmp(epr->name, program)) return epr->id; } return -1; } static Edje_Program * _edje_program_get_byname(Evas_Object *obj, const char *prog_name) { Edje_Program *epr; int i; GET_ED_OR_RETURN(NULL); if (!prog_name) return NULL; for (i = 0; i < ed->collection->patterns.table_programs_size; i++) { epr = ed->collection->patterns.table_programs[i]; if ((epr->name) && (strcmp(epr->name, prog_name) == 0)) return epr; } return NULL; } EAPI Eina_List * edje_edit_programs_list_get(Evas_Object *obj) { Eina_List *progs = NULL; int i; GET_ED_OR_RETURN(NULL); //printf("EE: Found %d programs\n", ed->table_programs_size); for (i = 0; i < ed->collection->patterns.table_programs_size; i++) { Edje_Program *epr; epr = ed->collection->patterns.table_programs[i]; /* XXX: bad, we miss programs this way, but since you can't access * them in any way without a name, better ignore them. */ if (!epr->name) continue; progs = eina_list_append(progs, eina_stringshare_add(epr->name)); } return progs; } EAPI Eina_Bool edje_edit_program_add(Evas_Object *obj, const char *name) { Edje_Program *epr; GET_ED_OR_RETURN(EINA_FALSE); //printf("ADD PROGRAM [new name: %s]\n", name); //Check if program already exists if (_edje_program_get_byname(obj, name)) return EINA_FALSE; //Alloc Edje_Program or return epr = _alloc(sizeof(Edje_Program)); if (!epr) return EINA_FALSE; //Add program to group // pc = ed->collection; /* By default, source and signal are empty, so they fill in nocmp category */ ed->collection->programs.nocmp = realloc(ed->collection->programs.nocmp, sizeof (Edje_Program*) * (ed->collection->programs.nocmp_count + 1)); ed->collection->programs.nocmp[ed->collection->programs.nocmp_count++] = epr; //Init Edje_Program epr->id = ed->collection->patterns.table_programs_size; epr->name = eina_stringshare_add(name); epr->signal = NULL; epr->source = NULL; epr->filter.part = NULL; epr->filter.state = NULL; epr->in.from = 0.0; epr->in.range = 0.0; epr->action = 0; epr->state = NULL; epr->value = 0.0; epr->state2 = NULL; epr->value2 = 0.0; epr->tween.mode = 1; epr->tween.time = ZERO; epr->targets = NULL; epr->after = NULL; //Update table_programs ed->collection->patterns.table_programs_size++; ed->collection->patterns.table_programs = realloc(ed->collection->patterns.table_programs, sizeof(Edje_Program *) * ed->collection->patterns.table_programs_size); ed->collection->patterns.table_programs[epr->id % ed->collection->patterns.table_programs_size] = epr; //Update patterns _edje_programs_patterns_clean(ed->collection); _edje_programs_patterns_init(ed->collection); return EINA_TRUE; } EAPI Eina_Bool edje_edit_program_del(Evas_Object *obj, const char *prog) { Eina_List *l, *l_next; Edje_Program_Target *prt; Edje_Program_After *pa; Edje_Program *p; Program_Script *ps, *old_ps; int id, i; int old_id = -1; GET_EED_OR_RETURN(EINA_FALSE); GET_ED_OR_RETURN(EINA_FALSE); GET_EPR_OR_RETURN(EINA_FALSE); //pc = ed->collection; //Remove program from programs list id = epr->id; _edje_program_remove(ed->collection, epr); /* fix table program */ if (epr->id != ed->collection->patterns.table_programs_size - 1) { /* If the removed program is not the last in the list/table, * put the last one in its place and update references to it later */ ed->collection->patterns.table_programs[epr->id] = ed->collection->patterns.table_programs[ed->collection->patterns.table_programs_size - 1]; old_id = ed->collection->patterns.table_programs_size - 1; ed->collection->patterns.table_programs[epr->id]->id = epr->id; } ps = eina_hash_find(eed->program_scripts, &id); old_ps = eina_hash_find(eed->program_scripts, &old_id); if (old_ps) { if (!ps) { ps = _alloc(sizeof(Program_Script)); ps->id = id; eina_hash_add(eed->program_scripts, &id, ps); } else { free(ps->code); free(ps->processed); ps->processed = NULL; ps->delete_me = EINA_FALSE; } ps->code = old_ps->code; old_ps->code = NULL; free(old_ps->processed); old_ps->processed = NULL; ps->dirty = EINA_TRUE; old_ps->dirty = EINA_FALSE; old_ps->delete_me = EINA_TRUE; } else if (ps) { ps->dirty = EINA_FALSE; ps->delete_me = EINA_TRUE; } //Free Edje_Program _edje_if_string_free(ed, epr->name); _edje_if_string_free(ed, epr->signal); _edje_if_string_free(ed, epr->source); _edje_if_string_free(ed, epr->filter.part); _edje_if_string_free(ed, epr->filter.state); _edje_if_string_free(ed, epr->state); _edje_if_string_free(ed, epr->state2); EINA_LIST_FREE(epr->targets, prt) free(prt); EINA_LIST_FREE(epr->after, pa) free(pa); free(epr); ed->collection->patterns.table_programs_size--; ed->collection->patterns.table_programs = realloc(ed->collection->patterns.table_programs, sizeof(Edje_Program *) * ed->collection->patterns.table_programs_size); //We also update all other programs that point to old_id and id for (i = 0; i < ed->collection->patterns.table_programs_size; i++) { p = ed->collection->patterns.table_programs[i]; /* check in afters */ EINA_LIST_FOREACH_SAFE(p->after, l, l_next, pa) { if (pa->id == old_id) pa->id = id; else if (pa->id == id) { p->after = eina_list_remove_list(p->after, l); free(pa); } } /* check in targets */ if (p->action == EDJE_ACTION_TYPE_ACTION_STOP) { Edje_Program_Target *pt; EINA_LIST_FOREACH_SAFE(p->targets, l, l_next, pt) { if (pt->id == old_id) pt->id = id; else if (pt->id == id) { p->targets = eina_list_remove_list(p->targets, l); free(pt); } } } } _edje_edit_flag_script_dirty(eed, EINA_TRUE); return EINA_TRUE; } EAPI Eina_Bool edje_edit_program_exist(Evas_Object *obj, const char *prog) { GET_EPR_OR_RETURN(EINA_FALSE); return EINA_TRUE; } EAPI Eina_Bool edje_edit_program_run(Evas_Object *obj, const char *prog) { GET_ED_OR_RETURN(EINA_FALSE); GET_EPR_OR_RETURN(EINA_FALSE); _edje_program_run(ed, epr, 0, "", ""); return EINA_TRUE; } EAPI Eina_Bool edje_edit_program_name_set(Evas_Object *obj, const char *prog, const char* new_name) { GET_EED_OR_RETURN(EINA_FALSE); GET_ED_OR_RETURN(EINA_FALSE); GET_EPR_OR_RETURN(EINA_FALSE); if (!new_name) return EINA_FALSE; if (_edje_program_get_byname(obj, new_name)) return EINA_FALSE; //printf("SET NAME for program: %s [new name: %s]\n", prog, new_name); _edje_if_string_free(ed, epr->name); epr->name = eina_stringshare_add(new_name); _edje_edit_flag_script_dirty(eed, EINA_TRUE); return EINA_TRUE; } EAPI const char * edje_edit_program_source_get(Evas_Object *obj, const char *prog) { GET_EPR_OR_RETURN(NULL); if (!epr->source) return NULL; //printf("GET SOURCE for program: %s [%s]\n", prog, epr->source); return eina_stringshare_add(epr->source); } EAPI Eina_Bool edje_edit_program_source_set(Evas_Object *obj, const char *prog, const char *source) { GET_ED_OR_RETURN(EINA_FALSE); GET_EPR_OR_RETURN(EINA_FALSE); if (!source) return EINA_FALSE; /* Remove from program array */ _edje_program_remove(ed->collection, epr); _edje_if_string_free(ed, epr->source); /* Insert it back */ epr->source = eina_stringshare_add(source); _edje_program_insert(ed->collection, epr); //Update patterns _edje_programs_patterns_clean(ed->collection); _edje_programs_patterns_init(ed->collection); return EINA_TRUE; } EAPI const char * edje_edit_program_filter_part_get(Evas_Object *obj, const char *prog) { GET_EPR_OR_RETURN(NULL); if (!epr->filter.part) return NULL; return eina_stringshare_add(epr->filter.part); } EAPI Eina_Bool edje_edit_program_filter_part_set(Evas_Object *obj, const char *prog, const char *filter_part) { GET_ED_OR_RETURN(EINA_FALSE); GET_EPR_OR_RETURN(EINA_FALSE); if (!filter_part) return EINA_FALSE; _edje_if_string_free(ed, epr->filter.part); epr->filter.part = eina_stringshare_add(filter_part); return EINA_TRUE; } EAPI const char * edje_edit_program_filter_state_get(Evas_Object *obj, const char *prog) { GET_EPR_OR_RETURN(NULL); if (!epr->filter.state) return NULL; return eina_stringshare_add(epr->filter.state); } EAPI Eina_Bool edje_edit_program_filter_state_set(Evas_Object *obj, const char *prog, const char *filter_state) { GET_ED_OR_RETURN(EINA_FALSE); GET_EPR_OR_RETURN(EINA_FALSE); if (!filter_state) return EINA_FALSE; _edje_if_string_free(ed, epr->filter.state); epr->filter.state = eina_stringshare_add(filter_state); return EINA_TRUE; } EAPI const char * edje_edit_program_signal_get(Evas_Object *obj, const char *prog) { GET_EPR_OR_RETURN(NULL); if (!epr->signal) return NULL; //printf("GET SIGNAL for program: %s [%s]\n", prog, epr->signal); return eina_stringshare_add(epr->signal); } EAPI Eina_Bool edje_edit_program_signal_set(Evas_Object *obj, const char *prog, const char *sig) { GET_ED_OR_RETURN(EINA_FALSE); GET_EPR_OR_RETURN(EINA_FALSE); if (!sig) return EINA_FALSE; /* Remove from program array */ _edje_program_remove(ed->collection, epr); _edje_if_string_free(ed, epr->signal); /* Insert it back */ epr->signal = eina_stringshare_add(sig); _edje_program_insert(ed->collection, epr); //Update patterns _edje_programs_patterns_clean(ed->collection); _edje_programs_patterns_init(ed->collection); return EINA_TRUE; } EAPI const char * edje_edit_program_state_get(Evas_Object *obj, const char *prog) { GET_EPR_OR_RETURN(NULL); if (!epr->state) return NULL; //printf("GET STATE for program: %s [%s %.2f]\n", prog, epr->state, epr->value); return eina_stringshare_add(epr->state); } EAPI Eina_Bool edje_edit_program_state_set(Evas_Object *obj, const char *prog, const char *state) { GET_ED_OR_RETURN(EINA_FALSE); GET_EPR_OR_RETURN(EINA_FALSE); //printf("SET STATE for program: %s\n", prog); _edje_if_string_free(ed, epr->state); epr->state = eina_stringshare_add(state); return EINA_TRUE; } EAPI const char * edje_edit_program_state2_get(Evas_Object *obj, const char *prog) { GET_EPR_OR_RETURN(NULL); if (!epr->state2) return NULL; //printf("GET STATE2 for program: %s [%s %.2f]\n", prog, epr->state2, epr->value2); return eina_stringshare_add(epr->state2); } EAPI Eina_Bool edje_edit_program_state2_set(Evas_Object *obj, const char *prog, const char *state2) { GET_ED_OR_RETURN(EINA_FALSE); GET_EPR_OR_RETURN(EINA_FALSE); //printf("SET STATE2 for program: %s\n", prog); _edje_if_string_free(ed, epr->state2); epr->state2 = eina_stringshare_add(state2); return EINA_TRUE; } EAPI double edje_edit_program_value_get(Evas_Object *obj, const char *prog) { GET_EPR_OR_RETURN(-1); //printf("GET VALUE for program: %s [%s %.2f]\n", prog, epr->state, epr->value); return epr->value; } EAPI Eina_Bool edje_edit_program_value_set(Evas_Object *obj, const char *prog, double value) { GET_EPR_OR_RETURN(EINA_FALSE); //printf("SET VALUE for program: %s [%.2f]\n", prog, value); epr->value = value; return EINA_TRUE; } EAPI double edje_edit_program_value2_get(Evas_Object *obj, const char *prog) { GET_EPR_OR_RETURN(-1); //printf("GET VALUE2 for program: %s [%s %.2f]\n", prog, epr->state2, epr->value2); return epr->value2; } EAPI Eina_Bool edje_edit_program_value2_set(Evas_Object *obj, const char *prog, double value) { GET_EPR_OR_RETURN(EINA_FALSE); //printf("SET VALUE for program: %s [%.2f]\n", prog, value); epr->value2 = value; return EINA_TRUE; } EAPI double edje_edit_program_in_from_get(Evas_Object *obj, const char *prog) { GET_EPR_OR_RETURN(0); //printf("GET IN.FROM for program: %s [%f]\n", prog, epr->in.from); return epr->in.from; } EAPI Eina_Bool edje_edit_program_in_from_set(Evas_Object *obj, const char *prog, double seconds) { GET_EPR_OR_RETURN(EINA_FALSE); //printf("SET IN.FROM for program: %s [%f]\n", prog, epr->in.from); epr->in.from = seconds; return EINA_TRUE; } EAPI double edje_edit_program_in_range_get(Evas_Object *obj, const char *prog) { GET_EPR_OR_RETURN(0); //printf("GET IN.RANGE for program: %s [%f]\n", prog, epr->in.range); return epr->in.range; } EAPI Eina_Bool edje_edit_program_in_range_set(Evas_Object *obj, const char *prog, double seconds) { GET_EPR_OR_RETURN(EINA_FALSE); //printf("SET IN.RANGE for program: %s [%f]\n", prog, epr->in.range); epr->in.range = seconds; return EINA_TRUE; } EAPI Edje_Tween_Mode edje_edit_program_transition_get(Evas_Object *obj, const char *prog) { GET_EPR_OR_RETURN(-1); //printf("GET TRANSITION for program: %s [%d]\n", prog, epr->tween.mode); return epr->tween.mode; } EAPI Eina_Bool edje_edit_program_transition_set(Evas_Object *obj, const char *prog, Edje_Tween_Mode transition) { GET_EPR_OR_RETURN(EINA_FALSE); //printf("GET TRANSITION for program: %s [%d]\n", prog, epr->tween.mode); epr->tween.mode = transition; return EINA_TRUE; } EAPI double edje_edit_program_transition_value1_get(Evas_Object *obj, const char *prog) { eina_error_set(0); GET_EPR_OR_RETURN(-1); return TO_DOUBLE(epr->tween.v1); } EAPI Eina_Bool edje_edit_program_transition_value1_set(Evas_Object *obj, const char *prog, double value) { eina_error_set(0); GET_EPR_OR_RETURN(EINA_FALSE); epr->tween.v1 = FROM_DOUBLE(value); return EINA_TRUE; } EAPI double edje_edit_program_transition_value2_get(Evas_Object *obj, const char *prog) { eina_error_set(0); GET_EPR_OR_RETURN(-1); return TO_DOUBLE(epr->tween.v2); } EAPI Eina_Bool edje_edit_program_transition_value2_set(Evas_Object *obj, const char *prog, double value) { eina_error_set(0); GET_EPR_OR_RETURN(EINA_FALSE); epr->tween.v2 = FROM_DOUBLE(value); return EINA_TRUE; } EAPI double edje_edit_program_transition_time_get(Evas_Object *obj, const char *prog) { GET_EPR_OR_RETURN(-1); //printf("GET TRANSITION_TIME for program: %s [%.4f]\n", prog, epr->tween.time); return TO_DOUBLE(epr->tween.time); } EAPI Eina_Bool edje_edit_program_transition_time_set(Evas_Object *obj, const char *prog, double seconds) { GET_EPR_OR_RETURN(EINA_FALSE); //printf("GET TRANSITION_TIME for program: %s [%.4f]\n", prog, epr->tween.time); epr->tween.time = FROM_DOUBLE(seconds); return EINA_TRUE; } EAPI Edje_Action_Type edje_edit_program_action_get(Evas_Object *obj, const char *prog) { GET_EPR_OR_RETURN(-1); //printf("GET ACTION for program: %s [%d]\n", prog, epr->action); return epr->action; } EAPI Eina_Bool edje_edit_program_action_set(Evas_Object *obj, const char *prog, Edje_Action_Type action) { Program_Script *ps; GET_EED_OR_RETURN(EINA_FALSE); GET_EPR_OR_RETURN(EINA_FALSE); //printf("SET ACTION for program: %s [%d]\n", prog, action); if (action >= EDJE_ACTION_TYPE_LAST) return EINA_FALSE; if ((Edje_Action_Type)epr->action == action) return EINA_TRUE; if (action == EDJE_ACTION_TYPE_SCRIPT) { ps = eina_hash_find(eed->program_scripts, &epr->id); if (!ps) { ps = _alloc(sizeof(Program_Script)); if (!ps) return EINA_FALSE; } ps->id = epr->id; ps->code = strdup(""); ps->dirty = EINA_TRUE; ps->delete_me = EINA_FALSE; eina_hash_set(eed->program_scripts, &ps->id, ps); _edje_edit_flag_script_dirty(eed, EINA_FALSE); } if (epr->action == EDJE_ACTION_TYPE_SCRIPT) { ps = eina_hash_find(eed->program_scripts, &epr->id); if (ps) { free(ps->code); free(ps->processed); ps->code = ps->processed = NULL; ps->dirty = EINA_FALSE; ps->delete_me = EINA_TRUE; _edje_edit_flag_script_dirty(eed, EINA_FALSE); } } epr->action = action; return EINA_TRUE; } EAPI Eina_List * edje_edit_program_targets_get(Evas_Object *obj, const char *prog) { Eina_List *l, *targets = NULL; Edje_Program_Target *t; GET_ED_OR_RETURN(NULL); GET_EPR_OR_RETURN(NULL); //printf("GET TARGETS for program: %s [count: %d]\n", prog, eina_list_count(epr->targets)); EINA_LIST_FOREACH(epr->targets, l, t) { if (epr->action == EDJE_ACTION_TYPE_STATE_SET) { /* the target is a part */ Edje_Real_Part *p = NULL; p = ed->table_parts[t->id % ed->table_parts_size]; if (p && p->part && p->part->name) targets = eina_list_append(targets, eina_stringshare_add(p->part->name)); } else if (epr->action == EDJE_ACTION_TYPE_ACTION_STOP) { /* the target is a program */ Edje_Program *p; p = ed->collection->patterns.table_programs[t->id % ed->collection->patterns.table_programs_size]; if (p && p->name) targets = eina_list_append(targets, eina_stringshare_add(p->name)); } } return targets; } EAPI Eina_Bool edje_edit_program_targets_clear(Evas_Object *obj, const char *prog) { GET_EPR_OR_RETURN(EINA_FALSE); while (epr->targets) { Edje_Program_Target *prt; prt = eina_list_data_get(epr->targets); epr->targets = eina_list_remove_list(epr->targets, epr->targets); free(prt); } return EINA_TRUE; } EAPI Eina_Bool edje_edit_program_target_add(Evas_Object *obj, const char *prog, const char *target) { int id; Edje_Program_Target *t; GET_ED_OR_RETURN(EINA_FALSE); GET_EPR_OR_RETURN(EINA_FALSE); if (epr->action == EDJE_ACTION_TYPE_STATE_SET) { /* the target is a part */ Edje_Real_Part *rp; rp = _edje_real_part_get(ed, target); if (!rp) return EINA_FALSE; id = rp->part->id; } else if (epr->action == EDJE_ACTION_TYPE_ACTION_STOP) { /* the target is a program */ Edje_Program *tar; tar = _edje_program_get_byname(obj, target); if (!tar) return EINA_FALSE; id = tar->id; } else return EINA_FALSE; t = _alloc(sizeof(Edje_Program_Target)); if (!t) return EINA_FALSE; t->id = id; epr->targets = eina_list_append(epr->targets, t); return EINA_TRUE; } EAPI Eina_Bool edje_edit_program_target_del(Evas_Object *obj, const char *prog, const char *target) { int id; Eina_List *l; Edje_Program_Target *t; GET_ED_OR_RETURN(EINA_FALSE); GET_EPR_OR_RETURN(EINA_FALSE); if (epr->action == EDJE_ACTION_TYPE_STATE_SET) { /* the target is a part */ Edje_Real_Part *rp; rp = _edje_real_part_get(ed, target); if (!rp) return EINA_FALSE; id = rp->part->id; } else if (epr->action == EDJE_ACTION_TYPE_ACTION_STOP) { /* the target is a program */ Edje_Program *tar; tar = _edje_program_get_byname(obj, target); if (!tar) return EINA_FALSE; id = tar->id; } else return EINA_FALSE; EINA_LIST_FOREACH(epr->targets, l, t) if (t->id == id) break; epr->targets = eina_list_remove_list(epr->targets, l); free(t); return EINA_TRUE; } EAPI Eina_List * edje_edit_program_afters_get(Evas_Object *obj, const char *prog) { Eina_List *l, *afters = NULL; Edje_Program_After *a; GET_ED_OR_RETURN(NULL); GET_EPR_OR_RETURN(NULL); // printf("GET AFTERS for program: %s [count: %d]\n", prog, eina_list_count(epr->after)); EINA_LIST_FOREACH(epr->after, l, a) { Edje_Program *p = NULL; p = ed->collection->patterns.table_programs[a->id % ed->collection->patterns.table_programs_size]; if (p && p->name) { //printf(" a: %d name: %s\n", a->id, p->name); afters = eina_list_append(afters, eina_stringshare_add(p->name)); } } return afters; } EAPI Eina_Bool edje_edit_program_afters_clear(Evas_Object *obj, const char *prog) { GET_EPR_OR_RETURN(EINA_FALSE); while (epr->after) { Edje_Program_After *pa; pa = eina_list_data_get(epr->after); epr->after = eina_list_remove_list(epr->after, epr->after); free(pa); } return EINA_TRUE; } EAPI Eina_Bool edje_edit_program_after_add(Evas_Object *obj, const char *prog, const char *after) { Edje_Program *af; Edje_Program_After *a; GET_EPR_OR_RETURN(EINA_FALSE); af = _edje_program_get_byname(obj, after); if (!af) return EINA_FALSE; a = _alloc(sizeof(Edje_Program_After)); if (!a) return EINA_FALSE; a->id = af->id; epr->after = eina_list_append(epr->after, a); return EINA_TRUE; } EAPI Eina_Bool edje_edit_program_after_del(Evas_Object *obj, const char *prog, const char *after) { Edje_Program *af; Edje_Program_After *a; Eina_List *l; GET_EPR_OR_RETURN(EINA_FALSE); af = _edje_program_get_byname(obj, after); if (!af) return EINA_FALSE; EINA_LIST_FOREACH(epr->after, l, a) if (a->id == af->id) { epr->after = eina_list_remove_list(epr->after, l); break; } return EINA_TRUE; } EAPI const char * edje_edit_program_api_name_get(Evas_Object *obj, const char *prog) { GET_EPR_OR_RETURN(NULL); return eina_stringshare_add(epr->api.name); } EAPI const char * edje_edit_program_api_description_get(Evas_Object *obj, const char *prog) { GET_EPR_OR_RETURN(NULL); return eina_stringshare_add(epr->api.description); } EAPI Eina_Bool edje_edit_program_api_name_set(Evas_Object *obj, const char *prog, const char* name) { GET_ED_OR_RETURN(EINA_FALSE); GET_EPR_OR_RETURN(EINA_FALSE); _edje_if_string_free(ed, epr->api.name); epr->api.name = eina_stringshare_add(name); return EINA_TRUE; } EAPI Eina_Bool edje_edit_program_api_description_set(Evas_Object *obj, const char *prog, const char *description) { GET_ED_OR_RETURN(EINA_FALSE); GET_EPR_OR_RETURN(EINA_FALSE); _edje_if_string_free(ed, epr->api.description); epr->api.description = eina_stringshare_add(description); return EINA_TRUE; } /*************************/ /* EMBRYO SCRIPTS API */ /*************************/ EAPI char * edje_edit_script_get(Evas_Object *obj) { GET_EED_OR_RETURN(NULL); GET_ED_OR_RETURN(NULL); if (!ed->collection) return NULL; if (!eed->embryo_source) return NULL; return strdup(eed->embryo_source); } EAPI Eina_Bool edje_edit_script_set(Evas_Object *obj, const char *code) { GET_EED_OR_RETURN(EINA_FALSE); free(eed->embryo_source); free(eed->embryo_processed); if (code) eed->embryo_source = strdup(code); else eed->embryo_source = NULL; eed->embryo_processed = NULL; eed->embryo_source_dirty = EINA_TRUE; _edje_edit_flag_script_dirty(eed, EINA_FALSE); return EINA_TRUE; } EAPI char * edje_edit_script_program_get(Evas_Object *obj, const char *prog) { Program_Script *ps; GET_EED_OR_RETURN(NULL); GET_EPR_OR_RETURN(NULL); if (epr->action != EDJE_ACTION_TYPE_SCRIPT) return NULL; ps = eina_hash_find(eed->program_scripts, &epr->id); if (!ps) /* mmm? it should be there, even if empty */ return NULL; return ps->code ? strdup(ps->code) : NULL; } EAPI Eina_Bool edje_edit_script_program_set(Evas_Object *obj, const char *prog, const char *code) { Program_Script *ps; GET_EED_OR_RETURN(EINA_FALSE); GET_EPR_OR_RETURN(EINA_FALSE); if (epr->action != EDJE_ACTION_TYPE_SCRIPT) return EINA_FALSE; ps = eina_hash_find(eed->program_scripts, &epr->id); if (!ps) /* ???? how so? */ return EINA_FALSE; free(ps->code); free(ps->processed); if (code) ps->code = strdup(code); else ps->code = NULL; ps->processed = NULL; ps->dirty = EINA_TRUE; _edje_edit_flag_script_dirty(eed, EINA_FALSE); return EINA_TRUE; } static int __part_replace(Edje_Edit *eed, char *pcode, char *name) { int id; id = _edje_part_id_find((Edje *)eed, name); if (id < 0) return 0; return eina_convert_itoa(id, pcode); } static int __program_replace(Edje_Edit *eed, char *pcode, char *name) { int id; id = _edje_program_id_find(eed, name); if (id < 0) return 0; return eina_convert_itoa(id, pcode); } static int __group_replace(Edje_Edit *eed EINA_UNUSED, char *pcode, char *name) { strcpy(pcode, name); return strlen(name) + 1; } static int __image_replace(Edje_Edit *eed, char *pcode, char *name) { int id; id = _edje_image_id_find(eed, name); if (id < 0) return 0; return eina_convert_itoa(id, pcode); } static char * _edje_edit_script_process(Edje_Edit *eed, const char *progname, char *code) { char *pcode, *psrc, *pdst; int codesize, pcodesize; int quoted = 0, escaped = 0; int line = 1; Eina_Bool success = EINA_TRUE; codesize = strlen(code); pcode = malloc(codesize + 1); if (!pcode) return NULL; pcodesize = 0; psrc = code; pdst = pcode; while (*psrc) { if (!quoted) { char *ptr = NULL; const char *what = NULL; int (*func)(Edje_Edit *, char *, char *); if (*psrc == 'P') { if (!strncmp(psrc, "PART:\"", 6)) { psrc += 6; ptr = psrc; func = __part_replace; what = "part"; } else if (!strncmp(psrc, "PROGRAM:\"", 9)) { psrc += 9; ptr = psrc; func = __program_replace; what = "program"; } } else if (*psrc == 'G') { if (!strncmp(psrc, "GROUP:\"", 7)) { psrc += 7; ptr = psrc; func = __group_replace; what = "group"; } } else if (*psrc == 'I') { if (!strncmp(psrc, "IMAGE:\"", 7)) { psrc += 7; ptr = psrc; func = __image_replace; what = "image"; } } else if (*psrc == '#') { while (*psrc) if (*psrc == '\n') break; line++; continue; } else if (*psrc == '\"') quoted = 1; else if (*psrc == '\n') line++; if (ptr) { int i = 0, inesc = 0; char *name; while (*psrc) { if (!inesc) { if (*psrc == '\\') inesc = 1; else if (*psrc == '\"') { /* string concatenation as in "foo""bar" */ if (*(psrc + 1) != '\"') { psrc++; break; } else psrc++; } } else inesc = 0; psrc++; } name = alloca(psrc - ptr); inesc = 0; while (*ptr) { if (!inesc) { if (*ptr == '\\') inesc = 1; else if (*ptr == '\"') { if (*(ptr + 1) == '\"') ptr++; else { name[i] = 0; break; } } else { name[i] = *ptr; name[i + 1] = 0; i++; } } else inesc = 0; ptr++; } i = func(eed, pdst, name); if (!i) { Edje_Edit_Script_Error *se; se = malloc(sizeof(Edje_Edit_Script_Error)); se->program_name = progname ? eina_stringshare_add(progname) : NULL; se->line = line; se->error_str = eina_stringshare_printf( "Referenced %s '%s' could not be found in object.", what, name); eed->errors = eina_list_append(eed->errors, se); success = EINA_FALSE; } else { pcodesize += i; pdst += i; } /* replaced reference for the right value, now go * to the next iteration */ continue; } } else { if (!escaped) { if (*psrc == '\"') quoted = 0; else if (*psrc == '\\') escaped = 1; } else if (escaped) escaped = 0; } *pdst = *psrc; pdst++; psrc++; pcodesize++; } if (!success) { free(pcode); return NULL; } if (pcodesize < codesize) pcode = realloc(pcode, pcodesize + 1); pcode[pcodesize] = 0; return pcode; } static Eina_Bool _edje_edit_embryo_rebuild(Edje_Edit *eed) { FILE *f; int fd, size, ret; const char *tmp_dir; char tmp_in[PATH_MAX]; char tmp_out[PATH_MAX]; char embryo_cc_path[PATH_MAX] = ""; char inc_path[PATH_MAX] = ""; char buf[4096]; Eina_Iterator *it; Program_Script *ps; Edje_Part_Collection *edc; Eina_Bool success = EINA_TRUE; /* we are optimists! */ Edje_Edit_Script_Error *se; Eina_Prefix *pfx; EINA_LIST_FREE(eed->errors, se) { eina_stringshare_del(se->program_name); eina_stringshare_del(se->error_str); free(se); } #ifdef HAVE_EVIL tmp_dir = evil_tmpdir_get(); #else tmp_dir = "/tmp"; #endif pfx = eina_prefix_new(NULL, /* argv[0] value (optional) */ edje_init, /* an optional symbol to check path of */ "EDJE", /* env var prefix to use (XXX_PREFIX, XXX_BIN_DIR etc. */ "edje", /* dir to add after "share" (PREFIX/share/DIRNAME) */ "include/edje.inc", /* a magic file to check for in PREFIX/share/DIRNAME for success */ PACKAGE_BIN_DIR, /* package bin dir @ compile time */ PACKAGE_LIB_DIR, /* package lib dir @ compile time */ PACKAGE_DATA_DIR, /* package data dir @ compile time */ PACKAGE_DATA_DIR /* if locale needed use LOCALE_DIR */ ); #ifdef _WIN32 # define BIN_EXT ".exe" #else # define BIN_EXT #endif #if defined(HAVE_GETUID) && defined(HAVE_GETEUID) if (getuid() == geteuid()) #endif { if (getenv("EFL_RUN_IN_TREE")) { snprintf(embryo_cc_path, sizeof(embryo_cc_path), "%s/src/bin/embryo/embryo_cc" BIN_EXT, PACKAGE_BUILD_DIR); snprintf(inc_path, sizeof(inc_path), "%s/data/edje/include", PACKAGE_BUILD_DIR); if (!ecore_file_exists(embryo_cc_path)) embryo_cc_path[0] = '\0'; } } if (embryo_cc_path[0] == '\0') { snprintf(embryo_cc_path, sizeof(embryo_cc_path), "%s/embryo_cc" BIN_EXT, eina_prefix_bin_get(pfx)); snprintf(inc_path, sizeof(inc_path), "%s/include", eina_prefix_data_get(pfx)); } #undef BIN_EXT eina_prefix_free(pfx); snprintf(tmp_in, sizeof(tmp_in), "%s/edje_edit.sma-tmp-XXXXXX", tmp_dir); snprintf(tmp_out, sizeof(tmp_out), "%s/edje_edit.amx-tmp-XXXXXX", tmp_dir); fd = mkstemp(tmp_in); if (fd < 0) return EINA_FALSE; /* FIXME: report something */ f = fdopen(fd, "w"); if (!f) { close(fd); unlink(tmp_in); return EINA_FALSE; } fprintf(f, "#include \n"); if (eed->embryo_source) { if (eed->all_dirty) { free(eed->embryo_processed); eed->embryo_processed = NULL; } if (!eed->embryo_processed) eed->embryo_processed = _edje_edit_script_process(eed, NULL, eed->embryo_source); if (!eed->embryo_processed) { /* oops.. an error finding references parts or something. * we could flag it and do some lighter processing of the * rest of the scripts, in order to find all the errors of * this kind and report them at once, but knowing already * that the script will not compile we can avoid some work */ success = EINA_FALSE; } else fprintf(f, "%s", eed->embryo_processed); } it = eina_hash_iterator_data_new(eed->program_scripts); EINA_ITERATOR_FOREACH(it, ps) { Edje_Program *epr; if (ps->delete_me) continue; if (eed->all_dirty) { free(ps->processed); ps->processed = NULL; } epr = eed->base->collection->patterns.table_programs[ps->id]; if (!ps->processed) ps->processed = _edje_edit_script_process(eed, epr->name, ps->code); if (!ps->processed) { /* oops.. an error finding references parts or something. * we could flag it and do some lighter processing of the * rest of the scripts, in order to find all the errors of * this kind and report them at once, but knowing already * that the script will not compile we can avoid some work */ success = EINA_FALSE; continue; } fprintf(f, "public _p%i(sig[], src[]) {\n", ps->id); fprintf(f, "%s", ps->processed); fprintf(f, "}\n"); } eina_iterator_free(it); fclose(f); if (!success) goto almost_out; fd = mkstemp(tmp_out); if (fd < 0) { success = EINA_FALSE; goto almost_out; } snprintf(buf, sizeof(buf), "%s -i %s -o %s %s", embryo_cc_path, inc_path, tmp_out, tmp_in); ret = system(buf); if ((ret < 0) || (ret > 1)) { success = EINA_FALSE; close(fd); goto the_doorway; } f = fdopen(fd, "rb"); if (!f) { success = EINA_FALSE; close(fd); goto the_doorway; } fseek(f, 0, SEEK_END); size = ftell(f); rewind(f); free(eed->bytecode); if (size > 0) { eed->bytecode = malloc(size); if (!eed->bytecode) { success = EINA_FALSE; goto the_way_out; } if (fread(eed->bytecode, size, 1, f) != 1) { success = EINA_FALSE; goto the_way_out; } } else eed->bytecode = NULL; /* correctness mostly, I don't see why we would get a 0 sized program */ eed->bytecode_size = size; eed->bytecode_dirty = EINA_TRUE; eed->script_need_recompile = EINA_FALSE; eed->all_dirty = EINA_FALSE; edc = eed->base->collection; embryo_program_free(edc->script); edc->script = embryo_program_new(eed->bytecode, eed->bytecode_size); _edje_embryo_script_init(edc); _edje_var_init((Edje *)eed); the_way_out: fclose(f); the_doorway: unlink(tmp_out); almost_out: unlink(tmp_in); return success; } EAPI Eina_Bool edje_edit_script_compile(Evas_Object *obj) { GET_EED_OR_RETURN(EINA_FALSE); if (!eed->script_need_recompile) return EINA_TRUE; return _edje_edit_embryo_rebuild(eed); } EAPI const Eina_List * edje_edit_script_error_list_get(Evas_Object *obj) { GET_EED_OR_RETURN(NULL); return eed->errors; } /***************************/ /* EDC SOURCE GENERATION */ /***************************/ #define I0 "" #define I1 " " #define I2 " " #define I3 " " #define I4 " " #define I5 " " #define I6 " " #define I7 " " #define BUF_APPEND(STR) \ ret &= eina_strbuf_append(buf, STR) #define BUF_APPENDF(FMT, ...) \ ret &= eina_strbuf_append_printf(buf, FMT, ##__VA_ARGS__) #define COLLECT_RESOURCE(condition_data, list) \ if (condition_data) \ { \ if (!eina_list_data_find(list, condition_data)) \ list = eina_list_append(list, condition_data); \ } static const char *types[] = {"NONE", "RECT", "TEXT", "IMAGE", "SWALLOW", "TEXTBLOCK", "GRADIENT", "GROUP", "BOX", "TABLE", "EXTERNAL", "PROXY", "SPACER"}; static const char *effects[] = {"NONE", "PLAIN", "OUTLINE", "SOFT_OUTLINE", "SHADOW", "SOFT_SHADOW", "OUTLINE_SHADOW", "OUTLINE_SOFT_SHADOW", "FAR_SHADOW", "FAR_SOFT_SHADOW", "GLOW"}; static const char *shadow_direction[] = {"BOTTOM_RIGHT", "BOTTOM", "BOTTOM_LEFT", "LEFT", "TOP_LEFT", "TOP", "TOP_RIGHT", "RIGHT"}; static const char *prefers[] = {"NONE", "VERTICAL", "HORIZONTAL", "BOTH"}; static Eina_Bool _edje_generate_source_of_group(Edje *ed, Edje_Part_Collection_Directory_Entry *pce, Eina_Strbuf *buf); static Eina_Bool _edje_generate_source_of_style(Edje * ed, const char *name, Eina_Strbuf *buf); static Eina_Bool _edje_generate_source_of_colorclass(Edje * ed, const char *name, Eina_Strbuf *buf); static const char * _edje_generate_image_source(Evas_Object *obj, const char *entry) { Eina_Strbuf *buf = eina_strbuf_new(); Eina_Bool ret = EINA_TRUE; if (!buf) return NULL; int comp = edje_edit_image_compression_type_get(obj, entry); if (comp < 0) return NULL; BUF_APPENDF("image: \"%s\" ", entry); if (comp == EDJE_EDIT_IMAGE_COMP_LOSSY) BUF_APPENDF("LOSSY %d;\n", edje_edit_image_compression_rate_get(obj, entry)); else if (comp == EDJE_EDIT_IMAGE_COMP_LOSSY_ETC1) BUF_APPENDF("LOSSY_ETC1 %d;\n", edje_edit_image_compression_rate_get(obj, entry)); else if (comp == EDJE_EDIT_IMAGE_COMP_RAW) BUF_APPEND("RAW;\n"); else if (comp == EDJE_EDIT_IMAGE_COMP_USER) BUF_APPEND("USER;\n"); else BUF_APPEND("COMP;\n"); if (!ret) { ERR("Generating EDC for Image"); eina_strbuf_free(buf); return NULL; } return eina_strbuf_string_get(buf); } EAPI const char * edje_edit_source_generate(Evas_Object *obj) { Edje_Part_Collection_Directory_Entry *ce; Edje_Part *part; Edje_Part_Description_Common *part_desc; Edje_Part_Description_Image *part_desc_image; Edje_Part_Description_Text *part_desc_text; unsigned int i, j; const char *entry; Eina_Strbuf *buf = eina_strbuf_new(); Eina_Bool ret = EINA_TRUE; Eina_List *images = NULL, *color_classes = NULL, *styles = NULL, *fonts = NULL; Eina_List *l; GET_ED_OR_RETURN(NULL); GET_EED_OR_RETURN(NULL); if (!ed->file) return NULL; ce = eina_hash_find(ed->file->collection, ed->group); if (!ce) return NULL; /* Go through all of group's parts to find all resources needed for that group. */ for (i = 0; i < ed->table_parts_size; i++) { part = ed->table_parts[i]->part; part_desc = (Edje_Part_Description_Common *)part->default_desc; /* find all image parts and collect all images required by those parts. */ if (part->type == EDJE_PART_TYPE_IMAGE) { /* parse "default" description of this part. */ part_desc_image = (Edje_Part_Description_Image *)part->default_desc; /* find image name according to it's id that is in description */ entry = _edje_image_name_find(eed, part_desc_image->image.id); COLLECT_RESOURCE(entry, images); /* look through all other's descriptions. */ for (j = 0; j < part->other.desc_count; j++) { part_desc_image = (Edje_Part_Description_Image *)part->other.desc[j]; entry = _edje_image_name_find(eed, part_desc_image->image.id); COLLECT_RESOURCE(entry, images); } } /* find all text, textblock part and fonts, styles required by those parts. */ if ((part->type == EDJE_PART_TYPE_TEXTBLOCK) || (part->type == EDJE_PART_TYPE_TEXT)) { part_desc_text = (Edje_Part_Description_Text *)part->default_desc; COLLECT_RESOURCE(part_desc_text->text.style.str, styles); if (part_desc_text->text.font.str) { Edje_Font_Directory_Entry *fnt; fnt = eina_hash_find(ed->file->fonts, part_desc_text->text.font.str); COLLECT_RESOURCE(fnt, fonts); } for (j = 0; j < part->other.desc_count; j++) { part_desc_text = (Edje_Part_Description_Text *)part->other.desc[j]; COLLECT_RESOURCE(part_desc_text->text.style.str, styles); if (part_desc_text->text.font.str) { Edje_Font_Directory_Entry *fnt; fnt = eina_hash_find(ed->file->fonts, part_desc_text->text.font.str); COLLECT_RESOURCE(fnt, fonts); } } } /* find all color_classes required by those every part. */ COLLECT_RESOURCE(part_desc->color_class, color_classes); for (j = 0; j < part->other.desc_count; j++) { part_desc = part->other.desc[j]; COLLECT_RESOURCE(part_desc->color_class, color_classes); } } /* if images were found, print them */ if (images) { BUF_APPEND(I0"images {\n"); EINA_LIST_FOREACH(images, l, entry) { const char *image_source = _edje_generate_image_source(obj, entry); if (!image_source) continue; BUF_APPENDF(I1"%s", image_source); } BUF_APPEND(I0"}\n\n"); } /* if styles were found, print them */ if (styles) { BUF_APPEND(I0 "styles {\n"); EINA_LIST_FOREACH(styles, l, entry) _edje_generate_source_of_style(ed, entry, buf); BUF_APPEND(I0 "}\n\n"); } /* if fonts were found, print them */ if (fonts) { BUF_APPEND(I0 "fonts {\n"); Edje_Font_Directory_Entry *fnt; EINA_LIST_FOREACH(fonts, l, fnt) { BUF_APPENDF(I1"font: \"%s\" \"%s\";\n", fnt->file, fnt->entry); } BUF_APPEND(I0 "}\n\n"); } /* if color_classes were found, print them */ if (color_classes) { BUF_APPEND(I0 "color_classes {\n"); EINA_LIST_FOREACH(color_classes, l, entry) _edje_generate_source_of_colorclass(ed, entry, buf); BUF_APPEND(I0 "}\n\n"); } /* print the main code of group collections */ BUF_APPEND(I0"collections {\n"); _edje_generate_source_of_group(ed, ce, buf); BUF_APPEND(I0"}"); if (!ret) { ERR("Generating EDC for This Group."); return NULL; } /* return resulted source code of the group */ return eina_strbuf_string_get(buf); } #undef COLLECT_RESOURCE static Eina_Bool _edje_generate_source_of_colorclass(Edje * ed, const char *name, Eina_Strbuf *buf) { Eina_List *l; Edje_Color_Class *cc; Eina_Bool ret = EINA_TRUE; EINA_LIST_FOREACH(ed->file->color_classes, l, cc) if (!strcmp(cc->name, name)) { BUF_APPENDF(I1 "color_class { name: \"%s\";\n", cc->name); BUF_APPENDF(I2 "color: %d %d %d %d;\n", cc->r, cc->g, cc->b, cc->a); BUF_APPENDF(I2 "color2: %d %d %d %d;\n", cc->r2, cc->g2, cc->b2, cc->a2); BUF_APPENDF(I2 "color3: %d %d %d %d;\n", cc->r3, cc->g3, cc->b3, cc->a3); BUF_APPEND(I1 "}\n"); } return ret; } static Eina_Bool _edje_generate_source_of_style(Edje * ed, const char *name, Eina_Strbuf *buf) { Eina_List *l, *ll; Edje_Style *s; Edje_Style_Tag *t; Eina_Bool ret = EINA_TRUE; int len, i; #define ESCAPE_VAL(VAL) \ for (i = 0, len = strlen(VAL); i < len; i++) \ switch(VAL[i]) \ { \ case '\n': \ { \ BUF_APPENDF("%s", "\\n"); \ break; \ } \ case '\t': \ { \ BUF_APPENDF("%s", "\\t"); \ break; \ } \ case '"': \ { \ BUF_APPENDF("%s", "\\\""); \ break; \ } \ case '\\': \ { \ BUF_APPENDF("%s", "\\\\"); \ break; \ } \ default: BUF_APPENDF("%c", VAL[i]); \ } EINA_LIST_FOREACH(ed->file->styles, l, s) if (!strcmp(s->name, name)) { t = s->tags ? s->tags->data : NULL; BUF_APPENDF(I1 "style { name:\"%s\";\n", s->name); if (t && t->value) { BUF_APPEND(I2 "base: \""); ESCAPE_VAL(t->value); BUF_APPEND("\";\n"); } EINA_LIST_FOREACH(s->tags, ll, t) if (ll->prev && t && t->value) { BUF_APPENDF(I2 "tag: \"%s\" \"", t->key); ESCAPE_VAL(t->value); BUF_APPEND("\";\n"); } BUF_APPEND(I1 "}\n"); return ret; } #undef ESCAPE_VAL return EINA_FALSE; } static Eina_Bool _edje_generate_source_of_program(Evas_Object *obj, const char *program, Eina_Strbuf *buf) { Eina_List *l, *ll; const char *s, *s2; double db, db2; char *data; Eina_Bool ret = EINA_TRUE; const char *api_name, *api_description; Edje_Program *epr; GET_EED_OR_RETURN(EINA_FALSE); epr = _edje_program_get_byname(obj, program); BUF_APPENDF(I3"program { name: \"%s\";\n", program); /* Signal */ if ((s = edje_edit_program_signal_get(obj, program))) { BUF_APPENDF(I4"signal: \"%s\";\n", s); edje_edit_string_free(s); } /* Source */ if ((s = edje_edit_program_source_get(obj, program))) { BUF_APPENDF(I4"source: \"%s\";\n", s); edje_edit_string_free(s); } /* Action */ switch (edje_edit_program_action_get(obj, program)) { case EDJE_ACTION_TYPE_ACTION_STOP: BUF_APPEND(I4"action: ACTION_STOP;\n"); break; case EDJE_ACTION_TYPE_STATE_SET: if ((s = edje_edit_program_state_get(obj, program))) { BUF_APPENDF(I4"action: STATE_SET \"%s\" %.2f;\n", s, edje_edit_program_value_get(obj, program)); edje_edit_string_free(s); } break; case EDJE_ACTION_TYPE_SIGNAL_EMIT: s = edje_edit_program_state_get(obj, program); s2 = edje_edit_program_state2_get(obj, program); if (s && s2) { BUF_APPENDF(I4"action: SIGNAL_EMIT \"%s\" \"%s\";\n", s, s2); edje_edit_string_free(s); edje_edit_string_free(s2); } break; case EDJE_ACTION_TYPE_SCRIPT: { Program_Script *ps; ps = eina_hash_find(eed->program_scripts, &epr->id); if (ps && !ps->delete_me) { BUF_APPEND(I4"script {\n"); BUF_APPEND(ps->code); BUF_APPEND(I4"}\n"); } } break; //TODO Support Drag //~ case EDJE_ACTION_TYPE_DRAG_VAL_SET: //~ eina_strbuf_append(buf, I4"action: DRAG_VAL_SET TODO;\n"); //~ break; //~ case EDJE_ACTION_TYPE_DRAG_VAL_STEP: //~ eina_strbuf_append(buf, I4"action: DRAG_VAL_STEP TODO;\n"); //~ break; //~ case EDJE_ACTION_TYPE_DRAG_VAL_PAGE: //~ eina_strbuf_append(buf, I4"action: DRAG_VAL_PAGE TODO;\n"); //~ break; default: break; } /* Transition */ db = edje_edit_program_transition_time_get(obj, program); switch (edje_edit_program_transition_get(obj, program)) { case EDJE_TWEEN_MODE_LINEAR: if (db) BUF_APPENDF(I4"transition: LINEAR %.5f;\n", db); break; case EDJE_TWEEN_MODE_ACCELERATE: BUF_APPENDF(I4"transition: ACCELERATE %.5f;\n", db); break; case EDJE_TWEEN_MODE_DECELERATE: BUF_APPENDF(I4"transition: DECELERATE %.5f;\n", db); break; case EDJE_TWEEN_MODE_SINUSOIDAL: BUF_APPENDF(I4"transition: SINUSOIDAL %.5f;\n", db); break; default: break; } /* In */ db = edje_edit_program_in_from_get(obj, program); db2 = edje_edit_program_in_range_get(obj, program); if (db || db2) BUF_APPENDF(I4"in: %.5f %.5f;\n", db, db2); /* Targets */ if ((ll = edje_edit_program_targets_get(obj, program))) { EINA_LIST_FOREACH(ll, l, data) BUF_APPENDF(I4"target: \"%s\";\n", data); edje_edit_string_list_free(ll); } /* Afters */ if ((ll = edje_edit_program_afters_get(obj, program))) { EINA_LIST_FOREACH(ll, l, data) BUF_APPENDF(I4"after: \"%s\";\n", data); edje_edit_string_list_free(ll); } // TODO Support script {} /* api */ api_name = edje_edit_program_api_name_get(obj, program); api_description = edje_edit_program_api_description_get(obj, program); if (api_name || api_description) { if (api_name && api_description) { BUF_APPENDF(I4"api: \"%s\" \"%s\";\n", api_name, api_description); edje_edit_string_free(api_name); edje_edit_string_free(api_description); } else if (api_name) { BUF_APPENDF(I4"api: \"%s\" \"\";\n", api_name); edje_edit_string_free(api_name); } else { BUF_APPENDF(I4"api: \"\" \"%s\";\n", api_description); edje_edit_string_free(api_description); } } BUF_APPEND(I3 "}\n"); return ret; } static Eina_Bool _edje_generate_source_of_state(Evas_Object *obj, const char *part, const char *state, double value, Eina_Strbuf *buf) { Eina_List *l, *ll; Eina_Bool ret = EINA_TRUE; GET_PD_OR_RETURN(EINA_FALSE); BUF_APPENDF(I4"description { state: \"%s\" %g;\n", pd->state.name, pd->state.value); //TODO Support inherit if (!pd->visible) BUF_APPEND(I5"visible: 0;\n"); if (pd->align.x != 0.5 || pd->align.y != 0.5) BUF_APPENDF(I5"align: %g %g;\n", TO_DOUBLE(pd->align.x), TO_DOUBLE(pd->align.y)); //TODO Support fixed if (pd->min.w || pd->min.h) BUF_APPENDF(I5"min: %d %d;\n", pd->min.w, pd->min.h); if (pd->max.w != -1 || pd->max.h != -1) BUF_APPENDF(I5"max: %d %d;\n", pd->max.w, pd->max.h); //TODO Support step if (pd->aspect.min || pd->aspect.max) BUF_APPENDF(I5"aspect: %g %g;\n", TO_DOUBLE(pd->aspect.min), TO_DOUBLE(pd->aspect.max)); if (pd->aspect.prefer) BUF_APPENDF(I5"aspect_preference: %s;\n", prefers[(int) pd->aspect.prefer]); if (pd->color_class) BUF_APPENDF(I5"color_class: \"%s\";\n", pd->color_class); if (pd->color.r != 255 || pd->color.g != 255 || pd->color.b != 255 || pd->color.a != 255) BUF_APPENDF(I5"color: %d %d %d %d;\n", pd->color.r, pd->color.g, pd->color.b, pd->color.a); if (pd->color2.r != 0 || pd->color2.g != 0 || pd->color2.b != 0 || pd->color2.a != 255) BUF_APPENDF(I5"color2: %d %d %d %d;\n", pd->color2.r, pd->color2.g, pd->color2.b, pd->color2.a); if (rp->part->type == EDJE_PART_TYPE_TEXT || rp->part->type == EDJE_PART_TYPE_TEXTBLOCK) { Edje_Part_Description_Text *txt; txt = (Edje_Part_Description_Text *) pd; if (txt->text.color3.r != 0 || txt->text.color3.g != 0 || txt->text.color3.b != 0 || txt->text.color3.a != 128) BUF_APPENDF(I5"color3: %d %d %d %d;\n", txt->text.color3.r, txt->text.color3.g, txt->text.color3.b, txt->text.color3.a); } //Rel1 if (pd->rel1.relative_x || pd->rel1.relative_y || pd->rel1.offset_x || pd->rel1.offset_y || pd->rel1.id_x != -1 || pd->rel1.id_y != -1) { BUF_APPEND(I5"rel1 {\n"); if (pd->rel1.relative_x || pd->rel1.relative_y) BUF_APPENDF(I6"relative: %g %g;\n", TO_DOUBLE(pd->rel1.relative_x), TO_DOUBLE(pd->rel1.relative_y)); if (pd->rel1.offset_x || pd->rel1.offset_y) BUF_APPENDF(I6"offset: %d %d;\n", pd->rel1.offset_x, pd->rel1.offset_y); if (pd->rel1.id_x != -1 && pd->rel1.id_x == pd->rel1.id_y) BUF_APPENDF(I6"to: \"%s\";\n", ed->table_parts[pd->rel1.id_x]->part->name); else { if (pd->rel1.id_x != -1) BUF_APPENDF(I6"to_x: \"%s\";\n", ed->table_parts[pd->rel1.id_x]->part->name); if (pd->rel1.id_y != -1) BUF_APPENDF(I6"to_y: \"%s\";\n", ed->table_parts[pd->rel1.id_y]->part->name); } BUF_APPEND(I5"}\n");//rel1 } //Rel2 if (pd->rel2.relative_x != 1.0 || pd->rel2.relative_y != 1.0 || pd->rel2.offset_x != -1 || pd->rel2.offset_y != -1 || pd->rel2.id_x != -1 || pd->rel2.id_y != -1) { BUF_APPEND(I5"rel2 {\n"); if (TO_DOUBLE(pd->rel2.relative_x) != 1.0 || TO_DOUBLE(pd->rel2.relative_y) != 1.0) BUF_APPENDF(I6"relative: %g %g;\n", TO_DOUBLE(pd->rel2.relative_x), TO_DOUBLE(pd->rel2.relative_y)); if (pd->rel2.offset_x != -1 || pd->rel2.offset_y != -1) BUF_APPENDF(I6"offset: %d %d;\n", pd->rel2.offset_x, pd->rel2.offset_y); if (pd->rel2.id_x != -1 && pd->rel2.id_x == pd->rel2.id_y) BUF_APPENDF(I6"to: \"%s\";\n", ed->table_parts[pd->rel2.id_x]->part->name); else { if (pd->rel2.id_x != -1) BUF_APPENDF(I6"to_x: \"%s\";\n", ed->table_parts[pd->rel2.id_x]->part->name); if (pd->rel2.id_y != -1) BUF_APPENDF(I6"to_y: \"%s\";\n", ed->table_parts[pd->rel2.id_y]->part->name); } BUF_APPEND(I5"}\n");//rel2 } //Image if (rp->part->type == EDJE_PART_TYPE_IMAGE) { char *data; const char *image_name; Edje_Part_Description_Image *img; img = (Edje_Part_Description_Image *) pd; BUF_APPEND(I5"image {\n"); image_name = _edje_image_name_find(eed, img->image.id); if (image_name) BUF_APPENDF(I6"normal: \"%s\";\n", image_name); ll = edje_edit_state_tweens_list_get(obj, part, state, value); EINA_LIST_FOREACH(ll, l, data) BUF_APPENDF(I6"tween: \"%s\";\n", data); edje_edit_string_list_free(ll); if (img->image.border.l || img->image.border.r || img->image.border.t || img->image.border.b) BUF_APPENDF(I6"border: %d %d %d %d;\n", img->image.border.l, img->image.border.r, img->image.border.t, img->image.border.b); if (img->image.border.no_fill == 1) BUF_APPEND(I6"middle: NONE;\n"); else if (img->image.border.no_fill == 0) BUF_APPEND(I6"middle: DEFAULT;\n"); else if (img->image.border.no_fill == 2) BUF_APPEND(I6"middle: SOLID;\n"); BUF_APPEND(I5"}\n");//image //Fill if (!img->image.fill.smooth || img->image.fill.pos_rel_x || img->image.fill.pos_rel_y || img->image.fill.pos_abs_x || img->image.fill.pos_abs_y || TO_DOUBLE(img->image.fill.rel_x) != 1.0 || TO_DOUBLE(img->image.fill.rel_y) != 1.0 || img->image.fill.abs_x || img->image.fill.abs_y) { BUF_APPEND(I5"fill {\n"); if (!img->image.fill.smooth) BUF_APPEND(I6"smooth: 0;\n"); //TODO Support spread if (img->image.fill.pos_rel_x || img->image.fill.pos_rel_y || img->image.fill.pos_abs_x || img->image.fill.pos_abs_y) { BUF_APPEND(I6"origin {\n"); if (img->image.fill.pos_rel_x || img->image.fill.pos_rel_y) BUF_APPENDF(I7"relative: %g %g;\n", TO_DOUBLE(img->image.fill.pos_rel_x), TO_DOUBLE(img->image.fill.pos_rel_y)); if (img->image.fill.pos_abs_x || img->image.fill.pos_abs_y) BUF_APPENDF(I7"offset: %d %d;\n", img->image.fill.pos_abs_x, img->image.fill.pos_abs_y); BUF_APPEND(I6"}\n"); } if (TO_DOUBLE(img->image.fill.rel_x) != 1.0 || TO_DOUBLE(img->image.fill.rel_y) != 1.0 || img->image.fill.abs_x || img->image.fill.abs_y) { BUF_APPEND(I6"size {\n"); if (img->image.fill.rel_x != 1.0 || img->image.fill.rel_y != 1.0) BUF_APPENDF(I7"relative: %g %g;\n", TO_DOUBLE(img->image.fill.rel_x), TO_DOUBLE(img->image.fill.rel_y)); if (img->image.fill.abs_x || img->image.fill.abs_y) BUF_APPENDF(I7"offset: %d %d;\n", img->image.fill.abs_x, img->image.fill.abs_y); BUF_APPEND(I6"}\n"); } BUF_APPEND(I5"}\n"); } } if (rp->part->type == EDJE_PART_TYPE_PROXY) { Edje_Part_Description_Proxy *pro; pro = (Edje_Part_Description_Proxy *) pd; //Fill BUF_APPEND(I5"fill {\n"); if (!pro->proxy.fill.smooth) BUF_APPEND(I6"smooth: 0;\n"); //TODO Support spread //TODO Support source if (pro->proxy.fill.pos_rel_x || pro->proxy.fill.pos_rel_y || pro->proxy.fill.pos_abs_x || pro->proxy.fill.pos_abs_y) { BUF_APPEND(I6"origin {\n"); if (pro->proxy.fill.pos_rel_x || pro->proxy.fill.pos_rel_y) BUF_APPENDF(I7"relative: %g %g;\n", TO_DOUBLE(pro->proxy.fill.pos_rel_x), TO_DOUBLE(pro->proxy.fill.pos_rel_y)); if (pro->proxy.fill.pos_abs_x || pro->proxy.fill.pos_abs_y) BUF_APPENDF(I7"offset: %d %d;\n", pro->proxy.fill.pos_abs_x, pro->proxy.fill.pos_abs_y); BUF_APPEND(I6"}\n"); } if (TO_DOUBLE(pro->proxy.fill.rel_x) != 1.0 || TO_DOUBLE(pro->proxy.fill.rel_y) != 1.0 || pro->proxy.fill.abs_x || pro->proxy.fill.abs_y) { BUF_APPEND(I6"size {\n"); if (pro->proxy.fill.rel_x != 1.0 || pro->proxy.fill.rel_y != 1.0) BUF_APPENDF(I7"relative: %g %g;\n", TO_DOUBLE(pro->proxy.fill.rel_x), TO_DOUBLE(pro->proxy.fill.rel_y)); if (pro->proxy.fill.abs_x || pro->proxy.fill.abs_y) BUF_APPENDF(I7"offset: %d %d;\n", pro->proxy.fill.abs_x, pro->proxy.fill.abs_y); BUF_APPEND(I6"}\n"); } BUF_APPEND(I5"}\n"); } //Text if (rp->part->type == EDJE_PART_TYPE_TEXT) { Edje_Part_Description_Text *txt; txt = (Edje_Part_Description_Text *) pd; BUF_APPEND(I5"text {\n"); if (edje_string_get(&txt->text.text)) { if (txt->text.text.id) BUF_APPENDF(I6"text: _(\"%s\");\n", edje_string_id_get(&txt->text.text)); else BUF_APPENDF(I6"text: \"%s\";\n", edje_string_get(&txt->text.text)); } if (edje_string_get(&txt->text.font)) { if (txt->text.font.id) BUF_APPENDF(I6"font: _(\"%s\");\n", edje_string_id_get(&txt->text.font)); else BUF_APPENDF(I6"font: \"%s\";\n", edje_string_get(&txt->text.font)); } if (txt->text.size) BUF_APPENDF(I6"size: %d;\n", txt->text.size); if (txt->text.text_class) BUF_APPENDF(I6"text_class: \"%s\";\n", txt->text.text_class); if (txt->text.fit_x || txt->text.fit_y) BUF_APPENDF(I6"fit: %d %d;\n", txt->text.fit_x, txt->text.fit_y); if (txt->text.min_x || txt->text.min_y) BUF_APPENDF(I6"min: \"%d\" \"%d\";\n", txt->text.min_x, txt->text.min_y); if (txt->text.max_x || txt->text.max_y) BUF_APPENDF(I6"max: %d %d;\n", txt->text.max_x, txt->text.max_y); if (TO_DOUBLE(txt->text.align.x) != 0.5 || TO_DOUBLE(txt->text.align.y) != 0.5) BUF_APPENDF(I6"align: %g %g;\n", TO_DOUBLE(txt->text.align.x), TO_DOUBLE(txt->text.align.y)); //TODO Support source //TODO Support text_source if (txt->text.ellipsis) BUF_APPENDF(I6"ellipsis: %g;\n", txt->text.ellipsis); BUF_APPEND(I5"}\n"); } //External if (rp->part->type == EDJE_PART_TYPE_EXTERNAL) { if ((ll = (Eina_List *)edje_edit_state_external_params_list_get(obj, part, state, value))) { Edje_External_Param *p; BUF_APPEND(I5"params {\n"); EINA_LIST_FOREACH(ll, l, p) { switch (p->type) { case EDJE_EXTERNAL_PARAM_TYPE_INT: BUF_APPENDF(I6"int: \"%s\" \"%d\";\n", p->name, p->i); break; case EDJE_EXTERNAL_PARAM_TYPE_DOUBLE: BUF_APPENDF(I6"double: \"%s\" \"%g\";\n", p->name, p->d); break; case EDJE_EXTERNAL_PARAM_TYPE_STRING: if (p->s) BUF_APPENDF(I6"string: \"%s\" \"%s\";\n", p->name, p->s); break; case EDJE_EXTERNAL_PARAM_TYPE_BOOL: BUF_APPENDF(I6"bool: \"%s\" \"%d\";\n", p->name, p->i); break; case EDJE_EXTERNAL_PARAM_TYPE_CHOICE: if (p->s) BUF_APPENDF(I6"choice: \"%s\" \"%s\";\n", p->name, p->s); break; default: break; } } BUF_APPEND(I5"}\n"); } } BUF_APPEND(I4"}\n");//description return ret; } static Eina_Bool _edje_generate_source_of_part(Evas_Object *obj, Edje_Part *ep, Eina_Strbuf *buf) { const char *part = ep->name; const char *str; Eina_List *l, *ll; char *data; Eina_Bool ret = EINA_TRUE; const char *api_name, *api_description; BUF_APPENDF(I3"part { name: \"%s\";\n", part); BUF_APPENDF(I4"type: %s;\n", types[edje_edit_part_type_get(obj, part)]); if (!edje_edit_part_mouse_events_get(obj, part)) BUF_APPEND(I4"mouse_events: 0;\n"); if (edje_edit_part_repeat_events_get(obj, part)) BUF_APPEND(I4"repeat_events: 1;\n"); if (edje_edit_part_scale_get(obj, part)) BUF_APPEND(I4"scale: 1;\n"); //TODO Support ignore_flags if (edje_edit_part_pointer_mode_get(obj, part) == EVAS_OBJECT_POINTER_MODE_NOGRAB) BUF_APPEND(I4"pointer_mode: NOGRAB;\n"); if (edje_edit_part_precise_is_inside_get(obj, part)) BUF_APPEND(I4"precise_is_inside: 1;\n"); if (edje_edit_part_access_get(obj, part)) BUF_APPEND(I4"access: 1;\n"); //TODO Support use_alternate_font_metrics if ((str = edje_edit_part_clip_to_get(obj, part))) { BUF_APPENDF(I4"clip_to: \"%s\";\n", str); edje_edit_string_free(str); } if ((str = edje_edit_part_source_get(obj, part))) { BUF_APPENDF(I4"source: \"%s\";\n", str); edje_edit_string_free(str); } if (edje_edit_part_effect_get(obj, part)) { int effect = edje_edit_part_effect_get(obj, part); if (effect & EDJE_TEXT_EFFECT_MASK_SHADOW_DIRECTION) { BUF_APPENDF(I4"effect: %s %s;\n", effects[effect & ~EDJE_TEXT_EFFECT_MASK_SHADOW_DIRECTION], shadow_direction[effect >> 4]); } else BUF_APPENDF(I4"effect: %s;\n", effects[effect]); } //Dragable if (edje_edit_part_drag_x_get(obj, part) || edje_edit_part_drag_y_get(obj, part)) { BUF_APPEND(I4"dragable {\n"); BUF_APPENDF(I5"x: %d %d %d;\n", edje_edit_part_drag_x_get(obj, part), edje_edit_part_drag_step_x_get(obj, part), edje_edit_part_drag_count_x_get(obj, part)); BUF_APPENDF(I5"y: %d %d %d;\n", edje_edit_part_drag_y_get(obj, part), edje_edit_part_drag_step_y_get(obj, part), edje_edit_part_drag_count_y_get(obj, part)); if ((str = edje_edit_part_drag_confine_get(obj, part))) { BUF_APPENDF(I5"confine: \"%s\";\n", str); edje_edit_string_free(str); } if ((str = edje_edit_part_drag_event_get(obj, part))) { BUF_APPENDF(I5"events: \"%s\";\n", str); edje_edit_string_free(str); } BUF_APPEND(I4"}\n"); } //Descriptions ll = edje_edit_part_states_list_get(obj, part); EINA_LIST_FOREACH(ll, l, data) { char state[512], *delim; double value; strncpy(state, data, sizeof(state) - 1); /* if we go over it, too bad.. the list of states may need to change to provide name and value separated */ delim = strchr(state, ' '); if (!delim) continue; *delim = '\0'; delim++; value = strtod(delim, NULL); ret &= _edje_generate_source_of_state(obj, part, state, value, buf); } edje_edit_string_list_free(ll); api_name = edje_edit_part_api_name_get(obj, part); api_description = edje_edit_part_api_description_get(obj, part); if (api_name || api_description) { if (api_name && api_description) { BUF_APPENDF(I4"api: \"%s\" \"%s\";\n", api_name, api_description); edje_edit_string_free(api_name); edje_edit_string_free(api_description); } else if (api_name) { BUF_APPENDF(I4"api: \"%s\" \"\";\n", api_name); edje_edit_string_free(api_name); } else { BUF_APPENDF(I4"api: \"\" \"%s\";\n", api_description); edje_edit_string_free(api_description); } } BUF_APPEND(I3"}\n");//part return ret; } static Eina_Bool _edje_generate_source_of_group(Edje *ed, Edje_Part_Collection_Directory_Entry *pce, Eina_Strbuf *buf) { Edje_Edit *eed; Eet_File *ef; Evas_Object *obj; Eina_List *l, *ll; unsigned int i; int w, h; char *data; const char *group = pce->entry; Edje_Part_Collection *pc; Eina_Bool ret = EINA_TRUE; Eina_List *alias_list = NULL; obj = edje_edit_object_add(ed->base->evas); if (!edje_object_file_set(obj, ed->file->path, group)) return EINA_FALSE; ef = eet_open(ed->file->path, EET_FILE_MODE_READ); if (!ef) { evas_object_del(obj); return EINA_FALSE; } eed = eo_data_scope_get(obj, MY_CLASS); pc = eed->base->collection; alias_list = edje_edit_group_aliases_get(obj, group); BUF_APPENDF(I1"group { name: \"%s\";\n", group); EINA_LIST_FOREACH(alias_list, l, data) BUF_APPENDF(I2"alias: \"%s\";\n", data); edje_edit_string_list_free(alias_list); w = edje_edit_group_min_w_get(obj); h = edje_edit_group_min_h_get(obj); if ((w > 0) || (h > 0)) BUF_APPENDF(I2"min: %d %d;\n", w, h); w = edje_edit_group_max_w_get(obj); h = edje_edit_group_max_h_get(obj); if ((w > 0) || (h > 0)) BUF_APPENDF(I2"max: %d %d;\n", w, h); /* Data */ if (pc->data) { Eina_Iterator *it; Eina_Hash_Tuple *tuple; BUF_APPEND(I2"data {\n"); it = eina_hash_iterator_tuple_new(pc->data); if (!it) { ERR("Generating EDC for Group[%s] data.", group); return EINA_FALSE; } EINA_ITERATOR_FOREACH(it, tuple) BUF_APPENDF(I3"item: \"%s\" \"%s\";\n", (char *)tuple->key, edje_string_get(tuple->data)); eina_iterator_free(it); BUF_APPEND(I2"}\n"); } if (eed->embryo_source) { BUF_APPEND(I2"script {\n"); BUF_APPEND(eed->embryo_source); BUF_APPEND(I2"}\n"); } /* Parts */ BUF_APPEND(I2"parts {\n"); for (i = 0; i < pc->parts_count; i++) { Edje_Part *ep; ep = pc->parts[i]; ret &= _edje_generate_source_of_part(obj, ep, buf); } BUF_APPEND(I2"}\n");//parts if (!ret) { ERR("Generating EDC for Group[%s] Parts.", group); return EINA_FALSE; } /* Programs */ if ((ll = edje_edit_programs_list_get(obj))) { BUF_APPEND(I2 "programs {\n"); EINA_LIST_FOREACH(ll, l, data) ret &= _edje_generate_source_of_program(obj, data, buf); BUF_APPEND(I2 "}\n"); edje_edit_string_list_free(ll); } BUF_APPEND(I1"}\n");//group if (!ret) { ERR("Generating EDC for Group[%s] Programs.", group); evas_object_del(obj); return EINA_FALSE; } eet_close(ef); evas_object_del(obj); return ret; } static Eina_Strbuf* _edje_generate_source(Evas_Object *obj) { Eina_Strbuf *buf; Eina_List *l, *ll; Edje_Font_Directory_Entry *fnt; char *entry; Eina_Bool ret = EINA_TRUE; GET_ED_OR_RETURN(NULL); /* Open a str buffer */ buf = eina_strbuf_new(); if (!buf) return NULL; /* Write edc into file */ //TODO Probably we need to save the file before generation /* Images */ if ((ll = edje_edit_images_list_get(obj))) { BUF_APPEND(I0"images {\n"); EINA_LIST_FOREACH(ll, l, entry) { const char *image_source = _edje_generate_image_source(obj, entry); if (!image_source) continue; BUF_APPENDF(I1"%s", image_source); } BUF_APPEND(I0"}\n\n"); edje_edit_string_list_free(ll); if (!ret) { ERR("Generating EDC for Images"); eina_strbuf_free(buf); return NULL; } } /* Fonts */ if (ed->file->fonts) { Eina_Iterator *it; it = eina_hash_iterator_data_new(ed->file->fonts); if (it) { BUF_APPEND(I0"fonts {\n"); EINA_ITERATOR_FOREACH(it, fnt) BUF_APPENDF(I1"font: \"%s\" \"%s\";\n", fnt->file, fnt->entry); BUF_APPEND(I0"}\n\n"); eina_iterator_free(it); if (!ret) { ERR("Generating EDC for Fonts"); eina_strbuf_free(buf); return NULL; } } } /* Data */ if ((ll = edje_edit_data_list_get(obj))) { BUF_APPEND(I0 "data {\n"); EINA_LIST_FOREACH(ll, l, entry) BUF_APPENDF(I1 "item: \"%s\" \"%s\";\n", entry, edje_edit_data_value_get(obj, entry)); BUF_APPEND(I0 "}\n\n"); edje_edit_string_list_free(ll); if (!ret) { ERR("Generating EDC for Data"); eina_strbuf_free(buf); return NULL; } } /* Color Classes */ if ((ll = edje_edit_color_classes_list_get(obj))) { BUF_APPEND(I0 "color_classes {\n"); EINA_LIST_FOREACH(ll, l, entry) _edje_generate_source_of_colorclass(ed, entry, buf); BUF_APPEND(I0 "}\n\n"); edje_edit_string_list_free(ll); if (!ret) { ERR("Generating EDC for Color Classes"); eina_strbuf_free(buf); return NULL; } } /* Styles */ if ((ll = edje_edit_styles_list_get(obj))) { BUF_APPEND(I0 "styles {\n"); EINA_LIST_FOREACH(ll, l, entry) _edje_generate_source_of_style(ed, entry, buf); BUF_APPEND(I0 "}\n\n"); edje_edit_string_list_free(ll); if (!ret) { ERR("Generating EDC for Styles"); eina_strbuf_free(buf); return NULL; } } /* Externals */ if ((ll = edje_edit_externals_list_get(obj))) { BUF_APPEND(I0 "externals {\n"); EINA_LIST_FOREACH(ll, l, entry) BUF_APPENDF(I1 "external: \"%s\";\n", entry); BUF_APPEND(I0 "}\n\n"); edje_edit_string_list_free(ll); if (!ret) { ERR("Generating EDC for Externals"); eina_strbuf_free(buf); return NULL; } } /* Collections */ if (ed->file->collection) { Eina_Iterator *it; Edje_Part_Collection_Directory_Entry *pce; BUF_APPEND("collections {\n"); it = eina_hash_iterator_data_new(ed->file->collection); if (!it) { ERR("Generating EDC for Collections"); eina_strbuf_free(buf); return NULL; } EINA_ITERATOR_FOREACH(it, pce) { if (!pce->group_alias) ret &= _edje_generate_source_of_group(ed, pce, buf); } eina_iterator_free(it); BUF_APPEND("}\n\n"); } return buf; } /*********************/ /* SAVING ROUTINES */ /*********************/ //////////////////////////////////////// typedef struct _SrcFile SrcFile; typedef struct _SrcFile_List SrcFile_List; struct _SrcFile { char *name; const char *file; }; struct _SrcFile_List { Eina_List *list; }; static Eet_Data_Descriptor *_srcfile_edd = NULL; static Eet_Data_Descriptor *_srcfile_list_edd = NULL; static void source_edd(void) { Eet_Data_Descriptor_Class eddc; if (_srcfile_edd) return; eet_eina_stream_data_descriptor_class_set(&eddc, sizeof (eddc), "srcfile", sizeof(SrcFile)); _srcfile_edd = eet_data_descriptor_stream_new(&eddc); EET_DATA_DESCRIPTOR_ADD_BASIC(_srcfile_edd, SrcFile, "name", name, EET_T_INLINED_STRING); EET_DATA_DESCRIPTOR_ADD_BASIC(_srcfile_edd, SrcFile, "file", file, EET_T_INLINED_STRING); eet_eina_stream_data_descriptor_class_set(&eddc, sizeof (eddc), "srcfile_list", sizeof(SrcFile_List)); _srcfile_list_edd = eet_data_descriptor_stream_new(&eddc); EET_DATA_DESCRIPTOR_ADD_LIST(_srcfile_list_edd, SrcFile_List, "list", list, _srcfile_edd); } ///////////////////////////////////////// static Eina_Bool _edje_edit_edje_file_save(Eet_File *eetf, Edje_File *ef) { /* Write Edje_File structure */ INF("** Writing Edje_File* ed->file"); if (eet_data_write(eetf, _edje_edd_edje_file, "edje/file", ef, 1) <= 0) { ERR("Error. unable to write \"edje_file\" entry to \"%s\"", ef->path); return EINA_FALSE; } return EINA_TRUE; } static Eina_Bool _edje_edit_collection_save(Eet_File *eetf, Edje_Part_Collection *epc) { char buf[256]; snprintf(buf, sizeof(buf), "edje/collections/%i", epc->id); if (eet_data_write(eetf, _edje_edd_edje_part_collection, buf, epc, 1) > 0) return EINA_TRUE; ERR("Error. unable to write \"%s\" part entry", buf); return EINA_FALSE; } static Eina_Bool _edje_edit_source_save(Eet_File *eetf, Evas_Object *obj) { SrcFile *sf; SrcFile_List *sfl; Eina_Strbuf *source_file; Eina_Bool ret = EINA_TRUE; source_file = _edje_generate_source(obj); if (!source_file) { ERR("Can't create edc source"); return EINA_FALSE; } //open the temp file and put the contents in SrcFile sf = _alloc(sizeof(SrcFile)); if (!sf) { ERR("Unable to create source file struct"); ret = EINA_FALSE; goto save_free_source; } sf->name = strdup("generated_source.edc"); if (!sf->name) { ERR("Unable to alloc filename"); ret = EINA_FALSE; goto save_free_sf; } sf->file = eina_strbuf_string_get(source_file); //create the needed list of source files (only one) sfl = _alloc(sizeof(SrcFile_List)); if (!sfl) { ERR("Unable to create file list"); ret = EINA_FALSE; goto save_free_filename; } sfl->list = NULL; sfl->list = eina_list_append(sfl->list, sf); if (!sfl->list) { ERR("Error. unable to append file in list"); ret = EINA_FALSE; goto save_free_sfl; } // write the sources list to the eet file source_edd(); if (eet_data_write(eetf, _srcfile_list_edd, "edje_sources", sfl, 1) <= 0) { ERR("Unable to write edc source"); ret = EINA_FALSE; } /* Clear stuff */ eina_list_free(sfl->list); save_free_sfl: free(sfl); save_free_filename: free(sf->name); save_free_sf: free(sf); save_free_source: eina_strbuf_free(source_file); return ret; } Eina_Bool _edje_edit_internal_save(Evas_Object *obj, int current_only) { Edje_File *ef; Eet_File *eetf; GET_EED_OR_RETURN(EINA_FALSE); GET_ED_OR_RETURN(EINA_FALSE); ef = ed->file; if (!ef) return EINA_FALSE; INF("*********** Saving file ******************"); INF("** path: %s", ef->path); /* Open the eet file */ eetf = eet_open(ef->path, EET_FILE_MODE_READ_WRITE); if (!eetf) { ERR("Error. unable to open \"%s\" for writing output", ef->path); return EINA_FALSE; } /* Set compiler name */ if (strcmp(ef->compiler, "edje_edit")) { _edje_if_string_free(ed, ef->compiler); ef->compiler = (char *)eina_stringshare_add("edje_edit"); } if (!_edje_edit_edje_file_save(eetf, ef)) { eet_close(eetf); return EINA_FALSE; } if (current_only) { if (ed->collection) { INF("** Writing Edje_Part_Collection* ed->collection " "[id: %d]", ed->collection->id); if (!_edje_edit_collection_save(eetf, ed->collection)) { eet_close(eetf); return EINA_FALSE; } } } else { Eina_List *l; Edje_Part_Collection *edc; Edje_Part_Collection_Directory_Entry *ce; Eina_Iterator *it; INF("** Writing all collections"); it = eina_hash_iterator_data_new(ef->collection); while (eina_iterator_next(it, (void **)&ce)) { if (ce->ref) { INF("** Writing hash Edje_Part_Collection* ed->collection " "[id: %d]", ce->id); if(!_edje_edit_collection_save(eetf, ce->ref)) { eet_close(eetf); return EINA_FALSE; } } } eina_iterator_free(it); EINA_LIST_FOREACH(ef->collection_cache, l, edc) { INF("** Writing cache Edje_Part_Collection* ed->collection " "[id: %d]", edc->id); if(!_edje_edit_collection_save(eetf, edc)) { eet_close(eetf); return EINA_FALSE; } } } if (eed->bytecode_dirty || eed->script_need_recompile) { char buf[64]; Eina_Iterator *it; Program_Script *ps; Eina_List *deathnote = NULL; if (eed->bytecode_dirty) { snprintf(buf, sizeof(buf), "edje/scripts/embryo/compiled/%i", ed->collection->id); eet_write(eetf, buf, eed->bytecode, eed->bytecode_size, 1); free(eed->bytecode); eed->bytecode = NULL; eed->bytecode_size = 0; eed->bytecode_dirty = EINA_FALSE; } if (eed->embryo_source_dirty) { snprintf(buf, sizeof(buf), "edje/scripts/embryo/source/%i", ed->collection->id); eet_write(eetf, buf, eed->embryo_source, strlen(eed->embryo_source) + 1, 1); eed->embryo_source_dirty = EINA_FALSE; } it = eina_hash_iterator_data_new(eed->program_scripts); EINA_ITERATOR_FOREACH(it, ps) { if (ps->dirty) { snprintf(buf, sizeof(buf), "edje/scripts/embryo/source/%i/%i", ed->collection->id, ps->id); eet_write(eetf, buf, ps->code, strlen(ps->code) + 1, 1); ps->dirty = EINA_FALSE; } else if (ps->delete_me) { snprintf(buf, sizeof(buf), "edje/scripts/embryo/source/%i/%i", ed->collection->id, ps->id); eet_delete(eetf, buf); deathnote = eina_list_append(deathnote, ps); } } eina_iterator_free(it); EINA_LIST_FREE(deathnote, ps) eina_hash_del(eed->program_scripts, &ps->id, ps); } if (!_edje_edit_source_save(eetf, obj)) { eet_close(eetf); return EINA_FALSE; } eet_close(eetf); /* Update mtime */ { struct stat st; if (stat(ed->path, &st) != 0) return EINA_FALSE; ef->mtime = st.st_mtime; } INF("*********** Saving DONE ******************"); return EINA_TRUE; } EAPI Eina_Bool edje_edit_save(Evas_Object *obj) { return _edje_edit_internal_save(obj, 1); } EAPI Eina_Bool edje_edit_save_all(Evas_Object *obj) { return _edje_edit_internal_save(obj, 0); } EAPI void edje_edit_print_internal_status(Evas_Object *obj) { /* Edje_Program *epr; unsigned int i; int j; */ Eina_Strbuf *source_file; GET_EED_OR_RETURN(); source_file =_edje_generate_source(obj); if (source_file) eina_strbuf_free(source_file); /* INF("****** CHECKIN' INTERNAL STRUCTS STATUS *********"); INF("path: '%s', group: '%s', parent: '%s'", ed->path, ed->group, ed->parent); INF("Parts [table:%d list:%d]", ed->table_parts_size, ed->collection->parts_count); for (i = 0; i < ed->collection->parts_count; ++i) { Edje_Real_Part *rp; Edje_Part *p; p = ed->collection->parts[i]; rp = ed->table_parts[p->id % ed->table_parts_size]; printf("part[%d]: '%s' ", p->id, p->name); if (p == rp->part) printf("OK!\n"); else printf("WRONG (table[%d]->name = '%s')\n", p->id, rp->part->name); } INF("Programs [table:%d list:%d,%d,%d,%d,%d]", ed->table_programs_size, 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); for(j = 0; j < ed->table_programs_size; ++j) { epr = ed->table_programs[i % ed->table_programs_size]; printf("program[%d]: '%s'\n", epr->id, epr->name); } INF("****************** END ************************"); */ } #include "edje_edit.eo.c"