clutter/actor: Allow specifying the layout manager for an actor type

Some actors have a well-defined layout manager other than FixedLayout.

If they do, we can handle the layout manager creation at the
ClutterActor instantiation, like GTK does for widget layout managers.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3445>
This commit is contained in:
Florian Müllner 2023-12-06 15:01:21 +01:00 committed by Marge Bot
parent 289e511c1a
commit 5291be8f30
2 changed files with 74 additions and 1 deletions

View File

@ -5654,11 +5654,19 @@ clutter_actor_constructor (GType gtype,
if (self->priv->layout_manager == NULL)
{
ClutterActorClass *actor_class;
ClutterLayoutManager *default_layout;
GType layout_manager_type;
actor_class = CLUTTER_ACTOR_GET_CLASS (self);
layout_manager_type = clutter_actor_class_get_layout_manager_type (actor_class);
if (layout_manager_type == G_TYPE_INVALID)
layout_manager_type = CLUTTER_TYPE_FIXED_LAYOUT;
CLUTTER_NOTE (LAYOUT, "Creating default layout manager");
default_layout = clutter_fixed_layout_new ();
default_layout = g_object_new (layout_manager_type, NULL);
clutter_actor_set_layout_manager (self, default_layout);
}
@ -5711,6 +5719,8 @@ clutter_actor_class_init (ClutterActorClass *klass)
klass->paint = clutter_actor_real_paint;
klass->destroy = clutter_actor_real_destroy;
klass->layout_manager_type = G_TYPE_INVALID;
/**
* ClutterActor:x:
*
@ -15413,12 +15423,25 @@ clutter_actor_set_layout_manager (ClutterActor *self,
ClutterLayoutManager *manager)
{
ClutterActorPrivate *priv;
GType expected_type, manager_type;
g_return_if_fail (CLUTTER_IS_ACTOR (self));
g_return_if_fail (manager == NULL || CLUTTER_IS_LAYOUT_MANAGER (manager));
priv = self->priv;
expected_type = clutter_actor_class_get_layout_manager_type (CLUTTER_ACTOR_GET_CLASS (self));
manager_type = manager != NULL ? G_TYPE_FROM_INSTANCE (manager) : G_TYPE_INVALID;
if (expected_type != G_TYPE_INVALID &&
manager_type != G_TYPE_INVALID &&
!g_type_is_a (manager_type, expected_type))
{
g_warning ("Trying to set layout manager of type %s, but actor only accepts %s",
g_type_name (manager_type), g_type_name (expected_type));
return;
}
if (priv->layout_manager != NULL)
{
g_clear_signal_handler (&priv->layout_changed_id, priv->layout_manager);
@ -18616,3 +18639,44 @@ clutter_actor_notify_transform_invalid (ClutterActor *self)
if (!graphene_matrix_equal (&old_transform, &priv->transform))
clutter_actor_queue_redraw (self);
}
/**
* clutter_actor_class_set_layout_manager_type
* @actor_class: A #ClutterActor class
* @type: A #GType
*
* Sets the type to be used for creating layout managers for
* actors of @actor_class.
*
* The given @type must be a subtype of [class@Clutter.LayoutManager].
*
* This function should only be called from class init functions of actors.
*/
void
clutter_actor_class_set_layout_manager_type (ClutterActorClass *actor_class,
GType type)
{
g_return_if_fail (CLUTTER_IS_ACTOR_CLASS (actor_class));
g_return_if_fail (g_type_is_a (type, CLUTTER_TYPE_LAYOUT_MANAGER));
actor_class->layout_manager_type = type;
}
/**
* clutter_actor_class_get_layout_manager_type
* @actor_class: A #ClutterActor class
*
* Retrieves the type of the [class@Clutter.LayoutManager]
* used by actors of class @actor_class.
*
* See also: [method@Clutter.ActorClass.set_layout_manager_type].
*
* Returns: type of a `ClutterLayoutManager` subclass, or %G_TYPE_INVALID
*/
GType
clutter_actor_class_get_layout_manager_type (ClutterActorClass *actor_class)
{
g_return_val_if_fail (CLUTTER_IS_ACTOR_CLASS (actor_class), G_TYPE_INVALID);
return actor_class->layout_manager_type;
}

View File

@ -251,6 +251,9 @@ struct _ClutterActorClass
ClutterActor *child);
void (* child_removed) (ClutterActor *self,
ClutterActor *child);
/* private */
GType layout_manager_type;
};
/**
@ -883,4 +886,10 @@ void clutter_actor_invalidate_transform (ClutterActor *self);
CLUTTER_EXPORT
void clutter_actor_invalidate_paint_volume (ClutterActor *self);
CLUTTER_EXPORT
void clutter_actor_class_set_layout_manager_type (ClutterActorClass *actor_class,
GType type);
CLUTTER_EXPORT
GType clutter_actor_class_get_layout_manager_type (ClutterActorClass *actor_class);
G_END_DECLS