[gtk/bin-removal: 28/44] flowboxchild: Derive from GtkWidget



commit dbbf4f52ca5c394b00a3a26ad1a41a5e35d96073
Author: Matthias Clasen <mclasen redhat com>
Date:   Sat May 2 20:53:40 2020 -0400

    flowboxchild: Derive from GtkWidget
    
    We want to remove GtkBin and GtkContainer as they don't
    provide much useful functionality anymore.
    
    See #2681

 docs/reference/gtk/gtk4-sections.txt |   2 +
 gtk/gtkflowbox.c                     | 171 +++++++++++++++++++++++++++++++++--
 gtk/gtkflowbox.h                     |  11 ++-
 3 files changed, 174 insertions(+), 10 deletions(-)
---
diff --git a/docs/reference/gtk/gtk4-sections.txt b/docs/reference/gtk/gtk4-sections.txt
index 32b14b1ed6..2e94aef317 100644
--- a/docs/reference/gtk/gtk4-sections.txt
+++ b/docs/reference/gtk/gtk4-sections.txt
@@ -5758,6 +5758,8 @@ gtk_flow_box_bind_model
 <SUBSECTION GtkFlowBoxChild>
 GtkFlowBoxChild
 gtk_flow_box_child_new
+gtk_flow_box_child_set_child
+gtk_flow_box_child_get_child
 gtk_flow_box_child_get_index
 gtk_flow_box_child_is_selected
 gtk_flow_box_child_changed
diff --git a/gtk/gtkflowbox.c b/gtk/gtkflowbox.c
index e0f0a61317..7324d2992f 100644
--- a/gtk/gtkflowbox.c
+++ b/gtk/gtkflowbox.c
@@ -79,6 +79,8 @@
 #include "gtkflowboxprivate.h"
 
 #include "gtkadjustment.h"
+#include "gtkbinlayout.h"
+#include "gtkbuildable.h"
 #include "gtkcsscolorvalueprivate.h"
 #include "gtkcssnodeprivate.h"
 #include "gtkgesturedrag.h"
@@ -99,7 +101,7 @@
 
 #include "a11y/gtkflowboxaccessibleprivate.h"
 #include "a11y/gtkflowboxchildaccessible.h"
