[gtk/bin-removal: 4/50] aspectframe: Derive from GtkWidget



commit 628a6b7f5952315851df85533eb55d7ce1554868
Author: Matthias Clasen <mclasen redhat com>
Date:   Fri May 1 15:18:11 2020 -0400

    aspectframe: 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.
    
    We have to implement GtkBuildable, in order to keep
    the <child> element in ui files working for aspect
    frames.
    
    See #2681

 gtk/gtkaspectframe.c | 131 ++++++++++++++++++++++++++++++++++++++++++++-------
 1 file changed, 114 insertions(+), 17 deletions(-)
---
diff --git a/gtk/gtkaspectframe.c b/gtk/gtkaspectframe.c
index 7d0cca3195..5e96ecc433 100644
--- a/gtk/gtkaspectframe.c
+++ b/gtk/gtkaspectframe.c
@@ -48,10 +48,10 @@
 #include "config.h"
 
 #include "gtkaspectframe.h"
-#include "gtkbin.h"
 
 #include "gtksizerequest.h"
 
+#include "gtkwidgetprivate.h"
 #include "gtkprivate.h"
 #include "gtkintl.h"
 
@@ -60,8 +60,9 @@ typedef struct _GtkAspectFrameClass GtkAspectFrameClass;
 
 struct _GtkAspectFrame
 {
-  GtkBin parent_instance;
+  GtkWidget parent_instance;
 
+  GtkWidget    *child;
   gboolean      obey_child;
   float         xalign;
   float         yalign;
@@ -70,7 +71,7 @@ struct _GtkAspectFrame
 
 struct _GtkAspectFrameClass
 {
-  GtkBinClass parent_class;
+  GtkWidgetClass parent_class;
 };
 
 enum {
@@ -82,6 +83,7 @@ enum {
   PROP_CHILD
 };
 
+static void gtk_aspect_frame_dispose      (GObject         *object);
 static void gtk_aspect_frame_set_property (GObject         *object,
                                            guint            prop_id,
                                            const GValue    *value,
@@ -94,11 +96,25 @@ static void gtk_aspect_frame_size_allocate (GtkWidget      *widget,
                                             int             width,
                                             int             height,
                                             int             baseline);
+static void gtk_aspect_frame_measure       (GtkWidget      *widget,
+                                            GtkOrientation  orientation,
+                                            int             for_size,
+                                            int             *minimum,
+                                            int             *natural,
+                                            int             *minimum_baseline,
+                                            int             *natural_baseline);
+
+static void gtk_aspect_frame_compute_expand (GtkWidget     *widget,
+                                             gboolean      *hexpand,
+                                             gboolean      *vexpand);
+static GtkSizeRequestMode
+            gtk_aspect_frame_get_request_mode (GtkWidget *widget);
+
 
 #define MAX_RATIO 10000.0
 #define MIN_RATIO 0.0001
 
-G_DEFINE_TYPE (GtkAspectFrame, gtk_aspect_frame, GTK_TYPE_BIN)
+G_DEFINE_TYPE (GtkAspectFrame, gtk_aspect_frame, GTK_TYPE_WIDGET)
 
 static void
 gtk_aspect_frame_class_init (GtkAspectFrameClass *class)
@@ -106,10 +122,16 @@ gtk_aspect_frame_class_init (GtkAspectFrameClass *class)
   GObjectClass *gobject_class = G_OBJECT_CLASS (class);
   GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
 
+  gobject_class->dispose = gtk_aspect_frame_dispose;
   gobject_class->set_property = gtk_aspect_frame_set_property;
   gobject_class->get_property = gtk_aspect_frame_get_property;
 
+  widget_class->measure = gtk_aspect_frame_measure;
   widget_class->size_allocate = gtk_aspect_frame_size_allocate;
+  widget_class->compute_expand = gtk_aspect_frame_compute_expand;
+  widget_class->get_request_mode = gtk_aspect_frame_get_request_mode;
+  widget_class->grab_focus = gtk_widget_grab_focus_none;
+  widget_class->focus = gtk_widget_focus_child;
 
   g_object_class_install_property (gobject_class,
                                    PROP_XALIGN,
@@ -160,6 +182,16 @@ gtk_aspect_frame_init (GtkAspectFrame *self)
   self->obey_child = TRUE;
 }
 
+static void
+gtk_aspect_frame_dispose (GObject *object)
+{
+  GtkAspectFrame *self = GTK_ASPECT_FRAME (object);
+
+  g_clear_pointer (&self->child, gtk_widget_unparent);
+
+  G_OBJECT_CLASS (gtk_aspect_frame_parent_class)->dispose (object);
+}
+
 static void
 gtk_aspect_frame_set_property (GObject         *object,
                                guint            prop_id,
@@ -438,12 +470,9 @@ static void
 compute_child_allocation (GtkAspectFrame *self,
                           GtkAllocation  *child_allocation)
 {
-  GtkBin *bin = GTK_BIN (self);
-  GtkWidget *child;
-  gdouble ratio;
+  double ratio;
 
-  child = gtk_bin_get_child (bin);
-  if (child && gtk_widget_get_visible (child))
+  if (self->child && gtk_widget_get_visible (self->child))
     {
       GtkAllocation full_allocation;
 
@@ -451,10 +480,10 @@ compute_child_allocation (GtkAspectFrame *self,
         {
           GtkRequisition child_requisition;
 
-          gtk_widget_get_preferred_size (child, &child_requisition, NULL);
+          gtk_widget_get_preferred_size (self->child, &child_requisition, NULL);
           if (child_requisition.height != 0)
             {
-              ratio = ((gdouble) child_requisition.width /
+              ratio = ((double) child_requisition.width /
                        child_requisition.height);
               if (ratio < MIN_RATIO)
                 ratio = MIN_RATIO;
@@ -487,6 +516,36 @@ compute_child_allocation (GtkAspectFrame *self,
     get_full_allocation (self, child_allocation);
 }
 
+static void
+gtk_aspect_frame_measure (GtkWidget      *widget,
+                          GtkOrientation  orientation,
+                          int             for_size,
+                          int             *minimum,
+                          int             *natural,
+                          int             *minimum_baseline,
+                          int             *natural_baseline)
+{
+  GtkAspectFrame *self = GTK_ASPECT_FRAME (widget);
+
+  if (self->child && gtk_widget_get_visible (self->child))
+    {
+      int child_min, child_nat;
+
+      gtk_widget_measure (self->child,
+                          orientation, for_size,
+                          &child_min, &child_nat,
+                          NULL, NULL);
+
+      *minimum = child_min;
+      *natural = child_nat;
+    }
+  else
+    {
+      *minimum = 0;
+      *natural = 0;
+    }
+}
+
 static void
 gtk_aspect_frame_size_allocate (GtkWidget *widget,
                                 int        width,
@@ -494,14 +553,42 @@ gtk_aspect_frame_size_allocate (GtkWidget *widget,
                                 int        baseline)
 {
   GtkAspectFrame *self = GTK_ASPECT_FRAME (widget);
-  GtkWidget *child;
   GtkAllocation new_allocation;
 
   compute_child_allocation (self, &new_allocation);
 
-  child = gtk_bin_get_child (GTK_BIN (widget));
-  if (child && gtk_widget_get_visible (child))
-    gtk_widget_size_allocate (child, &new_allocation, -1);
+  if (self->child && gtk_widget_get_visible (self->child))
+    gtk_widget_size_allocate (self->child, &new_allocation, -1);
+}
+
+static void
+gtk_aspect_frame_compute_expand (GtkWidget *widget,
+                                 gboolean  *hexpand,
+                                 gboolean  *vexpand)
+{
+  GtkAspectFrame *self = GTK_ASPECT_FRAME (widget);
+
+  if (self->child)
+    {
+      *hexpand = gtk_widget_compute_expand (self->child, GTK_ORIENTATION_HORIZONTAL);
+      *vexpand = gtk_widget_compute_expand (self->child, GTK_ORIENTATION_VERTICAL);
+    }
+  else
+    {
+      *hexpand = FALSE;
+      *vexpand = FALSE;
+    }
+}
+
+static GtkSizeRequestMode
+gtk_aspect_frame_get_request_mode (GtkWidget *widget)
+{
+  GtkAspectFrame *self = GTK_ASPECT_FRAME (widget);
+
+  if (self->child)
+    return gtk_widget_get_request_mode (self->child);
+  else
+    return GTK_SIZE_REQUEST_CONSTANT_SIZE;
 }
 
 /**
@@ -518,7 +605,17 @@ gtk_aspect_frame_set_child (GtkAspectFrame  *self,
   g_return_if_fail (GTK_IS_ASPECT_FRAME (self));
   g_return_if_fail (child == NULL || GTK_IS_WIDGET (child));
 
-  _gtk_bin_set_child (GTK_BIN (self), child);
+  if (self->child == child)
+    return;
+
+  g_clear_pointer (&self->child, gtk_widget_unparent);
+
+  if (child)
+    {
+      self->child = child;
+      gtk_widget_set_parent (child, GTK_WIDGET (self));
+    }
+
   g_object_notify (G_OBJECT (self), "child");
 }
 
@@ -535,6 +632,6 @@ gtk_aspect_frame_get_child (GtkAspectFrame *self)
 {
   g_return_val_if_fail (GTK_IS_ASPECT_FRAME (self), NULL);
 
-  return gtk_bin_get_child (GTK_BIN (self));
+  return self->child;
 }
 


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