From deb0057d7fccf7973e918e2e9510610fce5a4ab8 Mon Sep 17 00:00:00 2001 From: Cedric BAIL Date: Fri, 6 Jan 2012 11:28:38 +0000 Subject: [PATCH] edje: add EDJE_ASPECT_PREFER_SOURCE. NOTE: this is a prototype, play with and report any issue to me. SVN revision: 66937 --- legacy/edje/ChangeLog | 1 + legacy/edje/NEWS | 1 + legacy/edje/src/bin/edje_cc_handlers.c | 3 +- legacy/edje/src/lib/edje_calc.c | 373 +++++++++++++------------ legacy/edje/src/lib/edje_private.h | 3 +- 5 files changed, 205 insertions(+), 176 deletions(-) diff --git a/legacy/edje/ChangeLog b/legacy/edje/ChangeLog index ef648ab65e..9dd1453701 100644 --- a/legacy/edje/ChangeLog +++ b/legacy/edje/ChangeLog @@ -270,3 +270,4 @@ 2012-01-06 Cedric Bail * Unswallow object that are about to be swallowed if necessary. + * Add EDJE_ASPECT_PREFER_SOURCE. diff --git a/legacy/edje/NEWS b/legacy/edje/NEWS index c73e711a40..1b38efb0b6 100644 --- a/legacy/edje/NEWS +++ b/legacy/edje/NEWS @@ -6,6 +6,7 @@ Changes since Edje 1.1.0: Additions: * "recalc" smart callback for object size changes + * EDJE_ASPECT_PREFER_SOURCE. Improvements: * speedup load time of Edje file. diff --git a/legacy/edje/src/bin/edje_cc_handlers.c b/legacy/edje/src/bin/edje_cc_handlers.c index 6a3e58c41f..7535b3157a 100644 --- a/legacy/edje/src/bin/edje_cc_handlers.c +++ b/legacy/edje/src/bin/edje_cc_handlers.c @@ -4621,7 +4621,7 @@ st_collections_group_parts_part_description_aspect(void) [DIMENSION] @effect Sets the scope of the "aspect" property to a given dimension. Available - options are BOTH, VERTICAL, HORIZONTAL and NONE + options are BOTH, VERTICAL, HORIZONTAL, SOURCE and NONE @endproperty */ static void @@ -4634,6 +4634,7 @@ st_collections_group_parts_part_description_aspect_preference(void) "VERTICAL", EDJE_ASPECT_PREFER_VERTICAL, "HORIZONTAL", EDJE_ASPECT_PREFER_HORIZONTAL, "BOTH", EDJE_ASPECT_PREFER_BOTH, + "SOURCE", EDJE_ASPECT_PREFER_SOURCE, NULL); } diff --git a/legacy/edje/src/lib/edje_calc.c b/legacy/edje/src/lib/edje_calc.c index 5266d9b413..8e7e7cec7f 100644 --- a/legacy/edje/src/lib/edje_calc.c +++ b/legacy/edje/src/lib/edje_calc.c @@ -8,7 +8,8 @@ static void _edje_part_recalc_single(Edje *ed, Edje_Real_Part *ep, Edje_Real_Part *center, Edje_Real_Part *light, Edje_Real_Part *persp, Edje_Real_Part *rel1_to_x, Edje_Real_Part *rel1_to_y, Edje_Real_Part *rel2_to_x, Edje_Real_Part *rel2_to_y, - Edje_Real_Part *confine_to, Edje_Calc_Params *params); + Edje_Real_Part *confine_to, Edje_Calc_Params *params, + FLOAT_T pos); void _edje_part_pos_set(Edje *ed, Edje_Real_Part *ep, int mode, FLOAT_T pos, FLOAT_T v1, FLOAT_T v2) @@ -304,6 +305,179 @@ _edje_part_description_find(Edje *ed, Edje_Real_Part *rp, const char *name, return ret; } +static int +_edje_image_find(Evas_Object *obj, Edje *ed, Edje_Real_Part_Set **eps, Edje_Part_Description_Image *st, Edje_Part_Image_Id *imid) +{ + Edje_Image_Directory_Set_Entry *entry; + Edje_Image_Directory_Set *set = NULL; + Eina_List *l; + int w = 0; + int h = 0; + int id; + + if (!st && !imid) + return -1; + + if (st && !st->image.set) + return st->image.id; + + if (imid && !imid->set) + return imid->id; + + if (imid) + id = imid->id; + else + id = st->image.id; + + evas_object_geometry_get(obj, NULL, NULL, &w, &h); + + if (eps && *eps) + { + if ((*eps)->id == id) + set = (*eps)->set; + + if (set) + if ((*eps)->entry->size.min.w <= w && w <= (*eps)->entry->size.max.w) + if ((*eps)->entry->size.min.h <= h && h <= (*eps)->entry->size.max.h) + return (*eps)->entry->id; + } + + if (!set) + set = ed->file->image_dir->sets + id; + + EINA_LIST_FOREACH(set->entries, l, entry) + { + if (entry->size.min.w <= w && w <= entry->size.max.w) + if (entry->size.min.h <= h && h <= entry->size.max.h) + { + if (eps) + { + if (!*eps) + *eps = calloc(1, sizeof (Edje_Real_Part_Set)); + + if (*eps) + { + (*eps)->entry = entry; + (*eps)->set = set; + (*eps)->id = id; + } + } + return entry->id; + } + } + + return -1; +} + +static void +_edje_real_part_image_set(Edje *ed, Edje_Real_Part *ep, FLOAT_T pos) +{ + int image_id; + int image_count, image_num; + + image_id = _edje_image_find(ep->object, ed, + &ep->param1.set, + (Edje_Part_Description_Image*) ep->param1.description, + NULL); + if (image_id < 0) + { + Edje_Image_Directory_Entry *ie; + + if (!ed->file->image_dir) ie = NULL; + else ie = ed->file->image_dir->entries + (-image_id) - 1; + if ((ie) && + (ie->source_type == EDJE_IMAGE_SOURCE_TYPE_EXTERNAL) && + (ie->entry)) + { + evas_object_image_file_set(ep->object, ie->entry, NULL); + } + } + else + { + image_count = 2; + if (ep->param2) + image_count += ((Edje_Part_Description_Image*) ep->param2->description)->image.tweens_count; + image_num = TO_INT(MUL(pos, SUB(FROM_INT(image_count), + FROM_DOUBLE(0.5)))); + if (image_num > (image_count - 1)) + image_num = image_count - 1; + if (image_num == 0) + { + image_id = _edje_image_find(ep->object, ed, + &ep->param1.set, + (Edje_Part_Description_Image*) ep->param1.description, + NULL); + } + else + if (ep->param2) + { + if (image_num == (image_count - 1)) + { + image_id = _edje_image_find(ep->object, ed, + &ep->param2->set, + (Edje_Part_Description_Image*) ep->param2->description, + NULL); + } + else + { + Edje_Part_Image_Id *imid; + + imid = ((Edje_Part_Description_Image*) ep->param2->description)->image.tweens[image_num - 1]; + image_id = _edje_image_find(ep->object, ed, NULL, NULL, imid); + } + } + if (image_id < 0) + { + ERR("¨Part \"%s\" has description, " + "\"%s\" %3.3f with a missing image id!!!", + ep->part->name, + ep->param1.description->state.name, + ep->param1.description->state.value); + } + else + { + char buf[1024]; + + /* Replace snprint("edje/images/%i") == memcpy + itoa */ +#define IMAGES "edje/images/" + memcpy(buf, IMAGES, strlen(IMAGES)); + eina_convert_itoa(image_id, buf + strlen(IMAGES)); /* No need to check length as 2³² need only 10 characteres. */ + + evas_object_image_file_set(ep->object, ed->file->path, buf); + if (evas_object_image_load_error_get(ep->object) != EVAS_LOAD_ERROR_NONE) + { + ERR("Error loading image collection \"%s\" from " + "file \"%s\". Missing EET Evas loader module?", + buf, ed->file->path); + switch (evas_object_image_load_error_get(ep->object)) + { + case EVAS_LOAD_ERROR_GENERIC: + ERR("Error type: EVAS_LOAD_ERROR_GENERIC"); + break; + case EVAS_LOAD_ERROR_DOES_NOT_EXIST: + ERR("Error type: EVAS_LOAD_ERROR_DOES_NOT_EXIST"); + break; + case EVAS_LOAD_ERROR_PERMISSION_DENIED: + ERR("Error type: EVAS_LOAD_ERROR_PERMISSION_DENIED"); + break; + case EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED: + ERR("Error type: EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED"); + break; + case EVAS_LOAD_ERROR_CORRUPT_FILE: + ERR("Error type: EVAS_LOAD_ERROR_CORRUPT_FILE"); + break; + case EVAS_LOAD_ERROR_UNKNOWN_FORMAT: + ERR("Error type: EVAS_LOAD_ERROR_UNKNOWN_FORMAT"); + break; + default: + ERR("Error type: ???"); + break; + } + } + } + } +} + static void _edje_real_part_rel_to_apply(Edje *ed, Edje_Real_Part *ep, Edje_Real_Part_State *state) { @@ -608,11 +782,13 @@ _edje_part_recalc_single_rel(Edje *ed, } static Edje_Internal_Aspect -_edje_part_recalc_single_aspect(Edje_Real_Part *ep, +_edje_part_recalc_single_aspect(Edje *ed, + Edje_Real_Part *ep, Edje_Part_Description_Common *desc, Edje_Calc_Params *params, int *minw, int *minh, - int *maxw, int *maxh) + int *maxw, int *maxh, + FLOAT_T pos) { Edje_Internal_Aspect apref = EDJE_ASPECT_PREFER_NONE; FLOAT_T aspect, amax, amin; @@ -622,6 +798,17 @@ _edje_part_recalc_single_aspect(Edje_Real_Part *ep, else aspect = DIV(FROM_INT(params->w), FROM_INT(params->h)); amax = desc->aspect.max; amin = desc->aspect.min; + if (desc->aspect.prefer == EDJE_ASPECT_PREFER_SOURCE && + ep->part->type == EDJE_PART_TYPE_IMAGE) + { + Evas_Coord w, h; + + /* We only need pose to find the right image that would be displayed, + and the right aspect ratio in that case */ + _edje_real_part_image_set(ed, ep, pos); + evas_object_image_size_get(ep->object, &w, &h); + amin = amax = DIV(FROM_INT(w), FROM_INT(h)); + } if ((ep->swallow_params.aspect.w > 0) && (ep->swallow_params.aspect.h > 0)) amin = amax = @@ -703,6 +890,7 @@ _edje_part_recalc_single_aspect(Edje_Real_Part *ep, if ((amin > ZERO) && (aspect < amin)) new_h = DIV(FROM_INT(params->w), amin); break; + case EDJE_ASPECT_PREFER_SOURCE: case EDJE_ASPECT_PREFER_BOTH: /* keep both dimensions in check */ /* adjust for max aspect (width / height) */ @@ -1265,6 +1453,7 @@ _edje_part_recalc_single_min(Edje_Part_Description_Common *desc, minh = tmp; break; } + case EDJE_ASPECT_PREFER_SOURCE: case EDJE_ASPECT_PREFER_BOTH: tmp = minh * params->w / h; if (tmp >= minw) @@ -1331,6 +1520,7 @@ _edje_part_recalc_single_max(Edje_Part_Description_Common *desc, maxh = tmp; break; } + case EDJE_ASPECT_PREFER_SOURCE: case EDJE_ASPECT_PREFER_BOTH: tmp = maxh * params->w / h; if (tmp <= maxw) @@ -1675,7 +1865,8 @@ _edje_part_recalc_single(Edje *ed, Edje_Real_Part *rel2_to_x, Edje_Real_Part *rel2_to_y, Edje_Real_Part *confine_to, - Edje_Calc_Params *params) + Edje_Calc_Params *params, + FLOAT_T pos) { Edje_Color_Class *cc = NULL; Edje_Internal_Aspect apref; @@ -1690,7 +1881,7 @@ _edje_part_recalc_single(Edje *ed, _edje_part_recalc_single_rel(ed, ep, desc, rel1_to_x, rel1_to_y, rel2_to_x, rel2_to_y, params); /* aspect */ - apref = _edje_part_recalc_single_aspect(ep, desc, params, &minw, &minh, &maxw, &maxh); + apref = _edje_part_recalc_single_aspect(ed, ep, desc, params, &minw, &minh, &maxw, &maxh, pos); /* size step */ _edje_part_recalc_single_step(desc, params); @@ -1865,70 +2056,6 @@ _edje_table_recalc_apply(Edje *ed __UNUSED__, } } -static int -_edje_image_find(Evas_Object *obj, Edje *ed, Edje_Real_Part_Set **eps, Edje_Part_Description_Image *st, Edje_Part_Image_Id *imid) -{ - Edje_Image_Directory_Set_Entry *entry; - Edje_Image_Directory_Set *set = NULL; - Eina_List *l; - int w = 0; - int h = 0; - int id; - - if (!st && !imid) - return -1; - - if (st && !st->image.set) - return st->image.id; - - if (imid && !imid->set) - return imid->id; - - if (imid) - id = imid->id; - else - id = st->image.id; - - evas_object_geometry_get(obj, NULL, NULL, &w, &h); - - if (eps && *eps) - { - if ((*eps)->id == id) - set = (*eps)->set; - - if (set) - if ((*eps)->entry->size.min.w <= w && w <= (*eps)->entry->size.max.w) - if ((*eps)->entry->size.min.h <= h && h <= (*eps)->entry->size.max.h) - return (*eps)->entry->id; - } - - if (!set) - set = ed->file->image_dir->sets + id; - - EINA_LIST_FOREACH(set->entries, l, entry) - { - if (entry->size.min.w <= w && w <= entry->size.max.w) - if (entry->size.min.h <= h && h <= entry->size.max.h) - { - if (eps) - { - if (!*eps) - *eps = calloc(1, sizeof (Edje_Real_Part_Set)); - - if (*eps) - { - (*eps)->entry = entry; - (*eps)->set = set; - (*eps)->id = id; - } - } - return entry->id; - } - } - - return -1; -} - static void _edje_proxy_recalc_apply(Edje *ed, Edje_Real_Part *ep, Edje_Calc_Params *p3, Edje_Part_Description_Proxy *chosen_desc, FLOAT_T pos) { @@ -1977,8 +2104,6 @@ _edje_proxy_recalc_apply(Edje *ed, Edje_Real_Part *ep, Edje_Calc_Params *p3, Edj static void _edje_image_recalc_apply(Edje *ed, Edje_Real_Part *ep, Edje_Calc_Params *p3, Edje_Part_Description_Image *chosen_desc, FLOAT_T pos) { - int image_id; - int image_count, image_num; FLOAT_T sc; sc = ed->scale; @@ -2013,107 +2138,7 @@ _edje_image_recalc_apply(Edje *ed, Edje_Real_Part *ep, Edje_Calc_Params *p3, Edj else if (chosen_desc->image.border.no_fill == 2) evas_object_image_border_center_fill_set(ep->object, EVAS_BORDER_FILL_SOLID); - image_id = _edje_image_find(ep->object, ed, - &ep->param1.set, - (Edje_Part_Description_Image*) ep->param1.description, - NULL); - if (image_id < 0) - { - Edje_Image_Directory_Entry *ie; - - if (!ed->file->image_dir) ie = NULL; - else ie = ed->file->image_dir->entries + (-image_id) - 1; - if ((ie) && - (ie->source_type == EDJE_IMAGE_SOURCE_TYPE_EXTERNAL) && - (ie->entry)) - { - evas_object_image_file_set(ep->object, ie->entry, NULL); - } - } - else - { - image_count = 2; - if (ep->param2) - image_count += ((Edje_Part_Description_Image*) ep->param2->description)->image.tweens_count; - image_num = TO_INT(MUL(pos, SUB(FROM_INT(image_count), - FROM_DOUBLE(0.5)))); - if (image_num > (image_count - 1)) - image_num = image_count - 1; - if (image_num == 0) - { - image_id = _edje_image_find(ep->object, ed, - &ep->param1.set, - (Edje_Part_Description_Image*) ep->param1.description, - NULL); - } - else - if (ep->param2) - { - if (image_num == (image_count - 1)) - { - image_id = _edje_image_find(ep->object, ed, - &ep->param2->set, - (Edje_Part_Description_Image*) ep->param2->description, - NULL); - } - else - { - Edje_Part_Image_Id *imid; - - imid = ((Edje_Part_Description_Image*) ep->param2->description)->image.tweens[image_num - 1]; - image_id = _edje_image_find(ep->object, ed, NULL, NULL, imid); - } - } - if (image_id < 0) - { - ERR("¨Part \"%s\" has description, " - "\"%s\" %3.3f with a missing image id!!!", - ep->part->name, - ep->param1.description->state.name, - ep->param1.description->state.value); - } - else - { - char buf[1024]; - - /* Replace snprint("edje/images/%i") == memcpy + itoa */ -#define IMAGES "edje/images/" - memcpy(buf, IMAGES, strlen(IMAGES)); - eina_convert_itoa(image_id, buf + strlen(IMAGES)); /* No need to check length as 2³² need only 10 characteres. */ - - evas_object_image_file_set(ep->object, ed->file->path, buf); - if (evas_object_image_load_error_get(ep->object) != EVAS_LOAD_ERROR_NONE) - { - ERR("Error loading image collection \"%s\" from " - "file \"%s\". Missing EET Evas loader module?", - buf, ed->file->path); - switch (evas_object_image_load_error_get(ep->object)) - { - case EVAS_LOAD_ERROR_GENERIC: - ERR("Error type: EVAS_LOAD_ERROR_GENERIC"); - break; - case EVAS_LOAD_ERROR_DOES_NOT_EXIST: - ERR("Error type: EVAS_LOAD_ERROR_DOES_NOT_EXIST"); - break; - case EVAS_LOAD_ERROR_PERMISSION_DENIED: - ERR("Error type: EVAS_LOAD_ERROR_PERMISSION_DENIED"); - break; - case EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED: - ERR("Error type: EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED"); - break; - case EVAS_LOAD_ERROR_CORRUPT_FILE: - ERR("Error type: EVAS_LOAD_ERROR_CORRUPT_FILE"); - break; - case EVAS_LOAD_ERROR_UNKNOWN_FORMAT: - ERR("Error type: EVAS_LOAD_ERROR_UNKNOWN_FORMAT"); - break; - default: - ERR("Error type: ???"); - break; - } - } - } - } + _edje_real_part_image_set(ed, ep, pos); } static Edje_Real_Part * @@ -2367,7 +2392,7 @@ _edje_part_recalc(Edje *ed, Edje_Real_Part *ep, int flags, Edje_Calc_Params *sta _edje_part_recalc_single(ed, ep, ep->param1.description, chosen_desc, center[0], light[0], persp[0], ep->param1.rel1_to_x, ep->param1.rel1_to_y, ep->param1.rel2_to_x, ep->param1.rel2_to_y, confine_to, - p1); + p1, pos); #ifdef EDJE_CALC_CACHE ep->param1.state = ed->state; @@ -2415,7 +2440,7 @@ _edje_part_recalc(Edje *ed, Edje_Real_Part *ep, int flags, Edje_Calc_Params *sta _edje_part_recalc_single(ed, ep, ep->param2->description, chosen_desc, center[1], light[1], persp[1], ep->param2->rel1_to_x, ep->param2->rel1_to_y, ep->param2->rel2_to_x, ep->param2->rel2_to_y, confine_to, - p2); + p2, pos); #ifdef EDJE_CALC_CACHE ep->param2->state = ed->state; #endif diff --git a/legacy/edje/src/lib/edje_private.h b/legacy/edje/src/lib/edje_private.h index 038f51cb3c..e170c5811e 100644 --- a/legacy/edje/src/lib/edje_private.h +++ b/legacy/edje/src/lib/edje_private.h @@ -192,7 +192,8 @@ typedef enum EDJE_ASPECT_PREFER_NONE, EDJE_ASPECT_PREFER_VERTICAL, EDJE_ASPECT_PREFER_HORIZONTAL, - EDJE_ASPECT_PREFER_BOTH + EDJE_ASPECT_PREFER_BOTH, + EDJE_ASPECT_PREFER_SOURCE } Edje_Internal_Aspect; struct _Edje_Perspective