1 /* Clearlooks - a cairo based GTK+ engine
2 * Copyright (C) 2006 Benjamin Berg <benjamin@sipsolutions.net>
3 * Copyright (C) 2007-2008 Andrea Cimitan <andrea.cimitan@gmail.com>
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 *
19 * Project contact: <gnome-themes-list@gnome.org>
20 *
21 *
22 * This file defines the Clearlooks Glossy style
23 * Written by Andrea Cimitan <andrea.cimitan@gmail.com>
24 * and Benjamin Berg <benjamin@sipsolutions.net>
25 * Based on code by Richard Stellingwerff <remenic@gmail.com>
26 * and Daniel Borgmann <daniel.borgmann@gmail.com>
27 * from the ubuntulooks engine.
28 *
29 */
30
31
32 #include "clearlooks_draw.h"
33 #include "clearlooks_style.h"
34 #include "clearlooks_types.h"
35
36 #include "support.h"
37 #include <ge-support.h>
38
39 #include <cairo.h>
40
41
42 static void
clearlooks_draw_glossy_gradient(cairo_t * cr,double x,double y,int width,int height,const CairoColor * color,gboolean disabled,gboolean radius,CairoCorners corners)43 clearlooks_draw_glossy_gradient (cairo_t *cr,
44 double x, double y, int width, int height,
45 const CairoColor *color,
46 gboolean disabled, gboolean radius, CairoCorners corners)
47 {
48 CairoColor a, b, c, d;
49 cairo_pattern_t *pt;
50
51 ge_shade_color (color, disabled? 1.06 : 1.16, &a);
52 ge_shade_color (color, disabled? 1.02 : 1.08, &b);
53 ge_shade_color (color, disabled? 0.98 : 1.00, &c);
54 ge_shade_color (color, disabled? 1.02 : 1.08, &d);
55
56 pt = cairo_pattern_create_linear (x, y, x, y+height);
57 cairo_pattern_add_color_stop_rgb (pt, 0.0, a.r, a.g, a.b);
58 cairo_pattern_add_color_stop_rgb (pt, 0.5, b.r, b.g, b.b);
59 cairo_pattern_add_color_stop_rgb (pt, 0.5, c.r, c.g, c.b);
60 cairo_pattern_add_color_stop_rgb (pt, 1.0, d.r, d.g, d.b);
61
62 cairo_set_source (cr, pt);
63 ge_cairo_rounded_rectangle (cr, x, y, width, height, radius, corners);
64 cairo_fill (cr);
65
66 cairo_pattern_destroy (pt);
67 }
68
69 /* This draw_inset implementation only differes in the shades values from the
70 * default one. */
71 static void
clearlooks_glossy_draw_inset(cairo_t * cr,const CairoColor * bg_color,double x,double y,double width,double height,double radius,uint8 corners)72 clearlooks_glossy_draw_inset (cairo_t *cr,
73 const CairoColor *bg_color,
74 double x, double y, double width, double height,
75 double radius, uint8 corners)
76 {
77 CairoColor shadow;
78 CairoColor highlight;
79 double line_width;
80 double min = MIN (width, height);
81
82 line_width = cairo_get_line_width (cr);
83
84 /* not really sure of shading ratios... we will think */
85 ge_shade_color (bg_color, 0.93, &shadow);
86 ge_shade_color (bg_color, 1.07, &highlight);
87
88 /* highlight */
89 cairo_save (cr);
90
91 cairo_move_to (cr, x, y + height);
92 cairo_line_to (cr, x + min / 2.0, y + height - min / 2.0);
93 cairo_line_to (cr, x + width - min / 2.0, y + min / 2.0);
94 cairo_line_to (cr, x + width, y);
95 cairo_line_to (cr, x, y);
96 cairo_close_path (cr);
97
98 cairo_clip (cr);
99
100 ge_cairo_rounded_rectangle (cr, x + line_width / 2.0, y + line_width / 2.0,
101 width - line_width, height - line_width,
102 radius, corners);
103
104 ge_cairo_set_color (cr, &shadow);
105 cairo_stroke (cr);
106
107 cairo_restore (cr);
108
109 /* shadow */
110 cairo_save (cr);
111
112 cairo_move_to (cr, x, y + height);
113 cairo_line_to (cr, x + min / 2.0, y + height - min / 2.0);
114 cairo_line_to (cr, x + width - min / 2.0, y + min / 2.0);
115 cairo_line_to (cr, x + width, y);
116 cairo_line_to (cr, x + width, y + height);
117 cairo_close_path (cr);
118
119 cairo_clip (cr);
120
121 ge_cairo_rounded_rectangle (cr, x + line_width / 2.0, y + line_width / 2.0,
122 width - line_width, height - line_width,
123 radius, corners);
124
125 ge_cairo_set_color (cr, &highlight);
126 cairo_stroke (cr);
127
128 cairo_restore (cr);
129 }
130
131 static void
clearlooks_glossy_draw_light_inset(cairo_t * cr,const CairoColor * bg_color,double x,double y,double w,double h,double radius,uint8 corners)132 clearlooks_glossy_draw_light_inset (cairo_t *cr,
133 const CairoColor *bg_color,
134 double x, double y, double w, double h,
135 double radius, uint8 corners)
136 {
137 CairoColor shadow;
138 CairoColor highlight;
139
140 /* not really sure of shading ratios... we will think */
141 ge_shade_color (bg_color, 0.95, &shadow);
142 ge_shade_color (bg_color, 1.05, &highlight);
143
144 /* highlight */
145 cairo_move_to (cr, x + w + (radius * -0.2928932188), y - (radius * -0.2928932188)); /* 0.2928932... 1-sqrt(2)/2 gives middle of curve */
146
147 if (corners & CR_CORNER_TOPRIGHT)
148 cairo_arc (cr, x + w - radius, y + radius, radius, G_PI * 1.75, G_PI * 2);
149 else
150 cairo_line_to (cr, x + w, y);
151
152 if (corners & CR_CORNER_BOTTOMRIGHT)
153 cairo_arc (cr, x + w - radius, y + h - radius, radius, 0, G_PI * 0.5);
154 else
155 cairo_line_to (cr, x + w, y + h);
156
157 if (corners & CR_CORNER_BOTTOMLEFT)
158 cairo_arc (cr, x + radius, y + h - radius, radius, G_PI * 0.5, G_PI * 0.75);
159 else
160 cairo_line_to (cr, x, y + h);
161
162 ge_cairo_set_color (cr, &highlight);
163 cairo_stroke (cr);
164
165 /* shadow */
166 cairo_move_to (cr, x + (radius * 0.2928932188), y + h + (radius * -0.2928932188));
167
168 if (corners & CR_CORNER_BOTTOMLEFT)
169 cairo_arc (cr, x + radius, y + h - radius, radius, G_PI * 0.75, G_PI);
170 else
171 cairo_line_to (cr, x, y + h);
172
173 if (corners & CR_CORNER_TOPLEFT)
174 cairo_arc (cr, x + radius, y + radius, radius, G_PI, G_PI * 1.5);
175 else
176 cairo_line_to (cr, x, y);
177
178 if (corners & CR_CORNER_TOPRIGHT)
179 cairo_arc (cr, x + w - radius, y + radius, radius, G_PI * 1.5, G_PI * 1.75);
180 else
181 cairo_line_to (cr, x + w, y);
182
183 ge_cairo_set_color (cr, &shadow);
184 cairo_stroke (cr);
185 }
186
187 /* This function currently assumes that the input is translated by 0.5px! */
188 static void
clearlooks_glossy_draw_highlight_and_shade(cairo_t * cr,const CairoColor * bg_color,const ShadowParameters * params,int width,int height,gdouble radius)189 clearlooks_glossy_draw_highlight_and_shade (cairo_t *cr,
190 const CairoColor *bg_color,
191 const ShadowParameters *params,
192 int width, int height, gdouble radius)
193 {
194 CairoColor shadow;
195 CairoColor highlight;
196 uint8 corners = params->corners;
197 double x = 1.0;
198 double y = 1.0;
199
200 /* not really sure of shading ratios... we will think */
201 ge_shade_color (bg_color, 0.8, &shadow);
202 ge_shade_color (bg_color, 1.2, &highlight);
203
204 cairo_save (cr);
205
206 /* Top/Left highlight */
207 if (corners & CR_CORNER_BOTTOMLEFT)
208 cairo_move_to (cr, x, y+height-radius);
209 else
210 cairo_move_to (cr, x, y+height);
211
212 ge_cairo_rounded_corner (cr, x, y, radius, corners & CR_CORNER_TOPLEFT);
213
214 if (corners & CR_CORNER_TOPRIGHT)
215 cairo_line_to (cr, x+width-radius, y);
216 else
217 cairo_line_to (cr, x+width, y);
218
219 if (params->shadow & CL_SHADOW_OUT)
220 cairo_set_source_rgba (cr, highlight.r, highlight.g, highlight.b, 0.5);
221 else
222 cairo_set_source_rgba (cr, shadow.r, shadow.g, shadow.b, 0.5);
223
224 cairo_stroke (cr);
225
226 /* Bottom/Right highlight -- this includes the corners */
227 cairo_move_to (cr, x+width-radius, y); /* topright and by radius to the left */
228 ge_cairo_rounded_corner (cr, x+width, y, radius, corners & CR_CORNER_TOPRIGHT);
229 ge_cairo_rounded_corner (cr, x+width, y+height, radius, corners & CR_CORNER_BOTTOMRIGHT);
230 ge_cairo_rounded_corner (cr, x, y+height, radius, corners & CR_CORNER_BOTTOMLEFT);
231
232 if (params->shadow & CL_SHADOW_OUT)
233 cairo_set_source_rgba (cr, shadow.r, shadow.g, shadow.b, 0.5);
234 else
235 cairo_set_source_rgba (cr, highlight.r, highlight.g, highlight.b, 0.5);
236
237 cairo_stroke (cr);
238
239 cairo_restore (cr);
240 }
241
242 static void
clearlooks_glossy_draw_button(cairo_t * cr,const ClearlooksColors * colors,const WidgetParameters * params,int x,int y,int width,int height)243 clearlooks_glossy_draw_button (cairo_t *cr,
244 const ClearlooksColors *colors,
245 const WidgetParameters *params,
246 int x, int y, int width, int height)
247 {
248 double xoffset = 0, yoffset = 0;
249 CairoColor fill = colors->bg[params->state_type];
250 CairoColor border_normal = colors->shade[6];
251 CairoColor border_disabled = colors->shade[4];
252 double radius;
253
254 cairo_pattern_t *pattern;
255
256 cairo_save (cr);
257 cairo_translate (cr, x, y);
258 cairo_set_line_width (cr, 1.0);
259
260 /* Shadows and shadow */
261 if (params->xthickness == 3 || params->ythickness == 3)
262 {
263 if (params->xthickness == 3)
264 xoffset = 1;
265 if (params->ythickness == 3)
266 yoffset = 1;
267 }
268
269 radius = MIN (params->radius, MIN ((width - 2.0 - 2*xoffset) / 2.0, (height - 2.0 - 2*yoffset) / 2.0));
270
271 if (params->xthickness == 3 || params->ythickness == 3)
272 {
273 /* if (params->enable_shadow && !params->active && !params->disabled) */
274 if (!params->active && (params->prelight || params->enable_shadow))
275 {
276 /* shadow becomes a shadow to have 3d prelight buttons :) */
277 CairoColor shadow;
278
279 radius = MIN (params->radius, MIN ((width - 2.0 - 2*xoffset) / 2.0 - 1.0, (height - 2.0 - 2*yoffset) / 2.0 - 1.0));
280
281 ge_cairo_rounded_rectangle (cr, 0.5, 0.5, width-1, height-1, radius+1, params->corners);
282 ge_shade_color (¶ms->parentbg, 0.96, &shadow);
283 ge_cairo_set_color (cr, &shadow);
284 cairo_stroke (cr);
285
286 ge_cairo_rounded_rectangle (cr, 1.5, 1.5, width-2, height-2, radius+1, params->corners);
287 ge_shade_color (¶ms->parentbg, 0.92, &shadow);
288 ge_cairo_set_color (cr, &shadow);
289 cairo_stroke (cr);
290 }
291 else
292 {
293 if (!(params->disabled))
294 params->style_functions->draw_inset (cr, ¶ms->parentbg, 0, 0, width, height, params->radius+1, params->corners);
295 else
296 /*Draw a lighter inset */
297 clearlooks_glossy_draw_light_inset (cr, ¶ms->parentbg, 0, 0, width, height, params->radius+1, params->corners);
298 }
299 }
300
301 clearlooks_draw_glossy_gradient (cr, xoffset+1, yoffset+1,
302 width-(xoffset*2)-2, height-(yoffset*2)-2,
303 &fill, params->disabled, radius, params->corners);
304
305 /* Pressed button shadow */
306 if (params->active)
307 {
308 CairoColor shadow;
309 ge_shade_color (&fill, 0.92, &shadow);
310
311 cairo_save (cr);
312
313 ge_cairo_rounded_rectangle (cr, xoffset+1, yoffset+1, width-(xoffset*2)-2, height, radius, params->corners & (CR_CORNER_TOPLEFT | CR_CORNER_TOPRIGHT | CR_CORNER_BOTTOMLEFT));
314 cairo_clip (cr);
315 cairo_rectangle (cr, xoffset+1, yoffset+1, width-(xoffset*2)-2, 3);
316
317 pattern = cairo_pattern_create_linear (xoffset+1, yoffset+1, xoffset+1, yoffset+4);
318 cairo_pattern_add_color_stop_rgba (pattern, 0.0, shadow.r, shadow.g, shadow.b, 0.58);
319 cairo_pattern_add_color_stop_rgba (pattern, 1.0, shadow.r, shadow.g, shadow.b, 0.0);
320 cairo_set_source (cr, pattern);
321 cairo_fill (cr);
322 cairo_pattern_destroy (pattern);
323
324 cairo_rectangle (cr, xoffset+1, yoffset+1, 3, height-(yoffset*2)-2);
325
326 pattern = cairo_pattern_create_linear (xoffset+1, yoffset+1, xoffset+4, yoffset+1);
327 cairo_pattern_add_color_stop_rgba (pattern, 0.0, shadow.r, shadow.g, shadow.b, 0.58);
328 cairo_pattern_add_color_stop_rgba (pattern, 1.0, shadow.r, shadow.g, shadow.b, 0.0);
329 cairo_set_source (cr, pattern);
330 cairo_fill (cr);
331 cairo_pattern_destroy (pattern);
332
333 cairo_restore (cr);
334 }
335
336 /* Default button highlight */
337 if (params->is_default && !params->active && !params->disabled)
338 {
339 const CairoColor *shadow = &colors->spot[0];
340 double hh = (height-5)/2.0 + 1;
341
342 cairo_rectangle (cr, 3.5, 3.5, width-7, height-7);
343 ge_cairo_set_color (cr, shadow);
344 cairo_stroke (cr);
345
346 shadow = &colors->spot[0];
347 cairo_move_to (cr, 2.5, 2.5+hh); cairo_rel_line_to (cr, 0, -hh);
348 cairo_rel_line_to (cr, width-5, 0); cairo_rel_line_to (cr, 0, hh);
349 ge_cairo_set_color (cr, shadow);
350 cairo_stroke (cr);
351
352 hh--;
353
354 shadow = &colors->spot[1];
355 cairo_move_to (cr, 2.5, 2.5+hh); cairo_rel_line_to (cr, 0, hh);
356 cairo_rel_line_to (cr, width-5, 0); cairo_rel_line_to (cr, 0, -hh);
357 ge_cairo_set_color (cr, shadow);
358 cairo_stroke (cr);
359 }
360
361 /* Border */
362 if (params->is_default || (params->prelight && params->enable_shadow))
363 border_normal = colors->spot[2];
364 /* ge_mix_color (&border_normal, &colors->spot[2], 0.5, &border_normal); */
365 if (params->disabled)
366 ge_cairo_set_color (cr, &border_disabled);
367 else
368 clearlooks_set_mixed_color (cr, &border_normal, &fill, 0.2);
369 ge_cairo_rounded_rectangle (cr, xoffset + 0.5, yoffset + 0.5,
370 width-(xoffset*2)-1, height-(yoffset*2)-1,
371 radius, params->corners);
372 cairo_stroke (cr);
373 cairo_restore (cr);
374 }
375
376 static void
clearlooks_glossy_draw_progressbar_trough(cairo_t * cr,const ClearlooksColors * colors,const WidgetParameters * params,int x,int y,int width,int height)377 clearlooks_glossy_draw_progressbar_trough (cairo_t *cr,
378 const ClearlooksColors *colors,
379 const WidgetParameters *params,
380 int x, int y, int width, int height)
381 {
382 const CairoColor *border = &colors->shade[6];
383 CairoColor shadow;
384 cairo_pattern_t *pattern;
385 double radius = MIN (params->radius, MIN ((height-2.0) / 2.0, (width-2.0) / 2.0));
386
387 cairo_save (cr);
388
389 cairo_set_line_width (cr, 1.0);
390
391 /* Create trough box */
392 ge_cairo_rounded_rectangle (cr, x+1, y+1, width-2, height-2, radius, params->corners);
393 ge_cairo_set_color (cr, &colors->shade[2]);
394 cairo_fill (cr);
395
396 /* Draw border */
397 ge_cairo_rounded_rectangle (cr, x+0.5, y+0.5, width-1, height-1, radius, params->corners);
398 clearlooks_set_mixed_color (cr, border, &colors->shade[2], 0.3);
399 cairo_stroke (cr);
400
401 /* clip the corners of the shadows */
402 ge_cairo_rounded_rectangle (cr, x+1, y+1, width-2, height-2, radius, params->corners);
403 cairo_clip (cr);
404
405 ge_shade_color (border, 0.92, &shadow);
406
407 /* Top shadow */
408 cairo_rectangle (cr, x+1, y+1, width-2, 4);
409 pattern = cairo_pattern_create_linear (x, y, x, y+4);
410 cairo_pattern_add_color_stop_rgba (pattern, 0.0, shadow.r, shadow.g, shadow.b, 0.3);
411 cairo_pattern_add_color_stop_rgba (pattern, 1.0, shadow.r, shadow.g, shadow.b, 0.);
412 cairo_set_source (cr, pattern);
413 cairo_fill (cr);
414 cairo_pattern_destroy (pattern);
415
416 /* Left shadow */
417 cairo_rectangle (cr, x+1, y+1, 4, height-2);
418 pattern = cairo_pattern_create_linear (x, y, x+4, y);
419 cairo_pattern_add_color_stop_rgba (pattern, 0.0, shadow.r, shadow.g, shadow.b, 0.3);
420 cairo_pattern_add_color_stop_rgba (pattern, 1.0, shadow.r, shadow.g, shadow.b, 0.);
421 cairo_set_source (cr, pattern);
422 cairo_fill (cr);
423 cairo_pattern_destroy (pattern);
424
425 cairo_restore (cr);
426 }
427
428 static void
clearlooks_glossy_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)429 clearlooks_glossy_draw_progressbar_fill (cairo_t *cr,
430 const ClearlooksColors *colors,
431 const WidgetParameters *params,
432 const ProgressBarParameters *progressbar,
433 int x, int y, int width, int height,
434 gint offset)
435 {
436 boolean is_horizontal = progressbar->orientation < 2;
437 double tile_pos = 0;
438 double stroke_width;
439 double radius;
440 int x_step;
441
442 cairo_pattern_t *pattern;
443 CairoColor a;
444 CairoColor b;
445 CairoColor e;
446 CairoColor border;
447 CairoColor shadow;
448
449 radius = MAX (0, params->radius - params->xthickness);
450
451 cairo_save (cr);
452
453 if (!is_horizontal)
454 ge_cairo_exchange_axis (cr, &x, &y, &width, &height);
455
456 if ((progressbar->orientation == CL_ORIENTATION_RIGHT_TO_LEFT) || (progressbar->orientation == CL_ORIENTATION_BOTTOM_TO_TOP))
457 ge_cairo_mirror (cr, CR_MIRROR_HORIZONTAL, &x, &y, &width, &height);
458
459 /* Clamp the radius so that the _height_ fits ... */
460 radius = MIN (radius, height / 2.0);
461
462 stroke_width = height*2;
463 x_step = (((float)stroke_width/10)*offset); /* This looks weird ... */
464
465 cairo_translate (cr, x, y);
466
467 cairo_save (cr);
468 /* This is kind of nasty ... Clip twice from each side in case the length
469 * of the fill is smaller than twice the radius. */
470 ge_cairo_rounded_rectangle (cr, 0, 0, width + radius, height, radius, CR_CORNER_TOPLEFT | CR_CORNER_BOTTOMLEFT);
471 cairo_clip (cr);
472 ge_cairo_rounded_rectangle (cr, -radius, 0, width + radius, height, radius, CR_CORNER_TOPRIGHT | CR_CORNER_BOTTOMRIGHT);
473 cairo_clip (cr);
474
475 /* Draw the background gradient */
476 ge_shade_color (&colors->spot[1], 1.16, &a);
477 ge_shade_color (&colors->spot[1], 1.08, &b);
478 ge_shade_color (&colors->spot[1], 1.08, &e);
479 pattern = cairo_pattern_create_linear (0, 0, 0, height);
480 cairo_pattern_add_color_stop_rgb (pattern, 0.0, a.r, a.g, a.b);
481 cairo_pattern_add_color_stop_rgb (pattern, 0.5, b.r, b.g, b.b);
482 cairo_pattern_add_color_stop_rgb (pattern, 0.5, colors->spot[1].r, colors->spot[1].g, colors->spot[1].b);
483 cairo_pattern_add_color_stop_rgb (pattern, 1.0, e.r, e.g, e.b);
484 cairo_set_source (cr, pattern);
485 cairo_paint (cr);
486 cairo_pattern_destroy (pattern);
487
488 /* Draw the Strokes */
489 while (stroke_width > 0 && tile_pos <= width+x_step)
490 {
491 cairo_move_to (cr, stroke_width/2-x_step, 0);
492 cairo_line_to (cr, stroke_width-x_step, 0);
493 cairo_line_to (cr, stroke_width/2-x_step, height);
494 cairo_line_to (cr, -x_step, height);
495
496 cairo_translate (cr, stroke_width, 0);
497 tile_pos += stroke_width;
498 }
499
500 cairo_set_source_rgba (cr, colors->spot[2].r,
501 colors->spot[2].g,
502 colors->spot[2].b,
503 0.15);
504
505 cairo_fill (cr);
506 cairo_restore (cr); /* rounded clip region */
507
508 /* inner highlight border
509 * This is again kinda ugly. Draw once from each side, clipping away the other. */
510 cairo_set_source_rgba (cr, colors->spot[0].r, colors->spot[0].g, colors->spot[0].b, 0.3);
511
512 /* left side */
513 cairo_save (cr);
514 cairo_rectangle (cr, 0, 0, width / 2, height);
515 cairo_clip (cr);
516
517 if (progressbar->pulsing)
518 ge_cairo_rounded_rectangle (cr, 1.5, 0.5, width + radius, height - 1, radius, CR_CORNER_TOPLEFT | CR_CORNER_BOTTOMLEFT);
519 else
520 ge_cairo_rounded_rectangle (cr, 0.5, 0.5, width + radius, height - 1, radius, CR_CORNER_TOPLEFT | CR_CORNER_BOTTOMLEFT);
521
522 cairo_stroke (cr);
523 cairo_restore (cr); /* clip */
524
525 /* right side */
526 cairo_save (cr);
527 cairo_rectangle (cr, width / 2, 0, (width+1) / 2, height);
528 cairo_clip (cr);
529
530 if (progressbar->value < 1.0 || progressbar->pulsing)
531 ge_cairo_rounded_rectangle (cr, -1.5 - radius, 0.5, width + radius, height - 1, radius, CR_CORNER_TOPRIGHT | CR_CORNER_BOTTOMRIGHT);
532 else
533 ge_cairo_rounded_rectangle (cr, -0.5 - radius, 0.5, width + radius, height - 1, radius, CR_CORNER_TOPRIGHT | CR_CORNER_BOTTOMRIGHT);
534
535 cairo_stroke (cr);
536 cairo_restore (cr); /* clip */
537
538
539 /* Draw the dark lines and the shadow */
540 cairo_save (cr);
541 /* Again, this weird clip area. */
542 ge_cairo_rounded_rectangle (cr, -1.0, 0, width + radius + 2.0, height, radius, CR_CORNER_TOPLEFT | CR_CORNER_BOTTOMLEFT);
543 cairo_clip (cr);
544 ge_cairo_rounded_rectangle (cr, -radius - 1.0, 0, width + radius + 2.0, height, radius, CR_CORNER_TOPRIGHT | CR_CORNER_BOTTOMRIGHT);
545 cairo_clip (cr);
546
547 border = colors->spot[2];
548 border.a = 0.5;
549 ge_shade_color (&colors->shade[6], 0.92, &shadow);
550 shadow.a = 0.2;
551
552 if (progressbar->pulsing)
553 {
554 /* At the beginning of the bar. */
555 cairo_move_to (cr, 0.5 + radius, height + 0.5);
556 ge_cairo_rounded_corner (cr, 0.5, height + 0.5, radius + 1, CR_CORNER_BOTTOMLEFT);
557 ge_cairo_rounded_corner (cr, 0.5, -0.5, radius + 1, CR_CORNER_TOPLEFT);
558 ge_cairo_set_color (cr, &border);
559 cairo_stroke (cr);
560
561 cairo_move_to (cr, -0.5 + radius, height + 0.5);
562 ge_cairo_rounded_corner (cr, -0.5, height + 0.5, radius + 1, CR_CORNER_BOTTOMLEFT);
563 ge_cairo_rounded_corner (cr, -0.5, -0.5, radius + 1, CR_CORNER_TOPLEFT);
564 ge_cairo_set_color (cr, &shadow);
565 cairo_stroke (cr);
566 }
567 if (progressbar->value < 1.0 || progressbar->pulsing)
568 {
569 /* At the end of the bar. */
570 cairo_move_to (cr, width - 0.5 - radius, -0.5);
571 ge_cairo_rounded_corner (cr, width - 0.5, -0.5, radius + 1, CR_CORNER_TOPRIGHT);
572 ge_cairo_rounded_corner (cr, width - 0.5, height + 0.5, radius + 1, CR_CORNER_BOTTOMRIGHT);
573 ge_cairo_set_color (cr, &border);
574 cairo_stroke (cr);
575
576 cairo_move_to (cr, width + 0.5 - radius, -0.5);
577 ge_cairo_rounded_corner (cr, width + 0.5, -0.5, radius + 1, CR_CORNER_TOPRIGHT);
578 ge_cairo_rounded_corner (cr, width + 0.5, height + 0.5, radius + 1, CR_CORNER_BOTTOMRIGHT);
579 ge_cairo_set_color (cr, &shadow);
580 cairo_stroke (cr);
581 }
582
583 cairo_restore (cr);
584
585 cairo_restore (cr); /* rotation, mirroring */
586 }
587
588 static void
clearlooks_glossy_scale_draw_gradient(cairo_t * cr,const CairoColor * c1,const CairoColor * c2,const CairoColor * c3,int x,int y,int width,int height,boolean horizontal)589 clearlooks_glossy_scale_draw_gradient (cairo_t *cr,
590 const CairoColor *c1,
591 const CairoColor *c2,
592 const CairoColor *c3,
593 int x, int y, int width, int height,
594 boolean horizontal)
595 {
596 cairo_pattern_t *pattern;
597
598 pattern = cairo_pattern_create_linear (0.5, 0.5, horizontal ? 0.5 : width + 1, horizontal ? height + 1 : 0.5);
599 cairo_pattern_add_color_stop_rgb (pattern, 0.0, c1->r, c1->g, c1->b);
600 cairo_pattern_add_color_stop_rgb (pattern, 1.0, c2->r, c2->g, c2->b);
601
602 cairo_rectangle (cr, x, y, width, height);
603 cairo_set_source (cr, pattern);
604 cairo_fill (cr);
605 cairo_pattern_destroy (pattern);
606
607 clearlooks_set_mixed_color (cr, c3, c1, 0.3);
608 ge_cairo_inner_rectangle (cr, x, y, width, height);
609 cairo_stroke (cr);
610 }
611
612 #define TROUGH_SIZE 7
613 static void
clearlooks_glossy_draw_scale_trough(cairo_t * cr,const ClearlooksColors * colors,const WidgetParameters * params,const SliderParameters * slider,int x,int y,int width,int height)614 clearlooks_glossy_draw_scale_trough (cairo_t *cr,
615 const ClearlooksColors *colors,
616 const WidgetParameters *params,
617 const SliderParameters *slider,
618 int x, int y, int width, int height)
619 {
620 int trough_width, trough_height;
621 double translate_x, translate_y;
622
623 cairo_save (cr);
624
625 if (slider->horizontal)
626 {
627 trough_width = width;
628 trough_height = TROUGH_SIZE;
629
630 translate_x = x;
631 translate_y = y + (height/2) - (TROUGH_SIZE/2);
632 }
633 else
634 {
635 trough_width = TROUGH_SIZE;
636 trough_height = height;
637
638 translate_x = x + (width/2) - (TROUGH_SIZE/2);
639 translate_y = y;
640 }
641
642 cairo_set_line_width (cr, 1.0);
643 cairo_translate (cr, translate_x, translate_y);
644
645 if (!slider->fill_level)
646 params->style_functions->draw_inset (cr, ¶ms->parentbg, 0, 0, trough_width, trough_height, 0, 0);
647
648 if (!slider->lower && !slider->fill_level)
649 clearlooks_glossy_scale_draw_gradient (cr, &colors->shade[3], /* top */
650 &colors->shade[2], /* bottom */
651 &colors->shade[6], /* border */
652 1.0, 1.0, trough_width - 2, trough_height - 2,
653 slider->horizontal);
654 else
655 clearlooks_glossy_scale_draw_gradient (cr, &colors->spot[1], /* top */
656 &colors->spot[0], /* bottom */
657 &colors->spot[2], /* border */
658 1.0, 1.0, trough_width - 2, trough_height - 2,
659 slider->horizontal);
660 cairo_restore (cr);
661 }
662
663 static void
clearlooks_glossy_draw_tab(cairo_t * cr,const ClearlooksColors * colors,const WidgetParameters * params,const TabParameters * tab,int x,int y,int width,int height)664 clearlooks_glossy_draw_tab (cairo_t *cr,
665 const ClearlooksColors *colors,
666 const WidgetParameters *params,
667 const TabParameters *tab,
668 int x, int y, int width, int height)
669 {
670
671 const CairoColor *border = &colors->shade[5];
672 const CairoColor *stripe_fill = &colors->spot[1];
673 const CairoColor *stripe_border = &colors->spot[2];
674 const CairoColor *fill;
675 CairoColor hilight;
676
677 cairo_pattern_t *pattern;
678
679 double radius;
680 double strip_size;
681 double length;
682
683 radius = MIN (params->radius, MIN ((width - 2.0) / 2.0, (height - 2.0) / 2.0));
684
685 /* Set clip */
686 cairo_rectangle (cr, x, y, width, height);
687 cairo_clip (cr);
688 cairo_new_path (cr);
689
690 /* Translate and set line width */
691 cairo_set_line_width (cr, 1.0);
692 cairo_translate (cr, x+0.5, y+0.5);
693
694
695 /* Make the tabs slightly bigger than they should be, to create a gap */
696 /* And calculate the strip size too, while you're at it */
697 if (tab->gap_side == CL_GAP_TOP || tab->gap_side == CL_GAP_BOTTOM)
698 {
699 height += 3.0;
700 length = height;
701 strip_size = 2.0/height; /* 2 pixel high strip */
702
703 if (tab->gap_side == CL_GAP_TOP)
704 cairo_translate (cr, 0.0, -3.0); /* gap at the other side */
705 }
706 else
707 {
708 width += 3.0;
709 length = width;
710 strip_size = 2.0/width;
711
712 if (tab->gap_side == CL_GAP_LEFT)
713 cairo_translate (cr, -3.0, 0.0); /* gap at the other side */
714 }
715
716 /* Set the fill color */
717 fill = &colors->bg[params->state_type];
718
719 /* Set tab shape */
720 ge_cairo_rounded_rectangle (cr, 0, 0, width-1, height-1,
721 radius, params->corners);
722
723 /* Draw fill */
724 ge_cairo_set_color (cr, fill);
725 cairo_fill (cr);
726
727 ge_shade_color (fill, 1.3, &hilight);
728
729 /* Draw highlight */
730 if (!params->active)
731 {
732 ShadowParameters shadow;
733
734 shadow.shadow = CL_SHADOW_OUT;
735 shadow.corners = params->corners;
736
737 /* This is the only usage of clearlooks_glossy_draw_highlight_and_shade,
738 * the function assumes currently that the input is translated by 0.5 px. */
739 clearlooks_glossy_draw_highlight_and_shade (cr, &colors->bg[0], &shadow,
740 width,
741 height, radius);
742 }
743
744 if (params->active)
745 {
746 CairoColor shadow, hilight, f1, f2;
747
748 switch (tab->gap_side)
749 {
750 case CL_GAP_TOP:
751 pattern = cairo_pattern_create_linear (0, height-2, 0, 0);
752 break;
753 case CL_GAP_BOTTOM:
754 pattern = cairo_pattern_create_linear (0, 1, 0, height);
755 break;
756 case CL_GAP_LEFT:
757 pattern = cairo_pattern_create_linear (width-2, 0, 1, 0);
758 break;
759 case CL_GAP_RIGHT:
760 pattern = cairo_pattern_create_linear (1, 0, width-2, 0);
761 break;
762 default:
763 pattern = NULL;
764 }
765
766 ge_cairo_rounded_rectangle (cr, 0, 0, width-1, height-1, radius, params->corners);
767
768 ge_shade_color (fill, 1.06, &shadow);
769 ge_shade_color (fill, 1.18, &hilight);
770 ge_shade_color (fill, 1.12, &f1);
771 ge_shade_color (fill, 1.06, &f2);
772
773 cairo_pattern_add_color_stop_rgb (pattern, 0.0, hilight.r, hilight.g, hilight.b);
774 cairo_pattern_add_color_stop_rgb (pattern, 1.0/length, hilight.r, hilight.g, hilight.b);
775 cairo_pattern_add_color_stop_rgb (pattern, 1.0/length, f1.r, f1.g, f1.b);
776 cairo_pattern_add_color_stop_rgb (pattern, 0.45, f2.r, f2.g, f2.b);
777 cairo_pattern_add_color_stop_rgb (pattern, 0.45, fill->r, fill->g, fill->b);
778 cairo_pattern_add_color_stop_rgb (pattern, 1.0, shadow.r, shadow.g, shadow.b);
779 cairo_set_source (cr, pattern);
780 cairo_fill (cr);
781 cairo_pattern_destroy (pattern);
782 }
783 else
784 {
785 /* Draw shade */
786 switch (tab->gap_side)
787 {
788 case CL_GAP_TOP:
789 pattern = cairo_pattern_create_linear (0, height-2, 0, 0);
790 break;
791 case CL_GAP_BOTTOM:
792 pattern = cairo_pattern_create_linear (0, 0, 0, height);
793 break;
794 case CL_GAP_LEFT:
795 pattern = cairo_pattern_create_linear (width-2, 0, 0, 0);
796 break;
797 case CL_GAP_RIGHT:
798 pattern = cairo_pattern_create_linear (0, 0, width, 0);
799 break;
800 default:
801 pattern = NULL;
802 }
803
804 ge_cairo_rounded_rectangle (cr, 0, 0, width-1, height-1, radius, params->corners);
805
806
807 cairo_pattern_add_color_stop_rgba (pattern, 0.0, stripe_fill->r, stripe_fill->g, stripe_fill->b, 0.5);
808 cairo_pattern_add_color_stop_rgba (pattern, 0.8, fill->r, fill->g, fill->b, 0.0);
809 cairo_set_source (cr, pattern);
810 cairo_fill (cr);
811 cairo_pattern_destroy (pattern);
812 }
813
814 ge_cairo_rounded_rectangle (cr, 0, 0, width-1, height-1, radius, params->corners);
815
816 if (params->active)
817 {
818 ge_cairo_set_color (cr, border);
819 cairo_stroke (cr);
820 }
821 else
822 {
823 switch (tab->gap_side)
824 {
825 case CL_GAP_TOP:
826 pattern = cairo_pattern_create_linear (2, height-2, 2, 2);
827 break;
828 case CL_GAP_BOTTOM:
829 pattern = cairo_pattern_create_linear (2, 2, 2, height);
830 break;
831 case CL_GAP_LEFT:
832 pattern = cairo_pattern_create_linear (width-2, 2, 2, 2);
833 break;
834 case CL_GAP_RIGHT:
835 pattern = cairo_pattern_create_linear (2, 2, width, 2);
836 break;
837 default:
838 pattern = NULL;
839 }
840
841 cairo_pattern_add_color_stop_rgb (pattern, 0.0, stripe_border->r, stripe_border->g, stripe_border->b);
842 cairo_pattern_add_color_stop_rgb (pattern, 0.8, border->r, border->g, border->b);
843 cairo_set_source (cr, pattern);
844 cairo_stroke (cr);
845 cairo_pattern_destroy (pattern);
846 }
847 }
848
849 static void
clearlooks_glossy_draw_slider(cairo_t * cr,const ClearlooksColors * colors,const WidgetParameters * params,int x,int y,int width,int height)850 clearlooks_glossy_draw_slider (cairo_t *cr,
851 const ClearlooksColors *colors,
852 const WidgetParameters *params,
853 int x, int y, int width, int height)
854 {
855 const CairoColor *border = &colors->shade[7];
856 CairoColor fill;
857 CairoColor hilight;
858 CairoColor a, b, c, d;
859 cairo_pattern_t *pattern;
860
861 cairo_set_line_width (cr, 1.0);
862 cairo_translate (cr, x, y);
863
864 ge_shade_color (&colors->bg[params->state_type], 1.0, &fill);
865 if (params->prelight)
866 ge_shade_color (&fill, 1.1, &fill);
867
868 ge_shade_color (&fill, 1.25, &hilight);
869 ge_shade_color (&fill, 1.16, &a);
870 ge_shade_color (&fill, 1.08, &b);
871 ge_shade_color (&fill, 1.0, &c);
872 ge_shade_color (&fill, 1.08, &d);
873
874 pattern = cairo_pattern_create_linear (1, 1, 1, height-2);
875 cairo_pattern_add_color_stop_rgb (pattern, 0, a.r, a.g, a.b);
876 cairo_pattern_add_color_stop_rgb (pattern, 0.5, b.r, b.g, b.b);
877 cairo_pattern_add_color_stop_rgb (pattern, 0.5, c.r, c.g, c.b);
878 cairo_pattern_add_color_stop_rgb (pattern, 1.0, d.r, d.g, d.b);
879 cairo_rectangle (cr, 1, 1, width-2, height-2);
880 cairo_set_source (cr, pattern);
881 cairo_fill (cr);
882 cairo_pattern_destroy (pattern);
883
884 clearlooks_set_mixed_color (cr, border, &fill, 0.2);
885 if (params->prelight)
886 ge_cairo_set_color (cr, &colors->spot[2]);
887 ge_cairo_rounded_rectangle (cr, 0.5, 0.5, width-1, height-1, 2.5, params->corners);
888 cairo_stroke (cr);
889
890 cairo_set_source_rgba (cr, hilight.r, hilight.g, hilight.b, 0.5);
891 ge_cairo_rounded_rectangle (cr, 1.5, 1.5, width-3, height-3, 2.0, params->corners);
892 cairo_stroke (cr);
893 }
894
895 static void
clearlooks_glossy_draw_slider_button(cairo_t * cr,const ClearlooksColors * colors,const WidgetParameters * params,const SliderParameters * slider,int x,int y,int width,int height)896 clearlooks_glossy_draw_slider_button (cairo_t *cr,
897 const ClearlooksColors *colors,
898 const WidgetParameters *params,
899 const SliderParameters *slider,
900 int x, int y, int width, int height)
901 {
902 double radius = MIN (params->radius, MIN ((width - 1.0) / 2.0, (height - 1.0) / 2.0));
903
904 cairo_set_line_width (cr, 1.0);
905
906 if (!slider->horizontal)
907 ge_cairo_exchange_axis (cr, &x, &y, &width, &height);
908
909 cairo_translate (cr, x, y);
910 params->style_functions->draw_shadow (cr, colors, radius, width, height);
911 params->style_functions->draw_slider (cr, colors, params, 1, 1, width-2, height-2);
912 }
913
914 static void
clearlooks_glossy_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)915 clearlooks_glossy_draw_scrollbar_stepper (cairo_t *cr,
916 const ClearlooksColors *colors,
917 const WidgetParameters *widget,
918 const ScrollBarParameters *scrollbar,
919 const ScrollBarStepperParameters *stepper,
920 int x, int y, int width, int height)
921 {
922 CairoCorners corners = CR_CORNER_NONE;
923 const CairoColor *border = &colors->shade[7];
924 CairoColor fill, s1, s2, s4;
925 cairo_pattern_t *pattern;
926 ShadowParameters shadow;
927 double radius = MIN (widget->radius, MIN ((width - 2.0) / 2.0, (height - 2.0) / 2.0));
928
929 if (scrollbar->horizontal)
930 {
931 if (stepper->stepper == CL_STEPPER_A)
932 corners = CR_CORNER_TOPLEFT | CR_CORNER_BOTTOMLEFT;
933 else if (stepper->stepper == CL_STEPPER_D)
934 corners = CR_CORNER_TOPRIGHT | CR_CORNER_BOTTOMRIGHT;
935
936 if (stepper->stepper == CL_STEPPER_B)
937 {
938 x -= 1;
939 width += 1;
940 }
941 else if (stepper->stepper == CL_STEPPER_C)
942 {
943 width += 1;
944 }
945 }
946 else
947 {
948 if (stepper->stepper == CL_STEPPER_A)
949 corners = CR_CORNER_TOPLEFT | CR_CORNER_TOPRIGHT;
950 else if (stepper->stepper == CL_STEPPER_D)
951 corners = CR_CORNER_BOTTOMLEFT | CR_CORNER_BOTTOMRIGHT;
952
953 if (stepper->stepper == CL_STEPPER_B)
954 {
955 y -= 1;
956 height += 1;
957 }
958 else if (stepper->stepper == CL_STEPPER_C)
959 {
960 height += 1;
961 }
962 }
963
964 cairo_translate (cr, x, y);
965 cairo_set_line_width (cr, 1);
966
967 ge_cairo_rounded_rectangle (cr, 1, 1, width-2, height-2, radius, corners);
968
969 if (scrollbar->horizontal)
970 pattern = cairo_pattern_create_linear (0, 0, 0, height);
971 else
972 pattern = cairo_pattern_create_linear (0, 0, width, 0);
973
974 fill = colors->bg[widget->state_type];
975 ge_shade_color(&fill, 1.16, &s1);
976 ge_shade_color(&fill, 1.08, &s2);
977 ge_shade_color(&fill, 1.08, &s4);
978
979 cairo_pattern_add_color_stop_rgb(pattern, 0, s1.r, s1.g, s1.b);
980 cairo_pattern_add_color_stop_rgb(pattern, 0.5, s2.r, s2.g, s2.b);
981 cairo_pattern_add_color_stop_rgb(pattern, 0.5, fill.r, fill.g, fill.b);
982 cairo_pattern_add_color_stop_rgb(pattern, 1.0, s4.r, s4.g, s4.b);
983 cairo_set_source (cr, pattern);
984 cairo_fill (cr);
985 cairo_pattern_destroy (pattern);
986
987 ge_cairo_inner_rounded_rectangle (cr, 0, 0, width, height, radius, corners);
988 clearlooks_set_mixed_color (cr, border, &fill, 0.2);
989 if (widget->prelight)
990 ge_cairo_set_color (cr, &colors->spot[2]);
991 cairo_stroke (cr);
992
993 shadow.shadow = CL_SHADOW_OUT;
994 shadow.corners = corners;
995 }
996
997 static void
clearlooks_glossy_draw_scrollbar_slider(cairo_t * cr,const ClearlooksColors * colors,const WidgetParameters * widget,const ScrollBarParameters * scrollbar,int x,int y,int width,int height)998 clearlooks_glossy_draw_scrollbar_slider (cairo_t *cr,
999 const ClearlooksColors *colors,
1000 const WidgetParameters *widget,
1001 const ScrollBarParameters *scrollbar,
1002 int x, int y, int width, int height)
1003 {
1004 const CairoColor *border = &colors->shade[7];
1005 CairoColor fill = scrollbar->color;
1006 CairoColor hilight;
1007 CairoColor shade1, shade2, shade3;
1008 cairo_pattern_t *pattern;
1009
1010 if (scrollbar->junction & CL_JUNCTION_BEGIN)
1011 {
1012 if (scrollbar->horizontal)
1013 {
1014 x -= 1;
1015 width += 1;
1016 }
1017 else
1018 {
1019 y -= 1;
1020 height += 1;
1021 }
1022 }
1023 if (scrollbar->junction & CL_JUNCTION_END)
1024 {
1025 if (scrollbar->horizontal)
1026 width += 1;
1027 else
1028 height += 1;
1029 }
1030
1031 if (!scrollbar->horizontal)
1032 ge_cairo_exchange_axis (cr, &x, &y, &width, &height);
1033
1034 cairo_translate (cr, x, y);
1035
1036 if (widget->prelight)
1037 ge_shade_color (&fill, 1.1, &fill);
1038
1039 cairo_set_line_width (cr, 1);
1040
1041 ge_shade_color (&fill, 1.25, &hilight);
1042 ge_shade_color (&fill, 1.16, &shade1);
1043 ge_shade_color (&fill, 1.08, &shade2);
1044 ge_shade_color (&fill, 1.08, &shade3);
1045
1046 pattern = cairo_pattern_create_linear (1, 1, 1, height-2);
1047 cairo_pattern_add_color_stop_rgb (pattern, 0, shade1.r, shade1.g, shade1.b);
1048 cairo_pattern_add_color_stop_rgb (pattern, 0.5, shade2.r, shade2.g, shade2.b);
1049 cairo_pattern_add_color_stop_rgb (pattern, 0.5, fill.r, fill.g, fill.b);
1050 cairo_pattern_add_color_stop_rgb (pattern, 1, shade3.r, shade3.g, shade3.b);
1051 cairo_rectangle (cr, 1, 1, width-2, height-2);
1052 cairo_set_source (cr, pattern);
1053 cairo_fill (cr);
1054 cairo_pattern_destroy (pattern);
1055
1056 if (scrollbar->has_color)
1057 {
1058 cairo_set_source_rgba (cr, hilight.r, hilight.g, hilight.b, 0.5);
1059 ge_cairo_stroke_rectangle (cr, 1.5, 1.5, width-3, height-3);
1060 }
1061
1062 clearlooks_set_mixed_color (cr, border, &fill, scrollbar->has_color? 0.4 : 0.2);
1063 ge_cairo_stroke_rectangle (cr, 0.5, 0.5, width-1, height-1);
1064 }
1065
1066 static void
clearlooks_glossy_draw_list_view_header(cairo_t * cr,const ClearlooksColors * colors,const WidgetParameters * params,const ListViewHeaderParameters * header,int x,int y,int width,int height)1067 clearlooks_glossy_draw_list_view_header (cairo_t *cr,
1068 const ClearlooksColors *colors,
1069 const WidgetParameters *params,
1070 const ListViewHeaderParameters *header,
1071 int x, int y, int width, int height)
1072 {
1073 /*
1074 CairoColor *border = !params->prelight? (CairoColor*)&colors->shade[4] : (CairoColor*)&colors->spot[1];
1075 */
1076 const CairoColor *border = &colors->shade[4];
1077 const CairoColor *fill = &colors->bg[params->state_type];
1078 CairoColor hilight;
1079 CairoColor shade1, shade2, shade3;
1080
1081 cairo_pattern_t *pattern;
1082
1083 ge_shade_color (fill, 1.2, &hilight);
1084 ge_shade_color (fill, 1.08, &shade1);
1085 ge_shade_color (fill, 1.04, &shade2);
1086 ge_shade_color (fill, 1.04, &shade3);
1087
1088 cairo_translate (cr, x, y);
1089 cairo_set_line_width (cr, 1.0);
1090
1091 /* Draw the fill */
1092 pattern = cairo_pattern_create_linear (0, 0, 0, height);
1093 cairo_pattern_add_color_stop_rgb (pattern, 0.0, shade1.r, shade1.g, shade1.b);
1094 cairo_pattern_add_color_stop_rgb (pattern, 0.5, shade2.r, shade2.g, shade2.b);
1095 cairo_pattern_add_color_stop_rgb (pattern, 0.5, fill->r, fill->g, fill->b);
1096 cairo_pattern_add_color_stop_rgb (pattern, 1.0-1.0/height, shade3.r, shade3.g, shade3.b);
1097 cairo_pattern_add_color_stop_rgb (pattern, 1.0-1.0/height, border->r, border->g, border->b);
1098 cairo_pattern_add_color_stop_rgb (pattern, 1.0, border->r, border->g, border->b);
1099
1100 cairo_set_source (cr, pattern);
1101 cairo_rectangle (cr, 0, 0, width, height);
1102 cairo_fill (cr);
1103
1104 cairo_pattern_destroy (pattern);
1105
1106 /* Draw highlight */
1107 if (header->order & CL_ORDER_FIRST)
1108 {
1109 cairo_move_to (cr, 0.5, height-1);
1110 cairo_line_to (cr, 0.5, 0.5);
1111 }
1112 else
1113 cairo_move_to (cr, 0.0, 0.5);
1114
1115 cairo_line_to (cr, width, 0.5);
1116
1117 cairo_set_source_rgba (cr, hilight.r, hilight.g, hilight.b, 0.5);
1118 cairo_stroke (cr);
1119
1120 /* Draw resize grip */
1121 if ((params->ltr && !(header->order & CL_ORDER_LAST)) ||
1122 (!params->ltr && !(header->order & CL_ORDER_FIRST)) || header->resizable)
1123 {
1124 SeparatorParameters separator;
1125 separator.horizontal = FALSE;
1126
1127 if (params->ltr)
1128 params->style_functions->draw_separator (cr, colors, params, &separator,
1129 width-1.5, 4.0, 2, height-8.0);
1130 else
1131 params->style_functions->draw_separator (cr, colors, params, &separator,
1132 1.5, 4.0, 2, height-8.0);
1133 }
1134 }
1135
1136 static void
clearlooks_glossy_draw_toolbar(cairo_t * cr,const ClearlooksColors * colors,const WidgetParameters * widget,const ToolbarParameters * toolbar,int x,int y,int width,int height)1137 clearlooks_glossy_draw_toolbar (cairo_t *cr,
1138 const ClearlooksColors *colors,
1139 const WidgetParameters *widget,
1140 const ToolbarParameters *toolbar,
1141 int x, int y, int width, int height)
1142 {
1143 const CairoColor *fill = &colors->bg[GTK_STATE_NORMAL];
1144 const CairoColor *dark = &colors->shade[3];
1145 CairoColor light;
1146 ge_shade_color (fill, 1.1, &light);
1147
1148 cairo_set_line_width (cr, 1.0);
1149 cairo_translate (cr, x, y);
1150
1151 if (toolbar->style == 1) /* Enable Extra features */
1152 {
1153 cairo_pattern_t *pattern;
1154 CairoColor shade1, shade2, shade3;
1155
1156 ge_shade_color (fill, 1.08, &shade1);
1157 ge_shade_color (fill, 1.04, &shade2);
1158 ge_shade_color (fill, 1.04, &shade3);
1159
1160 /* Draw the fill */
1161 pattern = cairo_pattern_create_linear (0, 0, 0, height);
1162 cairo_pattern_add_color_stop_rgb (pattern, 0.0, shade1.r, shade1.g, shade1.b);
1163 cairo_pattern_add_color_stop_rgb (pattern, 0.5, shade2.r, shade2.g, shade2.b);
1164 cairo_pattern_add_color_stop_rgb (pattern, 0.5, fill->r, fill->g, fill->b);
1165 cairo_pattern_add_color_stop_rgb (pattern, 1.0, shade3.r, shade3.g, shade3.b);
1166
1167 cairo_set_source (cr, pattern);
1168 cairo_rectangle (cr, 0, 0, width, height);
1169 cairo_fill (cr);
1170
1171 cairo_pattern_destroy (pattern);
1172 }
1173 else /* Flat */
1174 {
1175 ge_cairo_set_color (cr, fill);
1176 cairo_paint (cr);
1177
1178 if (!toolbar->topmost)
1179 {
1180 /* Draw highlight */
1181 cairo_move_to (cr, 0, 0.5);
1182 cairo_line_to (cr, width-1, 0.5);
1183 ge_cairo_set_color (cr, &light);
1184 cairo_stroke (cr);
1185 }
1186 }
1187
1188 /* Draw shadow */
1189 cairo_move_to (cr, 0, height-0.5);
1190 cairo_line_to (cr, width-1, height-0.5);
1191 ge_cairo_set_color (cr, dark);
1192 cairo_stroke (cr);
1193 }
1194
1195 static void
clearlooks_glossy_draw_menuitem(cairo_t * cr,const ClearlooksColors * colors,const WidgetParameters * params,int x,int y,int width,int height)1196 clearlooks_glossy_draw_menuitem (cairo_t *cr,
1197 const ClearlooksColors *colors,
1198 const WidgetParameters *params,
1199 int x, int y, int width, int height)
1200 {
1201 const CairoColor *fill = &colors->spot[1];
1202 const CairoColor *border = &colors->spot[2];
1203 CairoColor shade1, shade2, shade3;
1204 cairo_pattern_t *pattern;
1205
1206 ge_shade_color (fill, 1.16, &shade1);
1207 ge_shade_color (fill, 1.08, &shade2);
1208 ge_shade_color (fill, 1.08, &shade3);
1209 cairo_set_line_width (cr, 1.0);
1210
1211 ge_cairo_rounded_rectangle (cr, x+0.5, y+0.5, width - 1, height - 1, params->radius, params->corners);
1212
1213 pattern = cairo_pattern_create_linear (x, y, x, y + height);
1214 cairo_pattern_add_color_stop_rgb (pattern, 0, shade1.r, shade1.g, shade1.b);
1215 cairo_pattern_add_color_stop_rgb (pattern, 0.5, shade2.r, shade2.g, shade2.b);
1216 cairo_pattern_add_color_stop_rgb (pattern, 0.5, fill->r, fill->g, fill->b);
1217 cairo_pattern_add_color_stop_rgb (pattern, 1, shade3.r, shade3.g, shade3.b);
1218
1219 cairo_set_source (cr, pattern);
1220 cairo_fill_preserve (cr);
1221 cairo_pattern_destroy (pattern);
1222
1223 ge_cairo_set_color (cr, border);
1224 cairo_stroke (cr);
1225 }
1226
1227 static void
clearlooks_glossy_draw_menubaritem(cairo_t * cr,const ClearlooksColors * colors,const WidgetParameters * params,int x,int y,int width,int height)1228 clearlooks_glossy_draw_menubaritem (cairo_t *cr,
1229 const ClearlooksColors *colors,
1230 const WidgetParameters *params,
1231 int x, int y, int width, int height)
1232 {
1233 const CairoColor *fill = &colors->spot[1];
1234 const CairoColor *border = &colors->spot[2];
1235 CairoColor shade1, shade2, shade3;
1236 cairo_pattern_t *pattern;
1237
1238 ge_shade_color (fill, 1.16, &shade1);
1239 ge_shade_color (fill, 1.08, &shade2);
1240 ge_shade_color (fill, 1.08, &shade3);
1241 cairo_set_line_width (cr, 1.0);
1242
1243 ge_cairo_rounded_rectangle (cr, x+0.5, y+0.5, width - 1, height - 1, params->radius, params->corners);
1244
1245 pattern = cairo_pattern_create_linear (x, y, x, y + height);
1246 cairo_pattern_add_color_stop_rgb (pattern, 0, shade1.r, shade1.g, shade1.b);
1247 cairo_pattern_add_color_stop_rgb (pattern, 0.5, shade2.r, shade2.g, shade2.b);
1248 cairo_pattern_add_color_stop_rgb (pattern, 0.5, fill->r, fill->g, fill->b);
1249 cairo_pattern_add_color_stop_rgb (pattern, 1, shade3.r, shade3.g, shade3.b);
1250
1251 cairo_set_source (cr, pattern);
1252 cairo_fill_preserve (cr);
1253 cairo_pattern_destroy (pattern);
1254
1255 ge_cairo_set_color (cr, border);
1256 cairo_stroke (cr);
1257 }
1258
1259 static void
clearlooks_glossy_draw_selected_cell(cairo_t * cr,const ClearlooksColors * colors,const WidgetParameters * params,int x,int y,int width,int height)1260 clearlooks_glossy_draw_selected_cell (cairo_t *cr,
1261 const ClearlooksColors *colors,
1262 const WidgetParameters *params,
1263 int x, int y, int width, int height)
1264 {
1265 CairoColor color;
1266
1267 if (params->focus)
1268 color = colors->base[params->state_type];
1269 else
1270 color = colors->base[GTK_STATE_ACTIVE];
1271
1272 clearlooks_draw_glossy_gradient (cr, x, y, width, height, &color, params->disabled, 0.0, CR_CORNER_NONE);
1273 }
1274
1275
1276 static void
clearlooks_glossy_draw_radiobutton(cairo_t * cr,const ClearlooksColors * colors,const WidgetParameters * widget,const CheckboxParameters * checkbox,int x,int y,int width,int height)1277 clearlooks_glossy_draw_radiobutton (cairo_t *cr,
1278 const ClearlooksColors *colors,
1279 const WidgetParameters *widget,
1280 const CheckboxParameters *checkbox,
1281 int x, int y, int width, int height)
1282 {
1283 const CairoColor *border;
1284 const CairoColor *dot;
1285 CairoColor shadow;
1286 CairoColor highlight;
1287 cairo_pattern_t *pt;
1288 gboolean inconsistent;
1289 gboolean draw_bullet = (checkbox->shadow_type == GTK_SHADOW_IN);
1290 gdouble w, h, cx, cy, radius;
1291
1292 w = (gdouble) width;
1293 h = (gdouble) height;
1294 cx = width / 2.0;
1295 cy = height / 2.0;
1296 radius = MIN (width, height) / 2.0;
1297
1298 inconsistent = (checkbox->shadow_type == GTK_SHADOW_ETCHED_IN);
1299 draw_bullet |= inconsistent;
1300
1301 if (widget->disabled)
1302 {
1303 border = &colors->shade[5];
1304 dot = &colors->shade[6];
1305 }
1306 else
1307 {
1308 if (widget->prelight)
1309 border = &colors->spot[2];
1310 else
1311 border = &colors->shade[6];
1312 dot = &colors->text[0];
1313 }
1314
1315 ge_shade_color (&widget->parentbg, 0.9, &shadow);
1316 ge_shade_color (&widget->parentbg, 1.1, &highlight);
1317
1318 pt = cairo_pattern_create_linear (0, 0, radius * 2.0, radius * 2.0);
1319 cairo_pattern_add_color_stop_rgb (pt, 0.0, shadow.r, shadow.b, shadow.g);
1320 cairo_pattern_add_color_stop_rgba (pt, 0.5, shadow.r, shadow.b, shadow.g, 0.5);
1321 cairo_pattern_add_color_stop_rgba (pt, 0.5, highlight.r, highlight.g, highlight.b, 0.5);
1322 cairo_pattern_add_color_stop_rgb (pt, 1.0, highlight.r, highlight.g, highlight.b);
1323
1324 cairo_translate (cr, x, y);
1325
1326 cairo_set_line_width (cr, MAX (1.0, floor (radius/3)));
1327 cairo_arc (cr, ceil (cx), ceil (cy), floor (radius - 0.1), 0, G_PI*2);
1328 cairo_set_source (cr, pt);
1329 cairo_stroke (cr);
1330 cairo_pattern_destroy (pt);
1331
1332 cairo_set_line_width (cr, MAX (1.0, floor (radius/6)));
1333
1334 cairo_arc (cr, ceil (cx), ceil (cy), MAX (1.0, ceil (radius) - 1.5), 0, G_PI*2);
1335
1336 if (!widget->disabled)
1337 {
1338 if (widget->prelight)
1339 clearlooks_set_mixed_color (cr, &colors->base[0], &colors->spot[1], 0.5);
1340 else
1341 ge_cairo_set_color (cr, &colors->base[0]);
1342 cairo_fill_preserve (cr);
1343 }
1344
1345 ge_cairo_set_color (cr, border);
1346 cairo_stroke (cr);
1347
1348 if (draw_bullet)
1349 {
1350 if (inconsistent)
1351 {
1352 cairo_set_line_cap(cr, CAIRO_LINE_CAP_ROUND);
1353 cairo_set_line_width (cr, ceil (radius * 2 / 3));
1354
1355 cairo_move_to (cr, ceil (cx - radius/3.0), ceil (cy));
1356 cairo_line_to (cr, ceil (cx + radius/3.0), ceil (cy));
1357
1358 ge_cairo_set_color (cr, dot);
1359 cairo_stroke (cr);
1360 }
1361 else
1362 {
1363 cairo_arc (cr, ceil (cx), ceil (cy), floor (radius/2.0), 0, G_PI*2);
1364 ge_cairo_set_color (cr, dot);
1365 cairo_fill (cr);
1366
1367 cairo_arc (cr, floor (cx - radius/10.0), floor (cy - radius/10.0), floor (radius/6.0), 0, G_PI*2);
1368 cairo_set_source_rgba (cr, highlight.r, highlight.g, highlight.b, 0.5);
1369 cairo_fill (cr);
1370 }
1371 }
1372 }
1373
1374 static void
clearlooks_glossy_draw_checkbox(cairo_t * cr,const ClearlooksColors * colors,const WidgetParameters * widget,const CheckboxParameters * checkbox,int x,int y,int width,int height)1375 clearlooks_glossy_draw_checkbox (cairo_t *cr,
1376 const ClearlooksColors *colors,
1377 const WidgetParameters *widget,
1378 const CheckboxParameters *checkbox,
1379 int x, int y, int width, int height)
1380 {
1381 const CairoColor *border;
1382 const CairoColor *dot;
1383 gboolean inconsistent = FALSE;
1384 gboolean draw_bullet = (checkbox->shadow_type == GTK_SHADOW_IN);
1385
1386 inconsistent = (checkbox->shadow_type == GTK_SHADOW_ETCHED_IN);
1387 draw_bullet |= inconsistent;
1388
1389 if (widget->disabled)
1390 {
1391 border = &colors->shade[5];
1392 dot = &colors->shade[6];
1393 }
1394 else
1395 {
1396 if (widget->prelight)
1397 border = &colors->spot[2];
1398 else
1399 border = &colors->shade[6];
1400 dot = &colors->text[GTK_STATE_NORMAL];
1401 }
1402
1403 cairo_translate (cr, x, y);
1404 cairo_set_line_width (cr, 1);
1405
1406 if (widget->xthickness > 2 && widget->ythickness > 2)
1407 {
1408 widget->style_functions->draw_inset (cr, &widget->parentbg, 0, 0,
1409 width, height, (widget->radius > 0)? 1 : 0, CR_CORNER_ALL);
1410
1411 /* Draw the rectangle for the checkbox itself */
1412 ge_cairo_rounded_rectangle (cr, 1.5, 1.5,
1413 width-3, height-3, (widget->radius > 0)? 1 : 0, CR_CORNER_ALL);
1414 }
1415 else
1416 {
1417 /* Draw the rectangle for the checkbox itself */
1418 ge_cairo_rounded_rectangle (cr, 0.5, 0.5,
1419 width-1, height-1, (widget->radius > 0)? 1 : 0, CR_CORNER_ALL);
1420 }
1421
1422 if (!widget->disabled)
1423 {
1424 if (widget->prelight)
1425 clearlooks_set_mixed_color (cr, &colors->base[0], &colors->spot[1], 0.5);
1426 else
1427 ge_cairo_set_color (cr, &colors->base[0]);
1428 cairo_fill_preserve (cr);
1429 }
1430
1431 ge_cairo_set_color (cr, border);
1432 cairo_stroke (cr);
1433
1434 if (draw_bullet)
1435 {
1436 if (inconsistent) /* Inconsistent */
1437 {
1438 cairo_set_line_width (cr, 2.0);
1439 cairo_move_to (cr, 3, height*0.5);
1440 cairo_line_to (cr, width-3, height*0.5);
1441 }
1442 else
1443 {
1444 cairo_set_line_width (cr, 1.7);
1445 cairo_move_to (cr, 0.5 + (width*0.2), (height*0.5));
1446 cairo_line_to (cr, 0.5 + (width*0.4), (height*0.7));
1447
1448 cairo_curve_to (cr, 0.5 + (width*0.4), (height*0.7),
1449 0.5 + (width*0.5), (height*0.4),
1450 0.5 + (width*0.70), (height*0.25));
1451
1452 }
1453
1454 ge_cairo_set_color (cr, dot);
1455 cairo_stroke (cr);
1456 }
1457 }
1458
1459 static void
clearlooks_glossy_draw_icon_view_item(cairo_t * cr,const ClearlooksColors * colors,const WidgetParameters * params,int x,int y,int width,int height)1460 clearlooks_glossy_draw_icon_view_item (cairo_t *cr,
1461 const ClearlooksColors *colors,
1462 const WidgetParameters *params,
1463 int x, int y, int width, int height)
1464 {
1465 CairoColor color;
1466 gfloat radius;
1467
1468 if (params->focus)
1469 color = colors->base[params->state_type];
1470 else
1471 color = colors->base[GTK_STATE_ACTIVE];
1472
1473 radius = MIN (width / 2, params->radius);
1474 radius = MIN (height / 2, radius);
1475
1476 clearlooks_draw_glossy_gradient (cr, x, y, width, height, &color, params->disabled, params->radius, CR_CORNER_ALL);
1477 }
1478
1479 void
clearlooks_register_style_glossy(ClearlooksStyleFunctions * functions,ClearlooksStyleConstants * constants)1480 clearlooks_register_style_glossy (ClearlooksStyleFunctions *functions, ClearlooksStyleConstants *constants)
1481 {
1482 functions->draw_inset = clearlooks_glossy_draw_inset;
1483 functions->draw_button = clearlooks_glossy_draw_button;
1484 functions->draw_progressbar_trough = clearlooks_glossy_draw_progressbar_trough;
1485 functions->draw_progressbar_fill = clearlooks_glossy_draw_progressbar_fill;
1486 functions->draw_scale_trough = clearlooks_glossy_draw_scale_trough;
1487 functions->draw_tab = clearlooks_glossy_draw_tab;
1488 functions->draw_slider = clearlooks_glossy_draw_slider;
1489 functions->draw_slider_button = clearlooks_glossy_draw_slider_button;
1490 functions->draw_scrollbar_stepper = clearlooks_glossy_draw_scrollbar_stepper;
1491 functions->draw_scrollbar_slider = clearlooks_glossy_draw_scrollbar_slider;
1492 functions->draw_list_view_header = clearlooks_glossy_draw_list_view_header;
1493 functions->draw_toolbar = clearlooks_glossy_draw_toolbar;
1494 functions->draw_menuitem = clearlooks_glossy_draw_menuitem;
1495 functions->draw_menubaritem = clearlooks_glossy_draw_menubaritem;
1496 functions->draw_selected_cell = clearlooks_glossy_draw_selected_cell;
1497 functions->draw_checkbox = clearlooks_glossy_draw_checkbox;
1498 functions->draw_radiobutton = clearlooks_glossy_draw_radiobutton;
1499 functions->draw_icon_view_item = clearlooks_glossy_draw_icon_view_item;
1500 }
1501