1 /* Clearlooks - a cairo based GTK+ engine
2  * Copyright (C) 2007-2008 Andrea Cimitan <andrea.cimitan@gmail.com>
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
17  *
18  * Project contact: <gnome-themes-list@gnome.org>
19  *
20  *
21  * This file defines the Clearlooks Gummy style
22  *
23  */
24 
25 
26 #include "clearlooks_draw.h"
27 #include "clearlooks_style.h"
28 #include "clearlooks_types.h"
29 
30 #include "support.h"
31 #include <ge-support.h>
32 
33 #include <cairo.h>
34 
35 /* Normal shadings */
36 #define SHADE_TOP 1.08
37 #define SHADE_CENTER_TOP 1.02
38 #define SHADE_BOTTOM 0.94
39 
40 /* Listview */
41 #define LISTVIEW_SHADE_TOP 1.06
42 #define LISTVIEW_SHADE_CENTER_TOP 1.02
43 #define LISTVIEW_SHADE_BOTTOM 0.96
44 
45 /* Toolbar */
46 #define TOOLBAR_SHADE_TOP 1.04
47 #define TOOLBAR_SHADE_CENTER_TOP 1.01
48 #define TOOLBAR_SHADE_BOTTOM 0.97
49 
50 static void
clearlooks_draw_gummy_gradient(cairo_t * cr,double x,double y,int width,int height,const CairoColor * color,gboolean disabled,gboolean radius,CairoCorners corners)51 clearlooks_draw_gummy_gradient (cairo_t          *cr,
52                                 double x, double y, int width, int height,
53                                 const CairoColor *color,
54                                 gboolean disabled, gboolean radius, CairoCorners corners)
55 {
56 	CairoColor fill;
57 	CairoColor shade1, shade2, shade3;
58 	cairo_pattern_t *pt;
59 
60 	ge_shade_color (color, disabled? 1.04 : SHADE_TOP, &shade1);
61 	ge_shade_color (color, disabled? 1.01 : SHADE_CENTER_TOP, &shade2);
62 	ge_shade_color (color, disabled? 0.99 : 1.0, &fill);
63 	ge_shade_color (color, disabled? 0.96 : SHADE_BOTTOM, &shade3);
64 
65 	pt = cairo_pattern_create_linear (x, y, x, y+height);
66 	cairo_pattern_add_color_stop_rgb (pt, 0.0, shade1.r, shade1.g, shade1.b);
67 	cairo_pattern_add_color_stop_rgb (pt, 0.5, shade2.r, shade2.g, shade2.b);
68 	cairo_pattern_add_color_stop_rgb (pt, 0.5, fill.r, fill.g, fill.b);
69 	cairo_pattern_add_color_stop_rgb (pt, 1.0, shade3.r, shade3.g, shade3.b);
70 
71 	cairo_set_source (cr, pt);
72 	ge_cairo_rounded_rectangle (cr, x, y, width, height, radius, corners);
73 	cairo_fill (cr);
74 
75 	cairo_pattern_destroy (pt);
76 }
77 
78 static void
clearlooks_gummy_draw_highlight_and_shade(cairo_t * cr,const CairoColor * bg_color,const ShadowParameters * params,int width,int height,gdouble radius)79 clearlooks_gummy_draw_highlight_and_shade (cairo_t                *cr,
80                                            const CairoColor       *bg_color,
81                                            const ShadowParameters *params,
82                                            int width, int height, gdouble radius)
83 {
84 	CairoColor shadow;
85 	CairoColor highlight;
86 	uint8 corners = params->corners;
87 	double x = 1.0;
88 	double y = 1.0;
89 
90 	/* not really sure of shading ratios... we will think */
91 	ge_shade_color (bg_color, 0.8, &shadow);
92 	ge_shade_color (bg_color, 1.2, &highlight);
93 
94 	cairo_save (cr);
95 
96 	/* Top/Left highlight */
97 	if (corners & CR_CORNER_BOTTOMLEFT)
98 		cairo_move_to (cr, x, y+height-radius);
99 	else
100 		cairo_move_to (cr, x, y+height);
101 
102 	ge_cairo_rounded_corner (cr, x, y, radius, corners & CR_CORNER_TOPLEFT);
103 
104 	if (corners & CR_CORNER_TOPRIGHT)
105 		cairo_line_to (cr, x+width-radius, y);
106 	else
107 		cairo_line_to (cr, x+width, y);
108 
109 	if (params->shadow & CL_SHADOW_OUT)
110 		cairo_set_source_rgba (cr, highlight.r, highlight.g, highlight.b, 0.5);
111 	else
112 		cairo_set_source_rgba (cr, shadow.r, shadow.g, shadow.b, 0.5);
113 
114 	cairo_stroke (cr);
115 
116 	/* Bottom/Right highlight -- this includes the corners */
117 	cairo_move_to (cr, x+width-radius, y); /* topright and by radius to the left */
118 	ge_cairo_rounded_corner (cr, x+width, y, radius, corners & CR_CORNER_TOPRIGHT);
119 	ge_cairo_rounded_corner (cr, x+width, y+height, radius, corners & CR_CORNER_BOTTOMRIGHT);
120 	ge_cairo_rounded_corner (cr, x, y+height, radius, corners & CR_CORNER_BOTTOMLEFT);
121 
122 	if (params->shadow & CL_SHADOW_OUT)
123 		cairo_set_source_rgba (cr, shadow.r, shadow.g, shadow.b, 0.5);
124 	else
125 		cairo_set_source_rgba (cr, highlight.r, highlight.g, highlight.b, 0.5);
126 
127 	cairo_stroke (cr);
128 
129 	cairo_restore (cr);
130 }
131 
132 static void
clearlooks_gummy_draw_button(cairo_t * cr,const ClearlooksColors * colors,const WidgetParameters * params,int x,int y,int width,int height)133 clearlooks_gummy_draw_button (cairo_t                *cr,
134                               const ClearlooksColors *colors,
135                               const WidgetParameters *params,
136                               int x, int y, int width, int height)
137 {
138 	double xoffset = 0, yoffset = 0;
139 	CairoColor fill            = colors->bg[params->state_type];
140 	CairoColor border_normal   = colors->shade[6];
141 	CairoColor border_disabled = colors->shade[4];
142 	double radius;
143 
144 	cairo_pattern_t *pattern;
145 
146 	cairo_save (cr);
147 	cairo_translate (cr, x, y);
148 	cairo_set_line_width (cr, 1.0);
149 
150 	if (params->xthickness >= 3)
151 	{
152 		xoffset = 1;
153 		yoffset = 1;
154 	}
155 
156 	radius = MIN (params->radius, MIN ((width - 2.0 - 2*xoffset) / 2.0, (height - 2.0 - 2*yoffset) / 2.0));
157 
158 	if (params->xthickness >= 3 || params->ythickness >= 3)
159 	{
160 		if (params->enable_shadow && !params->active && !params->disabled && !params->is_default)
161 		{
162 			CairoColor shadow;
163 
164 			radius = MIN (params->radius, MIN ((width - 2.0 - 2*xoffset) / 2.0 - 1.0, (height - 2.0 - 2*yoffset) / 2.0 - 1.0));
165 
166 			ge_cairo_inner_rounded_rectangle (cr, 0, 0, width, height, radius+1, params->corners);
167 			ge_shade_color (&params->parentbg, 0.97, &shadow);
168 			ge_cairo_set_color (cr, &shadow);
169 			cairo_stroke (cr);
170 
171 			ge_cairo_inner_rounded_rectangle (cr, 1, 1, width-1, height-1, radius+1, params->corners);
172 			ge_shade_color (&params->parentbg, 0.93, &shadow);
173 			ge_cairo_set_color (cr, &shadow);
174 			cairo_stroke (cr);
175 		}
176 
177 		if (params->is_default && !params->disabled)
178 		{
179 			CairoColor shadow = colors->spot[1];
180 
181 			radius = MIN (params->radius, MIN ((width - 2.0 - 2*xoffset) / 2.0 - 1.0, (height - 2.0 - 2*yoffset) / 2.0 - 1.0));
182 
183 			ge_cairo_inner_rounded_rectangle (cr, 0, 0, width, height, radius+1, params->corners);
184 			clearlooks_set_mixed_color (cr, &params->parentbg, &shadow, 0.5);
185 			cairo_stroke (cr);
186 		}
187 
188 		if (!(params->enable_shadow && !params->active && !params->disabled))
189 			params->style_functions->draw_inset (cr, &params->parentbg, 0, 0, width, height, params->radius+1, params->corners);
190 	}
191 
192 	clearlooks_draw_gummy_gradient (cr, xoffset+1, yoffset+1,
193 	                                width-(xoffset*2)-2, height-(yoffset*2)-2,
194 	                                &fill, params->disabled, radius, params->corners);
195 
196 	/* Pressed button shadow */
197 	if (params->active)
198 	{
199 		CairoColor shadow;
200 		ge_shade_color (&fill, 0.92, &shadow);
201 
202 		cairo_save (cr);
203 
204 		ge_cairo_rounded_rectangle (cr, xoffset+1, yoffset+1, width-(xoffset*2)-2, height, radius,
205 		                            params->corners & (CR_CORNER_TOPLEFT | CR_CORNER_TOPRIGHT | CR_CORNER_BOTTOMLEFT));
206 		cairo_clip (cr);
207 		cairo_rectangle (cr, xoffset+1, yoffset+1, width-(xoffset*2)-2, 3);
208 
209 		pattern = cairo_pattern_create_linear (xoffset+1, yoffset+1, xoffset+1, yoffset+4);
210 		cairo_pattern_add_color_stop_rgba (pattern, 0.0, shadow.r, shadow.g, shadow.b, 0.58);
211 		cairo_pattern_add_color_stop_rgba (pattern, 1.0, shadow.r, shadow.g, shadow.b, 0.0);
212 		cairo_set_source (cr, pattern);
213 		cairo_fill (cr);
214 		cairo_pattern_destroy (pattern);
215 
216 		cairo_rectangle (cr, xoffset+1, yoffset+1, 3, height-(yoffset*2)-2);
217 
218 		pattern = cairo_pattern_create_linear (xoffset+1, yoffset+1, xoffset+4, yoffset+1);
219 		cairo_pattern_add_color_stop_rgba (pattern, 0.0, shadow.r, shadow.g, shadow.b, 0.58);
220 		cairo_pattern_add_color_stop_rgba (pattern, 1.0, shadow.r, shadow.g, shadow.b, 0.0);
221 		cairo_set_source (cr, pattern);
222 		cairo_fill (cr);
223 		cairo_pattern_destroy (pattern);
224 
225 		cairo_restore (cr);
226 	}
227 
228 	/* Border */
229 	if (params->is_default) /* || (params->prelight && params->enable_shadow)) */
230 		border_normal = colors->spot[2];
231 	if (params->disabled)
232 		ge_cairo_set_color (cr, &border_disabled);
233 	else
234 		clearlooks_set_mixed_color (cr, &border_normal, &fill, 0.2);
235 	ge_cairo_rounded_rectangle (cr, xoffset + 0.5, yoffset + 0.5,
236 	                            width-(xoffset*2)-1, height-(yoffset*2)-1,
237 	                            radius, params->corners);
238 	cairo_stroke (cr);
239 
240 	if (!params->active)
241 	{
242 		params->style_functions->draw_top_left_highlight (cr, &fill, params, 1+xoffset, 1+xoffset,
243 		                                                  width-(1+xoffset)*2, height-(1+xoffset)*2,
244 		                                                  radius, params->corners);
245 	}
246 	cairo_restore (cr);
247 }
248 
249 static void
clearlooks_gummy_draw_entry(cairo_t * cr,const ClearlooksColors * colors,const WidgetParameters * params,const FocusParameters * focus,int x,int y,int width,int height)250 clearlooks_gummy_draw_entry (cairo_t                *cr,
251                              const ClearlooksColors *colors,
252                              const WidgetParameters *params,
253                              const FocusParameters  *focus,
254                              int x, int y, int width, int height)
255 {
256 	const CairoColor *base = &colors->base[params->state_type];
257 	CairoColor border = colors->shade[params->disabled ? 4 : 6];
258 	double radius = MIN (params->radius, MIN ((width - 4.0) / 2.0, (height - 4.0) / 2.0));
259 	int xoffset, yoffset;
260 
261 	if (params->focus)
262 		border = focus->color;
263 
264 	cairo_save (cr);
265 
266 	cairo_translate (cr, x, y);
267 	cairo_set_line_width (cr, 1.0);
268 
269 	if (params->xthickness >= 3 && params->ythickness >= 3)
270 	{
271 		params->style_functions->draw_inset (cr, &params->parentbg, 0, 0, width, height, radius+1, params->corners);
272 		xoffset = 1;
273 		yoffset = 1;
274 	}
275 	else
276 	{
277 		xoffset = 0;
278 		yoffset = 0;
279 	}
280 
281 	/* Now fill the area we want to be base[NORMAL]. */
282 	ge_cairo_rounded_rectangle (cr, xoffset + 1, yoffset + 1,
283 	                            width-2*(xoffset + 1), height-2*(yoffset + 1),
284 	                            MAX(0, radius-1), params->corners);
285 	ge_cairo_set_color (cr, base);
286 	cairo_fill (cr);
287 
288 	/* Draw the inner shadow */
289 	if (params->focus)
290 	{
291 		CairoColor focus_shadow;
292 		ge_shade_color (&border, 1.61, &focus_shadow);
293 
294 		clearlooks_set_mixed_color (cr, base, &focus_shadow, 0.5);
295 		ge_cairo_inner_rounded_rectangle (cr, xoffset + 1, yoffset + 1,
296 		                                  width-2*(xoffset + 1), height-2*(yoffset + 1),
297 		                                  MAX(0, radius-1), params->corners);
298 		cairo_stroke (cr);
299 	}
300 	else
301 	{
302 		CairoColor shadow;
303 		ge_shade_color (&border, 0.92, &shadow);
304 
305 		cairo_set_source_rgba (cr, shadow.r, shadow.g, shadow.b, params->disabled ? 0.09 : 0.18);
306 
307 		cairo_set_line_cap (cr, CAIRO_LINE_CAP_BUTT);
308 		cairo_move_to (cr, xoffset + 1.5, height-radius);
309 		cairo_arc (cr, xoffset + 1.5 + MAX(0, radius-1), yoffset + 1.5 + MAX(0, radius-1),
310 		           MAX(0, radius-1), G_PI, 270*(G_PI/180));
311 		cairo_line_to (cr, width-radius, yoffset + 1.5);
312 		cairo_stroke (cr);
313 	}
314 
315 	ge_cairo_inner_rounded_rectangle (cr, xoffset, yoffset, width-2*xoffset, height-2*yoffset, radius, params->corners);
316 	ge_cairo_set_color (cr, &border);
317 	cairo_stroke (cr);
318 
319 	cairo_restore (cr);
320 }
321 
322 static void
clearlooks_gummy_draw_progressbar_trough(cairo_t * cr,const ClearlooksColors * colors,const WidgetParameters * params,int x,int y,int width,int height)323 clearlooks_gummy_draw_progressbar_trough (cairo_t                *cr,
324                                           const ClearlooksColors *colors,
325                                           const WidgetParameters *params,
326                                           int x, int y, int width, int height)
327 {
328 	const CairoColor *border = &colors->shade[7];
329 	CairoColor        shadow;
330 	cairo_pattern_t  *pattern;
331 	double            radius = MIN (params->radius, MIN ((height-2.0) / 2.0, (width-2.0) / 2.0));
332 
333 	cairo_save (cr);
334 
335 	cairo_set_line_width (cr, 1.0);
336 
337 	/* Create trough box */
338 	ge_cairo_rounded_rectangle (cr, x+1, y+1, width-2, height-2, radius, params->corners);
339 	ge_cairo_set_color (cr, &colors->shade[2]);
340 	cairo_fill (cr);
341 
342 	/* Draw border */
343 	ge_cairo_rounded_rectangle (cr, x+0.5, y+0.5, width-1, height-1, radius, params->corners);
344 	clearlooks_set_mixed_color (cr, border, &colors->shade[2], 0.3);
345 	cairo_stroke (cr);
346 
347 	/* clip the corners of the shadows */
348 	ge_cairo_rounded_rectangle (cr, x+1, y+1, width-2, height-2, radius, params->corners);
349 	cairo_clip (cr);
350 
351 	ge_shade_color (border, 0.92, &shadow);
352 
353 	/* Top shadow */
354 	cairo_rectangle (cr, x+1, y+1, width-2, 4);
355 	pattern = cairo_pattern_create_linear (x, y, x, y+4);
356 	cairo_pattern_add_color_stop_rgba (pattern, 0.0, shadow.r, shadow.g, shadow.b, 0.3);
357 	cairo_pattern_add_color_stop_rgba (pattern, 1.0, shadow.r, shadow.g, shadow.b, 0.);
358 	cairo_set_source (cr, pattern);
359 	cairo_fill (cr);
360 	cairo_pattern_destroy (pattern);
361 
362 	/* Left shadow */
363 	cairo_rectangle (cr, x+1, y+1, 4, height-2);
364 	pattern = cairo_pattern_create_linear (x, y, x+4, y);
365 	cairo_pattern_add_color_stop_rgba (pattern, 0.0, shadow.r, shadow.g, shadow.b, 0.3);
366 	cairo_pattern_add_color_stop_rgba (pattern, 1.0, shadow.r, shadow.g, shadow.b, 0.);
367 	cairo_set_source (cr, pattern);
368 	cairo_fill (cr);
369 	cairo_pattern_destroy (pattern);
370 
371 	cairo_restore (cr);
372 }
373 
374 static void
clearlooks_gummy_draw_progressbar_fill(cairo_t * cr,const ClearlooksColors * colors,const WidgetParameters * params,const ProgressBarParameters * progressbar,int x,int y,int width,int height,gint offset)375 clearlooks_gummy_draw_progressbar_fill (cairo_t                     *cr,
376                                         const ClearlooksColors      *colors,
377                                         const WidgetParameters      *params,
378                                         const ProgressBarParameters *progressbar,
379                                         int x, int y, int width, int height, gint offset)
380 {
381 	boolean is_horizontal = progressbar->orientation < 2;
382 	double  tile_pos = 0;
383 	double  stroke_width;
384 	double  radius;
385 	int     x_step;
386 
387 	cairo_pattern_t *pattern;
388 	CairoColor       shade1, shade2, shade3;
389 	CairoColor       border;
390 	CairoColor       shadow;
391 
392 	radius = MAX (0, params->radius - params->xthickness);
393 
394 	cairo_save (cr);
395 
396 	if (!is_horizontal)
397 		ge_cairo_exchange_axis (cr, &x, &y, &width, &height);
398 
399 	if ((progressbar->orientation == CL_ORIENTATION_RIGHT_TO_LEFT) || (progressbar->orientation == CL_ORIENTATION_BOTTOM_TO_TOP))
400 		ge_cairo_mirror (cr, CR_MIRROR_HORIZONTAL, &x, &y, &width, &height);
401 
402 	/* Clamp the radius so that the _height_ fits ... */
403 	radius = MIN (radius, height / 2.0);
404 
405 	stroke_width = height*2;
406 	x_step = (((float)stroke_width/10)*offset); /* This looks weird ... */
407 
408 	cairo_translate (cr, x, y);
409 
410 	cairo_save (cr);
411 	/* This is kind of nasty ... Clip twice from each side in case the length
412 	 * of the fill is smaller than twice the radius. */
413 	ge_cairo_rounded_rectangle (cr, 0, 0, width + radius, height, radius, CR_CORNER_TOPLEFT | CR_CORNER_BOTTOMLEFT);
414 	cairo_clip (cr);
415 	ge_cairo_rounded_rectangle (cr, -radius, 0, width + radius, height, radius, CR_CORNER_TOPRIGHT | CR_CORNER_BOTTOMRIGHT);
416 	cairo_clip (cr);
417 
418 	/* Draw the background gradient */
419 	ge_shade_color (&colors->spot[1], SHADE_TOP, &shade1);
420 	ge_shade_color (&colors->spot[1], SHADE_CENTER_TOP, &shade2);
421 	ge_shade_color (&colors->spot[1], SHADE_BOTTOM, &shade3);
422 	pattern = cairo_pattern_create_linear (0, 0, 0, height);
423 	cairo_pattern_add_color_stop_rgb (pattern, 0.0, shade1.r, shade1.g, shade1.b);
424 	cairo_pattern_add_color_stop_rgb (pattern, 0.5, shade2.r, shade2.g, shade2.b);
425 	cairo_pattern_add_color_stop_rgb (pattern, 0.5, colors->spot[1].r, colors->spot[1].g, colors->spot[1].b);
426 	cairo_pattern_add_color_stop_rgb (pattern, 1.0, shade3.r, shade3.g, shade3.b);
427 	cairo_set_source (cr, pattern);
428 	cairo_paint (cr);
429 	cairo_pattern_destroy (pattern);
430 
431 	/* Draw the strokes */
432 	while (stroke_width > 0 && tile_pos <= width+x_step)
433 	{
434 		cairo_move_to (cr, stroke_width/2-x_step, 0);
435 		cairo_line_to (cr, stroke_width-x_step,   0);
436 		cairo_line_to (cr, stroke_width/2-x_step, height);
437 		cairo_line_to (cr, -x_step, height);
438 
439 		cairo_translate (cr, stroke_width, 0);
440 		tile_pos += stroke_width;
441 	}
442 
443 	cairo_set_source_rgba (cr, colors->spot[2].r,
444 	                           colors->spot[2].g,
445 	                           colors->spot[2].b,
446 	                           0.15);
447 
448 	cairo_fill (cr);
449 	cairo_restore (cr); /* rounded clip region */
450 
451 	/* inner highlight border
452 	 * This is again kinda ugly. Draw once from each side, clipping away the other. */
453 	cairo_set_source_rgba (cr, colors->spot[0].r, colors->spot[0].g, colors->spot[0].b, 0.2);
454 
455 	/* left side */
456 	cairo_save (cr);
457 	cairo_rectangle (cr, 0, 0, width / 2, height);
458 	cairo_clip (cr);
459 
460 	if (progressbar->pulsing)
461 		ge_cairo_rounded_rectangle (cr, 1.5, 0.5, width + radius, height - 1, radius, CR_CORNER_TOPLEFT | CR_CORNER_BOTTOMLEFT);
462 	else
463 		ge_cairo_rounded_rectangle (cr, 0.5, 0.5, width + radius, height - 1, radius, CR_CORNER_TOPLEFT | CR_CORNER_BOTTOMLEFT);
464 
465 	cairo_stroke (cr);
466 	cairo_restore (cr); /* clip */
467 
468 	/* right side */
469 	cairo_save (cr);
470 	cairo_rectangle (cr, width / 2, 0, (width+1) / 2, height);
471 	cairo_clip (cr);
472 
473 	if (progressbar->value < 1.0 || progressbar->pulsing)
474 		ge_cairo_rounded_rectangle (cr, -1.5 - radius, 0.5, width + radius, height - 1, radius, CR_CORNER_TOPRIGHT | CR_CORNER_BOTTOMRIGHT);
475 	else
476 		ge_cairo_rounded_rectangle (cr, -0.5 - radius, 0.5, width + radius, height - 1, radius, CR_CORNER_TOPRIGHT | CR_CORNER_BOTTOMRIGHT);
477 
478 	cairo_stroke (cr);
479 	cairo_restore (cr); /* clip */
480 
481 
482 	/* Draw the dark lines and the shadow */
483 	cairo_save (cr);
484 	/* Again, this weird clip area. */
485 	ge_cairo_rounded_rectangle (cr, -1.0, 0, width + radius + 2.0, height, radius, CR_CORNER_TOPLEFT | CR_CORNER_BOTTOMLEFT);
486 	cairo_clip (cr);
487 	ge_cairo_rounded_rectangle (cr, -radius - 1.0, 0, width + radius + 2.0, height, radius, CR_CORNER_TOPRIGHT | CR_CORNER_BOTTOMRIGHT);
488 	cairo_clip (cr);
489 
490 	border = colors->spot[2];
491 	border.a = 0.6;
492 	ge_shade_color (&colors->shade[7], 0.92, &shadow);
493 	shadow.a = 0.2;
494 
495 	if (progressbar->pulsing)
496 	{
497 		/* At the beginning of the bar. */
498 		cairo_move_to (cr, 0.5 + radius, height + 0.5);
499 		ge_cairo_rounded_corner (cr, 0.5, height + 0.5, radius + 1, CR_CORNER_BOTTOMLEFT);
500 		ge_cairo_rounded_corner (cr, 0.5, -0.5, radius + 1, CR_CORNER_TOPLEFT);
501 		ge_cairo_set_color (cr, &border);
502 		cairo_stroke (cr);
503 
504 		cairo_move_to (cr, -0.5 + radius, height + 0.5);
505 		ge_cairo_rounded_corner (cr, -0.5, height + 0.5, radius + 1, CR_CORNER_BOTTOMLEFT);
506 		ge_cairo_rounded_corner (cr, -0.5, -0.5, radius + 1, CR_CORNER_TOPLEFT);
507 		ge_cairo_set_color (cr, &shadow);
508 		cairo_stroke (cr);
509 	}
510 	if (progressbar->value < 1.0 || progressbar->pulsing)
511 	{
512 		/* At the end of the bar. */
513 		cairo_move_to (cr, width - 0.5 - radius, -0.5);
514 		ge_cairo_rounded_corner (cr, width - 0.5, -0.5, radius + 1, CR_CORNER_TOPRIGHT);
515 		ge_cairo_rounded_corner (cr, width - 0.5, height + 0.5, radius + 1, CR_CORNER_BOTTOMRIGHT);
516 		ge_cairo_set_color (cr, &border);
517 		cairo_stroke (cr);
518 
519 		cairo_move_to (cr, width + 0.5 - radius, -0.5);
520 		ge_cairo_rounded_corner (cr, width + 0.5, -0.5, radius + 1, CR_CORNER_TOPRIGHT);
521 		ge_cairo_rounded_corner (cr, width + 0.5, height + 0.5, radius + 1, CR_CORNER_BOTTOMRIGHT);
522 		ge_cairo_set_color (cr, &shadow);
523 		cairo_stroke (cr);
524 	}
525 
526 	cairo_restore (cr);
527 
528 	cairo_restore (cr); /* rotation, mirroring */
529 }
530 
531 static void
clearlooks_gummy_scale_draw_gradient(cairo_t * cr,const CairoColor * fill,const CairoColor * border,int x,int y,int width,int height,gboolean horizontal,gboolean in)532 clearlooks_gummy_scale_draw_gradient (cairo_t          *cr,
533                                       const CairoColor *fill,
534                                       const CairoColor *border,
535                                       int x, int y, int width, int height,
536                                       gboolean horizontal, gboolean in)
537 {
538 	cairo_pattern_t *pattern;
539 
540 	CairoColor f1, f2;
541 
542 	ge_shade_color (fill, in? 0.95 : 1.1, &f1);
543 	ge_shade_color (fill, in? 1.05 : 0.9, &f2);
544 
545 	pattern = cairo_pattern_create_linear (0.5, 0.5, horizontal ? 0.5 :  width + 1.0, horizontal ? height + 1.0 : 0.5);
546 	cairo_pattern_add_color_stop_rgba (pattern, 0.0, f1.r, f1.g, f1.b, f1.a);
547 	cairo_pattern_add_color_stop_rgba (pattern, 1.0, f2.r, f2.g, f2.b, f2.a);
548 
549 	cairo_rectangle (cr, x, y, width, height);
550 	cairo_set_source (cr, pattern);
551 	cairo_fill (cr);
552 	cairo_pattern_destroy (pattern);
553 
554 	clearlooks_set_mixed_color (cr, border, fill, 0.2);
555 	ge_cairo_inner_rectangle (cr, x, y, width, height);
556 	cairo_stroke (cr);
557 }
558 
559 #define TROUGH_SIZE 7
560 static void
clearlooks_gummy_draw_scale_trough(cairo_t * cr,const ClearlooksColors * colors,const WidgetParameters * params,const SliderParameters * slider,int x,int y,int width,int height)561 clearlooks_gummy_draw_scale_trough (cairo_t                *cr,
562                                     const ClearlooksColors *colors,
563                                     const WidgetParameters *params,
564                                     const SliderParameters *slider,
565                                     int x, int y, int width, int height)
566 {
567 	int    trough_width, trough_height;
568 	double translate_x, translate_y;
569 	CairoColor fill, border;
570 	gboolean in;
571 
572 	cairo_save (cr);
573 
574 	if (slider->horizontal)
575 	{
576 		trough_width  = width;
577 		trough_height = TROUGH_SIZE;
578 
579 		translate_x   = x;
580 		translate_y   = y + (height/2) - (TROUGH_SIZE/2);
581 	}
582 	else
583 	{
584 		trough_width  = TROUGH_SIZE;
585 		trough_height = height;
586 
587 		translate_x   = x + (width/2) - (TROUGH_SIZE/2);
588 		translate_y   = y;
589 	}
590 
591 	cairo_set_line_width (cr, 1.0);
592 	cairo_translate (cr, translate_x, translate_y);
593 
594 	if (!slider->fill_level)
595 		params->style_functions->draw_inset (cr, &params->parentbg, 0, 0, trough_width, trough_height, 0, 0);
596 
597 	if (!slider->lower && !slider->fill_level)
598 	{
599 		ge_shade_color (&params->parentbg, 0.896, &fill);
600 		border = colors->shade[6];
601 		in = TRUE;
602 	}
603 	else if (!slider->fill_level)
604 	{
605 		fill = colors->spot[1];
606 		border = colors->spot[2];
607 		in = FALSE;
608 	}
609 	else
610 	{
611 		fill = colors->spot[1];
612 		border = colors->spot[2];
613 
614 		fill.a = 0.25;
615 		border.a = 0.25;
616 
617 		in = FALSE;
618 	}
619 
620 	clearlooks_gummy_scale_draw_gradient (cr,
621 	                                      &fill,
622 	                                      &border,
623 	                                      1, 1, trough_width - 2, trough_height - 2,
624 	                                      slider->horizontal, in);
625 
626 	cairo_restore (cr);
627 }
628 
629 static void
clearlooks_gummy_draw_tab(cairo_t * cr,const ClearlooksColors * colors,const WidgetParameters * params,const TabParameters * tab,int x,int y,int width,int height)630 clearlooks_gummy_draw_tab (cairo_t                *cr,
631                            const ClearlooksColors *colors,
632                            const WidgetParameters *params,
633                            const TabParameters    *tab,
634                            int x, int y, int width, int height)
635 {
636 	const CairoColor *border        = &colors->shade[5];
637 	const CairoColor *stripe_fill   = &colors->spot[1];
638 	const CairoColor *stripe_border = &colors->spot[2];
639 	const CairoColor *fill;
640 
641 	cairo_pattern_t  *pattern = NULL;
642 
643 	double            radius;
644 	double            stripe_size = 2.0;
645 	double            stripe_fill_size;
646 	double            stripe_border_pos;
647 
648 	gboolean horizontal = FALSE;
649 
650 	radius = MIN (params->radius, MIN ((width - 2.0) / 2.0, (height - 2.0) / 2.0));
651 
652 	/* Set clip */
653 	cairo_rectangle      (cr, x, y, width, height);
654 	cairo_clip           (cr);
655 	cairo_new_path       (cr);
656 
657 	/* Translate and set line width */
658 	cairo_set_line_width (cr, 1.0);
659 	cairo_translate      (cr, x+0.5, y+0.5);
660 
661 	/* Make the tabs slightly bigger than they should be, to create a gap */
662 	/* And calculate the strip size too, while you're at it */
663 	if (tab->gap_side == CL_GAP_TOP || tab->gap_side == CL_GAP_BOTTOM)
664 	{
665 		if (params->ythickness == 3)
666 			stripe_size = 3.0;
667 
668 		height += 3.0;
669 		stripe_fill_size = (tab->gap_side == CL_GAP_TOP ? stripe_size/height : stripe_size/(height-2));
670 		stripe_border_pos = (tab->gap_side == CL_GAP_TOP ? (stripe_size+1.0)/height : (stripe_size+1.0)/(height-2));
671 
672 		horizontal = TRUE;
673 
674 		if (tab->gap_side == CL_GAP_TOP)
675 			cairo_translate (cr, 0.0, -3.0); /* gap at the other side */
676 	}
677 	else
678 	{
679 		if (params->xthickness == 3)
680 			stripe_size = 3.0;
681 
682 		width += 3.0;
683 		stripe_fill_size = (tab->gap_side == CL_GAP_LEFT ? stripe_size/width : stripe_size/(width-2));
684 		stripe_border_pos = (tab->gap_side == CL_GAP_LEFT ? (stripe_size+1.0)/width : (stripe_size+1.0)/(width-2));
685 
686 		if (tab->gap_side == CL_GAP_LEFT)
687 			cairo_translate (cr, -3.0, 0.0); /* gap at the other side */
688 	}
689 
690 	/* Set the fill color */
691 	fill = &colors->bg[params->state_type];
692 
693 	/* Set tab shape */
694 	ge_cairo_rounded_rectangle (cr, 0, 0, width-1, height-1,
695 	                            radius, params->corners);
696 
697 	/* Draw fill */
698 	ge_cairo_set_color (cr, fill);
699 	cairo_fill  (cr);
700 
701 	/* Draw highlight */
702 	if (!params->active)
703 	{
704 		ShadowParameters shadow;
705 
706 		shadow.shadow  = CL_SHADOW_OUT;
707 		shadow.corners = params->corners;
708 
709 		clearlooks_gummy_draw_highlight_and_shade (cr, &colors->bg[0], &shadow,
710 		                                           width, height, radius);
711 	}
712 
713 	if (params->active)
714 	{
715 		CairoColor hilight;
716 		CairoColor shade1, shade2, shade3;
717 
718 		ge_shade_color (fill, 1.15, &hilight);
719 		ge_shade_color (fill, SHADE_TOP, &shade1);
720 		ge_shade_color (fill, SHADE_CENTER_TOP, &shade2);
721 		ge_shade_color (fill, SHADE_BOTTOM, &shade3);
722 
723 		switch	(tab->gap_side)
724 		{
725 			case CL_GAP_TOP:
726 				pattern = cairo_pattern_create_linear (0, height-2, 0, 0);
727 				break;
728 			case CL_GAP_BOTTOM:
729 				pattern = cairo_pattern_create_linear (0, 1, 0, height);
730 				break;
731 			case CL_GAP_LEFT:
732 				pattern = cairo_pattern_create_linear (width-2, 0, 1, 0);
733 				break;
734 			case CL_GAP_RIGHT:
735 				pattern = cairo_pattern_create_linear (1, 0, width-2, 0);
736 				break;
737 		}
738 
739 		ge_cairo_rounded_rectangle (cr, 0, 0, width-1, height-1, radius, params->corners);
740 
741 		cairo_pattern_add_color_stop_rgb (pattern, 0.0, hilight.r, hilight.g, hilight.b);
742 		cairo_pattern_add_color_stop_rgb (pattern, 1.0/(horizontal ? height : width), hilight.r, hilight.g, hilight.b);
743 		cairo_pattern_add_color_stop_rgb (pattern, 1.0/(horizontal ? height : width), shade1.r, shade1.g, shade1.b);
744 		cairo_pattern_add_color_stop_rgb (pattern, 0.45, shade2.r, shade2.g, shade2.b);
745 		cairo_pattern_add_color_stop_rgb (pattern, 0.45, fill->r, fill->g, fill->b);
746 		cairo_pattern_add_color_stop_rgb (pattern, 1.0, shade3.r, shade3.g, shade3.b);
747 		cairo_set_source (cr, pattern);
748 		cairo_fill (cr);
749 		cairo_pattern_destroy (pattern);
750 	}
751 	else
752 	{
753 		CairoColor shade1;
754 
755 		ge_shade_color (fill, SHADE_TOP, &shade1);
756 
757 		switch	(tab->gap_side)
758 		{
759 			case CL_GAP_TOP:
760 				pattern = cairo_pattern_create_linear (0, height-2, 0, 0);
761 				break;
762 			case CL_GAP_BOTTOM:
763 				pattern = cairo_pattern_create_linear (0, 0, 0, height);
764 				break;
765 			case CL_GAP_LEFT:
766 				pattern = cairo_pattern_create_linear (width-2, 0, 0, 0);
767 				break;
768 			case CL_GAP_RIGHT:
769 				pattern = cairo_pattern_create_linear (0, 0, width, 0);
770 				break;
771 		}
772 
773 		ge_cairo_rounded_rectangle (cr, 0, 0, width-1, height-1, radius, params->corners);
774 
775 		cairo_pattern_add_color_stop_rgba (pattern, 0.0, stripe_fill->r, stripe_fill->g, stripe_fill->b, 0.6);
776 		/* cairo_pattern_add_color_stop_rgba (pattern, 1.0/(horizontal ? height : width), stripe_fill->r, stripe_fill->g, stripe_fill->b, 0.34);
777 		   cairo_pattern_add_color_stop_rgba (pattern, 1.0/(horizontal ? height : width), stripe_fill->r, stripe_fill->g, stripe_fill->b, 0.5); */
778 		cairo_pattern_add_color_stop_rgb  (pattern, stripe_fill_size, stripe_fill->r, stripe_fill->g, stripe_fill->b);
779 		cairo_pattern_add_color_stop_rgba (pattern, stripe_fill_size, stripe_border->r, stripe_border->g, stripe_border->b, 0.72);
780 		cairo_pattern_add_color_stop_rgba (pattern, stripe_border_pos, stripe_border->r, stripe_border->g, stripe_border->b, 0.72);
781 		cairo_pattern_add_color_stop_rgb  (pattern, stripe_border_pos, shade1.r, shade1.g, shade1.b);
782 		cairo_pattern_add_color_stop_rgba (pattern, 0.8, fill->r, fill->g, fill->b, 0.0);
783 		cairo_set_source (cr, pattern);
784 		cairo_fill (cr);
785 		cairo_pattern_destroy (pattern);
786 	}
787 
788 	ge_cairo_rounded_rectangle (cr, 0, 0, width-1, height-1, radius, params->corners);
789 
790 	if (params->active)
791 	{
792 		ge_cairo_set_color (cr, border);
793 		cairo_stroke (cr);
794 	}
795 	else
796 	{
797 		switch	(tab->gap_side)
798 		{
799 			case CL_GAP_TOP:
800 				pattern = cairo_pattern_create_linear (2, height-2, 2, 2);
801 				break;
802 			case CL_GAP_BOTTOM:
803 				pattern = cairo_pattern_create_linear (2, 2, 2, height);
804 				break;
805 			case CL_GAP_LEFT:
806 				pattern = cairo_pattern_create_linear (width-2, 2, 2, 2);
807 				break;
808 			case CL_GAP_RIGHT:
809 				pattern = cairo_pattern_create_linear (2, 2, width, 2);
810 				break;
811 		}
812 
813 		cairo_pattern_add_color_stop_rgb (pattern, 0.0, stripe_border->r, stripe_border->g, stripe_border->b);
814 		cairo_pattern_add_color_stop_rgb (pattern, 0.8, border->r,        border->g,        border->b);
815 		cairo_set_source (cr, pattern);
816 		cairo_stroke (cr);
817 		cairo_pattern_destroy (pattern);
818 	}
819 
820 	/* In current GTK+ focus and active cannot happen together, but we are robust against it. */
821 	if (params->focus && !params->active)
822 	{
823 		CairoColor focus_fill = tab->focus.color;
824 		CairoColor fill_shade1, fill_shade2, fill_shade3;
825 		CairoColor focus_border;
826 
827 		double focus_inset_x = ((tab->gap_side == CL_GAP_TOP || tab->gap_side == CL_GAP_BOTTOM) ? 4 : stripe_size + 3);
828 		double focus_inset_y = ((tab->gap_side == CL_GAP_TOP || tab->gap_side == CL_GAP_BOTTOM) ? stripe_size + 3 : 4);
829 		double border_alpha = 0.54;
830 		double fill_alpha = 0.17;
831 
832 		ge_shade_color (&focus_fill, 0.65, &focus_border);
833 		ge_shade_color (&focus_fill, 1.18, &fill_shade1);
834 		ge_shade_color (&focus_fill, 1.02, &fill_shade2);
835 		ge_shade_color (&focus_fill, 0.84, &fill_shade3);
836 
837 		ge_cairo_rounded_rectangle (cr, focus_inset_x, focus_inset_y, width-focus_inset_x*2-1, height-focus_inset_y*2-1, radius-1, CR_CORNER_ALL);
838 		pattern = cairo_pattern_create_linear (0, 0, 0, height);
839 
840 		cairo_pattern_add_color_stop_rgba (pattern, 0.0, fill_shade1.r, fill_shade1.g, fill_shade1.b, fill_alpha);
841 		cairo_pattern_add_color_stop_rgba (pattern, 0.5, fill_shade2.r, fill_shade2.g, fill_shade2.b, fill_alpha);
842 		cairo_pattern_add_color_stop_rgba (pattern, 0.5, focus_fill.r,   focus_fill.g, focus_fill.b,  fill_alpha);
843 		cairo_pattern_add_color_stop_rgba (pattern, 1.0, fill_shade3.r, fill_shade3.g, fill_shade3.b, fill_alpha);
844 		cairo_set_source (cr, pattern);
845 		cairo_fill_preserve (cr);
846 
847 		cairo_pattern_destroy (pattern);
848 
849 		clearlooks_set_mixed_color (cr, &params->parentbg, &focus_border, border_alpha);
850 		cairo_stroke (cr);
851 	}
852 }
853 
854 static void
clearlooks_gummy_draw_separator(cairo_t * cr,const ClearlooksColors * colors,const WidgetParameters * widget,const SeparatorParameters * separator,int x,int y,int width,int height)855 clearlooks_gummy_draw_separator (cairo_t                   *cr,
856                                  const ClearlooksColors    *colors,
857                                  const WidgetParameters    *widget,
858                                  const SeparatorParameters *separator,
859                                  int x, int y, int width, int height)
860 {
861 	CairoColor color = colors->shade[3];
862 	CairoColor hilight;
863 	ge_shade_color (&color, 1.3, &hilight);
864 
865 	cairo_save (cr);
866 	cairo_set_line_cap (cr, CAIRO_LINE_CAP_BUTT);
867 
868 	if (separator->horizontal)
869 	{
870 		cairo_set_line_width (cr, 1.0);
871 		cairo_translate      (cr, x, y+0.5);
872 
873 		cairo_move_to        (cr, 0.0,   0.0);
874 		cairo_line_to        (cr, width, 0.0);
875 		ge_cairo_set_color   (cr, &color);
876 		cairo_stroke         (cr);
877 
878 		cairo_move_to        (cr, 0.0,   1.0);
879 		cairo_line_to        (cr, width, 1.0);
880 		ge_cairo_set_color   (cr, &hilight);
881 		cairo_stroke         (cr);
882 	}
883 	else
884 	{
885 		cairo_set_line_width (cr, 1.0);
886 		cairo_translate      (cr, x+0.5, y);
887 
888 		cairo_move_to        (cr, 0.0, 0.0);
889 		cairo_line_to        (cr, 0.0, height);
890 		ge_cairo_set_color   (cr, &color);
891 		cairo_stroke         (cr);
892 
893 		cairo_move_to        (cr, 1.0, 0.0);
894 		cairo_line_to        (cr, 1.0, height);
895 		ge_cairo_set_color   (cr, &hilight);
896 		cairo_stroke         (cr);
897 	}
898 
899 	cairo_restore (cr);
900 }
901 
902 static void
clearlooks_gummy_draw_slider(cairo_t * cr,const ClearlooksColors * colors,const WidgetParameters * params,int x,int y,int width,int height)903 clearlooks_gummy_draw_slider (cairo_t                *cr,
904                               const ClearlooksColors *colors,
905                               const WidgetParameters *params,
906                               int x, int y, int width, int height)
907 {
908 	const CairoColor *border = &colors->shade[7];
909 	CairoColor fill;
910 	CairoColor shade1, shade2, shade3;
911 	cairo_pattern_t *pattern;
912 	int bar_x, i;
913 	int shift_x;
914 
915 	cairo_set_line_width (cr, 1.0);
916 	cairo_translate      (cr, x, y);
917 
918 	ge_shade_color (&colors->bg[params->state_type], 1.0, &fill);
919 	if (params->prelight)
920 		ge_shade_color (&fill, 1.04, &fill);
921 
922 	ge_shade_color (&fill, SHADE_TOP, &shade1);
923 	ge_shade_color (&fill, SHADE_CENTER_TOP, &shade2);
924 	ge_shade_color (&fill, SHADE_BOTTOM, &shade3);
925 
926 	pattern = cairo_pattern_create_linear (1, 1, 1, height-2);
927 	cairo_pattern_add_color_stop_rgb (pattern, 0,   shade1.r, shade1.g, shade1.b);
928 	cairo_pattern_add_color_stop_rgb (pattern, 0.5, shade2.r, shade2.g, shade2.b);
929 	cairo_pattern_add_color_stop_rgb (pattern, 0.5, fill.r, fill.g, fill.b);
930 	cairo_pattern_add_color_stop_rgb (pattern, 1.0, shade3.r, shade3.g, shade3.b);
931 	cairo_rectangle (cr, 1, 1, width-2, height-2);
932 	cairo_set_source (cr, pattern);
933 	cairo_fill (cr);
934 	cairo_pattern_destroy (pattern);
935 
936 	clearlooks_set_mixed_color (cr, border, &fill, 0.2);
937 	if (params->prelight)
938 		ge_cairo_set_color (cr, &colors->spot[2]);
939 	ge_cairo_rounded_rectangle (cr, 0.5, 0.5, width-1, height-1, 2.5, params->corners);
940 	cairo_stroke (cr);
941 
942 	/* Handle */
943 	shift_x = (width%2 == 0 ? 1 : 0);
944 	bar_x = width/2-3+shift_x;
945 	cairo_translate (cr, 0.5, 0.5);
946 	ge_cairo_set_color (cr, border);
947 	for (i=0; i<3-shift_x; i++)
948 	{
949 		cairo_move_to (cr, bar_x, 4);
950 		cairo_line_to (cr, bar_x, height-5);
951 		bar_x += 3;
952 	}
953 	cairo_stroke (cr);
954 
955 	params->style_functions->draw_top_left_highlight (cr, &fill, params, 1, 1, width-2, height-2, 2.0, params->corners);
956 }
957 
958 static void
clearlooks_gummy_draw_slider_button(cairo_t * cr,const ClearlooksColors * colors,const WidgetParameters * params,const SliderParameters * slider,int x,int y,int width,int height)959 clearlooks_gummy_draw_slider_button (cairo_t                *cr,
960                                      const ClearlooksColors *colors,
961                                      const WidgetParameters *params,
962                                      const SliderParameters *slider,
963                                      int x, int y, int width, int height)
964 {
965 	double radius = MIN (params->radius, MIN ((width - 1.0) / 2.0, (height - 1.0) / 2.0));
966 
967 	cairo_set_line_width (cr, 1.0);
968 
969 	if (!slider->horizontal)
970 		ge_cairo_exchange_axis (cr, &x, &y, &width, &height);
971 
972 	cairo_translate (cr, x, y);
973 
974 	params->style_functions->draw_shadow (cr, colors, radius, width, height);
975 	params->style_functions->draw_slider (cr, colors, params, 1, 1, width-2, height-2);
976 }
977 
978 static void
clearlooks_gummy_draw_scrollbar_stepper(cairo_t * cr,const ClearlooksColors * colors,const WidgetParameters * widget,const ScrollBarParameters * scrollbar,const ScrollBarStepperParameters * stepper,int x,int y,int width,int height)979 clearlooks_gummy_draw_scrollbar_stepper (cairo_t                          *cr,
980                                          const ClearlooksColors           *colors,
981                                          const WidgetParameters           *widget,
982                                          const ScrollBarParameters        *scrollbar,
983                                          const ScrollBarStepperParameters *stepper,
984                                          int x, int y, int width, int height)
985 {
986 	CairoCorners corners = CR_CORNER_NONE;
987 	const CairoColor *border = &colors->shade[scrollbar->has_color ? 7 : 6];
988 	CairoColor fill;
989 	CairoColor shade1, shade2, shade3;
990 	cairo_pattern_t *pattern;
991 	double radius = MIN (widget->radius, MIN ((width - 2.0) / 2.0, (height - 2.0) / 2.0));
992 
993 	if (scrollbar->horizontal)
994 	{
995 		if (stepper->stepper == CL_STEPPER_A)
996 			corners = CR_CORNER_TOPLEFT | CR_CORNER_BOTTOMLEFT;
997 		else if (stepper->stepper == CL_STEPPER_D)
998 			corners = CR_CORNER_TOPRIGHT | CR_CORNER_BOTTOMRIGHT;
999 
1000 		if (stepper->stepper == CL_STEPPER_B)
1001 		{
1002 			x -= 1;
1003 			width += 1;
1004 		}
1005 		else if (stepper->stepper == CL_STEPPER_C)
1006 		{
1007 			width += 1;
1008 		}
1009 	}
1010 	else
1011 	{
1012 		if (stepper->stepper == CL_STEPPER_A)
1013 			corners = CR_CORNER_TOPLEFT | CR_CORNER_TOPRIGHT;
1014 		else if (stepper->stepper == CL_STEPPER_D)
1015 			corners = CR_CORNER_BOTTOMLEFT | CR_CORNER_BOTTOMRIGHT;
1016 
1017 		if (stepper->stepper == CL_STEPPER_B)
1018 		{
1019 			y -= 1;
1020 			height += 1;
1021 		}
1022 		else if (stepper->stepper == CL_STEPPER_C)
1023 		{
1024 			height += 1;
1025 		}
1026 	}
1027 
1028 	cairo_translate (cr, x, y);
1029 	cairo_set_line_width (cr, 1);
1030 
1031 	ge_cairo_rounded_rectangle (cr, 1, 1, width-2, height-2, radius, corners);
1032 
1033 	if (scrollbar->horizontal)
1034 		pattern = cairo_pattern_create_linear (0, 0, 0, height);
1035 	else
1036 		pattern = cairo_pattern_create_linear (0, 0, width, 0);
1037 
1038 	fill = colors->bg[widget->state_type];
1039 	ge_shade_color (&fill, SHADE_TOP, &shade1);
1040 	ge_shade_color (&fill, SHADE_CENTER_TOP, &shade2);
1041 	ge_shade_color (&fill, SHADE_BOTTOM, &shade3);
1042 
1043 	cairo_pattern_add_color_stop_rgb (pattern, 0,   shade1.r, shade1.g, shade1.b);
1044 	cairo_pattern_add_color_stop_rgb (pattern, 0.5, shade2.r, shade2.g, shade2.b);
1045 	cairo_pattern_add_color_stop_rgb (pattern, 0.5, fill.r, fill.g, fill.b);
1046 	cairo_pattern_add_color_stop_rgb (pattern, 1.0, shade3.r, shade3.g, shade3.b);
1047 	cairo_set_source (cr, pattern);
1048 	cairo_fill (cr);
1049 	cairo_pattern_destroy (pattern);
1050 
1051 	widget->style_functions->draw_top_left_highlight (cr, &fill, widget, 1, 1, width - 2, height - 2,
1052 	                                                  radius, corners);
1053 
1054 	ge_cairo_rounded_rectangle (cr, 0.5, 0.5, width-1, height-1, radius, corners);
1055 	clearlooks_set_mixed_color (cr, border, &fill, 0.2);
1056 	cairo_stroke (cr);
1057 }
1058 
1059 static void
clearlooks_gummy_draw_scrollbar_slider(cairo_t * cr,const ClearlooksColors * colors,const WidgetParameters * widget,const ScrollBarParameters * scrollbar,int x,int y,int width,int height)1060 clearlooks_gummy_draw_scrollbar_slider (cairo_t                   *cr,
1061                                         const ClearlooksColors    *colors,
1062                                         const WidgetParameters    *widget,
1063                                         const ScrollBarParameters *scrollbar,
1064                                         int x, int y, int width, int height)
1065 {
1066 	CairoColor fill = scrollbar->color;
1067 	CairoColor border, handles;
1068 	CairoColor hilight;
1069 	CairoColor shade1, shade2, shade3;
1070 	cairo_pattern_t *pattern;
1071 	int bar_x, i;
1072 
1073 	gdouble hue_scroll, brightness_scroll, saturation_scroll;
1074 	gdouble hue_bg, brightness_bg, saturation_bg;
1075 
1076 	ge_hsb_from_color (&fill, &hue_scroll, &saturation_scroll, &brightness_scroll);
1077 	ge_hsb_from_color (&colors->bg[0], &hue_bg, &saturation_bg, &brightness_bg);
1078 
1079 	/* Set the right color for border and handles */
1080 	if ((fabs(saturation_scroll - saturation_bg) < 0.30) &&
1081 	    (fabs(brightness_scroll - brightness_bg) < 0.20))
1082 		ge_shade_color (&fill, 0.475, &border);
1083 	else
1084 		ge_shade_color (&fill, 0.575, &border);
1085 	/* The following lines increase contrast when the HUE is between 25 and 195, */
1086 	/* fixing a LOT of colorschemes! */
1087 	if (scrollbar->has_color && (hue_scroll < 195) && (hue_scroll > 25))
1088 		ge_shade_color (&border, 0.85, &border);
1089 
1090 	handles = border;
1091 	ge_mix_color (&border, &fill, scrollbar->has_color? 0.3 : 0.2, &border);
1092 
1093 	if (scrollbar->junction & CL_JUNCTION_BEGIN)
1094 	{
1095 		if (scrollbar->horizontal)
1096 		{
1097 			x -= 1;
1098 			width += 1;
1099 		}
1100 		else
1101 		{
1102 			y -= 1;
1103 			height += 1;
1104 		}
1105 	}
1106 	if (scrollbar->junction & CL_JUNCTION_END)
1107 	{
1108 		if (scrollbar->horizontal)
1109 			width += 1;
1110 		else
1111 			height += 1;
1112 	}
1113 
1114 	if (!scrollbar->horizontal)
1115 		ge_cairo_exchange_axis (cr, &x, &y, &width, &height);
1116 
1117 	cairo_translate (cr, x, y);
1118 
1119 	if (widget->prelight)
1120 		ge_shade_color (&fill, 1.04, &fill);
1121 
1122 	cairo_set_line_width (cr, 1);
1123 
1124 	ge_shade_color (&fill, widget->style_constants->topleft_highlight_shade, &hilight);
1125 	ge_shade_color (&fill, SHADE_TOP, &shade1);
1126 	ge_shade_color (&fill, SHADE_CENTER_TOP, &shade2);
1127 	ge_shade_color (&fill, SHADE_BOTTOM, &shade3);
1128 
1129 	pattern = cairo_pattern_create_linear (1, 1, 1, height-2);
1130 	cairo_pattern_add_color_stop_rgb (pattern, 0,   shade1.r, shade1.g, shade1.b);
1131 	cairo_pattern_add_color_stop_rgb (pattern, 0.5, shade2.r, shade2.g, shade2.b);
1132 	cairo_pattern_add_color_stop_rgb (pattern, 0.5, fill.r,  fill.g,  fill.b);
1133 	cairo_pattern_add_color_stop_rgb (pattern, 1,   shade3.r, shade3.g, shade3.b);
1134 	cairo_rectangle (cr, 1, 1, width-2, height-2);
1135 	cairo_set_source (cr, pattern);
1136 	cairo_fill (cr);
1137 	cairo_pattern_destroy (pattern);
1138 
1139 	if (scrollbar->has_color)
1140 	{
1141 		cairo_set_source_rgba (cr, hilight.r, hilight.g, hilight.b, 0.2);
1142 		ge_cairo_stroke_rectangle (cr, 1.5, 1.5, width-3, height-3);
1143 	}
1144 	else
1145 	{
1146 		cairo_move_to (cr, 1.5, height-1.5);
1147 		cairo_line_to (cr, 1.5, 1.5);
1148 		cairo_line_to (cr, width-1.5, 1.5);
1149 		cairo_set_source_rgba (cr, hilight.r, hilight.g, hilight.b, widget->style_constants->topleft_highlight_alpha);
1150 		cairo_stroke (cr);
1151 	}
1152 
1153 	ge_cairo_set_color (cr, &border);
1154 	ge_cairo_stroke_rectangle (cr, 0.5, 0.5, width-1, height-1);
1155 
1156 	/* Handle */
1157 	bar_x = width/2 - 4;
1158 	cairo_translate(cr, 0.5, 0.5);
1159 	ge_cairo_set_color (cr, &handles);
1160 	for (i=0; i<3; i++)
1161 	{
1162 		cairo_move_to (cr, bar_x, 5);
1163 		cairo_line_to (cr, bar_x, height-6);
1164 		bar_x += 3;
1165 	}
1166 	cairo_stroke (cr);
1167 }
1168 
1169 static void
clearlooks_gummy_draw_list_view_header(cairo_t * cr,const ClearlooksColors * colors,const WidgetParameters * params,const ListViewHeaderParameters * header,int x,int y,int width,int height)1170 clearlooks_gummy_draw_list_view_header (cairo_t                        *cr,
1171                                         const ClearlooksColors         *colors,
1172                                         const WidgetParameters         *params,
1173                                         const ListViewHeaderParameters *header,
1174                                         int x, int y, int width, int height)
1175 {
1176 /*
1177 	CairoColor *border = !params->prelight? (CairoColor*)&colors->shade[4] : (CairoColor*)&colors->spot[1];
1178 */
1179 	const CairoColor *border = &colors->shade[4];
1180 	const CairoColor *fill   = &colors->bg[params->state_type];
1181 	CairoColor hilight;
1182 	CairoColor shade1, shade2, shade3;
1183 
1184 	cairo_pattern_t *pattern;
1185 
1186 	ge_shade_color (fill, 1.11, &hilight);
1187 	ge_shade_color (fill, LISTVIEW_SHADE_TOP, &shade1);
1188 	ge_shade_color (fill, LISTVIEW_SHADE_CENTER_TOP, &shade2);
1189 	ge_shade_color (fill, LISTVIEW_SHADE_BOTTOM, &shade3);
1190 
1191 	cairo_translate (cr, x, y);
1192 	cairo_set_line_width (cr, 1.0);
1193 
1194 	/* Draw the fill */
1195 	pattern = cairo_pattern_create_linear (0, 0, 0, height);
1196 	cairo_pattern_add_color_stop_rgb (pattern, 0.0, shade1.r, shade1.g, shade1.b);
1197 	cairo_pattern_add_color_stop_rgb (pattern, 0.5, shade2.r, shade2.g, shade2.b);
1198 	cairo_pattern_add_color_stop_rgb (pattern, 0.5, fill->r, fill->g, fill->b);
1199 	cairo_pattern_add_color_stop_rgb (pattern, 1.0-1.0/height, shade3.r, shade3.g, shade3.b);
1200 	cairo_pattern_add_color_stop_rgb (pattern, 1.0-1.0/height, border->r, border->g, border->b);
1201 	cairo_pattern_add_color_stop_rgb (pattern, 1.0, border->r, border->g, border->b);
1202 
1203 	cairo_set_source (cr, pattern);
1204 	cairo_rectangle (cr, 0, 0, width, height);
1205 	cairo_fill (cr);
1206 
1207 	cairo_pattern_destroy (pattern);
1208 
1209 	/* Draw highlight */
1210 	if (header->order & CL_ORDER_FIRST)
1211 	{
1212 		cairo_move_to (cr, 0.5, height-1.5);
1213 		cairo_line_to (cr, 0.5, 0.5);
1214 	}
1215 	else
1216 		cairo_move_to (cr, 0.0, 0.5);
1217 
1218 	cairo_line_to (cr, width, 0.5);
1219 
1220 	ge_cairo_set_color (cr, &hilight);
1221 	cairo_stroke (cr);
1222 
1223 	/* Draw resize grip */
1224 	if ((params->ltr && !(header->order & CL_ORDER_LAST)) ||
1225 	    (!params->ltr && !(header->order & CL_ORDER_FIRST)) || header->resizable)
1226 	{
1227 		SeparatorParameters separator;
1228 		separator.horizontal = FALSE;
1229 
1230 		if (params->ltr)
1231 			params->style_functions->draw_separator (cr, colors, params, &separator,
1232 			                                         width-1.5, 4.0, 2, height-8.0);
1233 		else
1234 			params->style_functions->draw_separator (cr, colors, params, &separator,
1235 			                                         1.5, 4.0, 2, height-8.0);
1236 	}
1237 }
1238 
1239 static void
clearlooks_gummy_draw_toolbar(cairo_t * cr,const ClearlooksColors * colors,const WidgetParameters * widget,const ToolbarParameters * toolbar,int x,int y,int width,int height)1240 clearlooks_gummy_draw_toolbar (cairo_t                 *cr,
1241                                const ClearlooksColors  *colors,
1242                                const WidgetParameters  *widget,
1243                                const ToolbarParameters *toolbar,
1244                                int x, int y, int width, int height)
1245 {
1246 	const CairoColor *fill = &colors->bg[GTK_STATE_NORMAL];
1247 	const CairoColor *dark = &colors->shade[3];
1248 	CairoColor light;
1249 	ge_shade_color (fill, toolbar->style == 1 ? 1.1 : 1.05, &light);
1250 
1251 	cairo_set_line_width (cr, 1.0);
1252 	cairo_translate (cr, x, y);
1253 
1254 	if (toolbar->style == 1) /* Enable Extra features */
1255 	{
1256 		cairo_pattern_t *pattern;
1257 		CairoColor shade1, shade2, shade3;
1258 
1259 		ge_shade_color (fill, TOOLBAR_SHADE_TOP, &shade1);
1260 		ge_shade_color (fill, TOOLBAR_SHADE_CENTER_TOP, &shade2);
1261 		ge_shade_color (fill, TOOLBAR_SHADE_BOTTOM, &shade3);
1262 
1263 		/* Draw the fill */
1264 		pattern = cairo_pattern_create_linear (0, 0, 0, height);
1265 		cairo_pattern_add_color_stop_rgb (pattern, 0.0, shade1.r, shade1.g, shade1.b);
1266 		cairo_pattern_add_color_stop_rgb (pattern, 0.5, shade2.r, shade2.g, shade2.b);
1267 		cairo_pattern_add_color_stop_rgb (pattern, 0.5, fill->r, fill->g, fill->b);
1268 		cairo_pattern_add_color_stop_rgb (pattern, 1.0, shade3.r, shade3.g, shade3.b);
1269 
1270 		cairo_set_source (cr, pattern);
1271 		cairo_rectangle (cr, 0, 0, width, height);
1272 		cairo_fill (cr);
1273 
1274 		cairo_pattern_destroy (pattern);
1275 	}
1276 	else /* Flat */
1277 	{
1278 		ge_cairo_set_color (cr, fill);
1279 		cairo_paint (cr);
1280 	}
1281 
1282 	if (!toolbar->topmost)
1283 	{
1284 		/* Draw highlight */
1285 		cairo_move_to       (cr, 0, 0.5);
1286 		cairo_line_to       (cr, width-0.5, 0.5);
1287 		ge_cairo_set_color  (cr, &light);
1288 		cairo_stroke        (cr);
1289 	}
1290 
1291 	/* Draw shadow */
1292 	cairo_move_to       (cr, 0, height-0.5);
1293 	cairo_line_to       (cr, width-0.5, height-0.5);
1294 	ge_cairo_set_color  (cr, dark);
1295 	cairo_stroke        (cr);
1296 }
1297 
1298 static void
clearlooks_gummy_draw_menuitem(cairo_t * cr,const ClearlooksColors * colors,const WidgetParameters * params,int x,int y,int width,int height)1299 clearlooks_gummy_draw_menuitem (cairo_t                *cr,
1300                                 const ClearlooksColors *colors,
1301                                 const WidgetParameters *params,
1302                                 int x, int y, int width, int height)
1303 {
1304 	const CairoColor *fill = &colors->spot[1];
1305 	const CairoColor *border = &colors->spot[2];
1306 	CairoColor shade1, shade2, shade3;
1307 	cairo_pattern_t *pattern;
1308 
1309 	ge_shade_color (fill, SHADE_TOP, &shade1);
1310 	ge_shade_color (fill, SHADE_CENTER_TOP, &shade2);
1311 	ge_shade_color (fill, SHADE_BOTTOM, &shade3);
1312 	cairo_set_line_width (cr, 1.0);
1313 
1314 	ge_cairo_rounded_rectangle (cr, x+0.5, y+0.5, width - 1, height - 1, params->radius, params->corners);
1315 
1316 	pattern = cairo_pattern_create_linear (x, y, x, y + height);
1317 	cairo_pattern_add_color_stop_rgb (pattern, 0,   shade1.r, shade1.g, shade1.b);
1318 	cairo_pattern_add_color_stop_rgb (pattern, 0.5,	shade2.r, shade2.g, shade2.b);
1319 	cairo_pattern_add_color_stop_rgb (pattern, 0.5, fill->r,  fill->g,  fill->b);
1320 	cairo_pattern_add_color_stop_rgb (pattern, 1,	shade3.r, shade3.g, shade3.b);
1321 
1322 	cairo_set_source (cr, pattern);
1323 	cairo_fill_preserve (cr);
1324 	cairo_pattern_destroy (pattern);
1325 
1326 	ge_cairo_set_color (cr, border);
1327 	cairo_stroke (cr);
1328 }
1329 
1330 static void
clearlooks_gummy_draw_menubaritem(cairo_t * cr,const ClearlooksColors * colors,const WidgetParameters * params,int x,int y,int width,int height)1331 clearlooks_gummy_draw_menubaritem (cairo_t                *cr,
1332                                    const ClearlooksColors *colors,
1333                                    const WidgetParameters *params,
1334                                    int x, int y, int width, int height)
1335 {
1336 	const CairoColor *fill = &colors->spot[1];
1337 	const CairoColor *border = &colors->spot[2];
1338 	CairoColor shade1, shade2, shade3;
1339 	cairo_pattern_t *pattern;
1340 
1341 	ge_shade_color (fill, SHADE_TOP, &shade1);
1342 	ge_shade_color (fill, SHADE_CENTER_TOP, &shade2);
1343 	ge_shade_color (fill, SHADE_BOTTOM, &shade3);
1344 	cairo_set_line_width (cr, 1.0);
1345 
1346 	ge_cairo_rounded_rectangle (cr, x+0.5, y+0.5, width - 1, height - 1, params->radius, params->corners);
1347 
1348 	pattern = cairo_pattern_create_linear (x, y, x, y + height);
1349 	cairo_pattern_add_color_stop_rgb (pattern, 0,   shade1.r, shade1.g, shade1.b);
1350 	cairo_pattern_add_color_stop_rgb (pattern, 0.5,	shade2.r, shade2.g, shade2.b);
1351 	cairo_pattern_add_color_stop_rgb (pattern, 0.5, fill->r,  fill->g,  fill->b);
1352 	cairo_pattern_add_color_stop_rgb (pattern, 1,	shade3.r, shade3.g, shade3.b);
1353 
1354 	cairo_set_source (cr, pattern);
1355 	cairo_fill_preserve (cr);
1356 	cairo_pattern_destroy (pattern);
1357 
1358 	ge_cairo_set_color (cr, border);
1359 	cairo_stroke (cr);
1360 }
1361 
1362 static void
clearlooks_gummy_draw_selected_cell(cairo_t * cr,const ClearlooksColors * colors,const WidgetParameters * params,int x,int y,int width,int height)1363 clearlooks_gummy_draw_selected_cell (cairo_t                *cr,
1364 	                             const ClearlooksColors *colors,
1365 	                             const WidgetParameters *params,
1366 	                             int x, int y, int width, int height)
1367 {
1368 	CairoColor color;
1369 
1370 	if (params->focus)
1371 		color = colors->base[params->state_type];
1372 	else
1373 		color = colors->base[GTK_STATE_ACTIVE];
1374 
1375 	clearlooks_draw_gummy_gradient (cr, x, y, width, height, &color, params->disabled, 0.0, CR_CORNER_NONE);
1376 }
1377 
1378 static void
clearlooks_gummy_draw_statusbar(cairo_t * cr,const ClearlooksColors * colors,const WidgetParameters * widget,int x,int y,int width,int height)1379 clearlooks_gummy_draw_statusbar (cairo_t                *cr,
1380                                  const ClearlooksColors *colors,
1381                                  const WidgetParameters *widget,
1382                                  int x, int y, int width, int height)
1383 {
1384 	const CairoColor *dark = &colors->shade[3];
1385 	CairoColor hilight;
1386 
1387 	ge_shade_color (dark, 1.3, &hilight);
1388 
1389 	cairo_set_line_width  (cr, 1);
1390 	cairo_translate       (cr, x, y+0.5);
1391 	cairo_move_to         (cr, 0, 0);
1392 	cairo_line_to         (cr, width, 0);
1393 	ge_cairo_set_color    (cr, dark);
1394 	cairo_stroke          (cr);
1395 
1396 	cairo_translate       (cr, 0, 1);
1397 	cairo_move_to         (cr, 0, 0);
1398 	cairo_line_to         (cr, width, 0);
1399 	ge_cairo_set_color    (cr, &hilight);
1400 	cairo_stroke          (cr);
1401 }
1402 
1403 static void
clearlooks_gummy_draw_radiobutton(cairo_t * cr,const ClearlooksColors * colors,const WidgetParameters * widget,const CheckboxParameters * checkbox,int x,int y,int width,int height)1404 clearlooks_gummy_draw_radiobutton (cairo_t                  *cr,
1405                                    const ClearlooksColors   *colors,
1406                                    const WidgetParameters   *widget,
1407                                    const CheckboxParameters *checkbox,
1408                                    int x, int y, int width, int height)
1409 {
1410 	const CairoColor *border;
1411 	const CairoColor *dot;
1412 	CairoColor shadow;
1413 	CairoColor highlight;
1414 	cairo_pattern_t *pt;
1415 	gboolean inconsistent;
1416 	gboolean draw_bullet = (checkbox->shadow_type == GTK_SHADOW_IN);
1417 	gdouble w, h, cx, cy, radius;
1418 
1419 	w = (gdouble) width;
1420 	h = (gdouble) height;
1421 	cx = width / 2.0;
1422 	cy = height / 2.0;
1423 	radius = MIN (width, height) / 2.0;
1424 
1425 	inconsistent = (checkbox->shadow_type == GTK_SHADOW_ETCHED_IN);
1426 	draw_bullet |= inconsistent;
1427 
1428 	if (widget->disabled)
1429 	{
1430 		border = &colors->shade[5];
1431 		dot    = &colors->shade[6];
1432 	}
1433 	else
1434 	{
1435 		if (widget->prelight)
1436 			border = &colors->spot[2];
1437 		else
1438 			border = &colors->shade[6];
1439 		dot    = &colors->text[0];
1440 	}
1441 
1442 	ge_shade_color (&widget->parentbg, 0.9, &shadow);
1443 	ge_shade_color (&widget->parentbg, 1.1, &highlight);
1444 
1445 	pt = cairo_pattern_create_linear (0, 0, radius * 2.0, radius * 2.0);
1446 	cairo_pattern_add_color_stop_rgb (pt, 0.0, shadow.r, shadow.b, shadow.g);
1447 	cairo_pattern_add_color_stop_rgba (pt, 0.5, shadow.r, shadow.b, shadow.g, 0.5);
1448 	cairo_pattern_add_color_stop_rgba (pt, 0.5, highlight.r, highlight.g, highlight.b, 0.5);
1449 	cairo_pattern_add_color_stop_rgb (pt, 1.0, highlight.r, highlight.g, highlight.b);
1450 
1451 	cairo_translate (cr, x, y);
1452 
1453 	cairo_set_line_width (cr, MAX (1.0, floor (radius/3)));
1454 	cairo_arc (cr, ceil (cx), ceil (cy), floor (radius - 0.1), 0, G_PI*2);
1455 	cairo_set_source (cr, pt);
1456 	cairo_stroke (cr);
1457 	cairo_pattern_destroy (pt);
1458 
1459 	cairo_set_line_width (cr, MAX (1.0, floor (radius/6)));
1460 
1461 	cairo_arc (cr, ceil (cx), ceil (cy), MAX (1.0, ceil (radius) - 1.5), 0, G_PI*2);
1462 
1463 	if (!widget->disabled)
1464 	{
1465 		if (widget->prelight)
1466 			clearlooks_set_mixed_color (cr, &colors->base[0], &colors->spot[1], 0.5);
1467 		else
1468 			ge_cairo_set_color (cr, &colors->base[0]);
1469 		cairo_fill_preserve (cr);
1470 	}
1471 
1472 	ge_cairo_set_color (cr, border);
1473 	cairo_stroke (cr);
1474 
1475 	if (draw_bullet)
1476 	{
1477 		if (inconsistent)
1478 		{
1479 			gdouble line_width = floor (radius * 2 / 3);
1480 
1481 			cairo_set_line_cap(cr, CAIRO_LINE_CAP_ROUND);
1482 			cairo_set_line_width (cr, line_width);
1483 
1484 			cairo_move_to (cr, ceil (cx - radius/3.0 - line_width) + line_width, ceil (cy - line_width) + line_width);
1485 			cairo_line_to (cr, floor (cx + radius/3.0 + line_width) - line_width, ceil (cy - line_width) + line_width);
1486 
1487 			ge_cairo_set_color (cr, dot);
1488 			cairo_stroke (cr);
1489 		}
1490 		else
1491 		{
1492 			cairo_arc (cr, ceil (cx), ceil (cy), floor (radius/2.0), 0, G_PI*2);
1493 			ge_cairo_set_color (cr, dot);
1494 			cairo_fill (cr);
1495 
1496 			cairo_arc (cr, floor (cx - radius/10.0), floor (cy - radius/10.0), floor (radius/6.0), 0, G_PI*2);
1497 			cairo_set_source_rgba (cr, highlight.r, highlight.g, highlight.b, 0.5);
1498 			cairo_fill (cr);
1499 		}
1500 	}
1501 }
1502 
1503 static void
clearlooks_gummy_draw_checkbox(cairo_t * cr,const ClearlooksColors * colors,const WidgetParameters * widget,const CheckboxParameters * checkbox,int x,int y,int width,int height)1504 clearlooks_gummy_draw_checkbox (cairo_t                  *cr,
1505                                 const ClearlooksColors   *colors,
1506                                 const WidgetParameters   *widget,
1507                                 const CheckboxParameters *checkbox,
1508                                 int x, int y, int width, int height)
1509 {
1510 	const CairoColor *border;
1511 	const CairoColor *dot;
1512 	gboolean inconsistent = FALSE;
1513 	gboolean draw_bullet = (checkbox->shadow_type == GTK_SHADOW_IN);
1514 
1515 	inconsistent = (checkbox->shadow_type == GTK_SHADOW_ETCHED_IN);
1516 	draw_bullet |= inconsistent;
1517 
1518 	if (widget->disabled)
1519 	{
1520 		border = &colors->shade[5];
1521 		dot    = &colors->shade[6];
1522 	}
1523 	else
1524 	{
1525 		if (widget->prelight)
1526 			border = &colors->spot[2];
1527 		else
1528 			border = &colors->shade[6];
1529 		dot    = &colors->text[GTK_STATE_NORMAL];
1530 	}
1531 
1532 	cairo_translate (cr, x, y);
1533 	cairo_set_line_width (cr, 1);
1534 
1535 	if (widget->xthickness >= 3 && widget->ythickness >= 3)
1536 	{
1537 		widget->style_functions->draw_inset (cr, &widget->parentbg, 0, 0,
1538 		                                     width, height, (widget->radius > 0)? 1 : 0, CR_CORNER_ALL);
1539 
1540 		/* Draw the rectangle for the checkbox itself */
1541 		ge_cairo_rounded_rectangle (cr, 1.5, 1.5,
1542 		                            width-3, height-3, (widget->radius > 0)? 1 : 0, CR_CORNER_ALL);
1543 	}
1544 	else
1545 	{
1546 		/* Draw the rectangle for the checkbox itself */
1547 		ge_cairo_rounded_rectangle (cr, 0.5, 0.5,
1548 		                            width-1, height-1, (widget->radius > 0)? 1 : 0, CR_CORNER_ALL);
1549 	}
1550 
1551 	if (!widget->disabled)
1552 	{
1553 		if (widget->prelight)
1554 			clearlooks_set_mixed_color (cr, &colors->base[0], &colors->spot[1], 0.5);
1555 		else
1556 			ge_cairo_set_color (cr, &colors->base[0]);
1557 		cairo_fill_preserve (cr);
1558 	}
1559 
1560 	ge_cairo_set_color (cr, border);
1561 	cairo_stroke (cr);
1562 
1563 	if (draw_bullet)
1564 	{
1565 		if (inconsistent) /* Inconsistent */
1566 		{
1567 			cairo_set_line_width (cr, 2.0);
1568 			cairo_move_to (cr, 3, height*0.5);
1569 			cairo_line_to (cr, width-3, height*0.5);
1570 		}
1571 		else
1572 		{
1573 			cairo_set_line_width (cr, 1.7);
1574 			cairo_move_to (cr, 0.5 + (width*0.2), (height*0.5));
1575 			cairo_line_to (cr, 0.5 + (width*0.4), (height*0.7));
1576 
1577 			cairo_curve_to (cr, 0.5 + (width*0.4), (height*0.7),
1578 			                    0.5 + (width*0.5), (height*0.4),
1579 			                    0.5 + (width*0.70), (height*0.25));
1580 		}
1581 
1582 		ge_cairo_set_color (cr, dot);
1583 		cairo_stroke (cr);
1584 	}
1585 }
1586 
1587 static void
clearlooks_gummy_draw_icon_view_item(cairo_t * cr,const ClearlooksColors * colors,const WidgetParameters * params,int x,int y,int width,int height)1588 clearlooks_gummy_draw_icon_view_item (cairo_t                *cr,
1589 	                                  const ClearlooksColors *colors,
1590 	                                  const WidgetParameters *params,
1591 	                                  int x, int y, int width, int height)
1592 {
1593 	CairoColor color;
1594 	gfloat radius;
1595 
1596 	if (params->focus)
1597 		color = colors->base[params->state_type];
1598 	else
1599 		color = colors->base[GTK_STATE_ACTIVE];
1600 
1601 	radius = MIN (width / 2, params->radius);
1602 	radius = MIN (height / 2, radius);
1603 
1604 	clearlooks_draw_gummy_gradient (cr, x, y, width, height, &color, params->disabled, params->radius, CR_CORNER_ALL);
1605 }
1606 
1607 static void
clearlooks_gummy_draw_focus(cairo_t * cr,const ClearlooksColors * colors,const WidgetParameters * widget,const FocusParameters * focus,int x,int y,int width,int height)1608 clearlooks_gummy_draw_focus (cairo_t                *cr,
1609                              const ClearlooksColors *colors,
1610                              const WidgetParameters *widget,
1611                              const FocusParameters  *focus,
1612                              int x, int y, int width, int height)
1613 {
1614 	CairoColor fill = focus->color;
1615 	CairoColor fill_shade1, fill_shade2, fill_shade3;
1616 	CairoColor border;
1617 	CairoColor parentbg = widget->parentbg;
1618 
1619 	/* Default values */
1620 	double xoffset = 1.5;
1621 	double yoffset = 1.5;
1622 	double radius = widget->radius-1.0;
1623 	double border_alpha = 0.64;
1624 	double fill_alpha = 0.18;
1625 	double shadow_alpha = 0.5;
1626 	boolean focus_fill = TRUE;
1627 	boolean focus_border = TRUE;
1628 	boolean focus_shadow = FALSE;
1629 
1630 	ge_shade_color (&fill, 0.65, &border);
1631 	ge_shade_color (&fill, 1.18, &fill_shade1);
1632 	ge_shade_color (&fill, 1.02, &fill_shade2);
1633 	ge_shade_color (&fill, 0.84, &fill_shade3);
1634 
1635 	/* Do some useful things to adjust focus */
1636 	switch (focus->type)
1637 	{
1638 		case CL_FOCUS_BUTTON:
1639 			xoffset = -1.5-(focus->padding);
1640 			yoffset = -1.5-(focus->padding);
1641 			radius++;
1642 			border_alpha = 0.9;
1643 			fill_alpha = 0.12;
1644 			if (!widget->active)
1645 				focus_shadow = TRUE;
1646 			break;
1647 		case CL_FOCUS_BUTTON_FLAT:
1648 			xoffset = -1.5-(focus->padding);
1649 			yoffset = -1.5-(focus->padding);
1650 			radius++;
1651 			if (widget->active || widget->prelight)
1652 			{
1653 				border_alpha = 0.9;
1654 				fill_alpha = 0.12;
1655 				if (!widget->active)
1656 					focus_shadow = TRUE;
1657 			}
1658 			break;
1659 		case CL_FOCUS_LABEL:
1660 			xoffset = 0.5;
1661 			yoffset = 0.5;
1662 			break;
1663 		case CL_FOCUS_TREEVIEW:
1664 			parentbg = colors->base[widget->state_type];
1665 			xoffset = -1.5;
1666 			yoffset = -1.5;
1667 			fill_alpha = 0.08;
1668 			focus_border = FALSE;
1669 			break;
1670 		case CL_FOCUS_TREEVIEW_DND:
1671 			parentbg = colors->base[widget->state_type];
1672 			break;
1673 		case CL_FOCUS_TREEVIEW_HEADER:
1674 			cairo_translate (cr, -1, 0);
1675 			break;
1676 		case CL_FOCUS_TREEVIEW_ROW:
1677 			parentbg = colors->base[widget->state_type];
1678 			xoffset = -2.5; /* hack to hide vertical lines */
1679 			yoffset = 0.5;
1680 			radius = CLAMP (radius, 0.0, 2.0);
1681 			border_alpha = 0.7;
1682 			focus_fill = FALSE;
1683 			break;
1684 		case CL_FOCUS_TAB:
1685 			/* In current GTK+ focus and active cannot happen together, but we are robust against it.
1686 			 * IF the application sets the state to ACTIVE while drawing the tabs focus. */
1687 			if (widget->focus && !widget->active)
1688 				return;
1689 			break;
1690 		case CL_FOCUS_SCALE:
1691 			break;
1692 		case CL_FOCUS_ICONVIEW:
1693 			break;
1694 		case CL_FOCUS_UNKNOWN:
1695 			/* Fallback to classic function, dots */
1696 			clearlooks_draw_focus (cr, colors, widget, focus, x, y, width, height);
1697 			return;
1698 			break;
1699 		default:
1700 			break;
1701 	};
1702 
1703 	cairo_translate (cr, x, y);
1704 	cairo_set_line_width (cr, focus->line_width);
1705 
1706 	ge_cairo_rounded_rectangle (cr, xoffset, yoffset, width-(xoffset*2), height-(yoffset*2), radius, widget->corners);
1707 
1708 	if (focus_fill)
1709 	{
1710 		cairo_pattern_t *pattern;
1711 
1712 		pattern = cairo_pattern_create_linear (0, 0, 0, height);
1713 		cairo_pattern_add_color_stop_rgba (pattern, 0.0, fill_shade1.r, fill_shade1.g, fill_shade1.b, fill_alpha);
1714 		cairo_pattern_add_color_stop_rgba (pattern, 0.5, fill_shade2.r, fill_shade2.g, fill_shade2.b, fill_alpha);
1715 		cairo_pattern_add_color_stop_rgba (pattern, 0.5, fill.r,        fill.g,        fill.b,        fill_alpha);
1716 		cairo_pattern_add_color_stop_rgba (pattern, 1.0, fill_shade3.r, fill_shade3.g, fill_shade3.b, fill_alpha);
1717 		cairo_set_source (cr, pattern);
1718 		cairo_fill_preserve (cr);
1719 
1720 		cairo_pattern_destroy (pattern);
1721 	}
1722 
1723 	if (focus_border)
1724 	{
1725 		clearlooks_set_mixed_color (cr, &parentbg, &border, border_alpha);
1726 		cairo_stroke (cr);
1727 	}
1728 
1729 	if (focus_shadow)
1730 	{
1731 		if (radius > 0)
1732 			radius++;
1733 		ge_cairo_rounded_rectangle (cr, xoffset-1, yoffset-1, width-(xoffset*2)+2, height-(yoffset*2)+2, radius, widget->corners);
1734 		clearlooks_set_mixed_color (cr, &parentbg, &fill, shadow_alpha);
1735 		cairo_stroke (cr);
1736 	}
1737 }
1738 
1739 void
clearlooks_register_style_gummy(ClearlooksStyleFunctions * functions,ClearlooksStyleConstants * constants)1740 clearlooks_register_style_gummy (ClearlooksStyleFunctions *functions, ClearlooksStyleConstants *constants)
1741 {
1742 	functions->draw_button             = clearlooks_gummy_draw_button;
1743 	functions->draw_entry              = clearlooks_gummy_draw_entry;
1744 	functions->draw_progressbar_trough = clearlooks_gummy_draw_progressbar_trough;
1745 	functions->draw_progressbar_fill   = clearlooks_gummy_draw_progressbar_fill;
1746 	functions->draw_scale_trough       = clearlooks_gummy_draw_scale_trough;
1747 	functions->draw_tab                = clearlooks_gummy_draw_tab;
1748 	functions->draw_separator          = clearlooks_gummy_draw_separator;
1749 	functions->draw_slider             = clearlooks_gummy_draw_slider;
1750 	functions->draw_slider_button      = clearlooks_gummy_draw_slider_button;
1751 	functions->draw_scrollbar_stepper  = clearlooks_gummy_draw_scrollbar_stepper;
1752 	functions->draw_scrollbar_slider   = clearlooks_gummy_draw_scrollbar_slider;
1753 	functions->draw_list_view_header   = clearlooks_gummy_draw_list_view_header;
1754 	functions->draw_toolbar            = clearlooks_gummy_draw_toolbar;
1755 	functions->draw_menuitem           = clearlooks_gummy_draw_menuitem;
1756 	functions->draw_menubaritem        = clearlooks_gummy_draw_menubaritem;
1757 	functions->draw_selected_cell      = clearlooks_gummy_draw_selected_cell;
1758 	functions->draw_statusbar          = clearlooks_gummy_draw_statusbar;
1759 	functions->draw_checkbox           = clearlooks_gummy_draw_checkbox;
1760 	functions->draw_radiobutton        = clearlooks_gummy_draw_radiobutton;
1761 	functions->draw_icon_view_item     = clearlooks_gummy_draw_icon_view_item;
1762 	functions->draw_focus              = clearlooks_gummy_draw_focus;
1763 
1764 	constants->topleft_highlight_shade = 1.3;
1765 	constants->topleft_highlight_alpha = 0.4;
1766 }
1767