[gtk+/wip/cosimoc/range-gadget] WIP



commit b1ce4359790a3a0aa6a28ebb6322a0d7cbab5381
Author: Cosimo Cecchi <cosimoc gnome org>
Date:   Sat Jan 9 14:00:09 2016 -0800

    WIP

 gtk/gtkrange.c |  439 ++++++++++++++++++++++++++++---------------------------
 1 files changed, 223 insertions(+), 216 deletions(-)
---
diff --git a/gtk/gtkrange.c b/gtk/gtkrange.c
index e177ac7..bc04eba 100644
--- a/gtk/gtkrange.c
+++ b/gtk/gtkrange.c
@@ -32,6 +32,7 @@
 #include "gtkrangeprivate.h"
 
 #include "gtkadjustmentprivate.h"
+#include "gtkcsscustomgadgetprivate.h"
 #include "gtkcolorscaleprivate.h"
 #include "gtkintl.h"
 #include "gtkgesturelongpressprivate.h"
@@ -108,9 +109,9 @@ struct _GtkRangePrivate
   GtkCssNode *stepper_b_node;
   GtkCssNode *stepper_c_node;
   GtkCssNode *stepper_d_node;
-  GtkCssNode *trough_node;
-  GtkCssNode *highlight_node;
-  GtkCssNode *fill_node;
+  GtkCssGadget *trough_gadget;
+  GtkCssGadget *fill_gadget;
+  GtkCssGadget *highlight_gadget;
   GtkCssNode *slider_node;
 
   GtkOrientation     orientation;
@@ -778,16 +779,18 @@ gtk_range_init (GtkRange *range)
   _gtk_orientable_set_style_classes (GTK_ORIENTABLE (range));
 
   widget_node = gtk_widget_get_css_node (GTK_WIDGET (range));
-  priv->trough_node = gtk_css_node_new ();
-  gtk_css_node_set_name (priv->trough_node, I_("trough"));
-  gtk_css_node_set_parent (priv->trough_node, widget_node);
-  gtk_css_node_set_state (priv->trough_node, gtk_css_node_get_state (widget_node));
-  g_signal_connect_object (priv->trough_node, "style-changed", G_CALLBACK (node_style_changed_cb), range, 0);
-  g_object_unref (priv->trough_node);
+  priv->trough_gadget = gtk_css_custom_gadget_new ("trough",
+                                                   GTK_WIDGET (range),
+                                                   NULL, NULL,
+                                                   NULL, NULL, NULL,
+                                                   NULL, NULL);
+  gtk_css_node_set_parent (gtk_css_gadget_get_node (priv->trough_gadget), widget_node);
+  gtk_css_node_set_state (gtk_css_gadget_get_node (priv->trough_gadget),
+                          gtk_css_node_get_state (widget_node));
 
   priv->slider_node = gtk_css_node_new ();
   gtk_css_node_set_name (priv->slider_node, I_("slider"));
-  gtk_css_node_set_parent (priv->slider_node, priv->trough_node);
+  gtk_css_node_set_parent (priv->slider_node, gtk_css_gadget_get_node (priv->trough_gadget));
   gtk_css_node_set_state (priv->slider_node, gtk_css_node_get_state (widget_node));
   g_signal_connect_object (priv->slider_node, "style-changed", G_CALLBACK (node_style_changed_cb), range, 0);
   g_object_unref (priv->slider_node);
