[gtk+/wip/matthiasc/gadget] flowbox: Convert child to gadgets



commit c1f6b85290339ff75a02c7b58e8ddb5a82bf8175
Author: Matthias Clasen <mclasen redhat com>
Date:   Thu Dec 10 01:39:26 2015 -0500

    flowbox: Convert child to gadgets

 gtk/gtkflowbox.c |  294 +++++++++++++++++++++++++++---------------------------
 1 files changed, 149 insertions(+), 145 deletions(-)
---
diff --git a/gtk/gtkflowbox.c b/gtk/gtkflowbox.c
index 5c42dda..5dc9cc9 100644
--- a/gtk/gtkflowbox.c
+++ b/gtk/gtkflowbox.c
@@ -79,6 +79,8 @@
 #include "gtkcssnodeprivate.h"
 #include "gtkwidgetprivate.h"
 #include "gtkstylecontextprivate.h"
+#include "gtkcsscustomgadgetprivate.h"
+#include "gtkcontainerprivate.h"
 
 #include "a11y/gtkflowboxaccessibleprivate.h"
 #include "a11y/gtkflowboxchildaccessible.h"
@@ -262,6 +264,7 @@ typedef struct _GtkFlowBoxChildPrivate GtkFlowBoxChildPrivate;
 struct _GtkFlowBoxChildPrivate
 {
   GSequenceIter *iter;
+  GtkCssGadget  *gadget;
   gboolean       selected;
 };
 
@@ -383,54 +386,31 @@ static gboolean
 gtk_flow_box_child_draw (GtkWidget *widget,
                          cairo_t   *cr)
 {
-  GtkAllocation allocation = {0};
-  GtkStyleContext* context;
-  GtkStateFlags state;
-  GtkBorder border;
+  gtk_css_gadget_draw (CHILD_PRIV (GTK_FLOW_BOX_CHILD (widget))->gadget, cr);
 
-  gtk_widget_get_allocation (widget, &allocation);
-  context = gtk_widget_get_style_context (widget);
-  state = gtk_widget_get_state_flags (widget);
+  return FALSE;
+}
 
-  gtk_render_background (context, cr, 0, 0, allocation.width, allocation.height);
-  gtk_render_frame (context, cr, 0, 0, allocation.width, allocation.height);
+static gboolean
+gtk_flow_box_child_render (GtkCssGadget *gadget,
+                           cairo_t      *cr,
+                           int           x,
+                           int           y,
+                           int           width,
+                           int           height,
+                           gpointer      data)
+{
+  GtkWidget *widget;
 
-  if (gtk_widget_has_visible_focus (widget))
-    {
-      gtk_style_context_get_border (context, state, &border);
-      gtk_render_focus (context, cr, border.left, border.top,
-                        allocation.width - border.left - border.right,
-                        allocation.height - border.top - border.bottom);
-    }
+  widget = gtk_css_gadget_get_owner (gadget);
 
   GTK_WIDGET_CLASS (gtk_flow_box_child_parent_class)->draw (widget, cr);
 
-  return TRUE;
+  return gtk_widget_has_visible_focus (widget);
 }
 
 /* Size allocation {{{3 */
 
