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, ¶ms->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