[gtk/bin-removal: 17/40] revealer: Derive from GtkWidget



commit 41322e2a7a6a32ec1ae079597f70b443586db5f3
Author: Matthias Clasen <mclasen redhat com>
Date:   Sat May 2 18:56:57 2020 -0400

    revealer: Derive from GtkWidget
    
    We want to remove GtkBin and GtkContainer as they don't
    provide much useful functionality anymore. This requires
    us to move get_request_mode and compute_expand down.
    
    See #2681

 gtk/gtkrevealer.c | 180 ++++++++++++++++++++++++++++++++++++++----------------
 gtk/gtkrevealer.h |   2 +-
 2 files changed, 130 insertions(+), 52 deletions(-)
---
diff --git a/gtk/gtkrevealer.c b/gtk/gtkrevealer.c
index 94df6ad7bb..d325686a39 100644
--- a/gtk/gtkrevealer.c
+++ b/gtk/gtkrevealer.c
@@ -30,6 +30,7 @@
 #include "gtksettingsprivate.h"
 #include "gtktypebuiltins.h"
 #include "gtkwidgetprivate.h"
+#include "gtkbuildable.h"
 
 #include "fallback-c89.c"
 
@@ -88,14 +89,16 @@ enum  {
 typedef struct _GtkRevealerClass GtkRevealerClass;
 
 struct _GtkRevealer {
-  GtkBin parent_instance;
+  GtkWidget parent_instance;
 };
 
 struct _GtkRevealerClass {
-  GtkBinClass parent_class;
+  GtkWidgetClass parent_class;
 };
 
 typedef struct {
+  GtkWidget *child;
+
   GtkRevealerTransitionType transition_type;
   guint transition_duration;
 
@@ -109,12 +112,10 @@ typedef struct {
 
 static GParamSpec *props[LAST_PROP] = { NULL, };
 
-static void     gtk_revealer_real_add                            (GtkContainer  *widget,
-                                                                  GtkWidget     *child);
-static void     gtk_revealer_real_size_allocate                  (GtkWidget     *widget,
-                                                                  int            width,
-                                                                  int            height,
-                                                                  int            baseline);
+static void gtk_revealer_size_allocate (GtkWidget     *widget,
+                                        int            width,
+                                        int            height,
+                                        int            baseline);
 static void gtk_revealer_measure (GtkWidget      *widget,
                                   GtkOrientation  orientation,
                                   int             for_size,
@@ -126,7 +127,34 @@ static void gtk_revealer_measure (GtkWidget      *widget,
 static void     gtk_revealer_set_position (GtkRevealer *revealer,
                                            gdouble      pos);
 
-G_DEFINE_TYPE_WITH_PRIVATE (GtkRevealer, gtk_revealer, GTK_TYPE_BIN)
+static void gtk_revealer_buildable_iface_init (GtkBuildableIface *iface);
+
+G_DEFINE_TYPE_WITH_CODE (GtkRevealer, gtk_revealer, GTK_TYPE_WIDGET,
+                         G_ADD_PRIVATE (GtkRevealer)
+                         G_IMPLEMENT_INTERFACE (GTK_TYPE_BUILDABLE,
+                                                gtk_revealer_buildable_iface_init))
+
+static GtkBuildableIface *parent_buildable_iface;
+
+static void
+gtk_revealer_buildable_add_child (GtkBuildable *buildable,
+                                  GtkBuilder   *builder,
+                                  GObject      *child,
+                                  const gchar  *type)
+{
+  if (GTK_IS_WIDGET (child))
+    gtk_revealer_set_child (GTK_REVEALER (buildable), GTK_WIDGET (child));
+  else
+    parent_buildable_iface->add_child (buildable, builder, child, type);
+}
+
+static void
+gtk_revealer_buildable_iface_init (GtkBuildableIface *iface)
+{
+  parent_buildable_iface = g_type_interface_peek_parent (iface);
+
+  iface->add_child = gtk_revealer_buildable_add_child;
+}
 
 static void
 gtk_revealer_init (GtkRevealer *revealer)
@@ -141,6 +169,17 @@ gtk_revealer_init (GtkRevealer *revealer)
   gtk_widget_set_overflow (GTK_WIDGET (revealer), GTK_OVERFLOW_HIDDEN);
 }
 
+static void
+gtk_revealer_dispose (GObject *obj)
+{
+  GtkRevealer *revealer = GTK_REVEALER (obj);
+  GtkRevealerPrivate *priv = gtk_revealer_get_instance_private (revealer);
+
+  g_clear_pointer (&priv->child, gtk_widget_unparent);
+
+  G_OBJECT_CLASS (gtk_revealer_parent_class)->dispose (obj);
+}
+
 static void
 gtk_revealer_finalize (GObject *obj)
 {
@@ -232,22 +271,56 @@ gtk_revealer_unmap (GtkWidget *widget)
     }
 }
 
+static void
+gtk_revealer_compute_expand (GtkWidget *widget,
+                             gboolean  *hexpand,
+                             gboolean  *vexpand)
+{
+  GtkRevealer *revealer = GTK_REVEALER (widget);
+  GtkRevealerPrivate *priv = gtk_revealer_get_instance_private (revealer);
+
+  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;
+    }
+}
+
+static GtkSizeRequestMode
+gtk_revealer_get_request_mode (GtkWidget *widget)
+{
+  GtkRevealer *revealer = GTK_REVEALER (widget);
+  GtkRevealerPrivate *priv = gtk_revealer_get_instance_private (revealer);
+
+  if (priv->child)
+    return gtk_widget_get_request_mode (priv->child);
+  else
+    return GTK_SIZE_REQUEST_CONSTANT_SIZE;
+}
+
 static void
 gtk_revealer_class_init (GtkRevealerClass *klass)
 {
   GObjectClass *object_class = G_OBJECT_CLASS (klass);
   GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(klass);
-  GtkContainerClass *container_class = GTK_CONTAINER_CLASS (klass);
 
+  object_class->dispose = gtk_revealer_dispose;
+  object_class->finalize = gtk_revealer_finalize;
   object_class->get_property = gtk_revealer_get_property;
   object_class->set_property = gtk_revealer_set_property;
-  object_class->finalize = gtk_revealer_finalize;
 
   widget_class->unmap = gtk_revealer_unmap;
-  widget_class->size_allocate = gtk_revealer_real_size_allocate;
+  widget_class->size_allocate = gtk_revealer_size_allocate;
   widget_class->measure = gtk_revealer_measure;
-
-  container_class->add = gtk_revealer_real_add;
+  widget_class->compute_expand = gtk_revealer_compute_expand;
+  widget_class->get_request_mode = gtk_revealer_get_request_mode;
+  widget_class->grab_focus = gtk_widget_grab_focus_none;
+  widget_class->focus = gtk_widget_focus_child;
 
   props[PROP_TRANSITION_TYPE] =
     g_param_spec_enum ("transition-type",
@@ -324,19 +397,6 @@ effective_transition (GtkRevealer *revealer)
   return priv->transition_type;
 }
 
-static void
-gtk_revealer_real_add (GtkContainer *container,
-                       GtkWidget    *child)
-{
-  GtkRevealer *revealer = GTK_REVEALER (container);
-  GtkRevealerPrivate *priv = gtk_revealer_get_instance_private (revealer);
-
-  g_return_if_fail (child != NULL);
-  gtk_widget_set_child_visible (child, priv->current_pos != 0.0);
-
-  GTK_CONTAINER_CLASS (gtk_revealer_parent_class)->add (container, child);
-}
-
 static double
 get_child_size_scale (GtkRevealer    *revealer,
                       GtkOrientation  orientation)
@@ -381,25 +441,23 @@ get_child_size_scale (GtkRevealer    *revealer,
 }
 
 static void
-gtk_revealer_real_size_allocate (GtkWidget *widget,
-                                 int        width,
-                                 int        height,
-                                 int        baseline)
+gtk_revealer_size_allocate (GtkWidget *widget,
+                            int        width,
+                            int        height,
+                            int        baseline)
 {
   GtkRevealer *revealer = GTK_REVEALER (widget);
   GtkRevealerPrivate *priv = gtk_revealer_get_instance_private (revealer);
-  GtkWidget *child;
   GskTransform *transform;
   double hscale, vscale;
   int child_width, child_height;
 
-  child = gtk_bin_get_child (GTK_BIN (revealer));
-  if (child == NULL || !gtk_widget_get_visible (child))
+  if (priv->child == NULL || !gtk_widget_get_visible (priv->child))
     return;
 
   if (priv->current_pos >= 1.0)
     {
-      gtk_widget_allocate (child, width, height, baseline, NULL);
+      gtk_widget_allocate (priv->child, width, height, baseline, NULL);
       return;
     }
 
@@ -493,7 +551,7 @@ gtk_revealer_real_size_allocate (GtkWidget *widget,
       break;
     }
 
-  gtk_widget_allocate (child, child_width, child_height, -1, transform);
+  gtk_widget_allocate (priv->child, child_width, child_height, -1, transform);
 }
 
 static void
@@ -502,18 +560,16 @@ gtk_revealer_set_position (GtkRevealer *revealer,
 {
   GtkRevealerPrivate *priv = gtk_revealer_get_instance_private (revealer);
   gboolean new_visible;
-  GtkWidget *child;
   GtkRevealerTransitionType transition;
 
   priv->current_pos = pos;
 
   new_visible = priv->current_pos != 0.0;
 
-  child = gtk_bin_get_child (GTK_BIN (revealer));
-  if (child != NULL &&
-      new_visible != gtk_widget_get_child_visible (child))
+  if (priv->child != NULL &&
+      new_visible != gtk_widget_get_child_visible (priv->child))
     {
-      gtk_widget_set_child_visible (child, new_visible);
+      gtk_widget_set_child_visible (priv->child, new_visible);
       gtk_widget_queue_resize (GTK_WIDGET (revealer));
     }
 
@@ -673,6 +729,7 @@ gtk_revealer_measure (GtkWidget      *widget,
                       int            *natural_baseline)
 {
   GtkRevealer *self = GTK_REVEALER (widget);
+  GtkRevealerPrivate *priv = gtk_revealer_get_instance_private (self);
   double scale;
 
   scale = get_child_size_scale (self, OPPOSITE_ORIENTATION (orientation));
@@ -685,11 +742,19 @@ gtk_revealer_measure (GtkWidget      *widget,
         for_size = MIN (G_MAXINT, ceil (for_size / scale));
     }
 
-  GTK_WIDGET_CLASS (gtk_revealer_parent_class)->measure (widget,
-                                                         orientation,
-                                                         for_size,
-                                                         minimum, natural,
-                                                         NULL, NULL);
+  if (priv->child != NULL && _gtk_widget_get_visible (priv->child))
+    {
+      gtk_widget_measure (priv->child,
+                          orientation,
+                          for_size,
+                          minimum, natural,
+                          NULL, NULL);
+    }
+  else
+    {
+      *minimum = 0;
+      *natural = 0;
+    }
 
   scale = get_child_size_scale (self, orientation);
   *minimum = ceil (*minimum * scale);
@@ -792,10 +857,19 @@ void
 gtk_revealer_set_child (GtkRevealer *revealer,
                         GtkWidget   *child)
 {
-  if (!child)
-    gtk_container_remove (GTK_CONTAINER (revealer), gtk_bin_get_child (GTK_BIN (revealer)));
-  else
-    gtk_container_add (GTK_CONTAINER (revealer), child);
+  GtkRevealerPrivate *priv = gtk_revealer_get_instance_private (revealer);
+
+  g_return_if_fail (GTK_IS_REVEALER (revealer));
+  g_return_if_fail (child == NULL || GTK_IS_WIDGET (child));
+
+  g_clear_pointer (&priv->child, gtk_widget_unparent);
+
+  if (child)
+    {
+      gtk_widget_set_parent (child, GTK_WIDGET (revealer));
+      gtk_widget_set_child_visible (child, priv->current_pos != 0.0);
+      priv->child = child;
+   }
 
   g_object_notify_by_pspec (G_OBJECT (revealer), props[PROP_CHILD]);
 }
@@ -811,5 +885,9 @@ gtk_revealer_set_child (GtkRevealer *revealer,
 GtkWidget *
 gtk_revealer_get_child (GtkRevealer *revealer)
 {
-  return gtk_bin_get_child (GTK_BIN (revealer));
+  GtkRevealerPrivate *priv = gtk_revealer_get_instance_private (revealer);
+
+  g_return_val_if_fail (GTK_IS_REVEALER (revealer), NULL);
+
+  return priv->child;
 }
diff --git a/gtk/gtkrevealer.h b/gtk/gtkrevealer.h
index ca45221687..be2cc652b0 100644
--- a/gtk/gtkrevealer.h
+++ b/gtk/gtkrevealer.h
@@ -22,7 +22,7 @@
 #ifndef __GTK_REVEALER_H__
 #define __GTK_REVEALER_H__
 
-#include <gtk/gtkbin.h>
+#include <gtk/gtkwidget.h>
 
 G_BEGIN_DECLS
 


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