[clutter/wip/actor-content: 13/33] actor: Use ClutterContent to paint and pick



commit 721da7f14fc495175a1219efff1de9a77814acbe
Author: Emmanuele Bassi <ebassi linux intel com>
Date:   Mon Dec 6 14:09:59 2010 +0000

    actor: Use ClutterContent to paint and pick
    
    Use the paint_content and the apply_mask methods for ::paint, and the
    apply_mask for ::pick.

 clutter/clutter-actor.c |   91 +++++++++++++++++++++++++++++++++++++++++++++-
 clutter/clutter-actor.h |    4 ++
 2 files changed, 93 insertions(+), 2 deletions(-)
---
diff --git a/clutter/clutter-actor.c b/clutter/clutter-actor.c
index fe97b75..47df665 100644
--- a/clutter/clutter-actor.c
+++ b/clutter/clutter-actor.c
@@ -294,6 +294,7 @@
 #include "clutter-behaviour.h"
 #include "clutter-constraint.h"
 #include "clutter-container.h"
+#include "clutter-content-private.h"
 #include "clutter-debug.h"
 #include "clutter-effect-private.h"
 #include "clutter-enum-types.h"
@@ -501,6 +502,8 @@ struct _ClutterActorPrivate
   ClutterPaintVolume last_paint_volume;
 
   ClutterStageQueueRedrawEntry *queue_redraw_entry;
+
+  ClutterContent *content;
 };
 
 enum
@@ -589,10 +592,12 @@ enum
   PROP_CONSTRAINTS,
   PROP_EFFECT,
 
+  PROP_CONTENT,
+
   PROP_LAST
 };
 
-static GParamSpec *obj_props[PROP_LAST];
+static GParamSpec *obj_props[PROP_LAST] = { NULL, };
 
 enum
 {
@@ -1672,10 +1677,18 @@ static void
 clutter_actor_real_pick (ClutterActor       *self,
 			 const ClutterColor *color)
 {
+  ClutterActorPrivate *priv = self->priv;
+
   /* the default implementation is just to paint a rectangle
    * with the same size of the actor using the passed color
    */
-  if (clutter_actor_should_pick_paint (self))
+
+  if (!clutter_actor_should_pick_paint (self))
+    return;
+
+  if (priv->content != NULL)
+    _clutter_content_pick_content (priv->content, self, color);
+  else
     {
       ClutterActorBox box = { 0, };
       float width, height;
@@ -2975,6 +2988,9 @@ clutter_actor_continue_paint (ClutterActor *self)
     {
       priv->propagated_one_redraw = FALSE;
 
+      if (priv->content != NULL)
+        clutter_content_paint_content (priv->content, self);
+
       g_signal_emit (self, actor_signals[PAINT], 0);
     }
   else
@@ -3668,6 +3684,13 @@ clutter_actor_dispose (GObject *object)
       priv->flatten_effect = NULL;
     }
 
+  if (priv->content != NULL)
+    {
+      _clutter_content_remove_actor (priv->content, self);
+      g_object_unref (priv->content);
+      priv->content = NULL;
+    }
+
   g_signal_emit (self, actor_signals[DESTROY], 0);
 
   G_OBJECT_CLASS (clutter_actor_parent_class)->dispose (object);
@@ -4645,6 +4668,15 @@ clutter_actor_class_init (ClutterActorClass *klass)
   obj_props[PROP_EFFECT] = pspec;
   g_object_class_install_property (object_class, PROP_EFFECT, pspec);
 
+  obj_props[PROP_CONTENT] =
+    g_param_spec_object ("content",
+                         P_("Content"),
+                         P_("The content object that should be painted"),
+                         CLUTTER_TYPE_CONTENT,
+                         CLUTTER_PARAM_READWRITE);
+  g_object_class_install_property (object_class, PROP_CONTENT,
+                                   obj_props[PROP_CONTENT]);
+
   /**
    * ClutterActor::destroy:
    * @actor: the #ClutterActor which emitted the signal
@@ -12097,6 +12129,23 @@ _clutter_actor_get_paint_volume_real (ClutterActor *self,
 
   _clutter_paint_volume_init_static (pv, self);
 
+  /* the default implementation of ClutterActor::get_paint_volume()
+   * returns FALSE; this means that if we create a base Actor and
+   * assign it a Content, the paint volume will be ignored by the
+   * check below. thus, if a Content is set, then it takes precedence
+   * over the Actor's implementation.
+   */
+  if (priv->content != NULL &&
+      !clutter_content_get_paint_volume (priv->content, self, pv))
+    {
+      clutter_paint_volume_free (pv);
+      CLUTTER_NOTE (CLIPPING, "Bail from get_paint_volume (%s): "
+                    "Content %s failed to report a volume",
+                    _clutter_actor_get_debug_name (self),
+                    G_OBJECT_TYPE_NAME (priv->content));
+      return FALSE;
+    }
+
   if (!CLUTTER_ACTOR_GET_CLASS (self)->get_paint_volume (self, pv))
     {
       clutter_paint_volume_free (pv);
@@ -12503,3 +12552,41 @@ _clutter_actor_traverse (ClutterActor              *actor,
                                    0, /* start depth */
                                    user_data);
 }
+
+void
+clutter_actor_set_content (ClutterActor   *self,
+                           ClutterContent *content)
+{
+  ClutterActorPrivate *priv;
+
+  g_return_if_fail (CLUTTER_IS_ACTOR (self));
+  g_return_if_fail (content == NULL || CLUTTER_IS_CONTENT (content));
+
+  priv = self->priv;
+
+  if (priv->content == content)
+    return;
+
+  if (priv->content != NULL)
+    {
+      _clutter_content_remove_actor (priv->content, self);
+      g_object_unref (priv->content);
+    }
+
+  priv->content = content;
+  if (priv->content != NULL)
+    {
+      g_object_ref (priv->content);
+      _clutter_content_add_actor (priv->content, self);
+    }
+
+  g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_CONTENT]);
+}
+
+ClutterContent *
+clutter_actor_get_content (ClutterActor *self)
+{
+  g_return_val_if_fail (CLUTTER_IS_ACTOR (self), NULL);
+
+  return self->priv->content;
+}
diff --git a/clutter/clutter-actor.h b/clutter/clutter-actor.h
index 68a5e0f..f8de547 100644
--- a/clutter/clutter-actor.h
+++ b/clutter/clutter-actor.h
@@ -620,6 +620,10 @@ gboolean             clutter_actor_get_paint_box      (ClutterActor         *sel
 
 gboolean             clutter_actor_has_overlaps       (ClutterActor         *self);
 
+void                 clutter_actor_set_content        (ClutterActor         *self,
+                                                       ClutterContent       *content);
+ClutterContent *     clutter_actor_get_content        (ClutterActor         *self);
+
 G_END_DECLS
 
 #endif /* __CLUTTER_ACTOR_H__ */



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]