[gtk+] GtkStyleSet: Register the border-style and border-color properties



commit 3a455ed8f95324bdbf554935f7cff87518665c39
Author: Carlos Garnacho <carlosg gnome org>
Date:   Fri Oct 22 10:38:21 2010 +0200

    GtkStyleSet: Register the border-style and border-color properties
    
    This is also implemented in the theming engine, although the default
    CSS should be using it in order to theme buttons, troughs, sliders
    and such.

 gtk/gtkenums.h         |    6 +
 gtk/gtkstyleset.c      |    3 +
 gtk/gtkthemingengine.c |  292 +++++++++++++++++++++++++-----------------------
 3 files changed, 161 insertions(+), 140 deletions(-)
---
diff --git a/gtk/gtkenums.h b/gtk/gtkenums.h
index 85c8c56..99a52cf 100644
--- a/gtk/gtkenums.h
+++ b/gtk/gtkenums.h
@@ -618,6 +618,12 @@ typedef enum {
   GTK_JUNCTION_RIGHT  = 1 << 3
 } GtkJunctionSides;
 
+typedef enum {
+  GTK_BORDER_STYLE_NONE,
+  GTK_BORDER_STYLE_SOLID,
+  GTK_BORDER_STYLE_INSET,
+  GTK_BORDER_STYLE_OUTSET
+} GtkBorderStyle;
 
 G_END_DECLS
 
diff --git a/gtk/gtkstyleset.c b/gtk/gtkstyleset.c
index 9aa5519..a53a75c 100644
--- a/gtk/gtkstyleset.c
+++ b/gtk/gtkstyleset.c
@@ -23,6 +23,7 @@
 #include <gobject/gvaluecollector.h>
 #include <cairo/cairo-gobject.h>
 
+#include "gtktypebuiltins.h"
 #include "gtkstyleprovider.h"
 #include "gtkstyleset.h"
 #include "gtkprivate.h"
@@ -92,6 +93,8 @@ gtk_style_set_class_init (GtkStyleSetClass *klass)
 
   gtk_style_set_register_property ("border-width", G_TYPE_INT, NULL, NULL);
   gtk_style_set_register_property ("border-radius", G_TYPE_INT, NULL, NULL);
+  gtk_style_set_register_property ("border-style", GTK_TYPE_BORDER_STYLE, NULL, NULL);
+  gtk_style_set_register_property ("border-color", GDK_TYPE_COLOR, NULL, NULL);
 
   gtk_style_set_register_property ("background-image", CAIRO_GOBJECT_TYPE_PATTERN, NULL, NULL);
   gtk_style_set_register_property ("border-image", GTK_TYPE_9SLICE, NULL, NULL);
diff --git a/gtk/gtkthemingengine.c b/gtk/gtkthemingengine.c
index f91f1c3..b7e101b 100644
--- a/gtk/gtkthemingengine.c
+++ b/gtk/gtkthemingengine.c
@@ -52,7 +52,8 @@ enum {
   SIDE_LEFT   = 1,
   SIDE_BOTTOM = 1 << 1,
   SIDE_RIGHT  = 1 << 2,
-  SIDE_TOP    = 1 << 3
+  SIDE_TOP    = 1 << 3,
+  SIDE_ALL    = 0xF
 };
 
 struct GtkThemingEnginePrivate
@@ -1139,25 +1140,97 @@ color_shade (const GdkColor *color,
 }
 
 static void
