diff --git a/ChangeLog b/ChangeLog index c33568088..8108d2b57 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,25 @@ +2007-11-23 Emmanuele Bassi + + * 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 * clutter/clutter-event.h: Add more documentation. diff --git a/clutter/clutter-actor.c b/clutter/clutter-actor.c index 142bd2b77..ae76f8728 100644 --- a/clutter/clutter-actor.c +++ b/clutter/clutter-actor.c @@ -42,21 +42,21 @@ * Events are handled by connecting signal handlers to * the numerous event signal types. * 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 * Keyboard events are emitted if actor has focus, see - * clutter_stage_set_focus() - * 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). - * Once emitted, an event emmision chain has two + * clutter_stage_set_key_focus() + * 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. + * 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. + * 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"). * Pointer events will 'pass through' non reactive actors. * * @@ -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); + priv = self->priv; - if (klass->request_coords) - klass->request_coords (self, box); - - 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 diff --git a/clutter/clutter-entry.c b/clutter/clutter-entry.c index b34ade7d1..99b6d3f0a 100644 --- a/clutter/clutter-entry.c +++ b/clutter/clutter-entry.c @@ -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 diff --git a/clutter/clutter-group.c b/clutter/clutter-group.c index 18af1766c..3e903e0b4 100644 --- a/clutter/clutter-group.c +++ b/clutter/clutter-group.c @@ -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 diff --git a/clutter/clutter-hbox.c b/clutter/clutter-hbox.c index 166046429..6e96cfe70 100644 --- a/clutter/clutter-hbox.c +++ b/clutter/clutter-hbox.c @@ -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 diff --git a/clutter/clutter-label.c b/clutter/clutter-label.c index 8538bee38..90cdd8127 100644 --- a/clutter/clutter-label.c +++ b/clutter/clutter-label.c @@ -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 diff --git a/clutter/clutter-texture.c b/clutter/clutter-texture.c index 551cd0a17..896fb83bd 100644 --- a/clutter/clutter-texture.c +++ b/clutter/clutter-texture.c @@ -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 diff --git a/clutter/clutter-vbox.c b/clutter/clutter-vbox.c index 19797ad2f..5041ced2c 100644 --- a/clutter/clutter-vbox.c +++ b/clutter/clutter-vbox.c @@ -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 diff --git a/doc/reference/ChangeLog b/doc/reference/ChangeLog index e198375e0..2bc13a952 100644 --- a/doc/reference/ChangeLog +++ b/doc/reference/ChangeLog @@ -1,3 +1,8 @@ +2007-11-23 Emmanuele Bassi + + * subclassing-ClutterActor.sgml: Mention the chain-up needed when + overriding the request_coords() vfunc of ClutterActor. + 2007-11-23 Emmanuele Bassi * clutter-sections.txt: Add unused API. diff --git a/doc/reference/subclassing-ClutterActor.sgml b/doc/reference/subclassing-ClutterActor.sgml index 3ef2e5217..d8af3fe43 100644 --- a/doc/reference/subclassing-ClutterActor.sgml +++ b/doc/reference/subclassing-ClutterActor.sgml @@ -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. + 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. The ClutterActor::paint() method should be overridden if the actor needs to control its drawing process, by using the GL API