[gtk+/wip/matthiasc/gadget: 5/16] button: Convert to gadgets



commit 6478a6811546f0738e6c922966387eb62197269f
Author: Matthias Clasen <mclasen redhat com>
Date:   Thu Dec 3 21:56:25 2015 -0500

    button: Convert to gadgets
    
    This causes button size to go a bit bonkers.
    The theme will need fixes.

 gtk/gtkbutton.c        |  334 ++++++++++++++++++------------------------------
 gtk/gtkbuttonprivate.h |    2 +
 2 files changed, 127 insertions(+), 209 deletions(-)
---
diff --git a/gtk/gtkbutton.c b/gtk/gtkbutton.c
index 315a11b..dd8f15e 100644
--- a/gtk/gtkbutton.c
+++ b/gtk/gtkbutton.c
@@ -72,9 +72,8 @@
 #include "a11y/gtkbuttonaccessible.h"
 #include "gtkapplicationprivate.h"
 #include "gtkactionhelper.h"
-
-static const GtkBorder default_default_border = { 0, 0, 0, 0 };
-static const GtkBorder default_default_outside_border = { 0, 0, 0, 0 };
+#include "gtkcsscustomgadgetprivate.h"
+#include "gtkcontainerprivate.h"
 
 /* Time out before giving up on getting a key release when animating
  * the close button.
@@ -195,7 +194,28 @@ static void gtk_button_get_preferred_height_and_baseline_for_width (GtkWidget *w
                                                                    gint      *natural_size,
                                                                    gint      *minimum_baseline,
                                                                    gint      *natural_baseline);
-  
+
+static void     gtk_button_get_size      (GtkCssGadget        *gadget,
+                                          GtkOrientation       orientation,
+                                          gint                 for_size,
+                                          gint                *minimum_size,
+                                          gint                *natural_size,
+                                          gint                *minimum_baseline,
+                                          gint                *natural_baseline,
+                                          gpointer             data);
+static void     gtk_button_allocate      (GtkCssGadget        *gadget,
+                                          const GtkAllocation *allocation,
+                                          int                  baseline,
+                                          GtkAllocation       *out_clip,
+                                          gpointer             data);
+static gboolean gtk_button_draw_contents (GtkCssGadget        *gadget,
+                                          cairo_t             *cr,
+                                          int                  x,
+                                          int                  y,
+                                          int                  width,
+                                          int                  height,
+                                          gpointer             data);
+
 static GParamSpec *props[LAST_PROP] = { NULL, };
 static guint button_signals[LAST_SIGNAL] = { 0 };
 
@@ -493,7 +513,8 @@ gtk_button_class_init (GtkButtonClass *klass)
    * around a button that can become the default widget of its window.
    * For more information about default widgets, see gtk_widget_grab_default().
    *
-   * Deprecated: 3.14: use CSS margins and padding instead.
+   * Deprecated: 3.14: Use CSS margins and padding instead;
+   *     the value of this style property is ignored.
    */
 
   gtk_widget_class_install_style_property (widget_class,
@@ -511,7 +532,8 @@ gtk_button_class_init (GtkButtonClass *klass)
    * window. Extra outside space is always drawn outside the button border.
    * For more information about default widgets, see gtk_widget_grab_default().
    *
-   * Deprecated: 3.14: use CSS margins and padding instead.
+   * Deprecated: 3.14: Use CSS margins and padding instead;
+   *     the value of this style property is ignored.
    */
   gtk_widget_class_install_style_property (widget_class,
                                           g_param_spec_boxed ("default-outside-border",
@@ -720,6 +742,15 @@ gtk_button_init (GtkButton *button)
   g_signal_connect (priv->gesture, "update", G_CALLBACK (multipress_gesture_update_cb), button);
   g_signal_connect (priv->gesture, "cancel", G_CALLBACK (multipress_gesture_cancel_cb), button);
   gtk_event_controller_set_propagation_phase (GTK_EVENT_CONTROLLER (priv->gesture), GTK_PHASE_BUBBLE);
+
+  priv->gadget = gtk_css_custom_gadget_new_for_node (gtk_widget_get_css_node (GTK_WIDGET (button)),
+                                                     GTK_WIDGET (button),
+                                                     gtk_button_get_size,
+                                                     gtk_button_allocate,
+                                                     gtk_button_draw_contents,
+                                                     NULL,
+                                                     NULL);
+
 }
 
 static void
@@ -729,8 +760,8 @@ gtk_button_destroy (GtkWidget *widget)
   GtkButtonPrivate *priv = button->priv;
 
   g_clear_pointer (&priv->label_text, g_free);
-
   g_clear_object (&priv->gesture);
+  g_clear_object (&priv->gadget);
 
   GTK_WIDGET_CLASS (gtk_button_parent_class)->destroy (widget);
 }
@@ -787,7 +818,7 @@ gtk_button_add (GtkContainer *container,
   GTK_CONTAINER_CLASS (gtk_button_parent_class)->add (container, widget);
 }
 
-static void 
+static void
 gtk_button_dispose (GObject *object)
 {
   GtkButton *button = GTK_BUTTON (object);
@@ -1721,89 +1752,12 @@ gtk_button_style_updated (GtkWidget *widget)
 }
 
 static void
-gtk_button_get_props (GtkButton *button,
-                     GtkBorder *default_border,
-                     GtkBorder *default_outside_border,
-                      GtkBorder *padding,
-                      GtkBorder *border)
-{
-  GtkStyleContext *context;
-  GtkStateFlags state;
-  GtkBorder *tmp_border;
-
-  context = gtk_widget_get_style_context (GTK_WIDGET (button));
-  state = gtk_style_context_get_state (context);
-
-  if (default_border)
-    {
-      gtk_style_context_get_style (context,
-                                   "default-border", &tmp_border,
-                                   NULL);
-
-      if (tmp_border)
-       {
-         *default_border = *tmp_border;
-         gtk_border_free (tmp_border);
-       }
-      else
-       *default_border = default_default_border;
-    }
-
-  if (default_outside_border)
-    {
-      gtk_style_context_get_style (context,
-                                   "default-outside-border", &tmp_border,
-                                   NULL);
-
-      if (tmp_border)
-       {
-         *default_outside_border = *tmp_border;
-         gtk_border_free (tmp_border);
-       }
-      else
-       *default_outside_border = default_default_outside_border;
-    }
-
-  if (padding)
-    gtk_style_context_get_padding (context, state, padding);
-
-  if (border)
-    gtk_style_context_get_border (context, state, border);
-}
-
-/* Computes the size of the border around the button's child
- * including all CSS and style properties so it can be used
- * during size allocation and size request phases. */
-static void
-gtk_button_get_full_border (GtkButton *button,
-                            GtkBorder *full_border)
-{
-  GtkBorder default_border, padding, border;
-
-  gtk_button_get_props (button, &default_border, NULL,
-                        &padding, &border);
-
-  full_border->left = padding.left + border.left;
-  full_border->right = padding.right + border.right;
-  full_border->top = padding.top + border.top;
-  full_border->bottom = padding.bottom + border.bottom;
-
-  if (gtk_widget_get_can_default (GTK_WIDGET (button)))
-    {
-      full_border->left += default_border.left;
-      full_border->right += default_border.right;
-      full_border->top += default_border.top;
-      full_border->bottom += default_border.bottom;
-    }
-}
-
-static void
 gtk_button_size_allocate (GtkWidget     *widget,
                          GtkAllocation *allocation)
 {
   GtkButton *button = GTK_BUTTON (widget);
   GtkButtonPrivate *priv = button->priv;
-  GtkWidget *child;
+  GtkAllocation clip;
 
   gtk_widget_set_allocation (widget, allocation);
 
@@ -1814,91 +1768,58 @@ gtk_button_size_allocate (GtkWidget     *widget,
                             allocation->width,
                             allocation->height);
 
-  child = gtk_bin_get_child (GTK_BIN (button));
-  if (child && gtk_widget_get_visible (child))
-    {
-      GtkAllocation child_allocation;
-      GtkBorder border;
-      gint baseline;
+  gtk_css_gadget_allocate (priv->gadget,
+                           allocation,
+                           gtk_widget_get_allocated_baseline (widget),
+                           &clip);
 
-      gtk_button_get_full_border (button, &border);
-
-      child_allocation.x = allocation->x + border.left;
-      child_allocation.y = allocation->y + border.top;
-      child_allocation.width = allocation->width - border.left - border.right;
-      child_allocation.height = allocation->height - border.top - border.bottom;
+  gtk_widget_set_clip (widget, &clip);
+}
 
-      baseline = gtk_widget_get_allocated_baseline (widget);
-      if (baseline != -1)
-       baseline -= border.top;
+static void
+gtk_button_allocate (GtkCssGadget        *gadget,
+                     const GtkAllocation *allocation,
+                     int                  baseline,
+                     GtkAllocation       *out_clip,
+                     gpointer             unused)
+{
+  GtkWidget *widget;
+  GtkWidget *child;
 
-      child_allocation.width  = MAX (1, child_allocation.width);
-      child_allocation.height = MAX (1, child_allocation.height);
+  widget = gtk_css_gadget_get_owner (gadget);
 
-      gtk_widget_size_allocate_with_baseline (child, &child_allocation, baseline);
-    }
+  child = gtk_bin_get_child (GTK_BIN (widget));
+  if (child && gtk_widget_get_visible (child))
+    gtk_widget_size_allocate_with_baseline (child, (GtkAllocation *)allocation, baseline);
 
-  _gtk_widget_set_simple_clip (widget, NULL);
+  gtk_container_get_children_clip (GTK_CONTAINER (widget), out_clip);
 }
 
 static gboolean
 gtk_button_draw (GtkWidget *widget,
                 cairo_t   *cr)
 {
-  GtkButton *button = GTK_BUTTON (widget);
-  gint x, y;
-  gint width, height;
-  GtkBorder default_border;
-  GtkBorder default_outside_border;
-  GtkStyleContext *context;
-  GtkStateFlags state;
-
-  context = gtk_widget_get_style_context (widget);
-  state = gtk_style_context_get_state (context);
+  gtk_css_gadget_draw (GTK_BUTTON (widget)->priv->gadget, cr);
 
-  gtk_button_get_props (button, &default_border, &default_outside_border, NULL, NULL);
-
-  x = 0;
-  y = 0;
-  width = gtk_widget_get_allocated_width (widget);
-  height = gtk_widget_get_allocated_height (widget);
-
-  if (gtk_widget_has_default (widget) &&
-      gtk_button_get_relief (button) == GTK_RELIEF_NORMAL)
-    {
-      x += default_border.left;
-      y += default_border.top;
-      width -= default_border.left + default_border.right;
-      height -= default_border.top + default_border.bottom;
-    }
-  else if (gtk_widget_get_can_default (widget))
-    {
-      x += default_outside_border.left;
-      y += default_outside_border.top;
-      width -= default_outside_border.left + default_outside_border.right;
-      height -= default_outside_border.top + default_outside_border.bottom;
-    }
-
-  gtk_render_background (context, cr, x, y, width, height);
-  gtk_render_frame (context, cr, x, y, width, height);
-
-  if (gtk_widget_has_visible_focus (widget))
-    {
-      GtkBorder border;
-
-      gtk_style_context_get_border (context, state, &border);
+  return FALSE;
+}
 
-      x += border.left;
-      y += border.top;
-      width -= border.left + border.right;
-      height -= border.top + border.bottom;
+static gboolean
+gtk_button_draw_contents (GtkCssGadget *gadget,
+                          cairo_t      *cr,
+                          int           x,
+                          int           y,
+                          int           width,
+                          int           height,
+                          gpointer      data)
+{
+  GtkWidget *widget;
 
-      gtk_render_focus (context, cr, x, y, width, height);
-    }
+  widget = gtk_css_gadget_get_owner (gadget);
 
   GTK_WIDGET_CLASS (gtk_button_parent_class)->draw (widget, cr);
 
-  return FALSE;
+  return gtk_widget_has_visible_focus (widget);
 }
 
 static void
@@ -2128,106 +2049,101 @@ gtk_button_finish_activate (GtkButton *button,
 
 
 static void
-gtk_button_get_size (GtkWidget      *widget,
+gtk_button_get_size (GtkCssGadget   *gadget,
                     GtkOrientation  orientation,
                      gint            for_size,
-                    gint           *minimum_size,
-                    gint           *natural_size,
+                    gint           *minimum,
+                    gint           *natural,
                     gint           *minimum_baseline,
-                    gint           *natural_baseline)
+                    gint           *natural_baseline,
+                     gpointer        data)
 {
-  GtkButton *button = GTK_BUTTON (widget);
+  GtkWidget *widget;
   GtkWidget *child;
-  GtkBorder border;
-  gint minimum, natural;
 
-  gtk_button_get_full_border (button, &border);
+  widget = gtk_css_gadget_get_owner (gadget);
+  child = gtk_bin_get_child (GTK_BIN (widget));
 
-  if (orientation == GTK_ORIENTATION_HORIZONTAL)
-    {
-      minimum = border.left + border.right;
-      natural = minimum;
-
-      if (for_size >= 0)
-        for_size -= border.top + border.bottom;
-    }
+  if (child && gtk_widget_get_visible (child))
+    _gtk_widget_get_preferred_size_for_size (child,
+                                             orientation,
+                                             for_size,
+                                             minimum, natural,
+                                             minimum_baseline, natural_baseline);
   else
     {
-      minimum = border.top + border.bottom;
-      natural = minimum;
-
-      if (for_size >= 0)
-        for_size -= border.left + border.right;
+      *minimum = 0;
+      *natural = 0;
+      if (minimum_baseline)
+        *minimum_baseline = 0;
+      if (natural_baseline)
+        *natural_baseline = 0;
     }
-
-  if ((child = gtk_bin_get_child (GTK_BIN (button))) && 
-      gtk_widget_get_visible (child))
-    {
-      gint child_min, child_nat;
-      gint child_min_baseline = -1, child_nat_baseline = -1;
-
-      _gtk_widget_get_preferred_size_for_size (child,
-                                               orientation,
-                                               for_size,
-                                               &child_min, &child_nat,
-                                               &child_min_baseline, &child_nat_baseline);
-
-      if (minimum_baseline && child_min_baseline >= 0)
-       *minimum_baseline = child_min_baseline + border.top;
-      if (natural_baseline && child_nat_baseline >= 0)
-       *natural_baseline = child_nat_baseline + border.top;
-
-      minimum += child_min;
-      natural += child_nat;
-    }
-
-  *minimum_size = minimum;
-  *natural_size = natural;
 }
 
-static void 
+static void
 gtk_button_get_preferred_width (GtkWidget *widget,
                                 gint      *minimum_size,
                                 gint      *natural_size)
 {
-  gtk_button_get_size (widget, GTK_ORIENTATION_HORIZONTAL, -1, minimum_size, natural_size, NULL, NULL);
+  gtk_css_gadget_get_preferred_size (GTK_BUTTON (widget)->priv->gadget,
+                                     GTK_ORIENTATION_HORIZONTAL,
+                                     -1,
+                                     minimum_size, natural_size,
+                                     NULL, NULL);
 }
 
-static void 
+static void
 gtk_button_get_preferred_height (GtkWidget *widget,
                                  gint      *minimum_size,
                                  gint      *natural_size)
 {
-  gtk_button_get_size (widget, GTK_ORIENTATION_VERTICAL, -1, minimum_size, natural_size, NULL, NULL);
+  gtk_css_gadget_get_preferred_size (GTK_BUTTON (widget)->priv->gadget,
+                                     GTK_ORIENTATION_VERTICAL,
+                                     -1,
+                                     minimum_size, natural_size,
+                                     NULL, NULL);
 }
 
-static void 
+static void
 gtk_button_get_preferred_width_for_height (GtkWidget *widget,
                                            gint       for_size,
                                            gint      *minimum_size,
                                            gint      *natural_size)
 {
-  gtk_button_get_size (widget, GTK_ORIENTATION_HORIZONTAL, for_size, minimum_size, natural_size, NULL, NULL);
+  gtk_css_gadget_get_preferred_size (GTK_BUTTON (widget)->priv->gadget,
+                                     GTK_ORIENTATION_HORIZONTAL,
+                                     for_size,
+                                     minimum_size, natural_size,
+                                     NULL, NULL);
 }
 
-static void 
+static void
 gtk_button_get_preferred_height_for_width (GtkWidget *widget,
                                            gint       for_size,
                                            gint      *minimum_size,
                                            gint      *natural_size)
 {
-  gtk_button_get_size (widget, GTK_ORIENTATION_VERTICAL, for_size, minimum_size, natural_size, NULL, NULL);
+  gtk_css_gadget_get_preferred_size (GTK_BUTTON (widget)->priv->gadget,
+                                     GTK_ORIENTATION_VERTICAL,
+                                     for_size,
+                                     minimum_size, natural_size,
+                                     NULL, NULL);
 }
 
 static void
 gtk_button_get_preferred_height_and_baseline_for_width (GtkWidget *widget,
-                                                       gint       width,
+                                                       gint       for_size,
                                                        gint      *minimum_size,
                                                        gint      *natural_size,
                                                        gint      *minimum_baseline,
                                                        gint      *natural_baseline)
 {
-  gtk_button_get_size (widget, GTK_ORIENTATION_VERTICAL, width, minimum_size, natural_size, 
minimum_baseline, natural_baseline);
+  gtk_css_gadget_get_preferred_size (GTK_BUTTON (widget)->priv->gadget,
+                                     GTK_ORIENTATION_VERTICAL,
+                                     for_size,
+                                     minimum_size, natural_size,
+                                     minimum_baseline, natural_baseline);
 }
 
 /**
diff --git a/gtk/gtkbuttonprivate.h b/gtk/gtkbuttonprivate.h
index 2875660..5114a99 100644
--- a/gtk/gtkbuttonprivate.h
+++ b/gtk/gtkbuttonprivate.h
@@ -22,6 +22,7 @@
 #include "gtkactionhelper.h"
 #include "gtkgesturesingle.h"
 #include "deprecated/gtkaction.h"
+#include "gtkcssgadgetprivate.h"
 
 G_BEGIN_DECLS
 
@@ -31,6 +32,7 @@ struct _GtkButtonPrivate
   GtkAction             *action;
   GtkWidget             *image;
   GtkActionHelper       *action_helper;
+  GtkCssGadget          *gadget;
 
   GdkDevice             *grab_keyboard;
   GdkWindow             *event_window;


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