[gtk+] spinner: Use a gadget



commit 9e278293ca98b25649b93abe1bed385bc607eb2d
Author: Matthias Clasen <mclasen redhat com>
Date:   Thu Nov 26 14:59:57 2015 -0500

    spinner: Use a gadget
    
    This gives us min-width/height support. Currently, the spinner
    still has a hardcoded minimum size of 16 and doesn't grow beyond
    32. We may want to revisit that at some point.

 gtk/gtkspinner.c |  267 ++++++++++++++++++++++++++++++++----------------------
 1 files changed, 159 insertions(+), 108 deletions(-)
---
diff --git a/gtk/gtkspinner.c b/gtk/gtkspinner.c
index 6916f72..ed2c14d 100644
--- a/gtk/gtkspinner.c
+++ b/gtk/gtkspinner.c
@@ -38,6 +38,7 @@
 #include "gtkstylecontextprivate.h"
 #include "gtkwidgetprivate.h"
 #include "a11y/gtkspinneraccessible.h"
+#include "gtkcsscustomgadgetprivate.h"
 
 
 /**
@@ -59,8 +60,6 @@
  */
 
 
-#define SPINNER_SIZE 16
-
 enum {
   PROP_0,
   PROP_ACTIVE
@@ -68,149 +67,98 @@ enum {
 
 struct _GtkSpinnerPrivate
 {
+  GtkCssGadget *gadget;
   gboolean active;
 };
 
-static gboolean gtk_spinner_draw       (GtkWidget       *widget,
-                                        cairo_t         *cr);
-static void gtk_spinner_size_allocate  (GtkWidget       *widget,
-                                        GtkAllocation   *allocation);
-static void gtk_spinner_get_property   (GObject         *object,
-                                        guint            param_id,
-                                        GValue          *value,
-                                        GParamSpec      *pspec);
-static void gtk_spinner_set_property   (GObject         *object,
-                                        guint            param_id,
-                                        const GValue    *value,
-                                        GParamSpec      *pspec);
-static void gtk_spinner_set_active     (GtkSpinner      *spinner,
-                                        gboolean         active);
-static void gtk_spinner_get_preferred_width (GtkWidget  *widget,
-                                        gint            *minimum_size,
-                                        gint            *natural_size);
-static void gtk_spinner_get_preferred_height (GtkWidget *widget,
-                                        gint            *minimum_size,
-                                        gint            *natural_size);
-
-
 G_DEFINE_TYPE_WITH_PRIVATE (GtkSpinner, gtk_spinner, GTK_TYPE_WIDGET)
 
 static void
-gtk_spinner_class_init (GtkSpinnerClass *klass)
+gtk_spinner_finalize (GObject *object)
 {
-  GObjectClass *gobject_class;
-  GtkWidgetClass *widget_class;
-
-  gobject_class = G_OBJECT_CLASS(klass);
-  gobject_class->get_property = gtk_spinner_get_property;
-  gobject_class->set_property = gtk_spinner_set_property;
-
-  widget_class = GTK_WIDGET_CLASS(klass);
-  widget_class->size_allocate = gtk_spinner_size_allocate;
-  widget_class->draw = gtk_spinner_draw;
-  widget_class->get_preferred_width = gtk_spinner_get_preferred_width;
-  widget_class->get_preferred_height = gtk_spinner_get_preferred_height;
-
-  /* GtkSpinner:active:
-   *
-   * Whether the spinner is active
-   *
-   * Since: 2.20
-   */
-  g_object_class_install_property (gobject_class,
-                                   PROP_ACTIVE,
-                                   g_param_spec_boolean ("active",
-                                                         P_("Active"),
-                                                         P_("Whether the spinner is active"),
-                                                         FALSE,
-                                                         GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY));
-
-  gtk_widget_class_set_accessible_type (widget_class, GTK_TYPE_SPINNER_ACCESSIBLE);
-  gtk_widget_class_set_css_name (widget_class, "spinner");
-}
-
-static void
-gtk_spinner_get_property (GObject    *object,
-                          guint       param_id,
-                          GValue     *value,
-                          GParamSpec *pspec)
-{
-  GtkSpinnerPrivate *priv;
-
-  priv = GTK_SPINNER (object)->priv;
+  GtkSpinner *spinner = GTK_SPINNER (object);
 
-  switch (param_id)
-    {
-      case PROP_ACTIVE:
-        g_value_set_boolean (value, priv->active);
-        break;
-      default:
-        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
-    }
-}
+  g_clear_object (&spinner->priv->gadget);
 
-static void
-gtk_spinner_set_property (GObject      *object,
-                          guint         param_id,
-                          const GValue *value,
-                          GParamSpec   *pspec)
-{
-  switch (param_id)
-    {
-      case PROP_ACTIVE:
-        gtk_spinner_set_active (GTK_SPINNER (object), g_value_get_boolean (value));
-        break;
-      default:
-        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
-    }
+  G_OBJECT_CLASS (gtk_spinner_parent_class)->finalize (object);
 }
 
 static void
-gtk_spinner_init (GtkSpinner *spinner)
+gtk_spinner_measure (GtkCssGadget   *gadget,
+                     GtkOrientation  orientation,
+                     gint            for_size,
+                     gint           *minimum,
+                     gint           *natural,
+                     gint           *minimum_baseline,
+                     gint           *natural_baseline,
+                     gpointer        data)
 {
-  spinner->priv = gtk_spinner_get_instance_private (spinner);
-
-  gtk_widget_set_has_window (GTK_WIDGET (spinner), FALSE);
+  *minimum = *natural = 16;
 }
 
 static void
 gtk_spinner_get_preferred_width (GtkWidget *widget,
-                                 gint      *minimum_size,
-                                 gint      *natural_size)
+                                 gint      *minimum,
+                                 gint      *natural)
 {
-  *minimum_size = SPINNER_SIZE;
-  *natural_size = SPINNER_SIZE;
+  gtk_css_gadget_get_preferred_size (GTK_SPINNER (widget)->priv->gadget,
+                                     GTK_ORIENTATION_HORIZONTAL,
+                                     -1,
+                                     minimum, natural,
+                                     NULL, NULL);
 }
 
 static void
 gtk_spinner_get_preferred_height (GtkWidget *widget,
-                                  gint      *minimum_size,
-                                  gint      *natural_size)
+                                  gint      *minimum,
+                                  gint      *natural)
 {
-  *minimum_size = SPINNER_SIZE;
-  *natural_size = SPINNER_SIZE;
+  gtk_css_gadget_get_preferred_size (GTK_SPINNER (widget)->priv->gadget,
+                                     GTK_ORIENTATION_VERTICAL,
+                                     -1,
+                                     minimum, natural,
+                                     NULL, NULL);
 }
 
 static void
