[gtk-theme-engine-clearlooks] Make gradients tweakable



commit f288a75420797176b1551e9120d2619de436a511
Author: Matthias Clasen <mclasen redhat com>
Date:   Sun Nov 7 09:24:32 2010 -0500

    Make gradients tweakable
    
    Instead of hardcoded gradients for toolbars and menubars, allow to
    specify horizontal and vertical gradients in the rc file, like this:
    
    horizontal_gradient {
      stop <offset1> <color1>
      stop <offset2> <color2>
      ...
    }
    
    and similar for vertical gradients. We also use gradients for buttons.

 src/clearlooks_draw_gnome3.c |   83 ++++++++++++++++++++++--------------------
 src/clearlooks_rc_style.c    |   76 ++++++++++++++++++++++++++++++++++++++-
 src/clearlooks_rc_style.h    |    6 ++-
 src/clearlooks_style.c       |    6 +++
 src/clearlooks_types.h       |    9 +++++
 5 files changed, 137 insertions(+), 43 deletions(-)
---
diff --git a/src/clearlooks_draw_gnome3.c b/src/clearlooks_draw_gnome3.c
index 8f44467..90eeb72 100644
--- a/src/clearlooks_draw_gnome3.c
+++ b/src/clearlooks_draw_gnome3.c
@@ -94,6 +94,35 @@ clearlooks_gnome3_draw_entry (cairo_t *cr,
 }
 
 static void
