diff --git a/clutter/clutter-align-constraint.c b/clutter/clutter-align-constraint.c index 301763ecc..62e3a09e8 100644 --- a/clutter/clutter-align-constraint.c +++ b/clutter/clutter-align-constraint.c @@ -55,6 +55,7 @@ struct _ClutterAlignConstraint { ClutterConstraint parent_instance; + ClutterActor *actor; ClutterActor *source; ClutterAlignAxis align_axis; gfloat factor; @@ -82,52 +83,14 @@ G_DEFINE_TYPE (ClutterAlignConstraint, clutter_align_constraint, CLUTTER_TYPE_CONSTRAINT); -static void -update_actor_position (ClutterAlignConstraint *align) -{ - gfloat source_width, source_height; - gfloat actor_width, actor_height; - gfloat source_x, source_y; - gfloat new_position; - ClutterActor *actor; - - if (align->source == NULL) - return; - - if (!clutter_actor_meta_get_enabled (CLUTTER_ACTOR_META (align))) - return; - - actor = clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (align)); - if (actor == NULL) - return; - - clutter_actor_get_position (align->source, &source_x, &source_y); - clutter_actor_get_size (align->source, &source_width, &source_height); - clutter_actor_get_size (actor, &actor_width, &actor_height); - - switch (align->align_axis) - { - case CLUTTER_ALIGN_X_AXIS: - new_position = ((source_width - actor_width) * align->factor) - + source_x; - clutter_actor_set_x (actor, new_position); - break; - - case CLUTTER_ALIGN_Y_AXIS: - new_position = ((source_height - actor_height) * align->factor) - + source_y; - clutter_actor_set_y (actor, new_position); - break; - } -} - static void source_position_changed (ClutterActor *actor, const ClutterActorBox *allocation, ClutterAllocationFlags flags, ClutterAlignConstraint *align) { - update_actor_position (align); + if (align->actor != NULL) + clutter_actor_queue_relayout (align->actor); } static void @@ -137,6 +100,62 @@ source_destroyed (ClutterActor *actor, align->source = NULL; } +static void +clutter_align_constraint_set_actor (ClutterActorMeta *meta, + ClutterActor *new_actor) +{ + ClutterAlignConstraint *align = CLUTTER_ALIGN_CONSTRAINT (meta); + ClutterActorMetaClass *parent; + + /* store the pointer to the actor, for later use */ + align->actor = new_actor; + + parent = CLUTTER_ACTOR_META_CLASS (clutter_align_constraint_parent_class); + parent->set_actor (meta, new_actor); +} + +static void +clutter_align_constraint_update_allocation (ClutterConstraint *constraint, + ClutterActor *actor, + ClutterActorBox *allocation) +{ + ClutterAlignConstraint *align = CLUTTER_ALIGN_CONSTRAINT (constraint); + ClutterActorMeta *meta = CLUTTER_ACTOR_META (constraint); + gfloat source_width, source_height; + gfloat actor_width, actor_height; + gfloat source_x, source_y; + + if (align->source == NULL) + return; + + if (!clutter_actor_meta_get_enabled (meta)) + return; + + clutter_actor_get_position (align->source, &source_x, &source_y); + clutter_actor_get_size (align->source, &source_width, &source_height); + + switch (align->align_axis) + { + case CLUTTER_ALIGN_X_AXIS: + actor_width = clutter_actor_box_get_width (allocation); + allocation->x1 = ((source_width - actor_width) * align->factor) + + source_x; + allocation->x2 = allocation->x1 + actor_width; + break; + + case CLUTTER_ALIGN_Y_AXIS: + actor_height = clutter_actor_box_get_height (allocation); + allocation->y1 = ((source_height - actor_height) * align->factor) + + source_y; + allocation->y2 = allocation->y1 + actor_height; + break; + + default: + g_assert_not_reached (); + break; + } +} + static void clutter_align_constraint_set_property (GObject *gobject, guint prop_id, @@ -197,11 +216,17 @@ static void clutter_align_constraint_class_init (ClutterAlignConstraintClass *klass) { GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + ClutterActorMetaClass *meta_class = CLUTTER_ACTOR_META_CLASS (klass); + ClutterConstraintClass *constraint_class = CLUTTER_CONSTRAINT_CLASS (klass); GParamSpec *pspec; gobject_class->set_property = clutter_align_constraint_set_property; gobject_class->get_property = clutter_align_constraint_get_property; + meta_class->set_actor = clutter_align_constraint_set_actor; + + constraint_class->update_allocation = clutter_align_constraint_update_allocation; + /** * ClutterAlignConstraint:source: * @@ -261,6 +286,7 @@ clutter_align_constraint_class_init (ClutterAlignConstraintClass *klass) static void clutter_align_constraint_init (ClutterAlignConstraint *self) { + self->actor = NULL; self->source = NULL; self->align_axis = CLUTTER_ALIGN_X_AXIS; self->factor = 0.0f; @@ -328,7 +354,6 @@ clutter_align_constraint_set_source (ClutterAlignConstraint *align, } align->source = source; - if (align->source != NULL) { g_signal_connect (align->source, "allocation-changed", @@ -338,7 +363,8 @@ clutter_align_constraint_set_source (ClutterAlignConstraint *align, G_CALLBACK (source_destroyed), align); - update_actor_position (align); + if (align->actor != NULL) + clutter_actor_queue_relayout (align->actor); } _clutter_notify_by_pspec (G_OBJECT (align), obj_props[PROP_SOURCE]); @@ -383,7 +409,8 @@ clutter_align_constraint_set_align_axis (ClutterAlignConstraint *align, align->align_axis = axis; - update_actor_position (align); + if (align->actor != NULL) + clutter_actor_queue_relayout (align->actor); _clutter_notify_by_pspec (G_OBJECT (align), obj_props[PROP_ALIGN_AXIS]); } @@ -434,7 +461,8 @@ clutter_align_constraint_set_factor (ClutterAlignConstraint *align, align->factor = CLAMP (factor, 0.0, 1.0); - update_actor_position (align); + if (align->actor != NULL) + clutter_actor_queue_relayout (align->actor); _clutter_notify_by_pspec (G_OBJECT (align), obj_props[PROP_FACTOR]); } diff --git a/clutter/clutter-bind-constraint.c b/clutter/clutter-bind-constraint.c index 33528e0b2..b4f46a2d7 100644 --- a/clutter/clutter-bind-constraint.c +++ b/clutter/clutter-bind-constraint.c @@ -101,6 +101,7 @@ struct _ClutterBindConstraint { ClutterConstraint parent_instance; + ClutterActor *actor; ClutterActor *source; ClutterBindCoordinate coordinate; gfloat offset; @@ -128,67 +129,14 @@ G_DEFINE_TYPE (ClutterBindConstraint, clutter_bind_constraint, CLUTTER_TYPE_CONSTRAINT); -static void -update_actor_coords (ClutterBindConstraint *bind) -{ - gfloat source_width, source_height; - ClutterVertex source_position; - ClutterActor *actor; - - if (bind->source == NULL) - return; - - if (!clutter_actor_meta_get_enabled (CLUTTER_ACTOR_META (bind))) - return; - - actor = clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (bind)); - if (actor == NULL) - return; - - source_position.x = clutter_actor_get_x (bind->source); - source_position.y = clutter_actor_get_y (bind->source); - source_position.z = clutter_actor_get_depth (bind->source); - clutter_actor_get_size (bind->source, &source_width, &source_height); - - switch (bind->coordinate) - { - case CLUTTER_BIND_X: - clutter_actor_set_x (actor, source_position.x + bind->offset); - break; - - case CLUTTER_BIND_Y: - clutter_actor_set_y (actor, source_position.y + bind->offset); - break; - - case CLUTTER_BIND_Z: - clutter_actor_set_depth (actor, source_position.z + bind->offset); - break; - - case CLUTTER_BIND_WIDTH: - clutter_actor_set_width (actor, source_width + bind->offset); - break; - - case CLUTTER_BIND_HEIGHT: - clutter_actor_set_height (actor, source_height + bind->offset); - break; - } -} - static void source_allocation_changed (ClutterActor *source, const ClutterActorBox *allocation, ClutterAllocationFlags flags, ClutterBindConstraint *bind) { - update_actor_coords (bind); -} - -static void -source_depth_changed (GObject *gobject, - GParamSpec *pspec, - ClutterBindConstraint *bind) -{ - update_actor_coords (bind); + if (bind->actor != NULL) + clutter_actor_queue_relayout (bind->actor); } static void @@ -198,6 +146,69 @@ source_destroyed (ClutterActor *actor, bind->source = NULL; } +static void +clutter_bind_constraint_update_allocation (ClutterConstraint *constraint, + ClutterActor *actor, + ClutterActorBox *allocation) +{ + ClutterBindConstraint *bind = CLUTTER_BIND_CONSTRAINT (constraint); + ClutterActorMeta *meta = CLUTTER_ACTOR_META (constraint); + gfloat source_width, source_height; + gfloat actor_width, actor_height; + ClutterVertex source_position = { 0., }; + + if (bind->source == NULL) + return; + + if (!clutter_actor_meta_get_enabled (meta)) + return; + + source_position.x = clutter_actor_get_x (bind->source); + source_position.y = clutter_actor_get_y (bind->source); + clutter_actor_get_size (bind->source, &source_width, &source_height); + + clutter_actor_box_get_size (allocation, &actor_width, &actor_height); + + switch (bind->coordinate) + { + case CLUTTER_BIND_X: + allocation->x1 = source_position.x + bind->offset; + allocation->x2 = allocation->x1 + actor_width; + break; + + case CLUTTER_BIND_Y: + allocation->y1 = source_position.y + bind->offset; + allocation->y2 = allocation->y1 + actor_height; + break; + + case CLUTTER_BIND_WIDTH: + allocation->x2 = allocation->x1 + source_width + bind->offset; + break; + + case CLUTTER_BIND_HEIGHT: + allocation->y2 = allocation->y1 + source_height + bind->offset; + break; + + default: + g_assert_not_reached (); + break; + } +} + +static void +clutter_bind_constraint_set_actor (ClutterActorMeta *meta, + ClutterActor *new_actor) +{ + ClutterBindConstraint *bind = CLUTTER_BIND_CONSTRAINT (meta); + ClutterActorMetaClass *parent; + + /* store the pointer to the actor, for later use */ + bind->actor = new_actor; + + parent = CLUTTER_ACTOR_META_CLASS (clutter_bind_constraint_parent_class); + parent->set_actor (meta, new_actor); +} + static void clutter_bind_constraint_set_property (GObject *gobject, guint prop_id, @@ -257,12 +268,17 @@ clutter_bind_constraint_get_property (GObject *gobject, static void clutter_bind_constraint_class_init (ClutterBindConstraintClass *klass) { + ClutterActorMetaClass *meta_class = CLUTTER_ACTOR_META_CLASS (klass); + ClutterConstraintClass *constraint_class = CLUTTER_CONSTRAINT_CLASS (klass); GObjectClass *gobject_class = G_OBJECT_CLASS (klass); GParamSpec *pspec; gobject_class->set_property = clutter_bind_constraint_set_property; gobject_class->get_property = clutter_bind_constraint_get_property; + meta_class->set_actor = clutter_bind_constraint_set_actor; + + constraint_class->update_allocation = clutter_bind_constraint_update_allocation; /** * ClutterBindConstraint:source: * @@ -317,6 +333,7 @@ clutter_bind_constraint_class_init (ClutterBindConstraintClass *klass) static void clutter_bind_constraint_init (ClutterBindConstraint *self) { + self->actor = NULL; self->source = NULL; self->coordinate = CLUTTER_BIND_X; self->offset = 0.0f; @@ -368,6 +385,9 @@ clutter_bind_constraint_set_source (ClutterBindConstraint *constraint, g_return_if_fail (CLUTTER_IS_BIND_CONSTRAINT (constraint)); g_return_if_fail (source == NULL || CLUTTER_IS_ACTOR (source)); + if (constraint->source == source) + return; + old_source = constraint->source; if (old_source != NULL) { @@ -377,9 +397,6 @@ clutter_bind_constraint_set_source (ClutterBindConstraint *constraint, g_signal_handlers_disconnect_by_func (old_source, G_CALLBACK (source_allocation_changed), constraint); - g_signal_handlers_disconnect_by_func (old_source, - G_CALLBACK (source_depth_changed), - constraint); } constraint->source = source; @@ -388,14 +405,12 @@ clutter_bind_constraint_set_source (ClutterBindConstraint *constraint, g_signal_connect (constraint->source, "allocation-changed", G_CALLBACK (source_allocation_changed), constraint); - g_signal_connect (constraint->source, "notify::depth", - G_CALLBACK (source_depth_changed), - constraint); g_signal_connect (constraint->source, "destroy", G_CALLBACK (source_destroyed), constraint); - update_actor_coords (constraint); + if (constraint->actor != NULL) + clutter_actor_queue_relayout (constraint->actor); } _clutter_notify_by_pspec (G_OBJECT (constraint), obj_props[PROP_SOURCE]); @@ -439,7 +454,8 @@ clutter_bind_constraint_set_coordinate (ClutterBindConstraint *constraint, constraint->coordinate = coordinate; - update_actor_coords (constraint); + if (constraint->actor != NULL) + clutter_actor_queue_relayout (constraint->actor); _clutter_notify_by_pspec (G_OBJECT (constraint), obj_props[PROP_COORDINATE]); } @@ -483,7 +499,8 @@ clutter_bind_constraint_set_offset (ClutterBindConstraint *constraint, constraint->offset = offset; - update_actor_coords (constraint); + if (constraint->actor != NULL) + clutter_actor_queue_relayout (constraint->actor); _clutter_notify_by_pspec (G_OBJECT (constraint), obj_props[PROP_OFFSET]); } diff --git a/clutter/clutter-bind-constraint.h b/clutter/clutter-bind-constraint.h index 8eefa3e26..b88bfa432 100644 --- a/clutter/clutter-bind-constraint.h +++ b/clutter/clutter-bind-constraint.h @@ -51,7 +51,6 @@ typedef struct _ClutterBindConstraint ClutterBindConstraint; * ClutterBindCoordinate: * @CLUTTER_BIND_X: Bind the X coordinate * @CLUTTER_BIND_Y: Bind the Y coordinate - * @CLUTTER_BIND_Z: Bind the Z coordinate * @CLUTTER_BIND_WIDTH: Bind the width * @CLUTTER_BIND_HEIGHT: Bidng the height * @@ -62,7 +61,6 @@ typedef struct _ClutterBindConstraint ClutterBindConstraint; typedef enum { /*< prefix=CLUTTER_BIND >*/ CLUTTER_BIND_X, CLUTTER_BIND_Y, - CLUTTER_BIND_Z, CLUTTER_BIND_WIDTH, CLUTTER_BIND_HEIGHT } ClutterBindCoordinate;