-gtk_spinner_size_allocate (GtkWidget     *widget,
-                           GtkAllocation *allocation)
+gtk_spinner_allocate (GtkCssGadget        *gadget,
+                      const GtkAllocation *allocation,
+                      gint                 baseline,
+                      GtkAllocation       *out_clip,
+                      gpointer             data)
 {
+  GtkWidget *widget;
   GtkStyleContext *context;
-  GtkAllocation clip;
   gint size;
 
+  widget = gtk_css_gadget_get_owner (gadget);
   context = gtk_widget_get_style_context (widget);
   size = MIN (allocation->width, allocation->height);
 
+  gtk_widget_set_allocation (widget, allocation);
+
   _gtk_style_context_get_icon_extents (context,
-                                       &clip,
+                                       out_clip,
                                        allocation->x + (allocation->width - size) / 2,
                                        allocation->y + (allocation->height - size) / 2,
                                        size, size);
 
-  gdk_rectangle_union (&clip, allocation, &clip);
+  gdk_rectangle_union (out_clip, allocation, out_clip);
+}
+
+static void
+gtk_spinner_size_allocate (GtkWidget     *widget,
+                           GtkAllocation *allocation)
+{
+  GtkAllocation clip;
 
   gtk_widget_set_allocation (widget, allocation);
+
+  gtk_css_gadget_allocate (GTK_SPINNER (widget)->priv->gadget,
+                           allocation,
+                           gtk_widget_get_allocated_baseline (widget),
+                           &clip);
+
   gtk_widget_set_clip (widget, &clip);
 }
 
