diff --git a/legacy/edje/src/bin/edje_cc_handlers.c b/legacy/edje/src/bin/edje_cc_handlers.c index 104bde0087..59680ad744 100644 --- a/legacy/edje/src/bin/edje_cc_handlers.c +++ b/legacy/edje/src/bin/edje_cc_handlers.c @@ -209,6 +209,7 @@ static void st_collections_group_parts_part_description_map_rotation_y(void); static void st_collections_group_parts_part_description_map_rotation_z(void); static void st_collections_group_parts_part_description_map_on(void); static void st_collections_group_parts_part_description_map_backface_cull(void); +static void st_collections_group_parts_part_description_map_perspective_on(void); static void st_collections_group_parts_part_description_perspective_zplane(void); static void st_collections_group_parts_part_description_perspective_focal(void); static void st_collections_group_parts_part_api(void); @@ -431,6 +432,7 @@ New_Statement_Handler statement_handlers[] = {"collections.group.parts.part.description.map.rotation.z", st_collections_group_parts_part_description_map_rotation_z}, {"collections.group.parts.part.description.map.on", st_collections_group_parts_part_description_map_on}, {"collections.group.parts.part.description.map.backface_cull", st_collections_group_parts_part_description_map_backface_cull}, + {"collections.group.parts.part.description.map.perspective_on", st_collections_group_parts_part_description_map_perspective_on}, {"collections.group.parts.part.description.perspective.zplane", st_collections_group_parts_part_description_perspective_zplane}, {"collections.group.parts.part.description.perspective.focal", st_collections_group_parts_part_description_perspective_focal}, {"collections.group.parts.part.description.params.int", st_collections_group_parts_part_description_params_int}, @@ -3095,6 +3097,7 @@ ob_collections_group_parts_part_description(void) ed->map.rot.z = FROM_DOUBLE(0.0); ed->map.on = 0; ed->map.backcull = 0; + ed->map.persp_on = 0; ed->persp.zplane = 0; ed->persp.focal = 1000; ed->external_params = NULL; @@ -5641,6 +5644,7 @@ st_collections_group_parts_part_description_map_perspective(void) data_queue_part_lookup(pc, name, &(ed->map.id_persp)); free(name); } + ed->map.persp_on = 1; } static void @@ -5774,6 +5778,23 @@ st_collections_group_parts_part_description_map_backface_cull(void) ed->map.backcull = parse_bool(0); } +static void +st_collections_group_parts_part_description_map_perspective_on(void) +{ + Edje_Part_Collection *pc; + Edje_Part *ep; + Edje_Part_Description *ed; + + check_arg_count(1); + + pc = eina_list_data_get(eina_list_last(edje_collections)); + ep = eina_list_data_get(eina_list_last(pc->parts)); + + ed = ep->default_desc; + if (ep->other_desc) ed = eina_list_data_get(eina_list_last(ep->other_desc)); + ed->map.persp_on = parse_bool(0); +} + static void st_collections_group_parts_part_description_perspective_zplane(void) { diff --git a/legacy/edje/src/lib/Edje.h b/legacy/edje/src/lib/Edje.h index 70864d9e0a..40cc81af7d 100644 --- a/legacy/edje/src/lib/Edje.h +++ b/legacy/edje/src/lib/Edje.h @@ -536,15 +536,16 @@ extern "C" { EAPI const Eina_List *edje_available_modules_get(void); /* perspective info for maps inside edje objects */ -#if 1 // WORKING ONಈIT! these will work later. first perspectivg within 1 object typedef struct _Edje_Perspective Edje_Perspective; - EAPI Edje_Perspective *edje_perspective_new (Evas *e); - EAPI void edje_perspective_free (Edje_Perspective *ps); - EAPI void edje_perspective_set (Edje_Perspective *ps, Evas_Coord px, Evas_Coord py, Evas_Coord z0, Evas_Coord foc); - EAPI void edje_object_perspective_set(Evas_Object *obj, Edje_Perspective *persp); - EAPI const Edje_Perspective *edje_object_perspective_get(Evas_Object *obj); -#endif + EAPI Edje_Perspective *edje_perspective_new (Evas *e); + EAPI void edje_perspective_free (Edje_Perspective *ps); + EAPI void edje_perspective_set (Edje_Perspective *ps, Evas_Coord px, Evas_Coord py, Evas_Coord z0, Evas_Coord foc); + EAPI void edje_perspective_global_set (Edje_Perspective *ps, Eina_Bool global); + EAPI Eina_Bool edje_perspective_global_get (const Edje_Perspective *ps); + EAPI const Edje_Perspective *edje_evas_global_perspective_get(const Evas *e); + EAPI void edje_object_perspective_set (Evas_Object *obj, Edje_Perspective *ps); + EAPI const Edje_Perspective *edje_object_perspective_get (const Evas_Object *obj); #ifdef __cplusplus } diff --git a/legacy/edje/src/lib/edje_calc.c b/legacy/edje/src/lib/edje_calc.c index 390a990945..36d6d88aa4 100644 --- a/legacy/edje/src/lib/edje_calc.c +++ b/legacy/edje/src/lib/edje_calc.c @@ -2019,108 +2019,395 @@ _edje_part_recalc(Edje *ed, Edje_Real_Part *ep, int flags) if (chosen_desc->map.on) { Evas_Map *map; - Evas_Coord cx, cy, px, py, zplane, foc, lx, ly, lz; + Evas_Coord cx, cy; double rx, ry, rz; - int lr, lg, lb, lar, lag, lab; + Edje_Part_Description *desc1, *desc2; + + desc1 = ep->param1.description; + desc2 = NULL; + if (ep->param2) desc2 = ep->param2->description; + pos = ep->description_pos; + // create map and populate with part geometry map = evas_map_new(4); evas_map_util_points_populate_from_geometry (map, ed->x + pf->x, ed->y + pf->y, pf->w, pf->h, 0); + // default center - center of part cx = ed->x + pf->x + (pf->w / 2); cy = ed->y + pf->y + (pf->h / 2); - if ((chosen_desc->map.rot.id_center >= 0) && - (chosen_desc->map.rot.id_center != ep->part->id)) + + // if another center is specified - find it and caculate it + if ((desc1) && + (desc1->map.rot.id_center >= 0) && + (desc1->map.rot.id_center != ep->part->id)) { + Evas_Coord cx1, cy1, cx2, cy2; Edje_Real_Part *ep2 = - ed->table_parts[chosen_desc->map.rot.id_center % + ed->table_parts[desc1->map.rot.id_center % ed->table_parts_size]; + // get center for desc1 if (ep2) { - if (!ep2->calculated) - _edje_part_recalc(ed, ep2, flags); - cx = ed->x + ep2->x + (ep2->w / 2); - cy = ed->y + ep2->y + (ep2->h / 2); + if (!ep2->calculated) _edje_part_recalc(ed, ep2, flags); + cx1 = ed->x + ep2->x + (ep2->w / 2); + cy1 = ed->y + ep2->y + (ep2->h / 2); } + // if we have a desc2 and are on a partiual position to it + if ((pos != ZERO) && (desc2) && + (desc2->map.rot.id_center >= 0) && + (desc2->map.rot.id_center != ep->part->id)) + { + ep2 = ed->table_parts[desc2->map.rot.id_center % + ed->table_parts_size]; + // get 2nd center & merge with pos with center 1 + if (ep2) + { + if (!ep2->calculated) _edje_part_recalc(ed, ep2, flags); + cx2 = ed->x + ep2->x + (ep2->w / 2); + cy2 = ed->y + ep2->y + (ep2->h / 2); + cx1 += SCALE(pos, cx2 - cx1); + cy1 += SCALE(pos, cy2 - cy1); + } + } + cx = cx1; + cy = cy1; } - if ((ep->param2) && (ep->description_pos != ZERO)) + + // rotation - interpolate wit pos, if appropriate + if ((pos != ZERO) && (desc2)) { - rx = TO_DOUBLE(ADD(ep->param1.description->map.rot.x, - MUL(ep->description_pos, - SUB(ep->param2->description->map.rot.x, - ep->param1.description->map.rot.x)))); - ry = TO_DOUBLE(ADD(ep->param1.description->map.rot.y, - MUL(ep->description_pos, - SUB(ep->param2->description->map.rot.y, - ep->param1.description->map.rot.y)))); - rz = TO_DOUBLE(ADD(ep->param1.description->map.rot.z, - MUL(ep->description_pos, - SUB(ep->param2->description->map.rot.z, - ep->param1.description->map.rot.z)))); + rx = TO_DOUBLE(ADD(desc1->map.rot.x, + MUL(pos, SUB(desc2->map.rot.x, + desc1->map.rot.x)))); + ry = TO_DOUBLE(ADD(desc1->map.rot.y, + MUL(pos, SUB(desc2->map.rot.y, + desc1->map.rot.y)))); + rz = TO_DOUBLE(ADD(desc1->map.rot.z, + MUL(pos, SUB(desc2->map.rot.z, + desc1->map.rot.z)))); } else { - rx = TO_DOUBLE(ep->param1.description->map.rot.x); - ry = TO_DOUBLE(ep->param1.description->map.rot.y); - rz = TO_DOUBLE(ep->param1.description->map.rot.z); + // no 2 descriptions - just use rot + rx = TO_DOUBLE(desc1->map.rot.x); + ry = TO_DOUBLE(desc1->map.rot.y); + rz = TO_DOUBLE(desc1->map.rot.z); } evas_map_util_3d_rotate(map, rx, ry, rz, cx, cy, 0); - if ((chosen_desc->map.id_light >= 0) && - (chosen_desc->map.id_light != ep->part->id)) + + // calculate light color & position etc. if there is one + if (((desc1) && + (desc1->map.id_light >= 0) && + (desc1->map.id_light != ep->part->id)) || + ((desc2) && + (desc2->map.id_light >= 0) && + (desc2->map.id_light != ep->part->id))) { - Edje_Real_Part *ep2 = - ed->table_parts[chosen_desc->map.id_light % - ed->table_parts_size]; - if (ep2) + Evas_Coord lx, ly, lz; + int lr, lg, lb, lar, lag, lab; + Evas_Coord lx1, ly1, lz1; + int lr1, lg1, lb1, lar1, lag1, lab1, do1; + Evas_Coord lx2, ly2, lz2; + int lr2, lg2, lb2, lar2, lag2, lab2, do2; + + do1 = do2 = 0; + + if ((desc1) && + (desc1->map.id_light >= 0) && + (desc1->map.id_light != ep->part->id)) { - if (!ep2->calculated) - _edje_part_recalc(ed, ep2, flags); - lx = ed->x + ep2->x + (ep2->w / 2); - ly = ed->y + ep2->y + (ep2->h / 2); - lz = ep2->param1.description->persp.zplane; - lr = ep2->param1.description->color.r; - lg = ep2->param1.description->color.g; - lb = ep2->param1.description->color.b; - lar = ep2->param1.description->color2.r; - lag = ep2->param1.description->color2.g; - lab = ep2->param1.description->color2.b; - evas_map_util_3d_lighting(map, lx, ly, lz, - lr, lg, lb, lar, lag, lab); + Edje_Real_Part *ep2 = + ed->table_parts[desc1->map.id_light % + ed->table_parts_size]; + // get light part + if (ep2) + { + Edje_Part_Description *ep2desc1, *ep2desc2; + FLOAT_T ep2pos; + + do1 = 1; + if (!ep2->calculated) + _edje_part_recalc(ed, ep2, flags); + ep2desc1 = ep2->param1.description; + ep2desc2 = NULL; + if (ep2->param2) ep2desc2 = ep2->param2->description; + ep2pos = ep2->description_pos; + + // light x and y are already interpolated in part geom + lx1 = ed->x + ep2->x + (ep2->w / 2); + ly1 = ed->y + ep2->y + (ep2->h / 2); + // if light is transitioning - interpolate it + if ((ep2pos != ZERO) && (ep2desc2)) + { + lz1 = ep2desc1->persp.zplane + + TO_INT(SCALE(ep2pos, ep2desc2->persp.zplane - + ep2desc1->persp.zplane)); + lr1 = ep2desc1->color.r + + TO_INT(SCALE(ep2pos, ep2desc2->color.r - + ep2desc1->color.r)); + lg1 = ep2desc1->color.g + + TO_INT(SCALE(ep2pos, ep2desc2->color.g - + ep2desc1->color.b)); + lb1 = ep2desc1->color.b + + TO_INT(SCALE(ep2pos, ep2desc2->color.g - + ep2desc1->color.b)); + lar1 = ep2desc1->color2.r + + TO_INT(SCALE(ep2pos, ep2desc2->color2.r - + ep2desc1->color2.r)); + lag1 = ep2desc1->color2.g + + TO_INT(SCALE(ep2pos, ep2desc2->color2.g - + ep2desc1->color2.b)); + lab1 = ep2desc1->color2.b + + TO_INT(SCALE(ep2pos, ep2desc2->color2.g - + ep2desc1->color2.b)); + } + else + { + lz1 = ep2desc1->persp.zplane; + lr1 = ep2desc1->color.r; + lg1 = ep2desc1->color.g; + lb1 = ep2desc1->color.b; + lar1 = ep2desc1->color2.r; + lag1 = ep2desc1->color2.g; + lab1 = ep2desc1->color2.b; + } + } } - } - px = ed->x + (ed->w / 2); - py = ed->y + (ed->h / 2); - zplane = 0; - foc = 1000; - if ((chosen_desc->map.id_persp >= 0) && - (chosen_desc->map.id_persp != ep->part->id)) - { - Edje_Real_Part *ep2 = - ed->table_parts[chosen_desc->map.id_persp % - ed->table_parts_size]; - if (ep2) + if ((desc2) && + (desc2->map.id_light >= 0) && + (desc2->map.id_light != ep->part->id)) { - if (!ep2->calculated) - _edje_part_recalc(ed, ep2, flags); - px = ed->x + ep2->x + (ep2->w / 2); - py = ed->y + ep2->y + (ep2->h / 2); - zplane = ep2->param1.description->persp.zplane; - foc = ep2->param1.description->persp.focal; + Edje_Real_Part *ep2 = + ed->table_parts[desc2->map.id_light % + ed->table_parts_size]; + // get light part + if (ep2) + { + Edje_Part_Description *ep2desc1, *ep2desc2; + FLOAT_T ep2pos; + + do2 = 1; + if (!ep2->calculated) + _edje_part_recalc(ed, ep2, flags); + ep2desc1 = ep2->param1.description; + ep2desc2 = NULL; + if (ep2->param2) ep2desc2 = ep2->param2->description; + ep2pos = ep2->description_pos; + + // light x and y are already interpolated in part geom + lx2 = ed->x + ep2->x + (ep2->w / 2); + ly2 = ed->y + ep2->y + (ep2->h / 2); + // if light is transitioning - interpolate it + if ((ep2pos != ZERO) && (ep2desc2)) + { + lz2 = ep2desc1->persp.zplane + + TO_INT(SCALE(ep2pos, ep2desc2->persp.zplane - + ep2desc1->persp.zplane)); + lr2 = ep2desc1->color.r + + TO_INT(SCALE(ep2pos, ep2desc2->color.r - + ep2desc1->color.r)); + lg2 = ep2desc1->color.g + + TO_INT(SCALE(ep2pos, ep2desc2->color.g - + ep2desc1->color.b)); + lb2 = ep2desc1->color.b + + TO_INT(SCALE(ep2pos, ep2desc2->color.g - + ep2desc1->color.b)); + lar2 = ep2desc1->color2.r + + TO_INT(SCALE(ep2pos, ep2desc2->color2.r - + ep2desc1->color2.r)); + lag2 = ep2desc1->color2.g + + TO_INT(SCALE(ep2pos, ep2desc2->color2.g - + ep2desc1->color2.b)); + lab2 = ep2desc1->color2.b + + TO_INT(SCALE(ep2pos, ep2desc2->color2.g - + ep2desc1->color2.b)); + } + else + { + lz2 = ep2desc1->persp.zplane; + lr2 = ep2desc1->color.r; + lg2 = ep2desc1->color.g; + lb2 = ep2desc1->color.b; + lar2 = ep2desc1->color2.r; + lag2 = ep2desc1->color2.g; + lab2 = ep2desc1->color2.b; + } + } + } + if ((do1 && do2)) + { + lx = lx1 + TO_INT(SCALE(pos, lx2 - lx1)); + ly = ly1 + TO_INT(SCALE(pos, ly2 - ly1)); + lz = lz1 + TO_INT(SCALE(pos, lz2 - lz1)); + lr = lr1 + TO_INT(SCALE(pos, lr2 - lr1)); + lg = lg1 + TO_INT(SCALE(pos, lg2 - lg1)); + lb = lb1 + TO_INT(SCALE(pos, lb2 - lb1)); + lar = lar1 + TO_INT(SCALE(pos, lar2 - lar1)); + lag = lag1 + TO_INT(SCALE(pos, lag2 - lag1)); + lab = lab1 + TO_INT(SCALE(pos, lab2 - lab1)); + } + else if (do1) + { + lx = lx1; ly = ly1; lz = lz1; + lr = lr1; lg = lg1; lb = lb1; + lar = lar1; lag = lag1; lab = lab1; + } + else + { + lx = lx2; ly = ly2; lz = lz2; + lr = lr2; lg = lg2; lb = lb2; + lar = lar2; lag = lag2; lab = lab2; + } + evas_map_util_3d_lighting(map, + lx, ly, lz, + lr, lg, lb, + lar, lag, lab); + } + + // calculate perspective point + if (chosen_desc->map.persp_on) + { + Evas_Coord px, py, zplane, foc; + Evas_Coord px1, py1, zplane1, foc1; + Evas_Coord px2, py2, zplane2, foc2; + int do1, do2; + + do1 = do2 = 0; + + // default perspective point + px = ed->x + (ed->w / 2); + py = ed->y + (ed->h / 2); + zplane = 0; + foc = 1000; + + if ((desc1) && + (desc1->map.id_persp >= 0) && + (desc1->map.id_persp != ep->part->id)) + { + Edje_Real_Part *ep2 = ed->table_parts[desc1->map.id_persp % + ed->table_parts_size]; + if (ep2) + { + Edje_Part_Description *ep2desc1, *ep2desc2; + FLOAT_T ep2pos; + + do1 = 1; + if (!ep2->calculated) + _edje_part_recalc(ed, ep2, flags); + ep2desc1 = ep2->param1.description; + ep2desc2 = NULL; + if (ep2->param2) ep2desc2 = ep2->param2->description; + ep2pos = ep2->description_pos; + + px1 = ed->x + ep2->x + (ep2->w / 2); + py1 = ed->y + ep2->y + (ep2->h / 2); + if ((ep2pos != ZERO) && (ep2desc2)) + { + zplane1 = ep2desc1->persp.zplane + + TO_INT(SCALE(ep2pos, ep2desc2->persp.zplane - + ep2desc1->persp.zplane)); + foc1 = ep2desc1->persp.focal + + TO_INT(SCALE(ep2pos, ep2desc2->persp.focal - + ep2desc1->persp.focal)); + } + else + { + zplane1 = ep2desc1->persp.zplane; + foc1 = ep2desc1->persp.focal; + } + } + } + + if ((desc2) && + (desc2->map.id_persp >= 0) && + (desc2->map.id_persp != ep->part->id)) + { + Edje_Real_Part *ep2 = ed->table_parts[desc2->map.id_persp % + ed->table_parts_size]; + if (ep2) + { + Edje_Part_Description *ep2desc1, *ep2desc2; + FLOAT_T ep2pos; + + do2 = 1; + if (!ep2->calculated) + _edje_part_recalc(ed, ep2, flags); + ep2desc1 = ep2->param1.description; + ep2desc2 = NULL; + if (ep2->param2) ep2desc2 = ep2->param2->description; + ep2pos = ep2->description_pos; + + px2 = ed->x + ep2->x + (ep2->w / 2); + py2 = ed->y + ep2->y + (ep2->h / 2); + if ((ep2pos != ZERO) && (ep2desc2)) + { + zplane2 = ep2desc1->persp.zplane + + TO_INT(SCALE(ep2pos, ep2desc2->persp.zplane - + ep2desc1->persp.zplane)); + foc2 = ep2desc1->persp.focal + + TO_INT(SCALE(ep2pos, ep2desc2->persp.focal - + ep2desc1->persp.focal)); + } + else + { + zplane2 = ep2desc1->persp.zplane; + foc2 = ep2desc1->persp.focal; + } + } + } + + if ((do1) && (do2)) + { + px = px1 + TO_INT(SCALE(pos, px2 - px1)); + py = py1 + TO_INT(SCALE(pos, py2 - py1)); + zplane = zplane1 + TO_INT(SCALE(pos, zplane2 - zplane1)); + foc = foc1 + TO_INT(SCALE(pos, foc2 - foc1)); + } + else if (do1) + { + px = px1; py = py1; zplane = zplane1; foc = foc1; + } + else if (do2) + { + px = px2; py = py2; zplane = zplane2; foc = foc2; + } + else + { + if (ed->persp) + { + px = ed->persp->px; py = ed->persp->py; + zplane = ed->persp->z0; foc = ed->persp->foc; + } + else + { + const Edje_Perspective *ps; + + // fixme: a tad inefficient as this is a has lookup + ps = edje_object_perspective_get(ed->evas); + if (ps) + { + px = ps->px; py = ps->py; + zplane = ps->z0; foc = ps->foc; + } + } } evas_map_util_3d_perspective(map, px, py, zplane, foc); } - evas_object_map_set(mo, map); - evas_object_map_enable_set(mo, 1); - if (ep->param1.description->map.backcull) + + // handle backface culling (object is facing away from view + if (chosen_desc->map.backcull) { if (pf->visible) { if (evas_map_util_clockwise_get(map)) evas_object_show(mo); - else - evas_object_hide(mo); + else evas_object_hide(mo); } } + + evas_object_map_set(mo, map); + evas_object_map_enable_set(mo, 1); evas_map_free(map); } else diff --git a/legacy/edje/src/lib/edje_data.c b/legacy/edje/src/lib/edje_data.c index 9f9dc90b32..678771d479 100644 --- a/legacy/edje/src/lib/edje_data.c +++ b/legacy/edje/src/lib/edje_data.c @@ -356,6 +356,7 @@ _edje_edd_init(void) EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_part_description, Edje_Part_Description, "map.rot.y", map.rot.y, EDJE_T_FLOAT); EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_part_description, Edje_Part_Description, "map.rot.z", map.rot.z, EDJE_T_FLOAT); EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_part_description, Edje_Part_Description, "map.on", map.on, EET_T_UCHAR); + EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_part_description, Edje_Part_Description, "map.persp_on", map.persp_on, EET_T_UCHAR); EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_part_description, Edje_Part_Description, "map.backcull", map.backcull, EET_T_UCHAR); EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_part_description, Edje_Part_Description, "persp.zplane", persp.zplane, EET_T_INT); EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_part_description, Edje_Part_Description, "persp.focal", persp.focal, EET_T_INT); diff --git a/legacy/edje/src/lib/edje_private.h b/legacy/edje/src/lib/edje_private.h index 663496b193..68525743b0 100644 --- a/legacy/edje/src/lib/edje_private.h +++ b/legacy/edje/src/lib/edje_private.h @@ -127,10 +127,11 @@ EAPI extern int _edje_default_log_dom ; struct _Edje_Perspective { - Evas *e; - Evas_Coord px, py; - Evas_Coord z0, foc; - Eina_List *users; + Evas_Object *obj; + Evas *e; + Evas_Coord px, py, z0, foc; + Eina_List *users; + Eina_Bool global : 1; }; struct _Edje_Position_Scale @@ -673,6 +674,7 @@ struct _Edje_Part_Description } rot; unsigned char backcull; unsigned char on; + unsigned char persp_on; } map; struct { @@ -762,6 +764,8 @@ struct _Edje void *script_only_data; int table_programs_size; int table_parts_size; + + Edje_Perspective *persp; struct { Edje_Signals_Sources_Patterns callbacks; diff --git a/legacy/edje/src/lib/edje_smart.c b/legacy/edje/src/lib/edje_smart.c index 4fe09006fd..98f47c7bfb 100644 --- a/legacy/edje/src/lib/edje_smart.c +++ b/legacy/edje/src/lib/edje_smart.c @@ -97,6 +97,7 @@ _edje_smart_del(Evas_Object * obj) evas_object_smart_data_set(obj, NULL); if (_edje_script_only(ed)) _edje_script_only_shutdown(ed); if (_edje_lua_script_only(ed)) _edje_lua_script_only_shutdown(ed); + if (ed->persp) edje_object_perspective_set(obj, NULL); _edje_file_del(ed); _edje_clean_objects(ed); _edje_unref(ed); diff --git a/legacy/edje/src/lib/edje_util.c b/legacy/edje/src/lib/edje_util.c index 5aa4578227..147fe0eebf 100644 --- a/legacy/edje/src/lib/edje_util.c +++ b/legacy/edje/src/lib/edje_util.c @@ -3688,6 +3688,183 @@ edje_object_part_table_clear(Evas_Object *obj, const char *part, Eina_Bool clear return EINA_TRUE; } + + + + + + + + +static void +_edje_perspective_obj_del(void *data, Evas *e, Evas_Object *obj, void *event_info) +{ + Edje_Perspective *ps = data; + Evas_Object *o; + + EINA_LIST_FREE(ps->users, o) + { + Edje *ed; + + ed = evas_object_smart_data_get(o); + if (!ed) continue; + ed->persp = NULL; + ed->dirty = 1; + _edje_recalc_do(ed); + } + free(ps); +} + +EAPI Edje_Perspective * +edje_perspective_new(Evas *e) +{ + Edje_Perspective *ps; + Evas_Coord vx, vy, vw, vh; + + if (!e) return NULL; + ps = calloc(1, sizeof(Edje_Perspective)); + ps->obj = evas_object_rectangle_add(e); + evas_object_data_set(ps->obj, "_edje_perspective", ps); + evas_object_event_callback_add(ps->obj, EVAS_CALLBACK_DEL, _edje_perspective_obj_del, ps); + evas_output_viewport_get(e, &vx, &vy, &vw, &vh); + ps->e = e; + ps->px = vx + (vw / 2); + ps->py = vy + (vh / 2); + ps->z0 = 0; + ps->foc = 1000; + return ps; +} + +EAPI void +edje_perspective_free(Edje_Perspective *ps) +{ + if (!ps) return; + evas_object_del(ps->obj); +} + +EAPI void +edje_perspective_set(Edje_Perspective *ps, Evas_Coord px, Evas_Coord py, Evas_Coord z0, Evas_Coord foc) +{ + Eina_List *l; + Evas_Object *o; + + if (!ps) return; + if ((ps->px == px) && (ps->py == py) && (ps->z0 == z0) && (ps->foc == foc)) return; + ps->px = px; + ps->py = py; + ps->z0 = z0; + ps->foc = foc; + EINA_LIST_FOREACH(ps->users, l, o) + { + Edje *ed; + + ed = evas_object_smart_data_get(o); + if (!ed) continue; + if (!ed->persp) + { + ed->dirty = 1; + _edje_recalc_do(ed); + } + } + if (ps->global) + { + EINA_LIST_FOREACH(_edje_edjes, l, o) + { + Edje *ed; + + ed = evas_object_smart_data_get(o); + if (!ed) continue; + if (!ed->persp) + { + ed->dirty = 1; + _edje_recalc_do(ed); + } + } + } +} + +EAPI void +edje_perspective_global_set(Edje_Perspective *ps, Eina_Bool global) +{ + Evas_Object *o; + Eina_List *l; + + if (!ps) return; + if (ps->global == global) return; + if (global) + { + o = evas_object_name_find(evas_object_evas_get(ps->obj), + "_edje_perspective"); + if (o) evas_object_name_set(o, NULL); + evas_object_name_set(ps->obj, "_edje_perspective"); + } + else + evas_object_name_set(ps->obj, NULL); + ps->global = global; + EINA_LIST_FOREACH(_edje_edjes, l, o) + { + Edje *ed; + + ed = evas_object_smart_data_get(o); + if (!ed) continue; + if (!ed->persp) + { + ed->dirty = 1; + _edje_recalc_do(ed); + } + } +} + +EAPI Eina_Bool +edje_perspective_global_get(const Edje_Perspective *ps) +{ + if (!ps) return 0; + return ps->global; +} + +EAPI const Edje_Perspective * +edje_evas_global_perspective_get(const Evas *e) +{ + Evas_Object *obj; + + if (!e) return NULL; + obj = evas_object_name_find(e, "_edje_perspective"); + if (!obj) return NULL; + return evas_object_data_get(obj, "_edje_perspective"); +} + +EAPI void +edje_object_perspective_set(Evas_Object *obj, Edje_Perspective *ps) +{ + Edje *ed; + + ed = evas_object_smart_data_get(obj); + if (!ed) return; + if (ed->persp == ps) return; + if (ed->persp != ps) + { + if (ed->persp) + ed->persp->users = eina_list_remove(ed->persp->users, obj); + } + ed->persp = ps; + if (ps) ps->users = eina_list_append(ps->users, obj); + ed->dirty = 1; + _edje_recalc_do(ed); +} + +EAPI const Edje_Perspective * +edje_object_perspective_get(const Evas_Object *obj) +{ + Edje *ed; + + ed = evas_object_smart_data_get(obj); + if (!ed) return NULL; + return ed->persp; +} + + + + #define EDJE_PRELOAD_EMISSION "preload,done" #define EDJE_PRELOAD_SOURCE NULL