[gnome-software: 99/110] gs-info-window: Port to GTK4




commit de22d07b2a3a06c598611a2bbdf857ed2e2c9229
Author: Georges Basile Stavracas Neto <georges stavracas gmail com>
Date:   Tue Sep 28 16:36:17 2021 -0300

    gs-info-window: Port to GTK4
    
    Use a custom GtkBuildable implementation to achieve the
    same behavior of the previous GtkContainer code.

 src/gs-info-window.c | 100 +++++++++++++++++++++------------------------------
 src/gs-info-window.h |   2 ++
 2 files changed, 43 insertions(+), 59 deletions(-)
---
diff --git a/src/gs-info-window.c b/src/gs-info-window.c
index 33f0d5949..92b755fa9 100644
--- a/src/gs-info-window.c
+++ b/src/gs-info-window.c
@@ -34,12 +34,15 @@
 typedef struct
 {
        GtkWidget       *overlay;
-
-       GtkWidget       *user_widget;
 } GsInfoWindowPrivate;
 
+static void gs_info_window_buildable_init (GtkBuildableIface *iface);
+
+G_DEFINE_TYPE_WITH_CODE (GsInfoWindow, gs_info_window, ADW_TYPE_WINDOW,
+                        G_ADD_PRIVATE (GsInfoWindow)
+                        G_IMPLEMENT_INTERFACE (GTK_TYPE_BUILDABLE, gs_info_window_buildable_init))
 
-G_DEFINE_TYPE_WITH_PRIVATE (GsInfoWindow, gs_info_window, ADW_TYPE_WINDOW)
+static GtkBuildableIface *parent_buildable_iface;
 
 static void
 gs_info_window_init (GsInfoWindow *self)
@@ -48,77 +51,35 @@ gs_info_window_init (GsInfoWindow *self)
 }
 
 static void
-gs_info_window_destroy (GtkWidget *widget)
+gs_info_window_buildable_add_child (GtkBuildable *buildable,
+                                    GtkBuilder   *builder,
+                                    GObject      *child,
+                                    const char   *type)
 {
-       GsInfoWindow *self = GS_INFO_WINDOW (widget);
+       GsInfoWindow *self = GS_INFO_WINDOW (buildable);
        GsInfoWindowPrivate *priv = gs_info_window_get_instance_private (self);
 
-       if (priv->overlay) {
-               gtk_container_remove (GTK_CONTAINER (self), priv->overlay);
-               priv->user_widget = NULL;
-       }
-
-       GTK_WIDGET_CLASS (gs_info_window_parent_class)->destroy (widget);
+       if (!priv->overlay)
+               parent_buildable_iface->add_child (buildable, builder, child, type);
+       else if (GTK_IS_WIDGET (child))
+               gs_info_window_set_child (self, GTK_WIDGET (child));
+       else
+               GTK_BUILDER_WARN_INVALID_CHILD_TYPE (buildable, type);
 }
 
 static void
-gs_info_window_add (GtkContainer *container, GtkWidget *child)
+gs_info_window_buildable_init (GtkBuildableIface *iface)
 {
-       GsInfoWindow *self = GS_INFO_WINDOW (container);
-       GsInfoWindowPrivate *priv = gs_info_window_get_instance_private (self);
+       parent_buildable_iface = g_type_interface_peek_parent (iface);
 
-       if (!priv->overlay) {
-               GTK_CONTAINER_CLASS (gs_info_window_parent_class)->add (container, child);
-       } else if (!priv->user_widget) {
-               gtk_container_add (GTK_CONTAINER (priv->overlay), child);
-               priv->user_widget = child;
-       } else {
-               g_warning ("Attempting to add a second child to a GsInfoWindow, but a GsInfoWindow can only 
have one child");
-       }
-}
-
-static void
-gs_info_window_remove (GtkContainer *container, GtkWidget *child)
-{
-       GsInfoWindow *self = GS_INFO_WINDOW (container);
-       GsInfoWindowPrivate *priv = gs_info_window_get_instance_private (self);
-
-       if (child == priv->overlay) {
-               GTK_CONTAINER_CLASS (gs_info_window_parent_class)->remove (container, child);
-       } else if (child == priv->user_widget) {
-               gtk_container_remove (GTK_CONTAINER (priv->overlay), child);
-               priv->user_widget = NULL;
-       } else {
-               g_return_if_reached ();
-       }
-}
-
-static void
-gs_info_window_forall (GtkContainer *container, gboolean include_internals, GtkCallback callback, gpointer 
callback_data)
-{
-       GsInfoWindow *self = GS_INFO_WINDOW (container);
-       GsInfoWindowPrivate *priv = gs_info_window_get_instance_private (self);
+       iface->add_child = gs_info_window_buildable_add_child;
 
-       if (include_internals) {
-               GTK_CONTAINER_CLASS (gs_info_window_parent_class)->forall (container,
-                                                                          include_internals,
-                                                                          callback,
-                                                                          callback_data);
-       } else if (priv->user_widget) {
-               callback (priv->user_widget, callback_data);
-       }
 }
 
 static void
 gs_info_window_class_init (GsInfoWindowClass *klass)
 {
        GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
-       GtkContainerClass *container_class = GTK_CONTAINER_CLASS (klass);
-
-       widget_class->destroy = gs_info_window_destroy;
-       container_class->add = gs_info_window_add;
-       container_class->remove = gs_info_window_remove;
-       container_class->forall = gs_info_window_forall;
 
        gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/Software/gs-info-window.ui");
 
@@ -140,3 +101,24 @@ gs_info_window_new (void)
 {
        return g_object_new (GS_TYPE_INFO_WINDOW, NULL);
 }
+
+/**
+ * gs_info_window_set_child:
+ * @self: a #GsInfoWindow
+ * @widget: (nullable): the new child of @self
+ *
+ * Create a new #GsInfoWindow.
+ *
+ * Since: 42
+ */
+void
+gs_info_window_set_child (GsInfoWindow *self,
+                          GtkWidget    *widget)
+{
+       GsInfoWindowPrivate *priv;
+       g_return_if_fail (GS_IS_INFO_WINDOW (self));
+       g_return_if_fail (widget == NULL || GTK_IS_WIDGET (widget));
+
+       priv = gs_info_window_get_instance_private (self);
+       gtk_overlay_set_child (GTK_OVERLAY (priv->overlay), widget);
+}
diff --git a/src/gs-info-window.h b/src/gs-info-window.h
index 7a12207e2..30c8f4f5b 100644
--- a/src/gs-info-window.h
+++ b/src/gs-info-window.h
@@ -28,4 +28,6 @@ struct _GsInfoWindowClass
 
 GsInfoWindow   *gs_info_window_new     (void);
 
+void           gs_info_window_set_child (GsInfoWindow *self,
+                                         GtkWidget    *widget);
 G_END_DECLS


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]