@@ -218,14 +166,27 @@ static gboolean
 gtk_spinner_draw (GtkWidget *widget,
                   cairo_t   *cr)
 {
+  gtk_css_gadget_draw (GTK_SPINNER (widget)->priv->gadget, cr);
+
+  return FALSE;
+}
+
+static gboolean
+gtk_spinner_render (GtkCssGadget *gadget,
+                    cairo_t      *cr,
+                    gint          x,
+                    gint          y,
+                    gint          width,
+                    gint          height,
+                    gpointer      data)
+{
+  GtkWidget *widget;
   GtkStyleContext *context;
-  gint width, height;
   gint size;
 
+  widget = gtk_css_gadget_get_owner (gadget);
   context = gtk_widget_get_style_context (widget);
 
-  width = gtk_widget_get_allocated_width (widget);
-  height = gtk_widget_get_allocated_height (widget);
   size = MIN (width, height);
 
   gtk_render_activity (context, cr,
@@ -259,6 +220,96 @@ gtk_spinner_set_active (GtkSpinner *spinner,
     }
 }
 
+static void
+gtk_spinner_get_property (GObject    *object,
+                          guint       param_id,
+                          GValue     *value,
+                          GParamSpec *pspec)
+{
+  GtkSpinnerPrivate *priv;
+
+  priv = GTK_SPINNER (object)->priv;
+
+  switch (param_id)
+    {
+      case PROP_ACTIVE:
+        g_value_set_boolean (value, priv->active);
+        break;
+      default:
+        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
+    }
+}
+
+static void
+gtk_spinner_set_property (GObject      *object,
+                          guint         param_id,
+                          const GValue *value,
+                          GParamSpec   *pspec)
+{
+  switch (param_id)
+    {
+      case PROP_ACTIVE:
+        gtk_spinner_set_active (GTK_SPINNER (object), g_value_get_boolean (value));
+        break;
+      default:
+        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
+    }
+}
+
+static void
+gtk_spinner_class_init (GtkSpinnerClass *klass)
+{
+  GObjectClass *gobject_class;
+  GtkWidgetClass *widget_class;
+
+  gobject_class = G_OBJECT_CLASS(klass);
+  gobject_class->finalize = gtk_spinner_finalize;
+  gobject_class->get_property = gtk_spinner_get_property;
+  gobject_class->set_property = gtk_spinner_set_property;
+
+  widget_class = GTK_WIDGET_CLASS(klass);
+  widget_class->size_allocate = gtk_spinner_size_allocate;
+  widget_class->draw = gtk_spinner_draw;
+  widget_class->get_preferred_width = gtk_spinner_get_preferred_width;
+  widget_class->get_preferred_height = gtk_spinner_get_preferred_height;
+
+  /* GtkSpinner:active:
+   *
+   * Whether the spinner is active
+   *
+   * Since: 2.20
+   */
+  g_object_class_install_property (gobject_class,
+                                   PROP_ACTIVE,
+                                   g_param_spec_boolean ("active",
+                                                         P_("Active"),
+                                                         P_("Whether the spinner is active"),
+                                                         FALSE,
+                                                         GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY));
+
+  gtk_widget_class_set_accessible_type (widget_class, GTK_TYPE_SPINNER_ACCESSIBLE);
+  gtk_widget_class_set_css_name (widget_class, "spinner");
+}
+
+static void
+gtk_spinner_init (GtkSpinner *spinner)
+{
+  GtkCssNode *widget_node;
+
+  spinner->priv = gtk_spinner_get_instance_private (spinner);
+
+  gtk_widget_set_has_window (GTK_WIDGET (spinner), FALSE);
+
+  widget_node = gtk_widget_get_css_node (GTK_WIDGET (spinner));
+  spinner->priv->gadget = gtk_css_custom_gadget_new_for_node (widget_node,
+                                                              GTK_WIDGET (spinner),
+                                                              gtk_spinner_measure,
+                                                              gtk_spinner_allocate,
+                                                              gtk_spinner_render,
+                                                              NULL,
+                                                              NULL);
+}
+
 /**
  * gtk_spinner_new:
  *


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