2007-11-23 Emmanuele Bassi <ebassi@openedhand.com>
authorEmmanuele Bassi <ebassi@openedhand.com>
Fri, 23 Nov 2007 17:12:27 +0000 (17:12 +0000)
committerEmmanuele Bassi <ebassi@openedhand.com>
Fri, 23 Nov 2007 17:12:27 +0000 (17:12 +0000)
* clutter/clutter-actor.c:
(clutter_actor_real_request_coords),
(clutter_actor_request_coords),
(clutter_actor_class_init): Provide a default ::request_coords()
implementation in ClutterActor and use it to store the bounding
box passed to clutter_actor_request_coords(). This makes the code
more reliable and clean, and avoids a call to the subclass
request_coords() method if the bounding box did not change. Now,
every class overriding ClutterActor::request_coords() *must* chain
up to the parent class method or the bounding box will not be
saved inside the ClutterActor structure.

* clutter/clutter-entry.c:
* clutter/clutter-group.c:
* clutter/clutter-hbox.c:
* clutter/clutter-label.c:
* clutter/clutter-texture.c:
* clutter/clutter-vbox.c: Chain up to the parent class
request_coords() method.

ChangeLog
clutter/clutter-actor.c
clutter/clutter-entry.c
clutter/clutter-group.c
clutter/clutter-hbox.c
clutter/clutter-label.c
clutter/clutter-texture.c
clutter/clutter-vbox.c
doc/reference/ChangeLog
doc/reference/subclassing-ClutterActor.sgml

index c335680..8108d2b 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,27 @@
 2007-11-23  Emmanuele Bassi  <ebassi@openedhand.com>
 
+       * clutter/clutter-actor.c:
+       (clutter_actor_real_request_coords),
+       (clutter_actor_request_coords),
+       (clutter_actor_class_init): Provide a default ::request_coords()
+       implementation in ClutterActor and use it to store the bounding
+       box passed to clutter_actor_request_coords(). This makes the code
+       more reliable and clean, and avoids a call to the subclass
+       request_coords() method if the bounding box did not change. Now,
+       every class overriding ClutterActor::request_coords() *must* chain
+       up to the parent class method or the bounding box will not be
+       saved inside the ClutterActor structure.
+       
+       * clutter/clutter-entry.c:
+       * clutter/clutter-group.c:
+       * clutter/clutter-hbox.c:
+       * clutter/clutter-label.c:
+       * clutter/clutter-texture.c:
+       * clutter/clutter-vbox.c: Chain up to the parent class
+       request_coords() method.
+
+2007-11-23  Emmanuele Bassi  <ebassi@openedhand.com>
+
        * clutter/clutter-event.h: Add more documentation.
 
 2007-11-23  Emmanuele Bassi  <ebassi@openedhand.com>
index 142bd2b..ae76f87 100644 (file)
  *   <listitem><para>Events are handled by connecting signal handlers to
  *   the numerous event signal types.</para></listitem>
  *   <listitem><para>Event handlers must return %TRUE if they handled
- *   the event and wish to block the event emission chain; and %FALSE
+ *   the event and wish to block the event emission chain, or %FALSE
  *   if the emission chain must continue</para></listitem>
  *   <listitem><para>Keyboard events are emitted if actor has focus, see
- *   clutter_stage_set_focus()</para></listitem>
- *   <listitem><para>Motion events (motion, enter, leave) are only emitted
- *   per actor if clutter_enable_motion_events() was called with %TRUE. If
- *   set to %FALSE (the default) then only the stage emits motion
- *   events (no enter or leave events).</para></listitem>
- *   <listitem><para>Once emitted, an event emmision chain has two
+ *   clutter_stage_set_key_focus()</para></listitem>
+ *   <listitem><para>Motion events (motion, enter, leave) are not emitted
+ *   if clutter_set_motion_events_enabled() is called with %FALSE.
+ *   See clutter_set_motion_events_enabled() documentation for more
+ *   information.</para></listitem>
+ *   <listitem><para>Once emitted, an event emission chain has two
  *   phases: capture and bubble. A emitted event starts in the capture
