From e4c948b1502707630f15cb4ef12c6b73f3298a34 Mon Sep 17 00:00:00 2001 From: Emmanuele Bassi Date: Mon, 27 Feb 2012 11:59:57 +0000 Subject: [PATCH] actor: Add a method for computing the default paint volume Now that ClutterActor has a default paint volume, subclasses may wish to retrieve it without chaining up to the parent's implementation of the get_paint_volume() function. The get_default_paint_volume() returns a ClutterPaintVolume pointer to the paint volume as computed by the default implementation of the get_paint_volume() virtual function; it can only be used immediately, as it's not guaranteed to survive across multiple frames. --- clutter/clutter-actor.c | 125 ++++++++++++++++++++++------- clutter/clutter-actor.h | 1 + clutter/clutter.symbols | 1 + doc/reference/clutter/clutter-sections.txt | 1 + 4 files changed, 99 insertions(+), 29 deletions(-) diff --git a/clutter/clutter-actor.c b/clutter/clutter-actor.c index 0dd2205..58d09bc 100644 --- a/clutter/clutter-actor.c +++ b/clutter/clutter-actor.c @@ -4683,33 +4683,11 @@ atk_implementor_iface_init (AtkImplementorIface *iface) } static gboolean -clutter_actor_real_get_paint_volume (ClutterActor *self, - ClutterPaintVolume *volume) +clutter_actor_update_default_paint_volume (ClutterActor *self, + ClutterPaintVolume *volume) { ClutterActorPrivate *priv = self->priv; - ClutterActor *child; - ClutterActorClass *klass; - gboolean res; - - klass = CLUTTER_ACTOR_GET_CLASS (self); - - /* XXX - this thoroughly sucks, but we don't want to penalize users - * who use ClutterActor as a "new ClutterGroup" by forcing a full-stage - * redraw. This should go away in 2.0. - */ - if (klass->paint == clutter_actor_real_paint && - klass->get_paint_volume == clutter_actor_real_get_paint_volume) - { - res = TRUE; - } - else - { - /* this is the default return value: we cannot know if a class - * is going to paint outside its allocation, so we take the - * conservative approach. - */ - res = FALSE; - } + gboolean res = FALSE; /* we start from the allocation */ clutter_paint_volume_set_width (volume, @@ -4730,6 +4708,8 @@ clutter_actor_real_get_paint_volume (ClutterActor *self, } else { + ClutterActor *child; + if (priv->has_clip && priv->clip.width >= 0 && priv->clip.height >= 0) @@ -4774,6 +4754,89 @@ clutter_actor_real_get_paint_volume (ClutterActor *self, } return res; + +} + +static gboolean +clutter_actor_real_get_paint_volume (ClutterActor *self, + ClutterPaintVolume *volume) +{ + ClutterActorClass *klass; + gboolean res; + + klass = CLUTTER_ACTOR_GET_CLASS (self); + + /* XXX - this thoroughly sucks, but we don't want to penalize users + * who use ClutterActor as a "new ClutterGroup" by forcing a full-stage + * redraw. This should go away in 2.0. + */ + if (klass->paint == clutter_actor_real_paint && + klass->get_paint_volume == clutter_actor_real_get_paint_volume) + { + res = TRUE; + } + else + { + /* this is the default return value: we cannot know if a class + * is going to paint outside its allocation, so we take the + * conservative approach. + */ + res = FALSE; + } + + if (clutter_actor_update_default_paint_volume (self, volume)) + return res; + + return FALSE; +} + +/** + * clutter_actor_get_default_paint_volume: + * @self: a #ClutterActor + * + * Retrieves the default paint volume for @self. + * + * This function provides the same #ClutterPaintVolume that would be + * computed by the default implementation inside #ClutterActor of the + * #ClutterActorClass.get_paint_volume() virtual function. + * + * This function should only be used by #ClutterActor subclasses that + * cannot chain up to the parent implementation when computing their + * paint volume. + * + * Return value: (transfer none): a pointer to the default + * #ClutterPaintVolume, relative to the #ClutterActor, or %NULL if + * the actor could not compute a valid paint volume. The returned value + * is not guaranteed to be stable across multiple frames, so if you + * want to retain it, you will need to copy it using + * clutter_paint_volume_copy(). + * + * Since: 1.10 + */ +const ClutterPaintVolume * +clutter_actor_get_default_paint_volume (ClutterActor *self) +{ + ClutterPaintVolume volume; + ClutterPaintVolume *res; + + g_return_val_if_fail (CLUTTER_IS_ACTOR (self), NULL); + + res = NULL; + _clutter_paint_volume_init_static (&volume, self); + if (clutter_actor_update_default_paint_volume (self, &volume)) + { + ClutterActor *stage = _clutter_actor_get_stage_internal (self); + + if (stage != NULL) + { + res = _clutter_stage_paint_volume_stack_allocate (CLUTTER_STAGE (stage)); + _clutter_paint_volume_copy_static (&volume, res); + } + } + + clutter_paint_volume_free (&volume); + + return res; } static gboolean @@ -14481,8 +14544,10 @@ _clutter_actor_get_paint_volume_mutable (ClutterActor *self) * ensure their volume has a depth of 0. (This will be true so long as * you don't call clutter_paint_volume_set_depth().) * - * Return value: (transfer none): a pointer to a #ClutterPaintVolume - * or %NULL if no volume could be determined. + * Return value: (transfer none): a pointer to a #ClutterPaintVolume, + * or %NULL if no volume could be determined. The returned pointer + * is not guaranteed to be valid across multiple frames; if you want + * to keep it, you will need to copy it using clutter_paint_volume_copy(). * * Since: 1.6 */ @@ -14512,8 +14577,10 @@ clutter_actor_get_paint_volume (ClutterActor *self) * transformed paint volume of all of its children and union them * together using clutter_paint_volume_union(). * - * Return value: (transfer none): a pointer to a #ClutterPaintVolume - * or %NULL if no volume could be determined. + * Return value: (transfer none): a pointer to a #ClutterPaintVolume, + * or %NULL if no volume could be determined. The returned pointer is + * not guaranteed to be valid across multiple frames; if you wish to + * keep it, you will have to copy it using clutter_paint_volume_copy(). * * Since: 1.6 */ diff --git a/clutter/clutter-actor.h b/clutter/clutter-actor.h index 56c785b..2e6c079 100644 --- a/clutter/clutter-actor.h +++ b/clutter/clutter-actor.h @@ -454,6 +454,7 @@ void clutter_actor_get_background_color const ClutterPaintVolume * clutter_actor_get_paint_volume (ClutterActor *self); const ClutterPaintVolume * clutter_actor_get_transformed_paint_volume (ClutterActor *self, ClutterActor *relative_to_ancestor); +const ClutterPaintVolume * clutter_actor_get_default_paint_volume (ClutterActor *self); /* Events */ void clutter_actor_set_reactive (ClutterActor *actor, diff --git a/clutter/clutter.symbols b/clutter/clutter.symbols index 56c896b..4d6773d 100644 --- a/clutter/clutter.symbols +++ b/clutter/clutter.symbols @@ -90,6 +90,7 @@ clutter_actor_get_clip clutter_actor_get_clip_to_allocation clutter_actor_get_constraint clutter_actor_get_constraints +clutter_actor_get_default_paint_volume clutter_actor_get_depth clutter_actor_get_effect clutter_actor_get_effects diff --git a/doc/reference/clutter/clutter-sections.txt b/doc/reference/clutter/clutter-sections.txt index 59f92e9..33d030b 100644 --- a/doc/reference/clutter/clutter-sections.txt +++ b/doc/reference/clutter/clutter-sections.txt @@ -444,6 +444,7 @@ clutter_actor_get_transformation_matrix clutter_actor_get_paint_volume clutter_actor_get_paint_box clutter_actor_get_transformed_paint_volume +clutter_actor_get_default_paint_volume clutter_actor_set_anchor_point -- 2.7.4