-static void
-gtk_flow_box_child_get_full_border (GtkFlowBoxChild *child,
-                                    GtkBorder       *full_border)
-{
-  GtkWidget *widget = GTK_WIDGET (child);
-  GtkStyleContext *context;
-  GtkStateFlags state;
-  GtkBorder padding, border;
-
-  context = gtk_widget_get_style_context (widget);
-  state = gtk_style_context_get_state (context);
-
-  gtk_style_context_get_padding (context, state, &padding);
-  gtk_style_context_get_border (context, state, &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;
-}
-
 static GtkSizeRequestMode
 gtk_flow_box_child_get_request_mode (GtkWidget *widget)
 {
@@ -443,123 +423,122 @@ gtk_flow_box_child_get_request_mode (GtkWidget *widget)
     return GTK_SIZE_REQUEST_HEIGHT_FOR_WIDTH;
 }
 
-static void gtk_flow_box_child_get_preferred_width_for_height (GtkWidget *widget,
-                                                               gint       height,
-                                                               gint      *minimum_width,
-                                                               gint      *natural_width);
-static void gtk_flow_box_child_get_preferred_height           (GtkWidget *widget,
-                                                               gint      *minimum_height,
-                                                               gint      *natural_height);
+static void
+gtk_flow_box_child_get_preferred_height (GtkWidget *widget,
+                                         gint      *minimum,
+                                         gint      *natural)
+{
+  gtk_css_gadget_get_preferred_size (CHILD_PRIV (GTK_FLOW_BOX_CHILD (widget))->gadget,
+                                     GTK_ORIENTATION_VERTICAL,
+                                     -1,
+                                     minimum, natural,
+                                     NULL, NULL);
+}
 
 static void
 gtk_flow_box_child_get_preferred_height_for_width (GtkWidget *widget,
                                                    gint       width,
-                                                   gint      *minimum_height,
-                                                   gint      *natural_height)
+                                                   gint      *minimum,
+                                                   gint      *natural)
 {
-  if (gtk_flow_box_child_get_request_mode (widget) == GTK_SIZE_REQUEST_HEIGHT_FOR_WIDTH)
-    {
-      GtkWidget *child;
-      gint child_min = 0, child_natural = 0;
-      GtkBorder full_border = { 0, };
-
-      gtk_flow_box_child_get_full_border (GTK_FLOW_BOX_CHILD (widget), &full_border);
-      child = gtk_bin_get_child (GTK_BIN (widget));
-      if (child && gtk_widget_get_visible (child))
-        gtk_widget_get_preferred_height_for_width (child, width - full_border.left - full_border.right,
-                                                   &child_min, &child_natural);
-
-      *minimum_height = full_border.top + child_min + full_border.bottom;
-      *natural_height = full_border.top + child_natural + full_border.bottom;
-    }
-  else
-    {
-      gtk_flow_box_child_get_preferred_height (widget, minimum_height, natural_height);
-    }
+  gtk_css_gadget_get_preferred_size (CHILD_PRIV (GTK_FLOW_BOX_CHILD (widget))->gadget,
+                                     GTK_ORIENTATION_VERTICAL,
+                                     width,
+                                     minimum, natural,
+                                     NULL, NULL);
 }
 
 static void
 gtk_flow_box_child_get_preferred_width (GtkWidget *widget,
-                                        gint      *minimum_width,
-                                        gint      *natural_width)
+                                        gint      *minimum,
+                                        gint      *natural)
 {
-  if (gtk_flow_box_child_get_request_mode (widget) == GTK_SIZE_REQUEST_HEIGHT_FOR_WIDTH)
-    {
-      GtkWidget *child;
-      gint child_min = 0, child_natural = 0;
-      GtkBorder full_border = { 0, };
-
-      gtk_flow_box_child_get_full_border (GTK_FLOW_BOX_CHILD (widget), &full_border);
-      child = gtk_bin_get_child (GTK_BIN (widget));
-      if (child && gtk_widget_get_visible (child))
-        gtk_widget_get_preferred_width (child, &child_min, &child_natural);
-
-      *minimum_width = full_border.left + child_min + full_border.right;
-      *natural_width = full_border.left + child_natural + full_border.right;
-    }
-  else
-    {
-      gint natural_height;
-
-      gtk_flow_box_child_get_preferred_height (widget, NULL, &natural_height);
-      gtk_flow_box_child_get_preferred_width_for_height (widget, natural_height,
-                                                         minimum_width, natural_width);
-    }
+  gtk_css_gadget_get_preferred_size (CHILD_PRIV (GTK_FLOW_BOX_CHILD (widget))->gadget,
+                                     GTK_ORIENTATION_HORIZONTAL,
+                                     -1,
+                                     minimum, natural,
+                                     NULL, NULL);
 }
 
 static void
 gtk_flow_box_child_get_preferred_width_for_height (GtkWidget *widget,
                                                    gint       height,
-                                                   gint      *minimum_width,
-                                                   gint      *natural_width)
+                                                   gint      *minimum,
+                                                   gint      *natural)
 {
-  if (gtk_flow_box_child_get_request_mode (widget) == GTK_SIZE_REQUEST_HEIGHT_FOR_WIDTH)
-    {
-      gtk_flow_box_child_get_preferred_width (widget, minimum_width, natural_width);
-    }
-  else
-    {
-      GtkWidget *child;
-      gint child_min = 0, child_natural = 0;
-      GtkBorder full_border = { 0, };
-
-      gtk_flow_box_child_get_full_border (GTK_FLOW_BOX_CHILD (widget), &full_border);
-      child = gtk_bin_get_child (GTK_BIN (widget));
-      if (child && gtk_widget_get_visible (child))
-        gtk_widget_get_preferred_width_for_height (child, height - full_border.top - full_border.bottom,
-                                                   &child_min, &child_natural);
-
-      *minimum_width = full_border.left + child_min + full_border.right;
-      *natural_width = full_border.left + child_natural + full_border.right;
-    }
+  gtk_css_gadget_get_preferred_size (CHILD_PRIV (GTK_FLOW_BOX_CHILD (widget))->gadget,
+                                     GTK_ORIENTATION_HORIZONTAL,
+                                     height,
+                                     minimum, natural,
+                                     NULL, NULL);
 }
 
 static void
