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.
This commit is contained in:
Emmanuele Bassi 2007-11-23 17:12:27 +00:00
parent b0446d66fe
commit c4f89675e0
10 changed files with 89 additions and 40 deletions

View File

@ -1,3 +1,25 @@
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.

View File

@ -42,21 +42,21 @@
* <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);
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

View 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

View 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

View 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

View 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

View 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

View 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

View File

@ -1,3 +1,8 @@
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.

View 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