-
+ 
 /* Forward declarations and utilities {{{1 */
 
 static void gtk_flow_box_update_cursor       (GtkFlowBox      *box,
@@ -256,16 +258,26 @@ enum {
 
 static guint child_signals[CHILD_LAST_SIGNAL] = { 0 };
 
+enum {
+  PROP_CHILD = 1
+};
+
 typedef struct _GtkFlowBoxChildPrivate GtkFlowBoxChildPrivate;
 struct _GtkFlowBoxChildPrivate
 {
+  GtkWidget     *child;
   GSequenceIter *iter;
   gboolean       selected;
 };
 
 #define CHILD_PRIV(child) ((GtkFlowBoxChildPrivate*)gtk_flow_box_child_get_instance_private 
((GtkFlowBoxChild*)(child)))
 
-G_DEFINE_TYPE_WITH_PRIVATE (GtkFlowBoxChild, gtk_flow_box_child, GTK_TYPE_BIN)
+static void gtk_flow_box_child_buildable_iface_init (GtkBuildableIface *iface);
+
+G_DEFINE_TYPE_WITH_CODE (GtkFlowBoxChild, gtk_flow_box_child, GTK_TYPE_WIDGET,
+                         G_ADD_PRIVATE (GtkFlowBoxChild)
+                         G_IMPLEMENT_INTERFACE (GTK_TYPE_BUILDABLE,
+                                                gtk_flow_box_child_buildable_iface_init))
 
 /* Internal API {{{2 */
 
@@ -291,14 +303,36 @@ gtk_flow_box_child_set_focus (GtkFlowBoxChild *child)
 
 /* GtkWidget implementation {{{2 */
 
+static GtkBuildableIface *parent_child_buildable_iface;
+
+static void
+gtk_flow_box_child_buildable_add_child (GtkBuildable *buildable,
+                                        GtkBuilder   *builder,
+                                        GObject      *child,
+                                        const gchar  *type)
+{
+  if (GTK_IS_WIDGET (child))
+    gtk_flow_box_child_set_child (GTK_FLOW_BOX_CHILD (buildable), GTK_WIDGET (child));
+  else
+    parent_child_buildable_iface->add_child (buildable, builder, child, type);
+}
+
+static void
+gtk_flow_box_child_buildable_iface_init (GtkBuildableIface *iface)
+{
+  parent_child_buildable_iface = g_type_interface_peek_parent (iface);
+
+  iface->add_child = gtk_flow_box_child_buildable_add_child;
+}
+
 static gboolean
 gtk_flow_box_child_focus (GtkWidget        *widget,
                           GtkDirectionType  direction)
 {
+  GtkFlowBoxChild *self = GTK_FLOW_BOX_CHILD (widget);
+  GtkFlowBoxChildPrivate *priv = CHILD_PRIV (self);
+  GtkWidget *child = priv->child;
   gboolean had_focus = FALSE;
-  GtkWidget *child;
-
-  child = gtk_bin_get_child (GTK_BIN (widget));
 
   /* Without "can-focus" flag try to pass the focus to the child immediately */
   if (!gtk_widget_get_can_focus (widget))
@@ -384,6 +418,77 @@ gtk_flow_box_child_get_request_mode (GtkWidget *widget)
     return GTK_SIZE_REQUEST_HEIGHT_FOR_WIDTH;
 }
 
+static void
+gtk_flow_box_child_dispose (GObject *object)
+{
+  GtkFlowBoxChild *self = GTK_FLOW_BOX_CHILD (object);
+  GtkFlowBoxChildPrivate *priv = CHILD_PRIV (self);
+
+  g_clear_pointer (&priv->child, gtk_widget_unparent);
+
+  G_OBJECT_CLASS (gtk_flow_box_child_parent_class)->dispose (object);
+}
+
+static void
+gtk_flow_box_child_get_property (GObject    *object,
+                                 guint       prop_id,
+                                 GValue     *value,
+                                 GParamSpec *pspec)
+{
+  GtkFlowBoxChild *self = GTK_FLOW_BOX_CHILD (object);
+
+  switch (prop_id)
+    {
+    case PROP_CHILD:
+      g_value_set_object (value, gtk_flow_box_child_get_child (self));
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+    }
+}
+
+static void
+gtk_flow_box_child_set_property (GObject      *object,
+                                 guint         prop_id,
+                                 const GValue *value,
+                                 GParamSpec   *pspec)
+{
+  GtkFlowBoxChild *self = GTK_FLOW_BOX_CHILD (object);
+
+  switch (prop_id)
+    {
+    case PROP_CHILD:
+      gtk_flow_box_child_set_child (self, g_value_get_object (value));
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+    }
+}
+
+static void
+gtk_flow_box_child_compute_expand (GtkWidget *widget,
+                                   gboolean  *hexpand,
+                                   gboolean  *vexpand)
+{
+  GtkFlowBoxChild *self = GTK_FLOW_BOX_CHILD (widget);
+  GtkFlowBoxChildPrivate *priv = CHILD_PRIV (self);
+
+  if (priv->child)
+    {
+      *hexpand = gtk_widget_compute_expand (priv->child, GTK_ORIENTATION_HORIZONTAL);
+      *vexpand = gtk_widget_compute_expand (priv->child, GTK_ORIENTATION_VERTICAL);
+    }
+  else
+    {
+      *hexpand = FALSE;
+      *vexpand = FALSE;
+    }
+}
+
 /* GObject implementation {{{2 */
 
 static void
@@ -392,11 +497,24 @@ gtk_flow_box_child_class_init (GtkFlowBoxChildClass *class)
   GObjectClass *object_class = G_OBJECT_CLASS (class);
   GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
 
+  object_class->dispose = gtk_flow_box_child_dispose;
+  object_class->get_property = gtk_flow_box_child_get_property;
+  object_class->set_property = gtk_flow_box_child_set_property;
+
   widget_class->get_request_mode = gtk_flow_box_child_get_request_mode;
+  widget_class->compute_expand = gtk_flow_box_child_compute_expand;
   widget_class->focus = gtk_flow_box_child_focus;
 
   class->activate = gtk_flow_box_child_activate;
 
+  g_object_class_install_property (object_class,
+                                   PROP_CHILD,
+                                   g_param_spec_object ("child",
+                                                        P_("Child"),
+                                                        P_("The child widget"),
+                                                        GTK_TYPE_WIDGET,
+                                                        GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY));
+
   /**
    * GtkFlowBoxChild::activate:
    * @child: The child on which the signal is emitted
@@ -419,6 +537,7 @@ gtk_flow_box_child_class_init (GtkFlowBoxChildClass *class)
                   G_TYPE_NONE, 0);
   widget_class->activate_signal = child_signals[CHILD_ACTIVATE];
 
+  gtk_widget_class_set_layout_manager_type (widget_class, GTK_TYPE_BIN_LAYOUT);
   gtk_widget_class_set_accessible_role (widget_class, ATK_ROLE_LIST_ITEM);
   gtk_widget_class_set_css_name (widget_class, I_("flowboxchild"));
 }
@@ -427,7 +546,7 @@ static void
 gtk_flow_box_child_init (GtkFlowBoxChild *child)
 {
 }
-
+ 
 /* Public API {{{2 */
 
 /**
@@ -444,6 +563,43 @@ gtk_flow_box_child_new (void)
   return g_object_new (GTK_TYPE_FLOW_BOX_CHILD, NULL);
 }
 
+/**
+ * gtk_flow_box_child_set_child:
+ * @self: a #GtkFlowBoxChild
+ * @child: (allow-none): the child widget
+ *
+ * Sets the child widget of @self.
+ */
+void
+gtk_flow_box_child_set_child (GtkFlowBoxChild *self,
+                              GtkWidget       *child)
+{
+  GtkFlowBoxChildPrivate *priv = CHILD_PRIV (self);
+
+  g_clear_pointer (&priv->child, gtk_widget_unparent);
+
+  priv->child = child;
+  if (child)
+    gtk_widget_set_parent (child, GTK_WIDGET (self));
+  g_object_notify (G_OBJECT (self), "child");
+}
+
+/**
+ * gtk_flow_box_child_get_child:
+ * @self: a #GtkFlowBoxChild
+ *
+ * Gets the child widget of @self.
+ *
+ * Returns: (nullable) (transfer none): the child widget of @self
+ */
+GtkWidget *
+gtk_flow_box_child_get_child (GtkFlowBoxChild *self)
+{
+  GtkFlowBoxChildPrivate *priv = CHILD_PRIV (self);
+
+  return priv->child;
+}
+
 /**
  * gtk_flow_box_child_get_index:
  * @child: a #GtkFlowBoxChild
@@ -3853,8 +4009,7 @@ gtk_flow_box_insert (GtkFlowBox *box,
   else
     {
       child = GTK_FLOW_BOX_CHILD (gtk_flow_box_child_new ());
-      gtk_widget_show (GTK_WIDGET (child));
-      gtk_container_add (GTK_CONTAINER (child), widget);
+      gtk_flow_box_child_set_child (child, widget);
     }
 
   if (priv->sort_func != NULL)
diff --git a/gtk/gtkflowbox.h b/gtk/gtkflowbox.h
index ad1172d0e1..7e6e9becb4 100644
--- a/gtk/gtkflowbox.h
+++ b/gtk/gtkflowbox.h
@@ -51,12 +51,12 @@ typedef struct _GtkFlowBoxChildClass  GtkFlowBoxChildClass;
 
 struct _GtkFlowBoxChild
 {
-  GtkBin parent_instance;
+  GtkWidget parent_instance;
 };
 
 struct _GtkFlowBoxChildClass
 {
-  GtkBinClass parent_class;
+  GtkWidgetClass parent_class;
 
   void (* activate) (GtkFlowBoxChild *child);
 
@@ -80,6 +80,13 @@ GDK_AVAILABLE_IN_ALL
 GType                 gtk_flow_box_child_get_type            (void) G_GNUC_CONST;
 GDK_AVAILABLE_IN_ALL
 GtkWidget*            gtk_flow_box_child_new                 (void);
+
+GDK_AVAILABLE_IN_ALL
+void                  gtk_flow_box_child_set_child          (GtkFlowBoxChild *self,
+                                                             GtkWidget       *child);
+GDK_AVAILABLE_IN_ALL
+GtkWidget *           gtk_flow_box_child_get_child          (GtkFlowBoxChild *self);
+
 GDK_AVAILABLE_IN_ALL
 gint                  gtk_flow_box_child_get_index           (GtkFlowBoxChild *child);
 GDK_AVAILABLE_IN_ALL


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