Add ::queue-relayout signal to ClutterActor for ClutterClone

ClutterClone bases its preferred size on the preferred size of
the source actor, so it needs to invalid its cached preferred
size when the preferred size of the source actor changes.

In order for this to work, we need to have notification when
the size of the source actor changes, so add a ::queue-relayout
signal to ClutterActor.

Then connect to this from ClutterClone and queue a relayout
on the clone when a relayout is queued on the source.

http://bugzilla.openedhand.com/show_bug.cgi?id=1755

Signed-off-by: Emmanuele Bassi <ebassi@linux.intel.com>
This commit is contained in:
Owen W. Taylor 2009-08-07 21:16:04 -04:00 committed by Emmanuele Bassi
parent 56daae9d7b
commit 93e1d8e7a3
3 changed files with 62 additions and 11 deletions

View File

@ -425,6 +425,7 @@ enum
REALIZE,
UNREALIZE,
QUEUE_REDRAW,
QUEUE_RELAYOUT,
EVENT,
CAPTURED_EVENT,
BUTTON_PRESS_EVENT,
@ -1609,6 +1610,23 @@ clutter_actor_real_queue_redraw (ClutterActor *self,
}
}
void
clutter_actor_real_queue_relayout (ClutterActor *self)
{
ClutterActorPrivate *priv = self->priv;
priv->needs_width_request = TRUE;
priv->needs_height_request = TRUE;
priv->needs_allocation = TRUE;
/* always repaint also (no-op if not mapped) */
clutter_actor_queue_redraw (self);
/* We need to go all the way up the hierarchy */
if (priv->parent_actor)
clutter_actor_queue_relayout (priv->parent_actor);
}
/* like ClutterVertex, but with a w component */
typedef struct {
gfloat x;
@ -3851,6 +3869,32 @@ clutter_actor_class_init (ClutterActorClass *klass)
G_TYPE_NONE, 1,
CLUTTER_TYPE_ACTOR);
/**
* ClutterActor::queue-relayout
* @actor: the actor being queued for relayout
*
* The ::queue_layout signal is emitted when clutter_actor_queue_relayout()
* is called on an actor.
*
* The default implementation for #ClutterActor chains up to the
* parent actor and queues a relayout on the parent, thus "bubbling"
* the relayout queue up through the actor graph.
*
* The main purpose of this signal is to allow relayout to be propagated
* properly in the procense of #ClutterClone actors. Applications will
* not normally need to connect to this signal.
*
* Since: 1.2
*/
actor_signals[QUEUE_RELAYOUT] =
g_signal_new (I_("queue-relayout"),
G_TYPE_FROM_CLASS (object_class),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (ClutterActorClass, queue_relayout),
NULL, NULL,
clutter_marshal_VOID__VOID,
G_TYPE_NONE, 0);
/**
* ClutterActor::event:
* @actor: the actor which received the event
@ -4262,6 +4306,7 @@ clutter_actor_class_init (ClutterActorClass *klass)
klass->get_preferred_height = clutter_actor_real_get_preferred_height;
klass->allocate = clutter_actor_real_allocate;
klass->queue_redraw = clutter_actor_real_queue_redraw;
klass->queue_relayout = clutter_actor_real_queue_relayout;
klass->apply_transform = clutter_actor_real_apply_transform;
}
@ -4385,16 +4430,7 @@ clutter_actor_queue_relayout (ClutterActor *self)
priv->needs_allocation)
return; /* save some cpu cycles */
priv->needs_width_request = TRUE;
priv->needs_height_request = TRUE;
priv->needs_allocation = TRUE;
/* always repaint also (no-op if not mapped) */
clutter_actor_queue_redraw (self);
/* We need to go all the way up the hierarchy */
if (priv->parent_actor)
clutter_actor_queue_relayout (priv->parent_actor);
g_signal_emit (self, actor_signals[QUEUE_RELAYOUT], 0);
}
/**

View File

@ -202,6 +202,7 @@ struct _ClutterActor
* @captured_event: signal class closure for #ClutterActor::captured-event
* @key_focus_in: signal class closure for #ClutterActor::focus-in
* @key_focus_out: signal class closure for #ClutterActor::focus-out
* @queue_relayout: class handler for #ClutterActor::queue-relayout
*
* Base class for actors.
*/
@ -271,9 +272,11 @@ struct _ClutterActorClass
void (* key_focus_in) (ClutterActor *actor);
void (* key_focus_out) (ClutterActor *actor);
void (* queue_relayout) (ClutterActor *actor);
/*< private >*/
/* padding for future expansion */
gpointer _padding_dummy[32];
gpointer _padding_dummy[31];
};
GType clutter_actor_get_type (void) G_GNUC_CONST;

View File

@ -313,6 +313,13 @@ clone_source_queue_redraw_cb (ClutterActor *source,
clutter_actor_queue_redraw (CLUTTER_ACTOR (clone));
}
static void
clone_source_queue_relayout_cb (ClutterActor *source,
ClutterClone *clone)
{
clutter_actor_queue_relayout (CLUTTER_ACTOR (clone));
}
static void
clutter_clone_set_source_internal (ClutterClone *clone,
ClutterActor *source)
@ -329,6 +336,9 @@ clutter_clone_set_source_internal (ClutterClone *clone,
g_signal_handlers_disconnect_by_func (priv->clone_source,
(void *) clone_source_queue_redraw_cb,
clone);
g_signal_handlers_disconnect_by_func (priv->clone_source,
(void *) clone_source_queue_relayout_cb,
clone);
g_object_unref (priv->clone_source);
priv->clone_source = NULL;
}
@ -338,6 +348,8 @@ clutter_clone_set_source_internal (ClutterClone *clone,
priv->clone_source = g_object_ref (source);
g_signal_connect (priv->clone_source, "queue-redraw",
G_CALLBACK (clone_source_queue_redraw_cb), clone);
g_signal_connect (priv->clone_source, "queue-relayout",
G_CALLBACK (clone_source_queue_relayout_cb), clone);
}
g_object_notify (G_OBJECT (clone), "source");