From 6e85feecf844c7da61b66ef7eb5a4feea1bf7b9e Mon Sep 17 00:00:00 2001 From: Emmanuele Bassi Date: Fri, 6 Jul 2012 14:28:48 +0100 Subject: [PATCH] actor: Add :pivot-point-z For some transformations we need to be able to set the Z component of the pivot point. Unlike :pivot-point, the Z coordinate is not normalized because actors are 2D surfaces. https://bugzilla.gnome.org/show_bug.cgi?id=677853 --- clutter/clutter-actor-private.h | 1 + clutter/clutter-actor.c | 144 ++++++++++++++++++++++++++++---- clutter/clutter-actor.h | 5 ++ clutter/clutter.symbols | 2 + 4 files changed, 135 insertions(+), 17 deletions(-) diff --git a/clutter/clutter-actor-private.h b/clutter/clutter-actor-private.h index 6d7deecda..0efd8ec5f 100644 --- a/clutter/clutter-actor-private.h +++ b/clutter/clutter-actor-private.h @@ -204,6 +204,7 @@ struct _ClutterTransformInfo /* transformation center */ ClutterPoint pivot; + gfloat pivot_z; }; const ClutterTransformInfo * _clutter_actor_get_transform_info_or_defaults (ClutterActor *self); diff --git a/clutter/clutter-actor.c b/clutter/clutter-actor.c index 7f78e09ad..84f28ea61 100644 --- a/clutter/clutter-actor.c +++ b/clutter/clutter-actor.c @@ -871,6 +871,7 @@ enum PROP_REACTIVE, PROP_PIVOT_POINT, + PROP_PIVOT_POINT_Z, PROP_SCALE_X, PROP_SCALE_Y, @@ -2952,6 +2953,7 @@ clutter_actor_real_apply_transform (ClutterActor *self, info = _clutter_actor_get_transform_info_or_defaults (self); + /* compute the pivot point given the allocated size */ if (!clutter_point_equals (&info->pivot, clutter_point_zero ())) { pivot_x = (priv->allocation.x2 - priv->allocation.x1) @@ -2972,7 +2974,7 @@ clutter_actor_real_apply_transform (ClutterActor *self, /* pivot point, used as the transformation center */ if (pivot_x != 0.f || pivot_y != 0.f) - cogl_matrix_translate (transform, pivot_x, pivot_y, 0.f); + cogl_matrix_translate (transform, pivot_x, pivot_y, info->pivot_z); /* * because the rotation involves translations, we must scale @@ -2992,25 +2994,31 @@ clutter_actor_real_apply_transform (ClutterActor *self, } if (info->rz_angle) - TRANSFORM_ABOUT_ANCHOR_COORD (self, transform, - &info->rz_center, - cogl_matrix_rotate (transform, - info->rz_angle, - 0, 0, 1.0)); + { + TRANSFORM_ABOUT_ANCHOR_COORD (self, transform, + &info->rz_center, + cogl_matrix_rotate (transform, + info->rz_angle, + 0, 0, 1.0)); + } if (info->ry_angle) - TRANSFORM_ABOUT_ANCHOR_COORD (self, transform, - &info->ry_center, - cogl_matrix_rotate (transform, - info->ry_angle, - 0, 1.0, 0)); + { + TRANSFORM_ABOUT_ANCHOR_COORD (self, transform, + &info->ry_center, + cogl_matrix_rotate (transform, + info->ry_angle, + 0, 1.0, 0)); + } if (info->rx_angle) - TRANSFORM_ABOUT_ANCHOR_COORD (self, transform, - &info->rx_center, - cogl_matrix_rotate (transform, - info->rx_angle, - 1.0, 0, 0)); + { + TRANSFORM_ABOUT_ANCHOR_COORD (self, transform, + &info->rx_center, + cogl_matrix_rotate (transform, + info->rx_angle, + 1.0, 0, 0)); + } if (!clutter_anchor_coord_is_zero (&info->anchor)) { @@ -4093,9 +4101,10 @@ static const ClutterTransformInfo default_transform_info = { { 0, }, /* anchor */ - 0.0, /* z-position */ + 0.f, /* z-position */ CLUTTER_POINT_INIT_ZERO, /* pivot */ + 0.f /* pivot-z */ }; /*< private > @@ -4183,6 +4192,22 @@ clutter_actor_set_pivot_point_internal (ClutterActor *self, clutter_actor_queue_redraw (self); } +static inline void +clutter_actor_set_pivot_point_z_internal (ClutterActor *self, + float pivot_z) +{ + ClutterTransformInfo *info; + + info = _clutter_actor_get_transform_info (self); + info->pivot_z = pivot_z; + + self->priv->transform_valid = FALSE; + + g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_PIVOT_POINT_Z]); + + clutter_actor_queue_redraw (self); +} + /*< private > * clutter_actor_set_rotation_angle_internal: * @self: a #ClutterActor @@ -4705,6 +4730,10 @@ clutter_actor_set_property (GObject *object, } break; + case PROP_PIVOT_POINT_Z: + clutter_actor_set_pivot_point_z (actor, g_value_get_float (value)); + break; + case PROP_SCALE_X: clutter_actor_set_scale_factor (actor, CLUTTER_X_AXIS, g_value_get_double (value)); @@ -5091,6 +5120,15 @@ clutter_actor_get_property (GObject *object, } break; + case PROP_PIVOT_POINT_Z: + { + const ClutterTransformInfo *info; + + info = _clutter_actor_get_transform_info_or_defaults (actor); + g_value_set_float (value, info->pivot_z); + } + break; + case PROP_SCALE_X: { const ClutterTransformInfo *info; @@ -6362,6 +6400,26 @@ clutter_actor_class_init (ClutterActorClass *klass) G_PARAM_STATIC_STRINGS | CLUTTER_PARAM_ANIMATABLE); + /** + * ClutterActor:pivot-point-z: + * + * The Z component of the #ClutterActor:pivot-point, expressed as a value + * along the Z axis. + * + * The #ClutterActor:pivot-point-z property is animatable. + * + * Since: 1.12 + */ + obj_props[PROP_PIVOT_POINT_Z] = + g_param_spec_float ("pivot-point-z", + P_("Pivot Point Z"), + P_("Z component of the pivot point"), + -G_MAXFLOAT, G_MAXFLOAT, + 0.f, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS | + CLUTTER_PARAM_ANIMATABLE); + /** * ClutterActor:scale-x: * @@ -11184,6 +11242,54 @@ clutter_actor_get_pivot_point (ClutterActor *self, *pivot_y = info->pivot.y; } +/** + * clutter_actor_set_pivot_point_z: + * @self: a #ClutterActor + * @pivot_z: the Z coordinate of the actor's pivot point + * + * Sets the component on the Z axis of the #ClutterActor:pivot-point around + * which the scaling and rotation transformations occur. + * + * The @pivot_z value is expressed as a distance along the Z axis. + * + * Since: 1.12 + */ +void +clutter_actor_set_pivot_point_z (ClutterActor *self, + gfloat pivot_z) +{ + g_return_if_fail (CLUTTER_IS_ACTOR (self)); + + if (_clutter_actor_get_transition (self, obj_props[PROP_PIVOT_POINT_Z]) == NULL) + { + const ClutterTransformInfo *info; + + info = _clutter_actor_get_transform_info_or_defaults (self); + + _clutter_actor_create_transition (self, obj_props[PROP_PIVOT_POINT_Z], + info->pivot_z, + pivot_z); + } + else + _clutter_actor_update_transition (self, obj_props[PROP_PIVOT_POINT_Z], pivot_z); +} + +/** + * clutter_actor_get_pivot_point_z: + * @self: a #ClutterActor + * + * Retrieves the Z component of the #ClutterActor:pivot-point. + * + * Since: 1.12 + */ +gfloat +clutter_actor_get_pivot_point_z (ClutterActor *self) +{ + g_return_val_if_fail (CLUTTER_IS_ACTOR (self), 0.f); + + return _clutter_actor_get_transform_info_or_defaults (self)->pivot_z; +} + /** * clutter_actor_set_depth: * @self: a #ClutterActor @@ -14029,6 +14135,10 @@ clutter_actor_set_animatable_property (ClutterActor *actor, clutter_actor_set_pivot_point_internal (actor, g_value_get_boxed (value)); break; + case PROP_PIVOT_POINT_Z: + clutter_actor_set_pivot_point_z_internal (actor, g_value_get_float (value)); + break; + case PROP_SCALE_X: clutter_actor_set_scale_factor_internal (actor, g_value_get_double (value), diff --git a/clutter/clutter-actor.h b/clutter/clutter-actor.h index 32bbfec10..20e45f3a8 100644 --- a/clutter/clutter-actor.h +++ b/clutter/clutter-actor.h @@ -634,6 +634,11 @@ void clutter_actor_get_pivot_point gfloat *pivot_x, gfloat *pivot_y); CLUTTER_AVAILABLE_IN_1_12 +void clutter_actor_set_pivot_point_z (ClutterActor *self, + gfloat pivot_z); +CLUTTER_AVAILABLE_IN_1_12 +gfloat clutter_actor_get_pivot_point_z (ClutterActor *self); +CLUTTER_AVAILABLE_IN_1_12 void clutter_actor_set_rotation_angle (ClutterActor *self, ClutterRotateAxis axis, gdouble angle); diff --git a/clutter/clutter.symbols b/clutter/clutter.symbols index a32a219b7..15a6395bb 100644 --- a/clutter/clutter.symbols +++ b/clutter/clutter.symbols @@ -130,6 +130,7 @@ clutter_actor_get_paint_visibility clutter_actor_get_paint_volume clutter_actor_get_pango_context clutter_actor_get_parent +clutter_actor_get_pivot_point_z clutter_actor_get_pivot_point clutter_actor_get_position clutter_actor_get_preferred_height @@ -254,6 +255,7 @@ clutter_actor_set_name clutter_actor_set_offscreen_redirect clutter_actor_set_opacity clutter_actor_set_parent +clutter_actor_set_pivot_point_z clutter_actor_set_pivot_point clutter_actor_set_position clutter_actor_set_reactive