-_cairo_round_rectangle (cairo_t *cr,
-                        gdouble  radius,
-                        gdouble  x,
-                        gdouble  y,
-                        gdouble  width,
-                        gdouble  height)
+_cairo_round_rectangle_sides (cairo_t          *cr,
+                              gdouble           radius,
+                              gdouble           x,
+                              gdouble           y,
+                              gdouble           width,
+                              gdouble           height,
+                              guint             sides,
+                              GtkJunctionSides  junction)
 {
   radius = CLAMP (radius, 0, MIN (width / 2, height / 2));
 
-  if (radius == 0)
-    cairo_rectangle (cr, x, y, width, height);
+  if (sides & SIDE_RIGHT)
+    {
+      if (radius == 0 ||
+          (junction & GTK_JUNCTION_TOP) ||
+          (junction & GTK_JUNCTION_RIGHT))
+        cairo_move_to (cr, x + width, y);
+      else
+        {
+          cairo_new_sub_path (cr);
+          cairo_arc (cr, x + width - radius, y + radius, radius, - G_PI / 4, 0);
+        }
+
+      if (radius == 0 ||
+          (junction & GTK_JUNCTION_BOTTOM) ||
+          (junction & GTK_JUNCTION_RIGHT))
+        cairo_line_to (cr, x + width, y + height);
+      else
+        cairo_arc (cr, x + width - radius, y + height - radius, radius, 0, G_PI / 4);
+    }
+
+  if (sides & SIDE_BOTTOM)
+    {
+      if (radius != 0 &&
+          ! (junction & GTK_JUNCTION_RIGHT) &&
+          ! (junction & GTK_JUNCTION_BOTTOM))
+        {
+          if ((sides & SIDE_RIGHT) == 0)
+            cairo_new_sub_path (cr);
+
+          cairo_arc (cr, x + width - radius, y + height - radius, radius, G_PI / 4, G_PI / 2);
+        }
+
+      if (radius == 0 ||
+          (junction & GTK_JUNCTION_BOTTOM) ||
+          (junction & GTK_JUNCTION_LEFT))
+        cairo_line_to (cr, x, y + height);
+      else
+        cairo_arc (cr, x + radius, y + height - radius, radius, G_PI / 2, 3 * (G_PI / 4));
+    }
   else
+    cairo_move_to (cr, x, y + height);
+
+  if (sides & SIDE_LEFT)
+    {
+      if (radius != 0 &&
+          ! (junction & GTK_JUNCTION_LEFT) &&
+          ! (junction & GTK_JUNCTION_BOTTOM))
+        {
+          if ((sides & SIDE_BOTTOM) == 0)
+            cairo_new_sub_path (cr);
+
+          cairo_arc (cr, x + radius, y + height - radius, radius, 3 * (G_PI / 4), G_PI);
+        }
+
+      if (radius == 0 ||
+          (junction & GTK_JUNCTION_TOP) ||
+          (junction & GTK_JUNCTION_LEFT))
+        cairo_line_to (cr, x, y);
+      else
+        cairo_arc (cr, x + radius, y + radius, radius, G_PI, G_PI + G_PI / 4);
+    }
+
+  if (sides & SIDE_TOP)
     {
-      cairo_new_sub_path (cr);
-      cairo_arc (cr, x + width - radius, y + radius, radius, - G_PI / 2, 0);
-      cairo_arc (cr, x + width - radius, y + height - radius, radius, 0, G_PI / 2);
-      cairo_arc (cr, x + radius, y + height - radius, radius, G_PI / 2, G_PI);
-      cairo_arc (cr, x + radius, y + radius, radius, G_PI, 3 * (G_PI / 2));
-      cairo_close_path (cr);
+      if (radius != 0 &&
+          ! (junction & GTK_JUNCTION_TOP) &&
+          ! (junction & GTK_JUNCTION_LEFT))
+        {
+          if ((sides & SIDE_TOP) == 0)
+            cairo_new_sub_path (cr);
+
+          cairo_arc (cr, x + radius, y + radius, radius, 5 * (G_PI / 4), 3 * (G_PI / 2));
+        }
+
+      if (radius == 0 ||
+          (junction & GTK_JUNCTION_TOP) ||
+          (junction & GTK_JUNCTION_RIGHT))
+        cairo_line_to (cr, x + width, y);
+      else
+        cairo_arc (cr, x + width - radius, y + radius, radius, 3 * (G_PI / 2), - G_PI / 4);
     }
 }
 