-gtk_flow_box_child_get_preferred_height (GtkWidget *widget,
-                                         gint      *minimum_height,
-                                         gint      *natural_height)
+gtk_flow_box_child_measure (GtkCssGadget   *gadget,
+                            GtkOrientation  orientation,
+                            int             for_size,
+                            int            *minimum,
+                            int            *natural,
+                            int            *minimum_baseline,
+                            int            *natural_baseline,
+                            gpointer        data)
 {
-  if (gtk_flow_box_child_get_request_mode (widget) == GTK_SIZE_REQUEST_HEIGHT_FOR_WIDTH)
+  GtkWidget *widget;
+  GtkWidget *child;
+
+  widget = gtk_css_gadget_get_owner (gadget);
+  child = gtk_bin_get_child (GTK_BIN (widget));
+  if (!child || ! gtk_widget_get_visible (child))
     {
-      gint natural_width;
+      *minimum = *natural = 0;
+      return;
+    }
 
-      gtk_flow_box_child_get_preferred_width (widget, NULL, &natural_width);
-      gtk_flow_box_child_get_preferred_height_for_width (widget, natural_width,
-                                                         minimum_height, natural_height);
+  if (orientation == GTK_ORIENTATION_HORIZONTAL)
+    {
+      if (for_size < 0)
+        {
+          if (gtk_flow_box_child_get_request_mode (widget) == GTK_SIZE_REQUEST_HEIGHT_FOR_WIDTH)
+            {
+              gtk_widget_get_preferred_width (child, minimum, natural);
+            }
+          else
+            {
+              gint height;
+              gtk_widget_get_preferred_height (child, NULL, &height);
+              gtk_widget_get_preferred_width_for_height (child, height, minimum, natural);
+            }
+        }
+      else
+        {
+          if (gtk_flow_box_child_get_request_mode (widget) == GTK_SIZE_REQUEST_HEIGHT_FOR_WIDTH)
+            gtk_widget_get_preferred_width (child, minimum, natural);
+          else
+            gtk_widget_get_preferred_width_for_height (child, for_size, minimum, natural);
+        }
     }
   else
     {
-      GtkWidget *child;
-      gint child_min = 0, child_natural = 0;
-      GtkBorder full_border = { 0, };
-
-      gtk_flow_box_child_get_full_border (GTK_FLOW_BOX_CHILD (widget), &full_border);
-      child = gtk_bin_get_child (GTK_BIN (widget));
-      if (child && gtk_widget_get_visible (child))
-        gtk_widget_get_preferred_height (child, &child_min, &child_natural);
-
-      *minimum_height = full_border.top + child_min + full_border.bottom;
-      *natural_height = full_border.top + child_natural + full_border.bottom;
+      if (for_size < 0)
+        {
+          if (gtk_flow_box_child_get_request_mode (widget) == GTK_SIZE_REQUEST_HEIGHT_FOR_WIDTH)
+            {
+              gint width;
+              gtk_widget_get_preferred_width (child, NULL, &width);
+              gtk_widget_get_preferred_height_for_width (child, width, minimum, natural);
+            }
+          else
+            {
+              gtk_widget_get_preferred_height (child, minimum, natural);
+            }
+        }
+      else
+        {
+          if (gtk_flow_box_child_get_request_mode (widget) == GTK_SIZE_REQUEST_HEIGHT_FOR_WIDTH)
+            gtk_widget_get_preferred_height_for_width (child, for_size, minimum, natural);
+          else
+            gtk_widget_get_preferred_height (child, minimum, natural);
+        }
     }
 }
 
