mirror of
https://github.com/brl/mutter.git
synced 2025-01-12 04:34:40 +00:00
actor: Add :layout-manager
Now that ClutterActor implements the Container contract we can actually defer the size negotiation to a ClutterLayoutManager directly from the default implementation of the Actor's virtual functions.
This commit is contained in:
parent
b45d78e6a1
commit
11e876c86b
@ -492,6 +492,8 @@ struct _ClutterActorPrivate
|
|||||||
|
|
||||||
ClutterStageQueueRedrawEntry *queue_redraw_entry;
|
ClutterStageQueueRedrawEntry *queue_redraw_entry;
|
||||||
|
|
||||||
|
ClutterLayoutManager *layout_manager;
|
||||||
|
|
||||||
/* bitfields */
|
/* bitfields */
|
||||||
guint position_set : 1;
|
guint position_set : 1;
|
||||||
guint min_width_set : 1;
|
guint min_width_set : 1;
|
||||||
@ -608,6 +610,8 @@ enum
|
|||||||
PROP_CONSTRAINTS,
|
PROP_CONSTRAINTS,
|
||||||
PROP_EFFECT,
|
PROP_EFFECT,
|
||||||
|
|
||||||
|
PROP_LAYOUT_MANAGER,
|
||||||
|
|
||||||
PROP_LAST
|
PROP_LAST
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1756,6 +1760,26 @@ clutter_actor_real_get_preferred_width (ClutterActor *self,
|
|||||||
gfloat *min_width_p,
|
gfloat *min_width_p,
|
||||||
gfloat *natural_width_p)
|
gfloat *natural_width_p)
|
||||||
{
|
{
|
||||||
|
ClutterActorPrivate *priv = self->priv;
|
||||||
|
|
||||||
|
if (priv->children != NULL && priv->layout_manager != NULL)
|
||||||
|
{
|
||||||
|
ClutterContainer *container = CLUTTER_CONTAINER (self);
|
||||||
|
|
||||||
|
CLUTTER_NOTE (LAYOUT, "Querying the layout manager '%s'[%p] "
|
||||||
|
"for the preferred width",
|
||||||
|
G_OBJECT_TYPE_NAME (priv->layout_manager),
|
||||||
|
priv->layout_manager);
|
||||||
|
|
||||||
|
clutter_layout_manager_get_preferred_width (priv->layout_manager,
|
||||||
|
container,
|
||||||
|
for_height,
|
||||||
|
min_width_p,
|
||||||
|
natural_width_p);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/* Default implementation is always 0x0, usually an actor
|
/* Default implementation is always 0x0, usually an actor
|
||||||
* using this default is relying on someone to set the
|
* using this default is relying on someone to set the
|
||||||
* request manually
|
* request manually
|
||||||
@ -1775,6 +1799,25 @@ clutter_actor_real_get_preferred_height (ClutterActor *self,
|
|||||||
gfloat *min_height_p,
|
gfloat *min_height_p,
|
||||||
gfloat *natural_height_p)
|
gfloat *natural_height_p)
|
||||||
{
|
{
|
||||||
|
ClutterActorPrivate *priv = self->priv;
|
||||||
|
|
||||||
|
if (priv->children != NULL && priv->layout_manager != NULL)
|
||||||
|
{
|
||||||
|
ClutterContainer *container = CLUTTER_CONTAINER (self);
|
||||||
|
|
||||||
|
CLUTTER_NOTE (LAYOUT, "Querying the layout manager '%s'[%p] "
|
||||||
|
"for the preferred height",
|
||||||
|
G_OBJECT_TYPE_NAME (priv->layout_manager),
|
||||||
|
priv->layout_manager);
|
||||||
|
|
||||||
|
clutter_layout_manager_get_preferred_height (priv->layout_manager,
|
||||||
|
container,
|
||||||
|
for_width,
|
||||||
|
min_height_p,
|
||||||
|
natural_height_p);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
/* Default implementation is always 0x0, usually an actor
|
/* Default implementation is always 0x0, usually an actor
|
||||||
* using this default is relying on someone to set the
|
* using this default is relying on someone to set the
|
||||||
* request manually
|
* request manually
|
||||||
@ -1876,6 +1919,28 @@ clutter_actor_real_allocate (ClutterActor *self,
|
|||||||
priv->allocation_flags = flags;
|
priv->allocation_flags = flags;
|
||||||
priv->needs_allocation = FALSE;
|
priv->needs_allocation = FALSE;
|
||||||
|
|
||||||
|
/* we allocate our children before we notify changes in our geometry,
|
||||||
|
* so that people connecting to properties will be able to get valid
|
||||||
|
* data out of the sub-tree of the scene graph that has this actor at
|
||||||
|
* the root
|
||||||
|
*/
|
||||||
|
if (priv->children != NULL && priv->layout_manager != NULL)
|
||||||
|
{
|
||||||
|
ClutterContainer *container = CLUTTER_CONTAINER (self);
|
||||||
|
gfloat width, height;
|
||||||
|
ClutterActorBox children_box;
|
||||||
|
|
||||||
|
clutter_actor_box_get_size (&priv->allocation, &width, &height);
|
||||||
|
|
||||||
|
clutter_actor_box_set_origin (&children_box, 0, 0);
|
||||||
|
clutter_actor_box_set_size (&children_box, width, height);
|
||||||
|
|
||||||
|
clutter_layout_manager_allocate (priv->layout_manager,
|
||||||
|
container,
|
||||||
|
&children_box,
|
||||||
|
priv->allocation_flags);
|
||||||
|
}
|
||||||
|
|
||||||
g_object_freeze_notify (G_OBJECT (self));
|
g_object_freeze_notify (G_OBJECT (self));
|
||||||
|
|
||||||
if (x1_changed || y1_changed || x2_changed || y2_changed || flags_changed)
|
if (x1_changed || y1_changed || x2_changed || y2_changed || flags_changed)
|
||||||
@ -3466,6 +3531,10 @@ clutter_actor_set_property (GObject *object,
|
|||||||
clutter_actor_add_effect (actor, g_value_get_object (value));
|
clutter_actor_add_effect (actor, g_value_get_object (value));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case PROP_LAYOUT_MANAGER:
|
||||||
|
clutter_actor_set_layout_manager (actor, g_value_get_object (value));
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
break;
|
break;
|
||||||
@ -3731,6 +3800,10 @@ clutter_actor_get_property (GObject *object,
|
|||||||
g_value_set_boolean (value, priv->has_pointer);
|
g_value_set_boolean (value, priv->has_pointer);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case PROP_LAYOUT_MANAGER:
|
||||||
|
g_value_set_object (value, priv->layout_manager);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
break;
|
break;
|
||||||
@ -4759,6 +4832,15 @@ clutter_actor_class_init (ClutterActorClass *klass)
|
|||||||
obj_props[PROP_EFFECT] = pspec;
|
obj_props[PROP_EFFECT] = pspec;
|
||||||
g_object_class_install_property (object_class, PROP_EFFECT, pspec);
|
g_object_class_install_property (object_class, PROP_EFFECT, pspec);
|
||||||
|
|
||||||
|
obj_props[PROP_LAYOUT_MANAGER] =
|
||||||
|
g_param_spec_object ("layout-manager",
|
||||||
|
P_("Layout Manager"),
|
||||||
|
P_("The object controlling the layout of an actor's children"),
|
||||||
|
CLUTTER_TYPE_LAYOUT_MANAGER,
|
||||||
|
CLUTTER_PARAM_READWRITE);
|
||||||
|
g_object_class_install_property (object_class, PROP_LAYOUT_MANAGER,
|
||||||
|
obj_props[PROP_LAYOUT_MANAGER]);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ClutterActor::destroy:
|
* ClutterActor::destroy:
|
||||||
* @actor: the #ClutterActor which emitted the signal
|
* @actor: the #ClutterActor which emitted the signal
|
||||||
@ -12864,3 +12946,65 @@ _clutter_actor_traverse (ClutterActor *actor,
|
|||||||
0, /* start depth */
|
0, /* start depth */
|
||||||
user_data);
|
user_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
on_layout_manager_changed (ClutterLayoutManager *manager,
|
||||||
|
ClutterActor *self)
|
||||||
|
{
|
||||||
|
clutter_actor_queue_relayout (self);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
clutter_actor_set_layout_manager (ClutterActor *self,
|
||||||
|
ClutterLayoutManager *manager)
|
||||||
|
{
|
||||||
|
ClutterActorPrivate *priv;
|
||||||
|
|
||||||
|
g_return_if_fail (CLUTTER_IS_ACTOR (self));
|
||||||
|
g_return_if_fail (manager == NULL || CLUTTER_IS_LAYOUT_MANAGER (manager));
|
||||||
|
|
||||||
|
priv = self->priv;
|
||||||
|
|
||||||
|
if (priv->layout_manager != NULL)
|
||||||
|
{
|
||||||
|
g_signal_handlers_disconnect_by_func (priv->layout_manager,
|
||||||
|
G_CALLBACK (on_layout_manager_changed),
|
||||||
|
self);
|
||||||
|
clutter_layout_manager_set_container (priv->layout_manager, NULL);
|
||||||
|
g_object_unref (priv->layout_manager);
|
||||||
|
}
|
||||||
|
|
||||||
|
priv->layout_manager = manager;
|
||||||
|
|
||||||
|
if (priv->layout_manager != NULL)
|
||||||
|
{
|
||||||
|
g_object_ref_sink (priv->layout_manager);
|
||||||
|
clutter_layout_manager_set_container (priv->layout_manager,
|
||||||
|
CLUTTER_CONTAINER (self));
|
||||||
|
g_signal_connect (priv->layout_manager, "layout-changed",
|
||||||
|
G_CALLBACK (on_layout_manager_changed),
|
||||||
|
self);
|
||||||
|
}
|
||||||
|
|
||||||
|
clutter_actor_queue_relayout (self);
|
||||||
|
g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_LAYOUT_MANAGER]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* clutter_actor_get_layout_manager:
|
||||||
|
* @self: a #ClutterActor
|
||||||
|
*
|
||||||
|
* Retrieves the #ClutterLayoutManager used by @self.
|
||||||
|
*
|
||||||
|
* Return value: (transfer none): a pointer to the #ClutterLayoutManager,
|
||||||
|
* or %NULL
|
||||||
|
*
|
||||||
|
* Since: 1.10
|
||||||
|
*/
|
||||||
|
ClutterLayoutManager *
|
||||||
|
clutter_actor_get_layout_manager (ClutterActor *self)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (CLUTTER_IS_ACTOR (self), NULL);
|
||||||
|
|
||||||
|
return self->priv->layout_manager;
|
||||||
|
}
|
||||||
|
@ -363,6 +363,10 @@ void clutter_actor_set_x (ClutterActor
|
|||||||
gfloat x);
|
gfloat x);
|
||||||
void clutter_actor_set_y (ClutterActor *self,
|
void clutter_actor_set_y (ClutterActor *self,
|
||||||
gfloat y);
|
gfloat y);
|
||||||
|
void clutter_actor_set_layout_manager (ClutterActor *self,
|
||||||
|
ClutterLayoutManager *manager);
|
||||||
|
ClutterLayoutManager *clutter_actor_get_layout_manager (ClutterActor *self);
|
||||||
|
|
||||||
void clutter_actor_set_rotation (ClutterActor *self,
|
void clutter_actor_set_rotation (ClutterActor *self,
|
||||||
ClutterRotateAxis axis,
|
ClutterRotateAxis axis,
|
||||||
gdouble angle,
|
gdouble angle,
|
||||||
|
@ -43,7 +43,6 @@ G_BEGIN_DECLS
|
|||||||
#define CLUTTER_IS_LAYOUT_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CLUTTER_TYPE_LAYOUT_MANAGER))
|
#define CLUTTER_IS_LAYOUT_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CLUTTER_TYPE_LAYOUT_MANAGER))
|
||||||
#define CLUTTER_LAYOUT_MANAGER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CLUTTER_TYPE_LAYOUT_MANAGER, ClutterLayoutManagerClass))
|
#define CLUTTER_LAYOUT_MANAGER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CLUTTER_TYPE_LAYOUT_MANAGER, ClutterLayoutManagerClass))
|
||||||
|
|
||||||
typedef struct _ClutterLayoutManager ClutterLayoutManager;
|
|
||||||
typedef struct _ClutterLayoutManagerClass ClutterLayoutManagerClass;
|
typedef struct _ClutterLayoutManagerClass ClutterLayoutManagerClass;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -63,6 +63,7 @@ typedef struct _ClutterContainer ClutterContainer; /* dummy */
|
|||||||
typedef struct _ClutterChildMeta ClutterChildMeta;
|
typedef struct _ClutterChildMeta ClutterChildMeta;
|
||||||
typedef struct _ClutterLayoutMeta ClutterLayoutMeta;
|
typedef struct _ClutterLayoutMeta ClutterLayoutMeta;
|
||||||
typedef struct _ClutterActorMeta ClutterActorMeta;
|
typedef struct _ClutterActorMeta ClutterActorMeta;
|
||||||
|
typedef struct _ClutterLayoutManager ClutterLayoutManager;
|
||||||
|
|
||||||
typedef struct _ClutterAlpha ClutterAlpha;
|
typedef struct _ClutterAlpha ClutterAlpha;
|
||||||
typedef struct _ClutterAnimatable ClutterAnimatable; /* dummy */
|
typedef struct _ClutterAnimatable ClutterAnimatable; /* dummy */
|
||||||
|
Loading…
Reference in New Issue
Block a user