+draw_gradient (cairo_t       *cr,
+               ClearlooksGradient *gradient,
+               int x, int y, int width, int height)
+{
+        cairo_pattern_t *pattern;
+        gint i;
+
+        if (gradient->horizontal)
+                pattern = cairo_pattern_create_linear (x, y, x + width, y);
+        else
+                pattern = cairo_pattern_create_linear (x, y, x, y + height);
+
+        for (i = 0; i < gradient->n_stops; i++) {
+                gdouble offset;
+                CairoColor c;
+                offset = gradient->positions[i];
+                ge_gdk_color_to_cairo (&gradient->colors[i], &c);
+                cairo_pattern_add_color_stop_rgba (pattern, offset,
+                c.r, c.g, c.b, c.a);
+        }
+
+        cairo_set_source (cr, pattern);
+        cairo_rectangle (cr, x, y, width, height);
+        cairo_fill (cr);
+
+        cairo_pattern_destroy (pattern);
+}
+
+static void
 clearlooks_gnome3_draw_button (cairo_t *cr,
                         const ClearlooksColors *colors,
                         const WidgetParameters *params,
@@ -133,6 +162,7 @@ clearlooks_gnome3_draw_button (cairo_t *cr,
 	cairo_stroke (cr);
 
 	ge_cairo_inner_rounded_rectangle (cr, x + 1, y + 1, width - 2, height - 2, MAX(0, params->radius - 1), params->corners);
+
 	pattern = cairo_pattern_create_linear (x, y + 2, x, y + height - 4);
 	ge_cairo_pattern_add_color_stop_color (pattern, 0.0, &stroke_top_color);
 	ge_cairo_pattern_add_color_stop_color (pattern, 1.0, &stroke_bottom_color);
@@ -141,12 +171,9 @@ clearlooks_gnome3_draw_button (cairo_t *cr,
 	cairo_stroke (cr);
 
 	ge_cairo_rounded_rectangle (cr, x + 2, y + 2, width - 4, height - 4, MAX(0, params->radius - 2), params->corners);
-	pattern = cairo_pattern_create_linear (x, y + 3, x, y + height - 6);
-	ge_cairo_pattern_add_color_stop_color (pattern, 0.0, &fill_top_color);
-	ge_cairo_pattern_add_color_stop_color (pattern, 1.0, &fill_bottom_color);
-	cairo_set_source (cr, pattern);
-	cairo_pattern_destroy (pattern);
-	cairo_fill (cr);
+        if (colors->gradient) {
+                draw_gradient (cr, colors->gradient, x, y, width, height);
+        }
 
 	cairo_restore (cr);
 }
@@ -207,25 +234,11 @@ clearlooks_gnome3_draw_menubar (cairo_t *cr,
                                 const MenuBarParameters *menubar,
                                 int x, int y, int width, int height)
 {
-	CairoColor bg_top;
-	CairoColor bg_bottom;
-	cairo_pattern_t *pattern;
-
-	cairo_save (cr);
-	bg_bottom = colors->bg[GTK_STATE_NORMAL];
-	ge_shade_color (&colors->bg[GTK_STATE_NORMAL], 0.973, &bg_top);
-	pattern = cairo_pattern_create_linear (x, y + height * 0.2, x, y + height - 1.0);
-
-	ge_cairo_pattern_add_color_stop_color (pattern, 0.0, &bg_top);
-	ge_cairo_pattern_add_color_stop_color (pattern, 1.0, &bg_bottom);
-
-	cairo_set_source (cr, pattern);
-	cairo_pattern_destroy (pattern);
-
-	cairo_rectangle (cr, x, y, width, height);
-	cairo_fill (cr);
-
-	cairo_restore (cr);
+        cairo_save (cr);
+        if (colors->gradient) {
+                draw_gradient (cr, colors->gradient, x, y, width, height);
+        }
+        cairo_restore (cr);
 }
 
 static void
@@ -376,21 +389,11 @@ clearlooks_gnome3_draw_toolbar (cairo_t *cr,
                          const ToolbarParameters         *toolbar,
                          int x, int y, int width, int height)
 {
-	CairoColor top_bg = colors->bg[GTK_STATE_ACTIVE];
-	CairoColor bottom_bg = colors->bg[GTK_STATE_NORMAL];
-	cairo_pattern_t *pattern;
-
-	pattern = cairo_pattern_create_linear (x, y, x, y + height * 0.75);
-
-	ge_mix_color (&bottom_bg, &top_bg, 0.31, &bottom_bg);
-	ge_cairo_pattern_add_color_stop_color (pattern, 0.0, &top_bg);
-	ge_cairo_pattern_add_color_stop_color (pattern, 1.0, &bottom_bg);
-
-	cairo_set_source (cr, pattern);
-	cairo_rectangle (cr, x, y, width, height);
-	cairo_fill (cr);
-
-	cairo_pattern_destroy (pattern);
+        cairo_save (cr);
+        if (colors->gradient) {
+                draw_gradient (cr, colors->gradient, x, y, width, height);
+        }
+        cairo_restore (cr);
 }
 
 static void
diff --git a/src/clearlooks_rc_style.c b/src/clearlooks_rc_style.c
index 34c3120..2355d62 100644
--- a/src/clearlooks_rc_style.c
+++ b/src/clearlooks_rc_style.c
@@ -74,6 +74,10 @@ enum
 	TOKEN_TRUE,
 	TOKEN_FALSE,
 
+        TOKEN_HORIZONTAL_GRADIENT,
+        TOKEN_VERTICAL_GRADIENT,
+        TOKEN_STOP,
+
 	TOKEN_LAST
 };
 
@@ -103,7 +107,10 @@ static gchar* clearlooks_rc_symbols =
 	"GNOME3\0"
 
 	"TRUE\0"
-	"FALSE\0";
+	"FALSE\0"
+        "horizontal_gradient\0"
+        "vertical_gradient\0"
+        "stop\0";
 
 G_DEFINE_DYNAMIC_TYPE (ClearlooksRcStyle, clearlooks_rc_style, GTK_TYPE_RC_STYLE)
 
@@ -255,6 +262,65 @@ clearlooks_gtk2_rc_parse_int (GtkSettings  *settings,
 }
 
 static guint
+clearlooks_gtk2_rc_parse_color_stop (GtkSettings        *settings,
+                                     GScanner           *scanner,
+                                     GtkRcStyle         *style,
+                                     ClearlooksGradient *gradient)
+{
+        guint token;
+        gint n;
+
+        n = gradient->n_stops;
+
+        gradient->n_stops++;
+        gradient->positions = g_renew (gdouble, gradient->positions, gradient->n_stops);
+        gradient->colors = g_renew (GdkColor, gradient->colors, gradient->n_stops);
+
+        /* eat 'stop' */
+        token = g_scanner_get_next_token (scanner);
+
+        token = g_scanner_get_next_token (scanner);
+        if (token != G_TOKEN_FLOAT)
+                return G_TOKEN_FLOAT;
+        gradient->positions[n] = scanner->value.v_float;
+
+        return gtk_rc_parse_color_full (scanner, style, &gradient->colors[n]);
+}
+
+static guint
+clearlooks_gtk2_rc_parse_gradient (GtkSettings        *settings,
+                                   GScanner           *scanner,
+                                   GtkRcStyle         *style,
+                                   ClearlooksGradient *gradient)
+{
+        guint token;
+
+        /* skip */
+        token = g_scanner_get_next_token(scanner);
+        if (token == TOKEN_HORIZONTAL_GRADIENT)
+                gradient->horizontal = TRUE;
+        else
+                gradient->horizontal = FALSE;
+
+        token = g_scanner_get_next_token (scanner);
+
+        if (token != G_TOKEN_LEFT_CURLY)
+               return G_TOKEN_LEFT_CURLY;
+
+        do {
+                token = clearlooks_gtk2_rc_parse_color_stop (settings,scanner, style, gradient);
+                if (token != G_TOKEN_NONE)
+                        return token;
+        } while (g_scanner_peek_next_token (scanner) != G_TOKEN_RIGHT_CURLY);
+
+        token = g_scanner_get_next_token (scanner);
+        if (token != G_TOKEN_RIGHT_CURLY)
+               return G_TOKEN_RIGHT_CURLY;
+
+        return G_TOKEN_NONE;
+}
+
+static guint
 clearlooks_gtk2_rc_parse_style (GtkSettings      *settings,
                                 GScanner         *scanner,
                                 ClearlooksStyles *style)
@@ -433,6 +499,12 @@ clearlooks_rc_style_parse (GtkRcStyle *rc_style,
 				token = clearlooks_gtk2_rc_parse_dummy (settings, scanner, "listviewitemstyle");
 				break;
 
+                        case TOKEN_HORIZONTAL_GRADIENT:
+                        case TOKEN_VERTICAL_GRADIENT:
+                                token = clearlooks_gtk2_rc_parse_gradient (settings, scanner, rc_style, &clearlooks_style->gradient);
+				clearlooks_style->flags |= CL_FLAG_GRADIENT;
+                                break;
+
 			default:
 				g_scanner_get_next_token(scanner);
 				token = G_TOKEN_RIGHT_CURLY;
@@ -495,6 +567,8 @@ clearlooks_rc_style_merge (GtkRcStyle *dest,
 		dest_w->disable_focus = src_w->disable_focus;
 	if (flags & CL_FLAG_ACCEL_LABEL_SHADE)
 		dest_w->accel_label_shade = src_w->accel_label_shade;
+	if (flags & CL_FLAG_GRADIENT)
+		dest_w->gradient = src_w->gradient;
 
 	dest_w->flags |= src_w->flags;
 }
diff --git a/src/clearlooks_rc_style.h b/src/clearlooks_rc_style.h
index d6911c2..5e1c3b1 100644
--- a/src/clearlooks_rc_style.h
+++ b/src/clearlooks_rc_style.h
@@ -56,10 +56,10 @@ typedef enum {
 	CL_FLAG_RADIUS             = 1 <<  9,
 	CL_FLAG_HINT               = 1 <<  10,
 	CL_FLAG_DISABLE_FOCUS      = 1 <<  11,
-	CL_FLAG_ACCEL_LABEL_SHADE  = 1 <<  12
+	CL_FLAG_ACCEL_LABEL_SHADE  = 1 <<  12,
+	CL_FLAG_GRADIENT           = 1 <<  13
 } ClearlooksRcFlags;
 
-
 struct _ClearlooksRcStyle
 {
 	GtkRcStyle parent_instance;
@@ -80,8 +80,10 @@ struct _ClearlooksRcStyle
 	GQuark hint;
 	gboolean disable_focus;
 	double accel_label_shade;
+        ClearlooksGradient gradient;
 };
 
+
 struct _ClearlooksRcStyleClass
 {
 	GtkRcStyleClass parent_class;
diff --git a/src/clearlooks_style.c b/src/clearlooks_style.c
index cb1a585..d796102 100644
--- a/src/clearlooks_style.c
+++ b/src/clearlooks_style.c
@@ -1415,6 +1415,12 @@ clearlooks_style_realize (GtkStyle * style)
 		ge_gdk_color_to_cairo (&style->base[i], &clearlooks_style->colors.base[i]);
 		ge_gdk_color_to_cairo (&style->text[i], &clearlooks_style->colors.text[i]);
 	}
+
+        if (CLEARLOOKS_RC_STYLE (style->rc_style)->flags & CL_FLAG_GRADIENT)
+                clearlooks_style->colors.gradient =
+                        & (CLEARLOOKS_RC_STYLE (style->rc_style)->gradient);
+        else
+                clearlooks_style->colors.gradient = NULL;
 }
 
 static void
diff --git a/src/clearlooks_types.h b/src/clearlooks_types.h
index affb505..c97ca44 100644
--- a/src/clearlooks_types.h
+++ b/src/clearlooks_types.h
@@ -161,6 +161,14 @@ typedef struct
 
 typedef struct
 {
+        gboolean horizontal;
+        gint n_stops;
+        double *positions;
+        GdkColor *colors;
+} ClearlooksGradient;
+
+typedef struct
+{
 	CairoColor fg[5];
 	CairoColor bg[5];
 	CairoColor base[5];
@@ -168,6 +176,7 @@ typedef struct
 	
 	CairoColor shade[9];
 	CairoColor spot[3];
+        ClearlooksGradient *gradient;
 } ClearlooksColors;
 
 typedef struct



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