constraint: Add ::update_allocation()
authorEmmanuele Bassi <ebassi@linux.intel.com>
Fri, 17 Sep 2010 11:09:56 +0000 (12:09 +0100)
committerEmmanuele Bassi <ebassi@linux.intel.com>
Fri, 17 Sep 2010 11:17:50 +0000 (12:17 +0100)
The Constraint should plug directly into the allocation mechanism, and
modify the allocation of the actor to which they are applied to. This is
similar to the mechanism used by the Effect class to modify the paint
sequence of an actor.

clutter/clutter-actor.c
clutter/clutter-constraint.c
clutter/clutter-constraint.h
clutter/clutter-private.h

index 7706cf6..944c0a4 100644 (file)
@@ -1724,9 +1724,9 @@ clutter_actor_real_allocate (ClutterActor           *self,
   ClutterActorPrivate *priv = self->priv;
   gboolean x1_changed, y1_changed, x2_changed, y2_changed;
   gboolean flags_changed;
-  ClutterActorBox old = { 0, };
+  ClutterActorBox old_alloc = { 0, };
 
-  clutter_actor_store_old_geometry (self, &old);
+  clutter_actor_store_old_geometry (self, &old_alloc);
 
   x1_changed = priv->allocation.x1 != box->x1;
   y1_changed = priv->allocation.y1 != box->y1;
@@ -1749,11 +1749,11 @@ clutter_actor_real_allocate (ClutterActor           *self,
        * that wish to track the allocation flags
        */
       g_signal_emit (self, actor_signals[ALLOCATION_CHANGED], 0,
-                     box,
+                     &priv->allocation,
                      flags);
     }
 
-  clutter_actor_notify_if_geometry_changed (self, &old);
+  clutter_actor_notify_if_geometry_changed (self, &old_alloc);
 
   g_object_thaw_notify (G_OBJECT (self));
 }
@@ -4059,7 +4059,7 @@ clutter_actor_class_init (ClutterActorClass *klass)
   /**
    * ClutterActor:constraints:
    *
-   * Adds a #ClutterConstaint to the actor
+   * Adds a #ClutterConstraint to the actor
    *
    * Since: 1.4
    */
@@ -5279,6 +5279,7 @@ clutter_actor_allocate (ClutterActor           *self,
 {
   ClutterActorPrivate *priv;
   ClutterActorClass *klass;
+  ClutterActorBox alloc;
   gboolean child_moved;
 
   g_return_if_fail (CLUTTER_IS_ACTOR (self));
@@ -5292,8 +5293,22 @@ clutter_actor_allocate (ClutterActor           *self,
 
   priv = self->priv;
 
-  child_moved = (box->x1 != priv->allocation.x1 ||
-                 box->y1 != priv->allocation.y1);
+  alloc = *box;
+
+  if (priv->constraints != NULL)
+    {
+      const GList *constraints, *l;
+
+      constraints = _clutter_meta_group_peek_metas (priv->constraints);
+      for (l = constraints; l != NULL; l = l->next)
+        {
+          ClutterConstraint *constraint = l->data;
+          _clutter_constraint_update_allocation (constraint, self, &alloc);
+        }
+    }
+
+  child_moved = (alloc.x1 != priv->allocation.x1 ||
+                 alloc.y1 != priv->allocation.y1);
 
   /* If we get an allocation "out of the blue"
    * (we did not queue relayout), then we want to
@@ -5311,8 +5326,8 @@ clutter_actor_allocate (ClutterActor           *self,
   if (!priv->needs_allocation &&
       !(flags & CLUTTER_ABSOLUTE_ORIGIN_CHANGED) &&
       !child_moved &&
-      box->x2 == priv->allocation.x2 &&
-      box->y2 == priv->allocation.y2)
+      alloc.x2 == priv->allocation.x2 &&
+      alloc.y2 == priv->allocation.y2)
     {
       CLUTTER_NOTE (LAYOUT, "No allocation needed");
       return;
@@ -5330,7 +5345,7 @@ clutter_actor_allocate (ClutterActor           *self,
   CLUTTER_SET_PRIVATE_FLAGS (self, CLUTTER_IN_RELAYOUT);
 
   klass = CLUTTER_ACTOR_GET_CLASS (self);
-  klass->allocate (self, box, flags);
+  klass->allocate (self, &alloc, flags);
 
   CLUTTER_UNSET_PRIVATE_FLAGS (self, CLUTTER_IN_RELAYOUT);
 }
index 46f86f7..6e0bf28 100644 (file)
@@ -8,8 +8,10 @@
  * position or size.
  *
  * A #ClutterConstraint sub-class should contain the logic for modifying
- * the position or size of the #ClutterActor to which it is applied, using
- * the various signals and properties of #ClutterActor itself.
+ * the position or size of the #ClutterActor to which it is applied, by
+ * updating the actor's allocation. Each #ClutterConstraint can change the
+ * allocation of the actor to which they are applied by overriding the
+ * <function>update_allocation()</function> virtual function.
  *
  * #ClutterConstraint is available since Clutter 1.4
  */
@@ -20,6 +22,7 @@
 
 #include "clutter-constraint.h"
 
+#include "clutter-actor.h"
 #include "clutter-actor-meta-private.h"
 
 G_DEFINE_ABSTRACT_TYPE (ClutterConstraint,
@@ -27,11 +30,33 @@ G_DEFINE_ABSTRACT_TYPE (ClutterConstraint,
                         CLUTTER_TYPE_ACTOR_META);
 
 static void
+constraint_update_allocation (ClutterConstraint *constraint,
+                              ClutterActor      *actor,
+                              ClutterActorBox   *allocation)
+{
+}
+
+static void
 clutter_constraint_class_init (ClutterConstraintClass *klass)
 {
+  klass->update_allocation = constraint_update_allocation;
 }
 
 static void
 clutter_constraint_init (ClutterConstraint *self)
 {
 }
+
+void
+_clutter_constraint_update_allocation (ClutterConstraint *constraint,
+                                       ClutterActor      *actor,
+                                       ClutterActorBox   *allocation)
+{
+  g_return_if_fail (CLUTTER_IS_CONSTRAINT (constraint));
+  g_return_if_fail (CLUTTER_IS_ACTOR (actor));
+  g_return_if_fail (allocation != NULL);
+
+  CLUTTER_CONSTRAINT_GET_CLASS (constraint)->update_allocation (constraint,
+                                                                actor,
+                                                                allocation);
+}
index 9486705..6d2eabd 100644 (file)
@@ -69,6 +69,10 @@ struct _ClutterConstraintClass
   /*< private >*/
   ClutterActorMetaClass parent_class;
 
+  void (* update_allocation) (ClutterConstraint *constraint,
+                              ClutterActor      *actor,
+                              ClutterActorBox   *allocation);
+
   /*< private >*/
   void (* _clutter_constraint1) (void);
   void (* _clutter_constraint2) (void);
index 1c27aea..7c460d3 100644 (file)
@@ -383,6 +383,10 @@ gint32 _clutter_backend_get_units_serial (ClutterBackend *backend);
 gboolean _clutter_effect_pre_paint  (ClutterEffect *effect);
 void     _clutter_effect_post_paint (ClutterEffect *effect);
 
+void _clutter_constraint_update_allocation (ClutterConstraint *constraint,
+                                            ClutterActor      *actor,
+                                            ClutterActorBox   *allocation);
+
 GType _clutter_layout_manager_get_child_meta_type (ClutterLayoutManager *manager);
 
 void     _clutter_event_set_platform_data (ClutterEvent       *event,