@@ -1467,17 +1470,17 @@ gtk_range_set_show_fill_level (GtkRange *range,
 
   if (show_fill_level)
     {
-      priv->fill_node = gtk_css_node_new ();
-      gtk_css_node_set_name (priv->fill_node, I_("fill"));
-      gtk_css_node_set_parent (priv->fill_node, priv->trough_node);
-      gtk_css_node_set_state (priv->fill_node, gtk_css_node_get_state (priv->trough_node));
-      g_signal_connect_object (priv->fill_node, "style-changed", G_CALLBACK (node_style_changed_cb), range, 
0);
-      g_object_unref (priv->fill_node);
+      priv->fill_gadget = gtk_css_custom_gadget_new ("fill",
+                                                     GTK_WIDGET (range),
+                                                     priv->trough_gadget, NULL,
+                                                     NULL, NULL, NULL,
+                                                     NULL, NULL);
+      gtk_css_node_set_state (gtk_css_gadget_get_node (priv->fill_gadget),
+                              gtk_css_node_get_state (gtk_css_gadget_get_node (priv->trough_gadget)));
     }
   else
     {
-      gtk_css_node_set_parent (priv->fill_node, NULL);
-      priv->fill_node = NULL;
+      g_clear_object (&priv->fill_gadget);
     }
 
   g_object_notify_by_pspec (G_OBJECT (range), properties[PROP_SHOW_FILL_LEVEL]);
@@ -1644,6 +1647,10 @@ gtk_range_destroy (GtkWidget *widget)
   g_clear_object (&priv->multipress_gesture);
   g_clear_object (&priv->long_press_gesture);
 
+  g_clear_object (&priv->trough_gadget);
+  g_clear_object (&priv->fill_gadget);
+  g_clear_object (&priv->highlight_gadget);
+
   if (priv->adjustment)
     {
       g_signal_handlers_disconnect_by_func (priv->adjustment,
@@ -1719,11 +1726,167 @@ gtk_range_get_preferred_height (GtkWidget *widget,
 }
 
 static void
+gtk_range_allocate_trough (GtkRange *range,
+                           GtkAllocation *out_clip)
+{
+  GtkRangePrivate *priv = range->priv;
+  GtkAllocation widget_alloc;
+  GtkAllocation trough_alloc = priv->range_rect;
+  gboolean trough_under_steppers;
+  gint stepper_size;
+  gint stepper_spacing;
+
+  gtk_widget_style_get (GTK_WIDGET (range),
+                        "trough-under-steppers", &trough_under_steppers,
+                        "stepper-size",          &stepper_size,
+                        "stepper-spacing",       &stepper_spacing,
+                        NULL);
+
+  gtk_widget_get_allocation (GTK_WIDGET (range), &widget_alloc);
+  trough_alloc.x += widget_alloc.x;
+  trough_alloc.y += widget_alloc.y;
+
+  if (!trough_under_steppers)
+    {
+      gint offset  = 0;
+      gint shorter = 0;
+
+      if (priv->has_stepper_a)
+        offset += stepper_size;
+
+      if (priv->has_stepper_b)
+        offset += stepper_size;
+
+      shorter += offset;
+
+      if (priv->has_stepper_c)
+        shorter += stepper_size;
+
+      if (priv->has_stepper_d)
+        shorter += stepper_size;
+
+      if (priv->has_stepper_a || priv->has_stepper_b)
+        {
+          offset  += stepper_spacing;
+          shorter += stepper_spacing;
+        }
+
+      if (priv->has_stepper_c || priv->has_stepper_d)
+        {
+          shorter += stepper_spacing;
+        }
+
+      if (priv->orientation == GTK_ORIENTATION_HORIZONTAL)
+        {
+          trough_alloc.x     += offset;
+          trough_alloc.width -= shorter;
+        }
+      else
+        {
+          trough_alloc.y      += offset;
+          trough_alloc.height -= shorter;
+        }
+    }
+
+  gtk_css_gadget_allocate (priv->trough_gadget,
+                           &trough_alloc,
+                           gtk_widget_get_allocated_baseline (GTK_WIDGET (range)),
+                           out_clip);
+
+  if (priv->show_fill_level &&
+      gtk_adjustment_get_upper (priv->adjustment) - gtk_adjustment_get_page_size (priv->adjustment) -
+      gtk_adjustment_get_lower (priv->adjustment) != 0)
+    {
+      gdouble level;
+      gdouble fill = 0.0;
+      GtkAllocation content_alloc, fill_alloc, fill_clip;
+
+      gtk_css_gadget_get_content_allocation (priv->trough_gadget,
+                                             &content_alloc, NULL);
+      fill_alloc = content_alloc;
+
+      level = CLAMP (priv->fill_level,
+                     gtk_adjustment_get_lower (priv->adjustment),
+                     gtk_adjustment_get_upper (priv->adjustment) -
+                     gtk_adjustment_get_page_size (priv->adjustment));
+
+      fill = (level - gtk_adjustment_get_lower (priv->adjustment)) /
+        (gtk_adjustment_get_upper (priv->adjustment) -
+         gtk_adjustment_get_lower (priv->adjustment) -
+         gtk_adjustment_get_page_size (priv->adjustment));
+
+      if (priv->orientation == GTK_ORIENTATION_HORIZONTAL)
+        {
+          fill_alloc.width *= fill;
+
+          if (should_invert (range))
+            fill_alloc.x += content_alloc.width - fill_alloc.width;
+        }
+      else
+        {
+          fill_alloc.height *= fill;
+
+          if (should_invert (range))
+            fill_alloc.y += content_alloc.height - (fill_alloc.height * fill);
+        }
+
+      gtk_css_gadget_allocate (priv->fill_gadget,
+                               &fill_alloc,
+                               gtk_widget_get_allocated_baseline (GTK_WIDGET (range)),
+                               &fill_clip);
+      gdk_rectangle_union (out_clip, &fill_clip, out_clip);
+    }
+
+  if (priv->has_origin)
+    {
+      GtkAllocation content_alloc, highlight_alloc, highlight_clip;
+
+      gtk_css_gadget_get_content_allocation (priv->trough_gadget,
+                                             &content_alloc, NULL);
+      highlight_alloc = content_alloc;
+
+      if (priv->orientation == GTK_ORIENTATION_HORIZONTAL)
+        {
+          if (!should_invert (range))
+            {
+              highlight_alloc.x = content_alloc.x;
+              highlight_alloc.width = priv->slider.x + priv->slider.width / 2 - content_alloc.x + 
widget_alloc.x;
+            }
+          else
+            {
+              highlight_alloc.x = priv->slider.x + priv->slider.width / 2;
+              highlight_alloc.width = content_alloc.x + content_alloc.width - highlight_alloc.x;
+            }
+        }
+      else
+        {
+          if (!should_invert (range))
+            {
+              highlight_alloc.y = content_alloc.y;
+              highlight_alloc.height = priv->slider.y + priv->slider.height / 2 - content_alloc.y + 
widget_alloc.y;
+            }
+          else
+            {
+              highlight_alloc.y = priv->slider.y + priv->slider.height / 2;
+              highlight_alloc.height = content_alloc.y + content_alloc.height - highlight_alloc.y;
+            }
+        }
+
+      gtk_css_gadget_allocate (priv->highlight_gadget,
+                               &highlight_alloc,
+                               gtk_widget_get_allocated_baseline (GTK_WIDGET (range)),
+                               &highlight_clip);
+      gdk_rectangle_union (out_clip, &highlight_clip, out_clip);
+    }
+}
+
+static void
 gtk_range_size_allocate (GtkWidget     *widget,
                          GtkAllocation *allocation)
 {
   GtkRange *range = GTK_RANGE (widget);
   GtkRangePrivate *priv = range->priv;
+  GtkAllocation clip;
 
   gtk_widget_set_allocation (widget, allocation);
 
@@ -1735,7 +1898,9 @@ gtk_range_size_allocate (GtkWidget     *widget,
                             allocation->x, allocation->y,
                             allocation->width, allocation->height);
 
-  _gtk_widget_set_simple_clip (widget, NULL);
+  gtk_range_allocate_trough (range, &clip);
+
+  gtk_widget_set_clip (widget, &clip);
 }
 
 static void
@@ -1854,11 +2019,11 @@ update_trough_state (GtkRange *range)
   if (priv->grab_location == MOUSE_TROUGH)
     state |= GTK_STATE_FLAG_ACTIVE;
 
-  gtk_css_node_set_state (priv->trough_node, state);
-  if (priv->highlight_node)
-    gtk_css_node_set_state (priv->highlight_node, state);
-  if (priv->fill_node)
-    gtk_css_node_set_state (priv->fill_node, state);
+  gtk_css_node_set_state (gtk_css_gadget_get_node (priv->trough_gadget), state);
+  if (priv->highlight_gadget)
+    gtk_css_node_set_state (gtk_css_gadget_get_node (priv->highlight_gadget), state);
+  if (priv->fill_gadget)
+    gtk_css_node_set_state (gtk_css_gadget_get_node (priv->fill_gadget), state);
 }
 
 static void
@@ -1962,188 +2127,30 @@ gtk_range_draw (GtkWidget *widget,
   gdk_cairo_rectangle (cr, &priv->range_rect);
   cairo_clip (cr);
 
-    {
-      gint x = priv->range_rect.x;
-      gint y = priv->range_rect.y;
-      gint width = priv->range_rect.width;
-      gint height = priv->range_rect.height;
-      gboolean trough_under_steppers;
-      gint stepper_size;
-      gint stepper_spacing;
-
-      gtk_widget_style_get (GTK_WIDGET (range),
-                            "trough-under-steppers", &trough_under_steppers,
-                            "stepper-size",          &stepper_size,
-                            "stepper-spacing",       &stepper_spacing,
-                            NULL);
-
-      if (!trough_under_steppers)
-        {
-          gint offset  = 0;
-          gint shorter = 0;
-
-          if (priv->has_stepper_a)
-            offset += stepper_size;
-
-          if (priv->has_stepper_b)
-            offset += stepper_size;
-
-          shorter += offset;
-
-          if (priv->has_stepper_c)
-            shorter += stepper_size;
-
-          if (priv->has_stepper_d)
-            shorter += stepper_size;
-
-          if (priv->has_stepper_a || priv->has_stepper_b)
-            {
-              offset  += stepper_spacing;
-              shorter += stepper_spacing;
-            }
-
-          if (priv->has_stepper_c || priv->has_stepper_d)
-            {
-              shorter += stepper_spacing;
-            }
-
-          if (priv->orientation == GTK_ORIENTATION_HORIZONTAL)
-            {
-              x     += offset;
-              width -= shorter;
-            }
-          else
-            {
-              y      += offset;
-              height -= shorter;
-            }
-        }
-
-      if (draw_trough)
-        {
-          gtk_style_context_save_to_node (context, priv->trough_node);
-
-          gtk_style_context_get_margin (context, gtk_style_context_get_state (context), &margin);
-
-          x += margin.left;
-          y += margin.top;
-          width -= margin.left + margin.right;
-          height -= margin.top + margin.bottom;
-
-          gtk_render_background (context, cr, x, y, width, height);
-          gtk_render_frame (context, cr, x, y, width, height);
+  {
+    if (draw_trough)
+      {
+        gtk_css_gadget_draw (priv->trough_gadget, cr);
 
-          gtk_style_context_restore (context);
+        if (priv->show_fill_level &&
+            gtk_adjustment_get_upper (priv->adjustment) - gtk_adjustment_get_page_size (priv->adjustment) -
+            gtk_adjustment_get_lower (priv->adjustment) != 0)
+          gtk_css_gadget_draw (priv->fill_gadget, cr);
 
-          if (priv->show_fill_level &&
-              gtk_adjustment_get_upper (priv->adjustment) - gtk_adjustment_get_page_size (priv->adjustment) -
-              gtk_adjustment_get_lower (priv->adjustment) != 0)
-            {
-              gdouble level;
-              gdouble fill = 0.0;
-              gint fx = x;
-              gint fy = y;
-              gint fwidth = width;
-              gint fheight = height;
-
-              level = CLAMP (priv->fill_level,
-                             gtk_adjustment_get_lower (priv->adjustment),
-                             gtk_adjustment_get_upper (priv->adjustment) -
-                             gtk_adjustment_get_page_size (priv->adjustment));
-
-              fill = (level - gtk_adjustment_get_lower (priv->adjustment)) /
-                      (gtk_adjustment_get_upper (priv->adjustment) -
-                      gtk_adjustment_get_lower (priv->adjustment) -
-                      gtk_adjustment_get_page_size (priv->adjustment));
-
-              if (priv->orientation == GTK_ORIENTATION_HORIZONTAL)
-                {
-                  if (!should_invert (range))
-                    {
-                      fx = x;
-                      fwidth = width * fill;
-                    }
-                  else
-                    {
-                      fwidth = width * fill;
-                      fx = x + width - fwidth;
-                    }
-                }
-              else
-                {
-                  if (!should_invert (range))
-                    {
-                      fy = y;
-                      fheight = height * fill;
-                    }
-                  else
-                    {
-                      fheight = height * fill;
-                      fy = y + height - fheight;
-                    }
-                }
-
-              gtk_style_context_save_to_node (context, priv->fill_node);
-
-              gtk_render_background (context, cr, fx, fy, fwidth, fheight);
-              gtk_render_frame (context, cr, fx, fy, fwidth, fheight);
-
-              gtk_style_context_restore (context);
-            }
-
-          if (priv->has_origin)
-            {
-              gint fx = x;
-              gint fy = y;
-              gint fwidth = width;
-              gint fheight = height;
-
-              if (priv->orientation == GTK_ORIENTATION_HORIZONTAL)
-                {
-                  if (!should_invert (range))
-                    {
-                      fx = x;
-                      fwidth = priv->slider.x + priv->slider.width / 2 - x;
-                    }
-                  else
-                    {
-                      fx = priv->slider.x + priv->slider.width / 2;
-                      fwidth = x + width - fx;
-                    }
-                }
-              else
-                {
-                  if (!should_invert (range))
-                    {
-                      fy = y;
-                      fheight = priv->slider.y + priv->slider.height / 2 - y;
-                    }
-                  else
-                    {
-                      fy = priv->slider.y + priv->slider.height / 2;
-                      fheight = y + height - fy;
-                    }
-                }
-
-              gtk_style_context_save_to_node (context, priv->highlight_node);
-
-              gtk_render_background (context, cr, fx, fy, fwidth, fheight);
-              gtk_render_frame (context, cr, fx, fy, fwidth, fheight);
-
-              gtk_style_context_restore (context);
-            }
-        }
+        if (priv->has_origin)
+          gtk_css_gadget_draw (priv->highlight_gadget, cr);
+      }
 
-      if (!(gtk_widget_get_state_flags (widget) & GTK_STATE_FLAG_INSENSITIVE) &&
-          gtk_widget_has_visible_focus (widget))
-        {
-          gtk_render_focus (context, cr,
-                            priv->range_rect.x,
-                            priv->range_rect.y,
-                            priv->range_rect.width,
-                            priv->range_rect.height);
-        }
-    }
+    if (!(gtk_widget_get_state_flags (widget) & GTK_STATE_FLAG_INSENSITIVE) &&
+        gtk_widget_has_visible_focus (widget))
+      {
+        gtk_render_focus (context, cr,
+                          priv->range_rect.x,
+                          priv->range_rect.y,
+                          priv->range_rect.width,
+                          priv->range_rect.height);
+      }
+  }
 
   cairo_restore (cr);
 
@@ -4140,17 +4147,17 @@ _gtk_range_set_has_origin (GtkRange *range,
 
   if (has_origin)
     {
-      priv->highlight_node = gtk_css_node_new ();
-      gtk_css_node_set_name (priv->highlight_node, I_("highlight"));
-      gtk_css_node_set_parent (priv->highlight_node, priv->trough_node);
-      gtk_css_node_set_state (priv->highlight_node, gtk_css_node_get_state (priv->trough_node));
-      g_signal_connect_object (priv->highlight_node, "style-changed", G_CALLBACK (node_style_changed_cb), 
range, 0);
-      g_object_unref (priv->highlight_node);
+      priv->highlight_gadget = gtk_css_custom_gadget_new ("highlight",
+                                                          GTK_WIDGET (range),
+                                                          priv->trough_gadget, NULL,
+                                                          NULL, NULL, NULL,
+                                                          NULL, NULL);
+      gtk_css_node_set_state (gtk_css_gadget_get_node (priv->highlight_gadget),
+                              gtk_css_node_get_state (gtk_css_gadget_get_node (priv->trough_gadget)));
     }
   else
     {
-      gtk_css_node_set_parent (priv->highlight_node, NULL);
-      priv->highlight_node = NULL;
+      g_clear_object (&priv->highlight_gadget);
     }
 }
 
@@ -4278,7 +4285,7 @@ _gtk_range_set_steppers (GtkRange *range,
         {
           priv->stepper_a_node = create_stepper_node (range,
                                                       "down",
-                                                      priv->has_stepper_b ? priv->stepper_b_node : 
priv->trough_node,
+                                                      priv->has_stepper_b ? priv->stepper_b_node : 
gtk_css_gadget_get_node (priv->trough_gadget),
                                                       NULL);
         }
       else
@@ -4295,7 +4302,7 @@ _gtk_range_set_steppers (GtkRange *range,
         {
           priv->stepper_b_node = create_stepper_node (range,
                                                       "up",
-                                                      priv->trough_node,
+                                                      gtk_css_gadget_get_node (priv->trough_gadget),
                                                       NULL);
         }
       else
@@ -4313,7 +4320,7 @@ _gtk_range_set_steppers (GtkRange *range,
           priv->stepper_c_node = create_stepper_node (range,
                                                       "down",
                                                       NULL,
-                                                      priv->trough_node);
+                                                      gtk_css_gadget_get_node (priv->trough_gadget));
         }
       else
         {
@@ -4330,7 +4337,7 @@ _gtk_range_set_steppers (GtkRange *range,
           priv->stepper_d_node = create_stepper_node (range,
                                                       "up",
                                                       NULL,
-                                                      priv->has_stepper_c ? priv->stepper_c_node : 
priv->trough_node);
+                                                      priv->has_stepper_c ? priv->stepper_c_node : 
gtk_css_gadget_get_node (priv->trough_gadget));
         }
       else
         {
@@ -4345,5 +4352,5 @@ _gtk_range_set_steppers (GtkRange *range,
 GtkCssNode *
 gtk_range_get_trough_node (GtkRange *range)
 {
-  return range->priv->trough_node;
+  return gtk_css_gadget_get_node (range->priv->trough_gadget);
 }


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