From 3f0f7c73e091c2179b2175eb56aef62f16dd9b10 Mon Sep 17 00:00:00 2001 From: Emmanuele Bassi Date: Thu, 28 Mar 2019 16:58:00 +0000 Subject: [PATCH] Connect LayoutManager to LayoutChild If we want to inspect the type of layout properties exposed by a GtkLayoutManager, we need a way to connect the layout manager type to the GtkLayoutChild type it creates. In order to do so, we can set the GtkLayoutChild type on a field of the GtkLayoutManagerClass structure. Storing the GtkLayoutChild type on the class structure of the layout manager also allows us to implement a default create_layout_child() virtual function. --- gtk/gtkfixedlayout.c | 2 ++ gtk/gtklayoutmanager.c | 42 ++++++++++++++++++++++++++++-------------- gtk/gtklayoutmanager.h | 3 +++ 3 files changed, 33 insertions(+), 14 deletions(-) diff --git a/gtk/gtkfixedlayout.c b/gtk/gtkfixedlayout.c index 0895753edf..94e4c687b2 100644 --- a/gtk/gtkfixedlayout.c +++ b/gtk/gtkfixedlayout.c @@ -314,6 +314,8 @@ gtk_fixed_layout_class_init (GtkFixedLayoutClass *klass) { GtkLayoutManagerClass *layout_class = GTK_LAYOUT_MANAGER_CLASS (klass); + layout_class->layout_child_type = GTK_TYPE_FIXED_LAYOUT_CHILD; + layout_class->measure = gtk_fixed_layout_measure; layout_class->allocate = gtk_fixed_layout_allocate; layout_class->create_layout_child = gtk_fixed_layout_create_layout_child; diff --git a/gtk/gtklayoutmanager.c b/gtk/gtklayoutmanager.c index 90432eed87..cd7d1406b1 100644 --- a/gtk/gtklayoutmanager.c +++ b/gtk/gtklayoutmanager.c @@ -97,8 +97,6 @@ typedef struct { G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (GtkLayoutManager, gtk_layout_manager, G_TYPE_OBJECT) -static GQuark quark_layout_child; - static GtkSizeRequestMode gtk_layout_manager_real_get_request_mode (GtkLayoutManager *manager, GtkWidget *widget) @@ -141,14 +139,32 @@ gtk_layout_manager_real_allocate (GtkLayoutManager *manager, LAYOUT_MANAGER_WARN_NOT_IMPLEMENTED (manager, allocate); } +static GtkLayoutChild * +gtk_layout_manager_real_create_layout_child (GtkLayoutManager *manager, + GtkWidget *widget, + GtkWidget *child) +{ + GtkLayoutManagerClass *manager_class = GTK_LAYOUT_MANAGER_GET_CLASS (manager); + + if (manager_class->layout_child_type == G_TYPE_INVALID) + { + LAYOUT_MANAGER_WARN_NOT_IMPLEMENTED (manager, create_layout_child); + return NULL; + } + + return g_object_new (manager_class->layout_child_type, + "layout-manager", manager, + "child-widget", widget, + NULL); +} + static void gtk_layout_manager_class_init (GtkLayoutManagerClass *klass) { klass->get_request_mode = gtk_layout_manager_real_get_request_mode; klass->measure = gtk_layout_manager_real_measure; klass->allocate = gtk_layout_manager_real_allocate; - - quark_layout_child = g_quark_from_static_string ("-GtkLayoutManager-layout-child"); + klass->create_layout_child = gtk_layout_manager_real_create_layout_child; } static void @@ -382,14 +398,6 @@ gtk_layout_manager_get_layout_child (GtkLayoutManager *manager, return NULL; } - if (GTK_LAYOUT_MANAGER_GET_CLASS (manager)->create_layout_child == NULL) - { - g_critical ("The layout manager of type %s %p does not create " - "GtkLayoutChild instances", - G_OBJECT_TYPE_NAME (manager), manager); - return NULL; - } - if (priv->layout_children == NULL) { priv->layout_children = g_hash_table_new_full (NULL, NULL, @@ -410,9 +418,15 @@ gtk_layout_manager_get_layout_child (GtkLayoutManager *manager, } res = GTK_LAYOUT_MANAGER_GET_CLASS (manager)->create_layout_child (manager, parent, child); - g_assert (res != NULL); - g_assert (g_type_is_a (G_OBJECT_TYPE (res), GTK_TYPE_LAYOUT_CHILD)); + if (res == NULL) + { + g_critical ("The layout manager of type %s %p does not create " + "GtkLayoutChild instances", + G_OBJECT_TYPE_NAME (manager), manager); + return NULL; + } + g_assert (g_type_is_a (G_OBJECT_TYPE (res), GTK_TYPE_LAYOUT_CHILD)); g_hash_table_insert (priv->layout_children, child, res); return res; diff --git a/gtk/gtklayoutmanager.h b/gtk/gtklayoutmanager.h index 53f4931c69..06659ee70e 100644 --- a/gtk/gtklayoutmanager.h +++ b/gtk/gtklayoutmanager.h @@ -39,6 +39,7 @@ G_DECLARE_DERIVABLE_TYPE (GtkLayoutManager, gtk_layout_manager, GTK, LAYOUT_MANA * sizes of the widget using the layout manager for a given orientation * @allocate: a virtual function, used to allocate the size of the widget * using the layout manager + * @layout_child_type: the type of #GtkLayoutChild used by this layout manager * @create_layout_child: a virtual function, used to create a #GtkLayoutChild * meta object for the layout properties * @@ -70,6 +71,8 @@ struct _GtkLayoutManagerClass int height, int baseline); + GType layout_child_type; + GtkLayoutChild * (* create_layout_child) (GtkLayoutManager *manager, GtkWidget *widget, GtkWidget *for_child);