@@ -1174,9 +1247,11 @@ gtk_theming_engine_render_background (GtkThemingEngine *engine,
   GtkStateFlags flags;
   gboolean running;
   gdouble progress, alpha = 1;
+  GtkJunctionSides junction;
   gint radius;
 
   flags = gtk_theming_engine_get_state (engine);
+  junction = gtk_theming_engine_get_junction_sides (engine);
   cairo_save (cr);
 
   if (gtk_theming_engine_has_class (engine, "spinbutton") &&
@@ -1197,7 +1272,9 @@ gtk_theming_engine_render_background (GtkThemingEngine *engine,
 
   running = gtk_theming_engine_state_is_running (engine, GTK_STATE_PRELIGHT, &progress);
 
-  _cairo_round_rectangle (cr, (gdouble) radius, x, y, width, height);
+  _cairo_round_rectangle_sides (cr, (gdouble) radius,
+                                x, y, width, height,
+                                SIDE_ALL, junction);
   cairo_clip (cr);
 
   cairo_translate (cr, x, y);
@@ -1448,163 +1525,98 @@ gtk_theming_engine_render_frame (GtkThemingEngine *engine,
 {
   GtkStateFlags flags;
   GdkColor lighter, darker;
-  GdkColor *bg_color;
+  GdkColor *border_color;
   Gtk9Slice *slice;
+  GtkBorderStyle border_style;
+  gint border_width, radius;
+  GtkJunctionSides junction;
 
   flags = gtk_theming_engine_get_state (engine);
+  junction = gtk_theming_engine_get_junction_sides (engine);
 
   gtk_theming_engine_get (engine, flags,
                           "border-image", &slice,
-                          "background-color", &bg_color,
+                          "border-color", &border_color,
+                          "border-style", &border_style,
+                          "border-width", &border_width,
+                          "border-radius", &radius,
                           NULL);
 
   if (slice)
     {
       gtk_9slice_render (slice, cr, x, y, width, height);
       gtk_9slice_unref (slice);
-      gdk_color_free (bg_color);
-      return;
     }
-
-  cairo_save (cr);
-  cairo_set_line_width (cr, 1);
-
-  color_shade (bg_color, 0.7, &darker);
-  color_shade (bg_color, 1.3, &lighter);
-
-  if (gtk_theming_engine_has_class (engine, "entry") ||
-      gtk_theming_engine_has_class (engine, "scrolled-window") ||
-      gtk_theming_engine_has_class (engine, "viewport"))
+  else if (border_style != GTK_BORDER_STYLE_NONE)
     {
-      gdk_cairo_set_source_color (cr, bg_color);
-      add_path_rectangle_sides (cr, x + 1, y + 1, width - 2, height - 2,
-                                SIDE_BOTTOM | SIDE_RIGHT);
-      cairo_stroke (cr);
-
-      cairo_set_source_rgb (cr, 0, 0, 0);
-      add_path_rectangle_sides (cr, x + 1, y + 1, width - 2, height - 2,
-                                SIDE_TOP | SIDE_LEFT);
-      cairo_stroke (cr);
-
-      cairo_set_source_rgb (cr, 1, 1, 1);
-      add_path_rectangle_sides (cr, x, y, width, height,
-                                SIDE_BOTTOM | SIDE_RIGHT);
-      cairo_stroke (cr);
+      cairo_save (cr);
 
-      gdk_cairo_set_source_color (cr, &darker);
-      add_path_rectangle_sides (cr, x, y, width, height,
-                                SIDE_TOP | SIDE_LEFT);
-      cairo_stroke (cr);
-    }
-  else if (gtk_theming_engine_has_class (engine, "button") &&
-           gtk_theming_engine_has_class (engine, "default"))
-    {
-      cairo_set_source_rgb (cr, 0, 0, 0);
-      cairo_rectangle (cr, x + 0.5, x + 0.5, width - 1, height - 1);
-      cairo_stroke (cr);
-    }
-  else if (gtk_theming_engine_has_class (engine, "scrollbar") &&
-           gtk_theming_engine_has_class (engine, "trough"))
-    {
-      gdk_cairo_set_source_color (cr, &darker);
-      add_path_rectangle_sides (cr, x, y, width, height,
-                                SIDE_TOP | SIDE_LEFT);
-      cairo_stroke (cr);
+      color_shade (border_color, 0.7, &darker);
+      color_shade (border_color, 1.3, &lighter);
 
-      gdk_cairo_set_source_color (cr, &lighter);
-      add_path_rectangle_sides (cr, x, y, width, height,
-                                SIDE_BOTTOM | SIDE_RIGHT);
-      cairo_stroke (cr);
-    }
-  else if (gtk_theming_engine_has_class (engine, "spinbutton"))
-    {
-      if (gtk_theming_engine_has_class (engine, "button"))
+      switch (border_style)
         {
-          GtkJunctionSides sides;
-
-          sides = gtk_theming_engine_get_junction_sides (engine);
+        case GTK_BORDER_STYLE_NONE:
+          break;
+        case GTK_BORDER_STYLE_SOLID:
+          cairo_set_line_width (cr, border_width);
 
-          if (sides & GTK_JUNCTION_BOTTOM)
-            y += 2;
-
-          width -= 3;
-          height -= 2;
-
-          if (gtk_theming_engine_get_direction (engine) == GTK_TEXT_DIR_RTL)
-            x += 2;
-          else
-            x += 1;
+          if (border_width > 1)
+            {
+              x += (gdouble) border_width / 2;
+              y += (gdouble) border_width / 2;
+              width -= border_width;
+              height -= border_width;
+            }
 
-          gdk_cairo_set_source_color (cr, &lighter);
-          add_path_rectangle_sides (cr, x, y, width, height, SIDE_TOP);
+          _cairo_round_rectangle_sides (cr, (gdouble) radius, x, y, width, height,
+                                        SIDE_ALL, junction);
+          gdk_cairo_set_source_color (cr, border_color);
           cairo_stroke (cr);
 
-          gdk_cairo_set_source_color (cr, &darker);
-          add_path_rectangle_sides (cr, x, y, width, height, SIDE_BOTTOM);
-          cairo_stroke (cr);
-        }
-      else
-        {
-          gdk_cairo_set_source_color (cr, &lighter);
-          add_path_rectangle_sides (cr, x, y, width, height,
-                                    SIDE_BOTTOM | SIDE_RIGHT);
-          cairo_stroke (cr);
+          break;
+        case GTK_BORDER_STYLE_INSET:
+        case GTK_BORDER_STYLE_OUTSET:
+          cairo_set_line_width (cr, border_width);
+          cairo_set_line_cap (cr, CAIRO_LINE_CAP_SQUARE);
 
-          gdk_cairo_set_source_color (cr, &darker);
-          add_path_rectangle_sides (cr, x, y, width, height, SIDE_TOP);
-          cairo_stroke (cr);
+          if (border_width > 1)
+            {
+              gint d;
 
-          gdk_cairo_set_source_color (cr, bg_color);
-          add_path_rectangle_sides (cr, x, y, width - 1, height - 1, SIDE_BOTTOM);
-          cairo_stroke (cr);
+              d = border_width / 2;
+              x += d;
+              y += d;
+              width -= d * 2;
+              height -= d * 2;
+            }
 
-          cairo_set_source_rgb (cr, 0, 0, 0);
-          add_path_rectangle_sides (cr, x, y + 1, width - 1, height - 3,
-                                    SIDE_TOP | SIDE_LEFT | SIDE_RIGHT);
-          cairo_stroke (cr);
-        }
-    }
-  else
-    {
-      if (flags & GTK_STATE_FLAG_ACTIVE)
-        {
-          cairo_set_source_rgb (cr, 0, 0, 0);
-          add_path_rectangle_sides (cr, x + 1, y + 1, width - 2, height - 2,
-                                    SIDE_TOP | SIDE_LEFT);
-          cairo_stroke (cr);
+          if (border_style == GTK_BORDER_STYLE_INSET)
+            gdk_cairo_set_source_color (cr, border_color);
+          else
+            gdk_cairo_set_source_color (cr, &darker);
 
-          gdk_cairo_set_source_color (cr, &lighter);
-          add_path_rectangle_sides (cr, x, y, width, height,
-                                    SIDE_BOTTOM | SIDE_RIGHT);
+          _cairo_round_rectangle_sides (cr, (gdouble) radius, x, y, width, height,
+                                        SIDE_BOTTOM | SIDE_RIGHT, junction);
           cairo_stroke (cr);
 
-          gdk_cairo_set_source_color (cr, &darker);
-          add_path_rectangle_sides (cr, x, y, width, height,
-                                    SIDE_TOP | SIDE_LEFT);
-          cairo_stroke (cr);
-        }
-      else
-        {
-          gdk_cairo_set_source_color (cr, &darker);
-          add_path_rectangle_sides (cr, x, y, width - 1, height - 1,
-                                    SIDE_BOTTOM | SIDE_RIGHT);
-          cairo_stroke (cr);
+          if (border_style == GTK_BORDER_STYLE_INSET)
+            gdk_cairo_set_source_color (cr, &darker);
+          else
+            gdk_cairo_set_source_color (cr, border_color);
 
-          gdk_cairo_set_source_color (cr, &lighter);
-          add_path_rectangle_sides (cr, x, y, width, height,
-                                    SIDE_TOP | SIDE_LEFT);
+          _cairo_round_rectangle_sides (cr, (gdouble) radius, x, y, width, height,
+                                        SIDE_TOP | SIDE_LEFT, junction);
           cairo_stroke (cr);
 
-          cairo_set_source_rgb (cr, 0, 0, 0);
-          add_path_rectangle_sides (cr, x, y, width, height,
-                                    SIDE_BOTTOM | SIDE_RIGHT);
-          cairo_stroke (cr);
+          break;
         }
-    }
 
-  cairo_restore (cr);
+      cairo_restore (cr);
+    }
 
-  gdk_color_free (bg_color);
+  if (border_color)
+    gdk_color_free (border_color);
 }
 
 static void



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