- *   phase beginning at the stage and transversing child actors until
- *   the event source actor is reached. The emmision then enters the bubble
- *   phase transversing back up via parents to the stage. An event
- *   handler can abort this chain at point by returning
- *   %TRUE.</para></listitem> 
+ *   phase beginning at the stage and traversing every child actor until
+ *   the event source actor is reached. The emission then enters the bubble
+ *   phase, traversing back up the chain via parents until it reaches the
+ *   stage. Any event handler can abort this chain by returning
+ *   %TRUE (meaning "event handled").</para></listitem> 
  *   <listitem><para>Pointer events will 'pass through' non reactive actors.
  *   </para></listitem> 
  * </orderedlist>
@@ -864,52 +864,59 @@ clutter_actor_paint (ClutterActor *self)
 
 #undef M
 
+static void
+clutter_actor_real_request_coords (ClutterActor    *self,
+                                   ClutterActorBox *box)
+{
+  self->priv->coords = *box;
+}
+
 /**
  * clutter_actor_request_coords:
  * @self: A #ClutterActor
- * @box: A #ClutterActorBox with requested new co-ordinates in ClutterUnits
+ * @box: A #ClutterActorBox with the new coordinates, in ClutterUnits
  *
- * Requests new untransformed co-ordinates for the #ClutterActor
- * ralative to any parent.
+ * Requests new untransformed coordinates for the bounding box of
+ * a #ClutterActor. The coordinates must be relative to the current
+ * parent of the actor.
  *
- * This function should not be called directly by applications instead
- * the various position/geometry methods should be used.
- **/
+ * This function should not be called directly by applications;
+ * instead, the various position/geometry methods should be used.
+ *
+ * Note: Actors overriding the ClutterActor::request_coords() virtual
+ * function should always chain up to the parent class request_coords()
+ * method. Actors should override this function only if they need to
+ * recompute some internal state or need to reposition their evental
+ * children.
+ */
 void
 clutter_actor_request_coords (ClutterActor    *self,
                              ClutterActorBox *box)
 {
-  ClutterActorClass *klass;
+  ClutterActorPrivate *priv;
   gboolean x_change, y_change, width_change, height_change;
 
   g_return_if_fail (CLUTTER_IS_ACTOR (self));
   g_return_if_fail (box != NULL);
 
-  klass = CLUTTER_ACTOR_GET_CLASS (self);
-
-  if (klass->request_coords)
-    klass->request_coords (self, box);
+  priv = self->priv;
 
-  x_change     = (self->priv->coords.x1 != box->x1);
-  y_change     = (self->priv->coords.y1 != box->y1);
-  width_change = ((self->priv->coords.x2 - self->priv->coords.x1) !=
-      (box->x2 - box->x1));
-  height_change = ((self->priv->coords.y2 - self->priv->coords.y1) !=
-                  (box->y2 - box->y1));
+  /* avoid calling request coords if the coordinates did not change */
+  x_change      = (priv->coords.x1 != box->x1);
+  y_change      = (priv->coords.y1 != box->y1);
+  width_change  = ((priv->coords.x2 - priv->coords.x1) != (box->x2 - box->x1));
+  height_change = ((priv->coords.y2 - priv->coords.y1) != (box->y2 - box->y1));
 
   if (x_change || y_change || width_change || height_change)
     {
-      self->priv->coords.x1 = box->x1;
-      self->priv->coords.y1 = box->y1;
-      self->priv->coords.x2 = box->x2;
-      self->priv->coords.y2 = box->y2;
+      g_object_ref (self);
+      g_object_freeze_notify (G_OBJECT (self));
+
+      CLUTTER_ACTOR_GET_CLASS (self)->request_coords (self, box);
 
       if (CLUTTER_ACTOR_IS_VISIBLE (self))
        clutter_actor_queue_redraw (self);
 
-      g_object_ref (self);
-      g_object_freeze_notify (G_OBJECT (self));
-
       if (x_change)
        g_object_notify (G_OBJECT (self), "x");
 
@@ -1646,6 +1653,7 @@ clutter_actor_class_init (ClutterActorClass *klass)
   klass->hide = clutter_actor_real_hide;
   klass->hide_all = clutter_actor_hide;
   klass->pick = clutter_actor_real_pick;
+  klass->request_coords = clutter_actor_real_request_coords;
 }
 
 static void
index b34ade7..99b6d3f 100644 (file)
@@ -491,6 +491,8 @@ clutter_entry_request_coords (ClutterActor    *self,
 
       priv->width = width;
     }
+
+  CLUTTER_ACTOR_CLASS (clutter_entry_parent_class)->request_coords (self, box);
 }
 
 static void