@@ -567,38 +546,55 @@ static void
 gtk_flow_box_child_size_allocate (GtkWidget     *widget,
                                   GtkAllocation *allocation)
 {
-  GtkWidget *child;
+  GtkAllocation clip;
 
   gtk_widget_set_allocation (widget, allocation);
 
-  child = gtk_bin_get_child (GTK_BIN (widget));
-  if (child && gtk_widget_get_visible (child))
-    {
-      GtkAllocation child_allocation;
-      GtkBorder border = { 0, };
+  gtk_css_gadget_allocate (CHILD_PRIV (GTK_FLOW_BOX_CHILD (widget))->gadget,
+                           allocation,
+                           gtk_widget_get_allocated_baseline (widget),
+                           &clip);
+
+  gtk_widget_set_clip (widget, &clip);
+}
 
-      gtk_flow_box_child_get_full_border (GTK_FLOW_BOX_CHILD (widget), &border);
+static void
+gtk_flow_box_child_allocate (GtkCssGadget        *gadget,
+                             const GtkAllocation *allocation,
+                             int                  baseline,
+                             GtkAllocation       *out_clip,
+                             gpointer             data)
+{
+  GtkWidget *widget;
+  GtkWidget *child;
 
-      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;
+  widget = gtk_css_gadget_get_owner (gadget);
 
-      child_allocation.width  = MAX (1, child_allocation.width);
-      child_allocation.height = MAX (1, child_allocation.height);
+  child = gtk_bin_get_child (GTK_BIN (widget));
+  if (child && gtk_widget_get_visible (child))
+    gtk_widget_size_allocate (child, (GtkAllocation *)allocation);
 
-      gtk_widget_size_allocate (child, &child_allocation);
-    }
+  gtk_container_get_children_clip (GTK_CONTAINER (widget), out_clip);
 }
 
 /* GObject implementation {{{2 */
 
 static void
+gtk_flow_box_child_finalize (GObject *object)
+{
+  g_clear_object (&CHILD_PRIV (GTK_FLOW_BOX_CHILD (object))->gadget);
+
+  G_OBJECT_CLASS (gtk_flow_box_child_parent_class)->finalize (object);
+}
+
+static void
 gtk_flow_box_child_class_init (GtkFlowBoxChildClass *class)
 {
   GObjectClass *object_class = G_OBJECT_CLASS (class);
   GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
 
+  object_class->finalize = gtk_flow_box_child_finalize;
+
   widget_class->draw = gtk_flow_box_child_draw;
   widget_class->get_request_mode = gtk_flow_box_child_get_request_mode;
   widget_class->get_preferred_height = gtk_flow_box_child_get_preferred_height;
@@ -641,6 +637,14 @@ gtk_flow_box_child_init (GtkFlowBoxChild *child)
 {
   gtk_widget_set_can_focus (GTK_WIDGET (child), TRUE);
   gtk_widget_set_redraw_on_allocate (GTK_WIDGET (child), TRUE);
+
+  CHILD_PRIV (child)->gadget = gtk_css_custom_gadget_new_for_node (gtk_widget_get_css_node (GTK_WIDGET 
(child)),
+                                                     GTK_WIDGET (child),
+                                                     gtk_flow_box_child_measure,
+                                                     gtk_flow_box_child_allocate,
+                                                     gtk_flow_box_child_render,
+                                                     NULL,
+                                                     NULL);
 }
 
 /* Public API {{{2 */


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