1 /* Clearlooks - a cairo based GTK+ engine
2  * Copyright (C) 2007 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 Inverted style
22  *
23  */
24 
25 #include "clearlooks_draw.h"
26 #include "clearlooks_style.h"
27 #include "clearlooks_types.h"
28 
29 #include "support.h"
30 #include <ge-support.h>
31 
32 #include <cairo.h>
33 
34 
35 static void
clearlooks_set_border_gradient(cairo_t * cr,const CairoColor * color,double hilight,int width,int height)36 clearlooks_set_border_gradient (cairo_t *cr, const CairoColor *color, double hilight, int width, int height)
37 {
38 	cairo_pattern_t *pattern;
39 
40 	CairoColor bottom_shade;
41 	ge_shade_color (color, hilight, &bottom_shade);
42 
43 	pattern	= cairo_pattern_create_linear (0, 0, width, height);
44 	cairo_pattern_add_color_stop_rgb (pattern, 0, color->r, color->g, color->b);
45 	cairo_pattern_add_color_stop_rgb (pattern, 1, bottom_shade.r, bottom_shade.g, bottom_shade.b);
46 
47 	cairo_set_source (cr, pattern);
48 	cairo_pattern_destroy (pattern);
49 }
50 
51 static void
clearlooks_inverted_draw_button(cairo_t * cr,const ClearlooksColors * colors,const WidgetParameters * params,int x,int y,int width,int height)52 clearlooks_inverted_draw_button (cairo_t *cr,
53                         const ClearlooksColors *colors,
54                         const WidgetParameters *params,
55                         int x, int y, int width, int height)
56 {
57 	double xoffset = 0, yoffset = 0;
58 	double radius = params->radius;
59 	const CairoColor *fill = &colors->bg[params->state_type];
60 	const CairoColor *border_disabled = &colors->shade[4];
61 	CairoColor border_normal;
62 	CairoColor shadow;
63 
64 	ge_shade_color(&colors->shade[6], 1.05, &border_normal);
65 	ge_shade_color (&border_normal, 0.925, &shadow);
66 
67 	cairo_save (cr);
68 
69 	cairo_translate (cr, x, y);
70 	cairo_set_line_width (cr, 1.0);
71 
72 	if (params->xthickness == 3 || params->ythickness == 3)
73 	{
74 		if (params->xthickness == 3)
75 			xoffset = 1;
76 		if (params->ythickness == 3)
77 			yoffset = 1;
78 	}
79 
80 	radius = MIN (radius, MIN ((width - 2.0 - xoffset * 2.0) / 2.0, (height - 2.0 - yoffset * 2) / 2.0));
81 
82 	if (params->xthickness == 3 || params->ythickness == 3)
83 	{
84 		params->style_functions->draw_inset (cr, &params->parentbg, 0, 0, width, height, radius+1, params->corners);
85 	}
86 
87 	ge_cairo_rounded_rectangle (cr, xoffset+1, yoffset+1,
88 	                                     width-(xoffset*2)-2,
89 	                                     height-(yoffset*2)-2,
90 	                                     radius, params->corners);
91 
92 	if (!params->active)
93 	{
94 		cairo_pattern_t *pattern;
95 
96 		CairoColor top_shade, bottom_shade;
97 		ge_shade_color (fill, 0.95, &top_shade);
98 		ge_shade_color (fill, 1.05, &bottom_shade);
99 
100 		pattern	= cairo_pattern_create_linear (0, 0, 0, height);
101 		cairo_pattern_add_color_stop_rgb (pattern, 0.0, top_shade.r, top_shade.g, top_shade.b);
102 		cairo_pattern_add_color_stop_rgb (pattern, 1.0, bottom_shade.r, bottom_shade.g, bottom_shade.b);
103 		cairo_set_source (cr, pattern);
104 		cairo_fill (cr);
105 		cairo_pattern_destroy (pattern);
106 	}
107 	else
108 	{
109 		cairo_pattern_t *pattern;
110 
111 		ge_cairo_set_color (cr, fill);
112 		cairo_fill_preserve (cr);
113 
114 		pattern	= cairo_pattern_create_linear (0, 0, 0, height);
115 		cairo_pattern_add_color_stop_rgba (pattern, 0.0, shadow.r, shadow.g, shadow.b, 0.0);
116 		cairo_pattern_add_color_stop_rgba (pattern, 0.4, shadow.r, shadow.g, shadow.b, 0.0);
117 		cairo_pattern_add_color_stop_rgba (pattern, 1.0, shadow.r, shadow.g, shadow.b, 0.2);
118 		cairo_set_source (cr, pattern);
119 		cairo_fill_preserve (cr);
120 		cairo_pattern_destroy (pattern);
121 
122 		pattern	= cairo_pattern_create_linear (0, yoffset+1, 0, 3+yoffset);
123 		cairo_pattern_add_color_stop_rgba (pattern, 0.0, shadow.r, shadow.g, shadow.b, params->disabled ? 0.125 : 0.3);
124 		cairo_pattern_add_color_stop_rgba (pattern, 1.0, shadow.r, shadow.g, shadow.b, 0.0);
125 		cairo_set_source (cr, pattern);
126 		cairo_fill_preserve (cr);
127 		cairo_pattern_destroy (pattern);
128 
129 		pattern	= cairo_pattern_create_linear (xoffset+1, 0, 3+xoffset, 0);
130 		cairo_pattern_add_color_stop_rgba (pattern, 0.0, shadow.r, shadow.g, shadow.b, params->disabled ? 0.125 : 0.3);
131 		cairo_pattern_add_color_stop_rgba (pattern, 1.0, shadow.r, shadow.g, shadow.b, 0.0);
132 		cairo_set_source (cr, pattern);
133 		cairo_fill (cr);
134 		cairo_pattern_destroy (pattern);
135 	}
136 
137 	/* Drawing the border */
138 
139 	if (!params->active && params->is_default)
140 	{
141 		const CairoColor *l = &colors->shade[4];
142 		const CairoColor *d = &colors->shade[4];
143 		ge_cairo_set_color (cr, l);
144 		ge_cairo_stroke_rectangle (cr, 2.5, 2.5, width-5, height-5);
145 
146 		ge_cairo_set_color (cr, d);
147 		ge_cairo_stroke_rectangle (cr, 3.5, 3.5, width-7, height-7);
148 	}
149 
150 	if (params->disabled)
151 			ge_cairo_set_color (cr, border_disabled);
152 	else
153 		if (!params->active)
154 			clearlooks_set_border_gradient (cr, &border_normal, 1.32, 0, height);
155 		else
156 			ge_cairo_set_color (cr, &border_normal);
157 
158 	ge_cairo_rounded_rectangle (cr, xoffset + 0.5, yoffset + 0.5,
159                                   width-(xoffset*2)-1, height-(yoffset*2)-1,
160                                   radius, params->corners);
161 	cairo_stroke (cr);
162 
163 	/* Draw the "shadow" */
164 	if (!params->active)
165 	{
166 		/* Draw right shadow */
167 		cairo_move_to (cr, width-xoffset-1.5, yoffset + radius);
168 		cairo_line_to (cr, width-xoffset-1.5, height - yoffset - radius);
169 		cairo_set_source_rgba (cr, shadow.r, shadow.g, shadow.b, 0.1);
170 		cairo_stroke (cr);
171 
172 		/* Draw topleft shadow */
173 		params->style_functions->draw_top_left_highlight (cr, fill, params,
174 		                                                  xoffset+1, yoffset+1,
175 		                                                  width-2*(xoffset+1), height-2*(yoffset+1),
176 		                                                  radius, params->corners);
177 	}
178 	cairo_restore (cr);
179 }
180 
181 static void
clearlooks_inverted_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)182 clearlooks_inverted_draw_progressbar_fill (cairo_t *cr,
183                                   const ClearlooksColors *colors,
184                                   const WidgetParameters *params,
185                                   const ProgressBarParameters *progressbar,
186                                   int x, int y, int width, int height,
187                                   gint offset)
188 {
189 	boolean      is_horizontal = progressbar->orientation < 2;
190 	double       tile_pos = 0;
191 	double       stroke_width;
192 	double       radius;
193 	int          x_step;
194 
195 	cairo_pattern_t *pattern;
196 	CairoColor       bg_shade;
197 	CairoColor       border;
198 	CairoColor       shadow;
199 	CairoColor       top_shade;
200 
201 	radius = MAX (0, params->radius - params->xthickness);
202 
203 	cairo_save (cr);
204 
205 	if (!is_horizontal)
206 		ge_cairo_exchange_axis (cr, &x, &y, &width, &height);
207 
208 	if ((progressbar->orientation == CL_ORIENTATION_RIGHT_TO_LEFT) || (progressbar->orientation == CL_ORIENTATION_BOTTOM_TO_TOP))
209 		ge_cairo_mirror (cr, CR_MIRROR_HORIZONTAL, &x, &y, &width, &height);
210 
211 	/* Clamp the radius so that the _height_ fits ...  */
212 	radius = MIN (radius, height / 2.0);
213 
214 	stroke_width = height*2;
215 	x_step = (((float)stroke_width/10)*offset); /* This looks weird ... */
216 
217 	cairo_translate (cr, x, y);
218 
219 	cairo_save (cr);
220 	/* This is kind of nasty ... Clip twice from each side in case the length
221 	 * of the fill is smaller than twice the radius. */
222 	ge_cairo_rounded_rectangle (cr, 0, 0, width + radius, height, radius, CR_CORNER_TOPLEFT | CR_CORNER_BOTTOMLEFT);
223 	cairo_clip (cr);
224 	ge_cairo_rounded_rectangle (cr, -radius, 0, width + radius, height, radius, CR_CORNER_TOPRIGHT | CR_CORNER_BOTTOMRIGHT);
225 	cairo_clip (cr);
226 
227 
228 	ge_shade_color (&colors->spot[1], 1.05, &top_shade);
229 
230 	/* Draw the background gradient */
231 	ge_shade_color (&colors->spot[1], 0.925, &bg_shade);
232 	pattern = cairo_pattern_create_linear (0, 0, 0, height);
233 	cairo_pattern_add_color_stop_rgb (pattern, 0.0, bg_shade.r, bg_shade.g, bg_shade.b);
234 	cairo_pattern_add_color_stop_rgb (pattern, 0.5, top_shade.r, top_shade.g, top_shade.b);
235 	cairo_pattern_add_color_stop_rgb (pattern, 1.0, bg_shade.r, bg_shade.g, bg_shade.b);
236 	cairo_set_source (cr, pattern);
237 	cairo_paint (cr);
238 	cairo_pattern_destroy (pattern);
239 
240 	/* Draw the Strokes */
241 	while (stroke_width > 0 && tile_pos <= width+x_step)
242 	{
243 		cairo_move_to (cr, stroke_width/2-x_step, 0);
244 		cairo_line_to (cr, stroke_width-x_step,   0);
245 		cairo_line_to (cr, stroke_width/2-x_step, height);
246 		cairo_line_to (cr, -x_step, height);
247 
248 		cairo_translate (cr, stroke_width, 0);
249 		tile_pos += stroke_width;
250 	}
251 
252 	cairo_set_source_rgba (cr, colors->spot[2].r,
253 	                           colors->spot[2].g,
254 	                           colors->spot[2].b,
255 	                           0.15);
256 
257 	cairo_fill (cr);
258 	cairo_restore (cr); /* rounded clip region */
259 
260 	/* inner highlight border
261 	 * This is again kinda ugly. Draw once from each side, clipping away the other. */
262 	cairo_set_source_rgba (cr, colors->spot[0].r, colors->spot[0].g, colors->spot[0].b, 0.5);
263 
264 	/* left side */
265 	cairo_save (cr);
266 	cairo_rectangle (cr, 0, 0, width / 2, height);
267 	cairo_clip (cr);
268 
269 	if (progressbar->pulsing)
270 		ge_cairo_rounded_rectangle (cr, 1.5, 0.5, width + radius, height - 1, radius, CR_CORNER_TOPLEFT | CR_CORNER_BOTTOMLEFT);
271 	else
272 		ge_cairo_rounded_rectangle (cr, 0.5, 0.5, width + radius, height - 1, radius, CR_CORNER_TOPLEFT | CR_CORNER_BOTTOMLEFT);
273 
274 	cairo_stroke (cr);
275 	cairo_restore (cr); /* clip */
276 
277 	/* right side */
278 	cairo_save (cr);
279 	cairo_rectangle (cr, width / 2, 0, (width+1) / 2, height);
280 	cairo_clip (cr);
281 
282 	if (progressbar->value < 1.0 || progressbar->pulsing)
283 		ge_cairo_rounded_rectangle (cr, -1.5 - radius, 0.5, width + radius, height - 1, radius, CR_CORNER_TOPRIGHT | CR_CORNER_BOTTOMRIGHT);
284 	else
285 		ge_cairo_rounded_rectangle (cr, -0.5 - radius, 0.5, width + radius, height - 1, radius, CR_CORNER_TOPRIGHT | CR_CORNER_BOTTOMRIGHT);
286 
287 	cairo_stroke (cr);
288 	cairo_restore (cr); /* clip */
289 
290 
291 	/* Draw the dark lines and the shadow */
292 	cairo_save (cr);
293 	/* Again, this weird clip area. */
294 	ge_cairo_rounded_rectangle (cr, -1.0, 0, width + radius + 2.0, height, radius, CR_CORNER_TOPLEFT | CR_CORNER_BOTTOMLEFT);
295 	cairo_clip (cr);
296 	ge_cairo_rounded_rectangle (cr, -radius - 1.0, 0, width + radius + 2.0, height, radius, CR_CORNER_TOPRIGHT | CR_CORNER_BOTTOMRIGHT);
297 	cairo_clip (cr);
298 
299 	border = colors->spot[2];
300 	border.a = 0.5;
301 	shadow.r = 0.0;
302 	shadow.g = 0.0;
303 	shadow.b = 0.0;
304 	shadow.a = 0.1;
305 
306 	if (progressbar->pulsing)
307 	{
308 		/* At the beginning of the bar. */
309 		cairo_move_to (cr, 0.5 + radius, height + 0.5);
310 		ge_cairo_rounded_corner (cr, 0.5, height + 0.5, radius + 1, CR_CORNER_BOTTOMLEFT);
311 		ge_cairo_rounded_corner (cr, 0.5, -0.5, radius + 1, CR_CORNER_TOPLEFT);
312 		ge_cairo_set_color (cr, &border);
313 		cairo_stroke (cr);
314 
315 		cairo_move_to (cr, -0.5 + radius, height + 0.5);
316 		ge_cairo_rounded_corner (cr, -0.5, height + 0.5, radius + 1, CR_CORNER_BOTTOMLEFT);
317 		ge_cairo_rounded_corner (cr, -0.5, -0.5, radius + 1, CR_CORNER_TOPLEFT);
318 		ge_cairo_set_color (cr, &shadow);
319 		cairo_stroke (cr);
320 	}
321 	if (progressbar->value < 1.0 || progressbar->pulsing)
322 	{
323 		/* At the end of the bar. */
324 		cairo_move_to (cr, width - 0.5 - radius, -0.5);
325 		ge_cairo_rounded_corner (cr, width - 0.5, -0.5, radius + 1, CR_CORNER_TOPRIGHT);
326 		ge_cairo_rounded_corner (cr, width - 0.5, height + 0.5, radius + 1, CR_CORNER_BOTTOMRIGHT);
327 		ge_cairo_set_color (cr, &border);
328 		cairo_stroke (cr);
329 
330 		cairo_move_to (cr, width + 0.5 - radius, -0.5);
331 		ge_cairo_rounded_corner (cr, width + 0.5, -0.5, radius + 1, CR_CORNER_TOPRIGHT);
332 		ge_cairo_rounded_corner (cr, width + 0.5, height + 0.5, radius + 1, CR_CORNER_BOTTOMRIGHT);
333 		ge_cairo_set_color (cr, &shadow);
334 		cairo_stroke (cr);
335 	}
336 
337 	cairo_restore (cr);
338 
339 	cairo_restore (cr); /* rotation, mirroring */
340 }
341 
342 static void
clearlooks_inverted_draw_menuitem(cairo_t * cr,const ClearlooksColors * colors,const WidgetParameters * widget,int x,int y,int width,int height)343 clearlooks_inverted_draw_menuitem (cairo_t *cr,
344                           const ClearlooksColors          *colors,
345                           const WidgetParameters          *widget,
346                           int x, int y, int width, int height)
347 {
348 	const CairoColor *fill = &colors->spot[1];
349 	CairoColor fill_shade;
350 	CairoColor border = colors->spot[2];
351 	cairo_pattern_t *pattern;
352 
353 	ge_shade_color (&border, 1.05, &border);
354 	ge_shade_color (fill, 0.85, &fill_shade);
355 	cairo_set_line_width (cr, 1.0);
356 
357 	ge_cairo_rounded_rectangle (cr, x+0.5, y+0.5, width - 1, height - 1, widget->radius, widget->corners);
358 
359 	pattern = cairo_pattern_create_linear (x, y, x, y + height);
360 	cairo_pattern_add_color_stop_rgb (pattern, 0, fill_shade.r, fill_shade.g, fill_shade.b);
361 	cairo_pattern_add_color_stop_rgb (pattern, 1.0,   fill->r, fill->g, fill->b);
362 
363 	cairo_set_source (cr, pattern);
364 	cairo_fill_preserve  (cr);
365 	cairo_pattern_destroy (pattern);
366 
367 	ge_cairo_set_color (cr, &border);
368 	cairo_stroke (cr);
369 }
370 
371 static void
clearlooks_inverted_draw_menubaritem(cairo_t * cr,const ClearlooksColors * colors,const WidgetParameters * widget,int x,int y,int width,int height)372 clearlooks_inverted_draw_menubaritem (cairo_t *cr,
373                           const ClearlooksColors          *colors,
374                           const WidgetParameters          *widget,
375                           int x, int y, int width, int height)
376 {
377 	CairoColor *fill = (CairoColor*)&colors->spot[1];
378 	CairoColor fill_shade;
379 	CairoColor border = colors->spot[2];
380 	cairo_pattern_t *pattern;
381 
382 	ge_shade_color (&border, 1.05, &border);
383 	ge_shade_color (fill, 0.85, &fill_shade);
384 
385 	cairo_set_line_width (cr, 1.0);
386 	ge_cairo_rounded_rectangle (cr, x + 0.5, y + 0.5, width - 1, height, widget->radius, widget->corners);
387 
388 	pattern = cairo_pattern_create_linear (x, y, x, y + height);
389 	cairo_pattern_add_color_stop_rgb (pattern, 0, fill_shade.r, fill_shade.g, fill_shade.b);
390 	cairo_pattern_add_color_stop_rgb (pattern, 1.0,   fill->r, fill->g, fill->b);
391 
392 	cairo_set_source (cr, pattern);
393 	cairo_fill_preserve  (cr);
394 	cairo_pattern_destroy (pattern);
395 
396 	ge_cairo_set_color (cr, &border);
397 	cairo_stroke_preserve (cr);
398 }
399 
400 static void
clearlooks_inverted_draw_tab(cairo_t * cr,const ClearlooksColors * colors,const WidgetParameters * params,const TabParameters * tab,int x,int y,int width,int height)401 clearlooks_inverted_draw_tab (cairo_t *cr,
402                      const ClearlooksColors *colors,
403                      const WidgetParameters *params,
404                      const TabParameters    *tab,
405                      int x, int y, int width, int height)
406 {
407 	const CairoColor    *border1       = &colors->shade[6];
408 	const CairoColor    *border2       = &colors->shade[5];
409 	const CairoColor    *stripe_fill   = &colors->spot[1];
410 	const CairoColor    *stripe_border = &colors->spot[2];
411 	const CairoColor    *fill;
412 	CairoColor           hilight;
413 	CairoColor           shadow;
414 
415 	cairo_pattern_t     *pattern;
416 
417 	double               radius;
418 	double               strip_size;
419 	double               length;
420 
421 	radius = MIN (params->radius, MIN ((width - 2.0) / 2.0, (height - 2.0) / 2.0));
422 
423 	/* Set clip */
424 	cairo_rectangle      (cr, x, y, width, height);
425 	cairo_clip           (cr);
426 	cairo_new_path       (cr);
427 
428 	/* Translate and set line width */
429 	cairo_set_line_width (cr, 1.0);
430 	cairo_translate      (cr, x+0.5, y+0.5);
431 
432 
433 	/* Make the tabs slightly bigger than they should be, to create a gap */
434 	/* And calculate the strip size too, while you're at it */
435 	if (tab->gap_side == CL_GAP_TOP || tab->gap_side == CL_GAP_BOTTOM)
436 	{
437 		height += 3.0;
438 	 	length = height;
439 	 	strip_size = 2.0/height; /* 2 pixel high strip */
440 
441 		if (tab->gap_side == CL_GAP_TOP)
442 			cairo_translate (cr, 0.0, -3.0); /* gap at the other side */
443 	}
444 	else
445 	{
446 		width += 3.0;
447 	 	length = width;
448 	 	strip_size = 2.0/width;
449 
450 		if (tab->gap_side == CL_GAP_LEFT)
451 			cairo_translate (cr, -3.0, 0.0); /* gap at the other side */
452 	}
453 
454 	/* Set the fill color */
455 	fill = &colors->bg[params->state_type];
456 
457 	/* Set tab shape */
458 	ge_cairo_rounded_rectangle (cr, 0, 0, width-1, height-1,
459 	                            radius, params->corners);
460 
461 	/* Draw fill */
462 	ge_cairo_set_color (cr, fill);
463 	cairo_fill   (cr);
464 
465 	ge_shade_color (fill, 1.3, &hilight);
466 
467 	/* Draw highlight */
468 	if (!params->active)
469 	{
470 		ShadowParameters shadow;
471 
472 		shadow.shadow  = CL_SHADOW_OUT;
473 		shadow.corners = params->corners;
474 		/*
475 		clearlooks_draw_highlight_and_shade (cr, colors, &shadow,
476 		                                     width,
477 		                                     height, radius);*/
478 	}
479 
480 	if (params->active)
481 	{
482 		switch (tab->gap_side)
483 		{
484 			case CL_GAP_TOP:
485 				pattern = cairo_pattern_create_linear (0, height-2, 0, 0);
486 				break;
487 			case CL_GAP_BOTTOM:
488 				pattern = cairo_pattern_create_linear (0, 1, 0, height);
489 				break;
490 			case CL_GAP_LEFT:
491 				pattern = cairo_pattern_create_linear (width-2, 0, 1, 0);
492 				break;
493 			case CL_GAP_RIGHT:
494 				pattern = cairo_pattern_create_linear (1, 0, width-2, 0);
495 				break;
496 			default:
497 				pattern = NULL;
498 		}
499 
500 		ge_cairo_rounded_rectangle (cr, 0, 0, width-1, height-1, radius, params->corners);
501 
502 		ge_shade_color (fill, 0.92, &shadow);
503 
504 		cairo_pattern_add_color_stop_rgba  (pattern, 0.0,  				hilight.r, hilight.g, hilight.b, 0.4);
505 		cairo_pattern_add_color_stop_rgba  (pattern, 1.0/height,  hilight.r, hilight.g, hilight.b, 0.4);
506 		cairo_pattern_add_color_stop_rgb	(pattern, 1.0/height, 	fill->r,fill->g,fill->b);
507 		cairo_pattern_add_color_stop_rgb 	(pattern, 1.0, 					shadow.r,shadow.g,shadow.b);
508 		cairo_set_source (cr, pattern);
509 		cairo_fill (cr);
510 		cairo_pattern_destroy (pattern);
511 	}
512 	else
513 	{
514 		/* Draw shade */
515 		switch (tab->gap_side)
516 		{
517 			case CL_GAP_TOP:
518 				pattern = cairo_pattern_create_linear (0, height-2, 0, 0);
519 				break;
520 			case CL_GAP_BOTTOM:
521 				pattern = cairo_pattern_create_linear (0, 0, 0, height);
522 				break;
523 			case CL_GAP_LEFT:
524 				pattern = cairo_pattern_create_linear (width-2, 0, 0, 0);
525 				break;
526 			case CL_GAP_RIGHT:
527 				pattern = cairo_pattern_create_linear (0, 0, width, 0);
528 				break;
529 			default:
530 				pattern = NULL;
531 		}
532 
533 		ge_cairo_rounded_rectangle (cr, 0, 0, width-1, height-1, radius, params->corners);
534 
535 
536 		cairo_pattern_add_color_stop_rgb  (pattern, 0.0,        stripe_fill->r, stripe_fill->g, stripe_fill->b);
537 		cairo_pattern_add_color_stop_rgb  (pattern, strip_size, stripe_fill->r, stripe_fill->g, stripe_fill->b);
538 		cairo_pattern_add_color_stop_rgba (pattern, strip_size, hilight.r, hilight.g, hilight.b, 0.0);
539 		cairo_pattern_add_color_stop_rgba (pattern, 0.8,        hilight.r, hilight.g, hilight.b, 0.0);
540 		cairo_set_source (cr, pattern);
541 		cairo_fill (cr);
542 		cairo_pattern_destroy (pattern);
543 	}
544 
545 	ge_cairo_rounded_rectangle (cr, 0, 0, width-1, height-1, radius, params->corners);
546 
547 	if (params->active)
548 	{
549 		ge_cairo_set_color (cr, border2);
550 		cairo_stroke (cr);
551 	}
552 	else
553 	{
554 		switch (tab->gap_side)
555 		{
556 			case CL_GAP_TOP:
557 				pattern = cairo_pattern_create_linear (2, height-2, 2, 2);
558 				break;
559 			case CL_GAP_BOTTOM:
560 				pattern = cairo_pattern_create_linear (2, 2, 2, height);
561 				break;
562 			case CL_GAP_LEFT:
563 				pattern = cairo_pattern_create_linear (width-2, 2, 2, 2);
564 				break;
565 			case CL_GAP_RIGHT:
566 				pattern = cairo_pattern_create_linear (2, 2, width, 2);
567 				break;
568 			default:
569 				pattern = NULL;
570 		}
571 
572 		cairo_pattern_add_color_stop_rgb (pattern, 0.0,        stripe_border->r, stripe_border->g, stripe_border->b);
573 		cairo_pattern_add_color_stop_rgb (pattern, strip_size, stripe_border->r, stripe_border->g, stripe_border->b);
574 		cairo_pattern_add_color_stop_rgb (pattern, strip_size, border1->r,       border1->g,       border1->b);
575 		cairo_pattern_add_color_stop_rgb (pattern, 1.0,        border2->r,       border2->g,       border2->b);
576 		cairo_set_source (cr, pattern);
577 		cairo_stroke (cr);
578 		cairo_pattern_destroy (pattern);
579 	}
580 }
581 
582 static void
clearlooks_inverted_draw_slider(cairo_t * cr,const ClearlooksColors * colors,const WidgetParameters * params,int x,int y,int width,int height)583 clearlooks_inverted_draw_slider (cairo_t *cr,
584                         const ClearlooksColors *colors,
585                         const WidgetParameters *params,
586                         int x, int y, int width, int height)
587 {
588 	const CairoColor *border = &colors->shade[params->disabled ? 4 : 6];
589 	const CairoColor *spot   = &colors->spot[1];
590 	const CairoColor *fill   = &colors->shade[2];
591 	double radius = MIN (params->radius, MIN ((width - 1.0) / 2.0, (height - 1.0) / 2.0));
592 
593 	cairo_pattern_t *pattern;
594 
595 	cairo_set_line_width (cr, 1.0);
596 	cairo_translate      (cr, x, y);
597 
598 	if (params->disabled)
599 		border = &colors->shade[4];
600 	else if (params->prelight)
601 		border = &colors->spot[2];
602 	else
603 		border = &colors->shade[6];
604 
605 	/* fill the widget */
606 	cairo_rectangle (cr, 1.0, 1.0, width-2, height-2);
607 
608 	/* Fake light */
609 	if (!params->disabled)
610 	{
611 		const CairoColor *top = &colors->shade[2];
612 		const CairoColor *bot = &colors->shade[0];
613 
614 		pattern	= cairo_pattern_create_linear (0, 0, 0, height);
615 		cairo_pattern_add_color_stop_rgb (pattern, 0.0,  top->r, top->g, top->b);
616 		cairo_pattern_add_color_stop_rgb (pattern, 1.0,  bot->r, bot->g, bot->b);
617 		cairo_set_source (cr, pattern);
618 		cairo_fill (cr);
619 		cairo_pattern_destroy (pattern);
620 	}
621 	else
622 	{
623 		ge_cairo_set_color (cr, fill);
624 		cairo_rectangle    (cr, 1.0, 1.0, width-2, height-2);
625 		cairo_fill         (cr);
626 	}
627 
628 	/* Set the clip */
629 	cairo_save (cr);
630 	cairo_rectangle (cr, 1.0, 1.0, 6, height-2);
631 	cairo_rectangle (cr, width-7.0, 1.0, 6, height-2);
632 	cairo_clip_preserve (cr);
633 
634 	cairo_new_path (cr);
635 
636 	/* Draw the handles */
637 	ge_cairo_rounded_rectangle (cr, 1.0, 1.0, width-1, height-1, radius, params->corners);
638 	pattern = cairo_pattern_create_linear (0.5, 0.5, 0.5, 0.5+height);
639 
640 	if (params->prelight)
641 	{
642 		CairoColor highlight;
643 		ge_shade_color (spot, 1.5, &highlight);
644 		cairo_pattern_add_color_stop_rgb (pattern, 0.0, spot->r, spot->g, spot->b);
645 		cairo_pattern_add_color_stop_rgb (pattern, 1.0, highlight.r, highlight.g, highlight.b);
646 		cairo_set_source (cr, pattern);
647 	}
648 	else {
649 		CairoColor hilight;
650 		ge_shade_color (fill, 1.5, &hilight);
651 		cairo_set_source_rgba (cr, hilight.r, hilight.g, hilight.b, 0.5);
652 	}
653 
654 	cairo_fill (cr);
655 	cairo_pattern_destroy (pattern);
656 
657 	cairo_restore (cr);
658 
659 	/* Draw the border */
660 	ge_cairo_inner_rounded_rectangle (cr, 0, 0, width, height, radius, params->corners);
661 	if (params->prelight || params->disabled)
662 		ge_cairo_set_color (cr, border);
663 	else
664 		clearlooks_set_border_gradient (cr, border, 1.2, 0, height);
665 	cairo_stroke (cr);
666 
667 	/* Draw handle lines */
668 	if (width > 14)
669 	{
670 		cairo_move_to (cr, 6.5, 1.0);
671 		cairo_line_to (cr, 6.5, height-1);
672 
673 		cairo_move_to (cr, width-6.5, 1.0);
674 		cairo_line_to (cr, width-6.5, height-1);
675 
676 		cairo_set_line_width (cr, 1.0);
677 		cairo_set_source_rgba (cr, border->r,
678 		                           border->g,
679 		                           border->b,
680 	                                   0.3);
681 		cairo_stroke (cr);
682 	}
683 }
684 
685 static void
clearlooks_inverted_draw_list_view_header(cairo_t * cr,const ClearlooksColors * colors,const WidgetParameters * params,const ListViewHeaderParameters * header,int x,int y,int width,int height)686 clearlooks_inverted_draw_list_view_header (cairo_t *cr,
687                                   const ClearlooksColors          *colors,
688                                   const WidgetParameters          *params,
689                                   const ListViewHeaderParameters  *header,
690                                   int x, int y, int width, int height)
691 {
692 	const CairoColor *fill = &colors->bg[params->state_type];
693 	const CairoColor *border = &colors->shade[4];
694 	cairo_pattern_t *pattern;
695 	CairoColor hilight_header;
696 	CairoColor hilight;
697 	CairoColor shadow;
698 
699 	ge_shade_color (border, 1.5, &hilight);
700 	ge_shade_color (fill, 1.05, &hilight_header);
701 	ge_shade_color (fill, 0.95, &shadow);
702 
703 	cairo_translate (cr, x, y);
704 	cairo_set_line_width (cr, 1.0);
705 
706 	/* Draw highlight */
707 	if (header->order & CL_ORDER_FIRST)
708 	{
709 		cairo_move_to (cr, 0.5, height-1);
710 		cairo_line_to (cr, 0.5, 0.5);
711 	}
712 	else
713 		cairo_move_to (cr, 0.0, 0.5);
714 
715 	cairo_line_to (cr, width, 0.5);
716 
717 	ge_cairo_set_color (cr, &hilight);
718 	cairo_stroke (cr);
719 
720 	/* Draw bottom border */
721 	cairo_move_to (cr, 0.0, height-0.5);
722 	cairo_line_to (cr, width, height-0.5);
723 	ge_cairo_set_color (cr, border);
724 	cairo_stroke (cr);
725 
726 	/* Draw bottom shade */
727 	pattern = cairo_pattern_create_linear (0.0, 0, 0.0, height-1.0);
728 	cairo_pattern_add_color_stop_rgb     (pattern, 0.0, shadow.r, shadow.g, shadow.b);
729 	cairo_pattern_add_color_stop_rgb     (pattern, 1.0, hilight_header.r, hilight_header.g, hilight_header.b);
730 
731 	cairo_rectangle       (cr, 0, 1, width, height-2);
732 	cairo_set_source      (cr, pattern);
733 	cairo_fill            (cr);
734 	cairo_pattern_destroy (pattern);
735 
736 	/* Draw resize grip */
737 	if ((params->ltr && !(header->order & CL_ORDER_LAST)) ||
738 	    (!params->ltr && !(header->order & CL_ORDER_FIRST)) || header->resizable)
739 	{
740 		SeparatorParameters separator;
741 		separator.horizontal = FALSE;
742 
743 		if (params->ltr)
744 			params->style_functions->draw_separator (cr, colors, params, &separator,
745 			                                         width-1.5, 4.0, 2, height-8.0);
746 		else
747 			params->style_functions->draw_separator (cr, colors, params, &separator,
748 			                                         1.5, 4.0, 2, height-8.0);
749 	}
750 }
751 
752 
753 static void
clearlooks_inverted_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)754 clearlooks_inverted_draw_scrollbar_stepper (cairo_t *cr,
755                                    const ClearlooksColors           *colors,
756                                    const WidgetParameters           *widget,
757                                    const ScrollBarParameters        *scrollbar,
758                                    const ScrollBarStepperParameters *stepper,
759                                    int x, int y, int width, int height)
760 {
761 	CairoCorners corners = CR_CORNER_NONE;
762 	CairoColor border;
763 	CairoColor s1, s2, s3;
764 	cairo_pattern_t *pattern;
765 	double radius = MIN (widget->radius, MIN ((width - 2.0) / 2.0, (height - 2.0) / 2.0));
766 
767 	ge_shade_color(&colors->shade[6], 1.05, &border);
768 
769 	if (scrollbar->horizontal)
770 	{
771 		if (stepper->stepper == CL_STEPPER_A)
772 			corners = CR_CORNER_TOPLEFT | CR_CORNER_BOTTOMLEFT;
773 		else if (stepper->stepper == CL_STEPPER_D)
774 			corners = CR_CORNER_TOPRIGHT | CR_CORNER_BOTTOMRIGHT;
775 
776 		if (stepper->stepper == CL_STEPPER_B)
777 		{
778 			x -= 1;
779 			width += 1;
780 		}
781 		else if (stepper->stepper == CL_STEPPER_C)
782 		{
783 			width += 1;
784 		}
785 	}
786 	else
787 	{
788 		if (stepper->stepper == CL_STEPPER_A)
789 			corners = CR_CORNER_TOPLEFT | CR_CORNER_TOPRIGHT;
790 		else if (stepper->stepper == CL_STEPPER_D)
791 			corners = CR_CORNER_BOTTOMLEFT | CR_CORNER_BOTTOMRIGHT;
792 
793 		if (stepper->stepper == CL_STEPPER_B)
794 		{
795 			y -= 1;
796 			height += 1;
797 		}
798 		else if (stepper->stepper == CL_STEPPER_C)
799 		{
800 			height += 1;
801 		}
802 	}
803 
804 	cairo_translate (cr, x, y);
805 	cairo_set_line_width (cr, 1);
806 
807 	ge_cairo_rounded_rectangle (cr, 1, 1, width-2, height-2, radius, corners);
808 
809 	if (scrollbar->horizontal)
810 		pattern = cairo_pattern_create_linear (0, 0, 0, height);
811 	else
812 		pattern = cairo_pattern_create_linear (0, 0, width, 0);
813 
814 	s1 = colors->bg[widget->state_type];
815 	ge_shade_color(&s1, 0.95, &s2);
816 	ge_shade_color(&s1, 1.05, &s3);
817 
818 	cairo_pattern_add_color_stop_rgb(pattern, 0,    s2.r, s2.g, s2.b);
819 	cairo_pattern_add_color_stop_rgb(pattern, 1.0,  s3.r, s3.g, s3.b);
820 	cairo_set_source (cr, pattern);
821 	cairo_fill (cr);
822 	cairo_pattern_destroy (pattern);
823 
824 	widget->style_functions->draw_top_left_highlight (cr, &s1, widget, 1, 1, width-2, height-2, radius, corners);
825 
826 	ge_cairo_rounded_rectangle (cr, 0.5, 0.5, width-1, height-1, radius, corners);
827 	clearlooks_set_border_gradient (cr, &border, 1.2, (scrollbar->horizontal ? 0 : width), (scrollbar->horizontal ? height: 0));
828 	cairo_stroke (cr);
829 }
830 
831 static void
clearlooks_inverted_draw_scrollbar_slider(cairo_t * cr,const ClearlooksColors * colors,const WidgetParameters * widget,const ScrollBarParameters * scrollbar,int x,int y,int width,int height)832 clearlooks_inverted_draw_scrollbar_slider (cairo_t *cr,
833                                    const ClearlooksColors          *colors,
834                                    const WidgetParameters          *widget,
835                                    const ScrollBarParameters       *scrollbar,
836                                    int x, int y, int width, int height)
837 {
838 	if (scrollbar->junction & CL_JUNCTION_BEGIN)
839 	{
840 		if (scrollbar->horizontal)
841 		{
842 			x -= 1;
843 			width += 1;
844 		}
845 		else
846 		{
847 			y -= 1;
848 			height += 1;
849 		}
850 	}
851 	if (scrollbar->junction & CL_JUNCTION_END)
852 	{
853 		if (scrollbar->horizontal)
854 			width += 1;
855 		else
856 			height += 1;
857 	}
858 
859 	if (!scrollbar->horizontal)
860 		ge_cairo_exchange_axis (cr, &x, &y, &width, &height);
861 
862 	cairo_translate (cr, x, y);
863 
864 	if (scrollbar->has_color)
865 	{
866 		const CairoColor *border = &colors->shade[8];
867 		CairoColor  fill    = scrollbar->color;
868 		CairoColor  hilight;
869 		CairoColor  shade1, shade2, shade3;
870 		cairo_pattern_t *pattern;
871 
872 		if (widget->prelight)
873 			ge_shade_color (&fill, 1.1, &fill);
874 
875 		cairo_set_line_width (cr, 1);
876 
877 		ge_shade_color (&fill, 1.3, &hilight);
878 		ge_shade_color (&fill, 1.1, &shade1);
879 		ge_shade_color (&fill, 1.05, &shade2);
880 		ge_shade_color (&fill, 0.98, &shade3);
881 
882 		pattern = cairo_pattern_create_linear (1, 1, 1, height-2);
883 		cairo_pattern_add_color_stop_rgb (pattern, 0,    fill.r,  fill.g,  fill.b);
884 		cairo_pattern_add_color_stop_rgb (pattern, 0.5,  shade3.r, shade3.g, shade3.b);
885 		cairo_pattern_add_color_stop_rgb (pattern, 0.5,  shade2.r, shade2.g, shade2.b);
886 		cairo_pattern_add_color_stop_rgb (pattern, 1.0,  shade1.r, shade1.g, shade1.b);
887 		cairo_rectangle (cr, 1, 1, width-2, height-2);
888 		cairo_set_source (cr, pattern);
889 		cairo_fill (cr);
890 		cairo_pattern_destroy (pattern);
891 
892 		cairo_set_source_rgba (cr, hilight.r, hilight.g, hilight.b, 0.5);
893 		ge_cairo_stroke_rectangle (cr, 1.5, 1.5, width-3, height-3);
894 
895 		ge_cairo_set_color (cr, border);
896 		ge_cairo_stroke_rectangle (cr, 0.5, 0.5, width-1, height-1);
897 	}
898 	else
899 	{
900 		CairoColor border;
901 		CairoColor s1, s2, s3;
902 		cairo_pattern_t *pattern;
903 		int bar_x, i;
904 
905 		const CairoColor *dark  = &colors->shade[4];
906 		const CairoColor *light = &colors->shade[0];
907 
908 		ge_shade_color(&colors->shade[6], 1.05, &border);
909 
910 		pattern = cairo_pattern_create_linear(1, 1, 1, height-1);
911 
912 		s1 = colors->bg[widget->state_type];
913 		ge_shade_color(&s1, 0.95, &s2);
914 		ge_shade_color(&s1, 1.05, &s3);
915 
916 		cairo_pattern_add_color_stop_rgb(pattern, 0,    s2.r, s2.g, s2.b);
917 		cairo_pattern_add_color_stop_rgb(pattern, 1.0,  s3.r, s3.g, s3.b);
918 
919 		cairo_rectangle (cr, 1, 1, width-2, height-2);
920 		cairo_set_source(cr, pattern);
921 		cairo_fill(cr);
922 		cairo_pattern_destroy(pattern);
923 
924 		widget->style_functions->draw_top_left_highlight (cr, &s2, widget, 1, 1, width-2, height-2, 0, widget->corners);
925 
926 		clearlooks_set_border_gradient (cr, &border, 1.2, 0, height);
927 		ge_cairo_stroke_rectangle (cr, 0.5, 0.5, width-1, height-1);
928 
929 		/* draw handles */
930 		cairo_set_line_width (cr, 1);
931 
932 		bar_x = width/2 - 4;
933 		cairo_translate(cr, 0.5, 0.5);
934 		for (i=0; i<3; i++)
935 		{
936 			cairo_move_to (cr, bar_x, 4);
937 			cairo_line_to (cr, bar_x, height-5);
938 			ge_cairo_set_color (cr, dark);
939 			cairo_stroke (cr);
940 
941 			cairo_move_to (cr, bar_x+1, 4);
942 			cairo_line_to (cr, bar_x+1, height-5);
943 			ge_cairo_set_color (cr, light);
944 			cairo_stroke (cr);
945 
946 			bar_x += 3;
947 		}
948 	}
949 }
950 
951 static void
clearlooks_inverted_draw_selected_cell(cairo_t * cr,const ClearlooksColors * colors,const WidgetParameters * params,int x,int y,int width,int height)952 clearlooks_inverted_draw_selected_cell (cairo_t                  *cr,
953 	                       const ClearlooksColors   *colors,
954 	                       const WidgetParameters   *params,
955 	                       int x, int y, int width, int height)
956 {
957 	CairoColor upper_color;
958 	CairoColor lower_color;
959 	CairoColor border;
960 	cairo_pattern_t *pattern;
961 	cairo_save (cr);
962 
963 	cairo_translate (cr, x, y);
964 
965 	if (params->focus)
966 		upper_color = colors->base[params->state_type];
967 	else
968 		upper_color = colors->base[GTK_STATE_ACTIVE];
969 
970 	ge_shade_color(&upper_color, 0.9, &lower_color);
971 
972 	pattern = cairo_pattern_create_linear (0, 0, 0, height);
973 	cairo_pattern_add_color_stop_rgb (pattern, 0.0, lower_color.r,
974 	                                                lower_color.g,
975 	                                                lower_color.b);
976 	cairo_pattern_add_color_stop_rgb (pattern, 1.0, upper_color.r,
977 	                                                upper_color.g,
978 	                                                upper_color.b);
979 
980 
981 	cairo_set_source (cr, pattern);
982 	cairo_rectangle  (cr, 0, 0, width, height);
983 	cairo_fill       (cr);
984 	cairo_pattern_destroy (pattern);
985 
986 	ge_shade_color(&upper_color, 0.8, &border);
987 
988 	cairo_move_to  (cr, 0, 0.5);
989 	cairo_rel_line_to (cr, width, 0);
990 	cairo_move_to  (cr, 0, height-0.5);
991 	cairo_rel_line_to (cr, width, 0);
992 
993 	ge_cairo_set_color (cr, &border);
994 	cairo_stroke (cr);
995 
996 	cairo_restore (cr);
997 }
998 
999 void
clearlooks_register_style_inverted(ClearlooksStyleFunctions * functions,ClearlooksStyleConstants * constants)1000 clearlooks_register_style_inverted (ClearlooksStyleFunctions *functions, ClearlooksStyleConstants *constants)
1001 {
1002 	functions->draw_button            = clearlooks_inverted_draw_button;
1003 	functions->draw_slider            = clearlooks_inverted_draw_slider;
1004 	functions->draw_progressbar_fill  = clearlooks_inverted_draw_progressbar_fill;
1005 	functions->draw_menuitem          = clearlooks_inverted_draw_menuitem;
1006 	functions->draw_menubaritem       = clearlooks_inverted_draw_menubaritem;
1007 	functions->draw_tab               = clearlooks_inverted_draw_tab;
1008 	functions->draw_list_view_header  = clearlooks_inverted_draw_list_view_header;
1009 	functions->draw_scrollbar_stepper = clearlooks_inverted_draw_scrollbar_stepper;
1010 	functions->draw_scrollbar_slider  = clearlooks_inverted_draw_scrollbar_slider;
1011 	functions->draw_selected_cell     = clearlooks_inverted_draw_selected_cell;
1012 
1013 	constants->topleft_highlight_shade = 1.3;
1014 	constants->topleft_highlight_alpha = 0.7;
1015 }
1016 
1017