index 18af176..3e903e0 100644 (file)
@@ -124,8 +124,8 @@ clutter_group_pick (ClutterActor       *actor,
 
 
 static void
-clutter_group_request_coords (ClutterActor        *self,
-                             ClutterActorBox     *box)
+clutter_group_request_coords (ClutterActor    *self,
+                             ClutterActorBox *box)
 {
   ClutterActorBox cbox;
 
@@ -136,6 +136,8 @@ clutter_group_request_coords (ClutterActor        *self,
   */
   box->x2 = box->x1 + (cbox.x2 - cbox.x1);
   box->y2 = box->y1 + (cbox.y2 - cbox.y1);
+
+  CLUTTER_ACTOR_CLASS (clutter_group_parent_class)->request_coords (self, box);
 }
 
 static void
index 1660464..6e96cfe 100644 (file)
@@ -102,6 +102,8 @@ clutter_hbox_request_coords (ClutterActor    *actor,
   box->allocation.y1 = coords->y1;
   box->allocation.x2 = -1;
   box->allocation.y2 = -1;
+
+  CLUTTER_ACTOR_CLASS (clutter_hbox_parent_class)->request_coords (actor, coords);
 }
 
 static void
index 8538bee..90cdd81 100644 (file)
@@ -362,6 +362,8 @@ clutter_label_request_coords (ClutterActor    *self,
     clutter_label_clear_layout (label);
 
   priv->allocation = *box;
+
+  CLUTTER_ACTOR_CLASS (clutter_label_parent_class)->request_coords (self, box);
 }
 
 static void 
index 551cd0a..896fb83 100644 (file)
@@ -786,6 +786,8 @@ clutter_texture_request_coords (ClutterActor    *self,
   if (((box->x2 - box->x1) != (old_request.x2 - old_request.x1)) ||
       ((box->y2 - box->y1) != (old_request.y2 - old_request.y1)))
     texture->priv->sync_actor_size = FALSE;
+
+  CLUTTER_ACTOR_CLASS (clutter_texture_parent_class)->request_coords (self, box);
 }
 
 static void
index 19797ad..5041ced 100644 (file)
@@ -102,6 +102,8 @@ clutter_vbox_request_coords (ClutterActor    *actor,
   box->allocation.y1 = coords->y1;
   box->allocation.x2 = -1;
   box->allocation.y2 = -1;
+
+  CLUTTER_ACTOR_CLASS (clutter_vbox_parent_class)->request_coords (actor, coords);
 }
 
 static void
index e198375..2bc13a9 100644 (file)
@@ -1,5 +1,10 @@
 2007-11-23  Emmanuele Bassi  <ebassi@openedhand.com>
 
+       * subclassing-ClutterActor.sgml: Mention the chain-up needed when
+       overriding the request_coords() vfunc of ClutterActor.
+
+2007-11-23  Emmanuele Bassi  <ebassi@openedhand.com>
+
        * clutter-sections.txt: Add unused API.
 
 2007-11-21  Emmanuele Bassi  <ebassi@openedhand.com>
index 3ef2e52..d8af3fe 100644 (file)
@@ -77,8 +77,10 @@ foo_actor_query_coords (ClutterActor    *actor,
   is invoked when clutter_actor_request_coords() is called on an instance
   of that actor class. It is used to set the coordinates of the bounding
   box for the actor. Container actors, or composite actors with internal
-  children, should call clutter_actor_request_coords() on each visible
-  child.</para>
+  children, should override the request_coords() virtual function and call
+  clutter_actor_request_coords() on each visible child. Every actor class
+  overriding the request_coords() virtual function must chain up to the
+  parent class request_coords() method.</para>
 
   <para>The ClutterActor::paint() method should be overridden if the
   actor needs to control its drawing process, by using the GL API